* feat(agent): orchestrate external coding agents over ACP (#204)
Add an AgentBackend seam so an Agent can run on either the LLM AgentRunner
or an external agent. First backend: an ACP client that drives a coding CLI
(e.g. Claude Code via its ACP adapter) as a first-class team member — same
task DAG, shared memory, cascade, and token budget as LLM agents.
- Extract AgentBackend ({ run, stream }) that AgentRunner already implements;
Agent.getBackend() branches on AgentConfig.backend.
- AcpBackend spawns the agent over stdio JSON-RPC and maps session updates to
a RunResult (text, tool calls, usage); handles permissions and abort.
- ACP SDK as a lazy optional peer; new /acp subpath export.
- docs/external-agents.md, a hybrid-team example, and tests (in-process fake
agent + subprocess integration).
Experimental: ACP is young; token accounting maps ACP's single context
figure and client-side fs proxying is not implemented yet.
* fix(agent): harden ACP backend after review (#204)
Follow-up fixes on the ACP external-agent backend (PR #360):
- Token accounting: usage_update.used is a cumulative context-size gauge, not a
per-turn delta. Record each turn's increment so summing across a reused session
telescopes to the latest figure instead of double-counting.
- systemPrompt: ACP has no system-prompt field, so prepend the agent's systemPrompt
to the session's first turn (once). It was previously dropped and only fed
coordinator routing.
- Abort: when the signal is already aborted before a turn starts, return empty
output without prompting (no in-flight turn to cancel).
- Startup: clear the cached start() promise on failure so a later run retries
instead of re-throwing the same rejection forever.
- Permissions: auto-approve now prefers least-privilege allow_once over a
session-wide allow_always.
Docs (external-agents.md, CLAUDE.md) updated to match. ACP tests 10 to 15;
lint + full suite (1135) green.
Add AgentConfig.credentials, a per-agent secret bag threaded into
ToolUseContext.credentials. Tool code reads context.credentials?.KEY
instead of closing a shared secret over every tool, so each agent holds
only the credentials it was assigned; a compromised subagent can't reach
another agent's secrets. Per-agent bags flow through the existing config
spread, so no orchestrator changes are needed, and the coordinator (built
field-by-field) never receives user tool secrets.
Addresses the credential-scoping half of #19. Per-call risk gating stays
tracked in #96.
Redaction stopped at the observability layer, so secrets an agent emitted into its answer were persisted verbatim to shared memory and on-disk checkpoints. Add RedactingStore, a MemoryStore decorator that scrubs values on write, plus optional custom patterns on the redaction utilities. One wrap of the durable store closes both persistence sinks.
Closes#339.
- README_zh.md: add the "Cap estimated cost" section and production-checklist
row that #358 added only to the English package README, keeping EN/ZH in sync
- consensus.md: extend the budget invariant so maxCostBudget is documented at
the same verify-hook boundary as maxTokenBudget; standalone runConsensus
tracks tokens only
- README EN/ZH: switch the cost example to gpt-5.4-mini, pricing matching the
repo's existing cost-tiered-pipeline example
Follow-up documentation for #358.
Reverts the sponsor content added in #219:
- Drop the 'Provider community offers' section and MiniMax offer bullet
from README.md, README_zh.md, and the packages/core mirrors
- Delete docs/providers/minimax.md (offer-specific setup guide)
- Delete .github/brand/minimax-banner.png (used only by that guide)
MiniMax stays supported as a neutral provider: the provider table in
docs/providers.md, the MINIMAX_BASE_URL note in docs/cli.md, the
examples/providers/minimax.ts sample, and contributor credits are all kept.
Closes#340.
add spanId and optional parentId to every TraceEventBase
generate stable agent span IDs so LLM/tool spans can point to their owning agent span
link team-run worker agents under task spans, stream events under worker agent spans, and plan_ready under coordinator decomposition
document the trace parentage model and add focused tests for span linkage
Co-authored-by: sanhuo11 <tlysanhuo@gmail.com>
Zero-dependency, filesystem-backed MemoryStore with atomic fsync+rename
writes, so checkpoint/resume survives a process restart out of the box.
Node built-ins only; recommended as the checkpoint store while shared
memory stays in RAM. Includes load-time hardening that rejects non-object
metadata.
Closes#338
Error-aware task retry (opt-in via maxRetries > 0):
- Skip retries on provably-terminal failures (4xx client errors except
408/409/429, token-budget, invalid-message, aborted calls).
- Equal jitter on backoff to avoid lockstep retries against a rate-limited
provider.
- Honor abortSignal between attempts (no full-backoff sleep or extra attempt
after cancel).
- Non-streaming path preserves the structured error on AgentRunResult.error so
classification works off the default runTeam path; test-covered.
Off by default; behavior changes only when retry is enabled.
Closes#337
* docs(examples): prefix example run commands with packages/core/
Examples live under packages/core/, and both READMEs document running them from the repo root (npx tsx packages/core/examples/<path>.ts), but the in-file Run: headers and a few READMEs still used the bare examples/ path. The repo root has no top-level examples/, so copy-pasting those commands from root failed with file-not-found.
Prefixes 67 run/cd commands across 56 files (53 example scripts + examples/README.md + two integration READMEs). Markdown links that use the bare examples/ path are correct relative links and are left unchanged.
* docs: prefix two stale examples/ path references in docs/
context-management.md and tool-configuration.md referenced bare examples/ paths that do not resolve from the repo root. Make the first a relative link (matching the convention in model-routing.md) and prefix the second with packages/core/. Follow-up to the run-command fixes in this PR.
Cuts the per-task O(N^2) shared-memory snapshot volume (reused-store skip) and re-runs coordinator synthesis on runTeam restore, plus docs/checkpoint.md and README coverage. Closes#20. Refs #294#312#313.
* refactor(repo): monorepo groundwork for an easier first run
Trying OMA for the first time costs more than it should: a lot to read before anything runs, and no one-command way to watch a team actually work. The plan is to fix that with a `npm create oma` scaffold (a multi-agent demo that runs on the first try) and an npm README that leads with getting started. Neither lands cleanly until core lives in its own package, so this PR does that part first.
This is groundwork, not the payoff: nothing changes for anyone installing `@open-multi-agent/core` today. It turns the repo into an npm-workspaces monorepo with core in `packages/core/`, and splits the README into a GitHub landing page (root) and the npm package page (`packages/core/`). Doing it now, while the repo is small, avoids migrating twice.
The published package is byte-identical: same name, same three runtime dependencies, same entry points, guarded by an isolated-install smoke test. `npm ci` + lint + test (1060) + build pass; the tarball still ships only `dist/`, `README.md`, `LICENSE`, and `package.json`.
* build: restore cross-platform optional deps in package-lock.json
Regenerating the lockfile on macOS pruned the non-host rollup/esbuild optional binaries (npm/cli#4828), so Linux CI could not load @rollup/rollup-linux-x64-gnu and vitest failed to start. Rebuild the lock from the pre-migration base so every platform variant is present again. Verified with npm ci + lint + build + test (1060).
* fix(examples,docs): correct monorepo paths and anchors after the packages/core move
with-vercel-ai-sdk example (pre-existing, surfaced by the move):
- package.json: the @open-multi-agent/core file: link was file:../../, which
resolves to packages/core/examples (no manifest). Corrected to file:../../..
(packages/core); predev cd updated to match.
- package-lock.json regenerated: was linking ../.. and pinning a stale core
1.4.0; now links ../../.. at 1.7.0.
- README: setup paths and the file: note updated.
docs missed by the move:
- docs/cli.md: repo-clone build output is now packages/core/dist/cli/oma.js;
the quick-start anchor now lives in the package README.
- CONTRIBUTING.md: the architecture anchor and src/ entry-point paths now live
under packages/core/.
* chore: resolve .gitignore merge conflict
* feat(bedrock): implement native reasoning round-trip via signature (#223)
Inbound chat(): extract signature from reasoningText.signature and
redactedContent bytes into ReasoningBlock IR fields.
Inbound stream(): accumulate reasoningContent.signature delta into the
reasoning buffer; stamp onto the block at contentBlockStop.
Outbound: bedrock-provenance blocks with signature echo natively via
reasoningContent.reasoningText.{text,signature}; blocks with redactedData
echo via reasoningContent.redactedContent; unsigned foreign-provenance
blocks fall back to the existing thinking text path.
Upgrade capabilities.echoesReasoning from never to own-issued.
Add 9 new tests covering inbound/outbound round-trip for chat() and stream().
Update llm-adapter-capabilities test to reflect the new capability value.
Closes#223
* fix(bedrock): handle redactedContent delta in stream(), update docs
stream() handled the signature delta on ReasoningContentBlockDelta but
not redactedContent (the delta is a union of text/signature/redactedContent),
so a redacted thinking block over streaming was silently dropped even
though chat() already round-trips it. Buffer redactedContent per content
block index alongside text/signature and flush it into
ReasoningBlock.redactedData (base64), mirroring chat()'s handling, on both
the normal contentBlockStop path and the end-of-stream safety net.
Also updates docs/context-management.md, which still listed Bedrock under
capabilities.echoesReasoning === 'never' pending this exact follow-up; the
table and notes now reflect 'own-issued' with native round-trip on both
chat() and stream() (closes#223).
* Update .gitignore to remove markdown files
Remove specific markdown files from .gitignore
---------
Co-authored-by: Jack Chen <chenkaijie01@gmail.com>
Add docs/model-routing.md covering the opt-in modelRouting policy:
match dimensions, route config, routed phases, and the opt-in /
no-mutation guarantees. Link it from README.md and README_zh.md
following the docs/consensus.md precedent.
Refs #286, #271
* fix(tools)!: make built-in tools opt-in (default-deny)
A no-tools agent received every registered built-in, including an unsandboxed
bash, on the default path (runAgent, runTeam/runTasks, and the runTeam
short-circuit). Tool output flows back to the model provider, so under prompt
injection this was a remotely triggerable exec + exfiltration primitive. #83
added the allowlist/preset mechanism but kept default-allow; #264 sandboxed the
filesystem tools but left bash unsandboxed; together they opened this.
Built-in tools now require a positive grant via tools or toolPreset; with
neither, an agent resolves to zero. resolveTools() is the chokepoint and the
runner gates execution on the granted set, so a registered-but-ungranted call
returns a "not granted" error instead of running. Custom/runtime tools
(customTools/addTool) stay available since registration is the grant, and still
honor disallowedTools. delegate_to_agent follows the same rule. Same default-deny
model #87 enforces for cross-agent context.
OrchestratorConfig.defaultToolPreset restores the old allow-all in one line;
per-agent tools/toolPreset override it.
BREAKING CHANGE: agents relying on implicit built-in tools get none until
granted. Restore with defaultToolPreset: 'full', or grant per agent via
tools/toolPreset.
* docs: clarify defaultToolPreset excludes coordinator, synthesis, and consensus agents
* feat(minimax): upgrade default model to MiniMax-M3
- Switch the default minimax model hint in CLI from M2.7 to M3
- Update docs/providers.md, docs/providers/minimax.md, examples/providers/minimax.ts
and README mentions to recommend M3 as the default
- Note that M2.7 and MiniMax-M2.7-highspeed remain selectable for callers
that pin a model explicitly
- M3 specs: 512K context window, up to 128K output tokens, image input support
* docs(minimax): correct M3 context to 1M, drop unverified output-token figure
---------
Co-authored-by: octo-patch <octo-patch@github.com>
Co-authored-by: Jack Chen <chenkaijie01@gmail.com>
`runConsensus()` runs a proposer→judge propose/refute/converge loop, and an opt-in per-task `verify` hook applies the same check to a task's own result. Judges run sequentially to a quorum (refute or lens mode); only an accepted revision supersedes the task output, and judge usage counts against the parent `maxTokenBudget`.
Closes#275
* feat(llm): add Tencent Hunyuan provider adapter
Add a built-in `hunyuan` provider shortcut wrapping the OpenAI-compatible
Tencent Hunyuan API, following the existing doubao/qiniu thin-wrapper pattern.
- Default endpoint is the current Tencent MaaS / TokenHub surface
(https://tokenhub.tencentmaas.com/v1, `sk-...` keys, models like
`hy3-preview`). Tencent has announced the legacy Tencent Cloud endpoint
(https://api.hunyuan.cloud.tencent.com/v1) is being retired (sales stop
2026-06-30, full shutdown 2026-09-30); it remains reachable via
HUNYUAN_BASE_URL until then.
- HUNYUAN_API_KEY for credentials, optional HUNYUAN_BASE_URL to switch
clusters without code changes (mirrors the MiMo/MiniMax convention).
- Register in createAdapter factory, SupportedProvider, CLI provider
reference and model hint.
- Add adapter unit tests, a provider example, and provider docs.
Verified chat + function calling end-to-end through the framework adapter
interface against both surfaces: `hy3-preview` on TokenHub and
`hunyuan-turbos-latest` on the legacy Tencent Cloud endpoint.
* docs(hunyuan): align example label and adapter comments with MaaS/hy3 default
The adapter now defaults to the Tencent MaaS / TokenHub endpoint with the
hy3-preview model. Update the example index label (TurboS -> MaaS, hy3) and the
adapter docstring's default model / endpoint references to match.
Co-authored-by: Cursor <cursoragent@cursor.com>
* docs(hunyuan): scope tool-calling claims to verified models
* fix(llm): echo reasoning_content for Hunyuan interleaved thinking
hy3-preview (the default Hunyuan model) is a reasoning model whose
interleaved-thinking + tool-calling mode requires the prior turn's
reasoning_content to be backfilled on each tool-using turn per Tencent's
TokenHub spec; HunyuanAdapter inherited OpenAI's 'never'. Set
echoesReasoning: 'tool-use-only' (same as DeepSeek/MiMo). turbos/functioncall
emit no reasoning_content, so it is a no-op for them.
Refs #281
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Sandbox default root narrows from `process.cwd()` to `<cwd>/.agent-workspace`, an auto-created subdirectory. Built-in filesystem tools (`file_read`, `file_write`, `file_edit`, `grep`, `glob`) enforce this root and require absolute paths. `bash` is intentionally out of scope; full caveat and the three-config knob (default / `process.cwd()` / `null`) live in `docs/tool-configuration.md`.
`defaultWorkspaceDir()` centralises the fallback; `OrchestratorConfig.defaultCwd`, `AgentConfig.cwd`, `RunnerOptions.cwd`, and the tool-layer fallbacks in `path-safety`, `grep`, and `glob` all route through it. Only `file_write` auto-creates the root via `resolvePathWithinCwd`'s new `ensureRoot` option; read-only tools error on a missing root.
22 examples switched from `/tmp/` to `<cwd>/.agent-workspace/<sub>` (basics x 3, providers x 18, integrations x 1). `mcp-bilig-workpaper` routes its existing tmpdir workDir into the Agent's `cwd`.
`README.md`, `README_zh.md`, `docs/tool-configuration.md`, `docs/cli.md`, `docs/providers/minimax.md` updated. JSDoc on the four `cwd` fields aligned with the new default. `.gitignore` ignores `.agent-workspace/`.
`v1.4.2` is current on npm; no released version is affected. Consumers wanting the prior `process.cwd()` default can set `defaultCwd: process.cwd()` explicitly.
Sandbox built-in filesystem tools (`file_read`, `file_write`, `file_edit`, `grep`, `glob`) to a per-agent working directory. Paths must be absolute and resolve inside that directory; symlinks are resolved via `realpath` before the check and skipped during recursive walks via `lstat`. New config: `AgentConfig.cwd`, `OrchestratorConfig.defaultCwd`, `CoordinatorConfig.cwd` (per-agent override > orchestrator default > `process.cwd()`).
`bash` is deliberately not sandboxed; pass `disallowedTools: ['bash']` if path containment matters. Process-group cleanup is now in place so backgrounded children no longer outlive timeouts or aborts; aborted runs exit 130.
`mcp.ts` forwards `ToolUseContext.abortSignal` into `callTool` so MCP tools observe agent cancellations.
`resolvePathWithinCwd` returns the realpath-resolved candidate (rather than the raw input) so callers hand a symlink-free path to fs APIs, closing the TOCTOU window between the sandbox check and the fs call. The new `realpathTolerant` helper handles non-existent paths (e.g. `file_write` creating a new file) by resolving the longest existing prefix and re-attaching the suffix.
**Behavior change.** Sandbox is on by default. Agents that previously read or wrote files outside \`process.cwd()\`, or used relative paths, now get a sandbox error. Set \`OrchestratorConfig.defaultCwd\` to your workspace root for multi-directory deployments, or pass \`defaultCwd: null\` to restore unrestricted access.
First-class `provider: 'mimo'` backed by the OpenAI-compatible adapter, defaulting to https://api.xiaomimimo.com/v1 and MIMO_API_KEY. Token Plan keys (tp-*) read MIMO_BASE_URL for the cluster URL.
Overrides `echoesReasoning` to 'tool-use-only' so tool-calling agents replay reasoning_content correctly, matching DeepSeek V4 (#251).
Refs #25.
* feat(llm): cross-provider reasoning text fallback with opt-in (#223 Phase 2)
Phase 2 of #223 — wires the shared `<thinking>` text fallback into every
adapter's outbound path behind two new opt-in flags.
User-facing API (`AgentConfig` / `LLMChatOptions`):
- `preserveReasoningAsText?: boolean` — default `false`. When `true`,
outbound IR-to-native conversion downgrades each `ReasoningBlock` that
the target adapter cannot natively echo to inline `<thinking>` text and
prepends it to the next text part (rather than dropping silently).
- `compressReasoningText?: boolean | { minChars?: number }` — defaults
default-on when `preserveReasoningAsText` is true (per maintainer's #223
guidance to "tie compress default-on to the preserve flag"). Mirrors the
shape of `compressToolResults`; head+tail truncation defaults to 1200
chars per block.
Adapter wiring:
- openai-common.ts: refactored to drop the never-wired (since #234)
`OpenAIReasoningReplayOptions` type in favour of reading the AgentConfig
flags. Replaced the private `reasoningBlockToThinkingText` /
`truncateReasoningForReplay` helpers with the shared
`reasoningBlockToInlineText` introduced in Phase 1.
- openai.ts / azure-openai.ts / copilot.ts pass the new flags through
`buildOpenAIMessageList`. Subclasses (deepseek, grok, qiniu, minimax)
inherit chat() so the wiring propagates automatically.
- anthropic.ts: foreign-provenance reasoning falls back to plain text when
opt-in is set; own-provenance signed blocks still native-echo (Phase 1
contract unchanged); own-provenance UNSIGNED blocks now also fall back
to text rather than dropping silently (was always wasted otherwise).
- gemini.ts: same own/foreign-provenance pattern as anthropic, with the
same outbound capability gate.
- bedrock.ts: capability is `'never'` (until the deferred signature
follow-up restores native echo); all reasoning falls back to text when
opt-in is set. Emits a standalone text block since Bedrock messages
accept multiple content blocks.
- ai-sdk.ts: capability `'never'` — when opt-in is set, swaps the
AI SDK structured `{type: 'reasoning'}` part for a text part wrapped
in `<thinking>`. Default-off preserves pre-Phase-2 pass-through behaviour
to avoid silently changing what existing users have today.
Tests:
- Refreshed openai-common.test.ts to use the new flag names. Added cases
for `compressReasoningText: false` (no truncation) and the default-on
semantics when preserve is true and compress is undefined.
- Added per-adapter `reasoning text fallback (#223 Phase 2)` describe
blocks to anthropic, gemini, bedrock, and ai-sdk test files. Each
covers the default-off drop, the opt-in text-fallback, the
own-provenance native echo path, and (for anthropic) the redacted
placeholder.
- Updated tests/reasoning-fallback.test.ts so `maxChars: Infinity` now
asserts pass-through (no truncation) rather than clamp-to-1. The
positive-Infinity sentinel is how callers signal
`compressReasoningText: false`.
Docs + example:
- docs/context-management.md gains a "Preserving Reasoning Across
Providers" section with capability table, default behaviour rules,
and the loop-detector caveat for local OpenAI-compatible models.
- examples/patterns/cross-provider-reasoning.ts demonstrates the
Agent.prompt() model-swap scenario and documents the loop-detector
failure mode.
Refs #223
* test(llm): tighten reasoning-flag propagation test scope (#223 Phase 2 self-review)
Address self-review feedback before opening the Phase 2 PR:
- tests/runner-reasoning-flags.test.ts: rewrite header to honestly describe
what is covered. `AgentRunner.stream()` internally drives turns via
`adapter.chat()` (`runner.ts:766`) — `adapter.stream()` is on the
`LLMAdapter` interface but unused by the runner. The previous "stream path"
claim was therefore testing a non-existent code path. Drop the dead
`capturedStream` instrumentation; replace it with a `runner.stream()`
entrypoint test that exercises the same `adapter.chat()` propagation,
pinning the contract for the stream-side flag flow.
- tests/reasoning-fallback.test.ts: add a runtime-invariant test for the
`NO_TRUNCATION` constant. The Phase 2 commit exported the sentinel and
documented it in JSDoc, but had no test that would CI-fail if a future
refactor removed the `Number.POSITIVE_INFINITY` special-case branch in
`resolveMaxChars`. The new assertion ties the constant value, the
resolver branch, and the documented "no truncation" contract together.
Refs #223
* docs(context-management): acknowledge tool-use-only third capability state
After merging upstream/main (which added 'tool-use-only' for DeepSeek V4
via #251), update the capability table to include the new state and its
two sub-rules:
- tool-calling conversation → native reasoning_content echo
- non-tool conversation → drop (DeepSeek spec)
Also clarify that 'tool-use-only' is the only capability where
same-provider native echo happens WITHOUT preserveReasoningAsText opt-in
(the DeepSeek API forces it for protocol compliance).
Refs #223, #251
* fix(llm): add missing nativeReasoningEchoProvider to ReasoningOutboundOptions
Repair an omission from merge commit 9ca9a91: the field was added to my
working tree alongside the openai-common.ts conflict resolution, but
never staged — so the merge commit landed openai-common.ts referencing
`outboundOptions?.nativeReasoningEchoProvider` while the type declaration
on the receiving end (`ReasoningOutboundOptions` in reasoning-fallback.ts)
did not carry the field.
Locally the bug was masked because vitest runs against the working tree
where the field exists; `npm test` reported 869/874 passing. The pushed
branch would compile-fail at the openai-common.ts access site for any
reviewer pulling the PR.
This commit just adds the field declaration + its JSDoc (already used
correctly throughout openai-common.ts and openai.ts). No behaviour change
relative to what the merge intended.
Refs #223, #251
* fix: redact secrets in traces, bash env, and dashboard payloads
Adds src/utils/redaction.ts and applies best-effort redaction at three
sinks where sensitive data could leak:
- tool_call trace events (input, output)
- the bash tool's output buffer
- the post-run dashboard's embedded JSON payload
The bash tool no longer inherits the parent process.env. Child processes
receive a fixed allowlist (HOME, LANG, LC_ALL, LOGNAME, PATH, SHELL,
TEMP, TERM, TMP, TMPDIR, USER), so provider API keys and similar
secrets are no longer visible to spawned shells.
The post-run dashboard no longer loads Tailwind CDN, Google Fonts, or
Material Symbols at view time. The page is self-contained and renders
without network access.
llmMessagesToAiSdkModelMessages no longer concatenates the opaque
redactedData payload into the reasoning text emitted to the AI SDK; it
emits only the [redacted_thinking] marker.
The MCP GitHub example uses --no-install instead of -y and passes an
explicit env allowlist instead of spreading process.env.
* fix(redaction): consume full value for quoted and unquoted assignments
The single ASSIGNMENT_PATTERN stopped at the first whitespace inside a
value, so values with spaces were only partially redacted and the
remainder leaked into trace events, dashboard payloads, and the bash
output buffer. Three reviewer-reported cases on PR #263:
password=secret value -> password=[redacted] value
password="secret value" -> password="[redacted]" value"
apiKey: "abc def" -> apiKey: "[redacted]" def"
Splits the single pattern into two passes. The quoted pass consumes
to the back-referenced closing quote so password="my pass" is fully
matched. The unquoted pass consumes to the next structural delimiter
(comma, semicolon, brace, bracket, newline) so password=my pass is
fully matched.
Adds tests/redaction.test.ts covering the three reviewer cases, the
existing Authorization orphan-bracket regression, common token literal
patterns, and idempotence.
First-class `provider: 'doubao'` backed by the OpenAI-compatible adapter, defaulting to the Volcengine Ark endpoint and ARK_API_KEY env var.
Refs #25 (Doubao section). Original first-class attempt in #236 closed under the duplicate-claim rule when #232 was active.
DeepSeek retires deepseek-chat / deepseek-reasoner on 2026-07-24.
Switch DEFAULT_MODEL_HINT and examples to deepseek-v4-flash; upgrade
the examples/providers/deepseek.ts architect to deepseek-v4-pro since
deepseek-reasoner officially maps to v4-flash thinking mode and v4-pro
is the upstream "best for coding" pick. Adapter code unchanged.
* docs(examples/integrations): add governance README
Documents the two example categories under examples/integrations/:
- Reference integrations: wiring against widely used protocols or
frameworks (MCP, observability, Express, AI SDK). OMA team maintains
these once merged, regardless of who contributed them.
- Vendor integrations: examples paired with a specific third-party
commercial product. Reciprocal listing condition; no payment involved.
Adds submission flow for both categories and out-of-scope guidance.
Existing entries are credited to their contributors inline.
* docs: remove stale DECISIONS.md
Last updated 2026-04-09. The "Open to Adoption" section listed MCP as
up-next with #86 tracking, but MCP shipped weeks ago: tool/mcp.ts, the
@open-multi-agent/core/mcp subpath, and the mcp-github.ts example are
all in. Tracked issues (#20, #86, and the related #17) are all closed.
The "Won't Do" rationales for state persistence and agent handoffs are
preserved in their respective closed issue threads. The A2A
network-effect framing belongs in the README or internal strategy
notes, not a standalone infrequently-maintained doc.
Zero references in the repo. No broken links.
#239 removed the Doubao row because it pointed to a missing example and a sunset model ID. Both fixed now: example landed in #232 using doubao-1-5-pro-32k-250115.
#231 added a row pointing to examples/providers/doubao.ts (expected to
land via #232, still open) and using doubao-pro-32k (sunset by Volcengine
Ark on 2025-05-28). Users clicking through from the README hit both a 404
on the example link and an invalid model ID.
Add MiniMax as the first Founding Provider Community Offer Pilot
— a limited-time 12% discount for OMA users valid until 2026-06-30.
- README: new Provider community offers section in Ecosystem
- README_zh: Chinese equivalent (Provider 社区优惠)
- docs/providers/minimax.md: setup guide with offer details,
model description, configuration examples, and disclosure
* docs: align Chinese README with English version, optimize translations
- Restructure Chinese README to match English section order
- Add demo image, CI badge, Core Concepts section, AgentPool.runParallel
- Optimize 20+ translations for natural Chinese tech writing
- Tone adjustment: reduce colloquial language, unify terminology
- Remove feature-dump tagline and Grok/Groq disclaimer from both versions
- Clean up English README: fix awkward phrasing, missing article, extra blank line
- Add docs/observability.md and docs/providers.md
* Update README hero animation
* docs: use package-safe README hero URL
- Tighten positioning, lift demo, sharpen comparison table.
- Refresh temodar star count, drop dead link.
- Fold tool/memory/context sections into docs/.
- Swap npm downloads badge for GitHub forks.
- Correct custom context strategy signature and Copilot env var (README, README_zh, docs/context-management.md).
- Inline agent definitions so quick-start snippet is self-contained.
- Move CONTRIBUTING/CODE_OF_CONDUCT/SECURITY/codecov to .github/, DECISIONS.md to docs/.
- Fix CONTRIBUTING README link after the .github/ move.
- Ignore local .claude/ config dir.
- Restructure flow, sync README_zh, document quantized sampling.
- Refresh positioning, branding, and section layout (logo, banners, github social card).
- Polish Quick Start and consolidate provider tables.
- Drop forward reference to PR #174 in features bullet.
- Rework structure, factual fixes, add Featured Partner doc.
- Fix brand asset rendering: light banner no longer leaks the dark body background; dark banner and github-social regain previously-clipped content (terminal-log arrows, "★ open source" badge). Root cause: overflow:hidden on stage ancestors clipping the forced 1280px target during extraction.
- Replace fabricated token figures (12,847t / 8,402t / 3,914t) on the banner right column with action labels (design / impl / parallel / review). The numbers conflicted with how totalTokenUsage actually aggregates (input+output, includes coordinator decompose+synthesize, merges same-name agents).
Mirrors the DeepSeek provider coverage for Qiniu, landing after #154:
- README quick-start env list, Multi-model teams bullet, architecture
diagram, providers table (Verified), first-class support note, and
usage snippet with official Qiniu AI inference docs link
- docs/cli.md `oma provider template` list
- examples/providers/qiniu.ts modeled on examples/providers/deepseek.ts
* feat: expose custom MemoryStore via TeamConfig.sharedMemoryStore (#156)
The MemoryStore interface was already public, and SharedMemory / TeamInfo
already used the interface internally. This adds the final user-config wire
so integrators can attach custom backends (Redis, Postgres, Engram, etc.)
without hacking SharedMemory private fields.
Priority: sharedMemoryStore > sharedMemory: true > no memory.
Fully backward-compatible: existing sharedMemory: true users see no change.
SDK-only: the CLI cannot pass runtime objects through JSON config.
Closes#156.
* fix: validate sharedMemoryStore shape and reject from CLI JSON
Addresses Codex P2 review on #157. Plain objects from untrusted JSON could
previously reach `new SharedMemory(plainObject)` and crash later on the first
`.set`/`.list` call with a cryptic TypeError.
Defense-in-depth:
- SharedMemory constructor performs a runtime shape check and throws a clear
TypeError if the provided store does not implement get/set/list/delete/clear.
- CLI `asTeamConfig` explicitly rejects `sharedMemoryStore` in JSON with a
message pointing to the SDK path, since this field is documented SDK-only.
Adds 4 tests covering malformed stores (plain object, partial interface,
null, Team constructor path).
* fix: route falsy-but-present sharedMemoryStore through shape check
Addresses Codex finding 2 on #157. The truthy gate silently skipped falsy
values (null, 0, ''), letting config bugs downgrade to the default in-memory
store or no memory instead of failing fast.
Switched to `!== undefined` so any present value reaches SharedMemory's
runtime shape check and throws a clear TypeError. Adds 2 tests: null as a
bogus store throws; omitting the field still honors `sharedMemory: true`.
Adds `oma run --dashboard` to write a static post-execution DAG HTML to `oma-dashboards/runTeam-<timestamp>.html`.
- Pure `renderTeamRunDashboard(result: TeamRunResult)` in `src/dashboard/`, no FS/network I/O in the library
- `TeamRunResult` gains `goal` + `tasks: TaskExecutionRecord[]` (with `TaskExecutionMetrics`)
- `layoutTasks()` extracted as pure function with cycle detection
- XSS mitigations: `application/json` payload, `</script>` escape, `textContent`-only node rendering
- CLI awaits write before exit (no race with `process.exit`)
Closes#4
Co-authored-by: Ibrahim Kazimov <74775400+ibrahimkzmv@users.noreply.github.com>