* chore: release core v1.21.3 and create-oma-app v0.8.10
* docs(changelog): tighten the 1.21.3 entry
State the security fix once under Security with the affected range, keep Fixed for the two behaviors earlier releases shipped, and drop the ELOOP claim, which described a defect that existed only inside the fix PR and never shipped. Compatibility now points callers who write through an outside link to widening the working directory.
---------
Co-authored-by: oma-release-bot[bot] <315310457+oma-release-bot[bot]@users.noreply.github.com>
Co-authored-by: Jack Chen <jack@yuanasi.com>
* chore: release core v1.19.0, otel v0.1.4, and create-oma-app v0.8.5
* docs(changelog): correct two 1.19.0 claims and record two missed changes
Two entries described behavior that the code and docs do not support.
`restore()` was written as though the run store turns it into the resume
command. It is the resume command either way; `docs/run-store.md` states that
directly. What a run store adds is making a suspended record eligible and
taking the lease before the approval ledger is reconciled.
The `INVALID_TEAM_MAX_CONCURRENCY` entry asked readers to review `onProgress`
handlers that match event codes exhaustively. `OrchestratorEvent.type` gained
no member, `warning` already existed, and `data` is typed `unknown`, so no
exhaustive match can break. The entry now states what was added instead of
implying a compatibility review.
Two published changes were not recorded. The `delegate_to_agent` pool-exhausted
error text changed with the team concurrency work, and it is tool output rather
than a comment. The `@open-multi-agent/core` npm description was rewritten,
which is the first thing a reader sees on the package page.
Also drops "according to the supplied evidence" from the DeepSeek entry. It
described how the entry was written rather than how the name behaves.
* docs(changelog): describe the scaffolded _env.example change precisely
The 1.19.0 compatibility note said create-oma-app now scaffolds
OMA_MODEL=deepseek-flash. The template only names the model in a commented
DeepSeek block, so a generated project does not enable it by default. Say
what the file carries instead of implying an active setting.
* docs(changelog): name the scaffolded file as generated projects see it
The template ships as `_env.example` because npm strips real dotfiles on
publish, and `scaffold.ts` renames it to `.env.example` in the generated
project. A reader of this note has the generated project in front of them,
where the underscore form never appears.
---------
Co-authored-by: oma-release-bot[bot] <315310457+oma-release-bot[bot]@users.noreply.github.com>
Co-authored-by: Jack Chen <jack@yuanasi.com>
* chore: release core v1.18.0 and create-oma-app v0.8.4
* docs(changelog): name the otel release and the judgePrompt call-count change
Two gaps in the generated 1.18.0 entry.
The entry names @open-multi-agent/otel twice but never its version, so a reader
cannot tell which release carries upstream-policy. Both opt-ins are required to
get tool input/output into OpenTelemetry, which makes that number exactly the
one a reader needs, and earlier entries stated otel's version even when it was
not republished. The generated GitHub Release body lists package versions in its
own section, so the omission was confined to this file.
judgePrompt also changed how often it runs, not only what it may return. #563
moved it from once per score() call to once per judge, which a caller whose
judgePrompt is costly or has side effects observes directly. The Compatibility
note is narrowed to the signature, which is the part that actually stayed the
same.
---------
Co-authored-by: oma-release-bot[bot] <315310457+oma-release-bot[bot]@users.noreply.github.com>
Co-authored-by: Jack Chen <jack@yuanasi.com>
A library that gets installed into someone else's backend is judged partly on
what its own install pulls down. Three changes tighten that, and two questions
turned out to need no change at all.
The line this draws is what ships. Every dependency that stays inside the
repository is now pinned to the exact version the lockfile already resolved:
all 27 devDependencies across the four workspaces, plus the private release
bot's own zod. The lockfile change is 28 spec lines with no
resolution moved, no entry added or removed, and all 61 platform-specific
entries intact. A new root .npmrc sets save-exact=true so the next one arrives
pinned rather than as a range nobody notices.
What a consumer installs keeps its range: `dependencies` in packages/core, the
only published runtime block here, every `peerDependencies`, and otel's core
compatibility range. An exact version in those blocks overrides the consumer's
own resolution and stops their `npm audit fix` from reaching a patched build
until we cut a release, which is a worse trade than the install-time drift it
prevents. save-exact will still pin a new dependency added to one of them, so
the package job now asserts all three published manifests and fails when one
is left exact, next to the assertion that already covers otel's range.
min-release-age is deliberately not set. It first shipped in npm 11.10.0, and
the CI matrix runs Node 20 and 22, which bundle npm 10.8.2 and 10.9.8. Those
two accept the key, echo it back from `npm config get`, and never act on it,
so a quarantine window would hold on one leg of the matrix while silently
doing nothing on the other two. It also has no effect on `npm ci`, which
installs the lockfile verbatim.
Every `npm ci` that installs this repository's own tree now passes
--ignore-scripts, so a compromised dependency cannot run an install hook on a
runner that holds release credentials. Only three dependencies declare a
postinstall at all, and the full lint, test, build, scaffold, and example
suites pass on a tree installed that way. The `npm install` calls that stand
in for a real consumer are deliberately left alone: their job is to reproduce
what a user's install actually does, and hardening them would make the smoke
tests prove less than they claim.
A new scheduled Supply chain audit workflow asks two questions about the
dependencies that reach a consumer, an hour before the weekly release bot so a
finding lands before the release PR is drafted. --omit=dev is the point of
running it separately: auditing the full tree reports eighteen advisories,
every one of them in test and fixture tooling that never ships, and a
permanently red job is one nobody reads. The two steps fail differently.
`npm audit` reports into the run summary, because a new upstream advisory is
not this repository misbehaving and may have no fixed version yet.
`npm audit signatures` fails, because it compares served bytes against the
registry's own signature, so a mismatch is tampering rather than churn; all
27 production packages verify today.
Two things needed no change. npm provenance is already live: publish.yml
publishes through npm trusted publishing with id-token: write, which attaches
SLSA attestations on its own, and every version since core 1.16.0, otel 0.1.2,
and create-oma-app 0.8.1 carries one. And .npmrc left .gitignore in #198
because it only restated the default registry; it comes back tracked, with the
ignore rule narrowed so a contributor's own nested .npmrc stays out.
Every observability example used an in-process exporter, which proves the
adapter's semantics but never serializes a span or opens a socket. Nothing in
the repository showed the path an OpenTelemetry user actually takes, so the
exporter choice, Resource, auth headers, and shutdown order were left for each
reader to reconstruct.
`otlp-backend.ts` runs OTel SDK to OTLP/HTTP exporter to HTTP to a backend, and
prints what crossed the wire. The backend is a loopback listener the example
starts itself, so it still needs no API key, no external collector, and no
internet access; `OTLP_URL` and `OTLP_HEADERS` redirect the same payload to a
hosted vendor.
It also demonstrates two things that are easy to get wrong. `service.name`
belongs to the provider's Resource, and a provider built without one files
every span under `unknown_service:node`. Tool input and output require both
halves of the capture opt-in, so the example sets the core policy and the
adapter mode together and states what the run exports without them.
`runToolDemo` joins the shared demo runtime so the example can show a real
`execute_tool` span; the existing `runDemo` export is unchanged. The example is
registered in the catalog and in the smoke script, which now runs eight
examples.
* chore: release core v1.17.0 and create-oma-app v0.8.3
* docs(changelog): state the actual JSON Schema required-field change
The generated Compatibility section described the release bot's own review
scope instead of the release. It also summarized the #549 alignment as
"potentially stricter", which is half right: switching from a wrapper-type
check to Zod's isOptional() makes .nullable() properties required and stops
z.any() and z.unknown() properties from being required.
Replace both bullets with what changed and who it reaches. The export claim
is verified against the v1.16.1 barrel and subpath exports; the schema
behavior against zod 3.25.76.
---------
Co-authored-by: oma-release-bot[bot] <315310457+oma-release-bot[bot]@users.noreply.github.com>
Co-authored-by: Jack Chen <jack@yuanasi.com>
bench/ measures a multi-agent run against a single-agent baseline pursuing the
identical goal, on tokens, wall-clock, cost and judge-scored quality. Three
groups per task: A runs runTasks() with deterministic model routing and a token
budget, while B and C run one agent on the strong and the cheap tier, bracketing
A from both sides so an effect that holds against both is attributable to the
orchestration rather than to the model mix. Two tasks ship with it, both from
packages/core/examples/cookbook/: a four-role contract review DAG and a
single-pass meeting report.
Role prompts are read out of the example source at load time rather than
restated in the harness, so what gets measured cannot drift from what the
examples say. Token counts come off each provider response through a loopback
recording proxy, because TokenUsage carries no cache field and no per-model
split and so cannot price a group A run that deliberately mixes two tiers. The
framework's own counts are recorded alongside, and any disagreement lands in the
row's notes instead of being reconciled silently.
Quality is judge-scored, blind, and run in both presentation orders so position
preference cancels. A is judged once per challenger and each of those scores is
kept separately: A's score against B and its score against C are two
measurements taken under two different contrasts, and only the first belongs in
an A-minus-B comparison.
The report states only what it computed. Whether the token budget bound is read
off budget_exceeded. What dropping cache-contaminated repetitions would do to
the headline is recomputed and printed, including whether any comparison
reverses direction. Which rate schedule the invocation was billed on is checked
against the manifest's UTC window rather than assumed, because the configured
prices are peak rates and a run that happened off-peak was billed half of what
the cost column says. Vendor-specific facts are emitted only for the vendor that
actually ran, and a missing manifest is an error rather than a report whose
models and controlled variables all read unknown.
bench/ is not an npm workspace, so it is reached through explicit root scripts:
npm run lint ends with lint:bench, and npm test ends with bench:ab:test. Both
run in CI, the tests across Node 20, 22 and 24. npm run bench:ab:mock drives the
full pipeline against an offline stand-in upstream, so the wiring is checkable
without a key or a provider call.
Results (bench/REPORT.md, bench/results-*.csv, bench/runs/) are gitignored.
* chore: release core v1.16.1 and create-oma-app v0.8.2
* docs(changelog): scope the 1.16.1 entry to published behavior
Remove entries no consumer of the published packages can observe: the
release-bot fixes and the create-oma-app bump rule live in tooling that
is never published, the standalone consensus leak was introduced and
fixed inside this unreleased window so 1.16.0 never carried it, and
examples are excluded from the npm tarball. Correct the compatibility
note, which described the internal runConsensusCore signature as public
API.
Matches the editorial line set when 1.16.0 shipped in #523.
---------
Co-authored-by: oma-release-bot[bot] <315310457+oma-release-bot[bot]@users.noreply.github.com>
Co-authored-by: Jack Chen <jack@yuanasi.com>
* chore: release core v1.16.0 and create-oma-app v0.8.1
* docs(changelog): dedupe 1.16.0 sections
Collapse the duplicated Added/Changed/Fixed sections and drop release-bot and release-process entries that are not core public behavior.
---------
Co-authored-by: open-multi-agent-release-bot[bot] <315310457+open-multi-agent-release-bot[bot]@users.noreply.github.com>
Co-authored-by: Jack Chen <jack@yuanasi.com>
Co-authored-by: Jack Chen <chenkaijie01@gmail.com>
* fix(release-bot): disable thinking for synthesis agents
The release-reviewer runs with thinking effort high and maxTokens 3500. Its reasoning consumed the whole output budget (two attempts at ~3500 reasoning tokens each, empty text both times), so it never emitted the JSON releaseReviewSchema requires and structured-output validation failed after retry, failing the release closed. Disable extended thinking for the two synthesis agents (planner and reviewer) so they emit structured output directly. The two evidence agents keep high-effort thinking.
* chore: remove maintainer issue-to-PR automation
Removes the maintainer-bot, maintainer-host, maintainer-runtime, and
maintainer-harness-canary workspaces, their GitHub Actions workflows, and
their documentation. This issue-to-Draft-PR automation is removed in favor
of a local maintainer workflow.
Add a read-only Claude Code and DeepSeek harness canary with deterministic validation, credential isolation, bounded artifacts, and documented promotion gates.
The root `npm audit --omit=dev` reported two `fast-xml-builder` advisories,
GHSA-5wm8-gmm8-39j9 (high) and GHSA-45c6-75p6-83cc (moderate), reached through
`@aws-sdk/client-bedrock-runtime@3.1040.0`.
Consumers were never exposed. The Bedrock SDK is an optional peer dependency,
so a plain `@open-multi-agent/core` install resolves four packages, contains no
`@aws-sdk` directory, and audits clean. The advisories only ever sat in this
repository's own development tree.
`packages/core/package.json` already declares `^3.1040.0`, which permits the
fixed version, so only the lockfile pin held the vulnerable chain in place.
Refresh it to 3.1101.0, whose dependency tree no longer contains
`@aws-sdk/xml-builder`'s `fast-xml-parser` chain at all. No manifest changes.
Bump the three published packages for the coordinated npm release of the work
merged after v1.13.0, pin every generated starter to core 1.14.0, and finalize
the 1.14.0 changelog.
Core ships adaptive plan recovery, opt-in hybrid semantic execution routing,
DeepSeek V4 Flash reasoning controls, globally enforced task requirements, and
fail-closed validation for task DAGs and coordinator plans. The engines floor
moves from Node 18 to Node 20 across all three packages, so otel is republished
to carry that change; its core dependency range stays ^1.11.0.
#453 retargeted OpenAI to v6 and retained Node 20, and lowered the AI SDK
development dependencies in the same pass. Core still declares
`ai: ^5.0.0 || ^6.0.0 || ^7.0.0` as an optional peer range, so the AI SDK 7
support added in #348 was left without any test coverage.
Restore `ai` to ^7.0.0 and `@ai-sdk/openai` and `@ai-sdk/provider` to ^4.0.0
so the adapter is exercised against the newest range the package advertises.
These are development dependencies only, so no published bytes change.
`ai@7` declares `engines: node >=22` while core supports Node 20, so the
Node 20 leg now logs EBADENGINE warnings. The repository sets no
`engine-strict`, so installation still exits 0 and the full suite passes.
Refs #348, #453
* chore(deps)!: upgrade OpenAI SDK to v7
Require Node.js 22 across packages, starters, and CI. Add real SDK boundary coverage and reject unsupported custom tool calls explicitly.
Refs #391
* fix(core): classify OpenAI user aborts as cancellation
Use the SDK error constructor name because OpenAI v7 APIUserAbortError retains the default Error name. Cover retry and observability classification with the real SDK class.
* chore(deps)!: target OpenAI v6 and retain Node 20
* docs: simplify Node runtime guidance
The OTel JS ecosystem convention (official instrumentations, @vercel/otel, @prisma/instrumentation) is a peer dependency on the API so the application owns the single copy; npm 7+ auto-installs it. The package also moves off lockstep-with-core onto its own version track starting at 0.1.0, releasing only when it changes; compatibility is expressed by the ^1.10.0 core range.
* 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.
Widen the ai peer range to include v7, bump dev deps (ai@7, @ai-sdk/provider@4, @ai-sdk/openai@4), update the with-vercel-ai-sdk example (ai@7, @ai-sdk/react@4, @ai-sdk/openai-compatible@3) and migrate it to the v7 standalone UI-stream helpers, and document that the bridge needs Node 22 while core stays 18.
Patch release.
Fixes:
- defaultModel is now inherited by all executing agents, not just the
coordinator (#323)
- support Vercel AI SDK v6 in the optional peer range (#324)
create-oma-app template pin bumped to core 1.8.1 (CI-enforced match).
Widen the optional `ai` peer from `^5.0.0` to `^5.0.0 || ^6.0.0` so installs
that pair @open-multi-agent/core with AI SDK v6 (e.g. via @ai-sdk/react@3,
which pulls ai@6) no longer fail with ERESOLVE.
AISdkAdapter is compatible with both majors after one shim: v6 types
streamText().totalUsage as a PromiseLike (no .catch), so wrap it in
Promise.resolve() before the rejection guard. Dev deps bumped to the v6
line (ai@6, @ai-sdk/provider@3, @ai-sdk/openai@3) so CI typechecks the
adapter against v6.
npm's package-name similarity protection permanently rejects the
unscoped `create-oma`, so the intended `npm create oma` could never
resolve for users. Rename the package and command to `create-oma-app`
/ `npm create oma-app` so the one-command first run actually works;
the `-app` suffix keeps the OMA name and reads naturally.
Pure rename — package name, bin, directory, the command text in the
scaffolder and READMEs, and the CI workspace/path references. The
generated demo and template are unchanged. Published to npm as
create-oma-app@0.1.0.
* 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/.