effect 4.0.3 → 4.0.4

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 (207) hide show
  1. package/AGENTS.md +24 -0
  2. package/CLAUDE.md +24 -0
  3. package/ai-docs/package.json +2 -2
  4. package/ai-docs/src/52_graphql/10_basics.ts +111 -0
  5. package/ai-docs/src/52_graphql/20_testing.ts +45 -0
  6. package/ai-docs/src/52_graphql/30_batching.ts +116 -0
  7. package/ai-docs/src/52_graphql/40_aliased-batching.ts +122 -0
  8. package/ai-docs/src/52_graphql/50_errors-and-retries.ts +74 -0
  9. package/ai-docs/src/52_graphql/index.md +6 -0
  10. package/dist/Context.d.ts.map +1 -1
  11. package/dist/Context.js +9 -0
  12. package/dist/Context.js.map +1 -1
  13. package/dist/RequestResolver.d.ts.map +1 -1
  14. package/dist/RequestResolver.js +4 -10
  15. package/dist/RequestResolver.js.map +1 -1
  16. package/dist/Scheduler.d.ts +9 -0
  17. package/dist/Scheduler.d.ts.map +1 -1
  18. package/dist/Scheduler.js +9 -0
  19. package/dist/Scheduler.js.map +1 -1
  20. package/dist/Schema.d.ts +8 -0
  21. package/dist/Schema.d.ts.map +1 -1
  22. package/dist/Schema.js +7 -0
  23. package/dist/Schema.js.map +1 -1
  24. package/dist/SchemaGetter.d.ts +4 -0
  25. package/dist/SchemaGetter.d.ts.map +1 -1
  26. package/dist/SchemaGetter.js +52 -33
  27. package/dist/SchemaGetter.js.map +1 -1
  28. package/dist/Sink.d.ts.map +1 -1
  29. package/dist/Sink.js +38 -17
  30. package/dist/Sink.js.map +1 -1
  31. package/dist/Stream.d.ts +11 -0
  32. package/dist/Stream.d.ts.map +1 -1
  33. package/dist/Stream.js +16 -1
  34. package/dist/Stream.js.map +1 -1
  35. package/dist/Utils.js +8 -3
  36. package/dist/Utils.js.map +1 -1
  37. package/dist/ai/AnthropicStructuredOutput.js +0 -2
  38. package/dist/ai/AnthropicStructuredOutput.js.map +1 -1
  39. package/dist/ai/Chat.d.ts +2 -2
  40. package/dist/ai/Chat.d.ts.map +1 -1
  41. package/dist/ai/LanguageModel.d.ts +38 -7
  42. package/dist/ai/LanguageModel.d.ts.map +1 -1
  43. package/dist/ai/LanguageModel.js +25 -7
  44. package/dist/ai/LanguageModel.js.map +1 -1
  45. package/dist/ai/McpServer.d.ts +55 -0
  46. package/dist/ai/McpServer.d.ts.map +1 -1
  47. package/dist/ai/McpServer.js +132 -22
  48. package/dist/ai/McpServer.js.map +1 -1
  49. package/dist/ai/Prompt.d.ts.map +1 -1
  50. package/dist/ai/Prompt.js +28 -5
  51. package/dist/ai/Prompt.js.map +1 -1
  52. package/dist/ai/Response.d.ts +4 -3
  53. package/dist/ai/Response.d.ts.map +1 -1
  54. package/dist/ai/Response.js.map +1 -1
  55. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  56. package/dist/cluster/ClusterWorkflowEngine.js +46 -8
  57. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  58. package/dist/cluster/Sharding.d.ts.map +1 -1
  59. package/dist/cluster/Sharding.js +6 -4
  60. package/dist/cluster/Sharding.js.map +1 -1
  61. package/dist/encoding/Sse.d.ts +6 -0
  62. package/dist/encoding/Sse.d.ts.map +1 -1
  63. package/dist/encoding/Sse.js +62 -70
  64. package/dist/encoding/Sse.js.map +1 -1
  65. package/dist/graphql/GraphQL.d.ts +349 -0
  66. package/dist/graphql/GraphQL.d.ts.map +1 -0
  67. package/dist/graphql/GraphQL.js +207 -0
  68. package/dist/graphql/GraphQL.js.map +1 -0
  69. package/dist/graphql/GraphQLClient.d.ts +562 -0
  70. package/dist/graphql/GraphQLClient.d.ts.map +1 -0
  71. package/dist/graphql/GraphQLClient.js +498 -0
  72. package/dist/graphql/GraphQLClient.js.map +1 -0
  73. package/dist/graphql/GraphQLClientError.d.ts +445 -0
  74. package/dist/graphql/GraphQLClientError.d.ts.map +1 -0
  75. package/dist/graphql/GraphQLClientError.js +479 -0
  76. package/dist/graphql/GraphQLClientError.js.map +1 -0
  77. package/dist/graphql/GraphQLGroup.d.ts +118 -0
  78. package/dist/graphql/GraphQLGroup.d.ts.map +1 -0
  79. package/dist/graphql/GraphQLGroup.js +109 -0
  80. package/dist/graphql/GraphQLGroup.js.map +1 -0
  81. package/dist/graphql/GraphQLMiddleware.d.ts +249 -0
  82. package/dist/graphql/GraphQLMiddleware.d.ts.map +1 -0
  83. package/dist/graphql/GraphQLMiddleware.js +130 -0
  84. package/dist/graphql/GraphQLMiddleware.js.map +1 -0
  85. package/dist/graphql/GraphQLProtocol.d.ts +731 -0
  86. package/dist/graphql/GraphQLProtocol.d.ts.map +1 -0
  87. package/dist/graphql/GraphQLProtocol.js +719 -0
  88. package/dist/graphql/GraphQLProtocol.js.map +1 -0
  89. package/dist/graphql/GraphQLResolver.d.ts +453 -0
  90. package/dist/graphql/GraphQLResolver.d.ts.map +1 -0
  91. package/dist/graphql/GraphQLResolver.js +552 -0
  92. package/dist/graphql/GraphQLResolver.js.map +1 -0
  93. package/dist/graphql/index.d.ts +40 -0
  94. package/dist/graphql/index.d.ts.map +1 -0
  95. package/dist/graphql/index.js +41 -0
  96. package/dist/graphql/index.js.map +1 -0
  97. package/dist/http/HttpClient.d.ts +15 -0
  98. package/dist/http/HttpClient.d.ts.map +1 -1
  99. package/dist/http/HttpClient.js +24 -10
  100. package/dist/http/HttpClient.js.map +1 -1
  101. package/dist/http/HttpEffect.d.ts.map +1 -1
  102. package/dist/http/HttpEffect.js +14 -7
  103. package/dist/http/HttpEffect.js.map +1 -1
  104. package/dist/http/HttpMiddleware.d.ts.map +1 -1
  105. package/dist/http/HttpMiddleware.js +31 -32
  106. package/dist/http/HttpMiddleware.js.map +1 -1
  107. package/dist/http/HttpRouter.d.ts +35 -0
  108. package/dist/http/HttpRouter.d.ts.map +1 -1
  109. package/dist/http/HttpRouter.js +35 -0
  110. package/dist/http/HttpRouter.js.map +1 -1
  111. package/dist/http/HttpServerResponse.d.ts +8 -6
  112. package/dist/http/HttpServerResponse.d.ts.map +1 -1
  113. package/dist/http/HttpServerResponse.js +27 -16
  114. package/dist/http/HttpServerResponse.js.map +1 -1
  115. package/dist/http/Multipart.d.ts.map +1 -1
  116. package/dist/http/Multipart.js +15 -1
  117. package/dist/http/Multipart.js.map +1 -1
  118. package/dist/http-api/HttpApiScalar.d.ts +5 -0
  119. package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
  120. package/dist/http-api/HttpApiScalar.js.map +1 -1
  121. package/dist/internal/dateTime.js +40 -35
  122. package/dist/internal/dateTime.js.map +1 -1
  123. package/dist/internal/effect.js +8 -3
  124. package/dist/internal/effect.js.map +1 -1
  125. package/dist/internal/graphql.d.ts +2 -0
  126. package/dist/internal/graphql.d.ts.map +1 -0
  127. package/dist/internal/graphql.js +195 -0
  128. package/dist/internal/graphql.js.map +1 -0
  129. package/dist/internal/graphqlHeaders.d.ts +4 -0
  130. package/dist/internal/graphqlHeaders.d.ts.map +1 -0
  131. package/dist/internal/graphqlHeaders.js +11 -0
  132. package/dist/internal/graphqlHeaders.js.map +1 -0
  133. package/dist/internal/request.js +20 -1
  134. package/dist/internal/request.js.map +1 -1
  135. package/dist/internal/schema/toCodeDocument.js +4 -1
  136. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  137. package/dist/internal/schema/toJsonSchemaDocument.js +29 -5
  138. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  139. package/dist/internal/version.js +1 -1
  140. package/dist/net/Host.d.ts +49 -0
  141. package/dist/net/Host.d.ts.map +1 -1
  142. package/dist/net/Host.js +55 -0
  143. package/dist/net/Host.js.map +1 -1
  144. package/dist/net/NetAddress.d.ts +8 -0
  145. package/dist/net/NetAddress.d.ts.map +1 -1
  146. package/dist/net/NetAddress.js +8 -0
  147. package/dist/net/NetAddress.js.map +1 -1
  148. package/dist/rpc/RpcServer.d.ts.map +1 -1
  149. package/dist/rpc/RpcServer.js +36 -9
  150. package/dist/rpc/RpcServer.js.map +1 -1
  151. package/dist/socket/Socket.d.ts +6 -0
  152. package/dist/socket/Socket.d.ts.map +1 -1
  153. package/dist/socket/Socket.js.map +1 -1
  154. package/dist/workflow/DurableDeferred.d.ts.map +1 -1
  155. package/dist/workflow/DurableDeferred.js +32 -3
  156. package/dist/workflow/DurableDeferred.js.map +1 -1
  157. package/dist/workflow/WorkflowEngine.d.ts +24 -2
  158. package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
  159. package/dist/workflow/WorkflowEngine.js +11 -2
  160. package/dist/workflow/WorkflowEngine.js.map +1 -1
  161. package/package.json +6 -3
  162. package/src/Context.ts +9 -0
  163. package/src/RequestResolver.ts +4 -10
  164. package/src/Scheduler.ts +9 -0
  165. package/src/Schema.ts +8 -0
  166. package/src/SchemaGetter.ts +47 -35
  167. package/src/Sink.ts +45 -18
  168. package/src/Stream.ts +33 -4
  169. package/src/Utils.ts +8 -5
  170. package/src/ai/AnthropicStructuredOutput.ts +2 -2
  171. package/src/ai/Chat.ts +2 -2
  172. package/src/ai/LanguageModel.ts +96 -24
  173. package/src/ai/McpServer.ts +244 -90
  174. package/src/ai/Prompt.ts +24 -10
  175. package/src/ai/Response.ts +6 -3
  176. package/src/cluster/ClusterWorkflowEngine.ts +51 -12
  177. package/src/cluster/Sharding.ts +12 -9
  178. package/src/encoding/Sse.ts +69 -79
  179. package/src/graphql/GraphQL.ts +494 -0
  180. package/src/graphql/GraphQLClient.ts +912 -0
  181. package/src/graphql/GraphQLClientError.ts +542 -0
  182. package/src/graphql/GraphQLGroup.ts +167 -0
  183. package/src/graphql/GraphQLMiddleware.ts +253 -0
  184. package/src/graphql/GraphQLProtocol.ts +1286 -0
  185. package/src/graphql/GraphQLResolver.ts +1010 -0
  186. package/src/graphql/index.ts +48 -0
  187. package/src/http/HttpClient.ts +54 -10
  188. package/src/http/HttpEffect.ts +11 -5
  189. package/src/http/HttpMiddleware.ts +33 -34
  190. package/src/http/HttpRouter.ts +35 -0
  191. package/src/http/HttpServerResponse.ts +28 -16
  192. package/src/http/Multipart.ts +17 -1
  193. package/src/http-api/HttpApiScalar.ts +5 -0
  194. package/src/internal/dateTime.ts +13 -10
  195. package/src/internal/effect.ts +8 -3
  196. package/src/internal/graphql.ts +263 -0
  197. package/src/internal/graphqlHeaders.ts +11 -0
  198. package/src/internal/request.ts +31 -3
  199. package/src/internal/schema/toCodeDocument.ts +7 -1
  200. package/src/internal/schema/toJsonSchemaDocument.ts +34 -2
  201. package/src/internal/version.ts +1 -1
  202. package/src/net/Host.ts +72 -0
  203. package/src/net/NetAddress.ts +9 -0
  204. package/src/rpc/RpcServer.ts +55 -15
  205. package/src/socket/Socket.ts +6 -0
  206. package/src/workflow/DurableDeferred.ts +43 -5
  207. package/src/workflow/WorkflowEngine.ts +48 -4
