@open-multi-agent/core 1.4.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.
Files changed (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +373 -0
  3. package/dist/agent/agent.d.ts +153 -0
  4. package/dist/agent/agent.d.ts.map +1 -0
  5. package/dist/agent/agent.js +559 -0
  6. package/dist/agent/agent.js.map +1 -0
  7. package/dist/agent/loop-detector.d.ts +39 -0
  8. package/dist/agent/loop-detector.d.ts.map +1 -0
  9. package/dist/agent/loop-detector.js +122 -0
  10. package/dist/agent/loop-detector.js.map +1 -0
  11. package/dist/agent/pool.d.ts +158 -0
  12. package/dist/agent/pool.d.ts.map +1 -0
  13. package/dist/agent/pool.js +320 -0
  14. package/dist/agent/pool.js.map +1 -0
  15. package/dist/agent/runner.d.ts +242 -0
  16. package/dist/agent/runner.d.ts.map +1 -0
  17. package/dist/agent/runner.js +943 -0
  18. package/dist/agent/runner.js.map +1 -0
  19. package/dist/agent/structured-output.d.ts +33 -0
  20. package/dist/agent/structured-output.d.ts.map +1 -0
  21. package/dist/agent/structured-output.js +116 -0
  22. package/dist/agent/structured-output.js.map +1 -0
  23. package/dist/cli/oma.d.ts +30 -0
  24. package/dist/cli/oma.d.ts.map +1 -0
  25. package/dist/cli/oma.js +433 -0
  26. package/dist/cli/oma.js.map +1 -0
  27. package/dist/dashboard/layout-tasks.d.ts +23 -0
  28. package/dist/dashboard/layout-tasks.d.ts.map +1 -0
  29. package/dist/dashboard/layout-tasks.js +79 -0
  30. package/dist/dashboard/layout-tasks.js.map +1 -0
  31. package/dist/dashboard/render-team-run-dashboard.d.ts +11 -0
  32. package/dist/dashboard/render-team-run-dashboard.d.ts.map +1 -0
  33. package/dist/dashboard/render-team-run-dashboard.js +456 -0
  34. package/dist/dashboard/render-team-run-dashboard.js.map +1 -0
  35. package/dist/errors.d.ts +14 -0
  36. package/dist/errors.d.ts.map +1 -0
  37. package/dist/errors.js +20 -0
  38. package/dist/errors.js.map +1 -0
  39. package/dist/index.d.ts +79 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +92 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/llm/adapter.d.ts +54 -0
  44. package/dist/llm/adapter.d.ts.map +1 -0
  45. package/dist/llm/adapter.js +101 -0
  46. package/dist/llm/adapter.js.map +1 -0
  47. package/dist/llm/anthropic.d.ts +57 -0
  48. package/dist/llm/anthropic.d.ts.map +1 -0
  49. package/dist/llm/anthropic.js +432 -0
  50. package/dist/llm/anthropic.js.map +1 -0
  51. package/dist/llm/azure-openai.d.ts +74 -0
  52. package/dist/llm/azure-openai.d.ts.map +1 -0
  53. package/dist/llm/azure-openai.js +267 -0
  54. package/dist/llm/azure-openai.js.map +1 -0
  55. package/dist/llm/bedrock.d.ts +41 -0
  56. package/dist/llm/bedrock.d.ts.map +1 -0
  57. package/dist/llm/bedrock.js +345 -0
  58. package/dist/llm/bedrock.js.map +1 -0
  59. package/dist/llm/copilot.d.ts +92 -0
  60. package/dist/llm/copilot.d.ts.map +1 -0
  61. package/dist/llm/copilot.js +433 -0
  62. package/dist/llm/copilot.js.map +1 -0
  63. package/dist/llm/deepseek.d.ts +21 -0
  64. package/dist/llm/deepseek.d.ts.map +1 -0
  65. package/dist/llm/deepseek.js +24 -0
  66. package/dist/llm/deepseek.js.map +1 -0
  67. package/dist/llm/gemini.d.ts +65 -0
  68. package/dist/llm/gemini.d.ts.map +1 -0
  69. package/dist/llm/gemini.js +427 -0
  70. package/dist/llm/gemini.js.map +1 -0
  71. package/dist/llm/grok.d.ts +21 -0
  72. package/dist/llm/grok.d.ts.map +1 -0
  73. package/dist/llm/grok.js +24 -0
  74. package/dist/llm/grok.js.map +1 -0
  75. package/dist/llm/minimax.d.ts +21 -0
  76. package/dist/llm/minimax.d.ts.map +1 -0
  77. package/dist/llm/minimax.js +24 -0
  78. package/dist/llm/minimax.js.map +1 -0
  79. package/dist/llm/openai-common.d.ts +65 -0
  80. package/dist/llm/openai-common.d.ts.map +1 -0
  81. package/dist/llm/openai-common.js +286 -0
  82. package/dist/llm/openai-common.js.map +1 -0
  83. package/dist/llm/openai.d.ts +63 -0
  84. package/dist/llm/openai.d.ts.map +1 -0
  85. package/dist/llm/openai.js +256 -0
  86. package/dist/llm/openai.js.map +1 -0
  87. package/dist/llm/qiniu.d.ts +21 -0
  88. package/dist/llm/qiniu.d.ts.map +1 -0
  89. package/dist/llm/qiniu.js +24 -0
  90. package/dist/llm/qiniu.js.map +1 -0
  91. package/dist/mcp.d.ts +3 -0
  92. package/dist/mcp.d.ts.map +1 -0
  93. package/dist/mcp.js +2 -0
  94. package/dist/mcp.js.map +1 -0
  95. package/dist/memory/shared.d.ts +162 -0
  96. package/dist/memory/shared.d.ts.map +1 -0
  97. package/dist/memory/shared.js +294 -0
  98. package/dist/memory/shared.js.map +1 -0
  99. package/dist/memory/store.d.ts +72 -0
  100. package/dist/memory/store.d.ts.map +1 -0
  101. package/dist/memory/store.js +121 -0
  102. package/dist/memory/store.js.map +1 -0
  103. package/dist/orchestrator/orchestrator.d.ts +245 -0
  104. package/dist/orchestrator/orchestrator.d.ts.map +1 -0
  105. package/dist/orchestrator/orchestrator.js +1400 -0
  106. package/dist/orchestrator/orchestrator.js.map +1 -0
  107. package/dist/orchestrator/scheduler.d.ts +112 -0
  108. package/dist/orchestrator/scheduler.d.ts.map +1 -0
  109. package/dist/orchestrator/scheduler.js +256 -0
  110. package/dist/orchestrator/scheduler.js.map +1 -0
  111. package/dist/task/queue.d.ts +191 -0
  112. package/dist/task/queue.d.ts.map +1 -0
  113. package/dist/task/queue.js +408 -0
  114. package/dist/task/queue.js.map +1 -0
  115. package/dist/task/task.d.ts +90 -0
  116. package/dist/task/task.d.ts.map +1 -0
  117. package/dist/task/task.js +206 -0
  118. package/dist/task/task.js.map +1 -0
  119. package/dist/team/messaging.d.ts +106 -0
  120. package/dist/team/messaging.d.ts.map +1 -0
  121. package/dist/team/messaging.js +183 -0
  122. package/dist/team/messaging.js.map +1 -0
  123. package/dist/team/team.d.ts +141 -0
  124. package/dist/team/team.d.ts.map +1 -0
  125. package/dist/team/team.js +293 -0
  126. package/dist/team/team.js.map +1 -0
  127. package/dist/tool/built-in/bash.d.ts +12 -0
  128. package/dist/tool/built-in/bash.d.ts.map +1 -0
  129. package/dist/tool/built-in/bash.js +133 -0
  130. package/dist/tool/built-in/bash.js.map +1 -0
  131. package/dist/tool/built-in/delegate.d.ts +29 -0
  132. package/dist/tool/built-in/delegate.d.ts.map +1 -0
  133. package/dist/tool/built-in/delegate.js +92 -0
  134. package/dist/tool/built-in/delegate.js.map +1 -0
  135. package/dist/tool/built-in/file-edit.d.ts +14 -0
  136. package/dist/tool/built-in/file-edit.d.ts.map +1 -0
  137. package/dist/tool/built-in/file-edit.js +130 -0
  138. package/dist/tool/built-in/file-edit.js.map +1 -0
  139. package/dist/tool/built-in/file-read.d.ts +12 -0
  140. package/dist/tool/built-in/file-read.d.ts.map +1 -0
  141. package/dist/tool/built-in/file-read.js +82 -0
  142. package/dist/tool/built-in/file-read.js.map +1 -0
  143. package/dist/tool/built-in/file-write.d.ts +11 -0
  144. package/dist/tool/built-in/file-write.d.ts.map +1 -0
  145. package/dist/tool/built-in/file-write.js +70 -0
  146. package/dist/tool/built-in/file-write.js.map +1 -0
  147. package/dist/tool/built-in/fs-walk.d.ts +23 -0
  148. package/dist/tool/built-in/fs-walk.d.ts.map +1 -0
  149. package/dist/tool/built-in/fs-walk.js +78 -0
  150. package/dist/tool/built-in/fs-walk.js.map +1 -0
  151. package/dist/tool/built-in/glob.d.ts +12 -0
  152. package/dist/tool/built-in/glob.d.ts.map +1 -0
  153. package/dist/tool/built-in/glob.js +82 -0
  154. package/dist/tool/built-in/glob.js.map +1 -0
  155. package/dist/tool/built-in/grep.d.ts +15 -0
  156. package/dist/tool/built-in/grep.d.ts.map +1 -0
  157. package/dist/tool/built-in/grep.js +218 -0
  158. package/dist/tool/built-in/grep.js.map +1 -0
  159. package/dist/tool/built-in/index.d.ts +48 -0
  160. package/dist/tool/built-in/index.d.ts.map +1 -0
  161. package/dist/tool/built-in/index.js +56 -0
  162. package/dist/tool/built-in/index.js.map +1 -0
  163. package/dist/tool/executor.d.ts +100 -0
  164. package/dist/tool/executor.d.ts.map +1 -0
  165. package/dist/tool/executor.js +184 -0
  166. package/dist/tool/executor.js.map +1 -0
  167. package/dist/tool/framework.d.ts +167 -0
  168. package/dist/tool/framework.d.ts.map +1 -0
  169. package/dist/tool/framework.js +402 -0
  170. package/dist/tool/framework.js.map +1 -0
  171. package/dist/tool/mcp.d.ts +31 -0
  172. package/dist/tool/mcp.d.ts.map +1 -0
  173. package/dist/tool/mcp.js +175 -0
  174. package/dist/tool/mcp.js.map +1 -0
  175. package/dist/tool/text-tool-extractor.d.ts +32 -0
  176. package/dist/tool/text-tool-extractor.d.ts.map +1 -0
  177. package/dist/tool/text-tool-extractor.js +195 -0
  178. package/dist/tool/text-tool-extractor.js.map +1 -0
  179. package/dist/types.d.ts +916 -0
  180. package/dist/types.d.ts.map +1 -0
  181. package/dist/types.js +8 -0
  182. package/dist/types.js.map +1 -0
  183. package/dist/utils/keywords.d.ts +18 -0
  184. package/dist/utils/keywords.d.ts.map +1 -0
  185. package/dist/utils/keywords.js +32 -0
  186. package/dist/utils/keywords.js.map +1 -0
  187. package/dist/utils/semaphore.d.ts +49 -0
  188. package/dist/utils/semaphore.d.ts.map +1 -0
  189. package/dist/utils/semaphore.js +89 -0
  190. package/dist/utils/semaphore.js.map +1 -0
  191. package/dist/utils/tokens.d.ts +7 -0
  192. package/dist/utils/tokens.d.ts.map +1 -0
  193. package/dist/utils/tokens.js +30 -0
  194. package/dist/utils/tokens.js.map +1 -0
  195. package/dist/utils/trace.d.ts +12 -0
  196. package/dist/utils/trace.d.ts.map +1 -0
  197. package/dist/utils/trace.js +30 -0
  198. package/dist/utils/trace.js.map +1 -0
  199. package/docs/DECISIONS.md +49 -0
  200. package/docs/cli.md +265 -0
  201. package/docs/context-management.md +24 -0
  202. package/docs/featured-partner.md +28 -0
  203. package/docs/observability.md +56 -0
  204. package/docs/providers.md +78 -0
  205. package/docs/shared-memory.md +27 -0
  206. package/docs/tool-configuration.md +152 -0
  207. package/package.json +96 -0
package/docs/cli.md ADDED
@@ -0,0 +1,265 @@
1
+ # Command-line interface (`oma`)
2
+
3
+ The package ships a small binary **`oma`** that exposes the same primitives as the TypeScript API: `runTeam`, `runTasks`, plus a static provider reference. It is meant for **shell scripts and CI** (JSON on stdout, stable exit codes).
4
+
5
+ It does **not** provide an interactive REPL, working-directory injection into tools, human approval gates, or session persistence. Those stay in application code.
6
+
7
+ ## Installation and invocation
8
+
9
+ After installing the package, the binary is on `PATH` when using `npx` or a local `node_modules/.bin`:
10
+
11
+ ```bash
12
+ npm install @open-multi-agent/core
13
+ npx oma help
14
+ ```
15
+
16
+ From a clone of the repository you need a build first:
17
+
18
+ ```bash
19
+ npm run build
20
+ node dist/cli/oma.js help
21
+ ```
22
+
23
+ Set the usual provider API keys in the environment (see [README](../README.md#quick-start)); the CLI does not read secrets from flags. MiniMax additionally reads `MINIMAX_BASE_URL` to select the global (`https://api.minimax.io/v1`) or China (`https://api.minimaxi.com/v1`) endpoint.
24
+
25
+ OpenRouter works through the OpenAI-compatible adapter: set `provider` to `openai`, `baseURL` to `https://openrouter.ai/api/v1`, and pass `OPENROUTER_API_KEY` as the agent or orchestrator `apiKey`.
26
+
27
+ ---
28
+
29
+ ## Commands
30
+
31
+ ### `oma run`
32
+
33
+ Runs **`OpenMultiAgent.runTeam(team, goal)`**: coordinator decomposition, task queue, optional synthesis.
34
+
35
+ When invoked with `--dashboard`, the **`oma` CLI** writes a static post-execution DAG dashboard HTML to `oma-dashboards/runTeam-<timestamp>.html` under the current working directory (the library does not write files itself; if you want this outside the CLI, call `renderTeamRunDashboard(result)` in application code — see `src/dashboard/render-team-run-dashboard.ts`).
36
+
37
+ The dashboard page loads **Tailwind CSS** (Play CDN), **Google Fonts** (Space Grotesk, Inter, Material Symbols), and **Material Symbols** from the network at view time. Opening the HTML file requires an **online** environment unless you host or inline those assets yourself (a future improvement).
38
+
39
+ | Argument | Required | Description |
40
+ |----------|----------|-------------|
41
+ | `--goal` | Yes | Natural-language goal passed to the team run. |
42
+ | `--team` | Yes | Path to JSON (see [Team file](#team-file)). |
43
+ | `--orchestrator` | No | Path to JSON merged into `new OpenMultiAgent(...)` after any orchestrator fragment from the team file. |
44
+ | `--coordinator` | No | Path to JSON passed as `runTeam(..., { coordinator })` (`CoordinatorConfig`). |
45
+ | `--dashboard` | No | Write a post-execution DAG dashboard HTML to `oma-dashboards/runTeam-<timestamp>.html`. |
46
+
47
+ Global flags: [`--pretty`](#output-flags), [`--include-messages`](#output-flags).
48
+
49
+ ### `oma task`
50
+
51
+ Runs **`OpenMultiAgent.runTasks(team, tasks)`** with a fixed task list (no coordinator decomposition).
52
+
53
+ | Argument | Required | Description |
54
+ |----------|----------|-------------|
55
+ | `--file` | Yes | Path to [tasks file](#tasks-file). |
56
+ | `--team` | No | Path to JSON `TeamConfig`. When set, overrides the `team` object inside `--file`. |
57
+
58
+ Global flags: [`--pretty`](#output-flags), [`--include-messages`](#output-flags).
59
+
60
+ ### `oma provider`
61
+
62
+ Read-only helper for wiring JSON configs and env vars.
63
+
64
+ - **`oma provider`** or **`oma provider list`** — Prints JSON: built-in provider ids, API key environment variable names, whether `baseURL` is supported, and short notes (e.g. OpenAI-compatible servers, Copilot in CI).
65
+ - **`oma provider template <provider>`** — Prints a JSON object with example `orchestrator` and `agent` fields plus placeholder `env` entries. `<provider>` is one of: `anthropic`, `openai`, `gemini`, `grok`, `minimax`, `deepseek`, `qiniu`, `copilot`.
66
+
67
+ For OpenRouter, use the `openai` provider template, set `baseURL` to `https://openrouter.ai/api/v1`, and set `apiKey` from `OPENROUTER_API_KEY` in your JSON config.
68
+
69
+ Supports `--pretty`.
70
+
71
+ ### `oma`, `oma help`, `oma -h`, `oma --help`
72
+
73
+ Prints usage text to stdout and exits **0**.
74
+
75
+ ---
76
+
77
+ ## Configuration files
78
+
79
+ Shapes match the library types `TeamConfig`, `OrchestratorConfig`, `CoordinatorConfig`, and the task objects accepted by `runTasks()`.
80
+
81
+ ### Team file
82
+
83
+ Used with **`oma run --team`** (and optionally **`oma task --team`**).
84
+
85
+ **Option A — plain `TeamConfig`**
86
+
87
+ ```json
88
+ {
89
+ "name": "api-team",
90
+ "agents": [
91
+ {
92
+ "name": "architect",
93
+ "model": "claude-sonnet-4-6",
94
+ "provider": "anthropic",
95
+ "systemPrompt": "You design APIs.",
96
+ "tools": ["file_read", "file_write"],
97
+ "maxTurns": 6
98
+ }
99
+ ],
100
+ "sharedMemory": true
101
+ }
102
+ ```
103
+
104
+ **Option B — team plus default orchestrator settings**
105
+
106
+ ```json
107
+ {
108
+ "team": {
109
+ "name": "api-team",
110
+ "agents": [{ "name": "worker", "model": "claude-sonnet-4-6", "systemPrompt": "…" }]
111
+ },
112
+ "orchestrator": {
113
+ "defaultModel": "claude-sonnet-4-6",
114
+ "defaultProvider": "anthropic",
115
+ "maxConcurrency": 3
116
+ }
117
+ }
118
+ ```
119
+
120
+ Validation rules enforced by the CLI:
121
+
122
+ - Root (or `team`) must be an object.
123
+ - `team.name` is a non-empty string.
124
+ - `team.agents` is a non-empty array; each agent must have non-empty `name` and `model`.
125
+
126
+ Any other fields are passed through to the library as in TypeScript.
127
+
128
+ **SDK-only fields**: `sharedMemoryStore` (custom `MemoryStore` instance) cannot be set from JSON since it is a runtime object. Use `sharedMemory: true` for the default in-memory store, or wire a custom store in TypeScript via `orchestrator.createTeam()`.
129
+
130
+ ### Tasks file
131
+
132
+ Used with **`oma task --file`**.
133
+
134
+ ```json
135
+ {
136
+ "orchestrator": {
137
+ "defaultModel": "claude-sonnet-4-6"
138
+ },
139
+ "team": {
140
+ "name": "pipeline",
141
+ "agents": [
142
+ { "name": "designer", "model": "claude-sonnet-4-6", "systemPrompt": "…" },
143
+ { "name": "builder", "model": "claude-sonnet-4-6", "systemPrompt": "…" }
144
+ ],
145
+ "sharedMemory": true
146
+ },
147
+ "tasks": [
148
+ {
149
+ "title": "Design",
150
+ "description": "Produce a short spec for the feature.",
151
+ "assignee": "designer"
152
+ },
153
+ {
154
+ "title": "Implement",
155
+ "description": "Implement from the design.",
156
+ "assignee": "builder",
157
+ "dependsOn": ["Design"]
158
+ }
159
+ ]
160
+ }
161
+ ```
162
+
163
+ - **`dependsOn`** — Task titles (not internal ids), same convention as the coordinator output in the library.
164
+ - Optional per-task fields: `memoryScope` (`"dependencies"` \| `"all"`), `maxRetries`, `retryDelayMs`, `retryBackoff`.
165
+ - **`tasks`** must be a non-empty array; each item needs string `title` and `description`.
166
+
167
+ If **`--team path.json`** is passed, the file’s top-level `team` property is ignored and the external file is used instead (useful when the same team definition is shared across several pipeline files).
168
+
169
+ ### Orchestrator and coordinator JSON
170
+
171
+ These files are arbitrary JSON objects merged into **`OrchestratorConfig`** and **`CoordinatorConfig`**. Function-valued options (`onProgress`, `onApproval`, etc.) cannot appear in JSON and are not supported by the CLI.
172
+
173
+ ---
174
+
175
+ ## Output
176
+
177
+ ### Stdout
178
+
179
+ Every invocation prints **one JSON document** to stdout, followed by a newline.
180
+
181
+ **Successful `run` / `task`**
182
+
183
+ ```json
184
+ {
185
+ "command": "run",
186
+ "success": true,
187
+ "totalTokenUsage": { "input_tokens": 0, "output_tokens": 0 },
188
+ "agentResults": {
189
+ "architect": {
190
+ "success": true,
191
+ "output": "…",
192
+ "tokenUsage": { "input_tokens": 0, "output_tokens": 0 },
193
+ "toolCalls": [],
194
+ "structured": null,
195
+ "loopDetected": false,
196
+ "budgetExceeded": false
197
+ }
198
+ }
199
+ }
200
+ ```
201
+
202
+ `agentResults` keys are agent names. When an agent ran multiple tasks, the library merges results; the CLI mirrors the merged `AgentRunResult` fields.
203
+
204
+ **Errors (usage, validation, I/O, runtime)**
205
+
206
+ ```json
207
+ {
208
+ "error": {
209
+ "kind": "usage",
210
+ "message": "--goal and --team are required"
211
+ }
212
+ }
213
+ ```
214
+
215
+ `kind` is one of: `usage`, `validation`, `io`, `runtime`, or `internal` (uncaught errors in the outer handler).
216
+
217
+ ### Output flags
218
+
219
+ | Flag | Effect |
220
+ |------|--------|
221
+ | `--pretty` | Pretty-print JSON with indentation. |
222
+ | `--include-messages` | Include each agent’s full `messages` array in `agentResults`. **Very large** for long runs; default is omit. |
223
+
224
+ There is no separate progress stream; for rich telemetry use the TypeScript API with `onProgress` / `onTrace`.
225
+
226
+ ---
227
+
228
+ ## Exit codes
229
+
230
+ | Code | Meaning |
231
+ |------|---------|
232
+ | **0** | Success: `run`/`task` finished with `success === true`, or help / `provider` completed normally. |
233
+ | **1** | Run finished but **`success === false`** (agent or task failure as reported by the library). |
234
+ | **2** | Usage, validation, readable JSON errors, or file access issues (e.g. missing file). |
235
+ | **3** | Unexpected error, including typical LLM/API failures surfaced as thrown errors. |
236
+
237
+ In scripts:
238
+
239
+ ```bash
240
+ npx oma run --goal "Summarize README" --team team.json > result.json
241
+ code=$?
242
+ case $code in
243
+ 0) echo "OK" ;;
244
+ 1) echo "Run reported failure — inspect result.json" ;;
245
+ 2) echo "Bad inputs or files" ;;
246
+ 3) echo "Crash or API error" ;;
247
+ esac
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Argument parsing
253
+
254
+ - Long options only: `--goal`, `--team`, `--file`, etc.
255
+ - Values may be attached with `=`: `--team=./team.json`.
256
+ - Boolean-style flags (`--pretty`, `--include-messages`) take no value; if the next token does not start with `--`, it is treated as the value of the previous option (standard `getopt`-style pairing).
257
+
258
+ ---
259
+
260
+ ## Limitations (by design)
261
+
262
+ - No TTY session, history, or `stdin` goal input.
263
+ - No built-in **`cwd`** or metadata passed into `ToolUseContext` (tools use process cwd unless the library adds other hooks later).
264
+ - No **`onApproval`** from JSON; non-interactive batch only.
265
+ - Coordinator **`runTeam`** path still requires network and API keys like any other run.
@@ -0,0 +1,24 @@
1
+ # Context Management
2
+
3
+ Long-running agents can hit input token ceilings fast. Set `contextStrategy` on `AgentConfig` to control how the conversation shrinks as it grows:
4
+
5
+ ```typescript
6
+ const agent: AgentConfig = {
7
+ name: 'long-runner',
8
+ model: 'claude-sonnet-4-6',
9
+ // Pick one:
10
+ contextStrategy: { type: 'sliding-window', maxTurns: 20 },
11
+ // contextStrategy: { type: 'summarize', maxTokens: 80_000, summaryModel: 'claude-haiku-4-5' },
12
+ // contextStrategy: { type: 'compact', maxTokens: 100_000, preserveRecentTurns: 4 },
13
+ // contextStrategy: { type: 'custom', compress: (messages, estimatedTokens) => ... },
14
+ }
15
+ ```
16
+
17
+ | Strategy | When to reach for it |
18
+ |----------|----------------------|
19
+ | `sliding-window` | Cheapest. Keep the last N turns, drop the rest. |
20
+ | `summarize` | Send old turns to a summary model; keep the summary in place of the originals. |
21
+ | `compact` | Rule-based: truncate large assistant text blocks and tool results, keep recent turns intact. No extra LLM call. |
22
+ | `custom` | Supply your own `compress(messages, estimatedTokens)` function. |
23
+
24
+ Pairs well with `compressToolResults` and `maxToolOutputChars`.
@@ -0,0 +1,28 @@
1
+ # Featured Partner program
2
+
3
+ For products and platforms already integrated with `open-multi-agent`. Reserves prominent placement in the [Ecosystem](../README.md#ecosystem) section of the project README for 12 months at a time.
4
+
5
+ ## What you get
6
+
7
+ - Logo, 100-word description, and a maintainer endorsement quote in a dedicated row above the integrations list.
8
+ - 12-month placement, renewable.
9
+ - Cross-link from the [English](../README.md) and [中文](../README_zh.md) README.
10
+
11
+ ## Eligibility
12
+
13
+ - Active integration with `open-multi-agent` already in production or a publicly testable beta.
14
+ - Aligned with the project's positioning: TypeScript multi-agent orchestration, agent infrastructure, observability, memory backends, and adjacent tooling.
15
+
16
+ ## Cost
17
+
18
+ $3,000 USD per partner per 12-month placement. Single partner per slot at a time, renewable on the same terms.
19
+
20
+ ## How to apply
21
+
22
+ [Open an inquiry issue](https://github.com/open-multi-agent/open-multi-agent/issues/new?title=Featured+Partner+Inquiry&labels=featured-partner-inquiry) with:
23
+
24
+ - A short description of your product and how it integrates with `open-multi-agent`.
25
+ - A link to the integration code or live deployment.
26
+ - The contact you want us to reply to.
27
+
28
+ The maintainers will follow up to review and confirm.
@@ -0,0 +1,56 @@
1
+ # Observability
2
+
3
+ `open-multi-agent` exposes three telemetry layers: live progress events, structured trace spans, and a static post-run dashboard.
4
+
5
+ ## Progress Events
6
+
7
+ Use `onProgress` when you need lightweight lifecycle events for logs, terminal output, or a live UI.
8
+
9
+ ```typescript
10
+ const orchestrator = new OpenMultiAgent({
11
+ onProgress: (event) => {
12
+ console.log(event.type, event.task ?? event.agent ?? '')
13
+ },
14
+ })
15
+ ```
16
+
17
+ Common event types include `task_start`, `task_complete`, `task_retry`, `task_skipped`, `agent_start`, `agent_complete`, `budget_exceeded`, and `error`.
18
+
19
+ ## Trace Spans
20
+
21
+ Use `onTrace` when you need structured spans for LLM calls, tool executions, and tasks. Each span carries parent IDs, durations, token counts, and tool I/O.
22
+
23
+ ```typescript
24
+ const orchestrator = new OpenMultiAgent({
25
+ onTrace: async (span) => {
26
+ await traceSink.write(span)
27
+ },
28
+ })
29
+ ```
30
+
31
+ Forward trace spans to OpenTelemetry, Datadog, Honeycomb, Langfuse, or your own run database. See [`integrations/trace-observability`](../examples/integrations/trace-observability.ts) for a runnable example.
32
+
33
+ ## Post-Run Dashboard
34
+
35
+ `renderTeamRunDashboard(result)` returns a static HTML page that visualizes the executed task DAG with timing, token usage, per-task status, and task details.
36
+
37
+ ```typescript
38
+ import { writeFileSync } from 'node:fs'
39
+ import { renderTeamRunDashboard } from '@open-multi-agent/core'
40
+
41
+ const result = await orchestrator.runTeam(team, goal)
42
+ writeFileSync('run.html', renderTeamRunDashboard(result))
43
+ ```
44
+
45
+ The library does not write files by itself. The CLI can write dashboard HTML for you with `oma run --dashboard`; see [docs/cli.md](./cli.md).
46
+
47
+ The dashboard HTML loads Tailwind CSS and Google Fonts from the network at view time. Opening the generated HTML requires an online environment unless you host or inline those assets yourself.
48
+
49
+ ## What to Persist
50
+
51
+ For production runs, persist enough data to reconstruct a failure without replaying the entire job:
52
+
53
+ - `TeamRunResult.tasks` for the executed DAG and task states.
54
+ - `TeamRunResult.totalTokenUsage` for cost attribution.
55
+ - `onTrace` spans for LLM calls and tool executions.
56
+ - The rendered dashboard HTML when you need a shareable post-mortem artifact.
@@ -0,0 +1,78 @@
1
+ # Providers
2
+
3
+ `open-multi-agent` keeps the agent config shape stable across hosted, cloud, and local providers. Change `provider`, `model`, and the relevant credential; the rest of your team definition stays the same.
4
+
5
+ ```typescript
6
+ const agent = {
7
+ name: 'my-agent',
8
+ provider: 'anthropic',
9
+ model: 'claude-sonnet-4-6',
10
+ systemPrompt: 'You are a helpful assistant.',
11
+ }
12
+ ```
13
+
14
+ ## Built-In Provider Shortcuts
15
+
16
+ The framework ships a wired-in provider name for each of these. Set `provider` and the env var, and the adapter handles the endpoint.
17
+
18
+ > Under the hood, Anthropic, Gemini, and Bedrock use provider-specific APIs. The other built-in shortcuts are pre-configured wrappers around OpenAI-compatible endpoints; same wire format as the OpenAI-compatible table below, with the `baseURL` already supplied.
19
+
20
+ | Provider | Config | Env var | Example model | Notes |
21
+ |----------|--------|---------|---------------|-------|
22
+ | Anthropic (Claude) | `provider: 'anthropic'` | `ANTHROPIC_API_KEY` | `claude-sonnet-4-6` | Native Anthropic SDK. |
23
+ | Gemini | `provider: 'gemini'` | `GEMINI_API_KEY` | `gemini-2.5-pro` | Native Google GenAI SDK. Requires `npm install @google/genai`. |
24
+ | OpenAI (GPT) | `provider: 'openai'` | `OPENAI_API_KEY` | `gpt-4o` | |
25
+ | Azure OpenAI | `provider: 'azure-openai'` | `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_ENDPOINT` | `gpt-4` | Optional `AZURE_OPENAI_API_VERSION`, `AZURE_OPENAI_DEPLOYMENT`. |
26
+ | GitHub Copilot | `provider: 'copilot'` | `GITHUB_COPILOT_TOKEN` (falls back to `GITHUB_TOKEN`) | `gpt-4o` | Custom token-exchange flow on top of OpenAI protocol. |
27
+ | Grok (xAI) | `provider: 'grok'` | `XAI_API_KEY` | `grok-4` | OpenAI-compatible; endpoint is `api.x.ai/v1`. |
28
+ | DeepSeek | `provider: 'deepseek'` | `DEEPSEEK_API_KEY` | `deepseek-chat` | OpenAI-compatible. `deepseek-chat` (V3, coding) or `deepseek-reasoner` (thinking mode). |
29
+ | MiniMax (global) | `provider: 'minimax'` | `MINIMAX_API_KEY` | `MiniMax-M2.7` | OpenAI-compatible. |
30
+ | MiniMax (China) | `provider: 'minimax'` + `MINIMAX_BASE_URL` | `MINIMAX_API_KEY` | `MiniMax-M2.7` | Set `MINIMAX_BASE_URL=https://api.minimaxi.com/v1`. |
31
+ | Qiniu | `provider: 'qiniu'` | `QINIU_API_KEY` | `deepseek-v3` | OpenAI-compatible. Endpoint `https://api.qnaigc.com/v1`; multiple model families, see [Qiniu AI docs](https://developer.qiniu.com/aitokenapi/12882/ai-inference-api). |
32
+ | AWS Bedrock | `provider: 'bedrock'` | none (AWS SDK credential chain) | `anthropic.claude-3-5-haiku-20241022-v1:0` | No API key. Set `AWS_REGION` or pass `region` as the 4th arg to `createAdapter`. Credentials come from env vars, shared config, or IAM role. Newer Claude models can require a cross-region inference profile prefix such as `us.`. Also supports Llama, Mistral, and Cohere. See [`providers/bedrock`](../examples/providers/bedrock.ts). Requires `npm install @aws-sdk/client-bedrock-runtime`. |
33
+
34
+ ## OpenAI-Compatible Providers
35
+
36
+ No bundled shortcut is needed when a server speaks OpenAI Chat Completions. Use `provider: 'openai'` and point `baseURL` at the service.
37
+
38
+ | Service | Config | Env var | Example model | Notes |
39
+ |---------|--------|---------|---------------|-------|
40
+ | Ollama (local) | `provider: 'openai'` + `baseURL: 'http://localhost:11434/v1'` | none | `llama3.1` | |
41
+ | vLLM (local) | `provider: 'openai'` + `baseURL` | none | server-loaded | |
42
+ | LM Studio (local) | `provider: 'openai'` + `baseURL` | none | server-loaded | |
43
+ | llama.cpp server (local) | `provider: 'openai'` + `baseURL` | none | server-loaded | |
44
+ | OpenRouter | `provider: 'openai'` + `baseURL: 'https://openrouter.ai/api/v1'` + `apiKey` | `OPENROUTER_API_KEY` | `openai/gpt-4o-mini` | |
45
+ | Groq | `provider: 'openai'` + `baseURL: 'https://api.groq.com/openai/v1'` | `GROQ_API_KEY` | `llama-3.3-70b-versatile` | |
46
+ | Mistral | `provider: 'openai'` + `baseURL: 'https://api.mistral.ai/v1'` | `MISTRAL_API_KEY` | `mistral-large-latest` | See [`providers/mistral`](../examples/providers/mistral.ts). |
47
+
48
+ Other services can be connected the same way if they implement the OpenAI Chat Completions API, but they are not listed as verified providers here. For services where the key is not `OPENAI_API_KEY`, pass it explicitly via `apiKey`; otherwise the `openai` adapter falls back to `OPENAI_API_KEY`.
49
+
50
+ ## Local Model Tool-Calling
51
+
52
+ The framework supports tool-calling with local models served by Ollama, vLLM, LM Studio, or llama.cpp. Tool-calling is handled natively through the OpenAI-compatible API.
53
+
54
+ Verified local models include Gemma 4, Llama 3.1, Qwen 3, Mistral, and Phi-4. Ollama publishes its tool-capable models at [ollama.com/search?c=tools](https://ollama.com/search?c=tools).
55
+
56
+ If a local model returns tool calls as text instead of the `tool_calls` wire format, the framework automatically extracts them from the text output. This helps with thinking models or misconfigured local servers.
57
+
58
+ Use `timeoutMs` on `AgentConfig` for slow local inference:
59
+
60
+ ```typescript
61
+ const localAgent = {
62
+ name: 'local',
63
+ model: 'llama3.1',
64
+ provider: 'openai',
65
+ baseURL: 'http://localhost:11434/v1',
66
+ apiKey: 'ollama',
67
+ tools: ['bash', 'file_read'],
68
+ timeoutMs: 120_000,
69
+ }
70
+ ```
71
+
72
+ Highly quantized MoE models on consumer hardware can fall into repetition loops or hallucinate tool-call schemas under default sampling. `AgentConfig` exposes `topK`, `minP`, `frequencyPenalty`, `presencePenalty`, `parallelToolCalls`, and `extraBody` for server-specific knobs such as vLLM's `repetition_penalty`. See [`providers/local-quantized`](../examples/providers/local-quantized.ts) for a complete setup.
73
+
74
+ ## Troubleshooting
75
+
76
+ - Model not calling tools? Confirm it appears in Ollama's [Tools category](https://ollama.com/search?c=tools).
77
+ - Using Ollama? Update to the latest version with `ollama update`.
78
+ - Proxy interfering with local servers? Use `no_proxy=localhost`.
@@ -0,0 +1,27 @@
1
+ # Shared Memory
2
+
3
+ Teams can share a namespaced key-value store so later agents see earlier agents' findings. Enable it with a boolean for the default in-process store:
4
+
5
+ ```typescript
6
+ const team = orchestrator.createTeam('research-team', {
7
+ name: 'research-team',
8
+ agents: [researcher, writer],
9
+ sharedMemory: true,
10
+ })
11
+ ```
12
+
13
+ For durable or cross-process backends (Redis, Postgres, Engram, etc.), implement the `MemoryStore` interface and pass it via `sharedMemoryStore`. Keys are still namespaced as `<agentName>/<key>` before reaching the store:
14
+
15
+ ```typescript
16
+ import type { MemoryStore } from '@open-multi-agent/core'
17
+
18
+ class RedisStore implements MemoryStore { /* get/set/list/delete/clear */ }
19
+
20
+ const team = orchestrator.createTeam('durable-team', {
21
+ name: 'durable-team',
22
+ agents: [researcher, writer],
23
+ sharedMemoryStore: new RedisStore(),
24
+ })
25
+ ```
26
+
27
+ When both are provided, `sharedMemoryStore` wins. SDK-only: the CLI cannot pass runtime objects.
@@ -0,0 +1,152 @@
1
+ # Tool Configuration
2
+
3
+ Agents can be configured with fine-grained tool access control using presets, allowlists, and denylists.
4
+
5
+ ## Tool Presets
6
+
7
+ Predefined tool sets for common use cases:
8
+
9
+ ```typescript
10
+ const readonlyAgent: AgentConfig = {
11
+ name: 'reader',
12
+ model: 'claude-sonnet-4-6',
13
+ toolPreset: 'readonly', // file_read, grep, glob
14
+ }
15
+
16
+ const readwriteAgent: AgentConfig = {
17
+ name: 'editor',
18
+ model: 'claude-sonnet-4-6',
19
+ toolPreset: 'readwrite', // file_read, file_write, file_edit, grep, glob
20
+ }
21
+
22
+ const fullAgent: AgentConfig = {
23
+ name: 'executor',
24
+ model: 'claude-sonnet-4-6',
25
+ toolPreset: 'full', // file_read, file_write, file_edit, grep, glob, bash
26
+ }
27
+ ```
28
+
29
+ ## Advanced Filtering
30
+
31
+ Combine presets with allowlists and denylists for precise control:
32
+
33
+ ```typescript
34
+ const customAgent: AgentConfig = {
35
+ name: 'custom',
36
+ model: 'claude-sonnet-4-6',
37
+ toolPreset: 'readwrite', // Start with: file_read, file_write, file_edit, grep, glob
38
+ tools: ['file_read', 'grep'], // Allowlist: intersect with preset = file_read, grep
39
+ disallowedTools: ['grep'], // Denylist: subtract = file_read only
40
+ }
41
+ ```
42
+
43
+ **Resolution order:** preset → allowlist → denylist → framework safety rails.
44
+
45
+ ## Custom Tools
46
+
47
+ Two ways to give an agent a tool that is not in the built-in set.
48
+
49
+ **Inject at config time** via `customTools` on `AgentConfig`. Good when the orchestrator wires up tools centrally. Tools defined here bypass preset/allowlist filtering but still respect `disallowedTools`.
50
+
51
+ ```typescript
52
+ import { defineTool } from '@open-multi-agent/core'
53
+ import { z } from 'zod'
54
+
55
+ const weatherTool = defineTool({
56
+ name: 'get_weather',
57
+ description: 'Look up current weather for a city.',
58
+ inputSchema: z.object({ city: z.string() }),
59
+ execute: async ({ city }) => ({ data: await fetchWeather(city) }),
60
+ })
61
+
62
+ const agent: AgentConfig = {
63
+ name: 'assistant',
64
+ model: 'claude-sonnet-4-6',
65
+ customTools: [weatherTool],
66
+ }
67
+ ```
68
+
69
+ **Register at runtime** via `agent.addTool(tool)`. Tools added this way are always available, regardless of filtering.
70
+
71
+ ## Tool Output Control
72
+
73
+ Long tool outputs can blow up conversation size and cost. Two controls work together.
74
+
75
+ **Validation (optional).** Add `outputSchema` to catch malformed tool results before they are forwarded:
76
+
77
+ > **Note — two different `outputSchema` fields.** The one on `defineTool()` /
78
+ > `ToolDefinition` (shown below) validates a single **tool's** `ToolResult.data`
79
+ > — it is always a `ZodSchema<string>` because tool output is serialised as
80
+ > text. The `outputSchema` on [`AgentConfig`](../examples/patterns/structured-output.ts)
81
+ > is different: it validates the **agent's final answer** as parsed JSON
82
+ > against an arbitrary Zod schema (see _Structured output_ in `examples/`).
83
+ > Different types, different scopes — TypeScript won't warn you if you mix
84
+ > them up, so pick the one that matches the layer you're working at.
85
+
86
+ ```typescript
87
+ const jsonTool = defineTool({
88
+ name: 'json_tool',
89
+ description: 'Return JSON payload as string.',
90
+ inputSchema: z.object({}),
91
+ outputSchema: z.string().refine((value) => {
92
+ try {
93
+ JSON.parse(value)
94
+ return true
95
+ } catch {
96
+ return false
97
+ }
98
+ }, 'Output must be valid JSON'),
99
+ execute: async () => ({ data: '{"ok": true}' }),
100
+ })
101
+ ```
102
+
103
+ **Truncation.** Cap an individual tool result to a head + tail excerpt with a marker in between:
104
+
105
+ ```typescript
106
+ const agent: AgentConfig = {
107
+ // ...
108
+ maxToolOutputChars: 10_000, // applies to every tool this agent runs
109
+ }
110
+
111
+ // Per-tool override (takes priority over AgentConfig.maxToolOutputChars):
112
+ const bigQueryTool = defineTool({
113
+ // ...
114
+ maxOutputChars: 50_000,
115
+ })
116
+ ```
117
+
118
+ **Post-consumption compression.** Once the agent has acted on a tool result, compress older copies in the transcript so they stop costing input tokens on every subsequent turn. Error results are never compressed.
119
+
120
+ ```typescript
121
+ const agent: AgentConfig = {
122
+ // ...
123
+ compressToolResults: true, // default threshold: 500 chars
124
+ // or: compressToolResults: { minChars: 2_000 }
125
+ }
126
+ ```
127
+
128
+ ## MCP Tools (Model Context Protocol)
129
+
130
+ `open-multi-agent` can connect to stdio MCP servers and expose their tools directly to agents.
131
+
132
+ ```typescript
133
+ import { connectMCPTools } from '@open-multi-agent/core/mcp'
134
+
135
+ const { tools, disconnect } = await connectMCPTools({
136
+ command: 'npx',
137
+ args: ['-y', '@modelcontextprotocol/server-github'],
138
+ env: { GITHUB_TOKEN: process.env.GITHUB_TOKEN },
139
+ namePrefix: 'github',
140
+ })
141
+
142
+ // Register each MCP tool in your ToolRegistry, then include their names in AgentConfig.tools
143
+ // Don't forget cleanup when done
144
+ await disconnect()
145
+ ```
146
+
147
+ Notes:
148
+ - `@modelcontextprotocol/sdk` is an optional peer dependency, only needed when using MCP.
149
+ - Current transport support is stdio.
150
+ - MCP input validation is delegated to the MCP server (`inputSchema` is `z.any()`).
151
+
152
+ See [`integrations/mcp-github`](../examples/integrations/mcp-github.ts) for a full runnable setup.