

























@@ -4,7 +4,10 @@ import type {
44getDiagnosticSessionState as GetDiagnosticSessionStateType,
55SessionState,
66} from "../../logging/diagnostic-session-state.js";
7-import type { wrapToolWithBeforeToolCallHook as WrapToolWithBeforeToolCallHookType } from "../pi-tools.before-tool-call.js";
7+import type {
8+ToolOutcomeObserver,
9+wrapToolWithBeforeToolCallHook as WrapToolWithBeforeToolCallHookType,
10+} from "../pi-tools.before-tool-call.js";
811import type {
912recordToolCall as RecordToolCallType,
1013recordToolCallOutcome as RecordToolCallOutcomeType,
@@ -72,6 +75,7 @@ async function executeWrappedToolOutcome(
7275toolName: string,
7376toolParams: unknown,
7477result: unknown,
78+onToolOutcome?: ToolOutcomeObserver,
7579runId = baseParams.runId,
7680): Promise<unknown> {
7781const tool = wrapToolWithBeforeToolCallHook(
@@ -84,6 +88,7 @@ async function executeWrappedToolOutcome(
8488sessionKey: baseParams.sessionKey,
8589sessionId: baseParams.sessionId,
8690 runId,
91+ onToolOutcome,
8792},
8893);
8994liveToolCallSeq += 1;
@@ -159,12 +164,15 @@ describe("post-compaction loop guard wired into runEmbeddedPiAgent", () => {
159164// Attempt 2: post-compaction. The live wrapped-tool path records each
160165// outcome while the prompt is still running; the third identical result
161166// aborts before the attempt can return.
162-mockedRunEmbeddedAttempt.mockImplementationOnce(async () => {
167+mockedRunEmbeddedAttempt.mockImplementationOnce(async (attemptParams: unknown) => {
168+const onToolOutcome = (attemptParams as { onToolOutcome?: ToolOutcomeObserver })
169+.onToolOutcome;
163170for (let i = 0; i < 3; i += 1) {
164171await executeWrappedToolOutcome(
165172"gateway",
166173{ action: "lookup", path: "x" },
167174"identical-result",
175+onToolOutcome,
168176);
169177}
170178attemptReturned = true;
@@ -200,9 +208,16 @@ describe("post-compaction loop guard wired into runEmbeddedPiAgent", () => {
200208// Attempt 2 (post-compaction): identical args, but DIFFERENT result hash
201209// each time. This fills the window without triggering the persisted-loop
202210// abort because the tool is making progress.
203-mockedRunEmbeddedAttempt.mockImplementationOnce(async () => {
211+mockedRunEmbeddedAttempt.mockImplementationOnce(async (attemptParams: unknown) => {
212+const onToolOutcome = (attemptParams as { onToolOutcome?: ToolOutcomeObserver })
213+.onToolOutcome;
204214for (let i = 0; i < 3; i += 1) {
205-await executeWrappedToolOutcome("gateway", { action: "lookup", path: "x" }, `result-${i}`);
215+await executeWrappedToolOutcome(
216+"gateway",
217+{ action: "lookup", path: "x" },
218+`result-${i}`,
219+onToolOutcome,
220+);
206221}
207222return makeAttemptResult({
208223promptError: null,
@@ -235,9 +250,11 @@ describe("post-compaction loop guard wired into runEmbeddedPiAgent", () => {
235250// Attempt 2 (post-compaction): two distinct records → window full,
236251// guard disarms with no abort. We then append more identical records
237252// afterwards in this test to confirm they are not observed by the guard.
238-mockedRunEmbeddedAttempt.mockImplementationOnce(async () => {
239-await executeWrappedToolOutcome("read", { path: "/a" }, "ra");
240-await executeWrappedToolOutcome("write", { path: "/b" }, "rb");
253+mockedRunEmbeddedAttempt.mockImplementationOnce(async (attemptParams: unknown) => {
254+const onToolOutcome = (attemptParams as { onToolOutcome?: ToolOutcomeObserver })
255+.onToolOutcome;
256+await executeWrappedToolOutcome("read", { path: "/a" }, "ra", onToolOutcome);
257+await executeWrappedToolOutcome("write", { path: "/b" }, "rb", onToolOutcome);
241258return makeAttemptResult({
242259promptError: null,
243260toolMetas: [{ toolName: "read" }, { toolName: "write" }],
@@ -293,12 +310,15 @@ describe("post-compaction loop guard wired into runEmbeddedPiAgent", () => {
293310// Attempt 2 (post-compaction): three identical live tool outcomes while
294311// history is already at the cap. The guard aborts on the third result
295312// before the mocked attempt can return.
296-mockedRunEmbeddedAttempt.mockImplementationOnce(async () => {
313+mockedRunEmbeddedAttempt.mockImplementationOnce(async (attemptParams: unknown) => {
314+const onToolOutcome = (attemptParams as { onToolOutcome?: ToolOutcomeObserver })
315+.onToolOutcome;
297316for (let i = 0; i < 3; i += 1) {
298317await executeWrappedToolOutcome(
299318"gateway",
300319{ action: "lookup", path: "x" },
301320"identical-result",
321+onToolOutcome,
302322);
303323}
304324// History is still capped at HISTORY_TRIM_CAP after the trim.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。