ultisuite-client/lib/ai/chat-context.ts
R3D347HR4Y 9e9fd208ad
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat(admin-settings): enhance admin settings with new components and layout improvements
- Introduced new components for managing admin settings, including AdminListControls, AdminSettingsCard, and TechBrandSelectLabel.
- Implemented dynamic loading for admin settings sections to optimize performance.
- Enhanced the layout of various admin settings sections for better user experience.
- Updated the AiAssistantSection to include LLM provider management and improved model selection.
- Refactored authentication settings to streamline configuration and improve accessibility.
2026-06-15 00:22:20 +02:00

96 lines
3.8 KiB
TypeScript

export type AiEmbedApp = "mail" | "drive" | "contacts" | "docs" | "standalone"
export type AiChatContext = {
app: AiEmbedApp
temporary?: boolean
messageId?: string
accountId?: string
drivePath?: string
fileId?: string
contactId?: string
subject?: string
snippet?: string
/** UltiDocs — titre affiché */
documentTitle?: string
/** Chemin du fichier source (.docx, .md…) si sidecar */
sourcePath?: string
/** Extrait texte du document */
documentExcerpt?: string
/** Sélection courante dans l'éditeur */
selectionText?: string
/** JSON TipTap (éventuellement tronqué) */
documentJson?: string
/** Prompt système additionnel (non sérialisé en URL) */
systemPromptExtra?: string
}
export type AiPostMessage =
| {
type: "ULTI_CONTEXT_UPDATE"
context: AiChatContext
systemPrompt?: string
}
| { type: "ULTI_DOCS_APPLY"; payload: unknown }
| { type: "ULTI_ASSISTANT_TEXT"; text: string }
| { type: "ULTI_THEME"; theme: "light" | "dark" }
| {
type: "ULTI_SESSION"
token_secret?: string
mcp_url?: string
enabled_tools?: string[]
session_id?: string
}
| { type: "ULTI_OPEN_LINK"; href: string }
| { type: "ULTI_TOOL_RESULT"; payload: unknown }
export function buildEmbedSearchParams(
context: AiChatContext,
defaultModel?: string,
): string {
const params = new URLSearchParams()
const model = defaultModel?.trim()
if (model) params.set("model", model)
if (context.temporary !== false) params.set("temporary-chat", "true")
if (context.app) params.set("app", context.app)
if (context.messageId) params.set("message_id", context.messageId)
if (context.accountId) params.set("account_id", context.accountId)
if (context.drivePath) params.set("path", context.drivePath)
if (context.fileId) params.set("file_id", context.fileId)
if (context.contactId) params.set("contact_id", context.contactId)
if (context.subject) params.set("subject", context.subject)
if (context.snippet) params.set("snippet", context.snippet)
return params.toString()
}
export function systemPromptFromContext(context: AiChatContext): string {
const lines = [
"Tu es UltiAI, l'assistant intégré à la suite Ultimail (mail, drive, contacts, agenda).",
"Réponds en français sauf demande contraire. Utilise les tools disponibles pour agir sur les données utilisateur.",
"Recherche suite (index local) via suite_search ; recherche web publique via web_search si configurée.",
"Après chaque appel d'outil, réponds toujours en langage naturel : résume le résultat, cite les sources (sujet, chemin, nom), propose la suite.",
"Ne termine jamais un tour utilisateur avec uniquement un appel d'outil sans texte explicatif.",
"Respecte strictement le paramètre limit des tools (ne demande pas plus de résultats que nécessaire).",
]
if (context.app === "mail" && context.subject) {
lines.push(`Contexte mail — sujet: ${context.subject}`)
if (context.snippet) lines.push(`Extrait: ${context.snippet}`)
}
if (context.app === "drive" && context.drivePath) {
lines.push(`Contexte drive — fichier/dossier: ${context.drivePath}`)
}
if (context.app === "contacts" && context.contactId) {
lines.push(`Contexte contacts — fiche: ${context.contactId}`)
}
if (context.app === "docs") {
if (context.documentTitle) lines.push(`Document: ${context.documentTitle}`)
if (context.drivePath) lines.push(`Sidecar: ${context.drivePath}`)
if (context.sourcePath) lines.push(`Source: ${context.sourcePath}`)
if (context.selectionText) lines.push(`Sélection: ${context.selectionText}`)
if (context.documentExcerpt) lines.push(`Contenu:\n${context.documentExcerpt}`)
}
if (context.systemPromptExtra) {
lines.push("", context.systemPromptExtra)
}
return lines.join("\n")
}