@cicctencent/agent-core 0.1.17 → 0.1.19
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 +70 -1
- package/dist/cjs/agent/engine.d.ts +23 -0
- package/dist/cjs/agent/engine.d.ts.map +1 -1
- package/dist/cjs/agent/engine.js +78 -5
- package/dist/cjs/agent/engine.js.map +1 -1
- package/dist/cjs/agent/history-manager.d.ts +66 -1
- package/dist/cjs/agent/history-manager.d.ts.map +1 -1
- package/dist/cjs/agent/history-manager.js +232 -0
- package/dist/cjs/agent/history-manager.js.map +1 -1
- package/dist/cjs/agent/llm-caller.d.ts.map +1 -1
- package/dist/cjs/agent/llm-caller.js +10 -4
- package/dist/cjs/agent/llm-caller.js.map +1 -1
- package/dist/cjs/agent/profile-loader.d.ts +56 -0
- package/dist/cjs/agent/profile-loader.d.ts.map +1 -0
- package/dist/cjs/agent/profile-loader.js +145 -0
- package/dist/cjs/agent/profile-loader.js.map +1 -0
- package/dist/cjs/agent/types.d.ts +32 -3
- package/dist/cjs/agent/types.d.ts.map +1 -1
- package/dist/cjs/agent/types.js.map +1 -1
- package/dist/cjs/context/types.d.ts +3 -3
- package/dist/cjs/context/types.d.ts.map +1 -1
- package/dist/cjs/index.d.ts +26 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +42 -11
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/kb/in-memory-kb.d.ts +29 -0
- package/dist/cjs/kb/in-memory-kb.d.ts.map +1 -0
- package/dist/cjs/kb/in-memory-kb.js +210 -0
- package/dist/cjs/kb/in-memory-kb.js.map +1 -0
- package/dist/cjs/kb/rag-middleware.d.ts +31 -0
- package/dist/cjs/kb/rag-middleware.d.ts.map +1 -0
- package/dist/cjs/kb/rag-middleware.js +94 -0
- package/dist/cjs/kb/rag-middleware.js.map +1 -0
- package/dist/cjs/kb/types.d.ts +80 -0
- package/dist/cjs/kb/types.d.ts.map +1 -0
- package/dist/cjs/kb/types.js +6 -0
- package/dist/cjs/kb/types.js.map +1 -0
- package/dist/cjs/llm/anthropic-provider.d.ts +7 -0
- package/dist/cjs/llm/anthropic-provider.d.ts.map +1 -1
- package/dist/cjs/llm/anthropic-provider.js +84 -9
- package/dist/cjs/llm/anthropic-provider.js.map +1 -1
- package/dist/cjs/llm/openai-provider.d.ts +9 -0
- package/dist/cjs/llm/openai-provider.d.ts.map +1 -1
- package/dist/cjs/llm/openai-provider.js +41 -1
- package/dist/cjs/llm/openai-provider.js.map +1 -1
- package/dist/cjs/llm/pricing.d.ts +26 -0
- package/dist/cjs/llm/pricing.d.ts.map +1 -0
- package/dist/cjs/llm/pricing.js +86 -0
- package/dist/cjs/llm/pricing.js.map +1 -0
- package/dist/cjs/llm/usage-tracker.d.ts +119 -0
- package/dist/cjs/llm/usage-tracker.d.ts.map +1 -0
- package/dist/cjs/llm/usage-tracker.js +105 -0
- package/dist/cjs/llm/usage-tracker.js.map +1 -0
- package/dist/cjs/memory/extractor.js +1 -1
- package/dist/cjs/memory/extractor.js.map +1 -1
- package/dist/cjs/memory/persona.js +1 -1
- package/dist/cjs/memory/persona.js.map +1 -1
- package/dist/cjs/memory/scene.js +1 -1
- package/dist/cjs/memory/scene.js.map +1 -1
- package/dist/cjs/middleware/types.d.ts +2 -4
- package/dist/cjs/middleware/types.d.ts.map +1 -1
- package/dist/cjs/middleware/workspace-notes.d.ts +36 -0
- package/dist/cjs/middleware/workspace-notes.d.ts.map +1 -0
- package/dist/cjs/middleware/workspace-notes.js +53 -0
- package/dist/cjs/middleware/workspace-notes.js.map +1 -0
- package/dist/cjs/observability/logger.d.ts +1 -0
- package/dist/cjs/observability/logger.d.ts.map +1 -1
- package/dist/cjs/observability/logger.js.map +1 -1
- package/dist/cjs/observability/trace.d.ts +45 -0
- package/dist/cjs/observability/trace.d.ts.map +1 -0
- package/dist/cjs/observability/trace.js +59 -0
- package/dist/cjs/observability/trace.js.map +1 -0
- package/dist/cjs/runtime/run-registry-interface.d.ts +42 -0
- package/dist/cjs/runtime/run-registry-interface.d.ts.map +1 -0
- package/dist/cjs/runtime/run-registry-interface.js +7 -0
- package/dist/cjs/runtime/run-registry-interface.js.map +1 -0
- package/dist/cjs/runtime/run-registry.d.ts +15 -2
- package/dist/cjs/runtime/run-registry.d.ts.map +1 -1
- package/dist/cjs/runtime/run-registry.js +43 -1
- package/dist/cjs/runtime/run-registry.js.map +1 -1
- package/dist/cjs/sandbox/code-sandbox.d.ts +42 -0
- package/dist/cjs/sandbox/code-sandbox.d.ts.map +1 -0
- package/dist/cjs/sandbox/code-sandbox.js +59 -0
- package/dist/cjs/sandbox/code-sandbox.js.map +1 -0
- package/dist/cjs/skill/router.d.ts +20 -1
- package/dist/cjs/skill/router.d.ts.map +1 -1
- package/dist/cjs/skill/router.js +39 -1
- package/dist/cjs/skill/router.js.map +1 -1
- package/dist/cjs/skill/types.d.ts +1 -1
- package/dist/cjs/skill/types.d.ts.map +1 -1
- package/dist/cjs/skill/vector-index.d.ts +42 -0
- package/dist/cjs/skill/vector-index.d.ts.map +1 -0
- package/dist/cjs/skill/vector-index.js +70 -0
- package/dist/cjs/skill/vector-index.js.map +1 -0
- package/dist/cjs/store/history-persistence.d.ts +36 -0
- package/dist/cjs/store/history-persistence.d.ts.map +1 -0
- package/dist/cjs/store/history-persistence.js +142 -0
- package/dist/cjs/store/history-persistence.js.map +1 -0
- package/dist/cjs/types.d.ts +40 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/types.js +34 -0
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/token-counter.d.ts.map +1 -1
- package/dist/cjs/utils/token-counter.js +33 -1
- package/dist/cjs/utils/token-counter.js.map +1 -1
- package/dist/esm/agent/engine.d.ts +23 -0
- package/dist/esm/agent/engine.d.ts.map +1 -1
- package/dist/esm/agent/engine.js +78 -5
- package/dist/esm/agent/engine.js.map +1 -1
- package/dist/esm/agent/history-manager.d.ts +66 -1
- package/dist/esm/agent/history-manager.d.ts.map +1 -1
- package/dist/esm/agent/history-manager.js +232 -0
- package/dist/esm/agent/history-manager.js.map +1 -1
- package/dist/esm/agent/llm-caller.d.ts.map +1 -1
- package/dist/esm/agent/llm-caller.js +10 -4
- package/dist/esm/agent/llm-caller.js.map +1 -1
- package/dist/esm/agent/profile-loader.d.ts +56 -0
- package/dist/esm/agent/profile-loader.d.ts.map +1 -0
- package/dist/esm/agent/profile-loader.js +108 -0
- package/dist/esm/agent/profile-loader.js.map +1 -0
- package/dist/esm/agent/types.d.ts +32 -3
- package/dist/esm/agent/types.d.ts.map +1 -1
- package/dist/esm/agent/types.js.map +1 -1
- package/dist/esm/context/types.d.ts +3 -3
- package/dist/esm/context/types.d.ts.map +1 -1
- package/dist/esm/index.d.ts +26 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/kb/in-memory-kb.d.ts +29 -0
- package/dist/esm/kb/in-memory-kb.d.ts.map +1 -0
- package/dist/esm/kb/in-memory-kb.js +206 -0
- package/dist/esm/kb/in-memory-kb.js.map +1 -0
- package/dist/esm/kb/rag-middleware.d.ts +31 -0
- package/dist/esm/kb/rag-middleware.d.ts.map +1 -0
- package/dist/esm/kb/rag-middleware.js +91 -0
- package/dist/esm/kb/rag-middleware.js.map +1 -0
- package/dist/esm/kb/types.d.ts +80 -0
- package/dist/esm/kb/types.d.ts.map +1 -0
- package/dist/esm/kb/types.js +5 -0
- package/dist/esm/kb/types.js.map +1 -0
- package/dist/esm/llm/anthropic-provider.d.ts +7 -0
- package/dist/esm/llm/anthropic-provider.d.ts.map +1 -1
- package/dist/esm/llm/anthropic-provider.js +84 -9
- package/dist/esm/llm/anthropic-provider.js.map +1 -1
- package/dist/esm/llm/openai-provider.d.ts +9 -0
- package/dist/esm/llm/openai-provider.d.ts.map +1 -1
- package/dist/esm/llm/openai-provider.js +41 -1
- package/dist/esm/llm/openai-provider.js.map +1 -1
- package/dist/esm/llm/pricing.d.ts +26 -0
- package/dist/esm/llm/pricing.d.ts.map +1 -0
- package/dist/esm/llm/pricing.js +81 -0
- package/dist/esm/llm/pricing.js.map +1 -0
- package/dist/esm/llm/usage-tracker.d.ts +119 -0
- package/dist/esm/llm/usage-tracker.d.ts.map +1 -0
- package/dist/esm/llm/usage-tracker.js +101 -0
- package/dist/esm/llm/usage-tracker.js.map +1 -0
- package/dist/esm/memory/extractor.js +1 -1
- package/dist/esm/memory/extractor.js.map +1 -1
- package/dist/esm/memory/persona.js +1 -1
- package/dist/esm/memory/persona.js.map +1 -1
- package/dist/esm/memory/scene.js +1 -1
- package/dist/esm/memory/scene.js.map +1 -1
- package/dist/esm/middleware/types.d.ts +2 -4
- package/dist/esm/middleware/types.d.ts.map +1 -1
- package/dist/esm/middleware/workspace-notes.d.ts +36 -0
- package/dist/esm/middleware/workspace-notes.d.ts.map +1 -0
- package/dist/esm/middleware/workspace-notes.js +49 -0
- package/dist/esm/middleware/workspace-notes.js.map +1 -0
- package/dist/esm/observability/logger.d.ts +1 -0
- package/dist/esm/observability/logger.d.ts.map +1 -1
- package/dist/esm/observability/logger.js.map +1 -1
- package/dist/esm/observability/trace.d.ts +45 -0
- package/dist/esm/observability/trace.d.ts.map +1 -0
- package/dist/esm/observability/trace.js +55 -0
- package/dist/esm/observability/trace.js.map +1 -0
- package/dist/esm/runtime/run-registry-interface.d.ts +42 -0
- package/dist/esm/runtime/run-registry-interface.d.ts.map +1 -0
- package/dist/esm/runtime/run-registry-interface.js +6 -0
- package/dist/esm/runtime/run-registry-interface.js.map +1 -0
- package/dist/esm/runtime/run-registry.d.ts +15 -2
- package/dist/esm/runtime/run-registry.d.ts.map +1 -1
- package/dist/esm/runtime/run-registry.js +43 -1
- package/dist/esm/runtime/run-registry.js.map +1 -1
- package/dist/esm/sandbox/code-sandbox.d.ts +42 -0
- package/dist/esm/sandbox/code-sandbox.d.ts.map +1 -0
- package/dist/esm/sandbox/code-sandbox.js +56 -0
- package/dist/esm/sandbox/code-sandbox.js.map +1 -0
- package/dist/esm/skill/router.d.ts +20 -1
- package/dist/esm/skill/router.d.ts.map +1 -1
- package/dist/esm/skill/router.js +37 -0
- package/dist/esm/skill/router.js.map +1 -1
- package/dist/esm/skill/types.d.ts +1 -1
- package/dist/esm/skill/types.d.ts.map +1 -1
- package/dist/esm/skill/vector-index.d.ts +42 -0
- package/dist/esm/skill/vector-index.d.ts.map +1 -0
- package/dist/esm/skill/vector-index.js +66 -0
- package/dist/esm/skill/vector-index.js.map +1 -0
- package/dist/esm/store/history-persistence.d.ts +36 -0
- package/dist/esm/store/history-persistence.d.ts.map +1 -0
- package/dist/esm/store/history-persistence.js +105 -0
- package/dist/esm/store/history-persistence.js.map +1 -0
- package/dist/esm/types.d.ts +40 -1
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +32 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/token-counter.d.ts.map +1 -1
- package/dist/esm/utils/token-counter.js +33 -1
- package/dist/esm/utils/token-counter.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// VectorIndex — 向量索引接口与内存实现
|
|
4
|
+
// 纯 JS 余弦相似度,零外部依赖
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.InMemoryVectorIndex = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* InMemoryVectorIndex — 内存向量索引
|
|
10
|
+
* 纯 JS 余弦相似度实现,零外部依赖
|
|
11
|
+
*/
|
|
12
|
+
class InMemoryVectorIndex {
|
|
13
|
+
items = new Map();
|
|
14
|
+
/** 预计算的向量范数缓存 */
|
|
15
|
+
norms = new Map();
|
|
16
|
+
build(items) {
|
|
17
|
+
this.items.clear();
|
|
18
|
+
this.norms.clear();
|
|
19
|
+
for (const item of items) {
|
|
20
|
+
this.items.set(item.id, item);
|
|
21
|
+
this.norms.set(item.id, this.computeNorm(item.vector));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async search(query, k) {
|
|
25
|
+
if (this.items.size === 0 || k <= 0)
|
|
26
|
+
return [];
|
|
27
|
+
const queryNorm = this.computeNorm(query);
|
|
28
|
+
if (queryNorm === 0)
|
|
29
|
+
return [];
|
|
30
|
+
const results = [];
|
|
31
|
+
for (const [id, item] of this.items) {
|
|
32
|
+
const itemNorm = this.norms.get(id) ?? this.computeNorm(item.vector);
|
|
33
|
+
if (itemNorm === 0)
|
|
34
|
+
continue;
|
|
35
|
+
const score = this.dotProduct(query, item.vector) / (queryNorm * itemNorm);
|
|
36
|
+
results.push({ id, score, metadata: item.metadata });
|
|
37
|
+
}
|
|
38
|
+
results.sort((a, b) => b.score - a.score);
|
|
39
|
+
return results.slice(0, k);
|
|
40
|
+
}
|
|
41
|
+
add(item) {
|
|
42
|
+
this.items.set(item.id, item);
|
|
43
|
+
this.norms.set(item.id, this.computeNorm(item.vector));
|
|
44
|
+
}
|
|
45
|
+
remove(id) {
|
|
46
|
+
this.items.delete(id);
|
|
47
|
+
this.norms.delete(id);
|
|
48
|
+
}
|
|
49
|
+
size() {
|
|
50
|
+
return this.items.size;
|
|
51
|
+
}
|
|
52
|
+
// ---- 内部方法 ----
|
|
53
|
+
dotProduct(a, b) {
|
|
54
|
+
let sum = 0;
|
|
55
|
+
const len = Math.min(a.length, b.length);
|
|
56
|
+
for (let i = 0; i < len; i++) {
|
|
57
|
+
sum += a[i] * b[i];
|
|
58
|
+
}
|
|
59
|
+
return sum;
|
|
60
|
+
}
|
|
61
|
+
computeNorm(vec) {
|
|
62
|
+
let sum = 0;
|
|
63
|
+
for (let i = 0; i < vec.length; i++) {
|
|
64
|
+
sum += vec[i] * vec[i];
|
|
65
|
+
}
|
|
66
|
+
return Math.sqrt(sum);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.InMemoryVectorIndex = InMemoryVectorIndex;
|
|
70
|
+
//# sourceMappingURL=vector-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector-index.js","sourceRoot":"","sources":["../../../src/skill/vector-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Message } from '../types.js';
|
|
2
|
+
import type { HistoryPersistence } from '../agent/types.js';
|
|
3
|
+
export interface JsonlHistoryPersistenceOptions {
|
|
4
|
+
/** 存储目录(相对于 data 目录),默认 'history' */
|
|
5
|
+
dir?: string;
|
|
6
|
+
/** 使用项目级目录({cwd}/data)而非全局目录(~/.agent/data) */
|
|
7
|
+
projectLocal?: boolean;
|
|
8
|
+
/** 直接使用绝对路径(忽略 projectLocal 和 dir) */
|
|
9
|
+
absoluteDir?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Append-only JSONL 会话历史持久化
|
|
13
|
+
*
|
|
14
|
+
* 文件路径:{dataDir}/{dir}/{sessionId}.jsonl
|
|
15
|
+
*
|
|
16
|
+
* 特点:
|
|
17
|
+
* - Append-only:只追加不修改,保证审计完整性
|
|
18
|
+
* - JSONL 格式:每行一条 JSON,人类可读,可用 jq/grep 查询
|
|
19
|
+
* - 异步写入:不阻塞 Agent Loop
|
|
20
|
+
* - 容错:损坏行跳过,不中断加载
|
|
21
|
+
*/
|
|
22
|
+
export declare class JsonlHistoryPersistence implements HistoryPersistence {
|
|
23
|
+
private dir;
|
|
24
|
+
private projectLocal;
|
|
25
|
+
private absoluteDir?;
|
|
26
|
+
constructor(options?: JsonlHistoryPersistenceOptions);
|
|
27
|
+
/** 获取会话历史文件路径 */
|
|
28
|
+
private getFilePath;
|
|
29
|
+
/** 确保目录存在 */
|
|
30
|
+
private ensureDir;
|
|
31
|
+
save(sessionId: string, message: Message): Promise<void>;
|
|
32
|
+
load(sessionId: string): Promise<Message[] | null>;
|
|
33
|
+
delete(sessionId: string): Promise<void>;
|
|
34
|
+
exists(sessionId: string): Promise<boolean>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=history-persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-persistence.d.ts","sourceRoot":"","sources":["../../../src/store/history-persistence.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,MAAM,WAAW,8BAA8B;IAC7C,qCAAqC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,uBAAwB,YAAW,kBAAkB;IAChE,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,WAAW,CAAC,CAAS;gBAEjB,OAAO,GAAE,8BAAmC;IAMxD,iBAAiB;IACjB,OAAO,CAAC,WAAW;IASnB,aAAa;YACC,SAAS;IAOjB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IA+BlD,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CASlD"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// JsonlHistoryPersistence — Append-only JSONL 会话历史持久化
|
|
4
|
+
// ============================================================
|
|
5
|
+
//
|
|
6
|
+
// 每个 session 一个 .jsonl 文件,每行一条 Message JSON。
|
|
7
|
+
// - save(): 追加一行(append-only,不覆盖已有内容)
|
|
8
|
+
// - load(): 逐行读取重建 Message[]
|
|
9
|
+
// - delete(): 删除文件
|
|
10
|
+
//
|
|
11
|
+
// 设计参考:Claude Code 的 append-only JSONL 转录
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.JsonlHistoryPersistence = void 0;
|
|
47
|
+
const fsp = __importStar(require("fs/promises"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const data_dir_ts_1 = require("../utils/data-dir.js");
|
|
50
|
+
/**
|
|
51
|
+
* Append-only JSONL 会话历史持久化
|
|
52
|
+
*
|
|
53
|
+
* 文件路径:{dataDir}/{dir}/{sessionId}.jsonl
|
|
54
|
+
*
|
|
55
|
+
* 特点:
|
|
56
|
+
* - Append-only:只追加不修改,保证审计完整性
|
|
57
|
+
* - JSONL 格式:每行一条 JSON,人类可读,可用 jq/grep 查询
|
|
58
|
+
* - 异步写入:不阻塞 Agent Loop
|
|
59
|
+
* - 容错:损坏行跳过,不中断加载
|
|
60
|
+
*/
|
|
61
|
+
class JsonlHistoryPersistence {
|
|
62
|
+
dir;
|
|
63
|
+
projectLocal;
|
|
64
|
+
absoluteDir;
|
|
65
|
+
constructor(options = {}) {
|
|
66
|
+
this.dir = options.dir || 'history';
|
|
67
|
+
this.projectLocal = options.projectLocal ?? false;
|
|
68
|
+
this.absoluteDir = options.absoluteDir;
|
|
69
|
+
}
|
|
70
|
+
/** 获取会话历史文件路径 */
|
|
71
|
+
getFilePath(sessionId) {
|
|
72
|
+
// 防止路径遍历:只允许字母数字和 -_
|
|
73
|
+
const safeId = sessionId.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
74
|
+
if (this.absoluteDir) {
|
|
75
|
+
return path.join(this.absoluteDir, `${safeId}.jsonl`);
|
|
76
|
+
}
|
|
77
|
+
return (0, data_dir_ts_1.getDataPath)(`${this.dir}/${safeId}.jsonl`);
|
|
78
|
+
}
|
|
79
|
+
/** 确保目录存在 */
|
|
80
|
+
async ensureDir() {
|
|
81
|
+
const dirPath = this.absoluteDir
|
|
82
|
+
? this.absoluteDir
|
|
83
|
+
: path.dirname((0, data_dir_ts_1.getDataPath)(`${this.dir}/.placeholder`));
|
|
84
|
+
await fsp.mkdir(dirPath, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
async save(sessionId, message) {
|
|
87
|
+
await this.ensureDir();
|
|
88
|
+
const filePath = this.getFilePath(sessionId);
|
|
89
|
+
const line = JSON.stringify(message) + '\n';
|
|
90
|
+
await fsp.appendFile(filePath, line, 'utf-8');
|
|
91
|
+
}
|
|
92
|
+
async load(sessionId) {
|
|
93
|
+
const filePath = this.getFilePath(sessionId);
|
|
94
|
+
try {
|
|
95
|
+
await fsp.access(filePath);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
const raw = await fsp.readFile(filePath, 'utf-8');
|
|
102
|
+
const lines = raw.split('\n').filter(line => line.trim());
|
|
103
|
+
const messages = [];
|
|
104
|
+
for (const line of lines) {
|
|
105
|
+
try {
|
|
106
|
+
const msg = JSON.parse(line);
|
|
107
|
+
messages.push(msg);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// 跳过损坏行(如写入中断导致的不完整 JSON)
|
|
111
|
+
console.warn(`[JsonlHistoryPersistence] Skipped malformed line in ${filePath}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return messages;
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
console.error(`[JsonlHistoryPersistence] load error: ${filePath}`, e);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async delete(sessionId) {
|
|
122
|
+
const filePath = this.getFilePath(sessionId);
|
|
123
|
+
try {
|
|
124
|
+
await fsp.unlink(filePath);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// 文件不存在时静默忽略
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async exists(sessionId) {
|
|
131
|
+
const filePath = this.getFilePath(sessionId);
|
|
132
|
+
try {
|
|
133
|
+
await fsp.access(filePath);
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.JsonlHistoryPersistence = JsonlHistoryPersistence;
|
|
142
|
+
//# sourceMappingURL=history-persistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-persistence.js","sourceRoot":"","sources":["../../../src/store/history-persistence.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
/** 文本内容部分 */
|
|
2
|
+
export interface TextPart {
|
|
3
|
+
type: 'text';
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
/** 图片内容部分 */
|
|
7
|
+
export interface ImagePart {
|
|
8
|
+
type: 'image';
|
|
9
|
+
/** 图片来源:URL(http/https)或 base64 data URI(data:image/png;base64,...) */
|
|
10
|
+
source: string;
|
|
11
|
+
/** 图片 MIME 类型(如 image/png, image/jpeg),base64 时可从 data URI 推断 */
|
|
12
|
+
mimeType?: string;
|
|
13
|
+
/** 图片详情级别(OpenAI: low/high/auto),默认 auto */
|
|
14
|
+
detail?: 'low' | 'high' | 'auto';
|
|
15
|
+
}
|
|
16
|
+
/** 文件内容部分(PDF、文档等,由上层解析为文本后注入) */
|
|
17
|
+
export interface FilePart {
|
|
18
|
+
type: 'file';
|
|
19
|
+
/** 文件名 */
|
|
20
|
+
filename: string;
|
|
21
|
+
/** 文件内容(文本形式,已由上层解析提取) */
|
|
22
|
+
content: string;
|
|
23
|
+
/** 文件 MIME 类型 */
|
|
24
|
+
mimeType?: string;
|
|
25
|
+
}
|
|
26
|
+
/** 多模态内容部分(discriminated union) */
|
|
27
|
+
export type ContentPart = TextPart | ImagePart | FilePart;
|
|
1
28
|
/** 消息角色 */
|
|
2
29
|
export type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
3
30
|
/** LLM 发起的工具调用 */
|
|
@@ -12,7 +39,8 @@ export interface ToolCall {
|
|
|
12
39
|
/** LLM 消息 */
|
|
13
40
|
export interface Message {
|
|
14
41
|
role: MessageRole;
|
|
15
|
-
|
|
42
|
+
/** 消息内容:纯文本字符串、多模态内容部分数组、或 null(无内容) */
|
|
43
|
+
content: string | ContentPart[] | null;
|
|
16
44
|
/** assistant 消息中的工具调用请求 */
|
|
17
45
|
tool_calls?: ToolCall[];
|
|
18
46
|
/** tool 消息对应的 tool_call id */
|
|
@@ -24,6 +52,17 @@ export interface Message {
|
|
|
24
52
|
/** 扩展字段,上层可附加任意元数据 */
|
|
25
53
|
metadata?: Record<string, unknown>;
|
|
26
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* 从 Message.content 中提取纯文本(用于 Skill 路由、去重检测等场景)
|
|
57
|
+
* - string 直接返回
|
|
58
|
+
* - ContentPart[] 拼接所有 TextPart 和 FilePart 的文本
|
|
59
|
+
* - null 返回空字符串
|
|
60
|
+
*/
|
|
61
|
+
export declare function extractTextFromContent(content: string | ContentPart[] | null): string;
|
|
62
|
+
/**
|
|
63
|
+
* 判断消息内容是否为多模态(包含非文本部分)
|
|
64
|
+
*/
|
|
65
|
+
export declare function isMultimodalContent(content: string | ContentPart[] | null): boolean;
|
|
27
66
|
/** 所有事件的公共基座 */
|
|
28
67
|
export interface BaseEvent {
|
|
29
68
|
/** 事件时间戳(毫秒) */
|
package/dist/cjs/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAMA,WAAW;AACX,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AAEnE,kBAAkB;AAClB,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,aAAa;AACb,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/types.js
CHANGED
|
@@ -3,4 +3,38 @@
|
|
|
3
3
|
// Core 全局共享类型
|
|
4
4
|
// ============================================================
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.extractTextFromContent = extractTextFromContent;
|
|
7
|
+
exports.isMultimodalContent = isMultimodalContent;
|
|
8
|
+
// ---- ContentPart 辅助函数 ----
|
|
9
|
+
/**
|
|
10
|
+
* 从 Message.content 中提取纯文本(用于 Skill 路由、去重检测等场景)
|
|
11
|
+
* - string 直接返回
|
|
12
|
+
* - ContentPart[] 拼接所有 TextPart 和 FilePart 的文本
|
|
13
|
+
* - null 返回空字符串
|
|
14
|
+
*/
|
|
15
|
+
function extractTextFromContent(content) {
|
|
16
|
+
if (content == null)
|
|
17
|
+
return '';
|
|
18
|
+
if (typeof content === 'string')
|
|
19
|
+
return content;
|
|
20
|
+
return content
|
|
21
|
+
.map(part => {
|
|
22
|
+
if (part.type === 'text')
|
|
23
|
+
return part.text;
|
|
24
|
+
if (part.type === 'file')
|
|
25
|
+
return `[file: ${part.filename}]\n${part.content}`;
|
|
26
|
+
if (part.type === 'image')
|
|
27
|
+
return `[image: ${part.source.slice(0, 80)}]`;
|
|
28
|
+
return '';
|
|
29
|
+
})
|
|
30
|
+
.join('\n');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 判断消息内容是否为多模态(包含非文本部分)
|
|
34
|
+
*/
|
|
35
|
+
function isMultimodalContent(content) {
|
|
36
|
+
if (content == null || typeof content === 'string')
|
|
37
|
+
return false;
|
|
38
|
+
return content.some(part => part.type === 'image' || part.type === 'file');
|
|
39
|
+
}
|
|
6
40
|
//# sourceMappingURL=types.js.map
|
package/dist/cjs/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,cAAc;AACd,+DAA+D"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,cAAc;AACd,+DAA+D;;AA2E/D,wDAWC;AAKD,kDAGC;AA3BD,6BAA6B;AAE7B;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,OAAsC;IAC3E,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,OAAO,OAAO;SACX,GAAG,CAAC,IAAI,CAAC,EAAE;QACV,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;QAC3C,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,UAAU,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7E,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,WAAW,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;QACzE,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,OAAsC;IACxE,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACjE,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-counter.d.ts","sourceRoot":"","sources":["../../../src/utils/token-counter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"token-counter.d.ts","sourceRoot":"","sources":["../../../src/utils/token-counter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AA6BxD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAuBhD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAiC9D;AA0BD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD"}
|
|
@@ -72,7 +72,15 @@ function countMessageTokens(messages) {
|
|
|
72
72
|
total += countTokens(msg.role || '');
|
|
73
73
|
// content
|
|
74
74
|
if (msg.content) {
|
|
75
|
-
|
|
75
|
+
if (typeof msg.content === 'string') {
|
|
76
|
+
total += countTokens(msg.content);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// ContentPart[]:逐部分计算
|
|
80
|
+
for (const part of msg.content) {
|
|
81
|
+
total += countContentPartTokens(part);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
76
84
|
}
|
|
77
85
|
// tool_calls (序列化后的 token 数)
|
|
78
86
|
if (msg.tool_calls) {
|
|
@@ -90,6 +98,30 @@ function countMessageTokens(messages) {
|
|
|
90
98
|
total += 2;
|
|
91
99
|
return total;
|
|
92
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* 计算单个 ContentPart 的 token 估算值
|
|
103
|
+
* - TextPart: 精确计数
|
|
104
|
+
* - ImagePart: 按详情级别估算(参考 OpenAI Vision 定价)
|
|
105
|
+
* - low: ~85 tokens(512x512 固定)
|
|
106
|
+
* - high: ~170 tokens/tile(最多 4 tiles → ~680)
|
|
107
|
+
* - auto: 默认按 low 估算
|
|
108
|
+
* - FilePart: 计数文本内容
|
|
109
|
+
*/
|
|
110
|
+
function countContentPartTokens(part) {
|
|
111
|
+
switch (part.type) {
|
|
112
|
+
case 'text':
|
|
113
|
+
return countTokens(part.text);
|
|
114
|
+
case 'image':
|
|
115
|
+
// OpenAI Vision: low=85, high=170*tiles(1-4), auto≈85
|
|
116
|
+
if (part.detail === 'high')
|
|
117
|
+
return 680;
|
|
118
|
+
return 85;
|
|
119
|
+
case 'file':
|
|
120
|
+
return countTokens(part.content) + countTokens(part.filename);
|
|
121
|
+
default:
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
93
125
|
/**
|
|
94
126
|
* 估算文本 token 数(快速估算,不加载 tiktoken)
|
|
95
127
|
* 适用于对精度要求不高的场景,约 4 字符 = 1 token
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-counter.js","sourceRoot":"","sources":["../../../src/utils/token-counter.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,uCAAuC;AACvC,+DAA+D;;AAqC/D,kCAuBC;AAQD,
|
|
1
|
+
{"version":3,"file":"token-counter.js","sourceRoot":"","sources":["../../../src/utils/token-counter.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,6 +36,29 @@ export declare class AgentEngine {
|
|
|
36
36
|
* 获取会话历史副本(用于持久化保存)
|
|
37
37
|
*/
|
|
38
38
|
getHistorySnapshot(sessionId: string): Message[];
|
|
39
|
+
/**
|
|
40
|
+
* 从持久化存储加载会话历史(重启后恢复 Agent 上下文)
|
|
41
|
+
* 需要在 run() 之前调用
|
|
42
|
+
* @returns true 如果加载成功且有历史消息
|
|
43
|
+
*/
|
|
44
|
+
loadHistory(sessionId: string): Promise<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* 截断会话历史到指定位置(消息编辑场景)
|
|
47
|
+
* @param sessionId 会话 ID
|
|
48
|
+
* @param toIndex 保留的消息数量
|
|
49
|
+
* @returns 被截断掉的消息数量
|
|
50
|
+
*/
|
|
51
|
+
truncateHistory(sessionId: string, toIndex: number): number;
|
|
52
|
+
/**
|
|
53
|
+
* 从现有会话分叉创建新会话(对话分支场景)
|
|
54
|
+
* @param sourceSessionId 源会话 ID
|
|
55
|
+
* @param targetSessionId 目标会话 ID
|
|
56
|
+
* @param fromIndex 从源会话复制到哪个位置
|
|
57
|
+
* @returns 新会话中的消息数量
|
|
58
|
+
*/
|
|
59
|
+
forkHistory(sourceSessionId: string, targetSessionId: string, fromIndex?: number): number;
|
|
60
|
+
/** 获取会话历史的消息数量 */
|
|
61
|
+
getHistoryLength(sessionId: string): number;
|
|
39
62
|
/**
|
|
40
63
|
* 执行 Agent 任务(流式推送事件)
|
|
41
64
|
* 上层通过 for-await-of 消费事件流
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/agent/engine.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// ============================================================
|
|
4
4
|
// 职责:编排 HistoryManager、LLMCaller、ToolExecutor 完成 ReAct 循环
|
|
5
5
|
// 历史管理、LLM 调用、工具执行已分别抽离到独立模块
|
|
6
|
+
import { extractTextFromContent } from "../types.js";
|
|
6
7
|
import { HistoryManager } from "./history-manager.js";
|
|
7
8
|
import { LLMCaller } from "./llm-caller.js";
|
|
8
9
|
import { AgentToolExecutor } from "./tool-executor.js";
|
|
@@ -67,6 +68,7 @@ export class AgentEngine {
|
|
|
67
68
|
maxMessages: this.config.maxMessages,
|
|
68
69
|
contextBudget: this.config.contextBudget,
|
|
69
70
|
toolResultStore: this.config.toolResultStore,
|
|
71
|
+
persistence: this.config.historyPersistence,
|
|
70
72
|
});
|
|
71
73
|
this.llmCaller = new LLMCaller({
|
|
72
74
|
llmProvider: this.config.llmProvider,
|
|
@@ -123,6 +125,37 @@ export class AgentEngine {
|
|
|
123
125
|
getHistorySnapshot(sessionId) {
|
|
124
126
|
return this.historyManager.getHistorySnapshot(sessionId);
|
|
125
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* 从持久化存储加载会话历史(重启后恢复 Agent 上下文)
|
|
130
|
+
* 需要在 run() 之前调用
|
|
131
|
+
* @returns true 如果加载成功且有历史消息
|
|
132
|
+
*/
|
|
133
|
+
async loadHistory(sessionId) {
|
|
134
|
+
return this.historyManager.loadHistory(sessionId);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 截断会话历史到指定位置(消息编辑场景)
|
|
138
|
+
* @param sessionId 会话 ID
|
|
139
|
+
* @param toIndex 保留的消息数量
|
|
140
|
+
* @returns 被截断掉的消息数量
|
|
141
|
+
*/
|
|
142
|
+
truncateHistory(sessionId, toIndex) {
|
|
143
|
+
return this.historyManager.truncateHistory(sessionId, toIndex);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 从现有会话分叉创建新会话(对话分支场景)
|
|
147
|
+
* @param sourceSessionId 源会话 ID
|
|
148
|
+
* @param targetSessionId 目标会话 ID
|
|
149
|
+
* @param fromIndex 从源会话复制到哪个位置
|
|
150
|
+
* @returns 新会话中的消息数量
|
|
151
|
+
*/
|
|
152
|
+
forkHistory(sourceSessionId, targetSessionId, fromIndex) {
|
|
153
|
+
return this.historyManager.forkHistory(sourceSessionId, targetSessionId, fromIndex);
|
|
154
|
+
}
|
|
155
|
+
/** 获取会话历史的消息数量 */
|
|
156
|
+
getHistoryLength(sessionId) {
|
|
157
|
+
return this.historyManager.getHistoryLength(sessionId);
|
|
158
|
+
}
|
|
126
159
|
/**
|
|
127
160
|
* 执行 Agent 任务(流式推送事件)
|
|
128
161
|
* 上层通过 for-await-of 消费事件流
|
|
@@ -171,9 +204,11 @@ export class AgentEngine {
|
|
|
171
204
|
}
|
|
172
205
|
if (this.config.skillRouter) {
|
|
173
206
|
this.statusMap.set(sessionId, 'thinking');
|
|
174
|
-
|
|
207
|
+
// Skill 路由基于文本匹配,从多模态消息中提取文本
|
|
208
|
+
const routeText = typeof options.message === 'string' ? options.message : extractTextFromContent(options.message);
|
|
209
|
+
const routeResult = await this.config.skillRouter.route(routeText);
|
|
175
210
|
if (routeResult.skill) {
|
|
176
|
-
return { skillContent: routeResult.skill.content, actualMessage:
|
|
211
|
+
return { skillContent: routeResult.skill.content, actualMessage: options.message, skillMatched: true };
|
|
177
212
|
}
|
|
178
213
|
}
|
|
179
214
|
return { actualMessage: options.message, skillMatched: false };
|
|
@@ -226,12 +261,20 @@ export class AgentEngine {
|
|
|
226
261
|
// 则不再重复追加,避免 LLM 看到两条连续相同的 user 消息导致意图理解偏差
|
|
227
262
|
const history = this.historyManager.getHistory(sessionId);
|
|
228
263
|
const lastMsg = history.length > 0 ? history[history.length - 1] : null;
|
|
264
|
+
// 多模态消息去重:比较文本内容
|
|
265
|
+
const actualText = typeof actualMessage === 'string' ? actualMessage : extractTextFromContent(actualMessage);
|
|
229
266
|
const isDuplicateUserMessage = lastMsg?.role === 'user'
|
|
230
267
|
&& typeof lastMsg.content === 'string'
|
|
231
|
-
&& lastMsg.content ===
|
|
268
|
+
&& lastMsg.content === actualText;
|
|
269
|
+
// 非破坏性上下文投影(Context Collapse):
|
|
270
|
+
// 当历史 token 超过预算时,使用投影而非破坏性压缩,保留原始历史完整
|
|
271
|
+
const maxContextTokens = this.config.contextBudget?.maxContextTokens ?? 100000;
|
|
272
|
+
const projectedHistory = this.historyManager.getProjectedHistory
|
|
273
|
+
? this.historyManager.getProjectedHistory(sessionId, maxContextTokens)
|
|
274
|
+
: history;
|
|
232
275
|
return this.config.contextManager.buildMessages({
|
|
233
276
|
systemPrompt,
|
|
234
|
-
history,
|
|
277
|
+
history: projectedHistory,
|
|
235
278
|
userMessage: isDuplicateUserMessage ? undefined : actualMessage,
|
|
236
279
|
});
|
|
237
280
|
}
|
|
@@ -326,6 +369,25 @@ export class AgentEngine {
|
|
|
326
369
|
yield this.emitDone(state);
|
|
327
370
|
return;
|
|
328
371
|
}
|
|
372
|
+
// Token 预算检查
|
|
373
|
+
if (this.config.usageTracker && this.config.tokenBudget) {
|
|
374
|
+
const budgetCheck = this.config.usageTracker.checkBudget(state.sessionId, this.config.tokenBudget);
|
|
375
|
+
if (budgetCheck.exceeded) {
|
|
376
|
+
if (this.config.tokenBudget.onExceed === 'abort') {
|
|
377
|
+
console.warn(`[Engine] Token budget exceeded: ${budgetCheck.currentTokens}/${budgetCheck.maxTokens}, aborting session ${state.sessionId}`);
|
|
378
|
+
yield this.createEvent(state.sessionId, {
|
|
379
|
+
type: 'error',
|
|
380
|
+
error: `Token budget exceeded (${budgetCheck.currentTokens}/${budgetCheck.maxTokens} tokens). Task aborted to prevent cost overrun.`,
|
|
381
|
+
recoverable: false,
|
|
382
|
+
});
|
|
383
|
+
yield this.emitDone(state);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
console.warn(`[Engine] Token budget warning: ${budgetCheck.currentTokens}/${budgetCheck.maxTokens} for session ${state.sessionId}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
329
391
|
// Middleware.before + Hook: on_iteration_start
|
|
330
392
|
await this.runMiddlewarePhase('before', state);
|
|
331
393
|
await this.runHooks('on_iteration_start', {
|
|
@@ -379,7 +441,7 @@ export class AgentEngine {
|
|
|
379
441
|
}
|
|
380
442
|
this.historyManager.addHistory(state.sessionId, assistant);
|
|
381
443
|
if (assistant.content) {
|
|
382
|
-
state.lastContent = assistant.content;
|
|
444
|
+
state.lastContent = extractTextFromContent(assistant.content);
|
|
383
445
|
state.consecutiveSilentIterations = 0;
|
|
384
446
|
}
|
|
385
447
|
// 无 tool_calls → 检查是否提前停止(上一轮有工具调用,说明任务可能未完成)
|
|
@@ -720,6 +782,17 @@ export class AgentEngine {
|
|
|
720
782
|
// ---- 辅助 ----
|
|
721
783
|
emitDone(state) {
|
|
722
784
|
this.statusMap.set(state.sessionId, 'idle');
|
|
785
|
+
// 记录 Token 用量到 UsageTracker
|
|
786
|
+
if (this.config.usageTracker && state.totalUsage) {
|
|
787
|
+
const modelInfo = this.config.llmProvider.getModel();
|
|
788
|
+
this.config.usageTracker.record({
|
|
789
|
+
sessionId: state.sessionId,
|
|
790
|
+
provider: modelInfo.provider,
|
|
791
|
+
model: modelInfo.model,
|
|
792
|
+
usage: state.totalUsage,
|
|
793
|
+
iterations: state.iteration,
|
|
794
|
+
});
|
|
795
|
+
}
|
|
723
796
|
this.runHooks('on_complete', {
|
|
724
797
|
sessionId: state.sessionId,
|
|
725
798
|
iteration: state.iteration,
|