effect 4.0.0-beta.101 → 4.0.0-beta.102

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 (494) hide show
  1. package/dist/Array.d.ts.map +1 -1
  2. package/dist/Array.js +81 -5
  3. package/dist/Array.js.map +1 -1
  4. package/dist/Channel.d.ts.map +1 -1
  5. package/dist/Channel.js +27 -9
  6. package/dist/Channel.js.map +1 -1
  7. package/dist/Config.d.ts +1 -1
  8. package/dist/Config.d.ts.map +1 -1
  9. package/dist/Config.js +6 -5
  10. package/dist/Config.js.map +1 -1
  11. package/dist/ConfigProvider.js +7 -7
  12. package/dist/ConfigProvider.js.map +1 -1
  13. package/dist/Data.d.ts.map +1 -1
  14. package/dist/Data.js +2 -1
  15. package/dist/Data.js.map +1 -1
  16. package/dist/Effect.d.ts +61 -100
  17. package/dist/Effect.d.ts.map +1 -1
  18. package/dist/Effect.js +66 -39
  19. package/dist/Effect.js.map +1 -1
  20. package/dist/FiberHandle.d.ts.map +1 -1
  21. package/dist/FiberHandle.js +3 -2
  22. package/dist/FiberHandle.js.map +1 -1
  23. package/dist/Iterable.d.ts.map +1 -1
  24. package/dist/Iterable.js +2 -1
  25. package/dist/Iterable.js.map +1 -1
  26. package/dist/JsonPatch.d.ts.map +1 -1
  27. package/dist/JsonPatch.js +4 -3
  28. package/dist/JsonPatch.js.map +1 -1
  29. package/dist/JsonSchema.d.ts.map +1 -1
  30. package/dist/JsonSchema.js +9 -11
  31. package/dist/JsonSchema.js.map +1 -1
  32. package/dist/Logger.d.ts.map +1 -1
  33. package/dist/Logger.js +3 -2
  34. package/dist/Logger.js.map +1 -1
  35. package/dist/ManagedRuntime.d.ts +9 -0
  36. package/dist/ManagedRuntime.d.ts.map +1 -1
  37. package/dist/ManagedRuntime.js +3 -0
  38. package/dist/ManagedRuntime.js.map +1 -1
  39. package/dist/Metric.d.ts.map +1 -1
  40. package/dist/Metric.js +4 -3
  41. package/dist/Metric.js.map +1 -1
  42. package/dist/Optic.d.ts.map +1 -1
  43. package/dist/Optic.js +5 -4
  44. package/dist/Optic.js.map +1 -1
  45. package/dist/Option.d.ts.map +1 -1
  46. package/dist/Option.js +2 -1
  47. package/dist/Option.js.map +1 -1
  48. package/dist/PartitionedSemaphore.d.ts.map +1 -1
  49. package/dist/PartitionedSemaphore.js +1 -4
  50. package/dist/PartitionedSemaphore.js.map +1 -1
  51. package/dist/Record.d.ts +93 -1
  52. package/dist/Record.d.ts.map +1 -1
  53. package/dist/Record.js +57 -19
  54. package/dist/Record.js.map +1 -1
  55. package/dist/References.d.ts +0 -45
  56. package/dist/References.d.ts.map +1 -1
  57. package/dist/References.js +0 -45
  58. package/dist/References.js.map +1 -1
  59. package/dist/Request.d.ts.map +1 -1
  60. package/dist/Request.js +9 -6
  61. package/dist/Request.js.map +1 -1
  62. package/dist/Result.d.ts.map +1 -1
  63. package/dist/Result.js +2 -1
  64. package/dist/Result.js.map +1 -1
  65. package/dist/Schema.d.ts +1268 -495
  66. package/dist/Schema.d.ts.map +1 -1
  67. package/dist/Schema.js +2308 -614
  68. package/dist/Schema.js.map +1 -1
  69. package/dist/SchemaAST.d.ts +2 -2
  70. package/dist/SchemaAST.d.ts.map +1 -1
  71. package/dist/SchemaAST.js +189 -130
  72. package/dist/SchemaAST.js.map +1 -1
  73. package/dist/SchemaError.js +1 -1
  74. package/dist/SchemaError.js.map +1 -1
  75. package/dist/SchemaGetter.d.ts +13 -11
  76. package/dist/SchemaGetter.d.ts.map +1 -1
  77. package/dist/SchemaGetter.js +34 -24
  78. package/dist/SchemaGetter.js.map +1 -1
  79. package/dist/SchemaIssue.js +1 -1
  80. package/dist/SchemaIssue.js.map +1 -1
  81. package/dist/SchemaParser.d.ts.map +1 -1
  82. package/dist/SchemaParser.js +1 -12
  83. package/dist/SchemaParser.js.map +1 -1
  84. package/dist/SchemaRepresentation.d.ts +403 -1504
  85. package/dist/SchemaRepresentation.d.ts.map +1 -1
  86. package/dist/SchemaRepresentation.js +294 -2852
  87. package/dist/SchemaRepresentation.js.map +1 -1
  88. package/dist/SchemaTransformation.d.ts +2 -2
  89. package/dist/SchemaTransformation.js +3 -3
  90. package/dist/SchemaTransformation.js.map +1 -1
  91. package/dist/Semaphore.d.ts +5 -3
  92. package/dist/Semaphore.d.ts.map +1 -1
  93. package/dist/Semaphore.js.map +1 -1
  94. package/dist/Stream.d.ts +15 -9
  95. package/dist/Stream.d.ts.map +1 -1
  96. package/dist/Stream.js +46 -16
  97. package/dist/Stream.js.map +1 -1
  98. package/dist/Struct.d.ts.map +1 -1
  99. package/dist/Struct.js +5 -4
  100. package/dist/Struct.js.map +1 -1
  101. package/dist/Types.d.ts +1 -3
  102. package/dist/Types.d.ts.map +1 -1
  103. package/dist/index.d.ts +0 -4
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +0 -4
  106. package/dist/index.js.map +1 -1
  107. package/dist/internal/core.js +2 -1
  108. package/dist/internal/core.js.map +1 -1
  109. package/dist/internal/effect.js +64 -21
  110. package/dist/internal/effect.js.map +1 -1
  111. package/dist/internal/matcher.js +1 -1
  112. package/dist/internal/matcher.js.map +1 -1
  113. package/dist/internal/record.d.ts +0 -3
  114. package/dist/internal/record.d.ts.map +1 -1
  115. package/dist/internal/record.js +10 -5
  116. package/dist/internal/record.js.map +1 -1
  117. package/dist/internal/references.js +0 -4
  118. package/dist/internal/references.js.map +1 -1
  119. package/dist/internal/schema/annotations.js +12 -0
  120. package/dist/internal/schema/annotations.js.map +1 -1
  121. package/dist/internal/schema/fromJsonSchemaDocument.d.ts +2 -0
  122. package/dist/internal/schema/fromJsonSchemaDocument.d.ts.map +1 -0
  123. package/dist/internal/schema/fromJsonSchemaDocument.js +743 -0
  124. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -0
  125. package/dist/internal/schema/fromRepresentation.d.ts +2 -0
  126. package/dist/internal/schema/fromRepresentation.d.ts.map +1 -0
  127. package/dist/internal/schema/fromRepresentation.js +252 -0
  128. package/dist/internal/schema/fromRepresentation.js.map +1 -0
  129. package/dist/internal/schema/schema.js +28 -40
  130. package/dist/internal/schema/schema.js.map +1 -1
  131. package/dist/internal/schema/{arbitrary.d.ts → toArbitrary.d.ts} +1 -1
  132. package/dist/internal/schema/toArbitrary.d.ts.map +1 -0
  133. package/dist/internal/schema/{arbitrary.js → toArbitrary.js} +8 -9
  134. package/dist/internal/schema/toArbitrary.js.map +1 -0
  135. package/dist/internal/schema/toCodeDocument.d.ts +2 -0
  136. package/dist/internal/schema/toCodeDocument.d.ts.map +1 -0
  137. package/dist/internal/schema/toCodeDocument.js +438 -0
  138. package/dist/internal/schema/toCodeDocument.js.map +1 -0
  139. package/dist/internal/schema/toEquivalence.d.ts +2 -0
  140. package/dist/internal/schema/toEquivalence.d.ts.map +1 -0
  141. package/dist/internal/schema/{equivalence.js → toEquivalence.js} +15 -13
  142. package/dist/internal/schema/toEquivalence.js.map +1 -0
  143. package/dist/internal/schema/toJsonSchemaDocument.d.ts +2 -0
  144. package/dist/internal/schema/toJsonSchemaDocument.d.ts.map +1 -0
  145. package/dist/internal/schema/toJsonSchemaDocument.js +466 -0
  146. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -0
  147. package/dist/internal/schema/toRepresentation.d.ts +2 -0
  148. package/dist/internal/schema/toRepresentation.d.ts.map +1 -0
  149. package/dist/internal/schema/toRepresentation.js +369 -0
  150. package/dist/internal/schema/toRepresentation.js.map +1 -0
  151. package/dist/internal/stackTraceLimit.js +3 -6
  152. package/dist/internal/stackTraceLimit.js.map +1 -1
  153. package/dist/testing/TestClock.js +4 -1
  154. package/dist/testing/TestClock.js.map +1 -1
  155. package/dist/unstable/ai/AiError.d.ts +26 -26
  156. package/dist/unstable/ai/AiError.d.ts.map +1 -1
  157. package/dist/unstable/ai/AiError.js +5 -4
  158. package/dist/unstable/ai/AiError.js.map +1 -1
  159. package/dist/unstable/ai/AnthropicStructuredOutput.d.ts +21 -6
  160. package/dist/unstable/ai/AnthropicStructuredOutput.d.ts.map +1 -1
  161. package/dist/unstable/ai/AnthropicStructuredOutput.js +86 -316
  162. package/dist/unstable/ai/AnthropicStructuredOutput.js.map +1 -1
  163. package/dist/unstable/ai/EmbeddingModel.d.ts +1 -1
  164. package/dist/unstable/ai/EmbeddingModel.js +1 -1
  165. package/dist/unstable/ai/EmbeddingModel.js.map +1 -1
  166. package/dist/unstable/ai/LanguageModel.d.ts +4 -1
  167. package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
  168. package/dist/unstable/ai/LanguageModel.js +19 -17
  169. package/dist/unstable/ai/LanguageModel.js.map +1 -1
  170. package/dist/unstable/ai/McpSchema.d.ts +197 -197
  171. package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
  172. package/dist/unstable/ai/McpSchema.js +13 -13
  173. package/dist/unstable/ai/McpSchema.js.map +1 -1
  174. package/dist/unstable/ai/McpServer.d.ts +4 -4
  175. package/dist/unstable/ai/McpServer.d.ts.map +1 -1
  176. package/dist/unstable/ai/McpServer.js +116 -49
  177. package/dist/unstable/ai/McpServer.js.map +1 -1
  178. package/dist/unstable/ai/OpenAiStructuredOutput.d.ts +32 -10
  179. package/dist/unstable/ai/OpenAiStructuredOutput.d.ts.map +1 -1
  180. package/dist/unstable/ai/OpenAiStructuredOutput.js +193 -377
  181. package/dist/unstable/ai/OpenAiStructuredOutput.js.map +1 -1
  182. package/dist/unstable/ai/Response.d.ts +19 -19
  183. package/dist/unstable/ai/Response.d.ts.map +1 -1
  184. package/dist/unstable/ai/Response.js +14 -14
  185. package/dist/unstable/ai/Response.js.map +1 -1
  186. package/dist/unstable/ai/Tool.d.ts +4 -0
  187. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  188. package/dist/unstable/ai/Tool.js +11 -3
  189. package/dist/unstable/ai/Tool.js.map +1 -1
  190. package/dist/unstable/ai/Toolkit.d.ts +9 -1
  191. package/dist/unstable/ai/Toolkit.d.ts.map +1 -1
  192. package/dist/unstable/ai/Toolkit.js +14 -10
  193. package/dist/unstable/ai/Toolkit.js.map +1 -1
  194. package/dist/unstable/ai/internal/codec-transformer.js +15 -12
  195. package/dist/unstable/ai/internal/codec-transformer.js.map +1 -1
  196. package/dist/unstable/ai/internal/structured-output.d.ts +2 -0
  197. package/dist/unstable/ai/internal/structured-output.d.ts.map +1 -0
  198. package/dist/unstable/ai/internal/structured-output.js +316 -0
  199. package/dist/unstable/ai/internal/structured-output.js.map +1 -0
  200. package/dist/unstable/cli/CliError.d.ts +40 -2
  201. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  202. package/dist/unstable/cli/CliError.js +45 -6
  203. package/dist/unstable/cli/CliError.js.map +1 -1
  204. package/dist/unstable/cli/Command.js +14 -5
  205. package/dist/unstable/cli/Command.js.map +1 -1
  206. package/dist/unstable/cli/Param.js +3 -3
  207. package/dist/unstable/cli/Param.js.map +1 -1
  208. package/dist/unstable/cli/Primitive.js +1 -1
  209. package/dist/unstable/cli/Primitive.js.map +1 -1
  210. package/dist/unstable/cli/internal/command.d.ts +3 -1
  211. package/dist/unstable/cli/internal/command.d.ts.map +1 -1
  212. package/dist/unstable/cli/internal/command.js +11 -4
  213. package/dist/unstable/cli/internal/command.js.map +1 -1
  214. package/dist/unstable/cli/internal/config.d.ts +0 -48
  215. package/dist/unstable/cli/internal/config.d.ts.map +1 -1
  216. package/dist/unstable/cli/internal/config.js +8 -10
  217. package/dist/unstable/cli/internal/config.js.map +1 -1
  218. package/dist/unstable/cluster/ClusterWorkflowEngine.js +1 -1
  219. package/dist/unstable/cluster/ClusterWorkflowEngine.js.map +1 -1
  220. package/dist/unstable/cluster/Entity.js +1 -1
  221. package/dist/unstable/cluster/Entity.js.map +1 -1
  222. package/dist/unstable/cluster/Envelope.d.ts.map +1 -1
  223. package/dist/unstable/cluster/Envelope.js +2 -1
  224. package/dist/unstable/cluster/Envelope.js.map +1 -1
  225. package/dist/unstable/cluster/Reply.js +1 -1
  226. package/dist/unstable/cluster/Reply.js.map +1 -1
  227. package/dist/unstable/cluster/Runner.d.ts +1 -1
  228. package/dist/unstable/cluster/Runner.js +1 -1
  229. package/dist/unstable/cluster/Runner.js.map +1 -1
  230. package/dist/unstable/cluster/RunnerAddress.d.ts +1 -1
  231. package/dist/unstable/cluster/RunnerAddress.js +1 -1
  232. package/dist/unstable/cluster/RunnerAddress.js.map +1 -1
  233. package/dist/unstable/cluster/ShardId.js +1 -1
  234. package/dist/unstable/cluster/ShardId.js.map +1 -1
  235. package/dist/unstable/cluster/Sharding.d.ts.map +1 -1
  236. package/dist/unstable/cluster/Sharding.js +125 -24
  237. package/dist/unstable/cluster/Sharding.js.map +1 -1
  238. package/dist/unstable/cluster/ShardingConfig.d.ts +10 -2
  239. package/dist/unstable/cluster/ShardingConfig.d.ts.map +1 -1
  240. package/dist/unstable/cluster/ShardingConfig.js.map +1 -1
  241. package/dist/unstable/cluster/SingleRunner.d.ts +4 -2
  242. package/dist/unstable/cluster/SingleRunner.d.ts.map +1 -1
  243. package/dist/unstable/cluster/SingleRunner.js +2 -1
  244. package/dist/unstable/cluster/SingleRunner.js.map +1 -1
  245. package/dist/unstable/cluster/SqlMessageStorage.d.ts +7 -4
  246. package/dist/unstable/cluster/SqlMessageStorage.d.ts.map +1 -1
  247. package/dist/unstable/cluster/SqlMessageStorage.js +55 -24
  248. package/dist/unstable/cluster/SqlMessageStorage.js.map +1 -1
  249. package/dist/unstable/cluster/SqlRunnerStorage.d.ts.map +1 -1
  250. package/dist/unstable/cluster/SqlRunnerStorage.js +109 -62
  251. package/dist/unstable/cluster/SqlRunnerStorage.js.map +1 -1
  252. package/dist/unstable/cluster/internal/entityManager.js +19 -7
  253. package/dist/unstable/cluster/internal/entityManager.js.map +1 -1
  254. package/dist/unstable/cluster/internal/shardLock.d.ts +2 -0
  255. package/dist/unstable/cluster/internal/shardLock.d.ts.map +1 -0
  256. package/dist/unstable/cluster/internal/shardLock.js +4 -0
  257. package/dist/unstable/cluster/internal/shardLock.js.map +1 -0
  258. package/dist/unstable/devtools/DevToolsSchema.d.ts +20 -20
  259. package/dist/unstable/devtools/DevToolsSchema.d.ts.map +1 -1
  260. package/dist/unstable/devtools/DevToolsSchema.js +8 -5
  261. package/dist/unstable/devtools/DevToolsSchema.js.map +1 -1
  262. package/dist/unstable/eventlog/EventJournal.d.ts +1 -1
  263. package/dist/unstable/eventlog/EventJournal.js +1 -1
  264. package/dist/unstable/eventlog/EventJournal.js.map +1 -1
  265. package/dist/unstable/eventlog/EventLog.d.ts.map +1 -1
  266. package/dist/unstable/eventlog/EventLog.js +15 -11
  267. package/dist/unstable/eventlog/EventLog.js.map +1 -1
  268. package/dist/unstable/eventlog/EventLogEncryption.d.ts +1 -1
  269. package/dist/unstable/eventlog/EventLogEncryption.js +1 -1
  270. package/dist/unstable/eventlog/EventLogEncryption.js.map +1 -1
  271. package/dist/unstable/eventlog/EventLogMessage.d.ts +4 -4
  272. package/dist/unstable/eventlog/EventLogMessage.d.ts.map +1 -1
  273. package/dist/unstable/eventlog/EventLogMessage.js +8 -3
  274. package/dist/unstable/eventlog/EventLogMessage.js.map +1 -1
  275. package/dist/unstable/eventlog/EventLogRemote.d.ts +1 -1
  276. package/dist/unstable/eventlog/SqlEventJournal.js +2 -2
  277. package/dist/unstable/eventlog/SqlEventJournal.js.map +1 -1
  278. package/dist/unstable/eventlog/SqlEventLogServerEncrypted.js +1 -1
  279. package/dist/unstable/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
  280. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.js +3 -3
  281. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
  282. package/dist/unstable/http/Cookies.d.ts.map +1 -1
  283. package/dist/unstable/http/Cookies.js +24 -22
  284. package/dist/unstable/http/Cookies.js.map +1 -1
  285. package/dist/unstable/http/Headers.js +8 -8
  286. package/dist/unstable/http/Headers.js.map +1 -1
  287. package/dist/unstable/http/HttpClientRequest.d.ts +44 -0
  288. package/dist/unstable/http/HttpClientRequest.d.ts.map +1 -1
  289. package/dist/unstable/http/HttpClientRequest.js +14 -0
  290. package/dist/unstable/http/HttpClientRequest.js.map +1 -1
  291. package/dist/unstable/http/HttpServerRequest.d.ts.map +1 -1
  292. package/dist/unstable/http/HttpServerRequest.js +5 -4
  293. package/dist/unstable/http/HttpServerRequest.js.map +1 -1
  294. package/dist/unstable/http/Multipart.d.ts.map +1 -1
  295. package/dist/unstable/http/Multipart.js +17 -15
  296. package/dist/unstable/http/Multipart.js.map +1 -1
  297. package/dist/unstable/http/Template.js +1 -1
  298. package/dist/unstable/http/Template.js.map +1 -1
  299. package/dist/unstable/http/UrlParams.d.ts.map +1 -1
  300. package/dist/unstable/http/UrlParams.js +17 -14
  301. package/dist/unstable/http/UrlParams.js.map +1 -1
  302. package/dist/unstable/httpapi/HttpApi.js +3 -3
  303. package/dist/unstable/httpapi/HttpApi.js.map +1 -1
  304. package/dist/unstable/httpapi/HttpApiClient.js +5 -5
  305. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  306. package/dist/unstable/httpapi/HttpApiGroup.js +1 -1
  307. package/dist/unstable/httpapi/HttpApiGroup.js.map +1 -1
  308. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  309. package/dist/unstable/httpapi/OpenApi.js +37 -24
  310. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  311. package/dist/unstable/observability/OtlpExporter.d.ts +72 -1
  312. package/dist/unstable/observability/OtlpExporter.d.ts.map +1 -1
  313. package/dist/unstable/observability/OtlpExporter.js +69 -4
  314. package/dist/unstable/observability/OtlpExporter.js.map +1 -1
  315. package/dist/unstable/observability/OtlpLogger.d.ts +4 -3
  316. package/dist/unstable/observability/OtlpLogger.d.ts.map +1 -1
  317. package/dist/unstable/observability/OtlpLogger.js +2 -2
  318. package/dist/unstable/observability/OtlpLogger.js.map +1 -1
  319. package/dist/unstable/observability/OtlpMetrics.d.ts +7 -3
  320. package/dist/unstable/observability/OtlpMetrics.d.ts.map +1 -1
  321. package/dist/unstable/observability/OtlpMetrics.js +5 -2
  322. package/dist/unstable/observability/OtlpMetrics.js.map +1 -1
  323. package/dist/unstable/observability/OtlpTracer.d.ts +4 -3
  324. package/dist/unstable/observability/OtlpTracer.d.ts.map +1 -1
  325. package/dist/unstable/observability/OtlpTracer.js +2 -2
  326. package/dist/unstable/observability/OtlpTracer.js.map +1 -1
  327. package/dist/unstable/persistence/Persistable.d.ts.map +1 -1
  328. package/dist/unstable/persistence/Persistable.js +2 -1
  329. package/dist/unstable/persistence/Persistable.js.map +1 -1
  330. package/dist/unstable/persistence/RateLimiter.d.ts +2 -2
  331. package/dist/unstable/persistence/RateLimiter.js +2 -2
  332. package/dist/unstable/persistence/RateLimiter.js.map +1 -1
  333. package/dist/unstable/persistence/Redis.d.ts.map +1 -1
  334. package/dist/unstable/persistence/Redis.js +2 -2
  335. package/dist/unstable/persistence/Redis.js.map +1 -1
  336. package/dist/unstable/process/ChildProcessSpawner.js +3 -1
  337. package/dist/unstable/process/ChildProcessSpawner.js.map +1 -1
  338. package/dist/unstable/reactivity/AsyncResult.d.ts.map +1 -1
  339. package/dist/unstable/reactivity/AsyncResult.js +4 -3
  340. package/dist/unstable/reactivity/AsyncResult.js.map +1 -1
  341. package/dist/unstable/reactivity/Atom.d.ts +83 -0
  342. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  343. package/dist/unstable/reactivity/Atom.js +31 -0
  344. package/dist/unstable/reactivity/Atom.js.map +1 -1
  345. package/dist/unstable/reactivity/AtomRegistry.js +1 -1
  346. package/dist/unstable/reactivity/AtomRegistry.js.map +1 -1
  347. package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
  348. package/dist/unstable/rpc/RpcClient.js +2 -1
  349. package/dist/unstable/rpc/RpcClient.js.map +1 -1
  350. package/dist/unstable/schema/VariantSchema.d.ts +1 -2
  351. package/dist/unstable/schema/VariantSchema.d.ts.map +1 -1
  352. package/dist/unstable/schema/VariantSchema.js +13 -10
  353. package/dist/unstable/schema/VariantSchema.js.map +1 -1
  354. package/dist/unstable/socket/Socket.d.ts +1 -1
  355. package/dist/unstable/socket/Socket.js +1 -1
  356. package/dist/unstable/socket/Socket.js.map +1 -1
  357. package/dist/unstable/sql/SqlError.d.ts +2 -2
  358. package/dist/unstable/sql/SqlError.js +2 -2
  359. package/dist/unstable/sql/SqlError.js.map +1 -1
  360. package/dist/unstable/sql/Statement.d.ts.map +1 -1
  361. package/dist/unstable/sql/Statement.js +7 -6
  362. package/dist/unstable/sql/Statement.js.map +1 -1
  363. package/package.json +1 -1
  364. package/src/Array.ts +86 -25
  365. package/src/Channel.ts +32 -14
  366. package/src/Config.ts +6 -5
  367. package/src/ConfigProvider.ts +7 -7
  368. package/src/Data.ts +3 -2
  369. package/src/Effect.ts +70 -116
  370. package/src/FiberHandle.ts +3 -2
  371. package/src/Iterable.ts +2 -1
  372. package/src/JsonPatch.ts +4 -3
  373. package/src/JsonSchema.ts +9 -11
  374. package/src/Logger.ts +3 -2
  375. package/src/ManagedRuntime.ts +13 -0
  376. package/src/Metric.ts +4 -3
  377. package/src/Optic.ts +5 -4
  378. package/src/Option.ts +2 -1
  379. package/src/PartitionedSemaphore.ts +1 -4
  380. package/src/Record.ts +119 -22
  381. package/src/References.ts +0 -46
  382. package/src/Request.ts +5 -7
  383. package/src/Result.ts +2 -1
  384. package/src/Schema.ts +2537 -986
  385. package/src/SchemaAST.ts +228 -149
  386. package/src/SchemaError.ts +1 -1
  387. package/src/SchemaGetter.ts +36 -29
  388. package/src/SchemaIssue.ts +1 -1
  389. package/src/SchemaParser.ts +1 -25
  390. package/src/SchemaRepresentation.ts +697 -3398
  391. package/src/SchemaTransformation.ts +3 -3
  392. package/src/Semaphore.ts +5 -3
  393. package/src/Stream.ts +63 -19
  394. package/src/Struct.ts +5 -4
  395. package/src/Types.ts +1 -3
  396. package/src/index.ts +0 -5
  397. package/src/internal/core.ts +3 -2
  398. package/src/internal/effect.ts +67 -31
  399. package/src/internal/matcher.ts +1 -1
  400. package/src/internal/record.ts +11 -7
  401. package/src/internal/references.ts +0 -5
  402. package/src/internal/schema/annotations.ts +44 -0
  403. package/src/internal/schema/fromJsonSchemaDocument.ts +957 -0
  404. package/src/internal/schema/fromRepresentation.ts +345 -0
  405. package/src/internal/schema/schema.ts +45 -46
  406. package/src/internal/schema/{arbitrary.ts → toArbitrary.ts} +8 -10
  407. package/src/internal/schema/toCodeDocument.ts +572 -0
  408. package/src/internal/schema/{equivalence.ts → toEquivalence.ts} +12 -7
  409. package/src/internal/schema/toJsonSchemaDocument.ts +475 -0
  410. package/src/internal/schema/toRepresentation.ts +401 -0
  411. package/src/internal/stackTraceLimit.ts +3 -7
  412. package/src/testing/TestClock.ts +1 -1
  413. package/src/unstable/ai/AiError.ts +5 -4
  414. package/src/unstable/ai/AnthropicStructuredOutput.ts +102 -333
  415. package/src/unstable/ai/EmbeddingModel.ts +1 -1
  416. package/src/unstable/ai/LanguageModel.ts +30 -28
  417. package/src/unstable/ai/McpSchema.ts +15 -15
  418. package/src/unstable/ai/McpServer.ts +172 -56
  419. package/src/unstable/ai/OpenAiStructuredOutput.ts +230 -395
  420. package/src/unstable/ai/Response.ts +24 -24
  421. package/src/unstable/ai/Tool.ts +22 -4
  422. package/src/unstable/ai/Toolkit.ts +19 -7
  423. package/src/unstable/ai/internal/codec-transformer.ts +13 -7
  424. package/src/unstable/ai/internal/structured-output.ts +458 -0
  425. package/src/unstable/cli/CliError.ts +51 -5
  426. package/src/unstable/cli/Command.ts +4 -4
  427. package/src/unstable/cli/Param.ts +3 -3
  428. package/src/unstable/cli/Primitive.ts +1 -1
  429. package/src/unstable/cli/internal/command.ts +13 -5
  430. package/src/unstable/cli/internal/config.ts +8 -10
  431. package/src/unstable/cluster/ClusterWorkflowEngine.ts +3 -3
  432. package/src/unstable/cluster/Entity.ts +1 -1
  433. package/src/unstable/cluster/Envelope.ts +2 -1
  434. package/src/unstable/cluster/Reply.ts +1 -1
  435. package/src/unstable/cluster/Runner.ts +1 -1
  436. package/src/unstable/cluster/RunnerAddress.ts +1 -1
  437. package/src/unstable/cluster/ShardId.ts +1 -1
  438. package/src/unstable/cluster/Sharding.ts +161 -34
  439. package/src/unstable/cluster/ShardingConfig.ts +5 -1
  440. package/src/unstable/cluster/SingleRunner.ts +4 -2
  441. package/src/unstable/cluster/SqlMessageStorage.ts +83 -35
  442. package/src/unstable/cluster/SqlRunnerStorage.ts +186 -116
  443. package/src/unstable/cluster/internal/entityManager.ts +31 -10
  444. package/src/unstable/cluster/internal/shardLock.ts +9 -0
  445. package/src/unstable/devtools/DevToolsSchema.ts +10 -5
  446. package/src/unstable/eventlog/EventJournal.ts +1 -1
  447. package/src/unstable/eventlog/EventLog.ts +21 -11
  448. package/src/unstable/eventlog/EventLogEncryption.ts +1 -1
  449. package/src/unstable/eventlog/EventLogMessage.ts +10 -3
  450. package/src/unstable/eventlog/SqlEventJournal.ts +2 -2
  451. package/src/unstable/eventlog/SqlEventLogServerEncrypted.ts +1 -1
  452. package/src/unstable/eventlog/SqlEventLogServerUnencrypted.ts +6 -3
  453. package/src/unstable/http/Cookies.ts +29 -24
  454. package/src/unstable/http/Headers.ts +8 -8
  455. package/src/unstable/http/HttpClientRequest.ts +57 -0
  456. package/src/unstable/http/HttpServerRequest.ts +5 -4
  457. package/src/unstable/http/Multipart.ts +16 -13
  458. package/src/unstable/http/Template.ts +1 -1
  459. package/src/unstable/http/UrlParams.ts +17 -14
  460. package/src/unstable/httpapi/HttpApi.ts +3 -3
  461. package/src/unstable/httpapi/HttpApiClient.ts +5 -5
  462. package/src/unstable/httpapi/HttpApiGroup.ts +1 -1
  463. package/src/unstable/httpapi/OpenApi.ts +52 -28
  464. package/src/unstable/observability/OtlpExporter.ts +109 -5
  465. package/src/unstable/observability/OtlpLogger.ts +5 -5
  466. package/src/unstable/observability/OtlpMetrics.ts +8 -4
  467. package/src/unstable/observability/OtlpTracer.ts +8 -4
  468. package/src/unstable/persistence/Persistable.ts +3 -2
  469. package/src/unstable/persistence/RateLimiter.ts +2 -2
  470. package/src/unstable/persistence/Redis.ts +2 -2
  471. package/src/unstable/process/ChildProcessSpawner.ts +1 -1
  472. package/src/unstable/reactivity/AsyncResult.ts +4 -3
  473. package/src/unstable/reactivity/Atom.ts +92 -0
  474. package/src/unstable/reactivity/AtomRegistry.ts +1 -1
  475. package/src/unstable/rpc/RpcClient.ts +2 -1
  476. package/src/unstable/schema/VariantSchema.ts +14 -24
  477. package/src/unstable/socket/Socket.ts +1 -1
  478. package/src/unstable/sql/SqlError.ts +2 -2
  479. package/src/unstable/sql/Statement.ts +7 -6
  480. package/dist/SchemaUtils.d.ts +0 -28
  481. package/dist/SchemaUtils.d.ts.map +0 -1
  482. package/dist/SchemaUtils.js +0 -45
  483. package/dist/SchemaUtils.js.map +0 -1
  484. package/dist/internal/schema/arbitrary.d.ts.map +0 -1
  485. package/dist/internal/schema/arbitrary.js.map +0 -1
  486. package/dist/internal/schema/equivalence.d.ts +0 -2
  487. package/dist/internal/schema/equivalence.d.ts.map +0 -1
  488. package/dist/internal/schema/equivalence.js.map +0 -1
  489. package/dist/internal/schema/representation.d.ts +0 -2
  490. package/dist/internal/schema/representation.d.ts.map +0 -1
  491. package/dist/internal/schema/representation.js +0 -865
  492. package/dist/internal/schema/representation.js.map +0 -1
  493. package/src/SchemaUtils.ts +0 -51
  494. package/src/internal/schema/representation.ts +0 -795
