From 3880700c5fef5178e569e04fc76793964a3c2a84 Mon Sep 17 00:00:00 2001 From: dash <1549469775@qq.com> Date: Sun, 26 Apr 2026 20:51:42 +0800 Subject: [PATCH] feat: add conversation history demo to showcase multi-turn interactions Introduce a new demo for maintaining complete conversation history in the xllm package. This feature allows the accumulation of user and assistant messages across multiple turns, enabling both generate and stream functionalities to utilize the same history. Update the demo catalog to include this new functionality. --- packages/example/src/xllm/demos/catalog.ts | 8 +++ .../example/src/xllm/demos/conversation-history.ts | 60 ++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 packages/example/src/xllm/demos/conversation-history.ts diff --git a/packages/example/src/xllm/demos/catalog.ts b/packages/example/src/xllm/demos/catalog.ts index 88664ff..bcac6c3 100644 --- a/packages/example/src/xllm/demos/catalog.ts +++ b/packages/example/src/xllm/demos/catalog.ts @@ -1,5 +1,6 @@ import { createXllm, type XProviderName } from "@dm/xllm"; import { hasPrimaryConfig, primaryApiKey, primaryBaseUrl, primaryModel, primaryProvider } from "../env"; +import { runConversationHistoryDemo } from "./conversation-history"; import { runGenerateDemo } from "./generate"; import { runRequestSwitchDemo } from "./request-switch"; import { runStreamDemo } from "./stream"; @@ -41,6 +42,13 @@ export const xllmDemoCatalog: DemoDefinition[] = [ run: (client, log) => runGenerateDemo(client, log), }, { + id: "conversation-history", + title: "完整对话历史", + description: + "用 XMessage[] 累积多轮 user/assistant;generate 与 stream 共用同一条 history,并打印可持久化的 JSON。", + run: (client, log) => runConversationHistoryDemo(client, log), + }, + { id: "thinking", title: "DeepSeek 思考模式", description: diff --git a/packages/example/src/xllm/demos/conversation-history.ts b/packages/example/src/xllm/demos/conversation-history.ts new file mode 100644 index 0000000..f0112ce --- /dev/null +++ b/packages/example/src/xllm/demos/conversation-history.ts @@ -0,0 +1,60 @@ +import type { XMessage } from "@dm/xllm"; +import type { DemoLog, XllmClient } from "./types"; + +/** + * 维护完整对话历史:每轮把 user / assistant 按顺序压入 `messages`, + * 下一请求原样传入 `generate`(或 `stream`),模型才能看到前文。 + */ +export async function runConversationHistoryDemo(client: XllmClient, log: DemoLog): Promise { + log("========== 多轮对话 + 完整 history(generate)=========="); + + const history: XMessage[] = [ + { + role: "system", + content: [{ type: "text", text: "你是简洁助手,回答尽量短。" }], + }, + ]; + + const userTurns = [ + "我叫阿林,请记住。", + "我刚才说我叫什么?只回答名字。", + ]; + + for (let i = 0; i < userTurns.length; i += 1) { + const userText = userTurns[i]!; + log(`\n--- 第 ${i + 1} 轮 user: ${userText} ---`); + history.push({ role: "user", content: [{ type: "text", text: userText }] }); + + const result = await client.generate({ messages: history }); + const assistant: XMessage = { + role: "assistant", + content: [{ type: "text", text: result.text }], + ...(result.reasoning ? { reasoningContent: result.reasoning } : {}), + }; + history.push(assistant); + + log(`[assistant] ${result.text}`); + if (result.reasoning) { + log(`[reasoning 已写入 history.reasoningContent,长度 ${result.reasoning.length}]`); + } + log(`[当前 history 条数] ${history.length}(含 system)`); + } + + log("\n========== 完整 history(JSON,可供持久化 / 下次会话恢复)=========="); + log(JSON.stringify(history, null, 2)); + + log("\n--- 可选:用同一条 history 再流式问一轮(演示 stream 与 generate 共用历史)---"); + history.push({ + role: "user", + content: [{ type: "text", text: "用一句话总结我们聊了什么。" }], + }); + let streamed = ""; + for await (const event of client.stream({ messages: history })) { + if (event.type === "text.delta") { + streamed += event.text; + } + } + history.push({ role: "assistant", content: [{ type: "text", text: streamed }] }); + log(`[stream 本轮正文] ${streamed}`); + log(`[最终 history 条数] ${history.length}`); +}