@soleri/core 8.1.0 → 9.0.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 (128) hide show
  1. package/dist/brain/brain.d.ts +1 -8
  2. package/dist/brain/brain.d.ts.map +1 -1
  3. package/dist/brain/brain.js +5 -134
  4. package/dist/brain/brain.js.map +1 -1
  5. package/dist/cognee/client.d.ts +5 -0
  6. package/dist/cognee/client.d.ts.map +1 -1
  7. package/dist/cognee/client.js +83 -16
  8. package/dist/cognee/client.js.map +1 -1
  9. package/dist/cognee/sync-manager.d.ts +67 -8
  10. package/dist/cognee/sync-manager.d.ts.map +1 -1
  11. package/dist/cognee/sync-manager.js +129 -32
  12. package/dist/cognee/sync-manager.js.map +1 -1
  13. package/dist/cognee/types.d.ts +16 -0
  14. package/dist/cognee/types.d.ts.map +1 -1
  15. package/dist/context/context-engine.d.ts +2 -5
  16. package/dist/context/context-engine.d.ts.map +1 -1
  17. package/dist/context/context-engine.js +4 -31
  18. package/dist/context/context-engine.js.map +1 -1
  19. package/dist/curator/curator.d.ts +2 -5
  20. package/dist/curator/curator.d.ts.map +1 -1
  21. package/dist/curator/curator.js +4 -23
  22. package/dist/curator/curator.js.map +1 -1
  23. package/dist/engine/bin/soleri-engine.js +6 -5
  24. package/dist/engine/bin/soleri-engine.js.map +1 -1
  25. package/dist/engine/core-ops.d.ts.map +1 -1
  26. package/dist/engine/core-ops.js +11 -6
  27. package/dist/engine/core-ops.js.map +1 -1
  28. package/dist/engine/register-engine.d.ts.map +1 -1
  29. package/dist/engine/register-engine.js +0 -7
  30. package/dist/engine/register-engine.js.map +1 -1
  31. package/dist/index.d.ts +5 -5
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -4
  34. package/dist/index.js.map +1 -1
  35. package/dist/intelligence/types.d.ts +7 -0
  36. package/dist/intelligence/types.d.ts.map +1 -1
  37. package/dist/persona/defaults.d.ts +16 -0
  38. package/dist/persona/defaults.d.ts.map +1 -0
  39. package/dist/persona/defaults.js +78 -0
  40. package/dist/persona/defaults.js.map +1 -0
  41. package/dist/persona/index.d.ts +5 -0
  42. package/dist/persona/index.d.ts.map +1 -0
  43. package/dist/persona/index.js +4 -0
  44. package/dist/persona/index.js.map +1 -0
  45. package/dist/persona/loader.d.ts +11 -0
  46. package/dist/persona/loader.d.ts.map +1 -0
  47. package/dist/persona/loader.js +45 -0
  48. package/dist/persona/loader.js.map +1 -0
  49. package/dist/persona/prompt-generator.d.ts +13 -0
  50. package/dist/persona/prompt-generator.d.ts.map +1 -0
  51. package/dist/persona/prompt-generator.js +89 -0
  52. package/dist/persona/prompt-generator.js.map +1 -0
  53. package/dist/persona/types.d.ts +56 -0
  54. package/dist/persona/types.d.ts.map +1 -0
  55. package/dist/persona/types.js +9 -0
  56. package/dist/persona/types.js.map +1 -0
  57. package/dist/plugins/types.d.ts +13 -13
  58. package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
  59. package/dist/runtime/admin-extra-ops.js +5 -27
  60. package/dist/runtime/admin-extra-ops.js.map +1 -1
  61. package/dist/runtime/admin-ops.d.ts.map +1 -1
  62. package/dist/runtime/admin-ops.js +5 -37
  63. package/dist/runtime/admin-ops.js.map +1 -1
  64. package/dist/runtime/capture-ops.d.ts.map +1 -1
  65. package/dist/runtime/capture-ops.js +32 -16
  66. package/dist/runtime/capture-ops.js.map +1 -1
  67. package/dist/runtime/cognee-sync-ops.d.ts +2 -2
  68. package/dist/runtime/cognee-sync-ops.d.ts.map +1 -1
  69. package/dist/runtime/cognee-sync-ops.js +45 -7
  70. package/dist/runtime/cognee-sync-ops.js.map +1 -1
  71. package/dist/runtime/facades/index.d.ts +1 -1
  72. package/dist/runtime/facades/index.d.ts.map +1 -1
  73. package/dist/runtime/facades/index.js +1 -10
  74. package/dist/runtime/facades/index.js.map +1 -1
  75. package/dist/runtime/runtime.d.ts.map +1 -1
  76. package/dist/runtime/runtime.js +14 -53
  77. package/dist/runtime/runtime.js.map +1 -1
  78. package/dist/runtime/types.d.ts +6 -8
  79. package/dist/runtime/types.d.ts.map +1 -1
  80. package/dist/runtime/vault-linking-ops.d.ts.map +1 -1
  81. package/dist/runtime/vault-linking-ops.js +40 -0
  82. package/dist/runtime/vault-linking-ops.js.map +1 -1
  83. package/dist/runtime/vault-sharing-ops.d.ts.map +1 -1
  84. package/dist/runtime/vault-sharing-ops.js +53 -3
  85. package/dist/runtime/vault-sharing-ops.js.map +1 -1
  86. package/dist/vault/linking.d.ts +37 -0
  87. package/dist/vault/linking.d.ts.map +1 -1
  88. package/dist/vault/linking.js +73 -0
  89. package/dist/vault/linking.js.map +1 -1
  90. package/dist/vault/vault.d.ts +0 -2
  91. package/dist/vault/vault.d.ts.map +1 -1
  92. package/dist/vault/vault.js +0 -13
  93. package/dist/vault/vault.js.map +1 -1
  94. package/package.json +1 -1
  95. package/src/brain/brain.ts +4 -157
  96. package/src/context/context-engine.ts +3 -31
  97. package/src/curator/curator.ts +5 -28
  98. package/src/engine/bin/soleri-engine.ts +6 -5
  99. package/src/engine/core-ops.ts +11 -6
  100. package/src/engine/register-engine.ts +0 -7
  101. package/src/index.ts +20 -16
  102. package/src/intelligence/types.ts +8 -0
  103. package/src/persona/defaults.ts +96 -0
  104. package/src/persona/index.ts +9 -0
  105. package/src/persona/loader.ts +50 -0
  106. package/src/persona/prompt-generator.ts +109 -0
  107. package/src/persona/types.ts +72 -0
  108. package/src/runtime/admin-extra-ops.ts +5 -28
  109. package/src/runtime/admin-ops.ts +5 -38
  110. package/src/runtime/capture-ops.ts +33 -14
  111. package/src/runtime/facades/index.ts +1 -11
  112. package/src/runtime/runtime.ts +14 -54
  113. package/src/runtime/types.ts +6 -8
  114. package/src/runtime/vault-linking-ops.ts +41 -0
  115. package/src/runtime/vault-sharing-ops.ts +63 -4
  116. package/src/vault/linking.ts +94 -0
  117. package/src/vault/vault.ts +0 -14
  118. package/src/__tests__/cognee-client-gaps.test.ts +0 -474
  119. package/src/__tests__/cognee-client.test.ts +0 -524
  120. package/src/__tests__/cognee-hybrid-search.test.ts +0 -492
  121. package/src/__tests__/cognee-integration.test.ts +0 -80
  122. package/src/__tests__/cognee-sync-manager-deep.test.ts +0 -654
  123. package/src/__tests__/cognee-sync-manager.test.ts +0 -104
  124. package/src/cognee/client.ts +0 -370
  125. package/src/cognee/sync-manager.ts +0 -389
  126. package/src/cognee/types.ts +0 -62
  127. package/src/runtime/cognee-sync-ops.ts +0 -63
  128. package/src/runtime/facades/cognee-facade.ts +0 -164
