overmind-mcp 3.5.2 โ†’ 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,892 +1,463 @@
1
- # ๐ŸŒ‰ Overmind Bridge โ€” Agents Persistants & A2A
1
+ # ๐ŸŒ‰ Architecture 6 Bridges Isolรฉs NEXUS โ€” Peer-to-Peer
2
2
 
3
- > **Version**: Overmind v3.5.0 โ€” `src/bridge/` (1928 lignes OverBridgeServer + 443 OverBridgeService + 259 AgentRegistry)
4
- > **Date**: 2026-07-09
5
- > **Source**: `src/bridge/OverBridgeServer.ts`, `src/bridge/OverBridgeService.ts`, `src/bridge/AgentRegistry.ts`, `src/bin/overmind-bridge.ts`, `discord_llm/src/overmind-bridge.ts`
3
+ > **Version**: NEXUS V17 โ€” Architecture corrigรฉe 2026-07-09
4
+ > **Pattern**: 6 processes `overmind-bridge` INDร‰PENDANTS, communication HTTP A2A inter-bridges
5
+ > **PAS de dispatcher central sur :3100** โ€” chaque bridge a son port, son agent, son .env, ses logs
6
6
 
7
7
  ---
8
8
 
9
- ## Table des Matiรจres
10
-
11
- 1. [Vue d'Ensemble](#vue-densemble)
12
- 2. [Architecture du Bridge](#architecture-du-bridge)
13
- 3. [Les 3 Couches de Persistance](#les-3-couches-de-persistance)
14
- 4. [AgentRegistry โ€” ร‰tat Live en Mรฉmoire](#agentregistry--รฉtat-live-en-mรฉmoire)
15
- 5. [SessionStore โ€” Sessions Multi-Tenant](#sessionstore--sessions-multi-tenant)
16
- 6. [MessageLog โ€” Persistence Postgres](#messagelog--persistence-postgres)
17
- 7. [JSON-RPC 2.0 โ€” Toutes les Mรฉthodes](#json-rpc-20--toutes-les-mรฉthodes)
18
- 8. [A2A โ€” Agent-to-Agent](#a2a--agent-to-agent)
19
- 9. [A2A Extended โ€” Broadcast, Pipeline, Fanout, Delegate, Query](#a2a-extended--broadcast-pipeline-fanout-delegate-query)
20
- 10. [Comment Construire un Agent Persistant (comme discord_llm)](#comment-construire-un-agent-persistant-comme-discord_llm)
21
- 11. [CLI overmind-bridge](#cli-overmind-bridge)
22
- 12. [Dรฉmarrer le Serveur Bridge](#dรฉmarrer-le-serveur-bridge)
9
+ ## โŒ Ce que ce n'est PAS
23
10
 
24
- ---
25
-
26
- ## Vue d'Ensemble
27
-
28
- L'Overmind Bridge est un **serveur HTTP JSON-RPC 2.0** qui transforme les appels MCP one-shot en conversations persistantes et multi-tenant. C'est la couche qui rend les agents "always-on" โ€” mรชme entre deux requรชtes Discord, l'รฉtat de l'agent (session, contexte, mรฉmoire) est prรฉservรฉ.
11
+ - โŒ Un seul `OverBridgeServer` partagรฉ sur :3100 qui dispatche
12
+ - โŒ Un `OvermindBridge` qui route les appels vers les 6 agents
13
+ - โŒ Un bridge "central" qui connaรฎt tous les agents
29
14
 
30
- ### Le Problรจme Rรฉsolu
15
+ ## โœ… Ce que c'est
31
16
 
32
- ```
33
- Sans Bridge:
34
- Discord !sniper โ†’ spawn hermes CLI โ†’ rรฉpond โ†’ meurt
35
- Discord !sniper โ†’ spawn hermes CLI โ†’ rรฉpond โ†’ meurt (perte de contexte!)
17
+ Chaque agent NEXUS = **un process `overmind-bridge server` autonome** avec :
18
+ - Son propre port dรฉdiรฉ
19
+ - Son agent dรฉdiรฉ (configurรฉ via flag)
20
+ - Son propre .env (clรฉs API, peers)
21
+ - Ses propres logs
22
+ - Ses propres clients HTTP vers les autres bridges
36
23
 
37
- Avec Bridge:
38
- Discord !sniper โ†’ POST /rpc agent.run โ†’ agent (session persistรฉe)
39
- Discord !sniper โ†’ POST /rpc agent.run โ†’ agent (MรŠME session, contexte conservรฉ!)
40
- ```
24
+ La communication A2A = **HTTP POST inter-bridges** : agent A veut parler ร  agent B โ†’ POST `http://localhost:<port_b>/rpc` avec `agent.run`.
41
25
 
42
26
  ---
43
27
 
44
- ## Architecture du Bridge
28
+ ## Allocation des Ports
45
29
 
46
- ```
47
- โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
48
- โ”‚ CLIENTS (Discord, curl, Python) โ”‚
49
- โ”‚ โ”‚
50
- โ”‚ discord_llm/overmind-bridge.ts overmind-bridge CLI โ”‚
51
- โ”‚ (Express, port 3001) (call, scenario, status) โ”‚
52
- โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
53
- โ”‚ POST /rpc โ”‚
54
- โ”‚ JSON-RPC 2.0 โ”‚
55
- โ–ผ โ–ผ
56
- โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
57
- โ”‚ OverBridgeServer (port 3100) โ”‚
58
- โ”‚ src/bridge/OverBridgeServer.ts โ”‚
59
- โ”‚ โ”‚
60
- โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
61
- โ”‚ โ”‚ dispatchRpc() โ€” route les mรฉthodes JSON-RPC โ”‚ โ”‚
62
- โ”‚ โ”‚ agent.run | agent.a2a | agent.broadcast | agent.pipeline โ”‚ โ”‚
63
- โ”‚ โ”‚ agent.fanout | agent.delegate | agent.query โ”‚ โ”‚
64
- โ”‚ โ”‚ agent.status | agent.list | agent.kill โ”‚ โ”‚
65
- โ”‚ โ”‚ message.history | message.get | message.replay | stats โ”‚ โ”‚
66
- โ”‚ โ”‚ session.get | session.list | session.delete | session.statsโ”‚ โ”‚
67
- โ”‚ โ”‚ webhook.sms | health.ping โ”‚ โ”‚
68
- โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
69
- โ”‚ โ”‚
70
- โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
71
- โ”‚ โ”‚ AgentRegistryโ”‚ โ”‚ SessionStore โ”‚ โ”‚ MessageLog (Postgres) โ”‚ โ”‚
72
- โ”‚ โ”‚ (in-memory) โ”‚ โ”‚ (JSON file) โ”‚ โ”‚ (bridge_messages table) โ”‚ โ”‚
73
- โ”‚ โ”‚ busy/idle โ”‚ โ”‚ externalKey โ”‚ โ”‚ from/to/prompt/response โ”‚ โ”‚
74
- โ”‚ โ”‚ mutex/agent โ”‚ โ”‚ โ†’ sessionId โ”‚ โ”‚ status: pendingโ†’done โ”‚ โ”‚
75
- โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
76
- โ”‚ โ”‚
77
- โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
78
- โ”‚ โ”‚ OverBridgeService (SDK wrapper) โ”‚ โ”‚
79
- โ”‚ โ”‚ โ†’ BridgeProxy โ†’ HTTP POST http://[::1]:3099/mcp โ”‚ โ”‚
80
- โ”‚ โ”‚ โ†’ Overmind MCP Server โ†’ HermesGatewayRunner โ†’ Gateway :8642 โ”‚ โ”‚
81
- โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
82
- โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
83
- ```
84
-
85
- ---
30
+ | Bridge # | Port | Agent | Runner | Script |
31
+ |----------|------|-------|--------|--------|
32
+ | #1 | **:3101** | `nexus_master` | hermes | `start-bridge-master.ps1` |
33
+ | #2 | **:3102** | `nexus_trader` | hermes | `start-bridge-trader.ps1` |
34
+ | #3 | **:3103** | `nexus_risk_manager` | hermes | `start-bridge-risk.ps1` |
35
+ | #4 | **:3104** | `nexus_healer` | hermes | `start-bridge-healer.ps1` |
36
+ | #5 | **:3105** | `nexus_researcher` | hermes | `start-bridge-researcher.ps1` |
37
+ | #6 | **:3106** | `nexus_publisher` | hermes | `start-bridge-publisher.ps1` |
86
38
 
87
- ## Les 3 Couches de Persistance
39
+ ## Services PARTAGร‰S (single instance, utilisรฉs par les 6 bridges)
88
40
 
89
- | Couche | Stockage | TTL | Rรดle |
90
- |--------|----------|-----|------|
91
- | **AgentRegistry** | In-memory (Map) | Session live | Mutex par agent (1 run ร  la fois), statut busy/idle/online |
92
- | **SessionStore** | JSON file (`~/.overmind/bridge/sessions.json`) | 4h | Map `externalKey` โ†’ `sessionId` (multi-tenant: 1 session par utilisateur Discord) |
93
- | **MessageLog** | PostgreSQL (`bridge_messages` table) | Permanent | Historique complet: from, to, prompt, response, status, timestamps |
41
+ | Service | Port | Pourquoi single |
42
+ |---------|------|------------------|
43
+ | **Overmind MCP Server** | :3099 | Routing centralisรฉ โ€” tous les bridges passent par lui pour `run_agent` |
44
+ | **Hermes Gateway API** | :8642 | `X-Hermes-Profile` header route vers le bon profil โ€” 1 process Python = 6 profils |
45
+ | **PostgreSQL** | :5432 | `MessageLog` partagรฉ โ€” tous les bridges รฉcrivent leurs A2A messages dans la mรชme table `bridge_messages` |
94
46
 
95
47
  ---
96
48
 
97
- ## AgentRegistry โ€” ร‰tat Live en Mรฉmoire
98
-
99
- **Source**: `src/bridge/AgentRegistry.ts`
100
-
101
- Tracke l'รฉtat live de chaque agent avec un **mutex par agent** pour sรฉrialiser les appels concurrents :
49
+ ## Topologie Rรฉseau
50
+
51
+ ```
52
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
53
+ โ”‚ 6 BRIDGES ISOLร‰S โ€” P2P โ”‚
54
+ โ”‚ โ”‚
55
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
56
+ โ”‚ โ”‚ :3101 โ”‚ โ”‚ :3102 โ”‚ โ”‚ :3103 โ”‚ โ”‚
57
+ โ”‚ โ”‚ nexus_master โ”‚โ—„โ”€โ”€โ–บโ”‚ nexus_trader โ”‚โ—„โ”€โ”€โ–บโ”‚ nexus_risk_mgr โ”‚ โ”‚
58
+ โ”‚ โ”‚ bridge.ts โ”‚ โ”‚ bridge.ts โ”‚ โ”‚ bridge.ts โ”‚ โ”‚
59
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
60
+ โ”‚ โ”‚ HTTP A2A โ”‚ HTTP A2A โ”‚ HTTP A2A โ”‚
61
+ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
62
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
63
+ โ”‚ โ”‚ :3104 โ”‚ โ”‚ :3105 โ”‚ โ”‚ :3106 โ”‚ โ”‚
64
+ โ”‚ โ”‚ nexus_healer โ”‚โ—„โ”€โ”€โ–บโ”‚ nexus_researcherโ”‚โ—„โ”€โ”€โ–บโ”‚ nexus_publisher โ”‚ โ”‚
65
+ โ”‚ โ”‚ bridge.ts โ”‚ โ”‚ bridge.ts โ”‚ โ”‚ bridge.ts โ”‚ โ”‚
66
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
67
+ โ”‚ โ”‚
68
+ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
69
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
70
+ โ”‚ โ”‚ โ”‚
71
+ โ”‚ โ–ผ โ”‚
72
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
73
+ โ”‚ โ”‚ SERVICES PARTAGร‰S (single) โ”‚ โ”‚
74
+ โ”‚ โ”‚ โ€ข :3099 Overmind MCP Server โ”‚ โ”‚
75
+ โ”‚ โ”‚ โ€ข :8642 Hermes Gateway API โ”‚ โ”‚
76
+ โ”‚ โ”‚ โ€ข :5432 PostgreSQL (MessageLog) โ”‚ โ”‚
77
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
78
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
79
+ ```
80
+
81
+ ### Pattern de Communication
82
+
83
+ Quand `nexus_master` veut demander ร  `nexus_trader` d'exรฉcuter un trade :
102
84
 
103
85
  ```typescript
104
- interface AgentLiveState {
105
- name: string;
106
- runner: RunnerType;
107
- status: 'online' | 'offline' | 'busy' | 'idle';
108
- pid?: number;
109
- currentSessionId?: string; // Session en cours (si busy)
110
- lastActivityAt: number;
111
- totalRuns: number;
112
- totalErrors: number;
113
- a2aReceived: number; // Compteur A2A reรงu
114
- a2aSent: number; // Compteur A2A envoyรฉ
115
- }
116
- ```
117
-
118
- ### Mutex โ€” 1 Run ร  la Fois par Agent
119
-
120
- ```typescript
121
- // Si agent "trader_btc" est dรฉjร  en train de tourner,
122
- // le 2e appel attend que le 1er termine.
123
- await this.registry.withLock('trader_btc', async () => {
124
- this.registry.markBusy('trader_btc', sessionId);
125
- const result = await this.service.runAgent({ ... });
126
- this.registry.markIdle('trader_btc', !result.isError);
127
- return result;
128
- });
129
- ```
130
-
131
- ### Mรฉthodes Disponibles
132
-
133
- | Mรฉthode | Description |
134
- |---------|-------------|
135
- | `register(name, runner)` | Enregistre l'agent dans le registry |
136
- | `markBusy(name, sessionId)` | Marque comme occupรฉ (run en cours) |
137
- | `markIdle(name, success)` | Marque comme libre + incrรฉmente compteurs |
138
- | `markOnline(name)` | Marque comme en ligne |
139
- | `markOffline(name)` | Marque comme hors ligne |
140
- | `get(name)` | Retourne l'รฉtat live complet |
141
- | `list({ status, runner })` | Liste filtrรฉe des agents |
142
- | `stats()` | Stats globales (total, busy, idle, online) |
143
- | `incrementA2aSent(name)` | Incrรฉmente le compteur A2A envoyรฉ |
144
- | `incrementA2aReceived(name)` | Incrรฉmente le compteur A2A reรงu |
145
- | `prune(maxAgeMs)` | Nettoie les agents offline > 24h (auto toutes les 6h) |
146
-
147
- ---
148
-
149
- ## SessionStore โ€” Sessions Multi-Tenant
150
-
151
- **Source**: `src/bridge/SessionStore.ts`
152
-
153
- Le **multi-tenant** : chaque utilisateur externe a sa propre session persistante avec l'agent.
154
-
155
- ### Comment รงa Marche
156
-
157
- ```
158
- Utilisateur Discord A (!sniper analyse BTC)
159
- โ†’ externalKey = "discord_user_123"
160
- โ†’ SessionStore.get("discord_user_123", "sniperbot_analyst")
161
- โ†’ sessionId = "abc-123" (session restaurรฉe!)
162
- โ†’ runAgent avec sessionId="abc-123"
163
- โ†’ SessionStore.set("discord_user_123", "sniperbot_analyst", "abc-123")
164
-
165
- Utilisateur Discord B (!sniper analyse ETH)
166
- โ†’ externalKey = "discord_user_456"
167
- โ†’ SessionStore.get("discord_user_456", "sniperbot_analyst")
168
- โ†’ pas de session โ†’ nouvelle session
169
- โ†’ sessionId = "def-456"
170
- ```
171
-
172
- ### Persistence
173
-
174
- ```json
175
- // ~/.overmind/bridge/sessions.json
176
- {
177
- "discord_user_123:sniperbot_analyst": {
178
- "externalKey": "discord_user_123",
179
- "agentName": "sniperbot_analyst",
180
- "runner": "hermes",
181
- "sessionId": "abc-123",
182
- "context": { "lastTopic": "BTC", "language": "fr" },
183
- "createdAt": "2026-07-09T18:00:00Z",
184
- "updatedAt": "2026-07-09T18:05:00Z"
86
+ // Dans bridges/nexus_master/src/clients/MasterToTrader.ts
87
+ import { BridgeClient } from '@nexus/bridge-common';
88
+
89
+ export class MasterToTrader {
90
+ private client = new BridgeClient('http://127.0.0.1:3102');
91
+
92
+ async requestTrade(symbol: string, action: 'buy' | 'sell', size: number) {
93
+ return this.client.call('agent.run', {
94
+ agentName: 'nexus_trader',
95
+ runner: 'hermes',
96
+ prompt: `Exรฉcute trade: ${action} ${size} ${symbol}`,
97
+ externalKey: 'master_to_trader',
98
+ });
185
99
  }
186
100
  }
187
101
  ```
188
102
 
189
- ### TTL et Cleanup
190
-
191
- - TTL par dรฉfaut: **4h** (`sessionTtlMs: 4 * 60 * 60 * 1000`)
192
- - Cleanup automatique toutes les **5min** (`cleanupIntervalMs`)
193
- - Sessions expirรฉes โ†’ supprimรฉes du fichier
194
-
195
- ### Directives โ€” L'Agent Peut Mettre ร  Jour Sa Session
196
-
197
- Quand `enableDirectives: true`, l'agent peut รฉmettre des directives dans sa rรฉponse :
198
-
199
- ```
200
- SESSION_ID: new-session-xyz โ†’ met ร  jour le sessionId
201
- CONTEXT_UPDATE: {"lastTopic": "ETH"} โ†’ patch le contexte
202
- BRIDGE_HINT: "Analyse terminรฉe" โ†’ log seulement
203
- ```
204
-
205
- Le `DirectiveParser` (`src/bridge/DirectiveParser.ts`) parse ces directives, les applique au SessionStore, et les retire du texte visible par l'utilisateur.
206
-
207
- ---
208
-
209
- ## MessageLog โ€” Persistence Postgres
210
-
211
- **Source**: `src/bridge/MessageLog.ts`
212
-
213
- Historique permanent de tous les messages A2A et agent.run dans PostgreSQL.
214
-
215
- ### Schรฉma de Table
216
-
217
- ```sql
218
- CREATE TABLE bridge_messages (
219
- id UUID PRIMARY KEY,
220
- from_agent VARCHAR(255), -- NULL si client externe
221
- to_agent VARCHAR(255) NOT NULL,
222
- runner VARCHAR(50) NOT NULL,
223
- prompt TEXT NOT NULL,
224
- response TEXT,
225
- session_id VARCHAR(255),
226
- status VARCHAR(20) DEFAULT 'pending', -- pending โ†’ running โ†’ done/failed/timeout
227
- metadata JSONB,
228
- created_at TIMESTAMPTZ DEFAULT NOW(),
229
- updated_at TIMESTAMPTZ DEFAULT NOW()
230
- );
231
-
232
- CREATE INDEX idx_bridge_messages_to_agent ON bridge_messages(to_agent, created_at DESC);
233
- CREATE INDEX idx_bridge_messages_from_agent ON bridge_messages(from_agent, created_at DESC);
234
- CREATE INDEX idx_bridge_messages_status ON bridge_messages(status);
235
- ```
236
-
237
- ### Cycle de Vie d'un Message
238
-
239
- ```
240
- agent.run appelรฉ
241
- โ†’ messageLog.create() โ†’ status: "pending"
242
- โ†’ messageLog.markRunning() โ†’ status: "running"
243
- โ†’ agent termine...
244
- โ†’ succรจs: messageLog.markDone() โ†’ status: "done", response sauvegardรฉe
245
- โ†’ erreur: messageLog.markFailed() โ†’ status: "failed", error sauvegardรฉ
246
- โ†’ timeout: messageLog.markTimeout() โ†’ status: "timeout"
247
- ```
248
-
249
- ### Replay
250
-
251
- ```bash
252
- # Rejouer un message (re-run avec le mรชme prompt)
253
- curl -X POST http://localhost:3100/rpc \
254
- -d '{"jsonrpc":"2.0","id":1,"method":"message.replay","params":{"id":"7f3e8a1b-..."}}'
255
- ```
103
+ **Flow** :
104
+ 1. `nexus_master` (port 3101) reรงoit une requรชte externe
105
+ 2. Il appelle `MasterToTrader.requestTrade()`
106
+ 3. `BridgeClient` fait `POST http://127.0.0.1:3102/rpc`
107
+ 4. Le bridge `nexus_trader` (port 3102) reรงoit, exรฉcute via MCP
108
+ 5. Rรฉponse remontรฉe : `nexus_trader` โ†’ `nexus_master` โ†’ client externe
256
109
 
257
110
  ---
258
111
 
259
- ## JSON-RPC 2.0 โ€” Toutes les Mรฉthodes
260
-
261
- ### Endpoint
262
-
112
+ ## Arborescence des Bridges
113
+
114
+ ```
115
+ C:\Users\Deamon\Nexus\
116
+ โ”‚
117
+ โ”œโ”€โ”€ bridges/ โ† 6 WRAPPERS ISOLร‰S (un par agent)
118
+ โ”‚ โ”‚
119
+ โ”‚ โ”œโ”€โ”€ nexus_master/ โ† Bridge #1 (:3101)
120
+ โ”‚ โ”‚ โ”œโ”€โ”€ package.json โ† name: @nexus/bridge-master, dep: overmind-mcp
121
+ โ”‚ โ”‚ โ”œโ”€โ”€ tsconfig.json
122
+ โ”‚ โ”‚ โ”œโ”€โ”€ .env โ† AGENT_NAME, BRIDGE_PORT=3101, peers URLs
123
+ โ”‚ โ”‚ โ”œโ”€โ”€ README.md
124
+ โ”‚ โ”‚ โ”œโ”€โ”€ src/
125
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ bridge.ts โ† Entry point โ€” lance OverBridgeServer
126
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ config.ts โ† Lit .env + export config typรฉe
127
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ logger.ts โ† Pino logger dรฉdiรฉ
128
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ startup.ts โ† init MessageLog + SessionStore + connect MCP
129
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ clients/
130
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ MasterToTrader.ts โ† POST :3102/rpc
131
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ MasterToRisk.ts โ† POST :3103/rpc
132
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ MasterToResearcher.ts โ† POST :3105/rpc
133
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ MasterToPublisher.ts โ† POST :3106/rpc
134
+ โ”‚ โ”‚ โ”œโ”€โ”€ logs/
135
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ bridge-master.log
136
+ โ”‚ โ”‚ โ””โ”€โ”€ dist/ โ† Compilรฉ
137
+ โ”‚ โ”‚
138
+ โ”‚ โ”œโ”€โ”€ nexus_trader/ โ† Bridge #2 (:3102)
139
+ โ”‚ โ”‚ โ”œโ”€โ”€ package.json โ† name: @nexus/bridge-trader
140
+ โ”‚ โ”‚ โ”œโ”€โ”€ .env โ† BRIDGE_PORT=3102
141
+ โ”‚ โ”‚ โ”œโ”€โ”€ src/
142
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ bridge.ts
143
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ clients/
144
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ TraderToMaster.ts โ† POST :3101/rpc (comm au maรฎtre)
145
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ TraderToRisk.ts โ† POST :3103/rpc (check risk)
146
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ TraderToPublisher.ts โ† POST :3106/rpc (publier trade)
147
+ โ”‚ โ”‚ โ””โ”€โ”€ ...
148
+ โ”‚ โ”‚
149
+ โ”‚ โ”œโ”€โ”€ nexus_risk_manager/ โ† Bridge #3 (:3103)
150
+ โ”‚ โ”‚ โ””โ”€โ”€ ...
151
+ โ”‚ โ”œโ”€โ”€ nexus_healer/ โ† Bridge #4 (:3104)
152
+ โ”‚ โ”‚ โ””โ”€โ”€ ...
153
+ โ”‚ โ”œโ”€โ”€ nexus_researcher/ โ† Bridge #5 (:3105)
154
+ โ”‚ โ”‚ โ””โ”€โ”€ ...
155
+ โ”‚ โ””โ”€โ”€ nexus_publisher/ โ† Bridge #6 (:3106)
156
+ โ”‚ โ””โ”€โ”€ ...
157
+ โ”‚
158
+ โ”œโ”€โ”€ common/ โ† PARTAGร‰ entre les 6 bridges
159
+ โ”‚ โ”œโ”€โ”€ package.json โ† name: @nexus/bridge-common
160
+ โ”‚ โ”œโ”€โ”€ src/
161
+ โ”‚ โ”‚ โ”œโ”€โ”€ BaseBridge.ts โ† Classe abstraite โ€” factorise le boot
162
+ โ”‚ โ”‚ โ”œโ”€โ”€ BridgeClient.ts โ† Client HTTP vers un autre bridge
163
+ โ”‚ โ”‚ โ”œโ”€โ”€ types.ts โ† Interfaces partagรฉes
164
+ โ”‚ โ”‚ โ””โ”€โ”€ logger.ts โ† Pino config commune
165
+ โ”‚ โ””โ”€โ”€ dist/
166
+ โ”‚
167
+ โ”œโ”€โ”€ profiles/ โ† Profils Hermes (existants)
168
+ โ”‚ โ”œโ”€โ”€ nexus_master/{config.yaml,SOUL.md,.env,memories/,sessions/}
169
+ โ”‚ โ”œโ”€โ”€ nexus_trader/
170
+ โ”‚ โ”œโ”€โ”€ nexus_risk_manager/
171
+ โ”‚ โ”œโ”€โ”€ nexus_healer/
172
+ โ”‚ โ”œโ”€โ”€ nexus_researcher/
173
+ โ”‚ โ””โ”€โ”€ nexus_publisher/
174
+ โ”‚
175
+ โ”œโ”€โ”€ shared-infra/ โ† SERVICES PARTAGร‰S (dรฉjร  en prod)
176
+ โ”‚ โ”œโ”€โ”€ mcp-server/ โ† Overmind MCP :3099
177
+ โ”‚ โ”œโ”€โ”€ hermes-gateway/ โ† Gateway :8642
178
+ โ”‚ โ””โ”€โ”€ postgres/ โ† :5432
179
+ โ”‚
180
+ โ”œโ”€โ”€ scripts/ โ† SCRIPTS DE GESTION
181
+ โ”‚ โ”œโ”€โ”€ start-all-bridges.ps1 โ† Dรฉmarre les 6 en parallรจle (Start-Job)
182
+ โ”‚ โ”œโ”€โ”€ stop-all-bridges.ps1
183
+ โ”‚ โ”œโ”€โ”€ status-bridges.ps1
184
+ โ”‚ โ”œโ”€โ”€ seed-bridges.ps1 โ† Crรฉe dossiers + .env pour les 6
185
+ โ”‚ โ””โ”€โ”€ test-a2a-network.ps1 โ† Test E2E inter-bridges
186
+ โ”‚
187
+ โ””โ”€โ”€ logs/
188
+ โ”œโ”€โ”€ bridges/
189
+ โ”‚ โ”œโ”€โ”€ nexus_master.log
190
+ โ”‚ โ”œโ”€โ”€ nexus_trader.log
191
+ โ”‚ โ”œโ”€โ”€ nexus_risk_manager.log
192
+ โ”‚ โ”œโ”€โ”€ nexus_healer.log
193
+ โ”‚ โ”œโ”€โ”€ nexus_researcher.log
194
+ โ”‚ โ””โ”€โ”€ nexus_publisher.log
195
+ โ””โ”€โ”€ network/
196
+ โ””โ”€โ”€ a2a-traffic.log
263
197
  ```
264
- POST /rpc
265
- Content-Type: application/json
266
- Authorization: Bearer <token> (optionnel si authToken configurรฉ)
267
-
268
- # Single request
269
- {"jsonrpc":"2.0","id":1,"method":"agent.run","params":{...}}
270
-
271
- # Batch (parallรจle)
272
- [
273
- {"jsonrpc":"2.0","id":1,"method":"agent.run","params":{...}},
274
- {"jsonrpc":"2.0","id":2,"method":"agent.list","params":{}}
275
- ]
276
- ```
277
-
278
- ### Mรฉthodes Disponibles (24 mรฉthodes)
279
-
280
- #### Agents (10 mรฉthodes)
281
-
282
- | Mรฉthode | Params Requis | Params Optionnels | Description |
283
- |---------|---------------|-------------------|-------------|
284
- | `agent.run` | `agentName`, `runner`, `prompt` | `sessionId`, `path`, `model`, `mode`, `silent`, `externalKey`, `parseDirectives`, `metadata` | Lance un agent |
285
- | `agent.a2a` | `fromAgent`, `toAgent`, `runner`, `prompt` | `model`, `path`, `metadata` | Agent A parle ร  Agent B |
286
- | `agent.broadcast` | `fromAgent`, `runner`, `prompt` | `targets[]`, `race`, `agentTimeoutMs`, `model` | Fan-out global |
287
- | `agent.pipeline` | `initiator`, `runner`, `prompt`, `steps[]` | `accumulateContext`, `totalTimeoutMs` | Chaรฎne Aโ†’Bโ†’C |
288
- | `agent.fanout` | `fromAgent`, `runner`, `prompt`, `targets[]` | `mergeStrategy`, `agentTimeoutMs`, `model` | 1โ†’N + merge |
289
- | `agent.delegate` | `fromAgent`, `toAgent`, `runner`, `prompt` | `async`, `callbackUrl`, `model` | Fire-and-forget |
290
- | `agent.query` | `fromAgent`, `runner`, `prompt`, `targets[]` | `agentTimeoutMs`, `model` | Query multi-agents |
291
- | `agent.status` | `agentName` | `runner`, `action`, `sinceTimestamp`, `timeoutMs` | Status live |
292
- | `agent.list` | โ€” | `status`, `runner` | Liste des agents |
293
- | `agent.kill` | `agentName` | `runner` | Kill un agent |
294
-
295
- #### Messages (4 mรฉthodes)
296
-
297
- | Mรฉthode | Params | Description |
298
- |---------|--------|-------------|
299
- | `message.history` | `toAgent?`, `fromAgent?`, `status?`, `limit?`, `offset?`, `sinceHours?` | Historique paginรฉ |
300
- | `message.get` | `id` (UUID) | Rรฉcupรจre un message |
301
- | `message.replay` | `id` (UUID) | Rejoue un message |
302
- | `message.stats` | โ€” | Stats globales |
303
-
304
- #### Sessions (4 mรฉthodes)
305
-
306
- | Mรฉthode | Params | Description |
307
- |---------|--------|-------------|
308
- | `session.get` | `externalKey`, `agentName` | Session d'un utilisateur |
309
- | `session.list` | โ€” | Toutes les sessions |
310
- | `session.delete` | `externalKey`, `agentName` | Supprime une session |
311
- | `session.stats` | โ€” | Stats des sessions |
312
-
313
- #### Autres (6 mรฉthodes)
314
-
315
- | Mรฉthode | Description |
316
- |---------|-------------|
317
- | `health.ping` | Liveness check |
318
- | `webhook.sms` | Adapt + auto-dispatch webhook SMS |
319
- | `GET /health` | Healthcheck enrichi (hors RPC) |
320
- | `POST /webhook/:provider` | Webhook HTTP (voipms, twilio, discord) |
321
- | `GET /f/:filename` | Static file serve |
322
- | `OPTIONS *` | CORS preflight |
323
198
 
324
199
  ---
325
200
 
326
- ## A2A โ€” Agent-to-Agent
327
-
328
- ### Principe
201
+ ## Fichiers Clรฉs
329
202
 
330
- Agent A envoie un message ร  Agent B. Le bridge :
331
- 1. Enrichit le prompt avec un header A2A standardisรฉ
332
- 2. Persiste le message dans MessageLog (from=A, to=B)
333
- 3. Incrรฉmente les compteurs A2A (sent pour A, received pour B)
334
- 4. Exรฉcute B sous mutex (sรฉrialise les appels concurrents vers B)
335
- 5. Retourne la rรฉponse de B ร  A
336
-
337
- ### Format du Prompt A2A
338
-
339
- ```
340
- [A2A โ€” Agent-to-Agent Message]
341
- FROM: trader_btc
342
- TO: analyst_eth
343
- TIMESTAMP: 2026-07-09T18:30:00.000Z
344
- โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
345
- Valide mon analyse : le BTC va casser les 100k dans 48h
346
- ```
347
-
348
- ### Exemple curl
203
+ ### 1. `bridges/nexus_master/.env`
349
204
 
350
205
  ```bash
351
- curl -X POST http://localhost:3100/rpc \
352
- -H "Content-Type: application/json" \
353
- -d '{
354
- "jsonrpc": "2.0",
355
- "id": 1,
356
- "method": "agent.a2a",
357
- "params": {
358
- "fromAgent": "trader_btc",
359
- "toAgent": "analyst_eth",
360
- "runner": "hermes",
361
- "prompt": "Valide mon analyse : le BTC va casser les 100k dans 48h"
362
- }
363
- }'
364
- ```
206
+ # === Bridge :3101 โ€” nexus_master ===
207
+ AGENT_NAME=nexus_master
208
+ RUNNER=hermes
209
+ BRIDGE_PORT=3101
210
+ BRIDGE_HOST=127.0.0.1
211
+
212
+ # Upstream (services partagรฉs)
213
+ MCP_URL=http://[::1]:3099/mcp
214
+ HERMES_GATEWAY_URL=http://127.0.0.1:8642
215
+ HERMES_GATEWAY_KEY=hIhOKpVn3AgfW_sQO8XShjMb8YRhaZngSSv6UsWY0dc
216
+ POSTGRES_HOST=localhost
217
+ POSTGRES_DB=overmind
218
+ POSTGRES_USER=overmind
219
+ POSTGRES_PASSWORD=***
220
+
221
+ # Peers (autres bridges)
222
+ PEER_TRADER_URL=http://127.0.0.1:3102
223
+ PEER_RISK_URL=http://127.0.0.1:3103
224
+ PEER_HEALER_URL=http://127.0.0.1:3104
225
+ PEER_RESEARCHER_URL=http://127.0.0.1:3105
226
+ PEER_PUBLISHER_URL=http://127.0.0.1:3106
227
+
228
+ # Session config
229
+ SESSION_TTL_MS=14400000
230
+ MESSAGE_LOG_ENABLED=true
231
+ DIRECTIVES_ENABLED=true
232
+ ```
233
+
234
+ ### 2. `common/src/BaseBridge.ts` (partagรฉ)
365
235
 
366
- ### Rรฉponse
367
-
368
- ```json
369
- {
370
- "jsonrpc": "2.0",
371
- "id": 1,
372
- "result": {
373
- "messageId": "7f3e8a1b-...",
374
- "from": "trader_btc",
375
- "to": "analyst_eth",
376
- "sessionId": "api-abc123",
377
- "content": [{ "type": "text", "text": "Je valide avec conviction 75..." }],
378
- "isError": false
379
- }
236
+ ```typescript
237
+ import {
238
+ OverBridgeServer,
239
+ OverBridgeService,
240
+ loadMessageLogConfigFromEnv,
241
+ createBridgeLogger,
242
+ } from 'overmind-mcp/bridge';
243
+ import { BridgeClient } from './BridgeClient.js';
244
+
245
+ export interface BaseBridgeConfig {
246
+ agentName: string;
247
+ port: number;
248
+ host: string;
249
+ mcpUrl: string;
250
+ logger: any;
380
251
  }
381
- ```
382
-
383
- ---
384
-
385
- ## A2A Extended โ€” Broadcast, Pipeline, Fanout, Delegate, Query
386
-
387
- ### 1. Broadcast โ€” 1 โ†’ Tous (Fan-out Global)
388
-
389
- Un agent envoie un message ร  tous les agents online (ou ร  une liste cible).
390
-
391
- ```bash
392
- curl -X POST http://localhost:3100/rpc \
393
- -d '{
394
- "jsonrpc": "2.0", "id": 1,
395
- "method": "agent.broadcast",
396
- "params": {
397
- "fromAgent": "commander",
398
- "runner": "hermes",
399
- "prompt": "Alerte marchรฉ : BTC drop 5%",
400
- "race": false,
401
- "agentTimeoutMs": 60000
402
- }
403
- }'
404
- ```
405
-
406
- - `race: true` โ†’ retourne dรจs qu'un agent rรฉpond (premier qui gagne)
407
- - `race: false` โ†’ attend tous les agents
408
- - Si `targets` absent โ†’ tous les agents `online` (excluant l'รฉmetteur)
409
-
410
- ### 2. Pipeline โ€” Chaรฎne Sรฉquentielle Aโ†’Bโ†’C
411
-
412
- L'output de chaque step devient l'input du suivant.
413
-
414
- ```bash
415
- curl -X POST http://localhost:3100/rpc \
416
- -d '{
417
- "jsonrpc": "2.0", "id": 1,
418
- "method": "agent.pipeline",
419
- "params": {
420
- "initiator": "commander",
421
- "runner": "hermes",
422
- "prompt": "Analyse le marchรฉ BTC actuel",
423
- "steps": [
424
- { "agentName": "data_collector", "promptPrefix": "Rรฉcupรจre les donnรฉes:" },
425
- { "agentName": "analyst", "promptPrefix": "Analyse ces donnรฉes:" },
426
- { "agentName": "strategist", "promptPrefix": "Propose une stratรฉgie:" }
427
- ],
428
- "accumulateContext": true,
429
- "totalTimeoutMs": 3600000
430
- }
431
- }'
432
- ```
433
-
434
- - `accumulateContext: true` โ†’ chaque step reรงoit TOUS les outputs prรฉcรฉdents
435
- - `accumulateContext: false` โ†’ chaque step ne reรงoit que le dernier output
436
- - Timeout global avec deadline check ร  chaque step
437
-
438
- ### 3. Fanout โ€” 1 โ†’ N Parallรจle + Merge
439
252
 
440
- Un agent demande ร  plusieurs agents en parallรจle, puis merge les rรฉsultats.
441
-
442
- ```bash
443
- curl -X POST http://localhost:3100/rpc \
444
- -d '{
445
- "jsonrpc": "2.0", "id": 1,
446
- "method": "agent.fanout",
447
- "params": {
448
- "fromAgent": "commander",
449
- "runner": "hermes",
450
- "prompt": "Quelle stratรฉgie pour le BTC?",
451
- "targets": ["analyst_1", "analyst_2", "analyst_3"],
452
- "mergeStrategy": "best"
453
- }
454
- }'
455
- ```
456
-
457
- Stratรฉgies de merge :
458
-
459
- | Stratรฉgie | Description |
460
- |-----------|-------------|
461
- | `concat` | Concatรจne toutes les rรฉponses (dรฉfaut) |
462
- | `best` | Sรฉlectionne la plus longue rรฉponse |
463
- | `vote` | Vote par bucket de taille (100 chars) |
464
- | `first_success` | Premier qui rรฉussit |
465
-
466
- ### 4. Delegate โ€” Fire-and-Forget Async
467
-
468
- Dรฉlรจgue une tรขche ร  un agent de faรงon asynchrone. Retourne immรฉdiatement avec un `taskId`.
469
-
470
- ```bash
471
- curl -X POST http://localhost:3100/rpc \
472
- -d '{
473
- "jsonrpc": "2.0", "id": 1,
474
- "method": "agent.delegate",
475
- "params": {
476
- "fromAgent": "commander",
477
- "toAgent": "researcher",
478
- "runner": "hermes",
479
- "prompt": "Recherche l'historique des crashes BTC 2024",
480
- "async": true,
481
- "callbackUrl": "https://myapp.com/webhook/agent-done"
482
- }
483
- }'
484
- ```
485
-
486
- - `async: true` โ†’ retourne immรฉdiatement avec `taskId`
487
- - `callbackUrl` โ†’ POST le rรฉsultat quand l'agent termine
488
- - L'agent peut รชtre suivi via `agent.status(agentName: "researcher")`
489
-
490
- ### 5. Query โ€” Multi-Agent Read-Only
253
+ export abstract class BaseBridge {
254
+ protected service: OverBridgeService;
255
+ protected server: OverBridgeServer;
256
+
257
+ constructor(protected config: BaseBridgeConfig) {
258
+ this.service = new OverBridgeService({
259
+ mcpUrl: config.mcpUrl,
260
+ defaultTimeoutMs: 60_000,
261
+ agentTimeoutMs: 2_700_000,
262
+ maxRetries: 2,
263
+ }, config.logger);
264
+
265
+ this.server = new OverBridgeServer(this.service, {
266
+ port: config.port,
267
+ host: config.host,
268
+ postgres: loadMessageLogConfigFromEnv(),
269
+ enableMessageLog: true,
270
+ enableSessionStore: true,
271
+ enableDirectives: true,
272
+ sessionTtlMs: 4 * 60 * 60 * 1000,
273
+ rateLimitMax: 200,
274
+ sanitizeJson: true,
275
+ }, config.logger);
276
+ }
491
277
 
492
- Comme fanout mais optimisรฉ pour des rรฉponses courtes et rapides.
278
+ abstract getClients(): BridgeClient[];
493
279
 
494
- ```bash
495
- curl -X POST http://localhost:3100/rpc \
496
- -d '{
497
- "jsonrpc": "2.0", "id": 1,
498
- "method": "agent.query",
499
- "params": {
500
- "fromAgent": "commander",
501
- "runner": "hermes",
502
- "prompt": "Prix actuel du BTC?",
503
- "targets": ["price_bot_1", "price_bot_2"],
504
- "agentTimeoutMs": 30000
280
+ async start(): Promise<void> {
281
+ await this.server.start();
282
+ this.config.logger.info(`๐Ÿš€ Bridge ${this.config.agentName} ready on :${this.config.port}`);
283
+ for (const client of this.getClients()) {
284
+ await client.healthCheck();
505
285
  }
506
- }'
507
- ```
508
-
509
- ---
510
-
511
- ## Comment Construire un Agent Persistant (comme discord_llm)
512
-
513
- `discord_llm` est l'exemple canonique d'un client persistant du bridge. Voici le pattern complet :
514
-
515
- ### Architecture discord_llm
286
+ }
516
287
 
517
- ```
518
- โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
519
- โ”‚ discord_llm/ (package: discord-claude-bridge v3.5.0) โ”‚
520
- โ”‚ โ”‚
521
- โ”‚ startpipeline.ts โ†’ PipelineManager โ”‚
522
- โ”‚ โ”œโ”€โ”€ spawn overmind-bridge.ts (Express :3001) โ”‚
523
- โ”‚ โ”‚ โ”œโ”€โ”€ OverBridgeService (SDK wrapper) โ”‚
524
- โ”‚ โ”‚ โ”œโ”€โ”€ BridgeProxy โ†’ HTTP [::1]:3099/mcp โ”‚
525
- โ”‚ โ”‚ โ”œโ”€โ”€ SessionStore (multi-tenant, JSON file) โ”‚
526
- โ”‚ โ”‚ โ””โ”€โ”€ WebhookAdapter (voipms, twilio, discord) โ”‚
527
- โ”‚ โ”‚ โ”‚
528
- โ”‚ โ””โ”€โ”€ spawn discord-bot.ts (Discord.js) โ”‚
529
- โ”‚ โ”œโ”€โ”€ reรงoit !sniper <message> โ”‚
530
- โ”‚ โ””โ”€โ”€ POST localhost:3001/send โ”‚
531
- โ”‚ โ†’ OverBridgeService.runAgentForDiscord() โ”‚
532
- โ”‚ โ†’ BridgeProxy โ†’ MCP :3099 โ”‚
533
- โ”‚ โ†’ HermesGatewayRunner โ†’ Gateway :8642 โ”‚
534
- โ”‚ โ†’ rรฉponse โ†’ Discord โ”‚
535
- โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
288
+ async stop(): Promise<void> {
289
+ await this.server.stop();
290
+ }
291
+ }
536
292
  ```
537
293
 
538
- ### ร‰tape 1 : Importer le SDK Overmind
294
+ ### 3. `bridges/nexus_master/src/bridge.ts`
539
295
 
540
296
  ```typescript
541
- // Import depuis overmind-mcp (package npm ou file:../Workflow)
542
- import {
543
- OverBridgeService, // SDK haut niveau (runAgent, sessions, heartbeat)
544
- SessionStore, // Multi-tenant (externalKey โ†’ sessionId)
545
- WebhookAdapter, // Adaptation webhooks (SMS, Discord, Twilio)
546
- BridgeProxy, // Low-level MCP transport (HTTP JSON-RPC)
547
- } from 'overmind-mcp/bridge';
297
+ import { BaseBridge } from '@nexus/bridge-common';
298
+ import { config } from './config.js';
299
+ import { MasterToTrader } from './clients/MasterToTrader.js';
300
+ import { MasterToRisk } from './clients/MasterToRisk.js';
301
+ import { MasterToResearcher } from './clients/MasterToResearcher.js';
302
+ import { MasterToPublisher } from './clients/MasterToPublisher.js';
303
+ import { logger } from './logger.js';
304
+
305
+ class MasterBridge extends BaseBridge {
306
+ protected getClients() {
307
+ return [
308
+ new MasterToTrader(config.peerTraderUrl, logger),
309
+ new MasterToRisk(config.peerRiskUrl, logger),
310
+ new MasterToResearcher(config.peerResearcherUrl, logger),
311
+ new MasterToPublisher(config.peerPublisherUrl, logger),
312
+ ];
313
+ }
314
+ }
315
+
316
+ const bridge = new MasterBridge();
317
+ await bridge.start();
548
318
  ```
549
319
 
550
- ### ร‰tape 2 : Configurer le Bridge
320
+ ### 4. `bridges/nexus_master/src/clients/MasterToTrader.ts`
551
321
 
552
322
  ```typescript
553
- const OVERMIND_MCP_URL = process.env.OVERMIND_MCP_URL || 'http://localhost:3099/mcp';
554
- const AGENT_NAME = process.env.BRIDGE_AGENT || 'sniperbot_analyst';
555
- const RUNNER = 'hermes';
556
-
557
- // Low-level proxy โ†’ parle au MCP server
558
- const proxy = new BridgeProxy({
559
- mcpUrl: OVERMIND_MCP_URL,
560
- defaultTimeoutMs: 60_000,
561
- agentTimeoutMs: 2_700_000, // 45 min
562
- maxRetries: 2,
563
- retryDelayMs: 2_000,
564
- }, undefined, logger);
565
-
566
- // High-level service โ†’ session continuity + retry + circuit breaker
567
- const service = new OverBridgeService({
568
- mcpUrl: OVERMIND_MCP_URL,
569
- defaultTimeoutMs: 60_000,
570
- agentTimeoutMs: 2_700_000,
571
- maxRetries: 2,
572
- retryDelayMs: 2_000,
573
- }, logger);
574
-
575
- // Multi-tenant sessions
576
- const sessionStore = new SessionStore({
577
- persistPath: '~/.overmind/bridge/sessions.json',
578
- ttlMs: 4 * 60 * 60 * 1000, // 4h
579
- cleanupIntervalMs: 5 * 60 * 1000, // 5min
580
- }, logger);
581
-
582
- await sessionStore.init();
583
- ```
323
+ import { BridgeClient } from '@nexus/bridge-common';
584
324
 
585
- ### ร‰tape 3 : Exposer les Endpoints HTTP
325
+ export class MasterToTrader {
326
+ private client: BridgeClient;
586
327
 
587
- ```typescript
588
- import express from 'express';
589
- const app = express();
590
- app.use(express.json({ limit: '10mb' }));
591
-
592
- // โ”€โ”€โ”€ Route legacy (Discord bot) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
593
- app.post('/send', async (req, res) => {
594
- const { message, userId, username, channelId } = req.body;
595
-
596
- // Lance l'agent avec contexte Discord
597
- const result = await service.runAgentForDiscord(
598
- AGENT_NAME, RUNNER, message,
599
- { channelId, userId, username }
600
- );
601
-
602
- if (result.isError) {
603
- return res.status(500).json({ error: result.content.map(c => c.text).join('\n') });
328
+ constructor(traderUrl: string, logger: any) {
329
+ this.client = new BridgeClient(traderUrl, logger);
604
330
  }
605
331
 
606
- res.json({
607
- result: result.content.map(c => c.text).join('\n'),
608
- session_id: result.sessionId || service.sessionId,
609
- });
610
- });
611
-
612
- // โ”€โ”€โ”€ JSON-RPC 2.0 endpoint โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
613
- app.post('/rpc', async (req, res) => {
614
- const { method, params, id } = req.body;
615
-
616
- switch (method) {
617
- case 'agent.run':
618
- // Rรฉsolution sessionId via SessionStore
619
- let sessionId = params.sessionId;
620
- if (!sessionId && params.externalKey) {
621
- const stored = sessionStore.get(params.externalKey, params.agentName);
622
- if (stored) sessionId = stored.sessionId;
623
- }
624
-
625
- const result = await service.runAgent({
626
- agentName: params.agentName,
627
- runner: params.runner,
628
- prompt: params.prompt,
629
- sessionId,
630
- model: params.model,
631
- });
632
-
633
- // Sauvegarde sessionId pour cet utilisateur
634
- if (params.externalKey && result.sessionId) {
635
- sessionStore.set({
636
- externalKey: params.externalKey,
637
- agentName: params.agentName,
638
- runner: params.runner,
639
- sessionId: result.sessionId,
640
- });
641
- }
642
-
643
- return res.json({ jsonrpc: '2.0', id, result: {
644
- sessionId: result.sessionId,
645
- content: result.content,
646
- isError: result.isError,
647
- }});
648
-
649
- case 'agent.a2a':
650
- const enrichedPrompt = [
651
- `[A2A โ€” Agent-to-Agent Message]`,
652
- `FROM: ${params.fromAgent}`,
653
- `TO: ${params.toAgent}`,
654
- `TIMESTAMP: ${new Date().toISOString()}`,
655
- `โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”`,
656
- params.prompt,
657
- ].join('\n');
658
-
659
- const a2aResult = await service.runAgent({
660
- agentName: params.toAgent,
661
- runner: params.runner,
662
- prompt: enrichedPrompt,
663
- model: params.model,
664
- });
665
-
666
- return res.json({ jsonrpc: '2.0', id, result: {
667
- from: params.fromAgent,
668
- to: params.toAgent,
669
- sessionId: a2aResult.sessionId,
670
- content: a2aResult.content,
671
- isError: a2aResult.isError,
672
- }});
673
-
674
- case 'agent.list':
675
- const agents = await proxy.call('list_agents', { details: params.details });
676
- return res.json({ jsonrpc: '2.0', id, result: agents.result });
677
-
678
- case 'session.get':
679
- return res.json({ jsonrpc: '2.0', id, result: {
680
- session: sessionStore.get(params.externalKey, params.agentName) ?? null,
681
- }});
682
-
683
- case 'session.list':
684
- return res.json({ jsonrpc: '2.0', id, result: {
685
- sessions: sessionStore.list(),
686
- stats: sessionStore.stats(),
687
- }});
688
-
689
- case 'health.ping':
690
- return res.json({ jsonrpc: '2.0', id, result: { pong: true, ts: Date.now() }});
332
+ async requestTrade(symbol: string, action: 'buy' | 'sell', size: number): Promise<any> {
333
+ return this.client.call('agent.run', {
334
+ agentName: 'nexus_trader',
335
+ runner: 'hermes',
336
+ prompt: `Exรฉcute trade: ${action} ${size} ${symbol}`,
337
+ externalKey: 'master_to_trader',
338
+ });
691
339
  }
692
- });
693
-
694
- // โ”€โ”€โ”€ Health โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
695
- app.get('/health', async (_req, res) => {
696
- let mcpStatus = 'unknown';
697
- try {
698
- const health = await proxy.healthCheck();
699
- mcpStatus = health.status;
700
- } catch { mcpStatus = 'offline'; }
701
- res.json({
702
- status: 'ok',
703
- version: '5.1.0',
704
- mcp: { url: OVERMIND_MCP_URL, status: mcpStatus },
705
- sessions: sessionStore.stats(),
706
- });
707
- });
708
-
709
- app.listen(3001, () => logger.info('Bridge on :3001'));
710
- ```
711
-
712
- ### ร‰tape 4 : Dรฉmarrer le Pipeline
713
-
714
- ```typescript
715
- // startpipeline.ts โ€” orchestre bridge + bot
716
- class PipelineManager {
717
- async start() {
718
- // 1. Dรฉmarrer le bridge (HTTP server)
719
- this.bridgeProcess = spawn('node', ['dist/overmind-bridge.js']);
720
-
721
- // 2. Attendre qu'il soit prรชt
722
- await this.waitForBridge(); // GET /health jusqu'ร  200
723
340
 
724
- // 3. Dรฉmarrer le bot Discord
725
- this.discordProcess = spawn('node', ['dist/discord-bot.js']);
726
-
727
- // 4. Auto-restart du bot si crash (max 3 tentatives)
728
- this.discordProcess.on('exit', (code) => {
729
- if (!this.isShuttingDown) this.restartDiscordBot();
341
+ async askAnalysis(marketData: any): Promise<any> {
342
+ return this.client.call('agent.run', {
343
+ agentName: 'nexus_trader',
344
+ runner: 'hermes',
345
+ prompt: `Analyse ces donnรฉes: ${JSON.stringify(marketData)}`,
730
346
  });
731
347
  }
732
348
  }
733
349
  ```
734
350
 
735
- ### ร‰tape 5 : Configurer le .env
736
-
737
- ```bash
738
- # discord_llm/.env
739
- CLAUDE_SERVER_PORT=3001 # Port du bridge
740
- RUNNER=hermes # Runner Overmind
741
- BRIDGE_AGENT=sniperbot_analyst # Agent par dรฉfaut
742
- OVERMIND_MCP_URL=http://[::1]:3099/mcp # MCP server
743
- DISCORD_BOT_TOKEN=*** # Token Discord
744
- BOT_PREFIX=!sniper # Prรฉfixe commandes
745
- ```
746
-
747
351
  ---
748
352
 
749
- ## CLI overmind-bridge
750
-
751
- Le CLI `overmind-bridge` (`src/bin/overmind-bridge.ts`) permet de piloter le bridge sans รฉcrire de code.
752
-
753
- ### Dรฉmarrer le serveur
754
-
755
- ```bash
756
- overmind-bridge server --port 3100
757
- ```
758
-
759
- ### Appels one-shot (8 sources de prompt)
760
-
761
- ```bash
762
- # 1. Flag direct
763
- overmind-bridge call agent.run --agent scout --runner hermes --prompt "Analyse BTC"
764
-
765
- # 2. Stdin
766
- echo "Analyse BTC" | overmind-bridge call agent.run --agent scout --runner hermes --prompt-stdin
767
-
768
- # 3. Fichier
769
- overmind-bridge call agent.run --agent scout --runner hermes --prompt-file ./brief.txt
770
-
771
- # 4. Fichier + variables
772
- overmind-bridge call agent.run --agent scout --runner hermes \
773
- --prompt-file ./brief.txt --var ticker=BTC --var timeframe=4h
774
-
775
- # 5-8. env-var, scenario, pipe, multi-file (voir --help)
776
- ```
777
-
778
- ### A2A via CLI
779
-
780
- ```bash
781
- overmind-bridge call agent.a2a \
782
- --from scout --to analyst --runner hermes \
783
- --prompt "Valide mon analyse"
784
- ```
785
-
786
- ### Scรฉnarios multi-agents
787
-
788
- ```bash
789
- # JSON scenario file
790
- overmind-bridge scenario ./workflow.json --var ticker=BTC
791
- ```
792
-
793
- ### Status et Health
794
-
795
- ```bash
796
- # Status de tous les agents
797
- overmind-bridge status
798
-
799
- # Health du serveur
800
- overmind-bridge health
801
-
802
- # Replay un message
803
- overmind-bridge replay --id 7f3e8a1b-...
353
+ ## Scripts de Gestion
354
+
355
+ ### `scripts/start-all-bridges.ps1`
356
+
357
+ ```powershell
358
+ # Dรฉmarre les 6 bridges en parallรจle
359
+ $bridges = @(
360
+ @{ Name="master"; Port=3101 },
361
+ @{ Name="trader"; Port=3102 },
362
+ @{ Name="risk_manager"; Port=3103 },
363
+ @{ Name="healer"; Port=3104 },
364
+ @{ Name="researcher"; Port=3105 },
365
+ @{ Name="publisher"; Port=3106 }
366
+ )
367
+
368
+ $jobs = @()
369
+ foreach ($b in $bridges) {
370
+ $script = "cd '$PSScriptRoot\..\bridges\nexus_$($b.Name)' ; node dist/bridge.js"
371
+ $jobs += Start-Job -ScriptBlock { Invoke-Expression $args[0] } -ArgumentList $script
372
+ Write-Host "โœ… Started nexus_$($b.Name) on :$($b.Port)"
373
+ }
804
374
 
805
- # Sessions
806
- overmind-bridge sessions list
807
- overmind-bridge sessions get --key "+141****7735" --agent pdf_bon_travail
808
- overmind-bridge sessions rm --key "+141****7735" --agent pdf_bon_travail
375
+ Write-Host "`n6 bridges running. Press Ctrl+C to stop."
376
+ Wait-Job -Job $jobs
377
+ ```
378
+
379
+ ### `scripts/seed-bridges.ps1`
380
+
381
+ ```powershell
382
+ # Crรฉe la structure de dossiers + .env pour les 6 bridges
383
+ $template = @'
384
+ AGENT_NAME={AGENT}
385
+ RUNNER=hermes
386
+ BRIDGE_PORT={PORT}
387
+ BRIDGE_HOST=127.0.0.1
388
+ MCP_URL=http://[::1]:3099/mcp
389
+ HERMES_GATEWAY_URL=http://127.0.0.1:8642
390
+ HERMES_GATEWAY_KEY=<KEY>
391
+ PEER_TRADER_URL=http://127.0.0.1:3102
392
+ PEER_RISK_URL=http://127.0.0.1:3103
393
+ PEER_HEALER_URL=http://127.0.0.1:3104
394
+ PEER_RESEARCHER_URL=http://127.0.0.1:3105
395
+ PEER_PUBLISHER_URL=http://127.0.0.1:3106
396
+ '@
397
+
398
+ $config = @(
399
+ @{ Name="master"; Port=3101 },
400
+ @{ Name="trader"; Port=3102 },
401
+ @{ Name="risk_manager"; Port=3103 },
402
+ @{ Name="healer"; Port=3104 },
403
+ @{ Name="researcher"; Port=3105 },
404
+ @{ Name="publisher"; Port=3106 }
405
+ )
406
+
407
+ foreach ($c in $config) {
408
+ $dir = "$PSScriptRoot\..\bridges\nexus_$($c.Name)"
409
+ New-Item -ItemType Directory -Force -Path "$dir/src/clients"
410
+ New-Item -ItemType Directory -Force -Path "$dir/logs"
411
+ $env = $template -replace '{AGENT}', "nexus_$($c.Name)" -replace '{PORT}', $c.Port
412
+ Set-Content -Path "$dir/.env" -Value $env
413
+ Write-Host "โœ… Seeded nexus_$($c.Name) on :$($c.Port)"
414
+ }
809
415
  ```
810
416
 
811
417
  ---
812
418
 
813
- ## Dรฉmarrer le Serveur Bridge
814
-
815
- ### Option A : OverBridgeServer natif (port 3100)
816
-
817
- ```typescript
818
- import { OverBridgeServer, OverBridgeService, loadMessageLogConfigFromEnv } from 'overmind-mcp/bridge';
819
-
820
- const service = new OverBridgeService({
821
- mcpUrl: 'http://[::1]:3099/mcp',
822
- defaultTimeoutMs: 60_000,
823
- agentTimeoutMs: 2_700_000,
824
- }, logger);
825
-
826
- const server = new OverBridgeServer(service, {
827
- port: 3100,
828
- host: '127.0.0.1',
829
- postgres: loadMessageLogConfigFromEnv(),
830
- enableMessageLog: true, // Persistence Postgres
831
- enableSessionStore: true, // Multi-tenant sessions
832
- enableDirectives: true, // SESSION_ID, CONTEXT_UPDATE directives
833
- enableWebhooks: true, // /webhook/:provider
834
- sessionTtlMs: 4 * 60 * 60 * 1000, // 4h
835
- rateLimitMax: 100, // 100 req/min par IP
836
- allowedOrigins: ['*'],
837
- sanitizeJson: true, // Windows path repair
838
- });
839
-
840
- await server.start();
841
- // POST http://127.0.0.1:3100/rpc (JSON-RPC 2.0)
842
- // GET http://127.0.0.1:3100/health
843
- // POST http://127.0.0.1:3100/webhook/:provider
844
- ```
845
-
846
- ### Option B : Bridge lรฉger Express (comme discord_llm)
847
-
848
- Pour un client qui n'a pas besoin de Postgres MessageLog mais veut les sessions multi-tenant :
849
-
850
- ```typescript
851
- import express from 'express';
852
- import { OverBridgeService, SessionStore, BridgeProxy } from 'overmind-mcp/bridge';
853
-
854
- const app = express();
855
- app.use(express.json());
856
-
857
- const service = new OverBridgeService({ mcpUrl: 'http://[::1]:3099/mcp' });
858
- const sessions = new SessionStore({ persistPath: './sessions.json' });
859
- await sessions.init();
860
-
861
- // POST /send, POST /rpc, GET /health...
862
- app.listen(3001);
863
- ```
864
-
865
- ### Option C : CLI direct
866
-
867
- ```bash
868
- # Dรฉmarrer le serveur OverBridgeServer complet
869
- overmind-bridge server --port 3100 --enable-message-log --enable-sessions --enable-webhooks
419
+ ## Avantages de cette Architecture
420
+
421
+ | Bรฉnรฉfice | Explication |
422
+ |----------|-------------|
423
+ | **Isolation** | Chaque agent = son process, son port, ses logs. Crash d'un agent โ‰  crash des autres. |
424
+ | **Scaling indรฉpendant** | Tu peux redรฉmarrer `nexus_trader` sans toucher aux autres. |
425
+ | **Monitoring clair** | `GET :3101/health`, `GET :3102/health`, etc. โ€” chaque agent a sa mรฉtrique. |
426
+ | **Dรฉploiement granulaire** | Tu peux dรฉployer un agent sur une autre machine en gardant le mรชme code. |
427
+ | **Logs sรฉparรฉs** | `logs/bridges/nexus_master.log` โ€” debugging facile par agent. |
428
+ | **Config par agent** | `.env` dรฉdiรฉ โ€” clรฉs API diffรฉrentes si besoin. |
429
+ | **Pas de SPOF** | Si le bridge master crash, les 5 autres continuent ร  fonctionner entre eux. |
430
+
431
+ ## Flow Complet โ€” Exemple Concret
432
+
433
+ ```
434
+ Discord !sniper trade BTC
435
+ โ†“
436
+ discord_llm bridge (:3001)
437
+ โ†“ HTTP POST /send
438
+ โ†“
439
+ nexus_master bridge (:3101)
440
+ โ†“ BridgeClient.call('agent.run', agentName='nexus_trader')
441
+ โ†“ HTTP POST http://localhost:3102/rpc
442
+ โ†“
443
+ nexus_trader bridge (:3102)
444
+ โ†“ service.runAgent() โ†’ BridgeProxy โ†’ HTTP POST :3099/mcp
445
+ โ†“
446
+ Overmind MCP Server (:3099)
447
+ โ†“ runHermesAgent() โ†’ HermesGatewayRunner
448
+ โ†“ HTTP POST :8642/v1/chat/completions + X-Hermes-Profile: nexus_trader
449
+ โ†“
450
+ Hermes Gateway (:8642)
451
+ โ†“ Route vers profil nexus_trader
452
+ โ†“ Response: "BUY 0.1 BTC @ 67500"
453
+ โ†‘ retour en sens inverse โ†‘
870
454
  ```
871
455
 
872
456
  ---
873
457
 
874
- ## Configurations du OverBridgeServer
875
-
876
- | Config | Default | Description |
877
- |--------|---------|-------------|
878
- | `port` | 3100 | Port HTTP |
879
- | `host` | 127.0.0.1 | Host d'รฉcoute |
880
- | `postgres` | โ€” | Config Postgres pour MessageLog |
881
- | `enableMessageLog` | false | Persistence des messages en DB |
882
- | `enableSessionStore` | false | Sessions multi-tenant |
883
- | `enableDirectives` | false | Parse SESSION_ID, CONTEXT_UPDATE |
884
- | `enableWebhooks` | false | Auto-mount /webhook/:provider |
885
- | `authToken` | โ€” | Bearer token auth |
886
- | `healthCheckIntervalMs` | 30000 | Heartbeat vers MCP |
887
- | `sessionTtlMs` | 14400000 (4h) | TTL sessions |
888
- | `sessionStorePath` | ~/.overmind/bridge/sessions.json | Fichier persistence |
889
- | `jsonBodyLimit` | 10mb | Limite body |
890
- | `sanitizeJson` | false | Repair JSON Windows paths |
891
- | `allowedOrigins` | localhost:3000,5173 | CORS |
892
- | `rateLimitMax` | 100 | Max req/min par IP |
458
+ ## Rรฉfรฉrences
459
+
460
+ - `overmind-mcp/bridge` exports : `OverBridgeServer`, `OverBridgeService`, `BridgeProxy`, `SessionStore`, `MessageLog`
461
+ - Doc source : `Workflow/src/bridge/OverBridgeServer.ts` (1928 lignes)
462
+ - Profils Hermes existants : `~/.hermes/profiles/nexus_*` (7 profils crรฉรฉs)
463
+ - Gateway API : `Workflow/src/services/HermesGatewayRunner.ts` (HTTP+SSE, port 8642)