effect 4.0.4 → 4.0.5

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 (308) hide show
  1. package/ai-docs/src/52_graphql/10_basics.ts +19 -13
  2. package/ai-docs/src/52_graphql/30_batching.ts +6 -4
  3. package/ai-docs/src/52_graphql/40_aliased-batching.ts +6 -4
  4. package/dist/Array.d.ts +90 -6
  5. package/dist/Array.d.ts.map +1 -1
  6. package/dist/Array.js +4 -2
  7. package/dist/Array.js.map +1 -1
  8. package/dist/Channel.d.ts +6 -1
  9. package/dist/Channel.d.ts.map +1 -1
  10. package/dist/Channel.js +17 -3
  11. package/dist/Channel.js.map +1 -1
  12. package/dist/ConfigProvider.d.ts.map +1 -1
  13. package/dist/ConfigProvider.js +33 -32
  14. package/dist/ConfigProvider.js.map +1 -1
  15. package/dist/Duration.d.ts.map +1 -1
  16. package/dist/Duration.js +2 -5
  17. package/dist/Duration.js.map +1 -1
  18. package/dist/Effect.d.ts +61 -19
  19. package/dist/Effect.d.ts.map +1 -1
  20. package/dist/Effect.js +58 -39
  21. package/dist/Effect.js.map +1 -1
  22. package/dist/FileSystem.d.ts +23 -9
  23. package/dist/FileSystem.d.ts.map +1 -1
  24. package/dist/FileSystem.js.map +1 -1
  25. package/dist/Match.d.ts +20 -6
  26. package/dist/Match.d.ts.map +1 -1
  27. package/dist/Match.js +2 -2
  28. package/dist/Match.js.map +1 -1
  29. package/dist/Path.d.ts +37 -5
  30. package/dist/Path.d.ts.map +1 -1
  31. package/dist/Path.js +36 -5
  32. package/dist/Path.js.map +1 -1
  33. package/dist/Schema.d.ts +7 -2
  34. package/dist/Schema.d.ts.map +1 -1
  35. package/dist/Schema.js +9 -2
  36. package/dist/Schema.js.map +1 -1
  37. package/dist/String.d.ts +12 -0
  38. package/dist/String.d.ts.map +1 -1
  39. package/dist/String.js +17 -4
  40. package/dist/String.js.map +1 -1
  41. package/dist/TxRef.d.ts.map +1 -1
  42. package/dist/TxRef.js +3 -2
  43. package/dist/TxRef.js.map +1 -1
  44. package/dist/ai/AiError.d.ts +10 -10
  45. package/dist/ai/AiError.d.ts.map +1 -1
  46. package/dist/ai/AiError.js +1 -1
  47. package/dist/ai/AiError.js.map +1 -1
  48. package/dist/ai/Decision.d.ts +70 -19
  49. package/dist/ai/Decision.d.ts.map +1 -1
  50. package/dist/ai/Decision.js +37 -3
  51. package/dist/ai/Decision.js.map +1 -1
  52. package/dist/ai/DecisionModel.js +1 -1
  53. package/dist/ai/DecisionModel.js.map +1 -1
  54. package/dist/ai/LanguageModel.d.ts.map +1 -1
  55. package/dist/ai/LanguageModel.js +47 -35
  56. package/dist/ai/LanguageModel.js.map +1 -1
  57. package/dist/ai/McpServer.d.ts +6 -52
  58. package/dist/ai/McpServer.d.ts.map +1 -1
  59. package/dist/ai/McpServer.js +2 -28
  60. package/dist/ai/McpServer.js.map +1 -1
  61. package/dist/ai/Response.d.ts +1 -1
  62. package/dist/cli/Completions.d.ts +5 -0
  63. package/dist/cli/Completions.d.ts.map +1 -1
  64. package/dist/cli/Completions.js.map +1 -1
  65. package/dist/cli/Flag.d.ts +100 -0
  66. package/dist/cli/Flag.d.ts.map +1 -1
  67. package/dist/cli/Flag.js +33 -0
  68. package/dist/cli/Flag.js.map +1 -1
  69. package/dist/cli/Param.d.ts +87 -0
  70. package/dist/cli/Param.d.ts.map +1 -1
  71. package/dist/cli/Param.js +30 -0
  72. package/dist/cli/Param.js.map +1 -1
  73. package/dist/cli/internal/command.d.ts.map +1 -1
  74. package/dist/cli/internal/command.js +2 -1
  75. package/dist/cli/internal/command.js.map +1 -1
  76. package/dist/cli/internal/completions/bash.js +4 -3
  77. package/dist/cli/internal/completions/bash.js.map +1 -1
  78. package/dist/cli/internal/completions/descriptor.js +8 -1
  79. package/dist/cli/internal/completions/descriptor.js.map +1 -1
  80. package/dist/cli/internal/completions/fish.js +4 -4
  81. package/dist/cli/internal/completions/fish.js.map +1 -1
  82. package/dist/cli/internal/completions/powershell.js +3 -2
  83. package/dist/cli/internal/completions/powershell.js.map +1 -1
  84. package/dist/cli/internal/completions/zsh.js +7 -3
  85. package/dist/cli/internal/completions/zsh.js.map +1 -1
  86. package/dist/cli/internal/parser.js +11 -3
  87. package/dist/cli/internal/parser.js.map +1 -1
  88. package/dist/cli/internal/wizard.d.ts.map +1 -1
  89. package/dist/cli/internal/wizard.js +2 -1
  90. package/dist/cli/internal/wizard.js.map +1 -1
  91. package/dist/cluster/ClusterWorkflowEngine.d.ts +1 -0
  92. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  93. package/dist/cluster/ClusterWorkflowEngine.js +67 -13
  94. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  95. package/dist/cluster/MessageStorage.d.ts.map +1 -1
  96. package/dist/cluster/MessageStorage.js +20 -12
  97. package/dist/cluster/MessageStorage.js.map +1 -1
  98. package/dist/cluster/Runners.d.ts.map +1 -1
  99. package/dist/cluster/Runners.js +54 -34
  100. package/dist/cluster/Runners.js.map +1 -1
  101. package/dist/cluster/internal/entityManager.js +1 -1
  102. package/dist/cluster/internal/entityManager.js.map +1 -1
  103. package/dist/encoding/Sse.js +1 -1
  104. package/dist/encoding/Sse.js.map +1 -1
  105. package/dist/graphql/GraphQLClient.d.ts.map +1 -1
  106. package/dist/graphql/GraphQLClient.js +12 -5
  107. package/dist/graphql/GraphQLClient.js.map +1 -1
  108. package/dist/graphql/GraphQLProtocol.d.ts +249 -11
  109. package/dist/graphql/GraphQLProtocol.d.ts.map +1 -1
  110. package/dist/graphql/GraphQLProtocol.js +98 -8
  111. package/dist/graphql/GraphQLProtocol.js.map +1 -1
  112. package/dist/graphql/GraphQLResolver.d.ts +1 -1
  113. package/dist/graphql/GraphQLResolver.d.ts.map +1 -1
  114. package/dist/graphql/GraphQLResolver.js +46 -16
  115. package/dist/graphql/GraphQLResolver.js.map +1 -1
  116. package/dist/http/FetchHttpClient.d.ts +6 -3
  117. package/dist/http/FetchHttpClient.d.ts.map +1 -1
  118. package/dist/http/FetchHttpClient.js +6 -3
  119. package/dist/http/FetchHttpClient.js.map +1 -1
  120. package/dist/http/FindMyWay/internal/router.js +2 -1
  121. package/dist/http/FindMyWay/internal/router.js.map +1 -1
  122. package/dist/http/Headers.d.ts +3 -3
  123. package/dist/http/Headers.d.ts.map +1 -1
  124. package/dist/http/Headers.js +6 -5
  125. package/dist/http/Headers.js.map +1 -1
  126. package/dist/http/HttpClient.d.ts +12 -0
  127. package/dist/http/HttpClient.d.ts.map +1 -1
  128. package/dist/http/HttpClient.js +14 -1
  129. package/dist/http/HttpClient.js.map +1 -1
  130. package/dist/http/HttpClientError.d.ts.map +1 -1
  131. package/dist/http/HttpClientError.js +8 -6
  132. package/dist/http/HttpClientError.js.map +1 -1
  133. package/dist/http/HttpClientRequest.d.ts +147 -4
  134. package/dist/http/HttpClientRequest.d.ts.map +1 -1
  135. package/dist/http/HttpClientRequest.js +47 -1
  136. package/dist/http/HttpClientRequest.js.map +1 -1
  137. package/dist/http/HttpMiddleware.d.ts +60 -0
  138. package/dist/http/HttpMiddleware.d.ts.map +1 -1
  139. package/dist/http/HttpMiddleware.js +67 -5
  140. package/dist/http/HttpMiddleware.js.map +1 -1
  141. package/dist/http/HttpRouter.d.ts.map +1 -1
  142. package/dist/http/HttpRouter.js +52 -13
  143. package/dist/http/HttpRouter.js.map +1 -1
  144. package/dist/http/HttpServerError.d.ts.map +1 -1
  145. package/dist/http/HttpServerError.js +6 -4
  146. package/dist/http/HttpServerError.js.map +1 -1
  147. package/dist/http/HttpServerRequest.js +2 -2
  148. package/dist/http/HttpServerRequest.js.map +1 -1
  149. package/dist/http/HttpStaticServer.d.ts.map +1 -1
  150. package/dist/http/HttpStaticServer.js +4 -10
  151. package/dist/http/HttpStaticServer.js.map +1 -1
  152. package/dist/http/HttpTraceContext.js +1 -1
  153. package/dist/http/HttpTraceContext.js.map +1 -1
  154. package/dist/http/Url.d.ts.map +1 -1
  155. package/dist/http/Url.js +2 -1
  156. package/dist/http/Url.js.map +1 -1
  157. package/dist/http/UrlParams.d.ts +112 -8
  158. package/dist/http/UrlParams.d.ts.map +1 -1
  159. package/dist/http/UrlParams.js +141 -14
  160. package/dist/http/UrlParams.js.map +1 -1
  161. package/dist/http/internal/compression.d.ts +1 -1
  162. package/dist/http/internal/compression.d.ts.map +1 -1
  163. package/dist/http/internal/compression.js +2 -10
  164. package/dist/http/internal/compression.js.map +1 -1
  165. package/dist/http/internal/compressionBody.d.ts +2 -0
  166. package/dist/http/internal/compressionBody.d.ts.map +1 -0
  167. package/dist/http/internal/compressionBody.js +36 -0
  168. package/dist/http/internal/compressionBody.js.map +1 -0
  169. package/dist/http/internal/decompression.d.ts +2 -0
  170. package/dist/http/internal/decompression.d.ts.map +1 -0
  171. package/dist/http/internal/decompression.js +162 -0
  172. package/dist/http/internal/decompression.js.map +1 -0
  173. package/dist/http/internal/tracing.js +14 -4
  174. package/dist/http/internal/tracing.js.map +1 -1
  175. package/dist/http/internal/urlParams.d.ts +2 -0
  176. package/dist/http/internal/urlParams.d.ts.map +1 -0
  177. package/dist/http/internal/urlParams.js +4 -0
  178. package/dist/http/internal/urlParams.js.map +1 -0
  179. package/dist/http-api/HttpApiClient.d.ts.map +1 -1
  180. package/dist/http-api/HttpApiClient.js +2 -1
  181. package/dist/http-api/HttpApiClient.js.map +1 -1
  182. package/dist/internal/core.js +17 -1
  183. package/dist/internal/core.js.map +1 -1
  184. package/dist/internal/effect.js +5 -3
  185. package/dist/internal/effect.js.map +1 -1
  186. package/dist/internal/graphql.js +12 -2
  187. package/dist/internal/graphql.js.map +1 -1
  188. package/dist/internal/version.js +1 -1
  189. package/dist/observability/Otlp.d.ts +15 -0
  190. package/dist/observability/Otlp.d.ts.map +1 -1
  191. package/dist/observability/Otlp.js +3 -0
  192. package/dist/observability/Otlp.js.map +1 -1
  193. package/dist/observability/OtlpExporter.d.ts +8 -0
  194. package/dist/observability/OtlpExporter.d.ts.map +1 -1
  195. package/dist/observability/OtlpExporter.js +10 -1
  196. package/dist/observability/OtlpExporter.js.map +1 -1
  197. package/dist/observability/OtlpLogger.d.ts +17 -0
  198. package/dist/observability/OtlpLogger.d.ts.map +1 -1
  199. package/dist/observability/OtlpLogger.js +14 -1
  200. package/dist/observability/OtlpLogger.js.map +1 -1
  201. package/dist/observability/OtlpMetrics.d.ts +17 -0
  202. package/dist/observability/OtlpMetrics.d.ts.map +1 -1
  203. package/dist/observability/OtlpMetrics.js +13 -0
  204. package/dist/observability/OtlpMetrics.js.map +1 -1
  205. package/dist/observability/OtlpTracer.d.ts +17 -0
  206. package/dist/observability/OtlpTracer.d.ts.map +1 -1
  207. package/dist/observability/OtlpTracer.js +15 -2
  208. package/dist/observability/OtlpTracer.js.map +1 -1
  209. package/dist/reactivity/AsyncResult.d.ts +6 -0
  210. package/dist/reactivity/AsyncResult.d.ts.map +1 -1
  211. package/dist/reactivity/AsyncResult.js +27 -0
  212. package/dist/reactivity/AsyncResult.js.map +1 -1
  213. package/dist/reactivity/AtomRegistry.js +3 -1
  214. package/dist/reactivity/AtomRegistry.js.map +1 -1
  215. package/dist/rpc/RpcClient.d.ts.map +1 -1
  216. package/dist/rpc/RpcClient.js +6 -1
  217. package/dist/rpc/RpcClient.js.map +1 -1
  218. package/dist/sql/SqlClient.d.ts +8 -7
  219. package/dist/sql/SqlClient.d.ts.map +1 -1
  220. package/dist/sql/SqlClient.js +8 -7
  221. package/dist/sql/SqlClient.js.map +1 -1
  222. package/dist/testing/TestClock.d.ts +16 -3
  223. package/dist/testing/TestClock.d.ts.map +1 -1
  224. package/dist/testing/TestClock.js +112 -22
  225. package/dist/testing/TestClock.js.map +1 -1
  226. package/dist/workflow/Activity.js +1 -0
  227. package/dist/workflow/Activity.js.map +1 -1
  228. package/dist/workflow/Workflow.d.ts +22 -0
  229. package/dist/workflow/Workflow.d.ts.map +1 -1
  230. package/dist/workflow/Workflow.js +15 -3
  231. package/dist/workflow/Workflow.js.map +1 -1
  232. package/dist/workflow/WorkflowEngine.d.ts +20 -1
  233. package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
  234. package/dist/workflow/WorkflowEngine.js +35 -21
  235. package/dist/workflow/WorkflowEngine.js.map +1 -1
  236. package/package.json +1 -1
  237. package/src/Array.ts +95 -6
  238. package/src/Channel.ts +24 -3
  239. package/src/ConfigProvider.ts +40 -44
  240. package/src/Duration.ts +4 -5
  241. package/src/Effect.ts +140 -53
  242. package/src/FileSystem.ts +23 -9
  243. package/src/Match.ts +65 -12
  244. package/src/Path.ts +52 -7
  245. package/src/Schema.ts +17 -4
  246. package/src/String.ts +17 -4
  247. package/src/TxRef.ts +4 -2
  248. package/src/ai/AiError.ts +3 -1
  249. package/src/ai/Decision.ts +70 -21
  250. package/src/ai/DecisionModel.ts +1 -1
  251. package/src/ai/LanguageModel.ts +57 -51
  252. package/src/ai/McpServer.ts +15 -55
  253. package/src/cli/Completions.ts +5 -0
  254. package/src/cli/Flag.ts +101 -0
  255. package/src/cli/Param.ts +96 -0
  256. package/src/cli/internal/command.ts +2 -1
  257. package/src/cli/internal/completions/bash.ts +4 -3
  258. package/src/cli/internal/completions/descriptor.ts +10 -1
  259. package/src/cli/internal/completions/fish.ts +4 -4
  260. package/src/cli/internal/completions/powershell.ts +5 -2
  261. package/src/cli/internal/completions/zsh.ts +7 -3
  262. package/src/cli/internal/parser.ts +12 -3
  263. package/src/cli/internal/wizard.ts +2 -1
  264. package/src/cluster/ClusterWorkflowEngine.ts +92 -24
  265. package/src/cluster/MessageStorage.ts +14 -3
  266. package/src/cluster/Runners.ts +88 -66
  267. package/src/cluster/internal/entityManager.ts +1 -1
  268. package/src/encoding/Sse.ts +1 -1
  269. package/src/graphql/GraphQLClient.ts +17 -5
  270. package/src/graphql/GraphQLProtocol.ts +274 -20
  271. package/src/graphql/GraphQLResolver.ts +45 -17
  272. package/src/http/FetchHttpClient.ts +6 -3
  273. package/src/http/FindMyWay/internal/router.ts +2 -1
  274. package/src/http/Headers.ts +6 -9
  275. package/src/http/HttpClient.ts +18 -1
  276. package/src/http/HttpClientError.ts +10 -6
  277. package/src/http/HttpClientRequest.ts +173 -7
  278. package/src/http/HttpMiddleware.ts +85 -5
  279. package/src/http/HttpRouter.ts +60 -13
  280. package/src/http/HttpServerError.ts +8 -4
  281. package/src/http/HttpServerRequest.ts +2 -2
  282. package/src/http/HttpStaticServer.ts +4 -10
  283. package/src/http/HttpTraceContext.ts +1 -1
  284. package/src/http/Url.ts +2 -1
  285. package/src/http/UrlParams.ts +225 -26
  286. package/src/http/internal/compression.ts +3 -17
  287. package/src/http/internal/compressionBody.ts +56 -0
  288. package/src/http/internal/decompression.ts +226 -0
  289. package/src/http/internal/tracing.ts +21 -4
  290. package/src/http/internal/urlParams.ts +5 -0
  291. package/src/http-api/HttpApiClient.ts +2 -1
  292. package/src/internal/core.ts +21 -1
  293. package/src/internal/effect.ts +5 -4
  294. package/src/internal/graphql.ts +30 -7
  295. package/src/internal/version.ts +1 -1
  296. package/src/observability/Otlp.ts +18 -0
  297. package/src/observability/OtlpExporter.ts +14 -3
  298. package/src/observability/OtlpLogger.ts +31 -2
  299. package/src/observability/OtlpMetrics.ts +30 -1
  300. package/src/observability/OtlpTracer.ts +32 -3
  301. package/src/reactivity/AsyncResult.ts +31 -0
  302. package/src/reactivity/AtomRegistry.ts +3 -1
  303. package/src/rpc/RpcClient.ts +6 -1
  304. package/src/sql/SqlClient.ts +9 -7
  305. package/src/testing/TestClock.ts +144 -29
  306. package/src/workflow/Activity.ts +1 -0
  307. package/src/workflow/Workflow.ts +31 -5
  308. package/src/workflow/WorkflowEngine.ts +60 -22
