UNPKG

overmind-mcp

Version:

Orchestrateur universel agents IA multi-modeles via MCP. Inclut le protocole 'Custom-Nickname' pour identifier vos agents avec des surnoms originaux (The Chaos Prophet, Shadow Sniper, etc.), l'isolation mémoire (Private Memory Context) et le support pour

178 lines • 10.1 kB
/** * ╔══════════════════════════════════════════════════════════════════════╗ * ║ OVERMIND BRIDGE — OverBridgeService (Base Client SDK Wrapper) ║ * ║ ║ * ║ [SCRIPT DE BASE - CLIENT SDK WRAPPER] ║ * ║ API haut niveau pour interagir avec les agents, la mémoire, les ║ * ║ runs, et les sessions. Wrappe BridgeProxy pour offrir une ║ * ║ interface client simple et robuste (SDK). ║ * ║ ║ * ║ ARCHITECTURE — INPUT/OUTPUT CONTRACT ║ * ║ ───────────────────────────────────── ║ * ║ Discord ──input──→ overmind-bridge.js ──→ OverBridgeService ║ * ║ ↓ ║ * ║ BridgeProxy → MCP ║ * ║ ↓ ║ * ║ Agent (Hermes) ║ * ║ ↓ ║ * ║ OUTPUT via MCP discord ║ * ║ ║ * ║ ⚠️ INPUT ONLY: This service NEVER posts to Discord directly. ║ * ║ The agent handles its own output via its MCP discord tools. ║ * ║ This service only: ║ * ║ 1. Receives messages (Discord, HTTP, CLI) ║ * ║ 2. Formats context (channelId, userId, username) ║ * ║ 3. Forwards to agent via MCP run_agent ║ * ║ 4. Detects if agent posted via MCP (for logging only) ║ * ║ ║ * ║ LESSONS LEARNED (Striker deployment 2026-07): ║ * ║ - Bridge must NEVER post agent text → causes duplicate replies ║ * ║ - Agent timeout ≠ error (agent may still be processing) ║ * ║ - Session ID persists in subprocess, must force-reset state.db ║ * ║ - Discord context (channelId/userId/username) must be injected ║ * ║ - MCP output detection is for LOGGING ONLY, not for silencing ║ * ╚══════════════════════════════════════════════════════════════════════╝ */ import type { AgentResult, RunAgentOptions, AgentControlOptions, MemorySearchOptions, MemoryStoreOptions, MemoryRunsOptions, UpdateAgentConfigOptions, CreatePromptOptions, EditPromptOptions, BridgeConfig, SessionState, RunnerType, HealthStatus } from './types.js'; import { BridgeProxy } from './BridgeProxy.js'; import { type BridgeLogger } from './utils.js'; export declare class OverBridgeService { private readonly proxy; private session; private heartbeatInterval; constructor(config?: Partial<BridgeConfig>, logger?: BridgeLogger, initialSessionId?: string); get proxyAccess(): BridgeProxy; get sessionId(): string | undefined; get sessionInfo(): SessionState; /** * Initialise la connexion au serveur MCP, vérifie la santé initiale * et configure un heartbeat périodique avec auto-reconnect. * * Fix #3: Si le ping échoue, on reset le circuit breaker et on * réessaie de se reconnecter au lieu d'attendre un redémarrage manuel. */ connect(healthCheckIntervalMs?: number): Promise<HealthStatus>; /** * Ferme proprement le service en annulant le heartbeat actif. */ disconnect(): void; /** * Force un reset de session — le prochain appel démarre une nouvelle session. * * Si `agentName` est fourni, purge également le `state.db` du profile Hermes * correspondant pour éviter que le runner ne réutilise l'historique accumulé. * * Problème résolu : * Le runner Hermes persiste l'historique des messages dans * `<profilePath>/memories/state.db` (SQLite). Sans purge, un reset de * l'ID en mémoire ne suffit pas — la prochaine session est créée dans la * même DB qui accumulate les anciens messages, provoquant un contexte * fantôme et des réponses qui se référent à l'historique obsolète. * * @param agentName - Optionnel. Si fourni, purge state.db + WAL/SHM du profile. * @returns Objet décrivant ce qui a été purgé (pour logging/debug). */ resetSession(agentName?: string): { memoryCleared: boolean; inMemorySessionCleared: boolean; purgedFiles: string[]; profilePath?: string; error?: string; }; /** Force un sessionId spécifique (ex: reçu d'un env var) */ setSession(id: string): void; private updateSession; /** * Exécute un agent via `run_agent`. * Gère automatiquement la session continuity. * Injecte les defaultMcpServers du BridgeProxy si l'appelant n'en fournit pas * (héritage mémoire — l'agent a toujours accès au MCP memory). */ runAgent(options: RunAgentOptions): Promise<AgentResult>; /** * Raccourci : run agent avec contexte Discord auto-formaté. * * INPUT ONLY CONTRACT: * This method formats the Discord context and forwards to the agent. * It NEVER posts the agent's response back to Discord. * The agent must use its MCP discord tools (e.g. striker_discord, * serveur_discord) to deliver its output. * * @param agentName - Agent profile name (e.g. "striker_comptaria") * @param runner - Runner type (e.g. "hermes") * @param message - The user's message content (already prefix-stripped) * @param discordContext - Channel/user info for agent context * @returns AgentResult — the raw agent response (for logging only, NOT for posting) */ runAgentForDiscord(agentName: string, runner: RunnerType, message: string, discordContext: { channelId?: string; userId?: string; username?: string; }): Promise<AgentResult>; /** * Process and normalize an MCP agent response. * * IMPORTANT — OUTPUT DETECTION (logging only): * The agent's content may contain MCP tool call traces (e.g. * "Message envoyé sur Discord", "Embed publié sur Discord", or a * Discord message ID like "1531826331875147857"). * These traces are used ONLY for logging/debugging to confirm * the agent posted its output via MCP. They must NEVER trigger * the bridge to post the agent's text to Discord as a fallback. * * LESSONS LEARNED: * - If the agent didn't post via MCP, posting its text as a * "fallback" creates duplicate replies and confuses users. * - The proper fix is to ensure the agent's SOUL.md/prompt * instructs it to ALWAYS use MCP discord tools for output. * - Timeout responses (ETIMEDOUT) should preserve session state * because the agent may still be processing. * * @returns Normalized AgentResult with content, isError, and sessionId */ private _processAgentResponse; /** Status d'un agent en cours */ agentStatus(options: AgentControlOptions): Promise<AgentResult>; /** Kill un agent */ killAgent(agentName: string, runner?: RunnerType): Promise<AgentResult>; /** Recherche sémantique dans la mémoire Overmind */ memorySearch(options: MemorySearchOptions): Promise<AgentResult>; /** Stocke une connaissance dans la mémoire Overmind */ memoryStore(options: MemoryStoreOptions): Promise<AgentResult>; /** Historique et statistiques des runs en mémoire */ memoryRuns(options?: MemoryRunsOptions): Promise<AgentResult>; /** Liste tous les agents disponibles */ listAgents(details?: boolean): Promise<AgentResult>; /** Crée un nouvel agent */ createAgent(name: string, runner: RunnerType, prompt: string, model?: string, copyEnvFrom?: string, mode?: string, cliPath?: string): Promise<AgentResult>; /** Supprime un agent */ deleteAgent(name: string): Promise<AgentResult>; /** Récupère la configuration détaillée d'un agent */ getAgentConfigs(name: string): Promise<AgentResult>; /** Met à jour la configuration d'un agent */ updateAgentConfig(options: UpdateAgentConfigOptions): Promise<AgentResult>; /** Crée ou écrase un fichier prompt */ createPrompt(options: CreatePromptOptions): Promise<AgentResult>; /** Modifie un prompt par recherche-remplacement */ editPrompt(options: EditPromptOptions): Promise<AgentResult>; /** Lance plusieurs agents en parallèle via run_agents_parallel */ runParallel(agents: Array<{ taskId?: string; runner: RunnerType; prompt: string; agentName: string; path?: string; model?: string; mode?: string; }>, waitAll?: boolean): Promise<AgentResult>; /** Recherche séquentielle groupée en mémoire */ batchSearch(queries: string[], agentName?: string, limit?: number): Promise<AgentResult[]>; /** Stockage séquentiel groupé en mémoire */ batchStore(texts: Array<{ text: string; source?: 'user' | 'agent' | 'pattern' | 'error' | 'decision'; }>, agentName?: string): Promise<AgentResult[]>; /** Appel MCP raw — pour les tools non wrappés */ rawCall(toolName: string, args: Record<string, unknown>, timeoutMs?: number): Promise<AgentResult>; } //# sourceMappingURL=OverBridgeService.d.ts.map