Two roles failed in 2026-09 with STRUCTURED_OUTPUT_VALIDATION_FAILED on bracket mismatches deep inside long nested output, and the in-run correction failed the same way. #599 moved the nested object to the end of each schema so the model has no boundary to hold, which works around the symptom without changing what the provider guarantees. Set `response_format: { type: 'json_object' }` on the shared role config through `extraBody`. DeepSeek then guarantees that the answer parses as JSON, so the syntax failure class goes away at the source. A direct API probe with the pre-#599 planner schema, thinking at max effort, and a tool turn confirmed that DeepSeek accepts the mode in that combination and returned strict JSON on every run. OMA still validates the answer against the role's schema, so the in-run correction keeps handling schema mismatches. The scripted adapter test asserts that every role carries the mode, and the README documents it next to the shared output ceiling.
4.5 KiB
OMA Release Bot
This private workspace dogfoods @open-multi-agent/core to prepare OMA releases.
It is repository-local automation, not a published npm package.
Responsibility boundary
The bot deliberately separates judgment from authority:
- An explicit
runTasks()DAG runs two independent DeepSeek V4 Flash reviews in parallel: change classification and compatibility analysis. - A planner produces a bounded structured proposal. It can choose only
none,patch,minor, ormajorfor each package and concise changelog entries. - An independent reviewer approves or rejects that proposal.
- Deterministic TypeScript calculates versions, updates the known manifests and template pins, regenerates the lockfile, runs validation, and creates a ready pull request.
- A maintainer reviews and merges the PR. Only then can the deterministic
publish workflow run after
CIsucceeds on the exact merged release commit.
Every role thinks at DeepSeek's max effort and shares one 64,000-token
output ceiling. Reasoning and the answer are billed against that same ceiling,
so it is sized for both: a ceiling that only fits the answer leaves a role
emitting reasoning and no JSON, which surfaces as a schema failure rather than
as the truncation it is. The evidence roles have five turns and the planner and
reviewer three. Every DAG task has maxRetries: 0, so a failed role is not
silently rerun as a whole new analysis (OMA's one in-run structured-output
correction still applies). The complete planning DAG has a thirty-minute
wall-clock deadline. Every request also sets DeepSeek's JSON output mode
(response_format: json_object), so the provider guarantees that the answer
parses as JSON. OMA still validates the answer against the role's schema, so
the in-run correction only has to handle a schema mismatch, not a bracket
error in several thousand characters of nested output.
Repository diffs are untrusted evidence. The analyst and compatibility auditor
receive only three custom read-only tools: immutable release evidence, a
deterministic risk-ranked and size-bounded review bundle, and the release
contract. The model cannot supply repository paths to the bundle. The planner
and reviewer consume the immutable summary and structured dependency reports
without repository tools. No agent receives bash, filesystem write tools,
GitHub credentials, npm credentials, or publication tools.
Concrete package versions remain deterministic. In particular, every core
release increments create-oma-app; when no scaffolder files changed since the
last core tag, the bot forces a patch bump because the only release change is
the exact core template pin. A model-proposed larger scaffolder bump is used
only when the scaffolder workspace itself changed. This normalization happens
before the independent reviewer receives the proposal.
Commands
Run from the repository root after building the workspace:
npm run build -w @open-multi-agent/release-bot
# Read-only: calls DeepSeek and prints the structured result.
DEEPSEEK_API_KEY=... node packages/release-bot/dist/cli.js plan
# Mutating: intended for release-bot.yml with a GitHub App token.
node packages/release-bot/dist/cli.js prepare-pr
# Consequential: intended only for publish.yml with npm trusted publishing.
node packages/release-bot/dist/cli.js publish
prepare-pr validates the complete repository before it commits or pushes. It
refuses a dirty worktree, an advanced HEAD, unexpected file changes, duplicate
release PRs, and conflicting remote release branches.
publish is idempotent at package boundaries. It checks the public registry
before each package, publishes in the fixed core → otel →
create-oma-app order, waits for registry visibility, then creates the
lightweight core tag and GitHub Release. A rerun resumes missing stages. A tag
that exists before every expected package is visible fails closed.
Activation
The workflows are inert until maintainers configure the GitHub App, DeepSeek
secret, npm-release environment, and npm trusted publishers described in
.github/RELEASING.md. No long-lived npm token is
supported.
The GitHub App is intentional. GitHub documents
that pull requests or releases created with the repository GITHUB_TOKEN do
not trigger downstream workflows normally; an installation token lets PR CI
and release-smoke.yml start without a second manual workflow approval.