@@ -122,7 +122,7 @@ export interface LanguageModel {
122
122
  <Options extends NoExcessProperties<GenerateTextOptionsWithoutToolkit, Options>>(
123
123
  options: Options & GenerateTextOptionsWithoutToolkit
124
124
  ): Effect.Effect<
125
- GenerateTextResponse<{}>,
125
+ GenerateTextResponse<{}, ExtractToolParametersModeWithoutToolkit<Options>>,
126
126
  ExtractError<Options>,
127
127
  ExtractServices<Options>
128
128
  >
@@ -181,7 +181,7 @@ export interface LanguageModel {
181
181
  <Options extends NoExcessProperties<GenerateTextOptionsWithoutToolkit, Options>>(
182
182
  options: Options & GenerateTextOptionsWithoutToolkit
183
183
  ): Stream.Stream<
184
- Response.StreamPart<{}>,
184
+ Response.StreamPart<{}, ExtractToolParametersModeWithoutToolkit<Options>>,
185
185
  ExtractError<Options>,
186
186
  ExtractServices<Options>
187
187
  >
@@ -312,6 +312,22 @@ export interface GenerateTextOptions<Tools extends Record<string, Tool.Any>> {
312
312
  * resolver execution yourself.
313
313
  */
314
314
  readonly disableToolCallResolution?: boolean | undefined
315
+
316
+ /**
317
+ * Controls tool call validation when `disableToolCallResolution` is `true`.
318
+ * Defaults to `"strict"`, which validates tool names and encoded parameters.
319
+ *
320
+ * **Details**
321
+ *
322
+ * `"deferred"` returns model-generated calls with `unknown` parameters for
323
+ * the caller to validate, including undeclared names and calls without a
324
+ * toolkit. Provider-executed calls and other response parts remain validated.
325
+ * Providers must support this option to return undeclared tool calls.
326
+ *
327
+ * Has no effect when resolution is enabled; `Toolkit` validates parameters
328
+ * according to each tool's `failureMode`.
329
+ */
330
+ readonly toolCallValidation?: "strict" | "deferred" | undefined
315
331
  }
316
332
 
317
333
  type GenerateTextOptionsWithoutToolkit = Omit<GenerateTextOptions<{}>, "toolkit"> & {
@@ -589,18 +605,32 @@ export type ExtractTools<Options> = Options extends {
589
605
  : {}
590
606
 
591
607
  /**
592
- * Resolves to `"encoded"` when tool call resolution is
593
- * disabled, otherwise `"opaque"`.
608
+ * Resolves to `"deferred"` when tool call resolution may be disabled with
609
+ * deferred tool call validation. Otherwise resolves to `"encoded"` when tool
610
+ * call resolution is disabled and `"opaque"` when it may be enabled.
594
611
  *
595
612
  * @stability unstable
596
613
  * @category utility types
597
614
  * @since 4.0.0
598
615
  */
599
- export type ExtractToolParametersMode<Options> = Options extends {
600
- readonly disableToolCallResolution: true
601
- } ? "encoded"
616
+ export type ExtractToolParametersMode<Options> = "deferred" extends Options["toolCallValidation" & keyof Options] ?
617
+ true extends Options["disableToolCallResolution" & keyof Options] ? "deferred" : "opaque"
618
+ : Options extends { readonly disableToolCallResolution: true } ? "encoded"
602
619
  : "opaque"
603
620
 
621
+ /**
622
+ * Resolves the tool parameters mode for requests without a toolkit:
623
+ * `"deferred"` when tool call validation may be deferred, otherwise
624
+ * `"decoded"`.
625
+ *
626
+ * @stability unstable
627
+ * @category utility types
628
+ * @since 4.0.4
629
+ */
630
+ export type ExtractToolParametersModeWithoutToolkit<Options> = "deferred" extends ExtractToolParametersMode<Options>
631
+ ? "deferred"
632
+ : "decoded"
633
+
604
634
  type ExtractErrorFromToolkitOption<ToolkitValue, DisableToolCallResolution extends boolean> = ToolkitValue extends
605
635
  Toolkit.WithHandler<infer Tools> ?
606
636
  | AiError.AiError
@@ -785,6 +815,12 @@ export interface ProviderOptions {
785
815
  * prompt after the provider rejected the incremental request.
786
816
  */
787
817
  readonly incrementalFallback?: boolean | undefined
818
+
819
+ /**
820
+ * Defaults to `"strict"`. With `"deferred"`, return calls to tools absent
821
+ * from `tools` with unchanged parameters instead of `ToolNotFoundError`.
822
+ */
823
+ readonly toolCallValidation?: "strict" | "deferred" | undefined
788
824
  }
789
825
 
790
826
  /**
@@ -863,7 +899,7 @@ export const make: (params: {
863
899
  >(
864
900
  options: Options & GenerateTextOptions<Tools>
865
901
  ): Effect.Effect<
866
- GenerateTextResponse<Tools>,
902
+ GenerateTextResponse<Tools, Response.ToolParametersMode>,
867
903
  ExtractError<Options>,
868
904
  ExtractServices<Options>
869
905
  > =>
@@ -1071,6 +1107,10 @@ export const make: (params: {
1071
1107
  const toolChoice = options.toolChoice ?? "auto"
1072
1108
  const concurrency = options.concurrency ?? "unbounded"
1073
1109
  annotateRequestOptions(providerOptions, toolChoice, concurrency)
1110
+ const deferToolCallValidation = isToolCallValidationDeferred(options)
1111
+ if (deferToolCallValidation) {
1112
+ providerOptions.toolCallValidation = "deferred"
1113
+ }
1074
1114
 
1075
1115
  const generateWithNonIncrementalFallback = () => {
1076
1116
  const requestOptions: ProviderOptions = {
@@ -1120,7 +1160,7 @@ export const make: (params: {
1120
1160
  }
1121
1161
  }
1122
1162
  const ResponseSchema = Schema.mutable(
1123
- Schema.Array(Response.Part(Toolkit.empty))
1163
+ Schema.Array(withUndeclaredToolCalls(Response.Part(Toolkit.empty), deferToolCallValidation))
1124
1164
  )
1125
1165
  const rawContent = yield* generateWithNonIncrementalFallback()
1126
1166
  const content = yield* Schema.decodeEffect(ResponseSchema)(rawContent)
@@ -1158,7 +1198,7 @@ export const make: (params: {
1158
1198
  }
1159
1199
  }
1160
1200
  const ResponseSchema = Schema.mutable(
1161
- Schema.Array(Response.Part(Toolkit.empty))
1201
+ Schema.Array(withUndeclaredToolCalls(Response.Part(Toolkit.empty), deferToolCallValidation))
1162
1202
  )
1163
1203
  const rawContent = yield* generateWithNonIncrementalFallback()
1164
1204
  const content = yield* Schema.decodeEffect(ResponseSchema)(rawContent)
@@ -1232,10 +1272,13 @@ export const make: (params: {
1232
1272
  }
1233
1273
  }
1234
1274
 
1235
- const ResponseSchema = Schema.mutable(Schema.Array(Response.Part(
1236
- options.disableToolCallResolution === true
1237
- ? makeToolkitWithEncodedParameters(toolkit)
1238
- : makeToolkitWithOpaqueParameters(toolkit)
1275
+ const ResponseSchema = Schema.mutable(Schema.Array(withUndeclaredToolCalls(
1276
+ Response.Part(
1277
+ options.disableToolCallResolution === true && !deferToolCallValidation
1278
+ ? makeToolkitWithEncodedParameters(toolkit)
1279
+ : makeToolkitWithOpaqueParameters(toolkit)
1280
+ ),
1281
+ deferToolCallValidation
1239
1282
  )))
1240
1283
 
1241
1284
  // If tool call resolution is disabled, return the response without
@@ -1243,6 +1286,9 @@ export const make: (params: {
1243
1286
  if (options.disableToolCallResolution === true) {
1244
1287
  const rawContent = yield* generateWithNonIncrementalFallback()
1245
1288
  const content = yield* Schema.decodeEffect(ResponseSchema)(rawContent)
1289
+ if (deferToolCallValidation) {
1290
+ yield* validateProviderExecutedToolCalls(makeToolkitWithEncodedParameters(toolkit), rawContent)
1291
+ }
1246
1292
  if (tracker) {
1247
1293
  const responseMetadata = content.find((part) => part.type === "response-metadata")
1248
1294
  if (Predicate.isNotUndefined(responseMetadata) && Predicate.isNotUndefined(responseMetadata.id)) {
@@ -1324,6 +1370,10 @@ export const make: (params: {
1324
1370
  const toolChoice = options.toolChoice ?? "auto"
1325
1371
  const concurrency = options.concurrency ?? "unbounded"
1326
1372
  annotateRequestOptions(providerOptions, toolChoice, concurrency)
1373
+ const deferToolCallValidation = isToolCallValidationDeferred(options)
1374
+ if (deferToolCallValidation) {
1375
+ providerOptions.toolCallValidation = "deferred"
1376
+ }
1327
1377
 
1328
1378
  const streamWithNonIncrementalFallback = () => {
1329
1379
  const requestOptions: ProviderOptions = {
@@ -1383,7 +1433,9 @@ export const make: (params: {
1383
1433
  providerOptions.incrementalPrompt = prepared.value.prompt
1384
1434
  }
1385
1435
  }
1386
- const schema = Schema.NonEmptyArray(Response.StreamPart(Toolkit.empty))
1436
+ const schema = Schema.NonEmptyArray(
1437
+ withUndeclaredToolCalls(Response.StreamPart(Toolkit.empty), deferToolCallValidation)
1438
+ )
1387
1439
  const decodeParts = Schema.decodeEffect(schema)
1388
1440
  return pipe(
1389
1441
  streamWithNonIncrementalFallback(),
@@ -1432,7 +1484,9 @@ export const make: (params: {
1432
1484
  providerOptions.incrementalPrompt = prepared.value.prompt
1433
1485
  }
1434
1486
  }
1435
- const schema = Schema.NonEmptyArray(Response.StreamPart(Toolkit.empty))
1487
+ const schema = Schema.NonEmptyArray(
1488
+ withUndeclaredToolCalls(Response.StreamPart(Toolkit.empty), deferToolCallValidation)
1489
+ )
1436
1490
  const decodeParts = Schema.decodeEffect(schema)
1437
1491
  return pipe(
1438
1492
  streamWithNonIncrementalFallback(),
@@ -1535,19 +1589,26 @@ export const make: (params: {
1535
1589
  }
1536
1590
  }
1537
1591
 
1538
- const ResponseSchema = Schema.NonEmptyArray(Response.StreamPart(
1539
- options.disableToolCallResolution === true
1540
- ? makeToolkitWithEncodedParameters(toolkit)
1541
- : makeToolkitWithOpaqueParameters(toolkit)
1592
+ const ResponseSchema = Schema.NonEmptyArray(withUndeclaredToolCalls(
1593
+ Response.StreamPart(
1594
+ options.disableToolCallResolution === true && !deferToolCallValidation
1595
+ ? makeToolkitWithEncodedParameters(toolkit)
1596
+ : makeToolkitWithOpaqueParameters(toolkit)
1597
+ ),
1598
+ deferToolCallValidation
1542
1599
  ))
1543
1600
  const decodeParts = Schema.decodeEffect(ResponseSchema)
1544
1601
 
1545
1602
  // If tool call resolution is disabled, return the response without
1546
1603
  // resolving the tool calls that were generated
1547
1604
  if (options.disableToolCallResolution === true) {
1605
+ const encodedToolkit = deferToolCallValidation ? makeToolkitWithEncodedParameters(toolkit) : undefined
1548
1606
  return streamWithNonIncrementalFallback().pipe(
1549
1607
  Stream.mapArrayEffect((parts) =>
1550
1608
  decodeParts(parts).pipe(
1609
+ encodedToolkit
1610
+ ? Effect.tap(() => validateProviderExecutedToolCalls(encodedToolkit, parts))
1611
+ : identity,
1551
1612
  tracker ?
1552
1613
  Effect.tap((decodedParts) => {
1553
1614
  for (const part of decodedParts) {
@@ -1812,7 +1873,7 @@ export const generateText: {
1812
1873
  >(
1813
1874
  options: Options & GenerateTextOptionsWithoutToolkit
1814
1875
  ): Effect.Effect<
1815
- GenerateTextResponse<{}>,
1876
+ GenerateTextResponse<{}, ExtractToolParametersModeWithoutToolkit<Options>>,
1816
1877
  ExtractError<Options>,
1817
1878
  LanguageModel | ExtractServices<Options>
1818
1879
  >
@@ -1962,7 +2023,7 @@ export const streamText: {
1962
2023
  >(
1963
2024
  options: Options & GenerateTextOptionsWithoutToolkit
1964
2025
  ): Stream.Stream<
1965
- Response.StreamPart<{}>,
2026
+ Response.StreamPart<{}, ExtractToolParametersModeWithoutToolkit<Options>>,
1966
2027
  ExtractError<Options>,
1967
2028
  ExtractServices<Options> | LanguageModel
1968
2029
  >
@@ -2443,9 +2504,20 @@ const makeToolkitWithOpaqueParameters = <Tools extends Record<string, Tool.Any>>
2443
2504
  ...Object.values(toolkit.tools).map((tool) => withParameterMode(tool, "opaque"))
2444
2505
  )
2445
2506
 
2507
+ const isToolCallValidationDeferred = (options: GenerateTextOptions<any>): boolean =>
2508
+ options.disableToolCallResolution === true && options.toolCallValidation === "deferred"
2509
+
2510
+ const UndeclaredToolCallPart = Response.ToolCallPart("", Schema.Unknown).mapFields((fields) => ({
2511
+ ...fields,
2512
+ name: Schema.String
2513
+ }))
2514
+
2515
+ const withUndeclaredToolCalls = <S extends Schema.Top>(partSchema: S, deferToolCallValidation: boolean): S =>
2516
+ deferToolCallValidation ? Schema.Union([partSchema, UndeclaredToolCallPart]) as any : partSchema
2517
+
2446
2518
  // Provider-executed tools bypass Toolkit, so validate their parameters here.
2447
- const validateProviderExecutedToolCalls = <Tools extends Record<string, Tool.Any>>(
2448
- toolkit: Toolkit.WithHandler<Tools>,
2519
+ const validateProviderExecutedToolCalls = (
2520
+ toolkit: { readonly tools: Record<string, Tool.Any> },
2449
2521
  parts: ReadonlyArray<Response.PartEncoded | Response.StreamPartEncoded>
2450
2522
  ): Effect.Effect<void, Schema.SchemaError> =>
2451
2523
  Effect.forEach(