effect 4.0.0-beta.104 → 4.0.0-beta.106

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 (300) hide show
  1. package/AGENTS.md +381 -0
  2. package/CLAUDE.md +381 -0
  3. package/ai-docs/README.md +44 -0
  4. package/ai-docs/package.json +36 -0
  5. package/ai-docs/src/01_effect/01_basics/01_effect-gen.ts +30 -0
  6. package/ai-docs/src/01_effect/01_basics/02_effect-fn.ts +39 -0
  7. package/ai-docs/src/01_effect/01_basics/10_creating-effects.ts +74 -0
  8. package/ai-docs/src/01_effect/01_basics/index.md +5 -0
  9. package/ai-docs/src/01_effect/02_schema/10_schema-basics.ts +43 -0
  10. package/ai-docs/src/01_effect/02_schema/index.md +7 -0
  11. package/ai-docs/src/01_effect/03_services/01_service.ts +45 -0
  12. package/ai-docs/src/01_effect/03_services/10_reference.ts +10 -0
  13. package/ai-docs/src/01_effect/03_services/20_layer-composition.ts +70 -0
  14. package/ai-docs/src/01_effect/03_services/20_layer-unwrap.ts +66 -0
  15. package/ai-docs/src/01_effect/03_services/index.md +5 -0
  16. package/ai-docs/src/01_effect/04_errors/01_error-handling.ts +30 -0
  17. package/ai-docs/src/01_effect/04_errors/10_catch-tags.ts +24 -0
  18. package/ai-docs/src/01_effect/04_errors/20_reason-errors.ts +64 -0
  19. package/ai-docs/src/01_effect/04_errors/index.md +1 -0
  20. package/ai-docs/src/01_effect/05_resources/10_acquire-release.ts +105 -0
  21. package/ai-docs/src/01_effect/05_resources/20_layer-side-effects.ts +31 -0
  22. package/ai-docs/src/01_effect/05_resources/30_layer-map.ts +86 -0
  23. package/ai-docs/src/01_effect/05_resources/index.md +3 -0
  24. package/ai-docs/src/01_effect/06_running/10_run-main.ts +30 -0
  25. package/ai-docs/src/01_effect/06_running/20_layer-launch.ts +27 -0
  26. package/ai-docs/src/01_effect/06_running/index.md +1 -0
  27. package/ai-docs/src/01_effect/07_pubsub/10_pubsub.ts +56 -0
  28. package/ai-docs/src/01_effect/07_pubsub/index.md +3 -0
  29. package/ai-docs/src/03_stream/10_creating-streams.ts +103 -0
  30. package/ai-docs/src/03_stream/20_consuming-streams.ts +137 -0
  31. package/ai-docs/src/03_stream/30_encoding.ts +165 -0
  32. package/ai-docs/src/03_stream/index.md +4 -0
  33. package/ai-docs/src/04_integration/10_managed-runtime.ts +129 -0
  34. package/ai-docs/src/04_integration/index.md +5 -0
  35. package/ai-docs/src/05_batching/10_request-resolver.ts +89 -0
  36. package/ai-docs/src/05_batching/index.md +3 -0
  37. package/ai-docs/src/06_schedule/10_schedules.ts +110 -0
  38. package/ai-docs/src/06_schedule/index.md +3 -0
  39. package/ai-docs/src/07_datetime/10_creating-and-formatting.ts +30 -0
  40. package/ai-docs/src/07_datetime/20_time-zones.ts +44 -0
  41. package/ai-docs/src/07_datetime/index.md +5 -0
  42. package/ai-docs/src/08_observability/10_logging.ts +66 -0
  43. package/ai-docs/src/08_observability/20_otlp-tracing.ts +95 -0
  44. package/ai-docs/src/08_observability/index.md +7 -0
  45. package/ai-docs/src/09_testing/10_effect-tests.ts +55 -0
  46. package/ai-docs/src/09_testing/20_layer-tests.ts +138 -0
  47. package/ai-docs/src/09_testing/index.md +1 -0
  48. package/ai-docs/src/10_predicate/01_basics.ts +14 -0
  49. package/ai-docs/src/10_predicate/index.md +9 -0
  50. package/ai-docs/src/50_http-client/10_basics.ts +102 -0
  51. package/ai-docs/src/50_http-client/index.md +3 -0
  52. package/ai-docs/src/51_http-server/10_basics.ts +116 -0
  53. package/ai-docs/src/51_http-server/fixtures/api/Api.ts +14 -0
  54. package/ai-docs/src/51_http-server/fixtures/api/Authorization.ts +36 -0
  55. package/ai-docs/src/51_http-server/fixtures/api/System.ts +10 -0
  56. package/ai-docs/src/51_http-server/fixtures/api/Users.ts +91 -0
  57. package/ai-docs/src/51_http-server/fixtures/domain/User.ts +12 -0
  58. package/ai-docs/src/51_http-server/fixtures/domain/UserErrors.ts +22 -0
  59. package/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +36 -0
  60. package/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +71 -0
  61. package/ai-docs/src/51_http-server/fixtures/server/Users.ts +62 -0
  62. package/ai-docs/src/51_http-server/index.md +3 -0
  63. package/ai-docs/src/60_child-process/10_working-with-child-processes.ts +117 -0
  64. package/ai-docs/src/60_child-process/index.md +3 -0
  65. package/ai-docs/src/70_cli/10_basics.ts +136 -0
  66. package/ai-docs/src/70_cli/index.md +5 -0
  67. package/ai-docs/src/71_ai/10_language-model.ts +156 -0
  68. package/ai-docs/src/71_ai/20_tools.ts +226 -0
  69. package/ai-docs/src/71_ai/30_chat.ts +158 -0
  70. package/ai-docs/src/71_ai/fixtures/domain/LaunchPlan.ts +9 -0
  71. package/ai-docs/src/71_ai/index.md +5 -0
  72. package/ai-docs/src/80_cluster/10_entities.ts +97 -0
  73. package/ai-docs/src/80_cluster/index.md +4 -0
  74. package/ai-docs/src/index.md +10 -0
  75. package/ai-docs/tsconfig.json +24 -0
  76. package/dist/Brand.d.ts +3 -3
  77. package/dist/Brand.d.ts.map +1 -1
  78. package/dist/Brand.js +4 -3
  79. package/dist/Brand.js.map +1 -1
  80. package/dist/Config.d.ts.map +1 -1
  81. package/dist/Config.js +5 -4
  82. package/dist/Config.js.map +1 -1
  83. package/dist/ConfigProvider.d.ts +35 -3
  84. package/dist/ConfigProvider.d.ts.map +1 -1
  85. package/dist/ConfigProvider.js +41 -8
  86. package/dist/ConfigProvider.js.map +1 -1
  87. package/dist/Context.d.ts +0 -1
  88. package/dist/Context.d.ts.map +1 -1
  89. package/dist/Context.js +1 -22
  90. package/dist/Context.js.map +1 -1
  91. package/dist/Cron.d.ts +31 -0
  92. package/dist/Cron.d.ts.map +1 -1
  93. package/dist/Cron.js +58 -2
  94. package/dist/Cron.js.map +1 -1
  95. package/dist/Fiber.d.ts +1 -1
  96. package/dist/Fiber.d.ts.map +1 -1
  97. package/dist/Function.d.ts +26 -0
  98. package/dist/Function.d.ts.map +1 -1
  99. package/dist/Function.js +36 -0
  100. package/dist/Function.js.map +1 -1
  101. package/dist/JsonSchema.d.ts.map +1 -1
  102. package/dist/JsonSchema.js +34 -17
  103. package/dist/JsonSchema.js.map +1 -1
  104. package/dist/Optic.d.ts +35 -21
  105. package/dist/Optic.d.ts.map +1 -1
  106. package/dist/Optic.js +33 -34
  107. package/dist/Optic.js.map +1 -1
  108. package/dist/Schema.d.ts +105 -109
  109. package/dist/Schema.d.ts.map +1 -1
  110. package/dist/Schema.js +141 -104
  111. package/dist/Schema.js.map +1 -1
  112. package/dist/SchemaAST.d.ts +32 -17
  113. package/dist/SchemaAST.d.ts.map +1 -1
  114. package/dist/SchemaAST.js +79 -60
  115. package/dist/SchemaAST.js.map +1 -1
  116. package/dist/SchemaError.d.ts +8 -8
  117. package/dist/SchemaError.d.ts.map +1 -1
  118. package/dist/SchemaError.js +7 -6
  119. package/dist/SchemaError.js.map +1 -1
  120. package/dist/SchemaGetter.d.ts +8 -5
  121. package/dist/SchemaGetter.d.ts.map +1 -1
  122. package/dist/SchemaGetter.js +41 -37
  123. package/dist/SchemaGetter.js.map +1 -1
  124. package/dist/SchemaIssue.d.ts +195 -38
  125. package/dist/SchemaIssue.d.ts.map +1 -1
  126. package/dist/SchemaIssue.js +243 -68
  127. package/dist/SchemaIssue.js.map +1 -1
  128. package/dist/SchemaParser.d.ts +30 -0
  129. package/dist/SchemaParser.d.ts.map +1 -1
  130. package/dist/SchemaParser.js +39 -9
  131. package/dist/SchemaParser.js.map +1 -1
  132. package/dist/SchemaRepresentation.d.ts +15 -3
  133. package/dist/SchemaRepresentation.d.ts.map +1 -1
  134. package/dist/SchemaRepresentation.js +8 -2
  135. package/dist/SchemaRepresentation.js.map +1 -1
  136. package/dist/SchemaTransformation.d.ts +2 -2
  137. package/dist/SchemaTransformation.d.ts.map +1 -1
  138. package/dist/SchemaTransformation.js +26 -26
  139. package/dist/SchemaTransformation.js.map +1 -1
  140. package/dist/ScopedRef.d.ts.map +1 -1
  141. package/dist/ScopedRef.js +1 -1
  142. package/dist/ScopedRef.js.map +1 -1
  143. package/dist/Stdio.d.ts +17 -4
  144. package/dist/Stdio.d.ts.map +1 -1
  145. package/dist/Stdio.js +6 -3
  146. package/dist/Stdio.js.map +1 -1
  147. package/dist/TxQueue.js +1 -1
  148. package/dist/TxQueue.js.map +1 -1
  149. package/dist/internal/effect.js +2 -4
  150. package/dist/internal/effect.js.map +1 -1
  151. package/dist/internal/executionPlan.js +3 -2
  152. package/dist/internal/executionPlan.js.map +1 -1
  153. package/dist/internal/rcRef.js +18 -13
  154. package/dist/internal/rcRef.js.map +1 -1
  155. package/dist/internal/schema/fromJsonSchemaDocument.js +10 -6
  156. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
  157. package/dist/internal/schema/schema.js +1 -9
  158. package/dist/internal/schema/schema.js.map +1 -1
  159. package/dist/internal/schema/toArbitrary.d.ts +1 -4
  160. package/dist/internal/schema/toArbitrary.d.ts.map +1 -1
  161. package/dist/internal/schema/toArbitrary.js +0 -74
  162. package/dist/internal/schema/toArbitrary.js.map +1 -1
  163. package/dist/internal/schema/toJsonSchemaDocument.js +18 -4
  164. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  165. package/dist/internal/schema/toRepresentation.js +45 -43
  166. package/dist/internal/schema/toRepresentation.js.map +1 -1
  167. package/dist/testing/TestSchema.d.ts +1 -1
  168. package/dist/testing/TestSchema.d.ts.map +1 -1
  169. package/dist/testing/TestSchema.js +10 -9
  170. package/dist/testing/TestSchema.js.map +1 -1
  171. package/dist/unstable/ai/McpSchema.d.ts +110 -110
  172. package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
  173. package/dist/unstable/ai/McpServer.d.ts.map +1 -1
  174. package/dist/unstable/ai/McpServer.js +23 -11
  175. package/dist/unstable/ai/McpServer.js.map +1 -1
  176. package/dist/unstable/ai/Prompt.d.ts +4 -3
  177. package/dist/unstable/ai/Prompt.d.ts.map +1 -1
  178. package/dist/unstable/ai/Prompt.js +42 -17
  179. package/dist/unstable/ai/Prompt.js.map +1 -1
  180. package/dist/unstable/cluster/Entity.d.ts +2 -2
  181. package/dist/unstable/cluster/Entity.d.ts.map +1 -1
  182. package/dist/unstable/cluster/Entity.js.map +1 -1
  183. package/dist/unstable/cluster/EntityProxy.d.ts +3 -3
  184. package/dist/unstable/cluster/EntityProxy.d.ts.map +1 -1
  185. package/dist/unstable/cluster/EntityProxy.js +4 -3
  186. package/dist/unstable/cluster/EntityProxy.js.map +1 -1
  187. package/dist/unstable/cluster/Reply.js +4 -4
  188. package/dist/unstable/cluster/Reply.js.map +1 -1
  189. package/dist/unstable/cluster/Sharding.d.ts +2 -2
  190. package/dist/unstable/cluster/Sharding.d.ts.map +1 -1
  191. package/dist/unstable/cluster/Sharding.js +14 -5
  192. package/dist/unstable/cluster/Sharding.js.map +1 -1
  193. package/dist/unstable/encoding/Msgpack.d.ts.map +1 -1
  194. package/dist/unstable/encoding/Msgpack.js +6 -6
  195. package/dist/unstable/encoding/Msgpack.js.map +1 -1
  196. package/dist/unstable/eventlog/EventLogEncryption.d.ts +6 -5
  197. package/dist/unstable/eventlog/EventLogEncryption.d.ts.map +1 -1
  198. package/dist/unstable/eventlog/EventLogEncryption.js +14 -12
  199. package/dist/unstable/eventlog/EventLogEncryption.js.map +1 -1
  200. package/dist/unstable/eventlog/EventLogMessage.d.ts +3 -3
  201. package/dist/unstable/eventlog/EventLogMessage.d.ts.map +1 -1
  202. package/dist/unstable/eventlog/EventLogMessage.js +2 -3
  203. package/dist/unstable/eventlog/EventLogMessage.js.map +1 -1
  204. package/dist/unstable/eventlog/EventLogRemote.js +4 -4
  205. package/dist/unstable/eventlog/EventLogRemote.js.map +1 -1
  206. package/dist/unstable/eventlog/EventLogServerEncrypted.js +3 -2
  207. package/dist/unstable/eventlog/EventLogServerEncrypted.js.map +1 -1
  208. package/dist/unstable/http/HttpClient.d.ts +59 -3
  209. package/dist/unstable/http/HttpClient.d.ts.map +1 -1
  210. package/dist/unstable/http/HttpClient.js +33 -19
  211. package/dist/unstable/http/HttpClient.js.map +1 -1
  212. package/dist/unstable/http/HttpServerRequest.d.ts.map +1 -1
  213. package/dist/unstable/http/HttpServerRequest.js +7 -1
  214. package/dist/unstable/http/HttpServerRequest.js.map +1 -1
  215. package/dist/unstable/http/MultipartParser/internal/multipart.d.ts.map +1 -1
  216. package/dist/unstable/http/MultipartParser/internal/multipart.js +18 -6
  217. package/dist/unstable/http/MultipartParser/internal/multipart.js.map +1 -1
  218. package/dist/unstable/httpapi/HttpApiBuilder.js +10 -10
  219. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  220. package/dist/unstable/httpapi/HttpApiClient.js +9 -9
  221. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  222. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  223. package/dist/unstable/httpapi/OpenApi.js +1 -1
  224. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  225. package/dist/unstable/reactivity/AsyncResult.d.ts.map +1 -1
  226. package/dist/unstable/reactivity/AsyncResult.js +4 -4
  227. package/dist/unstable/reactivity/AsyncResult.js.map +1 -1
  228. package/dist/unstable/reactivity/Atom.d.ts +26 -11
  229. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  230. package/dist/unstable/reactivity/Atom.js +9 -22
  231. package/dist/unstable/reactivity/Atom.js.map +1 -1
  232. package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
  233. package/dist/unstable/rpc/RpcClient.js +8 -1
  234. package/dist/unstable/rpc/RpcClient.js.map +1 -1
  235. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  236. package/dist/unstable/rpc/RpcServer.js +3 -2
  237. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  238. package/dist/unstable/sql/SqlResolver.d.ts.map +1 -1
  239. package/dist/unstable/sql/SqlResolver.js +20 -16
  240. package/dist/unstable/sql/SqlResolver.js.map +1 -1
  241. package/dist/unstable/workers/Worker.d.ts.map +1 -1
  242. package/dist/unstable/workers/Worker.js +11 -12
  243. package/dist/unstable/workers/Worker.js.map +1 -1
  244. package/dist/unstable/workflow/Workflow.d.ts.map +1 -1
  245. package/dist/unstable/workflow/Workflow.js +2 -2
  246. package/dist/unstable/workflow/Workflow.js.map +1 -1
  247. package/package.json +5 -2
  248. package/src/Brand.ts +4 -4
  249. package/src/Config.ts +6 -4
  250. package/src/ConfigProvider.ts +43 -8
  251. package/src/Context.ts +1 -23
  252. package/src/Cron.ts +65 -2
  253. package/src/Fiber.ts +1 -1
  254. package/src/Function.ts +37 -0
  255. package/src/JsonSchema.ts +43 -42
  256. package/src/Optic.ts +59 -58
  257. package/src/Schema.ts +213 -217
  258. package/src/SchemaAST.ts +135 -78
  259. package/src/SchemaError.ts +9 -9
  260. package/src/SchemaGetter.ts +89 -30
  261. package/src/SchemaIssue.ts +285 -80
  262. package/src/SchemaParser.ts +51 -17
  263. package/src/SchemaRepresentation.ts +15 -3
  264. package/src/SchemaTransformation.ts +66 -18
  265. package/src/ScopedRef.ts +3 -1
  266. package/src/Stdio.ts +23 -4
  267. package/src/TxQueue.ts +1 -1
  268. package/src/internal/effect.ts +3 -6
  269. package/src/internal/executionPlan.ts +3 -2
  270. package/src/internal/rcRef.ts +24 -16
  271. package/src/internal/schema/fromJsonSchemaDocument.ts +19 -14
  272. package/src/internal/schema/schema.ts +1 -17
  273. package/src/internal/schema/toArbitrary.ts +0 -72
  274. package/src/internal/schema/toJsonSchemaDocument.ts +24 -4
  275. package/src/internal/schema/toRepresentation.ts +66 -48
  276. package/src/testing/TestSchema.ts +10 -10
  277. package/src/unstable/ai/McpServer.ts +23 -11
  278. package/src/unstable/ai/Prompt.ts +51 -19
  279. package/src/unstable/cluster/Entity.ts +7 -2
  280. package/src/unstable/cluster/EntityProxy.ts +12 -5
  281. package/src/unstable/cluster/Reply.ts +4 -4
  282. package/src/unstable/cluster/Sharding.ts +29 -17
  283. package/src/unstable/encoding/Msgpack.ts +12 -8
  284. package/src/unstable/eventlog/EventLogEncryption.ts +15 -16
  285. package/src/unstable/eventlog/EventLogMessage.ts +2 -3
  286. package/src/unstable/eventlog/EventLogRemote.ts +4 -4
  287. package/src/unstable/eventlog/EventLogServerEncrypted.ts +2 -2
  288. package/src/unstable/http/HttpClient.ts +132 -23
  289. package/src/unstable/http/HttpServerRequest.ts +8 -3
  290. package/src/unstable/http/MultipartParser/internal/multipart.ts +19 -6
  291. package/src/unstable/httpapi/HttpApiBuilder.ts +32 -13
  292. package/src/unstable/httpapi/HttpApiClient.ts +26 -8
  293. package/src/unstable/httpapi/OpenApi.ts +4 -1
  294. package/src/unstable/reactivity/AsyncResult.ts +11 -6
  295. package/src/unstable/reactivity/Atom.ts +44 -25
  296. package/src/unstable/rpc/RpcClient.ts +9 -1
  297. package/src/unstable/rpc/RpcServer.ts +4 -2
  298. package/src/unstable/sql/SqlResolver.ts +28 -20
  299. package/src/unstable/workers/Worker.ts +13 -14
  300. package/src/unstable/workflow/Workflow.ts +2 -5
