@gt-fe/eap-runtime 0.0.20 → 0.0.22
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 +4 -3
- package/dist/api/handlers/invoke.handler.d.ts +7 -0
- package/dist/api/handlers/invoke.handler.js +52 -10
- package/dist/api/handlers/stream.handler.d.ts +6 -0
- package/dist/api/handlers/stream.handler.js +60 -39
- package/dist/api/routes/agent.routes.d.ts +8 -1
- package/dist/checkpoint/file-checkpoint-saver.d.ts +4 -0
- package/dist/checkpoint/file-checkpoint-saver.js +51 -22
- package/dist/checkpoint/index.d.ts +1 -1
- package/dist/checkpoint/index.js +1 -1
- package/dist/common/types.d.ts +2 -2
- package/dist/common/types.js +1 -1
- package/dist/execution/index.d.ts +2 -0
- package/dist/execution/index.js +2 -0
- package/dist/execution/interceptors.d.ts +40 -0
- package/dist/execution/interceptors.js +23 -0
- package/dist/execution/ports.d.ts +18 -0
- package/dist/execution/ports.js +13 -0
- package/dist/governance/audit-reporter.d.ts +14 -0
- package/dist/governance/audit-reporter.js +18 -0
- package/dist/governance/index.d.ts +2 -0
- package/dist/governance/index.js +1 -0
- package/dist/governance/permission-guard.d.ts +6 -2
- package/dist/governance/permission-guard.js +38 -5
- package/dist/graph/adapters/graph-nesting.d.ts +12 -0
- package/dist/graph/adapters/graph-nesting.js +29 -0
- package/dist/graph/adapters/index.d.ts +2 -0
- package/dist/graph/adapters/index.js +2 -0
- package/dist/graph/adapters/langgraph-checkpointer.d.ts +11 -0
- package/dist/graph/adapters/langgraph-checkpointer.js +48 -9
- package/dist/graph/adapters/langgraph.adapter.d.ts +33 -11
- package/dist/graph/adapters/langgraph.adapter.js +200 -98
- package/dist/graph/adapters/skill-isolate.d.ts +13 -0
- package/dist/graph/adapters/skill-isolate.js +39 -0
- package/dist/graph/adapters/subgraph-compiler.d.ts +7 -2
- package/dist/graph/adapters/subgraph-compiler.js +63 -30
- package/dist/graph/contracts/executable-graph.d.ts +33 -5
- package/dist/graph/hitl/hitl-handler.d.ts +13 -4
- package/dist/graph/hitl/hitl-handler.js +80 -7
- package/dist/graph/nodes/index.d.ts +1 -0
- package/dist/graph/nodes/index.js +1 -0
- package/dist/graph/nodes/llm-node.d.ts +3 -1
- package/dist/graph/nodes/llm-node.js +26 -2
- package/dist/graph/nodes/rag/dedup.d.ts +20 -0
- package/dist/graph/nodes/rag/dedup.js +77 -0
- package/dist/graph/nodes/rag/denoise.d.ts +58 -0
- package/dist/graph/nodes/rag/denoise.js +220 -0
- package/dist/graph/nodes/rag/fusion/fuse.d.ts +11 -0
- package/dist/graph/nodes/rag/fusion/fuse.js +25 -0
- package/dist/graph/nodes/rag/fusion/normalize.d.ts +9 -0
- package/dist/graph/nodes/rag/fusion/normalize.js +135 -0
- package/dist/graph/nodes/rag/index.d.ts +18 -0
- package/dist/graph/nodes/rag/index.js +17 -0
- package/dist/graph/nodes/rag/prompts.d.ts +12 -0
- package/dist/graph/nodes/rag/prompts.js +40 -0
- package/dist/graph/nodes/rag/rag-node.d.ts +21 -0
- package/dist/graph/nodes/rag/rag-node.js +135 -0
- package/dist/graph/nodes/rag/rag-search-tool.d.ts +48 -0
- package/dist/graph/nodes/rag/rag-search-tool.js +230 -0
- package/dist/graph/nodes/rag/react-loop.d.ts +57 -0
- package/dist/graph/nodes/rag/react-loop.js +467 -0
- package/dist/graph/nodes/rag/retrievers/http-embedder.d.ts +29 -0
- package/dist/graph/nodes/rag/retrievers/http-embedder.js +66 -0
- package/dist/graph/nodes/rag/retrievers/in-memory-retriever.d.ts +17 -0
- package/dist/graph/nodes/rag/retrievers/in-memory-retriever.js +18 -0
- package/dist/graph/nodes/rag/retrievers/local-sqlite-retriever.d.ts +46 -0
- package/dist/graph/nodes/rag/retrievers/local-sqlite-retriever.js +85 -0
- package/dist/graph/nodes/rag/tools.d.ts +90 -0
- package/dist/graph/nodes/rag/tools.js +260 -0
- package/dist/graph/nodes/rag/types.d.ts +226 -0
- package/dist/graph/nodes/rag/types.js +9 -0
- package/dist/graph/nodes/tool-node.d.ts +19 -1
- package/dist/graph/nodes/tool-node.js +158 -33
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/memory/semantic-retrieval.service.d.ts +1 -1
- package/dist/memory/semantic-retrieval.service.js +13 -23
- package/dist/providers/index.d.ts +2 -2
- package/dist/providers/index.js +2 -2
- package/dist/providers/local-llm-provider.d.ts +6 -0
- package/dist/providers/local-llm-provider.js +29 -5
- package/dist/providers/routing-llm-provider.d.ts +7 -2
- package/dist/providers/routing-llm-provider.js +71 -16
- package/dist/registry/deployment-snapshot.js +18 -4
- package/dist/registry/graph-loader.d.ts +2 -0
- package/dist/registry/graph-loader.js +39 -2
- package/dist/registry/preload-flags.d.ts +1 -1
- package/dist/registry/preload-flags.js +1 -1
- package/dist/runtime/agent-runtime.d.ts +5 -0
- package/dist/runtime/agent-runtime.js +107 -70
- package/dist/runtime/dev-rag-deps.d.ts +21 -0
- package/dist/runtime/dev-rag-deps.js +186 -0
- package/dist/runtime/dev-runtime.d.ts +18 -2
- package/dist/runtime/dev-runtime.js +68 -8
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/types.d.ts +10 -9
- package/dist/session/apply-session-compression.d.ts +85 -0
- package/dist/session/apply-session-compression.js +281 -0
- package/dist/session/apply-session-memory.d.ts +21 -0
- package/dist/session/apply-session-memory.js +48 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +2 -0
- package/dist/session/persist-turn-messages.d.ts +57 -1
- package/dist/session/persist-turn-messages.js +160 -5
- package/dist/sse/events/index.d.ts +13 -4
- package/dist/sse/events/index.js +9 -1
- package/dist/sse/events/rag-events.d.ts +63 -0
- package/dist/sse/events/rag-events.js +9 -0
- package/dist/sse/events/session-events.d.ts +38 -0
- package/dist/sse/events/session-events.js +4 -0
- package/dist/token/index.d.ts +2 -1
- package/dist/token/index.js +2 -1
- package/dist/token/record-task-token-usage.d.ts +25 -0
- package/dist/token/record-task-token-usage.js +44 -0
- package/dist/token/token-detail-mode.d.ts +4 -4
- package/dist/token/token-detail-mode.js +4 -4
- package/dist/token/token-detail.d.ts +8 -0
- package/dist/token/token-detail.js +22 -0
- package/dist/token/token-stats.service.d.ts +2 -2
- package/dist/token/token-stats.service.js +1 -1
- package/dist/tool/create-tool-executor.d.ts +6 -0
- package/dist/tool/create-tool-executor.js +4 -3
- package/dist/tool/harness-primitives.d.ts +9 -1
- package/dist/tool/harness-primitives.js +43 -12
- package/dist/tool/index.d.ts +2 -1
- package/dist/tool/index.js +2 -1
- package/dist/tool/tool-confirmation.js +8 -5
- package/dist/tool/tool-executor.interface.d.ts +27 -0
- package/dist/tool/tool-orchestrator.d.ts +3 -1
- package/dist/tool/tool-orchestrator.js +15 -6
- package/dist/tool/tool-retry.d.ts +15 -0
- package/dist/tool/tool-retry.js +69 -0
- package/package.json +2 -2
|
@@ -9,10 +9,15 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { StateGraph, START, END, } from '@langchain/langgraph';
|
|
11
11
|
import { resolveCheckpointThreadId } from '../../session/persist-turn-messages.js';
|
|
12
|
+
import { checkpointStorageThreadId } from './langgraph-checkpointer.js';
|
|
12
13
|
import { LangGraphCheckpointer } from './langgraph-checkpointer.js';
|
|
13
14
|
import { SubGraphCompiler } from './subgraph-compiler.js';
|
|
15
|
+
import { assertEmbeddedSubgraphsAreFlat } from './graph-nesting.js';
|
|
16
|
+
import { isSkillContextIsolated } from './skill-isolate.js';
|
|
14
17
|
import { LLMNode } from '../nodes/llm-node.js';
|
|
15
18
|
import { ToolNode } from '../nodes/tool-node.js';
|
|
19
|
+
import { RagNode, RAG_SEARCH_TOOL_NAME, RagSearchToolExecutor } from '../nodes/rag/index.js';
|
|
20
|
+
import { resolveRagSources, appendSourceCatalog } from '../nodes/rag/tools.js';
|
|
16
21
|
import { ToolOrchestrator } from '../../tool/tool-orchestrator.js';
|
|
17
22
|
import { ToolResultInjector } from '../../tool/tool-result-injector.js';
|
|
18
23
|
import { fileArtifactFromToolOutput } from '../../tool/file-artifact.js';
|
|
@@ -33,12 +38,31 @@ import { classifySkillRead } from './skill-read.js';
|
|
|
33
38
|
import { skillEntryInvocationFromTool } from './skill-entry-span.js';
|
|
34
39
|
import { withGraphSpan } from '../trace-span.js';
|
|
35
40
|
import { executionTraceFromState, getExecutionStream, runWithExecutionTrace, } from '../execution-trace-context.js';
|
|
41
|
+
import { isRetryableToolFailure, resolveToolRetryConfig, sleepToolRetry, toolRetryDelayMs, } from '../../tool/tool-retry.js';
|
|
36
42
|
/** 图未写 `config.maxIterations` 时的 recursionLimit。`agent ⇄ tools` 一圈约 2,50 ≈ 24 次工具往返。 */
|
|
37
43
|
export const DEFAULT_GRAPH_RECURSION_LIMIT = 50;
|
|
38
44
|
/**
|
|
39
45
|
* LangGraph `recursionLimit` 计 superstep(每进一个节点 +1),不是 ReAct 圈数。
|
|
40
46
|
* 图上 `config.maxIterations` 优先;缺省 {@link DEFAULT_GRAPH_RECURSION_LIMIT}。
|
|
41
47
|
*/
|
|
48
|
+
/** 并行节点各自返回 [id] 时合并进同一路径;末项相同不重复。 */
|
|
49
|
+
export function mergeHistoryPath(current, update) {
|
|
50
|
+
const path = Array.isArray(current)
|
|
51
|
+
? current.filter((id) => typeof id === 'string' && id.trim().length > 0)
|
|
52
|
+
: [];
|
|
53
|
+
const add = Array.isArray(update) ? update : [];
|
|
54
|
+
for (const raw of add) {
|
|
55
|
+
if (typeof raw !== 'string')
|
|
56
|
+
continue;
|
|
57
|
+
const id = raw.trim();
|
|
58
|
+
if (!id)
|
|
59
|
+
continue;
|
|
60
|
+
if (path[path.length - 1] === id)
|
|
61
|
+
continue;
|
|
62
|
+
path.push(id);
|
|
63
|
+
}
|
|
64
|
+
return path.length > 1000 ? path.slice(path.length - 1000) : path;
|
|
65
|
+
}
|
|
42
66
|
function langGraphRunOptions(dsl, extra) {
|
|
43
67
|
const raw = dsl.config?.maxIterations;
|
|
44
68
|
const recursionLimit = typeof raw === 'number' && Number.isFinite(raw) && raw > 0
|
|
@@ -61,6 +85,7 @@ function langGraphRunOptions(dsl, extra) {
|
|
|
61
85
|
* 3. 提供 Checkpoint 提取与恢复能力
|
|
62
86
|
*/
|
|
63
87
|
export class LangGraphAdapter {
|
|
88
|
+
auditReporter;
|
|
64
89
|
checkpointer;
|
|
65
90
|
subGraphCompiler;
|
|
66
91
|
llmProvider;
|
|
@@ -77,17 +102,29 @@ export class LangGraphAdapter {
|
|
|
77
102
|
*/
|
|
78
103
|
governanceClient;
|
|
79
104
|
hitlHandler;
|
|
80
|
-
|
|
105
|
+
ragNodeDeps;
|
|
106
|
+
interceptors;
|
|
107
|
+
/** 开发 overlay 根;createDevRuntime 在恢复 process.env 之前钉死 */
|
|
108
|
+
overlayExtraRoots = [];
|
|
109
|
+
constructor(checkpointSaver, llmProvider, toolExecutor, governanceClient, hitlHandler, ragNodeDeps, interceptors, auditReporter) {
|
|
110
|
+
this.auditReporter = auditReporter;
|
|
81
111
|
this.governanceClient = governanceClient;
|
|
82
112
|
this.hitlHandler = hitlHandler;
|
|
113
|
+
this.ragNodeDeps = ragNodeDeps;
|
|
114
|
+
this.interceptors = interceptors;
|
|
83
115
|
this.checkpointer = checkpointSaver
|
|
84
116
|
? new LangGraphCheckpointer(checkpointSaver)
|
|
85
117
|
: undefined;
|
|
86
118
|
this.llmProvider = llmProvider ?? new EchoLLMProvider();
|
|
87
119
|
this.toolExecutor = toolExecutor;
|
|
88
120
|
this.toolOrchestrator = toolExecutor
|
|
89
|
-
? new ToolOrchestrator(toolExecutor, governanceClient)
|
|
121
|
+
? new ToolOrchestrator(toolExecutor, governanceClient, this.auditReporter)
|
|
90
122
|
: undefined;
|
|
123
|
+
// rag_search 装饰器注入同款编排器(内层 kb 派发与 tool 节点同一链路;
|
|
124
|
+
// 装饰器 deps 已显式提供 orchestrator 时不覆盖)
|
|
125
|
+
if (toolExecutor instanceof RagSearchToolExecutor && this.toolOrchestrator) {
|
|
126
|
+
toolExecutor.attachToolOrchestrator(this.toolOrchestrator);
|
|
127
|
+
}
|
|
91
128
|
this.toolResultInjector = new ToolResultInjector();
|
|
92
129
|
this.conditionEvaluator = new ConditionEvaluator();
|
|
93
130
|
this.systemPromptBuilder = new SystemPromptBuilder();
|
|
@@ -125,7 +162,7 @@ export class LangGraphAdapter {
|
|
|
125
162
|
return 'none';
|
|
126
163
|
});
|
|
127
164
|
// 必须在其他依赖初始化后再创建 SubGraphCompiler(它持有 adapter 引用)
|
|
128
|
-
this.subGraphCompiler = new SubGraphCompiler(this, governanceClient, this.skillAuditRecorder);
|
|
165
|
+
this.subGraphCompiler = new SubGraphCompiler(this, governanceClient, this.skillAuditRecorder, this.auditReporter);
|
|
129
166
|
}
|
|
130
167
|
/**
|
|
131
168
|
* 注册自定义条件评估函数
|
|
@@ -133,6 +170,10 @@ export class LangGraphAdapter {
|
|
|
133
170
|
registerConditionEvaluator(name, fn) {
|
|
134
171
|
this.conditionEvaluator.register(name, fn);
|
|
135
172
|
}
|
|
173
|
+
/** SDK 恢复 env 之后仍要把 overlay 算进 LLM jail 根,不能再读 process.env。 */
|
|
174
|
+
bindOverlayExtraRoots(roots) {
|
|
175
|
+
this.overlayExtraRoots = (roots ?? []).filter((root) => root.trim());
|
|
176
|
+
}
|
|
136
177
|
/**
|
|
137
178
|
* 节点旁路推送 RuntimeEvent(子图 Skill 生命周期、Tool 执行)。
|
|
138
179
|
* 无本次执行流式袋时为空操作(纯 invoke)。
|
|
@@ -290,7 +331,7 @@ export class LangGraphAdapter {
|
|
|
290
331
|
toolName: progress.toolName,
|
|
291
332
|
...(progress.toolset ? { toolset: progress.toolset } : {}),
|
|
292
333
|
error: progress.error ?? 'Unknown error',
|
|
293
|
-
willRetry:
|
|
334
|
+
willRetry: progress.willRetry === true,
|
|
294
335
|
...loc,
|
|
295
336
|
},
|
|
296
337
|
});
|
|
@@ -312,6 +353,7 @@ export class LangGraphAdapter {
|
|
|
312
353
|
*/
|
|
313
354
|
async buildGraph(dsl) {
|
|
314
355
|
this.assertShouldContinueTargetsTool(dsl);
|
|
356
|
+
assertEmbeddedSubgraphsAreFlat(dsl);
|
|
315
357
|
const silentNodeIds = new Set(dsl.nodes
|
|
316
358
|
.filter((node) => node.type === 'llm' && node.config?.['silent'] === true)
|
|
317
359
|
.map((node) => node.id));
|
|
@@ -342,6 +384,10 @@ export class LangGraphAdapter {
|
|
|
342
384
|
value: (_current, update) => update,
|
|
343
385
|
default: () => '',
|
|
344
386
|
},
|
|
387
|
+
historyPath: {
|
|
388
|
+
value: (current, update) => mergeHistoryPath(current, update),
|
|
389
|
+
default: () => [],
|
|
390
|
+
},
|
|
345
391
|
// ── 运行期上下文(ephemeral):由 invoke/stream 入口注入,节点只读 ──
|
|
346
392
|
userId: ephemeral(''),
|
|
347
393
|
// agentId 已废弃:channel 保留仅为旧 Checkpoint 反序列化兼容,新代码只写 agentCode
|
|
@@ -352,6 +398,8 @@ export class LangGraphAdapter {
|
|
|
352
398
|
correlationId: ephemeral(''),
|
|
353
399
|
taskId: ephemeral(''),
|
|
354
400
|
sessionId: ephemeral(''),
|
|
401
|
+
checkpointNs: ephemeral(undefined),
|
|
402
|
+
skillIsolateContext: ephemeral(undefined),
|
|
355
403
|
loadedTools: ephemeral(undefined),
|
|
356
404
|
loadedSkills: ephemeral(undefined),
|
|
357
405
|
skillDefinitions: ephemeral(undefined),
|
|
@@ -364,9 +412,15 @@ export class LangGraphAdapter {
|
|
|
364
412
|
agentDir: ephemeral(undefined),
|
|
365
413
|
executionContext: ephemeral(undefined),
|
|
366
414
|
forceToolServer: ephemeral(undefined),
|
|
415
|
+
// 请求级检索范围(前端圈定 fileIds/dirPaths;rag 节点读取,仅本地检索源生效)
|
|
416
|
+
ragScope: ephemeral(undefined),
|
|
417
|
+
// 会话级数据源勾选(数据源 id 列表,undefined=全部启用;rag 节点读取)
|
|
418
|
+
ragSources: ephemeral(undefined),
|
|
367
419
|
traceCollector: ephemeral(undefined),
|
|
368
420
|
traceId: ephemeral(undefined),
|
|
369
421
|
skillSpanId: ephemeral(undefined),
|
|
422
|
+
toolSpanId: ephemeral(undefined),
|
|
423
|
+
hitlToolCallId: ephemeral(undefined),
|
|
370
424
|
lastSpanId: ephemeral(undefined),
|
|
371
425
|
hitlChoice: ephemeral(undefined),
|
|
372
426
|
// ── LLM Token 使用量:数组累加器 reducer,每次 LLM 节点追加一条使用明细
|
|
@@ -378,7 +432,6 @@ export class LangGraphAdapter {
|
|
|
378
432
|
},
|
|
379
433
|
default: () => [],
|
|
380
434
|
},
|
|
381
|
-
__parallelResults: ephemeral(undefined),
|
|
382
435
|
__codeResult: ephemeral(undefined),
|
|
383
436
|
__codeError: ephemeral(undefined),
|
|
384
437
|
__conditionResult: ephemeral(undefined),
|
|
@@ -450,7 +503,7 @@ export class LangGraphAdapter {
|
|
|
450
503
|
*/
|
|
451
504
|
async *stream(graph, state) {
|
|
452
505
|
const ref = this.getCompiledRef(graph);
|
|
453
|
-
const input = this.graphStateToLangGraphInput(state);
|
|
506
|
+
const input = this.graphStateToLangGraphInput(this.applyDeclaredSearchFace(state, ref.dsl));
|
|
454
507
|
const queue = [];
|
|
455
508
|
const waiter = { fn: null };
|
|
456
509
|
let finished = false;
|
|
@@ -482,13 +535,7 @@ export class LangGraphAdapter {
|
|
|
482
535
|
const producer = runWithExecutionTrace({ ...traceCtx, stream: streamBag }, () => (async () => {
|
|
483
536
|
try {
|
|
484
537
|
const streamIterator = await ref.compiled.stream(input, langGraphRunOptions(ref.dsl, {
|
|
485
|
-
configurable:
|
|
486
|
-
thread_id: resolveCheckpointThreadId({
|
|
487
|
-
sessionId: typeof state.sessionId === 'string' ? state.sessionId : undefined,
|
|
488
|
-
taskId: state.taskId,
|
|
489
|
-
graphId: graph.id,
|
|
490
|
-
}),
|
|
491
|
-
},
|
|
538
|
+
configurable: this.checkpointConfigurable(state, graph),
|
|
492
539
|
streamMode: 'updates',
|
|
493
540
|
}));
|
|
494
541
|
for await (const update of streamIterator) {
|
|
@@ -523,18 +570,12 @@ export class LangGraphAdapter {
|
|
|
523
570
|
*/
|
|
524
571
|
async invoke(graph, state) {
|
|
525
572
|
const ref = this.getCompiledRef(graph);
|
|
526
|
-
const input = this.graphStateToLangGraphInput(state);
|
|
573
|
+
const input = this.graphStateToLangGraphInput(this.applyDeclaredSearchFace(state, ref.dsl));
|
|
527
574
|
const startTime = Date.now();
|
|
528
575
|
const traceCtx = executionTraceFromState(state);
|
|
529
576
|
// 只补 collector/traceId。子图套娃时外层 stream 袋经 ?? 保留。
|
|
530
577
|
const result = await runWithExecutionTrace(traceCtx, () => ref.compiled.invoke(input, langGraphRunOptions(ref.dsl, {
|
|
531
|
-
configurable:
|
|
532
|
-
thread_id: resolveCheckpointThreadId({
|
|
533
|
-
sessionId: typeof state.sessionId === 'string' ? state.sessionId : undefined,
|
|
534
|
-
taskId: state.taskId,
|
|
535
|
-
graphId: graph.id,
|
|
536
|
-
}),
|
|
537
|
-
},
|
|
578
|
+
configurable: this.checkpointConfigurable(state, graph),
|
|
538
579
|
})));
|
|
539
580
|
const duration = Date.now() - startTime;
|
|
540
581
|
const messages = Array.isArray(result['messages']) ? result['messages'] : [];
|
|
@@ -627,10 +668,35 @@ export class LangGraphAdapter {
|
|
|
627
668
|
// ─────────────────────────────────────────────
|
|
628
669
|
// Private helpers
|
|
629
670
|
// ─────────────────────────────────────────────
|
|
671
|
+
checkpointConfigurable(state, graph) {
|
|
672
|
+
const thread_id = resolveCheckpointThreadId({
|
|
673
|
+
sessionId: typeof state.sessionId === 'string' ? state.sessionId : undefined,
|
|
674
|
+
taskId: state.taskId,
|
|
675
|
+
graphId: graph.id,
|
|
676
|
+
});
|
|
677
|
+
const ns = typeof state.checkpointNs === 'string' ? state.checkpointNs.trim() : '';
|
|
678
|
+
// 子图是独立 compile 再 invoke,LangGraph put 不一定带回 checkpoint_ns;槽位编进 thread_id。
|
|
679
|
+
return { thread_id: checkpointStorageThreadId(thread_id, ns) };
|
|
680
|
+
}
|
|
630
681
|
/**
|
|
631
682
|
* 根据节点类型创建对应的执行函数
|
|
632
683
|
*/
|
|
633
684
|
createNodeFunction(node) {
|
|
685
|
+
const impl = this.createNodeFunctionBody(node);
|
|
686
|
+
return async (state) => {
|
|
687
|
+
const update = await impl(state);
|
|
688
|
+
const patch = update && typeof update === 'object' ? { ...update } : {};
|
|
689
|
+
const currentNode = typeof patch['currentNode'] === 'string' && String(patch['currentNode']).trim()
|
|
690
|
+
? String(patch['currentNode']).trim()
|
|
691
|
+
: node.id;
|
|
692
|
+
if (!Array.isArray(patch['historyPath'])) {
|
|
693
|
+
patch['historyPath'] = [currentNode];
|
|
694
|
+
}
|
|
695
|
+
patch['currentNode'] = currentNode;
|
|
696
|
+
return patch;
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
createNodeFunctionBody(node) {
|
|
634
700
|
switch (node.type) {
|
|
635
701
|
case 'llm':
|
|
636
702
|
return this.createLLMNodeFunction(node);
|
|
@@ -651,23 +717,26 @@ export class LangGraphAdapter {
|
|
|
651
717
|
case 'subgraph':
|
|
652
718
|
return this.createSubGraphNodeFunction(node);
|
|
653
719
|
case 'human':
|
|
654
|
-
|
|
655
|
-
return { currentNode: node.id };
|
|
656
|
-
};
|
|
657
|
-
case 'parallel':
|
|
658
|
-
return this.createParallelNodeFunction(node);
|
|
720
|
+
throw new AppError(ErrorCodes.GRAPH_BUILD_FAILED, `Graph 节点 "${node.id}" type=human 未实现;人工确认请用 require_confirmation`, { exposeMessage: true });
|
|
659
721
|
case 'code':
|
|
660
722
|
if (node.config?.['bindSkill'] === true) {
|
|
661
723
|
return this.createSkillBindNodeFunction(node);
|
|
662
724
|
}
|
|
663
725
|
return this.createCodeNodeFunction(node);
|
|
664
|
-
|
|
726
|
+
case 'rag':
|
|
727
|
+
return this.createRagNodeFunction(node);
|
|
728
|
+
default: {
|
|
665
729
|
if (node.config?.['bindSkill'] === true) {
|
|
666
730
|
return this.createSkillBindNodeFunction(node);
|
|
667
731
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
732
|
+
const type = String(node.type);
|
|
733
|
+
if (type === 'start' || type === 'end') {
|
|
734
|
+
return async (state) => {
|
|
735
|
+
return { ...state, currentNode: node.id };
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
throw new AppError(ErrorCodes.GRAPH_BUILD_FAILED, `Graph 节点 "${node.id}" type=${type} 不是合法类型`, { exposeMessage: true });
|
|
739
|
+
}
|
|
671
740
|
}
|
|
672
741
|
}
|
|
673
742
|
createSkillBindNodeFunction(node) {
|
|
@@ -744,7 +813,7 @@ export class LangGraphAdapter {
|
|
|
744
813
|
userId: 'system',
|
|
745
814
|
delegationToken: '',
|
|
746
815
|
agentCode: '',
|
|
747
|
-
}, (progress) => this.emitToolExecutionEvents(progress), this.hitlHandler, node.id);
|
|
816
|
+
}, (progress) => this.emitToolExecutionEvents(progress), this.hitlHandler, node.id, this.interceptors, node.config?.['retrievalSources'], node.config?.['totalK'], node.retry);
|
|
748
817
|
return (state) => toolNode.execute(state);
|
|
749
818
|
}
|
|
750
819
|
if (this.toolExecutor) {
|
|
@@ -767,7 +836,7 @@ export class LangGraphAdapter {
|
|
|
767
836
|
const jailExtraRoots = Object.values(skillDefs ?? {})
|
|
768
837
|
.map((skill) => skill.bundlePath)
|
|
769
838
|
.filter((p) => Boolean(p));
|
|
770
|
-
const
|
|
839
|
+
const request = {
|
|
771
840
|
toolCallId,
|
|
772
841
|
toolName,
|
|
773
842
|
arguments: defaultArgs,
|
|
@@ -775,7 +844,25 @@ export class LangGraphAdapter {
|
|
|
775
844
|
correlationId,
|
|
776
845
|
taskId,
|
|
777
846
|
...(jailExtraRoots.length > 0 ? { jailExtraRoots } : {}),
|
|
778
|
-
}
|
|
847
|
+
};
|
|
848
|
+
const retry = resolveToolRetryConfig(node.retry);
|
|
849
|
+
const maxRetries = retry?.maxRetries ?? 0;
|
|
850
|
+
let result = await this.toolExecutor.execute(request);
|
|
851
|
+
for (let attempt = 0; !result.success && attempt < maxRetries; attempt++) {
|
|
852
|
+
if (!isRetryableToolFailure(result))
|
|
853
|
+
break;
|
|
854
|
+
this.emitToolExecutionEvents({
|
|
855
|
+
toolCallId: result.toolCallId,
|
|
856
|
+
toolName: result.toolName,
|
|
857
|
+
status: 'error',
|
|
858
|
+
arguments: defaultArgs,
|
|
859
|
+
error: result.error,
|
|
860
|
+
willRetry: true,
|
|
861
|
+
node: node.id,
|
|
862
|
+
});
|
|
863
|
+
await sleepToolRetry(toolRetryDelayMs(attempt, retry.backoff));
|
|
864
|
+
result = await this.toolExecutor.execute(request);
|
|
865
|
+
}
|
|
779
866
|
const executionTime = Date.now() - startedAt;
|
|
780
867
|
const skillDirs = Object.values(skillDefs ?? {})
|
|
781
868
|
.filter((skill) => Boolean(skill.bundlePath))
|
|
@@ -787,6 +874,7 @@ export class LangGraphAdapter {
|
|
|
787
874
|
arguments: defaultArgs,
|
|
788
875
|
content: result.content,
|
|
789
876
|
error: result.error,
|
|
877
|
+
willRetry: false,
|
|
790
878
|
executionTime,
|
|
791
879
|
node: node.id,
|
|
792
880
|
...(skillDirs.length > 0 ? { skillDirs } : {}),
|
|
@@ -891,6 +979,9 @@ export class LangGraphAdapter {
|
|
|
891
979
|
loadedTools,
|
|
892
980
|
skillDefinitions: skillDefs,
|
|
893
981
|
});
|
|
982
|
+
if (this.overlayExtraRoots.length > 0) {
|
|
983
|
+
jail.extraRoots = [...(jail.extraRoots ?? []), ...this.overlayExtraRoots];
|
|
984
|
+
}
|
|
894
985
|
const workingDirectory = jail.workdir;
|
|
895
986
|
const jailRoots = resolveJailRoots(jail);
|
|
896
987
|
const skillDirs = Object.values(skillDefs ?? {})
|
|
@@ -972,7 +1063,7 @@ export class LangGraphAdapter {
|
|
|
972
1063
|
},
|
|
973
1064
|
});
|
|
974
1065
|
}
|
|
975
|
-
: undefined);
|
|
1066
|
+
: undefined, this.interceptors);
|
|
976
1067
|
const next = await llmNode.execute(state);
|
|
977
1068
|
const hydratedUpdate = loadedTools && loadedTools !== loadedToolsBase ? { loadedTools } : {};
|
|
978
1069
|
if (!silent)
|
|
@@ -990,6 +1081,31 @@ export class LangGraphAdapter {
|
|
|
990
1081
|
});
|
|
991
1082
|
};
|
|
992
1083
|
}
|
|
1084
|
+
/**
|
|
1085
|
+
* RAG 节点:编译期 fail-fast(deps 缺失),请求级状态经 execute(state) 流转
|
|
1086
|
+
*/
|
|
1087
|
+
createRagNodeFunction(node) {
|
|
1088
|
+
if (!this.ragNodeDeps) {
|
|
1089
|
+
throw new Error(`图使用了 type:rag 节点 "${node.id}",但宿主未注入 ragNodeDeps(LangGraphAdapter 第 6 参)`);
|
|
1090
|
+
}
|
|
1091
|
+
const ragNode = new RagNode(node.id, (node.config ?? {}), {
|
|
1092
|
+
...this.ragNodeDeps,
|
|
1093
|
+
// 未显式提供时复用 adapter 已组装的 orchestrator(§9.3:toolExecutor+governance 透传)
|
|
1094
|
+
toolOrchestrator: this.ragNodeDeps.toolOrchestrator ?? this.toolOrchestrator,
|
|
1095
|
+
// rag.* 事件接 SSE 旁路(请求级执行流存活期间有效;宿主/测试注入的 emitEvent 优先)
|
|
1096
|
+
emitEvent: this.ragNodeDeps.emitEvent ??
|
|
1097
|
+
((type, payload) => {
|
|
1098
|
+
this.emitStreamEvent({
|
|
1099
|
+
type,
|
|
1100
|
+
taskId: undefined,
|
|
1101
|
+
correlationId: undefined,
|
|
1102
|
+
timestamp: new Date().toISOString(),
|
|
1103
|
+
payload,
|
|
1104
|
+
});
|
|
1105
|
+
}),
|
|
1106
|
+
});
|
|
1107
|
+
return (state) => ragNode.execute(state);
|
|
1108
|
+
}
|
|
993
1109
|
/**
|
|
994
1110
|
* 子图节点:优先 config.subgraphDsl;否则按 skillId 从 state.skillDefinitions.workflow 解析。
|
|
995
1111
|
* 技能正文用短目录 + read_file,不灌 system。
|
|
@@ -1000,7 +1116,10 @@ export class LangGraphAdapter {
|
|
|
1000
1116
|
node.config?.['skillId'] ??
|
|
1001
1117
|
embeddedDsl?.name;
|
|
1002
1118
|
if (embeddedDsl) {
|
|
1003
|
-
return this.subGraphCompiler.compileSubGraph(embeddedDsl, configuredSkillId
|
|
1119
|
+
return this.subGraphCompiler.compileSubGraph(embeddedDsl, configuredSkillId, {
|
|
1120
|
+
isolateContext: isSkillContextIsolated(node),
|
|
1121
|
+
parentNodeId: node.id,
|
|
1122
|
+
});
|
|
1004
1123
|
}
|
|
1005
1124
|
return async (state) => {
|
|
1006
1125
|
const skillId = configuredSkillId ??
|
|
@@ -1011,70 +1130,13 @@ export class LangGraphAdapter {
|
|
|
1011
1130
|
if (!workflow?.nodes?.length) {
|
|
1012
1131
|
throw preloadSkillNotFound(`子图节点无法解析 Skill workflow: node=${node.id}, skillId=${skillId ?? '(none)'}`, { nodeId: node.id, skillId });
|
|
1013
1132
|
}
|
|
1014
|
-
const fn = this.subGraphCompiler.compileSubGraph(workflow, skillId ?? def?.skillId
|
|
1133
|
+
const fn = this.subGraphCompiler.compileSubGraph(workflow, skillId ?? def?.skillId, {
|
|
1134
|
+
isolateContext: isSkillContextIsolated(node),
|
|
1135
|
+
parentNodeId: node.id,
|
|
1136
|
+
});
|
|
1015
1137
|
return fn(state);
|
|
1016
1138
|
};
|
|
1017
1139
|
}
|
|
1018
|
-
/**
|
|
1019
|
-
* 并行节点:并行执行多个子任务分支
|
|
1020
|
-
*
|
|
1021
|
-
* 支持两种并行模式:
|
|
1022
|
-
* 1. branches 模式:node.branches 列出要并行执行的节点 ID,每个节点的执行函数由 DSL 定义
|
|
1023
|
-
* 2. tasks 模式:node.config.tasks 列出要并行执行的异步任务函数
|
|
1024
|
-
*
|
|
1025
|
-
* 执行结果合并到 state.__parallelResults 中。
|
|
1026
|
-
*/
|
|
1027
|
-
createParallelNodeFunction(node) {
|
|
1028
|
-
return async (state) => {
|
|
1029
|
-
const branchNodeIds = node.branches ?? node.config?.['branches'] ?? [];
|
|
1030
|
-
const tasks = node.config?.['tasks'];
|
|
1031
|
-
const results = [];
|
|
1032
|
-
if (tasks?.length) {
|
|
1033
|
-
// tasks 模式:并行执行配置的任务
|
|
1034
|
-
const promises = tasks.map(async (task) => {
|
|
1035
|
-
try {
|
|
1036
|
-
// 任务结果由外部注入的 task executor 处理
|
|
1037
|
-
// 此处仅记录任务 ID,实际执行依赖外部编排
|
|
1038
|
-
return { branchId: task.id, success: true, result: { taskId: task.id, status: 'dispatched' } };
|
|
1039
|
-
}
|
|
1040
|
-
catch (err) {
|
|
1041
|
-
return {
|
|
1042
|
-
branchId: task.id,
|
|
1043
|
-
success: false,
|
|
1044
|
-
error: err instanceof Error ? err.message : String(err),
|
|
1045
|
-
};
|
|
1046
|
-
}
|
|
1047
|
-
});
|
|
1048
|
-
results.push(...await Promise.all(promises));
|
|
1049
|
-
}
|
|
1050
|
-
else if (branchNodeIds.length) {
|
|
1051
|
-
// branches 模式:并行执行分支节点
|
|
1052
|
-
const promises = branchNodeIds.map(async (branchId) => {
|
|
1053
|
-
try {
|
|
1054
|
-
// 每个分支节点的实际执行由 LangGraph 编排层驱动
|
|
1055
|
-
// 并行节点仅负责触发并汇总状态
|
|
1056
|
-
return { branchId, success: true, result: { dispatched: true } };
|
|
1057
|
-
}
|
|
1058
|
-
catch (err) {
|
|
1059
|
-
return {
|
|
1060
|
-
branchId,
|
|
1061
|
-
success: false,
|
|
1062
|
-
error: err instanceof Error ? err.message : String(err),
|
|
1063
|
-
};
|
|
1064
|
-
}
|
|
1065
|
-
});
|
|
1066
|
-
results.push(...await Promise.all(promises));
|
|
1067
|
-
}
|
|
1068
|
-
const allSuccess = results.every((r) => r.success);
|
|
1069
|
-
return {
|
|
1070
|
-
...state,
|
|
1071
|
-
currentNode: node.id,
|
|
1072
|
-
__parallelResults: results,
|
|
1073
|
-
__parallelAllSuccess: allSuccess,
|
|
1074
|
-
__conditionResult: allSuccess ? 'success' : 'partial_failure',
|
|
1075
|
-
};
|
|
1076
|
-
};
|
|
1077
|
-
}
|
|
1078
1140
|
/**
|
|
1079
1141
|
* 代码执行节点:在受限沙箱中执行用户代码
|
|
1080
1142
|
*
|
|
@@ -1250,6 +1312,41 @@ export class LangGraphAdapter {
|
|
|
1250
1312
|
* 否则多轮回放时 DeepSeek thinking 会因缺少 reasoning_content 而 400,
|
|
1251
1313
|
* tool 消息也会丢掉 tool_call_id。
|
|
1252
1314
|
*/
|
|
1315
|
+
/**
|
|
1316
|
+
* 工具形态检索面白名单(图声明即真相):tool 节点 config.retrievalSources 声明的
|
|
1317
|
+
* 数据源目录 → 本图工具白名单(声明源解析出的工具 + rag_search)。未声明的检索类
|
|
1318
|
+
* 工具对主 LLM 工具表与执行链整体不可见/不可用;图未声明 = 不收敓名单(通用形态)。
|
|
1319
|
+
*
|
|
1320
|
+
* 约束——单检索面假设:find 只取全图首个带 retrievalSources 的 tool 节点、按它过滤
|
|
1321
|
+
* 全图 loadedTools。多 tool 节点各声明检索面属未支持场景:第二面的工具会被当成
|
|
1322
|
+
* 未声明而过滤,无法各自收敛;如需支持须改为 per-node 收敛(在节点边界分别过滤
|
|
1323
|
+
* loadedTools,而非此处全图一次性收敛)。
|
|
1324
|
+
*/
|
|
1325
|
+
applyDeclaredSearchFace(state, dsl) {
|
|
1326
|
+
const face = dsl?.nodes?.find((n) => n.type === 'tool' && n.config?.['retrievalSources']);
|
|
1327
|
+
const declaration = face?.config?.['retrievalSources'];
|
|
1328
|
+
const loaded = state.loadedTools;
|
|
1329
|
+
if (!declaration || !loaded || typeof loaded !== 'object')
|
|
1330
|
+
return state;
|
|
1331
|
+
const resolved = resolveRagSources({ retrievalSources: declaration });
|
|
1332
|
+
const allowed = new Set([...(resolved.toolScope ?? []), RAG_SEARCH_TOOL_NAME]);
|
|
1333
|
+
const filtered = {};
|
|
1334
|
+
for (const [name, def] of Object.entries(loaded)) {
|
|
1335
|
+
if (!allowed.has(name))
|
|
1336
|
+
continue;
|
|
1337
|
+
// 数据源目录写进保留工具的 description(幂等)——主 LLM 直调时与 rag 内核
|
|
1338
|
+
// 同一份目录,杜绝瞎猜 datasetCode;内核组表侧 appendSourceCatalog 幂等不重复
|
|
1339
|
+
const catalog = resolved.sourceCatalog[name];
|
|
1340
|
+
if (catalog?.length) {
|
|
1341
|
+
const desc = appendSourceCatalog(def.manifest.description, catalog);
|
|
1342
|
+
filtered[name] = { ...def, manifest: { ...def.manifest, description: desc } };
|
|
1343
|
+
}
|
|
1344
|
+
else {
|
|
1345
|
+
filtered[name] = def;
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
return { ...state, loadedTools: filtered };
|
|
1349
|
+
}
|
|
1253
1350
|
graphStateToLangGraphInput(state) {
|
|
1254
1351
|
const mapped = (state.messages ?? []).map((msg) => ({
|
|
1255
1352
|
role: msg.role,
|
|
@@ -1306,7 +1403,10 @@ export class LangGraphAdapter {
|
|
|
1306
1403
|
if (msg.role === 'assistant' && Array.isArray(msg.toolCalls) && msg.toolCalls.length > 0) {
|
|
1307
1404
|
// tool.called 由 Tool 节点在真正执行时发出,此处不再把 LLM function-call 当执行开始
|
|
1308
1405
|
// 子图节点的 updates 是内层已 stream 过的回写,不要再发空 reasoning chunk
|
|
1309
|
-
if (
|
|
1406
|
+
if (silentNodeIds.has(nodeId)) {
|
|
1407
|
+
continue;
|
|
1408
|
+
}
|
|
1409
|
+
if (subgraphNodeIds.has(nodeId) && streamedTextThisTurn) {
|
|
1310
1410
|
continue;
|
|
1311
1411
|
}
|
|
1312
1412
|
const hasText = typeof msg.content === 'string' && msg.content.trim().length > 0;
|
|
@@ -1333,7 +1433,9 @@ export class LangGraphAdapter {
|
|
|
1333
1433
|
continue;
|
|
1334
1434
|
}
|
|
1335
1435
|
if (msg.role === 'assistant' && typeof msg.content === 'string' && msg.content.length > 0) {
|
|
1336
|
-
if (silentNodeIds.has(nodeId)
|
|
1436
|
+
if (silentNodeIds.has(nodeId))
|
|
1437
|
+
continue;
|
|
1438
|
+
if (subgraphNodeIds.has(nodeId) && streamedTextThisTurn)
|
|
1337
1439
|
continue;
|
|
1338
1440
|
// 已通过 onChunk 推送过 token,避免整段重复
|
|
1339
1441
|
if (streamedTextThisTurn) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill 子图可选隔离(实验口)。仅节点 `isolateContext: true`。
|
|
3
|
+
* 只把本轮输入给子图,回写最后一条带正文的 assistant;没有则不回写。
|
|
4
|
+
* 子图 Checkpoint / HITL 走 `sessionId#父节点id`,不写父 latest。
|
|
5
|
+
*/
|
|
6
|
+
import type { GraphMessage } from '../contracts/executable-graph.js';
|
|
7
|
+
import type { GraphNode } from '../contracts/executable-graph.js';
|
|
8
|
+
/** 只认节点配置。进程环境变量不会给所有 subgraph 开隔离。 */
|
|
9
|
+
export declare function isSkillContextIsolated(node: GraphNode | undefined): boolean;
|
|
10
|
+
export declare function isolatedSkillMessages(parentMessages: GraphMessage[], skillInput: unknown): GraphMessage[];
|
|
11
|
+
/** 只回写最后一条带正文的 assistant;没有则空数组,避免把 tool 行丢给父图。 */
|
|
12
|
+
export declare function isolatedSkillOutput(added: GraphMessage[]): GraphMessage[];
|
|
13
|
+
export declare function isIsolatedSkillState(state: Record<string, unknown> | undefined): boolean;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill 子图可选隔离(实验口)。仅节点 `isolateContext: true`。
|
|
3
|
+
* 只把本轮输入给子图,回写最后一条带正文的 assistant;没有则不回写。
|
|
4
|
+
* 子图 Checkpoint / HITL 走 `sessionId#父节点id`,不写父 latest。
|
|
5
|
+
*/
|
|
6
|
+
/** 只认节点配置。进程环境变量不会给所有 subgraph 开隔离。 */
|
|
7
|
+
export function isSkillContextIsolated(node) {
|
|
8
|
+
return node?.config?.['isolateContext'] === true;
|
|
9
|
+
}
|
|
10
|
+
export function isolatedSkillMessages(parentMessages, skillInput) {
|
|
11
|
+
let text = '';
|
|
12
|
+
if (typeof skillInput === 'string' && skillInput.trim()) {
|
|
13
|
+
text = skillInput.trim();
|
|
14
|
+
}
|
|
15
|
+
else if (skillInput && typeof skillInput === 'object' && 'text' in skillInput) {
|
|
16
|
+
text = String(skillInput.text ?? '').trim();
|
|
17
|
+
}
|
|
18
|
+
if (!text) {
|
|
19
|
+
for (let i = parentMessages.length - 1; i >= 0; i--) {
|
|
20
|
+
if (parentMessages[i]?.role === 'user' && parentMessages[i]?.content) {
|
|
21
|
+
text = parentMessages[i].content;
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return [{ role: 'user', content: text || '' }];
|
|
27
|
+
}
|
|
28
|
+
/** 只回写最后一条带正文的 assistant;没有则空数组,避免把 tool 行丢给父图。 */
|
|
29
|
+
export function isolatedSkillOutput(added) {
|
|
30
|
+
for (let i = added.length - 1; i >= 0; i--) {
|
|
31
|
+
if (added[i]?.role === 'assistant' && added[i]?.content) {
|
|
32
|
+
return [{ role: 'assistant', content: added[i].content }];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
export function isIsolatedSkillState(state) {
|
|
38
|
+
return state?.['skillIsolateContext'] === true;
|
|
39
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 将 Skill DSL 编译为子图节点函数,嵌入父 Graph 执行。
|
|
5
5
|
* 子图作为独立 StateGraph 编译,父图通过节点函数调用子图并合并输出。
|
|
6
|
+
* Skill 子图不得再含 type=subgraph(G-3 / B14)。
|
|
6
7
|
*
|
|
7
8
|
* @see design.md §1.4 子图嵌套: Skill作为子图嵌入主Graph
|
|
8
9
|
* @see requirements.md Requirement 1 AC2 — 子图嵌套(Skill作为子图)
|
|
@@ -24,16 +25,20 @@ type LangGraphState = Record<string, unknown>;
|
|
|
24
25
|
* 4. 执行时,子图内部运行完整的 graph invoke 流程,输出合并回父图 state
|
|
25
26
|
*/
|
|
26
27
|
export declare class SubGraphCompiler {
|
|
28
|
+
private readonly auditReporter?;
|
|
27
29
|
private readonly adapter;
|
|
28
30
|
private readonly governanceClient?;
|
|
29
31
|
private readonly skillAuditRecorder?;
|
|
30
|
-
constructor(adapter?: LangGraphAdapter, governanceClient?: IGovernanceClient, skillAuditRecorder?: SkillAuditRecorder);
|
|
32
|
+
constructor(adapter?: LangGraphAdapter, governanceClient?: IGovernanceClient, skillAuditRecorder?: SkillAuditRecorder, auditReporter?: import("../../governance/audit-reporter.js").IAuditReporter | undefined);
|
|
31
33
|
/**
|
|
32
34
|
* 将 Skill DSL 编译为可嵌入父图的 NodeFunction
|
|
33
35
|
*
|
|
34
36
|
* @param dsl - Skill 的 GraphDSL 定义
|
|
35
37
|
* @param skillId - Skill 资源 ID(用于 checkPermission skill:use)
|
|
36
38
|
*/
|
|
37
|
-
compileSubGraph(dsl: GraphDSL, skillId?: string
|
|
39
|
+
compileSubGraph(dsl: GraphDSL, skillId?: string, options?: {
|
|
40
|
+
isolateContext?: boolean;
|
|
41
|
+
parentNodeId?: string;
|
|
42
|
+
}): NodeFunction<LangGraphState>;
|
|
38
43
|
}
|
|
39
44
|
export {};
|