feat(openclaw): assign glm-5.3-flash as primary conductor with prompt guardrail in adr 0002

This commit is contained in:
Moritz Graf
2026-09-14 08:12:54 +02:00
parent 4ae16b2640
commit 6bf3bb1348
2 changed files with 26 additions and 26 deletions
@@ -1,5 +1,5 @@
---
status: "proposed"
status: "accepted (trial: GLM-5.3-Flash)"
date: 2026-09-13
decision-makers: ["Moritz Graf", "Antigravity"]
consulted: []
@@ -65,17 +65,18 @@ How do we architect the full-spectrum model selection across **all modalities**
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Primary: │ │ Primary: │ │ Primary: │ │ Primary: │ │ STT: │
│ deepseek/ │ │ deepseek/ │ │ z-ai/ │ │ google/ │ │ openai/ │
│ deepseek-v4.1-fl│ │ deepseek-v4.1-fl│ │ glm-5.3-flash │ │ gemini-3.1- │ │ whisper-large- │
│ Primary (Trial):│ │ Primary (Trial):│ │ Primary: │ │ Primary: │ │ STT: │
│ z-ai/ │ │ z-ai/ │ │ z-ai/ │ │ google/ │ │ openai/ │
│ glm-5.3-flash │ │ glm-5.3-flash │ │ glm-5.3-flash │ │ gemini-3.1- │ │ whisper-large- │
│ │ │ │ │ │ │ flash-image │ │ v3-turbo │
│ Fallbacks: │ │ Fallbacks: │ │ Fallbacks: │ │ │ │
│ 1. glm-5.3-flash│ │ 1. glm-5.3-flash│ │ 1. deepseek- │ │ Fallbacks: │ │ TTS: │
│ 2. qwen3.8-flash│ │ 2. qwen3.8-flash│ │ v4.1-flash │ │ 1. gemini-3.1- │ │ google/ │
│ │ │ │ │ 2. qwen3.8-flash│ │ flash-preview│ │ gemini-3.1- │
│ Vision Fallback:│ │ │ │ │ │ 2. gemini-3-pro-│ │ flash-tts │
│ google/ │ │ │ │ │ │ image │ │ (FB: MiniMax 2.8│
│ gemini-3.1- │ │ │ │ │ │ │ │ Speech HD) │
│ 1. deepseek- │ │ 1. deepseek- │ │ 1. deepseek- │ │ Fallbacks: │ │ TTS: │
│ v4.1-flash │ │ v4.1-flash │ │ v4.1-flash │ │ 1. gemini-3.1- │ │ google/ │
│ 2. qwen3.8-flash│ │ 2. qwen3.8-flash│ │ 2. qwen3.8-flash│ │ flash-preview│ │ gemini-3.1- │
│ │ │ │ │ │ │ 2. gemini-3-pro-│ │ flash-tts │
│ Vision Fallback:│ │ │ │ │ │ image │ │ (FB: MiniMax 2.8│
│ google/ │ │ │ │ │ │ │ │ Speech HD) │
│ gemini-3.1- │ │ │ │ │ │ │ │ │
│ flash-image │ │ │ │ │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
```
@@ -85,23 +86,21 @@ How do we architect the full-spectrum model selection across **all modalities**
## Modality Specifications & Cost-Benefit Analysis
### 1. Interactive Conductor & Agentic Reasoning (Tier 1)
* **Primary**: `openrouter/deepseek/deepseek-v4.1-flash`
- **Pricing**: \$0.150 / 1M prompt (\$0.300 peak); \$0.600 / 1M completion. Under our nightly compaction regime (~15k tokens baseline), daily cost is only **~\$0.02–\$0.04 / day**.
- **Tool-Calling Reliability**: 100% native OpenAI JSON tool-calling compliance. Never leaks internal XML tokens into chat.
- **Latency**: Sub-3-second TTFT and fast streaming via DeepSeek's dedicated OpenRouter ASIC cluster, completely immune to the 20–77s prefill queuing observed with third-party GLM providers.
* **Primary (Active Trial)**: `openrouter/z-ai/glm-5.3-flash`
- **Pricing**: \$0.075 / 1M prompt tokens; \$0.300 / 1M completion tokens. This is 50–75% more cost-effective than DeepSeek V4.1-Flash and offers a 1.3M token context window. Under daytime context headroom (~25k–60k tokens), daily cost is only **~\$0.01–\$0.02 / day**.
- **Performance & Reasoning**: SOTA Chinese & English reasoning, competitive coding benchmarks, and native vision perception.
- **Forensic Diagnosis & Tool-Calling Protocol Fix**:
- *Incident*: On September 14, 2026, GLM-5.3-Flash emitted raw `<tool_call>supermarket__supermarket_search...</tool_call>` XML into Telegram instead of executing tools.
- *Root Cause Identified*: In Zhipu AI's pre-training tokenizer, function calls are emitted as special XML tokens. When models are queried through OpenRouter's OpenAI-compatible API, OpenRouter only intercepts and translates `<tool_call>` tokens into JSON if the tool `name` exists in the request's registered `tools: [...]` array. OpenClaw uses dynamic Tool Search (`tools.toolSearch.mode: "directory"`) where only 3 control tools (`tool_search`, `tool_describe`, `tool_call`) are registered in `tools`. When GLM received deferred schemas (e.g., `supermarket__supermarket_search`), its pre-training prior prompted it to call the tool directly. Because `supermarket__supermarket_search` was not in OpenRouter's `tools` array, OpenRouter passed the raw XML through as message text. Once that text entered the session history (events SEQ 297 & 306), GLM was in-context primed to repeat the XML pattern.
- *Remediation & Verification*: We introduced an explicit deferred tool execution protocol into `AGENTS.md` instructing the model that deferred tools must NEVER be called directly and MUST be routed via `tool_call({ id: 'tool_name', args: { ... } })`. Direct OpenRouter API probes confirmed that with this rule, GLM-5.3-Flash calls `tool_call` with 100% compliant JSON and zero XML leakage. Session events were sanitized.
* **Fallbacks**:
1. `openrouter/z-ai/glm-5.3-flash`: Fallback when DeepSeek is rate-limited or degraded.
1. `openrouter/deepseek/deepseek-v4.1-flash`: Rock-solid JSON tool-calling and sub-3s response times via dedicated OpenRouter ASIC cluster, available immediately if GLM experiences any upstream provider queuing or issues.
2. `openrouter/qwen/qwen3.8-flash`: Provider diversity.
> [!WARNING]
> **Production Defect in GLM-5.3-Flash (Tool Call XML Leakage)**:
> In live production testing on September 14, 2026, `z-ai/glm-5.3-flash` exhibited a critical tool-calling failure in OpenClaw's Tool Search architecture. When executing multi-turn tool dispatches (e.g. searching supermarkets, Geizhals, eBay, or live gold prices), GLM-5.3-Flash bypassed the `tool_call` wrapper and leaked its internal Chinese pre-training syntax (`<tool_call>name<arg_key>...</arg_key></tool_call>`) directly into the Telegram text stream. OpenClaw treated this as conversational text, dispatching raw XML to the user instead of executing the tools. DeepSeek V4.1-Flash strictly adheres to JSON tool calls and resolves this completely.
### 2. Autonomous Subagents (Tier 2)
* **Primary**: `openrouter/deepseek/deepseek-v4.1-flash`
- **Reliability & Execution**: Consistently compiles complex JSON payloads for external systems (e.g. Garmin Connect workouts, multi-source price aggregation) without XML leakage.
- **Execution**: Spawned via `sessions_spawn` with a 300-second timeout.
* **Fallback**: `openrouter/z-ai/glm-5.3-flash` for non-tool reasoning tasks.
* **Primary (Active Trial)**: `openrouter/z-ai/glm-5.3-flash`
- **Execution**: Spawned via `sessions_spawn` with a 300-second timeout. Inherits the `tool_call` protocol guardrails from `AGENTS.md`.
* **Fallback**: `openrouter/deepseek/deepseek-v4.1-flash` for high-concurrency tool execution fallback.
### 3. Background Daemon & Heartbeats (Tier 3)
* **Configuration**: `heartbeat.model: "openrouter/z-ai/glm-5.3-flash"`, `heartbeat.target: none`, `heartbeat.lightContext: true`.
@@ -158,9 +157,10 @@ To balance the user's desire to retain full conversation context across the enti
To align on remaining edge cases before final sign-off:
1. **Conductor Allocation Confirmed**:
- Following the tool-calling XML leakage diagnosed on September 14, `deepseek/deepseek-v4.1-flash` has been promoted to Primary Conductor for interactive chat and autonomous subagents. Its dedicated ASIC cluster provides instant tool execution and 2–4s response times at ~\$0.02–\$0.04/day.
- `z-ai/glm-5.3-flash` remains active for vision input and lightweight background heartbeats.
1. **Active Trial with GLM-5.3-Flash as Primary Conductor**:
- As requested, `z-ai/glm-5.3-flash` is now deployed as the Primary Conductor for interactive chat and autonomous subagents, equipped with the prompt guardrails against direct tool calls and XML leakage.
- `deepseek/deepseek-v4.1-flash` stands ready as the zero-latency primary fallback.
- We will observe real-world performance, tool adherence, and cost over the next several days.
2. **Thinking / Reasoning Mode on Telegram**:
- Currently, `thinking: medium` is enabled, emitting 100–300 reasoning tokens before generating conversational text.
- *Question*: Would you like to disable thinking mode (`thinking: none`) for standard Telegram chat turns (for near-instant replies) and keep reasoning active only for subagents?