@graphorin/memory 0.5.0 → 0.6.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 (235) hide show
  1. package/CHANGELOG.md +90 -1
  2. package/README.md +31 -31
  3. package/dist/conflict/index.d.ts +3 -1
  4. package/dist/conflict/index.js +1 -1
  5. package/dist/conflict/locale-packs/en.d.ts +13 -0
  6. package/dist/conflict/locale-packs/en.d.ts.map +1 -0
  7. package/dist/conflict/locale-packs/en.js +1 -1
  8. package/dist/conflict/locale-packs/en.js.map +1 -1
  9. package/dist/conflict/pipeline.d.ts +2 -2
  10. package/dist/conflict/pipeline.js +3 -3
  11. package/dist/conflict/pipeline.js.map +1 -1
  12. package/dist/conflict/stages/helpers.js +1 -1
  13. package/dist/conflict/stages/helpers.js.map +1 -1
  14. package/dist/conflict/stages/stage1-exact-dedup.js.map +1 -1
  15. package/dist/conflict/stages/stage2-embedding-three-zone.js.map +1 -1
  16. package/dist/conflict/stages/stage3-heuristic-regex.js +1 -1
  17. package/dist/conflict/stages/stage3-heuristic-regex.js.map +1 -1
  18. package/dist/conflict/stages/stage4-subject-predicate.js.map +1 -1
  19. package/dist/conflict/stages/stage5-defer-to-deep.js.map +1 -1
  20. package/dist/conflict/types.d.ts +7 -7
  21. package/dist/conflict/types.js +1 -1
  22. package/dist/conflict/types.js.map +1 -1
  23. package/dist/consolidator/budget.js +16 -3
  24. package/dist/consolidator/budget.js.map +1 -1
  25. package/dist/consolidator/decay.d.ts +13 -2
  26. package/dist/consolidator/decay.js +17 -5
  27. package/dist/consolidator/decay.js.map +1 -1
  28. package/dist/consolidator/dlq.js +1 -1
  29. package/dist/consolidator/dlq.js.map +1 -1
  30. package/dist/consolidator/errors.js +2 -2
  31. package/dist/consolidator/errors.js.map +1 -1
  32. package/dist/consolidator/index.js +8 -6
  33. package/dist/consolidator/index.js.map +1 -1
  34. package/dist/consolidator/lock.js +1 -1
  35. package/dist/consolidator/lock.js.map +1 -1
  36. package/dist/consolidator/noise-filter.js.map +1 -1
  37. package/dist/consolidator/phases/deep.js +6 -2
  38. package/dist/consolidator/phases/deep.js.map +1 -1
  39. package/dist/consolidator/phases/induce.d.ts +10 -10
  40. package/dist/consolidator/phases/induce.js +6 -6
  41. package/dist/consolidator/phases/induce.js.map +1 -1
  42. package/dist/consolidator/phases/learned-context.js +129 -0
  43. package/dist/consolidator/phases/learned-context.js.map +1 -0
  44. package/dist/consolidator/phases/light.js +2 -1
  45. package/dist/consolidator/phases/light.js.map +1 -1
  46. package/dist/consolidator/phases/reflect.js +5 -4
  47. package/dist/consolidator/phases/reflect.js.map +1 -1
  48. package/dist/consolidator/phases/standard.js +37 -8
  49. package/dist/consolidator/phases/standard.js.map +1 -1
  50. package/dist/consolidator/reconcile.js +1 -1
  51. package/dist/consolidator/reconcile.js.map +1 -1
  52. package/dist/consolidator/runtime.d.ts +4 -4
  53. package/dist/consolidator/runtime.d.ts.map +1 -1
  54. package/dist/consolidator/runtime.js +73 -16
  55. package/dist/consolidator/runtime.js.map +1 -1
  56. package/dist/consolidator/scheduler.d.ts +5 -5
  57. package/dist/consolidator/scheduler.js +1 -1
  58. package/dist/consolidator/scheduler.js.map +1 -1
  59. package/dist/consolidator/triggers.js +7 -7
  60. package/dist/consolidator/triggers.js.map +1 -1
  61. package/dist/consolidator/types.d.ts +68 -20
  62. package/dist/consolidator/types.d.ts.map +1 -1
  63. package/dist/consolidator/types.js +16 -6
  64. package/dist/consolidator/types.js.map +1 -1
  65. package/dist/context-engine/annotations.d.ts +9 -9
  66. package/dist/context-engine/annotations.js +3 -3
  67. package/dist/context-engine/annotations.js.map +1 -1
  68. package/dist/context-engine/auto-recall.js.map +1 -1
  69. package/dist/context-engine/compaction/clear-tool-results.d.ts +18 -3
  70. package/dist/context-engine/compaction/clear-tool-results.d.ts.map +1 -1
  71. package/dist/context-engine/compaction/clear-tool-results.js +26 -5
  72. package/dist/context-engine/compaction/clear-tool-results.js.map +1 -1
  73. package/dist/context-engine/compaction/compactor.js +19 -6
  74. package/dist/context-engine/compaction/compactor.js.map +1 -1
  75. package/dist/context-engine/compaction/hooks/reanchor-persona-block.js +4 -0
  76. package/dist/context-engine/compaction/hooks/reanchor-persona-block.js.map +1 -1
  77. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.js +1 -0
  78. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.js.map +1 -1
  79. package/dist/context-engine/compaction/hooks/reanchor-project-rules.js +2 -1
  80. package/dist/context-engine/compaction/hooks/reanchor-project-rules.js.map +1 -1
  81. package/dist/context-engine/compaction/hooks/reanchor-recent-results.d.ts +28 -0
  82. package/dist/context-engine/compaction/hooks/reanchor-recent-results.d.ts.map +1 -0
  83. package/dist/context-engine/compaction/hooks/reanchor-recent-results.js +71 -0
  84. package/dist/context-engine/compaction/hooks/reanchor-recent-results.js.map +1 -0
  85. package/dist/context-engine/compaction/hooks/types.d.ts +15 -3
  86. package/dist/context-engine/compaction/hooks/types.d.ts.map +1 -1
  87. package/dist/context-engine/compaction/index.d.ts +1 -0
  88. package/dist/context-engine/compaction/index.js +2 -1
  89. package/dist/context-engine/compaction/templates/summary-9-section.d.ts +10 -3
  90. package/dist/context-engine/compaction/templates/summary-9-section.d.ts.map +1 -1
  91. package/dist/context-engine/compaction/templates/summary-9-section.js +42 -5
  92. package/dist/context-engine/compaction/templates/summary-9-section.js.map +1 -1
  93. package/dist/context-engine/compaction/thresholds.js.map +1 -1
  94. package/dist/context-engine/compaction/types.d.ts +47 -7
  95. package/dist/context-engine/compaction/types.d.ts.map +1 -1
  96. package/dist/context-engine/engine.d.ts +23 -4
  97. package/dist/context-engine/engine.d.ts.map +1 -1
  98. package/dist/context-engine/engine.js +69 -15
  99. package/dist/context-engine/engine.js.map +1 -1
  100. package/dist/context-engine/index.d.ts +1 -0
  101. package/dist/context-engine/index.d.ts.map +1 -1
  102. package/dist/context-engine/index.js +2 -1
  103. package/dist/context-engine/locale-packs/en.js +14 -13
  104. package/dist/context-engine/locale-packs/en.js.map +1 -1
  105. package/dist/context-engine/locale-packs/types.d.ts +10 -10
  106. package/dist/context-engine/locale-packs/types.d.ts.map +1 -1
  107. package/dist/context-engine/locale-packs/types.js.map +1 -1
  108. package/dist/context-engine/metadata.d.ts +1 -1
  109. package/dist/context-engine/metadata.js +2 -2
  110. package/dist/context-engine/metadata.js.map +1 -1
  111. package/dist/context-engine/preambles/inbound-en.d.ts +1 -1
  112. package/dist/context-engine/preambles/inbound-en.js +1 -1
  113. package/dist/context-engine/preambles/inbound-en.js.map +1 -1
  114. package/dist/context-engine/privacy-filter.d.ts +2 -2
  115. package/dist/context-engine/privacy-filter.js +1 -1
  116. package/dist/context-engine/privacy-filter.js.map +1 -1
  117. package/dist/context-engine/templates/base-en.d.ts +1 -1
  118. package/dist/context-engine/templates/base-en.js +1 -1
  119. package/dist/context-engine/templates/base-en.js.map +1 -1
  120. package/dist/context-engine/templates/composer.d.ts +1 -1
  121. package/dist/context-engine/templates/composer.js.map +1 -1
  122. package/dist/context-engine/token-budget.d.ts +1 -1
  123. package/dist/context-engine/token-budget.js +1 -1
  124. package/dist/context-engine/token-budget.js.map +1 -1
  125. package/dist/context-engine/token-counter.d.ts +16 -7
  126. package/dist/context-engine/token-counter.d.ts.map +1 -1
  127. package/dist/context-engine/token-counter.js +31 -9
  128. package/dist/context-engine/token-counter.js.map +1 -1
  129. package/dist/errors/index.d.ts +2 -2
  130. package/dist/errors/index.js +4 -4
  131. package/dist/errors/index.js.map +1 -1
  132. package/dist/facade.d.ts +44 -15
  133. package/dist/facade.d.ts.map +1 -1
  134. package/dist/facade.js +16 -8
  135. package/dist/facade.js.map +1 -1
  136. package/dist/graph/entity-resolver.d.ts +2 -2
  137. package/dist/graph/entity-resolver.js +2 -2
  138. package/dist/graph/entity-resolver.js.map +1 -1
  139. package/dist/index.d.ts +9 -5
  140. package/dist/index.d.ts.map +1 -1
  141. package/dist/index.js +9 -4
  142. package/dist/index.js.map +1 -1
  143. package/dist/internal/contextualize.js +2 -2
  144. package/dist/internal/contextualize.js.map +1 -1
  145. package/dist/internal/embedder-binding.js +1 -1
  146. package/dist/internal/embedder-binding.js.map +1 -1
  147. package/dist/internal/id.js +1 -1
  148. package/dist/internal/id.js.map +1 -1
  149. package/dist/internal/injection-heuristics.js +25 -2
  150. package/dist/internal/injection-heuristics.js.map +1 -1
  151. package/dist/internal/spans.js +1 -1
  152. package/dist/internal/spans.js.map +1 -1
  153. package/dist/internal/storage-adapter.d.ts +71 -22
  154. package/dist/internal/storage-adapter.d.ts.map +1 -1
  155. package/dist/migration/embedder-migration.d.ts +7 -7
  156. package/dist/migration/embedder-migration.js.map +1 -1
  157. package/dist/search/explain.d.ts +7 -4
  158. package/dist/search/explain.d.ts.map +1 -1
  159. package/dist/search/explain.js +1 -1
  160. package/dist/search/explain.js.map +1 -1
  161. package/dist/search/fit-weights.d.ts +48 -0
  162. package/dist/search/fit-weights.d.ts.map +1 -0
  163. package/dist/search/fit-weights.js +70 -0
  164. package/dist/search/fit-weights.js.map +1 -0
  165. package/dist/search/graph-ppr.d.ts +36 -0
  166. package/dist/search/graph-ppr.d.ts.map +1 -0
  167. package/dist/search/graph-ppr.js +38 -0
  168. package/dist/search/graph-ppr.js.map +1 -0
  169. package/dist/search/index.d.ts +4 -1
  170. package/dist/search/index.js +4 -1
  171. package/dist/search/iterative.d.ts +15 -8
  172. package/dist/search/iterative.d.ts.map +1 -1
  173. package/dist/search/iterative.js +10 -9
  174. package/dist/search/iterative.js.map +1 -1
  175. package/dist/search/query-transform.d.ts +6 -6
  176. package/dist/search/query-transform.js +6 -6
  177. package/dist/search/query-transform.js.map +1 -1
  178. package/dist/search/rrf.d.ts +4 -4
  179. package/dist/search/rrf.js +4 -4
  180. package/dist/search/rrf.js.map +1 -1
  181. package/dist/search/trust.d.ts +30 -0
  182. package/dist/search/trust.d.ts.map +1 -0
  183. package/dist/search/trust.js +50 -0
  184. package/dist/search/trust.js.map +1 -0
  185. package/dist/search/types.d.ts +1 -1
  186. package/dist/tiers/episodic-memory.d.ts +6 -4
  187. package/dist/tiers/episodic-memory.d.ts.map +1 -1
  188. package/dist/tiers/episodic-memory.js +3 -2
  189. package/dist/tiers/episodic-memory.js.map +1 -1
  190. package/dist/tiers/index.d.ts +1 -1
  191. package/dist/tiers/index.js +1 -1
  192. package/dist/tiers/insight-memory.d.ts +4 -4
  193. package/dist/tiers/insight-memory.js +3 -3
  194. package/dist/tiers/insight-memory.js.map +1 -1
  195. package/dist/tiers/procedural-memory.d.ts +29 -7
  196. package/dist/tiers/procedural-memory.d.ts.map +1 -1
  197. package/dist/tiers/procedural-memory.js +66 -6
  198. package/dist/tiers/procedural-memory.js.map +1 -1
  199. package/dist/tiers/semantic-memory.d.ts +111 -30
  200. package/dist/tiers/semantic-memory.d.ts.map +1 -1
  201. package/dist/tiers/semantic-memory.js +120 -27
  202. package/dist/tiers/semantic-memory.js.map +1 -1
  203. package/dist/tiers/session-memory.d.ts +7 -7
  204. package/dist/tiers/session-memory.js +7 -7
  205. package/dist/tiers/session-memory.js.map +1 -1
  206. package/dist/tiers/shared-memory.d.ts +1 -1
  207. package/dist/tiers/shared-memory.js +1 -1
  208. package/dist/tiers/shared-memory.js.map +1 -1
  209. package/dist/tiers/working-memory.d.ts +3 -3
  210. package/dist/tiers/working-memory.js +2 -2
  211. package/dist/tiers/working-memory.js.map +1 -1
  212. package/dist/tools/block-tools.d.ts +9 -9
  213. package/dist/tools/block-tools.d.ts.map +1 -1
  214. package/dist/tools/block-tools.js +3 -3
  215. package/dist/tools/block-tools.js.map +1 -1
  216. package/dist/tools/fact-tools.d.ts +48 -31
  217. package/dist/tools/fact-tools.d.ts.map +1 -1
  218. package/dist/tools/fact-tools.js +30 -18
  219. package/dist/tools/fact-tools.js.map +1 -1
  220. package/dist/tools/index.d.ts +9 -2
  221. package/dist/tools/index.d.ts.map +1 -1
  222. package/dist/tools/index.js +4 -2
  223. package/dist/tools/index.js.map +1 -1
  224. package/dist/tools/recall-tools.d.ts +40 -20
  225. package/dist/tools/recall-tools.d.ts.map +1 -1
  226. package/dist/tools/recall-tools.js +29 -10
  227. package/dist/tools/recall-tools.js.map +1 -1
  228. package/dist/tools/runbook-tools.d.ts +76 -0
  229. package/dist/tools/runbook-tools.d.ts.map +1 -0
  230. package/dist/tools/runbook-tools.js +53 -0
  231. package/dist/tools/runbook-tools.js.map +1 -0
  232. package/dist/tools/taint.js +33 -0
  233. package/dist/tools/taint.js.map +1 -0
  234. package/dist/tools/types.d.ts +1 -1
  235. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","names":["catchupPolicy: ConsolidatorCatchupPolicy","registered: Array<{ id: string; kind: ParsedTrigger['kind']; raw: string }>","skipped: Array<{ raw: string; reason: 'unsupported-by-scheduler' | 'filtered-out' }>","declaration: TriggerDeclarationLike"],"sources":["../../src/consolidator/scheduler.ts"],"sourcesContent":["/**\n * Bridge helpers wire a {@link Consolidator} into the\n * `@graphorin/triggers` Scheduler so trigger declarations fire on\n * the documented schedule (DEC-150 \"same code path lib + server\").\n *\n * The bridge is structural: any object that exposes the same shape\n * as `@graphorin/triggers`'s `Scheduler` (a `register(declaration)`\n * method) works. The structural import keeps `@graphorin/memory`\n * dependency-free at the type level the workspace consumer\n * supplies the actual scheduler at runtime.\n *\n * @packageDocumentation\n */\n\nimport type { SessionScope } from '@graphorin/core';\nimport type { Consolidator } from './runtime.js';\nimport { type ParsedTrigger, parseTriggerSpec, reasonFromTrigger } from './triggers.js';\nimport type { ConsolidatorTriggerSpec } from './types.js';\n\n/**\n * Catch-up policy applied when a trigger missed one or more fires\n * while the scheduler was offline. Mirrors\n * `@graphorin/triggers`'s `CatchupPolicy` duplicated here so the\n * memory package stays import-free at the type level.\n *\n * @stable\n */\nexport type ConsolidatorCatchupPolicy = 'none' | 'last' | 'all';\n\n/**\n * Subset of the `@graphorin/triggers` Scheduler surface the bridge\n * needs. Defined structurally so consumers can inject mocks in\n * tests without taking the package dependency.\n *\n * @stable\n */\nexport interface SchedulerLike {\n register(declaration: TriggerDeclarationLike): Promise<unknown>;\n unregister?(id: string): Promise<void>;\n}\n\n/**\n * Subset of `@graphorin/triggers`'s `TriggerDeclaration` accepted\n * by {@link SchedulerLike.register}. Field names mirror the\n * upstream shape exactly so the structural type is interchangeable\n * with the real export.\n *\n * @stable\n */\nexport interface TriggerDeclarationLike {\n readonly id: string;\n readonly kind: 'cron' | 'interval' | 'idle' | 'event';\n readonly spec: string;\n readonly callback: (payload?: unknown) => void | Promise<void>;\n readonly options: {\n readonly catchupPolicy?: ConsolidatorCatchupPolicy;\n readonly maxCatchupRuns?: number;\n readonly catchupWindowMs?: number;\n readonly tags?: ReadonlyArray<string>;\n readonly acknowledgeLibMode?: boolean;\n };\n}\n\n/** Options accepted by {@link registerConsolidatorTriggers}. */\nexport interface RegisterTriggersOptions {\n /**\n * Scope passed to `consolidator.trigger(...)` for every fire. The\n * consolidator only operates on a single user/session at a time\n * (DEC-005 single-user-per-process); multi-tenant deployments\n * register one scheduler-trigger pair per scope.\n */\n readonly scope: SessionScope;\n /**\n * Catch-up policy applied to every registered trigger. Defaults\n * to `'none'` per DEC-150 safest for personal-assistant\n * scenarios.\n */\n readonly catchupPolicy?: ConsolidatorCatchupPolicy;\n /** Suppress the per-process library-mode WARN. Defaults to `true`. */\n readonly acknowledgeLibMode?: boolean;\n /** Optional id prefix useful when multiple scopes share a scheduler. */\n readonly idPrefix?: string;\n /** Optional tags forwarded to the scheduler. */\n readonly tags?: ReadonlyArray<string>;\n /**\n * Filter only register the supplied subset of triggers. By\n * default every parseable trigger declared on the consolidator is\n * registered (turn / event triggers are skipped because the\n * Scheduler has no way to fire them on its own).\n */\n readonly include?: ReadonlyArray<ConsolidatorTriggerSpec>;\n}\n\n/**\n * Outcome of {@link registerConsolidatorTriggers}.\n *\n * @stable\n */\nexport interface RegisterTriggersResult {\n readonly registered: ReadonlyArray<{\n readonly id: string;\n readonly kind: ParsedTrigger['kind'];\n readonly raw: string;\n }>;\n readonly skipped: ReadonlyArray<{\n readonly raw: string;\n readonly reason: 'unsupported-by-scheduler' | 'filtered-out';\n }>;\n}\n\n/**\n * Register every cron / idle / interval trigger declared on the\n * supplied consolidator with the scheduler. Each trigger fires\n * `consolidator.trigger(reason, scope)` so the lib-mode + server\n * paths converge on the same handler.\n *\n * Turn triggers (`turn:N`) and event triggers (`event:NAME`) are\n * skipped the scheduler cannot count user turns autonomously, and\n * event triggers fire from the consumer's emit path. The runtime\n * caller is responsible for those (e.g. invoking\n * `consolidator.trigger(...)` from the agent loop).\n *\n * @stable\n */\nexport async function registerConsolidatorTriggers(\n consolidator: Consolidator,\n scheduler: SchedulerLike,\n options: RegisterTriggersOptions,\n): Promise<RegisterTriggersResult> {\n const config = consolidator.config();\n const include = options.include ?? config.triggers;\n const acknowledgeLibMode = options.acknowledgeLibMode ?? true;\n const catchupPolicy: ConsolidatorCatchupPolicy = options.catchupPolicy ?? 'none';\n const registered: Array<{ id: string; kind: ParsedTrigger['kind']; raw: string }> = [];\n const skipped: Array<{ raw: string; reason: 'unsupported-by-scheduler' | 'filtered-out' }> = [];\n const seenSet = new Set(include);\n for (const spec of config.triggers) {\n if (!seenSet.has(spec)) {\n skipped.push({ raw: spec, reason: 'filtered-out' });\n continue;\n }\n const parsed = parseTriggerSpec(spec);\n if (parsed.kind === 'turn' || parsed.kind === 'event' || parsed.kind === 'budget') {\n skipped.push({ raw: parsed.raw, reason: 'unsupported-by-scheduler' });\n continue;\n }\n const id = `${options.idPrefix ?? 'consolidator'}:${parsed.raw}`;\n const kind: 'cron' | 'idle' | 'interval' = parsed.kind === 'cron' ? 'cron' : 'idle';\n const declaration: TriggerDeclarationLike = {\n id,\n kind,\n spec: parsed.kind === 'cron' ? parsed.expression : String(parsed.idleMs),\n async callback() {\n await consolidator.trigger(reasonFromTrigger(parsed), options.scope);\n },\n options: {\n catchupPolicy,\n acknowledgeLibMode,\n ...(options.tags !== undefined ? { tags: options.tags } : {}),\n },\n };\n await scheduler.register(declaration);\n registered.push({ id, kind: parsed.kind, raw: parsed.raw });\n }\n return Object.freeze({\n registered: Object.freeze(registered),\n skipped: Object.freeze(skipped),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA4HA,eAAsB,6BACpB,cACA,WACA,SACiC;CACjC,MAAM,SAAS,aAAa,QAAQ;CACpC,MAAM,UAAU,QAAQ,WAAW,OAAO;CAC1C,MAAM,qBAAqB,QAAQ,sBAAsB;CACzD,MAAMA,gBAA2C,QAAQ,iBAAiB;CAC1E,MAAMC,aAA8E,EAAE;CACtF,MAAMC,UAAuF,EAAE;CAC/F,MAAM,UAAU,IAAI,IAAI,QAAQ;AAChC,MAAK,MAAM,QAAQ,OAAO,UAAU;AAClC,MAAI,CAAC,QAAQ,IAAI,KAAK,EAAE;AACtB,WAAQ,KAAK;IAAE,KAAK;IAAM,QAAQ;IAAgB,CAAC;AACnD;;EAEF,MAAM,SAAS,iBAAiB,KAAK;AACrC,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,WAAW,OAAO,SAAS,UAAU;AACjF,WAAQ,KAAK;IAAE,KAAK,OAAO;IAAK,QAAQ;IAA4B,CAAC;AACrE;;EAEF,MAAM,KAAK,GAAG,QAAQ,YAAY,eAAe,GAAG,OAAO;EAE3D,MAAMC,cAAsC;GAC1C;GACA,MAHyC,OAAO,SAAS,SAAS,SAAS;GAI3E,MAAM,OAAO,SAAS,SAAS,OAAO,aAAa,OAAO,OAAO,OAAO;GACxE,MAAM,WAAW;AACf,UAAM,aAAa,QAAQ,kBAAkB,OAAO,EAAE,QAAQ,MAAM;;GAEtE,SAAS;IACP;IACA;IACA,GAAI,QAAQ,SAAS,SAAY,EAAE,MAAM,QAAQ,MAAM,GAAG,EAAE;IAC7D;GACF;AACD,QAAM,UAAU,SAAS,YAAY;AACrC,aAAW,KAAK;GAAE;GAAI,MAAM,OAAO;GAAM,KAAK,OAAO;GAAK,CAAC;;AAE7D,QAAO,OAAO,OAAO;EACnB,YAAY,OAAO,OAAO,WAAW;EACrC,SAAS,OAAO,OAAO,QAAQ;EAChC,CAAC"}
1
+ {"version":3,"file":"scheduler.js","names":["catchupPolicy: ConsolidatorCatchupPolicy","registered: Array<{ id: string; kind: ParsedTrigger['kind']; raw: string }>","skipped: Array<{ raw: string; reason: 'unsupported-by-scheduler' | 'filtered-out' }>","declaration: TriggerDeclarationLike"],"sources":["../../src/consolidator/scheduler.ts"],"sourcesContent":["/**\n * Bridge helpers - wire a {@link Consolidator} into the\n * `@graphorin/triggers` Scheduler so trigger declarations fire on\n * the documented schedule (DEC-150 - \"same code path lib + server\").\n *\n * The bridge is structural: any object that exposes the same shape\n * as `@graphorin/triggers`'s `Scheduler` (a `register(declaration)`\n * method) works. The structural import keeps `@graphorin/memory`\n * dependency-free at the type level - the workspace consumer\n * supplies the actual scheduler at runtime.\n *\n * @packageDocumentation\n */\n\nimport type { SessionScope } from '@graphorin/core';\nimport type { Consolidator } from './runtime.js';\nimport { type ParsedTrigger, parseTriggerSpec, reasonFromTrigger } from './triggers.js';\nimport type { ConsolidatorTriggerSpec } from './types.js';\n\n/**\n * Catch-up policy applied when a trigger missed one or more fires\n * while the scheduler was offline. Mirrors\n * `@graphorin/triggers`'s `CatchupPolicy` - duplicated here so the\n * memory package stays import-free at the type level.\n *\n * @stable\n */\nexport type ConsolidatorCatchupPolicy = 'none' | 'last' | 'all';\n\n/**\n * Subset of the `@graphorin/triggers` Scheduler surface the bridge\n * needs. Defined structurally so consumers can inject mocks in\n * tests without taking the package dependency.\n *\n * @stable\n */\nexport interface SchedulerLike {\n register(declaration: TriggerDeclarationLike): Promise<unknown>;\n unregister?(id: string): Promise<void>;\n}\n\n/**\n * Subset of `@graphorin/triggers`'s `TriggerDeclaration` accepted\n * by {@link SchedulerLike.register}. Field names mirror the\n * upstream shape exactly so the structural type is interchangeable\n * with the real export.\n *\n * @stable\n */\nexport interface TriggerDeclarationLike {\n readonly id: string;\n readonly kind: 'cron' | 'interval' | 'idle' | 'event';\n readonly spec: string;\n readonly callback: (payload?: unknown) => void | Promise<void>;\n readonly options: {\n readonly catchupPolicy?: ConsolidatorCatchupPolicy;\n readonly maxCatchupRuns?: number;\n readonly catchupWindowMs?: number;\n readonly tags?: ReadonlyArray<string>;\n readonly acknowledgeLibMode?: boolean;\n };\n}\n\n/** Options accepted by {@link registerConsolidatorTriggers}. */\nexport interface RegisterTriggersOptions {\n /**\n * Scope passed to `consolidator.trigger(...)` for every fire. The\n * consolidator only operates on a single user/session at a time\n * (DEC-005 single-user-per-process); multi-tenant deployments\n * register one scheduler-trigger pair per scope.\n */\n readonly scope: SessionScope;\n /**\n * Catch-up policy applied to every registered trigger. Defaults\n * to `'none'` per DEC-150 - safest for personal-assistant\n * scenarios.\n */\n readonly catchupPolicy?: ConsolidatorCatchupPolicy;\n /** Suppress the per-process library-mode WARN. Defaults to `true`. */\n readonly acknowledgeLibMode?: boolean;\n /** Optional id prefix - useful when multiple scopes share a scheduler. */\n readonly idPrefix?: string;\n /** Optional tags forwarded to the scheduler. */\n readonly tags?: ReadonlyArray<string>;\n /**\n * Filter - only register the supplied subset of triggers. By\n * default every parseable trigger declared on the consolidator is\n * registered (turn / event triggers are skipped because the\n * Scheduler has no way to fire them on its own).\n */\n readonly include?: ReadonlyArray<ConsolidatorTriggerSpec>;\n}\n\n/**\n * Outcome of {@link registerConsolidatorTriggers}.\n *\n * @stable\n */\nexport interface RegisterTriggersResult {\n readonly registered: ReadonlyArray<{\n readonly id: string;\n readonly kind: ParsedTrigger['kind'];\n readonly raw: string;\n }>;\n readonly skipped: ReadonlyArray<{\n readonly raw: string;\n readonly reason: 'unsupported-by-scheduler' | 'filtered-out';\n }>;\n}\n\n/**\n * Register every cron / idle / interval trigger declared on the\n * supplied consolidator with the scheduler. Each trigger fires\n * `consolidator.trigger(reason, scope)` so the lib-mode + server\n * paths converge on the same handler.\n *\n * Turn triggers (`turn:N`) and event triggers (`event:NAME`) are\n * skipped - the scheduler cannot count user turns autonomously, and\n * event triggers fire from the consumer's emit path. The runtime\n * caller is responsible for those (e.g. invoking\n * `consolidator.trigger(...)` from the agent loop).\n *\n * @stable\n */\nexport async function registerConsolidatorTriggers(\n consolidator: Consolidator,\n scheduler: SchedulerLike,\n options: RegisterTriggersOptions,\n): Promise<RegisterTriggersResult> {\n const config = consolidator.config();\n const include = options.include ?? config.triggers;\n const acknowledgeLibMode = options.acknowledgeLibMode ?? true;\n const catchupPolicy: ConsolidatorCatchupPolicy = options.catchupPolicy ?? 'none';\n const registered: Array<{ id: string; kind: ParsedTrigger['kind']; raw: string }> = [];\n const skipped: Array<{ raw: string; reason: 'unsupported-by-scheduler' | 'filtered-out' }> = [];\n const seenSet = new Set(include);\n for (const spec of config.triggers) {\n if (!seenSet.has(spec)) {\n skipped.push({ raw: spec, reason: 'filtered-out' });\n continue;\n }\n const parsed = parseTriggerSpec(spec);\n if (parsed.kind === 'turn' || parsed.kind === 'event' || parsed.kind === 'budget') {\n skipped.push({ raw: parsed.raw, reason: 'unsupported-by-scheduler' });\n continue;\n }\n const id = `${options.idPrefix ?? 'consolidator'}:${parsed.raw}`;\n const kind: 'cron' | 'idle' | 'interval' = parsed.kind === 'cron' ? 'cron' : 'idle';\n const declaration: TriggerDeclarationLike = {\n id,\n kind,\n spec: parsed.kind === 'cron' ? parsed.expression : String(parsed.idleMs),\n async callback() {\n await consolidator.trigger(reasonFromTrigger(parsed), options.scope);\n },\n options: {\n catchupPolicy,\n acknowledgeLibMode,\n ...(options.tags !== undefined ? { tags: options.tags } : {}),\n },\n };\n await scheduler.register(declaration);\n registered.push({ id, kind: parsed.kind, raw: parsed.raw });\n }\n return Object.freeze({\n registered: Object.freeze(registered),\n skipped: Object.freeze(skipped),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA4HA,eAAsB,6BACpB,cACA,WACA,SACiC;CACjC,MAAM,SAAS,aAAa,QAAQ;CACpC,MAAM,UAAU,QAAQ,WAAW,OAAO;CAC1C,MAAM,qBAAqB,QAAQ,sBAAsB;CACzD,MAAMA,gBAA2C,QAAQ,iBAAiB;CAC1E,MAAMC,aAA8E,EAAE;CACtF,MAAMC,UAAuF,EAAE;CAC/F,MAAM,UAAU,IAAI,IAAI,QAAQ;AAChC,MAAK,MAAM,QAAQ,OAAO,UAAU;AAClC,MAAI,CAAC,QAAQ,IAAI,KAAK,EAAE;AACtB,WAAQ,KAAK;IAAE,KAAK;IAAM,QAAQ;IAAgB,CAAC;AACnD;;EAEF,MAAM,SAAS,iBAAiB,KAAK;AACrC,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,WAAW,OAAO,SAAS,UAAU;AACjF,WAAQ,KAAK;IAAE,KAAK,OAAO;IAAK,QAAQ;IAA4B,CAAC;AACrE;;EAEF,MAAM,KAAK,GAAG,QAAQ,YAAY,eAAe,GAAG,OAAO;EAE3D,MAAMC,cAAsC;GAC1C;GACA,MAHyC,OAAO,SAAS,SAAS,SAAS;GAI3E,MAAM,OAAO,SAAS,SAAS,OAAO,aAAa,OAAO,OAAO,OAAO;GACxE,MAAM,WAAW;AACf,UAAM,aAAa,QAAQ,kBAAkB,OAAO,EAAE,QAAQ,MAAM;;GAEtE,SAAS;IACP;IACA;IACA,GAAI,QAAQ,SAAS,SAAY,EAAE,MAAM,QAAQ,MAAM,GAAG,EAAE;IAC7D;GACF;AACD,QAAM,UAAU,SAAS,YAAY;AACrC,aAAW,KAAK;GAAE;GAAI,MAAM,OAAO;GAAM,KAAK,OAAO;GAAK,CAAC;;AAE7D,QAAO,OAAO,OAAO;EACnB,YAAY,OAAO,OAAO,WAAW;EACrC,SAAS,OAAO,OAAO,QAAQ;EAChC,CAAC"}
@@ -4,13 +4,13 @@ const IDLE_PATTERN = /^(\d+(?:\.\d+)?)(ms|s|m|h)?$/u;
4
4
  function parseTriggerSpec(spec) {
5
5
  if (typeof spec !== "string" || spec.length === 0) throw new TypeError(`[graphorin/memory] consolidator trigger spec must be a non-empty string, got ${typeof spec}`);
6
6
  const colon = spec.indexOf(":");
7
- if (colon < 0) throw new TypeError(`[graphorin/memory] invalid trigger spec '${spec}' expected 'kind:value'`);
7
+ if (colon < 0) throw new TypeError(`[graphorin/memory] invalid trigger spec '${spec}' - expected 'kind:value'`);
8
8
  const kind = spec.slice(0, colon);
9
9
  const value = spec.slice(colon + 1);
10
10
  switch (kind) {
11
11
  case "turn": {
12
12
  const count = Number.parseInt(value, 10);
13
- if (!Number.isFinite(count) || count <= 0) throw new TypeError(`[graphorin/memory] invalid turn trigger '${spec}' expected positive integer`);
13
+ if (!Number.isFinite(count) || count <= 0) throw new TypeError(`[graphorin/memory] invalid turn trigger '${spec}' - expected positive integer`);
14
14
  return {
15
15
  kind: "turn",
16
16
  count,
@@ -19,9 +19,9 @@ function parseTriggerSpec(spec) {
19
19
  }
20
20
  case "idle": {
21
21
  const match = IDLE_PATTERN.exec(value);
22
- if (match === null) throw new TypeError(`[graphorin/memory] invalid idle trigger '${spec}' expected '5m' / '30s' / '1h'`);
22
+ if (match === null) throw new TypeError(`[graphorin/memory] invalid idle trigger '${spec}' - expected '5m' / '30s' / '1h'`);
23
23
  const idleMs = toMs(Number.parseFloat(match[1] ?? "NaN"), match[2] ?? "ms");
24
- if (!Number.isFinite(idleMs) || idleMs <= 0) throw new TypeError(`[graphorin/memory] invalid idle trigger '${spec}' non-positive duration`);
24
+ if (!Number.isFinite(idleMs) || idleMs <= 0) throw new TypeError(`[graphorin/memory] invalid idle trigger '${spec}' - non-positive duration`);
25
25
  return {
26
26
  kind: "idle",
27
27
  idleMs,
@@ -29,14 +29,14 @@ function parseTriggerSpec(spec) {
29
29
  };
30
30
  }
31
31
  case "cron":
32
- if (value.trim().length === 0) throw new TypeError(`[graphorin/memory] invalid cron trigger '${spec}' empty expression`);
32
+ if (value.trim().length === 0) throw new TypeError(`[graphorin/memory] invalid cron trigger '${spec}' - empty expression`);
33
33
  return {
34
34
  kind: "cron",
35
35
  expression: value,
36
36
  raw: spec
37
37
  };
38
38
  case "event":
39
- if (value.length === 0) throw new TypeError(`[graphorin/memory] invalid event trigger '${spec}' empty event name`);
39
+ if (value.length === 0) throw new TypeError(`[graphorin/memory] invalid event trigger '${spec}' - empty event name`);
40
40
  return {
41
41
  kind: "event",
42
42
  name: value,
@@ -44,7 +44,7 @@ function parseTriggerSpec(spec) {
44
44
  };
45
45
  case "budget": {
46
46
  const threshold = Number.parseFloat(value);
47
- if (!Number.isFinite(threshold) || threshold <= 0 || threshold >= 1) throw new TypeError(`[graphorin/memory] invalid budget trigger '${spec}' expected fraction between 0 and 1`);
47
+ if (!Number.isFinite(threshold) || threshold <= 0 || threshold >= 1) throw new TypeError(`[graphorin/memory] invalid budget trigger '${spec}' - expected fraction between 0 and 1`);
48
48
  return {
49
49
  kind: "budget",
50
50
  threshold,
@@ -1 +1 @@
1
- {"version":3,"file":"triggers.js","names":[],"sources":["../../src/consolidator/triggers.ts"],"sourcesContent":["/**\n * Trigger spec parser. Translates the human-friendly\n * `'turn:N'` / `'idle:Xm'` / `'cron:EXPR'` / `'event:NAME'` /\n * `'budget:N'` declarations into the runtime structure used by the\n * consolidator.\n *\n * The parser is exhaustive: every shape recognised here must be\n * matched in {@link parseTriggerSpec}; unrecognised shapes throw a\n * `TypeError` so misconfigured triggers fail at registration time\n * rather than silently never firing.\n *\n * @packageDocumentation\n */\n\nimport type { ConsolidatorTriggerReason, ConsolidatorTriggerSpec } from './types.js';\n\n/**\n * Parsed trigger declaration. The `kind` discriminator drives the\n * runtime dispatch; the `value` carries the spec-specific argument\n * already converted to a `number` (turns / millis / threshold) or a\n * string (cron expr / event name).\n *\n * @stable\n */\nexport type ParsedTrigger =\n | { readonly kind: 'turn'; readonly count: number; readonly raw: string }\n | { readonly kind: 'idle'; readonly idleMs: number; readonly raw: string }\n | { readonly kind: 'cron'; readonly expression: string; readonly raw: string }\n | { readonly kind: 'event'; readonly name: string; readonly raw: string }\n | { readonly kind: 'budget'; readonly threshold: number; readonly raw: string };\n\nconst IDLE_PATTERN = /^(\\d+(?:\\.\\d+)?)(ms|s|m|h)?$/u;\n\n/** Parse a {@link ConsolidatorTriggerSpec} into a {@link ParsedTrigger}. */\nexport function parseTriggerSpec(spec: ConsolidatorTriggerSpec): ParsedTrigger {\n if (typeof spec !== 'string' || spec.length === 0) {\n throw new TypeError(\n `[graphorin/memory] consolidator trigger spec must be a non-empty string, got ${typeof spec}`,\n );\n }\n const colon = spec.indexOf(':');\n if (colon < 0) {\n throw new TypeError(\n `[graphorin/memory] invalid trigger spec '${spec}' expected 'kind:value'`,\n );\n }\n const kind = spec.slice(0, colon);\n const value = spec.slice(colon + 1);\n\n switch (kind) {\n case 'turn': {\n const count = Number.parseInt(value, 10);\n if (!Number.isFinite(count) || count <= 0) {\n throw new TypeError(\n `[graphorin/memory] invalid turn trigger '${spec}' expected positive integer`,\n );\n }\n return { kind: 'turn', count, raw: spec };\n }\n case 'idle': {\n const match = IDLE_PATTERN.exec(value);\n if (match === null) {\n throw new TypeError(\n `[graphorin/memory] invalid idle trigger '${spec}' expected '5m' / '30s' / '1h'`,\n );\n }\n const num = Number.parseFloat(match[1] ?? 'NaN');\n const unit = match[2] ?? 'ms';\n const idleMs = toMs(num, unit);\n if (!Number.isFinite(idleMs) || idleMs <= 0) {\n throw new TypeError(\n `[graphorin/memory] invalid idle trigger '${spec}' non-positive duration`,\n );\n }\n return { kind: 'idle', idleMs, raw: spec };\n }\n case 'cron': {\n if (value.trim().length === 0) {\n throw new TypeError(`[graphorin/memory] invalid cron trigger '${spec}' empty expression`);\n }\n return { kind: 'cron', expression: value, raw: spec };\n }\n case 'event': {\n if (value.length === 0) {\n throw new TypeError(\n `[graphorin/memory] invalid event trigger '${spec}' empty event name`,\n );\n }\n return { kind: 'event', name: value, raw: spec };\n }\n case 'budget': {\n const threshold = Number.parseFloat(value);\n if (!Number.isFinite(threshold) || threshold <= 0 || threshold >= 1) {\n throw new TypeError(\n `[graphorin/memory] invalid budget trigger '${spec}' expected fraction between 0 and 1`,\n );\n }\n return { kind: 'budget', threshold, raw: spec };\n }\n default:\n throw new TypeError(`[graphorin/memory] unknown consolidator trigger kind '${kind}'`);\n }\n}\n\n/** Build a {@link ConsolidatorTriggerReason} from a parsed trigger. */\nexport function reasonFromTrigger(trigger: ParsedTrigger): ConsolidatorTriggerReason {\n switch (trigger.kind) {\n case 'turn':\n return { kind: 'turn', value: trigger.count };\n case 'idle':\n return { kind: 'idle', value: trigger.raw };\n case 'cron':\n return { kind: 'cron', value: trigger.expression };\n case 'event':\n return { kind: 'event', value: trigger.name };\n case 'budget':\n return { kind: 'budget', value: trigger.threshold };\n }\n}\n\nfunction toMs(value: number, unit: string): number {\n switch (unit) {\n case 'ms':\n return value;\n case 's':\n return value * 1000;\n case 'm':\n return value * 60 * 1000;\n case 'h':\n return value * 60 * 60 * 1000;\n default:\n return Number.NaN;\n }\n}\n"],"mappings":";AA+BA,MAAM,eAAe;;AAGrB,SAAgB,iBAAiB,MAA8C;AAC7E,KAAI,OAAO,SAAS,YAAY,KAAK,WAAW,EAC9C,OAAM,IAAI,UACR,gFAAgF,OAAO,OACxF;CAEH,MAAM,QAAQ,KAAK,QAAQ,IAAI;AAC/B,KAAI,QAAQ,EACV,OAAM,IAAI,UACR,4CAA4C,KAAK,2BAClD;CAEH,MAAM,OAAO,KAAK,MAAM,GAAG,MAAM;CACjC,MAAM,QAAQ,KAAK,MAAM,QAAQ,EAAE;AAEnC,SAAQ,MAAR;EACE,KAAK,QAAQ;GACX,MAAM,QAAQ,OAAO,SAAS,OAAO,GAAG;AACxC,OAAI,CAAC,OAAO,SAAS,MAAM,IAAI,SAAS,EACtC,OAAM,IAAI,UACR,4CAA4C,KAAK,+BAClD;AAEH,UAAO;IAAE,MAAM;IAAQ;IAAO,KAAK;IAAM;;EAE3C,KAAK,QAAQ;GACX,MAAM,QAAQ,aAAa,KAAK,MAAM;AACtC,OAAI,UAAU,KACZ,OAAM,IAAI,UACR,4CAA4C,KAAK,kCAClD;GAIH,MAAM,SAAS,KAFH,OAAO,WAAW,MAAM,MAAM,MAAM,EACnC,MAAM,MAAM,KACK;AAC9B,OAAI,CAAC,OAAO,SAAS,OAAO,IAAI,UAAU,EACxC,OAAM,IAAI,UACR,4CAA4C,KAAK,2BAClD;AAEH,UAAO;IAAE,MAAM;IAAQ;IAAQ,KAAK;IAAM;;EAE5C,KAAK;AACH,OAAI,MAAM,MAAM,CAAC,WAAW,EAC1B,OAAM,IAAI,UAAU,4CAA4C,KAAK,sBAAsB;AAE7F,UAAO;IAAE,MAAM;IAAQ,YAAY;IAAO,KAAK;IAAM;EAEvD,KAAK;AACH,OAAI,MAAM,WAAW,EACnB,OAAM,IAAI,UACR,6CAA6C,KAAK,sBACnD;AAEH,UAAO;IAAE,MAAM;IAAS,MAAM;IAAO,KAAK;IAAM;EAElD,KAAK,UAAU;GACb,MAAM,YAAY,OAAO,WAAW,MAAM;AAC1C,OAAI,CAAC,OAAO,SAAS,UAAU,IAAI,aAAa,KAAK,aAAa,EAChE,OAAM,IAAI,UACR,8CAA8C,KAAK,uCACpD;AAEH,UAAO;IAAE,MAAM;IAAU;IAAW,KAAK;IAAM;;EAEjD,QACE,OAAM,IAAI,UAAU,yDAAyD,KAAK,GAAG;;;;AAK3F,SAAgB,kBAAkB,SAAmD;AACnF,SAAQ,QAAQ,MAAhB;EACE,KAAK,OACH,QAAO;GAAE,MAAM;GAAQ,OAAO,QAAQ;GAAO;EAC/C,KAAK,OACH,QAAO;GAAE,MAAM;GAAQ,OAAO,QAAQ;GAAK;EAC7C,KAAK,OACH,QAAO;GAAE,MAAM;GAAQ,OAAO,QAAQ;GAAY;EACpD,KAAK,QACH,QAAO;GAAE,MAAM;GAAS,OAAO,QAAQ;GAAM;EAC/C,KAAK,SACH,QAAO;GAAE,MAAM;GAAU,OAAO,QAAQ;GAAW;;;AAIzD,SAAS,KAAK,OAAe,MAAsB;AACjD,SAAQ,MAAR;EACE,KAAK,KACH,QAAO;EACT,KAAK,IACH,QAAO,QAAQ;EACjB,KAAK,IACH,QAAO,QAAQ,KAAK;EACtB,KAAK,IACH,QAAO,QAAQ,KAAK,KAAK;EAC3B,QACE,QAAO"}
1
+ {"version":3,"file":"triggers.js","names":[],"sources":["../../src/consolidator/triggers.ts"],"sourcesContent":["/**\n * Trigger spec parser. Translates the human-friendly\n * `'turn:N'` / `'idle:Xm'` / `'cron:EXPR'` / `'event:NAME'` /\n * `'budget:N'` declarations into the runtime structure used by the\n * consolidator.\n *\n * The parser is exhaustive: every shape recognised here must be\n * matched in {@link parseTriggerSpec}; unrecognised shapes throw a\n * `TypeError` so misconfigured triggers fail at registration time\n * rather than silently never firing.\n *\n * @packageDocumentation\n */\n\nimport type { ConsolidatorTriggerReason, ConsolidatorTriggerSpec } from './types.js';\n\n/**\n * Parsed trigger declaration. The `kind` discriminator drives the\n * runtime dispatch; the `value` carries the spec-specific argument\n * already converted to a `number` (turns / millis / threshold) or a\n * string (cron expr / event name).\n *\n * @stable\n */\nexport type ParsedTrigger =\n | { readonly kind: 'turn'; readonly count: number; readonly raw: string }\n | { readonly kind: 'idle'; readonly idleMs: number; readonly raw: string }\n | { readonly kind: 'cron'; readonly expression: string; readonly raw: string }\n | { readonly kind: 'event'; readonly name: string; readonly raw: string }\n | { readonly kind: 'budget'; readonly threshold: number; readonly raw: string };\n\nconst IDLE_PATTERN = /^(\\d+(?:\\.\\d+)?)(ms|s|m|h)?$/u;\n\n/** Parse a {@link ConsolidatorTriggerSpec} into a {@link ParsedTrigger}. */\nexport function parseTriggerSpec(spec: ConsolidatorTriggerSpec): ParsedTrigger {\n if (typeof spec !== 'string' || spec.length === 0) {\n throw new TypeError(\n `[graphorin/memory] consolidator trigger spec must be a non-empty string, got ${typeof spec}`,\n );\n }\n const colon = spec.indexOf(':');\n if (colon < 0) {\n throw new TypeError(\n `[graphorin/memory] invalid trigger spec '${spec}' - expected 'kind:value'`,\n );\n }\n const kind = spec.slice(0, colon);\n const value = spec.slice(colon + 1);\n\n switch (kind) {\n case 'turn': {\n const count = Number.parseInt(value, 10);\n if (!Number.isFinite(count) || count <= 0) {\n throw new TypeError(\n `[graphorin/memory] invalid turn trigger '${spec}' - expected positive integer`,\n );\n }\n return { kind: 'turn', count, raw: spec };\n }\n case 'idle': {\n const match = IDLE_PATTERN.exec(value);\n if (match === null) {\n throw new TypeError(\n `[graphorin/memory] invalid idle trigger '${spec}' - expected '5m' / '30s' / '1h'`,\n );\n }\n const num = Number.parseFloat(match[1] ?? 'NaN');\n const unit = match[2] ?? 'ms';\n const idleMs = toMs(num, unit);\n if (!Number.isFinite(idleMs) || idleMs <= 0) {\n throw new TypeError(\n `[graphorin/memory] invalid idle trigger '${spec}' - non-positive duration`,\n );\n }\n return { kind: 'idle', idleMs, raw: spec };\n }\n case 'cron': {\n if (value.trim().length === 0) {\n throw new TypeError(`[graphorin/memory] invalid cron trigger '${spec}' - empty expression`);\n }\n return { kind: 'cron', expression: value, raw: spec };\n }\n case 'event': {\n if (value.length === 0) {\n throw new TypeError(\n `[graphorin/memory] invalid event trigger '${spec}' - empty event name`,\n );\n }\n return { kind: 'event', name: value, raw: spec };\n }\n case 'budget': {\n const threshold = Number.parseFloat(value);\n if (!Number.isFinite(threshold) || threshold <= 0 || threshold >= 1) {\n throw new TypeError(\n `[graphorin/memory] invalid budget trigger '${spec}' - expected fraction between 0 and 1`,\n );\n }\n return { kind: 'budget', threshold, raw: spec };\n }\n default:\n throw new TypeError(`[graphorin/memory] unknown consolidator trigger kind '${kind}'`);\n }\n}\n\n/** Build a {@link ConsolidatorTriggerReason} from a parsed trigger. */\nexport function reasonFromTrigger(trigger: ParsedTrigger): ConsolidatorTriggerReason {\n switch (trigger.kind) {\n case 'turn':\n return { kind: 'turn', value: trigger.count };\n case 'idle':\n return { kind: 'idle', value: trigger.raw };\n case 'cron':\n return { kind: 'cron', value: trigger.expression };\n case 'event':\n return { kind: 'event', value: trigger.name };\n case 'budget':\n return { kind: 'budget', value: trigger.threshold };\n }\n}\n\nfunction toMs(value: number, unit: string): number {\n switch (unit) {\n case 'ms':\n return value;\n case 's':\n return value * 1000;\n case 'm':\n return value * 60 * 1000;\n case 'h':\n return value * 60 * 60 * 1000;\n default:\n return Number.NaN;\n }\n}\n"],"mappings":";AA+BA,MAAM,eAAe;;AAGrB,SAAgB,iBAAiB,MAA8C;AAC7E,KAAI,OAAO,SAAS,YAAY,KAAK,WAAW,EAC9C,OAAM,IAAI,UACR,gFAAgF,OAAO,OACxF;CAEH,MAAM,QAAQ,KAAK,QAAQ,IAAI;AAC/B,KAAI,QAAQ,EACV,OAAM,IAAI,UACR,4CAA4C,KAAK,2BAClD;CAEH,MAAM,OAAO,KAAK,MAAM,GAAG,MAAM;CACjC,MAAM,QAAQ,KAAK,MAAM,QAAQ,EAAE;AAEnC,SAAQ,MAAR;EACE,KAAK,QAAQ;GACX,MAAM,QAAQ,OAAO,SAAS,OAAO,GAAG;AACxC,OAAI,CAAC,OAAO,SAAS,MAAM,IAAI,SAAS,EACtC,OAAM,IAAI,UACR,4CAA4C,KAAK,+BAClD;AAEH,UAAO;IAAE,MAAM;IAAQ;IAAO,KAAK;IAAM;;EAE3C,KAAK,QAAQ;GACX,MAAM,QAAQ,aAAa,KAAK,MAAM;AACtC,OAAI,UAAU,KACZ,OAAM,IAAI,UACR,4CAA4C,KAAK,kCAClD;GAIH,MAAM,SAAS,KAFH,OAAO,WAAW,MAAM,MAAM,MAAM,EACnC,MAAM,MAAM,KACK;AAC9B,OAAI,CAAC,OAAO,SAAS,OAAO,IAAI,UAAU,EACxC,OAAM,IAAI,UACR,4CAA4C,KAAK,2BAClD;AAEH,UAAO;IAAE,MAAM;IAAQ;IAAQ,KAAK;IAAM;;EAE5C,KAAK;AACH,OAAI,MAAM,MAAM,CAAC,WAAW,EAC1B,OAAM,IAAI,UAAU,4CAA4C,KAAK,sBAAsB;AAE7F,UAAO;IAAE,MAAM;IAAQ,YAAY;IAAO,KAAK;IAAM;EAEvD,KAAK;AACH,OAAI,MAAM,WAAW,EACnB,OAAM,IAAI,UACR,6CAA6C,KAAK,sBACnD;AAEH,UAAO;IAAE,MAAM;IAAS,MAAM;IAAO,KAAK;IAAM;EAElD,KAAK,UAAU;GACb,MAAM,YAAY,OAAO,WAAW,MAAM;AAC1C,OAAI,CAAC,OAAO,SAAS,UAAU,IAAI,aAAa,KAAK,aAAa,EAChE,OAAM,IAAI,UACR,8CAA8C,KAAK,uCACpD;AAEH,UAAO;IAAE,MAAM;IAAU;IAAW,KAAK;IAAM;;EAEjD,QACE,OAAM,IAAI,UAAU,yDAAyD,KAAK,GAAG;;;;AAK3F,SAAgB,kBAAkB,SAAmD;AACnF,SAAQ,QAAQ,MAAhB;EACE,KAAK,OACH,QAAO;GAAE,MAAM;GAAQ,OAAO,QAAQ;GAAO;EAC/C,KAAK,OACH,QAAO;GAAE,MAAM;GAAQ,OAAO,QAAQ;GAAK;EAC7C,KAAK,OACH,QAAO;GAAE,MAAM;GAAQ,OAAO,QAAQ;GAAY;EACpD,KAAK,QACH,QAAO;GAAE,MAAM;GAAS,OAAO,QAAQ;GAAM;EAC/C,KAAK,SACH,QAAO;GAAE,MAAM;GAAU,OAAO,QAAQ;GAAW;;;AAIzD,SAAS,KAAK,OAAe,MAAsB;AACjD,SAAQ,MAAR;EACE,KAAK,KACH,QAAO;EACT,KAAK,IACH,QAAO,QAAQ;EACjB,KAAK,IACH,QAAO,QAAQ,KAAK;EACtB,KAAK,IACH,QAAO,QAAQ,KAAK,KAAK;EAC3B,QACE,QAAO"}
@@ -1,8 +1,9 @@
1
1
  import { MemoryStoreAdapter } from "../internal/storage-adapter.js";
2
2
  import { ContextualRetrievalMode } from "../internal/contextualize.js";
3
3
  import { EpisodicMemory } from "../tiers/episodic-memory.js";
4
- import { SemanticMemory } from "../tiers/semantic-memory.js";
5
4
  import { SalienceWeights } from "./decay.js";
5
+ import { SemanticMemory } from "../tiers/semantic-memory.js";
6
+ import { WorkingMemory } from "../tiers/working-memory.js";
6
7
  import { Provider, SessionScope, Tracer } from "@graphorin/core";
7
8
 
8
9
  //#region src/consolidator/types.d.ts
@@ -17,7 +18,7 @@ import { Provider, SessionScope, Tracer } from "@graphorin/core";
17
18
  type ConsolidatorTriggerSpec = `turn:${number}` | `idle:${string}` | `cron:${string}` | `event:${string}` | `budget:${number}`;
18
19
  /**
19
20
  * Tier preset that selects a consolidator behaviour bundle. The
20
- * `'free'` preset is the default per DEC-144 / ADR-038 no LLM call
21
+ * `'free'` preset is the default per DEC-144 / ADR-038 - no LLM call
21
22
  * fires until the operator opts in.
22
23
  *
23
24
  * @stable
@@ -33,7 +34,12 @@ interface ConsolidatorTriggerReason {
33
34
  readonly value?: string | number;
34
35
  }
35
36
  /**
36
- * Hard cost ceilings enforced atomically per UTC day. The default
37
+ * Daily cost ceilings, tracked per budget window. How a breach is
38
+ * handled depends on {@link OnBudgetExceed}: `'pause'` / `'throw'`
39
+ * enforce, `'log'` (the shipped standard/full presets) only WARNs and
40
+ * keeps running. The USD leg accumulates only when a `priceUsage`
41
+ * pricer is configured (memory-consolidation-02) - without one every
42
+ * call prices at $0 and `maxCostPerDay` can never trip. The default
37
43
  * ceiling shape per tier is captured in
38
44
  * {@link CONSOLIDATOR_TIER_DEFAULTS}.
39
45
  *
@@ -61,7 +67,7 @@ interface ConsolidatorCeilings {
61
67
  }
62
68
  /**
63
69
  * Behaviour applied by the budget enforcer when a ceiling is hit
64
- * mid-run. `'pause'` is the conservative default the consolidator
70
+ * mid-run. `'pause'` is the conservative default - the consolidator
65
71
  * skips subsequent runs until the next budget reset; `'log'` keeps
66
72
  * running with a WARN; `'throw'` raises a typed
67
73
  * {@link BudgetExceededError}.
@@ -87,14 +93,14 @@ interface ConsolidatorConfig {
87
93
  readonly ceilings: ConsolidatorCeilings;
88
94
  readonly onExceed: OnBudgetExceed;
89
95
  /**
90
- * Advisory label for the standard phase's model recorded on spans /
96
+ * Advisory label for the standard phase's model - recorded on spans /
91
97
  * run telemetry only (MCON-7). Routing happens via
92
98
  * `CreateConsolidatorOptions.cheapProvider`; this string disables
93
99
  * nothing.
94
100
  */
95
101
  readonly cheapModel: string | null;
96
102
  /**
97
- * Advisory label for the deep phase's model telemetry only
103
+ * Advisory label for the deep phase's model - telemetry only
98
104
  * (MCON-7). Routing happens via
99
105
  * `CreateConsolidatorOptions.deepProvider`.
100
106
  */
@@ -107,7 +113,7 @@ interface ConsolidatorConfig {
107
113
  /**
108
114
  * Capacity-bounded eviction target for the light phase (X-1). When set,
109
115
  * each light pass archives the lowest-salience live facts in the LRU
110
- * decay window down to this many **cost / staleness control, not an
116
+ * decay window down to this many - **cost / staleness control, not an
111
117
  * accuracy lever**. `null` (the default at every tier) leaves storage
112
118
  * unbounded, so behaviour is identical to pre-X-1. Archiving is a soft,
113
119
  * recoverable move; nothing is hard-deleted.
@@ -135,9 +141,9 @@ interface ConsolidatorConfig {
135
141
  readonly formEpisodes: boolean;
136
142
  /**
137
143
  * Ask the episode-summarization call for an LLM importance score
138
- * (110, normalized to `[0, 1]`) so episodic triple-signal retrieval
144
+ * (1-10, normalized to `[0, 1]`) so episodic triple-signal retrieval
139
145
  * (recency × relevance × importance) runs on all three signals
140
- * (P1-2). Importance is always a *soft* signal it never gates
146
+ * (P1-2). Importance is always a *soft* signal - it never gates
141
147
  * retention. Defaults track {@link formEpisodes}.
142
148
  */
143
149
  readonly importanceScoring: boolean;
@@ -146,7 +152,7 @@ interface ConsolidatorConfig {
146
152
  * injection-clean **extraction** fact as `active` instead of quarantined, so
147
153
  * routine distillation surfaces in default recall without a manual
148
154
  * `memory review --promote`. Injection-flagged facts always stay quarantined
149
- * the security gate is preserved and episodes / insights / induced
155
+ * - the security gate is preserved - and episodes / insights / induced
150
156
  * procedures are unaffected (they remain quarantined-until-validated).
151
157
  * Defaults **off** at every tier: it trades the fail-safe default for
152
158
  * convenience and is an explicit operator opt-in.
@@ -158,7 +164,7 @@ interface ConsolidatorConfig {
158
164
  * higher-order, cited insights over recent memories (Generative
159
165
  * Agents). Insights land quarantined + `provenance: 'reflection'` and
160
166
  * are ranked below the facts they cite. Defaults **on at the `full`
161
- * tier only** (off at `free` / `cheap` / `standard` / `custom`) it
167
+ * tier only** (off at `free` / `cheap` / `standard` / `custom`) - it
162
168
  * is the most LLM-intensive phase. A no-op without an episodic tier
163
169
  * or an insight-capable storage adapter.
164
170
  */
@@ -175,14 +181,25 @@ interface ConsolidatorConfig {
175
181
  * Contextual retrieval for facts written by the standard phase (P1-3).
176
182
  * `'late-chunk'` (default at every tier) relies on the offline
177
183
  * situating-context prefix the shared {@link SemanticMemory} computes
178
- * for every write no extra LLM call. `'llm'` is the opt-in
184
+ * for every write - no extra LLM call. `'llm'` is the opt-in
179
185
  * enrichment: the standard phase spends one budgeted cheap-model call
180
- * per additive write to author a 12 sentence situating prefix, then
186
+ * per additive write to author a 1-2 sentence situating prefix, then
181
187
  * passes it as the write's index text. `'off'` indexes the bare text.
182
- * The `'llm'` mode is **consolidator-only** by construction the hot
188
+ * The `'llm'` mode is **consolidator-only** by construction - the hot
183
189
  * write path never has a provider for contextualization.
184
190
  */
185
191
  readonly contextualRetrieval: ContextualRetrievalMode;
192
+ /**
193
+ * Maintain the learned-context digest block (D3): after the deep
194
+ * phase, one budgeted LLM call rewrites the reserved
195
+ * `learned_context` working block from the previous digest + recent
196
+ * episodes / active insights / active procedures, so the system
197
+ * prompt carries a compact standing summary. Defaults **off at every
198
+ * tier** (Wave-D trial) - a no-op without a working tier handle.
199
+ */
200
+ readonly learnedContext: boolean;
201
+ /** Character bound enforced on the learned-context digest. Default `1200`. */
202
+ readonly learnedContextMaxChars: number;
186
203
  }
187
204
  /**
188
205
  * Per-phase last-run snapshot surfaced inside
@@ -216,7 +233,7 @@ interface ConsolidatorBudgetSnapshot {
216
233
  * Status snapshot returned by {@link Consolidator.status}.
217
234
  *
218
235
  * Public shape: `{ tier, queueDepth, dlqSize, lastRuns,
219
- * budgetRemaining, deferredRuns }` extended with a few additional
236
+ * budgetRemaining, deferredRuns }` - extended with a few additional
220
237
  * fields the server health endpoint and the
221
238
  * `graphorin consolidator status` CLI consume.
222
239
  *
@@ -245,7 +262,7 @@ interface ConsolidatorStatus {
245
262
  readonly deferredRuns: number;
246
263
  readonly emptyExtractions: number;
247
264
  readonly budget: ConsolidatorBudgetSnapshot;
248
- /** Spec alias surfaces remaining-budget figures at the top level. */
265
+ /** Spec alias - surfaces remaining-budget figures at the top level. */
249
266
  readonly budgetRemaining: {
250
267
  readonly tokens: number;
251
268
  readonly costUsd: number;
@@ -267,6 +284,8 @@ interface PhaseOutcome {
267
284
  readonly episodesFormed: number;
268
285
  /** Insights synthesized by the deep-phase reflection pass (P1-1). */
269
286
  readonly insightsCreated: number;
287
+ /** True when the learned-context digest block was rewritten (D3). */
288
+ readonly learnedContextUpdated?: boolean;
270
289
  readonly noiseFilteredCount: number;
271
290
  readonly emptyExtractions: number;
272
291
  readonly llmTokensUsed: number;
@@ -290,7 +309,7 @@ type PhaseListener = (outcome: PhaseOutcome & {
290
309
  */
291
310
  interface CreateConsolidatorOptions {
292
311
  /**
293
- * Storage adapter supplies the consolidator state, runs, DLQ,
312
+ * Storage adapter - supplies the consolidator state, runs, DLQ,
294
313
  * and per-tier helpers. The default `@graphorin/store-sqlite`
295
314
  * adapter exposes everything by construction.
296
315
  */
@@ -309,6 +328,13 @@ interface CreateConsolidatorOptions {
309
328
  * processed slice (P1-2). Omitted ⇒ episode formation is skipped.
310
329
  */
311
330
  readonly episodic?: EpisodicMemory;
331
+ /**
332
+ * The {@link WorkingMemory} tier instance from the parent
333
+ * `createMemory(...)` facade (D3). Required for the learned-context
334
+ * pass - without it the pass is a silent no-op even when
335
+ * `learnedContext` is enabled.
336
+ */
337
+ readonly working?: WorkingMemory;
312
338
  /**
313
339
  * Provider used by the standard + deep phases. Required when the
314
340
  * tier enables either phase; ignored when the active phases
@@ -316,15 +342,31 @@ interface CreateConsolidatorOptions {
316
342
  */
317
343
  readonly provider?: Provider | null;
318
344
  readonly tracer?: Tracer;
319
- /** Override the wall clock used by tests. */
345
+ /** Override the wall clock - used by tests. */
320
346
  readonly now?: () => number;
321
- /** Random source for stable run ids used by tests. */
347
+ /** Random source for stable run ids - used by tests. */
322
348
  readonly randomId?: () => string;
323
349
  readonly triggers?: ReadonlyArray<ConsolidatorTriggerSpec>;
324
350
  readonly tier?: ConsolidatorTier;
325
351
  readonly phases?: ReadonlyArray<ConsolidatorPhase>;
326
352
  readonly ceilings?: Partial<ConsolidatorCeilings>;
327
353
  readonly onExceed?: OnBudgetExceed;
354
+ /**
355
+ * USD pricer for phase LLM usage (memory-consolidation-02). Wire it
356
+ * to `@graphorin/pricing`'s `calculateCost` (or any per-token rate)
357
+ * so the `maxCostPerDay` ceiling can actually accumulate spend -
358
+ * without it every phase prices its calls at $0 and the USD ceiling
359
+ * never trips at any tier.
360
+ *
361
+ * ```ts
362
+ * priceUsage: ({ promptTokens, completionTokens }) =>
363
+ * (promptTokens * 3 + completionTokens * 15) / 1_000_000
364
+ * ```
365
+ */
366
+ readonly priceUsage?: (usage: {
367
+ promptTokens: number;
368
+ completionTokens: number;
369
+ }) => number;
328
370
  /**
329
371
  * Provider routed to the standard phase (extraction / episode /
330
372
  * reconcile / situating-context calls) when set (MCON-7). Falls back
@@ -369,11 +411,15 @@ interface CreateConsolidatorOptions {
369
411
  readonly reflectionMaxQuestions?: number;
370
412
  /** Override the per-tier {@link ConsolidatorConfig.contextualRetrieval} default (P1-3). */
371
413
  readonly contextualRetrieval?: ContextualRetrievalMode;
414
+ /** Override the per-tier {@link ConsolidatorConfig.learnedContext} default (D3). */
415
+ readonly learnedContext?: boolean;
416
+ /** Override the {@link ConsolidatorConfig.learnedContextMaxChars} default (D3). */
417
+ readonly learnedContextMaxChars?: number;
372
418
  /** Default scope used by event triggers + the manual `fireNow` path. */
373
419
  readonly defaultScope?: SessionScope;
374
420
  }
375
421
  /**
376
- * Tier preset table. The defaults follow ADR-038 §4 `'free'`
422
+ * Tier preset table. The defaults follow ADR-038 §4 - `'free'`
377
423
  * disables every LLM phase and pins zero ceilings, the upper tiers
378
424
  * widen the budget envelope progressively.
379
425
  *
@@ -391,6 +437,8 @@ declare const CONSOLIDATOR_TIER_DEFAULTS: Readonly<Record<ConsolidatorTier, {
391
437
  readonly importanceThreshold: number;
392
438
  readonly reflectionMaxQuestions: number;
393
439
  readonly contextualRetrieval: ContextualRetrievalMode;
440
+ readonly learnedContext: boolean;
441
+ readonly learnedContextMaxChars: number;
394
442
  }>>;
395
443
  //#endregion
396
444
  export { CONSOLIDATOR_TIER_DEFAULTS, ConsolidatorBudgetSnapshot, ConsolidatorCeilings, ConsolidatorConfig, ConsolidatorLastRuns, ConsolidatorPhase, ConsolidatorStatus, ConsolidatorTier, ConsolidatorTriggerReason, ConsolidatorTriggerSpec, CreateConsolidatorOptions, OnBudgetExceed, PhaseListener, PhaseOutcome };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/consolidator/types.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;AA8MuD,KAnL3C,uBAAA,GAmL2C,QAAA,MAAA,EAAA,GAAA,QAAA,MAAA,EAAA,GAAA,QAAA,MAAA,EAAA,GAAA,SAAA,MAAA,EAAA,GAAA,UAAA,MAAA,EAAA;AAWvD;AAcA;AAsBA;;;;;AAGmB,KAvNP,gBAAA,GAuNO,MAAA,GAAA,OAAA,GAAA,UAAA,GAAA,MAAA,GAAA,QAAA;;;;;AA6BnB;AAuBY,UApQK,yBAAA,CAoQQ;EACd,SAAA,IAAA,EAAA,MAAA,GAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,QAAA,GAAA,QAAA;EACS,SAAA,KAAA,CAAA,EAAA,MAAA,GAAA,MAAA;;;AAUpB;;;;;;AAgCoC,UApSnB,oBAAA,CAoSmB;EAAd,SAAA,eAAA,EAAA,MAAA;EACJ,SAAA,aAAA,EAAA,MAAA;EACgB;;;;;;EAaR,SAAA,iBAAA,EAAA,MAAA;EAIA,SAAA,gBAAA,EAAA,MAAA;EAOG;;;;AAkC7B;;;EAKqC,SAAA,UAAA,EAAA,MAAA;;;;;;;;;;;KAvUzB,cAAA;;;;;;KAOA,iBAAA;;;;;;UAOK,kBAAA;qBACI,cAAc;iBAClB;mBACE,cAAc;qBACZ;qBACA;;;;;;;;;;;;;;;yBAeI;;;;;;;;;;;;;;;;;;;4BAmBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA+DI;;;;;;;;;;UAWf,oBAAA;;;;;;;;;;;;;UAcA,0BAAA;;;;;;;;;;;;;;;;;;;;;UAsBA,kBAAA;iBACA;qBACI,cAAc;mBAChB,cAAc;;;;;;uBAMV;;qBAEF;;;;;;;mBAOF;;;;;;;;;;;;;UAcF,YAAA;kBACC;;;;;;;;;;;;;;;;;;;;;KAsBN,aAAA,aACD;kBACS;oBACE;;;;;;;UASL,yBAAA;;;;;;kBAMC;;;;;;;qBAOG;;;;;;;sBAOC;;;;;;sBAMA;oBACF;;;;;sBAKE,cAAc;kBAClB;oBACE,cAAc;sBACZ,QAAQ;sBACR;;;;;;2BAMK;;;;;0BAKD;;;;0BAIA;;;;;;;6BAOG;;;;;;;;;;;;;;;;;;;;;;iCAsBI;;0BAEP;;;;;;;;;cAUb,4BAA4B,SACvC,OACE;qBAEqB;mBACF,cAAc;;;qBAGZ;;;;;;gCAMW"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/consolidator/types.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;AAoNuD,KAxL3C,uBAAA,GAwL2C,QAAA,MAAA,EAAA,GAAA,QAAA,MAAA,EAAA,GAAA,QAAA,MAAA,EAAA,GAAA,SAAA,MAAA,EAAA,GAAA,UAAA,MAAA,EAAA;AAsBvD;AAcA;AAsBA;;;;;AAGmB,KAvOP,gBAAA,GAuOO,MAAA,GAAA,OAAA,GAAA,UAAA,GAAA,MAAA,GAAA,QAAA;;;;;AA6BnB;AAyBY,UAtRK,yBAAA,CAsRQ;EACd,SAAA,IAAA,EAAA,MAAA,GAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,QAAA,GAAA,QAAA;EACS,SAAA,KAAA,CAAA,EAAA,MAAA,GAAA,MAAA;;;AAUpB;;;;;;;;;;;AAyCoB,UA1TH,oBAAA,CA0TG;EACU,SAAA,eAAA,EAAA,MAAA;EAAR,SAAA,aAAA,EAAA,MAAA;EACA;;;;;;EA+DI,SAAA,iBAAA,EAAA,MAAA;EAAY,SAAA,gBAAA,EAAA,MAAA;EAUzB;;;;;;;EACX,SAAA,UAAA,EAAA,MAAA;;;;;;;;;;;KAxWU,cAAA;;;;;;KAOA,iBAAA;;;;;;UAOK,kBAAA;qBACI,cAAc;iBAClB;mBACE,cAAc;qBACZ;qBACA;;;;;;;;;;;;;;;yBAeI;;;;;;;;;;;;;;;;;;;4BAmBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA+DI;;;;;;;;;;;;;;;;;;;;;UAsBf,oBAAA;;;;;;;;;;;;;UAcA,0BAAA;;;;;;;;;;;;;;;;;;;;;UAsBA,kBAAA;iBACA;qBACI,cAAc;mBAChB,cAAc;;;;;;uBAMV;;qBAEF;;;;;;;mBAOF;;;;;;;;;;;;;UAcF,YAAA;kBACC;;;;;;;;;;;;;;;;;;;;;;;KAwBN,aAAA,aACD;kBACS;oBACE;;;;;;;UASL,yBAAA;;;;;;kBAMC;;;;;;;qBAOG;;;;;;;sBAOC;;;;;;;qBAOD;;;;;;sBAMC;oBACF;;;;;sBAKE,cAAc;kBAClB;oBACE,cAAc;sBACZ,QAAQ;sBACR;;;;;;;;;;;;;;;;;;;;;;2BAmBK;;;;;0BAKD;;;;0BAIA;;;;;;;6BAOG;;;;;;;;;;;;;;;;;;;;;;iCAsBI;;;;;;0BAMP;;;;;;;;;cAUb,4BAA4B,SACvC,OACE;qBAEqB;mBACF,cAAc;;;qBAGZ;;;;;;gCAMW"}
@@ -1,6 +1,6 @@
1
1
  //#region src/consolidator/types.ts
2
2
  /**
3
- * Tier preset table. The defaults follow ADR-038 §4 `'free'`
3
+ * Tier preset table. The defaults follow ADR-038 §4 - `'free'`
4
4
  * disables every LLM phase and pins zero ceilings, the upper tiers
5
5
  * widen the budget envelope progressively.
6
6
  *
@@ -24,7 +24,9 @@ const CONSOLIDATOR_TIER_DEFAULTS = Object.freeze({
24
24
  reflection: false,
25
25
  importanceThreshold: 3,
26
26
  reflectionMaxQuestions: 3,
27
- contextualRetrieval: "late-chunk"
27
+ contextualRetrieval: "late-chunk",
28
+ learnedContext: false,
29
+ learnedContextMaxChars: 1200
28
30
  },
29
31
  cheap: {
30
32
  ceilings: {
@@ -43,7 +45,9 @@ const CONSOLIDATOR_TIER_DEFAULTS = Object.freeze({
43
45
  reflection: false,
44
46
  importanceThreshold: 3,
45
47
  reflectionMaxQuestions: 3,
46
- contextualRetrieval: "late-chunk"
48
+ contextualRetrieval: "late-chunk",
49
+ learnedContext: false,
50
+ learnedContextMaxChars: 1200
47
51
  },
48
52
  standard: {
49
53
  ceilings: {
@@ -66,7 +70,9 @@ const CONSOLIDATOR_TIER_DEFAULTS = Object.freeze({
66
70
  reflection: false,
67
71
  importanceThreshold: 3,
68
72
  reflectionMaxQuestions: 3,
69
- contextualRetrieval: "late-chunk"
73
+ contextualRetrieval: "late-chunk",
74
+ learnedContext: false,
75
+ learnedContextMaxChars: 1200
70
76
  },
71
77
  full: {
72
78
  ceilings: {
@@ -89,7 +95,9 @@ const CONSOLIDATOR_TIER_DEFAULTS = Object.freeze({
89
95
  reflection: true,
90
96
  importanceThreshold: 3,
91
97
  reflectionMaxQuestions: 3,
92
- contextualRetrieval: "late-chunk"
98
+ contextualRetrieval: "late-chunk",
99
+ learnedContext: false,
100
+ learnedContextMaxChars: 1200
93
101
  },
94
102
  custom: {
95
103
  ceilings: {
@@ -108,7 +116,9 @@ const CONSOLIDATOR_TIER_DEFAULTS = Object.freeze({
108
116
  reflection: false,
109
117
  importanceThreshold: 3,
110
118
  reflectionMaxQuestions: 3,
111
- contextualRetrieval: "late-chunk"
119
+ contextualRetrieval: "late-chunk",
120
+ learnedContext: false,
121
+ learnedContextMaxChars: 1200
112
122
  }
113
123
  });
114
124
 
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":["CONSOLIDATOR_TIER_DEFAULTS: Readonly<\n Record<\n ConsolidatorTier,\n {\n readonly ceilings: ConsolidatorCeilings;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly cheapModel: string | null;\n readonly deepModel: string | null;\n readonly onExceed: OnBudgetExceed;\n readonly formEpisodes: boolean;\n readonly importanceScoring: boolean;\n readonly reflection: boolean;\n readonly importanceThreshold: number;\n readonly reflectionMaxQuestions: number;\n readonly contextualRetrieval: ContextualRetrievalMode;\n }\n >\n>"],"sources":["../../src/consolidator/types.ts"],"sourcesContent":["/**\n * Public types for the Phase 10c consolidator runtime.\n *\n * The consolidator is the background pipeline that turns raw\n * conversation turns into long-lived facts and episodes. The runtime\n * has three phases (`light` / `standard` / `deep`), an explicit cost\n * envelope, an idempotent cursor, a wait-then-defer lock, and a\n * dead-letter queue for retry-able failures. The binding architecture\n * references are DEC-133 / DEC-134 / ADR-038.\n *\n * @packageDocumentation\n */\n\nimport type { Provider, SessionScope, Tracer } from '@graphorin/core';\nimport type { ContextualRetrievalMode } from '../internal/contextualize.js';\nimport type { MemoryStoreAdapter } from '../internal/storage-adapter.js';\nimport type { EpisodicMemory } from '../tiers/episodic-memory.js';\nimport type { SemanticMemory } from '../tiers/semantic-memory.js';\nimport type { SalienceWeights } from './decay.js';\n\n/**\n * Trigger discriminator. The `'turn:N'` and `'idle:Xm'` variants are\n * the production defaults per DEC-133. `'cron:EXPR'`, `'event:NAME'`\n * and `'budget:N'` are opt-in.\n *\n * @stable\n */\nexport type ConsolidatorTriggerSpec =\n | `turn:${number}`\n | `idle:${string}`\n | `cron:${string}`\n | `event:${string}`\n | `budget:${number}`;\n\n/**\n * Tier preset that selects a consolidator behaviour bundle. The\n * `'free'` preset is the default per DEC-144 / ADR-038 — no LLM call\n * fires until the operator opts in.\n *\n * @stable\n */\nexport type ConsolidatorTier = 'free' | 'cheap' | 'standard' | 'full' | 'custom';\n\n/**\n * Triggering reason surfaced through `Consolidator.trigger(...)`.\n *\n * @stable\n */\nexport interface ConsolidatorTriggerReason {\n readonly kind: 'turn' | 'idle' | 'cron' | 'event' | 'budget' | 'manual';\n readonly value?: string | number;\n}\n\n/**\n * Hard cost ceilings enforced atomically per UTC day. The default\n * ceiling shape per tier is captured in\n * {@link CONSOLIDATOR_TIER_DEFAULTS}.\n *\n * @stable\n */\nexport interface ConsolidatorCeilings {\n readonly maxTokensPerDay: number;\n readonly maxCostPerDay: number;\n /**\n * ADVISORY (MCON-8): the per-scope lock serializes runs, so effective\n * concurrency is always 1 per scope regardless of this value. The\n * field is retained for forward compatibility; it enforces nothing\n * today.\n */\n readonly maxConcurrentRuns: number;\n readonly maxRunDurationMs: number;\n /**\n * Minimum quiet period between non-manual runs per scope (MCON-8).\n * After each run the runtime persists `nextEligibleAt = now +\n * cooldownMs`; trigger-driven runs (`turn` / `idle` / `cron` /\n * `event` / `budget`) inside that window defer with reason\n * `'cooldown'`. Manual `fireNow(...)` and DLQ replays bypass it.\n */\n readonly cooldownMs: number;\n}\n\n/**\n * Behaviour applied by the budget enforcer when a ceiling is hit\n * mid-run. `'pause'` is the conservative default — the consolidator\n * skips subsequent runs until the next budget reset; `'log'` keeps\n * running with a WARN; `'throw'` raises a typed\n * {@link BudgetExceededError}.\n *\n * @stable\n */\nexport type OnBudgetExceed = 'pause' | 'log' | 'throw';\n\n/**\n * Phase identifier used by the runtime + audit rows.\n *\n * @stable\n */\nexport type ConsolidatorPhase = 'light' | 'standard' | 'deep';\n\n/**\n * Locked-down configuration accepted by `createConsolidator(...)`.\n *\n * @stable\n */\nexport interface ConsolidatorConfig {\n readonly triggers: ReadonlyArray<ConsolidatorTriggerSpec>;\n readonly tier: ConsolidatorTier;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly ceilings: ConsolidatorCeilings;\n readonly onExceed: OnBudgetExceed;\n /**\n * Advisory label for the standard phase's model — recorded on spans /\n * run telemetry only (MCON-7). Routing happens via\n * `CreateConsolidatorOptions.cheapProvider`; this string disables\n * nothing.\n */\n readonly cheapModel: string | null;\n /**\n * Advisory label for the deep phase's model — telemetry only\n * (MCON-7). Routing happens via\n * `CreateConsolidatorOptions.deepProvider`.\n */\n readonly deepModel: string | null;\n readonly budgetResetSemantics: 'utc' | 'local' | 'sliding-24h';\n readonly noiseFilters: ReadonlyArray<'default' | 'minimal' | 'none'>;\n readonly lockWaitMs: number;\n readonly decayTauDays: number;\n readonly decayArchiveThreshold: number;\n /**\n * Capacity-bounded eviction target for the light phase (X-1). When set,\n * each light pass archives the lowest-salience live facts in the LRU\n * decay window down to this many — **cost / staleness control, not an\n * accuracy lever**. `null` (the default at every tier) leaves storage\n * unbounded, so behaviour is identical to pre-X-1. Archiving is a soft,\n * recoverable move; nothing is hard-deleted.\n */\n readonly decayCapacity: number | null;\n /**\n * Weights for the multi-signal salience score (X-1) that orders both\n * threshold archiving and capacity eviction. Defaults to\n * {@link DEFAULT_SALIENCE_WEIGHTS}; with neutral importance, active\n * status, and first-party provenance salience equals plain retention.\n */\n readonly salienceWeights: SalienceWeights;\n readonly maxStandardBatchSize: number;\n readonly maxDeepConflictsPerRun: number;\n readonly dlqMaxRetries: number;\n readonly dlqBaseBackoffMs: number;\n readonly dlqMaxBackoffMs: number;\n /**\n * Auto-form a quarantined episode from each processed standard-phase\n * slice (P1-2). Defaults on at the `standard`+ tiers, off at `free` /\n * `cheap` / `custom`. The episode summary is one budgeted LLM call;\n * when the budget is exhausted (or no episodic tier is wired) the\n * phase degrades to fact-only behaviour.\n */\n readonly formEpisodes: boolean;\n /**\n * Ask the episode-summarization call for an LLM importance score\n * (1–10, normalized to `[0, 1]`) so episodic triple-signal retrieval\n * (recency × relevance × importance) runs on all three signals\n * (P1-2). Importance is always a *soft* signal — it never gates\n * retention. Defaults track {@link formEpisodes}.\n */\n readonly importanceScoring: boolean;\n /**\n * Auto-promotion policy (MCON-2). When `true`, the standard phase admits an\n * injection-clean **extraction** fact as `active` instead of quarantined, so\n * routine distillation surfaces in default recall without a manual\n * `memory review --promote`. Injection-flagged facts always stay quarantined\n * — the security gate is preserved — and episodes / insights / induced\n * procedures are unaffected (they remain quarantined-until-validated).\n * Defaults **off** at every tier: it trades the fail-safe default for\n * convenience and is an explicit operator opt-in.\n */\n readonly autoPromoteExtraction: boolean;\n /**\n * Run the deep-phase reflection pass (P1-1): when accumulated episode\n * importance crosses {@link importanceThreshold}, synthesize\n * higher-order, cited insights over recent memories (Generative\n * Agents). Insights land quarantined + `provenance: 'reflection'` and\n * are ranked below the facts they cite. Defaults **on at the `full`\n * tier only** (off at `free` / `cheap` / `standard` / `custom`) — it\n * is the most LLM-intensive phase. A no-op without an episodic tier\n * or an insight-capable storage adapter.\n */\n readonly reflection: boolean;\n /**\n * Sum of recent episode importance (each in `[0, 1]`) at or above\n * which {@link reflection} fires. Below it the pass makes no LLM\n * call. Defaults to `3`.\n */\n readonly importanceThreshold: number;\n /** Upper bound on salient questions reflection asks per pass. Defaults to `3`. */\n readonly reflectionMaxQuestions: number;\n /**\n * Contextual retrieval for facts written by the standard phase (P1-3).\n * `'late-chunk'` (default at every tier) relies on the offline\n * situating-context prefix the shared {@link SemanticMemory} computes\n * for every write — no extra LLM call. `'llm'` is the opt-in\n * enrichment: the standard phase spends one budgeted cheap-model call\n * per additive write to author a 1–2 sentence situating prefix, then\n * passes it as the write's index text. `'off'` indexes the bare text.\n * The `'llm'` mode is **consolidator-only** by construction — the hot\n * write path never has a provider for contextualization.\n */\n readonly contextualRetrieval: ContextualRetrievalMode;\n}\n\n/**\n * Per-phase last-run snapshot surfaced inside\n * {@link ConsolidatorStatus.lastRuns}. Each entry carries the\n * timestamp of the most recent **completed** invocation for that\n * phase (`undefined` when the phase has never run).\n *\n * @stable\n */\nexport interface ConsolidatorLastRuns {\n readonly light?: string;\n readonly standard?: string;\n readonly deep?: string;\n}\n\n/**\n * Budget snapshot block of {@link ConsolidatorStatus}. Surfaces\n * both the absolute usage and the remaining envelope so consumers\n * (CLI, server health endpoint) can render the operator dashboard\n * without doing the math themselves.\n *\n * @stable\n */\nexport interface ConsolidatorBudgetSnapshot {\n readonly tokensUsedToday: number;\n readonly costUsedToday: number;\n readonly tokensRemaining: number;\n readonly costRemaining: number;\n readonly resetAt: string;\n}\n\n/**\n * Status snapshot returned by {@link Consolidator.status}.\n *\n * Public shape: `{ tier, queueDepth, dlqSize, lastRuns,\n * budgetRemaining, deferredRuns }` — extended with a few additional\n * fields the server health endpoint and the\n * `graphorin consolidator status` CLI consume.\n *\n * `queueDepth` is an alias for {@link pendingConflicts} (the size\n * of the deep-phase queue); both fields are populated for backwards\n * compatibility.\n *\n * @stable\n */\nexport interface ConsolidatorStatus {\n readonly tier: ConsolidatorTier;\n readonly triggers: ReadonlyArray<ConsolidatorTriggerSpec>;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly running: boolean;\n readonly paused: boolean;\n /** Most recent completed run timestamp (any phase). */\n readonly lastRunAt?: string;\n /** Phase of the most recent completed run. */\n readonly lastPhase?: ConsolidatorPhase;\n /** Per-phase last-completed timestamps surfaced for CLI / dashboard. */\n readonly lastRuns: ConsolidatorLastRuns;\n /** Spec alias for {@link pendingConflicts}. */\n readonly queueDepth: number;\n readonly pendingConflicts: number;\n readonly dlqSize: number;\n readonly deferredRuns: number;\n readonly emptyExtractions: number;\n readonly budget: ConsolidatorBudgetSnapshot;\n /** Spec alias — surfaces remaining-budget figures at the top level. */\n readonly budgetRemaining: {\n readonly tokens: number;\n readonly costUsd: number;\n };\n}\n\n/**\n * Outcome surfaced by every phase invocation. Recorded into\n * `consolidator_runs` and emitted on the AISpan.\n *\n * @stable\n */\nexport interface PhaseOutcome {\n readonly phase: ConsolidatorPhase;\n readonly status: 'completed' | 'failed' | 'deferred' | 'partial';\n readonly factsCreated: number;\n readonly factsUpdated: number;\n readonly conflictsResolved: number;\n /** Episodes auto-formed from the processed slice (P1-2). */\n readonly episodesFormed: number;\n /** Insights synthesized by the deep-phase reflection pass (P1-1). */\n readonly insightsCreated: number;\n readonly noiseFilteredCount: number;\n readonly emptyExtractions: number;\n readonly llmTokensUsed: number;\n readonly llmCostUsd: number | null;\n readonly errorMessage: string | null;\n}\n\n/**\n * Listener callback subscribed via\n * {@link Consolidator.onPhaseFinished}. Useful for tests + observers.\n *\n * @stable\n */\nexport type PhaseListener = (\n outcome: PhaseOutcome & {\n readonly scope: SessionScope;\n readonly trigger: ConsolidatorTriggerReason;\n },\n) => void;\n\n/**\n * Options accepted by {@link createConsolidator}.\n *\n * @stable\n */\nexport interface CreateConsolidatorOptions {\n /**\n * Storage adapter — supplies the consolidator state, runs, DLQ,\n * and per-tier helpers. The default `@graphorin/store-sqlite`\n * adapter exposes everything by construction.\n */\n readonly store: MemoryStoreAdapter;\n /**\n * The {@link SemanticMemory} tier instance from the parent\n * `createMemory(...)` facade. The standard phase routes every\n * extracted fact through `semantic.remember(...)` so the conflict\n * pipeline (Phase 10b) handles dedup / supersede.\n */\n readonly semantic: SemanticMemory;\n /**\n * The {@link EpisodicMemory} tier instance from the parent\n * `createMemory(...)` facade. When supplied (and `formEpisodes` is\n * on) the standard phase auto-forms a quarantined episode per\n * processed slice (P1-2). Omitted ⇒ episode formation is skipped.\n */\n readonly episodic?: EpisodicMemory;\n /**\n * Provider used by the standard + deep phases. Required when the\n * tier enables either phase; ignored when the active phases\n * collapse to `['light']`.\n */\n readonly provider?: Provider | null;\n readonly tracer?: Tracer;\n /** Override the wall clock — used by tests. */\n readonly now?: () => number;\n /** Random source for stable run ids — used by tests. */\n readonly randomId?: () => string;\n readonly triggers?: ReadonlyArray<ConsolidatorTriggerSpec>;\n readonly tier?: ConsolidatorTier;\n readonly phases?: ReadonlyArray<ConsolidatorPhase>;\n readonly ceilings?: Partial<ConsolidatorCeilings>;\n readonly onExceed?: OnBudgetExceed;\n /**\n * Provider routed to the standard phase (extraction / episode /\n * reconcile / situating-context calls) when set (MCON-7). Falls back\n * to `provider`. Pair with `cheapModel` for the telemetry label.\n */\n readonly cheapProvider?: Provider | null;\n /**\n * Provider routed to the deep phase (conflict judge) and the\n * reflection pass when set (MCON-7). Falls back to `provider`.\n */\n readonly deepProvider?: Provider | null;\n readonly cheapModel?: string | null;\n readonly deepModel?: string | null;\n readonly budgetResetSemantics?: 'utc' | 'local' | 'sliding-24h';\n readonly noiseFilters?: ReadonlyArray<'default' | 'minimal' | 'none'>;\n readonly lockWaitMs?: number;\n readonly decayTauDays?: number;\n readonly decayArchiveThreshold?: number;\n /** Override the {@link ConsolidatorConfig.decayCapacity} default (X-1). */\n readonly decayCapacity?: number | null;\n /** Override the {@link ConsolidatorConfig.salienceWeights} default (X-1). */\n readonly salienceWeights?: SalienceWeights;\n readonly maxStandardBatchSize?: number;\n readonly maxDeepConflictsPerRun?: number;\n readonly dlqMaxRetries?: number;\n readonly dlqBaseBackoffMs?: number;\n readonly dlqMaxBackoffMs?: number;\n /** Override the per-tier {@link ConsolidatorConfig.formEpisodes} default (P1-2). */\n readonly formEpisodes?: boolean;\n /** Override the per-tier {@link ConsolidatorConfig.importanceScoring} default (P1-2). */\n readonly importanceScoring?: boolean;\n /**\n * Opt in to auto-promotion of injection-clean extraction facts (MCON-2).\n * Defaults `false`. See {@link ConsolidatorConfig.autoPromoteExtraction}.\n */\n readonly autoPromoteExtraction?: boolean;\n /** Override the per-tier {@link ConsolidatorConfig.reflection} default (P1-1). */\n readonly reflection?: boolean;\n /** Override the {@link ConsolidatorConfig.importanceThreshold} default (P1-1). */\n readonly importanceThreshold?: number;\n /** Override the {@link ConsolidatorConfig.reflectionMaxQuestions} default (P1-1). */\n readonly reflectionMaxQuestions?: number;\n /** Override the per-tier {@link ConsolidatorConfig.contextualRetrieval} default (P1-3). */\n readonly contextualRetrieval?: ContextualRetrievalMode;\n /** Default scope used by event triggers + the manual `fireNow` path. */\n readonly defaultScope?: SessionScope;\n}\n\n/**\n * Tier preset table. The defaults follow ADR-038 §4 — `'free'`\n * disables every LLM phase and pins zero ceilings, the upper tiers\n * widen the budget envelope progressively.\n *\n * @stable\n */\nexport const CONSOLIDATOR_TIER_DEFAULTS: Readonly<\n Record<\n ConsolidatorTier,\n {\n readonly ceilings: ConsolidatorCeilings;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly cheapModel: string | null;\n readonly deepModel: string | null;\n readonly onExceed: OnBudgetExceed;\n readonly formEpisodes: boolean;\n readonly importanceScoring: boolean;\n readonly reflection: boolean;\n readonly importanceThreshold: number;\n readonly reflectionMaxQuestions: number;\n readonly contextualRetrieval: ContextualRetrievalMode;\n }\n >\n> = Object.freeze({\n free: {\n ceilings: {\n maxTokensPerDay: 0,\n maxCostPerDay: 0,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 5 * 60 * 1000,\n cooldownMs: 60_000,\n },\n phases: ['light'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'pause',\n formEpisodes: false,\n importanceScoring: false,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n cheap: {\n ceilings: {\n maxTokensPerDay: 50_000,\n maxCostPerDay: 0.2,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 5 * 60 * 1000,\n cooldownMs: 60_000,\n },\n phases: ['light', 'standard'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'pause',\n formEpisodes: false,\n importanceScoring: false,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n standard: {\n ceilings: {\n maxTokensPerDay: 200_000,\n maxCostPerDay: 1.0,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 10 * 60 * 1000,\n cooldownMs: 30_000,\n },\n phases: ['light', 'standard', 'deep'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'log',\n formEpisodes: true,\n importanceScoring: true,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n full: {\n ceilings: {\n maxTokensPerDay: 1_000_000,\n maxCostPerDay: 5.0,\n maxConcurrentRuns: 2,\n maxRunDurationMs: 15 * 60 * 1000,\n cooldownMs: 10_000,\n },\n phases: ['light', 'standard', 'deep'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'log',\n formEpisodes: true,\n importanceScoring: true,\n reflection: true,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n custom: {\n ceilings: {\n maxTokensPerDay: 0,\n maxCostPerDay: 0,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 5 * 60 * 1000,\n cooldownMs: 60_000,\n },\n phases: ['light'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'pause',\n formEpisodes: false,\n importanceScoring: false,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n});\n"],"mappings":";;;;;;;;AA4ZA,MAAaA,6BAiBT,OAAO,OAAO;CAChB,MAAM;EACJ,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAS;GAC3B,YAAY;GACb;EACD,QAAQ,CAAC,QAAQ;EACjB,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACD,OAAO;EACL,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAS;GAC3B,YAAY;GACb;EACD,QAAQ,CAAC,SAAS,WAAW;EAC7B,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACD,UAAU;EACR,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAU;GAC5B,YAAY;GACb;EACD,QAAQ;GAAC;GAAS;GAAY;GAAO;EACrC,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACD,MAAM;EACJ,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAU;GAC5B,YAAY;GACb;EACD,QAAQ;GAAC;GAAS;GAAY;GAAO;EACrC,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACD,QAAQ;EACN,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAS;GAC3B,YAAY;GACb;EACD,QAAQ,CAAC,QAAQ;EACjB,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACF,CAAC"}
1
+ {"version":3,"file":"types.js","names":["CONSOLIDATOR_TIER_DEFAULTS: Readonly<\n Record<\n ConsolidatorTier,\n {\n readonly ceilings: ConsolidatorCeilings;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly cheapModel: string | null;\n readonly deepModel: string | null;\n readonly onExceed: OnBudgetExceed;\n readonly formEpisodes: boolean;\n readonly importanceScoring: boolean;\n readonly reflection: boolean;\n readonly importanceThreshold: number;\n readonly reflectionMaxQuestions: number;\n readonly contextualRetrieval: ContextualRetrievalMode;\n readonly learnedContext: boolean;\n readonly learnedContextMaxChars: number;\n }\n >\n>"],"sources":["../../src/consolidator/types.ts"],"sourcesContent":["/**\n * Public types for the Phase 10c consolidator runtime.\n *\n * The consolidator is the background pipeline that turns raw\n * conversation turns into long-lived facts and episodes. The runtime\n * has three phases (`light` / `standard` / `deep`), an explicit cost\n * envelope, an idempotent cursor, a wait-then-defer lock, and a\n * dead-letter queue for retry-able failures. The binding architecture\n * references are DEC-133 / DEC-134 / ADR-038.\n *\n * @packageDocumentation\n */\n\nimport type { Provider, SessionScope, Tracer } from '@graphorin/core';\nimport type { ContextualRetrievalMode } from '../internal/contextualize.js';\nimport type { MemoryStoreAdapter } from '../internal/storage-adapter.js';\nimport type { EpisodicMemory } from '../tiers/episodic-memory.js';\nimport type { SemanticMemory } from '../tiers/semantic-memory.js';\nimport type { WorkingMemory } from '../tiers/working-memory.js';\nimport type { SalienceWeights } from './decay.js';\n\n/**\n * Trigger discriminator. The `'turn:N'` and `'idle:Xm'` variants are\n * the production defaults per DEC-133. `'cron:EXPR'`, `'event:NAME'`\n * and `'budget:N'` are opt-in.\n *\n * @stable\n */\nexport type ConsolidatorTriggerSpec =\n | `turn:${number}`\n | `idle:${string}`\n | `cron:${string}`\n | `event:${string}`\n | `budget:${number}`;\n\n/**\n * Tier preset that selects a consolidator behaviour bundle. The\n * `'free'` preset is the default per DEC-144 / ADR-038 - no LLM call\n * fires until the operator opts in.\n *\n * @stable\n */\nexport type ConsolidatorTier = 'free' | 'cheap' | 'standard' | 'full' | 'custom';\n\n/**\n * Triggering reason surfaced through `Consolidator.trigger(...)`.\n *\n * @stable\n */\nexport interface ConsolidatorTriggerReason {\n readonly kind: 'turn' | 'idle' | 'cron' | 'event' | 'budget' | 'manual';\n readonly value?: string | number;\n}\n\n/**\n * Daily cost ceilings, tracked per budget window. How a breach is\n * handled depends on {@link OnBudgetExceed}: `'pause'` / `'throw'`\n * enforce, `'log'` (the shipped standard/full presets) only WARNs and\n * keeps running. The USD leg accumulates only when a `priceUsage`\n * pricer is configured (memory-consolidation-02) - without one every\n * call prices at $0 and `maxCostPerDay` can never trip. The default\n * ceiling shape per tier is captured in\n * {@link CONSOLIDATOR_TIER_DEFAULTS}.\n *\n * @stable\n */\nexport interface ConsolidatorCeilings {\n readonly maxTokensPerDay: number;\n readonly maxCostPerDay: number;\n /**\n * ADVISORY (MCON-8): the per-scope lock serializes runs, so effective\n * concurrency is always 1 per scope regardless of this value. The\n * field is retained for forward compatibility; it enforces nothing\n * today.\n */\n readonly maxConcurrentRuns: number;\n readonly maxRunDurationMs: number;\n /**\n * Minimum quiet period between non-manual runs per scope (MCON-8).\n * After each run the runtime persists `nextEligibleAt = now +\n * cooldownMs`; trigger-driven runs (`turn` / `idle` / `cron` /\n * `event` / `budget`) inside that window defer with reason\n * `'cooldown'`. Manual `fireNow(...)` and DLQ replays bypass it.\n */\n readonly cooldownMs: number;\n}\n\n/**\n * Behaviour applied by the budget enforcer when a ceiling is hit\n * mid-run. `'pause'` is the conservative default - the consolidator\n * skips subsequent runs until the next budget reset; `'log'` keeps\n * running with a WARN; `'throw'` raises a typed\n * {@link BudgetExceededError}.\n *\n * @stable\n */\nexport type OnBudgetExceed = 'pause' | 'log' | 'throw';\n\n/**\n * Phase identifier used by the runtime + audit rows.\n *\n * @stable\n */\nexport type ConsolidatorPhase = 'light' | 'standard' | 'deep';\n\n/**\n * Locked-down configuration accepted by `createConsolidator(...)`.\n *\n * @stable\n */\nexport interface ConsolidatorConfig {\n readonly triggers: ReadonlyArray<ConsolidatorTriggerSpec>;\n readonly tier: ConsolidatorTier;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly ceilings: ConsolidatorCeilings;\n readonly onExceed: OnBudgetExceed;\n /**\n * Advisory label for the standard phase's model - recorded on spans /\n * run telemetry only (MCON-7). Routing happens via\n * `CreateConsolidatorOptions.cheapProvider`; this string disables\n * nothing.\n */\n readonly cheapModel: string | null;\n /**\n * Advisory label for the deep phase's model - telemetry only\n * (MCON-7). Routing happens via\n * `CreateConsolidatorOptions.deepProvider`.\n */\n readonly deepModel: string | null;\n readonly budgetResetSemantics: 'utc' | 'local' | 'sliding-24h';\n readonly noiseFilters: ReadonlyArray<'default' | 'minimal' | 'none'>;\n readonly lockWaitMs: number;\n readonly decayTauDays: number;\n readonly decayArchiveThreshold: number;\n /**\n * Capacity-bounded eviction target for the light phase (X-1). When set,\n * each light pass archives the lowest-salience live facts in the LRU\n * decay window down to this many - **cost / staleness control, not an\n * accuracy lever**. `null` (the default at every tier) leaves storage\n * unbounded, so behaviour is identical to pre-X-1. Archiving is a soft,\n * recoverable move; nothing is hard-deleted.\n */\n readonly decayCapacity: number | null;\n /**\n * Weights for the multi-signal salience score (X-1) that orders both\n * threshold archiving and capacity eviction. Defaults to\n * {@link DEFAULT_SALIENCE_WEIGHTS}; with neutral importance, active\n * status, and first-party provenance salience equals plain retention.\n */\n readonly salienceWeights: SalienceWeights;\n readonly maxStandardBatchSize: number;\n readonly maxDeepConflictsPerRun: number;\n readonly dlqMaxRetries: number;\n readonly dlqBaseBackoffMs: number;\n readonly dlqMaxBackoffMs: number;\n /**\n * Auto-form a quarantined episode from each processed standard-phase\n * slice (P1-2). Defaults on at the `standard`+ tiers, off at `free` /\n * `cheap` / `custom`. The episode summary is one budgeted LLM call;\n * when the budget is exhausted (or no episodic tier is wired) the\n * phase degrades to fact-only behaviour.\n */\n readonly formEpisodes: boolean;\n /**\n * Ask the episode-summarization call for an LLM importance score\n * (1-10, normalized to `[0, 1]`) so episodic triple-signal retrieval\n * (recency × relevance × importance) runs on all three signals\n * (P1-2). Importance is always a *soft* signal - it never gates\n * retention. Defaults track {@link formEpisodes}.\n */\n readonly importanceScoring: boolean;\n /**\n * Auto-promotion policy (MCON-2). When `true`, the standard phase admits an\n * injection-clean **extraction** fact as `active` instead of quarantined, so\n * routine distillation surfaces in default recall without a manual\n * `memory review --promote`. Injection-flagged facts always stay quarantined\n * - the security gate is preserved - and episodes / insights / induced\n * procedures are unaffected (they remain quarantined-until-validated).\n * Defaults **off** at every tier: it trades the fail-safe default for\n * convenience and is an explicit operator opt-in.\n */\n readonly autoPromoteExtraction: boolean;\n /**\n * Run the deep-phase reflection pass (P1-1): when accumulated episode\n * importance crosses {@link importanceThreshold}, synthesize\n * higher-order, cited insights over recent memories (Generative\n * Agents). Insights land quarantined + `provenance: 'reflection'` and\n * are ranked below the facts they cite. Defaults **on at the `full`\n * tier only** (off at `free` / `cheap` / `standard` / `custom`) - it\n * is the most LLM-intensive phase. A no-op without an episodic tier\n * or an insight-capable storage adapter.\n */\n readonly reflection: boolean;\n /**\n * Sum of recent episode importance (each in `[0, 1]`) at or above\n * which {@link reflection} fires. Below it the pass makes no LLM\n * call. Defaults to `3`.\n */\n readonly importanceThreshold: number;\n /** Upper bound on salient questions reflection asks per pass. Defaults to `3`. */\n readonly reflectionMaxQuestions: number;\n /**\n * Contextual retrieval for facts written by the standard phase (P1-3).\n * `'late-chunk'` (default at every tier) relies on the offline\n * situating-context prefix the shared {@link SemanticMemory} computes\n * for every write - no extra LLM call. `'llm'` is the opt-in\n * enrichment: the standard phase spends one budgeted cheap-model call\n * per additive write to author a 1-2 sentence situating prefix, then\n * passes it as the write's index text. `'off'` indexes the bare text.\n * The `'llm'` mode is **consolidator-only** by construction - the hot\n * write path never has a provider for contextualization.\n */\n readonly contextualRetrieval: ContextualRetrievalMode;\n /**\n * Maintain the learned-context digest block (D3): after the deep\n * phase, one budgeted LLM call rewrites the reserved\n * `learned_context` working block from the previous digest + recent\n * episodes / active insights / active procedures, so the system\n * prompt carries a compact standing summary. Defaults **off at every\n * tier** (Wave-D trial) - a no-op without a working tier handle.\n */\n readonly learnedContext: boolean;\n /** Character bound enforced on the learned-context digest. Default `1200`. */\n readonly learnedContextMaxChars: number;\n}\n\n/**\n * Per-phase last-run snapshot surfaced inside\n * {@link ConsolidatorStatus.lastRuns}. Each entry carries the\n * timestamp of the most recent **completed** invocation for that\n * phase (`undefined` when the phase has never run).\n *\n * @stable\n */\nexport interface ConsolidatorLastRuns {\n readonly light?: string;\n readonly standard?: string;\n readonly deep?: string;\n}\n\n/**\n * Budget snapshot block of {@link ConsolidatorStatus}. Surfaces\n * both the absolute usage and the remaining envelope so consumers\n * (CLI, server health endpoint) can render the operator dashboard\n * without doing the math themselves.\n *\n * @stable\n */\nexport interface ConsolidatorBudgetSnapshot {\n readonly tokensUsedToday: number;\n readonly costUsedToday: number;\n readonly tokensRemaining: number;\n readonly costRemaining: number;\n readonly resetAt: string;\n}\n\n/**\n * Status snapshot returned by {@link Consolidator.status}.\n *\n * Public shape: `{ tier, queueDepth, dlqSize, lastRuns,\n * budgetRemaining, deferredRuns }` - extended with a few additional\n * fields the server health endpoint and the\n * `graphorin consolidator status` CLI consume.\n *\n * `queueDepth` is an alias for {@link pendingConflicts} (the size\n * of the deep-phase queue); both fields are populated for backwards\n * compatibility.\n *\n * @stable\n */\nexport interface ConsolidatorStatus {\n readonly tier: ConsolidatorTier;\n readonly triggers: ReadonlyArray<ConsolidatorTriggerSpec>;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly running: boolean;\n readonly paused: boolean;\n /** Most recent completed run timestamp (any phase). */\n readonly lastRunAt?: string;\n /** Phase of the most recent completed run. */\n readonly lastPhase?: ConsolidatorPhase;\n /** Per-phase last-completed timestamps surfaced for CLI / dashboard. */\n readonly lastRuns: ConsolidatorLastRuns;\n /** Spec alias for {@link pendingConflicts}. */\n readonly queueDepth: number;\n readonly pendingConflicts: number;\n readonly dlqSize: number;\n readonly deferredRuns: number;\n readonly emptyExtractions: number;\n readonly budget: ConsolidatorBudgetSnapshot;\n /** Spec alias - surfaces remaining-budget figures at the top level. */\n readonly budgetRemaining: {\n readonly tokens: number;\n readonly costUsd: number;\n };\n}\n\n/**\n * Outcome surfaced by every phase invocation. Recorded into\n * `consolidator_runs` and emitted on the AISpan.\n *\n * @stable\n */\nexport interface PhaseOutcome {\n readonly phase: ConsolidatorPhase;\n readonly status: 'completed' | 'failed' | 'deferred' | 'partial';\n readonly factsCreated: number;\n readonly factsUpdated: number;\n readonly conflictsResolved: number;\n /** Episodes auto-formed from the processed slice (P1-2). */\n readonly episodesFormed: number;\n /** Insights synthesized by the deep-phase reflection pass (P1-1). */\n readonly insightsCreated: number;\n /** True when the learned-context digest block was rewritten (D3). */\n readonly learnedContextUpdated?: boolean;\n readonly noiseFilteredCount: number;\n readonly emptyExtractions: number;\n readonly llmTokensUsed: number;\n readonly llmCostUsd: number | null;\n readonly errorMessage: string | null;\n}\n\n/**\n * Listener callback subscribed via\n * {@link Consolidator.onPhaseFinished}. Useful for tests + observers.\n *\n * @stable\n */\nexport type PhaseListener = (\n outcome: PhaseOutcome & {\n readonly scope: SessionScope;\n readonly trigger: ConsolidatorTriggerReason;\n },\n) => void;\n\n/**\n * Options accepted by {@link createConsolidator}.\n *\n * @stable\n */\nexport interface CreateConsolidatorOptions {\n /**\n * Storage adapter - supplies the consolidator state, runs, DLQ,\n * and per-tier helpers. The default `@graphorin/store-sqlite`\n * adapter exposes everything by construction.\n */\n readonly store: MemoryStoreAdapter;\n /**\n * The {@link SemanticMemory} tier instance from the parent\n * `createMemory(...)` facade. The standard phase routes every\n * extracted fact through `semantic.remember(...)` so the conflict\n * pipeline (Phase 10b) handles dedup / supersede.\n */\n readonly semantic: SemanticMemory;\n /**\n * The {@link EpisodicMemory} tier instance from the parent\n * `createMemory(...)` facade. When supplied (and `formEpisodes` is\n * on) the standard phase auto-forms a quarantined episode per\n * processed slice (P1-2). Omitted ⇒ episode formation is skipped.\n */\n readonly episodic?: EpisodicMemory;\n /**\n * The {@link WorkingMemory} tier instance from the parent\n * `createMemory(...)` facade (D3). Required for the learned-context\n * pass - without it the pass is a silent no-op even when\n * `learnedContext` is enabled.\n */\n readonly working?: WorkingMemory;\n /**\n * Provider used by the standard + deep phases. Required when the\n * tier enables either phase; ignored when the active phases\n * collapse to `['light']`.\n */\n readonly provider?: Provider | null;\n readonly tracer?: Tracer;\n /** Override the wall clock - used by tests. */\n readonly now?: () => number;\n /** Random source for stable run ids - used by tests. */\n readonly randomId?: () => string;\n readonly triggers?: ReadonlyArray<ConsolidatorTriggerSpec>;\n readonly tier?: ConsolidatorTier;\n readonly phases?: ReadonlyArray<ConsolidatorPhase>;\n readonly ceilings?: Partial<ConsolidatorCeilings>;\n readonly onExceed?: OnBudgetExceed;\n /**\n * USD pricer for phase LLM usage (memory-consolidation-02). Wire it\n * to `@graphorin/pricing`'s `calculateCost` (or any per-token rate)\n * so the `maxCostPerDay` ceiling can actually accumulate spend -\n * without it every phase prices its calls at $0 and the USD ceiling\n * never trips at any tier.\n *\n * ```ts\n * priceUsage: ({ promptTokens, completionTokens }) =>\n * (promptTokens * 3 + completionTokens * 15) / 1_000_000\n * ```\n */\n readonly priceUsage?: (usage: { promptTokens: number; completionTokens: number }) => number;\n /**\n * Provider routed to the standard phase (extraction / episode /\n * reconcile / situating-context calls) when set (MCON-7). Falls back\n * to `provider`. Pair with `cheapModel` for the telemetry label.\n */\n readonly cheapProvider?: Provider | null;\n /**\n * Provider routed to the deep phase (conflict judge) and the\n * reflection pass when set (MCON-7). Falls back to `provider`.\n */\n readonly deepProvider?: Provider | null;\n readonly cheapModel?: string | null;\n readonly deepModel?: string | null;\n readonly budgetResetSemantics?: 'utc' | 'local' | 'sliding-24h';\n readonly noiseFilters?: ReadonlyArray<'default' | 'minimal' | 'none'>;\n readonly lockWaitMs?: number;\n readonly decayTauDays?: number;\n readonly decayArchiveThreshold?: number;\n /** Override the {@link ConsolidatorConfig.decayCapacity} default (X-1). */\n readonly decayCapacity?: number | null;\n /** Override the {@link ConsolidatorConfig.salienceWeights} default (X-1). */\n readonly salienceWeights?: SalienceWeights;\n readonly maxStandardBatchSize?: number;\n readonly maxDeepConflictsPerRun?: number;\n readonly dlqMaxRetries?: number;\n readonly dlqBaseBackoffMs?: number;\n readonly dlqMaxBackoffMs?: number;\n /** Override the per-tier {@link ConsolidatorConfig.formEpisodes} default (P1-2). */\n readonly formEpisodes?: boolean;\n /** Override the per-tier {@link ConsolidatorConfig.importanceScoring} default (P1-2). */\n readonly importanceScoring?: boolean;\n /**\n * Opt in to auto-promotion of injection-clean extraction facts (MCON-2).\n * Defaults `false`. See {@link ConsolidatorConfig.autoPromoteExtraction}.\n */\n readonly autoPromoteExtraction?: boolean;\n /** Override the per-tier {@link ConsolidatorConfig.reflection} default (P1-1). */\n readonly reflection?: boolean;\n /** Override the {@link ConsolidatorConfig.importanceThreshold} default (P1-1). */\n readonly importanceThreshold?: number;\n /** Override the {@link ConsolidatorConfig.reflectionMaxQuestions} default (P1-1). */\n readonly reflectionMaxQuestions?: number;\n /** Override the per-tier {@link ConsolidatorConfig.contextualRetrieval} default (P1-3). */\n readonly contextualRetrieval?: ContextualRetrievalMode;\n /** Override the per-tier {@link ConsolidatorConfig.learnedContext} default (D3). */\n readonly learnedContext?: boolean;\n /** Override the {@link ConsolidatorConfig.learnedContextMaxChars} default (D3). */\n readonly learnedContextMaxChars?: number;\n /** Default scope used by event triggers + the manual `fireNow` path. */\n readonly defaultScope?: SessionScope;\n}\n\n/**\n * Tier preset table. The defaults follow ADR-038 §4 - `'free'`\n * disables every LLM phase and pins zero ceilings, the upper tiers\n * widen the budget envelope progressively.\n *\n * @stable\n */\nexport const CONSOLIDATOR_TIER_DEFAULTS: Readonly<\n Record<\n ConsolidatorTier,\n {\n readonly ceilings: ConsolidatorCeilings;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly cheapModel: string | null;\n readonly deepModel: string | null;\n readonly onExceed: OnBudgetExceed;\n readonly formEpisodes: boolean;\n readonly importanceScoring: boolean;\n readonly reflection: boolean;\n readonly importanceThreshold: number;\n readonly reflectionMaxQuestions: number;\n readonly contextualRetrieval: ContextualRetrievalMode;\n readonly learnedContext: boolean;\n readonly learnedContextMaxChars: number;\n }\n >\n> = Object.freeze({\n free: {\n ceilings: {\n maxTokensPerDay: 0,\n maxCostPerDay: 0,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 5 * 60 * 1000,\n cooldownMs: 60_000,\n },\n phases: ['light'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'pause',\n formEpisodes: false,\n importanceScoring: false,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n learnedContext: false,\n learnedContextMaxChars: 1200,\n },\n cheap: {\n ceilings: {\n maxTokensPerDay: 50_000,\n maxCostPerDay: 0.2,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 5 * 60 * 1000,\n cooldownMs: 60_000,\n },\n phases: ['light', 'standard'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'pause',\n formEpisodes: false,\n importanceScoring: false,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n learnedContext: false,\n learnedContextMaxChars: 1200,\n },\n standard: {\n ceilings: {\n maxTokensPerDay: 200_000,\n maxCostPerDay: 1.0,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 10 * 60 * 1000,\n cooldownMs: 30_000,\n },\n phases: ['light', 'standard', 'deep'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'log',\n formEpisodes: true,\n importanceScoring: true,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n learnedContext: false,\n learnedContextMaxChars: 1200,\n },\n full: {\n ceilings: {\n maxTokensPerDay: 1_000_000,\n maxCostPerDay: 5.0,\n maxConcurrentRuns: 2,\n maxRunDurationMs: 15 * 60 * 1000,\n cooldownMs: 10_000,\n },\n phases: ['light', 'standard', 'deep'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'log',\n formEpisodes: true,\n importanceScoring: true,\n reflection: true,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n learnedContext: false,\n learnedContextMaxChars: 1200,\n },\n custom: {\n ceilings: {\n maxTokensPerDay: 0,\n maxCostPerDay: 0,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 5 * 60 * 1000,\n cooldownMs: 60_000,\n },\n phases: ['light'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'pause',\n formEpisodes: false,\n importanceScoring: false,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n learnedContext: false,\n learnedContextMaxChars: 1200,\n },\n});\n"],"mappings":";;;;;;;;AAucA,MAAaA,6BAmBT,OAAO,OAAO;CAChB,MAAM;EACJ,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAS;GAC3B,YAAY;GACb;EACD,QAAQ,CAAC,QAAQ;EACjB,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACrB,gBAAgB;EAChB,wBAAwB;EACzB;CACD,OAAO;EACL,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAS;GAC3B,YAAY;GACb;EACD,QAAQ,CAAC,SAAS,WAAW;EAC7B,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACrB,gBAAgB;EAChB,wBAAwB;EACzB;CACD,UAAU;EACR,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAU;GAC5B,YAAY;GACb;EACD,QAAQ;GAAC;GAAS;GAAY;GAAO;EACrC,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACrB,gBAAgB;EAChB,wBAAwB;EACzB;CACD,MAAM;EACJ,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAU;GAC5B,YAAY;GACb;EACD,QAAQ;GAAC;GAAS;GAAY;GAAO;EACrC,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACrB,gBAAgB;EAChB,wBAAwB;EACzB;CACD,QAAQ;EACN,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAS;GAC3B,YAAY;GACb;EACD,QAAQ,CAAC,QAAQ;EACjB,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACrB,gBAAgB;EAChB,wBAAwB;EACzB;CACF,CAAC"}
@@ -8,16 +8,16 @@
8
8
  * Every {@link MessageContent} part assembled by the ContextEngine
9
9
  * carries two **independent** annotations:
10
10
  *
11
- * - `graphorin.content.origin` where the content came from. Used
11
+ * - `graphorin.content.origin` - where the content came from. Used
12
12
  * by D3 (`withRedaction`) under `scanScope: 'untrusted'` to
13
13
  * decide whether to re-scan a part that already passed the D2
14
14
  * sensitivity-tier filter.
15
- * - `graphorin.content.inbound.trust` what trust class the source
15
+ * - `graphorin.content.inbound.trust` - what trust class the source
16
16
  * carries. Used by D4 (`withInboundSanitization`) and by Phase 12
17
17
  * (agent runtime) to gate the per-step preamble injection.
18
18
  *
19
19
  * Both annotations live as **span attributes only** (observability)
20
- * they are never serialized to the wire payload. The wire-stable
20
+ * - they are never serialized to the wire payload. The wire-stable
21
21
  * `ProviderRequest` shape is unchanged by Phase 10d.
22
22
  *
23
23
  * @packageDocumentation
@@ -49,18 +49,18 @@ type ContentOrigin = 'memory:tier-filtered' | 'system:framework' | 'agent:instru
49
49
  * Trust-class discriminator for an assembled message-content part.
50
50
  * Sibling axis to {@link ContentOrigin}; the two are independent.
51
51
  *
52
- * - `'trusted'` built-in framework tools + trusted-skill-bundled
52
+ * - `'trusted'` - built-in framework tools + trusted-skill-bundled
53
53
  * tools; D4 preamble does NOT fire on steps containing only
54
54
  * these parts.
55
- * - `'user-defined'` tools registered via `tool({...})` from user
55
+ * - `'user-defined'` - tools registered via `tool({...})` from user
56
56
  * application code; D4 preamble fires.
57
- * - `'untrusted-skill'` tools bundled by an untrusted skill; D4
57
+ * - `'untrusted-skill'` - tools bundled by an untrusted skill; D4
58
58
  * preamble fires; default policy is strip-and-wrap.
59
- * - `'mcp'` every `Tool` produced by `MCPClient.toTools(...)`; D4
59
+ * - `'mcp'` - every `Tool` produced by `MCPClient.toTools(...)`; D4
60
60
  * preamble fires; default policy is strip-and-wrap.
61
- * - `'web-search'` built-in `web_search` adapter; D4 preamble
61
+ * - `'web-search'` - built-in `web_search` adapter; D4 preamble
62
62
  * fires; default policy is strip-and-wrap.
63
- * - `'n/a'` non-tool-result parts for which the inbound-trust
63
+ * - `'n/a'` - non-tool-result parts for which the inbound-trust
64
64
  * axis is meaningless (`'user:input'`, `'memory:tier-filtered'`,
65
65
  * `'system:framework'`, `'agent:instructions'`,
66
66
  * `'tool-call:args'`).
@@ -8,16 +8,16 @@
8
8
  * Every {@link MessageContent} part assembled by the ContextEngine
9
9
  * carries two **independent** annotations:
10
10
  *
11
- * - `graphorin.content.origin` where the content came from. Used
11
+ * - `graphorin.content.origin` - where the content came from. Used
12
12
  * by D3 (`withRedaction`) under `scanScope: 'untrusted'` to
13
13
  * decide whether to re-scan a part that already passed the D2
14
14
  * sensitivity-tier filter.
15
- * - `graphorin.content.inbound.trust` what trust class the source
15
+ * - `graphorin.content.inbound.trust` - what trust class the source
16
16
  * carries. Used by D4 (`withInboundSanitization`) and by Phase 12
17
17
  * (agent runtime) to gate the per-step preamble injection.
18
18
  *
19
19
  * Both annotations live as **span attributes only** (observability)
20
- * they are never serialized to the wire payload. The wire-stable
20
+ * - they are never serialized to the wire payload. The wire-stable
21
21
  * `ProviderRequest` shape is unchanged by Phase 10d.
22
22
  *
23
23
  * @packageDocumentation