Skip to content

fix(coding-agent): request low reasoning for session title generation - #1266

Open
ImStillBlue wants to merge 2 commits into
code-yeongyu:mainfrom
ImStillBlue:fix/session-title-reasoning-mandatory
Open

fix(coding-agent): request low reasoning for session title generation#1266
ImStillBlue wants to merge 2 commits into
code-yeongyu:mainfrom
ImStillBlue:fix/session-title-reasoning-mandatory

Conversation

@ImStillBlue

@ImStillBlue ImStillBlue commented Sep 2, 2026

Copy link
Copy Markdown

Summary

The background session-title request left reasoning unset in buildTitleOptions(). For reasoning-capable models, pi-ai's OpenAI-completions layer then fills the gap with the provider's "disabled" mapping — on OpenRouter-format models that is reasoning: { effort: "none" }. Endpoints that mandate reasoning (observed with Z.ai GLM 5.x models, e.g. z-ai/glm-5.3-flash) reject that with:

Runtime error (session_title_generation): Reasoning is mandatory for this endpoint and cannot be disabled. (HTTP 400)

Regular agent turns are unaffected because they always carry the session's thinking level — only the background title call (and therefore every fresh session on such a model) failed. The same behavior is publicly documented against OpenRouter in openclaw#24851.

What changed

  • packages/coding-agent/src/core/session-title-generator.tsbuildTitleOptions() now sends reasoning: "low" explicitly, and raises maxTokens from 64 to 1024 so low-effort reasoning tokens don't consume the budget needed for the <title> output on token-based providers.
  • packages/coding-agent/test/session-title-generator.test.ts — deterministic regression test asserting the title request carries reasoning: "low" and maxTokens: 1024 via a fake streamFn (no network, no tokens).
  • packages/coding-agent/src/core/changes.md — fork-ledger entry per the changes.md contract.

Non-reasoning models are unaffected: pi-ai clamps the level per model and the OpenRouter reasoning branch only fires for model.reasoning === true.

Validation

  • bunx vitest run test/session-title-generator.test.ts — 12/12 pass (including the new regression test).
  • Root bun run check — pass (Biome, pinned-deps, ts-imports, shrinkwrap, install-lock, claude-sdk-platform-lock, tsc --noEmit, browser-smoke).
  • Manually verified against a local install of omo 5.0.0-0.beta.31 / senpi 2026.8.31: patching buildTitleOptions the same way eliminated the recurring session_title_generation 400 on OpenRouter z-ai/glm-5.3-flash sessions.

Residual risk

  • Titles on reasoning-capable models now include a small amount of reasoning output, marginally increasing cost per one-shot title call (bounded by maxTokens: 1024). An alternative would be retrying with a low effort only when the endpoint rejects disabled reasoning, but the simple explicit level avoids a second round trip for a known-broken class of endpoints.

Summary by cubic

Fixes session title generation on reasoning-mandatory endpoints by retrying once with low reasoning when the provider rejects the default reasoning-free title request, so new sessions on models like Z.ai GLM 5.x no longer fail with a 400 error.

  • Default title requests stay reasoning-free with maxTokens: 64, so healthy endpoints pay no reasoning cost.
  • Only a "Reasoning is mandatory" 400 triggers the retry with reasoning: "low" and maxTokens: 1024, leaving room for the <title> output once reasoning tokens count against the budget.
  • Adds regression tests covering the default path, the fallback retry, and non-matching errors (no retry).

Written for commit 94960ba. Summary will update on new commits.

Review in cubic

Unset reasoning on the background title request made token-based
providers fall back to their disabled mapping (reasoning:
{ effort: "none" } on OpenRouter-format models). Reasoning-mandatory
endpoints such as Z.ai GLM 5.x reject that with HTTP 400 'Reasoning is
mandatory for this endpoint and cannot be disabled.', surfacing as a
repeated session_title_generation runtime error in every session on
those models. Ask for low reasoning explicitly and raise maxTokens so
reasoning tokens leave room for the <title> output.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/coding-agent/src/core/session-title-generator.ts Outdated
…ry errors

Review follow-up: forcing reasoning: "low" on every title call taxes all
reasoning-capable models on a cosmetic background call, and some catalogs
map low to full effort (DeepSeek low -> "high" in openai-completions.ts).
Keep the default request reasoning-free and instead retry once with low
reasoning + maxTokens 1024 only when the provider answers with the
reasoning-mandatory 400. Healthy endpoints keep the zero-reasoning path.
@ImStillBlue

Copy link
Copy Markdown
Author

Valid review — pushed 94960ba addressing it.

Confirmed both claims: DEEPSEEK_THINKING_LEVEL_MAP / OPENROUTER_DEEPSEEK_THINKING_LEVEL_MAP map low: "high", and the unconditional reasoning: "low" enabled thinking on every title call across all reasoning-capable providers (Anthropic included, which previously had thinking disabled for titles).

Redesign per your suggestion: the default title request stays reasoning-free with maxTokens: 64; generateSessionTitle() now retries once with reasoning: "low" + maxTokens: 1024 only when the provider error matches "Reasoning is mandatory". Healthy endpoints keep the zero-reasoning path; broken endpoints pay one extra round trip (bounded by the same narrow retry policy). Added three tests: default attempt carries no reasoning, the reasoning-mandatory 400 triggers the fallback with low/1024, and other provider errors do not.

Validation: vitest run test/session-title-generator.test.ts 14/14, root bun run check pass.

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