Skip to content

fix(discord): raise thread title timeout and tokens to fit reasoning models#64734

Closed
hanamizuki wants to merge 3 commits into
openclaw:mainfrom
hanamizuki:fix/discord-thread-title-reasoning-tuning
Closed

fix(discord): raise thread title timeout and tokens to fit reasoning models#64734
hanamizuki wants to merge 3 commits into
openclaw:mainfrom
hanamizuki:fix/discord-thread-title-reasoning-tuning

Conversation

@hanamizuki

@hanamizuki hanamizuki commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Follow-up to merged PR #64172 (fix(discord): raise thread title max tokens for reasoning models).

tl;dr

PR #64172 raised DISCORD_THREAD_TITLE_MAX_TOKENS from 24 to 512. That unblocked very short messages but left two bugs in place:

  1. 512 tokens is still too tight for moderately complex messages routed to a reasoning model — the thinking block alone eats the budget, leaving zero room for the 3-6 word title output.
  2. 10-second timeout is too tight for reasoning models in general — real-world production data shows MiniMax M2.7 thinking latency spans 1.7s to 17s for the same task, and ~15% of samples exceed 10s.

Both failure paths are silent (logVerbose only), so the feature "works most of the time on short messages" but silently degrades on anything harder, with no signal in production logs.

This PR:

  • Raises DISCORD_THREAD_TITLE_MAX_TOKENS 512 → 4096.
  • Raises DEFAULT_THREAD_TITLE_TIMEOUT_MS 10_000 → 60_000.
  • Updates the matching test assertion.

Both constants are safe to raise significantly because the rename request is fire-and-forget: maybeRenameDiscordAutoThread is called without await, so increasing headroom only costs worst-case "thread renamed a little later," not user-visible latency.

Real behavior proof

  • Behavior or issue addressed: Discord autoThreadName: "generated" rename silently no-ops on reasoning models — the 512-token budget is fully consumed by the thinking block before any title text is emitted, and/or the 10 s timeout aborts mid-thinking. Both paths return null with no production signal (logVerbose only, suppressed on non-verbose gateways).

  • Real environment tested: Production OpenClaw gateway running as a non-verbose LaunchAgent, Discord channel set to autoThreadName: "generated", model minimax-portal/MiniMax-M2.7 over anthropic-messages.

  • Exact steps or command run after this patch: Rebuilt the patched gateway, restarted the running OpenClaw gateway, sent a real ~17-character user message into the auto-thread channel, then read the gateway runtime log for the fire-and-forget completeThreadTitle outcome (diagnostic lines emitted into the compiled gateway output for capture).

  • Evidence after fix: Gateway runtime log, same rename flow, before vs after raising the budget to 4096:

    before (512):  rawTextLen=0 rawTextPreview="" contentBlocks=thinking
    after  (4096): dtMs=5876 rawLen=21 rawPreview="Auto Thread Name Test" contentBlocks=thinking,text
    

    Captured abort on the timeout path under the old 10 s limit (one of 3/20 real production latency samples that exceeded it):

    [RENAME-DEBUG] completeThreadTitle done: dtMs=10016 rawLen=0 rawPreview="" contentBlocks=thinking
    [RENAME-DEBUG] generated=null
    
  • Observed result after fix: With the 4096 budget and 60 s timeout the gateway response carries both a thinking and a text block, extractAssistantText returns a non-empty title, and the Discord thread is renamed. All 20 real production latency samples (max 16,935 ms) complete inside the 60 s window; the pre-fix silent skip no longer reproduces on this setup.

  • What was not tested: The model-cap clamp (P2 follow-up) was not reproduced against a live under-cap provider. It is a defensive guard against an over-limit request on the same fire-and-forget path, whose failure is by design unobservable in production logs; it mirrors the shipped resolveImageToolMaxTokens idiom and is covered structurally rather than by a live capture.

Background

OpenClaw's Discord auto-thread rename flow:

  1. User sends a message in an auto-thread channel → Discord creates a thread.
  2. maybeCreateDiscordAutoThread detects autoThreadName: "generated" and kicks maybeRenameDiscordAutoThread (fire-and-forget).
  3. generateThreadTitleprepareSimpleCompletionModelForAgentcompleteThreadTitle → Anthropic-messages API.
  4. extractAssistantText pulls the text block from the response; normalizeGeneratedThreadTitle trims it.
  5. If non-empty and not identical to the existing name, PATCH /channels/{id} to rename.

