DSH Dynamic Tool Updates: DeepSeek Adapter & Recovery

Author
DeepSeekAgent.io Editorial Team
Published
Updated

Installing, upgrading, or removing a plugin changes the tools available to an active DeepSeek Harness Session. DSH needs to tell the model which tools appeared and which disappeared. If a provider route cannot represent that mid-conversation update correctly, an ordinary plugin operation can turn into a persistent HTTP 400.

A community report from October 21, 2026 traces this path on v0.2.1-rc.2: Agent Loop persisted tool additions and removals as a developer/message; the DeepSeek Adapter then serialized its tool-addition or tool-removal blocks into the request. When the upstream endpoint rejected that structure, the record remained in Session history, so retry, restart, and even /compact could project it again.

This differs from REQUEST_EXTENSION. That failure occurs before an HTTP request, often because plugin inventory or a manifest cannot be resolved. A dynamic-tool failure reaches the provider, but the route rejects the projected message structure.

Why DSH records tool changes

At the beginning of an Agent round, the system prompt and tool definitions establish a baseline. If a plugin registers new tools while the Session remains open, silently replacing the full list on the next request gives the model no explicit transition from “unavailable” to “available.” A dynamic-tool protocol records the delta:

previous tool set
  → plugin install, update, or removal
  → calculate additions and removals
  → append developer/message
  → adapter projects provider request

This is useful in long Sessions. The model can retain prior context while understanding registry changes, and stable prompt prefixes can improve KV Cache reuse. It works only when the Adapter and provider agree on the same mid-conversation update protocol.

Where the failure occurs

In the community reproduction, Agent Loop compares the baseline names with the current tool set and stores tool-addition and tool-removal content when it detects a difference. The DeepSeek Adapter projects those blocks into the message list and adds a related beta header when tool changes are present.

The captured request resembles:

{
  "role": "system",
  "content": [
    {
      "type": "tool_addition",
      "tool": { "type": "tool_reference", "name": "ops_bash" }
    }
  ]
}

The provider error points to the tool_addition location. The plugin tool itself did not fail during execution; the route rejected how its availability change was represented.

There are at least three capability gates in this design:

  1. whether Agent Loop should create a dynamic-tool record for the prepared call;
  2. whether the Adapter supports addition, removal, or both;
  3. whether the selected provider route accepts that message structure and header.

If advertised capability and endpoint behavior diverge, the Session can persist a record that later requests cannot project successfully.

Why restart or model switching may not help

A tool change is stored in Session V4 history rather than only in process memory. DSH projects it again after restart. A model switch may still use the same Adapter, or projection may retain the developer record for the next route, so changing the selected model does not necessarily remove the incompatible block.

An independent reproduction also reports that /compact can fail. Compaction must first construct a model request containing prior history, so it encounters the same record. The visible sequence becomes:

  • the Session works before a plugin update;
  • the first message after the update returns 400;
  • every later send returns the same error;
  • a new Session may work because it starts from the current tool baseline and has no mid-session delta to replay.

The last observation is a strong diagnostic signal, not proof by itself. Preserve the complete provider error and request ID to exclude credentials, credit, and ordinary context overflow.

Operations most likely to trigger it

  • installing a tool-providing plugin while a Session is open;
  • upgrading a plugin that adds, renames, or deletes tools;
  • disabling a plugin or switching Profile, removing many tools together;
  • hot reloading a plugin whose registered set differs from the header baseline;
  • resuming an older Session after current tool names have changed.

Merely opening the plugin market is not the trigger. The relevant event is a live Session observing a registry change and persisting the delta.

Identify this specific 400

SymptomMore likely layer
REQUEST_EXTENSION, no provider request IDLocal pre-request extension
Error identifies tool_addition or tool_removalDynamic-tool projection
Only the original Session fails after an updatePersistent tool-change record
New and old Sessions return 401, 402, or 429Credential, balance, or rate limit
context_length_exceededContext window or compaction
New Session works; old Session still fails after restartUnreplayable structure in old history

Do not delete the whole Profile just because the failure followed a plugin update. REQUEST_EXTENSION, plugin-runtime crashes, tool-protocol incompatibility, and provider authentication need different repairs.

A safer recovery sequence

1. Freeze the state

Stop automatic continuation and avoid more plugin changes. Record DSH version, plugin and version, Profile, model route, full HTTP status, and provider request ID.

2. Run a minimal new-Session check

Keep the current plugin set, create a new Session, send a short message with no tool call, and then invoke one read-only tool:

  • if it works, the provider and current baseline are probably valid; focus on the old Session history;
  • if it also fails, inspect registration, Adapter routing, and global configuration before migrating context.

3. Export task state

While the old Session remains readable, copy its confirmed findings, outstanding work, changed files, and completed side effects. If it cannot make another model call, use DSH export or read-only transcript access.

4. Resume from a reviewed summary

Start a new Session with a concise summary of the goal, completed work, remaining tasks, important paths, test status, and external actions that must not be repeated. Perform read-only verification before continuing.

5. Preserve the original data

Direct editing of compressed Session logs should not be routine recovery. The follow-up report found that even a readable rewritten log could disappear from the UI when Projection Cache state no longer matched its previous bytes. Keep the original as an audit record.

Preventing recurrence

  1. Do not update plugins during critical long-running tasks. Change the tool set after completion or a documented checkpoint.
  2. Test upgrades in an isolated Session. Verify registration, a read-only call, and the intended model route before using the plugin in production work.
  3. Capture a before/after tool inventory. Pay attention when one update renames or changes dozens of tools.
  4. Keep an external task checkpoint. Recovery should not depend entirely on one Session artifact.
  5. Pin DSH and plugin versions for reproducible work. Avoid floating upgrades inside a live run.

At the implementation layer, DSH can gate dynamic-tool persistence on prepared-call capability. Unsupported routes can resend the full tool list or omit the delta. If a provider rejects one of these messages, later projection should be able to ignore the record instead of permanently blocking the Session.

The KV Cache tradeoff

Dynamic tools also avoid rewriting a full tool schema on every turn, preserving a stable prompt prefix and improving cache reuse. Compatibility still takes priority:

  • routes that support mid-conversation updates can send deltas and retain a stable prefix;
  • unsupported routes should fall back to a full tool list or a fresh Session baseline;
  • an Adapter cannot assume that every gateway behind the same model ID implements the same beta protocol.

Record the complete route, not only the model ID. deepseek-flash through an account Adapter, an Anthropic-compatible endpoint, or a third-party gateway may accept different request structures.

Related reading

References