@synergenius/flow-weaver-pack-weaver 0.9.3 → 0.9.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/bot/ansi.d.ts +13 -0
- package/dist/bot/ansi.d.ts.map +1 -0
- package/dist/bot/ansi.js +13 -0
- package/dist/bot/ansi.js.map +1 -0
- package/dist/bot/assistant-core.d.ts.map +1 -1
- package/dist/bot/assistant-core.js +68 -32
- package/dist/bot/assistant-core.js.map +1 -1
- package/dist/bot/assistant-tools.d.ts +3 -2
- package/dist/bot/assistant-tools.d.ts.map +1 -1
- package/dist/bot/assistant-tools.js +6 -284
- package/dist/bot/assistant-tools.js.map +1 -1
- package/dist/bot/conversation-store.d.ts.map +1 -1
- package/dist/bot/conversation-store.js +1 -1
- package/dist/bot/conversation-store.js.map +1 -1
- package/dist/bot/error-classifier.d.ts +27 -0
- package/dist/bot/error-classifier.d.ts.map +1 -0
- package/dist/bot/error-classifier.js +71 -0
- package/dist/bot/error-classifier.js.map +1 -0
- package/dist/bot/error-guide.d.ts +2 -7
- package/dist/bot/error-guide.d.ts.map +1 -1
- package/dist/bot/error-guide.js +2 -31
- package/dist/bot/error-guide.js.map +1 -1
- package/dist/bot/paths.d.ts +11 -0
- package/dist/bot/paths.d.ts.map +1 -0
- package/dist/bot/paths.js +26 -0
- package/dist/bot/paths.js.map +1 -0
- package/dist/bot/response-formatter.d.ts +15 -0
- package/dist/bot/response-formatter.d.ts.map +1 -0
- package/dist/bot/response-formatter.js +40 -0
- package/dist/bot/response-formatter.js.map +1 -0
- package/dist/bot/retry-utils.d.ts +2 -16
- package/dist/bot/retry-utils.d.ts.map +1 -1
- package/dist/bot/retry-utils.js +2 -61
- package/dist/bot/retry-utils.js.map +1 -1
- package/dist/bot/rich-input.d.ts +39 -0
- package/dist/bot/rich-input.d.ts.map +1 -0
- package/dist/bot/rich-input.js +308 -0
- package/dist/bot/rich-input.js.map +1 -0
- package/dist/bot/safety.d.ts +10 -0
- package/dist/bot/safety.d.ts.map +1 -0
- package/dist/bot/safety.js +14 -0
- package/dist/bot/safety.js.map +1 -0
- package/dist/bot/slash-commands.d.ts +20 -0
- package/dist/bot/slash-commands.d.ts.map +1 -0
- package/dist/bot/slash-commands.js +93 -0
- package/dist/bot/slash-commands.js.map +1 -0
- package/dist/bot/steering.js +2 -2
- package/dist/bot/steering.js.map +1 -1
- package/dist/bot/task-queue.d.ts.map +1 -1
- package/dist/bot/task-queue.js +2 -15
- package/dist/bot/task-queue.js.map +1 -1
- package/dist/bot/terminal-renderer.d.ts.map +1 -1
- package/dist/bot/terminal-renderer.js +12 -13
- package/dist/bot/terminal-renderer.js.map +1 -1
- package/dist/bot/tool-registry.d.ts +24 -0
- package/dist/bot/tool-registry.d.ts.map +1 -0
- package/dist/bot/tool-registry.js +458 -0
- package/dist/bot/tool-registry.js.map +1 -0
- package/dist/bot/weaver-tools.d.ts +2 -2
- package/dist/bot/weaver-tools.d.ts.map +1 -1
- package/dist/bot/weaver-tools.js +4 -95
- package/dist/bot/weaver-tools.js.map +1 -1
- package/dist/cli-handlers.d.ts.map +1 -1
- package/dist/cli-handlers.js +1 -2
- package/dist/cli-handlers.js.map +1 -1
- package/dist/node-types/agent-execute.d.ts.map +1 -1
- package/dist/node-types/agent-execute.js +4 -8
- package/dist/node-types/agent-execute.js.map +1 -1
- package/flowweaver.manifest.json +1 -1
- package/package.json +1 -1
- package/src/bot/ansi.ts +12 -0
- package/src/bot/assistant-core.ts +70 -33
- package/src/bot/assistant-tools.ts +7 -294
- package/src/bot/conversation-store.ts +1 -1
- package/src/bot/error-classifier.ts +90 -0
- package/src/bot/error-guide.ts +2 -32
- package/src/bot/paths.ts +27 -0
- package/src/bot/response-formatter.ts +42 -0
- package/src/bot/retry-utils.ts +2 -74
- package/src/bot/rich-input.ts +307 -0
- package/src/bot/safety.ts +16 -0
- package/src/bot/slash-commands.ts +114 -0
- package/src/bot/steering.ts +2 -2
- package/src/bot/task-queue.ts +2 -16
- package/src/bot/terminal-renderer.ts +11 -14
- package/src/bot/tool-registry.ts +477 -0
- package/src/bot/weaver-tools.ts +4 -95
- package/src/cli-handlers.ts +1 -2
- package/src/node-types/agent-execute.ts +3 -6
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { ToolExecutor } from '@synergenius/flow-weaver/agent';
|
|
2
|
+
import { c } from './ansi.js';
|
|
3
|
+
|
|
4
|
+
export interface SlashContext {
|
|
5
|
+
executor: ToolExecutor;
|
|
6
|
+
out: (s: string) => void;
|
|
7
|
+
projectDir: string;
|
|
8
|
+
conversationId?: string;
|
|
9
|
+
onClear?: () => void;
|
|
10
|
+
onExit?: () => void;
|
|
11
|
+
onNew?: () => void;
|
|
12
|
+
onVerbose?: () => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SlashCommand {
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
handler: (ctx: SlashContext, args: string) => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const SLASH_COMMANDS: SlashCommand[] = [
|
|
22
|
+
{
|
|
23
|
+
name: '/help',
|
|
24
|
+
description: 'Show available commands',
|
|
25
|
+
handler: async (ctx) => {
|
|
26
|
+
ctx.out('\n Available commands:\n');
|
|
27
|
+
for (const cmd of SLASH_COMMANDS) {
|
|
28
|
+
ctx.out(` ${c.cyan(cmd.name.padEnd(12))} ${c.dim(cmd.description)}\n`);
|
|
29
|
+
}
|
|
30
|
+
ctx.out('\n');
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: '/status',
|
|
35
|
+
description: 'Show bots, queue, and conversation summary',
|
|
36
|
+
handler: async (ctx) => {
|
|
37
|
+
const bots = await ctx.executor('bot_list', {});
|
|
38
|
+
const summary = await ctx.executor('conversation_summary', {});
|
|
39
|
+
ctx.out(`\n ${bots.result}\n ${summary.result}\n\n`);
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: '/bots',
|
|
44
|
+
description: 'List running bots',
|
|
45
|
+
handler: async (ctx) => {
|
|
46
|
+
const result = await ctx.executor('bot_list', {});
|
|
47
|
+
ctx.out(`\n ${result.result}\n\n`);
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: '/clear',
|
|
52
|
+
description: 'Clear screen and start new conversation',
|
|
53
|
+
handler: async (ctx) => {
|
|
54
|
+
process.stderr.write('\x1b[2J\x1b[H');
|
|
55
|
+
ctx.onClear?.();
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: '/exit',
|
|
60
|
+
description: 'Exit the assistant',
|
|
61
|
+
handler: async (ctx) => {
|
|
62
|
+
ctx.onExit?.();
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: '/new',
|
|
67
|
+
description: 'Start a new conversation',
|
|
68
|
+
handler: async (ctx) => {
|
|
69
|
+
ctx.onNew?.();
|
|
70
|
+
ctx.out(`\n ${c.dim('New conversation started.')}\n\n`);
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: '/list',
|
|
75
|
+
description: 'List saved conversations',
|
|
76
|
+
handler: async (ctx) => {
|
|
77
|
+
const result = await ctx.executor('conversation_list', {});
|
|
78
|
+
ctx.out(`\n ${result.result}\n\n`);
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: '/verbose',
|
|
83
|
+
description: 'Toggle verbose mode (show AI thinking)',
|
|
84
|
+
handler: async (ctx) => {
|
|
85
|
+
ctx.onVerbose?.();
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: '/history',
|
|
90
|
+
description: 'Show conversation history summary',
|
|
91
|
+
handler: async (ctx) => {
|
|
92
|
+
const result = await ctx.executor('conversation_summary', {});
|
|
93
|
+
ctx.out(`\n ${result.result}\n\n`);
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
export function getSlashCompletions(partial: string): string[] {
|
|
99
|
+
if (!partial.startsWith('/')) return [];
|
|
100
|
+
return SLASH_COMMANDS
|
|
101
|
+
.filter(cmd => cmd.name.startsWith(partial))
|
|
102
|
+
.map(cmd => cmd.name);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export async function handleSlashCommand(
|
|
106
|
+
input: string,
|
|
107
|
+
ctx: SlashContext,
|
|
108
|
+
): Promise<boolean> {
|
|
109
|
+
const [name, ...rest] = input.split(' ');
|
|
110
|
+
const cmd = SLASH_COMMANDS.find(c => c.name === name);
|
|
111
|
+
if (!cmd) return false;
|
|
112
|
+
await cmd.handler(ctx, rest.join(' '));
|
|
113
|
+
return true;
|
|
114
|
+
}
|
package/src/bot/steering.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import * as os from 'node:os';
|
|
4
3
|
import { withFileLock } from './file-lock.js';
|
|
4
|
+
import { resolveWeaverDir } from './paths.js';
|
|
5
5
|
|
|
6
6
|
export interface SteeringCommand {
|
|
7
7
|
command: 'pause' | 'resume' | 'cancel' | 'redirect' | 'queue';
|
|
@@ -13,7 +13,7 @@ export class SteeringController {
|
|
|
13
13
|
private controlPath: string;
|
|
14
14
|
|
|
15
15
|
constructor(controlDir?: string) {
|
|
16
|
-
const dir = controlDir ??
|
|
16
|
+
const dir = controlDir ?? resolveWeaverDir();
|
|
17
17
|
this.controlPath = path.join(dir, 'control.json');
|
|
18
18
|
}
|
|
19
19
|
|
package/src/bot/task-queue.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import * as os from 'node:os';
|
|
4
3
|
import * as crypto from 'node:crypto';
|
|
5
4
|
import { withFileLock } from './file-lock.js';
|
|
6
5
|
import { parseNdjson } from './safe-json.js';
|
|
6
|
+
import { resolveWeaverDir } from './paths.js';
|
|
7
7
|
|
|
8
8
|
export interface QueuedTask {
|
|
9
9
|
id: string;
|
|
@@ -28,25 +28,11 @@ const MAX_PENDING = 200;
|
|
|
28
28
|
/** Don't re-queue tasks completed within this window (ms). */
|
|
29
29
|
const CYCLE_DEDUP_WINDOW = 3600_000; // 1 hour
|
|
30
30
|
|
|
31
|
-
/**
|
|
32
|
-
* Hash a project directory path into a short filesystem-safe string.
|
|
33
|
-
* Used for per-project queue isolation.
|
|
34
|
-
*/
|
|
35
|
-
function hashDir(dir: string): string {
|
|
36
|
-
return crypto.createHash('sha256').update(dir).digest('hex').slice(0, 8);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
31
|
export class TaskQueue {
|
|
40
32
|
readonly filePath: string;
|
|
41
33
|
|
|
42
34
|
constructor(dir?: string) {
|
|
43
|
-
|
|
44
|
-
const projectDir = process.env.WEAVER_PROJECT_DIR;
|
|
45
|
-
const base = dir
|
|
46
|
-
?? process.env.WEAVER_QUEUE_DIR
|
|
47
|
-
?? (projectDir
|
|
48
|
-
? path.join(os.homedir(), '.weaver', 'projects', hashDir(projectDir))
|
|
49
|
-
: path.join(os.homedir(), '.weaver'));
|
|
35
|
+
const base = dir ?? resolveWeaverDir();
|
|
50
36
|
this.filePath = path.join(base, 'task-queue.ndjson');
|
|
51
37
|
}
|
|
52
38
|
|
|
@@ -7,18 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { StreamEvent, ToolEvent } from '@synergenius/flow-weaver/agent';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const isTTY = process.stderr.isTTY ?? false;
|
|
13
|
-
const c = {
|
|
14
|
-
green: (s: string) => `\x1b[32m${s}\x1b[0m`,
|
|
15
|
-
red: (s: string) => `\x1b[31m${s}\x1b[0m`,
|
|
16
|
-
yellow: (s: string) => `\x1b[33m${s}\x1b[0m`,
|
|
17
|
-
cyan: (s: string) => `\x1b[36m${s}\x1b[0m`,
|
|
18
|
-
dim: (s: string) => `\x1b[2m${s}\x1b[0m`,
|
|
19
|
-
bold: (s: string) => `\x1b[1m${s}\x1b[0m`,
|
|
20
|
-
redBold: (s: string) => `\x1b[1;31m${s}\x1b[0m`,
|
|
21
|
-
};
|
|
10
|
+
import { c } from './ansi.js';
|
|
11
|
+
import { VERBOSE_TOOL_NAMES } from './tool-registry.js';
|
|
22
12
|
|
|
23
13
|
export interface RendererOptions {
|
|
24
14
|
verbose?: boolean;
|
|
@@ -180,9 +170,16 @@ export class TerminalRenderer {
|
|
|
180
170
|
|
|
181
171
|
if (event.type === 'tool_call_result') {
|
|
182
172
|
const elapsed = Date.now() - this.lastToolStartTime;
|
|
183
|
-
const
|
|
173
|
+
const raw = event.result ?? '';
|
|
184
174
|
const icon = event.isError ? c.red('✗') : c.dim('→');
|
|
185
|
-
|
|
175
|
+
// Show full multiline output for verbose tools; one-line summary for others
|
|
176
|
+
const isVerboseTool = VERBOSE_TOOL_NAMES.has(event.name);
|
|
177
|
+
if (isVerboseTool && raw.includes('\n') && raw.length > 120) {
|
|
178
|
+
this.out(` ${icon} ${c.dim(formatElapsed(elapsed))}\n${raw}\n`);
|
|
179
|
+
} else {
|
|
180
|
+
const result = raw.replace(/\n/g, ' ').slice(0, 200);
|
|
181
|
+
this.out(` ${icon} ${result} ${c.dim(formatElapsed(elapsed))}\n`);
|
|
182
|
+
}
|
|
186
183
|
}
|
|
187
184
|
}
|
|
188
185
|
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified tool registry — single source of truth for all weaver tool definitions.
|
|
3
|
+
* Merges assistant-tools.ts ASSISTANT_TOOLS and weaver-tools.ts WEAVER_TOOLS
|
|
4
|
+
* into one registry with metadata (category, contexts, verboseOutput).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ToolDefinition } from '@synergenius/flow-weaver/agent';
|
|
8
|
+
|
|
9
|
+
export interface WeaverTool extends ToolDefinition {
|
|
10
|
+
verboseOutput?: boolean;
|
|
11
|
+
category: 'bot-management' | 'queue' | 'flow-weaver' | 'project' | 'knowledge' | 'conversation' | 'ci' | 'web';
|
|
12
|
+
contexts: Array<'bot' | 'assistant'>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const ALL_TOOLS: WeaverTool[] = [
|
|
16
|
+
// ── Bot management (assistant only) ──────────────────────────────
|
|
17
|
+
{
|
|
18
|
+
name: 'bot_spawn',
|
|
19
|
+
description: 'Start a new bot session. Returns the bot name and status.',
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
name: { type: 'string', description: 'Unique name for this bot (e.g. "fix-templates")' },
|
|
24
|
+
project_dir: { type: 'string', description: 'Project directory for the bot to work in' },
|
|
25
|
+
parallel: { type: 'number', description: 'Number of parallel tasks (1-5, default 1)' },
|
|
26
|
+
deadline: { type: 'string', description: 'Stop time in HH:MM format (optional)' },
|
|
27
|
+
branch: { type: 'string', description: 'Git branch for commits (keeps main clean, good for overnight runs)' },
|
|
28
|
+
},
|
|
29
|
+
required: ['name'],
|
|
30
|
+
},
|
|
31
|
+
category: 'bot-management',
|
|
32
|
+
contexts: ['assistant'],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'bot_list',
|
|
36
|
+
description: 'List all bot sessions with their status, task counts, and cost.',
|
|
37
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
38
|
+
category: 'bot-management',
|
|
39
|
+
contexts: ['assistant'],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'bot_status',
|
|
43
|
+
description: 'Get detailed status of a specific bot including queue and recent activity.',
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: 'object',
|
|
46
|
+
properties: { name: { type: 'string', description: 'Bot name' } },
|
|
47
|
+
required: ['name'],
|
|
48
|
+
},
|
|
49
|
+
category: 'bot-management',
|
|
50
|
+
contexts: ['assistant'],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'bot_pause',
|
|
54
|
+
description: 'Pause a running bot. It will finish its current task then wait.',
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
properties: { name: { type: 'string', description: 'Bot name' } },
|
|
58
|
+
required: ['name'],
|
|
59
|
+
},
|
|
60
|
+
category: 'bot-management',
|
|
61
|
+
contexts: ['assistant'],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'bot_resume',
|
|
65
|
+
description: 'Resume a paused bot.',
|
|
66
|
+
inputSchema: {
|
|
67
|
+
type: 'object',
|
|
68
|
+
properties: { name: { type: 'string', description: 'Bot name' } },
|
|
69
|
+
required: ['name'],
|
|
70
|
+
},
|
|
71
|
+
category: 'bot-management',
|
|
72
|
+
contexts: ['assistant'],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'bot_stop',
|
|
76
|
+
description: 'Gracefully stop a bot (finishes current task, then exits).',
|
|
77
|
+
inputSchema: {
|
|
78
|
+
type: 'object',
|
|
79
|
+
properties: { name: { type: 'string', description: 'Bot name' } },
|
|
80
|
+
required: ['name'],
|
|
81
|
+
},
|
|
82
|
+
category: 'bot-management',
|
|
83
|
+
contexts: ['assistant'],
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'bot_logs',
|
|
87
|
+
description: 'Get recent output log from a bot.',
|
|
88
|
+
inputSchema: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: {
|
|
91
|
+
name: { type: 'string', description: 'Bot name' },
|
|
92
|
+
lines: { type: 'number', description: 'Number of lines to return (default 30)' },
|
|
93
|
+
},
|
|
94
|
+
required: ['name'],
|
|
95
|
+
},
|
|
96
|
+
verboseOutput: true,
|
|
97
|
+
category: 'bot-management',
|
|
98
|
+
contexts: ['assistant'],
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
// ── Queue management (assistant only) ────────────────────────────
|
|
102
|
+
{
|
|
103
|
+
name: 'queue_add',
|
|
104
|
+
description: 'Add a task to a bot\'s queue.',
|
|
105
|
+
inputSchema: {
|
|
106
|
+
type: 'object',
|
|
107
|
+
properties: {
|
|
108
|
+
bot: { type: 'string', description: 'Bot name' },
|
|
109
|
+
instruction: { type: 'string', description: 'Task instruction' },
|
|
110
|
+
targets: { type: 'array', items: { type: 'string' }, description: 'Target files (optional)' },
|
|
111
|
+
},
|
|
112
|
+
required: ['bot', 'instruction'],
|
|
113
|
+
},
|
|
114
|
+
category: 'queue',
|
|
115
|
+
contexts: ['assistant'],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'queue_add_batch',
|
|
119
|
+
description: 'Add multiple tasks to a bot\'s queue at once.',
|
|
120
|
+
inputSchema: {
|
|
121
|
+
type: 'object',
|
|
122
|
+
properties: {
|
|
123
|
+
bot: { type: 'string', description: 'Bot name' },
|
|
124
|
+
tasks: {
|
|
125
|
+
type: 'array',
|
|
126
|
+
items: {
|
|
127
|
+
type: 'object',
|
|
128
|
+
properties: {
|
|
129
|
+
instruction: { type: 'string' },
|
|
130
|
+
targets: { type: 'array', items: { type: 'string' } },
|
|
131
|
+
},
|
|
132
|
+
required: ['instruction'],
|
|
133
|
+
},
|
|
134
|
+
description: 'Array of tasks to add',
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
required: ['bot', 'tasks'],
|
|
138
|
+
},
|
|
139
|
+
category: 'queue',
|
|
140
|
+
contexts: ['assistant'],
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: 'queue_list',
|
|
144
|
+
description: 'List all tasks in a bot\'s queue with their status.',
|
|
145
|
+
inputSchema: {
|
|
146
|
+
type: 'object',
|
|
147
|
+
properties: { bot: { type: 'string', description: 'Bot name' } },
|
|
148
|
+
required: ['bot'],
|
|
149
|
+
},
|
|
150
|
+
category: 'queue',
|
|
151
|
+
contexts: ['assistant'],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: 'queue_retry',
|
|
155
|
+
description: 'Reset all failed tasks in a bot\'s queue to pending.',
|
|
156
|
+
inputSchema: {
|
|
157
|
+
type: 'object',
|
|
158
|
+
properties: { bot: { type: 'string', description: 'Bot name' } },
|
|
159
|
+
required: ['bot'],
|
|
160
|
+
},
|
|
161
|
+
category: 'queue',
|
|
162
|
+
contexts: ['assistant'],
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
// ── Flow-weaver tools ────────────────────────────────────────────
|
|
166
|
+
{
|
|
167
|
+
name: 'validate',
|
|
168
|
+
description: 'Run flow-weaver validate on a workflow file. Returns JSON with errors and warnings. Use this FIRST to discover issues, and AFTER patching to confirm fixes.',
|
|
169
|
+
inputSchema: { type: 'object', properties: { file: { type: 'string', description: 'Path to the workflow file to validate' } }, required: ['file'] },
|
|
170
|
+
category: 'flow-weaver',
|
|
171
|
+
contexts: ['bot'],
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: 'fw_validate',
|
|
175
|
+
description: 'Validate a workflow or directory of workflows. Returns errors and warnings.',
|
|
176
|
+
inputSchema: {
|
|
177
|
+
type: 'object',
|
|
178
|
+
properties: { path: { type: 'string', description: 'File or directory path' } },
|
|
179
|
+
required: ['path'],
|
|
180
|
+
},
|
|
181
|
+
category: 'flow-weaver',
|
|
182
|
+
contexts: ['assistant'],
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: 'fw_diagram',
|
|
186
|
+
description: 'Generate a text diagram of a workflow.',
|
|
187
|
+
inputSchema: {
|
|
188
|
+
type: 'object',
|
|
189
|
+
properties: { file: { type: 'string', description: 'Workflow file path' } },
|
|
190
|
+
required: ['file'],
|
|
191
|
+
},
|
|
192
|
+
verboseOutput: true,
|
|
193
|
+
category: 'flow-weaver',
|
|
194
|
+
contexts: ['assistant'],
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: 'fw_describe',
|
|
198
|
+
description: 'Get a natural language description of a workflow.',
|
|
199
|
+
inputSchema: {
|
|
200
|
+
type: 'object',
|
|
201
|
+
properties: { file: { type: 'string', description: 'Workflow file path' } },
|
|
202
|
+
required: ['file'],
|
|
203
|
+
},
|
|
204
|
+
verboseOutput: true,
|
|
205
|
+
category: 'flow-weaver',
|
|
206
|
+
contexts: ['assistant'],
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
name: 'fw_docs',
|
|
210
|
+
description: 'Look up Flow Weaver documentation by topic. Topics: concepts, jsdoc-grammar, advanced-annotations, built-in-nodes, scaffold, node-conversion, patterns, error-codes, debugging, export-interface.',
|
|
211
|
+
inputSchema: {
|
|
212
|
+
type: 'object',
|
|
213
|
+
properties: { topic: { type: 'string', description: 'Documentation topic slug' } },
|
|
214
|
+
required: ['topic'],
|
|
215
|
+
},
|
|
216
|
+
verboseOutput: true,
|
|
217
|
+
category: 'flow-weaver',
|
|
218
|
+
contexts: ['assistant'],
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
name: 'fw_diagram_mermaid',
|
|
222
|
+
description: 'Generate a Mermaid diagram of a workflow (can be rendered in any Mermaid viewer).',
|
|
223
|
+
inputSchema: {
|
|
224
|
+
type: 'object',
|
|
225
|
+
properties: { file: { type: 'string', description: 'Workflow file path' } },
|
|
226
|
+
required: ['file'],
|
|
227
|
+
},
|
|
228
|
+
verboseOutput: true,
|
|
229
|
+
category: 'flow-weaver',
|
|
230
|
+
contexts: ['assistant'],
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
// ── Project tools (shared or context-specific) ───────────────────
|
|
234
|
+
{
|
|
235
|
+
name: 'read_file',
|
|
236
|
+
description: 'Read a file and return its contents.',
|
|
237
|
+
inputSchema: {
|
|
238
|
+
type: 'object',
|
|
239
|
+
properties: { file: { type: 'string', description: 'File path' } },
|
|
240
|
+
required: ['file'],
|
|
241
|
+
},
|
|
242
|
+
category: 'project',
|
|
243
|
+
contexts: ['bot', 'assistant'],
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: 'list_files',
|
|
247
|
+
description: 'List files in a directory, optionally filtered by regex pattern.',
|
|
248
|
+
inputSchema: {
|
|
249
|
+
type: 'object',
|
|
250
|
+
properties: {
|
|
251
|
+
directory: { type: 'string', description: 'Directory to list' },
|
|
252
|
+
pattern: { type: 'string', description: 'Optional regex filter pattern' },
|
|
253
|
+
},
|
|
254
|
+
required: ['directory'],
|
|
255
|
+
},
|
|
256
|
+
category: 'project',
|
|
257
|
+
contexts: ['bot', 'assistant'],
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
name: 'run_shell',
|
|
261
|
+
description: 'Run a shell command (read-only operations recommended). Blocked: rm -rf, git push, sudo.',
|
|
262
|
+
inputSchema: {
|
|
263
|
+
type: 'object',
|
|
264
|
+
properties: { command: { type: 'string', description: 'Shell command to execute' } },
|
|
265
|
+
required: ['command'],
|
|
266
|
+
},
|
|
267
|
+
category: 'project',
|
|
268
|
+
contexts: ['bot', 'assistant'],
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: 'patch_file',
|
|
272
|
+
description: 'Apply surgical find-and-replace patches to a file. Each patch must have exact "find" and "replace" strings. Preferred over write_file for modifications.',
|
|
273
|
+
inputSchema: {
|
|
274
|
+
type: 'object',
|
|
275
|
+
properties: {
|
|
276
|
+
file: { type: 'string', description: 'Path to the file to patch' },
|
|
277
|
+
patches: {
|
|
278
|
+
type: 'array',
|
|
279
|
+
items: {
|
|
280
|
+
type: 'object',
|
|
281
|
+
properties: {
|
|
282
|
+
find: { type: 'string', description: 'Exact string to find' },
|
|
283
|
+
replace: { type: 'string', description: 'String to replace with' },
|
|
284
|
+
},
|
|
285
|
+
required: ['find', 'replace'],
|
|
286
|
+
},
|
|
287
|
+
description: 'Array of find/replace patches',
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
required: ['file', 'patches'],
|
|
291
|
+
},
|
|
292
|
+
category: 'project',
|
|
293
|
+
contexts: ['bot'],
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
name: 'write_file',
|
|
297
|
+
description: 'Write content to a file (creates or overwrites). Use patch_file instead for modifications to existing files.',
|
|
298
|
+
inputSchema: {
|
|
299
|
+
type: 'object',
|
|
300
|
+
properties: {
|
|
301
|
+
file: { type: 'string', description: 'Path to the file to write' },
|
|
302
|
+
content: { type: 'string', description: 'Complete file content' },
|
|
303
|
+
},
|
|
304
|
+
required: ['file', 'content'],
|
|
305
|
+
},
|
|
306
|
+
category: 'project',
|
|
307
|
+
contexts: ['bot'],
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: 'tsc_check',
|
|
311
|
+
description: 'Run TypeScript compiler check (no emit). Returns errors if any.',
|
|
312
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
313
|
+
verboseOutput: true,
|
|
314
|
+
category: 'project',
|
|
315
|
+
contexts: ['bot'],
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
name: 'run_tests',
|
|
319
|
+
description: 'Run project tests. Returns structured results with pass/fail counts.',
|
|
320
|
+
inputSchema: { type: 'object', properties: { pattern: { type: 'string', description: 'Test file pattern (optional)' } }, required: [] },
|
|
321
|
+
verboseOutput: true,
|
|
322
|
+
category: 'project',
|
|
323
|
+
contexts: ['bot'],
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
name: 'project_list',
|
|
327
|
+
description: 'List known project directories that have been used with weaver.',
|
|
328
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
329
|
+
category: 'project',
|
|
330
|
+
contexts: ['assistant'],
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
name: 'project_context',
|
|
334
|
+
description: 'Read package.json and .weaver-plan.md from a project directory to understand its context.',
|
|
335
|
+
inputSchema: {
|
|
336
|
+
type: 'object',
|
|
337
|
+
properties: { directory: { type: 'string', description: 'Absolute path to project directory' } },
|
|
338
|
+
required: ['directory'],
|
|
339
|
+
},
|
|
340
|
+
category: 'project',
|
|
341
|
+
contexts: ['assistant'],
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
// ── Knowledge tools ──────────────────────────────────────────────
|
|
345
|
+
{
|
|
346
|
+
name: 'knowledge_list',
|
|
347
|
+
description: 'List all stored knowledge entries for the current project.',
|
|
348
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
349
|
+
category: 'knowledge',
|
|
350
|
+
contexts: ['assistant'],
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
name: 'knowledge_search',
|
|
354
|
+
description: 'Search stored knowledge by keyword.',
|
|
355
|
+
inputSchema: {
|
|
356
|
+
type: 'object',
|
|
357
|
+
properties: { query: { type: 'string', description: 'Search query' } },
|
|
358
|
+
required: ['query'],
|
|
359
|
+
},
|
|
360
|
+
category: 'knowledge',
|
|
361
|
+
contexts: ['assistant'],
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
name: 'learn',
|
|
365
|
+
description: 'Store a fact for future tasks. Key should be descriptive (e.g. "file:src/agent.ts:port-issue").',
|
|
366
|
+
inputSchema: { type: 'object', properties: { key: { type: 'string' }, value: { type: 'string' } }, required: ['key', 'value'] },
|
|
367
|
+
category: 'knowledge',
|
|
368
|
+
contexts: ['bot'],
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
name: 'recall',
|
|
372
|
+
description: 'Look up stored knowledge. Returns matching entries.',
|
|
373
|
+
inputSchema: { type: 'object', properties: { query: { type: 'string' } }, required: ['query'] },
|
|
374
|
+
category: 'knowledge',
|
|
375
|
+
contexts: ['bot'],
|
|
376
|
+
},
|
|
377
|
+
|
|
378
|
+
// ── Conversation management (assistant only) ─────────────────────
|
|
379
|
+
{
|
|
380
|
+
name: 'conversation_list',
|
|
381
|
+
description: 'List saved assistant conversations with message counts and timestamps.',
|
|
382
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
383
|
+
category: 'conversation',
|
|
384
|
+
contexts: ['assistant'],
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
name: 'conversation_delete',
|
|
388
|
+
description: 'Delete a saved conversation by ID.',
|
|
389
|
+
inputSchema: {
|
|
390
|
+
type: 'object',
|
|
391
|
+
properties: { id: { type: 'string', description: 'Conversation ID to delete' } },
|
|
392
|
+
required: ['id'],
|
|
393
|
+
},
|
|
394
|
+
category: 'conversation',
|
|
395
|
+
contexts: ['assistant'],
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
name: 'conversation_summary',
|
|
399
|
+
description: 'Get a summary of the current conversation (message count, tokens, bots spawned).',
|
|
400
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
401
|
+
category: 'conversation',
|
|
402
|
+
contexts: ['assistant'],
|
|
403
|
+
},
|
|
404
|
+
|
|
405
|
+
// ── CI/CD (assistant only) ───────────────────────────────────────
|
|
406
|
+
{
|
|
407
|
+
name: 'github_status',
|
|
408
|
+
description: 'Check GitHub Actions status for a branch or PR. Requires gh CLI installed.',
|
|
409
|
+
inputSchema: {
|
|
410
|
+
type: 'object',
|
|
411
|
+
properties: {
|
|
412
|
+
branch: { type: 'string', description: 'Branch name (optional, defaults to current)' },
|
|
413
|
+
pr: { type: 'number', description: 'PR number (optional, checks PR status instead of branch)' },
|
|
414
|
+
},
|
|
415
|
+
required: [],
|
|
416
|
+
},
|
|
417
|
+
category: 'ci',
|
|
418
|
+
contexts: ['assistant'],
|
|
419
|
+
},
|
|
420
|
+
|
|
421
|
+
// ── Web access (shared) ──────────────────────────────────────────
|
|
422
|
+
{
|
|
423
|
+
name: 'web_fetch',
|
|
424
|
+
description: 'Fetch HTTP content from a URL. Returns text body (max 10KB).',
|
|
425
|
+
inputSchema: {
|
|
426
|
+
type: 'object',
|
|
427
|
+
properties: {
|
|
428
|
+
url: { type: 'string', description: 'URL to fetch' },
|
|
429
|
+
method: { type: 'string', description: 'HTTP method (default GET)', enum: ['GET', 'POST'] },
|
|
430
|
+
},
|
|
431
|
+
required: ['url'],
|
|
432
|
+
},
|
|
433
|
+
category: 'web',
|
|
434
|
+
contexts: ['bot', 'assistant'],
|
|
435
|
+
},
|
|
436
|
+
|
|
437
|
+
// ── Bot-only interactive ─────────────────────────────────────────
|
|
438
|
+
{
|
|
439
|
+
name: 'ask_user',
|
|
440
|
+
description: 'Ask the user a question and wait for response. Use when you need a decision.',
|
|
441
|
+
inputSchema: { type: 'object', properties: { question: { type: 'string' } }, required: ['question'] },
|
|
442
|
+
category: 'project',
|
|
443
|
+
contexts: ['bot'],
|
|
444
|
+
},
|
|
445
|
+
];
|
|
446
|
+
|
|
447
|
+
// ── Derived exports ──────────────────────────────────────────────────
|
|
448
|
+
|
|
449
|
+
export const BOT_TOOLS: ToolDefinition[] = ALL_TOOLS.filter(t => t.contexts.includes('bot'));
|
|
450
|
+
export const ASSISTANT_TOOLS: ToolDefinition[] = ALL_TOOLS.filter(t => t.contexts.includes('assistant'));
|
|
451
|
+
export const VERBOSE_TOOL_NAMES = new Set(ALL_TOOLS.filter(t => t.verboseOutput).map(t => t.name));
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Generate a prompt section grouping assistant tools by category.
|
|
455
|
+
*/
|
|
456
|
+
export function generateToolPromptSection(): string {
|
|
457
|
+
const groups = new Map<string, WeaverTool[]>();
|
|
458
|
+
for (const t of ALL_TOOLS.filter(t => t.contexts.includes('assistant'))) {
|
|
459
|
+
const list = groups.get(t.category) ?? [];
|
|
460
|
+
list.push(t);
|
|
461
|
+
groups.set(t.category, list);
|
|
462
|
+
}
|
|
463
|
+
const lines: string[] = [];
|
|
464
|
+
for (const [cat, tools] of groups) {
|
|
465
|
+
lines.push(`${cat}:`);
|
|
466
|
+
for (const t of tools) lines.push(` - ${t.name}: ${t.description}`);
|
|
467
|
+
lines.push('');
|
|
468
|
+
}
|
|
469
|
+
return lines.join('\n');
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Generate a comma-separated list of tools that produce verbose output.
|
|
474
|
+
*/
|
|
475
|
+
export function generateVerboseToolList(): string {
|
|
476
|
+
return [...VERBOSE_TOOL_NAMES].join(', ');
|
|
477
|
+
}
|