Summarize tool loop output

This commit is contained in:
2026-05-18 19:05:13 +03:00
parent 9d6cdb008b
commit 9352ade19f
4 changed files with 113 additions and 32 deletions
+56
View File
@@ -0,0 +1,56 @@
import type {PipelineArtifact} from "./user-request-pipeline/types.js";
import type {TelegramOutputAttachmentRecord, TelegramToolExecutionRecord} from "./telegram-stream-message.js";
import {summarizeModelOutput} from "./response-model-output.js";
export type ToolLoopSummary = {
status: "succeeded" | "skipped";
fallbackAction?: "continue_without_stage";
details: {
modelOutput: ReturnType<typeof summarizeModelOutput>;
count: number;
tools: Array<{
toolName: string;
callId: string;
resultChars: number;
}>;
};
artifacts?: PipelineArtifact[];
};
export function summarizeToolLoop(params: {
text: string;
executions: readonly TelegramToolExecutionRecord[];
outputAttachments: readonly TelegramOutputAttachmentRecord[];
}): ToolLoopSummary {
const count = params.executions.length;
const tools = params.executions.map(execution => ({
toolName: execution.toolName,
callId: execution.callId,
resultChars: execution.resultChars,
}));
return {
status: count ? "succeeded" : "skipped",
fallbackAction: count ? undefined : "continue_without_stage",
details: {
modelOutput: summarizeModelOutput({
text: params.text,
toolExecutions: params.executions,
outputAttachments: params.outputAttachments,
}),
count,
tools,
},
artifacts: count ? [{
kind: "tool_result",
stage: "tool_loop",
createdAt: new Date().toISOString(),
toolName: "summary",
callId: "tool_loop_summary",
resultText: JSON.stringify({
count,
tools,
}),
}] : undefined,
};
}
+8 -30
View File
@@ -22,6 +22,7 @@ import {runOpenAi} from "./unified-ai-runner.openai";
import {runOllama} from "./unified-ai-runner.ollama";
import {runMistral} from "./unified-ai-runner.mistral";
import {summarizeModelOutput} from "./response-model-output";
import {summarizeToolLoop} from "./tool-loop-summary";
import {
resolveTextToSpeechProviderForUser,
sendSynthesizedSpeech,
@@ -269,38 +270,15 @@ export async function runUnifiedAiResponsePipeline(params: {
name: "tool_loop",
async run() {
const executions = streamMessage.getToolExecutions();
const summary = summarizeToolLoop({
text: streamMessage.getText(),
executions,
outputAttachments: streamMessage.getOutputAttachments(),
});
return {
stage: "tool_loop",
status: executions.length ? "succeeded" : "skipped",
fallbackAction: executions.length ? undefined : "continue_without_stage",
details: {
modelOutput: summarizeModelOutput({
text: streamMessage.getText(),
toolExecutions: executions,
outputAttachments: streamMessage.getOutputAttachments(),
}),
count: executions.length,
tools: executions.map(execution => ({
toolName: execution.toolName,
callId: execution.callId,
resultChars: execution.resultChars,
})),
},
artifacts: executions.length ? [{
kind: "tool_result",
stage: "tool_loop",
createdAt: new Date().toISOString(),
toolName: "summary",
callId: "tool_loop_summary",
resultText: JSON.stringify({
count: executions.length,
tools: executions.map(execution => ({
toolName: execution.toolName,
callId: execution.callId,
resultChars: execution.resultChars,
})),
}),
}] : undefined,
...summary,
};
},
},