@effect-uai/core 0.1.0 → 0.3.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 (149) hide show
  1. package/README.md +2 -2
  2. package/dist/{AiError-CqmYjXyx.d.mts → AiError-CBuPHVKA.d.mts} +1 -1
  3. package/dist/{AiError-CqmYjXyx.d.mts.map → AiError-CBuPHVKA.d.mts.map} +1 -1
  4. package/dist/Image-BZmKfIdq.d.mts +61 -0
  5. package/dist/Image-BZmKfIdq.d.mts.map +1 -0
  6. package/dist/{Items-D1C2686t.d.mts → Items-CB8Bo3FI.d.mts} +132 -80
  7. package/dist/Items-CB8Bo3FI.d.mts.map +1 -0
  8. package/dist/Media-D_CpcM1Z.d.mts +57 -0
  9. package/dist/Media-D_CpcM1Z.d.mts.map +1 -0
  10. package/dist/{StructuredFormat-B5ueioNr.d.mts → StructuredFormat-BWq5Hd1O.d.mts} +5 -5
  11. package/dist/StructuredFormat-BWq5Hd1O.d.mts.map +1 -0
  12. package/dist/{Tool-5wxOCuOh.d.mts → Tool-DjVufH7i.d.mts} +13 -13
  13. package/dist/Tool-DjVufH7i.d.mts.map +1 -0
  14. package/dist/{Turn-rlTfuHaQ.d.mts → Turn-OPaILVIB.d.mts} +12 -29
  15. package/dist/Turn-OPaILVIB.d.mts.map +1 -0
  16. package/dist/{chunk-CfYAbeIz.mjs → chunk-uyGKjUfl.mjs} +2 -1
  17. package/dist/dist-DV5ISja1.mjs +13782 -0
  18. package/dist/dist-DV5ISja1.mjs.map +1 -0
  19. package/dist/domain/AiError.d.mts +1 -1
  20. package/dist/domain/AiError.mjs +1 -1
  21. package/dist/domain/Image.d.mts +2 -0
  22. package/dist/domain/Image.mjs +58 -0
  23. package/dist/domain/Image.mjs.map +1 -0
  24. package/dist/domain/Items.d.mts +2 -2
  25. package/dist/domain/Items.mjs +19 -42
  26. package/dist/domain/Items.mjs.map +1 -1
  27. package/dist/domain/Media.d.mts +2 -0
  28. package/dist/domain/Media.mjs +14 -0
  29. package/dist/domain/Media.mjs.map +1 -0
  30. package/dist/domain/Turn.d.mts +2 -2
  31. package/dist/domain/Turn.mjs +12 -8
  32. package/dist/domain/Turn.mjs.map +1 -1
  33. package/dist/embedding-model/Embedding.d.mts +107 -0
  34. package/dist/embedding-model/Embedding.d.mts.map +1 -0
  35. package/dist/embedding-model/Embedding.mjs +18 -0
  36. package/dist/embedding-model/Embedding.mjs.map +1 -0
  37. package/dist/embedding-model/EmbeddingModel.d.mts +97 -0
  38. package/dist/embedding-model/EmbeddingModel.d.mts.map +1 -0
  39. package/dist/embedding-model/EmbeddingModel.mjs +17 -0
  40. package/dist/embedding-model/EmbeddingModel.mjs.map +1 -0
  41. package/dist/index.d.mts +16 -8
  42. package/dist/index.mjs +10 -2
  43. package/dist/language-model/LanguageModel.d.mts +12 -20
  44. package/dist/language-model/LanguageModel.d.mts.map +1 -1
  45. package/dist/language-model/LanguageModel.mjs +3 -20
  46. package/dist/language-model/LanguageModel.mjs.map +1 -1
  47. package/dist/loop/Loop.d.mts +111 -2
  48. package/dist/loop/Loop.d.mts.map +1 -0
  49. package/dist/loop/Loop.mjs +39 -6
  50. package/dist/loop/Loop.mjs.map +1 -1
  51. package/dist/loop/Loop.test.d.mts +1 -0
  52. package/dist/loop/Loop.test.mjs +411 -0
  53. package/dist/loop/Loop.test.mjs.map +1 -0
  54. package/dist/magic-string.es-BgIV5Mu3.mjs +1013 -0
  55. package/dist/magic-string.es-BgIV5Mu3.mjs.map +1 -0
  56. package/dist/math/Vector.d.mts +47 -0
  57. package/dist/math/Vector.d.mts.map +1 -0
  58. package/dist/math/Vector.mjs +117 -0
  59. package/dist/math/Vector.mjs.map +1 -0
  60. package/dist/observability/Metrics.d.mts +2 -2
  61. package/dist/observability/Metrics.d.mts.map +1 -1
  62. package/dist/observability/Metrics.mjs +1 -1
  63. package/dist/observability/Metrics.mjs.map +1 -1
  64. package/dist/streaming/JSONL.mjs +1 -1
  65. package/dist/streaming/JSONL.test.d.mts +1 -0
  66. package/dist/streaming/JSONL.test.mjs +70 -0
  67. package/dist/streaming/JSONL.test.mjs.map +1 -0
  68. package/dist/streaming/Lines.mjs +1 -1
  69. package/dist/streaming/SSE.d.mts +2 -2
  70. package/dist/streaming/SSE.d.mts.map +1 -1
  71. package/dist/streaming/SSE.mjs +1 -1
  72. package/dist/streaming/SSE.mjs.map +1 -1
  73. package/dist/streaming/SSE.test.d.mts +1 -0
  74. package/dist/streaming/SSE.test.mjs +72 -0
  75. package/dist/streaming/SSE.test.mjs.map +1 -0
  76. package/dist/structured-format/StructuredFormat.d.mts +1 -1
  77. package/dist/structured-format/StructuredFormat.mjs +1 -1
  78. package/dist/structured-format/StructuredFormat.mjs.map +1 -1
  79. package/dist/testing/MockProvider.d.mts +6 -6
  80. package/dist/testing/MockProvider.d.mts.map +1 -1
  81. package/dist/testing/MockProvider.mjs.map +1 -1
  82. package/dist/tool/HistoryCheck.d.mts +6 -3
  83. package/dist/tool/HistoryCheck.d.mts.map +1 -1
  84. package/dist/tool/HistoryCheck.mjs +7 -1
  85. package/dist/tool/HistoryCheck.mjs.map +1 -1
  86. package/dist/tool/Outcome.d.mts +138 -2
  87. package/dist/tool/Outcome.d.mts.map +1 -0
  88. package/dist/tool/Outcome.mjs +34 -18
  89. package/dist/tool/Outcome.mjs.map +1 -1
  90. package/dist/tool/Resolvers.d.mts +30 -25
  91. package/dist/tool/Resolvers.d.mts.map +1 -1
  92. package/dist/tool/Resolvers.mjs +54 -44
  93. package/dist/tool/Resolvers.mjs.map +1 -1
  94. package/dist/tool/Resolvers.test.d.mts +1 -0
  95. package/dist/tool/Resolvers.test.mjs +317 -0
  96. package/dist/tool/Resolvers.test.mjs.map +1 -0
  97. package/dist/tool/Tool.d.mts +1 -1
  98. package/dist/tool/Tool.mjs +1 -1
  99. package/dist/tool/Tool.mjs.map +1 -1
  100. package/dist/tool/ToolEvent.d.mts +151 -2
  101. package/dist/tool/ToolEvent.d.mts.map +1 -0
  102. package/dist/tool/ToolEvent.mjs +30 -4
  103. package/dist/tool/ToolEvent.mjs.map +1 -1
  104. package/dist/tool/Toolkit.d.mts +24 -15
  105. package/dist/tool/Toolkit.d.mts.map +1 -1
  106. package/dist/tool/Toolkit.mjs +14 -13
  107. package/dist/tool/Toolkit.mjs.map +1 -1
  108. package/dist/tool/Toolkit.test.d.mts +1 -0
  109. package/dist/tool/Toolkit.test.mjs +113 -0
  110. package/dist/tool/Toolkit.test.mjs.map +1 -0
  111. package/package.json +29 -13
  112. package/src/domain/Image.ts +75 -0
  113. package/src/domain/Items.ts +18 -47
  114. package/src/domain/Media.ts +61 -0
  115. package/src/domain/Turn.ts +7 -17
  116. package/src/embedding-model/Embedding.ts +117 -0
  117. package/src/embedding-model/EmbeddingModel.ts +107 -0
  118. package/src/index.ts +9 -1
  119. package/src/language-model/LanguageModel.ts +2 -22
  120. package/src/loop/Loop.test.ts +114 -2
  121. package/src/loop/Loop.ts +69 -5
  122. package/src/math/Vector.ts +138 -0
  123. package/src/observability/Metrics.ts +1 -1
  124. package/src/streaming/SSE.ts +1 -1
  125. package/src/structured-format/StructuredFormat.ts +2 -2
  126. package/src/testing/MockProvider.ts +2 -2
  127. package/src/tool/HistoryCheck.ts +2 -5
  128. package/src/tool/Outcome.ts +39 -53
  129. package/src/tool/Resolvers.test.ts +46 -117
  130. package/src/tool/Resolvers.ts +74 -102
  131. package/src/tool/Tool.ts +9 -9
  132. package/src/tool/ToolEvent.ts +30 -26
  133. package/src/tool/Toolkit.test.ts +97 -2
  134. package/src/tool/Toolkit.ts +65 -67
  135. package/dist/Items-D1C2686t.d.mts.map +0 -1
  136. package/dist/Loop-CzSJo1h8.d.mts +0 -87
  137. package/dist/Loop-CzSJo1h8.d.mts.map +0 -1
  138. package/dist/Outcome-C2JYknCu.d.mts +0 -40
  139. package/dist/Outcome-C2JYknCu.d.mts.map +0 -1
  140. package/dist/StructuredFormat-B5ueioNr.d.mts.map +0 -1
  141. package/dist/Tool-5wxOCuOh.d.mts.map +0 -1
  142. package/dist/ToolEvent-B2N10hr3.d.mts +0 -29
  143. package/dist/ToolEvent-B2N10hr3.d.mts.map +0 -1
  144. package/dist/Turn-rlTfuHaQ.d.mts.map +0 -1
  145. package/dist/match/Match.d.mts +0 -16
  146. package/dist/match/Match.d.mts.map +0 -1
  147. package/dist/match/Match.mjs +0 -15
  148. package/dist/match/Match.mjs.map +0 -1
  149. package/src/match/Match.ts +0 -9
