@gt-fe/eap-runtime 0.0.10 → 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 +3 -3
- package/dist/api/handlers/invoke.handler.js +4 -0
- package/dist/api/handlers/stream.handler.js +5 -1
- package/dist/api/routes/agent.routes.d.ts +2 -2
- 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 +1 -1
- 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.adapter.js +12 -7
- package/dist/graph/contracts/executable-graph.d.ts +8 -6
- package/dist/graph/contracts/executable-graph.js +1 -1
- package/dist/graph/hitl/hitl-handler.d.ts +3 -0
- package/dist/graph/hitl/hitl-handler.js +4 -1
- package/dist/graph/nodes/tool-node.js +27 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/providers/echo-llm-provider.js +2 -2
- package/dist/providers/local-llm-provider.d.ts +1 -1
- package/dist/providers/local-llm-provider.js +1 -1
- package/dist/providers/routing-llm-provider.js +1 -1
- 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 +1 -1
- package/dist/registry/deployment-snapshot.d.ts +14 -2
- package/dist/registry/deployment-snapshot.js +57 -31
- package/dist/registry/graph-loader.d.ts +1 -1
- package/dist/registry/graph-loader.js +4 -4
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/index.js +1 -1
- 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.js +1 -1
- package/dist/runtime/agent-runtime.js +19 -5
- package/dist/runtime/dev-runtime.d.ts +1 -1
- package/dist/runtime/dev-runtime.js +6 -10
- package/dist/runtime/types.d.ts +2 -2
- package/dist/server.js +1 -1
- package/dist/sse/events/skill-events.d.ts +1 -1
- package/dist/sse/events/skill-events.js +1 -1
- package/dist/tool/create-tool-executor.d.ts +1 -1
- 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 +25 -3
- package/dist/tool/harness-primitives.js +157 -50
- package/dist/tool/http-tool-executor.js +15 -20
- package/dist/tool/index.d.ts +3 -2
- package/dist/tool/index.js +3 -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 +1 -1
- package/dist/tool/local-tool-executor.js +13 -9
- package/dist/tool/mcp-tool-executor.js +14 -6
- 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 +2 -2
- package/dist/tool/system-prompt-builder.js +8 -5
- 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 +1 -1
- package/dist/tool/tool-executor.interface.d.ts +13 -3
- 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 +2 -2
- 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
|
@@ -28,6 +28,7 @@ Enterprise Agent Platform **执行引擎**(LangGraph.js):Agent Graph 编
|
|
|
28
28
|
| 环境变量总表 | [`docs/governance/governance-env-config.md`](../docs/governance/governance-env-config.md) |
|
|
29
29
|
| 预装联调契约 | [`docs/contracts/preload-hosting-runtime-contract.md`](../docs/contracts/preload-hosting-runtime-contract.md) |
|
|
30
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) |
|
|
31
32
|
| 本地 Agent 闭环 | [`docs/workflows/local-agent-dev-loop.md`](../docs/workflows/local-agent-dev-loop.md) |
|
|
32
33
|
|
|
33
34
|
---
|
|
@@ -197,8 +198,7 @@ node ../fixtures/eap-preinstall-sample/scripts/seal-snapshot.mjs
|
|
|
197
198
|
|
|
198
199
|
| 模式 | 何时 | 说明 |
|
|
199
200
|
|------|------|------|
|
|
200
|
-
| `
|
|
201
|
-
| `mcp` / DevMcp | `eap chat --tool-mode mcp` | 本机直连 MCP(`EAP_TOOL_EXECUTION_MODE`,仅 createDevRuntime) |
|
|
201
|
+
| `mcp` / DevToolExecutor | 本地默认(`dev` + `mcp`) | 按清单直连 MCP / HTTP / 本机 code |
|
|
202
202
|
| Gateway | 生产 / Hosting | `EAP_TOOL_GATEWAY_TRANSPORT=mcp`(生产);`http` 仅调试 |
|
|
203
203
|
|
|
204
204
|
- 编排:`ToolOrchestrator` + `ToolExecutionRouter`(`deploymentContext`: `server` \| `desktop` \| `dev`)
|
|
@@ -254,7 +254,7 @@ FOUNDATION_SERVICE_URL=...
|
|
|
254
254
|
EAP_DEPLOYMENT_CONTEXT=dev
|
|
255
255
|
EAP_PREINSTALL_ROOT=/abs/path/to/preinstall # 或 Agent 工程内预装树
|
|
256
256
|
EAP_RUNTIME_STORAGE_PROFILE=dev
|
|
257
|
-
EAP_TOOL_EXECUTION_MODE=
|
|
257
|
+
EAP_TOOL_EXECUTION_MODE=mcp # 本地默认;http-debug 走 Gateway 调试口
|
|
258
258
|
# OPENAI_BASE_URL / OPENAI_API_KEY / EAP_DEFAULT_MODEL
|
|
259
259
|
```
|
|
260
260
|
|
|
@@ -178,6 +178,9 @@ export class InvokeOrchestrator {
|
|
|
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
|
});
|
|
@@ -25,7 +25,7 @@ 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
31
|
import { toLoadedSkillMap } from '../../tool/system-prompt-builder.js';
|
|
@@ -200,6 +200,9 @@ export class StreamOrchestrator {
|
|
|
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
|
*/
|
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
|
*/
|
|
@@ -84,7 +84,7 @@ export interface ExecutionNodeEvent {
|
|
|
84
84
|
/** 节点类型 */
|
|
85
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
|
/** 输入数据 */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 治理服务 HTTP 客户端(06-governance validateToken / checkPermission)
|
|
3
3
|
*/
|
|
4
|
-
import type { ExecutionContext, GovernancePermissionCheckParams, GovernancePermissionCheckResult } from '@
|
|
4
|
+
import type { ExecutionContext, GovernancePermissionCheckParams, GovernancePermissionCheckResult } from '@eap/contracts';
|
|
5
5
|
export interface HttpGovernanceClientOptions {
|
|
6
6
|
baseUrl: string;
|
|
7
7
|
timeout?: number;
|
|
@@ -40,25 +40,29 @@ export class HttpGovernanceClient {
|
|
|
40
40
|
if (response.status === 503 || response.status >= 500) {
|
|
41
41
|
return { allowed: false, reason: 'GOVERNANCE_UNAVAILABLE' };
|
|
42
42
|
}
|
|
43
|
+
if (response.status === 403) {
|
|
44
|
+
return { allowed: false, reason: await readDenyReason(response, 'NO_PERMISSION') };
|
|
45
|
+
}
|
|
43
46
|
if (!response.ok) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
return { allowed: false, reason: 'NO_PERMISSION' };
|
|
47
|
+
// 401/404/400 等是 Runtime→Foundation hop 失败,不是 C2「没工具权」
|
|
48
|
+
return { allowed: false, reason: 'GOVERNANCE_UNAVAILABLE' };
|
|
49
|
+
}
|
|
50
|
+
let body;
|
|
51
|
+
try {
|
|
52
|
+
body = (await response.json());
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return { allowed: false, reason: 'GOVERNANCE_UNAVAILABLE' };
|
|
55
56
|
}
|
|
56
|
-
const body = (await response.json());
|
|
57
57
|
const data = body.data ?? body;
|
|
58
|
-
|
|
59
|
-
allowed:
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
if (data.allowed === true) {
|
|
59
|
+
return { allowed: true };
|
|
60
|
+
}
|
|
61
|
+
const reason = asDenyReason(data.reason);
|
|
62
|
+
if (data.allowed === false && reason && reason !== 'GOVERNANCE_UNAVAILABLE') {
|
|
63
|
+
return { allowed: false, reason };
|
|
64
|
+
}
|
|
65
|
+
return { allowed: false, reason: 'GOVERNANCE_UNAVAILABLE' };
|
|
62
66
|
}
|
|
63
67
|
catch {
|
|
64
68
|
clearTimeout(timeoutId);
|
|
@@ -66,6 +70,26 @@ export class HttpGovernanceClient {
|
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
}
|
|
73
|
+
const DENY_REASONS = new Set([
|
|
74
|
+
'NO_PERMISSION',
|
|
75
|
+
'DATA_SCOPE_DENIED',
|
|
76
|
+
'GOVERNANCE_UNAVAILABLE',
|
|
77
|
+
]);
|
|
78
|
+
function asDenyReason(value) {
|
|
79
|
+
return typeof value === 'string' && DENY_REASONS.has(value)
|
|
80
|
+
? value
|
|
81
|
+
: undefined;
|
|
82
|
+
}
|
|
83
|
+
async function readDenyReason(response, fallback) {
|
|
84
|
+
try {
|
|
85
|
+
const errBody = (await response.json());
|
|
86
|
+
const errData = errBody.data ?? errBody;
|
|
87
|
+
return asDenyReason(errData.reason) ?? fallback;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return fallback;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
69
93
|
/** 本地/测试:跳过远程校验 */
|
|
70
94
|
export class AllowAllGovernanceClient {
|
|
71
95
|
async checkPermission(_ctx, _params) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 权限校验 — 对齐 06-governance R16.8
|
|
3
3
|
*/
|
|
4
|
-
export type { CallerType, ExecutionContext, GovernancePermissionCheckParams, GovernancePermissionCheckResult, PermissionAction, PermissionDenyReason, PermissionResourceType, } from '@
|
|
4
|
+
export type { CallerType, ExecutionContext, GovernancePermissionCheckParams, GovernancePermissionCheckResult, PermissionAction, PermissionDenyReason, PermissionResourceType, } from '@eap/contracts';
|
|
5
5
|
export type { IGovernanceClient } from './governance-client.js';
|
|
6
6
|
export { HttpGovernanceClient, AllowAllGovernanceClient, resolveExecutionContext, } from './governance-client.js';
|
|
7
|
-
export { assertToolPermission, assertSkillPermission, PermissionDeniedError, GovernanceUnavailableError, } from './permission-guard.js';
|
|
7
|
+
export { assertToolPermission, assertSkillPermission, permissionMessage, PermissionDeniedError, GovernanceUnavailableError, } from './permission-guard.js';
|
package/dist/governance/index.js
CHANGED
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* 权限校验 — 对齐 06-governance R16.8
|
|
3
3
|
*/
|
|
4
4
|
export { HttpGovernanceClient, AllowAllGovernanceClient, resolveExecutionContext, } from './governance-client.js';
|
|
5
|
-
export { assertToolPermission, assertSkillPermission, PermissionDeniedError, GovernanceUnavailableError, } from './permission-guard.js';
|
|
5
|
+
export { assertToolPermission, assertSkillPermission, permissionMessage, PermissionDeniedError, GovernanceUnavailableError, } from './permission-guard.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 执行期 Tool 权限守卫
|
|
3
3
|
*/
|
|
4
|
-
import type { ExecutionContext, PermissionDenyReason } from '@
|
|
4
|
+
import type { ExecutionContext, PermissionDenyReason } from '@eap/contracts';
|
|
5
5
|
import type { IGovernanceClient } from './governance-client.js';
|
|
6
6
|
export declare class GovernanceUnavailableError extends Error {
|
|
7
7
|
readonly reason: PermissionDenyReason;
|
|
@@ -11,6 +11,7 @@ export declare class PermissionDeniedError extends Error {
|
|
|
11
11
|
readonly reason: PermissionDenyReason;
|
|
12
12
|
constructor(reason?: PermissionDenyReason, message?: string);
|
|
13
13
|
}
|
|
14
|
+
export declare function permissionMessage(kind: 'tool' | 'skill', reason: PermissionDenyReason): string;
|
|
14
15
|
export declare function assertToolPermission(client: IGovernanceClient | undefined, ctx: ExecutionContext, toolId: string, options?: {
|
|
15
16
|
dataScope?: 'user-bound' | 'department-bound' | 'global';
|
|
16
17
|
resourceOwnerId?: string;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export class GovernanceUnavailableError extends Error {
|
|
5
5
|
reason = 'GOVERNANCE_UNAVAILABLE';
|
|
6
|
-
constructor(message = '
|
|
6
|
+
constructor(message = '治理服务不可用') {
|
|
7
7
|
super(message);
|
|
8
8
|
this.name = 'GovernanceUnavailableError';
|
|
9
9
|
}
|
|
@@ -11,11 +11,18 @@ export class GovernanceUnavailableError extends Error {
|
|
|
11
11
|
export class PermissionDeniedError extends Error {
|
|
12
12
|
reason;
|
|
13
13
|
constructor(reason = 'NO_PERMISSION', message) {
|
|
14
|
-
super(message ?? reason);
|
|
14
|
+
super(message ?? permissionMessage('tool', reason));
|
|
15
15
|
this.name = 'PermissionDeniedError';
|
|
16
16
|
this.reason = reason;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
export function permissionMessage(kind, reason) {
|
|
20
|
+
if (reason === 'DATA_SCOPE_DENIED')
|
|
21
|
+
return '数据范围不足';
|
|
22
|
+
if (reason === 'GOVERNANCE_UNAVAILABLE')
|
|
23
|
+
return '治理服务不可用';
|
|
24
|
+
return kind === 'skill' ? '用户无该 Skill 使用权限' : '用户无该 Tool 执行权限';
|
|
25
|
+
}
|
|
19
26
|
export async function assertToolPermission(client, ctx, toolId, options) {
|
|
20
27
|
if (!client) {
|
|
21
28
|
return;
|
|
@@ -34,7 +41,8 @@ export async function assertToolPermission(client, ctx, toolId, options) {
|
|
|
34
41
|
throw new GovernanceUnavailableError();
|
|
35
42
|
}
|
|
36
43
|
if (!result.allowed) {
|
|
37
|
-
|
|
44
|
+
const reason = result.reason ?? 'NO_PERMISSION';
|
|
45
|
+
throw new PermissionDeniedError(reason, permissionMessage('tool', reason));
|
|
38
46
|
}
|
|
39
47
|
}
|
|
40
48
|
/** Skill 激活守卫(04 R15.3) */
|
|
@@ -54,6 +62,7 @@ export async function assertSkillPermission(client, ctx, skillId) {
|
|
|
54
62
|
throw new GovernanceUnavailableError();
|
|
55
63
|
}
|
|
56
64
|
if (!result.allowed) {
|
|
57
|
-
|
|
65
|
+
const reason = result.reason ?? 'NO_PERMISSION';
|
|
66
|
+
throw new PermissionDeniedError(reason, permissionMessage('skill', reason));
|
|
58
67
|
}
|
|
59
68
|
}
|
|
@@ -19,13 +19,13 @@ import { fileArtifactFromToolOutput } from '../../tool/file-artifact.js';
|
|
|
19
19
|
import { EchoLLMProvider } from '../../providers/echo-llm-provider.js';
|
|
20
20
|
import { ConditionEvaluator } from '../condition-evaluator.js';
|
|
21
21
|
import { SystemPromptBuilder, buildToolCatalog, loadedToolsToApiTools } from '../../tool/system-prompt-builder.js';
|
|
22
|
-
import { resolveJailRoots } from '../../tool/harness-primitives.js';
|
|
22
|
+
import { resolveJailFromState, resolveJailRoots } from '../../tool/harness-primitives.js';
|
|
23
23
|
import os from 'node:os';
|
|
24
24
|
import { bindSelectedSkill } from '../nodes/skill-bind-node.js';
|
|
25
25
|
import { resolveGraphPrompt } from '../resolve-graph-prompt.js';
|
|
26
26
|
import { SkillAuditRecorder } from '../skill-audit-recorder.js';
|
|
27
27
|
import { preloadSkillNotFound } from '../../registry/preload-errors.js';
|
|
28
|
-
import { AppError, ErrorCodes } from '@
|
|
28
|
+
import { AppError, ErrorCodes } from '@eap/contracts';
|
|
29
29
|
import { isHitlDecision, lastAssistantHasUnansweredToolCalls } from '../hitl/hitl-handler.js';
|
|
30
30
|
import { classifySkillRead } from './skill-read.js';
|
|
31
31
|
import { withGraphSpan } from '../trace-span.js';
|
|
@@ -305,6 +305,7 @@ export class LangGraphAdapter {
|
|
|
305
305
|
skillRoute: ephemeral(undefined),
|
|
306
306
|
silentOutput: ephemeral(undefined),
|
|
307
307
|
promptRoots: ephemeral(undefined),
|
|
308
|
+
agentDir: ephemeral(undefined),
|
|
308
309
|
executionContext: ephemeral(undefined),
|
|
309
310
|
forceToolServer: ephemeral(undefined),
|
|
310
311
|
traceCollector: ephemeral(undefined),
|
|
@@ -799,7 +800,15 @@ export class LangGraphAdapter {
|
|
|
799
800
|
const toolCatalog = disableTools ? undefined : buildToolCatalog(loadedTools);
|
|
800
801
|
const execCtx = state['executionContext'];
|
|
801
802
|
const userId = (typeof execCtx?.userId === 'string' && execCtx.userId) || state['userId'];
|
|
802
|
-
const
|
|
803
|
+
const jail = resolveJailFromState({
|
|
804
|
+
agentDir: state['agentDir'],
|
|
805
|
+
userId,
|
|
806
|
+
executionContext: execCtx,
|
|
807
|
+
loadedTools,
|
|
808
|
+
skillDefinitions: skillDefs,
|
|
809
|
+
});
|
|
810
|
+
const workingDirectory = jail.workdir;
|
|
811
|
+
const jailRoots = resolveJailRoots(jail);
|
|
803
812
|
const skillDirs = Object.values(skillDefs ?? {})
|
|
804
813
|
.filter((skill) => Boolean(skill.bundlePath))
|
|
805
814
|
.map((skill) => ({
|
|
@@ -807,10 +816,6 @@ export class LangGraphAdapter {
|
|
|
807
816
|
bundlePath: skill.bundlePath,
|
|
808
817
|
entryFile: skill.entryFile,
|
|
809
818
|
}));
|
|
810
|
-
const jailRoots = resolveJailRoots({
|
|
811
|
-
workdir: workingDirectory,
|
|
812
|
-
extraRoots: skillDirs.map((s) => s.bundlePath),
|
|
813
|
-
});
|
|
814
819
|
const assembled = this.systemPromptBuilder.build({
|
|
815
820
|
developerPrompt: resolvedPrompt || undefined,
|
|
816
821
|
skillCatalog: catalog,
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
* Executable Graph 类型定义
|
|
3
3
|
*
|
|
4
4
|
* 定义 Graph 引擎核心的可执行图、DSL、节点、边等类型。
|
|
5
|
-
* 与 @
|
|
5
|
+
* 与 @eap/contracts 的 GraphDSL 基础类型互补,在 Runtime 层提供更丰富的类型支持。
|
|
6
6
|
*
|
|
7
7
|
* @see design.md §1.4 StateGraph Contract
|
|
8
8
|
* @see requirements.md Requirement 1 AC1-AC2
|
|
9
9
|
*/
|
|
10
|
-
import type { GraphDSL as BaseGraphDSL, GraphNode as BaseGraphNode, GraphEdge as BaseGraphEdge, GraphNodeType, GraphConfig } from '@
|
|
10
|
+
import type { GraphDSL as BaseGraphDSL, GraphNode as BaseGraphNode, GraphEdge as BaseGraphEdge, GraphNodeType, GraphConfig } from '@eap/contracts';
|
|
11
11
|
export type { GraphNodeType, GraphConfig };
|
|
12
12
|
/**
|
|
13
13
|
* RuntimeGraphConfig — Runtime 层扩展的 Graph 配置
|
|
14
14
|
*
|
|
15
|
-
* 在 @
|
|
15
|
+
* 在 @eap/contracts GraphConfig 基础上增加 Runtime 执行所需的 maxRetries。
|
|
16
16
|
*/
|
|
17
17
|
export interface RuntimeGraphConfig extends GraphConfig {
|
|
18
18
|
/** Graph 级默认重试次数(节点级 retry 可覆盖) */
|
|
@@ -21,7 +21,7 @@ export interface RuntimeGraphConfig extends GraphConfig {
|
|
|
21
21
|
/**
|
|
22
22
|
* GraphNode — Runtime 层扩展的节点定义
|
|
23
23
|
*
|
|
24
|
-
* 继承 @
|
|
24
|
+
* 继承 @eap/contracts 基础 GraphNode,增加 Runtime 执行所需的字段:
|
|
25
25
|
* - 重试配置(节点级 maxRetries + 退避策略)
|
|
26
26
|
* - HITL 标记(interrupt_before / interrupt_after)
|
|
27
27
|
* - 描述信息(调试/Trace 用)
|
|
@@ -79,7 +79,7 @@ export interface ConditionalBranch {
|
|
|
79
79
|
/**
|
|
80
80
|
* GraphDSL — Runtime 层扩展的声明式工作流定义
|
|
81
81
|
*
|
|
82
|
-
* 扩展 @
|
|
82
|
+
* 扩展 @eap/contracts 的 BaseGraphDSL,增加条件路由、入口/终止节点等。
|
|
83
83
|
*/
|
|
84
84
|
export interface GraphDSL extends Omit<BaseGraphDSL, 'config' | 'nodes' | 'edges'> {
|
|
85
85
|
/** 覆盖节点类型为 Runtime 扩展版本 */
|
|
@@ -163,7 +163,7 @@ export interface ExecutableGraph {
|
|
|
163
163
|
/** 底层引擎内部实例引用(opaque,由 adapter 管理) */
|
|
164
164
|
_engineInstance?: unknown;
|
|
165
165
|
}
|
|
166
|
-
import type { ExecutionContext as PlatformExecutionContext } from '@
|
|
166
|
+
import type { ExecutionContext as PlatformExecutionContext } from '@eap/contracts';
|
|
167
167
|
/**
|
|
168
168
|
* GraphState — 传入 stream/invoke 的上下文数据
|
|
169
169
|
*/
|
|
@@ -195,6 +195,8 @@ export interface GraphState {
|
|
|
195
195
|
silentOutput?: string;
|
|
196
196
|
/** 解析 graph 内 ./prompts/*.md 的根目录(agentDir + 工程根) */
|
|
197
197
|
promptRoots?: string[];
|
|
198
|
+
/** 预装 Agent 包目录:`{EAP_PREINSTALL_ROOT}/agents/<code>/<ver>` */
|
|
199
|
+
agentDir?: string;
|
|
198
200
|
activatedSkill?: string | null;
|
|
199
201
|
skillRoute?: string;
|
|
200
202
|
/** bind / invoke 解析出的 Skill 入参;子图 IO 校验读取 */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Executable Graph 类型定义
|
|
3
3
|
*
|
|
4
4
|
* 定义 Graph 引擎核心的可执行图、DSL、节点、边等类型。
|
|
5
|
-
* 与 @
|
|
5
|
+
* 与 @eap/contracts 的 GraphDSL 基础类型互补,在 Runtime 层提供更丰富的类型支持。
|
|
6
6
|
*
|
|
7
7
|
* @see design.md §1.4 StateGraph Contract
|
|
8
8
|
* @see requirements.md Requirement 1 AC1-AC2
|
|
@@ -16,6 +16,9 @@ import type { ISSEEmitter } from '../../sse/contracts/sse-emitter.contract.js';
|
|
|
16
16
|
import type { GraphState } from '../contracts/executable-graph.js';
|
|
17
17
|
/** HITL 默认等待时长(毫秒)= 300 秒。SSE `hitl.waited.timeout` 对外用秒。 */
|
|
18
18
|
export declare const DEFAULT_HITL_TIMEOUT_MS = 300000;
|
|
19
|
+
/** 超时收口对外文案(Task / Trace / AppError);枚举走 `hitl_timeout`。 */
|
|
20
|
+
export declare const HITL_TIMEOUT_MESSAGE = "HITL \u786E\u8BA4\u8D85\u65F6";
|
|
21
|
+
export declare const HITL_TIMEOUT_ERROR_CODE = "hitl_timeout";
|
|
19
22
|
/** HITL 超时行为 */
|
|
20
23
|
export type HitlTimeoutBehavior = 'error' | 'cancel' | 'auto-confirm';
|
|
21
24
|
/** HITL 中断配置 */
|
|
@@ -17,6 +17,9 @@ import { startGraphSpan, completeGraphSpan } from '../trace-span.js';
|
|
|
17
17
|
// ─────────────────────────────────────────────
|
|
18
18
|
/** HITL 默认等待时长(毫秒)= 300 秒。SSE `hitl.waited.timeout` 对外用秒。 */
|
|
19
19
|
export const DEFAULT_HITL_TIMEOUT_MS = 300_000;
|
|
20
|
+
/** 超时收口对外文案(Task / Trace / AppError);枚举走 `hitl_timeout`。 */
|
|
21
|
+
export const HITL_TIMEOUT_MESSAGE = 'HITL 确认超时';
|
|
22
|
+
export const HITL_TIMEOUT_ERROR_CODE = 'hitl_timeout';
|
|
20
23
|
/** HITL 超时错误(保留类型;timer 不再 throw,resume 逾期改走 AppError) */
|
|
21
24
|
export class HitlTimeoutError extends Error {
|
|
22
25
|
taskId;
|
|
@@ -444,7 +447,7 @@ export class HitlHandler {
|
|
|
444
447
|
const hitlSpanId = waiting.hitlSpanId ?? persisted.hitlSpanId;
|
|
445
448
|
await completeGraphSpan(checkpoint.state, hitlSpanId, {
|
|
446
449
|
status: 'failed',
|
|
447
|
-
error:
|
|
450
|
+
error: HITL_TIMEOUT_MESSAGE,
|
|
448
451
|
}, liveCollector);
|
|
449
452
|
}
|
|
450
453
|
return timeoutEvent;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* @see design.md §1.4 ToolNode: LangGraph的ToolNode封装
|
|
10
10
|
* @see requirements.md Requirement 8 AC1, AC3, AC5
|
|
11
11
|
*/
|
|
12
|
+
import { resolveJailFromState } from '../../tool/harness-primitives.js';
|
|
12
13
|
import { isHitlDecision, unwrapHitlPaused } from '../hitl/hitl-handler.js';
|
|
13
14
|
import { ToolConfirmationInterceptor } from '../../tool/tool-confirmation.js';
|
|
14
15
|
import { resolveCheckpointThreadId } from '../../session/persist-turn-messages.js';
|
|
@@ -19,6 +20,19 @@ function skillDirsFromState(state) {
|
|
|
19
20
|
.filter((skill) => Boolean(skill.bundlePath))
|
|
20
21
|
.map((skill) => ({ skillId: skill.skillId, bundlePath: skill.bundlePath }));
|
|
21
22
|
}
|
|
23
|
+
function resolveActiveSkillDir(state) {
|
|
24
|
+
const defs = state['skillDefinitions'];
|
|
25
|
+
if (!defs)
|
|
26
|
+
return undefined;
|
|
27
|
+
const activated = state['activatedSkill'];
|
|
28
|
+
if (typeof activated === 'string' && defs[activated]?.bundlePath) {
|
|
29
|
+
return defs[activated].bundlePath;
|
|
30
|
+
}
|
|
31
|
+
const paths = Object.values(defs)
|
|
32
|
+
.map((skill) => skill.bundlePath)
|
|
33
|
+
.filter((p) => Boolean(p));
|
|
34
|
+
return paths.length === 1 ? paths[0] : undefined;
|
|
35
|
+
}
|
|
22
36
|
export class ToolNode {
|
|
23
37
|
orchestrator;
|
|
24
38
|
injector;
|
|
@@ -53,7 +67,15 @@ export class ToolNode {
|
|
|
53
67
|
}
|
|
54
68
|
const loadedTools = state['loadedTools'];
|
|
55
69
|
const skillDirs = skillDirsFromState(state);
|
|
56
|
-
const
|
|
70
|
+
const jail = resolveJailFromState({
|
|
71
|
+
agentDir: state['agentDir'],
|
|
72
|
+
userId: state['userId'],
|
|
73
|
+
executionContext: state['executionContext'],
|
|
74
|
+
loadedTools,
|
|
75
|
+
skillDefinitions: state['skillDefinitions'],
|
|
76
|
+
});
|
|
77
|
+
const jailExtraRoots = jail.extraRoots ?? [];
|
|
78
|
+
const skillDir = resolveActiveSkillDir(state);
|
|
57
79
|
// 4. 转换为 ToolCallRequest[](附带 manifest 路由字段)
|
|
58
80
|
const requests = lastAssistantMessage.toolCalls.map((tc) => {
|
|
59
81
|
const loaded = loadedTools?.[tc.name];
|
|
@@ -73,7 +95,9 @@ export class ToolNode {
|
|
|
73
95
|
...(loaded?.manifest.version ? { toolVersion: loaded.manifest.version } : {}),
|
|
74
96
|
correlationId,
|
|
75
97
|
taskId,
|
|
98
|
+
...(jail.workdir ? { jailWorkdir: jail.workdir } : {}),
|
|
76
99
|
...(jailExtraRoots.length > 0 ? { jailExtraRoots } : {}),
|
|
100
|
+
...(skillDir ? { skillDir } : {}),
|
|
77
101
|
};
|
|
78
102
|
});
|
|
79
103
|
const executionContext = state['executionContext'];
|
|
@@ -161,7 +185,8 @@ export class ToolNode {
|
|
|
161
185
|
toolName: req.toolName,
|
|
162
186
|
content: `用户拒绝执行工具 ${req.toolName}`,
|
|
163
187
|
success: false,
|
|
164
|
-
error:
|
|
188
|
+
error: `用户拒绝执行工具 ${req.toolName}`,
|
|
189
|
+
errorCode: 'hitl_rejected',
|
|
165
190
|
};
|
|
166
191
|
}
|
|
167
192
|
else {
|
package/dist/index.d.ts
CHANGED
|
@@ -16,8 +16,8 @@ export * from './common/index.js';
|
|
|
16
16
|
export * from './registry/index.js';
|
|
17
17
|
export * from './providers/index.js';
|
|
18
18
|
export type { ITraceCollector, TraceEvent, TraceSession, ExecutionFlowEvent, ExecutionNodeEvent, TraceLinkEvent, TraceLinkNodeEvent, } from './contracts/trace-collector.js';
|
|
19
|
-
export type { ExecutionContext, CallerType, GovernancePermissionCheckParams, GovernancePermissionCheckResult, PermissionDenyReason, } from '@
|
|
20
|
-
export { HttpGovernanceClient, AllowAllGovernanceClient, resolveExecutionContext, assertToolPermission, assertSkillPermission, PermissionDeniedError, GovernanceUnavailableError, } from './governance/index.js';
|
|
19
|
+
export type { ExecutionContext, CallerType, GovernancePermissionCheckParams, GovernancePermissionCheckResult, PermissionDenyReason, } from '@eap/contracts';
|
|
20
|
+
export { HttpGovernanceClient, AllowAllGovernanceClient, resolveExecutionContext, assertToolPermission, assertSkillPermission, permissionMessage, PermissionDeniedError, GovernanceUnavailableError, } from './governance/index.js';
|
|
21
21
|
export type { IGovernanceClient } from './governance/index.js';
|
|
22
22
|
export { FileLlmTurnLog, InMemoryLlmTurnLog, createFileLlmTurnLogFromEnv, maskApiKey, resolveLlmTurnDir, } from './debug/llm-turn-log.js';
|
|
23
23
|
export { PostgresLlmTurnLog } from './debug/pg-llm-turn-log.js';
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,6 @@ export * from './common/index.js';
|
|
|
29
29
|
export * from './registry/index.js';
|
|
30
30
|
// LLM Providers
|
|
31
31
|
export * from './providers/index.js';
|
|
32
|
-
export { HttpGovernanceClient, AllowAllGovernanceClient, resolveExecutionContext, assertToolPermission, assertSkillPermission, PermissionDeniedError, GovernanceUnavailableError, } from './governance/index.js';
|
|
32
|
+
export { HttpGovernanceClient, AllowAllGovernanceClient, resolveExecutionContext, assertToolPermission, assertSkillPermission, permissionMessage, PermissionDeniedError, GovernanceUnavailableError, } from './governance/index.js';
|
|
33
33
|
export { FileLlmTurnLog, InMemoryLlmTurnLog, createFileLlmTurnLogFromEnv, maskApiKey, resolveLlmTurnDir, } from './debug/llm-turn-log.js';
|
|
34
34
|
export { PostgresLlmTurnLog } from './debug/pg-llm-turn-log.js';
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* - `call:echo-tool {"text":"hi"}` → arguments 使用解析后的 JSON
|
|
8
8
|
* - `call:echo-tool hi` → arguments 兜底为 `{ text: 'hi' }`
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* 仅用于本地闭环(无真实 LLM)下驱动 ToolNode,
|
|
11
|
+
* 让开发者无需接入模型即可完成 tool 调用链路验证。
|
|
12
12
|
*/
|
|
13
13
|
function parseSyntheticToolCall(content) {
|
|
14
14
|
if (!content)
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { ILLMProvider } from '../graph/nodes/llm-node.js';
|
|
6
6
|
import type { ILlmTurnLog } from '../debug/llm-turn-log.js';
|
|
7
|
-
import { type ModelCallDefaults } from '@
|
|
7
|
+
import { type ModelCallDefaults } from '@eap/contracts';
|
|
8
8
|
export interface LocalLlmConnection {
|
|
9
9
|
baseUrl: string;
|
|
10
10
|
apiKey: string;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 本地多模型 LLM:按节点 model 选网关。仅 dev。
|
|
3
3
|
* 连接表里只带 apiKeyEnv,密钥从 process.env 读取,不进 JSON。
|
|
4
4
|
*/
|
|
5
|
-
import { mergeModelCallParams } from '@
|
|
5
|
+
import { mergeModelCallParams } from '@eap/contracts';
|
|
6
6
|
import { HttpLLMProvider } from './http-llm-provider.js';
|
|
7
7
|
export const LLM_CONNECTIONS_ENV = 'EAP_LLM_CONNECTIONS';
|
|
8
8
|
export function parseLocalLlmConnectionRefs(env = process.env) {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - 支持任意 OpenAI 兼容 API(OpenAI / DeepSeek / 本地 Ollama 等)
|
|
12
12
|
* - 连接配置由 Foundation 统一管理,Runtime 无感知
|
|
13
13
|
*/
|
|
14
|
-
import { mergeModelCallParams } from '@
|
|
14
|
+
import { mergeModelCallParams } from '@eap/contracts';
|
|
15
15
|
import { EchoLLMProvider } from './echo-llm-provider.js';
|
|
16
16
|
import { HttpLLMProvider } from './http-llm-provider.js';
|
|
17
17
|
export class RoutingLLMProvider {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { resolveDeclaredModels, resolveAgentDefaultModel, resolveAgentModelAllowlist, } from '@
|
|
1
|
+
export { resolveDeclaredModels, resolveAgentDefaultModel, resolveAgentModelAllowlist, } from '@eap/contracts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { resolveDeclaredModels, resolveAgentDefaultModel, resolveAgentModelAllowlist, } from '@
|
|
1
|
+
export { resolveDeclaredModels, resolveAgentDefaultModel, resolveAgentModelAllowlist, } from '@eap/contracts';
|