fix(agents): instruct agent not to retry lost tool results#13282
fix(agents): instruct agent not to retry lost tool results#13282thebtf wants to merge 1 commit intoopenclaw:mainfrom
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
src/telegram/bot-message.test.ts
Outdated
| vi.mock("../hooks/internal-hooks.js", () => ({ | ||
| triggerInternalHook, | ||
| createInternalHookEvent, | ||
| })); | ||
|
|
There was a problem hiding this comment.
Mocking unused exports
This test now mocks triggerInternalHook/createInternalHookEvent and asserts triggerInternalHook was called, but src/telegram/bot-message.ts doesn’t import or call either function. As written, the assertion will fail (or is a no-op if the matcher never runs due to earlier failure). Either remove these mocks/assertions or update the production code to actually emit the hook event.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/bot-message.test.ts
Line: 16:20
Comment:
**Mocking unused exports**
This test now mocks `triggerInternalHook`/`createInternalHookEvent` and asserts `triggerInternalHook` was called, but `src/telegram/bot-message.ts` doesn’t import or call either function. As written, the assertion will fail (or is a no-op if the matcher never runs due to earlier failure). Either remove these mocks/assertions or update the production code to actually emit the hook event.
How can I resolve this? If you propose a fix, please make it concise.
src/hooks/internal-hooks.ts
Outdated
| export interface MessageReceivedContext { | ||
| ctxPayload: Record<string, unknown>; | ||
| channel: string; | ||
| messageId: string; | ||
| from: string; | ||
| to: string; | ||
| isGroup: boolean; | ||
| chatId: string; | ||
| senderId?: string; | ||
| hasMedia?: boolean; | ||
| mediaCount?: number; | ||
| timestamp?: number; | ||
| } | ||
|
|
||
| export type MessageReceivedHookEvent = InternalHookEvent & { | ||
| type: "message"; | ||
| action: "received"; | ||
| context: MessageReceivedContext; | ||
| }; | ||
|
|
||
| export function isMessageReceivedEvent( | ||
| event: InternalHookEvent, | ||
| ): event is MessageReceivedHookEvent { | ||
| if (event.type !== "message" || event.action !== "received") { | ||
| return false; | ||
| } | ||
| const context = event.context as Partial<MessageReceivedContext> | null; | ||
| if (!context || typeof context !== "object") { | ||
| return false; | ||
| } | ||
| return typeof context.channel === "string" && typeof context.messageId === "string"; | ||
| } |
There was a problem hiding this comment.
Type guard too weak
isMessageReceivedEvent() only validates context.channel and context.messageId, but ReceivedHookEvent’s context requires several other non-optional fields (from, to, chatId, isGroup, ctxPayload, etc.). Callers using this guard will still be able to read missing/invalid fields under the narrowed type. Either validate all required fields or loosen MessageReceivedContext to match what the guard guarantees.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/hooks/internal-hooks.ts
Line: 169:200
Comment:
**Type guard too weak**
`isMessageReceivedEvent()` only validates `context.channel` and `context.messageId`, but `ReceivedHookEvent`’s `context` requires several other non-optional fields (`from`, `to`, `chatId`, `isGroup`, `ctxPayload`, etc.). Callers using this guard will still be able to read missing/invalid fields under the narrowed type. Either validate all required fields or loosen `MessageReceivedContext` to match what the guard guarantees.
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (1)
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/agents/pi-embedded-runner/compact.ts
Line: 239:262
Comment:
**Wrong model id used**
`createOpenClawCodingTools()` is still passed `modelId` (the primary run model) even when compaction overrides are enabled (`effectiveProvider/effectiveModelId`). This makes tool defaults/policy keyed off the *wrong* model during compaction (e.g., provider-specific tool behavior, auth mode selection, or any model-id based decisions inside tools). Pass the effective model id/provider consistently for the compaction session to avoid mismatched tool behavior.
How can I resolve this? If you propose a fix, please make it concise. |
fee3dec to
3df5497
Compare
|
We've been investigating the underlying cause of the tool result loss bug and submitted a fix in #13746. The root cause is a race condition: pi-agent-core's This PR addresses a symptom but not the timing issue that causes tool results to be lost in the first place. The fix in #13746 adds See detailed analysis in our comment on #8643. |
bfc1ccb to
f92900f
Compare
3df5497 to
92fb241
Compare
92fb241 to
8b1040d
Compare
632087c to
c25190e
Compare
5901224 to
4b62cca
Compare
The synthetic error message inserted during transcript repair was too generic — agents would often retry the exact same call, triggering another rate-limit or timeout loop. Add explicit instructions: "DO NOT retry this exact call" and "inform the user about the error".
4b62cca to
6755f44
Compare
Summary
Test plan
makeMissingToolResult()Greptile Overview
Greptile Summary
This PR updates the synthetic tool-result text emitted during session transcript repair to explicitly tell agents not to retry a “lost” tool call, reducing retry loops on rate limits/timeouts.
It also adds new Pi embedded compaction capabilities:
agents.defaults.compaction.{model,overrideModel})agents.defaults.compaction.timeoutMs) with abort + clearer loggingreasoningon the model used for compaction sessionsFinally, it extends the internal hook event type union to include
messageand adds aMessageReceived*event shape + type guard, with related test changes in Telegram message processing.Confidence Score: 3/5
Context used:
dashboard- CLAUDE.md (source)dashboard- AGENTS.md (source)Validation
pnpm build— passespnpm check— passespnpm test— verified message text change manuallyContribution checklist