@loopingai/core 0.2.0 → 0.3.1

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.
@@ -1,211 +1,276 @@
1
- import { MockAgent, SnapshotAgent } from "undici";
2
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
1
+ import { existsSync } from "node:fs";
3
2
  import path from "node:path";
4
- import { VCR_CONTROL_ORIGIN, CASSETTE_NAME_RE } from "./vcr-shared.js";
3
+ import { Cassette, replayable } from "./vcr-store.js";
4
+ import { VCR_CONTROL_ORIGIN, VCR_MARKER_HEADER, CASSETTE_NAME_RE } from "./vcr-shared.js";
5
+ const CONTROL_HOST = new URL(VCR_CONTROL_ORIGIN).host;
5
6
  /**
6
- * undici stamps every cassette entry with two volatile fields we never want
7
- * committed: `callCount` which its recorder *mutates on every replay* (to walk
8
- * sequential responses) and `timestamp`, the record-time clock. Neither is
9
- * needed for playback (`callCount` defaults to 0 on load; `timestamp` is unused),
10
- * so we delete them from a freshly recorded cassette. Removing them is also what
11
- * stops a plain `npm test` from dirtying cassettes: with no persisted `callCount`
12
- * there is nothing for a replay to bump — and {@link VcrAgent.close} no longer
13
- * writes in playback anyway.
7
+ * Request headers dropped before a live call. `host` and `content-length` are
8
+ * recomputed by the outgoing fetch and a stale value corrupts it;
9
+ * `accept-encoding` is dropped so the body arrives as plaintext to store; the
10
+ * rest are hop-by-hop or Miniflare's own loopback bookkeeping.
14
11
  */
