@gt-fe/eap-runtime 0.0.8 → 0.0.11
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 +15 -20
- package/dist/api/handlers/invoke.handler.js +7 -3
- package/dist/api/handlers/messages.handler.js +0 -1
- package/dist/api/handlers/stream.handler.js +8 -4
- package/dist/api/routes/agent.routes.d.ts +2 -2
- package/dist/api/routes/agent.routes.js +2 -2
- package/dist/checkpoint/checkpoint-ref-notify.d.ts +10 -0
- package/dist/checkpoint/checkpoint-ref-notify.js +59 -0
- package/dist/checkpoint/index.d.ts +1 -0
- package/dist/checkpoint/index.js +1 -0
- package/dist/checkpoint/pg-checkpoint-saver.js +25 -2
- package/dist/common/agent-code.d.ts +2 -4
- package/dist/common/agent-code.js +4 -5
- package/dist/common/types.d.ts +5 -5
- package/dist/common/types.js +2 -2
- package/dist/contracts/permission-checker.d.ts +1 -1
- package/dist/contracts/trace-collector.d.ts +16 -2
- package/dist/debug/llm-turn-log.d.ts +100 -0
- package/dist/debug/llm-turn-log.js +130 -0
- package/dist/debug/pg-llm-turn-log.d.ts +22 -0
- package/dist/debug/pg-llm-turn-log.js +57 -0
- package/dist/governance/governance-client.d.ts +1 -1
- package/dist/governance/governance-client.js +40 -16
- package/dist/governance/index.d.ts +2 -2
- package/dist/governance/index.js +1 -1
- package/dist/governance/permission-guard.d.ts +2 -1
- package/dist/governance/permission-guard.js +13 -4
- package/dist/graph/adapters/langgraph-checkpointer.js +3 -1
- package/dist/graph/adapters/langgraph.adapter.d.ts +1 -0
- package/dist/graph/adapters/langgraph.adapter.js +153 -92
- package/dist/graph/adapters/skill-read.d.ts +12 -0
- package/dist/graph/adapters/skill-read.js +63 -0
- package/dist/graph/adapters/subgraph-compiler.js +5 -0
- package/dist/graph/contracts/executable-graph.d.ts +11 -9
- package/dist/graph/contracts/executable-graph.js +1 -1
- package/dist/graph/hitl/hitl-handler.d.ts +10 -0
- package/dist/graph/hitl/hitl-handler.js +50 -6
- package/dist/graph/nodes/llm-node.d.ts +14 -0
- package/dist/graph/nodes/skill-bind-node.js +1 -2
- package/dist/graph/nodes/tool-node.d.ts +2 -0
- package/dist/graph/nodes/tool-node.js +50 -10
- package/dist/graph/trace-span.d.ts +22 -0
- package/dist/graph/trace-span.js +69 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +3 -1
- package/dist/memory/compression/compression.repository.d.ts +1 -15
- package/dist/providers/echo-llm-provider.d.ts +1 -1
- package/dist/providers/echo-llm-provider.js +4 -3
- package/dist/providers/http-llm-provider.d.ts +4 -0
- package/dist/providers/http-llm-provider.js +129 -4
- package/dist/providers/local-llm-provider.d.ts +5 -1
- package/dist/providers/local-llm-provider.js +14 -6
- package/dist/providers/routing-llm-provider.d.ts +4 -0
- package/dist/providers/routing-llm-provider.js +12 -2
- package/dist/registry/agent-models.d.ts +1 -1
- package/dist/registry/agent-models.js +1 -1
- package/dist/registry/agent-registry-client.d.ts +3 -3
- package/dist/registry/deployment-snapshot.d.ts +17 -5
- package/dist/registry/deployment-snapshot.js +97 -49
- package/dist/registry/graph-loader.d.ts +2 -2
- package/dist/registry/graph-loader.js +43 -80
- package/dist/registry/index.d.ts +2 -2
- package/dist/registry/index.js +2 -2
- package/dist/registry/preload-errors.d.ts +1 -1
- package/dist/registry/preload-errors.js +1 -1
- package/dist/registry/skill-io-guard.js +1 -1
- package/dist/registry/skill-tree.d.ts +3 -0
- package/dist/registry/skill-tree.js +41 -3
- package/dist/runtime/agent-runtime.d.ts +42 -3
- package/dist/runtime/agent-runtime.js +129 -39
- package/dist/runtime/dev-runtime.d.ts +7 -4
- package/dist/runtime/dev-runtime.js +24 -21
- package/dist/runtime/index.d.ts +3 -3
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/storage-profile.d.ts +19 -10
- package/dist/runtime/storage-profile.js +42 -29
- package/dist/runtime/types.d.ts +17 -19
- package/dist/server.js +2 -2
- package/dist/session/session.service.d.ts +5 -0
- package/dist/session/session.service.js +12 -0
- package/dist/sse/events/index.d.ts +5 -3
- package/dist/sse/events/index.js +2 -0
- package/dist/sse/events/skill-events.d.ts +12 -1
- package/dist/sse/events/skill-events.js +1 -1
- package/dist/sse/trace-collector.d.ts +10 -0
- package/dist/sse/trace-collector.js +1 -0
- package/dist/token/token-budget.service.d.ts +2 -2
- package/dist/token/token-budget.service.js +1 -1
- package/dist/tool/create-tool-executor.d.ts +1 -1
- package/dist/tool/create-tool-executor.js +3 -2
- package/dist/tool/dev-http-executor.d.ts +1 -1
- package/dist/tool/dev-http-executor.js +10 -7
- package/dist/tool/dev-mcp-executor.js +5 -3
- package/dist/tool/dev-tool-executor.d.ts +1 -1
- package/dist/tool/dev-tool-executor.js +2 -2
- package/dist/tool/harness-command.d.ts +32 -0
- package/dist/tool/harness-command.js +276 -0
- package/dist/tool/harness-primitives.d.ts +54 -0
- package/dist/tool/harness-primitives.js +492 -0
- package/dist/tool/http-tool-executor.js +16 -21
- package/dist/tool/index.d.ts +4 -2
- package/dist/tool/index.js +4 -2
- package/dist/tool/local-mcp-client.d.ts +1 -1
- package/dist/tool/local-mcp-client.js +54 -23
- package/dist/tool/local-tool-executor.d.ts +4 -4
- package/dist/tool/local-tool-executor.js +18 -16
- package/dist/tool/mcp-tool-executor.js +23 -7
- package/dist/tool/skill-script-refs.d.ts +20 -0
- package/dist/tool/skill-script-refs.js +62 -0
- package/dist/tool/system-prompt-builder.d.ts +61 -25
- package/dist/tool/system-prompt-builder.js +198 -92
- package/dist/tool/timeout.d.ts +14 -0
- package/dist/tool/timeout.js +36 -0
- package/dist/tool/tool-confirmation.js +2 -1
- package/dist/tool/tool-execution-router.d.ts +1 -1
- package/dist/tool/tool-execution-router.js +2 -2
- package/dist/tool/tool-executor.interface.d.ts +23 -7
- package/dist/tool/tool-orchestrator.d.ts +1 -1
- package/dist/tool/tool-orchestrator.js +6 -3
- package/dist/utils/format-error.d.ts +2 -2
- package/dist/utils/format-error.js +2 -2
- package/dist/utils/http-error.d.ts +2 -2
- package/dist/utils/http-error.js +2 -2
- package/package.json +3 -3
- package/dist/common/concurrency.d.ts +0 -79
- package/dist/common/concurrency.js +0 -121
- package/dist/common/queue-consumer.d.ts +0 -125
- package/dist/common/queue-consumer.js +0 -159
- package/dist/tool/mock-tool-executor.d.ts +0 -28
- package/dist/tool/mock-tool-executor.js +0 -65
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ Enterprise Agent Platform **执行引擎**(LangGraph.js):Agent Graph 编
|
|
|
8
8
|
|
|
9
9
|
| 日期 | 摘要 |
|
|
10
10
|
|------|------|
|
|
11
|
+
| 2026-08-24 | 0.0.10:官方 Skill / Harness、`ForkParams`、对话详情、存储两档。依赖 `@eap/contracts@0.0.9`。详见 [CHANGELOG.md](./CHANGELOG.md) |
|
|
12
|
+
| 2026-08-21 | 0.0.9:Gateway `/mcp` JSON-RPC 补 `Accept`;`tools/call` 透传工具版本。详见 [CHANGELOG.md](./CHANGELOG.md) |
|
|
11
13
|
| 2026-08-19 | 0.0.8:Skill 子图 SSE 闭环;`ExecuteParams.traceId`;`tool.called` 改为 Tool 节点开始执行。依赖 `@eap/contracts@0.0.8`。详见 [CHANGELOG.md](./CHANGELOG.md) |
|
|
12
14
|
| 2026-08-18 | 0.0.7:`DevHttpExecutor`、`mode=mcp` 缺配置失败、HTTP 出站语义与 Gateway 共用 `@eap/contracts@0.0.7` |
|
|
13
15
|
| 2026-07-29 | 补全 `.env.example` 全量环境变量(部署上下文 / Tool / 预装 / 存储装配 / 调试分区);§5 预装开关表补 `EAP_PRELOAD_DEFINITION_CACHE` |
|
|
@@ -21,10 +23,12 @@ Enterprise Agent Platform **执行引擎**(LangGraph.js):Agent Graph 编
|
|
|
21
23
|
| 权威文档 | 路径 |
|
|
22
24
|
|----------|------|
|
|
23
25
|
| 模块规格 | [`.kiro/specs/04-runtime-core/`](../.kiro/specs/04-runtime-core/) |
|
|
26
|
+
| Runtime DDL | [`docs/ddl.md`](./docs/ddl.md) |
|
|
24
27
|
| SDK 集成手册 | [`docs/contracts/runtime-sdk-integration-final.md`](../docs/contracts/runtime-sdk-integration-final.md) |
|
|
25
28
|
| 环境变量总表 | [`docs/governance/governance-env-config.md`](../docs/governance/governance-env-config.md) |
|
|
26
29
|
| 预装联调契约 | [`docs/contracts/preload-hosting-runtime-contract.md`](../docs/contracts/preload-hosting-runtime-contract.md) |
|
|
27
30
|
| 预装加载与请求流转 | [`docs/contracts/runtime-preinstall-load-flow.md`](../docs/contracts/runtime-preinstall-load-flow.md) |
|
|
31
|
+
| 技能 FS 待办 | [`docs/TODO-skill-fs.md`](./docs/TODO-skill-fs.md) |
|
|
28
32
|
| 本地 Agent 闭环 | [`docs/workflows/local-agent-dev-loop.md`](../docs/workflows/local-agent-dev-loop.md) |
|
|
29
33
|
|
|
30
34
|
---
|
|
@@ -82,7 +86,7 @@ for await (const ev of agentRuntime.stream({ agentCode, input, sessionId, taskId
|
|
|
82
86
|
await agentRuntime.seedSessionMessages({ agentCode, messages: [ /* role: user | assistant */ ] });
|
|
83
87
|
await agentRuntime.resumeHitl(taskId, { choice, userId, /* … */ });
|
|
84
88
|
for await (const ev of agentRuntime.streamResumeHitl(taskId, { choice, userId })) { /* HITL 续跑事件 */ }
|
|
85
|
-
await agentRuntime.fork(checkpointId, { /*
|
|
89
|
+
await agentRuntime.fork({ checkpointId, taskId, traceId, overrides: { /* … */ } });
|
|
86
90
|
```
|
|
87
91
|
|
|
88
92
|
细则与字段表见 [`docs/contracts/runtime-sdk-integration-final.md`](../docs/contracts/runtime-sdk-integration-final.md)。
|
|
@@ -175,26 +179,18 @@ node ../fixtures/eap-preinstall-sample/scripts/seal-snapshot.mjs
|
|
|
175
179
|
|
|
176
180
|
## 6. 持久化与存储 Profile
|
|
177
181
|
|
|
178
|
-
|
|
182
|
+
`assembleRuntimeStorage()` 按 profile 与环境变量选择介质。表结构见 [`docs/ddl.md`](./docs/ddl.md)。
|
|
179
183
|
|
|
180
|
-
|
|
|
181
|
-
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
| `integration` | Redis + PG | (Hosting Session) | PG | Hosting 内嵌联调 |
|
|
185
|
-
| `production` | Redis + PG | (Hosting Session) | PG | 多副本生产 |
|
|
184
|
+
| 条件 | Checkpoint | Message / LLM 回合 | Token 配额 |
|
|
185
|
+
|------|------------|-------------------|------------|
|
|
186
|
+
| `EAP_RUNTIME_STORAGE_PROFILE=dev`,或未设 profile 且未配置数据库与 Redis | 文件(默认 `.eap/checkpoints`) | 文件 | 进程内,不落库 |
|
|
187
|
+
| `test` / `integration` / `production`,或未设 profile 但已配置 `DATABASE_URL`/`DB_*` 或 `REDIS_*` | Redis + PostgreSQL | PostgreSQL | PostgreSQL `token_budgets` |
|
|
186
188
|
|
|
187
|
-
|
|
189
|
+
后一路径缺少数据库或 Redis 时抛错。显式 `dev` 时即使已配置数据库仍使用文件。
|
|
188
190
|
|
|
189
|
-
|
|
190
|
-
|------|------|
|
|
191
|
-
| `EAP_CHECKPOINT_DIR` | File Checkpoint |
|
|
192
|
-
| `EAP_SESSION_DIR` | File Session |
|
|
193
|
-
| `EAP_MESSAGE_DIR` | File Message |
|
|
194
|
-
|
|
195
|
-
完整策略与库表约定:[`docs/governance/governance-env-config.md` §9](../docs/governance/governance-env-config.md#9-runtime-存储装配策略)、[`docs/architecture/session-message-checkpoint-alignment.md`](../docs/architecture/session-message-checkpoint-alignment.md)、[`docs/verification/db-storage-verification.md`](../docs/verification/db-storage-verification.md)。
|
|
191
|
+
仅文件路径使用的目录变量:`EAP_CHECKPOINT_DIR`、`EAP_SESSION_DIR`、`EAP_MESSAGE_DIR`(可用 `EAP_DATA_DIR` 作为根目录)。
|
|
196
192
|
|
|
197
|
-
|
|
193
|
+
环境变量总表:[governance-env-config.md §9](../docs/governance/governance-env-config.md#9-runtime-存储装配策略)。
|
|
198
194
|
|
|
199
195
|
---
|
|
200
196
|
|
|
@@ -202,8 +198,7 @@ node ../fixtures/eap-preinstall-sample/scripts/seal-snapshot.mjs
|
|
|
202
198
|
|
|
203
199
|
| 模式 | 何时 | 说明 |
|
|
204
200
|
|------|------|------|
|
|
205
|
-
| `
|
|
206
|
-
| `mcp` / DevMcp | `eap chat --tool-mode mcp` | 本机直连 MCP(`EAP_TOOL_EXECUTION_MODE`,仅 createDevRuntime) |
|
|
201
|
+
| `mcp` / DevToolExecutor | 本地默认(`dev` + `mcp`) | 按清单直连 MCP / HTTP / 本机 code |
|
|
207
202
|
| Gateway | 生产 / Hosting | `EAP_TOOL_GATEWAY_TRANSPORT=mcp`(生产);`http` 仅调试 |
|
|
208
203
|
|
|
209
204
|
- 编排:`ToolOrchestrator` + `ToolExecutionRouter`(`deploymentContext`: `server` \| `desktop` \| `dev`)
|
|
@@ -259,7 +254,7 @@ FOUNDATION_SERVICE_URL=...
|
|
|
259
254
|
EAP_DEPLOYMENT_CONTEXT=dev
|
|
260
255
|
EAP_PREINSTALL_ROOT=/abs/path/to/preinstall # 或 Agent 工程内预装树
|
|
261
256
|
EAP_RUNTIME_STORAGE_PROFILE=dev
|
|
262
|
-
EAP_TOOL_EXECUTION_MODE=
|
|
257
|
+
EAP_TOOL_EXECUTION_MODE=mcp # 本地默认;http-debug 走 Gateway 调试口
|
|
263
258
|
# OPENAI_BASE_URL / OPENAI_API_KEY / EAP_DEFAULT_MODEL
|
|
264
259
|
```
|
|
265
260
|
|
|
@@ -21,7 +21,8 @@ import { TokenBudgetExhaustedError } from '../../token/token-budget-guard.js';
|
|
|
21
21
|
import { resolveExecutionContext } from '../../governance/governance-client.js';
|
|
22
22
|
import { resolveSkillInputFromInvokeInput } from '../../registry/skill-io-guard.js';
|
|
23
23
|
import { toLoadedToolMap } from '../../tool/loaded-tool-definition.js';
|
|
24
|
-
import { toLoadedSkillMap
|
|
24
|
+
import { toLoadedSkillMap } from '../../tool/system-prompt-builder.js';
|
|
25
|
+
import { assembleLoadedTools } from '../../tool/harness-primitives.js';
|
|
25
26
|
import { resolveAgentCode } from '../../common/agent-code.js';
|
|
26
27
|
import { unwrapHitlPaused } from '../../graph/hitl/hitl-handler.js';
|
|
27
28
|
import { resolveTraceId } from '../../common/trace-id.js';
|
|
@@ -173,11 +174,13 @@ export class InvokeOrchestrator {
|
|
|
173
174
|
})
|
|
174
175
|
: undefined;
|
|
175
176
|
const skillDefinitions = toLoadedSkillMap(loadedSkills);
|
|
176
|
-
|
|
177
|
-
const loadedTools = mergeSkillScriptTools(loadedToolsBase, loadedSkills);
|
|
177
|
+
const loadedTools = assembleLoadedTools(loadedToolsBase);
|
|
178
178
|
const promptRoots = this.graphLoader
|
|
179
179
|
? await this.graphLoader.resolvePromptRoots(agentCode, req.agentVersion)
|
|
180
180
|
: [];
|
|
181
|
+
const agentDir = this.graphLoader
|
|
182
|
+
? (await this.graphLoader.resolveAgentDir(agentCode, req.agentVersion)) ?? undefined
|
|
183
|
+
: undefined;
|
|
181
184
|
// 组装 GraphState:有 Checkpoint 历史则只追加本轮 user,避免双重 append
|
|
182
185
|
const history = messageRecordsToGraphMessages(sessionContext.messages);
|
|
183
186
|
const messages = await buildTurnGraphMessages({
|
|
@@ -204,6 +207,7 @@ export class InvokeOrchestrator {
|
|
|
204
207
|
skillDefinitions,
|
|
205
208
|
skillInput,
|
|
206
209
|
promptRoots,
|
|
210
|
+
agentDir,
|
|
207
211
|
traceId: resolveTraceId(req),
|
|
208
212
|
traceCollector: this.traceCollector,
|
|
209
213
|
});
|
|
@@ -47,7 +47,6 @@ export class MessagesOrchestrator {
|
|
|
47
47
|
const agentVersion = req.agentVersion ?? metaVersion;
|
|
48
48
|
// ─── Step 2: 委托 InvokeOrchestrator(user/assistant Message 由 invoke 主路径写回)───
|
|
49
49
|
const invokeReq = {
|
|
50
|
-
agentId: session.agentId,
|
|
51
50
|
agentCode: session.agentId,
|
|
52
51
|
input,
|
|
53
52
|
sessionId,
|
|
@@ -25,10 +25,11 @@ import { TokenBudgetExhaustedError } from '../../token/token-budget-guard.js';
|
|
|
25
25
|
import { SSEEmitter } from '../../sse/sse-emitter.js';
|
|
26
26
|
import { resolveExecutionContext } from '../../governance/governance-client.js';
|
|
27
27
|
import { resolveSkillInputFromInvokeInput } from '../../registry/skill-io-guard.js';
|
|
28
|
-
import { ErrorCodes } from '@
|
|
28
|
+
import { ErrorCodes } from '@eap/contracts';
|
|
29
29
|
import { classifyRuntimeError } from '../../utils/http-error.js';
|
|
30
30
|
import { toLoadedToolMap } from '../../tool/loaded-tool-definition.js';
|
|
31
|
-
import { toLoadedSkillMap
|
|
31
|
+
import { toLoadedSkillMap } from '../../tool/system-prompt-builder.js';
|
|
32
|
+
import { assembleLoadedTools } from '../../tool/harness-primitives.js';
|
|
32
33
|
import { resolveAgentCode } from '../../common/agent-code.js';
|
|
33
34
|
import { unwrapHitlPaused } from './invoke.handler.js';
|
|
34
35
|
import { buildHitlWaitedPayload } from '../../graph/hitl/hitl-handler.js';
|
|
@@ -195,11 +196,13 @@ export class StreamOrchestrator {
|
|
|
195
196
|
? await this.graphLoader.loadSkillDefinitions(agentCode, { ...loadOpts, userId })
|
|
196
197
|
: undefined;
|
|
197
198
|
const skillDefinitions = toLoadedSkillMap(loadedSkills);
|
|
198
|
-
|
|
199
|
-
const loadedTools = mergeSkillScriptTools(loadedToolsBase, loadedSkills);
|
|
199
|
+
const loadedTools = assembleLoadedTools(loadedToolsBase);
|
|
200
200
|
const promptRoots = this.graphLoader
|
|
201
201
|
? await this.graphLoader.resolvePromptRoots(agentCode, req.agentVersion)
|
|
202
202
|
: [];
|
|
203
|
+
const agentDir = this.graphLoader
|
|
204
|
+
? (await this.graphLoader.resolveAgentDir(agentCode, req.agentVersion)) ?? undefined
|
|
205
|
+
: undefined;
|
|
203
206
|
// 组装 GraphState:有 Checkpoint 历史则只追加本轮 user,避免双重 append
|
|
204
207
|
const history = messageRecordsToGraphMessages(sessionContext.messages);
|
|
205
208
|
const messages = await buildTurnGraphMessages({
|
|
@@ -232,6 +235,7 @@ export class StreamOrchestrator {
|
|
|
232
235
|
skillDefinitions,
|
|
233
236
|
skillInput,
|
|
234
237
|
promptRoots,
|
|
238
|
+
agentDir,
|
|
235
239
|
traceId: resolveTraceId(req),
|
|
236
240
|
traceCollector: this.traceCollector,
|
|
237
241
|
});
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* 生产环境由 Hosting 提供对外 HTTP;本模块供 `EAP_DEV_HTTP=1` 本地调试。
|
|
5
5
|
*/
|
|
6
6
|
import type { ServerResponse } from 'node:http';
|
|
7
|
-
import type { InvokeRequest as ContractInvokeRequest, InvokeResponse as ContractInvokeResponse } from '@
|
|
7
|
+
import type { InvokeRequest as ContractInvokeRequest, InvokeResponse as ContractInvokeResponse } from '@eap/contracts';
|
|
8
8
|
import type { ITaskManager } from '../../task/task.service.js';
|
|
9
9
|
import type { SessionService } from '../../session/session.service.js';
|
|
10
10
|
import type { IStateGraphEngine } from '../../graph/contracts/executable-graph.js';
|
|
11
11
|
import type { SSEEmitter } from '../../sse/sse-emitter.js';
|
|
12
|
-
export type { InvokeConfig, InvokeResponseData } from '@
|
|
12
|
+
export type { InvokeConfig, InvokeResponseData } from '@eap/contracts';
|
|
13
13
|
/**
|
|
14
14
|
* dev HTTP 层 Invoke 请求(扩展 userId,Hosting 从 auth 注入)
|
|
15
15
|
*/
|
|
@@ -21,7 +21,7 @@ export function createAgentRouteHandlers(deps) {
|
|
|
21
21
|
*/
|
|
22
22
|
async function invokeHandler(req) {
|
|
23
23
|
const { input, sessionId, config, userId } = req;
|
|
24
|
-
const agentCode = req.agentCode
|
|
24
|
+
const agentCode = req.agentCode;
|
|
25
25
|
if (!agentCode) {
|
|
26
26
|
throw new Error('agentCode is required');
|
|
27
27
|
}
|
|
@@ -109,7 +109,7 @@ export function createAgentRouteHandlers(deps) {
|
|
|
109
109
|
*/
|
|
110
110
|
async function streamHandler(req, res) {
|
|
111
111
|
const { input, sessionId, config, userId } = req;
|
|
112
|
-
const agentCode = req.agentCode
|
|
112
|
+
const agentCode = req.agentCode;
|
|
113
113
|
if (!agentCode) {
|
|
114
114
|
res.write(`event: error\ndata: ${JSON.stringify({ error: 'agentCode is required' })}\n\n`);
|
|
115
115
|
res.end();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoint 落盘后通知上层写 checkpoint_refs。
|
|
3
|
+
* 无 traceId 或 spanId 则跳过;回调失败不抛。
|
|
4
|
+
* collector 不得写入持久化正文。
|
|
5
|
+
*/
|
|
6
|
+
import type { ITraceCollector } from '../contracts/trace-collector.js';
|
|
7
|
+
import type { CheckpointData } from '../graph/contracts/executable-graph.js';
|
|
8
|
+
/** 去掉不可序列化的 collector,再交给 Saver。 */
|
|
9
|
+
export declare function stripCheckpointCollectors(data: CheckpointData): CheckpointData;
|
|
10
|
+
export declare function notifyCheckpointRef(data: CheckpointData, collectorOverride?: ITraceCollector): Promise<void>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoint 落盘后通知上层写 checkpoint_refs。
|
|
3
|
+
* 无 traceId 或 spanId 则跳过;回调失败不抛。
|
|
4
|
+
* collector 不得写入持久化正文。
|
|
5
|
+
*/
|
|
6
|
+
function pickString(...values) {
|
|
7
|
+
for (const value of values) {
|
|
8
|
+
if (typeof value === 'string' && value.trim())
|
|
9
|
+
return value.trim();
|
|
10
|
+
}
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
function omitTraceCollector(record) {
|
|
14
|
+
const { traceCollector: _drop, ...rest } = record;
|
|
15
|
+
return rest;
|
|
16
|
+
}
|
|
17
|
+
/** 去掉不可序列化的 collector,再交给 Saver。 */
|
|
18
|
+
export function stripCheckpointCollectors(data) {
|
|
19
|
+
const state = omitTraceCollector({ ...data.state });
|
|
20
|
+
const snap = data.engineSnapshot ? { ...data.engineSnapshot } : undefined;
|
|
21
|
+
if (snap?.channel_values && typeof snap.channel_values === 'object') {
|
|
22
|
+
snap.channel_values = omitTraceCollector({
|
|
23
|
+
...snap.channel_values,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
...data,
|
|
28
|
+
state: state,
|
|
29
|
+
...(snap ? { engineSnapshot: snap } : {}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export async function notifyCheckpointRef(data, collectorOverride) {
|
|
33
|
+
const channels = data.engineSnapshot && typeof data.engineSnapshot.channel_values === 'object'
|
|
34
|
+
? data.engineSnapshot.channel_values
|
|
35
|
+
: {};
|
|
36
|
+
const state = (data.state ?? {});
|
|
37
|
+
const collector = (collectorOverride ??
|
|
38
|
+
channels['traceCollector'] ??
|
|
39
|
+
state['traceCollector']);
|
|
40
|
+
const traceId = pickString(state['traceId'], channels['traceId']);
|
|
41
|
+
const spanId = pickString(state['lastSpanId'], channels['lastSpanId']);
|
|
42
|
+
if (!collector?.recordCheckpointRef || !traceId || !spanId)
|
|
43
|
+
return;
|
|
44
|
+
try {
|
|
45
|
+
await collector.recordCheckpointRef({
|
|
46
|
+
checkpointId: data.checkpointId,
|
|
47
|
+
traceId,
|
|
48
|
+
spanId,
|
|
49
|
+
summary: {
|
|
50
|
+
nodeId: data.currentNodeId || pickString(channels['currentNode']),
|
|
51
|
+
threadId: data.threadId,
|
|
52
|
+
step: Array.isArray(data.historyPath) ? data.historyPath.length : undefined,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// 采集失败不阻断 Graph / HITL
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -3,6 +3,7 @@ export { RedisCheckpointSaver } from './redis-checkpoint-saver.js';
|
|
|
3
3
|
export type { RedisCheckpointSaverOptions } from './redis-checkpoint-saver.js';
|
|
4
4
|
export { CompositeCheckpointSaver } from './composite-checkpoint-saver.js';
|
|
5
5
|
export { restoreCheckpoint } from './restore-checkpoint.js';
|
|
6
|
+
export { notifyCheckpointRef, stripCheckpointCollectors } from './checkpoint-ref-notify.js';
|
|
6
7
|
export { createCheckpointData, serializeCheckpoint, deserializeCheckpoint, } from './checkpoint-serializer.js';
|
|
7
8
|
export type { CreateCheckpointParams } from './checkpoint-serializer.js';
|
|
8
9
|
export { FileCheckpointSaver } from './file-checkpoint-saver.js';
|
package/dist/checkpoint/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * from './contracts/index.js';
|
|
|
3
3
|
export { RedisCheckpointSaver } from './redis-checkpoint-saver.js';
|
|
4
4
|
export { CompositeCheckpointSaver } from './composite-checkpoint-saver.js';
|
|
5
5
|
export { restoreCheckpoint } from './restore-checkpoint.js';
|
|
6
|
+
export { notifyCheckpointRef, stripCheckpointCollectors } from './checkpoint-ref-notify.js';
|
|
6
7
|
export { createCheckpointData, serializeCheckpoint, deserializeCheckpoint, } from './checkpoint-serializer.js';
|
|
7
8
|
export { FileCheckpointSaver } from './file-checkpoint-saver.js';
|
|
8
9
|
export { InMemoryCheckpointSaver } from './in-memory-checkpoint-saver.js';
|
|
@@ -20,12 +20,16 @@ export class PostgresCheckpointSaver {
|
|
|
20
20
|
*/
|
|
21
21
|
async save(threadId, data) {
|
|
22
22
|
const sql = `
|
|
23
|
-
INSERT INTO checkpoints (
|
|
24
|
-
|
|
23
|
+
INSERT INTO checkpoints (
|
|
24
|
+
id, thread_id, checkpoint_id, current_node_id, history_path, state, engine_snapshot,
|
|
25
|
+
created_by, created_at, updated_by, updated_at
|
|
26
|
+
)
|
|
27
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
25
28
|
ON CONFLICT (thread_id, checkpoint_id) DO UPDATE SET
|
|
26
29
|
current_node_id = EXCLUDED.current_node_id,
|
|
27
30
|
history_path = EXCLUDED.history_path,
|
|
28
31
|
state = EXCLUDED.state,
|
|
32
|
+
engine_snapshot = EXCLUDED.engine_snapshot,
|
|
29
33
|
updated_by = EXCLUDED.updated_by,
|
|
30
34
|
updated_at = EXCLUDED.updated_at
|
|
31
35
|
`;
|
|
@@ -36,6 +40,7 @@ export class PostgresCheckpointSaver {
|
|
|
36
40
|
data.currentNodeId,
|
|
37
41
|
JSON.stringify(data.historyPath),
|
|
38
42
|
JSON.stringify(data.state),
|
|
43
|
+
data.engineSnapshot == null ? null : JSON.stringify(data.engineSnapshot),
|
|
39
44
|
data.createdBy || 'system',
|
|
40
45
|
data.createdAt,
|
|
41
46
|
data.updatedBy || 'system',
|
|
@@ -105,6 +110,7 @@ export class PostgresCheckpointSaver {
|
|
|
105
110
|
currentNodeId: source.currentNodeId,
|
|
106
111
|
historyPath: source.historyPath,
|
|
107
112
|
state: overrides ? { ...source.state, ...overrides } : source.state,
|
|
113
|
+
engineSnapshot: source.engineSnapshot,
|
|
108
114
|
createdBy: 'fork',
|
|
109
115
|
createdAt: now,
|
|
110
116
|
updatedBy: 'fork',
|
|
@@ -128,6 +134,7 @@ export class PostgresCheckpointSaver {
|
|
|
128
134
|
currentNodeId: row.current_node_id,
|
|
129
135
|
historyPath: typeof row.history_path === 'string' ? JSON.parse(row.history_path) : row.history_path,
|
|
130
136
|
state: typeof row.state === 'string' ? JSON.parse(row.state) : row.state,
|
|
137
|
+
engineSnapshot: parseJsonObject(row.engine_snapshot),
|
|
131
138
|
createdBy: row.created_by,
|
|
132
139
|
createdAt: row.created_at.toISOString(),
|
|
133
140
|
updatedBy: row.updated_by,
|
|
@@ -138,3 +145,19 @@ export class PostgresCheckpointSaver {
|
|
|
138
145
|
};
|
|
139
146
|
}
|
|
140
147
|
}
|
|
148
|
+
function parseJsonObject(value) {
|
|
149
|
+
if (value == null || value === '')
|
|
150
|
+
return undefined;
|
|
151
|
+
if (typeof value === 'object')
|
|
152
|
+
return value;
|
|
153
|
+
try {
|
|
154
|
+
const parsed = JSON.parse(value);
|
|
155
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
156
|
+
return parsed;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Agent
|
|
3
|
-
*
|
|
4
|
-
* 正式字段为 agentCode;历史 agentId 仅作同义兜底。
|
|
2
|
+
* Agent 对外主键。只认 agentCode。
|
|
3
|
+
* SessionRecord.agentId 是存储列名(值为 agentCode),不是本函数的入参。
|
|
5
4
|
*/
|
|
6
5
|
export declare function resolveAgentCode(input: {
|
|
7
6
|
agentCode?: string | null;
|
|
8
|
-
agentId?: string | null;
|
|
9
7
|
fallback?: string;
|
|
10
8
|
}): string;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Agent
|
|
3
|
-
*
|
|
4
|
-
* 正式字段为 agentCode;历史 agentId 仅作同义兜底。
|
|
2
|
+
* Agent 对外主键。只认 agentCode。
|
|
3
|
+
* SessionRecord.agentId 是存储列名(值为 agentCode),不是本函数的入参。
|
|
5
4
|
*/
|
|
6
5
|
export function resolveAgentCode(input) {
|
|
7
|
-
const code = input.agentCode ?? input.
|
|
6
|
+
const code = input.agentCode ?? input.fallback;
|
|
8
7
|
if (code == null || code === '') {
|
|
9
|
-
throw new Error('agentCode is required
|
|
8
|
+
throw new Error('agentCode is required');
|
|
10
9
|
}
|
|
11
10
|
return String(code);
|
|
12
11
|
}
|
package/dist/common/types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* eap-runtime 内部共享类型定义
|
|
3
3
|
*
|
|
4
|
-
* 本文件定义 Runtime 模块内部使用的类型,与 @
|
|
5
|
-
* - @
|
|
4
|
+
* 本文件定义 Runtime 模块内部使用的类型,与 @eap/contracts 中的公共协议类型互补但不重复。
|
|
5
|
+
* - @eap/contracts 定义跨模块的公共协议(如 Task 实体、Session 实体、Agent Manifest)
|
|
6
6
|
* - 本文件定义 Runtime 执行引擎内部流转的配置、上下文、枚举等
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
@@ -32,7 +32,7 @@ export declare const DEFAULT_RUNTIME_CONFIG: RuntimeConfig;
|
|
|
32
32
|
/**
|
|
33
33
|
* 执行上下文 — 贯穿 Graph 执行生命周期(Runtime 内部)
|
|
34
34
|
*
|
|
35
|
-
* 平台级 ExecutionContext(@
|
|
35
|
+
* 平台级 ExecutionContext(@eap/contracts)由 Hosting/eap dev 注入;
|
|
36
36
|
* 本类型在 Task 创建后组装,供引擎子服务使用。
|
|
37
37
|
*/
|
|
38
38
|
export interface RuntimeRunContext {
|
|
@@ -62,7 +62,7 @@ export type TaskStatus = 'pending' | 'running' | 'waiting_hitl' | 'success' | 'f
|
|
|
62
62
|
/**
|
|
63
63
|
* Runtime 执行上下文绑定状态(非平台 Session 生命周期)
|
|
64
64
|
*
|
|
65
|
-
* 平台 Session 三态(active/paused/closed)由 Hosting 管理,见 @
|
|
65
|
+
* 平台 Session 三态(active/paused/closed)由 Hosting 管理,见 @eap/contracts。
|
|
66
66
|
* Runtime 仅在引擎内标记执行上下文是否仍可绑定:`active` | `archived`。
|
|
67
67
|
*/
|
|
68
68
|
export type ExecutionSessionBindingStatus = 'active' | 'archived';
|
|
@@ -77,7 +77,7 @@ export type MessageRole = 'user' | 'assistant' | 'system' | 'tool';
|
|
|
77
77
|
/**
|
|
78
78
|
* 单次 LLM/Tool 调用的 Token 消耗记录
|
|
79
79
|
*
|
|
80
|
-
* 与 @
|
|
80
|
+
* 与 @eap/contracts.TokenUsage 的区别:
|
|
81
81
|
* - contracts 版本是 Task 级聚合结果(含 byNode/byModel)
|
|
82
82
|
* - 本类型是单次调用粒度的原始记录,用于 Runtime 内部累计和 stats.node_token 事件
|
|
83
83
|
*/
|
package/dist/common/types.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* eap-runtime 内部共享类型定义
|
|
3
3
|
*
|
|
4
|
-
* 本文件定义 Runtime 模块内部使用的类型,与 @
|
|
5
|
-
* - @
|
|
4
|
+
* 本文件定义 Runtime 模块内部使用的类型,与 @eap/contracts 中的公共协议类型互补但不重复。
|
|
5
|
+
* - @eap/contracts 定义跨模块的公共协议(如 Task 实体、Session 实体、Agent Manifest)
|
|
6
6
|
* - 本文件定义 Runtime 执行引擎内部流转的配置、上下文、枚举等
|
|
7
7
|
*/
|
|
8
8
|
/** RuntimeConfig 默认值 */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 权限校验器接口(对齐 06-governance R16.8)
|
|
3
3
|
*/
|
|
4
|
-
import type { ExecutionContext, GovernancePermissionCheckParams, GovernancePermissionCheckResult } from '@
|
|
4
|
+
import type { ExecutionContext, GovernancePermissionCheckParams, GovernancePermissionCheckResult } from '@eap/contracts';
|
|
5
5
|
/**
|
|
6
6
|
* IPermissionChecker — Runtime 执行期权限校验
|
|
7
7
|
*/
|
|
@@ -82,9 +82,9 @@ export interface ExecutionNodeEvent {
|
|
|
82
82
|
/** 节点名称 */
|
|
83
83
|
name: string;
|
|
84
84
|
/** 节点类型 */
|
|
85
|
-
type: 'start' | 'llm' | 'tool' | 'skill' | 'condition' | 'end';
|
|
85
|
+
type: 'start' | 'llm' | 'tool' | 'skill' | 'condition' | 'hitl' | 'end';
|
|
86
86
|
/** 工具运行环境(type=tool) */
|
|
87
|
-
toolRuntime?: 'local' | 'server' | 'both'
|
|
87
|
+
toolRuntime?: 'local' | 'server' | 'both';
|
|
88
88
|
/** Agent 对外主键 */
|
|
89
89
|
agentCode?: string;
|
|
90
90
|
/** 输入数据 */
|
|
@@ -184,6 +184,20 @@ export interface ITraceCollector {
|
|
|
184
184
|
outputTokens?: number;
|
|
185
185
|
totalTokens?: number;
|
|
186
186
|
}): Promise<void>;
|
|
187
|
+
/**
|
|
188
|
+
* Checkpoint 已落盘后的引用回调。Hosting 适配 TraceClient.recordCheckpointRef。
|
|
189
|
+
* Runtime 仅在同时有 traceId 与 spanId 时调用;不传 graph state 正文。
|
|
190
|
+
*/
|
|
191
|
+
recordCheckpointRef?(input: {
|
|
192
|
+
checkpointId: string;
|
|
193
|
+
traceId: string;
|
|
194
|
+
spanId: string;
|
|
195
|
+
summary?: {
|
|
196
|
+
nodeId?: string;
|
|
197
|
+
threadId?: string;
|
|
198
|
+
step?: number;
|
|
199
|
+
};
|
|
200
|
+
}): Promise<void>;
|
|
187
201
|
/**
|
|
188
202
|
* 创建链路
|
|
189
203
|
*
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 本地 LLM 回合落盘:每次模型调用写一份 JSON(入参、响应、URL、脱敏密钥、system 段)。
|
|
3
|
+
* 默认 `.eap/llm-turns/{sessionId}/`。EAP_LLM_TURN_LOG=0 关闭。
|
|
4
|
+
*/
|
|
5
|
+
export interface LlmTurnContext {
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
taskId?: string;
|
|
8
|
+
nodeId?: string;
|
|
9
|
+
agentCode?: string;
|
|
10
|
+
correlationId?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface LlmTurnRecord extends LlmTurnContext {
|
|
13
|
+
id: string;
|
|
14
|
+
ts: string;
|
|
15
|
+
url: string;
|
|
16
|
+
model: string;
|
|
17
|
+
temperature?: number;
|
|
18
|
+
maxTokens?: number;
|
|
19
|
+
apiKey: string;
|
|
20
|
+
systemPrompt?: string;
|
|
21
|
+
systemSections?: Array<{
|
|
22
|
+
id: string;
|
|
23
|
+
title: string;
|
|
24
|
+
chars: number;
|
|
25
|
+
body?: string;
|
|
26
|
+
}>;
|
|
27
|
+
tools?: string[];
|
|
28
|
+
messages: Array<{
|
|
29
|
+
role: string;
|
|
30
|
+
content: string;
|
|
31
|
+
toolCallId?: string;
|
|
32
|
+
toolCalls?: unknown;
|
|
33
|
+
}>;
|
|
34
|
+
response: {
|
|
35
|
+
content: string;
|
|
36
|
+
toolCalls?: unknown;
|
|
37
|
+
reasoningContent?: string;
|
|
38
|
+
inputTokens: number;
|
|
39
|
+
outputTokens: number;
|
|
40
|
+
finishReason?: string;
|
|
41
|
+
error?: string;
|
|
42
|
+
};
|
|
43
|
+
latencyMs: number;
|
|
44
|
+
}
|
|
45
|
+
export interface LlmTurnIndexEntry {
|
|
46
|
+
id: string;
|
|
47
|
+
ts: string;
|
|
48
|
+
sessionId?: string;
|
|
49
|
+
taskId?: string;
|
|
50
|
+
nodeId?: string;
|
|
51
|
+
model: string;
|
|
52
|
+
url: string;
|
|
53
|
+
file: string;
|
|
54
|
+
inputTokens: number;
|
|
55
|
+
outputTokens: number;
|
|
56
|
+
}
|
|
57
|
+
export type LlmTurnLogKind = 'memory' | 'file' | 'postgres';
|
|
58
|
+
export interface ILlmTurnLog {
|
|
59
|
+
readonly kind: LlmTurnLogKind;
|
|
60
|
+
record(turn: Omit<LlmTurnRecord, 'id' | 'ts'> & {
|
|
61
|
+
id?: string;
|
|
62
|
+
ts?: string;
|
|
63
|
+
}): Promise<LlmTurnRecord>;
|
|
64
|
+
list(sessionId: string): Promise<LlmTurnIndexEntry[]>;
|
|
65
|
+
read(sessionId: string, turnId: string): Promise<LlmTurnRecord | null>;
|
|
66
|
+
listSessions(): Promise<string[]>;
|
|
67
|
+
readonly baseDir: string;
|
|
68
|
+
}
|
|
69
|
+
export declare function finalizeLlmTurn(turn: Omit<LlmTurnRecord, 'id' | 'ts'> & {
|
|
70
|
+
id?: string;
|
|
71
|
+
ts?: string;
|
|
72
|
+
}): LlmTurnRecord;
|
|
73
|
+
export declare function toLlmTurnIndexEntry(record: LlmTurnRecord, file?: string): LlmTurnIndexEntry;
|
|
74
|
+
export declare function maskApiKey(key: string | undefined): string;
|
|
75
|
+
export declare function resolveLlmTurnDir(env?: NodeJS.ProcessEnv, cwd?: string): string;
|
|
76
|
+
export declare function createFileLlmTurnLogFromEnv(env?: NodeJS.ProcessEnv): FileLlmTurnLog | undefined;
|
|
77
|
+
export declare class InMemoryLlmTurnLog implements ILlmTurnLog {
|
|
78
|
+
readonly kind: "memory";
|
|
79
|
+
readonly baseDir = "memory://llm-turns";
|
|
80
|
+
private readonly bySession;
|
|
81
|
+
record(turn: Omit<LlmTurnRecord, 'id' | 'ts'> & {
|
|
82
|
+
id?: string;
|
|
83
|
+
ts?: string;
|
|
84
|
+
}): Promise<LlmTurnRecord>;
|
|
85
|
+
list(sessionId: string): Promise<LlmTurnIndexEntry[]>;
|
|
86
|
+
read(sessionId: string, turnId: string): Promise<LlmTurnRecord | null>;
|
|
87
|
+
listSessions(): Promise<string[]>;
|
|
88
|
+
}
|
|
89
|
+
export declare class FileLlmTurnLog implements ILlmTurnLog {
|
|
90
|
+
readonly baseDir: string;
|
|
91
|
+
readonly kind: "file";
|
|
92
|
+
constructor(baseDir: string);
|
|
93
|
+
record(turn: Omit<LlmTurnRecord, 'id' | 'ts'> & {
|
|
94
|
+
id?: string;
|
|
95
|
+
ts?: string;
|
|
96
|
+
}): Promise<LlmTurnRecord>;
|
|
97
|
+
list(sessionId: string): Promise<LlmTurnIndexEntry[]>;
|
|
98
|
+
read(sessionId: string, turnId: string): Promise<LlmTurnRecord | null>;
|
|
99
|
+
listSessions(): Promise<string[]>;
|
|
100
|
+
}
|