ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов 2.37 - вынос LLM-вызов живого чата из assistantService (большой prompt-блок) в отдельный адаптер, чтобы assistantService стал заметно чище.
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { runAssistantLivingChatLlmRuntime } from "../src/services/assistantLivingChatLlmRuntimeAdapter";
|
||||
|
||||
describe("assistant living chat llm runtime adapter", () => {
|
||||
it("builds prompt/context internally and calls chat client with bounded output tokens", async () => {
|
||||
const chatClient = {
|
||||
chat: vi.fn(async () => ({
|
||||
outputText: " llm-answer "
|
||||
}))
|
||||
};
|
||||
const loadAssistantCanonExcerpt = vi.fn(() => "canon-chunk");
|
||||
const sanitizeOutgoingAssistantText = vi.fn((value: unknown) => String(value ?? "").trim());
|
||||
|
||||
const result = await runAssistantLivingChatLlmRuntime({
|
||||
userMessage: "question",
|
||||
sessionItems: [{ role: "user", text: "prev" }],
|
||||
payload: {
|
||||
llmProvider: "openai",
|
||||
apiKey: "k",
|
||||
model: "m",
|
||||
baseUrl: "https://api.example.com",
|
||||
temperature: 0.2,
|
||||
maxOutputTokens: 5000
|
||||
},
|
||||
chatClient,
|
||||
loadAssistantCanonExcerpt,
|
||||
sanitizeOutgoingAssistantText,
|
||||
defaultModel: "gpt-default",
|
||||
defaultBaseUrl: "https://api.default.com",
|
||||
defaultApiKey: "fallback-key"
|
||||
});
|
||||
|
||||
expect(loadAssistantCanonExcerpt).toHaveBeenCalledWith(520);
|
||||
expect(chatClient.chat).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
llmProvider: "openai",
|
||||
apiKey: "k",
|
||||
model: "m",
|
||||
baseUrl: "https://api.example.com",
|
||||
temperature: 0.2,
|
||||
maxOutputTokens: 900
|
||||
}),
|
||||
expect.objectContaining({
|
||||
userMessage: expect.stringContaining("Сообщение пользователя:\nquestion"),
|
||||
maxOutputTokens: 900,
|
||||
temperature: 0.2,
|
||||
systemPrompt: expect.stringContaining("canon-chunk")
|
||||
})
|
||||
);
|
||||
const promptPayload = chatClient.chat.mock.calls[0]?.[1];
|
||||
expect(promptPayload.userMessage).toContain("user: prev");
|
||||
expect(sanitizeOutgoingAssistantText).toHaveBeenCalledWith(" llm-answer ", expect.any(String));
|
||||
expect(result).toBe("llm-answer");
|
||||
});
|
||||
|
||||
it("uses defaults and fallback text when model output is empty", async () => {
|
||||
const sanitizeOutgoingAssistantText = vi.fn((_value: unknown, fallback?: string) => String(fallback ?? ""));
|
||||
const result = await runAssistantLivingChatLlmRuntime({
|
||||
userMessage: "question",
|
||||
sessionItems: [],
|
||||
payload: {},
|
||||
chatClient: {
|
||||
chat: async () => ({
|
||||
outputText: ""
|
||||
})
|
||||
},
|
||||
loadAssistantCanonExcerpt: () => "canon",
|
||||
sanitizeOutgoingAssistantText,
|
||||
defaultModel: "gpt-default",
|
||||
defaultBaseUrl: "https://api.default.com",
|
||||
defaultApiKey: "fallback-key"
|
||||
});
|
||||
|
||||
expect(sanitizeOutgoingAssistantText).toHaveBeenCalledWith("", expect.any(String));
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user