- separate application-owned data from model-visible text, image, and file content
- map rich results across built-in adapters and preserve them through recovery
- retain backward compatibility for string tools and text-only errors
Closes#466
Map OMA thinking controls to DeepSeek's native request shape, keep the provider-specific max effort isolated from other OpenAI-family adapters, and refresh model guidance and canary coverage.
* 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
* feat(dashboard): surface per-task model, provider, and cost in Run Viewer
Roll each task's descendant LLM spans up into task-level model/provider/cost via the span parent chain (LLM spans carry these but no taskId), so the task panel shows what a task actually used instead of Not recorded. Also render task UUIDs as 8-char short ids (full id kept in tooltip and data-task-id).
* docs(brand): regenerate hero from a real run with cost; add MP4
Inject real DeepSeek list-price cost onto LLM spans in the hero capture, regenerate the Run Viewer snapshot and GIF, and commit the H.264 MP4 (previously written only to a gitignored dir).
* docs(readme): trial inline MP4 hero via jsDelivr CDN
Branch-only experiment to check whether GitHub autoplays a hand-authored video tag; GIF kept as poster and fallback. Revert to the GIF img if autoplay is stripped.
* docs(readme): keep GIF hero (GitHub strips external-src video)
The trial video tag is dropped by GitHub's sanitizer because its src is not a GitHub-hosted asset, taking the fallback img with it. Restore the original GIF img hero.
* feat(dashboard): show tool-call count on task detail; refresh hero
Task detail shows Tool calls: N instead of an N/A Tool row, so the task panel has no remaining Not recorded fields. Re-record the hero GIF/MP4 and refresh the snapshot HTML.
* feat(brand): swap hero demo to a JWT-auth run built by a specialist team
Replace the generic Express CRUD capture with a JWT (HS256) auth module built by five specialists (architect, backend-dev, qa-engineer, security-analyst, reviewer) in a 3-way parallel fan-out (implement + tests + threat-model) converging on an integration review, so the hero reads as work that needs a team. Harden the agent prompts (pinned filenames, minimal per-role tool grants, node --check only) so the capture runs clean on the first pass.
* docs(readme): list packages instead of a table to stop name wrapping
The two-row Packages table squeezed the Package column in the English README and wrapped the package names across lines. GitHub strips <nobr> and inline style, and non-breaking hyphens would break npm install copy-paste, so switch to a bulleted list where each name sits on a full-width line. Applied to README_zh.md too for parity.
Move the coordinator subsystem out of orchestrator.ts into coordinator.ts:
goal-decomposition parsing, coordinator prompt construction (system prompt,
roster, output format, decomposition), the synthesis pass, and task-spec loading.
The parse helpers are a pure move. The former private class methods become free
functions; two take the orchestrator config explicitly (buildCoordinatorBaseConfig,
runCoordinatorSynthesis) instead of this.config. Prompt string literals are
byte-for-byte unchanged (only code indentation shifts as methods de-indent to
module scope). One type follow-on: runCoordinatorSynthesis gains a
`?? DEFAULT_MODEL` guard because OrchestratorConfig.defaultModel is optional where
the resolved class field was not; it is dead at runtime (callers pass the resolved
config) and mirrors the same guard already in task-execution's executeQueue.
orchestrator.ts drops from 2213 to 1683 lines (57% below the original 3953). Also
updates the AGENTS.md layer map.
Verified with npm run lint, 1385 passing tests, zero diff under tests/, a
byte-identical parse block, all 87 single-quoted and 17 backtick prompt-string
literals identical, and a dist/index.d.ts identical to the pre-split build.
Third of three sequential pure-move PRs; builds on the merged #400 and #397.
Move the orchestration loop and the consensus subsystem out of orchestrator.ts
into two focused modules, with zero behavior change:
- task-execution.ts: the dependency-ordered execution loop (executeQueue),
delegation team-info, checkpoint saves, and per-task prompt assembly
- consensus.ts: the proposer/judge verification loop (runConsensusCore) and the
per-task verify hook (runTaskVerify)
orchestrator.ts drops from 3305 to 2213 lines. task-execution depends on
consensus (runTaskVerify); both build on the PR1 foundation modules. The module
graph stays acyclic.
Pure move: extracted bodies are byte-identical to the originals (only an export
prefix added) and the kept region is byte-identical. Verified with npm run lint,
1385 passing tests, zero diff under tests/, and a dist/index.d.ts identical to
the pre-split build.
Second of three sequential pure-move PRs; builds on the merged #397 foundation
modules.
Move pure module-level helpers out of the 3953-line orchestrator.ts into five
focused modules, with zero behavior change:
- run-context.ts: RunContext/ActiveCheckpoint types, run identity/metadata
helpers, and the token/error utilities (the dependency-free base)
- budget.ts: token/cost accounting, budget-cap enforcement, run-metrics rollup
- short-circuit.ts: isSimpleGoal / selectBestAgent
- retry.ts: executeWithRetry / computeRetryDelay
- agent-config.ts: buildAgent, default-tool-preset grant, model routing
orchestrator.ts drops to 3305 lines and re-exports isSimpleGoal, selectBestAgent,
computeRetryDelay, and executeWithRetry, so the index.ts barrel and all test
import paths are unchanged.
Pure move: extracted bodies are byte-identical to the originals (only an export
prefix added) and the kept region is byte-identical to origin/main. Verified with
npm run lint plus 1385 passing tests, zero diff under tests/, and a
dist/index.d.ts identical to the pre-split build.
First of three sequential pure-move PRs (PR2: consensus + task-execution;
PR3: coordinator + AGENTS.md).