Merge 580b59f6e6 into 4583f88626
This commit is contained in:
commit
215d2f9db5
@ -48,6 +48,8 @@ export type AgentRunLoopResult =
|
||||
autoCompactionCompleted: boolean;
|
||||
/** Payload keys sent directly (not via pipeline) during tool flush. */
|
||||
directlySentBlockKeys?: Set<string>;
|
||||
/** Tool call IDs that were executed successfully (phase === "result" without error). */
|
||||
executedToolCallIds?: Set<string>;
|
||||
}
|
||||
| { kind: "final"; payload: ReplyPayload };
|
||||
|
||||
@ -82,6 +84,8 @@ export async function runAgentTurnWithFallback(params: {
|
||||
let autoCompactionCompleted = false;
|
||||
// Track payloads sent directly (not via pipeline) during tool flush to avoid duplicates.
|
||||
const directlySentBlockKeys = new Set<string>();
|
||||
// Track tool calls that were executed successfully (completed with result phase).
|
||||
const executedToolCallIds = new Set<string>();
|
||||
|
||||
const runId = params.opts?.runId ?? crypto.randomUUID();
|
||||
params.opts?.onAgentRunStart?.(runId);
|
||||
@ -307,6 +311,14 @@ export async function runAgentTurnWithFallback(params: {
|
||||
if (phase === "start" || phase === "update") {
|
||||
await params.typingSignals.signalToolStart();
|
||||
}
|
||||
// Track successful tool execution (result phase without error).
|
||||
if (phase === "result") {
|
||||
const toolCallId = typeof evt.data.toolCallId === "string" ? evt.data.toolCallId : "";
|
||||
const isError = Boolean(evt.data.isError);
|
||||
if (toolCallId && !isError) {
|
||||
executedToolCallIds.add(toolCallId);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Track auto-compaction completion
|
||||
if (evt.stream === "compaction") {
|
||||
@ -554,5 +566,6 @@ export async function runAgentTurnWithFallback(params: {
|
||||
didLogHeartbeatStrip,
|
||||
autoCompactionCompleted,
|
||||
directlySentBlockKeys: directlySentBlockKeys.size > 0 ? directlySentBlockKeys : undefined,
|
||||
executedToolCallIds: executedToolCallIds.size > 0 ? executedToolCallIds : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@ -328,7 +328,13 @@ export async function runReplyAgent(params: {
|
||||
return finalizeWithFollowup(runOutcome.payload, queueKey, runFollowupTurn);
|
||||
}
|
||||
|
||||
const { runResult, fallbackProvider, fallbackModel, directlySentBlockKeys } = runOutcome;
|
||||
const {
|
||||
runResult,
|
||||
fallbackProvider,
|
||||
fallbackModel,
|
||||
directlySentBlockKeys,
|
||||
executedToolCallIds,
|
||||
} = runOutcome;
|
||||
let { didLogHeartbeatStrip, autoCompactionCompleted } = runOutcome;
|
||||
|
||||
if (
|
||||
@ -391,8 +397,33 @@ export async function runReplyAgent(params: {
|
||||
// Drain any late tool/block deliveries before deciding there's "nothing to send".
|
||||
// Otherwise, a late typing trigger (e.g. from a tool callback) can outlive the run and
|
||||
// keep the typing indicator stuck.
|
||||
if (payloadArray.length === 0)
|
||||
if (payloadArray.length === 0) {
|
||||
// If tools were executed but no final response was generated, send a confirmation.
|
||||
// Skip if verbose is enabled (onToolResult already sent notifications via tool callbacks)
|
||||
// or if it's a heartbeat (which should be silent).
|
||||
const hasExecutedTools =
|
||||
executedToolCallIds && executedToolCallIds.size > 0;
|
||||
const verboseEnabled = shouldEmitToolResult();
|
||||
// Only send confirmation if:
|
||||
// 1. Tools were executed successfully
|
||||
// 2. Verbose is disabled (onToolResult wasn't called, so no notifications were sent)
|
||||
// 3. Not a heartbeat (heartbeats should be silent)
|
||||
// 4. All pending tool tasks completed (to avoid race conditions)
|
||||
if (
|
||||
hasExecutedTools &&
|
||||
!verboseEnabled &&
|
||||
!isHeartbeat &&
|
||||
pendingToolTasks.size === 0
|
||||
) {
|
||||
const confirmationPayload: ReplyPayload = {
|
||||
text: "✅ Concluído",
|
||||
};
|
||||
const taggedConfirmation = applyReplyToMode(confirmationPayload);
|
||||
await signalTypingIfNeeded([taggedConfirmation], typingSignals);
|
||||
return finalizeWithFollowup(taggedConfirmation, queueKey, runFollowupTurn);
|
||||
}
|
||||
return finalizeWithFollowup(undefined, queueKey, runFollowupTurn);
|
||||
}
|
||||
|
||||
const payloadResult = buildReplyPayloads({
|
||||
payloads: payloadArray,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user