agent-scene-toolkit 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -0
- package/dist/index.cjs +118 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -1
- package/dist/index.d.ts +83 -1
- package/dist/index.js +118 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ Lightweight Agent orchestration library built on LangChain.
|
|
|
9
9
|
- **ToolKit**:静态能力包,按领域分组的工具集 + 使用策略 Prompt
|
|
10
10
|
- **AgentProfile**:角色身份,只需定义 name + systemPrompt + model
|
|
11
11
|
- **Scene**:运行时场景,注入动态上下文 + 决定当前可用的 ToolKit
|
|
12
|
+
- **KnowledgeBase**:知识库(RAG),纯文本数据 + 语义检索,AI 按需查阅
|
|
12
13
|
|
|
13
14
|
## 📦 Install
|
|
14
15
|
|
|
@@ -126,6 +127,115 @@ for await (const event of agent.chat({ message: '写一个30秒的广告脚本',
|
|
|
126
127
|
}
|
|
127
128
|
```
|
|
128
129
|
|
|
130
|
+
## RAG 知识库
|
|
131
|
+
|
|
132
|
+
让 Agent 具备**按需检索外部知识**的能力。只需提供文本数据 + 嵌入模型,AI 自动判断何时检索。
|
|
133
|
+
|
|
134
|
+
### 基本用法
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { createAgent, defineProfile, defineKnowledgeBase } from 'agent-scene-toolkit'
|
|
138
|
+
// 使用者自行选择嵌入模型(本地免费 / OpenAI / 其他)
|
|
139
|
+
import { HuggingFaceTransformersEmbeddings } from '@langchain/community/embeddings/hf_transformers'
|
|
140
|
+
|
|
141
|
+
// 1. 定义知识库
|
|
142
|
+
const faqKB = defineKnowledgeBase({
|
|
143
|
+
name: 'faq',
|
|
144
|
+
description: '产品常见问题,当用户问功能、价格、退款等问题时检索',
|
|
145
|
+
documents: [
|
|
146
|
+
'7天内无理由退款,联系客服即可办理',
|
|
147
|
+
'基础版99元/月,专业版299元/月',
|
|
148
|
+
'支持微信、支付宝、银行卡付款',
|
|
149
|
+
'工作日 9:00-18:00 提供在线客服',
|
|
150
|
+
],
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
// 2. 创建 Agent,传入知识库 + 嵌入模型
|
|
154
|
+
const agent = createAgent({
|
|
155
|
+
agents: [defineProfile({ name: '客服', systemPrompt: '你是产品客服...', model: 'gpt-4o' })],
|
|
156
|
+
knowledgeBases: [faqKB],
|
|
157
|
+
embeddings: new HuggingFaceTransformersEmbeddings({
|
|
158
|
+
model: 'Xenova/all-MiniLM-L6-v2',
|
|
159
|
+
}),
|
|
160
|
+
llm: { baseURL: 'https://api.bltcy.ai', apiKey: 'sk-xxx' },
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
// 3. 对话 — AI 自动判断是否需要检索
|
|
164
|
+
for await (const event of agent.chat({ message: '怎么退款?', threadId: 't-1' })) {
|
|
165
|
+
if (event.type === 'text') process.stdout.write(event.content)
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 从数据库 / API 动态加载
|
|
170
|
+
|
|
171
|
+
`documents` 支持异步函数,Agent 创建时自动调用加载数据:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
const dynamicKB = defineKnowledgeBase({
|
|
175
|
+
name: 'product-docs',
|
|
176
|
+
description: '产品操作手册',
|
|
177
|
+
documents: async () => {
|
|
178
|
+
// 从数据库加载
|
|
179
|
+
const rows = await db.query('SELECT content FROM docs')
|
|
180
|
+
return rows.map(r => r.content)
|
|
181
|
+
|
|
182
|
+
// 或从 API 加载
|
|
183
|
+
// const res = await fetch('https://my-api.com/docs')
|
|
184
|
+
// return res.json()
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 多知识库
|
|
190
|
+
|
|
191
|
+
AI 根据每个知识库的 `description` 自动选择检索哪个:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
const faqKB = defineKnowledgeBase({
|
|
195
|
+
name: 'faq',
|
|
196
|
+
description: '产品常见问题',
|
|
197
|
+
documents: ['7天内无理由退款', ...],
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
const apiDocsKB = defineKnowledgeBase({
|
|
201
|
+
name: 'api-docs',
|
|
202
|
+
description: 'API 接口文档,当用户问技术集成、接口调用时检索',
|
|
203
|
+
documents: ['POST /api/users 创建用户', ...],
|
|
204
|
+
topK: 5, // 返回前 5 条最相关结果(默认 3)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
const agent = createAgent({
|
|
208
|
+
agents: [developer],
|
|
209
|
+
knowledgeBases: [faqKB, apiDocsKB],
|
|
210
|
+
embeddings: new HuggingFaceTransformersEmbeddings({ model: 'Xenova/all-MiniLM-L6-v2' }),
|
|
211
|
+
llm: { ... },
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### SSE 事件
|
|
216
|
+
|
|
217
|
+
知识库检索复用 `tool_start` / `tool_end` 事件,**前端无需任何改动**:
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
data: {"type":"tool_start","toolName":"faq","input":{"query":"退款政策"}}
|
|
221
|
+
data: {"type":"tool_end","toolName":"faq","output":"7天内无理由退款,联系客服即可办理"}
|
|
222
|
+
data: {"type":"text","content":"根据我们的政策,7天内可以无理由退款..."}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 嵌入模型选择
|
|
226
|
+
|
|
227
|
+
库不内置嵌入模型,由使用者自行选择:
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// 方案 A:本地免费模型(推荐)
|
|
231
|
+
import { HuggingFaceTransformersEmbeddings } from '@langchain/community/embeddings/hf_transformers'
|
|
232
|
+
const embeddings = new HuggingFaceTransformersEmbeddings({ model: 'Xenova/all-MiniLM-L6-v2' })
|
|
233
|
+
|
|
234
|
+
// 方案 B:OpenAI Embeddings(需 API Key)
|
|
235
|
+
import { OpenAIEmbeddings } from '@langchain/openai'
|
|
236
|
+
const embeddings = new OpenAIEmbeddings({ model: 'text-embedding-3-small' })
|
|
237
|
+
```
|
|
238
|
+
|
|
129
239
|
## Express 集成
|
|
130
240
|
|
|
131
241
|
```typescript
|
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,7 @@ var langchain = require('langchain');
|
|
|
6
6
|
var messages = require('@langchain/core/messages');
|
|
7
7
|
var prebuilt = require('@langchain/langgraph/prebuilt');
|
|
8
8
|
var langgraphSupervisor = require('@langchain/langgraph-supervisor');
|
|
9
|
+
var tools = require('@langchain/core/tools');
|
|
9
10
|
|
|
10
11
|
// src/profile.ts
|
|
11
12
|
function defineProfile(input) {
|
|
@@ -31,6 +32,23 @@ function defineScene(input) {
|
|
|
31
32
|
return Object.freeze({ ...input });
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
// src/knowledge.ts
|
|
36
|
+
function defineKnowledgeBase(input) {
|
|
37
|
+
if (!input.name) throw new Error("KnowledgeBase name is required");
|
|
38
|
+
if (!input.description) throw new Error("KnowledgeBase description is required");
|
|
39
|
+
if (!input.documents) throw new Error("KnowledgeBase documents is required");
|
|
40
|
+
if (typeof input.documents !== "function" && !Array.isArray(input.documents)) {
|
|
41
|
+
throw new Error("KnowledgeBase documents must be a string[] or () => Promise<string[]>");
|
|
42
|
+
}
|
|
43
|
+
if (Array.isArray(input.documents) && input.documents.length === 0) {
|
|
44
|
+
throw new Error("KnowledgeBase documents must not be empty");
|
|
45
|
+
}
|
|
46
|
+
if (input.topK !== void 0 && (typeof input.topK !== "number" || input.topK < 1)) {
|
|
47
|
+
throw new Error("KnowledgeBase topK must be a positive number");
|
|
48
|
+
}
|
|
49
|
+
return Object.freeze({ ...input });
|
|
50
|
+
}
|
|
51
|
+
|
|
34
52
|
// src/prompt.ts
|
|
35
53
|
var BASE_PROMPT = `You are an autonomous AI agent. You can reason, plan, and take actions using the tools available to you.
|
|
36
54
|
|
|
@@ -403,11 +421,81 @@ function createExpressHandler(agent) {
|
|
|
403
421
|
}
|
|
404
422
|
};
|
|
405
423
|
}
|
|
424
|
+
function cosineSimilarity(a, b) {
|
|
425
|
+
let dot = 0;
|
|
426
|
+
let normA = 0;
|
|
427
|
+
let normB = 0;
|
|
428
|
+
for (let i = 0; i < a.length; i++) {
|
|
429
|
+
dot += a[i] * b[i];
|
|
430
|
+
normA += a[i] * a[i];
|
|
431
|
+
normB += b[i] * b[i];
|
|
432
|
+
}
|
|
433
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
434
|
+
return denom === 0 ? 0 : dot / denom;
|
|
435
|
+
}
|
|
436
|
+
async function initVectorStores(knowledgeBases, embeddings) {
|
|
437
|
+
const stores = [];
|
|
438
|
+
for (const kb of knowledgeBases) {
|
|
439
|
+
try {
|
|
440
|
+
const docs = typeof kb.documents === "function" ? await kb.documents() : kb.documents;
|
|
441
|
+
if (!docs.length) {
|
|
442
|
+
console.warn(`[initVectorStores] "${kb.name}" has no documents, skipping`);
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
console.log(`[initVectorStores] Embedding "${kb.name}" (${docs.length} documents)...`);
|
|
446
|
+
const vectors = await embeddings.embedDocuments(docs);
|
|
447
|
+
const records = docs.map((text, i) => ({
|
|
448
|
+
text,
|
|
449
|
+
vector: vectors[i]
|
|
450
|
+
}));
|
|
451
|
+
stores.push({ kb, records });
|
|
452
|
+
console.log(`[initVectorStores] "${kb.name}" ready (${records.length} vectors, dim=${vectors[0]?.length ?? 0})`);
|
|
453
|
+
} catch (error) {
|
|
454
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
455
|
+
console.error(`[initVectorStores] Failed to embed "${kb.name}":`, message);
|
|
456
|
+
throw new Error(`Failed to initialize knowledge base "${kb.name}": ${message}`);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return stores;
|
|
460
|
+
}
|
|
461
|
+
async function searchVectorStore(store, query, embeddings) {
|
|
462
|
+
const topK = store.kb.topK ?? 3;
|
|
463
|
+
const queryVector = await embeddings.embedQuery(query);
|
|
464
|
+
const scored = store.records.map((record) => ({
|
|
465
|
+
text: record.text,
|
|
466
|
+
score: cosineSimilarity(queryVector, record.vector)
|
|
467
|
+
}));
|
|
468
|
+
scored.sort((a, b) => b.score - a.score);
|
|
469
|
+
return scored.slice(0, topK).map((item) => item.text);
|
|
470
|
+
}
|
|
471
|
+
function buildKnowledgeTools(stores, embeddings) {
|
|
472
|
+
return stores.map((store) => new tools.DynamicTool({
|
|
473
|
+
name: store.kb.name,
|
|
474
|
+
description: store.kb.description,
|
|
475
|
+
func: async (query) => {
|
|
476
|
+
try {
|
|
477
|
+
const results = await searchVectorStore(store, query, embeddings);
|
|
478
|
+
if (results.length === 0) {
|
|
479
|
+
return "No relevant information found.";
|
|
480
|
+
}
|
|
481
|
+
return results.join("\n\n---\n\n");
|
|
482
|
+
} catch (error) {
|
|
483
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
484
|
+
console.error(`[buildKnowledgeTools] Search failed for "${store.kb.name}":`, message);
|
|
485
|
+
return `Search failed: ${message}`;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}));
|
|
489
|
+
}
|
|
406
490
|
|
|
407
491
|
// src/agent.ts
|
|
408
492
|
var Agent = class {
|
|
409
493
|
/** @internal */
|
|
410
494
|
options;
|
|
495
|
+
/** RAG 知识库转换而来的 DynamicTool 列表 */
|
|
496
|
+
knowledgeTools = [];
|
|
497
|
+
/** 异步初始化 Promise(向量化知识库等) */
|
|
498
|
+
readyPromise;
|
|
411
499
|
constructor(options) {
|
|
412
500
|
this.options = {
|
|
413
501
|
maxMessages: 50,
|
|
@@ -416,6 +504,26 @@ var Agent = class {
|
|
|
416
504
|
...options
|
|
417
505
|
};
|
|
418
506
|
this.validate();
|
|
507
|
+
this.readyPromise = this.init();
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* 异步初始化 — 向量化知识库并构建检索 Tool。
|
|
511
|
+
*
|
|
512
|
+
* 在构造函数中启动,chat() 首次调用时 await 确保完成。
|
|
513
|
+
* 若无 knowledgeBases,立即 resolve。
|
|
514
|
+
*/
|
|
515
|
+
async init() {
|
|
516
|
+
const { knowledgeBases, embeddings } = this.options;
|
|
517
|
+
if (!knowledgeBases?.length || !embeddings) return;
|
|
518
|
+
try {
|
|
519
|
+
const stores = await initVectorStores(knowledgeBases, embeddings);
|
|
520
|
+
this.knowledgeTools = buildKnowledgeTools(stores, embeddings);
|
|
521
|
+
console.log(`[Agent] ${this.knowledgeTools.length} knowledge tool(s) ready`);
|
|
522
|
+
} catch (error) {
|
|
523
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
524
|
+
console.error("[Agent] Knowledge base initialization failed:", message);
|
|
525
|
+
throw error;
|
|
526
|
+
}
|
|
419
527
|
}
|
|
420
528
|
/**
|
|
421
529
|
* 发起对话,返回标准化 SSE 事件的异步生成器。
|
|
@@ -433,6 +541,7 @@ var Agent = class {
|
|
|
433
541
|
*/
|
|
434
542
|
async *chat(chatOptions) {
|
|
435
543
|
try {
|
|
544
|
+
await this.readyPromise;
|
|
436
545
|
if (!chatOptions.message) {
|
|
437
546
|
yield { type: "error", message: "message is required" };
|
|
438
547
|
yield { type: "done" };
|
|
@@ -445,7 +554,11 @@ var Agent = class {
|
|
|
445
554
|
}
|
|
446
555
|
const scene = this.options.scene;
|
|
447
556
|
const activeToolkits = scene ? this.options.toolkits.filter((tk) => scene.toolkits.includes(tk.name)) : this.options.toolkits;
|
|
448
|
-
const tools =
|
|
557
|
+
const tools = [
|
|
558
|
+
...activeToolkits.flatMap((tk) => tk.tools),
|
|
559
|
+
...this.knowledgeTools
|
|
560
|
+
// RAG 知识库 Tool 注入
|
|
561
|
+
];
|
|
449
562
|
const toolkitPrompts = activeToolkits.map((tk) => tk.prompt);
|
|
450
563
|
const isMultiAgent = this.options.agents.length > 1 && !!this.options.supervisor;
|
|
451
564
|
let stream;
|
|
@@ -548,6 +661,9 @@ ${err.stack}` : ""}` : String(err);
|
|
|
548
661
|
}
|
|
549
662
|
}
|
|
550
663
|
}
|
|
664
|
+
if (this.options.knowledgeBases?.length && !this.options.embeddings) {
|
|
665
|
+
throw new Error("embeddings is required when knowledgeBases is provided");
|
|
666
|
+
}
|
|
551
667
|
}
|
|
552
668
|
};
|
|
553
669
|
function createAgent2(options) {
|
|
@@ -560,6 +676,7 @@ exports.buildSingleGraph = buildSingleGraph;
|
|
|
560
676
|
exports.buildSupervisorGraph = buildSupervisorGraph;
|
|
561
677
|
exports.createAgent = createAgent2;
|
|
562
678
|
exports.createExpressHandler = createExpressHandler;
|
|
679
|
+
exports.defineKnowledgeBase = defineKnowledgeBase;
|
|
563
680
|
exports.defineProfile = defineProfile;
|
|
564
681
|
exports.defineScene = defineScene;
|
|
565
682
|
exports.defineToolKit = defineToolKit;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/profile.ts","../src/toolkit.ts","../src/scene.ts","../src/prompt.ts","../src/graph/single.ts","../src/graph/supervisor.ts","../src/sse.ts","../src/middleware.ts","../src/agent.ts"],"names":["ChatOpenAI","createAgent","createMiddleware","HumanMessage","createReactAgent","createSupervisor","AIMessageChunk","ToolMessage","MemorySaver"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { AgentProfile } from './types'\r\n\r\n/**\r\n * 定义一个 Agent 角色身份。\r\n *\r\n * 校验必填字段后返回不可变对象。\r\n *\r\n * @param input - 角色配置\r\n * @returns 冻结的 AgentProfile 对象\r\n *\r\n * @example\r\n * ```ts\r\n * const director = defineProfile({\r\n * name: '导演',\r\n * systemPrompt: '你是一位视频导演...',\r\n * model: 'gpt-4o',\r\n * })\r\n * ```\r\n */\r\nexport function defineProfile(input: AgentProfile): Readonly<AgentProfile> {\r\n if (!input.name) throw new Error('Profile name is required')\r\n if (!input.systemPrompt) throw new Error('Profile systemPrompt is required')\r\n if (!input.model) throw new Error('Profile model is required')\r\n return Object.freeze({ ...input })\r\n}\r\n\r\n","import type { ToolKit } from './types'\r\n\r\n/**\r\n * 定义一个静态能力包。\r\n *\r\n * 校验必填字段后返回不可变对象。\r\n *\r\n * @param input - 能力包配置\r\n * @returns 冻结的 ToolKit 对象\r\n *\r\n * @example\r\n * ```ts\r\n * const canvasToolKit = defineToolKit({\r\n * name: 'canvas',\r\n * tools: [bindElementTool, bindTrackTool],\r\n * prompt: '画面调整时优先使用 canvas 工具...',\r\n * })\r\n * ```\r\n */\r\nexport function defineToolKit(input: ToolKit): Readonly<ToolKit> {\r\n if (!input.name) throw new Error('ToolKit name is required')\r\n if (!input.tools?.length) throw new Error('ToolKit tools must not be empty')\r\n if (!input.prompt) throw new Error('ToolKit prompt is required')\r\n return Object.freeze({ ...input })\r\n}\r\n\r\n","import type { Scene } from './types'\r\n\r\n/**\r\n * 定义一个运行时场景。\r\n *\r\n * 校验必填字段后返回不可变对象。\r\n *\r\n * @param input - 场景配置\r\n * @returns 冻结的 Scene 对象\r\n *\r\n * @example\r\n * ```ts\r\n * const timelineScene = defineScene({\r\n * name: 'timeline-editing',\r\n * toolkits: ['canvas', 'ai'],\r\n * prompt: (ctx) => `视频时长: ${ctx.duration}秒`,\r\n * onToolEnd: (toolName, result) => {\r\n * if (toolName === 'bindTrack') refreshTimeline()\r\n * },\r\n * })\r\n * ```\r\n */\r\nexport function defineScene(input: Scene): Readonly<Scene> {\r\n if (!input.name) throw new Error('Scene name is required')\r\n if (!input.toolkits?.length) throw new Error('Scene toolkits must not be empty')\r\n if (typeof input.prompt !== 'function') throw new Error('Scene prompt must be a function')\r\n return Object.freeze({ ...input })\r\n}\r\n\r\n","import type { AgentProfile, Scene } from './types'\r\n\r\n/**\r\n * 库内置基础指令 — 通用行为约束与 Agent 行为模式。\r\n *\r\n * 作为 Prompt 4 层拼接的第 ① 层,所有 Agent 共享。\r\n *\r\n * 核心设计:引导 LLM 以 Agent(自主代理)模式运行,而非被动问答。\r\n * ReAct 循环已由 LangGraph 引擎内置,此 prompt 负责引导 LLM 的思维方式。\r\n */\r\nconst BASE_PROMPT = `You are an autonomous AI agent. You can reason, plan, and take actions using the tools available to you.\r\n\r\n## Core Behavior\r\n- When given a task, break it down into steps, then execute each step using the appropriate tools.\r\n- After each tool call, observe the result and decide the next action. Continue until the task is fully completed.\r\n- If no tools are needed, respond directly with your knowledge.\r\n- Never fabricate uncertain information. If you cannot complete a task, explain why honestly.\r\n\r\n## Rules\r\n- Respond in the same language as the user.\r\n- Follow tool parameter schemas strictly — do not invent or omit required fields.\r\n- When multiple tools are available, choose the most relevant one for the current step.`\r\n\r\n/**\r\n * 构建 4 层 Prompt 拼接链。\r\n *\r\n * ```\r\n * ① Base — 库内置固定指令(通用行为约束、防御性指令)\r\n * ② Profile — agent.systemPrompt(角色身份)\r\n * ③ ToolKit — 当前场景激活的 ToolKit.prompt(0~N 个)\r\n * ④ Scene — scene.prompt(sceneContext)(仅绑定 Scene 时)\r\n * ```\r\n *\r\n * 各层以 `\\n\\n` 拼接,合并为单条 SystemMessage 字符串。\r\n *\r\n * @param params - 拼接所需的各层数据\r\n * @returns 完整的 system prompt 字符串\r\n */\r\nexport function buildPromptChain(params: {\r\n /** 当前 Agent 角色 */\r\n profile: AgentProfile\r\n /** 当前场景激活的 ToolKit prompt 列表 */\r\n toolkitPrompts: string[]\r\n /** 运行时场景(可选) */\r\n scene?: Scene\r\n /** 传给 scene.prompt(ctx) 的动态数据(可选) */\r\n sceneContext?: Record<string, any>\r\n}): string {\r\n const layers: string[] = [\r\n // ① Base — 库内置固定指令\r\n BASE_PROMPT,\r\n // ② Profile — 角色身份提示词\r\n params.profile.systemPrompt,\r\n // ③ ToolKit — 当前场景激活的能力包提示词\r\n ...params.toolkitPrompts,\r\n ]\r\n\r\n // ④ Scene — 动态运行时上下文提示词\r\n if (params.scene) {\r\n try {\r\n const scenePrompt = params.scene.prompt(params.sceneContext ?? {})\r\n layers.push(scenePrompt)\r\n } catch (error) {\r\n // Scene.prompt() 异常不应阻断流程,记录错误并跳过该层\r\n console.error('[buildPromptChain] Scene.prompt() error:', error)\r\n layers.push(`[Scene context unavailable due to error: ${error instanceof Error ? error.message : String(error)}]`)\r\n }\r\n }\r\n\r\n return layers.filter(Boolean).join('\\n\\n')\r\n}\r\n\r\n","import { ChatOpenAI } from '@langchain/openai'\r\nimport { createAgent, createMiddleware } from 'langchain'\r\nimport { HumanMessage } from '@langchain/core/messages'\r\nimport type { StructuredToolInterface } from '@langchain/core/tools'\r\nimport type { BaseCheckpointSaver } from '@langchain/langgraph'\r\nimport type { BaseCallbackHandler } from '@langchain/core/callbacks/base'\r\nimport type { AgentOptions } from '../types'\r\n\r\n/**\r\n * 构建单 Agent 图并返回双模式流。\r\n *\r\n * 使用 `createAgent` 创建 ReAct Agent,\r\n * 通过 `streamMode: ['messages', 'updates']` 同时获取:\r\n * - 逐 token 的文本流(messages 模式)\r\n * - 节点级别的完整更新(updates 模式,用于工具调用结果)\r\n *\r\n * Callbacks 在 LLM 层和 graph.stream() 层双重透传,\r\n * 确保观测工具能追踪完整 Agent 执行链路。\r\n *\r\n * ## 错误处理策略\r\n *\r\n * - **LLM 初始化异常**:ChatOpenAI 构造函数会在无效配置时抛出异常(如无效 API Key),\r\n * 由调用方(agent.ts)的顶层 try-catch 捕获并转换为 `error` 事件\r\n * - **Checkpointer 异常**:LangGraph 内部处理 checkpointer 加载/保存失败,\r\n * 失败时会降级为无记忆模式继续执行,不会中断流\r\n * - **工具执行异常**:LangGraph 内置异常处理,工具失败时会将错误信息作为 ToolMessage 返回给 LLM,\r\n * 由 LLM 决定如何处理(重试、跳过或报告用户)\r\n * - **流式输出异常**:stream() 过程中的网络异常或 LLM API 异常会抛出,\r\n * 由调用方的 try-catch 捕获\r\n *\r\n * @param params - 图构建参数\r\n * @returns 双模式流的异步可迭代对象\r\n * @throws 当 LLM 初始化失败或 stream() 执行失败时抛出异常\r\n */\r\nexport async function buildSingleGraph(params: {\r\n /** 完整的 system prompt(4 层拼接后) */\r\n systemPrompt: string\r\n /** 当前场景激活的工具列表 */\r\n tools: StructuredToolInterface[]\r\n /** Agent 模型标识 */\r\n model: string\r\n /** 用户消息 */\r\n message: string\r\n /** 对话线程 ID */\r\n threadId: string\r\n /** LangGraph Checkpointer */\r\n checkpointer: BaseCheckpointSaver\r\n /** 滑动窗口大小 */\r\n maxMessages: number\r\n /** LangChain Callbacks */\r\n callbacks: BaseCallbackHandler[]\r\n /** 底层 LLM 网关配置(OpenAI 兼容) */\r\n llm?: AgentOptions['llm']\r\n}) {\r\n const hasCallbacks = params.callbacks.length > 0\r\n const callbacksOrUndefined = hasCallbacks ? params.callbacks : undefined\r\n\r\n // LLM 初始化 — 可能抛出异常(无效 API Key / baseURL)\r\n let llm: ChatOpenAI\r\n try {\r\n llm = new ChatOpenAI({\r\n model: params.model,\r\n apiKey: params.llm?.apiKey,\r\n configuration: params.llm?.baseURL ? { baseURL: params.llm.baseURL } : undefined,\r\n // LLM 层透传 callbacks — 追踪 LLM 调用本身\r\n callbacks: callbacksOrUndefined,\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSingleGraph] LLM initialization failed:', message)\r\n throw new Error(`Failed to initialize LLM: ${message}`)\r\n }\r\n\r\n console.log('[buildSingleGraph] systemPrompt:', JSON.stringify(params.systemPrompt))\r\n console.log('[buildSingleGraph] model:', params.model)\r\n console.log('[buildSingleGraph] tools:', params.tools.map(t => t.name))\r\n console.log('[buildSingleGraph] threadId:', params.threadId)\r\n console.log('[buildSingleGraph] maxMessages:', params.maxMessages)\r\n\r\n // 图构建 — 可能抛出异常(无效配置)\r\n let graph: ReturnType<typeof createAgent>\r\n try {\r\n graph = createAgent({\r\n model: llm,\r\n tools: params.tools,\r\n checkpointer: params.checkpointer,\r\n systemPrompt: params.systemPrompt,\r\n // 滑动窗口中间件 — beforeModel 阶段裁剪消息,Checkpointer 仍全量存储\r\n middleware: [\r\n createMiddleware({\r\n name: 'sliding-window',\r\n beforeModel: (state) => {\r\n try {\r\n const max = params.maxMessages\r\n if (!state.messages || state.messages.length <= max) return undefined\r\n return { messages: state.messages.slice(-max) }\r\n } catch (error) {\r\n // 中间件异常不应阻断流程,记录错误并返回原始 state\r\n console.error('[buildSingleGraph] sliding-window middleware error:', error)\r\n return undefined\r\n }\r\n },\r\n }),\r\n ],\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSingleGraph] Graph creation failed:', message)\r\n throw new Error(`Failed to create agent graph: ${message}`)\r\n }\r\n\r\n // stream() 调用 — 可能抛出异常(网络异常、LLM API 异常)\r\n try {\r\n return graph.stream(\r\n { messages: [new HumanMessage(params.message)] },\r\n {\r\n configurable: { thread_id: params.threadId },\r\n recursionLimit: 25,\r\n streamMode: ['messages', 'updates'],\r\n // graph 层透传 callbacks — 追踪完整执行链路(工具调用、节点跳转等)\r\n callbacks: callbacksOrUndefined,\r\n },\r\n )\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSingleGraph] Stream initialization failed:', message)\r\n throw new Error(`Failed to start agent stream: ${message}`)\r\n }\r\n}\r\n\r\n","import { ChatOpenAI } from '@langchain/openai'\r\nimport { createReactAgent } from '@langchain/langgraph/prebuilt'\r\nimport { createSupervisor } from '@langchain/langgraph-supervisor'\r\nimport { HumanMessage } from '@langchain/core/messages'\r\nimport type { StructuredToolInterface } from '@langchain/core/tools'\r\nimport type { BaseCheckpointSaver } from '@langchain/langgraph'\r\nimport type { BaseCallbackHandler } from '@langchain/core/callbacks/base'\r\nimport type { AgentProfile, AgentOptions } from '../types'\r\n\r\n/**\r\n * 构建多 Agent Supervisor 图并返回双模式流。\r\n *\r\n * 使用 `@langchain/langgraph-supervisor` 的 `createSupervisor` 构建:\r\n * - Supervisor 负责任务分析与分派\r\n * - Workers 为各 AgentProfile 对应的 ReAct Agent\r\n *\r\n * 工具在 Supervisor 级别不注入(Supervisor 只负责路由),\r\n * 所有工具注入到 Worker Agent 中,由 Scene 过滤后的工具集共享。\r\n *\r\n * ## 错误处理策略\r\n *\r\n * - **LLM 初始化异常**:任一 LLM(Supervisor / Worker)初始化失败时抛出异常,\r\n * 由调用方(agent.ts)的顶层 try-catch 捕获\r\n * - **Worker 创建异常**:单个 Worker 创建失败时记录错误并跳过该 Worker,\r\n * 至少保证 1 个 Worker 可用才继续执行\r\n * - **Checkpointer 异常**:同单 Agent 模式,LangGraph 内部降级处理\r\n * - **流式输出异常**:stream() 过程中的异常会抛出,由调用方捕获\r\n *\r\n * @param params - 图构建参数\r\n * @returns 双模式流的异步可迭代对象\r\n * @throws 当 LLM 初始化失败、Worker 全部创建失败或 stream() 执行失败时抛出异常\r\n */\r\nexport async function buildSupervisorGraph(params: {\r\n /** Supervisor 的 Prompt(4 层拼接后,用于 Supervisor Agent) */\r\n supervisorPrompt: string\r\n /** 所有 AgentProfile 列表 */\r\n agents: AgentProfile[]\r\n /** Supervisor 的 agent name */\r\n supervisorName: string\r\n /** 当前场景激活的工具列表(所有 Worker 共享) */\r\n tools: StructuredToolInterface[]\r\n /** 各 Worker 的 Prompt 映射(profile.name → 4 层拼接后的 prompt) */\r\n workerPrompts: Map<string, string>\r\n /** 用户消息 */\r\n message: string\r\n /** 对话线程 ID */\r\n threadId: string\r\n /** LangGraph Checkpointer */\r\n checkpointer: BaseCheckpointSaver\r\n /** 滑动窗口大小 */\r\n maxMessages: number\r\n /** LangChain Callbacks */\r\n callbacks: BaseCallbackHandler[]\r\n /** 底层 LLM 网关配置(OpenAI 兼容) */\r\n llm?: AgentOptions['llm']\r\n}) {\r\n const hasCallbacks = params.callbacks.length > 0\r\n const callbacksOrUndefined = hasCallbacks ? params.callbacks : undefined\r\n\r\n // 为每个非 Supervisor 的 Agent 创建 Worker\r\n const workerProfiles = params.agents.filter(profile => profile.name !== params.supervisorName)\r\n const workers: ReturnType<typeof createReactAgent>[] = []\r\n const failedWorkers: string[] = []\r\n\r\n for (const profile of workerProfiles) {\r\n try {\r\n const workerLLM = new ChatOpenAI({\r\n model: profile.model,\r\n apiKey: params.llm?.apiKey,\r\n configuration: params.llm?.baseURL ? { baseURL: params.llm.baseURL } : undefined,\r\n callbacks: callbacksOrUndefined,\r\n })\r\n\r\n const workerPrompt = params.workerPrompts.get(profile.name) ?? profile.systemPrompt\r\n\r\n const worker = createReactAgent({\r\n llm: workerLLM,\r\n tools: params.tools,\r\n name: profile.name,\r\n prompt: workerPrompt,\r\n })\r\n\r\n workers.push(worker)\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error(`[buildSupervisorGraph] Failed to create worker \"${profile.name}\":`, message)\r\n failedWorkers.push(profile.name)\r\n }\r\n }\r\n\r\n // 至少需要 1 个 Worker 才能继续\r\n if (workers.length === 0) {\r\n throw new Error(\r\n `Failed to create any workers. All ${workerProfiles.length} workers failed: ${failedWorkers.join(', ')}`,\r\n )\r\n }\r\n\r\n if (failedWorkers.length > 0) {\r\n console.warn(\r\n `[buildSupervisorGraph] ${failedWorkers.length} worker(s) failed to initialize: ${failedWorkers.join(', ')}`,\r\n )\r\n }\r\n\r\n // Supervisor 使用指定 profile 的 model\r\n const supervisorProfile = params.agents.find(p => p.name === params.supervisorName)!\r\n let supervisorLLM: ChatOpenAI\r\n try {\r\n supervisorLLM = new ChatOpenAI({\r\n model: supervisorProfile.model,\r\n apiKey: params.llm?.apiKey,\r\n configuration: params.llm?.baseURL ? { baseURL: params.llm.baseURL } : undefined,\r\n callbacks: callbacksOrUndefined,\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSupervisorGraph] Supervisor LLM initialization failed:', message)\r\n throw new Error(`Failed to initialize Supervisor LLM: ${message}`)\r\n }\r\n\r\n console.log('[buildSupervisorGraph] supervisor:', params.supervisorName)\r\n console.log('[buildSupervisorGraph] workers:', workers.map((_, i) => workerProfiles[i]?.name))\r\n console.log('[buildSupervisorGraph] tools:', params.tools.map(t => t.name))\r\n console.log('[buildSupervisorGraph] threadId:', params.threadId)\r\n\r\n // 创建 Supervisor 图\r\n let workflow: ReturnType<typeof createSupervisor>\r\n try {\r\n // 类型断言:createReactAgent 返回的 CompiledStateGraph 泛型参数\r\n // 与 createSupervisor 期望的类型存在 TS 层面的微小差异(BaseChannel vs BinaryOperatorAggregate),\r\n // 运行时完全兼容,此处用 as any 桥接\r\n workflow = createSupervisor({\r\n agents: workers as any,\r\n llm: supervisorLLM,\r\n prompt: params.supervisorPrompt,\r\n // 保留完整消息历史,让前端能追踪 handoff 过程\r\n outputMode: 'full_history',\r\n // 滑动窗口 — 只裁剪发给 LLM 的消息,Checkpointer 仍全量存储\r\n // 与 single.ts 的 createMiddleware.beforeModel 策略一致\r\n preModelHook: (state: any) => {\r\n try {\r\n const max = params.maxMessages\r\n if (!state.messages || state.messages.length <= max) {\r\n return { llmInputMessages: state.messages || [] }\r\n }\r\n return { llmInputMessages: state.messages.slice(-max) }\r\n } catch (error) {\r\n // 中间件异常不应阻断流程,记录错误并返回原始消息\r\n console.error('[buildSupervisorGraph] sliding-window preModelHook error:', error)\r\n return { llmInputMessages: state.messages || [] }\r\n }\r\n },\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSupervisorGraph] Supervisor workflow creation failed:', message)\r\n throw new Error(`Failed to create supervisor workflow: ${message}`)\r\n }\r\n\r\n // compile 时注入 checkpointer\r\n let graph: ReturnType<typeof workflow.compile>\r\n try {\r\n graph = workflow.compile({\r\n checkpointer: params.checkpointer,\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSupervisorGraph] Graph compilation failed:', message)\r\n throw new Error(`Failed to compile supervisor graph: ${message}`)\r\n }\r\n\r\n // stream() 调用 — 可能抛出异常(网络异常、LLM API 异常)\r\n try {\r\n return graph.stream(\r\n { messages: [new HumanMessage(params.message)] },\r\n {\r\n configurable: { thread_id: params.threadId },\r\n recursionLimit: 50, // 多 Agent 需要更高的递归限制\r\n streamMode: ['messages', 'updates'],\r\n callbacks: callbacksOrUndefined,\r\n },\r\n )\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSupervisorGraph] Stream initialization failed:', message)\r\n throw new Error(`Failed to start supervisor stream: ${message}`)\r\n }\r\n}\r\n\r\n","import { AIMessageChunk, ToolMessage } from '@langchain/core/messages'\r\nimport type { BaseMessage } from '@langchain/core/messages'\r\nimport type { SSEEvent } from './types'\r\n\r\n/**\r\n * 将 LangGraph `stream()` 的双模式流(messages + updates)\r\n * 转换为标准化 SSEEvent 序列。\r\n *\r\n * 事件映射逻辑:\r\n * - `messages` 模式的 AIMessageChunk(含 content)→ `text` 事件\r\n * - `messages` 模式的 AIMessageChunk(含 tool_call_chunks)→ `tool_start` 事件\r\n * - `updates` 模式的 tools 节点输出(ToolMessage)→ `tool_end` 事件\r\n * - `messages` 模式的 metadata.langgraph_node 变化 → `agent` + `handoff` 事件(多 Agent)\r\n *\r\n * ## 错误处理\r\n *\r\n * - **流迭代异常**:stream 本身抛出异常时(网络中断、LLM API 异常),\r\n * 由调用方(agent.ts)的 try-catch 捕获并转换为 `error` 事件\r\n * - **chunk 解析异常**:单个 chunk 解析失败时记录错误并跳过该 chunk,不中断流\r\n * - **生命周期回调异常**:onToolEnd 抛出异常时静默捕获,不影响流\r\n *\r\n * @param stream - LangGraph stream() 返回的异步可迭代对象\r\n * @param onToolEnd - Scene.onToolEnd 生命周期回调(可选)\r\n */\r\nexport async function* transformStream(\r\n stream: AsyncIterable<any>,\r\n onToolEnd?: (toolName: string, result: any) => void,\r\n): AsyncGenerator<SSEEvent> {\r\n // 追踪当前活跃的 agent name,用于检测 handoff\r\n let currentAgentName: string | null = null\r\n\r\n for await (const chunk of stream) {\r\n let events: SSEEvent[]\r\n let detectedAgent: string | null\r\n\r\n // 解析 chunk — 单个 chunk 解析失败不应中断流\r\n try {\r\n const result = parseStreamChunk(chunk, currentAgentName)\r\n events = result.events\r\n detectedAgent = result.detectedAgent\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[transformStream] Failed to parse chunk:', message, chunk)\r\n // 跳过该 chunk,继续处理后续流\r\n continue\r\n }\r\n\r\n // 如果检测到 agent 切换,先 emit handoff 和 agent 事件\r\n if (detectedAgent && detectedAgent !== currentAgentName) {\r\n if (currentAgentName) {\r\n yield { type: 'handoff', from: currentAgentName, to: detectedAgent }\r\n }\r\n yield { type: 'agent', name: detectedAgent }\r\n currentAgentName = detectedAgent\r\n }\r\n\r\n for (const event of events) {\r\n yield event\r\n\r\n // 触发 Scene.onToolEnd 生命周期回调\r\n if (event.type === 'tool_end' && onToolEnd) {\r\n try {\r\n onToolEnd(event.toolName, event.output)\r\n } catch (error) {\r\n // 生命周期回调异常不应影响流,记录错误并继续\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error(`[transformStream] Scene.onToolEnd(\"${event.toolName}\") error:`, message)\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n/** parseStreamChunk 的返回类型 */\r\ninterface ParseResult {\r\n events: SSEEvent[]\r\n /** 从 metadata 中检测到的 agent 名称(仅 messages 模式) */\r\n detectedAgent: string | null\r\n}\r\n\r\n/**\r\n * 解析单个 stream chunk 为 SSEEvent 数组 + agent 检测。\r\n *\r\n * LangGraph `stream({ streamMode: ['messages', 'updates'] })` 产出的 chunk 格式:\r\n * - messages 模式: `['messages', [message, metadata]]`\r\n * - metadata.langgraph_node 标识消息来源节点(即 agent name)\r\n * - updates 模式: `['updates', { nodeName: { messages: [...] } }]`\r\n */\r\nfunction parseStreamChunk(chunk: any, currentAgentName: string | null): ParseResult {\r\n const events: SSEEvent[] = []\r\n let detectedAgent: string | null = null\r\n\r\n // 双 streamMode 下,chunk 是 [streamMode, data] 元组\r\n if (!Array.isArray(chunk) || chunk.length !== 2) return { events, detectedAgent }\r\n\r\n const [mode, data] = chunk\r\n\r\n if (mode === 'messages') {\r\n // data = [message, metadata]\r\n const [message, metadata] = data as [BaseMessage, any]\r\n\r\n // 从 metadata 中提取 agent name(多 Agent 场景)\r\n // langgraph_node 标识当前消息来自哪个节点(supervisor / worker name)\r\n if (metadata?.langgraph_node && typeof metadata.langgraph_node === 'string') {\r\n const nodeName = metadata.langgraph_node as string\r\n // 过滤掉内部节点名(如 \"tools\"、\"__start__\" 等),只关注 agent 节点\r\n if (nodeName !== 'tools' && !nodeName.startsWith('__')) {\r\n // Supervisor 模式下,supervisor 节点名默认为 \"supervisor\"\r\n // Worker 节点名为 createReactAgent 时指定的 name\r\n detectedAgent = nodeName\r\n }\r\n }\r\n\r\n // messages 模式下实际产出 MessageChunk,但 TS 推断为 BaseMessage\r\n if (AIMessageChunk.isInstance(message)) {\r\n // 工具调用 chunk(tool_start 事件)\r\n if (message.tool_call_chunks && message.tool_call_chunks.length > 0) {\r\n for (const toolChunk of message.tool_call_chunks) {\r\n // 只在 name 出现时才 emit tool_start(第一个 chunk 包含 name)\r\n if (toolChunk.name) {\r\n events.push({\r\n type: 'tool_start',\r\n toolName: toolChunk.name,\r\n input: {},\r\n })\r\n }\r\n }\r\n }\r\n\r\n // 文本内容 chunk(text 事件)\r\n const content = typeof message.content === 'string' ? message.content : ''\r\n if (content) {\r\n events.push({ type: 'text', content })\r\n }\r\n }\r\n }\r\n\r\n if (mode === 'updates') {\r\n // data = { nodeName: { messages: [...] } | nodeOutput }\r\n if (data && typeof data === 'object') {\r\n const nodeData = data as Record<string, any>\r\n\r\n // 遍历所有节点输出,查找 ToolMessage\r\n for (const [nodeName, nodeOutput] of Object.entries(nodeData)) {\r\n // tools 节点的输出包含 ToolMessage\r\n // 单 Agent: nodeName === 'tools'\r\n // 多 Agent: nodeName 可能是 worker 内部的 tools 节点(如 '{agentName}_tools')\r\n if (nodeOutput?.messages) {\r\n const toolMessages = nodeOutput.messages as BaseMessage[]\r\n for (const msg of toolMessages) {\r\n if (msg instanceof ToolMessage) {\r\n events.push({\r\n type: 'tool_end',\r\n toolName: msg.name ?? 'unknown',\r\n output: safeParseJSON(\r\n typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content),\r\n ),\r\n })\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { events, detectedAgent }\r\n}\r\n\r\n/**\r\n * 安全解析 JSON 字符串,失败则返回原始字符串。\r\n */\r\nfunction safeParseJSON(str: string): any {\r\n try {\r\n return JSON.parse(str)\r\n } catch {\r\n return str\r\n }\r\n}\r\n\r\n// ─── SSE 格式化工具 ─────────────────────────────────────\r\n\r\n/**\r\n * 将 SSEEvent 格式化为 SSE 协议字符串 `data: JSON\\n\\n`。\r\n */\r\nexport function formatSSE(event: SSEEvent): string {\r\n return `data: ${JSON.stringify(event)}\\n\\n`\r\n}\r\n\r\n","import type { Request, RequestHandler, Response } from 'express'\r\nimport type { Agent } from './agent'\r\nimport { formatSSE } from './sse'\r\nimport type { ChatOptions, SSEEvent } from './types'\r\n\r\n/**\r\n * 写入 SSE 必要响应头。\r\n */\r\nfunction writeSSEHeaders(res: Response): void {\r\n res.status(200)\r\n res.setHeader('Content-Type', 'text/event-stream; charset=utf-8')\r\n res.setHeader('Cache-Control', 'no-cache, no-transform')\r\n res.setHeader('Connection', 'keep-alive')\r\n res.setHeader('X-Accel-Buffering', 'no')\r\n res.flushHeaders?.()\r\n}\r\n\r\n/**\r\n * 从请求体中提取 chat 参数。\r\n */\r\nfunction parseChatOptions(req: Request): ChatOptions {\r\n const body = (req.body ?? {}) as Partial<ChatOptions>\r\n return {\r\n message: typeof body.message === 'string' ? body.message : '',\r\n threadId: typeof body.threadId === 'string' ? body.threadId : '',\r\n sceneContext: body.sceneContext,\r\n }\r\n}\r\n\r\n/**\r\n * 为 Agent 创建 Express SSE 处理器。\r\n *\r\n * 请求体格式:\r\n * {\r\n * \"message\": \"...\",\r\n * \"threadId\": \"...\",\r\n * \"sceneContext\": { ... }\r\n * }\r\n *\r\n * ## 错误处理\r\n *\r\n * - **请求体解析异常**:parseChatOptions 失败时返回 `error` 事件\r\n * - **agent.chat() 异常**:流迭代过程中的异常会被捕获并转换为 `error` 事件\r\n * - **响应写入异常**:res.write() 失败时(客户端断开连接)静默捕获,避免服务器崩溃\r\n * - **所有异常路径**:确保最终都会发送 `done` 事件并关闭响应\r\n */\r\nexport function createExpressHandler(agent: Agent): RequestHandler {\r\n return async (req: Request, res: Response) => {\r\n // 写入 SSE 响应头\r\n try {\r\n writeSSEHeaders(res)\r\n } catch (error) {\r\n // 响应头写入失败(极少见),记录错误并尝试返回 500\r\n console.error('[createExpressHandler] Failed to write SSE headers:', error)\r\n if (!res.headersSent) {\r\n res.status(500).json({ error: 'Failed to initialize SSE stream' })\r\n }\r\n return\r\n }\r\n\r\n // 安全写入 SSE 事件 — 捕获客户端断开连接等异常\r\n const safeWrite = (event: SSEEvent): boolean => {\r\n try {\r\n return res.write(formatSSE(event))\r\n } catch (error) {\r\n // 客户端断开连接时 res.write() 会抛出异常,静默捕获\r\n console.error('[createExpressHandler] Failed to write SSE event:', error)\r\n return false\r\n }\r\n }\r\n\r\n try {\r\n const chatOptions = parseChatOptions(req)\r\n\r\n // 迭代 agent.chat() 流\r\n for await (const event of agent.chat(chatOptions)) {\r\n const success = safeWrite(event)\r\n // 如果写入失败(客户端断开),提前退出循环\r\n if (!success && event.type !== 'done') {\r\n console.warn('[createExpressHandler] Client disconnected, stopping stream')\r\n break\r\n }\r\n }\r\n } catch (error) {\r\n // agent.chat() 或流迭代异常\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[createExpressHandler] Stream error:', message)\r\n safeWrite({ type: 'error', message })\r\n safeWrite({ type: 'done' })\r\n } finally {\r\n // 确保响应最终关闭\r\n try {\r\n res.end()\r\n } catch (error) {\r\n // res.end() 失败(客户端已断开),静默捕获\r\n console.error('[createExpressHandler] Failed to end response:', error)\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { MemorySaver } from '@langchain/langgraph'\r\nimport type { BaseCheckpointSaver } from '@langchain/langgraph'\r\nimport type { BaseCallbackHandler } from '@langchain/core/callbacks/base'\r\nimport { buildPromptChain } from './prompt'\r\nimport { buildSingleGraph } from './graph/single'\r\nimport { buildSupervisorGraph } from './graph/supervisor'\r\nimport { transformStream } from './sse'\r\nimport { createExpressHandler } from './middleware'\r\nimport type { RequestHandler } from 'express'\r\nimport type { AgentOptions, ChatOptions, SSEEvent } from './types'\r\n\r\n/**\r\n * Agent 实例的内部已解析配置类型。\r\n *\r\n * 将可选字段填充为默认值后的完整配置。\r\n */\r\ninterface ResolvedOptions extends AgentOptions {\r\n maxMessages: number\r\n callbacks: BaseCallbackHandler[]\r\n checkpointer: BaseCheckpointSaver\r\n}\r\n\r\n/**\r\n * Agent 核心类。\r\n *\r\n * 串联完整流程:参数校验 → ToolKit 过滤 → Prompt 拼接 → 图构建 → 流式输出。\r\n *\r\n * 不直接 new,通过 `createAgent()` 工厂函数创建。\r\n */\r\nexport class Agent {\r\n /** @internal */\r\n readonly options: ResolvedOptions\r\n\r\n constructor(options: AgentOptions) {\r\n this.options = {\r\n maxMessages: 50,\r\n callbacks: [],\r\n checkpointer: new MemorySaver(),\r\n ...options,\r\n }\r\n this.validate()\r\n }\r\n\r\n /**\r\n * 发起对话,返回标准化 SSE 事件的异步生成器。\r\n *\r\n * 完整流程:\r\n * 1. ToolKit 过滤(Scene.toolkits 决定)\r\n * 2. Prompt 4 层拼接(Base → Profile → ToolKit → Scene)\r\n * 3. 构建 LangGraph 图 + stream\r\n * 4. 转换流事件 → 标准化 SSEEvent\r\n *\r\n * 任何异常均以 `error` + `done` 事件正常结束流,不崩溃。\r\n *\r\n * @param chatOptions - 对话参数\r\n * @yields 标准化 SSE 事件序列\r\n */\r\n async *chat(chatOptions: ChatOptions): AsyncGenerator<SSEEvent> {\r\n try {\r\n // 参数校验\r\n if (!chatOptions.message) {\r\n yield { type: 'error', message: 'message is required' }\r\n yield { type: 'done' }\r\n return\r\n }\r\n if (!chatOptions.threadId) {\r\n yield { type: 'error', message: 'threadId is required' }\r\n yield { type: 'done' }\r\n return\r\n }\r\n\r\n // 1. ToolKit 过滤 — Scene 决定当前可用的工具集\r\n const scene = this.options.scene\r\n const activeToolkits = scene\r\n ? this.options.toolkits.filter(tk => scene.toolkits.includes(tk.name))\r\n : this.options.toolkits\r\n const tools = activeToolkits.flatMap(tk => tk.tools)\r\n const toolkitPrompts = activeToolkits.map(tk => tk.prompt)\r\n\r\n // 2. 判断单/多 Agent 策略\r\n const isMultiAgent = this.options.agents.length > 1 && !!this.options.supervisor\r\n\r\n let stream: AsyncIterable<any>\r\n\r\n if (isMultiAgent) {\r\n // 多 Agent 模式:Supervisor + Workers\r\n const supervisorProfile = this.options.agents.find(\r\n a => a.name === this.options.supervisor,\r\n )!\r\n\r\n // Supervisor 的 prompt(4 层拼接)\r\n const supervisorPrompt = buildPromptChain({\r\n profile: supervisorProfile,\r\n toolkitPrompts,\r\n scene,\r\n sceneContext: chatOptions.sceneContext,\r\n })\r\n\r\n // 各 Worker 的 prompt(4 层拼接)\r\n const workerPrompts = new Map<string, string>()\r\n for (const profile of this.options.agents) {\r\n if (profile.name !== this.options.supervisor) {\r\n workerPrompts.set(\r\n profile.name,\r\n buildPromptChain({\r\n profile,\r\n toolkitPrompts,\r\n scene,\r\n sceneContext: chatOptions.sceneContext,\r\n }),\r\n )\r\n }\r\n }\r\n\r\n stream = await buildSupervisorGraph({\r\n supervisorPrompt,\r\n agents: this.options.agents,\r\n supervisorName: this.options.supervisor!,\r\n tools,\r\n workerPrompts,\r\n message: chatOptions.message,\r\n threadId: chatOptions.threadId,\r\n checkpointer: this.options.checkpointer,\r\n maxMessages: this.options.maxMessages,\r\n callbacks: this.options.callbacks,\r\n llm: this.options.llm,\r\n })\r\n } else {\r\n // 单 Agent 模式\r\n const profile = this.options.agents[0]\r\n const systemPrompt = buildPromptChain({\r\n profile,\r\n toolkitPrompts,\r\n scene,\r\n sceneContext: chatOptions.sceneContext,\r\n })\r\n\r\n stream = await buildSingleGraph({\r\n systemPrompt,\r\n tools,\r\n model: profile.model,\r\n message: chatOptions.message,\r\n threadId: chatOptions.threadId,\r\n checkpointer: this.options.checkpointer,\r\n maxMessages: this.options.maxMessages,\r\n callbacks: this.options.callbacks,\r\n llm: this.options.llm,\r\n })\r\n }\r\n\r\n // 4. 转换流事件 → 标准化 SSE 事件\r\n yield* transformStream(stream, scene?.onToolEnd)\r\n yield { type: 'done' }\r\n } catch (err) {\r\n const message = err instanceof Error\r\n ? `${err.message}${err.cause ? ` | cause: ${err.cause}` : ''}${err.stack ? `\\n${err.stack}` : ''}`\r\n : String(err)\r\n console.error('[agent.chat] error:', message)\r\n yield { type: 'error', message }\r\n yield { type: 'done' }\r\n }\r\n }\r\n\r\n /**\r\n * 返回 Express RequestHandler,直接用于路由挂载。\r\n *\r\n * @example\r\n * ```ts\r\n * app.post('/chat', agent.handleRequest())\r\n * ```\r\n */\r\n handleRequest(): RequestHandler {\r\n return createExpressHandler(this)\r\n }\r\n\r\n /**\r\n * 参数校验 — 在构造时执行,快速失败。\r\n */\r\n private validate(): void {\r\n if (!this.options.agents.length) {\r\n throw new Error('At least one agent is required')\r\n }\r\n if (this.options.supervisor) {\r\n const found = this.options.agents.find(a => a.name === this.options.supervisor)\r\n if (!found) {\r\n throw new Error(`Supervisor \"${this.options.supervisor}\" not found in agents`)\r\n }\r\n }\r\n // 校验 Scene 引用的 ToolKit 是否都已注册\r\n if (this.options.scene) {\r\n const registeredNames = new Set(this.options.toolkits.map(tk => tk.name))\r\n for (const name of this.options.scene.toolkits) {\r\n if (!registeredNames.has(name)) {\r\n throw new Error(`Scene references toolkit \"${name}\" which is not registered`)\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 创建 Agent 实例。\r\n *\r\n * @param options - Agent 配置项\r\n * @returns Agent 实例\r\n *\r\n * @example\r\n * ```ts\r\n * const agent = createAgent({\r\n * toolkits: [canvasToolKit],\r\n * agents: [director],\r\n * scene: timelineScene,\r\n * })\r\n *\r\n * for await (const event of agent.chat({ message: '你好', threadId: 'thread-001' })) {\r\n * console.log(event)\r\n * }\r\n * ```\r\n */\r\nexport function createAgent(options: AgentOptions): Agent {\r\n return new Agent(options)\r\n}\r\n\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/profile.ts","../src/toolkit.ts","../src/scene.ts","../src/knowledge.ts","../src/prompt.ts","../src/graph/single.ts","../src/graph/supervisor.ts","../src/sse.ts","../src/middleware.ts","../src/rag.ts","../src/agent.ts"],"names":["ChatOpenAI","createAgent","createMiddleware","HumanMessage","createReactAgent","createSupervisor","AIMessageChunk","ToolMessage","DynamicTool","MemorySaver"],"mappings":";;;;;;;;;;;AAmBO,SAAS,cAAc,KAAA,EAA6C;AACzE,EAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,0BAA0B,CAAA;AAC3D,EAAA,IAAI,CAAC,KAAA,CAAM,YAAA,EAAc,MAAM,IAAI,MAAM,kCAAkC,CAAA;AAC3E,EAAA,IAAI,CAAC,KAAA,CAAM,KAAA,EAAO,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAC7D,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,EAAE,GAAG,OAAO,CAAA;AACnC;;;ACLO,SAAS,cAAc,KAAA,EAAmC;AAC/D,EAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,0BAA0B,CAAA;AAC3D,EAAA,IAAI,CAAC,KAAA,CAAM,KAAA,EAAO,QAAQ,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAC3E,EAAA,IAAI,CAAC,KAAA,CAAM,MAAA,EAAQ,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAC/D,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,EAAE,GAAG,OAAO,CAAA;AACnC;;;ACFO,SAAS,YAAY,KAAA,EAA+B;AACzD,EAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,wBAAwB,CAAA;AACzD,EAAA,IAAI,CAAC,KAAA,CAAM,QAAA,EAAU,QAAQ,MAAM,IAAI,MAAM,kCAAkC,CAAA;AAC/E,EAAA,IAAI,OAAO,KAAA,CAAM,MAAA,KAAW,YAAY,MAAM,IAAI,MAAM,iCAAiC,CAAA;AACzF,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,EAAE,GAAG,OAAO,CAAA;AACnC;;;ACKO,SAAS,oBAAoB,KAAA,EAA+C;AACjF,EAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,gCAAgC,CAAA;AACjE,EAAA,IAAI,CAAC,KAAA,CAAM,WAAA,EAAa,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAE/E,EAAA,IAAI,CAAC,KAAA,CAAM,SAAA,EAAW,MAAM,IAAI,MAAM,qCAAqC,CAAA;AAC3E,EAAA,IAAI,OAAO,MAAM,SAAA,KAAc,UAAA,IAAc,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,SAAS,CAAA,EAAG;AAC5E,IAAA,MAAM,IAAI,MAAM,uEAAuE,CAAA;AAAA,EACzF;AACA,EAAA,IAAI,KAAA,CAAM,QAAQ,KAAA,CAAM,SAAS,KAAK,KAAA,CAAM,SAAA,CAAU,WAAW,CAAA,EAAG;AAClE,IAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAAA,EAC7D;AACA,EAAA,IAAI,KAAA,CAAM,SAAS,MAAA,KAAc,OAAO,MAAM,IAAA,KAAS,QAAA,IAAY,KAAA,CAAM,IAAA,GAAO,CAAA,CAAA,EAAI;AAClF,IAAA,MAAM,IAAI,MAAM,8CAA8C,CAAA;AAAA,EAChE;AACA,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,EAAE,GAAG,OAAO,CAAA;AACnC;;;ACrCA,IAAM,WAAA,GAAc,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,uFAAA,CAAA;AA4Bb,SAAS,iBAAiB,MAAA,EAStB;AACT,EAAA,MAAM,MAAA,GAAmB;AAAA;AAAA,IAEvB,WAAA;AAAA;AAAA,IAEA,OAAO,OAAA,CAAQ,YAAA;AAAA;AAAA,IAEf,GAAG,MAAA,CAAO;AAAA,GACZ;AAGA,EAAA,IAAI,OAAO,KAAA,EAAO;AAChB,IAAA,IAAI;AACF,MAAA,MAAM,cAAc,MAAA,CAAO,KAAA,CAAM,OAAO,MAAA,CAAO,YAAA,IAAgB,EAAE,CAAA;AACjE,MAAA,MAAA,CAAO,KAAK,WAAW,CAAA;AAAA,IACzB,SAAS,KAAA,EAAO;AAEd,MAAA,OAAA,CAAQ,KAAA,CAAM,4CAA4C,KAAK,CAAA;AAC/D,MAAA,MAAA,CAAO,IAAA,CAAK,4CAA4C,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,IACnH;AAAA,EACF;AAEA,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,MAAM,CAAA;AAC3C;ACpCA,eAAsB,iBAAiB,MAAA,EAmBpC;AACD,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,SAAA,CAAU,MAAA,GAAS,CAAA;AAC/C,EAAA,MAAM,oBAAA,GAAuB,YAAA,GAAe,MAAA,CAAO,SAAA,GAAY,MAAA;AAG/D,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAIA,iBAAA,CAAW;AAAA,MACnB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,MAAA,EAAQ,OAAO,GAAA,EAAK,MAAA;AAAA,MACpB,aAAA,EAAe,OAAO,GAAA,EAAK,OAAA,GAAU,EAAE,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,OAAA,EAAQ,GAAI,KAAA,CAAA;AAAA;AAAA,MAEvE,SAAA,EAAW;AAAA,KACZ,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,OAAA,CAAQ,KAAA,CAAM,iDAAiD,OAAO,CAAA;AACtE,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,OAAO,CAAA,CAAE,CAAA;AAAA,EACxD;AAEA,EAAA,OAAA,CAAQ,IAAI,kCAAA,EAAoC,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,YAAY,CAAC,CAAA;AACnF,EAAA,OAAA,CAAQ,GAAA,CAAI,2BAAA,EAA6B,MAAA,CAAO,KAAK,CAAA;AACrD,EAAA,OAAA,CAAQ,GAAA,CAAI,6BAA6B,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA;AACtE,EAAA,OAAA,CAAQ,GAAA,CAAI,8BAAA,EAAgC,MAAA,CAAO,QAAQ,CAAA;AAC3D,EAAA,OAAA,CAAQ,GAAA,CAAI,iCAAA,EAAmC,MAAA,CAAO,WAAW,CAAA;AAGjE,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI;AACF,IAAA,KAAA,GAAQC,qBAAA,CAAY;AAAA,MAClB,KAAA,EAAO,GAAA;AAAA,MACP,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,cAAc,MAAA,CAAO,YAAA;AAAA,MACrB,cAAc,MAAA,CAAO,YAAA;AAAA;AAAA,MAErB,UAAA,EAAY;AAAA,QACVC,0BAAA,CAAiB;AAAA,UACf,IAAA,EAAM,gBAAA;AAAA,UACN,WAAA,EAAa,CAAC,KAAA,KAAU;AACtB,YAAA,IAAI;AACF,cAAA,MAAM,MAAM,MAAA,CAAO,WAAA;AACnB,cAAA,IAAI,CAAC,KAAA,CAAM,QAAA,IAAY,MAAM,QAAA,CAAS,MAAA,IAAU,KAAK,OAAO,KAAA,CAAA;AAC5D,cAAA,OAAO,EAAE,QAAA,EAAU,KAAA,CAAM,SAAS,KAAA,CAAM,CAAC,GAAG,CAAA,EAAE;AAAA,YAChD,SAAS,KAAA,EAAO;AAEd,cAAA,OAAA,CAAQ,KAAA,CAAM,uDAAuD,KAAK,CAAA;AAC1E,cAAA,OAAO,KAAA,CAAA;AAAA,YACT;AAAA,UACF;AAAA,SACD;AAAA;AACH,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,OAAA,CAAQ,KAAA,CAAM,6CAA6C,OAAO,CAAA;AAClE,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,OAAO,CAAA,CAAE,CAAA;AAAA,EAC5D;AAGA,EAAA,IAAI;AACF,IAAA,OAAO,KAAA,CAAM,MAAA;AAAA,MACX,EAAE,UAAU,CAAC,IAAIC,sBAAa,MAAA,CAAO,OAAO,CAAC,CAAA,EAAE;AAAA,MAC/C;AAAA,QACE,YAAA,EAAc,EAAE,SAAA,EAAW,MAAA,CAAO,QAAA,EAAS;AAAA,QAC3C,cAAA,EAAgB,EAAA;AAAA,QAChB,UAAA,EAAY,CAAC,UAAA,EAAY,SAAS,CAAA;AAAA;AAAA,QAElC,SAAA,EAAW;AAAA;AACb,KACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,OAAA,CAAQ,KAAA,CAAM,oDAAoD,OAAO,CAAA;AACzE,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,OAAO,CAAA,CAAE,CAAA;AAAA,EAC5D;AACF;AChGA,eAAsB,qBAAqB,MAAA,EAuBxC;AACD,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,SAAA,CAAU,MAAA,GAAS,CAAA;AAC/C,EAAA,MAAM,oBAAA,GAAuB,YAAA,GAAe,MAAA,CAAO,SAAA,GAAY,MAAA;AAG/D,EAAA,MAAM,cAAA,GAAiB,OAAO,MAAA,CAAO,MAAA,CAAO,aAAW,OAAA,CAAQ,IAAA,KAAS,OAAO,cAAc,CAAA;AAC7F,EAAA,MAAM,UAAiD,EAAC;AACxD,EAAA,MAAM,gBAA0B,EAAC;AAEjC,EAAA,KAAA,MAAW,WAAW,cAAA,EAAgB;AACpC,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,IAAIH,iBAAAA,CAAW;AAAA,QAC/B,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,MAAA,EAAQ,OAAO,GAAA,EAAK,MAAA;AAAA,QACpB,aAAA,EAAe,OAAO,GAAA,EAAK,OAAA,GAAU,EAAE,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,OAAA,EAAQ,GAAI,KAAA,CAAA;AAAA,QACvE,SAAA,EAAW;AAAA,OACZ,CAAA;AAED,MAAA,MAAM,eAAe,MAAA,CAAO,aAAA,CAAc,IAAI,OAAA,CAAQ,IAAI,KAAK,OAAA,CAAQ,YAAA;AAEvE,MAAA,MAAM,SAASI,yBAAA,CAAiB;AAAA,QAC9B,GAAA,EAAK,SAAA;AAAA,QACL,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,MAAA,EAAQ;AAAA,OACT,CAAA;AAED,MAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA,IACrB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gDAAA,EAAmD,OAAA,CAAQ,IAAI,MAAM,OAAO,CAAA;AAC1F,MAAA,aAAA,CAAc,IAAA,CAAK,QAAQ,IAAI,CAAA;AAAA,IACjC;AAAA,EACF;AAGA,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,qCAAqC,cAAA,CAAe,MAAM,oBAAoB,aAAA,CAAc,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KACxG;AAAA,EACF;AAEA,EAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,0BAA0B,aAAA,CAAc,MAAM,oCAAoC,aAAA,CAAc,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KAC5G;AAAA,EACF;AAGA,EAAA,MAAM,iBAAA,GAAoB,OAAO,MAAA,CAAO,IAAA,CAAK,OAAK,CAAA,CAAE,IAAA,KAAS,OAAO,cAAc,CAAA;AAClF,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI;AACF,IAAA,aAAA,GAAgB,IAAIJ,iBAAAA,CAAW;AAAA,MAC7B,OAAO,iBAAA,CAAkB,KAAA;AAAA,MACzB,MAAA,EAAQ,OAAO,GAAA,EAAK,MAAA;AAAA,MACpB,aAAA,EAAe,OAAO,GAAA,EAAK,OAAA,GAAU,EAAE,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,OAAA,EAAQ,GAAI,KAAA,CAAA;AAAA,MACvE,SAAA,EAAW;AAAA,KACZ,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,OAAA,CAAQ,KAAA,CAAM,gEAAgE,OAAO,CAAA;AACrF,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qCAAA,EAAwC,OAAO,CAAA,CAAE,CAAA;AAAA,EACnE;AAEA,EAAA,OAAA,CAAQ,GAAA,CAAI,oCAAA,EAAsC,MAAA,CAAO,cAAc,CAAA;AACvE,EAAA,OAAA,CAAQ,GAAA,CAAI,iCAAA,EAAmC,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM,cAAA,CAAe,CAAC,CAAA,EAAG,IAAI,CAAC,CAAA;AAC7F,EAAA,OAAA,CAAQ,GAAA,CAAI,iCAAiC,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA;AAC1E,EAAA,OAAA,CAAQ,GAAA,CAAI,kCAAA,EAAoC,MAAA,CAAO,QAAQ,CAAA;AAG/D,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AAIF,IAAA,QAAA,GAAWK,oCAAA,CAAiB;AAAA,MAC1B,MAAA,EAAQ,OAAA;AAAA,MACR,GAAA,EAAK,aAAA;AAAA,MACL,QAAQ,MAAA,CAAO,gBAAA;AAAA;AAAA,MAEf,UAAA,EAAY,cAAA;AAAA;AAAA;AAAA,MAGZ,YAAA,EAAc,CAAC,KAAA,KAAe;AAC5B,QAAA,IAAI;AACF,UAAA,MAAM,MAAM,MAAA,CAAO,WAAA;AACnB,UAAA,IAAI,CAAC,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,QAAA,CAAS,UAAU,GAAA,EAAK;AACnD,YAAA,OAAO,EAAE,gBAAA,EAAkB,KAAA,CAAM,QAAA,IAAY,EAAC,EAAE;AAAA,UAClD;AACA,UAAA,OAAO,EAAE,gBAAA,EAAkB,KAAA,CAAM,SAAS,KAAA,CAAM,CAAC,GAAG,CAAA,EAAE;AAAA,QACxD,SAAS,KAAA,EAAO;AAEd,UAAA,OAAA,CAAQ,KAAA,CAAM,6DAA6D,KAAK,CAAA;AAChF,UAAA,OAAO,EAAE,gBAAA,EAAkB,KAAA,CAAM,QAAA,IAAY,EAAC,EAAE;AAAA,QAClD;AAAA,MACF;AAAA,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,OAAA,CAAQ,KAAA,CAAM,+DAA+D,OAAO,CAAA;AACpF,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sCAAA,EAAyC,OAAO,CAAA,CAAE,CAAA;AAAA,EACpE;AAGA,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI;AACF,IAAA,KAAA,GAAQ,SAAS,OAAA,CAAQ;AAAA,MACvB,cAAc,MAAA,CAAO;AAAA,KACtB,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,OAAA,CAAQ,KAAA,CAAM,oDAAoD,OAAO,CAAA;AACzE,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,oCAAA,EAAuC,OAAO,CAAA,CAAE,CAAA;AAAA,EAClE;AAGA,EAAA,IAAI;AACF,IAAA,OAAO,KAAA,CAAM,MAAA;AAAA,MACX,EAAE,UAAU,CAAC,IAAIF,sBAAa,MAAA,CAAO,OAAO,CAAC,CAAA,EAAE;AAAA,MAC/C;AAAA,QACE,YAAA,EAAc,EAAE,SAAA,EAAW,MAAA,CAAO,QAAA,EAAS;AAAA,QAC3C,cAAA,EAAgB,EAAA;AAAA;AAAA,QAChB,UAAA,EAAY,CAAC,UAAA,EAAY,SAAS,CAAA;AAAA,QAClC,SAAA,EAAW;AAAA;AACb,KACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,OAAA,CAAQ,KAAA,CAAM,wDAAwD,OAAO,CAAA;AAC7E,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mCAAA,EAAsC,OAAO,CAAA,CAAE,CAAA;AAAA,EACjE;AACF;AClKA,gBAAuB,eAAA,CACrB,QACA,SAAA,EAC0B;AAE1B,EAAA,IAAI,gBAAA,GAAkC,IAAA;AAEtC,EAAA,WAAA,MAAiB,SAAS,MAAA,EAAQ;AAChC,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,aAAA;AAGJ,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,KAAA,EAAO,gBAAgB,CAAA;AACvD,MAAA,MAAA,GAAS,MAAA,CAAO,MAAA;AAChB,MAAA,aAAA,GAAgB,MAAA,CAAO,aAAA;AAAA,IACzB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,MAAA,OAAA,CAAQ,KAAA,CAAM,0CAAA,EAA4C,OAAA,EAAS,KAAK,CAAA;AAExE,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,aAAA,IAAiB,kBAAkB,gBAAA,EAAkB;AACvD,MAAA,IAAI,gBAAA,EAAkB;AACpB,QAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,gBAAA,EAAkB,IAAI,aAAA,EAAc;AAAA,MACrE;AACA,MAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,aAAA,EAAc;AAC3C,MAAA,gBAAA,GAAmB,aAAA;AAAA,IACrB;AAEA,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,KAAA;AAGN,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,UAAA,IAAc,SAAA,EAAW;AAC1C,QAAA,IAAI;AACF,UAAA,SAAA,CAAU,KAAA,CAAM,QAAA,EAAU,KAAA,CAAM,MAAM,CAAA;AAAA,QACxC,SAAS,KAAA,EAAO;AAEd,UAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,mCAAA,EAAsC,KAAA,CAAM,QAAQ,aAAa,OAAO,CAAA;AAAA,QACxF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAiBA,SAAS,gBAAA,CAAiB,OAAY,gBAAA,EAA8C;AAClF,EAAA,MAAM,SAAqB,EAAC;AAC5B,EAAA,IAAI,aAAA,GAA+B,IAAA;AAGnC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,EAAE,MAAA,EAAQ,aAAA,EAAc;AAEhF,EAAA,MAAM,CAAC,IAAA,EAAM,IAAI,CAAA,GAAI,KAAA;AAErB,EAAA,IAAI,SAAS,UAAA,EAAY;AAEvB,IAAA,MAAM,CAAC,OAAA,EAAS,QAAQ,CAAA,GAAI,IAAA;AAI5B,IAAA,IAAI,QAAA,EAAU,cAAA,IAAkB,OAAO,QAAA,CAAS,mBAAmB,QAAA,EAAU;AAC3E,MAAA,MAAM,WAAW,QAAA,CAAS,cAAA;AAE1B,MAAA,IAAI,aAAa,OAAA,IAAW,CAAC,QAAA,CAAS,UAAA,CAAW,IAAI,CAAA,EAAG;AAGtD,QAAA,aAAA,GAAgB,QAAA;AAAA,MAClB;AAAA,IACF;AAGA,IAAA,IAAIG,uBAAA,CAAe,UAAA,CAAW,OAAO,CAAA,EAAG;AAEtC,MAAA,IAAI,OAAA,CAAQ,gBAAA,IAAoB,OAAA,CAAQ,gBAAA,CAAiB,SAAS,CAAA,EAAG;AACnE,QAAA,KAAA,MAAW,SAAA,IAAa,QAAQ,gBAAA,EAAkB;AAEhD,UAAA,IAAI,UAAU,IAAA,EAAM;AAClB,YAAA,MAAA,CAAO,IAAA,CAAK;AAAA,cACV,IAAA,EAAM,YAAA;AAAA,cACN,UAAU,SAAA,CAAU,IAAA;AAAA,cACpB,OAAO;AAAC,aACT,CAAA;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAGA,MAAA,MAAM,UAAU,OAAO,OAAA,CAAQ,OAAA,KAAY,QAAA,GAAW,QAAQ,OAAA,GAAU,EAAA;AACxE,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,CAAA;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,SAAS,SAAA,EAAW;AAEtB,IAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACpC,MAAA,MAAM,QAAA,GAAW,IAAA;AAGjB,MAAA,KAAA,MAAW,CAAC,QAAA,EAAU,UAAU,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAI7D,QAAA,IAAI,YAAY,QAAA,EAAU;AACxB,UAAA,MAAM,eAAe,UAAA,CAAW,QAAA;AAChC,UAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,YAAA,IAAI,eAAeC,oBAAA,EAAa;AAC9B,cAAA,MAAA,CAAO,IAAA,CAAK;AAAA,gBACV,IAAA,EAAM,UAAA;AAAA,gBACN,QAAA,EAAU,IAAI,IAAA,IAAQ,SAAA;AAAA,gBACtB,MAAA,EAAQ,aAAA;AAAA,kBACN,OAAO,IAAI,OAAA,KAAY,QAAA,GAAW,IAAI,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO;AAAA;AAC5E,eACD,CAAA;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,QAAQ,aAAA,EAAc;AACjC;AAKA,SAAS,cAAc,GAAA,EAAkB;AACvC,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EACvB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,GAAA;AAAA,EACT;AACF;AAOO,SAAS,UAAU,KAAA,EAAyB;AACjD,EAAA,OAAO,CAAA,MAAA,EAAS,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC;;AAAA,CAAA;AACvC;;;AClLA,SAAS,gBAAgB,GAAA,EAAqB;AAC5C,EAAA,GAAA,CAAI,OAAO,GAAG,CAAA;AACd,EAAA,GAAA,CAAI,SAAA,CAAU,gBAAgB,kCAAkC,CAAA;AAChE,EAAA,GAAA,CAAI,SAAA,CAAU,iBAAiB,wBAAwB,CAAA;AACvD,EAAA,GAAA,CAAI,SAAA,CAAU,cAAc,YAAY,CAAA;AACxC,EAAA,GAAA,CAAI,SAAA,CAAU,qBAAqB,IAAI,CAAA;AACvC,EAAA,GAAA,CAAI,YAAA,IAAe;AACrB;AAKA,SAAS,iBAAiB,GAAA,EAA2B;AACnD,EAAA,MAAM,IAAA,GAAQ,GAAA,CAAI,IAAA,IAAQ,EAAC;AAC3B,EAAA,OAAO;AAAA,IACL,SAAS,OAAO,IAAA,CAAK,OAAA,KAAY,QAAA,GAAW,KAAK,OAAA,GAAU,EAAA;AAAA,IAC3D,UAAU,OAAO,IAAA,CAAK,QAAA,KAAa,QAAA,GAAW,KAAK,QAAA,GAAW,EAAA;AAAA,IAC9D,cAAc,IAAA,CAAK;AAAA,GACrB;AACF;AAmBO,SAAS,qBAAqB,KAAA,EAA8B;AACjE,EAAA,OAAO,OAAO,KAAc,GAAA,KAAkB;AAE5C,IAAA,IAAI;AACF,MAAA,eAAA,CAAgB,GAAG,CAAA;AAAA,IACrB,SAAS,KAAA,EAAO;AAEd,MAAA,OAAA,CAAQ,KAAA,CAAM,uDAAuD,KAAK,CAAA;AAC1E,MAAA,IAAI,CAAC,IAAI,WAAA,EAAa;AACpB,QAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,mCAAmC,CAAA;AAAA,MACnE;AACA,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KAA6B;AAC9C,MAAA,IAAI;AACF,QAAA,OAAO,GAAA,CAAI,KAAA,CAAM,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,MACnC,SAAS,KAAA,EAAO;AAEd,QAAA,OAAA,CAAQ,KAAA,CAAM,qDAAqD,KAAK,CAAA;AACxE,QAAA,OAAO,KAAA;AAAA,MACT;AAAA,IACF,CAAA;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,iBAAiB,GAAG,CAAA;AAGxC,MAAA,WAAA,MAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,CAAK,WAAW,CAAA,EAAG;AACjD,QAAA,MAAM,OAAA,GAAU,UAAU,KAAK,CAAA;AAE/B,QAAA,IAAI,CAAC,OAAA,IAAW,KAAA,CAAM,IAAA,KAAS,MAAA,EAAQ;AACrC,UAAA,OAAA,CAAQ,KAAK,6DAA6D,CAAA;AAC1E,UAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AAEd,MAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,MAAA,OAAA,CAAQ,KAAA,CAAM,wCAAwC,OAAO,CAAA;AAC7D,MAAA,SAAA,CAAU,EAAE,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,CAAA;AACpC,MAAA,SAAA,CAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAA;AAAA,IAC5B,CAAA,SAAE;AAEA,MAAA,IAAI;AACF,QAAA,GAAA,CAAI,GAAA,EAAI;AAAA,MACV,SAAS,KAAA,EAAO;AAEd,QAAA,OAAA,CAAQ,KAAA,CAAM,kDAAkD,KAAK,CAAA;AAAA,MACvE;AAAA,IACF;AAAA,EACF,CAAA;AACF;ACpEA,SAAS,gBAAA,CAAiB,GAAa,CAAA,EAAqB;AAC1D,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,GAAA,IAAO,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA;AACjB,IAAA,KAAA,IAAS,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA;AACnB,IAAA,KAAA,IAAS,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA;AAAA,EACrB;AACA,EAAA,MAAM,QAAQ,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA,GAAI,IAAA,CAAK,KAAK,KAAK,CAAA;AAChD,EAAA,OAAO,KAAA,KAAU,CAAA,GAAI,CAAA,GAAI,GAAA,GAAM,KAAA;AACjC;AAeA,eAAsB,gBAAA,CACpB,gBACA,UAAA,EACwB;AACxB,EAAA,MAAM,SAAwB,EAAC;AAE/B,EAAA,KAAA,MAAW,MAAM,cAAA,EAAgB;AAC/B,IAAA,IAAI;AAEF,MAAA,MAAM,IAAA,GAAO,OAAO,EAAA,CAAG,SAAA,KAAc,aACjC,MAAM,EAAA,CAAG,SAAA,EAAU,GACnB,EAAA,CAAG,SAAA;AAEP,MAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,QAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,oBAAA,EAAuB,EAAA,CAAG,IAAI,CAAA,4BAAA,CAA8B,CAAA;AACzE,QAAA;AAAA,MACF;AAEA,MAAA,OAAA,CAAQ,IAAI,CAAA,8BAAA,EAAiC,EAAA,CAAG,IAAI,CAAA,GAAA,EAAM,IAAA,CAAK,MAAM,CAAA,cAAA,CAAgB,CAAA;AACrF,MAAA,MAAM,OAAA,GAAU,MAAM,UAAA,CAAW,cAAA,CAAe,IAAI,CAAA;AAEpD,MAAA,MAAM,OAAA,GAA0B,IAAA,CAAK,GAAA,CAAI,CAAC,MAAM,CAAA,MAAO;AAAA,QACrD,IAAA;AAAA,QACA,MAAA,EAAQ,QAAQ,CAAC;AAAA,OACnB,CAAE,CAAA;AAEF,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,EAAA,EAAI,OAAA,EAAS,CAAA;AAC3B,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,oBAAA,EAAuB,EAAA,CAAG,IAAI,CAAA,SAAA,EAAY,OAAA,CAAQ,MAAM,CAAA,cAAA,EAAiB,OAAA,CAAQ,CAAC,CAAA,EAAG,MAAA,IAAU,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,IACjH,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,oCAAA,EAAuC,EAAA,CAAG,IAAI,MAAM,OAAO,CAAA;AACzE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qCAAA,EAAwC,GAAG,IAAI,CAAA,GAAA,EAAM,OAAO,CAAA,CAAE,CAAA;AAAA,IAChF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAeA,eAAe,iBAAA,CACb,KAAA,EACA,KAAA,EACA,UAAA,EACmB;AACnB,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,EAAA,CAAG,IAAA,IAAQ,CAAA;AAC9B,EAAA,MAAM,WAAA,GAAc,MAAM,UAAA,CAAW,UAAA,CAAW,KAAK,CAAA;AAGrD,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,CAAA,MAAA,MAAW;AAAA,IAC1C,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,KAAA,EAAO,gBAAA,CAAiB,WAAA,EAAa,MAAA,CAAO,MAAM;AAAA,GACpD,CAAE,CAAA;AAGF,EAAA,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AACvC,EAAA,OAAO,MAAA,CAAO,MAAM,CAAA,EAAG,IAAI,EAAE,GAAA,CAAI,CAAA,IAAA,KAAQ,KAAK,IAAI,CAAA;AACpD;AAgBO,SAAS,mBAAA,CACd,QACA,UAAA,EACe;AACf,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAA,KAAA,KAAS,IAAIC,iBAAA,CAAY;AAAA,IACzC,IAAA,EAAM,MAAM,EAAA,CAAG,IAAA;AAAA,IACf,WAAA,EAAa,MAAM,EAAA,CAAG,WAAA;AAAA,IACtB,IAAA,EAAM,OAAO,KAAA,KAAkB;AAC7B,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAU,MAAM,iBAAA,CAAkB,KAAA,EAAO,OAAO,UAAU,CAAA;AAChE,QAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,UAAA,OAAO,gCAAA;AAAA,QACT;AACA,QAAA,OAAO,OAAA,CAAQ,KAAK,aAAa,CAAA;AAAA,MACnC,SAAS,KAAA,EAAO;AACd,QAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,QAAA,OAAA,CAAQ,MAAM,CAAA,yCAAA,EAA4C,KAAA,CAAM,EAAA,CAAG,IAAI,MAAM,OAAO,CAAA;AACpF,QAAA,OAAO,kBAAkB,OAAO,CAAA,CAAA;AAAA,MAClC;AAAA,IACF;AAAA,GACD,CAAC,CAAA;AACJ;;;ACnIO,IAAM,QAAN,MAAY;AAAA;AAAA,EAER,OAAA;AAAA;AAAA,EAGD,iBAAgC,EAAC;AAAA;AAAA,EAGjC,YAAA;AAAA,EAER,YAAY,OAAA,EAAuB;AACjC,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,WAAA,EAAa,EAAA;AAAA,MACb,WAAW,EAAC;AAAA,MACZ,YAAA,EAAc,IAAIC,qBAAA,EAAY;AAAA,MAC9B,GAAG;AAAA,KACL;AACA,IAAA,IAAA,CAAK,QAAA,EAAS;AACd,IAAA,IAAA,CAAK,YAAA,GAAe,KAAK,IAAA,EAAK;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,IAAA,GAAsB;AAClC,IAAA,MAAM,EAAE,cAAA,EAAgB,UAAA,EAAW,GAAI,IAAA,CAAK,OAAA;AAC5C,IAAA,IAAI,CAAC,cAAA,EAAgB,MAAA,IAAU,CAAC,UAAA,EAAY;AAE5C,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,gBAAA,CAAiB,cAAA,EAAgB,UAAU,CAAA;AAChE,MAAA,IAAA,CAAK,cAAA,GAAiB,mBAAA,CAAoB,MAAA,EAAQ,UAAU,CAAA;AAC5D,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,QAAA,EAAW,IAAA,CAAK,cAAA,CAAe,MAAM,CAAA,wBAAA,CAA0B,CAAA;AAAA,IAC7E,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,MAAA,OAAA,CAAQ,KAAA,CAAM,iDAAiD,OAAO,CAAA;AACtE,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,OAAO,KAAK,WAAA,EAAoD;AAC9D,IAAA,IAAI;AAEF,MAAA,MAAM,IAAA,CAAK,YAAA;AAGX,MAAA,IAAI,CAAC,YAAY,OAAA,EAAS;AACxB,QAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,qBAAA,EAAsB;AACtD,QAAA,MAAM,EAAE,MAAM,MAAA,EAAO;AACrB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,CAAC,YAAY,QAAA,EAAU;AACzB,QAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,sBAAA,EAAuB;AACvD,QAAA,MAAM,EAAE,MAAM,MAAA,EAAO;AACrB,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,KAAA,GAAQ,KAAK,OAAA,CAAQ,KAAA;AAC3B,MAAA,MAAM,cAAA,GAAiB,KAAA,GACnB,IAAA,CAAK,OAAA,CAAQ,SAAS,MAAA,CAAO,CAAA,EAAA,KAAM,KAAA,CAAM,QAAA,CAAS,SAAS,EAAA,CAAG,IAAI,CAAC,CAAA,GACnE,KAAK,OAAA,CAAQ,QAAA;AACjB,MAAA,MAAM,KAAA,GAAQ;AAAA,QACZ,GAAG,cAAA,CAAe,OAAA,CAAQ,CAAA,EAAA,KAAM,GAAG,KAAK,CAAA;AAAA,QACxC,GAAG,IAAA,CAAK;AAAA;AAAA,OACV;AACA,MAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,GAAA,CAAI,CAAA,EAAA,KAAM,GAAG,MAAM,CAAA;AAGzD,MAAA,MAAM,YAAA,GAAe,KAAK,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,IAAK,CAAC,CAAC,IAAA,CAAK,OAAA,CAAQ,UAAA;AAEtE,MAAA,IAAI,MAAA;AAEJ,MAAA,IAAI,YAAA,EAAc;AAEhB,QAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,IAAA;AAAA,UAC5C,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,KAAS,IAAA,CAAK,OAAA,CAAQ;AAAA,SAC/B;AAGA,QAAA,MAAM,mBAAmB,gBAAA,CAAiB;AAAA,UACxC,OAAA,EAAS,iBAAA;AAAA,UACT,cAAA;AAAA,UACA,KAAA;AAAA,UACA,cAAc,WAAA,CAAY;AAAA,SAC3B,CAAA;AAGD,QAAA,MAAM,aAAA,uBAAoB,GAAA,EAAoB;AAC9C,QAAA,KAAA,MAAW,OAAA,IAAW,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ;AACzC,UAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY;AAC5C,YAAA,aAAA,CAAc,GAAA;AAAA,cACZ,OAAA,CAAQ,IAAA;AAAA,cACR,gBAAA,CAAiB;AAAA,gBACf,OAAA;AAAA,gBACA,cAAA;AAAA,gBACA,KAAA;AAAA,gBACA,cAAc,WAAA,CAAY;AAAA,eAC3B;AAAA,aACH;AAAA,UACF;AAAA,QACF;AAEA,QAAA,MAAA,GAAS,MAAM,oBAAA,CAAqB;AAAA,UAClC,gBAAA;AAAA,UACA,MAAA,EAAQ,KAAK,OAAA,CAAQ,MAAA;AAAA,UACrB,cAAA,EAAgB,KAAK,OAAA,CAAQ,UAAA;AAAA,UAC7B,KAAA;AAAA,UACA,aAAA;AAAA,UACA,SAAS,WAAA,CAAY,OAAA;AAAA,UACrB,UAAU,WAAA,CAAY,QAAA;AAAA,UACtB,YAAA,EAAc,KAAK,OAAA,CAAQ,YAAA;AAAA,UAC3B,WAAA,EAAa,KAAK,OAAA,CAAQ,WAAA;AAAA,UAC1B,SAAA,EAAW,KAAK,OAAA,CAAQ,SAAA;AAAA,UACxB,GAAA,EAAK,KAAK,OAAA,CAAQ;AAAA,SACnB,CAAA;AAAA,MACH,CAAA,MAAO;AAEL,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA;AACrC,QAAA,MAAM,eAAe,gBAAA,CAAiB;AAAA,UACpC,OAAA;AAAA,UACA,cAAA;AAAA,UACA,KAAA;AAAA,UACA,cAAc,WAAA,CAAY;AAAA,SAC3B,CAAA;AAED,QAAA,MAAA,GAAS,MAAM,gBAAA,CAAiB;AAAA,UAC9B,YAAA;AAAA,UACA,KAAA;AAAA,UACA,OAAO,OAAA,CAAQ,KAAA;AAAA,UACf,SAAS,WAAA,CAAY,OAAA;AAAA,UACrB,UAAU,WAAA,CAAY,QAAA;AAAA,UACtB,YAAA,EAAc,KAAK,OAAA,CAAQ,YAAA;AAAA,UAC3B,WAAA,EAAa,KAAK,OAAA,CAAQ,WAAA;AAAA,UAC1B,SAAA,EAAW,KAAK,OAAA,CAAQ,SAAA;AAAA,UACxB,GAAA,EAAK,KAAK,OAAA,CAAQ;AAAA,SACnB,CAAA;AAAA,MACH;AAGA,MAAA,OAAO,eAAA,CAAgB,MAAA,EAAQ,KAAA,EAAO,SAAS,CAAA;AAC/C,MAAA,MAAM,EAAE,MAAM,MAAA,EAAO;AAAA,IACvB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAC3B,CAAA,EAAG,GAAA,CAAI,OAAO,CAAA,EAAG,GAAA,CAAI,KAAA,GAAQ,CAAA,UAAA,EAAa,IAAI,KAAK,CAAA,CAAA,GAAK,EAAE,CAAA,EAAG,IAAI,KAAA,GAAQ;AAAA,EAAK,IAAI,KAAK,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA,GAC9F,OAAO,GAAG,CAAA;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,uBAAuB,OAAO,CAAA;AAC5C,MAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,OAAA,EAAQ;AAC/B,MAAA,MAAM,EAAE,MAAM,MAAA,EAAO;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,aAAA,GAAgC;AAC9B,IAAA,OAAO,qBAAqB,IAAI,CAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKQ,QAAA,GAAiB;AACvB,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAQ;AAC/B,MAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,IAClD;AACA,IAAA,IAAI,IAAA,CAAK,QAAQ,UAAA,EAAY;AAC3B,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,OAAK,CAAA,CAAE,IAAA,KAAS,IAAA,CAAK,OAAA,CAAQ,UAAU,CAAA;AAC9E,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,YAAA,EAAe,IAAA,CAAK,OAAA,CAAQ,UAAU,CAAA,qBAAA,CAAuB,CAAA;AAAA,MAC/E;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,MAAM,eAAA,GAAkB,IAAI,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,SAAS,GAAA,CAAI,CAAA,EAAA,KAAM,EAAA,CAAG,IAAI,CAAC,CAAA;AACxE,MAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,QAAA,EAAU;AAC9C,QAAA,IAAI,CAAC,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA,EAAG;AAC9B,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,IAAI,CAAA,yBAAA,CAA2B,CAAA;AAAA,QAC9E;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,KAAK,OAAA,CAAQ,cAAA,EAAgB,UAAU,CAAC,IAAA,CAAK,QAAQ,UAAA,EAAY;AACnE,MAAA,MAAM,IAAI,MAAM,wDAAwD,CAAA;AAAA,IAC1E;AAAA,EACF;AACF;AAqBO,SAASR,aAAY,OAAA,EAA8B;AACxD,EAAA,OAAO,IAAI,MAAM,OAAO,CAAA;AAC1B","file":"index.cjs","sourcesContent":["import type { AgentProfile } from './types'\r\n\r\n/**\r\n * 定义一个 Agent 角色身份。\r\n *\r\n * 校验必填字段后返回不可变对象。\r\n *\r\n * @param input - 角色配置\r\n * @returns 冻结的 AgentProfile 对象\r\n *\r\n * @example\r\n * ```ts\r\n * const director = defineProfile({\r\n * name: '导演',\r\n * systemPrompt: '你是一位视频导演...',\r\n * model: 'gpt-4o',\r\n * })\r\n * ```\r\n */\r\nexport function defineProfile(input: AgentProfile): Readonly<AgentProfile> {\r\n if (!input.name) throw new Error('Profile name is required')\r\n if (!input.systemPrompt) throw new Error('Profile systemPrompt is required')\r\n if (!input.model) throw new Error('Profile model is required')\r\n return Object.freeze({ ...input })\r\n}\r\n\r\n","import type { ToolKit } from './types'\r\n\r\n/**\r\n * 定义一个静态能力包。\r\n *\r\n * 校验必填字段后返回不可变对象。\r\n *\r\n * @param input - 能力包配置\r\n * @returns 冻结的 ToolKit 对象\r\n *\r\n * @example\r\n * ```ts\r\n * const canvasToolKit = defineToolKit({\r\n * name: 'canvas',\r\n * tools: [bindElementTool, bindTrackTool],\r\n * prompt: '画面调整时优先使用 canvas 工具...',\r\n * })\r\n * ```\r\n */\r\nexport function defineToolKit(input: ToolKit): Readonly<ToolKit> {\r\n if (!input.name) throw new Error('ToolKit name is required')\r\n if (!input.tools?.length) throw new Error('ToolKit tools must not be empty')\r\n if (!input.prompt) throw new Error('ToolKit prompt is required')\r\n return Object.freeze({ ...input })\r\n}\r\n\r\n","import type { Scene } from './types'\r\n\r\n/**\r\n * 定义一个运行时场景。\r\n *\r\n * 校验必填字段后返回不可变对象。\r\n *\r\n * @param input - 场景配置\r\n * @returns 冻结的 Scene 对象\r\n *\r\n * @example\r\n * ```ts\r\n * const timelineScene = defineScene({\r\n * name: 'timeline-editing',\r\n * toolkits: ['canvas', 'ai'],\r\n * prompt: (ctx) => `视频时长: ${ctx.duration}秒`,\r\n * onToolEnd: (toolName, result) => {\r\n * if (toolName === 'bindTrack') refreshTimeline()\r\n * },\r\n * })\r\n * ```\r\n */\r\nexport function defineScene(input: Scene): Readonly<Scene> {\r\n if (!input.name) throw new Error('Scene name is required')\r\n if (!input.toolkits?.length) throw new Error('Scene toolkits must not be empty')\r\n if (typeof input.prompt !== 'function') throw new Error('Scene prompt must be a function')\r\n return Object.freeze({ ...input })\r\n}\r\n\r\n","import type { KnowledgeBase } from './types'\n\n/**\n * 定义一个知识库。\n *\n * 校验必填字段后返回不可变对象。\n * 库内部自动将文本向量化并包装为 LangChain Tool,AI 根据 `description` 自主决定何时检索。\n *\n * @param input - 知识库配置\n * @returns 冻结的 KnowledgeBase 对象\n *\n * @example\n * ```ts\n * // 静态文本\n * const faqKB = defineKnowledgeBase({\n * name: 'faq',\n * description: '产品常见问题,当用户问功能、价格、退款等问题时检索',\n * documents: ['7天内无理由退款', '基础版99元/月', '支持微信支付宝付款'],\n * topK: 3,\n * })\n *\n * // 从数据库/API 动态加载\n * const dynamicKB = defineKnowledgeBase({\n * name: 'dynamic-docs',\n * description: '从数据库动态加载的文档',\n * documents: async () => {\n * const res = await fetch('/api/docs')\n * return res.json()\n * },\n * })\n * ```\n */\nexport function defineKnowledgeBase(input: KnowledgeBase): Readonly<KnowledgeBase> {\n if (!input.name) throw new Error('KnowledgeBase name is required')\n if (!input.description) throw new Error('KnowledgeBase description is required')\n // documents 可以是 string[] 或 () => Promise<string[]>\n if (!input.documents) throw new Error('KnowledgeBase documents is required')\n if (typeof input.documents !== 'function' && !Array.isArray(input.documents)) {\n throw new Error('KnowledgeBase documents must be a string[] or () => Promise<string[]>')\n }\n if (Array.isArray(input.documents) && input.documents.length === 0) {\n throw new Error('KnowledgeBase documents must not be empty')\n }\n if (input.topK !== undefined && (typeof input.topK !== 'number' || input.topK < 1)) {\n throw new Error('KnowledgeBase topK must be a positive number')\n }\n return Object.freeze({ ...input })\n}\n\n","import type { AgentProfile, Scene } from './types'\r\n\r\n/**\r\n * 库内置基础指令 — 通用行为约束与 Agent 行为模式。\r\n *\r\n * 作为 Prompt 4 层拼接的第 ① 层,所有 Agent 共享。\r\n *\r\n * 核心设计:引导 LLM 以 Agent(自主代理)模式运行,而非被动问答。\r\n * ReAct 循环已由 LangGraph 引擎内置,此 prompt 负责引导 LLM 的思维方式。\r\n */\r\nconst BASE_PROMPT = `You are an autonomous AI agent. You can reason, plan, and take actions using the tools available to you.\r\n\r\n## Core Behavior\r\n- When given a task, break it down into steps, then execute each step using the appropriate tools.\r\n- After each tool call, observe the result and decide the next action. Continue until the task is fully completed.\r\n- If no tools are needed, respond directly with your knowledge.\r\n- Never fabricate uncertain information. If you cannot complete a task, explain why honestly.\r\n\r\n## Rules\r\n- Respond in the same language as the user.\r\n- Follow tool parameter schemas strictly — do not invent or omit required fields.\r\n- When multiple tools are available, choose the most relevant one for the current step.`\r\n\r\n/**\r\n * 构建 4 层 Prompt 拼接链。\r\n *\r\n * ```\r\n * ① Base — 库内置固定指令(通用行为约束、防御性指令)\r\n * ② Profile — agent.systemPrompt(角色身份)\r\n * ③ ToolKit — 当前场景激活的 ToolKit.prompt(0~N 个)\r\n * ④ Scene — scene.prompt(sceneContext)(仅绑定 Scene 时)\r\n * ```\r\n *\r\n * 各层以 `\\n\\n` 拼接,合并为单条 SystemMessage 字符串。\r\n *\r\n * @param params - 拼接所需的各层数据\r\n * @returns 完整的 system prompt 字符串\r\n */\r\nexport function buildPromptChain(params: {\r\n /** 当前 Agent 角色 */\r\n profile: AgentProfile\r\n /** 当前场景激活的 ToolKit prompt 列表 */\r\n toolkitPrompts: string[]\r\n /** 运行时场景(可选) */\r\n scene?: Scene\r\n /** 传给 scene.prompt(ctx) 的动态数据(可选) */\r\n sceneContext?: Record<string, any>\r\n}): string {\r\n const layers: string[] = [\r\n // ① Base — 库内置固定指令\r\n BASE_PROMPT,\r\n // ② Profile — 角色身份提示词\r\n params.profile.systemPrompt,\r\n // ③ ToolKit — 当前场景激活的能力包提示词\r\n ...params.toolkitPrompts,\r\n ]\r\n\r\n // ④ Scene — 动态运行时上下文提示词\r\n if (params.scene) {\r\n try {\r\n const scenePrompt = params.scene.prompt(params.sceneContext ?? {})\r\n layers.push(scenePrompt)\r\n } catch (error) {\r\n // Scene.prompt() 异常不应阻断流程,记录错误并跳过该层\r\n console.error('[buildPromptChain] Scene.prompt() error:', error)\r\n layers.push(`[Scene context unavailable due to error: ${error instanceof Error ? error.message : String(error)}]`)\r\n }\r\n }\r\n\r\n return layers.filter(Boolean).join('\\n\\n')\r\n}\r\n\r\n","import { ChatOpenAI } from '@langchain/openai'\r\nimport { createAgent, createMiddleware } from 'langchain'\r\nimport { HumanMessage } from '@langchain/core/messages'\r\nimport type { StructuredToolInterface } from '@langchain/core/tools'\r\nimport type { BaseCheckpointSaver } from '@langchain/langgraph'\r\nimport type { BaseCallbackHandler } from '@langchain/core/callbacks/base'\r\nimport type { AgentOptions } from '../types'\r\n\r\n/**\r\n * 构建单 Agent 图并返回双模式流。\r\n *\r\n * 使用 `createAgent` 创建 ReAct Agent,\r\n * 通过 `streamMode: ['messages', 'updates']` 同时获取:\r\n * - 逐 token 的文本流(messages 模式)\r\n * - 节点级别的完整更新(updates 模式,用于工具调用结果)\r\n *\r\n * Callbacks 在 LLM 层和 graph.stream() 层双重透传,\r\n * 确保观测工具能追踪完整 Agent 执行链路。\r\n *\r\n * ## 错误处理策略\r\n *\r\n * - **LLM 初始化异常**:ChatOpenAI 构造函数会在无效配置时抛出异常(如无效 API Key),\r\n * 由调用方(agent.ts)的顶层 try-catch 捕获并转换为 `error` 事件\r\n * - **Checkpointer 异常**:LangGraph 内部处理 checkpointer 加载/保存失败,\r\n * 失败时会降级为无记忆模式继续执行,不会中断流\r\n * - **工具执行异常**:LangGraph 内置异常处理,工具失败时会将错误信息作为 ToolMessage 返回给 LLM,\r\n * 由 LLM 决定如何处理(重试、跳过或报告用户)\r\n * - **流式输出异常**:stream() 过程中的网络异常或 LLM API 异常会抛出,\r\n * 由调用方的 try-catch 捕获\r\n *\r\n * @param params - 图构建参数\r\n * @returns 双模式流的异步可迭代对象\r\n * @throws 当 LLM 初始化失败或 stream() 执行失败时抛出异常\r\n */\r\nexport async function buildSingleGraph(params: {\r\n /** 完整的 system prompt(4 层拼接后) */\r\n systemPrompt: string\r\n /** 当前场景激活的工具列表 */\r\n tools: StructuredToolInterface[]\r\n /** Agent 模型标识 */\r\n model: string\r\n /** 用户消息 */\r\n message: string\r\n /** 对话线程 ID */\r\n threadId: string\r\n /** LangGraph Checkpointer */\r\n checkpointer: BaseCheckpointSaver\r\n /** 滑动窗口大小 */\r\n maxMessages: number\r\n /** LangChain Callbacks */\r\n callbacks: BaseCallbackHandler[]\r\n /** 底层 LLM 网关配置(OpenAI 兼容) */\r\n llm?: AgentOptions['llm']\r\n}) {\r\n const hasCallbacks = params.callbacks.length > 0\r\n const callbacksOrUndefined = hasCallbacks ? params.callbacks : undefined\r\n\r\n // LLM 初始化 — 可能抛出异常(无效 API Key / baseURL)\r\n let llm: ChatOpenAI\r\n try {\r\n llm = new ChatOpenAI({\r\n model: params.model,\r\n apiKey: params.llm?.apiKey,\r\n configuration: params.llm?.baseURL ? { baseURL: params.llm.baseURL } : undefined,\r\n // LLM 层透传 callbacks — 追踪 LLM 调用本身\r\n callbacks: callbacksOrUndefined,\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSingleGraph] LLM initialization failed:', message)\r\n throw new Error(`Failed to initialize LLM: ${message}`)\r\n }\r\n\r\n console.log('[buildSingleGraph] systemPrompt:', JSON.stringify(params.systemPrompt))\r\n console.log('[buildSingleGraph] model:', params.model)\r\n console.log('[buildSingleGraph] tools:', params.tools.map(t => t.name))\r\n console.log('[buildSingleGraph] threadId:', params.threadId)\r\n console.log('[buildSingleGraph] maxMessages:', params.maxMessages)\r\n\r\n // 图构建 — 可能抛出异常(无效配置)\r\n let graph: ReturnType<typeof createAgent>\r\n try {\r\n graph = createAgent({\r\n model: llm,\r\n tools: params.tools,\r\n checkpointer: params.checkpointer,\r\n systemPrompt: params.systemPrompt,\r\n // 滑动窗口中间件 — beforeModel 阶段裁剪消息,Checkpointer 仍全量存储\r\n middleware: [\r\n createMiddleware({\r\n name: 'sliding-window',\r\n beforeModel: (state) => {\r\n try {\r\n const max = params.maxMessages\r\n if (!state.messages || state.messages.length <= max) return undefined\r\n return { messages: state.messages.slice(-max) }\r\n } catch (error) {\r\n // 中间件异常不应阻断流程,记录错误并返回原始 state\r\n console.error('[buildSingleGraph] sliding-window middleware error:', error)\r\n return undefined\r\n }\r\n },\r\n }),\r\n ],\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSingleGraph] Graph creation failed:', message)\r\n throw new Error(`Failed to create agent graph: ${message}`)\r\n }\r\n\r\n // stream() 调用 — 可能抛出异常(网络异常、LLM API 异常)\r\n try {\r\n return graph.stream(\r\n { messages: [new HumanMessage(params.message)] },\r\n {\r\n configurable: { thread_id: params.threadId },\r\n recursionLimit: 25,\r\n streamMode: ['messages', 'updates'],\r\n // graph 层透传 callbacks — 追踪完整执行链路(工具调用、节点跳转等)\r\n callbacks: callbacksOrUndefined,\r\n },\r\n )\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSingleGraph] Stream initialization failed:', message)\r\n throw new Error(`Failed to start agent stream: ${message}`)\r\n }\r\n}\r\n\r\n","import { ChatOpenAI } from '@langchain/openai'\r\nimport { createReactAgent } from '@langchain/langgraph/prebuilt'\r\nimport { createSupervisor } from '@langchain/langgraph-supervisor'\r\nimport { HumanMessage } from '@langchain/core/messages'\r\nimport type { StructuredToolInterface } from '@langchain/core/tools'\r\nimport type { BaseCheckpointSaver } from '@langchain/langgraph'\r\nimport type { BaseCallbackHandler } from '@langchain/core/callbacks/base'\r\nimport type { AgentProfile, AgentOptions } from '../types'\r\n\r\n/**\r\n * 构建多 Agent Supervisor 图并返回双模式流。\r\n *\r\n * 使用 `@langchain/langgraph-supervisor` 的 `createSupervisor` 构建:\r\n * - Supervisor 负责任务分析与分派\r\n * - Workers 为各 AgentProfile 对应的 ReAct Agent\r\n *\r\n * 工具在 Supervisor 级别不注入(Supervisor 只负责路由),\r\n * 所有工具注入到 Worker Agent 中,由 Scene 过滤后的工具集共享。\r\n *\r\n * ## 错误处理策略\r\n *\r\n * - **LLM 初始化异常**:任一 LLM(Supervisor / Worker)初始化失败时抛出异常,\r\n * 由调用方(agent.ts)的顶层 try-catch 捕获\r\n * - **Worker 创建异常**:单个 Worker 创建失败时记录错误并跳过该 Worker,\r\n * 至少保证 1 个 Worker 可用才继续执行\r\n * - **Checkpointer 异常**:同单 Agent 模式,LangGraph 内部降级处理\r\n * - **流式输出异常**:stream() 过程中的异常会抛出,由调用方捕获\r\n *\r\n * @param params - 图构建参数\r\n * @returns 双模式流的异步可迭代对象\r\n * @throws 当 LLM 初始化失败、Worker 全部创建失败或 stream() 执行失败时抛出异常\r\n */\r\nexport async function buildSupervisorGraph(params: {\r\n /** Supervisor 的 Prompt(4 层拼接后,用于 Supervisor Agent) */\r\n supervisorPrompt: string\r\n /** 所有 AgentProfile 列表 */\r\n agents: AgentProfile[]\r\n /** Supervisor 的 agent name */\r\n supervisorName: string\r\n /** 当前场景激活的工具列表(所有 Worker 共享) */\r\n tools: StructuredToolInterface[]\r\n /** 各 Worker 的 Prompt 映射(profile.name → 4 层拼接后的 prompt) */\r\n workerPrompts: Map<string, string>\r\n /** 用户消息 */\r\n message: string\r\n /** 对话线程 ID */\r\n threadId: string\r\n /** LangGraph Checkpointer */\r\n checkpointer: BaseCheckpointSaver\r\n /** 滑动窗口大小 */\r\n maxMessages: number\r\n /** LangChain Callbacks */\r\n callbacks: BaseCallbackHandler[]\r\n /** 底层 LLM 网关配置(OpenAI 兼容) */\r\n llm?: AgentOptions['llm']\r\n}) {\r\n const hasCallbacks = params.callbacks.length > 0\r\n const callbacksOrUndefined = hasCallbacks ? params.callbacks : undefined\r\n\r\n // 为每个非 Supervisor 的 Agent 创建 Worker\r\n const workerProfiles = params.agents.filter(profile => profile.name !== params.supervisorName)\r\n const workers: ReturnType<typeof createReactAgent>[] = []\r\n const failedWorkers: string[] = []\r\n\r\n for (const profile of workerProfiles) {\r\n try {\r\n const workerLLM = new ChatOpenAI({\r\n model: profile.model,\r\n apiKey: params.llm?.apiKey,\r\n configuration: params.llm?.baseURL ? { baseURL: params.llm.baseURL } : undefined,\r\n callbacks: callbacksOrUndefined,\r\n })\r\n\r\n const workerPrompt = params.workerPrompts.get(profile.name) ?? profile.systemPrompt\r\n\r\n const worker = createReactAgent({\r\n llm: workerLLM,\r\n tools: params.tools,\r\n name: profile.name,\r\n prompt: workerPrompt,\r\n })\r\n\r\n workers.push(worker)\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error(`[buildSupervisorGraph] Failed to create worker \"${profile.name}\":`, message)\r\n failedWorkers.push(profile.name)\r\n }\r\n }\r\n\r\n // 至少需要 1 个 Worker 才能继续\r\n if (workers.length === 0) {\r\n throw new Error(\r\n `Failed to create any workers. All ${workerProfiles.length} workers failed: ${failedWorkers.join(', ')}`,\r\n )\r\n }\r\n\r\n if (failedWorkers.length > 0) {\r\n console.warn(\r\n `[buildSupervisorGraph] ${failedWorkers.length} worker(s) failed to initialize: ${failedWorkers.join(', ')}`,\r\n )\r\n }\r\n\r\n // Supervisor 使用指定 profile 的 model\r\n const supervisorProfile = params.agents.find(p => p.name === params.supervisorName)!\r\n let supervisorLLM: ChatOpenAI\r\n try {\r\n supervisorLLM = new ChatOpenAI({\r\n model: supervisorProfile.model,\r\n apiKey: params.llm?.apiKey,\r\n configuration: params.llm?.baseURL ? { baseURL: params.llm.baseURL } : undefined,\r\n callbacks: callbacksOrUndefined,\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSupervisorGraph] Supervisor LLM initialization failed:', message)\r\n throw new Error(`Failed to initialize Supervisor LLM: ${message}`)\r\n }\r\n\r\n console.log('[buildSupervisorGraph] supervisor:', params.supervisorName)\r\n console.log('[buildSupervisorGraph] workers:', workers.map((_, i) => workerProfiles[i]?.name))\r\n console.log('[buildSupervisorGraph] tools:', params.tools.map(t => t.name))\r\n console.log('[buildSupervisorGraph] threadId:', params.threadId)\r\n\r\n // 创建 Supervisor 图\r\n let workflow: ReturnType<typeof createSupervisor>\r\n try {\r\n // 类型断言:createReactAgent 返回的 CompiledStateGraph 泛型参数\r\n // 与 createSupervisor 期望的类型存在 TS 层面的微小差异(BaseChannel vs BinaryOperatorAggregate),\r\n // 运行时完全兼容,此处用 as any 桥接\r\n workflow = createSupervisor({\r\n agents: workers as any,\r\n llm: supervisorLLM,\r\n prompt: params.supervisorPrompt,\r\n // 保留完整消息历史,让前端能追踪 handoff 过程\r\n outputMode: 'full_history',\r\n // 滑动窗口 — 只裁剪发给 LLM 的消息,Checkpointer 仍全量存储\r\n // 与 single.ts 的 createMiddleware.beforeModel 策略一致\r\n preModelHook: (state: any) => {\r\n try {\r\n const max = params.maxMessages\r\n if (!state.messages || state.messages.length <= max) {\r\n return { llmInputMessages: state.messages || [] }\r\n }\r\n return { llmInputMessages: state.messages.slice(-max) }\r\n } catch (error) {\r\n // 中间件异常不应阻断流程,记录错误并返回原始消息\r\n console.error('[buildSupervisorGraph] sliding-window preModelHook error:', error)\r\n return { llmInputMessages: state.messages || [] }\r\n }\r\n },\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSupervisorGraph] Supervisor workflow creation failed:', message)\r\n throw new Error(`Failed to create supervisor workflow: ${message}`)\r\n }\r\n\r\n // compile 时注入 checkpointer\r\n let graph: ReturnType<typeof workflow.compile>\r\n try {\r\n graph = workflow.compile({\r\n checkpointer: params.checkpointer,\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSupervisorGraph] Graph compilation failed:', message)\r\n throw new Error(`Failed to compile supervisor graph: ${message}`)\r\n }\r\n\r\n // stream() 调用 — 可能抛出异常(网络异常、LLM API 异常)\r\n try {\r\n return graph.stream(\r\n { messages: [new HumanMessage(params.message)] },\r\n {\r\n configurable: { thread_id: params.threadId },\r\n recursionLimit: 50, // 多 Agent 需要更高的递归限制\r\n streamMode: ['messages', 'updates'],\r\n callbacks: callbacksOrUndefined,\r\n },\r\n )\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[buildSupervisorGraph] Stream initialization failed:', message)\r\n throw new Error(`Failed to start supervisor stream: ${message}`)\r\n }\r\n}\r\n\r\n","import { AIMessageChunk, ToolMessage } from '@langchain/core/messages'\r\nimport type { BaseMessage } from '@langchain/core/messages'\r\nimport type { SSEEvent } from './types'\r\n\r\n/**\r\n * 将 LangGraph `stream()` 的双模式流(messages + updates)\r\n * 转换为标准化 SSEEvent 序列。\r\n *\r\n * 事件映射逻辑:\r\n * - `messages` 模式的 AIMessageChunk(含 content)→ `text` 事件\r\n * - `messages` 模式的 AIMessageChunk(含 tool_call_chunks)→ `tool_start` 事件\r\n * - `updates` 模式的 tools 节点输出(ToolMessage)→ `tool_end` 事件\r\n * - `messages` 模式的 metadata.langgraph_node 变化 → `agent` + `handoff` 事件(多 Agent)\r\n *\r\n * ## 错误处理\r\n *\r\n * - **流迭代异常**:stream 本身抛出异常时(网络中断、LLM API 异常),\r\n * 由调用方(agent.ts)的 try-catch 捕获并转换为 `error` 事件\r\n * - **chunk 解析异常**:单个 chunk 解析失败时记录错误并跳过该 chunk,不中断流\r\n * - **生命周期回调异常**:onToolEnd 抛出异常时静默捕获,不影响流\r\n *\r\n * @param stream - LangGraph stream() 返回的异步可迭代对象\r\n * @param onToolEnd - Scene.onToolEnd 生命周期回调(可选)\r\n */\r\nexport async function* transformStream(\r\n stream: AsyncIterable<any>,\r\n onToolEnd?: (toolName: string, result: any) => void,\r\n): AsyncGenerator<SSEEvent> {\r\n // 追踪当前活跃的 agent name,用于检测 handoff\r\n let currentAgentName: string | null = null\r\n\r\n for await (const chunk of stream) {\r\n let events: SSEEvent[]\r\n let detectedAgent: string | null\r\n\r\n // 解析 chunk — 单个 chunk 解析失败不应中断流\r\n try {\r\n const result = parseStreamChunk(chunk, currentAgentName)\r\n events = result.events\r\n detectedAgent = result.detectedAgent\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[transformStream] Failed to parse chunk:', message, chunk)\r\n // 跳过该 chunk,继续处理后续流\r\n continue\r\n }\r\n\r\n // 如果检测到 agent 切换,先 emit handoff 和 agent 事件\r\n if (detectedAgent && detectedAgent !== currentAgentName) {\r\n if (currentAgentName) {\r\n yield { type: 'handoff', from: currentAgentName, to: detectedAgent }\r\n }\r\n yield { type: 'agent', name: detectedAgent }\r\n currentAgentName = detectedAgent\r\n }\r\n\r\n for (const event of events) {\r\n yield event\r\n\r\n // 触发 Scene.onToolEnd 生命周期回调\r\n if (event.type === 'tool_end' && onToolEnd) {\r\n try {\r\n onToolEnd(event.toolName, event.output)\r\n } catch (error) {\r\n // 生命周期回调异常不应影响流,记录错误并继续\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error(`[transformStream] Scene.onToolEnd(\"${event.toolName}\") error:`, message)\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n/** parseStreamChunk 的返回类型 */\r\ninterface ParseResult {\r\n events: SSEEvent[]\r\n /** 从 metadata 中检测到的 agent 名称(仅 messages 模式) */\r\n detectedAgent: string | null\r\n}\r\n\r\n/**\r\n * 解析单个 stream chunk 为 SSEEvent 数组 + agent 检测。\r\n *\r\n * LangGraph `stream({ streamMode: ['messages', 'updates'] })` 产出的 chunk 格式:\r\n * - messages 模式: `['messages', [message, metadata]]`\r\n * - metadata.langgraph_node 标识消息来源节点(即 agent name)\r\n * - updates 模式: `['updates', { nodeName: { messages: [...] } }]`\r\n */\r\nfunction parseStreamChunk(chunk: any, currentAgentName: string | null): ParseResult {\r\n const events: SSEEvent[] = []\r\n let detectedAgent: string | null = null\r\n\r\n // 双 streamMode 下,chunk 是 [streamMode, data] 元组\r\n if (!Array.isArray(chunk) || chunk.length !== 2) return { events, detectedAgent }\r\n\r\n const [mode, data] = chunk\r\n\r\n if (mode === 'messages') {\r\n // data = [message, metadata]\r\n const [message, metadata] = data as [BaseMessage, any]\r\n\r\n // 从 metadata 中提取 agent name(多 Agent 场景)\r\n // langgraph_node 标识当前消息来自哪个节点(supervisor / worker name)\r\n if (metadata?.langgraph_node && typeof metadata.langgraph_node === 'string') {\r\n const nodeName = metadata.langgraph_node as string\r\n // 过滤掉内部节点名(如 \"tools\"、\"__start__\" 等),只关注 agent 节点\r\n if (nodeName !== 'tools' && !nodeName.startsWith('__')) {\r\n // Supervisor 模式下,supervisor 节点名默认为 \"supervisor\"\r\n // Worker 节点名为 createReactAgent 时指定的 name\r\n detectedAgent = nodeName\r\n }\r\n }\r\n\r\n // messages 模式下实际产出 MessageChunk,但 TS 推断为 BaseMessage\r\n if (AIMessageChunk.isInstance(message)) {\r\n // 工具调用 chunk(tool_start 事件)\r\n if (message.tool_call_chunks && message.tool_call_chunks.length > 0) {\r\n for (const toolChunk of message.tool_call_chunks) {\r\n // 只在 name 出现时才 emit tool_start(第一个 chunk 包含 name)\r\n if (toolChunk.name) {\r\n events.push({\r\n type: 'tool_start',\r\n toolName: toolChunk.name,\r\n input: {},\r\n })\r\n }\r\n }\r\n }\r\n\r\n // 文本内容 chunk(text 事件)\r\n const content = typeof message.content === 'string' ? message.content : ''\r\n if (content) {\r\n events.push({ type: 'text', content })\r\n }\r\n }\r\n }\r\n\r\n if (mode === 'updates') {\r\n // data = { nodeName: { messages: [...] } | nodeOutput }\r\n if (data && typeof data === 'object') {\r\n const nodeData = data as Record<string, any>\r\n\r\n // 遍历所有节点输出,查找 ToolMessage\r\n for (const [nodeName, nodeOutput] of Object.entries(nodeData)) {\r\n // tools 节点的输出包含 ToolMessage\r\n // 单 Agent: nodeName === 'tools'\r\n // 多 Agent: nodeName 可能是 worker 内部的 tools 节点(如 '{agentName}_tools')\r\n if (nodeOutput?.messages) {\r\n const toolMessages = nodeOutput.messages as BaseMessage[]\r\n for (const msg of toolMessages) {\r\n if (msg instanceof ToolMessage) {\r\n events.push({\r\n type: 'tool_end',\r\n toolName: msg.name ?? 'unknown',\r\n output: safeParseJSON(\r\n typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content),\r\n ),\r\n })\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { events, detectedAgent }\r\n}\r\n\r\n/**\r\n * 安全解析 JSON 字符串,失败则返回原始字符串。\r\n */\r\nfunction safeParseJSON(str: string): any {\r\n try {\r\n return JSON.parse(str)\r\n } catch {\r\n return str\r\n }\r\n}\r\n\r\n// ─── SSE 格式化工具 ─────────────────────────────────────\r\n\r\n/**\r\n * 将 SSEEvent 格式化为 SSE 协议字符串 `data: JSON\\n\\n`。\r\n */\r\nexport function formatSSE(event: SSEEvent): string {\r\n return `data: ${JSON.stringify(event)}\\n\\n`\r\n}\r\n\r\n","import type { Request, RequestHandler, Response } from 'express'\r\nimport type { Agent } from './agent'\r\nimport { formatSSE } from './sse'\r\nimport type { ChatOptions, SSEEvent } from './types'\r\n\r\n/**\r\n * 写入 SSE 必要响应头。\r\n */\r\nfunction writeSSEHeaders(res: Response): void {\r\n res.status(200)\r\n res.setHeader('Content-Type', 'text/event-stream; charset=utf-8')\r\n res.setHeader('Cache-Control', 'no-cache, no-transform')\r\n res.setHeader('Connection', 'keep-alive')\r\n res.setHeader('X-Accel-Buffering', 'no')\r\n res.flushHeaders?.()\r\n}\r\n\r\n/**\r\n * 从请求体中提取 chat 参数。\r\n */\r\nfunction parseChatOptions(req: Request): ChatOptions {\r\n const body = (req.body ?? {}) as Partial<ChatOptions>\r\n return {\r\n message: typeof body.message === 'string' ? body.message : '',\r\n threadId: typeof body.threadId === 'string' ? body.threadId : '',\r\n sceneContext: body.sceneContext,\r\n }\r\n}\r\n\r\n/**\r\n * 为 Agent 创建 Express SSE 处理器。\r\n *\r\n * 请求体格式:\r\n * {\r\n * \"message\": \"...\",\r\n * \"threadId\": \"...\",\r\n * \"sceneContext\": { ... }\r\n * }\r\n *\r\n * ## 错误处理\r\n *\r\n * - **请求体解析异常**:parseChatOptions 失败时返回 `error` 事件\r\n * - **agent.chat() 异常**:流迭代过程中的异常会被捕获并转换为 `error` 事件\r\n * - **响应写入异常**:res.write() 失败时(客户端断开连接)静默捕获,避免服务器崩溃\r\n * - **所有异常路径**:确保最终都会发送 `done` 事件并关闭响应\r\n */\r\nexport function createExpressHandler(agent: Agent): RequestHandler {\r\n return async (req: Request, res: Response) => {\r\n // 写入 SSE 响应头\r\n try {\r\n writeSSEHeaders(res)\r\n } catch (error) {\r\n // 响应头写入失败(极少见),记录错误并尝试返回 500\r\n console.error('[createExpressHandler] Failed to write SSE headers:', error)\r\n if (!res.headersSent) {\r\n res.status(500).json({ error: 'Failed to initialize SSE stream' })\r\n }\r\n return\r\n }\r\n\r\n // 安全写入 SSE 事件 — 捕获客户端断开连接等异常\r\n const safeWrite = (event: SSEEvent): boolean => {\r\n try {\r\n return res.write(formatSSE(event))\r\n } catch (error) {\r\n // 客户端断开连接时 res.write() 会抛出异常,静默捕获\r\n console.error('[createExpressHandler] Failed to write SSE event:', error)\r\n return false\r\n }\r\n }\r\n\r\n try {\r\n const chatOptions = parseChatOptions(req)\r\n\r\n // 迭代 agent.chat() 流\r\n for await (const event of agent.chat(chatOptions)) {\r\n const success = safeWrite(event)\r\n // 如果写入失败(客户端断开),提前退出循环\r\n if (!success && event.type !== 'done') {\r\n console.warn('[createExpressHandler] Client disconnected, stopping stream')\r\n break\r\n }\r\n }\r\n } catch (error) {\r\n // agent.chat() 或流迭代异常\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[createExpressHandler] Stream error:', message)\r\n safeWrite({ type: 'error', message })\r\n safeWrite({ type: 'done' })\r\n } finally {\r\n // 确保响应最终关闭\r\n try {\r\n res.end()\r\n } catch (error) {\r\n // res.end() 失败(客户端已断开),静默捕获\r\n console.error('[createExpressHandler] Failed to end response:', error)\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { DynamicTool } from '@langchain/core/tools'\nimport type { EmbeddingsInterface } from '@langchain/core/embeddings'\nimport type { KnowledgeBase } from './types'\n\n// ─── 内部数据结构 ────────────────────────────────────────\n\n/** 内存中的单条向量记录 */\ninterface VectorRecord {\n /** 原始文本 */\n text: string\n /** 嵌入向量 */\n vector: number[]\n}\n\n/** 单个知识库的向量存储 */\ninterface VectorStore {\n /** 知识库配置(含 name、description、topK) */\n kb: KnowledgeBase\n /** 向量记录列表 */\n records: VectorRecord[]\n}\n\n// ─── 向量数学 ────────────────────────────────────────────\n\n/**\n * 计算两个向量的余弦相似度。\n *\n * cosine(a, b) = dot(a, b) / (‖a‖ × ‖b‖)\n *\n * @returns [-1, 1] 之间的相似度值,越大越相似\n */\nfunction cosineSimilarity(a: number[], b: number[]): number {\n let dot = 0\n let normA = 0\n let normB = 0\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i]\n normA += a[i] * a[i]\n normB += b[i] * b[i]\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB)\n return denom === 0 ? 0 : dot / denom\n}\n\n// ─── 向量存储初始化 ──────────────────────────────────────\n\n/**\n * 初始化所有知识库的向量存储。\n *\n * 对每个 KnowledgeBase,调用 `embeddings.embedDocuments()` 批量向量化文本,\n * 然后将文本与向量配对存入内存。\n *\n * @param knowledgeBases - 知识库列表\n * @param embeddings - 嵌入模型实例\n * @returns 向量存储列表\n * @throws 当任一知识库的向量化失败时抛出异常\n */\nexport async function initVectorStores(\n knowledgeBases: KnowledgeBase[],\n embeddings: EmbeddingsInterface,\n): Promise<VectorStore[]> {\n const stores: VectorStore[] = []\n\n for (const kb of knowledgeBases) {\n try {\n // 解析 documents:支持静态数组或异步加载函数\n const docs = typeof kb.documents === 'function'\n ? await kb.documents()\n : kb.documents\n\n if (!docs.length) {\n console.warn(`[initVectorStores] \"${kb.name}\" has no documents, skipping`)\n continue\n }\n\n console.log(`[initVectorStores] Embedding \"${kb.name}\" (${docs.length} documents)...`)\n const vectors = await embeddings.embedDocuments(docs)\n\n const records: VectorRecord[] = docs.map((text, i) => ({\n text,\n vector: vectors[i],\n }))\n\n stores.push({ kb, records })\n console.log(`[initVectorStores] \"${kb.name}\" ready (${records.length} vectors, dim=${vectors[0]?.length ?? 0})`)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[initVectorStores] Failed to embed \"${kb.name}\":`, message)\n throw new Error(`Failed to initialize knowledge base \"${kb.name}\": ${message}`)\n }\n }\n\n return stores\n}\n\n// ─── 语义检索 ────────────────────────────────────────────\n\n/**\n * 对单个向量存储执行语义检索。\n *\n * 将 query 向量化后,与存储中的所有向量计算余弦相似度,\n * 返回相似度最高的 topK 条文本。\n *\n * @param store - 向量存储\n * @param query - 检索查询文本\n * @param embeddings - 嵌入模型实例\n * @returns 相似度最高的 topK 条文本\n */\nasync function searchVectorStore(\n store: VectorStore,\n query: string,\n embeddings: EmbeddingsInterface,\n): Promise<string[]> {\n const topK = store.kb.topK ?? 3\n const queryVector = await embeddings.embedQuery(query)\n\n // 计算每条记录与 query 的相似度\n const scored = store.records.map(record => ({\n text: record.text,\n score: cosineSimilarity(queryVector, record.vector),\n }))\n\n // 按相似度降序排序,取 topK\n scored.sort((a, b) => b.score - a.score)\n return scored.slice(0, topK).map(item => item.text)\n}\n\n// ─── Tool 构建 ───────────────────────────────────────────\n\n/**\n * 将向量存储列表转换为 DynamicTool 列表。\n *\n * 每个知识库 → 一个 DynamicTool:\n * - `name` = kb.name\n * - `description` = kb.description\n * - `func(query)` = 语义检索 topK 条文本\n *\n * @param stores - 向量存储列表\n * @param embeddings - 嵌入模型实例\n * @returns DynamicTool 列表,可直接注入 Agent 工具列表\n */\nexport function buildKnowledgeTools(\n stores: VectorStore[],\n embeddings: EmbeddingsInterface,\n): DynamicTool[] {\n return stores.map(store => new DynamicTool({\n name: store.kb.name,\n description: store.kb.description,\n func: async (query: string) => {\n try {\n const results = await searchVectorStore(store, query, embeddings)\n if (results.length === 0) {\n return 'No relevant information found.'\n }\n return results.join('\\n\\n---\\n\\n')\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[buildKnowledgeTools] Search failed for \"${store.kb.name}\":`, message)\n return `Search failed: ${message}`\n }\n },\n }))\n}\n\n","import { MemorySaver } from '@langchain/langgraph'\r\nimport type { BaseCheckpointSaver } from '@langchain/langgraph'\r\nimport type { BaseCallbackHandler } from '@langchain/core/callbacks/base'\r\nimport type { DynamicTool } from '@langchain/core/tools'\r\nimport { buildPromptChain } from './prompt'\r\nimport { buildSingleGraph } from './graph/single'\r\nimport { buildSupervisorGraph } from './graph/supervisor'\r\nimport { transformStream } from './sse'\r\nimport { createExpressHandler } from './middleware'\r\nimport { initVectorStores, buildKnowledgeTools } from './rag'\r\nimport type { RequestHandler } from 'express'\r\nimport type { AgentOptions, ChatOptions, SSEEvent } from './types'\r\n\r\n/**\r\n * Agent 实例的内部已解析配置类型。\r\n *\r\n * 将可选字段填充为默认值后的完整配置。\r\n */\r\ninterface ResolvedOptions extends AgentOptions {\r\n maxMessages: number\r\n callbacks: BaseCallbackHandler[]\r\n checkpointer: BaseCheckpointSaver\r\n}\r\n\r\n/**\r\n * Agent 核心类。\r\n *\r\n * 串联完整流程:参数校验 → ToolKit 过滤 → Prompt 拼接 → 图构建 → 流式输出。\r\n *\r\n * 不直接 new,通过 `createAgent()` 工厂函数创建。\r\n */\r\nexport class Agent {\r\n /** @internal */\r\n readonly options: ResolvedOptions\r\n\r\n /** RAG 知识库转换而来的 DynamicTool 列表 */\r\n private knowledgeTools: DynamicTool[] = []\r\n\r\n /** 异步初始化 Promise(向量化知识库等) */\r\n private readyPromise: Promise<void>\r\n\r\n constructor(options: AgentOptions) {\r\n this.options = {\r\n maxMessages: 50,\r\n callbacks: [],\r\n checkpointer: new MemorySaver(),\r\n ...options,\r\n }\r\n this.validate()\r\n this.readyPromise = this.init()\r\n }\r\n\r\n /**\r\n * 异步初始化 — 向量化知识库并构建检索 Tool。\r\n *\r\n * 在构造函数中启动,chat() 首次调用时 await 确保完成。\r\n * 若无 knowledgeBases,立即 resolve。\r\n */\r\n private async init(): Promise<void> {\r\n const { knowledgeBases, embeddings } = this.options\r\n if (!knowledgeBases?.length || !embeddings) return\r\n\r\n try {\r\n const stores = await initVectorStores(knowledgeBases, embeddings)\r\n this.knowledgeTools = buildKnowledgeTools(stores, embeddings)\r\n console.log(`[Agent] ${this.knowledgeTools.length} knowledge tool(s) ready`)\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error('[Agent] Knowledge base initialization failed:', message)\r\n throw error\r\n }\r\n }\r\n\r\n /**\r\n * 发起对话,返回标准化 SSE 事件的异步生成器。\r\n *\r\n * 完整流程:\r\n * 1. ToolKit 过滤(Scene.toolkits 决定)\r\n * 2. Prompt 4 层拼接(Base → Profile → ToolKit → Scene)\r\n * 3. 构建 LangGraph 图 + stream\r\n * 4. 转换流事件 → 标准化 SSEEvent\r\n *\r\n * 任何异常均以 `error` + `done` 事件正常结束流,不崩溃。\r\n *\r\n * @param chatOptions - 对话参数\r\n * @yields 标准化 SSE 事件序列\r\n */\r\n async *chat(chatOptions: ChatOptions): AsyncGenerator<SSEEvent> {\r\n try {\r\n // 确保知识库向量化完成\r\n await this.readyPromise\r\n\r\n // 参数校验\r\n if (!chatOptions.message) {\r\n yield { type: 'error', message: 'message is required' }\r\n yield { type: 'done' }\r\n return\r\n }\r\n if (!chatOptions.threadId) {\r\n yield { type: 'error', message: 'threadId is required' }\r\n yield { type: 'done' }\r\n return\r\n }\r\n\r\n // 1. ToolKit 过滤 — Scene 决定当前可用的工具集\r\n const scene = this.options.scene\r\n const activeToolkits = scene\r\n ? this.options.toolkits.filter(tk => scene.toolkits.includes(tk.name))\r\n : this.options.toolkits\r\n const tools = [\r\n ...activeToolkits.flatMap(tk => tk.tools),\r\n ...this.knowledgeTools, // RAG 知识库 Tool 注入\r\n ]\r\n const toolkitPrompts = activeToolkits.map(tk => tk.prompt)\r\n\r\n // 2. 判断单/多 Agent 策略\r\n const isMultiAgent = this.options.agents.length > 1 && !!this.options.supervisor\r\n\r\n let stream: AsyncIterable<any>\r\n\r\n if (isMultiAgent) {\r\n // 多 Agent 模式:Supervisor + Workers\r\n const supervisorProfile = this.options.agents.find(\r\n a => a.name === this.options.supervisor,\r\n )!\r\n\r\n // Supervisor 的 prompt(4 层拼接)\r\n const supervisorPrompt = buildPromptChain({\r\n profile: supervisorProfile,\r\n toolkitPrompts,\r\n scene,\r\n sceneContext: chatOptions.sceneContext,\r\n })\r\n\r\n // 各 Worker 的 prompt(4 层拼接)\r\n const workerPrompts = new Map<string, string>()\r\n for (const profile of this.options.agents) {\r\n if (profile.name !== this.options.supervisor) {\r\n workerPrompts.set(\r\n profile.name,\r\n buildPromptChain({\r\n profile,\r\n toolkitPrompts,\r\n scene,\r\n sceneContext: chatOptions.sceneContext,\r\n }),\r\n )\r\n }\r\n }\r\n\r\n stream = await buildSupervisorGraph({\r\n supervisorPrompt,\r\n agents: this.options.agents,\r\n supervisorName: this.options.supervisor!,\r\n tools,\r\n workerPrompts,\r\n message: chatOptions.message,\r\n threadId: chatOptions.threadId,\r\n checkpointer: this.options.checkpointer,\r\n maxMessages: this.options.maxMessages,\r\n callbacks: this.options.callbacks,\r\n llm: this.options.llm,\r\n })\r\n } else {\r\n // 单 Agent 模式\r\n const profile = this.options.agents[0]\r\n const systemPrompt = buildPromptChain({\r\n profile,\r\n toolkitPrompts,\r\n scene,\r\n sceneContext: chatOptions.sceneContext,\r\n })\r\n\r\n stream = await buildSingleGraph({\r\n systemPrompt,\r\n tools,\r\n model: profile.model,\r\n message: chatOptions.message,\r\n threadId: chatOptions.threadId,\r\n checkpointer: this.options.checkpointer,\r\n maxMessages: this.options.maxMessages,\r\n callbacks: this.options.callbacks,\r\n llm: this.options.llm,\r\n })\r\n }\r\n\r\n // 4. 转换流事件 → 标准化 SSE 事件\r\n yield* transformStream(stream, scene?.onToolEnd)\r\n yield { type: 'done' }\r\n } catch (err) {\r\n const message = err instanceof Error\r\n ? `${err.message}${err.cause ? ` | cause: ${err.cause}` : ''}${err.stack ? `\\n${err.stack}` : ''}`\r\n : String(err)\r\n console.error('[agent.chat] error:', message)\r\n yield { type: 'error', message }\r\n yield { type: 'done' }\r\n }\r\n }\r\n\r\n /**\r\n * 返回 Express RequestHandler,直接用于路由挂载。\r\n *\r\n * @example\r\n * ```ts\r\n * app.post('/chat', agent.handleRequest())\r\n * ```\r\n */\r\n handleRequest(): RequestHandler {\r\n return createExpressHandler(this)\r\n }\r\n\r\n /**\r\n * 参数校验 — 在构造时执行,快速失败。\r\n */\r\n private validate(): void {\r\n if (!this.options.agents.length) {\r\n throw new Error('At least one agent is required')\r\n }\r\n if (this.options.supervisor) {\r\n const found = this.options.agents.find(a => a.name === this.options.supervisor)\r\n if (!found) {\r\n throw new Error(`Supervisor \"${this.options.supervisor}\" not found in agents`)\r\n }\r\n }\r\n // 校验 Scene 引用的 ToolKit 是否都已注册\r\n if (this.options.scene) {\r\n const registeredNames = new Set(this.options.toolkits.map(tk => tk.name))\r\n for (const name of this.options.scene.toolkits) {\r\n if (!registeredNames.has(name)) {\r\n throw new Error(`Scene references toolkit \"${name}\" which is not registered`)\r\n }\r\n }\r\n }\r\n // 校验 knowledgeBases 与 embeddings 配套\r\n if (this.options.knowledgeBases?.length && !this.options.embeddings) {\r\n throw new Error('embeddings is required when knowledgeBases is provided')\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 创建 Agent 实例。\r\n *\r\n * @param options - Agent 配置项\r\n * @returns Agent 实例\r\n *\r\n * @example\r\n * ```ts\r\n * const agent = createAgent({\r\n * toolkits: [canvasToolKit],\r\n * agents: [director],\r\n * scene: timelineScene,\r\n * })\r\n *\r\n * for await (const event of agent.chat({ message: '你好', threadId: 'thread-001' })) {\r\n * console.log(event)\r\n * }\r\n * ```\r\n */\r\nexport function createAgent(options: AgentOptions): Agent {\r\n return new Agent(options)\r\n}\r\n\r\n"]}
|