@hgdc/assistant
v0.5.0
Published
Moteur commun de l'assistant IA des produits HGDC : outils typés (lecture, écriture, confirmation), boucle en flux avec Claude (Bedrock en UE) ou un modèle au format OpenAI (Infomaniak, en Suisse), tables et gardes Convex, crédits mensuels, clé chiffrée d
Readme
@hgdc/assistant
Le moteur commun de l'assistant IA des produits HGDC. Il vient de l'assistant de Mail, déjà en production, et de celui de Portal, son jumeau : un modèle en flux, traité en Suisse (Infomaniak, défaut) ou dans l'UE (Claude par AWS Bedrock, profil eu.), des outils typés qui agissent avec les droits de la personne, des cartes à confirmer pour tout ce qui envoie ou détruit, des conversations propres à chaque personne et des crédits mensuels par organisation.
L'interface est dans @hgdc/ui/assistant-view (panneau complet pour la colonne de AppShell) et @hgdc/ui/assistant-chat (briques). Guide pas à pas avec un exemple complet : Ajouter l'assistant à un produit. Décisions : ADR 0019 et ADR 0022, avec la migration produit par produit.
bun add @hgdc/assistant @anthropic-ai/sdkconvex (1.46+) et @anthropic-ai/sdk (0.134+, version de la stack) sont des dépendances paires : le produit les a déjà. @anthropic-ai/bedrock-sdk seulement pour Claude par Bedrock.
| Sous-chemin | Contenu | Environnement |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| @hgdc/assistant/tools | defineTools, toolDefinitions, parseToolCall (entrée vérifiée, champ inconnu refusé), toolResult (toujours tronqué), awaitingConfirmation, snapshotHash (SHA-256), types ToolNamesOf, ToolInputOf | partout |
| @hgdc/assistant/model | HAIKU_5_5 (modèle et tarifs), keyProvider, readKey, requestMicros, creditsFromMicros, microsFromCredits, currentMonth | partout |
| @hgdc/assistant/secret | sealSecret, openSecret (AES-GCM, clé HKDF du secret du déploiement, données associées liées à l'organisation), keyHint | Convex V8 et Node |
| @hgdc/assistant/convex | assistantTables(), startTurn (contrôle et réservation des crédits), progressMessage, finishTurn, turnContext, readStatus, listThreads, readThread, runReadTool, runWriteTool, runProposeTool, confirmAction, cancelAction, deleteThread, clés, crons, nLPD | queries et mutations |
| @hgdc/assistant/console | createConsoleAssistant : toutes les fonctions Convex de l'assistant d'une console, derrière la garde du produit | queries et mutations |
| @hgdc/assistant/console/node | createConsoleRunner : l'action du tour, sur le modèle souverain de la plateforme | action "use node" |
| @hgdc/assistant/node | runTurn (la boucle, bornée, garde « trifecta »), friendlyError, failureKind ; verifyKey déprécié | action "use node" |
| @hgdc/assistant/clients | sovereignClient() (le modèle de ASSISTANT_MODEL, Infomaniak par défaut), modelClient(option) | action "use node" |
| @hgdc/assistant/providers | MODEL_OPTIONS (catalogue : fournisseur, lieu de traitement, tarifs), modelOption, DEFAULT_MODEL_ID, PROCESSING_LABEL, infomaniakBaseUrl, sovereignReady, platformModel, usProcessingAllowed | partout |
| @hgdc/assistant/trifecta | taintAfter, isTrifecta, routeCall : la garde d'un tour, en fonctions pures | partout |
| @hgdc/assistant/openai | openAIClient : un point de terminaison au format OpenAI (Infomaniak AI Services) derrière l'interface de runTurn, appels d'outils compris | action "use node" |
| @hgdc/assistant/bedrock | bedrockClient : Claude par AWS Bedrock (profils eu.) | action "use node" |
Ce que le kit impose
- Aucune fonction Convex publique dans le kit. Le produit pose sa garde (
requireOrgMemberde@hgdc/auth/convex) dans chaque query et mutation, ou la donne àcreateConsoleAssistant, puis passe la personne vérifiée ({ organizationId, userId }). Chaque fonction du kit revérifie que la conversation, le message ou l'action appartient à cette personne dans cette organisation. - Données en Suisse ou dans l'UE. Variables :
INFOMANIAK_AI_TOKENetINFOMANIAK_AI_PRODUCT_ID, ouBEDROCK_REGION(région de l'UE ou de Suisse exigée,EU_BEDROCK_REGIONS: paseu-west-2, Londres) etBEDROCK_API_KEYavecASSISTANT_MODEL(profileu.exigé,assertEuBedrock). Anthropic en direct (verifyKey) traite aux États-Unis : refusé hors développement local, sauf drapeau expliciteASSISTANT_ALLOW_US_PROCESSING=1. - La classe d'un outil décide de son chemin, pas le produit :
readpasse parrunReadTool(query),writeparrunWriteTool,confirm(publie, supprime) etsend(envoie vers l'extérieur) parrunProposeTool, qui ne reçoit qu'unctxen lecture seule et n'enregistre qu'une carte. L'action n'a lieu que dansconfirmAction, appelée par la mutation publique de la personne qui clique, après une nouvelle description de la carte et la comparaison de son empreinte SHA-256. Une carte expire après 24 h. - Garde « trifecta » : un outil se marque
private(données privées) ouuntrusted(contenu de tiers). Quand un tour a lu les deux, la carte d'un outilsendporte une mise en garde ;trifecta: "block"refuse l'envoi pour ce tour. - Crédits : une réservation (3 crédits) prise dans la même transaction que le contrôle, ajustée au coût réel à la fin du tour, en micro-dollars entiers ; une réponse jamais finie garde sa réservation comme coût (
failStuckTurns). Une conversation ne s'efface pas pendant une réponse. - Bornes du tour : 25 étapes, 25 appels d'outils par étape, 8 minutes, 20 000 caractères par résultat d'outil, 700 000 octets d'historique (au-delà, la conversation est pleine).
- Mêmes outils pour MCP : le serveur MCP du produit (
createMcpHandlerde@hgdc/api/mcp) reprend le mêmeToolSet. Trois champs facultatifs d'un outil ne servent qu'à lui :title(nom affiché),annotations(surcharge des indications déduites de la classe) etoutput(schéma Zod du résultat). - Événements de l'application (confirmation, annulation, échec) : remis au modèle au tour suivant dans un bloc
<application_events>séparé, que ni la demande ni un résultat d'outil ne peuvent imiter.
Données et nLPD
- Les conversations restent dans la base Convex du produit (tables
assistant*). L'historique part au modèle à chaque tour : demandes, résultats des outils et réponses passent par Infomaniak (Suisse) ou AWS Bedrock (UE, profileu.), selonASSISTANT_MODEL. Chaque produit le dit sur sa page des données. eraseUser(par lots, à replanifier tant quedoneest faux ; anonymise aussi l'auteur d'une clé) etexportUser(conversations et cartes) servent l'effacement et l'export d'une personne ;purgeIdleThreadsefface les conversations sans activité (90 jours conseillés).TurnResult.failuredonne la nature d'une panne (api,timeout…) : c'est elle qui se journalise, jamais l'erreur brute du fournisseur ni le texte de la conversation.
