@loopingai/core 0.1.0 → 0.1.2

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 (67) hide show
  1. package/README.md +74 -1
  2. package/dist/agent/history.d.ts +3 -3
  3. package/dist/agent/index.d.ts +2 -2
  4. package/dist/agent/index.d.ts.map +1 -1
  5. package/dist/agent/index.js +1 -1
  6. package/dist/agent/index.js.map +1 -1
  7. package/dist/agent/model.d.ts +0 -7
  8. package/dist/agent/model.d.ts.map +1 -1
  9. package/dist/agent/model.js +0 -13
  10. package/dist/agent/model.js.map +1 -1
  11. package/dist/agent/session.d.ts +21 -11
  12. package/dist/agent/session.d.ts.map +1 -1
  13. package/dist/agent/session.js +13 -10
  14. package/dist/agent/session.js.map +1 -1
  15. package/dist/config.d.ts +0 -17
  16. package/dist/config.d.ts.map +1 -1
  17. package/dist/config.js +3 -6
  18. package/dist/config.js.map +1 -1
  19. package/dist/contract/index.d.ts +1 -1
  20. package/dist/contract/index.d.ts.map +1 -1
  21. package/dist/contract/index.js.map +1 -1
  22. package/dist/contract/plugin.d.ts +105 -3
  23. package/dist/contract/plugin.d.ts.map +1 -1
  24. package/dist/contract/plugin.js.map +1 -1
  25. package/dist/contract/validation.d.ts +6 -4
  26. package/dist/contract/validation.d.ts.map +1 -1
  27. package/dist/contract/validation.js.map +1 -1
  28. package/dist/db/db.d.ts +32 -14
  29. package/dist/db/db.d.ts.map +1 -1
  30. package/dist/db/db.js.map +1 -1
  31. package/dist/env.d.ts +1 -1
  32. package/dist/env.d.ts.map +1 -1
  33. package/dist/index.d.ts +3 -3
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +1 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/runtime/index.d.ts +31 -2
  38. package/dist/runtime/index.d.ts.map +1 -1
  39. package/dist/runtime/index.js +63 -2
  40. package/dist/runtime/index.js.map +1 -1
  41. package/dist/subagent/index.d.ts +3 -3
  42. package/dist/subagent/index.js +3 -3
  43. package/dist/subagent/workspace.d.ts +21 -0
  44. package/dist/subagent/workspace.d.ts.map +1 -1
  45. package/dist/subagent/workspace.js +80 -5
  46. package/dist/subagent/workspace.js.map +1 -1
  47. package/dist/subtasks/catalog.d.ts +5 -4
  48. package/dist/subtasks/catalog.d.ts.map +1 -1
  49. package/dist/subtasks/catalog.js +5 -4
  50. package/dist/subtasks/catalog.js.map +1 -1
  51. package/dist/subtasks/delegate.d.ts +2 -1
  52. package/dist/subtasks/delegate.d.ts.map +1 -1
  53. package/dist/subtasks/delegate.js +2 -1
  54. package/dist/subtasks/delegate.js.map +1 -1
  55. package/dist/testing/fake-session.d.ts +1 -1
  56. package/dist/testing/fake-session.d.ts.map +1 -1
  57. package/dist/testing/fake-session.js +1 -1
  58. package/dist/testing/fake-session.js.map +1 -1
  59. package/dist/testing/node.d.ts +23 -0
  60. package/dist/testing/node.d.ts.map +1 -1
  61. package/dist/testing/node.js +23 -0
  62. package/dist/testing/node.js.map +1 -1
  63. package/dist/testing/vcr-spec.d.ts +4 -4
  64. package/dist/testing/vcr-spec.d.ts.map +1 -1
  65. package/dist/testing/vcr-spec.js +32 -11
  66. package/dist/testing/vcr-spec.js.map +1 -1
  67. package/package.json +8 -4
@@ -22,7 +22,8 @@ export declare const DELEGATE_TOOL_NAME = "delegate";
22
22
  * performs this call, durably, outside the inference — so there is nothing for the
23
23
  * SDK to run, and the tool loop halts on the call rather than trying to continue
24
24
  * past it. That is what makes it a *control* tool: unlike the agent's work tools
25
- * (`recall`, `browser_*`, `set_context`), calling it ends the round.
25
+ * (`set_context`, and whatever the installed plugins offer), calling it ends the
26
+ * round.
26
27
  *
