@soleri/core 2.7.0 → 2.9.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/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +2 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/middleware.d.ts +13 -0
- package/dist/extensions/middleware.d.ts.map +1 -0
- package/dist/extensions/middleware.js +47 -0
- package/dist/extensions/middleware.js.map +1 -0
- package/dist/extensions/types.d.ts +64 -0
- package/dist/extensions/types.d.ts.map +1 -0
- package/dist/extensions/types.js +2 -0
- package/dist/extensions/types.js.map +1 -0
- package/dist/index.d.ts +8 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -16
- package/dist/index.js.map +1 -1
- package/dist/planning/gap-analysis.d.ts +2 -1
- package/dist/planning/gap-analysis.d.ts.map +1 -1
- package/dist/planning/gap-analysis.js +70 -1
- package/dist/planning/gap-analysis.js.map +1 -1
- package/dist/planning/gap-types.d.ts +8 -3
- package/dist/planning/gap-types.d.ts.map +1 -1
- package/dist/planning/gap-types.js +9 -1
- package/dist/planning/gap-types.js.map +1 -1
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +17 -5
- package/dist/planning/planner.js.map +1 -1
- package/dist/runtime/core-ops.d.ts +1 -1
- package/dist/runtime/core-ops.js +1 -1
- package/dist/runtime/facades/admin-facade.d.ts +8 -0
- package/dist/runtime/facades/admin-facade.d.ts.map +1 -0
- package/dist/runtime/facades/admin-facade.js +90 -0
- package/dist/runtime/facades/admin-facade.js.map +1 -0
- package/dist/runtime/facades/brain-facade.d.ts +8 -0
- package/dist/runtime/facades/brain-facade.d.ts.map +1 -0
- package/dist/runtime/facades/brain-facade.js +294 -0
- package/dist/runtime/facades/brain-facade.js.map +1 -0
- package/dist/runtime/facades/cognee-facade.d.ts +8 -0
- package/dist/runtime/facades/cognee-facade.d.ts.map +1 -0
- package/dist/runtime/facades/cognee-facade.js +154 -0
- package/dist/runtime/facades/cognee-facade.js.map +1 -0
- package/dist/runtime/facades/control-facade.d.ts +8 -0
- package/dist/runtime/facades/control-facade.d.ts.map +1 -0
- package/dist/runtime/facades/control-facade.js +244 -0
- package/dist/runtime/facades/control-facade.js.map +1 -0
- package/dist/runtime/facades/curator-facade.d.ts +8 -0
- package/dist/runtime/facades/curator-facade.d.ts.map +1 -0
- package/dist/runtime/facades/curator-facade.js +117 -0
- package/dist/runtime/facades/curator-facade.js.map +1 -0
- package/dist/runtime/facades/index.d.ts +10 -0
- package/dist/runtime/facades/index.d.ts.map +1 -0
- package/dist/runtime/facades/index.js +71 -0
- package/dist/runtime/facades/index.js.map +1 -0
- package/dist/runtime/facades/loop-facade.d.ts +8 -0
- package/dist/runtime/facades/loop-facade.d.ts.map +1 -0
- package/dist/runtime/facades/loop-facade.js +9 -0
- package/dist/runtime/facades/loop-facade.js.map +1 -0
- package/dist/runtime/facades/memory-facade.d.ts +8 -0
- package/dist/runtime/facades/memory-facade.d.ts.map +1 -0
- package/dist/runtime/facades/memory-facade.js +108 -0
- package/dist/runtime/facades/memory-facade.js.map +1 -0
- package/dist/runtime/facades/orchestrate-facade.d.ts +8 -0
- package/dist/runtime/facades/orchestrate-facade.d.ts.map +1 -0
- package/dist/runtime/facades/orchestrate-facade.js +58 -0
- package/dist/runtime/facades/orchestrate-facade.js.map +1 -0
- package/dist/runtime/facades/plan-facade.d.ts +8 -0
- package/dist/runtime/facades/plan-facade.d.ts.map +1 -0
- package/dist/runtime/facades/plan-facade.js +110 -0
- package/dist/runtime/facades/plan-facade.js.map +1 -0
- package/dist/runtime/facades/vault-facade.d.ts +8 -0
- package/dist/runtime/facades/vault-facade.d.ts.map +1 -0
- package/dist/runtime/facades/vault-facade.js +194 -0
- package/dist/runtime/facades/vault-facade.js.map +1 -0
- package/dist/runtime/grading-ops.d.ts +1 -1
- package/dist/runtime/grading-ops.js +2 -2
- package/dist/runtime/grading-ops.js.map +1 -1
- package/dist/runtime/vault-extra-ops.d.ts +2 -2
- package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.js +37 -2
- package/dist/runtime/vault-extra-ops.js.map +1 -1
- package/dist/streams/index.d.ts +4 -0
- package/dist/streams/index.d.ts.map +1 -0
- package/dist/streams/index.js +3 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams/normalize.d.ts +14 -0
- package/dist/streams/normalize.d.ts.map +1 -0
- package/dist/streams/normalize.js +43 -0
- package/dist/streams/normalize.js.map +1 -0
- package/dist/streams/replayable-stream.d.ts +19 -0
- package/dist/streams/replayable-stream.d.ts.map +1 -0
- package/dist/streams/replayable-stream.js +90 -0
- package/dist/streams/replayable-stream.js.map +1 -0
- package/dist/vault/content-hash.d.ts +16 -0
- package/dist/vault/content-hash.d.ts.map +1 -0
- package/dist/vault/content-hash.js +21 -0
- package/dist/vault/content-hash.js.map +1 -0
- package/dist/vault/vault.d.ts +9 -0
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +49 -3
- package/dist/vault/vault.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/content-hash.test.ts +60 -0
- package/src/__tests__/core-ops.test.ts +10 -7
- package/src/__tests__/extensions.test.ts +233 -0
- package/src/__tests__/grading-ops.test.ts +2 -2
- package/src/__tests__/memory-cross-project-ops.test.ts +2 -2
- package/src/__tests__/normalize.test.ts +75 -0
- package/src/__tests__/playbook.test.ts +4 -4
- package/src/__tests__/replayable-stream.test.ts +66 -0
- package/src/__tests__/vault-extra-ops.test.ts +1 -1
- package/src/__tests__/vault.test.ts +72 -0
- package/src/extensions/index.ts +2 -0
- package/src/extensions/middleware.ts +53 -0
- package/src/extensions/types.ts +64 -0
- package/src/index.ts +14 -17
- package/src/planning/gap-analysis.ts +95 -1
- package/src/planning/gap-types.ts +12 -2
- package/src/planning/planner.ts +17 -5
- package/src/runtime/facades/admin-facade.ts +101 -0
- package/src/runtime/facades/brain-facade.ts +331 -0
- package/src/runtime/facades/cognee-facade.ts +162 -0
- package/src/runtime/facades/control-facade.ts +279 -0
- package/src/runtime/facades/curator-facade.ts +132 -0
- package/src/runtime/facades/index.ts +74 -0
- package/src/runtime/facades/loop-facade.ts +12 -0
- package/src/runtime/facades/memory-facade.ts +114 -0
- package/src/runtime/facades/orchestrate-facade.ts +68 -0
- package/src/runtime/facades/plan-facade.ts +119 -0
- package/src/runtime/facades/vault-facade.ts +223 -0
- package/src/runtime/grading-ops.ts +2 -2
- package/src/runtime/vault-extra-ops.ts +38 -2
- package/src/streams/index.ts +3 -0
- package/src/streams/normalize.ts +56 -0
- package/src/streams/replayable-stream.ts +92 -0
- package/src/vault/content-hash.ts +31 -0
- package/src/vault/vault.ts +73 -3
- package/src/runtime/core-ops.ts +0 -1443
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control facade — agent behavior ops.
|
|
3
|
+
* identity, intent routing, morphing, guidelines, governance.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { OpDefinition } from '../../facades/types.js';
|
|
8
|
+
import type { AgentRuntime } from '../types.js';
|
|
9
|
+
import type { GuidelineCategory, OperationalMode } from '../../control/types.js';
|
|
10
|
+
import type { PolicyType, PolicyPreset } from '../../governance/types.js';
|
|
11
|
+
|
|
12
|
+
export function createControlFacadeOps(runtime: AgentRuntime): OpDefinition[] {
|
|
13
|
+
const { identityManager, intentRouter, governance } = runtime;
|
|
14
|
+
|
|
15
|
+
return [
|
|
16
|
+
// ─── Control (inline from core-ops.ts) ──────────────────────
|
|
17
|
+
{
|
|
18
|
+
name: 'get_identity',
|
|
19
|
+
description: 'Get current agent identity with guidelines.',
|
|
20
|
+
auth: 'read',
|
|
21
|
+
schema: z.object({
|
|
22
|
+
agentId: z.string().describe('Agent identifier.'),
|
|
23
|
+
}),
|
|
24
|
+
handler: async (params) => {
|
|
25
|
+
const identity = identityManager.getIdentity(params.agentId as string);
|
|
26
|
+
if (!identity) return { found: false, agentId: params.agentId };
|
|
27
|
+
return identity;
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'update_identity',
|
|
32
|
+
description: 'Update identity fields. Auto-versions and snapshots previous state.',
|
|
33
|
+
auth: 'write',
|
|
34
|
+
schema: z.object({
|
|
35
|
+
agentId: z.string(),
|
|
36
|
+
name: z.string().optional(),
|
|
37
|
+
role: z.string().optional(),
|
|
38
|
+
description: z.string().optional(),
|
|
39
|
+
personality: z.array(z.string()).optional(),
|
|
40
|
+
changedBy: z.string().optional(),
|
|
41
|
+
changeReason: z.string().optional(),
|
|
42
|
+
}),
|
|
43
|
+
handler: async (params) => {
|
|
44
|
+
const identity = identityManager.setIdentity(params.agentId as string, {
|
|
45
|
+
name: params.name as string | undefined,
|
|
46
|
+
role: params.role as string | undefined,
|
|
47
|
+
description: params.description as string | undefined,
|
|
48
|
+
personality: params.personality as string[] | undefined,
|
|
49
|
+
changedBy: params.changedBy as string | undefined,
|
|
50
|
+
changeReason: params.changeReason as string | undefined,
|
|
51
|
+
});
|
|
52
|
+
return { updated: true, identity };
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'add_guideline',
|
|
57
|
+
description: 'Add a behavioral guideline (behavior/preference/restriction/style).',
|
|
58
|
+
auth: 'write',
|
|
59
|
+
schema: z.object({
|
|
60
|
+
agentId: z.string(),
|
|
61
|
+
category: z.enum(['behavior', 'preference', 'restriction', 'style']),
|
|
62
|
+
text: z.string(),
|
|
63
|
+
priority: z.number().optional(),
|
|
64
|
+
}),
|
|
65
|
+
handler: async (params) => {
|
|
66
|
+
const guideline = identityManager.addGuideline(params.agentId as string, {
|
|
67
|
+
category: params.category as GuidelineCategory,
|
|
68
|
+
text: params.text as string,
|
|
69
|
+
priority: params.priority as number | undefined,
|
|
70
|
+
});
|
|
71
|
+
return { added: true, guideline };
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'remove_guideline',
|
|
76
|
+
description: 'Remove a guideline by ID.',
|
|
77
|
+
auth: 'write',
|
|
78
|
+
schema: z.object({
|
|
79
|
+
guidelineId: z.string(),
|
|
80
|
+
}),
|
|
81
|
+
handler: async (params) => {
|
|
82
|
+
const removed = identityManager.removeGuideline(params.guidelineId as string);
|
|
83
|
+
return { removed };
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'rollback_identity',
|
|
88
|
+
description: 'Restore a previous identity version. Creates a new version with the old data.',
|
|
89
|
+
auth: 'write',
|
|
90
|
+
schema: z.object({
|
|
91
|
+
agentId: z.string(),
|
|
92
|
+
version: z.number().describe('Version number to roll back to.'),
|
|
93
|
+
}),
|
|
94
|
+
handler: async (params) => {
|
|
95
|
+
const identity = identityManager.rollback(
|
|
96
|
+
params.agentId as string,
|
|
97
|
+
params.version as number,
|
|
98
|
+
);
|
|
99
|
+
return { rolledBack: true, identity };
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'route_intent',
|
|
104
|
+
description: 'Classify a prompt into intent + operational mode via keyword matching.',
|
|
105
|
+
auth: 'read',
|
|
106
|
+
schema: z.object({
|
|
107
|
+
prompt: z.string().describe('The user prompt to classify.'),
|
|
108
|
+
}),
|
|
109
|
+
handler: async (params) => {
|
|
110
|
+
return intentRouter.routeIntent(params.prompt as string);
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'morph',
|
|
115
|
+
description: 'Switch operational mode manually.',
|
|
116
|
+
auth: 'write',
|
|
117
|
+
schema: z.object({
|
|
118
|
+
mode: z
|
|
119
|
+
.string()
|
|
120
|
+
.describe('The operational mode to switch to (e.g., BUILD-MODE, FIX-MODE).'),
|
|
121
|
+
}),
|
|
122
|
+
handler: async (params) => {
|
|
123
|
+
return intentRouter.morph(params.mode as OperationalMode);
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'get_behavior_rules',
|
|
128
|
+
description: 'Get behavior rules for current or specified mode.',
|
|
129
|
+
auth: 'read',
|
|
130
|
+
schema: z.object({
|
|
131
|
+
mode: z.string().optional().describe('Mode to get rules for. Defaults to current mode.'),
|
|
132
|
+
}),
|
|
133
|
+
handler: async (params) => {
|
|
134
|
+
const mode = params.mode as OperationalMode | undefined;
|
|
135
|
+
const rules = intentRouter.getBehaviorRules(mode);
|
|
136
|
+
const currentMode = intentRouter.getCurrentMode();
|
|
137
|
+
return { mode: mode ?? currentMode, rules };
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
// ─── Governance (inline from core-ops.ts) ───────────────────
|
|
142
|
+
{
|
|
143
|
+
name: 'governance_policy',
|
|
144
|
+
description:
|
|
145
|
+
'Get, set, or apply a preset to vault governance policies (quota, retention, auto-capture).',
|
|
146
|
+
auth: 'write',
|
|
147
|
+
schema: z.object({
|
|
148
|
+
action: z.enum(['get', 'set', 'applyPreset']),
|
|
149
|
+
projectPath: z.string(),
|
|
150
|
+
policyType: z.enum(['quota', 'retention', 'auto-capture']).optional(),
|
|
151
|
+
config: z.record(z.unknown()).optional(),
|
|
152
|
+
preset: z.enum(['strict', 'moderate', 'permissive']).optional(),
|
|
153
|
+
changedBy: z.string().optional(),
|
|
154
|
+
}),
|
|
155
|
+
handler: async (params) => {
|
|
156
|
+
const action = params.action as string;
|
|
157
|
+
const projectPath = params.projectPath as string;
|
|
158
|
+
if (action === 'get') {
|
|
159
|
+
return governance.getPolicy(projectPath);
|
|
160
|
+
}
|
|
161
|
+
if (action === 'set') {
|
|
162
|
+
governance.setPolicy(
|
|
163
|
+
projectPath,
|
|
164
|
+
params.policyType as PolicyType,
|
|
165
|
+
params.config as Record<string, unknown>,
|
|
166
|
+
params.changedBy as string | undefined,
|
|
167
|
+
);
|
|
168
|
+
return { updated: true, policy: governance.getPolicy(projectPath) };
|
|
169
|
+
}
|
|
170
|
+
if (action === 'applyPreset') {
|
|
171
|
+
governance.applyPreset(
|
|
172
|
+
projectPath,
|
|
173
|
+
params.preset as PolicyPreset,
|
|
174
|
+
params.changedBy as string | undefined,
|
|
175
|
+
);
|
|
176
|
+
return {
|
|
177
|
+
applied: true,
|
|
178
|
+
preset: params.preset,
|
|
179
|
+
policy: governance.getPolicy(projectPath),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return { error: 'Unknown action: ' + action };
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: 'governance_proposals',
|
|
187
|
+
description:
|
|
188
|
+
'Manage knowledge capture proposals — list, approve, reject, modify, get stats, or expire stale.',
|
|
189
|
+
auth: 'write',
|
|
190
|
+
schema: z.object({
|
|
191
|
+
action: z.enum(['list', 'approve', 'reject', 'modify', 'stats', 'expire']),
|
|
192
|
+
projectPath: z.string().optional(),
|
|
193
|
+
proposalId: z.number().optional(),
|
|
194
|
+
decidedBy: z.string().optional(),
|
|
195
|
+
note: z.string().optional(),
|
|
196
|
+
modifications: z.record(z.unknown()).optional(),
|
|
197
|
+
maxAgeDays: z.number().optional(),
|
|
198
|
+
limit: z.number().optional(),
|
|
199
|
+
}),
|
|
200
|
+
handler: async (params) => {
|
|
201
|
+
const action = params.action as string;
|
|
202
|
+
if (action === 'list') {
|
|
203
|
+
return governance.listPendingProposals(
|
|
204
|
+
params.projectPath as string | undefined,
|
|
205
|
+
params.limit as number | undefined,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
if (action === 'approve') {
|
|
209
|
+
return governance.approveProposal(
|
|
210
|
+
params.proposalId as number,
|
|
211
|
+
params.decidedBy as string | undefined,
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
if (action === 'reject') {
|
|
215
|
+
return governance.rejectProposal(
|
|
216
|
+
params.proposalId as number,
|
|
217
|
+
params.decidedBy as string | undefined,
|
|
218
|
+
params.note as string | undefined,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
if (action === 'modify') {
|
|
222
|
+
return governance.modifyProposal(
|
|
223
|
+
params.proposalId as number,
|
|
224
|
+
params.modifications as Record<string, unknown>,
|
|
225
|
+
params.decidedBy as string | undefined,
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
if (action === 'stats') {
|
|
229
|
+
return governance.getProposalStats(params.projectPath as string | undefined);
|
|
230
|
+
}
|
|
231
|
+
if (action === 'expire') {
|
|
232
|
+
const expired = governance.expireStaleProposals(params.maxAgeDays as number | undefined);
|
|
233
|
+
return { expired };
|
|
234
|
+
}
|
|
235
|
+
return { error: 'Unknown action: ' + action };
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: 'governance_stats',
|
|
240
|
+
description: 'Get governance statistics — quota status and proposal stats for a project.',
|
|
241
|
+
auth: 'read',
|
|
242
|
+
schema: z.object({
|
|
243
|
+
projectPath: z.string(),
|
|
244
|
+
}),
|
|
245
|
+
handler: async (params) => {
|
|
246
|
+
const projectPath = params.projectPath as string;
|
|
247
|
+
return {
|
|
248
|
+
quotaStatus: governance.getQuotaStatus(projectPath),
|
|
249
|
+
proposalStats: governance.getProposalStats(projectPath),
|
|
250
|
+
};
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: 'governance_expire',
|
|
255
|
+
description: 'Expire stale pending proposals older than a threshold.',
|
|
256
|
+
auth: 'write',
|
|
257
|
+
schema: z.object({
|
|
258
|
+
projectPath: z.string().optional(),
|
|
259
|
+
maxAgeDays: z.number().optional().describe('Days threshold. Default 14.'),
|
|
260
|
+
}),
|
|
261
|
+
handler: async (params) => {
|
|
262
|
+
const expired = governance.expireStaleProposals(params.maxAgeDays as number | undefined);
|
|
263
|
+
return { expired };
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: 'governance_dashboard',
|
|
268
|
+
description:
|
|
269
|
+
'Get governance dashboard — vault size, quota usage, pending proposals, acceptance rate, evaluation trend.',
|
|
270
|
+
auth: 'read',
|
|
271
|
+
schema: z.object({
|
|
272
|
+
projectPath: z.string(),
|
|
273
|
+
}),
|
|
274
|
+
handler: async (params) => {
|
|
275
|
+
return governance.getDashboard(params.projectPath as string);
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
];
|
|
279
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Curator facade — quality ops.
|
|
3
|
+
* duplicate detection, contradictions, grooming, health audit.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { OpDefinition } from '../../facades/types.js';
|
|
8
|
+
import type { AgentRuntime } from '../types.js';
|
|
9
|
+
import { createCuratorExtraOps } from '../curator-extra-ops.js';
|
|
10
|
+
|
|
11
|
+
export function createCuratorFacadeOps(runtime: AgentRuntime): OpDefinition[] {
|
|
12
|
+
const { curator } = runtime;
|
|
13
|
+
|
|
14
|
+
return [
|
|
15
|
+
// ─── Curator (inline from core-ops.ts) ──────────────────────
|
|
16
|
+
{
|
|
17
|
+
name: 'curator_status',
|
|
18
|
+
description: 'Curator status — table row counts, last groomed timestamp.',
|
|
19
|
+
auth: 'read',
|
|
20
|
+
handler: async () => {
|
|
21
|
+
return curator.getStatus();
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'curator_detect_duplicates',
|
|
26
|
+
description: 'Detect duplicate entries using TF-IDF cosine similarity.',
|
|
27
|
+
auth: 'read',
|
|
28
|
+
schema: z.object({
|
|
29
|
+
entryId: z.string().optional().describe('Check a specific entry. Omit to scan all.'),
|
|
30
|
+
threshold: z.number().optional().describe('Similarity threshold (0-1). Default 0.45.'),
|
|
31
|
+
}),
|
|
32
|
+
handler: async (params) => {
|
|
33
|
+
return curator.detectDuplicates(
|
|
34
|
+
params.entryId as string | undefined,
|
|
35
|
+
params.threshold as number | undefined,
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'curator_contradictions',
|
|
41
|
+
description: 'List or detect contradictions between patterns and anti-patterns.',
|
|
42
|
+
auth: 'read',
|
|
43
|
+
schema: z.object({
|
|
44
|
+
status: z.enum(['open', 'resolved', 'dismissed']).optional().describe('Filter by status.'),
|
|
45
|
+
detect: z.boolean().optional().describe('If true, run detection before listing.'),
|
|
46
|
+
}),
|
|
47
|
+
handler: async (params) => {
|
|
48
|
+
if (params.detect) {
|
|
49
|
+
curator.detectContradictions();
|
|
50
|
+
}
|
|
51
|
+
return curator.getContradictions(
|
|
52
|
+
params.status as 'open' | 'resolved' | 'dismissed' | undefined,
|
|
53
|
+
);
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'curator_resolve_contradiction',
|
|
58
|
+
description: 'Resolve or dismiss a contradiction.',
|
|
59
|
+
auth: 'write',
|
|
60
|
+
schema: z.object({
|
|
61
|
+
id: z.number().describe('Contradiction ID.'),
|
|
62
|
+
resolution: z.enum(['resolved', 'dismissed']),
|
|
63
|
+
}),
|
|
64
|
+
handler: async (params) => {
|
|
65
|
+
return curator.resolveContradiction(
|
|
66
|
+
params.id as number,
|
|
67
|
+
params.resolution as 'resolved' | 'dismissed',
|
|
68
|
+
);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'curator_groom',
|
|
73
|
+
description: 'Groom a single entry — normalize tags, check staleness.',
|
|
74
|
+
auth: 'write',
|
|
75
|
+
schema: z.object({
|
|
76
|
+
entryId: z.string().describe('Entry ID to groom.'),
|
|
77
|
+
}),
|
|
78
|
+
handler: async (params) => {
|
|
79
|
+
return curator.groomEntry(params.entryId as string);
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'curator_groom_all',
|
|
84
|
+
description: 'Groom all vault entries — normalize tags, detect staleness.',
|
|
85
|
+
auth: 'write',
|
|
86
|
+
handler: async () => {
|
|
87
|
+
return curator.groomAll();
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'curator_consolidate',
|
|
92
|
+
description:
|
|
93
|
+
'Consolidate vault — find duplicates, stale entries, contradictions. Dry-run by default.',
|
|
94
|
+
auth: 'write',
|
|
95
|
+
schema: z.object({
|
|
96
|
+
dryRun: z.boolean().optional().describe('Default true. Set false to apply mutations.'),
|
|
97
|
+
staleDaysThreshold: z
|
|
98
|
+
.number()
|
|
99
|
+
.optional()
|
|
100
|
+
.describe('Days before entry is stale. Default 90.'),
|
|
101
|
+
duplicateThreshold: z
|
|
102
|
+
.number()
|
|
103
|
+
.optional()
|
|
104
|
+
.describe('Cosine similarity threshold. Default 0.45.'),
|
|
105
|
+
contradictionThreshold: z
|
|
106
|
+
.number()
|
|
107
|
+
.optional()
|
|
108
|
+
.describe('Contradiction threshold. Default 0.4.'),
|
|
109
|
+
}),
|
|
110
|
+
handler: async (params) => {
|
|
111
|
+
return curator.consolidate({
|
|
112
|
+
dryRun: params.dryRun as boolean | undefined,
|
|
113
|
+
staleDaysThreshold: params.staleDaysThreshold as number | undefined,
|
|
114
|
+
duplicateThreshold: params.duplicateThreshold as number | undefined,
|
|
115
|
+
contradictionThreshold: params.contradictionThreshold as number | undefined,
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'curator_health_audit',
|
|
121
|
+
description:
|
|
122
|
+
'Audit vault health — score (0-100), coverage, freshness, quality, tag health, recommendations.',
|
|
123
|
+
auth: 'read',
|
|
124
|
+
handler: async () => {
|
|
125
|
+
return curator.healthAudit();
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
// ─── Satellite ops ───────────────────────────────────────────
|
|
130
|
+
...createCuratorExtraOps(runtime),
|
|
131
|
+
];
|
|
132
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic facade assembler — creates 10 domain-specific facades
|
|
3
|
+
* matching Salvador's engine-level architecture.
|
|
4
|
+
*
|
|
5
|
+
* Each facade becomes its own MCP tool with op dispatch.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { FacadeConfig } from '../../facades/types.js';
|
|
9
|
+
import type { AgentRuntime } from '../types.js';
|
|
10
|
+
import { createVaultFacadeOps } from './vault-facade.js';
|
|
11
|
+
import { createPlanFacadeOps } from './plan-facade.js';
|
|
12
|
+
import { createBrainFacadeOps } from './brain-facade.js';
|
|
13
|
+
import { createMemoryFacadeOps } from './memory-facade.js';
|
|
14
|
+
import { createAdminFacadeOps } from './admin-facade.js';
|
|
15
|
+
import { createCuratorFacadeOps } from './curator-facade.js';
|
|
16
|
+
import { createLoopFacadeOps } from './loop-facade.js';
|
|
17
|
+
import { createOrchestrateFacadeOps } from './orchestrate-facade.js';
|
|
18
|
+
import { createControlFacadeOps } from './control-facade.js';
|
|
19
|
+
import { createCogneeFacadeOps } from './cognee-facade.js';
|
|
20
|
+
|
|
21
|
+
export function createSemanticFacades(runtime: AgentRuntime, agentId: string): FacadeConfig[] {
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
name: `${agentId}_vault`,
|
|
25
|
+
description: 'Knowledge management — search, CRUD, import/export, intake, archival.',
|
|
26
|
+
ops: createVaultFacadeOps(runtime),
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: `${agentId}_plan`,
|
|
30
|
+
description: 'Plan lifecycle — create, approve, execute, reconcile, complete, grading.',
|
|
31
|
+
ops: createPlanFacadeOps(runtime),
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: `${agentId}_brain`,
|
|
35
|
+
description: 'Learning system — intelligence pipeline, strengths, feedback, sessions.',
|
|
36
|
+
ops: createBrainFacadeOps(runtime),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: `${agentId}_memory`,
|
|
40
|
+
description: 'Session & cross-project memory — capture, search, dedup, promote.',
|
|
41
|
+
ops: createMemoryFacadeOps(runtime),
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: `${agentId}_admin`,
|
|
45
|
+
description: 'Infrastructure — health, config, telemetry, tokens, LLM, prompts.',
|
|
46
|
+
ops: createAdminFacadeOps(runtime),
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: `${agentId}_curator`,
|
|
50
|
+
description: 'Quality — duplicate detection, contradictions, grooming, health audit.',
|
|
51
|
+
ops: createCuratorFacadeOps(runtime),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: `${agentId}_loop`,
|
|
55
|
+
description: 'Iterative validation loops — start, iterate, cancel, complete, history.',
|
|
56
|
+
ops: createLoopFacadeOps(runtime),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: `${agentId}_orchestrate`,
|
|
60
|
+
description: 'Execution orchestration — project registration, playbooks, plan/execute/complete.',
|
|
61
|
+
ops: createOrchestrateFacadeOps(runtime),
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: `${agentId}_control`,
|
|
65
|
+
description: 'Agent behavior — identity, intent routing, morphing, guidelines, governance.',
|
|
66
|
+
ops: createControlFacadeOps(runtime),
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: `${agentId}_cognee`,
|
|
70
|
+
description: 'Knowledge graph — Cognee search, sync, export, graph stats.',
|
|
71
|
+
ops: createCogneeFacadeOps(runtime),
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loop facade — iterative validation loops.
|
|
3
|
+
* start, iterate, cancel, complete, history.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { OpDefinition } from '../../facades/types.js';
|
|
7
|
+
import type { AgentRuntime } from '../types.js';
|
|
8
|
+
import { createLoopOps } from '../loop-ops.js';
|
|
9
|
+
|
|
10
|
+
export function createLoopFacadeOps(runtime: AgentRuntime): OpDefinition[] {
|
|
11
|
+
return createLoopOps(runtime);
|
|
12
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory facade — session & cross-project memory ops.
|
|
3
|
+
* capture, search, dedup, promote.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { OpDefinition } from '../../facades/types.js';
|
|
8
|
+
import type { AgentRuntime } from '../types.js';
|
|
9
|
+
import { createMemoryExtraOps } from '../memory-extra-ops.js';
|
|
10
|
+
import { createMemoryCrossProjectOps } from '../memory-cross-project-ops.js';
|
|
11
|
+
|
|
12
|
+
export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
|
|
13
|
+
const { vault } = runtime;
|
|
14
|
+
|
|
15
|
+
return [
|
|
16
|
+
// ─── Memory (inline from core-ops.ts) ───────────────────────
|
|
17
|
+
{
|
|
18
|
+
name: 'memory_search',
|
|
19
|
+
description: 'Search memories using full-text search.',
|
|
20
|
+
auth: 'read',
|
|
21
|
+
schema: z.object({
|
|
22
|
+
query: z.string(),
|
|
23
|
+
type: z.enum(['session', 'lesson', 'preference']).optional(),
|
|
24
|
+
projectPath: z.string().optional(),
|
|
25
|
+
limit: z.number().optional(),
|
|
26
|
+
}),
|
|
27
|
+
handler: async (params) => {
|
|
28
|
+
return vault.searchMemories(params.query as string, {
|
|
29
|
+
type: params.type as string | undefined,
|
|
30
|
+
projectPath: params.projectPath as string | undefined,
|
|
31
|
+
limit: (params.limit as number) ?? 10,
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'memory_capture',
|
|
37
|
+
description: 'Capture a memory — session summary, lesson learned, or preference.',
|
|
38
|
+
auth: 'write',
|
|
39
|
+
schema: z.object({
|
|
40
|
+
projectPath: z.string(),
|
|
41
|
+
type: z.enum(['session', 'lesson', 'preference']),
|
|
42
|
+
context: z.string(),
|
|
43
|
+
summary: z.string(),
|
|
44
|
+
topics: z.array(z.string()).optional().default([]),
|
|
45
|
+
filesModified: z.array(z.string()).optional().default([]),
|
|
46
|
+
toolsUsed: z.array(z.string()).optional().default([]),
|
|
47
|
+
}),
|
|
48
|
+
handler: async (params) => {
|
|
49
|
+
const memory = vault.captureMemory({
|
|
50
|
+
projectPath: params.projectPath as string,
|
|
51
|
+
type: params.type as 'session' | 'lesson' | 'preference',
|
|
52
|
+
context: params.context as string,
|
|
53
|
+
summary: params.summary as string,
|
|
54
|
+
topics: (params.topics as string[]) ?? [],
|
|
55
|
+
filesModified: (params.filesModified as string[]) ?? [],
|
|
56
|
+
toolsUsed: (params.toolsUsed as string[]) ?? [],
|
|
57
|
+
});
|
|
58
|
+
return { captured: true, memory };
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'memory_list',
|
|
63
|
+
description: 'List memories with optional filters.',
|
|
64
|
+
auth: 'read',
|
|
65
|
+
schema: z.object({
|
|
66
|
+
type: z.enum(['session', 'lesson', 'preference']).optional(),
|
|
67
|
+
projectPath: z.string().optional(),
|
|
68
|
+
limit: z.number().optional(),
|
|
69
|
+
offset: z.number().optional(),
|
|
70
|
+
}),
|
|
71
|
+
handler: async (params) => {
|
|
72
|
+
const memories = vault.listMemories({
|
|
73
|
+
type: params.type as string | undefined,
|
|
74
|
+
projectPath: params.projectPath as string | undefined,
|
|
75
|
+
limit: (params.limit as number) ?? 50,
|
|
76
|
+
offset: (params.offset as number) ?? 0,
|
|
77
|
+
});
|
|
78
|
+
const stats = vault.memoryStats();
|
|
79
|
+
return { memories, stats };
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'session_capture',
|
|
84
|
+
description:
|
|
85
|
+
'Capture a session summary before context compaction. Called automatically by PreCompact hook.',
|
|
86
|
+
auth: 'write',
|
|
87
|
+
schema: z.object({
|
|
88
|
+
projectPath: z.string().optional().default('.'),
|
|
89
|
+
summary: z.string().describe('Brief summary of what was accomplished in this session'),
|
|
90
|
+
topics: z.array(z.string()).optional().default([]),
|
|
91
|
+
filesModified: z.array(z.string()).optional().default([]),
|
|
92
|
+
toolsUsed: z.array(z.string()).optional().default([]),
|
|
93
|
+
}),
|
|
94
|
+
handler: async (params) => {
|
|
95
|
+
const { resolve } = await import('node:path');
|
|
96
|
+
const projectPath = resolve((params.projectPath as string) ?? '.');
|
|
97
|
+
const memory = vault.captureMemory({
|
|
98
|
+
projectPath,
|
|
99
|
+
type: 'session',
|
|
100
|
+
context: 'Auto-captured before context compaction',
|
|
101
|
+
summary: params.summary as string,
|
|
102
|
+
topics: (params.topics as string[]) ?? [],
|
|
103
|
+
filesModified: (params.filesModified as string[]) ?? [],
|
|
104
|
+
toolsUsed: (params.toolsUsed as string[]) ?? [],
|
|
105
|
+
});
|
|
106
|
+
return { captured: true, memory, message: 'Session summary saved to memory.' };
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
// ─── Satellite ops ───────────────────────────────────────────
|
|
111
|
+
...createMemoryExtraOps(runtime),
|
|
112
|
+
...createMemoryCrossProjectOps(runtime),
|
|
113
|
+
];
|
|
114
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrate facade — execution orchestration ops.
|
|
3
|
+
* project registration, playbooks, plan/execute/complete.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { OpDefinition } from '../../facades/types.js';
|
|
8
|
+
import type { AgentRuntime } from '../types.js';
|
|
9
|
+
import { createOrchestrateOps } from '../orchestrate-ops.js';
|
|
10
|
+
import { createProjectOps } from '../project-ops.js';
|
|
11
|
+
import { createPlaybookOps } from '../playbook-ops.js';
|
|
12
|
+
|
|
13
|
+
export function createOrchestrateFacadeOps(runtime: AgentRuntime): OpDefinition[] {
|
|
14
|
+
const { vault, governance, projectRegistry } = runtime;
|
|
15
|
+
|
|
16
|
+
return [
|
|
17
|
+
// ─── Register (inline from core-ops.ts) ─────────────────────
|
|
18
|
+
{
|
|
19
|
+
name: 'register',
|
|
20
|
+
description:
|
|
21
|
+
'Register a project for this session. Call on every new session to track usage and get context.',
|
|
22
|
+
auth: 'write',
|
|
23
|
+
schema: z.object({
|
|
24
|
+
projectPath: z.string().optional().default('.'),
|
|
25
|
+
name: z.string().optional().describe('Project display name (derived from path if omitted)'),
|
|
26
|
+
}),
|
|
27
|
+
handler: async (params) => {
|
|
28
|
+
const { resolve } = await import('node:path');
|
|
29
|
+
const projectPath = resolve((params.projectPath as string) ?? '.');
|
|
30
|
+
const project = vault.registerProject(projectPath, params.name as string | undefined);
|
|
31
|
+
// Also track in project registry for cross-project features
|
|
32
|
+
projectRegistry.register(projectPath, params.name as string | undefined);
|
|
33
|
+
const stats = vault.stats();
|
|
34
|
+
const isNew = project.sessionCount === 1;
|
|
35
|
+
|
|
36
|
+
// Expire stale proposals on session start (fire-and-forget)
|
|
37
|
+
const policy = governance.getPolicy(projectPath);
|
|
38
|
+
const expired = governance.expireStaleProposals(policy.autoCapture.autoExpireDays);
|
|
39
|
+
|
|
40
|
+
const proposalStats = governance.getProposalStats(projectPath);
|
|
41
|
+
const quotaStatus = governance.getQuotaStatus(projectPath);
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
project,
|
|
45
|
+
is_new: isNew,
|
|
46
|
+
message: isNew
|
|
47
|
+
? 'Welcome! New project registered.'
|
|
48
|
+
: 'Welcome back! Session #' + project.sessionCount + ' for ' + project.name + '.',
|
|
49
|
+
vault: { entries: stats.totalEntries, domains: Object.keys(stats.byDomain) },
|
|
50
|
+
governance: {
|
|
51
|
+
pendingProposals: proposalStats.pending,
|
|
52
|
+
quotaPercent:
|
|
53
|
+
quotaStatus.maxTotal > 0
|
|
54
|
+
? Math.round((quotaStatus.total / quotaStatus.maxTotal) * 100)
|
|
55
|
+
: 0,
|
|
56
|
+
isQuotaWarning: quotaStatus.isWarning,
|
|
57
|
+
expiredThisSession: expired,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
// ─── Satellite ops ───────────────────────────────────────────
|
|
64
|
+
...createOrchestrateOps(runtime),
|
|
65
|
+
...createProjectOps(runtime),
|
|
66
|
+
...createPlaybookOps(runtime),
|
|
67
|
+
];
|
|
68
|
+
}
|