# Changelog

All notable changes to `@openthomas/thomas`. The format follows [Keep a
Changelog](https://keepachangelog.com/en/1.1.0/) loosely; dates are local
to where the release was cut.

## [0.5.0] — 2026-05-27

The first "fleet harness" cut. v0.4 shipped the legible-harness pipeline
(capture · decode · store · present). v0.5 turns it into a control
surface: a single route can swap models, fail over on quota, run a
text-only model on image-bearing requests, and serve `web_search`
locally — all without the agent noticing.

### Added

- **Per-route failover chains.** A route's target is now
  `{kind:'chain', members[]}`: an ordered list of models, each with
  optional `switchOn` rules (`error`, `budget {usdLimit, day|month}`,
  or new `tokens {tokenLimit, day|month}`). The last member is the
  unconditional fallback. The Routing card hosts the editor inline —
  the Strategies page is gone.
- **Token-quota switch rule.** Companion to the existing USD budget
  rule. `tokensInPeriod` sums `tokens_in + tokens_out` from the
  captured `actions` table.
- **Per-route capabilities** (`capabilities.vision`,
  `capabilities.web_search`). Vision companion routes image
  pre-describe to a designated model; web_search pins this route's
  searches to a specific Thomas tool-provider. Both surface in the
  Routing card under the chain editor.
- **Image pre-describe pass.** When a routed model can't see images
  and a vision companion is configured (or auto-pickable from the
  registry), Thomas calls the companion first to convert each image
  into a text description and forwards a text-only request.
  Cache-backed so multi-turn conversations re-describe an image only
  on its first appearance. Replaces the older tool-call vision-loop
  on routed paths.
- **`web_search` server-tool emulation** for routed models. Anthropic's
  `web_search_20250305` server tool only works on `api.anthropic.com`;
  when routed to a third party, Thomas rewrites the entry as a custom
  function tool, runs the executor loop locally (DuckDuckGo · Brave
  · Baidu), and feeds the results back to the model. Each search is
  captured as a `tool_call` action under the parent run so the
  dashboard surfaces the backend it served.
- **Claude `WebSearch` interception.** Same emulation loop now also
  picks up Claude Code / Claude Desktop's built-in `WebSearch`
  (PascalCase function tool), not just the `web_search_20250305`
  server tool — so pre-existing wires without `thomas-tools` MCP
  injection still benefit.
- **Baidu AI Search backend** with smart-search → plain web_search
  fallback. Tries `qianfan.baidubce.com/v2/ai_search/chat/completions`
  first (100 free/day) and falls back to `/v2/ai_search/web_search`
  (1500 free/month) on HTTP error or body-level `{code, message}`
  (Baidu's "quota exhausted" signal on a 200).
- **`thomas-tools` MCP** injected at wire time. Adds
  `mcp__thomas__web_search` and `mcp__thomas__web_fetch` so the agent
  can call Thomas-served search/fetch without needing the server-tool
  variant. Non-Anthropic upstreams strip Anthropic server tools by
  default; the MCP is the supported way to give them search anyway.
- **Tool-providers** registry and Control page. Per-backend secrets
  (DuckDuckGo · Brave · Baidu), cost-per-call, per-route pinning
  with a resolved-provider chip, and a "See · Tools" rollup showing
  the Thomas-executed share of activity.
- **Per-source-model routing** under wildcard (OAuth) routes. A
  `claude-code/*` chain can carry per-source-model overrides
  (`claude-code/claude-opus-4-7` pinned back to passthrough while the
  default routes everywhere else).
- **Claude Desktop wire** end-to-end. Detects, wires, and re-routes
  Claude Desktop alongside Claude Code / OpenClaw / Codex / Hermes.
- **Image cache** shared between the vision pre-describe and the
  legacy vision-loop so a multi-turn conversation doesn't describe
  the same image twice.
- **Translator hardening.** Parses Hermes/Qwen-style `<tool_calls>`
  XML and Claude `<invoke>/<parameter>` XML out of model text;
  threads `tool_choice` through IR for Anthropic↔OpenAI-chat;
  tolerant fallback for malformed or unterminated tool-call XML.

### Changed

- **Routing schema v2 → v3** (lossless auto-migration). The top-level
  `strategies` array is dropped; `{kind:'strategy', strategyId}`
  targets get inlined as chain members; `strategy.toolModels.vision`
  is lifted to `capabilities.vision` on the agent entry so
  failover-with-vision survives the migration.
- **Tool-providers: per-route is the only switch.** The global
  "active" provider concept is gone — every route either uses the
  agent's native search (default) or pins to a specific Thomas
  provider. Per-route pinning was always the recommended path; this
  removes the surprise of one route changing because the global
  active changed.
- **Run-detail UI** folds web_search tool executions into the Tools
  panel and surfaces the configured-target kind (`model` /
  `chain` / `passthrough`) alongside the upstream call rollup.
- **CLI** `route strategy` subcommands removed; `route set` gains
  `--chain` for inline failover authoring. Complex switch rules
  (budget / tokens) live in the dashboard.

### Fixed

- **Thinking blocks** are now preserved on the next turn of a
  web_search emulation loop when the upstream natively speaks
  `anthropic-messages` (e.g. DeepSeek's `/anthropic` endpoint). The
  raw `content[]` is echoed back verbatim instead of round-tripping
  through IR, which doesn't carry the opaque `signature` field —
  prevents `content[].thinking in the thinking mode must be passed
  back to the API` errors on multi-turn search.
- **Vision pre-describe + chain path** compose. A chain whose
  failover member is text-only (e.g. MiniMax-M2.7) no longer 400s
  on image-bearing requests; pre-describe runs once before the
  member loop and feeds the text-only `workingReq` to every member.
- **Web_search emulation cross-protocol.** The loop now reads
  assistant tool calls from IR instead of the upstream wire format,
  so it works regardless of whether the upstream returns Anthropic
  blocks or OpenAI `choices[].tool_calls`.
- **Streaming swap delegate.** When a streaming request would
  otherwise land in `runStreamingSwap` but needs the emulation loop
  (web_search) or pre-describe (vision), `runStreamingSwap`
  delegates to `runBuffered` instead of stripping the tool silently.

### Removed

- **Strategies page** (`/control/strategies`) and its CLI subcommands.
  Failover chains live on the Routing card now.
- **Global active tool-provider** setting. Replaced by per-route
  pinning.

### Privacy

No changes. v0.5 makes no new outbound calls beyond what `PRIVACY.md`
already documents for v0.4 (the daily plain GET to npm's public
registry for the update version check). The new backend calls (Baidu
Qianfan, DeepSeek `/anthropic`, etc.) are user-configured routes —
they go where the user told them to.

### Migration notes

- `~/.thomas/routing.json` migrates from v2 → v3 the first time the new
  daemon reads it. Any named strategies you authored get inlined as
  per-route chain members on the agents that referenced them. A
  `strategy.toolModels.vision` entry becomes
  `capabilities.vision = {via:'companion', modelId:…}` on the same
  agent. The original v2 file is preserved as
  `routing.json.v2-backup-<timestamp>` on first write.
- **Re-wire to pick up the new MCP tools.** If your existing
  `~/.claude/.claude.json` (Claude Code) or Claude Desktop config was
  wired before v0.5's `thomas-tools` MCP injection landed, run
  `thomas wire <agent>` again so `mcp__thomas__web_search` and
  `mcp__thomas__web_fetch` get added. The web_search emulation works
  without re-wiring too (intercepts Claude's `WebSearch` by name) but
  the MCP path is the supported one.

---

## [0.4.1] — 2026-04-18

Patch release on top of 0.4.0. Bug fixes around Codex OAuth refresh,
Anthropic SSE recovery, and the wire backup manifest.

## [0.4.0] — 2026-04-12

First public NPM release of `@openthomas/thomas` — the legible-harness
pipeline (capture · decode · store · present), MCP stdio wrap, React
dashboard, Risk taggers, and auto-wire for Claude Code · OpenClaw ·
Codex · Hermes · OpenCode.

[0.5.0]: https://github.com/openthomas-com/thomas/compare/v0.4.1...v0.5.0
[0.4.1]: https://github.com/openthomas-com/thomas/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/openthomas-com/thomas/releases/tag/v0.4.0
