@synergenius/flow-weaver-pack-weaver 0.9.151 → 0.9.153
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/ai-chat-provider.js +4 -4
- package/dist/ai-chat-provider.js.map +1 -1
- package/dist/bot/ai-client.d.ts +30 -0
- package/dist/bot/ai-client.d.ts.map +1 -1
- package/dist/bot/ai-client.js +37 -0
- package/dist/bot/ai-client.js.map +1 -1
- package/dist/bot/behavior-defaults.d.ts.map +1 -1
- package/dist/bot/behavior-defaults.js +7 -2
- package/dist/bot/behavior-defaults.js.map +1 -1
- package/dist/bot/capability-registry.d.ts.map +1 -1
- package/dist/bot/capability-registry.js +48 -30
- package/dist/bot/capability-registry.js.map +1 -1
- package/dist/bot/file-validator.d.ts +7 -0
- package/dist/bot/file-validator.d.ts.map +1 -1
- package/dist/bot/file-validator.js +76 -0
- package/dist/bot/file-validator.js.map +1 -1
- package/dist/bot/instance-manager.d.ts +22 -7
- package/dist/bot/instance-manager.d.ts.map +1 -1
- package/dist/bot/instance-manager.js +69 -7
- package/dist/bot/instance-manager.js.map +1 -1
- package/dist/bot/orchestrator.d.ts +11 -9
- package/dist/bot/orchestrator.d.ts.map +1 -1
- package/dist/bot/orchestrator.js +56 -107
- package/dist/bot/orchestrator.js.map +1 -1
- package/dist/bot/runner.d.ts +29 -0
- package/dist/bot/runner.d.ts.map +1 -1
- package/dist/bot/runner.js +114 -73
- package/dist/bot/runner.js.map +1 -1
- package/dist/bot/step-executor.d.ts.map +1 -1
- package/dist/bot/step-executor.js +106 -25
- package/dist/bot/step-executor.js.map +1 -1
- package/dist/bot/swarm-controller.d.ts +7 -6
- package/dist/bot/swarm-controller.d.ts.map +1 -1
- package/dist/bot/swarm-controller.js +64 -74
- package/dist/bot/swarm-controller.js.map +1 -1
- package/dist/bot/task-types.d.ts +1 -0
- package/dist/bot/task-types.d.ts.map +1 -1
- package/dist/bot/weaver-tools.d.ts +1 -1
- package/dist/bot/weaver-tools.d.ts.map +1 -1
- package/dist/bot/weaver-tools.js +6 -1
- package/dist/bot/weaver-tools.js.map +1 -1
- package/dist/node-types/agent-execute.js +2 -2
- package/dist/node-types/agent-execute.js.map +1 -1
- package/dist/node-types/bot-report.d.ts.map +1 -1
- package/dist/node-types/bot-report.js +5 -2
- package/dist/node-types/bot-report.js.map +1 -1
- package/dist/node-types/build-context.js +2 -1
- package/dist/node-types/build-context.js.map +1 -1
- package/dist/node-types/exec-validate-retry.d.ts +3 -3
- package/dist/node-types/exec-validate-retry.d.ts.map +1 -1
- package/dist/node-types/exec-validate-retry.js +13 -184
- package/dist/node-types/exec-validate-retry.js.map +1 -1
- package/dist/node-types/load-config.d.ts +1 -0
- package/dist/node-types/load-config.d.ts.map +1 -1
- package/dist/node-types/load-config.js +1 -0
- package/dist/node-types/load-config.js.map +1 -1
- package/dist/node-types/plan-task.d.ts +7 -5
- package/dist/node-types/plan-task.d.ts.map +1 -1
- package/dist/node-types/plan-task.js +282 -83
- package/dist/node-types/plan-task.js.map +1 -1
- package/dist/ui/bot-panel.js +1 -1
- package/dist/ui/capability-editor.js +48 -30
- package/dist/ui/profile-editor.js +46 -28
- package/dist/ui/swarm-dashboard.js +71 -33
- package/dist/ui/task-detail-view.js +22 -2
- package/dist/workflows/weaver-bot.d.ts +2 -2
- package/dist/workflows/weaver-bot.d.ts.map +1 -1
- package/dist/workflows/weaver-bot.js +5 -4
- package/dist/workflows/weaver-bot.js.map +1 -1
- package/flowweaver.manifest.json +1 -1
- package/package.json +1 -1
- package/src/ai-chat-provider.ts +4 -4
- package/src/bot/ai-client.ts +65 -0
- package/src/bot/behavior-defaults.ts +5 -2
- package/src/bot/capability-registry.ts +48 -30
- package/src/bot/file-validator.ts +97 -0
- package/src/bot/instance-manager.ts +77 -7
- package/src/bot/orchestrator.ts +63 -126
- package/src/bot/runner.ts +124 -70
- package/src/bot/step-executor.ts +115 -25
- package/src/bot/swarm-controller.ts +65 -76
- package/src/bot/task-types.ts +1 -0
- package/src/bot/weaver-tools.ts +7 -1
- package/src/node-types/agent-execute.ts +2 -2
- package/src/node-types/bot-report.ts +5 -2
- package/src/node-types/build-context.ts +2 -1
- package/src/node-types/exec-validate-retry.ts +14 -203
- package/src/node-types/load-config.ts +1 -0
- package/src/node-types/plan-task.ts +313 -88
- package/src/ui/bot-panel.tsx +1 -1
- package/src/ui/swarm-dashboard.tsx +3 -3
- package/src/ui/task-detail-view.tsx +25 -2
- package/src/workflows/weaver-bot.ts +5 -4
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
1
4
|
import { checkDesignQuality } from './design-checker.js';
|
|
2
5
|
import { fwValidate } from './fw-api.js';
|
|
3
6
|
export async function validateFiles(files, projectDir) {
|
|
@@ -5,6 +8,17 @@ export async function validateFiles(files, projectDir) {
|
|
|
5
8
|
for (const file of files) {
|
|
6
9
|
if (!file.endsWith('.ts'))
|
|
7
10
|
continue;
|
|
11
|
+
// Only run FW validation on files that contain @flowWeaver annotations.
|
|
12
|
+
// Plain TypeScript files (like server.ts) should not be FW-validated.
|
|
13
|
+
const absFile = path.isAbsolute(file) ? file : path.resolve(projectDir, file);
|
|
14
|
+
let hasFwAnnotation = false;
|
|
15
|
+
try {
|
|
16
|
+
const content = fs.readFileSync(absFile, 'utf-8');
|
|
17
|
+
hasFwAnnotation = content.includes('@flowWeaver') || content.includes('@flow-weaver');
|
|
18
|
+
}
|
|
19
|
+
catch { /* file read failed — skip FW validation */ }
|
|
20
|
+
if (!hasFwAnnotation)
|
|
21
|
+
continue;
|
|
8
22
|
try {
|
|
9
23
|
const { valid, errors, warnings, ast } = await fwValidate(file);
|
|
10
24
|
if (!valid) {
|
|
@@ -24,4 +38,66 @@ export async function validateFiles(files, projectDir) {
|
|
|
24
38
|
}
|
|
25
39
|
return results;
|
|
26
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Find the tsc binary: prefer the project's own node_modules/.bin/tsc,
|
|
43
|
+
* then walk up parent directories, then fall back to a bare 'tsc' (PATH lookup).
|
|
44
|
+
*/
|
|
45
|
+
function findTscBin(projectDir) {
|
|
46
|
+
let dir = projectDir;
|
|
47
|
+
// eslint-disable-next-line no-constant-condition
|
|
48
|
+
while (true) {
|
|
49
|
+
const candidate = path.join(dir, 'node_modules', '.bin', 'tsc');
|
|
50
|
+
if (fs.existsSync(candidate))
|
|
51
|
+
return candidate;
|
|
52
|
+
const parent = path.dirname(dir);
|
|
53
|
+
if (parent === dir)
|
|
54
|
+
break;
|
|
55
|
+
dir = parent;
|
|
56
|
+
}
|
|
57
|
+
return null; // caller will try bare 'tsc'
|
|
58
|
+
}
|
|
59
|
+
// Strip ANSI escape codes from tsc output
|
|
60
|
+
function stripAnsi(str) {
|
|
61
|
+
// eslint-disable-next-line no-control-regex
|
|
62
|
+
return str.replace(/\x1b\[[0-9;]*m/g, '');
|
|
63
|
+
}
|
|
64
|
+
export async function validateTypeScript(projectDir, opts) {
|
|
65
|
+
const timeoutMs = opts?.timeoutMs ?? 30_000;
|
|
66
|
+
// Check for tsconfig.json
|
|
67
|
+
const tsconfigPath = path.join(projectDir, 'tsconfig.json');
|
|
68
|
+
if (!fs.existsSync(tsconfigPath)) {
|
|
69
|
+
return { valid: true, errors: [] };
|
|
70
|
+
}
|
|
71
|
+
const tscBin = findTscBin(projectDir) ?? 'tsc';
|
|
72
|
+
return new Promise((resolve) => {
|
|
73
|
+
try {
|
|
74
|
+
const child = execFile(tscBin, ['--noEmit', '--pretty', 'false'], { cwd: projectDir, timeout: timeoutMs, env: { ...process.env } }, (error, stdout, stderr) => {
|
|
75
|
+
if (!error) {
|
|
76
|
+
return resolve({ valid: true, errors: [] });
|
|
77
|
+
}
|
|
78
|
+
// If the process was killed (timeout) or spawn failed, graceful fallback
|
|
79
|
+
if (error.killed || error.code === 'ENOENT') {
|
|
80
|
+
return resolve({ valid: true, errors: [] });
|
|
81
|
+
}
|
|
82
|
+
// tsc exits with code 2 on type errors; parse stdout for error lines
|
|
83
|
+
const output = stripAnsi((stdout || '') + (stderr || ''));
|
|
84
|
+
const lines = output.split('\n').filter((l) => l.trim().length > 0);
|
|
85
|
+
if (lines.length === 0) {
|
|
86
|
+
return resolve({ valid: true, errors: [] });
|
|
87
|
+
}
|
|
88
|
+
// Strip absolute projectDir prefix so errors use relative paths
|
|
89
|
+
const cleaned = lines.map(l => l.replaceAll(projectDir + '/', ''));
|
|
90
|
+
return resolve({ valid: false, errors: cleaned });
|
|
91
|
+
});
|
|
92
|
+
// Extra safety: if the child can't even spawn
|
|
93
|
+
child.on('error', () => {
|
|
94
|
+
resolve({ valid: true, errors: [] });
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// execFile itself threw (e.g. bad args) — graceful fallback
|
|
99
|
+
resolve({ valid: true, errors: [] });
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
27
103
|
//# sourceMappingURL=file-validator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-validator.js","sourceRoot":"","sources":["../../src/bot/file-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAqB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAUzC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAe,EACf,UAAkB;IAElB,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"file-validator.js","sourceRoot":"","sources":["../../src/bot/file-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* InstanceManager — manages
|
|
3
|
-
*
|
|
2
|
+
* InstanceManager — manages a dynamic pool of generic worker slots.
|
|
3
|
+
*
|
|
4
|
+
* Workers are profile-agnostic: any worker can run any profile's task.
|
|
5
|
+
* The profile is loaded per-task at execution time, not per-worker.
|
|
6
|
+
*
|
|
7
|
+
* Worker naming: `worker-0`, `worker-1`, ... (no per-profile instances).
|
|
4
8
|
*/
|
|
5
9
|
import type { BotProfile, BotInstance } from './profile-types.js';
|
|
6
10
|
export declare class InstanceManager {
|
|
7
11
|
private instances;
|
|
8
|
-
/** Spawn a
|
|
12
|
+
/** Spawn a single generic worker slot at the given index. */
|
|
13
|
+
spawnWorker(index: number): BotInstance;
|
|
14
|
+
/** Spawn a pool of N generic workers (worker-0 through worker-N-1). */
|
|
15
|
+
spawnPool(size: number): BotInstance[];
|
|
16
|
+
/** Find any idle worker (profile-agnostic). Returns a copy or null. */
|
|
17
|
+
findIdleWorker(): BotInstance | null;
|
|
18
|
+
/** Return all idle workers. */
|
|
19
|
+
findIdleWorkers(): BotInstance[];
|
|
20
|
+
/** @deprecated Use spawnWorker/spawnPool instead. Spawn a profile-bound instance. */
|
|
9
21
|
spawn(profile: BotProfile): BotInstance;
|
|
10
22
|
/** Get instance by ID (returns a copy), or null if not found. */
|
|
11
23
|
get(instanceId: string): BotInstance | null;
|
|
@@ -15,9 +27,12 @@ export declare class InstanceManager {
|
|
|
15
27
|
listByProfile(profileId: string): BotInstance[];
|
|
16
28
|
/** Return idle instances for a given profile. */
|
|
17
29
|
findIdle(profileId: string): BotInstance[];
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Mark a worker as executing a specific task/run.
|
|
32
|
+
* @param profileId — the profile being loaded for this task execution.
|
|
33
|
+
*/
|
|
34
|
+
markExecuting(instanceId: string, taskId: string, runId: string, profileId?: string): void;
|
|
35
|
+
/** Mark a worker as idle after task completion/failure. Clears profile association. */
|
|
21
36
|
markIdle(instanceId: string, success: boolean): void;
|
|
22
37
|
/** Record token/cost usage for an instance. */
|
|
23
38
|
recordUsage(instanceId: string, tokens: number, cost: number): void;
|
|
@@ -25,7 +40,7 @@ export declare class InstanceManager {
|
|
|
25
40
|
stop(instanceId: string): boolean;
|
|
26
41
|
/** Stop and remove all instances. */
|
|
27
42
|
stopAll(): void;
|
|
28
|
-
/**
|
|
43
|
+
/** @deprecated No longer needed in pool model. Kept for backward compat. */
|
|
29
44
|
scaleTo(profile: BotProfile, target: number): void;
|
|
30
45
|
}
|
|
31
46
|
//# sourceMappingURL=instance-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance-manager.d.ts","sourceRoot":"","sources":["../../src/bot/instance-manager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"instance-manager.d.ts","sourceRoot":"","sources":["../../src/bot/instance-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAElE,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAkC;IAMnD,6DAA6D;IAC7D,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IAqBvC,uEAAuE;IACvE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE;IAQtC,uEAAuE;IACvE,cAAc,IAAI,WAAW,GAAG,IAAI;IAOpC,+BAA+B;IAC/B,eAAe,IAAI,WAAW,EAAE;IAUhC,qFAAqF;IACrF,KAAK,CAAC,OAAO,EAAE,UAAU,GAAG,WAAW;IA+BvC,iEAAiE;IACjE,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAK3C,sCAAsC;IACtC,OAAO,IAAI,WAAW,EAAE;IAIxB,kEAAkE;IAClE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE;IAM/C,iDAAiD;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE;IAM1C;;;OAGG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAY1F,uFAAuF;IACvF,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAgBpD,+CAA+C;IAC/C,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAOnE,+DAA+D;IAC/D,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAIjC,qCAAqC;IACrC,OAAO,IAAI,IAAI;IAIf,4EAA4E;IAC5E,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;CAoBnD"}
|
|
@@ -1,10 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* InstanceManager — manages
|
|
3
|
-
*
|
|
2
|
+
* InstanceManager — manages a dynamic pool of generic worker slots.
|
|
3
|
+
*
|
|
4
|
+
* Workers are profile-agnostic: any worker can run any profile's task.
|
|
5
|
+
* The profile is loaded per-task at execution time, not per-worker.
|
|
6
|
+
*
|
|
7
|
+
* Worker naming: `worker-0`, `worker-1`, ... (no per-profile instances).
|
|
4
8
|
*/
|
|
5
9
|
export class InstanceManager {
|
|
6
10
|
instances = new Map();
|
|
7
|
-
|
|
11
|
+
// -----------------------------------------------------------------------
|
|
12
|
+
// Worker pool API (new)
|
|
13
|
+
// -----------------------------------------------------------------------
|
|
14
|
+
/** Spawn a single generic worker slot at the given index. */
|
|
15
|
+
spawnWorker(index) {
|
|
16
|
+
const instanceId = `worker-${index}`;
|
|
17
|
+
if (this.instances.has(instanceId)) {
|
|
18
|
+
throw new Error(`Worker already exists: ${instanceId}`);
|
|
19
|
+
}
|
|
20
|
+
const instance = {
|
|
21
|
+
instanceId,
|
|
22
|
+
profileId: '', // No profile until a task is assigned
|
|
23
|
+
index,
|
|
24
|
+
status: 'idle',
|
|
25
|
+
tokensUsed: 0,
|
|
26
|
+
cost: 0,
|
|
27
|
+
tasksCompleted: 0,
|
|
28
|
+
tasksFailed: 0,
|
|
29
|
+
};
|
|
30
|
+
this.instances.set(instanceId, instance);
|
|
31
|
+
return { ...instance };
|
|
32
|
+
}
|
|
33
|
+
/** Spawn a pool of N generic workers (worker-0 through worker-N-1). */
|
|
34
|
+
spawnPool(size) {
|
|
35
|
+
const spawned = [];
|
|
36
|
+
for (let i = 0; i < size; i++) {
|
|
37
|
+
spawned.push(this.spawnWorker(i));
|
|
38
|
+
}
|
|
39
|
+
return spawned;
|
|
40
|
+
}
|
|
41
|
+
/** Find any idle worker (profile-agnostic). Returns a copy or null. */
|
|
42
|
+
findIdleWorker() {
|
|
43
|
+
for (const inst of this.instances.values()) {
|
|
44
|
+
if (inst.status === 'idle')
|
|
45
|
+
return { ...inst };
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
/** Return all idle workers. */
|
|
50
|
+
findIdleWorkers() {
|
|
51
|
+
return [...this.instances.values()]
|
|
52
|
+
.filter((i) => i.status === 'idle')
|
|
53
|
+
.map((i) => ({ ...i }));
|
|
54
|
+
}
|
|
55
|
+
// -----------------------------------------------------------------------
|
|
56
|
+
// Legacy per-profile API (kept for backward compat, used by tests)
|
|
57
|
+
// -----------------------------------------------------------------------
|
|
58
|
+
/** @deprecated Use spawnWorker/spawnPool instead. Spawn a profile-bound instance. */
|
|
8
59
|
spawn(profile) {
|
|
9
60
|
const existing = this.listByProfile(profile.id);
|
|
10
61
|
if (existing.length >= profile.maxInstances) {
|
|
@@ -27,6 +78,9 @@ export class InstanceManager {
|
|
|
27
78
|
this.instances.set(instance.instanceId, instance);
|
|
28
79
|
return { ...instance };
|
|
29
80
|
}
|
|
81
|
+
// -----------------------------------------------------------------------
|
|
82
|
+
// Shared API
|
|
83
|
+
// -----------------------------------------------------------------------
|
|
30
84
|
/** Get instance by ID (returns a copy), or null if not found. */
|
|
31
85
|
get(instanceId) {
|
|
32
86
|
const inst = this.instances.get(instanceId);
|
|
@@ -48,8 +102,11 @@ export class InstanceManager {
|
|
|
48
102
|
.filter((i) => i.profileId === profileId && i.status === 'idle')
|
|
49
103
|
.map((i) => ({ ...i }));
|
|
50
104
|
}
|
|
51
|
-
/**
|
|
52
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Mark a worker as executing a specific task/run.
|
|
107
|
+
* @param profileId — the profile being loaded for this task execution.
|
|
108
|
+
*/
|
|
109
|
+
markExecuting(instanceId, taskId, runId, profileId) {
|
|
53
110
|
const inst = this.instances.get(instanceId);
|
|
54
111
|
if (!inst)
|
|
55
112
|
throw new Error(`Instance not found: ${instanceId}`);
|
|
@@ -57,8 +114,11 @@ export class InstanceManager {
|
|
|
57
114
|
inst.currentTaskId = taskId;
|
|
58
115
|
inst.currentRunId = runId;
|
|
59
116
|
inst.startedAt = new Date().toISOString();
|
|
117
|
+
if (profileId !== undefined) {
|
|
118
|
+
inst.profileId = profileId;
|
|
119
|
+
}
|
|
60
120
|
}
|
|
61
|
-
/** Mark
|
|
121
|
+
/** Mark a worker as idle after task completion/failure. Clears profile association. */
|
|
62
122
|
markIdle(instanceId, success) {
|
|
63
123
|
const inst = this.instances.get(instanceId);
|
|
64
124
|
if (!inst)
|
|
@@ -67,6 +127,8 @@ export class InstanceManager {
|
|
|
67
127
|
inst.currentTaskId = undefined;
|
|
68
128
|
inst.currentRunId = undefined;
|
|
69
129
|
inst.startedAt = undefined;
|
|
130
|
+
// Clear profile — worker is generic again
|
|
131
|
+
inst.profileId = '';
|
|
70
132
|
if (success) {
|
|
71
133
|
inst.tasksCompleted++;
|
|
72
134
|
}
|
|
@@ -90,7 +152,7 @@ export class InstanceManager {
|
|
|
90
152
|
stopAll() {
|
|
91
153
|
this.instances.clear();
|
|
92
154
|
}
|
|
93
|
-
/**
|
|
155
|
+
/** @deprecated No longer needed in pool model. Kept for backward compat. */
|
|
94
156
|
scaleTo(profile, target) {
|
|
95
157
|
const clamped = Math.max(0, Math.min(target, profile.maxInstances));
|
|
96
158
|
const current = this.listByProfile(profile.id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance-manager.js","sourceRoot":"","sources":["../../src/bot/instance-manager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"instance-manager.js","sourceRoot":"","sources":["../../src/bot/instance-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Orchestrator — the routing brain that decides which tasks go to which
|
|
2
|
+
* Orchestrator — the routing brain that decides which tasks go to which workers.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* In the worker pool model, workers are generic slots. The orchestrator:
|
|
5
|
+
* 1. Finds the profile for each task (via assignedProfile).
|
|
6
|
+
* 2. Assigns the task to any idle worker.
|
|
7
|
+
*
|
|
8
|
+
* Simplified cascade: exact-match profile → any idle worker.
|
|
9
|
+
* No more per-profile instance matching or scale-up actions.
|
|
6
10
|
*/
|
|
7
11
|
import type { BotProfile, OrchestratorDecision, OrchestratorInput, OrchestratorOutput } from './profile-types.js';
|
|
8
12
|
export interface AIRouterResult {
|
|
@@ -24,12 +28,10 @@ export declare class Orchestrator {
|
|
|
24
28
|
route(input: OrchestratorInput): Promise<OrchestratorOutput>;
|
|
25
29
|
getDecisionLog(limit?: number): OrchestratorDecision[];
|
|
26
30
|
clearDecisionLog(): void;
|
|
27
|
-
/**
|
|
28
|
-
private
|
|
29
|
-
/**
|
|
30
|
-
private
|
|
31
|
-
/** Determine which routing method was used. */
|
|
32
|
-
private _routingMethod;
|
|
31
|
+
/** Resolve which profileId should handle this task, including routing method. */
|
|
32
|
+
private _resolveProfile;
|
|
33
|
+
/** Find any idle worker that hasn't been claimed this cycle. */
|
|
34
|
+
private _findIdleWorker;
|
|
33
35
|
/** Record a decision in the log. */
|
|
34
36
|
private _recordDecision;
|
|
35
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/bot/orchestrator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/bot/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAEV,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAS5B,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACtG;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,SAAS,CAAC,CAAW;gBAEjB,OAAO,CAAC,EAAE,mBAAmB;IAQnC,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAwDlE,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,oBAAoB,EAAE;IAKtD,gBAAgB,IAAI,IAAI;IASxB,iFAAiF;YACnE,eAAe;IAoC7B,gEAAgE;IAChE,OAAO,CAAC,eAAe;IAMvB,oCAAoC;IACpC,OAAO,CAAC,eAAe;CAkBxB"}
|
package/dist/bot/orchestrator.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Orchestrator — the routing brain that decides which tasks go to which
|
|
2
|
+
* Orchestrator — the routing brain that decides which tasks go to which workers.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* In the worker pool model, workers are generic slots. The orchestrator:
|
|
5
|
+
* 1. Finds the profile for each task (via assignedProfile).
|
|
6
|
+
* 2. Assigns the task to any idle worker.
|
|
7
|
+
*
|
|
8
|
+
* Simplified cascade: exact-match profile → any idle worker.
|
|
9
|
+
* No more per-profile instance matching or scale-up actions.
|
|
6
10
|
*/
|
|
7
11
|
export class Orchestrator {
|
|
8
12
|
_decisionLog = [];
|
|
@@ -16,10 +20,9 @@ export class Orchestrator {
|
|
|
16
20
|
// ---------------------------------------------------------------------------
|
|
17
21
|
async route(input) {
|
|
18
22
|
const assignments = [];
|
|
19
|
-
const scaleActions = [];
|
|
20
23
|
const skippedTasks = [];
|
|
21
|
-
// Track
|
|
22
|
-
const
|
|
24
|
+
// Track workers claimed during this routing cycle to avoid double-assignment.
|
|
25
|
+
const claimedWorkerIds = new Set();
|
|
23
26
|
// Sort tasks by priority DESC (higher number = higher priority).
|
|
24
27
|
const sorted = [...input.pendingTasks].sort((a, b) => b.priority - a.priority);
|
|
25
28
|
for (const task of sorted) {
|
|
@@ -28,43 +31,38 @@ export class Orchestrator {
|
|
|
28
31
|
skippedTasks.push({ taskId: task.id, reason: 'budget-exhausted' });
|
|
29
32
|
continue;
|
|
30
33
|
}
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
// Resolve profile for this task (includes routing method)
|
|
35
|
+
const resolution = await this._resolveProfile(task, input.profiles);
|
|
36
|
+
if (!resolution) {
|
|
33
37
|
skippedTasks.push({ taskId: task.id, reason: 'no-eligible-profile' });
|
|
34
38
|
continue;
|
|
35
39
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
profileId: result.profileId,
|
|
42
|
-
instanceId: result.instanceId,
|
|
43
|
-
reason: result.reason,
|
|
44
|
-
method: result.method,
|
|
45
|
-
confidence: result.confidence,
|
|
46
|
-
});
|
|
47
|
-
this._recordDecision(task, result, eligible);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
// No idle instance available — request scale-up if possible.
|
|
51
|
-
const scaleProfile = eligible[0];
|
|
52
|
-
const currentCount = input.instances.filter((i) => i.profileId === scaleProfile.id).length;
|
|
53
|
-
if (currentCount < scaleProfile.maxInstances) {
|
|
54
|
-
// Only add one scale-up action per profile.
|
|
55
|
-
if (!scaleActions.some((sa) => sa.profileId === scaleProfile.id)) {
|
|
56
|
-
scaleActions.push({
|
|
57
|
-
profileId: scaleProfile.id,
|
|
58
|
-
action: 'scale-up',
|
|
59
|
-
targetInstances: currentCount + 1,
|
|
60
|
-
reason: `idle instances exhausted for profile ${scaleProfile.id}`,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
skippedTasks.push({ taskId: task.id, reason: 'no-idle-instance' });
|
|
40
|
+
// Find any idle worker
|
|
41
|
+
const idleWorker = this._findIdleWorker(input.instances, claimedWorkerIds);
|
|
42
|
+
if (!idleWorker) {
|
|
43
|
+
skippedTasks.push({ taskId: task.id, reason: 'no-idle-worker' });
|
|
44
|
+
continue;
|
|
65
45
|
}
|
|
46
|
+
claimedWorkerIds.add(idleWorker.instanceId);
|
|
47
|
+
const reason = `${resolution.method}: ${resolution.profileId} → ${idleWorker.instanceId}`;
|
|
48
|
+
assignments.push({
|
|
49
|
+
taskId: task.id,
|
|
50
|
+
profileId: resolution.profileId,
|
|
51
|
+
instanceId: idleWorker.instanceId,
|
|
52
|
+
reason,
|
|
53
|
+
method: resolution.method,
|
|
54
|
+
confidence: resolution.confidence,
|
|
55
|
+
});
|
|
56
|
+
this._recordDecision(task, {
|
|
57
|
+
profileId: resolution.profileId,
|
|
58
|
+
instanceId: idleWorker.instanceId,
|
|
59
|
+
method: resolution.method,
|
|
60
|
+
reason,
|
|
61
|
+
confidence: resolution.confidence,
|
|
62
|
+
}, input.profiles.filter(p => p.id === resolution.profileId));
|
|
66
63
|
}
|
|
67
|
-
|
|
64
|
+
// No scale actions in pool model — pool size is fixed at maxConcurrent
|
|
65
|
+
return { assignments, scaleActions: [], skippedTasks };
|
|
68
66
|
}
|
|
69
67
|
getDecisionLog(limit) {
|
|
70
68
|
if (limit === undefined)
|
|
@@ -78,88 +76,39 @@ export class Orchestrator {
|
|
|
78
76
|
// ---------------------------------------------------------------------------
|
|
79
77
|
// Internal
|
|
80
78
|
// ---------------------------------------------------------------------------
|
|
81
|
-
/**
|
|
82
|
-
|
|
79
|
+
/** Resolve which profileId should handle this task, including routing method. */
|
|
80
|
+
async _resolveProfile(task, profiles) {
|
|
81
|
+
// Exact match: task has assignedProfile
|
|
83
82
|
if (task.assignedProfile) {
|
|
84
|
-
const match = profiles.
|
|
85
|
-
if (match
|
|
86
|
-
return match;
|
|
87
|
-
// Assigned profile doesn't exist — return empty to skip this task
|
|
88
|
-
// rather than falling through to all profiles (silent mis-routing).
|
|
83
|
+
const match = profiles.find(p => p.id === task.assignedProfile);
|
|
84
|
+
if (match)
|
|
85
|
+
return { profileId: match.id, method: 'exact-match' };
|
|
89
86
|
console.warn(`[orchestrator] Task "${task.id}" assigned to profile "${task.assignedProfile}" which does not exist — skipping`);
|
|
90
|
-
return
|
|
87
|
+
return null;
|
|
91
88
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
async _selectInstance(task, eligible, instances, claimed) {
|
|
96
|
-
// Determine routing method
|
|
97
|
-
let method = this._routingMethod(task, eligible);
|
|
98
|
-
if (eligible.length === 1) {
|
|
99
|
-
const profile = eligible[0];
|
|
100
|
-
const idle = instances.find((i) => i.profileId === profile.id && i.status === 'idle' && !claimed.has(i.instanceId));
|
|
101
|
-
if (!idle)
|
|
102
|
-
return null;
|
|
103
|
-
return {
|
|
104
|
-
profileId: profile.id,
|
|
105
|
-
instanceId: idle.instanceId,
|
|
106
|
-
method,
|
|
107
|
-
reason: `${method}: ${profile.id}`,
|
|
108
|
-
};
|
|
89
|
+
// Single eligible profile
|
|
90
|
+
if (profiles.length === 1) {
|
|
91
|
+
return { profileId: profiles[0].id, method: 'single-eligible' };
|
|
109
92
|
}
|
|
110
|
-
//
|
|
111
|
-
if (this._aiRouter &&
|
|
93
|
+
// Multiple eligible profiles — try AI routing
|
|
94
|
+
if (this._aiRouter && profiles.length > 1) {
|
|
112
95
|
try {
|
|
113
|
-
const aiResult = await this._aiRouter.route(task,
|
|
114
|
-
const aiProfile =
|
|
96
|
+
const aiResult = await this._aiRouter.route(task, profiles);
|
|
97
|
+
const aiProfile = profiles.find(p => p.id === aiResult.profileId);
|
|
115
98
|
if (aiProfile) {
|
|
116
|
-
|
|
117
|
-
if (idle) {
|
|
118
|
-
return {
|
|
119
|
-
profileId: aiProfile.id,
|
|
120
|
-
instanceId: idle.instanceId,
|
|
121
|
-
method: 'ai-routed',
|
|
122
|
-
reason: `ai-routed: ${aiProfile.id} — ${aiResult.reason}`,
|
|
123
|
-
confidence: aiResult.confidence,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
// AI chose a profile but no idle instance — fall through to round-robin
|
|
99
|
+
return { profileId: aiProfile.id, method: 'ai-routed', confidence: aiResult.confidence };
|
|
127
100
|
}
|
|
128
|
-
// AI returned unknown profile — fall through to round-robin
|
|
129
101
|
}
|
|
130
102
|
catch {
|
|
131
103
|
// AI call failed — fall through to round-robin
|
|
132
104
|
}
|
|
133
105
|
}
|
|
134
|
-
//
|
|
135
|
-
method
|
|
136
|
-
let bestProfile = null;
|
|
137
|
-
let bestIdleCount = -1;
|
|
138
|
-
let bestInstance = null;
|
|
139
|
-
for (const profile of eligible) {
|
|
140
|
-
const idleInstances = instances.filter((i) => i.profileId === profile.id && i.status === 'idle' && !claimed.has(i.instanceId));
|
|
141
|
-
if (idleInstances.length > bestIdleCount) {
|
|
142
|
-
bestIdleCount = idleInstances.length;
|
|
143
|
-
bestProfile = profile;
|
|
144
|
-
bestInstance = idleInstances[0] ?? null;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (!bestProfile || !bestInstance)
|
|
148
|
-
return null;
|
|
149
|
-
return {
|
|
150
|
-
profileId: bestProfile.id,
|
|
151
|
-
instanceId: bestInstance.instanceId,
|
|
152
|
-
method,
|
|
153
|
-
reason: `${method}: ${bestProfile.id}`,
|
|
154
|
-
};
|
|
106
|
+
// Fallback: round-robin (first profile)
|
|
107
|
+
return profiles.length > 0 ? { profileId: profiles[0].id, method: 'round-robin' } : null;
|
|
155
108
|
}
|
|
156
|
-
/**
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return 'exact-match';
|
|
160
|
-
if (eligible.length === 1)
|
|
161
|
-
return 'single-eligible';
|
|
162
|
-
return 'round-robin';
|
|
109
|
+
/** Find any idle worker that hasn't been claimed this cycle. */
|
|
110
|
+
_findIdleWorker(instances, claimed) {
|
|
111
|
+
return instances.find((i) => i.status === 'idle' && !claimed.has(i.instanceId)) ?? null;
|
|
163
112
|
}
|
|
164
113
|
/** Record a decision in the log. */
|
|
165
114
|
_recordDecision(task, result, eligible) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/bot/orchestrator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/bot/orchestrator.ts"],"names":[],"mappings":"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"}
|
package/dist/bot/runner.d.ts
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
import type { AuditEventCallback, ExecutionEvent, WeaverConfig, WorkflowResult } from './types.js';
|
|
2
2
|
import type { NotificationErrorHandler } from './notifications.js';
|
|
3
|
+
export declare function buildSummary(result: unknown): string;
|
|
4
|
+
/**
|
|
5
|
+
* Build a markdown report from the workflow result's ctx field.
|
|
6
|
+
* Extracted for testability — same logic used inside runWorkflow.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildReport(result: Record<string, unknown> | null, success: boolean, stepLog?: import('./types.js').StepLogEntry[]): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Extract stepLog and plan from the result's ctx field.
|
|
11
|
+
* Extracted for testability — same logic used inside runWorkflow.
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractCtxData(result: Record<string, unknown> | null): {
|
|
14
|
+
stepLog?: import('./types.js').StepLogEntry[];
|
|
15
|
+
plan?: {
|
|
16
|
+
summary: string;
|
|
17
|
+
steps: Array<{
|
|
18
|
+
id: string;
|
|
19
|
+
operation: string;
|
|
20
|
+
description: string;
|
|
21
|
+
args?: Record<string, unknown>;
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Fallback: extract report from trace outputs (bot-report node's "Markdown report" port).
|
|
27
|
+
*/
|
|
28
|
+
export declare function extractReportFromTrace(trace: Array<{
|
|
29
|
+
type: string;
|
|
30
|
+
outputs?: unknown[];
|
|
31
|
+
}>): string | undefined;
|
|
3
32
|
export declare function runWorkflow(filePath: string, options?: {
|
|
4
33
|
params?: Record<string, unknown>;
|
|
5
34
|
verbose?: boolean;
|