Browse Source

fix: buildModelMessages approval-responded without result should not emit tool-call

When a tool-call is in 'approval-responded' state with approved=true but
hasResult=false (approval executed but result not yet available in
approvalToolResults), the code was pushing a tool-call part to the
assistant message without a corresponding tool-result in the tool message.

This caused providers (e.g. deepseek) to reject the prompt with
'Tool result is missing for tool call' or
'Invalid prompt: The messages do not match the ModelMessage[] schema'.

Fix: only push tool-approval-request (not tool-call) when hasResult=false.
Also clean up approval-requested branch to only include required fields
(type, approvalId, toolCallId) per AI SDK schema.

Co-authored-by: CodeFree <codefree@chinatelcom.cn>
feat/agent-independence
npmrun 2 months ago
parent
commit
322accb9b2
  1. BIN
      packages/drizzle-pkg/db.sqlite
  2. 18
      server/service/agent/chat-engine.ts

BIN
packages/drizzle-pkg/db.sqlite

Binary file not shown.

18
server/service/agent/chat-engine.ts

@ -90,8 +90,6 @@ function buildModelMessages(
type: "tool-approval-request", type: "tool-approval-request",
approvalId: p.approvalId, approvalId: p.approvalId,
toolCallId: p.toolCallId, toolCallId: p.toolCallId,
toolName: p.toolName,
input: p.args ?? {},
}); });
} else if (p.state === "approval-responded" && p.approvalId) { } else if (p.state === "approval-responded" && p.approvalId) {
const hasResult = opts.approvalToolResults?.[p.toolCallId] !== undefined; const hasResult = opts.approvalToolResults?.[p.toolCallId] !== undefined;
@ -104,17 +102,9 @@ function buildModelMessages(
}); });
} else { } else {
assistantContent.push({ assistantContent.push({
type: "tool-call",
toolCallId: p.toolCallId,
toolName: p.toolName,
input: p.args ?? {},
});
assistantContent.push({
type: "tool-approval-request", type: "tool-approval-request",
approvalId: p.approvalId, approvalId: p.approvalId,
toolCallId: p.toolCallId, toolCallId: p.toolCallId,
toolName: p.toolName,
input: p.args ?? {},
}); });
} }
} else { } else {
@ -440,10 +430,10 @@ export async function executeChat(params: ChatEngineParams): Promise<ChatEngineR
} }
: {}), : {}),
onError: (errorData) => { onError: (errorData) => {
const errMsg = errorData?.error instanceof Error const err = errorData?.error;
? errorData.error.message const errMsg = err instanceof Error ? err.message : String(err ?? "未知错误");
: String(errorData?.error ?? "未知错误"); const errCause = err instanceof Error ? JSON.stringify(err.cause ?? null, null, 2) : "";
logger.error("[%s] [CHAT-ENGINE] streamText error: %s", requestId, errMsg); logger.error("[%s] [CHAT-ENGINE] streamText error: %s\ncause: %s", requestId, errMsg, errCause);
}, },
onChunk: ({ chunk }) => { onChunk: ({ chunk }) => {
if (chunk.type === "text-delta") { if (chunk.type === "text-delta") {

Loading…
Cancel
Save