@ai-setting/roy-agent-core 1.5.41 → 1.5.42
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/config/index.js +1 -1
- package/dist/env/agent/index.js +3 -1
- package/dist/env/index.js +11 -10
- package/dist/env/mcp/index.js +1 -1
- package/dist/env/prompt/index.js +2 -1
- package/dist/env/task/delegate/index.js +3 -1
- package/dist/env/task/index.js +4 -2
- package/dist/env/workflow/index.js +1 -1
- package/dist/index.js +22 -12
- package/dist/shared/@ai-setting/roy-agent-core-7t05apnp.js +287 -0
- package/dist/shared/@ai-setting/{roy-agent-core-15x8fe5h.js → roy-agent-core-9q6sa7m3.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-yc543gnq.js → roy-agent-core-bmr6bdfb.js} +4 -0
- package/dist/shared/@ai-setting/{roy-agent-core-c8f2hync.js → roy-agent-core-ek6gk3wk.js} +62 -0
- package/dist/shared/@ai-setting/{roy-agent-core-frx4p6d1.js → roy-agent-core-nj8yerg9.js} +8 -0
- package/dist/shared/@ai-setting/{roy-agent-core-ycg9rk6z.js → roy-agent-core-xkb264a8.js} +18 -3
- package/dist/shared/@ai-setting/{roy-agent-core-v53rfk99.js → roy-agent-core-xz22rmak.js} +104 -36
- package/dist/shared/@ai-setting/{roy-agent-core-wb43x8hd.js → roy-agent-core-z1xf2fdk.js} +188 -25
- package/package.json +1 -1
package/dist/config/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
parseJSONCWithProtocols,
|
|
11
11
|
substituteEnvVars,
|
|
12
12
|
substituteProtocolRefs
|
|
13
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
13
|
+
} from "../shared/@ai-setting/roy-agent-core-nj8yerg9.js";
|
|
14
14
|
import"../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
15
15
|
import"../shared/@ai-setting/roy-agent-core-qxhq8ven.js";
|
|
16
16
|
import"../shared/@ai-setting/roy-agent-core-4jqq077c.js";
|
package/dist/env/agent/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentComponent,
|
|
3
3
|
AgentComponentConfigSchema
|
|
4
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
4
|
+
} from "../../shared/@ai-setting/roy-agent-core-ek6gk3wk.js";
|
|
5
5
|
import"../../shared/@ai-setting/roy-agent-core-e25xkv53.js";
|
|
6
|
+
import"../../shared/@ai-setting/roy-agent-core-7t05apnp.js";
|
|
7
|
+
import"../../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
6
8
|
import"../../shared/@ai-setting/roy-agent-core-ctdhjv68.js";
|
|
7
9
|
import {
|
|
8
10
|
SummaryAgent
|
package/dist/env/index.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BaseEnvironment
|
|
3
3
|
} from "../shared/@ai-setting/roy-agent-core-ee6nnnqw.js";
|
|
4
|
-
import {
|
|
5
|
-
XDG_PATHS,
|
|
6
|
-
getXDGPath,
|
|
7
|
-
getXDGPaths
|
|
8
|
-
} from "../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
9
4
|
import {
|
|
10
5
|
EventSourceComponent,
|
|
11
6
|
builtInHandlers,
|
|
@@ -26,7 +21,7 @@ import"../shared/@ai-setting/roy-agent-core-e9fdm13a.js";
|
|
|
26
21
|
import"../shared/@ai-setting/roy-agent-core-az13yzmc.js";
|
|
27
22
|
import {
|
|
28
23
|
WorkflowComponent
|
|
29
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
24
|
+
} from "../shared/@ai-setting/roy-agent-core-bmr6bdfb.js";
|
|
30
25
|
import"../shared/@ai-setting/roy-agent-core-0rtxwr28.js";
|
|
31
26
|
import"../shared/@ai-setting/roy-agent-core-2jnzv9at.js";
|
|
32
27
|
import"../shared/@ai-setting/roy-agent-core-69jskqjg.js";
|
|
@@ -39,20 +34,26 @@ import"../shared/@ai-setting/roy-agent-core-1ce3fqrk.js";
|
|
|
39
34
|
import {
|
|
40
35
|
AgentComponent,
|
|
41
36
|
AgentComponentConfigSchema
|
|
42
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
37
|
+
} from "../shared/@ai-setting/roy-agent-core-ek6gk3wk.js";
|
|
43
38
|
import"../shared/@ai-setting/roy-agent-core-e25xkv53.js";
|
|
44
39
|
import {
|
|
45
40
|
TaskComponent
|
|
46
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
47
|
-
import"../shared/@ai-setting/roy-agent-core-
|
|
41
|
+
} from "../shared/@ai-setting/roy-agent-core-9q6sa7m3.js";
|
|
42
|
+
import"../shared/@ai-setting/roy-agent-core-xz22rmak.js";
|
|
48
43
|
import"../shared/@ai-setting/roy-agent-core-hsxn8m1j.js";
|
|
44
|
+
import"../shared/@ai-setting/roy-agent-core-7t05apnp.js";
|
|
45
|
+
import {
|
|
46
|
+
XDG_PATHS,
|
|
47
|
+
getXDGPath,
|
|
48
|
+
getXDGPaths
|
|
49
|
+
} from "../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
49
50
|
import"../shared/@ai-setting/roy-agent-core-wa1kzqky.js";
|
|
50
51
|
import"../shared/@ai-setting/roy-agent-core-t94ktchq.js";
|
|
51
52
|
import"../shared/@ai-setting/roy-agent-core-92z6t4he.js";
|
|
52
53
|
import"../shared/@ai-setting/roy-agent-core-8gxth0eh.js";
|
|
53
54
|
import {
|
|
54
55
|
McpComponent
|
|
55
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
56
|
+
} from "../shared/@ai-setting/roy-agent-core-xkb264a8.js";
|
|
56
57
|
import"../shared/@ai-setting/roy-agent-core-ctdhjv68.js";
|
|
57
58
|
import"../shared/@ai-setting/roy-agent-core-1bfmxx89.js";
|
|
58
59
|
import"../shared/@ai-setting/roy-agent-core-kwhv9dcd.js";
|
package/dist/env/mcp/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
McpServerLocalConfigSchema,
|
|
9
9
|
McpServerRemoteConfigSchema,
|
|
10
10
|
getMcpPathPriority
|
|
11
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
11
|
+
} from "../../shared/@ai-setting/roy-agent-core-xkb264a8.js";
|
|
12
12
|
import"../../shared/@ai-setting/roy-agent-core-ctdhjv68.js";
|
|
13
13
|
import {
|
|
14
14
|
adaptMcpTool,
|
package/dist/env/prompt/index.js
CHANGED
|
@@ -3,7 +3,8 @@ import {
|
|
|
3
3
|
PromptConfigSchema,
|
|
4
4
|
PromptPathSchema,
|
|
5
5
|
PromptRenderer
|
|
6
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
6
|
+
} from "../../shared/@ai-setting/roy-agent-core-z1xf2fdk.js";
|
|
7
|
+
import"../../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
7
8
|
import"../../shared/@ai-setting/roy-agent-core-qxhq8ven.js";
|
|
8
9
|
import"../../shared/@ai-setting/roy-agent-core-4jqq077c.js";
|
|
9
10
|
import"../../shared/@ai-setting/roy-agent-core-2dhd60aw.js";
|
|
@@ -3,7 +3,9 @@ import {
|
|
|
3
3
|
BackgroundTaskManager,
|
|
4
4
|
createDelegateTool,
|
|
5
5
|
createStopTool
|
|
6
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
6
|
+
} from "../../../shared/@ai-setting/roy-agent-core-xz22rmak.js";
|
|
7
|
+
import"../../../shared/@ai-setting/roy-agent-core-7t05apnp.js";
|
|
8
|
+
import"../../../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
7
9
|
import"../../../shared/@ai-setting/roy-agent-core-92z6t4he.js";
|
|
8
10
|
import"../../../shared/@ai-setting/roy-agent-core-jqy2mdyq.js";
|
|
9
11
|
import"../../../shared/@ai-setting/roy-agent-core-z33en0cz.js";
|
package/dist/env/task/index.js
CHANGED
|
@@ -4,11 +4,13 @@ import {
|
|
|
4
4
|
TaskConfigSchema,
|
|
5
5
|
TaskPriorityEnum,
|
|
6
6
|
TaskStatusEnum
|
|
7
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
8
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
7
|
+
} from "../../shared/@ai-setting/roy-agent-core-9q6sa7m3.js";
|
|
8
|
+
import"../../shared/@ai-setting/roy-agent-core-xz22rmak.js";
|
|
9
9
|
import {
|
|
10
10
|
SQLiteTaskStore
|
|
11
11
|
} from "../../shared/@ai-setting/roy-agent-core-hsxn8m1j.js";
|
|
12
|
+
import"../../shared/@ai-setting/roy-agent-core-7t05apnp.js";
|
|
13
|
+
import"../../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
12
14
|
import"../../shared/@ai-setting/roy-agent-core-wa1kzqky.js";
|
|
13
15
|
import"../../shared/@ai-setting/roy-agent-core-t94ktchq.js";
|
|
14
16
|
import"../../shared/@ai-setting/roy-agent-core-92z6t4he.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
WorkflowComponent
|
|
3
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
3
|
+
} from "../../shared/@ai-setting/roy-agent-core-bmr6bdfb.js";
|
|
4
4
|
import"../../shared/@ai-setting/roy-agent-core-0rtxwr28.js";
|
|
5
5
|
import"../../shared/@ai-setting/roy-agent-core-2jnzv9at.js";
|
|
6
6
|
import"../../shared/@ai-setting/roy-agent-core-69jskqjg.js";
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "./shared/@ai-setting/roy-agent-core-kajktp3d.js";
|
|
13
13
|
import {
|
|
14
14
|
ConfigComponent
|
|
15
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
15
|
+
} from "./shared/@ai-setting/roy-agent-core-nj8yerg9.js";
|
|
16
16
|
import {
|
|
17
17
|
CommandsComponent
|
|
18
18
|
} from "./shared/@ai-setting/roy-agent-core-b4wd9tn6.js";
|
|
@@ -33,9 +33,13 @@ import {
|
|
|
33
33
|
} from "./shared/@ai-setting/roy-agent-core-rsybkb38.js";
|
|
34
34
|
import {
|
|
35
35
|
PromptComponent,
|
|
36
|
+
PromptStore,
|
|
36
37
|
getBuiltInPrompt,
|
|
37
38
|
getBuiltInPromptNames
|
|
38
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
39
|
+
} from "./shared/@ai-setting/roy-agent-core-z1xf2fdk.js";
|
|
40
|
+
import {
|
|
41
|
+
closeDatabase
|
|
42
|
+
} from "./shared/@ai-setting/roy-agent-core-9ffsvvcf.js";
|
|
39
43
|
import"./shared/@ai-setting/roy-agent-core-2grcjaad.js";
|
|
40
44
|
import {
|
|
41
45
|
MemoryComponent
|
|
@@ -58,11 +62,6 @@ import {
|
|
|
58
62
|
generateDescendingId,
|
|
59
63
|
generateId
|
|
60
64
|
} from "./shared/@ai-setting/roy-agent-core-ee6nnnqw.js";
|
|
61
|
-
import {
|
|
62
|
-
XDG_PATHS,
|
|
63
|
-
getXDGPath,
|
|
64
|
-
getXDGPaths
|
|
65
|
-
} from "./shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
66
65
|
import {
|
|
67
66
|
EventSourceComponent,
|
|
68
67
|
builtInHandlers,
|
|
@@ -93,7 +92,7 @@ import {
|
|
|
93
92
|
} from "./shared/@ai-setting/roy-agent-core-az13yzmc.js";
|
|
94
93
|
import {
|
|
95
94
|
WorkflowComponent
|
|
96
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
95
|
+
} from "./shared/@ai-setting/roy-agent-core-bmr6bdfb.js";
|
|
97
96
|
import {
|
|
98
97
|
init_node_registry_helper,
|
|
99
98
|
registerDecoratorNodeType
|
|
@@ -115,16 +114,24 @@ import"./shared/@ai-setting/roy-agent-core-1ce3fqrk.js";
|
|
|
115
114
|
import {
|
|
116
115
|
AgentComponent,
|
|
117
116
|
AgentComponentConfigSchema
|
|
118
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
117
|
+
} from "./shared/@ai-setting/roy-agent-core-ek6gk3wk.js";
|
|
119
118
|
import {
|
|
120
119
|
AskUserError,
|
|
121
120
|
init_workflow_hil
|
|
122
121
|
} from "./shared/@ai-setting/roy-agent-core-e25xkv53.js";
|
|
123
122
|
import {
|
|
124
123
|
TaskComponent
|
|
125
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
126
|
-
import"./shared/@ai-setting/roy-agent-core-
|
|
124
|
+
} from "./shared/@ai-setting/roy-agent-core-9q6sa7m3.js";
|
|
125
|
+
import"./shared/@ai-setting/roy-agent-core-xz22rmak.js";
|
|
127
126
|
import"./shared/@ai-setting/roy-agent-core-hsxn8m1j.js";
|
|
127
|
+
import {
|
|
128
|
+
AgentRegistry
|
|
129
|
+
} from "./shared/@ai-setting/roy-agent-core-7t05apnp.js";
|
|
130
|
+
import {
|
|
131
|
+
XDG_PATHS,
|
|
132
|
+
getXDGPath,
|
|
133
|
+
getXDGPaths
|
|
134
|
+
} from "./shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
128
135
|
import"./shared/@ai-setting/roy-agent-core-wa1kzqky.js";
|
|
129
136
|
import"./shared/@ai-setting/roy-agent-core-t94ktchq.js";
|
|
130
137
|
import {
|
|
@@ -137,7 +144,7 @@ import {
|
|
|
137
144
|
import"./shared/@ai-setting/roy-agent-core-psvxt4c9.js";
|
|
138
145
|
import {
|
|
139
146
|
McpComponent
|
|
140
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
147
|
+
} from "./shared/@ai-setting/roy-agent-core-xkb264a8.js";
|
|
141
148
|
import {
|
|
142
149
|
AgentError,
|
|
143
150
|
ComponentError,
|
|
@@ -365,6 +372,7 @@ export {
|
|
|
365
372
|
createLogger,
|
|
366
373
|
createInvokeConfig,
|
|
367
374
|
createHook,
|
|
375
|
+
closeDatabase,
|
|
368
376
|
builtInHandlers,
|
|
369
377
|
bashTool,
|
|
370
378
|
XDG_PATHS,
|
|
@@ -392,6 +400,7 @@ export {
|
|
|
392
400
|
ReplFormatter,
|
|
393
401
|
ProviderConfigSchema,
|
|
394
402
|
ProviderCapabilitiesSchema,
|
|
403
|
+
PromptStore,
|
|
395
404
|
PromptComponent,
|
|
396
405
|
PluginComponent,
|
|
397
406
|
OTelTracerProvider,
|
|
@@ -423,6 +432,7 @@ export {
|
|
|
423
432
|
BUILT_IN_EVENT_SOURCE_TYPE_LIST,
|
|
424
433
|
BUILT_IN_EVENT_SOURCE_TYPES,
|
|
425
434
|
AskUserError,
|
|
435
|
+
AgentRegistry,
|
|
426
436
|
AgentError,
|
|
427
437
|
AgentComponentConfigSchema,
|
|
428
438
|
AgentComponent
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getXDGPath
|
|
3
|
+
} from "./roy-agent-core-qxnbvgwe.js";
|
|
4
|
+
import {
|
|
5
|
+
createLogger,
|
|
6
|
+
init_logger
|
|
7
|
+
} from "./roy-agent-core-10n2jh7p.js";
|
|
8
|
+
|
|
9
|
+
// src/env/agent/agent-registry.ts
|
|
10
|
+
import { readdir, readFile, writeFile, mkdir, unlink } from "fs/promises";
|
|
11
|
+
import { existsSync } from "fs";
|
|
12
|
+
import { join } from "path";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import yaml from "yaml";
|
|
15
|
+
init_logger();
|
|
16
|
+
var logger = createLogger("agent:registry");
|
|
17
|
+
var AgentConfigSchema = z.object({
|
|
18
|
+
name: z.string(),
|
|
19
|
+
type: z.enum(["primary", "sub"]),
|
|
20
|
+
description: z.string().optional(),
|
|
21
|
+
systemPromptRef: z.string().optional(),
|
|
22
|
+
systemPrompt: z.string().optional(),
|
|
23
|
+
model: z.string().optional(),
|
|
24
|
+
maxIterations: z.number().optional(),
|
|
25
|
+
maxErrorRetries: z.number().optional(),
|
|
26
|
+
allowedTools: z.array(z.string()).optional(),
|
|
27
|
+
deniedTools: z.array(z.string()).optional(),
|
|
28
|
+
toolTimeout: z.number().optional(),
|
|
29
|
+
toolRetries: z.number().optional(),
|
|
30
|
+
doomLoopThreshold: z.number().optional(),
|
|
31
|
+
filterHistory: z.boolean().optional()
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
class AgentRegistry {
|
|
35
|
+
agents = new Map;
|
|
36
|
+
configDir;
|
|
37
|
+
configComponent;
|
|
38
|
+
promptComponent;
|
|
39
|
+
resolvePromptComponent;
|
|
40
|
+
constructor(options) {
|
|
41
|
+
this.configComponent = options.configComponent;
|
|
42
|
+
this.promptComponent = options.promptComponent ?? null;
|
|
43
|
+
this.resolvePromptComponent = options.resolvePromptComponent;
|
|
44
|
+
const customDir = this.configComponent?.get?.("agent.configDir");
|
|
45
|
+
if (customDir && typeof customDir === "string" && customDir.length > 0) {
|
|
46
|
+
this.configDir = customDir;
|
|
47
|
+
} else if (options.baseDir) {
|
|
48
|
+
this.configDir = join(options.baseDir, "agents");
|
|
49
|
+
} else {
|
|
50
|
+
this.configDir = join(getXDGPath("data"), "agents");
|
|
51
|
+
}
|
|
52
|
+
logger.debug(`[AgentRegistry] Config dir: ${this.configDir}`);
|
|
53
|
+
}
|
|
54
|
+
getConfigDir() {
|
|
55
|
+
return this.configDir;
|
|
56
|
+
}
|
|
57
|
+
hasAgent(name) {
|
|
58
|
+
return this.agents.has(name);
|
|
59
|
+
}
|
|
60
|
+
get(name) {
|
|
61
|
+
return this.agents.get(name);
|
|
62
|
+
}
|
|
63
|
+
list() {
|
|
64
|
+
return Array.from(this.agents.values());
|
|
65
|
+
}
|
|
66
|
+
listAgentsByType(type) {
|
|
67
|
+
return this.list().filter((agent) => agent.type === type);
|
|
68
|
+
}
|
|
69
|
+
register(agent) {
|
|
70
|
+
if (!agent.name) {
|
|
71
|
+
throw new Error("Agent name is required");
|
|
72
|
+
}
|
|
73
|
+
this.agents.set(agent.name, { ...agent });
|
|
74
|
+
logger.info(`[AgentRegistry] Registered agent: ${agent.name}`, { type: agent.type });
|
|
75
|
+
}
|
|
76
|
+
unregister(name) {
|
|
77
|
+
const deleted = this.agents.delete(name);
|
|
78
|
+
if (deleted) {
|
|
79
|
+
logger.info(`[AgentRegistry] Unregistered agent: ${name}`);
|
|
80
|
+
}
|
|
81
|
+
return deleted;
|
|
82
|
+
}
|
|
83
|
+
clear() {
|
|
84
|
+
this.agents.clear();
|
|
85
|
+
logger.info("[AgentRegistry] Cleared all agents");
|
|
86
|
+
}
|
|
87
|
+
async getSystemPrompt(name) {
|
|
88
|
+
const agent = this.agents.get(name);
|
|
89
|
+
if (!agent) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const promptComponent = this.getActivePromptComponent();
|
|
93
|
+
if (agent.systemPromptRef) {
|
|
94
|
+
try {
|
|
95
|
+
const prompt = promptComponent?.get?.(agent.systemPromptRef);
|
|
96
|
+
if (prompt) {
|
|
97
|
+
logger.debug(`[AgentRegistry] Resolved systemPromptRef: ${agent.systemPromptRef}`);
|
|
98
|
+
return prompt;
|
|
99
|
+
}
|
|
100
|
+
if (promptComponent?.getPrompt) {
|
|
101
|
+
const rendered = await promptComponent.getPrompt(agent.systemPromptRef);
|
|
102
|
+
if (rendered) {
|
|
103
|
+
return rendered;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (agent.systemPrompt) {
|
|
107
|
+
logger.debug(`[AgentRegistry] systemPromptRef not found, falling back to inline`);
|
|
108
|
+
return agent.systemPrompt;
|
|
109
|
+
}
|
|
110
|
+
return;
|
|
111
|
+
} catch (error) {
|
|
112
|
+
logger.warn(`[AgentRegistry] Failed to resolve systemPromptRef: ${agent.systemPromptRef}`, { error });
|
|
113
|
+
return agent.systemPrompt;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return agent.systemPrompt;
|
|
117
|
+
}
|
|
118
|
+
getActivePromptComponent() {
|
|
119
|
+
return this.resolvePromptComponent?.() ?? this.promptComponent;
|
|
120
|
+
}
|
|
121
|
+
getInlineSystemPrompt(name) {
|
|
122
|
+
const agent = this.agents.get(name);
|
|
123
|
+
if (!agent) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
return agent.systemPrompt;
|
|
127
|
+
}
|
|
128
|
+
async load() {
|
|
129
|
+
try {
|
|
130
|
+
return await this.loadFromDirectory(this.configDir);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
logger.warn(`[AgentRegistry] Failed to load agents: ${error}`);
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async loadFromDirectory(directory) {
|
|
137
|
+
let loaded = 0;
|
|
138
|
+
try {
|
|
139
|
+
if (!existsSync(directory)) {
|
|
140
|
+
logger.debug(`[AgentRegistry] Config directory does not exist: ${directory}`);
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
143
|
+
const files = await readdir(directory, { withFileTypes: true });
|
|
144
|
+
for (const file of files) {
|
|
145
|
+
const fullPath = join(directory, file.name);
|
|
146
|
+
if (file.isDirectory()) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (!isAgentConfigFile(file.name)) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const content = await readFile(fullPath, "utf-8");
|
|
154
|
+
const agent = this.parseAgentConfig(content, fullPath);
|
|
155
|
+
if (agent) {
|
|
156
|
+
this.agents.set(agent.name, agent);
|
|
157
|
+
logger.info(`[AgentRegistry] Loaded agent: ${agent.name} from ${file.name}`);
|
|
158
|
+
loaded++;
|
|
159
|
+
}
|
|
160
|
+
} catch (error) {
|
|
161
|
+
logger.warn(`[AgentRegistry] Failed to load agent from ${file.name}: ${error}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
logger.info(`[AgentRegistry] Loaded ${loaded} agents from ${directory}`);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
logger.warn(`[AgentRegistry] Error reading config directory: ${error}`);
|
|
167
|
+
}
|
|
168
|
+
return loaded;
|
|
169
|
+
}
|
|
170
|
+
parseAgentConfig(content, source) {
|
|
171
|
+
try {
|
|
172
|
+
const parsed = yaml.parse(content);
|
|
173
|
+
const result = AgentConfigSchema.safeParse(parsed);
|
|
174
|
+
if (!result.success) {
|
|
175
|
+
logger.warn(`[AgentRegistry] Invalid agent config: ${source}`, {
|
|
176
|
+
errors: result.error.errors
|
|
177
|
+
});
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
return result.data;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
logger.error(`[AgentRegistry] Failed to parse agent config: ${source}`, { error });
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async saveAgent(agent) {
|
|
187
|
+
try {
|
|
188
|
+
await this.ensureConfigDir();
|
|
189
|
+
const yamlContent = this.agentToYaml(agent);
|
|
190
|
+
const filePath = join(this.configDir, `${agent.name}.yaml`);
|
|
191
|
+
await writeFile(filePath, yamlContent, "utf-8");
|
|
192
|
+
this.agents.set(agent.name, agent);
|
|
193
|
+
logger.info(`[AgentRegistry] Saved agent: ${agent.name} to ${filePath}`);
|
|
194
|
+
return true;
|
|
195
|
+
} catch (error) {
|
|
196
|
+
logger.error(`[AgentRegistry] Failed to save agent: ${agent.name}`, { error });
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async ensureConfigDir() {
|
|
201
|
+
if (!existsSync(this.configDir)) {
|
|
202
|
+
await mkdir(this.configDir, { recursive: true });
|
|
203
|
+
logger.debug(`[AgentRegistry] Created config directory: ${this.configDir}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
agentToYaml(agent) {
|
|
207
|
+
const config = {
|
|
208
|
+
name: agent.name,
|
|
209
|
+
type: agent.type,
|
|
210
|
+
...agent.description !== undefined ? { description: agent.description } : {},
|
|
211
|
+
...agent.systemPromptRef !== undefined ? { systemPromptRef: agent.systemPromptRef } : {},
|
|
212
|
+
...agent.systemPrompt !== undefined ? { systemPrompt: agent.systemPrompt } : {},
|
|
213
|
+
...agent.model !== undefined ? { model: agent.model } : {},
|
|
214
|
+
...agent.maxIterations !== undefined ? { maxIterations: agent.maxIterations } : {},
|
|
215
|
+
...agent.maxErrorRetries !== undefined ? { maxErrorRetries: agent.maxErrorRetries } : {},
|
|
216
|
+
...agent.allowedTools !== undefined ? { allowedTools: agent.allowedTools } : {},
|
|
217
|
+
...agent.deniedTools !== undefined ? { deniedTools: agent.deniedTools } : {},
|
|
218
|
+
...agent.toolTimeout !== undefined ? { toolTimeout: agent.toolTimeout } : {},
|
|
219
|
+
...agent.toolRetries !== undefined ? { toolRetries: agent.toolRetries } : {},
|
|
220
|
+
...agent.doomLoopThreshold !== undefined ? { doomLoopThreshold: agent.doomLoopThreshold } : {},
|
|
221
|
+
...agent.filterHistory !== undefined ? { filterHistory: agent.filterHistory } : {}
|
|
222
|
+
};
|
|
223
|
+
return yaml.stringify(config).trimEnd() + `
|
|
224
|
+
`;
|
|
225
|
+
}
|
|
226
|
+
async deleteAgent(name) {
|
|
227
|
+
const agent = this.agents.get(name);
|
|
228
|
+
if (!agent) {
|
|
229
|
+
logger.warn(`[AgentRegistry] Agent not found: ${name}`);
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
const filePath = join(this.configDir, `${name}.yaml`);
|
|
234
|
+
if (existsSync(filePath)) {
|
|
235
|
+
await unlink(filePath);
|
|
236
|
+
logger.info(`[AgentRegistry] Deleted agent file: ${filePath}`);
|
|
237
|
+
}
|
|
238
|
+
this.agents.delete(name);
|
|
239
|
+
return true;
|
|
240
|
+
} catch (error) {
|
|
241
|
+
logger.error(`[AgentRegistry] Failed to delete agent: ${name}`, { error });
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
exportAgents(options = {}) {
|
|
246
|
+
const agents = this.list();
|
|
247
|
+
if (options.format === "json") {
|
|
248
|
+
return agents;
|
|
249
|
+
}
|
|
250
|
+
return agents;
|
|
251
|
+
}
|
|
252
|
+
exportAgentsAsJson() {
|
|
253
|
+
return JSON.stringify(this.list(), null, 2);
|
|
254
|
+
}
|
|
255
|
+
size() {
|
|
256
|
+
return this.agents.size;
|
|
257
|
+
}
|
|
258
|
+
configDirExists() {
|
|
259
|
+
return existsSync(this.configDir);
|
|
260
|
+
}
|
|
261
|
+
getAgentFilePath(name) {
|
|
262
|
+
return join(this.configDir, `${name}.yaml`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function isAgentConfigFile(fileName) {
|
|
266
|
+
return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
|
|
267
|
+
}
|
|
268
|
+
var DEFAULT_SUBAGENT_PROMPT = `You are a subagent created by the main agent to handle a specific task.
|
|
269
|
+
|
|
270
|
+
## Your Role
|
|
271
|
+
- You were created to handle: {task_description}
|
|
272
|
+
- Complete this task. That's your entire purpose.
|
|
273
|
+
- You are NOT the main agent. Don't try to be.
|
|
274
|
+
|
|
275
|
+
## Rules
|
|
276
|
+
1. **Stay focused** - Do your assigned task, nothing else
|
|
277
|
+
2. **Complete the task** - Your final message will be automatically reported to the main agent
|
|
278
|
+
3. **Don't initiate** - No heartbeats, no proactive actions, no side quests
|
|
279
|
+
4. **Be ephemeral** - You may be terminated after task completion. That's fine.
|
|
280
|
+
5. **No nested delegation** - Do NOT use delegate_task or stop_task tools. Complete the task yourself.
|
|
281
|
+
|
|
282
|
+
## Execution
|
|
283
|
+
- Use the available tools to complete the task
|
|
284
|
+
- If you need more information, ask the main agent through the result
|
|
285
|
+
- Return a clear summary of what you did and the results`;
|
|
286
|
+
|
|
287
|
+
export { AgentRegistry, DEFAULT_SUBAGENT_PROMPT };
|
|
@@ -259,6 +259,10 @@ class WorkflowComponent extends BaseComponent {
|
|
|
259
259
|
this._status = "stopping";
|
|
260
260
|
this.workflowService = null;
|
|
261
261
|
this.nodeRegistry = null;
|
|
262
|
+
try {
|
|
263
|
+
const { closeDatabase } = await import("./roy-agent-core-zwp3jp02.js");
|
|
264
|
+
closeDatabase();
|
|
265
|
+
} catch {}
|
|
262
266
|
this._status = "stopped";
|
|
263
267
|
componentLogger.info("WorkflowComponent stopped");
|
|
264
268
|
}
|
|
@@ -2,6 +2,9 @@ import {
|
|
|
2
2
|
AskUserError,
|
|
3
3
|
init_workflow_hil
|
|
4
4
|
} from "./roy-agent-core-e25xkv53.js";
|
|
5
|
+
import {
|
|
6
|
+
AgentRegistry
|
|
7
|
+
} from "./roy-agent-core-7t05apnp.js";
|
|
5
8
|
import {
|
|
6
9
|
ContextError
|
|
7
10
|
} from "./roy-agent-core-ctdhjv68.js";
|
|
@@ -166,6 +169,7 @@ class AgentComponent extends BaseComponent {
|
|
|
166
169
|
configWatcher;
|
|
167
170
|
messageConverter = new SessionMessageConverter;
|
|
168
171
|
_constructorConfig;
|
|
172
|
+
registry;
|
|
169
173
|
runCounter = 0;
|
|
170
174
|
constructor(options = {}) {
|
|
171
175
|
super();
|
|
@@ -185,6 +189,7 @@ class AgentComponent extends BaseComponent {
|
|
|
185
189
|
}
|
|
186
190
|
this.configComponent = options.configComponent;
|
|
187
191
|
await this.registerConfig(options);
|
|
192
|
+
await this.initRegistry(options.configComponent);
|
|
188
193
|
this.setStatus("running");
|
|
189
194
|
}
|
|
190
195
|
async registerConfig(options) {
|
|
@@ -271,6 +276,63 @@ class AgentComponent extends BaseComponent {
|
|
|
271
276
|
newValue: event.newValue
|
|
272
277
|
});
|
|
273
278
|
}
|
|
279
|
+
async initRegistry(configComponent) {
|
|
280
|
+
try {
|
|
281
|
+
this.registry = new AgentRegistry({
|
|
282
|
+
configComponent,
|
|
283
|
+
resolvePromptComponent: () => this.env?.getComponent?.("prompt") ?? null
|
|
284
|
+
});
|
|
285
|
+
const loadedCount = await this.registry.load();
|
|
286
|
+
logger.info(`[AgentComponent] Loaded ${loadedCount} agents from config directory`);
|
|
287
|
+
for (const agentDef of this.registry.list()) {
|
|
288
|
+
if (!this.agents.has(agentDef.name)) {
|
|
289
|
+
const systemPrompt = await this.registry.getSystemPrompt(agentDef.name);
|
|
290
|
+
this.registerAgent(agentDef.name, {
|
|
291
|
+
type: agentDef.type,
|
|
292
|
+
systemPrompt,
|
|
293
|
+
allowedTools: agentDef.allowedTools,
|
|
294
|
+
deniedTools: agentDef.deniedTools,
|
|
295
|
+
model: agentDef.model,
|
|
296
|
+
maxIterations: agentDef.maxIterations
|
|
297
|
+
});
|
|
298
|
+
logger.debug(`[AgentComponent] Registered agent from config: ${agentDef.name}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
} catch (error) {
|
|
302
|
+
logger.warn(`[AgentComponent] Failed to initialize AgentRegistry: ${error}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async syncRegistryAgentsFromConfig() {
|
|
306
|
+
if (!this.registry) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
for (const agentDef of this.registry.list()) {
|
|
310
|
+
const systemPrompt = await this.registry.getSystemPrompt(agentDef.name);
|
|
311
|
+
const existing = this.agents.get(agentDef.name);
|
|
312
|
+
if (existing) {
|
|
313
|
+
existing.config.systemPrompt = systemPrompt;
|
|
314
|
+
} else {
|
|
315
|
+
this.registerAgent(agentDef.name, {
|
|
316
|
+
type: agentDef.type,
|
|
317
|
+
systemPrompt,
|
|
318
|
+
allowedTools: agentDef.allowedTools,
|
|
319
|
+
deniedTools: agentDef.deniedTools,
|
|
320
|
+
model: agentDef.model,
|
|
321
|
+
maxIterations: agentDef.maxIterations
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
logger.debug(`[AgentComponent] Synced registry agent: ${agentDef.name}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
getRegistry() {
|
|
328
|
+
return this.registry;
|
|
329
|
+
}
|
|
330
|
+
getAgentFromRegistry(name) {
|
|
331
|
+
return this.registry?.get(name);
|
|
332
|
+
}
|
|
333
|
+
listAgentsFromRegistry() {
|
|
334
|
+
return this.registry?.list() ?? [];
|
|
335
|
+
}
|
|
274
336
|
async onStop() {
|
|
275
337
|
logger.info("[AgentComponent] Stopping and cleaning up resources...");
|
|
276
338
|
for (const [name, agent] of this.agents) {
|
|
@@ -1048,6 +1048,14 @@ class ConfigComponent extends BaseComponent {
|
|
|
1048
1048
|
}
|
|
1049
1049
|
this.sourceUnwatchFns.clear();
|
|
1050
1050
|
}
|
|
1051
|
+
shutdown() {
|
|
1052
|
+
this.unwatchAll();
|
|
1053
|
+
this.persistQueue.clear();
|
|
1054
|
+
}
|
|
1055
|
+
async onStop() {
|
|
1056
|
+
this.shutdown();
|
|
1057
|
+
await super.onStop();
|
|
1058
|
+
}
|
|
1051
1059
|
getSources() {
|
|
1052
1060
|
return [...this.sources];
|
|
1053
1061
|
}
|
|
@@ -318,10 +318,25 @@ class McpLoader {
|
|
|
318
318
|
return;
|
|
319
319
|
try {
|
|
320
320
|
await entry.client.close();
|
|
321
|
-
this.clients.delete(name);
|
|
322
|
-
logger2.info(`[McpLoader] Disconnected from ${name}`);
|
|
323
321
|
} catch (error) {
|
|
324
|
-
logger2.warn(`[McpLoader] Error
|
|
322
|
+
logger2.warn(`[McpLoader] Error closing client for ${name}`, { error });
|
|
323
|
+
}
|
|
324
|
+
await this.closeTransport(entry.transport, name);
|
|
325
|
+
this.clients.delete(name);
|
|
326
|
+
logger2.info(`[McpLoader] Disconnected from ${name}`);
|
|
327
|
+
}
|
|
328
|
+
async closeTransport(transport, name) {
|
|
329
|
+
try {
|
|
330
|
+
const transportAny = transport;
|
|
331
|
+
if (typeof transportAny.close === "function") {
|
|
332
|
+
await transportAny.close();
|
|
333
|
+
}
|
|
334
|
+
const child = transportAny._process ?? transportAny.process;
|
|
335
|
+
if (child?.pid && !child.killed) {
|
|
336
|
+
child.kill?.("SIGTERM");
|
|
337
|
+
}
|
|
338
|
+
} catch (error) {
|
|
339
|
+
logger2.warn(`[McpLoader] Error closing transport for ${name}`, { error });
|
|
325
340
|
}
|
|
326
341
|
}
|
|
327
342
|
async disconnectAll() {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_SUBAGENT_PROMPT
|
|
3
|
+
} from "./roy-agent-core-7t05apnp.js";
|
|
1
4
|
import {
|
|
2
5
|
TaskHookPoints
|
|
3
6
|
} from "./roy-agent-core-92z6t4he.js";
|
|
@@ -12,6 +15,54 @@ import {
|
|
|
12
15
|
// src/env/task/delegate/delegate-tool.ts
|
|
13
16
|
init_logger();
|
|
14
17
|
import { z } from "zod";
|
|
18
|
+
|
|
19
|
+
// src/env/task/delegate/subagent-resolver.ts
|
|
20
|
+
function isKnownSubagentType(subagentType, registry) {
|
|
21
|
+
if (getSubAgentSpec(subagentType)) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return registry?.hasAgent(subagentType) ?? false;
|
|
25
|
+
}
|
|
26
|
+
async function resolveSubAgentConfig(subagentType, options = {}) {
|
|
27
|
+
const getBuiltIn = options.getBuiltIn ?? getSubAgentSpec;
|
|
28
|
+
const builtIn = getBuiltIn(subagentType);
|
|
29
|
+
const agentDef = options.registry?.get(subagentType);
|
|
30
|
+
if (!builtIn && !agentDef) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (agentDef) {
|
|
34
|
+
return resolveFromRegistry(subagentType, agentDef, builtIn, options.registry);
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
subagentType,
|
|
38
|
+
description: builtIn.description,
|
|
39
|
+
basePrompt: builtIn.promptOverride || DEFAULT_SUBAGENT_PROMPT,
|
|
40
|
+
allowedTools: builtIn.allowedTools,
|
|
41
|
+
deniedTools: builtIn.deniedTools ?? ["delegate_task", "stop_task"],
|
|
42
|
+
fromRegistry: false
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async function resolveFromRegistry(subagentType, agentDef, builtIn, registry) {
|
|
46
|
+
const resolvedPrompt = registry ? await registry.getSystemPrompt(subagentType) : agentDef.systemPrompt;
|
|
47
|
+
return {
|
|
48
|
+
subagentType,
|
|
49
|
+
description: agentDef.description || builtIn?.description || "Custom agent",
|
|
50
|
+
basePrompt: resolvedPrompt || builtIn?.promptOverride || DEFAULT_SUBAGENT_PROMPT,
|
|
51
|
+
allowedTools: agentDef.allowedTools ?? builtIn?.allowedTools,
|
|
52
|
+
deniedTools: agentDef.deniedTools ?? builtIn?.deniedTools ?? ["delegate_task", "stop_task"],
|
|
53
|
+
fromRegistry: true
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function listKnownSubagentDescriptions(registry) {
|
|
57
|
+
const builtInLines = builtInSubAgents.map((agent) => `- ${agent.id}: ${agent.description}`);
|
|
58
|
+
const registryAgents = registry?.listAgentsByType("sub") ?? [];
|
|
59
|
+
const customLines = registryAgents.filter((agent) => !builtInSubAgents.some((builtIn) => builtIn.id === agent.name)).map((agent) => `- ${agent.name}: ${agent.description || "Custom agent"}`);
|
|
60
|
+
const lines = [...builtInLines, ...customLines];
|
|
61
|
+
return lines.join(`
|
|
62
|
+
`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/env/task/delegate/delegate-tool.ts
|
|
15
66
|
var logger = createLogger("task:delegate");
|
|
16
67
|
var BackgroundTaskEventTypes = {
|
|
17
68
|
STARTED: "task.background.started",
|
|
@@ -99,10 +150,6 @@ var builtInSubAgents = [
|
|
|
99
150
|
function getSubAgentSpec(id) {
|
|
100
151
|
return builtInSubAgents.find((agent) => agent.id === id);
|
|
101
152
|
}
|
|
102
|
-
function getSubAgentToolDescription() {
|
|
103
|
-
return builtInSubAgents.map((agent) => `- ${agent.id}: ${agent.description}`).join(`
|
|
104
|
-
`);
|
|
105
|
-
}
|
|
106
153
|
function ensureSubAgentRegistered(agentComponent, subagentType, basePrompt, subAgent, deniedTools) {
|
|
107
154
|
let agentInstance = agentComponent.getAgent(subagentType);
|
|
108
155
|
if (!agentInstance) {
|
|
@@ -341,24 +388,20 @@ class BackgroundTaskManager {
|
|
|
341
388
|
}
|
|
342
389
|
}
|
|
343
390
|
async executeWithAbort(subSession, prompt, timeoutMs, signal) {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
let basePrompt = subAgent?.promptOverride || `You are a subagent. Complete this task: {task_description}`;
|
|
359
|
-
const deniedTools = subAgent?.deniedTools || [];
|
|
360
|
-
let fullPrompt = basePrompt.replace(/{task_description}/g, taskDescription || "N/A");
|
|
361
|
-
fullPrompt += `
|
|
391
|
+
const metadata = subSession.info?.metadata || {};
|
|
392
|
+
const taskId = metadata.task_id;
|
|
393
|
+
const taskDescription = metadata.task_description || "";
|
|
394
|
+
const sessionId = subSession.id;
|
|
395
|
+
const subagentType = metadata.subagent_type || "general";
|
|
396
|
+
const agentComponent = this.env?.getComponent?.("agent");
|
|
397
|
+
const registry = agentComponent?.getRegistry?.();
|
|
398
|
+
const resolved = await resolveSubAgentConfig(subagentType, { registry });
|
|
399
|
+
const subAgent = getSubAgentSpec(subagentType);
|
|
400
|
+
const basePrompt = resolved?.basePrompt || subAgent?.promptOverride || `You are a subagent. Complete this task: {task_description}`;
|
|
401
|
+
const deniedTools = resolved?.deniedTools || subAgent?.deniedTools || [];
|
|
402
|
+
const allowedTools = resolved?.allowedTools || subAgent?.allowedTools;
|
|
403
|
+
let fullPrompt = basePrompt.replace(/{task_description}/g, taskDescription || "N/A");
|
|
404
|
+
fullPrompt += `
|
|
362
405
|
|
|
363
406
|
---
|
|
364
407
|
|
|
@@ -377,18 +420,31 @@ ${prompt}
|
|
|
377
420
|
- 使用可用工具完成任务
|
|
378
421
|
- 返回清晰的任务执行结果摘要
|
|
379
422
|
- 适时调用 task_operation_create 记录进展`;
|
|
380
|
-
|
|
381
|
-
|
|
423
|
+
if (!agentComponent) {
|
|
424
|
+
throw new Error("AgentComponent not found");
|
|
425
|
+
}
|
|
426
|
+
const subAgentForRegister = subAgent ? { ...subAgent, allowedTools } : allowedTools ? {
|
|
427
|
+
id: subagentType,
|
|
428
|
+
name: subagentType,
|
|
429
|
+
mode: "subagent",
|
|
430
|
+
description: resolved?.description || "Custom agent",
|
|
431
|
+
allowedTools,
|
|
432
|
+
deniedTools
|
|
433
|
+
} : undefined;
|
|
434
|
+
ensureSubAgentRegistered(agentComponent, subagentType, basePrompt, subAgentForRegister, deniedTools);
|
|
435
|
+
return new Promise((resolve, reject) => {
|
|
436
|
+
const timer = setTimeout(() => {
|
|
437
|
+
reject(new Error(`Task execution timeout after ${timeoutMs}ms`));
|
|
438
|
+
}, timeoutMs);
|
|
439
|
+
signal?.addEventListener("abort", () => {
|
|
382
440
|
clearTimeout(timer);
|
|
383
|
-
reject(new Error("
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
ensureSubAgentRegistered(agentComponent, subagentType, basePrompt, subAgent, deniedTools);
|
|
441
|
+
reject(new Error("Task execution stopped"));
|
|
442
|
+
});
|
|
387
443
|
this.env.handle_query?.(fullPrompt, {
|
|
388
444
|
sessionId,
|
|
389
445
|
deniedTools: deniedTools.length > 0 ? deniedTools : undefined,
|
|
390
446
|
agentType: subagentType
|
|
391
|
-
})
|
|
447
|
+
})?.then((result) => {
|
|
392
448
|
clearTimeout(timer);
|
|
393
449
|
resolve(result);
|
|
394
450
|
}).catch((error) => {
|
|
@@ -450,7 +506,7 @@ function createDelegateTool(taskComponent) {
|
|
|
450
506
|
description: `Launch a new sub-agent to handle complex, multistep tasks autonomously.
|
|
451
507
|
|
|
452
508
|
Available agent types:
|
|
453
|
-
${
|
|
509
|
+
${listKnownSubagentDescriptions()}
|
|
454
510
|
|
|
455
511
|
When using the delegate_task tool, you must specify a subagent_type parameter to select which agent type to use.
|
|
456
512
|
|
|
@@ -477,8 +533,9 @@ When using the delegate_task tool, you must specify a subagent_type parameter to
|
|
|
477
533
|
const { description, prompt, subagent_type = "general", background = false, timeout, cleanup, task_id, reason } = params;
|
|
478
534
|
const parentSessionId = ctx.session_id || "default";
|
|
479
535
|
logger.info(`[delegate_task] Called: description=${description}, subagent_type=${subagent_type}, background=${background}, task_id=${task_id}`);
|
|
480
|
-
const
|
|
481
|
-
|
|
536
|
+
const agentComponent = taskComponent.env?.getComponent?.("agent");
|
|
537
|
+
const registry = agentComponent?.getRegistry?.();
|
|
538
|
+
if (!isKnownSubagentType(subagent_type, registry)) {
|
|
482
539
|
return {
|
|
483
540
|
success: false,
|
|
484
541
|
output: "",
|
|
@@ -558,9 +615,13 @@ async function handleSyncTask(taskComponent, parentSessionId, description, promp
|
|
|
558
615
|
metadata: { execution_time_ms: Date.now() - startTime }
|
|
559
616
|
};
|
|
560
617
|
}
|
|
618
|
+
const agentComponent = taskComponent.env?.getComponent?.("agent");
|
|
619
|
+
const registry = agentComponent?.getRegistry?.();
|
|
620
|
+
const resolved = await resolveSubAgentConfig(subagentType, { registry });
|
|
561
621
|
const subAgent = getSubAgentSpec(subagentType);
|
|
562
|
-
let basePrompt = subAgent?.promptOverride || `You are a subagent. Complete this task: {task_description}`;
|
|
563
|
-
const deniedTools = subAgent?.deniedTools || [];
|
|
622
|
+
let basePrompt = resolved?.basePrompt || subAgent?.promptOverride || `You are a subagent. Complete this task: {task_description}`;
|
|
623
|
+
const deniedTools = resolved?.deniedTools || subAgent?.deniedTools || [];
|
|
624
|
+
const allowedTools = resolved?.allowedTools || subAgent?.allowedTools;
|
|
564
625
|
let fullPrompt = basePrompt.replace(/{task_description}/g, description || "N/A");
|
|
565
626
|
fullPrompt += `
|
|
566
627
|
|
|
@@ -581,7 +642,6 @@ ${prompt}
|
|
|
581
642
|
- 使用可用工具完成任务
|
|
582
643
|
- 返回清晰的任务执行结果摘要
|
|
583
644
|
- 适时调用 task_operation_create 记录进展`;
|
|
584
|
-
const agentComponent = taskComponent.env?.getComponent?.("agent");
|
|
585
645
|
if (!agentComponent) {
|
|
586
646
|
return {
|
|
587
647
|
success: false,
|
|
@@ -590,7 +650,15 @@ ${prompt}
|
|
|
590
650
|
metadata: { execution_time_ms: Date.now() - startTime }
|
|
591
651
|
};
|
|
592
652
|
}
|
|
593
|
-
|
|
653
|
+
const subAgentForRegister = subAgent ? { ...subAgent, allowedTools } : allowedTools ? {
|
|
654
|
+
id: subagentType,
|
|
655
|
+
name: subagentType,
|
|
656
|
+
mode: "subagent",
|
|
657
|
+
description: resolved?.description || "Custom agent",
|
|
658
|
+
allowedTools,
|
|
659
|
+
deniedTools
|
|
660
|
+
} : undefined;
|
|
661
|
+
ensureSubAgentRegistered(agentComponent, subagentType, basePrompt, subAgentForRegister, deniedTools);
|
|
594
662
|
const timeoutMs = timeout || DEFAULT_TIMEOUT;
|
|
595
663
|
let result;
|
|
596
664
|
try {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getXDGPath
|
|
3
|
+
} from "./roy-agent-core-qxnbvgwe.js";
|
|
1
4
|
import {
|
|
2
5
|
envKeyToConfigKey,
|
|
3
6
|
toEnvKey
|
|
@@ -236,6 +239,33 @@ roy-agent mcp list|tools|reload
|
|
|
236
239
|
roy-agent config|cfg list|export|import
|
|
237
240
|
\`\`\`
|
|
238
241
|
|
|
242
|
+
- \`roy-agent config list [component]\` - 查看组件配置 (tool/session/agent/prompt/all)
|
|
243
|
+
- \`roy-agent config export <component>\` - 导出组件配置
|
|
244
|
+
- \`roy-agent config import <component>\` - 导入组件配置
|
|
245
|
+
|
|
246
|
+
#### Agents Command
|
|
247
|
+
|
|
248
|
+
\`\`\`bash
|
|
249
|
+
roy-agent agents list|get|add|delete|config-dir
|
|
250
|
+
\`\`\`
|
|
251
|
+
|
|
252
|
+
- \`roy-agent agents list\` - 列出所有可用 agents
|
|
253
|
+
- \`roy-agent agents get <name>\` - 获取指定 agent 的详细信息和 resolved system prompt
|
|
254
|
+
- \`roy-agent agents add <name>\` - 添加 agent 配置(写入 YAML 文件)
|
|
255
|
+
- \`roy-agent agents delete <name>\` - 删除 agent 配置文件
|
|
256
|
+
- \`roy-agent agents config-dir\` - 显示 agent 配置目录路径
|
|
257
|
+
|
|
258
|
+
#### Prompt Command
|
|
259
|
+
|
|
260
|
+
\`\`\`bash
|
|
261
|
+
roy-agent prompt list|get|add|config-dir
|
|
262
|
+
\`\`\`
|
|
263
|
+
|
|
264
|
+
- \`roy-agent prompt list\` - 列出所有可用 prompts (built-in/directory/file/all)
|
|
265
|
+
- \`roy-agent prompt get <name>\` - 获取指定 prompt 的内容
|
|
266
|
+
- \`roy-agent prompt add <name>\` - 添加 prompt 并持久化到 ~/.local/share/roy-agent/prompts/
|
|
267
|
+
- \`roy-agent prompt config-dir\` - 显示 prompt 持久化目录路径
|
|
268
|
+
|
|
239
269
|
#### Debug Command
|
|
240
270
|
|
|
241
271
|
\`\`\`bash
|
|
@@ -557,16 +587,95 @@ function getBuiltInPrompt(name) {
|
|
|
557
587
|
return builtInPrompts[name];
|
|
558
588
|
}
|
|
559
589
|
|
|
590
|
+
// src/env/prompt/prompt-store.ts
|
|
591
|
+
import { mkdir, readFile, writeFile, unlink, readdir } from "fs/promises";
|
|
592
|
+
import { existsSync } from "fs";
|
|
593
|
+
import { join, dirname } from "path";
|
|
594
|
+
init_logger();
|
|
595
|
+
var logger = createLogger("prompt:store");
|
|
596
|
+
|
|
597
|
+
class PromptStore {
|
|
598
|
+
configDir;
|
|
599
|
+
constructor(options = {}) {
|
|
600
|
+
if (options.configDir && options.configDir.length > 0) {
|
|
601
|
+
this.configDir = options.configDir;
|
|
602
|
+
} else if (options.baseDir) {
|
|
603
|
+
this.configDir = join(options.baseDir, "prompts");
|
|
604
|
+
} else {
|
|
605
|
+
this.configDir = join(getXDGPath("data"), "prompts");
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
getConfigDir() {
|
|
609
|
+
return this.configDir;
|
|
610
|
+
}
|
|
611
|
+
configDirExists() {
|
|
612
|
+
return existsSync(this.configDir);
|
|
613
|
+
}
|
|
614
|
+
getPromptFilePath(name) {
|
|
615
|
+
return join(this.configDir, `${name}.md`);
|
|
616
|
+
}
|
|
617
|
+
async savePrompt(name, content) {
|
|
618
|
+
await this.ensureConfigDir();
|
|
619
|
+
const filePath = this.getPromptFilePath(name);
|
|
620
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
621
|
+
await writeFile(filePath, content, "utf-8");
|
|
622
|
+
logger.info(`[PromptStore] Saved prompt: ${name} -> ${filePath}`);
|
|
623
|
+
return filePath;
|
|
624
|
+
}
|
|
625
|
+
async deletePrompt(name) {
|
|
626
|
+
const filePath = this.getPromptFilePath(name);
|
|
627
|
+
if (!existsSync(filePath)) {
|
|
628
|
+
return false;
|
|
629
|
+
}
|
|
630
|
+
await unlink(filePath);
|
|
631
|
+
logger.info(`[PromptStore] Deleted prompt file: ${filePath}`);
|
|
632
|
+
return true;
|
|
633
|
+
}
|
|
634
|
+
async loadAll() {
|
|
635
|
+
if (!existsSync(this.configDir)) {
|
|
636
|
+
return [];
|
|
637
|
+
}
|
|
638
|
+
const prompts = [];
|
|
639
|
+
await this.collectPrompts(this.configDir, "", prompts);
|
|
640
|
+
return prompts;
|
|
641
|
+
}
|
|
642
|
+
async collectPrompts(directory, prefix, out) {
|
|
643
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
644
|
+
for (const entry of entries) {
|
|
645
|
+
const fullPath = join(directory, entry.name);
|
|
646
|
+
if (entry.isDirectory()) {
|
|
647
|
+
const nextPrefix = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
648
|
+
await this.collectPrompts(fullPath, nextPrefix, out);
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
if (!entry.isFile() || !entry.name.endsWith(".md")) {
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
const baseName = entry.name.slice(0, -3);
|
|
655
|
+
const name = prefix ? `${prefix}/${baseName}` : baseName;
|
|
656
|
+
const content = (await readFile(fullPath, "utf-8")).trim();
|
|
657
|
+
out.push({ name, content, filePath: fullPath });
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
async ensureConfigDir() {
|
|
661
|
+
if (!existsSync(this.configDir)) {
|
|
662
|
+
await mkdir(this.configDir, { recursive: true });
|
|
663
|
+
logger.debug(`[PromptStore] Created config directory: ${this.configDir}`);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
560
668
|
// src/env/prompt/prompt-component.ts
|
|
561
669
|
init_logger();
|
|
562
|
-
import { readFile, readdir } from "fs/promises";
|
|
563
|
-
import { join, basename, extname } from "path";
|
|
670
|
+
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
671
|
+
import { join as join2, basename, extname } from "path";
|
|
564
672
|
|
|
565
673
|
// src/env/prompt/prompt-config-registration.ts
|
|
566
674
|
var PROMPT_DEFAULTS = {
|
|
567
675
|
"prompt.defaultName": "default",
|
|
568
676
|
"prompt.variablePrefix": "{{",
|
|
569
|
-
"prompt.variableSuffix": "}}"
|
|
677
|
+
"prompt.variableSuffix": "}}",
|
|
678
|
+
"prompt.configDir": ""
|
|
570
679
|
};
|
|
571
680
|
var PROMPT_CONFIG_REGISTRATION = {
|
|
572
681
|
name: "prompt",
|
|
@@ -575,6 +684,7 @@ var PROMPT_CONFIG_REGISTRATION = {
|
|
|
575
684
|
],
|
|
576
685
|
keys: [
|
|
577
686
|
{ key: "prompt.promptPaths", sources: ["env", "file"] },
|
|
687
|
+
{ key: "prompt.configDir", sources: ["env", "file"] },
|
|
578
688
|
{ key: "prompt.defaultName", sources: ["env", "file"] },
|
|
579
689
|
{ key: "prompt.variablePrefix", sources: ["env", "file"] },
|
|
580
690
|
{ key: "prompt.variableSuffix", sources: ["env", "file"] }
|
|
@@ -582,7 +692,7 @@ var PROMPT_CONFIG_REGISTRATION = {
|
|
|
582
692
|
};
|
|
583
693
|
|
|
584
694
|
// src/env/prompt/prompt-component.ts
|
|
585
|
-
var
|
|
695
|
+
var logger2 = createLogger("prompt");
|
|
586
696
|
|
|
587
697
|
class PromptComponent extends BaseComponent {
|
|
588
698
|
name = "prompt";
|
|
@@ -591,6 +701,7 @@ class PromptComponent extends BaseComponent {
|
|
|
591
701
|
config;
|
|
592
702
|
configComponent;
|
|
593
703
|
renderer;
|
|
704
|
+
promptStore;
|
|
594
705
|
configWatcher;
|
|
595
706
|
constructor() {
|
|
596
707
|
super();
|
|
@@ -604,9 +715,10 @@ class PromptComponent extends BaseComponent {
|
|
|
604
715
|
this.configComponent = options.configComponent;
|
|
605
716
|
await this.registerConfig(options);
|
|
606
717
|
this.initRenderer();
|
|
718
|
+
this.initPromptStore();
|
|
607
719
|
await this.loadPrompts();
|
|
608
720
|
this.setStatus("running");
|
|
609
|
-
|
|
721
|
+
logger2.info(`[PromptComponent] Initialized with ${this.prompts.size} prompts`);
|
|
610
722
|
}
|
|
611
723
|
async registerConfig(options) {
|
|
612
724
|
const configComponent = options.configComponent;
|
|
@@ -700,7 +812,7 @@ class PromptComponent extends BaseComponent {
|
|
|
700
812
|
const value = event.newValue;
|
|
701
813
|
if (value === undefined)
|
|
702
814
|
return;
|
|
703
|
-
|
|
815
|
+
logger2.debug(`[PromptComponent] Config updated: ${key} = ${JSON.stringify(value)}`);
|
|
704
816
|
switch (key) {
|
|
705
817
|
case "prompt.defaultName":
|
|
706
818
|
if (this.config)
|
|
@@ -741,18 +853,20 @@ class PromptComponent extends BaseComponent {
|
|
|
741
853
|
suffix: config.variableSuffix,
|
|
742
854
|
strict: config.strictMode,
|
|
743
855
|
onMissingVariable: (name) => {
|
|
744
|
-
|
|
856
|
+
logger2.warn(`Undefined variable: ${name}`);
|
|
745
857
|
return `{{${name}}}`;
|
|
746
858
|
}
|
|
747
859
|
});
|
|
748
860
|
}
|
|
749
861
|
async onStart() {
|
|
750
|
-
|
|
862
|
+
logger2.info("[PromptComponent] Started");
|
|
751
863
|
}
|
|
752
864
|
async onStop() {
|
|
865
|
+
this.configWatcher?.();
|
|
866
|
+
this.configWatcher = undefined;
|
|
753
867
|
this.prompts.clear();
|
|
754
868
|
this.setStatus("stopped");
|
|
755
|
-
|
|
869
|
+
logger2.info("[PromptComponent] Stopped");
|
|
756
870
|
}
|
|
757
871
|
getPromptConfig(key, defaultValue) {
|
|
758
872
|
if (this.config && key in this.config) {
|
|
@@ -770,11 +884,11 @@ class PromptComponent extends BaseComponent {
|
|
|
770
884
|
};
|
|
771
885
|
const existing = this.prompts.get(name);
|
|
772
886
|
if (existing && !existing.overridable) {
|
|
773
|
-
|
|
887
|
+
logger2.debug(`[PromptComponent] Skip override for non-overridable prompt: ${name}`);
|
|
774
888
|
return;
|
|
775
889
|
}
|
|
776
890
|
this.prompts.set(name, entry);
|
|
777
|
-
|
|
891
|
+
logger2.debug(`[PromptComponent] Added prompt: ${name} (${source})`);
|
|
778
892
|
}
|
|
779
893
|
get(name) {
|
|
780
894
|
return this.prompts.get(name)?.content;
|
|
@@ -791,6 +905,34 @@ class PromptComponent extends BaseComponent {
|
|
|
791
905
|
list() {
|
|
792
906
|
return Array.from(this.prompts.keys());
|
|
793
907
|
}
|
|
908
|
+
listEntries() {
|
|
909
|
+
return Array.from(this.prompts.values());
|
|
910
|
+
}
|
|
911
|
+
getPromptStore() {
|
|
912
|
+
if (!this.promptStore) {
|
|
913
|
+
this.initPromptStore();
|
|
914
|
+
}
|
|
915
|
+
return this.promptStore;
|
|
916
|
+
}
|
|
917
|
+
getPromptConfigDir() {
|
|
918
|
+
return this.getPromptStore().getConfigDir();
|
|
919
|
+
}
|
|
920
|
+
async savePrompt(name, content) {
|
|
921
|
+
const filePath = await this.getPromptStore().savePrompt(name, content.trim());
|
|
922
|
+
this.add(name, content.trim(), "file");
|
|
923
|
+
const entry = this.prompts.get(name);
|
|
924
|
+
if (entry) {
|
|
925
|
+
entry.filePath = filePath;
|
|
926
|
+
}
|
|
927
|
+
return filePath;
|
|
928
|
+
}
|
|
929
|
+
async deletePromptFile(name) {
|
|
930
|
+
const deleted = await this.getPromptStore().deletePrompt(name);
|
|
931
|
+
if (deleted) {
|
|
932
|
+
this.delete(name);
|
|
933
|
+
}
|
|
934
|
+
return deleted;
|
|
935
|
+
}
|
|
794
936
|
size() {
|
|
795
937
|
return this.prompts.size;
|
|
796
938
|
}
|
|
@@ -799,7 +941,7 @@ class PromptComponent extends BaseComponent {
|
|
|
799
941
|
const targetName = this.has(name) ? name : defaultName;
|
|
800
942
|
const entry = this.prompts.get(targetName);
|
|
801
943
|
if (!entry) {
|
|
802
|
-
|
|
944
|
+
logger2.warn(`[PromptComponent] Prompt not found: ${name}, using fallback`);
|
|
803
945
|
return "You are a helpful assistant.";
|
|
804
946
|
}
|
|
805
947
|
return this.render(entry.content, variables, { name: targetName });
|
|
@@ -819,10 +961,31 @@ class PromptComponent extends BaseComponent {
|
|
|
819
961
|
extractVariables(content) {
|
|
820
962
|
return this.renderer.extractVariables(content);
|
|
821
963
|
}
|
|
964
|
+
initPromptStore() {
|
|
965
|
+
const customDir = this.configComponent?.get?.("prompt.configDir");
|
|
966
|
+
this.promptStore = new PromptStore({
|
|
967
|
+
configDir: typeof customDir === "string" && customDir.length > 0 ? customDir : undefined
|
|
968
|
+
});
|
|
969
|
+
}
|
|
822
970
|
async loadPrompts() {
|
|
823
971
|
await this.loadBuiltInPrompts();
|
|
972
|
+
await this.loadUserPrompts();
|
|
824
973
|
await this.loadExternalPrompts();
|
|
825
974
|
}
|
|
975
|
+
async loadUserPrompts() {
|
|
976
|
+
const store = this.getPromptStore();
|
|
977
|
+
const prompts = await store.loadAll();
|
|
978
|
+
for (const prompt of prompts) {
|
|
979
|
+
this.add(prompt.name, prompt.content, "file");
|
|
980
|
+
const entry = this.prompts.get(prompt.name);
|
|
981
|
+
if (entry) {
|
|
982
|
+
entry.filePath = prompt.filePath;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
if (prompts.length > 0) {
|
|
986
|
+
logger2.info(`[PromptComponent] Loaded ${prompts.length} prompts from ${store.getConfigDir()}`);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
826
989
|
async loadBuiltInPrompts() {
|
|
827
990
|
for (const [name, content] of Object.entries(builtInPrompts)) {
|
|
828
991
|
if (content) {
|
|
@@ -833,10 +996,10 @@ class PromptComponent extends BaseComponent {
|
|
|
833
996
|
overridable: false,
|
|
834
997
|
loadedAt: Date.now()
|
|
835
998
|
});
|
|
836
|
-
|
|
999
|
+
logger2.debug(`[PromptComponent] Loaded built-in prompt: ${name}`);
|
|
837
1000
|
}
|
|
838
1001
|
}
|
|
839
|
-
|
|
1002
|
+
logger2.info(`[PromptComponent] Loaded ${this.prompts.size} built-in prompts`);
|
|
840
1003
|
}
|
|
841
1004
|
async loadExternalPrompts() {
|
|
842
1005
|
const promptPaths = this.getPromptConfig("promptPaths", []);
|
|
@@ -848,22 +1011,22 @@ class PromptComponent extends BaseComponent {
|
|
|
848
1011
|
await this.loadFromDirectory(pathConfig.path, pathConfig.extension || ".md", pathConfig.recursive !== false);
|
|
849
1012
|
}
|
|
850
1013
|
} catch (error) {
|
|
851
|
-
|
|
1014
|
+
logger2.error(`[PromptComponent] Failed to load from ${pathConfig.path}:`, error);
|
|
852
1015
|
}
|
|
853
1016
|
}
|
|
854
1017
|
}
|
|
855
1018
|
async loadFromFile(filePath, name) {
|
|
856
1019
|
try {
|
|
857
|
-
const content = await
|
|
1020
|
+
const content = await readFile2(filePath, "utf-8");
|
|
858
1021
|
const promptName = name || basename(filePath, extname(filePath));
|
|
859
1022
|
this.add(promptName, content.trim(), "file");
|
|
860
1023
|
const entry = this.prompts.get(promptName);
|
|
861
1024
|
if (entry)
|
|
862
1025
|
entry.filePath = filePath;
|
|
863
|
-
|
|
1026
|
+
logger2.debug(`[PromptComponent] Loaded prompt from file: ${filePath}`);
|
|
864
1027
|
return true;
|
|
865
1028
|
} catch (error) {
|
|
866
|
-
|
|
1029
|
+
logger2.error(`[PromptComponent] Failed to load file ${filePath}:`, error);
|
|
867
1030
|
return false;
|
|
868
1031
|
}
|
|
869
1032
|
}
|
|
@@ -874,25 +1037,25 @@ class PromptComponent extends BaseComponent {
|
|
|
874
1037
|
for (const filePath of files) {
|
|
875
1038
|
const relativePath = filePath.replace(directory + "/", "");
|
|
876
1039
|
const promptName = relativePath.replace(/\\/g, "/").replace(new RegExp(escapeRegex2(extension) + "$"), "").replace(/\//g, "-");
|
|
877
|
-
const content = await
|
|
1040
|
+
const content = await readFile2(filePath, "utf-8");
|
|
878
1041
|
this.add(promptName, content.trim(), "directory");
|
|
879
1042
|
const entry = this.prompts.get(promptName);
|
|
880
1043
|
if (entry)
|
|
881
1044
|
entry.filePath = filePath;
|
|
882
1045
|
loaded++;
|
|
883
1046
|
}
|
|
884
|
-
|
|
1047
|
+
logger2.info(`[PromptComponent] Loaded ${loaded} prompts from directory: ${directory}`);
|
|
885
1048
|
} catch (error) {
|
|
886
|
-
|
|
1049
|
+
logger2.error(`[PromptComponent] Failed to load directory ${directory}:`, error);
|
|
887
1050
|
}
|
|
888
1051
|
return loaded;
|
|
889
1052
|
}
|
|
890
1053
|
async findFiles(dir, extension, recursive) {
|
|
891
1054
|
const files = [];
|
|
892
1055
|
try {
|
|
893
|
-
const entries = await
|
|
1056
|
+
const entries = await readdir2(dir, { withFileTypes: true });
|
|
894
1057
|
for (const entry of entries) {
|
|
895
|
-
const fullPath =
|
|
1058
|
+
const fullPath = join2(dir, entry.name);
|
|
896
1059
|
if (entry.isDirectory() && recursive) {
|
|
897
1060
|
const subFiles = await this.findFiles(fullPath, extension, true);
|
|
898
1061
|
files.push(...subFiles);
|
|
@@ -901,7 +1064,7 @@ class PromptComponent extends BaseComponent {
|
|
|
901
1064
|
}
|
|
902
1065
|
}
|
|
903
1066
|
} catch (error) {
|
|
904
|
-
|
|
1067
|
+
logger2.warn(`[PromptComponent] Cannot read directory ${dir}:`, error);
|
|
905
1068
|
}
|
|
906
1069
|
return files;
|
|
907
1070
|
}
|
|
@@ -919,4 +1082,4 @@ function escapeRegex2(str) {
|
|
|
919
1082
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
920
1083
|
}
|
|
921
1084
|
|
|
922
|
-
export { PromptPathSchema, PromptConfigSchema, PromptRenderer, getBuiltInPromptNames, getBuiltInPrompt, PromptComponent };
|
|
1085
|
+
export { PromptPathSchema, PromptConfigSchema, PromptRenderer, getBuiltInPromptNames, getBuiltInPrompt, PromptStore, PromptComponent };
|