@effect-uai/core 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/{AiError-CrdR1EQi.d.mts → AiError-Bf1pq4BB.d.mts} +8 -3
  2. package/dist/{AiError-CrdR1EQi.d.mts.map → AiError-Bf1pq4BB.d.mts.map} +1 -1
  3. package/dist/{Audio-DDSKCkSe.d.mts → Audio-CR7CSljJ.d.mts} +2 -2
  4. package/dist/{Audio-DDSKCkSe.d.mts.map → Audio-CR7CSljJ.d.mts.map} +1 -1
  5. package/dist/{Image-C_Zjpwhc.d.mts → Image-BZmKfIdq.d.mts} +2 -2
  6. package/dist/{Image-C_Zjpwhc.d.mts.map → Image-BZmKfIdq.d.mts.map} +1 -1
  7. package/dist/{Items-CgKD6Npw.d.mts → Items-BnIduEV2.d.mts} +9 -9
  8. package/dist/{Items-CgKD6Npw.d.mts.map → Items-BnIduEV2.d.mts.map} +1 -1
  9. package/dist/{Loop-B5_cqumi.d.mts → Loop-D8nWpowc.d.mts} +2 -2
  10. package/dist/{Loop-B5_cqumi.d.mts.map → Loop-D8nWpowc.d.mts.map} +1 -1
  11. package/dist/{Media-DOLyaygI.d.mts → Media-D_CpcM1Z.d.mts} +1 -1
  12. package/dist/{Media-DOLyaygI.d.mts.map → Media-D_CpcM1Z.d.mts.map} +1 -1
  13. package/dist/{StructuredFormat-CMJFD3sn.d.mts → StructuredFormat-DHaUJBdd.d.mts} +1 -1
  14. package/dist/{StructuredFormat-CMJFD3sn.d.mts.map → StructuredFormat-DHaUJBdd.d.mts.map} +1 -1
  15. package/dist/{Tool-0XUIT2A2.d.mts → Tool-2lC_XMth.d.mts} +64 -12
  16. package/dist/Tool-2lC_XMth.d.mts.map +1 -0
  17. package/dist/{ToolEvent-DYrAUJGs.d.mts → ToolEvent-cWZ2BnbS.d.mts} +2 -2
  18. package/dist/ToolEvent-cWZ2BnbS.d.mts.map +1 -0
  19. package/dist/{ToolResult-BZd-cEWW.d.mts → ToolResult-CL4hK_9z.d.mts} +10 -4
  20. package/dist/ToolResult-CL4hK_9z.d.mts.map +1 -0
  21. package/dist/{Toolkit-BKC8b8Xo.d.mts → Toolkit-Dr9l_hNy.d.mts} +64 -23
  22. package/dist/Toolkit-Dr9l_hNy.d.mts.map +1 -0
  23. package/dist/browser/Browser.d.mts +190 -0
  24. package/dist/browser/Browser.d.mts.map +1 -0
  25. package/dist/browser/Browser.mjs +34 -0
  26. package/dist/browser/Browser.mjs.map +1 -0
  27. package/dist/browser/BrowserError.d.mts +141 -0
  28. package/dist/browser/BrowserError.d.mts.map +1 -0
  29. package/dist/browser/BrowserError.mjs +89 -0
  30. package/dist/browser/BrowserError.mjs.map +1 -0
  31. package/dist/browser/BrowserTool.d.mts +58 -0
  32. package/dist/browser/BrowserTool.d.mts.map +1 -0
  33. package/dist/browser/BrowserTool.mjs +86 -0
  34. package/dist/browser/BrowserTool.mjs.map +1 -0
  35. package/dist/domain/AiError.d.mts +2 -2
  36. package/dist/domain/AiError.mjs +22 -3
  37. package/dist/domain/AiError.mjs.map +1 -1
  38. package/dist/domain/Audio.d.mts +1 -1
  39. package/dist/domain/Image.d.mts +1 -1
  40. package/dist/domain/Items.d.mts +1 -1
  41. package/dist/domain/Media.d.mts +1 -1
  42. package/dist/domain/Music.d.mts +1 -1
  43. package/dist/domain/Turn.d.mts +3 -3
  44. package/dist/embedding-model/Embedding.d.mts +1 -1
  45. package/dist/embedding-model/EmbeddingModel.d.mts +1 -1
  46. package/dist/index.d.mts +17 -12
  47. package/dist/index.mjs +14 -9
  48. package/dist/language-model/LanguageModel.d.mts +4 -4
  49. package/dist/loop/Loop.d.mts +1 -1
  50. package/dist/music-generator/MusicGenerator.d.mts +2 -2
  51. package/dist/observability/Metrics.d.mts +1 -1
  52. package/dist/retry/Retry.d.mts +1 -1
  53. package/dist/speech-synthesizer/SpeechSynthesizer.d.mts +2 -2
  54. package/dist/structured-format/StructuredFormat.d.mts +1 -1
  55. package/dist/testing/MockMusicGenerator.d.mts +1 -1
  56. package/dist/testing/MockProvider.d.mts +1 -1
  57. package/dist/testing/MockSpeechSynthesizer.d.mts +1 -1
  58. package/dist/tool/Approval.d.mts +19 -7
  59. package/dist/tool/Approval.d.mts.map +1 -1
  60. package/dist/tool/Approval.mjs +18 -11
  61. package/dist/tool/Approval.mjs.map +1 -1
  62. package/dist/tool/Approval.test.mjs +46 -7
  63. package/dist/tool/Approval.test.mjs.map +1 -1
  64. package/dist/tool/HistoryCheck.d.mts +2 -2
  65. package/dist/tool/Tool.d.mts +2 -2
  66. package/dist/tool/Tool.mjs +86 -22
  67. package/dist/tool/Tool.mjs.map +1 -1
  68. package/dist/tool/ToolEvent.d.mts +1 -1
  69. package/dist/tool/ToolEvent.mjs +5 -0
  70. package/dist/tool/ToolEvent.mjs.map +1 -1
  71. package/dist/tool/ToolResult.d.mts +2 -2
  72. package/dist/tool/ToolResult.mjs +15 -6
  73. package/dist/tool/ToolResult.mjs.map +1 -1
  74. package/dist/tool/Toolkit.d.mts +2 -2
  75. package/dist/tool/Toolkit.mjs +62 -22
  76. package/dist/tool/Toolkit.mjs.map +1 -1
  77. package/dist/tool/Toolkit.test.mjs +163 -9
  78. package/dist/tool/Toolkit.test.mjs.map +1 -1
  79. package/dist/transcriber/Transcriber.d.mts +2 -2
  80. package/dist/web-read/WebRead.d.mts +44 -0
  81. package/dist/web-read/WebRead.d.mts.map +1 -0
  82. package/dist/web-read/WebRead.mjs +18 -0
  83. package/dist/web-read/WebRead.mjs.map +1 -0
  84. package/dist/web-read/WebReadTool.d.mts +57 -0
  85. package/dist/web-read/WebReadTool.d.mts.map +1 -0
  86. package/dist/web-read/WebReadTool.mjs +59 -0
  87. package/dist/web-read/WebReadTool.mjs.map +1 -0
  88. package/dist/web-search/WebSearch.d.mts +1 -1
  89. package/dist/web-search/WebSearchTool.d.mts +12 -6
  90. package/dist/web-search/WebSearchTool.d.mts.map +1 -1
  91. package/dist/web-search/WebSearchTool.mjs +10 -5
  92. package/dist/web-search/WebSearchTool.mjs.map +1 -1
  93. package/package.json +21 -1
  94. package/src/browser/Browser.ts +268 -0
  95. package/src/browser/BrowserError.ts +145 -0
  96. package/src/browser/BrowserTool.ts +161 -0
  97. package/src/domain/AiError.ts +27 -1
  98. package/src/index.ts +5 -0
  99. package/src/tool/Approval.test.ts +55 -5
  100. package/src/tool/Approval.ts +72 -27
  101. package/src/tool/Tool.ts +146 -47
  102. package/src/tool/ToolEvent.ts +5 -0
  103. package/src/tool/ToolResult.ts +14 -8
  104. package/src/tool/Toolkit.test.ts +171 -2
  105. package/src/tool/Toolkit.ts +173 -60
  106. package/src/web-read/WebRead.ts +70 -0
  107. package/src/web-read/WebReadTool.ts +96 -0
  108. package/src/web-search/WebSearchTool.ts +11 -5
  109. package/dist/Tool-0XUIT2A2.d.mts.map +0 -1
  110. package/dist/ToolEvent-DYrAUJGs.d.mts.map +0 -1
  111. package/dist/ToolResult-BZd-cEWW.d.mts.map +0 -1
  112. package/dist/Toolkit-BKC8b8Xo.d.mts.map +0 -1
@@ -0,0 +1,86 @@
1
+ import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
2
+ import { fromEffectSchema, make } from "../tool/Tool.mjs";
3
+ import { make as make$1 } from "../tool/Toolkit.mjs";
4
+ import { Effect, Schema } from "effect";
5
+ //#region src/browser/BrowserTool.ts
6
+ var BrowserTool_exports = /* @__PURE__ */ __exportAll({
7
+ browserToolkit: () => browserToolkit,
8
+ clickTool: () => clickTool,
9
+ fillTool: () => fillTool,
10
+ gotoTool: () => gotoTool,
11
+ pressTool: () => pressTool,
12
+ scrollTool: () => scrollTool
13
+ });
14
+ const GotoArgs = Schema.Struct({ url: Schema.String.annotate({ description: "Absolute URL to navigate to." }) });
15
+ const ClickArgs = Schema.Struct({ ref: Schema.String.annotate({ description: "A CSS selector, or an element @ref if a page-reading tool provides one." }) });
16
+ const FillArgs = Schema.Struct({
17
+ ref: Schema.String.annotate({ description: "A CSS selector (or element @ref) of the input to fill." }),
18
+ text: Schema.String.annotate({ description: "The text to put in the input." })
19
+ });
20
+ const PressArgs = Schema.Struct({ key: Schema.String.annotate({ description: "Key to press, e.g. \"Enter\" to submit the focused input, \"Tab\", \"Escape\"." }) });
21
+ const ScrollArgs = Schema.Struct({ direction: Schema.Literals(["up", "down"]).annotate({ description: "Scroll the viewport up or down." }) });
22
+ const currentUrl = (session) => session.evaluate("location.href").pipe(Effect.flatMap(Schema.decodeUnknownEffect(Schema.String)), Effect.orElseSucceed(() => "(unknown)"));
23
+ const okAt = (session) => Effect.map(currentUrl(session), (url) => `ok (now at ${url})`);
24
+ const gotoTool = (session) => make({
25
+ name: "browser_goto",
26
+ description: "Navigate the browser to an absolute URL.",
27
+ inputSchema: fromEffectSchema(GotoArgs),
28
+ run: (args) => Effect.andThen(session.goto(args.url), okAt(session)).pipe(Effect.withSpan("browser_goto", {
29
+ kind: "client",
30
+ attributes: { "browser.url": args.url }
31
+ }))
32
+ });
33
+ const clickTool = (session) => make({
34
+ name: "browser_click",
35
+ description: "Click the element named by ref. A click may navigate to a new page.",
36
+ inputSchema: fromEffectSchema(ClickArgs),
37
+ run: (args) => Effect.andThen(session.click(args.ref), okAt(session)).pipe(Effect.withSpan("browser_click", {
38
+ kind: "client",
39
+ attributes: { "browser.ref": args.ref }
40
+ }))
41
+ });
42
+ const fillTool = (session) => make({
43
+ name: "browser_fill",
44
+ description: "Put text into the input named by ref. Filling alone does not submit; press Enter to submit the input.",
45
+ inputSchema: fromEffectSchema(FillArgs),
46
+ run: (args) => Effect.andThen(session.fill(args.ref, args.text), okAt(session)).pipe(Effect.withSpan("browser_fill", {
47
+ kind: "client",
48
+ attributes: { "browser.ref": args.ref }
49
+ }))
50
+ });
51
+ const pressTool = (session) => make({
52
+ name: "browser_press",
53
+ description: "Press a keyboard key against the focused element.",
54
+ inputSchema: fromEffectSchema(PressArgs),
55
+ run: (args) => Effect.andThen(session.press(args.key), okAt(session)).pipe(Effect.withSpan("browser_press", {
56
+ kind: "client",
57
+ attributes: { "browser.key": args.key }
58
+ }))
59
+ });
60
+ const scrollTool = (session) => make({
61
+ name: "browser_scroll",
62
+ description: "Scroll the viewport. Only useful to bring an element into view - a page-reading tool's text is already scroll-independent.",
63
+ inputSchema: fromEffectSchema(ScrollArgs),
64
+ run: (args) => Effect.andThen(session.scroll({ direction: args.direction }), okAt(session)).pipe(Effect.withSpan("browser_scroll", {
65
+ kind: "client",
66
+ attributes: { "browser.direction": args.direction }
67
+ }))
68
+ });
69
+ /**
70
+ * The canonical browser action verbs bundled as a `Toolkit`, closed over a
71
+ * live `BrowserSession`. Compose it with a recipe-local page-reading tool and
72
+ * whatever finish/signal tools the agent needs:
73
+ *
74
+ * const toolkit = yield* Toolkit.compose(
75
+ * browserToolkit(session),
76
+ * Toolkit.make(readPageTool(session), finishTool),
77
+ * )
78
+ *
79
+ * For an à-la-carte subset, use the individual `gotoTool` / `clickTool` / …
80
+ * constructors directly. Run a turn's calls with `{ concurrency: 1 }`.
81
+ */
82
+ const browserToolkit = (session) => make$1(gotoTool(session), clickTool(session), fillTool(session), pressTool(session), scrollTool(session));
83
+ //#endregion
84
+ export { browserToolkit, clickTool, fillTool, gotoTool, pressTool, scrollTool, BrowserTool_exports as t };
85
+
86
+ //# sourceMappingURL=BrowserTool.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserTool.mjs","names":["Tool.make","Tool.fromEffectSchema","Toolkit.make"],"sources":["../../src/browser/BrowserTool.ts"],"sourcesContent":["import { Effect, Schema } from \"effect\"\nimport * as Tool from \"../tool/Tool.js\"\nimport * as Toolkit from \"../tool/Toolkit.js\"\nimport type { BrowserSession } from \"./Browser.js\"\n\n// ---------------------------------------------------------------------------\n// Model-facing argument schemas. Annotated so the descriptions reach the\n// model through the rendered JSON Schema (JSDoc does not).\n// ---------------------------------------------------------------------------\n\nconst GotoArgs = Schema.Struct({\n url: Schema.String.annotate({ description: \"Absolute URL to navigate to.\" }),\n})\n\nconst ClickArgs = Schema.Struct({\n ref: Schema.String.annotate({\n description: \"A CSS selector, or an element @ref if a page-reading tool provides one.\",\n }),\n})\n\nconst FillArgs = Schema.Struct({\n ref: Schema.String.annotate({\n description: \"A CSS selector (or element @ref) of the input to fill.\",\n }),\n text: Schema.String.annotate({ description: \"The text to put in the input.\" }),\n})\n\nconst PressArgs = Schema.Struct({\n key: Schema.String.annotate({\n description: 'Key to press, e.g. \"Enter\" to submit the focused input, \"Tab\", \"Escape\".',\n }),\n})\n\nconst ScrollArgs = Schema.Struct({\n direction: Schema.Literals([\"up\", \"down\"]).annotate({\n description: \"Scroll the viewport up or down.\",\n }),\n})\n\n// ---------------------------------------------------------------------------\n// Uniform action outcome: the model always learns where the action left it.\n// ---------------------------------------------------------------------------\n\nconst currentUrl = (session: BrowserSession): Effect.Effect<string> =>\n session.evaluate(\"location.href\").pipe(\n Effect.flatMap(Schema.decodeUnknownEffect(Schema.String)),\n Effect.orElseSucceed(() => \"(unknown)\"),\n )\n\nconst okAt = (session: BrowserSession): Effect.Effect<string> =>\n Effect.map(currentUrl(session), (url) => `ok (now at ${url})`)\n\n// ---------------------------------------------------------------------------\n// The canonical browser action tools, each closed over a live `BrowserSession`\n// and failing with the full `BrowserError`. `Output` is a compact outcome\n// (`ok (now at <url>)`), not a page dump - a page-reading tool is the recipe's\n// to define, so history does not accumulate a full page per action.\n//\n// A failed action (stale ref, dead control, timeout) fails typed on the error\n// channel. Whether the model gets to recover from it is the loop's decision:\n// wrap the toolkit in `Toolkit.describeFailures(BrowserError.describe)` to\n// surface failures to the model, or map selectively to keep session/infra\n// errors (e.g. `BrowserSessionExpired`) fatal.\n//\n// Browser actions are order-dependent (fill, then press Enter): run a turn's\n// calls with `{ concurrency: 1 }`.\n// ---------------------------------------------------------------------------\n\nexport const gotoTool = (session: BrowserSession) =>\n Tool.make({\n name: \"browser_goto\",\n description: \"Navigate the browser to an absolute URL.\",\n inputSchema: Tool.fromEffectSchema(GotoArgs),\n run: (args) =>\n Effect.andThen(session.goto(args.url), okAt(session)).pipe(\n Effect.withSpan(\"browser_goto\", {\n kind: \"client\",\n attributes: { \"browser.url\": args.url },\n }),\n ),\n })\n\nexport const clickTool = (session: BrowserSession) =>\n Tool.make({\n name: \"browser_click\",\n description: \"Click the element named by ref. A click may navigate to a new page.\",\n inputSchema: Tool.fromEffectSchema(ClickArgs),\n run: (args) =>\n Effect.andThen(session.click(args.ref), okAt(session)).pipe(\n Effect.withSpan(\"browser_click\", {\n kind: \"client\",\n attributes: { \"browser.ref\": args.ref },\n }),\n ),\n })\n\nexport const fillTool = (session: BrowserSession) =>\n Tool.make({\n name: \"browser_fill\",\n description:\n \"Put text into the input named by ref. Filling alone does not submit; press Enter to submit the input.\",\n inputSchema: Tool.fromEffectSchema(FillArgs),\n run: (args) =>\n Effect.andThen(session.fill(args.ref, args.text), okAt(session)).pipe(\n Effect.withSpan(\"browser_fill\", {\n kind: \"client\",\n attributes: { \"browser.ref\": args.ref },\n }),\n ),\n })\n\nexport const pressTool = (session: BrowserSession) =>\n Tool.make({\n name: \"browser_press\",\n description: \"Press a keyboard key against the focused element.\",\n inputSchema: Tool.fromEffectSchema(PressArgs),\n run: (args) =>\n Effect.andThen(session.press(args.key), okAt(session)).pipe(\n Effect.withSpan(\"browser_press\", {\n kind: \"client\",\n attributes: { \"browser.key\": args.key },\n }),\n ),\n })\n\nexport const scrollTool = (session: BrowserSession) =>\n Tool.make({\n name: \"browser_scroll\",\n description:\n \"Scroll the viewport. Only useful to bring an element into view - a page-reading tool's text is already scroll-independent.\",\n inputSchema: Tool.fromEffectSchema(ScrollArgs),\n run: (args) =>\n Effect.andThen(session.scroll({ direction: args.direction }), okAt(session)).pipe(\n Effect.withSpan(\"browser_scroll\", {\n kind: \"client\",\n attributes: { \"browser.direction\": args.direction },\n }),\n ),\n })\n\n/**\n * The canonical browser action verbs bundled as a `Toolkit`, closed over a\n * live `BrowserSession`. Compose it with a recipe-local page-reading tool and\n * whatever finish/signal tools the agent needs:\n *\n * const toolkit = yield* Toolkit.compose(\n * browserToolkit(session),\n * Toolkit.make(readPageTool(session), finishTool),\n * )\n *\n * For an à-la-carte subset, use the individual `gotoTool` / `clickTool` / …\n * constructors directly. Run a turn's calls with `{ concurrency: 1 }`.\n */\nexport const browserToolkit = (session: BrowserSession) =>\n Toolkit.make(\n gotoTool(session),\n clickTool(session),\n fillTool(session),\n pressTool(session),\n scrollTool(session),\n )\n"],"mappings":";;;;;;;;;;;;;AAUA,MAAM,WAAW,OAAO,OAAO,EAC7B,KAAK,OAAO,OAAO,SAAS,EAAE,aAAa,gCAAgC,CAAC,EAC7E,CAAC;AAEF,MAAM,YAAY,OAAO,OAAO,EAC9B,KAAK,OAAO,OAAO,SAAS,EAC1B,aAAa,2EACd,CAAC,EACH,CAAC;AAEF,MAAM,WAAW,OAAO,OAAO;CAC7B,KAAK,OAAO,OAAO,SAAS,EAC1B,aAAa,0DACd,CAAC;CACF,MAAM,OAAO,OAAO,SAAS,EAAE,aAAa,iCAAiC,CAAC;CAC/E,CAAC;AAEF,MAAM,YAAY,OAAO,OAAO,EAC9B,KAAK,OAAO,OAAO,SAAS,EAC1B,aAAa,kFACd,CAAC,EACH,CAAC;AAEF,MAAM,aAAa,OAAO,OAAO,EAC/B,WAAW,OAAO,SAAS,CAAC,MAAM,OAAO,CAAC,CAAC,SAAS,EAClD,aAAa,mCACd,CAAC,EACH,CAAC;AAMF,MAAM,cAAc,YAClB,QAAQ,SAAS,gBAAgB,CAAC,KAChC,OAAO,QAAQ,OAAO,oBAAoB,OAAO,OAAO,CAAC,EACzD,OAAO,oBAAoB,YAAY,CACxC;AAEH,MAAM,QAAQ,YACZ,OAAO,IAAI,WAAW,QAAQ,GAAG,QAAQ,cAAc,IAAI,GAAG;AAkBhE,MAAa,YAAY,YACvBA,KAAU;CACR,MAAM;CACN,aAAa;CACb,aAAaC,iBAAsB,SAAS;CAC5C,MAAM,SACJ,OAAO,QAAQ,QAAQ,KAAK,KAAK,IAAI,EAAE,KAAK,QAAQ,CAAC,CAAC,KACpD,OAAO,SAAS,gBAAgB;EAC9B,MAAM;EACN,YAAY,EAAE,eAAe,KAAK,KAAK;EACxC,CAAC,CACH;CACJ,CAAC;AAEJ,MAAa,aAAa,YACxBD,KAAU;CACR,MAAM;CACN,aAAa;CACb,aAAaC,iBAAsB,UAAU;CAC7C,MAAM,SACJ,OAAO,QAAQ,QAAQ,MAAM,KAAK,IAAI,EAAE,KAAK,QAAQ,CAAC,CAAC,KACrD,OAAO,SAAS,iBAAiB;EAC/B,MAAM;EACN,YAAY,EAAE,eAAe,KAAK,KAAK;EACxC,CAAC,CACH;CACJ,CAAC;AAEJ,MAAa,YAAY,YACvBD,KAAU;CACR,MAAM;CACN,aACE;CACF,aAAaC,iBAAsB,SAAS;CAC5C,MAAM,SACJ,OAAO,QAAQ,QAAQ,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE,KAAK,QAAQ,CAAC,CAAC,KAC/D,OAAO,SAAS,gBAAgB;EAC9B,MAAM;EACN,YAAY,EAAE,eAAe,KAAK,KAAK;EACxC,CAAC,CACH;CACJ,CAAC;AAEJ,MAAa,aAAa,YACxBD,KAAU;CACR,MAAM;CACN,aAAa;CACb,aAAaC,iBAAsB,UAAU;CAC7C,MAAM,SACJ,OAAO,QAAQ,QAAQ,MAAM,KAAK,IAAI,EAAE,KAAK,QAAQ,CAAC,CAAC,KACrD,OAAO,SAAS,iBAAiB;EAC/B,MAAM;EACN,YAAY,EAAE,eAAe,KAAK,KAAK;EACxC,CAAC,CACH;CACJ,CAAC;AAEJ,MAAa,cAAc,YACzBD,KAAU;CACR,MAAM;CACN,aACE;CACF,aAAaC,iBAAsB,WAAW;CAC9C,MAAM,SACJ,OAAO,QAAQ,QAAQ,OAAO,EAAE,WAAW,KAAK,WAAW,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,KAC3E,OAAO,SAAS,kBAAkB;EAChC,MAAM;EACN,YAAY,EAAE,qBAAqB,KAAK,WAAW;EACpD,CAAC,CACH;CACJ,CAAC;;;;;;;;;;;;;;AAeJ,MAAa,kBAAkB,YAC7BC,OACE,SAAS,QAAQ,EACjB,UAAU,QAAQ,EAClB,SAAS,QAAQ,EACjB,UAAU,QAAQ,EAClB,WAAW,QAAQ,CACpB"}
@@ -1,2 +1,2 @@
1
- import { a as Cancelled, c as GenerationFailed, d as RateLimited, f as Scope, h as Unsupported, i as AuthSubtype, l as IncompleteTurn, m as Unavailable, o as ContentFiltered, p as Timeout, r as AuthFailed, s as ContextLengthExceeded, t as AiError, u as InvalidRequest } from "../AiError-CrdR1EQi.mjs";
2
- export { AiError, AuthFailed, AuthSubtype, Cancelled, ContentFiltered, ContextLengthExceeded, GenerationFailed, IncompleteTurn, InvalidRequest, RateLimited, Scope, Timeout, Unavailable, Unsupported };
1
+ import { a as Cancelled, c as GenerationFailed, d as RateLimited, f as Scope, g as describe, h as Unsupported, i as AuthSubtype, l as IncompleteTurn, m as Unavailable, o as ContentFiltered, p as Timeout, r as AuthFailed, s as ContextLengthExceeded, t as AiError, u as InvalidRequest } from "../AiError-Bf1pq4BB.mjs";
2
+ export { AiError, AuthFailed, AuthSubtype, Cancelled, ContentFiltered, ContextLengthExceeded, GenerationFailed, IncompleteTurn, InvalidRequest, RateLimited, Scope, Timeout, Unavailable, Unsupported, describe };
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
2
- import { Data } from "effect";
2
+ import { Data, Match } from "effect";
3
3
  //#region src/domain/AiError.ts