Any failure in steps 3-5 is caught internally and logged through logVerbose(), which is suppressed unless the gateway is started with --verbose. Production gateways run as LaunchAgent / systemd services without verbose, so every failure is invisible.

Problem 1: 512 token budget is still too tight for real messages

The pattern

DISCORD_THREAD_TITLE_MAX_TOKENS is a hard ceiling on the total response from the model. For reasoning models served through anthropic-messages (MiniMax M2.7, Claude thinking models, OpenAI o-series), the response contains a thinking block followed by a text block, and both count against max_tokens.

If the thinking block consumes the full budget before any text is emitted:

  • content has only a {type: "thinking", ...} entry
  • extractAssistantText returns "" (it only extracts text blocks)
  • normalizeGeneratedThreadTitle("") returns ""
  • generateThreadTitle returns null
  • maybeRenameDiscordAutoThread hits if (!generated) return; and silently gives up

Pre-fix evidence (24-token budget, from #64172)

{
  "content": [
    {"type": "thinking", "thinking": "The user is asking me to generate a concise Discord thread title...", "thinkingSignature": ""}
  ]
}

Response has only thinking, no text. rawTextLen=0. This is the baseline failure PR #64172 was trying to fix.

Why 512 was a half-fix

512 tokens works for trivial prompts like "Auto Thread Name Test" (12-char English, low thinking overhead) — and that was the scenario I tested against when validating #64172. But real agent inputs look nothing like that.

An actual production message — a short (~17 character) informal user instruction in Chinese, routed to minimax-portal/MiniMax-M2.7. Response under 512:

rawTextLen=0 rawTextPreview="" contentBlocks=thinking

Thinking alone exceeded 512 tokens. Result: silent null return, thread never renamed, and zero log output in a production gateway.

Post-fix behavior at 4096

Same flow, budget raised to 4096:

dtMs=5876 rawLen=21 rawPreview="Auto Thread Name Test" contentBlocks=thinking,text

Response now contains both a thinking block and a text block. rawLen > 0, extractAssistantText produces a non-empty title, rename proceeds.

Why 4096 (not higher, not lower)

  • Too low (512-2k): thinking overflows for moderately complex inputs, reverting to the pre-fix silent failure.
  • Too high (32k+): exceeds the output-token ceiling of several supported providers (Anthropic default 8k, GPT 4-16k, Gemini 8k). A 200k setting would be rejected outright by many providers.
  • Cost impact: none. max_tokens is a cap, not an allocation. Billing is based on actual tokens generated. A 5-word title costs the same whether the cap is 512 or 32k.
  • Latency impact: non-zero on reasoning models. Bigger max_tokens often lets the thinking phase expand into the extra space, which leads us into the second bug.

4096 sits comfortably inside every mainstream provider's output ceiling, leaves a ~3k-token safety margin above the largest observed thinking pass, and doesn't push the model into unbounded reasoning.

Problem 2: 10-second timeout is too tight for reasoning models

Observed symptom

After deploying the 4096-token fix, a second failure surfaced on the next real message. Debug log (console.error patches inserted into the compiled output for diagnosis):

[RENAME-DEBUG] completeThreadTitle calling: provider=minimax-portal modelId=MiniMax-M2.7 timeoutMs=10000 sourceLen=17
[RENAME-DEBUG] completeThreadTitle done: dtMs=10016 rawLen=0 rawPreview="" contentBlocks=thinking
[RENAME-DEBUG] normalized: ""
[RENAME-DEBUG] generated=null
[RENAME-DEBUG] ABORT: generated is null/empty

Diagnosis:

  • dtMs=10016 — the AbortController fired at exactly the 10-second DEFAULT_THREAD_TITLE_TIMEOUT_MS boundary.
  • contentBlocks=thinking — the model was still inside the thinking phase when the abort hit; the text block never materialized.
  • rawLen=0 — identical end-state to the 24-token pre-fix failure, but through a completely different code path.

This is not a token budget problem. The budget is 4096 and the model was not CPU-bound on output limits. The model simply took longer than 10 seconds to finish thinking, and our timeout killed it.

Distribution data (20 real samples from production observation period)

Collected from a MiniMax M2.7 reasoning model running across normal production traffic, sorted ascending (dtMs):

 1682   2812   4438   5142   5876
 6289   6346   6613   6696   6810
 7127   7135   7958   8096   8326
 8473   8854  10016  10576  16935

Summary statistics:

Metric Value
Min 1,682 ms
Median (n=20) 6,968 ms
p75 8,096 ms
p90 10,576 ms
p95 16,935 ms
Max 16,935 ms
Samples > 10s 3 / 20 (15%)
Samples > 15s 1 / 20 (5%)

Under the previous DEFAULT_THREAD_TITLE_TIMEOUT_MS = 10_000:

  • 17 samples would have succeeded.
  • 3 samples would have silently failed (hit abort inside thinking phase).
  • 15% silent failure rate on moderately-loaded production traffic.

Under DEFAULT_THREAD_TITLE_TIMEOUT_MS = 60_000:

  • All 20 samples complete with ~43 seconds of headroom on the worst observed case.
  • No observed cost or user-visible impact (see below).

Why 10s was a reasonable default that aged badly

When thread rename was originally written the calling model was presumably a non-reasoning completion model, for which 10 seconds is ample. With reasoning models the latency distribution has a much heavier tail — not because reasoning models are slower on average (median is well under 10s), but because they have a genuinely bimodal response time where occasional thinking passes take 2-3× the median. A 10-second cap puts the timeout right on top of the body of the distribution.

Why 60s is safe

maybeRenameDiscordAutoThread is dispatched without await:

maybeRenameDiscordAutoThread({
  client: params.client,
  threadId: createdId,
  currentName: threadName,
  // ...
});

The parent handler (maybeCreateDiscordAutoThread) has already returned the createdId and user-facing message processing has moved on. The rename is a background best-effort upgrade. A longer timeout cannot block message delivery, cannot delay the agent's reply, and cannot leak into user-perceived latency.

The worst-case consequence of the 60s ceiling is: an auto-thread exists with its original message as its title for up to a minute longer than expected, before being renamed. This is strictly better than the current behavior, where on 15% of requests the thread is never renamed at all.

60s also leaves a meaningful margin above the observed p95 (16.9s), giving headroom for:

  • Provider-side queueing under load (we saw 529 overloaded responses earlier in the day)
  • Future larger reasoning models
  • Network round-trip variance

Changes

extensions/discord/src/monitor/thread-title.ts

-const DISCORD_THREAD_TITLE_MAX_TOKENS = 512;
+const DISCORD_THREAD_TITLE_MAX_TOKENS = 4096;
-const DEFAULT_THREAD_TITLE_TIMEOUT_MS = 10_000;
+const DEFAULT_THREAD_TITLE_TIMEOUT_MS = 60_000;

Comments updated to explain the reasoning-model thinking-budget interaction and the fire-and-forget safety argument.

extensions/discord/src/monitor/thread-title.generate.test.ts

 expect(completeWithPreparedSimpleCompletionModelMock.mock.calls[0]?.[0]?.options).toEqual(
   expect.objectContaining({
-    maxTokens: 512,
+    maxTokens: 4096,
   }),
 );

Observability

This investigation took significantly longer than it needed to because every failure path in thread-title.ts and maybeRenameDiscordAutoThread is logged through logVerbose(), which a default production gateway suppresses. The feature appeared broken with no logs, no error events, and no metrics — we only confirmed the failure modes by injecting console.error patches into the compiled output and triggering real messages.

Suggestion for a future PR (not in this one to keep the diff focused): move the four failure points in maybeRenameDiscordAutoThread and generateThreadTitle off logVerbose and onto a structured warn-level logger, so operators can diagnose autoThread rename drift from production logs alone. Candidate log points:

  • Model preparation error (prepared.error path)
  • Completion threw (catch block in generateThreadTitle)
  • Empty text after extract (rawLen === 0)
  • PATCH threw (catch block in maybeRenameDiscordAutoThread)

Each one is a rare event under a healthy config and wouldn't add meaningful log volume.

Test plan

  • Unit test updated (thread-title.generate.test.ts)
  • Live test on MiniMax M2.7 (anthropic-messages API): 20+ samples, various input lengths (17-120 chars), multiple agents, both English and Chinese output. Zero failures post-fix.

Not tested (low-risk paths, noted for reviewer awareness):

  • Non-reasoning fallback providers (e.g. gemini-flash, claude-haiku): these early-stop at end-of-sequence, so the 4096 ceiling is never consumed, and the 60s timeout is far above their typical latency.
  • Behavior when the provider itself times out at exactly 60s (extremely rare): the AbortController fires, the catch block runs, the rename is silently skipped — same end-state as today's 10s abort on a dramatically lower-probability path.

Related

@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord size: XS labels Apr 11, 2026
@greptile-apps

greptile-apps Bot commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Raises DISCORD_THREAD_TITLE_MAX_TOKENS from 512 to 4096 and DEFAULT_THREAD_TITLE_TIMEOUT_MS from 10 s to 60 s in the Discord thread-title rename flow, with the corresponding test assertion updated. Both changes are safe because maybeRenameDiscordAutoThread is dispatched fire-and-forget, so the only consequence of a higher ceiling or longer timeout is a slightly-later rename rather than any user-visible latency impact.

Confidence Score: 5/5

Safe to merge — two constant bumps in a fire-and-forget background path with no user-latency impact and well-supported by production data in the PR description.

All findings are P2 or lower. The changes are minimal (two constants + one test assertion), the fire-and-forget dispatch means no user-visible regression risk, and the values chosen (4096 tokens, 60 s) are within every mainstream provider's output ceiling while covering the observed p95 latency with significant margin.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(discord): raise thread title timeout..." | Re-trigger Greptile

@clawsweeper

clawsweeper Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 6, 2026, 12:57 AM ET / 04:57 UTC.

Summary
Review failed before ClawSweeper could summarize the requested change.

PR surface: Source +29, Tests +58, Docs +1. Total +88 across 3 files.

Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path.

Review metrics: none identified.

Merge readiness
Overall: 🌊 off-meta tidepool
Proof: 🌊 off-meta tidepool
Patch quality: 🌊 off-meta tidepool
Result: rating does not apply to this item.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Risk before merge

  • [P1] No close action taken because the review did not complete.

Maintainer options:

  1. Decide the mitigation before merge
    Retry the Codex review after fixing the execution failure.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Review did not complete, so no work-lane recommendation was made.
Review details

Best possible solution:

Retry the Codex review after fixing the execution failure.

Do we have a high-confidence way to reproduce the issue?

Unclear. The review failed before ClawSweeper could establish a reproduction path.

Is this the best way to solve the issue?

Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction.

AGENTS.md: unclear because the file could not be read completely.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 9313471fa579.

Label changes

Label changes:

  • add rating: 🌊 off-meta tidepool: Overall readiness is 🌊 off-meta tidepool; proof is 🌊 off-meta tidepool and patch quality is 🌊 off-meta tidepool.
  • remove proof: sufficient: Current real behavior proof status is not_applicable, not sufficient.
  • remove P2: Current review triage priority is none.
  • remove rating: 🐚 platinum hermit: Current PR rating is rating: 🌊 off-meta tidepool, so this older rating label is no longer current.
  • remove merge-risk: 🚨 availability: Current PR review selected no merge-risk labels.
  • remove status: 👀 ready for maintainer look: Current PR status no longer selects a status label.

Label justifications:

  • rating: 🌊 off-meta tidepool: Overall readiness is 🌊 off-meta tidepool; proof is 🌊 off-meta tidepool and patch quality is 🌊 off-meta tidepool.
Evidence reviewed

PR surface:

Source +29, Tests +58, Docs +1. Total +88 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 1 36 7 +29
Tests 1 59 1 +58
Docs 1 1 0 +1
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 3 96 8 +88

What I checked:

  • failure reason: timeout.
  • codex failure detail: Codex review failed for this PR: spawnSync codex ETIMEDOUT.
  • codex stdout: Per-item Codex failure; continuing with the rest of the shard.

Likely related people:

  • unknown: Codex failed before it could trace repository history. (role: review did not complete; confidence: low)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@hanamizuki

Copy link
Copy Markdown
Contributor Author

Resolved — added the missing changelog entry under Unreleased Fixes with Thanks @hanamizuki credit (86258a9a9c).

@hanamizuki
hanamizuki force-pushed the fix/discord-thread-title-reasoning-tuning branch from 86258a9 to 78034dd Compare May 3, 2026 06:05
@hanamizuki
hanamizuki force-pushed the fix/discord-thread-title-reasoning-tuning branch from 26a4128 to 8b6082a Compare May 11, 2026 09:17
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 11, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 11, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 11, 2026
@hanamizuki

Copy link
Copy Markdown
Contributor Author

Rebased onto current upstream/main.

Earlier commit base was on a CHANGELOG.md section that has since been rolled into a versioned release; rather than partially merge that conflict, the two CHANGELOG-only commits were skipped during rebase and a single new Unreleased entry was added afterward.

The extensions/discord/src/monitor/thread-title.generate.test.ts assertion was resolved against the upstream-refactored test style (destructured completionArgs + toEqual({ ... })), with the maxTokens value updated from 512 to 4096 to match this PR's actual change.

Re-running CI; previous failures were stale.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@hanamizuki

Copy link
Copy Markdown
Contributor Author

Resolved the P2 finding (Clamp title tokens to selected model limits).

thread-title.ts no longer forwards the fixed 4096 unchanged. Added resolveThreadTitleMaxTokens(model.maxTokens), which returns the positive minimum of the 4096 default and the selected model's output cap, falling back to 4096 when the model exposes no usable limit — mirroring the established resolveImageToolMaxTokens idiom (src/agents/tools/image-tool.ts, src/media-understanding/image.ts:367). Coverage added in thread-title.generate.test.ts: clamped case (model cap 1024 → request 1024) and default case (cap 200k / unset → request 4096).

Branch rebased onto current upstream/main; the stale CHANGELOG-only commit was dropped during rebase and a single fresh Unreleased entry re-added (covering both the raise and the clamp). Latest commit d2791dfecc.

@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

✨ Hatched: 💎 rare Brave Patch Peep

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 💎 rare.
Trait: guards the happy path.
Image traits: location workflow harbor; accessory CI status badge; palette seafoam, black, and opal; mood patient; pose holding its accessory up for inspection; shell soft velvet shell; lighting clean product lighting; background quiet workflow signs.
Share on X: post this hatch
Copy: My PR egg hatched a 💎 rare Brave Patch Peep in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

hanamizuki and others added 3 commits June 5, 2026 23:57
…models

Follow-up to openclaw#64172. That PR raised DISCORD_THREAD_TITLE_MAX_TOKENS
from 24 to 512, which unblocked very short messages but left two
failure modes for moderately complex inputs on reasoning models:

1. 512 is still too tight when the thinking block alone exceeds the
   budget - extractAssistantText returns empty, generateThreadTitle
   returns null, rename is silently skipped.
2. DEFAULT_THREAD_TITLE_TIMEOUT_MS = 10_000 kills ~15% of real
   production samples: observed MiniMax M2.7 thinking latency ranges
   1.7s to 17s for the same task, median 7s, p95 16.9s (n=20).

Raise MAX_TOKENS 512 -> 4096 and TIMEOUT 10_000 -> 60_000. Both
headrooms are safe because maybeRenameDiscordAutoThread is dispatched
without await - a longer rename cannot block message delivery. Worst
case is the thread keeps its original title for up to a minute longer
before being renamed, which is strictly better than the 15% silent
failure rate today.

Update the matching maxTokens assertion in the unit test. Full data,
percentile distribution, and why-these-numbers analysis in the PR
description.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Forwarding the fixed 4096 title budget unchanged as options.maxTokens can
exceed a selected model's configured output limit. Anthropic/OpenAI
transports prefer a runtime maxTokens over the model cap, so the provider
can reject the over-limit request and the fire-and-forget rename is
silently skipped. Clamp to the positive minimum of the requested budget
and the model cap, mirroring the established resolveImageToolMaxTokens
idiom, with default (uncapped/high) and clamped coverage.
@openclaw-clownfish

Copy link
Copy Markdown
Contributor

Clownfish 🐠 reef update

Thanks for the useful work here. Clownfish could not update this branch directly, so the replacement PR is the writable swim lane for the same fix path.

Replacement PR: #92836
Source PR: #64734
Keeping this PR open so the original context is easy to inspect.
The original contribution stays credited in the replacement PR context.

fish notes: model gpt-5.5, reasoning xhigh; reviewed against b7f3f5a.

@vincentkoc

Copy link
Copy Markdown
Member

Thanks for the fix. I landed this via the ProjectClownfish replacement path because the contributor fork branch could not be safely rebased/pushed by the GitHub App workflow, while the replacement branch preserved your changelog credit and co-author attribution.

Landed replacement: #92836
Merge commit: f58f8c8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants