@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.
Files changed (207) hide show
  1. package/dist/brain/brain.d.ts +3 -1
  2. package/dist/brain/brain.d.ts.map +1 -1
  3. package/dist/brain/brain.js +60 -4
  4. package/dist/brain/brain.js.map +1 -1
  5. package/dist/brain/intelligence.d.ts +36 -1
  6. package/dist/brain/intelligence.d.ts.map +1 -1
  7. package/dist/brain/intelligence.js +119 -14
  8. package/dist/brain/intelligence.js.map +1 -1
  9. package/dist/brain/types.d.ts +32 -0
  10. package/dist/brain/types.d.ts.map +1 -1
  11. package/dist/control/identity-manager.d.ts +22 -0
  12. package/dist/control/identity-manager.d.ts.map +1 -0
  13. package/dist/control/identity-manager.js +233 -0
  14. package/dist/control/identity-manager.js.map +1 -0
  15. package/dist/control/intent-router.d.ts +32 -0
  16. package/dist/control/intent-router.d.ts.map +1 -0
  17. package/dist/control/intent-router.js +242 -0
  18. package/dist/control/intent-router.js.map +1 -0
  19. package/dist/control/types.d.ts +68 -0
  20. package/dist/control/types.d.ts.map +1 -0
  21. package/dist/control/types.js +9 -0
  22. package/dist/control/types.js.map +1 -0
  23. package/dist/curator/curator.d.ts +29 -0
  24. package/dist/curator/curator.d.ts.map +1 -1
  25. package/dist/curator/curator.js +135 -0
  26. package/dist/curator/curator.js.map +1 -1
  27. package/dist/facades/types.d.ts +1 -1
  28. package/dist/governance/governance.d.ts +42 -0
  29. package/dist/governance/governance.d.ts.map +1 -0
  30. package/dist/governance/governance.js +488 -0
  31. package/dist/governance/governance.js.map +1 -0
  32. package/dist/governance/index.d.ts +3 -0
  33. package/dist/governance/index.d.ts.map +1 -0
  34. package/dist/governance/index.js +2 -0
  35. package/dist/governance/index.js.map +1 -0
  36. package/dist/governance/types.d.ts +102 -0
  37. package/dist/governance/types.d.ts.map +1 -0
  38. package/dist/governance/types.js +3 -0
  39. package/dist/governance/types.js.map +1 -0
  40. package/dist/index.d.ts +32 -3
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +29 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/logging/logger.d.ts +37 -0
  45. package/dist/logging/logger.d.ts.map +1 -0
  46. package/dist/logging/logger.js +145 -0
  47. package/dist/logging/logger.js.map +1 -0
  48. package/dist/logging/types.d.ts +19 -0
  49. package/dist/logging/types.d.ts.map +1 -0
  50. package/dist/logging/types.js +2 -0
  51. package/dist/logging/types.js.map +1 -0
  52. package/dist/loop/loop-manager.d.ts +49 -0
  53. package/dist/loop/loop-manager.d.ts.map +1 -0
  54. package/dist/loop/loop-manager.js +105 -0
  55. package/dist/loop/loop-manager.js.map +1 -0
  56. package/dist/loop/types.d.ts +35 -0
  57. package/dist/loop/types.d.ts.map +1 -0
  58. package/dist/loop/types.js +8 -0
  59. package/dist/loop/types.js.map +1 -0
  60. package/dist/planning/gap-analysis.d.ts +29 -0
  61. package/dist/planning/gap-analysis.d.ts.map +1 -0
  62. package/dist/planning/gap-analysis.js +265 -0
  63. package/dist/planning/gap-analysis.js.map +1 -0
  64. package/dist/planning/gap-types.d.ts +29 -0
  65. package/dist/planning/gap-types.d.ts.map +1 -0
  66. package/dist/planning/gap-types.js +28 -0
  67. package/dist/planning/gap-types.js.map +1 -0
  68. package/dist/planning/planner.d.ts +150 -1
  69. package/dist/planning/planner.d.ts.map +1 -1
  70. package/dist/planning/planner.js +365 -2
  71. package/dist/planning/planner.js.map +1 -1
  72. package/dist/project/project-registry.d.ts +79 -0
  73. package/dist/project/project-registry.d.ts.map +1 -0
  74. package/dist/project/project-registry.js +276 -0
  75. package/dist/project/project-registry.js.map +1 -0
  76. package/dist/project/types.d.ts +28 -0
  77. package/dist/project/types.d.ts.map +1 -0
  78. package/dist/project/types.js +5 -0
  79. package/dist/project/types.js.map +1 -0
  80. package/dist/runtime/admin-extra-ops.d.ts +13 -0
  81. package/dist/runtime/admin-extra-ops.d.ts.map +1 -0
  82. package/dist/runtime/admin-extra-ops.js +284 -0
  83. package/dist/runtime/admin-extra-ops.js.map +1 -0
  84. package/dist/runtime/admin-ops.d.ts +15 -0
  85. package/dist/runtime/admin-ops.d.ts.map +1 -0
  86. package/dist/runtime/admin-ops.js +322 -0
  87. package/dist/runtime/admin-ops.js.map +1 -0
  88. package/dist/runtime/capture-ops.d.ts +15 -0
  89. package/dist/runtime/capture-ops.d.ts.map +1 -0
  90. package/dist/runtime/capture-ops.js +345 -0
  91. package/dist/runtime/capture-ops.js.map +1 -0
  92. package/dist/runtime/core-ops.d.ts +7 -3
  93. package/dist/runtime/core-ops.d.ts.map +1 -1
  94. package/dist/runtime/core-ops.js +474 -8
  95. package/dist/runtime/core-ops.js.map +1 -1
  96. package/dist/runtime/curator-extra-ops.d.ts +9 -0
  97. package/dist/runtime/curator-extra-ops.d.ts.map +1 -0
  98. package/dist/runtime/curator-extra-ops.js +59 -0
  99. package/dist/runtime/curator-extra-ops.js.map +1 -0
  100. package/dist/runtime/domain-ops.d.ts.map +1 -1
  101. package/dist/runtime/domain-ops.js +59 -13
  102. package/dist/runtime/domain-ops.js.map +1 -1
  103. package/dist/runtime/grading-ops.d.ts +14 -0
  104. package/dist/runtime/grading-ops.d.ts.map +1 -0
  105. package/dist/runtime/grading-ops.js +105 -0
  106. package/dist/runtime/grading-ops.js.map +1 -0
  107. package/dist/runtime/loop-ops.d.ts +13 -0
  108. package/dist/runtime/loop-ops.d.ts.map +1 -0
  109. package/dist/runtime/loop-ops.js +179 -0
  110. package/dist/runtime/loop-ops.js.map +1 -0
  111. package/dist/runtime/memory-cross-project-ops.d.ts +12 -0
  112. package/dist/runtime/memory-cross-project-ops.d.ts.map +1 -0
  113. package/dist/runtime/memory-cross-project-ops.js +165 -0
  114. package/dist/runtime/memory-cross-project-ops.js.map +1 -0
  115. package/dist/runtime/memory-extra-ops.d.ts +13 -0
  116. package/dist/runtime/memory-extra-ops.d.ts.map +1 -0
  117. package/dist/runtime/memory-extra-ops.js +173 -0
  118. package/dist/runtime/memory-extra-ops.js.map +1 -0
  119. package/dist/runtime/orchestrate-ops.d.ts +17 -0
  120. package/dist/runtime/orchestrate-ops.d.ts.map +1 -0
  121. package/dist/runtime/orchestrate-ops.js +240 -0
  122. package/dist/runtime/orchestrate-ops.js.map +1 -0
  123. package/dist/runtime/planning-extra-ops.d.ts +17 -0
  124. package/dist/runtime/planning-extra-ops.d.ts.map +1 -0
  125. package/dist/runtime/planning-extra-ops.js +300 -0
  126. package/dist/runtime/planning-extra-ops.js.map +1 -0
  127. package/dist/runtime/project-ops.d.ts +15 -0
  128. package/dist/runtime/project-ops.d.ts.map +1 -0
  129. package/dist/runtime/project-ops.js +181 -0
  130. package/dist/runtime/project-ops.js.map +1 -0
  131. package/dist/runtime/runtime.d.ts.map +1 -1
  132. package/dist/runtime/runtime.js +44 -1
  133. package/dist/runtime/runtime.js.map +1 -1
  134. package/dist/runtime/types.d.ts +21 -0
  135. package/dist/runtime/types.d.ts.map +1 -1
  136. package/dist/runtime/vault-extra-ops.d.ts +9 -0
  137. package/dist/runtime/vault-extra-ops.d.ts.map +1 -0
  138. package/dist/runtime/vault-extra-ops.js +195 -0
  139. package/dist/runtime/vault-extra-ops.js.map +1 -0
  140. package/dist/telemetry/telemetry.d.ts +48 -0
  141. package/dist/telemetry/telemetry.d.ts.map +1 -0
  142. package/dist/telemetry/telemetry.js +87 -0
  143. package/dist/telemetry/telemetry.js.map +1 -0
  144. package/dist/vault/vault.d.ts +94 -0
  145. package/dist/vault/vault.d.ts.map +1 -1
  146. package/dist/vault/vault.js +340 -1
  147. package/dist/vault/vault.js.map +1 -1
  148. package/package.json +1 -1
  149. package/src/__tests__/admin-extra-ops.test.ts +420 -0
  150. package/src/__tests__/admin-ops.test.ts +271 -0
  151. package/src/__tests__/brain-intelligence.test.ts +205 -0
  152. package/src/__tests__/brain.test.ts +131 -0
  153. package/src/__tests__/capture-ops.test.ts +509 -0
  154. package/src/__tests__/core-ops.test.ts +266 -2
  155. package/src/__tests__/curator-extra-ops.test.ts +359 -0
  156. package/src/__tests__/domain-ops.test.ts +66 -0
  157. package/src/__tests__/governance.test.ts +522 -0
  158. package/src/__tests__/grading-ops.test.ts +340 -0
  159. package/src/__tests__/identity-manager.test.ts +243 -0
  160. package/src/__tests__/intent-router.test.ts +222 -0
  161. package/src/__tests__/logger.test.ts +200 -0
  162. package/src/__tests__/loop-ops.test.ts +398 -0
  163. package/src/__tests__/memory-cross-project-ops.test.ts +246 -0
  164. package/src/__tests__/memory-extra-ops.test.ts +352 -0
  165. package/src/__tests__/orchestrate-ops.test.ts +284 -0
  166. package/src/__tests__/planner.test.ts +331 -0
  167. package/src/__tests__/planning-extra-ops.test.ts +548 -0
  168. package/src/__tests__/project-ops.test.ts +367 -0
  169. package/src/__tests__/vault-extra-ops.test.ts +407 -0
  170. package/src/brain/brain.ts +114 -7
  171. package/src/brain/intelligence.ts +179 -10
  172. package/src/brain/types.ts +38 -0
  173. package/src/control/identity-manager.ts +354 -0
  174. package/src/control/intent-router.ts +326 -0
  175. package/src/control/types.ts +102 -0
  176. package/src/curator/curator.ts +213 -0
  177. package/src/governance/governance.ts +698 -0
  178. package/src/governance/index.ts +18 -0
  179. package/src/governance/types.ts +111 -0
  180. package/src/index.ts +102 -2
  181. package/src/logging/logger.ts +154 -0
  182. package/src/logging/types.ts +21 -0
  183. package/src/loop/loop-manager.ts +130 -0
  184. package/src/loop/types.ts +44 -0
  185. package/src/planning/gap-analysis.ts +506 -0
  186. package/src/planning/gap-types.ts +58 -0
  187. package/src/planning/planner.ts +478 -2
  188. package/src/project/project-registry.ts +358 -0
  189. package/src/project/types.ts +31 -0
  190. package/src/runtime/admin-extra-ops.ts +307 -0
  191. package/src/runtime/admin-ops.ts +329 -0
  192. package/src/runtime/capture-ops.ts +385 -0
  193. package/src/runtime/core-ops.ts +535 -7
  194. package/src/runtime/curator-extra-ops.ts +71 -0
  195. package/src/runtime/domain-ops.ts +65 -13
  196. package/src/runtime/grading-ops.ts +121 -0
  197. package/src/runtime/loop-ops.ts +194 -0
  198. package/src/runtime/memory-cross-project-ops.ts +192 -0
  199. package/src/runtime/memory-extra-ops.ts +186 -0
  200. package/src/runtime/orchestrate-ops.ts +272 -0
  201. package/src/runtime/planning-extra-ops.ts +327 -0
  202. package/src/runtime/project-ops.ts +196 -0
  203. package/src/runtime/runtime.ts +49 -1
  204. package/src/runtime/types.ts +21 -0
  205. package/src/runtime/vault-extra-ops.ts +225 -0
  206. package/src/telemetry/telemetry.ts +118 -0
  207. package/src/vault/vault.ts +412 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Generic core operations factory — 37 ops that every agent gets.
2
+ * Generic core operations factory — 147 ops that every agent gets.
3
3
  *
4
4
  * These ops are agent-agnostic (no persona, no activation).
5
5
  * The 5 agent-specific ops (health, identity, activate, inject_claude_md, setup)
@@ -10,15 +10,46 @@ import { z } from 'zod';
10
10
  import type { OpDefinition } from '../facades/types.js';
11
11
  import type { IntelligenceEntry } from '../intelligence/types.js';
12
12
  import type { AgentRuntime } from './types.js';
13
+ import type { GuidelineCategory, OperationalMode } from '../control/types.js';
14
+ import type { PolicyType, PolicyPreset } from '../governance/types.js';
15
+ import type { CogneeSearchType } from '../cognee/types.js';
16
+ import { createPlanningExtraOps } from './planning-extra-ops.js';
17
+ import { createMemoryExtraOps } from './memory-extra-ops.js';
18
+ import { createVaultExtraOps } from './vault-extra-ops.js';
19
+ import { createAdminOps } from './admin-ops.js';
20
+ import { createAdminExtraOps } from './admin-extra-ops.js';
21
+ import { createLoopOps } from './loop-ops.js';
22
+ import { createOrchestrateOps } from './orchestrate-ops.js';
23
+ import { createGradingOps } from './grading-ops.js';
24
+ import { createCaptureOps } from './capture-ops.js';
25
+ import { createCuratorExtraOps } from './curator-extra-ops.js';
26
+ import { createProjectOps } from './project-ops.js';
27
+ import { createMemoryCrossProjectOps } from './memory-cross-project-ops.js';
13
28
 
