@gt-fe/eap-runtime 0.0.32 → 0.0.33
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/dist/api/handlers/invoke.handler.js +3 -1
- package/dist/api/handlers/stream.handler.js +3 -1
- package/dist/graph/adapters/langgraph.adapter.d.ts +0 -1
- package/dist/graph/adapters/langgraph.adapter.js +9 -19
- package/dist/graph/adapters/skill-entry-span.js +4 -1
- package/dist/graph/adapters/subgraph-compiler.js +11 -9
- package/dist/graph/contracts/executable-graph.d.ts +2 -0
- package/dist/graph/nodes/skill-bind-node.d.ts +1 -1
- package/dist/graph/nodes/skill-bind-node.js +6 -1
- package/dist/graph/nodes/tool-node.js +1 -0
- package/dist/registry/graph-loader.d.ts +11 -0
- package/dist/registry/graph-loader.js +28 -4
- package/dist/runtime/agent-runtime.js +10 -1
- package/dist/tool/index.d.ts +1 -1
- package/dist/tool/index.js +1 -1
- package/dist/tool/mcp-list.d.ts +3 -1
- package/dist/tool/mcp-list.js +4 -1
- package/dist/tool/system-prompt-builder.d.ts +8 -2
- package/dist/tool/system-prompt-builder.js +36 -8
- package/package.json +1 -1
|
@@ -27,7 +27,7 @@ import { classifyRuntimeError } from '../../utils/http-error.js';
|
|
|
27
27
|
import { DEFAULT_GRAPH_TIMEOUT_MS } from '../../common/types.js';
|
|
28
28
|
import { resolveTaskTimeoutMs } from '../../task/resolve-task-timeout.js';
|
|
29
29
|
import { runWithExecutionTrace } from '../../graph/execution-trace-context.js';
|
|
30
|
-
import { resolveAgentSystemPromptFromLoader } from '../../registry/graph-loader.js';
|
|
30
|
+
import { resolveAgentDisplayNameFromLoader, resolveAgentSystemPromptFromLoader, } from '../../registry/graph-loader.js';
|
|
31
31
|
import { toLoadedToolMap } from '../../tool/loaded-tool-definition.js';
|
|
32
32
|
import { toLoadedSkillMap } from '../../tool/system-prompt-builder.js';
|
|
33
33
|
import { assembleLoadedTools } from '../../tool/harness-primitives.js';
|
|
@@ -204,6 +204,7 @@ export class InvokeOrchestrator {
|
|
|
204
204
|
? (await this.graphLoader.resolveAgentDir(agentCode, req.agentVersion)) ?? undefined
|
|
205
205
|
: undefined;
|
|
206
206
|
const agentSystemPrompt = await resolveAgentSystemPromptFromLoader(this.graphLoader, agentCode, req.agentVersion);
|
|
207
|
+
const agentName = await resolveAgentDisplayNameFromLoader(this.graphLoader, agentCode, req.agentVersion);
|
|
207
208
|
// 模型上下文:Checkpoint 已有 messages 则压它;压成功用 __set 写回最新 Checkpoint。Message 库不改。
|
|
208
209
|
const facing = await loadModelFacingHistory({
|
|
209
210
|
sessionHistory: messageRecordsToGraphMessages(sessionContext.messages),
|
|
@@ -261,6 +262,7 @@ export class InvokeOrchestrator {
|
|
|
261
262
|
promptRoots,
|
|
262
263
|
agentDir,
|
|
263
264
|
agentSystemPrompt,
|
|
265
|
+
agentName,
|
|
264
266
|
traceId: resolveTraceId(req),
|
|
265
267
|
traceCollector: this.traceCollector,
|
|
266
268
|
abortSignal,
|
|
@@ -31,7 +31,7 @@ import { SSEEmitter } from '../../sse/sse-emitter.js';
|
|
|
31
31
|
import { resolveExecutionContext } from '../../governance/governance-client.js';
|
|
32
32
|
import { resolveSkillInputFromInvokeInput } from '../../registry/skill-io-guard.js';
|
|
33
33
|
import { ErrorCodes } from '@gt-fe/eap-contracts';
|
|
34
|
-
import { resolveAgentSystemPromptFromLoader } from '../../registry/graph-loader.js';
|
|
34
|
+
import { resolveAgentDisplayNameFromLoader, resolveAgentSystemPromptFromLoader, } from '../../registry/graph-loader.js';
|
|
35
35
|
import { classifyRuntimeError } from '../../utils/http-error.js';
|
|
36
36
|
import { toLoadedToolMap } from '../../tool/loaded-tool-definition.js';
|
|
37
37
|
import { toLoadedSkillMap } from '../../tool/system-prompt-builder.js';
|
|
@@ -222,6 +222,7 @@ export class StreamOrchestrator {
|
|
|
222
222
|
? (await this.graphLoader.resolveAgentDir(agentCode, req.agentVersion)) ?? undefined
|
|
223
223
|
: undefined;
|
|
224
224
|
const agentSystemPrompt = await resolveAgentSystemPromptFromLoader(this.graphLoader, agentCode, req.agentVersion);
|
|
225
|
+
const agentName = await resolveAgentDisplayNameFromLoader(this.graphLoader, agentCode, req.agentVersion);
|
|
225
226
|
// 模型上下文:Checkpoint 已有 messages 则压它;压成功用 __set 写回最新 Checkpoint。Message 库不改。
|
|
226
227
|
const facing = await loadModelFacingHistory({
|
|
227
228
|
sessionHistory: messageRecordsToGraphMessages(sessionContext.messages),
|
|
@@ -293,6 +294,7 @@ export class StreamOrchestrator {
|
|
|
293
294
|
promptRoots,
|
|
294
295
|
agentDir,
|
|
295
296
|
agentSystemPrompt,
|
|
297
|
+
agentName,
|
|
296
298
|
traceId: resolveTraceId(req),
|
|
297
299
|
traceCollector: this.traceCollector,
|
|
298
300
|
abortSignal,
|
|
@@ -127,7 +127,6 @@ export declare class LangGraphAdapter implements IStateGraphEngine {
|
|
|
127
127
|
private createNodeFunction;
|
|
128
128
|
private createNodeFunctionBody;
|
|
129
129
|
private createSkillBindNodeFunction;
|
|
130
|
-
private buildSkillCatalog;
|
|
131
130
|
private createToolNodeFunction;
|
|
132
131
|
private createLLMNodeFunction;
|
|
133
132
|
/**
|
|
@@ -23,7 +23,7 @@ import { ToolResultInjector } from '../../tool/tool-result-injector.js';
|
|
|
23
23
|
import { fileArtifactFromToolOutput } from '../../tool/file-artifact.js';
|
|
24
24
|
import { EchoLLMProvider } from '../../providers/echo-llm-provider.js';
|
|
25
25
|
import { ConditionEvaluator } from '../condition-evaluator.js';
|
|
26
|
-
import { SystemPromptBuilder, buildToolCatalog, loadedToolsToApiTools, resolveLlmPromptInputs } from '../../tool/system-prompt-builder.js';
|
|
26
|
+
import { SystemPromptBuilder, buildSkillCatalog, buildToolCatalog, loadedToolsToApiTools, resolveLlmPromptInputs, spokenName } from '../../tool/system-prompt-builder.js';
|
|
27
27
|
import { resolveJailFromState, resolveJailRoots } from '../../tool/harness-primitives.js';
|
|
28
28
|
import os from 'node:os';
|
|
29
29
|
import { bindSelectedSkill } from '../nodes/skill-bind-node.js';
|
|
@@ -306,6 +306,7 @@ export class LangGraphAdapter {
|
|
|
306
306
|
alreadyInSkillSpan: progress.inSkillSubgraph,
|
|
307
307
|
});
|
|
308
308
|
if (catalogSkill) {
|
|
309
|
+
const skillName = spokenName(progress.skillName, catalogSkill.skillId) ?? catalogSkill.skillId;
|
|
309
310
|
stream.sink({
|
|
310
311
|
type: 'skill.started',
|
|
311
312
|
taskId,
|
|
@@ -313,7 +314,7 @@ export class LangGraphAdapter {
|
|
|
313
314
|
timestamp,
|
|
314
315
|
payload: {
|
|
315
316
|
skillId: catalogSkill.skillId,
|
|
316
|
-
skillName
|
|
317
|
+
skillName,
|
|
317
318
|
path: catalogSkill.path,
|
|
318
319
|
...(progress.skillSpace ? { skillSpace: progress.skillSpace } : {}),
|
|
319
320
|
...(progress.skillVersion ? { skillVersion: progress.skillVersion } : {}),
|
|
@@ -326,7 +327,7 @@ export class LangGraphAdapter {
|
|
|
326
327
|
timestamp,
|
|
327
328
|
payload: {
|
|
328
329
|
skillId: catalogSkill.skillId,
|
|
329
|
-
skillName
|
|
330
|
+
skillName,
|
|
330
331
|
},
|
|
331
332
|
});
|
|
332
333
|
}
|
|
@@ -460,6 +461,7 @@ export class LangGraphAdapter {
|
|
|
460
461
|
// agentId 已废弃:channel 保留仅为旧 Checkpoint 反序列化兼容,新代码只写 agentCode
|
|
461
462
|
agentId: ephemeral(''),
|
|
462
463
|
agentCode: ephemeral(''),
|
|
464
|
+
agentName: ephemeral(undefined),
|
|
463
465
|
agentVersion: ephemeral(undefined),
|
|
464
466
|
delegationToken: ephemeral(''),
|
|
465
467
|
correlationId: ephemeral(''),
|
|
@@ -856,7 +858,7 @@ export class LangGraphAdapter {
|
|
|
856
858
|
correlationId: undefined,
|
|
857
859
|
timestamp: new Date().toISOString(),
|
|
858
860
|
payload: {
|
|
859
|
-
skillName: patch.skillName
|
|
861
|
+
skillName: spokenName(patch.skillName, patch.activatedSkill) ?? patch.activatedSkill,
|
|
860
862
|
skillId: patch.activatedSkill,
|
|
861
863
|
confidence: 1,
|
|
862
864
|
},
|
|
@@ -898,20 +900,6 @@ export class LangGraphAdapter {
|
|
|
898
900
|
};
|
|
899
901
|
};
|
|
900
902
|
}
|
|
901
|
-
buildSkillCatalog(defs) {
|
|
902
|
-
if (!defs)
|
|
903
|
-
return undefined;
|
|
904
|
-
const rows = Object.values(defs).map((skill) => {
|
|
905
|
-
const desc = (skill.description ?? '').replace(/\s+/g, ' ').trim();
|
|
906
|
-
const entry = skill.entryFile ?? (skill.bundlePath ? `${skill.bundlePath}/SKILL.md` : '');
|
|
907
|
-
const title = skill.name && skill.name !== skill.skillId ? `${skill.skillId}(${skill.name})` : skill.skillId;
|
|
908
|
-
const pathLine = entry ? `\n SKILL.md: ${entry}` : '';
|
|
909
|
-
return `- **${title}**${desc ? `:${desc}` : ''}${pathLine}`;
|
|
910
|
-
});
|
|
911
|
-
if (rows.length === 0)
|
|
912
|
-
return undefined;
|
|
913
|
-
return `# 可用技能\n要用某个技能时,调用 read_file 读取其 SKILL.md。脚本和参考文档默认在同一目录。\n${rows.join('\n')}`;
|
|
914
|
-
}
|
|
915
903
|
createToolNodeFunction(node) {
|
|
916
904
|
const toolName = node.config?.['tool'] ?? node.id;
|
|
917
905
|
const defaultArgs = node.config?.['arguments'] ?? {};
|
|
@@ -1061,6 +1049,7 @@ export class LangGraphAdapter {
|
|
|
1061
1049
|
const resolvedPrompt = resolveGraphPrompt(baseConfig.systemPrompt, promptRoots);
|
|
1062
1050
|
const loadedToolsBase = state['loadedTools'];
|
|
1063
1051
|
const agentCode = typeof state['agentCode'] === 'string' ? state['agentCode'] : undefined;
|
|
1052
|
+
const agentName = typeof state['agentName'] === 'string' ? state['agentName'] : undefined;
|
|
1064
1053
|
const skillDefs = state['skillDefinitions'];
|
|
1065
1054
|
const execCtx = state['executionContext'];
|
|
1066
1055
|
const userId = (typeof execCtx?.userId === 'string' && execCtx.userId) || state['userId'];
|
|
@@ -1092,7 +1081,7 @@ export class LangGraphAdapter {
|
|
|
1092
1081
|
const toolNames = loadedTools ? Object.keys(loadedTools) : [];
|
|
1093
1082
|
console.log(`[LLM-DEBUG] node=${node.id} loadedTools=${toolNames.length}:`, toolNames);
|
|
1094
1083
|
}
|
|
1095
|
-
const catalog = includeSkillCatalog ?
|
|
1084
|
+
const catalog = includeSkillCatalog ? buildSkillCatalog(skillDefs) : undefined;
|
|
1096
1085
|
const toolCatalog = disableTools ? undefined : buildToolCatalog(loadedTools);
|
|
1097
1086
|
const jail = resolveJailFromState({
|
|
1098
1087
|
agentDir: state['agentDir'],
|
|
@@ -1123,6 +1112,7 @@ export class LangGraphAdapter {
|
|
|
1123
1112
|
nodePrompt: promptInputs.nodePrompt,
|
|
1124
1113
|
skillCatalog: catalog,
|
|
1125
1114
|
toolCatalog,
|
|
1115
|
+
agentName,
|
|
1126
1116
|
agentCode,
|
|
1127
1117
|
userId,
|
|
1128
1118
|
workingDirectory,
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { classifySkillFile, classifySkillSpace, isReadTool, } from './skill-read.js';
|
|
12
12
|
import { completeGraphSpan, startGraphSpan } from '../trace-span.js';
|
|
13
|
+
import { spokenName } from '../../tool/system-prompt-builder.js';
|
|
13
14
|
function declaredSkillVersion(skillId, version) {
|
|
14
15
|
const raw = version?.trim();
|
|
15
16
|
if (!raw || raw === skillId)
|
|
@@ -27,9 +28,10 @@ export function skillTraceIdentity(state, skillId, fallbackPath) {
|
|
|
27
28
|
const bundle = info?.bundlePath || fallbackPath;
|
|
28
29
|
const skillSpace = bundle ? classifySkillSpace(bundle, { agentDir, userId }) : undefined;
|
|
29
30
|
const skillVersion = declaredSkillVersion(skillId, info?.version);
|
|
31
|
+
const skillName = spokenName(info?.name, undefined);
|
|
30
32
|
return {
|
|
31
33
|
skillId,
|
|
32
|
-
...(
|
|
34
|
+
...(skillName ? { skillName } : {}),
|
|
33
35
|
...(skillVersion ? { skillVersion } : {}),
|
|
34
36
|
...(skillSpace ? { skillSpace } : {}),
|
|
35
37
|
};
|
|
@@ -39,6 +41,7 @@ export function skillSpanFields(identity, extra) {
|
|
|
39
41
|
...(identity.skillVersion ? { version: identity.skillVersion } : {}),
|
|
40
42
|
input: {
|
|
41
43
|
skillId: identity.skillId,
|
|
44
|
+
...(identity.skillName ? { skillName: identity.skillName } : {}),
|
|
42
45
|
...(identity.skillSpace ? { skillSpace: identity.skillSpace } : {}),
|
|
43
46
|
...(extra?.path ? { path: extra.path } : {}),
|
|
44
47
|
...(extra?.source ? { source: extra.source } : {}),
|
|
@@ -13,7 +13,7 @@ import { LangGraphAdapter } from './langgraph.adapter.js';
|
|
|
13
13
|
import { assertSkillGraphHasNoSubgraphNodes } from './graph-nesting.js';
|
|
14
14
|
import { resolveExecutionTrace, warnTraceSpanFailure, } from '../execution-trace-context.js';
|
|
15
15
|
import { skillSpanFields, skillTraceIdentity } from './skill-entry-span.js';
|
|
16
|
-
import { filterLoadedToolsForSkill, } from '../../tool/system-prompt-builder.js';
|
|
16
|
+
import { filterLoadedToolsForSkill, spokenName, } from '../../tool/system-prompt-builder.js';
|
|
17
17
|
import { unwrapHitlPaused } from '../hitl/hitl-handler.js';
|
|
18
18
|
import { pickContextFields } from '../../token/context-window.js';
|
|
19
19
|
import { assertSkillIoIfEnabled, coerceSkillInputFromMessages, } from '../../registry/skill-io-guard.js';
|
|
@@ -65,11 +65,14 @@ export class SubGraphCompiler {
|
|
|
65
65
|
? state['skillSpanId']
|
|
66
66
|
: '';
|
|
67
67
|
const resuming = Boolean(existingSpanId);
|
|
68
|
+
const identity = skillTraceIdentity(state, resolvedSkillId);
|
|
69
|
+
const spanName = resolvedSkillId || dsl.name || 'skill';
|
|
70
|
+
const skillName = spokenName(identity.skillName, resolvedSkillId) ?? spanName;
|
|
68
71
|
const auditCtx = resuming
|
|
69
72
|
? undefined
|
|
70
73
|
: this.skillAuditRecorder?.startInvocation({
|
|
71
74
|
skillId: resolvedSkillId,
|
|
72
|
-
skillName
|
|
75
|
+
skillName,
|
|
73
76
|
agentCode: (state['agentCode'] ?? state['agentId']),
|
|
74
77
|
userId: state['userId'] ?? '',
|
|
75
78
|
taskId: state['taskId'],
|
|
@@ -77,8 +80,6 @@ export class SubGraphCompiler {
|
|
|
77
80
|
});
|
|
78
81
|
// 用父图这次调用上的 collector;内层 invoke 只补 collector/traceId,沿用外层流式袋。
|
|
79
82
|
const { collector: traceCollector, traceId } = resolveExecutionTrace(state);
|
|
80
|
-
const skillName = dsl.name || resolvedSkillId;
|
|
81
|
-
const identity = skillTraceIdentity(state, resolvedSkillId);
|
|
82
83
|
if (!resuming) {
|
|
83
84
|
adapter.emitStreamEvent({
|
|
84
85
|
type: 'skill.started',
|
|
@@ -87,7 +88,7 @@ export class SubGraphCompiler {
|
|
|
87
88
|
timestamp: new Date().toISOString(),
|
|
88
89
|
payload: {
|
|
89
90
|
skillId: resolvedSkillId,
|
|
90
|
-
skillName
|
|
91
|
+
skillName,
|
|
91
92
|
...(identity.skillSpace ? { skillSpace: identity.skillSpace } : {}),
|
|
92
93
|
...(identity.skillVersion ? { skillVersion: identity.skillVersion } : {}),
|
|
93
94
|
},
|
|
@@ -99,7 +100,7 @@ export class SubGraphCompiler {
|
|
|
99
100
|
const fields = skillSpanFields(identity, { source: 'subgraph' });
|
|
100
101
|
skillSpanId = await traceCollector.createNode({
|
|
101
102
|
traceId,
|
|
102
|
-
name:
|
|
103
|
+
name: spanName,
|
|
103
104
|
type: 'skill',
|
|
104
105
|
agentCode: state['agentCode'] ?? state['agentId'],
|
|
105
106
|
...(fields.version ? { version: fields.version } : {}),
|
|
@@ -111,7 +112,7 @@ export class SubGraphCompiler {
|
|
|
111
112
|
});
|
|
112
113
|
}
|
|
113
114
|
catch (err) {
|
|
114
|
-
warnTraceSpanFailure('createNode', { type: 'skill', name:
|
|
115
|
+
warnTraceSpanFailure('createNode', { type: 'skill', name: spanName, traceId }, err);
|
|
115
116
|
skillSpanId = null;
|
|
116
117
|
}
|
|
117
118
|
}
|
|
@@ -154,6 +155,7 @@ export class SubGraphCompiler {
|
|
|
154
155
|
userId,
|
|
155
156
|
delegationToken,
|
|
156
157
|
agentCode,
|
|
158
|
+
agentName: typeof state['agentName'] === 'string' ? state['agentName'] : undefined,
|
|
157
159
|
taskId: state['taskId'],
|
|
158
160
|
correlationId: state['correlationId'],
|
|
159
161
|
sessionId: state['sessionId'],
|
|
@@ -194,7 +196,7 @@ export class SubGraphCompiler {
|
|
|
194
196
|
});
|
|
195
197
|
}
|
|
196
198
|
catch (err) {
|
|
197
|
-
warnTraceSpanFailure('completeNode', { type: 'skill', name:
|
|
199
|
+
warnTraceSpanFailure('completeNode', { type: 'skill', name: spanName, traceId, spanId: skillSpanId }, err);
|
|
198
200
|
}
|
|
199
201
|
}
|
|
200
202
|
// 4. 只回写子图本步新增消息(含内部 tool 回合),禁止把入口历史再 append
|
|
@@ -269,7 +271,7 @@ export class SubGraphCompiler {
|
|
|
269
271
|
});
|
|
270
272
|
}
|
|
271
273
|
catch (completeErr) {
|
|
272
|
-
warnTraceSpanFailure('completeNode', { type: 'skill', name:
|
|
274
|
+
warnTraceSpanFailure('completeNode', { type: 'skill', name: spanName, traceId, spanId: skillSpanId }, completeErr);
|
|
273
275
|
}
|
|
274
276
|
}
|
|
275
277
|
adapter.emitStreamEvent({
|
|
@@ -181,6 +181,8 @@ export interface GraphState {
|
|
|
181
181
|
agentId?: string;
|
|
182
182
|
/** Agent 对外主键 */
|
|
183
183
|
agentCode?: string;
|
|
184
|
+
/** Agent 展示名(manifest.name);身份段对用户说话用,缺省回退 agentCode */
|
|
185
|
+
agentName?: string;
|
|
184
186
|
/** Hosting 路由选定的预装版本(AR-3b;写入 Checkpoint 供 HITL/Fork 恢复) */
|
|
185
187
|
agentVersion?: string;
|
|
186
188
|
correlationId?: string;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 可选图胶水:把 silent LLM 的结构化输出写成 skillRoute / activatedSkill。
|
|
3
3
|
* 不是 Graph 节点类型。技能正文走短目录 + read_file,不灌 system。
|
|
4
4
|
*/
|
|
5
|
-
import type
|
|
5
|
+
import { type LoadedSkillInfo, type LoadedSkillMap } from '../../tool/system-prompt-builder.js';
|
|
6
6
|
export type SkillRoute = 'skill' | 'clarify' | 'none';
|
|
7
7
|
export interface SkillBindPatch {
|
|
8
8
|
skillRoute: SkillRoute;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 可选图胶水:把 silent LLM 的结构化输出写成 skillRoute / activatedSkill。
|
|
3
|
+
* 不是 Graph 节点类型。技能正文走短目录 + read_file,不灌 system。
|
|
4
|
+
*/
|
|
5
|
+
import { spokenName } from '../../tool/system-prompt-builder.js';
|
|
1
6
|
function lastAssistantText(messages) {
|
|
2
7
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
3
8
|
const msg = messages[i];
|
|
@@ -89,7 +94,7 @@ export function bindSelectedSkill(state) {
|
|
|
89
94
|
return {
|
|
90
95
|
skillRoute: 'skill',
|
|
91
96
|
activatedSkill: skill.skillId,
|
|
92
|
-
skillName: skill.name
|
|
97
|
+
skillName: spokenName(skill.name, skill.skillId),
|
|
93
98
|
skillInput: params,
|
|
94
99
|
messages: nextMessages(),
|
|
95
100
|
};
|
|
@@ -20,8 +20,13 @@ export interface LoadAgentOptions {
|
|
|
20
20
|
export declare function resolveAgentSystemPromptFromLoader(loader: {
|
|
21
21
|
resolveAgentSystemPrompt?: (agentCode: string, version?: string) => Promise<string | undefined>;
|
|
22
22
|
} | undefined, agentCode: string, version?: string): Promise<string | undefined>;
|
|
23
|
+
export declare function resolveAgentDisplayNameFromLoader(loader: {
|
|
24
|
+
resolveAgentDisplayName?: (agentCode: string, version?: string) => Promise<string | undefined>;
|
|
25
|
+
} | undefined, agentCode: string, version?: string): Promise<string | undefined>;
|
|
23
26
|
/** manifest.prompts.system;空白视为缺省。 */
|
|
24
27
|
export declare function extractAgentSystemPrompt(manifest: unknown): string | undefined;
|
|
28
|
+
/** manifest.name;空白视为缺省。身份段对用户说话用,不当路由键。 */
|
|
29
|
+
export declare function extractAgentDisplayName(manifest: unknown): string | undefined;
|
|
25
30
|
export interface GraphLoaderConfig {
|
|
26
31
|
registryClient?: AgentRegistryClient;
|
|
27
32
|
deploymentContext?: DeploymentContext;
|
|
@@ -116,6 +121,12 @@ export declare class GraphLoader {
|
|
|
116
121
|
* 每轮 execute/stream 注入 GraphState.agentSystemPrompt;不写进节点 config。
|
|
117
122
|
*/
|
|
118
123
|
resolveAgentSystemPrompt(agentCode: string, version?: string): Promise<string | undefined>;
|
|
124
|
+
/**
|
|
125
|
+
* Agent 展示名(manifest.name)。
|
|
126
|
+
* 每轮 execute/stream 注入 GraphState.agentName;身份段对用户说话用。
|
|
127
|
+
*/
|
|
128
|
+
resolveAgentDisplayName(agentCode: string, version?: string): Promise<string | undefined>;
|
|
129
|
+
private fromAgentManifest;
|
|
119
130
|
/**
|
|
120
131
|
* 解析 agent tools[] + graph tool 节点 union;
|
|
121
132
|
* server+预装:以预装 manifest 为准;desktop 合并 ILocalToolInstallStore。
|
|
@@ -64,6 +64,11 @@ export async function resolveAgentSystemPromptFromLoader(loader, agentCode, vers
|
|
|
64
64
|
return undefined;
|
|
65
65
|
return loader.resolveAgentSystemPrompt(agentCode, version);
|
|
66
66
|
}
|
|
67
|
+
export async function resolveAgentDisplayNameFromLoader(loader, agentCode, version) {
|
|
68
|
+
if (!loader || typeof loader.resolveAgentDisplayName !== 'function')
|
|
69
|
+
return undefined;
|
|
70
|
+
return loader.resolveAgentDisplayName(agentCode, version);
|
|
71
|
+
}
|
|
67
72
|
/** manifest.prompts.system;空白视为缺省。 */
|
|
68
73
|
export function extractAgentSystemPrompt(manifest) {
|
|
69
74
|
if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest))
|
|
@@ -77,6 +82,16 @@ export function extractAgentSystemPrompt(manifest) {
|
|
|
77
82
|
const trimmed = system.trim();
|
|
78
83
|
return trimmed ? trimmed : undefined;
|
|
79
84
|
}
|
|
85
|
+
/** manifest.name;空白视为缺省。身份段对用户说话用,不当路由键。 */
|
|
86
|
+
export function extractAgentDisplayName(manifest) {
|
|
87
|
+
if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest))
|
|
88
|
+
return undefined;
|
|
89
|
+
const name = manifest.name;
|
|
90
|
+
if (typeof name !== 'string')
|
|
91
|
+
return undefined;
|
|
92
|
+
const trimmed = name.trim();
|
|
93
|
+
return trimmed ? trimmed : undefined;
|
|
94
|
+
}
|
|
80
95
|
function extractSkillPrompt(manifest) {
|
|
81
96
|
const prompt = manifest.prompt;
|
|
82
97
|
if (typeof prompt === 'string' && prompt.trim())
|
|
@@ -769,18 +784,27 @@ export class GraphLoader {
|
|
|
769
784
|
* 每轮 execute/stream 注入 GraphState.agentSystemPrompt;不写进节点 config。
|
|
770
785
|
*/
|
|
771
786
|
async resolveAgentSystemPrompt(agentCode, version) {
|
|
787
|
+
return this.fromAgentManifest(agentCode, version, extractAgentSystemPrompt);
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Agent 展示名(manifest.name)。
|
|
791
|
+
* 每轮 execute/stream 注入 GraphState.agentName;身份段对用户说话用。
|
|
792
|
+
*/
|
|
793
|
+
async resolveAgentDisplayName(agentCode, version) {
|
|
794
|
+
return this.fromAgentManifest(agentCode, version, extractAgentDisplayName);
|
|
795
|
+
}
|
|
796
|
+
async fromAgentManifest(agentCode, version, extract) {
|
|
772
797
|
if (this.deploymentSnapshot) {
|
|
773
798
|
const snap = await this.deploymentSnapshot.loadAgentSnapshot(agentCode, version);
|
|
774
|
-
if (snap)
|
|
775
|
-
return
|
|
776
|
-
}
|
|
799
|
+
if (snap)
|
|
800
|
+
return extract(snap.manifest);
|
|
777
801
|
if (this.blockRegistryDefinitions)
|
|
778
802
|
return undefined;
|
|
779
803
|
}
|
|
780
804
|
if (this.blockRegistryDefinitions || !this.registryClient)
|
|
781
805
|
return undefined;
|
|
782
806
|
const record = await this.registryClient.getAgent(agentCode);
|
|
783
|
-
return
|
|
807
|
+
return extract(record?.manifest);
|
|
784
808
|
}
|
|
785
809
|
/**
|
|
786
810
|
* 解析 agent tools[] + graph tool 节点 union;
|
|
@@ -11,7 +11,7 @@ import { DEFAULT_GRAPH_TIMEOUT_MS } from '../common/types.js';
|
|
|
11
11
|
import { resolveTaskTimeoutMs } from '../task/resolve-task-timeout.js';
|
|
12
12
|
import { runWithExecutionTrace } from '../graph/execution-trace-context.js';
|
|
13
13
|
import { HITL_TIMEOUT_ERROR_CODE, HITL_TIMEOUT_MESSAGE, HitlAlreadyTimedOutError, HitlNotWaitingError, buildHitlWaitedPayload, isHitlDeadlinePassed, loadHitlCheckpoint, readPersistedHitlWaiting, unwrapHitlPaused, } from '../graph/hitl/hitl-handler.js';
|
|
14
|
-
import { resolveAgentSystemPromptFromLoader } from '../registry/graph-loader.js';
|
|
14
|
+
import { resolveAgentDisplayNameFromLoader, resolveAgentSystemPromptFromLoader, } from '../registry/graph-loader.js';
|
|
15
15
|
import { toLoadedSkillMap } from '../tool/system-prompt-builder.js';
|
|
16
16
|
import { assembleLoadedTools } from '../tool/harness-primitives.js';
|
|
17
17
|
import { createFileLlmTurnLogFromEnv, } from '../debug/llm-turn-log.js';
|
|
@@ -330,6 +330,7 @@ export class AgentRuntime {
|
|
|
330
330
|
? (await this.deps.graphLoader.resolveAgentDir(agentCode, params.agentVersion)) ?? undefined
|
|
331
331
|
: undefined;
|
|
332
332
|
const agentSystemPrompt = await resolveAgentSystemPromptFromLoader(this.deps.graphLoader, agentCode, params.agentVersion);
|
|
333
|
+
const agentName = await resolveAgentDisplayNameFromLoader(this.deps.graphLoader, agentCode, params.agentVersion);
|
|
333
334
|
const facing = await loadModelFacingHistory({
|
|
334
335
|
sessionHistory: messageRecordsToGraphMessages(sessionContext.messages),
|
|
335
336
|
checkpointSaver: this.deps.checkpointSaver,
|
|
@@ -402,6 +403,7 @@ export class AgentRuntime {
|
|
|
402
403
|
promptRoots,
|
|
403
404
|
agentDir,
|
|
404
405
|
agentSystemPrompt,
|
|
406
|
+
agentName,
|
|
405
407
|
skillInput: resolveSkillInputFromInvokeInput(params.input),
|
|
406
408
|
traceId: resolveTraceId(params),
|
|
407
409
|
traceCollector: this.deps.traceCollector,
|
|
@@ -617,6 +619,9 @@ export class AgentRuntime {
|
|
|
617
619
|
agentSystemPrompt: (await resolveAgentSystemPromptFromLoader(this.deps.graphLoader, agentCode, agentVersion)) ?? (typeof resumedState.agentSystemPrompt === 'string'
|
|
618
620
|
? resumedState.agentSystemPrompt
|
|
619
621
|
: undefined),
|
|
622
|
+
agentName: (await resolveAgentDisplayNameFromLoader(this.deps.graphLoader, agentCode, agentVersion)) ?? (typeof resumedState.agentName === 'string' && resumedState.agentName.trim()
|
|
623
|
+
? resumedState.agentName.trim()
|
|
624
|
+
: undefined),
|
|
620
625
|
activatedSkill: resumedState.activatedSkill,
|
|
621
626
|
skillRoute: resumedState.skillRoute ??
|
|
622
627
|
(typeof resumedState.activatedSkill === 'string' && resumedState.activatedSkill
|
|
@@ -814,6 +819,9 @@ export class AgentRuntime {
|
|
|
814
819
|
const agentSystemPrompt = (await resolveAgentSystemPromptFromLoader(this.deps.graphLoader, agentCode, agentVersion)) ?? (typeof forkedCheckpoint.state.agentSystemPrompt === 'string'
|
|
815
820
|
? forkedCheckpoint.state.agentSystemPrompt
|
|
816
821
|
: undefined);
|
|
822
|
+
const agentName = (await resolveAgentDisplayNameFromLoader(this.deps.graphLoader, agentCode, agentVersion)) ?? (typeof forkedCheckpoint.state.agentName === 'string' && forkedCheckpoint.state.agentName.trim()
|
|
823
|
+
? forkedCheckpoint.state.agentName.trim()
|
|
824
|
+
: undefined);
|
|
817
825
|
const abortDeadlineMs = Date.now() + timeout;
|
|
818
826
|
try {
|
|
819
827
|
const forkState = { ...forkedCheckpoint.state };
|
|
@@ -827,6 +835,7 @@ export class AgentRuntime {
|
|
|
827
835
|
agentVersion,
|
|
828
836
|
agentDir,
|
|
829
837
|
agentSystemPrompt,
|
|
838
|
+
agentName,
|
|
830
839
|
userId,
|
|
831
840
|
delegationToken: overrides.executionContext?.delegationToken,
|
|
832
841
|
executionContext: overrides.executionContext,
|
package/dist/tool/index.d.ts
CHANGED
|
@@ -22,4 +22,4 @@ export { expandSkillScriptRefs, isSkillEntryFile, EAP_SKILL_DIR_ENV, } from './s
|
|
|
22
22
|
export { ToolResultInjector, type ToolMessage, } from './tool-result-injector.js';
|
|
23
23
|
export { ToolEventEmitter } from './tool-event-emitter.js';
|
|
24
24
|
export { ToolConfirmationInterceptor } from './tool-confirmation.js';
|
|
25
|
-
export { SystemPromptBuilder, naturalTimeWindows, loadedToolsToApiTools, toLoadedSkillMap, filterLoadedToolsForSkill, type PromptBuildContext, type PromptSection, type AssembledSystemPrompt, type ApiToolDefinition, type LoadedSkillInfo, type LoadedSkillMap, } from './system-prompt-builder.js';
|
|
25
|
+
export { SystemPromptBuilder, naturalTimeWindows, buildSkillCatalog, buildToolCatalog, catalogEntryTitle, spokenName, loadedToolsToApiTools, toLoadedSkillMap, filterLoadedToolsForSkill, type PromptBuildContext, type PromptSection, type AssembledSystemPrompt, type ApiToolDefinition, type LoadedSkillInfo, type LoadedSkillMap, } from './system-prompt-builder.js';
|
package/dist/tool/index.js
CHANGED
|
@@ -21,4 +21,4 @@ export { expandSkillScriptRefs, isSkillEntryFile, EAP_SKILL_DIR_ENV, } from './s
|
|
|
21
21
|
export { ToolResultInjector, } from './tool-result-injector.js';
|
|
22
22
|
export { ToolEventEmitter } from './tool-event-emitter.js';
|
|
23
23
|
export { ToolConfirmationInterceptor } from './tool-confirmation.js';
|
|
24
|
-
export { SystemPromptBuilder, naturalTimeWindows, loadedToolsToApiTools, toLoadedSkillMap, filterLoadedToolsForSkill, } from './system-prompt-builder.js';
|
|
24
|
+
export { SystemPromptBuilder, naturalTimeWindows, buildSkillCatalog, buildToolCatalog, catalogEntryTitle, spokenName, loadedToolsToApiTools, toLoadedSkillMap, filterLoadedToolsForSkill, } from './system-prompt-builder.js';
|
package/dist/tool/mcp-list.d.ts
CHANGED
|
@@ -53,17 +53,19 @@ export declare function mcpToolsetCode(loaded: {
|
|
|
53
53
|
execution?: unknown;
|
|
54
54
|
};
|
|
55
55
|
} | undefined): string | undefined;
|
|
56
|
-
/** Tool Span:工具集 code +
|
|
56
|
+
/** Tool Span:工具集 code + 声明版本 + 展示名(与函数名不同才写)。 */
|
|
57
57
|
export declare function toolTraceIdentity(loaded: {
|
|
58
58
|
toolId?: string;
|
|
59
59
|
name?: string;
|
|
60
60
|
manifest?: {
|
|
61
61
|
id?: string;
|
|
62
|
+
name?: string;
|
|
62
63
|
version?: string;
|
|
63
64
|
};
|
|
64
65
|
} | undefined, toolName: string): {
|
|
65
66
|
toolset?: string;
|
|
66
67
|
toolVersion?: string;
|
|
68
|
+
toolDisplayName?: string;
|
|
67
69
|
};
|
|
68
70
|
export interface HydrateMcpToolsAuth {
|
|
69
71
|
authContext: AuthContext;
|
package/dist/tool/mcp-list.js
CHANGED
|
@@ -130,13 +130,16 @@ function declaredToolVersion(toolName, version) {
|
|
|
130
130
|
return undefined;
|
|
131
131
|
return raw;
|
|
132
132
|
}
|
|
133
|
-
/** Tool Span:工具集 code +
|
|
133
|
+
/** Tool Span:工具集 code + 声明版本 + 展示名(与函数名不同才写)。 */
|
|
134
134
|
export function toolTraceIdentity(loaded, toolName) {
|
|
135
135
|
const toolset = toolsetCodeFromLoaded(loaded);
|
|
136
136
|
const toolVersion = declaredToolVersion(toolName, loaded?.manifest?.version);
|
|
137
|
+
const display = loaded?.manifest?.name?.trim();
|
|
138
|
+
const toolDisplayName = display && display !== toolName ? display : undefined;
|
|
137
139
|
return {
|
|
138
140
|
...(toolset ? { toolset } : {}),
|
|
139
141
|
...(toolVersion ? { toolVersion } : {}),
|
|
142
|
+
...(toolDisplayName ? { toolDisplayName } : {}),
|
|
140
143
|
};
|
|
141
144
|
}
|
|
142
145
|
/**
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* ```
|
|
8
8
|
* [平台规则常量] ← 代码内置,安全约束 + 行为准则(最高优先级)
|
|
9
9
|
* [当前时间] ← 运行时动态注入(自然周等时间规则的判定基准)
|
|
10
|
-
* [Agent 身份] ← agentName
|
|
11
|
-
* [可用工具短目录] ←
|
|
10
|
+
* [Agent 身份] ← 展示名 agentName,缺省 agentCode(对用户说话,不是路由键)
|
|
11
|
+
* [可用工具短目录] ← 展示名 + 调用名 + 一句话用途;完整 schema 仍走 API tools
|
|
12
12
|
* [Agent 基线] ← agent.manifest.json prompts.system;非 silent LLM
|
|
13
13
|
* [节点提示词] ← Graph LLM 节点 config.systemPrompt / systemPromptFile
|
|
14
14
|
* ```
|
|
@@ -109,6 +109,10 @@ export interface AssembledSystemPrompt {
|
|
|
109
109
|
text: string;
|
|
110
110
|
sections: PromptSection[];
|
|
111
111
|
}
|
|
112
|
+
/** 对人展示的名称。有展示名用展示名,否则用编码。 */
|
|
113
|
+
export declare function spokenName(displayName: string | undefined, code: string | undefined): string | undefined;
|
|
114
|
+
/** 短目录标题:展示名在前,调用键在行内。名称与编码相同则只写编码。 */
|
|
115
|
+
export declare function catalogEntryTitle(code: string, displayName: string | undefined, codePhrase: string): string;
|
|
112
116
|
/**
|
|
113
117
|
* 非 silent LLM 才带 Agent 基线;节点提示词空则省略。
|
|
114
118
|
* silent 只保留节点增量(选技能 / JSON)。
|
|
@@ -166,4 +170,6 @@ export type ApiToolDefinition = LLMToolDefinition;
|
|
|
166
170
|
*/
|
|
167
171
|
/** 名称 + 一句话用途,供 system「可用工具」段。schema 仍走 loadedToolsToApiTools。 */
|
|
168
172
|
export declare function buildToolCatalog(loadedTools: LoadedToolMap | undefined): string | undefined;
|
|
173
|
+
/** 展示名 + skillId,供 system「可用技能」段。read_file 仍用 skillId。 */
|
|
174
|
+
export declare function buildSkillCatalog(defs: LoadedSkillMap | undefined): string | undefined;
|
|
169
175
|
export declare function loadedToolsToApiTools(loadedTools: LoadedToolMap | undefined, skillTools?: string[]): ApiToolDefinition[];
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* ```
|
|
8
8
|
* [平台规则常量] ← 代码内置,安全约束 + 行为准则(最高优先级)
|
|
9
9
|
* [当前时间] ← 运行时动态注入(自然周等时间规则的判定基准)
|
|
10
|
-
* [Agent 身份] ← agentName
|
|
11
|
-
* [可用工具短目录] ←
|
|
10
|
+
* [Agent 身份] ← 展示名 agentName,缺省 agentCode(对用户说话,不是路由键)
|
|
11
|
+
* [可用工具短目录] ← 展示名 + 调用名 + 一句话用途;完整 schema 仍走 API tools
|
|
12
12
|
* [Agent 基线] ← agent.manifest.json prompts.system;非 silent LLM
|
|
13
13
|
* [节点提示词] ← Graph LLM 节点 config.systemPrompt / systemPromptFile
|
|
14
14
|
* ```
|
|
@@ -86,6 +86,22 @@ function trimPrompt(value) {
|
|
|
86
86
|
const trimmed = value.trim();
|
|
87
87
|
return trimmed ? trimmed : undefined;
|
|
88
88
|
}
|
|
89
|
+
/** 对人展示的名称。有展示名用展示名,否则用编码。 */
|
|
90
|
+
export function spokenName(displayName, code) {
|
|
91
|
+
const name = displayName?.trim();
|
|
92
|
+
if (name)
|
|
93
|
+
return name;
|
|
94
|
+
const id = code?.trim();
|
|
95
|
+
return id || undefined;
|
|
96
|
+
}
|
|
97
|
+
/** 短目录标题:展示名在前,调用键在行内。名称与编码相同则只写编码。 */
|
|
98
|
+
export function catalogEntryTitle(code, displayName, codePhrase) {
|
|
99
|
+
const id = code.trim();
|
|
100
|
+
const name = displayName?.trim();
|
|
101
|
+
if (name && name !== id)
|
|
102
|
+
return `**${name}**(${codePhrase})`;
|
|
103
|
+
return `**${id}**`;
|
|
104
|
+
}
|
|
89
105
|
/**
|
|
90
106
|
* 非 silent LLM 才带 Agent 基线;节点提示词空则省略。
|
|
91
107
|
* silent 只保留节点增量(选技能 / JSON)。
|
|
@@ -154,7 +170,7 @@ export class SystemPromptBuilder {
|
|
|
154
170
|
return lines.join('\n');
|
|
155
171
|
}
|
|
156
172
|
buildAgentIdentity(context) {
|
|
157
|
-
const name = context.agentName
|
|
173
|
+
const name = spokenName(context.agentName, context.agentCode);
|
|
158
174
|
return name ? `## Agent 身份\n你的名称是「${name}」。` : '';
|
|
159
175
|
}
|
|
160
176
|
buildJail(context) {
|
|
@@ -262,11 +278,8 @@ export function buildToolCatalog(loadedTools) {
|
|
|
262
278
|
return undefined;
|
|
263
279
|
const rows = Object.values(loadedTools).map((tool) => {
|
|
264
280
|
const desc = (tool.manifest.description ?? '').replace(/\s+/g, ' ').trim();
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
? `${tool.name}(${displayName})`
|
|
268
|
-
: tool.name;
|
|
269
|
-
return `- **${title}**${desc ? `:${desc}` : ''}`;
|
|
281
|
+
const title = catalogEntryTitle(tool.name, tool.manifest.name, `调用名 ${tool.name}`);
|
|
282
|
+
return `- ${title}${desc ? `:${desc}` : ''}`;
|
|
270
283
|
});
|
|
271
284
|
if (rows.length === 0)
|
|
272
285
|
return undefined;
|
|
@@ -276,6 +289,21 @@ export function buildToolCatalog(loadedTools) {
|
|
|
276
289
|
rows.join('\n'),
|
|
277
290
|
].join('\n');
|
|
278
291
|
}
|
|
292
|
+
/** 展示名 + skillId,供 system「可用技能」段。read_file 仍用 skillId。 */
|
|
293
|
+
export function buildSkillCatalog(defs) {
|
|
294
|
+
if (!defs)
|
|
295
|
+
return undefined;
|
|
296
|
+
const rows = Object.values(defs).map((skill) => {
|
|
297
|
+
const desc = (skill.description ?? '').replace(/\s+/g, ' ').trim();
|
|
298
|
+
const entry = skill.entryFile ?? (skill.bundlePath ? `${skill.bundlePath}/SKILL.md` : '');
|
|
299
|
+
const title = catalogEntryTitle(skill.skillId, skill.name, `skillId ${skill.skillId}`);
|
|
300
|
+
const pathLine = entry ? `\n SKILL.md: ${entry}` : '';
|
|
301
|
+
return `- ${title}${desc ? `:${desc}` : ''}${pathLine}`;
|
|
302
|
+
});
|
|
303
|
+
if (rows.length === 0)
|
|
304
|
+
return undefined;
|
|
305
|
+
return `# 可用技能\n要用某个技能时,调用 read_file 读取其 SKILL.md。脚本和参考文档默认在同一目录。\n${rows.join('\n')}`;
|
|
306
|
+
}
|
|
279
307
|
export function loadedToolsToApiTools(loadedTools, skillTools) {
|
|
280
308
|
if (!loadedTools)
|
|
281
309
|
return [];
|