@soleri/core 2.8.0 → 2.10.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.map +1 -1
- package/dist/planning/gap-analysis.js +3 -1
- package/dist/planning/gap-analysis.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/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 +52 -7
- 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/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
package/src/index.ts
CHANGED
|
@@ -29,8 +29,6 @@ export type {
|
|
|
29
29
|
MergedPlaybook,
|
|
30
30
|
PlaybookMatchResult,
|
|
31
31
|
} from './playbooks/index.js';
|
|
32
|
-
export { createPlaybookOps } from './runtime/playbook-ops.js';
|
|
33
|
-
|
|
34
32
|
// ─── Text Utilities ─────────────────────────────────────────────────
|
|
35
33
|
export {
|
|
36
34
|
tokenize,
|
|
@@ -239,6 +237,10 @@ export {
|
|
|
239
237
|
export { KeyPool, loadKeyPoolConfig } from './llm/key-pool.js';
|
|
240
238
|
export type { KeyPoolFiles } from './llm/key-pool.js';
|
|
241
239
|
|
|
240
|
+
// ─── Extensions ──────────────────────────────────────────────────────
|
|
241
|
+
export type { AgentExtensions, OpMiddleware, MiddlewareContext } from './extensions/index.js';
|
|
242
|
+
export { wrapWithMiddleware } from './extensions/index.js';
|
|
243
|
+
|
|
242
244
|
// ─── Facades ─────────────────────────────────────────────────────────
|
|
243
245
|
export { registerFacade, registerAllFacades } from './facades/facade-factory.js';
|
|
244
246
|
export { facadeInputSchema } from './facades/types.js';
|
|
@@ -285,22 +287,8 @@ export type { LogLevel, LogEntry, LogContext, LoggerConfig } from './logging/typ
|
|
|
285
287
|
|
|
286
288
|
// ─── Runtime Factory ────────────────────────────────────────────────
|
|
287
289
|
export { createAgentRuntime } from './runtime/runtime.js';
|
|
288
|
-
export {
|
|
290
|
+
export { createSemanticFacades } from './runtime/facades/index.js';
|
|
289
291
|
export { createDomainFacade, createDomainFacades } from './runtime/domain-ops.js';
|
|
290
|
-
export { createPlanningExtraOps } from './runtime/planning-extra-ops.js';
|
|
291
|
-
export { createMemoryExtraOps } from './runtime/memory-extra-ops.js';
|
|
292
|
-
export { createVaultExtraOps } from './runtime/vault-extra-ops.js';
|
|
293
|
-
export { createAdminOps } from './runtime/admin-ops.js';
|
|
294
|
-
export { createAdminExtraOps } from './runtime/admin-extra-ops.js';
|
|
295
|
-
export { createLoopOps } from './runtime/loop-ops.js';
|
|
296
|
-
export { createOrchestrateOps } from './runtime/orchestrate-ops.js';
|
|
297
|
-
export { createGradingOps } from './runtime/grading-ops.js';
|
|
298
|
-
export { createCaptureOps } from './runtime/capture-ops.js';
|
|
299
|
-
export { createCuratorExtraOps } from './runtime/curator-extra-ops.js';
|
|
300
|
-
export { createProjectOps } from './runtime/project-ops.js';
|
|
301
|
-
export { createMemoryCrossProjectOps } from './runtime/memory-cross-project-ops.js';
|
|
302
|
-
export { createCogneeSyncOps } from './runtime/cognee-sync-ops.js';
|
|
303
|
-
export { createIntakeOps } from './runtime/intake-ops.js';
|
|
304
292
|
export type { AgentRuntimeConfig, AgentRuntime } from './runtime/types.js';
|
|
305
293
|
|
|
306
294
|
// ─── Errors ────────────────────────────────────────────────────────────
|
|
@@ -337,6 +325,15 @@ export type {
|
|
|
337
325
|
FtsSearchOptions,
|
|
338
326
|
} from './persistence/index.js';
|
|
339
327
|
|
|
328
|
+
// ─── Streams ──────────────────────────────────────────────────────────
|
|
329
|
+
export { ReplayableStream } from './streams/index.js';
|
|
330
|
+
export { normalize, collect } from './streams/index.js';
|
|
331
|
+
export type { NestableInput } from './streams/index.js';
|
|
332
|
+
|
|
333
|
+
// ─── Content Hashing ──────────────────────────────────────────────────
|
|
334
|
+
export { computeContentHash } from './vault/content-hash.js';
|
|
335
|
+
export type { HashableEntry } from './vault/content-hash.js';
|
|
336
|
+
|
|
340
337
|
// ─── Prompts ───────────────────────────────────────────────────────────
|
|
341
338
|
export { TemplateManager, parseVariables, resolveIncludes } from './prompts/index.js';
|
|
342
339
|
export type { PromptTemplate, TemplateVariable, RenderOptions } from './prompts/index.js';
|
|
@@ -550,21 +550,45 @@ function analyzeKnowledgeDepth(plan: Plan): PlanGap[] {
|
|
|
550
550
|
const matches = desc.match(/[a-z]+-[a-z]+(-[a-z]+)*/g) || [];
|
|
551
551
|
// Filter to likely pattern IDs (hyphenated, 2+ segments, not common words)
|
|
552
552
|
const patternRefs = matches.filter(
|
|
553
|
-
(m) =>
|
|
553
|
+
(m) =>
|
|
554
|
+
m.length > 8 &&
|
|
555
|
+
NAMED_PATTERN_REGEX.test(m) &&
|
|
556
|
+
!['front-end', 'back-end', 'real-time', 'client-side', 'server-side'].includes(m),
|
|
554
557
|
);
|
|
555
558
|
namedPatternCount += patternRefs.length;
|
|
556
559
|
}
|
|
557
560
|
|
|
558
561
|
if (namedPatternCount >= 5) {
|
|
559
562
|
gaps.push(
|
|
560
|
-
gap(
|
|
563
|
+
gap(
|
|
564
|
+
'bonus',
|
|
565
|
+
'knowledge-depth',
|
|
566
|
+
`${namedPatternCount} vault pattern references across tasks — strong knowledge-informed plan.`,
|
|
567
|
+
'',
|
|
568
|
+
'tasks',
|
|
569
|
+
'vault_pattern_refs_high',
|
|
570
|
+
),
|
|
561
571
|
);
|
|
562
572
|
gaps.push(
|
|
563
|
-
gap(
|
|
573
|
+
gap(
|
|
574
|
+
'bonus',
|
|
575
|
+
'knowledge-depth',
|
|
576
|
+
'Vault pattern density indicates expert-level domain knowledge.',
|
|
577
|
+
'',
|
|
578
|
+
'tasks',
|
|
579
|
+
'vault_pattern_density',
|
|
580
|
+
),
|
|
564
581
|
);
|
|
565
582
|
} else if (namedPatternCount >= 2) {
|
|
566
583
|
gaps.push(
|
|
567
|
-
gap(
|
|
584
|
+
gap(
|
|
585
|
+
'bonus',
|
|
586
|
+
'knowledge-depth',
|
|
587
|
+
`${namedPatternCount} vault pattern references across tasks.`,
|
|
588
|
+
'',
|
|
589
|
+
'tasks',
|
|
590
|
+
'vault_pattern_refs_medium',
|
|
591
|
+
),
|
|
568
592
|
);
|
|
569
593
|
}
|
|
570
594
|
|
|
@@ -580,7 +604,14 @@ function analyzeKnowledgeDepth(plan: Plan): PlanGap[] {
|
|
|
580
604
|
|
|
581
605
|
if (plan.tasks.length > 0 && tasksWithCriteria / plan.tasks.length >= 0.8) {
|
|
582
606
|
gaps.push(
|
|
583
|
-
gap(
|
|
607
|
+
gap(
|
|
608
|
+
'bonus',
|
|
609
|
+
'knowledge-depth',
|
|
610
|
+
`${tasksWithCriteria}/${plan.tasks.length} tasks have acceptance criteria (${totalCriteria} total).`,
|
|
611
|
+
'',
|
|
612
|
+
'tasks',
|
|
613
|
+
'high_acceptance_criteria',
|
|
614
|
+
),
|
|
584
615
|
);
|
|
585
616
|
}
|
|
586
617
|
|
|
@@ -592,7 +623,14 @@ function analyzeKnowledgeDepth(plan: Plan): PlanGap[] {
|
|
|
592
623
|
|
|
593
624
|
if (indicatorHits >= 4) {
|
|
594
625
|
gaps.push(
|
|
595
|
-
gap(
|
|
626
|
+
gap(
|
|
627
|
+
'bonus',
|
|
628
|
+
'knowledge-depth',
|
|
629
|
+
`${indicatorHits} domain-specific knowledge indicators found (WCAG, ARIA, contrast ratios, touch targets, etc.).`,
|
|
630
|
+
'',
|
|
631
|
+
'tasks',
|
|
632
|
+
'domain_knowledge_indicators',
|
|
633
|
+
),
|
|
596
634
|
);
|
|
597
635
|
}
|
|
598
636
|
|
|
@@ -602,7 +640,14 @@ function analyzeKnowledgeDepth(plan: Plan): PlanGap[] {
|
|
|
602
640
|
plan.tasks.reduce((sum, t) => sum + (t.description?.length ?? 0), 0) / plan.tasks.length;
|
|
603
641
|
if (avgDescLength >= 80) {
|
|
604
642
|
gaps.push(
|
|
605
|
-
gap(
|
|
643
|
+
gap(
|
|
644
|
+
'bonus',
|
|
645
|
+
'knowledge-depth',
|
|
646
|
+
`Task descriptions average ${Math.round(avgDescLength)} chars — detailed and specific.`,
|
|
647
|
+
'',
|
|
648
|
+
'tasks',
|
|
649
|
+
'rich_task_descriptions',
|
|
650
|
+
),
|
|
606
651
|
);
|
|
607
652
|
}
|
|
608
653
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin facade — infrastructure ops.
|
|
3
|
+
* health, config, telemetry, tokens, LLM, prompts.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { OpDefinition } from '../../facades/types.js';
|
|
8
|
+
import type { AgentRuntime } from '../types.js';
|
|
9
|
+
import { createAdminOps } from '../admin-ops.js';
|
|
10
|
+
import { createAdminExtraOps } from '../admin-extra-ops.js';
|
|
11
|
+
|
|
12
|
+
export function createAdminFacadeOps(runtime: AgentRuntime): OpDefinition[] {
|
|
13
|
+
const { llmClient, keyPool } = runtime;
|
|
14
|
+
|
|
15
|
+
return [
|
|
16
|
+
// ─── LLM (inline from core-ops.ts) ──────────────────────────
|
|
17
|
+
{
|
|
18
|
+
name: 'llm_rotate',
|
|
19
|
+
description:
|
|
20
|
+
'Force rotate the active API key for a provider. Useful when rate-limited or key is failing.',
|
|
21
|
+
auth: 'write',
|
|
22
|
+
schema: z.object({
|
|
23
|
+
provider: z.enum(['openai', 'anthropic']),
|
|
24
|
+
}),
|
|
25
|
+
handler: async (params) => {
|
|
26
|
+
const provider = params.provider as 'openai' | 'anthropic';
|
|
27
|
+
const pool = keyPool[provider];
|
|
28
|
+
if (!pool.hasKeys) return { rotated: false, error: `No ${provider} keys configured` };
|
|
29
|
+
const newKey = pool.rotateOnError();
|
|
30
|
+
return {
|
|
31
|
+
rotated: newKey !== null,
|
|
32
|
+
activeKeyIndex: pool.activeKeyIndex,
|
|
33
|
+
poolSize: pool.poolSize,
|
|
34
|
+
exhausted: pool.exhausted,
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'llm_call',
|
|
40
|
+
description: 'Make an LLM completion call. Uses model routing config and key pool rotation.',
|
|
41
|
+
auth: 'write',
|
|
42
|
+
schema: z.object({
|
|
43
|
+
systemPrompt: z.string().describe('System prompt for the LLM.'),
|
|
44
|
+
userPrompt: z.string().describe('User prompt / task input.'),
|
|
45
|
+
model: z
|
|
46
|
+
.string()
|
|
47
|
+
.optional()
|
|
48
|
+
.describe('Model name. Routed via model-routing.json if omitted.'),
|
|
49
|
+
temperature: z.number().optional().describe('Sampling temperature (0-2). Default 0.3.'),
|
|
50
|
+
maxTokens: z.number().optional().describe('Max output tokens. Default 500.'),
|
|
51
|
+
caller: z.string().optional().describe('Caller name for routing. Default "core-ops".'),
|
|
52
|
+
task: z.string().optional().describe('Task name for routing.'),
|
|
53
|
+
}),
|
|
54
|
+
handler: async (params) => {
|
|
55
|
+
return llmClient.complete({
|
|
56
|
+
provider: 'openai',
|
|
57
|
+
model: (params.model as string) ?? '',
|
|
58
|
+
systemPrompt: params.systemPrompt as string,
|
|
59
|
+
userPrompt: params.userPrompt as string,
|
|
60
|
+
temperature: params.temperature as number | undefined,
|
|
61
|
+
maxTokens: params.maxTokens as number | undefined,
|
|
62
|
+
caller: (params.caller as string) ?? 'core-ops',
|
|
63
|
+
task: params.task as string | undefined,
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
// ─── Prompt Templates (inline from core-ops.ts) ─────────────
|
|
69
|
+
{
|
|
70
|
+
name: 'render_prompt',
|
|
71
|
+
description:
|
|
72
|
+
'Render a prompt template with variable substitution. Templates are .prompt files loaded from the templates directory.',
|
|
73
|
+
auth: 'read' as const,
|
|
74
|
+
schema: z.object({
|
|
75
|
+
template: z.string().describe('Template name (without .prompt extension)'),
|
|
76
|
+
variables: z.record(z.string()).optional().default({}),
|
|
77
|
+
strict: z.boolean().optional().default(true),
|
|
78
|
+
}),
|
|
79
|
+
handler: async (params) => {
|
|
80
|
+
const rendered = runtime.templateManager.render(
|
|
81
|
+
params.template as string,
|
|
82
|
+
(params.variables ?? {}) as Record<string, string>,
|
|
83
|
+
{ strict: params.strict as boolean },
|
|
84
|
+
);
|
|
85
|
+
return { rendered };
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'list_templates',
|
|
90
|
+
description: 'List all loaded prompt templates.',
|
|
91
|
+
auth: 'read' as const,
|
|
92
|
+
handler: async () => ({
|
|
93
|
+
templates: runtime.templateManager.listTemplates(),
|
|
94
|
+
}),
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
// ─── Satellite ops ───────────────────────────────────────────
|
|
98
|
+
...createAdminOps(runtime),
|
|
99
|
+
...createAdminExtraOps(runtime),
|
|
100
|
+
];
|
|
101
|
+
}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brain facade — learning system ops.
|
|
3
|
+
* intelligence pipeline, strengths, feedback, sessions.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { OpDefinition } from '../../facades/types.js';
|
|
8
|
+
import type { AgentRuntime } from '../types.js';
|
|
9
|
+
|
|
10
|
+
export function createBrainFacadeOps(runtime: AgentRuntime): OpDefinition[] {
|
|
11
|
+
const { brain, brainIntelligence, llmClient, keyPool, governance } = runtime;
|
|
12
|
+
|
|
13
|
+
return [
|
|
14
|
+
// ─── Brain (inline from core-ops.ts) ────────────────────────
|
|
15
|
+
{
|
|
16
|
+
name: 'record_feedback',
|
|
17
|
+
description:
|
|
18
|
+
'Record feedback on a search result — accepted or dismissed. Used for adaptive weight tuning.',
|
|
19
|
+
auth: 'write',
|
|
20
|
+
schema: z.object({
|
|
21
|
+
query: z.string().describe('The original search query'),
|
|
22
|
+
entryId: z.string().describe('The entry ID that was accepted or dismissed'),
|
|
23
|
+
action: z.enum(['accepted', 'dismissed']),
|
|
24
|
+
}),
|
|
25
|
+
handler: async (params) => {
|
|
26
|
+
brain.recordFeedback(
|
|
27
|
+
params.query as string,
|
|
28
|
+
params.entryId as string,
|
|
29
|
+
params.action as 'accepted' | 'dismissed',
|
|
30
|
+
);
|
|
31
|
+
return {
|
|
32
|
+
recorded: true,
|
|
33
|
+
query: params.query,
|
|
34
|
+
entryId: params.entryId,
|
|
35
|
+
action: params.action,
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'brain_feedback',
|
|
41
|
+
description:
|
|
42
|
+
'Enhanced feedback with typed actions (accepted/dismissed/modified/failed), source tracking, confidence, duration, and reason.',
|
|
43
|
+
auth: 'write',
|
|
44
|
+
schema: z.object({
|
|
45
|
+
query: z.string().describe('The original search query'),
|
|
46
|
+
entryId: z.string().describe('The entry ID'),
|
|
47
|
+
action: z.enum(['accepted', 'dismissed', 'modified', 'failed']),
|
|
48
|
+
source: z
|
|
49
|
+
.enum(['search', 'recommendation', 'tool-execution', 'explicit'])
|
|
50
|
+
.optional()
|
|
51
|
+
.describe("Feedback source. Default 'search'."),
|
|
52
|
+
confidence: z.number().optional().describe('Confidence 0-1. Default 0.6.'),
|
|
53
|
+
duration: z.number().optional().describe('Duration in ms.'),
|
|
54
|
+
context: z.string().optional().describe("JSON context string. Default '{}'."),
|
|
55
|
+
reason: z.string().optional().describe('Human-readable reason.'),
|
|
56
|
+
}),
|
|
57
|
+
handler: async (params) => {
|
|
58
|
+
const entry = brain.recordFeedback({
|
|
59
|
+
query: params.query as string,
|
|
60
|
+
entryId: params.entryId as string,
|
|
61
|
+
action: params.action as 'accepted' | 'dismissed' | 'modified' | 'failed',
|
|
62
|
+
source: params.source as
|
|
63
|
+
| 'search'
|
|
64
|
+
| 'recommendation'
|
|
65
|
+
| 'tool-execution'
|
|
66
|
+
| 'explicit'
|
|
67
|
+
| undefined,
|
|
68
|
+
confidence: params.confidence as number | undefined,
|
|
69
|
+
duration: params.duration as number | undefined,
|
|
70
|
+
context: params.context as string | undefined,
|
|
71
|
+
reason: params.reason as string | undefined,
|
|
72
|
+
});
|
|
73
|
+
return entry;
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'brain_feedback_stats',
|
|
78
|
+
description:
|
|
79
|
+
'Feedback statistics — counts by action and source, acceptance rate, average confidence.',
|
|
80
|
+
auth: 'read',
|
|
81
|
+
handler: async () => {
|
|
82
|
+
return brain.getFeedbackStats();
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'rebuild_vocabulary',
|
|
87
|
+
description: 'Force rebuild the TF-IDF vocabulary from all vault entries.',
|
|
88
|
+
auth: 'write',
|
|
89
|
+
handler: async () => {
|
|
90
|
+
brain.rebuildVocabulary();
|
|
91
|
+
return { rebuilt: true, vocabularySize: brain.getVocabularySize() };
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'brain_stats',
|
|
96
|
+
description:
|
|
97
|
+
'Get brain intelligence stats — vocabulary size, feedback count, current scoring weights, intelligence pipeline stats.',
|
|
98
|
+
auth: 'read',
|
|
99
|
+
handler: async () => {
|
|
100
|
+
const base = brain.getStats();
|
|
101
|
+
const intelligence = brainIntelligence.getStats();
|
|
102
|
+
return { ...base, intelligence };
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'brain_decay_report',
|
|
107
|
+
description:
|
|
108
|
+
'Show temporal decay scores for entries matching a query — reveals which entries are expiring, active, or expired.',
|
|
109
|
+
auth: 'read',
|
|
110
|
+
schema: z.object({
|
|
111
|
+
query: z.string().describe('Search query to find entries'),
|
|
112
|
+
limit: z.number().optional().describe('Max results (default 10)'),
|
|
113
|
+
}),
|
|
114
|
+
handler: async (params) => {
|
|
115
|
+
const results = await brain.getDecayReport(
|
|
116
|
+
params.query as string,
|
|
117
|
+
(params.limit as number | undefined) ?? 10,
|
|
118
|
+
);
|
|
119
|
+
return { results, count: results.length };
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'llm_status',
|
|
124
|
+
description:
|
|
125
|
+
'LLM client status — provider availability, key pool status, model routing config.',
|
|
126
|
+
auth: 'read',
|
|
127
|
+
handler: async () => {
|
|
128
|
+
const available = llmClient.isAvailable();
|
|
129
|
+
return {
|
|
130
|
+
providers: {
|
|
131
|
+
openai: {
|
|
132
|
+
available: available.openai,
|
|
133
|
+
keyPool: keyPool.openai.hasKeys ? keyPool.openai.getStatus() : null,
|
|
134
|
+
},
|
|
135
|
+
anthropic: {
|
|
136
|
+
available: available.anthropic,
|
|
137
|
+
keyPool: keyPool.anthropic.hasKeys ? keyPool.anthropic.getStatus() : null,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
routes: llmClient.getRoutes(),
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
// ─── Brain Intelligence ──────────────────────────────────────
|
|
146
|
+
{
|
|
147
|
+
name: 'brain_session_context',
|
|
148
|
+
description:
|
|
149
|
+
'Get recent session context — sessions, tool usage frequency, file change frequency.',
|
|
150
|
+
auth: 'read',
|
|
151
|
+
schema: z.object({
|
|
152
|
+
limit: z.number().optional().describe('Number of recent sessions. Default 10.'),
|
|
153
|
+
}),
|
|
154
|
+
handler: async (params) => {
|
|
155
|
+
return brainIntelligence.getSessionContext((params.limit as number) ?? 10);
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'brain_strengths',
|
|
160
|
+
description:
|
|
161
|
+
'Get pattern strength scores. 4-signal scoring: usage (0-25) + spread (0-25) + success (0-25) + recency (0-25).',
|
|
162
|
+
auth: 'read',
|
|
163
|
+
schema: z.object({
|
|
164
|
+
domain: z.string().optional(),
|
|
165
|
+
minStrength: z.number().optional().describe('Minimum strength score (0-100).'),
|
|
166
|
+
limit: z.number().optional(),
|
|
167
|
+
}),
|
|
168
|
+
handler: async (params) => {
|
|
169
|
+
return brainIntelligence.getStrengths({
|
|
170
|
+
domain: params.domain as string | undefined,
|
|
171
|
+
minStrength: params.minStrength as number | undefined,
|
|
172
|
+
limit: (params.limit as number) ?? 50,
|
|
173
|
+
});
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'brain_global_patterns',
|
|
178
|
+
description:
|
|
179
|
+
'Get cross-domain pattern registry — patterns that appear across multiple domains.',
|
|
180
|
+
auth: 'read',
|
|
181
|
+
schema: z.object({
|
|
182
|
+
limit: z.number().optional(),
|
|
183
|
+
}),
|
|
184
|
+
handler: async (params) => {
|
|
185
|
+
return brainIntelligence.getGlobalPatterns((params.limit as number) ?? 20);
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: 'brain_recommend',
|
|
190
|
+
description:
|
|
191
|
+
'Get pattern recommendations for a task context. Matches domain, task terms, and source-specific acceptance rates against known strengths.',
|
|
192
|
+
auth: 'read',
|
|
193
|
+
schema: z.object({
|
|
194
|
+
domain: z.string().optional(),
|
|
195
|
+
task: z.string().optional().describe('Task description for contextual matching.'),
|
|
196
|
+
source: z
|
|
197
|
+
.string()
|
|
198
|
+
.optional()
|
|
199
|
+
.describe(
|
|
200
|
+
'Feedback source to boost by (search, recommendation, tool-execution, explicit).',
|
|
201
|
+
),
|
|
202
|
+
limit: z.number().optional(),
|
|
203
|
+
}),
|
|
204
|
+
handler: async (params) => {
|
|
205
|
+
return brainIntelligence.recommend({
|
|
206
|
+
domain: params.domain as string | undefined,
|
|
207
|
+
task: params.task as string | undefined,
|
|
208
|
+
source: params.source as string | undefined,
|
|
209
|
+
limit: (params.limit as number) ?? 5,
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: 'brain_build_intelligence',
|
|
215
|
+
description:
|
|
216
|
+
'Run the full intelligence pipeline: compute strengths → build global registry → build domain profiles.',
|
|
217
|
+
auth: 'write',
|
|
218
|
+
handler: async () => {
|
|
219
|
+
return brainIntelligence.buildIntelligence();
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: 'brain_export',
|
|
224
|
+
description:
|
|
225
|
+
'Export all brain intelligence data — strengths, sessions, proposals, global patterns, domain profiles.',
|
|
226
|
+
auth: 'read',
|
|
227
|
+
handler: async () => {
|
|
228
|
+
return brainIntelligence.exportData();
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: 'brain_import',
|
|
233
|
+
description: 'Import brain intelligence data from a previous export.',
|
|
234
|
+
auth: 'write',
|
|
235
|
+
schema: z.object({
|
|
236
|
+
data: z.any().describe('BrainExportData object from brain_export.'),
|
|
237
|
+
}),
|
|
238
|
+
handler: async (params) => {
|
|
239
|
+
return brainIntelligence.importData(
|
|
240
|
+
params.data as import('../../brain/types.js').BrainExportData,
|
|
241
|
+
);
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
name: 'brain_extract_knowledge',
|
|
246
|
+
description:
|
|
247
|
+
'Extract knowledge proposals from a session using 6 heuristic rules (repeated tools, multi-file edits, long sessions, plan outcomes, feedback ratios).',
|
|
248
|
+
auth: 'write',
|
|
249
|
+
schema: z.object({
|
|
250
|
+
sessionId: z.string().describe('Session ID to extract knowledge from.'),
|
|
251
|
+
}),
|
|
252
|
+
handler: async (params) => {
|
|
253
|
+
return brainIntelligence.extractKnowledge(params.sessionId as string);
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
name: 'brain_archive_sessions',
|
|
258
|
+
description: 'Archive (delete) completed sessions older than N days.',
|
|
259
|
+
auth: 'write',
|
|
260
|
+
schema: z.object({
|
|
261
|
+
olderThanDays: z.number().optional().describe('Days threshold. Default 30.'),
|
|
262
|
+
}),
|
|
263
|
+
handler: async (params) => {
|
|
264
|
+
return brainIntelligence.archiveSessions((params.olderThanDays as number) ?? 30);
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: 'brain_promote_proposals',
|
|
269
|
+
description:
|
|
270
|
+
'Promote knowledge proposals to vault entries. Creates intelligence entries from auto-extracted patterns. Gated by governance policies.',
|
|
271
|
+
auth: 'write',
|
|
272
|
+
schema: z.object({
|
|
273
|
+
proposalIds: z.array(z.string()).describe('IDs of proposals to promote.'),
|
|
274
|
+
projectPath: z.string().optional().default('.'),
|
|
275
|
+
}),
|
|
276
|
+
handler: async (params) => {
|
|
277
|
+
const pp = (params.projectPath as string | undefined) ?? '.';
|
|
278
|
+
return brainIntelligence.promoteProposals(params.proposalIds as string[], governance, pp);
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
name: 'brain_lifecycle',
|
|
283
|
+
description:
|
|
284
|
+
'Start or end a brain session. Sessions track tool usage, file changes, and plan context.',
|
|
285
|
+
auth: 'write',
|
|
286
|
+
schema: z.object({
|
|
287
|
+
action: z.enum(['start', 'end']),
|
|
288
|
+
sessionId: z
|
|
289
|
+
.string()
|
|
290
|
+
.optional()
|
|
291
|
+
.describe('Required for end. Auto-generated for start if omitted.'),
|
|
292
|
+
domain: z.string().optional(),
|
|
293
|
+
context: z.string().optional(),
|
|
294
|
+
toolsUsed: z.array(z.string()).optional(),
|
|
295
|
+
filesModified: z.array(z.string()).optional(),
|
|
296
|
+
planId: z.string().optional(),
|
|
297
|
+
planOutcome: z.string().optional(),
|
|
298
|
+
}),
|
|
299
|
+
handler: async (params) => {
|
|
300
|
+
return brainIntelligence.lifecycle({
|
|
301
|
+
action: params.action as 'start' | 'end',
|
|
302
|
+
sessionId: params.sessionId as string | undefined,
|
|
303
|
+
domain: params.domain as string | undefined,
|
|
304
|
+
context: params.context as string | undefined,
|
|
305
|
+
toolsUsed: params.toolsUsed as string[] | undefined,
|
|
306
|
+
filesModified: params.filesModified as string[] | undefined,
|
|
307
|
+
planId: params.planId as string | undefined,
|
|
308
|
+
planOutcome: params.planOutcome as string | undefined,
|
|
309
|
+
});
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: 'brain_reset_extracted',
|
|
314
|
+
description:
|
|
315
|
+
'Reset extraction status on brain sessions, allowing re-extraction. Filter by sessionId, since date, or all.',
|
|
316
|
+
auth: 'write',
|
|
317
|
+
schema: z.object({
|
|
318
|
+
sessionId: z.string().optional().describe('Reset a specific session.'),
|
|
319
|
+
since: z.string().optional().describe('Reset sessions extracted since this ISO date.'),
|
|
320
|
+
all: z.boolean().optional().describe('Reset all extracted sessions.'),
|
|
321
|
+
}),
|
|
322
|
+
handler: async (params) => {
|
|
323
|
+
return brainIntelligence.resetExtracted({
|
|
324
|
+
sessionId: params.sessionId as string | undefined,
|
|
325
|
+
since: params.since as string | undefined,
|
|
326
|
+
all: params.all as boolean | undefined,
|
|
327
|
+
});
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
];
|
|
331
|
+
}
|