@autonome-research/thread-phase 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/agent/index.d.ts +28 -0
  4. package/dist/agent/index.d.ts.map +1 -0
  5. package/dist/agent/index.js +28 -0
  6. package/dist/agent/index.js.map +1 -0
  7. package/dist/agent/openai-adapter.d.ts +15 -0
  8. package/dist/agent/openai-adapter.d.ts.map +1 -0
  9. package/dist/agent/openai-adapter.js +57 -0
  10. package/dist/agent/openai-adapter.js.map +1 -0
  11. package/dist/agent/parse-json.d.ts +12 -0
  12. package/dist/agent/parse-json.d.ts.map +1 -0
  13. package/dist/agent/parse-json.js +31 -0
  14. package/dist/agent/parse-json.js.map +1 -0
  15. package/dist/agent/retry.d.ts +15 -0
  16. package/dist/agent/retry.d.ts.map +1 -0
  17. package/dist/agent/retry.js +35 -0
  18. package/dist/agent/retry.js.map +1 -0
  19. package/dist/agent/runner.d.ts +25 -0
  20. package/dist/agent/runner.d.ts.map +1 -0
  21. package/dist/agent/runner.js +270 -0
  22. package/dist/agent/runner.js.map +1 -0
  23. package/dist/agent/stream-consumer.d.ts +57 -0
  24. package/dist/agent/stream-consumer.d.ts.map +1 -0
  25. package/dist/agent/stream-consumer.js +126 -0
  26. package/dist/agent/stream-consumer.js.map +1 -0
  27. package/dist/agent/types.d.ts +135 -0
  28. package/dist/agent/types.d.ts.map +1 -0
  29. package/dist/agent/types.js +9 -0
  30. package/dist/agent/types.js.map +1 -0
  31. package/dist/agent-runner.d.ts +10 -0
  32. package/dist/agent-runner.d.ts.map +1 -0
  33. package/dist/agent-runner.js +10 -0
  34. package/dist/agent-runner.js.map +1 -0
  35. package/dist/agents/capability.d.ts +36 -0
  36. package/dist/agents/capability.d.ts.map +1 -0
  37. package/dist/agents/capability.js +51 -0
  38. package/dist/agents/capability.js.map +1 -0
  39. package/dist/agents/event-bus.d.ts +20 -0
  40. package/dist/agents/event-bus.d.ts.map +1 -0
  41. package/dist/agents/event-bus.js +40 -0
  42. package/dist/agents/event-bus.js.map +1 -0
  43. package/dist/agents/index.d.ts +23 -0
  44. package/dist/agents/index.d.ts.map +1 -0
  45. package/dist/agents/index.js +33 -0
  46. package/dist/agents/index.js.map +1 -0
  47. package/dist/agents/inference-adapter.d.ts +52 -0
  48. package/dist/agents/inference-adapter.d.ts.map +1 -0
  49. package/dist/agents/inference-adapter.js +209 -0
  50. package/dist/agents/inference-adapter.js.map +1 -0
  51. package/dist/agents/job-store-bridge.d.ts +44 -0
  52. package/dist/agents/job-store-bridge.d.ts.map +1 -0
  53. package/dist/agents/job-store-bridge.js +58 -0
  54. package/dist/agents/job-store-bridge.js.map +1 -0
  55. package/dist/agents/memory.d.ts +40 -0
  56. package/dist/agents/memory.d.ts.map +1 -0
  57. package/dist/agents/memory.js +14 -0
  58. package/dist/agents/memory.js.map +1 -0
  59. package/dist/agents/protocol.d.ts +302 -0
  60. package/dist/agents/protocol.d.ts.map +1 -0
  61. package/dist/agents/protocol.js +36 -0
  62. package/dist/agents/protocol.js.map +1 -0
  63. package/dist/agents/run-helpers.d.ts +70 -0
  64. package/dist/agents/run-helpers.d.ts.map +1 -0
  65. package/dist/agents/run-helpers.js +131 -0
  66. package/dist/agents/run-helpers.js.map +1 -0
  67. package/dist/agents/serialize-error.d.ts +18 -0
  68. package/dist/agents/serialize-error.d.ts.map +1 -0
  69. package/dist/agents/serialize-error.js +27 -0
  70. package/dist/agents/serialize-error.js.map +1 -0
  71. package/dist/agents/structured-output.d.ts +90 -0
  72. package/dist/agents/structured-output.d.ts.map +1 -0
  73. package/dist/agents/structured-output.js +101 -0
  74. package/dist/agents/structured-output.js.map +1 -0
  75. package/dist/agents/test-utils/conformance.d.ts +59 -0
  76. package/dist/agents/test-utils/conformance.d.ts.map +1 -0
  77. package/dist/agents/test-utils/conformance.js +207 -0
  78. package/dist/agents/test-utils/conformance.js.map +1 -0
  79. package/dist/agents/test-utils/index.d.ts +12 -0
  80. package/dist/agents/test-utils/index.d.ts.map +1 -0
  81. package/dist/agents/test-utils/index.js +12 -0
  82. package/dist/agents/test-utils/index.js.map +1 -0
  83. package/dist/agents/test-utils/mock-agent.d.ts +66 -0
  84. package/dist/agents/test-utils/mock-agent.d.ts.map +1 -0
  85. package/dist/agents/test-utils/mock-agent.js +244 -0
  86. package/dist/agents/test-utils/mock-agent.js.map +1 -0
  87. package/dist/agents/thread.d.ts +57 -0
  88. package/dist/agents/thread.d.ts.map +1 -0
  89. package/dist/agents/thread.js +128 -0
  90. package/dist/agents/thread.js.map +1 -0
  91. package/dist/agents/turn-accumulator.d.ts +94 -0
  92. package/dist/agents/turn-accumulator.d.ts.map +1 -0
  93. package/dist/agents/turn-accumulator.js +150 -0
  94. package/dist/agents/turn-accumulator.js.map +1 -0
  95. package/dist/agents/with-memory.d.ts +55 -0
  96. package/dist/agents/with-memory.d.ts.map +1 -0
  97. package/dist/agents/with-memory.js +155 -0
  98. package/dist/agents/with-memory.js.map +1 -0
  99. package/dist/agents/with-thread.d.ts +45 -0
  100. package/dist/agents/with-thread.d.ts.map +1 -0
  101. package/dist/agents/with-thread.js +70 -0
  102. package/dist/agents/with-thread.js.map +1 -0
  103. package/dist/cache.d.ts +47 -0
  104. package/dist/cache.d.ts.map +1 -0
  105. package/dist/cache.js +81 -0
  106. package/dist/cache.js.map +1 -0
  107. package/dist/context/compressor.d.ts +36 -0
  108. package/dist/context/compressor.d.ts.map +1 -0
  109. package/dist/context/compressor.js +158 -0
  110. package/dist/context/compressor.js.map +1 -0
  111. package/dist/context/index.d.ts +4 -0
  112. package/dist/context/index.d.ts.map +1 -0
  113. package/dist/context/index.js +4 -0
  114. package/dist/context/index.js.map +1 -0
  115. package/dist/context/result-capper.d.ts +32 -0
  116. package/dist/context/result-capper.d.ts.map +1 -0
  117. package/dist/context/result-capper.js +50 -0
  118. package/dist/context/result-capper.js.map +1 -0
  119. package/dist/context/token-budget.d.ts +81 -0
  120. package/dist/context/token-budget.d.ts.map +1 -0
  121. package/dist/context/token-budget.js +99 -0
  122. package/dist/context/token-budget.js.map +1 -0
  123. package/dist/helpers/caller.d.ts +18 -0
  124. package/dist/helpers/caller.d.ts.map +1 -0
  125. package/dist/helpers/caller.js +40 -0
  126. package/dist/helpers/caller.js.map +1 -0
  127. package/dist/helpers/hook.d.ts +73 -0
  128. package/dist/helpers/hook.d.ts.map +1 -0
  129. package/dist/helpers/hook.js +244 -0
  130. package/dist/helpers/hook.js.map +1 -0
  131. package/dist/helpers/index.d.ts +12 -0
  132. package/dist/helpers/index.d.ts.map +1 -0
  133. package/dist/helpers/index.js +11 -0
  134. package/dist/helpers/index.js.map +1 -0
  135. package/dist/helpers/one-shot.d.ts +27 -0
  136. package/dist/helpers/one-shot.d.ts.map +1 -0
  137. package/dist/helpers/one-shot.js +43 -0
  138. package/dist/helpers/one-shot.js.map +1 -0
  139. package/dist/helpers/schedule.d.ts +59 -0
  140. package/dist/helpers/schedule.d.ts.map +1 -0
  141. package/dist/helpers/schedule.js +118 -0
  142. package/dist/helpers/schedule.js.map +1 -0
  143. package/dist/helpers/types.d.ts +34 -0
  144. package/dist/helpers/types.d.ts.map +1 -0
  145. package/dist/helpers/types.js +11 -0
  146. package/dist/helpers/types.js.map +1 -0
  147. package/dist/index.d.ts +26 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +37 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/inference.d.ts +27 -0
  152. package/dist/inference.d.ts.map +1 -0
  153. package/dist/inference.js +34 -0
  154. package/dist/inference.js.map +1 -0
  155. package/dist/messages.d.ts +64 -0
  156. package/dist/messages.d.ts.map +1 -0
  157. package/dist/messages.js +17 -0
  158. package/dist/messages.js.map +1 -0
  159. package/dist/orchestrator.d.ts +56 -0
  160. package/dist/orchestrator.d.ts.map +1 -0
  161. package/dist/orchestrator.js +62 -0
  162. package/dist/orchestrator.js.map +1 -0
  163. package/dist/patterns/bounded-fanout-of.d.ts +61 -0
  164. package/dist/patterns/bounded-fanout-of.d.ts.map +1 -0
  165. package/dist/patterns/bounded-fanout-of.js +142 -0
  166. package/dist/patterns/bounded-fanout-of.js.map +1 -0
  167. package/dist/patterns/bounded-fanout.d.ts +111 -0
  168. package/dist/patterns/bounded-fanout.d.ts.map +1 -0
  169. package/dist/patterns/bounded-fanout.js +151 -0
  170. package/dist/patterns/bounded-fanout.js.map +1 -0
  171. package/dist/patterns/index.d.ts +14 -0
  172. package/dist/patterns/index.d.ts.map +1 -0
  173. package/dist/patterns/index.js +13 -0
  174. package/dist/patterns/index.js.map +1 -0
  175. package/dist/patterns/intent-gate.d.ts +27 -0
  176. package/dist/patterns/intent-gate.d.ts.map +1 -0
  177. package/dist/patterns/intent-gate.js +32 -0
  178. package/dist/patterns/intent-gate.js.map +1 -0
  179. package/dist/patterns/match.d.ts +30 -0
  180. package/dist/patterns/match.d.ts.map +1 -0
  181. package/dist/patterns/match.js +58 -0
  182. package/dist/patterns/match.js.map +1 -0
  183. package/dist/patterns/parallel-fanout.d.ts +28 -0
  184. package/dist/patterns/parallel-fanout.d.ts.map +1 -0
  185. package/dist/patterns/parallel-fanout.js +24 -0
  186. package/dist/patterns/parallel-fanout.js.map +1 -0
  187. package/dist/patterns/parallel-phases.d.ts +27 -0
  188. package/dist/patterns/parallel-phases.d.ts.map +1 -0
  189. package/dist/patterns/parallel-phases.js +77 -0
  190. package/dist/patterns/parallel-phases.js.map +1 -0
  191. package/dist/patterns/preflight-confidence.d.ts +20 -0
  192. package/dist/patterns/preflight-confidence.d.ts.map +1 -0
  193. package/dist/patterns/preflight-confidence.js +38 -0
  194. package/dist/patterns/preflight-confidence.js.map +1 -0
  195. package/dist/patterns/spot-check.d.ts +19 -0
  196. package/dist/patterns/spot-check.d.ts.map +1 -0
  197. package/dist/patterns/spot-check.js +33 -0
  198. package/dist/patterns/spot-check.js.map +1 -0
  199. package/dist/patterns/sub-pipeline.d.ts +84 -0
  200. package/dist/patterns/sub-pipeline.d.ts.map +1 -0
  201. package/dist/patterns/sub-pipeline.js +90 -0
  202. package/dist/patterns/sub-pipeline.js.map +1 -0
  203. package/dist/patterns/synthesize-with-followup.d.ts +35 -0
  204. package/dist/patterns/synthesize-with-followup.d.ts.map +1 -0
  205. package/dist/patterns/synthesize-with-followup.js +45 -0
  206. package/dist/patterns/synthesize-with-followup.js.map +1 -0
  207. package/dist/patterns/while-condition.d.ts +31 -0
  208. package/dist/patterns/while-condition.d.ts.map +1 -0
  209. package/dist/patterns/while-condition.js +59 -0
  210. package/dist/patterns/while-condition.js.map +1 -0
  211. package/dist/patterns/with-retry.d.ts +37 -0
  212. package/dist/patterns/with-retry.d.ts.map +1 -0
  213. package/dist/patterns/with-retry.js +73 -0
  214. package/dist/patterns/with-retry.js.map +1 -0
  215. package/dist/phase.d.ts +78 -0
  216. package/dist/phase.d.ts.map +1 -0
  217. package/dist/phase.js +36 -0
  218. package/dist/phase.js.map +1 -0
  219. package/dist/session/index.d.ts +5 -0
  220. package/dist/session/index.d.ts.map +1 -0
  221. package/dist/session/index.js +4 -0
  222. package/dist/session/index.js.map +1 -0
  223. package/dist/session/job-runner.d.ts +67 -0
  224. package/dist/session/job-runner.d.ts.map +1 -0
  225. package/dist/session/job-runner.js +131 -0
  226. package/dist/session/job-runner.js.map +1 -0
  227. package/dist/session/job-store.d.ts +98 -0
  228. package/dist/session/job-store.d.ts.map +1 -0
  229. package/dist/session/job-store.js +37 -0
  230. package/dist/session/job-store.js.map +1 -0
  231. package/dist/session/sqlite-job-store.d.ts +40 -0
  232. package/dist/session/sqlite-job-store.d.ts.map +1 -0
  233. package/dist/session/sqlite-job-store.js +200 -0
  234. package/dist/session/sqlite-job-store.js.map +1 -0
  235. package/dist/session/sse.d.ts +60 -0
  236. package/dist/session/sse.d.ts.map +1 -0
  237. package/dist/session/sse.js +97 -0
  238. package/dist/session/sse.js.map +1 -0
  239. package/dist/tools/index.d.ts +2 -0
  240. package/dist/tools/index.d.ts.map +1 -0
  241. package/dist/tools/index.js +2 -0
  242. package/dist/tools/index.js.map +1 -0
  243. package/dist/tools/registry.d.ts +44 -0
  244. package/dist/tools/registry.d.ts.map +1 -0
  245. package/dist/tools/registry.js +74 -0
  246. package/dist/tools/registry.js.map +1 -0
  247. package/dist/triggers/index.d.ts +15 -0
  248. package/dist/triggers/index.d.ts.map +1 -0
  249. package/dist/triggers/index.js +14 -0
  250. package/dist/triggers/index.js.map +1 -0
  251. package/dist/triggers/run-trigger.d.ts +86 -0
  252. package/dist/triggers/run-trigger.d.ts.map +1 -0
  253. package/dist/triggers/run-trigger.js +146 -0
  254. package/dist/triggers/run-trigger.js.map +1 -0
  255. package/dist/triggers/timer-trigger.d.ts +46 -0
  256. package/dist/triggers/timer-trigger.d.ts.map +1 -0
  257. package/dist/triggers/timer-trigger.js +74 -0
  258. package/dist/triggers/timer-trigger.js.map +1 -0
  259. package/dist/triggers/types.d.ts +61 -0
  260. package/dist/triggers/types.d.ts.map +1 -0
  261. package/dist/triggers/types.js +23 -0
  262. package/dist/triggers/types.js.map +1 -0
  263. package/package.json +64 -0
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Helper for translating primitive adapter-level callbacks into canonical
3
+ * `AgentEvent`s with correct turn-boundary semantics.
4
+ *
5
+ * The non-obvious problem this solves: some underlying runtimes (the in-tree
6
+ * OpenAI runner is one) emit their end-of-turn marker BEFORE the tool calls
7
+ * of that turn — the model decodes content, the runtime fires `round_complete`,
8
+ * then the tool calls follow as separate events. In canonical semantics, a
9
+ * `turn_end` belongs AFTER its turn's tool calls so `toolCallCount` reflects
10
+ * what actually happened in that turn.
11
+ *
12
+ * The accumulator handles this by deferring `turn_end` emission. Call
13
+ * `markTurnEnd()` when the underlying runtime says the turn ended; the event
14
+ * is held until the NEXT text delta (= new turn starts) or `close()` (= run
15
+ * ends). Tool calls in between count against the pending turn.
16
+ *
17
+ * Adapters whose runtime emits turn boundaries naturally (after all tool
18
+ * calls of the same turn) can still use this helper — `markTurnEnd()` +
19
+ * `close()` with no intervening events flushes immediately.
20
+ *
21
+ * Also handles the boilerplate of stamping `source` and `traceId` on every
22
+ * canonical event the adapter emits, which every adapter has to do.
23
+ *
24
+ * @internal
25
+ */
26
+ /** @internal */
27
+ export class TurnAccumulator {
28
+ emit;
29
+ source;
30
+ traceId;
31
+ turnText = '';
32
+ currentTurnToolCalls = 0;
33
+ pending = null;
34
+ constructor(emit, source, traceId) {
35
+ this.emit = emit;
36
+ this.source = source;
37
+ this.traceId = traceId;
38
+ }
39
+ /**
40
+ * Emit a text delta. Flushes any pending `turn_end` first — a text delta
41
+ * after `markTurnEnd()` is the canonical signal that a new turn has begun.
42
+ */
43
+ text(delta) {
44
+ if (this.pending)
45
+ this.flush();
46
+ this.turnText += delta;
47
+ this.emit({ type: 'text', source: this.source, traceId: this.traceId, delta });
48
+ }
49
+ /**
50
+ * Emit a thinking (reasoning) delta. Does NOT flush a pending turn —
51
+ * reasoning is intra-turn content, not a turn boundary signal.
52
+ */
53
+ thinking(delta) {
54
+ this.emit({ type: 'thinking', source: this.source, traceId: this.traceId, delta });
55
+ }
56
+ /**
57
+ * Emit a tool call. Counts toward the current turn regardless of which
58
+ * turn-end style the adapter uses — deferred (`markTurnEnd`) or
59
+ * immediate (`endTurn`).
60
+ */
61
+ toolCall(id, name, input) {
62
+ this.currentTurnToolCalls += 1;
63
+ this.emit({ type: 'tool_call', source: this.source, traceId: this.traceId, id, name, input });
64
+ }
65
+ /** Emit a tool result. Does not affect pending-turn state. */
66
+ toolResult(id, name, output, isError) {
67
+ this.emit({
68
+ type: 'tool_result',
69
+ source: this.source,
70
+ traceId: this.traceId,
71
+ id,
72
+ name,
73
+ output,
74
+ isError,
75
+ });
76
+ }
77
+ /**
78
+ * Emit a native (adapter-specific) event verbatim. Stamps `source` and
79
+ * `traceId` so adapters don't have to repeat the boilerplate. Does not
80
+ * affect pending-turn state.
81
+ */
82
+ native(kind, payload) {
83
+ this.emit({ type: 'native', source: this.source, traceId: this.traceId, kind, payload });
84
+ }
85
+ /**
86
+ * Mark the end of a turn — deferred-emission variant. Use when the
87
+ * underlying runtime emits its end-of-turn marker BEFORE the tool calls
88
+ * that belong to that turn (the in-tree OpenAI runner is one such case).
89
+ * The `turn_end` event is NOT emitted yet; it stays pending until either
90
+ * the next text delta (next turn starts) or `close()` (run ends). Tool
91
+ * calls that arrive between now and the flush count toward this turn.
92
+ *
93
+ * For runtimes with natural turn ordering (tool calls inside the turn,
94
+ * then turn boundary), use `endTurn()` instead.
95
+ *
96
+ * Optional `usage` is attached to the eventual `turn_end` event.
97
+ */
98
+ markTurnEnd(usage) {
99
+ this.pending = { text: this.turnText, openingToolCallCount: this.currentTurnToolCalls, usage };
100
+ this.turnText = '';
101
+ }
102
+ /**
103
+ * Emit a `turn_end` event NOW with the current turn's text and tool-call
104
+ * count, then reset the counters. Use when the underlying runtime
105
+ * already had all of this turn's tool calls before the boundary signal
106
+ * (the ACP `session/prompt` response is one such case — agent_message_chunks
107
+ * and tool_calls precede the stopReason).
108
+ *
109
+ * If a `markTurnEnd()` deferred turn is still pending, it's flushed first.
110
+ *
111
+ * Optional `usage` is attached to the emitted `turn_end` event.
112
+ */
113
+ endTurn(usage) {
114
+ if (this.pending)
115
+ this.flush();
116
+ this.emit({
117
+ type: 'turn_end',
118
+ source: this.source,
119
+ traceId: this.traceId,
120
+ assistantText: this.turnText,
121
+ usage,
122
+ toolCallCount: this.currentTurnToolCalls,
123
+ });
124
+ this.turnText = '';
125
+ this.currentTurnToolCalls = 0;
126
+ }
127
+ /**
128
+ * Flush any pending `turn_end`. Call once at run end, before emitting
129
+ * `agent_end`. Idempotent — calling twice with nothing pending is a no-op.
130
+ */
131
+ close() {
132
+ this.flush();
133
+ }
134
+ flush() {
135
+ if (!this.pending)
136
+ return;
137
+ const turnToolCalls = this.currentTurnToolCalls - this.pending.openingToolCallCount;
138
+ this.emit({
139
+ type: 'turn_end',
140
+ source: this.source,
141
+ traceId: this.traceId,
142
+ assistantText: this.pending.text,
143
+ usage: this.pending.usage,
144
+ toolCallCount: turnToolCalls,
145
+ });
146
+ this.pending = null;
147
+ this.currentTurnToolCalls = 0;
148
+ }
149
+ }
150
+ //# sourceMappingURL=turn-accumulator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-accumulator.js","sourceRoot":"","sources":["../../src/agents/turn-accumulator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Decorate an `AgentAdapter` with automatic memory recall + remember
3
+ * via a caller-supplied `MemoryProvider`.
4
+ *
5
+ * The wrapper:
6
+ *
7
+ * 1. Reads `runOptions.memoryProvider` at call time. If none is in
8
+ * scope, the wrapper is a no-op pass-through — caller can decorate
9
+ * an adapter once and decide per-call whether memory applies.
10
+ * 2. Before invoking the inner adapter, calls `provider.recall(scope, query?)`
11
+ * and splices the recalled string into the config via the
12
+ * `inject` callback. The inject signature is adapter-specific
13
+ * because each adapter shapes its prompt field differently
14
+ * (config.systemPrompt vs config.instructions vs config.prompt vs
15
+ * runnerOptions etc.).
16
+ * 3. Tees every emitted event into a capture buffer (for the later
17
+ * `remember` call) AND into the caller's `options.eventBus` if
18
+ * present. Pass-through; no events added or dropped.
19
+ * 4. After the inner run's `agent_end`, calls `provider.remember(scope, captured)`
20
+ * before resolving the wrapped run's `result`. Failures of either
21
+ * `recall` or `remember` surface as `native` events on the bus
22
+ * (`memory:recall_failed` / `memory:remember_failed`); the run
23
+ * itself never fails because of memory.
24
+ *
25
+ * @internal
26
+ */
27
+ import type { AgentAdapterMeta, MemoryScope } from './protocol.js';
28
+ /** @internal */
29
+ export interface WithMemoryOptions<TConfig> {
30
+ /** Identity scope (`userId` required; `appId` / `sessionId` optional). */
31
+ scope: MemoryScope;
32
+ /**
33
+ * Splice the recalled memory string into the inner adapter's config.
34
+ * Each adapter shapes its prompt field differently; the caller knows
35
+ * the adapter type and where the memory belongs.
36
+ */
37
+ inject: (config: TConfig, memory: string) => TConfig;
38
+ /**
39
+ * Optional: derive a query string from the config to refine recall.
40
+ * Useful when the recall backend supports semantic search (Honcho's
41
+ * `.chat()` interprets the query as the question being asked).
42
+ * Default: no query (provider gets `undefined`).
43
+ */
44
+ query?: (config: TConfig) => string | undefined;
45
+ }
46
+ /**
47
+ * Wrap an adapter so each invocation auto-recalls memory before the run
48
+ * and auto-remembers events after. Behavior is gated on the presence
49
+ * of `options.memoryProvider` at call time — no provider, no memory
50
+ * activity.
51
+ *
52
+ * @internal
53
+ */
54
+ export declare function withMemory<TConfig>(meta: AgentAdapterMeta<TConfig>, opts: WithMemoryOptions<TConfig>): AgentAdapterMeta<TConfig>;
55
+ //# sourceMappingURL=with-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-memory.d.ts","sourceRoot":"","sources":["../../src/agents/with-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EACV,gBAAgB,EAKhB,WAAW,EACZ,MAAM,eAAe,CAAC;AAGvB,gBAAgB;AAChB,MAAM,WAAW,iBAAiB,CAAC,OAAO;IACxC,0EAA0E;IAC1E,KAAK,EAAE,WAAW,CAAC;IACnB;;;;OAIG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD;;;;;OAKG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;CACjD;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAChC,IAAI,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAC/B,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAC/B,gBAAgB,CAAC,OAAO,CAAC,CAyH3B"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Decorate an `AgentAdapter` with automatic memory recall + remember
3
+ * via a caller-supplied `MemoryProvider`.
4
+ *
5
+ * The wrapper:
6
+ *
7
+ * 1. Reads `runOptions.memoryProvider` at call time. If none is in
8
+ * scope, the wrapper is a no-op pass-through — caller can decorate
9
+ * an adapter once and decide per-call whether memory applies.
10
+ * 2. Before invoking the inner adapter, calls `provider.recall(scope, query?)`
11
+ * and splices the recalled string into the config via the
12
+ * `inject` callback. The inject signature is adapter-specific
13
+ * because each adapter shapes its prompt field differently
14
+ * (config.systemPrompt vs config.instructions vs config.prompt vs
15
+ * runnerOptions etc.).
16
+ * 3. Tees every emitted event into a capture buffer (for the later
17
+ * `remember` call) AND into the caller's `options.eventBus` if
18
+ * present. Pass-through; no events added or dropped.
19
+ * 4. After the inner run's `agent_end`, calls `provider.remember(scope, captured)`
20
+ * before resolving the wrapped run's `result`. Failures of either
21
+ * `recall` or `remember` surface as `native` events on the bus
22
+ * (`memory:recall_failed` / `memory:remember_failed`); the run
23
+ * itself never fails because of memory.
24
+ *
25
+ * @internal
26
+ */
27
+ import { createEventBus } from './event-bus.js';
28
+ import { serializeError } from './serialize-error.js';
29
+ /**
30
+ * Wrap an adapter so each invocation auto-recalls memory before the run
31
+ * and auto-remembers events after. Behavior is gated on the presence
32
+ * of `options.memoryProvider` at call time — no provider, no memory
33
+ * activity.
34
+ *
35
+ * @internal
36
+ */
37
+ export function withMemory(meta, opts) {
38
+ return {
39
+ id: meta.id,
40
+ capabilities: meta.capabilities,
41
+ adapter: (config, runOptions) => {
42
+ const provider = runOptions?.memoryProvider;
43
+ if (!provider) {
44
+ // No provider in scope — transparent passthrough.
45
+ return meta.adapter(config, runOptions);
46
+ }
47
+ // Inner bus captures every event for the eventual remember() call
48
+ // AND mirrors to the caller's bus (if any). Pass-through bus, not
49
+ // a replacement.
50
+ const innerBus = createEventBus();
51
+ const captured = [];
52
+ const userBus = runOptions?.eventBus;
53
+ innerBus.on((event) => {
54
+ captured.push(event);
55
+ if (userBus) {
56
+ try {
57
+ userBus.emit(event);
58
+ }
59
+ catch {
60
+ // bus implementation is responsible for its own subscriber errors
61
+ }
62
+ }
63
+ });
64
+ // Lazy start: recall + inject must complete before the inner adapter
65
+ // is invoked. We can't await here (adapter must return synchronously)
66
+ // so the inner run resolves on first events-iteration or result-await
67
+ // via the standard memoized-promise pattern.
68
+ let innerRunPromise = null;
69
+ const innerOptions = {
70
+ ...(runOptions ?? {}),
71
+ eventBus: innerBus,
72
+ };
73
+ const getInnerRun = () => {
74
+ if (innerRunPromise)
75
+ return innerRunPromise;
76
+ innerRunPromise = (async () => {
77
+ let recalled = '';
78
+ try {
79
+ const query = opts.query?.(config);
80
+ recalled = await provider.recall(opts.scope, query);
81
+ }
82
+ catch (err) {
83
+ innerBus.emit({
84
+ type: 'native',
85
+ source: meta.id,
86
+ kind: 'memory:recall_failed',
87
+ payload: { error: serializeError(err) },
88
+ });
89
+ }
90
+ const effective = opts.inject(config, recalled);
91
+ return meta.adapter(effective, innerOptions);
92
+ })();
93
+ return innerRunPromise;
94
+ };
95
+ // Single-consumer guard on the wrapped events iterable. The inner
96
+ // run also guards its own events; the wrapper's guard catches the
97
+ // case where the wrapped run is iterated twice before inner exists.
98
+ let iteratorVended = false;
99
+ const events = {
100
+ [Symbol.asyncIterator]() {
101
+ if (iteratorVended) {
102
+ throw new Error('AgentRun.events is single-consumer; iterate it once. Use AgentEventBus (options.eventBus) for multi-subscriber fan-out.');
103
+ }
104
+ iteratorVended = true;
105
+ let innerIterator = null;
106
+ const ensureIterator = async () => {
107
+ if (innerIterator)
108
+ return innerIterator;
109
+ const run = await getInnerRun();
110
+ innerIterator = run.events[Symbol.asyncIterator]();
111
+ return innerIterator;
112
+ };
113
+ return {
114
+ async next() {
115
+ const it = await ensureIterator();
116
+ return it.next();
117
+ },
118
+ async return() {
119
+ if (innerIterator?.return) {
120
+ return innerIterator.return();
121
+ }
122
+ return { value: undefined, done: true };
123
+ },
124
+ };
125
+ },
126
+ };
127
+ const result = (async () => {
128
+ const run = await getInnerRun();
129
+ const inner = await run.result;
130
+ try {
131
+ await provider.remember(opts.scope, captured);
132
+ }
133
+ catch (err) {
134
+ innerBus.emit({
135
+ type: 'native',
136
+ source: meta.id,
137
+ kind: 'memory:remember_failed',
138
+ payload: { error: serializeError(err) },
139
+ });
140
+ }
141
+ return inner;
142
+ })();
143
+ return {
144
+ events,
145
+ result,
146
+ abort(reason) {
147
+ // Propagate abort once the inner run exists. If recall is still
148
+ // in flight, the abort takes effect right after recall resolves.
149
+ void getInnerRun().then((r) => r.abort(reason));
150
+ },
151
+ };
152
+ },
153
+ };
154
+ }
155
+ //# sourceMappingURL=with-memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-memory.js","sourceRoot":"","sources":["../../src/agents/with-memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Decorate an `AgentAdapter` with automatic `Thread` wiring:
3
+ *
4
+ * 1. Reads `thread.resumeTokens[meta.id]` and splices it into the
5
+ * inner config via the `applyResume` callback. Adapters whose
6
+ * resumption field name differs (anthropic has none, codex uses
7
+ * `previousResponseId`, ACP-based uses `resumeSessionId`, etc.)
8
+ * provide their own splice.
9
+ * 2. Tees every event into `thread.events`. The thread becomes a
10
+ * durable log of the conversation that flows between phases.
11
+ * 3. When a fresh `resumeToken` appears on `agent_start` or `agent_end`,
12
+ * writes it back to `thread.resumeTokens[meta.id]` so subsequent
13
+ * calls with the same thread auto-resume.
14
+ *
15
+ * Unlike `withMemory`, the thread is passed explicitly to the wrapper
16
+ * factory — `Thread` is a per-pipeline primitive, `MemoryProvider` is
17
+ * a cross-pipeline backend. Thread mutation happens through the same
18
+ * `appendEvent` / `setResumeToken` helpers callers would use manually.
19
+ *
20
+ * @internal
21
+ */
22
+ import type { AgentAdapterMeta, ResumeToken } from './protocol.js';
23
+ import { type Thread } from './thread.js';
24
+ /** @internal */
25
+ export interface WithThreadOptions<TConfig> {
26
+ /**
27
+ * Splice the thread's per-adapter resume token into the inner config.
28
+ * Called only when `thread.resumeTokens[meta.id]` is present. Adapters
29
+ * without resumption (anthropicAgent) omit this — the wrapper still
30
+ * mirrors events into the thread, just doesn't try to inject a resume.
31
+ */
32
+ applyResume?: (config: TConfig, resumeToken: ResumeToken) => TConfig;
33
+ }
34
+ /**
35
+ * Wrap an adapter so every invocation reads/writes a shared `Thread`.
36
+ * Events get appended; new resume tokens get persisted; existing tokens
37
+ * get spliced into the next run's config.
38
+ *
39
+ * Mutation is in-place on the supplied thread. The wrapper does not
40
+ * defensively clone — caller controls the thread's lifetime.
41
+ *
42
+ * @internal
43
+ */
44
+ export declare function withThread<TConfig>(meta: AgentAdapterMeta<TConfig>, thread: Thread, opts?: WithThreadOptions<TConfig>): AgentAdapterMeta<TConfig>;
45
+ //# sourceMappingURL=with-thread.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-thread.d.ts","sourceRoot":"","sources":["../../src/agents/with-thread.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EACV,gBAAgB,EAGhB,WAAW,EACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAIL,KAAK,MAAM,EACZ,MAAM,aAAa,CAAC;AAErB,gBAAgB;AAChB,MAAM,WAAW,iBAAiB,CAAC,OAAO;IACxC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC;CACtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAChC,IAAI,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAC/B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,iBAAiB,CAAC,OAAO,CAAM,GACpC,gBAAgB,CAAC,OAAO,CAAC,CAuC3B"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Decorate an `AgentAdapter` with automatic `Thread` wiring:
3
+ *
4
+ * 1. Reads `thread.resumeTokens[meta.id]` and splices it into the
5
+ * inner config via the `applyResume` callback. Adapters whose
6
+ * resumption field name differs (anthropic has none, codex uses
7
+ * `previousResponseId`, ACP-based uses `resumeSessionId`, etc.)
8
+ * provide their own splice.
9
+ * 2. Tees every event into `thread.events`. The thread becomes a
10
+ * durable log of the conversation that flows between phases.
11
+ * 3. When a fresh `resumeToken` appears on `agent_start` or `agent_end`,
12
+ * writes it back to `thread.resumeTokens[meta.id]` so subsequent
13
+ * calls with the same thread auto-resume.
14
+ *
15
+ * Unlike `withMemory`, the thread is passed explicitly to the wrapper
16
+ * factory — `Thread` is a per-pipeline primitive, `MemoryProvider` is
17
+ * a cross-pipeline backend. Thread mutation happens through the same
18
+ * `appendEvent` / `setResumeToken` helpers callers would use manually.
19
+ *
20
+ * @internal
21
+ */
22
+ import { createEventBus } from './event-bus.js';
23
+ import { appendEvent, resumeTokenFor, setResumeToken, } from './thread.js';
24
+ /**
25
+ * Wrap an adapter so every invocation reads/writes a shared `Thread`.
26
+ * Events get appended; new resume tokens get persisted; existing tokens
27
+ * get spliced into the next run's config.
28
+ *
29
+ * Mutation is in-place on the supplied thread. The wrapper does not
30
+ * defensively clone — caller controls the thread's lifetime.
31
+ *
32
+ * @internal
33
+ */
34
+ export function withThread(meta, thread, opts = {}) {
35
+ return {
36
+ id: meta.id,
37
+ capabilities: meta.capabilities,
38
+ adapter: (config, runOptions) => {
39
+ const existing = resumeTokenFor(thread, meta.id);
40
+ const effective = existing && opts.applyResume
41
+ ? opts.applyResume(config, existing)
42
+ : config;
43
+ // Tee events: append to thread, capture lifecycle resume tokens,
44
+ // then mirror to the caller's bus if one was supplied.
45
+ const innerBus = createEventBus();
46
+ const userBus = runOptions?.eventBus;
47
+ innerBus.on((event) => {
48
+ appendEvent(thread, event);
49
+ if ((event.type === 'agent_start' || event.type === 'agent_end') &&
50
+ event.resumeToken) {
51
+ setResumeToken(thread, meta.id, event.resumeToken);
52
+ }
53
+ if (userBus) {
54
+ try {
55
+ userBus.emit(event);
56
+ }
57
+ catch {
58
+ // bus implementation handles its own subscriber errors
59
+ }
60
+ }
61
+ });
62
+ const innerOptions = {
63
+ ...(runOptions ?? {}),
64
+ eventBus: innerBus,
65
+ };
66
+ return meta.adapter(effective, innerOptions);
67
+ },
68
+ };
69
+ }
70
+ //# sourceMappingURL=with-thread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-thread.js","sourceRoot":"","sources":["../../src/agents/with-thread.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAOhD,OAAO,EACL,WAAW,EACX,cAAc,EACd,cAAc,GAEf,MAAM,aAAa,CAAC;AAarB;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CACxB,IAA+B,EAC/B,MAAc,EACd,OAAmC,EAAE;IAErC,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,EAAY,EAAE;YACxC,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YACjD,MAAM,SAAS,GAAG,QAAQ,IAAI,IAAI,CAAC,WAAW;gBAC5C,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC;gBACpC,CAAC,CAAC,MAAM,CAAC;YAEX,iEAAiE;YACjE,uDAAuD;YACvD,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,UAAU,EAAE,QAAQ,CAAC;YACrC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBAC3B,IACE,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC;oBAC5D,KAAK,CAAC,WAAW,EACjB,CAAC;oBACD,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;gBACrD,CAAC;gBACD,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC;wBACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACtB,CAAC;oBAAC,MAAM,CAAC;wBACP,uDAAuD;oBACzD,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,YAAY,GAAoB;gBACpC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;gBACrB,QAAQ,EAAE,QAAQ;aACnB,CAAC;YAEF,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QAC/C,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Pipeline-scoped cache — shared across phases and tool calls within a single
3
+ * pipeline run. Avoids redundant work when multiple phases (or multiple
4
+ * parallel agents within a phase) read the same data.
5
+ *
6
+ * Created per-pipeline, cleared on completion.
7
+ *
8
+ * Namespacing: `cache.namespace('foo')` returns a sub-cache that prefixes all
9
+ * keys with `foo:`. Use this when two unrelated callers might pick the same
10
+ * key (e.g. `chunk:0`) to keep their entries isolated. Sub-caches share the
11
+ * underlying store, so `clear()` and `size` see all entries; `clear()` on a
12
+ * sub-cache only drops keys in that namespace.
13
+ */
14
+ export declare class PipelineCache {
15
+ private readonly store;
16
+ private readonly prefix;
17
+ constructor(store?: Map<string, unknown>, prefix?: string);
18
+ private k;
19
+ get<T>(key: string): T | undefined;
20
+ set(key: string, value: unknown): void;
21
+ has(key: string): boolean;
22
+ /** Cache-or-fetch. */
23
+ getOrFetch<T>(key: string, fetcher: () => Promise<T>): Promise<T>;
24
+ /**
25
+ * Clear cache entries.
26
+ *
27
+ * On the root cache: drops every entry.
28
+ * On a namespaced sub-cache: drops only entries whose keys start with this
29
+ * namespace's prefix; entries belonging to the root cache or other
30
+ * namespaces are untouched.
31
+ */
32
+ clear(): void;
33
+ /**
34
+ * Total entries in the underlying store, across all namespaces. This is
35
+ * shared state; a sub-cache reports the same number as the root.
36
+ */
37
+ get size(): number;
38
+ /**
39
+ * Return a sub-cache that prefixes all keys with `${name}:`. Sub-caches
40
+ * are cheap (no copy) and share the underlying store.
41
+ *
42
+ * Nesting is supported: `cache.namespace('a').namespace('b')` prefixes
43
+ * with `a:b:`. Empty names are rejected.
44
+ */
45
+ namespace(name: string): PipelineCache;
46
+ }
47
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAE,MAAW;IAK7D,OAAO,CAAC,CAAC;IAIT,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIlC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAItC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,sBAAsB;IAChB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAUvE;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI;IAUb;;;OAGG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;CAIvC"}
package/dist/cache.js ADDED
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Pipeline-scoped cache — shared across phases and tool calls within a single
3
+ * pipeline run. Avoids redundant work when multiple phases (or multiple
4
+ * parallel agents within a phase) read the same data.
5
+ *
6
+ * Created per-pipeline, cleared on completion.
7
+ *
8
+ * Namespacing: `cache.namespace('foo')` returns a sub-cache that prefixes all
9
+ * keys with `foo:`. Use this when two unrelated callers might pick the same
10
+ * key (e.g. `chunk:0`) to keep their entries isolated. Sub-caches share the
11
+ * underlying store, so `clear()` and `size` see all entries; `clear()` on a
12
+ * sub-cache only drops keys in that namespace.
13
+ */
14
+ export class PipelineCache {
15
+ store;
16
+ prefix;
17
+ constructor(store, prefix = '') {
18
+ this.store = store ?? new Map();
19
+ this.prefix = prefix;
20
+ }
21
+ k(key) {
22
+ return this.prefix ? `${this.prefix}${key}` : key;
23
+ }
24
+ get(key) {
25
+ return this.store.get(this.k(key));
26
+ }
27
+ set(key, value) {
28
+ this.store.set(this.k(key), value);
29
+ }
30
+ has(key) {
31
+ return this.store.has(this.k(key));
32
+ }
33
+ /** Cache-or-fetch. */
34
+ async getOrFetch(key, fetcher) {
35
+ const fullKey = this.k(key);
36
+ if (this.store.has(fullKey)) {
37
+ return this.store.get(fullKey);
38
+ }
39
+ const value = await fetcher();
40
+ this.store.set(fullKey, value);
41
+ return value;
42
+ }
43
+ /**
44
+ * Clear cache entries.
45
+ *
46
+ * On the root cache: drops every entry.
47
+ * On a namespaced sub-cache: drops only entries whose keys start with this
48
+ * namespace's prefix; entries belonging to the root cache or other
49
+ * namespaces are untouched.
50
+ */
51
+ clear() {
52
+ if (!this.prefix) {
53
+ this.store.clear();
54
+ return;
55
+ }
56
+ for (const k of [...this.store.keys()]) {
57
+ if (k.startsWith(this.prefix))
58
+ this.store.delete(k);
59
+ }
60
+ }
61
+ /**
62
+ * Total entries in the underlying store, across all namespaces. This is
63
+ * shared state; a sub-cache reports the same number as the root.
64
+ */
65
+ get size() {
66
+ return this.store.size;
67
+ }
68
+ /**
69
+ * Return a sub-cache that prefixes all keys with `${name}:`. Sub-caches
70
+ * are cheap (no copy) and share the underlying store.
71
+ *
72
+ * Nesting is supported: `cache.namespace('a').namespace('b')` prefixes
73
+ * with `a:b:`. Empty names are rejected.
74
+ */
75
+ namespace(name) {
76
+ if (!name)
77
+ throw new Error('PipelineCache.namespace: name must be non-empty');
78
+ return new PipelineCache(this.store, `${this.prefix}${name}:`);
79
+ }
80
+ }
81
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,OAAO,aAAa;IACP,KAAK,CAAuB;IAC5B,MAAM,CAAS;IAEhC,YAAY,KAA4B,EAAE,SAAiB,EAAE;QAC3D,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,IAAI,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEO,CAAC,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IACpD,CAAC;IAED,GAAG,CAAI,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAkB,CAAC;IACtD,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAc;QAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,sBAAsB;IACtB,KAAK,CAAC,UAAU,CAAI,GAAW,EAAE,OAAyB;QACxD,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAM,CAAC;QACtC,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACH,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,IAAY;QACpB,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAC9E,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC;IACjE,CAAC;CACF"}