14
29
  /**
15
- * Create the 37 generic core operations for an agent runtime.
30
+ * Create the 147 generic core operations for an agent runtime.
16
31
  *
17
32
  * Groups: search/vault (4), memory (4), export (1), planning (5),
18
- * brain (4), brain intelligence (11), curator (8).
33
+ * brain (7), brain intelligence (11), cognee (5),
34
+ * llm (2), curator (8), control (8), governance (5),
35
+ * planning-extra (9), memory-extra (8), vault-extra (12),
36
+ * admin (8), admin-extra (10), loop (7), orchestrate (5),
37
+ * grading (5), capture (4), curator-extra (4), project (12).
19
38
  */
20
39
  export function createCoreOps(runtime: AgentRuntime): OpDefinition[] {
21
- const { vault, brain, brainIntelligence, planner, curator, llmClient, keyPool } = runtime;
40
+ const {
41
+ vault,
42
+ brain,
43
+ brainIntelligence,
44
+ planner,
45
+ curator,
46
+ governance,
47
+ cognee,
48
+ identityManager,
49
+ intentRouter,
50
+ llmClient,
51
+ keyPool,
52
+ } = runtime;
22
53
 
23
54
  return [
24
55
  // ─── Search / Vault ──────────────────────────────────────────
@@ -87,9 +118,18 @@ export function createCoreOps(runtime: AgentRuntime): OpDefinition[] {
87
118
  const { resolve } = await import('node:path');
88
119
  const projectPath = resolve((params.projectPath as string) ?? '.');
89
120
  const project = vault.registerProject(projectPath, params.name as string | undefined);
121
+ // Also track in project registry for cross-project features
122
+ runtime.projectRegistry.register(projectPath, params.name as string | undefined);
90
123
  const stats = vault.stats();
91
124
  const isNew = project.sessionCount === 1;
92
125
 
126
+ // Expire stale proposals on session start (fire-and-forget)
127
+ const policy = governance.getPolicy(projectPath);
128
+ const expired = governance.expireStaleProposals(policy.autoCapture.autoExpireDays);
129
+
130
+ const proposalStats = governance.getProposalStats(projectPath);
131
+ const quotaStatus = governance.getQuotaStatus(projectPath);
132
+
93
133
  return {
94
134
  project,
95
135
  is_new: isNew,
@@ -97,6 +137,15 @@ export function createCoreOps(runtime: AgentRuntime): OpDefinition[] {
97
137
  ? 'Welcome! New project registered.'
98
138
  : 'Welcome back! Session #' + project.sessionCount + ' for ' + project.name + '.',
99
139
  vault: { entries: stats.totalEntries, domains: Object.keys(stats.byDomain) },
140
+ governance: {
141
+ pendingProposals: proposalStats.pending,
142
+ quotaPercent:
143
+ quotaStatus.maxTotal > 0
144
+ ? Math.round((quotaStatus.total / quotaStatus.maxTotal) * 100)
145
+ : 0,
146
+ isQuotaWarning: quotaStatus.isWarning,
147
+ expiredThisSession: expired,
148
+ },
100
149
  };
101
150
  },
102
151
  },
@@ -346,6 +395,52 @@ export function createCoreOps(runtime: AgentRuntime): OpDefinition[] {
346
395
  };
347
396
  },
348
397
  },
