@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.
Files changed (326) hide show
  1. package/README.md +323 -0
  2. package/dist/api/handlers/index.d.ts +3 -0
  3. package/dist/api/handlers/index.js +4 -0
  4. package/dist/api/handlers/invoke.handler.d.ts +77 -0
  5. package/dist/api/handlers/invoke.handler.js +411 -0
  6. package/dist/api/handlers/messages.handler.d.ts +53 -0
  7. package/dist/api/handlers/messages.handler.js +80 -0
  8. package/dist/api/handlers/stream.handler.d.ts +92 -0
  9. package/dist/api/handlers/stream.handler.js +432 -0
  10. package/dist/api/index.d.ts +3 -0
  11. package/dist/api/index.js +4 -0
  12. package/dist/api/middleware/auth.middleware.d.ts +96 -0
  13. package/dist/api/middleware/auth.middleware.js +158 -0
  14. package/dist/api/middleware/index.d.ts +1 -0
  15. package/dist/api/middleware/index.js +2 -0
  16. package/dist/api/routes/agent.routes.d.ts +44 -0
  17. package/dist/api/routes/agent.routes.js +204 -0
  18. package/dist/api/routes/index.d.ts +3 -0
  19. package/dist/api/routes/index.js +4 -0
  20. package/dist/api/routes/session.routes.d.ts +82 -0
  21. package/dist/api/routes/session.routes.js +169 -0
  22. package/dist/api/routes/task.routes.d.ts +75 -0
  23. package/dist/api/routes/task.routes.js +108 -0
  24. package/dist/checkpoint/checkpoint-serializer.d.ts +58 -0
  25. package/dist/checkpoint/checkpoint-serializer.js +81 -0
  26. package/dist/checkpoint/composite-checkpoint-saver.d.ts +42 -0
  27. package/dist/checkpoint/composite-checkpoint-saver.js +118 -0
  28. package/dist/checkpoint/contracts/checkpoint-saver.contract.d.ts +65 -0
  29. package/dist/checkpoint/contracts/checkpoint-saver.contract.js +12 -0
  30. package/dist/checkpoint/contracts/index.d.ts +1 -0
  31. package/dist/checkpoint/contracts/index.js +1 -0
  32. package/dist/checkpoint/file-checkpoint-saver.d.ts +19 -0
  33. package/dist/checkpoint/file-checkpoint-saver.js +98 -0
  34. package/dist/checkpoint/hybrid-checkpoint-saver.d.ts +130 -0
  35. package/dist/checkpoint/hybrid-checkpoint-saver.js +211 -0
  36. package/dist/checkpoint/in-memory-checkpoint-saver.d.ts +14 -0
  37. package/dist/checkpoint/in-memory-checkpoint-saver.js +46 -0
  38. package/dist/checkpoint/index.d.ts +16 -0
  39. package/dist/checkpoint/index.js +13 -0
  40. package/dist/checkpoint/mongo-checkpoint-saver.d.ts +38 -0
  41. package/dist/checkpoint/mongo-checkpoint-saver.js +56 -0
  42. package/dist/checkpoint/pg-checkpoint-saver.d.ts +59 -0
  43. package/dist/checkpoint/pg-checkpoint-saver.js +140 -0
  44. package/dist/checkpoint/redis-checkpoint-saver.d.ts +68 -0
  45. package/dist/checkpoint/redis-checkpoint-saver.js +173 -0
  46. package/dist/checkpoint/restore-checkpoint.d.ts +33 -0
  47. package/dist/checkpoint/restore-checkpoint.js +33 -0
  48. package/dist/common/agent-code.d.ts +10 -0
  49. package/dist/common/agent-code.js +12 -0
  50. package/dist/common/concurrency.d.ts +79 -0
  51. package/dist/common/concurrency.js +121 -0
  52. package/dist/common/health.d.ts +40 -0
  53. package/dist/common/health.js +37 -0
  54. package/dist/common/index.d.ts +5 -0
  55. package/dist/common/index.js +5 -0
  56. package/dist/common/logger.d.ts +34 -0
  57. package/dist/common/logger.js +38 -0
  58. package/dist/common/queue-consumer.d.ts +125 -0
  59. package/dist/common/queue-consumer.js +159 -0
  60. package/dist/common/trace-id.d.ts +2 -0
  61. package/dist/common/trace-id.js +8 -0
  62. package/dist/common/types.d.ts +104 -0
  63. package/dist/common/types.js +14 -0
  64. package/dist/contracts/index.d.ts +11 -0
  65. package/dist/contracts/index.js +10 -0
  66. package/dist/contracts/permission-checker.d.ts +10 -0
  67. package/dist/contracts/permission-checker.js +4 -0
  68. package/dist/contracts/trace-collector.d.ts +211 -0
  69. package/dist/contracts/trace-collector.js +13 -0
  70. package/dist/governance/governance-client.d.ts +38 -0
  71. package/dist/governance/governance-client.js +95 -0
  72. package/dist/governance/index.d.ts +7 -0
  73. package/dist/governance/index.js +5 -0
  74. package/dist/governance/permission-guard.d.ts +19 -0
  75. package/dist/governance/permission-guard.js +59 -0
  76. package/dist/graph/adapters/index.d.ts +3 -0
  77. package/dist/graph/adapters/index.js +3 -0
  78. package/dist/graph/adapters/langgraph-checkpointer.d.ts +40 -0
  79. package/dist/graph/adapters/langgraph-checkpointer.js +211 -0
  80. package/dist/graph/adapters/langgraph.adapter.d.ts +190 -0
  81. package/dist/graph/adapters/langgraph.adapter.js +1303 -0
  82. package/dist/graph/adapters/subgraph-compiler.d.ts +39 -0
  83. package/dist/graph/adapters/subgraph-compiler.js +248 -0
  84. package/dist/graph/condition-evaluator.d.ts +57 -0
  85. package/dist/graph/condition-evaluator.js +162 -0
  86. package/dist/graph/contracts/executable-graph.d.ts +340 -0
  87. package/dist/graph/contracts/executable-graph.js +10 -0
  88. package/dist/graph/contracts/index.d.ts +2 -0
  89. package/dist/graph/contracts/index.js +2 -0
  90. package/dist/graph/contracts/state-graph.contract.d.ts +76 -0
  91. package/dist/graph/contracts/state-graph.contract.js +11 -0
  92. package/dist/graph/hitl/hitl-handler.d.ts +199 -0
  93. package/dist/graph/hitl/hitl-handler.js +480 -0
  94. package/dist/graph/hitl/index.d.ts +1 -0
  95. package/dist/graph/hitl/index.js +1 -0
  96. package/dist/graph/index.d.ts +7 -0
  97. package/dist/graph/index.js +7 -0
  98. package/dist/graph/nodes/index.d.ts +2 -0
  99. package/dist/graph/nodes/index.js +2 -0
  100. package/dist/graph/nodes/llm-node.d.ts +182 -0
  101. package/dist/graph/nodes/llm-node.js +281 -0
  102. package/dist/graph/nodes/skill-bind-node.d.ts +32 -0
  103. package/dist/graph/nodes/skill-bind-node.js +116 -0
  104. package/dist/graph/nodes/tool-node.d.ts +75 -0
  105. package/dist/graph/nodes/tool-node.js +324 -0
  106. package/dist/graph/resolve-graph-prompt.d.ts +5 -0
  107. package/dist/graph/resolve-graph-prompt.js +75 -0
  108. package/dist/graph/retry/budget-aware-retry.d.ts +91 -0
  109. package/dist/graph/retry/budget-aware-retry.js +126 -0
  110. package/dist/graph/retry/index.d.ts +9 -0
  111. package/dist/graph/retry/index.js +8 -0
  112. package/dist/graph/retry/node-retry.d.ts +123 -0
  113. package/dist/graph/retry/node-retry.js +235 -0
  114. package/dist/graph/skill-audit-recorder.d.ts +126 -0
  115. package/dist/graph/skill-audit-recorder.js +114 -0
  116. package/dist/index.d.ts +21 -0
  117. package/dist/index.js +32 -0
  118. package/dist/memory/compression/compression-stats.d.ts +109 -0
  119. package/dist/memory/compression/compression-stats.js +144 -0
  120. package/dist/memory/compression/compression.repository.d.ts +62 -0
  121. package/dist/memory/compression/compression.repository.js +71 -0
  122. package/dist/memory/compression/index.d.ts +10 -0
  123. package/dist/memory/compression/index.js +15 -0
  124. package/dist/memory/compression/llm-summarize.d.ts +58 -0
  125. package/dist/memory/compression/llm-summarize.js +192 -0
  126. package/dist/memory/compression/sliding-window.compression.d.ts +60 -0
  127. package/dist/memory/compression/sliding-window.compression.js +175 -0
  128. package/dist/memory/index.d.ts +4 -0
  129. package/dist/memory/index.js +7 -0
  130. package/dist/memory/long-term-memory.service.d.ts +94 -0
  131. package/dist/memory/long-term-memory.service.js +120 -0
  132. package/dist/memory/message-compression.service.d.ts +128 -0
  133. package/dist/memory/message-compression.service.js +69 -0
  134. package/dist/memory/pg-memory.repository.d.ts +44 -0
  135. package/dist/memory/pg-memory.repository.js +108 -0
  136. package/dist/memory/semantic-retrieval.service.d.ts +148 -0
  137. package/dist/memory/semantic-retrieval.service.js +238 -0
  138. package/dist/providers/echo-llm-provider.d.ts +10 -0
  139. package/dist/providers/echo-llm-provider.js +87 -0
  140. package/dist/providers/http-llm-provider.d.ts +35 -0
  141. package/dist/providers/http-llm-provider.js +404 -0
  142. package/dist/providers/index.d.ts +7 -0
  143. package/dist/providers/index.js +5 -0
  144. package/dist/providers/local-llm-provider.d.ts +27 -0
  145. package/dist/providers/local-llm-provider.js +105 -0
  146. package/dist/providers/resolve-llm-model.d.ts +13 -0
  147. package/dist/providers/resolve-llm-model.js +30 -0
  148. package/dist/providers/routing-llm-provider.d.ts +28 -0
  149. package/dist/providers/routing-llm-provider.js +79 -0
  150. package/dist/registry/agent-models.d.ts +1 -0
  151. package/dist/registry/agent-models.js +1 -0
  152. package/dist/registry/agent-registry-client.d.ts +56 -0
  153. package/dist/registry/agent-registry-client.js +36 -0
  154. package/dist/registry/definition-cache.d.ts +37 -0
  155. package/dist/registry/definition-cache.js +82 -0
  156. package/dist/registry/deployment-snapshot.d.ts +99 -0
  157. package/dist/registry/deployment-snapshot.js +542 -0
  158. package/dist/registry/graph-loader.d.ts +134 -0
  159. package/dist/registry/graph-loader.js +985 -0
  160. package/dist/registry/index.d.ts +9 -0
  161. package/dist/registry/index.js +9 -0
  162. package/dist/registry/preload-errors.d.ts +13 -0
  163. package/dist/registry/preload-errors.js +35 -0
  164. package/dist/registry/preload-flags.d.ts +22 -0
  165. package/dist/registry/preload-flags.js +44 -0
  166. package/dist/registry/skill-io-guard.d.ts +25 -0
  167. package/dist/registry/skill-io-guard.js +98 -0
  168. package/dist/registry/skill-tree.d.ts +27 -0
  169. package/dist/registry/skill-tree.js +183 -0
  170. package/dist/runtime/agent-runtime.d.ts +106 -0
  171. package/dist/runtime/agent-runtime.js +777 -0
  172. package/dist/runtime/dev-runtime.d.ts +69 -0
  173. package/dist/runtime/dev-runtime.js +199 -0
  174. package/dist/runtime/index.d.ts +4 -0
  175. package/dist/runtime/index.js +3 -0
  176. package/dist/runtime/storage-profile.d.ts +50 -0
  177. package/dist/runtime/storage-profile.js +138 -0
  178. package/dist/runtime/types.d.ts +120 -0
  179. package/dist/runtime/types.js +9 -0
  180. package/dist/server.d.ts +12 -0
  181. package/dist/server.js +161 -0
  182. package/dist/session/compression-middleware.d.ts +126 -0
  183. package/dist/session/compression-middleware.js +230 -0
  184. package/dist/session/file-message.repository.d.ts +25 -0
  185. package/dist/session/file-message.repository.js +78 -0
  186. package/dist/session/file-session.repository.d.ts +72 -0
  187. package/dist/session/file-session.repository.js +212 -0
  188. package/dist/session/index.d.ts +13 -0
  189. package/dist/session/index.js +12 -0
  190. package/dist/session/message.service.d.ts +80 -0
  191. package/dist/session/message.service.js +128 -0
  192. package/dist/session/persist-turn-messages.d.ts +145 -0
  193. package/dist/session/persist-turn-messages.js +325 -0
  194. package/dist/session/pg-message.repository.d.ts +49 -0
  195. package/dist/session/pg-message.repository.js +149 -0
  196. package/dist/session/pg-session.repository.d.ts +46 -0
  197. package/dist/session/pg-session.repository.js +117 -0
  198. package/dist/session/session-context.service.d.ts +49 -0
  199. package/dist/session/session-context.service.js +66 -0
  200. package/dist/session/session.service.d.ts +194 -0
  201. package/dist/session/session.service.js +166 -0
  202. package/dist/sse/connection-event-logger.d.ts +21 -0
  203. package/dist/sse/connection-event-logger.js +33 -0
  204. package/dist/sse/contracts/index.d.ts +1 -0
  205. package/dist/sse/contracts/index.js +1 -0
  206. package/dist/sse/contracts/sse-emitter.contract.d.ts +74 -0
  207. package/dist/sse/contracts/sse-emitter.contract.js +11 -0
  208. package/dist/sse/event-buffer.d.ts +20 -0
  209. package/dist/sse/event-buffer.js +45 -0
  210. package/dist/sse/events/code-events.d.ts +19 -0
  211. package/dist/sse/events/code-events.js +9 -0
  212. package/dist/sse/events/collaboration-events.d.ts +37 -0
  213. package/dist/sse/events/collaboration-events.js +11 -0
  214. package/dist/sse/events/connection-events.d.ts +13 -0
  215. package/dist/sse/events/connection-events.js +9 -0
  216. package/dist/sse/events/file-events.d.ts +29 -0
  217. package/dist/sse/events/file-events.js +10 -0
  218. package/dist/sse/events/hitl-events.d.ts +33 -0
  219. package/dist/sse/events/hitl-events.js +10 -0
  220. package/dist/sse/events/index.d.ts +107 -0
  221. package/dist/sse/events/index.js +96 -0
  222. package/dist/sse/events/plan-events.d.ts +38 -0
  223. package/dist/sse/events/plan-events.js +11 -0
  224. package/dist/sse/events/reasoning-events.d.ts +35 -0
  225. package/dist/sse/events/reasoning-events.js +13 -0
  226. package/dist/sse/events/response-events.d.ts +25 -0
  227. package/dist/sse/events/response-events.js +12 -0
  228. package/dist/sse/events/session-events.d.ts +43 -0
  229. package/dist/sse/events/session-events.js +12 -0
  230. package/dist/sse/events/skill-events.d.ts +48 -0
  231. package/dist/sse/events/skill-events.js +11 -0
  232. package/dist/sse/events/stats-events.d.ts +44 -0
  233. package/dist/sse/events/stats-events.js +12 -0
  234. package/dist/sse/events/tool-events.d.ts +68 -0
  235. package/dist/sse/events/tool-events.js +14 -0
  236. package/dist/sse/index.d.ts +8 -0
  237. package/dist/sse/index.js +8 -0
  238. package/dist/sse/sse-connection-manager.d.ts +116 -0
  239. package/dist/sse/sse-connection-manager.js +185 -0
  240. package/dist/sse/sse-emitter.d.ts +108 -0
  241. package/dist/sse/sse-emitter.js +210 -0
  242. package/dist/sse/sse-heartbeat.d.ts +58 -0
  243. package/dist/sse/sse-heartbeat.js +76 -0
  244. package/dist/sse/trace-collector.d.ts +60 -0
  245. package/dist/sse/trace-collector.js +107 -0
  246. package/dist/task/contracts/index.d.ts +2 -0
  247. package/dist/task/contracts/index.js +1 -0
  248. package/dist/task/contracts/task-manager.contract.d.ts +160 -0
  249. package/dist/task/contracts/task-manager.contract.js +10 -0
  250. package/dist/task/index.d.ts +7 -0
  251. package/dist/task/index.js +5 -0
  252. package/dist/task/pg-task.repository.d.ts +47 -0
  253. package/dist/task/pg-task.repository.js +131 -0
  254. package/dist/task/task-progress-tracker.d.ts +67 -0
  255. package/dist/task/task-progress-tracker.js +80 -0
  256. package/dist/task/task-timeout.d.ts +70 -0
  257. package/dist/task/task-timeout.js +116 -0
  258. package/dist/task/task.service.d.ts +84 -0
  259. package/dist/task/task.service.js +233 -0
  260. package/dist/token/compression-budget-integration.d.ts +145 -0
  261. package/dist/token/compression-budget-integration.js +185 -0
  262. package/dist/token/context-window-budget.d.ts +113 -0
  263. package/dist/token/context-window-budget.js +134 -0
  264. package/dist/token/contracts/index.d.ts +1 -0
  265. package/dist/token/contracts/index.js +1 -0
  266. package/dist/token/contracts/token-budget.contract.d.ts +77 -0
  267. package/dist/token/contracts/token-budget.contract.js +11 -0
  268. package/dist/token/index.d.ts +12 -0
  269. package/dist/token/index.js +10 -0
  270. package/dist/token/pg-token-budget.repository.d.ts +39 -0
  271. package/dist/token/pg-token-budget.repository.js +116 -0
  272. package/dist/token/session-budget-checker.d.ts +54 -0
  273. package/dist/token/session-budget-checker.js +72 -0
  274. package/dist/token/token-budget-guard.d.ts +66 -0
  275. package/dist/token/token-budget-guard.js +97 -0
  276. package/dist/token/token-budget.service.d.ts +86 -0
  277. package/dist/token/token-budget.service.js +130 -0
  278. package/dist/token/token-detail-mode.d.ts +73 -0
  279. package/dist/token/token-detail-mode.js +107 -0
  280. package/dist/token/token-estimator.d.ts +80 -0
  281. package/dist/token/token-estimator.js +134 -0
  282. package/dist/token/token-stats.service.d.ts +88 -0
  283. package/dist/token/token-stats.service.js +94 -0
  284. package/dist/tool/create-tool-executor.d.ts +33 -0
  285. package/dist/tool/create-tool-executor.js +60 -0
  286. package/dist/tool/dev-http-executor.d.ts +18 -0
  287. package/dist/tool/dev-http-executor.js +96 -0
  288. package/dist/tool/dev-mcp-executor.d.ts +29 -0
  289. package/dist/tool/dev-mcp-executor.js +84 -0
  290. package/dist/tool/dev-tool-executor.d.ts +23 -0
  291. package/dist/tool/dev-tool-executor.js +55 -0
  292. package/dist/tool/file-artifact.d.ts +11 -0
  293. package/dist/tool/file-artifact.js +90 -0
  294. package/dist/tool/http-tool-executor.d.ts +17 -0
  295. package/dist/tool/http-tool-executor.js +158 -0
  296. package/dist/tool/index.d.ts +18 -0
  297. package/dist/tool/index.js +17 -0
  298. package/dist/tool/loaded-tool-definition.d.ts +35 -0
  299. package/dist/tool/loaded-tool-definition.js +9 -0
  300. package/dist/tool/local-mcp-client.d.ts +23 -0
  301. package/dist/tool/local-mcp-client.js +225 -0
  302. package/dist/tool/local-tool-executor.d.ts +37 -0
  303. package/dist/tool/local-tool-executor.js +249 -0
  304. package/dist/tool/mcp-tool-executor.d.ts +23 -0
  305. package/dist/tool/mcp-tool-executor.js +160 -0
  306. package/dist/tool/mock-tool-executor.d.ts +28 -0
  307. package/dist/tool/mock-tool-executor.js +65 -0
  308. package/dist/tool/system-prompt-builder.d.ts +114 -0
  309. package/dist/tool/system-prompt-builder.js +213 -0
  310. package/dist/tool/tool-confirmation.d.ts +29 -0
  311. package/dist/tool/tool-confirmation.js +81 -0
  312. package/dist/tool/tool-event-emitter.d.ts +58 -0
  313. package/dist/tool/tool-event-emitter.js +154 -0
  314. package/dist/tool/tool-execution-router.d.ts +25 -0
  315. package/dist/tool/tool-execution-router.js +50 -0
  316. package/dist/tool/tool-executor.interface.d.ts +85 -0
  317. package/dist/tool/tool-executor.interface.js +7 -0
  318. package/dist/tool/tool-orchestrator.d.ts +22 -0
  319. package/dist/tool/tool-orchestrator.js +104 -0
  320. package/dist/tool/tool-result-injector.d.ts +64 -0
  321. package/dist/tool/tool-result-injector.js +65 -0
  322. package/dist/utils/format-error.d.ts +4 -0
  323. package/dist/utils/format-error.js +4 -0
  324. package/dist/utils/http-error.d.ts +11 -0
  325. package/dist/utils/http-error.js +24 -0
  326. package/package.json +56 -0
