refactor: improve error handling in embedded run payloads by clarifying conditions for user-facing error messages and updating test descriptions for typing behavior
This commit is contained in:
committed by
Peter Steinberger
parent
95f82154f7
commit
1e8b291374
@@ -170,7 +170,11 @@ export function buildEmbeddedRunPayloads(params: {
|
|||||||
errorLower.includes("needs") ||
|
errorLower.includes("needs") ||
|
||||||
errorLower.includes("requires");
|
errorLower.includes("requires");
|
||||||
|
|
||||||
if (!hasUserFacingReply || !isRecoverableError) {
|
// Show tool errors only when:
|
||||||
|
// 1. There's no user-facing reply AND the error is not recoverable
|
||||||
|
// Recoverable errors (validation, missing params) are already in the model's context
|
||||||
|
// and shouldn't be surfaced to users since the model should retry.
|
||||||
|
if (!hasUserFacingReply && !isRecoverableError) {
|
||||||
const toolSummary = formatToolAggregate(
|
const toolSummary = formatToolAggregate(
|
||||||
params.lastToolError.toolName,
|
params.lastToolError.toolName,
|
||||||
params.lastToolError.meta ? [params.lastToolError.meta] : undefined,
|
params.lastToolError.meta ? [params.lastToolError.meta] : undefined,
|
||||||
@@ -182,8 +186,6 @@ export function buildEmbeddedRunPayloads(params: {
|
|||||||
isError: true,
|
isError: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Note: Recoverable errors are already in the model's context as tool_result is_error.
|
|
||||||
// We only suppress them when a user-facing reply already exists.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasAudioAsVoiceTag = replyItems.some((item) => item.audioAsVoice);
|
const hasAudioAsVoiceTag = replyItems.some((item) => item.audioAsVoice);
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
|||||||
expect(typing.startTypingOnText).not.toHaveBeenCalled();
|
expect(typing.startTypingOnText).not.toHaveBeenCalled();
|
||||||
expect(typing.startTypingLoop).not.toHaveBeenCalled();
|
expect(typing.startTypingLoop).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
it("starts typing on assistant message start in message mode", async () => {
|
it("does not start typing on assistant message start without prior text in message mode", async () => {
|
||||||
runEmbeddedPiAgentMock.mockImplementationOnce(async (params: EmbeddedPiAgentParams) => {
|
runEmbeddedPiAgentMock.mockImplementationOnce(async (params: EmbeddedPiAgentParams) => {
|
||||||
await params.onAssistantMessageStart?.();
|
await params.onAssistantMessageStart?.();
|
||||||
return { payloads: [{ text: "final" }], meta: {} };
|
return { payloads: [{ text: "final" }], meta: {} };
|
||||||
@@ -190,7 +190,8 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
|||||||
});
|
});
|
||||||
await run();
|
await run();
|
||||||
|
|
||||||
expect(typing.startTypingLoop).toHaveBeenCalled();
|
// Typing only starts when there's actual renderable text, not on message start alone
|
||||||
|
expect(typing.startTypingLoop).not.toHaveBeenCalled();
|
||||||
expect(typing.startTypingOnText).not.toHaveBeenCalled();
|
expect(typing.startTypingOnText).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
it("starts typing from reasoning stream in thinking mode", async () => {
|
it("starts typing from reasoning stream in thinking mode", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user