@itaila/archetype 0.3.30

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 (319) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +475 -0
  3. package/dist/audit/audit-persona.d.ts +163 -0
  4. package/dist/audit/audit-persona.d.ts.map +1 -0
  5. package/dist/audit/audit-persona.js +415 -0
  6. package/dist/audit/audit-persona.js.map +1 -0
  7. package/dist/audit/brain-reflection.d.ts +33 -0
  8. package/dist/audit/brain-reflection.d.ts.map +1 -0
  9. package/dist/audit/brain-reflection.js +148 -0
  10. package/dist/audit/brain-reflection.js.map +1 -0
  11. package/dist/audit/conversation-audit.d.ts +12 -0
  12. package/dist/audit/conversation-audit.d.ts.map +1 -0
  13. package/dist/audit/conversation-audit.js +76 -0
  14. package/dist/audit/conversation-audit.js.map +1 -0
  15. package/dist/audit/prompt-audit.d.ts +10 -0
  16. package/dist/audit/prompt-audit.d.ts.map +1 -0
  17. package/dist/audit/prompt-audit.js +153 -0
  18. package/dist/audit/prompt-audit.js.map +1 -0
  19. package/dist/audit/prompt-dump.d.ts +137 -0
  20. package/dist/audit/prompt-dump.d.ts.map +1 -0
  21. package/dist/audit/prompt-dump.js +269 -0
  22. package/dist/audit/prompt-dump.js.map +1 -0
  23. package/dist/audit/trace-integrity.d.ts +33 -0
  24. package/dist/audit/trace-integrity.d.ts.map +1 -0
  25. package/dist/audit/trace-integrity.js +109 -0
  26. package/dist/audit/trace-integrity.js.map +1 -0
  27. package/dist/audit/types.d.ts +92 -0
  28. package/dist/audit/types.d.ts.map +1 -0
  29. package/dist/audit/types.js +2 -0
  30. package/dist/audit/types.js.map +1 -0
  31. package/dist/audit/version.d.ts +14 -0
  32. package/dist/audit/version.d.ts.map +1 -0
  33. package/dist/audit/version.js +65 -0
  34. package/dist/audit/version.js.map +1 -0
  35. package/dist/brain.d.ts +7 -0
  36. package/dist/brain.d.ts.map +1 -0
  37. package/dist/brain.js +83 -0
  38. package/dist/brain.js.map +1 -0
  39. package/dist/builder/actions.d.ts +60 -0
  40. package/dist/builder/actions.d.ts.map +1 -0
  41. package/dist/builder/actions.js +257 -0
  42. package/dist/builder/actions.js.map +1 -0
  43. package/dist/builder/browser.d.ts +140 -0
  44. package/dist/builder/browser.d.ts.map +1 -0
  45. package/dist/builder/browser.js +232 -0
  46. package/dist/builder/browser.js.map +1 -0
  47. package/dist/builder/executor.d.ts +228 -0
  48. package/dist/builder/executor.d.ts.map +1 -0
  49. package/dist/builder/executor.js +1548 -0
  50. package/dist/builder/executor.js.map +1 -0
  51. package/dist/builder/index.d.ts +24 -0
  52. package/dist/builder/index.d.ts.map +1 -0
  53. package/dist/builder/index.js +24 -0
  54. package/dist/builder/index.js.map +1 -0
  55. package/dist/builder/node-test-discovery.d.ts +13 -0
  56. package/dist/builder/node-test-discovery.d.ts.map +1 -0
  57. package/dist/builder/node-test-discovery.js +45 -0
  58. package/dist/builder/node-test-discovery.js.map +1 -0
  59. package/dist/builder/sandbox.d.ts +172 -0
  60. package/dist/builder/sandbox.d.ts.map +1 -0
  61. package/dist/builder/sandbox.js +294 -0
  62. package/dist/builder/sandbox.js.map +1 -0
  63. package/dist/builder/workspace-files.d.ts +63 -0
  64. package/dist/builder/workspace-files.d.ts.map +1 -0
  65. package/dist/builder/workspace-files.js +190 -0
  66. package/dist/builder/workspace-files.js.map +1 -0
  67. package/dist/core/actions.d.ts +55 -0
  68. package/dist/core/actions.d.ts.map +1 -0
  69. package/dist/core/actions.js +311 -0
  70. package/dist/core/actions.js.map +1 -0
  71. package/dist/core/attachment-notes.d.ts +7 -0
  72. package/dist/core/attachment-notes.d.ts.map +1 -0
  73. package/dist/core/attachment-notes.js +38 -0
  74. package/dist/core/attachment-notes.js.map +1 -0
  75. package/dist/core/context.d.ts +10 -0
  76. package/dist/core/context.d.ts.map +1 -0
  77. package/dist/core/context.js +108 -0
  78. package/dist/core/context.js.map +1 -0
  79. package/dist/core/crud-prompt.d.ts +16 -0
  80. package/dist/core/crud-prompt.d.ts.map +1 -0
  81. package/dist/core/crud-prompt.js +268 -0
  82. package/dist/core/crud-prompt.js.map +1 -0
  83. package/dist/core/crud-schema.d.ts +12 -0
  84. package/dist/core/crud-schema.d.ts.map +1 -0
  85. package/dist/core/crud-schema.js +42 -0
  86. package/dist/core/crud-schema.js.map +1 -0
  87. package/dist/core/effective-config.d.ts +13 -0
  88. package/dist/core/effective-config.d.ts.map +1 -0
  89. package/dist/core/effective-config.js +33 -0
  90. package/dist/core/effective-config.js.map +1 -0
  91. package/dist/core/entities.d.ts +82 -0
  92. package/dist/core/entities.d.ts.map +1 -0
  93. package/dist/core/entities.js +116 -0
  94. package/dist/core/entities.js.map +1 -0
  95. package/dist/core/entity-helpers.d.ts +47 -0
  96. package/dist/core/entity-helpers.d.ts.map +1 -0
  97. package/dist/core/entity-helpers.js +122 -0
  98. package/dist/core/entity-helpers.js.map +1 -0
  99. package/dist/core/entity-registry.d.ts +47 -0
  100. package/dist/core/entity-registry.d.ts.map +1 -0
  101. package/dist/core/entity-registry.js +54 -0
  102. package/dist/core/entity-registry.js.map +1 -0
  103. package/dist/core/eq.d.ts +13 -0
  104. package/dist/core/eq.d.ts.map +1 -0
  105. package/dist/core/eq.js +41 -0
  106. package/dist/core/eq.js.map +1 -0
  107. package/dist/core/focus-context.d.ts +19 -0
  108. package/dist/core/focus-context.d.ts.map +1 -0
  109. package/dist/core/focus-context.js +46 -0
  110. package/dist/core/focus-context.js.map +1 -0
  111. package/dist/core/focus-mode-actions.d.ts +23 -0
  112. package/dist/core/focus-mode-actions.d.ts.map +1 -0
  113. package/dist/core/focus-mode-actions.js +74 -0
  114. package/dist/core/focus-mode-actions.js.map +1 -0
  115. package/dist/core/greeting.d.ts +10 -0
  116. package/dist/core/greeting.d.ts.map +1 -0
  117. package/dist/core/greeting.js +41 -0
  118. package/dist/core/greeting.js.map +1 -0
  119. package/dist/core/identity.d.ts +13 -0
  120. package/dist/core/identity.d.ts.map +1 -0
  121. package/dist/core/identity.js +54 -0
  122. package/dist/core/identity.js.map +1 -0
  123. package/dist/core/knowledge.d.ts +10 -0
  124. package/dist/core/knowledge.d.ts.map +1 -0
  125. package/dist/core/knowledge.js +40 -0
  126. package/dist/core/knowledge.js.map +1 -0
  127. package/dist/core/memory-actions.d.ts +38 -0
  128. package/dist/core/memory-actions.d.ts.map +1 -0
  129. package/dist/core/memory-actions.js +181 -0
  130. package/dist/core/memory-actions.js.map +1 -0
  131. package/dist/core/memory.d.ts +35 -0
  132. package/dist/core/memory.d.ts.map +1 -0
  133. package/dist/core/memory.js +168 -0
  134. package/dist/core/memory.js.map +1 -0
  135. package/dist/core/peer-actions.d.ts +15 -0
  136. package/dist/core/peer-actions.d.ts.map +1 -0
  137. package/dist/core/peer-actions.js +33 -0
  138. package/dist/core/peer-actions.js.map +1 -0
  139. package/dist/core/prompt-builder.d.ts +46 -0
  140. package/dist/core/prompt-builder.d.ts.map +1 -0
  141. package/dist/core/prompt-builder.js +543 -0
  142. package/dist/core/prompt-builder.js.map +1 -0
  143. package/dist/core/prompt-mode.d.ts +3 -0
  144. package/dist/core/prompt-mode.d.ts.map +1 -0
  145. package/dist/core/prompt-mode.js +6 -0
  146. package/dist/core/prompt-mode.js.map +1 -0
  147. package/dist/core/prompted-turn.d.ts +6 -0
  148. package/dist/core/prompted-turn.d.ts.map +1 -0
  149. package/dist/core/prompted-turn.js +48 -0
  150. package/dist/core/prompted-turn.js.map +1 -0
  151. package/dist/core/request-builder.d.ts +14 -0
  152. package/dist/core/request-builder.d.ts.map +1 -0
  153. package/dist/core/request-builder.js +64 -0
  154. package/dist/core/request-builder.js.map +1 -0
  155. package/dist/core/session-routing.d.ts +23 -0
  156. package/dist/core/session-routing.d.ts.map +1 -0
  157. package/dist/core/session-routing.js +59 -0
  158. package/dist/core/session-routing.js.map +1 -0
  159. package/dist/core/voice.d.ts +6 -0
  160. package/dist/core/voice.d.ts.map +1 -0
  161. package/dist/core/voice.js +30 -0
  162. package/dist/core/voice.js.map +1 -0
  163. package/dist/engine/chat.d.ts +45 -0
  164. package/dist/engine/chat.d.ts.map +1 -0
  165. package/dist/engine/chat.js +308 -0
  166. package/dist/engine/chat.js.map +1 -0
  167. package/dist/engine/continuity.d.ts +107 -0
  168. package/dist/engine/continuity.d.ts.map +1 -0
  169. package/dist/engine/continuity.js +320 -0
  170. package/dist/engine/continuity.js.map +1 -0
  171. package/dist/engine/crud.d.ts +62 -0
  172. package/dist/engine/crud.d.ts.map +1 -0
  173. package/dist/engine/crud.js +260 -0
  174. package/dist/engine/crud.js.map +1 -0
  175. package/dist/engine/side-effects.d.ts +93 -0
  176. package/dist/engine/side-effects.d.ts.map +1 -0
  177. package/dist/engine/side-effects.js +271 -0
  178. package/dist/engine/side-effects.js.map +1 -0
  179. package/dist/engine/staging.d.ts +29 -0
  180. package/dist/engine/staging.d.ts.map +1 -0
  181. package/dist/engine/staging.js +159 -0
  182. package/dist/engine/staging.js.map +1 -0
  183. package/dist/engine/working-set.d.ts +18 -0
  184. package/dist/engine/working-set.d.ts.map +1 -0
  185. package/dist/engine/working-set.js +246 -0
  186. package/dist/engine/working-set.js.map +1 -0
  187. package/dist/evals/action-contracts.d.ts +40 -0
  188. package/dist/evals/action-contracts.d.ts.map +1 -0
  189. package/dist/evals/action-contracts.js +208 -0
  190. package/dist/evals/action-contracts.js.map +1 -0
  191. package/dist/evals/brain-bloat.d.ts +39 -0
  192. package/dist/evals/brain-bloat.d.ts.map +1 -0
  193. package/dist/evals/brain-bloat.js +167 -0
  194. package/dist/evals/brain-bloat.js.map +1 -0
  195. package/dist/evals/brain-prescriptions.d.ts +30 -0
  196. package/dist/evals/brain-prescriptions.d.ts.map +1 -0
  197. package/dist/evals/brain-prescriptions.js +148 -0
  198. package/dist/evals/brain-prescriptions.js.map +1 -0
  199. package/dist/evals/cross-layer-duplicates.d.ts +49 -0
  200. package/dist/evals/cross-layer-duplicates.d.ts.map +1 -0
  201. package/dist/evals/cross-layer-duplicates.js +289 -0
  202. package/dist/evals/cross-layer-duplicates.js.map +1 -0
  203. package/dist/evals/entity-visibility.d.ts +28 -0
  204. package/dist/evals/entity-visibility.d.ts.map +1 -0
  205. package/dist/evals/entity-visibility.js +216 -0
  206. package/dist/evals/entity-visibility.js.map +1 -0
  207. package/dist/evals/index.d.ts +19 -0
  208. package/dist/evals/index.d.ts.map +1 -0
  209. package/dist/evals/index.js +11 -0
  210. package/dist/evals/index.js.map +1 -0
  211. package/dist/evals/judge.d.ts +22 -0
  212. package/dist/evals/judge.d.ts.map +1 -0
  213. package/dist/evals/judge.js +337 -0
  214. package/dist/evals/judge.js.map +1 -0
  215. package/dist/evals/operational-contract.d.ts +40 -0
  216. package/dist/evals/operational-contract.d.ts.map +1 -0
  217. package/dist/evals/operational-contract.js +115 -0
  218. package/dist/evals/operational-contract.js.map +1 -0
  219. package/dist/evals/prompt-content.d.ts +14 -0
  220. package/dist/evals/prompt-content.d.ts.map +1 -0
  221. package/dist/evals/prompt-content.js +104 -0
  222. package/dist/evals/prompt-content.js.map +1 -0
  223. package/dist/evals/runtime.d.ts +4 -0
  224. package/dist/evals/runtime.d.ts.map +1 -0
  225. package/dist/evals/runtime.js +197 -0
  226. package/dist/evals/runtime.js.map +1 -0
  227. package/dist/evals/sample-projects.d.ts +143 -0
  228. package/dist/evals/sample-projects.d.ts.map +1 -0
  229. package/dist/evals/sample-projects.js +644 -0
  230. package/dist/evals/sample-projects.js.map +1 -0
  231. package/dist/evals/types.d.ts +88 -0
  232. package/dist/evals/types.d.ts.map +1 -0
  233. package/dist/evals/types.js +2 -0
  234. package/dist/evals/types.js.map +1 -0
  235. package/dist/foundation/index.d.ts +158 -0
  236. package/dist/foundation/index.d.ts.map +1 -0
  237. package/dist/foundation/index.js +256 -0
  238. package/dist/foundation/index.js.map +1 -0
  239. package/dist/index.d.ts +223 -0
  240. package/dist/index.d.ts.map +1 -0
  241. package/dist/index.js +998 -0
  242. package/dist/index.js.map +1 -0
  243. package/dist/managed/autonomous-loop.d.ts +199 -0
  244. package/dist/managed/autonomous-loop.d.ts.map +1 -0
  245. package/dist/managed/autonomous-loop.js +451 -0
  246. package/dist/managed/autonomous-loop.js.map +1 -0
  247. package/dist/managed/conversation.d.ts +20 -0
  248. package/dist/managed/conversation.d.ts.map +1 -0
  249. package/dist/managed/conversation.js +40 -0
  250. package/dist/managed/conversation.js.map +1 -0
  251. package/dist/managed/knowledge.d.ts +7 -0
  252. package/dist/managed/knowledge.d.ts.map +1 -0
  253. package/dist/managed/knowledge.js +174 -0
  254. package/dist/managed/knowledge.js.map +1 -0
  255. package/dist/managed/memory-manager.d.ts +7 -0
  256. package/dist/managed/memory-manager.d.ts.map +1 -0
  257. package/dist/managed/memory-manager.js +18 -0
  258. package/dist/managed/memory-manager.js.map +1 -0
  259. package/dist/managed/memory-review.d.ts +45 -0
  260. package/dist/managed/memory-review.d.ts.map +1 -0
  261. package/dist/managed/memory-review.js +130 -0
  262. package/dist/managed/memory-review.js.map +1 -0
  263. package/dist/managed/storage.d.ts +2 -0
  264. package/dist/managed/storage.d.ts.map +1 -0
  265. package/dist/managed/storage.js +2 -0
  266. package/dist/managed/storage.js.map +1 -0
  267. package/dist/managed/work-history.d.ts +23 -0
  268. package/dist/managed/work-history.d.ts.map +1 -0
  269. package/dist/managed/work-history.js +31 -0
  270. package/dist/managed/work-history.js.map +1 -0
  271. package/dist/observability/index.d.ts +15 -0
  272. package/dist/observability/index.d.ts.map +1 -0
  273. package/dist/observability/index.js +15 -0
  274. package/dist/observability/index.js.map +1 -0
  275. package/dist/observability/render-run-markdown.d.ts +90 -0
  276. package/dist/observability/render-run-markdown.d.ts.map +1 -0
  277. package/dist/observability/render-run-markdown.js +231 -0
  278. package/dist/observability/render-run-markdown.js.map +1 -0
  279. package/dist/observability/turn-reporter.d.ts +20 -0
  280. package/dist/observability/turn-reporter.d.ts.map +1 -0
  281. package/dist/observability/turn-reporter.js +106 -0
  282. package/dist/observability/turn-reporter.js.map +1 -0
  283. package/dist/persona.d.ts +49 -0
  284. package/dist/persona.d.ts.map +1 -0
  285. package/dist/persona.js +287 -0
  286. package/dist/persona.js.map +1 -0
  287. package/dist/playbook/defaults.d.ts +25 -0
  288. package/dist/playbook/defaults.d.ts.map +1 -0
  289. package/dist/playbook/defaults.js +108 -0
  290. package/dist/playbook/defaults.js.map +1 -0
  291. package/dist/playbook/invariants.d.ts +244 -0
  292. package/dist/playbook/invariants.d.ts.map +1 -0
  293. package/dist/playbook/invariants.js +259 -0
  294. package/dist/playbook/invariants.js.map +1 -0
  295. package/dist/playbook/templates.d.ts +7 -0
  296. package/dist/playbook/templates.d.ts.map +1 -0
  297. package/dist/playbook/templates.js +437 -0
  298. package/dist/playbook/templates.js.map +1 -0
  299. package/dist/providers/gemini.d.ts +73 -0
  300. package/dist/providers/gemini.d.ts.map +1 -0
  301. package/dist/providers/gemini.js +536 -0
  302. package/dist/providers/gemini.js.map +1 -0
  303. package/dist/providers/types.d.ts +2 -0
  304. package/dist/providers/types.d.ts.map +1 -0
  305. package/dist/providers/types.js +2 -0
  306. package/dist/providers/types.js.map +1 -0
  307. package/dist/providers/zod-to-gemini.d.ts +8 -0
  308. package/dist/providers/zod-to-gemini.d.ts.map +1 -0
  309. package/dist/providers/zod-to-gemini.js +148 -0
  310. package/dist/providers/zod-to-gemini.js.map +1 -0
  311. package/dist/samples/pm-spec-agent.d.ts +22 -0
  312. package/dist/samples/pm-spec-agent.d.ts.map +1 -0
  313. package/dist/samples/pm-spec-agent.js +53 -0
  314. package/dist/samples/pm-spec-agent.js.map +1 -0
  315. package/dist/types.d.ts +920 -0
  316. package/dist/types.d.ts.map +1 -0
  317. package/dist/types.js +2 -0
  318. package/dist/types.js.map +1 -0
  319. package/package.json +68 -0