398
+ {
399
+ name: 'brain_feedback',
400
+ description:
401
+ 'Enhanced feedback with typed actions (accepted/dismissed/modified/failed), source tracking, confidence, duration, and reason.',
402
+ auth: 'write',
403
+ schema: z.object({
404
+ query: z.string().describe('The original search query'),
405
+ entryId: z.string().describe('The entry ID'),
406
+ action: z.enum(['accepted', 'dismissed', 'modified', 'failed']),
407
+ source: z
408
+ .enum(['search', 'recommendation', 'tool-execution', 'explicit'])
409
+ .optional()
410
+ .describe("Feedback source. Default 'search'."),
411
+ confidence: z.number().optional().describe('Confidence 0-1. Default 0.6.'),
412
+ duration: z.number().optional().describe('Duration in ms.'),
413
+ context: z.string().optional().describe("JSON context string. Default '{}'."),
414
+ reason: z.string().optional().describe('Human-readable reason.'),
415
+ }),
416
+ handler: async (params) => {
417
+ const entry = brain.recordFeedback({
418
+ query: params.query as string,
419
+ entryId: params.entryId as string,
420
+ action: params.action as 'accepted' | 'dismissed' | 'modified' | 'failed',
421
+ source: params.source as
422
+ | 'search'
423
+ | 'recommendation'
424
+ | 'tool-execution'
425
+ | 'explicit'
426
+ | undefined,
427
+ confidence: params.confidence as number | undefined,
428
+ duration: params.duration as number | undefined,
429
+ context: params.context as string | undefined,
430
+ reason: params.reason as string | undefined,
431
+ });
432
+ return entry;
433
+ },
434
+ },
435
+ {
436
+ name: 'brain_feedback_stats',
437
+ description:
438
+ 'Feedback statistics — counts by action and source, acceptance rate, average confidence.',
439
+ auth: 'read',
440
+ handler: async () => {
441
+ return brain.getFeedbackStats();
442
+ },
443
+ },
349
444
  {
350
445
  name: 'rebuild_vocabulary',
351
446
  description: 'Force rebuild the TF-IDF vocabulary from all vault entries.',
@@ -435,17 +530,24 @@ export function createCoreOps(runtime: AgentRuntime): OpDefinition[] {
435
530
  {
436
531
  name: 'brain_recommend',
437
532
  description:
438
- 'Get pattern recommendations for a task context. Matches domain and task terms against known strengths.',
533
+ 'Get pattern recommendations for a task context. Matches domain, task terms, and source-specific acceptance rates against known strengths.',
439
534
  auth: 'read',
440
535
  schema: z.object({
441
536
  domain: z.string().optional(),
442
537
  task: z.string().optional().describe('Task description for contextual matching.'),
538
+ source: z
539
+ .string()
540
+ .optional()
541
+ .describe(
542
+ 'Feedback source to boost by (search, recommendation, tool-execution, explicit).',
543
+ ),
443
544
  limit: z.number().optional(),
444
545
  }),
445
546
  handler: async (params) => {
446
547
  return brainIntelligence.recommend({
447
548
  domain: params.domain as string | undefined,
448
549
  task: params.task as string | undefined,
550
+ source: params.source as string | undefined,
449
551
  limit: (params.limit as number) ?? 5,
450
552
  });
451
553
  },
@@ -507,13 +609,15 @@ export function createCoreOps(runtime: AgentRuntime): OpDefinition[] {
507
609
  {
508
610
  name: 'brain_promote_proposals',
509
611
  description:
510
- 'Promote knowledge proposals to vault entries. Creates intelligence entries from auto-extracted patterns.',
612
+ 'Promote knowledge proposals to vault entries. Creates intelligence entries from auto-extracted patterns. Gated by governance policies.',
511
613
  auth: 'write',
512
614
  schema: z.object({
513
615
  proposalIds: z.array(z.string()).describe('IDs of proposals to promote.'),
616
+ projectPath: z.string().optional().default('.'),
514
617
  }),
515
618
  handler: async (params) => {
516
- return brainIntelligence.promoteProposals(params.proposalIds as string[]);
619
+ const pp = (params.projectPath as string | undefined) ?? '.';
620
+ return brainIntelligence.promoteProposals(params.proposalIds as string[], governance, pp);
517
621
  },
518
622
  },
519
623
  {
@@ -548,6 +652,153 @@ export function createCoreOps(runtime: AgentRuntime): OpDefinition[] {
548
652
  },
549
653
  },
550
654
 
655
+ {
656
+ name: 'brain_reset_extracted',
657
+ description:
658
+ 'Reset extraction status on brain sessions, allowing re-extraction. Filter by sessionId, since date, or all.',
659
+ auth: 'write',
660
+ schema: z.object({
661
+ sessionId: z.string().optional().describe('Reset a specific session.'),
662
+ since: z.string().optional().describe('Reset sessions extracted since this ISO date.'),
663
+ all: z.boolean().optional().describe('Reset all extracted sessions.'),
664
+ }),
665
+ handler: async (params) => {
666
+ return brainIntelligence.resetExtracted({
667
+ sessionId: params.sessionId as string | undefined,
668
+ since: params.since as string | undefined,
669
+ all: params.all as boolean | undefined,
670
+ });
671
+ },
672
+ },
673
+
674
+ // ─── Cognee ──────────────────────────────────────────────────
675
+ {
676
+ name: 'cognee_status',
677
+ description:
678
+ 'Cognee vector search health — availability, URL, latency. Checks the Cognee API endpoint.',
679
+ auth: 'read',
680
+ handler: async () => {
681
+ return cognee.healthCheck();
682
+ },
683
+ },
684
+ {
685
+ name: 'cognee_search',
686
+ description:
687
+ 'Vector similarity search via Cognee. Complements TF-IDF vault search with semantic understanding.',
688
+ auth: 'read',
689
+ schema: z.object({
690
+ query: z.string(),
691
+ searchType: z
692
+ .enum([
693
+ 'SUMMARIES',
694
+ 'CHUNKS',
695
+ 'RAG_COMPLETION',
696
+ 'TRIPLET_COMPLETION',
697
+ 'GRAPH_COMPLETION',
698
+ 'GRAPH_SUMMARY_COMPLETION',
699
+ 'NATURAL_LANGUAGE',
700
+ 'GRAPH_COMPLETION_COT',
701
+ 'FEELING_LUCKY',
702
+ 'CHUNKS_LEXICAL',
703
+ ])
704
+ .optional()
705
+ .describe('Cognee search type. Default CHUNKS (pure vector similarity).'),
706
+ limit: z.number().optional(),
707
+ }),
708
+ handler: async (params) => {
709
+ return cognee.search(params.query as string, {
710
+ searchType: params.searchType as CogneeSearchType | undefined,
711
+ limit: (params.limit as number) ?? 10,
712
+ });
713
+ },
714
+ },
715
+ {
716
+ name: 'cognee_add',
717
+ description:
718
+ 'Ingest vault entries into Cognee for vector indexing. Auto-schedules cognify after ingest.',
719
+ auth: 'write',
720
+ schema: z.object({
721
+ entryIds: z.array(z.string()).describe('Vault entry IDs to ingest into Cognee.'),
722
+ }),
723
+ handler: async (params) => {
724
+ const ids = params.entryIds as string[];
725
+ const entries = ids
726
+ .map((id) => vault.get(id))
727
+ .filter((e): e is IntelligenceEntry => e !== null && e !== undefined);
728
+ if (entries.length === 0) return { added: 0, error: 'No matching vault entries found' };
729
+ return cognee.addEntries(entries);
730
+ },
731
+ },
732
+ {
733
+ name: 'cognee_cognify',
734
+ description:
735
+ 'Trigger Cognee knowledge graph processing on the vault dataset. Usually auto-scheduled after add.',
736
+ auth: 'write',
737
+ handler: async () => {
738
+ return cognee.cognify();
739
+ },
740
+ },
741
+ {
742
+ name: 'cognee_config',
743
+ description: 'Get current Cognee client configuration and cached health status.',
744
+ auth: 'read',
745
+ handler: async () => {
746
+ return { config: cognee.getConfig(), cachedStatus: cognee.getStatus() };
747
+ },
748
+ },
749
+
750
+ // ─── LLM ─────────────────────────────────────────────────────
751
+ {
752
+ name: 'llm_rotate',
753
+ description:
754
+ 'Force rotate the active API key for a provider. Useful when rate-limited or key is failing.',
755
+ auth: 'write',
756
+ schema: z.object({
757
+ provider: z.enum(['openai', 'anthropic']),
758
+ }),
759
+ handler: async (params) => {
760
+ const provider = params.provider as 'openai' | 'anthropic';
761
+ const pool = keyPool[provider];
762
+ if (!pool.hasKeys) return { rotated: false, error: `No ${provider} keys configured` };
763
+ const newKey = pool.rotateOnError();
764
+ return {
765
+ rotated: newKey !== null,
766
+ activeKeyIndex: pool.activeKeyIndex,
767
+ poolSize: pool.poolSize,
768
+ exhausted: pool.exhausted,
769
+ };
770
+ },
771
+ },
772
+ {
773
+ name: 'llm_call',
774
+ description: 'Make an LLM completion call. Uses model routing config and key pool rotation.',
775
+ auth: 'write',
776
+ schema: z.object({
777
+ systemPrompt: z.string().describe('System prompt for the LLM.'),
778
+ userPrompt: z.string().describe('User prompt / task input.'),
779
+ model: z
780
+ .string()
781
+ .optional()
782
+ .describe('Model name. Routed via model-routing.json if omitted.'),
783
+ temperature: z.number().optional().describe('Sampling temperature (0-2). Default 0.3.'),
784
+ maxTokens: z.number().optional().describe('Max output tokens. Default 500.'),
785
+ caller: z.string().optional().describe('Caller name for routing. Default "core-ops".'),
786
+ task: z.string().optional().describe('Task name for routing.'),
787
+ }),
788
+ handler: async (params) => {
789
+ return llmClient.complete({
790
+ provider: 'openai',
791
+ model: (params.model as string) ?? '',
792
+ systemPrompt: params.systemPrompt as string,
793
+ userPrompt: params.userPrompt as string,
794
+ temperature: params.temperature as number | undefined,
795
+ maxTokens: params.maxTokens as number | undefined,
796
+ caller: (params.caller as string) ?? 'core-ops',
797
+ task: params.task as string | undefined,
798
+ });
799
+ },
800
+ },
801
+
551
802
  // ─── Curator ─────────────────────────────────────────────────
552
803
  {
553
804
  name: 'curator_status',
@@ -661,5 +912,282 @@ export function createCoreOps(runtime: AgentRuntime): OpDefinition[] {
661
912
  return curator.healthAudit();
662
913
  },
663
914
  },
915
+
916
+ // ─── Control ──────────────────────────────────────────────────────
917
+ {
918
+ name: 'get_identity',
919
+ description: 'Get current agent identity with guidelines.',
920
+ auth: 'read',
921
+ schema: z.object({
922
+ agentId: z.string().describe('Agent identifier.'),
923
+ }),
924
+ handler: async (params) => {
925
+ const identity = identityManager.getIdentity(params.agentId as string);
926
+ if (!identity) return { found: false, agentId: params.agentId };
927
+ return identity;
928
+ },
929
+ },
930
+ {
931
+ name: 'update_identity',
932
+ description: 'Update identity fields. Auto-versions and snapshots previous state.',
933
+ auth: 'write',
934
+ schema: z.object({
935
+ agentId: z.string(),
936
+ name: z.string().optional(),
937
+ role: z.string().optional(),
938
+ description: z.string().optional(),
939
+ personality: z.array(z.string()).optional(),
940
+ changedBy: z.string().optional(),
941
+ changeReason: z.string().optional(),
942
+ }),
943
+ handler: async (params) => {
944
+ const identity = identityManager.setIdentity(params.agentId as string, {
945
+ name: params.name as string | undefined,
946
+ role: params.role as string | undefined,
947
+ description: params.description as string | undefined,
948
+ personality: params.personality as string[] | undefined,
949
+ changedBy: params.changedBy as string | undefined,
950
+ changeReason: params.changeReason as string | undefined,
951
+ });
952
+ return { updated: true, identity };
953
+ },
954
+ },
955
+ {
956
+ name: 'add_guideline',
957
+ description: 'Add a behavioral guideline (behavior/preference/restriction/style).',
958
+ auth: 'write',
959
+ schema: z.object({
960
+ agentId: z.string(),
961
+ category: z.enum(['behavior', 'preference', 'restriction', 'style']),
962
+ text: z.string(),
963
+ priority: z.number().optional(),
964
+ }),
965
+ handler: async (params) => {
966
+ const guideline = identityManager.addGuideline(params.agentId as string, {
967
+ category: params.category as GuidelineCategory,
968
+ text: params.text as string,
969
+ priority: params.priority as number | undefined,
970
+ });
971
+ return { added: true, guideline };
972
+ },
973
+ },
974
+ {
975
+ name: 'remove_guideline',
976
+ description: 'Remove a guideline by ID.',
977
+ auth: 'write',
978
+ schema: z.object({
979
+ guidelineId: z.string(),
980
+ }),
981
+ handler: async (params) => {
982
+ const removed = identityManager.removeGuideline(params.guidelineId as string);
983
+ return { removed };
984
+ },
985
+ },
986
+ {
987
+ name: 'rollback_identity',
988
+ description: 'Restore a previous identity version. Creates a new version with the old data.',
989
+ auth: 'write',
990
+ schema: z.object({
991
+ agentId: z.string(),
992
+ version: z.number().describe('Version number to roll back to.'),
993
+ }),
994
+ handler: async (params) => {
995
+ const identity = identityManager.rollback(
996
+ params.agentId as string,
997
+ params.version as number,
998
+ );
999
+ return { rolledBack: true, identity };
1000
+ },
1001
+ },
1002
+ {
1003
+ name: 'route_intent',
1004
+ description: 'Classify a prompt into intent + operational mode via keyword matching.',
1005
+ auth: 'read',
1006
+ schema: z.object({
1007
+ prompt: z.string().describe('The user prompt to classify.'),
1008
+ }),
1009
+ handler: async (params) => {
1010
+ return intentRouter.routeIntent(params.prompt as string);
1011
+ },
1012
+ },
1013
+ {
1014
+ name: 'morph',
1015
+ description: 'Switch operational mode manually.',
1016
+ auth: 'write',
1017
+ schema: z.object({
1018
+ mode: z
1019
+ .string()
1020
+ .describe('The operational mode to switch to (e.g., BUILD-MODE, FIX-MODE).'),
1021
+ }),
1022
+ handler: async (params) => {
1023
+ return intentRouter.morph(params.mode as OperationalMode);
1024
+ },
1025
+ },
1026
+ {
1027
+ name: 'get_behavior_rules',
1028
+ description: 'Get behavior rules for current or specified mode.',
1029
+ auth: 'read',
1030
+ schema: z.object({
1031
+ mode: z.string().optional().describe('Mode to get rules for. Defaults to current mode.'),
1032
+ }),
1033
+ handler: async (params) => {
1034
+ const mode = params.mode as OperationalMode | undefined;
1035
+ const rules = intentRouter.getBehaviorRules(mode);
1036
+ const currentMode = intentRouter.getCurrentMode();
1037
+ return { mode: mode ?? currentMode, rules };
1038
+ },
1039
+ },
1040
+
1041
+ // ─── Governance ─────────────────────────────────────────────────
1042
+ {
1043
+ name: 'governance_policy',
1044
+ description:
1045
+ 'Get, set, or apply a preset to vault governance policies (quota, retention, auto-capture).',
1046
+ auth: 'write',
1047
+ schema: z.object({
1048
+ action: z.enum(['get', 'set', 'applyPreset']),
1049
+ projectPath: z.string(),
1050
+ policyType: z.enum(['quota', 'retention', 'auto-capture']).optional(),
1051
+ config: z.record(z.unknown()).optional(),
1052
+ preset: z.enum(['strict', 'moderate', 'permissive']).optional(),
1053
+ changedBy: z.string().optional(),
1054
+ }),
1055
+ handler: async (params) => {
1056
+ const action = params.action as string;
1057
+ const projectPath = params.projectPath as string;
1058
+ if (action === 'get') {
1059
+ return governance.getPolicy(projectPath);
1060
+ }
1061
+ if (action === 'set') {
1062
+ governance.setPolicy(
1063
+ projectPath,
1064
+ params.policyType as PolicyType,
1065
+ params.config as Record<string, unknown>,
1066
+ params.changedBy as string | undefined,
1067
+ );
1068
+ return { updated: true, policy: governance.getPolicy(projectPath) };
1069
+ }
1070
+ if (action === 'applyPreset') {
1071
+ governance.applyPreset(
1072
+ projectPath,
1073
+ params.preset as PolicyPreset,
1074
+ params.changedBy as string | undefined,
1075
+ );
1076
+ return {
1077
+ applied: true,
1078
+ preset: params.preset,
1079
+ policy: governance.getPolicy(projectPath),
1080
+ };
1081
+ }
1082
+ return { error: 'Unknown action: ' + action };
1083
+ },
1084
+ },
1085
+ {
1086
+ name: 'governance_proposals',
1087
+ description:
1088
+ 'Manage knowledge capture proposals — list, approve, reject, modify, get stats, or expire stale.',
1089
+ auth: 'write',
1090
+ schema: z.object({
1091
+ action: z.enum(['list', 'approve', 'reject', 'modify', 'stats', 'expire']),
1092
+ projectPath: z.string().optional(),
1093
+ proposalId: z.number().optional(),
1094
+ decidedBy: z.string().optional(),
1095
+ note: z.string().optional(),
1096
+ modifications: z.record(z.unknown()).optional(),
1097
+ maxAgeDays: z.number().optional(),
1098
+ limit: z.number().optional(),
1099
+ }),
1100
+ handler: async (params) => {
1101
+ const action = params.action as string;
1102
+ if (action === 'list') {
1103
+ return governance.listPendingProposals(
1104
+ params.projectPath as string | undefined,
1105
+ params.limit as number | undefined,
1106
+ );
1107
+ }
1108
+ if (action === 'approve') {
1109
+ return governance.approveProposal(
1110
+ params.proposalId as number,
1111
+ params.decidedBy as string | undefined,
1112
+ );
1113
+ }
1114
+ if (action === 'reject') {
1115
+ return governance.rejectProposal(
1116
+ params.proposalId as number,
1117
+ params.decidedBy as string | undefined,
1118
+ params.note as string | undefined,
1119
+ );
1120
+ }
1121
+ if (action === 'modify') {
1122
+ return governance.modifyProposal(
1123
+ params.proposalId as number,
1124
+ params.modifications as Record<string, unknown>,
1125
+ params.decidedBy as string | undefined,
1126
+ );
1127
+ }
1128
+ if (action === 'stats') {
1129
+ return governance.getProposalStats(params.projectPath as string | undefined);
1130
+ }
1131
+ if (action === 'expire') {
1132
+ const expired = governance.expireStaleProposals(params.maxAgeDays as number | undefined);
1133
+ return { expired };
1134
+ }
1135
+ return { error: 'Unknown action: ' + action };
1136
+ },
1137
+ },
1138
+ {
1139
+ name: 'governance_stats',
1140
+ description: 'Get governance statistics — quota status and proposal stats for a project.',
1141
+ auth: 'read',
1142
+ schema: z.object({
1143
+ projectPath: z.string(),
1144
+ }),
1145
+ handler: async (params) => {
1146
+ const projectPath = params.projectPath as string;
1147
+ return {
1148
+ quotaStatus: governance.getQuotaStatus(projectPath),
1149
+ proposalStats: governance.getProposalStats(projectPath),
1150
+ };
1151
+ },
1152
+ },
1153
+ {
1154
+ name: 'governance_expire',
1155
+ description: 'Expire stale pending proposals older than a threshold.',
1156
+ auth: 'write',
1157
+ schema: z.object({
1158
+ projectPath: z.string().optional(),
1159
+ maxAgeDays: z.number().optional().describe('Days threshold. Default 14.'),
1160
+ }),
1161
+ handler: async (params) => {
1162
+ const expired = governance.expireStaleProposals(params.maxAgeDays as number | undefined);
1163
+ return { expired };
1164
+ },
1165
+ },
1166
+ {
1167
+ name: 'governance_dashboard',
1168
+ description:
1169
+ 'Get governance dashboard — vault size, quota usage, pending proposals, acceptance rate, evaluation trend.',
1170
+ auth: 'read',
1171
+ schema: z.object({
1172
+ projectPath: z.string(),
1173
+ }),
1174
+ handler: async (params) => {
1175
+ return governance.getDashboard(params.projectPath as string);
1176
+ },
1177
+ },
1178
+
1179
+ // ─── Extra Ops (from dedicated modules) ─────────────────────────
1180
+ ...createPlanningExtraOps(runtime),
1181
+ ...createMemoryExtraOps(runtime),
1182
+ ...createVaultExtraOps(runtime),
1183
+ ...createAdminOps(runtime),
1184
+ ...createAdminExtraOps(runtime),
1185
+ ...createLoopOps(runtime),
1186
+ ...createOrchestrateOps(runtime),
1187
+ ...createGradingOps(runtime),
1188
+ ...createCaptureOps(runtime),
1189
+ ...createCuratorExtraOps(runtime),
1190
+ ...createProjectOps(runtime),
1191
+ ...createMemoryCrossProjectOps(runtime),
664
1192
  ];
665
1193
  }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Extra curator operations — 4 ops that extend the 8 base curator ops in core-ops.ts.
3
+ *
4
+ * Groups: entry history (2), queue stats (1), metadata enrichment (1).
5
+ */
6
+
7
+ import { z } from 'zod';
8
+ import type { OpDefinition } from '../facades/types.js';
9
+ import type { AgentRuntime } from './types.js';
10
+
11
+ export function createCuratorExtraOps(runtime: AgentRuntime): OpDefinition[] {
12
+ const { curator } = runtime;
13
+
14
+ return [
15
+ // ─── Entry History ──────────────────────────────────────────────
16
+ {
17
+ name: 'curator_entry_history',
18
+ description: 'Get version history (snapshots) for a vault entry.',
19
+ auth: 'read',
20
+ schema: z.object({
21
+ entryId: z.string().describe('Entry ID to get history for.'),
22
+ }),
23
+ handler: async (params) => {
24
+ const history = curator.getVersionHistory(params.entryId as string);
25
+ return { entryId: params.entryId, history, count: history.length };
26
+ },
27
+ },
28
+ {
29
+ name: 'curator_record_snapshot',
30
+ description: 'Manually record a snapshot of an entry\'s current state.',
31
+ auth: 'write',
32
+ schema: z.object({
33
+ entryId: z.string().describe('Entry ID to snapshot.'),
34
+ changedBy: z.string().optional().describe('Who made the change. Default "system".'),
35
+ changeReason: z.string().optional().describe('Why the snapshot was recorded.'),
36
+ }),
37
+ handler: async (params) => {
38
+ return curator.recordSnapshot(
39
+ params.entryId as string,
40
+ params.changedBy as string | undefined,
41
+ params.changeReason as string | undefined,
42
+ );
43
+ },
44
+ },
45
+
46
+ // ─── Queue Stats ────────────────────────────────────────────────
47
+ {
48
+ name: 'curator_queue_stats',
49
+ description:
50
+ 'Grooming queue statistics — total, groomed, ungroomed, stale (30+ days), fresh (7 days), average days since groom.',
51
+ auth: 'read',
52
+ handler: async () => {
53
+ return curator.getQueueStats();
54
+ },
55
+ },
56
+
57
+ // ─── Metadata Enrichment ────────────────────────────────────────
58
+ {
59
+ name: 'curator_enrich',
60
+ description:
61
+ 'Rule-based metadata enrichment — auto-capitalize title, normalize tags, infer severity/type from keywords, trim description.',
62
+ auth: 'write',
63
+ schema: z.object({
64
+ entryId: z.string().describe('Entry ID to enrich.'),
65
+ }),
66
+ handler: async (params) => {
67
+ return curator.enrichMetadata(params.entryId as string);
68
+ },
69
+ },
70
+ ];
71
+ }