@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.
- package/LICENSE +21 -0
- package/README.md +226 -0
- package/dist/agent/index.d.ts +28 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +28 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/openai-adapter.d.ts +15 -0
- package/dist/agent/openai-adapter.d.ts.map +1 -0
- package/dist/agent/openai-adapter.js +57 -0
- package/dist/agent/openai-adapter.js.map +1 -0
- package/dist/agent/parse-json.d.ts +12 -0
- package/dist/agent/parse-json.d.ts.map +1 -0
- package/dist/agent/parse-json.js +31 -0
- package/dist/agent/parse-json.js.map +1 -0
- package/dist/agent/retry.d.ts +15 -0
- package/dist/agent/retry.d.ts.map +1 -0
- package/dist/agent/retry.js +35 -0
- package/dist/agent/retry.js.map +1 -0
- package/dist/agent/runner.d.ts +25 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +270 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/stream-consumer.d.ts +57 -0
- package/dist/agent/stream-consumer.d.ts.map +1 -0
- package/dist/agent/stream-consumer.js +126 -0
- package/dist/agent/stream-consumer.js.map +1 -0
- package/dist/agent/types.d.ts +135 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +9 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/agent-runner.d.ts +10 -0
- package/dist/agent-runner.d.ts.map +1 -0
- package/dist/agent-runner.js +10 -0
- package/dist/agent-runner.js.map +1 -0
- package/dist/agents/capability.d.ts +36 -0
- package/dist/agents/capability.d.ts.map +1 -0
- package/dist/agents/capability.js +51 -0
- package/dist/agents/capability.js.map +1 -0
- package/dist/agents/event-bus.d.ts +20 -0
- package/dist/agents/event-bus.d.ts.map +1 -0
- package/dist/agents/event-bus.js +40 -0
- package/dist/agents/event-bus.js.map +1 -0
- package/dist/agents/index.d.ts +23 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +33 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/inference-adapter.d.ts +52 -0
- package/dist/agents/inference-adapter.d.ts.map +1 -0
- package/dist/agents/inference-adapter.js +209 -0
- package/dist/agents/inference-adapter.js.map +1 -0
- package/dist/agents/job-store-bridge.d.ts +44 -0
- package/dist/agents/job-store-bridge.d.ts.map +1 -0
- package/dist/agents/job-store-bridge.js +58 -0
- package/dist/agents/job-store-bridge.js.map +1 -0
- package/dist/agents/memory.d.ts +40 -0
- package/dist/agents/memory.d.ts.map +1 -0
- package/dist/agents/memory.js +14 -0
- package/dist/agents/memory.js.map +1 -0
- package/dist/agents/protocol.d.ts +302 -0
- package/dist/agents/protocol.d.ts.map +1 -0
- package/dist/agents/protocol.js +36 -0
- package/dist/agents/protocol.js.map +1 -0
- package/dist/agents/run-helpers.d.ts +70 -0
- package/dist/agents/run-helpers.d.ts.map +1 -0
- package/dist/agents/run-helpers.js +131 -0
- package/dist/agents/run-helpers.js.map +1 -0
- package/dist/agents/serialize-error.d.ts +18 -0
- package/dist/agents/serialize-error.d.ts.map +1 -0
- package/dist/agents/serialize-error.js +27 -0
- package/dist/agents/serialize-error.js.map +1 -0
- package/dist/agents/structured-output.d.ts +90 -0
- package/dist/agents/structured-output.d.ts.map +1 -0
- package/dist/agents/structured-output.js +101 -0
- package/dist/agents/structured-output.js.map +1 -0
- package/dist/agents/test-utils/conformance.d.ts +59 -0
- package/dist/agents/test-utils/conformance.d.ts.map +1 -0
- package/dist/agents/test-utils/conformance.js +207 -0
- package/dist/agents/test-utils/conformance.js.map +1 -0
- package/dist/agents/test-utils/index.d.ts +12 -0
- package/dist/agents/test-utils/index.d.ts.map +1 -0
- package/dist/agents/test-utils/index.js +12 -0
- package/dist/agents/test-utils/index.js.map +1 -0
- package/dist/agents/test-utils/mock-agent.d.ts +66 -0
- package/dist/agents/test-utils/mock-agent.d.ts.map +1 -0
- package/dist/agents/test-utils/mock-agent.js +244 -0
- package/dist/agents/test-utils/mock-agent.js.map +1 -0
- package/dist/agents/thread.d.ts +57 -0
- package/dist/agents/thread.d.ts.map +1 -0
- package/dist/agents/thread.js +128 -0
- package/dist/agents/thread.js.map +1 -0
- package/dist/agents/turn-accumulator.d.ts +94 -0
- package/dist/agents/turn-accumulator.d.ts.map +1 -0
- package/dist/agents/turn-accumulator.js +150 -0
- package/dist/agents/turn-accumulator.js.map +1 -0
- package/dist/agents/with-memory.d.ts +55 -0
- package/dist/agents/with-memory.d.ts.map +1 -0
- package/dist/agents/with-memory.js +155 -0
- package/dist/agents/with-memory.js.map +1 -0
- package/dist/agents/with-thread.d.ts +45 -0
- package/dist/agents/with-thread.d.ts.map +1 -0
- package/dist/agents/with-thread.js +70 -0
- package/dist/agents/with-thread.js.map +1 -0
- package/dist/cache.d.ts +47 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +81 -0
- package/dist/cache.js.map +1 -0
- package/dist/context/compressor.d.ts +36 -0
- package/dist/context/compressor.d.ts.map +1 -0
- package/dist/context/compressor.js +158 -0
- package/dist/context/compressor.js.map +1 -0
- package/dist/context/index.d.ts +4 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +4 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/result-capper.d.ts +32 -0
- package/dist/context/result-capper.d.ts.map +1 -0
- package/dist/context/result-capper.js +50 -0
- package/dist/context/result-capper.js.map +1 -0
- package/dist/context/token-budget.d.ts +81 -0
- package/dist/context/token-budget.d.ts.map +1 -0
- package/dist/context/token-budget.js +99 -0
- package/dist/context/token-budget.js.map +1 -0
- package/dist/helpers/caller.d.ts +18 -0
- package/dist/helpers/caller.d.ts.map +1 -0
- package/dist/helpers/caller.js +40 -0
- package/dist/helpers/caller.js.map +1 -0
- package/dist/helpers/hook.d.ts +73 -0
- package/dist/helpers/hook.d.ts.map +1 -0
- package/dist/helpers/hook.js +244 -0
- package/dist/helpers/hook.js.map +1 -0
- package/dist/helpers/index.d.ts +12 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +11 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/one-shot.d.ts +27 -0
- package/dist/helpers/one-shot.d.ts.map +1 -0
- package/dist/helpers/one-shot.js +43 -0
- package/dist/helpers/one-shot.js.map +1 -0
- package/dist/helpers/schedule.d.ts +59 -0
- package/dist/helpers/schedule.d.ts.map +1 -0
- package/dist/helpers/schedule.js +118 -0
- package/dist/helpers/schedule.js.map +1 -0
- package/dist/helpers/types.d.ts +34 -0
- package/dist/helpers/types.d.ts.map +1 -0
- package/dist/helpers/types.js +11 -0
- package/dist/helpers/types.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/inference.d.ts +27 -0
- package/dist/inference.d.ts.map +1 -0
- package/dist/inference.js +34 -0
- package/dist/inference.js.map +1 -0
- package/dist/messages.d.ts +64 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +17 -0
- package/dist/messages.js.map +1 -0
- package/dist/orchestrator.d.ts +56 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +62 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/patterns/bounded-fanout-of.d.ts +61 -0
- package/dist/patterns/bounded-fanout-of.d.ts.map +1 -0
- package/dist/patterns/bounded-fanout-of.js +142 -0
- package/dist/patterns/bounded-fanout-of.js.map +1 -0
- package/dist/patterns/bounded-fanout.d.ts +111 -0
- package/dist/patterns/bounded-fanout.d.ts.map +1 -0
- package/dist/patterns/bounded-fanout.js +151 -0
- package/dist/patterns/bounded-fanout.js.map +1 -0
- package/dist/patterns/index.d.ts +14 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +13 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/patterns/intent-gate.d.ts +27 -0
- package/dist/patterns/intent-gate.d.ts.map +1 -0
- package/dist/patterns/intent-gate.js +32 -0
- package/dist/patterns/intent-gate.js.map +1 -0
- package/dist/patterns/match.d.ts +30 -0
- package/dist/patterns/match.d.ts.map +1 -0
- package/dist/patterns/match.js +58 -0
- package/dist/patterns/match.js.map +1 -0
- package/dist/patterns/parallel-fanout.d.ts +28 -0
- package/dist/patterns/parallel-fanout.d.ts.map +1 -0
- package/dist/patterns/parallel-fanout.js +24 -0
- package/dist/patterns/parallel-fanout.js.map +1 -0
- package/dist/patterns/parallel-phases.d.ts +27 -0
- package/dist/patterns/parallel-phases.d.ts.map +1 -0
- package/dist/patterns/parallel-phases.js +77 -0
- package/dist/patterns/parallel-phases.js.map +1 -0
- package/dist/patterns/preflight-confidence.d.ts +20 -0
- package/dist/patterns/preflight-confidence.d.ts.map +1 -0
- package/dist/patterns/preflight-confidence.js +38 -0
- package/dist/patterns/preflight-confidence.js.map +1 -0
- package/dist/patterns/spot-check.d.ts +19 -0
- package/dist/patterns/spot-check.d.ts.map +1 -0
- package/dist/patterns/spot-check.js +33 -0
- package/dist/patterns/spot-check.js.map +1 -0
- package/dist/patterns/sub-pipeline.d.ts +84 -0
- package/dist/patterns/sub-pipeline.d.ts.map +1 -0
- package/dist/patterns/sub-pipeline.js +90 -0
- package/dist/patterns/sub-pipeline.js.map +1 -0
- package/dist/patterns/synthesize-with-followup.d.ts +35 -0
- package/dist/patterns/synthesize-with-followup.d.ts.map +1 -0
- package/dist/patterns/synthesize-with-followup.js +45 -0
- package/dist/patterns/synthesize-with-followup.js.map +1 -0
- package/dist/patterns/while-condition.d.ts +31 -0
- package/dist/patterns/while-condition.d.ts.map +1 -0
- package/dist/patterns/while-condition.js +59 -0
- package/dist/patterns/while-condition.js.map +1 -0
- package/dist/patterns/with-retry.d.ts +37 -0
- package/dist/patterns/with-retry.d.ts.map +1 -0
- package/dist/patterns/with-retry.js +73 -0
- package/dist/patterns/with-retry.js.map +1 -0
- package/dist/phase.d.ts +78 -0
- package/dist/phase.d.ts.map +1 -0
- package/dist/phase.js +36 -0
- package/dist/phase.js.map +1 -0
- package/dist/session/index.d.ts +5 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +4 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/job-runner.d.ts +67 -0
- package/dist/session/job-runner.d.ts.map +1 -0
- package/dist/session/job-runner.js +131 -0
- package/dist/session/job-runner.js.map +1 -0
- package/dist/session/job-store.d.ts +98 -0
- package/dist/session/job-store.d.ts.map +1 -0
- package/dist/session/job-store.js +37 -0
- package/dist/session/job-store.js.map +1 -0
- package/dist/session/sqlite-job-store.d.ts +40 -0
- package/dist/session/sqlite-job-store.d.ts.map +1 -0
- package/dist/session/sqlite-job-store.js +200 -0
- package/dist/session/sqlite-job-store.js.map +1 -0
- package/dist/session/sse.d.ts +60 -0
- package/dist/session/sse.d.ts.map +1 -0
- package/dist/session/sse.js +97 -0
- package/dist/session/sse.js.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +44 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +74 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/triggers/index.d.ts +15 -0
- package/dist/triggers/index.d.ts.map +1 -0
- package/dist/triggers/index.js +14 -0
- package/dist/triggers/index.js.map +1 -0
- package/dist/triggers/run-trigger.d.ts +86 -0
- package/dist/triggers/run-trigger.d.ts.map +1 -0
- package/dist/triggers/run-trigger.js +146 -0
- package/dist/triggers/run-trigger.js.map +1 -0
- package/dist/triggers/timer-trigger.d.ts +46 -0
- package/dist/triggers/timer-trigger.d.ts.map +1 -0
- package/dist/triggers/timer-trigger.js +74 -0
- package/dist/triggers/timer-trigger.js.map +1 -0
- package/dist/triggers/types.d.ts +61 -0
- package/dist/triggers/types.d.ts.map +1 -0
- package/dist/triggers/types.js +23 -0
- package/dist/triggers/types.js.map +1 -0
- 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"}
|
package/dist/cache.d.ts
ADDED
|
@@ -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"}
|