Merge commit '36c66dd290d3ce6eb1ccd310d0c658d4a32bb8eb' as 'repos/effect'
This commit is contained in:
736
repos/effect/packages/ai/anthropic/CHANGELOG.md
Normal file
736
repos/effect/packages/ai/anthropic/CHANGELOG.md
Normal file
@@ -0,0 +1,736 @@
|
||||
# @effect/ai-anthropic
|
||||
|
||||
## 4.0.0-beta.99
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#6371](https://github.com/Effect-TS/effect/pull/6371) [`7543afe`](https://github.com/Effect-TS/effect/commit/7543afea6f4d97d1f1ad876224323838a48daadd) Thanks @polRk! - Fix client-executed provider tools (Memory, Text Editor, Computer Use, Bash) which were unusable on the wire.
|
||||
- `makeResponse` (and the streaming equivalents) now map a provider `tool_use` wire name (e.g. `"memory"`) back to the tool's custom name (e.g. `"AnthropicMemory"`) that the toolkit is keyed by, instead of raising `ToolNotFoundError`.
|
||||
- `AnthropicTool.MemoryCreateCommand` now includes the required `file_text` field, so a `create` command no longer drops the file body.
|
||||
- Optional parameters on client-executed provider tools now use `Schema.optionalKey` instead of `Schema.optional`, which the Anthropic codec rejected with "Unsupported AST Undefined": `Memory`/`TextEditor` `view_range`, `ComputerUse` `coordinate`, and `Bash` `restart`.
|
||||
|
||||
Closes [#2615](https://github.com/Effect-TS/effect/issues/2615).
|
||||
|
||||
- Updated dependencies [[`8ce4795`](https://github.com/Effect-TS/effect/commit/8ce4795ccbaebca4292757db568c005a992546a4), [`80b539f`](https://github.com/Effect-TS/effect/commit/80b539f8aba68f478c75c35c2b4140c4ffc4fada), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`e6e6dba`](https://github.com/Effect-TS/effect/commit/e6e6dba6e9d86e7c2ad27dcedf289db76a19697f), [`bfb203e`](https://github.com/Effect-TS/effect/commit/bfb203e95aa439f731acad37fc3a9a831a190f1c), [`2e9a34a`](https://github.com/Effect-TS/effect/commit/2e9a34ac2bece4f3a206160480c991e3841dc67a), [`55d4eb3`](https://github.com/Effect-TS/effect/commit/55d4eb34f2c64d54f6a25a305b5c5438ebd7934e), [`bddb010`](https://github.com/Effect-TS/effect/commit/bddb010eac3d4436cb094edbbee7460c5440c162), [`a328835`](https://github.com/Effect-TS/effect/commit/a328835e50d76bc96648a1c1550456e8c9f81210), [`5560d05`](https://github.com/Effect-TS/effect/commit/5560d05aa6abdd29466d9c3412cc5e648b0adbde), [`8f6e3ad`](https://github.com/Effect-TS/effect/commit/8f6e3adb185b16e8820b98c509b308086f7ff1af), [`46997fa`](https://github.com/Effect-TS/effect/commit/46997fa60401f5e3c93daa4b61f7df8e31caaab4), [`9e6e12d`](https://github.com/Effect-TS/effect/commit/9e6e12d75c118cd265496f2880490d1f33a5c8bf), [`3394b93`](https://github.com/Effect-TS/effect/commit/3394b93d97d6f24fc38670641d1490289ffca7f1), [`febeabc`](https://github.com/Effect-TS/effect/commit/febeabc3f7c31094da000a23edeaabfe2ab00a38), [`54161c9`](https://github.com/Effect-TS/effect/commit/54161c98f6f3569e0c31842f54e6a257f9421c4c), [`385f7a4`](https://github.com/Effect-TS/effect/commit/385f7a4ee4a7359928597ea56d151dbaf5eb5802), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`7543afe`](https://github.com/Effect-TS/effect/commit/7543afea6f4d97d1f1ad876224323838a48daadd), [`44b9cf3`](https://github.com/Effect-TS/effect/commit/44b9cf3d240d726997b4bbcd0ede48e074d3c456), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`0a8aa6a`](https://github.com/Effect-TS/effect/commit/0a8aa6acb90a72b91c24d17133c950e4cacd8abd), [`c8d9fcf`](https://github.com/Effect-TS/effect/commit/c8d9fcf7b030f7c474effbab2764ce7aee1c7209), [`9ca7f9a`](https://github.com/Effect-TS/effect/commit/9ca7f9a69363e4485645966d5a93b8f9597c5206), [`e7aca89`](https://github.com/Effect-TS/effect/commit/e7aca894bb32fbb785b5830837e6061c415a6015), [`55d7560`](https://github.com/Effect-TS/effect/commit/55d75609b8acf8a1b54c1b1c7fbbb65ec741aa3e), [`f809189`](https://github.com/Effect-TS/effect/commit/f809189ddf6b6011ba43a9901baaa734e315da2a), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`0ebdbe7`](https://github.com/Effect-TS/effect/commit/0ebdbe74463dc84385956d0b1e8c2b79ebab5400), [`7517d09`](https://github.com/Effect-TS/effect/commit/7517d09f12a0b183a81bd425962c4e280a68b05d), [`212493b`](https://github.com/Effect-TS/effect/commit/212493b9a1eb98cd1ef6959c707a2e5784a5ae91), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`80ea8cb`](https://github.com/Effect-TS/effect/commit/80ea8cb9222ca73f564c8267ab2f82966fea027a), [`8df19f4`](https://github.com/Effect-TS/effect/commit/8df19f4fe81d90cc33ace88b9a77e5534f82d604)]:
|
||||
- effect@4.0.0-beta.99
|
||||
|
||||
## 4.0.0-beta.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`989603b`](https://github.com/Effect-TS/effect-smol/commit/989603b60ab1197b64acf214208e0d370cd1f842), [`214c458`](https://github.com/Effect-TS/effect-smol/commit/214c458084bb6995d543cd37d1055f24be3d454e), [`a037273`](https://github.com/Effect-TS/effect-smol/commit/a0372736ac34796969b051bbba4717d7983f1ebe), [`97fdaa9`](https://github.com/Effect-TS/effect-smol/commit/97fdaa9c1f522c65e579365d314a07878e2b904f), [`b24d248`](https://github.com/Effect-TS/effect-smol/commit/b24d248c8df44222ce642087cde2bd859a2dc709), [`19c222c`](https://github.com/Effect-TS/effect-smol/commit/19c222cac2353a3d7b7733caecb00556fffe9a5c), [`eec85dd`](https://github.com/Effect-TS/effect-smol/commit/eec85ddba09ea326fd268ee33eeffd47e50d4671), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`8849052`](https://github.com/Effect-TS/effect-smol/commit/884905232d1e9a365e046d8dde27bf9c5707f57f), [`c15e16a`](https://github.com/Effect-TS/effect-smol/commit/c15e16ad130d1fbde25d912b7ac55995066cb35b), [`01d00a3`](https://github.com/Effect-TS/effect-smol/commit/01d00a3abfbf1f37996cdbe738ea5137c646cdd7), [`8bd4589`](https://github.com/Effect-TS/effect-smol/commit/8bd458975a1b3a8ed042eccf317b93d28ded91e7), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`6e08428`](https://github.com/Effect-TS/effect-smol/commit/6e08428d980501b856f846ad3f3f0e4ea46e7786), [`388dcf9`](https://github.com/Effect-TS/effect-smol/commit/388dcf953f65d317547f34d40e6443c5f264205f), [`2b7ce2b`](https://github.com/Effect-TS/effect-smol/commit/2b7ce2b513e7ec2a77822f1116dc6ffb6ba93f4e), [`87bea7e`](https://github.com/Effect-TS/effect-smol/commit/87bea7e16259246f3bcdf565446394751abca953), [`ce38dc3`](https://github.com/Effect-TS/effect-smol/commit/ce38dc33bda805a684432cca071f4dc3c6b9a1ba), [`a807cd1`](https://github.com/Effect-TS/effect-smol/commit/a807cd170341deca8a1cfb52c4222585f2431bb9), [`fd8a356`](https://github.com/Effect-TS/effect-smol/commit/fd8a356f06a8c9ce4e7e0a13fc4021c178ed31de), [`c2a5edc`](https://github.com/Effect-TS/effect-smol/commit/c2a5edc3abd31ad5bc123362bc1213e03e4095c3), [`5946da3`](https://github.com/Effect-TS/effect-smol/commit/5946da3804a1be5e752b05b96bd058cdba50a1bf), [`4ae0c5f`](https://github.com/Effect-TS/effect-smol/commit/4ae0c5ffcbe6c56ddfcb05c639112a079483539e), [`5b2a0bc`](https://github.com/Effect-TS/effect-smol/commit/5b2a0bceea3a28a33a58555210c90a415dc74a76), [`72ac585`](https://github.com/Effect-TS/effect-smol/commit/72ac585884befde6af9208da738699a93f1bae79), [`5e8c1b8`](https://github.com/Effect-TS/effect-smol/commit/5e8c1b82bfafa121311f987a49ab75395e3647a7), [`0f9c078`](https://github.com/Effect-TS/effect-smol/commit/0f9c07841b04183f485ee6e6458de73b290b09f5)]:
|
||||
- effect@4.0.0-beta.98
|
||||
|
||||
## 4.0.0-beta.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2568](https://github.com/Effect-TS/effect-smol/pull/2568) [`97a4138`](https://github.com/Effect-TS/effect-smol/commit/97a4138f9e9d31d38026f935b52d423f5ccadc4f) Thanks @K-Mistele! - Widen the Anthropic `Model` schema to accept both known model identifiers as well
|
||||
as any string to allow for newer models
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.97
|
||||
|
||||
## 4.0.0-beta.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1503f45`](https://github.com/Effect-TS/effect-smol/commit/1503f45cb5bb2a74f4705252ec505a1f0ade7e62), [`57fe793`](https://github.com/Effect-TS/effect-smol/commit/57fe79316ffbc380b30626a168981fb26ae97459), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`97f29df`](https://github.com/Effect-TS/effect-smol/commit/97f29df457f7ffd07cfb4b379315c12c086af805)]:
|
||||
- effect@4.0.0-beta.96
|
||||
|
||||
## 4.0.0-beta.95
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2531](https://github.com/Effect-TS/effect-smol/pull/2531) [`bdca354`](https://github.com/Effect-TS/effect-smol/commit/bdca35449d5dfce5b4433da75ec0a88d0a9b2b27) Thanks @polRk! - Fix `Memory_20250818` provider-defined tool missing `requiresHandler: true`. Like the other client-executed tools (`TextEditor_20250728`, `Bash_2025*`, `ComputerUse_2025*`), the memory tool requires the application to implement its execution (view/create/str_replace/insert/delete/rename over `/memories/*`). Without this flag, `Tool.HandlersFor` excluded it from the required handlers, making it impossible to type-check a handler for `Memory_20250818` in `Toolkit.toLayer`.
|
||||
|
||||
- Updated dependencies [[`a482442`](https://github.com/Effect-TS/effect-smol/commit/a482442abdeb490e9652b854ec3495e4aa7273e7), [`fbefa85`](https://github.com/Effect-TS/effect-smol/commit/fbefa850fab2f0a302c20614496aeaaa2a8b5590), [`0b4a32f`](https://github.com/Effect-TS/effect-smol/commit/0b4a32f4260f0d8500942a133001b0d349328102), [`18a49e1`](https://github.com/Effect-TS/effect-smol/commit/18a49e1786679456258002ff9397faf02f678c2d), [`266cb90`](https://github.com/Effect-TS/effect-smol/commit/266cb90bb2c17aabc40563c32db334f09ba3d74b), [`912f095`](https://github.com/Effect-TS/effect-smol/commit/912f095a34572bbd3cedf6edb27878443e3e4a95), [`a6718f9`](https://github.com/Effect-TS/effect-smol/commit/a6718f9e00a15ca903b0732da46116cbf3d6aca7), [`bef5154`](https://github.com/Effect-TS/effect-smol/commit/bef51540a243aa2f872a00c01d0cd58b7a769baa), [`18e0564`](https://github.com/Effect-TS/effect-smol/commit/18e0564bd0f8ebbdfcaf1e2c21529948e9e4a81d), [`fb50f14`](https://github.com/Effect-TS/effect-smol/commit/fb50f14fc3657c1973785aa5b72ecf0b0d28e0b2)]:
|
||||
- effect@4.0.0-beta.95
|
||||
|
||||
## 4.0.0-beta.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`95a0e9b`](https://github.com/Effect-TS/effect-smol/commit/95a0e9bb62797af0e81c9998773405f248f218c5), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63), [`f11ce73`](https://github.com/Effect-TS/effect-smol/commit/f11ce73af60823754dc24194f4ffc561b9ea1c2d), [`ff30b6e`](https://github.com/Effect-TS/effect-smol/commit/ff30b6e7c2c63ffc56a4c5818d6d86b01b5ad528), [`1caab3c`](https://github.com/Effect-TS/effect-smol/commit/1caab3cc30f626efbf15e59d74f539a487e5c85c), [`aa80c47`](https://github.com/Effect-TS/effect-smol/commit/aa80c4775a04db87553e5568764cab7e32a72814), [`c2ae4fc`](https://github.com/Effect-TS/effect-smol/commit/c2ae4fce2f03a4cd1861c2b1179da7df656e662d), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63)]:
|
||||
- effect@4.0.0-beta.94
|
||||
|
||||
## 4.0.0-beta.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`00652fe`](https://github.com/Effect-TS/effect-smol/commit/00652fe95c18f87208e91343eb8bf218faa2f677), [`6c58167`](https://github.com/Effect-TS/effect-smol/commit/6c5816746eaf91d2a3c7c899c5720809fa230ae3), [`2bc5415`](https://github.com/Effect-TS/effect-smol/commit/2bc541501a7ef89e542d7cb98e96beb53cd205cc), [`e11cccc`](https://github.com/Effect-TS/effect-smol/commit/e11cccc7d5fe631abccc7d6e3bd296938de0fa2e), [`ba7e77e`](https://github.com/Effect-TS/effect-smol/commit/ba7e77e046b8641a3a4e9750bb88ca4a1d063d3f), [`5713ee7`](https://github.com/Effect-TS/effect-smol/commit/5713ee7edbc3054efde407b2286bbfd45bbc6e1c)]:
|
||||
- effect@4.0.0-beta.93
|
||||
|
||||
## 4.0.0-beta.92
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`affdc13`](https://github.com/Effect-TS/effect-smol/commit/affdc139045cc325dce321a84a580fdc1b2da7b9)]:
|
||||
- effect@4.0.0-beta.92
|
||||
|
||||
## 4.0.0-beta.91
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b135b25`](https://github.com/Effect-TS/effect-smol/commit/b135b2517fca9e7839734ace3699a7dfa75b9075), [`aaa21a3`](https://github.com/Effect-TS/effect-smol/commit/aaa21a369a171c600db294f2a4f640583043e150), [`3475ee6`](https://github.com/Effect-TS/effect-smol/commit/3475ee6c2bda6b05c6d7a12ce30c8bb840b5b1a6)]:
|
||||
- effect@4.0.0-beta.91
|
||||
|
||||
## 4.0.0-beta.90
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d237fdf`](https://github.com/Effect-TS/effect-smol/commit/d237fdf726481f76eb52a6196e111b24122bc3d5)]:
|
||||
- effect@4.0.0-beta.90
|
||||
|
||||
## 4.0.0-beta.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b7d46ab`](https://github.com/Effect-TS/effect-smol/commit/b7d46ab7e1a29d8711817bab583c9febf48a0dad), [`7777e15`](https://github.com/Effect-TS/effect-smol/commit/7777e1540fd3680dd8346723cffec812b9384669), [`5376197`](https://github.com/Effect-TS/effect-smol/commit/5376197ca8e50358a41b1fd3cec27bd1ec680ec6)]:
|
||||
- effect@4.0.0-beta.89
|
||||
|
||||
## 4.0.0-beta.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2450](https://github.com/Effect-TS/effect-smol/pull/2450) [`7b8a549`](https://github.com/Effect-TS/effect-smol/commit/7b8a5493950aa6f9e20024cd7e588838722218f0) Thanks @DomiR! - Fix non-streaming Anthropic responses throwing when a tool call carries `caller` metadata. The mapper emitted `caller.toolId: undefined`, but `ProviderMetadata` is `Record(String, NullOr(Json))` and `undefined` is not a valid Json value, so decoding the model's own response threw `Expected JSON value`. Emit `null` instead, matching the streaming mappers.
|
||||
|
||||
- Updated dependencies [[`911f1b8`](https://github.com/Effect-TS/effect-smol/commit/911f1b84790ce42b3a70c95b33e6f6fd9e74de8b), [`8beeeea`](https://github.com/Effect-TS/effect-smol/commit/8beeeea52879d8613a39468848f01c3092bd54d4), [`c306fcf`](https://github.com/Effect-TS/effect-smol/commit/c306fcfeb1ef38455156932a1faf49292b1318da)]:
|
||||
- effect@4.0.0-beta.88
|
||||
|
||||
## 4.0.0-beta.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a0c1a4`](https://github.com/Effect-TS/effect-smol/commit/5a0c1a4faee5707b5cc35e646ff1ffdad70f1956), [`1eea2ea`](https://github.com/Effect-TS/effect-smol/commit/1eea2ea3795ba47316b82b1ac8d4612c0ba389ed)]:
|
||||
- effect@4.0.0-beta.87
|
||||
|
||||
## 4.0.0-beta.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0b5795a`](https://github.com/Effect-TS/effect-smol/commit/0b5795a0ab4395e8f15955d8d96f2303084bfc64), [`3e3a859`](https://github.com/Effect-TS/effect-smol/commit/3e3a859ec6351a9e0d31674aabbd48fcefabb12e), [`7dbec24`](https://github.com/Effect-TS/effect-smol/commit/7dbec240dbf3bca599a20c486632abce694ef5ab), [`d8c00a1`](https://github.com/Effect-TS/effect-smol/commit/d8c00a171ac7141e8adc08c332d1162d9a9d56fc), [`85b6317`](https://github.com/Effect-TS/effect-smol/commit/85b631701e935866f2762bd595237aa718370cd9), [`6d0fda0`](https://github.com/Effect-TS/effect-smol/commit/6d0fda0d0cbdfffc523c89c57dfdb1608f84fb12), [`108a933`](https://github.com/Effect-TS/effect-smol/commit/108a9335ff8571928197e5847a09c28ac83d6f46), [`7e1f455`](https://github.com/Effect-TS/effect-smol/commit/7e1f455fab5005d769b939c91e519d450f802cf9), [`46b3e79`](https://github.com/Effect-TS/effect-smol/commit/46b3e79944cfdae7901eb148135c85b7eb39834e)]:
|
||||
- effect@4.0.0-beta.86
|
||||
|
||||
## 4.0.0-beta.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`328d97c`](https://github.com/Effect-TS/effect-smol/commit/328d97cc53c0dcb89077a5623e35b095eaa59a8c), [`8441836`](https://github.com/Effect-TS/effect-smol/commit/8441836e6dde70e8ae2126be9cefe9b45798b134), [`074e436`](https://github.com/Effect-TS/effect-smol/commit/074e4361091289104cb0ab6959dc3b0ea7794a6a), [`c1dfd60`](https://github.com/Effect-TS/effect-smol/commit/c1dfd60663eb13a58916f3712d877499943b628a), [`2ba316b`](https://github.com/Effect-TS/effect-smol/commit/2ba316bd15fcbf1c50626500d44a2c9b3bec19f5), [`7ce7344`](https://github.com/Effect-TS/effect-smol/commit/7ce7344c41056c79e2ee19ee6a9346c0f1d227c1)]:
|
||||
- effect@4.0.0-beta.85
|
||||
|
||||
## 4.0.0-beta.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`87f52ba`](https://github.com/Effect-TS/effect-smol/commit/87f52ba16c4370ffa3f84bf8e53038e1419c284e), [`b8ee07f`](https://github.com/Effect-TS/effect-smol/commit/b8ee07ffda8903b5ec2e45a786ddcba59f128fda), [`867c0d7`](https://github.com/Effect-TS/effect-smol/commit/867c0d70a09079b040260d45a1e92ff04dbfbf2f), [`b93bc6c`](https://github.com/Effect-TS/effect-smol/commit/b93bc6c9cb27b909a41d094c97c4f9d25bbc6d6b), [`57d387f`](https://github.com/Effect-TS/effect-smol/commit/57d387f92c30ab63e15e3e641f0a903b65886610), [`bacca41`](https://github.com/Effect-TS/effect-smol/commit/bacca4141c2400effae1eabfdb36c89a459cf246), [`0f8ac79`](https://github.com/Effect-TS/effect-smol/commit/0f8ac7959d29ed68c68ce25aabd6bf0cb7e63ecc), [`25b4482`](https://github.com/Effect-TS/effect-smol/commit/25b448270c01317703f25107e1480d4cd0246d9a), [`9cf3a25`](https://github.com/Effect-TS/effect-smol/commit/9cf3a25c66b0c44a52be9829870c44517ea52db2), [`8def767`](https://github.com/Effect-TS/effect-smol/commit/8def7674b1787f91035298cda4d122937e87ef72)]:
|
||||
- effect@4.0.0-beta.84
|
||||
|
||||
## 4.0.0-beta.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1f2e8ce`](https://github.com/Effect-TS/effect-smol/commit/1f2e8ceef09e0a791c850ed2ade01f97089596f9)]:
|
||||
- effect@4.0.0-beta.83
|
||||
|
||||
## 4.0.0-beta.82
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`193690b`](https://github.com/Effect-TS/effect-smol/commit/193690b642ea802bbed40d663bd677251bbe9dc3)]:
|
||||
- effect@4.0.0-beta.82
|
||||
|
||||
## 4.0.0-beta.81
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`93cb4f8`](https://github.com/Effect-TS/effect-smol/commit/93cb4f8fbfb9e07cb9dc86ce6b155fd1f8167914), [`60341d9`](https://github.com/Effect-TS/effect-smol/commit/60341d9ca744d0473ce3fab621ca9bd225af3a39), [`1105ab5`](https://github.com/Effect-TS/effect-smol/commit/1105ab56cb724212f7ea7b431396ce82e8fd0484), [`4500fbf`](https://github.com/Effect-TS/effect-smol/commit/4500fbfe00763d8a72af6e5d6c5988e8bd4ade36)]:
|
||||
- effect@4.0.0-beta.81
|
||||
|
||||
## 4.0.0-beta.80
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d944330`](https://github.com/Effect-TS/effect-smol/commit/d94433090ee03f426d43e13b883abae4494e55e6), [`f48659f`](https://github.com/Effect-TS/effect-smol/commit/f48659fdcc84930ebc1e5b45b540c0f973389182), [`7652aaa`](https://github.com/Effect-TS/effect-smol/commit/7652aaa3bdbc39f241fe58b54b9a43b713e22e12), [`98630b7`](https://github.com/Effect-TS/effect-smol/commit/98630b7c8f679c352ba6796636c85688fa009d8d), [`90ae23c`](https://github.com/Effect-TS/effect-smol/commit/90ae23cf07284da5e1bcd9dffa882e85df7e617b)]:
|
||||
- effect@4.0.0-beta.80
|
||||
|
||||
## 4.0.0-beta.79
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2357](https://github.com/Effect-TS/effect-smol/pull/2357) [`3efe308`](https://github.com/Effect-TS/effect-smol/commit/3efe308fcc6ac642c65560efbd1b3afc68052553) Thanks @jbmusso! - Mark the Claude 4-6 generation as supporting native structured output in `getModelCapabilities`. `claude-opus-4-6` and `claude-sonnet-4-6` support Anthropic's constrained-decoding structured output (verified against the live API), but were classified as `supportsStructuredOutput: false`, so `generateObject` fell back to a forced JSON tool instead of requesting `output_config.format` (`json_schema`). `claude-opus-4-7` / `claude-opus-4-8` are classified the same way for when the generated `Model` enum picks them up.
|
||||
|
||||
- Updated dependencies [[`b9704dc`](https://github.com/Effect-TS/effect-smol/commit/b9704dc9de9f1649ad502371014fe869b69a49a3), [`a207113`](https://github.com/Effect-TS/effect-smol/commit/a207113f66837bb54416926718a9a7d66774d079), [`5e9b9e2`](https://github.com/Effect-TS/effect-smol/commit/5e9b9e217b164ebfd4a002dd4380b3b1563200c3), [`7c128ae`](https://github.com/Effect-TS/effect-smol/commit/7c128aef458a1e2d224712e51c483c9badad1d44), [`0ada457`](https://github.com/Effect-TS/effect-smol/commit/0ada457c0513d8d908254ab77ebb7d29d2b523d6), [`d7cc5a2`](https://github.com/Effect-TS/effect-smol/commit/d7cc5a2bede3de10943aa0c6bdb4f26836a91efd), [`aad63be`](https://github.com/Effect-TS/effect-smol/commit/aad63becf65e0a6b076e94f8973be7bbe7fbd46f), [`09809f6`](https://github.com/Effect-TS/effect-smol/commit/09809f60f19ec98232f98b33e33e02ecb7e4fbd6), [`2fddda5`](https://github.com/Effect-TS/effect-smol/commit/2fddda5311929f46b61e503f0ade4fc749e8c77d), [`5f21768`](https://github.com/Effect-TS/effect-smol/commit/5f2176833399757c4500d8875b7f2fba0393de75), [`f27003e`](https://github.com/Effect-TS/effect-smol/commit/f27003e00524ff83f20dd9909f62b2f8795efe03)]:
|
||||
- effect@4.0.0-beta.79
|
||||
|
||||
## 4.0.0-beta.78
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7836b8e`](https://github.com/Effect-TS/effect-smol/commit/7836b8eb8bb0f3e04cdf554ee070caccf74f00c1), [`35d49a3`](https://github.com/Effect-TS/effect-smol/commit/35d49a3a09bdba6b513de87ddcead9e61a1042ba), [`4093258`](https://github.com/Effect-TS/effect-smol/commit/40932580e65bafab5f23c5f14b520cb411d0b2cd)]:
|
||||
- effect@4.0.0-beta.78
|
||||
|
||||
## 4.0.0-beta.77
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6e9a5ca`](https://github.com/Effect-TS/effect-smol/commit/6e9a5ca62a61156fd67b2518ad3ab14ac0d25f23), [`302f398`](https://github.com/Effect-TS/effect-smol/commit/302f3984ce206e35d86ddd99d3b72be144850a51)]:
|
||||
- effect@4.0.0-beta.77
|
||||
|
||||
## 4.0.0-beta.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`016108a`](https://github.com/Effect-TS/effect-smol/commit/016108a472af7048ddbbfd05f233e67529fafe12), [`95c03d2`](https://github.com/Effect-TS/effect-smol/commit/95c03d2c55930668c215b5a41c23cf7742fead84), [`07299a3`](https://github.com/Effect-TS/effect-smol/commit/07299a33c09fd52faa9810d30835a2622c752386)]:
|
||||
- effect@4.0.0-beta.76
|
||||
|
||||
## 4.0.0-beta.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`81b187c`](https://github.com/Effect-TS/effect-smol/commit/81b187c17a0d8817b58232826939154010ae49d7), [`ad4b535`](https://github.com/Effect-TS/effect-smol/commit/ad4b535e17f94ce35261829d5a3675f0a7808b4e), [`a29c2e7`](https://github.com/Effect-TS/effect-smol/commit/a29c2e7e3570920156702671d6f3367cd0195f6c), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`ffea4ec`](https://github.com/Effect-TS/effect-smol/commit/ffea4ecf2925f6a4c9fd13079d47584cbf2bed00), [`4255c9b`](https://github.com/Effect-TS/effect-smol/commit/4255c9ba78bb98c7838fbe9dccdd8465e9da5427)]:
|
||||
- effect@4.0.0-beta.75
|
||||
|
||||
## 4.0.0-beta.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b1fc6a4`](https://github.com/Effect-TS/effect-smol/commit/b1fc6a4b4d0ca7fa9fd162799ae17c86f2f7ee8e)]:
|
||||
- effect@4.0.0-beta.74
|
||||
|
||||
## 4.0.0-beta.73
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`361ca30`](https://github.com/Effect-TS/effect-smol/commit/361ca30eb6e134feece547d6e00f82be4cb23f75), [`b9598c6`](https://github.com/Effect-TS/effect-smol/commit/b9598c6a209e75bfdb87ee3b024ecd1e3923ff6e)]:
|
||||
- effect@4.0.0-beta.73
|
||||
|
||||
## 4.0.0-beta.72
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`73e67d1`](https://github.com/Effect-TS/effect-smol/commit/73e67d119a84d697773eaecb4865c6a71eb1a9cb), [`01d71ec`](https://github.com/Effect-TS/effect-smol/commit/01d71ec5a75f3c2747a8d3b1ad9701d1e27b7ce5), [`fcd707e`](https://github.com/Effect-TS/effect-smol/commit/fcd707e091a16e1b35343c901cc4052274e32239)]:
|
||||
- effect@4.0.0-beta.72
|
||||
|
||||
## 4.0.0-beta.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d8ac76b`](https://github.com/Effect-TS/effect-smol/commit/d8ac76b5bad458c42cebe8a0c1b3843f955ac293), [`2c3c00a`](https://github.com/Effect-TS/effect-smol/commit/2c3c00af6faba7b7d422af26a7a2bbc35636d230), [`3751e7c`](https://github.com/Effect-TS/effect-smol/commit/3751e7cf353e7a54cd692c37401207d9afba1e63), [`fc5f25b`](https://github.com/Effect-TS/effect-smol/commit/fc5f25b03ada5fc2431987768a74d3d3e75ca485), [`7ccced4`](https://github.com/Effect-TS/effect-smol/commit/7ccced42867c14c013b01160b3d292f14c05bd04), [`a2e1fe5`](https://github.com/Effect-TS/effect-smol/commit/a2e1fe5835c98c8ee4393a091b1d11b75126e349), [`4a4a36b`](https://github.com/Effect-TS/effect-smol/commit/4a4a36b10e6e616cad07584a43908f6a7e07e618), [`d350292`](https://github.com/Effect-TS/effect-smol/commit/d3502922b4740fa9d745797cbc3775cb67839b6d), [`730afb6`](https://github.com/Effect-TS/effect-smol/commit/730afb66696adf9bd5a328cbca29df9c05968771), [`df1b008`](https://github.com/Effect-TS/effect-smol/commit/df1b008f370f414c2a67a7b8139ef747af8e5fba), [`6d469d5`](https://github.com/Effect-TS/effect-smol/commit/6d469d567a7c41d7e5343bdee21d45b07b0e8190)]:
|
||||
- effect@4.0.0-beta.71
|
||||
|
||||
## 4.0.0-beta.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af7782d`](https://github.com/Effect-TS/effect-smol/commit/af7782d3008d08b043f3a3f261516001514b2b4e), [`7212d70`](https://github.com/Effect-TS/effect-smol/commit/7212d701a3eee7b3553ff502e2c066126e52e839)]:
|
||||
- effect@4.0.0-beta.70
|
||||
|
||||
## 4.0.0-beta.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70ea04a`](https://github.com/Effect-TS/effect-smol/commit/70ea04aa96a2a7859d738d414e1f0e3ed081a27a), [`d0ea8b0`](https://github.com/Effect-TS/effect-smol/commit/d0ea8b03f7d73ae076c1db12666141e480d11178), [`a57674b`](https://github.com/Effect-TS/effect-smol/commit/a57674b64845e9e75a456cf907bfdcb858859118), [`59aa334`](https://github.com/Effect-TS/effect-smol/commit/59aa334fbd0a504dda3c36f6d2ef1be7449b4b8b), [`8f4208e`](https://github.com/Effect-TS/effect-smol/commit/8f4208ee83bc7bdaa6793b5429847b45aab72470)]:
|
||||
- effect@4.0.0-beta.69
|
||||
|
||||
## 4.0.0-beta.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af8267f`](https://github.com/Effect-TS/effect-smol/commit/af8267f2f3588c3fb611e9286f6f933f29ce1217), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`f136bb7`](https://github.com/Effect-TS/effect-smol/commit/f136bb763048cbc6b17edd26496dba3e2415b9fa), [`6f38f07`](https://github.com/Effect-TS/effect-smol/commit/6f38f07d5941a211b251383aaab0f4f55e8a6557), [`aec9c40`](https://github.com/Effect-TS/effect-smol/commit/aec9c401a53db227f18bf5e0c84db7130ad862d6)]:
|
||||
- effect@4.0.0-beta.68
|
||||
|
||||
## 4.0.0-beta.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a42ef66`](https://github.com/Effect-TS/effect-smol/commit/a42ef6632abbddfa820995ae310ccc84ae8d9b6f), [`35594f8`](https://github.com/Effect-TS/effect-smol/commit/35594f811cafe471acd490114b103a1f8392c8d8), [`8bddd62`](https://github.com/Effect-TS/effect-smol/commit/8bddd628cb623f9533d345082583ff51cead6836), [`4be4c8d`](https://github.com/Effect-TS/effect-smol/commit/4be4c8d60862aa963869ee2ed9ffa048ffac0527), [`0c9d3ab`](https://github.com/Effect-TS/effect-smol/commit/0c9d3ab43eb721a370ed8306260cbac218c27e87), [`b156acc`](https://github.com/Effect-TS/effect-smol/commit/b156accd2691b4a051f823affdece7c39923ce85), [`d16c034`](https://github.com/Effect-TS/effect-smol/commit/d16c03434ee3e6dcd3bfc82b65d99e881d89025b), [`b559d68`](https://github.com/Effect-TS/effect-smol/commit/b559d68845f848a10153395778f035682d399075), [`a3de5d9`](https://github.com/Effect-TS/effect-smol/commit/a3de5d9215e5cc4a62e2666efbd7c1bf595eb84f), [`7e6c12e`](https://github.com/Effect-TS/effect-smol/commit/7e6c12ec9b3a5945f6c26e272cc8f6390541ad3e), [`098167a`](https://github.com/Effect-TS/effect-smol/commit/098167a220fe07da6f14455818733ab1b269c9dd)]:
|
||||
- effect@4.0.0-beta.67
|
||||
|
||||
## 4.0.0-beta.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ca2498e`](https://github.com/Effect-TS/effect-smol/commit/ca2498e702ac2d83fb7187707b7eb069bdb261a2), [`cd7d1fb`](https://github.com/Effect-TS/effect-smol/commit/cd7d1fba7e2e2c5ac3ad64e1be433440a5bda436), [`19a7033`](https://github.com/Effect-TS/effect-smol/commit/19a703367ec817cffc41d152da9b594827408e2b), [`33d26b4`](https://github.com/Effect-TS/effect-smol/commit/33d26b4210b2e974f146a71e7eed962f8ce00900), [`856766b`](https://github.com/Effect-TS/effect-smol/commit/856766b2c506aaed6d2df1d63bf3a5b1b062e1d4), [`079c7df`](https://github.com/Effect-TS/effect-smol/commit/079c7df82559bb9ce10a86dffb85d25e6ce07dc3)]:
|
||||
- effect@4.0.0-beta.66
|
||||
|
||||
## 4.0.0-beta.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6f11454`](https://github.com/Effect-TS/effect-smol/commit/6f11454a9b6c3bd00f6b35fd7af14a2f2d63a0a2)]:
|
||||
- effect@4.0.0-beta.65
|
||||
|
||||
## 4.0.0-beta.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d4877a`](https://github.com/Effect-TS/effect-smol/commit/7d4877a1929cdb690280ea254326c04f2ec97ea5)]:
|
||||
- effect@4.0.0-beta.64
|
||||
|
||||
## 4.0.0-beta.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7f927ff`](https://github.com/Effect-TS/effect-smol/commit/7f927ffb7a9801dcfc4096c29e369d13d65cd0ac), [`a696b3e`](https://github.com/Effect-TS/effect-smol/commit/a696b3e83a8504cdbe261a18c10a1cc0619ae102)]:
|
||||
- effect@4.0.0-beta.63
|
||||
|
||||
## 4.0.0-beta.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4ab4b90`](https://github.com/Effect-TS/effect-smol/commit/4ab4b9007dc27a52ffabc6fcb37c96eeec795bf7)]:
|
||||
- effect@4.0.0-beta.62
|
||||
|
||||
## 4.0.0-beta.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`50790af`](https://github.com/Effect-TS/effect-smol/commit/50790af9b190c38d10fb0723837d49b66432638f), [`71f7c3d`](https://github.com/Effect-TS/effect-smol/commit/71f7c3df997deda92c84146d569696dab3bd645c), [`aae8797`](https://github.com/Effect-TS/effect-smol/commit/aae8797b9cb383be0c182dd58d03d787c354238b)]:
|
||||
- effect@4.0.0-beta.61
|
||||
|
||||
## 4.0.0-beta.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f69d567`](https://github.com/Effect-TS/effect-smol/commit/f69d5675dcff9f4137295752baf066b7153fdc09), [`7909c95`](https://github.com/Effect-TS/effect-smol/commit/7909c954b8f6244a35a4b429f8dd0dff45dad620), [`bbb4dcc`](https://github.com/Effect-TS/effect-smol/commit/bbb4dcc6c406b83a416b4ad3541cc02037c420e4), [`7af2207`](https://github.com/Effect-TS/effect-smol/commit/7af2207901eabf3132c1b7010a69b3899c06fbbe), [`848b40a`](https://github.com/Effect-TS/effect-smol/commit/848b40a4bd4bf54a5098617d50c33c88eee8270a)]:
|
||||
- effect@4.0.0-beta.60
|
||||
|
||||
## 4.0.0-beta.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`56837ea`](https://github.com/Effect-TS/effect-smol/commit/56837ea2a338395b35550641374e9e589bd8b71d)]:
|
||||
- effect@4.0.0-beta.59
|
||||
|
||||
## 4.0.0-beta.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`11993d4`](https://github.com/Effect-TS/effect-smol/commit/11993d4934c66f5dc611b8bbf553f01d501ef8f7), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec)]:
|
||||
- effect@4.0.0-beta.58
|
||||
|
||||
## 4.0.0-beta.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a971f5c`](https://github.com/Effect-TS/effect-smol/commit/a971f5cbd92dfe4274420bf0966595eb35531060), [`8e110c5`](https://github.com/Effect-TS/effect-smol/commit/8e110c5f02a429ccc43a91df8678e402138c0851)]:
|
||||
- effect@4.0.0-beta.57
|
||||
|
||||
## 4.0.0-beta.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.56
|
||||
|
||||
## 4.0.0-beta.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42cc744`](https://github.com/Effect-TS/effect-smol/commit/42cc744570968deb365fb46d47b53d3277050c93), [`04855ce`](https://github.com/Effect-TS/effect-smol/commit/04855ceeca4d40c55a5750dd9893b691f8ea741a)]:
|
||||
- effect@4.0.0-beta.55
|
||||
|
||||
## 4.0.0-beta.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e4b74f9`](https://github.com/Effect-TS/effect-smol/commit/e4b74f9c01a0e9b6cd58416de4af3a26d51da7c8), [`4c72808`](https://github.com/Effect-TS/effect-smol/commit/4c728081851c66dacf889a816535671bc841ae96)]:
|
||||
- effect@4.0.0-beta.54
|
||||
|
||||
## 4.0.0-beta.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0768509`](https://github.com/Effect-TS/effect-smol/commit/07685094e931af07d104165195826a535b55fa7e), [`476aede`](https://github.com/Effect-TS/effect-smol/commit/476aede69c6efa06b5781ca5eb3e3b128ca29141), [`4f79c54`](https://github.com/Effect-TS/effect-smol/commit/4f79c542e7b508c235ff485d862cc8b29a8260c5), [`4be6a7c`](https://github.com/Effect-TS/effect-smol/commit/4be6a7cf35dab2a01d652f56dd35f0358c5a7e88), [`88927eb`](https://github.com/Effect-TS/effect-smol/commit/88927ebb896162cdba103b36553280b58e0facac)]:
|
||||
- effect@4.0.0-beta.53
|
||||
|
||||
## 4.0.0-beta.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`cf3a311`](https://github.com/Effect-TS/effect-smol/commit/cf3a311d863a8abb818840c3b80f847e621c43c1), [`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`131fdd5`](https://github.com/Effect-TS/effect-smol/commit/131fdd5b1f26531e265fe1a08f002002f47c276e)]:
|
||||
- effect@4.0.0-beta.52
|
||||
|
||||
## 4.0.0-beta.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`778d2af`](https://github.com/Effect-TS/effect-smol/commit/778d2afe9b5154bc1f9abae46d93ea7e54c87344), [`4e24dcf`](https://github.com/Effect-TS/effect-smol/commit/4e24dcf75037f65eebc1eb68623bc7cbf9d5512a), [`4b1c015`](https://github.com/Effect-TS/effect-smol/commit/4b1c0150e9bdb5559ed32d250deb66e17b4240c7), [`454f8ad`](https://github.com/Effect-TS/effect-smol/commit/454f8adad822929c3ef60f8280d0987226b049fd), [`6754a0c`](https://github.com/Effect-TS/effect-smol/commit/6754a0cd18626b06805a079cc5265525a5eb7d27), [`90f7fd5`](https://github.com/Effect-TS/effect-smol/commit/90f7fd5243871b30980964135db4512b8119fa82), [`d7e1519`](https://github.com/Effect-TS/effect-smol/commit/d7e151974934201fd93fa4c8a1192ee9a5d965a0), [`72a8122`](https://github.com/Effect-TS/effect-smol/commit/72a81228e09782bae512f7d041bbfbc78bc668d0)]:
|
||||
- effect@4.0.0-beta.51
|
||||
|
||||
## 4.0.0-beta.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`07be594`](https://github.com/Effect-TS/effect-smol/commit/07be594825de60f8e1b2102d21dbb9b8fc63b414), [`ae02433`](https://github.com/Effect-TS/effect-smol/commit/ae02433103ce28f53a0c9bfb4a44e75773289b7b)]:
|
||||
- effect@4.0.0-beta.50
|
||||
|
||||
## 4.0.0-beta.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d87873`](https://github.com/Effect-TS/effect-smol/commit/7d8787340ff549370f6f2a88b612e9ebbfd6ba45), [`c2f6f90`](https://github.com/Effect-TS/effect-smol/commit/c2f6f901b200a6e515b4f02c93ce8005b7bbf1c5), [`216f13c`](https://github.com/Effect-TS/effect-smol/commit/216f13c1fce454a21b489bb915714a17e791a1ac)]:
|
||||
- effect@4.0.0-beta.49
|
||||
|
||||
## 4.0.0-beta.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4da56ec`](https://github.com/Effect-TS/effect-smol/commit/4da56ecff129b2da40137ffede23a73cc4e532d8), [`a5e6f77`](https://github.com/Effect-TS/effect-smol/commit/a5e6f774bab195cf50ecdc818240765f69a3bf4a), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070)]:
|
||||
- effect@4.0.0-beta.48
|
||||
|
||||
## 4.0.0-beta.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c584726`](https://github.com/Effect-TS/effect-smol/commit/c58472674e750e6938df955044eab88feda95e45), [`86a91a4`](https://github.com/Effect-TS/effect-smol/commit/86a91a4f0c59286dfa9393232d8020dea70ed4db), [`131caf9`](https://github.com/Effect-TS/effect-smol/commit/131caf9525151a0cb29803a8f1dffa0f4f479d12), [`c3615c8`](https://github.com/Effect-TS/effect-smol/commit/c3615c88379b9daf252df0db72c6ac5a20326406)]:
|
||||
- effect@4.0.0-beta.47
|
||||
|
||||
## 4.0.0-beta.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a30b9e`](https://github.com/Effect-TS/effect-smol/commit/3a30b9e2ec2bd8b8193e1aa139f6878a07e3f5ee)]:
|
||||
- effect@4.0.0-beta.46
|
||||
|
||||
## 4.0.0-beta.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c3af6d`](https://github.com/Effect-TS/effect-smol/commit/5c3af6d554f60be34f8fc21d598d9a298ae11beb)]:
|
||||
- effect@4.0.0-beta.45
|
||||
|
||||
## 4.0.0-beta.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1961](https://github.com/Effect-TS/effect-smol/pull/1961) [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970) Thanks @IMax153! - Rename the `ServiceMap` module to `Context` across exports, docs, and tests.
|
||||
|
||||
- Updated dependencies [[`e3f0621`](https://github.com/Effect-TS/effect-smol/commit/e3f0621454c3f5d11070d30619da27c9232cadc1), [`5b476ab`](https://github.com/Effect-TS/effect-smol/commit/5b476abc0bd7e9bb59135ea1bcad2e4936227ced), [`6b40e5a`](https://github.com/Effect-TS/effect-smol/commit/6b40e5a4a6bd2087c15a3d7374d25057fdedfa16), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`3b09fb3`](https://github.com/Effect-TS/effect-smol/commit/3b09fb31c40c2802b01f21c23bcdd1fe7fb0aa82), [`2370410`](https://github.com/Effect-TS/effect-smol/commit/237041062e5af4594d32db91597e34e70a632877), [`dabc272`](https://github.com/Effect-TS/effect-smol/commit/dabc272444a700eb629c07ba3e77671a841ca86e), [`08b63c3`](https://github.com/Effect-TS/effect-smol/commit/08b63c3df11bd35c9fd6090dbd166287fdc40664), [`dfff04c`](https://github.com/Effect-TS/effect-smol/commit/dfff04c4c2b1d352dfad83992a6dce1280c85cf9), [`9baed9e`](https://github.com/Effect-TS/effect-smol/commit/9baed9e17e84702e6e480fcef6f86404f9e24be9), [`7846792`](https://github.com/Effect-TS/effect-smol/commit/7846792adc7e1631d62d26d657bd7ba6139f369b), [`1556a24`](https://github.com/Effect-TS/effect-smol/commit/1556a247623636b7ebe438fb56d77f1a7bf957bb), [`7c11bc2`](https://github.com/Effect-TS/effect-smol/commit/7c11bc292ab8e46252fe8f7576fb685917bfb8b5), [`b5ea591`](https://github.com/Effect-TS/effect-smol/commit/b5ea5913ec1d45d0dd12a327b9dd966bda2f6d02), [`0853afa`](https://github.com/Effect-TS/effect-smol/commit/0853afaeb1633b2d7f8b66893bd01c3aa1ef2c22), [`ac845f3`](https://github.com/Effect-TS/effect-smol/commit/ac845f3ab40e0b8719576e7f9bc16ea2e0e02cd4), [`b80c462`](https://github.com/Effect-TS/effect-smol/commit/b80c46247480f47bb64fc480fab48a3f37bc8888), [`b3f535d`](https://github.com/Effect-TS/effect-smol/commit/b3f535d9a7ac13b5fb984c29f93561c57a081ff0), [`6fe2e93`](https://github.com/Effect-TS/effect-smol/commit/6fe2e93cc2f1b173ef89651d74b6a5d2626b3226), [`cda8004`](https://github.com/Effect-TS/effect-smol/commit/cda800451c1ffbdddfc08415aed7b2d91e0412ee), [`8335477`](https://github.com/Effect-TS/effect-smol/commit/8335477a8a936a24b5f3ee6203c1b268bd1bfc3c), [`8c836f9`](https://github.com/Effect-TS/effect-smol/commit/8c836f99ab1e896b9580a71d67773625baff2eaf), [`718ff6f`](https://github.com/Effect-TS/effect-smol/commit/718ff6fe3e3d3820cefd67d2bff1b2224fe08060), [`7eed84f`](https://github.com/Effect-TS/effect-smol/commit/7eed84fc33c5781a6fb11bf4fd189d424902ebd4), [`5df46fe`](https://github.com/Effect-TS/effect-smol/commit/5df46fe2f654d59ab5fc1578f4fc27fa40368ef9), [`82dd0f2`](https://github.com/Effect-TS/effect-smol/commit/82dd0f26c6442b07143762ef7bc33742d3978dd6), [`03ae41e`](https://github.com/Effect-TS/effect-smol/commit/03ae41e7304cffac9f18feea22b73468feafc43a), [`4677a0a`](https://github.com/Effect-TS/effect-smol/commit/4677a0a58f95eea38a211efcd3f345f237a9e44a), [`87e1fc8`](https://github.com/Effect-TS/effect-smol/commit/87e1fc8b67e4901d75f567b2fecc3841ab762cc4), [`c1af1b7`](https://github.com/Effect-TS/effect-smol/commit/c1af1b756f63291e9c0298cf95c98a6920a0c2a0), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`c8a877b`](https://github.com/Effect-TS/effect-smol/commit/c8a877b53e8f29616335719e5dd1c3992dddf780), [`7da961a`](https://github.com/Effect-TS/effect-smol/commit/7da961ae4916229d2246699a5d3b20e5b2dd2020)]:
|
||||
- effect@4.0.0-beta.44
|
||||
|
||||
## 4.0.0-beta.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`2ae33d0`](https://github.com/Effect-TS/effect-smol/commit/2ae33d050914915f7cb9c25ab0a020901e08d596), [`979811a`](https://github.com/Effect-TS/effect-smol/commit/979811a4c3f7ed21ed18ef560c49fb7f5569e80e), [`eb7dbef`](https://github.com/Effect-TS/effect-smol/commit/eb7dbeffa883386ad912815e62c0820cac1fdf8e), [`cf50eb4`](https://github.com/Effect-TS/effect-smol/commit/cf50eb49cb04706dae5185f624708117c413dee8), [`1d046fe`](https://github.com/Effect-TS/effect-smol/commit/1d046fe484560e23f3e22cb23eec6433f8f1fa02)]:
|
||||
- effect@4.0.0-beta.43
|
||||
|
||||
## 4.0.0-beta.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`924e216`](https://github.com/Effect-TS/effect-smol/commit/924e216caa7e0bbf22e994a0cd2ce8b1f0f0b3ee), [`80e7f0c`](https://github.com/Effect-TS/effect-smol/commit/80e7f0cd9116e811e97b0ce30a77a8d1ecd072aa), [`f8328bf`](https://github.com/Effect-TS/effect-smol/commit/f8328bf0314da3dc7f31d314f94a5840e8d5217f), [`66d1c06`](https://github.com/Effect-TS/effect-smol/commit/66d1c06039079129707a230f7ad8c676439d7133), [`bee800b`](https://github.com/Effect-TS/effect-smol/commit/bee800bf285192a01bec72a7b7b51bc1159434e6), [`8930441`](https://github.com/Effect-TS/effect-smol/commit/8930441dee6f94c59c583d18d3ebd677cf1f2623)]:
|
||||
- effect@4.0.0-beta.42
|
||||
|
||||
## 4.0.0-beta.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`36f5c21`](https://github.com/Effect-TS/effect-smol/commit/36f5c2174d31ab42c4598bf81f178f40d0802283), [`d8ce758`](https://github.com/Effect-TS/effect-smol/commit/d8ce758669d6297ae932ac3251d83e7b49b22f30), [`11aab4c`](https://github.com/Effect-TS/effect-smol/commit/11aab4c6d37d5691adafc2d33da1a631b28ce814), [`3bc1efb`](https://github.com/Effect-TS/effect-smol/commit/3bc1efb53dd75b4a40de46f1f80c7f8a7d50af86), [`70e724e`](https://github.com/Effect-TS/effect-smol/commit/70e724e604604d4be1061cd8da0d360494998c84), [`738dee7`](https://github.com/Effect-TS/effect-smol/commit/738dee7edfd70af82dc4d2376db3a8ebe603eb48), [`2111963`](https://github.com/Effect-TS/effect-smol/commit/2111963f19b4c28c800664a8fac9590c1321885f), [`198a553`](https://github.com/Effect-TS/effect-smol/commit/198a553d9ce45f6a00bfc4d65ed0640669602d95)]:
|
||||
- effect@4.0.0-beta.41
|
||||
|
||||
## 4.0.0-beta.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f62860f`](https://github.com/Effect-TS/effect-smol/commit/f62860f0e5e45978fabf7256ae620a13152a772a), [`973f281`](https://github.com/Effect-TS/effect-smol/commit/973f2812529aadc1cc54598b2039799fa72b80f8)]:
|
||||
- effect@4.0.0-beta.40
|
||||
|
||||
## 4.0.0-beta.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f91fd3d`](https://github.com/Effect-TS/effect-smol/commit/f91fd3db39fe5628439fd175fba201a65a1aa9d0), [`edaae9d`](https://github.com/Effect-TS/effect-smol/commit/edaae9d65f464f941d7eddd723cd33d324f4b071), [`b47db0b`](https://github.com/Effect-TS/effect-smol/commit/b47db0bd5802064b6a24b3ea27c6ff2e0520d513), [`82d3c8e`](https://github.com/Effect-TS/effect-smol/commit/82d3c8e4f3f49b00df611b25aa6f8f74ec21b59b), [`7c22b31`](https://github.com/Effect-TS/effect-smol/commit/7c22b315d198dcbf44ae8cdb8b37879e1c9e3996)]:
|
||||
- effect@4.0.0-beta.39
|
||||
|
||||
## 4.0.0-beta.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f4dbe5b`](https://github.com/Effect-TS/effect-smol/commit/f4dbe5b26b9c2d33fae024bf44afbdf8541792cd), [`a71a607`](https://github.com/Effect-TS/effect-smol/commit/a71a607c89fb6669a12a562c2c23be81dfbe1adb), [`66a0494`](https://github.com/Effect-TS/effect-smol/commit/66a0494ed75cd12f2721dcbb1d8a072e3d9e14b6), [`5ef7218`](https://github.com/Effect-TS/effect-smol/commit/5ef7218fc559d57301fe929b8a0cab4033f4f1fd), [`472d260`](https://github.com/Effect-TS/effect-smol/commit/472d260655bc311fba5c2c6e23bb77d8f7e36ba0)]:
|
||||
- effect@4.0.0-beta.38
|
||||
|
||||
## 4.0.0-beta.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f7a0b71`](https://github.com/Effect-TS/effect-smol/commit/f7a0b711da8fdd645597dee29cacc5619c6afcf2), [`1e223c3`](https://github.com/Effect-TS/effect-smol/commit/1e223c30ccf835dfbb21284535d78549efaeca80), [`53740f4`](https://github.com/Effect-TS/effect-smol/commit/53740f47aa76d114b7d535649fb50efc54a09608), [`8c7cf89`](https://github.com/Effect-TS/effect-smol/commit/8c7cf89f719e580cbce1bf6c24e6996f1992a0a6), [`b6b81a9`](https://github.com/Effect-TS/effect-smol/commit/b6b81a940eaafcbc792d25413d6c02c707de31b2), [`8f4c1f9`](https://github.com/Effect-TS/effect-smol/commit/8f4c1f97ed60f8810b0b327b50117ffb2d8260d4), [`f2479f9`](https://github.com/Effect-TS/effect-smol/commit/f2479f9d3113b1f012db17a3852b4e28f478cf9c), [`c919921`](https://github.com/Effect-TS/effect-smol/commit/c9199217fad65529421d2cf95ecfff41257090fd), [`7af90c2`](https://github.com/Effect-TS/effect-smol/commit/7af90c2e3c99038eafa39650433839523790e2fe), [`f3be185`](https://github.com/Effect-TS/effect-smol/commit/f3be18569e5ca57c25eabf00df3ca601ebab43c7)]:
|
||||
- effect@4.0.0-beta.37
|
||||
|
||||
## 4.0.0-beta.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1775](https://github.com/Effect-TS/effect-smol/pull/1775) [`954e6d6`](https://github.com/Effect-TS/effect-smol/commit/954e6d655cd32d329b0bfeb872bb654f88b48a13) Thanks @tim-smart! - Add dynamic tool support to the Anthropic language model provider when preparing tool definitions for requests.
|
||||
|
||||
- Updated dependencies [[`60fcbcc`](https://github.com/Effect-TS/effect-smol/commit/60fcbcc43d09471e8f7e0969955d99dcefc5be81), [`0a60837`](https://github.com/Effect-TS/effect-smol/commit/0a6083713124440e630030375bab367e8d7df24e), [`49164d2`](https://github.com/Effect-TS/effect-smol/commit/49164d2c20a8d21b66514992c4a15d8521f6b36e), [`334b6e4`](https://github.com/Effect-TS/effect-smol/commit/334b6e4f76fe11941b516d61f57e268bc31f0ca6), [`5700695`](https://github.com/Effect-TS/effect-smol/commit/5700695f76ae6da6b94c9c87d4dd2b8054fb829b), [`f8f4456`](https://github.com/Effect-TS/effect-smol/commit/f8f445644f3aa7ec093cab7445198a62ba18a480), [`969d24f`](https://github.com/Effect-TS/effect-smol/commit/969d24fdfa48c4838e811983848d9cb4e9b3b12c), [`851eda0`](https://github.com/Effect-TS/effect-smol/commit/851eda0533946e39bacaaf581896320d7a4f3e8c), [`8059c1c`](https://github.com/Effect-TS/effect-smol/commit/8059c1c3eba9a90af7cd889ea261bcb8fff0c185), [`6f83295`](https://github.com/Effect-TS/effect-smol/commit/6f8329546a73eaddc7cb5e85ea8e37e73fbfb611), [`65f7f57`](https://github.com/Effect-TS/effect-smol/commit/65f7f5737575fed668987462c96d29a446707c32), [`e7fabd2`](https://github.com/Effect-TS/effect-smol/commit/e7fabd2265db690eae5cfc9b83730c84699aef61), [`89c3e98`](https://github.com/Effect-TS/effect-smol/commit/89c3e985401eb38f33a3ae21a94ad27de3c1d28b), [`53794ab`](https://github.com/Effect-TS/effect-smol/commit/53794ab7af30aa5c5004ecf53659fafbe4b10542)]:
|
||||
- effect@4.0.0-beta.36
|
||||
|
||||
## 4.0.0-beta.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9252b43`](https://github.com/Effect-TS/effect-smol/commit/9252b43560f507709c2985abcf52a7837b23ddf8), [`7daf387`](https://github.com/Effect-TS/effect-smol/commit/7daf3870a656882a488a60f67881e6808c8f4d04), [`e1664a3`](https://github.com/Effect-TS/effect-smol/commit/e1664a38bc31ef4ceb4e9324c7226e1e99bf9c07), [`fdaa6e0`](https://github.com/Effect-TS/effect-smol/commit/fdaa6e0a41b6b6605438fa8557441792135380a2), [`19aa47e`](https://github.com/Effect-TS/effect-smol/commit/19aa47ef7b470e427620edca8970dd9cdd551216), [`c667dad`](https://github.com/Effect-TS/effect-smol/commit/c667dad07777b860e4764a3ba9a6cc41c236cd98), [`764d150`](https://github.com/Effect-TS/effect-smol/commit/764d1501bc5026b60fc8aef6cb02a5a87c762801), [`3c27098`](https://github.com/Effect-TS/effect-smol/commit/3c27098b5685a63db2c2eff654a250c94d3fcfa7)]:
|
||||
- effect@4.0.0-beta.35
|
||||
|
||||
## 4.0.0-beta.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1763](https://github.com/Effect-TS/effect-smol/pull/1763) [`2fa940d`](https://github.com/Effect-TS/effect-smol/commit/2fa940d0709769c5fd1337c1f88400867f91989b) Thanks @teeverc! - Remove duplicate `ToolApprovalResponsePartOptions` from Anthropic package
|
||||
|
||||
- Updated dependencies [[`f2f75ee`](https://github.com/Effect-TS/effect-smol/commit/f2f75ee564bce1cd95f5189c7bdeeed4f92dacb1), [`342fc4b`](https://github.com/Effect-TS/effect-smol/commit/342fc4b051739e32e7977159f26ff9541eda664f), [`5d704ee`](https://github.com/Effect-TS/effect-smol/commit/5d704ee10d20e8eb107e34bb8a21feb5aa4a7685), [`00add69`](https://github.com/Effect-TS/effect-smol/commit/00add69b59551e9df34772eb927638b093f6d71e), [`58217d3`](https://github.com/Effect-TS/effect-smol/commit/58217d318a7d716ccd707cce0f41573946939c28), [`f4e2aba`](https://github.com/Effect-TS/effect-smol/commit/f4e2aba01b76d1e3059b297e3cc942284dfeafb2), [`e3b44b6`](https://github.com/Effect-TS/effect-smol/commit/e3b44b6a2af9ee21dc5c1e928f0c20af857fa7a9), [`e1472b7`](https://github.com/Effect-TS/effect-smol/commit/e1472b7525c5d57a48bdec2353c3b742f7f916c0), [`7686320`](https://github.com/Effect-TS/effect-smol/commit/7686320cd123fa352b5c3d076fb18a3cac0a9bba)]:
|
||||
- effect@4.0.0-beta.34
|
||||
|
||||
## 4.0.0-beta.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`571447d`](https://github.com/Effect-TS/effect-smol/commit/571447da67334449f8ae3d6ecb3d77ea4e0c4295)]:
|
||||
- effect@4.0.0-beta.33
|
||||
|
||||
## 4.0.0-beta.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf8fff8`](https://github.com/Effect-TS/effect-smol/commit/bf8fff8a5f54b6df74cb7bbb42346fe9ba52435a), [`1af3ef3`](https://github.com/Effect-TS/effect-smol/commit/1af3ef3e3ca7fd417d0fc15f8ca8fe207eba4f74), [`27fea0f`](https://github.com/Effect-TS/effect-smol/commit/27fea0f66910de5905f40fd63f8ddbb6f7ac5aba), [`2ad6c1b`](https://github.com/Effect-TS/effect-smol/commit/2ad6c1b2c85a3a0fe351e3d56636a75eb76b4b4e), [`398ac3e`](https://github.com/Effect-TS/effect-smol/commit/398ac3e01cb75efce0e4e2913d1450cf65866732), [`51fe22f`](https://github.com/Effect-TS/effect-smol/commit/51fe22f3266e417b6c541aaed4b75d246fac91e7), [`4605db6`](https://github.com/Effect-TS/effect-smol/commit/4605db69cfacddbdbf1525865ddfde135158090c), [`f4de1b0`](https://github.com/Effect-TS/effect-smol/commit/f4de1b087c998d0bad1d9468f70b7d16c13b9f6f), [`60214f2`](https://github.com/Effect-TS/effect-smol/commit/60214f2080b2aeb091f691140eb20acb741691c3), [`c4b8b0f`](https://github.com/Effect-TS/effect-smol/commit/c4b8b0ffa8efb47c4cd7578a8943d6868509373f), [`6d9393a`](https://github.com/Effect-TS/effect-smol/commit/6d9393a0770a18722d23340e77f15455de341245), [`6de4efe`](https://github.com/Effect-TS/effect-smol/commit/6de4efe463c783614ceb0c094d77a336a899cbe0), [`4f969d1`](https://github.com/Effect-TS/effect-smol/commit/4f969d1563ba755ffa116c8ae409bb3436bd881d), [`6cc67c8`](https://github.com/Effect-TS/effect-smol/commit/6cc67c855e054ee3f3ac3485dca5f7805e79e8fb), [`8531a22`](https://github.com/Effect-TS/effect-smol/commit/8531a22ffbb52e11a030b09f358cafbfdf5edff7), [`b226760`](https://github.com/Effect-TS/effect-smol/commit/b22676067617f15c00722a3a63fd7c2c172c3d45), [`47a51ab`](https://github.com/Effect-TS/effect-smol/commit/47a51aba0ecdf3ef478bfa28a498bca188399bd4), [`1521d02`](https://github.com/Effect-TS/effect-smol/commit/1521d02e1f19f1d795edaaf862c1a1031d9c755e)]:
|
||||
- effect@4.0.0-beta.32
|
||||
|
||||
## 4.0.0-beta.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6f23f0e`](https://github.com/Effect-TS/effect-smol/commit/6f23f0ed4cba573cd9395c2e582f582fe7271544), [`654aaec`](https://github.com/Effect-TS/effect-smol/commit/654aaec593305521b65dd042c204d761cc6e8c28), [`2958a42`](https://github.com/Effect-TS/effect-smol/commit/2958a42078966a8713a98f00485ab36484d5eccf), [`95d27a2`](https://github.com/Effect-TS/effect-smol/commit/95d27a239ed5147302605ab0b3147a056541b0c7), [`0fbaea8`](https://github.com/Effect-TS/effect-smol/commit/0fbaea8f9555a8044cec31a770394db613fc78e2), [`21d5d5e`](https://github.com/Effect-TS/effect-smol/commit/21d5d5e0439fd4d9bb6e508377215b1087555d45), [`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6e49959`](https://github.com/Effect-TS/effect-smol/commit/6e499590357a104c81779b3176cd3f84e4f91064), [`8f5805d`](https://github.com/Effect-TS/effect-smol/commit/8f5805dbdd0d1bc0ff0727cc398c8d80e544edee), [`990df2c`](https://github.com/Effect-TS/effect-smol/commit/990df2c3ceeb32e659acc10cc9485617f7b3c423)]:
|
||||
- effect@4.0.0-beta.31
|
||||
|
||||
## 4.0.0-beta.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c88e5b7`](https://github.com/Effect-TS/effect-smol/commit/c88e5b723ff09da4edaef6ce14d927ca01104a32), [`947d0e4`](https://github.com/Effect-TS/effect-smol/commit/947d0e4268ba5c4020ead380aa80812c7342408f), [`7517908`](https://github.com/Effect-TS/effect-smol/commit/75179085d159b88a1ab0bce70669d76dcf0d79a4), [`a49ecd5`](https://github.com/Effect-TS/effect-smol/commit/a49ecd5a183d7e7d33f47ff95e9d2dea5a12ead5), [`6993e33`](https://github.com/Effect-TS/effect-smol/commit/6993e3329122c834c20bacea72d8678232f4f103), [`514f2a2`](https://github.com/Effect-TS/effect-smol/commit/514f2a2ae54580fcacdbe2ea2196a83a852d0748), [`3214b47`](https://github.com/Effect-TS/effect-smol/commit/3214b47676de2d33fddc5fecfc2d226e6e83cc7b), [`95ec5ed`](https://github.com/Effect-TS/effect-smol/commit/95ec5ed345de77c893049e182d37a37cf164a268)]:
|
||||
- effect@4.0.0-beta.30
|
||||
|
||||
## 4.0.0-beta.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9d93adb`](https://github.com/Effect-TS/effect-smol/commit/9d93adb1c1795d1978391b30d7d2972c88052662), [`b52721c`](https://github.com/Effect-TS/effect-smol/commit/b52721cf0d11a567722b060c8536e3bdd4161f07), [`a891c7b`](https://github.com/Effect-TS/effect-smol/commit/a891c7b12f415b2287613dd4b91a09dfd38ef30d), [`ef26cdf`](https://github.com/Effect-TS/effect-smol/commit/ef26cdfb65d9955fc7e161629191930c2cc2c63f), [`82fd3ed`](https://github.com/Effect-TS/effect-smol/commit/82fd3ed922063ee5a34f96f3993c15c7515e4f67)]:
|
||||
- effect@4.0.0-beta.29
|
||||
|
||||
## 4.0.0-beta.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ff533f2`](https://github.com/Effect-TS/effect-smol/commit/ff533f203cd06302ad08032a27e01269b4a2d4c6), [`dc803ee`](https://github.com/Effect-TS/effect-smol/commit/dc803ee52ebd3e9f931118f0dfcb804542847556), [`d660b1c`](https://github.com/Effect-TS/effect-smol/commit/d660b1c99cb93d4f79715e91c7a4486801c0eefa), [`93a05e3`](https://github.com/Effect-TS/effect-smol/commit/93a05e3eaa624058b162aedd66aad70102837270), [`2a65cf6`](https://github.com/Effect-TS/effect-smol/commit/2a65cf6fd81ef63d944e6fb51f058d439bf4a834), [`a561a40`](https://github.com/Effect-TS/effect-smol/commit/a561a40cc41c548c2cf3153aca065ee92ee8aa57), [`29cd24d`](https://github.com/Effect-TS/effect-smol/commit/29cd24d1fe78480a72eeb38a90281ffddc0530bc), [`662a8e6`](https://github.com/Effect-TS/effect-smol/commit/662a8e6857dac64a7cd13bd8df4b0674654622f8), [`d2b52ba`](https://github.com/Effect-TS/effect-smol/commit/d2b52bae5b9336cf59729fbdcc4d7f09512b0cbf), [`407c3b4`](https://github.com/Effect-TS/effect-smol/commit/407c3b43a5d1414558e0e33b6f1fc0e6a6d489cc), [`42bc7ce`](https://github.com/Effect-TS/effect-smol/commit/42bc7ce5480f6f2953c39f8cb5c850d61df6f5a2), [`e741322`](https://github.com/Effect-TS/effect-smol/commit/e74132226cbfee24234311c7c1c13e6b7391384e), [`5c75fa8`](https://github.com/Effect-TS/effect-smol/commit/5c75fa8fb71163bc4c035ba1a215574dfd4badfc), [`747177b`](https://github.com/Effect-TS/effect-smol/commit/747177b0602f12d4461a843e953dfdffbeb0a429), [`326cd48`](https://github.com/Effect-TS/effect-smol/commit/326cd4828bce573fe985f35152155464bf4c5a70), [`627e922`](https://github.com/Effect-TS/effect-smol/commit/627e922b8d1e9521eae5e1caa5d667ad00b1619a), [`662287e`](https://github.com/Effect-TS/effect-smol/commit/662287e9abc76c941ccc2ee330aa07904d571341)]:
|
||||
- effect@4.0.0-beta.28
|
||||
|
||||
## 4.0.0-beta.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`903a839`](https://github.com/Effect-TS/effect-smol/commit/903a839e94239e6ec4568315af28e405bcad95f4), [`91a0168`](https://github.com/Effect-TS/effect-smol/commit/91a016836680a6669308ecf464d3584bcc4ae1b7), [`c890f9a`](https://github.com/Effect-TS/effect-smol/commit/c890f9a1b3a989ed22528bd5a43326342e05b142), [`1e985f2`](https://github.com/Effect-TS/effect-smol/commit/1e985f237d250b51b91de22dde77160c1e778ce7)]:
|
||||
- effect@4.0.0-beta.27
|
||||
|
||||
## 4.0.0-beta.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fb21462`](https://github.com/Effect-TS/effect-smol/commit/fb21462642cdd5b1bada92f3eba18ae20445be42), [`2ed26b1`](https://github.com/Effect-TS/effect-smol/commit/2ed26b139805700e3df39efaa768ff01565e5c86), [`e832a57`](https://github.com/Effect-TS/effect-smol/commit/e832a57b570fe38f010c1fd99bceac5a325a9e07), [`7f01be7`](https://github.com/Effect-TS/effect-smol/commit/7f01be7f8db363d4b2e88e6b5571e96bb815786f), [`e965143`](https://github.com/Effect-TS/effect-smol/commit/e9651431e114479e6becf8ca7b1ed99ac7e91ccc), [`b9b80f1`](https://github.com/Effect-TS/effect-smol/commit/b9b80f1f15e152ceef0a727d150b7dc230abae99), [`98252aa`](https://github.com/Effect-TS/effect-smol/commit/98252aa0c0b17fc73fbdad65d0a1104965f9fc0f), [`56fbd94`](https://github.com/Effect-TS/effect-smol/commit/56fbd94311ad19a05001ad649d9e34ab00c74541), [`3faa109`](https://github.com/Effect-TS/effect-smol/commit/3faa109b7d093fbf14ad410d3e11d663f16e28f1), [`692ecfe`](https://github.com/Effect-TS/effect-smol/commit/692ecfed99fe58056b7a5afe001f4fcd1a61c446), [`1e70b72`](https://github.com/Effect-TS/effect-smol/commit/1e70b72d0b210474d0e96a15a5cfc279eae37e0c), [`ecf0782`](https://github.com/Effect-TS/effect-smol/commit/ecf07829ef2dfc01d8943c96c4fe9c1b44b97926)]:
|
||||
- effect@4.0.0-beta.26
|
||||
|
||||
## 4.0.0-beta.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fa17bb5`](https://github.com/Effect-TS/effect-smol/commit/fa17bb5be9f2533d01e11322b14804c7dec43714), [`f46e5b5`](https://github.com/Effect-TS/effect-smol/commit/f46e5b5ca2a918ee4d9270167e79db223077c96f), [`ce4767c`](https://github.com/Effect-TS/effect-smol/commit/ce4767cadcacc6ce8ff4c3a0d0fbc82ede655f63), [`c830a8b`](https://github.com/Effect-TS/effect-smol/commit/c830a8b6c292a6528d7f9318759d34800b00372d)]:
|
||||
- effect@4.0.0-beta.25
|
||||
|
||||
## 4.0.0-beta.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a909e1c`](https://github.com/Effect-TS/effect-smol/commit/a909e1c1ac2bc707527f5073776e3e7d239688d9), [`8814a4e`](https://github.com/Effect-TS/effect-smol/commit/8814a4ef78d67144d27689370af10099ea210399), [`3f942c5`](https://github.com/Effect-TS/effect-smol/commit/3f942c51cefa7b2ffa7c49e8c8a2c887570ba4c0), [`774ed59`](https://github.com/Effect-TS/effect-smol/commit/774ed59c52b2ab578bbb897c4f551f812231e1d2), [`f54b8d3`](https://github.com/Effect-TS/effect-smol/commit/f54b8d398fedad1815fd1f4c49814ab938cfc385)]:
|
||||
- effect@4.0.0-beta.24
|
||||
|
||||
## 4.0.0-beta.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c73c41`](https://github.com/Effect-TS/effect-smol/commit/5c73c41b69eaeab80fcd62c9bfda490b446d1966)]:
|
||||
- effect@4.0.0-beta.23
|
||||
|
||||
## 4.0.0-beta.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0874332`](https://github.com/Effect-TS/effect-smol/commit/0874332f7c81118b06ac2eb105e0710211631479), [`c592dcd`](https://github.com/Effect-TS/effect-smol/commit/c592dcde0697e322065c8f418c0480ef910cb183), [`1dbe28d`](https://github.com/Effect-TS/effect-smol/commit/1dbe28dac8299cd3e218c9768450cfd173b5e294), [`564d730`](https://github.com/Effect-TS/effect-smol/commit/564d730b6bbf38dd8548a3b046e7a693b28699a4), [`3cfadc4`](https://github.com/Effect-TS/effect-smol/commit/3cfadc458b070c6cba6c5674b72a059f1e49118b), [`6634fd0`](https://github.com/Effect-TS/effect-smol/commit/6634fd07da067d80b8261fb2959d1a952b9e412e), [`d10dabe`](https://github.com/Effect-TS/effect-smol/commit/d10dabeb7af9a368f995829cd36ad08167cd8f95), [`f82f549`](https://github.com/Effect-TS/effect-smol/commit/f82f549a09e950e9d4987f279a800f4d953f0939), [`78a3382`](https://github.com/Effect-TS/effect-smol/commit/78a3382ddfbe034408f7480fa794733d9e82147b)]:
|
||||
- effect@4.0.0-beta.22
|
||||
|
||||
## 4.0.0-beta.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e691909`](https://github.com/Effect-TS/effect-smol/commit/e691909495ccb162ea7bfa351dd74632b99997cb), [`d5f413f`](https://github.com/Effect-TS/effect-smol/commit/d5f413f3c8fc57f2413cc5649c2003d6d4e5a6d7), [`139d152`](https://github.com/Effect-TS/effect-smol/commit/139d152941e562a073b5be12e8d66c8a4d4a8a57), [`947e3d4`](https://github.com/Effect-TS/effect-smol/commit/947e3d436ab8a017efda9b29be523efd1ca8df28), [`84b2cce`](https://github.com/Effect-TS/effect-smol/commit/84b2ccefe2aa3a7413b86738a4dc33cdb311ca55), [`7f5305e`](https://github.com/Effect-TS/effect-smol/commit/7f5305e69f5a33309e77b08a576edb25d7daaee2), [`9e6fd84`](https://github.com/Effect-TS/effect-smol/commit/9e6fd8471c93a3c643929151a3bdb62cb9c0ca0e), [`fdb8a4b`](https://github.com/Effect-TS/effect-smol/commit/fdb8a4b172721fbefe98bd5aa6fe4f0efd1da3eb), [`0f986ef`](https://github.com/Effect-TS/effect-smol/commit/0f986ef22f196fe091a7afdbd179485a7d888882), [`9355fc0`](https://github.com/Effect-TS/effect-smol/commit/9355fc0ffb5b7382146a5aed9eea83974b10d007)]:
|
||||
- effect@4.0.0-beta.21
|
||||
|
||||
## 4.0.0-beta.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1529](https://github.com/Effect-TS/effect-smol/pull/1529) [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8) Thanks @tim-smart! - Add dedicated AiError metadata interfaces per reason so provider packages can safely augment metadata without conflicting module declarations.
|
||||
|
||||
- [#1528](https://github.com/Effect-TS/effect-smol/pull/1528) [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34) Thanks @tim-smart! - Add `Model.ModelName` and provide it from AI model constructors.
|
||||
|
||||
- Updated dependencies [[`842a624`](https://github.com/Effect-TS/effect-smol/commit/842a624f79d5e1407460b0ef3ab27d14d48ccf74), [`4785eef`](https://github.com/Effect-TS/effect-smol/commit/4785eef5d7cf1edb96ef2509aed2ba4d1edf3862), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`12ee8e2`](https://github.com/Effect-TS/effect-smol/commit/12ee8e27df7eb393d83a5e403390d0cfc82ca732), [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34), [`989d1cc`](https://github.com/Effect-TS/effect-smol/commit/989d1cca936fce0cc459057825ba40e3f5ef3827)]:
|
||||
- effect@4.0.0-beta.20
|
||||
|
||||
## 4.0.0-beta.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.19
|
||||
|
||||
## 4.0.0-beta.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`01e31fd`](https://github.com/Effect-TS/effect-smol/commit/01e31fdf8e5206849d23cbafd23a346f2f177ab8), [`0890aab`](https://github.com/Effect-TS/effect-smol/commit/0890aab15ed9c5ba52c383a72fdc6a444d7504d5), [`725260b`](https://github.com/Effect-TS/effect-smol/commit/725260b53f5142d6af7a93a2f9f464f974eda92d)]:
|
||||
- effect@4.0.0-beta.18
|
||||
|
||||
## 4.0.0-beta.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8f59c32`](https://github.com/Effect-TS/effect-smol/commit/8f59c32922597a48392744f7203e284866747781)]:
|
||||
- effect@4.0.0-beta.17
|
||||
|
||||
## 4.0.0-beta.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf9096c`](https://github.com/Effect-TS/effect-smol/commit/bf9096c52a7d8791d93d232739e523eb84f6625a), [`29f81ca`](https://github.com/Effect-TS/effect-smol/commit/29f81ca07c67dba265804b140a7487fb15a5fc6b), [`68eb28c`](https://github.com/Effect-TS/effect-smol/commit/68eb28c2b0fc67a9f6204ade9bd16c5b37803bfb)]:
|
||||
- effect@4.0.0-beta.16
|
||||
|
||||
## 4.0.0-beta.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1502](https://github.com/Effect-TS/effect-smol/pull/1502) [`285b7e6`](https://github.com/Effect-TS/effect-smol/commit/285b7e667167566d5788367d5155b19c79f1bf22) Thanks @tim-smart! - allow undefined for ai config
|
||||
|
||||
- Updated dependencies [[`24ae609`](https://github.com/Effect-TS/effect-smol/commit/24ae60995d2fd7d621be356cdfdfd328c79639ba), [`0e3c059`](https://github.com/Effect-TS/effect-smol/commit/0e3c059987caa55ebd0c134f7c7b147c639c328e), [`e843b0a`](https://github.com/Effect-TS/effect-smol/commit/e843b0a7d7e7b600a0b3bd477f24e2e4cd26bc8b), [`f4389a2`](https://github.com/Effect-TS/effect-smol/commit/f4389a2cca3c5bbf00d69779f52ce41255f15a28), [`5b73de0`](https://github.com/Effect-TS/effect-smol/commit/5b73de095b3402d0c5c74092ace6ce18ebfad566), [`595d2d6`](https://github.com/Effect-TS/effect-smol/commit/595d2d6e7d50419f3532bd39266191532ace38f2)]:
|
||||
- effect@4.0.0-beta.15
|
||||
|
||||
## 4.0.0-beta.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c414700`](https://github.com/Effect-TS/effect-smol/commit/c414700ef1932e4b67d0102856de417336912350), [`a30c969`](https://github.com/Effect-TS/effect-smol/commit/a30c9699c0d736cf3952041e45d508b7d58907a9)]:
|
||||
- effect@4.0.0-beta.14
|
||||
|
||||
## 4.0.0-beta.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`368f4c3`](https://github.com/Effect-TS/effect-smol/commit/368f4c363dd117e6f5a19ad77b161176cfd29fdd), [`db8a579`](https://github.com/Effect-TS/effect-smol/commit/db8a579e93e93ff73b1e60712732e03b597b916b), [`668b703`](https://github.com/Effect-TS/effect-smol/commit/668b70337e9ddbb0d1ae2282a95c282ce404e562), [`d40e76b`](https://github.com/Effect-TS/effect-smol/commit/d40e76b973543979e60e04a6baca04a8c65bdfc2), [`6e18cf8`](https://github.com/Effect-TS/effect-smol/commit/6e18cf883e9905ca718a6697b6a2a4bbd42739aa), [`86062e8`](https://github.com/Effect-TS/effect-smol/commit/86062e8a0c61bca5412fc40d2cf151d676901f08), [`c27ce75`](https://github.com/Effect-TS/effect-smol/commit/c27ce75d34c74dcfc6dba1bf77f1ce88f410a0de), [`e2d4fbf`](https://github.com/Effect-TS/effect-smol/commit/e2d4fbfeeda6a5d2a4c5aeb0501d8240c248b9eb), [`114ab42`](https://github.com/Effect-TS/effect-smol/commit/114ab42ad0edc590d29169675a493e0e915aa58f), [`484caec`](https://github.com/Effect-TS/effect-smol/commit/484caec47cccac8b86db2910742e406dfc7173ab)]:
|
||||
- effect@4.0.0-beta.13
|
||||
|
||||
## 4.0.0-beta.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70a74e8`](https://github.com/Effect-TS/effect-smol/commit/70a74e88a8767c9d4acdb9e5f25aec9a33588d07), [`b5b6e10`](https://github.com/Effect-TS/effect-smol/commit/b5b6e10621d54bf8c9857fec0d647ced78ecd857), [`f5ce5a9`](https://github.com/Effect-TS/effect-smol/commit/f5ce5a915359c6ebf254079e1da23cab6cde34fb), [`a29eb70`](https://github.com/Effect-TS/effect-smol/commit/a29eb702ffe3fc58bd28c4d7857298cd65d73668), [`c7b36e5`](https://github.com/Effect-TS/effect-smol/commit/c7b36e541a23e9a00f64e25b23851e51a37dfce5), [`9381d6d`](https://github.com/Effect-TS/effect-smol/commit/9381d6d4d9d819a81a46e56d0364c76e92a4fbca), [`88439f1`](https://github.com/Effect-TS/effect-smol/commit/88439f13ca13549f3e4822c48c4f019c14fc2bcc), [`e35307d`](https://github.com/Effect-TS/effect-smol/commit/e35307dbeb8eb26a9923f958b894a8eaaf259bf2), [`c7df4bc`](https://github.com/Effect-TS/effect-smol/commit/c7df4bce34009474c63d62a807abfdafb76971eb), [`accaf3b`](https://github.com/Effect-TS/effect-smol/commit/accaf3be7ac8da36e2334c509c23b8c9e88ea160), [`3e1c270`](https://github.com/Effect-TS/effect-smol/commit/3e1c2707bbdf67720af1509642b8ced195790882), [`6cd81f7`](https://github.com/Effect-TS/effect-smol/commit/6cd81f73baad86f5bbfa455a55d75cde71e9611a), [`f222da3`](https://github.com/Effect-TS/effect-smol/commit/f222da3cdb44554f3324c2c52d0d005ee575053e), [`61f901d`](https://github.com/Effect-TS/effect-smol/commit/61f901d830005b66e22d1de889fda132aeea97cd)]:
|
||||
- effect@4.0.0-beta.12
|
||||
|
||||
## 4.0.0-beta.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`88659ed`](https://github.com/Effect-TS/effect-smol/commit/88659edb26e3623d557dccfe914c2c949672da16), [`f2915e8`](https://github.com/Effect-TS/effect-smol/commit/f2915e8e2efe80d50c281e53f297b9701d6dc199), [`eb71ace`](https://github.com/Effect-TS/effect-smol/commit/eb71acebbe0f228e4920278013beee3b67d62310), [`2a16999`](https://github.com/Effect-TS/effect-smol/commit/2a169996c7513d377ac47adbfd68e1490457135c), [`d42dd52`](https://github.com/Effect-TS/effect-smol/commit/d42dd52f11203f8e749fb5d3ecf7153e4a5a6814), [`339adaf`](https://github.com/Effect-TS/effect-smol/commit/339adaf850a62a892adebcb208c2d9dddf3b97b3), [`de19645`](https://github.com/Effect-TS/effect-smol/commit/de1964526d01102dd1cb99c8cfdd3e8df1f49ef1), [`9b1dc3b`](https://github.com/Effect-TS/effect-smol/commit/9b1dc3bcf2a1b68d0a67e3465db5ad01a1a56997), [`e4cb2f5`](https://github.com/Effect-TS/effect-smol/commit/e4cb2f55b30f4771ec1bf613ced36d6d96464dd5), [`8bced95`](https://github.com/Effect-TS/effect-smol/commit/8bced954ecb35d4489197a57b0efe927e7d75f49), [`9431420`](https://github.com/Effect-TS/effect-smol/commit/94314207c8019918200fbcb97aec992219f801f0), [`948dca2`](https://github.com/Effect-TS/effect-smol/commit/948dca22e4f672ba7a6db57f9899272bec7c08b8), [`d18e327`](https://github.com/Effect-TS/effect-smol/commit/d18e32765a2665e31ffb31e746bf983fcfac34c5), [`ab512f7`](https://github.com/Effect-TS/effect-smol/commit/ab512f7be1c0e6b359da921e22cd4944e4c57d3e)]:
|
||||
- effect@4.0.0-beta.11
|
||||
|
||||
## 4.0.0-beta.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`371acab`](https://github.com/Effect-TS/effect-smol/commit/371acabb58d56f3a7a5e3e33d3d5fdc9f5573c74), [`856d774`](https://github.com/Effect-TS/effect-smol/commit/856d7741f1e296dd5048c6ff2b44b95d023e6ae4), [`b9e9202`](https://github.com/Effect-TS/effect-smol/commit/b9e92023c38caa322975d77cfe83e2d34ac9305a), [`1d1a974`](https://github.com/Effect-TS/effect-smol/commit/1d1a974bd280c81bff5d4505491cda03ba7a3f36), [`6bfe2a6`](https://github.com/Effect-TS/effect-smol/commit/6bfe2a659bc6335db75709931f405da45301cba2), [`b12c811`](https://github.com/Effect-TS/effect-smol/commit/b12c81157be287b1649c210616a244b50ec094d2), [`d17d98a`](https://github.com/Effect-TS/effect-smol/commit/d17d98ad78e2b44d95ef434adab79ac3c35e75ab), [`68c3c7c`](https://github.com/Effect-TS/effect-smol/commit/68c3c7cb1e06ed94fa5c4c123a234b4ccbfdecd8)]:
|
||||
- effect@4.0.0-beta.10
|
||||
|
||||
## 4.0.0-beta.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3386557`](https://github.com/Effect-TS/effect-smol/commit/338655731564a7be9f8859dedbf4d5bcac6eb350), [`b6666e3`](https://github.com/Effect-TS/effect-smol/commit/b6666e3cf6bd44ba1a8704e65c256c30359cb422)]:
|
||||
- effect@4.0.0-beta.9
|
||||
|
||||
## 4.0.0-beta.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1354](https://github.com/Effect-TS/effect-smol/pull/1354) [`b94962c`](https://github.com/Effect-TS/effect-smol/commit/b94962c249d46cf96cdf2e41188dc9feda41536a) Thanks @IMax153! - Fix the generated schemas for ai providers
|
||||
|
||||
- Updated dependencies [[`246e672`](https://github.com/Effect-TS/effect-smol/commit/246e672dbbd7848d60e0c78fd66671b2f10b3752), [`807dec0`](https://github.com/Effect-TS/effect-smol/commit/807dec03801b4c58a6d00c237b6d98d6386911df)]:
|
||||
- effect@4.0.0-beta.8
|
||||
|
||||
## 4.0.0-beta.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a2bda6d`](https://github.com/Effect-TS/effect-smol/commit/a2bda6d4ef6de9d9b0c53ae2df5434f778d6161a), [`1f95a2b`](https://github.com/Effect-TS/effect-smol/commit/1f95a2b5aa9524bb38f4437f4691a664bf463ca1), [`a8d5e79`](https://github.com/Effect-TS/effect-smol/commit/a8d5e792fec201a83af0eb92fc79928d055125fd), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`06d8a03`](https://github.com/Effect-TS/effect-smol/commit/06d8a0391631e6130e3ab25227e59817852e227f), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`f9e883e`](https://github.com/Effect-TS/effect-smol/commit/f9e883e266fbda870336ee62f46b7ac85ba3de6e), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430)]:
|
||||
- effect@4.0.0-beta.7
|
||||
|
||||
## 4.0.0-beta.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1333](https://github.com/Effect-TS/effect-smol/pull/1333) [`96260bf`](https://github.com/Effect-TS/effect-smol/commit/96260bf5331fad6e38d2a79e94d70fd9a502ec29) Thanks @IMax153! - Fix tool calling for the Anthropic Effect AI SDK provider integration
|
||||
|
||||
- Updated dependencies [[`3247da2`](https://github.com/Effect-TS/effect-smol/commit/3247da28331f345f68be5dbd2974a7e03d300fe1), [`f205705`](https://github.com/Effect-TS/effect-smol/commit/f2057050dbd034b8c186be2d40c3d03ee63a5a3b), [`f35022c`](https://github.com/Effect-TS/effect-smol/commit/f35022c212e4111527e1bb43f360a67b2b49fa85), [`8622721`](https://github.com/Effect-TS/effect-smol/commit/86227217b02d43680a3c6f3c21731b1d852c91f5), [`fc660ab`](https://github.com/Effect-TS/effect-smol/commit/fc660ab8b5ebae38b8d6b96cbf2f9b880cc09253), [`f37dc33`](https://github.com/Effect-TS/effect-smol/commit/f37dc335f64622fa9ce8d6d1d5dd8fc3f260257b), [`3662f32`](https://github.com/Effect-TS/effect-smol/commit/3662f328fcfa3b2fa01ffa79da40e12e93fcede8), [`a7d436f`](https://github.com/Effect-TS/effect-smol/commit/a7d436f438dcd7f49b9485e4e95a4511f31fad7d), [`6856a41`](https://github.com/Effect-TS/effect-smol/commit/6856a415d7eddd9d73d60919e976f1d071421be4), [`8c417d0`](https://github.com/Effect-TS/effect-smol/commit/8c417d03475e5e12d00dca0c4781d0af7e66b86c), [`5419570`](https://github.com/Effect-TS/effect-smol/commit/5419570ba47ce882a3a10882707b46f66e464906), [`449c5ed`](https://github.com/Effect-TS/effect-smol/commit/449c5ed5318e8a874e730420bcf52918fa2ec80f), [`4b5ec12`](https://github.com/Effect-TS/effect-smol/commit/4b5ec12f87f95f2a3cd8fe4d5b26c6eb0529381a), [`df87937`](https://github.com/Effect-TS/effect-smol/commit/df879375fc3b169c43f9c434b3775e12b80dffe4), [`5dbfca8`](https://github.com/Effect-TS/effect-smol/commit/5dbfca8d1dbb6d18d1605d4f8562e99c86e2ff11), [`e629497`](https://github.com/Effect-TS/effect-smol/commit/e6294973d55597ab6b6deca6babbe1e946b2c91d), [`981c991`](https://github.com/Effect-TS/effect-smol/commit/981c991cd78db34def815d5754379d737157f005), [`1ca2ed6`](https://github.com/Effect-TS/effect-smol/commit/1ca2ed67301a5dc40ae0ed94346b99f26fd22bbe), [`45722bd`](https://github.com/Effect-TS/effect-smol/commit/45722bde974458311f11ad237711363a10ec6894), [`eb2a85e`](https://github.com/Effect-TS/effect-smol/commit/eb2a85ed4dc162b2535d304799333a5a20477fd0)]:
|
||||
- effect@4.0.0-beta.6
|
||||
|
||||
## 4.0.0-beta.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f6e133e`](https://github.com/Effect-TS/effect-smol/commit/f6e133e9a16b32317bd09ff08c12b97a0ae44600), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8), [`a88e206`](https://github.com/Effect-TS/effect-smol/commit/a88e206e44dc66ca5a2b45bedc797877c5dbb083), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8)]:
|
||||
- effect@4.0.0-beta.5
|
||||
|
||||
## 4.0.0-beta.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c5a18ef`](https://github.com/Effect-TS/effect-smol/commit/c5a18ef44171e3880bf983faee74529908974b32), [`bc6b885`](https://github.com/Effect-TS/effect-smol/commit/bc6b885b94d887a200657c0775dfa874dc15bc0c)]:
|
||||
- effect@4.0.0-beta.4
|
||||
|
||||
## 4.0.0-beta.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a0cf36`](https://github.com/Effect-TS/effect-smol/commit/3a0cf36eff106ba48d74e133c1598cd40613e530), [`c4da328`](https://github.com/Effect-TS/effect-smol/commit/c4da328d32fad1d61e0e538f5d371edf61521d7e)]:
|
||||
- effect@4.0.0-beta.3
|
||||
|
||||
## 4.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a22ce73`](https://github.com/Effect-TS/effect-smol/commit/a22ce73b2bd9305b7ba665694d2255c0e6d5a8d0), [`ebdabf7`](https://github.com/Effect-TS/effect-smol/commit/ebdabf79ff4e62c8384aa8cf9a8d2787d536ee78), [`8f663bb`](https://github.com/Effect-TS/effect-smol/commit/8f663bb121021bf12bd264e8ae385187cb7a5dae)]:
|
||||
- effect@4.0.0-beta.2
|
||||
|
||||
## 4.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0fecf70`](https://github.com/Effect-TS/effect-smol/commit/0fecf70048057623eed7c584a06671773a2b1743), [`709569e`](https://github.com/Effect-TS/effect-smol/commit/709569ed76bead9ebb0670599e4d890a07ca5a43)]:
|
||||
- effect@4.0.0-beta.1
|
||||
|
||||
## 4.0.0-beta.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#1183](https://github.com/Effect-TS/effect-smol/pull/1183) [`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66) Thanks @tim-smart! - v4 beta
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66)]:
|
||||
- effect@4.0.0-beta.0
|
||||
62
repos/effect/packages/ai/anthropic/codegen.yml
Normal file
62
repos/effect/packages/ai/anthropic/codegen.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
# yaml-language-server: $schema=../../tools/ai-codegen/codegen.schema.json
|
||||
spec:
|
||||
type: stainless-stats
|
||||
statsUrl: https://raw.githubusercontent.com/anthropics/anthropic-sdk-typescript/main/.stats.yml
|
||||
output: src/Generated.ts
|
||||
name: AnthropicClient
|
||||
patches:
|
||||
# Make iterations and speed optional in BetaUsage, iterations optional in BetaMessageDeltaUsage (API may omit these fields)
|
||||
- '[{"op":"remove","path":"/components/schemas/BetaUsage/required/9"},{"op":"remove","path":"/components/schemas/BetaUsage/required/5"},{"op":"remove","path":"/components/schemas/BetaMessageDeltaUsage/required/3"}]'
|
||||
header: |
|
||||
/**
|
||||
* @since 1.0.0
|
||||
*/
|
||||
excludeAnnotations:
|
||||
- examples
|
||||
replacements:
|
||||
# Schema.Unknown doesn't work with Schema.toCodecJson (used by HttpClientResponse.schemaBodyJson)
|
||||
# Replace with Schema.Json which properly handles arbitrary JSON values
|
||||
- from: "Schema.Record(Schema.String, Schema.Unknown)"
|
||||
to: "Schema.Record(Schema.String, Schema.Json)"
|
||||
- from: "{ readonly [x: string]: unknown }"
|
||||
to: "{ readonly [x: string]: Schema.Json }"
|
||||
# Index signature in struct rest pattern
|
||||
- from: "readonly [x: string]: unknown"
|
||||
to: "readonly [x: string]: Schema.Json"
|
||||
# Make citations optional in ResponseTextBlock (API may omit this field)
|
||||
- from: 'export type ResponseTextBlock = { readonly "citations":'
|
||||
to: 'export type ResponseTextBlock = { readonly "citations"?:'
|
||||
- from: "export const ResponseTextBlock = Schema.Struct({ \"citations\": Schema.Union([Schema.Array(Schema.Union([ResponseCharLocationCitation, ResponsePageLocationCitation, ResponseContentBlockLocationCitation, ResponseWebSearchResultLocationCitation, ResponseSearchResultLocationCitation], { mode: \"oneOf\" })), Schema.Null]).annotate({ \"title\": \"Citations\", \"description\": \"Citations supporting the text block.\\n\\nThe type of citation returned will depend on the type of document being cited. Citing a PDF results in `page_location`, plain text results in `char_location`, and content document results in `content_block_location`.\", \"default\": null }), \"text\":"
|
||||
to: "export const ResponseTextBlock = Schema.Struct({ \"citations\": Schema.optionalKey(Schema.Union([Schema.Array(Schema.Union([ResponseCharLocationCitation, ResponsePageLocationCitation, ResponseContentBlockLocationCitation, ResponseWebSearchResultLocationCitation, ResponseSearchResultLocationCitation], { mode: \"oneOf\" })), Schema.Null]).annotate({ \"title\": \"Citations\", \"description\": \"Citations supporting the text block.\\n\\nThe type of citation returned will depend on the type of document being cited. Citing a PDF results in `page_location`, plain text results in `char_location`, and content document results in `content_block_location`.\", \"default\": null })), \"text\":"
|
||||
# Make citations optional in BetaResponseTextBlock (API may omit this field)
|
||||
- from: 'export type BetaResponseTextBlock = { readonly "citations":'
|
||||
to: 'export type BetaResponseTextBlock = { readonly "citations"?:'
|
||||
- from: "export const BetaResponseTextBlock = Schema.Struct({ \"citations\": Schema.Union([Schema.Array(Schema.Union([BetaResponseCharLocationCitation, BetaResponsePageLocationCitation, BetaResponseContentBlockLocationCitation, BetaResponseWebSearchResultLocationCitation, BetaResponseSearchResultLocationCitation], { mode: \"oneOf\" })), Schema.Null]).annotate({ \"title\": \"Citations\", \"description\": \"Citations supporting the text block.\\n\\nThe type of citation returned will depend on the type of document being cited. Citing a PDF results in `page_location`, plain text results in `char_location`, and content document results in `content_block_location`.\", \"default\": null }), \"text\":"
|
||||
to: "export const BetaResponseTextBlock = Schema.Struct({ \"citations\": Schema.optionalKey(Schema.Union([Schema.Array(Schema.Union([BetaResponseCharLocationCitation, BetaResponsePageLocationCitation, BetaResponseContentBlockLocationCitation, BetaResponseWebSearchResultLocationCitation, BetaResponseSearchResultLocationCitation], { mode: \"oneOf\" })), Schema.Null]).annotate({ \"title\": \"Citations\", \"description\": \"Citations supporting the text block.\\n\\nThe type of citation returned will depend on the type of document being cited. Citing a PDF results in `page_location`, plain text results in `char_location`, and content document results in `content_block_location`.\", \"default\": null })), \"text\":"
|
||||
# Make server_tool_use optional in usage (API may omit this field)
|
||||
- from: 'readonly "server_tool_use": ServerToolUsage | null'
|
||||
to: 'readonly "server_tool_use"?: ServerToolUsage | null'
|
||||
- from: 'readonly "server_tool_use": BetaServerToolUsage | null'
|
||||
to: 'readonly "server_tool_use"?: BetaServerToolUsage | null'
|
||||
- from: '"server_tool_use": Schema.Union([ServerToolUsage, Schema.Null]).annotate({ "description": "The number of server tool requests.", "default": null }),'
|
||||
to: '"server_tool_use": Schema.optionalKey(Schema.Union([ServerToolUsage, Schema.Null]).annotate({ "description": "The number of server tool requests.", "default": null })),'
|
||||
- from: '"server_tool_use": Schema.Union([BetaServerToolUsage, Schema.Null]).annotate({ "description": "The number of server tool requests.", "default": null }),'
|
||||
to: '"server_tool_use": Schema.optionalKey(Schema.Union([BetaServerToolUsage, Schema.Null]).annotate({ "description": "The number of server tool requests.", "default": null })),'
|
||||
# Without trailing comma (for last field in struct)
|
||||
- from: '"server_tool_use": Schema.Union([BetaServerToolUsage, Schema.Null]).annotate({ "description": "The number of server tool requests.", "default": null }) })'
|
||||
to: '"server_tool_use": Schema.optionalKey(Schema.Union([BetaServerToolUsage, Schema.Null]).annotate({ "description": "The number of server tool requests.", "default": null })) })'
|
||||
- from: '"server_tool_use": Schema.Union([ServerToolUsage, Schema.Null]).annotate({ "description": "The number of server tool requests.", "default": null }) })'
|
||||
to: '"server_tool_use": Schema.optionalKey(Schema.Union([ServerToolUsage, Schema.Null]).annotate({ "description": "The number of server tool requests.", "default": null })) })'
|
||||
# Make context_management and container optional in BetaMessage (API may omit these fields)
|
||||
- from: 'readonly "context_management": BetaResponseContextManagement | null'
|
||||
to: 'readonly "context_management"?: BetaResponseContextManagement | null'
|
||||
- from: 'readonly "container": BetaContainer | null'
|
||||
to: 'readonly "container"?: BetaContainer | null'
|
||||
- from: "\"context_management\": Schema.Union([BetaResponseContextManagement, Schema.Null]).annotate({ \"description\": \"Context management response.\\n\\nInformation about context management strategies applied during the request.\", \"default\": null }),"
|
||||
to: "\"context_management\": Schema.optionalKey(Schema.Union([BetaResponseContextManagement, Schema.Null]).annotate({ \"description\": \"Context management response.\\n\\nInformation about context management strategies applied during the request.\", \"default\": null })),"
|
||||
- from: "\"container\": Schema.Union([BetaContainer, Schema.Null]).annotate({ \"description\": \"Information about the container used in this request.\\n\\nThis will be non-null if a container tool (e.g. code execution) was used.\", \"default\": null })"
|
||||
to: "\"container\": Schema.optionalKey(Schema.Union([BetaContainer, Schema.Null]).annotate({ \"description\": \"Information about the container used in this request.\\n\\nThis will be non-null if a container tool (e.g. code execution) was used.\", \"default\": null }))"
|
||||
# Make context_management optional in BetaMessageDeltaEvent (API may omit this field)
|
||||
- from: '"context_management": Schema.Union([BetaResponseContextManagement, Schema.Null]).annotate({ "description": "Information about context management strategies applied during the request", "default": null }),'
|
||||
to: '"context_management": Schema.optionalKey(Schema.Union([BetaResponseContextManagement, Schema.Null]).annotate({ "description": "Information about context management strategies applied during the request", "default": null })),'
|
||||
|
||||
25
repos/effect/packages/ai/anthropic/docgen.json
Normal file
25
repos/effect/packages/ai/anthropic/docgen.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "../../node_modules/@effect/docgen/schema.json",
|
||||
"srcLink": "https://github.com/Effect-TS/effect/tree/main/packages/ai/anthropic/src/",
|
||||
"exclude": ["src/internal/**/*.ts", "src/Generated.ts"],
|
||||
"examplesCompilerOptions": {
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "Bundler",
|
||||
"module": "ES2022",
|
||||
"target": "ES2022",
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"types": ["node"],
|
||||
"rewriteRelativeImportExtensions": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"paths": {
|
||||
"effect": ["../../../effect/src/index.js"],
|
||||
"effect/*": ["../../../effect/src/*.js"]
|
||||
},
|
||||
"plugins": [
|
||||
{ "name": "@effect/language-service", "includeSuggestionsInTsc": false }
|
||||
]
|
||||
}
|
||||
}
|
||||
66
repos/effect/packages/ai/anthropic/package.json
Normal file
66
repos/effect/packages/ai/anthropic/package.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "@effect/ai-anthropic",
|
||||
"version": "4.0.0-beta.99",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "An Anthropic provider integration for Effect AI SDK",
|
||||
"homepage": "https://effect.website",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Effect-TS/effect.git",
|
||||
"directory": "packages/ai/anthropic"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Effect-TS/effect/issues"
|
||||
},
|
||||
"tags": [
|
||||
"typescript",
|
||||
"ai",
|
||||
"anthropic"
|
||||
],
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"ai",
|
||||
"anthropic"
|
||||
],
|
||||
"sideEffects": [],
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts",
|
||||
"./*": "./src/*.ts",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
},
|
||||
"files": [
|
||||
"src/**/*.ts",
|
||||
"dist/**/*.js",
|
||||
"dist/**/*.js.map",
|
||||
"dist/**/*.d.ts",
|
||||
"dist/**/*.d.ts.map"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"provenance": true,
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./dist/index.js",
|
||||
"./*": "./dist/*.js",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"codegen": "effect-utils codegen",
|
||||
"build": "tsc -b tsconfig.json && pnpm babel",
|
||||
"babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
||||
"check": "tsc -b tsconfig.json",
|
||||
"test": "vitest",
|
||||
"coverage": "vitest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"effect": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "workspace:^"
|
||||
}
|
||||
}
|
||||
432
repos/effect/packages/ai/anthropic/src/AnthropicClient.ts
Normal file
432
repos/effect/packages/ai/anthropic/src/AnthropicClient.ts
Normal file
@@ -0,0 +1,432 @@
|
||||
/**
|
||||
* The `AnthropicClient` module defines the low-level Effect service for
|
||||
* Anthropic's Messages API. It builds a generated Anthropic HTTP client with
|
||||
* authentication headers, API version headers, response decoding, and error
|
||||
* mapping, then exposes helpers for regular and streaming message requests.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Array from "effect/Array"
|
||||
import type * as Config from "effect/Config"
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { identity } from "effect/Function"
|
||||
import * as Layer from "effect/Layer"
|
||||
import * as Predicate from "effect/Predicate"
|
||||
import * as Redacted from "effect/Redacted"
|
||||
import * as Schema from "effect/Schema"
|
||||
import * as Stream from "effect/Stream"
|
||||
import type * as AiError from "effect/unstable/ai/AiError"
|
||||
import * as Sse from "effect/unstable/encoding/Sse"
|
||||
import * as Headers from "effect/unstable/http/Headers"
|
||||
import * as HttpBody from "effect/unstable/http/HttpBody"
|
||||
import * as HttpClient from "effect/unstable/http/HttpClient"
|
||||
import type * as HttpClientError from "effect/unstable/http/HttpClientError"
|
||||
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
||||
import type * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
|
||||
import { AnthropicConfig } from "./AnthropicConfig.ts"
|
||||
import * as Generated from "./Generated.ts"
|
||||
import * as Errors from "./internal/errors.ts"
|
||||
|
||||
// =============================================================================
|
||||
// Service Interface
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Represents the Anthropic client service with methods for the Messages API, including regular and streaming message
|
||||
* creation.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface Service {
|
||||
/**
|
||||
* The underlying generated Anthropic client that exposes all API endpoints.
|
||||
*/
|
||||
readonly client: Generated.AnthropicClient
|
||||
|
||||
/**
|
||||
* Executes a low-level streaming HTTP request and decodes the Server-Sent Events response using the provided schema.
|
||||
*/
|
||||
readonly streamRequest: <S extends Sse.EventCodec>(
|
||||
schema: S
|
||||
) => (request: HttpClientRequest.HttpClientRequest) => Stream.Stream<
|
||||
S["Type"],
|
||||
HttpClientError.HttpClientError | Schema.SchemaError | Sse.Retry,
|
||||
S["DecodingServices"]
|
||||
>
|
||||
|
||||
/**
|
||||
* Creates a message using the Anthropic Messages API and maps all errors to the unified `AiError` type.
|
||||
*/
|
||||
readonly createMessage: (options: {
|
||||
readonly payload: typeof Generated.BetaCreateMessageParams.Encoded
|
||||
readonly params?: typeof Generated.BetaMessagesPostParams.Encoded | undefined
|
||||
}) => Effect.Effect<
|
||||
[body: typeof Generated.BetaMessage.Type, response: HttpClientResponse.HttpClientResponse],
|
||||
AiError.AiError
|
||||
>
|
||||
|
||||
/**
|
||||
* Creates a streaming message using the Anthropic Messages API and maps all errors to the unified `AiError` type.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The returned Effect yields the HTTP response and a stream of events as the model generates its response. The stream
|
||||
* automatically terminates when a `message_stop` event is received.
|
||||
*/
|
||||
readonly createMessageStream: (options: {
|
||||
readonly payload: Omit<typeof Generated.BetaCreateMessageParams.Encoded, "stream">
|
||||
readonly params?: typeof Generated.BetaMessagesPostParams.Encoded | undefined
|
||||
}) => Effect.Effect<
|
||||
[response: HttpClientResponse.HttpClientResponse, stream: Stream.Stream<MessageStreamEvent, AiError.AiError>],
|
||||
AiError.AiError
|
||||
>
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an event received from the Anthropic Messages API during a streaming request.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Events include:
|
||||
* - `message_start`: Initial event containing message metadata
|
||||
* - `message_delta`: Incremental updates to the message (e.g., stop reason)
|
||||
* - `message_stop`: Final event indicating the message is complete
|
||||
* - `content_block_start`: Start of a content block
|
||||
* - `content_block_delta`: Incremental content updates (text, tool use, etc.)
|
||||
* - `content_block_stop`: End of a content block
|
||||
* - `error`: Error events with type and message
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type MessageStreamEvent =
|
||||
| typeof Generated.BetaMessageStartEvent.Type
|
||||
| typeof Generated.BetaMessageDeltaEvent.Type
|
||||
| typeof Generated.BetaMessageStopEvent.Type
|
||||
| typeof Generated.BetaContentBlockStartEvent.Type
|
||||
| typeof Generated.BetaContentBlockDeltaEvent.Type
|
||||
| typeof Generated.BetaContentBlockStopEvent.Type
|
||||
| typeof Generated.BetaErrorResponse.Type
|
||||
|
||||
// =============================================================================
|
||||
// Service Identifier
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Service tag for the Anthropic client.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when accessing or providing the Anthropic client service through Effect's
|
||||
* context.
|
||||
*
|
||||
* @see {@link make} for constructing an Anthropic client effectfully
|
||||
* @see {@link layer} for providing a client from explicit options
|
||||
* @see {@link layerConfig} for providing a client from `Config`
|
||||
*
|
||||
* @category services
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class AnthropicClient extends Context.Service<AnthropicClient, Service>()(
|
||||
"@effect/ai-anthropic/AnthropicClient"
|
||||
) {}
|
||||
|
||||
// =============================================================================
|
||||
// Options
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Configuration for creating an Anthropic client.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when the Anthropic client settings are already available as values and
|
||||
* should be passed directly to `make` or `layer`.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* These options configure the base Anthropic URL, the `x-api-key`
|
||||
* authentication header, the `anthropic-version` header, and an optional
|
||||
* transformation of the underlying `HttpClient`.
|
||||
*
|
||||
* @see {@link make} for constructing an Anthropic client from explicit options
|
||||
* @see {@link layer} for providing an Anthropic client from explicit options
|
||||
* @see {@link layerConfig} for loading Anthropic client settings from `Config`
|
||||
*
|
||||
* @category options
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* The Anthropic API key for authentication. Requests are made without authentication when this is omitted, which is
|
||||
* useful for proxied setups or testing.
|
||||
*/
|
||||
readonly apiKey?: Redacted.Redacted<string> | undefined
|
||||
|
||||
/**
|
||||
* The base URL for the Anthropic API. Override this to use a proxy or a different API-compatible endpoint.
|
||||
*
|
||||
* @default "https://api.anthropic.com"
|
||||
*/
|
||||
readonly apiUrl?: string | undefined
|
||||
|
||||
/**
|
||||
* The Anthropic API version header value. This controls which version of the API to use.
|
||||
*
|
||||
* @default "2023-06-01"
|
||||
*/
|
||||
readonly apiVersion?: string | undefined
|
||||
|
||||
/**
|
||||
* Optional transformer for the underlying HTTP client, such as middleware, logging, or custom request/response
|
||||
* handling.
|
||||
*/
|
||||
readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Constructor
|
||||
// =============================================================================
|
||||
|
||||
const RedactedAnthropicHeaders = {
|
||||
AnthropicApiKey: "x-api-key"
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Anthropic client service with the given options.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you have explicit configuration values and need an `Effect` that
|
||||
* constructs the Anthropic client service, rather than providing it as a `Layer`.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The client handles API key authentication via the `x-api-key` header, API versioning via the `anthropic-version`
|
||||
* header, error mapping to the unified `AiError` type, and request/response transformations via `AnthropicConfig`. It
|
||||
* requires an `HttpClient` in the context.
|
||||
*
|
||||
* @see {@link layer} for providing the client as a `Layer` from explicit options
|
||||
* @see {@link layerConfig} for providing the client as a `Layer` with `Config`-based settings
|
||||
*
|
||||
* @category constructors
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const make = Effect.fnUntraced(
|
||||
function*(options: Options): Effect.fn.Return<Service, never, HttpClient.HttpClient> {
|
||||
const baseClient = yield* HttpClient.HttpClient
|
||||
const apiVersion = options.apiVersion ?? "2023-06-01"
|
||||
|
||||
const httpClient = baseClient.pipe(
|
||||
HttpClient.mapRequest((request) =>
|
||||
request.pipe(
|
||||
HttpClientRequest.prependUrl(options.apiUrl ?? "https://api.anthropic.com"),
|
||||
Predicate.isNotUndefined(options.apiKey)
|
||||
? HttpClientRequest.setHeader(
|
||||
RedactedAnthropicHeaders.AnthropicApiKey,
|
||||
Redacted.value(options.apiKey)
|
||||
)
|
||||
: identity,
|
||||
HttpClientRequest.setHeader("anthropic-version", apiVersion),
|
||||
HttpClientRequest.acceptJson
|
||||
)
|
||||
),
|
||||
Predicate.isNotUndefined(options.transformClient)
|
||||
? options.transformClient
|
||||
: identity
|
||||
)
|
||||
|
||||
const client = Generated.make(httpClient, {
|
||||
transformClient: Effect.fnUntraced(function*(client) {
|
||||
const config = yield* AnthropicConfig.getOrUndefined
|
||||
if (Predicate.isNotUndefined(config?.transformClient)) {
|
||||
return config.transformClient(client)
|
||||
}
|
||||
return client
|
||||
})
|
||||
})
|
||||
|
||||
const httpClientOk = HttpClient.filterStatusOk(httpClient)
|
||||
|
||||
const streamRequest =
|
||||
<S extends Sse.EventCodec>(schema: S) =>
|
||||
(request: HttpClientRequest.HttpClientRequest): Stream.Stream<
|
||||
S["Type"],
|
||||
HttpClientError.HttpClientError | Schema.SchemaError | Sse.Retry,
|
||||
S["DecodingServices"]
|
||||
> =>
|
||||
httpClientOk.execute(request).pipe(
|
||||
Effect.map((response) => response.stream),
|
||||
Stream.unwrap,
|
||||
Stream.decodeText,
|
||||
Stream.pipeThroughChannel(Sse.decodeSchema(schema))
|
||||
)
|
||||
|
||||
const createMessage = (options: {
|
||||
readonly payload: typeof Generated.BetaCreateMessageParams.Encoded
|
||||
readonly params?: typeof Generated.BetaMessagesPostParams.Encoded | undefined
|
||||
}): Effect.Effect<
|
||||
[body: typeof Generated.BetaMessage.Type, response: HttpClientResponse.HttpClientResponse],
|
||||
AiError.AiError
|
||||
> =>
|
||||
client.betaMessagesPost({ ...options, config: { includeResponse: true } }).pipe(
|
||||
Effect.catchTags({
|
||||
BetaMessagesPost4XX: (error) => Effect.fail(Errors.mapClientError(error, "createMessage")),
|
||||
HttpClientError: (error) => Errors.mapHttpClientError(error, "createMessage"),
|
||||
SchemaError: (error) => Effect.fail(Errors.mapSchemaError(error, "createMessage"))
|
||||
})
|
||||
)
|
||||
|
||||
const PingEvent = Schema.Struct({
|
||||
type: Schema.Literal("ping")
|
||||
})
|
||||
|
||||
const MessageEvent = Schema.Union([
|
||||
PingEvent,
|
||||
Generated.BetaMessageStartEvent,
|
||||
Generated.BetaMessageDeltaEvent,
|
||||
Generated.BetaMessageStopEvent,
|
||||
Generated.BetaContentBlockStartEvent,
|
||||
Generated.BetaContentBlockDeltaEvent,
|
||||
Generated.BetaContentBlockStopEvent,
|
||||
Generated.BetaErrorResponse
|
||||
])
|
||||
|
||||
const buildMessageStream = (
|
||||
response: HttpClientResponse.HttpClientResponse
|
||||
): [HttpClientResponse.HttpClientResponse, Stream.Stream<MessageStreamEvent, AiError.AiError>] => {
|
||||
const stream = response.stream.pipe(
|
||||
Stream.decodeText,
|
||||
Stream.pipeThroughChannel(Sse.decodeDataSchema(MessageEvent)),
|
||||
Stream.takeUntil((event) => event.data.type === "message_stop"),
|
||||
Stream.map((event) => event.data),
|
||||
Stream.filter((event): event is MessageStreamEvent => event.type !== "ping"),
|
||||
Stream.catchTags({
|
||||
// TODO: handle SSE retries
|
||||
Retry: (error) => Stream.die(error),
|
||||
HttpClientError: (error) => Stream.fromEffect(Errors.mapHttpClientError(error, "createMessageStream")),
|
||||
SchemaError: (error) => Stream.fail(Errors.mapSchemaError(error, "createMessageStream"))
|
||||
})
|
||||
) as any
|
||||
return [response, stream]
|
||||
}
|
||||
|
||||
const createMessageStream: Service["createMessageStream"] = (options) => {
|
||||
const request = HttpClientRequest.post("/v1/messages", {
|
||||
headers: Headers.fromInput({
|
||||
"anthropic-beta": options.params?.["anthropic-beta"] ?? undefined,
|
||||
"anthropic-version": options.params?.["anthropic-version"] ?? apiVersion
|
||||
}),
|
||||
body: HttpBody.jsonUnsafe({
|
||||
...options.payload,
|
||||
stream: true
|
||||
})
|
||||
})
|
||||
return httpClientOk.execute(request).pipe(
|
||||
Effect.map(buildMessageStream),
|
||||
Effect.catchTag(
|
||||
"HttpClientError",
|
||||
(error) => Errors.mapHttpClientError(error, "createMessageStream")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return AnthropicClient.of({
|
||||
client,
|
||||
streamRequest,
|
||||
createMessage,
|
||||
createMessageStream
|
||||
})
|
||||
},
|
||||
Effect.updateService(
|
||||
Headers.CurrentRedactedNames,
|
||||
Array.appendAll(Object.values(RedactedAnthropicHeaders))
|
||||
)
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// Layers
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Creates a layer for the Anthropic client with the given options.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you already have explicit `Options` values, such as an API key or
|
||||
* custom API URL, and want to provide `AnthropicClient` as a `Layer`.
|
||||
*
|
||||
* @see {@link make} for constructing the client service effectfully
|
||||
* @see {@link layerConfig} for loading client settings from `Config`
|
||||
*
|
||||
* @category layers
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const layer = (options: Options): Layer.Layer<AnthropicClient, never, HttpClient.HttpClient> =>
|
||||
Layer.effect(AnthropicClient, make(options))
|
||||
|
||||
/**
|
||||
* Creates a layer for the Anthropic client, loading the requisite configuration
|
||||
* via Effect's `Config` module.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you want to provide the Anthropic client as a `Layer` with
|
||||
* configuration loaded from Effect's `Config` module, such as from environment
|
||||
* variables or a secrets provider.
|
||||
*
|
||||
* @see {@link layer} for providing the client from explicit options instead of `Config`
|
||||
* @see {@link make} for constructing the client service effectfully
|
||||
*
|
||||
* @category layers
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const layerConfig = (options?: {
|
||||
/**
|
||||
* The Anthropic API key for authentication. Requests are made without authentication when this is omitted, which is
|
||||
* useful for proxied setups or testing.
|
||||
*/
|
||||
readonly apiKey?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
|
||||
|
||||
/**
|
||||
* The base URL for the Anthropic API. Override this to use a proxy or a different API-compatible endpoint.
|
||||
*
|
||||
* @default "https://api.anthropic.com"
|
||||
*/
|
||||
readonly apiUrl?: Config.Config<string> | undefined
|
||||
|
||||
/**
|
||||
* The Anthropic API version header value. This controls which version of the API to use.
|
||||
*
|
||||
* @default "2023-06-01"
|
||||
*/
|
||||
readonly apiVersion?: Config.Config<string> | undefined
|
||||
|
||||
/**
|
||||
* Optional transformer for the underlying HTTP client, such as middleware, logging, or custom request/response
|
||||
* handling.
|
||||
*/
|
||||
readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
|
||||
}): Layer.Layer<AnthropicClient, Config.ConfigError, HttpClient.HttpClient> =>
|
||||
Layer.effect(
|
||||
AnthropicClient,
|
||||
Effect.gen(function*() {
|
||||
const apiKey = Predicate.isNotUndefined(options?.apiKey)
|
||||
? yield* options.apiKey :
|
||||
undefined
|
||||
const apiUrl = Predicate.isNotUndefined(options?.apiUrl)
|
||||
? yield* options.apiUrl :
|
||||
undefined
|
||||
const apiVersion = Predicate.isNotUndefined(options?.apiVersion)
|
||||
? yield* options.apiVersion :
|
||||
undefined
|
||||
return yield* make({
|
||||
apiKey,
|
||||
apiUrl,
|
||||
apiVersion,
|
||||
transformClient: options?.transformClient
|
||||
})
|
||||
})
|
||||
)
|
||||
84
repos/effect/packages/ai/anthropic/src/AnthropicConfig.ts
Normal file
84
repos/effect/packages/ai/anthropic/src/AnthropicConfig.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* The `AnthropicConfig` module lets a workflow temporarily customize the HTTP
|
||||
* client used by generated Anthropic requests. It is used by
|
||||
* `AnthropicClient` when request helpers run, so code can add middleware,
|
||||
* logging, or other client changes without rebuilding the client layer.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import type { HttpClient } from "effect/unstable/http/HttpClient"
|
||||
|
||||
/**
|
||||
* Service tag for Anthropic client configuration overrides, such as transformations applied to the generated HTTP client.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need to provide or read Anthropic client configuration through
|
||||
* Effect's context from a layer or integration.
|
||||
*
|
||||
* @see {@link withClientTransform} for scoping an HTTP client transformation
|
||||
*
|
||||
* @category services
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class AnthropicConfig extends Context.Service<
|
||||
AnthropicConfig,
|
||||
AnthropicConfig.Service
|
||||
>()("@effect/ai-anthropic/AnthropicConfig") {
|
||||
/**
|
||||
* Gets the configured Anthropic service from the current context when present.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
static readonly getOrUndefined: Effect.Effect<typeof AnthropicConfig.Service | undefined> = Effect.map(
|
||||
Effect.context<never>(),
|
||||
(services) => services.mapUnsafe.get(AnthropicConfig.key)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Namespace containing types associated with the `AnthropicConfig` service.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export declare namespace AnthropicConfig {
|
||||
/**
|
||||
* Configuration provided through `AnthropicConfig`.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Use `transformClient` to wrap or replace the `HttpClient` used by generated Anthropic API requests.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface Service {
|
||||
readonly transformClient?: ((client: HttpClient) => HttpClient) | undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an effect with an `AnthropicConfig` override that transforms the underlying `HttpClient` used by generated Anthropic requests.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need to apply a temporary `HttpClient` transformation, such as adding middleware or logging, to a
|
||||
* specific scope of an effectful program.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const withClientTransform: {
|
||||
(transform: (client: HttpClient) => HttpClient): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
|
||||
<A, E, R>(self: Effect.Effect<A, E, R>, transform: (client: HttpClient) => HttpClient): Effect.Effect<A, E, R>
|
||||
} = dual(2, <A, E, R>(
|
||||
self: Effect.Effect<A, E, R>,
|
||||
transformClient: (client: HttpClient) => HttpClient
|
||||
) =>
|
||||
Effect.flatMap(
|
||||
AnthropicConfig.getOrUndefined,
|
||||
(config) => Effect.provideService(self, AnthropicConfig, { ...config, transformClient })
|
||||
))
|
||||
212
repos/effect/packages/ai/anthropic/src/AnthropicError.ts
Normal file
212
repos/effect/packages/ai/anthropic/src/AnthropicError.ts
Normal file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* Anthropic error metadata augmentation.
|
||||
*
|
||||
* Provides Anthropic-specific metadata fields for AI error types through module
|
||||
* augmentation, enabling typed access to Anthropic error details.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Anthropic-specific error metadata fields.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Contains the Anthropic error type and request identifier copied from provider
|
||||
* error responses when available. Either field may be `null` when Anthropic
|
||||
* does not include it or the response cannot be decoded.
|
||||
*
|
||||
* @see {@link AnthropicRateLimitMetadata} for rate-limit responses that also include parsed Anthropic rate-limit headers
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type AnthropicErrorMetadata = {
|
||||
/**
|
||||
* The Anthropic error type returned by the API.
|
||||
*/
|
||||
readonly errorType: string | null
|
||||
/**
|
||||
* The unique request ID for debugging with Anthropic support.
|
||||
*/
|
||||
readonly requestId: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic-specific rate limit metadata fields.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Extends base error metadata with rate limit-specific information from Anthropic's rate limit headers.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type AnthropicRateLimitMetadata = AnthropicErrorMetadata & {
|
||||
/**
|
||||
* Number of requests allowed in the current period.
|
||||
*/
|
||||
readonly requestsLimit: number | null
|
||||
/**
|
||||
* Number of requests remaining in the current period.
|
||||
*/
|
||||
readonly requestsRemaining: number | null
|
||||
/**
|
||||
* Time when the request rate limit resets.
|
||||
*/
|
||||
readonly requestsReset: string | null
|
||||
/**
|
||||
* Number of tokens allowed in the current period.
|
||||
*/
|
||||
readonly tokensLimit: number | null
|
||||
/**
|
||||
* Number of tokens remaining in the current period.
|
||||
*/
|
||||
readonly tokensRemaining: number | null
|
||||
/**
|
||||
* Time when the token rate limit resets.
|
||||
*/
|
||||
readonly tokensReset: string | null
|
||||
}
|
||||
|
||||
declare module "effect/unstable/ai/AiError" {
|
||||
/**
|
||||
* Anthropic metadata attached to `RateLimitError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Includes request identifiers, Anthropic error types, and parsed request or token limit headers when the provider rejects a request due to rate limits.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface RateLimitErrorMetadata {
|
||||
readonly anthropic?: AnthropicRateLimitMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic metadata attached to `QuotaExhaustedError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Captures the Anthropic error type and request identifier for failures where the account or workspace has exhausted its available quota.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface QuotaExhaustedErrorMetadata {
|
||||
readonly anthropic?: AnthropicErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic metadata attached to `AuthenticationError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves Anthropic error details for missing, invalid, or unauthorized API credentials while keeping the error in the shared AI error model.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface AuthenticationErrorMetadata {
|
||||
readonly anthropic?: AnthropicErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic metadata attached to `ContentPolicyError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Records Anthropic error details returned when a request or response is rejected by Anthropic safety or content policy enforcement.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface ContentPolicyErrorMetadata {
|
||||
readonly anthropic?: AnthropicErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic metadata attached to `InvalidRequestError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Provides the Anthropic error type and request identifier for malformed or unsupported requests rejected before model execution.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InvalidRequestErrorMetadata {
|
||||
readonly anthropic?: AnthropicErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic metadata attached to `InternalProviderError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves Anthropic request correlation data for provider-side failures that should be reported or investigated with Anthropic support.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InternalProviderErrorMetadata {
|
||||
readonly anthropic?: AnthropicErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic metadata attached to `InvalidOutputError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Describes Anthropic-specific context for responses that could not be decoded or interpreted as valid AI output.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InvalidOutputErrorMetadata {
|
||||
readonly anthropic?: AnthropicErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic metadata attached to `StructuredOutputError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Captures Anthropic error details for structured-output failures, including request correlation data useful when diagnosing schema-related responses.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface StructuredOutputErrorMetadata {
|
||||
readonly anthropic?: AnthropicErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic metadata attached to `UnsupportedSchemaError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Provides Anthropic error details for schemas that cannot be represented by or submitted to the Anthropic API.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface UnsupportedSchemaErrorMetadata {
|
||||
readonly anthropic?: AnthropicErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Anthropic metadata attached to `UnknownError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Retains the Anthropic error type and request identifier when a provider response cannot be classified as a more specific AI error.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface UnknownErrorMetadata {
|
||||
readonly anthropic?: AnthropicErrorMetadata | null
|
||||
}
|
||||
}
|
||||
3105
repos/effect/packages/ai/anthropic/src/AnthropicLanguageModel.ts
Normal file
3105
repos/effect/packages/ai/anthropic/src/AnthropicLanguageModel.ts
Normal file
File diff suppressed because it is too large
Load Diff
132
repos/effect/packages/ai/anthropic/src/AnthropicTelemetry.ts
Normal file
132
repos/effect/packages/ai/anthropic/src/AnthropicTelemetry.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* The `AnthropicTelemetry` module defines Anthropic-specific telemetry
|
||||
* attributes and a helper for adding them to a tracing span. It keeps the
|
||||
* standard GenAI telemetry attributes and adds request and response metadata
|
||||
* under the `gen_ai.anthropic.*` OpenTelemetry namespaces.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import { dual } from "effect/Function"
|
||||
import * as String from "effect/String"
|
||||
import type { Span } from "effect/Tracer"
|
||||
import type { Simplify } from "effect/Types"
|
||||
import * as Telemetry from "effect/unstable/ai/Telemetry"
|
||||
|
||||
/**
|
||||
* The attributes used to describe telemetry in the context of Generative
|
||||
* Artificial Intelligence (GenAI) Models requests and responses.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* These attributes follow the OpenTelemetry generative AI semantic
|
||||
* conventions:
|
||||
* https://opentelemetry.io/docs/specs/semconv/attributes-registry/gen-ai/
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type AnthropicTelemetryAttributes = Simplify<
|
||||
& Telemetry.GenAITelemetryAttributes
|
||||
& Telemetry.AttributesWithPrefix<RequestAttributes, "gen_ai.anthropic.request">
|
||||
& Telemetry.AttributesWithPrefix<ResponseAttributes, "gen_ai.anthropic.response">
|
||||
>
|
||||
|
||||
/**
|
||||
* All telemetry attributes which are part of the GenAI specification,
|
||||
* including the Anthropic-specific attributes.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type AllAttributes = Telemetry.AllAttributes & RequestAttributes & ResponseAttributes
|
||||
|
||||
/**
|
||||
* Telemetry attributes which are part of the GenAI specification and are
|
||||
* namespaced by `gen_ai.anthropic.request`.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface RequestAttributes {
|
||||
/**
|
||||
* Whether extended thinking is enabled.
|
||||
*/
|
||||
readonly extendedThinking?: boolean | null | undefined
|
||||
/**
|
||||
* The budget tokens for extended thinking.
|
||||
*/
|
||||
readonly thinkingBudgetTokens?: number | null | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Telemetry attributes which are part of the GenAI specification and are
|
||||
* namespaced by `gen_ai.anthropic.response`.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface ResponseAttributes {
|
||||
/**
|
||||
* The stop reason from the response.
|
||||
*/
|
||||
readonly stopReason?: string | null | undefined
|
||||
/**
|
||||
* Number of cache creation input tokens.
|
||||
*/
|
||||
readonly cacheCreationInputTokens?: number | null | undefined
|
||||
/**
|
||||
* Number of cache read input tokens.
|
||||
*/
|
||||
readonly cacheReadInputTokens?: number | null | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Options accepted by `addGenAIAnnotations`, combining standard GenAI telemetry attributes with optional Anthropic request and response attributes.
|
||||
*
|
||||
* @category options
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type AnthropicTelemetryAttributeOptions = Telemetry.GenAITelemetryAttributeOptions & {
|
||||
anthropic?: {
|
||||
request?: RequestAttributes | undefined
|
||||
response?: ResponseAttributes | undefined
|
||||
} | undefined
|
||||
}
|
||||
|
||||
const addAnthropicRequestAttributes = Telemetry.addSpanAttributes("gen_ai.anthropic.request", String.camelToSnake)<
|
||||
RequestAttributes
|
||||
>
|
||||
const addAnthropicResponseAttributes = Telemetry.addSpanAttributes("gen_ai.anthropic.response", String.camelToSnake)<
|
||||
ResponseAttributes
|
||||
>
|
||||
|
||||
/**
|
||||
* Applies the specified Anthropic GenAI telemetry attributes to the provided
|
||||
* `Span`.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to annotate an Anthropic model span with standard GenAI telemetry
|
||||
* attributes and Anthropic-specific request or response metadata.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* This method mutates the `Span` in place.
|
||||
*
|
||||
* @category annotations
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const addGenAIAnnotations: {
|
||||
(options: AnthropicTelemetryAttributeOptions): (span: Span) => void
|
||||
(span: Span, options: AnthropicTelemetryAttributeOptions): void
|
||||
} = dual(2, (span: Span, options: AnthropicTelemetryAttributeOptions) => {
|
||||
Telemetry.addGenAIAnnotations(span, options)
|
||||
if (options.anthropic != null) {
|
||||
if (options.anthropic.request != null) {
|
||||
addAnthropicRequestAttributes(span, options.anthropic.request)
|
||||
}
|
||||
if (options.anthropic.response != null) {
|
||||
addAnthropicResponseAttributes(span, options.anthropic.response)
|
||||
}
|
||||
}
|
||||
})
|
||||
2518
repos/effect/packages/ai/anthropic/src/AnthropicTool.ts
Normal file
2518
repos/effect/packages/ai/anthropic/src/AnthropicTool.ts
Normal file
File diff suppressed because it is too large
Load Diff
12592
repos/effect/packages/ai/anthropic/src/Generated.ts
Normal file
12592
repos/effect/packages/ai/anthropic/src/Generated.ts
Normal file
File diff suppressed because it is too large
Load Diff
40
repos/effect/packages/ai/anthropic/src/index.ts
Normal file
40
repos/effect/packages/ai/anthropic/src/index.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
// @barrel: Auto-generated exports. Do not edit manually.
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as AnthropicClient from "./AnthropicClient.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as AnthropicConfig from "./AnthropicConfig.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as AnthropicError from "./AnthropicError.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as AnthropicLanguageModel from "./AnthropicLanguageModel.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as AnthropicTelemetry from "./AnthropicTelemetry.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as AnthropicTool from "./AnthropicTool.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as Generated from "./Generated.ts"
|
||||
370
repos/effect/packages/ai/anthropic/src/internal/errors.ts
Normal file
370
repos/effect/packages/ai/anthropic/src/internal/errors.ts
Normal file
@@ -0,0 +1,370 @@
|
||||
import * as Duration from "effect/Duration"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import * as Number from "effect/Number"
|
||||
import * as Option from "effect/Option"
|
||||
import * as Predicate from "effect/Predicate"
|
||||
import * as Redactable from "effect/Redactable"
|
||||
import * as Schema from "effect/Schema"
|
||||
import * as AiError from "effect/unstable/ai/AiError"
|
||||
import type * as Response from "effect/unstable/ai/Response"
|
||||
import type * as HttpClientError from "effect/unstable/http/HttpClientError"
|
||||
import type * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
||||
import type * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
|
||||
import type { AnthropicErrorMetadata } from "../AnthropicError.ts"
|
||||
import type * as Generated from "../Generated.ts"
|
||||
|
||||
// =============================================================================
|
||||
// Anthropic Error Body Schema
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const AnthropicErrorBody = Schema.Struct({
|
||||
type: Schema.Literal("error"),
|
||||
error: Schema.Struct({
|
||||
type: Schema.String,
|
||||
message: Schema.String
|
||||
})
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
export type AnthropicClientErrorBody = {
|
||||
readonly type: "error"
|
||||
readonly error: {
|
||||
readonly type: string
|
||||
readonly message: string
|
||||
}
|
||||
readonly request_id: string | null
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Error Mappers
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const mapSchemaError = dual<
|
||||
(method: string) => (error: Schema.SchemaError) => AiError.AiError,
|
||||
(error: Schema.SchemaError, method: string) => AiError.AiError
|
||||
>(2, (error, method) =>
|
||||
AiError.make({
|
||||
module: "AnthropicClient",
|
||||
method,
|
||||
reason: AiError.InvalidOutputError.fromSchemaError(error)
|
||||
}))
|
||||
|
||||
/** @internal */
|
||||
export const mapClientError = dual<
|
||||
(method: string) => (error: Generated.AnthropicClientError<string, AnthropicClientErrorBody>) => AiError.AiError,
|
||||
(error: Generated.AnthropicClientError<string, AnthropicClientErrorBody>, method: string) => AiError.AiError
|
||||
>(2, (error, method) => {
|
||||
const { request, response, cause } = error
|
||||
const status = response.status
|
||||
const headers = response.headers as Record<string, string>
|
||||
const metadata: AnthropicErrorMetadata = {
|
||||
errorType: cause.error.type,
|
||||
requestId: cause.request_id
|
||||
}
|
||||
const http = buildHttpContext({ request, response, body: JSON.stringify(cause) })
|
||||
const reason = mapStatusCodeToReason({
|
||||
status,
|
||||
headers,
|
||||
message: cause.error.message,
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
return AiError.make({ module: "AnthropicClient", method, reason })
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
export const mapHttpClientError = dual<
|
||||
(method: string) => (error: HttpClientError.HttpClientError) => Effect.Effect<never, AiError.AiError>,
|
||||
(error: HttpClientError.HttpClientError, method: string) => Effect.Effect<never, AiError.AiError>
|
||||
>(2, (error, method) => {
|
||||
const reason = error.reason
|
||||
switch (reason._tag) {
|
||||
case "TransportError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "AnthropicClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "TransportError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "EncodeError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "AnthropicClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "EncodeError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "InvalidUrlError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "AnthropicClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "InvalidUrlError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "StatusCodeError": {
|
||||
return mapStatusCodeError(reason, method)
|
||||
}
|
||||
case "DecodeError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "AnthropicClient",
|
||||
method,
|
||||
reason: new AiError.InvalidOutputError({
|
||||
description: reason.description ?? "Failed to decode response"
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "EmptyBodyError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "AnthropicClient",
|
||||
method,
|
||||
reason: new AiError.InvalidOutputError({
|
||||
description: reason.description ?? "Response body was empty"
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
const mapStatusCodeError = Effect.fnUntraced(function*(
|
||||
error: HttpClientError.StatusCodeError,
|
||||
method: string
|
||||
) {
|
||||
const { request, response, description } = error
|
||||
const status = response.status
|
||||
const headers = response.headers as Record<string, string>
|
||||
const requestId = headers["request-id"]
|
||||
|
||||
let body: string | undefined = description
|
||||
if (!description || !description.startsWith("{")) {
|
||||
const responseBody = yield* Effect.option(response.text)
|
||||
if (Option.isSome(responseBody) && responseBody.value) {
|
||||
body = responseBody.value
|
||||
}
|
||||
}
|
||||
|
||||
let json: unknown = undefined
|
||||
// @effect-diagnostics effect/tryCatchInEffectGen:off
|
||||
try {
|
||||
json = Predicate.isNotUndefined(body) ? JSON.parse(body) : undefined
|
||||
} catch {
|
||||
json = undefined
|
||||
}
|
||||
const decoded = Schema.decodeUnknownOption(AnthropicErrorBody)(json)
|
||||
|
||||
const reason = mapStatusCodeToReason({
|
||||
status,
|
||||
headers,
|
||||
message: Option.isSome(decoded) ? decoded.value.error.message : undefined,
|
||||
http: buildHttpContext({ request, response, body }),
|
||||
metadata: {
|
||||
errorType: Option.isSome(decoded) ? decoded.value.error.type : null,
|
||||
requestId: requestId ?? null
|
||||
}
|
||||
})
|
||||
|
||||
return yield* AiError.make({ module: "AnthropicClient", method, reason })
|
||||
})
|
||||
|
||||
// =============================================================================
|
||||
// Rate Limits
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const parseRateLimitHeaders = (headers: Record<string, string>) => {
|
||||
const retryAfterRaw = headers["retry-after"]
|
||||
let retryAfter: Duration.Duration | undefined
|
||||
if (Predicate.isNotUndefined(retryAfterRaw)) {
|
||||
const parsed = Number.parse(retryAfterRaw)
|
||||
if (Option.isSome(parsed)) {
|
||||
retryAfter = Duration.seconds(parsed.value)
|
||||
}
|
||||
}
|
||||
const requestsLimitRaw = headers["anthropic-ratelimit-requests-limit"]
|
||||
const requestsRemainingRaw = headers["anthropic-ratelimit-requests-remaining"]
|
||||
const tokensLimitRaw = headers["anthropic-ratelimit-tokens-limit"]
|
||||
const tokensRemainingRaw = headers["anthropic-ratelimit-tokens-remaining"]
|
||||
return {
|
||||
retryAfter,
|
||||
requestsLimit: Predicate.isNotUndefined(requestsLimitRaw) ? Option.getOrNull(Number.parse(requestsLimitRaw)) : null,
|
||||
requestsRemaining: Predicate.isNotUndefined(requestsRemainingRaw)
|
||||
? Option.getOrNull(Number.parse(requestsRemainingRaw))
|
||||
: null,
|
||||
requestsReset: headers["anthropic-ratelimit-requests-reset"] ?? null,
|
||||
tokensLimit: Predicate.isNotUndefined(tokensLimitRaw) ? Option.getOrNull(Number.parse(tokensLimitRaw)) : null,
|
||||
tokensRemaining: Predicate.isNotUndefined(tokensRemainingRaw)
|
||||
? Option.getOrNull(Number.parse(tokensRemainingRaw))
|
||||
: null,
|
||||
tokensReset: headers["anthropic-ratelimit-tokens-reset"] ?? null
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// HTTP Context
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const buildHttpRequestDetails = (
|
||||
request: HttpClientRequest.HttpClientRequest
|
||||
): typeof Response.HttpRequestDetails.Type => ({
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
urlParams: Array.from(request.urlParams),
|
||||
hash: Option.getOrUndefined(request.hash),
|
||||
headers: Redactable.redact(request.headers) as Record<string, string>
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
export const buildHttpContext = (params: {
|
||||
readonly request: HttpClientRequest.HttpClientRequest
|
||||
readonly response?: HttpClientResponse.HttpClientResponse
|
||||
readonly body?: string | undefined
|
||||
}): typeof AiError.HttpContext.Type => ({
|
||||
request: buildHttpRequestDetails(params.request),
|
||||
response: Predicate.isNotUndefined(params.response)
|
||||
? {
|
||||
status: params.response.status,
|
||||
headers: Redactable.redact(params.response.headers) as Record<string, string>
|
||||
}
|
||||
: undefined,
|
||||
body: params.body
|
||||
})
|
||||
|
||||
// =============================================================================
|
||||
// HTTP Status Code
|
||||
// =============================================================================
|
||||
|
||||
const buildInvalidRequestDescription = (params: {
|
||||
readonly status: number
|
||||
readonly message: string | undefined
|
||||
readonly method: string
|
||||
readonly url: string
|
||||
readonly errorType: string | null
|
||||
readonly requestId: string | null
|
||||
readonly body: string | undefined
|
||||
}): string => {
|
||||
const parts: Array<string> = []
|
||||
|
||||
if (params.message) {
|
||||
parts.push(params.message)
|
||||
} else {
|
||||
parts.push(`HTTP ${params.status}`)
|
||||
}
|
||||
|
||||
parts.push(`(${params.method} ${params.url})`)
|
||||
|
||||
if (params.errorType) {
|
||||
parts.push(`[type: ${params.errorType}]`)
|
||||
}
|
||||
|
||||
if (params.requestId) {
|
||||
parts.push(`[requestId: ${params.requestId}]`)
|
||||
}
|
||||
|
||||
if (!params.message && params.body) {
|
||||
const truncated = params.body.length > 200
|
||||
? params.body.slice(0, 200) + "..."
|
||||
: params.body
|
||||
parts.push(`Response: ${truncated}`)
|
||||
}
|
||||
|
||||
return parts.join(" ")
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const mapStatusCodeToReason = ({ status, headers, message, metadata, http }: {
|
||||
readonly status: number
|
||||
readonly headers: Record<string, string>
|
||||
readonly message: string | undefined
|
||||
readonly metadata: AnthropicErrorMetadata
|
||||
readonly http: typeof AiError.HttpContext.Type
|
||||
}): AiError.AiErrorReason => {
|
||||
const invalidRequestDescription = buildInvalidRequestDescription({
|
||||
status,
|
||||
message,
|
||||
method: http.request.method,
|
||||
url: http.request.url,
|
||||
errorType: metadata.errorType,
|
||||
requestId: metadata.requestId,
|
||||
body: http.body
|
||||
})
|
||||
|
||||
switch (status) {
|
||||
case 400:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { anthropic: metadata },
|
||||
http
|
||||
})
|
||||
case 401:
|
||||
return new AiError.AuthenticationError({
|
||||
kind: "InvalidKey",
|
||||
metadata: { anthropic: metadata },
|
||||
http
|
||||
})
|
||||
case 403:
|
||||
return new AiError.AuthenticationError({
|
||||
kind: "InsufficientPermissions",
|
||||
metadata: { anthropic: metadata },
|
||||
http
|
||||
})
|
||||
case 404:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { anthropic: metadata },
|
||||
http
|
||||
})
|
||||
case 422:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { anthropic: metadata },
|
||||
http
|
||||
})
|
||||
case 429: {
|
||||
const { retryAfter, ...rateLimitMetadata } = parseRateLimitHeaders(headers)
|
||||
return new AiError.RateLimitError({
|
||||
retryAfter,
|
||||
metadata: {
|
||||
anthropic: {
|
||||
...metadata,
|
||||
...rateLimitMetadata
|
||||
}
|
||||
},
|
||||
http
|
||||
})
|
||||
}
|
||||
case 529:
|
||||
return new AiError.InternalProviderError({
|
||||
description: message ?? "Anthropic API is overloaded",
|
||||
metadata: { anthropic: metadata },
|
||||
http
|
||||
})
|
||||
default:
|
||||
if (status >= 500) {
|
||||
return new AiError.InternalProviderError({
|
||||
description: message ?? "Server error",
|
||||
metadata: { anthropic: metadata },
|
||||
http
|
||||
})
|
||||
}
|
||||
return new AiError.UnknownError({
|
||||
description: message,
|
||||
metadata: { anthropic: metadata },
|
||||
http
|
||||
})
|
||||
}
|
||||
}
|
||||
26
repos/effect/packages/ai/anthropic/src/internal/utilities.ts
Normal file
26
repos/effect/packages/ai/anthropic/src/internal/utilities.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import * as Predicate from "effect/Predicate"
|
||||
import type * as Response from "effect/unstable/ai/Response"
|
||||
|
||||
const finishReasonMap: Record<string, Response.FinishReason> = {
|
||||
end_turn: "stop",
|
||||
max_tokens: "length",
|
||||
pause_turn: "pause",
|
||||
refusal: "content-filter",
|
||||
stop_sequence: "stop",
|
||||
tool_use: "tool-calls"
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const resolveFinishReason = (
|
||||
finishReason: string,
|
||||
isJsonResponse: boolean = false
|
||||
): Response.FinishReason => {
|
||||
const reason = finishReasonMap[finishReason]
|
||||
if (Predicate.isUndefined(reason)) {
|
||||
return "unknown"
|
||||
}
|
||||
if (isJsonResponse && reason === "tool-calls") {
|
||||
return "stop"
|
||||
}
|
||||
return reason
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
import { AnthropicClient, AnthropicLanguageModel, AnthropicTool } from "@effect/ai-anthropic"
|
||||
import { assert, describe, it } from "@effect/vitest"
|
||||
import { Effect, Layer, Redacted, Schema, Stream } from "effect"
|
||||
import { AnthropicStructuredOutput, LanguageModel, Tool, Toolkit } from "effect/unstable/ai"
|
||||
import { HttpClient, type HttpClientError, type HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
|
||||
|
||||
describe("AnthropicLanguageModel", () => {
|
||||
describe("streamText", () => {
|
||||
it.effect("decodes tool call params in content_block_stop", () =>
|
||||
Effect.gen(function*() {
|
||||
const toolParams = { pattern: "*.ts" }
|
||||
|
||||
const layer = AnthropicClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(sseResponse(request, [
|
||||
{
|
||||
type: "message_start",
|
||||
message: {
|
||||
id: "msg_test_1",
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
model: "claude-sonnet-4-20250514",
|
||||
content: [],
|
||||
stop_reason: null,
|
||||
stop_sequence: null,
|
||||
usage: {
|
||||
cache_creation: null,
|
||||
cache_creation_input_tokens: null,
|
||||
cache_read_input_tokens: null,
|
||||
inference_geo: null,
|
||||
input_tokens: 10,
|
||||
output_tokens: 0,
|
||||
service_tier: null
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "content_block_start",
|
||||
index: 0,
|
||||
content_block: {
|
||||
type: "tool_use",
|
||||
id: "toolu_test_1",
|
||||
name: "GlobTool",
|
||||
input: {}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "content_block_delta",
|
||||
index: 0,
|
||||
delta: {
|
||||
type: "input_json_delta",
|
||||
partial_json: JSON.stringify(toolParams)
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "content_block_stop",
|
||||
index: 0
|
||||
},
|
||||
{
|
||||
type: "message_delta",
|
||||
delta: {
|
||||
stop_reason: "tool_use",
|
||||
stop_sequence: null
|
||||
},
|
||||
usage: {
|
||||
cache_creation_input_tokens: null,
|
||||
cache_read_input_tokens: null,
|
||||
input_tokens: null,
|
||||
output_tokens: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "message_stop"
|
||||
}
|
||||
]))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const GlobTool = Tool.make("GlobTool", {
|
||||
description: "Search for files",
|
||||
parameters: Schema.Struct({ pattern: Schema.String }),
|
||||
success: Schema.String
|
||||
})
|
||||
|
||||
const toolkit = Toolkit.make(GlobTool)
|
||||
const toolkitLayer = toolkit.toLayer({
|
||||
GlobTool: () => Effect.succeed("found.ts")
|
||||
})
|
||||
|
||||
const partsChunk = yield* LanguageModel.streamText({
|
||||
prompt: "find ts files",
|
||||
toolkit,
|
||||
disableToolCallResolution: true
|
||||
}).pipe(
|
||||
Stream.runCollect,
|
||||
Effect.provide(AnthropicLanguageModel.model("claude-sonnet-4-20250514")),
|
||||
Effect.provide(toolkitLayer),
|
||||
Effect.provide(layer)
|
||||
)
|
||||
|
||||
const parts = globalThis.Array.from(partsChunk)
|
||||
const toolCall = parts.find((part) => part.type === "tool-call")
|
||||
assert.isDefined(toolCall)
|
||||
if (toolCall?.type !== "tool-call") {
|
||||
return
|
||||
}
|
||||
|
||||
assert.strictEqual(toolCall.name, "GlobTool")
|
||||
assert.deepStrictEqual(toolCall.params, toolParams)
|
||||
}))
|
||||
|
||||
// `Model` is an open enum in Anthropic's spec (`anyOf: [{ type: string }, ...consts]`), and it is
|
||||
// $ref'd by response schemas. Responses must therefore decode for model ids that are newer than the
|
||||
// generated literals, and the id must survive decoding unchanged.
|
||||
it.effect("decodes responses for a model id that is not a known literal", () =>
|
||||
Effect.gen(function*() {
|
||||
const layer = AnthropicClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(sseResponse(request, [
|
||||
{
|
||||
type: "message_start",
|
||||
message: {
|
||||
id: "msg_test_1",
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
model: "claude-not-a-known-model-id",
|
||||
content: [],
|
||||
stop_reason: null,
|
||||
stop_sequence: null,
|
||||
usage: {
|
||||
cache_creation: null,
|
||||
cache_creation_input_tokens: null,
|
||||
cache_read_input_tokens: null,
|
||||
inference_geo: null,
|
||||
input_tokens: 10,
|
||||
output_tokens: 0,
|
||||
service_tier: null
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "content_block_start",
|
||||
index: 0,
|
||||
content_block: { type: "text", text: "" }
|
||||
},
|
||||
{
|
||||
type: "content_block_delta",
|
||||
index: 0,
|
||||
delta: { type: "text_delta", text: "Hello" }
|
||||
},
|
||||
{
|
||||
type: "content_block_stop",
|
||||
index: 0
|
||||
},
|
||||
{
|
||||
type: "message_delta",
|
||||
delta: {
|
||||
stop_reason: "end_turn",
|
||||
stop_sequence: null
|
||||
},
|
||||
usage: {
|
||||
cache_creation_input_tokens: null,
|
||||
cache_read_input_tokens: null,
|
||||
input_tokens: null,
|
||||
output_tokens: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "message_stop"
|
||||
}
|
||||
]))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const partsChunk = yield* LanguageModel.streamText({
|
||||
prompt: "say hello"
|
||||
}).pipe(
|
||||
Stream.runCollect,
|
||||
Effect.provide(AnthropicLanguageModel.model("claude-not-a-known-model-id")),
|
||||
Effect.provide(layer)
|
||||
)
|
||||
|
||||
const parts = globalThis.Array.from(partsChunk)
|
||||
const metadata = parts.find((part) => part.type === "response-metadata")
|
||||
assert.isDefined(metadata)
|
||||
if (metadata?.type !== "response-metadata") {
|
||||
return
|
||||
}
|
||||
|
||||
assert.strictEqual(metadata.modelId, "claude-not-a-known-model-id")
|
||||
|
||||
const text = parts.find((part) => part.type === "text-delta")
|
||||
assert.isDefined(text)
|
||||
if (text?.type !== "text-delta") {
|
||||
return
|
||||
}
|
||||
|
||||
assert.strictEqual(text.delta, "Hello")
|
||||
}))
|
||||
})
|
||||
|
||||
describe("generateText", () => {
|
||||
it.effect("encodes dynamic tools", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined = undefined
|
||||
const layer = AnthropicClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, {
|
||||
id: "msg_test_1",
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
model: "claude-sonnet-4-20250514",
|
||||
content: [{ type: "text", text: "Done" }],
|
||||
stop_reason: "end_turn",
|
||||
stop_sequence: null,
|
||||
usage: {
|
||||
cache_creation: null,
|
||||
cache_creation_input_tokens: null,
|
||||
cache_read_input_tokens: null,
|
||||
inference_geo: null,
|
||||
input_tokens: 10,
|
||||
output_tokens: 5,
|
||||
service_tier: null
|
||||
}
|
||||
}))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
const inputSchema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
query: { type: "string" },
|
||||
limit: { type: "number" }
|
||||
},
|
||||
required: ["query"],
|
||||
additionalProperties: false
|
||||
} as const
|
||||
|
||||
const DynamicTool = Tool.dynamic("DynamicTool", {
|
||||
description: "A dynamic tool",
|
||||
parameters: inputSchema
|
||||
})
|
||||
|
||||
yield* LanguageModel.generateText({
|
||||
prompt: "Use the dynamic tool",
|
||||
toolkit: Toolkit.make(DynamicTool),
|
||||
disableToolCallResolution: true
|
||||
}).pipe(
|
||||
Effect.provide(AnthropicLanguageModel.model("claude-sonnet-4-20250514")),
|
||||
Effect.provide(layer)
|
||||
)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const body = yield* getRequestBody(capturedRequest)
|
||||
const dynamicTool = body.tools.find((tool: any) => tool.name === "DynamicTool")
|
||||
|
||||
assert.isDefined(dynamicTool)
|
||||
if (dynamicTool === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
assert.strictEqual(dynamicTool.description, "A dynamic tool")
|
||||
assert.deepStrictEqual(dynamicTool.input_schema, inputSchema)
|
||||
}))
|
||||
})
|
||||
|
||||
describe("generateObject", () => {
|
||||
// A model that supports native structured output requests it via `output_config.format` (json_schema)
|
||||
// rather than falling back to a forced JSON tool.
|
||||
const assertNativeStructuredOutput = (model: string) =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined = undefined
|
||||
const layer = AnthropicClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, {
|
||||
id: "msg_test_1",
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
model,
|
||||
content: [{ type: "text", text: JSON.stringify({ name: "John", age: 30 }) }],
|
||||
stop_reason: "end_turn",
|
||||
stop_sequence: null,
|
||||
usage: {
|
||||
cache_creation: null,
|
||||
cache_creation_input_tokens: null,
|
||||
cache_read_input_tokens: null,
|
||||
inference_geo: null,
|
||||
input_tokens: 10,
|
||||
output_tokens: 5,
|
||||
service_tier: null
|
||||
}
|
||||
}))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
// Assert the request shape; the response outcome is irrelevant here.
|
||||
yield* LanguageModel.generateObject({
|
||||
prompt: "Give me a person",
|
||||
schema: Schema.Struct({ name: Schema.String, age: Schema.Number })
|
||||
}).pipe(
|
||||
Effect.provide(AnthropicLanguageModel.model(model)),
|
||||
Effect.provide(layer),
|
||||
Effect.ignore
|
||||
)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const body = yield* getRequestBody(capturedRequest)
|
||||
assert.strictEqual(body.output_config?.format?.type, "json_schema")
|
||||
})
|
||||
|
||||
it.effect("uses native json_schema output for claude-opus-4-6", () =>
|
||||
assertNativeStructuredOutput("claude-opus-4-6"))
|
||||
|
||||
it.effect("uses native json_schema output for claude-sonnet-4-6", () =>
|
||||
assertNativeStructuredOutput("claude-sonnet-4-6"))
|
||||
})
|
||||
|
||||
// The packaged `Memory_20250818` tool ships `customName: "AnthropicMemory"` /
|
||||
// `providerName: "memory"`, and is a client-executed provider tool. These
|
||||
// tests cover the round-trip that was broken on beta.98 (see #2615):
|
||||
// - the provider wire name ("memory") must resolve to the toolkit's custom
|
||||
// name ("AnthropicMemory"), otherwise `makeResponse` raises ToolNotFound
|
||||
// - `view_range` uses `Schema.optionalKey`, otherwise the Anthropic codec
|
||||
// rejects the tool schema with "Unsupported AST Undefined"
|
||||
// - `create` must carry `file_text`, otherwise the file body is dropped
|
||||
describe("Memory tool", () => {
|
||||
const memoryResponse = (request: HttpClientRequest.HttpClientRequest, input: unknown) =>
|
||||
jsonResponse(request, {
|
||||
id: "msg_test_1",
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
model: "claude-sonnet-4-20250514",
|
||||
content: [{ type: "tool_use", id: "toolu_mem_1", name: "memory", input }],
|
||||
stop_reason: "tool_use",
|
||||
stop_sequence: null,
|
||||
usage: {
|
||||
cache_creation: null,
|
||||
cache_creation_input_tokens: null,
|
||||
cache_read_input_tokens: null,
|
||||
inference_geo: null,
|
||||
input_tokens: 10,
|
||||
output_tokens: 5,
|
||||
service_tier: null
|
||||
}
|
||||
})
|
||||
|
||||
it.effect("resolves the provider wire name to the tool's custom name (view)", () =>
|
||||
Effect.gen(function*() {
|
||||
let receivedParams: unknown = undefined
|
||||
const toolkit = Toolkit.make(AnthropicTool.Memory_20250818({}))
|
||||
const toolkitLayer = toolkit.toLayer({
|
||||
AnthropicMemory: (params) => {
|
||||
receivedParams = params
|
||||
return Effect.succeed("memory listing")
|
||||
}
|
||||
})
|
||||
|
||||
const layer = AnthropicClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => Effect.succeed(memoryResponse(request, { command: "view", path: "/memories" })))
|
||||
))
|
||||
)
|
||||
|
||||
const response = yield* LanguageModel.generateText({
|
||||
prompt: "check memory",
|
||||
toolkit
|
||||
}).pipe(
|
||||
Effect.provide(AnthropicLanguageModel.model("claude-sonnet-4-20250514")),
|
||||
Effect.provide(toolkitLayer),
|
||||
Effect.provide(layer)
|
||||
)
|
||||
|
||||
// Handler was resolved under the custom name and received the decoded command
|
||||
assert.deepStrictEqual(receivedParams, { command: "view", path: "/memories" })
|
||||
|
||||
const toolResult = response.toolResults[0]
|
||||
assert.isDefined(toolResult)
|
||||
assert.strictEqual(toolResult.name, "AnthropicMemory")
|
||||
assert.strictEqual(toolResult.result, "memory listing")
|
||||
}))
|
||||
|
||||
it.effect("decodes the create command including file_text", () =>
|
||||
Effect.gen(function*() {
|
||||
let receivedParams: unknown = undefined
|
||||
const toolkit = Toolkit.make(AnthropicTool.Memory_20250818({}))
|
||||
const toolkitLayer = toolkit.toLayer({
|
||||
AnthropicMemory: (params) => {
|
||||
receivedParams = params
|
||||
return Effect.succeed("File created successfully at: /memories/notes.txt")
|
||||
}
|
||||
})
|
||||
|
||||
const layer = AnthropicClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(memoryResponse(request, {
|
||||
command: "create",
|
||||
path: "/memories/notes.txt",
|
||||
file_text: "hello world"
|
||||
}))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const response = yield* LanguageModel.generateText({
|
||||
prompt: "save a note",
|
||||
toolkit
|
||||
}).pipe(
|
||||
Effect.provide(AnthropicLanguageModel.model("claude-sonnet-4-20250514")),
|
||||
Effect.provide(toolkitLayer),
|
||||
Effect.provide(layer)
|
||||
)
|
||||
|
||||
assert.deepStrictEqual(receivedParams, {
|
||||
command: "create",
|
||||
path: "/memories/notes.txt",
|
||||
file_text: "hello world"
|
||||
})
|
||||
assert.strictEqual(response.toolResults[0]?.name, "AnthropicMemory")
|
||||
}))
|
||||
})
|
||||
|
||||
// Client-executed (`requiresHandler`) provider tools have their `parameters`
|
||||
// decoded via `toCodecAnthropic` when the model calls them. Optional
|
||||
// parameters must use `Schema.optionalKey` (not `Schema.optional`), otherwise
|
||||
// the codec rejects the schema with "Unsupported AST Undefined" (see #2615).
|
||||
describe("client provider tool parameters compile with the Anthropic codec", () => {
|
||||
const displayArgs = { displayWidthPx: 800, displayHeightPx: 600 }
|
||||
const clientTools: ReadonlyArray<readonly [string, Tool.AnyProviderDefined]> = [
|
||||
["Bash_20241022", AnthropicTool.Bash_20241022({})],
|
||||
["Bash_20250124", AnthropicTool.Bash_20250124({})],
|
||||
["ComputerUse_20241022", AnthropicTool.ComputerUse_20241022(displayArgs)],
|
||||
["ComputerUse_20250124", AnthropicTool.ComputerUse_20250124(displayArgs)],
|
||||
["ComputerUse_20251124", AnthropicTool.ComputerUse_20251124(displayArgs)],
|
||||
["Memory_20250818", AnthropicTool.Memory_20250818({})],
|
||||
["TextEditor_20241022", AnthropicTool.TextEditor_20241022({})],
|
||||
["TextEditor_20250124", AnthropicTool.TextEditor_20250124({})],
|
||||
["TextEditor_20250429", AnthropicTool.TextEditor_20250429({})],
|
||||
["TextEditor_20250728", AnthropicTool.TextEditor_20250728({})]
|
||||
]
|
||||
|
||||
for (const [name, tool] of clientTools) {
|
||||
it(name, () => {
|
||||
const codec = AnthropicStructuredOutput.toCodecAnthropic(tool.parametersSchema)
|
||||
assert.isDefined(codec)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const makeHttpClient = (
|
||||
handler: (
|
||||
request: HttpClientRequest.HttpClientRequest
|
||||
) => Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError.HttpClientError>
|
||||
) =>
|
||||
HttpClient.makeWith(
|
||||
Effect.fnUntraced(function*(requestEffect) {
|
||||
const request = yield* requestEffect
|
||||
return yield* handler(request)
|
||||
}),
|
||||
Effect.succeed as HttpClient.HttpClient.Preprocess<HttpClientError.HttpClientError, never>
|
||||
)
|
||||
|
||||
const sseResponse = (
|
||||
request: HttpClientRequest.HttpClientRequest,
|
||||
events: ReadonlyArray<unknown>
|
||||
): HttpClientResponse.HttpClientResponse =>
|
||||
HttpClientResponse.fromWeb(
|
||||
request,
|
||||
new Response(toSseBody(events), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"content-type": "text/event-stream"
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const jsonResponse = (
|
||||
request: HttpClientRequest.HttpClientRequest,
|
||||
body: unknown
|
||||
): HttpClientResponse.HttpClientResponse =>
|
||||
HttpClientResponse.fromWeb(
|
||||
request,
|
||||
new Response(JSON.stringify(body), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const getRequestBody = (request: HttpClientRequest.HttpClientRequest) =>
|
||||
Effect.gen(function*() {
|
||||
const body = request.body
|
||||
if (body._tag !== "Uint8Array") {
|
||||
return yield* Effect.die(new Error("Expected Uint8Array body"))
|
||||
}
|
||||
return JSON.parse(new TextDecoder().decode(body.body))
|
||||
})
|
||||
|
||||
const toSseBody = (events: ReadonlyArray<unknown>): string =>
|
||||
events.map((event) => `event: message_stream\ndata: ${JSON.stringify(event)}\n\n`).join("")
|
||||
8
repos/effect/packages/ai/anthropic/tsconfig.json
Normal file
8
repos/effect/packages/ai/anthropic/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/tsconfig",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{ "path": "../../effect" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { AnthropicLanguageModel } from "@effect/ai-anthropic"
|
||||
import { describe, expect, it } from "tstyche"
|
||||
|
||||
declare const acceptsKnownModel: (model: AnthropicLanguageModel.Model) => void
|
||||
|
||||
describe("AnthropicLanguageModel", () => {
|
||||
describe("Model", () => {
|
||||
it("keeps the known model ids as literals, while the constructors still accept custom ids", () => {
|
||||
expect(acceptsKnownModel).type.toBeCallableWith("claude-opus-4-8")
|
||||
expect(acceptsKnownModel).type.not.toBeCallableWith("not-a-real-model")
|
||||
expect(AnthropicLanguageModel.model).type.toBeCallableWith("not-a-real-model")
|
||||
})
|
||||
})
|
||||
})
|
||||
6
repos/effect/packages/ai/anthropic/vitest.config.ts
Normal file
6
repos/effect/packages/ai/anthropic/vitest.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { mergeConfig, type ViteUserConfig } from "vitest/config"
|
||||
import shared from "../../../vitest.shared.ts"
|
||||
|
||||
const config: ViteUserConfig = {}
|
||||
|
||||
export default mergeConfig(shared, config)
|
||||
742
repos/effect/packages/ai/openai-compat/CHANGELOG.md
Normal file
742
repos/effect/packages/ai/openai-compat/CHANGELOG.md
Normal file
@@ -0,0 +1,742 @@
|
||||
# @effect/ai-openai-compat
|
||||
|
||||
## 4.0.0-beta.99
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8ce4795`](https://github.com/Effect-TS/effect/commit/8ce4795ccbaebca4292757db568c005a992546a4), [`80b539f`](https://github.com/Effect-TS/effect/commit/80b539f8aba68f478c75c35c2b4140c4ffc4fada), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`e6e6dba`](https://github.com/Effect-TS/effect/commit/e6e6dba6e9d86e7c2ad27dcedf289db76a19697f), [`bfb203e`](https://github.com/Effect-TS/effect/commit/bfb203e95aa439f731acad37fc3a9a831a190f1c), [`2e9a34a`](https://github.com/Effect-TS/effect/commit/2e9a34ac2bece4f3a206160480c991e3841dc67a), [`55d4eb3`](https://github.com/Effect-TS/effect/commit/55d4eb34f2c64d54f6a25a305b5c5438ebd7934e), [`bddb010`](https://github.com/Effect-TS/effect/commit/bddb010eac3d4436cb094edbbee7460c5440c162), [`a328835`](https://github.com/Effect-TS/effect/commit/a328835e50d76bc96648a1c1550456e8c9f81210), [`5560d05`](https://github.com/Effect-TS/effect/commit/5560d05aa6abdd29466d9c3412cc5e648b0adbde), [`8f6e3ad`](https://github.com/Effect-TS/effect/commit/8f6e3adb185b16e8820b98c509b308086f7ff1af), [`46997fa`](https://github.com/Effect-TS/effect/commit/46997fa60401f5e3c93daa4b61f7df8e31caaab4), [`9e6e12d`](https://github.com/Effect-TS/effect/commit/9e6e12d75c118cd265496f2880490d1f33a5c8bf), [`3394b93`](https://github.com/Effect-TS/effect/commit/3394b93d97d6f24fc38670641d1490289ffca7f1), [`febeabc`](https://github.com/Effect-TS/effect/commit/febeabc3f7c31094da000a23edeaabfe2ab00a38), [`54161c9`](https://github.com/Effect-TS/effect/commit/54161c98f6f3569e0c31842f54e6a257f9421c4c), [`385f7a4`](https://github.com/Effect-TS/effect/commit/385f7a4ee4a7359928597ea56d151dbaf5eb5802), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`7543afe`](https://github.com/Effect-TS/effect/commit/7543afea6f4d97d1f1ad876224323838a48daadd), [`44b9cf3`](https://github.com/Effect-TS/effect/commit/44b9cf3d240d726997b4bbcd0ede48e074d3c456), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`0a8aa6a`](https://github.com/Effect-TS/effect/commit/0a8aa6acb90a72b91c24d17133c950e4cacd8abd), [`c8d9fcf`](https://github.com/Effect-TS/effect/commit/c8d9fcf7b030f7c474effbab2764ce7aee1c7209), [`9ca7f9a`](https://github.com/Effect-TS/effect/commit/9ca7f9a69363e4485645966d5a93b8f9597c5206), [`e7aca89`](https://github.com/Effect-TS/effect/commit/e7aca894bb32fbb785b5830837e6061c415a6015), [`55d7560`](https://github.com/Effect-TS/effect/commit/55d75609b8acf8a1b54c1b1c7fbbb65ec741aa3e), [`f809189`](https://github.com/Effect-TS/effect/commit/f809189ddf6b6011ba43a9901baaa734e315da2a), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`0ebdbe7`](https://github.com/Effect-TS/effect/commit/0ebdbe74463dc84385956d0b1e8c2b79ebab5400), [`7517d09`](https://github.com/Effect-TS/effect/commit/7517d09f12a0b183a81bd425962c4e280a68b05d), [`212493b`](https://github.com/Effect-TS/effect/commit/212493b9a1eb98cd1ef6959c707a2e5784a5ae91), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`80ea8cb`](https://github.com/Effect-TS/effect/commit/80ea8cb9222ca73f564c8267ab2f82966fea027a), [`8df19f4`](https://github.com/Effect-TS/effect/commit/8df19f4fe81d90cc33ace88b9a77e5534f82d604)]:
|
||||
- effect@4.0.0-beta.99
|
||||
|
||||
## 4.0.0-beta.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2608](https://github.com/Effect-TS/effect-smol/pull/2608) [`5f142a2`](https://github.com/Effect-TS/effect-smol/commit/5f142a2136e62274ec121273fecb5d248c19f159) Thanks @tim-smart! - Preserve autocomplete for known OpenAI-compatible model config properties while allowing provider-specific properties.
|
||||
|
||||
- [#2576](https://github.com/Effect-TS/effect-smol/pull/2576) [`0c2ed5e`](https://github.com/Effect-TS/effect-smol/commit/0c2ed5ee0ef5a437c5e6a2de456a5ddf214c281f) Thanks @tim-smart! - Normalize empty assistant message content to an empty string for OpenAI-compatible providers that reject null content values.
|
||||
|
||||
- Updated dependencies [[`989603b`](https://github.com/Effect-TS/effect-smol/commit/989603b60ab1197b64acf214208e0d370cd1f842), [`214c458`](https://github.com/Effect-TS/effect-smol/commit/214c458084bb6995d543cd37d1055f24be3d454e), [`a037273`](https://github.com/Effect-TS/effect-smol/commit/a0372736ac34796969b051bbba4717d7983f1ebe), [`97fdaa9`](https://github.com/Effect-TS/effect-smol/commit/97fdaa9c1f522c65e579365d314a07878e2b904f), [`b24d248`](https://github.com/Effect-TS/effect-smol/commit/b24d248c8df44222ce642087cde2bd859a2dc709), [`19c222c`](https://github.com/Effect-TS/effect-smol/commit/19c222cac2353a3d7b7733caecb00556fffe9a5c), [`eec85dd`](https://github.com/Effect-TS/effect-smol/commit/eec85ddba09ea326fd268ee33eeffd47e50d4671), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`8849052`](https://github.com/Effect-TS/effect-smol/commit/884905232d1e9a365e046d8dde27bf9c5707f57f), [`c15e16a`](https://github.com/Effect-TS/effect-smol/commit/c15e16ad130d1fbde25d912b7ac55995066cb35b), [`01d00a3`](https://github.com/Effect-TS/effect-smol/commit/01d00a3abfbf1f37996cdbe738ea5137c646cdd7), [`8bd4589`](https://github.com/Effect-TS/effect-smol/commit/8bd458975a1b3a8ed042eccf317b93d28ded91e7), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`6e08428`](https://github.com/Effect-TS/effect-smol/commit/6e08428d980501b856f846ad3f3f0e4ea46e7786), [`388dcf9`](https://github.com/Effect-TS/effect-smol/commit/388dcf953f65d317547f34d40e6443c5f264205f), [`2b7ce2b`](https://github.com/Effect-TS/effect-smol/commit/2b7ce2b513e7ec2a77822f1116dc6ffb6ba93f4e), [`87bea7e`](https://github.com/Effect-TS/effect-smol/commit/87bea7e16259246f3bcdf565446394751abca953), [`ce38dc3`](https://github.com/Effect-TS/effect-smol/commit/ce38dc33bda805a684432cca071f4dc3c6b9a1ba), [`a807cd1`](https://github.com/Effect-TS/effect-smol/commit/a807cd170341deca8a1cfb52c4222585f2431bb9), [`fd8a356`](https://github.com/Effect-TS/effect-smol/commit/fd8a356f06a8c9ce4e7e0a13fc4021c178ed31de), [`c2a5edc`](https://github.com/Effect-TS/effect-smol/commit/c2a5edc3abd31ad5bc123362bc1213e03e4095c3), [`5946da3`](https://github.com/Effect-TS/effect-smol/commit/5946da3804a1be5e752b05b96bd058cdba50a1bf), [`4ae0c5f`](https://github.com/Effect-TS/effect-smol/commit/4ae0c5ffcbe6c56ddfcb05c639112a079483539e), [`5b2a0bc`](https://github.com/Effect-TS/effect-smol/commit/5b2a0bceea3a28a33a58555210c90a415dc74a76), [`72ac585`](https://github.com/Effect-TS/effect-smol/commit/72ac585884befde6af9208da738699a93f1bae79), [`5e8c1b8`](https://github.com/Effect-TS/effect-smol/commit/5e8c1b82bfafa121311f987a49ab75395e3647a7), [`0f9c078`](https://github.com/Effect-TS/effect-smol/commit/0f9c07841b04183f485ee6e6458de73b290b09f5)]:
|
||||
- effect@4.0.0-beta.98
|
||||
|
||||
## 4.0.0-beta.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.97
|
||||
|
||||
## 4.0.0-beta.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1503f45`](https://github.com/Effect-TS/effect-smol/commit/1503f45cb5bb2a74f4705252ec505a1f0ade7e62), [`57fe793`](https://github.com/Effect-TS/effect-smol/commit/57fe79316ffbc380b30626a168981fb26ae97459), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`97f29df`](https://github.com/Effect-TS/effect-smol/commit/97f29df457f7ffd07cfb4b379315c12c086af805)]:
|
||||
- effect@4.0.0-beta.96
|
||||
|
||||
## 4.0.0-beta.95
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a482442`](https://github.com/Effect-TS/effect-smol/commit/a482442abdeb490e9652b854ec3495e4aa7273e7), [`fbefa85`](https://github.com/Effect-TS/effect-smol/commit/fbefa850fab2f0a302c20614496aeaaa2a8b5590), [`0b4a32f`](https://github.com/Effect-TS/effect-smol/commit/0b4a32f4260f0d8500942a133001b0d349328102), [`18a49e1`](https://github.com/Effect-TS/effect-smol/commit/18a49e1786679456258002ff9397faf02f678c2d), [`266cb90`](https://github.com/Effect-TS/effect-smol/commit/266cb90bb2c17aabc40563c32db334f09ba3d74b), [`912f095`](https://github.com/Effect-TS/effect-smol/commit/912f095a34572bbd3cedf6edb27878443e3e4a95), [`a6718f9`](https://github.com/Effect-TS/effect-smol/commit/a6718f9e00a15ca903b0732da46116cbf3d6aca7), [`bef5154`](https://github.com/Effect-TS/effect-smol/commit/bef51540a243aa2f872a00c01d0cd58b7a769baa), [`18e0564`](https://github.com/Effect-TS/effect-smol/commit/18e0564bd0f8ebbdfcaf1e2c21529948e9e4a81d), [`fb50f14`](https://github.com/Effect-TS/effect-smol/commit/fb50f14fc3657c1973785aa5b72ecf0b0d28e0b2)]:
|
||||
- effect@4.0.0-beta.95
|
||||
|
||||
## 4.0.0-beta.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`95a0e9b`](https://github.com/Effect-TS/effect-smol/commit/95a0e9bb62797af0e81c9998773405f248f218c5), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63), [`f11ce73`](https://github.com/Effect-TS/effect-smol/commit/f11ce73af60823754dc24194f4ffc561b9ea1c2d), [`ff30b6e`](https://github.com/Effect-TS/effect-smol/commit/ff30b6e7c2c63ffc56a4c5818d6d86b01b5ad528), [`1caab3c`](https://github.com/Effect-TS/effect-smol/commit/1caab3cc30f626efbf15e59d74f539a487e5c85c), [`aa80c47`](https://github.com/Effect-TS/effect-smol/commit/aa80c4775a04db87553e5568764cab7e32a72814), [`c2ae4fc`](https://github.com/Effect-TS/effect-smol/commit/c2ae4fce2f03a4cd1861c2b1179da7df656e662d), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63)]:
|
||||
- effect@4.0.0-beta.94
|
||||
|
||||
## 4.0.0-beta.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`00652fe`](https://github.com/Effect-TS/effect-smol/commit/00652fe95c18f87208e91343eb8bf218faa2f677), [`6c58167`](https://github.com/Effect-TS/effect-smol/commit/6c5816746eaf91d2a3c7c899c5720809fa230ae3), [`2bc5415`](https://github.com/Effect-TS/effect-smol/commit/2bc541501a7ef89e542d7cb98e96beb53cd205cc), [`e11cccc`](https://github.com/Effect-TS/effect-smol/commit/e11cccc7d5fe631abccc7d6e3bd296938de0fa2e), [`ba7e77e`](https://github.com/Effect-TS/effect-smol/commit/ba7e77e046b8641a3a4e9750bb88ca4a1d063d3f), [`5713ee7`](https://github.com/Effect-TS/effect-smol/commit/5713ee7edbc3054efde407b2286bbfd45bbc6e1c)]:
|
||||
- effect@4.0.0-beta.93
|
||||
|
||||
## 4.0.0-beta.92
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`affdc13`](https://github.com/Effect-TS/effect-smol/commit/affdc139045cc325dce321a84a580fdc1b2da7b9)]:
|
||||
- effect@4.0.0-beta.92
|
||||
|
||||
## 4.0.0-beta.91
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b135b25`](https://github.com/Effect-TS/effect-smol/commit/b135b2517fca9e7839734ace3699a7dfa75b9075), [`aaa21a3`](https://github.com/Effect-TS/effect-smol/commit/aaa21a369a171c600db294f2a4f640583043e150), [`3475ee6`](https://github.com/Effect-TS/effect-smol/commit/3475ee6c2bda6b05c6d7a12ce30c8bb840b5b1a6)]:
|
||||
- effect@4.0.0-beta.91
|
||||
|
||||
## 4.0.0-beta.90
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d237fdf`](https://github.com/Effect-TS/effect-smol/commit/d237fdf726481f76eb52a6196e111b24122bc3d5)]:
|
||||
- effect@4.0.0-beta.90
|
||||
|
||||
## 4.0.0-beta.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b7d46ab`](https://github.com/Effect-TS/effect-smol/commit/b7d46ab7e1a29d8711817bab583c9febf48a0dad), [`7777e15`](https://github.com/Effect-TS/effect-smol/commit/7777e1540fd3680dd8346723cffec812b9384669), [`5376197`](https://github.com/Effect-TS/effect-smol/commit/5376197ca8e50358a41b1fd3cec27bd1ec680ec6)]:
|
||||
- effect@4.0.0-beta.89
|
||||
|
||||
## 4.0.0-beta.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`911f1b8`](https://github.com/Effect-TS/effect-smol/commit/911f1b84790ce42b3a70c95b33e6f6fd9e74de8b), [`8beeeea`](https://github.com/Effect-TS/effect-smol/commit/8beeeea52879d8613a39468848f01c3092bd54d4), [`c306fcf`](https://github.com/Effect-TS/effect-smol/commit/c306fcfeb1ef38455156932a1faf49292b1318da)]:
|
||||
- effect@4.0.0-beta.88
|
||||
|
||||
## 4.0.0-beta.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a0c1a4`](https://github.com/Effect-TS/effect-smol/commit/5a0c1a4faee5707b5cc35e646ff1ffdad70f1956), [`1eea2ea`](https://github.com/Effect-TS/effect-smol/commit/1eea2ea3795ba47316b82b1ac8d4612c0ba389ed)]:
|
||||
- effect@4.0.0-beta.87
|
||||
|
||||
## 4.0.0-beta.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0b5795a`](https://github.com/Effect-TS/effect-smol/commit/0b5795a0ab4395e8f15955d8d96f2303084bfc64), [`3e3a859`](https://github.com/Effect-TS/effect-smol/commit/3e3a859ec6351a9e0d31674aabbd48fcefabb12e), [`7dbec24`](https://github.com/Effect-TS/effect-smol/commit/7dbec240dbf3bca599a20c486632abce694ef5ab), [`d8c00a1`](https://github.com/Effect-TS/effect-smol/commit/d8c00a171ac7141e8adc08c332d1162d9a9d56fc), [`85b6317`](https://github.com/Effect-TS/effect-smol/commit/85b631701e935866f2762bd595237aa718370cd9), [`6d0fda0`](https://github.com/Effect-TS/effect-smol/commit/6d0fda0d0cbdfffc523c89c57dfdb1608f84fb12), [`108a933`](https://github.com/Effect-TS/effect-smol/commit/108a9335ff8571928197e5847a09c28ac83d6f46), [`7e1f455`](https://github.com/Effect-TS/effect-smol/commit/7e1f455fab5005d769b939c91e519d450f802cf9), [`46b3e79`](https://github.com/Effect-TS/effect-smol/commit/46b3e79944cfdae7901eb148135c85b7eb39834e)]:
|
||||
- effect@4.0.0-beta.86
|
||||
|
||||
## 4.0.0-beta.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`328d97c`](https://github.com/Effect-TS/effect-smol/commit/328d97cc53c0dcb89077a5623e35b095eaa59a8c), [`8441836`](https://github.com/Effect-TS/effect-smol/commit/8441836e6dde70e8ae2126be9cefe9b45798b134), [`074e436`](https://github.com/Effect-TS/effect-smol/commit/074e4361091289104cb0ab6959dc3b0ea7794a6a), [`c1dfd60`](https://github.com/Effect-TS/effect-smol/commit/c1dfd60663eb13a58916f3712d877499943b628a), [`2ba316b`](https://github.com/Effect-TS/effect-smol/commit/2ba316bd15fcbf1c50626500d44a2c9b3bec19f5), [`7ce7344`](https://github.com/Effect-TS/effect-smol/commit/7ce7344c41056c79e2ee19ee6a9346c0f1d227c1)]:
|
||||
- effect@4.0.0-beta.85
|
||||
|
||||
## 4.0.0-beta.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`87f52ba`](https://github.com/Effect-TS/effect-smol/commit/87f52ba16c4370ffa3f84bf8e53038e1419c284e), [`b8ee07f`](https://github.com/Effect-TS/effect-smol/commit/b8ee07ffda8903b5ec2e45a786ddcba59f128fda), [`867c0d7`](https://github.com/Effect-TS/effect-smol/commit/867c0d70a09079b040260d45a1e92ff04dbfbf2f), [`b93bc6c`](https://github.com/Effect-TS/effect-smol/commit/b93bc6c9cb27b909a41d094c97c4f9d25bbc6d6b), [`57d387f`](https://github.com/Effect-TS/effect-smol/commit/57d387f92c30ab63e15e3e641f0a903b65886610), [`bacca41`](https://github.com/Effect-TS/effect-smol/commit/bacca4141c2400effae1eabfdb36c89a459cf246), [`0f8ac79`](https://github.com/Effect-TS/effect-smol/commit/0f8ac7959d29ed68c68ce25aabd6bf0cb7e63ecc), [`25b4482`](https://github.com/Effect-TS/effect-smol/commit/25b448270c01317703f25107e1480d4cd0246d9a), [`9cf3a25`](https://github.com/Effect-TS/effect-smol/commit/9cf3a25c66b0c44a52be9829870c44517ea52db2), [`8def767`](https://github.com/Effect-TS/effect-smol/commit/8def7674b1787f91035298cda4d122937e87ef72)]:
|
||||
- effect@4.0.0-beta.84
|
||||
|
||||
## 4.0.0-beta.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1f2e8ce`](https://github.com/Effect-TS/effect-smol/commit/1f2e8ceef09e0a791c850ed2ade01f97089596f9)]:
|
||||
- effect@4.0.0-beta.83
|
||||
|
||||
## 4.0.0-beta.82
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`193690b`](https://github.com/Effect-TS/effect-smol/commit/193690b642ea802bbed40d663bd677251bbe9dc3)]:
|
||||
- effect@4.0.0-beta.82
|
||||
|
||||
## 4.0.0-beta.81
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`93cb4f8`](https://github.com/Effect-TS/effect-smol/commit/93cb4f8fbfb9e07cb9dc86ce6b155fd1f8167914), [`60341d9`](https://github.com/Effect-TS/effect-smol/commit/60341d9ca744d0473ce3fab621ca9bd225af3a39), [`1105ab5`](https://github.com/Effect-TS/effect-smol/commit/1105ab56cb724212f7ea7b431396ce82e8fd0484), [`4500fbf`](https://github.com/Effect-TS/effect-smol/commit/4500fbfe00763d8a72af6e5d6c5988e8bd4ade36)]:
|
||||
- effect@4.0.0-beta.81
|
||||
|
||||
## 4.0.0-beta.80
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2380](https://github.com/Effect-TS/effect-smol/pull/2380) [`b5f67a0`](https://github.com/Effect-TS/effect-smol/commit/b5f67a0ce9c110b98731ac485e5894df9da07e3a) Thanks @walln! - Surface reasoning tokens from OpenAI-compatible chat completion responses.
|
||||
|
||||
- Updated dependencies [[`d944330`](https://github.com/Effect-TS/effect-smol/commit/d94433090ee03f426d43e13b883abae4494e55e6), [`f48659f`](https://github.com/Effect-TS/effect-smol/commit/f48659fdcc84930ebc1e5b45b540c0f973389182), [`7652aaa`](https://github.com/Effect-TS/effect-smol/commit/7652aaa3bdbc39f241fe58b54b9a43b713e22e12), [`98630b7`](https://github.com/Effect-TS/effect-smol/commit/98630b7c8f679c352ba6796636c85688fa009d8d), [`90ae23c`](https://github.com/Effect-TS/effect-smol/commit/90ae23cf07284da5e1bcd9dffa882e85df7e617b)]:
|
||||
- effect@4.0.0-beta.80
|
||||
|
||||
## 4.0.0-beta.79
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2338](https://github.com/Effect-TS/effect-smol/pull/2338) [`b12991f`](https://github.com/Effect-TS/effect-smol/commit/b12991f2346eda47fec72df5a89034394ad6c8fb) Thanks @boozedog! - Fix dropped streamed tool-call arguments when a provider sends `function.name: null` on continuation fragments.
|
||||
|
||||
OpenAI-compatible providers such as Fireworks send the tool name only on the first streamed `tool_calls` fragment and `function.name: null` on the continuation fragments that carry the argument deltas. `ChatCompletionToolFunctionDelta.name` was `Schema.optionalKey(Schema.String)` (non-nullable), so chunk validation rejected every continuation and silently discarded its argument delta, leaving the assembled tool call with empty or partial params. `name` is now nullable (`Schema.NullOr(Schema.String)`).
|
||||
|
||||
- Updated dependencies [[`b9704dc`](https://github.com/Effect-TS/effect-smol/commit/b9704dc9de9f1649ad502371014fe869b69a49a3), [`a207113`](https://github.com/Effect-TS/effect-smol/commit/a207113f66837bb54416926718a9a7d66774d079), [`5e9b9e2`](https://github.com/Effect-TS/effect-smol/commit/5e9b9e217b164ebfd4a002dd4380b3b1563200c3), [`7c128ae`](https://github.com/Effect-TS/effect-smol/commit/7c128aef458a1e2d224712e51c483c9badad1d44), [`0ada457`](https://github.com/Effect-TS/effect-smol/commit/0ada457c0513d8d908254ab77ebb7d29d2b523d6), [`d7cc5a2`](https://github.com/Effect-TS/effect-smol/commit/d7cc5a2bede3de10943aa0c6bdb4f26836a91efd), [`aad63be`](https://github.com/Effect-TS/effect-smol/commit/aad63becf65e0a6b076e94f8973be7bbe7fbd46f), [`09809f6`](https://github.com/Effect-TS/effect-smol/commit/09809f60f19ec98232f98b33e33e02ecb7e4fbd6), [`2fddda5`](https://github.com/Effect-TS/effect-smol/commit/2fddda5311929f46b61e503f0ade4fc749e8c77d), [`5f21768`](https://github.com/Effect-TS/effect-smol/commit/5f2176833399757c4500d8875b7f2fba0393de75), [`f27003e`](https://github.com/Effect-TS/effect-smol/commit/f27003e00524ff83f20dd9909f62b2f8795efe03)]:
|
||||
- effect@4.0.0-beta.79
|
||||
|
||||
## 4.0.0-beta.78
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7836b8e`](https://github.com/Effect-TS/effect-smol/commit/7836b8eb8bb0f3e04cdf554ee070caccf74f00c1), [`35d49a3`](https://github.com/Effect-TS/effect-smol/commit/35d49a3a09bdba6b513de87ddcead9e61a1042ba), [`4093258`](https://github.com/Effect-TS/effect-smol/commit/40932580e65bafab5f23c5f14b520cb411d0b2cd)]:
|
||||
- effect@4.0.0-beta.78
|
||||
|
||||
## 4.0.0-beta.77
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6e9a5ca`](https://github.com/Effect-TS/effect-smol/commit/6e9a5ca62a61156fd67b2518ad3ab14ac0d25f23), [`302f398`](https://github.com/Effect-TS/effect-smol/commit/302f3984ce206e35d86ddd99d3b72be144850a51)]:
|
||||
- effect@4.0.0-beta.77
|
||||
|
||||
## 4.0.0-beta.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`016108a`](https://github.com/Effect-TS/effect-smol/commit/016108a472af7048ddbbfd05f233e67529fafe12), [`95c03d2`](https://github.com/Effect-TS/effect-smol/commit/95c03d2c55930668c215b5a41c23cf7742fead84), [`07299a3`](https://github.com/Effect-TS/effect-smol/commit/07299a33c09fd52faa9810d30835a2622c752386)]:
|
||||
- effect@4.0.0-beta.76
|
||||
|
||||
## 4.0.0-beta.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`81b187c`](https://github.com/Effect-TS/effect-smol/commit/81b187c17a0d8817b58232826939154010ae49d7), [`ad4b535`](https://github.com/Effect-TS/effect-smol/commit/ad4b535e17f94ce35261829d5a3675f0a7808b4e), [`a29c2e7`](https://github.com/Effect-TS/effect-smol/commit/a29c2e7e3570920156702671d6f3367cd0195f6c), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`ffea4ec`](https://github.com/Effect-TS/effect-smol/commit/ffea4ecf2925f6a4c9fd13079d47584cbf2bed00), [`4255c9b`](https://github.com/Effect-TS/effect-smol/commit/4255c9ba78bb98c7838fbe9dccdd8465e9da5427)]:
|
||||
- effect@4.0.0-beta.75
|
||||
|
||||
## 4.0.0-beta.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b1fc6a4`](https://github.com/Effect-TS/effect-smol/commit/b1fc6a4b4d0ca7fa9fd162799ae17c86f2f7ee8e)]:
|
||||
- effect@4.0.0-beta.74
|
||||
|
||||
## 4.0.0-beta.73
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`361ca30`](https://github.com/Effect-TS/effect-smol/commit/361ca30eb6e134feece547d6e00f82be4cb23f75), [`b9598c6`](https://github.com/Effect-TS/effect-smol/commit/b9598c6a209e75bfdb87ee3b024ecd1e3923ff6e)]:
|
||||
- effect@4.0.0-beta.73
|
||||
|
||||
## 4.0.0-beta.72
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`73e67d1`](https://github.com/Effect-TS/effect-smol/commit/73e67d119a84d697773eaecb4865c6a71eb1a9cb), [`01d71ec`](https://github.com/Effect-TS/effect-smol/commit/01d71ec5a75f3c2747a8d3b1ad9701d1e27b7ce5), [`fcd707e`](https://github.com/Effect-TS/effect-smol/commit/fcd707e091a16e1b35343c901cc4052274e32239)]:
|
||||
- effect@4.0.0-beta.72
|
||||
|
||||
## 4.0.0-beta.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d8ac76b`](https://github.com/Effect-TS/effect-smol/commit/d8ac76b5bad458c42cebe8a0c1b3843f955ac293), [`2c3c00a`](https://github.com/Effect-TS/effect-smol/commit/2c3c00af6faba7b7d422af26a7a2bbc35636d230), [`3751e7c`](https://github.com/Effect-TS/effect-smol/commit/3751e7cf353e7a54cd692c37401207d9afba1e63), [`fc5f25b`](https://github.com/Effect-TS/effect-smol/commit/fc5f25b03ada5fc2431987768a74d3d3e75ca485), [`7ccced4`](https://github.com/Effect-TS/effect-smol/commit/7ccced42867c14c013b01160b3d292f14c05bd04), [`a2e1fe5`](https://github.com/Effect-TS/effect-smol/commit/a2e1fe5835c98c8ee4393a091b1d11b75126e349), [`4a4a36b`](https://github.com/Effect-TS/effect-smol/commit/4a4a36b10e6e616cad07584a43908f6a7e07e618), [`d350292`](https://github.com/Effect-TS/effect-smol/commit/d3502922b4740fa9d745797cbc3775cb67839b6d), [`730afb6`](https://github.com/Effect-TS/effect-smol/commit/730afb66696adf9bd5a328cbca29df9c05968771), [`df1b008`](https://github.com/Effect-TS/effect-smol/commit/df1b008f370f414c2a67a7b8139ef747af8e5fba), [`6d469d5`](https://github.com/Effect-TS/effect-smol/commit/6d469d567a7c41d7e5343bdee21d45b07b0e8190)]:
|
||||
- effect@4.0.0-beta.71
|
||||
|
||||
## 4.0.0-beta.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af7782d`](https://github.com/Effect-TS/effect-smol/commit/af7782d3008d08b043f3a3f261516001514b2b4e), [`7212d70`](https://github.com/Effect-TS/effect-smol/commit/7212d701a3eee7b3553ff502e2c066126e52e839)]:
|
||||
- effect@4.0.0-beta.70
|
||||
|
||||
## 4.0.0-beta.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70ea04a`](https://github.com/Effect-TS/effect-smol/commit/70ea04aa96a2a7859d738d414e1f0e3ed081a27a), [`d0ea8b0`](https://github.com/Effect-TS/effect-smol/commit/d0ea8b03f7d73ae076c1db12666141e480d11178), [`a57674b`](https://github.com/Effect-TS/effect-smol/commit/a57674b64845e9e75a456cf907bfdcb858859118), [`59aa334`](https://github.com/Effect-TS/effect-smol/commit/59aa334fbd0a504dda3c36f6d2ef1be7449b4b8b), [`8f4208e`](https://github.com/Effect-TS/effect-smol/commit/8f4208ee83bc7bdaa6793b5429847b45aab72470)]:
|
||||
- effect@4.0.0-beta.69
|
||||
|
||||
## 4.0.0-beta.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af8267f`](https://github.com/Effect-TS/effect-smol/commit/af8267f2f3588c3fb611e9286f6f933f29ce1217), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`f136bb7`](https://github.com/Effect-TS/effect-smol/commit/f136bb763048cbc6b17edd26496dba3e2415b9fa), [`6f38f07`](https://github.com/Effect-TS/effect-smol/commit/6f38f07d5941a211b251383aaab0f4f55e8a6557), [`aec9c40`](https://github.com/Effect-TS/effect-smol/commit/aec9c401a53db227f18bf5e0c84db7130ad862d6)]:
|
||||
- effect@4.0.0-beta.68
|
||||
|
||||
## 4.0.0-beta.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a42ef66`](https://github.com/Effect-TS/effect-smol/commit/a42ef6632abbddfa820995ae310ccc84ae8d9b6f), [`35594f8`](https://github.com/Effect-TS/effect-smol/commit/35594f811cafe471acd490114b103a1f8392c8d8), [`8bddd62`](https://github.com/Effect-TS/effect-smol/commit/8bddd628cb623f9533d345082583ff51cead6836), [`4be4c8d`](https://github.com/Effect-TS/effect-smol/commit/4be4c8d60862aa963869ee2ed9ffa048ffac0527), [`0c9d3ab`](https://github.com/Effect-TS/effect-smol/commit/0c9d3ab43eb721a370ed8306260cbac218c27e87), [`b156acc`](https://github.com/Effect-TS/effect-smol/commit/b156accd2691b4a051f823affdece7c39923ce85), [`d16c034`](https://github.com/Effect-TS/effect-smol/commit/d16c03434ee3e6dcd3bfc82b65d99e881d89025b), [`b559d68`](https://github.com/Effect-TS/effect-smol/commit/b559d68845f848a10153395778f035682d399075), [`a3de5d9`](https://github.com/Effect-TS/effect-smol/commit/a3de5d9215e5cc4a62e2666efbd7c1bf595eb84f), [`7e6c12e`](https://github.com/Effect-TS/effect-smol/commit/7e6c12ec9b3a5945f6c26e272cc8f6390541ad3e), [`098167a`](https://github.com/Effect-TS/effect-smol/commit/098167a220fe07da6f14455818733ab1b269c9dd)]:
|
||||
- effect@4.0.0-beta.67
|
||||
|
||||
## 4.0.0-beta.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ca2498e`](https://github.com/Effect-TS/effect-smol/commit/ca2498e702ac2d83fb7187707b7eb069bdb261a2), [`cd7d1fb`](https://github.com/Effect-TS/effect-smol/commit/cd7d1fba7e2e2c5ac3ad64e1be433440a5bda436), [`19a7033`](https://github.com/Effect-TS/effect-smol/commit/19a703367ec817cffc41d152da9b594827408e2b), [`33d26b4`](https://github.com/Effect-TS/effect-smol/commit/33d26b4210b2e974f146a71e7eed962f8ce00900), [`856766b`](https://github.com/Effect-TS/effect-smol/commit/856766b2c506aaed6d2df1d63bf3a5b1b062e1d4), [`079c7df`](https://github.com/Effect-TS/effect-smol/commit/079c7df82559bb9ce10a86dffb85d25e6ce07dc3)]:
|
||||
- effect@4.0.0-beta.66
|
||||
|
||||
## 4.0.0-beta.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6f11454`](https://github.com/Effect-TS/effect-smol/commit/6f11454a9b6c3bd00f6b35fd7af14a2f2d63a0a2)]:
|
||||
- effect@4.0.0-beta.65
|
||||
|
||||
## 4.0.0-beta.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d4877a`](https://github.com/Effect-TS/effect-smol/commit/7d4877a1929cdb690280ea254326c04f2ec97ea5)]:
|
||||
- effect@4.0.0-beta.64
|
||||
|
||||
## 4.0.0-beta.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2133](https://github.com/Effect-TS/effect-smol/pull/2133) [`5be0aaa`](https://github.com/Effect-TS/effect-smol/commit/5be0aaad694c9eb943a710eb4f896bc4c3fcae99) Thanks @Zelys-DFKH! - Fix `OpenAiLanguageModel` leaking library-only config fields (`fileIdPrefixes`, `strictJsonSchema`) into request body, causing OpenAI 400 errors.
|
||||
|
||||
- Updated dependencies [[`7f927ff`](https://github.com/Effect-TS/effect-smol/commit/7f927ffb7a9801dcfc4096c29e369d13d65cd0ac), [`a696b3e`](https://github.com/Effect-TS/effect-smol/commit/a696b3e83a8504cdbe261a18c10a1cc0619ae102)]:
|
||||
- effect@4.0.0-beta.63
|
||||
|
||||
## 4.0.0-beta.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4ab4b90`](https://github.com/Effect-TS/effect-smol/commit/4ab4b9007dc27a52ffabc6fcb37c96eeec795bf7)]:
|
||||
- effect@4.0.0-beta.62
|
||||
|
||||
## 4.0.0-beta.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`50790af`](https://github.com/Effect-TS/effect-smol/commit/50790af9b190c38d10fb0723837d49b66432638f), [`71f7c3d`](https://github.com/Effect-TS/effect-smol/commit/71f7c3df997deda92c84146d569696dab3bd645c), [`aae8797`](https://github.com/Effect-TS/effect-smol/commit/aae8797b9cb383be0c182dd58d03d787c354238b)]:
|
||||
- effect@4.0.0-beta.61
|
||||
|
||||
## 4.0.0-beta.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f69d567`](https://github.com/Effect-TS/effect-smol/commit/f69d5675dcff9f4137295752baf066b7153fdc09), [`7909c95`](https://github.com/Effect-TS/effect-smol/commit/7909c954b8f6244a35a4b429f8dd0dff45dad620), [`bbb4dcc`](https://github.com/Effect-TS/effect-smol/commit/bbb4dcc6c406b83a416b4ad3541cc02037c420e4), [`7af2207`](https://github.com/Effect-TS/effect-smol/commit/7af2207901eabf3132c1b7010a69b3899c06fbbe), [`848b40a`](https://github.com/Effect-TS/effect-smol/commit/848b40a4bd4bf54a5098617d50c33c88eee8270a)]:
|
||||
- effect@4.0.0-beta.60
|
||||
|
||||
## 4.0.0-beta.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`56837ea`](https://github.com/Effect-TS/effect-smol/commit/56837ea2a338395b35550641374e9e589bd8b71d)]:
|
||||
- effect@4.0.0-beta.59
|
||||
|
||||
## 4.0.0-beta.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`11993d4`](https://github.com/Effect-TS/effect-smol/commit/11993d4934c66f5dc611b8bbf553f01d501ef8f7), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec)]:
|
||||
- effect@4.0.0-beta.58
|
||||
|
||||
## 4.0.0-beta.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a971f5c`](https://github.com/Effect-TS/effect-smol/commit/a971f5cbd92dfe4274420bf0966595eb35531060), [`8e110c5`](https://github.com/Effect-TS/effect-smol/commit/8e110c5f02a429ccc43a91df8678e402138c0851)]:
|
||||
- effect@4.0.0-beta.57
|
||||
|
||||
## 4.0.0-beta.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.56
|
||||
|
||||
## 4.0.0-beta.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42cc744`](https://github.com/Effect-TS/effect-smol/commit/42cc744570968deb365fb46d47b53d3277050c93), [`04855ce`](https://github.com/Effect-TS/effect-smol/commit/04855ceeca4d40c55a5750dd9893b691f8ea741a)]:
|
||||
- effect@4.0.0-beta.55
|
||||
|
||||
## 4.0.0-beta.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e4b74f9`](https://github.com/Effect-TS/effect-smol/commit/e4b74f9c01a0e9b6cd58416de4af3a26d51da7c8), [`4c72808`](https://github.com/Effect-TS/effect-smol/commit/4c728081851c66dacf889a816535671bc841ae96)]:
|
||||
- effect@4.0.0-beta.54
|
||||
|
||||
## 4.0.0-beta.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0768509`](https://github.com/Effect-TS/effect-smol/commit/07685094e931af07d104165195826a535b55fa7e), [`476aede`](https://github.com/Effect-TS/effect-smol/commit/476aede69c6efa06b5781ca5eb3e3b128ca29141), [`4f79c54`](https://github.com/Effect-TS/effect-smol/commit/4f79c542e7b508c235ff485d862cc8b29a8260c5), [`4be6a7c`](https://github.com/Effect-TS/effect-smol/commit/4be6a7cf35dab2a01d652f56dd35f0358c5a7e88), [`88927eb`](https://github.com/Effect-TS/effect-smol/commit/88927ebb896162cdba103b36553280b58e0facac)]:
|
||||
- effect@4.0.0-beta.53
|
||||
|
||||
## 4.0.0-beta.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`cf3a311`](https://github.com/Effect-TS/effect-smol/commit/cf3a311d863a8abb818840c3b80f847e621c43c1), [`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`131fdd5`](https://github.com/Effect-TS/effect-smol/commit/131fdd5b1f26531e265fe1a08f002002f47c276e)]:
|
||||
- effect@4.0.0-beta.52
|
||||
|
||||
## 4.0.0-beta.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`778d2af`](https://github.com/Effect-TS/effect-smol/commit/778d2afe9b5154bc1f9abae46d93ea7e54c87344), [`4e24dcf`](https://github.com/Effect-TS/effect-smol/commit/4e24dcf75037f65eebc1eb68623bc7cbf9d5512a), [`4b1c015`](https://github.com/Effect-TS/effect-smol/commit/4b1c0150e9bdb5559ed32d250deb66e17b4240c7), [`454f8ad`](https://github.com/Effect-TS/effect-smol/commit/454f8adad822929c3ef60f8280d0987226b049fd), [`6754a0c`](https://github.com/Effect-TS/effect-smol/commit/6754a0cd18626b06805a079cc5265525a5eb7d27), [`90f7fd5`](https://github.com/Effect-TS/effect-smol/commit/90f7fd5243871b30980964135db4512b8119fa82), [`d7e1519`](https://github.com/Effect-TS/effect-smol/commit/d7e151974934201fd93fa4c8a1192ee9a5d965a0), [`72a8122`](https://github.com/Effect-TS/effect-smol/commit/72a81228e09782bae512f7d041bbfbc78bc668d0)]:
|
||||
- effect@4.0.0-beta.51
|
||||
|
||||
## 4.0.0-beta.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`07be594`](https://github.com/Effect-TS/effect-smol/commit/07be594825de60f8e1b2102d21dbb9b8fc63b414), [`ae02433`](https://github.com/Effect-TS/effect-smol/commit/ae02433103ce28f53a0c9bfb4a44e75773289b7b)]:
|
||||
- effect@4.0.0-beta.50
|
||||
|
||||
## 4.0.0-beta.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d87873`](https://github.com/Effect-TS/effect-smol/commit/7d8787340ff549370f6f2a88b612e9ebbfd6ba45), [`c2f6f90`](https://github.com/Effect-TS/effect-smol/commit/c2f6f901b200a6e515b4f02c93ce8005b7bbf1c5), [`216f13c`](https://github.com/Effect-TS/effect-smol/commit/216f13c1fce454a21b489bb915714a17e791a1ac)]:
|
||||
- effect@4.0.0-beta.49
|
||||
|
||||
## 4.0.0-beta.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4da56ec`](https://github.com/Effect-TS/effect-smol/commit/4da56ecff129b2da40137ffede23a73cc4e532d8), [`a5e6f77`](https://github.com/Effect-TS/effect-smol/commit/a5e6f774bab195cf50ecdc818240765f69a3bf4a), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070)]:
|
||||
- effect@4.0.0-beta.48
|
||||
|
||||
## 4.0.0-beta.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c584726`](https://github.com/Effect-TS/effect-smol/commit/c58472674e750e6938df955044eab88feda95e45), [`86a91a4`](https://github.com/Effect-TS/effect-smol/commit/86a91a4f0c59286dfa9393232d8020dea70ed4db), [`131caf9`](https://github.com/Effect-TS/effect-smol/commit/131caf9525151a0cb29803a8f1dffa0f4f479d12), [`c3615c8`](https://github.com/Effect-TS/effect-smol/commit/c3615c88379b9daf252df0db72c6ac5a20326406)]:
|
||||
- effect@4.0.0-beta.47
|
||||
|
||||
## 4.0.0-beta.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a30b9e`](https://github.com/Effect-TS/effect-smol/commit/3a30b9e2ec2bd8b8193e1aa139f6878a07e3f5ee)]:
|
||||
- effect@4.0.0-beta.46
|
||||
|
||||
## 4.0.0-beta.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c3af6d`](https://github.com/Effect-TS/effect-smol/commit/5c3af6d554f60be34f8fc21d598d9a298ae11beb)]:
|
||||
- effect@4.0.0-beta.45
|
||||
|
||||
## 4.0.0-beta.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1961](https://github.com/Effect-TS/effect-smol/pull/1961) [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970) Thanks @IMax153! - Rename the `ServiceMap` module to `Context` across exports, docs, and tests.
|
||||
|
||||
- Updated dependencies [[`e3f0621`](https://github.com/Effect-TS/effect-smol/commit/e3f0621454c3f5d11070d30619da27c9232cadc1), [`5b476ab`](https://github.com/Effect-TS/effect-smol/commit/5b476abc0bd7e9bb59135ea1bcad2e4936227ced), [`6b40e5a`](https://github.com/Effect-TS/effect-smol/commit/6b40e5a4a6bd2087c15a3d7374d25057fdedfa16), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`3b09fb3`](https://github.com/Effect-TS/effect-smol/commit/3b09fb31c40c2802b01f21c23bcdd1fe7fb0aa82), [`2370410`](https://github.com/Effect-TS/effect-smol/commit/237041062e5af4594d32db91597e34e70a632877), [`dabc272`](https://github.com/Effect-TS/effect-smol/commit/dabc272444a700eb629c07ba3e77671a841ca86e), [`08b63c3`](https://github.com/Effect-TS/effect-smol/commit/08b63c3df11bd35c9fd6090dbd166287fdc40664), [`dfff04c`](https://github.com/Effect-TS/effect-smol/commit/dfff04c4c2b1d352dfad83992a6dce1280c85cf9), [`9baed9e`](https://github.com/Effect-TS/effect-smol/commit/9baed9e17e84702e6e480fcef6f86404f9e24be9), [`7846792`](https://github.com/Effect-TS/effect-smol/commit/7846792adc7e1631d62d26d657bd7ba6139f369b), [`1556a24`](https://github.com/Effect-TS/effect-smol/commit/1556a247623636b7ebe438fb56d77f1a7bf957bb), [`7c11bc2`](https://github.com/Effect-TS/effect-smol/commit/7c11bc292ab8e46252fe8f7576fb685917bfb8b5), [`b5ea591`](https://github.com/Effect-TS/effect-smol/commit/b5ea5913ec1d45d0dd12a327b9dd966bda2f6d02), [`0853afa`](https://github.com/Effect-TS/effect-smol/commit/0853afaeb1633b2d7f8b66893bd01c3aa1ef2c22), [`ac845f3`](https://github.com/Effect-TS/effect-smol/commit/ac845f3ab40e0b8719576e7f9bc16ea2e0e02cd4), [`b80c462`](https://github.com/Effect-TS/effect-smol/commit/b80c46247480f47bb64fc480fab48a3f37bc8888), [`b3f535d`](https://github.com/Effect-TS/effect-smol/commit/b3f535d9a7ac13b5fb984c29f93561c57a081ff0), [`6fe2e93`](https://github.com/Effect-TS/effect-smol/commit/6fe2e93cc2f1b173ef89651d74b6a5d2626b3226), [`cda8004`](https://github.com/Effect-TS/effect-smol/commit/cda800451c1ffbdddfc08415aed7b2d91e0412ee), [`8335477`](https://github.com/Effect-TS/effect-smol/commit/8335477a8a936a24b5f3ee6203c1b268bd1bfc3c), [`8c836f9`](https://github.com/Effect-TS/effect-smol/commit/8c836f99ab1e896b9580a71d67773625baff2eaf), [`718ff6f`](https://github.com/Effect-TS/effect-smol/commit/718ff6fe3e3d3820cefd67d2bff1b2224fe08060), [`7eed84f`](https://github.com/Effect-TS/effect-smol/commit/7eed84fc33c5781a6fb11bf4fd189d424902ebd4), [`5df46fe`](https://github.com/Effect-TS/effect-smol/commit/5df46fe2f654d59ab5fc1578f4fc27fa40368ef9), [`82dd0f2`](https://github.com/Effect-TS/effect-smol/commit/82dd0f26c6442b07143762ef7bc33742d3978dd6), [`03ae41e`](https://github.com/Effect-TS/effect-smol/commit/03ae41e7304cffac9f18feea22b73468feafc43a), [`4677a0a`](https://github.com/Effect-TS/effect-smol/commit/4677a0a58f95eea38a211efcd3f345f237a9e44a), [`87e1fc8`](https://github.com/Effect-TS/effect-smol/commit/87e1fc8b67e4901d75f567b2fecc3841ab762cc4), [`c1af1b7`](https://github.com/Effect-TS/effect-smol/commit/c1af1b756f63291e9c0298cf95c98a6920a0c2a0), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`c8a877b`](https://github.com/Effect-TS/effect-smol/commit/c8a877b53e8f29616335719e5dd1c3992dddf780), [`7da961a`](https://github.com/Effect-TS/effect-smol/commit/7da961ae4916229d2246699a5d3b20e5b2dd2020)]:
|
||||
- effect@4.0.0-beta.44
|
||||
|
||||
## 4.0.0-beta.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`2ae33d0`](https://github.com/Effect-TS/effect-smol/commit/2ae33d050914915f7cb9c25ab0a020901e08d596), [`979811a`](https://github.com/Effect-TS/effect-smol/commit/979811a4c3f7ed21ed18ef560c49fb7f5569e80e), [`eb7dbef`](https://github.com/Effect-TS/effect-smol/commit/eb7dbeffa883386ad912815e62c0820cac1fdf8e), [`cf50eb4`](https://github.com/Effect-TS/effect-smol/commit/cf50eb49cb04706dae5185f624708117c413dee8), [`1d046fe`](https://github.com/Effect-TS/effect-smol/commit/1d046fe484560e23f3e22cb23eec6433f8f1fa02)]:
|
||||
- effect@4.0.0-beta.43
|
||||
|
||||
## 4.0.0-beta.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1859](https://github.com/Effect-TS/effect-smol/pull/1859) [`a4809db`](https://github.com/Effect-TS/effect-smol/commit/a4809db80f65601d37ccafc13d773e55909c4e98) Thanks @lloydrichards! - add dynamic tooling for openai and openai-compact language models
|
||||
|
||||
- Updated dependencies [[`924e216`](https://github.com/Effect-TS/effect-smol/commit/924e216caa7e0bbf22e994a0cd2ce8b1f0f0b3ee), [`80e7f0c`](https://github.com/Effect-TS/effect-smol/commit/80e7f0cd9116e811e97b0ce30a77a8d1ecd072aa), [`f8328bf`](https://github.com/Effect-TS/effect-smol/commit/f8328bf0314da3dc7f31d314f94a5840e8d5217f), [`66d1c06`](https://github.com/Effect-TS/effect-smol/commit/66d1c06039079129707a230f7ad8c676439d7133), [`bee800b`](https://github.com/Effect-TS/effect-smol/commit/bee800bf285192a01bec72a7b7b51bc1159434e6), [`8930441`](https://github.com/Effect-TS/effect-smol/commit/8930441dee6f94c59c583d18d3ebd677cf1f2623)]:
|
||||
- effect@4.0.0-beta.42
|
||||
|
||||
## 4.0.0-beta.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`36f5c21`](https://github.com/Effect-TS/effect-smol/commit/36f5c2174d31ab42c4598bf81f178f40d0802283), [`d8ce758`](https://github.com/Effect-TS/effect-smol/commit/d8ce758669d6297ae932ac3251d83e7b49b22f30), [`11aab4c`](https://github.com/Effect-TS/effect-smol/commit/11aab4c6d37d5691adafc2d33da1a631b28ce814), [`3bc1efb`](https://github.com/Effect-TS/effect-smol/commit/3bc1efb53dd75b4a40de46f1f80c7f8a7d50af86), [`70e724e`](https://github.com/Effect-TS/effect-smol/commit/70e724e604604d4be1061cd8da0d360494998c84), [`738dee7`](https://github.com/Effect-TS/effect-smol/commit/738dee7edfd70af82dc4d2376db3a8ebe603eb48), [`2111963`](https://github.com/Effect-TS/effect-smol/commit/2111963f19b4c28c800664a8fac9590c1321885f), [`198a553`](https://github.com/Effect-TS/effect-smol/commit/198a553d9ce45f6a00bfc4d65ed0640669602d95)]:
|
||||
- effect@4.0.0-beta.41
|
||||
|
||||
## 4.0.0-beta.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f62860f`](https://github.com/Effect-TS/effect-smol/commit/f62860f0e5e45978fabf7256ae620a13152a772a), [`973f281`](https://github.com/Effect-TS/effect-smol/commit/973f2812529aadc1cc54598b2039799fa72b80f8)]:
|
||||
- effect@4.0.0-beta.40
|
||||
|
||||
## 4.0.0-beta.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f91fd3d`](https://github.com/Effect-TS/effect-smol/commit/f91fd3db39fe5628439fd175fba201a65a1aa9d0), [`edaae9d`](https://github.com/Effect-TS/effect-smol/commit/edaae9d65f464f941d7eddd723cd33d324f4b071), [`b47db0b`](https://github.com/Effect-TS/effect-smol/commit/b47db0bd5802064b6a24b3ea27c6ff2e0520d513), [`82d3c8e`](https://github.com/Effect-TS/effect-smol/commit/82d3c8e4f3f49b00df611b25aa6f8f74ec21b59b), [`7c22b31`](https://github.com/Effect-TS/effect-smol/commit/7c22b315d198dcbf44ae8cdb8b37879e1c9e3996)]:
|
||||
- effect@4.0.0-beta.39
|
||||
|
||||
## 4.0.0-beta.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f4dbe5b`](https://github.com/Effect-TS/effect-smol/commit/f4dbe5b26b9c2d33fae024bf44afbdf8541792cd), [`a71a607`](https://github.com/Effect-TS/effect-smol/commit/a71a607c89fb6669a12a562c2c23be81dfbe1adb), [`66a0494`](https://github.com/Effect-TS/effect-smol/commit/66a0494ed75cd12f2721dcbb1d8a072e3d9e14b6), [`5ef7218`](https://github.com/Effect-TS/effect-smol/commit/5ef7218fc559d57301fe929b8a0cab4033f4f1fd), [`472d260`](https://github.com/Effect-TS/effect-smol/commit/472d260655bc311fba5c2c6e23bb77d8f7e36ba0)]:
|
||||
- effect@4.0.0-beta.38
|
||||
|
||||
## 4.0.0-beta.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f7a0b71`](https://github.com/Effect-TS/effect-smol/commit/f7a0b711da8fdd645597dee29cacc5619c6afcf2), [`1e223c3`](https://github.com/Effect-TS/effect-smol/commit/1e223c30ccf835dfbb21284535d78549efaeca80), [`53740f4`](https://github.com/Effect-TS/effect-smol/commit/53740f47aa76d114b7d535649fb50efc54a09608), [`8c7cf89`](https://github.com/Effect-TS/effect-smol/commit/8c7cf89f719e580cbce1bf6c24e6996f1992a0a6), [`b6b81a9`](https://github.com/Effect-TS/effect-smol/commit/b6b81a940eaafcbc792d25413d6c02c707de31b2), [`8f4c1f9`](https://github.com/Effect-TS/effect-smol/commit/8f4c1f97ed60f8810b0b327b50117ffb2d8260d4), [`f2479f9`](https://github.com/Effect-TS/effect-smol/commit/f2479f9d3113b1f012db17a3852b4e28f478cf9c), [`c919921`](https://github.com/Effect-TS/effect-smol/commit/c9199217fad65529421d2cf95ecfff41257090fd), [`7af90c2`](https://github.com/Effect-TS/effect-smol/commit/7af90c2e3c99038eafa39650433839523790e2fe), [`f3be185`](https://github.com/Effect-TS/effect-smol/commit/f3be18569e5ca57c25eabf00df3ca601ebab43c7)]:
|
||||
- effect@4.0.0-beta.37
|
||||
|
||||
## 4.0.0-beta.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`60fcbcc`](https://github.com/Effect-TS/effect-smol/commit/60fcbcc43d09471e8f7e0969955d99dcefc5be81), [`0a60837`](https://github.com/Effect-TS/effect-smol/commit/0a6083713124440e630030375bab367e8d7df24e), [`49164d2`](https://github.com/Effect-TS/effect-smol/commit/49164d2c20a8d21b66514992c4a15d8521f6b36e), [`334b6e4`](https://github.com/Effect-TS/effect-smol/commit/334b6e4f76fe11941b516d61f57e268bc31f0ca6), [`5700695`](https://github.com/Effect-TS/effect-smol/commit/5700695f76ae6da6b94c9c87d4dd2b8054fb829b), [`f8f4456`](https://github.com/Effect-TS/effect-smol/commit/f8f445644f3aa7ec093cab7445198a62ba18a480), [`969d24f`](https://github.com/Effect-TS/effect-smol/commit/969d24fdfa48c4838e811983848d9cb4e9b3b12c), [`851eda0`](https://github.com/Effect-TS/effect-smol/commit/851eda0533946e39bacaaf581896320d7a4f3e8c), [`8059c1c`](https://github.com/Effect-TS/effect-smol/commit/8059c1c3eba9a90af7cd889ea261bcb8fff0c185), [`6f83295`](https://github.com/Effect-TS/effect-smol/commit/6f8329546a73eaddc7cb5e85ea8e37e73fbfb611), [`65f7f57`](https://github.com/Effect-TS/effect-smol/commit/65f7f5737575fed668987462c96d29a446707c32), [`e7fabd2`](https://github.com/Effect-TS/effect-smol/commit/e7fabd2265db690eae5cfc9b83730c84699aef61), [`89c3e98`](https://github.com/Effect-TS/effect-smol/commit/89c3e985401eb38f33a3ae21a94ad27de3c1d28b), [`53794ab`](https://github.com/Effect-TS/effect-smol/commit/53794ab7af30aa5c5004ecf53659fafbe4b10542)]:
|
||||
- effect@4.0.0-beta.36
|
||||
|
||||
## 4.0.0-beta.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9252b43`](https://github.com/Effect-TS/effect-smol/commit/9252b43560f507709c2985abcf52a7837b23ddf8), [`7daf387`](https://github.com/Effect-TS/effect-smol/commit/7daf3870a656882a488a60f67881e6808c8f4d04), [`e1664a3`](https://github.com/Effect-TS/effect-smol/commit/e1664a38bc31ef4ceb4e9324c7226e1e99bf9c07), [`fdaa6e0`](https://github.com/Effect-TS/effect-smol/commit/fdaa6e0a41b6b6605438fa8557441792135380a2), [`19aa47e`](https://github.com/Effect-TS/effect-smol/commit/19aa47ef7b470e427620edca8970dd9cdd551216), [`c667dad`](https://github.com/Effect-TS/effect-smol/commit/c667dad07777b860e4764a3ba9a6cc41c236cd98), [`764d150`](https://github.com/Effect-TS/effect-smol/commit/764d1501bc5026b60fc8aef6cb02a5a87c762801), [`3c27098`](https://github.com/Effect-TS/effect-smol/commit/3c27098b5685a63db2c2eff654a250c94d3fcfa7)]:
|
||||
- effect@4.0.0-beta.35
|
||||
|
||||
## 4.0.0-beta.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1764](https://github.com/Effect-TS/effect-smol/pull/1764) [`342fc4b`](https://github.com/Effect-TS/effect-smol/commit/342fc4b051739e32e7977159f26ff9541eda664f) Thanks @tim-smart! - Add unstable EmbeddingModel support across core and OpenAI providers.
|
||||
- Add the unstable EmbeddingModel module API surface in `effect`, including service, request, response, and provider types.
|
||||
- Implement the unstable EmbeddingModel runtime constructor in `effect`, with `RequestResolver` batching, `embed` / `embedMany` spans, provider error propagation, deterministic ordering, and empty-input `embedMany` fast-path behavior.
|
||||
- Add and align EmbeddingModel behavior tests in `effect` for embedding usage, batching, ordering, and error handling.
|
||||
- Add `OpenAiEmbeddingModel` in `@effect/ai-openai`, including model / make / layer constructors, config overrides, and provider output index validation with deterministic reordering.
|
||||
- Add OpenAI-compatible EmbeddingModel provider support in `@effect/ai-openai-compat`, including config overrides, layer constructors, and output index validation.
|
||||
|
||||
- [#1771](https://github.com/Effect-TS/effect-smol/pull/1771) [`00add69`](https://github.com/Effect-TS/effect-smol/commit/00add69b59551e9df34772eb927638b093f6d71e) Thanks @tim-smart! - Add `EmbeddingModel.ModelDimensions` and require dimensions in embedding provider `model` constructors.
|
||||
|
||||
- Updated dependencies [[`f2f75ee`](https://github.com/Effect-TS/effect-smol/commit/f2f75ee564bce1cd95f5189c7bdeeed4f92dacb1), [`342fc4b`](https://github.com/Effect-TS/effect-smol/commit/342fc4b051739e32e7977159f26ff9541eda664f), [`5d704ee`](https://github.com/Effect-TS/effect-smol/commit/5d704ee10d20e8eb107e34bb8a21feb5aa4a7685), [`00add69`](https://github.com/Effect-TS/effect-smol/commit/00add69b59551e9df34772eb927638b093f6d71e), [`58217d3`](https://github.com/Effect-TS/effect-smol/commit/58217d318a7d716ccd707cce0f41573946939c28), [`f4e2aba`](https://github.com/Effect-TS/effect-smol/commit/f4e2aba01b76d1e3059b297e3cc942284dfeafb2), [`e3b44b6`](https://github.com/Effect-TS/effect-smol/commit/e3b44b6a2af9ee21dc5c1e928f0c20af857fa7a9), [`e1472b7`](https://github.com/Effect-TS/effect-smol/commit/e1472b7525c5d57a48bdec2353c3b742f7f916c0), [`7686320`](https://github.com/Effect-TS/effect-smol/commit/7686320cd123fa352b5c3d076fb18a3cac0a9bba)]:
|
||||
- effect@4.0.0-beta.34
|
||||
|
||||
## 4.0.0-beta.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`571447d`](https://github.com/Effect-TS/effect-smol/commit/571447da67334449f8ae3d6ecb3d77ea4e0c4295)]:
|
||||
- effect@4.0.0-beta.33
|
||||
|
||||
## 4.0.0-beta.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf8fff8`](https://github.com/Effect-TS/effect-smol/commit/bf8fff8a5f54b6df74cb7bbb42346fe9ba52435a), [`1af3ef3`](https://github.com/Effect-TS/effect-smol/commit/1af3ef3e3ca7fd417d0fc15f8ca8fe207eba4f74), [`27fea0f`](https://github.com/Effect-TS/effect-smol/commit/27fea0f66910de5905f40fd63f8ddbb6f7ac5aba), [`2ad6c1b`](https://github.com/Effect-TS/effect-smol/commit/2ad6c1b2c85a3a0fe351e3d56636a75eb76b4b4e), [`398ac3e`](https://github.com/Effect-TS/effect-smol/commit/398ac3e01cb75efce0e4e2913d1450cf65866732), [`51fe22f`](https://github.com/Effect-TS/effect-smol/commit/51fe22f3266e417b6c541aaed4b75d246fac91e7), [`4605db6`](https://github.com/Effect-TS/effect-smol/commit/4605db69cfacddbdbf1525865ddfde135158090c), [`f4de1b0`](https://github.com/Effect-TS/effect-smol/commit/f4de1b087c998d0bad1d9468f70b7d16c13b9f6f), [`60214f2`](https://github.com/Effect-TS/effect-smol/commit/60214f2080b2aeb091f691140eb20acb741691c3), [`c4b8b0f`](https://github.com/Effect-TS/effect-smol/commit/c4b8b0ffa8efb47c4cd7578a8943d6868509373f), [`6d9393a`](https://github.com/Effect-TS/effect-smol/commit/6d9393a0770a18722d23340e77f15455de341245), [`6de4efe`](https://github.com/Effect-TS/effect-smol/commit/6de4efe463c783614ceb0c094d77a336a899cbe0), [`4f969d1`](https://github.com/Effect-TS/effect-smol/commit/4f969d1563ba755ffa116c8ae409bb3436bd881d), [`6cc67c8`](https://github.com/Effect-TS/effect-smol/commit/6cc67c855e054ee3f3ac3485dca5f7805e79e8fb), [`8531a22`](https://github.com/Effect-TS/effect-smol/commit/8531a22ffbb52e11a030b09f358cafbfdf5edff7), [`b226760`](https://github.com/Effect-TS/effect-smol/commit/b22676067617f15c00722a3a63fd7c2c172c3d45), [`47a51ab`](https://github.com/Effect-TS/effect-smol/commit/47a51aba0ecdf3ef478bfa28a498bca188399bd4), [`1521d02`](https://github.com/Effect-TS/effect-smol/commit/1521d02e1f19f1d795edaaf862c1a1031d9c755e)]:
|
||||
- effect@4.0.0-beta.32
|
||||
|
||||
## 4.0.0-beta.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6f23f0e`](https://github.com/Effect-TS/effect-smol/commit/6f23f0ed4cba573cd9395c2e582f582fe7271544), [`654aaec`](https://github.com/Effect-TS/effect-smol/commit/654aaec593305521b65dd042c204d761cc6e8c28), [`2958a42`](https://github.com/Effect-TS/effect-smol/commit/2958a42078966a8713a98f00485ab36484d5eccf), [`95d27a2`](https://github.com/Effect-TS/effect-smol/commit/95d27a239ed5147302605ab0b3147a056541b0c7), [`0fbaea8`](https://github.com/Effect-TS/effect-smol/commit/0fbaea8f9555a8044cec31a770394db613fc78e2), [`21d5d5e`](https://github.com/Effect-TS/effect-smol/commit/21d5d5e0439fd4d9bb6e508377215b1087555d45), [`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6e49959`](https://github.com/Effect-TS/effect-smol/commit/6e499590357a104c81779b3176cd3f84e4f91064), [`8f5805d`](https://github.com/Effect-TS/effect-smol/commit/8f5805dbdd0d1bc0ff0727cc398c8d80e544edee), [`990df2c`](https://github.com/Effect-TS/effect-smol/commit/990df2c3ceeb32e659acc10cc9485617f7b3c423)]:
|
||||
- effect@4.0.0-beta.31
|
||||
|
||||
## 4.0.0-beta.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1692](https://github.com/Effect-TS/effect-smol/pull/1692) [`00caf4f`](https://github.com/Effect-TS/effect-smol/commit/00caf4fbe209ff56426e9bcd51a205bdb84b978e) Thanks @tim-smart! - Preserve streamed OpenAI compat tool call ids and names across fragmented chat completion chunks.
|
||||
|
||||
- Updated dependencies [[`c88e5b7`](https://github.com/Effect-TS/effect-smol/commit/c88e5b723ff09da4edaef6ce14d927ca01104a32), [`947d0e4`](https://github.com/Effect-TS/effect-smol/commit/947d0e4268ba5c4020ead380aa80812c7342408f), [`7517908`](https://github.com/Effect-TS/effect-smol/commit/75179085d159b88a1ab0bce70669d76dcf0d79a4), [`a49ecd5`](https://github.com/Effect-TS/effect-smol/commit/a49ecd5a183d7e7d33f47ff95e9d2dea5a12ead5), [`6993e33`](https://github.com/Effect-TS/effect-smol/commit/6993e3329122c834c20bacea72d8678232f4f103), [`514f2a2`](https://github.com/Effect-TS/effect-smol/commit/514f2a2ae54580fcacdbe2ea2196a83a852d0748), [`3214b47`](https://github.com/Effect-TS/effect-smol/commit/3214b47676de2d33fddc5fecfc2d226e6e83cc7b), [`95ec5ed`](https://github.com/Effect-TS/effect-smol/commit/95ec5ed345de77c893049e182d37a37cf164a268)]:
|
||||
- effect@4.0.0-beta.30
|
||||
|
||||
## 4.0.0-beta.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9d93adb`](https://github.com/Effect-TS/effect-smol/commit/9d93adb1c1795d1978391b30d7d2972c88052662), [`b52721c`](https://github.com/Effect-TS/effect-smol/commit/b52721cf0d11a567722b060c8536e3bdd4161f07), [`a891c7b`](https://github.com/Effect-TS/effect-smol/commit/a891c7b12f415b2287613dd4b91a09dfd38ef30d), [`ef26cdf`](https://github.com/Effect-TS/effect-smol/commit/ef26cdfb65d9955fc7e161629191930c2cc2c63f), [`82fd3ed`](https://github.com/Effect-TS/effect-smol/commit/82fd3ed922063ee5a34f96f3993c15c7515e4f67)]:
|
||||
- effect@4.0.0-beta.29
|
||||
|
||||
## 4.0.0-beta.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1634](https://github.com/Effect-TS/effect-smol/pull/1634) [`621d3a1`](https://github.com/Effect-TS/effect-smol/commit/621d3a1248ef50e83c35d71333c69bf01bc33a11) Thanks @tim-smart! - Allow custom request properties in openai-compat model config and chat request types, and forward model-level custom properties to chat-completions payloads.
|
||||
|
||||
- Updated dependencies [[`ff533f2`](https://github.com/Effect-TS/effect-smol/commit/ff533f203cd06302ad08032a27e01269b4a2d4c6), [`dc803ee`](https://github.com/Effect-TS/effect-smol/commit/dc803ee52ebd3e9f931118f0dfcb804542847556), [`d660b1c`](https://github.com/Effect-TS/effect-smol/commit/d660b1c99cb93d4f79715e91c7a4486801c0eefa), [`93a05e3`](https://github.com/Effect-TS/effect-smol/commit/93a05e3eaa624058b162aedd66aad70102837270), [`2a65cf6`](https://github.com/Effect-TS/effect-smol/commit/2a65cf6fd81ef63d944e6fb51f058d439bf4a834), [`a561a40`](https://github.com/Effect-TS/effect-smol/commit/a561a40cc41c548c2cf3153aca065ee92ee8aa57), [`29cd24d`](https://github.com/Effect-TS/effect-smol/commit/29cd24d1fe78480a72eeb38a90281ffddc0530bc), [`662a8e6`](https://github.com/Effect-TS/effect-smol/commit/662a8e6857dac64a7cd13bd8df4b0674654622f8), [`d2b52ba`](https://github.com/Effect-TS/effect-smol/commit/d2b52bae5b9336cf59729fbdcc4d7f09512b0cbf), [`407c3b4`](https://github.com/Effect-TS/effect-smol/commit/407c3b43a5d1414558e0e33b6f1fc0e6a6d489cc), [`42bc7ce`](https://github.com/Effect-TS/effect-smol/commit/42bc7ce5480f6f2953c39f8cb5c850d61df6f5a2), [`e741322`](https://github.com/Effect-TS/effect-smol/commit/e74132226cbfee24234311c7c1c13e6b7391384e), [`5c75fa8`](https://github.com/Effect-TS/effect-smol/commit/5c75fa8fb71163bc4c035ba1a215574dfd4badfc), [`747177b`](https://github.com/Effect-TS/effect-smol/commit/747177b0602f12d4461a843e953dfdffbeb0a429), [`326cd48`](https://github.com/Effect-TS/effect-smol/commit/326cd4828bce573fe985f35152155464bf4c5a70), [`627e922`](https://github.com/Effect-TS/effect-smol/commit/627e922b8d1e9521eae5e1caa5d667ad00b1619a), [`662287e`](https://github.com/Effect-TS/effect-smol/commit/662287e9abc76c941ccc2ee330aa07904d571341)]:
|
||||
- effect@4.0.0-beta.28
|
||||
|
||||
## 4.0.0-beta.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1623](https://github.com/Effect-TS/effect-smol/pull/1623) [`2cf00c1`](https://github.com/Effect-TS/effect-smol/commit/2cf00c184ccc994b7977f33996321923fa3534c4) Thanks @tim-smart! - Forward `OpenAiLanguageModel` `reasoning` config into chat-completions requests.
|
||||
|
||||
- Updated dependencies [[`903a839`](https://github.com/Effect-TS/effect-smol/commit/903a839e94239e6ec4568315af28e405bcad95f4), [`91a0168`](https://github.com/Effect-TS/effect-smol/commit/91a016836680a6669308ecf464d3584bcc4ae1b7), [`c890f9a`](https://github.com/Effect-TS/effect-smol/commit/c890f9a1b3a989ed22528bd5a43326342e05b142), [`1e985f2`](https://github.com/Effect-TS/effect-smol/commit/1e985f237d250b51b91de22dde77160c1e778ce7)]:
|
||||
- effect@4.0.0-beta.27
|
||||
|
||||
## 4.0.0-beta.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fb21462`](https://github.com/Effect-TS/effect-smol/commit/fb21462642cdd5b1bada92f3eba18ae20445be42), [`2ed26b1`](https://github.com/Effect-TS/effect-smol/commit/2ed26b139805700e3df39efaa768ff01565e5c86), [`e832a57`](https://github.com/Effect-TS/effect-smol/commit/e832a57b570fe38f010c1fd99bceac5a325a9e07), [`7f01be7`](https://github.com/Effect-TS/effect-smol/commit/7f01be7f8db363d4b2e88e6b5571e96bb815786f), [`e965143`](https://github.com/Effect-TS/effect-smol/commit/e9651431e114479e6becf8ca7b1ed99ac7e91ccc), [`b9b80f1`](https://github.com/Effect-TS/effect-smol/commit/b9b80f1f15e152ceef0a727d150b7dc230abae99), [`98252aa`](https://github.com/Effect-TS/effect-smol/commit/98252aa0c0b17fc73fbdad65d0a1104965f9fc0f), [`56fbd94`](https://github.com/Effect-TS/effect-smol/commit/56fbd94311ad19a05001ad649d9e34ab00c74541), [`3faa109`](https://github.com/Effect-TS/effect-smol/commit/3faa109b7d093fbf14ad410d3e11d663f16e28f1), [`692ecfe`](https://github.com/Effect-TS/effect-smol/commit/692ecfed99fe58056b7a5afe001f4fcd1a61c446), [`1e70b72`](https://github.com/Effect-TS/effect-smol/commit/1e70b72d0b210474d0e96a15a5cfc279eae37e0c), [`ecf0782`](https://github.com/Effect-TS/effect-smol/commit/ecf07829ef2dfc01d8943c96c4fe9c1b44b97926)]:
|
||||
- effect@4.0.0-beta.26
|
||||
|
||||
## 4.0.0-beta.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fa17bb5`](https://github.com/Effect-TS/effect-smol/commit/fa17bb5be9f2533d01e11322b14804c7dec43714), [`f46e5b5`](https://github.com/Effect-TS/effect-smol/commit/f46e5b5ca2a918ee4d9270167e79db223077c96f), [`ce4767c`](https://github.com/Effect-TS/effect-smol/commit/ce4767cadcacc6ce8ff4c3a0d0fbc82ede655f63), [`c830a8b`](https://github.com/Effect-TS/effect-smol/commit/c830a8b6c292a6528d7f9318759d34800b00372d)]:
|
||||
- effect@4.0.0-beta.25
|
||||
|
||||
## 4.0.0-beta.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a909e1c`](https://github.com/Effect-TS/effect-smol/commit/a909e1c1ac2bc707527f5073776e3e7d239688d9), [`8814a4e`](https://github.com/Effect-TS/effect-smol/commit/8814a4ef78d67144d27689370af10099ea210399), [`3f942c5`](https://github.com/Effect-TS/effect-smol/commit/3f942c51cefa7b2ffa7c49e8c8a2c887570ba4c0), [`774ed59`](https://github.com/Effect-TS/effect-smol/commit/774ed59c52b2ab578bbb897c4f551f812231e1d2), [`f54b8d3`](https://github.com/Effect-TS/effect-smol/commit/f54b8d398fedad1815fd1f4c49814ab938cfc385)]:
|
||||
- effect@4.0.0-beta.24
|
||||
|
||||
## 4.0.0-beta.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c73c41`](https://github.com/Effect-TS/effect-smol/commit/5c73c41b69eaeab80fcd62c9bfda490b446d1966)]:
|
||||
- effect@4.0.0-beta.23
|
||||
|
||||
## 4.0.0-beta.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0874332`](https://github.com/Effect-TS/effect-smol/commit/0874332f7c81118b06ac2eb105e0710211631479), [`c592dcd`](https://github.com/Effect-TS/effect-smol/commit/c592dcde0697e322065c8f418c0480ef910cb183), [`1dbe28d`](https://github.com/Effect-TS/effect-smol/commit/1dbe28dac8299cd3e218c9768450cfd173b5e294), [`564d730`](https://github.com/Effect-TS/effect-smol/commit/564d730b6bbf38dd8548a3b046e7a693b28699a4), [`3cfadc4`](https://github.com/Effect-TS/effect-smol/commit/3cfadc458b070c6cba6c5674b72a059f1e49118b), [`6634fd0`](https://github.com/Effect-TS/effect-smol/commit/6634fd07da067d80b8261fb2959d1a952b9e412e), [`d10dabe`](https://github.com/Effect-TS/effect-smol/commit/d10dabeb7af9a368f995829cd36ad08167cd8f95), [`f82f549`](https://github.com/Effect-TS/effect-smol/commit/f82f549a09e950e9d4987f279a800f4d953f0939), [`78a3382`](https://github.com/Effect-TS/effect-smol/commit/78a3382ddfbe034408f7480fa794733d9e82147b)]:
|
||||
- effect@4.0.0-beta.22
|
||||
|
||||
## 4.0.0-beta.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e691909`](https://github.com/Effect-TS/effect-smol/commit/e691909495ccb162ea7bfa351dd74632b99997cb), [`d5f413f`](https://github.com/Effect-TS/effect-smol/commit/d5f413f3c8fc57f2413cc5649c2003d6d4e5a6d7), [`139d152`](https://github.com/Effect-TS/effect-smol/commit/139d152941e562a073b5be12e8d66c8a4d4a8a57), [`947e3d4`](https://github.com/Effect-TS/effect-smol/commit/947e3d436ab8a017efda9b29be523efd1ca8df28), [`84b2cce`](https://github.com/Effect-TS/effect-smol/commit/84b2ccefe2aa3a7413b86738a4dc33cdb311ca55), [`7f5305e`](https://github.com/Effect-TS/effect-smol/commit/7f5305e69f5a33309e77b08a576edb25d7daaee2), [`9e6fd84`](https://github.com/Effect-TS/effect-smol/commit/9e6fd8471c93a3c643929151a3bdb62cb9c0ca0e), [`fdb8a4b`](https://github.com/Effect-TS/effect-smol/commit/fdb8a4b172721fbefe98bd5aa6fe4f0efd1da3eb), [`0f986ef`](https://github.com/Effect-TS/effect-smol/commit/0f986ef22f196fe091a7afdbd179485a7d888882), [`9355fc0`](https://github.com/Effect-TS/effect-smol/commit/9355fc0ffb5b7382146a5aed9eea83974b10d007)]:
|
||||
- effect@4.0.0-beta.21
|
||||
|
||||
## 4.0.0-beta.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1529](https://github.com/Effect-TS/effect-smol/pull/1529) [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8) Thanks @tim-smart! - Add dedicated AiError metadata interfaces per reason so provider packages can safely augment metadata without conflicting module declarations.
|
||||
|
||||
- [#1528](https://github.com/Effect-TS/effect-smol/pull/1528) [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34) Thanks @tim-smart! - Add `Model.ModelName` and provide it from AI model constructors.
|
||||
|
||||
- Updated dependencies [[`842a624`](https://github.com/Effect-TS/effect-smol/commit/842a624f79d5e1407460b0ef3ab27d14d48ccf74), [`4785eef`](https://github.com/Effect-TS/effect-smol/commit/4785eef5d7cf1edb96ef2509aed2ba4d1edf3862), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`12ee8e2`](https://github.com/Effect-TS/effect-smol/commit/12ee8e27df7eb393d83a5e403390d0cfc82ca732), [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34), [`989d1cc`](https://github.com/Effect-TS/effect-smol/commit/989d1cca936fce0cc459057825ba40e3f5ef3827)]:
|
||||
- effect@4.0.0-beta.20
|
||||
|
||||
## 4.0.0-beta.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.19
|
||||
|
||||
## 4.0.0-beta.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`01e31fd`](https://github.com/Effect-TS/effect-smol/commit/01e31fdf8e5206849d23cbafd23a346f2f177ab8), [`0890aab`](https://github.com/Effect-TS/effect-smol/commit/0890aab15ed9c5ba52c383a72fdc6a444d7504d5), [`725260b`](https://github.com/Effect-TS/effect-smol/commit/725260b53f5142d6af7a93a2f9f464f974eda92d)]:
|
||||
- effect@4.0.0-beta.18
|
||||
|
||||
## 4.0.0-beta.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8f59c32`](https://github.com/Effect-TS/effect-smol/commit/8f59c32922597a48392744f7203e284866747781)]:
|
||||
- effect@4.0.0-beta.17
|
||||
|
||||
## 4.0.0-beta.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf9096c`](https://github.com/Effect-TS/effect-smol/commit/bf9096c52a7d8791d93d232739e523eb84f6625a), [`29f81ca`](https://github.com/Effect-TS/effect-smol/commit/29f81ca07c67dba265804b140a7487fb15a5fc6b), [`68eb28c`](https://github.com/Effect-TS/effect-smol/commit/68eb28c2b0fc67a9f6204ade9bd16c5b37803bfb)]:
|
||||
- effect@4.0.0-beta.16
|
||||
|
||||
## 4.0.0-beta.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1502](https://github.com/Effect-TS/effect-smol/pull/1502) [`285b7e6`](https://github.com/Effect-TS/effect-smol/commit/285b7e667167566d5788367d5155b19c79f1bf22) Thanks @tim-smart! - allow undefined for ai config
|
||||
|
||||
- Updated dependencies [[`24ae609`](https://github.com/Effect-TS/effect-smol/commit/24ae60995d2fd7d621be356cdfdfd328c79639ba), [`0e3c059`](https://github.com/Effect-TS/effect-smol/commit/0e3c059987caa55ebd0c134f7c7b147c639c328e), [`e843b0a`](https://github.com/Effect-TS/effect-smol/commit/e843b0a7d7e7b600a0b3bd477f24e2e4cd26bc8b), [`f4389a2`](https://github.com/Effect-TS/effect-smol/commit/f4389a2cca3c5bbf00d69779f52ce41255f15a28), [`5b73de0`](https://github.com/Effect-TS/effect-smol/commit/5b73de095b3402d0c5c74092ace6ce18ebfad566), [`595d2d6`](https://github.com/Effect-TS/effect-smol/commit/595d2d6e7d50419f3532bd39266191532ace38f2)]:
|
||||
- effect@4.0.0-beta.15
|
||||
|
||||
## 4.0.0-beta.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c414700`](https://github.com/Effect-TS/effect-smol/commit/c414700ef1932e4b67d0102856de417336912350), [`a30c969`](https://github.com/Effect-TS/effect-smol/commit/a30c9699c0d736cf3952041e45d508b7d58907a9)]:
|
||||
- effect@4.0.0-beta.14
|
||||
|
||||
## 4.0.0-beta.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`368f4c3`](https://github.com/Effect-TS/effect-smol/commit/368f4c363dd117e6f5a19ad77b161176cfd29fdd), [`db8a579`](https://github.com/Effect-TS/effect-smol/commit/db8a579e93e93ff73b1e60712732e03b597b916b), [`668b703`](https://github.com/Effect-TS/effect-smol/commit/668b70337e9ddbb0d1ae2282a95c282ce404e562), [`d40e76b`](https://github.com/Effect-TS/effect-smol/commit/d40e76b973543979e60e04a6baca04a8c65bdfc2), [`6e18cf8`](https://github.com/Effect-TS/effect-smol/commit/6e18cf883e9905ca718a6697b6a2a4bbd42739aa), [`86062e8`](https://github.com/Effect-TS/effect-smol/commit/86062e8a0c61bca5412fc40d2cf151d676901f08), [`c27ce75`](https://github.com/Effect-TS/effect-smol/commit/c27ce75d34c74dcfc6dba1bf77f1ce88f410a0de), [`e2d4fbf`](https://github.com/Effect-TS/effect-smol/commit/e2d4fbfeeda6a5d2a4c5aeb0501d8240c248b9eb), [`114ab42`](https://github.com/Effect-TS/effect-smol/commit/114ab42ad0edc590d29169675a493e0e915aa58f), [`484caec`](https://github.com/Effect-TS/effect-smol/commit/484caec47cccac8b86db2910742e406dfc7173ab)]:
|
||||
- effect@4.0.0-beta.13
|
||||
|
||||
## 4.0.0-beta.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70a74e8`](https://github.com/Effect-TS/effect-smol/commit/70a74e88a8767c9d4acdb9e5f25aec9a33588d07), [`b5b6e10`](https://github.com/Effect-TS/effect-smol/commit/b5b6e10621d54bf8c9857fec0d647ced78ecd857), [`f5ce5a9`](https://github.com/Effect-TS/effect-smol/commit/f5ce5a915359c6ebf254079e1da23cab6cde34fb), [`a29eb70`](https://github.com/Effect-TS/effect-smol/commit/a29eb702ffe3fc58bd28c4d7857298cd65d73668), [`c7b36e5`](https://github.com/Effect-TS/effect-smol/commit/c7b36e541a23e9a00f64e25b23851e51a37dfce5), [`9381d6d`](https://github.com/Effect-TS/effect-smol/commit/9381d6d4d9d819a81a46e56d0364c76e92a4fbca), [`88439f1`](https://github.com/Effect-TS/effect-smol/commit/88439f13ca13549f3e4822c48c4f019c14fc2bcc), [`e35307d`](https://github.com/Effect-TS/effect-smol/commit/e35307dbeb8eb26a9923f958b894a8eaaf259bf2), [`c7df4bc`](https://github.com/Effect-TS/effect-smol/commit/c7df4bce34009474c63d62a807abfdafb76971eb), [`accaf3b`](https://github.com/Effect-TS/effect-smol/commit/accaf3be7ac8da36e2334c509c23b8c9e88ea160), [`3e1c270`](https://github.com/Effect-TS/effect-smol/commit/3e1c2707bbdf67720af1509642b8ced195790882), [`6cd81f7`](https://github.com/Effect-TS/effect-smol/commit/6cd81f73baad86f5bbfa455a55d75cde71e9611a), [`f222da3`](https://github.com/Effect-TS/effect-smol/commit/f222da3cdb44554f3324c2c52d0d005ee575053e), [`61f901d`](https://github.com/Effect-TS/effect-smol/commit/61f901d830005b66e22d1de889fda132aeea97cd)]:
|
||||
- effect@4.0.0-beta.12
|
||||
|
||||
## 4.0.0-beta.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`88659ed`](https://github.com/Effect-TS/effect-smol/commit/88659edb26e3623d557dccfe914c2c949672da16), [`f2915e8`](https://github.com/Effect-TS/effect-smol/commit/f2915e8e2efe80d50c281e53f297b9701d6dc199), [`eb71ace`](https://github.com/Effect-TS/effect-smol/commit/eb71acebbe0f228e4920278013beee3b67d62310), [`2a16999`](https://github.com/Effect-TS/effect-smol/commit/2a169996c7513d377ac47adbfd68e1490457135c), [`d42dd52`](https://github.com/Effect-TS/effect-smol/commit/d42dd52f11203f8e749fb5d3ecf7153e4a5a6814), [`339adaf`](https://github.com/Effect-TS/effect-smol/commit/339adaf850a62a892adebcb208c2d9dddf3b97b3), [`de19645`](https://github.com/Effect-TS/effect-smol/commit/de1964526d01102dd1cb99c8cfdd3e8df1f49ef1), [`9b1dc3b`](https://github.com/Effect-TS/effect-smol/commit/9b1dc3bcf2a1b68d0a67e3465db5ad01a1a56997), [`e4cb2f5`](https://github.com/Effect-TS/effect-smol/commit/e4cb2f55b30f4771ec1bf613ced36d6d96464dd5), [`8bced95`](https://github.com/Effect-TS/effect-smol/commit/8bced954ecb35d4489197a57b0efe927e7d75f49), [`9431420`](https://github.com/Effect-TS/effect-smol/commit/94314207c8019918200fbcb97aec992219f801f0), [`948dca2`](https://github.com/Effect-TS/effect-smol/commit/948dca22e4f672ba7a6db57f9899272bec7c08b8), [`d18e327`](https://github.com/Effect-TS/effect-smol/commit/d18e32765a2665e31ffb31e746bf983fcfac34c5), [`ab512f7`](https://github.com/Effect-TS/effect-smol/commit/ab512f7be1c0e6b359da921e22cd4944e4c57d3e)]:
|
||||
- effect@4.0.0-beta.11
|
||||
|
||||
## 4.0.0-beta.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`371acab`](https://github.com/Effect-TS/effect-smol/commit/371acabb58d56f3a7a5e3e33d3d5fdc9f5573c74), [`856d774`](https://github.com/Effect-TS/effect-smol/commit/856d7741f1e296dd5048c6ff2b44b95d023e6ae4), [`b9e9202`](https://github.com/Effect-TS/effect-smol/commit/b9e92023c38caa322975d77cfe83e2d34ac9305a), [`1d1a974`](https://github.com/Effect-TS/effect-smol/commit/1d1a974bd280c81bff5d4505491cda03ba7a3f36), [`6bfe2a6`](https://github.com/Effect-TS/effect-smol/commit/6bfe2a659bc6335db75709931f405da45301cba2), [`b12c811`](https://github.com/Effect-TS/effect-smol/commit/b12c81157be287b1649c210616a244b50ec094d2), [`d17d98a`](https://github.com/Effect-TS/effect-smol/commit/d17d98ad78e2b44d95ef434adab79ac3c35e75ab), [`68c3c7c`](https://github.com/Effect-TS/effect-smol/commit/68c3c7cb1e06ed94fa5c4c123a234b4ccbfdecd8)]:
|
||||
- effect@4.0.0-beta.10
|
||||
|
||||
## 4.0.0-beta.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3386557`](https://github.com/Effect-TS/effect-smol/commit/338655731564a7be9f8859dedbf4d5bcac6eb350), [`b6666e3`](https://github.com/Effect-TS/effect-smol/commit/b6666e3cf6bd44ba1a8704e65c256c30359cb422)]:
|
||||
- effect@4.0.0-beta.9
|
||||
|
||||
## 4.0.0-beta.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`246e672`](https://github.com/Effect-TS/effect-smol/commit/246e672dbbd7848d60e0c78fd66671b2f10b3752), [`807dec0`](https://github.com/Effect-TS/effect-smol/commit/807dec03801b4c58a6d00c237b6d98d6386911df)]:
|
||||
- effect@4.0.0-beta.8
|
||||
|
||||
## 4.0.0-beta.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a2bda6d`](https://github.com/Effect-TS/effect-smol/commit/a2bda6d4ef6de9d9b0c53ae2df5434f778d6161a), [`1f95a2b`](https://github.com/Effect-TS/effect-smol/commit/1f95a2b5aa9524bb38f4437f4691a664bf463ca1), [`a8d5e79`](https://github.com/Effect-TS/effect-smol/commit/a8d5e792fec201a83af0eb92fc79928d055125fd), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`06d8a03`](https://github.com/Effect-TS/effect-smol/commit/06d8a0391631e6130e3ab25227e59817852e227f), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`f9e883e`](https://github.com/Effect-TS/effect-smol/commit/f9e883e266fbda870336ee62f46b7ac85ba3de6e), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430)]:
|
||||
- effect@4.0.0-beta.7
|
||||
|
||||
## 4.0.0-beta.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3247da2`](https://github.com/Effect-TS/effect-smol/commit/3247da28331f345f68be5dbd2974a7e03d300fe1), [`f205705`](https://github.com/Effect-TS/effect-smol/commit/f2057050dbd034b8c186be2d40c3d03ee63a5a3b), [`f35022c`](https://github.com/Effect-TS/effect-smol/commit/f35022c212e4111527e1bb43f360a67b2b49fa85), [`8622721`](https://github.com/Effect-TS/effect-smol/commit/86227217b02d43680a3c6f3c21731b1d852c91f5), [`fc660ab`](https://github.com/Effect-TS/effect-smol/commit/fc660ab8b5ebae38b8d6b96cbf2f9b880cc09253), [`f37dc33`](https://github.com/Effect-TS/effect-smol/commit/f37dc335f64622fa9ce8d6d1d5dd8fc3f260257b), [`3662f32`](https://github.com/Effect-TS/effect-smol/commit/3662f328fcfa3b2fa01ffa79da40e12e93fcede8), [`a7d436f`](https://github.com/Effect-TS/effect-smol/commit/a7d436f438dcd7f49b9485e4e95a4511f31fad7d), [`6856a41`](https://github.com/Effect-TS/effect-smol/commit/6856a415d7eddd9d73d60919e976f1d071421be4), [`8c417d0`](https://github.com/Effect-TS/effect-smol/commit/8c417d03475e5e12d00dca0c4781d0af7e66b86c), [`5419570`](https://github.com/Effect-TS/effect-smol/commit/5419570ba47ce882a3a10882707b46f66e464906), [`449c5ed`](https://github.com/Effect-TS/effect-smol/commit/449c5ed5318e8a874e730420bcf52918fa2ec80f), [`4b5ec12`](https://github.com/Effect-TS/effect-smol/commit/4b5ec12f87f95f2a3cd8fe4d5b26c6eb0529381a), [`df87937`](https://github.com/Effect-TS/effect-smol/commit/df879375fc3b169c43f9c434b3775e12b80dffe4), [`5dbfca8`](https://github.com/Effect-TS/effect-smol/commit/5dbfca8d1dbb6d18d1605d4f8562e99c86e2ff11), [`e629497`](https://github.com/Effect-TS/effect-smol/commit/e6294973d55597ab6b6deca6babbe1e946b2c91d), [`981c991`](https://github.com/Effect-TS/effect-smol/commit/981c991cd78db34def815d5754379d737157f005), [`1ca2ed6`](https://github.com/Effect-TS/effect-smol/commit/1ca2ed67301a5dc40ae0ed94346b99f26fd22bbe), [`45722bd`](https://github.com/Effect-TS/effect-smol/commit/45722bde974458311f11ad237711363a10ec6894), [`eb2a85e`](https://github.com/Effect-TS/effect-smol/commit/eb2a85ed4dc162b2535d304799333a5a20477fd0)]:
|
||||
- effect@4.0.0-beta.6
|
||||
|
||||
## 4.0.0-beta.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f6e133e`](https://github.com/Effect-TS/effect-smol/commit/f6e133e9a16b32317bd09ff08c12b97a0ae44600), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8), [`a88e206`](https://github.com/Effect-TS/effect-smol/commit/a88e206e44dc66ca5a2b45bedc797877c5dbb083), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8)]:
|
||||
- effect@4.0.0-beta.5
|
||||
|
||||
## 4.0.0-beta.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c5a18ef`](https://github.com/Effect-TS/effect-smol/commit/c5a18ef44171e3880bf983faee74529908974b32), [`bc6b885`](https://github.com/Effect-TS/effect-smol/commit/bc6b885b94d887a200657c0775dfa874dc15bc0c)]:
|
||||
- effect@4.0.0-beta.4
|
||||
|
||||
## 4.0.0-beta.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a0cf36`](https://github.com/Effect-TS/effect-smol/commit/3a0cf36eff106ba48d74e133c1598cd40613e530), [`c4da328`](https://github.com/Effect-TS/effect-smol/commit/c4da328d32fad1d61e0e538f5d371edf61521d7e)]:
|
||||
- effect@4.0.0-beta.3
|
||||
|
||||
## 4.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a22ce73`](https://github.com/Effect-TS/effect-smol/commit/a22ce73b2bd9305b7ba665694d2255c0e6d5a8d0), [`ebdabf7`](https://github.com/Effect-TS/effect-smol/commit/ebdabf79ff4e62c8384aa8cf9a8d2787d536ee78), [`8f663bb`](https://github.com/Effect-TS/effect-smol/commit/8f663bb121021bf12bd264e8ae385187cb7a5dae)]:
|
||||
- effect@4.0.0-beta.2
|
||||
|
||||
## 4.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0fecf70`](https://github.com/Effect-TS/effect-smol/commit/0fecf70048057623eed7c584a06671773a2b1743), [`709569e`](https://github.com/Effect-TS/effect-smol/commit/709569ed76bead9ebb0670599e4d890a07ca5a43)]:
|
||||
- effect@4.0.0-beta.1
|
||||
|
||||
## 4.0.0-beta.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#1183](https://github.com/Effect-TS/effect-smol/pull/1183) [`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66) Thanks @tim-smart! - v4 beta
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66)]:
|
||||
- effect@4.0.0-beta.0
|
||||
23
repos/effect/packages/ai/openai-compat/docgen.json
Normal file
23
repos/effect/packages/ai/openai-compat/docgen.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "../../node_modules/@effect/docgen/schema.json",
|
||||
"srcLink": "https://github.com/Effect-TS/effect/tree/main/packages/ai/openai-compat/src/",
|
||||
"exclude": ["src/internal/**"],
|
||||
"examplesCompilerOptions": {
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "Bundler",
|
||||
"module": "ES2022",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"rewriteRelativeImportExtensions": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"paths": {
|
||||
"effect": ["../../../effect/src/index.js"],
|
||||
"effect/*": ["../../../effect/src/*.js"]
|
||||
},
|
||||
"plugins": [
|
||||
{ "name": "@effect/language-service", "includeSuggestionsInTsc": false }
|
||||
]
|
||||
}
|
||||
}
|
||||
68
repos/effect/packages/ai/openai-compat/package.json
Normal file
68
repos/effect/packages/ai/openai-compat/package.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "@effect/ai-openai-compat",
|
||||
"version": "4.0.0-beta.99",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "An OpenAI compat integration for Effect",
|
||||
"homepage": "https://effect.website",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Effect-TS/effect.git",
|
||||
"directory": "packages/ai/openai-compat"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Effect-TS/effect/issues"
|
||||
},
|
||||
"tags": [
|
||||
"typescript",
|
||||
"ai",
|
||||
"openai",
|
||||
"compat"
|
||||
],
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"ai",
|
||||
"openai",
|
||||
"compat"
|
||||
],
|
||||
"sideEffects": [],
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts",
|
||||
"./*": "./src/*.ts",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
},
|
||||
"files": [
|
||||
"src/**/*.ts",
|
||||
"dist/**/*.js",
|
||||
"dist/**/*.js.map",
|
||||
"dist/**/*.d.ts",
|
||||
"dist/**/*.d.ts.map"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"provenance": true,
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./dist/index.js",
|
||||
"./*": "./dist/*.js",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"codegen": "effect-utils codegen",
|
||||
"build": "tsc -b tsconfig.json && pnpm babel",
|
||||
"babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
||||
"check": "tsc -b tsconfig.json",
|
||||
"test": "vitest",
|
||||
"coverage": "vitest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"effect": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "workspace:^"
|
||||
}
|
||||
}
|
||||
1221
repos/effect/packages/ai/openai-compat/src/OpenAiClient.ts
Normal file
1221
repos/effect/packages/ai/openai-compat/src/OpenAiClient.ts
Normal file
File diff suppressed because it is too large
Load Diff
87
repos/effect/packages/ai/openai-compat/src/OpenAiConfig.ts
Normal file
87
repos/effect/packages/ai/openai-compat/src/OpenAiConfig.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* The `OpenAiConfig` module lets a workflow temporarily customize the HTTP
|
||||
* client used by OpenAI-compatible request helpers. Model, embedding, and
|
||||
* tool-calling code can use this scoped configuration to add middleware,
|
||||
* instrumentation, or routing without rebuilding the client layer.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import type { HttpClient } from "effect/unstable/http/HttpClient"
|
||||
|
||||
/**
|
||||
* Context service for OpenAI-compatible client configuration in the current
|
||||
* Effect scope.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use as the context service for scoped OpenAI-compatible client configuration
|
||||
* and HTTP client transforms.
|
||||
*
|
||||
* @see {@link withClientTransform} for scoping an HTTP client transformation
|
||||
*
|
||||
* @category services
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class OpenAiConfig extends Context.Service<
|
||||
OpenAiConfig,
|
||||
OpenAiConfig.Service
|
||||
>()("@effect/ai-openai-compat/OpenAiConfig") {
|
||||
/**
|
||||
* Gets the configured OpenAI-compatible service from the current context when present.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
static readonly getOrUndefined: Effect.Effect<typeof OpenAiConfig.Service | undefined> = Effect.map(
|
||||
Effect.context<never>(),
|
||||
(context) => context.mapUnsafe.get(OpenAiConfig.key)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Types associated with the `OpenAiConfig` context service.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export declare namespace OpenAiConfig {
|
||||
/**
|
||||
* Configuration consumed by OpenAI-compatible clients when they build or
|
||||
* resolve the underlying HTTP client.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface Service {
|
||||
readonly transformClient?: ((client: HttpClient) => HttpClient) | undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an HTTP client transform for the supplied effect.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to add provider-specific OpenAI-compatible HTTP behavior, such as
|
||||
* headers, retries, instrumentation, or proxy routing.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* OpenAI-compatible provider services read the transform from the
|
||||
* `OpenAiConfig` context.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const withClientTransform: {
|
||||
(transform: (client: HttpClient) => HttpClient): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
|
||||
<A, E, R>(self: Effect.Effect<A, E, R>, transform: (client: HttpClient) => HttpClient): Effect.Effect<A, E, R>
|
||||
} = dual(2, <A, E, R>(
|
||||
self: Effect.Effect<A, E, R>,
|
||||
transformClient: (client: HttpClient) => HttpClient
|
||||
) =>
|
||||
Effect.flatMap(
|
||||
OpenAiConfig.getOrUndefined,
|
||||
(config) => Effect.provideService(self, OpenAiConfig, { ...config, transformClient })
|
||||
))
|
||||
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
* The `OpenAiEmbeddingModel` module adapts OpenAI-compatible embeddings
|
||||
* endpoints to Effect's embedding model service. It sends embedding requests
|
||||
* through {@link OpenAiClient}, exposes constructors for layers and `AiModel`
|
||||
* values, supports scoped request configuration overrides, and checks that the
|
||||
* provider returns one numeric vector for each requested input.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import * as Layer from "effect/Layer"
|
||||
import type { Simplify } from "effect/Types"
|
||||
import * as AiError from "effect/unstable/ai/AiError"
|
||||
import * as EmbeddingModel from "effect/unstable/ai/EmbeddingModel"
|
||||
import * as AiModel from "effect/unstable/ai/Model"
|
||||
import type { CreateEmbedding200, CreateEmbeddingRequestJson } from "./OpenAiClient.ts"
|
||||
import { OpenAiClient } from "./OpenAiClient.ts"
|
||||
|
||||
/**
|
||||
* A model identifier accepted by an OpenAI-compatible embeddings endpoint.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type Model = string
|
||||
|
||||
type ConfigOptions = Simplify<Partial<Omit<CreateEmbeddingRequestJson, "input">>>
|
||||
type ModelConfig = Omit<ConfigOptions, "model"> & { readonly [x: string]: unknown }
|
||||
|
||||
/**
|
||||
* Context service for OpenAI embedding model configuration.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need to provide shared default request options for
|
||||
* OpenAI-compatible embedding operations through the Effect context, such as
|
||||
* `dimensions`, `encoding_format`, or `user`.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The service stores the embedding request payload without `input`. Requests
|
||||
* combine the selected model, layer or constructor config, and scoped context
|
||||
* config, with scoped context config taking precedence.
|
||||
*
|
||||
* @see {@link withConfigOverride} for scoping embedding request overrides
|
||||
*
|
||||
* @category context
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class Config extends Context.Service<
|
||||
Config,
|
||||
ConfigOptions & { readonly [x: string]: unknown }
|
||||
>()("@effect/ai-openai-compat/OpenAiEmbeddingModel/Config") {}
|
||||
|
||||
/**
|
||||
* Creates an `AiModel` for an OpenAI-compatible embedding model with its configured vector dimensions.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to provide an OpenAI-compatible `EmbeddingModel` and its `Dimensions`
|
||||
* service to an Effect program.
|
||||
*
|
||||
* @see {@link layer} for providing only the embedding model service
|
||||
* @see {@link withConfigOverride} for scoped request configuration overrides
|
||||
*
|
||||
* @category constructors
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const model = (
|
||||
model: string,
|
||||
options: Omit<ConfigOptions, "model" | "dimensions"> & {
|
||||
readonly dimensions: number
|
||||
readonly [x: string]: unknown
|
||||
}
|
||||
): AiModel.Model<"openai", EmbeddingModel.EmbeddingModel | EmbeddingModel.Dimensions, OpenAiClient> =>
|
||||
AiModel.make(
|
||||
"openai",
|
||||
model,
|
||||
Layer.merge(
|
||||
layer({
|
||||
model,
|
||||
config: options
|
||||
}),
|
||||
Layer.succeed(EmbeddingModel.Dimensions, options.dimensions)
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* Creates an OpenAI-compatible embedding model service backed by `OpenAiClient`.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need to build or provide an `EmbeddingModel` service directly
|
||||
* from an existing `OpenAiClient`.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The service sends embedding requests through `OpenAiClient.createEmbedding`.
|
||||
* Request config is merged as the selected model, constructor config, then
|
||||
* scoped `Config`, so scoped overrides take precedence. Provider usage
|
||||
* `prompt_tokens` is exposed as `usage.inputTokens`.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* Provider responses must contain one numeric vector for every requested input
|
||||
* with unique, in-range `index` values; otherwise embedding operations fail with
|
||||
* `AiError.InvalidOutputError`.
|
||||
*
|
||||
* @see {@link model} for the higher-level `AiModel` descriptor that also provides `EmbeddingModel.Dimensions`
|
||||
* @see {@link layer} for providing the service as a `Layer`
|
||||
* @see {@link withConfigOverride} for scoping embedding request overrides
|
||||
*
|
||||
* @category constructors
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const make = Effect.fnUntraced(function*({ model, config: providerConfig }: {
|
||||
readonly model: string
|
||||
readonly config?: ModelConfig | undefined
|
||||
}): Effect.fn.Return<EmbeddingModel.Service, never, OpenAiClient> {
|
||||
const client = yield* OpenAiClient
|
||||
|
||||
const makeConfig = Effect.gen(function*() {
|
||||
const services = yield* Effect.context<never>()
|
||||
return { model, ...providerConfig, ...services.mapUnsafe.get(Config.key) }
|
||||
})
|
||||
|
||||
return yield* EmbeddingModel.make({
|
||||
embedMany: Effect.fnUntraced(function*({ inputs }) {
|
||||
const config = yield* makeConfig
|
||||
const response = yield* client.createEmbedding({ ...config, input: inputs })
|
||||
return yield* mapProviderResponse(inputs.length, response)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Creates a layer for an OpenAI-compatible embedding model service.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when composing application layers and you want an OpenAI-compatible
|
||||
* embeddings endpoint to satisfy `EmbeddingModel.EmbeddingModel` while
|
||||
* supplying `OpenAiClient` from another layer.
|
||||
*
|
||||
* @see {@link make} for constructing the embedding model service effectfully
|
||||
* @see {@link model} for creating an `AiModel` with configured dimensions
|
||||
*
|
||||
* @category layers
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const layer = (options: {
|
||||
readonly model: string
|
||||
readonly config?: ModelConfig | undefined
|
||||
}): Layer.Layer<EmbeddingModel.EmbeddingModel, never, OpenAiClient> =>
|
||||
Layer.effect(EmbeddingModel.EmbeddingModel, make(options))
|
||||
|
||||
/**
|
||||
* Provides scoped request config overrides for OpenAI-compatible embedding model operations.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to apply embedding request options to one effect without changing the
|
||||
* model's default configuration.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The overrides are merged with any existing `Config` service for the duration
|
||||
* of the supplied effect. Fields in `overrides` take precedence over existing
|
||||
* config, and the helper supports both `effect.pipe(withConfigOverride(overrides))`
|
||||
* and `withConfigOverride(effect, overrides)`.
|
||||
*
|
||||
* @see {@link Config} for available OpenAI-compatible embedding request configuration fields
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const withConfigOverride: {
|
||||
(overrides: typeof Config.Service): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Config>>
|
||||
<A, E, R>(self: Effect.Effect<A, E, R>, overrides: typeof Config.Service): Effect.Effect<A, E, Exclude<R, Config>>
|
||||
} = dual<
|
||||
(
|
||||
overrides: typeof Config.Service
|
||||
) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Config>>,
|
||||
<A, E, R>(self: Effect.Effect<A, E, R>, overrides: typeof Config.Service) => Effect.Effect<A, E, Exclude<R, Config>>
|
||||
>(2, (self, overrides) =>
|
||||
Effect.flatMap(
|
||||
Effect.serviceOption(Config),
|
||||
(config) =>
|
||||
Effect.provideService(self, Config, {
|
||||
...(config._tag === "Some" ? config.value : {}),
|
||||
...overrides
|
||||
})
|
||||
))
|
||||
|
||||
const mapProviderResponse = (
|
||||
inputLength: number,
|
||||
response: CreateEmbedding200
|
||||
): Effect.Effect<EmbeddingModel.ProviderResponse, AiError.AiError> => {
|
||||
if (response.data.length !== inputLength) {
|
||||
return Effect.fail(
|
||||
invalidOutput(`Provider returned ${response.data.length} embeddings but expected ${inputLength}`)
|
||||
)
|
||||
}
|
||||
|
||||
const results = new Array<Array<number>>(inputLength)
|
||||
const seen = new Set<number>()
|
||||
|
||||
for (const entry of response.data) {
|
||||
if (!Number.isInteger(entry.index) || entry.index < 0 || entry.index >= inputLength) {
|
||||
return Effect.fail(invalidOutput(`Provider returned invalid embedding index: ${entry.index}`))
|
||||
}
|
||||
if (seen.has(entry.index)) {
|
||||
return Effect.fail(invalidOutput(`Provider returned duplicate embedding index: ${entry.index}`))
|
||||
}
|
||||
if (!Array.isArray(entry.embedding)) {
|
||||
return Effect.fail(invalidOutput(`Provider returned non-vector embedding at index ${entry.index}`))
|
||||
}
|
||||
|
||||
seen.add(entry.index)
|
||||
results[entry.index] = [...entry.embedding]
|
||||
}
|
||||
|
||||
if (seen.size !== inputLength) {
|
||||
return Effect.fail(
|
||||
invalidOutput(`Provider returned embeddings for ${seen.size} inputs but expected ${inputLength}`)
|
||||
)
|
||||
}
|
||||
|
||||
return Effect.succeed({
|
||||
results,
|
||||
usage: {
|
||||
inputTokens: response.usage?.prompt_tokens
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const invalidOutput = (description: string): AiError.AiError =>
|
||||
AiError.make({
|
||||
module: "OpenAiEmbeddingModel",
|
||||
method: "embedMany",
|
||||
reason: new AiError.InvalidOutputError({ description })
|
||||
})
|
||||
178
repos/effect/packages/ai/openai-compat/src/OpenAiError.ts
Normal file
178
repos/effect/packages/ai/openai-compat/src/OpenAiError.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* The `OpenAiError` module defines OpenAI-specific metadata that can be
|
||||
* attached to the shared `AiError` error types used by the AI packages. It is
|
||||
* primarily used by OpenAI-compatible clients to preserve provider details
|
||||
* such as error codes, error types, request IDs, and rate limit headers while
|
||||
* still exposing errors through the provider-neutral Effect AI error model.
|
||||
*
|
||||
* Use this module when mapping OpenAI API failures into `AiError` values and
|
||||
* when consumers need enough structured metadata to debug failed requests,
|
||||
* inspect quota or rate limit responses, or correlate an error with OpenAI
|
||||
* support. The exported types are metadata shapes only; the module augmentation
|
||||
* makes those shapes available on the corresponding shared AI error metadata
|
||||
* interfaces without defining new runtime error classes.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* OpenAI-specific error metadata fields.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenAiErrorMetadata = {
|
||||
/**
|
||||
* The OpenAI error code returned by the API.
|
||||
*/
|
||||
readonly errorCode: string | null
|
||||
/**
|
||||
* The OpenAI error type returned by the API.
|
||||
*/
|
||||
readonly errorType: string | null
|
||||
/**
|
||||
* The unique request ID for debugging with OpenAI support.
|
||||
*/
|
||||
readonly requestId: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI-specific rate limit metadata fields.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Extends base error metadata with rate limit specific information from
|
||||
* OpenAI's rate limit headers.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenAiRateLimitMetadata = OpenAiErrorMetadata & {
|
||||
/**
|
||||
* The rate limit type (e.g. "requests", "tokens").
|
||||
*/
|
||||
readonly limit: string | null
|
||||
/**
|
||||
* Number of remaining requests in the current window.
|
||||
*/
|
||||
readonly remaining: number | null
|
||||
/**
|
||||
* Time until the request rate limit resets.
|
||||
*/
|
||||
readonly resetRequests: string | null
|
||||
/**
|
||||
* Time until the token rate limit resets.
|
||||
*/
|
||||
readonly resetTokens: string | null
|
||||
}
|
||||
|
||||
declare module "effect/unstable/ai/AiError" {
|
||||
/**
|
||||
* Metadata attached to rate limit errors returned by OpenAI-compatible APIs.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface RateLimitErrorMetadata {
|
||||
readonly openai?: OpenAiRateLimitMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata attached when an OpenAI-compatible provider reports that quota or
|
||||
* billing limits have been exhausted.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface QuotaExhaustedErrorMetadata {
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata attached to authentication failures from OpenAI-compatible APIs,
|
||||
* such as invalid, missing, or unauthorized API credentials.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface AuthenticationErrorMetadata {
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata attached when an OpenAI-compatible provider rejects content because
|
||||
* it violates a safety or usage policy.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface ContentPolicyErrorMetadata {
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata attached to malformed or unsupported requests rejected by an
|
||||
* OpenAI-compatible API before model execution.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InvalidRequestErrorMetadata {
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata attached to unexpected server-side failures reported by an
|
||||
* OpenAI-compatible provider.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InternalProviderErrorMetadata {
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata attached when an OpenAI-compatible response cannot be converted
|
||||
* into the expected AI package output shape.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InvalidOutputErrorMetadata {
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata attached when an OpenAI-compatible structured output response does
|
||||
* not satisfy the requested schema or parsing constraints.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface StructuredOutputErrorMetadata {
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata attached when an OpenAI-compatible provider cannot support the
|
||||
* schema supplied for structured output or tool definitions.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface UnsupportedSchemaErrorMetadata {
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata attached when an OpenAI-compatible error response cannot be mapped
|
||||
* to a more specific shared AI error category.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface UnknownErrorMetadata {
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
}
|
||||
1948
repos/effect/packages/ai/openai-compat/src/OpenAiLanguageModel.ts
Normal file
1948
repos/effect/packages/ai/openai-compat/src/OpenAiLanguageModel.ts
Normal file
File diff suppressed because it is too large
Load Diff
164
repos/effect/packages/ai/openai-compat/src/OpenAiTelemetry.ts
Normal file
164
repos/effect/packages/ai/openai-compat/src/OpenAiTelemetry.ts
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* The `OpenAiTelemetry` module defines OpenAI-compatible telemetry attributes
|
||||
* and a helper for adding them to a tracing span. It keeps the standard GenAI
|
||||
* telemetry attributes and adds request and response metadata under the
|
||||
* `gen_ai.openai.*` OpenTelemetry namespaces.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import { dual } from "effect/Function"
|
||||
import * as String from "effect/String"
|
||||
import type { Span } from "effect/Tracer"
|
||||
import type { Simplify } from "effect/Types"
|
||||
import * as Telemetry from "effect/unstable/ai/Telemetry"
|
||||
|
||||
/**
|
||||
* The attributes used to describe telemetry in the context of Generative
|
||||
* Artificial Intelligence (GenAI) Models requests and responses.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* These attributes follow the OpenTelemetry generative AI semantic
|
||||
* conventions:
|
||||
* https://opentelemetry.io/docs/specs/semconv/attributes-registry/gen-ai/
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenAiTelemetryAttributes = Simplify<
|
||||
& Telemetry.GenAITelemetryAttributes
|
||||
& Telemetry.AttributesWithPrefix<RequestAttributes, "gen_ai.openai.request">
|
||||
& Telemetry.AttributesWithPrefix<ResponseAttributes, "gen_ai.openai.request">
|
||||
>
|
||||
|
||||
/**
|
||||
* All telemetry attributes which are part of the GenAI specification,
|
||||
* including the OpenAI-specific attributes.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type AllAttributes = Telemetry.AllAttributes & RequestAttributes & ResponseAttributes
|
||||
|
||||
/**
|
||||
* Telemetry attributes which are part of the GenAI specification and are
|
||||
* namespaced by `gen_ai.openai.request`.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface RequestAttributes {
|
||||
/**
|
||||
* The response format that is requested.
|
||||
*/
|
||||
readonly responseFormat?: (string & {}) | WellKnownResponseFormat | null | undefined
|
||||
/**
|
||||
* The service tier requested. May be a specific tier, `default`, or `auto`.
|
||||
*/
|
||||
readonly serviceTier?: (string & {}) | WellKnownServiceTier | null | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Telemetry attributes which are part of the GenAI specification and are
|
||||
* namespaced by `gen_ai.openai.response`.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface ResponseAttributes {
|
||||
/**
|
||||
* The service tier used for the response.
|
||||
*/
|
||||
readonly serviceTier?: string | null | undefined
|
||||
/**
|
||||
* A fingerprint to track any eventual change in the Generative AI
|
||||
* environment.
|
||||
*/
|
||||
readonly systemFingerprint?: string | null | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gen_ai.openai.request.response_format` attribute has a list of
|
||||
* well-known values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* If one of them applies, then the respective value **MUST** be used;
|
||||
* otherwise, a custom value **MAY** be used.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type WellKnownResponseFormat = "json_object" | "json_schema" | "text"
|
||||
|
||||
/**
|
||||
* The `gen_ai.openai.request.service_tier` attribute has a list of
|
||||
* well-known values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* If one of them applies, then the respective value **MUST** be used;
|
||||
* otherwise, a custom value **MAY** be used.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type WellKnownServiceTier = "auto" | "default"
|
||||
|
||||
/**
|
||||
* Options accepted by `addGenAIAnnotations`, combining standard GenAI telemetry
|
||||
* attributes with optional OpenAI-compatible request and response attributes.
|
||||
*
|
||||
* @category options
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenAiTelemetryAttributeOptions = Telemetry.GenAITelemetryAttributeOptions & {
|
||||
openai?: {
|
||||
request?: RequestAttributes | undefined
|
||||
response?: ResponseAttributes | undefined
|
||||
} | undefined
|
||||
}
|
||||
|
||||
const addOpenAiRequestAttributes = Telemetry.addSpanAttributes("gen_ai.openai.request", String.camelToSnake)<
|
||||
RequestAttributes
|
||||
>
|
||||
const addOpenAiResponseAttributes = Telemetry.addSpanAttributes("gen_ai.openai.response", String.camelToSnake)<
|
||||
ResponseAttributes
|
||||
>
|
||||
|
||||
/**
|
||||
* Applies the specified OpenAI GenAI telemetry attributes to the provided
|
||||
* `Span`.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to annotate an OpenAI-compatible model span with standard GenAI telemetry
|
||||
* attributes and OpenAI-specific request or response metadata.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Standard GenAI attributes are applied first. When OpenAI request or response
|
||||
* metadata is present, it is written under `gen_ai.openai.request.*` and
|
||||
* `gen_ai.openai.response.*` attributes.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* Mutates the supplied `Span` in place.
|
||||
*
|
||||
* @category tracing
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const addGenAIAnnotations: {
|
||||
(options: OpenAiTelemetryAttributeOptions): (span: Span) => void
|
||||
(span: Span, options: OpenAiTelemetryAttributeOptions): void
|
||||
} = dual(2, (span: Span, options: OpenAiTelemetryAttributeOptions) => {
|
||||
Telemetry.addGenAIAnnotations(span, options)
|
||||
if (options.openai != null) {
|
||||
if (options.openai.request != null) {
|
||||
addOpenAiRequestAttributes(span, options.openai.request)
|
||||
}
|
||||
if (options.openai.response != null) {
|
||||
addOpenAiResponseAttributes(span, options.openai.response)
|
||||
}
|
||||
}
|
||||
})
|
||||
35
repos/effect/packages/ai/openai-compat/src/index.ts
Normal file
35
repos/effect/packages/ai/openai-compat/src/index.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
// @barrel: Auto-generated exports. Do not edit manually.
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiClient from "./OpenAiClient.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiConfig from "./OpenAiConfig.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiEmbeddingModel from "./OpenAiEmbeddingModel.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiError from "./OpenAiError.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiLanguageModel from "./OpenAiLanguageModel.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiTelemetry from "./OpenAiTelemetry.ts"
|
||||
327
repos/effect/packages/ai/openai-compat/src/internal/errors.ts
Normal file
327
repos/effect/packages/ai/openai-compat/src/internal/errors.ts
Normal file
@@ -0,0 +1,327 @@
|
||||
import * as Arr from "effect/Array"
|
||||
import * as Duration from "effect/Duration"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import * as Number from "effect/Number"
|
||||
import * as Option from "effect/Option"
|
||||
import * as Redactable from "effect/Redactable"
|
||||
import * as Schema from "effect/Schema"
|
||||
import * as SchemaTransformation from "effect/SchemaTransformation"
|
||||
import * as String from "effect/String"
|
||||
import * as AiError from "effect/unstable/ai/AiError"
|
||||
import type * as Response from "effect/unstable/ai/Response"
|
||||
import type * as HttpClientError from "effect/unstable/http/HttpClientError"
|
||||
import type * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
||||
import type * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
|
||||
import type { OpenAiErrorMetadata } from "../OpenAiError.ts"
|
||||
|
||||
/** @internal */
|
||||
export const OpenAiErrorBody = Schema.Struct({
|
||||
error: Schema.Struct({
|
||||
message: Schema.String,
|
||||
type: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
status: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
param: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
code: Schema.optional(Schema.NullOr(Schema.Union([Schema.String, Schema.Number])))
|
||||
})
|
||||
})
|
||||
const OpenAiErrorBodyJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Union([
|
||||
OpenAiErrorBody,
|
||||
Schema.NonEmptyArray(OpenAiErrorBody).pipe(
|
||||
Schema.decodeTo(
|
||||
Schema.toType(OpenAiErrorBody),
|
||||
SchemaTransformation.transform({
|
||||
decode: Arr.headNonEmpty,
|
||||
encode: (item) => [item]
|
||||
})
|
||||
)
|
||||
)
|
||||
])))
|
||||
|
||||
/** @internal */
|
||||
export const mapSchemaError = dual<
|
||||
(method: string) => (error: Schema.SchemaError) => AiError.AiError,
|
||||
(error: Schema.SchemaError, method: string) => AiError.AiError
|
||||
>(2, (error, method) =>
|
||||
AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: AiError.InvalidOutputError.fromSchemaError(error)
|
||||
}))
|
||||
|
||||
/** @internal */
|
||||
export const mapHttpClientError = dual<
|
||||
(method: string) => (error: HttpClientError.HttpClientError) => Effect.Effect<never, AiError.AiError>,
|
||||
(error: HttpClientError.HttpClientError, method: string) => Effect.Effect<never, AiError.AiError>
|
||||
>(2, (error, method) => {
|
||||
const reason = error.reason
|
||||
switch (reason._tag) {
|
||||
case "TransportError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "TransportError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "EncodeError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "EncodeError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "InvalidUrlError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "InvalidUrlError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "StatusCodeError": {
|
||||
return mapStatusCodeError(reason, method)
|
||||
}
|
||||
case "DecodeError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.InvalidOutputError({
|
||||
description: reason.description ?? "Failed to decode response"
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "EmptyBodyError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.InvalidOutputError({
|
||||
description: reason.description ?? "Response body was empty"
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
const mapStatusCodeError = Effect.fnUntraced(function*(
|
||||
error: HttpClientError.StatusCodeError,
|
||||
method: string
|
||||
) {
|
||||
const { request, response, description } = error
|
||||
const status = response.status
|
||||
const headers = response.headers as Record<string, string>
|
||||
const requestId = headers["x-request-id"]
|
||||
|
||||
let body = yield* response.text.pipe(
|
||||
Effect.catchCause(() => Effect.succeed(description?.startsWith("{") ? description : undefined))
|
||||
)
|
||||
const decoded = OpenAiErrorBodyJson(body)
|
||||
|
||||
const reason = mapStatusCodeToReason({
|
||||
status,
|
||||
headers,
|
||||
message: Option.isSome(decoded) ? decoded.value.error.message : undefined,
|
||||
http: buildHttpContext({ request, response, body }),
|
||||
metadata: {
|
||||
errorCode: Option.isSome(decoded) ? decoded.value.error.code?.toString() ?? null : null,
|
||||
errorType: decoded.pipe(
|
||||
Option.flatMapNullishOr((d) => d.error.type ?? d.error.status),
|
||||
Option.map(String.toLowerCase),
|
||||
Option.getOrNull
|
||||
),
|
||||
requestId: requestId ?? null
|
||||
}
|
||||
})
|
||||
|
||||
return yield* AiError.make({ module: "OpenAiClient", method, reason })
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
export const parseRateLimitHeaders = (headers: Record<string, string>) => {
|
||||
const retryAfterRaw = headers["retry-after"]
|
||||
let retryAfter: Duration.Duration | undefined
|
||||
if (retryAfterRaw !== undefined) {
|
||||
const parsed = Number.parse(retryAfterRaw)
|
||||
if (Option.isSome(parsed)) {
|
||||
retryAfter = Duration.seconds(parsed.value)
|
||||
}
|
||||
}
|
||||
const remainingRaw = headers["x-ratelimit-remaining-requests"]
|
||||
const remaining = remainingRaw !== undefined ? Option.getOrNull(Number.parse(remainingRaw)) : null
|
||||
return {
|
||||
retryAfter,
|
||||
limit: headers["x-ratelimit-limit-requests"] ?? null,
|
||||
remaining,
|
||||
resetRequests: headers["x-ratelimit-reset-requests"] ?? null,
|
||||
resetTokens: headers["x-ratelimit-reset-tokens"] ?? null
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const buildHttpRequestDetails = (
|
||||
request: HttpClientRequest.HttpClientRequest
|
||||
): typeof Response.HttpRequestDetails.Type => ({
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
urlParams: Array.from(request.urlParams),
|
||||
hash: Option.getOrUndefined(request.hash),
|
||||
headers: Redactable.redact(request.headers) as Record<string, string>
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
export const buildHttpContext = (params: {
|
||||
readonly request: HttpClientRequest.HttpClientRequest
|
||||
readonly response?: HttpClientResponse.HttpClientResponse
|
||||
readonly body?: string | undefined
|
||||
}): typeof AiError.HttpContext.Type => ({
|
||||
request: buildHttpRequestDetails(params.request),
|
||||
response: params.response !== undefined
|
||||
? {
|
||||
status: params.response.status,
|
||||
headers: Redactable.redact(params.response.headers) as Record<string, string>
|
||||
}
|
||||
: undefined,
|
||||
body: params.body
|
||||
})
|
||||
|
||||
const buildInvalidRequestDescription = (params: {
|
||||
readonly status: number
|
||||
readonly message: string | undefined
|
||||
readonly method: string
|
||||
readonly url: string
|
||||
readonly errorCode: string | null
|
||||
readonly errorType: string | null
|
||||
readonly requestId: string | null
|
||||
readonly body: string | undefined
|
||||
}): string => {
|
||||
const parts: Array<string> = []
|
||||
|
||||
if (params.message) {
|
||||
parts.push(params.message)
|
||||
} else {
|
||||
parts.push(`HTTP ${params.status}`)
|
||||
}
|
||||
|
||||
parts.push(`(${params.method} ${params.url})`)
|
||||
|
||||
if (params.errorCode) {
|
||||
parts.push(`[code: ${params.errorCode}]`)
|
||||
} else if (params.errorType) {
|
||||
parts.push(`[type: ${params.errorType}]`)
|
||||
}
|
||||
|
||||
if (params.requestId) {
|
||||
parts.push(`[requestId: ${params.requestId}]`)
|
||||
}
|
||||
|
||||
if (!params.message && params.body) {
|
||||
const truncated = params.body.length > 200
|
||||
? params.body.slice(0, 200) + "..."
|
||||
: params.body
|
||||
parts.push(`Response: ${truncated}`)
|
||||
}
|
||||
|
||||
return parts.join(" ")
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const mapStatusCodeToReason = ({ status, headers, message, metadata, http }: {
|
||||
readonly status: number
|
||||
readonly headers: Record<string, string>
|
||||
readonly message: string | undefined
|
||||
readonly metadata: OpenAiErrorMetadata
|
||||
readonly http: typeof AiError.HttpContext.Type
|
||||
}): AiError.AiErrorReason => {
|
||||
const invalidRequestDescription = buildInvalidRequestDescription({
|
||||
status,
|
||||
message,
|
||||
method: http.request.method,
|
||||
url: http.request.url,
|
||||
errorCode: metadata.errorCode,
|
||||
errorType: metadata.errorType,
|
||||
requestId: metadata.requestId,
|
||||
body: http.body
|
||||
})
|
||||
|
||||
switch (status) {
|
||||
case 400:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { openai: metadata },
|
||||
http
|
||||
})
|
||||
case 401:
|
||||
return new AiError.AuthenticationError({
|
||||
kind: "InvalidKey",
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
case 403:
|
||||
return new AiError.AuthenticationError({
|
||||
kind: "InsufficientPermissions",
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
case 404:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { openai: metadata },
|
||||
http
|
||||
})
|
||||
case 409:
|
||||
case 422:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { openai: metadata },
|
||||
http
|
||||
})
|
||||
case 429: {
|
||||
if (
|
||||
metadata.errorCode === "insufficient_quota" ||
|
||||
metadata.errorType === "insufficient_quota" ||
|
||||
metadata.errorType?.includes("quota") ||
|
||||
metadata.errorType?.includes("exhausted")
|
||||
) {
|
||||
return new AiError.QuotaExhaustedError({
|
||||
metadata: { openai: metadata },
|
||||
http
|
||||
})
|
||||
}
|
||||
const { retryAfter, ...rateLimitMetadata } = parseRateLimitHeaders(headers)
|
||||
return new AiError.RateLimitError({
|
||||
retryAfter,
|
||||
metadata: {
|
||||
openai: {
|
||||
...metadata,
|
||||
...rateLimitMetadata
|
||||
}
|
||||
},
|
||||
http
|
||||
})
|
||||
}
|
||||
default:
|
||||
if (status >= 500) {
|
||||
return new AiError.InternalProviderError({
|
||||
description: message ?? "Server error",
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
}
|
||||
return new AiError.UnknownError({
|
||||
description: message,
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import type * as Response from "effect/unstable/ai/Response"
|
||||
|
||||
const finishReasonMap: Record<string, Response.FinishReason> = {
|
||||
content_filter: "content-filter",
|
||||
function_call: "tool-calls",
|
||||
length: "length",
|
||||
stop: "stop",
|
||||
tool_calls: "tool-calls"
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const resolveFinishReason = (
|
||||
finishReason: string | null | undefined,
|
||||
hasToolCalls: boolean
|
||||
): Response.FinishReason => {
|
||||
if (finishReason == null) {
|
||||
return hasToolCalls ? "tool-calls" : "stop"
|
||||
}
|
||||
const reason = finishReasonMap[finishReason]
|
||||
if (reason == null) {
|
||||
return hasToolCalls ? "tool-calls" : "unknown"
|
||||
}
|
||||
return reason
|
||||
}
|
||||
474
repos/effect/packages/ai/openai-compat/test/OpenAiClient.test.ts
Normal file
474
repos/effect/packages/ai/openai-compat/test/OpenAiClient.test.ts
Normal file
@@ -0,0 +1,474 @@
|
||||
import * as OpenAiClient from "@effect/ai-openai-compat/OpenAiClient"
|
||||
import { assert, describe, it } from "@effect/vitest"
|
||||
import { Effect, Layer, Redacted, Stream } from "effect"
|
||||
import { HttpClient, type HttpClientError, type HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
|
||||
|
||||
describe("OpenAiClient", () => {
|
||||
describe("request behavior", () => {
|
||||
it.effect("sets auth and OpenAI headers on /chat/completions requests", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("sk-test-key"),
|
||||
apiUrl: "https://compat.example.test/v1",
|
||||
organizationId: Redacted.make("org_123"),
|
||||
projectId: Redacted.make("proj_456")
|
||||
}).pipe(
|
||||
Effect.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, 200, makeChatCompletion()))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
yield* client.createResponse({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [{ role: "user", content: "hello" }]
|
||||
})
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
assert.isTrue(capturedRequest.url.endsWith("/chat/completions"))
|
||||
assert.isTrue(capturedRequest.url.startsWith("https://compat.example.test/v1"))
|
||||
assert.strictEqual(capturedRequest.headers["authorization"], "Bearer sk-test-key")
|
||||
assert.strictEqual(capturedRequest.headers["openai-organization"], "org_123")
|
||||
assert.strictEqual(capturedRequest.headers["openai-project"], "proj_456")
|
||||
|
||||
const body = yield* getRequestBody(capturedRequest)
|
||||
assert.strictEqual(body.messages[0]?.role, "user")
|
||||
assert.strictEqual(body.messages[0]?.content, "hello")
|
||||
}))
|
||||
|
||||
it.effect("passes custom chat-completions request properties through", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("sk-test-key")
|
||||
}).pipe(
|
||||
Effect.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, 200, makeChatCompletion()))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
yield* client.createResponse({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [{ role: "user", content: "hello" }],
|
||||
provider_feature: {
|
||||
enabled: true
|
||||
}
|
||||
})
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const body = yield* getRequestBody(capturedRequest)
|
||||
assert.deepStrictEqual(body.provider_feature, {
|
||||
enabled: true
|
||||
})
|
||||
}))
|
||||
|
||||
it.effect("uses /embeddings path and decodes permissive embedding payloads", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("sk-test-key"),
|
||||
apiUrl: "https://compat.example.test/v1"
|
||||
}).pipe(
|
||||
Effect.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, 200, {
|
||||
data: [{
|
||||
embedding: "YmFzZTY0LWRhdGE=",
|
||||
index: 0,
|
||||
object: "embedding",
|
||||
vendor_payload: { future_field: true }
|
||||
}],
|
||||
model: "my-custom-embedding-model",
|
||||
object: "list",
|
||||
usage: {
|
||||
prompt_tokens: 5,
|
||||
total_tokens: 5
|
||||
},
|
||||
unknown_top_level: true
|
||||
}))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
const embedding = yield* client.createEmbedding({
|
||||
model: "my-custom-embedding-model",
|
||||
input: "embed this"
|
||||
})
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
assert.isTrue(capturedRequest.url.endsWith("/embeddings"))
|
||||
assert.strictEqual(embedding.model, "my-custom-embedding-model")
|
||||
assert.strictEqual(embedding.data[0]?.index, 0)
|
||||
assert.strictEqual(typeof embedding.data[0]?.embedding, "string")
|
||||
}))
|
||||
|
||||
it.effect("sets stream=true for createResponseStream and returns chat chunks", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("sk-test-key")
|
||||
}).pipe(
|
||||
Effect.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(sseResponse(request, [
|
||||
{
|
||||
id: "chatcmpl_test_1",
|
||||
object: "chat.completion.chunk",
|
||||
model: "gpt-4o-mini",
|
||||
created: 1,
|
||||
future_provider_field: { accepted: true },
|
||||
choices: [{
|
||||
index: 0,
|
||||
delta: { content: "Hello" },
|
||||
finish_reason: null
|
||||
}]
|
||||
},
|
||||
{
|
||||
id: "chatcmpl_test_1",
|
||||
object: "chat.completion.chunk",
|
||||
model: "gpt-4o-mini",
|
||||
created: 1,
|
||||
usage: {
|
||||
prompt_tokens: 4,
|
||||
completion_tokens: 2,
|
||||
total_tokens: 6,
|
||||
prompt_tokens_details: { cached_tokens: 1 },
|
||||
completion_tokens_details: { reasoning_tokens: 1 }
|
||||
},
|
||||
choices: [{
|
||||
index: 0,
|
||||
delta: {},
|
||||
finish_reason: "stop"
|
||||
}]
|
||||
},
|
||||
"[DONE]"
|
||||
]))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
const eventsChunk = yield* client.createResponseStream({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [{ role: "user", content: "hello" }]
|
||||
}).pipe(
|
||||
Effect.flatMap(([_, stream]) => Stream.runCollect(stream))
|
||||
)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const body = yield* getRequestBody(capturedRequest)
|
||||
assert.strictEqual(body.stream, true)
|
||||
assert.strictEqual(body.stream_options.include_usage, true)
|
||||
assert.isTrue(capturedRequest.url.endsWith("/chat/completions"))
|
||||
|
||||
const events = globalThis.Array.from(eventsChunk)
|
||||
const firstEvent = events[0]
|
||||
const secondEvent = events[1]
|
||||
assert.isTrue(typeof firstEvent === "object")
|
||||
assert.isTrue(typeof secondEvent === "object")
|
||||
if (
|
||||
typeof firstEvent !== "object" || firstEvent === null || typeof secondEvent !== "object" ||
|
||||
secondEvent === null
|
||||
) {
|
||||
return
|
||||
}
|
||||
assert.strictEqual(firstEvent.id, "chatcmpl_test_1")
|
||||
assert.strictEqual(secondEvent.id, "chatcmpl_test_1")
|
||||
assert.strictEqual(events[2], "[DONE]")
|
||||
}))
|
||||
|
||||
it.effect("passes chat-completions tool_choice payload through unchanged", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("sk-test-key")
|
||||
}).pipe(
|
||||
Effect.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, 200, makeChatCompletion()))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
yield* client.createResponse({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [{ role: "user", content: "hello" }],
|
||||
tool_choice: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "TestTool"
|
||||
}
|
||||
},
|
||||
tools: [{
|
||||
type: "function",
|
||||
function: {
|
||||
name: "TestTool",
|
||||
parameters: {
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
input: { type: "string" }
|
||||
},
|
||||
required: ["input"]
|
||||
}
|
||||
}
|
||||
}]
|
||||
})
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const body = yield* getRequestBody(capturedRequest)
|
||||
assert.deepStrictEqual(body.tool_choice, { type: "function", function: { name: "TestTool" } })
|
||||
}))
|
||||
|
||||
it.effect("accepts assistant tool-call and tool result chat history", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("sk-test-key")
|
||||
}).pipe(
|
||||
Effect.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, 200, makeChatCompletion()))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
yield* client.createResponse({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [
|
||||
{
|
||||
role: "assistant",
|
||||
content: null,
|
||||
tool_calls: [{
|
||||
id: "patch_call_1",
|
||||
type: "function",
|
||||
function: {
|
||||
name: "apply_patch",
|
||||
arguments: JSON.stringify({
|
||||
call_id: "patch_call_1",
|
||||
operation: {
|
||||
type: "delete_file",
|
||||
path: "src/obsolete.ts"
|
||||
}
|
||||
})
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
role: "tool",
|
||||
tool_call_id: "patch_call_1",
|
||||
content: "deleted"
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const body = yield* getRequestBody(capturedRequest)
|
||||
const assistantMessages = body.messages.filter((message: any) => message.role === "assistant")
|
||||
const patchMessage = assistantMessages.find((message: any) =>
|
||||
message.tool_calls?.[0]?.function?.name === "apply_patch"
|
||||
)
|
||||
|
||||
assert.isDefined(patchMessage)
|
||||
|
||||
assert.strictEqual(patchMessage.tool_calls[0].id, "patch_call_1")
|
||||
assert.deepStrictEqual(JSON.parse(patchMessage.tool_calls[0].function.arguments), {
|
||||
call_id: "patch_call_1",
|
||||
operation: {
|
||||
type: "delete_file",
|
||||
path: "src/obsolete.ts"
|
||||
}
|
||||
})
|
||||
|
||||
const toolMessages = body.messages.filter((message: any) => message.role === "tool")
|
||||
const patchOutput = toolMessages.find((message: any) => message.tool_call_id === "patch_call_1")
|
||||
assert.isDefined(patchOutput)
|
||||
assert.strictEqual(patchOutput.content, "deleted")
|
||||
}))
|
||||
})
|
||||
|
||||
describe("error mapping", () => {
|
||||
it.effect("maps 400 responses to InvalidRequestError", () =>
|
||||
Effect.gen(function*() {
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("sk-test-key")
|
||||
}).pipe(
|
||||
Effect.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(jsonResponse(request, 400, {
|
||||
error: {
|
||||
message: "Bad request",
|
||||
type: "invalid_request_error",
|
||||
code: null
|
||||
}
|
||||
}))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const error = yield* client.createResponse({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [{ role: "user", content: "hello" }]
|
||||
}).pipe(Effect.flip)
|
||||
|
||||
assert.strictEqual(error._tag, "AiError")
|
||||
assert.strictEqual(error.method, "createResponse")
|
||||
assert.strictEqual(error.reason._tag, "InvalidRequestError")
|
||||
}))
|
||||
|
||||
it.effect("maps insufficient quota errors to QuotaExhaustedError", () =>
|
||||
Effect.gen(function*() {
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("sk-test-key")
|
||||
}).pipe(
|
||||
Effect.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(jsonResponse(request, 429, {
|
||||
error: {
|
||||
message: "You exceeded your current quota",
|
||||
type: "insufficient_quota",
|
||||
code: "insufficient_quota"
|
||||
}
|
||||
}))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const error = yield* client.createResponse({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [{ role: "user", content: "hello" }]
|
||||
}).pipe(Effect.flip)
|
||||
|
||||
assert.strictEqual(error._tag, "AiError")
|
||||
assert.strictEqual(error.method, "createResponse")
|
||||
assert.strictEqual(error.reason._tag, "QuotaExhaustedError")
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
const makeHttpClient = (
|
||||
handler: (
|
||||
request: HttpClientRequest.HttpClientRequest
|
||||
) => Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError.HttpClientError>
|
||||
) =>
|
||||
HttpClient.makeWith(
|
||||
Effect.fnUntraced(function*(requestEffect) {
|
||||
const request = yield* requestEffect
|
||||
return yield* handler(request)
|
||||
}),
|
||||
Effect.succeed as HttpClient.HttpClient.Preprocess<HttpClientError.HttpClientError, never>
|
||||
)
|
||||
|
||||
const makeChatCompletion = () => ({
|
||||
id: "chatcmpl_test_1",
|
||||
object: "chat.completion",
|
||||
model: "gpt-4o-mini",
|
||||
created: 1,
|
||||
choices: [{
|
||||
index: 0,
|
||||
finish_reason: "stop",
|
||||
message: {
|
||||
role: "assistant",
|
||||
content: "Hello"
|
||||
}
|
||||
}],
|
||||
usage: {
|
||||
prompt_tokens: 1,
|
||||
completion_tokens: 1,
|
||||
total_tokens: 2
|
||||
}
|
||||
})
|
||||
|
||||
const jsonResponse = (
|
||||
request: HttpClientRequest.HttpClientRequest,
|
||||
status: number,
|
||||
body: unknown
|
||||
): HttpClientResponse.HttpClientResponse =>
|
||||
HttpClientResponse.fromWeb(
|
||||
request,
|
||||
new Response(JSON.stringify(body), {
|
||||
status,
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const sseResponse = (
|
||||
request: HttpClientRequest.HttpClientRequest,
|
||||
events: ReadonlyArray<unknown>
|
||||
): HttpClientResponse.HttpClientResponse =>
|
||||
HttpClientResponse.fromWeb(
|
||||
request,
|
||||
new Response(toSseBody(events), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"content-type": "text/event-stream"
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const getRequestBody = (request: HttpClientRequest.HttpClientRequest) =>
|
||||
Effect.gen(function*() {
|
||||
const body = request.body
|
||||
if (body._tag === "Uint8Array") {
|
||||
const text = new TextDecoder().decode(body.body)
|
||||
return JSON.parse(text)
|
||||
}
|
||||
return yield* Effect.die(new Error("Expected Uint8Array body"))
|
||||
})
|
||||
|
||||
const toSseBody = (events: ReadonlyArray<unknown>): string =>
|
||||
events.map((event) => {
|
||||
if (typeof event === "string") {
|
||||
return `data: ${event}\n\n`
|
||||
}
|
||||
return `data: ${JSON.stringify(event)}\n\n`
|
||||
}).join("")
|
||||
@@ -0,0 +1,216 @@
|
||||
import { OpenAiClient, OpenAiEmbeddingModel } from "@effect/ai-openai-compat"
|
||||
import { assert, describe, it } from "@effect/vitest"
|
||||
import { Effect, Layer, Redacted } from "effect"
|
||||
import { EmbeddingModel } from "effect/unstable/ai"
|
||||
import { HttpClient, type HttpClientError, type HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
|
||||
|
||||
describe("OpenAiEmbeddingModel", () => {
|
||||
it.effect("model provides dimensions service", () =>
|
||||
Effect.gen(function*() {
|
||||
const dimensions = yield* EmbeddingModel.Dimensions
|
||||
assert.strictEqual(dimensions, 1536)
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.model("text-embedding-3-small", { dimensions: 1536 })),
|
||||
Effect.provideService(OpenAiClient.OpenAiClient, noopOpenAiClient)
|
||||
))
|
||||
|
||||
it.effect("reorders embeddings by provider index", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, {
|
||||
data: [
|
||||
{ index: 1, embedding: [20, 21] },
|
||||
{ index: 0, embedding: [10, 11] }
|
||||
],
|
||||
model: "text-embedding-3-small",
|
||||
usage: {
|
||||
prompt_tokens: 7,
|
||||
total_tokens: 7
|
||||
}
|
||||
}))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
const response = yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
return yield* model.embedMany(["first", "second"])
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({ model: "text-embedding-3-small" })),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.deepStrictEqual(response.embeddings.map((embedding) => embedding.vector), [[10, 11], [20, 21]])
|
||||
assert.strictEqual(response.usage.inputTokens, 7)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const requestBody = yield* getRequestBody(capturedRequest)
|
||||
assert.strictEqual(requestBody.model, "text-embedding-3-small")
|
||||
assert.deepStrictEqual(requestBody.input, ["first", "second"])
|
||||
}))
|
||||
|
||||
it.effect("merges config and applies withConfigOverride precedence", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, {
|
||||
data: [{ index: 0, embedding: [1, 2, 3] }],
|
||||
model: "override-model"
|
||||
}))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
yield* model.embed("hello")
|
||||
}).pipe(
|
||||
OpenAiEmbeddingModel.withConfigOverride({
|
||||
model: "override-model",
|
||||
dimensions: 1024,
|
||||
user: "request-user"
|
||||
}),
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({
|
||||
model: "base-model",
|
||||
config: {
|
||||
dimensions: 256,
|
||||
user: "provider-user"
|
||||
}
|
||||
})),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const requestBody = yield* getRequestBody(capturedRequest)
|
||||
assert.strictEqual(requestBody.model, "override-model")
|
||||
assert.strictEqual(requestBody.dimensions, 1024)
|
||||
assert.strictEqual(requestBody.user, "request-user")
|
||||
assert.deepStrictEqual(requestBody.input, ["hello"])
|
||||
}))
|
||||
|
||||
it.effect("fails with InvalidOutputError when provider returns duplicate indices", () =>
|
||||
Effect.gen(function*() {
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(jsonResponse(request, {
|
||||
data: [
|
||||
{ index: 0, embedding: [1] },
|
||||
{ index: 0, embedding: [2] }
|
||||
],
|
||||
model: "text-embedding-3-small",
|
||||
usage: {
|
||||
prompt_tokens: 2,
|
||||
total_tokens: 2
|
||||
}
|
||||
}))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const error = yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
return yield* model.embedMany(["a", "b"]).pipe(Effect.flip)
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({ model: "text-embedding-3-small" })),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.strictEqual(error._tag, "AiError")
|
||||
assert.strictEqual(error.reason._tag, "InvalidOutputError")
|
||||
}))
|
||||
|
||||
it.effect("fails with InvalidOutputError when provider returns non-vector embedding payload", () =>
|
||||
Effect.gen(function*() {
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(jsonResponse(request, {
|
||||
data: [{ index: 0, embedding: "AQID" }],
|
||||
model: "text-embedding-3-small",
|
||||
usage: {
|
||||
prompt_tokens: 1,
|
||||
total_tokens: 1
|
||||
}
|
||||
}))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const error = yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
return yield* model.embed("a").pipe(Effect.flip)
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({ model: "text-embedding-3-small" })),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.strictEqual(error._tag, "AiError")
|
||||
assert.strictEqual(error.reason._tag, "InvalidOutputError")
|
||||
}))
|
||||
})
|
||||
|
||||
const makeHttpClient = (
|
||||
handler: (
|
||||
request: HttpClientRequest.HttpClientRequest
|
||||
) => Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError.HttpClientError>
|
||||
) =>
|
||||
HttpClient.makeWith(
|
||||
Effect.fnUntraced(function*(requestEffect) {
|
||||
const request = yield* requestEffect
|
||||
return yield* handler(request)
|
||||
}),
|
||||
Effect.succeed as HttpClient.HttpClient.Preprocess<HttpClientError.HttpClientError, never>
|
||||
)
|
||||
|
||||
const jsonResponse = (
|
||||
request: HttpClientRequest.HttpClientRequest,
|
||||
body: unknown
|
||||
): HttpClientResponse.HttpClientResponse =>
|
||||
HttpClientResponse.fromWeb(
|
||||
request,
|
||||
new Response(JSON.stringify(body), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const getRequestBody = (request: HttpClientRequest.HttpClientRequest) =>
|
||||
Effect.gen(function*() {
|
||||
const body = request.body
|
||||
if (body._tag === "Uint8Array") {
|
||||
const text = new TextDecoder().decode(body.body)
|
||||
return JSON.parse(text)
|
||||
}
|
||||
return yield* Effect.die(new Error("Expected Uint8Array body"))
|
||||
})
|
||||
|
||||
const noopOpenAiClient: OpenAiClient.Service = {
|
||||
client: undefined as unknown as OpenAiClient.Service["client"],
|
||||
createResponse: () => Effect.die(new Error("noop")),
|
||||
createResponseStream: () => Effect.die(new Error("noop")),
|
||||
createEmbedding: () => Effect.die(new Error("noop"))
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
8
repos/effect/packages/ai/openai-compat/tsconfig.json
Normal file
8
repos/effect/packages/ai/openai-compat/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/tsconfig",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{ "path": "../../effect" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { OpenAiEmbeddingModel, OpenAiLanguageModel } from "@effect/ai-openai-compat"
|
||||
import { describe, expect, it } from "tstyche"
|
||||
|
||||
describe("OpenAI-compatible config", () => {
|
||||
it("accepts custom language model properties while preserving known property types", () => {
|
||||
expect(OpenAiLanguageModel.model).type.toBeCallableWith("model", {
|
||||
temperature: 0.5,
|
||||
vendor_setting: true
|
||||
})
|
||||
expect(OpenAiLanguageModel.model).type.not.toBeCallableWith("model", {
|
||||
temperature: "high"
|
||||
})
|
||||
})
|
||||
|
||||
it("accepts custom embedding properties while preserving known property types", () => {
|
||||
expect(OpenAiEmbeddingModel.model).type.toBeCallableWith("model", {
|
||||
dimensions: 3,
|
||||
user: "test-user",
|
||||
vendor_setting: true
|
||||
})
|
||||
expect(OpenAiEmbeddingModel.model).type.not.toBeCallableWith("model", {
|
||||
dimensions: 3,
|
||||
user: 1
|
||||
})
|
||||
})
|
||||
})
|
||||
6
repos/effect/packages/ai/openai-compat/vitest.config.ts
Normal file
6
repos/effect/packages/ai/openai-compat/vitest.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { mergeConfig, type ViteUserConfig } from "vitest/config"
|
||||
import shared from "../../../vitest.shared.ts"
|
||||
|
||||
const config: ViteUserConfig = {}
|
||||
|
||||
export default mergeConfig(shared, config)
|
||||
780
repos/effect/packages/ai/openai/CHANGELOG.md
Normal file
780
repos/effect/packages/ai/openai/CHANGELOG.md
Normal file
@@ -0,0 +1,780 @@
|
||||
# @effect/ai-openai
|
||||
|
||||
## 4.0.0-beta.99
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8ce4795`](https://github.com/Effect-TS/effect/commit/8ce4795ccbaebca4292757db568c005a992546a4), [`80b539f`](https://github.com/Effect-TS/effect/commit/80b539f8aba68f478c75c35c2b4140c4ffc4fada), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`e6e6dba`](https://github.com/Effect-TS/effect/commit/e6e6dba6e9d86e7c2ad27dcedf289db76a19697f), [`bfb203e`](https://github.com/Effect-TS/effect/commit/bfb203e95aa439f731acad37fc3a9a831a190f1c), [`2e9a34a`](https://github.com/Effect-TS/effect/commit/2e9a34ac2bece4f3a206160480c991e3841dc67a), [`55d4eb3`](https://github.com/Effect-TS/effect/commit/55d4eb34f2c64d54f6a25a305b5c5438ebd7934e), [`bddb010`](https://github.com/Effect-TS/effect/commit/bddb010eac3d4436cb094edbbee7460c5440c162), [`a328835`](https://github.com/Effect-TS/effect/commit/a328835e50d76bc96648a1c1550456e8c9f81210), [`5560d05`](https://github.com/Effect-TS/effect/commit/5560d05aa6abdd29466d9c3412cc5e648b0adbde), [`8f6e3ad`](https://github.com/Effect-TS/effect/commit/8f6e3adb185b16e8820b98c509b308086f7ff1af), [`46997fa`](https://github.com/Effect-TS/effect/commit/46997fa60401f5e3c93daa4b61f7df8e31caaab4), [`9e6e12d`](https://github.com/Effect-TS/effect/commit/9e6e12d75c118cd265496f2880490d1f33a5c8bf), [`3394b93`](https://github.com/Effect-TS/effect/commit/3394b93d97d6f24fc38670641d1490289ffca7f1), [`febeabc`](https://github.com/Effect-TS/effect/commit/febeabc3f7c31094da000a23edeaabfe2ab00a38), [`54161c9`](https://github.com/Effect-TS/effect/commit/54161c98f6f3569e0c31842f54e6a257f9421c4c), [`385f7a4`](https://github.com/Effect-TS/effect/commit/385f7a4ee4a7359928597ea56d151dbaf5eb5802), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`7543afe`](https://github.com/Effect-TS/effect/commit/7543afea6f4d97d1f1ad876224323838a48daadd), [`44b9cf3`](https://github.com/Effect-TS/effect/commit/44b9cf3d240d726997b4bbcd0ede48e074d3c456), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`0a8aa6a`](https://github.com/Effect-TS/effect/commit/0a8aa6acb90a72b91c24d17133c950e4cacd8abd), [`c8d9fcf`](https://github.com/Effect-TS/effect/commit/c8d9fcf7b030f7c474effbab2764ce7aee1c7209), [`9ca7f9a`](https://github.com/Effect-TS/effect/commit/9ca7f9a69363e4485645966d5a93b8f9597c5206), [`e7aca89`](https://github.com/Effect-TS/effect/commit/e7aca894bb32fbb785b5830837e6061c415a6015), [`55d7560`](https://github.com/Effect-TS/effect/commit/55d75609b8acf8a1b54c1b1c7fbbb65ec741aa3e), [`f809189`](https://github.com/Effect-TS/effect/commit/f809189ddf6b6011ba43a9901baaa734e315da2a), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`0ebdbe7`](https://github.com/Effect-TS/effect/commit/0ebdbe74463dc84385956d0b1e8c2b79ebab5400), [`7517d09`](https://github.com/Effect-TS/effect/commit/7517d09f12a0b183a81bd425962c4e280a68b05d), [`212493b`](https://github.com/Effect-TS/effect/commit/212493b9a1eb98cd1ef6959c707a2e5784a5ae91), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`80ea8cb`](https://github.com/Effect-TS/effect/commit/80ea8cb9222ca73f564c8267ab2f82966fea027a), [`8df19f4`](https://github.com/Effect-TS/effect/commit/8df19f4fe81d90cc33ace88b9a77e5534f82d604)]:
|
||||
- effect@4.0.0-beta.99
|
||||
|
||||
## 4.0.0-beta.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`989603b`](https://github.com/Effect-TS/effect-smol/commit/989603b60ab1197b64acf214208e0d370cd1f842), [`214c458`](https://github.com/Effect-TS/effect-smol/commit/214c458084bb6995d543cd37d1055f24be3d454e), [`a037273`](https://github.com/Effect-TS/effect-smol/commit/a0372736ac34796969b051bbba4717d7983f1ebe), [`97fdaa9`](https://github.com/Effect-TS/effect-smol/commit/97fdaa9c1f522c65e579365d314a07878e2b904f), [`b24d248`](https://github.com/Effect-TS/effect-smol/commit/b24d248c8df44222ce642087cde2bd859a2dc709), [`19c222c`](https://github.com/Effect-TS/effect-smol/commit/19c222cac2353a3d7b7733caecb00556fffe9a5c), [`eec85dd`](https://github.com/Effect-TS/effect-smol/commit/eec85ddba09ea326fd268ee33eeffd47e50d4671), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`8849052`](https://github.com/Effect-TS/effect-smol/commit/884905232d1e9a365e046d8dde27bf9c5707f57f), [`c15e16a`](https://github.com/Effect-TS/effect-smol/commit/c15e16ad130d1fbde25d912b7ac55995066cb35b), [`01d00a3`](https://github.com/Effect-TS/effect-smol/commit/01d00a3abfbf1f37996cdbe738ea5137c646cdd7), [`8bd4589`](https://github.com/Effect-TS/effect-smol/commit/8bd458975a1b3a8ed042eccf317b93d28ded91e7), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`6e08428`](https://github.com/Effect-TS/effect-smol/commit/6e08428d980501b856f846ad3f3f0e4ea46e7786), [`388dcf9`](https://github.com/Effect-TS/effect-smol/commit/388dcf953f65d317547f34d40e6443c5f264205f), [`2b7ce2b`](https://github.com/Effect-TS/effect-smol/commit/2b7ce2b513e7ec2a77822f1116dc6ffb6ba93f4e), [`87bea7e`](https://github.com/Effect-TS/effect-smol/commit/87bea7e16259246f3bcdf565446394751abca953), [`ce38dc3`](https://github.com/Effect-TS/effect-smol/commit/ce38dc33bda805a684432cca071f4dc3c6b9a1ba), [`a807cd1`](https://github.com/Effect-TS/effect-smol/commit/a807cd170341deca8a1cfb52c4222585f2431bb9), [`fd8a356`](https://github.com/Effect-TS/effect-smol/commit/fd8a356f06a8c9ce4e7e0a13fc4021c178ed31de), [`c2a5edc`](https://github.com/Effect-TS/effect-smol/commit/c2a5edc3abd31ad5bc123362bc1213e03e4095c3), [`5946da3`](https://github.com/Effect-TS/effect-smol/commit/5946da3804a1be5e752b05b96bd058cdba50a1bf), [`4ae0c5f`](https://github.com/Effect-TS/effect-smol/commit/4ae0c5ffcbe6c56ddfcb05c639112a079483539e), [`5b2a0bc`](https://github.com/Effect-TS/effect-smol/commit/5b2a0bceea3a28a33a58555210c90a415dc74a76), [`72ac585`](https://github.com/Effect-TS/effect-smol/commit/72ac585884befde6af9208da738699a93f1bae79), [`5e8c1b8`](https://github.com/Effect-TS/effect-smol/commit/5e8c1b82bfafa121311f987a49ab75395e3647a7), [`0f9c078`](https://github.com/Effect-TS/effect-smol/commit/0f9c07841b04183f485ee6e6458de73b290b09f5)]:
|
||||
- effect@4.0.0-beta.98
|
||||
|
||||
## 4.0.0-beta.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.97
|
||||
|
||||
## 4.0.0-beta.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1503f45`](https://github.com/Effect-TS/effect-smol/commit/1503f45cb5bb2a74f4705252ec505a1f0ade7e62), [`57fe793`](https://github.com/Effect-TS/effect-smol/commit/57fe79316ffbc380b30626a168981fb26ae97459), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`97f29df`](https://github.com/Effect-TS/effect-smol/commit/97f29df457f7ffd07cfb4b379315c12c086af805)]:
|
||||
- effect@4.0.0-beta.96
|
||||
|
||||
## 4.0.0-beta.95
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a482442`](https://github.com/Effect-TS/effect-smol/commit/a482442abdeb490e9652b854ec3495e4aa7273e7), [`fbefa85`](https://github.com/Effect-TS/effect-smol/commit/fbefa850fab2f0a302c20614496aeaaa2a8b5590), [`0b4a32f`](https://github.com/Effect-TS/effect-smol/commit/0b4a32f4260f0d8500942a133001b0d349328102), [`18a49e1`](https://github.com/Effect-TS/effect-smol/commit/18a49e1786679456258002ff9397faf02f678c2d), [`266cb90`](https://github.com/Effect-TS/effect-smol/commit/266cb90bb2c17aabc40563c32db334f09ba3d74b), [`912f095`](https://github.com/Effect-TS/effect-smol/commit/912f095a34572bbd3cedf6edb27878443e3e4a95), [`a6718f9`](https://github.com/Effect-TS/effect-smol/commit/a6718f9e00a15ca903b0732da46116cbf3d6aca7), [`bef5154`](https://github.com/Effect-TS/effect-smol/commit/bef51540a243aa2f872a00c01d0cd58b7a769baa), [`18e0564`](https://github.com/Effect-TS/effect-smol/commit/18e0564bd0f8ebbdfcaf1e2c21529948e9e4a81d), [`fb50f14`](https://github.com/Effect-TS/effect-smol/commit/fb50f14fc3657c1973785aa5b72ecf0b0d28e0b2)]:
|
||||
- effect@4.0.0-beta.95
|
||||
|
||||
## 4.0.0-beta.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`95a0e9b`](https://github.com/Effect-TS/effect-smol/commit/95a0e9bb62797af0e81c9998773405f248f218c5), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63), [`f11ce73`](https://github.com/Effect-TS/effect-smol/commit/f11ce73af60823754dc24194f4ffc561b9ea1c2d), [`ff30b6e`](https://github.com/Effect-TS/effect-smol/commit/ff30b6e7c2c63ffc56a4c5818d6d86b01b5ad528), [`1caab3c`](https://github.com/Effect-TS/effect-smol/commit/1caab3cc30f626efbf15e59d74f539a487e5c85c), [`aa80c47`](https://github.com/Effect-TS/effect-smol/commit/aa80c4775a04db87553e5568764cab7e32a72814), [`c2ae4fc`](https://github.com/Effect-TS/effect-smol/commit/c2ae4fce2f03a4cd1861c2b1179da7df656e662d), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63)]:
|
||||
- effect@4.0.0-beta.94
|
||||
|
||||
## 4.0.0-beta.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`00652fe`](https://github.com/Effect-TS/effect-smol/commit/00652fe95c18f87208e91343eb8bf218faa2f677), [`6c58167`](https://github.com/Effect-TS/effect-smol/commit/6c5816746eaf91d2a3c7c899c5720809fa230ae3), [`2bc5415`](https://github.com/Effect-TS/effect-smol/commit/2bc541501a7ef89e542d7cb98e96beb53cd205cc), [`e11cccc`](https://github.com/Effect-TS/effect-smol/commit/e11cccc7d5fe631abccc7d6e3bd296938de0fa2e), [`ba7e77e`](https://github.com/Effect-TS/effect-smol/commit/ba7e77e046b8641a3a4e9750bb88ca4a1d063d3f), [`5713ee7`](https://github.com/Effect-TS/effect-smol/commit/5713ee7edbc3054efde407b2286bbfd45bbc6e1c)]:
|
||||
- effect@4.0.0-beta.93
|
||||
|
||||
## 4.0.0-beta.92
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`affdc13`](https://github.com/Effect-TS/effect-smol/commit/affdc139045cc325dce321a84a580fdc1b2da7b9)]:
|
||||
- effect@4.0.0-beta.92
|
||||
|
||||
## 4.0.0-beta.91
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b135b25`](https://github.com/Effect-TS/effect-smol/commit/b135b2517fca9e7839734ace3699a7dfa75b9075), [`aaa21a3`](https://github.com/Effect-TS/effect-smol/commit/aaa21a369a171c600db294f2a4f640583043e150), [`3475ee6`](https://github.com/Effect-TS/effect-smol/commit/3475ee6c2bda6b05c6d7a12ce30c8bb840b5b1a6)]:
|
||||
- effect@4.0.0-beta.91
|
||||
|
||||
## 4.0.0-beta.90
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d237fdf`](https://github.com/Effect-TS/effect-smol/commit/d237fdf726481f76eb52a6196e111b24122bc3d5)]:
|
||||
- effect@4.0.0-beta.90
|
||||
|
||||
## 4.0.0-beta.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b7d46ab`](https://github.com/Effect-TS/effect-smol/commit/b7d46ab7e1a29d8711817bab583c9febf48a0dad), [`7777e15`](https://github.com/Effect-TS/effect-smol/commit/7777e1540fd3680dd8346723cffec812b9384669), [`5376197`](https://github.com/Effect-TS/effect-smol/commit/5376197ca8e50358a41b1fd3cec27bd1ec680ec6)]:
|
||||
- effect@4.0.0-beta.89
|
||||
|
||||
## 4.0.0-beta.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`911f1b8`](https://github.com/Effect-TS/effect-smol/commit/911f1b84790ce42b3a70c95b33e6f6fd9e74de8b), [`8beeeea`](https://github.com/Effect-TS/effect-smol/commit/8beeeea52879d8613a39468848f01c3092bd54d4), [`c306fcf`](https://github.com/Effect-TS/effect-smol/commit/c306fcfeb1ef38455156932a1faf49292b1318da)]:
|
||||
- effect@4.0.0-beta.88
|
||||
|
||||
## 4.0.0-beta.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a0c1a4`](https://github.com/Effect-TS/effect-smol/commit/5a0c1a4faee5707b5cc35e646ff1ffdad70f1956), [`1eea2ea`](https://github.com/Effect-TS/effect-smol/commit/1eea2ea3795ba47316b82b1ac8d4612c0ba389ed)]:
|
||||
- effect@4.0.0-beta.87
|
||||
|
||||
## 4.0.0-beta.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0b5795a`](https://github.com/Effect-TS/effect-smol/commit/0b5795a0ab4395e8f15955d8d96f2303084bfc64), [`3e3a859`](https://github.com/Effect-TS/effect-smol/commit/3e3a859ec6351a9e0d31674aabbd48fcefabb12e), [`7dbec24`](https://github.com/Effect-TS/effect-smol/commit/7dbec240dbf3bca599a20c486632abce694ef5ab), [`d8c00a1`](https://github.com/Effect-TS/effect-smol/commit/d8c00a171ac7141e8adc08c332d1162d9a9d56fc), [`85b6317`](https://github.com/Effect-TS/effect-smol/commit/85b631701e935866f2762bd595237aa718370cd9), [`6d0fda0`](https://github.com/Effect-TS/effect-smol/commit/6d0fda0d0cbdfffc523c89c57dfdb1608f84fb12), [`108a933`](https://github.com/Effect-TS/effect-smol/commit/108a9335ff8571928197e5847a09c28ac83d6f46), [`7e1f455`](https://github.com/Effect-TS/effect-smol/commit/7e1f455fab5005d769b939c91e519d450f802cf9), [`46b3e79`](https://github.com/Effect-TS/effect-smol/commit/46b3e79944cfdae7901eb148135c85b7eb39834e)]:
|
||||
- effect@4.0.0-beta.86
|
||||
|
||||
## 4.0.0-beta.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`328d97c`](https://github.com/Effect-TS/effect-smol/commit/328d97cc53c0dcb89077a5623e35b095eaa59a8c), [`8441836`](https://github.com/Effect-TS/effect-smol/commit/8441836e6dde70e8ae2126be9cefe9b45798b134), [`074e436`](https://github.com/Effect-TS/effect-smol/commit/074e4361091289104cb0ab6959dc3b0ea7794a6a), [`c1dfd60`](https://github.com/Effect-TS/effect-smol/commit/c1dfd60663eb13a58916f3712d877499943b628a), [`2ba316b`](https://github.com/Effect-TS/effect-smol/commit/2ba316bd15fcbf1c50626500d44a2c9b3bec19f5), [`7ce7344`](https://github.com/Effect-TS/effect-smol/commit/7ce7344c41056c79e2ee19ee6a9346c0f1d227c1)]:
|
||||
- effect@4.0.0-beta.85
|
||||
|
||||
## 4.0.0-beta.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`87f52ba`](https://github.com/Effect-TS/effect-smol/commit/87f52ba16c4370ffa3f84bf8e53038e1419c284e), [`b8ee07f`](https://github.com/Effect-TS/effect-smol/commit/b8ee07ffda8903b5ec2e45a786ddcba59f128fda), [`867c0d7`](https://github.com/Effect-TS/effect-smol/commit/867c0d70a09079b040260d45a1e92ff04dbfbf2f), [`b93bc6c`](https://github.com/Effect-TS/effect-smol/commit/b93bc6c9cb27b909a41d094c97c4f9d25bbc6d6b), [`57d387f`](https://github.com/Effect-TS/effect-smol/commit/57d387f92c30ab63e15e3e641f0a903b65886610), [`bacca41`](https://github.com/Effect-TS/effect-smol/commit/bacca4141c2400effae1eabfdb36c89a459cf246), [`0f8ac79`](https://github.com/Effect-TS/effect-smol/commit/0f8ac7959d29ed68c68ce25aabd6bf0cb7e63ecc), [`25b4482`](https://github.com/Effect-TS/effect-smol/commit/25b448270c01317703f25107e1480d4cd0246d9a), [`9cf3a25`](https://github.com/Effect-TS/effect-smol/commit/9cf3a25c66b0c44a52be9829870c44517ea52db2), [`8def767`](https://github.com/Effect-TS/effect-smol/commit/8def7674b1787f91035298cda4d122937e87ef72)]:
|
||||
- effect@4.0.0-beta.84
|
||||
|
||||
## 4.0.0-beta.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1f2e8ce`](https://github.com/Effect-TS/effect-smol/commit/1f2e8ceef09e0a791c850ed2ade01f97089596f9)]:
|
||||
- effect@4.0.0-beta.83
|
||||
|
||||
## 4.0.0-beta.82
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`193690b`](https://github.com/Effect-TS/effect-smol/commit/193690b642ea802bbed40d663bd677251bbe9dc3)]:
|
||||
- effect@4.0.0-beta.82
|
||||
|
||||
## 4.0.0-beta.81
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`93cb4f8`](https://github.com/Effect-TS/effect-smol/commit/93cb4f8fbfb9e07cb9dc86ce6b155fd1f8167914), [`60341d9`](https://github.com/Effect-TS/effect-smol/commit/60341d9ca744d0473ce3fab621ca9bd225af3a39), [`1105ab5`](https://github.com/Effect-TS/effect-smol/commit/1105ab56cb724212f7ea7b431396ce82e8fd0484), [`4500fbf`](https://github.com/Effect-TS/effect-smol/commit/4500fbfe00763d8a72af6e5d6c5988e8bd4ade36)]:
|
||||
- effect@4.0.0-beta.81
|
||||
|
||||
## 4.0.0-beta.80
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d944330`](https://github.com/Effect-TS/effect-smol/commit/d94433090ee03f426d43e13b883abae4494e55e6), [`f48659f`](https://github.com/Effect-TS/effect-smol/commit/f48659fdcc84930ebc1e5b45b540c0f973389182), [`7652aaa`](https://github.com/Effect-TS/effect-smol/commit/7652aaa3bdbc39f241fe58b54b9a43b713e22e12), [`98630b7`](https://github.com/Effect-TS/effect-smol/commit/98630b7c8f679c352ba6796636c85688fa009d8d), [`90ae23c`](https://github.com/Effect-TS/effect-smol/commit/90ae23cf07284da5e1bcd9dffa882e85df7e617b)]:
|
||||
- effect@4.0.0-beta.80
|
||||
|
||||
## 4.0.0-beta.79
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b9704dc`](https://github.com/Effect-TS/effect-smol/commit/b9704dc9de9f1649ad502371014fe869b69a49a3), [`a207113`](https://github.com/Effect-TS/effect-smol/commit/a207113f66837bb54416926718a9a7d66774d079), [`5e9b9e2`](https://github.com/Effect-TS/effect-smol/commit/5e9b9e217b164ebfd4a002dd4380b3b1563200c3), [`7c128ae`](https://github.com/Effect-TS/effect-smol/commit/7c128aef458a1e2d224712e51c483c9badad1d44), [`0ada457`](https://github.com/Effect-TS/effect-smol/commit/0ada457c0513d8d908254ab77ebb7d29d2b523d6), [`d7cc5a2`](https://github.com/Effect-TS/effect-smol/commit/d7cc5a2bede3de10943aa0c6bdb4f26836a91efd), [`aad63be`](https://github.com/Effect-TS/effect-smol/commit/aad63becf65e0a6b076e94f8973be7bbe7fbd46f), [`09809f6`](https://github.com/Effect-TS/effect-smol/commit/09809f60f19ec98232f98b33e33e02ecb7e4fbd6), [`2fddda5`](https://github.com/Effect-TS/effect-smol/commit/2fddda5311929f46b61e503f0ade4fc749e8c77d), [`5f21768`](https://github.com/Effect-TS/effect-smol/commit/5f2176833399757c4500d8875b7f2fba0393de75), [`f27003e`](https://github.com/Effect-TS/effect-smol/commit/f27003e00524ff83f20dd9909f62b2f8795efe03)]:
|
||||
- effect@4.0.0-beta.79
|
||||
|
||||
## 4.0.0-beta.78
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7836b8e`](https://github.com/Effect-TS/effect-smol/commit/7836b8eb8bb0f3e04cdf554ee070caccf74f00c1), [`35d49a3`](https://github.com/Effect-TS/effect-smol/commit/35d49a3a09bdba6b513de87ddcead9e61a1042ba), [`4093258`](https://github.com/Effect-TS/effect-smol/commit/40932580e65bafab5f23c5f14b520cb411d0b2cd)]:
|
||||
- effect@4.0.0-beta.78
|
||||
|
||||
## 4.0.0-beta.77
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6e9a5ca`](https://github.com/Effect-TS/effect-smol/commit/6e9a5ca62a61156fd67b2518ad3ab14ac0d25f23), [`302f398`](https://github.com/Effect-TS/effect-smol/commit/302f3984ce206e35d86ddd99d3b72be144850a51)]:
|
||||
- effect@4.0.0-beta.77
|
||||
|
||||
## 4.0.0-beta.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`016108a`](https://github.com/Effect-TS/effect-smol/commit/016108a472af7048ddbbfd05f233e67529fafe12), [`95c03d2`](https://github.com/Effect-TS/effect-smol/commit/95c03d2c55930668c215b5a41c23cf7742fead84), [`07299a3`](https://github.com/Effect-TS/effect-smol/commit/07299a33c09fd52faa9810d30835a2622c752386)]:
|
||||
- effect@4.0.0-beta.76
|
||||
|
||||
## 4.0.0-beta.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2312](https://github.com/Effect-TS/effect-smol/pull/2312) [`ad4b535`](https://github.com/Effect-TS/effect-smol/commit/ad4b535e17f94ce35261829d5a3675f0a7808b4e) Thanks @gcanti! - Validate `Schema.StructWithRest` fixed fields against rest index signatures at the type level so schemas cannot be constructed with incompatible decoded, encoded, or make shapes. This keeps `StructWithRest` types sound and updates the generated OpenAI conversation-items request schema to keep accepting arbitrary additional fields under the stricter validation.
|
||||
|
||||
- Updated dependencies [[`81b187c`](https://github.com/Effect-TS/effect-smol/commit/81b187c17a0d8817b58232826939154010ae49d7), [`ad4b535`](https://github.com/Effect-TS/effect-smol/commit/ad4b535e17f94ce35261829d5a3675f0a7808b4e), [`a29c2e7`](https://github.com/Effect-TS/effect-smol/commit/a29c2e7e3570920156702671d6f3367cd0195f6c), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`ffea4ec`](https://github.com/Effect-TS/effect-smol/commit/ffea4ecf2925f6a4c9fd13079d47584cbf2bed00), [`4255c9b`](https://github.com/Effect-TS/effect-smol/commit/4255c9ba78bb98c7838fbe9dccdd8465e9da5427)]:
|
||||
- effect@4.0.0-beta.75
|
||||
|
||||
## 4.0.0-beta.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b1fc6a4`](https://github.com/Effect-TS/effect-smol/commit/b1fc6a4b4d0ca7fa9fd162799ae17c86f2f7ee8e)]:
|
||||
- effect@4.0.0-beta.74
|
||||
|
||||
## 4.0.0-beta.73
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`361ca30`](https://github.com/Effect-TS/effect-smol/commit/361ca30eb6e134feece547d6e00f82be4cb23f75), [`b9598c6`](https://github.com/Effect-TS/effect-smol/commit/b9598c6a209e75bfdb87ee3b024ecd1e3923ff6e)]:
|
||||
- effect@4.0.0-beta.73
|
||||
|
||||
## 4.0.0-beta.72
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2280](https://github.com/Effect-TS/effect-smol/pull/2280) [`fa07f9e`](https://github.com/Effect-TS/effect-smol/commit/fa07f9e7138bde3e9404aa91c22b41e273aba091) Thanks @tim-smart! - improve openai websocket error status
|
||||
|
||||
- Updated dependencies [[`73e67d1`](https://github.com/Effect-TS/effect-smol/commit/73e67d119a84d697773eaecb4865c6a71eb1a9cb), [`01d71ec`](https://github.com/Effect-TS/effect-smol/commit/01d71ec5a75f3c2747a8d3b1ad9701d1e27b7ce5), [`fcd707e`](https://github.com/Effect-TS/effect-smol/commit/fcd707e091a16e1b35343c901cc4052274e32239)]:
|
||||
- effect@4.0.0-beta.72
|
||||
|
||||
## 4.0.0-beta.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2279](https://github.com/Effect-TS/effect-smol/pull/2279) [`1fab4ac`](https://github.com/Effect-TS/effect-smol/commit/1fab4acc63818dece3a0e732b1a71843f0759f21) Thanks @tim-smart! - handle missing output array in openai responses
|
||||
|
||||
- Updated dependencies [[`d8ac76b`](https://github.com/Effect-TS/effect-smol/commit/d8ac76b5bad458c42cebe8a0c1b3843f955ac293), [`2c3c00a`](https://github.com/Effect-TS/effect-smol/commit/2c3c00af6faba7b7d422af26a7a2bbc35636d230), [`3751e7c`](https://github.com/Effect-TS/effect-smol/commit/3751e7cf353e7a54cd692c37401207d9afba1e63), [`fc5f25b`](https://github.com/Effect-TS/effect-smol/commit/fc5f25b03ada5fc2431987768a74d3d3e75ca485), [`7ccced4`](https://github.com/Effect-TS/effect-smol/commit/7ccced42867c14c013b01160b3d292f14c05bd04), [`a2e1fe5`](https://github.com/Effect-TS/effect-smol/commit/a2e1fe5835c98c8ee4393a091b1d11b75126e349), [`4a4a36b`](https://github.com/Effect-TS/effect-smol/commit/4a4a36b10e6e616cad07584a43908f6a7e07e618), [`d350292`](https://github.com/Effect-TS/effect-smol/commit/d3502922b4740fa9d745797cbc3775cb67839b6d), [`730afb6`](https://github.com/Effect-TS/effect-smol/commit/730afb66696adf9bd5a328cbca29df9c05968771), [`df1b008`](https://github.com/Effect-TS/effect-smol/commit/df1b008f370f414c2a67a7b8139ef747af8e5fba), [`6d469d5`](https://github.com/Effect-TS/effect-smol/commit/6d469d567a7c41d7e5343bdee21d45b07b0e8190)]:
|
||||
- effect@4.0.0-beta.71
|
||||
|
||||
## 4.0.0-beta.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2224](https://github.com/Effect-TS/effect-smol/pull/2224) [`74d8f37`](https://github.com/Effect-TS/effect-smol/commit/74d8f37a05ce755ff09cff48f992cb80ce9e4769) Thanks @aniravi24! - Fix `OpenAIFile` schema decode failure on responses where `expires_at` and `status_details` are returned as literal `null`. The OpenAI files endpoint returns `null` (not omitted) for these fields when no expiration / status detail applies (e.g. uploads with `purpose: "user_data"`), but the upstream OpenAPI spec marks them only as optional. Codegen patches widen both fields to allow `null`, which now decodes cleanly via `OpenAiClient.createFile`, `retrieveFile`, `listFiles`, and any other endpoint returning the `OpenAIFile` shape.
|
||||
|
||||
- Updated dependencies [[`af7782d`](https://github.com/Effect-TS/effect-smol/commit/af7782d3008d08b043f3a3f261516001514b2b4e), [`7212d70`](https://github.com/Effect-TS/effect-smol/commit/7212d701a3eee7b3553ff502e2c066126e52e839)]:
|
||||
- effect@4.0.0-beta.70
|
||||
|
||||
## 4.0.0-beta.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70ea04a`](https://github.com/Effect-TS/effect-smol/commit/70ea04aa96a2a7859d738d414e1f0e3ed081a27a), [`d0ea8b0`](https://github.com/Effect-TS/effect-smol/commit/d0ea8b03f7d73ae076c1db12666141e480d11178), [`a57674b`](https://github.com/Effect-TS/effect-smol/commit/a57674b64845e9e75a456cf907bfdcb858859118), [`59aa334`](https://github.com/Effect-TS/effect-smol/commit/59aa334fbd0a504dda3c36f6d2ef1be7449b4b8b), [`8f4208e`](https://github.com/Effect-TS/effect-smol/commit/8f4208ee83bc7bdaa6793b5429847b45aab72470)]:
|
||||
- effect@4.0.0-beta.69
|
||||
|
||||
## 4.0.0-beta.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af8267f`](https://github.com/Effect-TS/effect-smol/commit/af8267f2f3588c3fb611e9286f6f933f29ce1217), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`f136bb7`](https://github.com/Effect-TS/effect-smol/commit/f136bb763048cbc6b17edd26496dba3e2415b9fa), [`6f38f07`](https://github.com/Effect-TS/effect-smol/commit/6f38f07d5941a211b251383aaab0f4f55e8a6557), [`aec9c40`](https://github.com/Effect-TS/effect-smol/commit/aec9c401a53db227f18bf5e0c84db7130ad862d6)]:
|
||||
- effect@4.0.0-beta.68
|
||||
|
||||
## 4.0.0-beta.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a42ef66`](https://github.com/Effect-TS/effect-smol/commit/a42ef6632abbddfa820995ae310ccc84ae8d9b6f), [`35594f8`](https://github.com/Effect-TS/effect-smol/commit/35594f811cafe471acd490114b103a1f8392c8d8), [`8bddd62`](https://github.com/Effect-TS/effect-smol/commit/8bddd628cb623f9533d345082583ff51cead6836), [`4be4c8d`](https://github.com/Effect-TS/effect-smol/commit/4be4c8d60862aa963869ee2ed9ffa048ffac0527), [`0c9d3ab`](https://github.com/Effect-TS/effect-smol/commit/0c9d3ab43eb721a370ed8306260cbac218c27e87), [`b156acc`](https://github.com/Effect-TS/effect-smol/commit/b156accd2691b4a051f823affdece7c39923ce85), [`d16c034`](https://github.com/Effect-TS/effect-smol/commit/d16c03434ee3e6dcd3bfc82b65d99e881d89025b), [`b559d68`](https://github.com/Effect-TS/effect-smol/commit/b559d68845f848a10153395778f035682d399075), [`a3de5d9`](https://github.com/Effect-TS/effect-smol/commit/a3de5d9215e5cc4a62e2666efbd7c1bf595eb84f), [`7e6c12e`](https://github.com/Effect-TS/effect-smol/commit/7e6c12ec9b3a5945f6c26e272cc8f6390541ad3e), [`098167a`](https://github.com/Effect-TS/effect-smol/commit/098167a220fe07da6f14455818733ab1b269c9dd)]:
|
||||
- effect@4.0.0-beta.67
|
||||
|
||||
## 4.0.0-beta.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ca2498e`](https://github.com/Effect-TS/effect-smol/commit/ca2498e702ac2d83fb7187707b7eb069bdb261a2), [`cd7d1fb`](https://github.com/Effect-TS/effect-smol/commit/cd7d1fba7e2e2c5ac3ad64e1be433440a5bda436), [`19a7033`](https://github.com/Effect-TS/effect-smol/commit/19a703367ec817cffc41d152da9b594827408e2b), [`33d26b4`](https://github.com/Effect-TS/effect-smol/commit/33d26b4210b2e974f146a71e7eed962f8ce00900), [`856766b`](https://github.com/Effect-TS/effect-smol/commit/856766b2c506aaed6d2df1d63bf3a5b1b062e1d4), [`079c7df`](https://github.com/Effect-TS/effect-smol/commit/079c7df82559bb9ce10a86dffb85d25e6ce07dc3)]:
|
||||
- effect@4.0.0-beta.66
|
||||
|
||||
## 4.0.0-beta.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6f11454`](https://github.com/Effect-TS/effect-smol/commit/6f11454a9b6c3bd00f6b35fd7af14a2f2d63a0a2)]:
|
||||
- effect@4.0.0-beta.65
|
||||
|
||||
## 4.0.0-beta.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d4877a`](https://github.com/Effect-TS/effect-smol/commit/7d4877a1929cdb690280ea254326c04f2ec97ea5)]:
|
||||
- effect@4.0.0-beta.64
|
||||
|
||||
## 4.0.0-beta.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2133](https://github.com/Effect-TS/effect-smol/pull/2133) [`5be0aaa`](https://github.com/Effect-TS/effect-smol/commit/5be0aaad694c9eb943a710eb4f896bc4c3fcae99) Thanks @Zelys-DFKH! - Fix `OpenAiLanguageModel` leaking library-only config fields (`fileIdPrefixes`, `strictJsonSchema`) into request body, causing OpenAI 400 errors.
|
||||
|
||||
- Updated dependencies [[`7f927ff`](https://github.com/Effect-TS/effect-smol/commit/7f927ffb7a9801dcfc4096c29e369d13d65cd0ac), [`a696b3e`](https://github.com/Effect-TS/effect-smol/commit/a696b3e83a8504cdbe261a18c10a1cc0619ae102)]:
|
||||
- effect@4.0.0-beta.63
|
||||
|
||||
## 4.0.0-beta.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4ab4b90`](https://github.com/Effect-TS/effect-smol/commit/4ab4b9007dc27a52ffabc6fcb37c96eeec795bf7)]:
|
||||
- effect@4.0.0-beta.62
|
||||
|
||||
## 4.0.0-beta.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`50790af`](https://github.com/Effect-TS/effect-smol/commit/50790af9b190c38d10fb0723837d49b66432638f), [`71f7c3d`](https://github.com/Effect-TS/effect-smol/commit/71f7c3df997deda92c84146d569696dab3bd645c), [`aae8797`](https://github.com/Effect-TS/effect-smol/commit/aae8797b9cb383be0c182dd58d03d787c354238b)]:
|
||||
- effect@4.0.0-beta.61
|
||||
|
||||
## 4.0.0-beta.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f69d567`](https://github.com/Effect-TS/effect-smol/commit/f69d5675dcff9f4137295752baf066b7153fdc09), [`7909c95`](https://github.com/Effect-TS/effect-smol/commit/7909c954b8f6244a35a4b429f8dd0dff45dad620), [`bbb4dcc`](https://github.com/Effect-TS/effect-smol/commit/bbb4dcc6c406b83a416b4ad3541cc02037c420e4), [`7af2207`](https://github.com/Effect-TS/effect-smol/commit/7af2207901eabf3132c1b7010a69b3899c06fbbe), [`848b40a`](https://github.com/Effect-TS/effect-smol/commit/848b40a4bd4bf54a5098617d50c33c88eee8270a)]:
|
||||
- effect@4.0.0-beta.60
|
||||
|
||||
## 4.0.0-beta.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2101](https://github.com/Effect-TS/effect-smol/pull/2101) [`953edef`](https://github.com/Effect-TS/effect-smol/commit/953edef2e1ade369e530017d64391281ef22f28f) Thanks @tim-smart! - don't omit reasoning from openai config
|
||||
|
||||
- Updated dependencies [[`56837ea`](https://github.com/Effect-TS/effect-smol/commit/56837ea2a338395b35550641374e9e589bd8b71d)]:
|
||||
- effect@4.0.0-beta.59
|
||||
|
||||
## 4.0.0-beta.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`11993d4`](https://github.com/Effect-TS/effect-smol/commit/11993d4934c66f5dc611b8bbf553f01d501ef8f7), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec)]:
|
||||
- effect@4.0.0-beta.58
|
||||
|
||||
## 4.0.0-beta.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a971f5c`](https://github.com/Effect-TS/effect-smol/commit/a971f5cbd92dfe4274420bf0966595eb35531060), [`8e110c5`](https://github.com/Effect-TS/effect-smol/commit/8e110c5f02a429ccc43a91df8678e402138c0851)]:
|
||||
- effect@4.0.0-beta.57
|
||||
|
||||
## 4.0.0-beta.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1933](https://github.com/Effect-TS/effect-smol/pull/1933) [`c5a7327`](https://github.com/Effect-TS/effect-smol/commit/c5a732746690185b8bb7935d0cf26a5ef21658e4) Thanks @IMax153! - Accept both `in-memory` and `in_memory` for OpenAI `prompt_cache_retention` schema fields.
|
||||
|
||||
- [#1933](https://github.com/Effect-TS/effect-smol/pull/1933) [`c5a7327`](https://github.com/Effect-TS/effect-smol/commit/c5a732746690185b8bb7935d0cf26a5ef21658e4) Thanks @IMax153! - Fix OpenAI MCP tool call handling to keep the canonical `OpenAiMcp` tool name across response and stream paths, including approval flows.
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.56
|
||||
|
||||
## 4.0.0-beta.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42cc744`](https://github.com/Effect-TS/effect-smol/commit/42cc744570968deb365fb46d47b53d3277050c93), [`04855ce`](https://github.com/Effect-TS/effect-smol/commit/04855ceeca4d40c55a5750dd9893b691f8ea741a)]:
|
||||
- effect@4.0.0-beta.55
|
||||
|
||||
## 4.0.0-beta.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e4b74f9`](https://github.com/Effect-TS/effect-smol/commit/e4b74f9c01a0e9b6cd58416de4af3a26d51da7c8), [`4c72808`](https://github.com/Effect-TS/effect-smol/commit/4c728081851c66dacf889a816535671bc841ae96)]:
|
||||
- effect@4.0.0-beta.54
|
||||
|
||||
## 4.0.0-beta.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2060](https://github.com/Effect-TS/effect-smol/pull/2060) [`aef2b1c`](https://github.com/Effect-TS/effect-smol/commit/aef2b1c0130a61a430f116465e4c200c51bcd9e2) Thanks @tim-smart! - add back openai reasoning types
|
||||
|
||||
- Updated dependencies [[`0768509`](https://github.com/Effect-TS/effect-smol/commit/07685094e931af07d104165195826a535b55fa7e), [`476aede`](https://github.com/Effect-TS/effect-smol/commit/476aede69c6efa06b5781ca5eb3e3b128ca29141), [`4f79c54`](https://github.com/Effect-TS/effect-smol/commit/4f79c542e7b508c235ff485d862cc8b29a8260c5), [`4be6a7c`](https://github.com/Effect-TS/effect-smol/commit/4be6a7cf35dab2a01d652f56dd35f0358c5a7e88), [`88927eb`](https://github.com/Effect-TS/effect-smol/commit/88927ebb896162cdba103b36553280b58e0facac)]:
|
||||
- effect@4.0.0-beta.53
|
||||
|
||||
## 4.0.0-beta.52
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2059](https://github.com/Effect-TS/effect-smol/pull/2059) [`6f73f92`](https://github.com/Effect-TS/effect-smol/commit/6f73f92291733dc1e970e222e63aba865183a072) Thanks @tim-smart! - Add a new public `OpenAiSchema` module with minimal local schemas for responses, streaming SSE events (including unknown-event fallback), and embeddings.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2059](https://github.com/Effect-TS/effect-smol/pull/2059) [`6f73f92`](https://github.com/Effect-TS/effect-smol/commit/6f73f92291733dc1e970e222e63aba865183a072) Thanks @tim-smart! - Add a new `OpenAiClientGenerated` module that exposes the generated OpenAI client as a dedicated context service with `make`, `layer`, and `layerConfig` constructors. This provides a compatibility path for direct generated-client access while preserving existing auth, base URL, header, and `OpenAiConfig.transformClient` wiring.
|
||||
|
||||
- [#2059](https://github.com/Effect-TS/effect-smol/pull/2059) [`6f73f92`](https://github.com/Effect-TS/effect-smol/commit/6f73f92291733dc1e970e222e63aba865183a072) Thanks @tim-smart! - Refactor `OpenAiClient` to the handwritten minimal-schema path so `client` now exposes the configured `HttpClient`, `createResponse` / `createResponseStream` / `createEmbedding` use `OpenAiSchema` request-response types, and websocket mode no longer depends on generated-client internals.
|
||||
|
||||
Also migrate OpenAI language and embedding model request-response typing to `OpenAiSchema` and make embedding decoding explicitly reject non-vector (string/base64) payloads with `InvalidOutputError`.
|
||||
|
||||
- Updated dependencies [[`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`cf3a311`](https://github.com/Effect-TS/effect-smol/commit/cf3a311d863a8abb818840c3b80f847e621c43c1), [`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`131fdd5`](https://github.com/Effect-TS/effect-smol/commit/131fdd5b1f26531e265fe1a08f002002f47c276e)]:
|
||||
- effect@4.0.0-beta.52
|
||||
|
||||
## 4.0.0-beta.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`778d2af`](https://github.com/Effect-TS/effect-smol/commit/778d2afe9b5154bc1f9abae46d93ea7e54c87344), [`4e24dcf`](https://github.com/Effect-TS/effect-smol/commit/4e24dcf75037f65eebc1eb68623bc7cbf9d5512a), [`4b1c015`](https://github.com/Effect-TS/effect-smol/commit/4b1c0150e9bdb5559ed32d250deb66e17b4240c7), [`454f8ad`](https://github.com/Effect-TS/effect-smol/commit/454f8adad822929c3ef60f8280d0987226b049fd), [`6754a0c`](https://github.com/Effect-TS/effect-smol/commit/6754a0cd18626b06805a079cc5265525a5eb7d27), [`90f7fd5`](https://github.com/Effect-TS/effect-smol/commit/90f7fd5243871b30980964135db4512b8119fa82), [`d7e1519`](https://github.com/Effect-TS/effect-smol/commit/d7e151974934201fd93fa4c8a1192ee9a5d965a0), [`72a8122`](https://github.com/Effect-TS/effect-smol/commit/72a81228e09782bae512f7d041bbfbc78bc668d0)]:
|
||||
- effect@4.0.0-beta.51
|
||||
|
||||
## 4.0.0-beta.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`07be594`](https://github.com/Effect-TS/effect-smol/commit/07be594825de60f8e1b2102d21dbb9b8fc63b414), [`ae02433`](https://github.com/Effect-TS/effect-smol/commit/ae02433103ce28f53a0c9bfb4a44e75773289b7b)]:
|
||||
- effect@4.0.0-beta.50
|
||||
|
||||
## 4.0.0-beta.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d87873`](https://github.com/Effect-TS/effect-smol/commit/7d8787340ff549370f6f2a88b612e9ebbfd6ba45), [`c2f6f90`](https://github.com/Effect-TS/effect-smol/commit/c2f6f901b200a6e515b4f02c93ce8005b7bbf1c5), [`216f13c`](https://github.com/Effect-TS/effect-smol/commit/216f13c1fce454a21b489bb915714a17e791a1ac)]:
|
||||
- effect@4.0.0-beta.49
|
||||
|
||||
## 4.0.0-beta.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4da56ec`](https://github.com/Effect-TS/effect-smol/commit/4da56ecff129b2da40137ffede23a73cc4e532d8), [`a5e6f77`](https://github.com/Effect-TS/effect-smol/commit/a5e6f774bab195cf50ecdc818240765f69a3bf4a), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070)]:
|
||||
- effect@4.0.0-beta.48
|
||||
|
||||
## 4.0.0-beta.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c584726`](https://github.com/Effect-TS/effect-smol/commit/c58472674e750e6938df955044eab88feda95e45), [`86a91a4`](https://github.com/Effect-TS/effect-smol/commit/86a91a4f0c59286dfa9393232d8020dea70ed4db), [`131caf9`](https://github.com/Effect-TS/effect-smol/commit/131caf9525151a0cb29803a8f1dffa0f4f479d12), [`c3615c8`](https://github.com/Effect-TS/effect-smol/commit/c3615c88379b9daf252df0db72c6ac5a20326406)]:
|
||||
- effect@4.0.0-beta.47
|
||||
|
||||
## 4.0.0-beta.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a30b9e`](https://github.com/Effect-TS/effect-smol/commit/3a30b9e2ec2bd8b8193e1aa139f6878a07e3f5ee)]:
|
||||
- effect@4.0.0-beta.46
|
||||
|
||||
## 4.0.0-beta.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c3af6d`](https://github.com/Effect-TS/effect-smol/commit/5c3af6d554f60be34f8fc21d598d9a298ae11beb)]:
|
||||
- effect@4.0.0-beta.45
|
||||
|
||||
## 4.0.0-beta.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1961](https://github.com/Effect-TS/effect-smol/pull/1961) [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970) Thanks @IMax153! - Rename the `ServiceMap` module to `Context` across exports, docs, and tests.
|
||||
|
||||
- Updated dependencies [[`e3f0621`](https://github.com/Effect-TS/effect-smol/commit/e3f0621454c3f5d11070d30619da27c9232cadc1), [`5b476ab`](https://github.com/Effect-TS/effect-smol/commit/5b476abc0bd7e9bb59135ea1bcad2e4936227ced), [`6b40e5a`](https://github.com/Effect-TS/effect-smol/commit/6b40e5a4a6bd2087c15a3d7374d25057fdedfa16), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`3b09fb3`](https://github.com/Effect-TS/effect-smol/commit/3b09fb31c40c2802b01f21c23bcdd1fe7fb0aa82), [`2370410`](https://github.com/Effect-TS/effect-smol/commit/237041062e5af4594d32db91597e34e70a632877), [`dabc272`](https://github.com/Effect-TS/effect-smol/commit/dabc272444a700eb629c07ba3e77671a841ca86e), [`08b63c3`](https://github.com/Effect-TS/effect-smol/commit/08b63c3df11bd35c9fd6090dbd166287fdc40664), [`dfff04c`](https://github.com/Effect-TS/effect-smol/commit/dfff04c4c2b1d352dfad83992a6dce1280c85cf9), [`9baed9e`](https://github.com/Effect-TS/effect-smol/commit/9baed9e17e84702e6e480fcef6f86404f9e24be9), [`7846792`](https://github.com/Effect-TS/effect-smol/commit/7846792adc7e1631d62d26d657bd7ba6139f369b), [`1556a24`](https://github.com/Effect-TS/effect-smol/commit/1556a247623636b7ebe438fb56d77f1a7bf957bb), [`7c11bc2`](https://github.com/Effect-TS/effect-smol/commit/7c11bc292ab8e46252fe8f7576fb685917bfb8b5), [`b5ea591`](https://github.com/Effect-TS/effect-smol/commit/b5ea5913ec1d45d0dd12a327b9dd966bda2f6d02), [`0853afa`](https://github.com/Effect-TS/effect-smol/commit/0853afaeb1633b2d7f8b66893bd01c3aa1ef2c22), [`ac845f3`](https://github.com/Effect-TS/effect-smol/commit/ac845f3ab40e0b8719576e7f9bc16ea2e0e02cd4), [`b80c462`](https://github.com/Effect-TS/effect-smol/commit/b80c46247480f47bb64fc480fab48a3f37bc8888), [`b3f535d`](https://github.com/Effect-TS/effect-smol/commit/b3f535d9a7ac13b5fb984c29f93561c57a081ff0), [`6fe2e93`](https://github.com/Effect-TS/effect-smol/commit/6fe2e93cc2f1b173ef89651d74b6a5d2626b3226), [`cda8004`](https://github.com/Effect-TS/effect-smol/commit/cda800451c1ffbdddfc08415aed7b2d91e0412ee), [`8335477`](https://github.com/Effect-TS/effect-smol/commit/8335477a8a936a24b5f3ee6203c1b268bd1bfc3c), [`8c836f9`](https://github.com/Effect-TS/effect-smol/commit/8c836f99ab1e896b9580a71d67773625baff2eaf), [`718ff6f`](https://github.com/Effect-TS/effect-smol/commit/718ff6fe3e3d3820cefd67d2bff1b2224fe08060), [`7eed84f`](https://github.com/Effect-TS/effect-smol/commit/7eed84fc33c5781a6fb11bf4fd189d424902ebd4), [`5df46fe`](https://github.com/Effect-TS/effect-smol/commit/5df46fe2f654d59ab5fc1578f4fc27fa40368ef9), [`82dd0f2`](https://github.com/Effect-TS/effect-smol/commit/82dd0f26c6442b07143762ef7bc33742d3978dd6), [`03ae41e`](https://github.com/Effect-TS/effect-smol/commit/03ae41e7304cffac9f18feea22b73468feafc43a), [`4677a0a`](https://github.com/Effect-TS/effect-smol/commit/4677a0a58f95eea38a211efcd3f345f237a9e44a), [`87e1fc8`](https://github.com/Effect-TS/effect-smol/commit/87e1fc8b67e4901d75f567b2fecc3841ab762cc4), [`c1af1b7`](https://github.com/Effect-TS/effect-smol/commit/c1af1b756f63291e9c0298cf95c98a6920a0c2a0), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`c8a877b`](https://github.com/Effect-TS/effect-smol/commit/c8a877b53e8f29616335719e5dd1c3992dddf780), [`7da961a`](https://github.com/Effect-TS/effect-smol/commit/7da961ae4916229d2246699a5d3b20e5b2dd2020)]:
|
||||
- effect@4.0.0-beta.44
|
||||
|
||||
## 4.0.0-beta.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1905](https://github.com/Effect-TS/effect-smol/pull/1905) [`fc1444d`](https://github.com/Effect-TS/effect-smol/commit/fc1444df6fb7223ed228650c5c927b1df54a8757) Thanks @tim-smart! - openai ws tweaks
|
||||
|
||||
- Updated dependencies [[`2ae33d0`](https://github.com/Effect-TS/effect-smol/commit/2ae33d050914915f7cb9c25ab0a020901e08d596), [`979811a`](https://github.com/Effect-TS/effect-smol/commit/979811a4c3f7ed21ed18ef560c49fb7f5569e80e), [`eb7dbef`](https://github.com/Effect-TS/effect-smol/commit/eb7dbeffa883386ad912815e62c0820cac1fdf8e), [`cf50eb4`](https://github.com/Effect-TS/effect-smol/commit/cf50eb49cb04706dae5185f624708117c413dee8), [`1d046fe`](https://github.com/Effect-TS/effect-smol/commit/1d046fe484560e23f3e22cb23eec6433f8f1fa02)]:
|
||||
- effect@4.0.0-beta.43
|
||||
|
||||
## 4.0.0-beta.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1859](https://github.com/Effect-TS/effect-smol/pull/1859) [`a4809db`](https://github.com/Effect-TS/effect-smol/commit/a4809db80f65601d37ccafc13d773e55909c4e98) Thanks @lloydrichards! - add dynamic tooling for openai and openai-compact language models
|
||||
|
||||
- [#1890](https://github.com/Effect-TS/effect-smol/pull/1890) [`4549175`](https://github.com/Effect-TS/effect-smol/commit/454917547e8c305707f0777f4efac7adaa924f00) Thanks @tim-smart! - reset openai websocket on error
|
||||
|
||||
- Updated dependencies [[`924e216`](https://github.com/Effect-TS/effect-smol/commit/924e216caa7e0bbf22e994a0cd2ce8b1f0f0b3ee), [`80e7f0c`](https://github.com/Effect-TS/effect-smol/commit/80e7f0cd9116e811e97b0ce30a77a8d1ecd072aa), [`f8328bf`](https://github.com/Effect-TS/effect-smol/commit/f8328bf0314da3dc7f31d314f94a5840e8d5217f), [`66d1c06`](https://github.com/Effect-TS/effect-smol/commit/66d1c06039079129707a230f7ad8c676439d7133), [`bee800b`](https://github.com/Effect-TS/effect-smol/commit/bee800bf285192a01bec72a7b7b51bc1159434e6), [`8930441`](https://github.com/Effect-TS/effect-smol/commit/8930441dee6f94c59c583d18d3ebd677cf1f2623)]:
|
||||
- effect@4.0.0-beta.42
|
||||
|
||||
## 4.0.0-beta.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1887](https://github.com/Effect-TS/effect-smol/pull/1887) [`f291344`](https://github.com/Effect-TS/effect-smol/commit/f2913443d99146a6b36d8437e50b94f7c03c1284) Thanks @tim-smart! - make defects a retryable network error in websocket mode
|
||||
|
||||
- Updated dependencies [[`36f5c21`](https://github.com/Effect-TS/effect-smol/commit/36f5c2174d31ab42c4598bf81f178f40d0802283), [`d8ce758`](https://github.com/Effect-TS/effect-smol/commit/d8ce758669d6297ae932ac3251d83e7b49b22f30), [`11aab4c`](https://github.com/Effect-TS/effect-smol/commit/11aab4c6d37d5691adafc2d33da1a631b28ce814), [`3bc1efb`](https://github.com/Effect-TS/effect-smol/commit/3bc1efb53dd75b4a40de46f1f80c7f8a7d50af86), [`70e724e`](https://github.com/Effect-TS/effect-smol/commit/70e724e604604d4be1061cd8da0d360494998c84), [`738dee7`](https://github.com/Effect-TS/effect-smol/commit/738dee7edfd70af82dc4d2376db3a8ebe603eb48), [`2111963`](https://github.com/Effect-TS/effect-smol/commit/2111963f19b4c28c800664a8fac9590c1321885f), [`198a553`](https://github.com/Effect-TS/effect-smol/commit/198a553d9ce45f6a00bfc4d65ed0640669602d95)]:
|
||||
- effect@4.0.0-beta.41
|
||||
|
||||
## 4.0.0-beta.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f62860f`](https://github.com/Effect-TS/effect-smol/commit/f62860f0e5e45978fabf7256ae620a13152a772a), [`973f281`](https://github.com/Effect-TS/effect-smol/commit/973f2812529aadc1cc54598b2039799fa72b80f8)]:
|
||||
- effect@4.0.0-beta.40
|
||||
|
||||
## 4.0.0-beta.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f91fd3d`](https://github.com/Effect-TS/effect-smol/commit/f91fd3db39fe5628439fd175fba201a65a1aa9d0), [`edaae9d`](https://github.com/Effect-TS/effect-smol/commit/edaae9d65f464f941d7eddd723cd33d324f4b071), [`b47db0b`](https://github.com/Effect-TS/effect-smol/commit/b47db0bd5802064b6a24b3ea27c6ff2e0520d513), [`82d3c8e`](https://github.com/Effect-TS/effect-smol/commit/82d3c8e4f3f49b00df611b25aa6f8f74ec21b59b), [`7c22b31`](https://github.com/Effect-TS/effect-smol/commit/7c22b315d198dcbf44ae8cdb8b37879e1c9e3996)]:
|
||||
- effect@4.0.0-beta.39
|
||||
|
||||
## 4.0.0-beta.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f4dbe5b`](https://github.com/Effect-TS/effect-smol/commit/f4dbe5b26b9c2d33fae024bf44afbdf8541792cd), [`a71a607`](https://github.com/Effect-TS/effect-smol/commit/a71a607c89fb6669a12a562c2c23be81dfbe1adb), [`66a0494`](https://github.com/Effect-TS/effect-smol/commit/66a0494ed75cd12f2721dcbb1d8a072e3d9e14b6), [`5ef7218`](https://github.com/Effect-TS/effect-smol/commit/5ef7218fc559d57301fe929b8a0cab4033f4f1fd), [`472d260`](https://github.com/Effect-TS/effect-smol/commit/472d260655bc311fba5c2c6e23bb77d8f7e36ba0)]:
|
||||
- effect@4.0.0-beta.38
|
||||
|
||||
## 4.0.0-beta.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f7a0b71`](https://github.com/Effect-TS/effect-smol/commit/f7a0b711da8fdd645597dee29cacc5619c6afcf2), [`1e223c3`](https://github.com/Effect-TS/effect-smol/commit/1e223c30ccf835dfbb21284535d78549efaeca80), [`53740f4`](https://github.com/Effect-TS/effect-smol/commit/53740f47aa76d114b7d535649fb50efc54a09608), [`8c7cf89`](https://github.com/Effect-TS/effect-smol/commit/8c7cf89f719e580cbce1bf6c24e6996f1992a0a6), [`b6b81a9`](https://github.com/Effect-TS/effect-smol/commit/b6b81a940eaafcbc792d25413d6c02c707de31b2), [`8f4c1f9`](https://github.com/Effect-TS/effect-smol/commit/8f4c1f97ed60f8810b0b327b50117ffb2d8260d4), [`f2479f9`](https://github.com/Effect-TS/effect-smol/commit/f2479f9d3113b1f012db17a3852b4e28f478cf9c), [`c919921`](https://github.com/Effect-TS/effect-smol/commit/c9199217fad65529421d2cf95ecfff41257090fd), [`7af90c2`](https://github.com/Effect-TS/effect-smol/commit/7af90c2e3c99038eafa39650433839523790e2fe), [`f3be185`](https://github.com/Effect-TS/effect-smol/commit/f3be18569e5ca57c25eabf00df3ca601ebab43c7)]:
|
||||
- effect@4.0.0-beta.37
|
||||
|
||||
## 4.0.0-beta.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1807](https://github.com/Effect-TS/effect-smol/pull/1807) [`1bbd4d9`](https://github.com/Effect-TS/effect-smol/commit/1bbd4d9d617e683a7f338ddd40d11f5838c722bd) Thanks @tim-smart! - Handle streamed OpenAI function calls from `response.function_call_arguments.done` so tool calls are emitted even when `response.output_item.done` is missing.
|
||||
|
||||
- [#1809](https://github.com/Effect-TS/effect-smol/pull/1809) [`126db2e`](https://github.com/Effect-TS/effect-smol/commit/126db2e38774c8ef4934321a70d39428ed4491ed) Thanks @tim-smart! - Fix OpenAI reasoning stream state handling so out-of-order reasoning summary events do not crash when prior reasoning item state is missing.
|
||||
|
||||
- Updated dependencies [[`60fcbcc`](https://github.com/Effect-TS/effect-smol/commit/60fcbcc43d09471e8f7e0969955d99dcefc5be81), [`0a60837`](https://github.com/Effect-TS/effect-smol/commit/0a6083713124440e630030375bab367e8d7df24e), [`49164d2`](https://github.com/Effect-TS/effect-smol/commit/49164d2c20a8d21b66514992c4a15d8521f6b36e), [`334b6e4`](https://github.com/Effect-TS/effect-smol/commit/334b6e4f76fe11941b516d61f57e268bc31f0ca6), [`5700695`](https://github.com/Effect-TS/effect-smol/commit/5700695f76ae6da6b94c9c87d4dd2b8054fb829b), [`f8f4456`](https://github.com/Effect-TS/effect-smol/commit/f8f445644f3aa7ec093cab7445198a62ba18a480), [`969d24f`](https://github.com/Effect-TS/effect-smol/commit/969d24fdfa48c4838e811983848d9cb4e9b3b12c), [`851eda0`](https://github.com/Effect-TS/effect-smol/commit/851eda0533946e39bacaaf581896320d7a4f3e8c), [`8059c1c`](https://github.com/Effect-TS/effect-smol/commit/8059c1c3eba9a90af7cd889ea261bcb8fff0c185), [`6f83295`](https://github.com/Effect-TS/effect-smol/commit/6f8329546a73eaddc7cb5e85ea8e37e73fbfb611), [`65f7f57`](https://github.com/Effect-TS/effect-smol/commit/65f7f5737575fed668987462c96d29a446707c32), [`e7fabd2`](https://github.com/Effect-TS/effect-smol/commit/e7fabd2265db690eae5cfc9b83730c84699aef61), [`89c3e98`](https://github.com/Effect-TS/effect-smol/commit/89c3e985401eb38f33a3ae21a94ad27de3c1d28b), [`53794ab`](https://github.com/Effect-TS/effect-smol/commit/53794ab7af30aa5c5004ecf53659fafbe4b10542)]:
|
||||
- effect@4.0.0-beta.36
|
||||
|
||||
## 4.0.0-beta.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1776](https://github.com/Effect-TS/effect-smol/pull/1776) [`f5e553d`](https://github.com/Effect-TS/effect-smol/commit/f5e553d133b8e0a303f6c82624d2fec4ab8043da) Thanks @tim-smart! - improve openai socket errors
|
||||
|
||||
- Updated dependencies [[`9252b43`](https://github.com/Effect-TS/effect-smol/commit/9252b43560f507709c2985abcf52a7837b23ddf8), [`7daf387`](https://github.com/Effect-TS/effect-smol/commit/7daf3870a656882a488a60f67881e6808c8f4d04), [`e1664a3`](https://github.com/Effect-TS/effect-smol/commit/e1664a38bc31ef4ceb4e9324c7226e1e99bf9c07), [`fdaa6e0`](https://github.com/Effect-TS/effect-smol/commit/fdaa6e0a41b6b6605438fa8557441792135380a2), [`19aa47e`](https://github.com/Effect-TS/effect-smol/commit/19aa47ef7b470e427620edca8970dd9cdd551216), [`c667dad`](https://github.com/Effect-TS/effect-smol/commit/c667dad07777b860e4764a3ba9a6cc41c236cd98), [`764d150`](https://github.com/Effect-TS/effect-smol/commit/764d1501bc5026b60fc8aef6cb02a5a87c762801), [`3c27098`](https://github.com/Effect-TS/effect-smol/commit/3c27098b5685a63db2c2eff654a250c94d3fcfa7)]:
|
||||
- effect@4.0.0-beta.35
|
||||
|
||||
## 4.0.0-beta.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1759](https://github.com/Effect-TS/effect-smol/pull/1759) [`8feecd2`](https://github.com/Effect-TS/effect-smol/commit/8feecd24158f254ca0571a1ddb554b560ed3177d) Thanks @tim-smart! - Ensure OpenAiSocket sends a `{"type":"response.cancel"}` websocket event when a response stream is interrupted.
|
||||
|
||||
- [#1764](https://github.com/Effect-TS/effect-smol/pull/1764) [`342fc4b`](https://github.com/Effect-TS/effect-smol/commit/342fc4b051739e32e7977159f26ff9541eda664f) Thanks @tim-smart! - Add unstable EmbeddingModel support across core and OpenAI providers.
|
||||
- Add the unstable EmbeddingModel module API surface in `effect`, including service, request, response, and provider types.
|
||||
- Implement the unstable EmbeddingModel runtime constructor in `effect`, with `RequestResolver` batching, `embed` / `embedMany` spans, provider error propagation, deterministic ordering, and empty-input `embedMany` fast-path behavior.
|
||||
- Add and align EmbeddingModel behavior tests in `effect` for embedding usage, batching, ordering, and error handling.
|
||||
- Add `OpenAiEmbeddingModel` in `@effect/ai-openai`, including model / make / layer constructors, config overrides, and provider output index validation with deterministic reordering.
|
||||
- Add OpenAI-compatible EmbeddingModel provider support in `@effect/ai-openai-compat`, including config overrides, layer constructors, and output index validation.
|
||||
|
||||
- [#1771](https://github.com/Effect-TS/effect-smol/pull/1771) [`00add69`](https://github.com/Effect-TS/effect-smol/commit/00add69b59551e9df34772eb927638b093f6d71e) Thanks @tim-smart! - Add `EmbeddingModel.ModelDimensions` and require dimensions in embedding provider `model` constructors.
|
||||
|
||||
- [#1765](https://github.com/Effect-TS/effect-smol/pull/1765) [`f4e2aba`](https://github.com/Effect-TS/effect-smol/commit/f4e2aba01b76d1e3059b297e3cc942284dfeafb2) Thanks @tim-smart! - retry incremental prompt on invalid request
|
||||
|
||||
- [#1760](https://github.com/Effect-TS/effect-smol/pull/1760) [`273f4c6`](https://github.com/Effect-TS/effect-smol/commit/273f4c6517f5adc4994734a46698c52015890d1a) Thanks @tim-smart! - handle openai ws error events
|
||||
|
||||
- Updated dependencies [[`f2f75ee`](https://github.com/Effect-TS/effect-smol/commit/f2f75ee564bce1cd95f5189c7bdeeed4f92dacb1), [`342fc4b`](https://github.com/Effect-TS/effect-smol/commit/342fc4b051739e32e7977159f26ff9541eda664f), [`5d704ee`](https://github.com/Effect-TS/effect-smol/commit/5d704ee10d20e8eb107e34bb8a21feb5aa4a7685), [`00add69`](https://github.com/Effect-TS/effect-smol/commit/00add69b59551e9df34772eb927638b093f6d71e), [`58217d3`](https://github.com/Effect-TS/effect-smol/commit/58217d318a7d716ccd707cce0f41573946939c28), [`f4e2aba`](https://github.com/Effect-TS/effect-smol/commit/f4e2aba01b76d1e3059b297e3cc942284dfeafb2), [`e3b44b6`](https://github.com/Effect-TS/effect-smol/commit/e3b44b6a2af9ee21dc5c1e928f0c20af857fa7a9), [`e1472b7`](https://github.com/Effect-TS/effect-smol/commit/e1472b7525c5d57a48bdec2353c3b742f7f916c0), [`7686320`](https://github.com/Effect-TS/effect-smol/commit/7686320cd123fa352b5c3d076fb18a3cac0a9bba)]:
|
||||
- effect@4.0.0-beta.34
|
||||
|
||||
## 4.0.0-beta.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1638](https://github.com/Effect-TS/effect-smol/pull/1638) [`e198fea`](https://github.com/Effect-TS/effect-smol/commit/e198fea76c89a36c6f05ea7b7d11d222cf5a240c) Thanks @tim-smart! - add OpenAiClient.withWebSocketMode
|
||||
|
||||
- Updated dependencies [[`571447d`](https://github.com/Effect-TS/effect-smol/commit/571447da67334449f8ae3d6ecb3d77ea4e0c4295)]:
|
||||
- effect@4.0.0-beta.33
|
||||
|
||||
## 4.0.0-beta.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf8fff8`](https://github.com/Effect-TS/effect-smol/commit/bf8fff8a5f54b6df74cb7bbb42346fe9ba52435a), [`1af3ef3`](https://github.com/Effect-TS/effect-smol/commit/1af3ef3e3ca7fd417d0fc15f8ca8fe207eba4f74), [`27fea0f`](https://github.com/Effect-TS/effect-smol/commit/27fea0f66910de5905f40fd63f8ddbb6f7ac5aba), [`2ad6c1b`](https://github.com/Effect-TS/effect-smol/commit/2ad6c1b2c85a3a0fe351e3d56636a75eb76b4b4e), [`398ac3e`](https://github.com/Effect-TS/effect-smol/commit/398ac3e01cb75efce0e4e2913d1450cf65866732), [`51fe22f`](https://github.com/Effect-TS/effect-smol/commit/51fe22f3266e417b6c541aaed4b75d246fac91e7), [`4605db6`](https://github.com/Effect-TS/effect-smol/commit/4605db69cfacddbdbf1525865ddfde135158090c), [`f4de1b0`](https://github.com/Effect-TS/effect-smol/commit/f4de1b087c998d0bad1d9468f70b7d16c13b9f6f), [`60214f2`](https://github.com/Effect-TS/effect-smol/commit/60214f2080b2aeb091f691140eb20acb741691c3), [`c4b8b0f`](https://github.com/Effect-TS/effect-smol/commit/c4b8b0ffa8efb47c4cd7578a8943d6868509373f), [`6d9393a`](https://github.com/Effect-TS/effect-smol/commit/6d9393a0770a18722d23340e77f15455de341245), [`6de4efe`](https://github.com/Effect-TS/effect-smol/commit/6de4efe463c783614ceb0c094d77a336a899cbe0), [`4f969d1`](https://github.com/Effect-TS/effect-smol/commit/4f969d1563ba755ffa116c8ae409bb3436bd881d), [`6cc67c8`](https://github.com/Effect-TS/effect-smol/commit/6cc67c855e054ee3f3ac3485dca5f7805e79e8fb), [`8531a22`](https://github.com/Effect-TS/effect-smol/commit/8531a22ffbb52e11a030b09f358cafbfdf5edff7), [`b226760`](https://github.com/Effect-TS/effect-smol/commit/b22676067617f15c00722a3a63fd7c2c172c3d45), [`47a51ab`](https://github.com/Effect-TS/effect-smol/commit/47a51aba0ecdf3ef478bfa28a498bca188399bd4), [`1521d02`](https://github.com/Effect-TS/effect-smol/commit/1521d02e1f19f1d795edaaf862c1a1031d9c755e)]:
|
||||
- effect@4.0.0-beta.32
|
||||
|
||||
## 4.0.0-beta.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6f23f0e`](https://github.com/Effect-TS/effect-smol/commit/6f23f0ed4cba573cd9395c2e582f582fe7271544), [`654aaec`](https://github.com/Effect-TS/effect-smol/commit/654aaec593305521b65dd042c204d761cc6e8c28), [`2958a42`](https://github.com/Effect-TS/effect-smol/commit/2958a42078966a8713a98f00485ab36484d5eccf), [`95d27a2`](https://github.com/Effect-TS/effect-smol/commit/95d27a239ed5147302605ab0b3147a056541b0c7), [`0fbaea8`](https://github.com/Effect-TS/effect-smol/commit/0fbaea8f9555a8044cec31a770394db613fc78e2), [`21d5d5e`](https://github.com/Effect-TS/effect-smol/commit/21d5d5e0439fd4d9bb6e508377215b1087555d45), [`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6e49959`](https://github.com/Effect-TS/effect-smol/commit/6e499590357a104c81779b3176cd3f84e4f91064), [`8f5805d`](https://github.com/Effect-TS/effect-smol/commit/8f5805dbdd0d1bc0ff0727cc398c8d80e544edee), [`990df2c`](https://github.com/Effect-TS/effect-smol/commit/990df2c3ceeb32e659acc10cc9485617f7b3c423)]:
|
||||
- effect@4.0.0-beta.31
|
||||
|
||||
## 4.0.0-beta.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1679](https://github.com/Effect-TS/effect-smol/pull/1679) [`d440fd4`](https://github.com/Effect-TS/effect-smol/commit/d440fd4e79f5943998249f5e67fb42505bd20228) Thanks @tim-smart! - Add support for OpenAI `keepalive` response stream events.
|
||||
|
||||
- Updated dependencies [[`c88e5b7`](https://github.com/Effect-TS/effect-smol/commit/c88e5b723ff09da4edaef6ce14d927ca01104a32), [`947d0e4`](https://github.com/Effect-TS/effect-smol/commit/947d0e4268ba5c4020ead380aa80812c7342408f), [`7517908`](https://github.com/Effect-TS/effect-smol/commit/75179085d159b88a1ab0bce70669d76dcf0d79a4), [`a49ecd5`](https://github.com/Effect-TS/effect-smol/commit/a49ecd5a183d7e7d33f47ff95e9d2dea5a12ead5), [`6993e33`](https://github.com/Effect-TS/effect-smol/commit/6993e3329122c834c20bacea72d8678232f4f103), [`514f2a2`](https://github.com/Effect-TS/effect-smol/commit/514f2a2ae54580fcacdbe2ea2196a83a852d0748), [`3214b47`](https://github.com/Effect-TS/effect-smol/commit/3214b47676de2d33fddc5fecfc2d226e6e83cc7b), [`95ec5ed`](https://github.com/Effect-TS/effect-smol/commit/95ec5ed345de77c893049e182d37a37cf164a268)]:
|
||||
- effect@4.0.0-beta.30
|
||||
|
||||
## 4.0.0-beta.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9d93adb`](https://github.com/Effect-TS/effect-smol/commit/9d93adb1c1795d1978391b30d7d2972c88052662), [`b52721c`](https://github.com/Effect-TS/effect-smol/commit/b52721cf0d11a567722b060c8536e3bdd4161f07), [`a891c7b`](https://github.com/Effect-TS/effect-smol/commit/a891c7b12f415b2287613dd4b91a09dfd38ef30d), [`ef26cdf`](https://github.com/Effect-TS/effect-smol/commit/ef26cdfb65d9955fc7e161629191930c2cc2c63f), [`82fd3ed`](https://github.com/Effect-TS/effect-smol/commit/82fd3ed922063ee5a34f96f3993c15c7515e4f67)]:
|
||||
- effect@4.0.0-beta.29
|
||||
|
||||
## 4.0.0-beta.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ff533f2`](https://github.com/Effect-TS/effect-smol/commit/ff533f203cd06302ad08032a27e01269b4a2d4c6), [`dc803ee`](https://github.com/Effect-TS/effect-smol/commit/dc803ee52ebd3e9f931118f0dfcb804542847556), [`d660b1c`](https://github.com/Effect-TS/effect-smol/commit/d660b1c99cb93d4f79715e91c7a4486801c0eefa), [`93a05e3`](https://github.com/Effect-TS/effect-smol/commit/93a05e3eaa624058b162aedd66aad70102837270), [`2a65cf6`](https://github.com/Effect-TS/effect-smol/commit/2a65cf6fd81ef63d944e6fb51f058d439bf4a834), [`a561a40`](https://github.com/Effect-TS/effect-smol/commit/a561a40cc41c548c2cf3153aca065ee92ee8aa57), [`29cd24d`](https://github.com/Effect-TS/effect-smol/commit/29cd24d1fe78480a72eeb38a90281ffddc0530bc), [`662a8e6`](https://github.com/Effect-TS/effect-smol/commit/662a8e6857dac64a7cd13bd8df4b0674654622f8), [`d2b52ba`](https://github.com/Effect-TS/effect-smol/commit/d2b52bae5b9336cf59729fbdcc4d7f09512b0cbf), [`407c3b4`](https://github.com/Effect-TS/effect-smol/commit/407c3b43a5d1414558e0e33b6f1fc0e6a6d489cc), [`42bc7ce`](https://github.com/Effect-TS/effect-smol/commit/42bc7ce5480f6f2953c39f8cb5c850d61df6f5a2), [`e741322`](https://github.com/Effect-TS/effect-smol/commit/e74132226cbfee24234311c7c1c13e6b7391384e), [`5c75fa8`](https://github.com/Effect-TS/effect-smol/commit/5c75fa8fb71163bc4c035ba1a215574dfd4badfc), [`747177b`](https://github.com/Effect-TS/effect-smol/commit/747177b0602f12d4461a843e953dfdffbeb0a429), [`326cd48`](https://github.com/Effect-TS/effect-smol/commit/326cd4828bce573fe985f35152155464bf4c5a70), [`627e922`](https://github.com/Effect-TS/effect-smol/commit/627e922b8d1e9521eae5e1caa5d667ad00b1619a), [`662287e`](https://github.com/Effect-TS/effect-smol/commit/662287e9abc76c941ccc2ee330aa07904d571341)]:
|
||||
- effect@4.0.0-beta.28
|
||||
|
||||
## 4.0.0-beta.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`903a839`](https://github.com/Effect-TS/effect-smol/commit/903a839e94239e6ec4568315af28e405bcad95f4), [`91a0168`](https://github.com/Effect-TS/effect-smol/commit/91a016836680a6669308ecf464d3584bcc4ae1b7), [`c890f9a`](https://github.com/Effect-TS/effect-smol/commit/c890f9a1b3a989ed22528bd5a43326342e05b142), [`1e985f2`](https://github.com/Effect-TS/effect-smol/commit/1e985f237d250b51b91de22dde77160c1e778ce7)]:
|
||||
- effect@4.0.0-beta.27
|
||||
|
||||
## 4.0.0-beta.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fb21462`](https://github.com/Effect-TS/effect-smol/commit/fb21462642cdd5b1bada92f3eba18ae20445be42), [`2ed26b1`](https://github.com/Effect-TS/effect-smol/commit/2ed26b139805700e3df39efaa768ff01565e5c86), [`e832a57`](https://github.com/Effect-TS/effect-smol/commit/e832a57b570fe38f010c1fd99bceac5a325a9e07), [`7f01be7`](https://github.com/Effect-TS/effect-smol/commit/7f01be7f8db363d4b2e88e6b5571e96bb815786f), [`e965143`](https://github.com/Effect-TS/effect-smol/commit/e9651431e114479e6becf8ca7b1ed99ac7e91ccc), [`b9b80f1`](https://github.com/Effect-TS/effect-smol/commit/b9b80f1f15e152ceef0a727d150b7dc230abae99), [`98252aa`](https://github.com/Effect-TS/effect-smol/commit/98252aa0c0b17fc73fbdad65d0a1104965f9fc0f), [`56fbd94`](https://github.com/Effect-TS/effect-smol/commit/56fbd94311ad19a05001ad649d9e34ab00c74541), [`3faa109`](https://github.com/Effect-TS/effect-smol/commit/3faa109b7d093fbf14ad410d3e11d663f16e28f1), [`692ecfe`](https://github.com/Effect-TS/effect-smol/commit/692ecfed99fe58056b7a5afe001f4fcd1a61c446), [`1e70b72`](https://github.com/Effect-TS/effect-smol/commit/1e70b72d0b210474d0e96a15a5cfc279eae37e0c), [`ecf0782`](https://github.com/Effect-TS/effect-smol/commit/ecf07829ef2dfc01d8943c96c4fe9c1b44b97926)]:
|
||||
- effect@4.0.0-beta.26
|
||||
|
||||
## 4.0.0-beta.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fa17bb5`](https://github.com/Effect-TS/effect-smol/commit/fa17bb5be9f2533d01e11322b14804c7dec43714), [`f46e5b5`](https://github.com/Effect-TS/effect-smol/commit/f46e5b5ca2a918ee4d9270167e79db223077c96f), [`ce4767c`](https://github.com/Effect-TS/effect-smol/commit/ce4767cadcacc6ce8ff4c3a0d0fbc82ede655f63), [`c830a8b`](https://github.com/Effect-TS/effect-smol/commit/c830a8b6c292a6528d7f9318759d34800b00372d)]:
|
||||
- effect@4.0.0-beta.25
|
||||
|
||||
## 4.0.0-beta.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a909e1c`](https://github.com/Effect-TS/effect-smol/commit/a909e1c1ac2bc707527f5073776e3e7d239688d9), [`8814a4e`](https://github.com/Effect-TS/effect-smol/commit/8814a4ef78d67144d27689370af10099ea210399), [`3f942c5`](https://github.com/Effect-TS/effect-smol/commit/3f942c51cefa7b2ffa7c49e8c8a2c887570ba4c0), [`774ed59`](https://github.com/Effect-TS/effect-smol/commit/774ed59c52b2ab578bbb897c4f551f812231e1d2), [`f54b8d3`](https://github.com/Effect-TS/effect-smol/commit/f54b8d398fedad1815fd1f4c49814ab938cfc385)]:
|
||||
- effect@4.0.0-beta.24
|
||||
|
||||
## 4.0.0-beta.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c73c41`](https://github.com/Effect-TS/effect-smol/commit/5c73c41b69eaeab80fcd62c9bfda490b446d1966)]:
|
||||
- effect@4.0.0-beta.23
|
||||
|
||||
## 4.0.0-beta.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0874332`](https://github.com/Effect-TS/effect-smol/commit/0874332f7c81118b06ac2eb105e0710211631479), [`c592dcd`](https://github.com/Effect-TS/effect-smol/commit/c592dcde0697e322065c8f418c0480ef910cb183), [`1dbe28d`](https://github.com/Effect-TS/effect-smol/commit/1dbe28dac8299cd3e218c9768450cfd173b5e294), [`564d730`](https://github.com/Effect-TS/effect-smol/commit/564d730b6bbf38dd8548a3b046e7a693b28699a4), [`3cfadc4`](https://github.com/Effect-TS/effect-smol/commit/3cfadc458b070c6cba6c5674b72a059f1e49118b), [`6634fd0`](https://github.com/Effect-TS/effect-smol/commit/6634fd07da067d80b8261fb2959d1a952b9e412e), [`d10dabe`](https://github.com/Effect-TS/effect-smol/commit/d10dabeb7af9a368f995829cd36ad08167cd8f95), [`f82f549`](https://github.com/Effect-TS/effect-smol/commit/f82f549a09e950e9d4987f279a800f4d953f0939), [`78a3382`](https://github.com/Effect-TS/effect-smol/commit/78a3382ddfbe034408f7480fa794733d9e82147b)]:
|
||||
- effect@4.0.0-beta.22
|
||||
|
||||
## 4.0.0-beta.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e691909`](https://github.com/Effect-TS/effect-smol/commit/e691909495ccb162ea7bfa351dd74632b99997cb), [`d5f413f`](https://github.com/Effect-TS/effect-smol/commit/d5f413f3c8fc57f2413cc5649c2003d6d4e5a6d7), [`139d152`](https://github.com/Effect-TS/effect-smol/commit/139d152941e562a073b5be12e8d66c8a4d4a8a57), [`947e3d4`](https://github.com/Effect-TS/effect-smol/commit/947e3d436ab8a017efda9b29be523efd1ca8df28), [`84b2cce`](https://github.com/Effect-TS/effect-smol/commit/84b2ccefe2aa3a7413b86738a4dc33cdb311ca55), [`7f5305e`](https://github.com/Effect-TS/effect-smol/commit/7f5305e69f5a33309e77b08a576edb25d7daaee2), [`9e6fd84`](https://github.com/Effect-TS/effect-smol/commit/9e6fd8471c93a3c643929151a3bdb62cb9c0ca0e), [`fdb8a4b`](https://github.com/Effect-TS/effect-smol/commit/fdb8a4b172721fbefe98bd5aa6fe4f0efd1da3eb), [`0f986ef`](https://github.com/Effect-TS/effect-smol/commit/0f986ef22f196fe091a7afdbd179485a7d888882), [`9355fc0`](https://github.com/Effect-TS/effect-smol/commit/9355fc0ffb5b7382146a5aed9eea83974b10d007)]:
|
||||
- effect@4.0.0-beta.21
|
||||
|
||||
## 4.0.0-beta.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1529](https://github.com/Effect-TS/effect-smol/pull/1529) [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8) Thanks @tim-smart! - Add dedicated AiError metadata interfaces per reason so provider packages can safely augment metadata without conflicting module declarations.
|
||||
|
||||
- [#1528](https://github.com/Effect-TS/effect-smol/pull/1528) [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34) Thanks @tim-smart! - Add `Model.ModelName` and provide it from AI model constructors.
|
||||
|
||||
- Updated dependencies [[`842a624`](https://github.com/Effect-TS/effect-smol/commit/842a624f79d5e1407460b0ef3ab27d14d48ccf74), [`4785eef`](https://github.com/Effect-TS/effect-smol/commit/4785eef5d7cf1edb96ef2509aed2ba4d1edf3862), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`12ee8e2`](https://github.com/Effect-TS/effect-smol/commit/12ee8e27df7eb393d83a5e403390d0cfc82ca732), [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34), [`989d1cc`](https://github.com/Effect-TS/effect-smol/commit/989d1cca936fce0cc459057825ba40e3f5ef3827)]:
|
||||
- effect@4.0.0-beta.20
|
||||
|
||||
## 4.0.0-beta.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1522](https://github.com/Effect-TS/effect-smol/pull/1522) [`19984c2`](https://github.com/Effect-TS/effect-smol/commit/19984c2c1b23ef06d69f9bbd4c4ad992a03c6860) Thanks @IMax153! - Fix missing `yield*` in `OpenAiLanguageModel.prepareResponseFormat`
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.19
|
||||
|
||||
## 4.0.0-beta.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1520](https://github.com/Effect-TS/effect-smol/pull/1520) [`725260b`](https://github.com/Effect-TS/effect-smol/commit/725260b53f5142d6af7a93a2f9f464f974eda92d) Thanks @IMax153! - Ensure that OpenAI JSON schemas for tool calls and structured outputs are properly transformed
|
||||
|
||||
- Updated dependencies [[`01e31fd`](https://github.com/Effect-TS/effect-smol/commit/01e31fdf8e5206849d23cbafd23a346f2f177ab8), [`0890aab`](https://github.com/Effect-TS/effect-smol/commit/0890aab15ed9c5ba52c383a72fdc6a444d7504d5), [`725260b`](https://github.com/Effect-TS/effect-smol/commit/725260b53f5142d6af7a93a2f9f464f974eda92d)]:
|
||||
- effect@4.0.0-beta.18
|
||||
|
||||
## 4.0.0-beta.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8f59c32`](https://github.com/Effect-TS/effect-smol/commit/8f59c32922597a48392744f7203e284866747781)]:
|
||||
- effect@4.0.0-beta.17
|
||||
|
||||
## 4.0.0-beta.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf9096c`](https://github.com/Effect-TS/effect-smol/commit/bf9096c52a7d8791d93d232739e523eb84f6625a), [`29f81ca`](https://github.com/Effect-TS/effect-smol/commit/29f81ca07c67dba265804b140a7487fb15a5fc6b), [`68eb28c`](https://github.com/Effect-TS/effect-smol/commit/68eb28c2b0fc67a9f6204ade9bd16c5b37803bfb)]:
|
||||
- effect@4.0.0-beta.16
|
||||
|
||||
## 4.0.0-beta.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1502](https://github.com/Effect-TS/effect-smol/pull/1502) [`285b7e6`](https://github.com/Effect-TS/effect-smol/commit/285b7e667167566d5788367d5155b19c79f1bf22) Thanks @tim-smart! - allow undefined for ai config
|
||||
|
||||
- Updated dependencies [[`24ae609`](https://github.com/Effect-TS/effect-smol/commit/24ae60995d2fd7d621be356cdfdfd328c79639ba), [`0e3c059`](https://github.com/Effect-TS/effect-smol/commit/0e3c059987caa55ebd0c134f7c7b147c639c328e), [`e843b0a`](https://github.com/Effect-TS/effect-smol/commit/e843b0a7d7e7b600a0b3bd477f24e2e4cd26bc8b), [`f4389a2`](https://github.com/Effect-TS/effect-smol/commit/f4389a2cca3c5bbf00d69779f52ce41255f15a28), [`5b73de0`](https://github.com/Effect-TS/effect-smol/commit/5b73de095b3402d0c5c74092ace6ce18ebfad566), [`595d2d6`](https://github.com/Effect-TS/effect-smol/commit/595d2d6e7d50419f3532bd39266191532ace38f2)]:
|
||||
- effect@4.0.0-beta.15
|
||||
|
||||
## 4.0.0-beta.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c414700`](https://github.com/Effect-TS/effect-smol/commit/c414700ef1932e4b67d0102856de417336912350), [`a30c969`](https://github.com/Effect-TS/effect-smol/commit/a30c9699c0d736cf3952041e45d508b7d58907a9)]:
|
||||
- effect@4.0.0-beta.14
|
||||
|
||||
## 4.0.0-beta.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`368f4c3`](https://github.com/Effect-TS/effect-smol/commit/368f4c363dd117e6f5a19ad77b161176cfd29fdd), [`db8a579`](https://github.com/Effect-TS/effect-smol/commit/db8a579e93e93ff73b1e60712732e03b597b916b), [`668b703`](https://github.com/Effect-TS/effect-smol/commit/668b70337e9ddbb0d1ae2282a95c282ce404e562), [`d40e76b`](https://github.com/Effect-TS/effect-smol/commit/d40e76b973543979e60e04a6baca04a8c65bdfc2), [`6e18cf8`](https://github.com/Effect-TS/effect-smol/commit/6e18cf883e9905ca718a6697b6a2a4bbd42739aa), [`86062e8`](https://github.com/Effect-TS/effect-smol/commit/86062e8a0c61bca5412fc40d2cf151d676901f08), [`c27ce75`](https://github.com/Effect-TS/effect-smol/commit/c27ce75d34c74dcfc6dba1bf77f1ce88f410a0de), [`e2d4fbf`](https://github.com/Effect-TS/effect-smol/commit/e2d4fbfeeda6a5d2a4c5aeb0501d8240c248b9eb), [`114ab42`](https://github.com/Effect-TS/effect-smol/commit/114ab42ad0edc590d29169675a493e0e915aa58f), [`484caec`](https://github.com/Effect-TS/effect-smol/commit/484caec47cccac8b86db2910742e406dfc7173ab)]:
|
||||
- effect@4.0.0-beta.13
|
||||
|
||||
## 4.0.0-beta.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70a74e8`](https://github.com/Effect-TS/effect-smol/commit/70a74e88a8767c9d4acdb9e5f25aec9a33588d07), [`b5b6e10`](https://github.com/Effect-TS/effect-smol/commit/b5b6e10621d54bf8c9857fec0d647ced78ecd857), [`f5ce5a9`](https://github.com/Effect-TS/effect-smol/commit/f5ce5a915359c6ebf254079e1da23cab6cde34fb), [`a29eb70`](https://github.com/Effect-TS/effect-smol/commit/a29eb702ffe3fc58bd28c4d7857298cd65d73668), [`c7b36e5`](https://github.com/Effect-TS/effect-smol/commit/c7b36e541a23e9a00f64e25b23851e51a37dfce5), [`9381d6d`](https://github.com/Effect-TS/effect-smol/commit/9381d6d4d9d819a81a46e56d0364c76e92a4fbca), [`88439f1`](https://github.com/Effect-TS/effect-smol/commit/88439f13ca13549f3e4822c48c4f019c14fc2bcc), [`e35307d`](https://github.com/Effect-TS/effect-smol/commit/e35307dbeb8eb26a9923f958b894a8eaaf259bf2), [`c7df4bc`](https://github.com/Effect-TS/effect-smol/commit/c7df4bce34009474c63d62a807abfdafb76971eb), [`accaf3b`](https://github.com/Effect-TS/effect-smol/commit/accaf3be7ac8da36e2334c509c23b8c9e88ea160), [`3e1c270`](https://github.com/Effect-TS/effect-smol/commit/3e1c2707bbdf67720af1509642b8ced195790882), [`6cd81f7`](https://github.com/Effect-TS/effect-smol/commit/6cd81f73baad86f5bbfa455a55d75cde71e9611a), [`f222da3`](https://github.com/Effect-TS/effect-smol/commit/f222da3cdb44554f3324c2c52d0d005ee575053e), [`61f901d`](https://github.com/Effect-TS/effect-smol/commit/61f901d830005b66e22d1de889fda132aeea97cd)]:
|
||||
- effect@4.0.0-beta.12
|
||||
|
||||
## 4.0.0-beta.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`88659ed`](https://github.com/Effect-TS/effect-smol/commit/88659edb26e3623d557dccfe914c2c949672da16), [`f2915e8`](https://github.com/Effect-TS/effect-smol/commit/f2915e8e2efe80d50c281e53f297b9701d6dc199), [`eb71ace`](https://github.com/Effect-TS/effect-smol/commit/eb71acebbe0f228e4920278013beee3b67d62310), [`2a16999`](https://github.com/Effect-TS/effect-smol/commit/2a169996c7513d377ac47adbfd68e1490457135c), [`d42dd52`](https://github.com/Effect-TS/effect-smol/commit/d42dd52f11203f8e749fb5d3ecf7153e4a5a6814), [`339adaf`](https://github.com/Effect-TS/effect-smol/commit/339adaf850a62a892adebcb208c2d9dddf3b97b3), [`de19645`](https://github.com/Effect-TS/effect-smol/commit/de1964526d01102dd1cb99c8cfdd3e8df1f49ef1), [`9b1dc3b`](https://github.com/Effect-TS/effect-smol/commit/9b1dc3bcf2a1b68d0a67e3465db5ad01a1a56997), [`e4cb2f5`](https://github.com/Effect-TS/effect-smol/commit/e4cb2f55b30f4771ec1bf613ced36d6d96464dd5), [`8bced95`](https://github.com/Effect-TS/effect-smol/commit/8bced954ecb35d4489197a57b0efe927e7d75f49), [`9431420`](https://github.com/Effect-TS/effect-smol/commit/94314207c8019918200fbcb97aec992219f801f0), [`948dca2`](https://github.com/Effect-TS/effect-smol/commit/948dca22e4f672ba7a6db57f9899272bec7c08b8), [`d18e327`](https://github.com/Effect-TS/effect-smol/commit/d18e32765a2665e31ffb31e746bf983fcfac34c5), [`ab512f7`](https://github.com/Effect-TS/effect-smol/commit/ab512f7be1c0e6b359da921e22cd4944e4c57d3e)]:
|
||||
- effect@4.0.0-beta.11
|
||||
|
||||
## 4.0.0-beta.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`371acab`](https://github.com/Effect-TS/effect-smol/commit/371acabb58d56f3a7a5e3e33d3d5fdc9f5573c74), [`856d774`](https://github.com/Effect-TS/effect-smol/commit/856d7741f1e296dd5048c6ff2b44b95d023e6ae4), [`b9e9202`](https://github.com/Effect-TS/effect-smol/commit/b9e92023c38caa322975d77cfe83e2d34ac9305a), [`1d1a974`](https://github.com/Effect-TS/effect-smol/commit/1d1a974bd280c81bff5d4505491cda03ba7a3f36), [`6bfe2a6`](https://github.com/Effect-TS/effect-smol/commit/6bfe2a659bc6335db75709931f405da45301cba2), [`b12c811`](https://github.com/Effect-TS/effect-smol/commit/b12c81157be287b1649c210616a244b50ec094d2), [`d17d98a`](https://github.com/Effect-TS/effect-smol/commit/d17d98ad78e2b44d95ef434adab79ac3c35e75ab), [`68c3c7c`](https://github.com/Effect-TS/effect-smol/commit/68c3c7cb1e06ed94fa5c4c123a234b4ccbfdecd8)]:
|
||||
- effect@4.0.0-beta.10
|
||||
|
||||
## 4.0.0-beta.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3386557`](https://github.com/Effect-TS/effect-smol/commit/338655731564a7be9f8859dedbf4d5bcac6eb350), [`b6666e3`](https://github.com/Effect-TS/effect-smol/commit/b6666e3cf6bd44ba1a8704e65c256c30359cb422)]:
|
||||
- effect@4.0.0-beta.9
|
||||
|
||||
## 4.0.0-beta.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1354](https://github.com/Effect-TS/effect-smol/pull/1354) [`b94962c`](https://github.com/Effect-TS/effect-smol/commit/b94962c249d46cf96cdf2e41188dc9feda41536a) Thanks @IMax153! - Fix the generated schemas for ai providers
|
||||
|
||||
- Updated dependencies [[`246e672`](https://github.com/Effect-TS/effect-smol/commit/246e672dbbd7848d60e0c78fd66671b2f10b3752), [`807dec0`](https://github.com/Effect-TS/effect-smol/commit/807dec03801b4c58a6d00c237b6d98d6386911df)]:
|
||||
- effect@4.0.0-beta.8
|
||||
|
||||
## 4.0.0-beta.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a2bda6d`](https://github.com/Effect-TS/effect-smol/commit/a2bda6d4ef6de9d9b0c53ae2df5434f778d6161a), [`1f95a2b`](https://github.com/Effect-TS/effect-smol/commit/1f95a2b5aa9524bb38f4437f4691a664bf463ca1), [`a8d5e79`](https://github.com/Effect-TS/effect-smol/commit/a8d5e792fec201a83af0eb92fc79928d055125fd), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`06d8a03`](https://github.com/Effect-TS/effect-smol/commit/06d8a0391631e6130e3ab25227e59817852e227f), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`f9e883e`](https://github.com/Effect-TS/effect-smol/commit/f9e883e266fbda870336ee62f46b7ac85ba3de6e), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430)]:
|
||||
- effect@4.0.0-beta.7
|
||||
|
||||
## 4.0.0-beta.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3247da2`](https://github.com/Effect-TS/effect-smol/commit/3247da28331f345f68be5dbd2974a7e03d300fe1), [`f205705`](https://github.com/Effect-TS/effect-smol/commit/f2057050dbd034b8c186be2d40c3d03ee63a5a3b), [`f35022c`](https://github.com/Effect-TS/effect-smol/commit/f35022c212e4111527e1bb43f360a67b2b49fa85), [`8622721`](https://github.com/Effect-TS/effect-smol/commit/86227217b02d43680a3c6f3c21731b1d852c91f5), [`fc660ab`](https://github.com/Effect-TS/effect-smol/commit/fc660ab8b5ebae38b8d6b96cbf2f9b880cc09253), [`f37dc33`](https://github.com/Effect-TS/effect-smol/commit/f37dc335f64622fa9ce8d6d1d5dd8fc3f260257b), [`3662f32`](https://github.com/Effect-TS/effect-smol/commit/3662f328fcfa3b2fa01ffa79da40e12e93fcede8), [`a7d436f`](https://github.com/Effect-TS/effect-smol/commit/a7d436f438dcd7f49b9485e4e95a4511f31fad7d), [`6856a41`](https://github.com/Effect-TS/effect-smol/commit/6856a415d7eddd9d73d60919e976f1d071421be4), [`8c417d0`](https://github.com/Effect-TS/effect-smol/commit/8c417d03475e5e12d00dca0c4781d0af7e66b86c), [`5419570`](https://github.com/Effect-TS/effect-smol/commit/5419570ba47ce882a3a10882707b46f66e464906), [`449c5ed`](https://github.com/Effect-TS/effect-smol/commit/449c5ed5318e8a874e730420bcf52918fa2ec80f), [`4b5ec12`](https://github.com/Effect-TS/effect-smol/commit/4b5ec12f87f95f2a3cd8fe4d5b26c6eb0529381a), [`df87937`](https://github.com/Effect-TS/effect-smol/commit/df879375fc3b169c43f9c434b3775e12b80dffe4), [`5dbfca8`](https://github.com/Effect-TS/effect-smol/commit/5dbfca8d1dbb6d18d1605d4f8562e99c86e2ff11), [`e629497`](https://github.com/Effect-TS/effect-smol/commit/e6294973d55597ab6b6deca6babbe1e946b2c91d), [`981c991`](https://github.com/Effect-TS/effect-smol/commit/981c991cd78db34def815d5754379d737157f005), [`1ca2ed6`](https://github.com/Effect-TS/effect-smol/commit/1ca2ed67301a5dc40ae0ed94346b99f26fd22bbe), [`45722bd`](https://github.com/Effect-TS/effect-smol/commit/45722bde974458311f11ad237711363a10ec6894), [`eb2a85e`](https://github.com/Effect-TS/effect-smol/commit/eb2a85ed4dc162b2535d304799333a5a20477fd0)]:
|
||||
- effect@4.0.0-beta.6
|
||||
|
||||
## 4.0.0-beta.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f6e133e`](https://github.com/Effect-TS/effect-smol/commit/f6e133e9a16b32317bd09ff08c12b97a0ae44600), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8), [`a88e206`](https://github.com/Effect-TS/effect-smol/commit/a88e206e44dc66ca5a2b45bedc797877c5dbb083), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8)]:
|
||||
- effect@4.0.0-beta.5
|
||||
|
||||
## 4.0.0-beta.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c5a18ef`](https://github.com/Effect-TS/effect-smol/commit/c5a18ef44171e3880bf983faee74529908974b32), [`bc6b885`](https://github.com/Effect-TS/effect-smol/commit/bc6b885b94d887a200657c0775dfa874dc15bc0c)]:
|
||||
- effect@4.0.0-beta.4
|
||||
|
||||
## 4.0.0-beta.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a0cf36`](https://github.com/Effect-TS/effect-smol/commit/3a0cf36eff106ba48d74e133c1598cd40613e530), [`c4da328`](https://github.com/Effect-TS/effect-smol/commit/c4da328d32fad1d61e0e538f5d371edf61521d7e)]:
|
||||
- effect@4.0.0-beta.3
|
||||
|
||||
## 4.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a22ce73`](https://github.com/Effect-TS/effect-smol/commit/a22ce73b2bd9305b7ba665694d2255c0e6d5a8d0), [`ebdabf7`](https://github.com/Effect-TS/effect-smol/commit/ebdabf79ff4e62c8384aa8cf9a8d2787d536ee78), [`8f663bb`](https://github.com/Effect-TS/effect-smol/commit/8f663bb121021bf12bd264e8ae385187cb7a5dae)]:
|
||||
- effect@4.0.0-beta.2
|
||||
|
||||
## 4.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0fecf70`](https://github.com/Effect-TS/effect-smol/commit/0fecf70048057623eed7c584a06671773a2b1743), [`709569e`](https://github.com/Effect-TS/effect-smol/commit/709569ed76bead9ebb0670599e4d890a07ca5a43)]:
|
||||
- effect@4.0.0-beta.1
|
||||
|
||||
## 4.0.0-beta.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#1183](https://github.com/Effect-TS/effect-smol/pull/1183) [`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66) Thanks @tim-smart! - v4 beta
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66)]:
|
||||
- effect@4.0.0-beta.0
|
||||
41
repos/effect/packages/ai/openai/codegen.yaml
Normal file
41
repos/effect/packages/ai/openai/codegen.yaml
Normal file
@@ -0,0 +1,41 @@
|
||||
# yaml-language-server: $schema=../../tools/ai-codegen/codegen.schema.json
|
||||
spec: https://app.stainless.com/api/spec/documented/openai/openapi.documented.yml
|
||||
output: src/Generated.ts
|
||||
name: OpenAiClient
|
||||
header: |
|
||||
/**
|
||||
* @since 1.0.0
|
||||
*/
|
||||
patches:
|
||||
- '[{"op":"replace","path":"/openapi","value":"3.0.0"}]'
|
||||
- '[{"op":"add","path":"/components/schemas/ModelResponseProperties/properties/user/nullable","value":true}]'
|
||||
- '[{"op":"add","path":"/components/schemas/ModelResponseProperties/properties/safety_identifier/nullable","value":true}]'
|
||||
- '[{"op":"add","path":"/components/schemas/ModelResponseProperties/properties/prompt_cache_key/nullable","value":true}]'
|
||||
- '[{"op":"add","path":"/components/schemas/Response/allOf/2/properties/usage/nullable","value":true}]'
|
||||
- '[{"op":"remove","path":"/components/schemas/ResponseFunctionCallArgumentsDoneEvent/required/2"}]'
|
||||
- '[{"op":"remove","path":"/components/schemas/WebSearchActionSearch/required/1"}]'
|
||||
- '[{"op":"add","path":"/components/schemas/ModelResponseProperties/properties/prompt_cache_retention/anyOf/0/enum/1","value":"in_memory"}]'
|
||||
- '[{"op":"add","path":"/components/schemas/PromptCacheRetentionEnum/enum/1","value":"in-memory"}]'
|
||||
- '[{"op":"replace","path":"/components/schemas/OpenAIFile/properties/expires_at","value":{"anyOf":[{"type":"integer","format":"unixtime","description":"The Unix timestamp (in seconds) for when the file will expire."},{"type":"null"}]}}]'
|
||||
- '[{"op":"add","path":"/components/schemas/OpenAIFile/properties/status_details/nullable","value":true}]'
|
||||
# Add missing keepalive stream event support
|
||||
- '[{"op":"add","path":"/components/schemas/ResponseKeepAliveEvent","value":{"type":"object","title":"Keep alive","description":"A keepalive event emitted during long-running response streams.","properties":{"type":{"type":"string","enum":["keepalive"],"description":"The type of the keepalive event. Always `keepalive`.","default":"keepalive","x-stainless-const":true},"sequence_number":{"type":"integer","description":"The sequence number of this keepalive event."}},"required":["type","sequence_number"]}}]'
|
||||
- '[{"op":"add","path":"/components/schemas/ResponseStreamEvent/anyOf/-","value":{"$ref":"#/components/schemas/ResponseKeepAliveEvent"}}]'
|
||||
# Add missing ResponseApplyPatchCallOperationDiffDeltaEvent schema
|
||||
- '[{"op":"add","path":"/components/schemas/ResponseApplyPatchCallOperationDiffDeltaEvent","value":{"title":"ResponseApplyPatchCallOperationDiffDelta","type":"object","description":"Event representing a delta for an apply_patch tool call operation diff.","properties":{"type":{"type":"string","enum":["response.apply_patch_call_operation_diff.delta"],"description":"The event type identifier.","x-stainless-const":true},"sequence_number":{"type":"integer","description":"The sequence number of this event."},"output_index":{"type":"integer","description":"The index of the output this delta applies to."},"item_id":{"type":"string","description":"Unique identifier for the API item associated with this event."},"delta":{"type":"string","description":"The incremental diff data for the apply_patch tool call."}},"required":["type","output_index","item_id","delta","sequence_number"]}}]'
|
||||
# Add missing ResponseApplyPatchCallOperationDiffDoneEvent schema (delta is optional - not always sent by OpenAI)
|
||||
- '[{"op":"add","path":"/components/schemas/ResponseApplyPatchCallOperationDiffDoneEvent","value":{"title":"ResponseApplyPatchCallOperationDiffDone","type":"object","description":"Event indicating that the operation diff for an apply_patch tool call is complete.","properties":{"type":{"type":"string","enum":["response.apply_patch_call_operation_diff.done"],"description":"The event type identifier.","x-stainless-const":true},"sequence_number":{"type":"integer","description":"The sequence number of this event."},"output_index":{"type":"integer","description":"The index of the output this event applies to."},"item_id":{"type":"string","description":"Unique identifier for the API item associated with this event."},"delta":{"type":"string","description":"The final diff data for the apply_patch tool call."}},"required":["type","output_index","item_id","sequence_number"]}}]'
|
||||
# Add both events to ResponseStreamEvent anyOf array
|
||||
- '[{"op":"add","path":"/components/schemas/ResponseStreamEvent/anyOf/-","value":{"$ref":"#/components/schemas/ResponseApplyPatchCallOperationDiffDeltaEvent"}}]'
|
||||
- '[{"op":"add","path":"/components/schemas/ResponseStreamEvent/anyOf/-","value":{"$ref":"#/components/schemas/ResponseApplyPatchCallOperationDiffDoneEvent"}}]'
|
||||
excludeAnnotations:
|
||||
- examples
|
||||
- default
|
||||
disableAdditionalProperties: true
|
||||
replacements:
|
||||
# Schema.Unknown doesn't work with Schema.toCodecJson (used by HttpClientResponse.schemaBodyJson)
|
||||
# Replace with Schema.Json which properly handles arbitrary JSON values
|
||||
- from: "Schema.Record(Schema.String, Schema.Unknown)"
|
||||
to: "Schema.Record(Schema.String, Schema.Json)"
|
||||
- from: "{ readonly [x: string]: unknown }"
|
||||
to: "{ readonly [x: string]: Schema.Json }"
|
||||
23
repos/effect/packages/ai/openai/docgen.json
Normal file
23
repos/effect/packages/ai/openai/docgen.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "../../node_modules/@effect/docgen/schema.json",
|
||||
"srcLink": "https://github.com/Effect-TS/effect/tree/main/packages/ai/openai/src/",
|
||||
"exclude": ["src/Generated.ts", "src/internal/**/*.ts"],
|
||||
"examplesCompilerOptions": {
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "Bundler",
|
||||
"module": "ES2022",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"rewriteRelativeImportExtensions": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"paths": {
|
||||
"effect": ["../../../effect/src/index.js"],
|
||||
"effect/*": ["../../../effect/src/*.js"]
|
||||
},
|
||||
"plugins": [
|
||||
{ "name": "@effect/language-service", "includeSuggestionsInTsc": false }
|
||||
]
|
||||
}
|
||||
}
|
||||
66
repos/effect/packages/ai/openai/package.json
Normal file
66
repos/effect/packages/ai/openai/package.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "@effect/ai-openai",
|
||||
"version": "4.0.0-beta.99",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "An OpenAI provider integration for Effect AI SDK",
|
||||
"homepage": "https://effect.website",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Effect-TS/effect.git",
|
||||
"directory": "packages/ai/openai"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Effect-TS/effect/issues"
|
||||
},
|
||||
"tags": [
|
||||
"typescript",
|
||||
"ai",
|
||||
"openai"
|
||||
],
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"ai",
|
||||
"openai"
|
||||
],
|
||||
"sideEffects": [],
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts",
|
||||
"./*": "./src/*.ts",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
},
|
||||
"files": [
|
||||
"src/**/*.ts",
|
||||
"dist/**/*.js",
|
||||
"dist/**/*.js.map",
|
||||
"dist/**/*.d.ts",
|
||||
"dist/**/*.d.ts.map"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"provenance": true,
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./dist/index.js",
|
||||
"./*": "./dist/*.js",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"codegen": "effect-utils codegen",
|
||||
"build": "tsc -b tsconfig.json && pnpm babel",
|
||||
"babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
||||
"check": "tsc -b tsconfig.json",
|
||||
"test": "vitest",
|
||||
"coverage": "vitest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"effect": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "workspace:^"
|
||||
}
|
||||
}
|
||||
35774
repos/effect/packages/ai/openai/src/Generated.ts
Normal file
35774
repos/effect/packages/ai/openai/src/Generated.ts
Normal file
File diff suppressed because it is too large
Load Diff
730
repos/effect/packages/ai/openai/src/OpenAiClient.ts
Normal file
730
repos/effect/packages/ai/openai/src/OpenAiClient.ts
Normal file
@@ -0,0 +1,730 @@
|
||||
/**
|
||||
* The `OpenAiClient` module defines the low-level Effect service used by the
|
||||
* OpenAI integration for Responses API and embedding requests. It builds a
|
||||
* configured HTTP client with authentication and OpenAI organization or project
|
||||
* headers, exposes helpers for non-streaming responses, SSE response streams,
|
||||
* WebSocket response streams, and embeddings, and maps transport or decoding
|
||||
* failures into `AiError`.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Array from "effect/Array"
|
||||
import type * as Config from "effect/Config"
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { identity } from "effect/Function"
|
||||
import * as Function from "effect/Function"
|
||||
import * as Layer from "effect/Layer"
|
||||
import * as Predicate from "effect/Predicate"
|
||||
import * as Queue from "effect/Queue"
|
||||
import * as RcRef from "effect/RcRef"
|
||||
import * as Redacted from "effect/Redacted"
|
||||
import * as Schema from "effect/Schema"
|
||||
import * as Scope from "effect/Scope"
|
||||
import * as Semaphore from "effect/Semaphore"
|
||||
import * as Stream from "effect/Stream"
|
||||
import * as AiError from "effect/unstable/ai/AiError"
|
||||
import * as ResponseIdTracker from "effect/unstable/ai/ResponseIdTracker"
|
||||
import * as Sse from "effect/unstable/encoding/Sse"
|
||||
import * as Headers from "effect/unstable/http/Headers"
|
||||
import * as HttpBody from "effect/unstable/http/HttpBody"
|
||||
import * as HttpClient from "effect/unstable/http/HttpClient"
|
||||
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
||||
import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
|
||||
import * as Socket from "effect/unstable/socket/Socket"
|
||||
import * as Errors from "./internal/errors.ts"
|
||||
import { OpenAiConfig } from "./OpenAiConfig.ts"
|
||||
import * as OpenAiSchema from "./OpenAiSchema.ts"
|
||||
|
||||
// =============================================================================
|
||||
// Service Interface
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Effect service interface for the handwritten OpenAI client.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Provides the configured HTTP client plus helpers for Responses API calls, streaming Responses events, and embeddings. Transport and schema decoding failures are mapped to `AiError`.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface Service {
|
||||
/**
|
||||
* The transformed HTTP client used by this service.
|
||||
*/
|
||||
readonly client: HttpClient.HttpClient
|
||||
|
||||
/**
|
||||
* Create a response using the OpenAI responses endpoint.
|
||||
*/
|
||||
readonly createResponse: (
|
||||
options: typeof OpenAiSchema.CreateResponse.Encoded
|
||||
) => Effect.Effect<
|
||||
readonly [body: typeof OpenAiSchema.Response.Type, response: HttpClientResponse.HttpClientResponse],
|
||||
AiError.AiError
|
||||
>
|
||||
|
||||
/**
|
||||
* Create a streaming response using the OpenAI responses endpoint.
|
||||
*/
|
||||
readonly createResponseStream: (
|
||||
options: Omit<typeof OpenAiSchema.CreateResponse.Encoded, "stream">
|
||||
) => Effect.Effect<
|
||||
readonly [
|
||||
response: HttpClientResponse.HttpClientResponse,
|
||||
stream: Stream.Stream<typeof OpenAiSchema.ResponseStreamEvent.Type, AiError.AiError>
|
||||
],
|
||||
AiError.AiError
|
||||
>
|
||||
|
||||
/**
|
||||
* Create embeddings using the OpenAI embeddings endpoint.
|
||||
*/
|
||||
readonly createEmbedding: (
|
||||
options: typeof OpenAiSchema.CreateEmbeddingRequest.Encoded
|
||||
) => Effect.Effect<typeof OpenAiSchema.CreateEmbeddingResponse.Type, AiError.AiError>
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Service Identifier
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Service tag for the OpenAI client.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when accessing or providing the OpenAI client service through Effect's
|
||||
* context.
|
||||
*
|
||||
* @see {@link make} for constructing an OpenAI client effectfully
|
||||
* @see {@link layer} for providing a client from explicit options
|
||||
* @see {@link layerConfig} for providing a client from `Config`
|
||||
*
|
||||
* @category services
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class OpenAiClient extends Context.Service<OpenAiClient, Service>()(
|
||||
"@effect/ai-openai/OpenAiClient"
|
||||
) {}
|
||||
|
||||
// =============================================================================
|
||||
// Options
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Options for configuring the OpenAI client.
|
||||
*
|
||||
* @category options
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* The OpenAI API key.
|
||||
*/
|
||||
readonly apiKey?: Redacted.Redacted<string> | undefined
|
||||
|
||||
/**
|
||||
* The base URL for the OpenAI API.
|
||||
*
|
||||
* @default "https://api.openai.com/v1"
|
||||
*/
|
||||
readonly apiUrl?: string | undefined
|
||||
|
||||
/**
|
||||
* Optional organization ID for multi-org accounts.
|
||||
*/
|
||||
readonly organizationId?: Redacted.Redacted<string> | undefined
|
||||
|
||||
/**
|
||||
* Optional project ID for project-scoped requests.
|
||||
*/
|
||||
readonly projectId?: Redacted.Redacted<string> | undefined
|
||||
|
||||
/**
|
||||
* Optional transformer for the HTTP client.
|
||||
*/
|
||||
readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Constructor
|
||||
// =============================================================================
|
||||
|
||||
const RedactedOpenAiHeaders = {
|
||||
OpenAiOrganization: "OpenAI-Organization",
|
||||
OpenAiProject: "OpenAI-Project"
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an OpenAI client service with the given options.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need the OpenAI client service value inside an effect.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The returned service uses the current `HttpClient`, prepends `apiUrl` or
|
||||
* `https://api.openai.com/v1`, adds the bearer token and optional OpenAI
|
||||
* organization/project headers, accepts JSON responses, filters for successful
|
||||
* HTTP statuses, and applies `transformClient` when provided.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* A scoped `OpenAiConfig.withClientTransform` is applied when request helpers
|
||||
* run, after the `transformClient` option supplied to `make`.
|
||||
*
|
||||
* @see {@link layer} for providing this client from explicit options
|
||||
* @see {@link layerConfig} for loading client settings from `Config`
|
||||
*
|
||||
* @category constructors
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const make = Effect.fnUntraced(
|
||||
function*(
|
||||
options: Options
|
||||
): Effect.fn.Return<Service, never, HttpClient.HttpClient> {
|
||||
const baseClient = yield* HttpClient.HttpClient
|
||||
const apiUrl = options.apiUrl ?? "https://api.openai.com/v1"
|
||||
|
||||
const httpClient = baseClient.pipe(
|
||||
HttpClient.mapRequest(Function.flow(
|
||||
HttpClientRequest.prependUrl(apiUrl),
|
||||
options.apiKey
|
||||
? HttpClientRequest.bearerToken(Redacted.value(options.apiKey))
|
||||
: identity,
|
||||
options.organizationId
|
||||
? HttpClientRequest.setHeader(
|
||||
RedactedOpenAiHeaders.OpenAiOrganization,
|
||||
Redacted.value(options.organizationId)
|
||||
)
|
||||
: identity,
|
||||
options.projectId
|
||||
? HttpClientRequest.setHeader(
|
||||
RedactedOpenAiHeaders.OpenAiProject,
|
||||
Redacted.value(options.projectId)
|
||||
)
|
||||
: identity,
|
||||
HttpClientRequest.acceptJson
|
||||
)),
|
||||
HttpClient.filterStatusOk,
|
||||
options.transformClient
|
||||
? options.transformClient
|
||||
: identity
|
||||
)
|
||||
|
||||
const resolveHttpClient = Effect.map(
|
||||
OpenAiConfig.getOrUndefined,
|
||||
(config) =>
|
||||
Predicate.isNotUndefined(config?.transformClient)
|
||||
? config.transformClient(httpClient)
|
||||
: httpClient
|
||||
)
|
||||
|
||||
const decodeResponse = HttpClientResponse.schemaBodyJson(OpenAiSchema.Response)
|
||||
|
||||
const createResponse = (
|
||||
payload: typeof OpenAiSchema.CreateResponse.Encoded
|
||||
): Effect.Effect<
|
||||
[body: typeof OpenAiSchema.Response.Type, response: HttpClientResponse.HttpClientResponse],
|
||||
AiError.AiError
|
||||
> =>
|
||||
Effect.flatMap(resolveHttpClient, (client) =>
|
||||
client.execute(
|
||||
HttpClientRequest.post("/responses", {
|
||||
body: HttpBody.jsonUnsafe(payload)
|
||||
})
|
||||
).pipe(
|
||||
Effect.flatMap((response) =>
|
||||
decodeResponse(response).pipe(
|
||||
Effect.map((body): [typeof OpenAiSchema.Response.Type, HttpClientResponse.HttpClientResponse] => [
|
||||
body,
|
||||
response
|
||||
])
|
||||
)
|
||||
),
|
||||
Effect.catchTags({
|
||||
HttpClientError: (error) => Errors.mapHttpClientError(error, "createResponse"),
|
||||
SchemaError: (error) => Effect.fail(Errors.mapSchemaError(error, "createResponse"))
|
||||
})
|
||||
))
|
||||
|
||||
const buildResponseStream = (
|
||||
response: HttpClientResponse.HttpClientResponse
|
||||
): [
|
||||
HttpClientResponse.HttpClientResponse,
|
||||
Stream.Stream<typeof OpenAiSchema.ResponseStreamEvent.Type, AiError.AiError>
|
||||
] => {
|
||||
const stream = response.stream.pipe(
|
||||
Stream.decodeText(),
|
||||
Stream.pipeThroughChannel(Sse.decodeDataSchema(OpenAiSchema.ResponseStreamEvent)),
|
||||
Stream.takeUntil((event) =>
|
||||
event.data.type === "response.completed" ||
|
||||
event.data.type === "response.incomplete"
|
||||
),
|
||||
Stream.map((event) => event.data),
|
||||
Stream.catchTags({
|
||||
// TODO: handle SSE retries
|
||||
Retry: (error) => Stream.die(error),
|
||||
HttpClientError: (error) => Stream.fromEffect(Errors.mapHttpClientError(error, "createResponseStream")),
|
||||
SchemaError: (error) => Stream.fail(Errors.mapSchemaError(error, "createResponseStream"))
|
||||
})
|
||||
)
|
||||
return [response, stream]
|
||||
}
|
||||
|
||||
const createResponseStream: Service["createResponseStream"] = (payload) =>
|
||||
Effect.contextWith((services) => {
|
||||
const socket = Context.getOrUndefined(services, OpenAiSocket)
|
||||
if (socket) return socket.createResponseStream(payload)
|
||||
return Effect.flatMap(resolveHttpClient, (client) =>
|
||||
client.execute(
|
||||
HttpClientRequest.post("/responses", {
|
||||
body: HttpBody.jsonUnsafe({ ...payload, stream: true })
|
||||
})
|
||||
).pipe(
|
||||
Effect.map(buildResponseStream),
|
||||
Effect.catchTag(
|
||||
"HttpClientError",
|
||||
(error) => Errors.mapHttpClientError(error, "createResponseStream")
|
||||
)
|
||||
))
|
||||
})
|
||||
|
||||
const decodeEmbedding = HttpClientResponse.schemaBodyJson(OpenAiSchema.CreateEmbeddingResponse)
|
||||
|
||||
const createEmbedding = (
|
||||
payload: typeof OpenAiSchema.CreateEmbeddingRequest.Encoded
|
||||
): Effect.Effect<typeof OpenAiSchema.CreateEmbeddingResponse.Type, AiError.AiError> =>
|
||||
Effect.flatMap(resolveHttpClient, (client) =>
|
||||
client.execute(
|
||||
HttpClientRequest.post("/embeddings", {
|
||||
body: HttpBody.jsonUnsafe(payload)
|
||||
})
|
||||
).pipe(
|
||||
Effect.flatMap(decodeEmbedding),
|
||||
Effect.catchTags({
|
||||
HttpClientError: (error) => Errors.mapHttpClientError(error, "createEmbedding"),
|
||||
SchemaError: (error) => Effect.fail(Errors.mapSchemaError(error, "createEmbedding"))
|
||||
})
|
||||
))
|
||||
|
||||
return OpenAiClient.of({
|
||||
client: httpClient,
|
||||
createResponse,
|
||||
createResponseStream,
|
||||
createEmbedding
|
||||
})
|
||||
},
|
||||
Effect.updateService(
|
||||
Headers.CurrentRedactedNames,
|
||||
Array.appendAll(Object.values(RedactedOpenAiHeaders))
|
||||
)
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// Layers
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Creates a layer for the OpenAI client with the given options.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you already have explicit `Options` values, such as an API key or
|
||||
* custom API URL, and want to provide `OpenAiClient` as a `Layer`.
|
||||
*
|
||||
* @see {@link make} for constructing the client service effectfully
|
||||
* @see {@link layerConfig} for loading client settings from `Config`
|
||||
*
|
||||
* @category layers
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const layer = (options: Options): Layer.Layer<OpenAiClient, never, HttpClient.HttpClient> =>
|
||||
Layer.effect(OpenAiClient, make(options))
|
||||
|
||||
/**
|
||||
* Creates a layer for the OpenAI client from provided `Config` values.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need client settings for OpenAI-compatible APIs to be read from
|
||||
* Effect `Config` values while providing `OpenAiClient` as a `Layer`.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Only config values supplied in `options` are loaded. Omitted fields are
|
||||
* passed to `make` as `undefined`, and `transformClient` is forwarded as a
|
||||
* plain option.
|
||||
*
|
||||
* @see {@link make} for constructing the client service effectfully
|
||||
* @see {@link layer} for providing the client from already-resolved options
|
||||
*
|
||||
* @category layers
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const layerConfig = (options?: {
|
||||
/**
|
||||
* The config value to load for the API key.
|
||||
*/
|
||||
readonly apiKey?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
|
||||
|
||||
/**
|
||||
* The config value to load for the API URL.
|
||||
*/
|
||||
readonly apiUrl?: Config.Config<string> | undefined
|
||||
|
||||
/**
|
||||
* The config value to load for the organization ID.
|
||||
*/
|
||||
readonly organizationId?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
|
||||
|
||||
/**
|
||||
* The config value to load for the project ID.
|
||||
*/
|
||||
readonly projectId?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
|
||||
|
||||
/**
|
||||
* Optional transformer for the HTTP client.
|
||||
*/
|
||||
readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
|
||||
}): Layer.Layer<OpenAiClient, Config.ConfigError, HttpClient.HttpClient> =>
|
||||
Layer.effect(
|
||||
OpenAiClient,
|
||||
Effect.gen(function*() {
|
||||
const apiKey = Predicate.isNotUndefined(options?.apiKey)
|
||||
? yield* options.apiKey :
|
||||
undefined
|
||||
const apiUrl = Predicate.isNotUndefined(options?.apiUrl)
|
||||
? yield* options.apiUrl :
|
||||
undefined
|
||||
const organizationId = Predicate.isNotUndefined(options?.organizationId)
|
||||
? yield* options.organizationId
|
||||
: undefined
|
||||
const projectId = Predicate.isNotUndefined(options?.projectId)
|
||||
? yield* options.projectId :
|
||||
undefined
|
||||
return yield* make({
|
||||
apiKey,
|
||||
apiUrl,
|
||||
organizationId,
|
||||
projectId,
|
||||
transformClient: options?.transformClient
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// Websocket mode
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Response stream event emitted by the OpenAI Responses API.
|
||||
*
|
||||
* @category Events
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type ResponseStreamEvent = typeof OpenAiSchema.ResponseStreamEvent.Type
|
||||
|
||||
/**
|
||||
* Service for creating OpenAI response streams over a WebSocket connection.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need direct access to the WebSocket-backed response streaming
|
||||
* service rather than wrapping an effect with WebSocket mode.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* `createResponseStream` sends a `response.create` message over the WebSocket
|
||||
* connection and returns an HTTP response together with a stream of
|
||||
* `ResponseStreamEvent` values.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* WebSocket response streams are serialized to one request at a time by the
|
||||
* shared socket service.
|
||||
*
|
||||
* @see {@link withWebSocketMode} for enabling WebSocket mode for one effect
|
||||
* @see {@link layerWebSocketMode} for providing WebSocket mode through a layer
|
||||
*
|
||||
* @category Websocket mode
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class OpenAiSocket extends Context.Service<OpenAiSocket, {
|
||||
/**
|
||||
* Create a streaming response using the OpenAI responses endpoint.
|
||||
*/
|
||||
readonly createResponseStream: (
|
||||
options: Omit<typeof OpenAiSchema.CreateResponse.Encoded, "stream">
|
||||
) => Effect.Effect<
|
||||
readonly [
|
||||
response: HttpClientResponse.HttpClientResponse,
|
||||
stream: Stream.Stream<ResponseStreamEvent, AiError.AiError>
|
||||
],
|
||||
AiError.AiError
|
||||
>
|
||||
}>()("@effect/ai-openai/OpenAiClient/OpenAiSocket") {}
|
||||
|
||||
const makeSocket = Effect.gen(function*() {
|
||||
const client = yield* OpenAiClient
|
||||
const tracker = yield* ResponseIdTracker.make
|
||||
const socketScope = yield* Effect.scope
|
||||
const makeRequest = Effect.flatMap(
|
||||
OpenAiConfig.getOrUndefined,
|
||||
(config) => {
|
||||
const httpClient = Predicate.isNotUndefined(config?.transformClient)
|
||||
? config.transformClient(client.client)
|
||||
: client.client
|
||||
return Effect.orDie(httpClient.preprocess(HttpClientRequest.post("/responses")))
|
||||
}
|
||||
)
|
||||
const makeWebSocket = yield* Socket.WebSocketConstructor
|
||||
|
||||
const decoder = new TextDecoder()
|
||||
|
||||
const queueRef: RcRef.RcRef<
|
||||
{
|
||||
readonly send: (message: typeof OpenAiSchema.CreateResponse.Encoded) => Effect.Effect<void, AiError.AiError>
|
||||
readonly incoming: Queue.Dequeue<ResponseStreamEvent, AiError.AiError>
|
||||
}
|
||||
> = yield* RcRef.make({
|
||||
idleTimeToLive: 60_000,
|
||||
acquire: Effect.gen(function*() {
|
||||
const scope = yield* Effect.scope
|
||||
const request = yield* makeRequest
|
||||
const socket = yield* Socket.makeWebSocket(request.url.replace(/^http/, "ws")).pipe(
|
||||
Effect.provideService(Socket.WebSocketConstructor, (url) =>
|
||||
makeWebSocket(url, {
|
||||
headers: request.headers
|
||||
} as any))
|
||||
)
|
||||
const write = yield* socket.writer
|
||||
|
||||
yield* Scope.addFinalizerExit(scope, () => {
|
||||
tracker.clearUnsafe()
|
||||
return Effect.void
|
||||
})
|
||||
|
||||
const incoming = yield* Queue.unbounded<ResponseStreamEvent, AiError.AiError>()
|
||||
const send = (message: typeof OpenAiSchema.CreateResponse.Encoded) =>
|
||||
write(JSON.stringify({
|
||||
type: "response.create",
|
||||
...message
|
||||
})).pipe(
|
||||
Effect.mapError((_error) =>
|
||||
AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method: "createResponseStream",
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "TransportError",
|
||||
request: {
|
||||
method: "POST",
|
||||
url: request.url,
|
||||
urlParams: [],
|
||||
hash: undefined,
|
||||
headers: request.headers
|
||||
},
|
||||
description: "Failed to send message over WebSocket"
|
||||
})
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
yield* socket.runRaw((msg) => {
|
||||
const text = typeof msg === "string" ? msg : decoder.decode(msg)
|
||||
try {
|
||||
const event = decodeEvent(text)
|
||||
if (event.type === "error" && "status" in event) {
|
||||
const status = Number(event.status)
|
||||
const error = "error" in event ? event.error as typeof ErrorEvent.Type.error : event
|
||||
const json = JSON.stringify(error)
|
||||
return Effect.fail(
|
||||
AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method: "createResponseStream",
|
||||
reason: AiError.reasonFromHttpStatus({
|
||||
description: json,
|
||||
status: isNaN(status) ? errorTypeToStatus[error.type] ?? 500 : status,
|
||||
metadata: error as any,
|
||||
http: {
|
||||
body: json,
|
||||
request: {
|
||||
method: "POST",
|
||||
url: request.url,
|
||||
urlParams: [],
|
||||
hash: undefined,
|
||||
headers: request.headers
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
Queue.offerUnsafe(incoming, event)
|
||||
} catch {}
|
||||
}).pipe(
|
||||
Effect.catchTag("SocketError", (error) =>
|
||||
AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method: "createResponseStream",
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "TransportError",
|
||||
request: {
|
||||
method: "POST",
|
||||
url: request.url,
|
||||
urlParams: [],
|
||||
hash: undefined,
|
||||
headers: request.headers
|
||||
},
|
||||
description: error.message
|
||||
})
|
||||
})),
|
||||
Effect.catchCause((cause) => Queue.failCause(incoming, cause)),
|
||||
Effect.ensuring(Effect.forkIn(RcRef.invalidate(queueRef), socketScope, {
|
||||
startImmediately: true
|
||||
})),
|
||||
Effect.forkScoped({ startImmediately: true })
|
||||
)
|
||||
|
||||
return { send, incoming } as const
|
||||
})
|
||||
})
|
||||
|
||||
// Prime the websocket
|
||||
yield* Effect.scoped(RcRef.get(queueRef))
|
||||
|
||||
// Websocket mode only allows one request at a time
|
||||
const semaphore = Semaphore.makeUnsafe(1)
|
||||
const request = yield* makeRequest
|
||||
|
||||
return OpenAiSocket.context({
|
||||
createResponseStream(options) {
|
||||
const stream = Stream.unwrap(Effect.gen(function*() {
|
||||
const scope = yield* Effect.scope
|
||||
yield* Effect.acquireRelease(
|
||||
semaphore.take(1),
|
||||
() => semaphore.release(1),
|
||||
{ interruptible: true }
|
||||
)
|
||||
const { send, incoming } = yield* RcRef.get(queueRef)
|
||||
let done = false
|
||||
|
||||
yield* Scope.addFinalizerExit(
|
||||
scope,
|
||||
() => done ? Effect.void : RcRef.invalidate(queueRef)
|
||||
)
|
||||
|
||||
yield* send(options).pipe(
|
||||
Effect.forkScoped({ startImmediately: true })
|
||||
)
|
||||
|
||||
return Stream.fromQueue(incoming).pipe(
|
||||
Stream.takeUntil((e) => {
|
||||
done = e.type === "response.completed" || e.type === "response.incomplete"
|
||||
return done
|
||||
})
|
||||
)
|
||||
}))
|
||||
|
||||
return Effect.succeed([
|
||||
HttpClientResponse.fromWeb(request, new Response()),
|
||||
stream
|
||||
])
|
||||
}
|
||||
}).pipe(
|
||||
Context.add(ResponseIdTracker.ResponseIdTracker, tracker)
|
||||
)
|
||||
})
|
||||
|
||||
const ErrorEvent = Schema.Struct({
|
||||
type: Schema.Literal("error"),
|
||||
status: Schema.Number.pipe(
|
||||
Schema.withDecodingDefault(Effect.succeed(500))
|
||||
),
|
||||
error: Schema.Struct({
|
||||
type: Schema.String,
|
||||
message: Schema.String
|
||||
})
|
||||
})
|
||||
|
||||
const errorTypeToStatus: Record<string, number> = {
|
||||
invalid_request_error: 400,
|
||||
invalid_api_key_error: 401,
|
||||
insufficient_quota_error: 429,
|
||||
rate_limit_error: 429,
|
||||
service_unavailable_error: 503
|
||||
}
|
||||
|
||||
const AllEvents = Schema.Union([ErrorEvent, OpenAiSchema.ResponseStreamEvent])
|
||||
const decodeEvent = Schema.decodeUnknownSync(Schema.fromJsonString(AllEvents))
|
||||
|
||||
/**
|
||||
* Uses OpenAI's WebSocket mode for response streams within the provided effect.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to enable WebSocket mode around one effect that creates OpenAI response
|
||||
* streams.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* This only works with the following WebSocket constructor layers:
|
||||
*
|
||||
* - `NodeSocket.layerWebSocketConstructorWS`
|
||||
* - `BunSocket.layerWebSocketConstructor`
|
||||
*
|
||||
* These constructor layers support the non-standard options needed to set the
|
||||
* Authorization header.
|
||||
*
|
||||
* @see {@link layerWebSocketMode} for providing WebSocket mode through a layer
|
||||
* @see {@link OpenAiSocket} for direct access to the WebSocket-backed streaming service
|
||||
*
|
||||
* @category Websocket mode
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const withWebSocketMode = <A, E, R>(
|
||||
effect: Effect.Effect<A, E, R>
|
||||
): Effect.Effect<
|
||||
A,
|
||||
E,
|
||||
Exclude<R, OpenAiSocket | ResponseIdTracker.ResponseIdTracker> | OpenAiClient | Socket.WebSocketConstructor
|
||||
> =>
|
||||
Effect.scopedWith((scope) =>
|
||||
Effect.flatMap(
|
||||
Scope.provide(makeSocket, scope),
|
||||
(services) => Effect.provideContext(effect, services)
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* Uses OpenAI's websocket mode for all responses that use the Layer.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to provide WebSocket mode through layer composition for effects that use
|
||||
* OpenAI response streaming.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* This only works with the following WebSocket constructor layers:
|
||||
*
|
||||
* - `NodeSocket.layerWebSocketConstructorWS`
|
||||
* - `BunSocket.layerWebSocketConstructor`
|
||||
*
|
||||
* These constructor layers support the non-standard options needed to set the
|
||||
* Authorization header.
|
||||
*
|
||||
* @see {@link withWebSocketMode} for enabling WebSocket mode around a single effect
|
||||
*
|
||||
* @category Websocket mode
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const layerWebSocketMode: Layer.Layer<
|
||||
OpenAiSocket | ResponseIdTracker.ResponseIdTracker,
|
||||
never,
|
||||
OpenAiClient | Socket.WebSocketConstructor
|
||||
> = Layer.effectContext(makeSocket)
|
||||
202
repos/effect/packages/ai/openai/src/OpenAiClientGenerated.ts
Normal file
202
repos/effect/packages/ai/openai/src/OpenAiClientGenerated.ts
Normal file
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Array from "effect/Array"
|
||||
import type * as Config from "effect/Config"
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { identity } from "effect/Function"
|
||||
import * as Function from "effect/Function"
|
||||
import * as Layer from "effect/Layer"
|
||||
import * as Predicate from "effect/Predicate"
|
||||
import * as Redacted from "effect/Redacted"
|
||||
import * as Headers from "effect/unstable/http/Headers"
|
||||
import * as HttpClient from "effect/unstable/http/HttpClient"
|
||||
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
||||
import * as Generated from "./Generated.ts"
|
||||
import { OpenAiConfig } from "./OpenAiConfig.ts"
|
||||
|
||||
// =============================================================================
|
||||
// Service Identifier
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Service identifier for the generated OpenAI client.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @category service
|
||||
*/
|
||||
export class OpenAiClientGenerated extends Context.Service<OpenAiClientGenerated, Generated.OpenAiClient>()(
|
||||
"@effect/ai-openai/OpenAiClientGenerated"
|
||||
) {}
|
||||
|
||||
// =============================================================================
|
||||
// Options
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Options for configuring the generated OpenAI client.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @category options
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* The OpenAI API key.
|
||||
*/
|
||||
readonly apiKey?: Redacted.Redacted<string> | undefined
|
||||
|
||||
/**
|
||||
* The base URL for the OpenAI API.
|
||||
*
|
||||
* @default "https://api.openai.com/v1"
|
||||
*/
|
||||
readonly apiUrl?: string | undefined
|
||||
|
||||
/**
|
||||
* Optional organization ID for multi-org accounts.
|
||||
*/
|
||||
readonly organizationId?: Redacted.Redacted<string> | undefined
|
||||
|
||||
/**
|
||||
* Optional project ID for project-scoped requests.
|
||||
*/
|
||||
readonly projectId?: Redacted.Redacted<string> | undefined
|
||||
|
||||
/**
|
||||
* Optional transformer for the HTTP client.
|
||||
*/
|
||||
readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
|
||||
}
|
||||
|
||||
const RedactedOpenAiHeaders = {
|
||||
OpenAiOrganization: "OpenAI-Organization",
|
||||
OpenAiProject: "OpenAI-Project"
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Constructor
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Creates a generated OpenAI client service with the given options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @category constructors
|
||||
*/
|
||||
export const make = Effect.fnUntraced(
|
||||
function*(options: Options): Effect.fn.Return<Generated.OpenAiClient, never, HttpClient.HttpClient> {
|
||||
const baseClient = yield* HttpClient.HttpClient
|
||||
const apiUrl = options.apiUrl ?? "https://api.openai.com/v1"
|
||||
|
||||
const httpClient = baseClient.pipe(
|
||||
HttpClient.mapRequest(Function.flow(
|
||||
HttpClientRequest.prependUrl(apiUrl),
|
||||
options.apiKey
|
||||
? HttpClientRequest.bearerToken(Redacted.value(options.apiKey))
|
||||
: identity,
|
||||
options.organizationId
|
||||
? HttpClientRequest.setHeader(
|
||||
RedactedOpenAiHeaders.OpenAiOrganization,
|
||||
Redacted.value(options.organizationId)
|
||||
)
|
||||
: identity,
|
||||
options.projectId
|
||||
? HttpClientRequest.setHeader(
|
||||
RedactedOpenAiHeaders.OpenAiProject,
|
||||
Redacted.value(options.projectId)
|
||||
)
|
||||
: identity,
|
||||
HttpClientRequest.acceptJson
|
||||
)),
|
||||
options.transformClient
|
||||
? options.transformClient
|
||||
: identity
|
||||
)
|
||||
|
||||
return Generated.make(httpClient, {
|
||||
transformClient: Effect.fnUntraced(function*(client) {
|
||||
const config = yield* OpenAiConfig.getOrUndefined
|
||||
if (Predicate.isNotUndefined(config?.transformClient)) {
|
||||
return config.transformClient(client)
|
||||
}
|
||||
return client
|
||||
})
|
||||
})
|
||||
},
|
||||
Effect.updateService(
|
||||
Headers.CurrentRedactedNames,
|
||||
Array.appendAll(Object.values(RedactedOpenAiHeaders))
|
||||
)
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// Layers
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Creates a layer for the generated OpenAI client with the given options.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @category layers
|
||||
*/
|
||||
export const layer = (options: Options): Layer.Layer<OpenAiClientGenerated, never, HttpClient.HttpClient> =>
|
||||
Layer.effect(OpenAiClientGenerated, make(options))
|
||||
|
||||
/**
|
||||
* Creates a layer for the generated OpenAI client, loading the requisite
|
||||
* configuration via Effect's `Config` module.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @category layers
|
||||
*/
|
||||
export const layerConfig = (options?: {
|
||||
/**
|
||||
* The config value to load for the API key.
|
||||
*/
|
||||
readonly apiKey?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
|
||||
|
||||
/**
|
||||
* The config value to load for the API URL.
|
||||
*/
|
||||
readonly apiUrl?: Config.Config<string> | undefined
|
||||
|
||||
/**
|
||||
* The config value to load for the organization ID.
|
||||
*/
|
||||
readonly organizationId?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
|
||||
|
||||
/**
|
||||
* The config value to load for the project ID.
|
||||
*/
|
||||
readonly projectId?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
|
||||
|
||||
/**
|
||||
* Optional transformer for the HTTP client.
|
||||
*/
|
||||
readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
|
||||
}): Layer.Layer<OpenAiClientGenerated, Config.ConfigError, HttpClient.HttpClient> =>
|
||||
Layer.effect(
|
||||
OpenAiClientGenerated,
|
||||
Effect.gen(function*() {
|
||||
const apiKey = Predicate.isNotUndefined(options?.apiKey)
|
||||
? yield* options.apiKey :
|
||||
undefined
|
||||
const apiUrl = Predicate.isNotUndefined(options?.apiUrl)
|
||||
? yield* options.apiUrl :
|
||||
undefined
|
||||
const organizationId = Predicate.isNotUndefined(options?.organizationId)
|
||||
? yield* options.organizationId
|
||||
: undefined
|
||||
const projectId = Predicate.isNotUndefined(options?.projectId)
|
||||
? yield* options.projectId :
|
||||
undefined
|
||||
return yield* make({
|
||||
apiKey,
|
||||
apiUrl,
|
||||
organizationId,
|
||||
projectId,
|
||||
transformClient: options?.transformClient
|
||||
})
|
||||
})
|
||||
)
|
||||
93
repos/effect/packages/ai/openai/src/OpenAiConfig.ts
Normal file
93
repos/effect/packages/ai/openai/src/OpenAiConfig.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* The `OpenAiConfig` module lets a workflow temporarily customize the HTTP
|
||||
* client used by `@effect/ai-openai` request helpers. OpenAI client, language
|
||||
* model, and embedding code read this scoped transform when they execute
|
||||
* provider calls.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import type { HttpClient } from "effect/unstable/http/HttpClient"
|
||||
|
||||
/**
|
||||
* Context service for scoped OpenAI configuration used by provider operations.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to provide scoped OpenAI client configuration, such as an HTTP client
|
||||
* transform, to OpenAI provider operations without passing it through each call.
|
||||
*
|
||||
* @see {@link withClientTransform} for scoping an HTTP client transformation
|
||||
*
|
||||
* @category services
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class OpenAiConfig extends Context.Service<
|
||||
OpenAiConfig,
|
||||
OpenAiConfig.Service
|
||||
>()("@effect/ai-openai/OpenAiConfig") {
|
||||
/**
|
||||
* Gets the configured OpenAI service from the current context when present.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
static readonly getOrUndefined: Effect.Effect<typeof OpenAiConfig.Service | undefined> = Effect.map(
|
||||
Effect.context<never>(),
|
||||
(context) => context.mapUnsafe.get(OpenAiConfig.key)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Types used by the `OpenAiConfig` context service.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export declare namespace OpenAiConfig {
|
||||
/**
|
||||
* Configuration values read by OpenAI provider operations when executing
|
||||
* requests.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface Service {
|
||||
readonly transformClient?: ((client: HttpClient) => HttpClient) | undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a scoped transform for the OpenAI HTTP client used by provider
|
||||
* operations.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need temporary OpenAI HTTP client customization for a single
|
||||
* effect or workflow without rebuilding the client layer.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Supports both data-first and data-last forms. The transform is stored in the
|
||||
* scoped `OpenAiConfig` service and read by OpenAI provider operations while
|
||||
* running the supplied effect.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* If a transform is already present in the scoped config, this helper replaces
|
||||
* it. Compose transforms manually when both should apply.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const withClientTransform: {
|
||||
(transform: (client: HttpClient) => HttpClient): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
|
||||
<A, E, R>(self: Effect.Effect<A, E, R>, transform: (client: HttpClient) => HttpClient): Effect.Effect<A, E, R>
|
||||
} = dual(2, <A, E, R>(
|
||||
self: Effect.Effect<A, E, R>,
|
||||
transformClient: (client: HttpClient) => HttpClient
|
||||
) =>
|
||||
Effect.flatMap(
|
||||
OpenAiConfig.getOrUndefined,
|
||||
(config) => Effect.provideService(self, OpenAiConfig, { ...config, transformClient })
|
||||
))
|
||||
258
repos/effect/packages/ai/openai/src/OpenAiEmbeddingModel.ts
Normal file
258
repos/effect/packages/ai/openai/src/OpenAiEmbeddingModel.ts
Normal file
@@ -0,0 +1,258 @@
|
||||
/**
|
||||
* The `OpenAiEmbeddingModel` module provides the OpenAI implementation of
|
||||
* Effect AI's `EmbeddingModel` service. It sends embedding requests through
|
||||
* `OpenAiClient`, exposes constructors for layers and `AiModel` values,
|
||||
* supports scoped request configuration overrides, and checks that OpenAI
|
||||
* returns one numeric vector for each requested input.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import * as Layer from "effect/Layer"
|
||||
import type { Simplify } from "effect/Types"
|
||||
import * as AiError from "effect/unstable/ai/AiError"
|
||||
import * as EmbeddingModel from "effect/unstable/ai/EmbeddingModel"
|
||||
import * as AiModel from "effect/unstable/ai/Model"
|
||||
import { OpenAiClient } from "./OpenAiClient.ts"
|
||||
import type * as OpenAiSchema from "./OpenAiSchema.ts"
|
||||
|
||||
/**
|
||||
* Model identifiers supported by OpenAI's embeddings API.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type Model = "text-embedding-ada-002" | "text-embedding-3-small" | "text-embedding-3-large"
|
||||
|
||||
/**
|
||||
* Context service for OpenAI embedding model configuration.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need scoped OpenAI request defaults or overrides for embedding
|
||||
* requests from Effect context.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The service stores the OpenAI create-embedding request payload without
|
||||
* `input`, carrying options such as `model`, `dimensions`, `encoding_format`,
|
||||
* and `user`.
|
||||
*
|
||||
* @see {@link withConfigOverride} for scoping embedding request overrides
|
||||
*
|
||||
* @category services
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class Config extends Context.Service<
|
||||
Config,
|
||||
Simplify<
|
||||
& Partial<
|
||||
Omit<
|
||||
typeof OpenAiSchema.CreateEmbeddingRequest.Encoded,
|
||||
"input"
|
||||
>
|
||||
>
|
||||
& {
|
||||
readonly [x: string]: unknown
|
||||
}
|
||||
>
|
||||
>()("@effect/ai-openai/OpenAiEmbeddingModel/Config") {}
|
||||
|
||||
/**
|
||||
* Creates an `AiModel` for an OpenAI embedding model with its configured vector dimensions.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to provide an OpenAI `EmbeddingModel` and its `Dimensions` service to an
|
||||
* Effect program.
|
||||
*
|
||||
* @see {@link layer} for providing only the embedding model service
|
||||
* @see {@link withConfigOverride} for scoped request configuration overrides
|
||||
*
|
||||
* @category constructors
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const model = (
|
||||
model: (string & {}) | Model,
|
||||
options: {
|
||||
readonly dimensions: number
|
||||
readonly config?: Omit<typeof Config.Service, "model" | "dimensions">
|
||||
}
|
||||
): AiModel.Model<"openai", EmbeddingModel.EmbeddingModel | EmbeddingModel.Dimensions, OpenAiClient> =>
|
||||
AiModel.make(
|
||||
"openai",
|
||||
model,
|
||||
Layer.merge(
|
||||
layer({
|
||||
model,
|
||||
config: {
|
||||
...options.config,
|
||||
dimensions: options.dimensions
|
||||
}
|
||||
}),
|
||||
Layer.succeed(EmbeddingModel.Dimensions, options.dimensions)
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* Creates an OpenAI embedding model service.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to construct the `EmbeddingModel.Service` effectfully when
|
||||
* `OpenAiClient` is already available in the environment.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The `model` option is sent with each embedding request. Constructor `config`
|
||||
* supplies create-embedding request fields other than `model` and `input`, and
|
||||
* scoped overrides from `withConfigOverride` are merged last for each request.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* The service expects numeric embedding vectors. It fails with
|
||||
* `InvalidOutputError` when the provider returns base64 embeddings,
|
||||
* out-of-range indexes, duplicate indexes, or an unexpected number of
|
||||
* embeddings.
|
||||
*
|
||||
* @see {@link layer} for providing the embedding model service as a layer
|
||||
* @see {@link model} for creating an `AiModel` that also provides dimensions
|
||||
* @see {@link withConfigOverride} for scoped request configuration overrides
|
||||
*
|
||||
* @category constructors
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const make = Effect.fnUntraced(function*({ model, config: providerConfig }: {
|
||||
readonly model: (string & {}) | Model
|
||||
readonly config?: Omit<typeof Config.Service, "model"> | undefined
|
||||
}): Effect.fn.Return<EmbeddingModel.Service, never, OpenAiClient> {
|
||||
const client = yield* OpenAiClient
|
||||
|
||||
const makeConfig = Effect.gen(function*() {
|
||||
const services = yield* Effect.context<never>()
|
||||
return { model, ...providerConfig, ...services.mapUnsafe.get(Config.key) }
|
||||
})
|
||||
|
||||
return yield* EmbeddingModel.make({
|
||||
embedMany: Effect.fnUntraced(function*({ inputs }) {
|
||||
const config = yield* makeConfig
|
||||
const response = yield* client.createEmbedding({ ...config, input: inputs })
|
||||
return yield* mapProviderResponse(inputs.length, response)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Creates a layer for the OpenAI embedding model.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when composing application layers and you want OpenAI to satisfy
|
||||
* `EmbeddingModel.EmbeddingModel` while supplying `OpenAiClient` from another
|
||||
* layer.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* Use the default floating-point embedding format. The service expects numeric
|
||||
* vectors and fails with `InvalidOutputError` if OpenAI returns base64
|
||||
* embeddings.
|
||||
*
|
||||
* @see {@link make} for constructing the embedding model service effectfully
|
||||
* @see {@link model} for creating an `AiModel` that also provides embedding dimensions
|
||||
*
|
||||
* @category layers
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const layer = (options: {
|
||||
readonly model: (string & {}) | Model
|
||||
readonly config?: Omit<typeof Config.Service, "model"> | undefined
|
||||
}): Layer.Layer<EmbeddingModel.EmbeddingModel, never, OpenAiClient> =>
|
||||
Layer.effect(EmbeddingModel.EmbeddingModel, make(options))
|
||||
|
||||
/**
|
||||
* Provides config overrides for OpenAI embedding model operations.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need scoped OpenAI embedding request defaults for a single
|
||||
* effect or workflow without rebuilding the embedding model service.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Supports both data-first and data-last forms. Existing scoped config is read
|
||||
* first, then the provided overrides are applied so override fields take
|
||||
* precedence.
|
||||
*
|
||||
* @see {@link Config} for the scoped embedding request configuration service
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const withConfigOverride: {
|
||||
(overrides: typeof Config.Service): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Config>>
|
||||
<A, E, R>(self: Effect.Effect<A, E, R>, overrides: typeof Config.Service): Effect.Effect<A, E, Exclude<R, Config>>
|
||||
} = dual<
|
||||
(
|
||||
overrides: typeof Config.Service
|
||||
) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Config>>,
|
||||
<A, E, R>(self: Effect.Effect<A, E, R>, overrides: typeof Config.Service) => Effect.Effect<A, E, Exclude<R, Config>>
|
||||
>(2, (self, overrides) =>
|
||||
Effect.flatMap(
|
||||
Effect.serviceOption(Config),
|
||||
(config) =>
|
||||
Effect.provideService(self, Config, {
|
||||
...(config._tag === "Some" ? config.value : {}),
|
||||
...overrides
|
||||
})
|
||||
))
|
||||
|
||||
const mapProviderResponse = (
|
||||
inputLength: number,
|
||||
response: typeof OpenAiSchema.CreateEmbeddingResponse.Type
|
||||
): Effect.Effect<EmbeddingModel.ProviderResponse, AiError.AiError> => {
|
||||
if (response.data.length !== inputLength) {
|
||||
return Effect.fail(
|
||||
invalidOutput("Provider returned " + response.data.length + " embeddings but expected " + inputLength)
|
||||
)
|
||||
}
|
||||
|
||||
const results = new Array<Array<number>>(inputLength)
|
||||
const seen = new Set<number>()
|
||||
|
||||
for (const entry of response.data) {
|
||||
if (!Number.isInteger(entry.index) || entry.index < 0 || entry.index >= inputLength) {
|
||||
return Effect.fail(invalidOutput("Provider returned invalid embedding index: " + entry.index))
|
||||
}
|
||||
if (seen.has(entry.index)) {
|
||||
return Effect.fail(invalidOutput("Provider returned duplicate embedding index: " + entry.index))
|
||||
}
|
||||
if (!Array.isArray(entry.embedding)) {
|
||||
return Effect.fail(invalidOutput("Provider returned non-vector embedding at index " + entry.index))
|
||||
}
|
||||
|
||||
seen.add(entry.index)
|
||||
results[entry.index] = [...entry.embedding]
|
||||
}
|
||||
|
||||
if (seen.size !== inputLength) {
|
||||
return Effect.fail(
|
||||
invalidOutput("Provider returned embeddings for " + seen.size + " inputs but expected " + inputLength)
|
||||
)
|
||||
}
|
||||
|
||||
return Effect.succeed({
|
||||
results,
|
||||
usage: {
|
||||
inputTokens: response.usage?.prompt_tokens
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const invalidOutput = (description: string): AiError.AiError =>
|
||||
AiError.make({
|
||||
module: "OpenAiEmbeddingModel",
|
||||
method: "embedMany",
|
||||
reason: new AiError.InvalidOutputError({ description })
|
||||
})
|
||||
242
repos/effect/packages/ai/openai/src/OpenAiError.ts
Normal file
242
repos/effect/packages/ai/openai/src/OpenAiError.ts
Normal file
@@ -0,0 +1,242 @@
|
||||
/**
|
||||
* OpenAI error metadata augmentation.
|
||||
*
|
||||
* Provides OpenAI-specific metadata fields for AI error types through module
|
||||
* augmentation, enabling typed access to OpenAI error details.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* OpenAI-specific error metadata fields.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenAiErrorMetadata = {
|
||||
/**
|
||||
* The OpenAI error code returned by the API.
|
||||
*/
|
||||
readonly errorCode: string | null
|
||||
/**
|
||||
* The OpenAI error type returned by the API.
|
||||
*/
|
||||
readonly errorType: string | null
|
||||
/**
|
||||
* The unique request ID for debugging with OpenAI support.
|
||||
*/
|
||||
readonly requestId: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI-specific rate limit metadata fields.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Extends base error metadata with rate limit specific information from
|
||||
* OpenAI's rate limit headers.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenAiRateLimitMetadata = OpenAiErrorMetadata & {
|
||||
/**
|
||||
* The rate limit type (e.g. "requests", "tokens").
|
||||
*/
|
||||
readonly limit: string | null
|
||||
/**
|
||||
* Number of remaining requests in the current window.
|
||||
*/
|
||||
readonly remaining: number | null
|
||||
/**
|
||||
* Time until the request rate limit resets.
|
||||
*/
|
||||
readonly resetRequests: string | null
|
||||
/**
|
||||
* Time until the token rate limit resets.
|
||||
*/
|
||||
readonly resetTokens: string | null
|
||||
}
|
||||
|
||||
declare module "effect/unstable/ai/AiError" {
|
||||
/**
|
||||
* OpenAI metadata attached to `RateLimitError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Captures OpenAI error details together with rate limit header information
|
||||
* from responses where the provider rejected the request because a limit was
|
||||
* reached.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface RateLimitErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the rate limit response.
|
||||
*/
|
||||
readonly openai?: OpenAiRateLimitMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI metadata attached to `QuotaExhaustedError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for failures caused by exhausted account,
|
||||
* billing, or usage quota.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface QuotaExhaustedErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the quota exhaustion response.
|
||||
*/
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI metadata attached to `AuthenticationError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for failed API key, authorization, or
|
||||
* permission checks.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface AuthenticationErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the authentication failure.
|
||||
*/
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI metadata attached to `ContentPolicyError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details when OpenAI rejects input or output because
|
||||
* it violates a content policy.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface ContentPolicyErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the content policy response.
|
||||
*/
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI metadata attached to `InvalidRequestError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for malformed requests, unsupported
|
||||
* parameters, or other request validation failures reported by OpenAI.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InvalidRequestErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the invalid request response.
|
||||
*/
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI metadata attached to `InternalProviderError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for OpenAI-side failures such as transient
|
||||
* server errors.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InternalProviderErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the internal provider response.
|
||||
*/
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI metadata attached to `InvalidOutputError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details when an OpenAI response cannot be parsed or
|
||||
* validated as the expected output.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InvalidOutputErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the invalid output response.
|
||||
*/
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI metadata attached to `StructuredOutputError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details when OpenAI returns content that does not
|
||||
* satisfy the requested structured output schema.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface StructuredOutputErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the structured output failure.
|
||||
*/
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI metadata attached to `UnsupportedSchemaError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details when an unsupported schema failure is
|
||||
* associated with an OpenAI response.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface UnsupportedSchemaErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the unsupported schema failure.
|
||||
*/
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAI metadata attached to `UnknownError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for OpenAI failures that do not map cleanly
|
||||
* to a more specific AI error category.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface UnknownErrorMetadata {
|
||||
/**
|
||||
* OpenAI-specific details for the unclassified provider failure.
|
||||
*/
|
||||
readonly openai?: OpenAiErrorMetadata | null
|
||||
}
|
||||
}
|
||||
3133
repos/effect/packages/ai/openai/src/OpenAiLanguageModel.ts
Normal file
3133
repos/effect/packages/ai/openai/src/OpenAiLanguageModel.ts
Normal file
File diff suppressed because it is too large
Load Diff
1286
repos/effect/packages/ai/openai/src/OpenAiSchema.ts
Normal file
1286
repos/effect/packages/ai/openai/src/OpenAiSchema.ts
Normal file
File diff suppressed because it is too large
Load Diff
162
repos/effect/packages/ai/openai/src/OpenAiTelemetry.ts
Normal file
162
repos/effect/packages/ai/openai/src/OpenAiTelemetry.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* The `OpenAiTelemetry` module defines OpenAI-specific telemetry attributes
|
||||
* and a helper for adding them to a tracing span. It keeps the standard GenAI
|
||||
* telemetry attributes and adds request and response metadata, such as response
|
||||
* format, service tier, and system fingerprint, under the `gen_ai.openai.*`
|
||||
* OpenTelemetry namespaces.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import { dual } from "effect/Function"
|
||||
import * as String from "effect/String"
|
||||
import type { Span } from "effect/Tracer"
|
||||
import type { Simplify } from "effect/Types"
|
||||
import * as Telemetry from "effect/unstable/ai/Telemetry"
|
||||
|
||||
/**
|
||||
* The attributes used to describe telemetry in the context of Generative
|
||||
* Artificial Intelligence (GenAI) Models requests and responses.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* These attributes follow the OpenTelemetry generative AI semantic
|
||||
* conventions:
|
||||
* https://opentelemetry.io/docs/specs/semconv/attributes-registry/gen-ai/
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenAiTelemetryAttributes = Simplify<
|
||||
& Telemetry.GenAITelemetryAttributes
|
||||
& Telemetry.AttributesWithPrefix<RequestAttributes, "gen_ai.openai.request">
|
||||
& Telemetry.AttributesWithPrefix<ResponseAttributes, "gen_ai.openai.request">
|
||||
>
|
||||
|
||||
/**
|
||||
* All telemetry attributes which are part of the GenAI specification,
|
||||
* including the OpenAI-specific attributes.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type AllAttributes = Telemetry.AllAttributes & RequestAttributes & ResponseAttributes
|
||||
|
||||
/**
|
||||
* Telemetry attributes which are part of the GenAI specification and are
|
||||
* namespaced by `gen_ai.openai.request`.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface RequestAttributes {
|
||||
/**
|
||||
* The response format that is requested.
|
||||
*/
|
||||
readonly responseFormat?: (string & {}) | WellKnownResponseFormat | null | undefined
|
||||
/**
|
||||
* The service tier requested. May be a specific tier, `default`, or `auto`.
|
||||
*/
|
||||
readonly serviceTier?: (string & {}) | WellKnownServiceTier | null | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Telemetry attributes which are part of the GenAI specification and are
|
||||
* namespaced by `gen_ai.openai.response`.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface ResponseAttributes {
|
||||
/**
|
||||
* The service tier used for the response.
|
||||
*/
|
||||
readonly serviceTier?: string | null | undefined
|
||||
/**
|
||||
* A fingerprint to track any eventual change in the Generative AI
|
||||
* environment.
|
||||
*/
|
||||
readonly systemFingerprint?: string | null | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gen_ai.openai.request.response_format` attribute has the following
|
||||
* list of well-known values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* If one of them applies, then the respective value **MUST** be used;
|
||||
* otherwise, a custom value **MAY** be used.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type WellKnownResponseFormat = "json_object" | "json_schema" | "text"
|
||||
|
||||
/**
|
||||
* The `gen_ai.openai.request.service_tier` attribute has the following
|
||||
* list of well-known values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* If one of them applies, then the respective value **MUST** be used;
|
||||
* otherwise, a custom value **MAY** be used.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type WellKnownServiceTier = "auto" | "default"
|
||||
|
||||
/**
|
||||
* Options accepted by `addGenAIAnnotations`, combining standard GenAI
|
||||
* telemetry attributes with optional OpenAI request and response attributes.
|
||||
*
|
||||
* @category options
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenAiTelemetryAttributeOptions = Telemetry.GenAITelemetryAttributeOptions & {
|
||||
openai?: {
|
||||
request?: RequestAttributes | undefined
|
||||
response?: ResponseAttributes | undefined
|
||||
} | undefined
|
||||
}
|
||||
|
||||
const addOpenAiRequestAttributes = Telemetry.addSpanAttributes("gen_ai.openai.request", String.camelToSnake)<
|
||||
RequestAttributes
|
||||
>
|
||||
const addOpenAiResponseAttributes = Telemetry.addSpanAttributes("gen_ai.openai.response", String.camelToSnake)<
|
||||
ResponseAttributes
|
||||
>
|
||||
|
||||
/**
|
||||
* Applies the specified OpenAI GenAI telemetry attributes to the provided
|
||||
* `Span`.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to annotate an existing OpenTelemetry span with standard GenAI attributes
|
||||
* plus OpenAI-specific request and response metadata.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* Mutates the supplied `Span` in place.
|
||||
*
|
||||
* @see {@link OpenAiTelemetryAttributeOptions} for the accepted telemetry attributes
|
||||
* @see {@link Telemetry.addGenAIAnnotations} for the provider-neutral annotation helper
|
||||
*
|
||||
* @category tracing
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const addGenAIAnnotations: {
|
||||
(options: OpenAiTelemetryAttributeOptions): (span: Span) => void
|
||||
(span: Span, options: OpenAiTelemetryAttributeOptions): void
|
||||
} = dual(2, (span: Span, options: OpenAiTelemetryAttributeOptions) => {
|
||||
Telemetry.addGenAIAnnotations(span, options)
|
||||
if (options.openai != null) {
|
||||
if (options.openai.request != null) {
|
||||
addOpenAiRequestAttributes(span, options.openai.request)
|
||||
}
|
||||
if (options.openai.response != null) {
|
||||
addOpenAiResponseAttributes(span, options.openai.response)
|
||||
}
|
||||
}
|
||||
})
|
||||
342
repos/effect/packages/ai/openai/src/OpenAiTool.ts
Normal file
342
repos/effect/packages/ai/openai/src/OpenAiTool.ts
Normal file
@@ -0,0 +1,342 @@
|
||||
/**
|
||||
* The `OpenAiTool` module defines OpenAI provider tools for Effect AI language
|
||||
* model requests. It exposes typed descriptors for tools such as Apply Patch,
|
||||
* Code Interpreter, File Search, Image Generation, MCP, Web Search, and
|
||||
* shell-like local tools, including their provider names, configuration
|
||||
* arguments, call parameters, success schemas, and handler requirements.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Schema from "effect/Schema"
|
||||
import * as Tool from "effect/unstable/ai/Tool"
|
||||
import * as Generated from "./Generated.ts"
|
||||
|
||||
/**
|
||||
* Union of all OpenAI provider-defined tools.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenAiTool =
|
||||
| ReturnType<typeof ApplyPatch>
|
||||
| ReturnType<typeof CodeInterpreter>
|
||||
| ReturnType<typeof FileSearch>
|
||||
| ReturnType<typeof Shell>
|
||||
| ReturnType<typeof ImageGeneration>
|
||||
| ReturnType<typeof LocalShell>
|
||||
| ReturnType<typeof Mcp>
|
||||
| ReturnType<typeof WebSearch>
|
||||
| ReturnType<typeof WebSearchPreview>
|
||||
|
||||
/**
|
||||
* Defines the OpenAI Apply Patch tool that allows the model to apply diffs by creating,
|
||||
* deleting, or updating files. This local tool runs in your environment and
|
||||
* requires a handler to execute file operations.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you want an OpenAI model to request structured file edits as create,
|
||||
* delete, or update operations that your application executes through a local
|
||||
* handler.
|
||||
*
|
||||
* @category tools
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const ApplyPatch = Tool.providerDefined({
|
||||
id: "openai.apply_patch",
|
||||
customName: "OpenAiApplyPatch",
|
||||
providerName: "apply_patch",
|
||||
requiresHandler: true,
|
||||
parameters: Schema.Struct({
|
||||
call_id: Generated.ApplyPatchToolCall.fields.call_id,
|
||||
operation: Generated.ApplyPatchToolCall.fields.operation
|
||||
}),
|
||||
success: Schema.Struct({
|
||||
status: Generated.ApplyPatchToolCallOutput.fields.status,
|
||||
output: Generated.ApplyPatchToolCallOutput.fields.output
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Defines the OpenAI Code Interpreter tool that allows the model to execute Python code in
|
||||
* a sandboxed environment.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to enable OpenAI-hosted Python execution for a model response.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The tool is configured with a `container` argument. Successful tool calls
|
||||
* expose `outputs`, which may contain logs or generated images, or `null` when
|
||||
* no outputs are available.
|
||||
*
|
||||
* @category tools
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const CodeInterpreter = Tool.providerDefined({
|
||||
id: "openai.code_interpreter",
|
||||
customName: "OpenAiCodeInterpreter",
|
||||
providerName: "code_interpreter",
|
||||
args: Schema.Struct({
|
||||
container: Generated.CodeInterpreterTool.fields.container
|
||||
}),
|
||||
parameters: Schema.Struct({
|
||||
code: Generated.CodeInterpreterToolCall.fields.code,
|
||||
container_id: Generated.CodeInterpreterToolCall.fields.container_id
|
||||
}),
|
||||
success: Schema.Struct({
|
||||
outputs: Generated.CodeInterpreterToolCall.fields.outputs
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Defines the OpenAI File Search tool that enables the model to search through uploaded
|
||||
* files and vector stores.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to let an OpenAI model search uploaded files through one or more vector
|
||||
* stores.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The tool requires `vector_store_ids` and accepts optional `filters`,
|
||||
* `max_num_results`, and `ranking_options`. Successful tool calls expose the
|
||||
* search `status`, generated `queries`, and optional `results`.
|
||||
*
|
||||
* @category tools
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const FileSearch = Tool.providerDefined({
|
||||
id: "openai.file_search",
|
||||
customName: "OpenAiFileSearch",
|
||||
providerName: "file_search",
|
||||
args: Schema.Struct({
|
||||
filters: Generated.FileSearchTool.fields.filters,
|
||||
max_num_results: Generated.FileSearchTool.fields.max_num_results,
|
||||
ranking_options: Generated.FileSearchTool.fields.ranking_options,
|
||||
vector_store_ids: Generated.FileSearchTool.fields.vector_store_ids
|
||||
}),
|
||||
success: Schema.Struct({
|
||||
status: Generated.FileSearchToolCall.fields.status,
|
||||
queries: Generated.FileSearchToolCall.fields.queries,
|
||||
results: Generated.FileSearchToolCall.fields.results
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Defines the OpenAI Image Generation tool that enables the model to generate images using
|
||||
* the GPT image models.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to enable OpenAI provider-defined image generation through a language
|
||||
* model response.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The tool configures the `image_generation` provider tool, including model,
|
||||
* size, quality, output format, moderation, background, input-image options,
|
||||
* and partial image settings. Successful tool calls expose `result` as base64
|
||||
* image data or `null`.
|
||||
*
|
||||
* @category tools
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const ImageGeneration = Tool.providerDefined({
|
||||
id: "openai.image_generation",
|
||||
customName: "OpenAiImageGeneration",
|
||||
providerName: "image_generation",
|
||||
args: Schema.Struct({
|
||||
background: Generated.ImageGenTool.fields.background,
|
||||
input_fidelity: Generated.ImageGenTool.fields.input_fidelity,
|
||||
input_image_mask: Generated.ImageGenTool.fields.input_image_mask,
|
||||
model: Generated.ImageGenTool.fields.model,
|
||||
moderation: Generated.ImageGenTool.fields.moderation,
|
||||
output_compression: Generated.ImageGenTool.fields.output_compression,
|
||||
output_format: Generated.ImageGenTool.fields.output_format,
|
||||
partial_images: Generated.ImageGenTool.fields.partial_images,
|
||||
quality: Generated.ImageGenTool.fields.quality,
|
||||
size: Generated.ImageGenTool.fields.size
|
||||
}),
|
||||
success: Schema.Struct({
|
||||
result: Generated.ImageGenToolCall.fields.result
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Defines the OpenAI Local Shell tool that enables the model to run a command with a local
|
||||
* shell. This local tool runs in your environment and requires a handler to
|
||||
* execute commands.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to let an OpenAI model request local shell commands that your application
|
||||
* executes through a handler.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The tool exposes a provider-defined `local_shell` call. It is marked as
|
||||
* handler-required, so applications must provide the command execution policy
|
||||
* and implementation.
|
||||
*
|
||||
* @category tools
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const LocalShell = Tool.providerDefined({
|
||||
id: "openai.local_shell",
|
||||
customName: "OpenAiLocalShell",
|
||||
providerName: "local_shell",
|
||||
requiresHandler: true,
|
||||
parameters: Schema.Struct({
|
||||
action: Generated.LocalShellToolCall.fields.action
|
||||
}),
|
||||
success: Schema.Struct({
|
||||
output: Generated.LocalShellToolCallOutput.fields.output
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Defines the OpenAI MCP tool that gives the model access to additional tools via remote
|
||||
* Model Context Protocol (MCP) servers.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to let an OpenAI model call tools exposed by a remote MCP server.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The tool accepts MCP server configuration such as allowed tools,
|
||||
* authorization, connector id, approval requirements, server metadata, and
|
||||
* server URL. Tool call results include the called tool name, arguments, output,
|
||||
* error, and server label.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* This schema leaves both `server_url` and `connector_id` optional, but OpenAI
|
||||
* may require a server URL or connector id for a usable MCP tool configuration.
|
||||
*
|
||||
* @category tools
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const Mcp = Tool.providerDefined({
|
||||
id: "openai.mcp",
|
||||
customName: "OpenAiMcp",
|
||||
providerName: "mcp",
|
||||
args: Schema.Struct({
|
||||
allowed_tools: Generated.MCPTool.fields.allowed_tools,
|
||||
authorization: Generated.MCPTool.fields.authorization,
|
||||
connector_id: Generated.MCPTool.fields.connector_id,
|
||||
require_approval: Generated.MCPTool.fields.require_approval,
|
||||
server_description: Generated.MCPTool.fields.server_description,
|
||||
server_label: Generated.MCPTool.fields.server_label,
|
||||
server_url: Generated.MCPTool.fields.server_url
|
||||
}),
|
||||
parameters: Schema.Unknown,
|
||||
success: Schema.Struct({
|
||||
type: Generated.MCPToolCall.fields.type,
|
||||
name: Generated.MCPToolCall.fields.name,
|
||||
arguments: Generated.MCPToolCall.fields.arguments,
|
||||
output: Generated.MCPToolCall.fields.output,
|
||||
error: Generated.MCPToolCall.fields.error,
|
||||
server_label: Generated.MCPToolCall.fields.server_label
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Defines the OpenAI shell tool for model-requested command execution.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to let an OpenAI model request shell commands that your application
|
||||
* executes through a handler.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The tool exposes a provider-defined `shell` call. It is marked as
|
||||
* handler-required, so applications must provide the command execution policy
|
||||
* and implementation.
|
||||
*
|
||||
* @category tools
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const Shell = Tool.providerDefined({
|
||||
id: "openai.shell",
|
||||
customName: "OpenAiShell",
|
||||
providerName: "shell",
|
||||
requiresHandler: true,
|
||||
parameters: Schema.Struct({
|
||||
action: Generated.FunctionShellCall.fields.action
|
||||
}),
|
||||
success: Schema.Struct({
|
||||
output: Generated.FunctionShellCallOutput.fields.output
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Defines the OpenAI Web Search tool that enables the model to search the web for
|
||||
* information.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to enable OpenAI provider-defined web search for a model response.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The tool accepts optional filters, user location, and search context size.
|
||||
* Successful calls expose the performed search action and status.
|
||||
*
|
||||
* @see {@link WebSearchPreview} for the preview web search provider tool
|
||||
*
|
||||
* @category tools
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const WebSearch = Tool.providerDefined({
|
||||
id: "openai.web_search",
|
||||
customName: "OpenAiWebSearch",
|
||||
providerName: "web_search",
|
||||
args: Schema.Struct({
|
||||
filters: Generated.WebSearchTool.fields.filters,
|
||||
user_location: Generated.WebSearchTool.fields.user_location,
|
||||
search_context_size: Generated.WebSearchTool.fields.search_context_size
|
||||
}),
|
||||
parameters: Schema.Struct({
|
||||
action: Generated.WebSearchToolCall.fields.action
|
||||
}),
|
||||
success: Schema.Struct({
|
||||
action: Generated.WebSearchToolCall.fields.action,
|
||||
status: Generated.WebSearchToolCall.fields.status
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Defines the OpenAI preview Web Search tool for model responses.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to enable the preview OpenAI web search provider tool.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The preview tool accepts optional user location and search context size, then
|
||||
* exposes the performed search action and status in successful calls.
|
||||
*
|
||||
* @see {@link WebSearch} for the stable web search provider tool
|
||||
*
|
||||
* @category tools
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const WebSearchPreview = Tool.providerDefined({
|
||||
id: "openai.web_search_preview",
|
||||
customName: "OpenAiWebSearchPreview",
|
||||
providerName: "web_search_preview",
|
||||
args: Schema.Struct({
|
||||
user_location: Generated.WebSearchPreviewTool.fields.user_location,
|
||||
search_context_size: Generated.WebSearchPreviewTool.fields.search_context_size
|
||||
}),
|
||||
success: Schema.Struct({
|
||||
action: Generated.WebSearchToolCall.fields.action,
|
||||
status: Generated.WebSearchToolCall.fields.status
|
||||
})
|
||||
})
|
||||
55
repos/effect/packages/ai/openai/src/index.ts
Normal file
55
repos/effect/packages/ai/openai/src/index.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
// @barrel: Auto-generated exports. Do not edit manually.
|
||||
|
||||
/**
|
||||
* @since 1.0.0
|
||||
*/
|
||||
export * as Generated from "./Generated.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiClient from "./OpenAiClient.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiClientGenerated from "./OpenAiClientGenerated.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiConfig from "./OpenAiConfig.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiEmbeddingModel from "./OpenAiEmbeddingModel.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiError from "./OpenAiError.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiLanguageModel from "./OpenAiLanguageModel.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiSchema from "./OpenAiSchema.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiTelemetry from "./OpenAiTelemetry.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenAiTool from "./OpenAiTool.ts"
|
||||
349
repos/effect/packages/ai/openai/src/internal/errors.ts
Normal file
349
repos/effect/packages/ai/openai/src/internal/errors.ts
Normal file
@@ -0,0 +1,349 @@
|
||||
import * as Duration from "effect/Duration"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import * as Number from "effect/Number"
|
||||
import * as Option from "effect/Option"
|
||||
import * as Predicate from "effect/Predicate"
|
||||
import * as Redactable from "effect/Redactable"
|
||||
import * as Schema from "effect/Schema"
|
||||
import * as AiError from "effect/unstable/ai/AiError"
|
||||
import type * as Response from "effect/unstable/ai/Response"
|
||||
import type * as HttpClientError from "effect/unstable/http/HttpClientError"
|
||||
import type * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
||||
import type * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
|
||||
import type { OpenAiErrorMetadata } from "../OpenAiError.ts"
|
||||
|
||||
// =============================================================================
|
||||
// OpenAI Error Body Schema
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const OpenAiErrorBody = Schema.Struct({
|
||||
error: Schema.Struct({
|
||||
message: Schema.String,
|
||||
type: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
param: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
code: Schema.optional(Schema.NullOr(Schema.String))
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================================================
|
||||
// Error Mappers
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const mapSchemaError = dual<
|
||||
(method: string) => (error: Schema.SchemaError) => AiError.AiError,
|
||||
(error: Schema.SchemaError, method: string) => AiError.AiError
|
||||
>(2, (error, method) =>
|
||||
AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: AiError.InvalidOutputError.fromSchemaError(error)
|
||||
}))
|
||||
|
||||
/** @internal */
|
||||
export const mapHttpClientError = dual<
|
||||
(method: string) => (error: HttpClientError.HttpClientError) => Effect.Effect<never, AiError.AiError>,
|
||||
(error: HttpClientError.HttpClientError, method: string) => Effect.Effect<never, AiError.AiError>
|
||||
>(2, (error, method) => {
|
||||
const reason = error.reason
|
||||
switch (reason._tag) {
|
||||
case "TransportError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "TransportError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "EncodeError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "EncodeError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "InvalidUrlError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "InvalidUrlError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "StatusCodeError": {
|
||||
return mapStatusCodeError(reason, method)
|
||||
}
|
||||
case "DecodeError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.InvalidOutputError({
|
||||
description: reason.description ?? "Failed to decode response"
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "EmptyBodyError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenAiClient",
|
||||
method,
|
||||
reason: new AiError.InvalidOutputError({
|
||||
description: reason.description ?? "Response body was empty"
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
const mapStatusCodeError = Effect.fnUntraced(function*(
|
||||
error: HttpClientError.StatusCodeError,
|
||||
method: string
|
||||
) {
|
||||
const { request, response, description } = error
|
||||
const status = response.status
|
||||
const headers = response.headers as Record<string, string>
|
||||
const requestId = headers["x-request-id"]
|
||||
|
||||
// Try to get the actual response body. The description from filterStatusOk
|
||||
// is often just "non 2xx status code", so try reading from response.text
|
||||
let body: string | undefined = description
|
||||
if (!description || !description.startsWith("{")) {
|
||||
const responseBody = yield* Effect.option(response.text)
|
||||
if (Option.isSome(responseBody) && responseBody.value) {
|
||||
body = responseBody.value
|
||||
}
|
||||
}
|
||||
|
||||
// Try to parse the body as JSON to extract error details
|
||||
let json: unknown = undefined
|
||||
// @effect-diagnostics effect/tryCatchInEffectGen:off
|
||||
try {
|
||||
json = Predicate.isNotUndefined(body) ? JSON.parse(body) : undefined
|
||||
} catch {
|
||||
json = undefined
|
||||
}
|
||||
const decoded = Schema.decodeUnknownOption(OpenAiErrorBody)(json)
|
||||
|
||||
const reason = mapStatusCodeToReason({
|
||||
status,
|
||||
headers,
|
||||
message: Option.isSome(decoded) ? decoded.value.error.message : undefined,
|
||||
http: buildHttpContext({ request, response, body }),
|
||||
metadata: {
|
||||
errorCode: Option.isSome(decoded) ? decoded.value.error.code ?? null : null,
|
||||
errorType: Option.isSome(decoded) ? decoded.value.error.type ?? null : null,
|
||||
requestId: requestId ?? null
|
||||
}
|
||||
})
|
||||
|
||||
return yield* AiError.make({ module: "OpenAiClient", method, reason })
|
||||
})
|
||||
|
||||
// =============================================================================
|
||||
// Rate Limits
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const parseRateLimitHeaders = (headers: Record<string, string>) => {
|
||||
const retryAfterRaw = headers["retry-after"]
|
||||
let retryAfter: Duration.Duration | undefined
|
||||
if (Predicate.isNotUndefined(retryAfterRaw)) {
|
||||
const parsed = Number.parse(retryAfterRaw)
|
||||
if (Option.isSome(parsed)) {
|
||||
retryAfter = Duration.seconds(parsed.value)
|
||||
}
|
||||
}
|
||||
const remainingRaw = headers["x-ratelimit-remaining-requests"]
|
||||
const remaining = Predicate.isNotUndefined(remainingRaw)
|
||||
? Option.getOrNull(Number.parse(remainingRaw))
|
||||
: null
|
||||
return {
|
||||
retryAfter,
|
||||
limit: headers["x-ratelimit-limit-requests"] ?? null,
|
||||
remaining,
|
||||
resetRequests: headers["x-ratelimit-reset-requests"] ?? null,
|
||||
resetTokens: headers["x-ratelimit-reset-tokens"] ?? null
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// HTTP Context
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const buildHttpRequestDetails = (
|
||||
request: HttpClientRequest.HttpClientRequest
|
||||
): typeof Response.HttpRequestDetails.Type => ({
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
urlParams: Array.from(request.urlParams),
|
||||
hash: Option.getOrUndefined(request.hash),
|
||||
headers: Redactable.redact(request.headers) as Record<string, string>
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
export const buildHttpContext = (params: {
|
||||
readonly request: HttpClientRequest.HttpClientRequest
|
||||
readonly response?: HttpClientResponse.HttpClientResponse
|
||||
readonly body?: string | undefined
|
||||
}): typeof AiError.HttpContext.Type => ({
|
||||
request: buildHttpRequestDetails(params.request),
|
||||
response: Predicate.isNotUndefined(params.response)
|
||||
? {
|
||||
status: params.response.status,
|
||||
headers: Redactable.redact(params.response.headers) as Record<string, string>
|
||||
}
|
||||
: undefined,
|
||||
body: params.body
|
||||
})
|
||||
|
||||
// =============================================================================
|
||||
// HTTP Status Code
|
||||
// =============================================================================
|
||||
|
||||
const buildInvalidRequestDescription = (params: {
|
||||
readonly status: number
|
||||
readonly message: string | undefined
|
||||
readonly method: string
|
||||
readonly url: string
|
||||
readonly errorCode: string | null
|
||||
readonly errorType: string | null
|
||||
readonly requestId: string | null
|
||||
readonly body: string | undefined
|
||||
}): string => {
|
||||
const parts: Array<string> = []
|
||||
|
||||
// Primary message or status description
|
||||
if (params.message) {
|
||||
parts.push(params.message)
|
||||
} else {
|
||||
parts.push(`HTTP ${params.status}`)
|
||||
}
|
||||
|
||||
// Request context
|
||||
parts.push(`(${params.method} ${params.url})`)
|
||||
|
||||
// Error code/type if available
|
||||
if (params.errorCode) {
|
||||
parts.push(`[code: ${params.errorCode}]`)
|
||||
} else if (params.errorType) {
|
||||
parts.push(`[type: ${params.errorType}]`)
|
||||
}
|
||||
|
||||
// Request ID for debugging
|
||||
if (params.requestId) {
|
||||
parts.push(`[requestId: ${params.requestId}]`)
|
||||
}
|
||||
|
||||
// If no message and we have body, show truncated body
|
||||
if (!params.message && params.body) {
|
||||
const truncated = params.body.length > 200
|
||||
? params.body.slice(0, 200) + "..."
|
||||
: params.body
|
||||
parts.push(`Response: ${truncated}`)
|
||||
}
|
||||
|
||||
return parts.join(" ")
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const mapStatusCodeToReason = ({ status, headers, message, metadata, http }: {
|
||||
readonly status: number
|
||||
readonly headers: Record<string, string>
|
||||
readonly message: string | undefined
|
||||
readonly metadata: OpenAiErrorMetadata
|
||||
readonly http: typeof AiError.HttpContext.Type
|
||||
}): AiError.AiErrorReason => {
|
||||
const invalidRequestDescription = buildInvalidRequestDescription({
|
||||
status,
|
||||
message,
|
||||
method: http.request.method,
|
||||
url: http.request.url,
|
||||
errorCode: metadata.errorCode,
|
||||
errorType: metadata.errorType,
|
||||
requestId: metadata.requestId,
|
||||
body: http.body
|
||||
})
|
||||
|
||||
switch (status) {
|
||||
case 400:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { openai: metadata },
|
||||
http
|
||||
})
|
||||
case 401:
|
||||
return new AiError.AuthenticationError({
|
||||
kind: "InvalidKey",
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
case 403:
|
||||
return new AiError.AuthenticationError({
|
||||
kind: "InsufficientPermissions",
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
case 404:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { openai: metadata },
|
||||
http
|
||||
})
|
||||
case 409:
|
||||
case 422:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { openai: metadata },
|
||||
http
|
||||
})
|
||||
case 429: {
|
||||
// Best-effort detection: OpenAI returns insufficient_quota for billing/quota issues
|
||||
if (
|
||||
metadata.errorCode === "insufficient_quota" ||
|
||||
metadata.errorType === "insufficient_quota"
|
||||
) {
|
||||
return new AiError.QuotaExhaustedError({
|
||||
metadata: { openai: metadata },
|
||||
http
|
||||
})
|
||||
}
|
||||
const { retryAfter, ...rateLimitMetadata } = parseRateLimitHeaders(headers)
|
||||
return new AiError.RateLimitError({
|
||||
retryAfter,
|
||||
metadata: {
|
||||
openai: {
|
||||
...metadata,
|
||||
...rateLimitMetadata
|
||||
}
|
||||
},
|
||||
http
|
||||
})
|
||||
}
|
||||
default:
|
||||
if (status >= 500) {
|
||||
return new AiError.InternalProviderError({
|
||||
description: message ?? "Server error",
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
}
|
||||
return new AiError.UnknownError({
|
||||
description: message,
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
}
|
||||
}
|
||||
27
repos/effect/packages/ai/openai/src/internal/utilities.ts
Normal file
27
repos/effect/packages/ai/openai/src/internal/utilities.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type * as Response from "effect/unstable/ai/Response"
|
||||
|
||||
const finishReasonMap: Record<string, Response.FinishReason> = {
|
||||
content_filter: "content-filter",
|
||||
function_call: "tool-calls",
|
||||
length: "length",
|
||||
stop: "stop",
|
||||
tool_calls: "tool-calls"
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const escapeJSONDelta = (delta: string): string => JSON.stringify(delta).slice(1, -1)
|
||||
|
||||
/** @internal */
|
||||
export const resolveFinishReason = (
|
||||
finishReason: string | null | undefined,
|
||||
hasToolCalls: boolean
|
||||
): Response.FinishReason => {
|
||||
if (finishReason == null) {
|
||||
return hasToolCalls ? "tool-calls" : "stop"
|
||||
}
|
||||
const reason = finishReasonMap[finishReason]
|
||||
if (reason == null) {
|
||||
return hasToolCalls ? "tool-calls" : "unknown"
|
||||
}
|
||||
return reason
|
||||
}
|
||||
798
repos/effect/packages/ai/openai/test/OpenAiClient.test.ts
Normal file
798
repos/effect/packages/ai/openai/test/OpenAiClient.test.ts
Normal file
@@ -0,0 +1,798 @@
|
||||
import type * as Generated from "@effect/ai-openai/Generated"
|
||||
import * as Errors from "@effect/ai-openai/internal/errors"
|
||||
import * as OpenAiClient from "@effect/ai-openai/OpenAiClient"
|
||||
import * as OpenAiClientGenerated from "@effect/ai-openai/OpenAiClientGenerated"
|
||||
import * as OpenAiConfig from "@effect/ai-openai/OpenAiConfig"
|
||||
import { assert, describe, it } from "@effect/vitest"
|
||||
import { Config, ConfigProvider, Effect, Layer, Redacted, Schema, Stream } from "effect"
|
||||
import type * as AiError from "effect/unstable/ai/AiError"
|
||||
import * as HttpClient from "effect/unstable/http/HttpClient"
|
||||
import * as HttpClientError from "effect/unstable/http/HttpClientError"
|
||||
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
||||
import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
|
||||
|
||||
// =============================================================================
|
||||
// Mock Helpers
|
||||
// =============================================================================
|
||||
|
||||
const makeMockResponse = (options: {
|
||||
readonly status: number
|
||||
readonly body: unknown
|
||||
readonly request?: HttpClientRequest.HttpClientRequest
|
||||
}): HttpClientResponse.HttpClientResponse => {
|
||||
// Always use a plain request for the response to avoid Redacted headers in error contexts
|
||||
const request = HttpClientRequest.get(options.request?.url ?? "/")
|
||||
const json = JSON.stringify(options.body)
|
||||
return HttpClientResponse.fromWeb(
|
||||
request,
|
||||
new Response(json, {
|
||||
status: options.status,
|
||||
headers: { "content-type": "application/json" }
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const makeMockStreamResponse = (options: {
|
||||
readonly events: ReadonlyArray<unknown>
|
||||
readonly request?: HttpClientRequest.HttpClientRequest
|
||||
}): HttpClientResponse.HttpClientResponse => {
|
||||
const request = HttpClientRequest.get(options.request?.url ?? "/")
|
||||
const body = options.events.map((event) => `data: ${JSON.stringify(event)}\n\n`).join("")
|
||||
return HttpClientResponse.fromWeb(
|
||||
request,
|
||||
new Response(body, {
|
||||
status: 200,
|
||||
headers: { "content-type": "text/event-stream" }
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const makeMockHttpClient = (
|
||||
handler: (
|
||||
request: HttpClientRequest.HttpClientRequest
|
||||
) => Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError.HttpClientError>
|
||||
): HttpClient.HttpClient =>
|
||||
HttpClient.makeWith<HttpClientError.HttpClientError, never, HttpClientError.HttpClientError, never>(
|
||||
(effect) =>
|
||||
Effect.flatMap(effect, handler) as Effect.Effect<
|
||||
HttpClientResponse.HttpClientResponse,
|
||||
HttpClientError.HttpClientError,
|
||||
never
|
||||
>,
|
||||
Effect.succeed
|
||||
)
|
||||
|
||||
const makeResponseBody = (
|
||||
overrides: Partial<typeof Generated.Response.Encoded> = {}
|
||||
): typeof Generated.Response.Encoded => ({
|
||||
id: "resp_test123",
|
||||
object: "response",
|
||||
created_at: 1,
|
||||
model: "gpt-4o-mini",
|
||||
status: "completed",
|
||||
output: [],
|
||||
metadata: null,
|
||||
temperature: null,
|
||||
top_p: null,
|
||||
tools: [],
|
||||
tool_choice: "auto",
|
||||
error: null,
|
||||
incomplete_details: null,
|
||||
instructions: null,
|
||||
parallel_tool_calls: false,
|
||||
...overrides
|
||||
})
|
||||
|
||||
// =============================================================================
|
||||
// Tests
|
||||
// =============================================================================
|
||||
|
||||
describe("OpenAiClient", () => {
|
||||
describe("make", () => {
|
||||
it.effect("sets Bearer token from apiKey", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: {}, request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("sk-test-12345")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
// Call method and ignore response parsing errors - we only care about the request
|
||||
yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(Effect.ignore)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
const authHeader = capturedRequest!.headers["authorization"]
|
||||
assert.strictEqual(authHeader, "Bearer sk-test-12345")
|
||||
}))
|
||||
|
||||
it.effect("prepends default URL", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: {}, request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(Effect.ignore)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.isTrue(capturedRequest!.url.startsWith("https://api.openai.com/v1"))
|
||||
}))
|
||||
|
||||
it.effect("uses custom apiUrl when provided", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: {}, request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key"),
|
||||
apiUrl: "https://custom.api.com/v2"
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(Effect.ignore)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.isTrue(capturedRequest!.url.startsWith("https://custom.api.com/v2"))
|
||||
}))
|
||||
|
||||
it.effect("sets OpenAI-Organization header when organizationId provided", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: {}, request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key"),
|
||||
organizationId: Redacted.make("org-12345")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(Effect.ignore)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.strictEqual(capturedRequest!.headers["openai-organization"], "org-12345")
|
||||
}))
|
||||
|
||||
it.effect("sets OpenAI-Project header when projectId provided", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: {}, request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key"),
|
||||
projectId: Redacted.make("proj-67890")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(Effect.ignore)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.strictEqual(capturedRequest!.headers["openai-project"], "proj-67890")
|
||||
}))
|
||||
|
||||
it.effect("applies transformClient option", () =>
|
||||
Effect.gen(function*() {
|
||||
let transformApplied = false
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({ status: 200, body: {}, request }))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key"),
|
||||
transformClient: (client) => {
|
||||
transformApplied = true
|
||||
return client
|
||||
}
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(Effect.ignore)
|
||||
assert.isTrue(transformApplied)
|
||||
}))
|
||||
|
||||
it.effect("exposes transformed HttpClient via client field", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: {}, request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key"),
|
||||
transformClient: (client) =>
|
||||
client.pipe(HttpClient.mapRequest(HttpClientRequest.setHeader("x-client-field", "enabled")))
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.client.execute(HttpClientRequest.get("/responses")).pipe(Effect.ignore)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.isTrue(capturedRequest!.url.startsWith("https://api.openai.com/v1"))
|
||||
assert.strictEqual(capturedRequest!.headers["authorization"], "Bearer test-key")
|
||||
assert.strictEqual(capturedRequest!.headers["x-client-field"], "enabled")
|
||||
}))
|
||||
|
||||
it.effect("applies OpenAiConfig transformClient after options transformClient", () =>
|
||||
Effect.gen(function*() {
|
||||
let optionsTransformApplied = false
|
||||
let configTransformApplied = false
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: makeResponseBody(), request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key"),
|
||||
transformClient: (client) => {
|
||||
optionsTransformApplied = true
|
||||
return client.pipe(
|
||||
HttpClient.mapRequest(HttpClientRequest.setHeader("x-openai-transform", "options"))
|
||||
)
|
||||
}
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.createResponse({
|
||||
model: "gpt-4o",
|
||||
input: "test"
|
||||
}).pipe(
|
||||
OpenAiConfig.withClientTransform((client) => {
|
||||
configTransformApplied = true
|
||||
return client.pipe(
|
||||
HttpClient.mapRequest(HttpClientRequest.setHeader("x-openai-transform", "config"))
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
assert.isTrue(optionsTransformApplied)
|
||||
assert.isTrue(configTransformApplied)
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.strictEqual(capturedRequest!.headers["x-openai-transform"], "config")
|
||||
}))
|
||||
})
|
||||
|
||||
describe("OpenAiClientGenerated", () => {
|
||||
it.effect("sets Bearer token from apiKey", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: makeResponseBody(), request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClientGenerated.make({
|
||||
apiKey: Redacted.make("sk-generated-test")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.createResponse({
|
||||
payload: {
|
||||
model: "gpt-4o",
|
||||
input: "test"
|
||||
}
|
||||
})
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.strictEqual(capturedRequest!.headers["authorization"], "Bearer sk-generated-test")
|
||||
}))
|
||||
|
||||
it.effect("prepends custom apiUrl", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: makeResponseBody(), request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClientGenerated.make({
|
||||
apiKey: Redacted.make("test-key"),
|
||||
apiUrl: "https://generated.example.test/v2"
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.createResponse({
|
||||
payload: {
|
||||
model: "gpt-4o",
|
||||
input: "test"
|
||||
}
|
||||
})
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.isTrue(capturedRequest!.url.startsWith("https://generated.example.test/v2"))
|
||||
}))
|
||||
|
||||
it.effect("applies OpenAiConfig transformClient after options transformClient", () =>
|
||||
Effect.gen(function*() {
|
||||
let optionsTransformApplied = false
|
||||
let configTransformApplied = false
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const mockClient = makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: makeResponseBody(), request }))
|
||||
})
|
||||
|
||||
const client = yield* OpenAiClientGenerated.make({
|
||||
apiKey: Redacted.make("test-key"),
|
||||
transformClient: (client) => {
|
||||
optionsTransformApplied = true
|
||||
return client.pipe(
|
||||
HttpClient.mapRequest(HttpClientRequest.setHeader("x-openai-transform", "options"))
|
||||
)
|
||||
}
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
yield* client.createResponse({
|
||||
payload: {
|
||||
model: "gpt-4o",
|
||||
input: "test"
|
||||
}
|
||||
}).pipe(
|
||||
OpenAiConfig.withClientTransform((client) => {
|
||||
configTransformApplied = true
|
||||
return client.pipe(
|
||||
HttpClient.mapRequest(HttpClientRequest.setHeader("x-openai-transform", "config"))
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
assert.isTrue(optionsTransformApplied)
|
||||
assert.isTrue(configTransformApplied)
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.strictEqual(capturedRequest!.headers["x-openai-transform"], "config")
|
||||
}))
|
||||
})
|
||||
|
||||
describe("layer", () => {
|
||||
it.effect("creates working service", () => {
|
||||
const HttpClientLayer = Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeMockHttpClient(() => Effect.succeed(makeMockResponse({ status: 200, body: {} })))
|
||||
)
|
||||
|
||||
const MainLayer = OpenAiClient.layer({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Layer.provide(HttpClientLayer))
|
||||
|
||||
return Effect.gen(function*() {
|
||||
const client = yield* OpenAiClient.OpenAiClient
|
||||
assert.isNotNull(client.client)
|
||||
}).pipe(Effect.provide(MainLayer))
|
||||
})
|
||||
|
||||
it.effect("layerConfig loads from Config", () => {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
const HttpClientLayer = Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeMockHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(makeMockResponse({ status: 200, body: {}, request }))
|
||||
})
|
||||
)
|
||||
|
||||
const configProvider = ConfigProvider.fromEnv({
|
||||
env: {
|
||||
MY_API_KEY: "sk-config-key",
|
||||
MY_API_URL: "https://config.api.com/v1"
|
||||
}
|
||||
})
|
||||
|
||||
// Use explicit config values to test the layerConfig mechanism
|
||||
// Provide explicit configs that won't fail for optional fields
|
||||
const MainLayer = OpenAiClient.layerConfig({
|
||||
apiKey: Config.redacted("MY_API_KEY"),
|
||||
apiUrl: Config.string("MY_API_URL")
|
||||
}).pipe(
|
||||
Layer.provide(HttpClientLayer),
|
||||
Layer.provide(ConfigProvider.layer(configProvider))
|
||||
)
|
||||
|
||||
return Effect.gen(function*() {
|
||||
const client = yield* OpenAiClient.OpenAiClient
|
||||
yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(Effect.ignore)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
assert.strictEqual(capturedRequest!.headers["authorization"], "Bearer sk-config-key")
|
||||
assert.isTrue(capturedRequest!.url.startsWith("https://config.api.com/v1"))
|
||||
}).pipe(Effect.provide(MainLayer))
|
||||
})
|
||||
})
|
||||
|
||||
describe("error mapping", () => {
|
||||
it.effect("maps TransportError to NetworkError reason", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient(() =>
|
||||
Effect.fail(
|
||||
new HttpClientError.HttpClientError({
|
||||
reason: new HttpClientError.TransportError({
|
||||
request: HttpClientRequest.get("/"),
|
||||
cause: new Error("Connection refused")
|
||||
})
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.module, "OpenAiClient")
|
||||
assert.strictEqual(result.method, "createResponse")
|
||||
assert.strictEqual(result.reason._tag, "NetworkError")
|
||||
}))
|
||||
|
||||
it.effect("maps 400 status to InvalidRequestError reason", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 400,
|
||||
body: { error: { message: "Bad request" } },
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.module, "OpenAiClient")
|
||||
assert.strictEqual(result.method, "createResponse")
|
||||
assert.strictEqual(result.reason._tag, "InvalidRequestError")
|
||||
}))
|
||||
|
||||
it.effect("maps 401 status to AuthenticationError reason", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 401,
|
||||
body: { error: { message: "Invalid API key" } },
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.reason._tag, "AuthenticationError")
|
||||
assert.strictEqual((result.reason as AiError.AuthenticationError).kind, "InvalidKey")
|
||||
}))
|
||||
|
||||
it.effect("maps 403 status to AuthenticationError with InsufficientPermissions", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 403,
|
||||
body: { error: { message: "Access denied" } },
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.reason._tag, "AuthenticationError")
|
||||
assert.strictEqual((result.reason as AiError.AuthenticationError).kind, "InsufficientPermissions")
|
||||
}))
|
||||
|
||||
it.effect("maps 429 status to RateLimitError reason", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 429,
|
||||
body: { error: { message: "Rate limit exceeded", type: "rate_limit_error", code: null } },
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.reason._tag, "RateLimitError")
|
||||
assert.isTrue(result.isRetryable)
|
||||
}))
|
||||
|
||||
it.effect("maps 429 with insufficient_quota code to QuotaExhaustedError", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 429,
|
||||
body: {
|
||||
error: {
|
||||
message: "You exceeded your current quota",
|
||||
type: "insufficient_quota",
|
||||
code: "insufficient_quota"
|
||||
}
|
||||
},
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.reason._tag, "QuotaExhaustedError")
|
||||
assert.isFalse(result.isRetryable)
|
||||
}))
|
||||
|
||||
it("mapStatusCodeToReason detects insufficient_quota as QuotaExhaustedError", () => {
|
||||
const http = {
|
||||
request: {
|
||||
method: "POST" as const,
|
||||
url: "https://api.openai.com",
|
||||
urlParams: [],
|
||||
hash: undefined,
|
||||
headers: {}
|
||||
}
|
||||
}
|
||||
const reason = Errors.mapStatusCodeToReason({
|
||||
status: 429,
|
||||
headers: {},
|
||||
message: "You exceeded your current quota",
|
||||
metadata: {
|
||||
errorCode: "insufficient_quota",
|
||||
errorType: "insufficient_quota",
|
||||
requestId: null
|
||||
},
|
||||
http
|
||||
})
|
||||
assert.strictEqual(reason._tag, "QuotaExhaustedError")
|
||||
})
|
||||
|
||||
it("OpenAiErrorBody decodes error with type and code", () => {
|
||||
const json = {
|
||||
error: {
|
||||
message: "You exceeded your current quota",
|
||||
type: "insufficient_quota",
|
||||
code: "insufficient_quota"
|
||||
}
|
||||
}
|
||||
const decoded = Schema.decodeUnknownSync(Errors.OpenAiErrorBody)(json)
|
||||
assert.strictEqual(decoded.error.message, "You exceeded your current quota")
|
||||
assert.strictEqual(decoded.error.type, "insufficient_quota")
|
||||
assert.strictEqual(decoded.error.code, "insufficient_quota")
|
||||
})
|
||||
|
||||
it.effect("maps 5xx status to InternalProviderError reason", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 500,
|
||||
body: { error: { message: "Internal server error" } },
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.reason._tag, "InternalProviderError")
|
||||
assert.isTrue(result.isRetryable)
|
||||
}))
|
||||
|
||||
it.effect("maps schema error to InvalidOutputError reason", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 200,
|
||||
body: { invalid: "response" },
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createResponse({ model: "gpt-4o", input: "test" }).pipe(
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.method, "createResponse")
|
||||
assert.strictEqual(result.reason._tag, "InvalidOutputError")
|
||||
}))
|
||||
})
|
||||
|
||||
describe("createEmbedding", () => {
|
||||
it.effect("maps 400 error to AiError", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 400,
|
||||
body: { error: { message: "Invalid model" } },
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createEmbedding({
|
||||
model: "invalid-model",
|
||||
input: "test"
|
||||
}).pipe(Effect.flip)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.method, "createEmbedding")
|
||||
assert.strictEqual(result.reason._tag, "InvalidRequestError")
|
||||
}))
|
||||
|
||||
it.effect("maps 429 error to RateLimitError", () =>
|
||||
Effect.gen(function*() {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 429,
|
||||
body: { error: { message: "Rate limit exceeded" } },
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const client = yield* OpenAiClient.make({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Effect.provide(Layer.succeed(HttpClient.HttpClient, mockClient)))
|
||||
|
||||
const result = yield* client.createEmbedding({
|
||||
model: "text-embedding-ada-002",
|
||||
input: "test"
|
||||
}).pipe(Effect.flip)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.reason._tag, "RateLimitError")
|
||||
}))
|
||||
})
|
||||
|
||||
describe("createResponseStream", () => {
|
||||
it.effect("accepts keepalive stream events", () => {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockStreamResponse({
|
||||
request,
|
||||
events: [
|
||||
{
|
||||
type: "response.created",
|
||||
sequence_number: 1,
|
||||
response: makeResponseBody({
|
||||
id: "resp_stream",
|
||||
status: "in_progress"
|
||||
})
|
||||
},
|
||||
{
|
||||
type: "keepalive",
|
||||
sequence_number: 2
|
||||
},
|
||||
{
|
||||
type: "response.completed",
|
||||
sequence_number: 3,
|
||||
response: makeResponseBody({
|
||||
id: "resp_stream"
|
||||
})
|
||||
}
|
||||
]
|
||||
}))
|
||||
)
|
||||
|
||||
const HttpClientLayer = Layer.succeed(HttpClient.HttpClient, mockClient)
|
||||
|
||||
const MainLayer = OpenAiClient.layer({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Layer.provide(HttpClientLayer))
|
||||
|
||||
return Effect.gen(function*() {
|
||||
const client = yield* OpenAiClient.OpenAiClient
|
||||
|
||||
const [_, stream] = yield* client.createResponseStream({
|
||||
model: "gpt-4o",
|
||||
input: "test"
|
||||
})
|
||||
|
||||
const events = yield* Stream.runCollect(stream)
|
||||
const parts = globalThis.Array.from(events)
|
||||
|
||||
assert.strictEqual(parts.length, 3)
|
||||
const keepAlive = parts[1]
|
||||
assert.strictEqual(keepAlive.type, "keepalive")
|
||||
if (keepAlive.type === "keepalive" && "sequence_number" in keepAlive) {
|
||||
assert.strictEqual(keepAlive.sequence_number, 2)
|
||||
}
|
||||
|
||||
const completed = parts[2]
|
||||
assert.isTrue(typeof completed === "object" && completed !== null && "type" in completed)
|
||||
if (typeof completed === "object" && completed !== null && "type" in completed) {
|
||||
assert.strictEqual(completed.type, "response.completed")
|
||||
if (
|
||||
completed.type === "response.completed" &&
|
||||
"response" in completed &&
|
||||
typeof completed.response === "object" &&
|
||||
completed.response !== null &&
|
||||
"id" in completed.response
|
||||
) {
|
||||
assert.strictEqual(completed.response.id, "resp_stream")
|
||||
}
|
||||
}
|
||||
}).pipe(Effect.provide(MainLayer))
|
||||
})
|
||||
|
||||
it.effect("maps HTTP error before stream starts", () => {
|
||||
const mockClient = makeMockHttpClient((request) =>
|
||||
Effect.succeed(makeMockResponse({
|
||||
status: 500,
|
||||
body: { error: { message: "Server error" } },
|
||||
request
|
||||
}))
|
||||
)
|
||||
|
||||
const HttpClientLayer = Layer.succeed(HttpClient.HttpClient, mockClient)
|
||||
|
||||
const MainLayer = OpenAiClient.layer({
|
||||
apiKey: Redacted.make("test-key")
|
||||
}).pipe(Layer.provide(HttpClientLayer))
|
||||
|
||||
return Effect.gen(function*() {
|
||||
const client = yield* OpenAiClient.OpenAiClient
|
||||
|
||||
const result = yield* client.createResponseStream({
|
||||
model: "gpt-4o",
|
||||
input: "test"
|
||||
}).pipe(
|
||||
Effect.andThen(([_, stream]) => Stream.runDrain(stream)),
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
assert.strictEqual(result._tag, "AiError")
|
||||
assert.strictEqual(result.reason._tag, "InternalProviderError")
|
||||
}).pipe(Effect.provide(MainLayer))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,289 @@
|
||||
import { OpenAiClient, OpenAiEmbeddingModel } from "@effect/ai-openai"
|
||||
import { assert, describe, it } from "@effect/vitest"
|
||||
import { Effect, Layer, Redacted } from "effect"
|
||||
import { EmbeddingModel } from "effect/unstable/ai"
|
||||
import { HttpClient, type HttpClientError, type HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
|
||||
|
||||
describe("OpenAiEmbeddingModel", () => {
|
||||
it.effect("model provides dimensions service", () =>
|
||||
Effect.gen(function*() {
|
||||
const dimensions = yield* EmbeddingModel.Dimensions
|
||||
assert.strictEqual(dimensions, 1536)
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.model("text-embedding-3-small", { dimensions: 1536 })),
|
||||
Effect.provideService(OpenAiClient.OpenAiClient, noopOpenAiClient)
|
||||
))
|
||||
|
||||
it.effect("reorders embeddings by provider index", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, {
|
||||
data: [
|
||||
{ index: 1, embedding: [20, 21], object: "embedding" },
|
||||
{ index: 0, embedding: [10, 11], object: "embedding" }
|
||||
],
|
||||
model: "text-embedding-3-small",
|
||||
object: "list",
|
||||
usage: {
|
||||
prompt_tokens: 7,
|
||||
total_tokens: 7
|
||||
}
|
||||
}))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
const response = yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
return yield* model.embedMany(["first", "second"])
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({ model: "text-embedding-3-small" })),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.deepStrictEqual(response.embeddings.map((embedding) => embedding.vector), [[10, 11], [20, 21]])
|
||||
assert.strictEqual(response.usage.inputTokens, 7)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const requestBody = yield* getRequestBody(capturedRequest)
|
||||
assert.strictEqual(requestBody.model, "text-embedding-3-small")
|
||||
assert.deepStrictEqual(requestBody.input, ["first", "second"])
|
||||
}))
|
||||
|
||||
it.effect("merges config and applies withConfigOverride precedence", () =>
|
||||
Effect.gen(function*() {
|
||||
let capturedRequest: HttpClientRequest.HttpClientRequest | undefined
|
||||
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) => {
|
||||
capturedRequest = request
|
||||
return Effect.succeed(jsonResponse(request, {
|
||||
data: [{ index: 0, embedding: [1, 2, 3], object: "embedding" }],
|
||||
model: "override-model",
|
||||
object: "list",
|
||||
usage: {
|
||||
prompt_tokens: 3,
|
||||
total_tokens: 3
|
||||
}
|
||||
}))
|
||||
})
|
||||
))
|
||||
)
|
||||
|
||||
yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
yield* model.embed("hello")
|
||||
}).pipe(
|
||||
OpenAiEmbeddingModel.withConfigOverride({
|
||||
model: "override-model",
|
||||
dimensions: 1024,
|
||||
user: "request-user"
|
||||
}),
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({
|
||||
model: "base-model",
|
||||
config: {
|
||||
dimensions: 256,
|
||||
user: "provider-user"
|
||||
}
|
||||
})),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.isDefined(capturedRequest)
|
||||
if (capturedRequest === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const requestBody = yield* getRequestBody(capturedRequest)
|
||||
assert.strictEqual(requestBody.model, "override-model")
|
||||
assert.strictEqual(requestBody.dimensions, 1024)
|
||||
assert.strictEqual(requestBody.user, "request-user")
|
||||
assert.deepStrictEqual(requestBody.input, ["hello"])
|
||||
}))
|
||||
|
||||
it.effect("fails with InvalidOutputError when provider returns duplicate indices", () =>
|
||||
Effect.gen(function*() {
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(jsonResponse(request, {
|
||||
data: [
|
||||
{ index: 0, embedding: [1], object: "embedding" },
|
||||
{ index: 0, embedding: [2], object: "embedding" }
|
||||
],
|
||||
model: "text-embedding-3-small",
|
||||
object: "list",
|
||||
usage: {
|
||||
prompt_tokens: 2,
|
||||
total_tokens: 2
|
||||
}
|
||||
}))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const error = yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
return yield* model.embedMany(["a", "b"]).pipe(Effect.flip)
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({ model: "text-embedding-3-small" })),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.strictEqual(error._tag, "AiError")
|
||||
assert.strictEqual(error.reason._tag, "InvalidOutputError")
|
||||
}))
|
||||
|
||||
it.effect("fails with InvalidOutputError when provider returns out-of-range indices", () =>
|
||||
Effect.gen(function*() {
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(jsonResponse(request, {
|
||||
data: [
|
||||
{ index: 0, embedding: [1], object: "embedding" },
|
||||
{ index: 2, embedding: [2], object: "embedding" }
|
||||
],
|
||||
model: "text-embedding-3-small",
|
||||
object: "list",
|
||||
usage: {
|
||||
prompt_tokens: 2,
|
||||
total_tokens: 2
|
||||
}
|
||||
}))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const error = yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
return yield* model.embedMany(["a", "b"]).pipe(Effect.flip)
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({ model: "text-embedding-3-small" })),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.strictEqual(error._tag, "AiError")
|
||||
assert.strictEqual(error.reason._tag, "InvalidOutputError")
|
||||
}))
|
||||
|
||||
it.effect("fails with InvalidOutputError when provider returns wrong embedding count", () =>
|
||||
Effect.gen(function*() {
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(jsonResponse(request, {
|
||||
data: [{ index: 0, embedding: [1], object: "embedding" }],
|
||||
model: "text-embedding-3-small",
|
||||
object: "list",
|
||||
usage: {
|
||||
prompt_tokens: 1,
|
||||
total_tokens: 1
|
||||
}
|
||||
}))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const error = yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
return yield* model.embedMany(["a", "b"]).pipe(Effect.flip)
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({ model: "text-embedding-3-small" })),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.strictEqual(error._tag, "AiError")
|
||||
assert.strictEqual(error.reason._tag, "InvalidOutputError")
|
||||
}))
|
||||
|
||||
it.effect("fails with InvalidOutputError when provider returns base64 embeddings", () =>
|
||||
Effect.gen(function*() {
|
||||
const clientLayer = OpenAiClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provide(Layer.succeed(
|
||||
HttpClient.HttpClient,
|
||||
makeHttpClient((request) =>
|
||||
Effect.succeed(jsonResponse(request, {
|
||||
data: [{ index: 0, embedding: "AQID", object: "embedding" }],
|
||||
model: "text-embedding-3-small",
|
||||
object: "list",
|
||||
usage: {
|
||||
prompt_tokens: 1,
|
||||
total_tokens: 1
|
||||
}
|
||||
}))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
const error = yield* Effect.gen(function*() {
|
||||
const model = yield* EmbeddingModel.EmbeddingModel
|
||||
return yield* model.embed("a").pipe(Effect.flip)
|
||||
}).pipe(
|
||||
Effect.provide(OpenAiEmbeddingModel.layer({ model: "text-embedding-3-small" })),
|
||||
Effect.provide(clientLayer)
|
||||
)
|
||||
|
||||
assert.strictEqual(error._tag, "AiError")
|
||||
assert.strictEqual(error.reason._tag, "InvalidOutputError")
|
||||
}))
|
||||
})
|
||||
|
||||
const makeHttpClient = (
|
||||
handler: (
|
||||
request: HttpClientRequest.HttpClientRequest
|
||||
) => Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError.HttpClientError>
|
||||
) =>
|
||||
HttpClient.makeWith(
|
||||
Effect.fnUntraced(function*(requestEffect) {
|
||||
const request = yield* requestEffect
|
||||
return yield* handler(request)
|
||||
}),
|
||||
Effect.succeed as HttpClient.HttpClient.Preprocess<HttpClientError.HttpClientError, never>
|
||||
)
|
||||
|
||||
const jsonResponse = (
|
||||
request: HttpClientRequest.HttpClientRequest,
|
||||
body: unknown
|
||||
): HttpClientResponse.HttpClientResponse =>
|
||||
HttpClientResponse.fromWeb(
|
||||
request,
|
||||
new Response(JSON.stringify(body), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const getRequestBody = (request: HttpClientRequest.HttpClientRequest) =>
|
||||
Effect.gen(function*() {
|
||||
const body = request.body
|
||||
if (body._tag === "Uint8Array") {
|
||||
const text = new TextDecoder().decode(body.body)
|
||||
return JSON.parse(text)
|
||||
}
|
||||
return yield* Effect.die(new Error("Expected Uint8Array body"))
|
||||
})
|
||||
|
||||
const noopOpenAiClient: OpenAiClient.Service = {
|
||||
client: undefined as unknown as OpenAiClient.Service["client"],
|
||||
createResponse: () => Effect.die(new Error("noop")),
|
||||
createResponseStream: () => Effect.die(new Error("noop")),
|
||||
createEmbedding: () => Effect.die(new Error("noop"))
|
||||
}
|
||||
1528
repos/effect/packages/ai/openai/test/OpenAiLanguageModel.test.ts
Normal file
1528
repos/effect/packages/ai/openai/test/OpenAiLanguageModel.test.ts
Normal file
File diff suppressed because it is too large
Load Diff
273
repos/effect/packages/ai/openai/test/OpenAiSchema.test.ts
Normal file
273
repos/effect/packages/ai/openai/test/OpenAiSchema.test.ts
Normal file
@@ -0,0 +1,273 @@
|
||||
import * as OpenAiSchema from "@effect/ai-openai/OpenAiSchema"
|
||||
import { assert, describe, it } from "@effect/vitest"
|
||||
import { Effect, Schema, Stream } from "effect"
|
||||
import * as Sse from "effect/unstable/encoding/Sse"
|
||||
|
||||
const makeResponse = (overrides: Record<string, unknown> = {}) => ({
|
||||
id: "resp_123",
|
||||
object: "response",
|
||||
model: "gpt-4o-mini",
|
||||
status: "completed",
|
||||
created_at: 1,
|
||||
output: [],
|
||||
...overrides
|
||||
})
|
||||
|
||||
describe("OpenAiSchema", () => {
|
||||
it("decodes a representative response payload", () => {
|
||||
const decoded = Schema.decodeUnknownSync(OpenAiSchema.Response)({
|
||||
...makeResponse(),
|
||||
output: [
|
||||
{
|
||||
id: "msg_1",
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
status: "completed",
|
||||
content: [
|
||||
{
|
||||
type: "output_text",
|
||||
text: "hello",
|
||||
annotations: [
|
||||
{
|
||||
type: "url_citation",
|
||||
url: "https://example.com",
|
||||
start_index: 0,
|
||||
end_index: 5,
|
||||
title: "example"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "refusal",
|
||||
refusal: "cannot comply"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "fc_1",
|
||||
type: "function_call",
|
||||
call_id: "call_1",
|
||||
name: "lookup",
|
||||
arguments: "{}",
|
||||
status: "completed"
|
||||
},
|
||||
{
|
||||
id: "reasoning_1",
|
||||
type: "reasoning",
|
||||
summary: [
|
||||
{
|
||||
type: "summary_text",
|
||||
text: "thinking"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
usage: {
|
||||
input_tokens: 10,
|
||||
output_tokens: 20,
|
||||
total_tokens: 30
|
||||
}
|
||||
})
|
||||
|
||||
assert.strictEqual(decoded.id, "resp_123")
|
||||
assert.strictEqual(decoded.output.length, 3)
|
||||
assert.strictEqual(decoded.output[0].type, "message")
|
||||
if (decoded.output[0].type === "message") {
|
||||
assert.strictEqual(decoded.output[0].content[0].type, "output_text")
|
||||
}
|
||||
})
|
||||
|
||||
it("decodes required stream events", () => {
|
||||
const response = makeResponse({ status: "in_progress" })
|
||||
const applyPatchItem = {
|
||||
id: "ap_1",
|
||||
type: "apply_patch_call",
|
||||
call_id: "call_ap",
|
||||
operation: {
|
||||
type: "update_file",
|
||||
path: "README.md",
|
||||
diff: "@@"
|
||||
}
|
||||
}
|
||||
|
||||
const events = [
|
||||
{ type: "response.created", sequence_number: 1, response },
|
||||
{
|
||||
type: "response.completed",
|
||||
sequence_number: 2,
|
||||
response: makeResponse()
|
||||
},
|
||||
{ type: "response.incomplete", sequence_number: 3, response: makeResponse({ status: "incomplete" }) },
|
||||
{ type: "response.failed", sequence_number: 4, response: makeResponse({ status: "failed" }) },
|
||||
{ type: "response.output_item.added", sequence_number: 5, output_index: 0, item: applyPatchItem },
|
||||
{ type: "response.output_item.done", sequence_number: 6, output_index: 0, item: applyPatchItem },
|
||||
{
|
||||
type: "response.output_text.delta",
|
||||
sequence_number: 7,
|
||||
item_id: "msg_1",
|
||||
output_index: 0,
|
||||
content_index: 0,
|
||||
delta: "hel"
|
||||
},
|
||||
{
|
||||
type: "response.output_text.annotation.added",
|
||||
sequence_number: 8,
|
||||
item_id: "msg_1",
|
||||
output_index: 0,
|
||||
content_index: 0,
|
||||
annotation_index: 0,
|
||||
annotation: {
|
||||
type: "file_path",
|
||||
file_id: "file_1",
|
||||
index: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "response.reasoning_summary_part.added",
|
||||
sequence_number: 9,
|
||||
item_id: "reasoning_1",
|
||||
output_index: 1,
|
||||
summary_index: 0,
|
||||
part: { type: "summary_text", text: "thinking" }
|
||||
},
|
||||
{
|
||||
type: "response.reasoning_summary_part.done",
|
||||
sequence_number: 10,
|
||||
item_id: "reasoning_1",
|
||||
output_index: 1,
|
||||
summary_index: 0,
|
||||
part: { type: "summary_text", text: "thinking" }
|
||||
},
|
||||
{
|
||||
type: "response.reasoning_summary_text.delta",
|
||||
sequence_number: 11,
|
||||
item_id: "reasoning_1",
|
||||
output_index: 1,
|
||||
summary_index: 0,
|
||||
delta: "..."
|
||||
},
|
||||
{
|
||||
type: "response.function_call_arguments.delta",
|
||||
sequence_number: 12,
|
||||
item_id: "fc_1",
|
||||
output_index: 2,
|
||||
delta: "{"
|
||||
},
|
||||
{
|
||||
type: "response.function_call_arguments.done",
|
||||
sequence_number: 13,
|
||||
item_id: "fc_1",
|
||||
output_index: 2,
|
||||
arguments: "{}"
|
||||
},
|
||||
{
|
||||
type: "response.code_interpreter_call_code.delta",
|
||||
sequence_number: 14,
|
||||
item_id: "code_1",
|
||||
output_index: 3,
|
||||
delta: "print"
|
||||
},
|
||||
{
|
||||
type: "response.code_interpreter_call_code.done",
|
||||
sequence_number: 15,
|
||||
item_id: "code_1",
|
||||
output_index: 3,
|
||||
code: "print('ok')"
|
||||
},
|
||||
{
|
||||
type: "response.apply_patch_call_operation_diff.delta",
|
||||
sequence_number: 16,
|
||||
item_id: "ap_1",
|
||||
output_index: 4,
|
||||
delta: "@@"
|
||||
},
|
||||
{
|
||||
type: "response.apply_patch_call_operation_diff.done",
|
||||
sequence_number: 17,
|
||||
item_id: "ap_1",
|
||||
output_index: 4,
|
||||
delta: "@@"
|
||||
},
|
||||
{
|
||||
type: "response.image_generation_call.partial_image",
|
||||
sequence_number: 18,
|
||||
item_id: "img_1",
|
||||
output_index: 5,
|
||||
partial_image_b64: "AQID"
|
||||
}
|
||||
]
|
||||
|
||||
for (const event of events) {
|
||||
const decoded = Schema.decodeUnknownSync(OpenAiSchema.ResponseStreamEvent)(event)
|
||||
assert.strictEqual(decoded.type, event.type)
|
||||
}
|
||||
})
|
||||
|
||||
it.effect("keeps keepalive and unknown events tolerant in SSE decoding", () =>
|
||||
Effect.gen(function*() {
|
||||
const sseBody = [
|
||||
{
|
||||
type: "response.created",
|
||||
sequence_number: 1,
|
||||
response: makeResponse({ status: "in_progress" })
|
||||
},
|
||||
{
|
||||
type: "keepalive",
|
||||
sequence_number: 2,
|
||||
heartbeat: true
|
||||
},
|
||||
{
|
||||
type: "provider.future_event",
|
||||
sequence_number: 3,
|
||||
nested: { ok: true }
|
||||
},
|
||||
{
|
||||
type: "response.completed",
|
||||
sequence_number: 4,
|
||||
response: makeResponse({ status: "completed" })
|
||||
}
|
||||
].map((event) => `data: ${JSON.stringify(event)}\n\n`).join("")
|
||||
|
||||
const events = yield* Stream.fromIterable([sseBody]).pipe(
|
||||
Stream.pipeThroughChannel(Sse.decodeDataSchema(OpenAiSchema.ResponseStreamEvent)),
|
||||
Stream.map((event) => event.data),
|
||||
Stream.runCollect
|
||||
)
|
||||
|
||||
const decoded = globalThis.Array.from(events)
|
||||
assert.strictEqual(decoded.length, 4)
|
||||
assert.strictEqual(decoded[1].type, "keepalive")
|
||||
assert.strictEqual(decoded[2].type, "provider.future_event")
|
||||
if (decoded[1].type === "keepalive") {
|
||||
assert.strictEqual(decoded[1].sequence_number, 2)
|
||||
}
|
||||
}))
|
||||
|
||||
it.effect("does not silently decode malformed known events as unknown", () =>
|
||||
Effect.gen(function*() {
|
||||
const malformed = yield* Schema.decodeUnknownEffect(OpenAiSchema.ResponseStreamEvent)({
|
||||
type: "response.completed",
|
||||
sequence_number: 1
|
||||
}).pipe(Effect.flip)
|
||||
|
||||
assert.isDefined(malformed)
|
||||
}))
|
||||
|
||||
it("decodes embedding response variants (numeric + string/base64)", () => {
|
||||
const numeric = Schema.decodeUnknownSync(OpenAiSchema.CreateEmbeddingResponse)({
|
||||
object: "list",
|
||||
model: "text-embedding-3-small",
|
||||
data: [{ object: "embedding", index: 0, embedding: [0.1, 0.2] }],
|
||||
usage: { prompt_tokens: 2, total_tokens: 2 }
|
||||
})
|
||||
const base64 = Schema.decodeUnknownSync(OpenAiSchema.CreateEmbeddingResponse)({
|
||||
object: "list",
|
||||
model: "text-embedding-3-small",
|
||||
data: [{ object: "embedding", index: 0, embedding: "AQID" }],
|
||||
usage: { prompt_tokens: 2, total_tokens: 2 }
|
||||
})
|
||||
|
||||
assert.strictEqual(numeric.data[0].embedding[0], 0.1)
|
||||
assert.strictEqual(base64.data[0].embedding, "AQID")
|
||||
})
|
||||
})
|
||||
8
repos/effect/packages/ai/openai/tsconfig.json
Normal file
8
repos/effect/packages/ai/openai/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/tsconfig",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{ "path": "../../effect" }
|
||||
]
|
||||
}
|
||||
6
repos/effect/packages/ai/openai/vitest.config.ts
Normal file
6
repos/effect/packages/ai/openai/vitest.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { mergeConfig, type ViteUserConfig } from "vitest/config"
|
||||
import shared from "../../../vitest.shared.ts"
|
||||
|
||||
const config: ViteUserConfig = {}
|
||||
|
||||
export default mergeConfig(shared, config)
|
||||
725
repos/effect/packages/ai/openrouter/CHANGELOG.md
Normal file
725
repos/effect/packages/ai/openrouter/CHANGELOG.md
Normal file
@@ -0,0 +1,725 @@
|
||||
# @effect/ai-openrouter
|
||||
|
||||
## 4.0.0-beta.99
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8ce4795`](https://github.com/Effect-TS/effect/commit/8ce4795ccbaebca4292757db568c005a992546a4), [`80b539f`](https://github.com/Effect-TS/effect/commit/80b539f8aba68f478c75c35c2b4140c4ffc4fada), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`e6e6dba`](https://github.com/Effect-TS/effect/commit/e6e6dba6e9d86e7c2ad27dcedf289db76a19697f), [`bfb203e`](https://github.com/Effect-TS/effect/commit/bfb203e95aa439f731acad37fc3a9a831a190f1c), [`2e9a34a`](https://github.com/Effect-TS/effect/commit/2e9a34ac2bece4f3a206160480c991e3841dc67a), [`55d4eb3`](https://github.com/Effect-TS/effect/commit/55d4eb34f2c64d54f6a25a305b5c5438ebd7934e), [`bddb010`](https://github.com/Effect-TS/effect/commit/bddb010eac3d4436cb094edbbee7460c5440c162), [`a328835`](https://github.com/Effect-TS/effect/commit/a328835e50d76bc96648a1c1550456e8c9f81210), [`5560d05`](https://github.com/Effect-TS/effect/commit/5560d05aa6abdd29466d9c3412cc5e648b0adbde), [`8f6e3ad`](https://github.com/Effect-TS/effect/commit/8f6e3adb185b16e8820b98c509b308086f7ff1af), [`46997fa`](https://github.com/Effect-TS/effect/commit/46997fa60401f5e3c93daa4b61f7df8e31caaab4), [`9e6e12d`](https://github.com/Effect-TS/effect/commit/9e6e12d75c118cd265496f2880490d1f33a5c8bf), [`3394b93`](https://github.com/Effect-TS/effect/commit/3394b93d97d6f24fc38670641d1490289ffca7f1), [`febeabc`](https://github.com/Effect-TS/effect/commit/febeabc3f7c31094da000a23edeaabfe2ab00a38), [`54161c9`](https://github.com/Effect-TS/effect/commit/54161c98f6f3569e0c31842f54e6a257f9421c4c), [`385f7a4`](https://github.com/Effect-TS/effect/commit/385f7a4ee4a7359928597ea56d151dbaf5eb5802), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`7543afe`](https://github.com/Effect-TS/effect/commit/7543afea6f4d97d1f1ad876224323838a48daadd), [`44b9cf3`](https://github.com/Effect-TS/effect/commit/44b9cf3d240d726997b4bbcd0ede48e074d3c456), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`0a8aa6a`](https://github.com/Effect-TS/effect/commit/0a8aa6acb90a72b91c24d17133c950e4cacd8abd), [`c8d9fcf`](https://github.com/Effect-TS/effect/commit/c8d9fcf7b030f7c474effbab2764ce7aee1c7209), [`9ca7f9a`](https://github.com/Effect-TS/effect/commit/9ca7f9a69363e4485645966d5a93b8f9597c5206), [`e7aca89`](https://github.com/Effect-TS/effect/commit/e7aca894bb32fbb785b5830837e6061c415a6015), [`55d7560`](https://github.com/Effect-TS/effect/commit/55d75609b8acf8a1b54c1b1c7fbbb65ec741aa3e), [`f809189`](https://github.com/Effect-TS/effect/commit/f809189ddf6b6011ba43a9901baaa734e315da2a), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`0ebdbe7`](https://github.com/Effect-TS/effect/commit/0ebdbe74463dc84385956d0b1e8c2b79ebab5400), [`7517d09`](https://github.com/Effect-TS/effect/commit/7517d09f12a0b183a81bd425962c4e280a68b05d), [`212493b`](https://github.com/Effect-TS/effect/commit/212493b9a1eb98cd1ef6959c707a2e5784a5ae91), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`80ea8cb`](https://github.com/Effect-TS/effect/commit/80ea8cb9222ca73f564c8267ab2f82966fea027a), [`8df19f4`](https://github.com/Effect-TS/effect/commit/8df19f4fe81d90cc33ace88b9a77e5534f82d604)]:
|
||||
- effect@4.0.0-beta.99
|
||||
|
||||
## 4.0.0-beta.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`989603b`](https://github.com/Effect-TS/effect-smol/commit/989603b60ab1197b64acf214208e0d370cd1f842), [`214c458`](https://github.com/Effect-TS/effect-smol/commit/214c458084bb6995d543cd37d1055f24be3d454e), [`a037273`](https://github.com/Effect-TS/effect-smol/commit/a0372736ac34796969b051bbba4717d7983f1ebe), [`97fdaa9`](https://github.com/Effect-TS/effect-smol/commit/97fdaa9c1f522c65e579365d314a07878e2b904f), [`b24d248`](https://github.com/Effect-TS/effect-smol/commit/b24d248c8df44222ce642087cde2bd859a2dc709), [`19c222c`](https://github.com/Effect-TS/effect-smol/commit/19c222cac2353a3d7b7733caecb00556fffe9a5c), [`eec85dd`](https://github.com/Effect-TS/effect-smol/commit/eec85ddba09ea326fd268ee33eeffd47e50d4671), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`8849052`](https://github.com/Effect-TS/effect-smol/commit/884905232d1e9a365e046d8dde27bf9c5707f57f), [`c15e16a`](https://github.com/Effect-TS/effect-smol/commit/c15e16ad130d1fbde25d912b7ac55995066cb35b), [`01d00a3`](https://github.com/Effect-TS/effect-smol/commit/01d00a3abfbf1f37996cdbe738ea5137c646cdd7), [`8bd4589`](https://github.com/Effect-TS/effect-smol/commit/8bd458975a1b3a8ed042eccf317b93d28ded91e7), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`6e08428`](https://github.com/Effect-TS/effect-smol/commit/6e08428d980501b856f846ad3f3f0e4ea46e7786), [`388dcf9`](https://github.com/Effect-TS/effect-smol/commit/388dcf953f65d317547f34d40e6443c5f264205f), [`2b7ce2b`](https://github.com/Effect-TS/effect-smol/commit/2b7ce2b513e7ec2a77822f1116dc6ffb6ba93f4e), [`87bea7e`](https://github.com/Effect-TS/effect-smol/commit/87bea7e16259246f3bcdf565446394751abca953), [`ce38dc3`](https://github.com/Effect-TS/effect-smol/commit/ce38dc33bda805a684432cca071f4dc3c6b9a1ba), [`a807cd1`](https://github.com/Effect-TS/effect-smol/commit/a807cd170341deca8a1cfb52c4222585f2431bb9), [`fd8a356`](https://github.com/Effect-TS/effect-smol/commit/fd8a356f06a8c9ce4e7e0a13fc4021c178ed31de), [`c2a5edc`](https://github.com/Effect-TS/effect-smol/commit/c2a5edc3abd31ad5bc123362bc1213e03e4095c3), [`5946da3`](https://github.com/Effect-TS/effect-smol/commit/5946da3804a1be5e752b05b96bd058cdba50a1bf), [`4ae0c5f`](https://github.com/Effect-TS/effect-smol/commit/4ae0c5ffcbe6c56ddfcb05c639112a079483539e), [`5b2a0bc`](https://github.com/Effect-TS/effect-smol/commit/5b2a0bceea3a28a33a58555210c90a415dc74a76), [`72ac585`](https://github.com/Effect-TS/effect-smol/commit/72ac585884befde6af9208da738699a93f1bae79), [`5e8c1b8`](https://github.com/Effect-TS/effect-smol/commit/5e8c1b82bfafa121311f987a49ab75395e3647a7), [`0f9c078`](https://github.com/Effect-TS/effect-smol/commit/0f9c07841b04183f485ee6e6458de73b290b09f5)]:
|
||||
- effect@4.0.0-beta.98
|
||||
|
||||
## 4.0.0-beta.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.97
|
||||
|
||||
## 4.0.0-beta.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1503f45`](https://github.com/Effect-TS/effect-smol/commit/1503f45cb5bb2a74f4705252ec505a1f0ade7e62), [`57fe793`](https://github.com/Effect-TS/effect-smol/commit/57fe79316ffbc380b30626a168981fb26ae97459), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`97f29df`](https://github.com/Effect-TS/effect-smol/commit/97f29df457f7ffd07cfb4b379315c12c086af805)]:
|
||||
- effect@4.0.0-beta.96
|
||||
|
||||
## 4.0.0-beta.95
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a482442`](https://github.com/Effect-TS/effect-smol/commit/a482442abdeb490e9652b854ec3495e4aa7273e7), [`fbefa85`](https://github.com/Effect-TS/effect-smol/commit/fbefa850fab2f0a302c20614496aeaaa2a8b5590), [`0b4a32f`](https://github.com/Effect-TS/effect-smol/commit/0b4a32f4260f0d8500942a133001b0d349328102), [`18a49e1`](https://github.com/Effect-TS/effect-smol/commit/18a49e1786679456258002ff9397faf02f678c2d), [`266cb90`](https://github.com/Effect-TS/effect-smol/commit/266cb90bb2c17aabc40563c32db334f09ba3d74b), [`912f095`](https://github.com/Effect-TS/effect-smol/commit/912f095a34572bbd3cedf6edb27878443e3e4a95), [`a6718f9`](https://github.com/Effect-TS/effect-smol/commit/a6718f9e00a15ca903b0732da46116cbf3d6aca7), [`bef5154`](https://github.com/Effect-TS/effect-smol/commit/bef51540a243aa2f872a00c01d0cd58b7a769baa), [`18e0564`](https://github.com/Effect-TS/effect-smol/commit/18e0564bd0f8ebbdfcaf1e2c21529948e9e4a81d), [`fb50f14`](https://github.com/Effect-TS/effect-smol/commit/fb50f14fc3657c1973785aa5b72ecf0b0d28e0b2)]:
|
||||
- effect@4.0.0-beta.95
|
||||
|
||||
## 4.0.0-beta.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`95a0e9b`](https://github.com/Effect-TS/effect-smol/commit/95a0e9bb62797af0e81c9998773405f248f218c5), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63), [`f11ce73`](https://github.com/Effect-TS/effect-smol/commit/f11ce73af60823754dc24194f4ffc561b9ea1c2d), [`ff30b6e`](https://github.com/Effect-TS/effect-smol/commit/ff30b6e7c2c63ffc56a4c5818d6d86b01b5ad528), [`1caab3c`](https://github.com/Effect-TS/effect-smol/commit/1caab3cc30f626efbf15e59d74f539a487e5c85c), [`aa80c47`](https://github.com/Effect-TS/effect-smol/commit/aa80c4775a04db87553e5568764cab7e32a72814), [`c2ae4fc`](https://github.com/Effect-TS/effect-smol/commit/c2ae4fce2f03a4cd1861c2b1179da7df656e662d), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63)]:
|
||||
- effect@4.0.0-beta.94
|
||||
|
||||
## 4.0.0-beta.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`00652fe`](https://github.com/Effect-TS/effect-smol/commit/00652fe95c18f87208e91343eb8bf218faa2f677), [`6c58167`](https://github.com/Effect-TS/effect-smol/commit/6c5816746eaf91d2a3c7c899c5720809fa230ae3), [`2bc5415`](https://github.com/Effect-TS/effect-smol/commit/2bc541501a7ef89e542d7cb98e96beb53cd205cc), [`e11cccc`](https://github.com/Effect-TS/effect-smol/commit/e11cccc7d5fe631abccc7d6e3bd296938de0fa2e), [`ba7e77e`](https://github.com/Effect-TS/effect-smol/commit/ba7e77e046b8641a3a4e9750bb88ca4a1d063d3f), [`5713ee7`](https://github.com/Effect-TS/effect-smol/commit/5713ee7edbc3054efde407b2286bbfd45bbc6e1c)]:
|
||||
- effect@4.0.0-beta.93
|
||||
|
||||
## 4.0.0-beta.92
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`affdc13`](https://github.com/Effect-TS/effect-smol/commit/affdc139045cc325dce321a84a580fdc1b2da7b9)]:
|
||||
- effect@4.0.0-beta.92
|
||||
|
||||
## 4.0.0-beta.91
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b135b25`](https://github.com/Effect-TS/effect-smol/commit/b135b2517fca9e7839734ace3699a7dfa75b9075), [`aaa21a3`](https://github.com/Effect-TS/effect-smol/commit/aaa21a369a171c600db294f2a4f640583043e150), [`3475ee6`](https://github.com/Effect-TS/effect-smol/commit/3475ee6c2bda6b05c6d7a12ce30c8bb840b5b1a6)]:
|
||||
- effect@4.0.0-beta.91
|
||||
|
||||
## 4.0.0-beta.90
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d237fdf`](https://github.com/Effect-TS/effect-smol/commit/d237fdf726481f76eb52a6196e111b24122bc3d5)]:
|
||||
- effect@4.0.0-beta.90
|
||||
|
||||
## 4.0.0-beta.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b7d46ab`](https://github.com/Effect-TS/effect-smol/commit/b7d46ab7e1a29d8711817bab583c9febf48a0dad), [`7777e15`](https://github.com/Effect-TS/effect-smol/commit/7777e1540fd3680dd8346723cffec812b9384669), [`5376197`](https://github.com/Effect-TS/effect-smol/commit/5376197ca8e50358a41b1fd3cec27bd1ec680ec6)]:
|
||||
- effect@4.0.0-beta.89
|
||||
|
||||
## 4.0.0-beta.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`911f1b8`](https://github.com/Effect-TS/effect-smol/commit/911f1b84790ce42b3a70c95b33e6f6fd9e74de8b), [`8beeeea`](https://github.com/Effect-TS/effect-smol/commit/8beeeea52879d8613a39468848f01c3092bd54d4), [`c306fcf`](https://github.com/Effect-TS/effect-smol/commit/c306fcfeb1ef38455156932a1faf49292b1318da)]:
|
||||
- effect@4.0.0-beta.88
|
||||
|
||||
## 4.0.0-beta.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a0c1a4`](https://github.com/Effect-TS/effect-smol/commit/5a0c1a4faee5707b5cc35e646ff1ffdad70f1956), [`1eea2ea`](https://github.com/Effect-TS/effect-smol/commit/1eea2ea3795ba47316b82b1ac8d4612c0ba389ed)]:
|
||||
- effect@4.0.0-beta.87
|
||||
|
||||
## 4.0.0-beta.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0b5795a`](https://github.com/Effect-TS/effect-smol/commit/0b5795a0ab4395e8f15955d8d96f2303084bfc64), [`3e3a859`](https://github.com/Effect-TS/effect-smol/commit/3e3a859ec6351a9e0d31674aabbd48fcefabb12e), [`7dbec24`](https://github.com/Effect-TS/effect-smol/commit/7dbec240dbf3bca599a20c486632abce694ef5ab), [`d8c00a1`](https://github.com/Effect-TS/effect-smol/commit/d8c00a171ac7141e8adc08c332d1162d9a9d56fc), [`85b6317`](https://github.com/Effect-TS/effect-smol/commit/85b631701e935866f2762bd595237aa718370cd9), [`6d0fda0`](https://github.com/Effect-TS/effect-smol/commit/6d0fda0d0cbdfffc523c89c57dfdb1608f84fb12), [`108a933`](https://github.com/Effect-TS/effect-smol/commit/108a9335ff8571928197e5847a09c28ac83d6f46), [`7e1f455`](https://github.com/Effect-TS/effect-smol/commit/7e1f455fab5005d769b939c91e519d450f802cf9), [`46b3e79`](https://github.com/Effect-TS/effect-smol/commit/46b3e79944cfdae7901eb148135c85b7eb39834e)]:
|
||||
- effect@4.0.0-beta.86
|
||||
|
||||
## 4.0.0-beta.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`328d97c`](https://github.com/Effect-TS/effect-smol/commit/328d97cc53c0dcb89077a5623e35b095eaa59a8c), [`8441836`](https://github.com/Effect-TS/effect-smol/commit/8441836e6dde70e8ae2126be9cefe9b45798b134), [`074e436`](https://github.com/Effect-TS/effect-smol/commit/074e4361091289104cb0ab6959dc3b0ea7794a6a), [`c1dfd60`](https://github.com/Effect-TS/effect-smol/commit/c1dfd60663eb13a58916f3712d877499943b628a), [`2ba316b`](https://github.com/Effect-TS/effect-smol/commit/2ba316bd15fcbf1c50626500d44a2c9b3bec19f5), [`7ce7344`](https://github.com/Effect-TS/effect-smol/commit/7ce7344c41056c79e2ee19ee6a9346c0f1d227c1)]:
|
||||
- effect@4.0.0-beta.85
|
||||
|
||||
## 4.0.0-beta.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2379](https://github.com/Effect-TS/effect-smol/pull/2379) [`717d1c8`](https://github.com/Effect-TS/effect-smol/commit/717d1c8b160d4de631b6b7938abcad9e3472c3d7) Thanks @walln! - Convert audio file parts in prompts into OpenRouter `input_audio` content blocks.
|
||||
|
||||
Previously, every non-image file part was converted into a generic `file` content block. OpenRouter only accepts audio as base64-encoded `input_audio` content parts, so audio attachments were rejected or mishandled by the upstream provider.
|
||||
|
||||
Audio file parts with a recognized `mediaType` (aac, aiff, flac, m4a, mp3, ogg, pcm16, pcm24, and wav) are now converted into `input_audio` blocks. Unsupported audio media types and `URL` audio data fail with an `AiError` since OpenRouter requires base64-encoded audio data and does not fetch audio URLs.
|
||||
|
||||
- Updated dependencies [[`87f52ba`](https://github.com/Effect-TS/effect-smol/commit/87f52ba16c4370ffa3f84bf8e53038e1419c284e), [`b8ee07f`](https://github.com/Effect-TS/effect-smol/commit/b8ee07ffda8903b5ec2e45a786ddcba59f128fda), [`867c0d7`](https://github.com/Effect-TS/effect-smol/commit/867c0d70a09079b040260d45a1e92ff04dbfbf2f), [`b93bc6c`](https://github.com/Effect-TS/effect-smol/commit/b93bc6c9cb27b909a41d094c97c4f9d25bbc6d6b), [`57d387f`](https://github.com/Effect-TS/effect-smol/commit/57d387f92c30ab63e15e3e641f0a903b65886610), [`bacca41`](https://github.com/Effect-TS/effect-smol/commit/bacca4141c2400effae1eabfdb36c89a459cf246), [`0f8ac79`](https://github.com/Effect-TS/effect-smol/commit/0f8ac7959d29ed68c68ce25aabd6bf0cb7e63ecc), [`25b4482`](https://github.com/Effect-TS/effect-smol/commit/25b448270c01317703f25107e1480d4cd0246d9a), [`9cf3a25`](https://github.com/Effect-TS/effect-smol/commit/9cf3a25c66b0c44a52be9829870c44517ea52db2), [`8def767`](https://github.com/Effect-TS/effect-smol/commit/8def7674b1787f91035298cda4d122937e87ef72)]:
|
||||
- effect@4.0.0-beta.84
|
||||
|
||||
## 4.0.0-beta.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1f2e8ce`](https://github.com/Effect-TS/effect-smol/commit/1f2e8ceef09e0a791c850ed2ade01f97089596f9)]:
|
||||
- effect@4.0.0-beta.83
|
||||
|
||||
## 4.0.0-beta.82
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`193690b`](https://github.com/Effect-TS/effect-smol/commit/193690b642ea802bbed40d663bd677251bbe9dc3)]:
|
||||
- effect@4.0.0-beta.82
|
||||
|
||||
## 4.0.0-beta.81
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`93cb4f8`](https://github.com/Effect-TS/effect-smol/commit/93cb4f8fbfb9e07cb9dc86ce6b155fd1f8167914), [`60341d9`](https://github.com/Effect-TS/effect-smol/commit/60341d9ca744d0473ce3fab621ca9bd225af3a39), [`1105ab5`](https://github.com/Effect-TS/effect-smol/commit/1105ab56cb724212f7ea7b431396ce82e8fd0484), [`4500fbf`](https://github.com/Effect-TS/effect-smol/commit/4500fbfe00763d8a72af6e5d6c5988e8bd4ade36)]:
|
||||
- effect@4.0.0-beta.81
|
||||
|
||||
## 4.0.0-beta.80
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d944330`](https://github.com/Effect-TS/effect-smol/commit/d94433090ee03f426d43e13b883abae4494e55e6), [`f48659f`](https://github.com/Effect-TS/effect-smol/commit/f48659fdcc84930ebc1e5b45b540c0f973389182), [`7652aaa`](https://github.com/Effect-TS/effect-smol/commit/7652aaa3bdbc39f241fe58b54b9a43b713e22e12), [`98630b7`](https://github.com/Effect-TS/effect-smol/commit/98630b7c8f679c352ba6796636c85688fa009d8d), [`90ae23c`](https://github.com/Effect-TS/effect-smol/commit/90ae23cf07284da5e1bcd9dffa882e85df7e617b)]:
|
||||
- effect@4.0.0-beta.80
|
||||
|
||||
## 4.0.0-beta.79
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b9704dc`](https://github.com/Effect-TS/effect-smol/commit/b9704dc9de9f1649ad502371014fe869b69a49a3), [`a207113`](https://github.com/Effect-TS/effect-smol/commit/a207113f66837bb54416926718a9a7d66774d079), [`5e9b9e2`](https://github.com/Effect-TS/effect-smol/commit/5e9b9e217b164ebfd4a002dd4380b3b1563200c3), [`7c128ae`](https://github.com/Effect-TS/effect-smol/commit/7c128aef458a1e2d224712e51c483c9badad1d44), [`0ada457`](https://github.com/Effect-TS/effect-smol/commit/0ada457c0513d8d908254ab77ebb7d29d2b523d6), [`d7cc5a2`](https://github.com/Effect-TS/effect-smol/commit/d7cc5a2bede3de10943aa0c6bdb4f26836a91efd), [`aad63be`](https://github.com/Effect-TS/effect-smol/commit/aad63becf65e0a6b076e94f8973be7bbe7fbd46f), [`09809f6`](https://github.com/Effect-TS/effect-smol/commit/09809f60f19ec98232f98b33e33e02ecb7e4fbd6), [`2fddda5`](https://github.com/Effect-TS/effect-smol/commit/2fddda5311929f46b61e503f0ade4fc749e8c77d), [`5f21768`](https://github.com/Effect-TS/effect-smol/commit/5f2176833399757c4500d8875b7f2fba0393de75), [`f27003e`](https://github.com/Effect-TS/effect-smol/commit/f27003e00524ff83f20dd9909f62b2f8795efe03)]:
|
||||
- effect@4.0.0-beta.79
|
||||
|
||||
## 4.0.0-beta.78
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7836b8e`](https://github.com/Effect-TS/effect-smol/commit/7836b8eb8bb0f3e04cdf554ee070caccf74f00c1), [`35d49a3`](https://github.com/Effect-TS/effect-smol/commit/35d49a3a09bdba6b513de87ddcead9e61a1042ba), [`4093258`](https://github.com/Effect-TS/effect-smol/commit/40932580e65bafab5f23c5f14b520cb411d0b2cd)]:
|
||||
- effect@4.0.0-beta.78
|
||||
|
||||
## 4.0.0-beta.77
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6e9a5ca`](https://github.com/Effect-TS/effect-smol/commit/6e9a5ca62a61156fd67b2518ad3ab14ac0d25f23), [`302f398`](https://github.com/Effect-TS/effect-smol/commit/302f3984ce206e35d86ddd99d3b72be144850a51)]:
|
||||
- effect@4.0.0-beta.77
|
||||
|
||||
## 4.0.0-beta.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`016108a`](https://github.com/Effect-TS/effect-smol/commit/016108a472af7048ddbbfd05f233e67529fafe12), [`95c03d2`](https://github.com/Effect-TS/effect-smol/commit/95c03d2c55930668c215b5a41c23cf7742fead84), [`07299a3`](https://github.com/Effect-TS/effect-smol/commit/07299a33c09fd52faa9810d30835a2622c752386)]:
|
||||
- effect@4.0.0-beta.76
|
||||
|
||||
## 4.0.0-beta.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`81b187c`](https://github.com/Effect-TS/effect-smol/commit/81b187c17a0d8817b58232826939154010ae49d7), [`ad4b535`](https://github.com/Effect-TS/effect-smol/commit/ad4b535e17f94ce35261829d5a3675f0a7808b4e), [`a29c2e7`](https://github.com/Effect-TS/effect-smol/commit/a29c2e7e3570920156702671d6f3367cd0195f6c), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`ffea4ec`](https://github.com/Effect-TS/effect-smol/commit/ffea4ecf2925f6a4c9fd13079d47584cbf2bed00), [`4255c9b`](https://github.com/Effect-TS/effect-smol/commit/4255c9ba78bb98c7838fbe9dccdd8465e9da5427)]:
|
||||
- effect@4.0.0-beta.75
|
||||
|
||||
## 4.0.0-beta.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b1fc6a4`](https://github.com/Effect-TS/effect-smol/commit/b1fc6a4b4d0ca7fa9fd162799ae17c86f2f7ee8e)]:
|
||||
- effect@4.0.0-beta.74
|
||||
|
||||
## 4.0.0-beta.73
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`361ca30`](https://github.com/Effect-TS/effect-smol/commit/361ca30eb6e134feece547d6e00f82be4cb23f75), [`b9598c6`](https://github.com/Effect-TS/effect-smol/commit/b9598c6a209e75bfdb87ee3b024ecd1e3923ff6e)]:
|
||||
- effect@4.0.0-beta.73
|
||||
|
||||
## 4.0.0-beta.72
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`73e67d1`](https://github.com/Effect-TS/effect-smol/commit/73e67d119a84d697773eaecb4865c6a71eb1a9cb), [`01d71ec`](https://github.com/Effect-TS/effect-smol/commit/01d71ec5a75f3c2747a8d3b1ad9701d1e27b7ce5), [`fcd707e`](https://github.com/Effect-TS/effect-smol/commit/fcd707e091a16e1b35343c901cc4052274e32239)]:
|
||||
- effect@4.0.0-beta.72
|
||||
|
||||
## 4.0.0-beta.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d8ac76b`](https://github.com/Effect-TS/effect-smol/commit/d8ac76b5bad458c42cebe8a0c1b3843f955ac293), [`2c3c00a`](https://github.com/Effect-TS/effect-smol/commit/2c3c00af6faba7b7d422af26a7a2bbc35636d230), [`3751e7c`](https://github.com/Effect-TS/effect-smol/commit/3751e7cf353e7a54cd692c37401207d9afba1e63), [`fc5f25b`](https://github.com/Effect-TS/effect-smol/commit/fc5f25b03ada5fc2431987768a74d3d3e75ca485), [`7ccced4`](https://github.com/Effect-TS/effect-smol/commit/7ccced42867c14c013b01160b3d292f14c05bd04), [`a2e1fe5`](https://github.com/Effect-TS/effect-smol/commit/a2e1fe5835c98c8ee4393a091b1d11b75126e349), [`4a4a36b`](https://github.com/Effect-TS/effect-smol/commit/4a4a36b10e6e616cad07584a43908f6a7e07e618), [`d350292`](https://github.com/Effect-TS/effect-smol/commit/d3502922b4740fa9d745797cbc3775cb67839b6d), [`730afb6`](https://github.com/Effect-TS/effect-smol/commit/730afb66696adf9bd5a328cbca29df9c05968771), [`df1b008`](https://github.com/Effect-TS/effect-smol/commit/df1b008f370f414c2a67a7b8139ef747af8e5fba), [`6d469d5`](https://github.com/Effect-TS/effect-smol/commit/6d469d567a7c41d7e5343bdee21d45b07b0e8190)]:
|
||||
- effect@4.0.0-beta.71
|
||||
|
||||
## 4.0.0-beta.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af7782d`](https://github.com/Effect-TS/effect-smol/commit/af7782d3008d08b043f3a3f261516001514b2b4e), [`7212d70`](https://github.com/Effect-TS/effect-smol/commit/7212d701a3eee7b3553ff502e2c066126e52e839)]:
|
||||
- effect@4.0.0-beta.70
|
||||
|
||||
## 4.0.0-beta.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70ea04a`](https://github.com/Effect-TS/effect-smol/commit/70ea04aa96a2a7859d738d414e1f0e3ed081a27a), [`d0ea8b0`](https://github.com/Effect-TS/effect-smol/commit/d0ea8b03f7d73ae076c1db12666141e480d11178), [`a57674b`](https://github.com/Effect-TS/effect-smol/commit/a57674b64845e9e75a456cf907bfdcb858859118), [`59aa334`](https://github.com/Effect-TS/effect-smol/commit/59aa334fbd0a504dda3c36f6d2ef1be7449b4b8b), [`8f4208e`](https://github.com/Effect-TS/effect-smol/commit/8f4208ee83bc7bdaa6793b5429847b45aab72470)]:
|
||||
- effect@4.0.0-beta.69
|
||||
|
||||
## 4.0.0-beta.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af8267f`](https://github.com/Effect-TS/effect-smol/commit/af8267f2f3588c3fb611e9286f6f933f29ce1217), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`f136bb7`](https://github.com/Effect-TS/effect-smol/commit/f136bb763048cbc6b17edd26496dba3e2415b9fa), [`6f38f07`](https://github.com/Effect-TS/effect-smol/commit/6f38f07d5941a211b251383aaab0f4f55e8a6557), [`aec9c40`](https://github.com/Effect-TS/effect-smol/commit/aec9c401a53db227f18bf5e0c84db7130ad862d6)]:
|
||||
- effect@4.0.0-beta.68
|
||||
|
||||
## 4.0.0-beta.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a42ef66`](https://github.com/Effect-TS/effect-smol/commit/a42ef6632abbddfa820995ae310ccc84ae8d9b6f), [`35594f8`](https://github.com/Effect-TS/effect-smol/commit/35594f811cafe471acd490114b103a1f8392c8d8), [`8bddd62`](https://github.com/Effect-TS/effect-smol/commit/8bddd628cb623f9533d345082583ff51cead6836), [`4be4c8d`](https://github.com/Effect-TS/effect-smol/commit/4be4c8d60862aa963869ee2ed9ffa048ffac0527), [`0c9d3ab`](https://github.com/Effect-TS/effect-smol/commit/0c9d3ab43eb721a370ed8306260cbac218c27e87), [`b156acc`](https://github.com/Effect-TS/effect-smol/commit/b156accd2691b4a051f823affdece7c39923ce85), [`d16c034`](https://github.com/Effect-TS/effect-smol/commit/d16c03434ee3e6dcd3bfc82b65d99e881d89025b), [`b559d68`](https://github.com/Effect-TS/effect-smol/commit/b559d68845f848a10153395778f035682d399075), [`a3de5d9`](https://github.com/Effect-TS/effect-smol/commit/a3de5d9215e5cc4a62e2666efbd7c1bf595eb84f), [`7e6c12e`](https://github.com/Effect-TS/effect-smol/commit/7e6c12ec9b3a5945f6c26e272cc8f6390541ad3e), [`098167a`](https://github.com/Effect-TS/effect-smol/commit/098167a220fe07da6f14455818733ab1b269c9dd)]:
|
||||
- effect@4.0.0-beta.67
|
||||
|
||||
## 4.0.0-beta.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ca2498e`](https://github.com/Effect-TS/effect-smol/commit/ca2498e702ac2d83fb7187707b7eb069bdb261a2), [`cd7d1fb`](https://github.com/Effect-TS/effect-smol/commit/cd7d1fba7e2e2c5ac3ad64e1be433440a5bda436), [`19a7033`](https://github.com/Effect-TS/effect-smol/commit/19a703367ec817cffc41d152da9b594827408e2b), [`33d26b4`](https://github.com/Effect-TS/effect-smol/commit/33d26b4210b2e974f146a71e7eed962f8ce00900), [`856766b`](https://github.com/Effect-TS/effect-smol/commit/856766b2c506aaed6d2df1d63bf3a5b1b062e1d4), [`079c7df`](https://github.com/Effect-TS/effect-smol/commit/079c7df82559bb9ce10a86dffb85d25e6ce07dc3)]:
|
||||
- effect@4.0.0-beta.66
|
||||
|
||||
## 4.0.0-beta.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6f11454`](https://github.com/Effect-TS/effect-smol/commit/6f11454a9b6c3bd00f6b35fd7af14a2f2d63a0a2)]:
|
||||
- effect@4.0.0-beta.65
|
||||
|
||||
## 4.0.0-beta.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d4877a`](https://github.com/Effect-TS/effect-smol/commit/7d4877a1929cdb690280ea254326c04f2ec97ea5)]:
|
||||
- effect@4.0.0-beta.64
|
||||
|
||||
## 4.0.0-beta.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7f927ff`](https://github.com/Effect-TS/effect-smol/commit/7f927ffb7a9801dcfc4096c29e369d13d65cd0ac), [`a696b3e`](https://github.com/Effect-TS/effect-smol/commit/a696b3e83a8504cdbe261a18c10a1cc0619ae102)]:
|
||||
- effect@4.0.0-beta.63
|
||||
|
||||
## 4.0.0-beta.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4ab4b90`](https://github.com/Effect-TS/effect-smol/commit/4ab4b9007dc27a52ffabc6fcb37c96eeec795bf7)]:
|
||||
- effect@4.0.0-beta.62
|
||||
|
||||
## 4.0.0-beta.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`50790af`](https://github.com/Effect-TS/effect-smol/commit/50790af9b190c38d10fb0723837d49b66432638f), [`71f7c3d`](https://github.com/Effect-TS/effect-smol/commit/71f7c3df997deda92c84146d569696dab3bd645c), [`aae8797`](https://github.com/Effect-TS/effect-smol/commit/aae8797b9cb383be0c182dd58d03d787c354238b)]:
|
||||
- effect@4.0.0-beta.61
|
||||
|
||||
## 4.0.0-beta.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f69d567`](https://github.com/Effect-TS/effect-smol/commit/f69d5675dcff9f4137295752baf066b7153fdc09), [`7909c95`](https://github.com/Effect-TS/effect-smol/commit/7909c954b8f6244a35a4b429f8dd0dff45dad620), [`bbb4dcc`](https://github.com/Effect-TS/effect-smol/commit/bbb4dcc6c406b83a416b4ad3541cc02037c420e4), [`7af2207`](https://github.com/Effect-TS/effect-smol/commit/7af2207901eabf3132c1b7010a69b3899c06fbbe), [`848b40a`](https://github.com/Effect-TS/effect-smol/commit/848b40a4bd4bf54a5098617d50c33c88eee8270a)]:
|
||||
- effect@4.0.0-beta.60
|
||||
|
||||
## 4.0.0-beta.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`56837ea`](https://github.com/Effect-TS/effect-smol/commit/56837ea2a338395b35550641374e9e589bd8b71d)]:
|
||||
- effect@4.0.0-beta.59
|
||||
|
||||
## 4.0.0-beta.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`11993d4`](https://github.com/Effect-TS/effect-smol/commit/11993d4934c66f5dc611b8bbf553f01d501ef8f7), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec)]:
|
||||
- effect@4.0.0-beta.58
|
||||
|
||||
## 4.0.0-beta.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a971f5c`](https://github.com/Effect-TS/effect-smol/commit/a971f5cbd92dfe4274420bf0966595eb35531060), [`8e110c5`](https://github.com/Effect-TS/effect-smol/commit/8e110c5f02a429ccc43a91df8678e402138c0851)]:
|
||||
- effect@4.0.0-beta.57
|
||||
|
||||
## 4.0.0-beta.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.56
|
||||
|
||||
## 4.0.0-beta.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42cc744`](https://github.com/Effect-TS/effect-smol/commit/42cc744570968deb365fb46d47b53d3277050c93), [`04855ce`](https://github.com/Effect-TS/effect-smol/commit/04855ceeca4d40c55a5750dd9893b691f8ea741a)]:
|
||||
- effect@4.0.0-beta.55
|
||||
|
||||
## 4.0.0-beta.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e4b74f9`](https://github.com/Effect-TS/effect-smol/commit/e4b74f9c01a0e9b6cd58416de4af3a26d51da7c8), [`4c72808`](https://github.com/Effect-TS/effect-smol/commit/4c728081851c66dacf889a816535671bc841ae96)]:
|
||||
- effect@4.0.0-beta.54
|
||||
|
||||
## 4.0.0-beta.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0768509`](https://github.com/Effect-TS/effect-smol/commit/07685094e931af07d104165195826a535b55fa7e), [`476aede`](https://github.com/Effect-TS/effect-smol/commit/476aede69c6efa06b5781ca5eb3e3b128ca29141), [`4f79c54`](https://github.com/Effect-TS/effect-smol/commit/4f79c542e7b508c235ff485d862cc8b29a8260c5), [`4be6a7c`](https://github.com/Effect-TS/effect-smol/commit/4be6a7cf35dab2a01d652f56dd35f0358c5a7e88), [`88927eb`](https://github.com/Effect-TS/effect-smol/commit/88927ebb896162cdba103b36553280b58e0facac)]:
|
||||
- effect@4.0.0-beta.53
|
||||
|
||||
## 4.0.0-beta.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`cf3a311`](https://github.com/Effect-TS/effect-smol/commit/cf3a311d863a8abb818840c3b80f847e621c43c1), [`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`131fdd5`](https://github.com/Effect-TS/effect-smol/commit/131fdd5b1f26531e265fe1a08f002002f47c276e)]:
|
||||
- effect@4.0.0-beta.52
|
||||
|
||||
## 4.0.0-beta.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`778d2af`](https://github.com/Effect-TS/effect-smol/commit/778d2afe9b5154bc1f9abae46d93ea7e54c87344), [`4e24dcf`](https://github.com/Effect-TS/effect-smol/commit/4e24dcf75037f65eebc1eb68623bc7cbf9d5512a), [`4b1c015`](https://github.com/Effect-TS/effect-smol/commit/4b1c0150e9bdb5559ed32d250deb66e17b4240c7), [`454f8ad`](https://github.com/Effect-TS/effect-smol/commit/454f8adad822929c3ef60f8280d0987226b049fd), [`6754a0c`](https://github.com/Effect-TS/effect-smol/commit/6754a0cd18626b06805a079cc5265525a5eb7d27), [`90f7fd5`](https://github.com/Effect-TS/effect-smol/commit/90f7fd5243871b30980964135db4512b8119fa82), [`d7e1519`](https://github.com/Effect-TS/effect-smol/commit/d7e151974934201fd93fa4c8a1192ee9a5d965a0), [`72a8122`](https://github.com/Effect-TS/effect-smol/commit/72a81228e09782bae512f7d041bbfbc78bc668d0)]:
|
||||
- effect@4.0.0-beta.51
|
||||
|
||||
## 4.0.0-beta.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`07be594`](https://github.com/Effect-TS/effect-smol/commit/07be594825de60f8e1b2102d21dbb9b8fc63b414), [`ae02433`](https://github.com/Effect-TS/effect-smol/commit/ae02433103ce28f53a0c9bfb4a44e75773289b7b)]:
|
||||
- effect@4.0.0-beta.50
|
||||
|
||||
## 4.0.0-beta.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d87873`](https://github.com/Effect-TS/effect-smol/commit/7d8787340ff549370f6f2a88b612e9ebbfd6ba45), [`c2f6f90`](https://github.com/Effect-TS/effect-smol/commit/c2f6f901b200a6e515b4f02c93ce8005b7bbf1c5), [`216f13c`](https://github.com/Effect-TS/effect-smol/commit/216f13c1fce454a21b489bb915714a17e791a1ac)]:
|
||||
- effect@4.0.0-beta.49
|
||||
|
||||
## 4.0.0-beta.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4da56ec`](https://github.com/Effect-TS/effect-smol/commit/4da56ecff129b2da40137ffede23a73cc4e532d8), [`a5e6f77`](https://github.com/Effect-TS/effect-smol/commit/a5e6f774bab195cf50ecdc818240765f69a3bf4a), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070)]:
|
||||
- effect@4.0.0-beta.48
|
||||
|
||||
## 4.0.0-beta.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c584726`](https://github.com/Effect-TS/effect-smol/commit/c58472674e750e6938df955044eab88feda95e45), [`86a91a4`](https://github.com/Effect-TS/effect-smol/commit/86a91a4f0c59286dfa9393232d8020dea70ed4db), [`131caf9`](https://github.com/Effect-TS/effect-smol/commit/131caf9525151a0cb29803a8f1dffa0f4f479d12), [`c3615c8`](https://github.com/Effect-TS/effect-smol/commit/c3615c88379b9daf252df0db72c6ac5a20326406)]:
|
||||
- effect@4.0.0-beta.47
|
||||
|
||||
## 4.0.0-beta.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a30b9e`](https://github.com/Effect-TS/effect-smol/commit/3a30b9e2ec2bd8b8193e1aa139f6878a07e3f5ee)]:
|
||||
- effect@4.0.0-beta.46
|
||||
|
||||
## 4.0.0-beta.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c3af6d`](https://github.com/Effect-TS/effect-smol/commit/5c3af6d554f60be34f8fc21d598d9a298ae11beb)]:
|
||||
- effect@4.0.0-beta.45
|
||||
|
||||
## 4.0.0-beta.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1961](https://github.com/Effect-TS/effect-smol/pull/1961) [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970) Thanks @IMax153! - Rename the `ServiceMap` module to `Context` across exports, docs, and tests.
|
||||
|
||||
- Updated dependencies [[`e3f0621`](https://github.com/Effect-TS/effect-smol/commit/e3f0621454c3f5d11070d30619da27c9232cadc1), [`5b476ab`](https://github.com/Effect-TS/effect-smol/commit/5b476abc0bd7e9bb59135ea1bcad2e4936227ced), [`6b40e5a`](https://github.com/Effect-TS/effect-smol/commit/6b40e5a4a6bd2087c15a3d7374d25057fdedfa16), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`3b09fb3`](https://github.com/Effect-TS/effect-smol/commit/3b09fb31c40c2802b01f21c23bcdd1fe7fb0aa82), [`2370410`](https://github.com/Effect-TS/effect-smol/commit/237041062e5af4594d32db91597e34e70a632877), [`dabc272`](https://github.com/Effect-TS/effect-smol/commit/dabc272444a700eb629c07ba3e77671a841ca86e), [`08b63c3`](https://github.com/Effect-TS/effect-smol/commit/08b63c3df11bd35c9fd6090dbd166287fdc40664), [`dfff04c`](https://github.com/Effect-TS/effect-smol/commit/dfff04c4c2b1d352dfad83992a6dce1280c85cf9), [`9baed9e`](https://github.com/Effect-TS/effect-smol/commit/9baed9e17e84702e6e480fcef6f86404f9e24be9), [`7846792`](https://github.com/Effect-TS/effect-smol/commit/7846792adc7e1631d62d26d657bd7ba6139f369b), [`1556a24`](https://github.com/Effect-TS/effect-smol/commit/1556a247623636b7ebe438fb56d77f1a7bf957bb), [`7c11bc2`](https://github.com/Effect-TS/effect-smol/commit/7c11bc292ab8e46252fe8f7576fb685917bfb8b5), [`b5ea591`](https://github.com/Effect-TS/effect-smol/commit/b5ea5913ec1d45d0dd12a327b9dd966bda2f6d02), [`0853afa`](https://github.com/Effect-TS/effect-smol/commit/0853afaeb1633b2d7f8b66893bd01c3aa1ef2c22), [`ac845f3`](https://github.com/Effect-TS/effect-smol/commit/ac845f3ab40e0b8719576e7f9bc16ea2e0e02cd4), [`b80c462`](https://github.com/Effect-TS/effect-smol/commit/b80c46247480f47bb64fc480fab48a3f37bc8888), [`b3f535d`](https://github.com/Effect-TS/effect-smol/commit/b3f535d9a7ac13b5fb984c29f93561c57a081ff0), [`6fe2e93`](https://github.com/Effect-TS/effect-smol/commit/6fe2e93cc2f1b173ef89651d74b6a5d2626b3226), [`cda8004`](https://github.com/Effect-TS/effect-smol/commit/cda800451c1ffbdddfc08415aed7b2d91e0412ee), [`8335477`](https://github.com/Effect-TS/effect-smol/commit/8335477a8a936a24b5f3ee6203c1b268bd1bfc3c), [`8c836f9`](https://github.com/Effect-TS/effect-smol/commit/8c836f99ab1e896b9580a71d67773625baff2eaf), [`718ff6f`](https://github.com/Effect-TS/effect-smol/commit/718ff6fe3e3d3820cefd67d2bff1b2224fe08060), [`7eed84f`](https://github.com/Effect-TS/effect-smol/commit/7eed84fc33c5781a6fb11bf4fd189d424902ebd4), [`5df46fe`](https://github.com/Effect-TS/effect-smol/commit/5df46fe2f654d59ab5fc1578f4fc27fa40368ef9), [`82dd0f2`](https://github.com/Effect-TS/effect-smol/commit/82dd0f26c6442b07143762ef7bc33742d3978dd6), [`03ae41e`](https://github.com/Effect-TS/effect-smol/commit/03ae41e7304cffac9f18feea22b73468feafc43a), [`4677a0a`](https://github.com/Effect-TS/effect-smol/commit/4677a0a58f95eea38a211efcd3f345f237a9e44a), [`87e1fc8`](https://github.com/Effect-TS/effect-smol/commit/87e1fc8b67e4901d75f567b2fecc3841ab762cc4), [`c1af1b7`](https://github.com/Effect-TS/effect-smol/commit/c1af1b756f63291e9c0298cf95c98a6920a0c2a0), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`c8a877b`](https://github.com/Effect-TS/effect-smol/commit/c8a877b53e8f29616335719e5dd1c3992dddf780), [`7da961a`](https://github.com/Effect-TS/effect-smol/commit/7da961ae4916229d2246699a5d3b20e5b2dd2020)]:
|
||||
- effect@4.0.0-beta.44
|
||||
|
||||
## 4.0.0-beta.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`2ae33d0`](https://github.com/Effect-TS/effect-smol/commit/2ae33d050914915f7cb9c25ab0a020901e08d596), [`979811a`](https://github.com/Effect-TS/effect-smol/commit/979811a4c3f7ed21ed18ef560c49fb7f5569e80e), [`eb7dbef`](https://github.com/Effect-TS/effect-smol/commit/eb7dbeffa883386ad912815e62c0820cac1fdf8e), [`cf50eb4`](https://github.com/Effect-TS/effect-smol/commit/cf50eb49cb04706dae5185f624708117c413dee8), [`1d046fe`](https://github.com/Effect-TS/effect-smol/commit/1d046fe484560e23f3e22cb23eec6433f8f1fa02)]:
|
||||
- effect@4.0.0-beta.43
|
||||
|
||||
## 4.0.0-beta.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`924e216`](https://github.com/Effect-TS/effect-smol/commit/924e216caa7e0bbf22e994a0cd2ce8b1f0f0b3ee), [`80e7f0c`](https://github.com/Effect-TS/effect-smol/commit/80e7f0cd9116e811e97b0ce30a77a8d1ecd072aa), [`f8328bf`](https://github.com/Effect-TS/effect-smol/commit/f8328bf0314da3dc7f31d314f94a5840e8d5217f), [`66d1c06`](https://github.com/Effect-TS/effect-smol/commit/66d1c06039079129707a230f7ad8c676439d7133), [`bee800b`](https://github.com/Effect-TS/effect-smol/commit/bee800bf285192a01bec72a7b7b51bc1159434e6), [`8930441`](https://github.com/Effect-TS/effect-smol/commit/8930441dee6f94c59c583d18d3ebd677cf1f2623)]:
|
||||
- effect@4.0.0-beta.42
|
||||
|
||||
## 4.0.0-beta.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1871](https://github.com/Effect-TS/effect-smol/pull/1871) [`977386d`](https://github.com/Effect-TS/effect-smol/commit/977386da5e2e8aac2c07e99175673e0b5771191b) Thanks @IMax153! - Fix HTTP Referer header name in the `OpenRouterClient`
|
||||
|
||||
- Updated dependencies [[`36f5c21`](https://github.com/Effect-TS/effect-smol/commit/36f5c2174d31ab42c4598bf81f178f40d0802283), [`d8ce758`](https://github.com/Effect-TS/effect-smol/commit/d8ce758669d6297ae932ac3251d83e7b49b22f30), [`11aab4c`](https://github.com/Effect-TS/effect-smol/commit/11aab4c6d37d5691adafc2d33da1a631b28ce814), [`3bc1efb`](https://github.com/Effect-TS/effect-smol/commit/3bc1efb53dd75b4a40de46f1f80c7f8a7d50af86), [`70e724e`](https://github.com/Effect-TS/effect-smol/commit/70e724e604604d4be1061cd8da0d360494998c84), [`738dee7`](https://github.com/Effect-TS/effect-smol/commit/738dee7edfd70af82dc4d2376db3a8ebe603eb48), [`2111963`](https://github.com/Effect-TS/effect-smol/commit/2111963f19b4c28c800664a8fac9590c1321885f), [`198a553`](https://github.com/Effect-TS/effect-smol/commit/198a553d9ce45f6a00bfc4d65ed0640669602d95)]:
|
||||
- effect@4.0.0-beta.41
|
||||
|
||||
## 4.0.0-beta.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f62860f`](https://github.com/Effect-TS/effect-smol/commit/f62860f0e5e45978fabf7256ae620a13152a772a), [`973f281`](https://github.com/Effect-TS/effect-smol/commit/973f2812529aadc1cc54598b2039799fa72b80f8)]:
|
||||
- effect@4.0.0-beta.40
|
||||
|
||||
## 4.0.0-beta.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f91fd3d`](https://github.com/Effect-TS/effect-smol/commit/f91fd3db39fe5628439fd175fba201a65a1aa9d0), [`edaae9d`](https://github.com/Effect-TS/effect-smol/commit/edaae9d65f464f941d7eddd723cd33d324f4b071), [`b47db0b`](https://github.com/Effect-TS/effect-smol/commit/b47db0bd5802064b6a24b3ea27c6ff2e0520d513), [`82d3c8e`](https://github.com/Effect-TS/effect-smol/commit/82d3c8e4f3f49b00df611b25aa6f8f74ec21b59b), [`7c22b31`](https://github.com/Effect-TS/effect-smol/commit/7c22b315d198dcbf44ae8cdb8b37879e1c9e3996)]:
|
||||
- effect@4.0.0-beta.39
|
||||
|
||||
## 4.0.0-beta.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f4dbe5b`](https://github.com/Effect-TS/effect-smol/commit/f4dbe5b26b9c2d33fae024bf44afbdf8541792cd), [`a71a607`](https://github.com/Effect-TS/effect-smol/commit/a71a607c89fb6669a12a562c2c23be81dfbe1adb), [`66a0494`](https://github.com/Effect-TS/effect-smol/commit/66a0494ed75cd12f2721dcbb1d8a072e3d9e14b6), [`5ef7218`](https://github.com/Effect-TS/effect-smol/commit/5ef7218fc559d57301fe929b8a0cab4033f4f1fd), [`472d260`](https://github.com/Effect-TS/effect-smol/commit/472d260655bc311fba5c2c6e23bb77d8f7e36ba0)]:
|
||||
- effect@4.0.0-beta.38
|
||||
|
||||
## 4.0.0-beta.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f7a0b71`](https://github.com/Effect-TS/effect-smol/commit/f7a0b711da8fdd645597dee29cacc5619c6afcf2), [`1e223c3`](https://github.com/Effect-TS/effect-smol/commit/1e223c30ccf835dfbb21284535d78549efaeca80), [`53740f4`](https://github.com/Effect-TS/effect-smol/commit/53740f47aa76d114b7d535649fb50efc54a09608), [`8c7cf89`](https://github.com/Effect-TS/effect-smol/commit/8c7cf89f719e580cbce1bf6c24e6996f1992a0a6), [`b6b81a9`](https://github.com/Effect-TS/effect-smol/commit/b6b81a940eaafcbc792d25413d6c02c707de31b2), [`8f4c1f9`](https://github.com/Effect-TS/effect-smol/commit/8f4c1f97ed60f8810b0b327b50117ffb2d8260d4), [`f2479f9`](https://github.com/Effect-TS/effect-smol/commit/f2479f9d3113b1f012db17a3852b4e28f478cf9c), [`c919921`](https://github.com/Effect-TS/effect-smol/commit/c9199217fad65529421d2cf95ecfff41257090fd), [`7af90c2`](https://github.com/Effect-TS/effect-smol/commit/7af90c2e3c99038eafa39650433839523790e2fe), [`f3be185`](https://github.com/Effect-TS/effect-smol/commit/f3be18569e5ca57c25eabf00df3ca601ebab43c7)]:
|
||||
- effect@4.0.0-beta.37
|
||||
|
||||
## 4.0.0-beta.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`60fcbcc`](https://github.com/Effect-TS/effect-smol/commit/60fcbcc43d09471e8f7e0969955d99dcefc5be81), [`0a60837`](https://github.com/Effect-TS/effect-smol/commit/0a6083713124440e630030375bab367e8d7df24e), [`49164d2`](https://github.com/Effect-TS/effect-smol/commit/49164d2c20a8d21b66514992c4a15d8521f6b36e), [`334b6e4`](https://github.com/Effect-TS/effect-smol/commit/334b6e4f76fe11941b516d61f57e268bc31f0ca6), [`5700695`](https://github.com/Effect-TS/effect-smol/commit/5700695f76ae6da6b94c9c87d4dd2b8054fb829b), [`f8f4456`](https://github.com/Effect-TS/effect-smol/commit/f8f445644f3aa7ec093cab7445198a62ba18a480), [`969d24f`](https://github.com/Effect-TS/effect-smol/commit/969d24fdfa48c4838e811983848d9cb4e9b3b12c), [`851eda0`](https://github.com/Effect-TS/effect-smol/commit/851eda0533946e39bacaaf581896320d7a4f3e8c), [`8059c1c`](https://github.com/Effect-TS/effect-smol/commit/8059c1c3eba9a90af7cd889ea261bcb8fff0c185), [`6f83295`](https://github.com/Effect-TS/effect-smol/commit/6f8329546a73eaddc7cb5e85ea8e37e73fbfb611), [`65f7f57`](https://github.com/Effect-TS/effect-smol/commit/65f7f5737575fed668987462c96d29a446707c32), [`e7fabd2`](https://github.com/Effect-TS/effect-smol/commit/e7fabd2265db690eae5cfc9b83730c84699aef61), [`89c3e98`](https://github.com/Effect-TS/effect-smol/commit/89c3e985401eb38f33a3ae21a94ad27de3c1d28b), [`53794ab`](https://github.com/Effect-TS/effect-smol/commit/53794ab7af30aa5c5004ecf53659fafbe4b10542)]:
|
||||
- effect@4.0.0-beta.36
|
||||
|
||||
## 4.0.0-beta.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9252b43`](https://github.com/Effect-TS/effect-smol/commit/9252b43560f507709c2985abcf52a7837b23ddf8), [`7daf387`](https://github.com/Effect-TS/effect-smol/commit/7daf3870a656882a488a60f67881e6808c8f4d04), [`e1664a3`](https://github.com/Effect-TS/effect-smol/commit/e1664a38bc31ef4ceb4e9324c7226e1e99bf9c07), [`fdaa6e0`](https://github.com/Effect-TS/effect-smol/commit/fdaa6e0a41b6b6605438fa8557441792135380a2), [`19aa47e`](https://github.com/Effect-TS/effect-smol/commit/19aa47ef7b470e427620edca8970dd9cdd551216), [`c667dad`](https://github.com/Effect-TS/effect-smol/commit/c667dad07777b860e4764a3ba9a6cc41c236cd98), [`764d150`](https://github.com/Effect-TS/effect-smol/commit/764d1501bc5026b60fc8aef6cb02a5a87c762801), [`3c27098`](https://github.com/Effect-TS/effect-smol/commit/3c27098b5685a63db2c2eff654a250c94d3fcfa7)]:
|
||||
- effect@4.0.0-beta.35
|
||||
|
||||
## 4.0.0-beta.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f2f75ee`](https://github.com/Effect-TS/effect-smol/commit/f2f75ee564bce1cd95f5189c7bdeeed4f92dacb1), [`342fc4b`](https://github.com/Effect-TS/effect-smol/commit/342fc4b051739e32e7977159f26ff9541eda664f), [`5d704ee`](https://github.com/Effect-TS/effect-smol/commit/5d704ee10d20e8eb107e34bb8a21feb5aa4a7685), [`00add69`](https://github.com/Effect-TS/effect-smol/commit/00add69b59551e9df34772eb927638b093f6d71e), [`58217d3`](https://github.com/Effect-TS/effect-smol/commit/58217d318a7d716ccd707cce0f41573946939c28), [`f4e2aba`](https://github.com/Effect-TS/effect-smol/commit/f4e2aba01b76d1e3059b297e3cc942284dfeafb2), [`e3b44b6`](https://github.com/Effect-TS/effect-smol/commit/e3b44b6a2af9ee21dc5c1e928f0c20af857fa7a9), [`e1472b7`](https://github.com/Effect-TS/effect-smol/commit/e1472b7525c5d57a48bdec2353c3b742f7f916c0), [`7686320`](https://github.com/Effect-TS/effect-smol/commit/7686320cd123fa352b5c3d076fb18a3cac0a9bba)]:
|
||||
- effect@4.0.0-beta.34
|
||||
|
||||
## 4.0.0-beta.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`571447d`](https://github.com/Effect-TS/effect-smol/commit/571447da67334449f8ae3d6ecb3d77ea4e0c4295)]:
|
||||
- effect@4.0.0-beta.33
|
||||
|
||||
## 4.0.0-beta.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf8fff8`](https://github.com/Effect-TS/effect-smol/commit/bf8fff8a5f54b6df74cb7bbb42346fe9ba52435a), [`1af3ef3`](https://github.com/Effect-TS/effect-smol/commit/1af3ef3e3ca7fd417d0fc15f8ca8fe207eba4f74), [`27fea0f`](https://github.com/Effect-TS/effect-smol/commit/27fea0f66910de5905f40fd63f8ddbb6f7ac5aba), [`2ad6c1b`](https://github.com/Effect-TS/effect-smol/commit/2ad6c1b2c85a3a0fe351e3d56636a75eb76b4b4e), [`398ac3e`](https://github.com/Effect-TS/effect-smol/commit/398ac3e01cb75efce0e4e2913d1450cf65866732), [`51fe22f`](https://github.com/Effect-TS/effect-smol/commit/51fe22f3266e417b6c541aaed4b75d246fac91e7), [`4605db6`](https://github.com/Effect-TS/effect-smol/commit/4605db69cfacddbdbf1525865ddfde135158090c), [`f4de1b0`](https://github.com/Effect-TS/effect-smol/commit/f4de1b087c998d0bad1d9468f70b7d16c13b9f6f), [`60214f2`](https://github.com/Effect-TS/effect-smol/commit/60214f2080b2aeb091f691140eb20acb741691c3), [`c4b8b0f`](https://github.com/Effect-TS/effect-smol/commit/c4b8b0ffa8efb47c4cd7578a8943d6868509373f), [`6d9393a`](https://github.com/Effect-TS/effect-smol/commit/6d9393a0770a18722d23340e77f15455de341245), [`6de4efe`](https://github.com/Effect-TS/effect-smol/commit/6de4efe463c783614ceb0c094d77a336a899cbe0), [`4f969d1`](https://github.com/Effect-TS/effect-smol/commit/4f969d1563ba755ffa116c8ae409bb3436bd881d), [`6cc67c8`](https://github.com/Effect-TS/effect-smol/commit/6cc67c855e054ee3f3ac3485dca5f7805e79e8fb), [`8531a22`](https://github.com/Effect-TS/effect-smol/commit/8531a22ffbb52e11a030b09f358cafbfdf5edff7), [`b226760`](https://github.com/Effect-TS/effect-smol/commit/b22676067617f15c00722a3a63fd7c2c172c3d45), [`47a51ab`](https://github.com/Effect-TS/effect-smol/commit/47a51aba0ecdf3ef478bfa28a498bca188399bd4), [`1521d02`](https://github.com/Effect-TS/effect-smol/commit/1521d02e1f19f1d795edaaf862c1a1031d9c755e)]:
|
||||
- effect@4.0.0-beta.32
|
||||
|
||||
## 4.0.0-beta.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6f23f0e`](https://github.com/Effect-TS/effect-smol/commit/6f23f0ed4cba573cd9395c2e582f582fe7271544), [`654aaec`](https://github.com/Effect-TS/effect-smol/commit/654aaec593305521b65dd042c204d761cc6e8c28), [`2958a42`](https://github.com/Effect-TS/effect-smol/commit/2958a42078966a8713a98f00485ab36484d5eccf), [`95d27a2`](https://github.com/Effect-TS/effect-smol/commit/95d27a239ed5147302605ab0b3147a056541b0c7), [`0fbaea8`](https://github.com/Effect-TS/effect-smol/commit/0fbaea8f9555a8044cec31a770394db613fc78e2), [`21d5d5e`](https://github.com/Effect-TS/effect-smol/commit/21d5d5e0439fd4d9bb6e508377215b1087555d45), [`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6e49959`](https://github.com/Effect-TS/effect-smol/commit/6e499590357a104c81779b3176cd3f84e4f91064), [`8f5805d`](https://github.com/Effect-TS/effect-smol/commit/8f5805dbdd0d1bc0ff0727cc398c8d80e544edee), [`990df2c`](https://github.com/Effect-TS/effect-smol/commit/990df2c3ceeb32e659acc10cc9485617f7b3c423)]:
|
||||
- effect@4.0.0-beta.31
|
||||
|
||||
## 4.0.0-beta.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c88e5b7`](https://github.com/Effect-TS/effect-smol/commit/c88e5b723ff09da4edaef6ce14d927ca01104a32), [`947d0e4`](https://github.com/Effect-TS/effect-smol/commit/947d0e4268ba5c4020ead380aa80812c7342408f), [`7517908`](https://github.com/Effect-TS/effect-smol/commit/75179085d159b88a1ab0bce70669d76dcf0d79a4), [`a49ecd5`](https://github.com/Effect-TS/effect-smol/commit/a49ecd5a183d7e7d33f47ff95e9d2dea5a12ead5), [`6993e33`](https://github.com/Effect-TS/effect-smol/commit/6993e3329122c834c20bacea72d8678232f4f103), [`514f2a2`](https://github.com/Effect-TS/effect-smol/commit/514f2a2ae54580fcacdbe2ea2196a83a852d0748), [`3214b47`](https://github.com/Effect-TS/effect-smol/commit/3214b47676de2d33fddc5fecfc2d226e6e83cc7b), [`95ec5ed`](https://github.com/Effect-TS/effect-smol/commit/95ec5ed345de77c893049e182d37a37cf164a268)]:
|
||||
- effect@4.0.0-beta.30
|
||||
|
||||
## 4.0.0-beta.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9d93adb`](https://github.com/Effect-TS/effect-smol/commit/9d93adb1c1795d1978391b30d7d2972c88052662), [`b52721c`](https://github.com/Effect-TS/effect-smol/commit/b52721cf0d11a567722b060c8536e3bdd4161f07), [`a891c7b`](https://github.com/Effect-TS/effect-smol/commit/a891c7b12f415b2287613dd4b91a09dfd38ef30d), [`ef26cdf`](https://github.com/Effect-TS/effect-smol/commit/ef26cdfb65d9955fc7e161629191930c2cc2c63f), [`82fd3ed`](https://github.com/Effect-TS/effect-smol/commit/82fd3ed922063ee5a34f96f3993c15c7515e4f67)]:
|
||||
- effect@4.0.0-beta.29
|
||||
|
||||
## 4.0.0-beta.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ff533f2`](https://github.com/Effect-TS/effect-smol/commit/ff533f203cd06302ad08032a27e01269b4a2d4c6), [`dc803ee`](https://github.com/Effect-TS/effect-smol/commit/dc803ee52ebd3e9f931118f0dfcb804542847556), [`d660b1c`](https://github.com/Effect-TS/effect-smol/commit/d660b1c99cb93d4f79715e91c7a4486801c0eefa), [`93a05e3`](https://github.com/Effect-TS/effect-smol/commit/93a05e3eaa624058b162aedd66aad70102837270), [`2a65cf6`](https://github.com/Effect-TS/effect-smol/commit/2a65cf6fd81ef63d944e6fb51f058d439bf4a834), [`a561a40`](https://github.com/Effect-TS/effect-smol/commit/a561a40cc41c548c2cf3153aca065ee92ee8aa57), [`29cd24d`](https://github.com/Effect-TS/effect-smol/commit/29cd24d1fe78480a72eeb38a90281ffddc0530bc), [`662a8e6`](https://github.com/Effect-TS/effect-smol/commit/662a8e6857dac64a7cd13bd8df4b0674654622f8), [`d2b52ba`](https://github.com/Effect-TS/effect-smol/commit/d2b52bae5b9336cf59729fbdcc4d7f09512b0cbf), [`407c3b4`](https://github.com/Effect-TS/effect-smol/commit/407c3b43a5d1414558e0e33b6f1fc0e6a6d489cc), [`42bc7ce`](https://github.com/Effect-TS/effect-smol/commit/42bc7ce5480f6f2953c39f8cb5c850d61df6f5a2), [`e741322`](https://github.com/Effect-TS/effect-smol/commit/e74132226cbfee24234311c7c1c13e6b7391384e), [`5c75fa8`](https://github.com/Effect-TS/effect-smol/commit/5c75fa8fb71163bc4c035ba1a215574dfd4badfc), [`747177b`](https://github.com/Effect-TS/effect-smol/commit/747177b0602f12d4461a843e953dfdffbeb0a429), [`326cd48`](https://github.com/Effect-TS/effect-smol/commit/326cd4828bce573fe985f35152155464bf4c5a70), [`627e922`](https://github.com/Effect-TS/effect-smol/commit/627e922b8d1e9521eae5e1caa5d667ad00b1619a), [`662287e`](https://github.com/Effect-TS/effect-smol/commit/662287e9abc76c941ccc2ee330aa07904d571341)]:
|
||||
- effect@4.0.0-beta.28
|
||||
|
||||
## 4.0.0-beta.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`903a839`](https://github.com/Effect-TS/effect-smol/commit/903a839e94239e6ec4568315af28e405bcad95f4), [`91a0168`](https://github.com/Effect-TS/effect-smol/commit/91a016836680a6669308ecf464d3584bcc4ae1b7), [`c890f9a`](https://github.com/Effect-TS/effect-smol/commit/c890f9a1b3a989ed22528bd5a43326342e05b142), [`1e985f2`](https://github.com/Effect-TS/effect-smol/commit/1e985f237d250b51b91de22dde77160c1e778ce7)]:
|
||||
- effect@4.0.0-beta.27
|
||||
|
||||
## 4.0.0-beta.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fb21462`](https://github.com/Effect-TS/effect-smol/commit/fb21462642cdd5b1bada92f3eba18ae20445be42), [`2ed26b1`](https://github.com/Effect-TS/effect-smol/commit/2ed26b139805700e3df39efaa768ff01565e5c86), [`e832a57`](https://github.com/Effect-TS/effect-smol/commit/e832a57b570fe38f010c1fd99bceac5a325a9e07), [`7f01be7`](https://github.com/Effect-TS/effect-smol/commit/7f01be7f8db363d4b2e88e6b5571e96bb815786f), [`e965143`](https://github.com/Effect-TS/effect-smol/commit/e9651431e114479e6becf8ca7b1ed99ac7e91ccc), [`b9b80f1`](https://github.com/Effect-TS/effect-smol/commit/b9b80f1f15e152ceef0a727d150b7dc230abae99), [`98252aa`](https://github.com/Effect-TS/effect-smol/commit/98252aa0c0b17fc73fbdad65d0a1104965f9fc0f), [`56fbd94`](https://github.com/Effect-TS/effect-smol/commit/56fbd94311ad19a05001ad649d9e34ab00c74541), [`3faa109`](https://github.com/Effect-TS/effect-smol/commit/3faa109b7d093fbf14ad410d3e11d663f16e28f1), [`692ecfe`](https://github.com/Effect-TS/effect-smol/commit/692ecfed99fe58056b7a5afe001f4fcd1a61c446), [`1e70b72`](https://github.com/Effect-TS/effect-smol/commit/1e70b72d0b210474d0e96a15a5cfc279eae37e0c), [`ecf0782`](https://github.com/Effect-TS/effect-smol/commit/ecf07829ef2dfc01d8943c96c4fe9c1b44b97926)]:
|
||||
- effect@4.0.0-beta.26
|
||||
|
||||
## 4.0.0-beta.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fa17bb5`](https://github.com/Effect-TS/effect-smol/commit/fa17bb5be9f2533d01e11322b14804c7dec43714), [`f46e5b5`](https://github.com/Effect-TS/effect-smol/commit/f46e5b5ca2a918ee4d9270167e79db223077c96f), [`ce4767c`](https://github.com/Effect-TS/effect-smol/commit/ce4767cadcacc6ce8ff4c3a0d0fbc82ede655f63), [`c830a8b`](https://github.com/Effect-TS/effect-smol/commit/c830a8b6c292a6528d7f9318759d34800b00372d)]:
|
||||
- effect@4.0.0-beta.25
|
||||
|
||||
## 4.0.0-beta.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a909e1c`](https://github.com/Effect-TS/effect-smol/commit/a909e1c1ac2bc707527f5073776e3e7d239688d9), [`8814a4e`](https://github.com/Effect-TS/effect-smol/commit/8814a4ef78d67144d27689370af10099ea210399), [`3f942c5`](https://github.com/Effect-TS/effect-smol/commit/3f942c51cefa7b2ffa7c49e8c8a2c887570ba4c0), [`774ed59`](https://github.com/Effect-TS/effect-smol/commit/774ed59c52b2ab578bbb897c4f551f812231e1d2), [`f54b8d3`](https://github.com/Effect-TS/effect-smol/commit/f54b8d398fedad1815fd1f4c49814ab938cfc385)]:
|
||||
- effect@4.0.0-beta.24
|
||||
|
||||
## 4.0.0-beta.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c73c41`](https://github.com/Effect-TS/effect-smol/commit/5c73c41b69eaeab80fcd62c9bfda490b446d1966)]:
|
||||
- effect@4.0.0-beta.23
|
||||
|
||||
## 4.0.0-beta.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0874332`](https://github.com/Effect-TS/effect-smol/commit/0874332f7c81118b06ac2eb105e0710211631479), [`c592dcd`](https://github.com/Effect-TS/effect-smol/commit/c592dcde0697e322065c8f418c0480ef910cb183), [`1dbe28d`](https://github.com/Effect-TS/effect-smol/commit/1dbe28dac8299cd3e218c9768450cfd173b5e294), [`564d730`](https://github.com/Effect-TS/effect-smol/commit/564d730b6bbf38dd8548a3b046e7a693b28699a4), [`3cfadc4`](https://github.com/Effect-TS/effect-smol/commit/3cfadc458b070c6cba6c5674b72a059f1e49118b), [`6634fd0`](https://github.com/Effect-TS/effect-smol/commit/6634fd07da067d80b8261fb2959d1a952b9e412e), [`d10dabe`](https://github.com/Effect-TS/effect-smol/commit/d10dabeb7af9a368f995829cd36ad08167cd8f95), [`f82f549`](https://github.com/Effect-TS/effect-smol/commit/f82f549a09e950e9d4987f279a800f4d953f0939), [`78a3382`](https://github.com/Effect-TS/effect-smol/commit/78a3382ddfbe034408f7480fa794733d9e82147b)]:
|
||||
- effect@4.0.0-beta.22
|
||||
|
||||
## 4.0.0-beta.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e691909`](https://github.com/Effect-TS/effect-smol/commit/e691909495ccb162ea7bfa351dd74632b99997cb), [`d5f413f`](https://github.com/Effect-TS/effect-smol/commit/d5f413f3c8fc57f2413cc5649c2003d6d4e5a6d7), [`139d152`](https://github.com/Effect-TS/effect-smol/commit/139d152941e562a073b5be12e8d66c8a4d4a8a57), [`947e3d4`](https://github.com/Effect-TS/effect-smol/commit/947e3d436ab8a017efda9b29be523efd1ca8df28), [`84b2cce`](https://github.com/Effect-TS/effect-smol/commit/84b2ccefe2aa3a7413b86738a4dc33cdb311ca55), [`7f5305e`](https://github.com/Effect-TS/effect-smol/commit/7f5305e69f5a33309e77b08a576edb25d7daaee2), [`9e6fd84`](https://github.com/Effect-TS/effect-smol/commit/9e6fd8471c93a3c643929151a3bdb62cb9c0ca0e), [`fdb8a4b`](https://github.com/Effect-TS/effect-smol/commit/fdb8a4b172721fbefe98bd5aa6fe4f0efd1da3eb), [`0f986ef`](https://github.com/Effect-TS/effect-smol/commit/0f986ef22f196fe091a7afdbd179485a7d888882), [`9355fc0`](https://github.com/Effect-TS/effect-smol/commit/9355fc0ffb5b7382146a5aed9eea83974b10d007)]:
|
||||
- effect@4.0.0-beta.21
|
||||
|
||||
## 4.0.0-beta.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1529](https://github.com/Effect-TS/effect-smol/pull/1529) [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8) Thanks @tim-smart! - Add dedicated AiError metadata interfaces per reason so provider packages can safely augment metadata without conflicting module declarations.
|
||||
|
||||
- [#1528](https://github.com/Effect-TS/effect-smol/pull/1528) [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34) Thanks @tim-smart! - Add `Model.ModelName` and provide it from AI model constructors.
|
||||
|
||||
- Updated dependencies [[`842a624`](https://github.com/Effect-TS/effect-smol/commit/842a624f79d5e1407460b0ef3ab27d14d48ccf74), [`4785eef`](https://github.com/Effect-TS/effect-smol/commit/4785eef5d7cf1edb96ef2509aed2ba4d1edf3862), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`12ee8e2`](https://github.com/Effect-TS/effect-smol/commit/12ee8e27df7eb393d83a5e403390d0cfc82ca732), [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34), [`989d1cc`](https://github.com/Effect-TS/effect-smol/commit/989d1cca936fce0cc459057825ba40e3f5ef3827)]:
|
||||
- effect@4.0.0-beta.20
|
||||
|
||||
## 4.0.0-beta.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.19
|
||||
|
||||
## 4.0.0-beta.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`01e31fd`](https://github.com/Effect-TS/effect-smol/commit/01e31fdf8e5206849d23cbafd23a346f2f177ab8), [`0890aab`](https://github.com/Effect-TS/effect-smol/commit/0890aab15ed9c5ba52c383a72fdc6a444d7504d5), [`725260b`](https://github.com/Effect-TS/effect-smol/commit/725260b53f5142d6af7a93a2f9f464f974eda92d)]:
|
||||
- effect@4.0.0-beta.18
|
||||
|
||||
## 4.0.0-beta.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8f59c32`](https://github.com/Effect-TS/effect-smol/commit/8f59c32922597a48392744f7203e284866747781)]:
|
||||
- effect@4.0.0-beta.17
|
||||
|
||||
## 4.0.0-beta.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf9096c`](https://github.com/Effect-TS/effect-smol/commit/bf9096c52a7d8791d93d232739e523eb84f6625a), [`29f81ca`](https://github.com/Effect-TS/effect-smol/commit/29f81ca07c67dba265804b140a7487fb15a5fc6b), [`68eb28c`](https://github.com/Effect-TS/effect-smol/commit/68eb28c2b0fc67a9f6204ade9bd16c5b37803bfb)]:
|
||||
- effect@4.0.0-beta.16
|
||||
|
||||
## 4.0.0-beta.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1502](https://github.com/Effect-TS/effect-smol/pull/1502) [`285b7e6`](https://github.com/Effect-TS/effect-smol/commit/285b7e667167566d5788367d5155b19c79f1bf22) Thanks @tim-smart! - allow undefined for ai config
|
||||
|
||||
- Updated dependencies [[`24ae609`](https://github.com/Effect-TS/effect-smol/commit/24ae60995d2fd7d621be356cdfdfd328c79639ba), [`0e3c059`](https://github.com/Effect-TS/effect-smol/commit/0e3c059987caa55ebd0c134f7c7b147c639c328e), [`e843b0a`](https://github.com/Effect-TS/effect-smol/commit/e843b0a7d7e7b600a0b3bd477f24e2e4cd26bc8b), [`f4389a2`](https://github.com/Effect-TS/effect-smol/commit/f4389a2cca3c5bbf00d69779f52ce41255f15a28), [`5b73de0`](https://github.com/Effect-TS/effect-smol/commit/5b73de095b3402d0c5c74092ace6ce18ebfad566), [`595d2d6`](https://github.com/Effect-TS/effect-smol/commit/595d2d6e7d50419f3532bd39266191532ace38f2)]:
|
||||
- effect@4.0.0-beta.15
|
||||
|
||||
## 4.0.0-beta.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c414700`](https://github.com/Effect-TS/effect-smol/commit/c414700ef1932e4b67d0102856de417336912350), [`a30c969`](https://github.com/Effect-TS/effect-smol/commit/a30c9699c0d736cf3952041e45d508b7d58907a9)]:
|
||||
- effect@4.0.0-beta.14
|
||||
|
||||
## 4.0.0-beta.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`368f4c3`](https://github.com/Effect-TS/effect-smol/commit/368f4c363dd117e6f5a19ad77b161176cfd29fdd), [`db8a579`](https://github.com/Effect-TS/effect-smol/commit/db8a579e93e93ff73b1e60712732e03b597b916b), [`668b703`](https://github.com/Effect-TS/effect-smol/commit/668b70337e9ddbb0d1ae2282a95c282ce404e562), [`d40e76b`](https://github.com/Effect-TS/effect-smol/commit/d40e76b973543979e60e04a6baca04a8c65bdfc2), [`6e18cf8`](https://github.com/Effect-TS/effect-smol/commit/6e18cf883e9905ca718a6697b6a2a4bbd42739aa), [`86062e8`](https://github.com/Effect-TS/effect-smol/commit/86062e8a0c61bca5412fc40d2cf151d676901f08), [`c27ce75`](https://github.com/Effect-TS/effect-smol/commit/c27ce75d34c74dcfc6dba1bf77f1ce88f410a0de), [`e2d4fbf`](https://github.com/Effect-TS/effect-smol/commit/e2d4fbfeeda6a5d2a4c5aeb0501d8240c248b9eb), [`114ab42`](https://github.com/Effect-TS/effect-smol/commit/114ab42ad0edc590d29169675a493e0e915aa58f), [`484caec`](https://github.com/Effect-TS/effect-smol/commit/484caec47cccac8b86db2910742e406dfc7173ab)]:
|
||||
- effect@4.0.0-beta.13
|
||||
|
||||
## 4.0.0-beta.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70a74e8`](https://github.com/Effect-TS/effect-smol/commit/70a74e88a8767c9d4acdb9e5f25aec9a33588d07), [`b5b6e10`](https://github.com/Effect-TS/effect-smol/commit/b5b6e10621d54bf8c9857fec0d647ced78ecd857), [`f5ce5a9`](https://github.com/Effect-TS/effect-smol/commit/f5ce5a915359c6ebf254079e1da23cab6cde34fb), [`a29eb70`](https://github.com/Effect-TS/effect-smol/commit/a29eb702ffe3fc58bd28c4d7857298cd65d73668), [`c7b36e5`](https://github.com/Effect-TS/effect-smol/commit/c7b36e541a23e9a00f64e25b23851e51a37dfce5), [`9381d6d`](https://github.com/Effect-TS/effect-smol/commit/9381d6d4d9d819a81a46e56d0364c76e92a4fbca), [`88439f1`](https://github.com/Effect-TS/effect-smol/commit/88439f13ca13549f3e4822c48c4f019c14fc2bcc), [`e35307d`](https://github.com/Effect-TS/effect-smol/commit/e35307dbeb8eb26a9923f958b894a8eaaf259bf2), [`c7df4bc`](https://github.com/Effect-TS/effect-smol/commit/c7df4bce34009474c63d62a807abfdafb76971eb), [`accaf3b`](https://github.com/Effect-TS/effect-smol/commit/accaf3be7ac8da36e2334c509c23b8c9e88ea160), [`3e1c270`](https://github.com/Effect-TS/effect-smol/commit/3e1c2707bbdf67720af1509642b8ced195790882), [`6cd81f7`](https://github.com/Effect-TS/effect-smol/commit/6cd81f73baad86f5bbfa455a55d75cde71e9611a), [`f222da3`](https://github.com/Effect-TS/effect-smol/commit/f222da3cdb44554f3324c2c52d0d005ee575053e), [`61f901d`](https://github.com/Effect-TS/effect-smol/commit/61f901d830005b66e22d1de889fda132aeea97cd)]:
|
||||
- effect@4.0.0-beta.12
|
||||
|
||||
## 4.0.0-beta.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`88659ed`](https://github.com/Effect-TS/effect-smol/commit/88659edb26e3623d557dccfe914c2c949672da16), [`f2915e8`](https://github.com/Effect-TS/effect-smol/commit/f2915e8e2efe80d50c281e53f297b9701d6dc199), [`eb71ace`](https://github.com/Effect-TS/effect-smol/commit/eb71acebbe0f228e4920278013beee3b67d62310), [`2a16999`](https://github.com/Effect-TS/effect-smol/commit/2a169996c7513d377ac47adbfd68e1490457135c), [`d42dd52`](https://github.com/Effect-TS/effect-smol/commit/d42dd52f11203f8e749fb5d3ecf7153e4a5a6814), [`339adaf`](https://github.com/Effect-TS/effect-smol/commit/339adaf850a62a892adebcb208c2d9dddf3b97b3), [`de19645`](https://github.com/Effect-TS/effect-smol/commit/de1964526d01102dd1cb99c8cfdd3e8df1f49ef1), [`9b1dc3b`](https://github.com/Effect-TS/effect-smol/commit/9b1dc3bcf2a1b68d0a67e3465db5ad01a1a56997), [`e4cb2f5`](https://github.com/Effect-TS/effect-smol/commit/e4cb2f55b30f4771ec1bf613ced36d6d96464dd5), [`8bced95`](https://github.com/Effect-TS/effect-smol/commit/8bced954ecb35d4489197a57b0efe927e7d75f49), [`9431420`](https://github.com/Effect-TS/effect-smol/commit/94314207c8019918200fbcb97aec992219f801f0), [`948dca2`](https://github.com/Effect-TS/effect-smol/commit/948dca22e4f672ba7a6db57f9899272bec7c08b8), [`d18e327`](https://github.com/Effect-TS/effect-smol/commit/d18e32765a2665e31ffb31e746bf983fcfac34c5), [`ab512f7`](https://github.com/Effect-TS/effect-smol/commit/ab512f7be1c0e6b359da921e22cd4944e4c57d3e)]:
|
||||
- effect@4.0.0-beta.11
|
||||
|
||||
## 4.0.0-beta.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`371acab`](https://github.com/Effect-TS/effect-smol/commit/371acabb58d56f3a7a5e3e33d3d5fdc9f5573c74), [`856d774`](https://github.com/Effect-TS/effect-smol/commit/856d7741f1e296dd5048c6ff2b44b95d023e6ae4), [`b9e9202`](https://github.com/Effect-TS/effect-smol/commit/b9e92023c38caa322975d77cfe83e2d34ac9305a), [`1d1a974`](https://github.com/Effect-TS/effect-smol/commit/1d1a974bd280c81bff5d4505491cda03ba7a3f36), [`6bfe2a6`](https://github.com/Effect-TS/effect-smol/commit/6bfe2a659bc6335db75709931f405da45301cba2), [`b12c811`](https://github.com/Effect-TS/effect-smol/commit/b12c81157be287b1649c210616a244b50ec094d2), [`d17d98a`](https://github.com/Effect-TS/effect-smol/commit/d17d98ad78e2b44d95ef434adab79ac3c35e75ab), [`68c3c7c`](https://github.com/Effect-TS/effect-smol/commit/68c3c7cb1e06ed94fa5c4c123a234b4ccbfdecd8)]:
|
||||
- effect@4.0.0-beta.10
|
||||
|
||||
## 4.0.0-beta.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3386557`](https://github.com/Effect-TS/effect-smol/commit/338655731564a7be9f8859dedbf4d5bcac6eb350), [`b6666e3`](https://github.com/Effect-TS/effect-smol/commit/b6666e3cf6bd44ba1a8704e65c256c30359cb422)]:
|
||||
- effect@4.0.0-beta.9
|
||||
|
||||
## 4.0.0-beta.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1354](https://github.com/Effect-TS/effect-smol/pull/1354) [`b94962c`](https://github.com/Effect-TS/effect-smol/commit/b94962c249d46cf96cdf2e41188dc9feda41536a) Thanks @IMax153! - Fix the generated schemas for ai providers
|
||||
|
||||
- Updated dependencies [[`246e672`](https://github.com/Effect-TS/effect-smol/commit/246e672dbbd7848d60e0c78fd66671b2f10b3752), [`807dec0`](https://github.com/Effect-TS/effect-smol/commit/807dec03801b4c58a6d00c237b6d98d6386911df)]:
|
||||
- effect@4.0.0-beta.8
|
||||
|
||||
## 4.0.0-beta.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a2bda6d`](https://github.com/Effect-TS/effect-smol/commit/a2bda6d4ef6de9d9b0c53ae2df5434f778d6161a), [`1f95a2b`](https://github.com/Effect-TS/effect-smol/commit/1f95a2b5aa9524bb38f4437f4691a664bf463ca1), [`a8d5e79`](https://github.com/Effect-TS/effect-smol/commit/a8d5e792fec201a83af0eb92fc79928d055125fd), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`06d8a03`](https://github.com/Effect-TS/effect-smol/commit/06d8a0391631e6130e3ab25227e59817852e227f), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`f9e883e`](https://github.com/Effect-TS/effect-smol/commit/f9e883e266fbda870336ee62f46b7ac85ba3de6e), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430)]:
|
||||
- effect@4.0.0-beta.7
|
||||
|
||||
## 4.0.0-beta.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3247da2`](https://github.com/Effect-TS/effect-smol/commit/3247da28331f345f68be5dbd2974a7e03d300fe1), [`f205705`](https://github.com/Effect-TS/effect-smol/commit/f2057050dbd034b8c186be2d40c3d03ee63a5a3b), [`f35022c`](https://github.com/Effect-TS/effect-smol/commit/f35022c212e4111527e1bb43f360a67b2b49fa85), [`8622721`](https://github.com/Effect-TS/effect-smol/commit/86227217b02d43680a3c6f3c21731b1d852c91f5), [`fc660ab`](https://github.com/Effect-TS/effect-smol/commit/fc660ab8b5ebae38b8d6b96cbf2f9b880cc09253), [`f37dc33`](https://github.com/Effect-TS/effect-smol/commit/f37dc335f64622fa9ce8d6d1d5dd8fc3f260257b), [`3662f32`](https://github.com/Effect-TS/effect-smol/commit/3662f328fcfa3b2fa01ffa79da40e12e93fcede8), [`a7d436f`](https://github.com/Effect-TS/effect-smol/commit/a7d436f438dcd7f49b9485e4e95a4511f31fad7d), [`6856a41`](https://github.com/Effect-TS/effect-smol/commit/6856a415d7eddd9d73d60919e976f1d071421be4), [`8c417d0`](https://github.com/Effect-TS/effect-smol/commit/8c417d03475e5e12d00dca0c4781d0af7e66b86c), [`5419570`](https://github.com/Effect-TS/effect-smol/commit/5419570ba47ce882a3a10882707b46f66e464906), [`449c5ed`](https://github.com/Effect-TS/effect-smol/commit/449c5ed5318e8a874e730420bcf52918fa2ec80f), [`4b5ec12`](https://github.com/Effect-TS/effect-smol/commit/4b5ec12f87f95f2a3cd8fe4d5b26c6eb0529381a), [`df87937`](https://github.com/Effect-TS/effect-smol/commit/df879375fc3b169c43f9c434b3775e12b80dffe4), [`5dbfca8`](https://github.com/Effect-TS/effect-smol/commit/5dbfca8d1dbb6d18d1605d4f8562e99c86e2ff11), [`e629497`](https://github.com/Effect-TS/effect-smol/commit/e6294973d55597ab6b6deca6babbe1e946b2c91d), [`981c991`](https://github.com/Effect-TS/effect-smol/commit/981c991cd78db34def815d5754379d737157f005), [`1ca2ed6`](https://github.com/Effect-TS/effect-smol/commit/1ca2ed67301a5dc40ae0ed94346b99f26fd22bbe), [`45722bd`](https://github.com/Effect-TS/effect-smol/commit/45722bde974458311f11ad237711363a10ec6894), [`eb2a85e`](https://github.com/Effect-TS/effect-smol/commit/eb2a85ed4dc162b2535d304799333a5a20477fd0)]:
|
||||
- effect@4.0.0-beta.6
|
||||
|
||||
## 4.0.0-beta.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f6e133e`](https://github.com/Effect-TS/effect-smol/commit/f6e133e9a16b32317bd09ff08c12b97a0ae44600), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8), [`a88e206`](https://github.com/Effect-TS/effect-smol/commit/a88e206e44dc66ca5a2b45bedc797877c5dbb083), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8)]:
|
||||
- effect@4.0.0-beta.5
|
||||
|
||||
## 4.0.0-beta.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c5a18ef`](https://github.com/Effect-TS/effect-smol/commit/c5a18ef44171e3880bf983faee74529908974b32), [`bc6b885`](https://github.com/Effect-TS/effect-smol/commit/bc6b885b94d887a200657c0775dfa874dc15bc0c)]:
|
||||
- effect@4.0.0-beta.4
|
||||
|
||||
## 4.0.0-beta.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1306](https://github.com/Effect-TS/effect-smol/pull/1306) [`c9fb5a5`](https://github.com/Effect-TS/effect-smol/commit/c9fb5a5bfb1c331c91d592323f4027b72a3bc0b4) Thanks @Leka74! - Fix sparse array crash in `streamText` tool call handling.
|
||||
|
||||
- Updated dependencies [[`3a0cf36`](https://github.com/Effect-TS/effect-smol/commit/3a0cf36eff106ba48d74e133c1598cd40613e530), [`c4da328`](https://github.com/Effect-TS/effect-smol/commit/c4da328d32fad1d61e0e538f5d371edf61521d7e)]:
|
||||
- effect@4.0.0-beta.3
|
||||
|
||||
## 4.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a22ce73`](https://github.com/Effect-TS/effect-smol/commit/a22ce73b2bd9305b7ba665694d2255c0e6d5a8d0), [`ebdabf7`](https://github.com/Effect-TS/effect-smol/commit/ebdabf79ff4e62c8384aa8cf9a8d2787d536ee78), [`8f663bb`](https://github.com/Effect-TS/effect-smol/commit/8f663bb121021bf12bd264e8ae385187cb7a5dae)]:
|
||||
- effect@4.0.0-beta.2
|
||||
|
||||
## 4.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0fecf70`](https://github.com/Effect-TS/effect-smol/commit/0fecf70048057623eed7c584a06671773a2b1743), [`709569e`](https://github.com/Effect-TS/effect-smol/commit/709569ed76bead9ebb0670599e4d890a07ca5a43)]:
|
||||
- effect@4.0.0-beta.1
|
||||
|
||||
## 4.0.0-beta.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#1183](https://github.com/Effect-TS/effect-smol/pull/1183) [`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66) Thanks @tim-smart! - v4 beta
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66)]:
|
||||
- effect@4.0.0-beta.0
|
||||
35
repos/effect/packages/ai/openrouter/codegen.yml
Normal file
35
repos/effect/packages/ai/openrouter/codegen.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
# yaml-language-server: $schema=../../tools/ai-codegen/codegen.schema.json
|
||||
spec: https://openrouter.ai/openapi.yaml
|
||||
output: src/Generated.ts
|
||||
name: OpenRouterClient
|
||||
header: |
|
||||
/**
|
||||
* @since 1.0.0
|
||||
*/
|
||||
excludeAnnotations:
|
||||
- default
|
||||
disableAdditionalProperties: true
|
||||
patches:
|
||||
# Replace OpenResponsesStreamEvent with a flat oneOf of $refs.
|
||||
# The original uses allOf wrappers that inline OpenResponsesNonStreamingResponse
|
||||
# into each variant, producing lines over 1M chars that crash dprint.
|
||||
- '[{"op":"replace","path":"/components/schemas/OpenResponsesStreamEvent","value":{"oneOf":[{"$ref":"#/components/schemas/OpenResponsesCreatedEvent"},{"$ref":"#/components/schemas/OpenResponsesInProgressEvent"},{"$ref":"#/components/schemas/OpenResponsesCompletedEvent"},{"$ref":"#/components/schemas/OpenResponsesIncompleteEvent"},{"$ref":"#/components/schemas/OpenResponsesFailedEvent"},{"$ref":"#/components/schemas/OpenResponsesErrorEvent"},{"$ref":"#/components/schemas/OpenResponsesOutputItemAddedEvent"},{"$ref":"#/components/schemas/OpenResponsesOutputItemDoneEvent"},{"$ref":"#/components/schemas/OpenResponsesContentPartAddedEvent"},{"$ref":"#/components/schemas/OpenResponsesContentPartDoneEvent"},{"$ref":"#/components/schemas/OpenResponsesTextDeltaEvent"},{"$ref":"#/components/schemas/OpenResponsesTextDoneEvent"},{"$ref":"#/components/schemas/OpenResponsesRefusalDeltaEvent"},{"$ref":"#/components/schemas/OpenResponsesRefusalDoneEvent"},{"$ref":"#/components/schemas/OpenResponsesOutputTextAnnotationAddedEvent"},{"$ref":"#/components/schemas/OpenResponsesFunctionCallArgumentsDeltaEvent"},{"$ref":"#/components/schemas/OpenResponsesFunctionCallArgumentsDoneEvent"},{"$ref":"#/components/schemas/OpenResponsesReasoningDeltaEvent"},{"$ref":"#/components/schemas/OpenResponsesReasoningDoneEvent"},{"$ref":"#/components/schemas/OpenResponsesReasoningSummaryPartAddedEvent"},{"$ref":"#/components/schemas/OpenResponsesReasoningSummaryPartDoneEvent"},{"$ref":"#/components/schemas/OpenResponsesReasoningSummaryTextDeltaEvent"},{"$ref":"#/components/schemas/OpenResponsesReasoningSummaryTextDoneEvent"},{"$ref":"#/components/schemas/OpenResponsesImageGenCallInProgress"},{"$ref":"#/components/schemas/OpenResponsesImageGenCallGenerating"},{"$ref":"#/components/schemas/OpenResponsesImageGenCallPartialImage"},{"$ref":"#/components/schemas/OpenResponsesImageGenCallCompleted"}]}}]'
|
||||
# Fix AssistantMessage images to include type:"image_url" discriminator and nullable
|
||||
- '[{"op":"replace","path":"/components/schemas/AssistantMessage/properties/images","value":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","const":"image_url"},"image_url":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]}},"required":["type","image_url"]}},{"type":"null"}]}}]'
|
||||
# Add images to ChatStreamingMessageChunk (streaming delta)
|
||||
- '[{"op":"add","path":"/components/schemas/ChatStreamingMessageChunk/properties/images","value":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","const":"image_url"},"image_url":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]}},"required":["type","image_url"]}},{"type":"null"}]}}]'
|
||||
# Add annotations to AssistantMessage (non-streaming)
|
||||
- '[{"op":"add","path":"/components/schemas/AssistantMessage/properties/annotations","value":{"anyOf":[{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url_citation"},"url_citation":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"},"start_index":{"type":"number"},"end_index":{"type":"number"},"content":{"type":"string"}},"required":["url"]}},"required":["type","url_citation"]},{"type":"object","properties":{"type":{"type":"string","const":"file_annotation"},"file_annotation":{"type":"object","properties":{"file_id":{"type":"string"},"quote":{"type":"string"}},"required":["file_id"]}},"required":["type","file_annotation"]},{"type":"object","properties":{"type":{"type":"string","const":"file"},"file":{"type":"object","properties":{"hash":{"type":"string"},"name":{"type":"string"},"content":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"text":{"type":"string"}},"required":["type"]}}},"required":["hash","name"]}},"required":["type","file"]}]}},{"type":"null"}]}}]'
|
||||
# Add annotations to ChatStreamingMessageChunk (streaming delta)
|
||||
- '[{"op":"add","path":"/components/schemas/ChatStreamingMessageChunk/properties/annotations","value":{"anyOf":[{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url_citation"},"url_citation":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"},"start_index":{"type":"number"},"end_index":{"type":"number"},"content":{"type":"string"}},"required":["url"]}},"required":["type","url_citation"]},{"type":"object","properties":{"type":{"type":"string","const":"file_annotation"},"file_annotation":{"type":"object","properties":{"file_id":{"type":"string"},"quote":{"type":"string"}},"required":["file_id"]}},"required":["type","file_annotation"]},{"type":"object","properties":{"type":{"type":"string","const":"file"},"file":{"type":"object","properties":{"hash":{"type":"string"},"name":{"type":"string"},"content":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"text":{"type":"string"}},"required":["type"]}}},"required":["hash","name"]}},"required":["type","file"]}]}},{"type":"null"}]}}]'
|
||||
# Make tool call delta fields nullable (models like kimi-k2.5, minimax-m2.5 send null)
|
||||
- '[{"op":"replace","path":"/components/schemas/ChatStreamingMessageToolCall/properties/id","value":{"anyOf":[{"type":"string"},{"type":"null"}]}},{"op":"replace","path":"/components/schemas/ChatStreamingMessageToolCall/properties/type","value":{"anyOf":[{"type":"string","const":"function"},{"type":"null"}]}},{"op":"replace","path":"/components/schemas/ChatStreamingMessageToolCall/properties/function/properties/name","value":{"anyOf":[{"type":"string"},{"type":"null"}]}}]'
|
||||
# Make finish_reason optional (only present on final streaming chunk)
|
||||
- '[{"op":"remove","path":"/components/schemas/ChatStreamingChoice/required/1"}]'
|
||||
replacements:
|
||||
# Schema.Unknown doesn't work with Schema.toCodecJson (used by HttpClientResponse.schemaBodyJson)
|
||||
# Replace with Schema.Json which properly handles arbitrary JSON values
|
||||
- from: "Schema.Record(Schema.String, Schema.Unknown)"
|
||||
to: "Schema.Record(Schema.String, Schema.Json)"
|
||||
- from: "{ readonly [x: string]: unknown }"
|
||||
to: "{ readonly [x: string]: Schema.Json }"
|
||||
23
repos/effect/packages/ai/openrouter/docgen.json
Normal file
23
repos/effect/packages/ai/openrouter/docgen.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "../../node_modules/@effect/docgen/schema.json",
|
||||
"srcLink": "https://github.com/Effect-TS/effect/tree/main/packages/ai/openrouter/src/",
|
||||
"exclude": ["src/Generated.ts", "src/internal/**/*.ts"],
|
||||
"examplesCompilerOptions": {
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "Bundler",
|
||||
"module": "ES2022",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"rewriteRelativeImportExtensions": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"paths": {
|
||||
"effect": ["../../../effect/src/index.js"],
|
||||
"effect/*": ["../../../effect/src/*.js"]
|
||||
},
|
||||
"plugins": [
|
||||
{ "name": "@effect/language-service", "includeSuggestionsInTsc": false }
|
||||
]
|
||||
}
|
||||
}
|
||||
66
repos/effect/packages/ai/openrouter/package.json
Normal file
66
repos/effect/packages/ai/openrouter/package.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "@effect/ai-openrouter",
|
||||
"version": "4.0.0-beta.99",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "An OpenRouter provider integration for Effect AI SDK",
|
||||
"homepage": "https://effect.website",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Effect-TS/effect.git",
|
||||
"directory": "packages/ai/openrouter"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Effect-TS/effect/issues"
|
||||
},
|
||||
"tags": [
|
||||
"typescript",
|
||||
"ai",
|
||||
"openrouter"
|
||||
],
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"ai",
|
||||
"openrouter"
|
||||
],
|
||||
"sideEffects": [],
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts",
|
||||
"./*": "./src/*.ts",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
},
|
||||
"files": [
|
||||
"src/**/*.ts",
|
||||
"dist/**/*.js",
|
||||
"dist/**/*.js.map",
|
||||
"dist/**/*.d.ts",
|
||||
"dist/**/*.d.ts.map"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"provenance": true,
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./dist/index.js",
|
||||
"./*": "./dist/*.js",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"codegen": "effect-utils codegen",
|
||||
"build": "tsc -b tsconfig.json && pnpm babel",
|
||||
"babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
||||
"check": "tsc -b tsconfig.json",
|
||||
"test": "vitest",
|
||||
"coverage": "vitest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"effect": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "workspace:^"
|
||||
}
|
||||
}
|
||||
10028
repos/effect/packages/ai/openrouter/src/Generated.ts
Normal file
10028
repos/effect/packages/ai/openrouter/src/Generated.ts
Normal file
File diff suppressed because it is too large
Load Diff
357
repos/effect/packages/ai/openrouter/src/OpenRouterClient.ts
Normal file
357
repos/effect/packages/ai/openrouter/src/OpenRouterClient.ts
Normal file
@@ -0,0 +1,357 @@
|
||||
/**
|
||||
* The `OpenRouterClient` module provides an Effect service for calling
|
||||
* OpenRouter's chat completions API. It wraps the generated OpenRouter HTTP
|
||||
* client with Effect-native constructors, layers, authentication and optional
|
||||
* site ranking headers, typed errors, and streaming support.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import type * as Config from "effect/Config"
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { identity } from "effect/Function"
|
||||
import * as Layer from "effect/Layer"
|
||||
import * as Predicate from "effect/Predicate"
|
||||
import type * as Redacted from "effect/Redacted"
|
||||
import * as Schema from "effect/Schema"
|
||||
import * as Stream from "effect/Stream"
|
||||
import type * as AiError from "effect/unstable/ai/AiError"
|
||||
import * as Sse from "effect/unstable/encoding/Sse"
|
||||
import * as HttpBody from "effect/unstable/http/HttpBody"
|
||||
import * as HttpClient from "effect/unstable/http/HttpClient"
|
||||
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
||||
import type * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
|
||||
import * as Generated from "./Generated.ts"
|
||||
import * as Errors from "./internal/errors.ts"
|
||||
import { OpenRouterConfig } from "./OpenRouterConfig.ts"
|
||||
|
||||
// =============================================================================
|
||||
// Service Interface
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* The OpenRouter client service interface.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Provides methods for interacting with OpenRouter's Chat Completions API,
|
||||
* including both synchronous and streaming message creation.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface Service {
|
||||
readonly client: Generated.OpenRouterClient
|
||||
|
||||
readonly createChatCompletion: (
|
||||
options: typeof Generated.ChatGenerationParams.Encoded
|
||||
) => Effect.Effect<
|
||||
[body: typeof Generated.SendChatCompletionRequest200.Type, response: HttpClientResponse.HttpClientResponse],
|
||||
AiError.AiError
|
||||
>
|
||||
|
||||
readonly createChatCompletionStream: (
|
||||
options: Omit<typeof Generated.ChatGenerationParams.Encoded, "stream" | "stream_options">
|
||||
) => Effect.Effect<
|
||||
[
|
||||
response: HttpClientResponse.HttpClientResponse,
|
||||
stream: Stream.Stream<ChatStreamingResponseChunkData, AiError.AiError>
|
||||
],
|
||||
AiError.AiError
|
||||
>
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoded `data` payload from an OpenRouter chat completion streaming chunk.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The payload contains streamed choices, model metadata, optional usage, and may
|
||||
* include an OpenRouter error object for a streamed response.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type ChatStreamingResponseChunkData = typeof Generated.ChatStreamingResponseChunk.fields.data.Type
|
||||
|
||||
// =============================================================================
|
||||
// Service Identifier
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Service tag for the OpenRouter client.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when accessing or providing the OpenRouter client service through
|
||||
* Effect's context.
|
||||
*
|
||||
* @see {@link make} for constructing an OpenRouter client effectfully
|
||||
* @see {@link layer} for providing a client from explicit options
|
||||
* @see {@link layerConfig} for providing a client from `Config`
|
||||
*
|
||||
* @category services
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class OpenRouterClient extends Context.Service<
|
||||
OpenRouterClient,
|
||||
Service
|
||||
>()("@effect/ai-openrouter/OpenRouterClient") {}
|
||||
|
||||
// =============================================================================
|
||||
// Options
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Configuration for creating an OpenRouter client.
|
||||
*
|
||||
* @category options
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type Options = {
|
||||
readonly apiKey?: Redacted.Redacted<string> | undefined
|
||||
|
||||
readonly apiUrl?: string | undefined
|
||||
|
||||
/**
|
||||
* Optional URL of your site for rankings on `openrouter.ai`.
|
||||
*/
|
||||
readonly siteReferrer?: string | undefined
|
||||
|
||||
/**
|
||||
* Optional title of your site for rankings on `openrouter.ai`.
|
||||
*/
|
||||
readonly siteTitle?: string | undefined
|
||||
|
||||
/**
|
||||
* Optional transformer for the underlying HTTP client.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to add middleware, logging, or custom request/response handling.
|
||||
*/
|
||||
readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Constructor
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Creates an OpenRouter client service from explicit options.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need the OpenRouter client service value inside an effect.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The returned service uses the current `HttpClient`, prepends `apiUrl` or
|
||||
* `https://openrouter.ai/api/v1`, adds the bearer token and optional
|
||||
* `HTTP-Referer` and `X-Title` headers, accepts JSON responses, and applies
|
||||
* `transformClient` when provided.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* Scoped `OpenRouterConfig.withClientTransform` applies to generated client
|
||||
* request methods. Streaming chat completion requests are sent directly by this
|
||||
* module and do not read that scoped transform.
|
||||
*
|
||||
* @see {@link layer} for providing this client from explicit options
|
||||
* @see {@link layerConfig} for loading client settings from `Config`
|
||||
*
|
||||
* @category constructors
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const make = Effect.fnUntraced(
|
||||
function*(options: Options): Effect.fn.Return<Service, never, HttpClient.HttpClient> {
|
||||
const baseClient = yield* HttpClient.HttpClient
|
||||
|
||||
const httpClient = baseClient.pipe(
|
||||
HttpClient.mapRequest((request) =>
|
||||
request.pipe(
|
||||
HttpClientRequest.prependUrl(options.apiUrl ?? "https://openrouter.ai/api/v1"),
|
||||
options.apiKey ? HttpClientRequest.bearerToken(options.apiKey) : identity,
|
||||
options.siteReferrer ? HttpClientRequest.setHeader("HTTP-Referer", options.siteReferrer) : identity,
|
||||
options.siteTitle ? HttpClientRequest.setHeader("X-Title", options.siteTitle) : identity,
|
||||
HttpClientRequest.acceptJson
|
||||
)
|
||||
),
|
||||
options.transformClient ?? identity
|
||||
)
|
||||
|
||||
const httpClientOk = HttpClient.filterStatusOk(httpClient)
|
||||
|
||||
const client = Generated.make(httpClient, {
|
||||
transformClient: Effect.fnUntraced(function*(client) {
|
||||
const config = yield* OpenRouterConfig.getOrUndefined
|
||||
if (Predicate.isNotUndefined(config?.transformClient)) {
|
||||
return config.transformClient(client)
|
||||
}
|
||||
return client
|
||||
})
|
||||
})
|
||||
|
||||
const createChatCompletion: Service["createChatCompletion"] = (payload) =>
|
||||
client.sendChatCompletionRequest({ payload, config: { includeResponse: true } }).pipe(
|
||||
Effect.catchTags({
|
||||
SendChatCompletionRequest400: (error) => Effect.fail(Errors.mapClientError(error, "createChatCompletion")),
|
||||
SendChatCompletionRequest401: (error) => Effect.fail(Errors.mapClientError(error, "createChatCompletion")),
|
||||
SendChatCompletionRequest429: (error) => Effect.fail(Errors.mapClientError(error, "createChatCompletion")),
|
||||
SendChatCompletionRequest500: (error) => Effect.fail(Errors.mapClientError(error, "createChatCompletion")),
|
||||
HttpClientError: (error) => Errors.mapHttpClientError(error, "createChatCompletion"),
|
||||
SchemaError: (error) => Effect.fail(Errors.mapSchemaError(error, "createChatCompletion"))
|
||||
})
|
||||
)
|
||||
|
||||
const buildChatCompletionStream = (
|
||||
response: HttpClientResponse.HttpClientResponse
|
||||
): [
|
||||
HttpClientResponse.HttpClientResponse,
|
||||
Stream.Stream<ChatStreamingResponseChunkData, AiError.AiError>
|
||||
] => {
|
||||
const stream = response.stream.pipe(
|
||||
Stream.decodeText(),
|
||||
Stream.pipeThroughChannel(Sse.decode()),
|
||||
Stream.mapEffect((event) => decodeChatCompletionSseData(event.data)),
|
||||
Stream.takeWhile((data) => data !== "[DONE]"),
|
||||
Stream.catchTags({
|
||||
// TODO: handle SSE retries
|
||||
Retry: (error) => Stream.die(error),
|
||||
HttpClientError: (error) => Stream.fromEffect(Errors.mapHttpClientError(error, "createChatCompletionStream")),
|
||||
SchemaError: (error) => Stream.fail(Errors.mapSchemaError(error, "createChatCompletionStream"))
|
||||
})
|
||||
) as any
|
||||
return [response, stream]
|
||||
}
|
||||
|
||||
const createChatCompletionStream: Service["createChatCompletionStream"] = (payload) =>
|
||||
httpClientOk.execute(
|
||||
HttpClientRequest.post("/chat/completions", {
|
||||
body: HttpBody.jsonUnsafe({
|
||||
...payload,
|
||||
stream: true,
|
||||
stream_options: { include_usage: true }
|
||||
})
|
||||
})
|
||||
).pipe(
|
||||
Effect.map(buildChatCompletionStream),
|
||||
Effect.catchTag(
|
||||
"HttpClientError",
|
||||
(error) => Errors.mapHttpClientError(error, "createChatCompletionStream")
|
||||
)
|
||||
)
|
||||
|
||||
return OpenRouterClient.of({
|
||||
client,
|
||||
createChatCompletion,
|
||||
createChatCompletionStream
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// Layers
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Creates a layer for the OpenRouter client with the given options.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you already have the OpenRouter client options in code and want to
|
||||
* provide `OpenRouterClient` as a layer.
|
||||
*
|
||||
* @see {@link make} for constructing the client service effectfully
|
||||
* @see {@link layerConfig} for loading client settings from `Config`
|
||||
*
|
||||
* @category layers
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const layer = (options: Options): Layer.Layer<OpenRouterClient, never, HttpClient.HttpClient> =>
|
||||
Layer.effect(OpenRouterClient, make(options))
|
||||
|
||||
/**
|
||||
* Creates a layer for the OpenRouter client from provided `Config` values.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need client settings for OpenRouter to be read from Effect
|
||||
* `Config` values while providing `OpenRouterClient` as a layer.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Only config values supplied in `options` are loaded. Omitted fields are
|
||||
* passed to `make` as `undefined`, and `transformClient` is forwarded as a
|
||||
* plain option.
|
||||
*
|
||||
* @see {@link make} for constructing the client service effectfully
|
||||
* @see {@link layer} for providing the client from already-resolved options
|
||||
*
|
||||
* @category layers
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const layerConfig = (options?: {
|
||||
/**
|
||||
* The config value to load for the API key.
|
||||
*/
|
||||
readonly apiKey?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
|
||||
|
||||
/**
|
||||
* The config value to load for the API URL.
|
||||
*/
|
||||
readonly apiUrl?: Config.Config<string> | undefined
|
||||
|
||||
/**
|
||||
* The config value to load for the site referrer URL.
|
||||
*/
|
||||
readonly siteReferrer?: Config.Config<string> | undefined
|
||||
|
||||
/**
|
||||
* The config value to load for the site title.
|
||||
*/
|
||||
readonly siteTitle?: Config.Config<string> | undefined
|
||||
|
||||
/**
|
||||
* Optional transformer for the HTTP client.
|
||||
*/
|
||||
readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
|
||||
}): Layer.Layer<OpenRouterClient, Config.ConfigError, HttpClient.HttpClient> =>
|
||||
Layer.effect(
|
||||
OpenRouterClient,
|
||||
Effect.gen(function*() {
|
||||
const apiKey = Predicate.isNotUndefined(options?.apiKey)
|
||||
? yield* options.apiKey
|
||||
: undefined
|
||||
const apiUrl = Predicate.isNotUndefined(options?.apiUrl)
|
||||
? yield* options.apiUrl
|
||||
: undefined
|
||||
const siteReferrer = Predicate.isNotUndefined(options?.siteReferrer)
|
||||
? yield* options.siteReferrer
|
||||
: undefined
|
||||
const siteTitle = Predicate.isNotUndefined(options?.siteTitle)
|
||||
? yield* options.siteTitle
|
||||
: undefined
|
||||
return yield* make({
|
||||
apiKey,
|
||||
apiUrl,
|
||||
siteReferrer,
|
||||
siteTitle,
|
||||
transformClient: options?.transformClient
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// Internal Utilities
|
||||
// =============================================================================
|
||||
|
||||
const ChatStreamingResponseChunkDataFromString = Schema.fromJsonString(Generated.ChatStreamingResponseChunk.fields.data)
|
||||
const decodeChatStreamingResponseChunkData = Schema.decodeUnknownEffect(ChatStreamingResponseChunkDataFromString)
|
||||
|
||||
const decodeChatCompletionSseData = (
|
||||
data: string
|
||||
): Effect.Effect<ChatStreamingResponseChunkData | "[DONE]", Schema.SchemaError> =>
|
||||
data === "[DONE]"
|
||||
? Effect.succeed(data)
|
||||
: decodeChatStreamingResponseChunkData(data)
|
||||
99
repos/effect/packages/ai/openrouter/src/OpenRouterConfig.ts
Normal file
99
repos/effect/packages/ai/openrouter/src/OpenRouterConfig.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* The `OpenRouterConfig` module lets a workflow temporarily customize the HTTP
|
||||
* client used by generated OpenRouter request methods. `OpenRouterClient` reads
|
||||
* this scoped transform when generated client operations execute, so callers can
|
||||
* add middleware or instrumentation without rebuilding the client layer.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Context from "effect/Context"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import type { HttpClient } from "effect/unstable/http/HttpClient"
|
||||
|
||||
/**
|
||||
* Context service for scoped OpenRouter provider configuration used by client
|
||||
* operations.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use as the context service tag when manually providing or reading scoped
|
||||
* OpenRouter provider configuration in an Effect context.
|
||||
*
|
||||
* @see {@link withClientTransform} for scoping an HTTP client transformation
|
||||
*
|
||||
* @category services
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export class OpenRouterConfig extends Context.Service<
|
||||
OpenRouterConfig,
|
||||
OpenRouterConfig.Service
|
||||
>()("@effect/ai-openrouter/OpenRouterConfig") {
|
||||
/**
|
||||
* Gets the configured OpenRouter service from the current context when present.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
static readonly getOrUndefined: Effect.Effect<typeof OpenRouterConfig.Service | undefined> = Effect.map(
|
||||
Effect.context<never>(),
|
||||
(services) => services.mapUnsafe.get(OpenRouterConfig.key)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Types associated with the `OpenRouterConfig` context service.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export declare namespace OpenRouterConfig {
|
||||
/**
|
||||
* Configuration values read by OpenRouter provider operations when resolving
|
||||
* the generated HTTP client.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface Service {
|
||||
readonly transformClient?: ((client: HttpClient) => HttpClient) | undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a scoped transform for the OpenRouter HTTP client used by provider
|
||||
* operations.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need temporary OpenRouter HTTP client customization for a
|
||||
* single effect or workflow without rebuilding the client layer.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Supports both data-first and data-last forms. The transform is stored in the
|
||||
* scoped `OpenRouterConfig` service and read by generated OpenRouter request
|
||||
* operations while running the supplied effect.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* If a transform is already present in the scoped config, this helper replaces
|
||||
* it. Compose transforms manually when both should apply. Streaming chat
|
||||
* completion requests are sent directly by `OpenRouterClient.make` and do not
|
||||
* read this scoped transform.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const withClientTransform: {
|
||||
(transform: (client: HttpClient) => HttpClient): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
|
||||
<A, E, R>(self: Effect.Effect<A, E, R>, transform: (client: HttpClient) => HttpClient): Effect.Effect<A, E, R>
|
||||
} = dual<
|
||||
(transform: (client: HttpClient) => HttpClient) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
|
||||
<A, E, R>(self: Effect.Effect<A, E, R>, transform: (client: HttpClient) => HttpClient) => Effect.Effect<A, E, R>
|
||||
>(
|
||||
2,
|
||||
(self, transformClient) =>
|
||||
Effect.flatMap(
|
||||
OpenRouterConfig.getOrUndefined,
|
||||
(config) => Effect.provideService(self, OpenRouterConfig, { ...config, transformClient })
|
||||
)
|
||||
)
|
||||
225
repos/effect/packages/ai/openrouter/src/OpenRouterError.ts
Normal file
225
repos/effect/packages/ai/openrouter/src/OpenRouterError.ts
Normal file
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* OpenRouter error metadata augmentation.
|
||||
*
|
||||
* Provides OpenRouter-specific metadata fields for AI error types through
|
||||
* module augmentation, enabling typed access to OpenRouter error details.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* OpenRouter-specific error metadata fields.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenRouterErrorMetadata = {
|
||||
/**
|
||||
* The error code returned by the API.
|
||||
*/
|
||||
readonly errorCode: string | number | null
|
||||
/**
|
||||
* The error type returned by the API.
|
||||
*/
|
||||
readonly errorType: string | null
|
||||
/**
|
||||
* The unique request ID for debugging.
|
||||
*/
|
||||
readonly requestId: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter-specific rate limit metadata fields.
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type OpenRouterRateLimitMetadata = OpenRouterErrorMetadata & {
|
||||
readonly limit: string | null
|
||||
readonly remaining: number | null
|
||||
readonly resetRequests: string | null
|
||||
readonly resetTokens: string | null
|
||||
}
|
||||
|
||||
declare module "effect/unstable/ai/AiError" {
|
||||
/**
|
||||
* OpenRouter metadata attached to `RateLimitError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Captures OpenRouter error details together with rate limit header
|
||||
* information from responses where the provider rejected the request because
|
||||
* a limit was reached.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface RateLimitErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the rate limit response.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterRateLimitMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter metadata attached to `QuotaExhaustedError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for failures caused by exhausted account,
|
||||
* billing, or usage quota.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface QuotaExhaustedErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the quota exhaustion response.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter metadata attached to `AuthenticationError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for failed API key, authorization, or
|
||||
* permission checks.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface AuthenticationErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the authentication failure.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter metadata attached to `ContentPolicyError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details when OpenRouter rejects input or output
|
||||
* because it violates a content policy.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface ContentPolicyErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the content policy response.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter metadata attached to `InvalidRequestError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for malformed requests, unsupported
|
||||
* parameters, or other request validation failures reported by OpenRouter.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InvalidRequestErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the invalid request response.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter metadata attached to `InternalProviderError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for OpenRouter-side failures such as
|
||||
* transient server errors or overload responses.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InternalProviderErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the internal provider response.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter metadata attached to `InvalidOutputError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details when an OpenRouter response cannot be
|
||||
* parsed or validated as the expected output.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface InvalidOutputErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the invalid output response.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter metadata attached to `StructuredOutputError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details when OpenRouter returns content that does
|
||||
* not satisfy the requested structured output schema.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface StructuredOutputErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the structured output failure.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter metadata attached to `UnsupportedSchemaError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details when an unsupported schema failure is
|
||||
* associated with an OpenRouter response.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface UnsupportedSchemaErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the unsupported schema failure.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterErrorMetadata | null
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter metadata attached to `UnknownError` values.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Preserves provider error details for OpenRouter failures that do not map
|
||||
* cleanly to a more specific AI error category.
|
||||
*
|
||||
* @category configuration
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface UnknownErrorMetadata {
|
||||
/**
|
||||
* OpenRouter-specific details for the unclassified provider failure.
|
||||
*/
|
||||
readonly openrouter?: OpenRouterErrorMetadata | null
|
||||
}
|
||||
}
|
||||
1861
repos/effect/packages/ai/openrouter/src/OpenRouterLanguageModel.ts
Normal file
1861
repos/effect/packages/ai/openrouter/src/OpenRouterLanguageModel.ts
Normal file
File diff suppressed because it is too large
Load Diff
30
repos/effect/packages/ai/openrouter/src/index.ts
Normal file
30
repos/effect/packages/ai/openrouter/src/index.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
// @barrel: Auto-generated exports. Do not edit manually.
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as Generated from "./Generated.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenRouterClient from "./OpenRouterClient.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenRouterConfig from "./OpenRouterConfig.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenRouterError from "./OpenRouterError.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * as OpenRouterLanguageModel from "./OpenRouterLanguageModel.ts"
|
||||
375
repos/effect/packages/ai/openrouter/src/internal/errors.ts
Normal file
375
repos/effect/packages/ai/openrouter/src/internal/errors.ts
Normal file
@@ -0,0 +1,375 @@
|
||||
import * as Duration from "effect/Duration"
|
||||
import * as Effect from "effect/Effect"
|
||||
import { dual } from "effect/Function"
|
||||
import * as Number from "effect/Number"
|
||||
import * as Option from "effect/Option"
|
||||
import * as Predicate from "effect/Predicate"
|
||||
import * as Redactable from "effect/Redactable"
|
||||
import * as Schema from "effect/Schema"
|
||||
import * as AiError from "effect/unstable/ai/AiError"
|
||||
import type * as Response from "effect/unstable/ai/Response"
|
||||
import type * as HttpClientError from "effect/unstable/http/HttpClientError"
|
||||
import type * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
||||
import type * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
|
||||
import type * as Generated from "../Generated.ts"
|
||||
import type { OpenRouterErrorMetadata } from "../OpenRouterError.ts"
|
||||
|
||||
// =============================================================================
|
||||
// OpenRouter Error Body Schema
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const OpenRouterErrorBody = Schema.Struct({
|
||||
error: Schema.Struct({
|
||||
message: Schema.String,
|
||||
type: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
code: Schema.optional(Schema.NullOr(Schema.Union([Schema.String, Schema.Number.check(Schema.isFinite())])))
|
||||
})
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
export type OpenRouterClientErrorBody = {
|
||||
readonly error: {
|
||||
readonly code: string | number | null
|
||||
readonly message: string
|
||||
readonly param?: string | null
|
||||
readonly type?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Error Mappers
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const mapSchemaError = dual<
|
||||
(method: string) => (error: Schema.SchemaError) => AiError.AiError,
|
||||
(error: Schema.SchemaError, method: string) => AiError.AiError
|
||||
>(2, (error, method) =>
|
||||
AiError.make({
|
||||
module: "OpenRouterClient",
|
||||
method,
|
||||
reason: AiError.InvalidOutputError.fromSchemaError(error)
|
||||
}))
|
||||
|
||||
/** @internal */
|
||||
export const mapClientError = dual<
|
||||
(method: string) => (error: Generated.OpenRouterClientError<string, OpenRouterClientErrorBody>) => AiError.AiError,
|
||||
(error: Generated.OpenRouterClientError<string, OpenRouterClientErrorBody>, method: string) => AiError.AiError
|
||||
>(2, (error, method) => {
|
||||
const { request, response, cause } = error
|
||||
const status = response.status
|
||||
const headers = response.headers as Record<string, string>
|
||||
const metadata: OpenRouterErrorMetadata = {
|
||||
errorCode: cause.error.code ?? null,
|
||||
errorType: cause.error.type ?? null,
|
||||
requestId: headers["x-request-id"] ?? null
|
||||
}
|
||||
const http = buildHttpContext({ request, response, body: JSON.stringify(cause) })
|
||||
const reason = mapStatusCodeToReason({
|
||||
status,
|
||||
headers,
|
||||
message: cause.error.message,
|
||||
metadata,
|
||||
http
|
||||
})
|
||||
return AiError.make({ module: "OpenRouterClient", method, reason })
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
export const mapHttpClientError = dual<
|
||||
(method: string) => (error: HttpClientError.HttpClientError) => Effect.Effect<never, AiError.AiError>,
|
||||
(error: HttpClientError.HttpClientError, method: string) => Effect.Effect<never, AiError.AiError>
|
||||
>(2, (error, method) => {
|
||||
const reason = error.reason
|
||||
switch (reason._tag) {
|
||||
case "TransportError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenRouterClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "TransportError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "EncodeError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenRouterClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "EncodeError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "InvalidUrlError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenRouterClient",
|
||||
method,
|
||||
reason: new AiError.NetworkError({
|
||||
reason: "InvalidUrlError",
|
||||
description: reason.description,
|
||||
request: buildHttpRequestDetails(reason.request)
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "StatusCodeError": {
|
||||
return mapStatusCodeError(reason, method)
|
||||
}
|
||||
case "DecodeError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenRouterClient",
|
||||
method,
|
||||
reason: new AiError.InvalidOutputError({
|
||||
description: reason.description ?? "Failed to decode response"
|
||||
})
|
||||
}))
|
||||
}
|
||||
case "EmptyBodyError": {
|
||||
return Effect.fail(AiError.make({
|
||||
module: "OpenRouterClient",
|
||||
method,
|
||||
reason: new AiError.InvalidOutputError({
|
||||
description: reason.description ?? "Response body was empty"
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
const mapStatusCodeError = Effect.fnUntraced(function*(
|
||||
error: HttpClientError.StatusCodeError,
|
||||
method: string
|
||||
) {
|
||||
const { request, response, description } = error
|
||||
const status = response.status
|
||||
const headers = response.headers as Record<string, string>
|
||||
const requestId = headers["x-request-id"]
|
||||
|
||||
let body: string | undefined = description
|
||||
if (!description || !description.startsWith("{")) {
|
||||
const responseBody = yield* Effect.option(response.text)
|
||||
if (Option.isSome(responseBody) && responseBody.value) {
|
||||
body = responseBody.value
|
||||
}
|
||||
}
|
||||
|
||||
let json: unknown = undefined
|
||||
// @effect-diagnostics effect/tryCatchInEffectGen:off
|
||||
try {
|
||||
json = Predicate.isNotUndefined(body) ? JSON.parse(body) : undefined
|
||||
} catch {
|
||||
json = undefined
|
||||
}
|
||||
const decoded = Schema.decodeUnknownOption(OpenRouterErrorBody)(json)
|
||||
|
||||
const reason = mapStatusCodeToReason({
|
||||
status,
|
||||
headers,
|
||||
message: Option.isSome(decoded) ? decoded.value.error.message : undefined,
|
||||
http: buildHttpContext({ request, response, body }),
|
||||
metadata: {
|
||||
errorCode: Option.isSome(decoded) ? decoded.value.error.code ?? null : null,
|
||||
errorType: Option.isSome(decoded) ? decoded.value.error.type ?? null : null,
|
||||
requestId: requestId ?? null
|
||||
}
|
||||
})
|
||||
|
||||
return yield* AiError.make({ module: "OpenRouterClient", method, reason })
|
||||
})
|
||||
|
||||
// =============================================================================
|
||||
// Rate Limits
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const parseRateLimitHeaders = (headers: Record<string, string>) => {
|
||||
const retryAfterRaw = headers["retry-after"]
|
||||
let retryAfter: Duration.Duration | undefined
|
||||
if (Predicate.isNotUndefined(retryAfterRaw)) {
|
||||
const parsed = Number.parse(retryAfterRaw)
|
||||
if (Option.isSome(parsed)) {
|
||||
retryAfter = Duration.seconds(parsed.value)
|
||||
}
|
||||
}
|
||||
const remainingRaw = headers["x-ratelimit-remaining-requests"]
|
||||
const remaining = Predicate.isNotUndefined(remainingRaw)
|
||||
? Option.getOrNull(Number.parse(remainingRaw))
|
||||
: null
|
||||
return {
|
||||
retryAfter,
|
||||
limit: headers["x-ratelimit-limit-requests"] ?? null,
|
||||
remaining,
|
||||
resetRequests: headers["x-ratelimit-reset-requests"] ?? null,
|
||||
resetTokens: headers["x-ratelimit-reset-tokens"] ?? null
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// HTTP Context
|
||||
// =============================================================================
|
||||
|
||||
/** @internal */
|
||||
export const buildHttpRequestDetails = (
|
||||
request: HttpClientRequest.HttpClientRequest
|
||||
): typeof Response.HttpRequestDetails.Type => ({
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
urlParams: Array.from(request.urlParams),
|
||||
hash: Option.getOrUndefined(request.hash),
|
||||
headers: Redactable.redact(request.headers) as Record<string, string>
|
||||
})
|
||||
|
||||
/** @internal */
|
||||
export const buildHttpContext = (params: {
|
||||
readonly request: HttpClientRequest.HttpClientRequest
|
||||
readonly response?: HttpClientResponse.HttpClientResponse
|
||||
readonly body?: string | undefined
|
||||
}): typeof AiError.HttpContext.Type => ({
|
||||
request: buildHttpRequestDetails(params.request),
|
||||
response: Predicate.isNotUndefined(params.response)
|
||||
? {
|
||||
status: params.response.status,
|
||||
headers: Redactable.redact(params.response.headers) as Record<string, string>
|
||||
}
|
||||
: undefined,
|
||||
body: params.body
|
||||
})
|
||||
|
||||
// =============================================================================
|
||||
// HTTP Status Code
|
||||
// =============================================================================
|
||||
|
||||
const buildInvalidRequestDescription = (params: {
|
||||
readonly status: number
|
||||
readonly message: string | undefined
|
||||
readonly method: string
|
||||
readonly url: string
|
||||
readonly errorCode: string | number | null
|
||||
readonly errorType: string | null
|
||||
readonly requestId: string | null
|
||||
readonly body: string | undefined
|
||||
}): string => {
|
||||
const parts: Array<string> = []
|
||||
|
||||
if (params.message) {
|
||||
parts.push(params.message)
|
||||
} else {
|
||||
parts.push(`HTTP ${params.status}`)
|
||||
}
|
||||
|
||||
parts.push(`(${params.method} ${params.url})`)
|
||||
|
||||
if (params.errorCode) {
|
||||
parts.push(`[code: ${params.errorCode}]`)
|
||||
} else if (params.errorType) {
|
||||
parts.push(`[type: ${params.errorType}]`)
|
||||
}
|
||||
|
||||
if (params.requestId) {
|
||||
parts.push(`[requestId: ${params.requestId}]`)
|
||||
}
|
||||
|
||||
if (!params.message && params.body) {
|
||||
const truncated = params.body.length > 200
|
||||
? params.body.slice(0, 200) + "..."
|
||||
: params.body
|
||||
parts.push(`Response: ${truncated}`)
|
||||
}
|
||||
|
||||
return parts.join(" ")
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const mapStatusCodeToReason = ({ status, headers, message, metadata, http }: {
|
||||
readonly status: number
|
||||
readonly headers: Record<string, string>
|
||||
readonly message: string | undefined
|
||||
readonly metadata: OpenRouterErrorMetadata
|
||||
readonly http: typeof AiError.HttpContext.Type
|
||||
}): AiError.AiErrorReason => {
|
||||
const invalidRequestDescription = buildInvalidRequestDescription({
|
||||
status,
|
||||
message,
|
||||
method: http.request.method,
|
||||
url: http.request.url,
|
||||
errorCode: metadata.errorCode,
|
||||
errorType: metadata.errorType,
|
||||
requestId: metadata.requestId,
|
||||
body: http.body
|
||||
})
|
||||
|
||||
switch (status) {
|
||||
case 400:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { openrouter: metadata },
|
||||
http
|
||||
})
|
||||
case 401:
|
||||
return new AiError.AuthenticationError({
|
||||
kind: "InvalidKey",
|
||||
metadata: { openrouter: metadata },
|
||||
http
|
||||
})
|
||||
case 403:
|
||||
return new AiError.AuthenticationError({
|
||||
kind: "InsufficientPermissions",
|
||||
metadata: { openrouter: metadata },
|
||||
http
|
||||
})
|
||||
case 404:
|
||||
case 409:
|
||||
case 422:
|
||||
return new AiError.InvalidRequestError({
|
||||
description: invalidRequestDescription,
|
||||
metadata: { openrouter: metadata },
|
||||
http
|
||||
})
|
||||
case 429: {
|
||||
if (
|
||||
metadata.errorCode === "insufficient_quota" ||
|
||||
metadata.errorType === "insufficient_quota"
|
||||
) {
|
||||
return new AiError.QuotaExhaustedError({
|
||||
metadata: { openrouter: metadata },
|
||||
http
|
||||
})
|
||||
}
|
||||
const { retryAfter, ...rateLimitMetadata } = parseRateLimitHeaders(headers)
|
||||
return new AiError.RateLimitError({
|
||||
retryAfter,
|
||||
metadata: {
|
||||
openrouter: {
|
||||
...metadata,
|
||||
...rateLimitMetadata
|
||||
}
|
||||
},
|
||||
http
|
||||
})
|
||||
}
|
||||
case 529:
|
||||
return new AiError.InternalProviderError({
|
||||
description: message ?? "OpenRouter API is overloaded",
|
||||
metadata: { openrouter: metadata },
|
||||
http
|
||||
})
|
||||
default:
|
||||
if (status >= 500) {
|
||||
return new AiError.InternalProviderError({
|
||||
description: message ?? "Server error",
|
||||
metadata: { openrouter: metadata },
|
||||
http
|
||||
})
|
||||
}
|
||||
return new AiError.UnknownError({
|
||||
description: message,
|
||||
metadata: { openrouter: metadata },
|
||||
http
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import * as Predicate from "effect/Predicate"
|
||||
import type * as Response from "effect/unstable/ai/Response"
|
||||
import type { ReasoningDetails } from "../OpenRouterLanguageModel.ts"
|
||||
|
||||
const finishReasonMap: Record<string, Response.FinishReason> = {
|
||||
content_filter: "content-filter",
|
||||
error: "error",
|
||||
function_call: "tool-calls",
|
||||
length: "length",
|
||||
tool_calls: "tool-calls",
|
||||
stop: "stop"
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const resolveFinishReason = (
|
||||
finishReason: string | null | undefined
|
||||
): Response.FinishReason =>
|
||||
Predicate.isNotNullish(finishReason)
|
||||
? finishReasonMap[finishReason]
|
||||
: "other"
|
||||
|
||||
/**
|
||||
* Tracks ReasoningDetailUnion entries and deduplicates them based
|
||||
* on a derived canonical key.
|
||||
*
|
||||
* This is used when converting messages to ensure the API request only
|
||||
* contains unique reasoning details, preventing "Duplicate item found with id"
|
||||
* errors in multi-turn conversations.
|
||||
*
|
||||
* The canonical key logic matches the OpenRouter API's deduplication exactly
|
||||
* (see openrouter-web/packages/llm-interfaces/reasonings/duplicate-tracker.ts):
|
||||
* - Summary: key = summary field
|
||||
* - Encrypted: key = id field (if truthy) or data field
|
||||
* - Text: key = text field (if truthy) or signature field (if truthy)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export class ReasoningDetailsDuplicateTracker {
|
||||
readonly #seenKeys = new Set<string>()
|
||||
|
||||
/**
|
||||
* Attempts to track a detail.
|
||||
*
|
||||
* or `false` if it was skipped (no valid key) or already seen (duplicate).
|
||||
*/
|
||||
upsert(detail: ReasoningDetails[number]): boolean {
|
||||
const key = this.getCanonicalKey(detail)
|
||||
|
||||
if (Predicate.isNull(key)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.#seenKeys.has(key)) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.#seenKeys.add(key)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private getCanonicalKey(detail: ReasoningDetails[number]): string | null {
|
||||
// This logic matches the OpenRouter API's deduplication exactly.
|
||||
// See: openrouter-web/packages/llm-interfaces/reasonings/duplicate-tracker.ts
|
||||
switch (detail.type) {
|
||||
case "reasoning.summary": {
|
||||
return detail.summary
|
||||
}
|
||||
|
||||
case "reasoning.encrypted": {
|
||||
return Predicate.isNotNullish(detail.id) ? detail.id : detail.data
|
||||
}
|
||||
|
||||
case "reasoning.text": {
|
||||
if (Predicate.isNotNullish(detail.text)) {
|
||||
return detail.text
|
||||
}
|
||||
|
||||
if (Predicate.isNotNullish(detail.signature)) {
|
||||
return detail.signature
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
default: {
|
||||
// Handle unknown types gracefully
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
import { Generated, OpenRouterClient, OpenRouterLanguageModel } from "@effect/ai-openrouter"
|
||||
import { assert, describe, it } from "@effect/vitest"
|
||||
import { deepStrictEqual, strictEqual } from "@effect/vitest/utils"
|
||||
import { Array, Context, Effect, Layer, Redacted, Ref, Schema } from "effect"
|
||||
import { LanguageModel, Prompt } from "effect/unstable/ai"
|
||||
import { HttpClient, type HttpClientError, type HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
|
||||
|
||||
describe("OpenRouterLanguageModel", () => {
|
||||
describe("generateText", () => {
|
||||
describe("message preparation", () => {
|
||||
describe("audio file parts", () => {
|
||||
it.effect("converts audio bytes to input_audio", () =>
|
||||
Effect.gen(function*() {
|
||||
const audioData = new Uint8Array([0x49, 0x44, 0x33, 0x04]) // ID3v2 magic bytes
|
||||
|
||||
yield* LanguageModel.generateText({
|
||||
prompt: Prompt.make([{
|
||||
role: "user",
|
||||
content: [
|
||||
Prompt.filePart({
|
||||
mediaType: "audio/mpeg",
|
||||
data: audioData
|
||||
})
|
||||
]
|
||||
}])
|
||||
}).pipe(Effect.provide(OpenRouterLanguageModel.model("google/gemini-2.5-flash")))
|
||||
|
||||
const requests = yield* MockHttpClient.requests
|
||||
const body = yield* getRequestBody(requests[0])
|
||||
|
||||
const userMessage = body.messages.find((message: any) => message.role === "user")
|
||||
deepStrictEqual(userMessage.content, [{
|
||||
type: "input_audio",
|
||||
input_audio: {
|
||||
data: "SUQzBA==",
|
||||
format: "mp3"
|
||||
}
|
||||
}])
|
||||
}).pipe(Effect.provide(makeTestLayer())))
|
||||
|
||||
it.effect("converts base64 data url audio to input_audio", () =>
|
||||
Effect.gen(function*() {
|
||||
yield* LanguageModel.generateText({
|
||||
prompt: Prompt.make([{
|
||||
role: "user",
|
||||
content: [
|
||||
Prompt.filePart({
|
||||
mediaType: "audio/wav",
|
||||
data: "data:audio/wav;base64,UklGRg=="
|
||||
})
|
||||
]
|
||||
}])
|
||||
}).pipe(Effect.provide(OpenRouterLanguageModel.model("google/gemini-2.5-flash")))
|
||||
|
||||
const requests = yield* MockHttpClient.requests
|
||||
const body = yield* getRequestBody(requests[0])
|
||||
|
||||
const userMessage = body.messages.find((message: any) => message.role === "user")
|
||||
deepStrictEqual(userMessage.content, [{
|
||||
type: "input_audio",
|
||||
input_audio: {
|
||||
data: "UklGRg==",
|
||||
format: "wav"
|
||||
}
|
||||
}])
|
||||
}).pipe(Effect.provide(makeTestLayer())))
|
||||
|
||||
it.effect("maps audio media types to OpenRouter audio formats", () =>
|
||||
Effect.gen(function*() {
|
||||
const mediaTypes: ReadonlyArray<readonly [mediaType: string, format: string]> = [
|
||||
["audio/aac", "aac"],
|
||||
["audio/x-aiff", "aiff"],
|
||||
["audio/flac", "flac"],
|
||||
["audio/L16", "pcm16"],
|
||||
["audio/mp4", "m4a"],
|
||||
["audio/mp3", "mp3"],
|
||||
["audio/ogg", "ogg"],
|
||||
["audio/x-wav", "wav"]
|
||||
]
|
||||
|
||||
yield* LanguageModel.generateText({
|
||||
prompt: Prompt.make([{
|
||||
role: "user",
|
||||
content: mediaTypes.map(([mediaType]) =>
|
||||
Prompt.filePart({
|
||||
mediaType,
|
||||
data: new Uint8Array([0x00])
|
||||
})
|
||||
)
|
||||
}])
|
||||
}).pipe(Effect.provide(OpenRouterLanguageModel.model("google/gemini-2.5-flash")))
|
||||
|
||||
const requests = yield* MockHttpClient.requests
|
||||
const body = yield* getRequestBody(requests[0])
|
||||
|
||||
const userMessage = body.messages.find((message: any) => message.role === "user")
|
||||
deepStrictEqual(
|
||||
userMessage.content.map((item: any) => item.input_audio.format),
|
||||
mediaTypes.map(([, format]) => format)
|
||||
)
|
||||
}).pipe(Effect.provide(makeTestLayer())))
|
||||
|
||||
it.effect("fails on unsupported audio media types", () =>
|
||||
Effect.gen(function*() {
|
||||
const error = yield* LanguageModel.generateText({
|
||||
prompt: Prompt.make([{
|
||||
role: "user",
|
||||
content: [
|
||||
Prompt.filePart({
|
||||
mediaType: "audio/webm",
|
||||
data: new Uint8Array([0x00])
|
||||
})
|
||||
]
|
||||
}])
|
||||
}).pipe(
|
||||
Effect.provide(OpenRouterLanguageModel.model("google/gemini-2.5-flash")),
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
strictEqual(error.reason._tag, "InvalidUserInputError")
|
||||
assert.include(error.message, "audio/webm")
|
||||
}).pipe(Effect.provide(makeTestLayer())))
|
||||
|
||||
it.effect("fails on audio URLs", () =>
|
||||
Effect.gen(function*() {
|
||||
const error = yield* LanguageModel.generateText({
|
||||
prompt: Prompt.make([{
|
||||
role: "user",
|
||||
content: [
|
||||
Prompt.filePart({
|
||||
mediaType: "audio/mpeg",
|
||||
data: new URL("https://example.com/audio.mp3")
|
||||
})
|
||||
]
|
||||
}])
|
||||
}).pipe(
|
||||
Effect.provide(OpenRouterLanguageModel.model("google/gemini-2.5-flash")),
|
||||
Effect.flip
|
||||
)
|
||||
|
||||
strictEqual(error.reason._tag, "InvalidUserInputError")
|
||||
}).pipe(Effect.provide(makeTestLayer())))
|
||||
|
||||
it.effect("converts non-audio files to file blocks", () =>
|
||||
Effect.gen(function*() {
|
||||
const pdfData = new Uint8Array([0x25, 0x50, 0x44, 0x46]) // %PDF
|
||||
|
||||
yield* LanguageModel.generateText({
|
||||
prompt: Prompt.make([{
|
||||
role: "user",
|
||||
content: [
|
||||
Prompt.filePart({
|
||||
mediaType: "application/pdf",
|
||||
fileName: "document.pdf",
|
||||
data: pdfData
|
||||
})
|
||||
]
|
||||
}])
|
||||
}).pipe(Effect.provide(OpenRouterLanguageModel.model("google/gemini-2.5-flash")))
|
||||
|
||||
const requests = yield* MockHttpClient.requests
|
||||
const body = yield* getRequestBody(requests[0])
|
||||
|
||||
const userMessage = body.messages.find((message: any) => message.role === "user")
|
||||
deepStrictEqual(userMessage.content, [{
|
||||
type: "file",
|
||||
file: {
|
||||
filename: "document.pdf",
|
||||
file_data: "data:application/pdf;base64,JVBERg=="
|
||||
}
|
||||
}])
|
||||
}).pipe(Effect.provide(makeTestLayer())))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================================================
|
||||
// Test Infrastructure
|
||||
// =============================================================================
|
||||
|
||||
class MockOpenRouterResponse extends Context.Service<MockOpenRouterResponse, {
|
||||
readonly status: number
|
||||
readonly body: typeof Generated.SendChatCompletionRequest200.Type
|
||||
readonly headers?: Record<string, string> | undefined
|
||||
}>()("MockOpenRouterResponse") {}
|
||||
|
||||
class MockHttpClient extends Context.Service<MockHttpClient, {
|
||||
readonly requests: Effect.Effect<ReadonlyArray<HttpClientRequest.HttpClientRequest>>
|
||||
}>()("MockHttpClient") {
|
||||
static requests = Effect.service(MockHttpClient).pipe(
|
||||
Effect.flatMap((client) => client.requests)
|
||||
)
|
||||
}
|
||||
|
||||
const encodeResponse = Schema.encodeEffect(Generated.SendChatCompletionRequest200)
|
||||
|
||||
const makeHttpClient = Effect.gen(function*() {
|
||||
const capturedRequests = yield* Ref.make<ReadonlyArray<HttpClientRequest.HttpClientRequest>>([])
|
||||
const response = yield* MockOpenRouterResponse
|
||||
const body = yield* Effect.orDie(encodeResponse(response.body))
|
||||
|
||||
const httpClient = HttpClient.makeWith(
|
||||
Effect.fnUntraced(function*(requestEffect) {
|
||||
const request = yield* requestEffect
|
||||
yield* Ref.update(capturedRequests, Array.append(request))
|
||||
return HttpClientResponse.fromWeb(
|
||||
request,
|
||||
new Response(JSON.stringify(body), {
|
||||
headers: response.headers ?? {},
|
||||
status: response.status
|
||||
})
|
||||
)
|
||||
}),
|
||||
Effect.succeed as HttpClient.HttpClient.Preprocess<HttpClientError.HttpClientError, never>
|
||||
)
|
||||
|
||||
return Context.make(HttpClient.HttpClient, httpClient).pipe(
|
||||
Context.add(MockHttpClient, MockHttpClient.of({ requests: Ref.get(capturedRequests) }))
|
||||
)
|
||||
})
|
||||
|
||||
const HttpClientLayer = Layer.effectContext(makeHttpClient)
|
||||
|
||||
const makeDefaultResponse = (
|
||||
overrides: Partial<typeof Generated.SendChatCompletionRequest200.Type> = {}
|
||||
): typeof Generated.SendChatCompletionRequest200.Type => ({
|
||||
id: "gen-test123",
|
||||
choices: [{
|
||||
finish_reason: "stop",
|
||||
index: 0,
|
||||
message: {
|
||||
role: "assistant",
|
||||
content: "Hello!"
|
||||
}
|
||||
}],
|
||||
created: 1234567890,
|
||||
model: "google/gemini-2.5-flash",
|
||||
object: "chat.completion",
|
||||
...overrides
|
||||
})
|
||||
|
||||
const makeTestLayer = (options: {
|
||||
readonly body?: Partial<typeof Generated.SendChatCompletionRequest200.Type>
|
||||
readonly status?: number
|
||||
readonly headers?: Record<string, string>
|
||||
} = {}) =>
|
||||
OpenRouterClient.layer({ apiKey: Redacted.make("sk-test-key") }).pipe(
|
||||
Layer.provideMerge(HttpClientLayer),
|
||||
Layer.provide(Layer.succeed(MockOpenRouterResponse, {
|
||||
body: makeDefaultResponse(options.body),
|
||||
status: options.status ?? 200,
|
||||
headers: options.headers ?? {}
|
||||
}))
|
||||
)
|
||||
|
||||
const getRequestBody = (request: HttpClientRequest.HttpClientRequest) =>
|
||||
Effect.gen(function*() {
|
||||
const body = request.body
|
||||
if (body._tag === "Uint8Array") {
|
||||
const text = new TextDecoder().decode(body.body)
|
||||
return JSON.parse(text)
|
||||
}
|
||||
return yield* Effect.die(new Error("Expected Uint8Array body"))
|
||||
})
|
||||
10
repos/effect/packages/ai/openrouter/tsconfig.json
Normal file
10
repos/effect/packages/ai/openrouter/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/tsconfig",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{ "path": "../../effect" },
|
||||
{ "path": "../anthropic" },
|
||||
{ "path": "../openai" }
|
||||
]
|
||||
}
|
||||
6
repos/effect/packages/ai/openrouter/vitest.config.ts
Normal file
6
repos/effect/packages/ai/openrouter/vitest.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { mergeConfig, type ViteUserConfig } from "vitest/config"
|
||||
import shared from "../../../vitest.shared.ts"
|
||||
|
||||
const config: ViteUserConfig = {}
|
||||
|
||||
export default mergeConfig(shared, config)
|
||||
711
repos/effect/packages/atom/react/CHANGELOG.md
Normal file
711
repos/effect/packages/atom/react/CHANGELOG.md
Normal file
@@ -0,0 +1,711 @@
|
||||
# @effect/atom-react
|
||||
|
||||
## 4.0.0-beta.99
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8ce4795`](https://github.com/Effect-TS/effect/commit/8ce4795ccbaebca4292757db568c005a992546a4), [`80b539f`](https://github.com/Effect-TS/effect/commit/80b539f8aba68f478c75c35c2b4140c4ffc4fada), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`e6e6dba`](https://github.com/Effect-TS/effect/commit/e6e6dba6e9d86e7c2ad27dcedf289db76a19697f), [`bfb203e`](https://github.com/Effect-TS/effect/commit/bfb203e95aa439f731acad37fc3a9a831a190f1c), [`2e9a34a`](https://github.com/Effect-TS/effect/commit/2e9a34ac2bece4f3a206160480c991e3841dc67a), [`55d4eb3`](https://github.com/Effect-TS/effect/commit/55d4eb34f2c64d54f6a25a305b5c5438ebd7934e), [`bddb010`](https://github.com/Effect-TS/effect/commit/bddb010eac3d4436cb094edbbee7460c5440c162), [`a328835`](https://github.com/Effect-TS/effect/commit/a328835e50d76bc96648a1c1550456e8c9f81210), [`5560d05`](https://github.com/Effect-TS/effect/commit/5560d05aa6abdd29466d9c3412cc5e648b0adbde), [`8f6e3ad`](https://github.com/Effect-TS/effect/commit/8f6e3adb185b16e8820b98c509b308086f7ff1af), [`46997fa`](https://github.com/Effect-TS/effect/commit/46997fa60401f5e3c93daa4b61f7df8e31caaab4), [`9e6e12d`](https://github.com/Effect-TS/effect/commit/9e6e12d75c118cd265496f2880490d1f33a5c8bf), [`3394b93`](https://github.com/Effect-TS/effect/commit/3394b93d97d6f24fc38670641d1490289ffca7f1), [`febeabc`](https://github.com/Effect-TS/effect/commit/febeabc3f7c31094da000a23edeaabfe2ab00a38), [`54161c9`](https://github.com/Effect-TS/effect/commit/54161c98f6f3569e0c31842f54e6a257f9421c4c), [`385f7a4`](https://github.com/Effect-TS/effect/commit/385f7a4ee4a7359928597ea56d151dbaf5eb5802), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`7543afe`](https://github.com/Effect-TS/effect/commit/7543afea6f4d97d1f1ad876224323838a48daadd), [`44b9cf3`](https://github.com/Effect-TS/effect/commit/44b9cf3d240d726997b4bbcd0ede48e074d3c456), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`0a8aa6a`](https://github.com/Effect-TS/effect/commit/0a8aa6acb90a72b91c24d17133c950e4cacd8abd), [`c8d9fcf`](https://github.com/Effect-TS/effect/commit/c8d9fcf7b030f7c474effbab2764ce7aee1c7209), [`9ca7f9a`](https://github.com/Effect-TS/effect/commit/9ca7f9a69363e4485645966d5a93b8f9597c5206), [`e7aca89`](https://github.com/Effect-TS/effect/commit/e7aca894bb32fbb785b5830837e6061c415a6015), [`55d7560`](https://github.com/Effect-TS/effect/commit/55d75609b8acf8a1b54c1b1c7fbbb65ec741aa3e), [`f809189`](https://github.com/Effect-TS/effect/commit/f809189ddf6b6011ba43a9901baaa734e315da2a), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`0ebdbe7`](https://github.com/Effect-TS/effect/commit/0ebdbe74463dc84385956d0b1e8c2b79ebab5400), [`7517d09`](https://github.com/Effect-TS/effect/commit/7517d09f12a0b183a81bd425962c4e280a68b05d), [`212493b`](https://github.com/Effect-TS/effect/commit/212493b9a1eb98cd1ef6959c707a2e5784a5ae91), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`80ea8cb`](https://github.com/Effect-TS/effect/commit/80ea8cb9222ca73f564c8267ab2f82966fea027a), [`8df19f4`](https://github.com/Effect-TS/effect/commit/8df19f4fe81d90cc33ace88b9a77e5534f82d604)]:
|
||||
- effect@4.0.0-beta.99
|
||||
|
||||
## 4.0.0-beta.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`989603b`](https://github.com/Effect-TS/effect-smol/commit/989603b60ab1197b64acf214208e0d370cd1f842), [`214c458`](https://github.com/Effect-TS/effect-smol/commit/214c458084bb6995d543cd37d1055f24be3d454e), [`a037273`](https://github.com/Effect-TS/effect-smol/commit/a0372736ac34796969b051bbba4717d7983f1ebe), [`97fdaa9`](https://github.com/Effect-TS/effect-smol/commit/97fdaa9c1f522c65e579365d314a07878e2b904f), [`b24d248`](https://github.com/Effect-TS/effect-smol/commit/b24d248c8df44222ce642087cde2bd859a2dc709), [`19c222c`](https://github.com/Effect-TS/effect-smol/commit/19c222cac2353a3d7b7733caecb00556fffe9a5c), [`eec85dd`](https://github.com/Effect-TS/effect-smol/commit/eec85ddba09ea326fd268ee33eeffd47e50d4671), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`8849052`](https://github.com/Effect-TS/effect-smol/commit/884905232d1e9a365e046d8dde27bf9c5707f57f), [`c15e16a`](https://github.com/Effect-TS/effect-smol/commit/c15e16ad130d1fbde25d912b7ac55995066cb35b), [`01d00a3`](https://github.com/Effect-TS/effect-smol/commit/01d00a3abfbf1f37996cdbe738ea5137c646cdd7), [`8bd4589`](https://github.com/Effect-TS/effect-smol/commit/8bd458975a1b3a8ed042eccf317b93d28ded91e7), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`6e08428`](https://github.com/Effect-TS/effect-smol/commit/6e08428d980501b856f846ad3f3f0e4ea46e7786), [`388dcf9`](https://github.com/Effect-TS/effect-smol/commit/388dcf953f65d317547f34d40e6443c5f264205f), [`2b7ce2b`](https://github.com/Effect-TS/effect-smol/commit/2b7ce2b513e7ec2a77822f1116dc6ffb6ba93f4e), [`87bea7e`](https://github.com/Effect-TS/effect-smol/commit/87bea7e16259246f3bcdf565446394751abca953), [`ce38dc3`](https://github.com/Effect-TS/effect-smol/commit/ce38dc33bda805a684432cca071f4dc3c6b9a1ba), [`a807cd1`](https://github.com/Effect-TS/effect-smol/commit/a807cd170341deca8a1cfb52c4222585f2431bb9), [`fd8a356`](https://github.com/Effect-TS/effect-smol/commit/fd8a356f06a8c9ce4e7e0a13fc4021c178ed31de), [`c2a5edc`](https://github.com/Effect-TS/effect-smol/commit/c2a5edc3abd31ad5bc123362bc1213e03e4095c3), [`5946da3`](https://github.com/Effect-TS/effect-smol/commit/5946da3804a1be5e752b05b96bd058cdba50a1bf), [`4ae0c5f`](https://github.com/Effect-TS/effect-smol/commit/4ae0c5ffcbe6c56ddfcb05c639112a079483539e), [`5b2a0bc`](https://github.com/Effect-TS/effect-smol/commit/5b2a0bceea3a28a33a58555210c90a415dc74a76), [`72ac585`](https://github.com/Effect-TS/effect-smol/commit/72ac585884befde6af9208da738699a93f1bae79), [`5e8c1b8`](https://github.com/Effect-TS/effect-smol/commit/5e8c1b82bfafa121311f987a49ab75395e3647a7), [`0f9c078`](https://github.com/Effect-TS/effect-smol/commit/0f9c07841b04183f485ee6e6458de73b290b09f5)]:
|
||||
- effect@4.0.0-beta.98
|
||||
|
||||
## 4.0.0-beta.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.97
|
||||
|
||||
## 4.0.0-beta.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1503f45`](https://github.com/Effect-TS/effect-smol/commit/1503f45cb5bb2a74f4705252ec505a1f0ade7e62), [`57fe793`](https://github.com/Effect-TS/effect-smol/commit/57fe79316ffbc380b30626a168981fb26ae97459), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`97f29df`](https://github.com/Effect-TS/effect-smol/commit/97f29df457f7ffd07cfb4b379315c12c086af805)]:
|
||||
- effect@4.0.0-beta.96
|
||||
|
||||
## 4.0.0-beta.95
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a482442`](https://github.com/Effect-TS/effect-smol/commit/a482442abdeb490e9652b854ec3495e4aa7273e7), [`fbefa85`](https://github.com/Effect-TS/effect-smol/commit/fbefa850fab2f0a302c20614496aeaaa2a8b5590), [`0b4a32f`](https://github.com/Effect-TS/effect-smol/commit/0b4a32f4260f0d8500942a133001b0d349328102), [`18a49e1`](https://github.com/Effect-TS/effect-smol/commit/18a49e1786679456258002ff9397faf02f678c2d), [`266cb90`](https://github.com/Effect-TS/effect-smol/commit/266cb90bb2c17aabc40563c32db334f09ba3d74b), [`912f095`](https://github.com/Effect-TS/effect-smol/commit/912f095a34572bbd3cedf6edb27878443e3e4a95), [`a6718f9`](https://github.com/Effect-TS/effect-smol/commit/a6718f9e00a15ca903b0732da46116cbf3d6aca7), [`bef5154`](https://github.com/Effect-TS/effect-smol/commit/bef51540a243aa2f872a00c01d0cd58b7a769baa), [`18e0564`](https://github.com/Effect-TS/effect-smol/commit/18e0564bd0f8ebbdfcaf1e2c21529948e9e4a81d), [`fb50f14`](https://github.com/Effect-TS/effect-smol/commit/fb50f14fc3657c1973785aa5b72ecf0b0d28e0b2)]:
|
||||
- effect@4.0.0-beta.95
|
||||
|
||||
## 4.0.0-beta.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`95a0e9b`](https://github.com/Effect-TS/effect-smol/commit/95a0e9bb62797af0e81c9998773405f248f218c5), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63), [`f11ce73`](https://github.com/Effect-TS/effect-smol/commit/f11ce73af60823754dc24194f4ffc561b9ea1c2d), [`ff30b6e`](https://github.com/Effect-TS/effect-smol/commit/ff30b6e7c2c63ffc56a4c5818d6d86b01b5ad528), [`1caab3c`](https://github.com/Effect-TS/effect-smol/commit/1caab3cc30f626efbf15e59d74f539a487e5c85c), [`aa80c47`](https://github.com/Effect-TS/effect-smol/commit/aa80c4775a04db87553e5568764cab7e32a72814), [`c2ae4fc`](https://github.com/Effect-TS/effect-smol/commit/c2ae4fce2f03a4cd1861c2b1179da7df656e662d), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63)]:
|
||||
- effect@4.0.0-beta.94
|
||||
|
||||
## 4.0.0-beta.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`00652fe`](https://github.com/Effect-TS/effect-smol/commit/00652fe95c18f87208e91343eb8bf218faa2f677), [`6c58167`](https://github.com/Effect-TS/effect-smol/commit/6c5816746eaf91d2a3c7c899c5720809fa230ae3), [`2bc5415`](https://github.com/Effect-TS/effect-smol/commit/2bc541501a7ef89e542d7cb98e96beb53cd205cc), [`e11cccc`](https://github.com/Effect-TS/effect-smol/commit/e11cccc7d5fe631abccc7d6e3bd296938de0fa2e), [`ba7e77e`](https://github.com/Effect-TS/effect-smol/commit/ba7e77e046b8641a3a4e9750bb88ca4a1d063d3f), [`5713ee7`](https://github.com/Effect-TS/effect-smol/commit/5713ee7edbc3054efde407b2286bbfd45bbc6e1c)]:
|
||||
- effect@4.0.0-beta.93
|
||||
|
||||
## 4.0.0-beta.92
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`affdc13`](https://github.com/Effect-TS/effect-smol/commit/affdc139045cc325dce321a84a580fdc1b2da7b9)]:
|
||||
- effect@4.0.0-beta.92
|
||||
|
||||
## 4.0.0-beta.91
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b135b25`](https://github.com/Effect-TS/effect-smol/commit/b135b2517fca9e7839734ace3699a7dfa75b9075), [`aaa21a3`](https://github.com/Effect-TS/effect-smol/commit/aaa21a369a171c600db294f2a4f640583043e150), [`3475ee6`](https://github.com/Effect-TS/effect-smol/commit/3475ee6c2bda6b05c6d7a12ce30c8bb840b5b1a6)]:
|
||||
- effect@4.0.0-beta.91
|
||||
|
||||
## 4.0.0-beta.90
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d237fdf`](https://github.com/Effect-TS/effect-smol/commit/d237fdf726481f76eb52a6196e111b24122bc3d5)]:
|
||||
- effect@4.0.0-beta.90
|
||||
|
||||
## 4.0.0-beta.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b7d46ab`](https://github.com/Effect-TS/effect-smol/commit/b7d46ab7e1a29d8711817bab583c9febf48a0dad), [`7777e15`](https://github.com/Effect-TS/effect-smol/commit/7777e1540fd3680dd8346723cffec812b9384669), [`5376197`](https://github.com/Effect-TS/effect-smol/commit/5376197ca8e50358a41b1fd3cec27bd1ec680ec6)]:
|
||||
- effect@4.0.0-beta.89
|
||||
|
||||
## 4.0.0-beta.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`911f1b8`](https://github.com/Effect-TS/effect-smol/commit/911f1b84790ce42b3a70c95b33e6f6fd9e74de8b), [`8beeeea`](https://github.com/Effect-TS/effect-smol/commit/8beeeea52879d8613a39468848f01c3092bd54d4), [`c306fcf`](https://github.com/Effect-TS/effect-smol/commit/c306fcfeb1ef38455156932a1faf49292b1318da)]:
|
||||
- effect@4.0.0-beta.88
|
||||
|
||||
## 4.0.0-beta.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a0c1a4`](https://github.com/Effect-TS/effect-smol/commit/5a0c1a4faee5707b5cc35e646ff1ffdad70f1956), [`1eea2ea`](https://github.com/Effect-TS/effect-smol/commit/1eea2ea3795ba47316b82b1ac8d4612c0ba389ed)]:
|
||||
- effect@4.0.0-beta.87
|
||||
|
||||
## 4.0.0-beta.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0b5795a`](https://github.com/Effect-TS/effect-smol/commit/0b5795a0ab4395e8f15955d8d96f2303084bfc64), [`3e3a859`](https://github.com/Effect-TS/effect-smol/commit/3e3a859ec6351a9e0d31674aabbd48fcefabb12e), [`7dbec24`](https://github.com/Effect-TS/effect-smol/commit/7dbec240dbf3bca599a20c486632abce694ef5ab), [`d8c00a1`](https://github.com/Effect-TS/effect-smol/commit/d8c00a171ac7141e8adc08c332d1162d9a9d56fc), [`85b6317`](https://github.com/Effect-TS/effect-smol/commit/85b631701e935866f2762bd595237aa718370cd9), [`6d0fda0`](https://github.com/Effect-TS/effect-smol/commit/6d0fda0d0cbdfffc523c89c57dfdb1608f84fb12), [`108a933`](https://github.com/Effect-TS/effect-smol/commit/108a9335ff8571928197e5847a09c28ac83d6f46), [`7e1f455`](https://github.com/Effect-TS/effect-smol/commit/7e1f455fab5005d769b939c91e519d450f802cf9), [`46b3e79`](https://github.com/Effect-TS/effect-smol/commit/46b3e79944cfdae7901eb148135c85b7eb39834e)]:
|
||||
- effect@4.0.0-beta.86
|
||||
|
||||
## 4.0.0-beta.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`328d97c`](https://github.com/Effect-TS/effect-smol/commit/328d97cc53c0dcb89077a5623e35b095eaa59a8c), [`8441836`](https://github.com/Effect-TS/effect-smol/commit/8441836e6dde70e8ae2126be9cefe9b45798b134), [`074e436`](https://github.com/Effect-TS/effect-smol/commit/074e4361091289104cb0ab6959dc3b0ea7794a6a), [`c1dfd60`](https://github.com/Effect-TS/effect-smol/commit/c1dfd60663eb13a58916f3712d877499943b628a), [`2ba316b`](https://github.com/Effect-TS/effect-smol/commit/2ba316bd15fcbf1c50626500d44a2c9b3bec19f5), [`7ce7344`](https://github.com/Effect-TS/effect-smol/commit/7ce7344c41056c79e2ee19ee6a9346c0f1d227c1)]:
|
||||
- effect@4.0.0-beta.85
|
||||
|
||||
## 4.0.0-beta.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`87f52ba`](https://github.com/Effect-TS/effect-smol/commit/87f52ba16c4370ffa3f84bf8e53038e1419c284e), [`b8ee07f`](https://github.com/Effect-TS/effect-smol/commit/b8ee07ffda8903b5ec2e45a786ddcba59f128fda), [`867c0d7`](https://github.com/Effect-TS/effect-smol/commit/867c0d70a09079b040260d45a1e92ff04dbfbf2f), [`b93bc6c`](https://github.com/Effect-TS/effect-smol/commit/b93bc6c9cb27b909a41d094c97c4f9d25bbc6d6b), [`57d387f`](https://github.com/Effect-TS/effect-smol/commit/57d387f92c30ab63e15e3e641f0a903b65886610), [`bacca41`](https://github.com/Effect-TS/effect-smol/commit/bacca4141c2400effae1eabfdb36c89a459cf246), [`0f8ac79`](https://github.com/Effect-TS/effect-smol/commit/0f8ac7959d29ed68c68ce25aabd6bf0cb7e63ecc), [`25b4482`](https://github.com/Effect-TS/effect-smol/commit/25b448270c01317703f25107e1480d4cd0246d9a), [`9cf3a25`](https://github.com/Effect-TS/effect-smol/commit/9cf3a25c66b0c44a52be9829870c44517ea52db2), [`8def767`](https://github.com/Effect-TS/effect-smol/commit/8def7674b1787f91035298cda4d122937e87ef72)]:
|
||||
- effect@4.0.0-beta.84
|
||||
|
||||
## 4.0.0-beta.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1f2e8ce`](https://github.com/Effect-TS/effect-smol/commit/1f2e8ceef09e0a791c850ed2ade01f97089596f9)]:
|
||||
- effect@4.0.0-beta.83
|
||||
|
||||
## 4.0.0-beta.82
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`193690b`](https://github.com/Effect-TS/effect-smol/commit/193690b642ea802bbed40d663bd677251bbe9dc3)]:
|
||||
- effect@4.0.0-beta.82
|
||||
|
||||
## 4.0.0-beta.81
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`93cb4f8`](https://github.com/Effect-TS/effect-smol/commit/93cb4f8fbfb9e07cb9dc86ce6b155fd1f8167914), [`60341d9`](https://github.com/Effect-TS/effect-smol/commit/60341d9ca744d0473ce3fab621ca9bd225af3a39), [`1105ab5`](https://github.com/Effect-TS/effect-smol/commit/1105ab56cb724212f7ea7b431396ce82e8fd0484), [`4500fbf`](https://github.com/Effect-TS/effect-smol/commit/4500fbfe00763d8a72af6e5d6c5988e8bd4ade36)]:
|
||||
- effect@4.0.0-beta.81
|
||||
|
||||
## 4.0.0-beta.80
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d944330`](https://github.com/Effect-TS/effect-smol/commit/d94433090ee03f426d43e13b883abae4494e55e6), [`f48659f`](https://github.com/Effect-TS/effect-smol/commit/f48659fdcc84930ebc1e5b45b540c0f973389182), [`7652aaa`](https://github.com/Effect-TS/effect-smol/commit/7652aaa3bdbc39f241fe58b54b9a43b713e22e12), [`98630b7`](https://github.com/Effect-TS/effect-smol/commit/98630b7c8f679c352ba6796636c85688fa009d8d), [`90ae23c`](https://github.com/Effect-TS/effect-smol/commit/90ae23cf07284da5e1bcd9dffa882e85df7e617b)]:
|
||||
- effect@4.0.0-beta.80
|
||||
|
||||
## 4.0.0-beta.79
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b9704dc`](https://github.com/Effect-TS/effect-smol/commit/b9704dc9de9f1649ad502371014fe869b69a49a3), [`a207113`](https://github.com/Effect-TS/effect-smol/commit/a207113f66837bb54416926718a9a7d66774d079), [`5e9b9e2`](https://github.com/Effect-TS/effect-smol/commit/5e9b9e217b164ebfd4a002dd4380b3b1563200c3), [`7c128ae`](https://github.com/Effect-TS/effect-smol/commit/7c128aef458a1e2d224712e51c483c9badad1d44), [`0ada457`](https://github.com/Effect-TS/effect-smol/commit/0ada457c0513d8d908254ab77ebb7d29d2b523d6), [`d7cc5a2`](https://github.com/Effect-TS/effect-smol/commit/d7cc5a2bede3de10943aa0c6bdb4f26836a91efd), [`aad63be`](https://github.com/Effect-TS/effect-smol/commit/aad63becf65e0a6b076e94f8973be7bbe7fbd46f), [`09809f6`](https://github.com/Effect-TS/effect-smol/commit/09809f60f19ec98232f98b33e33e02ecb7e4fbd6), [`2fddda5`](https://github.com/Effect-TS/effect-smol/commit/2fddda5311929f46b61e503f0ade4fc749e8c77d), [`5f21768`](https://github.com/Effect-TS/effect-smol/commit/5f2176833399757c4500d8875b7f2fba0393de75), [`f27003e`](https://github.com/Effect-TS/effect-smol/commit/f27003e00524ff83f20dd9909f62b2f8795efe03)]:
|
||||
- effect@4.0.0-beta.79
|
||||
|
||||
## 4.0.0-beta.78
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7836b8e`](https://github.com/Effect-TS/effect-smol/commit/7836b8eb8bb0f3e04cdf554ee070caccf74f00c1), [`35d49a3`](https://github.com/Effect-TS/effect-smol/commit/35d49a3a09bdba6b513de87ddcead9e61a1042ba), [`4093258`](https://github.com/Effect-TS/effect-smol/commit/40932580e65bafab5f23c5f14b520cb411d0b2cd)]:
|
||||
- effect@4.0.0-beta.78
|
||||
|
||||
## 4.0.0-beta.77
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6e9a5ca`](https://github.com/Effect-TS/effect-smol/commit/6e9a5ca62a61156fd67b2518ad3ab14ac0d25f23), [`302f398`](https://github.com/Effect-TS/effect-smol/commit/302f3984ce206e35d86ddd99d3b72be144850a51)]:
|
||||
- effect@4.0.0-beta.77
|
||||
|
||||
## 4.0.0-beta.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`016108a`](https://github.com/Effect-TS/effect-smol/commit/016108a472af7048ddbbfd05f233e67529fafe12), [`95c03d2`](https://github.com/Effect-TS/effect-smol/commit/95c03d2c55930668c215b5a41c23cf7742fead84), [`07299a3`](https://github.com/Effect-TS/effect-smol/commit/07299a33c09fd52faa9810d30835a2622c752386)]:
|
||||
- effect@4.0.0-beta.76
|
||||
|
||||
## 4.0.0-beta.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`81b187c`](https://github.com/Effect-TS/effect-smol/commit/81b187c17a0d8817b58232826939154010ae49d7), [`ad4b535`](https://github.com/Effect-TS/effect-smol/commit/ad4b535e17f94ce35261829d5a3675f0a7808b4e), [`a29c2e7`](https://github.com/Effect-TS/effect-smol/commit/a29c2e7e3570920156702671d6f3367cd0195f6c), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`ffea4ec`](https://github.com/Effect-TS/effect-smol/commit/ffea4ecf2925f6a4c9fd13079d47584cbf2bed00), [`4255c9b`](https://github.com/Effect-TS/effect-smol/commit/4255c9ba78bb98c7838fbe9dccdd8465e9da5427)]:
|
||||
- effect@4.0.0-beta.75
|
||||
|
||||
## 4.0.0-beta.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b1fc6a4`](https://github.com/Effect-TS/effect-smol/commit/b1fc6a4b4d0ca7fa9fd162799ae17c86f2f7ee8e)]:
|
||||
- effect@4.0.0-beta.74
|
||||
|
||||
## 4.0.0-beta.73
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`361ca30`](https://github.com/Effect-TS/effect-smol/commit/361ca30eb6e134feece547d6e00f82be4cb23f75), [`b9598c6`](https://github.com/Effect-TS/effect-smol/commit/b9598c6a209e75bfdb87ee3b024ecd1e3923ff6e)]:
|
||||
- effect@4.0.0-beta.73
|
||||
|
||||
## 4.0.0-beta.72
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`73e67d1`](https://github.com/Effect-TS/effect-smol/commit/73e67d119a84d697773eaecb4865c6a71eb1a9cb), [`01d71ec`](https://github.com/Effect-TS/effect-smol/commit/01d71ec5a75f3c2747a8d3b1ad9701d1e27b7ce5), [`fcd707e`](https://github.com/Effect-TS/effect-smol/commit/fcd707e091a16e1b35343c901cc4052274e32239)]:
|
||||
- effect@4.0.0-beta.72
|
||||
|
||||
## 4.0.0-beta.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d8ac76b`](https://github.com/Effect-TS/effect-smol/commit/d8ac76b5bad458c42cebe8a0c1b3843f955ac293), [`2c3c00a`](https://github.com/Effect-TS/effect-smol/commit/2c3c00af6faba7b7d422af26a7a2bbc35636d230), [`3751e7c`](https://github.com/Effect-TS/effect-smol/commit/3751e7cf353e7a54cd692c37401207d9afba1e63), [`fc5f25b`](https://github.com/Effect-TS/effect-smol/commit/fc5f25b03ada5fc2431987768a74d3d3e75ca485), [`7ccced4`](https://github.com/Effect-TS/effect-smol/commit/7ccced42867c14c013b01160b3d292f14c05bd04), [`a2e1fe5`](https://github.com/Effect-TS/effect-smol/commit/a2e1fe5835c98c8ee4393a091b1d11b75126e349), [`4a4a36b`](https://github.com/Effect-TS/effect-smol/commit/4a4a36b10e6e616cad07584a43908f6a7e07e618), [`d350292`](https://github.com/Effect-TS/effect-smol/commit/d3502922b4740fa9d745797cbc3775cb67839b6d), [`730afb6`](https://github.com/Effect-TS/effect-smol/commit/730afb66696adf9bd5a328cbca29df9c05968771), [`df1b008`](https://github.com/Effect-TS/effect-smol/commit/df1b008f370f414c2a67a7b8139ef747af8e5fba), [`6d469d5`](https://github.com/Effect-TS/effect-smol/commit/6d469d567a7c41d7e5343bdee21d45b07b0e8190)]:
|
||||
- effect@4.0.0-beta.71
|
||||
|
||||
## 4.0.0-beta.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af7782d`](https://github.com/Effect-TS/effect-smol/commit/af7782d3008d08b043f3a3f261516001514b2b4e), [`7212d70`](https://github.com/Effect-TS/effect-smol/commit/7212d701a3eee7b3553ff502e2c066126e52e839)]:
|
||||
- effect@4.0.0-beta.70
|
||||
|
||||
## 4.0.0-beta.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70ea04a`](https://github.com/Effect-TS/effect-smol/commit/70ea04aa96a2a7859d738d414e1f0e3ed081a27a), [`d0ea8b0`](https://github.com/Effect-TS/effect-smol/commit/d0ea8b03f7d73ae076c1db12666141e480d11178), [`a57674b`](https://github.com/Effect-TS/effect-smol/commit/a57674b64845e9e75a456cf907bfdcb858859118), [`59aa334`](https://github.com/Effect-TS/effect-smol/commit/59aa334fbd0a504dda3c36f6d2ef1be7449b4b8b), [`8f4208e`](https://github.com/Effect-TS/effect-smol/commit/8f4208ee83bc7bdaa6793b5429847b45aab72470)]:
|
||||
- effect@4.0.0-beta.69
|
||||
|
||||
## 4.0.0-beta.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af8267f`](https://github.com/Effect-TS/effect-smol/commit/af8267f2f3588c3fb611e9286f6f933f29ce1217), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`f136bb7`](https://github.com/Effect-TS/effect-smol/commit/f136bb763048cbc6b17edd26496dba3e2415b9fa), [`6f38f07`](https://github.com/Effect-TS/effect-smol/commit/6f38f07d5941a211b251383aaab0f4f55e8a6557), [`aec9c40`](https://github.com/Effect-TS/effect-smol/commit/aec9c401a53db227f18bf5e0c84db7130ad862d6)]:
|
||||
- effect@4.0.0-beta.68
|
||||
|
||||
## 4.0.0-beta.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a42ef66`](https://github.com/Effect-TS/effect-smol/commit/a42ef6632abbddfa820995ae310ccc84ae8d9b6f), [`35594f8`](https://github.com/Effect-TS/effect-smol/commit/35594f811cafe471acd490114b103a1f8392c8d8), [`8bddd62`](https://github.com/Effect-TS/effect-smol/commit/8bddd628cb623f9533d345082583ff51cead6836), [`4be4c8d`](https://github.com/Effect-TS/effect-smol/commit/4be4c8d60862aa963869ee2ed9ffa048ffac0527), [`0c9d3ab`](https://github.com/Effect-TS/effect-smol/commit/0c9d3ab43eb721a370ed8306260cbac218c27e87), [`b156acc`](https://github.com/Effect-TS/effect-smol/commit/b156accd2691b4a051f823affdece7c39923ce85), [`d16c034`](https://github.com/Effect-TS/effect-smol/commit/d16c03434ee3e6dcd3bfc82b65d99e881d89025b), [`b559d68`](https://github.com/Effect-TS/effect-smol/commit/b559d68845f848a10153395778f035682d399075), [`a3de5d9`](https://github.com/Effect-TS/effect-smol/commit/a3de5d9215e5cc4a62e2666efbd7c1bf595eb84f), [`7e6c12e`](https://github.com/Effect-TS/effect-smol/commit/7e6c12ec9b3a5945f6c26e272cc8f6390541ad3e), [`098167a`](https://github.com/Effect-TS/effect-smol/commit/098167a220fe07da6f14455818733ab1b269c9dd)]:
|
||||
- effect@4.0.0-beta.67
|
||||
|
||||
## 4.0.0-beta.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ca2498e`](https://github.com/Effect-TS/effect-smol/commit/ca2498e702ac2d83fb7187707b7eb069bdb261a2), [`cd7d1fb`](https://github.com/Effect-TS/effect-smol/commit/cd7d1fba7e2e2c5ac3ad64e1be433440a5bda436), [`19a7033`](https://github.com/Effect-TS/effect-smol/commit/19a703367ec817cffc41d152da9b594827408e2b), [`33d26b4`](https://github.com/Effect-TS/effect-smol/commit/33d26b4210b2e974f146a71e7eed962f8ce00900), [`856766b`](https://github.com/Effect-TS/effect-smol/commit/856766b2c506aaed6d2df1d63bf3a5b1b062e1d4), [`079c7df`](https://github.com/Effect-TS/effect-smol/commit/079c7df82559bb9ce10a86dffb85d25e6ce07dc3)]:
|
||||
- effect@4.0.0-beta.66
|
||||
|
||||
## 4.0.0-beta.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6f11454`](https://github.com/Effect-TS/effect-smol/commit/6f11454a9b6c3bd00f6b35fd7af14a2f2d63a0a2)]:
|
||||
- effect@4.0.0-beta.65
|
||||
|
||||
## 4.0.0-beta.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d4877a`](https://github.com/Effect-TS/effect-smol/commit/7d4877a1929cdb690280ea254326c04f2ec97ea5)]:
|
||||
- effect@4.0.0-beta.64
|
||||
|
||||
## 4.0.0-beta.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7f927ff`](https://github.com/Effect-TS/effect-smol/commit/7f927ffb7a9801dcfc4096c29e369d13d65cd0ac), [`a696b3e`](https://github.com/Effect-TS/effect-smol/commit/a696b3e83a8504cdbe261a18c10a1cc0619ae102)]:
|
||||
- effect@4.0.0-beta.63
|
||||
|
||||
## 4.0.0-beta.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4ab4b90`](https://github.com/Effect-TS/effect-smol/commit/4ab4b9007dc27a52ffabc6fcb37c96eeec795bf7)]:
|
||||
- effect@4.0.0-beta.62
|
||||
|
||||
## 4.0.0-beta.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`50790af`](https://github.com/Effect-TS/effect-smol/commit/50790af9b190c38d10fb0723837d49b66432638f), [`71f7c3d`](https://github.com/Effect-TS/effect-smol/commit/71f7c3df997deda92c84146d569696dab3bd645c), [`aae8797`](https://github.com/Effect-TS/effect-smol/commit/aae8797b9cb383be0c182dd58d03d787c354238b)]:
|
||||
- effect@4.0.0-beta.61
|
||||
|
||||
## 4.0.0-beta.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f69d567`](https://github.com/Effect-TS/effect-smol/commit/f69d5675dcff9f4137295752baf066b7153fdc09), [`7909c95`](https://github.com/Effect-TS/effect-smol/commit/7909c954b8f6244a35a4b429f8dd0dff45dad620), [`bbb4dcc`](https://github.com/Effect-TS/effect-smol/commit/bbb4dcc6c406b83a416b4ad3541cc02037c420e4), [`7af2207`](https://github.com/Effect-TS/effect-smol/commit/7af2207901eabf3132c1b7010a69b3899c06fbbe), [`848b40a`](https://github.com/Effect-TS/effect-smol/commit/848b40a4bd4bf54a5098617d50c33c88eee8270a)]:
|
||||
- effect@4.0.0-beta.60
|
||||
|
||||
## 4.0.0-beta.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`56837ea`](https://github.com/Effect-TS/effect-smol/commit/56837ea2a338395b35550641374e9e589bd8b71d)]:
|
||||
- effect@4.0.0-beta.59
|
||||
|
||||
## 4.0.0-beta.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`11993d4`](https://github.com/Effect-TS/effect-smol/commit/11993d4934c66f5dc611b8bbf553f01d501ef8f7), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec)]:
|
||||
- effect@4.0.0-beta.58
|
||||
|
||||
## 4.0.0-beta.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a971f5c`](https://github.com/Effect-TS/effect-smol/commit/a971f5cbd92dfe4274420bf0966595eb35531060), [`8e110c5`](https://github.com/Effect-TS/effect-smol/commit/8e110c5f02a429ccc43a91df8678e402138c0851)]:
|
||||
- effect@4.0.0-beta.57
|
||||
|
||||
## 4.0.0-beta.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.56
|
||||
|
||||
## 4.0.0-beta.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42cc744`](https://github.com/Effect-TS/effect-smol/commit/42cc744570968deb365fb46d47b53d3277050c93), [`04855ce`](https://github.com/Effect-TS/effect-smol/commit/04855ceeca4d40c55a5750dd9893b691f8ea741a)]:
|
||||
- effect@4.0.0-beta.55
|
||||
|
||||
## 4.0.0-beta.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e4b74f9`](https://github.com/Effect-TS/effect-smol/commit/e4b74f9c01a0e9b6cd58416de4af3a26d51da7c8), [`4c72808`](https://github.com/Effect-TS/effect-smol/commit/4c728081851c66dacf889a816535671bc841ae96)]:
|
||||
- effect@4.0.0-beta.54
|
||||
|
||||
## 4.0.0-beta.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0768509`](https://github.com/Effect-TS/effect-smol/commit/07685094e931af07d104165195826a535b55fa7e), [`476aede`](https://github.com/Effect-TS/effect-smol/commit/476aede69c6efa06b5781ca5eb3e3b128ca29141), [`4f79c54`](https://github.com/Effect-TS/effect-smol/commit/4f79c542e7b508c235ff485d862cc8b29a8260c5), [`4be6a7c`](https://github.com/Effect-TS/effect-smol/commit/4be6a7cf35dab2a01d652f56dd35f0358c5a7e88), [`88927eb`](https://github.com/Effect-TS/effect-smol/commit/88927ebb896162cdba103b36553280b58e0facac)]:
|
||||
- effect@4.0.0-beta.53
|
||||
|
||||
## 4.0.0-beta.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`cf3a311`](https://github.com/Effect-TS/effect-smol/commit/cf3a311d863a8abb818840c3b80f847e621c43c1), [`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`131fdd5`](https://github.com/Effect-TS/effect-smol/commit/131fdd5b1f26531e265fe1a08f002002f47c276e)]:
|
||||
- effect@4.0.0-beta.52
|
||||
|
||||
## 4.0.0-beta.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`778d2af`](https://github.com/Effect-TS/effect-smol/commit/778d2afe9b5154bc1f9abae46d93ea7e54c87344), [`4e24dcf`](https://github.com/Effect-TS/effect-smol/commit/4e24dcf75037f65eebc1eb68623bc7cbf9d5512a), [`4b1c015`](https://github.com/Effect-TS/effect-smol/commit/4b1c0150e9bdb5559ed32d250deb66e17b4240c7), [`454f8ad`](https://github.com/Effect-TS/effect-smol/commit/454f8adad822929c3ef60f8280d0987226b049fd), [`6754a0c`](https://github.com/Effect-TS/effect-smol/commit/6754a0cd18626b06805a079cc5265525a5eb7d27), [`90f7fd5`](https://github.com/Effect-TS/effect-smol/commit/90f7fd5243871b30980964135db4512b8119fa82), [`d7e1519`](https://github.com/Effect-TS/effect-smol/commit/d7e151974934201fd93fa4c8a1192ee9a5d965a0), [`72a8122`](https://github.com/Effect-TS/effect-smol/commit/72a81228e09782bae512f7d041bbfbc78bc668d0)]:
|
||||
- effect@4.0.0-beta.51
|
||||
|
||||
## 4.0.0-beta.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`07be594`](https://github.com/Effect-TS/effect-smol/commit/07be594825de60f8e1b2102d21dbb9b8fc63b414), [`ae02433`](https://github.com/Effect-TS/effect-smol/commit/ae02433103ce28f53a0c9bfb4a44e75773289b7b)]:
|
||||
- effect@4.0.0-beta.50
|
||||
|
||||
## 4.0.0-beta.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d87873`](https://github.com/Effect-TS/effect-smol/commit/7d8787340ff549370f6f2a88b612e9ebbfd6ba45), [`c2f6f90`](https://github.com/Effect-TS/effect-smol/commit/c2f6f901b200a6e515b4f02c93ce8005b7bbf1c5), [`216f13c`](https://github.com/Effect-TS/effect-smol/commit/216f13c1fce454a21b489bb915714a17e791a1ac)]:
|
||||
- effect@4.0.0-beta.49
|
||||
|
||||
## 4.0.0-beta.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4da56ec`](https://github.com/Effect-TS/effect-smol/commit/4da56ecff129b2da40137ffede23a73cc4e532d8), [`a5e6f77`](https://github.com/Effect-TS/effect-smol/commit/a5e6f774bab195cf50ecdc818240765f69a3bf4a), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070)]:
|
||||
- effect@4.0.0-beta.48
|
||||
|
||||
## 4.0.0-beta.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c584726`](https://github.com/Effect-TS/effect-smol/commit/c58472674e750e6938df955044eab88feda95e45), [`86a91a4`](https://github.com/Effect-TS/effect-smol/commit/86a91a4f0c59286dfa9393232d8020dea70ed4db), [`131caf9`](https://github.com/Effect-TS/effect-smol/commit/131caf9525151a0cb29803a8f1dffa0f4f479d12), [`c3615c8`](https://github.com/Effect-TS/effect-smol/commit/c3615c88379b9daf252df0db72c6ac5a20326406)]:
|
||||
- effect@4.0.0-beta.47
|
||||
|
||||
## 4.0.0-beta.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a30b9e`](https://github.com/Effect-TS/effect-smol/commit/3a30b9e2ec2bd8b8193e1aa139f6878a07e3f5ee)]:
|
||||
- effect@4.0.0-beta.46
|
||||
|
||||
## 4.0.0-beta.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c3af6d`](https://github.com/Effect-TS/effect-smol/commit/5c3af6d554f60be34f8fc21d598d9a298ae11beb)]:
|
||||
- effect@4.0.0-beta.45
|
||||
|
||||
## 4.0.0-beta.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1961](https://github.com/Effect-TS/effect-smol/pull/1961) [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970) Thanks @IMax153! - Rename the `ServiceMap` module to `Context` across exports, docs, and tests.
|
||||
|
||||
- Updated dependencies [[`e3f0621`](https://github.com/Effect-TS/effect-smol/commit/e3f0621454c3f5d11070d30619da27c9232cadc1), [`5b476ab`](https://github.com/Effect-TS/effect-smol/commit/5b476abc0bd7e9bb59135ea1bcad2e4936227ced), [`6b40e5a`](https://github.com/Effect-TS/effect-smol/commit/6b40e5a4a6bd2087c15a3d7374d25057fdedfa16), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`3b09fb3`](https://github.com/Effect-TS/effect-smol/commit/3b09fb31c40c2802b01f21c23bcdd1fe7fb0aa82), [`2370410`](https://github.com/Effect-TS/effect-smol/commit/237041062e5af4594d32db91597e34e70a632877), [`dabc272`](https://github.com/Effect-TS/effect-smol/commit/dabc272444a700eb629c07ba3e77671a841ca86e), [`08b63c3`](https://github.com/Effect-TS/effect-smol/commit/08b63c3df11bd35c9fd6090dbd166287fdc40664), [`dfff04c`](https://github.com/Effect-TS/effect-smol/commit/dfff04c4c2b1d352dfad83992a6dce1280c85cf9), [`9baed9e`](https://github.com/Effect-TS/effect-smol/commit/9baed9e17e84702e6e480fcef6f86404f9e24be9), [`7846792`](https://github.com/Effect-TS/effect-smol/commit/7846792adc7e1631d62d26d657bd7ba6139f369b), [`1556a24`](https://github.com/Effect-TS/effect-smol/commit/1556a247623636b7ebe438fb56d77f1a7bf957bb), [`7c11bc2`](https://github.com/Effect-TS/effect-smol/commit/7c11bc292ab8e46252fe8f7576fb685917bfb8b5), [`b5ea591`](https://github.com/Effect-TS/effect-smol/commit/b5ea5913ec1d45d0dd12a327b9dd966bda2f6d02), [`0853afa`](https://github.com/Effect-TS/effect-smol/commit/0853afaeb1633b2d7f8b66893bd01c3aa1ef2c22), [`ac845f3`](https://github.com/Effect-TS/effect-smol/commit/ac845f3ab40e0b8719576e7f9bc16ea2e0e02cd4), [`b80c462`](https://github.com/Effect-TS/effect-smol/commit/b80c46247480f47bb64fc480fab48a3f37bc8888), [`b3f535d`](https://github.com/Effect-TS/effect-smol/commit/b3f535d9a7ac13b5fb984c29f93561c57a081ff0), [`6fe2e93`](https://github.com/Effect-TS/effect-smol/commit/6fe2e93cc2f1b173ef89651d74b6a5d2626b3226), [`cda8004`](https://github.com/Effect-TS/effect-smol/commit/cda800451c1ffbdddfc08415aed7b2d91e0412ee), [`8335477`](https://github.com/Effect-TS/effect-smol/commit/8335477a8a936a24b5f3ee6203c1b268bd1bfc3c), [`8c836f9`](https://github.com/Effect-TS/effect-smol/commit/8c836f99ab1e896b9580a71d67773625baff2eaf), [`718ff6f`](https://github.com/Effect-TS/effect-smol/commit/718ff6fe3e3d3820cefd67d2bff1b2224fe08060), [`7eed84f`](https://github.com/Effect-TS/effect-smol/commit/7eed84fc33c5781a6fb11bf4fd189d424902ebd4), [`5df46fe`](https://github.com/Effect-TS/effect-smol/commit/5df46fe2f654d59ab5fc1578f4fc27fa40368ef9), [`82dd0f2`](https://github.com/Effect-TS/effect-smol/commit/82dd0f26c6442b07143762ef7bc33742d3978dd6), [`03ae41e`](https://github.com/Effect-TS/effect-smol/commit/03ae41e7304cffac9f18feea22b73468feafc43a), [`4677a0a`](https://github.com/Effect-TS/effect-smol/commit/4677a0a58f95eea38a211efcd3f345f237a9e44a), [`87e1fc8`](https://github.com/Effect-TS/effect-smol/commit/87e1fc8b67e4901d75f567b2fecc3841ab762cc4), [`c1af1b7`](https://github.com/Effect-TS/effect-smol/commit/c1af1b756f63291e9c0298cf95c98a6920a0c2a0), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`c8a877b`](https://github.com/Effect-TS/effect-smol/commit/c8a877b53e8f29616335719e5dd1c3992dddf780), [`7da961a`](https://github.com/Effect-TS/effect-smol/commit/7da961ae4916229d2246699a5d3b20e5b2dd2020)]:
|
||||
- effect@4.0.0-beta.44
|
||||
|
||||
## 4.0.0-beta.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`2ae33d0`](https://github.com/Effect-TS/effect-smol/commit/2ae33d050914915f7cb9c25ab0a020901e08d596), [`979811a`](https://github.com/Effect-TS/effect-smol/commit/979811a4c3f7ed21ed18ef560c49fb7f5569e80e), [`eb7dbef`](https://github.com/Effect-TS/effect-smol/commit/eb7dbeffa883386ad912815e62c0820cac1fdf8e), [`cf50eb4`](https://github.com/Effect-TS/effect-smol/commit/cf50eb49cb04706dae5185f624708117c413dee8), [`1d046fe`](https://github.com/Effect-TS/effect-smol/commit/1d046fe484560e23f3e22cb23eec6433f8f1fa02)]:
|
||||
- effect@4.0.0-beta.43
|
||||
|
||||
## 4.0.0-beta.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`924e216`](https://github.com/Effect-TS/effect-smol/commit/924e216caa7e0bbf22e994a0cd2ce8b1f0f0b3ee), [`80e7f0c`](https://github.com/Effect-TS/effect-smol/commit/80e7f0cd9116e811e97b0ce30a77a8d1ecd072aa), [`f8328bf`](https://github.com/Effect-TS/effect-smol/commit/f8328bf0314da3dc7f31d314f94a5840e8d5217f), [`66d1c06`](https://github.com/Effect-TS/effect-smol/commit/66d1c06039079129707a230f7ad8c676439d7133), [`bee800b`](https://github.com/Effect-TS/effect-smol/commit/bee800bf285192a01bec72a7b7b51bc1159434e6), [`8930441`](https://github.com/Effect-TS/effect-smol/commit/8930441dee6f94c59c583d18d3ebd677cf1f2623)]:
|
||||
- effect@4.0.0-beta.42
|
||||
|
||||
## 4.0.0-beta.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`36f5c21`](https://github.com/Effect-TS/effect-smol/commit/36f5c2174d31ab42c4598bf81f178f40d0802283), [`d8ce758`](https://github.com/Effect-TS/effect-smol/commit/d8ce758669d6297ae932ac3251d83e7b49b22f30), [`11aab4c`](https://github.com/Effect-TS/effect-smol/commit/11aab4c6d37d5691adafc2d33da1a631b28ce814), [`3bc1efb`](https://github.com/Effect-TS/effect-smol/commit/3bc1efb53dd75b4a40de46f1f80c7f8a7d50af86), [`70e724e`](https://github.com/Effect-TS/effect-smol/commit/70e724e604604d4be1061cd8da0d360494998c84), [`738dee7`](https://github.com/Effect-TS/effect-smol/commit/738dee7edfd70af82dc4d2376db3a8ebe603eb48), [`2111963`](https://github.com/Effect-TS/effect-smol/commit/2111963f19b4c28c800664a8fac9590c1321885f), [`198a553`](https://github.com/Effect-TS/effect-smol/commit/198a553d9ce45f6a00bfc4d65ed0640669602d95)]:
|
||||
- effect@4.0.0-beta.41
|
||||
|
||||
## 4.0.0-beta.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f62860f`](https://github.com/Effect-TS/effect-smol/commit/f62860f0e5e45978fabf7256ae620a13152a772a), [`973f281`](https://github.com/Effect-TS/effect-smol/commit/973f2812529aadc1cc54598b2039799fa72b80f8)]:
|
||||
- effect@4.0.0-beta.40
|
||||
|
||||
## 4.0.0-beta.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f91fd3d`](https://github.com/Effect-TS/effect-smol/commit/f91fd3db39fe5628439fd175fba201a65a1aa9d0), [`edaae9d`](https://github.com/Effect-TS/effect-smol/commit/edaae9d65f464f941d7eddd723cd33d324f4b071), [`b47db0b`](https://github.com/Effect-TS/effect-smol/commit/b47db0bd5802064b6a24b3ea27c6ff2e0520d513), [`82d3c8e`](https://github.com/Effect-TS/effect-smol/commit/82d3c8e4f3f49b00df611b25aa6f8f74ec21b59b), [`7c22b31`](https://github.com/Effect-TS/effect-smol/commit/7c22b315d198dcbf44ae8cdb8b37879e1c9e3996)]:
|
||||
- effect@4.0.0-beta.39
|
||||
|
||||
## 4.0.0-beta.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f4dbe5b`](https://github.com/Effect-TS/effect-smol/commit/f4dbe5b26b9c2d33fae024bf44afbdf8541792cd), [`a71a607`](https://github.com/Effect-TS/effect-smol/commit/a71a607c89fb6669a12a562c2c23be81dfbe1adb), [`66a0494`](https://github.com/Effect-TS/effect-smol/commit/66a0494ed75cd12f2721dcbb1d8a072e3d9e14b6), [`5ef7218`](https://github.com/Effect-TS/effect-smol/commit/5ef7218fc559d57301fe929b8a0cab4033f4f1fd), [`472d260`](https://github.com/Effect-TS/effect-smol/commit/472d260655bc311fba5c2c6e23bb77d8f7e36ba0)]:
|
||||
- effect@4.0.0-beta.38
|
||||
|
||||
## 4.0.0-beta.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f7a0b71`](https://github.com/Effect-TS/effect-smol/commit/f7a0b711da8fdd645597dee29cacc5619c6afcf2), [`1e223c3`](https://github.com/Effect-TS/effect-smol/commit/1e223c30ccf835dfbb21284535d78549efaeca80), [`53740f4`](https://github.com/Effect-TS/effect-smol/commit/53740f47aa76d114b7d535649fb50efc54a09608), [`8c7cf89`](https://github.com/Effect-TS/effect-smol/commit/8c7cf89f719e580cbce1bf6c24e6996f1992a0a6), [`b6b81a9`](https://github.com/Effect-TS/effect-smol/commit/b6b81a940eaafcbc792d25413d6c02c707de31b2), [`8f4c1f9`](https://github.com/Effect-TS/effect-smol/commit/8f4c1f97ed60f8810b0b327b50117ffb2d8260d4), [`f2479f9`](https://github.com/Effect-TS/effect-smol/commit/f2479f9d3113b1f012db17a3852b4e28f478cf9c), [`c919921`](https://github.com/Effect-TS/effect-smol/commit/c9199217fad65529421d2cf95ecfff41257090fd), [`7af90c2`](https://github.com/Effect-TS/effect-smol/commit/7af90c2e3c99038eafa39650433839523790e2fe), [`f3be185`](https://github.com/Effect-TS/effect-smol/commit/f3be18569e5ca57c25eabf00df3ca601ebab43c7)]:
|
||||
- effect@4.0.0-beta.37
|
||||
|
||||
## 4.0.0-beta.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`60fcbcc`](https://github.com/Effect-TS/effect-smol/commit/60fcbcc43d09471e8f7e0969955d99dcefc5be81), [`0a60837`](https://github.com/Effect-TS/effect-smol/commit/0a6083713124440e630030375bab367e8d7df24e), [`49164d2`](https://github.com/Effect-TS/effect-smol/commit/49164d2c20a8d21b66514992c4a15d8521f6b36e), [`334b6e4`](https://github.com/Effect-TS/effect-smol/commit/334b6e4f76fe11941b516d61f57e268bc31f0ca6), [`5700695`](https://github.com/Effect-TS/effect-smol/commit/5700695f76ae6da6b94c9c87d4dd2b8054fb829b), [`f8f4456`](https://github.com/Effect-TS/effect-smol/commit/f8f445644f3aa7ec093cab7445198a62ba18a480), [`969d24f`](https://github.com/Effect-TS/effect-smol/commit/969d24fdfa48c4838e811983848d9cb4e9b3b12c), [`851eda0`](https://github.com/Effect-TS/effect-smol/commit/851eda0533946e39bacaaf581896320d7a4f3e8c), [`8059c1c`](https://github.com/Effect-TS/effect-smol/commit/8059c1c3eba9a90af7cd889ea261bcb8fff0c185), [`6f83295`](https://github.com/Effect-TS/effect-smol/commit/6f8329546a73eaddc7cb5e85ea8e37e73fbfb611), [`65f7f57`](https://github.com/Effect-TS/effect-smol/commit/65f7f5737575fed668987462c96d29a446707c32), [`e7fabd2`](https://github.com/Effect-TS/effect-smol/commit/e7fabd2265db690eae5cfc9b83730c84699aef61), [`89c3e98`](https://github.com/Effect-TS/effect-smol/commit/89c3e985401eb38f33a3ae21a94ad27de3c1d28b), [`53794ab`](https://github.com/Effect-TS/effect-smol/commit/53794ab7af30aa5c5004ecf53659fafbe4b10542)]:
|
||||
- effect@4.0.0-beta.36
|
||||
|
||||
## 4.0.0-beta.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9252b43`](https://github.com/Effect-TS/effect-smol/commit/9252b43560f507709c2985abcf52a7837b23ddf8), [`7daf387`](https://github.com/Effect-TS/effect-smol/commit/7daf3870a656882a488a60f67881e6808c8f4d04), [`e1664a3`](https://github.com/Effect-TS/effect-smol/commit/e1664a38bc31ef4ceb4e9324c7226e1e99bf9c07), [`fdaa6e0`](https://github.com/Effect-TS/effect-smol/commit/fdaa6e0a41b6b6605438fa8557441792135380a2), [`19aa47e`](https://github.com/Effect-TS/effect-smol/commit/19aa47ef7b470e427620edca8970dd9cdd551216), [`c667dad`](https://github.com/Effect-TS/effect-smol/commit/c667dad07777b860e4764a3ba9a6cc41c236cd98), [`764d150`](https://github.com/Effect-TS/effect-smol/commit/764d1501bc5026b60fc8aef6cb02a5a87c762801), [`3c27098`](https://github.com/Effect-TS/effect-smol/commit/3c27098b5685a63db2c2eff654a250c94d3fcfa7)]:
|
||||
- effect@4.0.0-beta.35
|
||||
|
||||
## 4.0.0-beta.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f2f75ee`](https://github.com/Effect-TS/effect-smol/commit/f2f75ee564bce1cd95f5189c7bdeeed4f92dacb1), [`342fc4b`](https://github.com/Effect-TS/effect-smol/commit/342fc4b051739e32e7977159f26ff9541eda664f), [`5d704ee`](https://github.com/Effect-TS/effect-smol/commit/5d704ee10d20e8eb107e34bb8a21feb5aa4a7685), [`00add69`](https://github.com/Effect-TS/effect-smol/commit/00add69b59551e9df34772eb927638b093f6d71e), [`58217d3`](https://github.com/Effect-TS/effect-smol/commit/58217d318a7d716ccd707cce0f41573946939c28), [`f4e2aba`](https://github.com/Effect-TS/effect-smol/commit/f4e2aba01b76d1e3059b297e3cc942284dfeafb2), [`e3b44b6`](https://github.com/Effect-TS/effect-smol/commit/e3b44b6a2af9ee21dc5c1e928f0c20af857fa7a9), [`e1472b7`](https://github.com/Effect-TS/effect-smol/commit/e1472b7525c5d57a48bdec2353c3b742f7f916c0), [`7686320`](https://github.com/Effect-TS/effect-smol/commit/7686320cd123fa352b5c3d076fb18a3cac0a9bba)]:
|
||||
- effect@4.0.0-beta.34
|
||||
|
||||
## 4.0.0-beta.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`571447d`](https://github.com/Effect-TS/effect-smol/commit/571447da67334449f8ae3d6ecb3d77ea4e0c4295)]:
|
||||
- effect@4.0.0-beta.33
|
||||
|
||||
## 4.0.0-beta.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf8fff8`](https://github.com/Effect-TS/effect-smol/commit/bf8fff8a5f54b6df74cb7bbb42346fe9ba52435a), [`1af3ef3`](https://github.com/Effect-TS/effect-smol/commit/1af3ef3e3ca7fd417d0fc15f8ca8fe207eba4f74), [`27fea0f`](https://github.com/Effect-TS/effect-smol/commit/27fea0f66910de5905f40fd63f8ddbb6f7ac5aba), [`2ad6c1b`](https://github.com/Effect-TS/effect-smol/commit/2ad6c1b2c85a3a0fe351e3d56636a75eb76b4b4e), [`398ac3e`](https://github.com/Effect-TS/effect-smol/commit/398ac3e01cb75efce0e4e2913d1450cf65866732), [`51fe22f`](https://github.com/Effect-TS/effect-smol/commit/51fe22f3266e417b6c541aaed4b75d246fac91e7), [`4605db6`](https://github.com/Effect-TS/effect-smol/commit/4605db69cfacddbdbf1525865ddfde135158090c), [`f4de1b0`](https://github.com/Effect-TS/effect-smol/commit/f4de1b087c998d0bad1d9468f70b7d16c13b9f6f), [`60214f2`](https://github.com/Effect-TS/effect-smol/commit/60214f2080b2aeb091f691140eb20acb741691c3), [`c4b8b0f`](https://github.com/Effect-TS/effect-smol/commit/c4b8b0ffa8efb47c4cd7578a8943d6868509373f), [`6d9393a`](https://github.com/Effect-TS/effect-smol/commit/6d9393a0770a18722d23340e77f15455de341245), [`6de4efe`](https://github.com/Effect-TS/effect-smol/commit/6de4efe463c783614ceb0c094d77a336a899cbe0), [`4f969d1`](https://github.com/Effect-TS/effect-smol/commit/4f969d1563ba755ffa116c8ae409bb3436bd881d), [`6cc67c8`](https://github.com/Effect-TS/effect-smol/commit/6cc67c855e054ee3f3ac3485dca5f7805e79e8fb), [`8531a22`](https://github.com/Effect-TS/effect-smol/commit/8531a22ffbb52e11a030b09f358cafbfdf5edff7), [`b226760`](https://github.com/Effect-TS/effect-smol/commit/b22676067617f15c00722a3a63fd7c2c172c3d45), [`47a51ab`](https://github.com/Effect-TS/effect-smol/commit/47a51aba0ecdf3ef478bfa28a498bca188399bd4), [`1521d02`](https://github.com/Effect-TS/effect-smol/commit/1521d02e1f19f1d795edaaf862c1a1031d9c755e)]:
|
||||
- effect@4.0.0-beta.32
|
||||
|
||||
## 4.0.0-beta.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6f23f0e`](https://github.com/Effect-TS/effect-smol/commit/6f23f0ed4cba573cd9395c2e582f582fe7271544), [`654aaec`](https://github.com/Effect-TS/effect-smol/commit/654aaec593305521b65dd042c204d761cc6e8c28), [`2958a42`](https://github.com/Effect-TS/effect-smol/commit/2958a42078966a8713a98f00485ab36484d5eccf), [`95d27a2`](https://github.com/Effect-TS/effect-smol/commit/95d27a239ed5147302605ab0b3147a056541b0c7), [`0fbaea8`](https://github.com/Effect-TS/effect-smol/commit/0fbaea8f9555a8044cec31a770394db613fc78e2), [`21d5d5e`](https://github.com/Effect-TS/effect-smol/commit/21d5d5e0439fd4d9bb6e508377215b1087555d45), [`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6e49959`](https://github.com/Effect-TS/effect-smol/commit/6e499590357a104c81779b3176cd3f84e4f91064), [`8f5805d`](https://github.com/Effect-TS/effect-smol/commit/8f5805dbdd0d1bc0ff0727cc398c8d80e544edee), [`990df2c`](https://github.com/Effect-TS/effect-smol/commit/990df2c3ceeb32e659acc10cc9485617f7b3c423)]:
|
||||
- effect@4.0.0-beta.31
|
||||
|
||||
## 4.0.0-beta.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c88e5b7`](https://github.com/Effect-TS/effect-smol/commit/c88e5b723ff09da4edaef6ce14d927ca01104a32), [`947d0e4`](https://github.com/Effect-TS/effect-smol/commit/947d0e4268ba5c4020ead380aa80812c7342408f), [`7517908`](https://github.com/Effect-TS/effect-smol/commit/75179085d159b88a1ab0bce70669d76dcf0d79a4), [`a49ecd5`](https://github.com/Effect-TS/effect-smol/commit/a49ecd5a183d7e7d33f47ff95e9d2dea5a12ead5), [`6993e33`](https://github.com/Effect-TS/effect-smol/commit/6993e3329122c834c20bacea72d8678232f4f103), [`514f2a2`](https://github.com/Effect-TS/effect-smol/commit/514f2a2ae54580fcacdbe2ea2196a83a852d0748), [`3214b47`](https://github.com/Effect-TS/effect-smol/commit/3214b47676de2d33fddc5fecfc2d226e6e83cc7b), [`95ec5ed`](https://github.com/Effect-TS/effect-smol/commit/95ec5ed345de77c893049e182d37a37cf164a268)]:
|
||||
- effect@4.0.0-beta.30
|
||||
|
||||
## 4.0.0-beta.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9d93adb`](https://github.com/Effect-TS/effect-smol/commit/9d93adb1c1795d1978391b30d7d2972c88052662), [`b52721c`](https://github.com/Effect-TS/effect-smol/commit/b52721cf0d11a567722b060c8536e3bdd4161f07), [`a891c7b`](https://github.com/Effect-TS/effect-smol/commit/a891c7b12f415b2287613dd4b91a09dfd38ef30d), [`ef26cdf`](https://github.com/Effect-TS/effect-smol/commit/ef26cdfb65d9955fc7e161629191930c2cc2c63f), [`82fd3ed`](https://github.com/Effect-TS/effect-smol/commit/82fd3ed922063ee5a34f96f3993c15c7515e4f67)]:
|
||||
- effect@4.0.0-beta.29
|
||||
|
||||
## 4.0.0-beta.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ff533f2`](https://github.com/Effect-TS/effect-smol/commit/ff533f203cd06302ad08032a27e01269b4a2d4c6), [`dc803ee`](https://github.com/Effect-TS/effect-smol/commit/dc803ee52ebd3e9f931118f0dfcb804542847556), [`d660b1c`](https://github.com/Effect-TS/effect-smol/commit/d660b1c99cb93d4f79715e91c7a4486801c0eefa), [`93a05e3`](https://github.com/Effect-TS/effect-smol/commit/93a05e3eaa624058b162aedd66aad70102837270), [`2a65cf6`](https://github.com/Effect-TS/effect-smol/commit/2a65cf6fd81ef63d944e6fb51f058d439bf4a834), [`a561a40`](https://github.com/Effect-TS/effect-smol/commit/a561a40cc41c548c2cf3153aca065ee92ee8aa57), [`29cd24d`](https://github.com/Effect-TS/effect-smol/commit/29cd24d1fe78480a72eeb38a90281ffddc0530bc), [`662a8e6`](https://github.com/Effect-TS/effect-smol/commit/662a8e6857dac64a7cd13bd8df4b0674654622f8), [`d2b52ba`](https://github.com/Effect-TS/effect-smol/commit/d2b52bae5b9336cf59729fbdcc4d7f09512b0cbf), [`407c3b4`](https://github.com/Effect-TS/effect-smol/commit/407c3b43a5d1414558e0e33b6f1fc0e6a6d489cc), [`42bc7ce`](https://github.com/Effect-TS/effect-smol/commit/42bc7ce5480f6f2953c39f8cb5c850d61df6f5a2), [`e741322`](https://github.com/Effect-TS/effect-smol/commit/e74132226cbfee24234311c7c1c13e6b7391384e), [`5c75fa8`](https://github.com/Effect-TS/effect-smol/commit/5c75fa8fb71163bc4c035ba1a215574dfd4badfc), [`747177b`](https://github.com/Effect-TS/effect-smol/commit/747177b0602f12d4461a843e953dfdffbeb0a429), [`326cd48`](https://github.com/Effect-TS/effect-smol/commit/326cd4828bce573fe985f35152155464bf4c5a70), [`627e922`](https://github.com/Effect-TS/effect-smol/commit/627e922b8d1e9521eae5e1caa5d667ad00b1619a), [`662287e`](https://github.com/Effect-TS/effect-smol/commit/662287e9abc76c941ccc2ee330aa07904d571341)]:
|
||||
- effect@4.0.0-beta.28
|
||||
|
||||
## 4.0.0-beta.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`903a839`](https://github.com/Effect-TS/effect-smol/commit/903a839e94239e6ec4568315af28e405bcad95f4), [`91a0168`](https://github.com/Effect-TS/effect-smol/commit/91a016836680a6669308ecf464d3584bcc4ae1b7), [`c890f9a`](https://github.com/Effect-TS/effect-smol/commit/c890f9a1b3a989ed22528bd5a43326342e05b142), [`1e985f2`](https://github.com/Effect-TS/effect-smol/commit/1e985f237d250b51b91de22dde77160c1e778ce7)]:
|
||||
- effect@4.0.0-beta.27
|
||||
|
||||
## 4.0.0-beta.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fb21462`](https://github.com/Effect-TS/effect-smol/commit/fb21462642cdd5b1bada92f3eba18ae20445be42), [`2ed26b1`](https://github.com/Effect-TS/effect-smol/commit/2ed26b139805700e3df39efaa768ff01565e5c86), [`e832a57`](https://github.com/Effect-TS/effect-smol/commit/e832a57b570fe38f010c1fd99bceac5a325a9e07), [`7f01be7`](https://github.com/Effect-TS/effect-smol/commit/7f01be7f8db363d4b2e88e6b5571e96bb815786f), [`e965143`](https://github.com/Effect-TS/effect-smol/commit/e9651431e114479e6becf8ca7b1ed99ac7e91ccc), [`b9b80f1`](https://github.com/Effect-TS/effect-smol/commit/b9b80f1f15e152ceef0a727d150b7dc230abae99), [`98252aa`](https://github.com/Effect-TS/effect-smol/commit/98252aa0c0b17fc73fbdad65d0a1104965f9fc0f), [`56fbd94`](https://github.com/Effect-TS/effect-smol/commit/56fbd94311ad19a05001ad649d9e34ab00c74541), [`3faa109`](https://github.com/Effect-TS/effect-smol/commit/3faa109b7d093fbf14ad410d3e11d663f16e28f1), [`692ecfe`](https://github.com/Effect-TS/effect-smol/commit/692ecfed99fe58056b7a5afe001f4fcd1a61c446), [`1e70b72`](https://github.com/Effect-TS/effect-smol/commit/1e70b72d0b210474d0e96a15a5cfc279eae37e0c), [`ecf0782`](https://github.com/Effect-TS/effect-smol/commit/ecf07829ef2dfc01d8943c96c4fe9c1b44b97926)]:
|
||||
- effect@4.0.0-beta.26
|
||||
|
||||
## 4.0.0-beta.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fa17bb5`](https://github.com/Effect-TS/effect-smol/commit/fa17bb5be9f2533d01e11322b14804c7dec43714), [`f46e5b5`](https://github.com/Effect-TS/effect-smol/commit/f46e5b5ca2a918ee4d9270167e79db223077c96f), [`ce4767c`](https://github.com/Effect-TS/effect-smol/commit/ce4767cadcacc6ce8ff4c3a0d0fbc82ede655f63), [`c830a8b`](https://github.com/Effect-TS/effect-smol/commit/c830a8b6c292a6528d7f9318759d34800b00372d)]:
|
||||
- effect@4.0.0-beta.25
|
||||
|
||||
## 4.0.0-beta.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a909e1c`](https://github.com/Effect-TS/effect-smol/commit/a909e1c1ac2bc707527f5073776e3e7d239688d9), [`8814a4e`](https://github.com/Effect-TS/effect-smol/commit/8814a4ef78d67144d27689370af10099ea210399), [`3f942c5`](https://github.com/Effect-TS/effect-smol/commit/3f942c51cefa7b2ffa7c49e8c8a2c887570ba4c0), [`774ed59`](https://github.com/Effect-TS/effect-smol/commit/774ed59c52b2ab578bbb897c4f551f812231e1d2), [`f54b8d3`](https://github.com/Effect-TS/effect-smol/commit/f54b8d398fedad1815fd1f4c49814ab938cfc385)]:
|
||||
- effect@4.0.0-beta.24
|
||||
|
||||
## 4.0.0-beta.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c73c41`](https://github.com/Effect-TS/effect-smol/commit/5c73c41b69eaeab80fcd62c9bfda490b446d1966)]:
|
||||
- effect@4.0.0-beta.23
|
||||
|
||||
## 4.0.0-beta.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0874332`](https://github.com/Effect-TS/effect-smol/commit/0874332f7c81118b06ac2eb105e0710211631479), [`c592dcd`](https://github.com/Effect-TS/effect-smol/commit/c592dcde0697e322065c8f418c0480ef910cb183), [`1dbe28d`](https://github.com/Effect-TS/effect-smol/commit/1dbe28dac8299cd3e218c9768450cfd173b5e294), [`564d730`](https://github.com/Effect-TS/effect-smol/commit/564d730b6bbf38dd8548a3b046e7a693b28699a4), [`3cfadc4`](https://github.com/Effect-TS/effect-smol/commit/3cfadc458b070c6cba6c5674b72a059f1e49118b), [`6634fd0`](https://github.com/Effect-TS/effect-smol/commit/6634fd07da067d80b8261fb2959d1a952b9e412e), [`d10dabe`](https://github.com/Effect-TS/effect-smol/commit/d10dabeb7af9a368f995829cd36ad08167cd8f95), [`f82f549`](https://github.com/Effect-TS/effect-smol/commit/f82f549a09e950e9d4987f279a800f4d953f0939), [`78a3382`](https://github.com/Effect-TS/effect-smol/commit/78a3382ddfbe034408f7480fa794733d9e82147b)]:
|
||||
- effect@4.0.0-beta.22
|
||||
|
||||
## 4.0.0-beta.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e691909`](https://github.com/Effect-TS/effect-smol/commit/e691909495ccb162ea7bfa351dd74632b99997cb), [`d5f413f`](https://github.com/Effect-TS/effect-smol/commit/d5f413f3c8fc57f2413cc5649c2003d6d4e5a6d7), [`139d152`](https://github.com/Effect-TS/effect-smol/commit/139d152941e562a073b5be12e8d66c8a4d4a8a57), [`947e3d4`](https://github.com/Effect-TS/effect-smol/commit/947e3d436ab8a017efda9b29be523efd1ca8df28), [`84b2cce`](https://github.com/Effect-TS/effect-smol/commit/84b2ccefe2aa3a7413b86738a4dc33cdb311ca55), [`7f5305e`](https://github.com/Effect-TS/effect-smol/commit/7f5305e69f5a33309e77b08a576edb25d7daaee2), [`9e6fd84`](https://github.com/Effect-TS/effect-smol/commit/9e6fd8471c93a3c643929151a3bdb62cb9c0ca0e), [`fdb8a4b`](https://github.com/Effect-TS/effect-smol/commit/fdb8a4b172721fbefe98bd5aa6fe4f0efd1da3eb), [`0f986ef`](https://github.com/Effect-TS/effect-smol/commit/0f986ef22f196fe091a7afdbd179485a7d888882), [`9355fc0`](https://github.com/Effect-TS/effect-smol/commit/9355fc0ffb5b7382146a5aed9eea83974b10d007)]:
|
||||
- effect@4.0.0-beta.21
|
||||
|
||||
## 4.0.0-beta.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`842a624`](https://github.com/Effect-TS/effect-smol/commit/842a624f79d5e1407460b0ef3ab27d14d48ccf74), [`4785eef`](https://github.com/Effect-TS/effect-smol/commit/4785eef5d7cf1edb96ef2509aed2ba4d1edf3862), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`12ee8e2`](https://github.com/Effect-TS/effect-smol/commit/12ee8e27df7eb393d83a5e403390d0cfc82ca732), [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34), [`989d1cc`](https://github.com/Effect-TS/effect-smol/commit/989d1cca936fce0cc459057825ba40e3f5ef3827)]:
|
||||
- effect@4.0.0-beta.20
|
||||
|
||||
## 4.0.0-beta.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.19
|
||||
|
||||
## 4.0.0-beta.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`01e31fd`](https://github.com/Effect-TS/effect-smol/commit/01e31fdf8e5206849d23cbafd23a346f2f177ab8), [`0890aab`](https://github.com/Effect-TS/effect-smol/commit/0890aab15ed9c5ba52c383a72fdc6a444d7504d5), [`725260b`](https://github.com/Effect-TS/effect-smol/commit/725260b53f5142d6af7a93a2f9f464f974eda92d)]:
|
||||
- effect@4.0.0-beta.18
|
||||
|
||||
## 4.0.0-beta.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8f59c32`](https://github.com/Effect-TS/effect-smol/commit/8f59c32922597a48392744f7203e284866747781)]:
|
||||
- effect@4.0.0-beta.17
|
||||
|
||||
## 4.0.0-beta.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf9096c`](https://github.com/Effect-TS/effect-smol/commit/bf9096c52a7d8791d93d232739e523eb84f6625a), [`29f81ca`](https://github.com/Effect-TS/effect-smol/commit/29f81ca07c67dba265804b140a7487fb15a5fc6b), [`68eb28c`](https://github.com/Effect-TS/effect-smol/commit/68eb28c2b0fc67a9f6204ade9bd16c5b37803bfb)]:
|
||||
- effect@4.0.0-beta.16
|
||||
|
||||
## 4.0.0-beta.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`24ae609`](https://github.com/Effect-TS/effect-smol/commit/24ae60995d2fd7d621be356cdfdfd328c79639ba), [`0e3c059`](https://github.com/Effect-TS/effect-smol/commit/0e3c059987caa55ebd0c134f7c7b147c639c328e), [`e843b0a`](https://github.com/Effect-TS/effect-smol/commit/e843b0a7d7e7b600a0b3bd477f24e2e4cd26bc8b), [`f4389a2`](https://github.com/Effect-TS/effect-smol/commit/f4389a2cca3c5bbf00d69779f52ce41255f15a28), [`5b73de0`](https://github.com/Effect-TS/effect-smol/commit/5b73de095b3402d0c5c74092ace6ce18ebfad566), [`595d2d6`](https://github.com/Effect-TS/effect-smol/commit/595d2d6e7d50419f3532bd39266191532ace38f2)]:
|
||||
- effect@4.0.0-beta.15
|
||||
|
||||
## 4.0.0-beta.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c414700`](https://github.com/Effect-TS/effect-smol/commit/c414700ef1932e4b67d0102856de417336912350), [`a30c969`](https://github.com/Effect-TS/effect-smol/commit/a30c9699c0d736cf3952041e45d508b7d58907a9)]:
|
||||
- effect@4.0.0-beta.14
|
||||
|
||||
## 4.0.0-beta.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`368f4c3`](https://github.com/Effect-TS/effect-smol/commit/368f4c363dd117e6f5a19ad77b161176cfd29fdd), [`db8a579`](https://github.com/Effect-TS/effect-smol/commit/db8a579e93e93ff73b1e60712732e03b597b916b), [`668b703`](https://github.com/Effect-TS/effect-smol/commit/668b70337e9ddbb0d1ae2282a95c282ce404e562), [`d40e76b`](https://github.com/Effect-TS/effect-smol/commit/d40e76b973543979e60e04a6baca04a8c65bdfc2), [`6e18cf8`](https://github.com/Effect-TS/effect-smol/commit/6e18cf883e9905ca718a6697b6a2a4bbd42739aa), [`86062e8`](https://github.com/Effect-TS/effect-smol/commit/86062e8a0c61bca5412fc40d2cf151d676901f08), [`c27ce75`](https://github.com/Effect-TS/effect-smol/commit/c27ce75d34c74dcfc6dba1bf77f1ce88f410a0de), [`e2d4fbf`](https://github.com/Effect-TS/effect-smol/commit/e2d4fbfeeda6a5d2a4c5aeb0501d8240c248b9eb), [`114ab42`](https://github.com/Effect-TS/effect-smol/commit/114ab42ad0edc590d29169675a493e0e915aa58f), [`484caec`](https://github.com/Effect-TS/effect-smol/commit/484caec47cccac8b86db2910742e406dfc7173ab)]:
|
||||
- effect@4.0.0-beta.13
|
||||
|
||||
## 4.0.0-beta.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70a74e8`](https://github.com/Effect-TS/effect-smol/commit/70a74e88a8767c9d4acdb9e5f25aec9a33588d07), [`b5b6e10`](https://github.com/Effect-TS/effect-smol/commit/b5b6e10621d54bf8c9857fec0d647ced78ecd857), [`f5ce5a9`](https://github.com/Effect-TS/effect-smol/commit/f5ce5a915359c6ebf254079e1da23cab6cde34fb), [`a29eb70`](https://github.com/Effect-TS/effect-smol/commit/a29eb702ffe3fc58bd28c4d7857298cd65d73668), [`c7b36e5`](https://github.com/Effect-TS/effect-smol/commit/c7b36e541a23e9a00f64e25b23851e51a37dfce5), [`9381d6d`](https://github.com/Effect-TS/effect-smol/commit/9381d6d4d9d819a81a46e56d0364c76e92a4fbca), [`88439f1`](https://github.com/Effect-TS/effect-smol/commit/88439f13ca13549f3e4822c48c4f019c14fc2bcc), [`e35307d`](https://github.com/Effect-TS/effect-smol/commit/e35307dbeb8eb26a9923f958b894a8eaaf259bf2), [`c7df4bc`](https://github.com/Effect-TS/effect-smol/commit/c7df4bce34009474c63d62a807abfdafb76971eb), [`accaf3b`](https://github.com/Effect-TS/effect-smol/commit/accaf3be7ac8da36e2334c509c23b8c9e88ea160), [`3e1c270`](https://github.com/Effect-TS/effect-smol/commit/3e1c2707bbdf67720af1509642b8ced195790882), [`6cd81f7`](https://github.com/Effect-TS/effect-smol/commit/6cd81f73baad86f5bbfa455a55d75cde71e9611a), [`f222da3`](https://github.com/Effect-TS/effect-smol/commit/f222da3cdb44554f3324c2c52d0d005ee575053e), [`61f901d`](https://github.com/Effect-TS/effect-smol/commit/61f901d830005b66e22d1de889fda132aeea97cd)]:
|
||||
- effect@4.0.0-beta.12
|
||||
|
||||
## 4.0.0-beta.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`88659ed`](https://github.com/Effect-TS/effect-smol/commit/88659edb26e3623d557dccfe914c2c949672da16), [`f2915e8`](https://github.com/Effect-TS/effect-smol/commit/f2915e8e2efe80d50c281e53f297b9701d6dc199), [`eb71ace`](https://github.com/Effect-TS/effect-smol/commit/eb71acebbe0f228e4920278013beee3b67d62310), [`2a16999`](https://github.com/Effect-TS/effect-smol/commit/2a169996c7513d377ac47adbfd68e1490457135c), [`d42dd52`](https://github.com/Effect-TS/effect-smol/commit/d42dd52f11203f8e749fb5d3ecf7153e4a5a6814), [`339adaf`](https://github.com/Effect-TS/effect-smol/commit/339adaf850a62a892adebcb208c2d9dddf3b97b3), [`de19645`](https://github.com/Effect-TS/effect-smol/commit/de1964526d01102dd1cb99c8cfdd3e8df1f49ef1), [`9b1dc3b`](https://github.com/Effect-TS/effect-smol/commit/9b1dc3bcf2a1b68d0a67e3465db5ad01a1a56997), [`e4cb2f5`](https://github.com/Effect-TS/effect-smol/commit/e4cb2f55b30f4771ec1bf613ced36d6d96464dd5), [`8bced95`](https://github.com/Effect-TS/effect-smol/commit/8bced954ecb35d4489197a57b0efe927e7d75f49), [`9431420`](https://github.com/Effect-TS/effect-smol/commit/94314207c8019918200fbcb97aec992219f801f0), [`948dca2`](https://github.com/Effect-TS/effect-smol/commit/948dca22e4f672ba7a6db57f9899272bec7c08b8), [`d18e327`](https://github.com/Effect-TS/effect-smol/commit/d18e32765a2665e31ffb31e746bf983fcfac34c5), [`ab512f7`](https://github.com/Effect-TS/effect-smol/commit/ab512f7be1c0e6b359da921e22cd4944e4c57d3e)]:
|
||||
- effect@4.0.0-beta.11
|
||||
|
||||
## 4.0.0-beta.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`371acab`](https://github.com/Effect-TS/effect-smol/commit/371acabb58d56f3a7a5e3e33d3d5fdc9f5573c74), [`856d774`](https://github.com/Effect-TS/effect-smol/commit/856d7741f1e296dd5048c6ff2b44b95d023e6ae4), [`b9e9202`](https://github.com/Effect-TS/effect-smol/commit/b9e92023c38caa322975d77cfe83e2d34ac9305a), [`1d1a974`](https://github.com/Effect-TS/effect-smol/commit/1d1a974bd280c81bff5d4505491cda03ba7a3f36), [`6bfe2a6`](https://github.com/Effect-TS/effect-smol/commit/6bfe2a659bc6335db75709931f405da45301cba2), [`b12c811`](https://github.com/Effect-TS/effect-smol/commit/b12c81157be287b1649c210616a244b50ec094d2), [`d17d98a`](https://github.com/Effect-TS/effect-smol/commit/d17d98ad78e2b44d95ef434adab79ac3c35e75ab), [`68c3c7c`](https://github.com/Effect-TS/effect-smol/commit/68c3c7cb1e06ed94fa5c4c123a234b4ccbfdecd8)]:
|
||||
- effect@4.0.0-beta.10
|
||||
|
||||
## 4.0.0-beta.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3386557`](https://github.com/Effect-TS/effect-smol/commit/338655731564a7be9f8859dedbf4d5bcac6eb350), [`b6666e3`](https://github.com/Effect-TS/effect-smol/commit/b6666e3cf6bd44ba1a8704e65c256c30359cb422)]:
|
||||
- effect@4.0.0-beta.9
|
||||
|
||||
## 4.0.0-beta.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`246e672`](https://github.com/Effect-TS/effect-smol/commit/246e672dbbd7848d60e0c78fd66671b2f10b3752), [`807dec0`](https://github.com/Effect-TS/effect-smol/commit/807dec03801b4c58a6d00c237b6d98d6386911df)]:
|
||||
- effect@4.0.0-beta.8
|
||||
|
||||
## 4.0.0-beta.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a2bda6d`](https://github.com/Effect-TS/effect-smol/commit/a2bda6d4ef6de9d9b0c53ae2df5434f778d6161a), [`1f95a2b`](https://github.com/Effect-TS/effect-smol/commit/1f95a2b5aa9524bb38f4437f4691a664bf463ca1), [`a8d5e79`](https://github.com/Effect-TS/effect-smol/commit/a8d5e792fec201a83af0eb92fc79928d055125fd), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`06d8a03`](https://github.com/Effect-TS/effect-smol/commit/06d8a0391631e6130e3ab25227e59817852e227f), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`f9e883e`](https://github.com/Effect-TS/effect-smol/commit/f9e883e266fbda870336ee62f46b7ac85ba3de6e), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430)]:
|
||||
- effect@4.0.0-beta.7
|
||||
|
||||
## 4.0.0-beta.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3247da2`](https://github.com/Effect-TS/effect-smol/commit/3247da28331f345f68be5dbd2974a7e03d300fe1), [`f205705`](https://github.com/Effect-TS/effect-smol/commit/f2057050dbd034b8c186be2d40c3d03ee63a5a3b), [`f35022c`](https://github.com/Effect-TS/effect-smol/commit/f35022c212e4111527e1bb43f360a67b2b49fa85), [`8622721`](https://github.com/Effect-TS/effect-smol/commit/86227217b02d43680a3c6f3c21731b1d852c91f5), [`fc660ab`](https://github.com/Effect-TS/effect-smol/commit/fc660ab8b5ebae38b8d6b96cbf2f9b880cc09253), [`f37dc33`](https://github.com/Effect-TS/effect-smol/commit/f37dc335f64622fa9ce8d6d1d5dd8fc3f260257b), [`3662f32`](https://github.com/Effect-TS/effect-smol/commit/3662f328fcfa3b2fa01ffa79da40e12e93fcede8), [`a7d436f`](https://github.com/Effect-TS/effect-smol/commit/a7d436f438dcd7f49b9485e4e95a4511f31fad7d), [`6856a41`](https://github.com/Effect-TS/effect-smol/commit/6856a415d7eddd9d73d60919e976f1d071421be4), [`8c417d0`](https://github.com/Effect-TS/effect-smol/commit/8c417d03475e5e12d00dca0c4781d0af7e66b86c), [`5419570`](https://github.com/Effect-TS/effect-smol/commit/5419570ba47ce882a3a10882707b46f66e464906), [`449c5ed`](https://github.com/Effect-TS/effect-smol/commit/449c5ed5318e8a874e730420bcf52918fa2ec80f), [`4b5ec12`](https://github.com/Effect-TS/effect-smol/commit/4b5ec12f87f95f2a3cd8fe4d5b26c6eb0529381a), [`df87937`](https://github.com/Effect-TS/effect-smol/commit/df879375fc3b169c43f9c434b3775e12b80dffe4), [`5dbfca8`](https://github.com/Effect-TS/effect-smol/commit/5dbfca8d1dbb6d18d1605d4f8562e99c86e2ff11), [`e629497`](https://github.com/Effect-TS/effect-smol/commit/e6294973d55597ab6b6deca6babbe1e946b2c91d), [`981c991`](https://github.com/Effect-TS/effect-smol/commit/981c991cd78db34def815d5754379d737157f005), [`1ca2ed6`](https://github.com/Effect-TS/effect-smol/commit/1ca2ed67301a5dc40ae0ed94346b99f26fd22bbe), [`45722bd`](https://github.com/Effect-TS/effect-smol/commit/45722bde974458311f11ad237711363a10ec6894), [`eb2a85e`](https://github.com/Effect-TS/effect-smol/commit/eb2a85ed4dc162b2535d304799333a5a20477fd0)]:
|
||||
- effect@4.0.0-beta.6
|
||||
|
||||
## 4.0.0-beta.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1314](https://github.com/Effect-TS/effect-smol/pull/1314) [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8) Thanks @zeyuri! - Port ReactHydration to effect-smol.
|
||||
|
||||
Add `Hydration` module to `effect/unstable/reactivity` with `dehydrate`, `hydrate`, and `toValues` for SSR state serialization. Add `HydrationBoundary` React component to `@effect/atom-react` with two-phase hydration (new atoms in render, existing atoms after commit).
|
||||
|
||||
- Updated dependencies [[`f6e133e`](https://github.com/Effect-TS/effect-smol/commit/f6e133e9a16b32317bd09ff08c12b97a0ae44600), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8), [`a88e206`](https://github.com/Effect-TS/effect-smol/commit/a88e206e44dc66ca5a2b45bedc797877c5dbb083), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8)]:
|
||||
- effect@4.0.0-beta.5
|
||||
|
||||
## 4.0.0-beta.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c5a18ef`](https://github.com/Effect-TS/effect-smol/commit/c5a18ef44171e3880bf983faee74529908974b32), [`bc6b885`](https://github.com/Effect-TS/effect-smol/commit/bc6b885b94d887a200657c0775dfa874dc15bc0c)]:
|
||||
- effect@4.0.0-beta.4
|
||||
|
||||
## 4.0.0-beta.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a0cf36`](https://github.com/Effect-TS/effect-smol/commit/3a0cf36eff106ba48d74e133c1598cd40613e530), [`c4da328`](https://github.com/Effect-TS/effect-smol/commit/c4da328d32fad1d61e0e538f5d371edf61521d7e)]:
|
||||
- effect@4.0.0-beta.3
|
||||
|
||||
## 4.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a22ce73`](https://github.com/Effect-TS/effect-smol/commit/a22ce73b2bd9305b7ba665694d2255c0e6d5a8d0), [`ebdabf7`](https://github.com/Effect-TS/effect-smol/commit/ebdabf79ff4e62c8384aa8cf9a8d2787d536ee78), [`8f663bb`](https://github.com/Effect-TS/effect-smol/commit/8f663bb121021bf12bd264e8ae385187cb7a5dae)]:
|
||||
- effect@4.0.0-beta.2
|
||||
|
||||
## 4.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0fecf70`](https://github.com/Effect-TS/effect-smol/commit/0fecf70048057623eed7c584a06671773a2b1743), [`709569e`](https://github.com/Effect-TS/effect-smol/commit/709569ed76bead9ebb0670599e4d890a07ca5a43)]:
|
||||
- effect@4.0.0-beta.1
|
||||
|
||||
## 4.0.0-beta.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#1183](https://github.com/Effect-TS/effect-smol/pull/1183) [`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66) Thanks @tim-smart! - v4 beta
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66)]:
|
||||
- effect@4.0.0-beta.0
|
||||
21
repos/effect/packages/atom/react/LICENSE
Normal file
21
repos/effect/packages/atom/react/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023-present The Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
7
repos/effect/packages/atom/react/README.md
Normal file
7
repos/effect/packages/atom/react/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# `@effect/atom-react`
|
||||
|
||||
React bindings for the Effect Atom modules.
|
||||
|
||||
## Documentation
|
||||
|
||||
- **API Reference**: [View the full documentation](https://effect-ts.github.io/effect/docs/atom-react).
|
||||
24
repos/effect/packages/atom/react/docgen.json
Normal file
24
repos/effect/packages/atom/react/docgen.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/@effect/docgen/schema.json",
|
||||
"srcLink": "https://github.com/Effect-TS/effect/tree/main/packages/atom/react/src/",
|
||||
"exclude": ["src/internal/**/*.ts"],
|
||||
"examplesCompilerOptions": {
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "Bundler",
|
||||
"module": "ES2022",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"types": ["node"],
|
||||
"rewriteRelativeImportExtensions": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"paths": {
|
||||
"effect": ["../../../effect/src/index.js"],
|
||||
"effect/*": ["../../../effect/src/*.js"]
|
||||
},
|
||||
"plugins": [
|
||||
{ "name": "@effect/language-service", "includeSuggestionsInTsc": false }
|
||||
]
|
||||
}
|
||||
}
|
||||
78
repos/effect/packages/atom/react/package.json
Normal file
78
repos/effect/packages/atom/react/package.json
Normal file
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"name": "@effect/atom-react",
|
||||
"version": "4.0.0-beta.99",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "React bindings for the Effect Atom modules",
|
||||
"homepage": "https://effect.website",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Effect-TS/effect.git",
|
||||
"directory": "packages/atom/react"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Effect-TS/effect/issues"
|
||||
},
|
||||
"tags": [
|
||||
"typescript",
|
||||
"react",
|
||||
"database"
|
||||
],
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"react",
|
||||
"database"
|
||||
],
|
||||
"sideEffects": [],
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts",
|
||||
"./*": "./src/*.ts",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
},
|
||||
"files": [
|
||||
"src/**/*.ts",
|
||||
"dist/**/*.js",
|
||||
"dist/**/*.js.map",
|
||||
"dist/**/*.d.ts",
|
||||
"dist/**/*.d.ts.map"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"provenance": true,
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./dist/index.js",
|
||||
"./*": "./dist/*.js",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -b tsconfig.json && pnpm babel",
|
||||
"babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
||||
"check": "tsc -b tsconfig.json",
|
||||
"test": "vitest",
|
||||
"coverage": "vitest --coverage"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "workspace:^",
|
||||
"react": "^19.2.4",
|
||||
"scheduler": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@types/react": "^19.2.17",
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"@types/scheduler": "^0.26.0",
|
||||
"effect": "workspace:^",
|
||||
"jsdom": "^29.1.1",
|
||||
"react": "19.2.7",
|
||||
"react-dom": "19.2.7",
|
||||
"react-error-boundary": "^6.1.2",
|
||||
"scheduler": "^0.27.0"
|
||||
}
|
||||
}
|
||||
476
repos/effect/packages/atom/react/src/Hooks.ts
Normal file
476
repos/effect/packages/atom/react/src/Hooks.ts
Normal file
@@ -0,0 +1,476 @@
|
||||
/**
|
||||
* React hooks for working with Effect atoms from components. The hooks read,
|
||||
* write, mount, refresh, and subscribe to atoms from `RegistryContext`, handle
|
||||
* `AsyncResult` atoms with React Suspense, and expose helpers for reading and
|
||||
* deriving `AtomRef` values.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
"use client"
|
||||
|
||||
import * as Cause from "effect/Cause"
|
||||
import * as Effect from "effect/Effect"
|
||||
import * as Exit from "effect/Exit"
|
||||
import type * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
||||
import * as Atom from "effect/unstable/reactivity/Atom"
|
||||
import type * as AtomRef from "effect/unstable/reactivity/AtomRef"
|
||||
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
||||
import * as React from "react"
|
||||
import { RegistryContext } from "./RegistryContext.ts"
|
||||
|
||||
interface AtomStore<A> {
|
||||
readonly subscribe: (f: () => void) => () => void
|
||||
readonly snapshot: () => A
|
||||
readonly getServerSnapshot: () => A
|
||||
}
|
||||
|
||||
const storeRegistry = new WeakMap<AtomRegistry.AtomRegistry, WeakMap<Atom.Atom<any>, AtomStore<any>>>()
|
||||
|
||||
function makeStore<A>(registry: AtomRegistry.AtomRegistry, atom: Atom.Atom<A>): AtomStore<A> {
|
||||
let stores = storeRegistry.get(registry)
|
||||
if (stores === undefined) {
|
||||
stores = new WeakMap()
|
||||
storeRegistry.set(registry, stores)
|
||||
}
|
||||
const store = stores.get(atom)
|
||||
if (store !== undefined) {
|
||||
return store
|
||||
}
|
||||
const newStore: AtomStore<A> = {
|
||||
subscribe(f) {
|
||||
return registry.subscribe(atom, f)
|
||||
},
|
||||
snapshot() {
|
||||
return registry.get(atom)
|
||||
},
|
||||
getServerSnapshot() {
|
||||
return Atom.getServerValue(atom, registry)
|
||||
}
|
||||
}
|
||||
stores.set(atom, newStore)
|
||||
return newStore
|
||||
}
|
||||
|
||||
function useStore<A>(registry: AtomRegistry.AtomRegistry, atom: Atom.Atom<A>): A {
|
||||
const store = makeStore(registry, atom)
|
||||
|
||||
return React.useSyncExternalStore(store.subscribe, store.snapshot, store.getServerSnapshot)
|
||||
}
|
||||
|
||||
const initialValuesSet = new WeakMap<AtomRegistry.AtomRegistry, WeakSet<Atom.Atom<any>>>()
|
||||
|
||||
/**
|
||||
* Seeds initial atom values in the current React atom registry.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to seed atom values from a React component after the current registry
|
||||
* already exists.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* Each atom is initialized at most once for a given registry by this hook, so
|
||||
* later calls for the same atom in that registry are ignored.
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomInitialValues = (initialValues: Iterable<readonly [Atom.Atom<any>, any]>): void => {
|
||||
const registry = React.useContext(RegistryContext)
|
||||
let set = initialValuesSet.get(registry)
|
||||
if (set === undefined) {
|
||||
set = new WeakSet()
|
||||
initialValuesSet.set(registry, set)
|
||||
}
|
||||
for (const [atom, value] of initialValues) {
|
||||
if (!set.has(atom)) {
|
||||
set.add(atom)
|
||||
;(registry as any).ensureNode(atom).setValue(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes to an atom in the current React registry and returns its current
|
||||
* value, optionally mapped through a selector.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a React component needs to render from an atom value without also
|
||||
* returning a setter.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* When a selector is provided, the hook maps the atom before subscribing so the
|
||||
* component reads the selected value from the current `RegistryContext`.
|
||||
*
|
||||
* @see {@link useAtom} for reading and updating a writable atom from one component
|
||||
* @see {@link useAtomRef} for reading an `AtomRef` directly
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomValue: {
|
||||
<A>(atom: Atom.Atom<A>): A
|
||||
<A, B>(atom: Atom.Atom<A>, f: (_: A) => B): B
|
||||
} = <A>(atom: Atom.Atom<A>, f?: (_: A) => A): A => {
|
||||
const registry = React.useContext(RegistryContext)
|
||||
if (f) {
|
||||
const atomB = React.useMemo(() => Atom.map(atom, f), [atom, f])
|
||||
return useStore(registry, atomB)
|
||||
}
|
||||
return useStore(registry, atom)
|
||||
}
|
||||
|
||||
function mountAtom<A>(registry: AtomRegistry.AtomRegistry, atom: Atom.Atom<A>): void {
|
||||
React.useEffect(() => registry.mount(atom), [atom, registry])
|
||||
}
|
||||
|
||||
function setAtom<R, W, Mode extends "value" | "promise" | "promiseExit" = never>(
|
||||
registry: AtomRegistry.AtomRegistry,
|
||||
atom: Atom.Writable<R, W>,
|
||||
options?: {
|
||||
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
||||
}
|
||||
): "promise" extends Mode ? (
|
||||
(value: W) => Promise<AsyncResult.AsyncResult.Success<R>>
|
||||
) :
|
||||
"promiseExit" extends Mode ? (
|
||||
(value: W) => Promise<Exit.Exit<AsyncResult.AsyncResult.Success<R>, AsyncResult.AsyncResult.Failure<R>>>
|
||||
) :
|
||||
((value: W | ((value: R) => W)) => void)
|
||||
{
|
||||
if (options?.mode === "promise" || options?.mode === "promiseExit") {
|
||||
return React.useCallback((value: W) => {
|
||||
registry.set(atom, value)
|
||||
const promise = Effect.runPromiseExit(
|
||||
AtomRegistry.getResult(registry, atom as Atom.Atom<AsyncResult.AsyncResult<any, any>>, {
|
||||
suspendOnWaiting: true
|
||||
})
|
||||
)
|
||||
return options!.mode === "promise" ? promise.then(flattenExit) : promise
|
||||
}, [registry, atom, options.mode]) as any
|
||||
}
|
||||
return React.useCallback((value: W | ((value: R) => W)) => {
|
||||
registry.set(atom, typeof value === "function" ? (value as any)(registry.get(atom)) : value)
|
||||
}, [registry, atom]) as any
|
||||
}
|
||||
|
||||
const flattenExit = <A, E>(exit: Exit.Exit<A, E>): A => {
|
||||
if (Exit.isSuccess(exit)) return exit.value
|
||||
throw Cause.squash(exit.cause)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mounts an atom in the current React registry for the lifetime of the
|
||||
* component.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to keep an atom mounted from a React component without reading, writing,
|
||||
* or refreshing it.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The hook uses the current `RegistryContext` and releases the mount through
|
||||
* React effect cleanup when the component unmounts or when the registry or atom
|
||||
* dependency changes.
|
||||
*
|
||||
* @see {@link useAtomSet} for mounting a writable atom while returning a setter
|
||||
* @see {@link useAtomRefresh} for mounting an atom while returning a refresh callback
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomMount = <A>(atom: Atom.Atom<A>): void => {
|
||||
const registry = React.useContext(RegistryContext)
|
||||
mountAtom(registry, atom)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mounts a writable atom and returns a setter without subscribing to its value.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a React component needs to update a writable atom without rendering
|
||||
* from that atom's value.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The hook mounts the atom and returns a setter. In value mode the setter
|
||||
* accepts a write value or updater function; for `AsyncResult` atoms, `promise`
|
||||
* and `promiseExit` modes return a promise for the success value or full `Exit`.
|
||||
*
|
||||
* @see {@link useAtom} for reading and updating the same writable atom
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomSet = <
|
||||
R,
|
||||
W,
|
||||
Mode extends "value" | "promise" | "promiseExit" = never
|
||||
>(
|
||||
atom: Atom.Writable<R, W>,
|
||||
options?: {
|
||||
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
||||
}
|
||||
): "promise" extends Mode ? (
|
||||
(value: W) => Promise<AsyncResult.AsyncResult.Success<R>>
|
||||
) :
|
||||
"promiseExit" extends Mode ? (
|
||||
(value: W) => Promise<Exit.Exit<AsyncResult.AsyncResult.Success<R>, AsyncResult.AsyncResult.Failure<R>>>
|
||||
) :
|
||||
((value: W | ((value: R) => W)) => void) =>
|
||||
{
|
||||
const registry = React.useContext(RegistryContext)
|
||||
mountAtom(registry, atom)
|
||||
return setAtom(registry, atom, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mounts an atom and returns a callback that refreshes it in the current React
|
||||
* registry.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to expose a React callback that requests a refresh for an atom without
|
||||
* reading or writing its value.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The hook uses the current `RegistryContext`, mounts the atom for the
|
||||
* component lifetime, and returns a callback that calls `registry.refresh`.
|
||||
*
|
||||
* @see {@link useAtomMount} for mounting an atom without returning a refresh callback
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomRefresh = <A>(atom: Atom.Atom<A>): () => void => {
|
||||
const registry = React.useContext(RegistryContext)
|
||||
mountAtom(registry, atom)
|
||||
return React.useCallback(() => {
|
||||
registry.refresh(atom)
|
||||
}, [registry, atom])
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes to a writable atom and returns its current value together with a
|
||||
* setter for updating it.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a React component needs both to render the current value of a
|
||||
* writable atom and update it from the same component.
|
||||
*
|
||||
* @see {@link useAtomValue} for subscribing to an atom without a setter
|
||||
* @see {@link useAtomSet} for updating a writable atom without subscribing to its value
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtom = <R, W, const Mode extends "value" | "promise" | "promiseExit" = never>(
|
||||
atom: Atom.Writable<R, W>,
|
||||
options?: {
|
||||
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
||||
}
|
||||
): readonly [
|
||||
value: R,
|
||||
write: "promise" extends Mode ? (
|
||||
(value: W) => Promise<AsyncResult.AsyncResult.Success<R>>
|
||||
) :
|
||||
"promiseExit" extends Mode ? (
|
||||
(value: W) => Promise<Exit.Exit<AsyncResult.AsyncResult.Success<R>, AsyncResult.AsyncResult.Failure<R>>>
|
||||
) :
|
||||
((value: W | ((value: R) => W)) => void)
|
||||
] => {
|
||||
const registry = React.useContext(RegistryContext)
|
||||
return [
|
||||
useStore(registry, atom),
|
||||
setAtom(registry, atom, options)
|
||||
] as const
|
||||
}
|
||||
|
||||
const atomPromiseMap = {
|
||||
suspendOnWaiting: new Map<Atom.Atom<any>, Promise<void>>(),
|
||||
default: new Map<Atom.Atom<any>, Promise<void>>()
|
||||
}
|
||||
|
||||
function atomToPromise<A, E>(
|
||||
registry: AtomRegistry.AtomRegistry,
|
||||
atom: Atom.Atom<AsyncResult.AsyncResult<A, E>>,
|
||||
suspendOnWaiting: boolean
|
||||
) {
|
||||
const map = suspendOnWaiting ? atomPromiseMap.suspendOnWaiting : atomPromiseMap.default
|
||||
let promise = map.get(atom)
|
||||
if (promise !== undefined) {
|
||||
return promise
|
||||
}
|
||||
promise = new Promise<void>((resolve) => {
|
||||
const dispose = registry.subscribe(atom, (result) => {
|
||||
if (result._tag === "Initial" || (suspendOnWaiting && result.waiting)) {
|
||||
return
|
||||
}
|
||||
setTimeout(dispose, 1000)
|
||||
resolve()
|
||||
map.delete(atom)
|
||||
})
|
||||
})
|
||||
map.set(atom, promise)
|
||||
return promise
|
||||
}
|
||||
|
||||
function atomResultOrSuspend<A, E>(
|
||||
registry: AtomRegistry.AtomRegistry,
|
||||
atom: Atom.Atom<AsyncResult.AsyncResult<A, E>>,
|
||||
suspendOnWaiting: boolean
|
||||
) {
|
||||
const value = useStore(registry, atom)
|
||||
if (value._tag === "Initial" || (suspendOnWaiting && value.waiting)) {
|
||||
throw atomToPromise(registry, atom, suspendOnWaiting)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an `AsyncResult` atom through React Suspense, suspending while the
|
||||
* result is initial or configured as waiting.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a React component should render only after an `AsyncResult` atom has
|
||||
* left its initial state, with loading delegated to a Suspense boundary.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* `suspendOnWaiting` defaults to `false`. When `includeFailure` is `true`, a
|
||||
* failure result is returned instead of being thrown.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* Without `includeFailure`, failure results are thrown with
|
||||
* `Cause.squash(result.cause)`, so callers need an error boundary for failures.
|
||||
*
|
||||
* @see {@link useAtomValue} for reading the raw `AsyncResult` value without Suspense
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomSuspense = <A, E, const IncludeFailure extends boolean = false>(
|
||||
atom: Atom.Atom<AsyncResult.AsyncResult<A, E>>,
|
||||
options?: {
|
||||
readonly suspendOnWaiting?: boolean | undefined
|
||||
readonly includeFailure?: IncludeFailure | undefined
|
||||
}
|
||||
): AsyncResult.Success<A, E> | (IncludeFailure extends true ? AsyncResult.Failure<A, E> : never) => {
|
||||
const registry = React.useContext(RegistryContext)
|
||||
const result = atomResultOrSuspend(registry, atom, options?.suspendOnWaiting ?? false)
|
||||
if (result._tag === "Failure" && !options?.includeFailure) {
|
||||
throw Cause.squash(result.cause)
|
||||
}
|
||||
return result as any
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes a callback to an atom in the current React registry for the
|
||||
* component lifetime.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a React component needs to run a callback for atom changes without
|
||||
* reading the atom value during render.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The subscription is installed in a React effect and cleaned up on unmount or
|
||||
* dependency change. When `options.immediate` is enabled, the callback receives
|
||||
* the current value when the effect subscribes.
|
||||
*
|
||||
* @see {@link useAtomValue} for reading an atom value during render instead of running a callback
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomSubscribe = <A>(
|
||||
atom: Atom.Atom<A>,
|
||||
f: (_: A) => void,
|
||||
options?: { readonly immediate?: boolean }
|
||||
): void => {
|
||||
const registry = React.useContext(RegistryContext)
|
||||
React.useEffect(
|
||||
() => registry.subscribe(atom, f, options),
|
||||
[registry, atom, f, options?.immediate]
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes to an atom ref and returns its latest value.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a React component should render from an `AtomRef.ReadonlyRef`
|
||||
* directly instead of reading an atom through the current registry.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The hook subscribes with `ref.subscribe`, triggers re-renders through React
|
||||
* state, and returns the current `ref.value`.
|
||||
*
|
||||
* @see {@link useAtomValue} for reading an `Atom` from the current registry
|
||||
* @see {@link useAtomRefPropValue} for reading a property ref value
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomRef = <A>(ref: AtomRef.ReadonlyRef<A>): A => {
|
||||
const [, setValue] = React.useState(ref.value)
|
||||
React.useEffect(() => ref.subscribe(setValue), [ref])
|
||||
return ref.value
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a memoized atom ref for a property of another atom ref.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to derive an `AtomRef` for one property of an object-shaped atom ref.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The hook memoizes `ref.prop(prop)` for the `[ref, prop]` dependency pair and
|
||||
* returns the property ref so callers can read, set, update, or subscribe to
|
||||
* that nested property.
|
||||
*
|
||||
* @see {@link useAtomRef} for subscribing to an atom ref value
|
||||
* @see {@link useAtomRefPropValue} for subscribing directly to a property value
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomRefProp = <A, K extends keyof A>(ref: AtomRef.AtomRef<A>, prop: K): AtomRef.AtomRef<A[K]> =>
|
||||
React.useMemo(() => ref.prop(prop), [ref, prop])
|
||||
|
||||
/**
|
||||
* Subscribes to a property ref derived from an atom ref and returns its current
|
||||
* value.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a React component needs only the current value of one property from
|
||||
* an object-shaped `AtomRef`.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The hook composes `useAtomRefProp(ref, prop)` with `useAtomRef`, so the
|
||||
* property ref is memoized for the `[ref, prop]` pair and then subscribed
|
||||
* through `ref.subscribe`.
|
||||
*
|
||||
* @see {@link useAtomRefProp} for returning the property ref directly
|
||||
* @see {@link useAtomRef} for subscribing to a whole atom ref value
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomRefPropValue = <A, K extends keyof A>(ref: AtomRef.AtomRef<A>, prop: K): A[K] =>
|
||||
useAtomRef(useAtomRefProp(ref, prop))
|
||||
109
repos/effect/packages/atom/react/src/ReactHydration.ts
Normal file
109
repos/effect/packages/atom/react/src/ReactHydration.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* React helpers for applying dehydrated Effect Atom state to a React subtree.
|
||||
* The `HydrationBoundary` component reads the nearest `RegistryContext`,
|
||||
* hydrates new Atom values before children render, and delays updates for
|
||||
* existing Atom values until after commit so React transitions do not update
|
||||
* the current UI too early.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
"use client"
|
||||
import * as Hydration from "effect/unstable/reactivity/Hydration"
|
||||
import * as React from "react"
|
||||
import { RegistryContext } from "./RegistryContext.ts"
|
||||
|
||||
/**
|
||||
* Props for a boundary that applies dehydrated Atom values to the nearest
|
||||
* {@link RegistryContext} while rendering its children.
|
||||
*
|
||||
* @category components
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface HydrationBoundaryProps {
|
||||
state?: Iterable<Hydration.DehydratedAtom>
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a React hydration boundary that loads dehydrated Atom values into
|
||||
* the current Atom registry.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to apply dehydrated Atom state to a React subtree that reads from the
|
||||
* nearest `RegistryContext`.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* New Atom values are hydrated during render so descendants can read them
|
||||
* immediately, while values for existing Atoms are deferred until after commit
|
||||
* so transition data does not update the current UI before React accepts it.
|
||||
*
|
||||
* @see {@link Hydration.dehydrate} for producing dehydrated Atom state
|
||||
* @see {@link Hydration.hydrate} for lower-level non-React hydration
|
||||
*
|
||||
* @category components
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const HydrationBoundary: React.FC<HydrationBoundaryProps> = ({
|
||||
children,
|
||||
state
|
||||
}) => {
|
||||
const registry = React.useContext(RegistryContext)
|
||||
|
||||
// This useMemo is for performance reasons only, everything inside it must
|
||||
// be safe to run in every render and code here should be read as "in render".
|
||||
//
|
||||
// This code needs to happen during the render phase, because after initial
|
||||
// SSR, hydration needs to happen _before_ children render. Also, if hydrating
|
||||
// during a transition, we want to hydrate as much as is safe in render so
|
||||
// we can prerender as much as possible.
|
||||
//
|
||||
// For any Atom values that already exist in the registry, we want to hold back on
|
||||
// hydrating until _after_ the render phase. The reason for this is that during
|
||||
// transitions, we don't want the existing Atom values and subscribers to update to
|
||||
// the new data on the current page, only _after_ the transition is committed.
|
||||
// If the transition is aborted, we will have hydrated any _new_ Atom values, but
|
||||
// we throw away the fresh data for any existing ones to avoid unexpectedly
|
||||
// updating the UI.
|
||||
const hydrationQueue: Array<Hydration.DehydratedAtomValue> | undefined = React.useMemo(() => {
|
||||
if (state) {
|
||||
const dehydratedAtoms = Array.from(state) as Array<Hydration.DehydratedAtomValue>
|
||||
const nodes = registry.getNodes()
|
||||
|
||||
const newDehydratedAtoms: Array<Hydration.DehydratedAtomValue> = []
|
||||
const existingDehydratedAtoms: Array<Hydration.DehydratedAtomValue> = []
|
||||
|
||||
for (const dehydratedAtom of dehydratedAtoms) {
|
||||
const existingNode = nodes.get(dehydratedAtom.key)
|
||||
|
||||
if (!existingNode) {
|
||||
// This is a new Atom value, safe to hydrate immediately
|
||||
newDehydratedAtoms.push(dehydratedAtom)
|
||||
} else {
|
||||
// This Atom value already exists, queue it for later hydration
|
||||
existingDehydratedAtoms.push(dehydratedAtom)
|
||||
}
|
||||
}
|
||||
|
||||
if (newDehydratedAtoms.length > 0) {
|
||||
// It's actually fine to call this with state that already exists
|
||||
// in the registry, or is older. hydrate() is idempotent.
|
||||
Hydration.hydrate(registry, newDehydratedAtoms)
|
||||
}
|
||||
|
||||
if (existingDehydratedAtoms.length > 0) {
|
||||
return existingDehydratedAtoms
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}, [registry, state])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (hydrationQueue) {
|
||||
Hydration.hydrate(registry, hydrationQueue)
|
||||
}
|
||||
}, [registry, hydrationQueue])
|
||||
|
||||
return React.createElement(React.Fragment, {}, children)
|
||||
}
|
||||
108
repos/effect/packages/atom/react/src/RegistryContext.ts
Normal file
108
repos/effect/packages/atom/react/src/RegistryContext.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* React context and provider for the Atom registry used by Effect Atom hooks.
|
||||
* The registry stores atom values, schedules update work, and cleans up unused
|
||||
* atoms. Sharing one registry through React context lets components in the same
|
||||
* subtree read and write the same atom state.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
"use client"
|
||||
|
||||
import type * as Atom from "effect/unstable/reactivity/Atom"
|
||||
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
||||
import * as React from "react"
|
||||
import * as Scheduler from "scheduler"
|
||||
|
||||
/**
|
||||
* Schedules Atom registry work with React's scheduler at low priority and
|
||||
* returns a cancellation function for the scheduled task.
|
||||
*
|
||||
* @category context
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export function scheduleTask(f: () => void): () => void {
|
||||
const node = Scheduler.unstable_scheduleCallback(Scheduler.unstable_LowPriority, f)
|
||||
return () => Scheduler.unstable_cancelCallback(node)
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a React context that supplies the `AtomRegistry` used by Atom hooks and
|
||||
* hydration helpers, defaulting to a standalone registry when no provider is
|
||||
* present.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to supply an existing `AtomRegistry` through React context when hooks or
|
||||
* hydration helpers need to share registry state that is managed outside
|
||||
* `RegistryProvider`.
|
||||
*
|
||||
* @see {@link RegistryProvider} for creating and providing a registry for a React subtree
|
||||
*
|
||||
* @category context
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const RegistryContext = React.createContext<AtomRegistry.AtomRegistry>(AtomRegistry.make({
|
||||
scheduleTask,
|
||||
defaultIdleTTL: 400
|
||||
}))
|
||||
|
||||
/**
|
||||
* Provides a stable `AtomRegistry` to a React subtree, optionally seeding
|
||||
* initial atom values and overriding registry scheduling or idle settings.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to scope atom state, scheduling, and idle cleanup to a React subtree.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The provider creates one `AtomRegistry` with `AtomRegistry.make`, passes it
|
||||
* through `RegistryContext.Provider`, and forwards `initialValues`,
|
||||
* `scheduleTask`, `timeoutResolution`, and `defaultIdleTTL` only when that
|
||||
* registry is created.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* Option changes after the first render do not rebuild the registry. When the
|
||||
* provider unmounts, registry disposal is delayed briefly and canceled if the
|
||||
* provider remounts before the timeout fires.
|
||||
*
|
||||
* @see {@link RegistryContext} for the React context supplied by this provider
|
||||
*
|
||||
* @category context
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const RegistryProvider = (options: {
|
||||
readonly children?: React.ReactNode | undefined
|
||||
readonly initialValues?: Iterable<readonly [Atom.Atom<any>, any]> | undefined
|
||||
readonly scheduleTask?: ((f: () => void) => () => void) | undefined
|
||||
readonly timeoutResolution?: number | undefined
|
||||
readonly defaultIdleTTL?: number | undefined
|
||||
}) => {
|
||||
const ref = React.useRef<{
|
||||
readonly registry: AtomRegistry.AtomRegistry
|
||||
timeout?: number | undefined
|
||||
}>(null)
|
||||
if (ref.current === null) {
|
||||
ref.current = {
|
||||
registry: AtomRegistry.make({
|
||||
scheduleTask: options.scheduleTask ?? scheduleTask,
|
||||
initialValues: options.initialValues,
|
||||
timeoutResolution: options.timeoutResolution,
|
||||
defaultIdleTTL: options.defaultIdleTTL
|
||||
})
|
||||
}
|
||||
}
|
||||
React.useEffect(() => {
|
||||
if (ref.current?.timeout !== undefined) {
|
||||
clearTimeout(ref.current.timeout)
|
||||
}
|
||||
return () => {
|
||||
ref.current!.timeout = setTimeout(() => {
|
||||
ref.current?.registry.dispose()
|
||||
ref.current = null
|
||||
}, 500) as any
|
||||
}
|
||||
}, [ref])
|
||||
return React.createElement(RegistryContext.Provider, { value: ref.current.registry }, options?.children)
|
||||
}
|
||||
151
repos/effect/packages/atom/react/src/ScopedAtom.ts
Normal file
151
repos/effect/packages/atom/react/src/ScopedAtom.ts
Normal file
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* React helpers for creating Atom instances that belong to one component
|
||||
* subtree. `make` returns a scoped atom with a provider, context, and `use`
|
||||
* accessor. Each provider creates its own Atom once, so different subtrees can
|
||||
* use the same scoped atom definition without sharing state.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
"use client"
|
||||
|
||||
import type * as Atom from "effect/unstable/reactivity/Atom"
|
||||
import * as React from "react"
|
||||
|
||||
/**
|
||||
* Literal type used as the `ScopedAtom` type identifier.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Used as the computed property key and marker value stored on `ScopedAtom`
|
||||
* objects.
|
||||
*
|
||||
* @category type IDs
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export type TypeId = "~@effect/atom-react/ScopedAtom"
|
||||
|
||||
/**
|
||||
* Type identifier for ScopedAtom.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* Used as the computed property key and marker value stored on `ScopedAtom`
|
||||
* objects.
|
||||
*
|
||||
* @category type IDs
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const TypeId: TypeId = "~@effect/atom-react/ScopedAtom"
|
||||
|
||||
/**
|
||||
* Scoped Atom interface with a provider-backed instance.
|
||||
*
|
||||
* **Example** (Providing and reading a scoped atom)
|
||||
*
|
||||
* ```ts
|
||||
* import { make, useAtomValue } from "@effect/atom-react"
|
||||
* import { Atom } from "effect/unstable/reactivity"
|
||||
* import * as React from "react"
|
||||
*
|
||||
* const Counter = make(() => Atom.make(0))
|
||||
*
|
||||
* function View() {
|
||||
* const atom = Counter.use()
|
||||
* const value = useAtomValue(atom)
|
||||
* return React.createElement("div", null, value)
|
||||
* }
|
||||
*
|
||||
* export function App() {
|
||||
* return React.createElement(Counter.Provider, null, React.createElement(View))
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @category models
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export interface ScopedAtom<A extends Atom.Atom<any>, Input = never> {
|
||||
readonly [TypeId]: TypeId
|
||||
use(): A
|
||||
Provider: [Input] extends [never] ? React.FC<{ readonly children?: React.ReactNode | undefined }>
|
||||
: React.FC<{ readonly children?: React.ReactNode | undefined; readonly value: Input }>
|
||||
Context: React.Context<A>
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ScopedAtom from a factory function.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to create an atom instance that is owned by a React provider and scoped
|
||||
* to a component subtree.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The returned scoped atom includes a `Provider`, `Context`, and `use`
|
||||
* accessor. The provider creates the atom once for its lifetime, passing the
|
||||
* `value` prop to the factory when the scoped atom expects input.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* `use` must run under the matching provider. Changing the provider `value`
|
||||
* prop after mount does not recreate the atom.
|
||||
*
|
||||
* **Example** (Creating a scoped atom with input)
|
||||
*
|
||||
* ```ts
|
||||
* import { make, useAtomValue } from "@effect/atom-react"
|
||||
* import { Atom } from "effect/unstable/reactivity"
|
||||
* import * as React from "react"
|
||||
*
|
||||
* const User = make((name: string) => Atom.make(name))
|
||||
*
|
||||
* function UserName() {
|
||||
* const atom = User.use()
|
||||
* const value = useAtomValue(atom)
|
||||
* return React.createElement("span", null, value)
|
||||
* }
|
||||
*
|
||||
* export function App() {
|
||||
* return React.createElement(
|
||||
* User.Provider,
|
||||
* { value: "Ada" },
|
||||
* React.createElement(UserName)
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @category constructors
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const make = <A extends Atom.Atom<any>, Input = never>(
|
||||
f: (() => A) | ((input: Input) => A)
|
||||
): ScopedAtom<A, Input> => {
|
||||
const Context = React.createContext<A>(undefined as unknown as A)
|
||||
|
||||
const use = (): A => {
|
||||
const atom = React.useContext(Context)
|
||||
if (atom === undefined) {
|
||||
throw new Error("ScopedAtom used outside of its Provider")
|
||||
}
|
||||
return atom
|
||||
}
|
||||
|
||||
const Provider: React.FC<{ readonly children?: React.ReactNode | undefined; readonly value?: Input }> = (props) => {
|
||||
const atom = React.useRef<A | null>(null)
|
||||
if (atom.current === null) {
|
||||
if ("value" in props) {
|
||||
atom.current = (f as (input: Input) => A)(props.value as Input)
|
||||
} else {
|
||||
atom.current = (f as () => A)()
|
||||
}
|
||||
}
|
||||
return React.createElement(Context.Provider, { value: atom.current }, props.children)
|
||||
}
|
||||
|
||||
return {
|
||||
[TypeId]: TypeId,
|
||||
use,
|
||||
Provider: Provider as any,
|
||||
Context
|
||||
}
|
||||
}
|
||||
23
repos/effect/packages/atom/react/src/index.ts
Normal file
23
repos/effect/packages/atom/react/src/index.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * from "./Hooks.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * from "./RegistryContext.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * from "./ReactHydration.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * from "./ScopedAtom.ts"
|
||||
650
repos/effect/packages/atom/react/test/index.test.tsx
Normal file
650
repos/effect/packages/atom/react/test/index.test.tsx
Normal file
@@ -0,0 +1,650 @@
|
||||
// <reference types="@testing-library/jest-dom" />
|
||||
import { act, render, screen, waitFor } from "@testing-library/react"
|
||||
import { Cause, Context, Effect, Latch, Layer } from "effect"
|
||||
import * as Schema from "effect/Schema"
|
||||
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
||||
import * as Atom from "effect/unstable/reactivity/Atom"
|
||||
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
||||
import * as Hydration from "effect/unstable/reactivity/Hydration"
|
||||
import * as React from "react"
|
||||
import { Suspense } from "react"
|
||||
import { renderToString } from "react-dom/server"
|
||||
import { ErrorBoundary } from "react-error-boundary"
|
||||
import { beforeEach, describe, expect, it, test, vi } from "vitest"
|
||||
import { HydrationBoundary, RegistryContext, RegistryProvider, useAtomSuspense, useAtomValue } from "../src/index.ts"
|
||||
import * as ScopedAtom from "../src/ScopedAtom.ts"
|
||||
|
||||
describe("atom-react", () => {
|
||||
let registry: AtomRegistry.AtomRegistry
|
||||
|
||||
beforeEach(() => {
|
||||
registry = AtomRegistry.make()
|
||||
})
|
||||
|
||||
describe("runtime", () => {
|
||||
test("can inject test layers", () => {
|
||||
class TheNumber extends Context.Service<TheNumber>()("TheNumber", {
|
||||
make: Effect.succeed({ n: 42 as number })
|
||||
}) {
|
||||
static readonly layer = Layer.effect(this, this.make)
|
||||
}
|
||||
const runtime = Atom.runtime(TheNumber.layer)
|
||||
const numberAtom = runtime.atom(TheNumber.use((_) => Effect.succeed(_.n)))
|
||||
|
||||
function TestComponent() {
|
||||
const value = useAtomValue(numberAtom, AsyncResult.getOrThrow)
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
render(
|
||||
<RegistryProvider
|
||||
initialValues={[
|
||||
Atom.initialValue(
|
||||
runtime.layer,
|
||||
Layer.succeed(TheNumber, { n: 69 })
|
||||
)
|
||||
]}
|
||||
>
|
||||
<TestComponent />
|
||||
</RegistryProvider>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("69")
|
||||
})
|
||||
})
|
||||
|
||||
describe("useAtomValue", () => {
|
||||
test("should read value from simple Atom", () => {
|
||||
const atom = Atom.make(42)
|
||||
|
||||
function TestComponent() {
|
||||
const value = useAtomValue(atom)
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
render(<TestComponent />)
|
||||
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("42")
|
||||
})
|
||||
|
||||
test("should read value with transform function", () => {
|
||||
const atom = Atom.make(42)
|
||||
|
||||
function TestComponent() {
|
||||
const value = useAtomValue(atom, (x) => x * 2)
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
render(<TestComponent />)
|
||||
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("84")
|
||||
})
|
||||
|
||||
test("should update when Atom value changes", async () => {
|
||||
const atom = Atom.make("initial")
|
||||
|
||||
function TestComponent() {
|
||||
const value = useAtomValue(atom)
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
render(
|
||||
<RegistryContext.Provider value={registry}>
|
||||
<TestComponent />
|
||||
</RegistryContext.Provider>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("initial")
|
||||
|
||||
act(() => {
|
||||
registry.set(atom, "updated")
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("updated")
|
||||
})
|
||||
})
|
||||
|
||||
test("should work with computed Atom", () => {
|
||||
const baseAtom = Atom.make(10)
|
||||
const computedAtom = Atom.make((get) => get(baseAtom) * 2)
|
||||
|
||||
function TestComponent() {
|
||||
const value = useAtomValue(computedAtom)
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
render(<TestComponent />)
|
||||
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("20")
|
||||
})
|
||||
|
||||
test("suspense success", () => {
|
||||
const atom = Atom.make(Effect.never)
|
||||
|
||||
function TestComponent() {
|
||||
const value = useAtomSuspense(atom).value
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
render(
|
||||
<Suspense fallback={<div data-testid="loading">Loading...</div>}>
|
||||
<TestComponent />
|
||||
</Suspense>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("loading")).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe("ScopedAtom", () => {
|
||||
test("throws when used outside Provider", () => {
|
||||
const counter = ScopedAtom.make(() => Atom.make(0))
|
||||
|
||||
function TestComponent() {
|
||||
counter.use()
|
||||
return <div>ok</div>
|
||||
}
|
||||
|
||||
expect(() => render(<TestComponent />)).toThrow("ScopedAtom used outside of its Provider")
|
||||
})
|
||||
|
||||
test("scopes atom instances per Provider", async () => {
|
||||
const counter = ScopedAtom.make(() => Atom.make(0))
|
||||
|
||||
function Count() {
|
||||
const atom = counter.use()
|
||||
const value = useAtomValue(atom)
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
function SetTo({ value }: { readonly value: number }) {
|
||||
const atom = counter.use()
|
||||
const registry = React.useContext(RegistryContext)
|
||||
React.useEffect(() => {
|
||||
registry.set(atom, value)
|
||||
}, [registry, atom, value])
|
||||
return null
|
||||
}
|
||||
|
||||
render(
|
||||
<div>
|
||||
<counter.Provider>
|
||||
<SetTo value={1} />
|
||||
<Count />
|
||||
</counter.Provider>
|
||||
<counter.Provider>
|
||||
<SetTo value={2} />
|
||||
<Count />
|
||||
</counter.Provider>
|
||||
</div>
|
||||
)
|
||||
|
||||
await waitFor(() => {
|
||||
const values = screen.getAllByTestId("value")
|
||||
expect(values[0]).toHaveTextContent("1")
|
||||
expect(values[1]).toHaveTextContent("2")
|
||||
})
|
||||
})
|
||||
|
||||
test("input factory uses provider value once", () => {
|
||||
const makeAtom = vi.fn((value: number) => Atom.make(value))
|
||||
const scoped = ScopedAtom.make(makeAtom)
|
||||
|
||||
function Count() {
|
||||
const atom = scoped.use()
|
||||
const value = useAtomValue(atom)
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
const { rerender } = render(
|
||||
<scoped.Provider value={10}>
|
||||
<Count />
|
||||
</scoped.Provider>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("10")
|
||||
expect(makeAtom).toHaveBeenCalledTimes(1)
|
||||
expect(makeAtom).toHaveBeenCalledWith(10)
|
||||
|
||||
rerender(
|
||||
<scoped.Provider value={99}>
|
||||
<Count />
|
||||
</scoped.Provider>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("10")
|
||||
expect(makeAtom).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
test("integrates with useAtomValue", async () => {
|
||||
const scoped = ScopedAtom.make(() => Atom.make(0))
|
||||
|
||||
function Counter() {
|
||||
const atom = scoped.use()
|
||||
const value = useAtomValue(atom)
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
function IncrementOnce() {
|
||||
const atom = scoped.use()
|
||||
const registry = React.useContext(RegistryContext)
|
||||
React.useEffect(() => {
|
||||
registry.set(atom, 1)
|
||||
}, [registry, atom])
|
||||
return null
|
||||
}
|
||||
|
||||
render(
|
||||
<scoped.Provider>
|
||||
<IncrementOnce />
|
||||
<Counter />
|
||||
</scoped.Provider>
|
||||
)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("1")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test("suspense error", () => {
|
||||
const atom = Atom.make(Effect.fail(new Error("test")))
|
||||
function TestComponent() {
|
||||
const value = useAtomSuspense(atom).value
|
||||
return <div data-testid="value">{value}</div>
|
||||
}
|
||||
|
||||
render(
|
||||
<ErrorBoundary fallback={<div data-testid="error">Error</div>}>
|
||||
<Suspense fallback={<div data-testid="loading">Loading...</div>}>
|
||||
<TestComponent />
|
||||
</Suspense>
|
||||
</ErrorBoundary>,
|
||||
{
|
||||
onCaughtError: ((error: unknown) => {
|
||||
if (error instanceof Error && error.message === "test") {
|
||||
return
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error)
|
||||
}) as unknown as undefined // todo: fix idk why the types are weird
|
||||
}
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("error")).toBeInTheDocument()
|
||||
})
|
||||
|
||||
describe("hydration", () => {
|
||||
test("basic hydration with number atom and result atoms", () => {
|
||||
const atomBasic = Atom.make(0).pipe(
|
||||
Atom.serializable({
|
||||
key: "basic",
|
||||
schema: Schema.Number
|
||||
})
|
||||
)
|
||||
const e: Effect.Effect<number, string> = Effect.never
|
||||
const makeAtomResult = (key: string) =>
|
||||
Atom.make(e).pipe(
|
||||
Atom.serializable({
|
||||
key,
|
||||
schema: AsyncResult.Schema({
|
||||
success: Schema.Number,
|
||||
error: Schema.String
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
const atomResult1 = makeAtomResult("success")
|
||||
const atomResult2 = makeAtomResult("errored")
|
||||
const atomResult3 = makeAtomResult("pending")
|
||||
|
||||
// Use a server-side registry to generate properly encoded dehydrated state
|
||||
const serverRegistry = AtomRegistry.make()
|
||||
serverRegistry.mount(atomBasic)
|
||||
serverRegistry.set(atomBasic, 1)
|
||||
serverRegistry.mount(atomResult1)
|
||||
;(serverRegistry.getNodes().get("success") as any).setValue(
|
||||
AsyncResult.success(123)
|
||||
)
|
||||
serverRegistry.mount(atomResult2)
|
||||
;(serverRegistry.getNodes().get("errored") as any).setValue(
|
||||
AsyncResult.failure(Cause.fail("error"))
|
||||
)
|
||||
serverRegistry.mount(atomResult3)
|
||||
// atomResult3 stays Initial (just mounted, effect is Effect.never)
|
||||
|
||||
const dehydratedState = Hydration.dehydrate(serverRegistry, {
|
||||
encodeInitialAs: "value-only"
|
||||
})
|
||||
|
||||
function Basic() {
|
||||
const value = useAtomValue(atomBasic)
|
||||
return <div data-testid="hydration-basic-value">{value}</div>
|
||||
}
|
||||
|
||||
function Result1() {
|
||||
const value = useAtomValue(atomResult1)
|
||||
return AsyncResult.match(value, {
|
||||
onSuccess: (result) => <div data-testid="value-1">{result.value}</div>,
|
||||
onFailure: () => <div data-testid="error-1">Error</div>,
|
||||
onInitial: () => <div data-testid="loading-1">Loading...</div>
|
||||
})
|
||||
}
|
||||
|
||||
function Result2() {
|
||||
const value = useAtomValue(atomResult2)
|
||||
return AsyncResult.match(value, {
|
||||
onSuccess: (result) => <div data-testid="value-2">{result.value}</div>,
|
||||
onFailure: () => <div data-testid="error-2">Error</div>,
|
||||
onInitial: () => <div data-testid="loading-2">Loading...</div>
|
||||
})
|
||||
}
|
||||
|
||||
function Result3() {
|
||||
const value = useAtomValue(atomResult3)
|
||||
return AsyncResult.match(value, {
|
||||
onSuccess: (result) => <div data-testid="value-3">{result.value}</div>,
|
||||
onFailure: () => <div data-testid="error-3">Error</div>,
|
||||
onInitial: () => <div data-testid="loading-3">Loading...</div>
|
||||
})
|
||||
}
|
||||
|
||||
render(
|
||||
<RegistryContext.Provider value={AtomRegistry.make()}>
|
||||
<HydrationBoundary state={dehydratedState}>
|
||||
<Basic />
|
||||
<Result1 />
|
||||
<Result2 />
|
||||
<Result3 />
|
||||
</HydrationBoundary>
|
||||
</RegistryContext.Provider>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("hydration-basic-value")).toHaveTextContent("1")
|
||||
expect(screen.getByTestId("value-1")).toHaveTextContent("123")
|
||||
expect(screen.getByTestId("error-2")).toBeInTheDocument()
|
||||
expect(screen.getByTestId("loading-3")).toBeInTheDocument()
|
||||
})
|
||||
|
||||
test("hydration streaming with resultPromise", async () => {
|
||||
const latch = Latch.makeUnsafe()
|
||||
let start = 0
|
||||
let stop = 0
|
||||
const atom = Atom.make(
|
||||
Effect.gen(function*() {
|
||||
start = start + 1
|
||||
yield* latch.await
|
||||
stop = stop + 1
|
||||
return 1
|
||||
})
|
||||
).pipe(
|
||||
Atom.serializable({
|
||||
key: "test",
|
||||
schema: AsyncResult.Schema({
|
||||
success: Schema.Number
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
registry.mount(atom)
|
||||
|
||||
expect(start).toBe(1)
|
||||
expect(stop).toBe(0)
|
||||
|
||||
const dehydratedState = Hydration.dehydrate(registry, {
|
||||
encodeInitialAs: "promise"
|
||||
})
|
||||
|
||||
function TestComponent() {
|
||||
const value = useAtomValue(atom)
|
||||
return <div data-testid="value">{value._tag}</div>
|
||||
}
|
||||
|
||||
render(
|
||||
// provide a fresh registry each time to simulate hydration
|
||||
<RegistryContext.Provider value={AtomRegistry.make()}>
|
||||
<HydrationBoundary state={dehydratedState}>
|
||||
<TestComponent />
|
||||
</HydrationBoundary>
|
||||
</RegistryContext.Provider>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("Initial")
|
||||
|
||||
act(() => {
|
||||
Effect.runSync(latch.open)
|
||||
})
|
||||
await Effect.runPromise(latch.await)
|
||||
|
||||
const result = registry.get(atom)
|
||||
expect(result._tag).toBe("Success")
|
||||
if (result._tag === "Success") {
|
||||
expect(result.value).toBe(1)
|
||||
}
|
||||
|
||||
expect(screen.getByTestId("value")).toHaveTextContent("Success")
|
||||
expect(start).toBe(1)
|
||||
expect(stop).toBe(1)
|
||||
})
|
||||
|
||||
test("HydrationBoundary splits new vs existing atoms", () => {
|
||||
const newAtom = Atom.make(0).pipe(
|
||||
Atom.serializable({ key: "new-atom", schema: Schema.Number })
|
||||
)
|
||||
|
||||
// Use a server registry to generate dehydrated state
|
||||
const serverRegistry = AtomRegistry.make()
|
||||
serverRegistry.mount(newAtom)
|
||||
serverRegistry.set(newAtom, 99)
|
||||
const dehydratedState = Hydration.dehydrate(serverRegistry)
|
||||
|
||||
function NewValue() {
|
||||
const value = useAtomValue(newAtom)
|
||||
return <div data-testid="new">{value}</div>
|
||||
}
|
||||
|
||||
// Render with a fresh client registry (no pre-existing atoms)
|
||||
render(
|
||||
<RegistryContext.Provider value={AtomRegistry.make()}>
|
||||
<HydrationBoundary state={dehydratedState}>
|
||||
<NewValue />
|
||||
</HydrationBoundary>
|
||||
</RegistryContext.Provider>
|
||||
)
|
||||
|
||||
// New atom should be hydrated immediately during render
|
||||
expect(screen.getByTestId("new")).toHaveTextContent("99")
|
||||
})
|
||||
|
||||
test("dehydrate with encodeInitialAs ignore (default)", () => {
|
||||
const atom = Atom.make(Effect.never as Effect.Effect<number>).pipe(
|
||||
Atom.serializable({
|
||||
key: "initial-atom",
|
||||
schema: AsyncResult.Schema({ success: Schema.Number })
|
||||
})
|
||||
)
|
||||
|
||||
registry.mount(atom)
|
||||
|
||||
// Default behavior: Initial values should be ignored
|
||||
const state = Hydration.dehydrate(registry)
|
||||
const values = Hydration.toValues(state)
|
||||
|
||||
expect(values.length).toBe(0)
|
||||
})
|
||||
|
||||
test("dehydrate with encodeInitialAs value-only", () => {
|
||||
const atom = Atom.make(Effect.never as Effect.Effect<number>).pipe(
|
||||
Atom.serializable({
|
||||
key: "initial-atom",
|
||||
schema: AsyncResult.Schema({ success: Schema.Number })
|
||||
})
|
||||
)
|
||||
|
||||
registry.mount(atom)
|
||||
|
||||
// value-only: should encode the Initial value without a resultPromise
|
||||
const state = Hydration.dehydrate(registry, {
|
||||
encodeInitialAs: "value-only"
|
||||
})
|
||||
const values = Hydration.toValues(state)
|
||||
|
||||
expect(values.length).toBe(1)
|
||||
expect(values[0].key).toBe("initial-atom")
|
||||
expect(values[0].resultPromise).toBeUndefined()
|
||||
})
|
||||
|
||||
test("serializable encode/decode survives JSON roundtrip (wire transfer)", () => {
|
||||
const atom = Atom.make(0 as never).pipe(
|
||||
Atom.serializable({
|
||||
key: "wire-test",
|
||||
schema: AsyncResult.Schema({
|
||||
success: Schema.Struct({ name: Schema.String }),
|
||||
error: Schema.String
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
const original = AsyncResult.success({ name: "hello" })
|
||||
|
||||
// Encode using the atom's serializable encode
|
||||
const encoded = atom[Atom.SerializableTypeId].encode(original)
|
||||
|
||||
// Simulate wire transfer (seroval / JSON serialization roundtrip)
|
||||
const wireTransferred = JSON.parse(JSON.stringify(encoded))
|
||||
|
||||
// Decode after wire transfer — this was the bug: decode would fail
|
||||
// because the encoded value lost its AsyncResult prototype
|
||||
const decoded = atom[Atom.SerializableTypeId].decode(wireTransferred)
|
||||
|
||||
expect(AsyncResult.isAsyncResult(decoded)).toBe(true)
|
||||
expect(decoded._tag).toBe("Success")
|
||||
if (AsyncResult.isSuccess(decoded)) {
|
||||
expect(decoded.value).toEqual({ name: "hello" })
|
||||
}
|
||||
})
|
||||
|
||||
test("dehydrate + JSON roundtrip + hydrate works (SSR simulation)", () => {
|
||||
const atom = Atom.make(Effect.never as Effect.Effect<number>).pipe(
|
||||
Atom.serializable({
|
||||
key: "ssr-wire",
|
||||
schema: AsyncResult.Schema({ success: Schema.Number })
|
||||
})
|
||||
)
|
||||
|
||||
// Server: dehydrate
|
||||
const serverRegistry = AtomRegistry.make()
|
||||
serverRegistry.mount(atom)
|
||||
;(serverRegistry.getNodes().get("ssr-wire") as any).setValue(
|
||||
AsyncResult.success(42)
|
||||
)
|
||||
const dehydratedState = Hydration.dehydrate(serverRegistry)
|
||||
|
||||
// Simulate wire transfer (seroval / JSON)
|
||||
const wireTransferred = JSON.parse(JSON.stringify(dehydratedState))
|
||||
|
||||
// Client: hydrate from wire-transferred state
|
||||
function TestComponent() {
|
||||
const value = useAtomValue(atom)
|
||||
return (
|
||||
<div data-testid="ssr-wire-value">
|
||||
{AsyncResult.isSuccess(value) ? value.value : "not-success"}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render(
|
||||
<RegistryContext.Provider value={AtomRegistry.make()}>
|
||||
<HydrationBoundary state={wireTransferred}>
|
||||
<TestComponent />
|
||||
</HydrationBoundary>
|
||||
</RegistryContext.Provider>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("ssr-wire-value")).toHaveTextContent("42")
|
||||
})
|
||||
|
||||
test("empty state is a no-op", () => {
|
||||
function TestComponent() {
|
||||
return <div data-testid="hydration-empty-state">OK</div>
|
||||
}
|
||||
|
||||
render(
|
||||
<HydrationBoundary state={[]}>
|
||||
<TestComponent />
|
||||
</HydrationBoundary>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("hydration-empty-state")).toHaveTextContent("OK")
|
||||
})
|
||||
|
||||
test("hydrate with no state is a no-op", () => {
|
||||
function TestComponent() {
|
||||
return <div data-testid="hydration-no-state">OK</div>
|
||||
}
|
||||
|
||||
render(
|
||||
<HydrationBoundary>
|
||||
<TestComponent />
|
||||
</HydrationBoundary>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId("hydration-no-state")).toHaveTextContent("OK")
|
||||
})
|
||||
})
|
||||
|
||||
describe("SSR", () => {
|
||||
it("should run atom's during SSR by default", () => {
|
||||
const getCount = vi.fn(() => 0)
|
||||
const counterAtom = Atom.make(getCount)
|
||||
|
||||
function TestComponent() {
|
||||
const count = useAtomValue(counterAtom)
|
||||
return <div>{count}</div>
|
||||
}
|
||||
|
||||
function App() {
|
||||
return <TestComponent />
|
||||
}
|
||||
|
||||
const ssrHtml = renderToString(<App />)
|
||||
|
||||
expect(getCount).toHaveBeenCalled()
|
||||
expect(ssrHtml).toContain("0")
|
||||
|
||||
render(<App />)
|
||||
|
||||
expect(getCount).toHaveBeenCalled()
|
||||
expect(screen.getByText("0")).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
it("should not execute Atom effects during SSR when using withServerSnapshot", () => {
|
||||
const mockFetchData = vi.fn(() => 0)
|
||||
|
||||
const userDataAtom = Atom.make(Effect.sync(() => mockFetchData())).pipe(
|
||||
Atom.withServerValueInitial
|
||||
)
|
||||
|
||||
function TestComponent() {
|
||||
const result = useAtomValue(userDataAtom)
|
||||
|
||||
return <div>{result._tag}</div>
|
||||
}
|
||||
|
||||
function App() {
|
||||
return <TestComponent />
|
||||
}
|
||||
|
||||
const ssrHtml = renderToString(<App />)
|
||||
|
||||
expect(mockFetchData).not.toHaveBeenCalled()
|
||||
expect(ssrHtml).toContain("Initial")
|
||||
|
||||
render(<App />)
|
||||
|
||||
expect(mockFetchData).toHaveBeenCalled()
|
||||
expect(screen.getByText("Success")).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
8
repos/effect/packages/atom/react/tsconfig.json
Normal file
8
repos/effect/packages/atom/react/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/tsconfig",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{ "path": "../../effect" }
|
||||
]
|
||||
}
|
||||
9
repos/effect/packages/atom/react/vitest.config.ts
Normal file
9
repos/effect/packages/atom/react/vitest.config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { mergeConfig } from "vitest/config"
|
||||
import shared from "../../../vitest.shared.ts"
|
||||
|
||||
export default mergeConfig(shared, {
|
||||
test: {
|
||||
environment: "jsdom",
|
||||
setupFiles: ["./vitest.setup.ts"]
|
||||
}
|
||||
})
|
||||
8
repos/effect/packages/atom/react/vitest.setup.ts
Normal file
8
repos/effect/packages/atom/react/vitest.setup.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
// oxlint-disable-next-line no-unassigned-import
|
||||
import "@testing-library/jest-dom/vitest"
|
||||
import { cleanup } from "@testing-library/react"
|
||||
import { afterEach } from "vitest"
|
||||
|
||||
afterEach(() => {
|
||||
cleanup()
|
||||
})
|
||||
707
repos/effect/packages/atom/solid/CHANGELOG.md
Normal file
707
repos/effect/packages/atom/solid/CHANGELOG.md
Normal file
@@ -0,0 +1,707 @@
|
||||
# @effect/atom-solid
|
||||
|
||||
## 4.0.0-beta.99
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8ce4795`](https://github.com/Effect-TS/effect/commit/8ce4795ccbaebca4292757db568c005a992546a4), [`80b539f`](https://github.com/Effect-TS/effect/commit/80b539f8aba68f478c75c35c2b4140c4ffc4fada), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`e6e6dba`](https://github.com/Effect-TS/effect/commit/e6e6dba6e9d86e7c2ad27dcedf289db76a19697f), [`bfb203e`](https://github.com/Effect-TS/effect/commit/bfb203e95aa439f731acad37fc3a9a831a190f1c), [`2e9a34a`](https://github.com/Effect-TS/effect/commit/2e9a34ac2bece4f3a206160480c991e3841dc67a), [`55d4eb3`](https://github.com/Effect-TS/effect/commit/55d4eb34f2c64d54f6a25a305b5c5438ebd7934e), [`bddb010`](https://github.com/Effect-TS/effect/commit/bddb010eac3d4436cb094edbbee7460c5440c162), [`a328835`](https://github.com/Effect-TS/effect/commit/a328835e50d76bc96648a1c1550456e8c9f81210), [`5560d05`](https://github.com/Effect-TS/effect/commit/5560d05aa6abdd29466d9c3412cc5e648b0adbde), [`8f6e3ad`](https://github.com/Effect-TS/effect/commit/8f6e3adb185b16e8820b98c509b308086f7ff1af), [`46997fa`](https://github.com/Effect-TS/effect/commit/46997fa60401f5e3c93daa4b61f7df8e31caaab4), [`9e6e12d`](https://github.com/Effect-TS/effect/commit/9e6e12d75c118cd265496f2880490d1f33a5c8bf), [`3394b93`](https://github.com/Effect-TS/effect/commit/3394b93d97d6f24fc38670641d1490289ffca7f1), [`febeabc`](https://github.com/Effect-TS/effect/commit/febeabc3f7c31094da000a23edeaabfe2ab00a38), [`54161c9`](https://github.com/Effect-TS/effect/commit/54161c98f6f3569e0c31842f54e6a257f9421c4c), [`385f7a4`](https://github.com/Effect-TS/effect/commit/385f7a4ee4a7359928597ea56d151dbaf5eb5802), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`7543afe`](https://github.com/Effect-TS/effect/commit/7543afea6f4d97d1f1ad876224323838a48daadd), [`44b9cf3`](https://github.com/Effect-TS/effect/commit/44b9cf3d240d726997b4bbcd0ede48e074d3c456), [`7eea4d0`](https://github.com/Effect-TS/effect/commit/7eea4d0b73ec554915d7066a71f46326ce2ba45f), [`0a8aa6a`](https://github.com/Effect-TS/effect/commit/0a8aa6acb90a72b91c24d17133c950e4cacd8abd), [`c8d9fcf`](https://github.com/Effect-TS/effect/commit/c8d9fcf7b030f7c474effbab2764ce7aee1c7209), [`9ca7f9a`](https://github.com/Effect-TS/effect/commit/9ca7f9a69363e4485645966d5a93b8f9597c5206), [`e7aca89`](https://github.com/Effect-TS/effect/commit/e7aca894bb32fbb785b5830837e6061c415a6015), [`55d7560`](https://github.com/Effect-TS/effect/commit/55d75609b8acf8a1b54c1b1c7fbbb65ec741aa3e), [`f809189`](https://github.com/Effect-TS/effect/commit/f809189ddf6b6011ba43a9901baaa734e315da2a), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`0ebdbe7`](https://github.com/Effect-TS/effect/commit/0ebdbe74463dc84385956d0b1e8c2b79ebab5400), [`7517d09`](https://github.com/Effect-TS/effect/commit/7517d09f12a0b183a81bd425962c4e280a68b05d), [`212493b`](https://github.com/Effect-TS/effect/commit/212493b9a1eb98cd1ef6959c707a2e5784a5ae91), [`88a54cc`](https://github.com/Effect-TS/effect/commit/88a54cc341006e3ebcb13482c618f62a680ce199), [`80ea8cb`](https://github.com/Effect-TS/effect/commit/80ea8cb9222ca73f564c8267ab2f82966fea027a), [`8df19f4`](https://github.com/Effect-TS/effect/commit/8df19f4fe81d90cc33ace88b9a77e5534f82d604)]:
|
||||
- effect@4.0.0-beta.99
|
||||
|
||||
## 4.0.0-beta.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`989603b`](https://github.com/Effect-TS/effect-smol/commit/989603b60ab1197b64acf214208e0d370cd1f842), [`214c458`](https://github.com/Effect-TS/effect-smol/commit/214c458084bb6995d543cd37d1055f24be3d454e), [`a037273`](https://github.com/Effect-TS/effect-smol/commit/a0372736ac34796969b051bbba4717d7983f1ebe), [`97fdaa9`](https://github.com/Effect-TS/effect-smol/commit/97fdaa9c1f522c65e579365d314a07878e2b904f), [`b24d248`](https://github.com/Effect-TS/effect-smol/commit/b24d248c8df44222ce642087cde2bd859a2dc709), [`19c222c`](https://github.com/Effect-TS/effect-smol/commit/19c222cac2353a3d7b7733caecb00556fffe9a5c), [`eec85dd`](https://github.com/Effect-TS/effect-smol/commit/eec85ddba09ea326fd268ee33eeffd47e50d4671), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`8849052`](https://github.com/Effect-TS/effect-smol/commit/884905232d1e9a365e046d8dde27bf9c5707f57f), [`c15e16a`](https://github.com/Effect-TS/effect-smol/commit/c15e16ad130d1fbde25d912b7ac55995066cb35b), [`01d00a3`](https://github.com/Effect-TS/effect-smol/commit/01d00a3abfbf1f37996cdbe738ea5137c646cdd7), [`8bd4589`](https://github.com/Effect-TS/effect-smol/commit/8bd458975a1b3a8ed042eccf317b93d28ded91e7), [`0082f4f`](https://github.com/Effect-TS/effect-smol/commit/0082f4f74fb139fd578f87f0a790e845133983dc), [`6e08428`](https://github.com/Effect-TS/effect-smol/commit/6e08428d980501b856f846ad3f3f0e4ea46e7786), [`388dcf9`](https://github.com/Effect-TS/effect-smol/commit/388dcf953f65d317547f34d40e6443c5f264205f), [`2b7ce2b`](https://github.com/Effect-TS/effect-smol/commit/2b7ce2b513e7ec2a77822f1116dc6ffb6ba93f4e), [`87bea7e`](https://github.com/Effect-TS/effect-smol/commit/87bea7e16259246f3bcdf565446394751abca953), [`ce38dc3`](https://github.com/Effect-TS/effect-smol/commit/ce38dc33bda805a684432cca071f4dc3c6b9a1ba), [`a807cd1`](https://github.com/Effect-TS/effect-smol/commit/a807cd170341deca8a1cfb52c4222585f2431bb9), [`fd8a356`](https://github.com/Effect-TS/effect-smol/commit/fd8a356f06a8c9ce4e7e0a13fc4021c178ed31de), [`c2a5edc`](https://github.com/Effect-TS/effect-smol/commit/c2a5edc3abd31ad5bc123362bc1213e03e4095c3), [`5946da3`](https://github.com/Effect-TS/effect-smol/commit/5946da3804a1be5e752b05b96bd058cdba50a1bf), [`4ae0c5f`](https://github.com/Effect-TS/effect-smol/commit/4ae0c5ffcbe6c56ddfcb05c639112a079483539e), [`5b2a0bc`](https://github.com/Effect-TS/effect-smol/commit/5b2a0bceea3a28a33a58555210c90a415dc74a76), [`72ac585`](https://github.com/Effect-TS/effect-smol/commit/72ac585884befde6af9208da738699a93f1bae79), [`5e8c1b8`](https://github.com/Effect-TS/effect-smol/commit/5e8c1b82bfafa121311f987a49ab75395e3647a7), [`0f9c078`](https://github.com/Effect-TS/effect-smol/commit/0f9c07841b04183f485ee6e6458de73b290b09f5)]:
|
||||
- effect@4.0.0-beta.98
|
||||
|
||||
## 4.0.0-beta.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.97
|
||||
|
||||
## 4.0.0-beta.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1503f45`](https://github.com/Effect-TS/effect-smol/commit/1503f45cb5bb2a74f4705252ec505a1f0ade7e62), [`57fe793`](https://github.com/Effect-TS/effect-smol/commit/57fe79316ffbc380b30626a168981fb26ae97459), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`0c2f78f`](https://github.com/Effect-TS/effect-smol/commit/0c2f78f695ec474e1ff5474da183577975e418f5), [`97f29df`](https://github.com/Effect-TS/effect-smol/commit/97f29df457f7ffd07cfb4b379315c12c086af805)]:
|
||||
- effect@4.0.0-beta.96
|
||||
|
||||
## 4.0.0-beta.95
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a482442`](https://github.com/Effect-TS/effect-smol/commit/a482442abdeb490e9652b854ec3495e4aa7273e7), [`fbefa85`](https://github.com/Effect-TS/effect-smol/commit/fbefa850fab2f0a302c20614496aeaaa2a8b5590), [`0b4a32f`](https://github.com/Effect-TS/effect-smol/commit/0b4a32f4260f0d8500942a133001b0d349328102), [`18a49e1`](https://github.com/Effect-TS/effect-smol/commit/18a49e1786679456258002ff9397faf02f678c2d), [`266cb90`](https://github.com/Effect-TS/effect-smol/commit/266cb90bb2c17aabc40563c32db334f09ba3d74b), [`912f095`](https://github.com/Effect-TS/effect-smol/commit/912f095a34572bbd3cedf6edb27878443e3e4a95), [`a6718f9`](https://github.com/Effect-TS/effect-smol/commit/a6718f9e00a15ca903b0732da46116cbf3d6aca7), [`bef5154`](https://github.com/Effect-TS/effect-smol/commit/bef51540a243aa2f872a00c01d0cd58b7a769baa), [`18e0564`](https://github.com/Effect-TS/effect-smol/commit/18e0564bd0f8ebbdfcaf1e2c21529948e9e4a81d), [`fb50f14`](https://github.com/Effect-TS/effect-smol/commit/fb50f14fc3657c1973785aa5b72ecf0b0d28e0b2)]:
|
||||
- effect@4.0.0-beta.95
|
||||
|
||||
## 4.0.0-beta.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`95a0e9b`](https://github.com/Effect-TS/effect-smol/commit/95a0e9bb62797af0e81c9998773405f248f218c5), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63), [`f11ce73`](https://github.com/Effect-TS/effect-smol/commit/f11ce73af60823754dc24194f4ffc561b9ea1c2d), [`ff30b6e`](https://github.com/Effect-TS/effect-smol/commit/ff30b6e7c2c63ffc56a4c5818d6d86b01b5ad528), [`1caab3c`](https://github.com/Effect-TS/effect-smol/commit/1caab3cc30f626efbf15e59d74f539a487e5c85c), [`aa80c47`](https://github.com/Effect-TS/effect-smol/commit/aa80c4775a04db87553e5568764cab7e32a72814), [`c2ae4fc`](https://github.com/Effect-TS/effect-smol/commit/c2ae4fce2f03a4cd1861c2b1179da7df656e662d), [`a0a3490`](https://github.com/Effect-TS/effect-smol/commit/a0a3490bbce765f199d8e077aceac504f0462e63)]:
|
||||
- effect@4.0.0-beta.94
|
||||
|
||||
## 4.0.0-beta.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`00652fe`](https://github.com/Effect-TS/effect-smol/commit/00652fe95c18f87208e91343eb8bf218faa2f677), [`6c58167`](https://github.com/Effect-TS/effect-smol/commit/6c5816746eaf91d2a3c7c899c5720809fa230ae3), [`2bc5415`](https://github.com/Effect-TS/effect-smol/commit/2bc541501a7ef89e542d7cb98e96beb53cd205cc), [`e11cccc`](https://github.com/Effect-TS/effect-smol/commit/e11cccc7d5fe631abccc7d6e3bd296938de0fa2e), [`ba7e77e`](https://github.com/Effect-TS/effect-smol/commit/ba7e77e046b8641a3a4e9750bb88ca4a1d063d3f), [`5713ee7`](https://github.com/Effect-TS/effect-smol/commit/5713ee7edbc3054efde407b2286bbfd45bbc6e1c)]:
|
||||
- effect@4.0.0-beta.93
|
||||
|
||||
## 4.0.0-beta.92
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`affdc13`](https://github.com/Effect-TS/effect-smol/commit/affdc139045cc325dce321a84a580fdc1b2da7b9)]:
|
||||
- effect@4.0.0-beta.92
|
||||
|
||||
## 4.0.0-beta.91
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b135b25`](https://github.com/Effect-TS/effect-smol/commit/b135b2517fca9e7839734ace3699a7dfa75b9075), [`aaa21a3`](https://github.com/Effect-TS/effect-smol/commit/aaa21a369a171c600db294f2a4f640583043e150), [`3475ee6`](https://github.com/Effect-TS/effect-smol/commit/3475ee6c2bda6b05c6d7a12ce30c8bb840b5b1a6)]:
|
||||
- effect@4.0.0-beta.91
|
||||
|
||||
## 4.0.0-beta.90
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d237fdf`](https://github.com/Effect-TS/effect-smol/commit/d237fdf726481f76eb52a6196e111b24122bc3d5)]:
|
||||
- effect@4.0.0-beta.90
|
||||
|
||||
## 4.0.0-beta.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b7d46ab`](https://github.com/Effect-TS/effect-smol/commit/b7d46ab7e1a29d8711817bab583c9febf48a0dad), [`7777e15`](https://github.com/Effect-TS/effect-smol/commit/7777e1540fd3680dd8346723cffec812b9384669), [`5376197`](https://github.com/Effect-TS/effect-smol/commit/5376197ca8e50358a41b1fd3cec27bd1ec680ec6)]:
|
||||
- effect@4.0.0-beta.89
|
||||
|
||||
## 4.0.0-beta.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`911f1b8`](https://github.com/Effect-TS/effect-smol/commit/911f1b84790ce42b3a70c95b33e6f6fd9e74de8b), [`8beeeea`](https://github.com/Effect-TS/effect-smol/commit/8beeeea52879d8613a39468848f01c3092bd54d4), [`c306fcf`](https://github.com/Effect-TS/effect-smol/commit/c306fcfeb1ef38455156932a1faf49292b1318da)]:
|
||||
- effect@4.0.0-beta.88
|
||||
|
||||
## 4.0.0-beta.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a0c1a4`](https://github.com/Effect-TS/effect-smol/commit/5a0c1a4faee5707b5cc35e646ff1ffdad70f1956), [`1eea2ea`](https://github.com/Effect-TS/effect-smol/commit/1eea2ea3795ba47316b82b1ac8d4612c0ba389ed)]:
|
||||
- effect@4.0.0-beta.87
|
||||
|
||||
## 4.0.0-beta.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0b5795a`](https://github.com/Effect-TS/effect-smol/commit/0b5795a0ab4395e8f15955d8d96f2303084bfc64), [`3e3a859`](https://github.com/Effect-TS/effect-smol/commit/3e3a859ec6351a9e0d31674aabbd48fcefabb12e), [`7dbec24`](https://github.com/Effect-TS/effect-smol/commit/7dbec240dbf3bca599a20c486632abce694ef5ab), [`d8c00a1`](https://github.com/Effect-TS/effect-smol/commit/d8c00a171ac7141e8adc08c332d1162d9a9d56fc), [`85b6317`](https://github.com/Effect-TS/effect-smol/commit/85b631701e935866f2762bd595237aa718370cd9), [`6d0fda0`](https://github.com/Effect-TS/effect-smol/commit/6d0fda0d0cbdfffc523c89c57dfdb1608f84fb12), [`108a933`](https://github.com/Effect-TS/effect-smol/commit/108a9335ff8571928197e5847a09c28ac83d6f46), [`7e1f455`](https://github.com/Effect-TS/effect-smol/commit/7e1f455fab5005d769b939c91e519d450f802cf9), [`46b3e79`](https://github.com/Effect-TS/effect-smol/commit/46b3e79944cfdae7901eb148135c85b7eb39834e)]:
|
||||
- effect@4.0.0-beta.86
|
||||
|
||||
## 4.0.0-beta.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`328d97c`](https://github.com/Effect-TS/effect-smol/commit/328d97cc53c0dcb89077a5623e35b095eaa59a8c), [`8441836`](https://github.com/Effect-TS/effect-smol/commit/8441836e6dde70e8ae2126be9cefe9b45798b134), [`074e436`](https://github.com/Effect-TS/effect-smol/commit/074e4361091289104cb0ab6959dc3b0ea7794a6a), [`c1dfd60`](https://github.com/Effect-TS/effect-smol/commit/c1dfd60663eb13a58916f3712d877499943b628a), [`2ba316b`](https://github.com/Effect-TS/effect-smol/commit/2ba316bd15fcbf1c50626500d44a2c9b3bec19f5), [`7ce7344`](https://github.com/Effect-TS/effect-smol/commit/7ce7344c41056c79e2ee19ee6a9346c0f1d227c1)]:
|
||||
- effect@4.0.0-beta.85
|
||||
|
||||
## 4.0.0-beta.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`87f52ba`](https://github.com/Effect-TS/effect-smol/commit/87f52ba16c4370ffa3f84bf8e53038e1419c284e), [`b8ee07f`](https://github.com/Effect-TS/effect-smol/commit/b8ee07ffda8903b5ec2e45a786ddcba59f128fda), [`867c0d7`](https://github.com/Effect-TS/effect-smol/commit/867c0d70a09079b040260d45a1e92ff04dbfbf2f), [`b93bc6c`](https://github.com/Effect-TS/effect-smol/commit/b93bc6c9cb27b909a41d094c97c4f9d25bbc6d6b), [`57d387f`](https://github.com/Effect-TS/effect-smol/commit/57d387f92c30ab63e15e3e641f0a903b65886610), [`bacca41`](https://github.com/Effect-TS/effect-smol/commit/bacca4141c2400effae1eabfdb36c89a459cf246), [`0f8ac79`](https://github.com/Effect-TS/effect-smol/commit/0f8ac7959d29ed68c68ce25aabd6bf0cb7e63ecc), [`25b4482`](https://github.com/Effect-TS/effect-smol/commit/25b448270c01317703f25107e1480d4cd0246d9a), [`9cf3a25`](https://github.com/Effect-TS/effect-smol/commit/9cf3a25c66b0c44a52be9829870c44517ea52db2), [`8def767`](https://github.com/Effect-TS/effect-smol/commit/8def7674b1787f91035298cda4d122937e87ef72)]:
|
||||
- effect@4.0.0-beta.84
|
||||
|
||||
## 4.0.0-beta.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1f2e8ce`](https://github.com/Effect-TS/effect-smol/commit/1f2e8ceef09e0a791c850ed2ade01f97089596f9)]:
|
||||
- effect@4.0.0-beta.83
|
||||
|
||||
## 4.0.0-beta.82
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`193690b`](https://github.com/Effect-TS/effect-smol/commit/193690b642ea802bbed40d663bd677251bbe9dc3)]:
|
||||
- effect@4.0.0-beta.82
|
||||
|
||||
## 4.0.0-beta.81
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`93cb4f8`](https://github.com/Effect-TS/effect-smol/commit/93cb4f8fbfb9e07cb9dc86ce6b155fd1f8167914), [`60341d9`](https://github.com/Effect-TS/effect-smol/commit/60341d9ca744d0473ce3fab621ca9bd225af3a39), [`1105ab5`](https://github.com/Effect-TS/effect-smol/commit/1105ab56cb724212f7ea7b431396ce82e8fd0484), [`4500fbf`](https://github.com/Effect-TS/effect-smol/commit/4500fbfe00763d8a72af6e5d6c5988e8bd4ade36)]:
|
||||
- effect@4.0.0-beta.81
|
||||
|
||||
## 4.0.0-beta.80
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d944330`](https://github.com/Effect-TS/effect-smol/commit/d94433090ee03f426d43e13b883abae4494e55e6), [`f48659f`](https://github.com/Effect-TS/effect-smol/commit/f48659fdcc84930ebc1e5b45b540c0f973389182), [`7652aaa`](https://github.com/Effect-TS/effect-smol/commit/7652aaa3bdbc39f241fe58b54b9a43b713e22e12), [`98630b7`](https://github.com/Effect-TS/effect-smol/commit/98630b7c8f679c352ba6796636c85688fa009d8d), [`90ae23c`](https://github.com/Effect-TS/effect-smol/commit/90ae23cf07284da5e1bcd9dffa882e85df7e617b)]:
|
||||
- effect@4.0.0-beta.80
|
||||
|
||||
## 4.0.0-beta.79
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b9704dc`](https://github.com/Effect-TS/effect-smol/commit/b9704dc9de9f1649ad502371014fe869b69a49a3), [`a207113`](https://github.com/Effect-TS/effect-smol/commit/a207113f66837bb54416926718a9a7d66774d079), [`5e9b9e2`](https://github.com/Effect-TS/effect-smol/commit/5e9b9e217b164ebfd4a002dd4380b3b1563200c3), [`7c128ae`](https://github.com/Effect-TS/effect-smol/commit/7c128aef458a1e2d224712e51c483c9badad1d44), [`0ada457`](https://github.com/Effect-TS/effect-smol/commit/0ada457c0513d8d908254ab77ebb7d29d2b523d6), [`d7cc5a2`](https://github.com/Effect-TS/effect-smol/commit/d7cc5a2bede3de10943aa0c6bdb4f26836a91efd), [`aad63be`](https://github.com/Effect-TS/effect-smol/commit/aad63becf65e0a6b076e94f8973be7bbe7fbd46f), [`09809f6`](https://github.com/Effect-TS/effect-smol/commit/09809f60f19ec98232f98b33e33e02ecb7e4fbd6), [`2fddda5`](https://github.com/Effect-TS/effect-smol/commit/2fddda5311929f46b61e503f0ade4fc749e8c77d), [`5f21768`](https://github.com/Effect-TS/effect-smol/commit/5f2176833399757c4500d8875b7f2fba0393de75), [`f27003e`](https://github.com/Effect-TS/effect-smol/commit/f27003e00524ff83f20dd9909f62b2f8795efe03)]:
|
||||
- effect@4.0.0-beta.79
|
||||
|
||||
## 4.0.0-beta.78
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7836b8e`](https://github.com/Effect-TS/effect-smol/commit/7836b8eb8bb0f3e04cdf554ee070caccf74f00c1), [`35d49a3`](https://github.com/Effect-TS/effect-smol/commit/35d49a3a09bdba6b513de87ddcead9e61a1042ba), [`4093258`](https://github.com/Effect-TS/effect-smol/commit/40932580e65bafab5f23c5f14b520cb411d0b2cd)]:
|
||||
- effect@4.0.0-beta.78
|
||||
|
||||
## 4.0.0-beta.77
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6e9a5ca`](https://github.com/Effect-TS/effect-smol/commit/6e9a5ca62a61156fd67b2518ad3ab14ac0d25f23), [`302f398`](https://github.com/Effect-TS/effect-smol/commit/302f3984ce206e35d86ddd99d3b72be144850a51)]:
|
||||
- effect@4.0.0-beta.77
|
||||
|
||||
## 4.0.0-beta.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`016108a`](https://github.com/Effect-TS/effect-smol/commit/016108a472af7048ddbbfd05f233e67529fafe12), [`95c03d2`](https://github.com/Effect-TS/effect-smol/commit/95c03d2c55930668c215b5a41c23cf7742fead84), [`07299a3`](https://github.com/Effect-TS/effect-smol/commit/07299a33c09fd52faa9810d30835a2622c752386)]:
|
||||
- effect@4.0.0-beta.76
|
||||
|
||||
## 4.0.0-beta.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`81b187c`](https://github.com/Effect-TS/effect-smol/commit/81b187c17a0d8817b58232826939154010ae49d7), [`ad4b535`](https://github.com/Effect-TS/effect-smol/commit/ad4b535e17f94ce35261829d5a3675f0a7808b4e), [`a29c2e7`](https://github.com/Effect-TS/effect-smol/commit/a29c2e7e3570920156702671d6f3367cd0195f6c), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`1fdd9ae`](https://github.com/Effect-TS/effect-smol/commit/1fdd9aeed92b6bb70987c862e7f6f66ead0339b3), [`ffea4ec`](https://github.com/Effect-TS/effect-smol/commit/ffea4ecf2925f6a4c9fd13079d47584cbf2bed00), [`4255c9b`](https://github.com/Effect-TS/effect-smol/commit/4255c9ba78bb98c7838fbe9dccdd8465e9da5427)]:
|
||||
- effect@4.0.0-beta.75
|
||||
|
||||
## 4.0.0-beta.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b1fc6a4`](https://github.com/Effect-TS/effect-smol/commit/b1fc6a4b4d0ca7fa9fd162799ae17c86f2f7ee8e)]:
|
||||
- effect@4.0.0-beta.74
|
||||
|
||||
## 4.0.0-beta.73
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`361ca30`](https://github.com/Effect-TS/effect-smol/commit/361ca30eb6e134feece547d6e00f82be4cb23f75), [`b9598c6`](https://github.com/Effect-TS/effect-smol/commit/b9598c6a209e75bfdb87ee3b024ecd1e3923ff6e)]:
|
||||
- effect@4.0.0-beta.73
|
||||
|
||||
## 4.0.0-beta.72
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`73e67d1`](https://github.com/Effect-TS/effect-smol/commit/73e67d119a84d697773eaecb4865c6a71eb1a9cb), [`01d71ec`](https://github.com/Effect-TS/effect-smol/commit/01d71ec5a75f3c2747a8d3b1ad9701d1e27b7ce5), [`fcd707e`](https://github.com/Effect-TS/effect-smol/commit/fcd707e091a16e1b35343c901cc4052274e32239)]:
|
||||
- effect@4.0.0-beta.72
|
||||
|
||||
## 4.0.0-beta.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d8ac76b`](https://github.com/Effect-TS/effect-smol/commit/d8ac76b5bad458c42cebe8a0c1b3843f955ac293), [`2c3c00a`](https://github.com/Effect-TS/effect-smol/commit/2c3c00af6faba7b7d422af26a7a2bbc35636d230), [`3751e7c`](https://github.com/Effect-TS/effect-smol/commit/3751e7cf353e7a54cd692c37401207d9afba1e63), [`fc5f25b`](https://github.com/Effect-TS/effect-smol/commit/fc5f25b03ada5fc2431987768a74d3d3e75ca485), [`7ccced4`](https://github.com/Effect-TS/effect-smol/commit/7ccced42867c14c013b01160b3d292f14c05bd04), [`a2e1fe5`](https://github.com/Effect-TS/effect-smol/commit/a2e1fe5835c98c8ee4393a091b1d11b75126e349), [`4a4a36b`](https://github.com/Effect-TS/effect-smol/commit/4a4a36b10e6e616cad07584a43908f6a7e07e618), [`d350292`](https://github.com/Effect-TS/effect-smol/commit/d3502922b4740fa9d745797cbc3775cb67839b6d), [`730afb6`](https://github.com/Effect-TS/effect-smol/commit/730afb66696adf9bd5a328cbca29df9c05968771), [`df1b008`](https://github.com/Effect-TS/effect-smol/commit/df1b008f370f414c2a67a7b8139ef747af8e5fba), [`6d469d5`](https://github.com/Effect-TS/effect-smol/commit/6d469d567a7c41d7e5343bdee21d45b07b0e8190)]:
|
||||
- effect@4.0.0-beta.71
|
||||
|
||||
## 4.0.0-beta.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af7782d`](https://github.com/Effect-TS/effect-smol/commit/af7782d3008d08b043f3a3f261516001514b2b4e), [`7212d70`](https://github.com/Effect-TS/effect-smol/commit/7212d701a3eee7b3553ff502e2c066126e52e839)]:
|
||||
- effect@4.0.0-beta.70
|
||||
|
||||
## 4.0.0-beta.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70ea04a`](https://github.com/Effect-TS/effect-smol/commit/70ea04aa96a2a7859d738d414e1f0e3ed081a27a), [`d0ea8b0`](https://github.com/Effect-TS/effect-smol/commit/d0ea8b03f7d73ae076c1db12666141e480d11178), [`a57674b`](https://github.com/Effect-TS/effect-smol/commit/a57674b64845e9e75a456cf907bfdcb858859118), [`59aa334`](https://github.com/Effect-TS/effect-smol/commit/59aa334fbd0a504dda3c36f6d2ef1be7449b4b8b), [`8f4208e`](https://github.com/Effect-TS/effect-smol/commit/8f4208ee83bc7bdaa6793b5429847b45aab72470)]:
|
||||
- effect@4.0.0-beta.69
|
||||
|
||||
## 4.0.0-beta.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`af8267f`](https://github.com/Effect-TS/effect-smol/commit/af8267f2f3588c3fb611e9286f6f933f29ce1217), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`0176eaf`](https://github.com/Effect-TS/effect-smol/commit/0176eaf3ecd7c1b99a10268f2af02d7e8ce161e5), [`f136bb7`](https://github.com/Effect-TS/effect-smol/commit/f136bb763048cbc6b17edd26496dba3e2415b9fa), [`6f38f07`](https://github.com/Effect-TS/effect-smol/commit/6f38f07d5941a211b251383aaab0f4f55e8a6557), [`aec9c40`](https://github.com/Effect-TS/effect-smol/commit/aec9c401a53db227f18bf5e0c84db7130ad862d6)]:
|
||||
- effect@4.0.0-beta.68
|
||||
|
||||
## 4.0.0-beta.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a42ef66`](https://github.com/Effect-TS/effect-smol/commit/a42ef6632abbddfa820995ae310ccc84ae8d9b6f), [`35594f8`](https://github.com/Effect-TS/effect-smol/commit/35594f811cafe471acd490114b103a1f8392c8d8), [`8bddd62`](https://github.com/Effect-TS/effect-smol/commit/8bddd628cb623f9533d345082583ff51cead6836), [`4be4c8d`](https://github.com/Effect-TS/effect-smol/commit/4be4c8d60862aa963869ee2ed9ffa048ffac0527), [`0c9d3ab`](https://github.com/Effect-TS/effect-smol/commit/0c9d3ab43eb721a370ed8306260cbac218c27e87), [`b156acc`](https://github.com/Effect-TS/effect-smol/commit/b156accd2691b4a051f823affdece7c39923ce85), [`d16c034`](https://github.com/Effect-TS/effect-smol/commit/d16c03434ee3e6dcd3bfc82b65d99e881d89025b), [`b559d68`](https://github.com/Effect-TS/effect-smol/commit/b559d68845f848a10153395778f035682d399075), [`a3de5d9`](https://github.com/Effect-TS/effect-smol/commit/a3de5d9215e5cc4a62e2666efbd7c1bf595eb84f), [`7e6c12e`](https://github.com/Effect-TS/effect-smol/commit/7e6c12ec9b3a5945f6c26e272cc8f6390541ad3e), [`098167a`](https://github.com/Effect-TS/effect-smol/commit/098167a220fe07da6f14455818733ab1b269c9dd)]:
|
||||
- effect@4.0.0-beta.67
|
||||
|
||||
## 4.0.0-beta.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ca2498e`](https://github.com/Effect-TS/effect-smol/commit/ca2498e702ac2d83fb7187707b7eb069bdb261a2), [`cd7d1fb`](https://github.com/Effect-TS/effect-smol/commit/cd7d1fba7e2e2c5ac3ad64e1be433440a5bda436), [`19a7033`](https://github.com/Effect-TS/effect-smol/commit/19a703367ec817cffc41d152da9b594827408e2b), [`33d26b4`](https://github.com/Effect-TS/effect-smol/commit/33d26b4210b2e974f146a71e7eed962f8ce00900), [`856766b`](https://github.com/Effect-TS/effect-smol/commit/856766b2c506aaed6d2df1d63bf3a5b1b062e1d4), [`079c7df`](https://github.com/Effect-TS/effect-smol/commit/079c7df82559bb9ce10a86dffb85d25e6ce07dc3)]:
|
||||
- effect@4.0.0-beta.66
|
||||
|
||||
## 4.0.0-beta.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6f11454`](https://github.com/Effect-TS/effect-smol/commit/6f11454a9b6c3bd00f6b35fd7af14a2f2d63a0a2)]:
|
||||
- effect@4.0.0-beta.65
|
||||
|
||||
## 4.0.0-beta.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d4877a`](https://github.com/Effect-TS/effect-smol/commit/7d4877a1929cdb690280ea254326c04f2ec97ea5)]:
|
||||
- effect@4.0.0-beta.64
|
||||
|
||||
## 4.0.0-beta.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7f927ff`](https://github.com/Effect-TS/effect-smol/commit/7f927ffb7a9801dcfc4096c29e369d13d65cd0ac), [`a696b3e`](https://github.com/Effect-TS/effect-smol/commit/a696b3e83a8504cdbe261a18c10a1cc0619ae102)]:
|
||||
- effect@4.0.0-beta.63
|
||||
|
||||
## 4.0.0-beta.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4ab4b90`](https://github.com/Effect-TS/effect-smol/commit/4ab4b9007dc27a52ffabc6fcb37c96eeec795bf7)]:
|
||||
- effect@4.0.0-beta.62
|
||||
|
||||
## 4.0.0-beta.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`50790af`](https://github.com/Effect-TS/effect-smol/commit/50790af9b190c38d10fb0723837d49b66432638f), [`71f7c3d`](https://github.com/Effect-TS/effect-smol/commit/71f7c3df997deda92c84146d569696dab3bd645c), [`aae8797`](https://github.com/Effect-TS/effect-smol/commit/aae8797b9cb383be0c182dd58d03d787c354238b)]:
|
||||
- effect@4.0.0-beta.61
|
||||
|
||||
## 4.0.0-beta.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f69d567`](https://github.com/Effect-TS/effect-smol/commit/f69d5675dcff9f4137295752baf066b7153fdc09), [`7909c95`](https://github.com/Effect-TS/effect-smol/commit/7909c954b8f6244a35a4b429f8dd0dff45dad620), [`bbb4dcc`](https://github.com/Effect-TS/effect-smol/commit/bbb4dcc6c406b83a416b4ad3541cc02037c420e4), [`7af2207`](https://github.com/Effect-TS/effect-smol/commit/7af2207901eabf3132c1b7010a69b3899c06fbbe), [`848b40a`](https://github.com/Effect-TS/effect-smol/commit/848b40a4bd4bf54a5098617d50c33c88eee8270a)]:
|
||||
- effect@4.0.0-beta.60
|
||||
|
||||
## 4.0.0-beta.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`56837ea`](https://github.com/Effect-TS/effect-smol/commit/56837ea2a338395b35550641374e9e589bd8b71d)]:
|
||||
- effect@4.0.0-beta.59
|
||||
|
||||
## 4.0.0-beta.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`11993d4`](https://github.com/Effect-TS/effect-smol/commit/11993d4934c66f5dc611b8bbf553f01d501ef8f7), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec), [`96c8b22`](https://github.com/Effect-TS/effect-smol/commit/96c8b22c2057ccddbf10ed269d7697f22119b3ec)]:
|
||||
- effect@4.0.0-beta.58
|
||||
|
||||
## 4.0.0-beta.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a971f5c`](https://github.com/Effect-TS/effect-smol/commit/a971f5cbd92dfe4274420bf0966595eb35531060), [`8e110c5`](https://github.com/Effect-TS/effect-smol/commit/8e110c5f02a429ccc43a91df8678e402138c0851)]:
|
||||
- effect@4.0.0-beta.57
|
||||
|
||||
## 4.0.0-beta.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.56
|
||||
|
||||
## 4.0.0-beta.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42cc744`](https://github.com/Effect-TS/effect-smol/commit/42cc744570968deb365fb46d47b53d3277050c93), [`04855ce`](https://github.com/Effect-TS/effect-smol/commit/04855ceeca4d40c55a5750dd9893b691f8ea741a)]:
|
||||
- effect@4.0.0-beta.55
|
||||
|
||||
## 4.0.0-beta.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e4b74f9`](https://github.com/Effect-TS/effect-smol/commit/e4b74f9c01a0e9b6cd58416de4af3a26d51da7c8), [`4c72808`](https://github.com/Effect-TS/effect-smol/commit/4c728081851c66dacf889a816535671bc841ae96)]:
|
||||
- effect@4.0.0-beta.54
|
||||
|
||||
## 4.0.0-beta.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0768509`](https://github.com/Effect-TS/effect-smol/commit/07685094e931af07d104165195826a535b55fa7e), [`476aede`](https://github.com/Effect-TS/effect-smol/commit/476aede69c6efa06b5781ca5eb3e3b128ca29141), [`4f79c54`](https://github.com/Effect-TS/effect-smol/commit/4f79c542e7b508c235ff485d862cc8b29a8260c5), [`4be6a7c`](https://github.com/Effect-TS/effect-smol/commit/4be6a7cf35dab2a01d652f56dd35f0358c5a7e88), [`88927eb`](https://github.com/Effect-TS/effect-smol/commit/88927ebb896162cdba103b36553280b58e0facac)]:
|
||||
- effect@4.0.0-beta.53
|
||||
|
||||
## 4.0.0-beta.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`cf3a311`](https://github.com/Effect-TS/effect-smol/commit/cf3a311d863a8abb818840c3b80f847e621c43c1), [`8e04bfc`](https://github.com/Effect-TS/effect-smol/commit/8e04bfc95554b74eac205d67a20388e056b21499), [`131fdd5`](https://github.com/Effect-TS/effect-smol/commit/131fdd5b1f26531e265fe1a08f002002f47c276e)]:
|
||||
- effect@4.0.0-beta.52
|
||||
|
||||
## 4.0.0-beta.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`778d2af`](https://github.com/Effect-TS/effect-smol/commit/778d2afe9b5154bc1f9abae46d93ea7e54c87344), [`4e24dcf`](https://github.com/Effect-TS/effect-smol/commit/4e24dcf75037f65eebc1eb68623bc7cbf9d5512a), [`4b1c015`](https://github.com/Effect-TS/effect-smol/commit/4b1c0150e9bdb5559ed32d250deb66e17b4240c7), [`454f8ad`](https://github.com/Effect-TS/effect-smol/commit/454f8adad822929c3ef60f8280d0987226b049fd), [`6754a0c`](https://github.com/Effect-TS/effect-smol/commit/6754a0cd18626b06805a079cc5265525a5eb7d27), [`90f7fd5`](https://github.com/Effect-TS/effect-smol/commit/90f7fd5243871b30980964135db4512b8119fa82), [`d7e1519`](https://github.com/Effect-TS/effect-smol/commit/d7e151974934201fd93fa4c8a1192ee9a5d965a0), [`72a8122`](https://github.com/Effect-TS/effect-smol/commit/72a81228e09782bae512f7d041bbfbc78bc668d0)]:
|
||||
- effect@4.0.0-beta.51
|
||||
|
||||
## 4.0.0-beta.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`07be594`](https://github.com/Effect-TS/effect-smol/commit/07be594825de60f8e1b2102d21dbb9b8fc63b414), [`ae02433`](https://github.com/Effect-TS/effect-smol/commit/ae02433103ce28f53a0c9bfb4a44e75773289b7b)]:
|
||||
- effect@4.0.0-beta.50
|
||||
|
||||
## 4.0.0-beta.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d87873`](https://github.com/Effect-TS/effect-smol/commit/7d8787340ff549370f6f2a88b612e9ebbfd6ba45), [`c2f6f90`](https://github.com/Effect-TS/effect-smol/commit/c2f6f901b200a6e515b4f02c93ce8005b7bbf1c5), [`216f13c`](https://github.com/Effect-TS/effect-smol/commit/216f13c1fce454a21b489bb915714a17e791a1ac)]:
|
||||
- effect@4.0.0-beta.49
|
||||
|
||||
## 4.0.0-beta.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4da56ec`](https://github.com/Effect-TS/effect-smol/commit/4da56ecff129b2da40137ffede23a73cc4e532d8), [`a5e6f77`](https://github.com/Effect-TS/effect-smol/commit/a5e6f774bab195cf50ecdc818240765f69a3bf4a), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070), [`f1ba5b8`](https://github.com/Effect-TS/effect-smol/commit/f1ba5b8584d325a541156928cecf041b37fd5070)]:
|
||||
- effect@4.0.0-beta.48
|
||||
|
||||
## 4.0.0-beta.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c584726`](https://github.com/Effect-TS/effect-smol/commit/c58472674e750e6938df955044eab88feda95e45), [`86a91a4`](https://github.com/Effect-TS/effect-smol/commit/86a91a4f0c59286dfa9393232d8020dea70ed4db), [`131caf9`](https://github.com/Effect-TS/effect-smol/commit/131caf9525151a0cb29803a8f1dffa0f4f479d12), [`c3615c8`](https://github.com/Effect-TS/effect-smol/commit/c3615c88379b9daf252df0db72c6ac5a20326406)]:
|
||||
- effect@4.0.0-beta.47
|
||||
|
||||
## 4.0.0-beta.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a30b9e`](https://github.com/Effect-TS/effect-smol/commit/3a30b9e2ec2bd8b8193e1aa139f6878a07e3f5ee)]:
|
||||
- effect@4.0.0-beta.46
|
||||
|
||||
## 4.0.0-beta.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c3af6d`](https://github.com/Effect-TS/effect-smol/commit/5c3af6d554f60be34f8fc21d598d9a298ae11beb)]:
|
||||
- effect@4.0.0-beta.45
|
||||
|
||||
## 4.0.0-beta.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1938](https://github.com/Effect-TS/effect-smol/pull/1938) [`23bbaac`](https://github.com/Effect-TS/effect-smol/commit/23bbaace8fd22a76e5f57aea8b4899374c40194e) Thanks @tim-smart! - allow atoms to be computed in solid bindings
|
||||
|
||||
- Updated dependencies [[`e3f0621`](https://github.com/Effect-TS/effect-smol/commit/e3f0621454c3f5d11070d30619da27c9232cadc1), [`5b476ab`](https://github.com/Effect-TS/effect-smol/commit/5b476abc0bd7e9bb59135ea1bcad2e4936227ced), [`6b40e5a`](https://github.com/Effect-TS/effect-smol/commit/6b40e5a4a6bd2087c15a3d7374d25057fdedfa16), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`3b09fb3`](https://github.com/Effect-TS/effect-smol/commit/3b09fb31c40c2802b01f21c23bcdd1fe7fb0aa82), [`2370410`](https://github.com/Effect-TS/effect-smol/commit/237041062e5af4594d32db91597e34e70a632877), [`dabc272`](https://github.com/Effect-TS/effect-smol/commit/dabc272444a700eb629c07ba3e77671a841ca86e), [`08b63c3`](https://github.com/Effect-TS/effect-smol/commit/08b63c3df11bd35c9fd6090dbd166287fdc40664), [`dfff04c`](https://github.com/Effect-TS/effect-smol/commit/dfff04c4c2b1d352dfad83992a6dce1280c85cf9), [`9baed9e`](https://github.com/Effect-TS/effect-smol/commit/9baed9e17e84702e6e480fcef6f86404f9e24be9), [`7846792`](https://github.com/Effect-TS/effect-smol/commit/7846792adc7e1631d62d26d657bd7ba6139f369b), [`1556a24`](https://github.com/Effect-TS/effect-smol/commit/1556a247623636b7ebe438fb56d77f1a7bf957bb), [`7c11bc2`](https://github.com/Effect-TS/effect-smol/commit/7c11bc292ab8e46252fe8f7576fb685917bfb8b5), [`b5ea591`](https://github.com/Effect-TS/effect-smol/commit/b5ea5913ec1d45d0dd12a327b9dd966bda2f6d02), [`0853afa`](https://github.com/Effect-TS/effect-smol/commit/0853afaeb1633b2d7f8b66893bd01c3aa1ef2c22), [`ac845f3`](https://github.com/Effect-TS/effect-smol/commit/ac845f3ab40e0b8719576e7f9bc16ea2e0e02cd4), [`b80c462`](https://github.com/Effect-TS/effect-smol/commit/b80c46247480f47bb64fc480fab48a3f37bc8888), [`b3f535d`](https://github.com/Effect-TS/effect-smol/commit/b3f535d9a7ac13b5fb984c29f93561c57a081ff0), [`6fe2e93`](https://github.com/Effect-TS/effect-smol/commit/6fe2e93cc2f1b173ef89651d74b6a5d2626b3226), [`cda8004`](https://github.com/Effect-TS/effect-smol/commit/cda800451c1ffbdddfc08415aed7b2d91e0412ee), [`8335477`](https://github.com/Effect-TS/effect-smol/commit/8335477a8a936a24b5f3ee6203c1b268bd1bfc3c), [`8c836f9`](https://github.com/Effect-TS/effect-smol/commit/8c836f99ab1e896b9580a71d67773625baff2eaf), [`718ff6f`](https://github.com/Effect-TS/effect-smol/commit/718ff6fe3e3d3820cefd67d2bff1b2224fe08060), [`7eed84f`](https://github.com/Effect-TS/effect-smol/commit/7eed84fc33c5781a6fb11bf4fd189d424902ebd4), [`5df46fe`](https://github.com/Effect-TS/effect-smol/commit/5df46fe2f654d59ab5fc1578f4fc27fa40368ef9), [`82dd0f2`](https://github.com/Effect-TS/effect-smol/commit/82dd0f26c6442b07143762ef7bc33742d3978dd6), [`03ae41e`](https://github.com/Effect-TS/effect-smol/commit/03ae41e7304cffac9f18feea22b73468feafc43a), [`4677a0a`](https://github.com/Effect-TS/effect-smol/commit/4677a0a58f95eea38a211efcd3f345f237a9e44a), [`87e1fc8`](https://github.com/Effect-TS/effect-smol/commit/87e1fc8b67e4901d75f567b2fecc3841ab762cc4), [`c1af1b7`](https://github.com/Effect-TS/effect-smol/commit/c1af1b756f63291e9c0298cf95c98a6920a0c2a0), [`7bb5dce`](https://github.com/Effect-TS/effect-smol/commit/7bb5dce60e1d904ef049a0287dec2b2e6113c970), [`c8a877b`](https://github.com/Effect-TS/effect-smol/commit/c8a877b53e8f29616335719e5dd1c3992dddf780), [`7da961a`](https://github.com/Effect-TS/effect-smol/commit/7da961ae4916229d2246699a5d3b20e5b2dd2020)]:
|
||||
- effect@4.0.0-beta.44
|
||||
|
||||
## 4.0.0-beta.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`2ae33d0`](https://github.com/Effect-TS/effect-smol/commit/2ae33d050914915f7cb9c25ab0a020901e08d596), [`979811a`](https://github.com/Effect-TS/effect-smol/commit/979811a4c3f7ed21ed18ef560c49fb7f5569e80e), [`eb7dbef`](https://github.com/Effect-TS/effect-smol/commit/eb7dbeffa883386ad912815e62c0820cac1fdf8e), [`cf50eb4`](https://github.com/Effect-TS/effect-smol/commit/cf50eb49cb04706dae5185f624708117c413dee8), [`1d046fe`](https://github.com/Effect-TS/effect-smol/commit/1d046fe484560e23f3e22cb23eec6433f8f1fa02)]:
|
||||
- effect@4.0.0-beta.43
|
||||
|
||||
## 4.0.0-beta.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`924e216`](https://github.com/Effect-TS/effect-smol/commit/924e216caa7e0bbf22e994a0cd2ce8b1f0f0b3ee), [`80e7f0c`](https://github.com/Effect-TS/effect-smol/commit/80e7f0cd9116e811e97b0ce30a77a8d1ecd072aa), [`f8328bf`](https://github.com/Effect-TS/effect-smol/commit/f8328bf0314da3dc7f31d314f94a5840e8d5217f), [`66d1c06`](https://github.com/Effect-TS/effect-smol/commit/66d1c06039079129707a230f7ad8c676439d7133), [`bee800b`](https://github.com/Effect-TS/effect-smol/commit/bee800bf285192a01bec72a7b7b51bc1159434e6), [`8930441`](https://github.com/Effect-TS/effect-smol/commit/8930441dee6f94c59c583d18d3ebd677cf1f2623)]:
|
||||
- effect@4.0.0-beta.42
|
||||
|
||||
## 4.0.0-beta.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`36f5c21`](https://github.com/Effect-TS/effect-smol/commit/36f5c2174d31ab42c4598bf81f178f40d0802283), [`d8ce758`](https://github.com/Effect-TS/effect-smol/commit/d8ce758669d6297ae932ac3251d83e7b49b22f30), [`11aab4c`](https://github.com/Effect-TS/effect-smol/commit/11aab4c6d37d5691adafc2d33da1a631b28ce814), [`3bc1efb`](https://github.com/Effect-TS/effect-smol/commit/3bc1efb53dd75b4a40de46f1f80c7f8a7d50af86), [`70e724e`](https://github.com/Effect-TS/effect-smol/commit/70e724e604604d4be1061cd8da0d360494998c84), [`738dee7`](https://github.com/Effect-TS/effect-smol/commit/738dee7edfd70af82dc4d2376db3a8ebe603eb48), [`2111963`](https://github.com/Effect-TS/effect-smol/commit/2111963f19b4c28c800664a8fac9590c1321885f), [`198a553`](https://github.com/Effect-TS/effect-smol/commit/198a553d9ce45f6a00bfc4d65ed0640669602d95)]:
|
||||
- effect@4.0.0-beta.41
|
||||
|
||||
## 4.0.0-beta.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f62860f`](https://github.com/Effect-TS/effect-smol/commit/f62860f0e5e45978fabf7256ae620a13152a772a), [`973f281`](https://github.com/Effect-TS/effect-smol/commit/973f2812529aadc1cc54598b2039799fa72b80f8)]:
|
||||
- effect@4.0.0-beta.40
|
||||
|
||||
## 4.0.0-beta.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f91fd3d`](https://github.com/Effect-TS/effect-smol/commit/f91fd3db39fe5628439fd175fba201a65a1aa9d0), [`edaae9d`](https://github.com/Effect-TS/effect-smol/commit/edaae9d65f464f941d7eddd723cd33d324f4b071), [`b47db0b`](https://github.com/Effect-TS/effect-smol/commit/b47db0bd5802064b6a24b3ea27c6ff2e0520d513), [`82d3c8e`](https://github.com/Effect-TS/effect-smol/commit/82d3c8e4f3f49b00df611b25aa6f8f74ec21b59b), [`7c22b31`](https://github.com/Effect-TS/effect-smol/commit/7c22b315d198dcbf44ae8cdb8b37879e1c9e3996)]:
|
||||
- effect@4.0.0-beta.39
|
||||
|
||||
## 4.0.0-beta.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f4dbe5b`](https://github.com/Effect-TS/effect-smol/commit/f4dbe5b26b9c2d33fae024bf44afbdf8541792cd), [`a71a607`](https://github.com/Effect-TS/effect-smol/commit/a71a607c89fb6669a12a562c2c23be81dfbe1adb), [`66a0494`](https://github.com/Effect-TS/effect-smol/commit/66a0494ed75cd12f2721dcbb1d8a072e3d9e14b6), [`5ef7218`](https://github.com/Effect-TS/effect-smol/commit/5ef7218fc559d57301fe929b8a0cab4033f4f1fd), [`472d260`](https://github.com/Effect-TS/effect-smol/commit/472d260655bc311fba5c2c6e23bb77d8f7e36ba0)]:
|
||||
- effect@4.0.0-beta.38
|
||||
|
||||
## 4.0.0-beta.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f7a0b71`](https://github.com/Effect-TS/effect-smol/commit/f7a0b711da8fdd645597dee29cacc5619c6afcf2), [`1e223c3`](https://github.com/Effect-TS/effect-smol/commit/1e223c30ccf835dfbb21284535d78549efaeca80), [`53740f4`](https://github.com/Effect-TS/effect-smol/commit/53740f47aa76d114b7d535649fb50efc54a09608), [`8c7cf89`](https://github.com/Effect-TS/effect-smol/commit/8c7cf89f719e580cbce1bf6c24e6996f1992a0a6), [`b6b81a9`](https://github.com/Effect-TS/effect-smol/commit/b6b81a940eaafcbc792d25413d6c02c707de31b2), [`8f4c1f9`](https://github.com/Effect-TS/effect-smol/commit/8f4c1f97ed60f8810b0b327b50117ffb2d8260d4), [`f2479f9`](https://github.com/Effect-TS/effect-smol/commit/f2479f9d3113b1f012db17a3852b4e28f478cf9c), [`c919921`](https://github.com/Effect-TS/effect-smol/commit/c9199217fad65529421d2cf95ecfff41257090fd), [`7af90c2`](https://github.com/Effect-TS/effect-smol/commit/7af90c2e3c99038eafa39650433839523790e2fe), [`f3be185`](https://github.com/Effect-TS/effect-smol/commit/f3be18569e5ca57c25eabf00df3ca601ebab43c7)]:
|
||||
- effect@4.0.0-beta.37
|
||||
|
||||
## 4.0.0-beta.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`60fcbcc`](https://github.com/Effect-TS/effect-smol/commit/60fcbcc43d09471e8f7e0969955d99dcefc5be81), [`0a60837`](https://github.com/Effect-TS/effect-smol/commit/0a6083713124440e630030375bab367e8d7df24e), [`49164d2`](https://github.com/Effect-TS/effect-smol/commit/49164d2c20a8d21b66514992c4a15d8521f6b36e), [`334b6e4`](https://github.com/Effect-TS/effect-smol/commit/334b6e4f76fe11941b516d61f57e268bc31f0ca6), [`5700695`](https://github.com/Effect-TS/effect-smol/commit/5700695f76ae6da6b94c9c87d4dd2b8054fb829b), [`f8f4456`](https://github.com/Effect-TS/effect-smol/commit/f8f445644f3aa7ec093cab7445198a62ba18a480), [`969d24f`](https://github.com/Effect-TS/effect-smol/commit/969d24fdfa48c4838e811983848d9cb4e9b3b12c), [`851eda0`](https://github.com/Effect-TS/effect-smol/commit/851eda0533946e39bacaaf581896320d7a4f3e8c), [`8059c1c`](https://github.com/Effect-TS/effect-smol/commit/8059c1c3eba9a90af7cd889ea261bcb8fff0c185), [`6f83295`](https://github.com/Effect-TS/effect-smol/commit/6f8329546a73eaddc7cb5e85ea8e37e73fbfb611), [`65f7f57`](https://github.com/Effect-TS/effect-smol/commit/65f7f5737575fed668987462c96d29a446707c32), [`e7fabd2`](https://github.com/Effect-TS/effect-smol/commit/e7fabd2265db690eae5cfc9b83730c84699aef61), [`89c3e98`](https://github.com/Effect-TS/effect-smol/commit/89c3e985401eb38f33a3ae21a94ad27de3c1d28b), [`53794ab`](https://github.com/Effect-TS/effect-smol/commit/53794ab7af30aa5c5004ecf53659fafbe4b10542)]:
|
||||
- effect@4.0.0-beta.36
|
||||
|
||||
## 4.0.0-beta.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9252b43`](https://github.com/Effect-TS/effect-smol/commit/9252b43560f507709c2985abcf52a7837b23ddf8), [`7daf387`](https://github.com/Effect-TS/effect-smol/commit/7daf3870a656882a488a60f67881e6808c8f4d04), [`e1664a3`](https://github.com/Effect-TS/effect-smol/commit/e1664a38bc31ef4ceb4e9324c7226e1e99bf9c07), [`fdaa6e0`](https://github.com/Effect-TS/effect-smol/commit/fdaa6e0a41b6b6605438fa8557441792135380a2), [`19aa47e`](https://github.com/Effect-TS/effect-smol/commit/19aa47ef7b470e427620edca8970dd9cdd551216), [`c667dad`](https://github.com/Effect-TS/effect-smol/commit/c667dad07777b860e4764a3ba9a6cc41c236cd98), [`764d150`](https://github.com/Effect-TS/effect-smol/commit/764d1501bc5026b60fc8aef6cb02a5a87c762801), [`3c27098`](https://github.com/Effect-TS/effect-smol/commit/3c27098b5685a63db2c2eff654a250c94d3fcfa7)]:
|
||||
- effect@4.0.0-beta.35
|
||||
|
||||
## 4.0.0-beta.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f2f75ee`](https://github.com/Effect-TS/effect-smol/commit/f2f75ee564bce1cd95f5189c7bdeeed4f92dacb1), [`342fc4b`](https://github.com/Effect-TS/effect-smol/commit/342fc4b051739e32e7977159f26ff9541eda664f), [`5d704ee`](https://github.com/Effect-TS/effect-smol/commit/5d704ee10d20e8eb107e34bb8a21feb5aa4a7685), [`00add69`](https://github.com/Effect-TS/effect-smol/commit/00add69b59551e9df34772eb927638b093f6d71e), [`58217d3`](https://github.com/Effect-TS/effect-smol/commit/58217d318a7d716ccd707cce0f41573946939c28), [`f4e2aba`](https://github.com/Effect-TS/effect-smol/commit/f4e2aba01b76d1e3059b297e3cc942284dfeafb2), [`e3b44b6`](https://github.com/Effect-TS/effect-smol/commit/e3b44b6a2af9ee21dc5c1e928f0c20af857fa7a9), [`e1472b7`](https://github.com/Effect-TS/effect-smol/commit/e1472b7525c5d57a48bdec2353c3b742f7f916c0), [`7686320`](https://github.com/Effect-TS/effect-smol/commit/7686320cd123fa352b5c3d076fb18a3cac0a9bba)]:
|
||||
- effect@4.0.0-beta.34
|
||||
|
||||
## 4.0.0-beta.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`571447d`](https://github.com/Effect-TS/effect-smol/commit/571447da67334449f8ae3d6ecb3d77ea4e0c4295)]:
|
||||
- effect@4.0.0-beta.33
|
||||
|
||||
## 4.0.0-beta.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf8fff8`](https://github.com/Effect-TS/effect-smol/commit/bf8fff8a5f54b6df74cb7bbb42346fe9ba52435a), [`1af3ef3`](https://github.com/Effect-TS/effect-smol/commit/1af3ef3e3ca7fd417d0fc15f8ca8fe207eba4f74), [`27fea0f`](https://github.com/Effect-TS/effect-smol/commit/27fea0f66910de5905f40fd63f8ddbb6f7ac5aba), [`2ad6c1b`](https://github.com/Effect-TS/effect-smol/commit/2ad6c1b2c85a3a0fe351e3d56636a75eb76b4b4e), [`398ac3e`](https://github.com/Effect-TS/effect-smol/commit/398ac3e01cb75efce0e4e2913d1450cf65866732), [`51fe22f`](https://github.com/Effect-TS/effect-smol/commit/51fe22f3266e417b6c541aaed4b75d246fac91e7), [`4605db6`](https://github.com/Effect-TS/effect-smol/commit/4605db69cfacddbdbf1525865ddfde135158090c), [`f4de1b0`](https://github.com/Effect-TS/effect-smol/commit/f4de1b087c998d0bad1d9468f70b7d16c13b9f6f), [`60214f2`](https://github.com/Effect-TS/effect-smol/commit/60214f2080b2aeb091f691140eb20acb741691c3), [`c4b8b0f`](https://github.com/Effect-TS/effect-smol/commit/c4b8b0ffa8efb47c4cd7578a8943d6868509373f), [`6d9393a`](https://github.com/Effect-TS/effect-smol/commit/6d9393a0770a18722d23340e77f15455de341245), [`6de4efe`](https://github.com/Effect-TS/effect-smol/commit/6de4efe463c783614ceb0c094d77a336a899cbe0), [`4f969d1`](https://github.com/Effect-TS/effect-smol/commit/4f969d1563ba755ffa116c8ae409bb3436bd881d), [`6cc67c8`](https://github.com/Effect-TS/effect-smol/commit/6cc67c855e054ee3f3ac3485dca5f7805e79e8fb), [`8531a22`](https://github.com/Effect-TS/effect-smol/commit/8531a22ffbb52e11a030b09f358cafbfdf5edff7), [`b226760`](https://github.com/Effect-TS/effect-smol/commit/b22676067617f15c00722a3a63fd7c2c172c3d45), [`47a51ab`](https://github.com/Effect-TS/effect-smol/commit/47a51aba0ecdf3ef478bfa28a498bca188399bd4), [`1521d02`](https://github.com/Effect-TS/effect-smol/commit/1521d02e1f19f1d795edaaf862c1a1031d9c755e)]:
|
||||
- effect@4.0.0-beta.32
|
||||
|
||||
## 4.0.0-beta.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6f23f0e`](https://github.com/Effect-TS/effect-smol/commit/6f23f0ed4cba573cd9395c2e582f582fe7271544), [`654aaec`](https://github.com/Effect-TS/effect-smol/commit/654aaec593305521b65dd042c204d761cc6e8c28), [`2958a42`](https://github.com/Effect-TS/effect-smol/commit/2958a42078966a8713a98f00485ab36484d5eccf), [`95d27a2`](https://github.com/Effect-TS/effect-smol/commit/95d27a239ed5147302605ab0b3147a056541b0c7), [`0fbaea8`](https://github.com/Effect-TS/effect-smol/commit/0fbaea8f9555a8044cec31a770394db613fc78e2), [`21d5d5e`](https://github.com/Effect-TS/effect-smol/commit/21d5d5e0439fd4d9bb6e508377215b1087555d45), [`5a84853`](https://github.com/Effect-TS/effect-smol/commit/5a8485397b7f321ae021640c1999821143659462), [`6e49959`](https://github.com/Effect-TS/effect-smol/commit/6e499590357a104c81779b3176cd3f84e4f91064), [`8f5805d`](https://github.com/Effect-TS/effect-smol/commit/8f5805dbdd0d1bc0ff0727cc398c8d80e544edee), [`990df2c`](https://github.com/Effect-TS/effect-smol/commit/990df2c3ceeb32e659acc10cc9485617f7b3c423)]:
|
||||
- effect@4.0.0-beta.31
|
||||
|
||||
## 4.0.0-beta.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c88e5b7`](https://github.com/Effect-TS/effect-smol/commit/c88e5b723ff09da4edaef6ce14d927ca01104a32), [`947d0e4`](https://github.com/Effect-TS/effect-smol/commit/947d0e4268ba5c4020ead380aa80812c7342408f), [`7517908`](https://github.com/Effect-TS/effect-smol/commit/75179085d159b88a1ab0bce70669d76dcf0d79a4), [`a49ecd5`](https://github.com/Effect-TS/effect-smol/commit/a49ecd5a183d7e7d33f47ff95e9d2dea5a12ead5), [`6993e33`](https://github.com/Effect-TS/effect-smol/commit/6993e3329122c834c20bacea72d8678232f4f103), [`514f2a2`](https://github.com/Effect-TS/effect-smol/commit/514f2a2ae54580fcacdbe2ea2196a83a852d0748), [`3214b47`](https://github.com/Effect-TS/effect-smol/commit/3214b47676de2d33fddc5fecfc2d226e6e83cc7b), [`95ec5ed`](https://github.com/Effect-TS/effect-smol/commit/95ec5ed345de77c893049e182d37a37cf164a268)]:
|
||||
- effect@4.0.0-beta.30
|
||||
|
||||
## 4.0.0-beta.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9d93adb`](https://github.com/Effect-TS/effect-smol/commit/9d93adb1c1795d1978391b30d7d2972c88052662), [`b52721c`](https://github.com/Effect-TS/effect-smol/commit/b52721cf0d11a567722b060c8536e3bdd4161f07), [`a891c7b`](https://github.com/Effect-TS/effect-smol/commit/a891c7b12f415b2287613dd4b91a09dfd38ef30d), [`ef26cdf`](https://github.com/Effect-TS/effect-smol/commit/ef26cdfb65d9955fc7e161629191930c2cc2c63f), [`82fd3ed`](https://github.com/Effect-TS/effect-smol/commit/82fd3ed922063ee5a34f96f3993c15c7515e4f67)]:
|
||||
- effect@4.0.0-beta.29
|
||||
|
||||
## 4.0.0-beta.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ff533f2`](https://github.com/Effect-TS/effect-smol/commit/ff533f203cd06302ad08032a27e01269b4a2d4c6), [`dc803ee`](https://github.com/Effect-TS/effect-smol/commit/dc803ee52ebd3e9f931118f0dfcb804542847556), [`d660b1c`](https://github.com/Effect-TS/effect-smol/commit/d660b1c99cb93d4f79715e91c7a4486801c0eefa), [`93a05e3`](https://github.com/Effect-TS/effect-smol/commit/93a05e3eaa624058b162aedd66aad70102837270), [`2a65cf6`](https://github.com/Effect-TS/effect-smol/commit/2a65cf6fd81ef63d944e6fb51f058d439bf4a834), [`a561a40`](https://github.com/Effect-TS/effect-smol/commit/a561a40cc41c548c2cf3153aca065ee92ee8aa57), [`29cd24d`](https://github.com/Effect-TS/effect-smol/commit/29cd24d1fe78480a72eeb38a90281ffddc0530bc), [`662a8e6`](https://github.com/Effect-TS/effect-smol/commit/662a8e6857dac64a7cd13bd8df4b0674654622f8), [`d2b52ba`](https://github.com/Effect-TS/effect-smol/commit/d2b52bae5b9336cf59729fbdcc4d7f09512b0cbf), [`407c3b4`](https://github.com/Effect-TS/effect-smol/commit/407c3b43a5d1414558e0e33b6f1fc0e6a6d489cc), [`42bc7ce`](https://github.com/Effect-TS/effect-smol/commit/42bc7ce5480f6f2953c39f8cb5c850d61df6f5a2), [`e741322`](https://github.com/Effect-TS/effect-smol/commit/e74132226cbfee24234311c7c1c13e6b7391384e), [`5c75fa8`](https://github.com/Effect-TS/effect-smol/commit/5c75fa8fb71163bc4c035ba1a215574dfd4badfc), [`747177b`](https://github.com/Effect-TS/effect-smol/commit/747177b0602f12d4461a843e953dfdffbeb0a429), [`326cd48`](https://github.com/Effect-TS/effect-smol/commit/326cd4828bce573fe985f35152155464bf4c5a70), [`627e922`](https://github.com/Effect-TS/effect-smol/commit/627e922b8d1e9521eae5e1caa5d667ad00b1619a), [`662287e`](https://github.com/Effect-TS/effect-smol/commit/662287e9abc76c941ccc2ee330aa07904d571341)]:
|
||||
- effect@4.0.0-beta.28
|
||||
|
||||
## 4.0.0-beta.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`903a839`](https://github.com/Effect-TS/effect-smol/commit/903a839e94239e6ec4568315af28e405bcad95f4), [`91a0168`](https://github.com/Effect-TS/effect-smol/commit/91a016836680a6669308ecf464d3584bcc4ae1b7), [`c890f9a`](https://github.com/Effect-TS/effect-smol/commit/c890f9a1b3a989ed22528bd5a43326342e05b142), [`1e985f2`](https://github.com/Effect-TS/effect-smol/commit/1e985f237d250b51b91de22dde77160c1e778ce7)]:
|
||||
- effect@4.0.0-beta.27
|
||||
|
||||
## 4.0.0-beta.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fb21462`](https://github.com/Effect-TS/effect-smol/commit/fb21462642cdd5b1bada92f3eba18ae20445be42), [`2ed26b1`](https://github.com/Effect-TS/effect-smol/commit/2ed26b139805700e3df39efaa768ff01565e5c86), [`e832a57`](https://github.com/Effect-TS/effect-smol/commit/e832a57b570fe38f010c1fd99bceac5a325a9e07), [`7f01be7`](https://github.com/Effect-TS/effect-smol/commit/7f01be7f8db363d4b2e88e6b5571e96bb815786f), [`e965143`](https://github.com/Effect-TS/effect-smol/commit/e9651431e114479e6becf8ca7b1ed99ac7e91ccc), [`b9b80f1`](https://github.com/Effect-TS/effect-smol/commit/b9b80f1f15e152ceef0a727d150b7dc230abae99), [`98252aa`](https://github.com/Effect-TS/effect-smol/commit/98252aa0c0b17fc73fbdad65d0a1104965f9fc0f), [`56fbd94`](https://github.com/Effect-TS/effect-smol/commit/56fbd94311ad19a05001ad649d9e34ab00c74541), [`3faa109`](https://github.com/Effect-TS/effect-smol/commit/3faa109b7d093fbf14ad410d3e11d663f16e28f1), [`692ecfe`](https://github.com/Effect-TS/effect-smol/commit/692ecfed99fe58056b7a5afe001f4fcd1a61c446), [`1e70b72`](https://github.com/Effect-TS/effect-smol/commit/1e70b72d0b210474d0e96a15a5cfc279eae37e0c), [`ecf0782`](https://github.com/Effect-TS/effect-smol/commit/ecf07829ef2dfc01d8943c96c4fe9c1b44b97926)]:
|
||||
- effect@4.0.0-beta.26
|
||||
|
||||
## 4.0.0-beta.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fa17bb5`](https://github.com/Effect-TS/effect-smol/commit/fa17bb5be9f2533d01e11322b14804c7dec43714), [`f46e5b5`](https://github.com/Effect-TS/effect-smol/commit/f46e5b5ca2a918ee4d9270167e79db223077c96f), [`ce4767c`](https://github.com/Effect-TS/effect-smol/commit/ce4767cadcacc6ce8ff4c3a0d0fbc82ede655f63), [`c830a8b`](https://github.com/Effect-TS/effect-smol/commit/c830a8b6c292a6528d7f9318759d34800b00372d)]:
|
||||
- effect@4.0.0-beta.25
|
||||
|
||||
## 4.0.0-beta.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a909e1c`](https://github.com/Effect-TS/effect-smol/commit/a909e1c1ac2bc707527f5073776e3e7d239688d9), [`8814a4e`](https://github.com/Effect-TS/effect-smol/commit/8814a4ef78d67144d27689370af10099ea210399), [`3f942c5`](https://github.com/Effect-TS/effect-smol/commit/3f942c51cefa7b2ffa7c49e8c8a2c887570ba4c0), [`774ed59`](https://github.com/Effect-TS/effect-smol/commit/774ed59c52b2ab578bbb897c4f551f812231e1d2), [`f54b8d3`](https://github.com/Effect-TS/effect-smol/commit/f54b8d398fedad1815fd1f4c49814ab938cfc385)]:
|
||||
- effect@4.0.0-beta.24
|
||||
|
||||
## 4.0.0-beta.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5c73c41`](https://github.com/Effect-TS/effect-smol/commit/5c73c41b69eaeab80fcd62c9bfda490b446d1966)]:
|
||||
- effect@4.0.0-beta.23
|
||||
|
||||
## 4.0.0-beta.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0874332`](https://github.com/Effect-TS/effect-smol/commit/0874332f7c81118b06ac2eb105e0710211631479), [`c592dcd`](https://github.com/Effect-TS/effect-smol/commit/c592dcde0697e322065c8f418c0480ef910cb183), [`1dbe28d`](https://github.com/Effect-TS/effect-smol/commit/1dbe28dac8299cd3e218c9768450cfd173b5e294), [`564d730`](https://github.com/Effect-TS/effect-smol/commit/564d730b6bbf38dd8548a3b046e7a693b28699a4), [`3cfadc4`](https://github.com/Effect-TS/effect-smol/commit/3cfadc458b070c6cba6c5674b72a059f1e49118b), [`6634fd0`](https://github.com/Effect-TS/effect-smol/commit/6634fd07da067d80b8261fb2959d1a952b9e412e), [`d10dabe`](https://github.com/Effect-TS/effect-smol/commit/d10dabeb7af9a368f995829cd36ad08167cd8f95), [`f82f549`](https://github.com/Effect-TS/effect-smol/commit/f82f549a09e950e9d4987f279a800f4d953f0939), [`78a3382`](https://github.com/Effect-TS/effect-smol/commit/78a3382ddfbe034408f7480fa794733d9e82147b)]:
|
||||
- effect@4.0.0-beta.22
|
||||
|
||||
## 4.0.0-beta.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e691909`](https://github.com/Effect-TS/effect-smol/commit/e691909495ccb162ea7bfa351dd74632b99997cb), [`d5f413f`](https://github.com/Effect-TS/effect-smol/commit/d5f413f3c8fc57f2413cc5649c2003d6d4e5a6d7), [`139d152`](https://github.com/Effect-TS/effect-smol/commit/139d152941e562a073b5be12e8d66c8a4d4a8a57), [`947e3d4`](https://github.com/Effect-TS/effect-smol/commit/947e3d436ab8a017efda9b29be523efd1ca8df28), [`84b2cce`](https://github.com/Effect-TS/effect-smol/commit/84b2ccefe2aa3a7413b86738a4dc33cdb311ca55), [`7f5305e`](https://github.com/Effect-TS/effect-smol/commit/7f5305e69f5a33309e77b08a576edb25d7daaee2), [`9e6fd84`](https://github.com/Effect-TS/effect-smol/commit/9e6fd8471c93a3c643929151a3bdb62cb9c0ca0e), [`fdb8a4b`](https://github.com/Effect-TS/effect-smol/commit/fdb8a4b172721fbefe98bd5aa6fe4f0efd1da3eb), [`0f986ef`](https://github.com/Effect-TS/effect-smol/commit/0f986ef22f196fe091a7afdbd179485a7d888882), [`9355fc0`](https://github.com/Effect-TS/effect-smol/commit/9355fc0ffb5b7382146a5aed9eea83974b10d007)]:
|
||||
- effect@4.0.0-beta.21
|
||||
|
||||
## 4.0.0-beta.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`842a624`](https://github.com/Effect-TS/effect-smol/commit/842a624f79d5e1407460b0ef3ab27d14d48ccf74), [`4785eef`](https://github.com/Effect-TS/effect-smol/commit/4785eef5d7cf1edb96ef2509aed2ba4d1edf3862), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`12ee8e2`](https://github.com/Effect-TS/effect-smol/commit/12ee8e27df7eb393d83a5e403390d0cfc82ca732), [`e542c94`](https://github.com/Effect-TS/effect-smol/commit/e542c942bee4729138b02222f4421220a90a57d8), [`8fac95b`](https://github.com/Effect-TS/effect-smol/commit/8fac95bd9e0338b7a82da8da579c1ac22afa045c), [`6f4ebd1`](https://github.com/Effect-TS/effect-smol/commit/6f4ebd193c2595983394127dd808601b75430d34), [`989d1cc`](https://github.com/Effect-TS/effect-smol/commit/989d1cca936fce0cc459057825ba40e3f5ef3827)]:
|
||||
- effect@4.0.0-beta.20
|
||||
|
||||
## 4.0.0-beta.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- effect@4.0.0-beta.19
|
||||
|
||||
## 4.0.0-beta.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`01e31fd`](https://github.com/Effect-TS/effect-smol/commit/01e31fdf8e5206849d23cbafd23a346f2f177ab8), [`0890aab`](https://github.com/Effect-TS/effect-smol/commit/0890aab15ed9c5ba52c383a72fdc6a444d7504d5), [`725260b`](https://github.com/Effect-TS/effect-smol/commit/725260b53f5142d6af7a93a2f9f464f974eda92d)]:
|
||||
- effect@4.0.0-beta.18
|
||||
|
||||
## 4.0.0-beta.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8f59c32`](https://github.com/Effect-TS/effect-smol/commit/8f59c32922597a48392744f7203e284866747781)]:
|
||||
- effect@4.0.0-beta.17
|
||||
|
||||
## 4.0.0-beta.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bf9096c`](https://github.com/Effect-TS/effect-smol/commit/bf9096c52a7d8791d93d232739e523eb84f6625a), [`29f81ca`](https://github.com/Effect-TS/effect-smol/commit/29f81ca07c67dba265804b140a7487fb15a5fc6b), [`68eb28c`](https://github.com/Effect-TS/effect-smol/commit/68eb28c2b0fc67a9f6204ade9bd16c5b37803bfb)]:
|
||||
- effect@4.0.0-beta.16
|
||||
|
||||
## 4.0.0-beta.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`24ae609`](https://github.com/Effect-TS/effect-smol/commit/24ae60995d2fd7d621be356cdfdfd328c79639ba), [`0e3c059`](https://github.com/Effect-TS/effect-smol/commit/0e3c059987caa55ebd0c134f7c7b147c639c328e), [`e843b0a`](https://github.com/Effect-TS/effect-smol/commit/e843b0a7d7e7b600a0b3bd477f24e2e4cd26bc8b), [`f4389a2`](https://github.com/Effect-TS/effect-smol/commit/f4389a2cca3c5bbf00d69779f52ce41255f15a28), [`5b73de0`](https://github.com/Effect-TS/effect-smol/commit/5b73de095b3402d0c5c74092ace6ce18ebfad566), [`595d2d6`](https://github.com/Effect-TS/effect-smol/commit/595d2d6e7d50419f3532bd39266191532ace38f2)]:
|
||||
- effect@4.0.0-beta.15
|
||||
|
||||
## 4.0.0-beta.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c414700`](https://github.com/Effect-TS/effect-smol/commit/c414700ef1932e4b67d0102856de417336912350), [`a30c969`](https://github.com/Effect-TS/effect-smol/commit/a30c9699c0d736cf3952041e45d508b7d58907a9)]:
|
||||
- effect@4.0.0-beta.14
|
||||
|
||||
## 4.0.0-beta.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`368f4c3`](https://github.com/Effect-TS/effect-smol/commit/368f4c363dd117e6f5a19ad77b161176cfd29fdd), [`db8a579`](https://github.com/Effect-TS/effect-smol/commit/db8a579e93e93ff73b1e60712732e03b597b916b), [`668b703`](https://github.com/Effect-TS/effect-smol/commit/668b70337e9ddbb0d1ae2282a95c282ce404e562), [`d40e76b`](https://github.com/Effect-TS/effect-smol/commit/d40e76b973543979e60e04a6baca04a8c65bdfc2), [`6e18cf8`](https://github.com/Effect-TS/effect-smol/commit/6e18cf883e9905ca718a6697b6a2a4bbd42739aa), [`86062e8`](https://github.com/Effect-TS/effect-smol/commit/86062e8a0c61bca5412fc40d2cf151d676901f08), [`c27ce75`](https://github.com/Effect-TS/effect-smol/commit/c27ce75d34c74dcfc6dba1bf77f1ce88f410a0de), [`e2d4fbf`](https://github.com/Effect-TS/effect-smol/commit/e2d4fbfeeda6a5d2a4c5aeb0501d8240c248b9eb), [`114ab42`](https://github.com/Effect-TS/effect-smol/commit/114ab42ad0edc590d29169675a493e0e915aa58f), [`484caec`](https://github.com/Effect-TS/effect-smol/commit/484caec47cccac8b86db2910742e406dfc7173ab)]:
|
||||
- effect@4.0.0-beta.13
|
||||
|
||||
## 4.0.0-beta.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`70a74e8`](https://github.com/Effect-TS/effect-smol/commit/70a74e88a8767c9d4acdb9e5f25aec9a33588d07), [`b5b6e10`](https://github.com/Effect-TS/effect-smol/commit/b5b6e10621d54bf8c9857fec0d647ced78ecd857), [`f5ce5a9`](https://github.com/Effect-TS/effect-smol/commit/f5ce5a915359c6ebf254079e1da23cab6cde34fb), [`a29eb70`](https://github.com/Effect-TS/effect-smol/commit/a29eb702ffe3fc58bd28c4d7857298cd65d73668), [`c7b36e5`](https://github.com/Effect-TS/effect-smol/commit/c7b36e541a23e9a00f64e25b23851e51a37dfce5), [`9381d6d`](https://github.com/Effect-TS/effect-smol/commit/9381d6d4d9d819a81a46e56d0364c76e92a4fbca), [`88439f1`](https://github.com/Effect-TS/effect-smol/commit/88439f13ca13549f3e4822c48c4f019c14fc2bcc), [`e35307d`](https://github.com/Effect-TS/effect-smol/commit/e35307dbeb8eb26a9923f958b894a8eaaf259bf2), [`c7df4bc`](https://github.com/Effect-TS/effect-smol/commit/c7df4bce34009474c63d62a807abfdafb76971eb), [`accaf3b`](https://github.com/Effect-TS/effect-smol/commit/accaf3be7ac8da36e2334c509c23b8c9e88ea160), [`3e1c270`](https://github.com/Effect-TS/effect-smol/commit/3e1c2707bbdf67720af1509642b8ced195790882), [`6cd81f7`](https://github.com/Effect-TS/effect-smol/commit/6cd81f73baad86f5bbfa455a55d75cde71e9611a), [`f222da3`](https://github.com/Effect-TS/effect-smol/commit/f222da3cdb44554f3324c2c52d0d005ee575053e), [`61f901d`](https://github.com/Effect-TS/effect-smol/commit/61f901d830005b66e22d1de889fda132aeea97cd)]:
|
||||
- effect@4.0.0-beta.12
|
||||
|
||||
## 4.0.0-beta.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`88659ed`](https://github.com/Effect-TS/effect-smol/commit/88659edb26e3623d557dccfe914c2c949672da16), [`f2915e8`](https://github.com/Effect-TS/effect-smol/commit/f2915e8e2efe80d50c281e53f297b9701d6dc199), [`eb71ace`](https://github.com/Effect-TS/effect-smol/commit/eb71acebbe0f228e4920278013beee3b67d62310), [`2a16999`](https://github.com/Effect-TS/effect-smol/commit/2a169996c7513d377ac47adbfd68e1490457135c), [`d42dd52`](https://github.com/Effect-TS/effect-smol/commit/d42dd52f11203f8e749fb5d3ecf7153e4a5a6814), [`339adaf`](https://github.com/Effect-TS/effect-smol/commit/339adaf850a62a892adebcb208c2d9dddf3b97b3), [`de19645`](https://github.com/Effect-TS/effect-smol/commit/de1964526d01102dd1cb99c8cfdd3e8df1f49ef1), [`9b1dc3b`](https://github.com/Effect-TS/effect-smol/commit/9b1dc3bcf2a1b68d0a67e3465db5ad01a1a56997), [`e4cb2f5`](https://github.com/Effect-TS/effect-smol/commit/e4cb2f55b30f4771ec1bf613ced36d6d96464dd5), [`8bced95`](https://github.com/Effect-TS/effect-smol/commit/8bced954ecb35d4489197a57b0efe927e7d75f49), [`9431420`](https://github.com/Effect-TS/effect-smol/commit/94314207c8019918200fbcb97aec992219f801f0), [`948dca2`](https://github.com/Effect-TS/effect-smol/commit/948dca22e4f672ba7a6db57f9899272bec7c08b8), [`d18e327`](https://github.com/Effect-TS/effect-smol/commit/d18e32765a2665e31ffb31e746bf983fcfac34c5), [`ab512f7`](https://github.com/Effect-TS/effect-smol/commit/ab512f7be1c0e6b359da921e22cd4944e4c57d3e)]:
|
||||
- effect@4.0.0-beta.11
|
||||
|
||||
## 4.0.0-beta.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`371acab`](https://github.com/Effect-TS/effect-smol/commit/371acabb58d56f3a7a5e3e33d3d5fdc9f5573c74), [`856d774`](https://github.com/Effect-TS/effect-smol/commit/856d7741f1e296dd5048c6ff2b44b95d023e6ae4), [`b9e9202`](https://github.com/Effect-TS/effect-smol/commit/b9e92023c38caa322975d77cfe83e2d34ac9305a), [`1d1a974`](https://github.com/Effect-TS/effect-smol/commit/1d1a974bd280c81bff5d4505491cda03ba7a3f36), [`6bfe2a6`](https://github.com/Effect-TS/effect-smol/commit/6bfe2a659bc6335db75709931f405da45301cba2), [`b12c811`](https://github.com/Effect-TS/effect-smol/commit/b12c81157be287b1649c210616a244b50ec094d2), [`d17d98a`](https://github.com/Effect-TS/effect-smol/commit/d17d98ad78e2b44d95ef434adab79ac3c35e75ab), [`68c3c7c`](https://github.com/Effect-TS/effect-smol/commit/68c3c7cb1e06ed94fa5c4c123a234b4ccbfdecd8)]:
|
||||
- effect@4.0.0-beta.10
|
||||
|
||||
## 4.0.0-beta.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3386557`](https://github.com/Effect-TS/effect-smol/commit/338655731564a7be9f8859dedbf4d5bcac6eb350), [`b6666e3`](https://github.com/Effect-TS/effect-smol/commit/b6666e3cf6bd44ba1a8704e65c256c30359cb422)]:
|
||||
- effect@4.0.0-beta.9
|
||||
|
||||
## 4.0.0-beta.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`246e672`](https://github.com/Effect-TS/effect-smol/commit/246e672dbbd7848d60e0c78fd66671b2f10b3752), [`807dec0`](https://github.com/Effect-TS/effect-smol/commit/807dec03801b4c58a6d00c237b6d98d6386911df)]:
|
||||
- effect@4.0.0-beta.8
|
||||
|
||||
## 4.0.0-beta.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a2bda6d`](https://github.com/Effect-TS/effect-smol/commit/a2bda6d4ef6de9d9b0c53ae2df5434f778d6161a), [`1f95a2b`](https://github.com/Effect-TS/effect-smol/commit/1f95a2b5aa9524bb38f4437f4691a664bf463ca1), [`a8d5e79`](https://github.com/Effect-TS/effect-smol/commit/a8d5e792fec201a83af0eb92fc79928d055125fd), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`a5386ba`](https://github.com/Effect-TS/effect-smol/commit/a5386ba67005dff697d45a45398f398773f58dcf), [`06d8a03`](https://github.com/Effect-TS/effect-smol/commit/06d8a0391631e6130e3ab25227e59817852e227f), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430), [`f9e883e`](https://github.com/Effect-TS/effect-smol/commit/f9e883e266fbda870336ee62f46b7ac85ba3de6e), [`8caac76`](https://github.com/Effect-TS/effect-smol/commit/8caac76a35821edfe03c75dab5eb056e8fc05430)]:
|
||||
- effect@4.0.0-beta.7
|
||||
|
||||
## 4.0.0-beta.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3247da2`](https://github.com/Effect-TS/effect-smol/commit/3247da28331f345f68be5dbd2974a7e03d300fe1), [`f205705`](https://github.com/Effect-TS/effect-smol/commit/f2057050dbd034b8c186be2d40c3d03ee63a5a3b), [`f35022c`](https://github.com/Effect-TS/effect-smol/commit/f35022c212e4111527e1bb43f360a67b2b49fa85), [`8622721`](https://github.com/Effect-TS/effect-smol/commit/86227217b02d43680a3c6f3c21731b1d852c91f5), [`fc660ab`](https://github.com/Effect-TS/effect-smol/commit/fc660ab8b5ebae38b8d6b96cbf2f9b880cc09253), [`f37dc33`](https://github.com/Effect-TS/effect-smol/commit/f37dc335f64622fa9ce8d6d1d5dd8fc3f260257b), [`3662f32`](https://github.com/Effect-TS/effect-smol/commit/3662f328fcfa3b2fa01ffa79da40e12e93fcede8), [`a7d436f`](https://github.com/Effect-TS/effect-smol/commit/a7d436f438dcd7f49b9485e4e95a4511f31fad7d), [`6856a41`](https://github.com/Effect-TS/effect-smol/commit/6856a415d7eddd9d73d60919e976f1d071421be4), [`8c417d0`](https://github.com/Effect-TS/effect-smol/commit/8c417d03475e5e12d00dca0c4781d0af7e66b86c), [`5419570`](https://github.com/Effect-TS/effect-smol/commit/5419570ba47ce882a3a10882707b46f66e464906), [`449c5ed`](https://github.com/Effect-TS/effect-smol/commit/449c5ed5318e8a874e730420bcf52918fa2ec80f), [`4b5ec12`](https://github.com/Effect-TS/effect-smol/commit/4b5ec12f87f95f2a3cd8fe4d5b26c6eb0529381a), [`df87937`](https://github.com/Effect-TS/effect-smol/commit/df879375fc3b169c43f9c434b3775e12b80dffe4), [`5dbfca8`](https://github.com/Effect-TS/effect-smol/commit/5dbfca8d1dbb6d18d1605d4f8562e99c86e2ff11), [`e629497`](https://github.com/Effect-TS/effect-smol/commit/e6294973d55597ab6b6deca6babbe1e946b2c91d), [`981c991`](https://github.com/Effect-TS/effect-smol/commit/981c991cd78db34def815d5754379d737157f005), [`1ca2ed6`](https://github.com/Effect-TS/effect-smol/commit/1ca2ed67301a5dc40ae0ed94346b99f26fd22bbe), [`45722bd`](https://github.com/Effect-TS/effect-smol/commit/45722bde974458311f11ad237711363a10ec6894), [`eb2a85e`](https://github.com/Effect-TS/effect-smol/commit/eb2a85ed4dc162b2535d304799333a5a20477fd0)]:
|
||||
- effect@4.0.0-beta.6
|
||||
|
||||
## 4.0.0-beta.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f6e133e`](https://github.com/Effect-TS/effect-smol/commit/f6e133e9a16b32317bd09ff08c12b97a0ae44600), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8), [`a88e206`](https://github.com/Effect-TS/effect-smol/commit/a88e206e44dc66ca5a2b45bedc797877c5dbb083), [`e3893cc`](https://github.com/Effect-TS/effect-smol/commit/e3893ccf2632338c7d8e745f639dcd825a9d42f8)]:
|
||||
- effect@4.0.0-beta.5
|
||||
|
||||
## 4.0.0-beta.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c5a18ef`](https://github.com/Effect-TS/effect-smol/commit/c5a18ef44171e3880bf983faee74529908974b32), [`bc6b885`](https://github.com/Effect-TS/effect-smol/commit/bc6b885b94d887a200657c0775dfa874dc15bc0c)]:
|
||||
- effect@4.0.0-beta.4
|
||||
|
||||
## 4.0.0-beta.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3a0cf36`](https://github.com/Effect-TS/effect-smol/commit/3a0cf36eff106ba48d74e133c1598cd40613e530), [`c4da328`](https://github.com/Effect-TS/effect-smol/commit/c4da328d32fad1d61e0e538f5d371edf61521d7e)]:
|
||||
- effect@4.0.0-beta.3
|
||||
|
||||
## 4.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a22ce73`](https://github.com/Effect-TS/effect-smol/commit/a22ce73b2bd9305b7ba665694d2255c0e6d5a8d0), [`ebdabf7`](https://github.com/Effect-TS/effect-smol/commit/ebdabf79ff4e62c8384aa8cf9a8d2787d536ee78), [`8f663bb`](https://github.com/Effect-TS/effect-smol/commit/8f663bb121021bf12bd264e8ae385187cb7a5dae)]:
|
||||
- effect@4.0.0-beta.2
|
||||
|
||||
## 4.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0fecf70`](https://github.com/Effect-TS/effect-smol/commit/0fecf70048057623eed7c584a06671773a2b1743), [`709569e`](https://github.com/Effect-TS/effect-smol/commit/709569ed76bead9ebb0670599e4d890a07ca5a43)]:
|
||||
- effect@4.0.0-beta.1
|
||||
|
||||
## 4.0.0-beta.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#1183](https://github.com/Effect-TS/effect-smol/pull/1183) [`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66) Thanks @tim-smart! - v4 beta
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be642ab`](https://github.com/Effect-TS/effect-smol/commit/be642ab1b3b4cd49e53c9732d7aba1b367fddd66)]:
|
||||
- effect@4.0.0-beta.0
|
||||
21
repos/effect/packages/atom/solid/LICENSE
Normal file
21
repos/effect/packages/atom/solid/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023-present The Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
7
repos/effect/packages/atom/solid/README.md
Normal file
7
repos/effect/packages/atom/solid/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# `@effect/atom-solid`
|
||||
|
||||
SolidJS bindings for the Effect Atom modules.
|
||||
|
||||
## Documentation
|
||||
|
||||
- **API Reference**: [View the full documentation](https://effect-ts.github.io/effect/docs/atom-solid).
|
||||
25
repos/effect/packages/atom/solid/docgen.json
Normal file
25
repos/effect/packages/atom/solid/docgen.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/@effect/docgen/schema.json",
|
||||
"projectHomepage": "https://effect-ts.github.io/effect/docs/atom-solid",
|
||||
"srcLink": "https://github.com/Effect-TS/effect/tree/main/packages/atom/solid/src/",
|
||||
"enforceVersion": true,
|
||||
"exclude": ["src/internal/**/*.ts"],
|
||||
"examplesCompilerOptions": {
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "Bundler",
|
||||
"module": "ES2022",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"rewriteRelativeImportExtensions": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"paths": {
|
||||
"effect": ["../../../effect/src/index.js"],
|
||||
"effect/*": ["../../../effect/src/*.js"]
|
||||
},
|
||||
"plugins": [
|
||||
{ "name": "@effect/language-service", "includeSuggestionsInTsc": false }
|
||||
]
|
||||
}
|
||||
}
|
||||
71
repos/effect/packages/atom/solid/package.json
Normal file
71
repos/effect/packages/atom/solid/package.json
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "@effect/atom-solid",
|
||||
"version": "4.0.0-beta.99",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "SolidJS bindings for the Effect Atom modules",
|
||||
"homepage": "https://effect.website",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Effect-TS/effect.git",
|
||||
"directory": "packages/atom/solid"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Effect-TS/effect/issues"
|
||||
},
|
||||
"tags": [
|
||||
"typescript",
|
||||
"solid",
|
||||
"database"
|
||||
],
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"solid",
|
||||
"database"
|
||||
],
|
||||
"sideEffects": [],
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts",
|
||||
"./*": "./src/*.ts",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
},
|
||||
"files": [
|
||||
"src/**/*.ts",
|
||||
"dist/**/*.js",
|
||||
"dist/**/*.js.map",
|
||||
"dist/**/*.d.ts",
|
||||
"dist/**/*.d.ts.map"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"provenance": true,
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./dist/index.js",
|
||||
"./*": "./dist/*.js",
|
||||
"./internal/*": null,
|
||||
"./*/index": null
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -b tsconfig.json && pnpm babel",
|
||||
"babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
||||
"check": "tsc -b tsconfig.json",
|
||||
"test": "vitest",
|
||||
"coverage": "vitest --coverage"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "workspace:^",
|
||||
"solid-js": ">=1 <2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@solidjs/testing-library": "^0.8.0",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"effect": "workspace:^",
|
||||
"jsdom": "^29.1.1",
|
||||
"solid-js": "^1.9.14"
|
||||
}
|
||||
}
|
||||
359
repos/effect/packages/atom/solid/src/Hooks.ts
Normal file
359
repos/effect/packages/atom/solid/src/Hooks.ts
Normal file
@@ -0,0 +1,359 @@
|
||||
/**
|
||||
* Solid hooks for using Effect Atoms from components and computations. The
|
||||
* hooks read and write atoms through the current `RegistryContext`, mount atoms
|
||||
* for cleanup, subscribe callbacks, seed initial values, expose `AsyncResult`
|
||||
* atoms as Solid resources, and read values from `AtomRef` references.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import * as Cause from "effect/Cause"
|
||||
import * as Effect from "effect/Effect"
|
||||
import * as Exit from "effect/Exit"
|
||||
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
||||
import * as Atom from "effect/unstable/reactivity/Atom"
|
||||
import type * as AtomRef from "effect/unstable/reactivity/AtomRef"
|
||||
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
||||
import type { Accessor, ResourceOptions, ResourceReturn } from "solid-js"
|
||||
import { createComputed, createEffect, createMemo, createResource, createSignal, onCleanup, useContext } from "solid-js"
|
||||
import { RegistryContext } from "./RegistryContext.ts"
|
||||
|
||||
const initialValuesSet = new WeakMap<AtomRegistry.AtomRegistry, WeakSet<Atom.Atom<any>>>()
|
||||
|
||||
/**
|
||||
* Seeds initial atom values in the current Solid atom registry.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to seed atom values from a Solid component after the current registry
|
||||
* already exists.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* For each atom in the current registry, this hook applies the first value
|
||||
* supplied through the hook. Later calls for the same atom in that registry are
|
||||
* ignored.
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomInitialValues = (initialValues: Iterable<readonly [Atom.Atom<any>, any]>): void => {
|
||||
const registry = useContext(RegistryContext)
|
||||
let set = initialValuesSet.get(registry)
|
||||
if (set === undefined) {
|
||||
set = new WeakSet()
|
||||
initialValuesSet.set(registry, set)
|
||||
}
|
||||
for (const [atom, value] of initialValues) {
|
||||
if (!set.has(atom)) {
|
||||
set.add(atom)
|
||||
;(registry as any).ensureNode(atom).setValue(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes to an atom in the current Solid registry and returns its value as
|
||||
* a Solid accessor.
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomValue: {
|
||||
<A>(atom: () => Atom.Atom<A>): Accessor<A>
|
||||
<A, B>(atom: () => Atom.Atom<A>, f: (_: A) => B): Accessor<B>
|
||||
} = <A>(atom: () => Atom.Atom<A>, f?: (_: A) => A): Accessor<A> => {
|
||||
const registry = useContext(RegistryContext)
|
||||
return createAtomAccessor(registry, f ? () => Atom.map(atom(), f) : atom)
|
||||
}
|
||||
|
||||
function createAtomAccessor<A>(registry: AtomRegistry.AtomRegistry, atom: () => Atom.Atom<A>): Accessor<A> {
|
||||
const [value, setValue] = createSignal<A>(null as any)
|
||||
createComputed(() => {
|
||||
onCleanup(registry.subscribe(atom(), setValue as any, constImmediate))
|
||||
})
|
||||
return value
|
||||
}
|
||||
|
||||
const constImmediate = { immediate: true }
|
||||
|
||||
function mountAtom<A>(registry: AtomRegistry.AtomRegistry, atom: () => Atom.Atom<A>): void {
|
||||
createComputed(() => {
|
||||
onCleanup(registry.mount(atom()))
|
||||
})
|
||||
}
|
||||
|
||||
function setAtom<R, W, Mode extends "value" | "promise" | "promiseExit" = never>(
|
||||
registry: AtomRegistry.AtomRegistry,
|
||||
atom: () => Atom.Writable<R, W>,
|
||||
options?: {
|
||||
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
||||
}
|
||||
): "promise" extends Mode ? (
|
||||
(value: W) => Promise<AsyncResult.AsyncResult.Success<R>>
|
||||
) :
|
||||
"promiseExit" extends Mode ? (
|
||||
(value: W) => Promise<Exit.Exit<AsyncResult.AsyncResult.Success<R>, AsyncResult.AsyncResult.Failure<R>>>
|
||||
) :
|
||||
((value: W | ((value: R) => W)) => void)
|
||||
{
|
||||
const memo = createMemo(atom)
|
||||
if (options?.mode === "promise" || options?.mode === "promiseExit") {
|
||||
return ((value: W) => {
|
||||
registry.set(memo(), value)
|
||||
const promise = Effect.runPromiseExit(
|
||||
AtomRegistry.getResult(registry, memo() as Atom.Atom<AsyncResult.AsyncResult<any, any>>, {
|
||||
suspendOnWaiting: true
|
||||
})
|
||||
)
|
||||
return options!.mode === "promise" ? promise.then(flattenExit) : promise
|
||||
}) as any
|
||||
}
|
||||
return ((value: W | ((value: R) => W)) => {
|
||||
registry.set(memo(), typeof value === "function" ? (value as any)(registry.get(memo())) : value)
|
||||
}) as any
|
||||
}
|
||||
|
||||
const flattenExit = <A, E>(exit: Exit.Exit<A, E>): A => {
|
||||
if (Exit.isSuccess(exit)) return exit.value
|
||||
throw Cause.squash(exit.cause)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mounts an atom in the current Solid registry for the lifetime of the current
|
||||
* Solid computation.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to keep an atom mounted from a Solid owner without reading, writing, or
|
||||
* refreshing it.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The hook uses the current `RegistryContext`, mounts inside a Solid
|
||||
* computation, and releases the mount through Solid cleanup when the
|
||||
* computation changes or the owner is disposed.
|
||||
*
|
||||
* @see {@link useAtomSet} for mounting a writable atom while returning a setter
|
||||
* @see {@link useAtomRefresh} for mounting an atom while returning a refresh callback
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomMount = <A>(atom: () => Atom.Atom<A>): void => {
|
||||
const registry = useContext(RegistryContext)
|
||||
mountAtom(registry, atom)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a setter for a writable atom without subscribing to its value.
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomSet = <
|
||||
R,
|
||||
W,
|
||||
Mode extends "value" | "promise" | "promiseExit" = never
|
||||
>(
|
||||
atom: () => Atom.Writable<R, W>,
|
||||
options?: {
|
||||
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
||||
}
|
||||
): "promise" extends Mode ? (
|
||||
(value: W) => Promise<AsyncResult.AsyncResult.Success<R>>
|
||||
) :
|
||||
"promiseExit" extends Mode ? (
|
||||
(value: W) => Promise<Exit.Exit<AsyncResult.AsyncResult.Success<R>, AsyncResult.AsyncResult.Failure<R>>>
|
||||
) :
|
||||
((value: W | ((value: R) => W)) => void) =>
|
||||
{
|
||||
const registry = useContext(RegistryContext)
|
||||
mountAtom(registry, atom)
|
||||
return setAtom(registry, atom, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mounts an atom and returns a callback that refreshes the current atom.
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomRefresh = <A>(atom: () => Atom.Atom<A>): () => void => {
|
||||
const registry = useContext(RegistryContext)
|
||||
mountAtom(registry, atom)
|
||||
const memo = createMemo(atom)
|
||||
return () => registry.refresh(memo())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Solid accessor for a writable atom together with a setter for
|
||||
* updating it.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a Solid component or computation needs both a reactive accessor for
|
||||
* a writable atom and a write function for that same atom.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The setter accepts either a write value or an updater function. For
|
||||
* `AsyncResult` atoms, `promise` and `promiseExit` modes return promises for the
|
||||
* success value or full `Exit`.
|
||||
*
|
||||
* @see {@link useAtomValue} for subscribing to an atom without a setter
|
||||
* @see {@link useAtomSet} for updating a writable atom without subscribing to its value
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtom = <R, W, const Mode extends "value" | "promise" | "promiseExit" = never>(
|
||||
atom: () => Atom.Writable<R, W>,
|
||||
options?: {
|
||||
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
||||
}
|
||||
): readonly [
|
||||
value: Accessor<R>,
|
||||
write: "promise" extends Mode ? (
|
||||
(value: W) => Promise<AsyncResult.AsyncResult.Success<R>>
|
||||
) :
|
||||
"promiseExit" extends Mode ? (
|
||||
(value: W) => Promise<Exit.Exit<AsyncResult.AsyncResult.Success<R>, AsyncResult.AsyncResult.Failure<R>>>
|
||||
) :
|
||||
((value: W | ((value: R) => W)) => void)
|
||||
] => {
|
||||
const registry = useContext(RegistryContext)
|
||||
return [
|
||||
createAtomAccessor(registry, atom),
|
||||
setAtom(registry, atom, options)
|
||||
] as const
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes a callback to an atom in the current Solid registry.
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomSubscribe = <A>(
|
||||
atom: () => Atom.Atom<A>,
|
||||
f: (_: A) => void,
|
||||
options?: { readonly immediate?: boolean }
|
||||
): void => {
|
||||
const registry = useContext(RegistryContext)
|
||||
createEffect(() => {
|
||||
onCleanup(registry.subscribe(atom(), f, options))
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an `AsyncResult` atom into a Solid resource.
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomResource = <A, E>(
|
||||
atom: () => Atom.Atom<AsyncResult.AsyncResult<A, E>>,
|
||||
options?: ResourceOptions<A> & {
|
||||
readonly suspendOnWaiting?: boolean | undefined
|
||||
}
|
||||
): ResourceReturn<A, void> => {
|
||||
const result = useAtomValue(atom)
|
||||
return createResource(result, (result) => {
|
||||
if (AsyncResult.isInitial(result) || (options?.suspendOnWaiting && result.waiting)) {
|
||||
return constUnresolvedPromise
|
||||
} else if (AsyncResult.isSuccess(result)) {
|
||||
return Promise.resolve(result.value)
|
||||
}
|
||||
return Promise.reject(Cause.squash(result.cause))
|
||||
})
|
||||
}
|
||||
|
||||
const constUnresolvedPromise = new Promise<never>(() => {})
|
||||
|
||||
/**
|
||||
* Subscribes to an atom ref and returns its value as a Solid accessor.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a Solid component or computation should render from an
|
||||
* `AtomRef.ReadonlyRef` directly instead of reading an atom through the current
|
||||
* registry.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The hook accepts a thunk for the ref, reads `ref().value`, subscribes with
|
||||
* `ref.subscribe`, and releases the subscription through Solid cleanup when
|
||||
* the selected ref changes or the owner is disposed.
|
||||
*
|
||||
* @see {@link useAtomValue} for reading an `Atom` from the current registry
|
||||
* @see {@link useAtomRefPropValue} for reading a property ref value
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomRef = <A>(ref: () => AtomRef.ReadonlyRef<A>): Accessor<A> => {
|
||||
const [value, setValue] = createSignal(null as A)
|
||||
createComputed(() => {
|
||||
const r = ref()
|
||||
setValue(r.value as any)
|
||||
onCleanup(r.subscribe(setValue))
|
||||
})
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Solid accessor for a property ref derived from an atom ref.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to derive an `AtomRef` for one property of an object-shaped atom ref in a
|
||||
* Solid computation.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The returned accessor memoizes `ref().prop(prop)`, updating when the source
|
||||
* ref thunk produces a different ref.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
||||
* the property key should change.
|
||||
*
|
||||
* @see {@link useAtomRef} for subscribing to an atom ref value
|
||||
* @see {@link useAtomRefPropValue} for subscribing directly to a property value
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomRefProp = <A, K extends keyof A>(
|
||||
ref: () => AtomRef.AtomRef<A>,
|
||||
prop: K
|
||||
): Accessor<AtomRef.AtomRef<A[K]>> => createMemo(() => ref().prop(prop))
|
||||
|
||||
/**
|
||||
* Returns a Solid accessor for the value of a property ref derived from an atom
|
||||
* ref.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when a Solid component or computation needs the value of one property
|
||||
* from an object-shaped `AtomRef` without keeping the intermediate property ref.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The hook composes `useAtomRefProp(ref, prop)` with `useAtomRef`, returning a
|
||||
* Solid accessor for the selected property value.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
||||
* the property key should change.
|
||||
*
|
||||
* @see {@link useAtomRef} for subscribing to a whole atom ref value
|
||||
* @see {@link useAtomRefProp} for returning the property ref directly
|
||||
*
|
||||
* @category hooks
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const useAtomRefPropValue = <A, K extends keyof A>(ref: () => AtomRef.AtomRef<A>, prop: K): Accessor<A[K]> =>
|
||||
useAtomRef(useAtomRefProp(ref, prop))
|
||||
80
repos/effect/packages/atom/solid/src/RegistryContext.ts
Normal file
80
repos/effect/packages/atom/solid/src/RegistryContext.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Solid context and provider for the Atom registry used by Effect Atom hooks.
|
||||
* The registry stores atom values, schedules update work, and cleans up unused
|
||||
* atoms. Sharing one registry through Solid context lets components and
|
||||
* computations in the same owner tree read and write the same atom state.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
import type * as Atom from "effect/unstable/reactivity/Atom"
|
||||
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
||||
import type { JSX } from "solid-js"
|
||||
import { createComponent, createContext, onCleanup } from "solid-js"
|
||||
|
||||
/**
|
||||
* Provides a Solid context that carries the `AtomRegistry` used by atom hooks in the
|
||||
* current owner tree.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use when you need to integrate lower-level Solid context APIs, such as custom
|
||||
* providers or hooks, instead of using the default atom hook setup.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* When no provider is present, the context uses a standalone default registry.
|
||||
*
|
||||
* @see {@link RegistryProvider} for creating and providing a registry for a Solid subtree
|
||||
*
|
||||
* @category context
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const RegistryContext = createContext<AtomRegistry.AtomRegistry>(AtomRegistry.make())
|
||||
|
||||
/**
|
||||
* Creates an `AtomRegistry` for a Solid subtree, optionally seeding initial atom
|
||||
* values and scheduler settings, and disposes the registry when the owner is
|
||||
* cleaned up.
|
||||
*
|
||||
* **When to use**
|
||||
*
|
||||
* Use to scope atom state, scheduling, and cleanup to a Solid subtree.
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* The provider creates an `AtomRegistry` with `AtomRegistry.make`, forwards
|
||||
* `initialValues`, `scheduleTask`, `timeoutResolution`, and
|
||||
* `defaultIdleTTL`, and supplies the registry through `RegistryContext`.
|
||||
*
|
||||
* **Gotchas**
|
||||
*
|
||||
* Provider options are consumed when the registry is created; they are not
|
||||
* reactive updates. A custom `scheduleTask` should return a cancellation
|
||||
* function that is safe to call during Solid cleanup.
|
||||
*
|
||||
* @see {@link RegistryContext} for the context supplied by this provider
|
||||
*
|
||||
* @category context
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export const RegistryProvider = (options: {
|
||||
readonly children?: JSX.Element | undefined
|
||||
readonly initialValues?: Iterable<readonly [Atom.Atom<any>, any]> | undefined
|
||||
readonly scheduleTask?: ((f: () => void) => () => void) | undefined
|
||||
readonly timeoutResolution?: number | undefined
|
||||
readonly defaultIdleTTL?: number | undefined
|
||||
}) => {
|
||||
const registry = AtomRegistry.make({
|
||||
scheduleTask: options.scheduleTask,
|
||||
initialValues: options.initialValues,
|
||||
timeoutResolution: options.timeoutResolution,
|
||||
defaultIdleTTL: options.defaultIdleTTL ?? 400
|
||||
})
|
||||
onCleanup(() => registry.dispose())
|
||||
return createComponent(RegistryContext.Provider, {
|
||||
value: registry,
|
||||
get children() {
|
||||
return options.children
|
||||
}
|
||||
})
|
||||
}
|
||||
13
repos/effect/packages/atom/solid/src/index.ts
Normal file
13
repos/effect/packages/atom/solid/src/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * from "./Hooks.ts"
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
export * from "./RegistryContext.ts"
|
||||
296
repos/effect/packages/atom/solid/test/index.test.tsx
Normal file
296
repos/effect/packages/atom/solid/test/index.test.tsx
Normal file
@@ -0,0 +1,296 @@
|
||||
import {
|
||||
RegistryContext,
|
||||
useAtom,
|
||||
useAtomInitialValues,
|
||||
useAtomRef,
|
||||
useAtomRefProp,
|
||||
useAtomRefPropValue,
|
||||
useAtomResource,
|
||||
useAtomValue
|
||||
} from "@effect/atom-solid"
|
||||
import { assert, describe, it } from "@effect/vitest"
|
||||
import { AsyncResult, Atom, AtomRef, AtomRegistry } from "effect/unstable/reactivity"
|
||||
import { type Accessor, createComponent, createEffect, createRoot, type Resource } from "solid-js"
|
||||
|
||||
describe("atom-solid", () => {
|
||||
describe("useAtomValue", () => {
|
||||
it("reads value from simple Atom", () => {
|
||||
const atom = Atom.make(42)
|
||||
let observed: number | undefined
|
||||
const dispose = renderAtomValue(atom, (value) => {
|
||||
observed = value
|
||||
})
|
||||
assert.strictEqual(observed, 42)
|
||||
dispose()
|
||||
})
|
||||
|
||||
it("reads value with transform function", () => {
|
||||
const atom = Atom.make(42)
|
||||
let observed: number | undefined
|
||||
const dispose = renderAtomValue(atom, (value) => {
|
||||
observed = value
|
||||
}, { map: (value) => value * 2 })
|
||||
assert.strictEqual(observed, 84)
|
||||
dispose()
|
||||
})
|
||||
|
||||
it("updates when Atom value changes", () => {
|
||||
const registry = AtomRegistry.make()
|
||||
const atom = Atom.make("initial")
|
||||
let observed: string | undefined
|
||||
const dispose = renderAtomValue(atom, (value) => {
|
||||
observed = value
|
||||
}, { registry })
|
||||
assert.strictEqual(observed, "initial")
|
||||
registry.set(atom, "updated")
|
||||
assert.strictEqual(observed, "updated")
|
||||
dispose()
|
||||
})
|
||||
|
||||
it("works with computed Atom", () => {
|
||||
const baseAtom = Atom.make(10)
|
||||
const computedAtom = Atom.make((get) => get(baseAtom) * 2)
|
||||
let observed: number | undefined
|
||||
const dispose = renderAtomValue(computedAtom, (value) => {
|
||||
observed = value
|
||||
})
|
||||
assert.strictEqual(observed, 20)
|
||||
dispose()
|
||||
})
|
||||
})
|
||||
|
||||
describe("useAtom", () => {
|
||||
it("updates value with setter", () => {
|
||||
const atom = Atom.make(0)
|
||||
let observed: number | undefined
|
||||
const dispose = createRoot((dispose) => {
|
||||
const [value, setValue] = useAtom(() => atom)
|
||||
createEffect(() => {
|
||||
observed = value()
|
||||
})
|
||||
createEffect(() => {
|
||||
if (value() !== 0) {
|
||||
return
|
||||
}
|
||||
setValue(1)
|
||||
setValue((current) => current + 1)
|
||||
})
|
||||
return dispose
|
||||
})
|
||||
assert.strictEqual(observed, 2)
|
||||
dispose()
|
||||
})
|
||||
})
|
||||
|
||||
describe("useAtomInitialValues", () => {
|
||||
it("applies initial values once per registry", () => {
|
||||
const registry = AtomRegistry.make()
|
||||
const atom = Atom.make(0)
|
||||
createRoot((dispose) => {
|
||||
createComponent(RegistryContext.Provider, {
|
||||
value: registry,
|
||||
get children() {
|
||||
useAtomInitialValues([[atom, 1]])
|
||||
useAtomInitialValues([[atom, 2]])
|
||||
assert.strictEqual(registry.get(atom), 1)
|
||||
return null
|
||||
}
|
||||
})
|
||||
return dispose
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("AtomRef", () => {
|
||||
it("updates when AtomRef changes", () => {
|
||||
const ref = AtomRef.make(0)
|
||||
let observed: number | undefined
|
||||
const dispose = renderAtomRef(ref, (value) => {
|
||||
observed = value
|
||||
})
|
||||
assert.strictEqual(observed, 0)
|
||||
ref.set(1)
|
||||
assert.strictEqual(observed, 1)
|
||||
dispose()
|
||||
})
|
||||
|
||||
it("updates when AtomRef prop changes", () => {
|
||||
const ref = AtomRef.make({ count: 0, label: "a" })
|
||||
const propRef = useAtomRefProp(() => ref, "count")
|
||||
let observed: number | undefined
|
||||
const dispose = renderAtomRef(propRef(), (value) => {
|
||||
observed = value
|
||||
})
|
||||
assert.strictEqual(observed, 0)
|
||||
ref.set({ count: 1, label: "a" })
|
||||
assert.strictEqual(observed, 1)
|
||||
dispose()
|
||||
})
|
||||
|
||||
it("updates when AtomRef prop value changes", () => {
|
||||
const ref = AtomRef.make({ count: 0, label: "a" })
|
||||
let observed: number | undefined
|
||||
const dispose = renderAccessor(() => useAtomRefPropValue(() => ref, "count"), (value) => {
|
||||
observed = value
|
||||
})
|
||||
assert.strictEqual(observed, 0)
|
||||
ref.set({ count: 2, label: "a" })
|
||||
assert.strictEqual(observed, 2)
|
||||
dispose()
|
||||
})
|
||||
})
|
||||
|
||||
describe("useAtomResource", () => {
|
||||
it("suspends on Initial result", () => {
|
||||
const atom = Atom.make(AsyncResult.initial<number, Error>())
|
||||
const { resource, dispose } = renderAtomResource(() => atom)
|
||||
assert.strictEqual(resource.loading, true)
|
||||
assert.strictEqual(resource(), undefined)
|
||||
dispose()
|
||||
})
|
||||
})
|
||||
|
||||
//
|
||||
// it("suspends on waiting when suspendOnWaiting is true", () => {
|
||||
// const atom = Atom.make(AsyncResult.success(1, { waiting: true }))
|
||||
// const { resource, dispose } = renderAtomResource(atom, { suspendOnWaiting: true })
|
||||
// assert.strictEqual(resource.loading, true)
|
||||
// assert.strictEqual(resource(), undefined)
|
||||
// dispose()
|
||||
// })
|
||||
//
|
||||
// it("returns success value by default", async () => {
|
||||
// const atom = Atom.make(AsyncResult.success(5, { waiting: true }))
|
||||
// const { resource, dispose } = renderAtomResource(atom)
|
||||
// await Promise.resolve()
|
||||
// await Promise.resolve()
|
||||
// assert.strictEqual(resource.loading, false)
|
||||
// assert.strictEqual(resource(), 5)
|
||||
// dispose()
|
||||
// })
|
||||
//
|
||||
// it("surfaces failure via Cause.squash", async () => {
|
||||
// const error = new Error("boom")
|
||||
// const atom = Atom.make(AsyncResult.fail(error))
|
||||
// let resource: ReturnType<typeof useAtomResource>[0] | undefined
|
||||
// let caught: unknown
|
||||
// const dispose = createRoot((dispose) => {
|
||||
// catchError(() => {
|
||||
// ;[resource] = useAtomResource(atom)
|
||||
// createEffect(() => {
|
||||
// resource?.()
|
||||
// })
|
||||
// }, (err) => {
|
||||
// caught = err
|
||||
// })
|
||||
// return dispose
|
||||
// })
|
||||
// await Promise.resolve()
|
||||
// await Promise.resolve()
|
||||
// assert.ok(caught instanceof Error)
|
||||
// assert.strictEqual(caught.message, "boom")
|
||||
// assert.strictEqual(resource?.error, caught)
|
||||
// assert.strictEqual(resource?.loading, false)
|
||||
// dispose()
|
||||
// })
|
||||
//
|
||||
// it("preserves success result when preserveResult is true", async () => {
|
||||
// const atom = Atom.make(Effect.succeed(7))
|
||||
// const { resource, dispose } = renderAtomResource(atom, { preserveResult: true })
|
||||
// await Promise.resolve()
|
||||
// await Promise.resolve()
|
||||
// const result = resource()!
|
||||
// assert.strictEqual(AsyncResult.isSuccess(result), true)
|
||||
// if (AsyncResult.isSuccess(result)) {
|
||||
// assert.strictEqual(result.value, 7)
|
||||
// }
|
||||
// assert.strictEqual(resource.error, undefined)
|
||||
// dispose()
|
||||
// })
|
||||
//
|
||||
// it("preserves failure result when preserveResult is true", async () => {
|
||||
// const error = new Error("failure")
|
||||
// const atom = Atom.make(Effect.fail(error))
|
||||
// const { resource, dispose } = renderAtomResource(atom, { preserveResult: true })
|
||||
// await Promise.resolve()
|
||||
// await Promise.resolve()
|
||||
// const result = resource()!
|
||||
// assert.strictEqual(AsyncResult.isFailure(result), true)
|
||||
// if (AsyncResult.isFailure(result)) {
|
||||
// const squashed = Cause.squash(result.cause)
|
||||
// assert.ok(squashed instanceof Error)
|
||||
// assert.strictEqual(squashed.message, "failure")
|
||||
// }
|
||||
// assert.strictEqual(resource.error, undefined)
|
||||
// dispose()
|
||||
// })
|
||||
// })
|
||||
})
|
||||
|
||||
const renderAtomRef = function<A>(ref: AtomRef.ReadonlyRef<A>, onValue: (_: A) => void) {
|
||||
return createRoot((dispose) => {
|
||||
const accessor = useAtomRef(() => ref)
|
||||
createEffect(() => {
|
||||
onValue(accessor())
|
||||
})
|
||||
return dispose
|
||||
})
|
||||
}
|
||||
|
||||
const renderAccessor = function<A>(makeAccessor: () => Accessor<A>, onValue: (_: A) => void) {
|
||||
return createRoot((dispose) => {
|
||||
const accessor = makeAccessor()
|
||||
createEffect(() => {
|
||||
onValue(accessor())
|
||||
})
|
||||
return dispose
|
||||
})
|
||||
}
|
||||
|
||||
const renderAtomValue = function<A, B = A>(
|
||||
atom: Atom.Atom<A>,
|
||||
onValue: (_: B) => void,
|
||||
options?: { readonly registry?: AtomRegistry.AtomRegistry; readonly map?: (_: A) => B }
|
||||
) {
|
||||
return createRoot((dispose) => {
|
||||
const run = () => {
|
||||
const accessor = options?.map ? useAtomValue(() => atom, options.map) : useAtomValue(() => atom)
|
||||
createEffect(() => {
|
||||
onValue(accessor() as B)
|
||||
})
|
||||
return null
|
||||
}
|
||||
|
||||
if (options?.registry) {
|
||||
createComponent(RegistryContext.Provider, {
|
||||
value: options.registry,
|
||||
get children() {
|
||||
return run()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
run()
|
||||
}
|
||||
|
||||
return dispose
|
||||
})
|
||||
}
|
||||
|
||||
const renderAtomResource = function<A, E>(
|
||||
atom: () => Atom.Atom<AsyncResult.AsyncResult<A, E>>,
|
||||
options?: {
|
||||
readonly suspendOnWaiting?: boolean | undefined
|
||||
}
|
||||
) {
|
||||
let resource:
|
||||
| Resource<A>
|
||||
| undefined
|
||||
const dispose = createRoot((dispose) => {
|
||||
;[resource] = useAtomResource(atom, options)
|
||||
createEffect(() => {
|
||||
resource?.()
|
||||
})
|
||||
return dispose
|
||||
})
|
||||
return { resource: resource!, dispose }
|
||||
}
|
||||
8
repos/effect/packages/atom/solid/tsconfig.json
Normal file
8
repos/effect/packages/atom/solid/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/tsconfig",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{ "path": "../../effect" }
|
||||
]
|
||||
}
|
||||
15
repos/effect/packages/atom/solid/vitest.config.ts
Normal file
15
repos/effect/packages/atom/solid/vitest.config.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { mergeConfig } from "vitest/config"
|
||||
import shared from "../../../vitest.shared.ts"
|
||||
|
||||
export default mergeConfig(shared, {
|
||||
resolve: {
|
||||
conditions: ["browser"]
|
||||
},
|
||||
esbuild: {
|
||||
target: "es2022"
|
||||
},
|
||||
test: {
|
||||
environment: "jsdom",
|
||||
setupFiles: ["./vitest.setup.ts"]
|
||||
}
|
||||
})
|
||||
8
repos/effect/packages/atom/solid/vitest.setup.ts
Normal file
8
repos/effect/packages/atom/solid/vitest.setup.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
// oxlint-disable-next-line no-unassigned-import
|
||||
import "@testing-library/jest-dom/vitest"
|
||||
import { cleanup } from "@solidjs/testing-library"
|
||||
import { afterEach } from "vitest"
|
||||
|
||||
afterEach(() => {
|
||||
cleanup()
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user