Add dual-model agent chat#8
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
/api/capabilitiescontract backed by DS4 model metadata and an innocuous capability probe/api/agent/chatloop for Qwen3.6 and DeepSeek V4 Flashruntime_status,model_info, andweb_searchtoolsweb_searchbefore any network requestDSBOX_PORT, and reports an older non-JSON backend explicitlyfc1561f36080829ecc43695af29d82782a852e86Why
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 offpreference, 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_searchfrom the next tool schema, while the thread still contained a successful historicalweb_search. Qwen correctly reused that tool name, but DS4 rejected it as unknown and surfacedfinish_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.listenreportedEADDRINUSEthrough 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
mainat head9b9f5b034297b092c45e9c677829e2e7b8f05f5a. While that PR is under review, this DSBox branch usescodex/qwen-tool-dialect. After merge, switchQWEN35_RUNTIME_BRANCHback tomainand pin the actual SHA onmainthat contains the change; this may differ fromfc1561fafter a squash merge.Validation
verifychecks passing127.0.0.1:4242, withWeb onactive by default and no console warnings or errorscerca il pil della germania nel 2023: two completed DuckDuckGo tool calls followed by a final Italian answer, with no malformed-output failureweb_searchparsed successfully, emittedtool_permission_deniedwith notool_call.startedor network request, then completed the run cleanlyruntime_status, thenmodel_info, followed byrun.completedmake model-free-testds4_test --server