package/src/Match.ts CHANGED
@@ -712,6 +712,26 @@ export const withReturnType: <Ret>() => <I, F, R, A, Pr, _, Args extends Array<a
712
712
  ) => [Ret] extends [[A] extends [never] ? any : A] ? Matcher<I, F, R, A, Pr, Ret, Args>
713
713
  : "withReturnType constraint does not extend Result type" = internal.withReturnType
714
714
 
715
+ // `P` is a const type parameter, so object literals skip excess-property checks.
716
+ // Reject pattern keys that no object variant of the input has. Functions,
717
+ // refinements, and array patterns are not checked.
718
+ type PatternKey<K> = K extends number ? `${K}` : K
719
+
720
+ type PatternKeys<A> = object extends A ? PropertyKey
721
+ : A extends object ? PatternKey<keyof A>
722
+ : never
723
+
724
+ type ObjectPatternGuard<A, P> = [P] extends [Function | ReadonlyArray<any> | SafeRefinement<never, any>] ? unknown
725
+ : [P] extends [object] ? { readonly [K in Exclude<PatternKey<keyof P>, PatternKeys<A>>]: never }
726
+ : unknown
727
+
728
+ type ExactPattern<R, P> = (Types.PatternPrimitive<R> | Types.PatternBase<R>) & ObjectPatternGuard<R, P>
729
+
730
+ type ExactPatterns<R, P> = {
731
+ readonly [I in keyof P]: I extends number | `${number}` ? P[I] & ExactPattern<R, P[I]>
732
+ : P[I]
733
+ }
734
+
715
735
  /**
716
736
  * Defines a condition for matching values.
717
737
  *
@@ -763,7 +783,7 @@ export const withReturnType: <Ret>() => <I, F, R, A, Pr, _, Args extends Array<a
763
783
  */
764
784
  export const when: <
765
785
  R,
766
- const P extends Types.PatternPrimitive<R> | Types.PatternBase<R>,
786
+ const P extends ExactPattern<R, P>,
767
787
  Ret,
768
788
  Args extends Array<any>,
769
789
  Fn extends (_: Types.WhenMatch<R, P>, ...args: Args) => Ret
@@ -831,7 +851,7 @@ export const whenOr: <
831
851
  Args extends Array<any>,
832
852
  Fn extends (_: Types.WhenMatch<R, P[number]>, ...args: Args) => Ret
833
853
  >(
834
- ...args: [...patterns: P, f: Fn]
854
+ ...args: [...patterns: ExactPatterns<R, P>, f: Fn]
835
855
  ) => <I, F, A, Pr>(
836
856
  self: Matcher<I, F, R, A, Pr, Ret, Args>
837
857
  ) => Matcher<
@@ -842,7 +862,13 @@ export const whenOr: <
842
862
  Pr,
843
863
  Ret,
844
864
  Args
845
- > = internal.whenOr
865
+ > = <
866
+ R,
867
+ const P extends ReadonlyArray<Types.PatternPrimitive<R> | Types.PatternBase<R>>,
868
+ Ret,
869
+ Args extends Array<any>,
870
+ Fn extends (_: Types.WhenMatch<R, P[number]>, ...args: Args) => Ret
871
+ >(...args: [...patterns: ExactPatterns<R, P>, f: Fn]) => internal.whenOr<R, P, Ret, Args, Fn>(...args)
846
872
 
