Skip to content

Add dual-model agent chat#8

Merged
andreaborio merged 5 commits into
mainfrom
codex/dual-model-agent
Jul 16, 2026
Merged

Add dual-model agent chat#8
andreaborio merged 5 commits into
mainfrom
codex/dual-model-agent

Conversation

@andreaborio

@andreaborio andreaborio commented Jul 15, 2026

Copy link
Copy Markdown
Owner

What changed

  • adds a real /api/capabilities contract backed by DS4 model metadata and an innocuous capability probe
  • adds a model-neutral /api/agent/chat loop for Qwen3.6 and DeepSeek V4 Flash
  • exposes bounded read-only runtime_status, model_info, and web_search tools
  • makes Web available by default in Agent mode, with a visible persistent opt-out instead of a per-message authorization step
  • keeps historical tool schemas parseable when a permission is later disabled, while the executor still blocks web_search before any network request
  • streams canonical run, reasoning, text, tool lifecycle, usage, completion, and error events
  • persists tool activity in chat, preserves parallel tool history and reasoning continuity, supports cancel/reload, drops failed turns before retry, and falls back to standard chat when capability is not verified
  • adds fan-out, concurrency, byte, timeout, step, history, and network-permission guardrails
  • fails fast on an occupied DSBox control port, makes the Vite proxy honor DSBOX_PORT, and reports an older non-JSON backend explicitly
  • updates Qwen runtime and agent UI to match the real OpenAI Chat Completions tool support; OpenCode and Pi are available, while Codex and Claude remain disabled for their unsupported wire protocols
  • documents the competitor map, architecture, compatibility matrix, and P0-P5 roadmap
  • pins the integration branch to DS4 commit fc1561f36080829ecc43695af29d82782a852e86

Why

DSBox needs a state-of-the-art local chat that can run one safe agent loop across its two primary model families without leaking Qwen or DeepSeek protocol details into the UI. Web search should work from normal Agent chat without asking the user to re-enable the same capability for every message, while retaining a durable opt-out.

Impact

Users get visible tool execution, parallel read-only calls, reliable follow-ups, automatic Web availability in Agent mode, a persistent Web off preference, and safe standard-chat fallback. If Web is disabled after an earlier search, historical calls remain parseable but execution is denied before the network. Startup no longer claims success while an older DSBox process owns the control port, and Qwen capability copy now matches the runtime instead of describing it as tool-free.

Root cause

The previous chat path treated all output as text and inferred model behavior outside a formal capability contract. It had no canonical tool lifecycle, execution policy, persistent tool history, or cross-model adapter boundary.

The Web regression came from coupling parseability to the current request permission: the one-shot UI reset removed web_search from the next tool schema, while the thread still contained a successful historical web_search. Qwen correctly reused that tool name, but DS4 rejected it as unknown and surfaced finish_reason: error. DSBox now separates schema continuity from execution authorization and removes incomplete failed turns from retry history.

During live recovery, Express 5 also exposed a separate startup issue: app.listen reported EADDRINUSE through its callback, but DSBox ignored the error and could keep metrics alive while the browser continued talking to an older backend.

Dependency

Draft DS4 PR andreaborio/ds4#2 provides the Qwen native tool dialect. Its branch now includes current main at head 9b9f5b034297b092c45e9c677829e2e7b8f05f5a. While that PR is under review, this DSBox branch uses codex/qwen-tool-dialect. After merge, switch QWEN35_RUNTIME_BRANCH back to main and pin the actual SHA on main that contains the change; this may differ from fc1561f after a squash merge.

Validation

  • 199 DSBox tests across 21 files
  • client and server TypeScript typecheck
  • production Vite build
  • both GitHub verify checks passing
  • live browser QA on 127.0.0.1:4242, with Web on active by default and no console warnings or errors
  • exact live Qwen retry of cerca il pil della germania nel 2023: two completed DuckDuckGo tool calls followed by a final Italian answer, with no malformed-output failure
  • live Qwen opt-out regression: a historical web_search parsed successfully, emitted tool_permission_denied with no tool_call.started or network request, then completed the run cleanly
  • live Qwen agent run executing runtime_status, then model_info, followed by run.completed
  • DS4 make model-free-test
  • DS4 ASan + UBSan ds4_test --server
  • post-merge-base real Qwen resident tool call, tool-result continuation with cached prefix, and structured streaming
  • prior real DeepSeek V4 Flash tool round-trip regression smoke

@andreaborio andreaborio merged commit e42fcde into main Jul 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant