feat(local-models): apply OpenAI execution guidance to Qwen / DeepSeek / GLM families - #35087
feat(local-models): apply OpenAI execution guidance to Qwen / DeepSeek / GLM families#35087intelac wants to merge 1 commit into
Conversation
…k / GLM families PR NousResearch#27797 extended the tier-2 OPENAI_MODEL_EXECUTION_GUIDANCE block from {gpt, codex} to {grok} after observing Grok hits the same failure modes that this block addresses: claiming completion without tool calls, suggesting workarounds instead of using existing tools, replying with plans instead of executing. Local-model users running Qwen / DeepSeek / GLM via oMLX, LM Studio, or OpenRouter hit identical failure modes. These families are already in the tier-1 TOOL_USE_ENFORCEMENT_MODELS tuple but were excluded from the tier-2 gate, which remained a hard-coded substring check in agent/system_prompt.py. This change: 1. Promotes the substring match to OPENAI_EXECUTION_DISCIPLINE_MODELS tuple in agent/prompt_builder.py (mirrors the shape of TOOL_USE_ENFORCEMENT_MODELS). Adds qwen, deepseek, glm to the defaults alongside gpt / codex / grok. 2. Adds an `agent.execution_discipline` config knob with the same value semantics as `agent.tool_use_enforcement`: "auto" (default) — substring-match against the tuple above true / "true" / "always" / "yes" / "on" — always inject false / "false" / "never" / "no" / "off" — never inject [list] — custom substring list Plumbed in agent/agent_init.py alongside `_tool_use_enforcement`. 3. Refactors the tier-2 gate in agent/system_prompt.py from a hard- coded `if` into a config-driven block that mirrors the existing tier-1 logic. The escape hatch (list / true) lets users whose local model has been loaded under a renamed identifier opt in without having to fork. 4. Updates website/docs/user-guide/configuration.md with the new `agent.execution_discipline` key + corrects the `tool_use_enforcement` default list (was missing the glm / qwen / deepseek entries that have been in TOOL_USE_ENFORCEMENT_MODELS). The OPENAI_ prefix on the guidance constant is retained for backwards compat with imports/tests, following the precedent set in PR NousResearch#27797. Tests: 6 new tests in TestToolUseEnforcementConfig: - test_auto_injects_execution_guidance_for_qwen - test_auto_injects_execution_guidance_for_qwen_bare_local_name - test_auto_injects_execution_guidance_for_deepseek - test_auto_injects_execution_guidance_for_glm - test_execution_discipline_explicit_on_for_claude - test_execution_discipline_custom_list Full tests/run_agent/test_run_agent.py: 359/359 green. Full tests/run_agent/test_provider_parity.py: 89/89 green in isolation. Related: NousResearch#27797 (Grok extension precedent), NousResearch#29677 (Qwen/DeepSeek local models on llama.cpp — adjacent context on the local-model substring set).
|
When running Qwen 3.6 27B Q8 via llama.cpp, often times the model just starts running the same tool call over and over and over again. It gets stuck in these loops. Then sometimes I'll stop it and ask for a status report or something, and it will just ignore me and keep running the tool calls. Not sure why it's doing this, but do you think this PR fixes these problems as well? |
|
Good question! Sadly this PR probably won't help with that one. 😅 This PR is for the opposite problem — models that give up too early (say "done" without actually doing the work). What you're hitting is the model getting stuck repeating a tool call, which is a different beast. That loop is usually a model/inference thing, not a prompt thing. A few things that have helped me with Qwen on llama.cpp:
The "it ignores me when I ask for a status report" part is separate — that's about whether the harness interrupts a running turn, not the prompt. If you can reproduce it, opening a separate issue with your model + llama.cpp flags + context length would be the best way to get it looked at. Hope that helps! 🙂 |
|
Thanks for identifying a real tier mismatch. Current main still has Problems
Suggested changes
This is an automated hermes-sweeper review. |
Problem
PR #27797 extended the tier-2
OPENAI_MODEL_EXECUTION_GUIDANCEblock from{gpt, codex}to{grok}after observing Grok hits the same failure modes that this block addresses: claiming completion without tool calls, suggesting workarounds instead of using existing tools, replying with plans instead of executing.Local-model users running Qwen / DeepSeek / GLM via oMLX, LM Studio, or OpenRouter hit identical failure modes. These families are already in the tier-1
TOOL_USE_ENFORCEMENT_MODELStuple but were excluded from the tier-2 gate, which remained a hard-coded substring check inagent/system_prompt.py.Solution
Promote the substring match to
OPENAI_EXECUTION_DISCIPLINE_MODELStuple inagent/prompt_builder.py(mirrors the shape ofTOOL_USE_ENFORCEMENT_MODELS). Addsqwen,deepseek,glmto the defaults alongsidegpt/codex/grok.Add an
agent.execution_disciplineconfig knob with the same value semantics asagent.tool_use_enforcement:"auto"(default) — substring-match against the tuple abovetrue/"true"/"always"/"yes"/"on"— always injectfalse/"false"/"never"/"no"/"off"— never inject[list]— custom substring listPlumbed in
agent/agent_init.pyalongside_tool_use_enforcement.Refactor the tier-2 gate in
agent/system_prompt.pyfrom a hard-codedifinto a config-driven block that mirrors the existing tier-1 logic. The escape hatch (list /true) lets users whose local model has been loaded under a renamed identifier opt in without having to fork.Update
website/docs/user-guide/configuration.mdwith the newagent.execution_disciplinekey + correct thetool_use_enforcementdefault list (was missing theglm/qwen/deepseekentries that have been inTOOL_USE_ENFORCEMENT_MODELS).The
OPENAI_prefix on the guidance constant is retained for backwards compat with imports/tests, following the precedent set in #27797.Files changed
agent/prompt_builder.pyOPENAI_EXECUTION_DISCIPLINE_MODELStupleagent/agent_init.py_execution_disciplineplumbingagent/system_prompt.pytests/run_agent/test_run_agent.pywebsite/docs/user-guide/configuration.md+196 / -10, no API changes, no breaking behavior for existing users.
Tests
6 new tests in
TestToolUseEnforcementConfig:test_auto_injects_execution_guidance_for_qwentest_auto_injects_execution_guidance_for_qwen_bare_local_nametest_auto_injects_execution_guidance_for_deepseektest_auto_injects_execution_guidance_for_glmtest_execution_discipline_explicit_on_for_claudetest_execution_discipline_custom_listFull
tests/run_agent/test_run_agent.py: 359/359 green.Full
tests/run_agent/test_provider_parity.py: 89/89 green in isolation.How to test
Related