@@ -1,2 +1,151 @@
1
- import { i as isOutput, n as isApprovalRequested, r as isIntermediate, t as ToolEvent } from "../ToolEvent-B2N10hr3.mjs";
2
- export { ToolEvent, isApprovalRequested, isIntermediate, isOutput };
1
+ import { ToolResult } from "./Outcome.mjs";
2
+ import { Data } from "effect";
3
+ import * as _$effect_Unify0 from "effect/Unify";
4
+
5
+ //#region src/tool/ToolEvent.d.ts
6
+ declare namespace ToolEvent_d_exports {
7
+ export { ToolEvent, isApprovalRequested, isIntermediate, isOutput };
8
+ }
9
+ type ToolEvent = Data.TaggedEnum<{
10
+ ApprovalRequested: {
11
+ readonly call_id: string;
12
+ readonly tool: string;
13
+ readonly arguments: string;
14
+ };
15
+ Intermediate: {
16
+ readonly call_id: string;
17
+ readonly tool: string;
18
+ readonly data: unknown;
19
+ };
20
+ Output: {
21
+ readonly result: ToolResult;
22
+ };
23
+ }>;
24
+ /**
25
+ * Namespace of constructors, type guards, and matchers for `ToolEvent`,
26
+ * provided by `Data.taggedEnum`. Use `ToolEvent.Output({ result })` to build
27
+ * an event, `ToolEvent.$is("Output")` for type narrowing,
28
+ * `ToolEvent.$match({ ApprovalRequested, Intermediate, Output })` for
29
+ * exhaustive pattern matching.
30
+ */
31
+ declare const ToolEvent: {
32
+ readonly ApprovalRequested: Data.TaggedEnum.ConstructorFrom<{
33
+ readonly _tag: "ApprovalRequested";
34
+ readonly call_id: string;
35
+ readonly tool: string;
36
+ readonly arguments: string;
37
+ }, "_tag">;
38
+ readonly Intermediate: Data.TaggedEnum.ConstructorFrom<{
39
+ readonly _tag: "Intermediate";
40
+ readonly call_id: string;
41
+ readonly tool: string;
42
+ readonly data: unknown;
43
+ }, "_tag">;
44
+ readonly Output: Data.TaggedEnum.ConstructorFrom<{
45
+ readonly _tag: "Output";
46
+ readonly result: ToolResult;
47
+ }, "_tag">;
48
+ readonly $is: <Tag extends "ApprovalRequested" | "Intermediate" | "Output">(tag: Tag) => (u: unknown) => u is Extract<{
49
+ readonly _tag: "ApprovalRequested";
50
+ readonly call_id: string;
51
+ readonly tool: string;
52
+ readonly arguments: string;
53
+ }, {
54
+ readonly _tag: Tag;
55
+ }> | Extract<{
56
+ readonly _tag: "Intermediate";
57
+ readonly call_id: string;
58
+ readonly tool: string;
59
+ readonly data: unknown;
60
+ }, {
61
+ readonly _tag: Tag;
62
+ }> | Extract<{
63
+ readonly _tag: "Output";
64
+ readonly result: ToolResult;
65
+ }, {
66
+ readonly _tag: Tag;
67
+ }>;
68
+ readonly $match: {
69
+ <Cases extends {
70
+ readonly ApprovalRequested: (args: {
71
+ readonly _tag: "ApprovalRequested";
72
+ readonly call_id: string;
73
+ readonly tool: string;
74
+ readonly arguments: string;
75
+ }) => any;
76
+ readonly Intermediate: (args: {
77
+ readonly _tag: "Intermediate";
78
+ readonly call_id: string;
79
+ readonly tool: string;
80
+ readonly data: unknown;
81
+ }) => any;
82
+ readonly Output: (args: {
83
+ readonly _tag: "Output";
84
+ readonly result: ToolResult;
85
+ }) => any;
86
+ }>(cases: Cases): (value: {
87
+ readonly _tag: "ApprovalRequested";
88
+ readonly call_id: string;
89
+ readonly tool: string;
90
+ readonly arguments: string;
91
+ } | {
92
+ readonly _tag: "Intermediate";
93
+ readonly call_id: string;
94
+ readonly tool: string;
95
+ readonly data: unknown;
96
+ } | {
97
+ readonly _tag: "Output";
98
+ readonly result: ToolResult;
99
+ }) => _$effect_Unify0.Unify<ReturnType<Cases["ApprovalRequested" | "Intermediate" | "Output"]>>;
100
+ <Cases extends {
101
+ readonly ApprovalRequested: (args: {
102
+ readonly _tag: "ApprovalRequested";
103
+ readonly call_id: string;
104
+ readonly tool: string;
105
+ readonly arguments: string;
106
+ }) => any;
107
+ readonly Intermediate: (args: {
108
+ readonly _tag: "Intermediate";
109
+ readonly call_id: string;
110
+ readonly tool: string;
111
+ readonly data: unknown;
112
+ }) => any;
113
+ readonly Output: (args: {
114
+ readonly _tag: "Output";
115
+ readonly result: ToolResult;
116
+ }) => any;
117
+ }>(value: {
118
+ readonly _tag: "ApprovalRequested";
119
+ readonly call_id: string;
120
+ readonly tool: string;
121
+ readonly arguments: string;
122
+ } | {
123
+ readonly _tag: "Intermediate";
124
+ readonly call_id: string;
125
+ readonly tool: string;
126
+ readonly data: unknown;
127
+ } | {
128
+ readonly _tag: "Output";
129
+ readonly result: ToolResult;
130
+ }, cases: Cases): _$effect_Unify0.Unify<ReturnType<Cases["ApprovalRequested" | "Intermediate" | "Output"]>>;
131
+ };
132
+ };
133
+ declare const isApprovalRequested: (u: unknown) => u is {
134
+ readonly _tag: "ApprovalRequested";
135
+ readonly call_id: string;
136
+ readonly tool: string;
137
+ readonly arguments: string;
138
+ };
139
+ declare const isIntermediate: (u: unknown) => u is {
140
+ readonly _tag: "Intermediate";
141
+ readonly call_id: string;
142
+ readonly tool: string;
143
+ readonly data: unknown;
144
+ };
145
+ declare const isOutput: (u: unknown) => u is {
146
+ readonly _tag: "Output";
147
+ readonly result: ToolResult;
148
+ };
149
+ //#endregion
150
+ export { ToolEvent, isApprovalRequested, isIntermediate, isOutput, ToolEvent_d_exports as t };
151
+ //# sourceMappingURL=ToolEvent.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolEvent.d.mts","names":[],"sources":["../../src/tool/ToolEvent.ts"],"mappings":";;;;;;;;KAaY,SAAA,GAAY,IAAA,CAAK,UAAA;EAC3B,iBAAA;IAAA,SACW,OAAA;IAAA,SACA,IAAA;IAAA,SACA,SAAA;EAAA;EAEX,YAAA;IAAA,SACW,OAAA;IAAA,SACA,IAAA;IAAA,SACA,IAAA;EAAA;EAEX,MAAA;IAAA,SACW,MAAA,EAAQ,UAAA;EAAA;AAAA;;;;;AAWrB;;;cAAa,SAAA;EAAA;;;;;;;;;;;;;;qBAXQ,UAAA;EAAA;EAAA;;;;;;;;;;;;;;;;qBAAA,UAAA;EAAA;IAAA;;;;;;;;;;;;;;;;;;yBAAA,UAAA;MAAA;IAAA;;;;;;;;;;;;uBAAA,UAAA;IAAA;;;;;;;;;;;;;;;;yBAAA,UAAA;MAAA;IAAA;;;;;;;;;;;;uBAAA,UAAA;IAAA;;;cAaR,mBAAA,GAAmB,CAAA,cAAA,CAAA;EAAA;;;;;cACnB,cAAA,GAAc,CAAA,cAAA,CAAA;EAAA;;;;;cACd,QAAA,GAAQ,CAAA,cAAA,CAAA;EAAA;mBAfA,UAAA;AAAA"}
@@ -1,8 +1,34 @@
1
+ import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
2
+ import { Data } from "effect";
1
3
  //#region src/tool/ToolEvent.ts
2
- const isApprovalRequested = (e) => e._tag === "ApprovalRequested";
3
- const isIntermediate = (e) => e._tag === "Intermediate";
4
- const isOutput = (e) => e._tag === "Output";
4
+ /**
5
+ * The event type emitted while handling tool calls.
6
+ *
7
+ * - ApprovalRequested : gated calls waiting for approval
8
+ * - Intermediate : per-element passthrough from a streaming tool's run
9
+ * - Output : terminal result (carries a structured ToolResult)
10
+ *
11
+ * Recipes thread `ToolEvent.Output.result` through `continueWith` and apply
12
+ * `toFunctionCallOutput` when appending to history.
13
+ */
14
+ var ToolEvent_exports = /* @__PURE__ */ __exportAll({
15
+ ToolEvent: () => ToolEvent,
16
+ isApprovalRequested: () => isApprovalRequested,
17
+ isIntermediate: () => isIntermediate,
18
+ isOutput: () => isOutput
19
+ });
20
+ /**
21
+ * Namespace of constructors, type guards, and matchers for `ToolEvent`,
22
+ * provided by `Data.taggedEnum`. Use `ToolEvent.Output({ result })` to build
23
+ * an event, `ToolEvent.$is("Output")` for type narrowing,
24
+ * `ToolEvent.$match({ ApprovalRequested, Intermediate, Output })` for
25
+ * exhaustive pattern matching.
26
+ */
27
+ const ToolEvent = Data.taggedEnum();
28
+ const isApprovalRequested = ToolEvent.$is("ApprovalRequested");
29
+ const isIntermediate = ToolEvent.$is("Intermediate");
30
+ const isOutput = ToolEvent.$is("Output");
5
31
  //#endregion
6
- export { isApprovalRequested, isIntermediate, isOutput };
32
+ export { ToolEvent, isApprovalRequested, isIntermediate, isOutput, ToolEvent_exports as t };
7
33
 
8
34
  //# sourceMappingURL=ToolEvent.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolEvent.mjs","names":[],"sources":["../../src/tool/ToolEvent.ts"],"sourcesContent":["/**\n * The event type emitted by `Toolkit.executeAllWithResolver`.\n *\n * - ApprovalRequested : gated calls before resolver returns\n * - Intermediate : per-element passthrough from a streaming tool's run\n * - Output : terminal result (carries a structured ToolResult)\n *\n * Recipes thread `ToolEvent.Output.result` through `nextStateFrom` and apply\n * `toFunctionCallOutput` when appending to history.\n */\nimport type { ToolResult } from \"./Outcome.js\"\n\nexport type ToolEvent =\n | {\n readonly _tag: \"ApprovalRequested\"\n readonly call_id: string\n readonly tool: string\n readonly arguments: string\n }\n | {\n readonly _tag: \"Intermediate\"\n readonly call_id: string\n readonly tool: string\n readonly data: unknown\n }\n | { readonly _tag: \"Output\"; readonly result: ToolResult }\n\nexport const isApprovalRequested = (\n e: ToolEvent,\n): e is Extract<ToolEvent, { _tag: \"ApprovalRequested\" }> => e._tag === \"ApprovalRequested\"\n\nexport const isIntermediate = (\n e: ToolEvent,\n): e is Extract<ToolEvent, { _tag: \"Intermediate\" }> => e._tag === \"Intermediate\"\n\nexport const isOutput = (e: ToolEvent): e is Extract<ToolEvent, { _tag: \"Output\" }> =>\n e._tag === \"Output\"\n"],"mappings":";AA2BA,MAAa,uBACX,MAC2D,EAAE,SAAS;AAExE,MAAa,kBACX,MACsD,EAAE,SAAS;AAEnE,MAAa,YAAY,MACvB,EAAE,SAAS"}
