@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,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Middleware — 3种认证方式
|
|
3
|
+
*
|
|
4
|
+
* 支持:
|
|
5
|
+
* - CAS SSO Token (Cookie: CAS_TOKEN) — 浏览器用户
|
|
6
|
+
* - API Key (Authorization: Bearer <token>) — 业务系统集成
|
|
7
|
+
* - CLI Token (X-CLI-Token header) — 开发者 Playground
|
|
8
|
+
*
|
|
9
|
+
* Requirement 11 AC8: THE 系统 SHALL 支持3种认证方式调用
|
|
10
|
+
*/
|
|
11
|
+
// ─────────────────────────────────────────────
|
|
12
|
+
// Error
|
|
13
|
+
// ─────────────────────────────────────────────
|
|
14
|
+
/**
|
|
15
|
+
* 认证失败自定义错误
|
|
16
|
+
*/
|
|
17
|
+
export class AuthenticationError extends Error {
|
|
18
|
+
code = 'AUTHENTICATION_FAILED';
|
|
19
|
+
constructor(message = 'Authentication required') {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = 'AuthenticationError';
|
|
22
|
+
// 确保 instanceof 正常工作
|
|
23
|
+
Object.setPrototypeOf(this, AuthenticationError.prototype);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// ─────────────────────────────────────────────
|
|
27
|
+
// Constants
|
|
28
|
+
// ─────────────────────────────────────────────
|
|
29
|
+
/** CAS SSO Cookie 名称 */
|
|
30
|
+
const CAS_COOKIE_NAME = 'CAS_TOKEN';
|
|
31
|
+
/** CLI Token 请求头名称 */
|
|
32
|
+
const CLI_TOKEN_HEADER = 'x-cli-token';
|
|
33
|
+
/** Authorization 请求头名称 */
|
|
34
|
+
const AUTHORIZATION_HEADER = 'authorization';
|
|
35
|
+
/** Bearer 前缀 */
|
|
36
|
+
const BEARER_PREFIX = 'Bearer ';
|
|
37
|
+
// ─────────────────────────────────────────────
|
|
38
|
+
// AuthMiddleware
|
|
39
|
+
// ─────────────────────────────────────────────
|
|
40
|
+
/**
|
|
41
|
+
* Auth Middleware — 按优先级尝试3种认证方式
|
|
42
|
+
*
|
|
43
|
+
* 优先级:CAS SSO Cookie > Authorization Bearer > X-CLI-Token
|
|
44
|
+
*/
|
|
45
|
+
export class AuthMiddleware {
|
|
46
|
+
authService;
|
|
47
|
+
constructor(authService) {
|
|
48
|
+
this.authService = authService;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 认证入口
|
|
52
|
+
*
|
|
53
|
+
* 按优先级依次尝试:
|
|
54
|
+
* 1. CAS SSO Cookie (CAS_TOKEN)
|
|
55
|
+
* 2. Authorization: Bearer <token> (API Key)
|
|
56
|
+
* 3. X-CLI-Token header (CLI Token)
|
|
57
|
+
*
|
|
58
|
+
* @throws AuthenticationError 如果无有效凭证或验证失败
|
|
59
|
+
*/
|
|
60
|
+
async authenticate(req) {
|
|
61
|
+
// 1. 尝试 CAS SSO Cookie
|
|
62
|
+
const casToken = this.extractCasToken(req);
|
|
63
|
+
if (casToken) {
|
|
64
|
+
const user = await this.authService.validate(casToken, 'cas_sso');
|
|
65
|
+
if (user)
|
|
66
|
+
return user;
|
|
67
|
+
}
|
|
68
|
+
// 2. 尝试 Authorization: Bearer <token>
|
|
69
|
+
const bearerToken = this.extractBearerToken(req);
|
|
70
|
+
if (bearerToken) {
|
|
71
|
+
const user = await this.authService.validate(bearerToken, 'api_key');
|
|
72
|
+
if (user)
|
|
73
|
+
return user;
|
|
74
|
+
}
|
|
75
|
+
// 3. 尝试 X-CLI-Token header
|
|
76
|
+
const cliToken = this.extractCliToken(req);
|
|
77
|
+
if (cliToken) {
|
|
78
|
+
const user = await this.authService.validate(cliToken, 'cli_token');
|
|
79
|
+
if (user)
|
|
80
|
+
return user;
|
|
81
|
+
}
|
|
82
|
+
// 均未命中 → 抛出认证错误
|
|
83
|
+
throw new AuthenticationError('No valid credentials provided');
|
|
84
|
+
}
|
|
85
|
+
// ─── Private helpers ──────────────────────────
|
|
86
|
+
/**
|
|
87
|
+
* 从 Cookie 中提取 CAS Token
|
|
88
|
+
*/
|
|
89
|
+
extractCasToken(req) {
|
|
90
|
+
// 优先从已解析的 cookies 对象中取
|
|
91
|
+
if (req.cookies?.[CAS_COOKIE_NAME]) {
|
|
92
|
+
return req.cookies[CAS_COOKIE_NAME];
|
|
93
|
+
}
|
|
94
|
+
// 回退:从 cookie header 手动解析
|
|
95
|
+
const cookieHeader = req.headers['cookie'];
|
|
96
|
+
if (!cookieHeader)
|
|
97
|
+
return undefined;
|
|
98
|
+
const cookies = parseCookieHeader(cookieHeader);
|
|
99
|
+
return cookies[CAS_COOKIE_NAME];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 从 Authorization header 提取 Bearer Token
|
|
103
|
+
*/
|
|
104
|
+
extractBearerToken(req) {
|
|
105
|
+
const authHeader = req.headers[AUTHORIZATION_HEADER];
|
|
106
|
+
if (!authHeader)
|
|
107
|
+
return undefined;
|
|
108
|
+
if (authHeader.startsWith(BEARER_PREFIX)) {
|
|
109
|
+
const token = authHeader.slice(BEARER_PREFIX.length).trim();
|
|
110
|
+
return token || undefined;
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 从 X-CLI-Token header 提取 CLI Token
|
|
116
|
+
*/
|
|
117
|
+
extractCliToken(req) {
|
|
118
|
+
const token = req.headers[CLI_TOKEN_HEADER];
|
|
119
|
+
return token?.trim() || undefined;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// ─────────────────────────────────────────────
|
|
123
|
+
// Standalone authenticate function (convenience)
|
|
124
|
+
// ─────────────────────────────────────────────
|
|
125
|
+
/**
|
|
126
|
+
* 便捷函数 — 创建 AuthMiddleware 实例并执行认证
|
|
127
|
+
*
|
|
128
|
+
* @param req - 框架无关的请求对象
|
|
129
|
+
* @param authService - 认证服务实现
|
|
130
|
+
* @returns 认证后的用户信息
|
|
131
|
+
* @throws AuthenticationError
|
|
132
|
+
*/
|
|
133
|
+
export async function authenticate(req, authService) {
|
|
134
|
+
const middleware = new AuthMiddleware(authService);
|
|
135
|
+
return middleware.authenticate(req);
|
|
136
|
+
}
|
|
137
|
+
// ─────────────────────────────────────────────
|
|
138
|
+
// Utils
|
|
139
|
+
// ─────────────────────────────────────────────
|
|
140
|
+
/**
|
|
141
|
+
* 简易 Cookie header 解析
|
|
142
|
+
* 格式: "name1=value1; name2=value2"
|
|
143
|
+
*/
|
|
144
|
+
function parseCookieHeader(header) {
|
|
145
|
+
const result = {};
|
|
146
|
+
const pairs = header.split(';');
|
|
147
|
+
for (const pair of pairs) {
|
|
148
|
+
const eqIdx = pair.indexOf('=');
|
|
149
|
+
if (eqIdx === -1)
|
|
150
|
+
continue;
|
|
151
|
+
const key = pair.slice(0, eqIdx).trim();
|
|
152
|
+
const value = pair.slice(eqIdx + 1).trim();
|
|
153
|
+
if (key) {
|
|
154
|
+
result[key] = value;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './auth.middleware.js';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Invoke API — Route Handlers(dev-only HTTP 适配层)
|
|
3
|
+
*
|
|
4
|
+
* 生产环境由 Hosting 提供对外 HTTP;本模块供 `EAP_DEV_HTTP=1` 本地调试。
|
|
5
|
+
*/
|
|
6
|
+
import type { ServerResponse } from 'node:http';
|
|
7
|
+
import type { InvokeRequest as ContractInvokeRequest, InvokeResponse as ContractInvokeResponse } from '@gt-fe/eap-contracts';
|
|
8
|
+
import type { ITaskManager } from '../../task/task.service.js';
|
|
9
|
+
import type { SessionService } from '../../session/session.service.js';
|
|
10
|
+
import type { IStateGraphEngine } from '../../graph/contracts/executable-graph.js';
|
|
11
|
+
import type { SSEEmitter } from '../../sse/sse-emitter.js';
|
|
12
|
+
export type { InvokeConfig, InvokeResponseData } from '@gt-fe/eap-contracts';
|
|
13
|
+
/**
|
|
14
|
+
* dev HTTP 层 Invoke 请求(扩展 userId,Hosting 从 auth 注入)
|
|
15
|
+
*/
|
|
16
|
+
export type InvokeRequest = ContractInvokeRequest & {
|
|
17
|
+
userId?: string;
|
|
18
|
+
};
|
|
19
|
+
export type InvokeResponse = ContractInvokeResponse;
|
|
20
|
+
/** 流式调用请求 — 与 InvokeRequest 相同 */
|
|
21
|
+
export type StreamRequest = InvokeRequest;
|
|
22
|
+
/**
|
|
23
|
+
* Agent 路由处理器依赖
|
|
24
|
+
*/
|
|
25
|
+
export interface AgentRouteDependencies {
|
|
26
|
+
/** Task 管理器 */
|
|
27
|
+
taskManager: ITaskManager;
|
|
28
|
+
/** Session 服务 */
|
|
29
|
+
sessionService: SessionService;
|
|
30
|
+
/** Graph 引擎 */
|
|
31
|
+
graphEngine: IStateGraphEngine;
|
|
32
|
+
/** SSE 发射器 */
|
|
33
|
+
sseEmitter: SSEEmitter;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 创建 Agent 路由处理器
|
|
37
|
+
*
|
|
38
|
+
* @param deps - 依赖注入
|
|
39
|
+
* @returns 路由处理器函数
|
|
40
|
+
*/
|
|
41
|
+
export declare function createAgentRouteHandlers(deps: AgentRouteDependencies): {
|
|
42
|
+
invokeHandler: (req: InvokeRequest) => Promise<InvokeResponse>;
|
|
43
|
+
streamHandler: (req: StreamRequest, res: ServerResponse) => Promise<void>;
|
|
44
|
+
};
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Invoke API — Route Handlers(dev-only HTTP 适配层)
|
|
3
|
+
*
|
|
4
|
+
* 生产环境由 Hosting 提供对外 HTTP;本模块供 `EAP_DEV_HTTP=1` 本地调试。
|
|
5
|
+
*/
|
|
6
|
+
// ─────────────────────────────────────────────
|
|
7
|
+
// Route Handlers
|
|
8
|
+
// ─────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* 创建 Agent 路由处理器
|
|
11
|
+
*
|
|
12
|
+
* @param deps - 依赖注入
|
|
13
|
+
* @returns 路由处理器函数
|
|
14
|
+
*/
|
|
15
|
+
export function createAgentRouteHandlers(deps) {
|
|
16
|
+
const { taskManager, sessionService, graphEngine, sseEmitter } = deps;
|
|
17
|
+
/**
|
|
18
|
+
* 同步调用 Agent
|
|
19
|
+
*
|
|
20
|
+
* 接收解析后的请求体,执行 Agent Graph,等待完整结果返回。
|
|
21
|
+
*/
|
|
22
|
+
async function invokeHandler(req) {
|
|
23
|
+
const { input, sessionId, config, userId } = req;
|
|
24
|
+
const agentCode = req.agentCode ?? req.agentId;
|
|
25
|
+
if (!agentCode) {
|
|
26
|
+
throw new Error('agentCode is required');
|
|
27
|
+
}
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
try {
|
|
30
|
+
// 1. 获取或创建 Session
|
|
31
|
+
let resolvedSessionId = sessionId;
|
|
32
|
+
if (!resolvedSessionId) {
|
|
33
|
+
const session = await sessionService.createSession({
|
|
34
|
+
userId: userId ?? 'anonymous',
|
|
35
|
+
agentId: agentCode,
|
|
36
|
+
});
|
|
37
|
+
resolvedSessionId = session.id;
|
|
38
|
+
}
|
|
39
|
+
// 2. 创建 Task
|
|
40
|
+
const task = await taskManager.create({
|
|
41
|
+
id: req.taskId,
|
|
42
|
+
agentId: agentCode,
|
|
43
|
+
sessionId: resolvedSessionId,
|
|
44
|
+
userId: userId ?? 'anonymous',
|
|
45
|
+
correlationId: `corr-${Date.now()}`,
|
|
46
|
+
input,
|
|
47
|
+
timeout: 60000,
|
|
48
|
+
});
|
|
49
|
+
// 3. 执行 Graph
|
|
50
|
+
const graph = await graphEngine.buildGraph({
|
|
51
|
+
name: agentCode,
|
|
52
|
+
version: '1.0.0',
|
|
53
|
+
nodes: [],
|
|
54
|
+
edges: [],
|
|
55
|
+
conditionalEdges: [],
|
|
56
|
+
entryPoint: '__start__',
|
|
57
|
+
finishPoints: ['__end__'],
|
|
58
|
+
description: '',
|
|
59
|
+
state: {},
|
|
60
|
+
config: {},
|
|
61
|
+
});
|
|
62
|
+
const result = await graphEngine.invoke(graph, {
|
|
63
|
+
messages: [{ role: 'user', content: input }],
|
|
64
|
+
userId: userId ?? 'anonymous',
|
|
65
|
+
});
|
|
66
|
+
// 4. 完成 Task
|
|
67
|
+
await taskManager.updateStatus(task.id, 'success', result.output);
|
|
68
|
+
// 5. 计算耗时
|
|
69
|
+
const duration = Date.now() - startTime;
|
|
70
|
+
return {
|
|
71
|
+
code: 'ok',
|
|
72
|
+
data: {
|
|
73
|
+
taskId: task.id,
|
|
74
|
+
sessionId: resolvedSessionId,
|
|
75
|
+
output: result.output ?? '',
|
|
76
|
+
tokenUsage: {
|
|
77
|
+
input: result.tokenUsage?.input ?? 0,
|
|
78
|
+
output: result.tokenUsage?.output ?? 0,
|
|
79
|
+
total: result.tokenUsage?.total ?? 0,
|
|
80
|
+
},
|
|
81
|
+
duration,
|
|
82
|
+
status: 'success',
|
|
83
|
+
},
|
|
84
|
+
traceId: task.id,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
// 错误处理
|
|
89
|
+
const duration = Date.now() - startTime;
|
|
90
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
91
|
+
return {
|
|
92
|
+
code: 'runtime.graph.execution_error',
|
|
93
|
+
data: {
|
|
94
|
+
taskId: '',
|
|
95
|
+
sessionId: sessionId ?? '',
|
|
96
|
+
output: '',
|
|
97
|
+
tokenUsage: { input: 0, output: 0, total: 0 },
|
|
98
|
+
duration,
|
|
99
|
+
status: 'failed',
|
|
100
|
+
},
|
|
101
|
+
traceId: '',
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 流式调用 Agent(SSE)
|
|
107
|
+
*
|
|
108
|
+
* 接收解析后的请求体,通过 Node.js ServerResponse 推送 SSE 事件流。
|
|
109
|
+
*/
|
|
110
|
+
async function streamHandler(req, res) {
|
|
111
|
+
const { input, sessionId, config, userId } = req;
|
|
112
|
+
const agentCode = req.agentCode ?? req.agentId;
|
|
113
|
+
if (!agentCode) {
|
|
114
|
+
res.write(`event: error\ndata: ${JSON.stringify({ error: 'agentCode is required' })}\n\n`);
|
|
115
|
+
res.end();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// 设置 SSE 标准响应头
|
|
119
|
+
res.writeHead(200, {
|
|
120
|
+
'Content-Type': 'text/event-stream',
|
|
121
|
+
'Cache-Control': 'no-cache',
|
|
122
|
+
'Connection': 'keep-alive',
|
|
123
|
+
'X-Accel-Buffering': 'no', // 禁用 Nginx 缓冲
|
|
124
|
+
});
|
|
125
|
+
try {
|
|
126
|
+
// 1. 获取或创建 Session
|
|
127
|
+
let resolvedSessionId = sessionId;
|
|
128
|
+
if (!resolvedSessionId) {
|
|
129
|
+
const session = await sessionService.createSession({
|
|
130
|
+
userId: userId ?? 'anonymous',
|
|
131
|
+
agentId: agentCode,
|
|
132
|
+
});
|
|
133
|
+
resolvedSessionId = session.id;
|
|
134
|
+
}
|
|
135
|
+
// 2. 创建 Task
|
|
136
|
+
const task = await taskManager.create({
|
|
137
|
+
id: req.taskId,
|
|
138
|
+
agentId: agentCode,
|
|
139
|
+
sessionId: resolvedSessionId,
|
|
140
|
+
userId: userId ?? 'anonymous',
|
|
141
|
+
correlationId: `corr-${Date.now()}`,
|
|
142
|
+
input,
|
|
143
|
+
timeout: 60000,
|
|
144
|
+
});
|
|
145
|
+
// 3. 发送 task.started 事件
|
|
146
|
+
const taskId = task.id;
|
|
147
|
+
const timestamp = new Date().toISOString();
|
|
148
|
+
res.write(`event: task.started\ndata: ${JSON.stringify({
|
|
149
|
+
taskId,
|
|
150
|
+
sessionId: resolvedSessionId,
|
|
151
|
+
timestamp,
|
|
152
|
+
})}\n\n`);
|
|
153
|
+
// 4. 流式执行 Graph
|
|
154
|
+
const graph2 = await graphEngine.buildGraph({
|
|
155
|
+
name: agentCode,
|
|
156
|
+
version: '1.0.0',
|
|
157
|
+
nodes: [],
|
|
158
|
+
edges: [],
|
|
159
|
+
conditionalEdges: [],
|
|
160
|
+
entryPoint: '__start__',
|
|
161
|
+
finishPoints: ['__end__'],
|
|
162
|
+
description: '',
|
|
163
|
+
state: {},
|
|
164
|
+
config: {},
|
|
165
|
+
});
|
|
166
|
+
const stream = graphEngine.stream(graph2, {
|
|
167
|
+
messages: [{ role: 'user', content: input }],
|
|
168
|
+
userId: userId ?? 'anonymous',
|
|
169
|
+
});
|
|
170
|
+
// 5. 将 Graph 事件转为 SSE 格式
|
|
171
|
+
for await (const event of stream) {
|
|
172
|
+
// 检查连接是否关闭
|
|
173
|
+
if (res.writableEnded)
|
|
174
|
+
break;
|
|
175
|
+
// 发送 SSE 事件
|
|
176
|
+
res.write(`event: ${event.type}\ndata: ${JSON.stringify(event.payload)}\n\n`);
|
|
177
|
+
}
|
|
178
|
+
// 6. 完成 Task
|
|
179
|
+
await taskManager.updateStatus(taskId, 'success');
|
|
180
|
+
// 7. 发送 task.completed 事件
|
|
181
|
+
res.write(`event: task.completed\ndata: ${JSON.stringify({
|
|
182
|
+
taskId,
|
|
183
|
+
duration: Date.now() - new Date(timestamp).getTime(),
|
|
184
|
+
timestamp: new Date().toISOString(),
|
|
185
|
+
})}\n\n`);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
// 发送错误事件
|
|
189
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
190
|
+
res.write(`event: error\ndata: ${JSON.stringify({
|
|
191
|
+
error: errorMessage,
|
|
192
|
+
timestamp: new Date().toISOString(),
|
|
193
|
+
})}\n\n`);
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
// 关闭连接
|
|
197
|
+
res.end();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
invokeHandler,
|
|
202
|
+
streamHandler,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Messages API — Route Handlers
|
|
3
|
+
*
|
|
4
|
+
* 框架无关的路由处理函数,接受解析后的请求体,返回响应体。
|
|
5
|
+
* - postMessageHandler: 在已有会话中发送新消息,触发 Agent 执行
|
|
6
|
+
* - getMessagesHandler: 获取会话消息历史
|
|
7
|
+
*
|
|
8
|
+
* Requirement 11: Agent Invoke API — AC3, AC5
|
|
9
|
+
*/
|
|
10
|
+
import type { MessageRecord, SessionService } from '../../session/session.service.js';
|
|
11
|
+
import type { ITaskManager } from '../../task/task.service.js';
|
|
12
|
+
import type { IStateGraphEngine } from '../../graph/contracts/executable-graph.js';
|
|
13
|
+
import type { InvokeConfig, InvokeResponse } from './agent.routes.js';
|
|
14
|
+
/**
|
|
15
|
+
* 发送消息请求 — POST /api/v1/sessions/:sessionId/messages
|
|
16
|
+
*/
|
|
17
|
+
export interface PostMessageRequest {
|
|
18
|
+
/** 目标 Session ID(从路径参数获取) */
|
|
19
|
+
sessionId: string;
|
|
20
|
+
/** 用户输入 */
|
|
21
|
+
input: string;
|
|
22
|
+
/** 执行配置(可选) */
|
|
23
|
+
config?: InvokeConfig;
|
|
24
|
+
/** 用户 ID */
|
|
25
|
+
userId?: string;
|
|
26
|
+
/** 预装版本;缺省时回退 session.metadata.agentVersion */
|
|
27
|
+
agentVersion?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 发送消息响应 — 与 InvokeResponse 相同(触发 Agent 执行)
|
|
31
|
+
*/
|
|
32
|
+
export type PostMessageResponse = InvokeResponse;
|
|
33
|
+
/**
|
|
34
|
+
* 获取消息历史请求 — GET /api/v1/sessions/:sessionId/messages
|
|
35
|
+
*/
|
|
36
|
+
export interface GetMessagesRequest {
|
|
37
|
+
/** 目标 Session ID(从路径参数获取) */
|
|
38
|
+
sessionId: string;
|
|
39
|
+
/** 返回条数上限(可选) */
|
|
40
|
+
limit?: number;
|
|
41
|
+
/** 偏移量(可选) */
|
|
42
|
+
offset?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 获取消息历史响应数据
|
|
46
|
+
*/
|
|
47
|
+
export interface GetMessagesResponseData {
|
|
48
|
+
/** 消息列表 */
|
|
49
|
+
messages: MessageRecord[];
|
|
50
|
+
/** 消息总数(可选,用于分页) */
|
|
51
|
+
total?: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 获取消息历史完整响应
|
|
55
|
+
*/
|
|
56
|
+
export interface GetMessagesResponse {
|
|
57
|
+
/** 业务码:'ok' 表示成功,否则为三段式错误码 */
|
|
58
|
+
code: string;
|
|
59
|
+
/** 响应数据 */
|
|
60
|
+
data: GetMessagesResponseData;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Session 路由处理器依赖
|
|
64
|
+
*/
|
|
65
|
+
export interface SessionRouteDependencies {
|
|
66
|
+
/** Session 服务 */
|
|
67
|
+
sessionService: SessionService;
|
|
68
|
+
/** Task 管理器 */
|
|
69
|
+
taskManager: ITaskManager;
|
|
70
|
+
/** Graph 引擎 */
|
|
71
|
+
graphEngine: IStateGraphEngine;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 创建 Session 路由处理器
|
|
75
|
+
*
|
|
76
|
+
* @param deps - 依赖注入
|
|
77
|
+
* @returns 路由处理器函数
|
|
78
|
+
*/
|
|
79
|
+
export declare function createSessionRouteHandlers(deps: SessionRouteDependencies): {
|
|
80
|
+
postMessageHandler: (req: PostMessageRequest) => Promise<PostMessageResponse>;
|
|
81
|
+
getMessagesHandler: (req: GetMessagesRequest) => Promise<GetMessagesResponse>;
|
|
82
|
+
};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Messages API — Route Handlers
|
|
3
|
+
*
|
|
4
|
+
* 框架无关的路由处理函数,接受解析后的请求体,返回响应体。
|
|
5
|
+
* - postMessageHandler: 在已有会话中发送新消息,触发 Agent 执行
|
|
6
|
+
* - getMessagesHandler: 获取会话消息历史
|
|
7
|
+
*
|
|
8
|
+
* Requirement 11: Agent Invoke API — AC3, AC5
|
|
9
|
+
*/
|
|
10
|
+
// ─────────────────────────────────────────────
|
|
11
|
+
// Route Handlers
|
|
12
|
+
// ─────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* 创建 Session 路由处理器
|
|
15
|
+
*
|
|
16
|
+
* @param deps - 依赖注入
|
|
17
|
+
* @returns 路由处理器函数
|
|
18
|
+
*/
|
|
19
|
+
export function createSessionRouteHandlers(deps) {
|
|
20
|
+
const { sessionService, taskManager, graphEngine } = deps;
|
|
21
|
+
/**
|
|
22
|
+
* 在已有会话中发送新消息
|
|
23
|
+
*
|
|
24
|
+
* 接收解析后的请求体,在现有 Session 上下文中触发 Agent 执行。
|
|
25
|
+
*/
|
|
26
|
+
async function postMessageHandler(req) {
|
|
27
|
+
const { sessionId, input, config, userId } = req;
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
try {
|
|
30
|
+
// 1. 验证 Session 存在
|
|
31
|
+
const session = await sessionService.getSession(sessionId);
|
|
32
|
+
if (!session) {
|
|
33
|
+
return {
|
|
34
|
+
code: 'runtime.session.not_found',
|
|
35
|
+
data: {
|
|
36
|
+
taskId: '',
|
|
37
|
+
sessionId,
|
|
38
|
+
output: '',
|
|
39
|
+
tokenUsage: { input: 0, output: 0, total: 0 },
|
|
40
|
+
duration: Date.now() - startTime,
|
|
41
|
+
status: 'failed',
|
|
42
|
+
},
|
|
43
|
+
traceId: '',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// 2. 加载 Session 历史消息作为上下文
|
|
47
|
+
const history = await sessionService.loadHistory(sessionId, {
|
|
48
|
+
limit: 50, // 最近 50 条消息
|
|
49
|
+
});
|
|
50
|
+
// 3. 创建 Task
|
|
51
|
+
const task = await taskManager.create({
|
|
52
|
+
agentId: session.agentId,
|
|
53
|
+
sessionId,
|
|
54
|
+
userId: userId ?? session.userId,
|
|
55
|
+
correlationId: `corr-${Date.now()}`,
|
|
56
|
+
input,
|
|
57
|
+
timeout: 60000,
|
|
58
|
+
});
|
|
59
|
+
// 4. 构建消息列表(历史 + 新消息)
|
|
60
|
+
const messages = [
|
|
61
|
+
...history.map((m) => ({
|
|
62
|
+
role: m.role,
|
|
63
|
+
content: m.content,
|
|
64
|
+
})),
|
|
65
|
+
{ role: 'user', content: input },
|
|
66
|
+
];
|
|
67
|
+
// 5. 执行 Graph
|
|
68
|
+
const graph = await graphEngine.buildGraph({
|
|
69
|
+
name: session.agentId,
|
|
70
|
+
version: '1.0.0',
|
|
71
|
+
nodes: [],
|
|
72
|
+
edges: [],
|
|
73
|
+
conditionalEdges: [],
|
|
74
|
+
entryPoint: '__start__',
|
|
75
|
+
finishPoints: ['__end__'],
|
|
76
|
+
description: '',
|
|
77
|
+
state: {},
|
|
78
|
+
config: {},
|
|
79
|
+
});
|
|
80
|
+
const result = await graphEngine.invoke(graph, {
|
|
81
|
+
messages,
|
|
82
|
+
userId: userId ?? session.userId,
|
|
83
|
+
});
|
|
84
|
+
// 6. 完成 Task
|
|
85
|
+
await taskManager.updateStatus(task.id, 'success', result.output);
|
|
86
|
+
// 7. 计算耗时
|
|
87
|
+
const duration = Date.now() - startTime;
|
|
88
|
+
return {
|
|
89
|
+
code: 'ok',
|
|
90
|
+
data: {
|
|
91
|
+
taskId: task.id,
|
|
92
|
+
sessionId,
|
|
93
|
+
output: result.output ?? '',
|
|
94
|
+
tokenUsage: {
|
|
95
|
+
input: result.tokenUsage?.input ?? 0,
|
|
96
|
+
output: result.tokenUsage?.output ?? 0,
|
|
97
|
+
total: result.tokenUsage?.total ?? 0,
|
|
98
|
+
},
|
|
99
|
+
duration,
|
|
100
|
+
status: 'success',
|
|
101
|
+
},
|
|
102
|
+
traceId: task.id,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
// 错误处理
|
|
107
|
+
const duration = Date.now() - startTime;
|
|
108
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
109
|
+
return {
|
|
110
|
+
code: 'runtime.graph.execution_error',
|
|
111
|
+
data: {
|
|
112
|
+
taskId: '',
|
|
113
|
+
sessionId,
|
|
114
|
+
output: '',
|
|
115
|
+
tokenUsage: { input: 0, output: 0, total: 0 },
|
|
116
|
+
duration,
|
|
117
|
+
status: 'failed',
|
|
118
|
+
},
|
|
119
|
+
traceId: '',
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* 获取会话消息历史
|
|
125
|
+
*
|
|
126
|
+
* 接收解析后的请求体,返回指定 Session 的消息列表(支持分页)。
|
|
127
|
+
*/
|
|
128
|
+
async function getMessagesHandler(req) {
|
|
129
|
+
const { sessionId, limit, offset } = req;
|
|
130
|
+
try {
|
|
131
|
+
// 1. 验证 Session 存在
|
|
132
|
+
const session = await sessionService.getSession(sessionId);
|
|
133
|
+
if (!session) {
|
|
134
|
+
return {
|
|
135
|
+
code: 'runtime.session.not_found',
|
|
136
|
+
data: {
|
|
137
|
+
messages: [],
|
|
138
|
+
total: 0,
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
// 2. 查询消息
|
|
143
|
+
const messages = await sessionService.loadHistory(sessionId, {
|
|
144
|
+
limit: limit ?? 50,
|
|
145
|
+
offset: offset ?? 0,
|
|
146
|
+
});
|
|
147
|
+
return {
|
|
148
|
+
code: 'ok',
|
|
149
|
+
data: {
|
|
150
|
+
messages,
|
|
151
|
+
total: messages.length,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
return {
|
|
157
|
+
code: 'runtime.graph.execution_error',
|
|
158
|
+
data: {
|
|
159
|
+
messages: [],
|
|
160
|
+
total: 0,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
postMessageHandler,
|
|
167
|
+
getMessagesHandler,
|
|
168
|
+
};
|
|
169
|
+
}
|