Normalize model call output
This commit is contained in:
+1
-1
@@ -80,7 +80,7 @@
|
||||
## 6. Сделать model_call и tool_loop физически отдельными stages
|
||||
|
||||
- [ ] Stage `model_call` должен делать только один model request.
|
||||
- [ ] Stage `model_call` должен возвращать normalized model output.
|
||||
- [x] Stage `model_call` должен возвращать normalized model output.
|
||||
- [ ] Stage `tool_loop` должен решать, есть ли tool calls.
|
||||
- [ ] Stage `tool_loop` должен выполнять tools через общий `executeToolBatch`.
|
||||
- [ ] Stage `tool_loop` должен добавлять tool results в provider adapter.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import type {TelegramOutputAttachmentRecord, TelegramToolExecutionRecord} from "./telegram-stream-message.js";
|
||||
|
||||
export type NormalizedModelOutput = {
|
||||
text: string;
|
||||
toolExecutions: TelegramToolExecutionRecord[];
|
||||
outputAttachments: TelegramOutputAttachmentRecord[];
|
||||
};
|
||||
|
||||
export function summarizeModelOutput(params: {
|
||||
text: string;
|
||||
toolExecutions: readonly TelegramToolExecutionRecord[];
|
||||
outputAttachments: readonly TelegramOutputAttachmentRecord[];
|
||||
}): NormalizedModelOutput {
|
||||
return {
|
||||
text: params.text.trim(),
|
||||
toolExecutions: [...params.toolExecutions],
|
||||
outputAttachments: [...params.outputAttachments],
|
||||
};
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import {runToolRankStage} from "./tool-rank-stage";
|
||||
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 {
|
||||
resolveTextToSpeechProviderForUser,
|
||||
sendSynthesizedSpeech,
|
||||
@@ -254,6 +255,13 @@ export async function runUnifiedAiResponsePipeline(params: {
|
||||
return {
|
||||
stage: "model_call",
|
||||
status: "succeeded",
|
||||
details: {
|
||||
modelOutput: summarizeModelOutput({
|
||||
text: streamMessage.getText(),
|
||||
toolExecutions: streamMessage.getToolExecutions(),
|
||||
outputAttachments: streamMessage.getOutputAttachments(),
|
||||
}),
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
@@ -266,6 +274,11 @@ export async function runUnifiedAiResponsePipeline(params: {
|
||||
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,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const {summarizeModelOutput} = await import("../dist/ai/response-model-output.js");
|
||||
|
||||
test("model output summary trims text and copies attachment records", () => {
|
||||
const toolExecutions = [{toolName: "read_file", callId: "1", argumentsText: "{}", resultChars: 10}];
|
||||
const outputAttachments = [{artifactKind: "generated_file", fileName: "out.txt", sizeBytes: 12}];
|
||||
|
||||
const summary = summarizeModelOutput({
|
||||
text: " hello world ",
|
||||
toolExecutions,
|
||||
outputAttachments,
|
||||
});
|
||||
|
||||
assert.deepEqual(summary, {
|
||||
text: "hello world",
|
||||
toolExecutions,
|
||||
outputAttachments,
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user