package/dist/index.js ADDED
@@ -0,0 +1,998 @@
1
+ import { PersonaEngine } from './persona.js';
2
+ import { resolveConversation, loadHistory, loadAttachmentCarryForwardSections, endConversation } from './managed/conversation.js';
3
+ import { loadMemories, expandPromptMemoryLoadBudget } from './managed/memory-manager.js';
4
+ import { reviewMemories as reviewMemoriesFn } from './managed/memory-review.js';
5
+ import { MEMORY_ACTION_NAMES, CRAFT_MEMORY_ACTION_NAMES } from './core/memory-actions.js';
6
+ import { executeSideEffects } from './engine/side-effects.js';
7
+ import { resolveActions } from './core/effective-config.js';
8
+ import { buildPeerAction, PEER_ACTION_NAME, PEER_ACTION_NAMES } from './core/peer-actions.js';
9
+ import { buildAnnotations, buildPeerAnnotation } from './core/actions.js';
10
+ import { buildAssistantContinuityMessage } from './engine/continuity.js';
11
+ import { commitCrud, crudActionToAnnotation, resolveTempIds } from './engine/crud.js';
12
+ import { buildAttachmentCarryForwardMessage } from './core/attachment-notes.js';
13
+ import { commitWorkingSet as commitWorkingSetEngine, reviewWorkingSetDelta as reviewWorkingSetDeltaEngine, summarizeWorkingSet, usesWorkingSet, } from './engine/working-set.js';
14
+ export { archetype, auditFoundationSourceBoundary, foundationLowLevelImports, foundationPromptKnobs, rejectPromptKnobs, } from './foundation/index.js';
15
+ // ─── Trace utilities ────────────────────────────────────────────────────────
16
+ /**
17
+ * Extract alerts from a TurnTrace — scan for failures and return severity-tagged entries.
18
+ * Use this to surface problems in admin panels, chat debug cards, or console output.
19
+ */
20
+ export function extractAlerts(trace) {
21
+ const alerts = [];
22
+ if (!trace.parseOk) {
23
+ alerts.push({ severity: 'error', message: 'Failed to parse LLM response as JSON' });
24
+ }
25
+ for (const error of trace.errors) {
26
+ if (error.includes('legacy top-level "crudActions" key')) {
27
+ alerts.push({ severity: 'warn', message: error });
28
+ }
29
+ }
30
+ for (const a of trace.actions) {
31
+ if (a.status === 'unknown_action') {
32
+ alerts.push({ severity: 'error', message: `Unknown action "${a.name}" — not defined in persona config`, action: a.name });
33
+ }
34
+ else if (a.status === 'invalid') {
35
+ alerts.push({ severity: 'warn', message: `Action "${a.name}" failed validation: ${a.error ?? 'unknown'}`, action: a.name });
36
+ }
37
+ }
38
+ for (const c of trace.crudActions) {
39
+ if (c.status === 'invalid') {
40
+ alerts.push({ severity: 'warn', message: `CRUD ${c.operation} ${c.entity} failed validation: ${c.error ?? 'unknown'}`, action: `${c.operation} ${c.entity}` });
41
+ }
42
+ }
43
+ for (const e of trace.executionResults) {
44
+ if (e.status === 'failed') {
45
+ alerts.push({ severity: 'error', message: `CRUD ${e.operation} ${e.entity} failed execution: ${e.error ?? 'unknown'}`, action: `${e.operation} ${e.entity}` });
46
+ }
47
+ }
48
+ for (const d of trace.domainActions) {
49
+ if (d.status === 'failed') {
50
+ alerts.push({ severity: 'error', message: `Domain action "${d.name}" failed: ${d.error ?? 'unknown'}`, action: d.name });
51
+ }
52
+ }
53
+ // Check peer consultations for failures
54
+ if (trace.peerConsultations) {
55
+ for (const pc of trace.peerConsultations) {
56
+ const peerAlerts = extractAlerts(pc.trace);
57
+ for (const pa of peerAlerts) {
58
+ alerts.push({ severity: pa.severity, message: `[peer:${pc.peer}] ${pa.message}`, action: pa.action });
59
+ }
60
+ }
61
+ }
62
+ return alerts;
63
+ }
64
+ /**
65
+ * Summarize a TurnTrace into a structured object for chat debug cards and admin views.
66
+ * Returns the full story — outcome notes, action details, pipeline sections — not just counts.
67
+ * This is the rendering contract: what this function returns is what the UI should show.
68
+ */
69
+ export function summarizeTrace(trace) {
70
+ const alerts = extractAlerts(trace);
71
+ const allItems = [...trace.actions, ...trace.crudActions, ...trace.executionResults, ...trace.domainActions];
72
+ const failedCount = allItems.filter(a => a.status === 'invalid' || a.status === 'failed' || a.status === 'unknown_action').length;
73
+ return {
74
+ traceId: trace.traceId,
75
+ personaId: trace.personaId,
76
+ correlationId: trace.correlationId,
77
+ durationMs: trace.completedAt ? trace.completedAt - trace.startedAt : null,
78
+ parseOk: trace.parseOk,
79
+ repairAttempted: trace.repairAttempted,
80
+ repairSucceeded: trace.repairSucceeded,
81
+ alerts,
82
+ outcomeNotes: trace.outcomeNotes,
83
+ actions: trace.actions,
84
+ crudActions: trace.crudActions,
85
+ executionResults: trace.executionResults,
86
+ domainActions: trace.domainActions,
87
+ peerConsultations: trace.peerConsultations?.map(pc => ({
88
+ peer: pc.peer,
89
+ query: pc.query.slice(0, 200),
90
+ durationMs: pc.durationMs,
91
+ alertCount: extractAlerts(pc.trace).length,
92
+ })),
93
+ errors: trace.errors,
94
+ actionCount: allItems.length,
95
+ failedCount,
96
+ };
97
+ }
98
+ function logTraceAlerts(trace) {
99
+ const alerts = extractAlerts(trace);
100
+ for (const alert of alerts) {
101
+ const prefix = alert.severity === 'error'
102
+ ? '\x1b[31m[ARCHETYPE ALERT]\x1b[0m'
103
+ : '\x1b[33m[ARCHETYPE WARN]\x1b[0m';
104
+ console[alert.severity === 'error' ? 'error' : 'warn'](`${prefix} ${alert.message}`);
105
+ }
106
+ }
107
+ function createTracePersister(adapter) {
108
+ let warned = false;
109
+ return async (conversationId, trace) => {
110
+ if (adapter.saveTrace) {
111
+ await adapter.saveTrace(conversationId, trace);
112
+ }
113
+ else if (!warned) {
114
+ console.warn('[archetype] Trace persistence unavailable — implement saveTrace() on StorageAdapter');
115
+ warned = true;
116
+ }
117
+ };
118
+ }
119
+ // ─── Public API ──────────────────────────────────────────────────────────────
120
+ /**
121
+ * Define a persona from config. Returns a PersonaEngine for stateless chat.
122
+ */
123
+ export function definePersona(config) {
124
+ return new PersonaEngine(config);
125
+ }
126
+ /**
127
+ * Wrap a persona engine with a storage adapter for auto-persisting
128
+ * conversations and memories. Layer 2 — opt-in.
129
+ */
130
+ export function withStorage(engine, options) {
131
+ const { adapter, historyLimit = 30, memoryBudget = 8000, craftMemoryBudget = 3000, retrospect: retrospectConfig, memoryReview: reviewConfig, knowledge, peers, } = options;
132
+ // When peers are configured, create a peer-aware engine with consultPeer action merged in.
133
+ // This ensures the prompt includes peer descriptions and validation works against the schema.
134
+ const effectiveEngine = peers && Object.keys(peers).length > 0
135
+ ? new PersonaEngine({
136
+ ...engine.config,
137
+ actions: { ...(engine.config.actions ?? {}), ...buildPeerAction(peers) },
138
+ })
139
+ : engine;
140
+ const persistTrace = createTracePersister(adapter);
141
+ // ─── Auto memory review state ──────────────────────────────────────────────
142
+ let lastReviewedAt = null;
143
+ let reviewInFlight = false;
144
+ const shouldAutoReview = () => {
145
+ if (!reviewConfig?.auto)
146
+ return false;
147
+ if (reviewInFlight)
148
+ return false;
149
+ if (lastReviewedAt === null)
150
+ return true; // first run since startup
151
+ const intervalMs = (reviewConfig.interval ?? 7) * 86400000;
152
+ return Date.now() - lastReviewedAt >= intervalMs;
153
+ };
154
+ const runAutoReview = async () => {
155
+ reviewInFlight = true;
156
+ try {
157
+ // User memories
158
+ const result = await reviewMemoriesFn({
159
+ adapter,
160
+ provider: engine.config.provider,
161
+ maxAge: reviewConfig?.maxAge ?? 7,
162
+ preservePinned: reviewConfig?.preservePinned ?? true,
163
+ memoryPurpose: engine.config.memory?.purpose,
164
+ categoryDescriptions: engine.config.memory?.categories,
165
+ scope: 'user',
166
+ });
167
+ if (result.removed > 0) {
168
+ console.log(`[archetype] Reviewed user memories: ${result.removed} → ${result.created}`);
169
+ }
170
+ // Craft memories (if enabled)
171
+ if (engine.config.craftMemory?.enabled && adapter.loadCraftMemories) {
172
+ const craftResult = await reviewMemoriesFn({
173
+ adapter,
174
+ provider: engine.config.provider,
175
+ maxAge: reviewConfig?.maxAge ?? 7,
176
+ preservePinned: reviewConfig?.preservePinned ?? true,
177
+ memoryPurpose: engine.config.craftMemory.purpose,
178
+ categoryDescriptions: engine.config.craftMemory.categories,
179
+ scope: 'craft',
180
+ });
181
+ if (craftResult.removed > 0) {
182
+ console.log(`[archetype] Reviewed craft memories: ${craftResult.removed} → ${craftResult.created}`);
183
+ }
184
+ }
185
+ lastReviewedAt = Date.now();
186
+ }
187
+ catch (err) {
188
+ console.error('[archetype] Auto memory review failed:', err instanceof Error ? err.message : err);
189
+ }
190
+ finally {
191
+ reviewInFlight = false;
192
+ }
193
+ };
194
+ /**
195
+ * Check if auto-retrospective should run based on the last message timestamp.
196
+ * Returns true if the last assistant/user message is from a previous calendar day.
197
+ */
198
+ const shouldAutoRetrospect = (history, timezone) => {
199
+ if (!retrospectConfig?.auto)
200
+ return false;
201
+ if (history.length === 0)
202
+ return false;
203
+ // Find the last non-note message with a timestamp
204
+ const lastMsg = [...history].reverse().find(m => m.createdAt);
205
+ if (!lastMsg?.createdAt)
206
+ return false;
207
+ const lastDate = timezone
208
+ ? new Date(lastMsg.createdAt).toLocaleDateString('en-CA', { timeZone: timezone })
209
+ : new Date(lastMsg.createdAt).toISOString().slice(0, 10);
210
+ const today = timezone
211
+ ? new Date().toLocaleDateString('en-CA', { timeZone: timezone })
212
+ : new Date().toISOString().slice(0, 10);
213
+ return lastDate !== today;
214
+ };
215
+ const loadCraftMemories = async () => {
216
+ if (!engine.config.craftMemory?.enabled || !adapter.loadCraftMemories)
217
+ return [];
218
+ return adapter.loadCraftMemories({ budget: expandPromptMemoryLoadBudget(craftMemoryBudget) });
219
+ };
220
+ const loadKnowledgeDocuments = async (input) => {
221
+ if (!knowledge?.adapter)
222
+ return [];
223
+ const query = knowledge.buildQuery?.(input) ?? defaultKnowledgeQuery(input);
224
+ if (!query)
225
+ return [];
226
+ return knowledge.adapter.searchDocuments({
227
+ query,
228
+ budget: knowledge.budget ?? effectiveEngine.config.knowledge?.budget,
229
+ maxDocuments: knowledge.maxDocuments ?? effectiveEngine.config.knowledge?.maxDocuments,
230
+ });
231
+ };
232
+ const runPreTurnMaintenance = async (input) => {
233
+ if (retrospectConfig?.auto) {
234
+ const rawMessages = input.rawMessages ?? await adapter.getMessages(input.conversationId, historyLimit);
235
+ if (shouldAutoRetrospect(rawMessages, input.timezone)) {
236
+ const historyForRetrospect = rawMessages
237
+ .filter(m => !m.isNote && (m.role === 'user' || m.role === 'assistant'))
238
+ .map(m => ({ role: m.role, content: m.content }));
239
+ try {
240
+ await runRetrospect({
241
+ conversationId: input.conversationId,
242
+ context: input.context,
243
+ timezone: input.timezone,
244
+ promptNow: input.promptNow,
245
+ userIdentity: input.userIdentity,
246
+ locale: input.locale,
247
+ directives: input.directives,
248
+ promptMode: input.promptMode,
249
+ promptScaffold: input.promptScaffold,
250
+ extraSystemSections: input.extraSystemSections,
251
+ guidelines: retrospectConfig.guidelines,
252
+ history: historyForRetrospect,
253
+ });
254
+ }
255
+ catch (err) {
256
+ console.error('[archetype] Auto retrospective failed:', err instanceof Error ? err.message : err);
257
+ }
258
+ }
259
+ }
260
+ if (shouldAutoReview()) {
261
+ await runAutoReview();
262
+ }
263
+ };
264
+ const loadManagedTurnState = async (conversationId, knowledgeInput) => {
265
+ const history = await loadHistory(adapter, conversationId, historyLimit);
266
+ const attachmentSections = await loadAttachmentCarryForwardSections(adapter, conversationId, historyLimit);
267
+ const workingSet = usesWorkingSet(effectiveEngine.config)
268
+ ? await loadManagedWorkingSet(adapter, conversationId)
269
+ : null;
270
+ const memories = await loadMemories(adapter, memoryBudget);
271
+ const knowledgeDocuments = knowledgeInput ? await loadKnowledgeDocuments({ ...knowledgeInput, history }) : [];
272
+ const craftMemories = await loadCraftMemories();
273
+ return { history, attachmentSections, workingSet, memories, knowledgeDocuments, craftMemories };
274
+ };
275
+ const executeManagedMemorySideEffects = async (result, options) => {
276
+ const executedCrudAnnotations = [];
277
+ const executedMemoryActionNames = new Set();
278
+ const actionOutcomes = [];
279
+ const memoryCrudEntities = new Set(['memory', 'craftMemory']);
280
+ const trace = result.trace;
281
+ if (result.crudActions && result.crudActions.length > 0) {
282
+ const resolvedCrud = resolveTempIds(result.crudActions);
283
+ const memoryCrudActions = resolvedCrud.filter(action => memoryCrudEntities.has(action.entity));
284
+ const memoryCrudHandler = buildMemoryCrudHandler(adapter);
285
+ const craftCrudHandler = buildCraftMemoryCrudHandler(adapter);
286
+ for (const crudAction of memoryCrudActions) {
287
+ try {
288
+ if (crudAction.entity === 'memory') {
289
+ await memoryCrudHandler(crudAction);
290
+ }
291
+ else if (crudAction.entity === 'craftMemory') {
292
+ await craftCrudHandler(crudAction);
293
+ }
294
+ if (options?.annotateCrud) {
295
+ executedCrudAnnotations.push(crudActionToAnnotation(crudAction, {
296
+ memory: { schema: {}, label: 'Memory', displayField: 'content' },
297
+ craftMemory: { schema: {}, label: 'Craft Memory', displayField: 'content' },
298
+ }));
299
+ }
300
+ trace.executionResults.push({
301
+ operation: crudAction.operation,
302
+ entity: crudAction.entity,
303
+ id: crudAction.id,
304
+ params: crudAction.params ?? {},
305
+ status: 'executed',
306
+ });
307
+ actionOutcomes.push({
308
+ outcomeNote: crudOutcomeNote(crudAction, 'executed'),
309
+ status: 'executed',
310
+ success: true,
311
+ });
312
+ }
313
+ catch (err) {
314
+ const errorMsg = err instanceof Error ? err.message : String(err);
315
+ console.warn(`[archetype] Memory CRUD failed: ${crudAction.operation} ${crudAction.entity}: ${errorMsg}`);
316
+ trace.executionResults.push({
317
+ operation: crudAction.operation,
318
+ entity: crudAction.entity,
319
+ id: crudAction.id,
320
+ params: crudAction.params ?? {},
321
+ status: 'failed',
322
+ error: errorMsg,
323
+ });
324
+ actionOutcomes.push({
325
+ outcomeNote: crudOutcomeNote(crudAction, 'failed', errorMsg),
326
+ status: 'failed',
327
+ success: false,
328
+ error: errorMsg,
329
+ });
330
+ }
331
+ }
332
+ }
333
+ if (result.actions.length > 0) {
334
+ const legacyMemoryActions = result.actions.filter(action => MEMORY_ACTION_NAMES.has(action.name) || CRAFT_MEMORY_ACTION_NAMES.has(action.name));
335
+ if (legacyMemoryActions.length > 0) {
336
+ const allHandlers = { ...buildMemoryHandlers(adapter), ...buildCraftMemoryHandlers(adapter) };
337
+ const effectiveActions = resolveActions(effectiveEngine.config) ?? {};
338
+ const legacyResults = await executeSideEffects(legacyMemoryActions, allHandlers, effectiveActions);
339
+ for (const legacyResult of legacyResults) {
340
+ if (legacyResult.status === 'executed' && legacyResult.success) {
341
+ executedMemoryActionNames.add(legacyResult.action.name);
342
+ }
343
+ actionOutcomes.push({
344
+ action: legacyResult.action,
345
+ status: legacyResult.status,
346
+ success: legacyResult.success,
347
+ error: legacyResult.error,
348
+ annotation: legacyResult.annotation,
349
+ });
350
+ }
351
+ }
352
+ }
353
+ return { executedCrudAnnotations, executedMemoryActionNames, actionOutcomes };
354
+ };
355
+ const executeManagedDomainCrud = async (result, domainCrud) => {
356
+ if (!domainCrud || !result.crudActions || result.crudActions.length === 0) {
357
+ return { actionOutcomes: [], results: [] };
358
+ }
359
+ const sdkCrudEntities = new Set(['memory', 'craftMemory']);
360
+ const resolvedCrud = resolveTempIds(result.crudActions);
361
+ const domainActions = resolvedCrud.filter(action => !sdkCrudEntities.has(action.entity));
362
+ if (domainActions.length === 0)
363
+ return { actionOutcomes: [], results: [] };
364
+ const preparedActions = domainCrud.prepare ? await domainCrud.prepare(domainActions) : domainActions;
365
+ const results = await commitCrud(preparedActions, domainCrud.handlers, { trace: result.trace });
366
+ const customNotes = domainCrud.summarize
367
+ ? (await domainCrud.summarize({ actions: preparedActions, results }))
368
+ .map(note => note.trim())
369
+ .filter(Boolean)
370
+ : [];
371
+ const fallbackOutcomes = preparedActions.map((action, index) => {
372
+ const result = results[index];
373
+ const success = Boolean(result?.success);
374
+ return {
375
+ outcomeNote: crudOutcomeNote(action, success ? 'executed' : 'failed', result?.error),
376
+ status: success ? 'executed' : 'failed',
377
+ success,
378
+ error: result?.error,
379
+ };
380
+ });
381
+ const actionOutcomes = customNotes.length > 0
382
+ ? [
383
+ ...customNotes.map((note) => ({
384
+ outcomeNote: note,
385
+ status: 'executed',
386
+ success: true,
387
+ })),
388
+ ...fallbackOutcomes.filter(outcome => outcome.success === false),
389
+ ]
390
+ : fallbackOutcomes;
391
+ return { actionOutcomes, results };
392
+ };
393
+ const finalizeManagedTurn = async (params) => {
394
+ await adapter.saveMessage(params.conversationId, {
395
+ role: 'assistant',
396
+ content: params.assistantContent,
397
+ actionsJson: params.actionsJson ?? null,
398
+ isNote: false,
399
+ });
400
+ if (params.saveAttachmentNotes && params.result.attachmentNotes && params.result.attachmentNotes.length > 0) {
401
+ await adapter.saveMessage(params.conversationId, {
402
+ role: 'system',
403
+ content: buildAttachmentCarryForwardMessage(params.result.attachmentNotes),
404
+ isNote: true,
405
+ });
406
+ }
407
+ const trace = params.result.trace;
408
+ trace.completedAt = Date.now();
409
+ logTraceAlerts(trace);
410
+ await persistTrace(params.conversationId, trace);
411
+ return {
412
+ ...params.result,
413
+ crudActions: stripSdkCrudActions(params.result.crudActions),
414
+ conversationId: params.conversationId,
415
+ };
416
+ };
417
+ const runPromptedTurn = async (input) => {
418
+ const conversationId = await resolveConversation(adapter, input.conversationId, input.trigger ?? 'prompted_turn', input.metadata);
419
+ await runPreTurnMaintenance({
420
+ conversationId,
421
+ context: input.context,
422
+ timezone: input.timezone,
423
+ promptNow: input.promptNow,
424
+ userIdentity: input.userIdentity,
425
+ locale: input.locale,
426
+ directives: input.directives,
427
+ promptMode: input.promptMode,
428
+ promptScaffold: input.promptScaffold,
429
+ extraSystemSections: input.extraSystemSections,
430
+ });
431
+ const { history, attachmentSections, workingSet, memories, knowledgeDocuments, craftMemories } = await loadManagedTurnState(conversationId, {
432
+ mode: 'prompted-turn',
433
+ intent: input.intent,
434
+ context: input.context,
435
+ history: input.history,
436
+ userIdentity: input.userIdentity,
437
+ });
438
+ const result = await effectiveEngine.promptedTurn({
439
+ intent: input.intent,
440
+ label: input.label,
441
+ timezone: input.timezone,
442
+ promptNow: input.promptNow,
443
+ userIdentity: input.userIdentity,
444
+ locale: input.locale,
445
+ memories,
446
+ knowledgeDocuments: input.knowledgeDocuments ?? knowledgeDocuments,
447
+ craftMemories,
448
+ context: input.context,
449
+ turnKind: input.turnKind,
450
+ promptMode: input.promptMode,
451
+ directives: input.directives,
452
+ promptScaffold: input.promptScaffold,
453
+ guidelines: input.guidelines,
454
+ extraSystemSections: [...attachmentSections, ...(input.extraSystemSections ?? [])],
455
+ history: input.history ?? history,
456
+ workingSet,
457
+ crudValidation: input.crudValidation,
458
+ crudValidationRetries: input.crudValidationRetries,
459
+ });
460
+ if (usesWorkingSet(effectiveEngine.config) && result.workingSet) {
461
+ await saveManagedWorkingSet(adapter, conversationId, result.workingSet);
462
+ }
463
+ const memoryEffects = await executeManagedMemorySideEffects(result, { annotateCrud: true });
464
+ const domainEffects = await executeManagedDomainCrud(result, input.domainCrud);
465
+ const persistedActions = selectPersistedActions(effectiveEngine.config, result.actions);
466
+ const isSdkAction = (name) => MEMORY_ACTION_NAMES.has(name) || CRAFT_MEMORY_ACTION_NAMES.has(name) || PEER_ACTION_NAMES.has(name);
467
+ const annotatedActions = persistedActions.filter(action => !isSdkAction(action.name) || memoryEffects.executedMemoryActionNames.has(action.name));
468
+ const actionAnnotations = annotatedActions.length > 0
469
+ ? buildAnnotations(annotatedActions.map(action => ({ name: action.name, params: action.params })))
470
+ : [];
471
+ const annotatedContent = buildAssistantContinuityMessage({
472
+ message: result.message,
473
+ modelOutcomeNotes: result.outcomeNotes,
474
+ actionOutcomes: [...memoryEffects.actionOutcomes, ...domainEffects.actionOutcomes],
475
+ actionAnnotations: [...actionAnnotations, ...memoryEffects.executedCrudAnnotations],
476
+ });
477
+ return finalizeManagedTurn({
478
+ conversationId,
479
+ result,
480
+ assistantContent: annotatedContent,
481
+ actionsJson: annotatedActions.length > 0 ? JSON.stringify(annotatedActions) : null,
482
+ saveAttachmentNotes: true,
483
+ });
484
+ };
485
+ const runRetrospect = async (input) => {
486
+ const memories = await loadMemories(adapter, memoryBudget);
487
+ const historyConversationId = input.conversationId
488
+ ?? (await adapter.getActiveConversation())?.id
489
+ ?? null;
490
+ let history = input.history ?? [];
491
+ if (history.length === 0) {
492
+ history = historyConversationId
493
+ ? await loadHistory(adapter, historyConversationId, historyLimit)
494
+ : [];
495
+ }
496
+ const attachmentSections = historyConversationId
497
+ ? await loadAttachmentCarryForwardSections(adapter, historyConversationId, historyLimit)
498
+ : [];
499
+ const knowledgeDocuments = input.knowledgeDocuments ?? await loadKnowledgeDocuments({
500
+ mode: 'retrospect',
501
+ context: input.context,
502
+ history,
503
+ userIdentity: input.userIdentity,
504
+ });
505
+ const craftMemories = await loadCraftMemories();
506
+ const result = await engine.retrospect({
507
+ timezone: input.timezone,
508
+ promptNow: input.promptNow,
509
+ userIdentity: input.userIdentity,
510
+ locale: input.locale,
511
+ memories,
512
+ knowledgeDocuments,
513
+ craftMemories,
514
+ context: input.context,
515
+ promptMode: input.promptMode,
516
+ directives: input.directives,
517
+ promptScaffold: input.promptScaffold,
518
+ guidelines: input.guidelines,
519
+ extraSystemSections: [...attachmentSections, ...(input.extraSystemSections ?? [])],
520
+ history,
521
+ });
522
+ const hasActions = result.actions.length > 0;
523
+ const hasCrudActions = result.crudActions && result.crudActions.length > 0;
524
+ if (!hasActions && !hasCrudActions)
525
+ return result;
526
+ const retrospectResults = [];
527
+ // Execute CRUD-based memory mutations
528
+ if (hasCrudActions) {
529
+ const memoryCrudHandler = buildMemoryCrudHandler(adapter);
530
+ const craftCrudHandler = buildCraftMemoryCrudHandler(adapter);
531
+ for (const crudAction of result.crudActions) {
532
+ try {
533
+ if (crudAction.entity === 'memory') {
534
+ await memoryCrudHandler(crudAction);
535
+ }
536
+ else if (crudAction.entity === 'craftMemory') {
537
+ await craftCrudHandler(crudAction);
538
+ }
539
+ retrospectResults.push({
540
+ name: `${crudAction.operation}_${crudAction.entity}`,
541
+ status: 'executed',
542
+ });
543
+ }
544
+ catch (err) {
545
+ retrospectResults.push({
546
+ name: `${crudAction.operation}_${crudAction.entity}`,
547
+ status: 'failed',
548
+ error: err instanceof Error ? err.message : String(err),
549
+ });
550
+ }
551
+ }
552
+ }
553
+ // Legacy action-based memory mutations (backward compat)
554
+ if (hasActions) {
555
+ const allHandlers = {
556
+ ...buildMemoryHandlers(adapter),
557
+ ...buildCraftMemoryHandlers(adapter),
558
+ };
559
+ const effectiveActions = resolveActions(effectiveEngine.config) ?? {};
560
+ const sideEffectResults = await executeSideEffects(result.actions, allHandlers, effectiveActions);
561
+ for (const item of sideEffectResults) {
562
+ retrospectResults.push({
563
+ name: item.action.name,
564
+ status: item.status,
565
+ error: item.error,
566
+ });
567
+ }
568
+ }
569
+ return {
570
+ ...result,
571
+ results: retrospectResults,
572
+ };
573
+ };
574
+ return {
575
+ engine: effectiveEngine,
576
+ async chat(input) {
577
+ const conversationId = await resolveConversation(adapter, input.conversationId, input.trigger, input.metadata);
578
+ const rawMessagesBeforeTurn = await adapter.getMessages(conversationId, historyLimit);
579
+ await adapter.saveMessage(conversationId, {
580
+ role: 'user',
581
+ content: input.message,
582
+ isNote: false,
583
+ });
584
+ await runPreTurnMaintenance({
585
+ conversationId,
586
+ context: input.context,
587
+ timezone: input.timezone,
588
+ promptNow: input.promptNow,
589
+ userIdentity: input.userIdentity,
590
+ locale: input.locale,
591
+ directives: input.directives,
592
+ promptScaffold: input.promptScaffold,
593
+ extraSystemSections: input.extraSystemSections,
594
+ rawMessages: rawMessagesBeforeTurn,
595
+ });
596
+ const { history, attachmentSections, workingSet, memories, knowledgeDocuments, craftMemories } = await loadManagedTurnState(conversationId, {
597
+ mode: 'chat',
598
+ message: input.message,
599
+ context: input.context,
600
+ userIdentity: input.userIdentity,
601
+ });
602
+ const historyForLLM = history.slice(0, -1);
603
+ const chatInput = {
604
+ message: input.message,
605
+ history: historyForLLM,
606
+ context: input.context,
607
+ memories,
608
+ knowledgeDocuments: input.knowledgeDocuments ?? knowledgeDocuments,
609
+ craftMemories,
610
+ timezone: input.timezone,
611
+ promptNow: input.promptNow,
612
+ directives: input.directives,
613
+ promptMode: input.promptMode,
614
+ promptScaffold: input.promptScaffold,
615
+ extraSystemSections: [...attachmentSections, ...(input.extraSystemSections ?? [])],
616
+ userIdentity: input.userIdentity,
617
+ locale: input.locale,
618
+ personaId: input.personaId,
619
+ correlationId: input.correlationId,
620
+ attachments: input.attachments,
621
+ workingSet,
622
+ crudValidation: input.crudValidation,
623
+ crudValidationRetries: input.crudValidationRetries,
624
+ };
625
+ let result = await effectiveEngine.chat(chatInput);
626
+ if (peers && Object.keys(peers).length > 0) {
627
+ const peerActions = result.actions.filter(a => a.name === PEER_ACTION_NAME);
628
+ if (peerActions.length > 0) {
629
+ const consultations = [];
630
+ for (const action of peerActions) {
631
+ const { peer: peerName, query } = action.params;
632
+ const peerConfig = peers[peerName];
633
+ if (!peerConfig) {
634
+ result.trace.errors.push(`Unknown peer: "${peerName}" — not declared in peers config`);
635
+ continue;
636
+ }
637
+ const peerStart = Date.now();
638
+ try {
639
+ const peerContext = await peerConfig.contextBuilder(query, input.context ?? {});
640
+ const peerConvId = peerConfig.conversationResolver
641
+ ? await peerConfig.conversationResolver()
642
+ : undefined;
643
+ const peerResult = await peerConfig.persona.chat({
644
+ message: query,
645
+ conversationId: peerConvId,
646
+ context: peerContext,
647
+ personaId: peerName,
648
+ correlationId: input.correlationId,
649
+ timezone: input.timezone,
650
+ });
651
+ consultations.push({
652
+ peer: peerName,
653
+ query,
654
+ response: peerResult.message,
655
+ trace: peerResult.trace,
656
+ durationMs: Date.now() - peerStart,
657
+ });
658
+ }
659
+ catch (err) {
660
+ const errorMsg = err instanceof Error ? err.message : String(err);
661
+ result.trace.errors.push(`Peer consultation "${peerName}" failed: ${errorMsg}`);
662
+ console.warn(`[archetype] Peer consultation failed: ${peerName}: ${errorMsg}`);
663
+ }
664
+ }
665
+ if (consultations.length > 0) {
666
+ // Stamp consultations on the initial trace (preserved even after re-call)
667
+ result.trace.peerConsultations = consultations;
668
+ // Re-call engine with enriched context — peer responses injected via extraSystemSections
669
+ const peerSections = consultations.map(c => `--- FROM ${c.peer.toUpperCase()} ---\nYou asked: "${c.query}"\n\n${c.response}\n--- END ${c.peer.toUpperCase()} ---`);
670
+ const enrichedResult = await effectiveEngine.chat({
671
+ ...chatInput,
672
+ extraSystemSections: [
673
+ ...peerSections,
674
+ ...(chatInput.extraSystemSections ?? []),
675
+ ],
676
+ });
677
+ // Merge: use the enriched response but keep the original trace (with peer consultations)
678
+ const enrichedTrace = enrichedResult.trace;
679
+ enrichedTrace.personaId = result.trace.personaId;
680
+ enrichedTrace.correlationId = result.trace.correlationId;
681
+ enrichedTrace.peerConsultations = consultations;
682
+ result = enrichedResult;
683
+ }
684
+ }
685
+ }
686
+ // Filter out consultPeer actions from persisted actions — they're SDK-internal
687
+ result = {
688
+ ...result,
689
+ actions: result.actions.filter(a => !PEER_ACTION_NAMES.has(a.name)),
690
+ };
691
+ if (usesWorkingSet(effectiveEngine.config) && result.workingSet) {
692
+ await saveManagedWorkingSet(adapter, conversationId, result.workingSet);
693
+ }
694
+ const persistedActions = selectPersistedActions(effectiveEngine.config, result.actions);
695
+ const memoryEffects = await executeManagedMemorySideEffects(result, { annotateCrud: true });
696
+ const domainEffects = await executeManagedDomainCrud(result, input.domainCrud);
697
+ const isSdkAction = (name) => MEMORY_ACTION_NAMES.has(name) || CRAFT_MEMORY_ACTION_NAMES.has(name) || PEER_ACTION_NAMES.has(name);
698
+ const annotatedActions = persistedActions.filter(a => !isSdkAction(a.name) || memoryEffects.executedMemoryActionNames.has(a.name));
699
+ const actionAnnotations = annotatedActions.length > 0
700
+ ? buildAnnotations(annotatedActions.map(a => ({ name: a.name, params: a.params })))
701
+ : [];
702
+ const allAnnotations = [...actionAnnotations, ...memoryEffects.executedCrudAnnotations];
703
+ const peerAnnotation = result.trace.peerConsultations?.length
704
+ ? buildPeerAnnotation(result.trace.peerConsultations)
705
+ : '';
706
+ const annotatedContent = buildAssistantContinuityMessage({
707
+ message: result.message,
708
+ modelOutcomeNotes: result.outcomeNotes,
709
+ actionOutcomes: [...memoryEffects.actionOutcomes, ...domainEffects.actionOutcomes],
710
+ actionAnnotations: allAnnotations,
711
+ extraHistorySections: peerAnnotation ? [peerAnnotation] : [],
712
+ });
713
+ return finalizeManagedTurn({
714
+ conversationId,
715
+ result,
716
+ assistantContent: annotatedContent,
717
+ actionsJson: annotatedActions.length > 0 ? JSON.stringify(annotatedActions) : null,
718
+ saveAttachmentNotes: true,
719
+ });
720
+ },
721
+ async greet(input) {
722
+ const result = await runPromptedTurn({
723
+ ...input,
724
+ trigger: input.trigger ?? 'greeting',
725
+ label: 'Greeting',
726
+ intent: "You're checking in on a fresh or resumed session. Generate a warm, natural check-in that reads like a thoughtful person, not a notification.",
727
+ turnKind: 'proactive-conversation',
728
+ });
729
+ return { greeting: result.message, conversationId: result.conversationId };
730
+ },
731
+ async promptedTurn(input) {
732
+ return runPromptedTurn(input);
733
+ },
734
+ async retrospect(input) {
735
+ return runRetrospect(input);
736
+ },
737
+ async reviewWorkingSet(input) {
738
+ const workingSet = await loadManagedWorkingSet(adapter, input.conversationId);
739
+ if (!workingSet) {
740
+ throw new Error(`No working set found for conversation ${input.conversationId}`);
741
+ }
742
+ const reviewed = reviewWorkingSetDeltaEngine(workingSet, {
743
+ deltaId: input.deltaId,
744
+ decision: input.decision,
745
+ });
746
+ await saveManagedWorkingSet(adapter, input.conversationId, reviewed);
747
+ return {
748
+ conversationId: input.conversationId,
749
+ workingSet: reviewed,
750
+ summary: summarizeWorkingSet(reviewed),
751
+ };
752
+ },
753
+ async commitWorkingSet(input) {
754
+ const workingSet = await loadManagedWorkingSet(adapter, input.conversationId);
755
+ if (!workingSet) {
756
+ throw new Error(`No working set found for conversation ${input.conversationId}`);
757
+ }
758
+ const committed = await commitWorkingSetEngine(workingSet, input.handlers, input.deltaIds);
759
+ await saveManagedWorkingSet(adapter, input.conversationId, committed.workingSet);
760
+ return {
761
+ conversationId: input.conversationId,
762
+ workingSet: committed.workingSet,
763
+ results: committed.results,
764
+ };
765
+ },
766
+ async endConversation(conversationId) {
767
+ await endConversation(adapter, conversationId);
768
+ if (adapter.clearWorkingSet) {
769
+ await adapter.clearWorkingSet(conversationId);
770
+ }
771
+ },
772
+ };
773
+ }
774
+ function defaultKnowledgeQuery(input) {
775
+ const base = input.mode === 'chat'
776
+ ? input.message
777
+ : input.mode === 'prompted-turn'
778
+ ? input.intent
779
+ : input.history?.slice(-4).map(item => item.content).join('\n');
780
+ const query = base?.trim();
781
+ return query ? query : null;
782
+ }
783
+ function selectPersistedActions(config, actions) {
784
+ if (!usesWorkingSet(config))
785
+ return actions;
786
+ return actions.filter(action => MEMORY_ACTION_NAMES.has(action.name) || CRAFT_MEMORY_ACTION_NAMES.has(action.name));
787
+ }
788
+ function stripSdkCrudActions(crudActions) {
789
+ if (!crudActions || crudActions.length === 0)
790
+ return crudActions;
791
+ const sdkCrudEntities = new Set(['memory', 'craftMemory']);
792
+ const filtered = crudActions.filter(action => !sdkCrudEntities.has(action.entity));
793
+ return filtered.length > 0 ? filtered : undefined;
794
+ }
795
+ function crudOutcomeNote(action, status, error) {
796
+ const summary = `crud ${action.operation} ${action.entity}`;
797
+ return status === 'failed'
798
+ ? `${summary} failed${error ? `: ${error}` : '.'}`
799
+ : `${summary} executed.`;
800
+ }
801
+ async function loadManagedWorkingSet(adapter, conversationId) {
802
+ if (!adapter.loadWorkingSet || !adapter.saveWorkingSet || !adapter.clearWorkingSet) {
803
+ throw new Error('This persona uses staging.model = "working-set", but the StorageAdapter does not implement loadWorkingSet/saveWorkingSet/clearWorkingSet.');
804
+ }
805
+ return adapter.loadWorkingSet(conversationId);
806
+ }
807
+ async function saveManagedWorkingSet(adapter, conversationId, workingSet) {
808
+ if (!adapter.saveWorkingSet) {
809
+ throw new Error('This persona uses staging.model = "working-set", but the StorageAdapter does not implement saveWorkingSet.');
810
+ }
811
+ await adapter.saveWorkingSet(conversationId, workingSet);
812
+ }
813
+ /**
814
+ * Build side-effect handlers for built-in memory actions.
815
+ * These route saveMemory/updateMemory/deleteMemory to the StorageAdapter.
816
+ */
817
+ function buildMemoryHandlers(adapter) {
818
+ return {
819
+ saveMemory: async (params) => {
820
+ const { content, category, source, stability, contextHint } = params;
821
+ await adapter.saveMemory({
822
+ content,
823
+ category,
824
+ source,
825
+ stability,
826
+ contextHint,
827
+ pinned: false,
828
+ createdAt: new Date().toISOString(),
829
+ });
830
+ return { success: true };
831
+ },
832
+ updateMemory: async (params) => {
833
+ const { id, content, category, source, stability, contextHint } = params;
834
+ await adapter.updateMemory(id, { content, category, source, stability, contextHint });
835
+ return { success: true };
836
+ },
837
+ deleteMemory: async (params) => {
838
+ const { id } = params;
839
+ await adapter.deleteMemory(id);
840
+ return { success: true };
841
+ },
842
+ };
843
+ }
844
+ function buildCraftMemoryHandlers(adapter) {
845
+ return {
846
+ saveCraftMemory: async (params) => {
847
+ if (!adapter.saveCraftMemory)
848
+ throw new Error('StorageAdapter does not implement saveCraftMemory');
849
+ const { content, category, source, stability, contextHint } = params;
850
+ await adapter.saveCraftMemory({
851
+ content,
852
+ category,
853
+ scope: 'craft',
854
+ source,
855
+ stability,
856
+ contextHint,
857
+ pinned: false,
858
+ createdAt: new Date().toISOString(),
859
+ });
860
+ return { success: true };
861
+ },
862
+ updateCraftMemory: async (params) => {
863
+ if (!adapter.updateCraftMemory)
864
+ throw new Error('StorageAdapter does not implement updateCraftMemory');
865
+ const { id, content, category, source, stability, contextHint } = params;
866
+ await adapter.updateCraftMemory(id, { content, category, source, stability, contextHint });
867
+ return { success: true };
868
+ },
869
+ deleteCraftMemory: async (params) => {
870
+ if (!adapter.deleteCraftMemory)
871
+ throw new Error('StorageAdapter does not implement deleteCraftMemory');
872
+ const { id } = params;
873
+ await adapter.deleteCraftMemory(id);
874
+ return { success: true };
875
+ },
876
+ };
877
+ }
878
+ /**
879
+ * CRUD handler for memory entity — routes create/update/delete to the StorageAdapter.
880
+ */
881
+ function buildMemoryCrudHandler(adapter) {
882
+ return async (action) => {
883
+ if (action.operation === 'create') {
884
+ const { content, category, source, stability, contextHint } = (action.params ?? {});
885
+ await adapter.saveMemory({
886
+ content,
887
+ category,
888
+ source,
889
+ stability,
890
+ contextHint,
891
+ pinned: false,
892
+ createdAt: new Date().toISOString(),
893
+ });
894
+ }
895
+ else if (action.operation === 'update' && action.id) {
896
+ await adapter.updateMemory(action.id, action.params);
897
+ }
898
+ else if (action.operation === 'delete' && action.id) {
899
+ await adapter.deleteMemory(action.id);
900
+ }
901
+ };
902
+ }
903
+ /**
904
+ * CRUD handler for craftMemory entity — routes create/update/delete to the StorageAdapter.
905
+ */
906
+ function buildCraftMemoryCrudHandler(adapter) {
907
+ return async (action) => {
908
+ if (action.operation === 'create') {
909
+ if (!adapter.saveCraftMemory)
910
+ throw new Error('StorageAdapter does not implement saveCraftMemory');
911
+ const { content, category, source, stability, contextHint } = (action.params ?? {});
912
+ await adapter.saveCraftMemory({
913
+ content,
914
+ category,
915
+ scope: 'craft',
916
+ source,
917
+ stability,
918
+ contextHint,
919
+ pinned: false,
920
+ createdAt: new Date().toISOString(),
921
+ });
922
+ }
923
+ else if (action.operation === 'update' && action.id) {
924
+ if (!adapter.updateCraftMemory)
925
+ throw new Error('StorageAdapter does not implement updateCraftMemory');
926
+ await adapter.updateCraftMemory(action.id, action.params);
927
+ }
928
+ else if (action.operation === 'delete' && action.id) {
929
+ if (!adapter.deleteCraftMemory)
930
+ throw new Error('StorageAdapter does not implement deleteCraftMemory');
931
+ await adapter.deleteCraftMemory(action.id);
932
+ }
933
+ };
934
+ }
935
+ // ─── Re-exports ──────────────────────────────────────────────────────────────
936
+ export { Gemini, buildGeminiResponseSchema, buildGeminiActionOnlySchema, resolveFallbackChain } from './providers/gemini.js';
937
+ export { zodToGeminiSchema } from './providers/zod-to-gemini.js';
938
+ export { PersonaEngine } from './persona.js';
939
+ export { parseBrainMarkdown, loadBrainFile, resolvePersonaBrain, getBrainSection, resolvePersonaConfigBrain } from './brain.js';
940
+ export { buildSystemPrompt, buildGreetingPrompt, buildPromptedTurnPrompt, buildRetrospectPrompt } from './core/prompt-builder.js';
941
+ export { buildIdentityBlock } from './core/identity.js';
942
+ export { buildVoiceBlock } from './core/voice.js';
943
+ export { buildEQBlock } from './core/eq.js';
944
+ export { serializeAllContext, serializeContextBlock } from './core/context.js';
945
+ export { selectMemoriesForPrompt, buildMemoryBlock, inferMemoryCategory } from './core/memory.js';
946
+ export { buildActionsBlock, buildActionAnnotation, buildAnnotations, annotateMessage, stripActionAnnotations, stripAnnotationsForDisplay, buildPeerAnnotation } from './core/actions.js';
947
+ export { PEER_ACTION_NAME, PEER_ACTION_NAMES } from './core/peer-actions.js';
948
+ export { shouldGreet, buildGreetingHint } from './core/greeting.js';
949
+ export { executeSideEffects, getProposedActions, getExecutedAnnotations, buildAssistantHistoryMessage, confirmActions, summarizeSideEffects, } from './engine/side-effects.js';
950
+ export { resolveActions, resolveEntities, resolveEffectiveConfig } from './core/effective-config.js';
951
+ export { buildChatLLMRequest, buildPromptedTurnLLMRequest } from './core/request-builder.js';
952
+ export { resolveConversation, loadHistory } from './managed/conversation.js';
953
+ export { buildAttachmentCarryForwardMessage, buildAttachmentCarryForwardSection, parseAttachmentCarryForwardMessage, collectAttachmentCarryForwardNotes, } from './core/attachment-notes.js';
954
+ export { loadMemories } from './managed/memory-manager.js';
955
+ /** @deprecated Legacy exports — memory mutations now use the entity CRUD system. Kept for backward compat. */
956
+ export { MEMORY_ACTIONS, MEMORY_ACTION_NAMES, buildMemoryActions, CRAFT_MEMORY_ACTIONS, CRAFT_MEMORY_ACTION_NAMES, buildCraftMemoryActions } from './core/memory-actions.js';
957
+ export { buildMemoryEntityConfig, buildCraftMemoryEntityConfig } from './core/memory-actions.js';
958
+ export { buildFocusContextInputs, renderFocusWorkItem } from './core/focus-context.js';
959
+ export { ENTER_FOCUS_MODE_ACTION_NAME, UPDATE_FOCUS_WORK_ITEM_ACTION_NAME, RETURN_TO_SESSION_ACTION_NAME, FOCUS_MODE_ACTIONS, buildFocusActionSets, enterFocusModeAction, enterFocusModeOutcomeNote, isEnterFocusModeAction, updateFocusWorkItemAction, updateFocusWorkItemOutcomeNote, isUpdateFocusWorkItemAction, returnToSessionAction, returnToSessionOutcomeNote, isReturnToSessionAction, } from './core/focus-mode-actions.js';
960
+ export { resolveAddressedParticipantId, resolveSessionRecipientId } from './core/session-routing.js';
961
+ /** Advanced: defineEntity() and crud() for manual entity CRUD wiring. Most apps use `entities` on PersonaConfig instead. */
962
+ export { defineEntity, crud } from './core/entities.js';
963
+ export { buildEntityRegistry } from './core/entity-registry.js';
964
+ export { buildEntitiesBlock } from './core/crud-prompt.js';
965
+ export { buildCrudActionsSchema } from './core/crud-schema.js';
966
+ export { validateCrudActions, crudActionToAnnotation, resolveTempIds, separateCrudActions, validateAndTraceCrud, commitCrud } from './engine/crud.js';
967
+ export { buildAssistantContinuityMessage, buildOutcomeNoteFromActionOutcome, collectOutcomeNotes, compactActionForHistory, compactActionSummary, compactValueForHistory, prepareTurnLedgerChatTurn, renderTurnLedgerEntryForModel, renderTurnLedgerForDisplay, renderTurnLedgerForModel, } from './engine/continuity.js';
968
+ export { parseActionName, actionLabel, getActionDisplayTitle, isEntityAction } from './core/entity-helpers.js';
969
+ export { reviewMemories, compactMemories } from './managed/memory-review.js';
970
+ export { runAutonomousLoop } from './managed/autonomous-loop.js';
971
+ export { createBatch, updateActionStatus, editActionParams, commitBatch, summarizeBatch } from './engine/staging.js';
972
+ export { applyActionsToWorkingSet, buildWorkingSetSection, commitWorkingSet, reviewWorkingSetDelta, summarizeWorkingSet, usesWorkingSet, } from './engine/working-set.js';
973
+ export { runEvalConversation, auditBrainBloat, auditOperationalPromptContract, auditPromptContent, auditCrossLayerDuplicates, auditActionContracts, auditBrainPrescriptions, auditEntityVisibility, judgeEvalTurn, judgeEvalConversation, judgePairwiseConversations, SAMPLE_PROJECTS, } from './evals/index.js';
974
+ export { COACH_TEMPLATE, NUTRITION_TEMPLATE, FITNESS_TEMPLATE, LANGUAGE_TUTOR_TEMPLATE, CHIEF_OF_STAFF_TEMPLATE, } from './playbook/templates.js';
975
+ export { auditPrompt } from './audit/prompt-audit.js';
976
+ export { auditConversation } from './audit/conversation-audit.js';
977
+ export { auditByBrainReflection } from './audit/brain-reflection.js';
978
+ export { configVersion } from './audit/version.js';
979
+ export { auditPersona, formatAuditReport, printAuditReport, } from './audit/audit-persona.js';
980
+ export { dumpPromptForReview, createPromptTraceRecorder, formatAsArtifact, } from './audit/prompt-dump.js';
981
+ export { auditTraceIntegrity } from './audit/trace-integrity.js';
982
+ export { JUDGMENT_OVER_LITERALISM_NUDGE, PRECEDENCE_OF_SIGNALS_NUDGE, MATCH_MESSAGE_TO_ACTIONS_NUDGE, ACTION_RESULTS_ARE_WORLD_STATE_NUDGE, MEMORY_SELF_BOX_WARNING, CONTEXTHINT_CAPTURES_THE_WHY, EXPERT_AUTONOMY_NUDGE, LOAD_BEARING_INVARIANTS, } from './playbook/invariants.js';
983
+ export { createMarkdownKnowledgeAdapter } from './managed/knowledge.js';
984
+ // ─── Builder: coder-persona primitives ──────────────────────────────────────
985
+ // Action contracts for building code-writing agent personas. Pick from the
986
+ // `coderActions` dictionary. Implementations (Sandbox + BrowserHarness) land
987
+ // in follow-up promotion steps.
988
+ export { coderActions, readFileAction, applyPatchAction, writeFileAction, editFileAction, deleteFileAction, listFilesAction, searchInFilesAction, runInstallAction, runBuildAction, runTestsAction, runLintAction, runStartAction, runCommandAction, browserOpenAction, browserScreenshotAction, browserClickAction, browserTypeAction, browserKeyAction, browserConsoleAction, finishAttemptAction, } from './builder/actions.js';
989
+ export { filterNodeTestFilePaths, isNodeTestFilePath, } from './builder/node-test-discovery.js';
990
+ export { makeWorkHistoryEntry, renderWorkHistoryEntries, renderWorkHistoryEntry, } from './managed/work-history.js';
991
+ export { createPmSpecPersonaConfig, createPmSpecWorkItem, pmSpecContextInputs, } from './samples/pm-spec-agent.js';
992
+ // ─── Observability ──────────────────────────────────────────────────
993
+ // Shared telemetry: onTurn reporter (errors.jsonl + diagnostics.md)
994
+ // and a pure render-run-markdown renderer every autonomous-loop
995
+ // consumer can reuse.
996
+ export { createTurnReporter } from './observability/turn-reporter.js';
997
+ export { renderRunMarkdown, tryParseAssistantPayload, summarizeAction, } from './observability/render-run-markdown.js';
998
+ //# sourceMappingURL=index.js.map