@@ -0,0 +1,60 @@
1
+ /**
2
+ * SlidingWindowCompression — 滑动窗口 + LLM 摘要压缩策略
3
+ *
4
+ * 压缩策略:
5
+ * 1. 保留最近 N 轮对话(preserveRecentRounds)
6
+ * 2. 将历史部分用 LLM 生成摘要
7
+ * 3. 用摘要 + 最近 N 轮 替换原始消息
8
+ *
9
+ * @see message-compression.service.ts 压缩接口定义
10
+ * @see requirements.md Requirement 4.3
11
+ */
12
+ import type { GraphMessage } from '../../graph/contracts/executable-graph.js';
13
+ import type { CompressionConfig, CompressionResult, IMessageCompressionService } from '../message-compression.service.js';
14
+ /**
15
+ * LLM 摘要函数接口
16
+ *
17
+ * 由外部注入,支持不同的 LLM 实现。
18
+ */
19
+ export type SummarizeFunction = (messages: GraphMessage[]) => Promise<string>;
20
+ export declare class SlidingWindowCompression implements IMessageCompressionService {
21
+ private readonly config;
22
+ private readonly summarize;
23
+ constructor(config?: Partial<CompressionConfig>, summarize?: SummarizeFunction);
24
+ /**
25
+ * 检查是否需要压缩
26
+ */
27
+ checkCompression(messages: GraphMessage[], config?: Partial<CompressionConfig>): CompressionResult;
28
+ /**
29
+ * 执行消息压缩
30
+ *
31
+ * 滑动窗口策略:
32
+ * 1. 找到最近 N 轮的起始位置
33
+ * 2. 将历史部分用 LLM 生成摘要
34
+ * 3. 用摘要 + 最近 N 轮替换原始消息
35
+ */
36
+ compress(messages: GraphMessage[], config?: Partial<CompressionConfig>): Promise<GraphMessage[]>;
37
+ /**
38
+ * 估算消息的 Token 数
39
+ */
40
+ estimateTokens(messages: GraphMessage[]): number;
41
+ /**
42
+ * 找到最近 N 轮的起始位置
43
+ *
44
+ * 从后往前数 N 个 user 消息,返回分割点索引。
45
+ */
46
+ private findSplitIndex;
47
+ }
48
+ /**
49
+ * 截断压缩策略
50
+ *
51
+ * 直接丢弃旧消息,只保留最近 N 条。
52
+ * 简单但会丢失上下文,不推荐用于生产环境。
53
+ */
54
+ export declare class TruncateCompression implements IMessageCompressionService {
55
+ private readonly config;
56
+ constructor(config?: Partial<CompressionConfig>);
57
+ checkCompression(messages: GraphMessage[], config?: Partial<CompressionConfig>): CompressionResult;
58
+ compress(messages: GraphMessage[], config?: Partial<CompressionConfig>): Promise<GraphMessage[]>;
59
+ estimateTokens(messages: GraphMessage[]): number;
60
+ }
@@ -0,0 +1,175 @@
1
+ /**
2
+ * SlidingWindowCompression — 滑动窗口 + LLM 摘要压缩策略
3
+ *
4
+ * 压缩策略:
5
+ * 1. 保留最近 N 轮对话(preserveRecentRounds)
6
+ * 2. 将历史部分用 LLM 生成摘要
7
+ * 3. 用摘要 + 最近 N 轮 替换原始消息
8
+ *
9
+ * @see message-compression.service.ts 压缩接口定义
10
+ * @see requirements.md Requirement 4.3
11
+ */
12
+ import { DEFAULT_COMPRESSION_CONFIG, estimateMessagesTokens, countRounds, } from '../message-compression.service.js';
13
+ /**
14
+ * 默认摘要函数(占位)
15
+ *
16
+ * 实际使用时应注入真实的 LLM 摘要函数。
17
+ */
18
+ async function defaultSummarize(messages) {
19
+ // 提取消息内容作为简单摘要
20
+ const contents = messages
21
+ .filter((m) => m.role === 'user' || m.role === 'assistant')
22
+ .map((m) => `${m.role}: ${m.content.substring(0, 100)}`)
23
+ .join('\n');
24
+ return `[对话摘要]\n${contents}`;
25
+ }
26
+ // ─────────────────────────────────────────────
27
+ // SlidingWindowCompression
28
+ // ─────────────────────────────────────────────
29
+ export class SlidingWindowCompression {
30
+ config;
31
+ summarize;
32
+ constructor(config, summarize) {
33
+ this.config = { ...DEFAULT_COMPRESSION_CONFIG, ...config };
34
+ this.summarize = summarize ?? defaultSummarize;
35
+ }
36
+ /**
37
+ * 检查是否需要压缩
38
+ */
39
+ checkCompression(messages, config) {
40
+ const mergedConfig = { ...this.config, ...config };
41
+ const currentTokens = this.estimateTokens(messages);
42
+ const currentRounds = countRounds(messages);
43
+ // 检查 Token 数是否超限
44
+ if (currentTokens > mergedConfig.maxTokens) {
45
+ return {
46
+ needsCompression: true,
47
+ reason: 'token-exceeded',
48
+ currentTokens,
49
+ currentRounds,
50
+ };
51
+ }
52
+ // 检查轮次是否超限
53
+ if (currentRounds > mergedConfig.maxRounds) {
54
+ return {
55
+ needsCompression: true,
56
+ reason: 'rounds-exceeded',
57
+ currentTokens,
58
+ currentRounds,
59
+ };
60
+ }
61
+ return {
62
+ needsCompression: false,
63
+ currentTokens,
64
+ currentRounds,
65
+ };
66
+ }
67
+ /**
68
+ * 执行消息压缩
69
+ *
70
+ * 滑动窗口策略:
71
+ * 1. 找到最近 N 轮的起始位置
72
+ * 2. 将历史部分用 LLM 生成摘要
73
+ * 3. 用摘要 + 最近 N 轮替换原始消息
74
+ */
75
+ async compress(messages, config) {
76
+ const mergedConfig = { ...this.config, ...config };
77
+ // 1. 找到最近 N 轮的起始位置
78
+ const splitIndex = this.findSplitIndex(messages, mergedConfig.preserveRecentRounds);
79
+ // 如果消息太少,不需要压缩
80
+ if (splitIndex <= 0) {
81
+ return messages;
82
+ }
83
+ // 2. 分割消息:历史部分 + 最近部分
84
+ const historyMessages = messages.slice(0, splitIndex);
85
+ const recentMessages = messages.slice(splitIndex);
86
+ // 3. 用 LLM 生成摘要
87
+ const summary = await this.summarize(historyMessages);
88
+ // 4. 构造压缩后的消息列表
89
+ const compressedMessages = [
90
+ // 摘要作为 system 消息
91
+ {
92
+ role: 'system',
93
+ content: `[对话历史摘要]\n${summary}`,
94
+ },
95
+ // 保留最近 N 轮
96
+ ...recentMessages,
97
+ ];
98
+ return compressedMessages;
99
+ }
100
+ /**
101
+ * 估算消息的 Token 数
102
+ */
103
+ estimateTokens(messages) {
104
+ return estimateMessagesTokens(messages);
105
+ }
106
+ /**
107
+ * 找到最近 N 轮的起始位置
108
+ *
109
+ * 从后往前数 N 个 user 消息,返回分割点索引。
110
+ */
111
+ findSplitIndex(messages, preserveRounds) {
112
+ let userCount = 0;
113
+ for (let i = messages.length - 1; i >= 0; i--) {
114
+ if (messages[i].role === 'user') {
115
+ userCount++;
116
+ if (userCount >= preserveRounds) {
117
+ return i;
118
+ }
119
+ }
120
+ }
121
+ // 如果消息轮次不足,返回 0(不压缩)
122
+ return 0;
123
+ }
124
+ }
125
+ // ─────────────────────────────────────────────
126
+ // TruncateCompression — 截断策略(简单但不推荐)
127
+ // ─────────────────────────────────────────────
128
+ /**
129
+ * 截断压缩策略
130
+ *
131
+ * 直接丢弃旧消息,只保留最近 N 条。
132
+ * 简单但会丢失上下文,不推荐用于生产环境。
133
+ */
134
+ export class TruncateCompression {
135
+ config;
136
+ constructor(config) {
137
+ this.config = { ...DEFAULT_COMPRESSION_CONFIG, ...config };
138
+ }
139
+ checkCompression(messages, config) {
140
+ const mergedConfig = { ...this.config, ...config };
141
+ const currentTokens = this.estimateTokens(messages);
142
+ const currentRounds = countRounds(messages);
143
+ if (currentTokens > mergedConfig.maxTokens || currentRounds > mergedConfig.maxRounds) {
144
+ return {
145
+ needsCompression: true,
146
+ reason: currentTokens > mergedConfig.maxTokens ? 'token-exceeded' : 'rounds-exceeded',
147
+ currentTokens,
148
+ currentRounds,
149
+ };
150
+ }
151
+ return {
152
+ needsCompression: false,
153
+ currentTokens,
154
+ currentRounds,
155
+ };
156
+ }
157
+ async compress(messages, config) {
158
+ const mergedConfig = { ...this.config, ...config };
159
+ const preserveCount = mergedConfig.preserveRecentRounds * 2; // 每轮 2 条消息
160
+ if (messages.length <= preserveCount) {
161
+ return messages;
162
+ }
163
+ // 截断:只保留最近 N 条消息
164
+ const truncated = messages.slice(-preserveCount);
165
+ // 添加截断标记
166
+ const marker = {
167
+ role: 'system',
168
+ content: `[注意:以下对话之前的历史已被截断,共丢失 ${messages.length - truncated.length} 条消息]`,
169
+ };
170
+ return [marker, ...truncated];
171
+ }
172
+ estimateTokens(messages) {
173
+ return estimateMessagesTokens(messages);
174
+ }
175
+ }
@@ -0,0 +1,4 @@
1
+ export { LongTermMemoryService, InMemoryMemoryRepository, type IMemoryRepository, type MemoryRecord, type MemoryType, type CompressionResult, } from './long-term-memory.service.js';
2
+ export { PostgresMemoryRepository } from './pg-memory.repository.js';
3
+ export { SlidingWindowCompression, TruncateCompression, type IMessageCompressionService, type CompressionConfig, type SummarizeFunction, DEFAULT_COMPRESSION_CONFIG, estimateMessagesTokens, countRounds, } from './compression/index.js';
4
+ export { SemanticRetrievalService, InMemoryVectorStore, type RetrievalConfig, type RetrievalStrategy, type RetrievalResult, type IVectorStore, type VectorResult, type EmbeddingFunction, DEFAULT_RETRIEVAL_CONFIG, } from './semantic-retrieval.service.js';
@@ -0,0 +1,7 @@
1
+ // Memory Management — 长期记忆服务
2
+ export { LongTermMemoryService, InMemoryMemoryRepository, } from './long-term-memory.service.js';
3
+ export { PostgresMemoryRepository } from './pg-memory.repository.js';
4
+ // 消息压缩模块
5
+ export { SlidingWindowCompression, TruncateCompression, DEFAULT_COMPRESSION_CONFIG, estimateMessagesTokens, countRounds, } from './compression/index.js';
6
+ // 语义检索模块
7
+ export { SemanticRetrievalService, InMemoryVectorStore, DEFAULT_RETRIEVAL_CONFIG, } from './semantic-retrieval.service.js';
@@ -0,0 +1,94 @@
1
+ /**
2
+ * LongTermMemoryService — 跨 Session 长期记忆管理
3
+ *
4
+ * 功能:
5
+ * - store: 存储用户偏好/摘要/事实
6
+ * - retrieve: 按相关性检索记忆
7
+ * - forget: 删除指定记忆
8
+ * - compress: 判断消息是否超阈值需要压缩(实际 LLM 摘要为外部关注)
9
+ * - injectMemories: 将相关记忆注入 GraphState
10
+ *
11
+ * @see design.md §1.1 记忆管理
12
+ * @see design.md §1.3 memories 表
13
+ */
14
+ import type { GraphState, GraphMessage } from '../graph/contracts/executable-graph.js';
15
+ /** 记忆类型 */
16
+ export type MemoryType = 'preference' | 'summary' | 'fact';
17
+ /**
18
+ * MemoryRecord — 对应 memories 表
19
+ */
20
+ export interface MemoryRecord {
21
+ id: string;
22
+ userId: string;
23
+ agentCode: string;
24
+ type: MemoryType;
25
+ content: string;
26
+ relevanceScore: number;
27
+ createdBy: string;
28
+ createdAt: string;
29
+ updatedBy: string;
30
+ updatedAt: string;
31
+ isDeleted: boolean;
32
+ deletedBy?: string | null;
33
+ deletedAt?: string | null;
34
+ }
35
+ /**
36
+ * compress 方法的返回值
37
+ */
38
+ export interface CompressionResult {
39
+ /** 是否需要压缩 */
40
+ needsCompression: boolean;
41
+ /** 当前消息数 */
42
+ messageCount: number;
43
+ /** 阈值 */
44
+ threshold: number;
45
+ }
46
+ /**
47
+ * IMemoryRepository — 记忆持久化接口
48
+ */
49
+ export interface IMemoryRepository {
50
+ save(record: MemoryRecord): Promise<void>;
51
+ findByUserAndAgent(userId: string, agentCode: string, limit?: number): Promise<MemoryRecord[]>;
52
+ delete(id: string): Promise<void>;
53
+ update(record: MemoryRecord): Promise<void>;
54
+ }
55
+ /**
56
+ * InMemoryMemoryRepository — Map-based 内存实现
57
+ *
58
+ * 开发/测试用,生产由 PostgresMemoryRepository 替换
59
+ */
60
+ export declare class InMemoryMemoryRepository implements IMemoryRepository {
61
+ private readonly store;
62
+ save(record: MemoryRecord): Promise<void>;
63
+ findByUserAndAgent(userId: string, agentCode: string, limit?: number): Promise<MemoryRecord[]>;
64
+ delete(id: string): Promise<void>;
65
+ update(record: MemoryRecord): Promise<void>;
66
+ }
67
+ export declare class LongTermMemoryService {
68
+ private readonly repository;
69
+ constructor(repository?: IMemoryRepository);
70
+ /**
71
+ * 存储一条记忆
72
+ */
73
+ store(userId: string, agentCode: string, type: MemoryType, content: string, relevanceScore?: number): Promise<MemoryRecord>;
74
+ /**
75
+ * 检索记忆,按 relevanceScore 降序排列
76
+ */
77
+ retrieve(userId: string, agentCode: string, limit?: number): Promise<MemoryRecord[]>;
78
+ /**
79
+ * 删除(遗忘)一条记忆
80
+ */
81
+ forget(memoryId: string): Promise<void>;
82
+ /**
83
+ * 判断消息是否超阈值需要压缩
84
+ *
85
+ * ponytail: 实际 LLM summarize 是外部关注,这里只返回"是否需要"标志
86
+ */
87
+ compress(messages: GraphMessage[], threshold: number): CompressionResult;
88
+ /**
89
+ * 将相关记忆注入 GraphState
90
+ *
91
+ * 从长期记忆中加载相关上下文,以 system 消息的形式注入到 state.messages 开头。
92
+ */
93
+ injectMemories(state: GraphState, userId: string, agentCode: string): Promise<GraphState>;
94
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * LongTermMemoryService — 跨 Session 长期记忆管理
3
+ *
4
+ * 功能:
5
+ * - store: 存储用户偏好/摘要/事实
6
+ * - retrieve: 按相关性检索记忆
7
+ * - forget: 删除指定记忆
8
+ * - compress: 判断消息是否超阈值需要压缩(实际 LLM 摘要为外部关注)
9
+ * - injectMemories: 将相关记忆注入 GraphState
10
+ *
11
+ * @see design.md §1.1 记忆管理
12
+ * @see design.md §1.3 memories 表
13
+ */
14
+ import { randomUUID } from 'node:crypto';
15
+ // ─────────────────────────────────────────────
16
+ // In-Memory Repository (Default)
17
+ // ─────────────────────────────────────────────
18
+ /**
19
+ * InMemoryMemoryRepository — Map-based 内存实现
20
+ *
21
+ * 开发/测试用,生产由 PostgresMemoryRepository 替换
22
+ */
23
+ export class InMemoryMemoryRepository {
24
+ store = new Map();
25
+ async save(record) {
26
+ this.store.set(record.id, { ...record });
27
+ }
28
+ async findByUserAndAgent(userId, agentCode, limit) {
29
+ const results = [];
30
+ for (const record of this.store.values()) {
31
+ if (record.userId === userId && record.agentCode === agentCode) {
32
+ results.push({ ...record });
33
+ }
34
+ }
35
+ // 按 relevanceScore 降序
36
+ results.sort((a, b) => b.relevanceScore - a.relevanceScore);
37
+ return limit !== undefined ? results.slice(0, limit) : results;
38
+ }
39
+ async delete(id) {
40
+ this.store.delete(id);
41
+ }
42
+ async update(record) {
43
+ this.store.set(record.id, { ...record });
44
+ }
45
+ }
46
+ // ─────────────────────────────────────────────
47
+ // LongTermMemoryService
48
+ // ─────────────────────────────────────────────
49
+ export class LongTermMemoryService {
50
+ repository;
51
+ constructor(repository) {
52
+ this.repository = repository ?? new InMemoryMemoryRepository();
53
+ }
54
+ /**
55
+ * 存储一条记忆
56
+ */
57
+ async store(userId, agentCode, type, content, relevanceScore = 1.0) {
58
+ const now = new Date().toISOString();
59
+ const record = {
60
+ id: randomUUID(),
61
+ userId,
62
+ agentCode,
63
+ type,
64
+ content,
65
+ relevanceScore,
66
+ createdBy: userId,
67
+ createdAt: now,
68
+ updatedBy: userId,
69
+ updatedAt: now,
70
+ isDeleted: false,
71
+ };
72
+ await this.repository.save(record);
73
+ return record;
74
+ }
75
+ /**
76
+ * 检索记忆,按 relevanceScore 降序排列
77
+ */
78
+ async retrieve(userId, agentCode, limit) {
79
+ return this.repository.findByUserAndAgent(userId, agentCode, limit);
80
+ }
81
+ /**
82
+ * 删除(遗忘)一条记忆
83
+ */
84
+ async forget(memoryId) {
85
+ await this.repository.delete(memoryId);
86
+ }
87
+ /**
88
+ * 判断消息是否超阈值需要压缩
89
+ *
90
+ * ponytail: 实际 LLM summarize 是外部关注,这里只返回"是否需要"标志
91
+ */
92
+ compress(messages, threshold) {
93
+ return {
94
+ needsCompression: messages.length > threshold,
95
+ messageCount: messages.length,
96
+ threshold,
97
+ };
98
+ }
99
+ /**
100
+ * 将相关记忆注入 GraphState
101
+ *
102
+ * 从长期记忆中加载相关上下文,以 system 消息的形式注入到 state.messages 开头。
103
+ */
104
+ async injectMemories(state, userId, agentCode) {
105
+ const memories = await this.retrieve(userId, agentCode);
106
+ if (memories.length === 0)
107
+ return state;
108
+ const memoryContent = memories
109
+ .map((m) => `[${m.type}] ${m.content}`)
110
+ .join('\n');
111
+ const memoryMessage = {
112
+ role: 'system',
113
+ content: `[Long-term Memory]\n${memoryContent}`,
114
+ };
115
+ return {
116
+ ...state,
117
+ messages: [memoryMessage, ...state.messages],
118
+ };
119
+ }
120
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * MessageCompressionService — 消息压缩服务
3
+ *
4
+ * 当对话消息过长时自动触发压缩,保留关键信息同时减少 Token 数。
5
+ * 支持多种压缩策略:滑动窗口 + LLM 摘要、截断、headroom 等。
6
+ *
7
+ * @see design.md §1.1 记忆管理
8
+ * @see requirements.md Requirement 4.3
9
+ */
10
+ import type { GraphMessage } from '../graph/contracts/executable-graph.js';
11
+ /**
12
+ * 压缩策略类型
13
+ */
14
+ export type CompressionStrategy = 'sliding-window' | 'truncate' | 'headroom';
15
+ /**
16
+ * 压缩配置
17
+ */
18
+ export interface CompressionConfig {
19
+ /** 压缩策略(默认 sliding-window) */
20
+ strategy: CompressionStrategy;
21
+ /** 触发压缩的 Token 上限(默认模型 context window 的 70%) */
22
+ maxTokens: number;
23
+ /** 备用:按轮次触发(默认 20 轮) */
24
+ maxRounds: number;
25
+ /** 压缩后保留的最近轮次(默认 5 轮) */
26
+ preserveRecentRounds: number;
27
+ /** 目标压缩比(压缩后/压缩前,默认 0.3) */
28
+ compressionRatio: number;
29
+ /** 用于摘要的模型(可选,默认使用当前 Agent 的模型) */
30
+ summaryModel?: string;
31
+ }
32
+ /**
33
+ * 默认压缩配置
34
+ */
35
+ export declare const DEFAULT_COMPRESSION_CONFIG: CompressionConfig;
36
+ /**
37
+ * 压缩触发原因
38
+ */
39
+ export type CompressionReason = 'token-exceeded' | 'rounds-exceeded' | 'manual';
40
+ /**
41
+ * 压缩结果
42
+ */
43
+ export interface CompressionResult {
44
+ /** 是否需要压缩 */
45
+ needsCompression: boolean;
46
+ /** 触发原因 */
47
+ reason?: CompressionReason;
48
+ /** 当前 Token 数 */
49
+ currentTokens: number;
50
+ /** 当前轮次数 */
51
+ currentRounds: number;
52
+ /** 压缩后的消息(仅在执行压缩后返回) */
53
+ compressedMessages?: GraphMessage[];
54
+ /** 实际压缩比 */
55
+ compressionRatio?: number;
56
+ /** 生成的摘要内容 */
57
+ summary?: string;
58
+ }
59
+ /**
60
+ * 压缩记录(审计用)
61
+ */
62
+ export interface CompressionRecord {
63
+ /** 会话 ID */
64
+ sessionId: string;
65
+ /** 任务 ID(可选) */
66
+ taskId: string | null;
67
+ /** 原始消息数 */
68
+ originalMessageCount: number;
69
+ /** 压缩后消息数 */
70
+ compressedMessageCount: number;
71
+ /** 原始 Token 数 */
72
+ originalTokens: number;
73
+ /** 压缩后 Token 数 */
74
+ compressedTokens: number;
75
+ /** 使用的策略 */
76
+ strategy: CompressionStrategy;
77
+ /** 摘要内容 */
78
+ summaryContent: string;
79
+ /** 创建人 */
80
+ createdBy: string;
81
+ /** 创建时间 */
82
+ createdAt: string;
83
+ }
84
+ /**
85
+ * IMessageCompressionService — 消息压缩服务接口
86
+ */
87
+ export interface IMessageCompressionService {
88
+ /**
89
+ * 检查是否需要压缩
90
+ *
91
+ * @param messages - 当前消息列表
92
+ * @param config - 压缩配置
93
+ * @returns 压缩检查结果
94
+ */
95
+ checkCompression(messages: GraphMessage[], config?: Partial<CompressionConfig>): CompressionResult;
96
+ /**
97
+ * 执行消息压缩
98
+ *
99
+ * @param messages - 原始消息列表
100
+ * @param config - 压缩配置
101
+ * @returns 压缩后的消息列表
102
+ */
103
+ compress(messages: GraphMessage[], config?: Partial<CompressionConfig>): Promise<GraphMessage[]>;
104
+ /**
105
+ * 估算消息的 Token 数
106
+ *
107
+ * @param messages - 消息列表
108
+ * @returns 估算的 Token 数
109
+ */
110
+ estimateTokens(messages: GraphMessage[]): number;
111
+ }
112
+ /**
113
+ * 简单的 Token 估算器
114
+ *
115
+ * 基于字符数估算 Token 数,粗略但快速。
116
+ * 中文约 1.5 字符 = 1 Token,英文约 4 字符 = 1 Token。
117
+ */
118
+ export declare function estimateTokenCount(text: string): number;
119
+ /**
120
+ * 估算消息列表的 Token 数
121
+ */
122
+ export declare function estimateMessagesTokens(messages: GraphMessage[]): number;
123
+ /**
124
+ * 计算消息轮次数
125
+ *
126
+ * 一个 user + assistant 消息对算一轮。
127
+ */
128
+ export declare function countRounds(messages: GraphMessage[]): number;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * MessageCompressionService — 消息压缩服务
3
+ *
4
+ * 当对话消息过长时自动触发压缩,保留关键信息同时减少 Token 数。
5
+ * 支持多种压缩策略:滑动窗口 + LLM 摘要、截断、headroom 等。
6
+ *
7
+ * @see design.md §1.1 记忆管理
8
+ * @see requirements.md Requirement 4.3
9
+ */
10
+ /**
11
+ * 默认压缩配置
12
+ */
13
+ export const DEFAULT_COMPRESSION_CONFIG = {
14
+ strategy: 'sliding-window',
15
+ maxTokens: 100000, // 约 70% of 128k context
16
+ maxRounds: 20,
17
+ preserveRecentRounds: 5,
18
+ compressionRatio: 0.3,
19
+ };
20
+ // ─────────────────────────────────────────────
21
+ // Token 估算器
22
+ // ─────────────────────────────────────────────
23
+ /**
24
+ * 简单的 Token 估算器
25
+ *
26
+ * 基于字符数估算 Token 数,粗略但快速。
27
+ * 中文约 1.5 字符 = 1 Token,英文约 4 字符 = 1 Token。
28
+ */
29
+ export function estimateTokenCount(text) {
30
+ // 统计中文字符数
31
+ const chineseChars = (text.match(/[\u4e00-\u9fff]/g) || []).length;
32
+ // 统计非中文字符数
33
+ const otherChars = text.length - chineseChars;
34
+ // 中文 1.5 字符 ≈ 1 Token,英文 4 字符 ≈ 1 Token
35
+ return Math.ceil(chineseChars / 1.5 + otherChars / 4);
36
+ }
37
+ /**
38
+ * 估算消息列表的 Token 数
39
+ */
40
+ export function estimateMessagesTokens(messages) {
41
+ let totalTokens = 0;
42
+ for (const msg of messages) {
43
+ // 基础开销(role、格式等)
44
+ totalTokens += 4;
45
+ // 内容 Token
46
+ if (msg.content) {
47
+ totalTokens += estimateTokenCount(msg.content);
48
+ }
49
+ // toolCalls 额外开销
50
+ if (msg.toolCalls) {
51
+ totalTokens += estimateTokenCount(JSON.stringify(msg.toolCalls));
52
+ }
53
+ }
54
+ return totalTokens;
55
+ }
56
+ /**
57
+ * 计算消息轮次数
58
+ *
59
+ * 一个 user + assistant 消息对算一轮。
60
+ */
61
+ export function countRounds(messages) {
62
+ let rounds = 0;
63
+ for (const msg of messages) {
64
+ if (msg.role === 'user') {
65
+ rounds++;
66
+ }
67
+ }
68
+ return rounds;
69
+ }