847
873
  /**
848
874
  * Matches a value that satisfies all provided patterns.
@@ -890,7 +916,7 @@ export const whenAnd: <
890
916
  Args extends Array<any>,
891
917
  Fn extends (_: Types.WhenMatch<R, T.UnionToIntersection<P[number]>>, ...args: Args) => Ret
892
918
  >(
893
- ...args: [...patterns: P, f: Fn]
919
+ ...args: [...patterns: ExactPatterns<R, P>, f: Fn]
894
920
  ) => <I, F, A, Pr>(
895
921
  self: Matcher<I, F, R, A, Pr, Ret, Args>
896
922
  ) => Matcher<
@@ -901,7 +927,13 @@ export const whenAnd: <
901
927
  Pr,
902
928
  Ret,
903
929
  Args
904
- > = internal.whenAnd
930
+ > = <
931
+ R,
932
+ const P extends ReadonlyArray<Types.PatternPrimitive<R> | Types.PatternBase<R>>,
933
+ Ret,
934
+ Args extends Array<any>,
935
+ Fn extends (_: Types.WhenMatch<R, T.UnionToIntersection<P[number]>>, ...args: Args) => Ret
936
+ >(...args: [...patterns: ExactPatterns<R, P>, f: Fn]) => internal.whenAnd<R, P, Ret, Args, Fn>(...args)
905
937
 
906
938
  /**
907
939
  * Matches values based on a specified discriminant field.
@@ -1398,7 +1430,7 @@ export const tagsExhaustive: <
1398
1430
  */
1399
1431
  export const not: <
1400
1432
  R,
1401
- const P extends Types.PatternPrimitive<R> | Types.PatternBase<R>,
1433
+ const P extends ExactPattern<R, P>,
1402
1434
  Ret,
1403
1435
  Args extends Array<any>,
1404
1436
  Fn extends (_: Types.NotMatch<R, P>, ...args: Args) => Ret