27
28
  * Its `inputSchema` is the delegation contract itself, and it is the **only**
28
29
  * declaration of this tool. One schema has to serve both directions — the calls
@@ -1 +1 @@
1
- {"version":3,"file":"delegate.d.ts","sourceRoot":"","sources":["../../src/subtasks/delegate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,IAAI,EAAE,MAAM,IAAI,CAAC;AAErC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,SAAS,EACT,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,kBAAkB,aAAa,CAAC;AAE7C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,mBAAmB,EAC1B,WAAW,EAAE,MAAM,GAClB,IAAI,CAQN;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAExE;AAeD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,qBAAqB,CAavB;AAED,sFAAsF;AACtF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,sBAAsB,EAAE,CAU1B"}
1
+ {"version":3,"file":"delegate.d.ts","sourceRoot":"","sources":["../../src/subtasks/delegate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,IAAI,EAAE,MAAM,IAAI,CAAC;AAErC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,SAAS,EACT,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,kBAAkB,aAAa,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,mBAAmB,EAC1B,WAAW,EAAE,MAAM,GAClB,IAAI,CAQN;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAExE;AAeD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,qBAAqB,CAavB;AAED,sFAAsF;AACtF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,sBAAsB,EAAE,CAU1B"}
@@ -21,7 +21,8 @@ export const DELEGATE_TOOL_NAME = "delegate";
21
21
  * performs this call, durably, outside the inference — so there is nothing for the
22
22
  * SDK to run, and the tool loop halts on the call rather than trying to continue
23
23
  * past it. That is what makes it a *control* tool: unlike the agent's work tools
24
- * (`recall`, `browser_*`, `set_context`), calling it ends the round.
24
+ * (`set_context`, and whatever the installed plugins offer), calling it ends the
25
+ * round.
25
26
  *
26
27
  * Its `inputSchema` is the delegation contract itself, and it is the **only**
27
28
  * declaration of this tool. One schema has to serve both directions — the calls
@@ -1 +1 @@
1
- {"version":3,"file":"delegate.js","sourceRoot":"","sources":["../../src/subtasks/delegate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAa,MAAM,IAAI,CAAC;AACrC,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AASrE;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAE7C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAA0B,EAC1B,WAAmB;IAEnB,OAAO,IAAI,CAAC;QACV,WAAW,EACT,0LAA0L;YAC1L,yFAAyF;YACzF,KAAK,CAAC,WAAW,EAAE;QACrB,WAAW,EAAE,+BAA+B,CAAC,KAAK,EAAE,WAAW,CAAC;KACjE,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,KAAa;IAC9D,OAAO,QAAQ,MAAM,UAAU,KAAK,WAAW,CAAC;AAClD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,aAAa,CAAC,EAAa;IAClC,OAAO,IAAI,EAAE,EAAE,CAAC;AAClB,CAAC;AAoBD;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,QAA6B;IAE7B,OAAO;QACL,KAAK;QACL,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAClC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC;YACzC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC;YAC9C,uEAAuE;YACvE,sEAAsE;YACtE,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,kBAAkB,CAChC,QAA6B;IAE7B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EACJ,MAAM,CAAC,MAAM,KAAK,WAAW;YAC3B,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAChE,CAAC,CAAC,IAAI;KACX,CAAC,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"delegate.js","sourceRoot":"","sources":["../../src/subtasks/delegate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAa,MAAM,IAAI,CAAC;AACrC,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AASrE;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAA0B,EAC1B,WAAmB;IAEnB,OAAO,IAAI,CAAC;QACV,WAAW,EACT,0LAA0L;YAC1L,yFAAyF;YACzF,KAAK,CAAC,WAAW,EAAE;QACrB,WAAW,EAAE,+BAA+B,CAAC,KAAK,EAAE,WAAW,CAAC;KACjE,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,KAAa;IAC9D,OAAO,QAAQ,MAAM,UAAU,KAAK,WAAW,CAAC;AAClD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,aAAa,CAAC,EAAa;IAClC,OAAO,IAAI,EAAE,EAAE,CAAC;AAClB,CAAC;AAoBD;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,QAA6B;IAE7B,OAAO;QACL,KAAK;QACL,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAClC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC;YACzC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC;YAC9C,uEAAuE;YACvE,sEAAsE;YACtE,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,kBAAkB,CAChC,QAA6B;IAE7B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EACJ,MAAM,CAAC,MAAM,KAAK,WAAW;YAC3B,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAChE,CAAC,CAAC,IAAI;KACX,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -15,7 +15,7 @@ import type { SessionLike } from "../agent/session.js";
15
15
  export declare class FakeSession implements SessionLike {
16
16
  messages: SessionMessage[];
17
17
  system: string;
18
- /** Compaction overlays to report — non-empty gates the `recall` tool on. */
18
+ /** Compaction overlays to report — non-empty history has been displaced. */
19
19
  compactions: unknown[];
20
20
  appendMessage(m: SessionMessage): void;
21
21
  getHistory(): Promise<SessionMessage[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"fake-session.d.ts","sourceRoot":"","sources":["../../src/testing/fake-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,qBAAa,WAAY,YAAW,WAAW;IAC7C,QAAQ,EAAE,cAAc,EAAE,CAAM;IAChC,MAAM,SAAsC;IAC5C,4EAA4E;IAC5E,WAAW,EAAE,OAAO,EAAE,CAAM;IAE5B,aAAa,CAAC,CAAC,EAAE,cAAc;IAIzB,UAAU;IAGV,UAAU,CAAC,EAAE,EAAE,MAAM;IAGrB,mBAAmB;IAGnB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAGzB,cAAc;CAGrB"}
1
+ {"version":3,"file":"fake-session.d.ts","sourceRoot":"","sources":["../../src/testing/fake-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,qBAAa,WAAY,YAAW,WAAW;IAC7C,QAAQ,EAAE,cAAc,EAAE,CAAM;IAChC,MAAM,SAAsC;IAC5C,8EAA8E;IAC9E,WAAW,EAAE,OAAO,EAAE,CAAM;IAE5B,aAAa,CAAC,CAAC,EAAE,cAAc;IAIzB,UAAU;IAGV,UAAU,CAAC,EAAE,EAAE,MAAM;IAGrB,mBAAmB;IAGnB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAGzB,cAAc;CAGrB"}
@@ -12,7 +12,7 @@
12
12
  export class FakeSession {
13
13
  messages = [];
14
14
  system = "SOUL BLOCK\n\n## memory\n(empty)";
15
- /** Compaction overlays to report — non-empty gates the `recall` tool on. */
15
+ /** Compaction overlays to report — non-empty history has been displaced. */
16
16
  compactions = [];
17
17
  appendMessage(m) {
18
18
  if (this.messages.some((existing) => existing.id === m.id))
@@ -1 +1 @@
1
- {"version":3,"file":"fake-session.js","sourceRoot":"","sources":["../../src/testing/fake-session.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,WAAW;IACtB,QAAQ,GAAqB,EAAE,CAAC;IAChC,MAAM,GAAG,kCAAkC,CAAC;IAC5C,4EAA4E;IAC5E,WAAW,GAAc,EAAE,CAAC;IAE5B,aAAa,CAAC,CAAiB;QAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YAAE,OAAO;QACnE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;IACxD,CAAC;IACD,KAAK,CAAC,mBAAmB;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF"}
1
+ {"version":3,"file":"fake-session.js","sourceRoot":"","sources":["../../src/testing/fake-session.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,WAAW;IACtB,QAAQ,GAAqB,EAAE,CAAC;IAChC,MAAM,GAAG,kCAAkC,CAAC;IAC5C,8EAA8E;IAC9E,WAAW,GAAc,EAAE,CAAC;IAE5B,aAAa,CAAC,CAAiB;QAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YAAE,OAAO;QACnE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;IACxD,CAAC;IACD,KAAK,CAAC,mBAAmB;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF"}
@@ -12,8 +12,31 @@
12
12
  * ```ts
13
13
  * // vitest.config.ts
14
14
  * import { createVcrAgent } from "@loopingai/core/testing/node";
15
+ *
16
+ * export default defineConfig({
17
+ * plugins: [cloudflareTest({ miniflare: { fetchMock: createVcrAgent({ … }) } })],
18
+ * test: { globalSetup: ["@loopingai/core/testing/vcr-global-setup"] }
19
+ * });
15
20
  * ```
16
21
  *
22
+ * ## Two version constraints, both of which fail unreadably
23
+ *
24
+ * **1. `@cloudflare/vitest-pool-workers` must be `^0.18`.** The recorder is
25
+ * installed as Miniflare's `fetchMock`, and that option **does not exist in
26
+ * Miniflare 5**, which pool `0.19`+ depends on — only `outboundService` remains.
27
+ * On a newer pool the option is silently ignored rather than rejected, so
28
+ * `disableNetConnect()` never takes effect, every request goes to the real
29
+ * network, and each one fails as `internal error; reference = …` naming nothing.
30
+ * That is why the peer range is pinned rather than open.
31
+ *
32
+ * **2. Your `undici` must be the copy Miniflare uses.** `fetchMock` is an undici
33
+ * `MockAgent` and Miniflare validates it against *its own* undici, so two copies
34
+ * in one `node_modules` fail with `Input not instance of MockAgent`. Miniflare
35
+ * pins an exact version (7.28.0 at the time of writing) and this package's
36
+ * `undici` peer range tracks it. Check with
37
+ * `ls node_modules/miniflare/node_modules/undici` — anything there means a
38
+ * second copy, and the fix is to align yours rather than to debug the message.
39
+ *
17
40
  * For the common case — wiring cassette flush/teardown — you do not need this
18
41
  * subpath at all. Point `globalSetup` at
19
42
  * `@loopingai/core/testing/vcr-global-setup`, which is this module's `setup`/
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/testing/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACL,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/testing/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EACL,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -12,8 +12,31 @@
12
12
  * ```ts
13
13
  * // vitest.config.ts
14
14
  * import { createVcrAgent } from "@loopingai/core/testing/node";
15
+ *
16
+ * export default defineConfig({
17
+ * plugins: [cloudflareTest({ miniflare: { fetchMock: createVcrAgent({ … }) } })],
18
+ * test: { globalSetup: ["@loopingai/core/testing/vcr-global-setup"] }
19
+ * });
15
20
  * ```
16
21
  *
22
+ * ## Two version constraints, both of which fail unreadably
23
+ *
24
+ * **1. `@cloudflare/vitest-pool-workers` must be `^0.18`.** The recorder is
25
+ * installed as Miniflare's `fetchMock`, and that option **does not exist in
26
+ * Miniflare 5**, which pool `0.19`+ depends on — only `outboundService` remains.
27
+ * On a newer pool the option is silently ignored rather than rejected, so
28
+ * `disableNetConnect()` never takes effect, every request goes to the real
29
+ * network, and each one fails as `internal error; reference = …` naming nothing.
30
+ * That is why the peer range is pinned rather than open.
31
+ *
32
+ * **2. Your `undici` must be the copy Miniflare uses.** `fetchMock` is an undici
33
+ * `MockAgent` and Miniflare validates it against *its own* undici, so two copies
34
+ * in one `node_modules` fail with `Input not instance of MockAgent`. Miniflare
35
+ * pins an exact version (7.28.0 at the time of writing) and this package's
36
+ * `undici` peer range tracks it. Check with
37
+ * `ls node_modules/miniflare/node_modules/undici` — anything there means a
38
+ * second copy, and the fix is to align yours rather than to debug the message.
39
+ *
17
40
  * For the common case — wiring cassette flush/teardown — you do not need this
18
41
  * subpath at all. Point `globalSetup` at
19
42
  * `@loopingai/core/testing/vcr-global-setup`, which is this module's `setup`/
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/testing/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACL,cAAc,EACd,QAAQ,EACR,QAAQ,EAET,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/testing/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EACL,cAAc,EACd,QAAQ,EACR,QAAQ,EAET,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,9 +1,9 @@
1
1
  import type { RunnerTestCase } from "vitest";
2
2
  /**
3
- * Cassette filename for a test: `kebab(<file rel to test/, minus .spec.ts>)`
4
- * then each describe level then the test name, all kebab-cased and joined by
5
- * `--`, plus `.snapshot.json`. Example:
6
- * `recipes-arc-game-recorded--arc-game-recorded-real-api--starts-a-real-game-and-closes-the-scorecard-on-abort.snapshot.json`.
3
+ * Cassette filename for a test: `kebab(<project-relative path, minus
4
+ * .spec.ts>)` then each describe level then the test name, all kebab-cased and
5
+ * joined by `--`, plus `.snapshot.json`. Example:
6
+ * `test-arc-agi-recorded--arc-recorded-real-api--plays-a-real-game.snapshot.json`.
7
7
  * Exported for debugging / the cassette-rename step.
8
8
  */
9
9
  export declare function cassetteNameFor(task: RunnerTestCase): string;
@@ -1 +1 @@
1
- {"version":3,"file":"vcr-spec.d.ts","sourceRoot":"","sources":["../../src/testing/vcr-spec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,QAAQ,CAAC;AA0B9D;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAc5D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,IAAI,CA8BrC"}
1
+ {"version":3,"file":"vcr-spec.d.ts","sourceRoot":"","sources":["../../src/testing/vcr-spec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,QAAQ,CAAC;AAkD9D;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAW5D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,IAAI,CA8BrC"}
@@ -20,17 +20,38 @@ function isFileTask(suite) {
20
20
  return typeof suite.filepath === "string";
21
21
  }
22
22
  /**
23
- * Cassette filename for a test: `kebab(<file rel to test/, minus .spec.ts>)`
24
- * then each describe level then the test name, all kebab-cased and joined by
25
- * `--`, plus `.snapshot.json`. Example:
26
- * `recipes-arc-game-recorded--arc-game-recorded-real-api--starts-a-real-game-and-closes-the-scorecard-on-abort.snapshot.json`.
23
+ * The spec's path relative to the project root.
24
+ *
25
+ * Vitest already computes this as `file.name`, which is the whole answer: it is
26
+ * stable across machines and checkouts, and it is *unique per spec file*, which
27
+ * is what a cassette name has to be.
28
+ *
29
+ * Deriving it from `filepath` instead — by stripping a leading `test/` or
30
+ * `src/` — got this wrong twice. Splitting on a segment that never matched
31
+ * returned the absolute path unchanged, so a cassette was named after the
32
+ * developer's home directory; and stripping *both* roots collapsed
33
+ * `test/api.spec.ts` and `src/api.spec.ts` onto one name, which for a store
34
+ * keyed solely by filename means one recording silently overwrites the other
35
+ * and playback serves the wrong responses.
36
+ *
37
+ * The fallback is only for a runner that does not populate `name`; a bare
38
+ * filename can still collide, but it is strictly better than an absolute path
39
+ * and nothing here reaches it.
40
+ */
41
+ function relativeSpecPath(file) {
42
+ if (typeof file.name === "string" && file.name !== "")
43
+ return file.name;
44
+ return file.filepath.replace(/\\/g, "/").split("/").pop();
45
+ }
46
+ /**
47
+ * Cassette filename for a test: `kebab(<project-relative path, minus
48
+ * .spec.ts>)` then each describe level then the test name, all kebab-cased and
49
+ * joined by `--`, plus `.snapshot.json`. Example:
50
+ * `test-arc-agi-recorded--arc-recorded-real-api--plays-a-real-game.snapshot.json`.
27
51
  * Exported for debugging / the cassette-rename step.
28
52
  */
29
53
  export function cassetteNameFor(task) {
30
- const rel = task.file.filepath
31
- .split(/[\\/]test[\\/]/)
32
- .pop()
33
- .replace(/\.spec\.ts$/, "");
54
+ const rel = relativeSpecPath(task.file).replace(/\.spec\.ts$/, "");
34
55
  const suites = [];
35
56
  let suite = task.suite;
36
57
  while (suite && !isFileTask(suite)) {
@@ -52,9 +73,9 @@ export function setupRecording() {
52
73
  method: "POST"
53
74
  });
54
75
  if (res.status === 404) {
55
- throw new Error(`No VCR cassette "${cassette}". Record it with \`npm run test:record\` ` +
56
- `(add \`-- -t "${ctx.task.name}"\` to record only this test), which ` +
57
- `needs a real ARC_API_KEY in .env.test.`);
76
+ throw new Error(`No VCR cassette "${cassette}". Record it with \`RECORD=1\` ` +
77
+ `(add \`-t "${ctx.task.name}"\` to record only this test), which needs ` +
78
+ `whatever real credentials the recorded API calls require.`);
58
79
  }
59
80
  if (res.status === 409) {
60
81
  throw new Error(`VCR cassette "${cassette}" could not activate: another recorded test is ` +
@@ -1 +1 @@
1
- {"version":3,"file":"vcr-spec.js","sourceRoot":"","sources":["../../src/testing/vcr-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;;;GAUG;AAEH,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAClC,CAAC;KACE,WAAW,EAAE;KACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;KAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAE7B,kFAAkF;AAClF,SAAS,UAAU,CAAC,KAAsB;IACxC,OAAO,OAAQ,KAA+B,CAAC,QAAQ,KAAK,QAAQ,CAAC;AACvE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAoB;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ;SAC3B,KAAK,CAAC,gBAAgB,CAAC;SACvB,GAAG,EAAG;SACN,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAE9B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAgC,IAAI,CAAC,KAAK,CAAC;IACpD,OAAO,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC;AAC9E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc;IAC5B,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,kBAAkB,iBAAiB,QAAQ,EAAE,EAAE;YACxE,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,oBAAoB,QAAQ,4CAA4C;gBACtE,iBAAiB,GAAG,CAAC,IAAI,CAAC,IAAI,uCAAuC;gBACrE,wCAAwC,CAC3C,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,iBAAiB,QAAQ,iDAAiD;gBACxE,iEAAiE;gBACjE,kCAAkC,CACrC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,mCAAmC,GAAG,CAAC,MAAM,iBAAiB,QAAQ,IAAI,CAC3E,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,KAAK,CAAC,GAAG,kBAAkB,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"vcr-spec.js","sourceRoot":"","sources":["../../src/testing/vcr-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;;;GAUG;AAEH,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAClC,CAAC;KACE,WAAW,EAAE;KACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;KAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAE7B,kFAAkF;AAClF,SAAS,UAAU,CAAC,KAAsB;IACxC,OAAO,OAAQ,KAA+B,CAAC,QAAQ,KAAK,QAAQ,CAAC;AACvE,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAS,gBAAgB,CAAC,IAA4B;IACpD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IACxE,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAoB;IAClD,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAEnE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAgC,IAAI,CAAC,KAAK,CAAC;IACpD,OAAO,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC;AAC9E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc;IAC5B,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,kBAAkB,iBAAiB,QAAQ,EAAE,EAAE;YACxE,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,oBAAoB,QAAQ,iCAAiC;gBAC3D,cAAc,GAAG,CAAC,IAAI,CAAC,IAAI,6CAA6C;gBACxE,2DAA2D,CAC9D,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,iBAAiB,QAAQ,iDAAiD;gBACxE,iEAAiE;gBACjE,kCAAkC,CACrC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,mCAAmC,GAAG,CAAC,MAAM,iBAAiB,QAAQ,IAAI,CAC3E,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,KAAK,CAAC,GAAG,kBAAkB,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopingai/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
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",
@@ -102,13 +102,17 @@
102
102
  "zod": "^4.4.3"
103
103
  },
104
104
  "peerDependencies": {
105
+ "@cloudflare/vitest-pool-workers": "^0.18.8",
105
106
  "agents": "^0.20.0",
106
107
  "ai": "^7.0.40",
107
- "undici": ">=8",
108
+ "undici": "^7.28.0",
108
109
  "vitest": ">=4",
109
110
  "workers-ai-provider": "^4.0.0"
110
111
  },
111
112
  "peerDependenciesMeta": {
113
+ "@cloudflare/vitest-pool-workers": {
114
+ "optional": true
115
+ },
112
116
  "undici": {
113
117
  "optional": true
114
118
  },
@@ -117,7 +121,7 @@
117
121
  }
118
122
  },
119
123
  "devDependencies": {
120
- "@cloudflare/vitest-pool-workers": "^0.20.1",
124
+ "@cloudflare/vitest-pool-workers": "^0.18.8",
121
125
  "@types/node": "^26.1.1",
122
126
  "agents": "^0.20.0",
123
127
  "ai": "^7.0.40",
@@ -126,7 +130,7 @@
126
130
  "prettier": "^3.9.6",
127
131
  "typescript": "^6.0.3",
128
132
  "typescript-eslint": "^8.65.0",
129
- "undici": "8.9.0",
133
+ "undici": "7.28.0",
130
134
  "vitest": "^4.1.10",
131
135
  "workers-ai-provider": "^4.0.0",
132
136
  "wrangler": "^4.114.0"