1
+ {"version":3,"file":"ToolEvent.mjs","names":[],"sources":["../../src/tool/ToolEvent.ts"],"sourcesContent":["/**\n * The event type emitted while handling tool calls.\n *\n * - ApprovalRequested : gated calls waiting for approval\n * - Intermediate : per-element passthrough from a streaming tool's run\n * - Output : terminal result (carries a structured ToolResult)\n *\n * Recipes thread `ToolEvent.Output.result` through `continueWith` and apply\n * `toFunctionCallOutput` when appending to history.\n */\nimport { Data } from \"effect\"\nimport type { ToolResult } from \"./Outcome.js\"\n\nexport type ToolEvent = Data.TaggedEnum<{\n ApprovalRequested: {\n readonly call_id: string\n readonly tool: string\n readonly arguments: string\n }\n Intermediate: {\n readonly call_id: string\n readonly tool: string\n readonly data: unknown\n }\n Output: {\n readonly result: ToolResult\n }\n}>\n\n/**\n * Namespace of constructors, type guards, and matchers for `ToolEvent`,\n * provided by `Data.taggedEnum`. Use `ToolEvent.Output({ result })` to build\n * an event, `ToolEvent.$is(\"Output\")` for type narrowing,\n * `ToolEvent.$match({ ApprovalRequested, Intermediate, Output })` for\n * exhaustive pattern matching.\n */\nexport const ToolEvent = Data.taggedEnum<ToolEvent>()\n\nexport const isApprovalRequested = ToolEvent.$is(\"ApprovalRequested\")\nexport const isIntermediate = ToolEvent.$is(\"Intermediate\")\nexport const isOutput = ToolEvent.$is(\"Output\")\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,MAAa,YAAY,KAAK,YAAuB;AAErD,MAAa,sBAAsB,UAAU,IAAI,oBAAoB;AACrE,MAAa,iBAAiB,UAAU,IAAI,eAAe;AAC3D,MAAa,WAAW,UAAU,IAAI,SAAS"}
@@ -1,19 +1,25 @@
1
- import { o as FunctionCall } from "../Items-D1C2686t.mjs";
2
- import { a as Tool, o as ToolDescriptor, t as AnyKindTool } from "../Tool-5wxOCuOh.mjs";
3
- import { t as Event } from "../Loop-CzSJo1h8.mjs";
4
- import { n as ToolResult, t as ToolDecision } from "../Outcome-C2JYknCu.mjs";
5
- import { t as ToolEvent } from "../ToolEvent-B2N10hr3.mjs";
6
- import { Effect, Stream } from "effect";
1
+ import { o as FunctionCall } from "../Items-CB8Bo3FI.mjs";
2
+ import { a as Tool, i as StreamingTool, o as ToolDescriptor, t as AnyKindTool } from "../Tool-DjVufH7i.mjs";
3
+ import { Event } from "../loop/Loop.mjs";
4
+ import { ToolResult } from "./Outcome.mjs";
5
+ import { ToolEvent } from "./ToolEvent.mjs";
6
+ import { Stream } from "effect";
7
7
 
8
8
  //#region src/tool/Toolkit.d.ts
9
9
  declare namespace Toolkit_d_exports {
10
- export { AnyTool, ExecuteOptions, Resolver, Toolkit, ToolsR, executeAll, executeAllWithResolver, make, nextStateFrom, toDescriptors };
10
+ export { AnyTool, ExecuteOptions, ToolKindR, Toolkit, ToolsR, continueWith, executeAll, make, outputEvent, outputEvents, toDescriptors };
11
11
  }
12
12
  type AnyTool = Tool<string, any, any, any>;
13
13
  type Toolkit<Tools extends ReadonlyArray<AnyTool>> = {
14
14
  readonly tools: Tools;
15
15
  };
16
16
  type ToolsR<Tools extends ReadonlyArray<AnyTool>> = Tools[number] extends Tool<any, any, any, infer R> ? R : never;
17
+ /**
18
+ * Union of every tool's `R` requirements in a mixed plain + streaming array.
19
+ * Used by `executeAll` to surface the services tools need at the recipe
20
+ * level, so the loop's stream type carries them through to `Effect.provide`.
21
+ */
22
+ type ToolKindR<Tools extends ReadonlyArray<AnyKindTool<any>>> = Tools[number] extends StreamingTool<any, any, any, any, infer R> ? R : Tools[number] extends Tool<any, any, any, infer R> ? R : never;
17
23
  declare const make: <const Tools extends ReadonlyArray<AnyTool>>(tools: Tools) => Toolkit<Tools>;
18
24
  /**
19
25
  * Render every tool in a toolkit to a provider-agnostic descriptor.
@@ -21,14 +27,17 @@ declare const make: <const Tools extends ReadonlyArray<AnyTool>>(tools: Tools) =
21
27
  * Standard Schema converter (draft 2020-12).
22
28
  */
23
29
  declare const toDescriptors: <Tools extends ReadonlyArray<AnyTool>>(toolkit: Toolkit<Tools>) => ReadonlyArray<ToolDescriptor>;
24
- type Resolver = (call: FunctionCall) => Effect.Effect<ToolDecision>;
25
- interface ExecuteOptions {
30
+ type ExecuteOptions = {
26
31
  readonly concurrency?: number | "unbounded";
27
- }
28
- declare const executeAllWithResolver: (tools: ReadonlyArray<AnyKindTool>, calls: ReadonlyArray<FunctionCall>, resolve: Resolver, options?: ExecuteOptions) => Stream.Stream<ToolEvent>;
29
- /** No-resolver shortcut: every call gets `Execute`. */
30
- declare const executeAll: (tools: ReadonlyArray<AnyKindTool>, calls: ReadonlyArray<FunctionCall>, options?: ExecuteOptions) => Stream.Stream<ToolEvent>;
31
- declare const nextStateFrom: <S>(stream: Stream.Stream<ToolEvent>, build: (results: ReadonlyArray<ToolResult>) => S) => Stream.Stream<Event<ToolEvent, S>>;
32
+ };
33
+ /** Execute every provided call. Approval/rejection policy belongs upstream. */
34
+ declare const executeAll: <Tools extends ReadonlyArray<AnyKindTool<any>>>(tools: Tools, calls: ReadonlyArray<FunctionCall>, options?: ExecuteOptions) => Stream.Stream<ToolEvent, never, ToolKindR<Tools>>;
35
+ declare const outputEvent: (result: ToolResult) => ToolEvent;
36
+ declare const outputEvents: (results: ReadonlyArray<ToolResult>) => Stream.Stream<ToolEvent>;
37
+ declare const continueWith: {
38
+ <S>(build: (results: ReadonlyArray<ToolResult>) => S): <R>(stream: Stream.Stream<ToolEvent, never, R>) => Stream.Stream<Event<ToolEvent, S>, never, R>;
39
+ <S, R>(stream: Stream.Stream<ToolEvent, never, R>, build: (results: ReadonlyArray<ToolResult>) => S): Stream.Stream<Event<ToolEvent, S>, never, R>;
40
+ };
32
41
  //#endregion
33
- export { AnyTool, ExecuteOptions, Resolver, Toolkit, ToolsR, executeAll, executeAllWithResolver, make, nextStateFrom, Toolkit_d_exports as t, toDescriptors };
42
+ export { AnyTool, ExecuteOptions, ToolKindR, Toolkit, ToolsR, continueWith, executeAll, make, outputEvent, outputEvents, Toolkit_d_exports as t, toDescriptors };
34
43
  //# sourceMappingURL=Toolkit.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toolkit.d.mts","names":[],"sources":["../../src/tool/Toolkit.ts"],"mappings":";;;;;;;;;;;KAqBY,OAAA,GAAU,IAAA;AAAA,KAEV,OAAA,eAAsB,aAAA,CAAc,OAAA;EAAA,SACrC,KAAA,EAAO,KAAA;AAAA;AAAA,KAGN,MAAA,eAAqB,aAAA,CAAc,OAAA,KAC7C,KAAA,iBAAsB,IAAA,2BAA+B,CAAA;AAAA,cAE1C,IAAA,uBAA4B,aAAA,CAAc,OAAA,GAAU,KAAA,EAAO,KAAA,KAAQ,OAAA,CAAQ,KAAA;;;;;;cAS3E,aAAA,iBAA+B,aAAA,CAAc,OAAA,GACxD,OAAA,EAAS,OAAA,CAAQ,KAAA,MAChB,aAAA,CAAc,cAAA;AAAA,KAmBL,QAAA,IAAY,IAAA,EAAM,YAAA,KAAiB,MAAA,CAAO,MAAA,CAAO,YAAA;AAAA,UAE5C,cAAA;EAAA,SACN,WAAA;AAAA;AAAA,cAGE,sBAAA,GACX,KAAA,EAAO,aAAA,CAAc,WAAA,GACrB,KAAA,EAAO,aAAA,CAAc,YAAA,GACrB,OAAA,EAAS,QAAA,EACT,OAAA,GAAU,cAAA,KACT,MAAA,CAAO,MAAA,CAAO,SAAA;;cAYJ,UAAA,GACX,KAAA,EAAO,aAAA,CAAc,WAAA,GACrB,KAAA,EAAO,aAAA,CAAc,YAAA,GACrB,OAAA,GAAU,cAAA,KACT,MAAA,CAAO,MAAA,CAAO,SAAA;AAAA,cAmIJ,aAAA,MACX,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,SAAA,GACtB,KAAA,GAAQ,OAAA,EAAS,aAAA,CAAc,UAAA,MAAgB,CAAA,KAC9C,MAAA,CAAO,MAAA,CAAO,KAAA,CAAW,SAAA,EAAW,CAAA"}
1
+ {"version":3,"file":"Toolkit.d.mts","names":[],"sources":["../../src/tool/Toolkit.ts"],"mappings":";;;;;;;;;;;KAgBY,OAAA,GAAU,IAAA;AAAA,KAEV,OAAA,eAAsB,aAAA,CAAc,OAAA;EAAA,SACrC,KAAA,EAAO,KAAA;AAAA;AAAA,KAGN,MAAA,eAAqB,aAAA,CAAc,OAAA,KAC7C,KAAA,iBAAsB,IAAA,2BAA+B,CAAA;;;;;;KAO3C,SAAA,eAAwB,aAAA,CAAc,WAAA,UAChD,KAAA,iBAAsB,aAAA,gCAClB,CAAA,GACA,KAAA,iBAAsB,IAAA,2BACpB,CAAA;AAAA,cAGK,IAAA,uBAA4B,aAAA,CAAc,OAAA,GAAU,KAAA,EAAO,KAAA,KAAQ,OAAA,CAAQ,KAAA;;;;;AArBxF;cA8Ba,aAAA,iBAA+B,aAAA,CAAc,OAAA,GACxD,OAAA,EAAS,OAAA,CAAQ,KAAA,MAChB,aAAA,CAAc,cAAA;AAAA,KAgBL,cAAA;EAAA,SACD,WAAA;AAAA;AA/CX;AAAA,cAmDa,UAAA,iBAA4B,aAAA,CAAc,WAAA,QACrD,KAAA,EAAO,KAAA,EACP,KAAA,EAAO,aAAA,CAAc,YAAA,GACrB,OAAA,GAAU,cAAA,KACT,MAAA,CAAO,MAAA,CAAO,SAAA,SAAkB,SAAA,CAAU,KAAA;AAAA,cAOhC,WAAA,GAAe,MAAA,EAAQ,UAAA,KAAa,SAAA;AAAA,cAEpC,YAAA,GAAgB,OAAA,EAAS,aAAA,CAAc,UAAA,MAAc,MAAA,CAAO,MAAA,CAAO,SAAA;AAAA,cAyHnE,YAAA;EAAA,IAET,KAAA,GAAQ,OAAA,EAAS,aAAA,CAAc,UAAA,MAAgB,CAAA,OAE/C,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,SAAA,SAAkB,CAAA,MACrC,MAAA,CAAO,MAAA,CAAO,KAAA,CAAW,SAAA,EAAW,CAAA,UAAW,CAAA;EAAA,OAElD,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,SAAA,SAAkB,CAAA,GACxC,KAAA,GAAQ,OAAA,EAAS,aAAA,CAAc,UAAA,MAAgB,CAAA,GAC9C,MAAA,CAAO,MAAA,CAAO,KAAA,CAAW,SAAA,EAAW,CAAA,UAAW,CAAA;AAAA"}
@@ -1,15 +1,16 @@
1
- import { t as __exportAll } from "../chunk-CfYAbeIz.mjs";
1
+ import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
2
2
  import { nextAfterFold } from "../loop/Loop.mjs";
3
3
  import { isStreamingTool } from "./Tool.mjs";
4
- import { execute, executionError, rejected } from "./Outcome.mjs";
4
+ import { executionError, rejected } from "./Outcome.mjs";
5
5
  import { isOutput } from "./ToolEvent.mjs";
6
- import { Array, Effect, Match, Ref, Stream } from "effect";
6
+ import { Array, Effect, Function, Ref, Stream } from "effect";
7
7
  //#region src/tool/Toolkit.ts
8
8
  var Toolkit_exports = /* @__PURE__ */ __exportAll({
9
+ continueWith: () => continueWith,
9
10
  executeAll: () => executeAll,
10
- executeAllWithResolver: () => executeAllWithResolver,
11
11
  make: () => make,
12
- nextStateFrom: () => nextStateFrom,
12
+ outputEvent: () => outputEvent,
13
+ outputEvents: () => outputEvents,
13
14
  toDescriptors: () => toDescriptors
14
15
  });
15
16
  const make = (tools) => ({ tools });
@@ -31,13 +32,13 @@ const toDescriptors = (toolkit) => toolkit.tools.map((tool) => {
31
32
  inputSchema
32
33
  };
33
34
  });