@@ -4,21 +4,15 @@
4
4
  * OpenAI structured output accepts only a subset of JSON Schema. This module
5
5
  * converts an Effect `Schema.Codec` into a provider-compatible JSON Schema and
6
6
  * a matching codec for decoding the model response back into the original
7
- * application type. When possible, unsupported schema shapes are rewritten into
8
- * supported ones; schema kinds that cannot be represented safely fail during
9
- * conversion.
7
+ * application type. Unsupported constraints can be omitted from the provider
8
+ * schema and remain enforced by the returned codec.
10
9
  *
11
10
  * @since 4.0.0
12
11
  */
13
- import * as Arr from "../../Array.ts"
14
12
  import * as JsonSchema from "../../JsonSchema.ts"
15
- import * as Option from "../../Option.ts"
16
- import * as Predicate from "../../Predicate.ts"
17
13
  import * as Rec from "../../Record.ts"
18
14
  import * as Schema from "../../Schema.ts"
19
- import * as SchemaAST from "../../SchemaAST.ts"
20
- import * as SchemaTransformation from "../../SchemaTransformation.ts"
21
- import * as Tool from "./Tool.ts"
15
+ import * as InternalStructuredOutput from "./internal/structured-output.ts"
22
16
 
23
17
  /**
24
18
  * Converts a `Schema.Codec` to OpenAI structured-output JSON Schema and a
@@ -27,25 +21,36 @@ import * as Tool from "./Tool.ts"
27
21
  * **When to use**
28
22
  *
29
23
  * Use when you send Effect Schema-backed structured output requests to OpenAI
30
- * and need provider-compatible JSON Schema without losing the decoded
31
- * application type.
24
+ * standard models and need provider-compatible JSON Schema without losing the
25
+ * decoded application type.
32
26
  *
33
27
  * **Details**
34
28
  *
35
29
  * Returns the JSON Schema to include in the request and the codec to use when
36
- * decoding the model response. If the input schema already fits OpenAI's
37
- * supported JSON Schema subset, the original codec is returned unchanged.
30
+ * decoding the model response. The codec remains authoritative: the provider
31
+ * JSON Schema can be a lossy, less restrictive representation when OpenAI
32
+ * cannot express an Effect Schema constraint. Conversion throws when the
33
+ * resulting root is not an object or contains `anyOf`.
38
34
  *
39
35
  * **Gotchas**
40
36
  *
41
37
  * - Some schemas use a provider-safe encoded shape: tuples become objects with
42
- * numeric string keys, records become arrays of `[key, value]` pairs, and
43
- * optional properties become required nullable properties.
38
+ * numeric string keys, objects with index signatures become arrays of
39
+ * `[key, value]` pairs, and optional properties become required nullable
40
+ * properties.
44
41
  * - `oneOf` unions are emitted as `anyOf` unions.
45
- * - Regex patterns from multiple filters are merged into one `pattern` because
46
- * OpenAI structured output does not support `allOf`.
47
- * - Unsupported schema kinds throw during conversion instead of producing a
48
- * lossy schema.
42
+ * - Compatible regex patterns are merged because OpenAI structured output does
43
+ * not support `allOf`.
44
+ * - The root JSON Schema must be an object and cannot use `anyOf`.
45
+ * - Constraints inside `allOf` are retained only when they have an explicit,
46
+ * semantics-preserving normalization rule.
47
+ * - Structural constraints inside `allOf`, such as `properties`, `required`,
48
+ * `additionalProperties`, and `items`, are omitted instead of being merged
49
+ * with a different meaning.
50
+ * - Unsupported constraints are removed from the provider schema and are still
51
+ * checked while decoding with the returned codec.
52
+ * - Compatibility targets standard OpenAI models. Fine-tuned models support a
53
+ * smaller JSON Schema subset.
49
54
  *
50
55
  * @category Codec Transformation
51
56
  * @since 4.0.0
@@ -56,421 +61,251 @@ export function toCodecOpenAI<T, E, RD, RE>(
56
61
  codec: Schema.ConstraintCodec<T, unknown, RD, RE>
57
62
  jsonSchema: JsonSchema.JsonSchema
58
63
  } {
59
- const to = schema.ast
60
- const from = recurOpenAI(SchemaAST.toEncoded(to))
61
- const codec = from === to
62
- ? schema
63
- : Schema.make<typeof schema>(SchemaAST.decodeTo(from, to, SchemaTransformation.passthrough()))
64
- const document = JsonSchema.resolveTopLevel$ref(Schema.toJsonSchemaDocument(codec))
64
+ const codec = InternalStructuredOutput.toCodec(schema)
65
+ const document = JsonSchema.resolveTopLevel$ref(
66
+ Schema.toJsonSchemaDocument(codec, { generateDescriptions: true })
67
+ )
65
68
  const jsonSchema = rewriteOpenAI(document.schema)
69
+ if (jsonSchema.type !== "object" || jsonSchema.anyOf !== undefined) {
70
+ throw new Error(
71
+ `OpenAiStructuredOutput: Root JSON Schema must have type "object" and must not use "anyOf"`
72
+ )
73
+ }
66
74
  if (Object.keys(document.definitions).length > 0) {
67
75
  jsonSchema.$defs = Rec.map(document.definitions, rewriteOpenAI)
68
76
  }
69
77
  return { codec, jsonSchema }
70
78
  }
71
79
 
72
- /**
73
- * Post-processes the JSON schema produced by `Schema.toJsonSchemaDocument`,
74
- * recursively flattening `allOf` arrays by merging each member's keys into
75
- * the parent object. This is necessary because OpenAI structured output does
76
- * not support `allOf`.
77
- */
78
80
  function rewriteOpenAI(schema: JsonSchema.JsonSchema): JsonSchema.JsonSchema {
79
- const out: JsonSchema.JsonSchema = {}
80
- for (const [k, v] of Object.entries(schema)) {
81
- if (k === "allOf" && Array.isArray(v)) {
82
- for (const member of v) {
83
- Object.assign(out, rewriteOpenAI(member as JsonSchema.JsonSchema))
81
+ return InternalStructuredOutput.walkJsonSchema(schema, (schema) => {
82
+ const normalized = normalizeAllOf(schema)
83
+ const out: JsonSchema.JsonSchema = {}
84
+ let unsupportedFormat: string | undefined
85
+ for (const [key, value] of Object.entries(normalized)) {
86
+ if (key === "format") {
87
+ if (typeof value === "string" && formats.has(value) && supportsType(key, normalized.type)) out.format = value
88
+ else if (typeof value === "string") unsupportedFormat = value
89
+ } else if (supportedKeywords.has(key) && supportsType(key, normalized.type)) {
90
+ if (key !== "additionalProperties" || value === false) out[key] = value
84
91
  }
85
- } else if (Array.isArray(v)) {
86
- out[k] = v.map((item) =>
87
- typeof item === "object" && item !== null && !Array.isArray(item)
88
- ? rewriteOpenAI(item as JsonSchema.JsonSchema)
89
- : item
90
- )
91
- } else if (typeof v === "object" && v !== null) {
92
- out[k] = rewriteOpenAI(v as JsonSchema.JsonSchema)
93
- } else {
94
- out[k] = v
95
92
  }
93
+ if (unsupportedFormat !== undefined) {
94
+ InternalStructuredOutput.appendDescription(out, `a value with a format of ${unsupportedFormat}`)
95
+ }
96
+ if (out.type === "object" && out.properties === undefined && out.additionalProperties === false) {
97
+ out.properties = {}
98
+ }
99
+ return out
100
+ })
101
+ }
102
+
103
+ function supportsType(key: string, type: unknown): boolean {
104
+ if (typeof type !== "string") return true
105
+ switch (key) {
106
+ case "pattern":
107
+ case "format":
108
+ return type === "string"
109
+ case "multipleOf":
110
+ case "minimum":
111
+ case "exclusiveMinimum":
112
+ case "maximum":
113
+ case "exclusiveMaximum":
114
+ return type === "number" || type === "integer"
115
+ case "items":
116
+ case "minItems":
117
+ case "maxItems":
118
+ return type === "array"
119
+ case "properties":
120
+ case "patternProperties":
121
+ case "required":
122
+ case "additionalProperties":
123
+ return type === "object"
124
+ default:
125
+ return true
96
126
  }
97
- if (out.type === "object" && out.properties === undefined && out.additionalProperties === false) {
98
- out.properties = {}
127
+ }
128
+
129
+ function normalizeAllOf(schema: JsonSchema.JsonSchema): JsonSchema.JsonSchema {
130
+ if (!Array.isArray(schema.allOf)) return schema
131
+
132
+ const out: JsonSchema.JsonSchema = {}
133
+ const patterns: Array<string> = []
134
+ const baseKeywords = new Set<string>()
135
+ const memberKeywords = new Set<string>()
136
+ const ambiguousKeywords = new Set<string>()
137
+ for (const [key, value] of Object.entries(schema)) {
138
+ if (key === "allOf") continue
139
+ baseKeywords.add(key)
140
+ if (key === "pattern" && typeof value === "string") patterns.push(value)
141
+ else out[key] = value
142
+ }
143
+ for (const member of schema.allOf) {
144
+ if (!InternalStructuredOutput.isJsonSchema(member)) continue
145
+ for (const [key, value] of Object.entries(member)) {
146
+ mergeAllOfKeyword(out, key, value, patterns, baseKeywords, memberKeywords, ambiguousKeywords)
147
+ }
148
+ }
149
+ const uniquePatterns = Array.from(new Set(patterns))
150
+ if (uniquePatterns.length === 1) {
151
+ out.pattern = uniquePatterns[0]
152
+ } else if (uniquePatterns.length > 1) {
153
+ const combined = uniquePatterns.map((source) => `(?=[\\s\\S]*?(?:${source}))`).join("")
154
+ out.pattern = `^${combined}`
99
155
  }
100
156
  return out
101
157
  }
102
158
 
103
- function recurOpenAI(ast: SchemaAST.AST): SchemaAST.AST {
104
- switch (ast._tag) {
105
- case "Declaration":
106
- case "Void":
107
- case "Never":
108
- case "Unknown":
109
- case "Any":
110
- case "BigInt":
111
- case "Symbol":
112
- case "UniqueSymbol":
113
- case "ObjectKeyword":
114
- case "Enum":
115
- case "TemplateLiteral":
116
- return unsupportedAst(
117
- ast,
118
- "OpenAI structured output does not support this schema kind; consider transforming the schema or using a different provider"
119
- )
120
- case "Undefined":
121
- return unsupportedAst(
122
- ast,
123
- "OpenAI structured output does not support undefined; consider transforming the schema or using a different provider; if using `Schema.optional`, consider using `Schema.optionalKey` instead"
124
- )
125
- case "Null":
126
- return ast
127
- case "String": {
128
- const { annotations, filters } = get(ast)
129
- if (annotations !== undefined || filters !== undefined) {
130
- return new SchemaAST.String(annotations, filters)
131
- }
132
- return ast
133
- }
134
- case "Number": {
135
- const { annotations, filters } = get(ast)
136
- if (annotations !== undefined || filters !== undefined) {
137
- return new SchemaAST.Number(annotations, filters)
138
- }
139
- return ast
140
- }
141
- case "Boolean":
142
- return ast
143
- case "Literal": {
144
- const literal = ast.literal
145
- if (typeof literal === "string" || typeof literal === "number" || typeof literal === "boolean") {
146
- const { annotations, filters } = get(ast)
147
- if (annotations !== undefined || filters !== undefined) {
148
- return new SchemaAST.Literal(ast.literal, annotations, filters)
149
- }
150
- return ast
151
- }
152
- throw new Error(
153
- `${errorPrefix}: Unsupported literal type ${typeof literal} (value: ${
154
- String(literal)
155
- }) (supported: string | number | boolean)`
156
- )
157
- }
158
- case "Union": {
159
- if (ast.mode === "oneOf") {
160
- return new SchemaAST.Union(ast.types, "anyOf", ast.annotations, ast.checks)
159
+ function mergeAllOfKeyword(
160
+ out: JsonSchema.JsonSchema,
161
+ key: string,
162
+ value: unknown,
163
+ patterns: Array<string>,
164
+ baseKeywords: ReadonlySet<string>,
165
+ memberKeywords: Set<string>,
166
+ ambiguousKeywords: Set<string>
167
+ ): void {
168
+ switch (key) {
169
+ case "description":
170
+ if (typeof value === "string") InternalStructuredOutput.appendDescription(out, value)
171
+ return
172
+ case "pattern":
173
+ if (typeof value === "string") patterns.push(value)
174
+ return
175
+ case "minimum":
176
+ case "exclusiveMinimum":
177
+ mergeLowerBound(out, key, value)
178
+ return
179
+ case "maximum":
180
+ case "exclusiveMaximum":
181
+ mergeUpperBound(out, key, value)
182
+ return
183
+ case "minItems":
184
+ mergeMinimum(out, key, value)
185
+ return
186
+ case "maxItems":
187
+ mergeMaximum(out, key, value)
188
+ return
189
+ default:
190
+ if (!normalizableAllOfKeywords.has(key) || baseKeywords.has(key) || ambiguousKeywords.has(key)) return
191
+ if (!memberKeywords.has(key)) {
192
+ out[key] = value
193
+ memberKeywords.add(key)
194
+ } else if (out[key] !== value) {
195
+ delete out[key]
196
+ memberKeywords.delete(key)
197
+ ambiguousKeywords.add(key)
161
198
  }
162
- const types = SchemaAST.mapOrSame(ast.types, recurOpenAI)
163
- const { annotations, filters } = get(ast)
164
- if (types !== ast.types || annotations !== undefined || filters !== undefined) {
165
- return new SchemaAST.Union(types, "anyOf", annotations, filters)
166
- }
167
- return ast
168
- }
169
- case "Arrays": {
170
- if (ast.rest.length > 1) {
171
- throw new Error(
172
- `${errorPrefix}: Post-rest elements are not supported for arrays (rest length: ${ast.rest.length})`
173
- )
174
- }
175
- let { annotations, filters } = get(ast)
176
- if (ast.elements.length > 0) {
177
- // tuples are not supported by OpenAI, we translate them to objects with string keys
178
- if (annotations !== undefined && typeof annotations.description === "string") {
179
- annotations.description = `${TUPLE_DESCRIPTION}; ${annotations.description}`
180
- } else {
181
- annotations ??= {}
182
- annotations.description = TUPLE_DESCRIPTION
183
- }
184
- const propertySignatures = ast.elements.map((e, i) => {
185
- return new SchemaAST.PropertySignature(String(i), e)
186
- })
187
- if (ast.rest.length === 1) {
188
- propertySignatures.push(
189
- new SchemaAST.PropertySignature(REST_PROPERTY_NAME, new SchemaAST.Arrays(false, [], ast.rest))
190
- )
191
- }
192
- return SchemaAST.decodeTo(
193
- recurOpenAI(new SchemaAST.Objects(propertySignatures, [], annotations, filters)),
194
- ast,
195
- SchemaTransformation.transform({
196
- decode: (o) => {
197
- let t: Array<unknown> = []
198
- for (let i = 0; i < ast.elements.length; i++) {
199
- const k = String(i)
200
- if (o[k] !== undefined) {
201
- t.push(o[k])
202
- }
203
- }
204
- if (REST_PROPERTY_NAME in o) {
205
- t = [...t, ...o[REST_PROPERTY_NAME]]
206
- }
207
- return t
208
- },
209
- encode: (t) => {
210
- const o: Record<string, unknown> = {}
211
- for (let i = 0; i < ast.elements.length; i++) {
212
- if (t.length >= i) {
213
- o[String(i)] = t[i]
214
- }
215
- }
216
- if (ast.rest.length === 1) {
217
- o[REST_PROPERTY_NAME] = t.length >= ast.elements.length ? t.slice(ast.elements.length) : []
218
- }
219
- return o
220
- }
221
- })
222
- )
223
- } else {
224
- const rest = SchemaAST.mapOrSame(ast.rest, recurOpenAI)
225
- if (rest !== ast.rest || annotations !== undefined || filters !== undefined) {
226
- return new SchemaAST.Arrays(false, [], rest, annotations, filters)
227
- }
228
- return ast
229
- }
230
- }
231
- case "Objects": {
232
- let { annotations, filters } = get(ast)
233
- if (ast.indexSignatures.length === 0) {
234
- const propertySignatures = SchemaAST.mapOrSame(ast.propertySignatures, (ps) => {
235
- if (typeof ps.name !== "string") {
236
- throw new Error(
237
- `${errorPrefix}: Property names must be strings (got ${typeof ps.name})`
238
- )
239
- }
240
- let type = recurOpenAI(ps.type)
241
- // optional properties are not supported by OpenAI, so we translate them to nullable unions
242
- if (SchemaAST.isOptional(ps.type)) {
243
- type = SchemaAST.decodeTo(
244
- new SchemaAST.Union([type, SchemaAST.null], "anyOf"),
245
- SchemaAST.optionalKey(type),
246
- SchemaTransformation.transformOptional({
247
- decode: Option.filter(Predicate.isNotNull),
248
- encode: Option.orElseSome(() => null)
249
- })
250
- )
251
- }
252
- if (type === ps.type) {
253
- return ps
254
- }
255
- return new SchemaAST.PropertySignature(ps.name, type)
256
- })
257
- if (
258
- propertySignatures !== ast.propertySignatures || annotations !== undefined || filters !== undefined
259
- ) {
260
- return new SchemaAST.Objects(propertySignatures, [], annotations, filters)
261
- }
262
- } else if (ast.indexSignatures.length === 1 && ast.propertySignatures.length === 0) {
263
- const is = ast.indexSignatures[0]
264
- if (Tool.isEmptyParamsRecord(is)) {
265
- return ast
266
- }
267
- // records are not supported by OpenAI, so we translate them to arrays of key-value pairs
268
- if (annotations !== undefined && typeof annotations.description === "string") {
269
- annotations.description = `${RECORD_DESCRIPTION}; ${annotations.description}`
270
- } else {
271
- annotations ??= {}
272
- annotations.description = RECORD_DESCRIPTION
273
- }
274
- return SchemaAST.decodeTo(
275
- recurOpenAI(
276
- new SchemaAST.Arrays(false, [], [new SchemaAST.Arrays(false, [is.parameter, is.type], [])], annotations)
277
- ),
278
- ast,
279
- SchemaTransformation.transform({
280
- decode: Object.fromEntries,
281
- encode: Object.entries
282
- })
283
- )
284
- } else {
285
- throw new Error(
286
- `${errorPrefix}: unsupported object schema shape (properties: ${ast.propertySignatures.length}, indexSignatures: ${ast.indexSignatures.length}). Supported: plain objects (properties only) or records (single index signature, no properties)`
287
- )
288
- }
289
- return ast
290
- }
291
- case "Suspend": {
292
- const cached = cache.get(ast)
293
- if (cached) return cached
294
- const { annotations } = get(ast)
295
- const out = new SchemaAST.Suspend(() => recurOpenAI(ast.thunk()), annotations)
296
- cache.set(ast, out)
297
- return out
298
- }
199
+ return
299
200
  }
300
201
  }
301
202
 
302
- const cache = new Map<SchemaAST.AST, SchemaAST.AST>()
303
-
304
- const errorPrefix = "OpenAiStructuredOutput"
305
-
306
- function unsupportedAst(ast: SchemaAST.AST, details?: string): never {
307
- const base = `Unsupported AST ${ast._tag}`
308
- const full = `${errorPrefix}: ${base}`
309
- throw new Error(details !== undefined ? `${full} (${details})` : full)
203
+ function mergeMinimum(schema: JsonSchema.JsonSchema, key: string, value: unknown): void {
204
+ if (typeof value !== "number") return
205
+ const current = schema[key]
206
+ if (typeof current !== "number" || value > current) schema[key] = value
310
207
  }
311
208
 
312
- const REST_PROPERTY_NAME = "__rest__"
313
-
314
- const RECORD_DESCRIPTION =
315
- "Object encoded as array of [key, value] pairs. Apply object constraints to the decoded object"
316
-
317
- const TUPLE_DESCRIPTION =
318
- "Tuple encoded as an object with numeric string keys ('0', '1', ...). If present, '__rest__' contains remaining elements"
319
-
320
- type Annotation =
321
- | { readonly _tag: "description"; readonly description: string }
322
- | { readonly _tag: "format"; readonly format: string }
323
-
324
- type Filter =
325
- | Annotation
326
- | { readonly _tag: "filter"; readonly filter: SchemaAST.Filter<any> }
327
- | { readonly _tag: "regex"; readonly source: string }
209
+ function mergeMaximum(schema: JsonSchema.JsonSchema, key: string, value: unknown): void {
210
+ if (typeof value !== "number") return
211
+ const current = schema[key]
212
+ if (typeof current !== "number" || value < current) schema[key] = value
213
+ }
328
214
 
329
- const get = (ast: SchemaAST.AST): {
330
- annotations: Record<string, string> | undefined
331
- filters: [SchemaAST.Check<any>, ...SchemaAST.Check<any>[]] | undefined
332
- } => {
333
- const annotations: Record<string, string> = {}
334
- const filters: Array<SchemaAST.Filter<any>> = []
335
- const regexSources: Array<string> = []
336
- const checks = getChecks(ast, SchemaAST.isArrays(ast))
337
- if (checks.length > 0) {
338
- for (const check of checks) {
339
- switch (check._tag) {
340
- case "description": {
341
- if (annotations.description !== undefined) {
342
- annotations.description += ` and ${check.description}`
343
- } else {
344
- annotations.description = check.description
345
- }
346
- break
347
- }
348
- case "format": {
349
- annotations.format = check.format
350
- break
351
- }
352
- case "filter": {
353
- filters.push(check.filter)
354
- break
355
- }
356
- case "regex": {
357
- regexSources.push(check.source)
358
- break
359
- }
360
- }
361
- }
215
+ function mergeLowerBound(schema: JsonSchema.JsonSchema, key: string, value: unknown): void {
216
+ if (typeof value !== "number") {
217
+ if (!Object.hasOwn(schema, key)) schema[key] = value
218
+ return
362
219
  }
363
- // OpenAI does not support allOf, so we merge multiple regex patterns into a single isPattern filter
364
- if (regexSources.length === 1) {
365
- filters.push(SchemaAST.isPattern(new RegExp(regexSources[0])))
366
- } else if (regexSources.length > 1) {
367
- const combined = regexSources.map((s) => `(?=[\\s\\S]*?(?:${s}))`).join("")
368
- filters.push(SchemaAST.isPattern(new RegExp(`^${combined}`)))
220
+ const minimum = typeof schema.minimum === "number" ? schema.minimum : undefined
221
+ const exclusiveMinimum = typeof schema.exclusiveMinimum === "number" ? schema.exclusiveMinimum : undefined
222
+ let current: { readonly value: number; readonly exclusive: boolean } | undefined
223
+ if (minimum !== undefined) current = { value: minimum, exclusive: false }
224
+ if (
225
+ exclusiveMinimum !== undefined &&
226
+ (current === undefined || exclusiveMinimum >= current.value)
227
+ ) {
228
+ current = { value: exclusiveMinimum, exclusive: true }
369
229
  }
370
- return {
371
- annotations: Object.keys(annotations).length > 0 ? annotations : undefined,
372
- filters: Arr.isArrayNonEmpty(filters) ? filters : undefined
230
+ const candidate = { value, exclusive: key === "exclusiveMinimum" }
231
+ if (
232
+ current === undefined ||
233
+ candidate.value > current.value ||
234
+ (candidate.value === current.value && candidate.exclusive)
235
+ ) {
236
+ current = candidate
373
237
  }
238
+ delete schema.minimum
239
+ delete schema.exclusiveMinimum
240
+ schema[current.exclusive ? "exclusiveMinimum" : "minimum"] = current.value
374
241
  }
375
242
 
376
- const getChecks = (ast: SchemaAST.AST, isArray: boolean): Array<Filter> => [
377
- ...(ast.checks !== undefined ? getFilters(ast.checks, isArray) : []),
378
- ...getAnnotations(ast.annotations)
379
- ]
380
-
381
- const getAnnotations = (annotations: Schema.Annotations.Filter | undefined): Array<Annotation> => {
382
- const out: Array<Annotation> = []
383
- if (annotations !== undefined) {
384
- const description = annotations?.description
385
- ?? (annotations.meta?._tag === "isInt" || annotations.meta?._tag === "isFinite"
386
- ? undefined
387
- : annotations?.expected)
388
- if (typeof description === "string") {
389
- out.push({ _tag: "description", description })
390
- }
391
- const format = annotations?.format
392
- if (typeof format === "string") {
393
- if (formats.includes(format)) {
394
- out.push({ _tag: "format", format })
395
- } else {
396
- out.push({ _tag: "description", description: `a value with a format of ${format}` })
397
- }
398
- }
243
+ function mergeUpperBound(schema: JsonSchema.JsonSchema, key: string, value: unknown): void {
244
+ if (typeof value !== "number") {
245
+ if (!Object.hasOwn(schema, key)) schema[key] = value
246
+ return
399
247
  }
400
- return out
401
- }
402
-
403
- function getFilter(filter: SchemaAST.Filter<any>, isArray: boolean): Array<Filter> {
404
- let out: Array<Filter> = []
405
- const annotations = getAnnotations(filter.annotations)
406
- const meta = filter.annotations?.meta
407
- if (meta !== undefined) {
408
- switch (meta._tag) {
409
- case "isMinLength":
410
- case "isMaxLength":
411
- case "isLengthBetween": {
412
- out = out.concat(annotations)
413
- if (isArray) {
414
- out.push({ _tag: "filter", filter: resetFilter(filter) })
415
- }
416
- break
417
- }
418
- case "isInt":
419
- case "isFinite":
420
- case "isGreaterThan":
421
- case "isGreaterThanOrEqualTo":
422
- case "isLessThan":
423
- case "isLessThanOrEqualTo":
424
- case "isBetween":
425
- case "isMultipleOf": {
426
- out = out.concat(annotations)
427
- out.push({ _tag: "filter", filter: resetFilter(filter) })
428
- break
429
- }
430
- default: {
431
- out = out.concat(annotations)
432
- break
433
- }
434
- }
435
- if ("regExp" in meta && meta.regExp instanceof RegExp) {
436
- out.push({ _tag: "regex", source: meta.regExp.source })
437
- }
248
+ const maximum = typeof schema.maximum === "number" ? schema.maximum : undefined
249
+ const exclusiveMaximum = typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : undefined
250
+ let current: { readonly value: number; readonly exclusive: boolean } | undefined
251
+ if (maximum !== undefined) current = { value: maximum, exclusive: false }
252
+ if (
253
+ exclusiveMaximum !== undefined &&
254
+ (current === undefined || exclusiveMaximum <= current.value)
255
+ ) {
256
+ current = { value: exclusiveMaximum, exclusive: true }
438
257
  }
439
- return out
258
+ const candidate = { value, exclusive: key === "exclusiveMaximum" }
259
+ if (
260
+ current === undefined ||
261
+ candidate.value < current.value ||
262
+ (candidate.value === current.value && candidate.exclusive)
263
+ ) {
264
+ current = candidate
265
+ }
266
+ delete schema.maximum
267
+ delete schema.exclusiveMaximum
268
+ schema[current.exclusive ? "exclusiveMaximum" : "maximum"] = current.value
440
269
  }
441
270
 
442
- function resetFilter(filter: SchemaAST.Filter<any>): SchemaAST.Filter<any> {
443
- return filter.annotate({
444
- description: undefined,
445
- expected: undefined,
446
- title: undefined,
447
- format: undefined
448
- })
449
- }
271
+ const supportedKeywords = new Set([
272
+ "$ref",
273
+ "type",
274
+ "title",
275
+ "description",
276
+ "enum",
277
+ "anyOf",
278
+ "properties",
279
+ "required",
280
+ "additionalProperties",
281
+ "items",
282
+ "pattern",
283
+ "multipleOf",
284
+ "minimum",
285
+ "exclusiveMinimum",
286
+ "maximum",
287
+ "exclusiveMaximum",
288
+ "minItems",
289
+ "maxItems"
290
+ ])
450
291
 
451
- function getFilters(
452
- checks: readonly [SchemaAST.Check<any>, ...SchemaAST.Check<any>[]],
453
- isArray: boolean
454
- ): Array<Filter> {
455
- return checks.flatMap((check) => {
456
- switch (check._tag) {
457
- case "Filter":
458
- return getFilter(check, isArray)
459
- case "FilterGroup":
460
- return getFilters(check.checks, isArray)
461
- }
462
- })
463
- }
292
+ const normalizableAllOfKeywords = new Set([
293
+ "$ref",
294
+ "title",
295
+ "enum",
296
+ "anyOf",
297
+ "format",
298
+ "multipleOf"
299
+ ])
464
300
 
465
- const formats = [
301
+ const formats = new Set([
466
302
  "date-time",
467
303
  "time",
468
304
  "date",
469
305
  "duration",
470
306
  "email",
471
307
  "hostname",
472
- "uri",
473
308
  "ipv4",
474
309
  "ipv6",
475
310
  "uuid"
476
- ]
311
+ ])