@@ -34,20 +34,6 @@ type LazyOption<T> = (
34
34
  recursionStack: RecursionStack
35
35
  ) => FastCheck.Arbitrary<T> | undefined
36
36
 
37
- export interface MutableReport {
38
- readonly warnings: Array<Schema.Annotations.ToArbitrary.Warning>
39
- }
40
-
41
- /** @internal */
42
- export function makeReport(): MutableReport {
43
- return { warnings: [] }
44
- }
45
-
46
- /** @internal */
47
- export function toReport(report: MutableReport): Schema.Annotations.ToArbitrary.Report {
48
- return { warnings: report.warnings.slice() }
49
- }
50
-
51
37
  function arbitraryError(what: string) {
52
38
  return new Error(`Unable to derive an arbitrary for ${what}`)
53
39
  }
@@ -394,64 +380,6 @@ function finiteNumberContext(ctx: Context): Context {
394
380
  }
395
381
  }
396
382
 
397
- function reportChecks(report: MutableReport, checks: SchemaAST.Checks | undefined, path: ReadonlyArray<PropertyKey>) {
398
- function visit(check: SchemaAST.Check<any>, covered: boolean) {
399
- const arbitrary = check.annotations?.arbitrary
400
- const nextCovered = covered || arbitrary?.constraint !== undefined || arbitrary?.candidate !== undefined
401
- if (check._tag !== "Filter") {
402
- for (const child of check.checks) {
403
- visit(child, nextCovered)
404
- }
405
- } else if (!nextCovered) {
406
- const description = check.annotations?.representation?.id ?? check.annotations?.identifier ??
407
- check.annotations?.expected
408
- report.warnings.push({ _tag: "OpaqueFilter", path, ...(description === undefined ? {} : { description }) })
409
- }
410
- }
411
- checks?.forEach((check) => visit(check, false))
412
- }
413
-
414
- /** @internal */
415
- export function collectReport(ast: SchemaAST.AST, report: MutableReport) {
416
- const stack = new WeakSet<SchemaAST.AST>()
417
- function visit(ast: SchemaAST.AST, path: ReadonlyArray<PropertyKey>) {
418
- if (stack.has(ast)) {
419
- return
420
- }
421
- stack.add(ast)
422
- reportChecks(report, ast.checks, path)
423
- switch (ast._tag) {
424
- case "Declaration":
425
- ast.typeParameters.forEach((tp) => visit(tp, path))
426
- break
427
- case "Arrays": {
428
- for (const [i, type] of [...ast.elements, ...ast.rest].entries()) {
429
- visit(type, [...path, i])
430
- }
431
- break
432
- }
433
- case "Objects":
434
- ast.propertySignatures.forEach((ps) => visit(ps.type, [...path, ps.name]))
435
- ast.indexSignatures.forEach((is) => {
436
- visit(is.parameter, path)
437
- visit(is.type, path)
438
- })
439
- break
440
- case "Union":
441
- ast.types.forEach((type) => visit(type, path))
442
- break
443
- case "TemplateLiteral":
444
- ast.parts.forEach((part, i) => visit(SchemaAST.toEncoded(part), [...path, i]))
445
- break
446
- case "Suspend":
447
- visit(ast.thunk(), path)
448
- break
449
- }
450
- stack.delete(ast)
451
- }
452
- visit(ast, [])
453
- }
454
-
455
383
  function applyCandidates(
456
384
  fc: typeof FastCheck,
457
385
  ctx: Context,
@@ -1,7 +1,8 @@
1
1
  import * as Arr from "../../Array.ts"
2
2
  import * as Equal from "../../Equal.ts"
3
- import { escapeToken } from "../../JsonPointer.ts"
3
+ import { escapeToken, unescapeToken } from "../../JsonPointer.ts"
4
4
  import type * as JsonSchema from "../../JsonSchema.ts"
5
+ import { rewriteRefs } from "../../JsonSchema.ts"
5
6
  import * as RegEx from "../../RegExp.ts"
6
7
  import type * as Schema from "../../Schema.ts"
7
8
  import * as SchemaAST from "../../SchemaAST.ts"
@@ -21,6 +22,11 @@ const jsonSchemaAnnotationExcludedKeys = new Set([
21
22
  ...InternalAnnotations.jsonSchemaAnnotationKeys
22
23
  ])
23
24
 
25
+ /** @internal */
26
+ export const toRepresentationOptions = {
27
+ isAnonymousReferenceAllowed: (ast: SchemaAST.AST): boolean => !SchemaAST.isDeclaration(ast)
28
+ }
29
+
24
30
  function collectJsonSchemaAnnotations(
25
31
  annotations: Schema.Annotations.Annotations | undefined,
26
32
  options: Schema.ToJsonSchemaOptions | undefined
@@ -142,22 +148,26 @@ function compileJsonSchema(
142
148
  references: SchemaRepresentation.References,
143
149
  options: Schema.ToJsonSchemaOptions | undefined
144
150
  ): JsonSchema.MultiDocument<"draft-2020-12"> {
145
- const definitions: Record<string, JsonSchema.JsonSchema> = {}
146
151
  // null = compiling, string = canonical key, object = compiled schema
147
152
  const definitionStates = new Map<string, JsonSchema.JsonSchema | string | null>()
148
153
  const compiledRepresentations = new WeakMap<SchemaRepresentation.Representation, JsonSchema.JsonSchema>()
149
154
  const fallbackDefinitions = new Map<string, Array<string>>()
155
+ let hasAliases = false
150
156
  const referenceKeys = Object.keys(references)
151
157
  for (const key of referenceKeys) {
152
158
  compileDefinition(key, ["references", key])
153
159
  }
160
+ const schemas = Arr.map(
161
+ representations,
162
+ (representation, index) => finalizeJsonSchema(recur(representation, rootPaths[index]))
163
+ )
164
+ const definitions: Record<string, JsonSchema.JsonSchema> = {}
154
165
  for (const key of referenceKeys) {
155
166
  const compiled = definitionStates.get(key)!
156
167
  if (typeof compiled !== "string") {
157
- InternalRecord.assignProperty(definitions, key, compiled)
168
+ InternalRecord.assignProperty(definitions, key, finalizeJsonSchema(compiled))
158
169
  }
159
170
  }
160
- const schemas = Arr.map(representations, (representation, index) => recur(representation, rootPaths[index]))
161
171
  return { dialect: "draft-2020-12", schemas, definitions }
162
172
 
163
173
  function compileDefinition(key: string, path: Path): string {
@@ -179,6 +189,7 @@ function compileJsonSchema(
179
189
  if (candidates === undefined) fallbackDefinitions.set(fallback, [key])
180
190
  else candidates.push(key)
181
191
  } else {
192
+ hasAliases = true
182
193
  definitionStates.set(key, match)
183
194
  return match
184
195
  }
@@ -187,6 +198,15 @@ function compileJsonSchema(
187
198
  return key
188
199
  }
189
200
 
201
+ function finalizeJsonSchema(schema: JsonSchema.JsonSchema): JsonSchema.JsonSchema {
202
+ if (!hasAliases) return schema
203
+ return rewriteRefs(schema, ($ref) =>
204
+ $ref.replace(/^#\/\$defs\/([^/]*)/, (match, token) => {
205
+ const canonical = definitionStates.get(unescapeToken(token))
206
+ return typeof canonical === "string" ? `#/$defs/${escapeToken(canonical)}` : match
207
+ }))
208
+ }
209
+
190
210
  function getIdentifierFallback(
191
211
  representation: SchemaRepresentation.Representation
192
212
  ): string | undefined {
@@ -7,17 +7,24 @@ import * as InternalAnnotations from "./annotations.ts"
7
7
 
8
8
  /** @internal */
9
9
  export function toRepresentation(
10
- ast: SchemaAST.AST
10
+ ast: SchemaAST.AST,
11
+ options?: Options
11
12
  ): SchemaRepresentation.Document {
12
- const { references, representations } = toRepresentations([ast])
13
+ const { references, representations } = toRepresentations([ast], options)
13
14
  return { representation: representations[0], references }
14
15
  }
15
16
 
16
17
  /** @internal */
17
18
  export function toRepresentations(
18
- asts: readonly [SchemaAST.AST, ...Array<SchemaAST.AST>]
19
+ asts: readonly [SchemaAST.AST, ...Array<SchemaAST.AST>],
20
+ options?: Options
19
21
  ): SchemaRepresentation.MultiDocument {
20
- return fromASTs(asts)
22
+ return fromASTs(asts, options)
23
+ }
24
+
25
+ /** @internal */
26
+ export interface Options {
27
+ readonly isAnonymousReferenceAllowed?: ((ast: SchemaAST.AST) => boolean) | undefined
21
28
  }
22
29
 
23
30
  type CheckRepresentationAnnotation = SchemaRepresentation.CheckRepresentationAnnotation<
@@ -28,11 +35,49 @@ function annotationsField<A>(annotations: A | undefined): { readonly annotations
28
35
  return annotations === undefined ? undefined : { annotations }
29
36
  }
30
37
 
31
- // Preserve repeated structural nodes as references without adding noise for leaf nodes.
32
- function isShareable(ast: SchemaAST.AST): boolean {
33
- return SchemaAST.isArrays(ast) ||
34
- SchemaAST.isObjects(ast) ||
35
- (SchemaAST.isUnion(ast) && ast.types.some(isShareable))
38
+ function hasShareableStructure(
39
+ ast: SchemaAST.AST,
40
+ isAnonymousReferenceAllowed: Options["isAnonymousReferenceAllowed"]
41
+ ): boolean {
42
+ if (isAnonymousReferenceAllowed?.(ast) === false) return false
43
+ switch (ast._tag) {
44
+ case "Arrays":
45
+ case "Objects":
46
+ case "Suspend":
47
+ return true
48
+ case "Declaration":
49
+ return true
50
+ case "Union":
51
+ return ast.types.some((ast) => hasShareableStructure(ast, isAnonymousReferenceAllowed))
52
+ default:
53
+ return false
54
+ }
55
+ }
56
+
57
+ function isWorthReferencing(bodyCost: number, occurrences: number): boolean {
58
+ return occurrences * bodyCost > bodyCost + occurrences + 1
59
+ }
60
+
61
+ function isAnonymousReferenceEligible(
62
+ ast: SchemaAST.AST,
63
+ occurrences: number,
64
+ isAnonymousReferenceAllowed: Options["isAnonymousReferenceAllowed"]
65
+ ): boolean {
66
+ if (isAnonymousReferenceAllowed?.(ast) === false) return false
67
+ if (hasShareableStructure(ast, isAnonymousReferenceAllowed)) return true
68
+ switch (ast._tag) {
69
+ case "Union":
70
+ return isWorthReferencing(ast.types.length + 1, occurrences)
71
+ case "Enum":
72
+ return isWorthReferencing(ast.enums.length + 1, occurrences)
73
+ case "TemplateLiteral":
74
+ return isWorthReferencing(ast.parts.length + 1, occurrences)
75
+ case "Literal":
76
+ return typeof ast.literal === "string" &&
77
+ isWorthReferencing(ast.literal.length / 32 + 1, occurrences)
78
+ default:
79
+ return false
80
+ }
36
81
  }
37
82
 
38
83
  interface ReferenceIdentifier {
@@ -54,17 +99,15 @@ function resolveReferenceIdentifier(
54
99
  }
55
100
 
56
101
  function fromASTs(
57
- asts: readonly [SchemaAST.AST, ...Array<SchemaAST.AST>]
102
+ asts: readonly [SchemaAST.AST, ...Array<SchemaAST.AST>],
103
+ options: Options | undefined
58
104
  ): SchemaRepresentation.MultiDocument {
59
105
  const references: Record<string, SchemaRepresentation.Representation> = {}
60
106
  const anonymousReferences = new Map<SchemaAST.AST, string>()
61
107
  const referenceOwners = new Map<string, SchemaAST.AST>()
62
- const valueIds = new Map<unknown, number>()
63
- const canonicalByKey = new Map<string, SchemaAST.AST>()
64
- let nextValueId = 0
65
108
  const buildingReferences = new Set<string>()
66
109
  const visiting = new Set<SchemaAST.AST>()
67
- const visited = new Set<SchemaAST.AST>()
110
+ const occurrences = new Map<SchemaAST.AST, number>()
68
111
  const shared = new Set<SchemaAST.AST>()
69
112
 
70
113
  for (const ast of asts) visit(ast)
@@ -84,35 +127,6 @@ function fromASTs(
84
127
  return candidate
85
128
  }
86
129
 
87
- function getValueId(value: unknown): number {
88
- if (typeof value === "number" && globalThis.Number.isNaN(value)) {
89
- return nextValueId++
90
- }
91
- const found = valueIds.get(value)
92
- if (found !== undefined) return found
93
- const id = nextValueId++
94
- valueIds.set(value, id)
95
- return id
96
- }
97
-
98
- function getIdentityKey(ast: SchemaAST.AST): string {
99
- let identity = ast._tag
100
- for (const [key, value] of Object.entries(ast)) {
101
- if (key !== "_tag" && key !== "context") identity += `:${getValueId(value)}`
102
- }
103
- return identity
104
- }
105
-
106
- function getCanonicalAST(ast: SchemaAST.AST): SchemaAST.AST {
107
- const key = getIdentityKey(ast)
108
- const canonical = canonicalByKey.get(key)
109
- if (canonical === undefined) {
110
- canonicalByKey.set(key, ast)
111
- return ast
112
- }
113
- return canonical
114
- }
115
-
116
130
  function annotateReference(
117
131
  ast: SchemaAST.AST,
118
132
  referenceIdentifier: ReferenceIdentifier,
@@ -143,12 +157,16 @@ function fromASTs(
143
157
 
144
158
  function visit(input: SchemaAST.AST): void {
145
159
  const ast = SchemaAST.getLastEncoding(input)
146
- const owner = getCanonicalAST(ast)
147
- if (visited.has(owner)) {
148
- if (isShareable(ast)) shared.add(owner)
160
+ const owner = SchemaAST.getContextOwner(ast)
161
+ const count = (occurrences.get(owner) ?? 0) + 1
162
+ occurrences.set(owner, count)
163
+ if (count > 1) {
164
+ if (
165
+ !shared.has(owner) &&
166
+ isAnonymousReferenceEligible(owner, count, options?.isAnonymousReferenceAllowed)
167
+ ) shared.add(owner)
149
168
  return
150
169
  }
151
- visited.add(owner)
152
170
  visitChecks(ast.checks)
153
171
  switch (ast._tag) {
154
172
  case "Declaration":
@@ -178,7 +196,7 @@ function fromASTs(
178
196
 
179
197
  function recur(input: SchemaAST.AST): SchemaRepresentation.Representation {
180
198
  const ast = SchemaAST.getLastEncoding(input)
181
- const owner = getCanonicalAST(ast)
199
+ const owner = SchemaAST.getContextOwner(ast)
182
200
  const referenceIdentifier = resolveReferenceIdentifier(input, ast)
183
201
  if (referenceIdentifier !== undefined) {
184
202
  const reference = getReference(referenceIdentifier.identifier, owner)
@@ -17,7 +17,7 @@ import * as Record from "../Record.ts"
17
17
  import * as Result from "../Result.ts"
18
18
  import * as Schema from "../Schema.ts"
19
19
  import * as SchemaAST from "../SchemaAST.ts"
20
- import type * as SchemaIssue from "../SchemaIssue.ts"
20
+ import * as SchemaIssue from "../SchemaIssue.ts"
21
21
  import * as SchemaParser from "../SchemaParser.ts"
22
22
  import * as FastCheck from "../testing/FastCheck.ts"
23
23
 
@@ -123,7 +123,7 @@ export class Asserts<S extends Schema.Constraint> {
123
123
  async function succeed(input: S["~type.make.in"], expected?: S["Type"]) {
124
124
  const r = await Effect.runPromise(
125
125
  makeEffect(input, options).pipe(
126
- Effect.mapErrorEager((issue) => issue.toString()),
126
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
127
127
  Effect.result
128
128
  )
129
129
  )
@@ -135,7 +135,7 @@ export class Asserts<S extends Schema.Constraint> {
135
135
  async fail(input: unknown, message: string) {
136
136
  const r = await Effect.runPromise(
137
137
  makeEffect(input, options).pipe(
138
- Effect.mapErrorEager((issue) => issue.toString()),
138
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
139
139
  Effect.result
140
140
  )
141
141
  )
@@ -172,13 +172,13 @@ export class Asserts<S extends Schema.Constraint> {
172
172
  }) {
173
173
  const decodeUnknownEffect = SchemaParser.decodeUnknownEffect(this.schema)
174
174
  const encodeEffect = SchemaParser.encodeEffect(this.schema)
175
- const arbitrary = Schema.toArbitrary(this.schema)
175
+ const arbitrary = Schema.toArbitrary(this.schema)(FastCheck)
176
176
  return FastCheck.assert(
177
177
  FastCheck.asyncProperty(arbitrary, async (t) => {
178
178
  const r = await Effect.runPromise(
179
179
  encodeEffect(t).pipe(
180
180
  Effect.flatMapEager((e) => decodeUnknownEffect(e)),
181
- Effect.mapErrorEager((issue) => issue.toString()),
181
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
182
182
  Effect.result
183
183
  )
184
184
  )
@@ -280,7 +280,7 @@ export class Asserts<S extends Schema.Constraint> {
280
280
  }) {
281
281
  const params = options?.params
282
282
  const is = Schema.is(schema)
283
- const arb = Schema.toArbitrary(schema)
283
+ const arb = Schema.toArbitrary(schema)(FastCheck)
284
284
  FastCheck.assert(FastCheck.property(arb, (a) => is(a)), { numRuns: 20, ...params })
285
285
  }
286
286
  }
@@ -367,7 +367,7 @@ export class Decoding<S extends Schema.Constraint> {
367
367
  ) {
368
368
  const r = await Effect.runPromise(
369
369
  this.decodeUnknownEffect(input, this.options?.parseOptions).pipe(
370
- Effect.mapErrorEager((issue) => issue.toString()),
370
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
371
371
  Effect.result
372
372
  )
373
373
  )
@@ -401,7 +401,7 @@ export class Decoding<S extends Schema.Constraint> {
401
401
  ) {
402
402
  const r = await Effect.runPromise(
403
403
  this.decodeUnknownEffect(input, this.options?.parseOptions).pipe(
404
- Effect.mapErrorEager((issue) => issue.toString()),
404
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
405
405
  Effect.result
406
406
  )
407
407
  )
@@ -507,7 +507,7 @@ export class Encoding<S extends Schema.Constraint> {
507
507
  ) {
508
508
  const r = await Effect.runPromise(
509
509
  this.encodeUnknownEffect(input, this.options?.parseOptions).pipe(
510
- Effect.mapErrorEager((issue) => issue.toString()),
510
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
511
511
  Effect.result
512
512
  )
513
513
  )
@@ -541,7 +541,7 @@ export class Encoding<S extends Schema.Constraint> {
541
541
  ) {
542
542
  const r = await Effect.runPromise(
543
543
  this.encodeUnknownEffect(input, this.options?.parseOptions).pipe(
544
- Effect.mapErrorEager((issue) => issue.toString()),
544
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
545
545
  Effect.result
546
546
  )
547
547
  )
@@ -489,7 +489,7 @@ const runWithProtocolState = Effect.fnUntraced(function*(options: {
489
489
  const isHttp = Option.isSome(yield* Effect.serviceOption(HttpRouter.HttpRouter))
490
490
  const sessions = protocolState.sessions
491
491
  const clientProtocols = new Map<number, McpProtocol.ProtocolAdapter>()
492
- const cancelledRequests = new Map<number, Set<string>>()
492
+ const activeRequests = new Map<number, Map<string, boolean>>()
493
493
  const handlers = yield* Layer.build(layerHandlers(options, {
494
494
  sessions,
495
495
  protocolRegistry
@@ -577,11 +577,13 @@ const runWithProtocolState = Effect.fnUntraced(function*(options: {
577
577
  ...protocol,
578
578
  send: (clientId, response) => {
579
579
  if (response._tag === "Exit") {
580
- const requests = cancelledRequests.get(clientId)
581
- if (requests?.delete(requestKey(response.requestId)) === true) {
582
- if (requests.size === 0) {
583
- cancelledRequests.delete(clientId)
584
- }
580
+ const requests = activeRequests.get(clientId)
581
+ const key = requestKey(response.requestId)
582
+ const cancelled = requests?.get(key)
583
+ if (requests !== undefined && requests.delete(key) && requests.size === 0) {
584
+ activeRequests.delete(clientId)
585
+ }
586
+ if (cancelled === true) {
585
587
  return Effect.void
586
588
  }
587
589
  }
@@ -670,9 +672,12 @@ const runWithProtocolState = Effect.fnUntraced(function*(options: {
670
672
  if (request.tag === "notifications/cancelled") {
671
673
  return decodeCancelledNotification(request.payload).pipe(
672
674
  Effect.flatMap(({ requestId }) => {
673
- const requests = cancelledRequests.get(clientId) ?? new Set<string>()
674
- requests.add(requestKey(requestId))
675
- cancelledRequests.set(clientId, requests)
675
+ const key = requestKey(requestId)
676
+ const requests = activeRequests.get(clientId)
677
+ if (requests?.has(key) !== true) {
678
+ return Effect.void
679
+ }
680
+ requests.set(key, true)
676
681
  return f(clientId, {
677
682
  _tag: "Interrupt",
678
683
  requestId: RpcMessage.RequestId(requestId)
@@ -732,7 +737,14 @@ const runWithProtocolState = Effect.fnUntraced(function*(options: {
732
737
  }
733
738
  return selectedProtocol.payloadCodecs(rpc).decode(request.payload).pipe(
734
739
  Effect.matchEffect({
735
- onSuccess: () => f(clientId, routedRequest),
740
+ onSuccess: () => {
741
+ if (request.isNotification !== true) {
742
+ const requests = activeRequests.get(clientId) ?? new Map<string, boolean>()
743
+ requests.set(requestKey(request.id), false)
744
+ activeRequests.set(clientId, requests)
745
+ }
746
+ return f(clientId, routedRequest)
747
+ },
736
748
  onFailure: () =>
737
749
  request.isNotification
738
750
  ? Effect.void
@@ -752,7 +764,7 @@ const runWithProtocolState = Effect.fnUntraced(function*(options: {
752
764
  case "Interrupt":
753
765
  return f(clientId, request)
754
766
  case "Eof":
755
- cancelledRequests.delete(clientId)
767
+ activeRequests.delete(clientId)
756
768
  return f(clientId, request)
757
769
  case "Pong":
758
770
  case "Exit":
@@ -1840,20 +1840,30 @@ export const Prompt: Schema.Codec<Prompt, PromptEncoded> = Schema.Struct({
1840
1840
  Schema.decodeTo(
1841
1841
  $Prompt,
1842
1842
  SchemaTransformation.transformOrFail({
1843
- decode: (input) =>
1843
+ decode: (input, options) =>
1844
1844
  Effect.mapBothEager(
1845
1845
  SchemaParser.decodeEffect(Schema.Array(Message))(input.content),
1846
1846
  {
1847
1847
  onSuccess: makePrompt,
1848
- onFailure: () => new SchemaIssue.InvalidValue({ message: "Invalid Prompt messages" })
1848
+ onFailure: () =>
1849
+ new SchemaIssue.InvalidValue(
1850
+ { message: "Invalid Prompt messages" },
1851
+ input.content,
1852
+ options
1853
+ )
1849
1854
  }
1850
1855
  ),
1851
- encode: (prompt) =>
1856
+ encode: (prompt, options) =>
1852
1857
  Effect.mapBothEager(
1853
1858
  SchemaParser.encodeEffect(Schema.Array(Message))(prompt.content),
1854
1859
  {
1855
1860
  onSuccess: (messages) => ({ content: messages }),
1856
- onFailure: () => new SchemaIssue.InvalidValue({ message: "Invalid Prompt messages" })
1861
+ onFailure: () =>
1862
+ new SchemaIssue.InvalidValue(
1863
+ { message: "Invalid Prompt messages" },
1864
+ prompt.content,
1865
+ options
1866
+ )
1857
1867
  }
1858
1868
  )
1859
1869
  })
@@ -1994,11 +2004,23 @@ export const make = (input: RawInput): Prompt => {
1994
2004
  */
1995
2005
  export const fromMessages = (messages: ReadonlyArray<Message>): Prompt => makePrompt(messages)
1996
2006
 
2007
+ const mergeOptions = (left: ProviderOptions, right: ProviderOptions): ProviderOptions => {
2008
+ const result: Record<string, ProviderOptions[string]> = { ...left }
2009
+ for (const [provider, metadata] of Object.entries(right)) {
2010
+ const previous = result[provider]
2011
+ result[provider] = Predicate.isObject(previous) && Predicate.isObject(metadata)
2012
+ ? Object.assign({}, previous, metadata)
2013
+ : metadata
2014
+ }
2015
+ return result
2016
+ }
2017
+
1997
2018
  /**
1998
2019
  * Creates a `Prompt` from response parts by folding completed text and
1999
- * reasoning streams into assistant parts, placing tool calls and approval
2000
- * requests in an assistant message, and placing non-preliminary tool results
2001
- * in a tool message using their encoded results.
2020
+ * reasoning streams into assistant parts, preserving provider metadata as
2021
+ * prompt options, placing tool calls and approval requests in an assistant
2022
+ * message, and placing non-preliminary tool results in a tool message using
2023
+ * their encoded results.
2002
2024
  *
2003
2025
  * **Example** (Creating prompts from response parts)
2004
2026
  *
@@ -2042,55 +2064,63 @@ export const fromResponseParts = (parts: ReadonlyArray<Response.AnyPart>): Promp
2042
2064
  const assistantParts: Array<AssistantMessagePart> = []
2043
2065
  const toolParts: Array<ToolMessagePart> = []
2044
2066
 
2045
- const activeTextDeltas = new Map<string, { text: string }>()
2046
- const activeReasoningDeltas = new Map<string, { text: string }>()
2067
+ const activeTextDeltas = new Map<string, { text: string; options: ProviderOptions }>()
2068
+ const activeReasoningDeltas = new Map<string, { text: string; options: ProviderOptions }>()
2047
2069
 
2048
2070
  for (const part of parts) {
2049
2071
  switch (part.type) {
2050
2072
  // Text Parts
2051
2073
  case "text": {
2052
- assistantParts.push(makePart("text", { text: part.text }))
2074
+ assistantParts.push(makePart("text", { text: part.text, options: part.metadata }))
2053
2075
  break
2054
2076
  }
2055
2077
 
2056
2078
  // Text Parts (streaming)
2057
2079
  case "text-start": {
2058
- activeTextDeltas.set(part.id, { text: "" })
2080
+ activeTextDeltas.set(part.id, { text: "", options: part.metadata })
2059
2081
  break
2060
2082
  }
2061
2083
  case "text-delta": {
2062
2084
  if (activeTextDeltas.has(part.id)) {
2063
- activeTextDeltas.get(part.id)!.text += part.delta
2085
+ const active = activeTextDeltas.get(part.id)!
2086
+ active.text += part.delta
2087
+ active.options = mergeOptions(active.options, part.metadata)
2064
2088
  }
2065
2089
  break
2066
2090
  }
2067
2091
  case "text-end": {
2068
2092
  if (activeTextDeltas.has(part.id)) {
2069
- assistantParts.push(makePart("text", activeTextDeltas.get(part.id)!))
2093
+ const active = activeTextDeltas.get(part.id)!
2094
+ active.options = mergeOptions(active.options, part.metadata)
2095
+ assistantParts.push(makePart("text", active))
2070
2096
  }
2071
2097
  break
2072
2098
  }
2073
2099
 
2074
2100
  // Reasoning Parts
2075
2101
  case "reasoning": {
2076
- assistantParts.push(makePart("reasoning", { text: part.text }))
2102
+ assistantParts.push(makePart("reasoning", { text: part.text, options: part.metadata }))
2077
2103
  break
2078
2104
  }
2079
2105
 
2080
2106
  // Reasoning Parts (streaming)
2081
2107
  case "reasoning-start": {
2082
- activeReasoningDeltas.set(part.id, { text: "" })
2108
+ activeReasoningDeltas.set(part.id, { text: "", options: part.metadata })
2083
2109
  break
2084
2110
  }
2085
2111
  case "reasoning-delta": {
2086
2112
  if (activeReasoningDeltas.has(part.id)) {
2087
- activeReasoningDeltas.get(part.id)!.text += part.delta
2113
+ const active = activeReasoningDeltas.get(part.id)!
2114
+ active.text += part.delta
2115
+ active.options = mergeOptions(active.options, part.metadata)
2088
2116
  }
2089
2117
  break
2090
2118
  }
2091
2119
  case "reasoning-end": {
2092
2120
  if (activeReasoningDeltas.has(part.id)) {
2093
- assistantParts.push(makePart("reasoning", activeReasoningDeltas.get(part.id)!))
2121
+ const active = activeReasoningDeltas.get(part.id)!
2122
+ active.options = mergeOptions(active.options, part.metadata)
2123
+ assistantParts.push(makePart("reasoning", active))
2094
2124
  }
2095
2125
  break
2096
2126
  }
@@ -2101,7 +2131,8 @@ export const fromResponseParts = (parts: ReadonlyArray<Response.AnyPart>): Promp
2101
2131
  id: part.id,
2102
2132
  name: part.name,
2103
2133
  params: part.params,
2104
- providerExecuted: part.providerExecuted ?? false
2134
+ providerExecuted: part.providerExecuted ?? false,
2135
+ options: part.metadata
2105
2136
  }))
2106
2137
  break
2107
2138
  }
@@ -2115,7 +2146,8 @@ export const fromResponseParts = (parts: ReadonlyArray<Response.AnyPart>): Promp
2115
2146
  name: part.name,
2116
2147
  isFailure: part.isFailure,
2117
2148
  result: part.encodedResult,
2118
- providerExecuted: part.providerExecuted ?? false
2149
+ providerExecuted: part.providerExecuted ?? false,
2150
+ options: part.metadata
2119
2151
  }))
2120
2152
  }
2121
2153
  break
@@ -34,7 +34,12 @@ import * as RpcClient from "../rpc/RpcClient.ts"
34
34
  import * as RpcGroup from "../rpc/RpcGroup.ts"
35
35
  import * as RpcSchema from "../rpc/RpcSchema.ts"
36
36
  import * as RpcServer from "../rpc/RpcServer.ts"
37
- import type { AlreadyProcessingMessage, MailboxFull, PersistenceError } from "./ClusterError.ts"
37
+ import type {
38
+ AlreadyProcessingMessage,
39
+ EntityNotAssignedToRunner,
40
+ MailboxFull,
41
+ PersistenceError
42
+ } from "./ClusterError.ts"
38
43
  import { Persisted, ShardGroup, Uninterruptible } from "./ClusterSchema.ts"
39
44
  import { EntityAddress } from "./EntityAddress.ts"
40
45
  import type { EntityId } from "./EntityId.ts"
@@ -117,7 +122,7 @@ export interface Entity<
117
122
  entityId: string
118
123
  ) => RpcClient.RpcClient.From<
119
124
  Rpcs,
120
- MailboxFull | AlreadyProcessingMessage | PersistenceError
125
+ MailboxFull | AlreadyProcessingMessage | PersistenceError | EntityNotAssignedToRunner
121
126
  >,
122
127
  never,
123
128
  Sharding