@effect/ai 0.26.0 → 0.27.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 (188) hide show
  1. package/Chat/package.json +6 -0
  2. package/EmbeddingModel/package.json +6 -0
  3. package/IdGenerator/package.json +6 -0
  4. package/LanguageModel/package.json +6 -0
  5. package/Model/package.json +6 -0
  6. package/Prompt/package.json +6 -0
  7. package/Response/package.json +6 -0
  8. package/Telemetry/package.json +6 -0
  9. package/Tool/package.json +6 -0
  10. package/Toolkit/package.json +6 -0
  11. package/dist/cjs/AiError.js +575 -11
  12. package/dist/cjs/AiError.js.map +1 -1
  13. package/dist/cjs/Chat.js +302 -0
  14. package/dist/cjs/Chat.js.map +1 -0
  15. package/dist/cjs/EmbeddingModel.js +184 -0
  16. package/dist/cjs/EmbeddingModel.js.map +1 -0
  17. package/dist/cjs/IdGenerator.js +255 -0
  18. package/dist/cjs/IdGenerator.js.map +1 -0
  19. package/dist/cjs/LanguageModel.js +584 -0
  20. package/dist/cjs/LanguageModel.js.map +1 -0
  21. package/dist/cjs/McpServer.js +12 -4
  22. package/dist/cjs/McpServer.js.map +1 -1
  23. package/dist/cjs/Model.js +118 -0
  24. package/dist/cjs/Model.js.map +1 -0
  25. package/dist/cjs/Prompt.js +649 -0
  26. package/dist/cjs/Prompt.js.map +1 -0
  27. package/dist/cjs/Response.js +635 -0
  28. package/dist/cjs/Response.js.map +1 -0
  29. package/dist/cjs/Telemetry.js +176 -0
  30. package/dist/cjs/Telemetry.js.map +1 -0
  31. package/dist/cjs/Tokenizer.js +87 -8
  32. package/dist/cjs/Tokenizer.js.map +1 -1
  33. package/dist/cjs/Tool.js +556 -0
  34. package/dist/cjs/Tool.js.map +1 -0
  35. package/dist/cjs/Toolkit.js +279 -0
  36. package/dist/cjs/Toolkit.js.map +1 -0
  37. package/dist/cjs/index.js +21 -19
  38. package/dist/dts/AiError.d.ts +577 -9
  39. package/dist/dts/AiError.d.ts.map +1 -1
  40. package/dist/dts/Chat.d.ts +356 -0
  41. package/dist/dts/Chat.d.ts.map +1 -0
  42. package/dist/dts/EmbeddingModel.d.ts +153 -0
  43. package/dist/dts/EmbeddingModel.d.ts.map +1 -0
  44. package/dist/dts/IdGenerator.d.ts +272 -0
  45. package/dist/dts/IdGenerator.d.ts.map +1 -0
  46. package/dist/dts/LanguageModel.d.ts +458 -0
  47. package/dist/dts/LanguageModel.d.ts.map +1 -0
  48. package/dist/dts/McpSchema.d.ts +25 -25
  49. package/dist/dts/McpServer.d.ts +6 -4
  50. package/dist/dts/McpServer.d.ts.map +1 -1
  51. package/dist/dts/Model.d.ts +124 -0
  52. package/dist/dts/Model.d.ts.map +1 -0
  53. package/dist/dts/Prompt.d.ts +1119 -0
  54. package/dist/dts/Prompt.d.ts.map +1 -0
  55. package/dist/dts/Response.d.ts +1519 -0
  56. package/dist/dts/Response.d.ts.map +1 -0
  57. package/dist/dts/Telemetry.d.ts +520 -0
  58. package/dist/dts/Telemetry.d.ts.map +1 -0
  59. package/dist/dts/Tokenizer.d.ts +131 -13
  60. package/dist/dts/Tokenizer.d.ts.map +1 -1
  61. package/dist/dts/Tool.d.ts +876 -0
  62. package/dist/dts/Tool.d.ts.map +1 -0
  63. package/dist/dts/Toolkit.d.ts +310 -0
  64. package/dist/dts/Toolkit.d.ts.map +1 -0
  65. package/dist/dts/index.d.ts +498 -13
  66. package/dist/dts/index.d.ts.map +1 -1
  67. package/dist/esm/AiError.js +570 -10
  68. package/dist/esm/AiError.js.map +1 -1
  69. package/dist/esm/Chat.js +291 -0
  70. package/dist/esm/Chat.js.map +1 -0
  71. package/dist/esm/EmbeddingModel.js +173 -0
  72. package/dist/esm/EmbeddingModel.js.map +1 -0
  73. package/dist/esm/IdGenerator.js +245 -0
  74. package/dist/esm/IdGenerator.js.map +1 -0
  75. package/dist/esm/LanguageModel.js +572 -0
  76. package/dist/esm/LanguageModel.js.map +1 -0
  77. package/dist/esm/McpServer.js +12 -4
  78. package/dist/esm/McpServer.js.map +1 -1
  79. package/dist/esm/Model.js +108 -0
  80. package/dist/esm/Model.js.map +1 -0
  81. package/dist/esm/Prompt.js +633 -0
  82. package/dist/esm/Prompt.js.map +1 -0
  83. package/dist/esm/Response.js +619 -0
  84. package/dist/esm/Response.js.map +1 -0
  85. package/dist/esm/Telemetry.js +166 -0
  86. package/dist/esm/Telemetry.js.map +1 -0
  87. package/dist/esm/Tokenizer.js +87 -8
  88. package/dist/esm/Tokenizer.js.map +1 -1
  89. package/dist/esm/Tool.js +534 -0
  90. package/dist/esm/Tool.js.map +1 -0
  91. package/dist/esm/Toolkit.js +269 -0
  92. package/dist/esm/Toolkit.js.map +1 -0
  93. package/dist/esm/index.js +498 -13
  94. package/dist/esm/index.js.map +1 -1
  95. package/package.json +76 -68
  96. package/src/AiError.ts +739 -9
  97. package/src/Chat.ts +546 -0
  98. package/src/EmbeddingModel.ts +311 -0
  99. package/src/IdGenerator.ts +320 -0
  100. package/src/LanguageModel.ts +1074 -0
  101. package/src/McpServer.ts +337 -194
  102. package/src/Model.ts +155 -0
  103. package/src/Prompt.ts +1616 -0
  104. package/src/Response.ts +2131 -0
  105. package/src/Telemetry.ts +655 -0
  106. package/src/Tokenizer.ts +145 -24
  107. package/src/Tool.ts +1267 -0
  108. package/src/Toolkit.ts +516 -0
  109. package/src/index.ts +499 -13
  110. package/AiChat/package.json +0 -6
  111. package/AiEmbeddingModel/package.json +0 -6
  112. package/AiInput/package.json +0 -6
  113. package/AiLanguageModel/package.json +0 -6
  114. package/AiModel/package.json +0 -6
  115. package/AiResponse/package.json +0 -6
  116. package/AiTelemetry/package.json +0 -6
  117. package/AiTool/package.json +0 -6
  118. package/AiToolkit/package.json +0 -6
  119. package/dist/cjs/AiChat.js +0 -122
  120. package/dist/cjs/AiChat.js.map +0 -1
  121. package/dist/cjs/AiEmbeddingModel.js +0 -109
  122. package/dist/cjs/AiEmbeddingModel.js.map +0 -1
  123. package/dist/cjs/AiInput.js +0 -458
  124. package/dist/cjs/AiInput.js.map +0 -1
  125. package/dist/cjs/AiLanguageModel.js +0 -351
  126. package/dist/cjs/AiLanguageModel.js.map +0 -1
  127. package/dist/cjs/AiModel.js +0 -37
  128. package/dist/cjs/AiModel.js.map +0 -1
  129. package/dist/cjs/AiResponse.js +0 -681
  130. package/dist/cjs/AiResponse.js.map +0 -1
  131. package/dist/cjs/AiTelemetry.js +0 -58
  132. package/dist/cjs/AiTelemetry.js.map +0 -1
  133. package/dist/cjs/AiTool.js +0 -150
  134. package/dist/cjs/AiTool.js.map +0 -1
  135. package/dist/cjs/AiToolkit.js +0 -157
  136. package/dist/cjs/AiToolkit.js.map +0 -1
  137. package/dist/cjs/internal/common.js +0 -21
  138. package/dist/cjs/internal/common.js.map +0 -1
  139. package/dist/dts/AiChat.d.ts +0 -101
  140. package/dist/dts/AiChat.d.ts.map +0 -1
  141. package/dist/dts/AiEmbeddingModel.d.ts +0 -65
  142. package/dist/dts/AiEmbeddingModel.d.ts.map +0 -1
  143. package/dist/dts/AiInput.d.ts +0 -590
  144. package/dist/dts/AiInput.d.ts.map +0 -1
  145. package/dist/dts/AiLanguageModel.d.ts +0 -302
  146. package/dist/dts/AiLanguageModel.d.ts.map +0 -1
  147. package/dist/dts/AiModel.d.ts +0 -25
  148. package/dist/dts/AiModel.d.ts.map +0 -1
  149. package/dist/dts/AiResponse.d.ts +0 -863
  150. package/dist/dts/AiResponse.d.ts.map +0 -1
  151. package/dist/dts/AiTelemetry.d.ts +0 -242
  152. package/dist/dts/AiTelemetry.d.ts.map +0 -1
  153. package/dist/dts/AiTool.d.ts +0 -334
  154. package/dist/dts/AiTool.d.ts.map +0 -1
  155. package/dist/dts/AiToolkit.d.ts +0 -96
  156. package/dist/dts/AiToolkit.d.ts.map +0 -1
  157. package/dist/dts/internal/common.d.ts +0 -2
  158. package/dist/dts/internal/common.d.ts.map +0 -1
  159. package/dist/esm/AiChat.js +0 -111
  160. package/dist/esm/AiChat.js.map +0 -1
  161. package/dist/esm/AiEmbeddingModel.js +0 -98
  162. package/dist/esm/AiEmbeddingModel.js.map +0 -1
  163. package/dist/esm/AiInput.js +0 -433
  164. package/dist/esm/AiInput.js.map +0 -1
  165. package/dist/esm/AiLanguageModel.js +0 -340
  166. package/dist/esm/AiLanguageModel.js.map +0 -1
  167. package/dist/esm/AiModel.js +0 -29
  168. package/dist/esm/AiModel.js.map +0 -1
  169. package/dist/esm/AiResponse.js +0 -657
  170. package/dist/esm/AiResponse.js.map +0 -1
  171. package/dist/esm/AiTelemetry.js +0 -48
  172. package/dist/esm/AiTelemetry.js.map +0 -1
  173. package/dist/esm/AiTool.js +0 -134
  174. package/dist/esm/AiTool.js.map +0 -1
  175. package/dist/esm/AiToolkit.js +0 -147
  176. package/dist/esm/AiToolkit.js.map +0 -1
  177. package/dist/esm/internal/common.js +0 -14
  178. package/dist/esm/internal/common.js.map +0 -1
  179. package/src/AiChat.ts +0 -251
  180. package/src/AiEmbeddingModel.ts +0 -169
  181. package/src/AiInput.ts +0 -602
  182. package/src/AiLanguageModel.ts +0 -685
  183. package/src/AiModel.ts +0 -53
  184. package/src/AiResponse.ts +0 -986
  185. package/src/AiTelemetry.ts +0 -333
  186. package/src/AiTool.ts +0 -579
  187. package/src/AiToolkit.ts +0 -265
  188. package/src/internal/common.ts +0 -12
