Persist tool loop summary artifact

This commit is contained in:
2026-05-18 19:31:48 +03:00
parent 9a105caf0b
commit 57985ce87b
3 changed files with 58 additions and 2 deletions
+1 -1
View File
@@ -85,7 +85,7 @@
- [x] Stage `tool_loop` должен выполнять tools через общий `executeToolBatch`. - [x] Stage `tool_loop` должен выполнять tools через общий `executeToolBatch`.
- [x] Stage `tool_loop` должен добавлять tool results в provider adapter. - [x] Stage `tool_loop` должен добавлять tool results в provider adapter.
- [x] Stage `tool_loop` должен управлять max rounds. - [x] Stage `tool_loop` должен управлять max rounds.
- [ ] Stage `tool_loop` должен сохранять tool result artifacts. - [x] Stage `tool_loop` должен сохранять tool result artifacts.
- [x] Stage `tool_loop` должен уметь завершаться без tools как `skipped`. - [x] Stage `tool_loop` должен уметь завершаться без tools как `skipped`.
- [ ] Убрать tool loop из `runOpenAi`. - [ ] Убрать tool loop из `runOpenAi`.
- [ ] Убрать tool loop из `runMistral`. - [ ] Убрать tool loop из `runMistral`.
+39
View File
@@ -0,0 +1,39 @@
import type {StoredAttachment} from "../model/stored-attachment";
import type {TelegramOutputAttachmentRecord, TelegramToolExecutionRecord} from "./telegram-stream-message.js";
import {persistInternalJsonArtifactAttachment} from "./internal-artifact-store";
export async function persistToolLoopSummaryArtifactAttachment(params: {
chatId: number;
messageId: number;
text: string;
executions: readonly TelegramToolExecutionRecord[];
outputAttachments: readonly TelegramOutputAttachmentRecord[];
}): Promise<StoredAttachment | undefined> {
if (!params.executions.length) return undefined;
return await persistInternalJsonArtifactAttachment({
artifactKind: "tool_result",
fileNamePrefix: "tool-loop-summary",
chatId: params.chatId,
messageId: params.messageId,
payload: {
stage: "tool_loop",
text: params.text.trim(),
executions: params.executions.map(execution => ({
toolName: execution.toolName,
callId: execution.callId,
argumentsText: execution.argumentsText,
resultChars: execution.resultChars,
startedAt: execution.startedAt,
finishedAt: execution.finishedAt,
})),
outputAttachments: params.outputAttachments,
},
metadata: {
stage: "tool_loop",
toolExecutions: params.executions.length,
outputAttachments: params.outputAttachments.length,
textChars: params.text.trim().length,
},
});
}
+18 -1
View File
@@ -23,6 +23,7 @@ import {runOllama} from "./unified-ai-runner.ollama";
import {runMistral} from "./unified-ai-runner.mistral"; import {runMistral} from "./unified-ai-runner.mistral";
import {summarizeModelOutput} from "./response-model-output"; import {summarizeModelOutput} from "./response-model-output";
import {summarizeToolLoop} from "./tool-loop-summary"; import {summarizeToolLoop} from "./tool-loop-summary";
import {persistToolLoopSummaryArtifactAttachment} from "./tool-loop-artifact-store";
import { import {
resolveTextToSpeechProviderForUser, resolveTextToSpeechProviderForUser,
sendSynthesizedSpeech, sendSynthesizedSpeech,
@@ -270,15 +271,31 @@ export async function runUnifiedAiResponsePipeline(params: {
name: "tool_loop", name: "tool_loop",
async run() { async run() {
const executions = streamMessage.getToolExecutions(); const executions = streamMessage.getToolExecutions();
const outputAttachments = streamMessage.getOutputAttachments();
const summary = summarizeToolLoop({ const summary = summarizeToolLoop({
text: streamMessage.getText(), text: streamMessage.getText(),
executions, executions,
outputAttachments: streamMessage.getOutputAttachments(), outputAttachments,
}); });
const persisted = await persistToolLoopSummaryArtifactAttachment({
chatId: options.msg.chat.id,
messageId: options.msg.message_id,
text: streamMessage.getText(),
executions,
outputAttachments,
});
if (persisted) {
await streamMessage.storeInternalAttachment(persisted);
}
return { return {
stage: "tool_loop", stage: "tool_loop",
...summary, ...summary,
details: {
...summary.details,
persistedSummaryArtifact: !!persisted,
},
}; };
}, },
}, },