principles-disciple 1.7.4 → 1.7.5
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/commands/focus.js +30 -155
- package/dist/constants/diagnostician.d.ts +16 -0
- package/dist/constants/diagnostician.js +60 -0
- package/dist/constants/tools.d.ts +2 -2
- package/dist/constants/tools.js +1 -1
- package/dist/core/config.d.ts +12 -0
- package/dist/core/config.js +7 -0
- package/dist/core/evolution-engine.js +1 -1
- package/dist/core/focus-history.d.ts +92 -0
- package/dist/core/focus-history.js +490 -0
- package/dist/core/init.js +2 -2
- package/dist/core/profile.js +1 -1
- package/dist/hooks/gate.js +3 -3
- package/dist/hooks/prompt.js +73 -22
- package/dist/hooks/subagent.js +1 -2
- package/dist/http/principles-console-route.d.ts +7 -0
- package/dist/http/principles-console-route.js +243 -1
- package/dist/index.js +0 -2
- package/dist/service/central-database.d.ts +104 -0
- package/dist/service/central-database.js +648 -0
- package/dist/service/evolution-worker.js +3 -3
- package/dist/tools/deep-reflect.js +1 -2
- package/dist/utils/subagent-probe.d.ts +11 -0
- package/dist/utils/subagent-probe.js +46 -1
- package/package.json +2 -1
- package/templates/langs/en/core/AGENTS.md +1 -1
- package/templates/langs/en/core/TOOLS.md +1 -1
- package/templates/langs/zh/core/AGENTS.md +1 -1
- package/templates/langs/zh/core/TOOLS.md +1 -1
- package/{agents/auditor.md → templates/langs/zh/skills/pd-auditor/SKILL.md} +3 -3
- package/{agents/diagnostician.md → templates/langs/zh/skills/pd-diagnostician/SKILL.md} +39 -29
- package/{agents/explorer.md → templates/langs/zh/skills/pd-explorer/SKILL.md} +3 -3
- package/{agents/implementer.md → templates/langs/zh/skills/pd-implementer/SKILL.md} +3 -3
- package/{agents/planner.md → templates/langs/zh/skills/pd-planner/SKILL.md} +3 -3
- package/{agents/reporter.md → templates/langs/zh/skills/pd-reporter/SKILL.md} +3 -3
- package/{agents/reviewer.md → templates/langs/zh/skills/pd-reviewer/SKILL.md} +3 -3
- package/dist/core/agent-loader.d.ts +0 -44
- package/dist/core/agent-loader.js +0 -147
- package/dist/tools/agent-spawn.d.ts +0 -54
- package/dist/tools/agent-spawn.js +0 -456
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* This utility provides a reliable way to detect which mode we're in.
|
|
9
9
|
*/
|
|
10
|
+
import type { OpenClawPluginApi } from '../openclaw-sdk.js';
|
|
11
|
+
type SubagentRuntime = NonNullable<OpenClawPluginApi['runtime']>['subagent'];
|
|
10
12
|
/**
|
|
11
13
|
* Check if the subagent runtime is actually functional.
|
|
12
14
|
*
|
|
@@ -21,3 +23,12 @@
|
|
|
21
23
|
export declare function isSubagentRuntimeAvailable(subagent: {
|
|
22
24
|
run?: unknown;
|
|
23
25
|
} | undefined): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Get the actual subagent runtime, preferring the global gateway subagent
|
|
28
|
+
* if the passed one is not available.
|
|
29
|
+
*
|
|
30
|
+
* This is useful for cases where the plugin was loaded with allowGatewaySubagentBinding
|
|
31
|
+
* but the late-binding proxy isn't resolving correctly.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getAvailableSubagentRuntime(subagent: SubagentRuntime | undefined): SubagentRuntime | undefined;
|
|
34
|
+
export {};
|
|
@@ -7,6 +7,22 @@
|
|
|
7
7
|
*
|
|
8
8
|
* This utility provides a reliable way to detect which mode we're in.
|
|
9
9
|
*/
|
|
10
|
+
/**
|
|
11
|
+
* Try to access the global gateway subagent runtime.
|
|
12
|
+
* This is a fallback for cases where the plugin was loaded with
|
|
13
|
+
* allowGatewaySubagentBinding but the late-binding proxy isn't working.
|
|
14
|
+
*/
|
|
15
|
+
function getGlobalGatewaySubagent() {
|
|
16
|
+
try {
|
|
17
|
+
// Access the global symbol that OpenClaw uses for gateway subagent
|
|
18
|
+
const symbol = Symbol.for('openclaw.plugin.gatewaySubagentRuntime');
|
|
19
|
+
const globalState = globalThis[symbol];
|
|
20
|
+
return globalState?.subagent ?? null;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
10
26
|
/**
|
|
11
27
|
* Check if the subagent runtime is actually functional.
|
|
12
28
|
*
|
|
@@ -27,10 +43,39 @@ export function isSubagentRuntimeAvailable(subagent) {
|
|
|
27
43
|
return false;
|
|
28
44
|
// In gateway mode, methods are AsyncFunction instances
|
|
29
45
|
// In embedded mode, methods are regular Function instances that throw
|
|
30
|
-
|
|
46
|
+
const isAsync = runFn.constructor?.name === 'AsyncFunction';
|
|
47
|
+
if (isAsync)
|
|
48
|
+
return true;
|
|
49
|
+
// Fallback: Check if it's a Proxy that might late-bind to the gateway subagent
|
|
50
|
+
// This handles the case where the plugin was loaded with allowGatewaySubagentBinding
|
|
51
|
+
// but the proxy hasn't resolved yet
|
|
52
|
+
const globalGateway = getGlobalGatewaySubagent();
|
|
53
|
+
if (globalGateway && typeof globalGateway.run === 'function') {
|
|
54
|
+
return globalGateway.run.constructor?.name === 'AsyncFunction';
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
31
57
|
}
|
|
32
58
|
catch {
|
|
33
59
|
// Any error means unavailable
|
|
34
60
|
return false;
|
|
35
61
|
}
|
|
36
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the actual subagent runtime, preferring the global gateway subagent
|
|
65
|
+
* if the passed one is not available.
|
|
66
|
+
*
|
|
67
|
+
* This is useful for cases where the plugin was loaded with allowGatewaySubagentBinding
|
|
68
|
+
* but the late-binding proxy isn't resolving correctly.
|
|
69
|
+
*/
|
|
70
|
+
export function getAvailableSubagentRuntime(subagent) {
|
|
71
|
+
// First check if the passed subagent is available
|
|
72
|
+
if (isSubagentRuntimeAvailable(subagent)) {
|
|
73
|
+
return subagent;
|
|
74
|
+
}
|
|
75
|
+
// Fallback to global gateway subagent
|
|
76
|
+
const globalGateway = getGlobalGatewaySubagent();
|
|
77
|
+
if (globalGateway && isSubagentRuntimeAvailable(globalGateway)) {
|
|
78
|
+
return globalGateway;
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "principles-disciple",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.5",
|
|
4
4
|
"description": "Native OpenClaw plugin for Principles Disciple",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@sinclair/typebox": "^0.34.48",
|
|
68
68
|
"better-sqlite3": "^12.8.0",
|
|
69
|
+
"lucide-react": "^0.468.0",
|
|
69
70
|
"micromatch": "^4.0.8",
|
|
70
71
|
"react": "^19.2.0",
|
|
71
72
|
"react-dom": "^19.2.0",
|
|
@@ -213,6 +213,6 @@ When completing any coding task (via AI coding assistant or direct):
|
|
|
213
213
|
Use this to avoid confusing peer agents with Principles internal workers:
|
|
214
214
|
|
|
215
215
|
- **Peer agents / peer sessions**: `agents_list`, `sessions_list`, `sessions_send`, `sessions_spawn`
|
|
216
|
-
- **Internal workers** (for example `diagnostician`, `explorer`):
|
|
216
|
+
- **Internal workers** (for example `diagnostician`, `explorer`): use `sessions_spawn with pd-diagnostician/pd-explorer skills`
|
|
217
217
|
- **Inspect internal workers**: use `subagents`
|
|
218
218
|
- **Do not** treat `diagnostician` or `explorer` as peer session targets
|
|
@@ -57,6 +57,6 @@ Tool returns: Blind Spots → Risk Warnings → Alternative Approaches → Recom
|
|
|
57
57
|
## 4. Agent Routing Clarification
|
|
58
58
|
|
|
59
59
|
- `agents_list`, `sessions_list`, `sessions_send`, and `sessions_spawn` are for peer agents and peer sessions
|
|
60
|
-
- `
|
|
60
|
+
- Use `sessions_spawn` with `pd-diagnostician` or `pd-explorer` skills to start Principles internal workers
|
|
61
61
|
- `subagents` inspects already-started internal workers and their outputs
|
|
62
62
|
- Do not use peer-session tools to pretend an internal worker is a peer agent
|
|
@@ -214,6 +214,6 @@ _This folder is home. Treat it that way._
|
|
|
214
214
|
用下面这几条避免把同级代理和 Principles 内部 worker 混淆:
|
|
215
215
|
|
|
216
216
|
- **同级代理 / 同级会话**:`agents_list`、`sessions_list`、`sessions_send`、`sessions_spawn`
|
|
217
|
-
- **内部 worker**(例如 `diagnostician`、`explorer`):使用 `
|
|
217
|
+
- **内部 worker**(例如 `diagnostician`、`explorer`):使用 `sessions_spawn` 配合 `pd-diagnostician/pd-explorer` skill 启动
|
|
218
218
|
- **查询内部 worker**:使用 `subagents`
|
|
219
219
|
- **不要**把 `diagnostician` 或 `explorer` 当成同级 peer session 目标
|
|
@@ -57,6 +57,6 @@ deep_reflect(
|
|
|
57
57
|
## 4. 智能体路由澄清
|
|
58
58
|
|
|
59
59
|
- `agents_list`、`sessions_list`、`sessions_send`、`sessions_spawn` 用于同级代理和同级会话
|
|
60
|
-
- `
|
|
60
|
+
- 使用 `sessions_spawn` 配合 `pd-diagnostician/pd-explorer` skill 启动 Principles 内部 worker,例如 `diagnostician`、`explorer`
|
|
61
61
|
- `subagents` 用于查看已启动内部 worker 的状态和输出
|
|
62
62
|
- 不要用同级会话工具把内部 worker 伪装成同级代理
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description:
|
|
4
|
-
|
|
2
|
+
name: pd-diagnostician
|
|
3
|
+
description: 根因分析智能体。使用 verb/adjective + 5 Whys 方法进行系统性诊断。当需要分析 Pain 信号、工具失败、或系统性问题根因时使用。
|
|
4
|
+
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Diagnostician - 根因分析智能体
|
|
@@ -21,44 +21,54 @@ permissionMode: allowSubagentSpawn
|
|
|
21
21
|
- `agent_id`: 智能体 ID(如 main, builder, diagnostician 等)
|
|
22
22
|
- `pain_timestamp`: 疼痛发生时间
|
|
23
23
|
|
|
24
|
+
**🔄 渐进式信息获取策略**(按优先级执行,任一成功即可):
|
|
25
|
+
|
|
26
|
+
| 优先级 | 数据源 | 条件 | 操作 |
|
|
27
|
+
|--------|--------|------|------|
|
|
28
|
+
| P1 | JSONL 会话文件 | session_id 存在且文件可读 | 读取完整对话 |
|
|
29
|
+
| P2 | task 内嵌上下文 | task 包含 "Recent Conversation Context" | 直接使用 |
|
|
30
|
+
| P3 | 主动证据收集 | 以上都不可用 | 跳到 Phase 1 增强 |
|
|
31
|
+
|
|
24
32
|
**执行步骤**:
|
|
25
33
|
|
|
26
34
|
1. **解析 task 字符串**,提取 `session_id` 和 `agent_id`(如果存在)
|
|
27
|
-
2.
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"max_summary_length": 3000
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
```
|
|
35
|
+
2. **尝试读取 JSONL**(仅当 session_id 存在时):
|
|
36
|
+
- 路径: `~/.openclaw/agents/{agent_id}/sessions/{session_id}.jsonl`
|
|
37
|
+
- 如果文件不存在或不可读,记录 `jsonl_available: false`
|
|
38
|
+
3. **检查 task 内嵌上下文**:
|
|
39
|
+
- 查找 `**Recent Conversation Context**:` 标记
|
|
40
|
+
- 如果存在,提取并使用
|
|
41
|
+
4. **降级处理**(当以上都不可用时):
|
|
42
|
+
- 不要停止!继续执行 Phase 1
|
|
43
|
+
- 在 Phase 1 中 **主动扩展证据收集范围**:
|
|
44
|
+
- 搜索 `.state/logs/events.jsonl` 中与 pain 相关的事件
|
|
45
|
+
- 根据 `reason` 字段中的关键词搜索代码库
|
|
46
|
+
- 读取 `reason` 中提到的文件路径
|
|
47
|
+
- 在输出中标注 `context_source: "inferred"`
|
|
48
|
+
|
|
49
|
+
**智能过滤**(JSONL 读取成功时):
|
|
50
|
+
- 忽略 `toolResult` 类型(数据太大)
|
|
51
|
+
- 忽略 `thinking` 类型
|
|
52
|
+
- 只保留 `user` 和 `assistant` 的 `text` 内容
|
|
53
|
+
- 每条消息截断到 500 字符
|
|
51
54
|
|
|
52
55
|
**输出字段**:
|
|
53
56
|
```json
|
|
54
57
|
{
|
|
55
58
|
"phase": "context_extraction",
|
|
56
|
-
"session_id": "xxx",
|
|
59
|
+
"session_id": "xxx或null",
|
|
57
60
|
"agent_id": "main",
|
|
58
|
-
"
|
|
61
|
+
"context_source": "jsonl|task_embedded|inferred",
|
|
62
|
+
"jsonl_available": true,
|
|
63
|
+
"conversation_summary": "[用户]: ...\n[助手]: ... 或 基于推断的上下文描述"
|
|
59
64
|
}
|
|
60
65
|
```
|
|
61
66
|
|
|
67
|
+
**⚠️ 重要提示**:
|
|
68
|
+
- 即使完全没有对话上下文,也要继续诊断!
|
|
69
|
+
- 利用 `reason` 字段中的错误信息进行代码搜索
|
|
70
|
+
- 发挥你的智能,从代码和日志中推断问题背景
|
|
71
|
+
|
|
62
72
|
---
|
|
63
73
|
|
|
64
74
|
### Phase 1: 证据收集 [必执行]
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Definition Loader
|
|
3
|
-
*
|
|
4
|
-
* Parses agent definitions from agents/*.md files.
|
|
5
|
-
* These definitions are used to construct extraSystemPrompt for subagent runs.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Parsed agent definition from markdown file
|
|
9
|
-
*/
|
|
10
|
-
export interface AgentDefinition {
|
|
11
|
-
/** Agent identifier (e.g., 'explorer', 'diagnostician') */
|
|
12
|
-
name: string;
|
|
13
|
-
/** Human-readable description */
|
|
14
|
-
description: string;
|
|
15
|
-
/** The markdown body (system prompt for subagent) */
|
|
16
|
-
systemPrompt: string;
|
|
17
|
-
/** Tools the agent can use (informational, not enforced by OpenClaw) */
|
|
18
|
-
tools?: string[];
|
|
19
|
-
/** Preferred model (informational, OpenClaw subagents use parent model) */
|
|
20
|
-
model?: string;
|
|
21
|
-
/** Permission mode (informational) */
|
|
22
|
-
permissionMode?: string;
|
|
23
|
-
/** Associated skills */
|
|
24
|
-
skills?: string[];
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Load agent definition by name
|
|
28
|
-
*
|
|
29
|
-
* @param name - Agent name (e.g., 'explorer', 'diagnostician')
|
|
30
|
-
* @returns Agent definition or null if not found
|
|
31
|
-
*/
|
|
32
|
-
export declare function loadAgentDefinition(name: string): AgentDefinition | null;
|
|
33
|
-
/**
|
|
34
|
-
* List all available agents
|
|
35
|
-
*
|
|
36
|
-
* @returns Array of agent names
|
|
37
|
-
*/
|
|
38
|
-
export declare function listAvailableAgents(): string[];
|
|
39
|
-
/**
|
|
40
|
-
* Load all agent definitions
|
|
41
|
-
*
|
|
42
|
-
* @returns Map of agent name to definition
|
|
43
|
-
*/
|
|
44
|
-
export declare function loadAllAgents(): Map<string, AgentDefinition>;
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Definition Loader
|
|
3
|
-
*
|
|
4
|
-
* Parses agent definitions from agents/*.md files.
|
|
5
|
-
* These definitions are used to construct extraSystemPrompt for subagent runs.
|
|
6
|
-
*/
|
|
7
|
-
import * as fs from 'fs';
|
|
8
|
-
import * as path from 'path';
|
|
9
|
-
/**
|
|
10
|
-
* Parse markdown file with YAML frontmatter
|
|
11
|
-
*/
|
|
12
|
-
function parseMarkdown(content) {
|
|
13
|
-
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
14
|
-
if (!match) {
|
|
15
|
-
return { frontmatter: {}, body: content };
|
|
16
|
-
}
|
|
17
|
-
const frontmatter = {};
|
|
18
|
-
const frontmatterText = match[1];
|
|
19
|
-
const body = match[2];
|
|
20
|
-
// Simple YAML-like parsing
|
|
21
|
-
let currentKey = '';
|
|
22
|
-
let currentArray = null;
|
|
23
|
-
frontmatterText.split('\n').forEach(line => {
|
|
24
|
-
// Array item
|
|
25
|
-
if (line.match(/^\s*-\s+/)) {
|
|
26
|
-
if (currentArray !== null) {
|
|
27
|
-
const value = line.replace(/^\s*-\s+/, '').trim();
|
|
28
|
-
currentArray.push(value);
|
|
29
|
-
}
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
// Key-value pair
|
|
33
|
-
const colonIndex = line.indexOf(':');
|
|
34
|
-
if (colonIndex > 0) {
|
|
35
|
-
const key = line.slice(0, colonIndex).trim();
|
|
36
|
-
const value = line.slice(colonIndex + 1).trim();
|
|
37
|
-
if (value === '') {
|
|
38
|
-
// Start of array
|
|
39
|
-
currentKey = key;
|
|
40
|
-
currentArray = [];
|
|
41
|
-
frontmatter[key] = currentArray;
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
// Simple value
|
|
45
|
-
currentKey = '';
|
|
46
|
-
currentArray = null;
|
|
47
|
-
frontmatter[key] = value;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
return { frontmatter, body };
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Resolve the agents directory path
|
|
55
|
-
* Handles both development and installed scenarios
|
|
56
|
-
*/
|
|
57
|
-
function resolveAgentsDir() {
|
|
58
|
-
// Try multiple locations
|
|
59
|
-
const possiblePaths = [
|
|
60
|
-
// Development: relative to dist/core/
|
|
61
|
-
path.resolve(__dirname, '../../agents'),
|
|
62
|
-
// Installed: relative to extension root
|
|
63
|
-
path.resolve(__dirname, '../agents'),
|
|
64
|
-
// Absolute fallback
|
|
65
|
-
path.resolve(process.cwd(), 'agents'),
|
|
66
|
-
];
|
|
67
|
-
for (const p of possiblePaths) {
|
|
68
|
-
if (fs.existsSync(p)) {
|
|
69
|
-
return p;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Return default (may not exist)
|
|
73
|
-
return possiblePaths[0];
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Load agent definition by name
|
|
77
|
-
*
|
|
78
|
-
* @param name - Agent name (e.g., 'explorer', 'diagnostician')
|
|
79
|
-
* @returns Agent definition or null if not found
|
|
80
|
-
*/
|
|
81
|
-
export function loadAgentDefinition(name) {
|
|
82
|
-
const agentsDir = resolveAgentsDir();
|
|
83
|
-
const mdPath = path.join(agentsDir, `${name}.md`);
|
|
84
|
-
if (!fs.existsSync(mdPath)) {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
try {
|
|
88
|
-
const content = fs.readFileSync(mdPath, 'utf8');
|
|
89
|
-
const { frontmatter, body } = parseMarkdown(content);
|
|
90
|
-
// Extract tools as array (support both string and array formats)
|
|
91
|
-
let tools;
|
|
92
|
-
if (Array.isArray(frontmatter.tools)) {
|
|
93
|
-
tools = frontmatter.tools;
|
|
94
|
-
}
|
|
95
|
-
else if (typeof frontmatter.tools === 'string') {
|
|
96
|
-
tools = frontmatter.tools.split(',').map(s => s.trim()).filter(Boolean);
|
|
97
|
-
}
|
|
98
|
-
return {
|
|
99
|
-
name: frontmatter.name || name,
|
|
100
|
-
description: frontmatter.description || '',
|
|
101
|
-
systemPrompt: body.trim(),
|
|
102
|
-
tools,
|
|
103
|
-
model: frontmatter.model,
|
|
104
|
-
permissionMode: frontmatter.permissionMode,
|
|
105
|
-
skills: frontmatter.skills,
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
console.error(`[AgentLoader] Failed to load agent ${name}:`, err);
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* List all available agents
|
|
115
|
-
*
|
|
116
|
-
* @returns Array of agent names
|
|
117
|
-
*/
|
|
118
|
-
export function listAvailableAgents() {
|
|
119
|
-
const agentsDir = resolveAgentsDir();
|
|
120
|
-
if (!fs.existsSync(agentsDir)) {
|
|
121
|
-
return [];
|
|
122
|
-
}
|
|
123
|
-
try {
|
|
124
|
-
const files = fs.readdirSync(agentsDir);
|
|
125
|
-
return files
|
|
126
|
-
.filter(f => f.endsWith('.md'))
|
|
127
|
-
.map(f => path.basename(f, '.md'));
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
return [];
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Load all agent definitions
|
|
135
|
-
*
|
|
136
|
-
* @returns Map of agent name to definition
|
|
137
|
-
*/
|
|
138
|
-
export function loadAllAgents() {
|
|
139
|
-
const agents = new Map();
|
|
140
|
-
for (const name of listAvailableAgents()) {
|
|
141
|
-
const def = loadAgentDefinition(name);
|
|
142
|
-
if (def) {
|
|
143
|
-
agents.set(name, def);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return agents;
|
|
147
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Spawn Tool
|
|
3
|
-
*
|
|
4
|
-
* Provides a tool for spawning subagents with predefined agent definitions.
|
|
5
|
-
* Uses the low-level OpenClaw Subagent API.
|
|
6
|
-
*/
|
|
7
|
-
import type { OpenClawPluginApi } from '../openclaw-sdk.js';
|
|
8
|
-
/**
|
|
9
|
-
* Create Agent Spawn Tool
|
|
10
|
-
*
|
|
11
|
-
* Uses factory pattern to capture `api` in closure, following OpenClaw plugin SDK conventions.
|
|
12
|
-
* The execute signature must be: async (_toolCallId: string, rawParams: Record<string, unknown>)
|
|
13
|
-
*/
|
|
14
|
-
export declare function createAgentSpawnTool(api: OpenClawPluginApi): {
|
|
15
|
-
name: string;
|
|
16
|
-
description: string;
|
|
17
|
-
parameters: import("@sinclair/typebox").TObject<{
|
|
18
|
-
agentType: import("@sinclair/typebox").TString;
|
|
19
|
-
task: import("@sinclair/typebox").TString;
|
|
20
|
-
runInBackground: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
21
|
-
}>;
|
|
22
|
-
/**
|
|
23
|
-
* Execution logic for the agent spawn tool
|
|
24
|
-
*
|
|
25
|
-
* OpenClaw tool execute signature:
|
|
26
|
-
* - First parameter: _toolCallId (string) - the tool call ID
|
|
27
|
-
* - Second parameter: rawParams (Record<string, unknown>) - the actual parameters
|
|
28
|
-
* - Third parameter (optional): signal (AbortSignal) - for cancellation
|
|
29
|
-
*/
|
|
30
|
-
execute(_toolCallId: string, rawParams: Record<string, unknown>): Promise<{
|
|
31
|
-
content: Array<{
|
|
32
|
-
type: string;
|
|
33
|
-
text: string;
|
|
34
|
-
}>;
|
|
35
|
-
}>;
|
|
36
|
-
};
|
|
37
|
-
export declare const agentSpawnTool: {
|
|
38
|
-
name: string;
|
|
39
|
-
description: string;
|
|
40
|
-
parameters: import("@sinclair/typebox").TObject<{
|
|
41
|
-
agentType: import("@sinclair/typebox").TString;
|
|
42
|
-
task: import("@sinclair/typebox").TString;
|
|
43
|
-
runInBackground: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
44
|
-
}>;
|
|
45
|
-
execute: () => never;
|
|
46
|
-
};
|
|
47
|
-
/**
|
|
48
|
-
* Batch spawn multiple agents in sequence
|
|
49
|
-
* Useful for evolution workflow
|
|
50
|
-
*/
|
|
51
|
-
export declare function spawnAgentSequence(agents: Array<{
|
|
52
|
-
type: string;
|
|
53
|
-
task: string;
|
|
54
|
-
}>, api: OpenClawPluginApi, onProgress?: (agent: string, result: string) => void): Promise<Map<string, string>>;
|