fix(ai): adaptive per-model token budget on truncation #78
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/ai-truncation-retry"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
After #72, a recurring "recreate" AI job failed with:
The truncation detection works — but the generators returned
ErrResponseTruncatedstraight to the caller, so the job failed. The ~22–25s durations of the successful jobs show the configured model is a reasoning model that occasionally spends its whole budget on hidden reasoning tokens and stops atfinish_reason: "length"before finishing the JSON.Fix (two clearly separated layers)
1. In-job recovery (fast). The voice-engine and campaign retry loops catch
ErrResponseTruncatedand double the token budget (escalateBudget, 2048 → 4096 → 8192, capped) and retry, so the current job still succeeds.2. Cross-job learning (gentle, per model). Always starting at 2048 would make a heavy model pay for a truncated attempt + escalate-retry on every job. A process-wide
budgetMemoryadapts the starting budget per model — but only on a pattern, not a fluke:truncationsBeforeRaise(3) times does its starting budget creep up — and then by just onetokenBudgetStep(1024), not by doubling — capped atmaxTokenBudget. The counter resets, so the next raise needs a fresh run of truncations.So an isolated truncation is absorbed by the in-job retry and leaves the default alone; a genuinely heavy model slowly settles at a starting budget that stops it from looping.
Model()was added to theClientinterface to key the memory.The memory is process-local (re-learns after a restart); persisting it across restarts is a possible follow-up. The 10-minute
jobExecutionTimeoutleaves ample room for the larger retries (each call ≈25s).Tests (added, TDD)
budgetClientsimulates a reasoning model that truncates below a token threshold.truncationsBeforeRaisetruncations does a later job start one step higher.budgetMemoryunit test: ignores one-offs, raises one step per pattern (no doubling), caps atmaxTokenBudget, leaves other models untouched.go build ./...,go vet ./...,go test ./...all pass.Follow-up to #72 / #75.
🤖 Generated with Claude Code
fix(ai): retry with a larger token budget on truncationto fix(ai): adaptive per-model token budget on truncationRaising the starting budget after a single truncation was too eager ("einmal ist keinmal"). Now: - In-job recovery still doubles the budget so the current job succeeds. - The learned *starting* budget only moves after a model truncates truncationsBeforeRaise (3) times, and then only by one gentle tokenBudgetStep (1024), not by doubling — capped at maxTokenBudget. So an isolated truncation is treated as a fluke and changes nothing; a genuine pattern nudges the default up slowly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>