@@ -2835,6 +2867,32 @@ export declare namespace Types {
2835
2867
 
2836
2868
  type Simplify<A> = { [K in keyof A]: A[K] } & {}
2837
2869
 
2870
+ // Tuple patterns match a prefix at runtime. For inputs with a variadic part,
2871
+ // narrow each position the pattern requires and keep the rest of the input.
2872
+ type NarrowArrayPattern<I extends ReadonlyArray<any>, P extends ReadonlyArray<any>> = number extends I["length"]
2873
+ ? number extends P["length"] ? MapArrayPattern<I, P>
2874
+ : P["length"] extends Required<P>["length"] ? NarrowArrayPrefix<I, P>
2875
+ : MapArrayPattern<I, P>
2876
+ : MapArrayPattern<I, P>
2877
+
2878
+ type MapArrayPattern<I, P> = {
2879
+ readonly [K in keyof I]: K extends keyof P ? ExtractAndNarrow<I[K], P[K]> : I[K]
2880
+ } extends infer R ? Fail extends R[keyof R] ? never
2881
+ : R
2882
+ : never
2883
+
2884
+ type NarrowArrayPrefix<
2885
+ I extends ReadonlyArray<any>,
2886
+ P extends ReadonlyArray<any>,
2887
+ Out extends ReadonlyArray<any> = readonly []
2888
+ > = P extends readonly [infer PH, ...infer PT] ?
2889
+ I extends readonly [infer IH, ...infer IT] ?
2890
+ [ExtractAndNarrow<IH, PH>] extends [infer N] ? [N] extends [never] ? never
2891
+ : NarrowArrayPrefix<IT, PT, readonly [...Out, N]>
2892
+ : never
2893
+ : NarrowArrayPrefix<readonly [I[number], ...Array<I[number]>], P, Out>
2894
+ : readonly [...Out, ...I]
2895
+
2838
2896
  type ExtractAndNarrow<Input, P> = P extends Predicate.Refinement<infer _In, infer _Out> ?
2839
2897
  _Out extends Input ? Extract<_Out, Input>
2840
2898
  : Extract<Input, _Out> :
@@ -2843,12 +2901,7 @@ export declare namespace Types {
2843
2901
  : Extract<Input, _In>
2844
2902
  : P extends Predicate.Predicate<infer _In> ? Extract<Input, _In>
2845
2903
  : Input extends infer I ? Exclude<
2846
- I extends ReadonlyArray<any> ? P extends ReadonlyArray<any> ? {
2847
- readonly [K in keyof I]: K extends keyof P ? ExtractAndNarrow<I[K], P[K]>
2848
- : I[K]
2849
- } extends infer R ? Fail extends R[keyof R] ? never
2850
- : R
2851
- : never
2904
+ I extends ReadonlyArray<any> ? P extends ReadonlyArray<any> ? NarrowArrayPattern<I, P>
2852
2905
  : never
2853
2906
  : IsPlainObject<I> extends true ? string extends keyof I ? I extends P ? I
2854
2907
  : never
package/src/Path.ts CHANGED
@@ -14,6 +14,7 @@ import * as Context from "./Context.ts"
14
14
  import * as Effect from "./Effect.ts"
15
15
  import { identity } from "./Function.ts"
16
16
  import * as Layer from "./Layer.ts"
17
+ import * as Option from "./Option.ts"
17
18
  import { BadArgument } from "./PlatformError.ts"
18
19
 
19
20
  /**
@@ -47,10 +48,17 @@ export const TypeId = "~effect/Path"
47
48
  * formatting, and converting file system paths. URL conversion methods return
48
49
  * `Effect`s because invalid file URLs or paths can fail with `BadArgument`.
49
50
  *
51
+ * `resolveWithin(root, input)` resolves a relative `input` beneath `root` and
52
+ * returns `Option.none()` when the result would leave the root or when `input`
53
+ * has its own root (an absolute path, or a Windows drive or UNC prefix). The
54
+ * root itself is allowed. The check is lexical: it does not follow symlinks,
55
+ * so it is not a sandbox on its own. A relative `root` is resolved against the
56
+ * current working directory, as with `resolve`.
57
+ *
50
58
  * **Example** (Using path operations)
51
59
  *
52
60
  * ```ts import.meta.vitest
53
- * import { Effect, Path } from "effect"
61
+ * import { Effect, Option, Path } from "effect"
54
62
  *
55
63
  * const program = Effect.gen(function*() {
56
64
  * const path = yield* Path.Path
@@ -64,7 +72,8 @@ export const TypeId = "~effect/Path"
64
72
  * isAbsolute: path.isAbsolute("/absolute/path"),
65
73
  * name: path.parse("/path/to/file.txt").name,
66
74
  * relative: path.relative("/from/path", "/to/path"),
67
- * resolved: path.resolve("/base", "relative", "path")
75
+ * resolved: path.resolve("/base", "relative", "path"),
76
+ * within: path.resolveWithin("/base", "../outside")
68
77
  * }
69
78
  * })
70
79
  *
@@ -78,6 +87,7 @@ export const TypeId = "~effect/Path"
78
87
  * result.name // => "file"
79
88
  * result.relative // => "../../to/path"
80
89
  * result.resolved // => "/base/relative/path"
90
+ * result.within // => Option.none()
81
91
  * ```
82
92
  *
83
93
  * @stability unstable
@@ -98,6 +108,7 @@ export interface Path {
98
108
  readonly parse: (path: string) => Path.Parsed
99
109
  readonly relative: (from: string, to: string) => string
100
110
  readonly resolve: (...pathSegments: ReadonlyArray<string>) => string
111
+ readonly resolveWithin: (root: string, input: string) => Option.Option<string>
101
112
  readonly toFileUrl: (path: string) => Effect.Effect<URL, BadArgument>
102
113
  readonly toNamespacedPath: (path: string) => string
103
114
  }
@@ -204,8 +215,7 @@ export declare namespace Path {
204
215
  * import { Effect, Layer, Path } from "effect"
205
216
  *
206
217
  * // Create a custom path implementation
207
- * const customPath: Path.Path = {
208
- * [Path.TypeId]: Path.TypeId,
218
+ * const customPath = Path.make({
209
219
  * sep: "/",
210
220
  * basename: (path: string, suffix?: string) => {
211
221
  * const base = path.split("/").pop() || ""
@@ -239,7 +249,7 @@ export declare namespace Path {
239
249
  * resolve: (...pathSegments: ReadonlyArray<string>) => pathSegments.join("/"),
240
250
  * toFileUrl: (path: string) => Effect.succeed(new URL(`file://${path}`)),
241
251
  * toNamespacedPath: (path: string) => path
242
- * }
252
+ * })
243
253
  *
244
254
  * // Provide the path service
245
255
  * const customPathLayer = Layer.succeed(Path.Path)(customPath)
@@ -259,6 +269,42 @@ export declare namespace Path {
259
269
  */
260
270
  export const Path: Context.Service<Path, Path> = Context.Service("effect/Path")
261
271
 
272
+ /**
273
+ * Creates a `Path` service from platform path operations.
274
+ *
275
+ * **When to use**
276
+ *
277
+ * Use to build a `Path` implementation, such as a platform layer or a test
278
+ * double, without implementing the operations that can be derived from the
279
+ * others.
280
+ *
281
+ * **Details**
282
+ *
283
+ * Adds the `Path` type marker and derives `resolveWithin` from the provided
284
+ * `parse`, `resolve`, `relative`, `isAbsolute`, and `sep`, so containment
285
+ * follows the same platform rules as those operations.
286
+ *
287
+ * @see {@link layer} for the built-in POSIX `Path` service layer
288
+ *
289
+ * @stability unstable
290
+ * @category constructors
291
+ * @since 4.0.0
292
+ */
293
+ export const make = (impl: Omit<Path, typeof TypeId | "resolveWithin">): Path =>
294
+ Path.of({
295
+ ...impl,
296
+ [TypeId]: TypeId,
297
+ resolveWithin(root, input) {
298
+ if (impl.parse(input).root !== "") return Option.none()
299
+ const base = impl.resolve(root)
300
+ const candidate = impl.resolve(base, input)
301
+ const relative = impl.relative(base, candidate)
302
+ return relative === ".." || relative.startsWith(`..${impl.sep}`) || impl.isAbsolute(relative)
303
+ ? Option.none()
304
+ : Option.some(candidate)
305
+ }
306
+ })
307
+
262
308
  /**
263
309
  * The following functions are adapted from the Node.js source code:
264
310
  * https://github.com/nodejs/node/blob/main/lib/internal/url.js
@@ -479,8 +525,7 @@ function encodePathChars(filepath: string) {
479
525
  return filepath
480
526
  }
481
527
 
482
- const posixImpl = Path.of({
483
- [TypeId]: TypeId,
528
+ const posixImpl = make({
484
529
  resolve,
485
530
  normalize(path) {
486
531
  if (path.length === 0) return "."
package/src/Schema.ts CHANGED
@@ -36,6 +36,7 @@ import * as HashMap_ from "./HashMap.ts"
36
36
  import * as HashSet_ from "./HashSet.ts"
37
37
  import * as Cookies_ from "./http/Cookies.ts"
38
38
  import * as Headers_ from "./http/Headers.ts"
39
+ import * as UrlParams_internal from "./http/internal/urlParams.ts"
39
40
  import * as UrlParams_ from "./http/UrlParams.ts"
40
41
  import { NodeInspectSymbol } from "./Inspectable.ts"
41
42
  import * as core from "./internal/core.ts"
@@ -5966,6 +5967,9 @@ export type DecodingDefaultOptions = {
5966
5967
  function toIssueEffect<A, R>(
5967
5968
  self: Effect.Effect<A, SchemaError, R>
5968
5969
  ): Effect.Effect<A, SchemaIssue.Issue, R> {
5970
+ if (effectIsExit(self) && self._tag === "Success") {
5971
+ return self as unknown as Exit_.Exit<A, SchemaIssue.Issue>
5972
+ }
5969
5973
  return Effect.catchCause(self, (cause) => Effect.failCauseSync(() => Cause_.map(cause, (error) => error.issue)))
5970
5974
  }
5971
5975
  /**
@@ -6312,6 +6316,12 @@ type Flatten<Schemas> = Schemas extends readonly [infer Head, ...infer Tail]
6312
6316
  ? Head extends Union<infer Inner> ? [...Flatten<Inner>, ...Flatten<Tail>]
6313
6317
  : [Head, ...Flatten<Tail>]
6314
6318
  : []
6319
+ type DiscriminantKey<T extends PropertyKey> = T extends number ? `${T}` : T
6320
+ type EnsureUniqueDiscriminants<Tags extends ReadonlyArray<PropertyKey>, Seen = never> = Tags extends
6321
+ readonly [infer Head extends PropertyKey, ...infer Tail extends ReadonlyArray<PropertyKey>]
6322
+ ? [DiscriminantKey<Head> & Seen] extends [never] ? EnsureUniqueDiscriminants<Tail, Seen | DiscriminantKey<Head>>
6323
+ : never
6324
+ : unknown
6315
6325
  type MatchCasesResult<Cases> = {
6316
6326
  [K in keyof Cases]-?: NonNullable<Cases[K]> extends (...args: Array<any>) => infer R ? R : never
6317
6327
  }[keyof Cases]
@@ -6396,7 +6406,10 @@ export type toTaggedUnion<
6396
6406
  *
6397
6407
  * **Gotchas**
6398
6408
  *
6399
- * Throws if multiple members use the same discriminant property key.
6409
+ * Rejects overlapping discriminant types in known member tuples at compile
6410
+ * time, including nested unions. Numeric and string values such as `1` and
6411
+ * `"1"` count as duplicates. Also throws at runtime if multiple members use the
6412
+ * same discriminant property key.
6400
6413
  *
6401
6414
  * **Example** (Adding tagged-union utilities to an existing union)
6402
6415
  *
@@ -6423,7 +6436,7 @@ export type toTaggedUnion<
6423
6436
  */
6424
6437
  export function toTaggedUnion<const Tag extends PropertyKey>(tag: Tag) {
6425
6438
  return <const Members extends ReadonlyArray<Constraint & { readonly Type: { readonly [K in Tag]: PropertyKey } }>>(
6426
- self: Union<Members>
6439
+ self: Union<Members> & NoInfer<EnsureUniqueDiscriminants<TaggedUnionUtils<Tag, Members>["discriminants"]>>
6427
6440
  ): toTaggedUnion<Tag, Members> => {
6428
6441
  const cases: Record<PropertyKey, unknown> = {}
6429
6442
  const discriminants: Array<PropertyKey> = []
@@ -15221,9 +15234,9 @@ export const UrlParams: UrlParams = declare(
15221
15234
  toCodec: () =>
15222
15235
  link<UrlParams_.UrlParams>()(
15223
15236
  ArraySchema(Tuple([String, String])),
15224
- SchemaTransformation.transform({
15237
+ SchemaTransformation.transform<UrlParams_.UrlParams, ReadonlyArray<readonly [string, string]>>({
15225
15238
  decode: UrlParams_.make,
15226
- encode: (self) => self.params
15239
+ encode: (self) => self.params.map(([key, value]) => [key, UrlParams_internal.unwrap(value)])
15227
15240
  })
15228
15241
  )
15229
15242
  }
package/src/String.ts CHANGED
@@ -1441,6 +1441,12 @@ export const stripMargin = (self: string): string => stripMarginWith(self, "|")
1441
1441
  /**
1442
1442
  * Converts a snake_case string to camelCase.
1443
1443
  *
1444
+ * **Details**
1445
+ *
1446
+ * Keeps the first character, then replaces each later underscore and the
1447
+ * character after it with that character uppercased. A trailing underscore is
1448
+ * dropped. Input made only of an even number of underscores returns `""`.
1449
+ *
1444
1450
  * **Example** (Converting snake_case to camelCase)
1445
1451
  *
1446
1452
  * ```ts import.meta.vitest
@@ -1455,10 +1461,10 @@ export const stripMargin = (self: string): string => stripMarginWith(self, "|")
1455
1461
  * @since 2.0.0
1456
1462
  */
1457
1463
  export const snakeToCamel = (self: string): string => {
1458
- if (self.length === 0) return self
1464
+ if (self.length === 0 || (self.length % 2 === 0 && self[0] === "_" && /^_+$/.test(self))) return ""
1459
1465
  let str = self[0]
1460
1466
  for (let i = 1; i < self.length; i++) {
1461
- str += self[i] === "_" ? self[++i].toUpperCase() : self[i]
1467
+ str += self[i] === "_" ? self.charAt(++i).toUpperCase() : self[i]
1462
1468
  }
1463
1469
  return str
1464
1470
  }
@@ -1466,6 +1472,12 @@ export const snakeToCamel = (self: string): string => {
1466
1472
  /**
1467
1473
  * Converts a snake_case string to PascalCase.
1468
1474
  *
1475
+ * **Details**
1476
+ *
1477
+ * Uppercases the first character, then replaces each later underscore and the
1478
+ * character after it with that character uppercased. A trailing underscore is
1479
+ * dropped. Input made only of an even number of underscores returns `""`.
1480
+ *
1469
1481
  * **Example** (Converting snake_case to PascalCase)
1470
1482
  *
1471
1483
  * ```ts import.meta.vitest
@@ -1480,10 +1492,10 @@ export const snakeToCamel = (self: string): string => {
1480
1492
  * @since 2.0.0
1481
1493
  */
1482
1494
  export const snakeToPascal = (self: string): string => {
1483
- if (self.length === 0) return self
1495
+ if (self.length === 0 || (self.length % 2 === 0 && self[0] === "_" && /^_+$/.test(self))) return ""
1484
1496
  let str = self[0].toUpperCase()
1485
1497
  for (let i = 1; i < self.length; i++) {
1486
- str += self[i] === "_" ? self[++i].toUpperCase() : self[i]
1498
+ str += self[i] === "_" ? self.charAt(++i).toUpperCase() : self[i]
1487
1499
  }
1488
1500
  return str
1489
1501
  }
@@ -1739,6 +1751,7 @@ const normalizeCase = (
1739
1751
  while (result.charAt(end - 1) === "\0") {
1740
1752
  end--
1741
1753
  }
1754
+ if (start >= end) return ""
1742
1755
 
1743
1756
  // Transform each token independently.
1744
1757
  return result.slice(start, end).split("\0").map(transform).join(delimiter)
package/src/TxRef.ts CHANGED
@@ -13,6 +13,7 @@
13
13
  * @since 4.0.0
14
14
  */
15
15
  import * as Effect from "./Effect.ts"
16
+ import type { TransactionMetaInner } from "./Effect.ts"
16
17
  import { dual } from "./Function.ts"
17
18
  import { pipeArguments } from "./Pipeable.ts"
18
19
  import type { Pipeable } from "./Pipeable.ts"
@@ -140,10 +141,11 @@ export const makeUnsafe = <A>(initial: A): TxRef<A> => ({
140
141
  })
141
142
 
142
143
  const journalEntry = <A>(state: Effect.Transaction["Service"], self: TxRef<A>) => {
143
- let entry = state.journal.get(self)
144
+ const journal = (state as TransactionMetaInner).journal
145
+ let entry = journal.get(self)
144
146
  if (entry === undefined) {
145
147
  entry = { version: self.version, value: self.value, written: false }
146
- state.journal.set(self, entry)
148
+ journal.set(self, entry)
147
149
  }
148
150
  return entry
149
151
  }
package/src/ai/AiError.ts CHANGED
@@ -47,7 +47,9 @@ import * as Schema from "../Schema.ts"
47
47
  export const HttpRequestDetails = Schema.Struct({
48
48
  method: Schema.Literals(["GET", "POST", "PATCH", "PUT", "DELETE", "HEAD", "OPTIONS", "TRACE", "QUERY"]),
49
49
  url: Schema.String,
50
- urlParams: Schema.Array(Schema.Tuple([Schema.String, Schema.String])),
50
+ urlParams: Schema.Array(
51
+ Schema.Tuple([Schema.String, Schema.Union([Schema.String, Schema.Redacted(Schema.String)])])
52
+ ),
51
53
  hash: Schema.optional(Schema.String),
52
54
  headers: Schema.Record(
53
55
  Schema.String,
@@ -28,9 +28,23 @@ export type TypeId = "~effect/ai/Decision"
28
28
  */
29
29
  export const TypeId: TypeId = "~effect/ai/Decision"
30
30
 
31
+ /**
32
+ * Decision instructions or descriptions: a string, JSON object, or JSON array.
33
+ *
34
+ * **Details**
35
+ *
36
+ * TypeScript interfaces lack the index signature required by `Schema.JsonObject`;
37
+ * use object literals, type aliases, or Schema types instead.
38
+ *
39
+ * @stability unstable
40
+ * @category models
41
+ * @since 4.0.5
42
+ */
43
+ export type Description = string | Schema.JsonObject | Schema.JsonArray
44
+
31
45
  /**
32
46
  * Decision that assigns the input one label out of a set of criteria.
33
- * `criteria` maps labels to descriptions.
47
+ * `criteria` maps labels to descriptions; use `null` for a label without a description.
34
48
  *
35
49
  * @see {@link classify} for the constructor
36
50
  * @see {@link ClassifyAnswer} for the answer produced by this decision
@@ -41,13 +55,14 @@ export const TypeId: TypeId = "~effect/ai/Decision"
41
55
  */
42
56
  export interface Classify<Label extends string> {
43
57
  readonly _tag: "Classify"
44
- readonly instructions: string
45
- readonly criteria: { readonly [L in Label]: string }
58
+ readonly instructions: Description
59
+ readonly criteria: { readonly [L in Label]: Description | null }
46
60
  }
47
61
 
48
62
  /**
49
63
  * Decision that places the input on an ordered scale of criteria.
50
- * `criteria` lists levels from lowest to highest.
64
+ * `criteria` lists levels from lowest to highest, with labels for answers and
65
+ * descriptions for the provider.
51
66
  *
52
67
  * @see {@link rate} for the constructor
53
68
  * @see {@link RateAnswer} for the answer produced by this decision
@@ -58,8 +73,8 @@ export interface Classify<Label extends string> {
58
73
  */
59
74
  export interface Rate<Level extends string> {
60
75
  readonly _tag: "Rate"
61
- readonly instructions: string
62
- readonly criteria: ReadonlyArray<Level>
76
+ readonly instructions: Description
77
+ readonly criteria: ReadonlyArray<{ readonly label: Level; readonly description: Description }>
63
78
  }
64
79
 
65
80
  /**
@@ -76,10 +91,10 @@ export interface Rate<Level extends string> {
76
91
  */
77
92
  export interface Probability {
78
93
  readonly _tag: "Probability"
79
- readonly instructions: string
94
+ readonly instructions: Description
80
95
  readonly criteria?: {
81
- readonly false: string
82
- readonly true: string
96
+ readonly false: Description
97
+ readonly true: Description
83
98
  } | undefined
84
99
  }
85
100
 
@@ -110,8 +125,9 @@ export interface ClassifyAnswer<Label extends string> {
110
125
  /**
111
126
  * Answer to a {@link Rate} decision.
112
127
  * `rating` is the probability-weighted position on the scale and may fall
113
- * between two levels, within `[0, criteria.length - 1]`. `label` is the level
114
- * with the highest probability, choosing the first criteria entry on ties.
128
+ * between two levels, within `[0, criteria.length - 1]`. `label` is the label
129
+ * of the level with the highest probability, choosing the first criteria entry
130
+ * on ties.
115
131
  * `confidence` is an optional, provider-defined measure in `[0, 1]`.
116
132
  *
117
133
  * @stability unstable
@@ -176,6 +192,7 @@ export interface Definition<Input extends Schema.Constraint, Decisions extends R
176
192
 
177
193
  /**
178
194
  * Creates a classification decision from labelled criteria.
195
+ * Descriptions can be `null` when the label needs no explanation.
179
196
  * Throws if fewer than two labels are supplied.
180
197
  *
181
198
  * **Example** (Choosing a department)
@@ -201,8 +218,8 @@ export interface Definition<Input extends Schema.Constraint, Decisions extends R
201
218
  * @since 4.0.0
202
219
  */
203
220
  export const classify = <Label extends string>(options: {
204
- readonly instructions: string
205
- readonly criteria: { readonly [L in Label]: string }
221
+ readonly instructions: Description
222
+ readonly criteria: { readonly [L in Label]: Description | null }
206
223
  }): Classify<Label> => {
207
224
  if (Object.keys(options.criteria).length < 2) {
208
225
  throw new Error("Decision.classify: criteria must contain at least two labels")
@@ -216,7 +233,9 @@ export const classify = <Label extends string>(options: {
216
233
 
217
234
  /**
218
235
  * Creates a rating decision from an ordered list of criteria.
219
- * Throws if fewer than two levels or duplicate levels are supplied.
236
+ * Strings serve as both label and description; use `{ label, description }`
237
+ * to separate them. Answers use the label.
238
+ * Throws if fewer than two levels or duplicate labels are supplied.
220
239
  *
221
240
  * **Example** (Rating frustration)
222
241
  *
@@ -229,6 +248,33 @@ export const classify = <Label extends string>(options: {
229
248
  * })
230
249
  * ```
231
250
  *
251
+ * **Example** (Describing levels with structure)
252
+ *
253
+ * ```ts
254
+ * import { Decision } from "effect/ai"
255
+ *
256
+ * const severity = Decision.rate({
257
+ * instructions: "How severe is the reported issue?",
258
+ * criteria: [
259
+ * "cosmetic",
260
+ * {
261
+ * label: "degraded",
262
+ * description: {
263
+ * what: "Broken or degraded feature, but workaround exists",
264
+ * examples: ["export fails in one browser but works in another"]
265
+ * }
266
+ * },
267
+ * {
268
+ * label: "blocking",
269
+ * description: {
270
+ * what: "Blocking issue; no workaround exists",
271
+ * examples: ["cannot log in", "data loss"]
272
+ * }
273
+ * }
274
+ * ]
275
+ * })
276
+ * ```
277
+ *
232
278
  * @see {@link classify} for unordered labels
233
279
  *
234
280
  * @stability unstable
@@ -236,19 +282,22 @@ export const classify = <Label extends string>(options: {
236
282
  * @since 4.0.0
237
283
  */
238
284
  export const rate = <const Level extends string>(options: {
239
- readonly instructions: string
240
- readonly criteria: ReadonlyArray<Level>
285
+ readonly instructions: Description
286
+ readonly criteria: ReadonlyArray<Level | { readonly label: Level; readonly description: Description }>
241
287
  }): Rate<Level> => {
242
288
  if (options.criteria.length < 2) {
243
289
  throw new Error("Decision.rate: criteria must contain at least two levels")
244
290
  }
245
- if (new Set(options.criteria).size !== options.criteria.length) {
291
+ const criteria = options.criteria.map((level) =>
292
+ typeof level === "string" ? { label: level, description: level } : level
293
+ )
294
+ if (new Set(criteria.map((level) => level.label)).size !== criteria.length) {
246
295
  throw new Error("Decision.rate: criteria must contain distinct levels")
247
296
  }
248
297
  return {
249
298
  _tag: "Rate",
250
299
  instructions: options.instructions,
251
- criteria: options.criteria
300
+ criteria
252
301
  }
253
302
  }
254
303
 
@@ -287,10 +336,10 @@ export const rate = <const Level extends string>(options: {
287
336
  * @since 4.0.0
288
337
  */
289
338
  export const probability = (options: {
290
- readonly instructions: string
339
+ readonly instructions: Description
291
340
  readonly criteria?: {
292
- readonly false: string
293
- readonly true: string
341
+ readonly false: Description
342
+ readonly true: Description
294
343
  } | undefined
295
344
  }): Probability => ({
296
345
  _tag: "Probability",
@@ -290,7 +290,7 @@ const validateAnswer = (
290
290
  return { label: answer.label, probabilities, ...(confidence === undefined ? undefined : { confidence }) }
291
291
  }
292
292
  case "Rate": {
293
- const levels = decision.criteria
293
+ const levels = decision.criteria.map((level) => level.label)
294
294
  if (!isFiniteNumber(answer.rating) || answer.rating < 0 || answer.rating > levels.length - 1) {
295
295
  return invalidOutput(`Provider returned a rating outside [0, ${levels.length - 1}] for decision "${key}"`)
296
296
  }