@graphorin/memory 0.5.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 (287) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +21 -0
  3. package/README.md +401 -0
  4. package/dist/conflict/index.d.ts +3 -0
  5. package/dist/conflict/index.js +7 -0
  6. package/dist/conflict/locale-packs/en.js +262 -0
  7. package/dist/conflict/locale-packs/en.js.map +1 -0
  8. package/dist/conflict/locale-packs/index.js +4 -0
  9. package/dist/conflict/locale-packs/types.d.ts +103 -0
  10. package/dist/conflict/locale-packs/types.d.ts.map +1 -0
  11. package/dist/conflict/locale-packs/types.js +55 -0
  12. package/dist/conflict/locale-packs/types.js.map +1 -0
  13. package/dist/conflict/pipeline.d.ts +35 -0
  14. package/dist/conflict/pipeline.d.ts.map +1 -0
  15. package/dist/conflict/pipeline.js +257 -0
  16. package/dist/conflict/pipeline.js.map +1 -0
  17. package/dist/conflict/stages/helpers.js +66 -0
  18. package/dist/conflict/stages/helpers.js.map +1 -0
  19. package/dist/conflict/stages/stage1-exact-dedup.js +21 -0
  20. package/dist/conflict/stages/stage1-exact-dedup.js.map +1 -0
  21. package/dist/conflict/stages/stage2-embedding-three-zone.js +37 -0
  22. package/dist/conflict/stages/stage2-embedding-three-zone.js.map +1 -0
  23. package/dist/conflict/stages/stage3-heuristic-regex.js +45 -0
  24. package/dist/conflict/stages/stage3-heuristic-regex.js.map +1 -0
  25. package/dist/conflict/stages/stage4-subject-predicate.js +31 -0
  26. package/dist/conflict/stages/stage4-subject-predicate.js.map +1 -0
  27. package/dist/conflict/stages/stage5-defer-to-deep.js +22 -0
  28. package/dist/conflict/stages/stage5-defer-to-deep.js.map +1 -0
  29. package/dist/conflict/types.d.ts +222 -0
  30. package/dist/conflict/types.d.ts.map +1 -0
  31. package/dist/conflict/types.js +50 -0
  32. package/dist/conflict/types.js.map +1 -0
  33. package/dist/consolidator/budget.d.ts +1 -0
  34. package/dist/consolidator/budget.js +214 -0
  35. package/dist/consolidator/budget.js.map +1 -0
  36. package/dist/consolidator/decay.d.ts +35 -0
  37. package/dist/consolidator/decay.d.ts.map +1 -0
  38. package/dist/consolidator/decay.js +91 -0
  39. package/dist/consolidator/decay.js.map +1 -0
  40. package/dist/consolidator/dlq.js +58 -0
  41. package/dist/consolidator/dlq.js.map +1 -0
  42. package/dist/consolidator/errors.d.ts +54 -0
  43. package/dist/consolidator/errors.d.ts.map +1 -0
  44. package/dist/consolidator/errors.js +67 -0
  45. package/dist/consolidator/errors.js.map +1 -0
  46. package/dist/consolidator/idempotency.d.ts +1 -0
  47. package/dist/consolidator/idempotency.js +22 -0
  48. package/dist/consolidator/idempotency.js.map +1 -0
  49. package/dist/consolidator/index.d.ts +34 -0
  50. package/dist/consolidator/index.d.ts.map +1 -0
  51. package/dist/consolidator/index.js +163 -0
  52. package/dist/consolidator/index.js.map +1 -0
  53. package/dist/consolidator/lock.d.ts +2 -0
  54. package/dist/consolidator/lock.js +89 -0
  55. package/dist/consolidator/lock.js.map +1 -0
  56. package/dist/consolidator/noise-filter.d.ts +2 -0
  57. package/dist/consolidator/noise-filter.js +173 -0
  58. package/dist/consolidator/noise-filter.js.map +1 -0
  59. package/dist/consolidator/phases/deep.d.ts +4 -0
  60. package/dist/consolidator/phases/deep.js +198 -0
  61. package/dist/consolidator/phases/deep.js.map +1 -0
  62. package/dist/consolidator/phases/induce.d.ts +154 -0
  63. package/dist/consolidator/phases/induce.d.ts.map +1 -0
  64. package/dist/consolidator/phases/induce.js +253 -0
  65. package/dist/consolidator/phases/induce.js.map +1 -0
  66. package/dist/consolidator/phases/light.d.ts +4 -0
  67. package/dist/consolidator/phases/light.js +99 -0
  68. package/dist/consolidator/phases/light.js.map +1 -0
  69. package/dist/consolidator/phases/reflect.js +287 -0
  70. package/dist/consolidator/phases/reflect.js.map +1 -0
  71. package/dist/consolidator/phases/standard.d.ts +8 -0
  72. package/dist/consolidator/phases/standard.js +499 -0
  73. package/dist/consolidator/phases/standard.js.map +1 -0
  74. package/dist/consolidator/reconcile.js +192 -0
  75. package/dist/consolidator/reconcile.js.map +1 -0
  76. package/dist/consolidator/runtime.d.ts +62 -0
  77. package/dist/consolidator/runtime.d.ts.map +1 -0
  78. package/dist/consolidator/runtime.js +580 -0
  79. package/dist/consolidator/runtime.js.map +1 -0
  80. package/dist/consolidator/scheduler.d.ts +111 -0
  81. package/dist/consolidator/scheduler.d.ts.map +1 -0
  82. package/dist/consolidator/scheduler.js +71 -0
  83. package/dist/consolidator/scheduler.js.map +1 -0
  84. package/dist/consolidator/triggers.d.ts +40 -0
  85. package/dist/consolidator/triggers.d.ts.map +1 -0
  86. package/dist/consolidator/triggers.js +94 -0
  87. package/dist/consolidator/triggers.js.map +1 -0
  88. package/dist/consolidator/types.d.ts +397 -0
  89. package/dist/consolidator/types.d.ts.map +1 -0
  90. package/dist/consolidator/types.js +117 -0
  91. package/dist/consolidator/types.js.map +1 -0
  92. package/dist/context-engine/annotations.d.ts +118 -0
  93. package/dist/context-engine/annotations.d.ts.map +1 -0
  94. package/dist/context-engine/annotations.js +102 -0
  95. package/dist/context-engine/annotations.js.map +1 -0
  96. package/dist/context-engine/auto-recall.d.ts +52 -0
  97. package/dist/context-engine/auto-recall.d.ts.map +1 -0
  98. package/dist/context-engine/auto-recall.js +41 -0
  99. package/dist/context-engine/auto-recall.js.map +1 -0
  100. package/dist/context-engine/compaction/clear-tool-results.d.ts +55 -0
  101. package/dist/context-engine/compaction/clear-tool-results.d.ts.map +1 -0
  102. package/dist/context-engine/compaction/clear-tool-results.js +97 -0
  103. package/dist/context-engine/compaction/clear-tool-results.js.map +1 -0
  104. package/dist/context-engine/compaction/compactor.d.ts +52 -0
  105. package/dist/context-engine/compaction/compactor.d.ts.map +1 -0
  106. package/dist/context-engine/compaction/compactor.js +196 -0
  107. package/dist/context-engine/compaction/compactor.js.map +1 -0
  108. package/dist/context-engine/compaction/hooks/reanchor-persona-block.d.ts +15 -0
  109. package/dist/context-engine/compaction/hooks/reanchor-persona-block.d.ts.map +1 -0
  110. package/dist/context-engine/compaction/hooks/reanchor-persona-block.js +27 -0
  111. package/dist/context-engine/compaction/hooks/reanchor-persona-block.js.map +1 -0
  112. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.d.ts +18 -0
  113. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.d.ts.map +1 -0
  114. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.js +47 -0
  115. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.js.map +1 -0
  116. package/dist/context-engine/compaction/hooks/reanchor-project-rules.d.ts +15 -0
  117. package/dist/context-engine/compaction/hooks/reanchor-project-rules.d.ts.map +1 -0
  118. package/dist/context-engine/compaction/hooks/reanchor-project-rules.js +32 -0
  119. package/dist/context-engine/compaction/hooks/reanchor-project-rules.js.map +1 -0
  120. package/dist/context-engine/compaction/hooks/types.d.ts +42 -0
  121. package/dist/context-engine/compaction/hooks/types.d.ts.map +1 -0
  122. package/dist/context-engine/compaction/index.d.ts +9 -0
  123. package/dist/context-engine/compaction/index.js +9 -0
  124. package/dist/context-engine/compaction/templates/summary-9-section.d.ts +84 -0
  125. package/dist/context-engine/compaction/templates/summary-9-section.d.ts.map +1 -0
  126. package/dist/context-engine/compaction/templates/summary-9-section.js +84 -0
  127. package/dist/context-engine/compaction/templates/summary-9-section.js.map +1 -0
  128. package/dist/context-engine/compaction/thresholds.d.ts +68 -0
  129. package/dist/context-engine/compaction/thresholds.d.ts.map +1 -0
  130. package/dist/context-engine/compaction/thresholds.js +63 -0
  131. package/dist/context-engine/compaction/thresholds.js.map +1 -0
  132. package/dist/context-engine/compaction/types.d.ts +202 -0
  133. package/dist/context-engine/compaction/types.d.ts.map +1 -0
  134. package/dist/context-engine/engine.d.ts +258 -0
  135. package/dist/context-engine/engine.d.ts.map +1 -0
  136. package/dist/context-engine/engine.js +424 -0
  137. package/dist/context-engine/engine.js.map +1 -0
  138. package/dist/context-engine/index.d.ts +68 -0
  139. package/dist/context-engine/index.d.ts.map +1 -0
  140. package/dist/context-engine/index.js +24 -0
  141. package/dist/context-engine/locale-packs/en.d.ts +14 -0
  142. package/dist/context-engine/locale-packs/en.d.ts.map +1 -0
  143. package/dist/context-engine/locale-packs/en.js +87 -0
  144. package/dist/context-engine/locale-packs/en.js.map +1 -0
  145. package/dist/context-engine/locale-packs/index.js +4 -0
  146. package/dist/context-engine/locale-packs/resolver.d.ts +41 -0
  147. package/dist/context-engine/locale-packs/resolver.d.ts.map +1 -0
  148. package/dist/context-engine/locale-packs/resolver.js +119 -0
  149. package/dist/context-engine/locale-packs/resolver.js.map +1 -0
  150. package/dist/context-engine/locale-packs/types.d.ts +119 -0
  151. package/dist/context-engine/locale-packs/types.d.ts.map +1 -0
  152. package/dist/context-engine/locale-packs/types.js +24 -0
  153. package/dist/context-engine/locale-packs/types.js.map +1 -0
  154. package/dist/context-engine/metadata.d.ts +40 -0
  155. package/dist/context-engine/metadata.d.ts.map +1 -0
  156. package/dist/context-engine/metadata.js +66 -0
  157. package/dist/context-engine/metadata.js.map +1 -0
  158. package/dist/context-engine/preambles/inbound-en.d.ts +20 -0
  159. package/dist/context-engine/preambles/inbound-en.d.ts.map +1 -0
  160. package/dist/context-engine/preambles/inbound-en.js +23 -0
  161. package/dist/context-engine/preambles/inbound-en.js.map +1 -0
  162. package/dist/context-engine/privacy-filter.d.ts +108 -0
  163. package/dist/context-engine/privacy-filter.d.ts.map +1 -0
  164. package/dist/context-engine/privacy-filter.js +113 -0
  165. package/dist/context-engine/privacy-filter.js.map +1 -0
  166. package/dist/context-engine/templates/base-en.d.ts +19 -0
  167. package/dist/context-engine/templates/base-en.d.ts.map +1 -0
  168. package/dist/context-engine/templates/base-en.js +22 -0
  169. package/dist/context-engine/templates/base-en.js.map +1 -0
  170. package/dist/context-engine/templates/composer.d.ts +55 -0
  171. package/dist/context-engine/templates/composer.d.ts.map +1 -0
  172. package/dist/context-engine/templates/composer.js +51 -0
  173. package/dist/context-engine/templates/composer.js.map +1 -0
  174. package/dist/context-engine/token-budget.d.ts +99 -0
  175. package/dist/context-engine/token-budget.d.ts.map +1 -0
  176. package/dist/context-engine/token-budget.js +211 -0
  177. package/dist/context-engine/token-budget.js.map +1 -0
  178. package/dist/context-engine/token-counter.d.ts +54 -0
  179. package/dist/context-engine/token-counter.d.ts.map +1 -0
  180. package/dist/context-engine/token-counter.js +81 -0
  181. package/dist/context-engine/token-counter.js.map +1 -0
  182. package/dist/errors/index.d.ts +171 -0
  183. package/dist/errors/index.d.ts.map +1 -0
  184. package/dist/errors/index.js +206 -0
  185. package/dist/errors/index.js.map +1 -0
  186. package/dist/facade.d.ts +278 -0
  187. package/dist/facade.d.ts.map +1 -0
  188. package/dist/facade.js +265 -0
  189. package/dist/facade.js.map +1 -0
  190. package/dist/graph/entity-resolver.d.ts +135 -0
  191. package/dist/graph/entity-resolver.d.ts.map +1 -0
  192. package/dist/graph/entity-resolver.js +202 -0
  193. package/dist/graph/entity-resolver.js.map +1 -0
  194. package/dist/graph/index.d.ts +1 -0
  195. package/dist/index.d.ts +103 -0
  196. package/dist/index.d.ts.map +1 -0
  197. package/dist/index.js +95 -0
  198. package/dist/index.js.map +1 -0
  199. package/dist/internal/contextualize.d.ts +14 -0
  200. package/dist/internal/contextualize.d.ts.map +1 -0
  201. package/dist/internal/contextualize.js +110 -0
  202. package/dist/internal/contextualize.js.map +1 -0
  203. package/dist/internal/embedder-binding.js +50 -0
  204. package/dist/internal/embedder-binding.js.map +1 -0
  205. package/dist/internal/id.js +24 -0
  206. package/dist/internal/id.js.map +1 -0
  207. package/dist/internal/injection-heuristics.js +64 -0
  208. package/dist/internal/injection-heuristics.js.map +1 -0
  209. package/dist/internal/spans.js +35 -0
  210. package/dist/internal/spans.js.map +1 -0
  211. package/dist/internal/storage-adapter.d.ts +742 -0
  212. package/dist/internal/storage-adapter.d.ts.map +1 -0
  213. package/dist/migration/embedder-migration.d.ts +124 -0
  214. package/dist/migration/embedder-migration.d.ts.map +1 -0
  215. package/dist/migration/embedder-migration.js +109 -0
  216. package/dist/migration/embedder-migration.js.map +1 -0
  217. package/dist/migration/index.d.ts +2 -0
  218. package/dist/migration/index.js +3 -0
  219. package/dist/search/explain.d.ts +74 -0
  220. package/dist/search/explain.d.ts.map +1 -0
  221. package/dist/search/explain.js +50 -0
  222. package/dist/search/explain.js.map +1 -0
  223. package/dist/search/index.d.ts +6 -0
  224. package/dist/search/index.js +6 -0
  225. package/dist/search/iterative.d.ts +223 -0
  226. package/dist/search/iterative.d.ts.map +1 -0
  227. package/dist/search/iterative.js +330 -0
  228. package/dist/search/iterative.js.map +1 -0
  229. package/dist/search/query-transform.d.ts +112 -0
  230. package/dist/search/query-transform.d.ts.map +1 -0
  231. package/dist/search/query-transform.js +184 -0
  232. package/dist/search/query-transform.js.map +1 -0
  233. package/dist/search/rrf.d.ts +95 -0
  234. package/dist/search/rrf.d.ts.map +1 -0
  235. package/dist/search/rrf.js +166 -0
  236. package/dist/search/rrf.js.map +1 -0
  237. package/dist/search/types.d.ts +50 -0
  238. package/dist/search/types.d.ts.map +1 -0
  239. package/dist/tiers/episodic-memory.d.ts +142 -0
  240. package/dist/tiers/episodic-memory.d.ts.map +1 -0
  241. package/dist/tiers/episodic-memory.js +254 -0
  242. package/dist/tiers/episodic-memory.js.map +1 -0
  243. package/dist/tiers/index.d.ts +8 -0
  244. package/dist/tiers/index.js +9 -0
  245. package/dist/tiers/insight-memory.d.ts +71 -0
  246. package/dist/tiers/insight-memory.d.ts.map +1 -0
  247. package/dist/tiers/insight-memory.js +133 -0
  248. package/dist/tiers/insight-memory.js.map +1 -0
  249. package/dist/tiers/procedural-memory.d.ts +147 -0
  250. package/dist/tiers/procedural-memory.d.ts.map +1 -0
  251. package/dist/tiers/procedural-memory.js +267 -0
  252. package/dist/tiers/procedural-memory.js.map +1 -0
  253. package/dist/tiers/semantic-memory.d.ts +461 -0
  254. package/dist/tiers/semantic-memory.d.ts.map +1 -0
  255. package/dist/tiers/semantic-memory.js +631 -0
  256. package/dist/tiers/semantic-memory.js.map +1 -0
  257. package/dist/tiers/session-memory.d.ts +117 -0
  258. package/dist/tiers/session-memory.d.ts.map +1 -0
  259. package/dist/tiers/session-memory.js +163 -0
  260. package/dist/tiers/session-memory.js.map +1 -0
  261. package/dist/tiers/shared-memory.d.ts +29 -0
  262. package/dist/tiers/shared-memory.d.ts.map +1 -0
  263. package/dist/tiers/shared-memory.js +58 -0
  264. package/dist/tiers/shared-memory.js.map +1 -0
  265. package/dist/tiers/working-memory.d.ts +129 -0
  266. package/dist/tiers/working-memory.d.ts.map +1 -0
  267. package/dist/tiers/working-memory.js +229 -0
  268. package/dist/tiers/working-memory.js.map +1 -0
  269. package/dist/tools/block-tools.d.ts +98 -0
  270. package/dist/tools/block-tools.d.ts.map +1 -0
  271. package/dist/tools/block-tools.js +114 -0
  272. package/dist/tools/block-tools.js.map +1 -0
  273. package/dist/tools/fact-tools.d.ts +294 -0
  274. package/dist/tools/fact-tools.d.ts.map +1 -0
  275. package/dist/tools/fact-tools.js +293 -0
  276. package/dist/tools/fact-tools.js.map +1 -0
  277. package/dist/tools/index.d.ts +35 -0
  278. package/dist/tools/index.d.ts.map +1 -0
  279. package/dist/tools/index.js +36 -0
  280. package/dist/tools/index.js.map +1 -0
  281. package/dist/tools/recall-tools.d.ts +209 -0
  282. package/dist/tools/recall-tools.d.ts.map +1 -0
  283. package/dist/tools/recall-tools.js +170 -0
  284. package/dist/tools/recall-tools.js.map +1 -0
  285. package/dist/tools/types.d.ts +40 -0
  286. package/dist/tools/types.d.ts.map +1 -0
  287. package/package.json +119 -0
