@gt-fe/eap-runtime 0.0.8
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 +323 -0
- package/dist/api/handlers/index.d.ts +3 -0
- package/dist/api/handlers/index.js +4 -0
- package/dist/api/handlers/invoke.handler.d.ts +77 -0
- package/dist/api/handlers/invoke.handler.js +411 -0
- package/dist/api/handlers/messages.handler.d.ts +53 -0
- package/dist/api/handlers/messages.handler.js +80 -0
- package/dist/api/handlers/stream.handler.d.ts +92 -0
- package/dist/api/handlers/stream.handler.js +432 -0
- package/dist/api/index.d.ts +3 -0
- package/dist/api/index.js +4 -0
- package/dist/api/middleware/auth.middleware.d.ts +96 -0
- package/dist/api/middleware/auth.middleware.js +158 -0
- package/dist/api/middleware/index.d.ts +1 -0
- package/dist/api/middleware/index.js +2 -0
- package/dist/api/routes/agent.routes.d.ts +44 -0
- package/dist/api/routes/agent.routes.js +204 -0
- package/dist/api/routes/index.d.ts +3 -0
- package/dist/api/routes/index.js +4 -0
- package/dist/api/routes/session.routes.d.ts +82 -0
- package/dist/api/routes/session.routes.js +169 -0
- package/dist/api/routes/task.routes.d.ts +75 -0
- package/dist/api/routes/task.routes.js +108 -0
- package/dist/checkpoint/checkpoint-serializer.d.ts +58 -0
- package/dist/checkpoint/checkpoint-serializer.js +81 -0
- package/dist/checkpoint/composite-checkpoint-saver.d.ts +42 -0
- package/dist/checkpoint/composite-checkpoint-saver.js +118 -0
- package/dist/checkpoint/contracts/checkpoint-saver.contract.d.ts +65 -0
- package/dist/checkpoint/contracts/checkpoint-saver.contract.js +12 -0
- package/dist/checkpoint/contracts/index.d.ts +1 -0
- package/dist/checkpoint/contracts/index.js +1 -0
- package/dist/checkpoint/file-checkpoint-saver.d.ts +19 -0
- package/dist/checkpoint/file-checkpoint-saver.js +98 -0
- package/dist/checkpoint/hybrid-checkpoint-saver.d.ts +130 -0
- package/dist/checkpoint/hybrid-checkpoint-saver.js +211 -0
- package/dist/checkpoint/in-memory-checkpoint-saver.d.ts +14 -0
- package/dist/checkpoint/in-memory-checkpoint-saver.js +46 -0
- package/dist/checkpoint/index.d.ts +16 -0
- package/dist/checkpoint/index.js +13 -0
- package/dist/checkpoint/mongo-checkpoint-saver.d.ts +38 -0
- package/dist/checkpoint/mongo-checkpoint-saver.js +56 -0
- package/dist/checkpoint/pg-checkpoint-saver.d.ts +59 -0
- package/dist/checkpoint/pg-checkpoint-saver.js +140 -0
- package/dist/checkpoint/redis-checkpoint-saver.d.ts +68 -0
- package/dist/checkpoint/redis-checkpoint-saver.js +173 -0
- package/dist/checkpoint/restore-checkpoint.d.ts +33 -0
- package/dist/checkpoint/restore-checkpoint.js +33 -0
- package/dist/common/agent-code.d.ts +10 -0
- package/dist/common/agent-code.js +12 -0
- package/dist/common/concurrency.d.ts +79 -0
- package/dist/common/concurrency.js +121 -0
- package/dist/common/health.d.ts +40 -0
- package/dist/common/health.js +37 -0
- package/dist/common/index.d.ts +5 -0
- package/dist/common/index.js +5 -0
- package/dist/common/logger.d.ts +34 -0
- package/dist/common/logger.js +38 -0
- package/dist/common/queue-consumer.d.ts +125 -0
- package/dist/common/queue-consumer.js +159 -0
- package/dist/common/trace-id.d.ts +2 -0
- package/dist/common/trace-id.js +8 -0
- package/dist/common/types.d.ts +104 -0
- package/dist/common/types.js +14 -0
- package/dist/contracts/index.d.ts +11 -0
- package/dist/contracts/index.js +10 -0
- package/dist/contracts/permission-checker.d.ts +10 -0
- package/dist/contracts/permission-checker.js +4 -0
- package/dist/contracts/trace-collector.d.ts +211 -0
- package/dist/contracts/trace-collector.js +13 -0
- package/dist/governance/governance-client.d.ts +38 -0
- package/dist/governance/governance-client.js +95 -0
- package/dist/governance/index.d.ts +7 -0
- package/dist/governance/index.js +5 -0
- package/dist/governance/permission-guard.d.ts +19 -0
- package/dist/governance/permission-guard.js +59 -0
- package/dist/graph/adapters/index.d.ts +3 -0
- package/dist/graph/adapters/index.js +3 -0
- package/dist/graph/adapters/langgraph-checkpointer.d.ts +40 -0
- package/dist/graph/adapters/langgraph-checkpointer.js +211 -0
- package/dist/graph/adapters/langgraph.adapter.d.ts +190 -0
- package/dist/graph/adapters/langgraph.adapter.js +1303 -0
- package/dist/graph/adapters/subgraph-compiler.d.ts +39 -0
- package/dist/graph/adapters/subgraph-compiler.js +248 -0
- package/dist/graph/condition-evaluator.d.ts +57 -0
- package/dist/graph/condition-evaluator.js +162 -0
- package/dist/graph/contracts/executable-graph.d.ts +340 -0
- package/dist/graph/contracts/executable-graph.js +10 -0
- package/dist/graph/contracts/index.d.ts +2 -0
- package/dist/graph/contracts/index.js +2 -0
- package/dist/graph/contracts/state-graph.contract.d.ts +76 -0
- package/dist/graph/contracts/state-graph.contract.js +11 -0
- package/dist/graph/hitl/hitl-handler.d.ts +199 -0
- package/dist/graph/hitl/hitl-handler.js +480 -0
- package/dist/graph/hitl/index.d.ts +1 -0
- package/dist/graph/hitl/index.js +1 -0
- package/dist/graph/index.d.ts +7 -0
- package/dist/graph/index.js +7 -0
- package/dist/graph/nodes/index.d.ts +2 -0
- package/dist/graph/nodes/index.js +2 -0
- package/dist/graph/nodes/llm-node.d.ts +182 -0
- package/dist/graph/nodes/llm-node.js +281 -0
- package/dist/graph/nodes/skill-bind-node.d.ts +32 -0
- package/dist/graph/nodes/skill-bind-node.js +116 -0
- package/dist/graph/nodes/tool-node.d.ts +75 -0
- package/dist/graph/nodes/tool-node.js +324 -0
- package/dist/graph/resolve-graph-prompt.d.ts +5 -0
- package/dist/graph/resolve-graph-prompt.js +75 -0
- package/dist/graph/retry/budget-aware-retry.d.ts +91 -0
- package/dist/graph/retry/budget-aware-retry.js +126 -0
- package/dist/graph/retry/index.d.ts +9 -0
- package/dist/graph/retry/index.js +8 -0
- package/dist/graph/retry/node-retry.d.ts +123 -0
- package/dist/graph/retry/node-retry.js +235 -0
- package/dist/graph/skill-audit-recorder.d.ts +126 -0
- package/dist/graph/skill-audit-recorder.js +114 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +32 -0
- package/dist/memory/compression/compression-stats.d.ts +109 -0
- package/dist/memory/compression/compression-stats.js +144 -0
- package/dist/memory/compression/compression.repository.d.ts +62 -0
- package/dist/memory/compression/compression.repository.js +71 -0
- package/dist/memory/compression/index.d.ts +10 -0
- package/dist/memory/compression/index.js +15 -0
- package/dist/memory/compression/llm-summarize.d.ts +58 -0
- package/dist/memory/compression/llm-summarize.js +192 -0
- package/dist/memory/compression/sliding-window.compression.d.ts +60 -0
- package/dist/memory/compression/sliding-window.compression.js +175 -0
- package/dist/memory/index.d.ts +4 -0
- package/dist/memory/index.js +7 -0
- package/dist/memory/long-term-memory.service.d.ts +94 -0
- package/dist/memory/long-term-memory.service.js +120 -0
- package/dist/memory/message-compression.service.d.ts +128 -0
- package/dist/memory/message-compression.service.js +69 -0
- package/dist/memory/pg-memory.repository.d.ts +44 -0
- package/dist/memory/pg-memory.repository.js +108 -0
- package/dist/memory/semantic-retrieval.service.d.ts +148 -0
- package/dist/memory/semantic-retrieval.service.js +238 -0
- package/dist/providers/echo-llm-provider.d.ts +10 -0
- package/dist/providers/echo-llm-provider.js +87 -0
- package/dist/providers/http-llm-provider.d.ts +35 -0
- package/dist/providers/http-llm-provider.js +404 -0
- package/dist/providers/index.d.ts +7 -0
- package/dist/providers/index.js +5 -0
- package/dist/providers/local-llm-provider.d.ts +27 -0
- package/dist/providers/local-llm-provider.js +105 -0
- package/dist/providers/resolve-llm-model.d.ts +13 -0
- package/dist/providers/resolve-llm-model.js +30 -0
- package/dist/providers/routing-llm-provider.d.ts +28 -0
- package/dist/providers/routing-llm-provider.js +79 -0
- package/dist/registry/agent-models.d.ts +1 -0
- package/dist/registry/agent-models.js +1 -0
- package/dist/registry/agent-registry-client.d.ts +56 -0
- package/dist/registry/agent-registry-client.js +36 -0
- package/dist/registry/definition-cache.d.ts +37 -0
- package/dist/registry/definition-cache.js +82 -0
- package/dist/registry/deployment-snapshot.d.ts +99 -0
- package/dist/registry/deployment-snapshot.js +542 -0
- package/dist/registry/graph-loader.d.ts +134 -0
- package/dist/registry/graph-loader.js +985 -0
- package/dist/registry/index.d.ts +9 -0
- package/dist/registry/index.js +9 -0
- package/dist/registry/preload-errors.d.ts +13 -0
- package/dist/registry/preload-errors.js +35 -0
- package/dist/registry/preload-flags.d.ts +22 -0
- package/dist/registry/preload-flags.js +44 -0
- package/dist/registry/skill-io-guard.d.ts +25 -0
- package/dist/registry/skill-io-guard.js +98 -0
- package/dist/registry/skill-tree.d.ts +27 -0
- package/dist/registry/skill-tree.js +183 -0
- package/dist/runtime/agent-runtime.d.ts +106 -0
- package/dist/runtime/agent-runtime.js +777 -0
- package/dist/runtime/dev-runtime.d.ts +69 -0
- package/dist/runtime/dev-runtime.js +199 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.js +3 -0
- package/dist/runtime/storage-profile.d.ts +50 -0
- package/dist/runtime/storage-profile.js +138 -0
- package/dist/runtime/types.d.ts +120 -0
- package/dist/runtime/types.js +9 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.js +161 -0
- package/dist/session/compression-middleware.d.ts +126 -0
- package/dist/session/compression-middleware.js +230 -0
- package/dist/session/file-message.repository.d.ts +25 -0
- package/dist/session/file-message.repository.js +78 -0
- package/dist/session/file-session.repository.d.ts +72 -0
- package/dist/session/file-session.repository.js +212 -0
- package/dist/session/index.d.ts +13 -0
- package/dist/session/index.js +12 -0
- package/dist/session/message.service.d.ts +80 -0
- package/dist/session/message.service.js +128 -0
- package/dist/session/persist-turn-messages.d.ts +145 -0
- package/dist/session/persist-turn-messages.js +325 -0
- package/dist/session/pg-message.repository.d.ts +49 -0
- package/dist/session/pg-message.repository.js +149 -0
- package/dist/session/pg-session.repository.d.ts +46 -0
- package/dist/session/pg-session.repository.js +117 -0
- package/dist/session/session-context.service.d.ts +49 -0
- package/dist/session/session-context.service.js +66 -0
- package/dist/session/session.service.d.ts +194 -0
- package/dist/session/session.service.js +166 -0
- package/dist/sse/connection-event-logger.d.ts +21 -0
- package/dist/sse/connection-event-logger.js +33 -0
- package/dist/sse/contracts/index.d.ts +1 -0
- package/dist/sse/contracts/index.js +1 -0
- package/dist/sse/contracts/sse-emitter.contract.d.ts +74 -0
- package/dist/sse/contracts/sse-emitter.contract.js +11 -0
- package/dist/sse/event-buffer.d.ts +20 -0
- package/dist/sse/event-buffer.js +45 -0
- package/dist/sse/events/code-events.d.ts +19 -0
- package/dist/sse/events/code-events.js +9 -0
- package/dist/sse/events/collaboration-events.d.ts +37 -0
- package/dist/sse/events/collaboration-events.js +11 -0
- package/dist/sse/events/connection-events.d.ts +13 -0
- package/dist/sse/events/connection-events.js +9 -0
- package/dist/sse/events/file-events.d.ts +29 -0
- package/dist/sse/events/file-events.js +10 -0
- package/dist/sse/events/hitl-events.d.ts +33 -0
- package/dist/sse/events/hitl-events.js +10 -0
- package/dist/sse/events/index.d.ts +107 -0
- package/dist/sse/events/index.js +96 -0
- package/dist/sse/events/plan-events.d.ts +38 -0
- package/dist/sse/events/plan-events.js +11 -0
- package/dist/sse/events/reasoning-events.d.ts +35 -0
- package/dist/sse/events/reasoning-events.js +13 -0
- package/dist/sse/events/response-events.d.ts +25 -0
- package/dist/sse/events/response-events.js +12 -0
- package/dist/sse/events/session-events.d.ts +43 -0
- package/dist/sse/events/session-events.js +12 -0
- package/dist/sse/events/skill-events.d.ts +48 -0
- package/dist/sse/events/skill-events.js +11 -0
- package/dist/sse/events/stats-events.d.ts +44 -0
- package/dist/sse/events/stats-events.js +12 -0
- package/dist/sse/events/tool-events.d.ts +68 -0
- package/dist/sse/events/tool-events.js +14 -0
- package/dist/sse/index.d.ts +8 -0
- package/dist/sse/index.js +8 -0
- package/dist/sse/sse-connection-manager.d.ts +116 -0
- package/dist/sse/sse-connection-manager.js +185 -0
- package/dist/sse/sse-emitter.d.ts +108 -0
- package/dist/sse/sse-emitter.js +210 -0
- package/dist/sse/sse-heartbeat.d.ts +58 -0
- package/dist/sse/sse-heartbeat.js +76 -0
- package/dist/sse/trace-collector.d.ts +60 -0
- package/dist/sse/trace-collector.js +107 -0
- package/dist/task/contracts/index.d.ts +2 -0
- package/dist/task/contracts/index.js +1 -0
- package/dist/task/contracts/task-manager.contract.d.ts +160 -0
- package/dist/task/contracts/task-manager.contract.js +10 -0
- package/dist/task/index.d.ts +7 -0
- package/dist/task/index.js +5 -0
- package/dist/task/pg-task.repository.d.ts +47 -0
- package/dist/task/pg-task.repository.js +131 -0
- package/dist/task/task-progress-tracker.d.ts +67 -0
- package/dist/task/task-progress-tracker.js +80 -0
- package/dist/task/task-timeout.d.ts +70 -0
- package/dist/task/task-timeout.js +116 -0
- package/dist/task/task.service.d.ts +84 -0
- package/dist/task/task.service.js +233 -0
- package/dist/token/compression-budget-integration.d.ts +145 -0
- package/dist/token/compression-budget-integration.js +185 -0
- package/dist/token/context-window-budget.d.ts +113 -0
- package/dist/token/context-window-budget.js +134 -0
- package/dist/token/contracts/index.d.ts +1 -0
- package/dist/token/contracts/index.js +1 -0
- package/dist/token/contracts/token-budget.contract.d.ts +77 -0
- package/dist/token/contracts/token-budget.contract.js +11 -0
- package/dist/token/index.d.ts +12 -0
- package/dist/token/index.js +10 -0
- package/dist/token/pg-token-budget.repository.d.ts +39 -0
- package/dist/token/pg-token-budget.repository.js +116 -0
- package/dist/token/session-budget-checker.d.ts +54 -0
- package/dist/token/session-budget-checker.js +72 -0
- package/dist/token/token-budget-guard.d.ts +66 -0
- package/dist/token/token-budget-guard.js +97 -0
- package/dist/token/token-budget.service.d.ts +86 -0
- package/dist/token/token-budget.service.js +130 -0
- package/dist/token/token-detail-mode.d.ts +73 -0
- package/dist/token/token-detail-mode.js +107 -0
- package/dist/token/token-estimator.d.ts +80 -0
- package/dist/token/token-estimator.js +134 -0
- package/dist/token/token-stats.service.d.ts +88 -0
- package/dist/token/token-stats.service.js +94 -0
- package/dist/tool/create-tool-executor.d.ts +33 -0
- package/dist/tool/create-tool-executor.js +60 -0
- package/dist/tool/dev-http-executor.d.ts +18 -0
- package/dist/tool/dev-http-executor.js +96 -0
- package/dist/tool/dev-mcp-executor.d.ts +29 -0
- package/dist/tool/dev-mcp-executor.js +84 -0
- package/dist/tool/dev-tool-executor.d.ts +23 -0
- package/dist/tool/dev-tool-executor.js +55 -0
- package/dist/tool/file-artifact.d.ts +11 -0
- package/dist/tool/file-artifact.js +90 -0
- package/dist/tool/http-tool-executor.d.ts +17 -0
- package/dist/tool/http-tool-executor.js +158 -0
- package/dist/tool/index.d.ts +18 -0
- package/dist/tool/index.js +17 -0
- package/dist/tool/loaded-tool-definition.d.ts +35 -0
- package/dist/tool/loaded-tool-definition.js +9 -0
- package/dist/tool/local-mcp-client.d.ts +23 -0
- package/dist/tool/local-mcp-client.js +225 -0
- package/dist/tool/local-tool-executor.d.ts +37 -0
- package/dist/tool/local-tool-executor.js +249 -0
- package/dist/tool/mcp-tool-executor.d.ts +23 -0
- package/dist/tool/mcp-tool-executor.js +160 -0
- package/dist/tool/mock-tool-executor.d.ts +28 -0
- package/dist/tool/mock-tool-executor.js +65 -0
- package/dist/tool/system-prompt-builder.d.ts +114 -0
- package/dist/tool/system-prompt-builder.js +213 -0
- package/dist/tool/tool-confirmation.d.ts +29 -0
- package/dist/tool/tool-confirmation.js +81 -0
- package/dist/tool/tool-event-emitter.d.ts +58 -0
- package/dist/tool/tool-event-emitter.js +154 -0
- package/dist/tool/tool-execution-router.d.ts +25 -0
- package/dist/tool/tool-execution-router.js +50 -0
- package/dist/tool/tool-executor.interface.d.ts +85 -0
- package/dist/tool/tool-executor.interface.js +7 -0
- package/dist/tool/tool-orchestrator.d.ts +22 -0
- package/dist/tool/tool-orchestrator.js +104 -0
- package/dist/tool/tool-result-injector.d.ts +64 -0
- package/dist/tool/tool-result-injector.js +65 -0
- package/dist/utils/format-error.d.ts +4 -0
- package/dist/utils/format-error.js +4 -0
- package/dist/utils/http-error.d.ts +11 -0
- package/dist/utils/http-error.js +24 -0
- package/package.json +56 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TaskService — ITaskManager 实现
|
|
3
|
+
*
|
|
4
|
+
* 管理 Task 生命周期:创建、状态流转、查询、Token消耗记录、进度跟踪。
|
|
5
|
+
* v1 使用 in-memory Map 存储,后续由 TaskRepository 替换。
|
|
6
|
+
*
|
|
7
|
+
* @see task-manager.contract.ts
|
|
8
|
+
* @see requirements.md Requirement 7 AC1-AC5
|
|
9
|
+
*/
|
|
10
|
+
import { randomUUID } from 'node:crypto';
|
|
11
|
+
import { TaskProgressTracker } from './task-progress-tracker.js';
|
|
12
|
+
// ─────────────────────────────────────────────
|
|
13
|
+
// State Transition Validation
|
|
14
|
+
// ─────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* 合法状态流转映射
|
|
17
|
+
*
|
|
18
|
+
* pending → running
|
|
19
|
+
* running → success | failed | timeout | token_exhausted
|
|
20
|
+
*/
|
|
21
|
+
const VALID_TRANSITIONS = {
|
|
22
|
+
pending: ['running'],
|
|
23
|
+
running: ['success', 'failed', 'timeout', 'token_exhausted', 'waiting_hitl'],
|
|
24
|
+
waiting_hitl: ['running', 'timeout', 'failed'],
|
|
25
|
+
success: [],
|
|
26
|
+
failed: [],
|
|
27
|
+
timeout: [],
|
|
28
|
+
token_exhausted: [],
|
|
29
|
+
};
|
|
30
|
+
// ─────────────────────────────────────────────
|
|
31
|
+
// In-Memory Repository (Default)
|
|
32
|
+
// ─────────────────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* InMemoryTaskRepository — 内存存储实现
|
|
35
|
+
*
|
|
36
|
+
* 用于开发/测试阶段,后续替换为 MySQL 实现。
|
|
37
|
+
*/
|
|
38
|
+
export class InMemoryTaskRepository {
|
|
39
|
+
store = new Map();
|
|
40
|
+
async save(task) {
|
|
41
|
+
this.store.set(task.id, { ...task });
|
|
42
|
+
}
|
|
43
|
+
async findById(id) {
|
|
44
|
+
const record = this.store.get(id);
|
|
45
|
+
return record ? { ...record } : null;
|
|
46
|
+
}
|
|
47
|
+
async update(task) {
|
|
48
|
+
this.store.set(task.id, { ...task });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// ─────────────────────────────────────────────
|
|
52
|
+
// TaskService Implementation
|
|
53
|
+
// ─────────────────────────────────────────────
|
|
54
|
+
export class TaskService {
|
|
55
|
+
repository;
|
|
56
|
+
progressTracker;
|
|
57
|
+
constructor(repository, progressTracker) {
|
|
58
|
+
this.repository = repository ?? new InMemoryTaskRepository();
|
|
59
|
+
this.progressTracker = progressTracker ?? new TaskProgressTracker();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 获取内部 progressTracker 实例(供 Graph 引擎更新节点进度)
|
|
63
|
+
*/
|
|
64
|
+
getProgressTracker() {
|
|
65
|
+
return this.progressTracker;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 创建新 Task,初始状态为 pending
|
|
69
|
+
*/
|
|
70
|
+
async create(params) {
|
|
71
|
+
const now = new Date().toISOString();
|
|
72
|
+
const id = params.id?.trim() || randomUUID();
|
|
73
|
+
// 上游复用 id 时禁止静默覆盖已有 Task
|
|
74
|
+
if (params.id?.trim()) {
|
|
75
|
+
const existing = await this.repository.findById(id);
|
|
76
|
+
if (existing && !existing.isDeleted) {
|
|
77
|
+
throw new Error(`Task already exists: ${id}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const task = {
|
|
81
|
+
id,
|
|
82
|
+
agentId: params.agentId,
|
|
83
|
+
sessionId: params.sessionId,
|
|
84
|
+
userId: params.userId,
|
|
85
|
+
correlationId: params.correlationId,
|
|
86
|
+
input: params.input,
|
|
87
|
+
output: null,
|
|
88
|
+
status: 'pending',
|
|
89
|
+
traceId: null,
|
|
90
|
+
tokenUsage: [],
|
|
91
|
+
cost: 0,
|
|
92
|
+
startedAt: null,
|
|
93
|
+
completedAt: null,
|
|
94
|
+
createdBy: params.userId,
|
|
95
|
+
createdAt: now,
|
|
96
|
+
updatedBy: params.userId,
|
|
97
|
+
updatedAt: now,
|
|
98
|
+
isDeleted: false,
|
|
99
|
+
};
|
|
100
|
+
await this.repository.save(task);
|
|
101
|
+
return task;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 获取完整 Task 记录(供 AgentRuntime.resumeHitl / fork 使用)
|
|
105
|
+
*/
|
|
106
|
+
async getTask(taskId) {
|
|
107
|
+
return this.repository.findById(taskId);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* 更新 Task 状态
|
|
111
|
+
*
|
|
112
|
+
* 验证状态流转合法性,设置时间戳:
|
|
113
|
+
* - pending→running: 设置 startedAt
|
|
114
|
+
* - running→终态: 设置 completedAt 和 output
|
|
115
|
+
*/
|
|
116
|
+
async updateStatus(taskId, status, output) {
|
|
117
|
+
const task = await this.findTaskOrThrow(taskId);
|
|
118
|
+
if (!this.isValidTransition(task.status, status)) {
|
|
119
|
+
throw new Error(`Invalid state transition: cannot transition from '${task.status}' to '${status}' for task '${taskId}'`);
|
|
120
|
+
}
|
|
121
|
+
const now = new Date().toISOString();
|
|
122
|
+
task.status = status;
|
|
123
|
+
if (status === 'running') {
|
|
124
|
+
task.startedAt = now;
|
|
125
|
+
}
|
|
126
|
+
// waiting_hitl:写入 output(含 hitlThreadId)供冷恢复;非终态、不设 completedAt
|
|
127
|
+
if (status === 'waiting_hitl' && output !== undefined) {
|
|
128
|
+
task.output = output;
|
|
129
|
+
}
|
|
130
|
+
if (status === 'success' || status === 'failed' || status === 'timeout' || status === 'token_exhausted') {
|
|
131
|
+
task.completedAt = now;
|
|
132
|
+
if (output !== undefined) {
|
|
133
|
+
task.output = output;
|
|
134
|
+
}
|
|
135
|
+
// 终态时清理进度跟踪
|
|
136
|
+
this.progressTracker.removeProgress(taskId);
|
|
137
|
+
}
|
|
138
|
+
await this.repository.update(task);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 仅当当前状态为 `from` 时流转。并发下 timeout/resume 抢占时返回 false,不抛错。
|
|
142
|
+
*/
|
|
143
|
+
async tryUpdateStatus(taskId, from, to, output) {
|
|
144
|
+
const task = await this.repository.findById(taskId);
|
|
145
|
+
if (!task || task.isDeleted || task.status !== from) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
if (!this.isValidTransition(from, to)) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
await this.updateStatus(taskId, to, output);
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 获取 Task 当前状态信息(供轮询使用)
|
|
156
|
+
*
|
|
157
|
+
* 优先返回 progressTracker 中的显式进度,回退到基于状态的粗粒度计算。
|
|
158
|
+
*/
|
|
159
|
+
async getStatus(taskId) {
|
|
160
|
+
const task = await this.findTaskOrThrow(taskId);
|
|
161
|
+
const trackedProgress = this.progressTracker.getProgress(taskId);
|
|
162
|
+
const progress = trackedProgress !== null
|
|
163
|
+
? trackedProgress.progress
|
|
164
|
+
: this.calculateProgress(task.status);
|
|
165
|
+
const duration = this.calculateDuration(task);
|
|
166
|
+
return {
|
|
167
|
+
status: task.status,
|
|
168
|
+
progress,
|
|
169
|
+
startedAt: task.startedAt,
|
|
170
|
+
duration,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 记录一次 Token 消耗,累加到 Task 的 tokenUsage 和 cost
|
|
175
|
+
*/
|
|
176
|
+
async recordTokenUsage(taskId, usage) {
|
|
177
|
+
const task = await this.findTaskOrThrow(taskId);
|
|
178
|
+
task.tokenUsage.push(usage);
|
|
179
|
+
task.cost += usage.costEstimate;
|
|
180
|
+
await this.repository.update(task);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* 更新 Task 执行进度(用于长任务轮询)
|
|
184
|
+
*
|
|
185
|
+
* 进度值会被 clamp 到 0-100 范围。仅 running 状态的 Task 可更新进度。
|
|
186
|
+
*/
|
|
187
|
+
async updateProgress(taskId, progress) {
|
|
188
|
+
const task = await this.findTaskOrThrow(taskId);
|
|
189
|
+
if (task.status !== 'running') {
|
|
190
|
+
throw new Error(`Cannot update progress for task '${taskId}' in '${task.status}' status (must be 'running')`);
|
|
191
|
+
}
|
|
192
|
+
this.progressTracker.updateProgress(taskId, progress);
|
|
193
|
+
}
|
|
194
|
+
// ─────────────────────────────────────────────
|
|
195
|
+
// Private Helpers
|
|
196
|
+
// ─────────────────────────────────────────────
|
|
197
|
+
async findTaskOrThrow(taskId) {
|
|
198
|
+
const task = await this.repository.findById(taskId);
|
|
199
|
+
if (!task) {
|
|
200
|
+
throw new Error(`Task not found: '${taskId}'`);
|
|
201
|
+
}
|
|
202
|
+
return task;
|
|
203
|
+
}
|
|
204
|
+
isValidTransition(from, to) {
|
|
205
|
+
return VALID_TRANSITIONS[from]?.includes(to) ?? false;
|
|
206
|
+
}
|
|
207
|
+
calculateProgress(status) {
|
|
208
|
+
switch (status) {
|
|
209
|
+
case 'pending':
|
|
210
|
+
return 0;
|
|
211
|
+
case 'running':
|
|
212
|
+
return 50;
|
|
213
|
+
case 'success':
|
|
214
|
+
case 'failed':
|
|
215
|
+
case 'timeout':
|
|
216
|
+
case 'token_exhausted':
|
|
217
|
+
return 100;
|
|
218
|
+
default:
|
|
219
|
+
return 0;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
calculateDuration(task) {
|
|
223
|
+
if (!task.startedAt) {
|
|
224
|
+
return 0;
|
|
225
|
+
}
|
|
226
|
+
const start = new Date(task.startedAt).getTime();
|
|
227
|
+
if (task.completedAt) {
|
|
228
|
+
return new Date(task.completedAt).getTime() - start;
|
|
229
|
+
}
|
|
230
|
+
// 仍在运行中,返回到当前的时长
|
|
231
|
+
return Date.now() - start;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CompressionBudgetIntegration — 压缩与预算集成
|
|
3
|
+
*
|
|
4
|
+
* 将 CompressionMiddleware 与 ContextWindowBudget 集成,
|
|
5
|
+
* 实现基于 Token 预算的自动压缩触发。
|
|
6
|
+
*
|
|
7
|
+
* @see context-window-budget.ts 上下文窗口预算
|
|
8
|
+
* @see compression-middleware.ts 压缩中间件
|
|
9
|
+
*/
|
|
10
|
+
import type { MessageRecord } from '../session/session.service.js';
|
|
11
|
+
import type { ILLMProvider } from '../graph/nodes/llm-node.js';
|
|
12
|
+
import type { ContextSource } from './context-window-budget.js';
|
|
13
|
+
import type { ICompressionRepository } from '../memory/compression/compression.repository.js';
|
|
14
|
+
import type { IMessageRepository } from '../session/session.service.js';
|
|
15
|
+
/**
|
|
16
|
+
* 集成配置
|
|
17
|
+
*/
|
|
18
|
+
export interface CompressionBudgetConfig {
|
|
19
|
+
/** 模型 context window 大小 */
|
|
20
|
+
modelContextWindow: number;
|
|
21
|
+
/** 历史消息占比阈值(超过此比例触发压缩,默认 0.8) */
|
|
22
|
+
historyThreshold?: number;
|
|
23
|
+
/** 压缩后目标占比(默认 0.5) */
|
|
24
|
+
targetRatio?: number;
|
|
25
|
+
/** 是否启用自动压缩(默认 true) */
|
|
26
|
+
autoCompress?: boolean;
|
|
27
|
+
/** LLM 配置 */
|
|
28
|
+
llmConfig?: {
|
|
29
|
+
provider?: ILLMProvider;
|
|
30
|
+
model?: string;
|
|
31
|
+
temperature?: number;
|
|
32
|
+
maxTokens?: number;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 预算检查结果
|
|
37
|
+
*/
|
|
38
|
+
export interface BudgetCheckResult {
|
|
39
|
+
/** 是否需要压缩 */
|
|
40
|
+
needsCompression: boolean;
|
|
41
|
+
/** 当前历史消息 Token 数 */
|
|
42
|
+
currentTokens: number;
|
|
43
|
+
/** 历史消息 Token 上限 */
|
|
44
|
+
maxTokens: number;
|
|
45
|
+
/** 使用率 */
|
|
46
|
+
usageRatio: number;
|
|
47
|
+
/** 压缩后目标 Token 数 */
|
|
48
|
+
targetTokens?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 压缩执行结果
|
|
52
|
+
*/
|
|
53
|
+
export interface CompressionExecutionResult {
|
|
54
|
+
/** 是否执行了压缩 */
|
|
55
|
+
compressed: boolean;
|
|
56
|
+
/** 原始消息数 */
|
|
57
|
+
originalCount: number;
|
|
58
|
+
/** 压缩后消息数 */
|
|
59
|
+
compressedCount?: number;
|
|
60
|
+
/** 原始 Token 数 */
|
|
61
|
+
originalTokens: number;
|
|
62
|
+
/** 压缩后 Token 数 */
|
|
63
|
+
compressedTokens?: number;
|
|
64
|
+
/** 压缩率 */
|
|
65
|
+
compressionRatio?: number;
|
|
66
|
+
/** 压缩耗时(毫秒) */
|
|
67
|
+
durationMs?: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* CompressionBudgetIntegration — 压缩与预算集成服务
|
|
71
|
+
*
|
|
72
|
+
* 功能:
|
|
73
|
+
* 1. 监控历史消息的 Token 使用情况
|
|
74
|
+
* 2. 当历史消息超出预算阈值时自动触发压缩
|
|
75
|
+
* 3. 压缩后确保历史消息在预算范围内
|
|
76
|
+
*/
|
|
77
|
+
export declare class CompressionBudgetIntegration {
|
|
78
|
+
private readonly budget;
|
|
79
|
+
private readonly compression;
|
|
80
|
+
private readonly config;
|
|
81
|
+
constructor(config: CompressionBudgetConfig, repository?: ICompressionRepository, messageRepository?: IMessageRepository);
|
|
82
|
+
/**
|
|
83
|
+
* 检查历史消息是否需要压缩
|
|
84
|
+
*
|
|
85
|
+
* @param messages - 历史消息列表
|
|
86
|
+
* @returns 预算检查结果
|
|
87
|
+
*/
|
|
88
|
+
checkBudget(messages: MessageRecord[]): BudgetCheckResult;
|
|
89
|
+
/**
|
|
90
|
+
* 处理历史消息(自动压缩)
|
|
91
|
+
*
|
|
92
|
+
* @param messages - 原始历史消息
|
|
93
|
+
* @param context - 上下文信息
|
|
94
|
+
* @returns 处理后的消息列表
|
|
95
|
+
*/
|
|
96
|
+
processHistory(messages: MessageRecord[], context: {
|
|
97
|
+
sessionId: string;
|
|
98
|
+
taskId?: string;
|
|
99
|
+
userId: string;
|
|
100
|
+
}): Promise<{
|
|
101
|
+
messages: MessageRecord[];
|
|
102
|
+
result: CompressionExecutionResult;
|
|
103
|
+
}>;
|
|
104
|
+
/**
|
|
105
|
+
* 获取预算分配情况
|
|
106
|
+
*
|
|
107
|
+
* @param usage - 各来源的已使用 Token 数
|
|
108
|
+
* @returns 预算分配结果
|
|
109
|
+
*/
|
|
110
|
+
getBudgetAllocation(usage?: Partial<Record<ContextSource, number>>): import("./context-window-budget.js").BudgetAllocation;
|
|
111
|
+
/**
|
|
112
|
+
* 获取配置
|
|
113
|
+
*/
|
|
114
|
+
getConfig(): {
|
|
115
|
+
modelContextWindow: number;
|
|
116
|
+
historyThreshold: number;
|
|
117
|
+
targetRatio: number;
|
|
118
|
+
autoCompress: boolean;
|
|
119
|
+
llmConfig?: CompressionBudgetConfig["llmConfig"];
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* MessageRecord 转 GraphMessage
|
|
123
|
+
*/
|
|
124
|
+
private toGraphMessages;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* 创建压缩预算集成服务
|
|
128
|
+
*
|
|
129
|
+
* @param config - 配置
|
|
130
|
+
* @param repository - 压缩记录存储(可选)
|
|
131
|
+
* @param messageRepository - 消息存储(可选)
|
|
132
|
+
* @returns CompressionBudgetIntegration 实例
|
|
133
|
+
*/
|
|
134
|
+
export declare function createCompressionBudgetIntegration(config: CompressionBudgetConfig, repository?: ICompressionRepository, messageRepository?: IMessageRepository): CompressionBudgetIntegration;
|
|
135
|
+
/**
|
|
136
|
+
* 创建带 LLM 能力的压缩预算集成服务
|
|
137
|
+
*
|
|
138
|
+
* @param provider - ILLMProvider 实例
|
|
139
|
+
* @param modelContextWindow - 模型 context window 大小
|
|
140
|
+
* @param config - 可选配置
|
|
141
|
+
* @param repository - 压缩记录存储(可选)
|
|
142
|
+
* @param messageRepository - 消息存储(可选)
|
|
143
|
+
* @returns CompressionBudgetIntegration 实例
|
|
144
|
+
*/
|
|
145
|
+
export declare function createCompressionBudgetIntegrationWithLLM(provider: ILLMProvider, modelContextWindow: number, config?: Partial<CompressionBudgetConfig>, repository?: ICompressionRepository, messageRepository?: IMessageRepository): CompressionBudgetIntegration;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CompressionBudgetIntegration — 压缩与预算集成
|
|
3
|
+
*
|
|
4
|
+
* 将 CompressionMiddleware 与 ContextWindowBudget 集成,
|
|
5
|
+
* 实现基于 Token 预算的自动压缩触发。
|
|
6
|
+
*
|
|
7
|
+
* @see context-window-budget.ts 上下文窗口预算
|
|
8
|
+
* @see compression-middleware.ts 压缩中间件
|
|
9
|
+
*/
|
|
10
|
+
import { createContextBudget } from './context-window-budget.js';
|
|
11
|
+
import { CompressionMiddleware, createCompressionMiddlewareWithLLM, } from '../session/compression-middleware.js';
|
|
12
|
+
import { estimateMessagesTokens } from '../memory/message-compression.service.js';
|
|
13
|
+
// ─────────────────────────────────────────────
|
|
14
|
+
// CompressionBudgetIntegration
|
|
15
|
+
// ─────────────────────────────────────────────
|
|
16
|
+
/**
|
|
17
|
+
* CompressionBudgetIntegration — 压缩与预算集成服务
|
|
18
|
+
*
|
|
19
|
+
* 功能:
|
|
20
|
+
* 1. 监控历史消息的 Token 使用情况
|
|
21
|
+
* 2. 当历史消息超出预算阈值时自动触发压缩
|
|
22
|
+
* 3. 压缩后确保历史消息在预算范围内
|
|
23
|
+
*/
|
|
24
|
+
export class CompressionBudgetIntegration {
|
|
25
|
+
budget;
|
|
26
|
+
compression;
|
|
27
|
+
config;
|
|
28
|
+
constructor(config, repository, messageRepository) {
|
|
29
|
+
this.config = {
|
|
30
|
+
modelContextWindow: config.modelContextWindow,
|
|
31
|
+
historyThreshold: config.historyThreshold ?? 0.8,
|
|
32
|
+
targetRatio: config.targetRatio ?? 0.5,
|
|
33
|
+
autoCompress: config.autoCompress ?? true,
|
|
34
|
+
llmConfig: config.llmConfig,
|
|
35
|
+
};
|
|
36
|
+
// 创建预算管理器
|
|
37
|
+
this.budget = createContextBudget(this.config.modelContextWindow);
|
|
38
|
+
// 创建压缩中间件
|
|
39
|
+
if (this.config.llmConfig?.provider) {
|
|
40
|
+
this.compression = createCompressionMiddlewareWithLLM(this.config.llmConfig.provider, {
|
|
41
|
+
llmConfig: this.config.llmConfig,
|
|
42
|
+
}, repository, messageRepository);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.compression = new CompressionMiddleware({}, undefined, repository, messageRepository);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 检查历史消息是否需要压缩
|
|
50
|
+
*
|
|
51
|
+
* @param messages - 历史消息列表
|
|
52
|
+
* @returns 预算检查结果
|
|
53
|
+
*/
|
|
54
|
+
checkBudget(messages) {
|
|
55
|
+
// 估算当前 Token 数
|
|
56
|
+
const graphMessages = this.toGraphMessages(messages);
|
|
57
|
+
const currentTokens = estimateMessagesTokens(graphMessages);
|
|
58
|
+
// 获取历史消息的 Token 上限
|
|
59
|
+
const maxTokens = this.budget.getMaxTokens('history');
|
|
60
|
+
// 计算使用率
|
|
61
|
+
const usageRatio = maxTokens > 0 ? currentTokens / maxTokens : 0;
|
|
62
|
+
// 检查是否超过阈值
|
|
63
|
+
const needsCompression = usageRatio > this.config.historyThreshold;
|
|
64
|
+
// 计算压缩目标
|
|
65
|
+
const targetTokens = needsCompression
|
|
66
|
+
? Math.floor(maxTokens * this.config.targetRatio)
|
|
67
|
+
: undefined;
|
|
68
|
+
return {
|
|
69
|
+
needsCompression,
|
|
70
|
+
currentTokens,
|
|
71
|
+
maxTokens,
|
|
72
|
+
usageRatio,
|
|
73
|
+
targetTokens,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 处理历史消息(自动压缩)
|
|
78
|
+
*
|
|
79
|
+
* @param messages - 原始历史消息
|
|
80
|
+
* @param context - 上下文信息
|
|
81
|
+
* @returns 处理后的消息列表
|
|
82
|
+
*/
|
|
83
|
+
async processHistory(messages, context) {
|
|
84
|
+
// 检查预算
|
|
85
|
+
const budgetCheck = this.checkBudget(messages);
|
|
86
|
+
// 如果不需要压缩或未启用自动压缩,直接返回
|
|
87
|
+
if (!budgetCheck.needsCompression || !this.config.autoCompress) {
|
|
88
|
+
return {
|
|
89
|
+
messages,
|
|
90
|
+
result: {
|
|
91
|
+
compressed: false,
|
|
92
|
+
originalCount: messages.length,
|
|
93
|
+
originalTokens: budgetCheck.currentTokens,
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// 执行压缩
|
|
98
|
+
const startTime = Date.now();
|
|
99
|
+
const compressedMessages = await this.compression.processMessages(messages, context);
|
|
100
|
+
const duration = Date.now() - startTime;
|
|
101
|
+
// 计算压缩后的 Token 数
|
|
102
|
+
const compressedGraphMessages = this.toGraphMessages(compressedMessages);
|
|
103
|
+
const compressedTokens = estimateMessagesTokens(compressedGraphMessages);
|
|
104
|
+
// 计算压缩率
|
|
105
|
+
const compressionRatio = budgetCheck.currentTokens > 0
|
|
106
|
+
? compressedTokens / budgetCheck.currentTokens
|
|
107
|
+
: 1;
|
|
108
|
+
return {
|
|
109
|
+
messages: compressedMessages,
|
|
110
|
+
result: {
|
|
111
|
+
compressed: true,
|
|
112
|
+
originalCount: messages.length,
|
|
113
|
+
compressedCount: compressedMessages.length,
|
|
114
|
+
originalTokens: budgetCheck.currentTokens,
|
|
115
|
+
compressedTokens,
|
|
116
|
+
compressionRatio,
|
|
117
|
+
durationMs: duration,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 获取预算分配情况
|
|
123
|
+
*
|
|
124
|
+
* @param usage - 各来源的已使用 Token 数
|
|
125
|
+
* @returns 预算分配结果
|
|
126
|
+
*/
|
|
127
|
+
getBudgetAllocation(usage) {
|
|
128
|
+
return this.budget.calculateAllocation(usage ?? {});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 获取配置
|
|
132
|
+
*/
|
|
133
|
+
getConfig() {
|
|
134
|
+
return { ...this.config };
|
|
135
|
+
}
|
|
136
|
+
// ─────────────────────────────────────────────
|
|
137
|
+
// Private
|
|
138
|
+
// ─────────────────────────────────────────────
|
|
139
|
+
/**
|
|
140
|
+
* MessageRecord 转 GraphMessage
|
|
141
|
+
*/
|
|
142
|
+
toGraphMessages(messages) {
|
|
143
|
+
return messages.map((m) => ({
|
|
144
|
+
role: m.role,
|
|
145
|
+
content: m.content,
|
|
146
|
+
toolCalls: m.toolCalls,
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// ─────────────────────────────────────────────
|
|
151
|
+
// 工厂函数
|
|
152
|
+
// ─────────────────────────────────────────────
|
|
153
|
+
/**
|
|
154
|
+
* 创建压缩预算集成服务
|
|
155
|
+
*
|
|
156
|
+
* @param config - 配置
|
|
157
|
+
* @param repository - 压缩记录存储(可选)
|
|
158
|
+
* @param messageRepository - 消息存储(可选)
|
|
159
|
+
* @returns CompressionBudgetIntegration 实例
|
|
160
|
+
*/
|
|
161
|
+
export function createCompressionBudgetIntegration(config, repository, messageRepository) {
|
|
162
|
+
return new CompressionBudgetIntegration(config, repository, messageRepository);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* 创建带 LLM 能力的压缩预算集成服务
|
|
166
|
+
*
|
|
167
|
+
* @param provider - ILLMProvider 实例
|
|
168
|
+
* @param modelContextWindow - 模型 context window 大小
|
|
169
|
+
* @param config - 可选配置
|
|
170
|
+
* @param repository - 压缩记录存储(可选)
|
|
171
|
+
* @param messageRepository - 消息存储(可选)
|
|
172
|
+
* @returns CompressionBudgetIntegration 实例
|
|
173
|
+
*/
|
|
174
|
+
export function createCompressionBudgetIntegrationWithLLM(provider, modelContextWindow, config, repository, messageRepository) {
|
|
175
|
+
return new CompressionBudgetIntegration({
|
|
176
|
+
...config,
|
|
177
|
+
modelContextWindow,
|
|
178
|
+
llmConfig: {
|
|
179
|
+
provider,
|
|
180
|
+
model: config?.llmConfig?.model ?? 'DeepSeek-V4-Pro',
|
|
181
|
+
temperature: config?.llmConfig?.temperature ?? 0.3,
|
|
182
|
+
maxTokens: config?.llmConfig?.maxTokens ?? 1024,
|
|
183
|
+
},
|
|
184
|
+
}, repository, messageRepository);
|
|
185
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContextWindowBudget — 上下文窗口预算分配
|
|
3
|
+
*
|
|
4
|
+
* 管理上下文窗口的 Token 分配,防止单一来源占满上下文。
|
|
5
|
+
* 支持配置历史消息、RAG 结果、Tool Schema 各占上下文窗口的比例上限。
|
|
6
|
+
*
|
|
7
|
+
* @see requirements.md Requirement 12.5
|
|
8
|
+
* @see token/token-budget.service.ts Token Budget 控制
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* 上下文来源类型
|
|
12
|
+
*/
|
|
13
|
+
export type ContextSource = 'history' | 'rag' | 'tools' | 'system' | 'memory';
|
|
14
|
+
/**
|
|
15
|
+
* 上下文窗口预算配置
|
|
16
|
+
*/
|
|
17
|
+
export interface ContextWindowBudgetConfig {
|
|
18
|
+
/** 模型 context window 总 Token 数 */
|
|
19
|
+
totalTokens: number;
|
|
20
|
+
/** 各来源的 Token 比例上限 */
|
|
21
|
+
sourceRatios: Record<ContextSource, number>;
|
|
22
|
+
/** 预留给模型输出的 Token 数(默认 20%) */
|
|
23
|
+
outputReserve: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 默认上下文窗口预算配置
|
|
27
|
+
*/
|
|
28
|
+
export declare const DEFAULT_CONTEXT_BUDGET_CONFIG: ContextWindowBudgetConfig;
|
|
29
|
+
/**
|
|
30
|
+
* 来源 Token 分配
|
|
31
|
+
*/
|
|
32
|
+
export interface SourceAllocation {
|
|
33
|
+
/** 来源类型 */
|
|
34
|
+
source: ContextSource;
|
|
35
|
+
/** 分配的 Token 上限 */
|
|
36
|
+
maxTokens: number;
|
|
37
|
+
/** 已使用的 Token 数 */
|
|
38
|
+
usedTokens: number;
|
|
39
|
+
/** 剩余可用 Token 数 */
|
|
40
|
+
remainingTokens: number;
|
|
41
|
+
/** 使用率(0-1) */
|
|
42
|
+
usageRatio: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 预算分配结果
|
|
46
|
+
*/
|
|
47
|
+
export interface BudgetAllocation {
|
|
48
|
+
/** 总 Token 数 */
|
|
49
|
+
totalTokens: number;
|
|
50
|
+
/** 可用 Token 数(扣除输出预留) */
|
|
51
|
+
availableTokens: number;
|
|
52
|
+
/** 各来源的分配情况 */
|
|
53
|
+
sources: SourceAllocation[];
|
|
54
|
+
/** 是否超限 */
|
|
55
|
+
isExceeded: boolean;
|
|
56
|
+
/** 超限的来源列表 */
|
|
57
|
+
exceededSources: ContextSource[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* ContextWindowBudget — 上下文窗口预算管理
|
|
61
|
+
*/
|
|
62
|
+
export declare class ContextWindowBudget {
|
|
63
|
+
private readonly config;
|
|
64
|
+
constructor(config?: Partial<ContextWindowBudgetConfig>);
|
|
65
|
+
/**
|
|
66
|
+
* 获取指定来源的 Token 上限
|
|
67
|
+
*
|
|
68
|
+
* @param source - 来源类型
|
|
69
|
+
* @returns Token 上限
|
|
70
|
+
*/
|
|
71
|
+
getMaxTokens(source: ContextSource): number;
|
|
72
|
+
/**
|
|
73
|
+
* 检查指定来源是否超限
|
|
74
|
+
*
|
|
75
|
+
* @param source - 来源类型
|
|
76
|
+
* @param usedTokens - 已使用的 Token 数
|
|
77
|
+
* @returns 是否超限
|
|
78
|
+
*/
|
|
79
|
+
isExceeded(source: ContextSource, usedTokens: number): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* 计算预算分配
|
|
82
|
+
*
|
|
83
|
+
* @param usage - 各来源的已使用 Token 数
|
|
84
|
+
* @returns 预算分配结果
|
|
85
|
+
*/
|
|
86
|
+
calculateAllocation(usage: Partial<Record<ContextSource, number>>): BudgetAllocation;
|
|
87
|
+
/**
|
|
88
|
+
* 裁剪消息以符合预算
|
|
89
|
+
*
|
|
90
|
+
* 如果历史消息超出预算,从前面开始删除旧消息。
|
|
91
|
+
*
|
|
92
|
+
* @param messages - 原始消息列表
|
|
93
|
+
* @param maxTokens - Token 上限
|
|
94
|
+
* @param estimateFn - Token 估算函数
|
|
95
|
+
* @returns 裁剪后的消息列表
|
|
96
|
+
*/
|
|
97
|
+
trimMessages<T extends {
|
|
98
|
+
role: string;
|
|
99
|
+
content: string;
|
|
100
|
+
}>(messages: T[], maxTokens: number, estimateFn: (messages: T[]) => number): T[];
|
|
101
|
+
/**
|
|
102
|
+
* 获取配置
|
|
103
|
+
*/
|
|
104
|
+
getConfig(): ContextWindowBudgetConfig;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 创建上下文窗口预算实例
|
|
108
|
+
*
|
|
109
|
+
* @param modelContextWindow - 模型的 context window 大小
|
|
110
|
+
* @param config - 可选的自定义配置
|
|
111
|
+
* @returns ContextWindowBudget 实例
|
|
112
|
+
*/
|
|
113
|
+
export declare function createContextBudget(modelContextWindow: number, config?: Partial<ContextWindowBudgetConfig>): ContextWindowBudget;
|