4
4
  var AiError_exports = /* @__PURE__ */ __exportAll({
5
5
  AuthFailed: () => AuthFailed,
@@ -12,7 +12,8 @@ var AiError_exports = /* @__PURE__ */ __exportAll({
12
12
  RateLimited: () => RateLimited,
13
13
  Timeout: () => Timeout,
14
14
  Unavailable: () => Unavailable,
15
- Unsupported: () => Unsupported
15
+ Unsupported: () => Unsupported,
16
+ describe: () => describe
16
17
  });
17
18
  var RateLimited = class extends Data.TaggedError("RateLimited") {};
18
19
  var Unavailable = class extends Data.TaggedError("Unavailable") {};
@@ -50,7 +51,25 @@ var IncompleteTurn = class extends Data.TaggedError("IncompleteTurn") {};
50
51
  * (`TtsIncrementalText`, `SttStreaming`) on the R channel instead.
51
52
  */
52
53
  var Unsupported = class extends Data.TaggedError("Unsupported") {};
54
+ const withReason = (base, reason) => reason === void 0 ? base : `${base}: ${reason}`;
55
+ /**
56
+ * Short human-readable description of an error, for logs and model-facing
57
+ * failure messages. Prose, not a contract; branch on `_tag` instead.
58
+ */
59
+ const describe = Match.type().pipe(Match.discriminatorsExhaustive("_tag")({
60
+ RateLimited: (e) => `rate limited by ${e.provider}; try again later`,
61
+ Unavailable: (e) => `${e.provider} is temporarily unavailable`,
62
+ Timeout: (e) => `the ${e.provider} request timed out`,
63
+ ContentFiltered: (e) => withReason(`blocked by ${e.provider}'s content filter`, e.reason),
64
+ ContextLengthExceeded: (e) => `the request exceeded ${e.provider}'s context limit`,
65
+ InvalidRequest: (e) => e.param === void 0 ? `${e.provider} rejected the request` : `${e.provider} rejected the request (param: ${e.param})`,
66
+ AuthFailed: (e) => `authentication against ${e.provider} failed (${e.subtype})`,
67
+ Cancelled: (e) => `the ${e.provider} request was cancelled`,
68
+ IncompleteTurn: () => "the provider stream ended without completing",
69
+ GenerationFailed: (e) => e.message ?? `${e.provider} failed mid-generation`,
70
+ Unsupported: (e) => withReason(`${e.provider} does not support ${e.capability}`, e.reason)
71
+ }));
53
72
  //#endregion
54
- export { AuthFailed, Cancelled, ContentFiltered, ContextLengthExceeded, GenerationFailed, IncompleteTurn, InvalidRequest, RateLimited, Timeout, Unavailable, Unsupported, AiError_exports as t };
73
+ export { AuthFailed, Cancelled, ContentFiltered, ContextLengthExceeded, GenerationFailed, IncompleteTurn, InvalidRequest, RateLimited, Timeout, Unavailable, Unsupported, describe, AiError_exports as t };
55
74
 
56
75
  //# sourceMappingURL=AiError.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"AiError.mjs","names":[],"sources":["../../src/domain/AiError.ts"],"sourcesContent":["import { Data, Duration } from \"effect\"\n\nexport type Scope = \"rpm\" | \"tpm\" | \"rpd\" | \"tpd\"\n\nexport class RateLimited extends Data.TaggedError(\"RateLimited\")<{\n provider: string\n retryAfter?: Duration.Duration\n scope?: Scope\n requestId?: string\n raw: unknown\n}> {}\n\nexport class Unavailable extends Data.TaggedError(\"Unavailable\")<{\n provider: string\n retryAfter?: Duration.Duration\n status?: number\n requestId?: string\n raw: unknown\n}> {}\n\nexport class Timeout extends Data.TaggedError(\"Timeout\")<{\n provider: string\n requestId?: string\n raw: unknown\n}> {}\n\nexport class ContentFiltered extends Data.TaggedError(\"ContentFiltered\")<{\n provider: string\n reason?: string\n requestId?: string\n raw: unknown\n}> {}\n\nexport class ContextLengthExceeded extends Data.TaggedError(\"ContextLengthExceeded\")<{\n provider: string\n modelLimit?: number\n requested?: number\n raw: unknown\n}> {}\n\nexport class InvalidRequest extends Data.TaggedError(\"InvalidRequest\")<{\n provider: string\n param?: string\n requestId?: string\n raw: unknown\n}> {}\n\nexport type AuthSubtype = \"auth\" | \"permission\" | \"billing\" | \"quota\"\n\nexport class AuthFailed extends Data.TaggedError(\"AuthFailed\")<{\n provider: string\n subtype: AuthSubtype\n raw: unknown\n}> {}\n\nexport class Cancelled extends Data.TaggedError(\"Cancelled\")<{\n provider: string\n}> {}\n\n/**\n * The model errored mid-generation. Distinct from `Unavailable` (transport\n * problem before generation started) and from `IncompleteTurn` (provider\n * stream ended without a terminal event). The provider's own error message,\n * if any, is on `message`.\n */\nexport class GenerationFailed extends Data.TaggedError(\"GenerationFailed\")<{\n provider: string\n code?: string\n message?: string\n requestId?: string\n raw: unknown\n}> {}\n\n/**\n * The provider's delta stream ended without a terminal `TurnComplete`.\n * Indicates a misbehaving provider or a connection that dropped mid-flight.\n * Non-terminal deltas seen so far have already been emitted downstream.\n */\nexport class IncompleteTurn extends Data.TaggedError(\"IncompleteTurn\")<{\n raw?: unknown\n}> {}\n\n/**\n * The provider does not implement the requested capability for this\n * specific request. Distinct from `InvalidRequest` (the request shape is\n * malformed) and `AuthFailed` (the request was rejected).\n *\n * Reserved for request-data-dependent gaps where the provider supports\n * the method in general but not for these inputs — e.g. Google's\n * `streamSynthesisFrom` works only for Chirp 3 HD voices; calling it\n * with a Neural2 voice ID fails `Unsupported`.\n *\n * Blanket provider-level gaps (e.g. OpenAI has no incremental-text-in\n * TTS at all) are gated at compile time via capability marker tags\n * (`TtsIncrementalText`, `SttStreaming`) on the R channel instead.\n */\nexport class Unsupported extends Data.TaggedError(\"Unsupported\")<{\n provider: string\n capability: string\n reason?: string\n}> {}\n\nexport type AiError =\n | RateLimited\n | Unavailable\n | Timeout\n | ContentFiltered\n | ContextLengthExceeded\n | InvalidRequest\n | AuthFailed\n | Cancelled\n | IncompleteTurn\n | GenerationFailed\n | Unsupported\n"],"mappings":";;;;;;;;;;;;;;;;AAIA,IAAa,cAAb,cAAiC,KAAK,YAAY,cAAc,CAM7D;AAEH,IAAa,cAAb,cAAiC,KAAK,YAAY,cAAc,CAM7D;AAEH,IAAa,UAAb,cAA6B,KAAK,YAAY,UAAU,CAIrD;AAEH,IAAa,kBAAb,cAAqC,KAAK,YAAY,kBAAkB,CAKrE;AAEH,IAAa,wBAAb,cAA2C,KAAK,YAAY,wBAAwB,CAKjF;AAEH,IAAa,iBAAb,cAAoC,KAAK,YAAY,iBAAiB,CAKnE;AAIH,IAAa,aAAb,cAAgC,KAAK,YAAY,aAAa,CAI3D;AAEH,IAAa,YAAb,cAA+B,KAAK,YAAY,YAAY,CAEzD;;;;;;;AAQH,IAAa,mBAAb,cAAsC,KAAK,YAAY,mBAAmB,CAMvE;;;;;;AAOH,IAAa,iBAAb,cAAoC,KAAK,YAAY,iBAAiB,CAEnE;;;;;;;;;;;;;;;AAgBH,IAAa,cAAb,cAAiC,KAAK,YAAY,cAAc,CAI7D"}
1
+ {"version":3,"file":"AiError.mjs","names":[],"sources":["../../src/domain/AiError.ts"],"sourcesContent":["import { Data, Duration, Match } from \"effect\"\n\nexport type Scope = \"rpm\" | \"tpm\" | \"rpd\" | \"tpd\"\n\nexport class RateLimited extends Data.TaggedError(\"RateLimited\")<{\n provider: string\n retryAfter?: Duration.Duration\n scope?: Scope\n requestId?: string\n raw: unknown\n}> {}\n\nexport class Unavailable extends Data.TaggedError(\"Unavailable\")<{\n provider: string\n retryAfter?: Duration.Duration\n status?: number\n requestId?: string\n raw: unknown\n}> {}\n\nexport class Timeout extends Data.TaggedError(\"Timeout\")<{\n provider: string\n requestId?: string\n raw: unknown\n}> {}\n\nexport class ContentFiltered extends Data.TaggedError(\"ContentFiltered\")<{\n provider: string\n reason?: string\n requestId?: string\n raw: unknown\n}> {}\n\nexport class ContextLengthExceeded extends Data.TaggedError(\"ContextLengthExceeded\")<{\n provider: string\n modelLimit?: number\n requested?: number\n raw: unknown\n}> {}\n\nexport class InvalidRequest extends Data.TaggedError(\"InvalidRequest\")<{\n provider: string\n param?: string\n requestId?: string\n raw: unknown\n}> {}\n\nexport type AuthSubtype = \"auth\" | \"permission\" | \"billing\" | \"quota\"\n\nexport class AuthFailed extends Data.TaggedError(\"AuthFailed\")<{\n provider: string\n subtype: AuthSubtype\n raw: unknown\n}> {}\n\nexport class Cancelled extends Data.TaggedError(\"Cancelled\")<{\n provider: string\n}> {}\n\n/**\n * The model errored mid-generation. Distinct from `Unavailable` (transport\n * problem before generation started) and from `IncompleteTurn` (provider\n * stream ended without a terminal event). The provider's own error message,\n * if any, is on `message`.\n */\nexport class GenerationFailed extends Data.TaggedError(\"GenerationFailed\")<{\n provider: string\n code?: string\n message?: string\n requestId?: string\n raw: unknown\n}> {}\n\n/**\n * The provider's delta stream ended without a terminal `TurnComplete`.\n * Indicates a misbehaving provider or a connection that dropped mid-flight.\n * Non-terminal deltas seen so far have already been emitted downstream.\n */\nexport class IncompleteTurn extends Data.TaggedError(\"IncompleteTurn\")<{\n raw?: unknown\n}> {}\n\n/**\n * The provider does not implement the requested capability for this\n * specific request. Distinct from `InvalidRequest` (the request shape is\n * malformed) and `AuthFailed` (the request was rejected).\n *\n * Reserved for request-data-dependent gaps where the provider supports\n * the method in general but not for these inputs — e.g. Google's\n * `streamSynthesisFrom` works only for Chirp 3 HD voices; calling it\n * with a Neural2 voice ID fails `Unsupported`.\n *\n * Blanket provider-level gaps (e.g. OpenAI has no incremental-text-in\n * TTS at all) are gated at compile time via capability marker tags\n * (`TtsIncrementalText`, `SttStreaming`) on the R channel instead.\n */\nexport class Unsupported extends Data.TaggedError(\"Unsupported\")<{\n provider: string\n capability: string\n reason?: string\n}> {}\n\nexport type AiError =\n | RateLimited\n | Unavailable\n | Timeout\n | ContentFiltered\n | ContextLengthExceeded\n | InvalidRequest\n | AuthFailed\n | Cancelled\n | IncompleteTurn\n | GenerationFailed\n | Unsupported\n\nconst withReason = (base: string, reason: string | undefined): string =>\n reason === undefined ? base : `${base}: ${reason}`\n\n/**\n * Short human-readable description of an error, for logs and model-facing\n * failure messages. Prose, not a contract; branch on `_tag` instead.\n */\nexport const describe: (e: AiError) => string = Match.type<AiError>().pipe(\n Match.discriminatorsExhaustive(\"_tag\")({\n RateLimited: (e) => `rate limited by ${e.provider}; try again later`,\n Unavailable: (e) => `${e.provider} is temporarily unavailable`,\n Timeout: (e) => `the ${e.provider} request timed out`,\n ContentFiltered: (e) => withReason(`blocked by ${e.provider}'s content filter`, e.reason),\n ContextLengthExceeded: (e) => `the request exceeded ${e.provider}'s context limit`,\n InvalidRequest: (e) =>\n e.param === undefined\n ? `${e.provider} rejected the request`\n : `${e.provider} rejected the request (param: ${e.param})`,\n AuthFailed: (e) => `authentication against ${e.provider} failed (${e.subtype})`,\n Cancelled: (e) => `the ${e.provider} request was cancelled`,\n IncompleteTurn: () => \"the provider stream ended without completing\",\n GenerationFailed: (e) => e.message ?? `${e.provider} failed mid-generation`,\n Unsupported: (e) => withReason(`${e.provider} does not support ${e.capability}`, e.reason),\n }),\n)\n"],"mappings":";;;;;;;;;;;;;;;;;AAIA,IAAa,cAAb,cAAiC,KAAK,YAAY,cAAc,CAM7D;AAEH,IAAa,cAAb,cAAiC,KAAK,YAAY,cAAc,CAM7D;AAEH,IAAa,UAAb,cAA6B,KAAK,YAAY,UAAU,CAIrD;AAEH,IAAa,kBAAb,cAAqC,KAAK,YAAY,kBAAkB,CAKrE;AAEH,IAAa,wBAAb,cAA2C,KAAK,YAAY,wBAAwB,CAKjF;AAEH,IAAa,iBAAb,cAAoC,KAAK,YAAY,iBAAiB,CAKnE;AAIH,IAAa,aAAb,cAAgC,KAAK,YAAY,aAAa,CAI3D;AAEH,IAAa,YAAb,cAA+B,KAAK,YAAY,YAAY,CAEzD;;;;;;;AAQH,IAAa,mBAAb,cAAsC,KAAK,YAAY,mBAAmB,CAMvE;;;;;;AAOH,IAAa,iBAAb,cAAoC,KAAK,YAAY,iBAAiB,CAEnE;;;;;;;;;;;;;;;AAgBH,IAAa,cAAb,cAAiC,KAAK,YAAY,cAAc,CAI7D;AAeH,MAAM,cAAc,MAAc,WAChC,WAAW,KAAA,IAAY,OAAO,GAAG,KAAK,IAAI;;;;;AAM5C,MAAa,WAAmC,MAAM,MAAe,CAAC,KACpE,MAAM,yBAAyB,OAAO,CAAC;CACrC,cAAc,MAAM,mBAAmB,EAAE,SAAS;CAClD,cAAc,MAAM,GAAG,EAAE,SAAS;CAClC,UAAU,MAAM,OAAO,EAAE,SAAS;CAClC,kBAAkB,MAAM,WAAW,cAAc,EAAE,SAAS,oBAAoB,EAAE,OAAO;CACzF,wBAAwB,MAAM,wBAAwB,EAAE,SAAS;CACjE,iBAAiB,MACf,EAAE,UAAU,KAAA,IACR,GAAG,EAAE,SAAS,yBACd,GAAG,EAAE,SAAS,gCAAgC,EAAE,MAAM;CAC5D,aAAa,MAAM,0BAA0B,EAAE,SAAS,WAAW,EAAE,QAAQ;CAC7E,YAAY,MAAM,OAAO,EAAE,SAAS;CACpC,sBAAsB;CACtB,mBAAmB,MAAM,EAAE,WAAW,GAAG,EAAE,SAAS;CACpD,cAAc,MAAM,WAAW,GAAG,EAAE,SAAS,oBAAoB,EAAE,cAAc,EAAE,OAAO;CAC3F,CAAC,CACH"}
@@ -1,2 +1,2 @@
1
- import { a as AudioSource, c as isAudioBytes, i as AudioMimeType, l as isAudioUrl, n as AudioChunk, r as AudioFormat, s as isAudioBase64, t as AudioBlob } from "../Audio-DDSKCkSe.mjs";
1
+ import { a as AudioSource, c as isAudioBytes, i as AudioMimeType, l as isAudioUrl, n as AudioChunk, r as AudioFormat, s as isAudioBase64, t as AudioBlob } from "../Audio-CR7CSljJ.mjs";
2
2
  export { AudioBlob, AudioChunk, AudioFormat, AudioMimeType, AudioSource, isAudioBase64, isAudioBytes, isAudioUrl };
@@ -1,2 +1,2 @@
1
- import { a as ImageUrlSource, c as imageBytes, d as isImageBytes, f as isImageUrl, i as ImageSource, l as imageUrl, n as ImageBytesSource, r as ImageMimeType, s as imageBase64, t as ImageBase64Source, u as isImageBase64 } from "../Image-C_Zjpwhc.mjs";
1
+ import { a as ImageUrlSource, c as imageBytes, d as isImageBytes, f as isImageUrl, i as ImageSource, l as imageUrl, n as ImageBytesSource, r as ImageMimeType, s as imageBase64, t as ImageBase64Source, u as isImageBase64 } from "../Image-BZmKfIdq.mjs";
2
2
  export { ImageBase64Source, ImageBytesSource, ImageMimeType, ImageSource, ImageUrlSource, imageBase64, imageBytes, imageUrl, isImageBase64, isImageBytes, isImageUrl };
@@ -1,2 +1,2 @@
1
- import { A as isReasoning, C as isContainerFileCitation, D as isInputText, E as isInputImage, F as systemText, I as toolCallOutput, L as userText, M as isToolCall, N as isToolCallOutput, O as isMessage, P as isUrlCitation, S as assistantText, T as isFilePath, _ as StopReason, a as FilePath, b as UrlCitation, c as InputText, d as Message, f as OutputText, g as Role, h as Refusal, i as FileCitation, j as isRefusal, k as isOutputText, l as InputTokensDetails, m as Reasoning, n as ContainerFileCitation, o as HistoryItem, p as OutputTokensDetails, r as ContentBlock, s as InputImage, t as Annotation, v as ToolCall, w as isFileCitation, x as Usage, y as ToolCallOutput } from "../Items-CgKD6Npw.mjs";
1
+ import { A as isReasoning, C as isContainerFileCitation, D as isInputText, E as isInputImage, F as systemText, I as toolCallOutput, L as userText, M as isToolCall, N as isToolCallOutput, O as isMessage, P as isUrlCitation, S as assistantText, T as isFilePath, _ as StopReason, a as FilePath, b as UrlCitation, c as InputText, d as Message, f as OutputText, g as Role, h as Refusal, i as FileCitation, j as isRefusal, k as isOutputText, l as InputTokensDetails, m as Reasoning, n as ContainerFileCitation, o as HistoryItem, p as OutputTokensDetails, r as ContentBlock, s as InputImage, t as Annotation, v as ToolCall, w as isFileCitation, x as Usage, y as ToolCallOutput } from "../Items-BnIduEV2.mjs";
2
2
  export { Annotation, ContainerFileCitation, ContentBlock, FileCitation, FilePath, HistoryItem, InputImage, InputText, InputTokensDetails, Message, OutputText, OutputTokensDetails, Reasoning, Refusal, Role, StopReason, ToolCall, ToolCallOutput, UrlCitation, Usage, assistantText, isContainerFileCitation, isFileCitation, isFilePath, isInputImage, isInputText, isMessage, isOutputText, isReasoning, isRefusal, isToolCall, isToolCallOutput, isUrlCitation, systemText, toolCallOutput, userText };
@@ -1,2 +1,2 @@
1
- import { c as isMediaUrl, i as MediaUrl, n as MediaBytes, o as isMediaBase64, r as MediaSource, s as isMediaBytes, t as MediaBase64 } from "../Media-DOLyaygI.mjs";
1
+ import { c as isMediaUrl, i as MediaUrl, n as MediaBytes, o as isMediaBase64, r as MediaSource, s as isMediaBytes, t as MediaBase64 } from "../Media-D_CpcM1Z.mjs";
2
2
  export { MediaBase64, MediaBytes, MediaSource, MediaUrl, isMediaBase64, isMediaBytes, isMediaUrl };
@@ -1,4 +1,4 @@
1
- import { n as AudioChunk, r as AudioFormat, t as AudioBlob } from "../Audio-DDSKCkSe.mjs";
1
+ import { n as AudioChunk, r as AudioFormat, t as AudioBlob } from "../Audio-CR7CSljJ.mjs";
2
2
  import { Duration } from "effect";
3
3
 
4
4
  //#region src/domain/Music.d.ts
@@ -1,6 +1,6 @@
1
- import { i as ImageSource } from "../Image-C_Zjpwhc.mjs";
2
- import { d as Message, m as Reasoning, o as HistoryItem, v as ToolCall, x as Usage, y as ToolCallOutput } from "../Items-CgKD6Npw.mjs";
3
- import { i as StructuredFormat, n as JsonParseError, r as StructuredDecodeError } from "../StructuredFormat-CMJFD3sn.mjs";
1
+ import { i as ImageSource } from "../Image-BZmKfIdq.mjs";
2
+ import { d as Message, m as Reasoning, o as HistoryItem, v as ToolCall, x as Usage, y as ToolCallOutput } from "../Items-BnIduEV2.mjs";
3
+ import { i as StructuredFormat, n as JsonParseError, r as StructuredDecodeError } from "../StructuredFormat-DHaUJBdd.mjs";
4
4
  import { Data, Effect, Schema, Stream } from "effect";
5
5
  import * as _$effect_Cause0 from "effect/Cause";
6
6
  import * as _$effect_Types0 from "effect/Types";
@@ -1,4 +1,4 @@
1
- import { i as ImageSource } from "../Image-C_Zjpwhc.mjs";
1
+ import { i as ImageSource } from "../Image-BZmKfIdq.mjs";
2
2
 
3
3
  //#region src/embedding-model/Embedding.d.ts
4
4
  declare namespace Embedding_d_exports {
@@ -1,4 +1,4 @@
1
- import { t as AiError } from "../AiError-CrdR1EQi.mjs";
1
+ import { t as AiError } from "../AiError-Bf1pq4BB.mjs";
2
2
  import { EmbedInput, EmbeddingFor, ResponseEncoding, Usage } from "./Embedding.mjs";
3
3
  import { Context, Effect } from "effect";
4
4
 
package/dist/index.d.mts CHANGED
@@ -1,20 +1,23 @@
1
+ import { t as BrowserError_d_exports } from "./browser/BrowserError.mjs";
2
+ import { t as Browser_d_exports } from "./browser/Browser.mjs";
3
+ import { a as Media_d_exports } from "./Media-D_CpcM1Z.mjs";
4
+ import { o as Image_d_exports } from "./Image-BZmKfIdq.mjs";
5
+ import { u as Items_d_exports } from "./Items-BnIduEV2.mjs";
6
+ import { _ as Tool_d_exports } from "./Tool-2lC_XMth.mjs";
7
+ import { t as BrowserTool_d_exports } from "./browser/BrowserTool.mjs";
1
8
  import { t as Capabilities_d_exports } from "./capabilities/Capabilities.mjs";
2
- import { n as AiError_d_exports } from "./AiError-CrdR1EQi.mjs";
3
- import { a as Media_d_exports } from "./Media-DOLyaygI.mjs";
4
- import { o as Audio_d_exports } from "./Audio-DDSKCkSe.mjs";
5
- import { o as Image_d_exports } from "./Image-C_Zjpwhc.mjs";
6
- import { u as Items_d_exports } from "./Items-CgKD6Npw.mjs";
9
+ import { n as AiError_d_exports } from "./AiError-Bf1pq4BB.mjs";
10
+ import { o as Audio_d_exports } from "./Audio-CR7CSljJ.mjs";
7
11
  import { t as Music_d_exports } from "./domain/Music.mjs";
8
12
  import { t as Transcript_d_exports } from "./domain/Transcript.mjs";
9
- import { a as StructuredFormat_d_exports } from "./StructuredFormat-CMJFD3sn.mjs";
13
+ import { a as StructuredFormat_d_exports } from "./StructuredFormat-DHaUJBdd.mjs";
10
14
  import { t as Turn_d_exports } from "./domain/Turn.mjs";
11
15
  import { t as Embedding_d_exports } from "./embedding-model/Embedding.mjs";
12
16
  import { t as EmbeddingModel_d_exports } from "./embedding-model/EmbeddingModel.mjs";
13
- import { t as Loop_d_exports } from "./Loop-B5_cqumi.mjs";
14
- import { m as Tool_d_exports } from "./Tool-0XUIT2A2.mjs";
15
- import { n as ToolResult_d_exports } from "./ToolResult-BZd-cEWW.mjs";
16
- import { n as ToolEvent_d_exports } from "./ToolEvent-DYrAUJGs.mjs";
17
- import { c as Toolkit_d_exports } from "./Toolkit-BKC8b8Xo.mjs";
17
+ import { t as Loop_d_exports } from "./Loop-D8nWpowc.mjs";
18
+ import { n as ToolResult_d_exports } from "./ToolResult-CL4hK_9z.mjs";
19
+ import { n as ToolEvent_d_exports } from "./ToolEvent-cWZ2BnbS.mjs";
20
+ import { l as Toolkit_d_exports } from "./Toolkit-Dr9l_hNy.mjs";
18
21
  import { t as LanguageModel_d_exports } from "./language-model/LanguageModel.mjs";
19
22
  import { t as MusicGenerator_d_exports } from "./music-generator/MusicGenerator.mjs";
20
23
  import { t as Memory_d_exports } from "./sandbox/Memory.mjs";
@@ -24,6 +27,8 @@ import { t as SandboxImage_d_exports } from "./sandbox/SandboxImage.mjs";
24
27
  import { t as SandboxNetwork_d_exports } from "./sandbox/SandboxNetwork.mjs";
25
28
  import { t as SpeechSynthesizer_d_exports } from "./speech-synthesizer/SpeechSynthesizer.mjs";
26
29
  import { t as Transcriber_d_exports } from "./transcriber/Transcriber.mjs";
30
+ import { t as WebRead_d_exports } from "./web-read/WebRead.mjs";
31
+ import { t as WebReadTool_d_exports } from "./web-read/WebReadTool.mjs";
27
32
  import { t as WebSearch_d_exports } from "./web-search/WebSearch.mjs";
28
33
  import { t as WebSearchTool_d_exports } from "./web-search/WebSearchTool.mjs";
29
34
  import { t as Vector_d_exports } from "./math/Vector.mjs";
@@ -35,4 +40,4 @@ import { t as Lines_d_exports } from "./streaming/Lines.mjs";
35
40
  import { t as SSE_d_exports } from "./streaming/SSE.mjs";
36
41
  import { t as Metrics_d_exports } from "./observability/Metrics.mjs";
37
42
  import { t as Telemetry_d_exports } from "./observability/Telemetry.mjs";
38
- export { AiError_d_exports as AiError, Approval_d_exports as Approval, Audio_d_exports as Audio, Capabilities_d_exports as Capabilities, Embedding_d_exports as Embedding, EmbeddingModel_d_exports as EmbeddingModel, HistoryCheck_d_exports as HistoryCheck, Image_d_exports as Image, Items_d_exports as Items, JSONL_d_exports as JSONL, LanguageModel_d_exports as LanguageModel, Lines_d_exports as Lines, Loop_d_exports as Loop, Media_d_exports as Media, Memory_d_exports as Memory, Metrics_d_exports as Metrics, Music_d_exports as Music, MusicGenerator_d_exports as MusicGenerator, Retry_d_exports as Retry, SSE_d_exports as SSE, Sandbox_d_exports as Sandbox, SandboxError_d_exports as SandboxError, SandboxImage_d_exports as SandboxImage, SandboxNetwork_d_exports as SandboxNetwork, SpeechSynthesizer_d_exports as SpeechSynthesizer, StructuredFormat_d_exports as StructuredFormat, Telemetry_d_exports as Telemetry, Tool_d_exports as Tool, ToolEvent_d_exports as ToolEvent, ToolResult_d_exports as ToolResult, Toolkit_d_exports as Toolkit, Transcriber_d_exports as Transcriber, Transcript_d_exports as Transcript, Turn_d_exports as Turn, Vector_d_exports as Vector, WebSearch_d_exports as WebSearch, WebSearchTool_d_exports as WebSearchTool };
43
+ export { AiError_d_exports as AiError, Approval_d_exports as Approval, Audio_d_exports as Audio, Browser_d_exports as Browser, BrowserError_d_exports as BrowserError, BrowserTool_d_exports as BrowserTool, Capabilities_d_exports as Capabilities, Embedding_d_exports as Embedding, EmbeddingModel_d_exports as EmbeddingModel, HistoryCheck_d_exports as HistoryCheck, Image_d_exports as Image, Items_d_exports as Items, JSONL_d_exports as JSONL, LanguageModel_d_exports as LanguageModel, Lines_d_exports as Lines, Loop_d_exports as Loop, Media_d_exports as Media, Memory_d_exports as Memory, Metrics_d_exports as Metrics, Music_d_exports as Music, MusicGenerator_d_exports as MusicGenerator, Retry_d_exports as Retry, SSE_d_exports as SSE, Sandbox_d_exports as Sandbox, SandboxError_d_exports as SandboxError, SandboxImage_d_exports as SandboxImage, SandboxNetwork_d_exports as SandboxNetwork, SpeechSynthesizer_d_exports as SpeechSynthesizer, StructuredFormat_d_exports as StructuredFormat, Telemetry_d_exports as Telemetry, Tool_d_exports as Tool, ToolEvent_d_exports as ToolEvent, ToolResult_d_exports as ToolResult, Toolkit_d_exports as Toolkit, Transcriber_d_exports as Transcriber, Transcript_d_exports as Transcript, Turn_d_exports as Turn, Vector_d_exports as Vector, WebRead_d_exports as WebRead, WebReadTool_d_exports as WebReadTool, WebSearch_d_exports as WebSearch, WebSearchTool_d_exports as WebSearchTool };
package/dist/index.mjs CHANGED
@@ -1,13 +1,21 @@
1
1
  import { t as AiError_exports } from "./domain/AiError.mjs";
2
2
  import { t as Audio_exports } from "./domain/Audio.mjs";
3
- import { t as Capabilities_exports } from "./capabilities/Capabilities.mjs";
3
+ import { t as Browser_exports } from "./browser/Browser.mjs";
4
+ import { t as BrowserError_exports } from "./browser/BrowserError.mjs";
4
5
  import { t as Image_exports } from "./domain/Image.mjs";
5
6
  import { t as Items_exports } from "./domain/Items.mjs";
7
+ import { t as ToolResult_exports } from "./tool/ToolResult.mjs";
8
+ import { t as Tool_exports } from "./tool/Tool.mjs";
9
+ import { t as StructuredFormat_exports } from "./structured-format/StructuredFormat.mjs";
10
+ import { t as Turn_exports } from "./domain/Turn.mjs";
11
+ import { t as Loop_exports } from "./loop/Loop.mjs";
12
+ import { t as ToolEvent_exports } from "./tool/ToolEvent.mjs";
13
+ import { t as Toolkit_exports } from "./tool/Toolkit.mjs";
14
+ import { t as BrowserTool_exports } from "./browser/BrowserTool.mjs";
15
+ import { t as Capabilities_exports } from "./capabilities/Capabilities.mjs";
6
16
  import { t as Media_exports } from "./domain/Media.mjs";
7
17
  import { t as Music_exports } from "./domain/Music.mjs";
8
18
  import { t as Transcript_exports } from "./domain/Transcript.mjs";
9
- import { t as StructuredFormat_exports } from "./structured-format/StructuredFormat.mjs";
10
- import { t as Turn_exports } from "./domain/Turn.mjs";
11
19
  import { t as Embedding_exports } from "./embedding-model/Embedding.mjs";
12
20
  import { t as EmbeddingModel_exports } from "./embedding-model/EmbeddingModel.mjs";
13
21
  import { t as LanguageModel_exports } from "./language-model/LanguageModel.mjs";
@@ -19,15 +27,12 @@ import { t as SandboxImage_exports } from "./sandbox/SandboxImage.mjs";
19
27
  import { t as SandboxNetwork_exports } from "./sandbox/SandboxNetwork.mjs";
20
28
  import { t as SpeechSynthesizer_exports } from "./speech-synthesizer/SpeechSynthesizer.mjs";
21
29
  import { t as Transcriber_exports } from "./transcriber/Transcriber.mjs";
30
+ import { t as WebRead_exports } from "./web-read/WebRead.mjs";
31
+ import { t as WebReadTool_exports } from "./web-read/WebReadTool.mjs";
22
32
  import { t as WebSearch_exports } from "./web-search/WebSearch.mjs";
23
- import { t as Tool_exports } from "./tool/Tool.mjs";
24
33
  import { t as WebSearchTool_exports } from "./web-search/WebSearchTool.mjs";
25
34
  import { t as Vector_exports } from "./math/Vector.mjs";
26
- import { t as Loop_exports } from "./loop/Loop.mjs";
27
35
  import { t as Retry_exports } from "./retry/Retry.mjs";
28
- import { t as ToolResult_exports } from "./tool/ToolResult.mjs";
29
- import { t as ToolEvent_exports } from "./tool/ToolEvent.mjs";
30
- import { t as Toolkit_exports } from "./tool/Toolkit.mjs";
31
36
  import { t as Approval_exports } from "./tool/Approval.mjs";
32
37
  import { t as HistoryCheck_exports } from "./tool/HistoryCheck.mjs";
33
38
  import { t as JSONL_exports } from "./streaming/JSONL.mjs";
@@ -35,4 +40,4 @@ import { t as Lines_exports } from "./streaming/Lines.mjs";
35
40
  import { t as SSE_exports } from "./streaming/SSE.mjs";
36
41
  import { t as Metrics_exports } from "./observability/Metrics.mjs";
37
42
  import { t as Telemetry_exports } from "./observability/Telemetry.mjs";
38
- export { AiError_exports as AiError, Approval_exports as Approval, Audio_exports as Audio, Capabilities_exports as Capabilities, Embedding_exports as Embedding, EmbeddingModel_exports as EmbeddingModel, HistoryCheck_exports as HistoryCheck, Image_exports as Image, Items_exports as Items, JSONL_exports as JSONL, LanguageModel_exports as LanguageModel, Lines_exports as Lines, Loop_exports as Loop, Media_exports as Media, Memory_exports as Memory, Metrics_exports as Metrics, Music_exports as Music, MusicGenerator_exports as MusicGenerator, Retry_exports as Retry, SSE_exports as SSE, Sandbox_exports as Sandbox, SandboxError_exports as SandboxError, SandboxImage_exports as SandboxImage, SandboxNetwork_exports as SandboxNetwork, SpeechSynthesizer_exports as SpeechSynthesizer, StructuredFormat_exports as StructuredFormat, Telemetry_exports as Telemetry, Tool_exports as Tool, ToolEvent_exports as ToolEvent, ToolResult_exports as ToolResult, Toolkit_exports as Toolkit, Transcriber_exports as Transcriber, Transcript_exports as Transcript, Turn_exports as Turn, Vector_exports as Vector, WebSearch_exports as WebSearch, WebSearchTool_exports as WebSearchTool };
43
+ export { AiError_exports as AiError, Approval_exports as Approval, Audio_exports as Audio, Browser_exports as Browser, BrowserError_exports as BrowserError, BrowserTool_exports as BrowserTool, Capabilities_exports as Capabilities, Embedding_exports as Embedding, EmbeddingModel_exports as EmbeddingModel, HistoryCheck_exports as HistoryCheck, Image_exports as Image, Items_exports as Items, JSONL_exports as JSONL, LanguageModel_exports as LanguageModel, Lines_exports as Lines, Loop_exports as Loop, Media_exports as Media, Memory_exports as Memory, Metrics_exports as Metrics, Music_exports as Music, MusicGenerator_exports as MusicGenerator, Retry_exports as Retry, SSE_exports as SSE, Sandbox_exports as Sandbox, SandboxError_exports as SandboxError, SandboxImage_exports as SandboxImage, SandboxNetwork_exports as SandboxNetwork, SpeechSynthesizer_exports as SpeechSynthesizer, StructuredFormat_exports as StructuredFormat, Telemetry_exports as Telemetry, Tool_exports as Tool, ToolEvent_exports as ToolEvent, ToolResult_exports as ToolResult, Toolkit_exports as Toolkit, Transcriber_exports as Transcriber, Transcript_exports as Transcript, Turn_exports as Turn, Vector_exports as Vector, WebRead_exports as WebRead, WebReadTool_exports as WebReadTool, WebSearch_exports as WebSearch, WebSearchTool_exports as WebSearchTool };
@@ -1,8 +1,8 @@
1
- import { t as AiError } from "../AiError-CrdR1EQi.mjs";
2
- import { o as HistoryItem } from "../Items-CgKD6Npw.mjs";
3
- import { i as StructuredFormat } from "../StructuredFormat-CMJFD3sn.mjs";
1
+ import { o as HistoryItem } from "../Items-BnIduEV2.mjs";
2
+ import { t as AiError } from "../AiError-Bf1pq4BB.mjs";
3
+ import { i as StructuredFormat } from "../StructuredFormat-DHaUJBdd.mjs";
4
4
  import { Turn, TurnEvent } from "../domain/Turn.mjs";
5
- import { o as Toolkit } from "../Toolkit-BKC8b8Xo.mjs";
5
+ import { o as Toolkit } from "../Toolkit-Dr9l_hNy.mjs";
6
6
  import { Context, Effect, Stream } from "effect";
7
7
 
8
8
  //#region src/language-model/LanguageModel.d.ts
@@ -1,2 +1,2 @@
1
- import { a as StopWith, c as loopOver, d as onTurnComplete, f as stop, i as Stop, l as loopWithState, n as Next, o as Value, p as value, r as Step, s as loop, u as next } from "../Loop-B5_cqumi.mjs";
1
+ import { a as StopWith, c as loopOver, d as onTurnComplete, f as stop, i as Stop, l as loopWithState, n as Next, o as Value, p as value, r as Step, s as loop, u as next } from "../Loop-D8nWpowc.mjs";
2
2
  export { Next, Step, Stop, StopWith, Value, loop, loopOver, loopWithState, next, onTurnComplete, stop, value };
@@ -1,5 +1,5 @@
1
- import { t as AiError } from "../AiError-CrdR1EQi.mjs";
2
- import { n as AudioChunk } from "../Audio-DDSKCkSe.mjs";
1
+ import { t as AiError } from "../AiError-Bf1pq4BB.mjs";
2
+ import { n as AudioChunk } from "../Audio-CR7CSljJ.mjs";
3
3
  import { CommonGenerateMusicRequest, CommonStreamGenerateMusicRequest, GenerateResult, MusicResult, MusicSection, MusicSessionControl, MusicSessionInput, MusicStreamEvent, Watermark, WeightedPrompt } from "../domain/Music.mjs";
4
4
  import { Context, Effect, Stream } from "effect";
5
5
 
@@ -1,4 +1,4 @@
1
- import { x as Usage } from "../Items-CgKD6Npw.mjs";
1
+ import { x as Usage } from "../Items-BnIduEV2.mjs";
2
2
  import { TurnEvent } from "../domain/Turn.mjs";
3
3
  import { Duration, Effect, Option, Stream } from "effect";
4
4
 
@@ -1,4 +1,4 @@
1
- import { d as RateLimited, m as Unavailable, p as Timeout, t as AiError } from "../AiError-CrdR1EQi.mjs";
1
+ import { d as RateLimited, m as Unavailable, p as Timeout, t as AiError } from "../AiError-Bf1pq4BB.mjs";
2
2
  import { Effect, Schedule, Stream } from "effect";
3
3
  import * as _$effect_Cause0 from "effect/Cause";
4
4
  import * as _$effect_Types0 from "effect/Types";
@@ -1,5 +1,5 @@
1
- import { t as AiError } from "../AiError-CrdR1EQi.mjs";
2
- import { n as AudioChunk, r as AudioFormat, t as AudioBlob } from "../Audio-DDSKCkSe.mjs";
1
+ import { t as AiError } from "../AiError-Bf1pq4BB.mjs";
2
+ import { n as AudioChunk, r as AudioFormat, t as AudioBlob } from "../Audio-CR7CSljJ.mjs";
3
3
  import { Context, Effect, Stream } from "effect";
4
4
 
5
5
  //#region src/speech-synthesizer/SpeechSynthesizer.d.ts
@@ -1,2 +1,2 @@
1
- import { c as decodeJsonLines, d as parseJson, i as StructuredFormat, l as decodeJsonLinesRecoverable, n as JsonParseError, o as StructuredSchema, r as StructuredDecodeError, s as decode, t as DecodeIssue, u as fromEffectSchema } from "../StructuredFormat-CMJFD3sn.mjs";
1
+ import { c as decodeJsonLines, d as parseJson, i as StructuredFormat, l as decodeJsonLinesRecoverable, n as JsonParseError, o as StructuredSchema, r as StructuredDecodeError, s as decode, t as DecodeIssue, u as fromEffectSchema } from "../StructuredFormat-DHaUJBdd.mjs";
2
2
  export { DecodeIssue, JsonParseError, StructuredDecodeError, StructuredFormat, StructuredSchema, decode, decodeJsonLines, decodeJsonLinesRecoverable, fromEffectSchema, parseJson };
@@ -1,4 +1,4 @@
1
- import { n as AudioChunk } from "../Audio-DDSKCkSe.mjs";
1
+ import { n as AudioChunk } from "../Audio-CR7CSljJ.mjs";
2
2
  import { CommonGenerateMusicRequest, CommonStreamGenerateMusicRequest, GenerateResult, MusicStreamEvent, audioEvent } from "../domain/Music.mjs";
3
3
  import { MusicGenerator, MusicInteractiveSession } from "../music-generator/MusicGenerator.mjs";
4
4
  import { Effect, Layer } from "effect";
@@ -1,4 +1,4 @@
1
- import { o as HistoryItem } from "../Items-CgKD6Npw.mjs";
1
+ import { o as HistoryItem } from "../Items-BnIduEV2.mjs";
2
2
  import { Turn } from "../domain/Turn.mjs";
3
3
  import { LanguageModel, LanguageModelService } from "../language-model/LanguageModel.mjs";
4
4
  import { Duration, Effect, Layer } from "effect";
@@ -1,4 +1,4 @@
1
- import { n as AudioChunk, t as AudioBlob } from "../Audio-DDSKCkSe.mjs";
1
+ import { n as AudioChunk, t as AudioBlob } from "../Audio-CR7CSljJ.mjs";
2
2
  import { CommonStreamSynthesizeRequest, CommonSynthesizeDialogueRequest, CommonSynthesizeRequest, MultiSpeakerTts, SpeechSynthesizer, TtsIncrementalText } from "../speech-synthesizer/SpeechSynthesizer.mjs";
3
3
  import { Effect, Layer } from "effect";
4
4
 
@@ -1,12 +1,12 @@
1
- import { v as ToolCall } from "../Items-CgKD6Npw.mjs";
2
- import { t as ToolResult } from "../ToolResult-BZd-cEWW.mjs";
3
- import { t as ToolEvent } from "../ToolEvent-DYrAUJGs.mjs";
4
- import { Data, Effect, Queue, Scope, Stream } from "effect";
1
+ import { v as ToolCall } from "../Items-BnIduEV2.mjs";
2
+ import { t as ToolResult } from "../ToolResult-CL4hK_9z.mjs";
3
+ import { t as ToolEvent } from "../ToolEvent-cWZ2BnbS.mjs";
4
+ import { Data, Duration, Effect, Queue, Scope, Stream } from "effect";
5
5
  import * as _$effect_Unify0 from "effect/Unify";
6
6
 
7
7
  //#region src/tool/Approval.d.ts
8
8
  declare namespace Approval_d_exports {
9
- export { ApprovalDecision, ApprovalMapEntry, ToolCallPlan, Verdict, approvalRequested, approve, fromMap, fromQueue, reject, splitApprovalDecisions };
9
+ export { ApprovalDecision, ApprovalMapEntry, FromQueueOptions, ToolCallPlan, Verdict, approvalRequested, approve, fromMap, fromQueue, reject, splitApprovalDecisions };
10
10
  }
11
11
  type ToolCallPlan = {
12
12
  readonly approved: ReadonlyArray<ToolCall>;
@@ -84,12 +84,24 @@ type Verdict = {
84
84
  readonly decision: "approve" | "deny";
85
85
  readonly reason?: string;
86
86
  };
87
+ type FromQueueOptions = {
88
+ /**
89
+ * Resolve any still-pending gated call as `cancelled` once this elapses,
90
+ * so a lost or never-sent verdict cannot hang the decisions stream
91
+ * forever. Omit to wait indefinitely.
92
+ */
93
+ readonly timeout?: Duration.Input;
94
+ };
87
95
  /**
88
96
  * Queue-backed approval planner. Safe calls are returned immediately in
89
97
  * `approved`; gated calls emit `ApprovalRequested` events and later produce
90
98
  * one `ApprovalDecision` when their matching verdict arrives.
99
+ *
100
+ * The verdict queue is a single-consumer transport: run one approval round
101
+ * at a time (the router retires once every gated call of the round is
102
+ * resolved). For overlapping rounds, use one queue per round.
91
103
  */
92
- declare const fromQueue: (predicate: (call: ToolCall) => boolean, verdicts: Queue.Dequeue<Verdict>) => (calls: ReadonlyArray<ToolCall>) => Effect.Effect<{
104
+ declare const fromQueue: (predicate: (call: ToolCall) => boolean, verdicts: Queue.Dequeue<Verdict>, options?: FromQueueOptions) => (calls: ReadonlyArray<ToolCall>) => Effect.Effect<{
93
105
  readonly approved: ReadonlyArray<ToolCall>;
94
106
  readonly decisions: Stream.Stream<ApprovalDecision>;
95
107
  readonly approvalRequests: Stream.Stream<ToolEvent>;
@@ -102,5 +114,5 @@ type ApprovalMapEntry = {
102
114
  };
103
115
  declare const fromMap: (predicate: (call: ToolCall) => boolean, approvals: ReadonlyMap<string, ApprovalMapEntry>) => (calls: ReadonlyArray<ToolCall>) => ToolCallPlan;
104
116
  //#endregion
105
- export { ApprovalDecision, ApprovalMapEntry, ToolCallPlan, Verdict, approvalRequested, approve, fromMap, fromQueue, reject, splitApprovalDecisions, Approval_d_exports as t };
117
+ export { ApprovalDecision, ApprovalMapEntry, FromQueueOptions, ToolCallPlan, Verdict, approvalRequested, approve, fromMap, fromQueue, reject, splitApprovalDecisions, Approval_d_exports as t };
106
118
  //# sourceMappingURL=Approval.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Approval.d.mts","names":[],"sources":["../../src/tool/Approval.ts"],"mappings":";;;;;;;;;;KAYY,YAAA;EAAA,SACD,QAAA,EAAU,aAAA,CAAc,QAAA;EAAA,SACxB,QAAA,EAAU,aAAA,CAAc,UAAA;AAAA;AAAA,KAGvB,gBAAA,GAAmB,IAAA,CAAK,UAAA;EAClC,QAAA;IAAA,SAAqB,IAAA,EAAM,QAAA;EAAA;EAC3B,QAAA;IAAA,SAAqB,MAAA,EAAQ,UAAA;EAAA;AAAA;AAAA,cAGlB,gBAAA;EAAA;;mBAJgB,QAAA;EAAA;EAAA;;qBACE,UAAA;EAAA;EAAA;;mBADF,QAAA;EAAA;IAAA;;;qBACE,UAAA;EAAA;IAAA;;;;;;uBADF,QAAA;MAAA;MAAA;;yBACE,UAAA;MAAA;IAAA;;qBADF,QAAA;IAAA;MAAA;uBACE,UAAA;IAAA;;;;uBADF,QAAA;MAAA;MAAA;;yBACE,UAAA;MAAA;IAAA;;qBADF,QAAA;IAAA;MAAA;uBACE,UAAA;IAAA;;;cAKlB,OAAA,GAAW,IAAA,EAAM,QAAA,KAAW,gBAAA;AAAA,cAE5B,MAAA,GAAU,MAAA,EAAQ,UAAA,KAAa,gBAAA;AAAA,cAG/B,sBAAA,GAA0B,SAAA,EAAW,aAAA,CAAc,gBAAA,MAAoB,YAAA;AAAA,cASvE,iBAAA,GAAqB,IAAA,EAAM,QAAA,KAAW,SAAA;AAAA,KAWvC,OAAA;EAAA,SACD,OAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;AAAA;;;;;;cAQE,SAAA,GACV,SAAA,GAAY,IAAA,EAAM,QAAA,cAAsB,QAAA,EAAU,KAAA,CAAM,OAAA,CAAQ,OAAA,OAE/D,KAAA,EAAO,aAAA,CAAc,QAAA,MACpB,MAAA,CAAO,MAAA;EAAA,SAEG,QAAA,EAAU,aAAA,CAAc,QAAA;EAAA,SACxB,SAAA,EAAW,MAAA,CAAO,MAAA,CAAO,gBAAA;EAAA,SACzB,gBAAA,EAAkB,MAAA,CAAO,MAAA,CAAO,SAAA;AAAA,UAG3C,KAAA,CAAM,KAAA;AAAA,KAkDE,gBAAA;EAAA,SACG,QAAA;AAAA;EAAA,SACA,QAAA;EAAA,SAA2B,MAAA;AAAA;AAAA,cAE7B,OAAA,GACV,SAAA,GAAY,IAAA,EAAM,QAAA,cAAsB,SAAA,EAAW,WAAA,SAAoB,gBAAA,OACvE,KAAA,EAAO,aAAA,CAAc,QAAA,MAAY,YAAA"}
1
+ {"version":3,"file":"Approval.d.mts","names":[],"sources":["../../src/tool/Approval.ts"],"mappings":";;;;;;;;;;KAYY,YAAA;EAAA,SACD,QAAA,EAAU,aAAA,CAAc,QAAA;EAAA,SACxB,QAAA,EAAU,aAAA,CAAc,UAAA;AAAA;AAAA,KAGvB,gBAAA,GAAmB,IAAA,CAAK,UAAA;EAClC,QAAA;IAAA,SAAqB,IAAA,EAAM,QAAA;EAAA;EAC3B,QAAA;IAAA,SAAqB,MAAA,EAAQ,UAAA;EAAA;AAAA;AAAA,cAGlB,gBAAA;EAAA;;mBAJgB,QAAA;EAAA;EAAA;;qBACE,UAAA;EAAA;EAAA;;mBADF,QAAA;EAAA;IAAA;;;qBACE,UAAA;EAAA;IAAA;;;;;;uBADF,QAAA;MAAA;MAAA;;yBACE,UAAA;MAAA;IAAA;;qBADF,QAAA;IAAA;MAAA;uBACE,UAAA;IAAA;;;;uBADF,QAAA;MAAA;MAAA;;yBACE,UAAA;MAAA;IAAA;;qBADF,QAAA;IAAA;MAAA;uBACE,UAAA;IAAA;;;cAKlB,OAAA,GAAW,IAAA,EAAM,QAAA,KAAW,gBAAA;AAAA,cAE5B,MAAA,GAAU,MAAA,EAAQ,UAAA,KAAa,gBAAA;AAAA,cAG/B,sBAAA,GAA0B,SAAA,EAAW,aAAA,CAAc,gBAAA,MAAoB,YAAA;AAAA,cASvE,iBAAA,GAAqB,IAAA,EAAM,QAAA,KAAW,SAAA;AAAA,KAWvC,OAAA;EAAA,SACD,OAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;AAAA;AAAA,KAGC,gBAAA;;;;;;WAMD,OAAA,GAAU,QAAA,CAAS,KAAA;AAAA;;;;;;;;;;cAYjB,SAAA,GAET,SAAA,GAAY,IAAA,EAAM,QAAA,cAClB,QAAA,EAAU,KAAA,CAAM,OAAA,CAAQ,OAAA,GACxB,OAAA,GAAU,gBAAA,MAGV,KAAA,EAAO,aAAA,CAAc,QAAA,MACpB,MAAA,CAAO,MAAA;EAAA,SAEG,QAAA,EAAU,aAAA,CAAc,QAAA;EAAA,SACxB,SAAA,EAAW,MAAA,CAAO,MAAA,CAAO,gBAAA;EAAA,SACzB,gBAAA,EAAkB,MAAA,CAAO,MAAA,CAAO,SAAA;AAAA,UAG3C,KAAA,CAAM,KAAA;AAAA,KA8EE,gBAAA;EAAA,SACG,QAAA;AAAA;EAAA,SACA,QAAA;EAAA,SAA2B,MAAA;AAAA;AAAA,cAE7B,OAAA,GACV,SAAA,GAAY,IAAA,EAAM,QAAA,cAAsB,SAAA,EAAW,WAAA,SAAoB,gBAAA,OACvE,KAAA,EAAO,aAAA,CAAc,QAAA,MAAY,YAAA"}
@@ -1,7 +1,7 @@
1
1
  import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
2
2
  import { cancelled, denied } from "./ToolResult.mjs";
3
3
  import { ToolEvent } from "./ToolEvent.mjs";
4
- import { Data, Deferred, Effect, Queue, Stream } from "effect";
4
+ import { Data, Deferred, Effect, Queue, Ref, Stream } from "effect";
5
5
  //#region src/tool/Approval.ts
6
6
  /**
7
7
  * Approval helpers for the two transport flavors.
@@ -41,23 +41,30 @@ const approvalRequested = (call) => ToolEvent.ApprovalRequested({
41
41
  * Queue-backed approval planner. Safe calls are returned immediately in
42
42
  * `approved`; gated calls emit `ApprovalRequested` events and later produce
43
43
  * one `ApprovalDecision` when their matching verdict arrives.
44
+ *
45
+ * The verdict queue is a single-consumer transport: run one approval round
46
+ * at a time (the router retires once every gated call of the round is
47
+ * resolved). For overlapping rounds, use one queue per round.
44
48
  */
45
- const fromQueue = (predicate, verdicts) => (calls) => Effect.gen(function* () {
49
+ const fromQueue = (predicate, verdicts, options) => (calls) => Effect.gen(function* () {
46
50
  const gated = calls.filter(predicate);
47
51
  const approved = calls.filter((call) => !predicate(call));
48
52
  const entries = yield* Effect.forEach(gated, (call) => Deferred.make().pipe(Effect.map((d) => [call.call_id, d])));
49
53
  const deferreds = new Map(entries);
50
- yield* Effect.forkScoped(Effect.forever(Effect.gen(function* () {
51
- const v = yield* Queue.take(verdicts);
52
- const d = deferreds.get(v.call_id);
53
- if (d !== void 0) yield* Deferred.succeed(d, v);
54
- })));
54
+ const callById = new Map(gated.map((c) => [c.call_id, c]));
55
+ const outstanding = yield* Ref.make(gated.length);
56
+ const resolve = (call, decision) => Deferred.succeed(deferreds.get(call.call_id), decision).pipe(Effect.flatMap((won) => won ? Ref.update(outstanding, (n) => n - 1) : Effect.void));
57
+ const route = Effect.suspend(() => Ref.get(outstanding).pipe(Effect.flatMap((n) => n <= 0 ? Effect.void : Queue.take(verdicts).pipe(Effect.flatMap((v) => {
58
+ const call = callById.get(v.call_id);
59
+ return (call === void 0 ? Effect.void : resolve(call, v.decision === "approve" ? approve(call) : reject(denied(call, v.reason)))).pipe(Effect.andThen(route));
60
+ })))));
61
+ if (gated.length > 0) {
62
+ yield* Effect.forkScoped(route);
63
+ if (options?.timeout !== void 0) yield* Effect.forkScoped(Effect.sleep(options.timeout).pipe(Effect.andThen(Effect.forEach(gated, (call) => resolve(call, reject(cancelled(call, "approval timed out")))))));
64
+ }
55
65
  return {
56
66
  approved,
57
- decisions: Stream.fromIterable(gated).pipe(Stream.flatMap((call) => {
58
- const d = deferreds.get(call.call_id);
59
- return Stream.fromEffect(Deferred.await(d).pipe(Effect.map((v) => v.decision === "approve" ? approve(call) : reject(denied(call, v.reason)))));
60
- }, { concurrency: "unbounded" })),
67
+ decisions: Stream.fromIterable(gated).pipe(Stream.flatMap((call) => Stream.fromEffect(Deferred.await(deferreds.get(call.call_id))), { concurrency: "unbounded" })),
61
68
  approvalRequests: Stream.fromIterable(gated.map(approvalRequested))
62
69
  };
63
70
  });
@@ -1 +1 @@
1
- {"version":3,"file":"Approval.mjs","names":[],"sources":["../../src/tool/Approval.ts"],"sourcesContent":["/**\n * Approval helpers for the two transport flavors.\n *\n * These helpers only decide which calls are approved and which synthetic\n * results must be returned to the model. Tool execution stays explicit at\n * the recipe boundary via `Toolkit.run`.\n */\nimport { Data, Deferred, Effect, Queue, Scope, Stream } from \"effect\"\nimport type { ToolCall } from \"../domain/Items.js\"\nimport { type ToolResult, cancelled, denied } from \"./ToolResult.js\"\nimport { ToolEvent } from \"./ToolEvent.js\"\n\nexport type ToolCallPlan = {\n readonly approved: ReadonlyArray<ToolCall>\n readonly rejected: ReadonlyArray<ToolResult>\n}\n\nexport type ApprovalDecision = Data.TaggedEnum<{\n Approved: { readonly call: ToolCall }\n Rejected: { readonly result: ToolResult }\n}>\n\nexport const ApprovalDecision = Data.taggedEnum<ApprovalDecision>()\n\nexport const approve = (call: ToolCall): ApprovalDecision => ApprovalDecision.Approved({ call })\n\nexport const reject = (result: ToolResult): ApprovalDecision =>\n ApprovalDecision.Rejected({ result })\n\nexport const splitApprovalDecisions = (decisions: ReadonlyArray<ApprovalDecision>): ToolCallPlan =>\n decisions.reduce<ToolCallPlan>(\n (acc, decision) =>\n decision._tag === \"Approved\"\n ? { ...acc, approved: [...acc.approved, decision.call] }\n : { ...acc, rejected: [...acc.rejected, decision.result] },\n { approved: [], rejected: [] },\n )\n\nexport const approvalRequested = (call: ToolCall): ToolEvent =>\n ToolEvent.ApprovalRequested({\n call_id: call.call_id,\n tool: call.name,\n arguments: call.arguments,\n })\n\n// ---------------------------------------------------------------------------\n// Verdict queue (WebSocket-style transport).\n// ---------------------------------------------------------------------------\n\nexport type Verdict = {\n readonly call_id: string\n readonly decision: \"approve\" | \"deny\"\n readonly reason?: string\n}\n\n/**\n * Queue-backed approval planner. Safe calls are returned immediately in\n * `approved`; gated calls emit `ApprovalRequested` events and later produce\n * one `ApprovalDecision` when their matching verdict arrives.\n */\nexport const fromQueue =\n (predicate: (call: ToolCall) => boolean, verdicts: Queue.Dequeue<Verdict>) =>\n (\n calls: ReadonlyArray<ToolCall>,\n ): Effect.Effect<\n {\n readonly approved: ReadonlyArray<ToolCall>\n readonly decisions: Stream.Stream<ApprovalDecision>\n readonly approvalRequests: Stream.Stream<ToolEvent>\n },\n never,\n Scope.Scope\n > =>\n Effect.gen(function* () {\n const gated = calls.filter(predicate)\n const approved = calls.filter((call) => !predicate(call))\n\n const entries = yield* Effect.forEach(gated, (call) =>\n Deferred.make<Verdict>().pipe(Effect.map((d) => [call.call_id, d] as const)),\n )\n const deferreds: ReadonlyMap<string, Deferred.Deferred<Verdict>> = new Map(entries)\n\n // Router is forked into the surrounding Scope so it lives as long\n // as the consumer is pulling events. Recipes typically supply the\n // scope by wrapping the events construction in `Stream.unwrap`.\n yield* Effect.forkScoped(\n Effect.forever(\n Effect.gen(function* () {\n const v = yield* Queue.take(verdicts)\n const d = deferreds.get(v.call_id)\n if (d !== undefined) yield* Deferred.succeed(d, v)\n }),\n ),\n )\n\n const decisions = Stream.fromIterable(gated).pipe(\n Stream.flatMap(\n (call) => {\n const d = deferreds.get(call.call_id)!\n return Stream.fromEffect(\n Deferred.await(d).pipe(\n Effect.map((v) =>\n v.decision === \"approve\" ? approve(call) : reject(denied(call, v.reason)),\n ),\n ),\n )\n },\n { concurrency: \"unbounded\" },\n ),\n )\n\n const approvalRequests = Stream.fromIterable<ToolEvent>(gated.map(approvalRequested))\n\n return { approved, decisions, approvalRequests }\n })\n\n// ---------------------------------------------------------------------------\n// Approval map (HTTP-style transport). Verdicts arrive synchronously\n// bundled in the request payload. Missing entries → cancelled.\n// ---------------------------------------------------------------------------\n\nexport type ApprovalMapEntry =\n | { readonly decision: \"approve\" }\n | { readonly decision: \"deny\"; readonly reason?: string }\n\nexport const fromMap =\n (predicate: (call: ToolCall) => boolean, approvals: ReadonlyMap<string, ApprovalMapEntry>) =>\n (calls: ReadonlyArray<ToolCall>): ToolCallPlan =>\n splitApprovalDecisions(\n calls.map((call) => {\n if (!predicate(call)) return approve(call)\n const v = approvals.get(call.call_id)\n if (v === undefined) return reject(cancelled(call))\n return v.decision === \"approve\" ? approve(call) : reject(denied(call, v.reason))\n }),\n )\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,mBAAmB,KAAK,YAA8B;AAEnE,MAAa,WAAW,SAAqC,iBAAiB,SAAS,EAAE,MAAM,CAAC;AAEhG,MAAa,UAAU,WACrB,iBAAiB,SAAS,EAAE,QAAQ,CAAC;AAEvC,MAAa,0BAA0B,cACrC,UAAU,QACP,KAAK,aACJ,SAAS,SAAS,aACd;CAAE,GAAG;CAAK,UAAU,CAAC,GAAG,IAAI,UAAU,SAAS,KAAK;CAAE,GACtD;CAAE,GAAG;CAAK,UAAU,CAAC,GAAG,IAAI,UAAU,SAAS,OAAO;CAAE,EAC9D;CAAE,UAAU,EAAE;CAAE,UAAU,EAAE;CAAE,CAC/B;AAEH,MAAa,qBAAqB,SAChC,UAAU,kBAAkB;CAC1B,SAAS,KAAK;CACd,MAAM,KAAK;CACX,WAAW,KAAK;CACjB,CAAC;;;;;;AAiBJ,MAAa,aACV,WAAwC,cAEvC,UAUA,OAAO,IAAI,aAAa;CACtB,MAAM,QAAQ,MAAM,OAAO,UAAU;CACrC,MAAM,WAAW,MAAM,QAAQ,SAAS,CAAC,UAAU,KAAK,CAAC;CAEzD,MAAM,UAAU,OAAO,OAAO,QAAQ,QAAQ,SAC5C,SAAS,MAAe,CAAC,KAAK,OAAO,KAAK,MAAM,CAAC,KAAK,SAAS,EAAE,CAAU,CAAC,CAC7E;CACD,MAAM,YAA6D,IAAI,IAAI,QAAQ;AAKnF,QAAO,OAAO,WACZ,OAAO,QACL,OAAO,IAAI,aAAa;EACtB,MAAM,IAAI,OAAO,MAAM,KAAK,SAAS;EACrC,MAAM,IAAI,UAAU,IAAI,EAAE,QAAQ;AAClC,MAAI,MAAM,KAAA,EAAW,QAAO,SAAS,QAAQ,GAAG,EAAE;GAClD,CACH,CACF;AAoBD,QAAO;EAAE;EAAU,WAlBD,OAAO,aAAa,MAAM,CAAC,KAC3C,OAAO,SACJ,SAAS;GACR,MAAM,IAAI,UAAU,IAAI,KAAK,QAAQ;AACrC,UAAO,OAAO,WACZ,SAAS,MAAM,EAAE,CAAC,KAChB,OAAO,KAAK,MACV,EAAE,aAAa,YAAY,QAAQ,KAAK,GAAG,OAAO,OAAO,MAAM,EAAE,OAAO,CAAC,CAC1E,CACF,CACF;KAEH,EAAE,aAAa,aAAa,CAC7B,CAKyB;EAAE,kBAFL,OAAO,aAAwB,MAAM,IAAI,kBAAkB,CAEtC;EAAE;EAChD;AAWN,MAAa,WACV,WAAwC,eACxC,UACC,uBACE,MAAM,KAAK,SAAS;AAClB,KAAI,CAAC,UAAU,KAAK,CAAE,QAAO,QAAQ,KAAK;CAC1C,MAAM,IAAI,UAAU,IAAI,KAAK,QAAQ;AACrC,KAAI,MAAM,KAAA,EAAW,QAAO,OAAO,UAAU,KAAK,CAAC;AACnD,QAAO,EAAE,aAAa,YAAY,QAAQ,KAAK,GAAG,OAAO,OAAO,MAAM,EAAE,OAAO,CAAC;EAChF,CACH"}
1
+ {"version":3,"file":"Approval.mjs","names":[],"sources":["../../src/tool/Approval.ts"],"sourcesContent":["/**\n * Approval helpers for the two transport flavors.\n *\n * These helpers only decide which calls are approved and which synthetic\n * results must be returned to the model. Tool execution stays explicit at\n * the recipe boundary via `Toolkit.run`.\n */\nimport { Data, Deferred, type Duration, Effect, Queue, Ref, Scope, Stream } from \"effect\"\nimport type { ToolCall } from \"../domain/Items.js\"\nimport { type ToolResult, cancelled, denied } from \"./ToolResult.js\"\nimport { ToolEvent } from \"./ToolEvent.js\"\n\nexport type ToolCallPlan = {\n readonly approved: ReadonlyArray<ToolCall>\n readonly rejected: ReadonlyArray<ToolResult>\n}\n\nexport type ApprovalDecision = Data.TaggedEnum<{\n Approved: { readonly call: ToolCall }\n Rejected: { readonly result: ToolResult }\n}>\n\nexport const ApprovalDecision = Data.taggedEnum<ApprovalDecision>()\n\nexport const approve = (call: ToolCall): ApprovalDecision => ApprovalDecision.Approved({ call })\n\nexport const reject = (result: ToolResult): ApprovalDecision =>\n ApprovalDecision.Rejected({ result })\n\nexport const splitApprovalDecisions = (decisions: ReadonlyArray<ApprovalDecision>): ToolCallPlan =>\n decisions.reduce<ToolCallPlan>(\n (acc, decision) =>\n decision._tag === \"Approved\"\n ? { ...acc, approved: [...acc.approved, decision.call] }\n : { ...acc, rejected: [...acc.rejected, decision.result] },\n { approved: [], rejected: [] },\n )\n\nexport const approvalRequested = (call: ToolCall): ToolEvent =>\n ToolEvent.ApprovalRequested({\n call_id: call.call_id,\n tool: call.name,\n arguments: call.arguments,\n })\n\n// ---------------------------------------------------------------------------\n// Verdict queue (WebSocket-style transport).\n// ---------------------------------------------------------------------------\n\nexport type Verdict = {\n readonly call_id: string\n readonly decision: \"approve\" | \"deny\"\n readonly reason?: string\n}\n\nexport type FromQueueOptions = {\n /**\n * Resolve any still-pending gated call as `cancelled` once this elapses,\n * so a lost or never-sent verdict cannot hang the decisions stream\n * forever. Omit to wait indefinitely.\n */\n readonly timeout?: Duration.Input\n}\n\n/**\n * Queue-backed approval planner. Safe calls are returned immediately in\n * `approved`; gated calls emit `ApprovalRequested` events and later produce\n * one `ApprovalDecision` when their matching verdict arrives.\n *\n * The verdict queue is a single-consumer transport: run one approval round\n * at a time (the router retires once every gated call of the round is\n * resolved). For overlapping rounds, use one queue per round.\n */\nexport const fromQueue =\n (\n predicate: (call: ToolCall) => boolean,\n verdicts: Queue.Dequeue<Verdict>,\n options?: FromQueueOptions,\n ) =>\n (\n calls: ReadonlyArray<ToolCall>,\n ): Effect.Effect<\n {\n readonly approved: ReadonlyArray<ToolCall>\n readonly decisions: Stream.Stream<ApprovalDecision>\n readonly approvalRequests: Stream.Stream<ToolEvent>\n },\n never,\n Scope.Scope\n > =>\n Effect.gen(function* () {\n const gated = calls.filter(predicate)\n const approved = calls.filter((call) => !predicate(call))\n\n const entries = yield* Effect.forEach(gated, (call) =>\n Deferred.make<ApprovalDecision>().pipe(Effect.map((d) => [call.call_id, d] as const)),\n )\n const deferreds: ReadonlyMap<string, Deferred.Deferred<ApprovalDecision>> = new Map(entries)\n const callById: ReadonlyMap<string, ToolCall> = new Map(gated.map((c) => [c.call_id, c]))\n const outstanding = yield* Ref.make(gated.length)\n\n // Complete a deferred once; decrement only on the winning transition so\n // a late verdict for an already-resolved call is a no-op.\n const resolve = (call: ToolCall, decision: ApprovalDecision) =>\n Deferred.succeed(deferreds.get(call.call_id)!, decision).pipe(\n Effect.flatMap((won) => (won ? Ref.update(outstanding, (n) => n - 1) : Effect.void)),\n )\n\n // Router retires once every gated call is resolved (by verdict or\n // timeout), so sequential rounds over one queue do not accumulate\n // racing routers. Recursive + suspended: stack-safe, no imperative loop.\n const route: Effect.Effect<void> = Effect.suspend(() =>\n Ref.get(outstanding).pipe(\n Effect.flatMap((n) =>\n n <= 0\n ? Effect.void\n : Queue.take(verdicts).pipe(\n Effect.flatMap((v) => {\n const call = callById.get(v.call_id)\n return (\n call === undefined\n ? Effect.void\n : resolve(\n call,\n v.decision === \"approve\"\n ? approve(call)\n : reject(denied(call, v.reason)),\n )\n ).pipe(Effect.andThen(route))\n }),\n ),\n ),\n ),\n )\n\n if (gated.length > 0) {\n yield* Effect.forkScoped(route)\n if (options?.timeout !== undefined) {\n yield* Effect.forkScoped(\n Effect.sleep(options.timeout).pipe(\n Effect.andThen(\n Effect.forEach(gated, (call) =>\n resolve(call, reject(cancelled(call, \"approval timed out\"))),\n ),\n ),\n ),\n )\n }\n }\n\n const decisions = Stream.fromIterable(gated).pipe(\n Stream.flatMap((call) => Stream.fromEffect(Deferred.await(deferreds.get(call.call_id)!)), {\n concurrency: \"unbounded\",\n }),\n )\n\n const approvalRequests = Stream.fromIterable<ToolEvent>(gated.map(approvalRequested))\n\n return { approved, decisions, approvalRequests }\n })\n\n// ---------------------------------------------------------------------------\n// Approval map (HTTP-style transport). Verdicts arrive synchronously\n// bundled in the request payload. Missing entries → cancelled.\n// ---------------------------------------------------------------------------\n\nexport type ApprovalMapEntry =\n | { readonly decision: \"approve\" }\n | { readonly decision: \"deny\"; readonly reason?: string }\n\nexport const fromMap =\n (predicate: (call: ToolCall) => boolean, approvals: ReadonlyMap<string, ApprovalMapEntry>) =>\n (calls: ReadonlyArray<ToolCall>): ToolCallPlan =>\n splitApprovalDecisions(\n calls.map((call) => {\n if (!predicate(call)) return approve(call)\n const v = approvals.get(call.call_id)\n if (v === undefined) return reject(cancelled(call))\n return v.decision === \"approve\" ? approve(call) : reject(denied(call, v.reason))\n }),\n )\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,mBAAmB,KAAK,YAA8B;AAEnE,MAAa,WAAW,SAAqC,iBAAiB,SAAS,EAAE,MAAM,CAAC;AAEhG,MAAa,UAAU,WACrB,iBAAiB,SAAS,EAAE,QAAQ,CAAC;AAEvC,MAAa,0BAA0B,cACrC,UAAU,QACP,KAAK,aACJ,SAAS,SAAS,aACd;CAAE,GAAG;CAAK,UAAU,CAAC,GAAG,IAAI,UAAU,SAAS,KAAK;CAAE,GACtD;CAAE,GAAG;CAAK,UAAU,CAAC,GAAG,IAAI,UAAU,SAAS,OAAO;CAAE,EAC9D;CAAE,UAAU,EAAE;CAAE,UAAU,EAAE;CAAE,CAC/B;AAEH,MAAa,qBAAqB,SAChC,UAAU,kBAAkB;CAC1B,SAAS,KAAK;CACd,MAAM,KAAK;CACX,WAAW,KAAK;CACjB,CAAC;;;;;;;;;;AA8BJ,MAAa,aAET,WACA,UACA,aAGA,UAUA,OAAO,IAAI,aAAa;CACtB,MAAM,QAAQ,MAAM,OAAO,UAAU;CACrC,MAAM,WAAW,MAAM,QAAQ,SAAS,CAAC,UAAU,KAAK,CAAC;CAEzD,MAAM,UAAU,OAAO,OAAO,QAAQ,QAAQ,SAC5C,SAAS,MAAwB,CAAC,KAAK,OAAO,KAAK,MAAM,CAAC,KAAK,SAAS,EAAE,CAAU,CAAC,CACtF;CACD,MAAM,YAAsE,IAAI,IAAI,QAAQ;CAC5F,MAAM,WAA0C,IAAI,IAAI,MAAM,KAAK,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;CACzF,MAAM,cAAc,OAAO,IAAI,KAAK,MAAM,OAAO;CAIjD,MAAM,WAAW,MAAgB,aAC/B,SAAS,QAAQ,UAAU,IAAI,KAAK,QAAQ,EAAG,SAAS,CAAC,KACvD,OAAO,SAAS,QAAS,MAAM,IAAI,OAAO,cAAc,MAAM,IAAI,EAAE,GAAG,OAAO,KAAM,CACrF;CAKH,MAAM,QAA6B,OAAO,cACxC,IAAI,IAAI,YAAY,CAAC,KACnB,OAAO,SAAS,MACd,KAAK,IACD,OAAO,OACP,MAAM,KAAK,SAAS,CAAC,KACnB,OAAO,SAAS,MAAM;EACpB,MAAM,OAAO,SAAS,IAAI,EAAE,QAAQ;AACpC,UACE,SAAS,KAAA,IACL,OAAO,OACP,QACE,MACA,EAAE,aAAa,YACX,QAAQ,KAAK,GACb,OAAO,OAAO,MAAM,EAAE,OAAO,CAAC,CACnC,EACL,KAAK,OAAO,QAAQ,MAAM,CAAC;GAC7B,CACH,CACN,CACF,CACF;AAED,KAAI,MAAM,SAAS,GAAG;AACpB,SAAO,OAAO,WAAW,MAAM;AAC/B,MAAI,SAAS,YAAY,KAAA,EACvB,QAAO,OAAO,WACZ,OAAO,MAAM,QAAQ,QAAQ,CAAC,KAC5B,OAAO,QACL,OAAO,QAAQ,QAAQ,SACrB,QAAQ,MAAM,OAAO,UAAU,MAAM,qBAAqB,CAAC,CAAC,CAC7D,CACF,CACF,CACF;;AAYL,QAAO;EAAE;EAAU,WARD,OAAO,aAAa,MAAM,CAAC,KAC3C,OAAO,SAAS,SAAS,OAAO,WAAW,SAAS,MAAM,UAAU,IAAI,KAAK,QAAQ,CAAE,CAAC,EAAE,EACxF,aAAa,aACd,CAAC,CAKwB;EAAE,kBAFL,OAAO,aAAwB,MAAM,IAAI,kBAAkB,CAEtC;EAAE;EAChD;AAWN,MAAa,WACV,WAAwC,eACxC,UACC,uBACE,MAAM,KAAK,SAAS;AAClB,KAAI,CAAC,UAAU,KAAK,CAAE,QAAO,QAAQ,KAAK;CAC1C,MAAM,IAAI,UAAU,IAAI,KAAK,QAAQ;AACrC,KAAI,MAAM,KAAA,EAAW,QAAO,OAAO,UAAU,KAAK,CAAC;AACnD,QAAO,EAAE,aAAa,YAAY,QAAQ,KAAK,GAAG,OAAO,OAAO,MAAM,EAAE,OAAO,CAAC;EAChF,CACH"}