@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,432 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamOrchestrator — 流式调用编排器
|
|
3
|
+
*
|
|
4
|
+
* 实现 POST /api/v1/agents/:agentCode/stream 的核心编排逻辑:
|
|
5
|
+
* 1. 检查 Session 日预算(SessionBudgetChecker)
|
|
6
|
+
* 2. 解析/创建 Session 上下文(SessionContextService),sessionId 缺失时自动创建
|
|
7
|
+
* 3. 创建 Task(TaskService)
|
|
8
|
+
* 4. 启动 Task(pending → running)
|
|
9
|
+
* 5. 通过 SSEEmitter 推送事件流
|
|
10
|
+
* 6. 构建/流式执行 Graph(IStateGraphEngine.stream())
|
|
11
|
+
* 7. 将 RuntimeEvent 转为 SSE 事件推送
|
|
12
|
+
* 8. 记录 Token 消耗 + 完成 Task + 关闭 SSE 连接
|
|
13
|
+
*
|
|
14
|
+
* 与 InvokeOrchestrator 区别:
|
|
15
|
+
* - 使用 Graph.stream() 而非 invoke()
|
|
16
|
+
* - 通过 SSEEmitter 实时推送事件,而非等待完整结果
|
|
17
|
+
* - 在流式过程中逐步 emit 各类事件(session.created, task.started, response.chunk 等)
|
|
18
|
+
*
|
|
19
|
+
* @see design.md §1.5 /stream 内部执行逻辑
|
|
20
|
+
* @see requirements.md Requirement 11 AC2
|
|
21
|
+
*/
|
|
22
|
+
import { buildHitlWaitingTaskOutput, buildTurnGraphMessages, buildTurnTranscriptFromStreamEvents, extractStreamReasoning, extractStreamTextDelta, messageRecordsToGraphMessages, persistHitlWaitingPlaceholder, persistTurnTranscript, persistUserTurnMessage, } from '../../session/persist-turn-messages.js';
|
|
23
|
+
import { SessionBudgetExhaustedError } from '../../token/session-budget-checker.js';
|
|
24
|
+
import { TokenBudgetExhaustedError } from '../../token/token-budget-guard.js';
|
|
25
|
+
import { SSEEmitter } from '../../sse/sse-emitter.js';
|
|
26
|
+
import { resolveExecutionContext } from '../../governance/governance-client.js';
|
|
27
|
+
import { resolveSkillInputFromInvokeInput } from '../../registry/skill-io-guard.js';
|
|
28
|
+
import { ErrorCodes } from '@gt-fe/eap-contracts';
|
|
29
|
+
import { classifyRuntimeError } from '../../utils/http-error.js';
|
|
30
|
+
import { toLoadedToolMap } from '../../tool/loaded-tool-definition.js';
|
|
31
|
+
import { toLoadedSkillMap, mergeSkillScriptTools } from '../../tool/system-prompt-builder.js';
|
|
32
|
+
import { resolveAgentCode } from '../../common/agent-code.js';
|
|
33
|
+
import { unwrapHitlPaused } from './invoke.handler.js';
|
|
34
|
+
import { buildHitlWaitedPayload } from '../../graph/hitl/hitl-handler.js';
|
|
35
|
+
import { resolveTraceId } from '../../common/trace-id.js';
|
|
36
|
+
// ─────────────────────────────────────────────
|
|
37
|
+
// Placeholder Graph DSL (Agent Registry 接入前)
|
|
38
|
+
// ─────────────────────────────────────────────
|
|
39
|
+
const DEFAULT_GRAPH_DSL = {
|
|
40
|
+
name: 'default-graph',
|
|
41
|
+
version: '1.0.0',
|
|
42
|
+
state: { messages: 'array' },
|
|
43
|
+
nodes: [
|
|
44
|
+
{ id: 'llm', type: 'llm', config: {} },
|
|
45
|
+
],
|
|
46
|
+
edges: [
|
|
47
|
+
{ from: '__start__', to: 'llm' },
|
|
48
|
+
{ from: 'llm', to: '__end__' },
|
|
49
|
+
],
|
|
50
|
+
config: { timeout: 60000 },
|
|
51
|
+
};
|
|
52
|
+
// ─────────────────────────────────────────────
|
|
53
|
+
// StreamOrchestrator
|
|
54
|
+
// ─────────────────────────────────────────────
|
|
55
|
+
/**
|
|
56
|
+
* StreamOrchestrator — 流式调用全流程编排
|
|
57
|
+
*
|
|
58
|
+
* 协调 SessionContextService、TaskService、IStateGraphEngine、SSEEmitter、TokenStatsService
|
|
59
|
+
* 等服务完成一次 SSE 流式 Agent 调用的完整生命周期。
|
|
60
|
+
*/
|
|
61
|
+
export class StreamOrchestrator {
|
|
62
|
+
sessionContextService;
|
|
63
|
+
taskService;
|
|
64
|
+
graphEngine;
|
|
65
|
+
tokenStatsService;
|
|
66
|
+
tokenBudgetGuard;
|
|
67
|
+
sessionBudgetChecker;
|
|
68
|
+
messageService;
|
|
69
|
+
graphLoader;
|
|
70
|
+
checkpointSaver;
|
|
71
|
+
traceCollector;
|
|
72
|
+
constructor(deps) {
|
|
73
|
+
this.sessionContextService = deps.sessionContextService;
|
|
74
|
+
this.taskService = deps.taskService;
|
|
75
|
+
this.graphEngine = deps.graphEngine;
|
|
76
|
+
this.tokenStatsService = deps.tokenStatsService;
|
|
77
|
+
this.tokenBudgetGuard = deps.tokenBudgetGuard;
|
|
78
|
+
this.sessionBudgetChecker = deps.sessionBudgetChecker;
|
|
79
|
+
this.messageService = deps.messageService;
|
|
80
|
+
this.graphLoader = deps.graphLoader;
|
|
81
|
+
this.checkpointSaver = deps.checkpointSaver;
|
|
82
|
+
this.traceCollector = deps.traceCollector;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 执行流式调用编排
|
|
86
|
+
*
|
|
87
|
+
* @param req - 解析后的调用请求(与 InvokeRequest 相同)
|
|
88
|
+
* @param res - Node.js HTTP ServerResponse,用于写入 SSE 事件
|
|
89
|
+
* @param userId - 经认证的用户 ID
|
|
90
|
+
*/
|
|
91
|
+
async execute(req, res, userId) {
|
|
92
|
+
const startTime = Date.now();
|
|
93
|
+
const agentCode = resolveAgentCode(req);
|
|
94
|
+
const ctx = resolveExecutionContext({ ...req, agentCode }, userId);
|
|
95
|
+
const correlationId = ctx.correlationId;
|
|
96
|
+
const effectiveUserId = ctx.userId ?? userId;
|
|
97
|
+
// 创建 SSEEmitter 绑定到 ServerResponse
|
|
98
|
+
const emitter = new SSEEmitter(res, {
|
|
99
|
+
heartbeatInterval: 30000,
|
|
100
|
+
correlationId,
|
|
101
|
+
});
|
|
102
|
+
// 启动自动心跳
|
|
103
|
+
emitter.startHeartbeat();
|
|
104
|
+
try {
|
|
105
|
+
await this.executeInternal(req, emitter, effectiveUserId, correlationId, startTime, ctx);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
// 确保异常情况下也能正确关闭 SSE 连接
|
|
109
|
+
this.emitErrorAndClose(emitter, correlationId, '', error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// ─────────────────────────────────────────────
|
|
113
|
+
// Private: 内部编排逻辑
|
|
114
|
+
// ─────────────────────────────────────────────
|
|
115
|
+
async executeInternal(req, emitter, userId, correlationId, startTime, executionContext) {
|
|
116
|
+
const agentCode = resolveAgentCode(req);
|
|
117
|
+
// ─── Step 1: 检查 Session 日预算 ───
|
|
118
|
+
if (req.sessionId) {
|
|
119
|
+
try {
|
|
120
|
+
await this.sessionBudgetChecker.assertBudgetAvailable(req.sessionId);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error instanceof SessionBudgetExhaustedError) {
|
|
124
|
+
this.emitErrorAndClose(emitter, correlationId, '', error);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// ─── Step 2: 解析/创建 Session 上下文(auto-create when absent) ───
|
|
131
|
+
const sessionContext = await this.sessionContextService.resolveSessionContext({
|
|
132
|
+
sessionId: req.sessionId,
|
|
133
|
+
userId,
|
|
134
|
+
agentId: agentCode,
|
|
135
|
+
agentVersion: req.agentVersion,
|
|
136
|
+
});
|
|
137
|
+
const sessionId = sessionContext.session.id;
|
|
138
|
+
// 新创建的 Session 也检查预算
|
|
139
|
+
if (!req.sessionId) {
|
|
140
|
+
try {
|
|
141
|
+
await this.sessionBudgetChecker.assertBudgetAvailable(sessionId);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (error instanceof SessionBudgetExhaustedError) {
|
|
145
|
+
this.emitErrorAndClose(emitter, correlationId, '', error);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// 更新 emitter 的 taskId 上下文(此时还没 taskId,后续再更新)
|
|
152
|
+
// ─── Emit: session.created(仅新 Session 时推送) ───
|
|
153
|
+
if (sessionContext.isNew) {
|
|
154
|
+
emitter.emit(this.buildSSEEvent('session.created', correlationId, '', {
|
|
155
|
+
sessionId,
|
|
156
|
+
userId,
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
159
|
+
// ─── Step 3: 创建 Task(Hosting 传入 taskId 时复用)───
|
|
160
|
+
const timeout = req.config?.timeout ?? 60000;
|
|
161
|
+
const task = await this.taskService.create({
|
|
162
|
+
id: req.taskId,
|
|
163
|
+
agentId: agentCode,
|
|
164
|
+
sessionId,
|
|
165
|
+
userId,
|
|
166
|
+
correlationId,
|
|
167
|
+
input: req.input,
|
|
168
|
+
timeout,
|
|
169
|
+
});
|
|
170
|
+
const taskId = task.id;
|
|
171
|
+
// ─── Step 4: 启动 Task (pending → running) ───
|
|
172
|
+
await this.taskService.updateStatus(taskId, 'running');
|
|
173
|
+
// ─── Step 4b: 持久化本轮 user(多轮短期记忆)───
|
|
174
|
+
await persistUserTurnMessage(this.messageService, {
|
|
175
|
+
sessionId,
|
|
176
|
+
taskId,
|
|
177
|
+
correlationId,
|
|
178
|
+
content: req.input,
|
|
179
|
+
});
|
|
180
|
+
// ─── Emit: task.started ───
|
|
181
|
+
emitter.emit(this.buildSSEEvent('task.started', correlationId, taskId, {
|
|
182
|
+
taskId,
|
|
183
|
+
sessionId,
|
|
184
|
+
}));
|
|
185
|
+
// ─── Step 5: 构建 Graph — 每次请求创建独立 StateGraph 实例,确保请求间无共享可变状态 ───
|
|
186
|
+
const loadOpts = { agentVersion: req.agentVersion };
|
|
187
|
+
const graphDsl = this.graphLoader
|
|
188
|
+
? await this.graphLoader.loadGraph(agentCode, loadOpts)
|
|
189
|
+
: DEFAULT_GRAPH_DSL;
|
|
190
|
+
const graph = await this.graphEngine.buildGraph(graphDsl);
|
|
191
|
+
const loadedToolsBase = this.graphLoader
|
|
192
|
+
? toLoadedToolMap(await this.graphLoader.loadToolDefinitions(agentCode, loadOpts))
|
|
193
|
+
: undefined;
|
|
194
|
+
const loadedSkills = this.graphLoader
|
|
195
|
+
? await this.graphLoader.loadSkillDefinitions(agentCode, { ...loadOpts, userId })
|
|
196
|
+
: undefined;
|
|
197
|
+
const skillDefinitions = toLoadedSkillMap(loadedSkills);
|
|
198
|
+
// Skill scripts 虚拟 Tool 并入 loadedTools(同名不覆盖平台 Tool)
|
|
199
|
+
const loadedTools = mergeSkillScriptTools(loadedToolsBase, loadedSkills);
|
|
200
|
+
const promptRoots = this.graphLoader
|
|
201
|
+
? await this.graphLoader.resolvePromptRoots(agentCode, req.agentVersion)
|
|
202
|
+
: [];
|
|
203
|
+
// 组装 GraphState:有 Checkpoint 历史则只追加本轮 user,避免双重 append
|
|
204
|
+
const history = messageRecordsToGraphMessages(sessionContext.messages);
|
|
205
|
+
const messages = await buildTurnGraphMessages({
|
|
206
|
+
history,
|
|
207
|
+
input: req.input,
|
|
208
|
+
checkpointSaver: this.checkpointSaver,
|
|
209
|
+
threadId: sessionId,
|
|
210
|
+
});
|
|
211
|
+
const skillInput = resolveSkillInputFromInvokeInput(req.input);
|
|
212
|
+
let assistantText = '';
|
|
213
|
+
let toolCallReasoningContent;
|
|
214
|
+
let assistantReasoningContent;
|
|
215
|
+
const pendingToolCalls = [];
|
|
216
|
+
const toolResults = [];
|
|
217
|
+
// ─── Step 6: Graph.stream() 流式执行 ───
|
|
218
|
+
try {
|
|
219
|
+
const eventStream = this.graphEngine.stream(graph, {
|
|
220
|
+
messages,
|
|
221
|
+
userId,
|
|
222
|
+
delegationToken: executionContext.delegationToken,
|
|
223
|
+
agentCode,
|
|
224
|
+
agentVersion: req.agentVersion,
|
|
225
|
+
correlationId,
|
|
226
|
+
taskId,
|
|
227
|
+
sessionId,
|
|
228
|
+
executionContext,
|
|
229
|
+
forceToolServer: req.config?.forceToolServer,
|
|
230
|
+
loadedTools,
|
|
231
|
+
loadedSkills,
|
|
232
|
+
skillDefinitions,
|
|
233
|
+
skillInput,
|
|
234
|
+
promptRoots,
|
|
235
|
+
traceId: resolveTraceId(req),
|
|
236
|
+
traceCollector: this.traceCollector,
|
|
237
|
+
});
|
|
238
|
+
// 逐事件转发到 SSE;顺带把节点 token 记入 TokenStatsService(stream 原先未 record → 结尾全 0)
|
|
239
|
+
for await (const runtimeEvent of eventStream) {
|
|
240
|
+
// 连接已断开则提前退出
|
|
241
|
+
if (!emitter.isConnected) {
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
if (runtimeEvent.type === 'stats.node_token_usage') {
|
|
245
|
+
const p = runtimeEvent.payload;
|
|
246
|
+
this.tokenStatsService.record(taskId, {
|
|
247
|
+
nodeId: p.nodeId ?? 'unknown',
|
|
248
|
+
model: p.model ?? 'unknown',
|
|
249
|
+
inputTokens: p.inputTokens ?? 0,
|
|
250
|
+
outputTokens: p.outputTokens ?? 0,
|
|
251
|
+
costEstimate: p.costEstimate ?? 0,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (runtimeEvent.type === 'tool.called') {
|
|
255
|
+
const p = runtimeEvent.payload;
|
|
256
|
+
if (p.toolCallId && p.toolName) {
|
|
257
|
+
pendingToolCalls.push({
|
|
258
|
+
id: p.toolCallId,
|
|
259
|
+
name: p.toolName,
|
|
260
|
+
arguments: p.arguments ?? {},
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
if (typeof p.reasoningContent === 'string' && p.reasoningContent) {
|
|
264
|
+
toolCallReasoningContent = p.reasoningContent;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (runtimeEvent.type === 'tool.result') {
|
|
268
|
+
const p = runtimeEvent.payload;
|
|
269
|
+
if (p.toolCallId && p.toolName) {
|
|
270
|
+
toolResults.push({
|
|
271
|
+
toolCallId: p.toolCallId,
|
|
272
|
+
toolName: p.toolName,
|
|
273
|
+
content: p.content,
|
|
274
|
+
success: p.success !== false,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const streamedReasoning = extractStreamReasoning(runtimeEvent.type, runtimeEvent.payload);
|
|
279
|
+
if (streamedReasoning)
|
|
280
|
+
assistantReasoningContent = streamedReasoning;
|
|
281
|
+
const delta = extractStreamTextDelta(runtimeEvent.type, runtimeEvent.payload);
|
|
282
|
+
if (delta) {
|
|
283
|
+
if (runtimeEvent.type === 'response.final') {
|
|
284
|
+
// final 若带完整文本则覆盖累加,避免与 chunk 重复拼接
|
|
285
|
+
if (delta.trim())
|
|
286
|
+
assistantText = delta;
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
assistantText += delta;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// 将 RuntimeEvent 转为 SSEEvent 并推送
|
|
293
|
+
emitter.emit(this.runtimeEventToSSE(runtimeEvent, correlationId, taskId));
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
const hitlPaused = unwrapHitlPaused(error);
|
|
298
|
+
if (hitlPaused) {
|
|
299
|
+
await this.taskService.updateStatus(taskId, 'waiting_hitl', buildHitlWaitingTaskOutput({
|
|
300
|
+
threadId: hitlPaused.threadId,
|
|
301
|
+
question: hitlPaused.question,
|
|
302
|
+
options: hitlPaused.options,
|
|
303
|
+
}));
|
|
304
|
+
await persistHitlWaitingPlaceholder(this.messageService, {
|
|
305
|
+
sessionId,
|
|
306
|
+
taskId,
|
|
307
|
+
correlationId,
|
|
308
|
+
question: hitlPaused.question,
|
|
309
|
+
options: hitlPaused.options,
|
|
310
|
+
threadId: hitlPaused.threadId,
|
|
311
|
+
});
|
|
312
|
+
// interrupt 已 emit hitl.waiting;此处补状态事件并正常收尾(非 failed)
|
|
313
|
+
emitter.emit(this.buildSSEEvent('hitl.waited', correlationId, taskId, buildHitlWaitedPayload(hitlPaused)));
|
|
314
|
+
emitter.close();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
// ─── 错误处理:TokenBudgetExhausted ───
|
|
318
|
+
if (error instanceof TokenBudgetExhaustedError) {
|
|
319
|
+
await this.taskService.updateStatus(taskId, 'token_exhausted', error.message);
|
|
320
|
+
this.emitErrorAndClose(emitter, correlationId, taskId, error);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
// ─── 错误处理:Timeout ───
|
|
324
|
+
if (this.isTimeoutError(error)) {
|
|
325
|
+
await this.taskService.updateStatus(taskId, 'timeout');
|
|
326
|
+
emitter.emit(this.buildSSEEvent('task.error', correlationId, taskId, {
|
|
327
|
+
code: ErrorCodes.TASK_TIMEOUT,
|
|
328
|
+
message: 'Task execution timed out',
|
|
329
|
+
recoverable: false,
|
|
330
|
+
}));
|
|
331
|
+
emitter.close();
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
// ─── 错误处理:通用错误 ───
|
|
335
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
336
|
+
await this.taskService.updateStatus(taskId, 'failed', errorMessage);
|
|
337
|
+
this.emitErrorAndClose(emitter, correlationId, taskId, error);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
// ─── Step 7: 发送结束事件序列 ───
|
|
341
|
+
// Emit: response.final(带完整 assistant 文本,供客户端兜底)
|
|
342
|
+
const tokenStats = this.tokenStatsService.getTaskStats(taskId);
|
|
343
|
+
emitter.emit(this.buildSSEEvent('response.final', correlationId, taskId, {
|
|
344
|
+
content: assistantText,
|
|
345
|
+
format: 'text',
|
|
346
|
+
}));
|
|
347
|
+
// Emit: stats.token_usage
|
|
348
|
+
const totalTokens = (tokenStats.total.input ?? 0) + (tokenStats.total.output ?? 0);
|
|
349
|
+
emitter.emit(this.buildSSEEvent('stats.token_usage', correlationId, taskId, {
|
|
350
|
+
total: {
|
|
351
|
+
input: tokenStats.total.input,
|
|
352
|
+
output: tokenStats.total.output,
|
|
353
|
+
total: tokenStats.total.total ?? totalTokens,
|
|
354
|
+
},
|
|
355
|
+
byNode: tokenStats.byNode,
|
|
356
|
+
byModel: tokenStats.byModel,
|
|
357
|
+
costEstimate: tokenStats.costEstimate,
|
|
358
|
+
}));
|
|
359
|
+
// ─── Step 8: 记录 Token + 完成 Task + 关闭 SSE ───
|
|
360
|
+
const duration = Date.now() - startTime;
|
|
361
|
+
// Emit: task.completed
|
|
362
|
+
emitter.emit(this.buildSSEEvent('task.completed', correlationId, taskId, {
|
|
363
|
+
taskId,
|
|
364
|
+
duration,
|
|
365
|
+
}));
|
|
366
|
+
// Task 状态流转 → success
|
|
367
|
+
await this.taskService.updateStatus(taskId, 'success');
|
|
368
|
+
// ─── Step 8b: 持久化 transcript(与 invoke 同序)───
|
|
369
|
+
await persistTurnTranscript(this.messageService, {
|
|
370
|
+
sessionId,
|
|
371
|
+
taskId,
|
|
372
|
+
correlationId,
|
|
373
|
+
messages: buildTurnTranscriptFromStreamEvents({
|
|
374
|
+
pendingToolCalls,
|
|
375
|
+
toolResults,
|
|
376
|
+
assistantText,
|
|
377
|
+
toolCallReasoningContent,
|
|
378
|
+
assistantReasoningContent,
|
|
379
|
+
}),
|
|
380
|
+
assistantTokenCount: tokenStats.total.output ?? 0,
|
|
381
|
+
});
|
|
382
|
+
// 关闭 SSE 连接
|
|
383
|
+
emitter.close();
|
|
384
|
+
}
|
|
385
|
+
// ─────────────────────────────────────────────
|
|
386
|
+
// Private Helpers
|
|
387
|
+
// ─────────────────────────────────────────────
|
|
388
|
+
/**
|
|
389
|
+
* 将 RuntimeEvent 转为 SSEEvent
|
|
390
|
+
*/
|
|
391
|
+
runtimeEventToSSE(event, correlationId, taskId) {
|
|
392
|
+
return {
|
|
393
|
+
type: event.type,
|
|
394
|
+
data: event.payload,
|
|
395
|
+
correlationId: event.correlationId ?? correlationId,
|
|
396
|
+
taskId: event.taskId ?? taskId,
|
|
397
|
+
timestamp: event.timestamp,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* 构建标准 SSEEvent
|
|
402
|
+
*/
|
|
403
|
+
buildSSEEvent(type, correlationId, taskId, data) {
|
|
404
|
+
return {
|
|
405
|
+
type,
|
|
406
|
+
data,
|
|
407
|
+
correlationId,
|
|
408
|
+
taskId,
|
|
409
|
+
timestamp: new Date().toISOString(),
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* 发射错误事件并关闭连接
|
|
414
|
+
*/
|
|
415
|
+
emitErrorAndClose(emitter, correlationId, taskId, error) {
|
|
416
|
+
const appErr = classifyRuntimeError(error);
|
|
417
|
+
const body = appErr.toApiResponse();
|
|
418
|
+
emitter.emit(this.buildSSEEvent('task.error', correlationId, taskId, {
|
|
419
|
+
code: body.code,
|
|
420
|
+
message: body.message ?? '系统内部错误',
|
|
421
|
+
recoverable: false,
|
|
422
|
+
}));
|
|
423
|
+
emitter.close();
|
|
424
|
+
}
|
|
425
|
+
isTimeoutError(error) {
|
|
426
|
+
if (error instanceof Error) {
|
|
427
|
+
const msg = error.message.toLowerCase();
|
|
428
|
+
return msg.includes('timeout') || msg.includes('timed out');
|
|
429
|
+
}
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
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
|
+
* 认证模式
|
|
13
|
+
*/
|
|
14
|
+
export type AuthMode = 'cas_sso' | 'api_key' | 'cli_token';
|
|
15
|
+
/**
|
|
16
|
+
* 认证后的用户信息
|
|
17
|
+
*/
|
|
18
|
+
export interface AuthenticatedUser {
|
|
19
|
+
/** 用户 ID */
|
|
20
|
+
userId: string;
|
|
21
|
+
/** 用户角色列表 */
|
|
22
|
+
roles: string[];
|
|
23
|
+
/** 使用的认证方式 */
|
|
24
|
+
authMode: AuthMode;
|
|
25
|
+
/** 关联的 Agent(值为 agentCode;API Key 场景可能绑定特定 Agent) */
|
|
26
|
+
agentId?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 框架无关的请求抽象
|
|
30
|
+
*/
|
|
31
|
+
export interface AuthRequest {
|
|
32
|
+
/** HTTP 请求头(key 小写) */
|
|
33
|
+
headers: Record<string, string | undefined>;
|
|
34
|
+
/** 解析后的 Cookie(可选) */
|
|
35
|
+
cookies?: Record<string, string>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 认证服务接口 — 由外部实现注入
|
|
39
|
+
*/
|
|
40
|
+
export interface IAuthService {
|
|
41
|
+
/**
|
|
42
|
+
* 验证 token 并返回用户信息
|
|
43
|
+
* @param token - 待验证的凭证
|
|
44
|
+
* @param mode - 认证模式
|
|
45
|
+
* @returns 验证成功返回用户信息,失败返回 null
|
|
46
|
+
*/
|
|
47
|
+
validate(token: string, mode: AuthMode): Promise<AuthenticatedUser | null>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 认证失败自定义错误
|
|
51
|
+
*/
|
|
52
|
+
export declare class AuthenticationError extends Error {
|
|
53
|
+
readonly code = "AUTHENTICATION_FAILED";
|
|
54
|
+
constructor(message?: string);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Auth Middleware — 按优先级尝试3种认证方式
|
|
58
|
+
*
|
|
59
|
+
* 优先级:CAS SSO Cookie > Authorization Bearer > X-CLI-Token
|
|
60
|
+
*/
|
|
61
|
+
export declare class AuthMiddleware {
|
|
62
|
+
private readonly authService;
|
|
63
|
+
constructor(authService: IAuthService);
|
|
64
|
+
/**
|
|
65
|
+
* 认证入口
|
|
66
|
+
*
|
|
67
|
+
* 按优先级依次尝试:
|
|
68
|
+
* 1. CAS SSO Cookie (CAS_TOKEN)
|
|
69
|
+
* 2. Authorization: Bearer <token> (API Key)
|
|
70
|
+
* 3. X-CLI-Token header (CLI Token)
|
|
71
|
+
*
|
|
72
|
+
* @throws AuthenticationError 如果无有效凭证或验证失败
|
|
73
|
+
*/
|
|
74
|
+
authenticate(req: AuthRequest): Promise<AuthenticatedUser>;
|
|
75
|
+
/**
|
|
76
|
+
* 从 Cookie 中提取 CAS Token
|
|
77
|
+
*/
|
|
78
|
+
private extractCasToken;
|
|
79
|
+
/**
|
|
80
|
+
* 从 Authorization header 提取 Bearer Token
|
|
81
|
+
*/
|
|
82
|
+
private extractBearerToken;
|
|
83
|
+
/**
|
|
84
|
+
* 从 X-CLI-Token header 提取 CLI Token
|
|
85
|
+
*/
|
|
86
|
+
private extractCliToken;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 便捷函数 — 创建 AuthMiddleware 实例并执行认证
|
|
90
|
+
*
|
|
91
|
+
* @param req - 框架无关的请求对象
|
|
92
|
+
* @param authService - 认证服务实现
|
|
93
|
+
* @returns 认证后的用户信息
|
|
94
|
+
* @throws AuthenticationError
|
|
95
|
+
*/
|
|
96
|
+
export declare function authenticate(req: AuthRequest, authService: IAuthService): Promise<AuthenticatedUser>;
|