@@ -0,0 +1,572 @@
1
+ /**
2
+ * The `LanguageModel` module provides AI text generation capabilities with tool
3
+ * calling support.
4
+ *
5
+ * This module offers a comprehensive interface for interacting with large
6
+ * language models, supporting both streaming and non-streaming text generation,
7
+ * structured output generation, and tool calling functionality. It provides a
8
+ * unified API that can be implemented by different AI providers while
9
+ * maintaining type safety and effect management.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { LanguageModel } from "@effect/ai"
14
+ * import { Effect } from "effect"
15
+ *
16
+ * // Basic text generation
17
+ * const program = Effect.gen(function* () {
18
+ * const response = yield* LanguageModel.generateText({
19
+ * prompt: "Explain quantum computing"
20
+ * })
21
+ *
22
+ * console.log(response.text)
23
+ *
24
+ * return response
25
+ * })
26
+ * ```
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { LanguageModel } from "@effect/ai"
31
+ * import { Effect, Schema } from "effect"
32
+ *
33
+ * // Structured output generation
34
+ * const ContactSchema = Schema.Struct({
35
+ * name: Schema.String,
36
+ * email: Schema.String
37
+ * })
38
+ *
39
+ * const extractContact = Effect.gen(function* () {
40
+ * const response = yield* LanguageModel.generateObject({
41
+ * prompt: "Extract contact: John Doe, john@example.com",
42
+ * schema: ContactSchema
43
+ * })
44
+ *
45
+ * return response.value
46
+ * })
47
+ * ```
48
+ *
49
+ * @since 1.0.0
50
+ */
51
+ import * as Chunk from "effect/Chunk";
52
+ import * as Context from "effect/Context";
53
+ import * as Effect from "effect/Effect";
54
+ import * as Option from "effect/Option";
55
+ import * as ParseResult from "effect/ParseResult";
56
+ import * as Predicate from "effect/Predicate";
57
+ import * as Schema from "effect/Schema";
58
+ import * as Stream from "effect/Stream";
59
+ import * as AiError from "./AiError.js";
60
+ import { defaultIdGenerator, IdGenerator } from "./IdGenerator.js";
61
+ import * as Prompt from "./Prompt.js";
62
+ import * as Response from "./Response.js";
63
+ import { CurrentSpanTransformer } from "./Telemetry.js";
64
+ import * as Toolkit from "./Toolkit.js";
65
+ // =============================================================================
66
+ // Service Definition
67
+ // =============================================================================
68
+ /**
69
+ * The `LanguageModel` service tag for dependency injection.
70
+ *
71
+ * This tag provides access to language model functionality throughout your
72
+ * application, enabling text generation, streaming, and structured output
73
+ * capabilities.
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * import { LanguageModel } from "@effect/ai"
78
+ * import { Effect } from "effect"
79
+ *
80
+ * const useLanguageModel = Effect.gen(function* () {
81
+ * const model = yield* LanguageModel
82
+ * const response = yield* model.generateText({
83
+ * prompt: "What is machine learning?"
84
+ * })
85
+ * return response.text
86
+ * })
87
+ * ```
88
+ *
89
+ * @since 1.0.0
90
+ * @category Context
91
+ */
92
+ export class LanguageModel extends /*#__PURE__*/Context.Tag("@effect/ai/LanguageModel")() {}
93
+ /**
94
+ * Response class for text generation operations.
95
+ *
96
+ * Contains the generated content and provides convenient accessors for
97
+ * extracting different types of response parts like text, tool calls, and usage
98
+ * information.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * import { LanguageModel } from "@effect/ai"
103
+ * import { Effect } from "effect"
104
+ *
105
+ * const program = Effect.gen(function* () {
106
+ * const response = yield* LanguageModel.generateText({
107
+ * prompt: "Explain photosynthesis"
108
+ * })
109
+ *
110
+ * console.log(response.text) // Generated text content
111
+ * console.log(response.finishReason) // "stop", "length", etc.
112
+ * console.log(response.usage) // Usage information
113
+ *
114
+ * return response
115
+ * })
116
+ * ```
117
+ *
118
+ * @since 1.0.0
119
+ * @category Models
120
+ */
121
+ export class GenerateTextResponse {
122
+ content;
123
+ constructor(content) {
124
+ this.content = content;
125
+ }
126
+ /**
127
+ * Extracts and concatenates all text parts from the response.
128
+ */
129
+ get text() {
130
+ const text = [];
131
+ for (const part of this.content) {
132
+ if (part.type === "text") {
133
+ text.push(part.text);
134
+ }
135
+ }
136
+ return text.join("");
137
+ }
138
+ /**
139
+ * Returns all reasoning parts from the response.
140
+ */
141
+ get reasoning() {
142
+ return this.content.filter(part => part.type === "reasoning");
143
+ }
144
+ /**
145
+ * Extracts and concatenates all reasoning text, or undefined if none exists.
146
+ */
147
+ get reasoningText() {
148
+ const text = [];
149
+ for (const part of this.content) {
150
+ if (part.type === "reasoning") {
151
+ text.push(part.text);
152
+ }
153
+ }
154
+ return text.length === 0 ? undefined : text.join("");
155
+ }
156
+ /**
157
+ * Returns all tool call parts from the response.
158
+ */
159
+ get toolCalls() {
160
+ return this.content.filter(part => part.type === "tool-call");
161
+ }
162
+ /**
163
+ * Returns all tool result parts from the response.
164
+ */
165
+ get toolResults() {
166
+ return this.content.filter(part => part.type === "tool-result");
167
+ }
168
+ /**
169
+ * The reason why text generation finished.
170
+ */
171
+ get finishReason() {
172
+ const finishPart = this.content.find(part => part.type === "finish");
173
+ return Predicate.isUndefined(finishPart) ? "unknown" : finishPart.reason;
174
+ }
175
+ /**
176
+ * Token usage statistics for the generation request.
177
+ */
178
+ get usage() {
179
+ const finishPart = this.content.find(part => part.type === "finish");
180
+ if (Predicate.isUndefined(finishPart)) {
181
+ return new Response.Usage({
182
+ inputTokens: undefined,
183
+ outputTokens: undefined,
184
+ totalTokens: undefined,
185
+ reasoningTokens: undefined,
186
+ cachedInputTokens: undefined
187
+ });
188
+ }
189
+ return finishPart.usage;
190
+ }
191
+ }
192
+ /**
193
+ * Response class for structured object generation operations.
194
+ *
195
+ * @example
196
+ * ```ts
197
+ * import { LanguageModel } from "@effect/ai"
198
+ * import { Effect, Schema } from "effect"
199
+ *
200
+ * const UserSchema = Schema.Struct({
201
+ * name: Schema.String,
202
+ * email: Schema.String
203
+ * })
204
+ *
205
+ * const program = Effect.gen(function* () {
206
+ * const response = yield* LanguageModel.generateObject({
207
+ * prompt: "Create user: John Doe, john@example.com",
208
+ * schema: UserSchema
209
+ * })
210
+ *
211
+ * console.log(response.value) // { name: "John Doe", email: "john@example.com" }
212
+ * console.log(response.text) // Raw generated text
213
+ *
214
+ * return response.value
215
+ * })
216
+ * ```
217
+ *
218
+ * @since 1.0.0
219
+ * @category Models
220
+ */
221
+ export class GenerateObjectResponse extends GenerateTextResponse {
222
+ /**
223
+ * The parsed structured object that conforms to the provided schema.
224
+ */
225
+ value;
226
+ constructor(value, content) {
227
+ super(content);
228
+ this.value = value;
229
+ }
230
+ }
231
+ /**
232
+ * Creates a LanguageModel service from provider-specific implementations.
233
+ *
234
+ * This constructor takes provider-specific implementations for text generation
235
+ * and streaming text generation and returns a LanguageModel service.
236
+ *
237
+ * @since 1.0.0
238
+ * @category Constructors
239
+ */
240
+ export const make = /*#__PURE__*/Effect.fnUntraced(function* (params) {
241
+ const parentSpanTransformer = yield* Effect.serviceOption(CurrentSpanTransformer);
242
+ const getSpanTransformer = Effect.serviceOption(CurrentSpanTransformer).pipe(Effect.map(Option.orElse(() => parentSpanTransformer)));
243
+ const idGenerator = yield* Effect.serviceOption(IdGenerator).pipe(Effect.map(Option.getOrElse(() => defaultIdGenerator)));
244
+ const generateText = options => Effect.useSpan("LanguageModel.generateText", {
245
+ captureStackTrace: false,
246
+ attributes: {
247
+ concurrency: options.concurrency,
248
+ toolChoice: options.toolChoice
249
+ }
250
+ }, Effect.fnUntraced(function* (span) {
251
+ const spanTransformer = yield* getSpanTransformer;
252
+ const providerOptions = {
253
+ prompt: Prompt.make(options.prompt),
254
+ tools: [],
255
+ toolChoice: "none",
256
+ responseFormat: {
257
+ type: "text"
258
+ },
259
+ span
260
+ };
261
+ const content = yield* generateContent(options, providerOptions);
262
+ applySpanTransformer(spanTransformer, content, providerOptions);
263
+ return new GenerateTextResponse(content);
264
+ }, Effect.catchTag("ParseError", error => AiError.MalformedOutput.fromParseError({
265
+ module: "LanguageModel",
266
+ method: "generateText",
267
+ error
268
+ })), (effect, span) => Effect.withParentSpan(effect, span), Effect.provideService(IdGenerator, idGenerator)));
269
+ const generateObject = options => {
270
+ const schema = options.schema;
271
+ const objectName = getObjectName(options.objectName, schema);
272
+ return Effect.useSpan("LanguageModel.generateObject", {
273
+ captureStackTrace: false,
274
+ attributes: {
275
+ objectName,
276
+ concurrency: options.concurrency,
277
+ toolChoice: options.toolChoice
278
+ }
279
+ }, Effect.fnUntraced(function* (span) {
280
+ const spanTransformer = yield* getSpanTransformer;
281
+ const providerOptions = {
282
+ prompt: Prompt.make(options.prompt),
283
+ tools: [],
284
+ toolChoice: "none",
285
+ responseFormat: {
286
+ type: "json",
287
+ objectName,
288
+ schema
289
+ },
290
+ span
291
+ };
292
+ const content = yield* generateContent(options, providerOptions);
293
+ applySpanTransformer(spanTransformer, content, providerOptions);
294
+ const value = yield* resolveStructuredOutput(content, schema);
295
+ return new GenerateObjectResponse(value, content);
296
+ }, Effect.catchTag("ParseError", error => AiError.MalformedOutput.fromParseError({
297
+ module: "LanguageModel",
298
+ method: "generateText",
299
+ error
300
+ })), (effect, span) => Effect.withParentSpan(effect, span), Effect.provideService(IdGenerator, idGenerator)));
301
+ };
302
+ const streamText = Effect.fnUntraced(function* (options) {
303
+ const span = yield* Effect.makeSpanScoped("LanguageModel.streamText", {
304
+ captureStackTrace: false,
305
+ attributes: {
306
+ concurrency: options.concurrency,
307
+ toolChoice: options.toolChoice
308
+ }
309
+ });
310
+ const providerOptions = {
311
+ prompt: Prompt.make(options.prompt),
312
+ tools: [],
313
+ toolChoice: "none",
314
+ responseFormat: {
315
+ type: "text"
316
+ },
317
+ span
318
+ };
319
+ // Resolve the content stream for the request
320
+ const stream = yield* streamContent(options, providerOptions);
321
+ // Return the stream immediately if there is no span transformer
322
+ const spanTransformer = yield* getSpanTransformer;
323
+ if (Option.isNone(spanTransformer)) {
324
+ return stream;
325
+ }
326
+ // Otherwise aggregate generated content and apply the span transformer
327
+ // when the stream is finished
328
+ let content = [];
329
+ return stream.pipe(Stream.mapChunks(chunk => {
330
+ content = [...content, ...chunk];
331
+ return chunk;
332
+ }), Stream.ensuring(Effect.sync(() => {
333
+ spanTransformer.value({
334
+ ...providerOptions,
335
+ response: content
336
+ });
337
+ })));
338
+ }, Stream.unwrapScoped, Stream.mapError(error => ParseResult.isParseError(error) ? AiError.MalformedOutput.fromParseError({
339
+ module: "LanguageModel",
340
+ method: "streamText",
341
+ error
342
+ }) : error), Stream.provideService(IdGenerator, idGenerator));
343
+ const generateContent = Effect.fnUntraced(function* (options, providerOptions) {
344
+ const toolChoice = options.toolChoice ?? "auto";
345
+ // If there is no toolkit, the generated content can be returned immediately
346
+ if (Predicate.isUndefined(options.toolkit)) {
347
+ const ResponseSchema = Schema.mutable(Schema.Array(Response.Part(Toolkit.empty)));
348
+ const rawContent = yield* params.generateText(providerOptions);
349
+ const content = yield* Schema.decodeUnknown(ResponseSchema)(rawContent);
350
+ return content;
351
+ }
352
+ // If there is a toolkit resolve and apply it to the provider options
353
+ const toolkit = yield* resolveToolkit(options.toolkit);
354
+ // If the resolved toolkit is empty, return the generated content immediately
355
+ if (Object.values(toolkit.tools).length === 0) {
356
+ const ResponseSchema = Schema.mutable(Schema.Array(Response.Part(Toolkit.empty)));
357
+ const rawContent = yield* params.generateText(providerOptions);
358
+ const content = yield* Schema.decodeUnknown(ResponseSchema)(rawContent);
359
+ return content;
360
+ }
361
+ const tools = typeof toolChoice === "object" && "oneOf" in toolChoice ? Object.values(toolkit.tools).filter(tool => toolChoice.oneOf.includes(tool.name)) : Object.values(toolkit.tools);
362
+ providerOptions.tools = tools;
363
+ providerOptions.toolChoice = toolChoice;
364
+ // If tool call resolution is disabled, return the response without
365
+ // resolving the tool calls that were generated
366
+ if (options.disableToolCallResolution === true) {
367
+ const ResponseSchema = Schema.mutable(Schema.Array(Response.Part(Toolkit.empty)));
368
+ const rawContent = yield* params.generateText(providerOptions);
369
+ const content = yield* Schema.decodeUnknown(ResponseSchema)(rawContent);
370
+ return content;
371
+ }
372
+ const rawContent = yield* params.generateText(providerOptions);
373
+ // Resolve the generated tool calls
374
+ const toolResults = yield* resolveToolCalls(rawContent, toolkit, options.concurrency);
375
+ const ResponseSchema = Schema.mutable(Schema.Array(Response.Part(toolkit)));
376
+ const content = yield* Schema.decodeUnknown(ResponseSchema)(rawContent);
377
+ // Return the content merged with the tool call results
378
+ return [...content, ...toolResults];
379
+ });
380
+ const streamContent = Effect.fnUntraced(function* (options, providerOptions) {
381
+ const toolChoice = options.toolChoice ?? "auto";
382
+ // If there is no toolkit, return immediately
383
+ if (Predicate.isUndefined(options.toolkit)) {
384
+ const schema = Schema.ChunkFromSelf(Response.StreamPart(Toolkit.empty));
385
+ const decode = Schema.decode(schema);
386
+ return params.streamText(providerOptions).pipe(Stream.mapChunksEffect(decode));
387
+ }
388
+ // If there is a toolkit resolve and apply it to the provider options
389
+ const toolkit = Effect.isEffect(options.toolkit) ? yield* options.toolkit : options.toolkit;
390
+ // If the toolkit is empty, return immediately
391
+ if (Object.values(toolkit.tools).length === 0) {
392
+ const schema = Schema.ChunkFromSelf(Response.StreamPart(Toolkit.empty));
393
+ const decode = Schema.decode(schema);
394
+ return params.streamText(providerOptions).pipe(Stream.mapChunksEffect(decode));
395
+ }
396
+ const tools = typeof toolChoice === "object" && "oneOf" in toolChoice ? Object.values(toolkit.tools).filter(tool => toolChoice.oneOf.includes(tool.name)) : Object.values(toolkit.tools);
397
+ providerOptions.tools = tools;
398
+ providerOptions.toolChoice = toolChoice;
399
+ // If tool call resolution is disabled, return the response without
400
+ // resolving the tool calls that were generated
401
+ if (options.disableToolCallResolution === true) {
402
+ const schema = Schema.ChunkFromSelf(Response.StreamPart(toolkit));
403
+ const decode = Schema.decode(schema);
404
+ return params.streamText(providerOptions).pipe(Stream.mapChunksEffect(decode));
405
+ }
406
+ const ResponseSchema = Schema.Chunk(Response.StreamPart(toolkit));
407
+ const decode = Schema.decode(ResponseSchema);
408
+ return params.streamText(providerOptions).pipe(Stream.mapChunksEffect(Effect.fnUntraced(function* (chunk) {
409
+ const rawContent = Chunk.toArray(chunk);
410
+ const toolResults = yield* resolveToolCalls(rawContent, toolkit, options.concurrency);
411
+ const content = yield* decode(rawContent);
412
+ return Chunk.unsafeFromArray([...content, ...toolResults]);
413
+ })));
414
+ });
415
+ return {
416
+ generateText,
417
+ generateObject,
418
+ streamText
419
+ };
420
+ });
421
+ // =============================================================================
422
+ // Accessors
423
+ // =============================================================================
424
+ /**
425
+ * Generate text using a language model.
426
+ *
427
+ * @example
428
+ * ```ts
429
+ * import { LanguageModel } from "@effect/ai"
430
+ * import { Effect } from "effect"
431
+ *
432
+ * const program = Effect.gen(function* () {
433
+ * const response = yield* LanguageModel.generateText({
434
+ * prompt: "Write a haiku about programming",
435
+ * toolChoice: "none"
436
+ * })
437
+ *
438
+ * console.log(response.text)
439
+ * console.log(response.usage.totalTokens)
440
+ *
441
+ * return response
442
+ * })
443
+ * ```
444
+ *
445
+ * @since 1.0.0
446
+ * @category Functions
447
+ */
448
+ export const generateText = /*#__PURE__*/Effect.serviceFunctionEffect(LanguageModel, model => model.generateText);
449
+ /**
450
+ * Generate a structured object from a schema using a language model.
451
+ *
452
+ * @example
453
+ * ```ts
454
+ * import { LanguageModel } from "@effect/ai"
455
+ * import { Effect, Schema } from "effect"
456
+ *
457
+ * const EventSchema = Schema.Struct({
458
+ * title: Schema.String,
459
+ * date: Schema.String,
460
+ * location: Schema.String
461
+ * })
462
+ *
463
+ * const program = Effect.gen(function* () {
464
+ * const response = yield* LanguageModel.generateObject({
465
+ * prompt: "Extract event info: Tech Conference on March 15th in San Francisco",
466
+ * schema: EventSchema,
467
+ * objectName: "event"
468
+ * })
469
+ *
470
+ * console.log(response.value)
471
+ * // { title: "Tech Conference", date: "March 15th", location: "San Francisco" }
472
+ *
473
+ * return response.value
474
+ * })
475
+ * ```
476
+ *
477
+ * @since 1.0.0
478
+ * @category Functions
479
+ */
480
+ export const generateObject = /*#__PURE__*/Effect.serviceFunctionEffect(LanguageModel, model => model.generateObject);
481
+ /**
482
+ * Generate text using a language model with streaming output.
483
+ *
484
+ * Returns a stream of response parts that are emitted as soon as they are
485
+ * available from the model, enabling real-time text generation experiences.
486
+ *
487
+ * @example
488
+ * ```ts
489
+ * import { LanguageModel } from "@effect/ai"
490
+ * import { Effect, Stream, Console } from "effect"
491
+ *
492
+ * const program = LanguageModel.streamText({
493
+ * prompt: "Write a story about a space explorer"
494
+ * }).pipe(Stream.runForEach((part) => {
495
+ * if (part.type === "text-delta") {
496
+ * return Console.log(part.delta)
497
+ * }
498
+ * return Effect.void
499
+ * }))
500
+ * ```
501
+ *
502
+ * @since 1.0.0
503
+ * @category Functions
504
+ */
505
+ export const streamText = options => Stream.unwrap(LanguageModel.pipe(Effect.map(model => model.streamText(options))));
506
+ // =============================================================================
507
+ // Tool Call Resolution
508
+ // =============================================================================
509
+ const resolveToolCalls = (content, toolkit, concurrency) => {
510
+ const toolNames = [];
511
+ const toolCalls = [];
512
+ for (const part of content) {
513
+ if (part.type === "tool-call") {
514
+ toolNames.push(part.name);
515
+ if (part.providerExecuted === true) {
516
+ continue;
517
+ }
518
+ toolCalls.push(part);
519
+ }
520
+ }
521
+ return Effect.forEach(toolCalls, toolCall => {
522
+ return toolkit.handle(toolCall.name, toolCall.params).pipe(Effect.map(({
523
+ encodedResult,
524
+ result
525
+ }) => Response.makePart("tool-result", {
526
+ id: toolCall.id,
527
+ name: toolCall.name,
528
+ result,
529
+ encodedResult,
530
+ providerName: toolCall.providerName,
531
+ providerExecuted: false
532
+ })));
533
+ }, {
534
+ concurrency
535
+ });
536
+ };
537
+ // =============================================================================
538
+ // Utilities
539
+ // =============================================================================
540
+ const resolveToolkit = toolkit => Effect.isEffect(toolkit) ? toolkit : Effect.succeed(toolkit);
541
+ const getObjectName = (objectName, schema) => Predicate.isNotUndefined(objectName) ? objectName : "_tag" in schema ? schema._tag : "identifier" in schema ? schema.identifier : "generateObject";
542
+ const resolveStructuredOutput = /*#__PURE__*/Effect.fnUntraced(function* (response, ResultSchema) {
543
+ const text = [];
544
+ for (const part of response) {
545
+ if (part.type === "text") {
546
+ text.push(part.text);
547
+ }
548
+ }
549
+ if (text.length === 0) {
550
+ return yield* new AiError.MalformedOutput({
551
+ module: "LanguageModel",
552
+ method: "generateObject",
553
+ description: "No object was generated by the large language model"
554
+ });
555
+ }
556
+ const decode = Schema.decode(Schema.parseJson(ResultSchema));
557
+ return yield* Effect.mapError(decode(text.join("")), cause => new AiError.MalformedOutput({
558
+ module: "LanguageModel",
559
+ method: "generateObject",
560
+ description: "Generated object failed to conform to provided schema",
561
+ cause
562
+ }));
563
+ });
564
+ const applySpanTransformer = (transformer, response, options) => {
565
+ if (Option.isSome(transformer)) {
566
+ transformer.value({
567
+ ...options,
568
+ response: response
569
+ });
570
+ }
571
+ };
572
+ //# sourceMappingURL=LanguageModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LanguageModel.js","names":["Chunk","Context","Effect","Option","ParseResult","Predicate","Schema","Stream","AiError","defaultIdGenerator","IdGenerator","Prompt","Response","CurrentSpanTransformer","Toolkit","LanguageModel","Tag","GenerateTextResponse","content","constructor","text","part","type","push","join","reasoning","filter","reasoningText","length","undefined","toolCalls","toolResults","finishReason","finishPart","find","isUndefined","reason","usage","Usage","inputTokens","outputTokens","totalTokens","reasoningTokens","cachedInputTokens","GenerateObjectResponse","value","make","fnUntraced","params","parentSpanTransformer","serviceOption","getSpanTransformer","pipe","map","orElse","idGenerator","getOrElse","generateText","options","useSpan","captureStackTrace","attributes","concurrency","toolChoice","span","spanTransformer","providerOptions","prompt","tools","responseFormat","generateContent","applySpanTransformer","catchTag","error","MalformedOutput","fromParseError","module","method","effect","withParentSpan","provideService","generateObject","schema","objectName","getObjectName","resolveStructuredOutput","streamText","makeSpanScoped","stream","streamContent","isNone","mapChunks","chunk","ensuring","sync","response","unwrapScoped","mapError","isParseError","toolkit","ResponseSchema","mutable","Array","Part","empty","rawContent","decodeUnknown","resolveToolkit","Object","values","tool","oneOf","includes","name","disableToolCallResolution","resolveToolCalls","ChunkFromSelf","StreamPart","decode","mapChunksEffect","isEffect","toArray","unsafeFromArray","serviceFunctionEffect","model","unwrap","toolNames","providerExecuted","forEach","toolCall","handle","encodedResult","result","makePart","id","providerName","succeed","isNotUndefined","_tag","identifier","ResultSchema","description","parseJson","cause","transformer","isSome"],"sources":["../../src/LanguageModel.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -19,8 +19,8 @@ import * as RcMap from "effect/RcMap";
19
19
  import * as Schema from "effect/Schema";
