@backendkit-labs/orchestrator-agent 0.1.1
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/AGENT.md +69 -0
- package/dist/config.d.ts +342 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +88 -0
- package/dist/config.js.map +1 -0
- package/dist/executor.d.ts +99 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +274 -0
- package/dist/executor.js.map +1 -0
- package/dist/planner.d.ts +21 -0
- package/dist/planner.d.ts.map +1 -0
- package/dist/planner.js +78 -0
- package/dist/planner.js.map +1 -0
- package/dist/profile.d.ts +4 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +36 -0
- package/dist/profile.js.map +1 -0
- package/dist/provider.d.ts +13 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +116 -0
- package/dist/provider.js.map +1 -0
- package/dist/run-store.d.ts +47 -0
- package/dist/run-store.d.ts.map +1 -0
- package/dist/run-store.js +28 -0
- package/dist/run-store.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +466 -0
- package/dist/server.js.map +1 -0
- package/dist/static-flow.d.ts +110 -0
- package/dist/static-flow.d.ts.map +1 -0
- package/dist/static-flow.js +82 -0
- package/dist/static-flow.js.map +1 -0
- package/package.json +40 -0
package/dist/executor.js
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { AgentEngine, AgentRegistry, ToolRegistry, ProviderRegistry, CallbackTransport, defineTool, } from '@backendkit-labs/agent-core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { OpenAICompatibleProvider, callLLM } from './provider.js';
|
|
4
|
+
// ── Executor ──────────────────────────────────────────────────────────────────
|
|
5
|
+
export class PlanExecutor {
|
|
6
|
+
config;
|
|
7
|
+
ragSearchFn;
|
|
8
|
+
onProgress;
|
|
9
|
+
reflection;
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
this.config = opts.config;
|
|
12
|
+
this.ragSearchFn = opts.ragSearchFn;
|
|
13
|
+
this.onProgress = opts.onProgress ?? (() => { });
|
|
14
|
+
this.reflection = opts.reflection;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Execute a plan from scratch or resume after a gate approval.
|
|
18
|
+
*
|
|
19
|
+
* @param plan Full task plan.
|
|
20
|
+
* @param priorResults Steps already completed in a previous execution segment
|
|
21
|
+
* (used when resuming after a gate). Those steps are treated
|
|
22
|
+
* as done and skipped.
|
|
23
|
+
*/
|
|
24
|
+
async execute(plan, priorResults = []) {
|
|
25
|
+
const results = [...priorResults];
|
|
26
|
+
const completed = new Set(priorResults.map(r => r.subtask_id));
|
|
27
|
+
const remaining = plan.subtasks.filter(st => !completed.has(st.id));
|
|
28
|
+
while (remaining.length > 0) {
|
|
29
|
+
const ready = remaining.filter(st => st.depends_on.every(dep => completed.has(dep)));
|
|
30
|
+
if (ready.length === 0) {
|
|
31
|
+
throw new Error('Circular dependency detected in task plan');
|
|
32
|
+
}
|
|
33
|
+
for (const subtask of ready) {
|
|
34
|
+
// Resolve explicit gate from subtask or agent config
|
|
35
|
+
const agentCfg = this.config.agents.find(a => a.id === subtask.agent_id);
|
|
36
|
+
const needsGate = subtask.gate ?? agentCfg?.gate ?? false;
|
|
37
|
+
const explicitCriteria = subtask.gate_criteria ?? agentCfg?.gate_criteria ?? [];
|
|
38
|
+
// ── Cable 2: check active policyRules before running ───────────
|
|
39
|
+
// Rules that match this step add criteria to the gate, turning
|
|
40
|
+
// un-gated steps into gated ones — deterministically, without LLM.
|
|
41
|
+
const { matchedRuleIds, ruleCriteria } = await this.checkActiveRules(subtask.task, agentCfg?.domain);
|
|
42
|
+
const forceGate = matchedRuleIds.length > 0;
|
|
43
|
+
const allCriteria = [...explicitCriteria, ...ruleCriteria];
|
|
44
|
+
if (forceGate) {
|
|
45
|
+
this.onProgress(` ⚠ [${subtask.id}] ${matchedRuleIds.length} policy rule(s) applied — gate enforced`);
|
|
46
|
+
}
|
|
47
|
+
// ─────────────────────────────────────────────────────────────────
|
|
48
|
+
const result = await this.runSubTask(subtask, results);
|
|
49
|
+
results.push(result);
|
|
50
|
+
completed.add(subtask.id);
|
|
51
|
+
remaining.splice(remaining.indexOf(subtask), 1);
|
|
52
|
+
if ((needsGate || forceGate) && result.success) {
|
|
53
|
+
return {
|
|
54
|
+
gateRequired: true,
|
|
55
|
+
stepId: subtask.id,
|
|
56
|
+
agentId: subtask.agent_id,
|
|
57
|
+
output: result.result,
|
|
58
|
+
criteria: allCriteria,
|
|
59
|
+
completedSoFar: results,
|
|
60
|
+
appliedRuleIds: matchedRuleIds,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const summary = this.consolidate(plan, results);
|
|
66
|
+
return { plan, results, summary, complete: true };
|
|
67
|
+
}
|
|
68
|
+
async runSubTask(subtask, priorResults) {
|
|
69
|
+
const agentCfg = this.config.agents.find(a => a.id === subtask.agent_id);
|
|
70
|
+
this.onProgress(` → [${subtask.id}] ${agentCfg?.name ?? subtask.agent_id}: ${subtask.task.slice(0, 80)}…`);
|
|
71
|
+
const start = Date.now();
|
|
72
|
+
try {
|
|
73
|
+
const result = agentCfg
|
|
74
|
+
? await this.runSpecialist(agentCfg, subtask, priorResults)
|
|
75
|
+
: `No agent configured for id: ${subtask.agent_id}`;
|
|
76
|
+
return {
|
|
77
|
+
subtask_id: subtask.id,
|
|
78
|
+
agent_id: subtask.agent_id,
|
|
79
|
+
task: subtask.task,
|
|
80
|
+
result,
|
|
81
|
+
success: true,
|
|
82
|
+
duration_ms: Date.now() - start,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
return {
|
|
87
|
+
subtask_id: subtask.id,
|
|
88
|
+
agent_id: subtask.agent_id,
|
|
89
|
+
task: subtask.task,
|
|
90
|
+
result: `Error: ${err instanceof Error ? err.message : String(err)}`,
|
|
91
|
+
success: false,
|
|
92
|
+
duration_ms: Date.now() - start,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async runSpecialist(agentCfg, subtask, priorResults) {
|
|
97
|
+
const providerCfg = this.config.providers[agentCfg.provider];
|
|
98
|
+
if (!providerCfg) {
|
|
99
|
+
throw new Error(`Provider "${agentCfg.provider}" not configured for agent "${agentCfg.id}"`);
|
|
100
|
+
}
|
|
101
|
+
const provider = new OpenAICompatibleProvider(providerCfg);
|
|
102
|
+
// Build vault context for this specialist
|
|
103
|
+
let vaultContext = '';
|
|
104
|
+
if (this.ragSearchFn) {
|
|
105
|
+
try {
|
|
106
|
+
vaultContext = await this.ragSearchFn(subtask.task);
|
|
107
|
+
}
|
|
108
|
+
catch { /* vault optional */ }
|
|
109
|
+
}
|
|
110
|
+
// Include relevant prior results as context
|
|
111
|
+
const priorContext = priorResults.length > 0
|
|
112
|
+
? '\n\nContext from previous steps:\n' +
|
|
113
|
+
priorResults.map(r => `[${r.agent_id}] ${r.task}\n→ ${r.result.slice(0, 300)}`).join('\n\n')
|
|
114
|
+
: '';
|
|
115
|
+
const systemPrompt = agentCfg.system_prompt ?? buildSpecialistPrompt(agentCfg);
|
|
116
|
+
const userPrompt = [
|
|
117
|
+
subtask.task,
|
|
118
|
+
vaultContext ? `\nRelevant knowledge:\n${vaultContext}` : '',
|
|
119
|
+
priorContext,
|
|
120
|
+
].filter(Boolean).join('\n');
|
|
121
|
+
return callLLM(provider, systemPrompt, userPrompt);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Cable 2: query active policyRules and match against this subtask.
|
|
125
|
+
* Returns matched rule IDs and the criteria text to show the human approver.
|
|
126
|
+
* No-op when reflection is not configured.
|
|
127
|
+
*/
|
|
128
|
+
async checkActiveRules(taskText, agentDomain) {
|
|
129
|
+
if (!this.reflection)
|
|
130
|
+
return { matchedRuleIds: [], ruleCriteria: [] };
|
|
131
|
+
let rules;
|
|
132
|
+
try {
|
|
133
|
+
rules = await this.reflection.activeRules({ domain: agentDomain });
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return { matchedRuleIds: [], ruleCriteria: [] };
|
|
137
|
+
}
|
|
138
|
+
const matchedRuleIds = [];
|
|
139
|
+
const ruleCriteria = [];
|
|
140
|
+
for (const rule of rules) {
|
|
141
|
+
if (matchesSubtask(rule, taskText, agentDomain)) {
|
|
142
|
+
matchedRuleIds.push(rule.id);
|
|
143
|
+
ruleCriteria.push(...ruleToGateCriteria(rule));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return { matchedRuleIds, ruleCriteria };
|
|
147
|
+
}
|
|
148
|
+
consolidate(plan, results) {
|
|
149
|
+
const successCount = results.filter(r => r.success).length;
|
|
150
|
+
const lines = [
|
|
151
|
+
`## ${plan.summary}`,
|
|
152
|
+
`Completed ${successCount}/${results.length} sub-tasks.`,
|
|
153
|
+
'',
|
|
154
|
+
];
|
|
155
|
+
for (const r of results) {
|
|
156
|
+
const icon = r.success ? '✓' : '✗';
|
|
157
|
+
lines.push(`**${icon} [${r.agent_id}]** ${r.task.slice(0, 80)}`);
|
|
158
|
+
lines.push(r.result.slice(0, 500));
|
|
159
|
+
lines.push('');
|
|
160
|
+
}
|
|
161
|
+
return lines.join('\n');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Returns true when a policyRule applies to a subtask.
|
|
166
|
+
* Match requires at least one of:
|
|
167
|
+
* - domain match + keyword hit
|
|
168
|
+
* - domain match + no keywords (catch-all for that domain)
|
|
169
|
+
* - no domain specified + keyword hit
|
|
170
|
+
* A rule with neither domain nor keywords is skipped (too broad).
|
|
171
|
+
*/
|
|
172
|
+
function matchesSubtask(rule, taskText, agentDomain) {
|
|
173
|
+
const cond = rule.if;
|
|
174
|
+
if (cond.domain) {
|
|
175
|
+
if (!agentDomain)
|
|
176
|
+
return false;
|
|
177
|
+
const domains = Array.isArray(cond.domain) ? cond.domain : [cond.domain];
|
|
178
|
+
if (!domains.includes(agentDomain))
|
|
179
|
+
return false;
|
|
180
|
+
// Domain matched — keywords narrow it further; if none, it's a domain catch-all
|
|
181
|
+
if (!cond.keywords?.length)
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
if (cond.keywords?.length) {
|
|
185
|
+
const lower = taskText.toLowerCase();
|
|
186
|
+
return cond.keywords.some((kw) => lower.includes(kw.toLowerCase()));
|
|
187
|
+
}
|
|
188
|
+
return false; // no domain, no keywords → too broad
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Converts a policyRule's `then` action into human-readable gate criteria.
|
|
192
|
+
* These criteria are shown to the approver alongside the agent's output.
|
|
193
|
+
*/
|
|
194
|
+
function ruleToGateCriteria(rule) {
|
|
195
|
+
const a = rule.then;
|
|
196
|
+
const criteria = [];
|
|
197
|
+
if (a.mustInclude?.length)
|
|
198
|
+
criteria.push(`Debe incluir: ${a.mustInclude.join(', ')}`);
|
|
199
|
+
if (a.mustPass?.length)
|
|
200
|
+
criteria.push(`Debe cumplir: ${a.mustPass.join(', ')}`);
|
|
201
|
+
if (a.mustExecute?.length)
|
|
202
|
+
criteria.push(`Debe ejecutar: ${a.mustExecute.join(', ')}`);
|
|
203
|
+
if (a.requireArchitectureReview)
|
|
204
|
+
criteria.push('Requiere revisión de arquitectura');
|
|
205
|
+
if (a.requireSecurityReview)
|
|
206
|
+
criteria.push('Requiere revisión de seguridad');
|
|
207
|
+
if (a.requireQaApproval)
|
|
208
|
+
criteria.push('Requiere aprobación de QA');
|
|
209
|
+
return criteria.length > 0
|
|
210
|
+
? criteria
|
|
211
|
+
: [`Política "${rule.name}" aplicada — revisión requerida`];
|
|
212
|
+
}
|
|
213
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
214
|
+
function buildSpecialistPrompt(agent) {
|
|
215
|
+
return [
|
|
216
|
+
`You are ${agent.name}, a specialist agent.`,
|
|
217
|
+
'',
|
|
218
|
+
`Domain: ${agent.description}`,
|
|
219
|
+
`Capabilities: ${agent.capabilities.join(', ')}`,
|
|
220
|
+
'',
|
|
221
|
+
'Execute the assigned task thoroughly and return a structured, actionable result.',
|
|
222
|
+
'Stay within your domain. If a request is outside your capabilities, say so clearly.',
|
|
223
|
+
].join('\n');
|
|
224
|
+
}
|
|
225
|
+
// ── Orchestrator engine (for interactive mode) ────────────────────────────────
|
|
226
|
+
// Builds a full AgentEngine with ask_agent tool for direct LLM-driven orchestration.
|
|
227
|
+
export function buildOrchestratorEngine(opts) {
|
|
228
|
+
const { config, orchestratorProfile, ragTool, ragSearchFn, onProgress } = opts;
|
|
229
|
+
const executor = new PlanExecutor({ config, ragSearchFn, onProgress });
|
|
230
|
+
const askAgentTool = defineTool({
|
|
231
|
+
name: 'ask_agent',
|
|
232
|
+
description: 'Delegate a task to a configured specialist agent',
|
|
233
|
+
input: z.object({
|
|
234
|
+
agent_id: z.string().describe('ID of the specialist agent from orchestrator.yaml'),
|
|
235
|
+
task: z.string().describe('Specific task for the specialist to execute'),
|
|
236
|
+
}),
|
|
237
|
+
execute: async ({ agent_id, task }) => {
|
|
238
|
+
const agentCfg = config.agents.find(a => a.id === agent_id);
|
|
239
|
+
if (!agentCfg) {
|
|
240
|
+
return `No agent with id "${agent_id}". Available: ${config.agents.map(a => a.id).join(', ')}`;
|
|
241
|
+
}
|
|
242
|
+
onProgress?.(` → delegating to ${agentCfg.name}…`);
|
|
243
|
+
return executor['runSpecialist'](agentCfg, { id: 'x', agent_id, task, depends_on: [] }, []);
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
const tools = new ToolRegistry();
|
|
247
|
+
if (ragTool)
|
|
248
|
+
tools.register(ragTool);
|
|
249
|
+
tools.register(askAgentTool);
|
|
250
|
+
const orchestratorProviderCfg = config.providers[config.orchestrator.provider];
|
|
251
|
+
if (!orchestratorProviderCfg) {
|
|
252
|
+
throw new Error(`Orchestrator provider "${config.orchestrator.provider}" not found in providers config`);
|
|
253
|
+
}
|
|
254
|
+
const providers = new ProviderRegistry();
|
|
255
|
+
providers.register(config.orchestrator.provider, new OpenAICompatibleProvider(orchestratorProviderCfg));
|
|
256
|
+
const agents = new AgentRegistry();
|
|
257
|
+
agents.register(orchestratorProfile);
|
|
258
|
+
const transport = new CallbackTransport((evt) => {
|
|
259
|
+
if (evt.type === 'tool_call')
|
|
260
|
+
onProgress?.(` ● ${evt.name}`);
|
|
261
|
+
});
|
|
262
|
+
return new AgentEngine({
|
|
263
|
+
model: { provider: config.orchestrator.provider, id: orchestratorProviderCfg.model },
|
|
264
|
+
agents,
|
|
265
|
+
tools,
|
|
266
|
+
providers,
|
|
267
|
+
defaultProvider: config.orchestrator.provider,
|
|
268
|
+
defaultAgentId: 'orchestrator',
|
|
269
|
+
transport,
|
|
270
|
+
maxIterations: 20,
|
|
271
|
+
iterationMode: 'auto',
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AgentConfig } from './config.js';
|
|
2
|
+
export interface SubTask {
|
|
3
|
+
id: string;
|
|
4
|
+
agent_id: string;
|
|
5
|
+
task: string;
|
|
6
|
+
depends_on: string[];
|
|
7
|
+
gate?: boolean;
|
|
8
|
+
gate_criteria?: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface TaskPlan {
|
|
11
|
+
summary: string;
|
|
12
|
+
subtasks: SubTask[];
|
|
13
|
+
}
|
|
14
|
+
export declare class TaskPlanner {
|
|
15
|
+
private readonly callLLM;
|
|
16
|
+
constructor(callLLM: (system: string, user: string) => Promise<string>);
|
|
17
|
+
plan(task: string, agents: AgentConfig[], vaultContext?: string): Promise<TaskPlan>;
|
|
18
|
+
private parse;
|
|
19
|
+
private validate;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=planner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,MAAM,WAAW,OAAO;IACpB,EAAE,EAAc,MAAM,CAAC;IACvB,QAAQ,EAAQ,MAAM,CAAC;IACvB,IAAI,EAAY,MAAM,CAAC;IACvB,UAAU,EAAM,MAAM,EAAE,CAAC;IACzB,IAAI,CAAC,EAAW,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,QAAQ;IACrB,OAAO,EAAI,MAAM,CAAC;IAClB,QAAQ,EAAG,OAAO,EAAE,CAAC;CACxB;AA6BD,qBAAa,WAAW;IAEhB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC;IAGzE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsBzF,OAAO,CAAC,KAAK;IAcb,OAAO,CAAC,QAAQ;CAgBnB"}
|
package/dist/planner.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// ── Prompt ────────────────────────────────────────────────────────────────────
|
|
2
|
+
const PLANNER_SYSTEM = `You are a task decomposition expert.
|
|
3
|
+
Given a task and a list of available specialist agents, produce a JSON execution plan.
|
|
4
|
+
|
|
5
|
+
Output ONLY valid JSON — no markdown, no explanation:
|
|
6
|
+
{
|
|
7
|
+
"summary": "one-line description of the overall plan",
|
|
8
|
+
"subtasks": [
|
|
9
|
+
{
|
|
10
|
+
"id": "t1",
|
|
11
|
+
"agent_id": "agent-id-from-list",
|
|
12
|
+
"task": "specific, actionable instruction for this specialist",
|
|
13
|
+
"depends_on": []
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Rules:
|
|
19
|
+
- Use only agent IDs from the provided list.
|
|
20
|
+
- depends_on: [] means the sub-task can start immediately.
|
|
21
|
+
- depends_on: ["t1"] means this sub-task waits for t1 to finish.
|
|
22
|
+
- If no agent matches a needed capability, use agent_id="unresolved" and note the gap in the task field.
|
|
23
|
+
- Keep each task description focused and self-contained.`;
|
|
24
|
+
// ── TaskPlanner ───────────────────────────────────────────────────────────────
|
|
25
|
+
export class TaskPlanner {
|
|
26
|
+
callLLM;
|
|
27
|
+
constructor(callLLM) {
|
|
28
|
+
this.callLLM = callLLM;
|
|
29
|
+
}
|
|
30
|
+
async plan(task, agents, vaultContext) {
|
|
31
|
+
const agentList = agents
|
|
32
|
+
.map(a => `- id: ${a.id}\n name: ${a.name}\n capabilities: [${a.capabilities.join(', ')}]`)
|
|
33
|
+
.join('\n');
|
|
34
|
+
const contextBlock = vaultContext
|
|
35
|
+
? `\nKnowledge base context (use to inform the plan):\n${vaultContext}\n`
|
|
36
|
+
: '';
|
|
37
|
+
const user = [
|
|
38
|
+
`Task: ${task}`,
|
|
39
|
+
contextBlock,
|
|
40
|
+
'Available agents:',
|
|
41
|
+
agentList,
|
|
42
|
+
'',
|
|
43
|
+
'Produce the execution plan as JSON.',
|
|
44
|
+
].join('\n');
|
|
45
|
+
const raw = await this.callLLM(PLANNER_SYSTEM, user);
|
|
46
|
+
return this.parse(raw);
|
|
47
|
+
}
|
|
48
|
+
parse(raw) {
|
|
49
|
+
const jsonMatch = raw.match(/```(?:json)?\s*([\s\S]*?)```/) ?? raw.match(/(\{[\s\S]*\})/);
|
|
50
|
+
const jsonStr = jsonMatch ? jsonMatch[1].trim() : raw.trim();
|
|
51
|
+
try {
|
|
52
|
+
const plan = JSON.parse(jsonStr);
|
|
53
|
+
this.validate(plan);
|
|
54
|
+
return plan;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
throw new Error(`TaskPlanner: could not parse plan.\nRaw output: ${raw.slice(0, 500)}\nError: ${String(err)}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
validate(plan) {
|
|
61
|
+
if (!plan.summary || !Array.isArray(plan.subtasks)) {
|
|
62
|
+
throw new Error('Plan missing required fields: summary, subtasks');
|
|
63
|
+
}
|
|
64
|
+
for (const st of plan.subtasks) {
|
|
65
|
+
if (!st.id || !st.agent_id || !st.task || !Array.isArray(st.depends_on)) {
|
|
66
|
+
throw new Error(`Sub-task malformed: ${JSON.stringify(st)}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const ids = new Set(plan.subtasks.map(s => s.id));
|
|
70
|
+
for (const st of plan.subtasks) {
|
|
71
|
+
for (const dep of st.depends_on) {
|
|
72
|
+
if (!ids.has(dep))
|
|
73
|
+
throw new Error(`Sub-task ${st.id} depends on unknown id: ${dep}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=planner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAKtD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAkCjF"}
|
package/dist/profile.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Builds the orchestrator's AgentProfile dynamically from orchestrator.yaml.
|
|
2
|
+
// The system prompt is generated from configured agents — not hardcoded.
|
|
3
|
+
export function buildOrchestratorProfile(config) {
|
|
4
|
+
const agentList = config.agents
|
|
5
|
+
.map(a => ` - ${a.id} (${a.name}): ${a.description}\n capabilities: [${a.capabilities.join(', ')}]`)
|
|
6
|
+
.join('\n');
|
|
7
|
+
const systemPrompt = [
|
|
8
|
+
`You are ${config.orchestrator.name}, an intelligent task orchestrator.`,
|
|
9
|
+
'',
|
|
10
|
+
'Your responsibilities:',
|
|
11
|
+
'1. Understand the user\'s request and identify which specialists are needed.',
|
|
12
|
+
'2. Search the shared knowledge vault with search_knowledge for relevant context.',
|
|
13
|
+
'3. Delegate each part of the task to the appropriate specialist via ask_agent.',
|
|
14
|
+
'4. For independent tasks, you can call ask_agent multiple times.',
|
|
15
|
+
'5. Consolidate all results into a coherent, actionable final answer.',
|
|
16
|
+
'',
|
|
17
|
+
'Available specialists:',
|
|
18
|
+
agentList,
|
|
19
|
+
'',
|
|
20
|
+
'Rules:',
|
|
21
|
+
'- Always search the vault before delegating — existing decisions should guide the plan.',
|
|
22
|
+
'- Never execute domain work yourself — delegate everything to specialists.',
|
|
23
|
+
'- If a task requires capabilities no agent has, say so explicitly.',
|
|
24
|
+
'- Cite specialist results in your final answer.',
|
|
25
|
+
].join('\n');
|
|
26
|
+
return {
|
|
27
|
+
id: 'orchestrator',
|
|
28
|
+
name: config.orchestrator.name,
|
|
29
|
+
icon: '◆',
|
|
30
|
+
description: 'Dynamic task orchestrator — routes and coordinates configured specialist agents.',
|
|
31
|
+
systemPrompt,
|
|
32
|
+
allowedTools: ['search_knowledge', 'ask_agent'],
|
|
33
|
+
delegatesTo: config.agents.map(a => a.id),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.js","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"AAGA,6EAA6E;AAC7E,yEAAyE;AAEzE,MAAM,UAAU,wBAAwB,CAAC,MAA0B;IAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,WAAW,wBAAwB,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;SACvG,IAAI,CAAC,IAAI,CAAC,CAAC;IAEhB,MAAM,YAAY,GAAG;QACjB,WAAW,MAAM,CAAC,YAAY,CAAC,IAAI,qCAAqC;QACxE,EAAE;QACF,wBAAwB;QACxB,8EAA8E;QAC9E,kFAAkF;QAClF,gFAAgF;QAChF,kEAAkE;QAClE,sEAAsE;QACtE,EAAE;QACF,wBAAwB;QACxB,SAAS;QACT,EAAE;QACF,QAAQ;QACR,yFAAyF;QACzF,4EAA4E;QAC5E,oEAAoE;QACpE,iDAAiD;KACpD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO;QACH,EAAE,EAAY,cAAc;QAC5B,IAAI,EAAU,MAAM,CAAC,YAAY,CAAC,IAAI;QACtC,IAAI,EAAU,GAAG;QACjB,WAAW,EAAG,kFAAkF;QAChG,YAAY;QACZ,YAAY,EAAE,CAAC,kBAAkB,EAAE,WAAW,CAAC;QAC/C,WAAW,EAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { LLMProvider, LLMMessage, LLMStreamCallbacks, ToolDefinition } from '@backendkit-labs/agent-core';
|
|
2
|
+
import type { ProviderConfig } from './config.js';
|
|
3
|
+
export declare class OpenAICompatibleProvider implements LLMProvider {
|
|
4
|
+
private readonly client;
|
|
5
|
+
private readonly model;
|
|
6
|
+
private readonly maxRetries;
|
|
7
|
+
private readonly temperature;
|
|
8
|
+
constructor(cfg: ProviderConfig, maxRetries?: number);
|
|
9
|
+
chat(messages: LLMMessage[], tools: ToolDefinition[], callbacks: LLMStreamCallbacks): Promise<void>;
|
|
10
|
+
private stream;
|
|
11
|
+
}
|
|
12
|
+
export declare function callLLM(provider: OpenAICompatibleProvider, system: string, user: string): Promise<string>;
|
|
13
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC/G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAiBlD,qBAAa,wBAAyB,YAAW,WAAW;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,GAAG,EAAE,cAAc,EAAE,UAAU,SAAI;IAWzC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,SAAS,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;YA2B3F,MAAM;CA8CvB;AAID,wBAAsB,OAAO,CACzB,QAAQ,EAAE,wBAAwB,EAClC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAgBjB"}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
// OpenAI-compatible provider — covers DeepSeek, Ollama, and OpenAI.
|
|
3
|
+
// DeepSeek: base_url=https://api.deepseek.com
|
|
4
|
+
// Ollama: base_url=http://localhost:11434/v1, api_key=ollama
|
|
5
|
+
// OpenAI: base_url omitted (default)
|
|
6
|
+
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
7
|
+
function isRetryable(err) {
|
|
8
|
+
if (err && typeof err === 'object' && 'status' in err) {
|
|
9
|
+
const s = err.status;
|
|
10
|
+
return s === 429 || s >= 500;
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
export class OpenAICompatibleProvider {
|
|
15
|
+
client;
|
|
16
|
+
model;
|
|
17
|
+
maxRetries;
|
|
18
|
+
temperature;
|
|
19
|
+
constructor(cfg, maxRetries = 3) {
|
|
20
|
+
this.client = new OpenAI({
|
|
21
|
+
apiKey: cfg.api_key ?? 'no-key',
|
|
22
|
+
baseURL: cfg.base_url,
|
|
23
|
+
maxRetries: 0,
|
|
24
|
+
});
|
|
25
|
+
this.model = cfg.model;
|
|
26
|
+
this.maxRetries = maxRetries;
|
|
27
|
+
this.temperature = cfg.model.includes('reasoner') ? 1 : 0;
|
|
28
|
+
}
|
|
29
|
+
async chat(messages, tools, callbacks) {
|
|
30
|
+
const oaiTools = tools.map(t => ({
|
|
31
|
+
type: 'function',
|
|
32
|
+
function: { name: t.name, description: t.description, parameters: t.parameters },
|
|
33
|
+
}));
|
|
34
|
+
let attempt = 0;
|
|
35
|
+
let emitted = false;
|
|
36
|
+
while (attempt < this.maxRetries) {
|
|
37
|
+
attempt++;
|
|
38
|
+
try {
|
|
39
|
+
await this.stream(messages, oaiTools, {
|
|
40
|
+
...callbacks,
|
|
41
|
+
onChunk: (d) => { emitted = true; callbacks.onChunk?.(d); },
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
if (emitted || !isRetryable(err) || attempt >= this.maxRetries) {
|
|
47
|
+
callbacks.onError(err instanceof Error ? err : new Error(String(err)));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await sleep(Math.min(1000 * 2 ** attempt, 16_000));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async stream(messages, oaiTools, callbacks) {
|
|
55
|
+
const stream = await this.client.chat.completions.create({
|
|
56
|
+
model: this.model,
|
|
57
|
+
messages: messages,
|
|
58
|
+
tools: oaiTools.length ? oaiTools : undefined,
|
|
59
|
+
tool_choice: oaiTools.length ? 'auto' : undefined,
|
|
60
|
+
temperature: this.temperature,
|
|
61
|
+
stream: true,
|
|
62
|
+
stream_options: { include_usage: true },
|
|
63
|
+
});
|
|
64
|
+
let content = '';
|
|
65
|
+
const toolBuffers = new Map();
|
|
66
|
+
for await (const chunk of stream) {
|
|
67
|
+
if (chunk.usage)
|
|
68
|
+
callbacks.onMetrics?.(chunk.usage.prompt_tokens, chunk.usage.completion_tokens);
|
|
69
|
+
const delta = chunk.choices[0]?.delta;
|
|
70
|
+
if (!delta)
|
|
71
|
+
continue;
|
|
72
|
+
if (delta.content) {
|
|
73
|
+
content += delta.content;
|
|
74
|
+
callbacks.onChunk?.(delta.content);
|
|
75
|
+
}
|
|
76
|
+
if (delta.tool_calls) {
|
|
77
|
+
for (const tc of delta.tool_calls) {
|
|
78
|
+
if (!toolBuffers.has(tc.index))
|
|
79
|
+
toolBuffers.set(tc.index, { id: '', name: '', args: '' });
|
|
80
|
+
const buf = toolBuffers.get(tc.index);
|
|
81
|
+
if (tc.id)
|
|
82
|
+
buf.id = tc.id;
|
|
83
|
+
if (tc.function?.name)
|
|
84
|
+
buf.name += tc.function.name;
|
|
85
|
+
if (tc.function?.arguments)
|
|
86
|
+
buf.args += tc.function.arguments;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const toolCalls = [...toolBuffers.entries()]
|
|
91
|
+
.sort(([a], [b]) => a - b)
|
|
92
|
+
.map(([, b]) => ({ id: b.id, type: 'function', function: { name: b.name, arguments: b.args } }));
|
|
93
|
+
for (const tc of toolCalls)
|
|
94
|
+
callbacks.onToolCall?.(tc.function.name, tc.function.arguments, tc.id);
|
|
95
|
+
callbacks.onDone({
|
|
96
|
+
role: 'assistant',
|
|
97
|
+
content: content || null,
|
|
98
|
+
tool_calls: toolCalls.length ? toolCalls : undefined,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// ── Simple one-shot LLM call (no tools, no streaming, returns full text) ─────
|
|
103
|
+
export async function callLLM(provider, system, user) {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
let result = '';
|
|
106
|
+
provider.chat([
|
|
107
|
+
{ role: 'system', content: system },
|
|
108
|
+
{ role: 'user', content: user },
|
|
109
|
+
], [], {
|
|
110
|
+
onChunk: (d) => { result += d; },
|
|
111
|
+
onDone: () => { resolve(result); },
|
|
112
|
+
onError: (err) => { reject(err); },
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAI5B,oEAAoE;AACpE,8CAA8C;AAC9C,+DAA+D;AAC/D,uCAAuC;AAEvC,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAExE,SAAS,WAAW,CAAC,GAAY;IAC7B,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,QAAQ,IAAI,GAAG,EAAE,CAAC;QACpD,MAAM,CAAC,GAAI,GAA0B,CAAC,MAAM,CAAC;QAC7C,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC;IACjC,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,MAAM,OAAO,wBAAwB;IAChB,MAAM,CAAS;IACf,KAAK,CAAS;IACd,UAAU,CAAS;IACnB,WAAW,CAAS;IAErC,YAAY,GAAmB,EAAE,UAAU,GAAG,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC;YACrB,MAAM,EAAE,GAAG,CAAC,OAAO,IAAI,QAAQ;YAC/B,OAAO,EAAE,GAAG,CAAC,QAAQ;YACrB,UAAU,EAAE,CAAC;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,GAAS,GAAG,CAAC,KAAK,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAI,UAAU,CAAC;QAC9B,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAsB,EAAE,KAAuB,EAAE,SAA6B;QACrF,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7B,IAAI,EAAE,UAAmB;YACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE;SACnF,CAAC,CAAqC,CAAC;QAExC,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,OAAO,GAAI,KAAK,CAAC;QAErB,OAAO,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC/B,OAAO,EAAE,CAAC;YACV,IAAI,CAAC;gBACD,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE;oBAClC,GAAG,SAAS;oBACZ,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;iBAC9D,CAAC,CAAC;gBACH,OAAO;YACX,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,IAAI,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBAC7D,SAAS,CAAC,OAAO,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBACvE,OAAO;gBACX,CAAC;gBACD,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;YACvD,CAAC;QACL,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,MAAM,CAChB,QAAsB,EACtB,QAA0C,EAC1C,SAA6B;QAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;YACrD,KAAK,EAAW,IAAI,CAAC,KAAK;YAC1B,QAAQ,EAAQ,QAAoD;YACpE,KAAK,EAAW,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAI,CAAC,CAAC,SAAS;YACzD,WAAW,EAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAM,CAAC,CAAC,SAAS;YACzD,WAAW,EAAK,IAAI,CAAC,WAAW;YAChC,MAAM,EAAU,IAAI;YACpB,cAAc,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;SAC1C,CAAC,CAAC;QAEH,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsD,CAAC;QAElF,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC/B,IAAI,KAAK,CAAC,KAAK;gBAAE,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACjG,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;YACtC,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC;gBAAC,SAAS,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YACpF,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBACnB,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBAChC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC;wBAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC1F,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAE,CAAC;oBACvC,IAAI,EAAE,CAAC,EAAE;wBAAkB,GAAG,CAAC,EAAE,GAAK,EAAE,CAAC,EAAE,CAAC;oBAC5C,IAAI,EAAE,CAAC,QAAQ,EAAE,IAAI;wBAAO,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACzD,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS;wBAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAClE,CAAC;YACL,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAG,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;aACvC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAmB,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAE9G,KAAK,MAAM,EAAE,IAAI,SAAS;YAAE,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAEnG,SAAS,CAAC,MAAM,CAAC;YACb,IAAI,EAAQ,WAAW;YACvB,OAAO,EAAK,OAAO,IAAI,IAAI;YAC3B,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;SACvD,CAAC,CAAC;IACP,CAAC;CACJ;AAED,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,OAAO,CACzB,QAAkC,EAClC,MAAc,EACd,IAAY;IAEZ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CACT;YACI,EAAE,IAAI,EAAE,QAAQ,EAAK,OAAO,EAAE,MAAM,EAAE;YACtC,EAAE,IAAI,EAAE,MAAM,EAAO,OAAO,EAAE,IAAI,EAAI;SACzC,EACD,EAAE,EACF;YACI,OAAO,EAAG,CAAC,CAAC,EAAI,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,EAAI,GAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvC,OAAO,EAAG,CAAC,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACtC,CACJ,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type RunStatus = 'running' | 'waiting_gate' | 'complete' | 'failed';
|
|
2
|
+
export interface StepResult {
|
|
3
|
+
stepId: string;
|
|
4
|
+
agentId: string;
|
|
5
|
+
task: string;
|
|
6
|
+
output: string;
|
|
7
|
+
success: boolean;
|
|
8
|
+
durationMs: number;
|
|
9
|
+
}
|
|
10
|
+
export interface GatePending {
|
|
11
|
+
gateId: string;
|
|
12
|
+
stepId: string;
|
|
13
|
+
agentId: string;
|
|
14
|
+
output: string;
|
|
15
|
+
criteria: string[];
|
|
16
|
+
requestedAt: string;
|
|
17
|
+
/** IDs of policyRules that triggered this gate automatically (Cable 2). */
|
|
18
|
+
appliedRuleIds?: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface RunState {
|
|
21
|
+
runId: string;
|
|
22
|
+
task: string;
|
|
23
|
+
configPath: string;
|
|
24
|
+
status: RunStatus;
|
|
25
|
+
startedAt: string;
|
|
26
|
+
updatedAt: string;
|
|
27
|
+
completedAt?: string;
|
|
28
|
+
plan?: unknown;
|
|
29
|
+
completedSteps: StepResult[];
|
|
30
|
+
currentStep?: {
|
|
31
|
+
stepId: string;
|
|
32
|
+
agentId: string;
|
|
33
|
+
startedAt: string;
|
|
34
|
+
};
|
|
35
|
+
waitingGate?: GatePending;
|
|
36
|
+
vaultNotePath?: string;
|
|
37
|
+
finalReport?: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare class RunStore {
|
|
41
|
+
private readonly dir;
|
|
42
|
+
constructor(dir?: string);
|
|
43
|
+
newRunId(): string;
|
|
44
|
+
save(state: RunState): void;
|
|
45
|
+
load(runId: string): RunState | null;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=run-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-store.d.ts","sourceRoot":"","sources":["../src/run-store.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,cAAc,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3E,MAAM,WAAW,UAAU;IACvB,MAAM,EAAM,MAAM,CAAC;IACnB,OAAO,EAAK,MAAM,CAAC;IACnB,IAAI,EAAQ,MAAM,CAAC;IACnB,MAAM,EAAM,MAAM,CAAC;IACnB,OAAO,EAAK,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IACxB,MAAM,EAAW,MAAM,CAAC;IACxB,MAAM,EAAW,MAAM,CAAC;IACxB,OAAO,EAAU,MAAM,CAAC;IACxB,MAAM,EAAW,MAAM,CAAC;IACxB,QAAQ,EAAS,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAM,MAAM,CAAC;IACxB,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACrB,KAAK,EAAY,MAAM,CAAC;IACxB,IAAI,EAAa,MAAM,CAAC;IACxB,UAAU,EAAO,MAAM,CAAC;IACxB,MAAM,EAAW,SAAS,CAAC;IAC3B,SAAS,EAAQ,MAAM,CAAC;IACxB,SAAS,EAAQ,MAAM,CAAC;IACxB,WAAW,CAAC,EAAK,MAAM,CAAC;IACxB,IAAI,CAAC,EAAY,OAAO,CAAC;IACzB,cAAc,EAAG,UAAU,EAAE,CAAC;IAC9B,WAAW,CAAC,EAAK;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACxE,WAAW,CAAC,EAAK,WAAW,CAAC;IAC7B,aAAa,CAAC,EAAG,MAAM,CAAC;IACxB,WAAW,CAAC,EAAK,MAAM,CAAC;IACxB,KAAK,CAAC,EAAW,MAAM,CAAC;CAC3B;AAMD,qBAAa,QAAQ;IACjB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;gBAEjB,GAAG,SAAc;IAK7B,QAAQ,IAAI,MAAM;IAIlB,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAS3B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;CASvC"}
|