@@ -36,7 +36,7 @@ interface PluginInfo {
36
36
  * Create 24 extended admin operations for production observability.
37
37
  */
38
38
  export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
39
- const { vault, brain, cognee, telemetry } = runtime;
39
+ const { vault, brain, telemetry } = runtime;
40
40
 
41
41
  // In-memory permission level — default 'moderate'
42
42
  let permissionLevel: PermissionLevel = 'moderate';
@@ -240,7 +240,6 @@ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
240
240
  description: 'Status of all runtime modules — check each is initialized.',
241
241
  auth: 'read',
242
242
  handler: async () => {
243
- const cogneeStatus = cognee?.getStatus() ?? null;
244
243
  const llmAvailable = runtime.llmClient.isAvailable();
245
244
  const loopStatus = runtime.loop.getStatus();
246
245
 
@@ -250,7 +249,6 @@ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
250
249
  planner: true,
251
250
  curator: runtime.curator.getStatus().initialized,
252
251
  governance: true,
253
- cognee: { available: cogneeStatus?.available ?? false },
254
252
  loop: { active: loopStatus !== null },
255
253
  llm: {
256
254
  openai: llmAvailable.openai,
@@ -280,7 +278,7 @@ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
280
278
  // ─── Garbage Collection ─────────────────────────────────────────
281
279
  {
282
280
  name: 'admin_gc',
283
- description: 'Trigger garbage collection on in-memory caches — brain, cognee, telemetry.',
281
+ description: 'Trigger garbage collection on in-memory caches — brain, telemetry.',
284
282
  auth: 'write',
285
283
  handler: async () => {
286
284
  const cleared: string[] = [];
@@ -292,15 +290,6 @@ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
292
290
  // Brain rebuild failed — graceful degradation
293
291
  }
294
292
 
295
- if (cognee) {
296
- try {
297
- cognee.resetPendingCognify();
298
- cleared.push('cognee');
299
- } catch {
300
- // Cognee reset failed — graceful degradation
301
- }
302
- }
303
-
304
293
  try {
305
294
  telemetry.reset();
306
295
  cleared.push('telemetry');
@@ -331,7 +320,6 @@ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
331
320
  'planner',
332
321
  'curator',
333
322
  'governance',
334
- 'cognee',
335
323
  'loop',
336
324
  'identityManager',
337
325
  'intentRouter',
@@ -677,7 +665,7 @@ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
677
665
  description: 'Get health status of a specific subsystem.',
678
666
  auth: 'read',
679
667
  schema: z.object({
680
- subsystem: z.string().describe('Subsystem name (e.g. "vault", "cognee", "llm")'),
668
+ subsystem: z.string().describe('Subsystem name (e.g. "vault", "brain", "llm")'),
681
669
  }),
682
670
  handler: async (params) => {
683
671
  const sub = runtime.health.get(params.subsystem as string);
@@ -707,7 +695,7 @@ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
707
695
  description: 'Get the current value of a specific feature flag.',
708
696
  auth: 'read',
709
697
  schema: z.object({
710
- flag: z.string().describe('Flag name (e.g. "auth-enforcement", "cognee-sync")'),
698
+ flag: z.string().describe('Flag name (e.g. "auth-enforcement", "vault-sync")'),
711
699
  }),
712
700
  handler: async (params) => {
713
701
  const flag = params.flag as string;
@@ -772,7 +760,7 @@ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
772
760
  {
773
761
  name: 'admin_setup_check',
774
762
  description:
775
- 'Check agent setup status — vault health, brain vocabulary, cognee connection, LLM keys, templates.',
763
+ 'Check agent setup status — vault health, brain vocabulary, LLM keys, templates.',
776
764
  auth: 'read',
777
765
  handler: async () => {
778
766
  const checks: Record<string, { ok: boolean; detail: string }> = {};
@@ -799,17 +787,6 @@ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
799
787
  checks.brain = { ok: false, detail: 'Brain not initialized' };
800
788
  }
801
789
 
802
- // Cognee
803
- const cogneeStatus = cognee?.getStatus() ?? null;
804
- checks.cognee = {
805
- ok: cogneeStatus?.available ?? false,
806
- detail: cognee
807
- ? cogneeStatus?.available
808
- ? 'Connected'
809
- : 'Not available (optional)'
810
- : 'Disabled',
811
- };
812
-
813
790
  // LLM keys
814
791
  const llmAvail = runtime.llmClient.isAvailable();
815
792
  checks.llm = {
@@ -41,17 +41,16 @@ function getCoreVersion(): string {
41
41
  * Groups: health (1), introspection (4), diagnostics (2), mutation (1).
42
42
  */
43
43
  export function createAdminOps(runtime: AgentRuntime): OpDefinition[] {
44
- const { vault, brain, brainIntelligence, cognee, llmClient, curator } = runtime;
44
+ const { vault, brain, brainIntelligence, llmClient, curator } = runtime;
45
45
 
46
46
  return [
47
47
  // ─── Health ──────────────────────────────────────────────────────
48
48
  {
49
49
  name: 'admin_health',
50
- description: 'Comprehensive agent health check — vault, cognee, LLM, brain status.',
50
+ description: 'Comprehensive agent health check — vault, LLM, brain status.',
51
51
  auth: 'read',
52
52
  handler: async () => {
53
53
  const vaultStats = vault.stats();
54
- const cogneeStatus = cognee?.getStatus() ?? null;
55
54
  const llmAvailable = llmClient.isAvailable();
56
55
  const brainStats = brain.getStats();
57
56
  const curatorStatus = curator.getStatus();
@@ -59,7 +58,6 @@ export function createAdminOps(runtime: AgentRuntime): OpDefinition[] {
59
58
  return {
60
59
  status: 'ok',
61
60
  vault: { entries: vaultStats.totalEntries, domains: Object.keys(vaultStats.byDomain) },
62
- cognee: { available: cogneeStatus?.available ?? false },
63
61
  llm: llmAvailable,
64
62
  brain: {
65
63
  vocabularySize: brainStats.vocabularySize,
@@ -174,21 +172,14 @@ export function createAdminOps(runtime: AgentRuntime): OpDefinition[] {
174
172
  // ─── Mutation ────────────────────────────────────────────────────
175
173
  {
176
174
  name: 'admin_reset_cache',
177
- description:
178
- 'Clear all caches — brain vocabulary and cognee health cache. Forces fresh data on next access.',
175
+ description: 'Clear all caches — brain vocabulary. Forces fresh data on next access.',
179
176
  auth: 'write',
180
177
  handler: async () => {
181
- // Rebuild brain vocabulary (clears old TF-IDF state, rebuilds from vault)
182
178
  brain.rebuildVocabulary();
183
179
 
184
- // Reset cognee health cache by checking health again (no direct reset method)
185
- // The next isAvailable check will need a fresh health probe
186
- const cogneeHealth = cognee ? await cognee.healthCheck().catch(() => null) : null;
187
-
188
180
  return {
189
- cleared: ['brain_vocabulary', ...(cognee ? ['cognee_health_cache'] : [])],
181
+ cleared: ['brain_vocabulary'],
190
182
  brainVocabularySize: brain.getStats().vocabularySize,
191
- cogneeAvailable: cogneeHealth?.available ?? false,
192
183
  };
193
184
  },
194
185
  },
@@ -250,31 +241,7 @@ export function createAdminOps(runtime: AgentRuntime): OpDefinition[] {
250
241
  });
251
242
  }
252
243
 
253
- // 4. Cognee availability
254
- try {
255
- const cogneeStatus = cognee?.getStatus() ?? null;
256
- if (cogneeStatus?.available) {
257
- checks.push({
258
- name: 'cognee',
259
- status: 'ok',
260
- detail: `Connected to ${cogneeStatus.url}`,
261
- });
262
- } else {
263
- checks.push({
264
- name: 'cognee',
265
- status: 'warn',
266
- detail: cogneeStatus?.error ?? 'Not connected (no health check yet)',
267
- });
268
- }
269
- } catch (err) {
270
- checks.push({
271
- name: 'cognee',
272
- status: 'error',
273
- detail: err instanceof Error ? err.message : String(err),
274
- });
275
- }
276
-
277
- // 5. LLM key pools
244
+ // 4. LLM key pools
278
245
  const llmStatus = llmClient.isAvailable();
279
246
  checks.push({
280
247
  name: 'llm_openai',
@@ -228,34 +228,52 @@ export function createCaptureOps(runtime: AgentRuntime): OpDefinition[] {
228
228
  }
229
229
  }
230
230
 
231
- // Auto-suggest links for captured entries (Zettelkasten enrichment)
232
- let suggestedLinks: Array<{
231
+ // Auto-link captured entries (Zettelkasten enrichment)
232
+ // Creates links for suggestions above threshold; returns remaining as suggestions
233
+ const AUTO_LINK_THRESHOLD = 0.7;
234
+ const AUTO_LINK_MAX = 3;
235
+ let autoLinkedCount = 0;
236
+ const suggestedLinks: Array<{
233
237
  entryId: string;
234
238
  title: string;
235
239
  suggestedType: string;
236
240
  score: number;
241
+ autoLinked: boolean;
237
242
  }> = [];
238
243
  try {
239
244
  if (captured > 0) {
240
- const firstCaptured = results.find((r) => r.action === 'capture');
241
- if (firstCaptured) {
242
- const { LinkManager } = await import('../vault/linking.js');
243
- const lm = new LinkManager(vault.getProvider());
244
- const suggestions = lm.suggestLinks(firstCaptured.id, 3);
245
- suggestedLinks = suggestions
246
- .filter(
247
- (s) => s.entryId !== firstCaptured.id && !s.entryId.endsWith(firstCaptured.id),
248
- )
249
- .map((s) => ({
245
+ const { LinkManager } = await import('../vault/linking.js');
246
+ const lm = new LinkManager(vault.getProvider());
247
+
248
+ // Process ALL captured entries, not just the first
249
+ const capturedEntries = results.filter((r) => r.action === 'capture');
250
+ for (const capturedEntry of capturedEntries) {
251
+ const suggestions = lm.suggestLinks(capturedEntry.id, AUTO_LINK_MAX + 2);
252
+ const filtered = suggestions.filter(
253
+ (s) => s.entryId !== capturedEntry.id && !s.entryId.endsWith(capturedEntry.id),
254
+ );
255
+
256
+ let linkedForThisEntry = 0;
257
+ for (const s of filtered) {
258
+ const aboveThreshold = s.score >= AUTO_LINK_THRESHOLD;
259
+ const canAutoLink = aboveThreshold && linkedForThisEntry < AUTO_LINK_MAX;
260
+ if (canAutoLink) {
261
+ lm.addLink(capturedEntry.id, s.entryId, s.suggestedType);
262
+ linkedForThisEntry++;
263
+ autoLinkedCount++;
264
+ }
265
+ suggestedLinks.push({
250
266
  entryId: s.entryId,
251
267
  title: s.title,
252
268
  suggestedType: s.suggestedType,
253
269
  score: s.score,
254
- }));
270
+ autoLinked: canAutoLink,
271
+ });
272
+ }
255
273
  }
256
274
  }
257
275
  } catch {
258
- /* never break capture for suggestions */
276
+ /* never break capture for linking failures */
259
277
  }
260
278
 
261
279
  return {
@@ -263,6 +281,7 @@ export function createCaptureOps(runtime: AgentRuntime): OpDefinition[] {
263
281
  proposed,
264
282
  rejected,
265
283
  duplicated,
284
+ autoLinkedCount,
266
285
  results,
267
286
  ...(suggestedLinks.length > 0 ? { suggestedLinks } : {}),
268
287
  };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Semantic facade assembler — creates 10 domain-specific facades
2
+ * Semantic facade assembler — creates domain-specific facades
3
3
  * matching Salvador's engine-level architecture.
4
4
  *
5
5
  * Each facade becomes its own MCP tool with op dispatch.
@@ -16,7 +16,6 @@ import { createCuratorFacadeOps } from './curator-facade.js';
16
16
  import { createLoopFacadeOps } from './loop-facade.js';
17
17
  import { createOrchestrateFacadeOps } from './orchestrate-facade.js';
18
18
  import { createControlFacadeOps } from './control-facade.js';
19
- import { createCogneeFacadeOps } from './cognee-facade.js';
20
19
  import { createContextFacadeOps } from './context-facade.js';
21
20
  import { createAgencyFacadeOps } from './agency-facade.js';
22
21
  import { createChatFacadeOps } from './chat-facade.js';
@@ -88,14 +87,5 @@ export function createSemanticFacades(runtime: AgentRuntime, agentId: string): F
88
87
  },
89
88
  ];
90
89
 
91
- // Cognee facade — only registered when Cognee integration is enabled
92
- if (runtime.cognee) {
93
- facades.push({
94
- name: `${agentId}_cognee`,
95
- description: 'Knowledge graph — Cognee search, sync, export, graph stats.',
96
- ops: createCogneeFacadeOps(runtime),
97
- });
98
- }
99
-
100
90
  return facades;
101
91
  }
@@ -14,7 +14,6 @@ import { BrainIntelligence } from '../brain/intelligence.js';
14
14
  import { Planner } from '../planning/planner.js';
15
15
  import { Curator } from '../curator/curator.js';
16
16
  import { Governance } from '../governance/governance.js';
17
- import { CogneeClient } from '../cognee/client.js';
18
17
  import { LoopManager } from '../loop/loop-manager.js';
19
18
  import { IdentityManager } from '../control/identity-manager.js';
20
19
  import { IntentRouter } from '../control/intent-router.js';
@@ -22,7 +21,6 @@ import { KeyPool, loadKeyPoolConfig } from '../llm/key-pool.js';
22
21
  import { discoverAnthropicToken } from '../llm/oauth-discovery.js';
23
22
  import { loadIntelligenceData } from '../intelligence/loader.js';
24
23
  import { LLMClient } from '../llm/llm-client.js';
25
- import { CogneeSyncManager } from '../cognee/sync-manager.js';
26
24
  import { IntakePipeline } from '../intake/intake-pipeline.js';
27
25
  import { TextIngester } from '../intake/text-ingester.js';
28
26
  import { Telemetry } from '../telemetry/telemetry.js';
@@ -50,6 +48,8 @@ import { PipelineRunner } from '../queue/pipeline-runner.js';
50
48
  import { evaluateQuality } from '../curator/quality-gate.js';
51
49
  import { classifyEntry } from '../curator/classifier.js';
52
50
  import type { AgentRuntimeConfig, AgentRuntime } from './types.js';
51
+ import { loadPersona } from '../persona/loader.js';
52
+ import { generatePersonaInstructions } from '../persona/prompt-generator.js';
53
53
 
54
54
  /**
55
55
  * Create a fully initialized agent runtime.
@@ -95,25 +95,15 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
95
95
  // Planner — multi-step task tracking
96
96
  const planner = new Planner(plansPath);
97
97
 
98
- // Cognee — vector search client (opt-in, graceful degradation if Cognee is down)
99
- let cognee: CogneeClient | null = null;
100
- if (config.cognee) {
101
- const cogneePartial: Partial<import('../cognee/types.js').CogneeConfig> = { dataset: agentId };
102
- if (process.env.COGNEE_BASE_URL) cogneePartial.baseUrl = process.env.COGNEE_BASE_URL;
103
- if (process.env.COGNEE_API_TOKEN) cogneePartial.apiToken = process.env.COGNEE_API_TOKEN;
104
- if (process.env.COGNEE_DATASET) cogneePartial.dataset = process.env.COGNEE_DATASET;
105
- cognee = new CogneeClient(cogneePartial);
106
- }
107
-
108
98
  // Brain — intelligence layer (TF-IDF scoring, auto-tagging, dedup)
109
99
  // Pass vaultManager so intelligentSearch queries all connected sources (not just agent tier)
110
- const brain = new Brain(vault, cognee ?? undefined, vaultManager);
100
+ const brain = new Brain(vault, vaultManager);
111
101
 
112
102
  // Brain Intelligence — pattern strengths, session knowledge, intelligence pipeline
113
103
  const brainIntelligence = new BrainIntelligence(vault, brain);
114
104
 
115
105
  // Curator — vault self-maintenance (dedup, contradictions, grooming, health)
116
- const curator = new Curator(vault, cognee ?? undefined);
106
+ const curator = new Curator(vault);
117
107
 
118
108
  // Governance — policy engine + proposal tracker for gated knowledge capture
119
109
  const governance = new Governance(vault);
@@ -152,17 +142,6 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
152
142
  const anthropicKeyPool = new KeyPool(anthropicConfig);
153
143
  const llmClient = new LLMClient(openaiKeyPool, anthropicKeyPool, agentId);
154
144
 
155
- // Cognee Sync Manager — queue-based dirty tracking with offline resilience (only when Cognee enabled)
156
- let syncManager: CogneeSyncManager | null = null;
157
- if (cognee) {
158
- syncManager = new CogneeSyncManager(
159
- vault.getProvider(),
160
- cognee,
161
- process.env.COGNEE_DATASET ?? agentId,
162
- );
163
- vault.setSyncManager(syncManager);
164
- }
165
-
166
145
  // Link Manager — Zettelkasten auto-linking on vault ingestion
167
146
  const linkManager = new LinkManager(vault.getProvider());
168
147
  vault.setLinkManager(linkManager, { enabled: true, maxLinks: 3 });
@@ -184,7 +163,7 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
184
163
  const vaultBranching = new VaultBranching(vault);
185
164
 
186
165
  // Context Engine — entity extraction, knowledge retrieval, confidence scoring
187
- const contextEngine = new ContextEngine(vault, brain, brainIntelligence, cognee);
166
+ const contextEngine = new ContextEngine(vault, brain, brainIntelligence);
188
167
 
189
168
  // Agency Manager — proactive file watching, pattern surfacing (disabled by default)
190
169
  const agencyManager = new AgencyManager(vault);
@@ -196,10 +175,6 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
196
175
  const health = new HealthRegistry();
197
176
  health.register('vault', 'healthy');
198
177
  health.register('brain', 'healthy');
199
- health.register(
200
- 'cognee',
201
- cognee ? (cognee.getStatus()?.available ? 'healthy' : 'degraded') : 'down',
202
- );
203
178
  health.register(
204
179
  'llm',
205
180
  llmClient.isAvailable().openai || llmClient.isAvailable().anthropic ? 'healthy' : 'degraded',
@@ -228,7 +203,6 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
228
203
  planner,
229
204
  curator,
230
205
  governance,
231
- cognee,
232
206
  loop,
233
207
  identityManager,
234
208
  intentRouter,
@@ -237,7 +211,6 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
237
211
  telemetry,
238
212
  projectRegistry,
239
213
  templateManager,
240
- syncManager,
241
214
  intakePipeline,
242
215
  textIngester,
243
216
  authPolicy: { mode: 'permissive', callerLevel: 'admin' },
@@ -335,26 +308,6 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
335
308
  const result = curator.consolidate({ dryRun: false, staleDaysThreshold: 90 });
336
309
  return { archived: result.staleEntries.length, result };
337
310
  });
338
- pr.registerHandler('cognee-ingest', async (job) => {
339
- if (!cognee) return { skipped: true, reason: 'cognee not available' };
340
- const entry = vault.get(job.entryId ?? '');
341
- if (!entry) return { skipped: true, reason: 'entry not found' };
342
- try {
343
- const result = await cognee.addEntries([entry]);
344
- return { ingested: result.added };
345
- } catch {
346
- return { skipped: true, reason: 'cognee ingestion failed' };
347
- }
348
- });
349
- pr.registerHandler('cognee-cognify', async (_job) => {
350
- if (!cognee) return { skipped: true, reason: 'cognee not available' };
351
- try {
352
- const result = await cognee.cognify();
353
- return result;
354
- } catch {
355
- return { skipped: true, reason: 'cognee cognify failed' };
356
- }
357
- });
358
311
  pr.registerHandler('verify-searchable', async (job) => {
359
312
  const entry = vault.get(job.entryId ?? '');
360
313
  if (!entry) return { skipped: true, reason: 'entry not found' };
@@ -364,10 +317,17 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
364
317
  });
365
318
  return pr;
366
319
  })(),
320
+ persona: (() => {
321
+ const p = loadPersona(agentId, config.persona ?? undefined);
322
+ logger.info(`[Persona] Loaded: ${p.name} (${p.template})`);
323
+ return p;
324
+ })(),
325
+ personaInstructions: (() => {
326
+ const p = loadPersona(agentId, config.persona ?? undefined);
327
+ return generatePersonaInstructions(p);
328
+ })(),
367
329
  createdAt: Date.now(),
368
330
  close: () => {
369
- syncManager?.close();
370
- cognee?.resetPendingCognify();
371
331
  vaultManager.close();
372
332
  },
373
333
  };
@@ -4,7 +4,6 @@ import type { BrainIntelligence } from '../brain/intelligence.js';
4
4
  import type { Planner } from '../planning/planner.js';
5
5
  import type { Curator } from '../curator/curator.js';
6
6
  import type { Governance } from '../governance/governance.js';
7
- import type { CogneeClient } from '../cognee/client.js';
8
7
  import type { KeyPool } from '../llm/key-pool.js';
9
8
  import type { LLMClient } from '../llm/llm-client.js';
10
9
  import type { IdentityManager } from '../control/identity-manager.js';
@@ -13,7 +12,6 @@ import type { LoopManager } from '../loop/loop-manager.js';
13
12
  import type { Telemetry } from '../telemetry/telemetry.js';
14
13
  import type { ProjectRegistry } from '../project/project-registry.js';
15
14
  import type { TemplateManager } from '../prompts/template-manager.js';
16
- import type { CogneeSyncManager } from '../cognee/sync-manager.js';
17
15
  import type { IntakePipeline } from '../intake/intake-pipeline.js';
18
16
  import type { Logger } from '../logging/logger.js';
19
17
  import type { LogLevel } from '../logging/types.js';
@@ -55,10 +53,10 @@ export interface AgentRuntimeConfig {
55
53
  logLevel?: LogLevel;
56
54
  /** Path to shared global vault. Default: ~/.soleri/vault.db */
57
55
  sharedVaultPath?: string;
58
- /** Enable Cognee vector search integration. Default: false (opt-in). */
59
- cognee?: boolean;
60
56
  /** Path to the agent's root directory (containing agent.yaml, instructions/, etc.). Optional — set by engine binary. */
61
57
  agentDir?: string;
58
+ /** Persona configuration from agent.yaml. If omitted, Italian Craftsperson default is used. */
59
+ persona?: Partial<import('../persona/types.js').PersonaConfig>;
62
60
  }
63
61
 
64
62
  /**
@@ -74,8 +72,6 @@ export interface AgentRuntime {
74
72
  planner: Planner;
75
73
  curator: Curator;
76
74
  governance: Governance;
77
- /** Cognee vector search client. Null when Cognee integration is disabled. */
78
- cognee: CogneeClient | null;
79
75
  loop: LoopManager;
80
76
  identityManager: IdentityManager;
81
77
  intentRouter: IntentRouter;
@@ -84,8 +80,6 @@ export interface AgentRuntime {
84
80
  telemetry: Telemetry;
85
81
  projectRegistry: ProjectRegistry;
86
82
  templateManager: TemplateManager;
87
- /** Cognee sync manager. Null when Cognee integration is disabled. */
88
- syncManager: CogneeSyncManager | null;
89
83
  intakePipeline: IntakePipeline;
90
84
  /** Mutable auth policy — controls facade dispatch enforcement. */
91
85
  authPolicy: AuthPolicy;
@@ -123,6 +117,10 @@ export interface AgentRuntime {
123
117
  jobQueue: JobQueue;
124
118
  /** Pipeline runner — background polling loop for job execution. */
125
119
  pipelineRunner: PipelineRunner;
120
+ /** Agent persona — defines character, voice, and cultural texture. */
121
+ persona: import('../persona/types.js').PersonaConfig;
122
+ /** Generated persona system instructions for LLM context. */
123
+ personaInstructions: import('../persona/types.js').PersonaSystemInstructions;
126
124
  /** Timestamp (ms since epoch) when this runtime was created. */
127
125
  createdAt: number;
128
126
  /** Close the vault database connection. Call on shutdown. */
@@ -400,6 +400,47 @@ export function createVaultLinkingOps(runtime: AgentRuntime): OpDefinition[] {
400
400
  };
401
401
  },
402
402
  },
403
+ {
404
+ name: 'backfill_links',
405
+ description:
406
+ 'Generate Zettelkasten links for orphan entries using FTS5 suggestions. One-time backfill for vaults with entries but no links.',
407
+ auth: 'write',
408
+ schema: z.object({
409
+ threshold: z.coerce
410
+ .number()
411
+ .min(0)
412
+ .max(1)
413
+ .default(0.7)
414
+ .describe('Min suggestion score to create link (default: 0.7)'),
415
+ maxLinks: z.coerce
416
+ .number()
417
+ .int()
418
+ .min(1)
419
+ .max(10)
420
+ .default(3)
421
+ .describe('Max links per entry (default: 3)'),
422
+ dryRun: z.boolean().optional().default(false).describe('Preview without creating links'),
423
+ batchSize: z.coerce
424
+ .number()
425
+ .int()
426
+ .min(1)
427
+ .max(200)
428
+ .default(50)
429
+ .describe('Entries per batch (default: 50)'),
430
+ }),
431
+ handler: async (params) => {
432
+ const result = linkManager.backfillLinks({
433
+ threshold: params.threshold as number,
434
+ maxLinks: params.maxLinks as number,
435
+ dryRun: params.dryRun as boolean,
436
+ batchSize: params.batchSize as number,
437
+ });
438
+ return {
439
+ ...result,
440
+ ...(result.preview ? { previewSample: result.preview.slice(0, 20) } : {}),
441
+ };
442
+ },
443
+ },
403
444
  {
404
445
  name: 'link_stats',
405
446
  description:
@@ -13,7 +13,12 @@ import type { OpDefinition } from '../facades/types.js';
13
13
  import type { AgentRuntime } from './types.js';
14
14
  import { detectScope, type ScopeInput } from '../vault/scope-detector.js';
15
15
  import { GitVaultSync, type GitVaultSyncConfig } from '../vault/git-vault-sync.js';
16
- import type { IntelligenceEntry, IntelligenceBundle } from '../intelligence/types.js';
16
+ import type {
17
+ IntelligenceEntry,
18
+ IntelligenceBundle,
19
+ IntelligenceBundleLink,
20
+ } from '../intelligence/types.js';
21
+ import { LinkManager } from '../vault/linking.js';
17
22
 
18
23
  export function createVaultSharingOps(runtime: AgentRuntime): OpDefinition[] {
19
24
  const { vault, knowledgeReview } = runtime;
@@ -147,10 +152,38 @@ export function createVaultSharingOps(runtime: AgentRuntime): OpDefinition[] {
147
152
  byDomain.get(d)!.push(entry);
148
153
  }
149
154
 
155
+ // Collect links for exported entries (Zettelkasten edge export)
156
+ const entryIds = new Set(entries.map((e) => e.id));
157
+ const linkManager = new LinkManager(vault.getProvider());
158
+ const allLinks = linkManager.getAllLinksForEntries([...entryIds]);
159
+ // Only include links where BOTH endpoints are in the export set
160
+ const exportLinks = allLinks.filter(
161
+ (l) => entryIds.has(l.sourceId) && entryIds.has(l.targetId),
162
+ );
163
+
164
+ // Build a domain→links map (group by source entry's domain)
165
+ const entryDomainMap = new Map(entries.map((e) => [e.id, e.domain]));
166
+ const linksByDomain = new Map<string, IntelligenceBundleLink[]>();
167
+ for (const link of exportLinks) {
168
+ const linkDomain = entryDomainMap.get(link.sourceId) ?? 'unknown';
169
+ if (!linksByDomain.has(linkDomain)) linksByDomain.set(linkDomain, []);
170
+ linksByDomain.get(linkDomain)!.push({
171
+ sourceId: link.sourceId,
172
+ targetId: link.targetId,
173
+ linkType: link.linkType,
174
+ note: link.note,
175
+ });
176
+ }
177
+
150
178
  const version = (params.version as string) ?? '1.0.0';
151
179
  const bundles: IntelligenceBundle[] = [];
152
180
  for (const [d, domainEntries] of byDomain) {
153
- bundles.push({ domain: d, version, entries: domainEntries });
181
+ bundles.push({
182
+ domain: d,
183
+ version,
184
+ entries: domainEntries,
185
+ links: linksByDomain.get(d) ?? [],
186
+ });
154
187
  }
155
188
 
156
189
  return {
@@ -158,6 +191,7 @@ export function createVaultSharingOps(runtime: AgentRuntime): OpDefinition[] {
158
191
  version,
159
192
  bundles,
160
193
  totalEntries: entries.length,
194
+ totalLinks: exportLinks.length,
161
195
  domains: [...byDomain.keys()],
162
196
  };
163
197
  },
@@ -187,10 +221,17 @@ export function createVaultSharingOps(runtime: AgentRuntime): OpDefinition[] {
187
221
  domain: string;
188
222
  version: string;
189
223
  entries: IntelligenceEntry[];
224
+ links?: IntelligenceBundleLink[];
190
225
  }>;
191
226
  const forceTier = params.tier as 'agent' | 'project' | 'team' | undefined;
192
227
  let imported = 0;
193
228
  let duplicates = 0;
229
+ let linksCreated = 0;
230
+ let linksSkipped = 0;
231
+
232
+ // Track ID remapping: bundle entry ID → actual vault entry ID
233
+ const idRemap = new Map<string, string>();
234
+ const linkManager = new LinkManager(vault.getProvider());
194
235
 
195
236
  for (const bundle of bundles) {
196
237
  const entries = bundle.entries.map((e) => ({
@@ -198,13 +239,31 @@ export function createVaultSharingOps(runtime: AgentRuntime): OpDefinition[] {
198
239
  tier: forceTier ?? e.tier ?? 'project',
199
240
  }));
200
241
  const results = vault.seedDedup(entries);
201
- for (const r of results) {
242
+ for (let i = 0; i < results.length; i++) {
243
+ const r = results[i];
244
+ const originalId = bundle.entries[i].id;
245
+ // For duplicates, map to the existing vault entry; for inserts, keep original ID
246
+ idRemap.set(originalId, r.existingId ?? r.id);
202
247
  if (r.action === 'inserted') imported++;
203
248
  else duplicates++;
204
249
  }
250
+
251
+ // Import links if present
252
+ if (bundle.links && bundle.links.length > 0) {
253
+ for (const link of bundle.links) {
254
+ const sourceId = idRemap.get(link.sourceId);
255
+ const targetId = idRemap.get(link.targetId);
256
+ if (sourceId && targetId) {
257
+ linkManager.addLink(sourceId, targetId, link.linkType, link.note);
258
+ linksCreated++;
259
+ } else {
260
+ linksSkipped++;
261
+ }
262
+ }
263
+ }
205
264
  }
206
265
 
207
- return { imported, duplicates, total: imported + duplicates };
266
+ return { imported, duplicates, linksCreated, linksSkipped, total: imported + duplicates };
208
267
  },
209
268
  },
210
269