20
20
  import * as AST from "effect/SchemaAST";
21
21
  import * as FindMyWay from "find-my-way-ts";
22
- import * as AiTool from "./AiTool.js";
23
22
  import { CallToolResult, ClientNotificationRpcs, ClientRpcs, CompleteResult, Elicit, ElicitationDeclined, GetPromptResult, InternalError, InvalidParams, ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult, McpServerClient, McpServerClientMiddleware, ParamAnnotation, Prompt, Resource, ResourceTemplate, ServerNotificationRpcs, ServerRequestRpcs, TextContent, Tool, ToolAnnotations } from "./McpSchema.js";
23
+ import * as AiTool from "./Tool.js";
24
24
  /**
25
25
  * @since 1.0.0
26
26
  * @category McpServer
@@ -68,6 +68,7 @@ export class McpServer extends /*#__PURE__*/Context.Tag("@effect/ai/McpServer")(
68
68
  return McpServer.of({
69
69
  notifications: notifications.client,
70
70
  notificationsMailbox,
71
+ initializedClients: new Set(),
71
72
  get tools() {
72
73
  return tools;
73
74
  },
@@ -259,7 +260,11 @@ export const run = /*#__PURE__*/Effect.fnUntraced(function* (options) {
259
260
  payload: encoded
260
261
  };
261
262
  const clientIds = yield* patchedProtocol.clientIds;
262
- for (const clientId of clientIds) {
263
+ for (const clientId of server.initializedClients) {
264
+ if (!clientIds.has(clientId)) {
265
+ server.initializedClients.delete(clientId);
266
+ continue;
267
+ }
263
268
  yield* patchedProtocol.send(clientId, message);
264
269
  }
265
270
  })), Effect.catchAllCause(() => Effect.void), Effect.forever, Effect.forkScoped);
@@ -414,7 +419,7 @@ export const registerToolkit = /*#__PURE__*/Effect.fnUntraced(function* (toolkit
414
419
  const registry = yield* McpServer;
415
420
  const built = yield* toolkit;
416
421
  const context = yield* Effect.context();
417
- for (const tool of built.tools) {
422
+ for (const tool of Object.values(built.tools)) {
418
423
  const mcpTool = new Tool({
419
424
  name: tool.name,
420
425
  description: tool.description,
@@ -700,7 +705,9 @@ const layerHandlers = serverInfo => ClientRpcs.toLayer(Effect.gen(function* () {
700
705
  return {
701
706
  // Requests
702
707
  ping: () => Effect.succeed({}),
703
- initialize(params) {
708
+ initialize(params, {
709
+ clientId
710
+ }) {
704
711
  const requestedVersion = params.protocolVersion;
705
712
  const capabilities = {
706
713
  completions: {}
@@ -721,6 +728,7 @@ const layerHandlers = serverInfo => ClientRpcs.toLayer(Effect.gen(function* () {
721
728
  listChanged: true
722
729
  };
723
730
  }
731
+ server.initializedClients.add(clientId);
724
732
  return Effect.succeed({
725
733
  capabilities,
726
734
  serverInfo,