fix(agent): capture compaction retry AbortError for model fallback#341
fix(agent): capture compaction retry AbortError for model fallback#341erikpr1994 wants to merge 1 commit intoopenclaw:mainfrom
Conversation
Wrap waitForCompactionRetry() in try/catch to capture AbortError that was escaping and bypassing the model fallback mechanism. When a timeout fires, session.abort() causes both session.prompt() and waitForCompactionRetry() to throw AbortError. Previously only the prompt error was captured, allowing the compaction error to escape to model-fallback.ts where it was immediately re-thrown (line 199: isAbortError check), bypassing fallback model attempts. Fixes openclaw#313
steipete
left a comment
There was a problem hiding this comment.
Guard compaction retry catch to AbortError only. Right now non-abort errors from waitForCompactionRetry() get treated as promptError and routed through fallback, which can mask real bugs. Suggest: catch err; if isAbortError(err) { if (!promptError) promptError = err; } else { throw err; }. File: src/agents/pi-embedded-runner.ts:909.
|
Landed on main via fast-forward. Commits:\n- cd4e202 fix(agent): capture compaction retry AbortError for model fallback\n- e816991 docs: update changelog + clawtributor list for PR #341 (added @erikpr1994)\n\nTests:\n- pnpm lint (fails: formatter in src/commands/configure.ts; pre-existing)\n- pnpm build (pass)\n- pnpm test (pass; 2 live tests skipped)\n- pnpm docs:build (fails: 126 broken links; pre-existing) |
|
Landed on main. Fix keeps compaction retry AbortError as fallback trigger while rethrowing non-abort errors. Added changelog + clawtributor entry. Commits: cd4e202, e816991. Tests: pnpm lint (fails: formatter in src/commands/configure.ts; pre-existing), pnpm build (pass), pnpm test (pass; 2 live tests skipped), pnpm docs:build (fails: 126 broken links; pre-existing). |
* feat(agents): add runtime tool-approval orchestrator with approvals.tools config - Add approvals.tools config types + zod schema (enabled, mode, timeoutMs, policy, routing, classifier) - Create tool-approval orchestrator module (decision engine, param redaction, gateway integration) - Integrate orchestrator into before-tool-call wrapper path (runs after plugin hooks, before execution) - Add ToolApprovalBlockedError with stable machine-readable error shape - Add 90 tests covering all mode/decision/risk branches - Backward-compatible: no behavior change when approvals.tools is missing or disabled * feat: upgrade /approve and Discord handler to canonical tool approvals - /approve now queries tool.approvals.get for canonical records and resolves via tool.approval.resolve (with requestHash); falls back to legacy exec.approval.resolve when no canonical record is found - Discord handler listens for tool.approval.requested/resolved events and renders generic tool approval embeds for non-exec tools - resolveApproval prefers tool.approval.resolve when requestHash is cached, keeping legacy exec path for backward compatibility - Updated command description to 'tool approval requests' - Added shouldHandleToolApproval for canonical event filtering - Extended tests with canonical, legacy-fallback, and gateway-error scenarios * refactor: rename .clawdbrain → .openclaw and fix repo/domain references - Settings dir: ~/.clawdbrain → ~/.openclaw - Repo references: openclaw/clawdbrain → dgarson/clawdbrain - Domain: clawdbrain.bot → openclaw.ai - CLI command: clawdbrain login → openclaw login - 48 files changed across src/, docs/, apps/web/, ui/ * cron timeout fixes * feat(agents): wire tool approval context from config into tool creation path - Inject approvals.tools config into wrapToolWithBeforeToolCallHook context - Populate channel field from messageProvider via resolveGatewayMessageChannel - Wire callGatewayTool as the gateway call adapter for approval requests - Approval context is only constructed when approvals.tools exists and is enabled * fix: address review gaps in tool approval handler - Exec dedup: store canonical request for exec tools and defer embed creation by 200ms so the legacy mirror gets first shot; if the mirror never arrives, fall back to a generic tool embed (future-proofs against legacy event removal) - Extract sendToolApprovalEmbed to eliminate code duplication - Add buildApprovalCustomId / parseApprovalData generic aliases (same wire format, clearer naming for non-exec tool code paths) - Add alias identity tests * fix: minor tool approval request fixes * auto-reply/approval integration fix * include exec approval doc * fix: agent-runner-execution integration into auto-reply, executor/kernel fixes * more work on agent runner and memory/heartbeta integration * lots of tests resulting from unification of exec kernel; refactored * Redact arrays in approval helper * lancedb fixes * more fixes/test updates * fix: minor problem * fix: restore proper non-throwing session label truncation * Tests: cover DM thread URL summaries (openclaw#341) --------- Co-authored-by: Claude <[email protected]>
* Fix unstable mute implementation on Windows/Linux * add some delay before the mute so the audio feedback plays --------- Co-authored-by: CJ Pais <[email protected]>
67d6e403d Merge pull request openclaw#352 from Zhumin-lv-wn/fix/card-finalize-use-accumulated-content bddb4427f fix(card): fix AI Card streaming finalization bugs c535af6c5 Merge pull request openclaw#350 from Zhumin-lv-wn/fix/card-finalize-use-accumulated-content d044bf291 fix(card): fix AI Card streaming finalization bugs de7b25ced Merge pull request openclaw#344 from ming1523/pr/dingtalk-thinking-reaction-clean-main-20260315 c66604576 test(dingtalk): 补充 emoji 模式说明与测试 ca98030cf merge(main): 同步最新主线并清理 PR344 冲突 60071fc60 refactor(dingtalk): 收敛 ack reaction API 调用 0babd7cbe chore(todo): regroup PRs under task checklist items 27922ce76 fix(dingtalk): 补齐 ackReaction review 收尾 e7998195b feat(dingtalk): 支持 ackReaction emoji 模式 094b6bd15 merge(main): 解决 PR344 与主线冲突 110d12deb test(dingtalk): 补强 ackReaction 自定义文本覆盖 8b8fd1482 feat(dingtalk): align ack reaction config with official docs 3c86d7a72 Merge pull request openclaw#348 from Zhumin-lv-wn/fix/card-finalize-use-accumulated-content 9f20a89f8 test(card): verify finalize uses accumulated content across multi-turn tool calls 12762e872 fix(card): use accumulated content for AI Card finalization f2bd84788 chore(todo): align latest issue/pr findings into existing hierarchy 00a80263a Merge pull request openclaw#346 from aoxiaotian-ai/fix/inbound-handler-textToSend-type a2a897ab1 fix(inbound-handler): guard textToSend undefined in card final/tool deliver 50e44f212 Merge pull request openclaw#313 from bkloveming/fix/peer-id-lazy-preload-for-delivery-queue 04e3b98c8 Merge pull request openclaw#311 from LazyBug1E0CF/fix/dingtalk-reply-media bb6da5d38 test: cover inbound reply media delivery paths 883a7931a fix: deliver MEDIA attachments in inbound reply handler 418a4b450 Merge pull request openclaw#341 from Zhumin-lv-wn/perf/streaming-response-optimization 2f1d906b8 fix: retry peer-id preload on top-level failures 9ede8d331 fix: harden peer-id preload idempotency and coverage 413517940 fix: lazy-preload peer ID registry to fix 400 errors in delivery queue e29e36072 Merge pull request openclaw#343 from soimy/codex/fix-dingtalk-idle-reconnect dc1f5194e Merge pull request openclaw#248 from androidshu/codex/fix-action-send-mediaurl-upload e22a8b781 test(integration): cover actions.send mediaUrl redirect upload chain fb626f1b4 Merge remote-tracking branch 'origin/main' into codex/pr-248 d1c012877 fix(dingtalk): harden mediaUrl prepare and redirect DNS pinning 332cddd23 feat(dingtalk): parse pdf/docx text into context (openclaw#298) d435be58c fix: address copilot review feedback 34edb2178 fix: restore connection manager heartbeat monitoring db3071c3e fix: stabilize dingtalk stream reconnect baseline 95a3fbbd8 fix: add curly braces for early returns (lint curly rule) a691fe2dc Merge branch 'soimy:main' into perf/streaming-response-optimization dee2ad1eb docs: clarify thinking always streams; add answerPrefix threshold tests 298cea5e1 fix: answerPrefix threshold and disableBlockStreaming condition 0579f1281 feat(dingtalk): add AI Card streaming optimization with CardDraftController 2aec0034e Revert "Merge pull request openclaw#332 from ming1523/pr/dingtalk-thinking-reaction-main-20260314" ee259200c Merge pull request openclaw#332 from ming1523/pr/dingtalk-thinking-reaction-main-20260314 b0f4f7762 fix(dingtalk): prefer thinking reaction feedback 41abbc12a fix(dingtalk): tighten thinking reaction gating 06a6f5d0f feat(dingtalk): add native thinking reaction feedback 5970a7af1 chore(todo): align latest issue/pr findings into existing hierarchy 862bfca8f fix: add connection manager heartbeat e30c2f0da refactor: remove unsupported socket idle reconnect path bf4a1233c fix: avoid idle reconnects on quiet stream connections e49cd9f44 Revert "feat(dingtalk): 增加异步回执模式" (openclaw#334) 54dff048e chore: add .playwright to .gitignore for generated files e76461b29 chore(todo): align latest issue/pr findings into existing hierarchy 3aea182c6 Merge pull request openclaw#231 from huww98/fix/stop-reason c296ff109 Merge pull request openclaw#295 from ming1523/pr/async-mode-connector-borrow-20260311 bcfd1db7d fix: don't supress stop reason e00f8f324 docs: add README table of contents 53fe911fd Merge remote-tracking branch 'origin/main' into pr-check-295 79f583443 fix(dingtalk): keep control aliases off async path 4ac48703b fix(dingtalk): force markdown replies in async mode cfda4c05c docs(dingtalk): trim unrelated README drift from async ack PR a9198437a fix(dingtalk): keep async inflight lock until completion 97638c7cf fix(dingtalk): tighten async ack delivery semantics 061305ef2 fix(dingtalk): import async mode config type 84f092c80 feat(dingtalk): add async ack mode for inbound messages git-subtree-dir: extensions/dingtalk git-subtree-split: 67d6e403db157e08d7658186756c4cbd16f9fd0c
Summary
waitForCompactionRetry()in try/catch to capture AbortError that was escaping and bypassing model fallbacksession.prompt()andwaitForCompactionRetry()can throw AbortErrormodel-fallback.tswhereisAbortError()check immediately re-throwsChanges
waitForCompactionRetry()inpi-embedded-runner.tspromptErrorif one wasn't already capturedRoot Cause
In
pi-embedded-runner.ts,waitForCompactionRetry()at line 912 was outside the try/catch block that capturespromptError. When a timeout occurs:abortRun(true)is called → setstimedOut = trueand callssession.abort()session.prompt()throws AbortError → caught aspromptErrorwaitForCompactionRetry()ALSO throws AbortError → NOT caught, escapes!model-fallback.ts:199:if (isAbortError(err)) throw err;→ bypasses fallbackTest Plan
pnpm lintpassespnpm buildpassespnpm test src/agents/passes (26 passed, 2 skipped)Related
Fixes #313