@soleri/core 2.1.0 → 2.4.0
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/brain/brain.d.ts +3 -1
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +60 -4
- package/dist/brain/brain.js.map +1 -1
- package/dist/brain/intelligence.d.ts +36 -1
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +119 -14
- package/dist/brain/intelligence.js.map +1 -1
- package/dist/brain/types.d.ts +32 -0
- package/dist/brain/types.d.ts.map +1 -1
- package/dist/control/identity-manager.d.ts +22 -0
- package/dist/control/identity-manager.d.ts.map +1 -0
- package/dist/control/identity-manager.js +233 -0
- package/dist/control/identity-manager.js.map +1 -0
- package/dist/control/intent-router.d.ts +32 -0
- package/dist/control/intent-router.d.ts.map +1 -0
- package/dist/control/intent-router.js +242 -0
- package/dist/control/intent-router.js.map +1 -0
- package/dist/control/types.d.ts +68 -0
- package/dist/control/types.d.ts.map +1 -0
- package/dist/control/types.js +9 -0
- package/dist/control/types.js.map +1 -0
- package/dist/curator/curator.d.ts +29 -0
- package/dist/curator/curator.d.ts.map +1 -1
- package/dist/curator/curator.js +135 -0
- package/dist/curator/curator.js.map +1 -1
- package/dist/facades/types.d.ts +1 -1
- package/dist/governance/governance.d.ts +42 -0
- package/dist/governance/governance.d.ts.map +1 -0
- package/dist/governance/governance.js +488 -0
- package/dist/governance/governance.js.map +1 -0
- package/dist/governance/index.d.ts +3 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/index.js +2 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/governance/types.d.ts +102 -0
- package/dist/governance/types.d.ts.map +1 -0
- package/dist/governance/types.js +3 -0
- package/dist/governance/types.js.map +1 -0
- package/dist/index.d.ts +32 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/logger.d.ts +37 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +145 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/types.d.ts +19 -0
- package/dist/logging/types.d.ts.map +1 -0
- package/dist/logging/types.js +2 -0
- package/dist/logging/types.js.map +1 -0
- package/dist/loop/loop-manager.d.ts +49 -0
- package/dist/loop/loop-manager.d.ts.map +1 -0
- package/dist/loop/loop-manager.js +105 -0
- package/dist/loop/loop-manager.js.map +1 -0
- package/dist/loop/types.d.ts +35 -0
- package/dist/loop/types.d.ts.map +1 -0
- package/dist/loop/types.js +8 -0
- package/dist/loop/types.js.map +1 -0
- package/dist/planning/gap-analysis.d.ts +29 -0
- package/dist/planning/gap-analysis.d.ts.map +1 -0
- package/dist/planning/gap-analysis.js +265 -0
- package/dist/planning/gap-analysis.js.map +1 -0
- package/dist/planning/gap-types.d.ts +29 -0
- package/dist/planning/gap-types.d.ts.map +1 -0
- package/dist/planning/gap-types.js +28 -0
- package/dist/planning/gap-types.js.map +1 -0
- package/dist/planning/planner.d.ts +150 -1
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +365 -2
- package/dist/planning/planner.js.map +1 -1
- package/dist/project/project-registry.d.ts +79 -0
- package/dist/project/project-registry.d.ts.map +1 -0
- package/dist/project/project-registry.js +276 -0
- package/dist/project/project-registry.js.map +1 -0
- package/dist/project/types.d.ts +28 -0
- package/dist/project/types.d.ts.map +1 -0
- package/dist/project/types.js +5 -0
- package/dist/project/types.js.map +1 -0
- package/dist/runtime/admin-extra-ops.d.ts +13 -0
- package/dist/runtime/admin-extra-ops.d.ts.map +1 -0
- package/dist/runtime/admin-extra-ops.js +284 -0
- package/dist/runtime/admin-extra-ops.js.map +1 -0
- package/dist/runtime/admin-ops.d.ts +15 -0
- package/dist/runtime/admin-ops.d.ts.map +1 -0
- package/dist/runtime/admin-ops.js +322 -0
- package/dist/runtime/admin-ops.js.map +1 -0
- package/dist/runtime/capture-ops.d.ts +15 -0
- package/dist/runtime/capture-ops.d.ts.map +1 -0
- package/dist/runtime/capture-ops.js +345 -0
- package/dist/runtime/capture-ops.js.map +1 -0
- package/dist/runtime/core-ops.d.ts +7 -3
- package/dist/runtime/core-ops.d.ts.map +1 -1
- package/dist/runtime/core-ops.js +474 -8
- package/dist/runtime/core-ops.js.map +1 -1
- package/dist/runtime/curator-extra-ops.d.ts +9 -0
- package/dist/runtime/curator-extra-ops.d.ts.map +1 -0
- package/dist/runtime/curator-extra-ops.js +59 -0
- package/dist/runtime/curator-extra-ops.js.map +1 -0
- package/dist/runtime/domain-ops.d.ts.map +1 -1
- package/dist/runtime/domain-ops.js +59 -13
- package/dist/runtime/domain-ops.js.map +1 -1
- package/dist/runtime/grading-ops.d.ts +14 -0
- package/dist/runtime/grading-ops.d.ts.map +1 -0
- package/dist/runtime/grading-ops.js +105 -0
- package/dist/runtime/grading-ops.js.map +1 -0
- package/dist/runtime/loop-ops.d.ts +13 -0
- package/dist/runtime/loop-ops.d.ts.map +1 -0
- package/dist/runtime/loop-ops.js +179 -0
- package/dist/runtime/loop-ops.js.map +1 -0
- package/dist/runtime/memory-cross-project-ops.d.ts +12 -0
- package/dist/runtime/memory-cross-project-ops.d.ts.map +1 -0
- package/dist/runtime/memory-cross-project-ops.js +165 -0
- package/dist/runtime/memory-cross-project-ops.js.map +1 -0
- package/dist/runtime/memory-extra-ops.d.ts +13 -0
- package/dist/runtime/memory-extra-ops.d.ts.map +1 -0
- package/dist/runtime/memory-extra-ops.js +173 -0
- package/dist/runtime/memory-extra-ops.js.map +1 -0
- package/dist/runtime/orchestrate-ops.d.ts +17 -0
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -0
- package/dist/runtime/orchestrate-ops.js +240 -0
- package/dist/runtime/orchestrate-ops.js.map +1 -0
- package/dist/runtime/planning-extra-ops.d.ts +17 -0
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -0
- package/dist/runtime/planning-extra-ops.js +300 -0
- package/dist/runtime/planning-extra-ops.js.map +1 -0
- package/dist/runtime/project-ops.d.ts +15 -0
- package/dist/runtime/project-ops.d.ts.map +1 -0
- package/dist/runtime/project-ops.js +181 -0
- package/dist/runtime/project-ops.js.map +1 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +44 -1
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +21 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.d.ts +9 -0
- package/dist/runtime/vault-extra-ops.d.ts.map +1 -0
- package/dist/runtime/vault-extra-ops.js +195 -0
- package/dist/runtime/vault-extra-ops.js.map +1 -0
- package/dist/telemetry/telemetry.d.ts +48 -0
- package/dist/telemetry/telemetry.d.ts.map +1 -0
- package/dist/telemetry/telemetry.js +87 -0
- package/dist/telemetry/telemetry.js.map +1 -0
- package/dist/vault/vault.d.ts +94 -0
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +340 -1
- package/dist/vault/vault.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/admin-extra-ops.test.ts +420 -0
- package/src/__tests__/admin-ops.test.ts +271 -0
- package/src/__tests__/brain-intelligence.test.ts +205 -0
- package/src/__tests__/brain.test.ts +131 -0
- package/src/__tests__/capture-ops.test.ts +509 -0
- package/src/__tests__/core-ops.test.ts +266 -2
- package/src/__tests__/curator-extra-ops.test.ts +359 -0
- package/src/__tests__/domain-ops.test.ts +66 -0
- package/src/__tests__/governance.test.ts +522 -0
- package/src/__tests__/grading-ops.test.ts +340 -0
- package/src/__tests__/identity-manager.test.ts +243 -0
- package/src/__tests__/intent-router.test.ts +222 -0
- package/src/__tests__/logger.test.ts +200 -0
- package/src/__tests__/loop-ops.test.ts +398 -0
- package/src/__tests__/memory-cross-project-ops.test.ts +246 -0
- package/src/__tests__/memory-extra-ops.test.ts +352 -0
- package/src/__tests__/orchestrate-ops.test.ts +284 -0
- package/src/__tests__/planner.test.ts +331 -0
- package/src/__tests__/planning-extra-ops.test.ts +548 -0
- package/src/__tests__/project-ops.test.ts +367 -0
- package/src/__tests__/vault-extra-ops.test.ts +407 -0
- package/src/brain/brain.ts +114 -7
- package/src/brain/intelligence.ts +179 -10
- package/src/brain/types.ts +38 -0
- package/src/control/identity-manager.ts +354 -0
- package/src/control/intent-router.ts +326 -0
- package/src/control/types.ts +102 -0
- package/src/curator/curator.ts +213 -0
- package/src/governance/governance.ts +698 -0
- package/src/governance/index.ts +18 -0
- package/src/governance/types.ts +111 -0
- package/src/index.ts +102 -2
- package/src/logging/logger.ts +154 -0
- package/src/logging/types.ts +21 -0
- package/src/loop/loop-manager.ts +130 -0
- package/src/loop/types.ts +44 -0
- package/src/planning/gap-analysis.ts +506 -0
- package/src/planning/gap-types.ts +58 -0
- package/src/planning/planner.ts +478 -2
- package/src/project/project-registry.ts +358 -0
- package/src/project/types.ts +31 -0
- package/src/runtime/admin-extra-ops.ts +307 -0
- package/src/runtime/admin-ops.ts +329 -0
- package/src/runtime/capture-ops.ts +385 -0
- package/src/runtime/core-ops.ts +535 -7
- package/src/runtime/curator-extra-ops.ts +71 -0
- package/src/runtime/domain-ops.ts +65 -13
- package/src/runtime/grading-ops.ts +121 -0
- package/src/runtime/loop-ops.ts +194 -0
- package/src/runtime/memory-cross-project-ops.ts +192 -0
- package/src/runtime/memory-extra-ops.ts +186 -0
- package/src/runtime/orchestrate-ops.ts +272 -0
- package/src/runtime/planning-extra-ops.ts +327 -0
- package/src/runtime/project-ops.ts +196 -0
- package/src/runtime/runtime.ts +49 -1
- package/src/runtime/types.ts +21 -0
- package/src/runtime/vault-extra-ops.ts +225 -0
- package/src/telemetry/telemetry.ts +118 -0
- package/src/vault/vault.ts +412 -1
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extended planning operations — 9 ops for advanced plan lifecycle management.
|
|
3
|
+
*
|
|
4
|
+
* These complement the 5 basic planning ops in core-ops.ts with:
|
|
5
|
+
* iteration, splitting, reconciliation, lifecycle completion,
|
|
6
|
+
* dispatch, review, archival, task listing, and statistics.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import type { OpDefinition } from '../facades/types.js';
|
|
11
|
+
import type { AgentRuntime } from './types.js';
|
|
12
|
+
import type { DriftItem } from '../planning/planner.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create 9 extended planning operations for an agent runtime.
|
|
16
|
+
*
|
|
17
|
+
* Groups: mutation (plan_iterate, plan_split, plan_reconcile, plan_complete_lifecycle,
|
|
18
|
+
* plan_review, plan_archive), query (plan_dispatch, plan_list_tasks, plan_stats).
|
|
19
|
+
*/
|
|
20
|
+
export function createPlanningExtraOps(runtime: AgentRuntime): OpDefinition[] {
|
|
21
|
+
const { planner, vault } = runtime;
|
|
22
|
+
|
|
23
|
+
return [
|
|
24
|
+
// ─── Plan Iteration ───────────────────────────────────────────
|
|
25
|
+
{
|
|
26
|
+
name: 'plan_iterate',
|
|
27
|
+
description:
|
|
28
|
+
'Revise a draft plan — change objective, scope, decisions, or add/remove tasks. Only works on draft plans.',
|
|
29
|
+
auth: 'write',
|
|
30
|
+
schema: z.object({
|
|
31
|
+
planId: z.string().describe('ID of the draft plan to iterate on'),
|
|
32
|
+
objective: z.string().optional().describe('New objective (replaces existing)'),
|
|
33
|
+
scope: z.string().optional().describe('New scope (replaces existing)'),
|
|
34
|
+
decisions: z.array(z.string()).optional().describe('New decisions list (replaces existing)'),
|
|
35
|
+
addTasks: z
|
|
36
|
+
.array(z.object({ title: z.string(), description: z.string() }))
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Tasks to append'),
|
|
39
|
+
removeTasks: z
|
|
40
|
+
.array(z.string())
|
|
41
|
+
.optional()
|
|
42
|
+
.describe('Task IDs to remove'),
|
|
43
|
+
}),
|
|
44
|
+
handler: async (params) => {
|
|
45
|
+
try {
|
|
46
|
+
const plan = planner.iterate(params.planId as string, {
|
|
47
|
+
objective: params.objective as string | undefined,
|
|
48
|
+
scope: params.scope as string | undefined,
|
|
49
|
+
decisions: params.decisions as string[] | undefined,
|
|
50
|
+
addTasks: params.addTasks as Array<{ title: string; description: string }> | undefined,
|
|
51
|
+
removeTasks: params.removeTasks as string[] | undefined,
|
|
52
|
+
});
|
|
53
|
+
return { iterated: true, plan };
|
|
54
|
+
} catch (err) {
|
|
55
|
+
return { error: (err as Error).message };
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
// ─── Plan Split ───────────────────────────────────────────────
|
|
61
|
+
{
|
|
62
|
+
name: 'plan_split',
|
|
63
|
+
description:
|
|
64
|
+
'Split a plan into sub-tasks with dependency tracking. Replaces existing tasks with a new set. Works on draft or approved plans.',
|
|
65
|
+
auth: 'write',
|
|
66
|
+
schema: z.object({
|
|
67
|
+
planId: z.string().describe('Plan ID to split tasks for'),
|
|
68
|
+
tasks: z
|
|
69
|
+
.array(
|
|
70
|
+
z.object({
|
|
71
|
+
title: z.string(),
|
|
72
|
+
description: z.string(),
|
|
73
|
+
dependsOn: z.array(z.string()).optional().describe('Task IDs this task depends on'),
|
|
74
|
+
}),
|
|
75
|
+
)
|
|
76
|
+
.describe('New task list with optional dependency references (task-1, task-2, etc.)'),
|
|
77
|
+
}),
|
|
78
|
+
handler: async (params) => {
|
|
79
|
+
try {
|
|
80
|
+
const plan = planner.splitTasks(
|
|
81
|
+
params.planId as string,
|
|
82
|
+
params.tasks as Array<{ title: string; description: string; dependsOn?: string[] }>,
|
|
83
|
+
);
|
|
84
|
+
return { split: true, taskCount: plan.tasks.length, plan };
|
|
85
|
+
} catch (err) {
|
|
86
|
+
return { error: (err as Error).message };
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// ─── Plan Reconcile ───────────────────────────────────────────
|
|
92
|
+
{
|
|
93
|
+
name: 'plan_reconcile',
|
|
94
|
+
description:
|
|
95
|
+
'Capture what actually happened vs what was planned. Produces a drift analysis with accuracy score. Works on executing or completed plans.',
|
|
96
|
+
auth: 'write',
|
|
97
|
+
schema: z.object({
|
|
98
|
+
planId: z.string().describe('Plan ID to reconcile'),
|
|
99
|
+
actualOutcome: z.string().describe('Description of what actually happened'),
|
|
100
|
+
driftItems: z
|
|
101
|
+
.array(
|
|
102
|
+
z.object({
|
|
103
|
+
type: z.enum(['skipped', 'added', 'modified', 'reordered']),
|
|
104
|
+
description: z.string(),
|
|
105
|
+
impact: z.enum(['low', 'medium', 'high']),
|
|
106
|
+
rationale: z.string(),
|
|
107
|
+
}),
|
|
108
|
+
)
|
|
109
|
+
.optional()
|
|
110
|
+
.describe('Specific drift items — differences between plan and reality'),
|
|
111
|
+
}),
|
|
112
|
+
handler: async (params) => {
|
|
113
|
+
try {
|
|
114
|
+
const plan = planner.reconcile(params.planId as string, {
|
|
115
|
+
actualOutcome: params.actualOutcome as string,
|
|
116
|
+
driftItems: params.driftItems as DriftItem[] | undefined,
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
reconciled: true,
|
|
120
|
+
accuracy: plan.reconciliation!.accuracy,
|
|
121
|
+
driftCount: plan.reconciliation!.driftItems.length,
|
|
122
|
+
plan,
|
|
123
|
+
};
|
|
124
|
+
} catch (err) {
|
|
125
|
+
return { error: (err as Error).message };
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
// ─── Plan Complete Lifecycle ──────────────────────────────────
|
|
131
|
+
{
|
|
132
|
+
name: 'plan_complete_lifecycle',
|
|
133
|
+
description:
|
|
134
|
+
'Extract knowledge from a completed and reconciled plan. Captures patterns and anti-patterns into the vault based on drift analysis.',
|
|
135
|
+
auth: 'write',
|
|
136
|
+
schema: z.object({
|
|
137
|
+
planId: z.string().describe('Plan ID (must be completed with reconciliation data)'),
|
|
138
|
+
patterns: z
|
|
139
|
+
.array(z.string())
|
|
140
|
+
.optional()
|
|
141
|
+
.describe('Patterns discovered during execution'),
|
|
142
|
+
antiPatterns: z
|
|
143
|
+
.array(z.string())
|
|
144
|
+
.optional()
|
|
145
|
+
.describe('Anti-patterns discovered during execution'),
|
|
146
|
+
}),
|
|
147
|
+
handler: async (params) => {
|
|
148
|
+
try {
|
|
149
|
+
const plan = planner.get(params.planId as string);
|
|
150
|
+
if (!plan) return { error: `Plan not found: ${params.planId}` };
|
|
151
|
+
if (plan.status !== 'completed')
|
|
152
|
+
return { error: `Plan must be completed — current status: '${plan.status}'` };
|
|
153
|
+
|
|
154
|
+
const patterns = (params.patterns as string[] | undefined) ?? [];
|
|
155
|
+
const antiPatterns = (params.antiPatterns as string[] | undefined) ?? [];
|
|
156
|
+
let captured = 0;
|
|
157
|
+
|
|
158
|
+
// Capture patterns into vault
|
|
159
|
+
for (const p of patterns) {
|
|
160
|
+
vault.add({
|
|
161
|
+
id: `plan-pattern-${plan.id}-${captured}`,
|
|
162
|
+
type: 'pattern',
|
|
163
|
+
domain: 'planning',
|
|
164
|
+
title: p,
|
|
165
|
+
severity: 'suggestion',
|
|
166
|
+
description: `Discovered during plan: ${plan.objective}`,
|
|
167
|
+
tags: ['plan-knowledge', plan.id],
|
|
168
|
+
});
|
|
169
|
+
captured++;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Capture anti-patterns into vault
|
|
173
|
+
for (const ap of antiPatterns) {
|
|
174
|
+
vault.add({
|
|
175
|
+
id: `plan-antipattern-${plan.id}-${captured}`,
|
|
176
|
+
type: 'anti-pattern',
|
|
177
|
+
domain: 'planning',
|
|
178
|
+
title: ap,
|
|
179
|
+
severity: 'warning',
|
|
180
|
+
description: `Discovered during plan: ${plan.objective}`,
|
|
181
|
+
tags: ['plan-knowledge', plan.id],
|
|
182
|
+
});
|
|
183
|
+
captured++;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
completed: true,
|
|
188
|
+
knowledgeCaptured: captured,
|
|
189
|
+
patternsAdded: patterns.length,
|
|
190
|
+
antiPatternsAdded: antiPatterns.length,
|
|
191
|
+
reconciliation: plan.reconciliation ?? null,
|
|
192
|
+
};
|
|
193
|
+
} catch (err) {
|
|
194
|
+
return { error: (err as Error).message };
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
// ─── Plan Dispatch ────────────────────────────────────────────
|
|
200
|
+
{
|
|
201
|
+
name: 'plan_dispatch',
|
|
202
|
+
description:
|
|
203
|
+
'Get task execution instructions for subagents. Returns the task, its unmet dependencies, and whether it is ready to execute.',
|
|
204
|
+
auth: 'read',
|
|
205
|
+
schema: z.object({
|
|
206
|
+
planId: z.string().describe('Plan ID'),
|
|
207
|
+
taskId: z.string().describe('Task ID to get dispatch instructions for'),
|
|
208
|
+
}),
|
|
209
|
+
handler: async (params) => {
|
|
210
|
+
try {
|
|
211
|
+
const dispatch = planner.getDispatch(
|
|
212
|
+
params.planId as string,
|
|
213
|
+
params.taskId as string,
|
|
214
|
+
);
|
|
215
|
+
return dispatch;
|
|
216
|
+
} catch (err) {
|
|
217
|
+
return { error: (err as Error).message };
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
// ─── Plan Review ──────────────────────────────────────────────
|
|
223
|
+
{
|
|
224
|
+
name: 'plan_review',
|
|
225
|
+
description:
|
|
226
|
+
'Submit review evidence for a plan or specific task. Records reviewer, outcome, and comments.',
|
|
227
|
+
auth: 'write',
|
|
228
|
+
schema: z.object({
|
|
229
|
+
planId: z.string().describe('Plan ID to review'),
|
|
230
|
+
taskId: z.string().optional().describe('Specific task ID (omit to review the whole plan)'),
|
|
231
|
+
reviewer: z.string().describe('Name or ID of reviewer'),
|
|
232
|
+
outcome: z
|
|
233
|
+
.enum(['approved', 'rejected', 'needs_changes'])
|
|
234
|
+
.describe('Review outcome'),
|
|
235
|
+
comments: z.string().describe('Review comments'),
|
|
236
|
+
}),
|
|
237
|
+
handler: async (params) => {
|
|
238
|
+
try {
|
|
239
|
+
const plan = planner.addReview(params.planId as string, {
|
|
240
|
+
taskId: params.taskId as string | undefined,
|
|
241
|
+
reviewer: params.reviewer as string,
|
|
242
|
+
outcome: params.outcome as 'approved' | 'rejected' | 'needs_changes',
|
|
243
|
+
comments: params.comments as string,
|
|
244
|
+
});
|
|
245
|
+
return {
|
|
246
|
+
reviewed: true,
|
|
247
|
+
totalReviews: plan.reviews?.length ?? 0,
|
|
248
|
+
plan: { id: plan.id, status: plan.status },
|
|
249
|
+
};
|
|
250
|
+
} catch (err) {
|
|
251
|
+
return { error: (err as Error).message };
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
// ─── Plan Archive ─────────────────────────────────────────────
|
|
257
|
+
{
|
|
258
|
+
name: 'plan_archive',
|
|
259
|
+
description:
|
|
260
|
+
'Archive completed plans older than N days. Removes them from active store and returns the archived plans.',
|
|
261
|
+
auth: 'admin',
|
|
262
|
+
schema: z.object({
|
|
263
|
+
olderThanDays: z.number().describe('Archive plans completed more than this many days ago'),
|
|
264
|
+
}),
|
|
265
|
+
handler: async (params) => {
|
|
266
|
+
try {
|
|
267
|
+
const olderThanDays = (params.olderThanDays as number) ?? 30;
|
|
268
|
+
const archived = planner.archive(olderThanDays);
|
|
269
|
+
return { archived: archived.length, plans: archived.map((p) => ({ id: p.id, objective: p.objective })) };
|
|
270
|
+
} catch (err) {
|
|
271
|
+
return { error: (err as Error).message };
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
|
|
276
|
+
// ─── Plan List Tasks ──────────────────────────────────────────
|
|
277
|
+
{
|
|
278
|
+
name: 'plan_list_tasks',
|
|
279
|
+
description:
|
|
280
|
+
'List all tasks for a plan with their current status. Optionally filter by status.',
|
|
281
|
+
auth: 'read',
|
|
282
|
+
schema: z.object({
|
|
283
|
+
planId: z.string().describe('Plan ID'),
|
|
284
|
+
status: z
|
|
285
|
+
.enum(['pending', 'in_progress', 'completed', 'skipped', 'failed'])
|
|
286
|
+
.optional()
|
|
287
|
+
.describe('Filter tasks by status'),
|
|
288
|
+
}),
|
|
289
|
+
handler: async (params) => {
|
|
290
|
+
try {
|
|
291
|
+
const plan = planner.get(params.planId as string);
|
|
292
|
+
if (!plan) return { error: `Plan not found: ${params.planId}` };
|
|
293
|
+
|
|
294
|
+
const statusFilter = params.status as string | undefined;
|
|
295
|
+
const tasks = statusFilter
|
|
296
|
+
? plan.tasks.filter((t) => t.status === statusFilter)
|
|
297
|
+
: plan.tasks;
|
|
298
|
+
|
|
299
|
+
return {
|
|
300
|
+
planId: plan.id,
|
|
301
|
+
planStatus: plan.status,
|
|
302
|
+
total: plan.tasks.length,
|
|
303
|
+
filtered: tasks.length,
|
|
304
|
+
tasks,
|
|
305
|
+
};
|
|
306
|
+
} catch (err) {
|
|
307
|
+
return { error: (err as Error).message };
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
// ─── Plan Stats ───────────────────────────────────────────────
|
|
313
|
+
{
|
|
314
|
+
name: 'plan_stats',
|
|
315
|
+
description:
|
|
316
|
+
'Planning statistics — total plans, breakdown by status, average tasks per plan, task status distribution.',
|
|
317
|
+
auth: 'read',
|
|
318
|
+
handler: async () => {
|
|
319
|
+
try {
|
|
320
|
+
return planner.stats();
|
|
321
|
+
} catch (err) {
|
|
322
|
+
return { error: (err as Error).message };
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
];
|
|
327
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project registry operations — 12 ops for managing projects, rules, and links.
|
|
3
|
+
*
|
|
4
|
+
* These ops expose the ProjectRegistry module as facade operations.
|
|
5
|
+
* All state is persisted in the Vault's SQLite database.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import type { OpDefinition } from '../facades/types.js';
|
|
10
|
+
import type { AgentRuntime } from './types.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create the 12 project registry operations for an agent runtime.
|
|
14
|
+
*
|
|
15
|
+
* Groups: projects (3), rules (4), links (4), misc (1).
|
|
16
|
+
*/
|
|
17
|
+
export function createProjectOps(runtime: AgentRuntime): OpDefinition[] {
|
|
18
|
+
const { projectRegistry } = runtime;
|
|
19
|
+
|
|
20
|
+
return [
|
|
21
|
+
// ─── Projects ───────────────────────────────────────────────────
|
|
22
|
+
{
|
|
23
|
+
name: 'project_get',
|
|
24
|
+
description: 'Get a registered project by ID.',
|
|
25
|
+
auth: 'read',
|
|
26
|
+
schema: z.object({
|
|
27
|
+
projectId: z.string().describe('Project ID to look up'),
|
|
28
|
+
}),
|
|
29
|
+
handler: async (params) => {
|
|
30
|
+
const project = projectRegistry.get(params.projectId as string);
|
|
31
|
+
if (!project) {
|
|
32
|
+
return { found: false, project: null };
|
|
33
|
+
}
|
|
34
|
+
return { found: true, project };
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'project_list',
|
|
39
|
+
description: 'List all registered projects, ordered by last accessed time.',
|
|
40
|
+
auth: 'read',
|
|
41
|
+
handler: async () => {
|
|
42
|
+
const projects = projectRegistry.list();
|
|
43
|
+
return { count: projects.length, projects };
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'project_unregister',
|
|
48
|
+
description: 'Unregister a project — removes it and all associated rules and links.',
|
|
49
|
+
auth: 'write',
|
|
50
|
+
schema: z.object({
|
|
51
|
+
projectId: z.string().describe('Project ID to unregister'),
|
|
52
|
+
}),
|
|
53
|
+
handler: async (params) => {
|
|
54
|
+
const removed = projectRegistry.unregister(params.projectId as string);
|
|
55
|
+
return { removed, projectId: params.projectId };
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
// ─── Rules ──────────────────────────────────────────────────────
|
|
60
|
+
{
|
|
61
|
+
name: 'project_get_rules',
|
|
62
|
+
description: 'Get all rules for a specific project.',
|
|
63
|
+
auth: 'read',
|
|
64
|
+
schema: z.object({
|
|
65
|
+
projectId: z.string().describe('Project ID'),
|
|
66
|
+
}),
|
|
67
|
+
handler: async (params) => {
|
|
68
|
+
const rules = projectRegistry.getRules(params.projectId as string);
|
|
69
|
+
return { count: rules.length, rules };
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'project_list_rules',
|
|
74
|
+
description: 'List all projects with their associated rules.',
|
|
75
|
+
auth: 'read',
|
|
76
|
+
handler: async () => {
|
|
77
|
+
const result = projectRegistry.listRulesAll();
|
|
78
|
+
return {
|
|
79
|
+
count: result.length,
|
|
80
|
+
projects: result.map((r) => ({
|
|
81
|
+
project: r.project,
|
|
82
|
+
ruleCount: r.rules.length,
|
|
83
|
+
rules: r.rules,
|
|
84
|
+
})),
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'project_add_rule',
|
|
90
|
+
description: 'Add a rule to a project — behavior, preference, restriction, or convention.',
|
|
91
|
+
auth: 'write',
|
|
92
|
+
schema: z.object({
|
|
93
|
+
projectId: z.string().describe('Project ID to add the rule to'),
|
|
94
|
+
category: z.enum(['behavior', 'preference', 'restriction', 'convention']).describe('Rule category'),
|
|
95
|
+
text: z.string().describe('Rule text'),
|
|
96
|
+
priority: z.number().default(0).describe('Priority (higher = more important)'),
|
|
97
|
+
}),
|
|
98
|
+
handler: async (params) => {
|
|
99
|
+
const rule = projectRegistry.addRule(params.projectId as string, {
|
|
100
|
+
category: params.category as 'behavior' | 'preference' | 'restriction' | 'convention',
|
|
101
|
+
text: params.text as string,
|
|
102
|
+
priority: (params.priority as number) ?? 0,
|
|
103
|
+
});
|
|
104
|
+
return { added: true, rule };
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'project_remove_rule',
|
|
109
|
+
description: 'Remove a project rule by its ID.',
|
|
110
|
+
auth: 'write',
|
|
111
|
+
schema: z.object({
|
|
112
|
+
ruleId: z.string().describe('Rule ID to remove'),
|
|
113
|
+
}),
|
|
114
|
+
handler: async (params) => {
|
|
115
|
+
const removed = projectRegistry.removeRule(params.ruleId as string);
|
|
116
|
+
return { removed, ruleId: params.ruleId };
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
// ─── Links ──────────────────────────────────────────────────────
|
|
121
|
+
{
|
|
122
|
+
name: 'project_link',
|
|
123
|
+
description: 'Create a link between two projects (related, parent, child, fork).',
|
|
124
|
+
auth: 'write',
|
|
125
|
+
schema: z.object({
|
|
126
|
+
sourceId: z.string().describe('Source project ID'),
|
|
127
|
+
targetId: z.string().describe('Target project ID'),
|
|
128
|
+
linkType: z.enum(['related', 'parent', 'child', 'fork']).describe('Type of link'),
|
|
129
|
+
}),
|
|
130
|
+
handler: async (params) => {
|
|
131
|
+
const link = projectRegistry.link(
|
|
132
|
+
params.sourceId as string,
|
|
133
|
+
params.targetId as string,
|
|
134
|
+
params.linkType as 'related' | 'parent' | 'child' | 'fork',
|
|
135
|
+
);
|
|
136
|
+
return { linked: true, link };
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: 'project_unlink',
|
|
141
|
+
description: 'Remove links between two projects. Omit linkType to remove all link types.',
|
|
142
|
+
auth: 'write',
|
|
143
|
+
schema: z.object({
|
|
144
|
+
sourceId: z.string().describe('Source project ID'),
|
|
145
|
+
targetId: z.string().describe('Target project ID'),
|
|
146
|
+
linkType: z.enum(['related', 'parent', 'child', 'fork']).optional().describe('Specific link type to remove'),
|
|
147
|
+
}),
|
|
148
|
+
handler: async (params) => {
|
|
149
|
+
const count = projectRegistry.unlink(
|
|
150
|
+
params.sourceId as string,
|
|
151
|
+
params.targetId as string,
|
|
152
|
+
params.linkType as 'related' | 'parent' | 'child' | 'fork' | undefined,
|
|
153
|
+
);
|
|
154
|
+
return { removed: count, sourceId: params.sourceId, targetId: params.targetId };
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'project_get_links',
|
|
159
|
+
description: 'Get all links for a project (both incoming and outgoing).',
|
|
160
|
+
auth: 'read',
|
|
161
|
+
schema: z.object({
|
|
162
|
+
projectId: z.string().describe('Project ID'),
|
|
163
|
+
}),
|
|
164
|
+
handler: async (params) => {
|
|
165
|
+
const links = projectRegistry.getLinks(params.projectId as string);
|
|
166
|
+
return { count: links.length, links };
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: 'project_linked_projects',
|
|
171
|
+
description: 'Get linked projects with full details — project info, link type, and direction.',
|
|
172
|
+
auth: 'read',
|
|
173
|
+
schema: z.object({
|
|
174
|
+
projectId: z.string().describe('Project ID'),
|
|
175
|
+
}),
|
|
176
|
+
handler: async (params) => {
|
|
177
|
+
const linked = projectRegistry.getLinkedProjects(params.projectId as string);
|
|
178
|
+
return { count: linked.length, linked };
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
// ─── Misc ───────────────────────────────────────────────────────
|
|
183
|
+
{
|
|
184
|
+
name: 'project_touch',
|
|
185
|
+
description: 'Update the last accessed timestamp for a project.',
|
|
186
|
+
auth: 'write',
|
|
187
|
+
schema: z.object({
|
|
188
|
+
projectId: z.string().describe('Project ID to touch'),
|
|
189
|
+
}),
|
|
190
|
+
handler: async (params) => {
|
|
191
|
+
projectRegistry.touch(params.projectId as string);
|
|
192
|
+
return { touched: true, projectId: params.projectId };
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
];
|
|
196
|
+
}
|
package/src/runtime/runtime.ts
CHANGED
|
@@ -14,9 +14,17 @@ import { Brain } from '../brain/brain.js';
|
|
|
14
14
|
import { BrainIntelligence } from '../brain/intelligence.js';
|
|
15
15
|
import { Planner } from '../planning/planner.js';
|
|
16
16
|
import { Curator } from '../curator/curator.js';
|
|
17
|
+
import { Governance } from '../governance/governance.js';
|
|
18
|
+
import { CogneeClient } from '../cognee/client.js';
|
|
19
|
+
import { LoopManager } from '../loop/loop-manager.js';
|
|
20
|
+
import { IdentityManager } from '../control/identity-manager.js';
|
|
21
|
+
import { IntentRouter } from '../control/intent-router.js';
|
|
17
22
|
import { KeyPool, loadKeyPoolConfig } from '../llm/key-pool.js';
|
|
18
23
|
import { loadIntelligenceData } from '../intelligence/loader.js';
|
|
19
24
|
import { LLMClient } from '../llm/llm-client.js';
|
|
25
|
+
import { Telemetry } from '../telemetry/telemetry.js';
|
|
26
|
+
import { ProjectRegistry } from '../project/project-registry.js';
|
|
27
|
+
import { createLogger } from '../logging/logger.js';
|
|
20
28
|
import type { AgentRuntimeConfig, AgentRuntime } from './types.js';
|
|
21
29
|
|
|
22
30
|
/**
|
|
@@ -33,6 +41,9 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
|
|
|
33
41
|
const vaultPath = config.vaultPath ?? join(agentHome, 'vault.db');
|
|
34
42
|
const plansPath = config.plansPath ?? join(agentHome, 'plans.json');
|
|
35
43
|
|
|
44
|
+
// Logger — structured output to stderr
|
|
45
|
+
const logger = createLogger({ level: config.logLevel, prefix: `[${agentId}]` });
|
|
46
|
+
|
|
36
47
|
// Vault — persistent SQLite knowledge store
|
|
37
48
|
const vault = new Vault(vaultPath);
|
|
38
49
|
|
|
@@ -56,6 +67,31 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
|
|
|
56
67
|
// Curator — vault self-maintenance (dedup, contradictions, grooming, health)
|
|
57
68
|
const curator = new Curator(vault);
|
|
58
69
|
|
|
70
|
+
// Governance — policy engine + proposal tracker for gated knowledge capture
|
|
71
|
+
const governance = new Governance(vault);
|
|
72
|
+
|
|
73
|
+
// Cognee — vector search client (graceful degradation if Cognee is down)
|
|
74
|
+
const cogneePartial: Partial<import('../cognee/types.js').CogneeConfig> = { dataset: agentId };
|
|
75
|
+
if (process.env.COGNEE_BASE_URL) cogneePartial.baseUrl = process.env.COGNEE_BASE_URL;
|
|
76
|
+
if (process.env.COGNEE_API_TOKEN) cogneePartial.apiToken = process.env.COGNEE_API_TOKEN;
|
|
77
|
+
if (process.env.COGNEE_DATASET) cogneePartial.dataset = process.env.COGNEE_DATASET;
|
|
78
|
+
const cognee = new CogneeClient(cogneePartial);
|
|
79
|
+
|
|
80
|
+
// Loop Manager — iterative validation loop tracking (in-memory, session-scoped)
|
|
81
|
+
const loop = new LoopManager();
|
|
82
|
+
|
|
83
|
+
// Identity Manager — agent persona CRUD with versioning/rollback
|
|
84
|
+
const identityManager = new IdentityManager(vault);
|
|
85
|
+
|
|
86
|
+
// Intent Router — keyword-based intent classification and mode management
|
|
87
|
+
const intentRouter = new IntentRouter(vault);
|
|
88
|
+
|
|
89
|
+
// Telemetry — in-memory facade call tracking
|
|
90
|
+
const telemetry = new Telemetry();
|
|
91
|
+
|
|
92
|
+
// Project Registry — multi-project tracking with rules and links
|
|
93
|
+
const projectRegistry = new ProjectRegistry(vault.getDb());
|
|
94
|
+
|
|
59
95
|
// LLM key pools and client
|
|
60
96
|
const keyPoolFiles = loadKeyPoolConfig(agentId);
|
|
61
97
|
const openaiKeyPool = new KeyPool(keyPoolFiles.openai);
|
|
@@ -64,13 +100,25 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
|
|
|
64
100
|
|
|
65
101
|
return {
|
|
66
102
|
config,
|
|
103
|
+
logger,
|
|
67
104
|
vault,
|
|
68
105
|
brain,
|
|
69
106
|
brainIntelligence,
|
|
70
107
|
planner,
|
|
71
108
|
curator,
|
|
109
|
+
governance,
|
|
110
|
+
cognee,
|
|
111
|
+
loop,
|
|
112
|
+
identityManager,
|
|
113
|
+
intentRouter,
|
|
72
114
|
keyPool: { openai: openaiKeyPool, anthropic: anthropicKeyPool },
|
|
73
115
|
llmClient,
|
|
74
|
-
|
|
116
|
+
telemetry,
|
|
117
|
+
projectRegistry,
|
|
118
|
+
createdAt: Date.now(),
|
|
119
|
+
close: () => {
|
|
120
|
+
cognee.resetPendingCognify();
|
|
121
|
+
vault.close();
|
|
122
|
+
},
|
|
75
123
|
};
|
|
76
124
|
}
|
package/src/runtime/types.ts
CHANGED
|
@@ -3,8 +3,17 @@ import type { Brain } from '../brain/brain.js';
|
|
|
3
3
|
import type { BrainIntelligence } from '../brain/intelligence.js';
|
|
4
4
|
import type { Planner } from '../planning/planner.js';
|
|
5
5
|
import type { Curator } from '../curator/curator.js';
|
|
6
|
+
import type { Governance } from '../governance/governance.js';
|
|
7
|
+
import type { CogneeClient } from '../cognee/client.js';
|
|
6
8
|
import type { KeyPool } from '../llm/key-pool.js';
|
|
7
9
|
import type { LLMClient } from '../llm/llm-client.js';
|
|
10
|
+
import type { IdentityManager } from '../control/identity-manager.js';
|
|
11
|
+
import type { IntentRouter } from '../control/intent-router.js';
|
|
12
|
+
import type { LoopManager } from '../loop/loop-manager.js';
|
|
13
|
+
import type { Telemetry } from '../telemetry/telemetry.js';
|
|
14
|
+
import type { ProjectRegistry } from '../project/project-registry.js';
|
|
15
|
+
import type { Logger } from '../logging/logger.js';
|
|
16
|
+
import type { LogLevel } from '../logging/types.js';
|
|
8
17
|
|
|
9
18
|
/**
|
|
10
19
|
* Configuration for creating an agent runtime.
|
|
@@ -19,6 +28,8 @@ export interface AgentRuntimeConfig {
|
|
|
19
28
|
plansPath?: string;
|
|
20
29
|
/** Intelligence data directory to seed vault from. Optional. */
|
|
21
30
|
dataDir?: string;
|
|
31
|
+
/** Minimum log level. Default: 'info' (or SOLERI_LOG_LEVEL env var). */
|
|
32
|
+
logLevel?: LogLevel;
|
|
22
33
|
}
|
|
23
34
|
|
|
24
35
|
/**
|
|
@@ -27,13 +38,23 @@ export interface AgentRuntimeConfig {
|
|
|
27
38
|
*/
|
|
28
39
|
export interface AgentRuntime {
|
|
29
40
|
config: AgentRuntimeConfig;
|
|
41
|
+
logger: Logger;
|
|
30
42
|
vault: Vault;
|
|
31
43
|
brain: Brain;
|
|
32
44
|
brainIntelligence: BrainIntelligence;
|
|
33
45
|
planner: Planner;
|
|
34
46
|
curator: Curator;
|
|
47
|
+
governance: Governance;
|
|
48
|
+
cognee: CogneeClient;
|
|
49
|
+
loop: LoopManager;
|
|
50
|
+
identityManager: IdentityManager;
|
|
51
|
+
intentRouter: IntentRouter;
|
|
35
52
|
keyPool: { openai: KeyPool; anthropic: KeyPool };
|
|
36
53
|
llmClient: LLMClient;
|
|
54
|
+
telemetry: Telemetry;
|
|
55
|
+
projectRegistry: ProjectRegistry;
|
|
56
|
+
/** Timestamp (ms since epoch) when this runtime was created. */
|
|
57
|
+
createdAt: number;
|
|
37
58
|
/** Close the vault database connection. Call on shutdown. */
|
|
38
59
|
close(): void;
|
|
39
60
|
}
|