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
TypeScript
/**
* ╔══════════════════════════════════════════════════════════════════════╗
* ║ 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