@@ -0,0 +1,129 @@
1
+ import { MemoryStoreAdapter } from "../internal/storage-adapter.js";
2
+ import { Block, Sensitivity, SessionScope, Tracer, ZodLikeSchema } from "@graphorin/core";
3
+
4
+ //#region src/tiers/working-memory.d.ts
5
+
6
+ /**
7
+ * Author-time block specification accepted by
8
+ * {@link defineBlock} and {@link WorkingMemory.define}.
9
+ *
10
+ * @stable
11
+ */
12
+ interface BlockSpec {
13
+ readonly label: string;
14
+ readonly description?: string;
15
+ readonly schema?: ZodLikeSchema<unknown>;
16
+ /** Maximum length of the rendered value in characters. */
17
+ readonly charLimit: number;
18
+ /** Default `'internal'`. */
19
+ readonly sensitivity?: Sensitivity;
20
+ /** Default `false`. */
21
+ readonly readOnly?: boolean;
22
+ /**
23
+ * Per-block default value. Applied on first definition only; later
24
+ * runs preserve any value already in storage.
25
+ */
26
+ readonly defaultValue?: string;
27
+ /** Default `'truncate'` — `'reject'` opt-in for strict use cases. */
28
+ readonly overflowPolicy?: 'truncate' | 'reject';
29
+ /** Optional free-form labels surfaced through `tags`. */
30
+ readonly tags?: ReadonlyArray<string>;
31
+ }
32
+ /**
33
+ * Frozen block definition returned by {@link defineBlock}. Re-used by
34
+ * the agent runtime / context engine to know which blocks should be
35
+ * compiled into the system prompt every step.
36
+ *
37
+ * @stable
38
+ */
39
+ interface BlockDefinition {
40
+ readonly label: string;
41
+ readonly description?: string;
42
+ readonly schema?: ZodLikeSchema<unknown>;
43
+ readonly charLimit: number;
44
+ readonly sensitivity: Sensitivity;
45
+ readonly readOnly: boolean;
46
+ readonly defaultValue?: string;
47
+ readonly overflowPolicy: 'truncate' | 'reject';
48
+ readonly tags?: ReadonlyArray<string>;
49
+ }
50
+ /**
51
+ * Build a frozen {@link BlockDefinition}. Surfaced as `blocks.define(...)`
52
+ * for ergonomic call-sites; the underlying object is the same shape
53
+ * the {@link WorkingMemory.define} method accepts.
54
+ *
55
+ * @stable
56
+ */
57
+ declare function defineBlock(spec: BlockSpec): BlockDefinition;
58
+ /**
59
+ * `WorkingMemory` — labeled, character-bounded blocks rendered into
60
+ * every system prompt. Operations:
61
+ *
62
+ * - `define(spec)`: idempotently registers a block definition; the
63
+ * block's row is created in storage on the next `write` call so
64
+ * operators can change `description` between runs without
65
+ * triggering a write.
66
+ * - `read(scope, label)` / `list(scope)`: surface the current block
67
+ * contents.
68
+ * - `write(scope, label, value)`: full replace.
69
+ * - `append(scope, label, content)`: append-with-newline.
70
+ * - `replace(scope, label, oldUnique, newText)`: targeted replace
71
+ * with a uniqueness check.
72
+ * - `compile(scope)`: render the active blocks for the context
73
+ * engine (used by Phase 10d).
74
+ *
75
+ * @stable
76
+ */
77
+ declare class WorkingMemory {
78
+ #private;
79
+ constructor(args: {
80
+ store: MemoryStoreAdapter;
81
+ tracer: Tracer;
82
+ });
83
+ /** Register a block definition. Returns the same definition object. */
84
+ define(definition: BlockDefinition): BlockDefinition;
85
+ /** Snapshot of every registered definition. */
86
+ definitions(): ReadonlyArray<BlockDefinition>;
87
+ /** Lookup a definition by label. */
88
+ definitionFor(label: string): BlockDefinition | undefined;
89
+ /** List active (non-deleted) blocks for the supplied scope. */
90
+ list(scope: SessionScope): Promise<ReadonlyArray<Block>>;
91
+ /** Read a single block's value (or `null` when absent). */
92
+ read(scope: SessionScope, label: string): Promise<string | null>;
93
+ /** Replace a block's value entirely. Honours overflow policy. */
94
+ write(scope: SessionScope, label: string, value: string): Promise<Block>;
95
+ /** Append `content` to a block (with a newline separator). */
96
+ append(scope: SessionScope, label: string, content: string): Promise<Block>;
97
+ /**
98
+ * Replace the unique substring `oldUnique` inside the block's value
99
+ * with `newText`. Throws `WorkingBlockReplaceMismatchError` when
100
+ * the substring is missing or appears more than once.
101
+ */
102
+ replace(scope: SessionScope, label: string, oldUnique: string, newText: string): Promise<Block>;
103
+ /** Run `mutator(current) => next` and persist the result. */
104
+ rethink(scope: SessionScope, label: string, mutator: (current: string) => string | Promise<string>): Promise<Block>;
105
+ /** Soft-delete a block. */
106
+ forget(scope: SessionScope, label: string, reason?: string): Promise<void>;
107
+ /**
108
+ * Attach a working block to an additional agent. Backed by the
109
+ * adapter's `shared.attach(...)` join table so multi-agent crews
110
+ * can share the same block without duplicating storage.
111
+ */
112
+ attach(scope: SessionScope, blockId: string, agentId: string): Promise<void>;
113
+ /** Detach a working block from an agent. */
114
+ detach(scope: SessionScope, blockId: string, agentId: string): Promise<void>;
115
+ /**
116
+ * Render a deterministic `<memory_blocks>` XML fragment for the
117
+ * supplied scope. The full layered system prompt (six layers) is
118
+ * produced by Phase 10d's ContextEngine; this method ships the
119
+ * minimum-viable rendering used by the smoke acceptance criteria.
120
+ *
121
+ * The optional `agentId` argument is reserved for the per-agent
122
+ * filtering Phase 10d wires through. In Phase 10a the argument is
123
+ * accepted but ignored — the rendering is scope-wide.
124
+ */
125
+ compile(scope: SessionScope, agentId?: string): Promise<string>;
126
+ }
127
+ //#endregion
128
+ export { BlockDefinition, BlockSpec, WorkingMemory, defineBlock };
129
+ //# sourceMappingURL=working-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"working-memory.d.ts","names":[],"sources":["../../src/tiers/working-memory.ts"],"sourcesContent":[],"mappings":";;;;;;;AAgBA;;;;AAkB+B,UAlBd,SAAA,CAkBc;EAUd,SAAA,KAAA,EAAA,MAAe;EAGZ,SAAA,WAAA,CAAA,EAAA,MAAA;EAEI,SAAA,MAAA,CAAA,EA9BJ,aA8BI,CAAA,OAAA,CAAA;EAIN;EAAa,SAAA,SAAA,EAAA,MAAA;EAUf;EAyCH,SAAA,WAAa,CAAA,EAjFD,WAiFC;EAKG;EAA4B,SAAA,QAAA,CAAA,EAAA,OAAA;EAOpC;;;;EAWW,SAAA,YAAA,CAAA,EAAA,MAAA;EAKZ;EAAqC,SAAA,cAAA,CAAA,EAAA,UAAA,GAAA,QAAA;EAAd;EAAR,SAAA,IAAA,CAAA,EAlGjB,aAkGiB,CAAA,MAAA,CAAA;;;;;;;;;AA+CxB,UAvIM,eAAA,CAuIN;EAIE,SAAA,KAAA,EAAA,MAAA;EAAR,SAAA,WAAA,CAAA,EAAA,MAAA;EAaM,SAAA,MAAA,CAAA,EArJS,aAqJT,CAAA,OAAA,CAAA;EAEgC,SAAA,SAAA,EAAA,MAAA;EAC9B,SAAA,WAAA,EAtJW,WAsJX;EAAR,SAAA,QAAA,EAAA,OAAA;EAKiB,SAAA,YAAA,CAAA,EAAA,MAAA;EAA+C,SAAA,cAAA,EAAA,UAAA,GAAA,QAAA;EAiB/C,SAAA,IAAA,CAAA,EAxKJ,aAwKI,CAAA,MAAA,CAAA;;;;;;;;;iBA9JN,WAAA,OAAkB,YAAY;;;;;;;;;;;;;;;;;;;;cAyCjC,aAAA;;;WAKgB;YAA4B;;;qBAOpC,kBAAkB;;iBAMtB,cAAc;;gCAKC;;cAKZ,eAAe,QAAQ,cAAc;;cASrC,8BAA8B;;eAoB7B,6CAA6C,QAAQ;;gBAKpD,+CAA+C,QAAQ;;;;;;iBAalE,kEAIN,QAAQ;;iBAaF,oEAEgC,kBACtC,QAAQ;;gBAKS,+CAA+C;;;;;;gBAiB/C,iDAAiD;;gBAiBjD,iDAAiD;;;;;;;;;;;iBA0BhD,iCAAiC"}
@@ -0,0 +1,229 @@
1
+ import { withMemorySpan } from "../internal/spans.js";
2
+ import { WorkingBlockOverflowError, WorkingBlockReadOnlyError, WorkingBlockReplaceMismatchError } from "../errors/index.js";
3
+ import { newMemoryId } from "../internal/id.js";
4
+
5
+ //#region src/tiers/working-memory.ts
6
+ /**
7
+ * Build a frozen {@link BlockDefinition}. Surfaced as `blocks.define(...)`
8
+ * for ergonomic call-sites; the underlying object is the same shape
9
+ * the {@link WorkingMemory.define} method accepts.
10
+ *
11
+ * @stable
12
+ */
13
+ function defineBlock(spec) {
14
+ if (!spec.label || spec.label.length === 0) throw new TypeError("[graphorin/memory] BlockSpec.label must be a non-empty string.");
15
+ if (!Number.isInteger(spec.charLimit) || spec.charLimit <= 0) throw new TypeError(`[graphorin/memory] BlockSpec.charLimit must be a positive integer, got ${String(spec.charLimit)}.`);
16
+ return Object.freeze({
17
+ label: spec.label,
18
+ ...spec.description !== void 0 ? { description: spec.description } : {},
19
+ ...spec.schema !== void 0 ? { schema: spec.schema } : {},
20
+ charLimit: spec.charLimit,
21
+ sensitivity: spec.sensitivity ?? "internal",
22
+ readOnly: spec.readOnly ?? false,
23
+ ...spec.defaultValue !== void 0 ? { defaultValue: spec.defaultValue } : {},
24
+ overflowPolicy: spec.overflowPolicy ?? "truncate",
25
+ ...spec.tags !== void 0 ? { tags: Object.freeze([...spec.tags]) } : {}
26
+ });
27
+ }
28
+ /**
29
+ * `WorkingMemory` — labeled, character-bounded blocks rendered into
30
+ * every system prompt. Operations:
31
+ *
32
+ * - `define(spec)`: idempotently registers a block definition; the
33
+ * block's row is created in storage on the next `write` call so
34
+ * operators can change `description` between runs without
35
+ * triggering a write.
36
+ * - `read(scope, label)` / `list(scope)`: surface the current block
37
+ * contents.
38
+ * - `write(scope, label, value)`: full replace.
39
+ * - `append(scope, label, content)`: append-with-newline.
40
+ * - `replace(scope, label, oldUnique, newText)`: targeted replace
41
+ * with a uniqueness check.
42
+ * - `compile(scope)`: render the active blocks for the context
43
+ * engine (used by Phase 10d).
44
+ *
45
+ * @stable
46
+ */
47
+ var WorkingMemory = class {
48
+ #store;
49
+ #tracer;
50
+ #defs;
51
+ constructor(args) {
52
+ this.#store = args.store;
53
+ this.#tracer = args.tracer;
54
+ this.#defs = /* @__PURE__ */ new Map();
55
+ }
56
+ /** Register a block definition. Returns the same definition object. */
57
+ define(definition) {
58
+ this.#defs.set(definition.label, definition);
59
+ return definition;
60
+ }
61
+ /** Snapshot of every registered definition. */
62
+ definitions() {
63
+ return Array.from(this.#defs.values());
64
+ }
65
+ /** Lookup a definition by label. */
66
+ definitionFor(label) {
67
+ return this.#defs.get(label);
68
+ }
69
+ /** List active (non-deleted) blocks for the supplied scope. */
70
+ async list(scope) {
71
+ return withMemorySpan(this.#tracer, "memory.read.working", scope, {}, async (span) => {
72
+ const out = await this.#store.working.list(scope);
73
+ span.setAttributes({ "memory.read.working.count": out.length });
74
+ return out;
75
+ });
76
+ }
77
+ /** Read a single block's value (or `null` when absent). */
78
+ async read(scope, label) {
79
+ return withMemorySpan(this.#tracer, "memory.read.working", scope, { "memory.block.label": label }, async (span) => {
80
+ const block = await this.#store.working.get(scope, label);
81
+ span.setAttributes({ "memory.read.working.found": block !== null });
82
+ if (block !== null) return block.value;
83
+ return this.#defs.get(label)?.defaultValue ?? null;
84
+ });
85
+ }
86
+ /** Replace a block's value entirely. Honours overflow policy. */
87
+ async write(scope, label, value) {
88
+ return this.#mutate(scope, label, async () => value);
89
+ }
90
+ /** Append `content` to a block (with a newline separator). */
91
+ async append(scope, label, content) {
92
+ return this.#mutate(scope, label, async (current) => {
93
+ if (current === "" || current === void 0) return content;
94
+ return `${current}\n${content}`;
95
+ });
96
+ }
97
+ /**
98
+ * Replace the unique substring `oldUnique` inside the block's value
99
+ * with `newText`. Throws `WorkingBlockReplaceMismatchError` when
100
+ * the substring is missing or appears more than once.
101
+ */
102
+ async replace(scope, label, oldUnique, newText) {
103
+ return this.#mutate(scope, label, async (current) => {
104
+ const haystack = current ?? "";
105
+ const occurrences = countOccurrences(haystack, oldUnique);
106
+ if (occurrences !== 1) throw new WorkingBlockReplaceMismatchError(label, occurrences);
107
+ return haystack.replace(oldUnique, newText);
108
+ });
109
+ }
110
+ /** Run `mutator(current) => next` and persist the result. */
111
+ async rethink(scope, label, mutator) {
112
+ return this.#mutate(scope, label, async (current) => mutator(current ?? ""));
113
+ }
114
+ /** Soft-delete a block. */
115
+ async forget(scope, label, reason) {
116
+ await withMemorySpan(this.#tracer, "memory.write.working", scope, {
117
+ "memory.block.label": label,
118
+ "memory.write.working.action": "forget"
119
+ }, async () => {
120
+ await this.#store.working.delete(scope, label, reason);
121
+ });
122
+ }
123
+ /**
124
+ * Attach a working block to an additional agent. Backed by the
125
+ * adapter's `shared.attach(...)` join table so multi-agent crews
126
+ * can share the same block without duplicating storage.
127
+ */
128
+ async attach(scope, blockId, agentId) {
129
+ await withMemorySpan(this.#tracer, "memory.write.working", scope, {
130
+ "memory.write.working.action": "attach",
131
+ "memory.block.id": blockId,
132
+ "memory.write.working.target_agent_id": agentId
133
+ }, async () => {
134
+ await this.#store.shared.attach(blockId, agentId);
135
+ });
136
+ }
137
+ /** Detach a working block from an agent. */
138
+ async detach(scope, blockId, agentId) {
139
+ await withMemorySpan(this.#tracer, "memory.write.working", scope, {
140
+ "memory.write.working.action": "detach",
141
+ "memory.block.id": blockId,
142
+ "memory.write.working.target_agent_id": agentId
143
+ }, async () => {
144
+ await this.#store.shared.detach(blockId, agentId);
145
+ });
146
+ }
147
+ /**
148
+ * Render a deterministic `<memory_blocks>` XML fragment for the
149
+ * supplied scope. The full layered system prompt (six layers) is
150
+ * produced by Phase 10d's ContextEngine; this method ships the
151
+ * minimum-viable rendering used by the smoke acceptance criteria.
152
+ *
153
+ * The optional `agentId` argument is reserved for the per-agent
154
+ * filtering Phase 10d wires through. In Phase 10a the argument is
155
+ * accepted but ignored — the rendering is scope-wide.
156
+ */
157
+ async compile(scope, agentId) {
158
+ const blocks = await this.list(scope);
159
+ if (blocks.length === 0) return "";
160
+ const lines = ["<memory_blocks>"];
161
+ for (const block of blocks) {
162
+ const description = block.description !== void 0 ? ` description="${escapeXml(block.description)}"` : "";
163
+ lines.push(` <block label="${escapeXml(block.label)}"${description}>`);
164
+ lines.push(` ${escapeXml(block.value)}`);
165
+ lines.push(" </block>");
166
+ }
167
+ lines.push("</memory_blocks>");
168
+ return lines.join("\n");
169
+ }
170
+ async #mutate(scope, label, nextValueFn) {
171
+ return withMemorySpan(this.#tracer, "memory.write.working", scope, { "memory.block.label": label }, async (span) => {
172
+ const definition = this.#requireDefinition(label);
173
+ if (definition.readOnly === true) throw new WorkingBlockReadOnlyError(label);
174
+ const existing = await this.#store.working.get(scope, label);
175
+ const enforcedValue = enforceCharLimit(await nextValueFn(existing?.value ?? definition.defaultValue), definition);
176
+ const now = (/* @__PURE__ */ new Date()).toISOString();
177
+ const block = {
178
+ id: existing?.id ?? newMemoryId("block"),
179
+ kind: "working",
180
+ userId: scope.userId,
181
+ ...scope.sessionId !== void 0 ? { sessionId: scope.sessionId } : {},
182
+ ...scope.agentId !== void 0 ? { agentId: scope.agentId } : {},
183
+ sensitivity: definition.sensitivity,
184
+ label,
185
+ ...definition.description !== void 0 ? { description: definition.description } : {},
186
+ value: enforcedValue,
187
+ charLimit: definition.charLimit,
188
+ readOnly: definition.readOnly,
189
+ ...definition.tags !== void 0 ? { tags: definition.tags } : {},
190
+ createdAt: existing?.createdAt ?? now,
191
+ updatedAt: now
192
+ };
193
+ await this.#store.working.upsert(scope, block);
194
+ span.setAttributes({
195
+ "memory.write.working.action": existing === null ? "create" : "update",
196
+ "memory.write.working.length": enforcedValue.length
197
+ });
198
+ return block;
199
+ });
200
+ }
201
+ #requireDefinition(label) {
202
+ const def = this.#defs.get(label);
203
+ if (def !== void 0) return def;
204
+ throw new TypeError(`[graphorin/memory] working block '${label}' was not defined. Call memory.working.define(blocks.define({...})) before writing to it.`);
205
+ }
206
+ };
207
+ function enforceCharLimit(value, definition) {
208
+ if (value.length <= definition.charLimit) return value;
209
+ if (definition.overflowPolicy === "reject") throw new WorkingBlockOverflowError(definition.label, value.length, definition.charLimit);
210
+ return value.slice(0, definition.charLimit);
211
+ }
212
+ function countOccurrences(haystack, needle) {
213
+ if (needle.length === 0) return 0;
214
+ let count = 0;
215
+ let idx = 0;
216
+ for (;;) {
217
+ const next = haystack.indexOf(needle, idx);
218
+ if (next === -1) return count;
219
+ count += 1;
220
+ idx = next + needle.length;
221
+ }
222
+ }
223
+ function escapeXml(value) {
224
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
225
+ }
226
+
227
+ //#endregion
228
+ export { WorkingMemory, defineBlock };
229
+ //# sourceMappingURL=working-memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"working-memory.js","names":["#store","#tracer","#defs","#mutate","#requireDefinition","block: Block"],"sources":["../../src/tiers/working-memory.ts"],"sourcesContent":["import type { Block, Sensitivity, SessionScope, Tracer, ZodLikeSchema } from '@graphorin/core';\nimport {\n WorkingBlockOverflowError,\n WorkingBlockReadOnlyError,\n WorkingBlockReplaceMismatchError,\n} from '../errors/index.js';\nimport { newMemoryId } from '../internal/id.js';\nimport { withMemorySpan } from '../internal/spans.js';\nimport type { MemoryStoreAdapter } from '../internal/storage-adapter.js';\n\n/**\n * Author-time block specification accepted by\n * {@link defineBlock} and {@link WorkingMemory.define}.\n *\n * @stable\n */\nexport interface BlockSpec {\n readonly label: string;\n readonly description?: string;\n readonly schema?: ZodLikeSchema<unknown>;\n /** Maximum length of the rendered value in characters. */\n readonly charLimit: number;\n /** Default `'internal'`. */\n readonly sensitivity?: Sensitivity;\n /** Default `false`. */\n readonly readOnly?: boolean;\n /**\n * Per-block default value. Applied on first definition only; later\n * runs preserve any value already in storage.\n */\n readonly defaultValue?: string;\n /** Default `'truncate'` — `'reject'` opt-in for strict use cases. */\n readonly overflowPolicy?: 'truncate' | 'reject';\n /** Optional free-form labels surfaced through `tags`. */\n readonly tags?: ReadonlyArray<string>;\n}\n\n/**\n * Frozen block definition returned by {@link defineBlock}. Re-used by\n * the agent runtime / context engine to know which blocks should be\n * compiled into the system prompt every step.\n *\n * @stable\n */\nexport interface BlockDefinition {\n readonly label: string;\n readonly description?: string;\n readonly schema?: ZodLikeSchema<unknown>;\n readonly charLimit: number;\n readonly sensitivity: Sensitivity;\n readonly readOnly: boolean;\n readonly defaultValue?: string;\n readonly overflowPolicy: 'truncate' | 'reject';\n readonly tags?: ReadonlyArray<string>;\n}\n\n/**\n * Build a frozen {@link BlockDefinition}. Surfaced as `blocks.define(...)`\n * for ergonomic call-sites; the underlying object is the same shape\n * the {@link WorkingMemory.define} method accepts.\n *\n * @stable\n */\nexport function defineBlock(spec: BlockSpec): BlockDefinition {\n if (!spec.label || spec.label.length === 0) {\n throw new TypeError('[graphorin/memory] BlockSpec.label must be a non-empty string.');\n }\n if (!Number.isInteger(spec.charLimit) || spec.charLimit <= 0) {\n throw new TypeError(\n `[graphorin/memory] BlockSpec.charLimit must be a positive integer, got ${String(spec.charLimit)}.`,\n );\n }\n return Object.freeze({\n label: spec.label,\n ...(spec.description !== undefined ? { description: spec.description } : {}),\n ...(spec.schema !== undefined ? { schema: spec.schema } : {}),\n charLimit: spec.charLimit,\n sensitivity: spec.sensitivity ?? 'internal',\n readOnly: spec.readOnly ?? false,\n ...(spec.defaultValue !== undefined ? { defaultValue: spec.defaultValue } : {}),\n overflowPolicy: spec.overflowPolicy ?? 'truncate',\n ...(spec.tags !== undefined ? { tags: Object.freeze([...spec.tags]) } : {}),\n });\n}\n\n/**\n * `WorkingMemory` — labeled, character-bounded blocks rendered into\n * every system prompt. Operations:\n *\n * - `define(spec)`: idempotently registers a block definition; the\n * block's row is created in storage on the next `write` call so\n * operators can change `description` between runs without\n * triggering a write.\n * - `read(scope, label)` / `list(scope)`: surface the current block\n * contents.\n * - `write(scope, label, value)`: full replace.\n * - `append(scope, label, content)`: append-with-newline.\n * - `replace(scope, label, oldUnique, newText)`: targeted replace\n * with a uniqueness check.\n * - `compile(scope)`: render the active blocks for the context\n * engine (used by Phase 10d).\n *\n * @stable\n */\nexport class WorkingMemory {\n readonly #store: MemoryStoreAdapter;\n readonly #tracer: Tracer;\n readonly #defs: Map<string, BlockDefinition>;\n\n constructor(args: { store: MemoryStoreAdapter; tracer: Tracer }) {\n this.#store = args.store;\n this.#tracer = args.tracer;\n this.#defs = new Map();\n }\n\n /** Register a block definition. Returns the same definition object. */\n define(definition: BlockDefinition): BlockDefinition {\n this.#defs.set(definition.label, definition);\n return definition;\n }\n\n /** Snapshot of every registered definition. */\n definitions(): ReadonlyArray<BlockDefinition> {\n return Array.from(this.#defs.values());\n }\n\n /** Lookup a definition by label. */\n definitionFor(label: string): BlockDefinition | undefined {\n return this.#defs.get(label);\n }\n\n /** List active (non-deleted) blocks for the supplied scope. */\n async list(scope: SessionScope): Promise<ReadonlyArray<Block>> {\n return withMemorySpan(this.#tracer, 'memory.read.working', scope, {}, async (span) => {\n const out = await this.#store.working.list(scope);\n span.setAttributes({ 'memory.read.working.count': out.length });\n return out;\n });\n }\n\n /** Read a single block's value (or `null` when absent). */\n async read(scope: SessionScope, label: string): Promise<string | null> {\n return withMemorySpan(\n this.#tracer,\n 'memory.read.working',\n scope,\n { 'memory.block.label': label },\n async (span) => {\n const block = await this.#store.working.get(scope, label);\n span.setAttributes({ 'memory.read.working.found': block !== null });\n if (block !== null) return block.value;\n // MST-8: a defined-but-unwritten block answers with its declared\n // defaultValue (previously advertised, copied into the\n // definition, and then never read by anything).\n const definition = this.#defs.get(label);\n return definition?.defaultValue ?? null;\n },\n );\n }\n\n /** Replace a block's value entirely. Honours overflow policy. */\n async write(scope: SessionScope, label: string, value: string): Promise<Block> {\n return this.#mutate(scope, label, async () => value);\n }\n\n /** Append `content` to a block (with a newline separator). */\n async append(scope: SessionScope, label: string, content: string): Promise<Block> {\n return this.#mutate(scope, label, async (current) => {\n if (current === '' || current === undefined) return content;\n return `${current}\\n${content}`;\n });\n }\n\n /**\n * Replace the unique substring `oldUnique` inside the block's value\n * with `newText`. Throws `WorkingBlockReplaceMismatchError` when\n * the substring is missing or appears more than once.\n */\n async replace(\n scope: SessionScope,\n label: string,\n oldUnique: string,\n newText: string,\n ): Promise<Block> {\n return this.#mutate(scope, label, async (current) => {\n const haystack = current ?? '';\n const occurrences = countOccurrences(haystack, oldUnique);\n if (occurrences !== 1) {\n throw new WorkingBlockReplaceMismatchError(label, occurrences);\n }\n return haystack.replace(oldUnique, newText);\n });\n }\n\n /** Run `mutator(current) => next` and persist the result. */\n async rethink(\n scope: SessionScope,\n label: string,\n mutator: (current: string) => string | Promise<string>,\n ): Promise<Block> {\n return this.#mutate(scope, label, async (current) => mutator(current ?? ''));\n }\n\n /** Soft-delete a block. */\n async forget(scope: SessionScope, label: string, reason?: string): Promise<void> {\n await withMemorySpan(\n this.#tracer,\n 'memory.write.working',\n scope,\n { 'memory.block.label': label, 'memory.write.working.action': 'forget' },\n async () => {\n await this.#store.working.delete(scope, label, reason);\n },\n );\n }\n\n /**\n * Attach a working block to an additional agent. Backed by the\n * adapter's `shared.attach(...)` join table so multi-agent crews\n * can share the same block without duplicating storage.\n */\n async attach(scope: SessionScope, blockId: string, agentId: string): Promise<void> {\n await withMemorySpan(\n this.#tracer,\n 'memory.write.working',\n scope,\n {\n 'memory.write.working.action': 'attach',\n 'memory.block.id': blockId,\n 'memory.write.working.target_agent_id': agentId,\n },\n async () => {\n await this.#store.shared.attach(blockId, agentId);\n },\n );\n }\n\n /** Detach a working block from an agent. */\n async detach(scope: SessionScope, blockId: string, agentId: string): Promise<void> {\n await withMemorySpan(\n this.#tracer,\n 'memory.write.working',\n scope,\n {\n 'memory.write.working.action': 'detach',\n 'memory.block.id': blockId,\n 'memory.write.working.target_agent_id': agentId,\n },\n async () => {\n await this.#store.shared.detach(blockId, agentId);\n },\n );\n }\n\n /**\n * Render a deterministic `<memory_blocks>` XML fragment for the\n * supplied scope. The full layered system prompt (six layers) is\n * produced by Phase 10d's ContextEngine; this method ships the\n * minimum-viable rendering used by the smoke acceptance criteria.\n *\n * The optional `agentId` argument is reserved for the per-agent\n * filtering Phase 10d wires through. In Phase 10a the argument is\n * accepted but ignored — the rendering is scope-wide.\n */\n async compile(scope: SessionScope, agentId?: string): Promise<string> {\n void agentId;\n const blocks = await this.list(scope);\n if (blocks.length === 0) return '';\n const lines = ['<memory_blocks>'];\n for (const block of blocks) {\n const description =\n block.description !== undefined ? ` description=\"${escapeXml(block.description)}\"` : '';\n lines.push(` <block label=\"${escapeXml(block.label)}\"${description}>`);\n lines.push(` ${escapeXml(block.value)}`);\n lines.push(' </block>');\n }\n lines.push('</memory_blocks>');\n return lines.join('\\n');\n }\n\n async #mutate(\n scope: SessionScope,\n label: string,\n nextValueFn: (current: string | undefined) => Promise<string>,\n ): Promise<Block> {\n return withMemorySpan(\n this.#tracer,\n 'memory.write.working',\n scope,\n { 'memory.block.label': label },\n async (span) => {\n const definition = this.#requireDefinition(label);\n if (definition.readOnly === true) {\n // MRET-14: a dedicated kind — the old\n // WorkingBlockReplaceMismatchError(label, 0) read as \"substring\n // matched 0 times\" and misled replace-retry callers.\n throw new WorkingBlockReadOnlyError(label);\n }\n const existing = await this.#store.working.get(scope, label);\n // MST-8: first materialization starts from the declared default,\n // so an append/replace on an unwritten block composes with it.\n const candidate = await nextValueFn(existing?.value ?? definition.defaultValue);\n const enforcedValue = enforceCharLimit(candidate, definition);\n const now = new Date().toISOString();\n const id = existing?.id ?? newMemoryId('block');\n const block: Block = {\n id,\n kind: 'working',\n userId: scope.userId,\n ...(scope.sessionId !== undefined ? { sessionId: scope.sessionId } : {}),\n ...(scope.agentId !== undefined ? { agentId: scope.agentId } : {}),\n sensitivity: definition.sensitivity,\n label,\n ...(definition.description !== undefined ? { description: definition.description } : {}),\n value: enforcedValue,\n charLimit: definition.charLimit,\n readOnly: definition.readOnly,\n ...(definition.tags !== undefined ? { tags: definition.tags } : {}),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n };\n await this.#store.working.upsert(scope, block);\n span.setAttributes({\n 'memory.write.working.action': existing === null ? 'create' : 'update',\n 'memory.write.working.length': enforcedValue.length,\n });\n return block;\n },\n );\n }\n\n #requireDefinition(label: string): BlockDefinition {\n const def = this.#defs.get(label);\n if (def !== undefined) return def;\n throw new TypeError(\n `[graphorin/memory] working block '${label}' was not defined. ` +\n 'Call memory.working.define(blocks.define({...})) before writing to it.',\n );\n }\n}\n\nfunction enforceCharLimit(value: string, definition: BlockDefinition): string {\n if (value.length <= definition.charLimit) return value;\n if (definition.overflowPolicy === 'reject') {\n throw new WorkingBlockOverflowError(definition.label, value.length, definition.charLimit);\n }\n return value.slice(0, definition.charLimit);\n}\n\nfunction countOccurrences(haystack: string, needle: string): number {\n if (needle.length === 0) return 0;\n let count = 0;\n let idx = 0;\n for (;;) {\n const next = haystack.indexOf(needle, idx);\n if (next === -1) return count;\n count += 1;\n idx = next + needle.length;\n }\n}\n\nfunction escapeXml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n"],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ import { MemoryToolDeps } from "./types.js";
2
+ import { Tool } from "@graphorin/core";
3
+ import { z } from "zod";
4
+
5
+ //#region src/tools/block-tools.d.ts
6
+ declare const blockAppendInputSchema: z.ZodObject<{
7
+ label: z.ZodString;
8
+ content: z.ZodString;
9
+ }, "strip", z.ZodTypeAny, {
10
+ label: string;
11
+ content: string;
12
+ }, {
13
+ label: string;
14
+ content: string;
15
+ }>;
16
+ declare const blockAppendOutputSchema: z.ZodObject<{
17
+ label: z.ZodString;
18
+ length: z.ZodNumber;
19
+ }, "strip", z.ZodTypeAny, {
20
+ length: number;
21
+ label: string;
22
+ }, {
23
+ length: number;
24
+ label: string;
25
+ }>;
26
+ type BlockAppendInput = z.infer<typeof blockAppendInputSchema>;
27
+ type BlockAppendOutput = z.infer<typeof blockAppendOutputSchema>;
28
+ declare const blockReplaceInputSchema: z.ZodObject<{
29
+ label: z.ZodString;
30
+ oldUnique: z.ZodString;
31
+ newText: z.ZodString;
32
+ }, "strip", z.ZodTypeAny, {
33
+ label: string;
34
+ oldUnique: string;
35
+ newText: string;
36
+ }, {
37
+ label: string;
38
+ oldUnique: string;
39
+ newText: string;
40
+ }>;
41
+ declare const blockReplaceOutputSchema: z.ZodObject<{
42
+ label: z.ZodString;
43
+ length: z.ZodNumber;
44
+ }, "strip", z.ZodTypeAny, {
45
+ length: number;
46
+ label: string;
47
+ }, {
48
+ length: number;
49
+ label: string;
50
+ }>;
51
+ type BlockReplaceInput = z.infer<typeof blockReplaceInputSchema>;
52
+ type BlockReplaceOutput = z.infer<typeof blockReplaceOutputSchema>;
53
+ declare const blockRethinkInputSchema: z.ZodObject<{
54
+ label: z.ZodString;
55
+ newValue: z.ZodString;
56
+ }, "strip", z.ZodTypeAny, {
57
+ label: string;
58
+ newValue: string;
59
+ }, {
60
+ label: string;
61
+ newValue: string;
62
+ }>;
63
+ declare const blockRethinkOutputSchema: z.ZodObject<{
64
+ label: z.ZodString;
65
+ length: z.ZodNumber;
66
+ }, "strip", z.ZodTypeAny, {
67
+ length: number;
68
+ label: string;
69
+ }, {
70
+ length: number;
71
+ label: string;
72
+ }>;
73
+ type BlockRethinkInput = z.infer<typeof blockRethinkInputSchema>;
74
+ type BlockRethinkOutput = z.infer<typeof blockRethinkOutputSchema>;
75
+ /**
76
+ * `block_append` — append text (with a newline separator) to a working
77
+ * memory block.
78
+ *
79
+ * @stable
80
+ */
81
+ declare function createBlockAppendTool(deps: MemoryToolDeps): Tool<BlockAppendInput, BlockAppendOutput>;
82
+ /**
83
+ * `block_replace` — replace a unique substring inside a working
84
+ * memory block. Throws when the substring is missing or appears more
85
+ * than once.
86
+ *
87
+ * @stable
88
+ */
89
+ declare function createBlockReplaceTool(deps: MemoryToolDeps): Tool<BlockReplaceInput, BlockReplaceOutput>;
90
+ /**
91
+ * `block_rethink` — rewrite a working memory block from scratch.
92
+ *
93
+ * @stable
94
+ */
95
+ declare function createBlockRethinkTool(deps: MemoryToolDeps): Tool<BlockRethinkInput, BlockRethinkOutput>;
96
+ //#endregion
97
+ export { createBlockAppendTool, createBlockReplaceTool, createBlockRethinkTool };
98
+ //# sourceMappingURL=block-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-tools.d.ts","names":[],"sources":["../../src/tools/block-tools.ts"],"sourcesContent":[],"mappings":";;;;;cAKM,wBAAsB,CAAA,CAAA;;EAAtB,OAAA,aAAA;;;;CAAsB,EAAA;EAAA,KAAA,EAAA,MAAA;EAItB,OAAA,EAAA,MAAA;;cAAA,yBAAuB,CAAA,CAAA;;EAAA,MAAA,aAAA;CAAA,EAAA,OAAA,cAAA,EAAA;EAKxB,MAAA,EAAA,MAAA;EACA,KAAA,EAAA,MAAA;AAA2B,CAAA,EAAA;;;;KAD3B,gBAAA,GAAmB,CAAA,CAAE,aAAa;KAClC,iBAAA,GAAoB,CAAA,CAAE,KAEE,CAAA,OAFW,uBAEX,CAAA;cAAvB,uBAAuB,EAAA,CAAA,CAAA,SAAA,CAAA;EAKvB,KAAA,aAAA;;;;EAAwB,KAAA,EAAA,MAAA;EAAA,SAAA,EAAA,MAAA;EAKzB,OAAA,EAAA,MAAA;AAA2B,CAAA,EAAA;EAG1B,KAAA,EAAA,MAAA;;;;cARA,wBAQuB,EARC,CAAA,CAAA,SAQD,CAAA;EAAA,KAAA,aAAA;EAIvB,MAAA,aAAA;;;;CAAwB,EAAA;EAAA,MAAA,EAAA,MAAA;EAKzB,KAAA,EAAA,MAAA;AAA2B,CAAA,CAAA;AAShC,KArBK,iBAAA,GAAoB,CAAA,CAAE,KAqBU,CAAA,OArBG,uBAqBH,CAAA;KApBhC,kBAAA,GAAqB,CAAA,CAAE,KAqBpB,CAAA,OArBiC,wBAqBjC,CAAA;cAnBF,uBAoBE,EApBqB,CAAA,CAAA,SAoBrB,CAAA;EAAkB,KAAA,aAAA;EAAvB,QAAA,aAAA;CAAI,EAAA,OAAA,cAAA,EAAA;EA2BS,KAAA,EAAA,MAAA;EACR,QAAA,EAAA,MAAA;CACA,EAAA;EAAmB,KAAA,EAAA,MAAA;EAAxB,QAAA,EAAA,MAAA;CAAI,CAAA;AAyBP,cAtEM,wBAsEgC,EAtER,CAAA,CAAA,SAsEQ,CAAA;EAC9B,KAAA,aAAA;EACA,MAAA,aAAA;CAAmB,EAAA,OAAA,cAAA,EAAA;EAAxB,MAAA,EAAA,MAAA;EAAI,KAAA,EAAA,MAAA;;;;;KAnEF,iBAAA,GAAoB,CAAA,CAAE,aAAa;KACnC,kBAAA,GAAqB,CAAA,CAAE,aAAa;;;;;;;iBAQzB,qBAAA,OACR,iBACL,KAAK,kBAAkB;;;;;;;;iBA2BV,sBAAA,OACR,iBACL,KAAK,mBAAmB;;;;;;iBAyBX,sBAAA,OACR,iBACL,KAAK,mBAAmB"}
@@ -0,0 +1,114 @@
1
+ import { tool } from "@graphorin/tools";
2
+ import { z } from "zod";
3
+
4
+ //#region src/tools/block-tools.ts
5
+ const blockAppendInputSchema = z.object({
6
+ label: z.string().min(1).max(128),
7
+ content: z.string().min(1)
8
+ });
9
+ const blockAppendOutputSchema = z.object({
10
+ label: z.string(),
11
+ length: z.number()
12
+ });
13
+ const blockReplaceInputSchema = z.object({
14
+ label: z.string().min(1).max(128),
15
+ oldUnique: z.string().min(1),
16
+ newText: z.string()
17
+ });
18
+ const blockReplaceOutputSchema = z.object({
19
+ label: z.string(),
20
+ length: z.number()
21
+ });
22
+ const blockRethinkInputSchema = z.object({
23
+ label: z.string().min(1).max(128),
24
+ newValue: z.string()
25
+ });
26
+ const blockRethinkOutputSchema = z.object({
27
+ label: z.string(),
28
+ length: z.number()
29
+ });
30
+ /**
31
+ * `block_append` — append text (with a newline separator) to a working
32
+ * memory block.
33
+ *
34
+ * @stable
35
+ */
36
+ function createBlockAppendTool(deps) {
37
+ return tool({
38
+ name: "block_append",
39
+ description: "Append text to a working memory block. The block is identified by its label (registered via memory.working.define(...)). Use this when accumulating notes, observations, or reasoning steps that should persist across turns.",
40
+ inputSchema: blockAppendInputSchema,
41
+ outputSchema: blockAppendOutputSchema,
42
+ sideEffectClass: "side-effecting",
43
+ sandboxPolicy: "none",
44
+ sensitivity: "internal",
45
+ memoryGuardTier: "memory-aware",
46
+ tags: ["memory", "working"],
47
+ async execute(input, ctx) {
48
+ const scope = await deps.resolveScope(ctx);
49
+ const block = await deps.working.append(scope, input.label, input.content);
50
+ return {
51
+ label: block.label,
52
+ length: block.value.length
53
+ };
54
+ }
55
+ });
56
+ }
57
+ /**
58
+ * `block_replace` — replace a unique substring inside a working
59
+ * memory block. Throws when the substring is missing or appears more
60
+ * than once.
61
+ *
62
+ * @stable
63
+ */
64
+ function createBlockReplaceTool(deps) {
65
+ return tool({
66
+ name: "block_replace",
67
+ description: "Replace a UNIQUE substring inside a working memory block. The substring must appear exactly once; the call fails fast if missing or non-unique. Use block_rethink for full rewrites.",
68
+ inputSchema: blockReplaceInputSchema,
69
+ outputSchema: blockReplaceOutputSchema,
70
+ sideEffectClass: "side-effecting",
71
+ sandboxPolicy: "none",
72
+ sensitivity: "internal",
73
+ memoryGuardTier: "memory-aware",
74
+ tags: ["memory", "working"],
75
+ async execute(input, ctx) {
76
+ const scope = await deps.resolveScope(ctx);
77
+ const block = await deps.working.replace(scope, input.label, input.oldUnique, input.newText);
78
+ return {
79
+ label: block.label,
80
+ length: block.value.length
81
+ };
82
+ }
83
+ });
84
+ }
85
+ /**
86
+ * `block_rethink` — rewrite a working memory block from scratch.
87
+ *
88
+ * @stable
89
+ */
90
+ function createBlockRethinkTool(deps) {
91
+ return tool({
92
+ name: "block_rethink",
93
+ description: "Replace a working memory block's value entirely. Use this when restructuring or summarising the block's contents. For surgical edits, prefer block_replace.",
94
+ inputSchema: blockRethinkInputSchema,
95
+ outputSchema: blockRethinkOutputSchema,
96
+ sideEffectClass: "side-effecting",
97
+ sandboxPolicy: "none",
98
+ sensitivity: "internal",
99
+ memoryGuardTier: "memory-aware",
100
+ tags: ["memory", "working"],
101
+ async execute(input, ctx) {
102
+ const scope = await deps.resolveScope(ctx);
103
+ const block = await deps.working.rethink(scope, input.label, () => input.newValue);
104
+ return {
105
+ label: block.label,
106
+ length: block.value.length
107
+ };
108
+ }
109
+ });
110
+ }
111
+
112
+ //#endregion
113
+ export { createBlockAppendTool, createBlockReplaceTool, createBlockRethinkTool };
114
+ //# sourceMappingURL=block-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-tools.js","names":[],"sources":["../../src/tools/block-tools.ts"],"sourcesContent":["import type { Tool } from '@graphorin/core';\nimport { tool } from '@graphorin/tools';\nimport { z } from 'zod';\nimport type { MemoryToolDeps } from './types.js';\n\nconst blockAppendInputSchema = z.object({\n label: z.string().min(1).max(128),\n content: z.string().min(1),\n});\nconst blockAppendOutputSchema = z.object({\n label: z.string(),\n length: z.number(),\n});\n\ntype BlockAppendInput = z.infer<typeof blockAppendInputSchema>;\ntype BlockAppendOutput = z.infer<typeof blockAppendOutputSchema>;\n\nconst blockReplaceInputSchema = z.object({\n label: z.string().min(1).max(128),\n oldUnique: z.string().min(1),\n newText: z.string(),\n});\nconst blockReplaceOutputSchema = z.object({\n label: z.string(),\n length: z.number(),\n});\n\ntype BlockReplaceInput = z.infer<typeof blockReplaceInputSchema>;\ntype BlockReplaceOutput = z.infer<typeof blockReplaceOutputSchema>;\n\nconst blockRethinkInputSchema = z.object({\n label: z.string().min(1).max(128),\n newValue: z.string(),\n});\nconst blockRethinkOutputSchema = z.object({\n label: z.string(),\n length: z.number(),\n});\n\ntype BlockRethinkInput = z.infer<typeof blockRethinkInputSchema>;\ntype BlockRethinkOutput = z.infer<typeof blockRethinkOutputSchema>;\n\n/**\n * `block_append` — append text (with a newline separator) to a working\n * memory block.\n *\n * @stable\n */\nexport function createBlockAppendTool(\n deps: MemoryToolDeps,\n): Tool<BlockAppendInput, BlockAppendOutput> {\n return tool<BlockAppendInput, BlockAppendOutput>({\n name: 'block_append',\n description:\n 'Append text to a working memory block. The block is identified by its label (registered via memory.working.define(...)). Use this when accumulating notes, observations, or reasoning steps that should persist across turns.',\n inputSchema: blockAppendInputSchema,\n outputSchema: blockAppendOutputSchema,\n sideEffectClass: 'side-effecting',\n sandboxPolicy: 'none',\n sensitivity: 'internal',\n memoryGuardTier: 'memory-aware',\n tags: ['memory', 'working'],\n async execute(input, ctx) {\n const scope = await deps.resolveScope(ctx);\n const block = await deps.working.append(scope, input.label, input.content);\n return { label: block.label, length: block.value.length };\n },\n });\n}\n\n/**\n * `block_replace` — replace a unique substring inside a working\n * memory block. Throws when the substring is missing or appears more\n * than once.\n *\n * @stable\n */\nexport function createBlockReplaceTool(\n deps: MemoryToolDeps,\n): Tool<BlockReplaceInput, BlockReplaceOutput> {\n return tool<BlockReplaceInput, BlockReplaceOutput>({\n name: 'block_replace',\n description:\n 'Replace a UNIQUE substring inside a working memory block. The substring must appear exactly once; the call fails fast if missing or non-unique. Use block_rethink for full rewrites.',\n inputSchema: blockReplaceInputSchema,\n outputSchema: blockReplaceOutputSchema,\n sideEffectClass: 'side-effecting',\n sandboxPolicy: 'none',\n sensitivity: 'internal',\n memoryGuardTier: 'memory-aware',\n tags: ['memory', 'working'],\n async execute(input, ctx) {\n const scope = await deps.resolveScope(ctx);\n const block = await deps.working.replace(scope, input.label, input.oldUnique, input.newText);\n return { label: block.label, length: block.value.length };\n },\n });\n}\n\n/**\n * `block_rethink` — rewrite a working memory block from scratch.\n *\n * @stable\n */\nexport function createBlockRethinkTool(\n deps: MemoryToolDeps,\n): Tool<BlockRethinkInput, BlockRethinkOutput> {\n return tool<BlockRethinkInput, BlockRethinkOutput>({\n name: 'block_rethink',\n description:\n \"Replace a working memory block's value entirely. Use this when restructuring or summarising the block's contents. For surgical edits, prefer block_replace.\",\n inputSchema: blockRethinkInputSchema,\n outputSchema: blockRethinkOutputSchema,\n sideEffectClass: 'side-effecting',\n sandboxPolicy: 'none',\n sensitivity: 'internal',\n memoryGuardTier: 'memory-aware',\n tags: ['memory', 'working'],\n async execute(input, ctx) {\n const scope = await deps.resolveScope(ctx);\n const block = await deps.working.rethink(scope, input.label, () => input.newValue);\n return { label: block.label, length: block.value.length };\n },\n });\n}\n"],"mappings":";;;;AAKA,MAAM,yBAAyB,EAAE,OAAO;CACtC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI;CACjC,SAAS,EAAE,QAAQ,CAAC,IAAI,EAAE;CAC3B,CAAC;AACF,MAAM,0BAA0B,EAAE,OAAO;CACvC,OAAO,EAAE,QAAQ;CACjB,QAAQ,EAAE,QAAQ;CACnB,CAAC;AAKF,MAAM,0BAA0B,EAAE,OAAO;CACvC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI;CACjC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE;CAC5B,SAAS,EAAE,QAAQ;CACpB,CAAC;AACF,MAAM,2BAA2B,EAAE,OAAO;CACxC,OAAO,EAAE,QAAQ;CACjB,QAAQ,EAAE,QAAQ;CACnB,CAAC;AAKF,MAAM,0BAA0B,EAAE,OAAO;CACvC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI;CACjC,UAAU,EAAE,QAAQ;CACrB,CAAC;AACF,MAAM,2BAA2B,EAAE,OAAO;CACxC,OAAO,EAAE,QAAQ;CACjB,QAAQ,EAAE,QAAQ;CACnB,CAAC;;;;;;;AAWF,SAAgB,sBACd,MAC2C;AAC3C,QAAO,KAA0C;EAC/C,MAAM;EACN,aACE;EACF,aAAa;EACb,cAAc;EACd,iBAAiB;EACjB,eAAe;EACf,aAAa;EACb,iBAAiB;EACjB,MAAM,CAAC,UAAU,UAAU;EAC3B,MAAM,QAAQ,OAAO,KAAK;GACxB,MAAM,QAAQ,MAAM,KAAK,aAAa,IAAI;GAC1C,MAAM,QAAQ,MAAM,KAAK,QAAQ,OAAO,OAAO,MAAM,OAAO,MAAM,QAAQ;AAC1E,UAAO;IAAE,OAAO,MAAM;IAAO,QAAQ,MAAM,MAAM;IAAQ;;EAE5D,CAAC;;;;;;;;;AAUJ,SAAgB,uBACd,MAC6C;AAC7C,QAAO,KAA4C;EACjD,MAAM;EACN,aACE;EACF,aAAa;EACb,cAAc;EACd,iBAAiB;EACjB,eAAe;EACf,aAAa;EACb,iBAAiB;EACjB,MAAM,CAAC,UAAU,UAAU;EAC3B,MAAM,QAAQ,OAAO,KAAK;GACxB,MAAM,QAAQ,MAAM,KAAK,aAAa,IAAI;GAC1C,MAAM,QAAQ,MAAM,KAAK,QAAQ,QAAQ,OAAO,MAAM,OAAO,MAAM,WAAW,MAAM,QAAQ;AAC5F,UAAO;IAAE,OAAO,MAAM;IAAO,QAAQ,MAAM,MAAM;IAAQ;;EAE5D,CAAC;;;;;;;AAQJ,SAAgB,uBACd,MAC6C;AAC7C,QAAO,KAA4C;EACjD,MAAM;EACN,aACE;EACF,aAAa;EACb,cAAc;EACd,iBAAiB;EACjB,eAAe;EACf,aAAa;EACb,iBAAiB;EACjB,MAAM,CAAC,UAAU,UAAU;EAC3B,MAAM,QAAQ,OAAO,KAAK;GACxB,MAAM,QAAQ,MAAM,KAAK,aAAa,IAAI;GAC1C,MAAM,QAAQ,MAAM,KAAK,QAAQ,QAAQ,OAAO,MAAM,aAAa,MAAM,SAAS;AAClF,UAAO;IAAE,OAAO,MAAM;IAAO,QAAQ,MAAM,MAAM;IAAQ;;EAE5D,CAAC"}