Merge 5db5dc2def into fa9ec6e854
This commit is contained in:
commit
87e61765c5
@ -18,6 +18,7 @@ export function guardSessionManager(
|
||||
agentId?: string;
|
||||
sessionKey?: string;
|
||||
allowSyntheticToolResults?: boolean;
|
||||
dropOrphanToolResults?: boolean;
|
||||
},
|
||||
): GuardedSessionManager {
|
||||
if (typeof (sessionManager as GuardedSessionManager).flushPendingToolResults === "function") {
|
||||
@ -48,6 +49,7 @@ export function guardSessionManager(
|
||||
const guard = installSessionToolResultGuard(sessionManager, {
|
||||
transformToolResultForPersistence: transform,
|
||||
allowSyntheticToolResults: opts?.allowSyntheticToolResults,
|
||||
dropOrphanToolResults: opts?.dropOrphanToolResults,
|
||||
});
|
||||
(sessionManager as GuardedSessionManager).flushPendingToolResults = guard.flushPendingToolResults;
|
||||
return sessionManager as GuardedSessionManager;
|
||||
|
||||
@ -72,6 +72,25 @@ describe("installSessionToolResultGuard", () => {
|
||||
expect(messages.map((m) => m.role)).toEqual(["assistant", "toolResult"]);
|
||||
});
|
||||
|
||||
it("drops orphan toolResult messages by default", () => {
|
||||
const sm = SessionManager.inMemory();
|
||||
installSessionToolResultGuard(sm);
|
||||
|
||||
sm.appendMessage({
|
||||
role: "toolResult",
|
||||
toolCallId: "orphan_call",
|
||||
content: [{ type: "text", text: "no matching tool call" }],
|
||||
isError: true,
|
||||
} as AgentMessage);
|
||||
|
||||
const messages = sm
|
||||
.getEntries()
|
||||
.filter((e) => e.type === "message")
|
||||
.map((e) => (e as { message: AgentMessage }).message);
|
||||
|
||||
expect(messages).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("preserves ordering with multiple tool calls and partial results", () => {
|
||||
const sm = SessionManager.inMemory();
|
||||
const guard = installSessionToolResultGuard(sm);
|
||||
|
||||
@ -49,6 +49,11 @@ export function installSessionToolResultGuard(
|
||||
* Defaults to true.
|
||||
*/
|
||||
allowSyntheticToolResults?: boolean;
|
||||
/**
|
||||
* Whether to drop toolResult messages that do not match a pending tool call.
|
||||
* Defaults to true to avoid corrupting transcripts with orphan tool results.
|
||||
*/
|
||||
dropOrphanToolResults?: boolean;
|
||||
},
|
||||
): {
|
||||
flushPendingToolResults: () => void;
|
||||
@ -66,6 +71,7 @@ export function installSessionToolResultGuard(
|
||||
};
|
||||
|
||||
const allowSyntheticToolResults = opts?.allowSyntheticToolResults ?? true;
|
||||
const dropOrphanToolResults = opts?.dropOrphanToolResults ?? true;
|
||||
|
||||
const flushPendingToolResults = () => {
|
||||
if (pending.size === 0) return;
|
||||
@ -90,6 +96,9 @@ export function installSessionToolResultGuard(
|
||||
if (role === "toolResult") {
|
||||
const id = extractToolResultId(message as Extract<AgentMessage, { role: "toolResult" }>);
|
||||
const toolName = id ? pending.get(id) : undefined;
|
||||
if (id && !pending.has(id) && dropOrphanToolResults) {
|
||||
return undefined as never;
|
||||
}
|
||||
if (id) pending.delete(id);
|
||||
return originalAppend(
|
||||
persistToolResult(message, {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user