@soleri/core 8.0.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 (239) 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/brain/knowledge-synthesizer.d.ts.map +1 -1
  6. package/dist/brain/knowledge-synthesizer.js +0 -2
  7. package/dist/brain/knowledge-synthesizer.js.map +1 -1
  8. package/dist/cognee/client.d.ts +5 -0
  9. package/dist/cognee/client.d.ts.map +1 -1
  10. package/dist/cognee/client.js +83 -16
  11. package/dist/cognee/client.js.map +1 -1
  12. package/dist/cognee/sync-manager.d.ts +67 -8
  13. package/dist/cognee/sync-manager.d.ts.map +1 -1
  14. package/dist/cognee/sync-manager.js +129 -32
  15. package/dist/cognee/sync-manager.js.map +1 -1
  16. package/dist/cognee/types.d.ts +16 -0
  17. package/dist/cognee/types.d.ts.map +1 -1
  18. package/dist/context/context-engine.d.ts +2 -5
  19. package/dist/context/context-engine.d.ts.map +1 -1
  20. package/dist/context/context-engine.js +4 -31
  21. package/dist/context/context-engine.js.map +1 -1
  22. package/dist/curator/classifier.d.ts.map +1 -1
  23. package/dist/curator/classifier.js +0 -2
  24. package/dist/curator/classifier.js.map +1 -1
  25. package/dist/curator/curator.d.ts +2 -5
  26. package/dist/curator/curator.d.ts.map +1 -1
  27. package/dist/curator/curator.js +4 -23
  28. package/dist/curator/curator.js.map +1 -1
  29. package/dist/curator/quality-gate.d.ts.map +1 -1
  30. package/dist/curator/quality-gate.js +0 -2
  31. package/dist/curator/quality-gate.js.map +1 -1
  32. package/dist/domain-packs/index.d.ts +0 -3
  33. package/dist/domain-packs/index.d.ts.map +1 -1
  34. package/dist/domain-packs/index.js +0 -3
  35. package/dist/domain-packs/index.js.map +1 -1
  36. package/dist/domain-packs/loader.d.ts.map +1 -1
  37. package/dist/domain-packs/loader.js +20 -4
  38. package/dist/domain-packs/loader.js.map +1 -1
  39. package/dist/domain-packs/pack-runtime.d.ts +5 -5
  40. package/dist/domain-packs/pack-runtime.d.ts.map +1 -1
  41. package/dist/domain-packs/pack-runtime.js +2 -2
  42. package/dist/domain-packs/pack-runtime.js.map +1 -1
  43. package/dist/domain-packs/types.d.ts +8 -2
  44. package/dist/domain-packs/types.d.ts.map +1 -1
  45. package/dist/domain-packs/types.js.map +1 -1
  46. package/dist/engine/bin/soleri-engine.js +18 -7
  47. package/dist/engine/bin/soleri-engine.js.map +1 -1
  48. package/dist/engine/core-ops.d.ts.map +1 -1
  49. package/dist/engine/core-ops.js +11 -6
  50. package/dist/engine/core-ops.js.map +1 -1
  51. package/dist/engine/index.d.ts +2 -0
  52. package/dist/engine/index.d.ts.map +1 -1
  53. package/dist/engine/index.js +1 -0
  54. package/dist/engine/index.js.map +1 -1
  55. package/dist/engine/module-manifest.d.ts +28 -0
  56. package/dist/engine/module-manifest.d.ts.map +1 -0
  57. package/dist/engine/module-manifest.js +85 -0
  58. package/dist/engine/module-manifest.js.map +1 -0
  59. package/dist/engine/register-engine.d.ts +19 -0
  60. package/dist/engine/register-engine.d.ts.map +1 -1
  61. package/dist/engine/register-engine.js +15 -9
  62. package/dist/engine/register-engine.js.map +1 -1
  63. package/dist/index.d.ts +5 -6
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +3 -5
  66. package/dist/index.js.map +1 -1
  67. package/dist/intake/content-classifier.d.ts.map +1 -1
  68. package/dist/intake/content-classifier.js +0 -2
  69. package/dist/intake/content-classifier.js.map +1 -1
  70. package/dist/intelligence/types.d.ts +7 -0
  71. package/dist/intelligence/types.d.ts.map +1 -1
  72. package/dist/llm/llm-client.d.ts.map +1 -1
  73. package/dist/llm/llm-client.js +8 -4
  74. package/dist/llm/llm-client.js.map +1 -1
  75. package/dist/llm/oauth-discovery.d.ts +0 -8
  76. package/dist/llm/oauth-discovery.d.ts.map +1 -1
  77. package/dist/llm/oauth-discovery.js +0 -19
  78. package/dist/llm/oauth-discovery.js.map +1 -1
  79. package/dist/llm/types.d.ts +4 -2
  80. package/dist/llm/types.d.ts.map +1 -1
  81. package/dist/packs/pack-installer.d.ts +2 -1
  82. package/dist/packs/pack-installer.d.ts.map +1 -1
  83. package/dist/packs/pack-installer.js +10 -1
  84. package/dist/packs/pack-installer.js.map +1 -1
  85. package/dist/persistence/index.d.ts +0 -1
  86. package/dist/persistence/index.d.ts.map +1 -1
  87. package/dist/persistence/index.js +0 -1
  88. package/dist/persistence/index.js.map +1 -1
  89. package/dist/persistence/types.d.ts +2 -6
  90. package/dist/persistence/types.d.ts.map +1 -1
  91. package/dist/persona/defaults.d.ts +16 -0
  92. package/dist/persona/defaults.d.ts.map +1 -0
  93. package/dist/persona/defaults.js +78 -0
  94. package/dist/persona/defaults.js.map +1 -0
  95. package/dist/persona/index.d.ts +5 -0
  96. package/dist/persona/index.d.ts.map +1 -0
  97. package/dist/persona/index.js +4 -0
  98. package/dist/persona/index.js.map +1 -0
  99. package/dist/persona/loader.d.ts +11 -0
  100. package/dist/persona/loader.d.ts.map +1 -0
  101. package/dist/persona/loader.js +45 -0
  102. package/dist/persona/loader.js.map +1 -0
  103. package/dist/persona/prompt-generator.d.ts +13 -0
  104. package/dist/persona/prompt-generator.d.ts.map +1 -0
  105. package/dist/persona/prompt-generator.js +89 -0
  106. package/dist/persona/prompt-generator.js.map +1 -0
  107. package/dist/persona/types.d.ts +56 -0
  108. package/dist/persona/types.d.ts.map +1 -0
  109. package/dist/persona/types.js +9 -0
  110. package/dist/persona/types.js.map +1 -0
  111. package/dist/plugins/index.d.ts +4 -0
  112. package/dist/plugins/index.d.ts.map +1 -1
  113. package/dist/plugins/index.js +4 -0
  114. package/dist/plugins/index.js.map +1 -1
  115. package/dist/plugins/plugin-registry.d.ts +4 -0
  116. package/dist/plugins/plugin-registry.d.ts.map +1 -1
  117. package/dist/plugins/plugin-registry.js +4 -0
  118. package/dist/plugins/plugin-registry.js.map +1 -1
  119. package/dist/plugins/types.d.ts +36 -31
  120. package/dist/plugins/types.d.ts.map +1 -1
  121. package/dist/plugins/types.js +6 -3
  122. package/dist/plugins/types.js.map +1 -1
  123. package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
  124. package/dist/runtime/admin-extra-ops.js +5 -27
  125. package/dist/runtime/admin-extra-ops.js.map +1 -1
  126. package/dist/runtime/admin-ops.d.ts.map +1 -1
  127. package/dist/runtime/admin-ops.js +5 -37
  128. package/dist/runtime/admin-ops.js.map +1 -1
  129. package/dist/runtime/capture-ops.d.ts.map +1 -1
  130. package/dist/runtime/capture-ops.js +32 -16
  131. package/dist/runtime/capture-ops.js.map +1 -1
  132. package/dist/runtime/claude-md-helpers.d.ts +0 -9
  133. package/dist/runtime/claude-md-helpers.d.ts.map +1 -1
  134. package/dist/runtime/claude-md-helpers.js +1 -14
  135. package/dist/runtime/claude-md-helpers.js.map +1 -1
  136. package/dist/runtime/cognee-sync-ops.d.ts +2 -2
  137. package/dist/runtime/cognee-sync-ops.d.ts.map +1 -1
  138. package/dist/runtime/cognee-sync-ops.js +45 -7
  139. package/dist/runtime/cognee-sync-ops.js.map +1 -1
  140. package/dist/runtime/facades/admin-facade.d.ts.map +1 -1
  141. package/dist/runtime/facades/admin-facade.js +1 -2
  142. package/dist/runtime/facades/admin-facade.js.map +1 -1
  143. package/dist/runtime/facades/index.d.ts +1 -1
  144. package/dist/runtime/facades/index.d.ts.map +1 -1
  145. package/dist/runtime/facades/index.js +1 -10
  146. package/dist/runtime/facades/index.js.map +1 -1
  147. package/dist/runtime/pack-ops.d.ts +3 -0
  148. package/dist/runtime/pack-ops.d.ts.map +1 -1
  149. package/dist/runtime/pack-ops.js +18 -1
  150. package/dist/runtime/pack-ops.js.map +1 -1
  151. package/dist/runtime/plugin-ops.d.ts.map +1 -1
  152. package/dist/runtime/plugin-ops.js +3 -0
  153. package/dist/runtime/plugin-ops.js.map +1 -1
  154. package/dist/runtime/runtime.d.ts.map +1 -1
  155. package/dist/runtime/runtime.js +14 -53
  156. package/dist/runtime/runtime.js.map +1 -1
  157. package/dist/runtime/session-briefing.d.ts.map +1 -1
  158. package/dist/runtime/session-briefing.js +14 -0
  159. package/dist/runtime/session-briefing.js.map +1 -1
  160. package/dist/runtime/types.d.ts +6 -8
  161. package/dist/runtime/types.d.ts.map +1 -1
  162. package/dist/runtime/vault-linking-ops.d.ts.map +1 -1
  163. package/dist/runtime/vault-linking-ops.js +42 -4
  164. package/dist/runtime/vault-linking-ops.js.map +1 -1
  165. package/dist/runtime/vault-sharing-ops.d.ts.map +1 -1
  166. package/dist/runtime/vault-sharing-ops.js +53 -3
  167. package/dist/runtime/vault-sharing-ops.js.map +1 -1
  168. package/dist/vault/linking.d.ts +37 -0
  169. package/dist/vault/linking.d.ts.map +1 -1
  170. package/dist/vault/linking.js +73 -0
  171. package/dist/vault/linking.js.map +1 -1
  172. package/dist/vault/vault.d.ts +9 -2
  173. package/dist/vault/vault.d.ts.map +1 -1
  174. package/dist/vault/vault.js +21 -12
  175. package/dist/vault/vault.js.map +1 -1
  176. package/package.json +6 -4
  177. package/src/__tests__/curator-pipeline-e2e.test.ts +187 -0
  178. package/src/__tests__/module-manifest-drift.test.ts +59 -0
  179. package/src/brain/brain.ts +4 -157
  180. package/src/brain/knowledge-synthesizer.ts +0 -2
  181. package/src/context/context-engine.ts +3 -31
  182. package/src/curator/classifier.ts +0 -2
  183. package/src/curator/curator.ts +5 -28
  184. package/src/curator/quality-gate.ts +0 -2
  185. package/src/domain-packs/index.ts +0 -6
  186. package/src/domain-packs/loader.ts +25 -5
  187. package/src/domain-packs/pack-runtime.ts +6 -6
  188. package/src/domain-packs/types.ts +8 -2
  189. package/src/engine/bin/soleri-engine.ts +23 -7
  190. package/src/engine/core-ops.ts +11 -6
  191. package/src/engine/index.ts +2 -0
  192. package/src/engine/module-manifest.ts +99 -0
  193. package/src/engine/register-engine.ts +21 -9
  194. package/src/index.ts +20 -17
  195. package/src/intake/content-classifier.ts +0 -2
  196. package/src/intelligence/types.ts +8 -0
  197. package/src/llm/llm-client.ts +12 -6
  198. package/src/llm/oauth-discovery.ts +0 -18
  199. package/src/llm/types.ts +4 -2
  200. package/src/packs/pack-installer.ts +16 -1
  201. package/src/persistence/index.ts +0 -1
  202. package/src/persistence/types.ts +2 -6
  203. package/src/persona/defaults.ts +96 -0
  204. package/src/persona/index.ts +9 -0
  205. package/src/persona/loader.ts +50 -0
  206. package/src/persona/prompt-generator.ts +109 -0
  207. package/src/persona/types.ts +72 -0
  208. package/src/plugins/index.ts +4 -0
  209. package/src/plugins/plugin-registry.ts +6 -1
  210. package/src/plugins/types.ts +10 -5
  211. package/src/runtime/admin-extra-ops.ts +5 -28
  212. package/src/runtime/admin-ops.ts +5 -38
  213. package/src/runtime/capture-ops.ts +33 -14
  214. package/src/runtime/claude-md-helpers.ts +1 -19
  215. package/src/runtime/facades/admin-facade.ts +1 -2
  216. package/src/runtime/facades/index.ts +1 -11
  217. package/src/runtime/pack-ops.ts +26 -1
  218. package/src/runtime/plugin-ops.ts +3 -0
  219. package/src/runtime/runtime.ts +14 -54
  220. package/src/runtime/session-briefing.ts +14 -0
  221. package/src/runtime/types.ts +6 -8
  222. package/src/runtime/vault-linking-ops.ts +43 -4
  223. package/src/runtime/vault-sharing-ops.ts +63 -4
  224. package/src/vault/linking.ts +94 -0
  225. package/src/vault/vault.ts +24 -12
  226. package/src/__tests__/cognee-client-gaps.test.ts +0 -474
  227. package/src/__tests__/cognee-client.test.ts +0 -524
  228. package/src/__tests__/cognee-hybrid-search.test.ts +0 -492
  229. package/src/__tests__/cognee-integration.test.ts +0 -80
  230. package/src/__tests__/cognee-sync-manager-deep.test.ts +0 -654
  231. package/src/__tests__/cognee-sync-manager.test.ts +0 -104
  232. package/src/__tests__/postgres-provider.test.ts +0 -116
  233. package/src/cognee/client.ts +0 -370
  234. package/src/cognee/sync-manager.ts +0 -389
  235. package/src/cognee/types.ts +0 -62
  236. package/src/health/doctor-checks.ts +0 -115
  237. package/src/persistence/postgres-provider.ts +0 -310
  238. package/src/runtime/cognee-sync-ops.ts +0 -63
  239. package/src/runtime/facades/cognee-facade.ts +0 -164
@@ -1,6 +1,5 @@
1
1
  import type { Vault } from '../vault/vault.js';
2
2
  import type { IntelligenceEntry } from '../intelligence/types.js';
3
- import type { CogneeClient } from '../cognee/client.js';
4
3
  import type { PersistenceProvider } from '../persistence/types.js';
5
4
  import {
6
5
  tokenize,
@@ -51,12 +50,10 @@ const DEFAULT_TAG_ALIASES: Array<[string, string]> = [
51
50
 
52
51
  export class Curator {
53
52
  private vault: Vault;
54
- private cognee: CogneeClient | undefined;
55
53
  private provider: PersistenceProvider;
56
54
 
57
- constructor(vault: Vault, cognee?: CogneeClient) {
55
+ constructor(vault: Vault) {
58
56
  this.vault = vault;
59
- this.cognee = cognee;
60
57
  this.provider = vault.getProvider();
61
58
  this.initializeTables();
62
59
  this.seedDefaultAliases();
@@ -378,8 +375,7 @@ export class Curator {
378
375
 
379
376
  async detectContradictionsHybrid(threshold?: number): Promise<{
380
377
  contradictions: Contradiction[];
381
- cogneeAvailable: boolean;
382
- method: 'hybrid' | 'tfidf-only';
378
+ method: 'tfidf-only';
383
379
  }> {
384
380
  const effectiveThreshold = threshold ?? DEFAULT_CONTRADICTION_THRESHOLD;
385
381
  const entries = this.vault.list({ limit: 100000 });
@@ -387,14 +383,12 @@ export class Curator {
387
383
  const patterns = entries.filter((e) => e.type === 'pattern');
388
384
 
389
385
  if (antipatterns.length === 0 || patterns.length === 0) {
390
- return { contradictions: [], cogneeAvailable: false, method: 'tfidf-only' };
386
+ return { contradictions: [], method: 'tfidf-only' };
391
387
  }
392
388
 
393
389
  const vocabulary = this.buildVocabulary(entries);
394
390
  const detected: Contradiction[] = [];
395
391
 
396
- const cogneeAvailable = this.cognee?.isAvailable ?? false;
397
-
398
392
  for (const ap of antipatterns) {
399
393
  let candidates: IntelligenceEntry[];
400
394
  try {
@@ -410,23 +404,7 @@ export class Curator {
410
404
  for (const pattern of candidates) {
411
405
  const pText = [pattern.title, pattern.description, pattern.context ?? ''].join(' ');
412
406
  const pVec = calculateTfIdf(tokenize(pText), vocabulary);
413
- const tfidfScore = cosineSimilarity(apVec, pVec);
414
-
415
- let finalScore = tfidfScore;
416
- if (cogneeAvailable && this.cognee) {
417
- try {
418
- const cogneeResults = await this.cognee.search(`${ap.title} ${pattern.title}`, {
419
- limit: 5,
420
- });
421
- const cogneeScore =
422
- cogneeResults.length > 0
423
- ? cogneeResults.reduce((sum, r) => sum + r.score, 0) / cogneeResults.length
424
- : 0;
425
- finalScore = 0.6 * tfidfScore + 0.4 * cogneeScore;
426
- } catch {
427
- finalScore = tfidfScore;
428
- }
429
- }
407
+ const finalScore = cosineSimilarity(apVec, pVec);
430
408
 
431
409
  if (finalScore >= effectiveThreshold) {
432
410
  const result = this.provider.run(
@@ -446,8 +424,7 @@ export class Curator {
446
424
 
447
425
  return {
448
426
  contradictions: detected,
449
- cogneeAvailable,
450
- method: cogneeAvailable ? 'hybrid' : 'tfidf-only',
427
+ method: 'tfidf-only',
451
428
  };
452
429
  }
453
430
 
@@ -97,8 +97,6 @@ export async function evaluateQuality(
97
97
 
98
98
  try {
99
99
  const result = await llm.complete({
100
- provider: 'openai',
101
- model: 'gpt-4o-mini',
102
100
  systemPrompt: 'You are a knowledge quality evaluator. Respond only with JSON.',
103
101
  userPrompt: prompt,
104
102
  temperature: 0.1,
@@ -11,12 +11,6 @@ export {
11
11
 
12
12
  export { loadDomainPack, loadDomainPacksFromConfig, resolveDependencies } from './loader.js';
13
13
 
14
- export { installKnowledge, type KnowledgeInstallResult } from './knowledge-installer.js';
15
-
16
- export { installSkills, type SkillsInstallResult } from './skills-installer.js';
17
-
18
- export { injectDomainRules, removeDomainRules } from './inject-rules.js';
19
-
20
14
  export {
21
15
  type PackRuntime,
22
16
  type PackProjectContext,
@@ -18,7 +18,8 @@ export async function loadDomainPack(packageName: string): Promise<DomainPackMan
18
18
  mod = await import(packageName);
19
19
  } catch (err) {
20
20
  throw new Error(
21
- `Failed to import domain pack "${packageName}": ${err instanceof Error ? err.message : String(err)}`, { cause: err },
21
+ `Failed to import domain pack "${packageName}": ${err instanceof Error ? err.message : String(err)}`,
22
+ { cause: err },
22
23
  );
23
24
  }
24
25
 
@@ -33,10 +34,29 @@ export async function loadDomainPack(packageName: string): Promise<DomainPackMan
33
34
  throw new Error(`Domain pack "${packageName}" failed validation: ${result.errors.message}`);
34
35
  }
35
36
 
36
- return {
37
- ...result.data,
38
- packageName,
39
- };
37
+ const manifest: DomainPackManifest = { ...result.data, packageName };
38
+
39
+ // Warn if pack's engine requirement is mismatched
40
+ try {
41
+ const pkgJson = await import(`${packageName}/package.json`, { with: { type: 'json' } })
42
+ .then((m) => m.default)
43
+ .catch(() => null);
44
+ const peerCore = pkgJson?.peerDependencies?.['@soleri/core'];
45
+ if (peerCore) {
46
+ const requiredMajor = parseInt(peerCore.replace(/[^0-9]/g, ''), 10);
47
+ const { ENGINE_MAJOR_VERSION } = await import('../engine/module-manifest.js');
48
+ if (requiredMajor && ENGINE_MAJOR_VERSION && requiredMajor > ENGINE_MAJOR_VERSION) {
49
+ console.error(
50
+ `[warn] Domain pack "${packageName}" requires @soleri/core ${peerCore} ` +
51
+ `but engine is v${ENGINE_MAJOR_VERSION}. Upgrade @soleri/core.`,
52
+ );
53
+ }
54
+ }
55
+ } catch {
56
+ // Version check is best-effort — don't block loading
57
+ }
58
+
59
+ return manifest;
40
60
  }
41
61
 
42
62
  /**
@@ -14,7 +14,7 @@ import type { Vault } from '../vault/vault.js';
14
14
  */
15
15
  export interface PackProjectContext {
16
16
  id: string;
17
- name: string;
17
+ name?: string;
18
18
  path: string;
19
19
  colors?: {
20
20
  [scale: string]: {
@@ -49,7 +49,7 @@ export interface PackRuntime {
49
49
  getProject(projectId: string): PackProjectContext | undefined;
50
50
 
51
51
  /** List all registered projects */
52
- listProjects(): Array<{ id: string; name: string; path: string }>;
52
+ listProjects(): Array<{ id: string; name?: string; path: string }>;
53
53
 
54
54
  /** Create a session check (for tool chaining) */
55
55
  createCheck(type: string, data: Record<string, unknown>): string;
@@ -70,8 +70,8 @@ export interface PackRuntime {
70
70
  export function createPackRuntime(runtime: {
71
71
  vault: Vault;
72
72
  projectRegistry: {
73
- getProject(id: string): PackProjectContext | undefined;
74
- listProjects(): Array<{ id: string; name: string; path: string }>;
73
+ get(id: string): PackProjectContext | null;
74
+ list(): Array<{ id: string; name?: string; path: string }>;
75
75
  };
76
76
  sessionStore?: {
77
77
  createCheck(type: string, data: Record<string, unknown>): string;
@@ -81,8 +81,8 @@ export function createPackRuntime(runtime: {
81
81
  }): PackRuntime {
82
82
  return {
83
83
  vault: runtime.vault,
84
- getProject: (id) => runtime.projectRegistry.getProject(id),
85
- listProjects: () => runtime.projectRegistry.listProjects(),
84
+ getProject: (id) => runtime.projectRegistry.get(id) ?? undefined,
85
+ listProjects: () => runtime.projectRegistry.list(),
86
86
  createCheck: (type, data) => {
87
87
  if (!runtime.sessionStore) throw new Error('Session store not available');
88
88
  return runtime.sessionStore.createCheck(type, data);
@@ -93,8 +93,14 @@ export interface DomainPack {
93
93
  requires?: string[];
94
94
  /** Called after pack is installed (one-time setup). */
95
95
  onInstall?: (runtime: AgentRuntime) => Promise<void>;
96
- /** Called each time the agent starts (runtime initialization). */
97
- onActivate?: (runtime: AgentRuntime) => Promise<void>;
96
+ /**
97
+ * Called each time the agent starts (runtime initialization).
98
+ *
99
+ * Receives `PackRuntime` (narrowed interface with vault, projects, session checks).
100
+ * The full `AgentRuntime` is passed as second argument for backwards compatibility
101
+ * but is deprecated — packs should only use `PackRuntime`.
102
+ */
103
+ onActivate?: (packRuntime: PackRuntime, runtime?: AgentRuntime) => Promise<void>;
98
104
  }
99
105
 
100
106
  // ---------------------------------------------------------------------------
@@ -71,12 +71,13 @@ async function main(): Promise<void> {
71
71
  ? resolve((engineConfig.vault as string).replace(/^~/, homedir()))
72
72
  : join(homedir(), `.${agentId}`, 'vault.db');
73
73
 
74
- // 3. Create runtime
74
+ // 3. Create runtime (with persona from agent.yaml if present)
75
+ const personaConfig = config.persona as Record<string, unknown> | undefined;
75
76
  const runtime = createAgentRuntime({
76
77
  agentId,
77
78
  vaultPath,
78
79
  agentDir,
79
- cognee: (engineConfig.cognee as boolean) ?? false,
80
+ persona: personaConfig as import('../../persona/types.js').PersonaConfig | undefined,
80
81
  });
81
82
 
82
83
  console.error(`${tag} Vault: ${vaultPath}`);
@@ -117,6 +118,14 @@ async function main(): Promise<void> {
117
118
  // 6. Seed default playbooks
118
119
  seedDefaultPlaybooks(runtime.vault);
119
120
 
121
+ // Log vault stats for first-run visibility
122
+ const vaultStats = runtime.vault.stats();
123
+ console.error(
124
+ `${tag} Vault: ${vaultStats.totalEntries} entries (${Object.entries(vaultStats.byType ?? {})
125
+ .map(([t, n]) => `${n} ${t}`)
126
+ .join(', ')})`,
127
+ );
128
+
120
129
  // 7. Load domain packs
121
130
  const packs = (config.packs ?? []) as Array<{ name: string; package: string; version?: string }>;
122
131
  const loadedPacks: Array<{ name: string; facades?: Array<{ name: string; ops: unknown[] }> }> =
@@ -129,9 +138,12 @@ async function main(): Promise<void> {
129
138
  const manifests = await loadDomainPacksFromConfig(refs);
130
139
 
131
140
  // Packs activate sequentially — order may matter for dependencies
141
+ const { createPackRuntime } = await import('../../domain-packs/pack-runtime.js');
142
+ const narrowedRuntime = createPackRuntime(runtime);
143
+
132
144
  for (const manifest of manifests) {
133
145
  if (manifest.onActivate) {
134
- await manifest.onActivate(runtime); // eslint-disable-line no-await-in-loop
146
+ await manifest.onActivate(narrowedRuntime, runtime); // eslint-disable-line no-await-in-loop
135
147
  }
136
148
  loadedPacks.push(manifest);
137
149
  console.error(`${tag} Domain pack: ${manifest.name}`);
@@ -164,21 +176,21 @@ async function main(): Promise<void> {
164
176
  version: '1.0.0',
165
177
  });
166
178
 
167
- // 11. Register persona prompt
168
- server.prompt('persona', 'Get agent persona and principles', () => ({
179
+ // 11. Register persona prompt (uses composable persona system)
180
+ server.prompt('persona', 'Get agent persona and character instructions', () => ({
169
181
  messages: [
170
182
  {
171
183
  role: 'user' as const,
172
184
  content: {
173
185
  type: 'text' as const,
174
- text: `You are ${identity.name}. ${identity.role}.\n\nPrinciples:\n${identity.principles.map((p) => `- ${p}`).join('\n')}\n\nTone: ${identity.tone}`,
186
+ text: runtime.personaInstructions.instructions,
175
187
  },
176
188
  },
177
189
  ],
178
190
  }));
179
191
 
180
192
  // 12. Register all engine tools
181
- const { tools, totalOps } = registerEngine(server, runtime, {
193
+ const { tools, totalOps, registerTool } = registerEngine(server, runtime, {
182
194
  agentId,
183
195
  coreOps,
184
196
  domains: identity.domains,
@@ -195,6 +207,10 @@ async function main(): Promise<void> {
195
207
 
196
208
  console.error(`${tag} Registered ${tools.length} tools (${totalOps} ops)`);
197
209
 
210
+ // Enable hot reload for post-boot pack/plugin installation
211
+ const { setHotRegister } = await import('../../runtime/pack-ops.js');
212
+ setHotRegister(registerTool);
213
+
198
214
  // 13. Connect stdio transport
199
215
  const transport = new StdioServerTransport();
200
216
  await server.connect(transport);
@@ -101,26 +101,32 @@ export function createCoreOps(
101
101
 
102
102
  // Build activation context
103
103
  const s = runtime.vault.stats();
104
+ const persona = runtime.persona;
105
+ const personaInstructions = runtime.personaInstructions;
104
106
  return {
105
107
  activated: true,
106
108
  agent: {
107
109
  id: identity.id,
108
- name: identity.name,
110
+ name: persona.name,
109
111
  role: identity.role,
110
112
  description: identity.description,
111
113
  format: 'filetree',
112
114
  },
113
115
  persona: {
114
- tone: identity.tone,
115
- principles: identity.principles,
116
- greeting: identity.greeting ?? `Hello! I am ${identity.name}.`,
116
+ template: persona.template,
117
+ name: persona.name,
118
+ culture: persona.culture,
119
+ voice: persona.voice,
120
+ traits: persona.traits,
121
+ quirks: persona.quirks,
122
+ greeting: personaInstructions.greeting,
123
+ instructions: personaInstructions.instructions,
117
124
  },
118
125
  vault: {
119
126
  connected: true,
120
127
  entries: s.totalEntries,
121
128
  domains: Object.keys(s.byDomain),
122
129
  },
123
- domains: identity.domains,
124
130
  };
125
131
  },
126
132
  },
@@ -162,7 +168,6 @@ export function createCoreOps(
162
168
  byType: s.byType,
163
169
  },
164
170
  engine: {
165
- cognee: runtime.cognee !== null && runtime.cognee !== undefined,
166
171
  brain: true,
167
172
  curator: true,
168
173
  planner: true,
@@ -17,3 +17,5 @@ export { registerEngine } from './register-engine.js';
17
17
  export type { EngineRegistrationOptions, EngineRegistrationResult } from './register-engine.js';
18
18
  export { createCoreOps } from './core-ops.js';
19
19
  export type { AgentIdentityConfig } from './core-ops.js';
20
+ export { ENGINE_MODULE_MANIFEST, CORE_KEY_OPS } from './module-manifest.js';
21
+ export type { ModuleManifestEntry } from './module-manifest.js';
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Soleri Engine Module Manifest
3
+ *
4
+ * Single source of truth for engine module names, descriptions, and key ops.
5
+ * Used by register-engine.ts at runtime and by @soleri/forge for template generation.
6
+ *
7
+ * This file is intentionally dependency-free so it can be imported by any package.
8
+ */
9
+
10
+ export interface ModuleManifestEntry {
11
+ /** Suffix for tool name: {agentId}_{suffix} */
12
+ suffix: string;
13
+ /** Human-readable description */
14
+ description: string;
15
+ /** Representative ops shown in placeholder tables (max 4) */
16
+ keyOps: string[];
17
+ /** If true, module requires a runtime condition to register */
18
+ conditional?: boolean;
19
+ }
20
+
21
+ /**
22
+ * Canonical list of engine modules.
23
+ * Order here determines order in generated tool tables.
24
+ */
25
+ export const ENGINE_MODULE_MANIFEST: ModuleManifestEntry[] = [
26
+ {
27
+ suffix: 'vault',
28
+ description: 'Knowledge management — search, CRUD, import/export, intake, archival.',
29
+ keyOps: ['search_intelligent', 'capture_knowledge', 'capture_quick'],
30
+ },
31
+ {
32
+ suffix: 'plan',
33
+ description: 'Plan lifecycle — create, approve, execute, reconcile, complete, grading.',
34
+ keyOps: ['create_plan', 'approve_plan', 'plan_split', 'plan_reconcile'],
35
+ },
36
+ {
37
+ suffix: 'brain',
38
+ description: 'Learning system — intelligence pipeline, strengths, feedback, sessions.',
39
+ keyOps: ['recommend', 'strengths', 'feedback'],
40
+ },
41
+ {
42
+ suffix: 'memory',
43
+ description: 'Session & cross-project memory — capture, search, dedup, promote.',
44
+ keyOps: ['memory_search', 'memory_capture', 'session_capture'],
45
+ },
46
+ {
47
+ suffix: 'admin',
48
+ description: 'Infrastructure — health, config, telemetry, tokens, LLM, prompts.',
49
+ keyOps: ['admin_health', 'admin_tool_list', 'admin_diagnostic'],
50
+ },
51
+ {
52
+ suffix: 'curator',
53
+ description: 'Quality — duplicate detection, contradictions, grooming, health audit.',
54
+ keyOps: ['curator_groom', 'curator_status', 'curator_health'],
55
+ },
56
+ {
57
+ suffix: 'loop',
58
+ description: 'Iterative validation loops — start, iterate, cancel, complete, history.',
59
+ keyOps: ['loop_start', 'loop_status', 'loop_cancel'],
60
+ },
61
+ {
62
+ suffix: 'orchestrate',
63
+ description:
64
+ 'Execution orchestration — project registration, playbooks, plan/execute/complete.',
65
+ keyOps: ['orchestrate_plan', 'orchestrate_execute', 'orchestrate_complete'],
66
+ },
67
+ {
68
+ suffix: 'control',
69
+ description: 'Agent behavior — identity, intent routing, morphing, guidelines, governance.',
70
+ keyOps: ['route_intent', 'morph', 'get_behavior_rules'],
71
+ },
72
+ {
73
+ suffix: 'context',
74
+ description: 'Context analysis — entity extraction, knowledge retrieval, confidence scoring.',
75
+ keyOps: ['context_extract_entities', 'context_retrieve_knowledge', 'context_analyze'],
76
+ },
77
+ {
78
+ suffix: 'agency',
79
+ description: 'Proactive intelligence — file watching, pattern surfacing, warnings.',
80
+ keyOps: ['agency_scan_file', 'agency_surface_patterns', 'agency_warnings'],
81
+ },
82
+ {
83
+ suffix: 'chat',
84
+ description: 'Chat transport — session management, response chunking, authentication.',
85
+ keyOps: ['chat_send', 'chat_history', 'chat_session'],
86
+ },
87
+ {
88
+ suffix: 'cognee',
89
+ description: 'Knowledge graph — Cognee search, sync, export, graph stats.',
90
+ keyOps: ['cognee_search', 'cognee_add', 'cognee_cognify'],
91
+ conditional: true,
92
+ },
93
+ ];
94
+
95
+ /** Core facade ops (always present, not in ENGINE_MODULES) */
96
+ export const CORE_KEY_OPS = ['health', 'identity', 'register', 'activate'];
97
+
98
+ /** Engine major version — used for compatibility checks against domain packs. */
99
+ export const ENGINE_MAJOR_VERSION = 8;
@@ -32,7 +32,6 @@ import { createCuratorFacadeOps } from '../runtime/facades/curator-facade.js';
32
32
  import { createLoopFacadeOps } from '../runtime/facades/loop-facade.js';
33
33
  import { createOrchestrateFacadeOps } from '../runtime/facades/orchestrate-facade.js';
34
34
  import { createControlFacadeOps } from '../runtime/facades/control-facade.js';
35
- import { createCogneeFacadeOps } from '../runtime/facades/cognee-facade.js';
36
35
  import { createContextFacadeOps } from '../runtime/facades/context-facade.js';
37
36
  import { createAgencyFacadeOps } from '../runtime/facades/agency-facade.js';
38
37
  import { createChatFacadeOps } from '../runtime/facades/chat-facade.js';
@@ -60,6 +59,12 @@ export interface EngineRegistrationResult {
60
59
  tools: string[];
61
60
  /** Total op count across all tools */
62
61
  totalOps: number;
62
+ /**
63
+ * Register a new MCP tool at runtime (hot reload).
64
+ * Call this after installing a pack or activating a plugin post-boot.
65
+ * Automatically notifies connected clients via sendToolListChanged().
66
+ */
67
+ registerTool: (toolName: string, description: string, ops: OpDefinition[]) => void;
63
68
  }
64
69
 
65
70
  // ─── Module Definition ────────────────────────────────────────────────
@@ -75,7 +80,8 @@ interface ModuleDef {
75
80
  condition?: (runtime: AgentRuntime) => boolean;
76
81
  }
77
82
 
78
- const ENGINE_MODULES: ModuleDef[] = [
83
+ /** @internal Exported for drift testing — do not use outside engine */
84
+ export const ENGINE_MODULES: ModuleDef[] = [
79
85
  {
80
86
  suffix: 'vault',
81
87
  description: 'Knowledge management — search, CRUD, import/export, intake, archival.',
@@ -137,12 +143,6 @@ const ENGINE_MODULES: ModuleDef[] = [
137
143
  description: 'Chat transport — session management, response chunking, authentication.',
138
144
  createOps: createChatFacadeOps,
139
145
  },
140
- {
141
- suffix: 'cognee',
142
- description: 'Knowledge graph — Cognee search, sync, export, graph stats.',
143
- createOps: createCogneeFacadeOps,
144
- condition: (rt) => rt.cognee !== null && rt.cognee !== undefined,
145
- },
146
146
  ];
147
147
 
148
148
  // ─── Core Registration ────────────────────────────────────────────────
@@ -233,7 +233,19 @@ export function registerEngine(
233
233
  }
234
234
  }
235
235
 
236
- return { tools: registeredTools, totalOps };
236
+ const registerTool = (toolName: string, description: string, ops: OpDefinition[]) => {
237
+ registerModuleTool(server, toolName, description, ops, authPolicy);
238
+ registeredTools.push(toolName);
239
+ totalOps += ops.length;
240
+ // Notify connected clients that tool list changed
241
+ try {
242
+ (server as unknown as { sendToolListChanged?: () => void }).sendToolListChanged?.();
243
+ } catch {
244
+ // Server may not support notifications yet — safe to ignore
245
+ }
246
+ };
247
+
248
+ return { tools: registeredTools, totalOps, registerTool };
237
249
  }
238
250
 
239
251
  // ─── Tool Registration (No Factory) ──────────────────────────────────
package/src/index.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  // ─── Intelligence ────────────────────────────────────────────────────
2
- export type { IntelligenceEntry, IntelligenceBundle } from './intelligence/types.js';
2
+ export type {
3
+ IntelligenceEntry,
4
+ IntelligenceBundle,
5
+ IntelligenceBundleLink,
6
+ } from './intelligence/types.js';
3
7
  export { loadIntelligenceData, loadPacks } from './intelligence/loader.js';
4
8
 
5
9
  // ─── Vault ───────────────────────────────────────────────────────────
@@ -249,21 +253,6 @@ export type {
249
253
  BrowserToolResult,
250
254
  } from './chat/index.js';
251
255
 
252
- // ─── Cognee ─────────────────────────────────────────────────────────
253
- export { CogneeClient } from './cognee/client.js';
254
- export type {
255
- CogneeConfig,
256
- CogneeSearchResult,
257
- CogneeSearchType,
258
- CogneeStatus,
259
- CogneeAddResult,
260
- CogneeCognifyResult,
261
- } from './cognee/types.js';
262
-
263
- // ─── Cognee Sync ──────────────────────────────────────────────────────
264
- export { CogneeSyncManager } from './cognee/sync-manager.js';
265
- export type { SyncOp, SyncStatus, SyncQueueItem, SyncManagerStats } from './cognee/sync-manager.js';
266
-
267
256
  // ─── Intake Pipeline ──────────────────────────────────────────────────
268
257
  export { IntakePipeline } from './intake/intake-pipeline.js';
269
258
  export { classifyChunk, VALID_TYPES, CLASSIFICATION_PROMPT } from './intake/content-classifier.js';
@@ -489,6 +478,21 @@ export type {
489
478
  IntegrityResult,
490
479
  } from './health/index.js';
491
480
 
481
+ // ─── Persona ──────────────────────────────────────────────────────────
482
+ export type {
483
+ PersonaConfig,
484
+ ArchivedPersona,
485
+ PersonaCreateInput,
486
+ PersonaSystemInstructions,
487
+ } from './persona/types.js';
488
+ export {
489
+ ITALIAN_CRAFTSPERSON,
490
+ PERSONA_TEMPLATES,
491
+ createDefaultPersona,
492
+ } from './persona/defaults.js';
493
+ export { loadPersona } from './persona/loader.js';
494
+ export { generatePersonaInstructions, getRandomSignoff } from './persona/prompt-generator.js';
495
+
492
496
  // ─── Runtime Factory ────────────────────────────────────────────────
493
497
  export { createAgentRuntime } from './runtime/runtime.js';
494
498
  export { createSemanticFacades } from './runtime/facades/index.js';
@@ -541,7 +545,6 @@ export type {
541
545
 
542
546
  // ─── Persistence ───────────────────────────────────────────────────────
543
547
  export { SQLitePersistenceProvider } from './persistence/index.js';
544
- export { PostgresPersistenceProvider, translateSql } from './persistence/index.js';
545
548
  export type {
546
549
  PersistenceProvider,
547
550
  PersistenceParams,
@@ -60,8 +60,6 @@ export async function classifyChunk(
60
60
  ): Promise<ClassifiedItem[]> {
61
61
  try {
62
62
  const result = await llm.complete({
63
- provider: 'openai',
64
- model: 'gpt-4o-mini',
65
63
  systemPrompt: CLASSIFICATION_PROMPT,
66
64
  userPrompt: chunkText,
67
65
  maxTokens: 4096,
@@ -17,8 +17,16 @@ export interface IntelligenceEntry {
17
17
  validUntil?: number; // unix epoch — when entry expires (null = never)
18
18
  }
19
19
 
20
+ export interface IntelligenceBundleLink {
21
+ sourceId: string;
22
+ targetId: string;
23
+ linkType: 'supports' | 'contradicts' | 'extends' | 'sequences';
24
+ note?: string;
25
+ }
26
+
20
27
  export interface IntelligenceBundle {
21
28
  domain: string;
22
29
  version: string;
23
30
  entries: IntelligenceEntry[];
31
+ links?: IntelligenceBundleLink[];
24
32
  }
@@ -160,6 +160,8 @@ interface AnthropicClient {
160
160
  };
161
161
  }
162
162
 
163
+ type ResolvedLLMOptions = LLMCallOptions & { model: string; provider: 'openai' | 'anthropic' };
164
+
163
165
  export class LLMClient {
164
166
  private openaiKeyPool: KeyPool;
165
167
  private anthropicKeyPool: KeyPool;
@@ -181,11 +183,15 @@ export class LLMClient {
181
183
 
182
184
  async complete(options: LLMCallOptions): Promise<LLMCallResult> {
183
185
  const routed = this.router.resolve(options.caller, options.task, options.model);
184
- const resolvedOptions = { ...options, model: routed.model, provider: routed.provider };
186
+ const resolved: ResolvedLLMOptions = {
187
+ ...options,
188
+ model: options.model ?? routed.model,
189
+ provider: options.provider ?? routed.provider,
190
+ };
185
191
 
186
- return resolvedOptions.provider === 'anthropic'
187
- ? this.callAnthropic(resolvedOptions)
188
- : this.callOpenAI(resolvedOptions);
192
+ return resolved.provider === 'anthropic'
193
+ ? this.callAnthropic(resolved)
194
+ : this.callOpenAI(resolved);
189
195
  }
190
196
 
191
197
  isAvailable(): { openai: boolean; anthropic: boolean } {
@@ -203,7 +209,7 @@ export class LLMClient {
203
209
  // OPENAI
204
210
  // ===========================================================================
205
211
 
206
- private async callOpenAI(options: LLMCallOptions): Promise<LLMCallResult> {
212
+ private async callOpenAI(options: ResolvedLLMOptions): Promise<LLMCallResult> {
207
213
  const keyPool = this.openaiKeyPool.hasKeys ? this.openaiKeyPool : null;
208
214
 
209
215
  if (!keyPool) {
@@ -275,7 +281,7 @@ export class LLMClient {
275
281
  // ANTHROPIC
276
282
  // ===========================================================================
277
283
 
278
- private async callAnthropic(options: LLMCallOptions): Promise<LLMCallResult> {
284
+ private async callAnthropic(options: ResolvedLLMOptions): Promise<LLMCallResult> {
279
285
  const client = await this.getAnthropicClient();
280
286
  if (!client) {
281
287
  throw new LLMError('Anthropic API key not configured', { retryable: false });
@@ -43,24 +43,6 @@ export function discoverAnthropicToken(): string | null {
43
43
  return token;
44
44
  }
45
45
 
46
- /**
47
- * Clear the cached token (for testing or rotation).
48
- */
49
- export function resetTokenCache(): void {
50
- cachedToken = null;
51
- cacheTimestamp = 0;
52
- }
53
-
54
- /**
55
- * Get discovery source info (for diagnostics).
56
- */
57
- export function getTokenSource(): string {
58
- if (process.env.ANTHROPIC_API_KEY) return 'env:ANTHROPIC_API_KEY';
59
- if (tryCredentialsFile()) return 'file:credentials';
60
- if (tryPlatformKeychain()) return `keychain:${platform()}`;
61
- return 'none';
62
- }
63
-
64
46
  // ─── Discovery Methods ───────────────────────────────────────────────
65
47
 
66
48
  function tryEnvVar(): string | null {