34
- const executeAllWithResolver = (tools, calls, resolve, options) => Stream.fromIterable(calls).pipe(Stream.flatMap((call) => Stream.unwrap(resolve(call).pipe(Effect.map((decision) => dispatch(tools, call, decision)))), { concurrency: options?.concurrency ?? "unbounded" }));
35
- /** No-resolver shortcut: every call gets `Execute`. */
36
- const executeAll = (tools, calls, options) => executeAllWithResolver(tools, calls, () => Effect.succeed(execute), options);
37
- const dispatch = (tools, call, decision) => Match.value(decision).pipe(Match.tag("Execute", () => runOne(tools, call)), Match.tag("Reject", (d) => Stream.succeed({
35
+ /** Execute every provided call. Approval/rejection policy belongs upstream. */
36
+ const executeAll = (tools, calls, options) => Stream.fromIterable(calls).pipe(Stream.flatMap((call) => runOne(tools, call), { concurrency: options?.concurrency ?? "unbounded" }));
37
+ const outputEvent = (result) => ({
38
38
  _tag: "Output",
39
- result: d.result
40
- })), Match.exhaustive);
39
+ result
40
+ });
41
+ const outputEvents = (results) => Stream.fromIterable(results.map(outputEvent));
41
42
  const valueResult = (call, tool, value) => ({
42
43
  _tag: "Value",
43
44
  call_id: call.call_id,
@@ -98,8 +99,8 @@ const runStreaming = (tool, call) => Stream.unwrap(Effect.gen(function* () {
98
99
  _tag: "Output",
99
100
  result: executionError(call, "Tool execution failed")
100
101
  })));
101
- const nextStateFrom = (stream, build) => nextAfterFold(stream, [], (acc, e) => isOutput(e) ? Array.append(acc, e.result) : acc, build);
102
+ const continueWith = Function.dual(2, (stream, build) => nextAfterFold(stream, [], (acc, e) => isOutput(e) ? Array.append(acc, e.result) : acc, build));
102
103
  //#endregion
103
- export { executeAll, executeAllWithResolver, make, nextStateFrom, Toolkit_exports as t, toDescriptors };
104
+ export { continueWith, executeAll, make, outputEvent, outputEvents, Toolkit_exports as t, toDescriptors };
104
105
 
105
106
  //# sourceMappingURL=Toolkit.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toolkit.mjs","names":["executeDecision","Arr","Loop.nextAfterFold"],"sources":["../../src/tool/Toolkit.ts"],"sourcesContent":["import { Array as Arr, Effect, Match, Ref, Stream } from \"effect\"\nimport * as Loop from \"../loop/Loop.js\"\nimport type { FunctionCall } from \"../domain/Items.js\"\nimport {\n type AnyKindTool,\n type AnyPlainTool,\n type AnyStreamingTool,\n isStreamingTool,\n type Tool,\n type ToolDescriptor,\n} from \"./Tool.js\"\nimport {\n type ToolDecision,\n type ToolResult,\n execute as executeDecision,\n executionError,\n rejected,\n} from \"./Outcome.js\"\nimport type { ToolEvent } from \"./ToolEvent.js\"\nimport { isOutput } from \"./ToolEvent.js\"\n\nexport type AnyTool = Tool<string, any, any, any>\n\nexport type Toolkit<Tools extends ReadonlyArray<AnyTool>> = {\n readonly tools: Tools\n}\n\nexport type ToolsR<Tools extends ReadonlyArray<AnyTool>> =\n Tools[number] extends Tool<any, any, any, infer R> ? R : never\n\nexport const make = <const Tools extends ReadonlyArray<AnyTool>>(tools: Tools): Toolkit<Tools> => ({\n tools,\n})\n\n/**\n * Render every tool in a toolkit to a provider-agnostic descriptor.\n * `inputSchema` is the JSON Schema document produced by the tool's\n * Standard Schema converter (draft 2020-12).\n */\nexport const toDescriptors = <Tools extends ReadonlyArray<AnyTool>>(\n toolkit: Toolkit<Tools>,\n): ReadonlyArray<ToolDescriptor> =>\n toolkit.tools.map((tool) => {\n const inputSchema = tool.inputSchema[\"~standard\"].jsonSchema.input({\n target: \"draft-2020-12\",\n })\n return tool.strict !== undefined\n ? { name: tool.name, description: tool.description, inputSchema, strict: tool.strict }\n : { name: tool.name, description: tool.description, inputSchema }\n })\n\n// ---------------------------------------------------------------------------\n// Resolver-based executor. Streams `ToolEvent`s in real time, dispatches\n// streaming and plain tools uniformly, and lets the caller decide what\n// happens to each call (Execute or Reject) before execution.\n//\n// `executeAllWithResolver` is the general primitive. `executeAllStream` is\n// the no-resolver shortcut.\n// ---------------------------------------------------------------------------\n\nexport type Resolver = (call: FunctionCall) => Effect.Effect<ToolDecision>\n\nexport interface ExecuteOptions {\n readonly concurrency?: number | \"unbounded\"\n}\n\nexport const executeAllWithResolver = (\n tools: ReadonlyArray<AnyKindTool>,\n calls: ReadonlyArray<FunctionCall>,\n resolve: Resolver,\n options?: ExecuteOptions,\n): Stream.Stream<ToolEvent> =>\n Stream.fromIterable(calls).pipe(\n Stream.flatMap(\n (call) =>\n Stream.unwrap(\n resolve(call).pipe(Effect.map((decision) => dispatch(tools, call, decision))),\n ),\n { concurrency: options?.concurrency ?? \"unbounded\" },\n ),\n )\n\n/** No-resolver shortcut: every call gets `Execute`. */\nexport const executeAll = (\n tools: ReadonlyArray<AnyKindTool>,\n calls: ReadonlyArray<FunctionCall>,\n options?: ExecuteOptions,\n): Stream.Stream<ToolEvent> =>\n executeAllWithResolver(tools, calls, () => Effect.succeed(executeDecision), options)\n\nconst dispatch = (\n tools: ReadonlyArray<AnyKindTool>,\n call: FunctionCall,\n decision: ToolDecision,\n): Stream.Stream<ToolEvent> =>\n Match.value(decision).pipe(\n Match.tag(\"Execute\", () => runOne(tools, call)),\n Match.tag(\"Reject\", (d) =>\n Stream.succeed<ToolEvent>({ _tag: \"Output\", result: d.result }),\n ),\n Match.exhaustive,\n )\n\nconst valueResult = (call: FunctionCall, tool: string, value: unknown): ToolResult => ({\n _tag: \"Value\",\n call_id: call.call_id,\n tool,\n value,\n})\n\nconst runOne = (\n tools: ReadonlyArray<AnyKindTool>,\n call: FunctionCall,\n): Stream.Stream<ToolEvent> => {\n const tool = tools.find((t) => t.name === call.name)\n if (tool === undefined) {\n // Graceful: emit a synthetic Failure so OTHER calls in this turn\n // still execute. LLMs hallucinate tool names; MCP tools come and go.\n return Stream.succeed<ToolEvent>({\n _tag: \"Output\",\n result: rejected(call, \"unknown_tool\", `No tool registered with name \"${call.name}\"`),\n })\n }\n if (isStreamingTool(tool)) return runStreaming(tool, call)\n return runPlain(tool, call)\n}\n\nconst runPlain = (\n tool: AnyPlainTool,\n call: FunctionCall,\n): Stream.Stream<ToolEvent> =>\n Stream.fromEffect(\n Effect.gen(function* () {\n const parsed = yield* Effect.try({\n try: () => JSON.parse(call.arguments) as unknown,\n catch: () => \"json_parse_error\" as const,\n })\n const validated = yield* Effect.tryPromise({\n try: () => Promise.resolve(tool.inputSchema[\"~standard\"].validate(parsed)),\n catch: () => \"validation_threw\" as const,\n })\n if (validated.issues !== undefined) {\n return executionError(call, \"Tool input failed schema validation\")\n }\n const output = yield* tool.run(validated.value)\n return valueResult(call, tool.name, output)\n }).pipe(\n Effect.catchCause(() => Effect.succeed(executionError(call, \"Tool execution failed\"))),\n Effect.map((result) => ({ _tag: \"Output\", result }) satisfies ToolEvent),\n ),\n )\n\nconst runStreaming = (\n tool: AnyStreamingTool,\n call: FunctionCall,\n): Stream.Stream<ToolEvent> =>\n Stream.unwrap(\n Effect.gen(function* () {\n const parsed = yield* Effect.try({\n try: () => JSON.parse(call.arguments) as unknown,\n catch: () => \"json_parse_error\" as const,\n })\n const validated = yield* Effect.tryPromise({\n try: () => Promise.resolve(tool.inputSchema[\"~standard\"].validate(parsed)),\n catch: () => \"validation_threw\" as const,\n })\n if (validated.issues !== undefined) {\n return Stream.succeed<ToolEvent>({\n _tag: \"Output\",\n result: executionError(call, \"Tool input failed schema validation\"),\n })\n }\n\n // Real-time: tap each event into a Ref as it flows; emit one\n // Intermediate per event; then concat one synthetic Output element\n // built from the accumulated Ref via `finalize`.\n const ref = yield* Ref.make<Array<unknown>>([])\n const intermediates = tool.run(validated.value).pipe(\n Stream.tap((event) => Ref.update(ref, Arr.append(event))),\n Stream.map(\n (data) =>\n ({\n _tag: \"Intermediate\",\n call_id: call.call_id,\n tool: tool.name,\n data,\n }) satisfies ToolEvent,\n ),\n )\n const output = Stream.fromEffect(\n Ref.get(ref).pipe(\n Effect.map(\n (events) =>\n ({\n _tag: \"Output\",\n result: valueResult(call, tool.name, tool.finalize(events)),\n }) satisfies ToolEvent,\n ),\n ),\n )\n return intermediates.pipe(Stream.concat(output))\n }),\n ).pipe(\n Stream.catchCause(() =>\n Stream.succeed<ToolEvent>({\n _tag: \"Output\",\n result: executionError(call, \"Tool execution failed\"),\n }),\n ),\n )\n\n// ---------------------------------------------------------------------------\n// `nextStateFrom` - bridge from a `Stream<ToolEvent>` to the loop's emit\n// shape. Drains the stream to the consumer in real-time, taps every\n// `Output` into an internal Ref, and at end-of-stream emits\n// `Loop.next(build(results))`. Recipe never sees the Ref.\n// ---------------------------------------------------------------------------\n\nexport const nextStateFrom = <S>(\n stream: Stream.Stream<ToolEvent>,\n build: (results: ReadonlyArray<ToolResult>) => S,\n): Stream.Stream<Loop.Event<ToolEvent, S>> =>\n Loop.nextAfterFold(\n stream,\n [] as ReadonlyArray<ToolResult>,\n (acc, e) => (isOutput(e) ? Arr.append(acc, e.result) : acc),\n build,\n )\n"],"mappings":"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"}
1
+ {"version":3,"file":"Toolkit.mjs","names":["Arr","Loop.nextAfterFold"],"sources":["../../src/tool/Toolkit.ts"],"sourcesContent":["import { Array as Arr, Effect, Function, Ref, Stream } from \"effect\"\nimport * as Loop from \"../loop/Loop.js\"\nimport type { FunctionCall } from \"../domain/Items.js\"\nimport {\n type AnyKindTool,\n type AnyPlainTool,\n type AnyStreamingTool,\n isStreamingTool,\n type StreamingTool,\n type Tool,\n type ToolDescriptor,\n} from \"./Tool.js\"\nimport { type ToolResult, executionError, rejected } from \"./Outcome.js\"\nimport type { ToolEvent } from \"./ToolEvent.js\"\nimport { isOutput } from \"./ToolEvent.js\"\n\nexport type AnyTool = Tool<string, any, any, any>\n\nexport type Toolkit<Tools extends ReadonlyArray<AnyTool>> = {\n readonly tools: Tools\n}\n\nexport type ToolsR<Tools extends ReadonlyArray<AnyTool>> =\n Tools[number] extends Tool<any, any, any, infer R> ? R : never\n\n/**\n * Union of every tool's `R` requirements in a mixed plain + streaming array.\n * Used by `executeAll` to surface the services tools need at the recipe\n * level, so the loop's stream type carries them through to `Effect.provide`.\n */\nexport type ToolKindR<Tools extends ReadonlyArray<AnyKindTool<any>>> =\n Tools[number] extends StreamingTool<any, any, any, any, infer R>\n ? R\n : Tools[number] extends Tool<any, any, any, infer R>\n ? R\n : never\n\nexport const make = <const Tools extends ReadonlyArray<AnyTool>>(tools: Tools): Toolkit<Tools> => ({\n tools,\n})\n\n/**\n * Render every tool in a toolkit to a provider-agnostic descriptor.\n * `inputSchema` is the JSON Schema document produced by the tool's\n * Standard Schema converter (draft 2020-12).\n */\nexport const toDescriptors = <Tools extends ReadonlyArray<AnyTool>>(\n toolkit: Toolkit<Tools>,\n): ReadonlyArray<ToolDescriptor> =>\n toolkit.tools.map((tool) => {\n const inputSchema = tool.inputSchema[\"~standard\"].jsonSchema.input({\n target: \"draft-2020-12\",\n })\n return tool.strict !== undefined\n ? { name: tool.name, description: tool.description, inputSchema, strict: tool.strict }\n : { name: tool.name, description: tool.description, inputSchema }\n })\n\n// ---------------------------------------------------------------------------\n// Tool executor. Streams `ToolEvent`s in real time and dispatches streaming\n// and plain tools uniformly. Policy stays outside this module: callers pass\n// only the calls they have already decided should run.\n// ---------------------------------------------------------------------------\n\nexport type ExecuteOptions = {\n readonly concurrency?: number | \"unbounded\"\n}\n\n/** Execute every provided call. Approval/rejection policy belongs upstream. */\nexport const executeAll = <Tools extends ReadonlyArray<AnyKindTool<any>>>(\n tools: Tools,\n calls: ReadonlyArray<FunctionCall>,\n options?: ExecuteOptions,\n): Stream.Stream<ToolEvent, never, ToolKindR<Tools>> =>\n Stream.fromIterable(calls).pipe(\n Stream.flatMap((call) => runOne(tools, call), {\n concurrency: options?.concurrency ?? \"unbounded\",\n }),\n )\n\nexport const outputEvent = (result: ToolResult): ToolEvent => ({ _tag: \"Output\", result })\n\nexport const outputEvents = (results: ReadonlyArray<ToolResult>): Stream.Stream<ToolEvent> =>\n Stream.fromIterable(results.map(outputEvent))\n\nconst valueResult = (call: FunctionCall, tool: string, value: unknown): ToolResult => ({\n _tag: \"Value\",\n call_id: call.call_id,\n tool,\n value,\n})\n\nconst runOne = <R>(\n tools: ReadonlyArray<AnyKindTool<R>>,\n call: FunctionCall,\n): Stream.Stream<ToolEvent, never, R> => {\n const tool = tools.find((t) => t.name === call.name)\n if (tool === undefined) {\n // Graceful: emit a synthetic Failure so OTHER calls in this turn\n // still execute. LLMs hallucinate tool names; MCP tools come and go.\n return Stream.succeed<ToolEvent>({\n _tag: \"Output\",\n result: rejected(call, \"unknown_tool\", `No tool registered with name \"${call.name}\"`),\n })\n }\n if (isStreamingTool(tool)) return runStreaming(tool, call)\n return runPlain(tool, call)\n}\n\nconst runPlain = <R>(\n tool: AnyPlainTool<R>,\n call: FunctionCall,\n): Stream.Stream<ToolEvent, never, R> =>\n Stream.fromEffect(\n Effect.gen(function* () {\n const parsed = yield* Effect.try({\n try: () => JSON.parse(call.arguments) as unknown,\n catch: () => \"json_parse_error\" as const,\n })\n const validated = yield* Effect.tryPromise({\n try: () => Promise.resolve(tool.inputSchema[\"~standard\"].validate(parsed)),\n catch: () => \"validation_threw\" as const,\n })\n if (validated.issues !== undefined) {\n return executionError(call, \"Tool input failed schema validation\")\n }\n const output = yield* tool.run(validated.value)\n return valueResult(call, tool.name, output)\n }).pipe(\n Effect.catchCause(() => Effect.succeed(executionError(call, \"Tool execution failed\"))),\n Effect.map((result) => ({ _tag: \"Output\", result }) satisfies ToolEvent),\n ),\n )\n\nconst runStreaming = <R>(\n tool: AnyStreamingTool<R>,\n call: FunctionCall,\n): Stream.Stream<ToolEvent, never, R> =>\n Stream.unwrap(\n Effect.gen(function* () {\n const parsed = yield* Effect.try({\n try: () => JSON.parse(call.arguments) as unknown,\n catch: () => \"json_parse_error\" as const,\n })\n const validated = yield* Effect.tryPromise({\n try: () => Promise.resolve(tool.inputSchema[\"~standard\"].validate(parsed)),\n catch: () => \"validation_threw\" as const,\n })\n if (validated.issues !== undefined) {\n return Stream.succeed<ToolEvent>({\n _tag: \"Output\",\n result: executionError(call, \"Tool input failed schema validation\"),\n })\n }\n\n // Real-time: tap each event into a Ref as it flows; emit one\n // Intermediate per event; then concat one synthetic Output element\n // built from the accumulated Ref via `finalize`.\n const ref = yield* Ref.make<Array<unknown>>([])\n const intermediates = tool.run(validated.value).pipe(\n Stream.tap((event) => Ref.update(ref, Arr.append(event))),\n Stream.map(\n (data) =>\n ({\n _tag: \"Intermediate\",\n call_id: call.call_id,\n tool: tool.name,\n data,\n }) satisfies ToolEvent,\n ),\n )\n const output = Stream.fromEffect(\n Ref.get(ref).pipe(\n Effect.map(\n (events) =>\n ({\n _tag: \"Output\",\n result: valueResult(call, tool.name, tool.finalize(events)),\n }) satisfies ToolEvent,\n ),\n ),\n )\n return intermediates.pipe(Stream.concat(output))\n }),\n ).pipe(\n Stream.catchCause(() =>\n Stream.succeed<ToolEvent>({\n _tag: \"Output\",\n result: executionError(call, \"Tool execution failed\"),\n }),\n ),\n )\n\n// ---------------------------------------------------------------------------\n// `continueWith` - bridge from a `Stream<ToolEvent>` to the loop's emit\n// shape. Drains the stream to the consumer in real-time, taps every\n// `Output` into an internal Ref, and at end-of-stream emits\n// `Loop.next(build(results))`. Recipe never sees the Ref.\n//\n// Dual: data-first `continueWith(stream, build)` and data-last\n// `stream.pipe(continueWith(build))` both work.\n// ---------------------------------------------------------------------------\n\nexport const continueWith: {\n <S>(\n build: (results: ReadonlyArray<ToolResult>) => S,\n ): <R>(\n stream: Stream.Stream<ToolEvent, never, R>,\n ) => Stream.Stream<Loop.Event<ToolEvent, S>, never, R>\n <S, R>(\n stream: Stream.Stream<ToolEvent, never, R>,\n build: (results: ReadonlyArray<ToolResult>) => S,\n ): Stream.Stream<Loop.Event<ToolEvent, S>, never, R>\n} = Function.dual(\n 2,\n <S, R>(\n stream: Stream.Stream<ToolEvent, never, R>,\n build: (results: ReadonlyArray<ToolResult>) => S,\n ): Stream.Stream<Loop.Event<ToolEvent, S>, never, R> =>\n Loop.nextAfterFold(\n stream,\n [] as ReadonlyArray<ToolResult>,\n (acc, e) => (isOutput(e) ? Arr.append(acc, e.result) : acc),\n build,\n ),\n)\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,113 @@
1
+ import { fromEffectSchema, make } from "./Tool.mjs";
2
+ import { isValue } from "./Outcome.mjs";
3
+ import { isOutput } from "./ToolEvent.mjs";
4
+ import { executeAll, make as make$1, toDescriptors } from "./Toolkit.mjs";
5
+ import { i as it, n as globalExpect, r as describe, t as import_dist } from "../dist-DV5ISja1.mjs";
6
+ import { Context, Effect, Layer, Schema, Stream } from "effect";
7
+ //#region src/tool/Toolkit.test.ts
8
+ describe("Toolkit.toDescriptors", () => {
9
+ const GetWeatherInput = Schema.Struct({ city: Schema.String });
10
+ const getWeather = make({
11
+ name: "get_weather",
12
+ description: "Look up the current temperature for a city.",
13
+ inputSchema: fromEffectSchema(GetWeatherInput),
14
+ run: ({ city }) => Effect.succeed({
15
+ city,
16
+ tempC: 18
17
+ })
18
+ });
19
+ it("renders the input schema as a JSON Schema document", () => {
20
+ const [desc] = toDescriptors(make$1([getWeather]));
21
+ globalExpect(desc?.name).toBe("get_weather");
22
+ globalExpect(desc?.description).toBe("Look up the current temperature for a city.");
23
+ globalExpect(desc?.inputSchema).toMatchObject({
24
+ type: "object",
25
+ properties: { city: { type: "string" } },
26
+ required: ["city"]
27
+ });
28
+ });
29
+ it("includes strict flag only when set on the tool", () => {
30
+ const [s, l] = toDescriptors(make$1([make({
31
+ name: "strict_one",
32
+ description: "",
33
+ inputSchema: fromEffectSchema(GetWeatherInput),
34
+ run: () => Effect.succeed({}),
35
+ strict: true
36
+ }), make({
37
+ name: "loose_one",
38
+ description: "",
39
+ inputSchema: fromEffectSchema(GetWeatherInput),
40
+ run: () => Effect.succeed({})
41
+ })]));
42
+ globalExpect(s?.strict).toBe(true);
43
+ globalExpect(l).not.toHaveProperty("strict");
44
+ });
45
+ });
46
+ describe("Toolkit.executeAll - tools with R requirements", () => {
47
+ class WeatherApiKey extends Context.Service()("test/WeatherApiKey") {}
48
+ class GeoApiKey extends Context.Service()("test/GeoApiKey") {}
49
+ const Empty = Schema.Struct({});
50
+ const getWeather = make({
51
+ name: "get_weather",
52
+ description: "",
53
+ inputSchema: fromEffectSchema(Empty),
54
+ run: () => Effect.gen(function* () {
55
+ const { key } = yield* WeatherApiKey;
56
+ return {
57
+ source: "weather",
58
+ key
59
+ };
60
+ })
61
+ });
62
+ const getCoords = make({
63
+ name: "get_coords",
64
+ description: "",
65
+ inputSchema: fromEffectSchema(Empty),
66
+ run: () => Effect.gen(function* () {
67
+ const { key } = yield* GeoApiKey;
68
+ return {
69
+ source: "geo",
70
+ key
71
+ };
72
+ })
73
+ });
74
+ const call = (name, id) => ({
75
+ type: "function_call",
76
+ call_id: id,
77
+ name,
78
+ arguments: "{}"
79
+ });
80
+ it("propagates each tool's R into the resulting Stream's requirements", () => {
81
+ (0, import_dist.expectTypeOf)(executeAll([getWeather, getCoords], [])).toEqualTypeOf();
82
+ });
83
+ it("runs each tool with its own service injected", async () => {
84
+ const layer = Layer.mergeAll(Layer.succeed(WeatherApiKey, { key: "weather-123" }), Layer.succeed(GeoApiKey, { key: "geo-456" }));
85
+ const program = executeAll([getWeather, getCoords], [call("get_weather", "c1"), call("get_coords", "c2")]).pipe(Stream.runCollect, Effect.provide(layer));
86
+ const events = await Effect.runPromise(program);
87
+ const outputs = Array.from(events).filter(isOutput);
88
+ const byCall = new Map(outputs.map((e) => [e.result.call_id, e.result]));
89
+ const w = byCall.get("c1");
90
+ const g = byCall.get("c2");
91
+ globalExpect(w !== void 0 && isValue(w) && w.value).toEqual({
92
+ source: "weather",
93
+ key: "weather-123"
94
+ });
95
+ globalExpect(g !== void 0 && isValue(g) && g.value).toEqual({
96
+ source: "geo",
97
+ key: "geo-456"
98
+ });
99
+ });
100
+ it("with no service-needing tools, R is never", () => {
101
+ const plain = make({
102
+ name: "plain",
103
+ description: "",
104
+ inputSchema: fromEffectSchema(Empty),
105
+ run: () => Effect.succeed(0)
106
+ });
107
+ (0, import_dist.expectTypeOf)(executeAll([plain], [])).toEqualTypeOf();
108
+ });
109
+ });
110
+ //#endregion
111
+ export {};
112
+
113
+ //# sourceMappingURL=Toolkit.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toolkit.test.mjs","names":["Tool.make","Tool.fromEffectSchema","Toolkit.toDescriptors","Toolkit.make","Toolkit.executeAll"],"sources":["../../src/tool/Toolkit.test.ts"],"sourcesContent":["import { Context, Effect, Layer, Schema, Stream } from \"effect\"\nimport { describe, expect, expectTypeOf, it } from \"vitest\"\nimport type { FunctionCall } from \"../domain/Items.js\"\nimport { isOutput } from \"./ToolEvent.js\"\nimport { isValue } from \"./Outcome.js\"\nimport * as Tool from \"./Tool.js\"\nimport * as Toolkit from \"./Toolkit.js\"\n\ndescribe(\"Toolkit.toDescriptors\", () => {\n const GetWeatherInput = Schema.Struct({ city: Schema.String })\n\n const getWeather = Tool.make({\n name: \"get_weather\",\n description: \"Look up the current temperature for a city.\",\n inputSchema: Tool.fromEffectSchema(GetWeatherInput),\n run: ({ city }) => Effect.succeed({ city, tempC: 18 }),\n })\n\n it(\"renders the input schema as a JSON Schema document\", () => {\n const [desc] = Toolkit.toDescriptors(Toolkit.make([getWeather]))\n expect(desc?.name).toBe(\"get_weather\")\n expect(desc?.description).toBe(\"Look up the current temperature for a city.\")\n expect(desc?.inputSchema).toMatchObject({\n type: \"object\",\n properties: { city: { type: \"string\" } },\n required: [\"city\"],\n })\n })\n\n it(\"includes strict flag only when set on the tool\", () => {\n const strictTool = Tool.make({\n name: \"strict_one\",\n description: \"\",\n inputSchema: Tool.fromEffectSchema(GetWeatherInput),\n run: () => Effect.succeed({}),\n strict: true,\n })\n const looseTool = Tool.make({\n name: \"loose_one\",\n description: \"\",\n inputSchema: Tool.fromEffectSchema(GetWeatherInput),\n run: () => Effect.succeed({}),\n })\n const [s, l] = Toolkit.toDescriptors(Toolkit.make([strictTool, looseTool]))\n expect(s?.strict).toBe(true)\n expect(l).not.toHaveProperty(\"strict\")\n })\n})\n\ndescribe(\"Toolkit.executeAll - tools with R requirements\", () => {\n // Two distinct services, modelling the \"typed per-tool context\" use case\n // (cf. AI SDK 7's `toolsContext`). In Effect each tool declares its R, the\n // compiler enforces it, and `executeAll` surfaces the union for the caller\n // to provide via Layer.\n type WeatherApiKeyShape = { readonly key: string }\n class WeatherApiKey extends Context.Service<WeatherApiKey, WeatherApiKeyShape>()(\n \"test/WeatherApiKey\",\n ) {}\n\n type GeoApiKeyShape = { readonly key: string }\n class GeoApiKey extends Context.Service<GeoApiKey, GeoApiKeyShape>()(\"test/GeoApiKey\") {}\n\n const Empty = Schema.Struct({})\n\n const getWeather = Tool.make({\n name: \"get_weather\",\n description: \"\",\n inputSchema: Tool.fromEffectSchema(Empty),\n run: () =>\n Effect.gen(function* () {\n const { key } = yield* WeatherApiKey\n return { source: \"weather\", key }\n }),\n })\n\n const getCoords = Tool.make({\n name: \"get_coords\",\n description: \"\",\n inputSchema: Tool.fromEffectSchema(Empty),\n run: () =>\n Effect.gen(function* () {\n const { key } = yield* GeoApiKey\n return { source: \"geo\", key }\n }),\n })\n\n const call = (name: string, id: string): FunctionCall => ({\n type: \"function_call\",\n call_id: id,\n name,\n arguments: \"{}\",\n })\n\n it(\"propagates each tool's R into the resulting Stream's requirements\", () => {\n const stream = Toolkit.executeAll([getWeather, getCoords], [])\n expectTypeOf(stream).toEqualTypeOf<\n Stream.Stream<import(\"./ToolEvent.js\").ToolEvent, never, WeatherApiKey | GeoApiKey>\n >()\n })\n\n it(\"runs each tool with its own service injected\", async () => {\n const layer = Layer.mergeAll(\n Layer.succeed(WeatherApiKey, { key: \"weather-123\" }),\n Layer.succeed(GeoApiKey, { key: \"geo-456\" }),\n )\n\n const program = Toolkit.executeAll(\n [getWeather, getCoords],\n [call(\"get_weather\", \"c1\"), call(\"get_coords\", \"c2\")],\n ).pipe(Stream.runCollect, Effect.provide(layer))\n\n const events = await Effect.runPromise(program)\n const outputs = Array.from(events).filter(isOutput)\n const byCall = new Map(outputs.map((e) => [e.result.call_id, e.result]))\n\n const w = byCall.get(\"c1\")\n const g = byCall.get(\"c2\")\n expect(w !== undefined && isValue(w) && w.value).toEqual({\n source: \"weather\",\n key: \"weather-123\",\n })\n expect(g !== undefined && isValue(g) && g.value).toEqual({\n source: \"geo\",\n key: \"geo-456\",\n })\n })\n\n it(\"with no service-needing tools, R is never\", () => {\n const plain = Tool.make({\n name: \"plain\",\n description: \"\",\n inputSchema: Tool.fromEffectSchema(Empty),\n run: () => Effect.succeed(0),\n })\n const stream = Toolkit.executeAll([plain], [])\n expectTypeOf(stream).toEqualTypeOf<\n Stream.Stream<import(\"./ToolEvent.js\").ToolEvent, never, never>\n >()\n })\n})\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-uai/core",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Low-level primitives (loop, conversation, items, tools, streaming codecs) for building AI agents with Effect.",
5
5
  "keywords": [
6
6
  "agents",
@@ -20,6 +20,12 @@
20
20
  "url": "https://github.com/betalyra/effect-uai",
21
21
  "directory": "packages/core"
22
22
  },
23
+ "files": [
24
+ "dist",
25
+ "src",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
23
29
  "type": "module",
24
30
  "main": "./dist/index.mjs",
25
31
  "types": "./dist/index.d.mts",
@@ -32,14 +38,30 @@
32
38
  "types": "./dist/domain/AiError.d.mts",
33
39
  "import": "./dist/domain/AiError.mjs"
34
40
  },
41
+ "./Image": {
42
+ "types": "./dist/domain/Image.d.mts",
43
+ "import": "./dist/domain/Image.mjs"
44
+ },
35
45
  "./Items": {
36
46
  "types": "./dist/domain/Items.d.mts",
37
47
  "import": "./dist/domain/Items.mjs"
38
48
  },
49
+ "./Media": {
50
+ "types": "./dist/domain/Media.d.mts",
51
+ "import": "./dist/domain/Media.mjs"
52
+ },
39
53
  "./Turn": {
40
54
  "types": "./dist/domain/Turn.d.mts",
41
55
  "import": "./dist/domain/Turn.mjs"
42
56
  },
57
+ "./Embedding": {
58
+ "types": "./dist/embedding-model/Embedding.d.mts",
59
+ "import": "./dist/embedding-model/Embedding.mjs"
60
+ },
61
+ "./EmbeddingModel": {
62
+ "types": "./dist/embedding-model/EmbeddingModel.d.mts",
63
+ "import": "./dist/embedding-model/EmbeddingModel.mjs"
64
+ },
43
65
  "./LanguageModel": {
44
66
  "types": "./dist/language-model/LanguageModel.d.mts",
45
67
  "import": "./dist/language-model/LanguageModel.mjs"
@@ -48,9 +70,9 @@
48
70
  "types": "./dist/loop/Loop.d.mts",
49
71
  "import": "./dist/loop/Loop.mjs"
50
72
  },
51
- "./Match": {
52
- "types": "./dist/match/Match.d.mts",
53
- "import": "./dist/match/Match.mjs"
73
+ "./Vector": {
74
+ "types": "./dist/math/Vector.d.mts",
75
+ "import": "./dist/math/Vector.mjs"
54
76
  },
55
77
  "./Tool": {
56
78
  "types": "./dist/tool/Tool.d.mts",
@@ -101,25 +123,19 @@
101
123
  "import": "./dist/testing/MockProvider.mjs"
102
124
  }
103
125
  },
104
- "files": [
105
- "dist",
106
- "src",
107
- "README.md",
108
- "LICENSE"
109
- ],
110
126
  "publishConfig": {
111
127
  "access": "public"
112
128
  },
113
129
  "dependencies": {
114
130
  "@standard-schema/spec": "^1.1.0"
115
131
  },
116
- "peerDependencies": {
117
- "effect": "4.0.0-beta.57"
118
- },
119
132
  "devDependencies": {
120
133
  "effect": "4.0.0-beta.57",
121
134
  "typescript": "^6.0.3"
122
135
  },
136
+ "peerDependencies": {
137
+ "effect": "4.0.0-beta.57"
138
+ },
123
139
  "scripts": {
124
140
  "build": "tsdown",
125
141
  "typecheck": "tsc --noEmit"