15
- function stripVolatileFields(file) {
16
- const entries = JSON.parse(readFileSync(file, "utf8"));
17
- for (const { snapshot } of entries) {
18
- delete snapshot.callCount;
19
- delete snapshot.timestamp;
20
- }
21
- writeFileSync(file, JSON.stringify(entries, null, 2));
12
+ const SKIP_REQUEST_HEADERS = new Set([
13
+ "accept-encoding",
14
+ "connection",
15
+ "content-length",
16
+ "host",
17
+ "keep-alive",
18
+ "te",
19
+ "trailer",
20
+ "transfer-encoding",
21
+ "upgrade"
22
+ ]);
23
+ function headerRecord(headers) {
24
+ const record = {};
25
+ headers.forEach((value, name) => {
26
+ record[name.toLowerCase()] = value;
27
+ });
28
+ return record;
22
29
  }
23
- function originHost(origin) {
24
- if (!origin)
25
- return null;
26
- try {
27
- return new URL(String(origin)).host;
28
- }
29
- catch {
30
- return null;
31
- }
30
+ /** `set-cookie` is the one header `forEach` folds together destructively. */
31
+ function responseHeaderRecord(headers) {
32
+ const record = {};
33
+ headers.forEach((value, name) => {
34
+ record[name.toLowerCase()] = value;
35
+ });
36
+ const cookies = headers.getSetCookie?.() ?? [];
37
+ if (cookies.length > 0)
38
+ record["set-cookie"] = cookies;
39
+ return record;
32
40
  }
33
- const CONTROL_HOST = new URL(VCR_CONTROL_ORIGIN).host;
34
41
  /**
35
- * The single agent Miniflare accepts as `fetchMock` (it allows only one), fanning
36
- * outbound worker requests out by role:
37
- *
38
- * - **Control channel** ({@link VCR_CONTROL_ORIGIN}) → ordinary MockAgent
39
- * interceptors whose reply callbacks flip the *active cassette*. This is how a
40
- * spec running in workerd (no filesystem) tells this Node-side agent which
41
- * test is running — see `setupRecording` (vcr-spec.ts).
42
- * - **Passthrough hosts** (the gateway JWKS) → ordinary MockAgent interceptors,
43
- * unchanged from before VCR existed.
44
- * - **Everything else, while a cassette is active** → that cassette's undici
45
- * {@link SnapshotAgent} record/replay. In playback a request with no matching
46
- * recording throws `No snapshot found` — offline, never the network.
47
- * - **Everything else, with no active cassette** → ordinary MockAgent behavior
48
- * (`disableNetConnect()` → offline error). A non-recorded test never reaches
49
- * the network.
42
+ * The one place a `Response` is built, so recording and replaying a given
43
+ * cassette entry cannot disagree about it.
50
44
  *
51
- * There is **no registry**: cassettes are keyed per test (file + describe + test
52
- * name) by the spec helper, activated one at a time over the control channel. A
53
- * new recorded spec touches only its own `.spec` file.
54
- *
55
- * Why `VcrAgent extends MockAgent` rather than `SnapshotAgent`: a `SnapshotAgent`'s
56
- * `dispatch` fully overrides `MockAgent`'s (it never falls back to the interceptor
57
- * path), so one `SnapshotAgent` cannot also serve the control/interceptor fixtures
58
- * — and cannot serve more than one cassette. Keeping one internal `SnapshotAgent`
59
- * per cassette and dispatching to the active one, with an ordinary
60
- * `MockAgent.dispatch` fallback for control/passthrough/offline, leaves the
61
- * interceptor path exactly as it always worked. Miniflare validates `fetchMock`
62
- * with `instanceof MockAgent`, which `VcrAgent` satisfies directly.
45
+ * `Response` rejects *any* non-null body on 204/205/304 an empty `Uint8Array`
46
+ * throws just as a full one does — so a recorded 204 has to be handed back with
47
+ * a null body or it cannot be replayed at all.
63
48
  */
64
- export class VcrAgent extends MockAgent {
49
+ function toResponse({ status, headers, body }) {
50
+ const nullBody = status === 204 || status === 205 || status === 304;
51
+ return new Response(nullBody ? null : body, { status, headers });
52
+ }
53
+ function json(status, value) {
54
+ return new Response(JSON.stringify(value), {
55
+ status,
56
+ headers: {
57
+ "content-type": "application/json",
58
+ [VCR_MARKER_HEADER]: "1"
59
+ }
60
+ });
61
+ }
62
+ class Recorder {
65
63
  #snapshotsDir;
66
64
  #record;
67
- #passthrough;
65
+ #handlers;
66
+ #allowNetwork;
68
67
  #excludeHeaders;
69
- #ignoreHeaders;
70
- /** One SnapshotAgent per cassette name, created lazily on first activation. */
71
- #agents = new Map();
68
+ /** One cassette per name, created on first activation. */
69
+ #cassettes = new Map();
72
70
  #active = null;
73
71
  #activeName = null;
72
+ /** Requests that could not be served since the active cassette was set. */
73
+ #misses = [];
74
74
  constructor(options) {
75
- super();
76
75
  this.#snapshotsDir = options.snapshotsDir;
77
76
  this.#record = options.record;
78
- this.#passthrough = new Set(options.passthroughHosts);
79
- this.#excludeHeaders = options.excludeHeaders;
80
- this.#ignoreHeaders = options.ignoreHeaders;
81
- this.#registerControl();
77
+ this.#handlers = options.handlers ?? {};
78
+ this.#allowNetwork = new Set(options.allowNetworkHosts ?? []);
79
+ this.#excludeHeaders = options.excludeHeaders ?? [];
82
80
  }
83
- /** Persistent interceptors backing the control channel (see class doc). */
84
- #registerControl() {
85
- const control = this.get(VCR_CONTROL_ORIGIN);
86
- control
87
- // RegExp path so any `?cassette=…` query matches; the name is read from
88
- // opts.path (the body is a ReadableStream and can't be read synchronously).
89
- .intercept({ path: /^\/use(\?|$)/, method: "POST" })
90
- .reply((opts) => this.#onUse(opts))
91
- .persist();
92
- control
93
- .intercept({ path: "/release", method: "POST" })
94
- .reply(() => {
81
+ handle = async (request) => {
82
+ const url = new URL(request.url);
83
+ if (url.host === CONTROL_HOST)
84
+ return this.#control(url);
85
+ const handler = this.#handlers[url.host];
86
+ if (handler)
87
+ return handler(request);
88
+ // Read once: the body is needed to key the cassette *and* to forward.
89
+ const bytes = Buffer.from(await request.arrayBuffer());
90
+ if (this.#allowNetwork.has(url.host))
91
+ return this.#live(request, bytes);
92
+ const body = bytes.toString("utf8");
93
+ const what = `${request.method} ${request.url}`;
94
+ if (this.#active === null) {
95
+ this.#misses.push(what);
96
+ return this.#blocked(`VCR blocked ${what}: no cassette is active for this test. ` +
97
+ `Call setupRecording() at the top of the spec, or add the host to ` +
98
+ `allowNetworkHosts / handlers.`);
99
+ }
100
+ if (this.#record)
101
+ return this.#recordOne(request, bytes);
102
+ const hit = this.#active.match(request.method, request.url, body);
103
+ if (hit)
104
+ return toResponse(hit);
105
+ this.#misses.push(what);
106
+ return this.#blocked(`VCR has no recording of ${what} in ${path.basename(this.#active.file)}. ` +
107
+ `Re-record with RECORD=1. The cassette holds: ` +
108
+ `${this.#active.recorded.join(", ") || "(nothing)"}.`);
109
+ };
110
+ /**
111
+ * A miss cannot be made to *reject* the Worker's `fetch()` — Miniflare catches
112
+ * whatever an outbound service throws and turns it into a 500 anyway. So the
113
+ * message goes in the body where it can be read, and the miss is also reported
114
+ * on `/release` so the test itself fails with it. That is the half the old
115
+ * harness lacked: `disableNetConnect()` rejected, and the rejection surfaced
116
+ * as `internal error; reference = …` naming nothing.
117
+ */
118
+ #blocked(message) {
119
+ return new Response(message, {
120
+ status: 500,
121
+ headers: { [VCR_MARKER_HEADER]: "1" }
122
+ });
123
+ }
124
+ #control(url) {
125
+ if (url.pathname === "/release") {
126
+ const misses = this.#misses;
127
+ // Write here rather than only at teardown, so a run that is interrupted
128
+ // still keeps every cassette whose test finished. A no-op in playback:
129
+ // `flush()` returns immediately unless something was recorded.
130
+ this.#active?.flush();
95
131
  this.#active = null;
96
132
  this.#activeName = null;
97
- return { statusCode: 204 };
98
- })
99
- .persist();
100
- }
101
- /** Activate the named cassette (get-or-create its SnapshotAgent). `opts.path`
102
- * is undici's reply-callback request path, e.g. `/use?cassette=<name>`. */
103
- #onUse(opts) {
104
- const name = new URL(opts.path, VCR_CONTROL_ORIGIN).searchParams.get("cassette") ?? "";
133
+ this.#misses = [];
134
+ return json(200, { misses });
135
+ }
136
+ if (url.pathname !== "/use")
137
+ return json(404, { error: "unknown" });
138
+ const name = url.searchParams.get("cassette") ?? "";
105
139
  if (!CASSETTE_NAME_RE.test(name)) {
106
- return { statusCode: 400, data: `invalid cassette name: ${name}` };
140
+ return json(400, { error: `invalid cassette name: ${name}` });
107
141
  }
108
- // Cheap tripwire: recorded specs are expected to run sequentially, so a
109
- // second cassette activating while another is held means parallel recorded
110
- // tests are sharing this agent surface it loudly rather than mis-record.
142
+ // Recorded specs are expected to run sequentially: a second cassette
143
+ // activating while one is held means two of them are sharing this recorder,
144
+ // which mis-records rather than failing, so say so instead.
111
145
  if (this.#activeName !== null && this.#activeName !== name) {
112
- return {
113
- statusCode: 409,
114
- data: `cassette ${this.#activeName} still active`
115
- };
146
+ return json(409, { error: `cassette ${this.#activeName} still active` });
116
147
  }
117
148
  const file = path.join(this.#snapshotsDir, name);
118
- // Playback with no cassette → 404, which the spec turns into a "record it"
119
- // error. In record mode the file is created on first write.
149
+ // Playback with no cassette on disk → 404, which the spec turns into a
150
+ // "record it" failure. Recording creates the file on first write.
120
151
  if (!this.#record && !existsSync(file)) {
121
- return { statusCode: 404, data: `no cassette ${name}` };
152
+ return json(404, { error: `no cassette ${name}` });
122
153
  }
123
- this.#active = this.#agentFor(name, file);
154
+ this.#active = this.#cassetteFor(name, file);
124
155
  this.#activeName = name;
125
- return { statusCode: 204 };
156
+ this.#misses = [];
157
+ return json(200, { cassette: name });
126
158
  }
127
- #agentFor(name, file) {
128
- let agent = this.#agents.get(name);
129
- if (!agent) {
130
- agent = new SnapshotAgent({
131
- // `"record"`, not undici's `"update"`: update mode replays any request
132
- // already in the cassette and only hits the network for new ones —
133
- // silently stale the moment recorded traffic no longer matches live
134
- // behavior (e.g. a re-used game id). `"record"` never loads or matches
135
- // existing entries, so a recording run always reflects the live API.
136
- mode: this.#record ? "record" : "playback",
137
- snapshotPath: file,
138
- excludeHeaders: this.#excludeHeaders,
139
- ignoreHeaders: this.#ignoreHeaders,
140
- autoFlush: this.#record
141
- });
142
- this.#agents.set(name, agent);
159
+ #cassetteFor(name, file) {
160
+ let cassette = this.#cassettes.get(name);
161
+ if (!cassette) {
162
+ cassette = new Cassette(file, { excludeHeaders: this.#excludeHeaders });
163
+ // Recording deliberately starts from nothing rather than topping up an
164
+ // existing file: a cassette that mixes today's traffic with last month's
165
+ // is stale in a way no assertion can see.
166
+ if (!this.#record)
167
+ cassette.load();
168
+ this.#cassettes.set(name, cassette);
143
169
  }
144
- return agent;
170
+ return cassette;
145
171
  }
146
- dispatch(opts, handler) {
147
- const host = originHost(opts.origin);
148
- const vcr = host !== null &&
149
- host !== CONTROL_HOST &&
150
- !this.#passthrough.has(host) &&
151
- this.#active !== null;
152
- if (vcr)
153
- return this.#active.dispatch(opts, handler);
154
- return super.dispatch(opts, handler);
172
+ /** The real call, with the headers the Worker sent minus the unforwardable. */
173
+ #live(request, body) {
174
+ const headers = [];
175
+ request.headers.forEach((value, name) => {
176
+ if (!SKIP_REQUEST_HEADERS.has(name.toLowerCase())) {
177
+ headers.push([name, value]);
178
+ }
179
+ });
180
+ return fetch(request.url, {
181
+ method: request.method,
182
+ headers,
183
+ body: body.byteLength > 0 ? body : undefined,
184
+ // Matches what Miniflare's own `fetch(req, { dispatcher })` sugar did, so
185
+ // a recording captures the same final response the Worker used to see.
186
+ redirect: "follow"
187
+ });
155
188
  }
156
189
  /**
157
- * Closes every cassette's `SnapshotAgent`, then this agent.
158
- *
159
- * Record mode: `SnapshotAgent.close()` saves each cassette, stops its
160
- * recorder's auto-flush timer, and closes its real sockets all required (see
161
- * {@link closeVcr}). We then {@link stripVolatileFields} from each saved file
162
- * so the committed cassette carries no `callCount`/`timestamp`.
163
- *
164
- * Playback mode: undici's `SnapshotAgent.close()` *unconditionally* re-saves
165
- * the cassette, writing back the `callCount` its recorder mutates on every
166
- * replay — the side effect that dirtied cassettes on a plain `npm test`. There
167
- * is nothing to save and no real socket in playback, so we skip that save
168
- * entirely and only stop each recorder's timers.
190
+ * `requestBytes` is forwarded to the live endpoint **as received**. The
191
+ * cassette stores the utf-8 text of it, which is what the format has always
192
+ * held and what keys the entry but a payload that is not valid utf-8 must
193
+ * not be re-encoded on its way to a real API, so the two are kept separate
194
+ * rather than the string being round-tripped back into bytes.
169
195
  */
196
+ async #recordOne(request, requestBytes) {
197
+ const live = await this.#live(request, requestBytes);
198
+ const bytes = Buffer.from(await live.arrayBuffer());
199
+ const recordedRequest = {
200
+ method: request.method,
201
+ url: request.url,
202
+ headers: headerRecord(request.headers),
203
+ body: requestBytes.toString("utf8")
204
+ };
205
+ const recordedResponse = {
206
+ statusCode: live.status,
207
+ headers: responseHeaderRecord(live.headers),
208
+ body: bytes.toString("base64")
209
+ };
210
+ this.#active.record(recordedRequest, recordedResponse);
211
+ // Serve the response through the same path a replay takes, so a recording
212
+ // run and the replay of what it just wrote cannot disagree.
213
+ return toResponse(replayable(recordedResponse));
214
+ }
170
215
  async close() {
171
- if (this.#record) {
172
- await Promise.all([...this.#agents.values()].map((a) => a.close()));
173
- for (const name of this.#agents.keys()) {
174
- stripVolatileFields(path.join(this.#snapshotsDir, name));
175
- }
176
- }
177
- else {
178
- for (const a of this.#agents.values())
179
- a.getRecorder().destroy();
180
- }
181
- await super.close();
216
+ for (const cassette of this.#cassettes.values())
217
+ cassette.flush();
182
218
  }
183
219
  }
184
- export function createVcrAgent(options) {
185
- const agent = new VcrAgent(options);
186
- globalThis[VCR_KEY] = agent;
187
- return agent;
220
+ /**
221
+ * Build the recorder and register it for {@link closeVcr}.
222
+ *
223
+ * ```ts
224
+ * // vitest.config.ts
225
+ * const vcr = createVcr({
226
+ * snapshotsDir: path.resolve(import.meta.dirname, "test/snapshots"),
227
+ * record: recordFromEnv(),
228
+ * excludeHeaders: ["x-api-key", "authorization", "cookie", "set-cookie"]
229
+ * });
230
+ *
231
+ * export default defineConfig({
232
+ * plugins: [cloudflareTest({ miniflare: { outboundService: vcr.outboundService } })],
233
+ * test: { globalSetup: ["@loopingai/core/testing/vcr-global-setup"] }
234
+ * });
235
+ * ```
236
+ */
237
+ export function createVcr(options) {
238
+ const recorder = new Recorder(options);
239
+ const vcr = {
240
+ outboundService: recorder.handle,
241
+ close: () => recorder.close()
242
+ };
243
+ globalThis[VCR_KEY] = vcr;
244
+ return vcr;
245
+ }
246
+ /**
247
+ * Whether this run records, from `RECORD`.
248
+ *
249
+ * Compared against `"1"` rather than tested for truthiness, because every
250
+ * non-empty string is truthy: `RECORD=0` and `RECORD=false` — the two things
251
+ * someone reaches for to turn recording *off* — would otherwise turn it on and
252
+ * overwrite committed cassettes with live traffic. The opposite mistake
253
+ * (`RECORD=true` not recording) fails loudly on the next assertion and costs
254
+ * nothing.
255
+ */
256
+ export function recordFromEnv() {
257
+ return process.env.RECORD === "1";
188
258
  }
189
- /** globalThis slot so the Vitest globalSetup teardown can reach the live agent
259
+ /** globalThis slot so the Vitest globalSetup teardown can reach the recorder
190
260
  * created during config evaluation (same process, possibly a different module
191
261
  * realm — globalThis is the reliable channel). */
192
262
  const VCR_KEY = "__VCR_AGENT__";
193
263
  /**
194
- * Flush and close the active VCR agent (all its cassettes). In record mode,
195
- * undici's recorder arms a self-refreshing, non-`unref`ed auto-flush timer and
196
- * the real `SnapshotAgent` keeps sockets open both keep the process alive
197
- * after tests finish and trip Vitest's "close timed out" at teardown. Calling
198
- * this (from a Vitest `globalSetup` teardown, which runs before Vite closes its
199
- * own server) stops them. A no-op if no agent was created, and in playback only
200
- * stops recorder timers — {@link VcrAgent.close} deliberately does not re-save
201
- * the cassette there (see its doc).
264
+ * Flush every cassette. Cassettes are already written when each one is
265
+ * released, so this is a safety net for a run that ended without releasing —
266
+ * and a no-op if no recorder was created.
202
267
  */
203
268
  export async function closeVcr() {
204
269
  const g = globalThis;
205
- const agent = g[VCR_KEY];
206
- if (!agent)
270
+ const vcr = g[VCR_KEY];
271
+ if (!vcr)
207
272
  return;
208
273
  g[VCR_KEY] = undefined;
209
- await agent.close();
274
+ await vcr.close();
210
275
  }
211
276
  //# sourceMappingURL=vcr.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vcr.js","sourceRoot":"","sources":["../../src/testing/vcr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAmB,MAAM,QAAQ,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEvE;;;;;;;;;GASG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAElD,CAAC;IACJ,KAAK,MAAM,EAAE,QAAQ,EAAE,IAAI,OAAO,EAAE,CAAC;QACnC,OAAO,QAAQ,CAAC,SAAS,CAAC;QAC1B,OAAO,QAAQ,CAAC,SAAS,CAAC;IAC5B,CAAC;IACD,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,UAAU,CAAC,MAAgC;IAClD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAoBD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,OAAO,QAAS,SAAQ,SAAS;IAC5B,aAAa,CAAS;IACtB,OAAO,CAAU;IACjB,YAAY,CAAc;IAC1B,eAAe,CAAY;IAC3B,cAAc,CAAY;IACnC,+EAA+E;IACtE,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IACpD,OAAO,GAAyB,IAAI,CAAC;IACrC,WAAW,GAAkB,IAAI,CAAC;IAElC,YAAY,OAA8B;QACxC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;QAC1C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACtD,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;QAC9C,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;QAC5C,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,2EAA2E;IAC3E,gBAAgB;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAC7C,OAAO;YACL,wEAAwE;YACxE,4EAA4E;aAC3E,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;aACnD,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAClC,OAAO,EAAE,CAAC;QACb,OAAO;aACJ,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;aAC/C,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;QAC7B,CAAC,CAAC;aACD,OAAO,EAAE,CAAC;IACf,CAAC;IAED;gFAC4E;IAC5E,MAAM,CAAC,IAAsB;QAC3B,MAAM,IAAI,GACR,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QAC5E,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,0BAA0B,IAAI,EAAE,EAAE,CAAC;QACrE,CAAC;QACD,wEAAwE;QACxE,2EAA2E;QAC3E,2EAA2E;QAC3E,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YAC3D,OAAO;gBACL,UAAU,EAAE,GAAG;gBACf,IAAI,EAAE,YAAY,IAAI,CAAC,WAAW,eAAe;aAClD,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACjD,2EAA2E;QAC3E,4DAA4D;QAC5D,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,eAAe,IAAI,EAAE,EAAE,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,SAAS,CAAC,IAAY,EAAE,IAAY;QAClC,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,IAAI,aAAa,CAAC;gBACxB,uEAAuE;gBACvE,mEAAmE;gBACnE,oEAAoE;gBACpE,uEAAuE;gBACvE,qEAAqE;gBACrE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU;gBAC1C,YAAY,EAAE,IAAI;gBAClB,cAAc,EAAE,IAAI,CAAC,eAAe;gBACpC,aAAa,EAAE,IAAI,CAAC,cAAc;gBAClC,SAAS,EAAE,IAAI,CAAC,OAAO;aACxB,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,QAAQ,CACN,IAAgC,EAChC,OAAmC;QAEnC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,GAAG,GACP,IAAI,KAAK,IAAI;YACb,IAAI,KAAK,YAAY;YACrB,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;YAC5B,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC;QACxB,IAAI,GAAG;YAAE,OAAO,IAAI,CAAC,OAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAY,CAAC;QACjE,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACpE,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;gBACvC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;gBAAE,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,CAAC;QACnE,CAAC;QACD,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,UAAsC,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;IACzD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;mDAEmD;AACnD,MAAM,OAAO,GAAG,eAAe,CAAC;AAEhC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,CAAC,GAAG,UAAqC,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAyB,CAAC;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,CAAC,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IACvB,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"vcr.js","sourceRoot":"","sources":["../../src/testing/vcr.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopingai/core",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Shared, mandatory foundation for Looping agents on Cloudflare Workers: zero-trust A2A, durable task lifecycle, delegation and subagent runtime, test harness.",
5
5
  "keywords": [
6
6
  "a2a",
@@ -100,16 +100,15 @@
100
100
  },
101
101
  "dependencies": {
102
102
  "@a2a-js/sdk": "^1.0.0",
103
- "@cloudflare/workers-types": "^5.20260801.1",
103
+ "@cloudflare/workers-types": "^5.20260804.1",
104
104
  "drizzle-orm": "^0.45.2",
105
- "jose": "^6.2.7",
105
+ "jose": "^6.2.8",
106
106
  "zod": "^4.4.3"
107
107
  },
108
108
  "peerDependencies": {
109
- "@cloudflare/vitest-pool-workers": "^0.18.8",
109
+ "@cloudflare/vitest-pool-workers": ">=0.18",
110
110
  "agents": "^0.20.0",
111
- "ai": "^7.0.40",
112
- "undici": "^7.28.0",
111
+ "ai": "^7.0.51",
113
112
  "vitest": ">=4",
114
113
  "workers-ai-provider": "^4.0.0"
115
114
  },
@@ -117,15 +116,12 @@
117
116
  "@cloudflare/vitest-pool-workers": {
118
117
  "optional": true
119
118
  },
120
- "undici": {
121
- "optional": true
122
- },
123
119
  "vitest": {
124
120
  "optional": true
125
121
  }
126
122
  },
127
123
  "devDependencies": {
128
- "@cloudflare/vitest-pool-workers": "^0.18.8",
124
+ "@cloudflare/vitest-pool-workers": "^0.20.1",
129
125
  "@types/node": "^26.1.1",
130
126
  "agents": "^0.20.0",
131
127
  "ai": "^7.0.40",
@@ -133,11 +129,10 @@
133
129
  "eslint": "^10.8.0",
134
130
  "prettier": "^3.9.6",
135
131
  "typescript": "^6.0.3",
136
- "typescript-eslint": "^8.65.0",
137
- "undici": "7.28.0",
132
+ "typescript-eslint": "^8.66.0",
138
133
  "vitest": "^4.1.10",
139
134
  "workers-ai-provider": "^4.0.0",
140
- "wrangler": "^4.114.0"
135
+ "wrangler": "^4.118.0"
141
136
  },
142
137
  "engines": {
143
138
  "node": ">=24"
@@ -145,6 +140,11 @@
145
140
  "publishConfig": {
146
141
  "access": "public"
147
142
  },
143
+ "overrides": {
144
+ "@esbuild-kit/core-utils": {
145
+ "esbuild": "^0.25.0"
146
+ }
147
+ },
148
148
  "allowScripts": {
149
149
  "esbuild": false,
150
150
  "fsevents": false,