From 90ff2b1086d664f0d37b849ac40a5fa8f52be818 Mon Sep 17 00:00:00 2001 From: Kyle Mistele Date: Sat, 3 Oct 2026 14:16:57 -0700 Subject: [PATCH 1/2] chore: upgrade to Effect 4.0.0 and Alchemy 2.0.0-beta.80 Effect 4.0.0 is the first stable v4 release. Alchemy beta.80 requires `effect@^4.0.0`, so both move together; @effect/tsgo goes to 0.48.0. - Import paths move from `effect/unstable/*` to `effect/*`. - Follow the 4.0.0 renames: PascalCase `Config` and CLI `Flag` constructors, `Schema.isStartingWith`, `LanguageModel.LanguageModel`, `ByteSize.bytes`, and `effect/encoding` `Base64`/`Base64Url`. - Refresh the vendored @effect/ai-openai, ai-anthropic and ai-openai-compat sources from rc.112 to 4.0.0 with a three-way merge that keeps the HumanLayer delta; update UPSTREAM.md and checksums. - `Schema.brand` now takes one literal name, so `makeBrandedId` asserts its runtime-computed name once (brands are type-only at runtime). - Add `AnyTool` for fold's erased tools: with `Tool.Any`, 4.0.0's new parameter-encoding and handler-start requirements come out unknown and leak into every model request. - Turn off the new `unstableApiUsage` diagnostic: 4.0.0 marks effect/ai, effect/http and the other moved modules unstable, and fold is built on them. Co-Authored-By: Claude Opus 5.5 HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0f3fc-13b0-758f-a343-fae04e83a7a9 --- .claude/skills/effect-program-design/SKILL.md | 2 +- .oxlintrc.jsonc | 2 + AGENTS.md | 6 +- bun.lock | 300 ++++---------- examples/alchemy-cloudflare/src/Api.ts | 2 +- .../alchemy-cloudflare/src/ChatSession.ts | 4 +- examples/alchemy-cloudflare/src/Worker.ts | 2 +- examples/alchemy-cloudflare/src/Workspace.ts | 2 +- .../src/WorkspaceFileSystem.ts | 4 +- examples/alchemy-cloudflare/test/Api.test.ts | 2 +- package.json | 12 +- packages/effect-ai-anthropic/README.md | 2 +- packages/effect-ai-anthropic/UPSTREAM.md | 10 +- .../src/AnthropicClient.ts | 60 ++- .../src/AnthropicConfig.ts | 2 +- .../effect-ai-anthropic/src/AnthropicError.ts | 2 +- .../src/AnthropicLanguageModel.ts | 132 +++--- .../src/AnthropicTelemetry.ts | 2 +- .../effect-ai-anthropic/src/AnthropicTool.ts | 111 ++++- packages/effect-ai-anthropic/src/Generated.ts | 37 +- packages/effect-ai-anthropic/src/index.ts | 4 + .../src/internal/errors.ts | 12 +- .../src/internal/utilities.ts | 2 +- .../test/HumanlayerFork.test.ts | 4 +- packages/effect-ai-openai-compat/README.md | 2 +- packages/effect-ai-openai-compat/UPSTREAM.md | 18 +- .../effect-ai-openai-compat/UPSTREAM.sha256 | 10 +- .../src/OpenAiClient.ts | 61 ++- .../src/OpenAiConfig.ts | 2 +- .../src/OpenAiEmbeddingModel.ts | 19 +- .../src/OpenAiError.ts | 2 +- .../src/OpenAiLanguageModel.ts | 101 +++-- .../src/OpenAiTelemetry.ts | 2 +- packages/effect-ai-openai-compat/src/index.ts | 3 + .../src/internal/errors.ts | 12 +- .../src/internal/utilities.ts | 2 +- packages/effect-ai-openai/README.md | 2 +- packages/effect-ai-openai/UPSTREAM.md | 10 +- packages/effect-ai-openai/src/Generated.ts | 72 ++-- packages/effect-ai-openai/src/OpenAiClient.ts | 232 +++++++---- .../src/OpenAiClientGenerated.ts | 12 +- packages/effect-ai-openai/src/OpenAiConfig.ts | 2 +- .../src/OpenAiEmbeddingModel.ts | 21 +- packages/effect-ai-openai/src/OpenAiError.ts | 2 +- .../src/OpenAiLanguageModel.ts | 390 +++++++++++++----- packages/effect-ai-openai/src/OpenAiSchema.ts | 119 +++++- .../effect-ai-openai/src/OpenAiTelemetry.ts | 2 +- packages/effect-ai-openai/src/OpenAiTool.ts | 112 +++-- packages/effect-ai-openai/src/index.ts | 7 + .../effect-ai-openai/src/internal/errors.ts | 12 +- .../src/internal/utilities.ts | 2 +- .../test/HumanlayerFork.test.ts | 4 +- packages/effect-branded-id/src/index.ts | 18 +- packages/fold-agent/examples/ConfigAgent.ts | 2 +- .../fold-agent/examples/SkillsFromDisk.ts | 2 +- .../scripts/update-managed-binaries.ts | 2 +- .../scripts/update-model-catalog.ts | 2 +- .../fold-agent/src/Bin/ManagedBinaries.ts | 6 +- .../fold-agent/src/Catalog/LoadCatalog.ts | 2 +- packages/fold-agent/src/Config/AgentModels.ts | 2 +- .../fold-agent/src/Config/ModelSelections.ts | 2 +- packages/fold-agent/src/Mode/Launch.ts | 4 +- packages/fold-agent/src/Mode/Mode.ts | 4 +- packages/fold-agent/src/Mode/Rpi.ts | 4 +- packages/fold-agent/src/Mode/Subagents.ts | 4 +- .../fold-agent/src/Session/TitleGenerator.ts | 2 +- packages/fold-agent/src/Tools/BashTool.ts | 2 +- packages/fold-agent/src/Tools/CodingTools.ts | 4 +- packages/fold-agent/src/Tools/WebFetchTool.ts | 4 +- .../fold-agent/src/Tools/WebSearchTool.ts | 2 +- packages/fold-agent/src/Tools/WebTools.ts | 2 +- .../test/Bin/ManagedBinaries.vi.test.ts | 4 +- .../test/Catalog/LoadCatalog.vi.test.ts | 2 +- .../Codex/CodexImageReadDelivery.vi.test.ts | 7 +- .../test/Codex/CodexLive.vi.test.ts | 2 +- .../EffectToolResultEncodingRepro.vi.test.ts | 6 +- .../test/Codex/SessionModelPathTestHarness.ts | 4 +- ...ToolResultFormattingIntegration.vi.test.ts | 4 +- .../fold-agent/test/Mode/Launch.vi.test.ts | 2 +- packages/fold-agent/test/Mode/Rlm.vi.test.ts | 2 +- packages/fold-agent/test/Mode/Rpi.vi.test.ts | 2 +- .../fold-agent/test/Mode/Subagents.vi.test.ts | 2 +- .../test/Session/SessionLayout.vi.test.ts | 2 +- .../test/Session/TitleGenerator.vi.test.ts | 2 +- packages/fold-agent/test/TestHelpers.ts | 4 +- .../fold-agent/test/Tools/BashTool.vi.test.ts | 2 +- .../test/Tools/WebFetchTool.vi.test.ts | 2 +- .../test/Tools/WebTimeouts.vi.test.ts | 2 +- packages/fold-cli/src/Commands.ts | 44 +- packages/fold-cli/src/Run.ts | 4 +- packages/fold-cli/src/cli.ts | 2 +- packages/fold-cli/src/tui/HostedTuiSession.ts | 4 +- packages/fold-cli/src/tui/Shell.tsx | 2 +- .../fold-cli/src/tui/TuiSessionWorkspace.ts | 4 +- packages/fold-codex/src/CodexAuth.ts | 2 +- packages/fold-codex/src/CodexModel.ts | 8 +- packages/fold-codex/src/Hardening.ts | 2 +- packages/fold-codex/src/OAuthFlows.ts | 7 +- packages/fold-codex/test/CodexAuth.vi.test.ts | 2 +- .../fold-codex/test/CodexModel.vi.test.ts | 4 +- .../test/CodexModelCredentials.vi.test.ts | 2 +- packages/fold-codex/test/Hardening.vi.test.ts | 2 +- packages/fold-core/examples/AnthropicAgent.ts | 2 +- .../fold-core/examples/AutoCompactAgent.ts | 2 +- packages/fold-core/examples/ModelSwitch.ts | 2 +- packages/fold-core/examples/OpenaiAgent.ts | 2 +- packages/fold-core/examples/SkillsAgent.ts | 2 +- .../src/AgentRuntime/AgentRuntimeLayer.ts | 6 +- packages/fold-core/src/Api/ModelDescriptor.ts | 10 +- packages/fold-core/src/Api/ProviderModels.ts | 10 +- packages/fold-core/src/Api/Provisioning.ts | 4 +- packages/fold-core/src/Api/StartSession.ts | 2 +- packages/fold-core/src/Api/ToolDefinition.ts | 2 +- .../src/Compaction/CompactionLayer.ts | 2 +- .../fold-core/src/EventLog/MessageContent.ts | 2 +- packages/fold-core/src/EventLog/Schemas.ts | 2 +- packages/fold-core/src/EventLog/Usage.ts | 2 +- packages/fold-core/src/HookRunner/Schema.ts | 2 +- .../fold-core/src/Model/RequestBuilder.ts | 15 +- .../src/StopConditions/StopConditions.ts | 2 +- .../fold-core/src/Subagents/SubagentEngine.ts | 2 +- .../src/ToolRuntime/ToolRuntimeLayer.ts | 2 +- .../src/ToolRuntime/ToolRuntimeService.ts | 2 +- .../src/ToolRuntime/ToolsetFactory.ts | 6 +- .../src/ToolRuntime/ToolsetService.ts | 33 +- .../AgentRuntimeModelSettings.vi.test.ts | 4 +- .../AgentRuntimePrefix.vi.test.ts | 2 +- .../AgentRuntime/AgentRuntimeTestHelpers.ts | 2 +- .../AgentRuntimeToolRun.vi.test.ts | 2 +- packages/fold-core/test/Api/ApiTestHelpers.ts | 2 +- .../test/Api/Provisioning.vi.test.ts | 4 +- .../test/Api/ResumeSession.vi.test.ts | 2 +- .../test/Api/SessionControlHarness.ts | 4 +- .../Compaction/CompactionEngine.vi.test.ts | 2 +- .../fold-core/test/EventLog/Usage.vi.test.ts | 2 +- .../test/HookRunner/PassThrough.vi.test.ts | 2 +- .../test/HookRunner/PreRequestHook.vi.test.ts | 2 +- ...nthropicToolResultEncodingRepro.vi.test.ts | 6 +- .../test/Model/RequestBuilder.vi.test.ts | 2 +- .../Model/RequestBuilderImages.vi.test.ts | 9 +- .../test/Projection/Projection.vi.test.ts | 2 +- .../test/Session/SessionTestHelpers.ts | 2 +- .../fold-core/test/Subagents/DriveHarness.ts | 2 +- .../test/TestLayers/ScriptedLanguageModel.ts | 2 +- .../ScriptedLanguageModelUsage.vi.test.ts | 2 +- .../fold-core/test/TestLayers/TestTools.ts | 2 +- .../ToolRuntimeInterrupt.vi.test.ts | 2 +- .../ToolRuntimeStateSnapshot.vi.test.ts | 2 +- .../ToolRuntime/ToolRuntimeTestHelpers.ts | 4 +- packages/fold-opencode/src/OpenCodeAuth.ts | 2 +- packages/fold-opencode/src/OpenCodeModel.ts | 6 +- .../test/OpenCodeAuth.vi.test.ts | 2 +- packages/fold-xai/src/OAuthFlows.ts | 2 +- packages/fold-xai/src/XaiAuth.ts | 2 +- packages/fold-xai/src/XaiModel.ts | 6 +- .../release/fixtures/provider-consumer.mjs | 4 +- tsconfig.json | 8 +- 157 files changed, 1476 insertions(+), 902 deletions(-) diff --git a/.claude/skills/effect-program-design/SKILL.md b/.claude/skills/effect-program-design/SKILL.md index c1ba7c7..a7c0ecc 100644 --- a/.claude/skills/effect-program-design/SKILL.md +++ b/.claude/skills/effect-program-design/SKILL.md @@ -12,7 +12,7 @@ Build deep Fold modules: a small, domain-shaped public interface hides descripto details, persistence, resource ownership, and workflow coordination. Keep expected failures in Effect's error channel, dependencies in `R`, resources in scopes, and external values at explicit schema boundaries. -Fold is an Effect v4 (`4.0.0-rc.109`) Bun monorepo. Read the installed declarations first; when they do not settle an +Fold is an Effect v4 (`4.0.0`) Bun monorepo. Read the installed declarations first; when they do not settle an API, read `~/projects/effect`, not Effect v3 documentation or examples. ## Fold's architecture diff --git a/.oxlintrc.jsonc b/.oxlintrc.jsonc index 6e0ede9..0c854f1 100644 --- a/.oxlintrc.jsonc +++ b/.oxlintrc.jsonc @@ -74,6 +74,8 @@ "effecttsgo/prefer-succeed-some-or-none": "error", "effecttsgo/prefer-typed-schema-decoder": "error", "effecttsgo/prefer-unsafe-constructor": "error", + // Effect 4.0.0 marks its ai, http and other moved modules unstable, and fold is built on them. + "effecttsgo/unstable-api-usage": "off", "effecttsgo/promise-in-effect-success": "error", "effecttsgo/provide-layer-succeed-to-provide-service": "error", "effecttsgo/race-first-with-sleep-to-timeout": "error", diff --git a/AGENTS.md b/AGENTS.md index b15c0c5..6c5af21 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,7 +5,7 @@ Bun monorepo. Packages live in `packages/*` and run TypeScript directly (no buil ## Stack - **Runtime / package manager:** Bun (`bun@1.3.14`) -- **Framework:** Effect **v4** (`4.0.0-rc.109`) +- **Framework:** Effect **v4** (`4.0.0`) - **Testing:** Vitest + `@effect/vitest` - **Lint / format:** oxlint + oxfmt (120 col, no semicolons) - **Effect editor tooling:** `@effect/tsgo` with the `@effect/language-service` TS plugin. `tsc` and oxlint are patched @@ -32,8 +32,8 @@ packages reference them with `"": "catalog:"`. Bump the version in the cata ## Effect v4 source (read this, not v3 docs) -This repo targets **Effect v4 (release candidate)** — its API differs from the widely-documented v3. The v4 -source is the `effect` repo: +This repo targets **Effect v4** — its API differs from the widely-documented v3, and from the v4 release +candidates (e.g. `effect/unstable/http` became `effect/http`). The v4 source is the `effect` repo: - In Riptide worktree tasks it is checked out as a sibling at **`../effect`**. - Locally it lives at **`~/projects/effect`**. diff --git a/bun.lock b/bun.lock index 3e41be4..08ee907 100644 --- a/bun.lock +++ b/bun.lock @@ -5,7 +5,7 @@ "": { "name": "fold", "devDependencies": { - "@effect/tsgo": "0.47.0", + "@effect/tsgo": "0.48.0", "@oxlint/plugins": "1.86.0", "@types/bun": "catalog:", "@types/node": "catalog:", @@ -270,9 +270,9 @@ "catalog": { "@cloudflare/computer": "https://github.com/K-Mistele/computer/releases/download/fold-91611593a1d7/cloudflare-computer-0.3.1.tgz", "@cloudflare/workers-types": "5.20260929.1", - "@effect/platform-bun": "4.0.0-rc.112", - "@effect/platform-node": "4.0.0-rc.112", - "@effect/vitest": "4.0.0-rc.112", + "@effect/platform-bun": "4.0.0", + "@effect/platform-node": "4.0.0", + "@effect/vitest": "4.0.0", "@kitlangton/terminal-control": "0.3.1", "@opentui/core": "0.4.3", "@opentui/keymap": "0.4.3", @@ -283,8 +283,8 @@ "@types/node": "26.1.0", "@types/turndown": "5.0.6", "@vitest/coverage-v8": "4.1.9", - "alchemy": "2.0.0-beta.76", - "effect": "4.0.0-rc.112", + "alchemy": "2.0.0-beta.80", + "effect": "4.0.0", "solid-js": "1.9.12", "turndown": "7.2.4", "typescript": "7.0.2", @@ -292,54 +292,16 @@ "yaml": "2.9.0", }, "packages": { - "@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="], + "@alchemy.run/cloudflare-runtime": ["@alchemy.run/cloudflare-runtime@2.0.0-beta.80", "", { "dependencies": { "@alchemy.run/node-utils": "2.0.0-beta.80", "@cloudflare/unenv-preset": "^2.16.1", "@puppeteer/browsers": "^3.2.0", "capnp-es": "^0.0.16", "magic-string": "^0.30.21", "mime": "^4.0.7", "sharp": "^0.35.3", "unenv": "^2.0.0-rc.24", "workerd": "1.20260918.1", "yauzl": "^3.4.0" }, "peerDependencies": { "@distilled.cloud/cloudflare": "1.0.0-rc.13", "@effect/platform-bun": "^4.0.0", "@effect/platform-node": "^4.0.0", "effect": "^4.0.0", "rolldown": "1.2.5", "vite": "^7.0.0 || ^8.0.0" }, "optionalPeers": ["@effect/platform-bun", "@effect/platform-node", "rolldown", "vite"] }, "sha512-vrMDVAQ+LlzFGkgfIbi/65iwskdSxxWYhJX03sFL72mvkGxvb8RQSKrbxLGHhMz0QSZh796dOff1z9zOwxsIbA=="], - "@alchemy.run/cloudflare-runtime": ["@alchemy.run/cloudflare-runtime@2.0.0-beta.76", "", { "dependencies": { "@alchemy.run/node-utils": "2.0.0-beta.76", "@cloudflare/unenv-preset": "^2.16.0", "@puppeteer/browsers": "^3.2.0", "capnp-es": "^0.0.14", "magic-string": "^0.30.21", "sharp": "^0.35.3", "unenv": "^2.0.0-rc.24", "workerd": "1.20260704.1", "yauzl": "^3.4.0" }, "peerDependencies": { "@distilled.cloud/cloudflare": "1.0.0-rc.8", "@effect/platform-bun": ">=4.0.0-rc.112 || >=4.0.0", "@effect/platform-node": ">=4.0.0-rc.112 || >=4.0.0", "effect": ">=4.0.0-rc.112 || >=4.0.0", "rolldown": "1.2.5", "vite": "^7.0.0 || ^8.0.0" }, "optionalPeers": ["@effect/platform-bun", "@effect/platform-node", "rolldown", "vite"] }, "sha512-rH5BFh0Xq7aExpSpITyQbC+Jqfc9XgwJXidHVHTi1tNRC6/KAWg4tOzBfwiFIxljFLLYcApzlYFvLa/fTYcEjw=="], + "@alchemy.run/floci": ["@alchemy.run/floci@2.0.0-beta.80", "", { "peerDependencies": { "effect": "^4.0.0" } }, "sha512-gtUXFitVY9pSQQYCDtSVyjfd5YOKY3Wleg3WCG5yWno7/l7xBo4kfOMbM63tzWnmka9LewVSITbMfwnC4D/73A=="], - "@alchemy.run/floci": ["@alchemy.run/floci@2.0.0-beta.76", "", { "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-UIKd+Hki3t5seDpLfyRBwWiNukKlbAqDCTOYBD+n49b/WQIgEWHhYXzGtnwC7OY/b3KAv5p7gsdn8IpPnRXR8g=="], + "@alchemy.run/node-utils": ["@alchemy.run/node-utils@2.0.0-beta.80", "", { "dependencies": { "chokidar": "^5.0.0", "rolldown": "1.2.5" } }, "sha512-uOhVDQZTjwh1AU4mrk0wB5rQaziTwSrVMfqwFP8wALfU//nveu4goOWZimHtqytXiybENh+iEbALH25EFAkc7A=="], - "@alchemy.run/node-utils": ["@alchemy.run/node-utils@2.0.0-beta.76", "", {}, "sha512-KUAlGdoeWeMEToUP1V3I+mEf6FVzUjU+6Tc8savNvMsXN9t3uwZVqD1FeMzTMzMTJJijjxVljQTCtyoeE9W43w=="], + "@alchemy.run/sigil": ["@alchemy.run/sigil@0.1.0-alpha.1", "", { "peerDependencies": { "@types/react": ">=19.2.0", "react-devtools-core": ">=6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-RtHELG2w+GluVewRsuKm66idtPzC+4STptMr/61X1Vy5uBkDzcCzjzV8G6jUa4iBv6Il0hHV7UL6wvv//9nD/Q=="], "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], - "@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="], - - "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], - - "@aws-sdk/core": ["@aws-sdk/core@3.978.1", "", { "dependencies": { "@aws-sdk/types": "^3.974.6", "@aws-sdk/xml-builder": "^3.972.41", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.35.0", "@smithy/signature-v4": "^5.7.3", "@smithy/types": "^4.19.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-LbY9aGsEiznDWmUc30Nwv3aIX/+dbwTx8KfS0yOC3NPYMO+O91e6jkT1azf34FwjOndq8/Q+RcVVZz5xnerwdg=="], - - "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.71", "", { "dependencies": { "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-rsxsi8tF3vMGdWdaHQNXceHBdb49442yR2Pe08K+Phoc/yICbptdsHwL25Wf0z5+hjhSS5a+hDJHP7Xul4zvHQ=="], - - "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.72", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-xTKO/FWJPozTIXbozVnVGoNBhaGba8TBcx+KyUjRVeOlXE+dUc7GTR1cLvu0uTdIdmemzaFbqqCshXeZA1fZew=="], - - "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.74", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.12.1", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-u91E/hT8f4d1xy0Jl7VG4nVKJ3lxbrZkoBTeSVoJdWBiSEUMwMS/9+e0H/aJVQV//Lt5wuzP+E69v4aRSsNTmw=="], - - "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.973.17", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/credential-provider-env": "^3.972.72", "@aws-sdk/credential-provider-http": "^3.972.74", "@aws-sdk/credential-provider-login": "^3.972.79", "@aws-sdk/credential-provider-process": "^3.972.72", "@aws-sdk/credential-provider-sso": "^3.973.16", "@aws-sdk/credential-provider-web-identity": "^3.972.78", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/credential-provider-imds": "^4.5.2", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-ged4KXdBkvIC81bLvNHHuQKdKak/VXhQTR1NWYTTqW0474nlmsxy9O/vlgTIohDDWH3xpBdtVMZRyjb+DnocDA=="], - - "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.79", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-L+Z85anONJd8MaiuraO4wRxATCdEejBZ3K3eymzWI5JPXa9sOS9CkIm72PBKqXKX+Z9p9NGMX5AIMXm0LEflgw=="], - - "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.84", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.72", "@aws-sdk/credential-provider-http": "^3.972.74", "@aws-sdk/credential-provider-ini": "^3.973.17", "@aws-sdk/credential-provider-process": "^3.972.72", "@aws-sdk/credential-provider-sso": "^3.973.16", "@aws-sdk/credential-provider-web-identity": "^3.972.78", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/credential-provider-imds": "^4.5.2", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-oHt854odINVwzwsh+c5x69j0ajm4DbqqqVJ+O1ECsCIZeMDAbzFpXItaqP7UZstJj/ATdTk/KFSH0LaNAgV+kA=="], - - "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.72", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-rLIp2xbMjX/k9/od7APpqq1ZgXXnV0pOL1Th3ZsL8Wu0TRtBsDTVS8iPqcfRFcHakFxPvR04OSTv2ka2qOb/2A=="], - - "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.973.16", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/token-providers": "3.1138.0", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-IGihaJfFZYacJJr/odqILCoK7W/mvrZ7cuK7ECn3sAu4vLC6u0V8bS7mCGbdugJ8Aum2tnvqmx0F2MRFp2rn9g=="], - - "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.78", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-/y9WvNtlcPBGLR0qc1a+9J/xtYZfVczvLUOuXaVWylzttH7ewsxwHtjmiJSolNrVSDorIxHGHMU61CbonRkmwA=="], - - "@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.1143.0", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/credential-provider-cognito-identity": "^3.972.71", "@aws-sdk/credential-provider-env": "^3.972.72", "@aws-sdk/credential-provider-http": "^3.972.74", "@aws-sdk/credential-provider-ini": "^3.973.17", "@aws-sdk/credential-provider-login": "^3.972.79", "@aws-sdk/credential-provider-node": "^3.972.84", "@aws-sdk/credential-provider-process": "^3.972.72", "@aws-sdk/credential-provider-sso": "^3.973.16", "@aws-sdk/credential-provider-web-identity": "^3.972.78", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/credential-provider-imds": "^4.5.2", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-1Tifq2jFMJy4JN6buq7fY8qlN8+3yZvD7aG9ZWRneRlwjvjurS56aftzMXTmBWSOa2eJHlLx4eNuFu6pLc6K5g=="], - - "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.46", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/signature-v4-multi-region": "^3.996.47", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.12.1", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-oRxtBcka/JGHGs9l9p9IVajGoTP8vTPmoAzdHGy4Qcy9P5vPnDf6nhIeM/COQNY9k/OahImTRaLkHftoXvfcmQ=="], - - "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.47", "", { "dependencies": { "@aws-sdk/types": "^3.974.6", "@smithy/signature-v4": "^5.7.3", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-Zk08macMvQTHzQJCLJVkOlviVoqwYMrpXv4lmLN7b7sAbiMoOK7Go0NYdR5UeF+MW8LIbRmwrNy9u/5VvX1U5g=="], - - "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1138.0", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-GpyAr0DD63YOEmYFM6Df+gJuIgC92MMTiBK4FTKfxii5MJ9ge20epR7LyroulscYlG89J+ZB2ivFDPjvfQhzdw=="], - - "@aws-sdk/types": ["@aws-sdk/types@3.974.6", "", { "dependencies": { "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-v/clNZzZnDxGyvpHMOGpJKVXFAExJzUNAAjaWGdcx8QAcXLGwTaOkw33p5SHAi0YAioK32xB3hWwOekRVfmfKg=="], - - "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.41", "", { "dependencies": { "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-ctjVSyCMegrWfXlx6VqzSBFI6UqmQ5ZlnfMhdLIiWmhoH8UAQxSCP5N3OpG7X3k4LnS7ou74C4mt20+bfTW2aQ=="], - - "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.3.0", "", {}, "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ=="], - "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="], @@ -408,71 +370,81 @@ "@chevrotain/utils": ["@chevrotain/utils@10.5.0", "", {}, "sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ=="], - "@clack/core": ["@clack/core@1.5.1", "", { "dependencies": { "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ=="], - - "@clack/prompts": ["@clack/prompts@1.8.1", "", { "dependencies": { "@clack/core": "1.5.1", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ=="], - "@cloudflare/computer": ["@cloudflare/computer@https://github.com/K-Mistele/computer/releases/download/fold-91611593a1d7/cloudflare-computer-0.3.1.tgz", { "dependencies": { "acorn": "^8.17.0", "capnweb": "^0.10.0", "just-bash": "^3.0.1" }, "peerDependencies": { "@platformatic/vfs": "*", "ai": "^6.0.196 || ^7.0.0", "zod": "^4.4.3" }, "optionalPeers": ["@platformatic/vfs", "ai", "zod"] }, "sha512-TC9Pqi3UtVbaA/jSW9ZOVUQcfnQaSJdJkTK1sc8oL0skyopVFtjxX6N3vrbqzavN50zKXpxTDPL6xRh6hyP2VQ=="], "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.2", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": ">1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-JBP1+Z7ZSNG/d4mRP+y8VC5dka3tZVMLEZRvS+rzQ4DGV1EoxRFQckcJTTkXbHSQiTj0DtNI01Zwb/V2fX0mvQ=="], - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260704.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-XO+vvdhhTNZSsIWCkZ+JaE/JrFUmQAB0H0y/sVkAf32xa2TYBRvFUMwjSqf6WxtlxcKPQvmbLfpO/UQ0l/q4eQ=="], + "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260918.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-H5Em6Wd0jjxaloYh2rp+WLBl2eWbkk7nSP1svGt6K1RSv/rNVqmKdpjZPJTBSavOmeYGa88qvtOWwS+33OHTqQ=="], - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260704.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-6iI7nbOOO8PzEQ6UZVBZB/hv95m8jl0yvyjMuWrF5cJbiLb5zPw3KnpqvGi+aeOs2ZmUkc81i1FWKfXwLXzPRA=="], + "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260918.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-CR9JRZEQo93fNgBVF4Df2H2/VYO4n7rxSseSwCVv3bJQEb0huADUSCj2FK4ipxar8ToOEB4wawyw0vJo5U/rQQ=="], - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260704.1", "", { "os": "linux", "cpu": "x64" }, "sha512-3mT0YHtxT7eLjghu3hKSJDUQoz+AYv8FM43nLPYhM0YiHOxr8OlmvnCb2Lp7v/U3bwd3Gnx7WEqjSppR583mGg=="], + "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260918.1", "", { "os": "linux", "cpu": "x64" }, "sha512-UQ2nnY3qpXLzQ80frmWO+8HvtqyWaQILe8QYZwpemdjT+sqwCz4Dz+0/WVkFco0v/04kIIqikVeLTY/7gEhmkw=="], - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260704.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-Opo7cPTPg4x0WwK+eZSDszCyFLKQkOGNCWxF005HRTJ5SJH8h0K9KyrC1k4LBwx3haXSVi+E1eGqo1gZ1Hmhkg=="], + "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260918.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-4rib51MaLNWweUIUxM/Xj558M5QmyZoBSf0ffv+lYah5VTrvwnez3XGxX72pElnBKHROvAPOi5msQ5Ts8JSI0A=="], - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260704.1", "", { "os": "win32", "cpu": "x64" }, "sha512-a97Ecnzhy04x3U052VKPCNp863F7Wf00WY7Ga5P0SbtYvaO1PDzylsHrvFMPKeiDFcOwqiredawmJ+v6bhIgeQ=="], + "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260918.1", "", { "os": "win32", "cpu": "x64" }, "sha512-sATrMx5ShYYgmgUGrcTmvsFSJBFuN95NEkX3xwb1qk8w1A6h5N11sea7yN2IeibwPyPmXKjWNjXOno0hZAM71Q=="], "@cloudflare/workers-types": ["@cloudflare/workers-types@5.20260929.1", "", {}, "sha512-VlkFyzSqv2LeMK92eyyfnNvSTW4Nu37cR8T8OM4FF2xcNCsGy8/BxcNk9Jr4ZV0PlmKsCKvS49CfRZTVKBseUw=="], - "@distilled.cloud/aws": ["@distilled.cloud/aws@1.0.0-rc.8", "", { "dependencies": { "@aws-crypto/crc32": "^5.2.0", "@aws-crypto/util": "^5.2.0", "@aws-sdk/credential-providers": "^3.994.0", "@aws-sdk/types": "^3.973.1", "@distilled.cloud/core": "1.0.0-rc.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "aws4fetch": "^1.0.20", "fast-xml-parser": "^5.3.4" }, "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-eL4tRACU4TSykk/6+ItwUTZs93r3tRlrBn36ohqaUxqYYOfmssYlt/SLCzos4nlLgCxb+1T6BAstgYC848v1EQ=="], + "@distilled.cloud/acme": ["@distilled.cloud/acme@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-3rmzH125jQxk0zpCvXGNEybSaqpAolyCX+8LWDDrXf+wIKs67GflkJyQLjOOh0lKARe29hdUZGgqEbbvpp0LNA=="], + + "@distilled.cloud/aws": ["@distilled.cloud/aws@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13", "@smithy/types": "^4.17.2" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-6ZGcp0LkniB0I2l8Gr7vKRQgTZTch0/07iuvuMZv9Nu+rWwNuZG9VHTUdlIoarWgCHFUNN8yvSYBGOjaeN99tQ=="], + + "@distilled.cloud/axiom": ["@distilled.cloud/axiom@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-aRoJtvfXgWi5dtfjuJvDwnArRKvv2MPYHCxYeZcxZbqe62IaQA5yu/khft7TJvxeDyJoSDnVXZu3RyJjNmBA4g=="], + + "@distilled.cloud/cloudflare": ["@distilled.cloud/cloudflare@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-Py5FoA6azyYExDb91VaeC+9x+ravOBSRhXeUmpcQjCtgqmOdiXgc2YZGMMPI68DF+kMuHRVIrR+2uRZNDOhYjw=="], + + "@distilled.cloud/core": ["@distilled.cloud/core@1.0.0-rc.13", "", { "dependencies": { "graphql": "16.11.0" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-RYyrxW+F5zrTuu1UWV/JoycholBCIkXIusYJdDniDwCdmbjdKGl07KlkkeeY774uBawNGf+pt1ESNGeLVnNHsg=="], + + "@distilled.cloud/doppler": ["@distilled.cloud/doppler@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-GgOEUCc4Bx0C+lYNfZ4OqaA3ULvqDUQTJC8gobSh1L0jfrWclv/kRcSr43v4IXyStld+saUvDfDZgeGzlE74OA=="], - "@distilled.cloud/axiom": ["@distilled.cloud/axiom@1.0.0-rc.8", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.8" }, "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-lczeM0FPuF1mLZu7V8vcj8Klm9b1VSo4A75PP2a4km/cjphDl9LKamUwrSGLEY9denmqd1nn4+g2Svw1UmGpEw=="], + "@distilled.cloud/fly-io": ["@distilled.cloud/fly-io@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-Ipp+9nvs+PzqwDPhZq2/BEHNUeWzXKhrvjfT/eBLFHo/QpH0HgdMH8MSQe6/LGszZoormwA6ZrTv2wxaFO7ZiQ=="], - "@distilled.cloud/cloudflare": ["@distilled.cloud/cloudflare@1.0.0-rc.8", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.8" }, "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-nhEyGOaupi/JmT0PS1DEMH5Ebwu004pvQv3Emzt9MJz3mF3LTdiuAnxP86rf3jsFtfa826TDokKArVMq55OKRA=="], + "@distilled.cloud/gcp": ["@distilled.cloud/gcp@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-un8jqil9ejt96oN+OfEDUsbrEOpC6Ut4B/73DqKDttvt0Btal1OeBNTTQsftVCpeEzXAvkYKGRIT2AeEu1J5jA=="], - "@distilled.cloud/core": ["@distilled.cloud/core@1.0.0-rc.8", "", { "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-baZMSaBh9kEyAqdhO+UbkvVDK+wqyI8d0UW0paSp5CqVResOl7ydHU4tCbBUOLoxOrqLRWfmImKrhW9SY1R8qw=="], + "@distilled.cloud/hetzner": ["@distilled.cloud/hetzner@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-FvqofgMypNkeZbnjGjWMZqvqGd9GxcMzdbi/6JrbcPaHMJG+CCBGt/mAa7mLlEovzwVaGCsBnOXJ6rP5pZjB4Q=="], - "@distilled.cloud/fly-io": ["@distilled.cloud/fly-io@1.0.0-rc.8", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.8" }, "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-0HqVLIpBxmuvrIrnmziz8iK39F5cBxkHlz43WR2s+tFidbPlCzmnci6gxixxiwMBCzcmiRmv57xQxuQzgfDQMw=="], + "@distilled.cloud/infisical": ["@distilled.cloud/infisical@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-Zz8ksA/Y8UUUnWag2UBxB5WYA6wLqOS78ugWJ3cOr9Ot+4bC0NJYWanq35uFInozLXWhun84USU2wOI+mdwQUQ=="], - "@distilled.cloud/hetzner": ["@distilled.cloud/hetzner@1.0.0-rc.8", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.8" }, "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-CAPj912qUQXMetyFvJEc7PJnSG4DR6RBvGXCOfQcJVgGTspt/IdT3iIeIInTUf6rgFRsqoGiRfS4ywTqWoqLFA=="], + "@distilled.cloud/neon": ["@distilled.cloud/neon@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-2JvbBFj1kBfkDVPnWcJZ7TJ1cJwWBtScAY7SNJ2qNBUuAK1Wf2kjJXU0/j16eCJ48BQigPArQFWL51wVu/EUQQ=="], - "@distilled.cloud/neon": ["@distilled.cloud/neon@1.0.0-rc.8", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.8" }, "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-xIgxgoDyIs/G5lW8T2r4oyHpOcRzBO1wu7p46lU3ppuJ2rlJR4pmP9dF7KxStAVglr9yK3wmmmnraLoCAtd8Sg=="], + "@distilled.cloud/planetscale": ["@distilled.cloud/planetscale@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-AM97YGRnDfZdqsxFgQMQ83p7ZlRqxS6/foTTJA5P590UMbbOyrQyFyd33BD0agul8a3ngZde3Oej6v7BN55aWw=="], - "@distilled.cloud/planetscale": ["@distilled.cloud/planetscale@1.0.0-rc.8", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.8" }, "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-D0mnkT2Gnk/SKWoz05rkf7+sngH8+5m5ugjQ1GycsFMfTxUVSIVUIHX9yrO5vFrTsMlNsmrMR+7a9R3ZMGCWkA=="], + "@distilled.cloud/prisma": ["@distilled.cloud/prisma@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-+UmHSp9JV8XQl5t5tTdQBY+dWZ9abrEoc7leYEctA0Ar1TrKZEl2EaeQDoumrg4RyGaacRlirEbxaDFI4SOPtQ=="], - "@distilled.cloud/railway": ["@distilled.cloud/railway@1.0.0-rc.8", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.8" }, "peerDependencies": { "effect": ">=4.0.0-rc.112 || >=4.0.0" } }, "sha512-VW2YdbblVHhYww5JVtOjFlv3jBFl7xlt6/xTfkNxxgXgzJ5GYVlD3gPgBIpGy9Pcnv9rVRA6CL7QZeYeu47c9Q=="], + "@distilled.cloud/railway": ["@distilled.cloud/railway@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-yXalRS3GFLo3hWM0HXptqudi23NVCM4FRD20db2/Ob9FFcNrMJik1fopv+74HOiV+BuxfkCP609KsEK6LVdB/g=="], - "@effect/platform-bun": ["@effect/platform-bun@4.0.0-rc.112", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-rc.112" }, "peerDependencies": { "effect": "^4.0.0-rc.112" } }, "sha512-Y5n2HhV/vsbrJls9ukX42RL7zqXQxISHegWFsP9njsCyDmGTnq7QYSO82rglwrLPwtTrv5dkSRTuGw4+oXxgMg=="], + "@distilled.cloud/stripe": ["@distilled.cloud/stripe@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-jLTJ1mg4U39lHZb9EGYBJLR91yB3LSG6fVxix+r1BbqaTovWzE+NuJ7fu9fRSeax9jRAqsGLLxe9IxJbOtwQnQ=="], - "@effect/platform-node": ["@effect/platform-node@4.0.0-rc.112", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-rc.112", "mime": "^4.1.0", "undici": "^8.10.0" }, "peerDependencies": { "effect": "^4.0.0-rc.112", "redis": ">=5.0.0 <7.0.0" } }, "sha512-/BMAcdNGQQskLmI0Zoa95KfTZkr9HV9N4NSxaSrusG6GeW6Ulp9KvZ+Rlaiw8lnOt43CXjFLdfll5/k5rxL4hQ=="], + "@distilled.cloud/zerossl": ["@distilled.cloud/zerossl@1.0.0-rc.13", "", { "dependencies": { "@distilled.cloud/core": "1.0.0-rc.13" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-dnxhg39lZjpTdZbHCVYPoUC9E2r8eSHbqiYDhSq2EurVPJcc9YRXlxZR1bP1nniSp078XV8GA+aUECt/Z56aQg=="], - "@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-rc.112", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.21.3" }, "peerDependencies": { "effect": "^4.0.0-rc.112" } }, "sha512-ttjz0xKamFN7vL8pNDYVwddJLjZvqKePc05djlz2VcdaKbLsnYbtMnL1rbOfHgEnIUSHGh7FkjaN4DM1Ov81sQ=="], + "@effect/platform-bun": ["@effect/platform-bun@4.0.0", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-g9O41Sub/+JKfLjvBNEoqR1Pg6wtc2bbYzv7Kw8YsMihbt/ypCn7ZoydEXaHvTTUvbVrXOQbVFlfplyo84Clug=="], - "@effect/sql-d1": ["@effect/sql-d1@4.0.0-rc.118", "", { "dependencies": { "@cloudflare/workers-types": "^5.20260926.1" }, "peerDependencies": { "effect": "^4.0.0-rc.118" } }, "sha512-V9Pma4c1ecRqQig3KaLTIV4AptUNgojWoIw55VgkDhQBtmrZhrd4V617/FNna11S7L1VePth5vUBNt/kFxs4iQ=="], + "@effect/platform-node": ["@effect/platform-node@4.0.0", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0", "undici": "^8.11.2" }, "peerDependencies": { "effect": "^4.0.0", "redis": ">=5.0.0 <7.0.0" } }, "sha512-/L+4MUbl8FejPKLHLROYSOebvHnfixkP8KiblSD/DE5uH5xENZBHaux4nH6XMnRP+lr8ajpEJFS8sUrmmxFJeQ=="], - "@effect/sql-sqlite-do": ["@effect/sql-sqlite-do@4.0.0-rc.118", "", { "peerDependencies": { "effect": "^4.0.0-rc.118" } }, "sha512-wuT52JOf5vqekrjprLDwNkjBk13xXB0rNUlbdPD645CajQmYgtAfpVlMv/329UNmsCUGoxUdYYglcl8xtpZlfQ=="], + "@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.22.0" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-VBXHJU9UXVZPdQGGDRjGXpo+TpOzRwZuMrdKAtIxi1qwcRftmacZ1zTgIrzBa0Z2RA2KVkoOecQUsTlt/nJZhw=="], - "@effect/tsgo": ["@effect/tsgo@0.47.0", "", { "optionalDependencies": { "@effect/tsgo-darwin-arm64": "0.47.0", "@effect/tsgo-darwin-x64": "0.47.0", "@effect/tsgo-linux-arm": "0.47.0", "@effect/tsgo-linux-arm64": "0.47.0", "@effect/tsgo-linux-x64": "0.47.0", "@effect/tsgo-win32-arm64": "0.47.0", "@effect/tsgo-win32-x64": "0.47.0" }, "bin": { "effect-tsgo": "dist/effect-tsgo.cjs" } }, "sha512-70L1cp9Lj8rJeKmLseg2RLaQ95IM2CR3BFF6Ytq1fjio3V9cEwMuOzBYSRlIAK2x+dTyxvFdabvbMr+DF7XD7g=="], + "@effect/sql-d1": ["@effect/sql-d1@4.0.0", "", { "dependencies": { "@cloudflare/workers-types": "^5.20260926.1" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-pmkzncZCGD6CLyvc89keEBU85h+gHVCu/LKQnThd+ruYSUbG0R9jYA+lnk3R8Djp0wQW6SbsbmHQuhopIYyo3Q=="], - "@effect/tsgo-darwin-arm64": ["@effect/tsgo-darwin-arm64@0.47.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-X4MF7+GOiOk0EzcdY2bqSFl8yXYoD3VvzFcDE5ZyEO1oLGa4UGJjRmJBQt/LQFil8MW68uvAmE+Thh/Y2VTyuA=="], + "@effect/sql-sqlite-do": ["@effect/sql-sqlite-do@4.0.0", "", { "peerDependencies": { "effect": "^4.0.0" } }, "sha512-XkRZmQOPblzwjmAJ0RWSOiLlTsKkf1EigZsxUNuIuk4uZ/pnufSqvDpXubCwv8iyRTbOLFMmM+EyOEH5V5XqAw=="], - "@effect/tsgo-darwin-x64": ["@effect/tsgo-darwin-x64@0.47.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-vANaJYOFsIpX5KiMI0p3Y1DeFIT6N1Y8uTeBo6WKOCfeI1r0vcMUX1gEiLDPJBdweH7bbvyzbiUFX0/fnWgKEg=="], + "@effect/tsgo": ["@effect/tsgo@0.48.0", "", { "optionalDependencies": { "@effect/tsgo-darwin-arm64": "0.48.0", "@effect/tsgo-darwin-x64": "0.48.0", "@effect/tsgo-linux-arm": "0.48.0", "@effect/tsgo-linux-arm64": "0.48.0", "@effect/tsgo-linux-x64": "0.48.0", "@effect/tsgo-win32-arm64": "0.48.0", "@effect/tsgo-win32-x64": "0.48.0" }, "bin": { "effect-tsgo": "dist/effect-tsgo.cjs" } }, "sha512-802nDQDmDxT/zGtGqJp+AVvhMMHfnHNxdAK92612hDU1ba1fWrXlxY2ayuTi3iACIP94NCIdSaFRaTcqw/FEnw=="], - "@effect/tsgo-linux-arm": ["@effect/tsgo-linux-arm@0.47.0", "", { "os": "linux", "cpu": "arm" }, "sha512-nmoRTsK8nfcPl2uhksmxpyXFoKcAHkZPrUiSheO8wEbdCo/aFTe2UKfAgrRtMZ8qr3gD1tpKxXWrRfvlZTwp0g=="], + "@effect/tsgo-darwin-arm64": ["@effect/tsgo-darwin-arm64@0.48.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MGfjTc/ZLlX045/7br+adgpyo6z/4MJIzMgnISYVWvUgIOzGbGbwdlkINHn4x0ADKZh3f8M2jBzGPv0BPp9m/A=="], - "@effect/tsgo-linux-arm64": ["@effect/tsgo-linux-arm64@0.47.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-44tFG3S9MU6vQCsDIQlV/72NHrAmo4T9Q6adFJDNjaRzv4eIEu9TPHAflIVghCRFWkmvhElnKp6VSh4vJ5jwlw=="], + "@effect/tsgo-darwin-x64": ["@effect/tsgo-darwin-x64@0.48.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-8szoWf9x70jsdanlS3420SdyEBL587nuNbtFz3kX+e2siMM0VJpB5pkyHdHhS+b55aV2Q3mwzdzAogpR2QfCKQ=="], - "@effect/tsgo-linux-x64": ["@effect/tsgo-linux-x64@0.47.0", "", { "os": "linux", "cpu": "x64" }, "sha512-DL3DiNZNMKnEdVNHpQPtuDSV4DdAtY6owgfQYYgF1uExjqS/5ZWZICEm1ZpdeLMIaCFbRdeSv7uEu1RrTGCuyw=="], + "@effect/tsgo-linux-arm": ["@effect/tsgo-linux-arm@0.48.0", "", { "os": "linux", "cpu": "arm" }, "sha512-bT+WWcJ825itR2Zv/XLiCpMN4jqT95hwdWOcb5hBo+kRZhSYBfDupBeEQWea62BTBUvM6d0TzufIyTYEFtVBpw=="], - "@effect/tsgo-win32-arm64": ["@effect/tsgo-win32-arm64@0.47.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-LctXaODCUDIjmxcSqqQ2OnLffQwLIct09YsAs9ZiTBPnxdRy4eQYPxe4ImfvTIEDkYDG/nfG3h7tL+EIvix45A=="], + "@effect/tsgo-linux-arm64": ["@effect/tsgo-linux-arm64@0.48.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-GDhHkqiAh97Xkrf6zNKJVROkCnyrxGxw5LB2YecVxycIjcCqFn7CQW98LkBDTPgEr1tvW/RPUg64GSlMkJbl9A=="], - "@effect/tsgo-win32-x64": ["@effect/tsgo-win32-x64@0.47.0", "", { "os": "win32", "cpu": "x64" }, "sha512-keYrly656yhEdB3pigkCJaT2oI7I7RcB1QcF4akTggBNuLsh1WT5Ksy2xuHD8QkUiNz6pRwFUSW9Qh83zJQX8g=="], + "@effect/tsgo-linux-x64": ["@effect/tsgo-linux-x64@0.48.0", "", { "os": "linux", "cpu": "x64" }, "sha512-P/NZ51S1bMYygEw5g50QjHY/lDapV2vdkh4GW6Ewyze4j+lOCHb395/DgkR1rege8WwLxxcnrCoJ5uAQFfuz5Q=="], - "@effect/vitest": ["@effect/vitest@4.0.0-rc.112", "", { "peerDependencies": { "effect": "^4.0.0-rc.112", "vitest": ">=4.1.0 <5.0.0" } }, "sha512-mEKh/FI64mt8JK1/v9mpOrJYdnp+UFZdRUBMEdZMiKz7klg6NPqVgg/oeAGH6wOOQc2iAPcfc2H9BbAv1KyzMQ=="], + "@effect/tsgo-win32-arm64": ["@effect/tsgo-win32-arm64@0.48.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-K06BaR2cGq79BMmQsoaYjBLn1flWvq2iGYMdcLEI91W8rh2nyzLw7pr82CTwgyIKe/HuUqh8CEyyueTBMq8uHQ=="], + + "@effect/tsgo-win32-x64": ["@effect/tsgo-win32-x64@0.48.0", "", { "os": "win32", "cpu": "x64" }, "sha512-NBeaA0llPlosW2HFBOI8BbBYAi66RmK31rA/yDoREOG3i0S+t0wtB0eRJMjjlBw1lj6kwdIKdP3XMsaNscJ7gw=="], + + "@effect/vitest": ["@effect/vitest@4.0.0", "", { "peerDependencies": { "effect": "^4.0.0", "vitest": ">=5.0.0 <6.0.0" } }, "sha512-kGElCPFGtP+CgMCwV/HjJWqtE3zYo6I1+8MSA54l+EI24lPU9p2Efa+TBp1jfkg9j711KKzEqgSAy3VzTsb76Q=="], "@electric-sql/pglite": ["@electric-sql/pglite@0.3.15", "", {}, "sha512-Cj++n1Mekf9ETfdc16TlDi+cDDQF0W7EcbyRHYOAeZdsAe8M/FJg18itDTSwyHfar2WIezawM9o0EKaRGVKygQ=="], @@ -630,22 +602,12 @@ "@mrleebo/prisma-ast": ["@mrleebo/prisma-ast@0.13.1", "", { "dependencies": { "chevrotain": "^10.5.0", "lilconfig": "^2.1.0" } }, "sha512-XyroGQXcHrZdvmrGJvsA9KNeOOgGMg1Vg9OlheUsBOSKznLMDl+YChxbkboRHvtFYJEMRYmlV3uoo/njCw05iw=="], - "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ=="], - - "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w=="], - - "@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4", "", { "os": "linux", "cpu": "arm" }, "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw=="], - - "@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw=="], - - "@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ=="], - - "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", "", { "os": "win32", "cpu": "x64" }, "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], "@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="], + "@neon/functions": ["@neon/functions@0.11.0", "", { "peerDependencies": { "hono": "^4.7.8" }, "optionalPeers": ["hono"] }, "sha512-xyIEk9aULR2nBTzyTgxljkM8aS+Ppe9oVw/t5mdqYOlY/mLFppHSZHq8hiWVDWy6Ca8oLd3loTtfVz+cZQQjsA=="], + "@noble/hashes": ["@noble/hashes@2.2.0", "", {}, "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg=="], "@nodable/entities": ["@nodable/entities@3.1.0", "", {}, "sha512-LsS/DjHr+uDM647Gru/cA8+J3a3HfhttwCKLyuoyN7yXTFCxKBtSgMQBvrW9yNPa2/zDRUNuGPaH5QUFoa4arQ=="], @@ -862,30 +824,8 @@ "@silvia-odwyer/photon-node": ["@silvia-odwyer/photon-node@0.3.4", "", {}, "sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA=="], - "@smithy/core": ["@smithy/core@3.35.0", "", { "dependencies": { "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-zRMhfkByhT2snNdr1si24vJitU6Cr9ix2MikUfWmkAgp4jrNP0GcKSP5YvwQ+TlI8AZXER5QOGJn3JsVtSD9/A=="], - - "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.5.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg=="], - - "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.8.0", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA=="], - - "@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], - - "@smithy/node-config-provider": ["@smithy/node-config-provider@4.6.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "tslib": "^2.6.2" } }, "sha512-zMrXu/O5tPa7GLtra8L4wFG6DACcXT9QV4Ay+WEAjUhXm1dVq7c/q9Qv9gkJZNLY8hmQKg08778kDcxpKNMqOA=="], - - "@smithy/node-http-handler": ["@smithy/node-http-handler@4.12.1", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw=="], - - "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.7.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "tslib": "^2.6.2" } }, "sha512-XsIDj5gVG4YRxGS4n4TiBDAogPWRHXKZyor6JW/sEuaa/7BvKADe9j45jI2dPYCnYbKkLBmbZ4qN9ns0sH+kMQ=="], - - "@smithy/signature-v4": ["@smithy/signature-v4@5.7.4", "", { "dependencies": { "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-tHy0K0VtqNd5Y7Y41h0a0Lhh0L1GzC08dTWg0F7vRJWFtTENg7IZikf3wQkanYIRdb7ngoIPMTmqgUi401fEeQ=="], - "@smithy/types": ["@smithy/types@4.19.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-r7jh49VJxGerfAcTQA6gXcKc+98zOp/tqRwzYjgOE+iSQsP6cEU1hq2QzbuipmP68QtYdY9wKEhiCQZIzHgZ4Q=="], - "@smithy/util-base64": ["@smithy/util-base64@4.6.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "tslib": "^2.6.2" } }, "sha512-wTQX1hPfElIqY6AzM/s6c4UgpMxCL4MwJ5u6340ksLPq78lur6Y+keheIDk5gMX4G3KFh4MERcDt6xhRq+ie1Q=="], - - "@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - - "@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="], @@ -970,9 +910,7 @@ "acorn": ["acorn@8.18.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ=="], - "alchemy": ["alchemy@2.0.0-beta.76", "", { "dependencies": { "@alchemy.run/cloudflare-runtime": "2.0.0-beta.76", "@alchemy.run/floci": "2.0.0-beta.76", "@alchemy.run/node-utils": "2.0.0-beta.76", "@aws-sdk/credential-providers": "^3.0.0", "@clack/prompts": "^1.7.0", "@distilled.cloud/aws": "1.0.0-rc.8", "@distilled.cloud/axiom": "1.0.0-rc.8", "@distilled.cloud/cloudflare": "1.0.0-rc.8", "@distilled.cloud/core": "1.0.0-rc.8", "@distilled.cloud/fly-io": "1.0.0-rc.8", "@distilled.cloud/hetzner": "1.0.0-rc.8", "@distilled.cloud/neon": "1.0.0-rc.8", "@distilled.cloud/planetscale": "1.0.0-rc.8", "@distilled.cloud/railway": "1.0.0-rc.8", "@effect/sql-d1": ">=4.0.0-rc.112 || >=4.0.0", "@effect/sql-sqlite-do": ">=4.0.0-rc.112 || >=4.0.0", "@effect/vitest": ">=4.0.0-rc.112 || >=4.0.0", "@libsql/client": "^0.17.0", "@octokit/rest": "^22.0.1", "@octokit/webhooks": "^14.2.0", "@prisma/dev": "^0.20.0", "@smithy/node-config-provider": "^4.0.0", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@types/aws-lambda": "^8.10.152", "aws4fetch": "^1.0.20", "capnweb": "^0.6.1", "fast-glob": "^3.3.2", "fast-xml-parser": "^5.3.4", "ink": "^6.3.1", "jszip": "^3.10.1", "libsodium-wrappers": "^0.8.3", "pathe": "^2.0.3", "picomatch": "^4.0.4", "react": "^19.2.0", "rolldown": "1.2.5", "undici": "^7.16.0", "yaml": "^2.0.0" }, "peerDependencies": { "@alchemy.run/frontend-frameworks": "2.0.0-beta.76", "@aws/durable-execution-sdk-js": "^2.1.0", "@effect/platform-bun": ">=4.0.0-rc.112 || >=4.0.0", "@effect/platform-node": ">=4.0.0-rc.112 || >=4.0.0", "@effect/sql-mysql2": ">=4.0.0-rc.112 || >=4.0.0", "@effect/sql-pg": ">=4.0.0-rc.112 || >=4.0.0", "@vercel/nft": "^1.10.2", "drizzle-kit": "1.0.0-rc.5-ab785fc", "drizzle-orm": "1.0.0-rc.5-ab785fc", "effect": ">=4.0.0-rc.112 || >=4.0.0", "mongodb": "^6.10.0", "mysql2": "^3.24.2", "pg": "^8.22.0", "vite": "^8.0.7", "ws": "^8.20.0" }, "optionalPeers": ["@alchemy.run/frontend-frameworks", "@aws/durable-execution-sdk-js", "@effect/platform-bun", "@effect/platform-node", "@effect/sql-mysql2", "@effect/sql-pg", "@vercel/nft", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "pg", "vite", "ws"], "bin": { "alchemy": "./bin/cli.js" } }, "sha512-XpcsXWk38YV9nO0v7s5PPjlMVtF8OQPeP8YqLu1iMzrq33bwViEOqkwQn3cgFiD7/QsnNcCju+hCXyeBwXrdtg=="], - - "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], + "alchemy": ["alchemy@2.0.0-beta.80", "", { "dependencies": { "@alchemy.run/cloudflare-runtime": "2.0.0-beta.80", "@alchemy.run/floci": "2.0.0-beta.80", "@alchemy.run/node-utils": "2.0.0-beta.80", "@alchemy.run/sigil": "0.1.0-alpha.1", "@distilled.cloud/acme": "1.0.0-rc.13", "@distilled.cloud/aws": "1.0.0-rc.13", "@distilled.cloud/axiom": "1.0.0-rc.13", "@distilled.cloud/cloudflare": "1.0.0-rc.13", "@distilled.cloud/core": "1.0.0-rc.13", "@distilled.cloud/doppler": "1.0.0-rc.13", "@distilled.cloud/fly-io": "1.0.0-rc.13", "@distilled.cloud/gcp": "1.0.0-rc.13", "@distilled.cloud/hetzner": "1.0.0-rc.13", "@distilled.cloud/infisical": "1.0.0-rc.13", "@distilled.cloud/neon": "1.0.0-rc.13", "@distilled.cloud/planetscale": "1.0.0-rc.13", "@distilled.cloud/prisma": "1.0.0-rc.13", "@distilled.cloud/railway": "1.0.0-rc.13", "@distilled.cloud/stripe": "1.0.0-rc.13", "@distilled.cloud/zerossl": "1.0.0-rc.13", "@effect/sql-d1": "^4.0.0", "@effect/sql-sqlite-do": "^4.0.0", "@libsql/client": "^0.17.0", "@neon/functions": "0.11.0", "@octokit/rest": "^22.0.1", "@octokit/webhooks": "^14.2.0", "@prisma/dev": "^0.20.0", "@types/aws-lambda": "^8.10.152", "capnweb": "^0.12.0", "fflate": "^0.8.3", "libsodium-wrappers": "^0.8.3", "pathe": "^2.0.3", "picomatch": "^4.0.4", "rolldown": "1.2.5", "tinyglobby": "^0.2.17", "yaml": "^2.9.0" }, "peerDependencies": { "@alchemy.run/frontend-frameworks": "2.0.0-beta.80", "@aws/durable-execution-sdk-js": "^2.1.0", "@effect/platform-bun": "^4.0.0", "@effect/platform-node": "^4.0.0", "@effect/sql-mysql2": "^4.0.0", "@effect/sql-pg": "^4.0.0", "@effect/vitest": "^4.0.0", "@prisma/orm-postgres": "8.0.0-rc.11", "@vercel/nft": "^1.10.2", "drizzle-kit": "1.0.0-rc.5-ab785fc", "drizzle-orm": "1.0.0-rc.5-ab785fc", "effect": "^4.0.0", "mongodb": "^6.10.0", "mysql2": "^3.24.2", "pg": "^8.22.0", "prisma": "8.0.0-rc.15", "vite": "^8.0.7", "ws": "^8.21.0" }, "optionalPeers": ["@alchemy.run/frontend-frameworks", "@aws/durable-execution-sdk-js", "@effect/platform-bun", "@effect/platform-node", "@effect/sql-mysql2", "@effect/sql-pg", "@effect/vitest", "@prisma/orm-postgres", "@vercel/nft", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "pg", "prisma", "vite", "ws"], "bin": { "alchemy": "./bin/cli.js" } }, "sha512-2y7mswypPiApxuEdp8NGMfzCGB5+9W6OmQAuePyZ2xBkgoCpEqtKAnASuvKGUZPSYNESENbamXDuI5428ewu9w=="], "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], @@ -984,10 +922,6 @@ "ast-v8-to-istanbul": ["ast-v8-to-istanbul@1.0.5", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.31", "estree-walker": "^3.0.3", "js-tokens": "^10.0.0" } }, "sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA=="], - "auto-bind": ["auto-bind@5.0.1", "", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="], - - "aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], - "babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.7", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-/O6JWUmjv03OI9lL2ry9bUjpD5S3PclM55RRJEyCdcFZ5W2SEA/59d+l2hNsk3gI6kiWRdRPdOtqZmsQzFN1pQ=="], "babel-plugin-module-resolver": ["babel-plugin-module-resolver@5.0.2", "", { "dependencies": { "find-babel-config": "^2.1.1", "glob": "^9.3.3", "pkg-up": "^3.1.0", "reselect": "^4.1.7", "resolve": "^1.22.8" } }, "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg=="], @@ -1006,8 +940,6 @@ "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], - "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="], - "brace-expansion": ["brace-expansion@5.0.12", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], @@ -1022,40 +954,28 @@ "caniuse-lite": ["caniuse-lite@1.0.30001805", "", {}, "sha512-52noaS3DubycKSXaU30TwPGIp+POyQSUVa5jBEq3vkRkY0kjyb3LQgvhU6WGyCcyXqVLWO0Cw0Q6BSdD0kUfVA=="], - "capnp-es": ["capnp-es@0.0.14", "", { "peerDependencies": { "typescript": "^5.7.3" }, "optionalPeers": ["typescript"], "bin": { "capnp-es": "dist/compiler/capnpc-js.mjs", "capnpc-js": "dist/compiler/capnpc-js.mjs", "capnpc-ts": "dist/compiler/capnpc-ts.mjs", "capnpc-dts": "dist/compiler/capnpc-dts.mjs" } }, "sha512-8lWj4GJISiqRSlAJGkWpI4Azib7QY5UDIkqxeHcI7aAnXVk9SFuWxl1Fme+2HhzNANV0WTJqwUZvvXvloc3sBA=="], + "capnp-es": ["capnp-es@0.0.16", "", { "peerDependencies": { "typescript": "^5.7.3 || ^6.0.0" }, "optionalPeers": ["typescript"], "bin": { "capnp-es": "dist/compiler/capnpc-js.mjs", "capnpc-js": "dist/compiler/capnpc-js.mjs", "capnpc-dts": "dist/compiler/capnpc-dts.mjs", "capnpc-ts": "dist/compiler/capnpc-ts.mjs" } }, "sha512-pqhhnRqGfDdgHa+rz4JVO9j1jnkyqsHRYrD4RBtIwxCknYSRG7Mjs+x3IRfd20u+ZGS0IhW2L7cDv9ZcIkCYhQ=="], "capnweb": ["capnweb@0.10.0", "", {}, "sha512-lQ2nlzaifkqBeNfs8RLErn7NZ8FNf3vn1W7J3nSH73edWG+0B5nHZGR51S2S9HMZEuZcEypOO469dZRY/BluFA=="], "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], - "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], - "chevrotain": ["chevrotain@10.5.0", "", { "dependencies": { "@chevrotain/cst-dts-gen": "10.5.0", "@chevrotain/gast": "10.5.0", "@chevrotain/types": "10.5.0", "@chevrotain/utils": "10.5.0", "lodash": "4.17.21", "regexp-to-ast": "0.5.0" } }, "sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A=="], - "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], - - "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], - - "cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="], + "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], - "cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="], + "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], "cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="], "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="], - "code-excerpt": ["code-excerpt@4.0.0", "", { "dependencies": { "convert-to-spaces": "^2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="], - "commander": ["commander@6.2.1", "", {}, "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="], "content-type": ["content-type@3.1.1", "", {}, "sha512-GW4qUsfFo59d0HbUibDlWv5wPz+vAAcaTWbKIuKCf0JkC7wWkSyf8f13IpXn5JkeMlB2P8iTSSIjwXljorg2vA=="], "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "convert-to-spaces": ["convert-to-spaces@2.0.1", "", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="], - - "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], - "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], @@ -1070,7 +990,7 @@ "diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="], - "effect": ["effect@4.0.0-rc.112", "", { "dependencies": { "fast-check": "^4.9.0", "msgpackr": "^2.0.5" } }, "sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A=="], + "effect": ["effect@4.0.0", "", {}, "sha512-ooc1TG5t+FfzgYnFz2ff6BBKyZ7EwBRVXC7c4RhQUAD6/TZ2gTXXMeb4WX7a19ozQo4J73/QW+S00YAIresoMQ=="], "electron-to-chromium": ["electron-to-chromium@1.5.391", "", {}, "sha512-YmCu4856jkgKT1Nh6fwRdeVrM6Ydf/fBnq51tpmSfX+jOcUMTxh31yH6hjKScRenhB2oDSvA9oooxcpjogPeig=="], @@ -1080,36 +1000,22 @@ "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], - "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], - "error-causes": ["error-causes@3.0.2", "", {}, "sha512-i0B8zq1dHL6mM85FGoxaJnVtx6LD5nL2v0hlpGdntg5FOSyzQ46c9lmz5qx0xRS2+PWHGOHcYxGIBC5Le2dRMw=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], "es-module-lexer": ["es-module-lexer@2.3.1", "", {}, "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA=="], - "es-toolkit": ["es-toolkit@1.52.0", "", {}, "sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA=="], - "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], - "escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="], - "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="], "expect-type": ["expect-type@1.4.0", "", {}, "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA=="], - "fast-check": ["fast-check@4.9.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg=="], - "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], - "fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="], - - "fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="], - - "fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="], - "fast-xml-builder": ["fast-xml-builder@1.3.1", "", { "dependencies": { "path-expression-matcher": "^1.6.2", "xml-naming": "^0.3.0" } }, "sha512-pIM/1n3ntFXKYrUZwW7QCK0gAW7XY+wzj1YMIV3tLDvPj/V+zTGJK5e3/4WJfwj0qWw2ElNXiTixda/R+3YSug=="], "fast-xml-parser": ["fast-xml-parser@5.11.2", "", { "dependencies": { "@nodable/entities": "^3.0.1", "fast-xml-builder": "^1.2.0", "is-unsafe": "^2.0.0", "path-expression-matcher": "^1.6.2", "strnum": "^2.4.2", "xml-naming": "^0.3.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-R9iDuNrQYeQut46cn2r2wHKn4HYzVDvDm5J1wW+koZewykv0yuO2HChTYeZtrULyHIDM9cj9TUXloCsueCQUog=="], @@ -1118,6 +1024,8 @@ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "fflate": ["fflate@0.8.3", "", {}, "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA=="], + "file-type": ["file-type@21.3.4", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], @@ -1156,6 +1064,8 @@ "graphmatch": ["graphmatch@1.1.1", "", {}, "sha512-5ykVn/EXM1hF0XCaWh05VbYvEiOL2lY1kBxZtaYsyvjp7cmWOU1XsAdfQBwClraEofXDT197lFbXOEVMHpvQOg=="], + "graphql": ["graphql@16.11.0", "", {}, "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw=="], + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], @@ -1170,32 +1080,20 @@ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="], - - "indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], - "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], "ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="], - "ink": ["ink@6.8.0", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.4", "ansi-escapes": "^7.3.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^5.1.1", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.33.0", "scheduler": "^0.27.0", "signal-exit": "^3.0.7", "slice-ansi": "^8.0.0", "stack-utils": "^2.0.6", "string-width": "^8.1.1", "terminal-size": "^4.0.1", "type-fest": "^5.4.1", "widest-line": "^6.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": ">=6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-sbl1RdLOgkO9isK42WCZlJCFN9hb++sX9dsklOvfd1YQ3bQ2AiFu12Q6tFlr0HvEUvzraJntQCCpfEoUe9DSzA=="], - "is-core-module": ["is-core-module@2.16.2", "", { "dependencies": { "hasown": "^2.0.3" } }, "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA=="], "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], - "is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], - "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], - "is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="], - "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], "is-unsafe": ["is-unsafe@2.0.2", "", {}, "sha512-HgbIHPBH0KHHCcjLfGsCvhtPTVxjaAZlXjwdz7/GQC40SjSe4sfQsar8J5VFo8JOSbarkpV0OLG95bbaNd9aAQ=="], - "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], - "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], @@ -1214,8 +1112,6 @@ "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], - "jszip": ["jszip@3.10.2", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-3l+rb15IOWtUhU0H5MFqES/T6Kh7abYwjosBey/vD6hDt8zoEffkSC5Ws5SGtgVw3gBx2NEbhTeSW1+kWkpyTQ=="], - "just-bash": ["just-bash@3.4.2", "", { "dependencies": { "diff": "^8.0.4", "fast-xml-parser": "^5.10.1", "file-type": "^21.3.4", "ini": "^6.0.0", "minimatch": "^10.2.6", "modern-tar": "^0.7.7", "papaparse": "^5.6.0", "quickjs-emscripten": "^0.32.0", "re2js": "^1.3.3", "seek-bzip": "^2.0.0", "smol-toml": "^1.8.0", "sprintf-js": "^1.1.3", "sql.js": "^1.14.1", "turndown": "^7.2.4", "undici": "^7.29.0", "yaml": "^2.9.0" }, "optionalDependencies": { "@mongodb-js/zstd": "^7.0.0", "node-liblzma": "^2.2.0" }, "bin": { "just-bash": "dist/bin/just-bash.js", "just-bash-shell": "dist/bin/shell/shell.js" } }, "sha512-T0Vpy7YRgCjxJdqG3tkxn0ZnIDLJvVwb8hH4L+6NVdp+Te27jQxjxnszW9ODjEKbWxWujj83rP5S0GQxCSufgg=="], "libsodium": ["libsodium@0.8.4", "", {}, "sha512-lMcYaRi0zcs7tarATsQUYC7rstliIXZuoq0c6zXSgNtSNtdvBgkSegjWhpMJAXzKX3SUSwIp7+zEsob+j3LuRw=="], @@ -1224,8 +1120,6 @@ "libsql": ["libsql@0.5.29", "", { "dependencies": { "@neon-rs/load": "^0.0.4", "detect-libc": "2.0.2" }, "optionalDependencies": { "@libsql/darwin-arm64": "0.5.29", "@libsql/darwin-x64": "0.5.29", "@libsql/linux-arm-gnueabihf": "0.5.29", "@libsql/linux-arm-musleabihf": "0.5.29", "@libsql/linux-arm64-gnu": "0.5.29", "@libsql/linux-arm64-musl": "0.5.29", "@libsql/linux-x64-gnu": "0.5.29", "@libsql/linux-x64-musl": "0.5.29", "@libsql/win32-x64-msvc": "0.5.29" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "arm", "x64", "arm64", ] }, "sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg=="], - "lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="], - "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], @@ -1272,8 +1166,6 @@ "mime": ["mime@4.1.0", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw=="], - "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], - "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], "minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="], @@ -1288,10 +1180,6 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "msgpackr": ["msgpackr@2.1.0", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-p/pBCVO63CsvvpkomUnNNag6+n38rULuDA6HHe70o2gtC8ODI52foF/4ko2qQcp6OiErJXTmrZeXmsGGHsIQNQ=="], - - "msgpackr-extract": ["msgpackr-extract@3.0.4", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw=="], - "nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="], "napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="], @@ -1302,8 +1190,6 @@ "node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="], - "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="], - "node-liblzma": ["node-liblzma@2.2.0", "", { "dependencies": { "node-addon-api": "^8.5.0", "node-gyp-build": "^4.8.4" }, "bin": { "nxz": "lib/cli/nxz.js" } }, "sha512-s0KzNOWwOJJgPG6wxg6cKohnAl9Wk/oW1KrQaVzJBjQwVcUGPQCzpR46Ximygjqj/3KhOrtJXnYMp/xYAXp75g=="], "node-releases": ["node-releases@2.0.51", "", {}, "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ=="], @@ -1312,8 +1198,6 @@ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], - "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], - "oxfmt": ["oxfmt@0.62.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.62.0", "@oxfmt/binding-android-arm64": "0.62.0", "@oxfmt/binding-darwin-arm64": "0.62.0", "@oxfmt/binding-darwin-x64": "0.62.0", "@oxfmt/binding-freebsd-x64": "0.62.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.62.0", "@oxfmt/binding-linux-arm-musleabihf": "0.62.0", "@oxfmt/binding-linux-arm64-gnu": "0.62.0", "@oxfmt/binding-linux-arm64-musl": "0.62.0", "@oxfmt/binding-linux-ppc64-gnu": "0.62.0", "@oxfmt/binding-linux-riscv64-gnu": "0.62.0", "@oxfmt/binding-linux-riscv64-musl": "0.62.0", "@oxfmt/binding-linux-s390x-gnu": "0.62.0", "@oxfmt/binding-linux-x64-gnu": "0.62.0", "@oxfmt/binding-linux-x64-musl": "0.62.0", "@oxfmt/binding-openharmony-arm64": "0.62.0", "@oxfmt/binding-win32-arm64-msvc": "0.62.0", "@oxfmt/binding-win32-ia32-msvc": "0.62.0", "@oxfmt/binding-win32-x64-msvc": "0.62.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-vxgGHTmnDU9j4CX7dDBLzxgmHxfda/yPcgJkGCMUSCwRmz+euo/V08xXLNgXTeqAB9Fhf3Pe2nO1RNKLCVgphQ=="], "oxlint": ["oxlint@1.86.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.86.0", "@oxlint/binding-android-arm64": "1.86.0", "@oxlint/binding-darwin-arm64": "1.86.0", "@oxlint/binding-darwin-x64": "1.86.0", "@oxlint/binding-freebsd-x64": "1.86.0", "@oxlint/binding-linux-arm-gnueabihf": "1.86.0", "@oxlint/binding-linux-arm-musleabihf": "1.86.0", "@oxlint/binding-linux-arm64-gnu": "1.86.0", "@oxlint/binding-linux-arm64-musl": "1.86.0", "@oxlint/binding-linux-ppc64-gnu": "1.86.0", "@oxlint/binding-linux-riscv64-gnu": "1.86.0", "@oxlint/binding-linux-riscv64-musl": "1.86.0", "@oxlint/binding-linux-s390x-gnu": "1.86.0", "@oxlint/binding-linux-x64-gnu": "1.86.0", "@oxlint/binding-linux-x64-musl": "1.86.0", "@oxlint/binding-openharmony-arm64": "1.86.0", "@oxlint/binding-win32-arm64-msvc": "1.86.0", "@oxlint/binding-win32-ia32-msvc": "1.86.0", "@oxlint/binding-win32-x64-msvc": "1.86.0" }, "peerDependencies": { "oxlint-tsgolint": ">=7.0.2003", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-og0lhgvZfgGF//gOOmZXvtr+GmBbAGEnbEhv/QUg7UW2Wi4wHMnJbnMD+zuHgPdJxdklfgpPupdlAaAySyxrZg=="], @@ -1326,14 +1210,10 @@ "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], - "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], - "papaparse": ["papaparse@5.7.0", "", {}, "sha512-qBGxg/7Q3Kl9Wfhrz2Z74UnvnHTXLNG6jmKJFeBvP2+y4lV7So+7SR62+Zd47JvdrCkX+nDcnr0ObPzek/+6RA=="], "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], - "patch-console": ["patch-console@2.0.0", "", {}, "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA=="], - "path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="], "path-expression-matcher": ["path-expression-matcher@1.6.2", "", {}, "sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ=="], @@ -1358,16 +1238,12 @@ "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], - "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], - "promise-limit": ["promise-limit@2.7.0", "", {}, "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="], "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], "pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="], - "pure-rand": ["pure-rand@8.4.2", "", {}, "sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng=="], - "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], "quickjs-emscripten": ["quickjs-emscripten@0.32.0", "", { "dependencies": { "@jitl/quickjs-wasmfile-debug-asyncify": "0.32.0", "@jitl/quickjs-wasmfile-debug-sync": "0.32.0", "@jitl/quickjs-wasmfile-release-asyncify": "0.32.0", "@jitl/quickjs-wasmfile-release-sync": "0.32.0", "quickjs-emscripten-core": "0.32.0" } }, "sha512-So0Sqw869y/S2oE3Nuc0uT3Dhqgvsj8FSrwBdsuTosVsG8ME5/OcudU1GxsrIFdFABgy17GHnTVO9TYV/bLQcA=="], @@ -1384,7 +1260,9 @@ "react-reconciler": ["react-reconciler@0.33.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA=="], - "readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "readdirp": ["readdirp@5.1.1", "", {}, "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA=="], "redis": ["redis@6.2.1", "", { "dependencies": { "@redis/bloom": "6.2.1", "@redis/client": "6.2.1", "@redis/json": "6.2.1", "@redis/search": "6.2.1", "@redis/time-series": "6.2.1" } }, "sha512-Z9VHtgYs48PiQC77X9O2Er8Hj4T+5BtFjT91/vi5Is1D04N72cA946ZslM1ImJw8ZctFBZWAVjM7S5wJNeHMpg=="], @@ -1396,8 +1274,6 @@ "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], - "restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="], - "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], @@ -1420,8 +1296,6 @@ "seroval-plugins": ["seroval-plugins@1.5.5", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-+BDhqYM6CEn3x09v44dpa9p6974FuUB2dxk+Ctn04k0cO1Zt6QODTXfmEZK0eBaTe/fJBvP4NMGuNJ+R8T+QMg=="], - "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="], - "sharp": ["sharp@0.35.5", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.5", "@img/sharp-darwin-x64": "0.35.5", "@img/sharp-freebsd-wasm32": "0.35.5", "@img/sharp-libvips-darwin-arm64": "1.3.4", "@img/sharp-libvips-darwin-x64": "1.3.4", "@img/sharp-libvips-linux-arm": "1.3.4", "@img/sharp-libvips-linux-arm64": "1.3.4", "@img/sharp-libvips-linux-ppc64": "1.3.4", "@img/sharp-libvips-linux-riscv64": "1.3.4", "@img/sharp-libvips-linux-s390x": "1.3.4", "@img/sharp-libvips-linux-x64": "1.3.4", "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", "@img/sharp-libvips-linuxmusl-x64": "1.3.4", "@img/sharp-linux-arm": "0.35.5", "@img/sharp-linux-arm64": "0.35.5", "@img/sharp-linux-ppc64": "0.35.5", "@img/sharp-linux-riscv64": "0.35.5", "@img/sharp-linux-s390x": "0.35.5", "@img/sharp-linux-x64": "0.35.5", "@img/sharp-linuxmusl-arm64": "0.35.5", "@img/sharp-linuxmusl-x64": "0.35.5", "@img/sharp-webcontainers-wasm32": "0.35.5", "@img/sharp-win32-arm64": "0.35.5", "@img/sharp-win32-ia32": "0.35.5", "@img/sharp-win32-x64": "0.35.5" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], @@ -1432,16 +1306,12 @@ "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], - "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="], "simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="], - "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], - - "slice-ansi": ["slice-ansi@8.0.0", "", { "dependencies": { "ansi-styles": "^6.2.3", "is-fullwidth-code-point": "^5.1.0" } }, "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg=="], - "smol-toml": ["smol-toml@1.9.0", "", {}, "sha512-hpd+HLON7HdZXqYchMM/+LaTTbdK0AU3NngIJ4KVyWbY9bfQqdL9cD+4yf6dUoU2Ap4VsU0JkQi6FxAI1B2mXQ=="], "solid-js": ["solid-js@1.9.12", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.5.0", "seroval-plugins": "~1.5.0" } }, "sha512-QzKaSJq2/iDrWR1As6MHZQ8fQkdOBf8GReYb7L5iKwMGceg7HxDcaOHk0at66tNgn9U2U7dXo8ZZpLIAmGMzgw=="], @@ -1452,8 +1322,6 @@ "sql.js": ["sql.js@1.14.2", "", {}, "sha512-3ZGPovObMFrdw79zrUHbfdE/DLIsy8jdNdssmMSQuRAymedU6q84asPt0kgiqrdMYlPegDItiIMfmIXzZnYFcw=="], - "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="], - "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], "std-env": ["std-env@4.2.0", "", {}, "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw=="], @@ -1474,14 +1342,10 @@ "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], - "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="], - "tar-fs": ["tar-fs@2.1.5", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw=="], "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], - "terminal-size": ["terminal-size@4.0.1", "", {}, "sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ=="], - "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], "tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], @@ -1502,15 +1366,13 @@ "turndown": ["turndown@7.2.4", "", { "dependencies": { "@mixmark-io/domino": "^2.2.0" } }, "sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ=="], - "type-fest": ["type-fest@5.10.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA=="], - "typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="], "typescript-compiler": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], "uint8array-extras": ["uint8array-extras@1.6.0", "", {}, "sha512-8iAasVS4wUx0gPLjH8Xtz2PeDzTSiy8QiLGu2DT3X5GU+egFEQhpnbtkehbAwjvDcxIERmCYcysiODFmE3Ud0Q=="], - "undici": ["undici@8.10.1", "", {}, "sha512-YQ3WlbqjYMmNpdvDH64jAgLjxuAR9+649calDWhbshYaeQGO2bR4nI94ORJmwI3J9YhoKQnpyGOK+0zlWS5N5Q=="], + "undici": ["undici@8.11.2", "", {}, "sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ=="], "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], @@ -1534,9 +1396,7 @@ "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], - "widest-line": ["widest-line@6.0.0", "", { "dependencies": { "string-width": "^8.1.0" } }, "sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA=="], - - "workerd": ["workerd@1.20260704.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260704.1", "@cloudflare/workerd-darwin-arm64": "1.20260704.1", "@cloudflare/workerd-linux-64": "1.20260704.1", "@cloudflare/workerd-linux-arm64": "1.20260704.1", "@cloudflare/workerd-windows-64": "1.20260704.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-GDZ0jzIYDYfN7rCt/oFJv4BG3QJ+4IS2kfRvxEMY9VKIfPhzo63PH69Ir7ug8LfORCgCtmfkiQVXrqbot7pZTQ=="], + "workerd": ["workerd@1.20260918.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260918.1", "@cloudflare/workerd-darwin-arm64": "1.20260918.1", "@cloudflare/workerd-linux-64": "1.20260918.1", "@cloudflare/workerd-linux-arm64": "1.20260918.1", "@cloudflare/workerd-windows-64": "1.20260918.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-NsjfQlBNQ0iEniv/STOy4zbp8s5k60PzL1Ter02Eg44arbDhHtf6UOs03E31XDRmmBFxSIkAZuCyld3RKH1wqA=="], "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], @@ -1558,12 +1418,12 @@ "yauzl": ["yauzl@3.4.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw=="], - "yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="], - "zeptomatch": ["zeptomatch@2.1.0", "", { "dependencies": { "grammex": "^3.1.11", "graphmatch": "^1.1.0" } }, "sha512-KiGErG2J0G82LSpniV0CtIzjlJ10E04j02VOudJsPyPwNZgGnRKQy7I1R7GMyg/QswnE4l7ohSGrQbQbjXPPDA=="], "@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + "@effect/platform-node-shared/ws": ["ws@8.22.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg=="], + "@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], "@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], @@ -1574,22 +1434,12 @@ "@puppeteer/browsers/modern-tar": ["modern-tar@0.8.5", "", {}, "sha512-snEhs+6G5Tjd4I7tLCDOaoln2RgE0bD19RzEKgvgK2hZ5VKy3MpLhLTZ2fWpXSTg4K2cyPwp+VHATFJhxfnOeA=="], - "alchemy/capnweb": ["capnweb@0.6.1", "", {}, "sha512-fmhV26QPd1ewf5R74h55oVZnGwIcSaRMzbfLQUy8+zOBjuTmT3KXoT8wxHvnp1m9Ht9BoUUS5ZwNLoVLfQTyBg=="], - - "alchemy/undici": ["undici@7.30.0", "", {}, "sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ=="], + "alchemy/capnweb": ["capnweb@0.12.0", "", {}, "sha512-jgZ/LMtMVTi+RVlooIslH78Gg23XbDTdvcLghWx3oz17D6u5GuJARt+uhZk/wcTo+f81eeabfnow4d3zLBj+JQ=="], "babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="], - "bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - - "cli-truncate/string-width": ["string-width@8.3.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ=="], - - "foreground-child/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - "glob/minimatch": ["minimatch@8.0.7", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg=="], - "ink/string-width": ["string-width@8.3.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ=="], - "just-bash/diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="], "just-bash/undici": ["undici@7.30.0", "", {}, "sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ=="], @@ -1608,18 +1458,16 @@ "path-scurry/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + "proper-lockfile/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + "rc/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], "react-devtools-core/ws": ["ws@7.5.12", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-1xGnbYN3zbog9CwuNDQULNRrTCLIn46/WmpR1f0w6PsCYQHkylZr5vkd6kfMZYV6pRnQkcPNRyiA8LsrNKyhpg=="], "sharp/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], - "tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - "vite/rolldown": ["rolldown@1.1.5", "", { "dependencies": { "@oxc-project/types": "=0.139.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.5", "@rolldown/binding-darwin-arm64": "1.1.5", "@rolldown/binding-darwin-x64": "1.1.5", "@rolldown/binding-freebsd-x64": "1.1.5", "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", "@rolldown/binding-linux-arm64-gnu": "1.1.5", "@rolldown/binding-linux-arm64-musl": "1.1.5", "@rolldown/binding-linux-ppc64-gnu": "1.1.5", "@rolldown/binding-linux-s390x-gnu": "1.1.5", "@rolldown/binding-linux-x64-gnu": "1.1.5", "@rolldown/binding-linux-x64-musl": "1.1.5", "@rolldown/binding-openharmony-arm64": "1.1.5", "@rolldown/binding-wasm32-wasi": "1.1.5", "@rolldown/binding-win32-arm64-msvc": "1.1.5", "@rolldown/binding-win32-x64-msvc": "1.1.5" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA=="], - "widest-line/string-width": ["string-width@8.3.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ=="], - "yargs/string-width": ["string-width@8.3.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ=="], "@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], diff --git a/examples/alchemy-cloudflare/src/Api.ts b/examples/alchemy-cloudflare/src/Api.ts index 9f8862c..60d2d63 100644 --- a/examples/alchemy-cloudflare/src/Api.ts +++ b/examples/alchemy-cloudflare/src/Api.ts @@ -10,7 +10,7 @@ */ import { AgentFinishedLogEntry, LogEntry, SessionId } from '@humanlayer/fold-core' import { Effect, Schema } from 'effect' -import { HttpRouter, HttpServerRequest, HttpServerResponse } from 'effect/unstable/http' +import { HttpRouter, HttpServerRequest, HttpServerResponse } from 'effect/http' import { ChatSessions, Message } from './ChatSessions' diff --git a/examples/alchemy-cloudflare/src/ChatSession.ts b/examples/alchemy-cloudflare/src/ChatSession.ts index 1eee0b8..4a89a54 100644 --- a/examples/alchemy-cloudflare/src/ChatSession.ts +++ b/examples/alchemy-cloudflare/src/ChatSession.ts @@ -47,7 +47,7 @@ import { Stream, SynchronizedRef, } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { bashTool } from './BashTool' import type { Message, WhenRunning } from './ChatSessions' @@ -148,7 +148,7 @@ export default class ChatSession extends Cloudflare.DurableObject() Effect.gen(function* () { const state = yield* Cloudflare.DurableObjectState // Read from the deploy environment and bound to the Worker as a secret. Missing, the deploy fails. - const apiKey = yield* Config.redacted('OPENAI_API_KEY').pipe(Effect.orDie) + const apiKey = yield* Config.Redacted('OPENAI_API_KEY').pipe(Effect.orDie) const eventLogs = yield* DurableObjectEventLog const keepalive = yield* Keepalive const expiry = yield* SessionExpiry diff --git a/examples/alchemy-cloudflare/src/Worker.ts b/examples/alchemy-cloudflare/src/Worker.ts index e5d95f8..a9579f7 100644 --- a/examples/alchemy-cloudflare/src/Worker.ts +++ b/examples/alchemy-cloudflare/src/Worker.ts @@ -4,7 +4,7 @@ */ import * as Cloudflare from 'alchemy/Cloudflare' import { Effect } from 'effect' -import { HttpRouter } from 'effect/unstable/http' +import { HttpRouter } from 'effect/http' import { ChatRoutes } from './Api' import { ChatSessions } from './ChatSessions' diff --git a/examples/alchemy-cloudflare/src/Workspace.ts b/examples/alchemy-cloudflare/src/Workspace.ts index 3d73e23..e0cf884 100644 --- a/examples/alchemy-cloudflare/src/Workspace.ts +++ b/examples/alchemy-cloudflare/src/Workspace.ts @@ -24,7 +24,7 @@ const REPO_NAME = /^(?!\.{1,2}$)[\w.-]+$/ * `name` under `/workspace` (the URL's last path segment when absent). */ export const Repo = Schema.Struct({ - url: Schema.String.check(Schema.isStartsWith('https://')), + url: Schema.String.check(Schema.isStartingWith('https://')), name: Schema.optionalKey(Schema.String), ref: Schema.optionalKey(Schema.String), }) diff --git a/examples/alchemy-cloudflare/src/WorkspaceFileSystem.ts b/examples/alchemy-cloudflare/src/WorkspaceFileSystem.ts index b0fc425..75e5334 100644 --- a/examples/alchemy-cloudflare/src/WorkspaceFileSystem.ts +++ b/examples/alchemy-cloudflare/src/WorkspaceFileSystem.ts @@ -7,7 +7,7 @@ * `realPath` returns the path unchanged: fold only uses it to key its per-file write lock. */ import type { RpcCallError } from 'alchemy' -import { Effect, FileSystem, Option, PlatformError } from 'effect' +import { ByteSize, Effect, FileSystem, Option, PlatformError } from 'effect' import type { FileInfo, ComputerResult } from './computer/Contract' @@ -85,7 +85,7 @@ const toInfo = (info: FileInfo): FileSystem.File.Info => ({ uid: Option.none(), gid: Option.none(), rdev: Option.none(), - size: FileSystem.Size(info.size), + size: ByteSize.bytes(info.size), blksize: Option.none(), blocks: Option.none(), }) diff --git a/examples/alchemy-cloudflare/test/Api.test.ts b/examples/alchemy-cloudflare/test/Api.test.ts index 785de59..dd132b5 100644 --- a/examples/alchemy-cloudflare/test/Api.test.ts +++ b/examples/alchemy-cloudflare/test/Api.test.ts @@ -15,7 +15,7 @@ import { type LogEntryInput, } from '@humanlayer/fold-core' import { Context, Effect, Layer, Predicate, Ref, Schema, Scope, Stream } from 'effect' -import { HttpRouter } from 'effect/unstable/http' +import { HttpRouter } from 'effect/http' import { expect } from 'vitest' import { ChatRoutes } from '../src/Api' diff --git a/package.json b/package.json index 455fd87..c31d2ee 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ ], "catalog": { "@kitlangton/terminal-control": "0.3.1", - "alchemy": "2.0.0-beta.76", + "alchemy": "2.0.0-beta.80", "@cloudflare/computer": "https://github.com/K-Mistele/computer/releases/download/fold-91611593a1d7/cloudflare-computer-0.3.1.tgz", "@platformatic/vfs": "0.4.0", "@cloudflare/workers-types": "5.20260929.1", @@ -38,10 +38,10 @@ "@opentui/keymap": "0.4.3", "@opentui/solid": "0.4.3", "solid-js": "1.9.12", - "effect": "4.0.0-rc.112", - "@effect/platform-node": "4.0.0-rc.112", - "@effect/platform-bun": "4.0.0-rc.112", - "@effect/vitest": "4.0.0-rc.112", + "effect": "4.0.0", + "@effect/platform-node": "4.0.0", + "@effect/platform-bun": "4.0.0", + "@effect/vitest": "4.0.0", "@silvia-odwyer/photon-node": "0.3.4", "turndown": "7.2.4", "@types/turndown": "5.0.6", @@ -54,7 +54,7 @@ } }, "devDependencies": { - "@effect/tsgo": "0.47.0", + "@effect/tsgo": "0.48.0", "@oxlint/plugins": "1.86.0", "@types/bun": "catalog:", "@types/node": "catalog:", diff --git a/packages/effect-ai-anthropic/README.md b/packages/effect-ai-anthropic/README.md index 7617c5b..6cc09d9 100644 --- a/packages/effect-ai-anthropic/README.md +++ b/packages/effect-ai-anthropic/README.md @@ -5,7 +5,7 @@ An [Anthropic](https://www.anthropic.com) provider for the Effect AI modules. In ## Installation ```sh -npm install effect@4.0.0-rc.112 @humanlayer/effect-ai-anthropic +npm install effect@4.0.0 @humanlayer/effect-ai-anthropic ``` ## Documentation diff --git a/packages/effect-ai-anthropic/UPSTREAM.md b/packages/effect-ai-anthropic/UPSTREAM.md index 6c111b2..edf45be 100644 --- a/packages/effect-ai-anthropic/UPSTREAM.md +++ b/packages/effect-ai-anthropic/UPSTREAM.md @@ -5,11 +5,11 @@ This directory is a vendored source snapshot of the published Effect Anthropic p | Field | Value | | ---------------- | ------------------------------------------------------------------------------------------------- | -| Upstream package | `@effect/ai-anthropic@4.0.0-rc.112` | -| Source artifact | `https://registry.npmjs.org/@effect/ai-anthropic/-/ai-anthropic-4.0.0-rc.112.tgz` | -| npm integrity | `sha512-2GQKD3IzfCJuS3DgeuBwUjEYk5iyOqgK5etQkYZ3Ho8IuL8BtGR9d8G5AIiRV0xkNy5DD4vGnDGSHxKWsW2TRg==` | -| Tarball SHA-256 | `4a1bc081405cd7b11e7b4a2f4d1f5eb113b72270ed58043fbd7d104b29e473fc` | -| Imported at | `2026-09-03` | +| Upstream package | `@effect/ai-anthropic@4.0.0` | +| Source artifact | `https://registry.npmjs.org/@effect/ai-anthropic/-/ai-anthropic-4.0.0.tgz` | +| npm integrity | `sha512-/xZYmvRE9yDLKiz1pOIx0CVaB+o0zdJd6sTG9KQbFSkM+Ule0U/6yeN+Q6KD9I7Z73t3WxhK9Xmg1eqU6+IVmQ==` | +| Tarball SHA-256 | `68969de51307457a74aea94273f05f7eab7b570f940ade95bf57b8847fe8e355` | +| Imported at | `2026-10-03` | | Imported inputs | `src/**`, `README.md`, and `LICENSE` | | License | MIT; copied to [`LICENSE`](./LICENSE) | diff --git a/packages/effect-ai-anthropic/src/AnthropicClient.ts b/packages/effect-ai-anthropic/src/AnthropicClient.ts index d9b672e..0803eed 100644 --- a/packages/effect-ai-anthropic/src/AnthropicClient.ts +++ b/packages/effect-ai-anthropic/src/AnthropicClient.ts @@ -4,26 +4,27 @@ * authentication headers, API version headers, response decoding, and error * mapping, then exposes helpers for regular and streaming message requests. * + * @stability unstable * @since 4.0.0 */ +import type * as AiError from "effect/ai/AiError" 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 * as Sse from "effect/encoding/Sse" import { identity } from "effect/Function" +import * as Headers from "effect/http/Headers" +import * as HttpBody from "effect/http/HttpBody" +import * as HttpClient from "effect/http/HttpClient" +import * as HttpClientError from "effect/http/HttpClientError" +import * as HttpClientRequest from "effect/http/HttpClientRequest" +import type * as HttpClientResponse from "effect/http/HttpClientResponse" 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" @@ -36,6 +37,7 @@ import * as Errors from "./internal/errors.ts" * Represents the Anthropic client service with methods for the Messages API, including regular and streaming message * creation. * + * @stability unstable * @category services * @since 4.0.0 */ @@ -98,6 +100,7 @@ export interface Service { * - `content_block_stop`: End of a content block * - `error`: Error events with type and message * + * @stability unstable * @category models * @since 4.0.0 */ @@ -126,6 +129,7 @@ export type MessageStreamEvent = * @see {@link layer} for providing a client from explicit options * @see {@link layerConfig} for providing a client from `Config` * + * @stability unstable * @category services * @since 4.0.0 */ @@ -155,6 +159,7 @@ export class AnthropicClient extends Context.Service() * @see {@link layer} for providing an Anthropic client from explicit options * @see {@link layerConfig} for loading Anthropic client settings from `Config` * + * @stability unstable * @category options * @since 4.0.0 */ @@ -216,6 +221,7 @@ const withRedactedHeaders = Effect.updateService( * @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 * + * @stability unstable * @category constructors * @since 4.0.0 */ @@ -243,7 +249,41 @@ export const make = Effect.fnUntraced( : identity ) - const client = Generated.make(httpClient, { + // Let status mapping handle gateway errors without an Anthropic envelope. + const generatedHttpClient = HttpClient.transformResponse( + httpClient, + Effect.flatMap((response) => { + if ( + response.status < 400 || response.status >= 500 || + !response.request.url.endsWith("/v1/messages?beta=true") + ) { + return Effect.succeed(response) + } + return Effect.flatMap(Effect.option(response.json), (body) => { + if ( + body._tag === "Some" && + Schema.decodeUnknownOption(Generated.BetaMessagesPost4XX)(body.value)._tag === "Some" + ) { + return Effect.succeed(response) + } + return Effect.flatMap( + Effect.orElseSucceed(response.text, () => "Unexpected status code"), + (description) => + Effect.fail( + new HttpClientError.HttpClientError({ + reason: new HttpClientError.StatusCodeError({ + request: response.request, + response, + description + }) + }) + ) + ) + }) + }) + ) + + const client = Generated.make(generatedHttpClient, { transformClient: Effect.fnUntraced(function*(client) { const config = yield* AnthropicConfig.getOrUndefined if (Predicate.isNotUndefined(config?.transformClient)) { @@ -366,6 +406,7 @@ export const make = Effect.fnUntraced( * @see {@link make} for constructing the client service effectfully * @see {@link layerConfig} for loading client settings from `Config` * + * @stability unstable * @category layers * @since 4.0.0 */ @@ -385,6 +426,7 @@ export const layer = (options: Options): Layer.Layer | undefined -}): Effect.fn.Return { +}): Effect.fn.Return { const client = yield* AnthropicClient const makeConfig: Effect.Effect = Effect.contextWith((services) => @@ -713,8 +735,13 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig if (betas.size > 0) { params["anthropic-beta"] = Array.from(betas).join(",") } - const { disableParallelToolCalls: _, output_config, structuredOutputs: _structuredOutputs, ...requestConfig } = - config + const { + disableParallelToolCalls: _, + output_config, + strictJsonSchema: _strictJsonSchema, + structuredOutputs: _structuredOutputs, + ...requestConfig + } = config const payload: Mutable = { ...requestConfig, max_tokens: requestConfig.max_tokens ?? capabilities.maxOutputTokens, @@ -778,6 +805,7 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig * @see {@link make} for constructing the language model service effectfully * @see {@link model} for creating a model service directly * + * @stability unstable * @category layers * @since 4.0.0 */ @@ -804,6 +832,7 @@ export const layer = (options: { * * @see {@link Config} for available Anthropic request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -825,6 +854,7 @@ export const withConfigOverride: { * * @see {@link Config} for available Anthropic request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -846,6 +876,7 @@ export const withConfigOverride: { * * @see {@link Config} for available Anthropic request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -868,6 +899,7 @@ export const withConfigOverride: { * * @see {@link Config} for available Anthropic request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -889,6 +921,7 @@ export const withConfigOverride: { * * @see {@link Config} for available Anthropic request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -970,7 +1003,13 @@ const prepareMessages = Effect.fnUntraced( const source = isUrlData(part.data) ? { type: "url", url: getUrlString(part.data) } as const - : { type: "base64", media_type: mediaType, data: Encoding.encodeBase64(part.data) } as const + : { + type: "base64", + media_type: mediaType, + data: typeof part.data === "string" + ? part.data.replace(/^data:[^;]+;base64,/, "") + : Base64.encode(part.data) + } as const content.push({ type: "image", source, cache_control: cacheControl }) } else if (part.mediaType === "application/pdf" || part.mediaType === "text/plain") { @@ -988,7 +1027,7 @@ const prepareMessages = Effect.fnUntraced( ? { type: "base64", media_type: "application/pdf", - data: typeof part.data === "string" ? part.data : Encoding.encodeBase64(part.data) + data: typeof part.data === "string" ? part.data : Base64.encode(part.data) } as const : { type: "text", @@ -1075,7 +1114,7 @@ const prepareMessages = Effect.fnUntraced( media_type: mediaType, data: Predicate.isString(outputPart.data) ? outputPart.data - : Encoding.encodeBase64(outputPart.data) + : Base64.encode(outputPart.data) } toolResultContent.push({ type: "image", source }) } @@ -1367,6 +1406,7 @@ const prepareMessages = Effect.fnUntraced( * * @see {@link AnthropicProviderDefinedTool} for the request shape used by Anthropic built-in provider tools * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -1380,6 +1420,7 @@ export type AnthropicUserDefinedTool = typeof Generated.BetaTool.Encoded * These include Anthropic's built-in tools like computer use, code execution, * web search, and text editing. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -1411,10 +1452,6 @@ const prepareTools = Effect.fnUntraced( readonly tools: ReadonlyArray | undefined readonly toolChoice: typeof Generated.BetaToolChoice.Encoded | undefined }, AiError.AiError> { - if (options.tools.length === 0 || options.toolChoice === "none") { - return { tools: undefined, toolChoice: undefined } - } - // Return a JSON response tool when using non-native structured outputs if (options.responseFormat.type === "json" && !capabilities.supportsStructuredOutput) { const input_schema = yield* tryJsonSchema(options.responseFormat.schema, "prepareTools") @@ -1434,6 +1471,10 @@ const prepareTools = Effect.fnUntraced( } } + if (options.tools.length === 0 || options.toolChoice === "none") { + return { tools: undefined, toolChoice: undefined } + } + const userTools: Array = [] const providerTools: Array = [] @@ -1688,6 +1729,9 @@ const makeResponse = Effect.fnUntraced( const mcpToolCalls: Map = new Map() const serverToolCalls: Map = new Map() const citableDocuments = extractCitableDocuments(options.prompt) + const responseFormat = options.responseFormat + const hasStructuredOutputTool = responseFormat.type === "json" && + rawResponse.content.some((part) => part.type === "tool_use" && part.name === responseFormat.objectName) parts.push({ type: "response-metadata", @@ -1700,10 +1744,12 @@ const makeResponse = Effect.fnUntraced( for (const part of rawResponse.content) { switch (part.type) { case "text": { - // Text parts are added for both text and json response formats. - // For native structured output (json_schema), the JSON comes directly - // in a text content block. For tool-based structured output, text may - // also be present alongside the tool_use. + // The response tool supplies the JSON payload. Accompanying prose + // must not be concatenated with it during structured output decoding. + if (hasStructuredOutputTool) { + break + } + parts.push({ type: "text", text: part.text @@ -1750,7 +1796,7 @@ const makeResponse = Effect.fnUntraced( case "tool_use": { // When the `"json"` response format is requested, the JSON we need // is returned by a tool call injected into the request - if (options.responseFormat.type === "json") { + if (responseFormat.type === "json" && part.name === responseFormat.objectName) { parts.push({ type: "text", text: JSON.stringify(part.input) @@ -3227,19 +3273,13 @@ const transformToolCallParams = Effect.fnUntraced(function* - ).pipe(Effect.mapError((error) => - AiError.make({ - module: "AnthropicLanguageModel", - method: "makeResponse", - reason: new AiError.ToolParameterValidationError({ - toolName, - toolParams, - description: formatIssue(error.issue) - }) - }) - )) + Schema.decodeEffect(codec)(toolParams) as Effect.Effect + ).pipe( + Effect.flatMap((decoded) => + Schema.encodeUnknownEffect(tool.parametersSchema)(decoded) as Effect.Effect + ), + Effect.orElseSucceed(() => toolParams) + ) }) diff --git a/packages/effect-ai-anthropic/src/AnthropicTelemetry.ts b/packages/effect-ai-anthropic/src/AnthropicTelemetry.ts index b8252bc..ca3e3ff 100644 --- a/packages/effect-ai-anthropic/src/AnthropicTelemetry.ts +++ b/packages/effect-ai-anthropic/src/AnthropicTelemetry.ts @@ -6,11 +6,11 @@ * * @since 4.0.0 */ +import * as Telemetry from "effect/ai/Telemetry" 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 diff --git a/packages/effect-ai-anthropic/src/AnthropicTool.ts b/packages/effect-ai-anthropic/src/AnthropicTool.ts index e0f9751..2588928 100644 --- a/packages/effect-ai-anthropic/src/AnthropicTool.ts +++ b/packages/effect-ai-anthropic/src/AnthropicTool.ts @@ -5,10 +5,11 @@ * Tool Search, which can be attached to Anthropic-backed Effect AI language * model requests. * + * @stability unstable * @since 4.0.0 */ +import * as Tool from "effect/ai/Tool" import * as Schema from "effect/Schema" -import * as Tool from "effect/unstable/ai/Tool" import * as Generated from "./Generated.ts" /** @@ -25,6 +26,7 @@ import * as Generated from "./Generated.ts" * including Bash, Code Execution, Computer Use, Memory, Text Editor, Tool * Search, Web Fetch, and Web Search tool versions. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -65,6 +67,7 @@ export type AnthropicTool = * * @see {@link Bash_20250124} for the newer 2025-01-24 version of the bash tool * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -95,6 +98,7 @@ export const Bash_20241022 = Tool.providerDefined({ * * @see {@link Bash_20241022} for the older 2024-10-22 version of the bash tool * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -128,6 +132,7 @@ export const Bash_20250124 = Tool.providerDefined({ * * @see {@link CodeExecution_20250522} for the parent tool definition * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -141,6 +146,7 @@ export const CodeExecutionProgrammaticToolCall = Schema.Struct({ /** * Input payload for a programmatic code execution tool call, including the source code to execute. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -161,6 +167,7 @@ export type CodeExecutionProgrammaticToolCall = typeof CodeExecutionProgrammatic * * @see {@link CodeExecution_20250522} for the provider-defined tool that consumes this input variant * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -191,6 +198,7 @@ export const CodeExecutionBashCommand = Schema.Struct({ * @see {@link CodeExecutionTextEditorStrReplace} for replacing text through text editor code execution * @see {@link CodeExecution_20250522} for the provider-defined tool that consumes this payload * + * @stability unstable * @category models * @since 4.0.0 */ @@ -212,6 +220,7 @@ export type CodeExecutionBashCommand = typeof CodeExecutionBashCommand.Type * @see {@link CodeExecutionTextEditorCreate} for the command that creates a file * @see {@link CodeExecutionTextEditorStrReplace} for the command that replaces text in a file * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -245,6 +254,7 @@ export const CodeExecutionTextEditorView = Schema.Struct({ * @see {@link CodeExecution_20250522} for the provider-defined code execution tool that includes this payload * @see {@link TextEditorViewCommand} for the standalone text editor view payload * + * @stability unstable * @category models * @since 4.0.0 */ @@ -268,6 +278,7 @@ export type CodeExecutionTextEditorView = typeof CodeExecutionTextEditorView.Typ * @see {@link CodeExecutionTextEditorView} for the matching view request * @see {@link CodeExecutionTextEditorStrReplace} for the matching replace request * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -286,6 +297,7 @@ export const CodeExecutionTextEditorCreate = Schema.Struct({ /** * Input payload for creating a file through the text editor code execution tool, optionally including initial file text. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -307,6 +319,7 @@ export type CodeExecutionTextEditorCreate = typeof CodeExecutionTextEditorCreate * @see {@link CodeExecutionTextEditorView} for reading file contents before choosing the replacement text * @see {@link CodeExecution_20250522} for the provider-defined tool that consumes this payload * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -329,6 +342,7 @@ export const CodeExecutionTextEditorStrReplace = Schema.Struct({ /** * Input payload for replacing text in a file through the text editor code execution tool. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -356,6 +370,7 @@ const CodeExecution_20250522_Parameters = Schema.Union([ * * @see {@link CodeExecution_20250825} for the provider-defined tool that consumes this schema * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -380,6 +395,7 @@ export const CodeExecution_20250825_Parameters = Schema.Struct({ * * @see {@link CodeExecution_20250825} for the provider-defined tool that consumes this payload * + * @stability unstable * @category models * @since 4.0.0 */ @@ -405,6 +421,7 @@ export type CodeExecution_20250825_Parameters = typeof CodeExecution_20250825_Pa * * @see {@link CodeExecutionProgrammaticToolCall} for the programmatic tool call schema * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -433,6 +450,7 @@ export const CodeExecution_20250522 = Tool.providerDefined({ * @see {@link CodeExecution_20250522} for the older 2025-05-22 code execution tool * @see {@link CodeExecution_20250825_Parameters} for the input schema consumed by this tool * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -480,6 +498,7 @@ export const CodeExecution_20250825 = Tool.providerDefined({ * * This schema validates tuple shape only and does not check display bounds. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -487,6 +506,7 @@ export const Coordinate = Schema.Tuple([Schema.Int, Schema.Int]) /** * An `[x, y]` screen coordinate in pixels. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -509,6 +529,7 @@ export type Coordinate = typeof Coordinate.Type * This schema validates four numbers only and does not check coordinate ordering * or display bounds. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -516,6 +537,7 @@ export const Region = Schema.Tuple([Schema.Int, Schema.Int, Schema.Int, Schema.I /** * An `[x1, y1, x2, y2]` screen region in pixels, from top-left to bottom-right. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -526,6 +548,7 @@ export type Region = typeof Region.Type * * @see {@link ComputerUseScrollAction} for the action payload that consumes this schema * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -533,6 +556,7 @@ export const ScrollDirection = Schema.Literals(["up", "down", "left", "right"]) /** * Direction used by computer-use scroll actions: `"up"`, `"down"`, `"left"`, or `"right"`. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -545,6 +569,7 @@ export type ScrollDirection = typeof ScrollDirection.Type * * Allowed values are `"alt"`, `"ctrl"`, `"meta"`, and `"shift"`. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -556,6 +581,7 @@ export const ModifierKey = Schema.Literals(["alt", "ctrl", "meta", "shift"]) * * Allowed values are `"alt"`, `"ctrl"`, `"meta"`, and `"shift"`. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -605,6 +631,7 @@ const ComputerUse_20251124_Args = Schema.Struct({ * @see {@link TypeAction} for entering ordinary text strings * @see {@link ComputerUseHoldKeyAction} for holding a key for a duration * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -634,6 +661,7 @@ export const ComputerUseKeyAction = Schema.Struct({ * `text` is typed as `string`; the paired schema does not validate * provider-specific key names or key combinations. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -662,6 +690,7 @@ export type ComputerUseKeyAction = typeof ComputerUseKeyAction.Type * @see {@link ComputerUseDoubleClickAction} for performing a double click * @see {@link ComputerUseMouseMoveAction} for moving the mouse without clicking * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -676,6 +705,7 @@ export const ComputerUseLeftClickAction = Schema.Struct({ /** * Computer-use action payload for performing a left click, optionally at a specific coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -701,6 +731,7 @@ export type ComputerUseLeftClickAction = typeof ComputerUseLeftClickAction.Type * does not validate that the point falls within the configured display * dimensions. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -714,6 +745,7 @@ export const ComputerUseMouseMoveAction = Schema.Struct({ /** * Computer-use action payload for moving the mouse cursor to a specific coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -734,6 +766,7 @@ export type ComputerUseMouseMoveAction = typeof ComputerUseMouseMoveAction.Type * * @see {@link ComputerUseZoomAction} for requesting a zoomed-in screenshot of a specific screen region with the 2025-11-24 computer-use tool * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -743,6 +776,7 @@ export const ComputerUseScreenshotAction = Schema.Struct({ /** * Computer-use action payload for capturing the current display. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -763,6 +797,7 @@ export type ComputerUseScreenshotAction = typeof ComputerUseScreenshotAction.Typ * * @see {@link ComputerUseKeyAction} for key presses and keyboard shortcuts * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -781,6 +816,7 @@ export const TypeAction = Schema.Struct({ * The payload uses `action: "type"` and a `text` string containing the text to * enter. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -820,6 +856,7 @@ const ComputerUse_20241022_Actions = Schema.Union([ * * @see {@link ComputerUseLeftClickAction} for performing a single left click * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -834,6 +871,7 @@ export const ComputerUseDoubleClickAction = Schema.Struct({ /** * Computer-use action payload for performing a double click, optionally at a specific coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -861,6 +899,7 @@ export type ComputerUseDoubleClickAction = typeof ComputerUseDoubleClickAction.T * @see {@link ComputerUseKeyAction} for pressing a key or key combination without holding it * @see {@link ComputerUseWaitAction} for pausing between actions without holding a key * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -889,6 +928,7 @@ export const ComputerUseHoldKeyAction = Schema.Struct({ * * @see {@link ComputerUseKeyAction} for a single key press or key combination without a hold duration * + * @stability unstable * @category models * @since 4.0.0 */ @@ -916,6 +956,7 @@ export type ComputerUseHoldKeyAction = typeof ComputerUseHoldKeyAction.Type * @see {@link ComputerUseLeftMouseDownAction} for starting a manual drag sequence * @see {@link ComputerUseLeftMouseUpAction} for ending a manual drag sequence * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -933,6 +974,7 @@ export const ComputerUseLeftClickDragAction = Schema.Struct({ /** * Computer-use action payload for dragging from a start coordinate to an end coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -946,6 +988,7 @@ export type ComputerUseLeftClickDragAction = typeof ComputerUseLeftClickDragActi * Use when constructing a manual click or drag sequence that should press and * hold the left mouse button before a later release. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -960,6 +1003,7 @@ export const ComputerUseLeftMouseDownAction = Schema.Struct({ /** * Computer-use action payload for pressing and holding the left mouse button, optionally at a specific coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -973,6 +1017,7 @@ export type ComputerUseLeftMouseDownAction = typeof ComputerUseLeftMouseDownActi * Use when constructing a manual click or drag sequence that should release the * left mouse button after it was previously held down. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -987,6 +1032,7 @@ export const ComputerUseLeftMouseUpAction = Schema.Struct({ /** * Computer-use action payload for releasing the left mouse button, optionally at a specific coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1014,6 +1060,7 @@ export type ComputerUseLeftMouseUpAction = typeof ComputerUseLeftMouseUpAction.T * @see {@link ComputerUseLeftClickAction} for primary-button clicks * @see {@link ComputerUseRightClickAction} for secondary-button clicks * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1028,6 +1075,7 @@ export const ComputerUseMiddleClickAction = Schema.Struct({ /** * Computer-use action payload for performing a middle click, optionally at a specific coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1051,6 +1099,7 @@ export type ComputerUseMiddleClickAction = typeof ComputerUseMiddleClickAction.T * @see {@link ComputerUseLeftClickAction} for the corresponding left-click action * @see {@link ComputerUseMiddleClickAction} for the corresponding middle-click action * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1065,6 +1114,7 @@ export const ComputerUseRightClickAction = Schema.Struct({ /** * Computer-use action payload for performing a right click, optionally at a specific coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1090,6 +1140,7 @@ export type ComputerUseRightClickAction = typeof ComputerUseRightClickAction.Typ * @see {@link ComputerUse_20250124} for the tool version that accepts this action * @see {@link ScrollDirection} for the accepted direction literals * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1112,6 +1163,7 @@ export const ComputerUseScrollAction = Schema.Struct({ /** * Computer-use action payload for scrolling by a specified amount in a specified direction, optionally from a coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1139,6 +1191,7 @@ export type ComputerUseScrollAction = typeof ComputerUseScrollAction.Type * @see {@link ComputerUseDoubleClickAction} for the two-click variant * @see {@link ComputerUseLeftClickAction} for a single left click * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1153,6 +1206,7 @@ export const ComputerUseTripleClickAction = Schema.Struct({ /** * Computer-use action payload for performing a triple click, optionally at a specific coordinate. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1179,6 +1233,7 @@ export type ComputerUseTripleClickAction = typeof ComputerUseTripleClickAction.T * @see {@link ComputerUseHoldKeyAction} for another duration-based computer-use action * @see {@link ComputerUse_20250124} for the tool version that accepts this action * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1192,6 +1247,7 @@ export const ComputerUseWaitAction = Schema.Struct({ /** * Computer-use action payload for pausing for a specified duration. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1235,6 +1291,7 @@ const ComputerUse_20250124_Actions = Schema.Union([ * @see {@link ComputerUse_20251124} for the tool version that accepts this action * @see {@link ComputerUseScreenshotAction} for capturing the full screen instead * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1255,6 +1312,7 @@ export const ComputerUseZoomAction = Schema.Struct({ * `region` is only a four-number tuple and does not validate corner ordering or * display bounds. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1277,6 +1335,7 @@ const ComputerUse_20251124_Actions = Schema.Union([ * Requires the "computer-use-2024-10-22" beta header. * Basic actions only: screenshot, left_click, type, key, mouse_move. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -1308,6 +1367,7 @@ export const ComputerUse_20241022 = Tool.providerDefined({ * @see {@link ComputerUse_20241022} for the older basic action set * @see {@link ComputerUse_20251124} for the newer zoom-capable version * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -1342,6 +1402,7 @@ export const ComputerUse_20250124 = Tool.providerDefined({ * @see {@link ComputerUse_20250124} for the previous action set without zoom * @see {@link ComputerUseZoomAction} for the zoom action payload * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -1380,6 +1441,7 @@ export const ComputerUse_20251124 = Tool.providerDefined({ * @see {@link MemoryViewCommand} for memory view payloads that use this range * @see {@link TextEditorViewCommand} for text editor view payloads that use this range * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1391,6 +1453,7 @@ export const ViewRange = Schema.Tuple([Schema.Int, Schema.Int]) * * Use when typing `view_range` for memory or text editor view commands. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1408,6 +1471,7 @@ export type ViewRange = typeof ViewRange.Type * The payload contains `command: "create"`, a `path` string, and the * `file_text` content to write to the file. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1425,6 +1489,7 @@ export const MemoryCreateCommand = Schema.Struct({ /** * Memory tool command payload for creating a new file at a path. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1433,6 +1498,7 @@ export type MemoryCreateCommand = typeof MemoryCreateCommand.Type /** * Schema for a memory command that deletes a file or directory. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1446,6 +1512,7 @@ export const MemoryDeleteCommand = Schema.Struct({ /** * Memory tool command payload for deleting a file or directory at a path. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1466,6 +1533,7 @@ export type MemoryDeleteCommand = typeof MemoryDeleteCommand.Type * @see {@link Memory_20250818} for the provider-defined tool that consumes this command * @see {@link MemoryStrReplaceCommand} for replacing existing text instead * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1487,6 +1555,7 @@ export const MemoryInsertCommand = Schema.Struct({ /** * Memory tool command payload for inserting text at a specific line in a file. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1500,6 +1569,7 @@ export type MemoryInsertCommand = typeof MemoryInsertCommand.Type * The payload uses `command: "rename"` and requires `old_path` as the current * path plus `new_path` as the new destination path. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1517,6 +1587,7 @@ export const MemoryRenameCommand = Schema.Struct({ /** * Memory tool command payload for renaming or moving a file or directory. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1537,6 +1608,7 @@ export type MemoryRenameCommand = typeof MemoryRenameCommand.Type * * @see {@link Memory_20250818} for the provider-defined tool that consumes this command * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1558,6 +1630,7 @@ export const MemoryStrReplaceCommand = Schema.Struct({ /** * Memory tool command payload for replacing text in a file. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1571,6 +1644,7 @@ export type MemoryStrReplaceCommand = typeof MemoryStrReplaceCommand.Type * When used on a file, returns file contents optionally limited by `view_range`. * When used on a directory, lists contents. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1588,6 +1662,7 @@ export const MemoryViewCommand = Schema.Struct({ /** * Memory tool command payload for viewing a file or directory, optionally with a file line range. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1614,6 +1689,7 @@ const Memory_20250818_Commands = Schema.Union([ * Provides commands for creating, viewing, editing, renaming, and deleting * files within the model's memory space. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -1651,6 +1727,7 @@ export const Memory_20250818 = Tool.providerDefined({ * * @see {@link CodeExecutionTextEditorView} for the code-execution variant without `view_range` * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1674,6 +1751,7 @@ export const TextEditorViewCommand = Schema.Struct({ * `view_range` is a 1-indexed `[start, end]` tuple where `-1` means through * the end of the file. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1696,6 +1774,7 @@ export type TextEditorViewCommand = typeof TextEditorViewCommand.Type * * Fails if the file already exists. Parent directories must exist. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1722,6 +1801,7 @@ export const TextEditorCreateCommand = Schema.Struct({ * * The command fails if the file already exists or if parent directories are missing. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1748,6 +1828,7 @@ export type TextEditorCreateCommand = typeof TextEditorCreateCommand.Type * @see {@link TextEditorViewCommand} for reading contents before choosing `old_str` * @see {@link CodeExecutionTextEditorStrReplace} for the code-execution variant * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1779,6 +1860,7 @@ export const TextEditorStrReplaceCommand = Schema.Struct({ * The `old_str` must match exactly, including whitespace and indentation, and * must be unique in the file. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1792,6 +1874,7 @@ export type TextEditorStrReplaceCommand = typeof TextEditorStrReplaceCommand.Typ * Inserts the new text after the specified line number. Use `0` to insert at * the beginning of the file; other values are 1-indexed. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1813,6 +1896,7 @@ export const TextEditorInsertCommand = Schema.Struct({ /** * Text editor command payload for inserting text after a specific line number in a file. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1832,6 +1916,7 @@ export type TextEditorInsertCommand = typeof TextEditorInsertCommand.Type * `text_editor_20250124`, but not in `text_editor_20250429` or * `text_editor_20250728`. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1850,6 +1935,7 @@ export const TextEditorUndoEditCommand = Schema.Struct({ * Available for `text_editor_20241022` and `text_editor_20250124`, but not for * `text_editor_20250429` or `text_editor_20250728`. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1902,6 +1988,7 @@ const TextEditor_StrReplaceBasedEdit_Args = Schema.Struct({ * @see {@link TextEditor_20250124} for the newer `str_replace_editor` version * @see {@link TextEditor_20250728} for the Claude 4 `str_replace_based_edit_tool` line * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -1930,6 +2017,7 @@ export const TextEditor_20241022 = Tool.providerDefined({ * @see {@link TextEditor_20241022} for the older `str_replace_editor` version * @see {@link TextEditor_20250429} for the Claude 4 `str_replace_based_edit_tool` line * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -1961,6 +2049,7 @@ export const TextEditor_20250124 = Tool.providerDefined({ * @see {@link TextEditor_20250124} for the previous `str_replace_editor` version * @see {@link TextEditor_20250728} for the later Claude 4 text editor version * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -1986,6 +2075,7 @@ export const TextEditor_20250429 = Tool.providerDefined({ * * This version does not support the `undo_edit` command. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -2023,6 +2113,7 @@ export const TextEditor_20250728 = Tool.providerDefined({ * * @see {@link WebSearch_20250305_Args} for the argument schema that consumes this location * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -2073,6 +2164,7 @@ export const WebSearchUserLocation = Schema.Struct({ * @see {@link WebSearch_20250305} for the provider-defined tool that consumes these arguments * @see {@link WebSearchUserLocation} for localizing search results * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -2105,6 +2197,7 @@ export const WebSearch_20250305_Args = Schema.Struct({ * * `allowedDomains` and `blockedDomains` are mutually exclusive. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -2124,6 +2217,7 @@ export type WebSearch_20250305_Args = typeof WebSearch_20250305_Args.Type * * @see {@link WebSearch_20250305} for the provider-defined tool that consumes this payload * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -2142,6 +2236,7 @@ export const WebSearchParameters = Schema.Struct({ * * @see {@link WebSearch_20250305} for the provider-defined tool that consumes this payload * + * @stability unstable * @category models * @since 4.0.0 */ @@ -2166,6 +2261,7 @@ export type WebSearchParameters = typeof WebSearchParameters.Type * * @see {@link WebFetch_20250910} for retrieving known URLs after discovery * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -2201,6 +2297,7 @@ export const WebSearch_20250305 = Tool.providerDefined({ * * @see {@link WebFetch_20250910_Args} for the argument schema that consumes this configuration * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -2225,6 +2322,7 @@ export const WebFetchCitationsConfig = Schema.Struct({ * * @see {@link WebFetch_20250910_Args} for the argument schema that consumes this configuration * + * @stability unstable * @category models * @since 4.0.0 */ @@ -2256,6 +2354,7 @@ export type WebFetchCitationsConfig = typeof WebFetchCitationsConfig.Type * @see {@link WebFetch_20250910} for the provider-defined tool that consumes these arguments * @see {@link WebFetchCitationsConfig} for configuring citations * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -2299,6 +2398,7 @@ export const WebFetch_20250910_Args = Schema.Struct({ * `maxContentTokens` is approximate and does not apply to binary content such * as PDFs. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -2327,6 +2427,7 @@ export type WebFetch_20250910_Args = typeof WebFetch_20250910_Args.Type * * @see {@link WebFetch_20250910} for the provider-defined tool that consumes this payload * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -2354,6 +2455,7 @@ export const WebFetchParameters = Schema.Struct({ * The URL must be user-provided or from prior search/fetch results. Maximum URL * length is 250 characters. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -2379,6 +2481,7 @@ export type WebFetchParameters = typeof WebFetchParameters.Type * * @see {@link WebSearch_20250305} for discovering URLs before fetching specific content * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -2408,6 +2511,7 @@ export const WebFetch_20250910 = Tool.providerDefined({ * Claude constructs regex patterns using Python's `re.search()` syntax. * Maximum query length: 200 characters. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -2425,6 +2529,7 @@ export const ToolSearchRegexParameters = Schema.Struct({ * Claude constructs regex patterns using Python's `re.search()` syntax. * Maximum query length: 200 characters. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -2445,6 +2550,7 @@ export type ToolSearchRegexParameters = typeof ToolSearchRegexParameters.Type * * @see {@link ToolSearchBM25_20251119} for the provider-defined tool that consumes these parameters * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -2457,6 +2563,7 @@ export const ToolSearchBM25Parameters = Schema.Struct({ /** * Type of the parameters Claude supplies when invoking BM25 natural-language Anthropic tool search. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -2476,6 +2583,7 @@ export type ToolSearchBM25Parameters = typeof ToolSearchBM25Parameters.Type * argument names, and argument descriptions. * Requires the "advanced-tool-use-2025-11-20" beta header. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -2505,6 +2613,7 @@ export const ToolSearchRegex_20251119 = Tool.providerDefined({ * * @see {@link ToolSearchRegex_20251119} for the regex-pattern alternative * + * @stability unstable * @category tools * @since 4.0.0 */ diff --git a/packages/effect-ai-anthropic/src/Generated.ts b/packages/effect-ai-anthropic/src/Generated.ts index 319aeb2..e9d060a 100644 --- a/packages/effect-ai-anthropic/src/Generated.ts +++ b/packages/effect-ai-anthropic/src/Generated.ts @@ -1,16 +1,17 @@ /** + * @stability unstable * @since 4.0.0 */ import * as Data from "effect/Data" import * as Effect from "effect/Effect" +import * as HttpClient from "effect/http/HttpClient" +import * as HttpClientError from "effect/http/HttpClientError" +import * as HttpClientRequest from "effect/http/HttpClientRequest" +import * as HttpClientResponse from "effect/http/HttpClientResponse" import type { SchemaError } from "effect/Schema" import * as Schema from "effect/Schema" import * as Stream from "effect/Stream" -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" // non-recursive definitions export type APIError = { readonly "message": string; readonly "type": "api_error" } export const APIError = Schema.Struct({ @@ -7718,7 +7719,7 @@ export type BetaMessage = { readonly "cache_creation": BetaCacheCreation | null readonly "cache_creation_input_tokens": number | null readonly "cache_read_input_tokens": number | null - readonly "inference_geo": string | null + readonly "inference_geo"?: string | null readonly "input_tokens": number readonly "iterations"?: BetaIterationsUsage readonly "output_tokens": number @@ -7782,11 +7783,13 @@ export const BetaMessage = Schema.Struct({ "description": "The number of input tokens read from the cache.", "default": null }), - "inference_geo": Schema.Union([Schema.String, Schema.Null]).annotate({ - "title": "Inference Geo", - "description": "The geographic region where inference was performed for this request.", - "default": null - }), + "inference_geo": Schema.optionalKey( + Schema.Union([Schema.String, Schema.Null]).annotate({ + "title": "Inference Geo", + "description": "The geographic region where inference was performed for this request.", + "default": null + }) + ), "input_tokens": Schema.Number.annotate({ "title": "Input Tokens", "description": "The number of input tokens which were used." @@ -7872,7 +7875,7 @@ export type Message = { readonly "cache_creation": CacheCreation | null readonly "cache_creation_input_tokens": number | null readonly "cache_read_input_tokens": number | null - readonly "inference_geo": string | null + readonly "inference_geo"?: string | null readonly "input_tokens": number readonly "output_tokens": number readonly "server_tool_use"?: ServerToolUsage | null @@ -7933,11 +7936,13 @@ export const Message = Schema.Struct({ "description": "The number of input tokens read from the cache.", "default": null }), - "inference_geo": Schema.Union([Schema.String, Schema.Null]).annotate({ - "title": "Inference Geo", - "description": "The geographic region where inference was performed for this request.", - "default": null - }), + "inference_geo": Schema.optionalKey( + Schema.Union([Schema.String, Schema.Null]).annotate({ + "title": "Inference Geo", + "description": "The geographic region where inference was performed for this request.", + "default": null + }) + ), "input_tokens": Schema.Number.annotate({ "title": "Input Tokens", "description": "The number of input tokens which were used." diff --git a/packages/effect-ai-anthropic/src/index.ts b/packages/effect-ai-anthropic/src/index.ts index 48af730..9882f69 100644 --- a/packages/effect-ai-anthropic/src/index.ts +++ b/packages/effect-ai-anthropic/src/index.ts @@ -5,6 +5,7 @@ // @barrel: Auto-generated exports. Do not edit manually. /** + * @stability unstable * @since 4.0.0 */ export * as AnthropicClient from "./AnthropicClient.ts" @@ -20,6 +21,7 @@ export * as AnthropicConfig from "./AnthropicConfig.ts" export * as AnthropicError from "./AnthropicError.ts" /** + * @stability unstable * @since 4.0.0 */ export * as AnthropicLanguageModel from "./AnthropicLanguageModel.ts" @@ -30,11 +32,13 @@ export * as AnthropicLanguageModel from "./AnthropicLanguageModel.ts" export * as AnthropicTelemetry from "./AnthropicTelemetry.ts" /** + * @stability unstable * @since 4.0.0 */ export * as AnthropicTool from "./AnthropicTool.ts" /** + * @stability unstable * @since 4.0.0 */ export * as Generated from "./Generated.ts" diff --git a/packages/effect-ai-anthropic/src/internal/errors.ts b/packages/effect-ai-anthropic/src/internal/errors.ts index e0b2e95..8576ad8 100644 --- a/packages/effect-ai-anthropic/src/internal/errors.ts +++ b/packages/effect-ai-anthropic/src/internal/errors.ts @@ -1,17 +1,17 @@ +import * as AiError from "effect/ai/AiError" +import type * as Response from "effect/ai/Response" import * as Duration from "effect/Duration" import * as Effect from "effect/Effect" +import type * as Sse from "effect/encoding/Sse" import { dual } from "effect/Function" +import type * as HttpClientError from "effect/http/HttpClientError" +import type * as HttpClientRequest from "effect/http/HttpClientRequest" +import type * as HttpClientResponse from "effect/http/HttpClientResponse" 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 Sse from "effect/unstable/encoding/Sse" -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" diff --git a/packages/effect-ai-anthropic/src/internal/utilities.ts b/packages/effect-ai-anthropic/src/internal/utilities.ts index 322b035..43cdd8a 100644 --- a/packages/effect-ai-anthropic/src/internal/utilities.ts +++ b/packages/effect-ai-anthropic/src/internal/utilities.ts @@ -1,5 +1,5 @@ +import type * as Response from "effect/ai/Response" import * as Predicate from "effect/Predicate" -import type * as Response from "effect/unstable/ai/Response" const finishReasonMap: Record = { end_turn: "stop", diff --git a/packages/effect-ai-anthropic/test/HumanlayerFork.test.ts b/packages/effect-ai-anthropic/test/HumanlayerFork.test.ts index 3ebde98..b8416f0 100644 --- a/packages/effect-ai-anthropic/test/HumanlayerFork.test.ts +++ b/packages/effect-ai-anthropic/test/HumanlayerFork.test.ts @@ -1,8 +1,8 @@ import { assert, describe, it } from '@effect/vitest' import { AnthropicClient, AnthropicLanguageModel } from '@humanlayer/effect-ai-anthropic' import { Effect, Layer, Predicate, Redacted, Schema } from 'effect' -import { LanguageModel, Prompt } from 'effect/unstable/ai' -import { HttpClient, type HttpClientError, HttpClientResponse } from 'effect/unstable/http' +import { LanguageModel, Prompt } from 'effect/ai' +import { HttpClient, type HttpClientError, HttpClientResponse } from 'effect/http' const CapturedRequest = Schema.Struct({ messages: Schema.Array( diff --git a/packages/effect-ai-openai-compat/README.md b/packages/effect-ai-openai-compat/README.md index dfae504..92479c8 100644 --- a/packages/effect-ai-openai-compat/README.md +++ b/packages/effect-ai-openai-compat/README.md @@ -5,7 +5,7 @@ Connects the Effect AI modules to any OpenAI-compatible API, with support for ch ## Installation ```sh -npm install effect@4.0.0-rc.112 @humanlayer/effect-ai-openai-compat +npm install effect@4.0.0 @humanlayer/effect-ai-openai-compat ``` ## Documentation diff --git a/packages/effect-ai-openai-compat/UPSTREAM.md b/packages/effect-ai-openai-compat/UPSTREAM.md index 29c26cc..8de01a4 100644 --- a/packages/effect-ai-openai-compat/UPSTREAM.md +++ b/packages/effect-ai-openai-compat/UPSTREAM.md @@ -3,15 +3,15 @@ This directory is a vendored source snapshot of the published Effect OpenAI-compatible provider. It does not contain upstream `dist/` output. -| Field | Value | -| ---------------- | ---------------------------------------------------------------------------------------------------- | -| Upstream package | `@effect/ai-openai-compat@4.0.0-rc.112` | -| Source artifact | `https://registry.npmjs.org/@effect/ai-openai-compat/-/ai-openai-compat-4.0.0-rc.112.tgz` | -| npm integrity | `sha512-bfNYHgfjhzKhD7E1j1g2wPqAIucH6xiFylpT7YGVjF8SuF4i7TY5iLzfHp9Hr1RvF8fwiSGHt9nvnzrixGOkG9YZw==` | -| Tarball SHA-256 | `add1fb7a94bfcb8cd1e16ce2f8ba40296bba7d6eab55b9b230af3e3e53d12489` | -| Imported at | `2026-09-03` | -| Imported inputs | `src/**`, `README.md`, and `LICENSE` | -| License | MIT; copied to [`LICENSE`](./LICENSE) | +| Field | Value | +| ---------------- | ------------------------------------------------------------------------------------------------- | +| Upstream package | `@effect/ai-openai-compat@4.0.0` | +| Source artifact | `https://registry.npmjs.org/@effect/ai-openai-compat/-/ai-openai-compat-4.0.0.tgz` | +| npm integrity | `sha512-zoFwI5M7pUEj4UMHMbPsQGaVRxirIAIqzfVZAtpjJPXWwd/acwxN4kI1nS9gfn/lCHvFIc9xPEMstforcODesw==` | +| Tarball SHA-256 | `d515c57d9bbbf328825d29db6df2a44e2fede63b1ac516577d0879dbe63570a3` | +| Imported at | `2026-10-03` | +| Imported inputs | `src/**`, `README.md`, and `LICENSE` | +| License | MIT; copied to [`LICENSE`](./LICENSE) | This initial import preserves upstream provider behavior. Its Effect service/config keys use the `@humanlayer/effect-ai-openai-compat` namespace, so upstream and forked layers cannot satisfy one another accidentally diff --git a/packages/effect-ai-openai-compat/UPSTREAM.sha256 b/packages/effect-ai-openai-compat/UPSTREAM.sha256 index d079aa5..9238638 100644 --- a/packages/effect-ai-openai-compat/UPSTREAM.sha256 +++ b/packages/effect-ai-openai-compat/UPSTREAM.sha256 @@ -1,6 +1,6 @@ 774c3bc5924ad8ae6c5a75f1c53db13feb238ade15989625c513d07b60dedf30 LICENSE -7679c41fbb174be989187819f03e8e2ca96bae7e53d237445d534904ba610840 src/index.ts -c2c89a577e793ae7c9f337497fc76166bb3ef0a1745ed945d1260876c09814bb src/internal/errors.ts -ae0e49c772a58d474a9b07498f7e46f895f56da35b02c5c076901a7724bd8c38 src/internal/utilities.ts -a74a18141785d1db63fde9010bba4fbb12d6fc0d9948c3e57c4df460dfe6abea src/OpenAiError.ts -1cd5cecd963395d5f12f721481ea7b4bdc37b2f63ba1ff85a82e52fe4b155dbc src/OpenAiTelemetry.ts +62ed67485a5bd3b755ef4c0d6a13be7f1b7f41e5a52a7d2c40c8f8b26f4093d0 src/index.ts +867a2d0d599a98f55595efa7d571279d12f27f9d0d97cb8ba83e6ec7bf6825b5 src/internal/errors.ts +e60d3e1dde464e9afc4b82d4e0efe3b386e83b4c57f01f6c91935484fde27a65 src/internal/utilities.ts +abf11ed4582e38e2fcb2b98b3b550530dbf97925922f068607caf6d0e61f0439 src/OpenAiError.ts +2f9e565bd595d136831431a42a461b40d763f7e90deaf9c0270aaaa63020e8c6 src/OpenAiTelemetry.ts diff --git a/packages/effect-ai-openai-compat/src/OpenAiClient.ts b/packages/effect-ai-openai-compat/src/OpenAiClient.ts index 0f83229..f36fa6c 100644 --- a/packages/effect-ai-openai-compat/src/OpenAiClient.ts +++ b/packages/effect-ai-openai-compat/src/OpenAiClient.ts @@ -5,23 +5,24 @@ * typed helpers for non-streaming chat completions, streaming chat completions, * and embedding requests. * + * @stability unstable * @since 4.0.0 */ +import type * as AiError from "effect/ai/AiError" 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 * as Sse from "effect/encoding/Sse" import { identity } from "effect/Function" +import * as Headers from "effect/http/Headers" +import * as HttpClient from "effect/http/HttpClient" +import * as HttpClientRequest from "effect/http/HttpClientRequest" +import * as HttpClientResponse from "effect/http/HttpClientResponse" import * as Layer from "effect/Layer" 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 HttpClient from "effect/unstable/http/HttpClient" -import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest" -import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse" import * as Errors from "./internal/errors.ts" import { OpenAiConfig } from "./OpenAiConfig.ts" @@ -34,6 +35,7 @@ import { OpenAiConfig } from "./OpenAiConfig.ts" * completions, streaming chat completions, and embeddings. Transport and * schema decoding failures are mapped to `AiError`. * + * @stability unstable * @category services * @since 4.0.0 */ @@ -77,6 +79,7 @@ export interface Service { * @see {@link layer} for providing the service from explicit options * @see {@link layerConfig} for loading client settings from `Config` * + * @stability unstable * @category services * @since 4.0.0 */ @@ -87,6 +90,7 @@ export class OpenAiClient extends Context.Service()( /** * Configuration options used to construct an OpenAI-compatible client. * + * @stability unstable * @category options * @since 4.0.0 */ @@ -130,6 +134,7 @@ const withRedactedHeaders = Effect.updateService( * @see {@link layer} for providing this client from explicit options * @see {@link layerConfig} for loading client settings from `Config` * + * @stability unstable * @category constructors * @since 4.0.0 */ @@ -288,6 +293,7 @@ export const make = Effect.fnUntraced( * @see {@link make} for constructing the client service effectfully * @see {@link layerConfig} for loading client settings from `Config` * + * @stability unstable * @category layers * @since 4.0.0 */ @@ -312,6 +318,7 @@ export const layer = (options: Options): Layer.Layer & { readonly [x: string]: unknow * * @see {@link withConfigOverride} for scoping embedding request overrides * + * @stability unstable * @category services * @since 4.0.0 */ @@ -65,6 +68,7 @@ export class Config extends Context.Service< * @see {@link layer} for providing only the embedding model service * @see {@link withConfigOverride} for scoped request configuration overrides * + * @stability unstable * @category constructors * @since 4.0.0 */ @@ -112,13 +116,14 @@ export const model = ( * @see {@link layer} for providing the service as a `Layer` * @see {@link withConfigOverride} for scoping embedding request overrides * + * @stability unstable * @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 { +}): Effect.fn.Return { const client = yield* OpenAiClient const makeConfig = Effect.contextWith((services: Context.Context) => @@ -146,6 +151,7 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig * @see {@link make} for constructing the embedding model service effectfully * @see {@link model} for creating an `AiModel` with configured dimensions * + * @stability unstable * @category layers * @since 4.0.0 */ @@ -172,6 +178,7 @@ export const layer = (options: { * * @see {@link Config} for available OpenAI-compatible embedding request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -193,6 +200,7 @@ export const withConfigOverride: { * * @see {@link Config} for available OpenAI-compatible embedding request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -214,6 +222,7 @@ export const withConfigOverride: { * * @see {@link Config} for available OpenAI-compatible embedding request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -236,6 +245,7 @@ export const withConfigOverride: { * * @see {@link Config} for available OpenAI-compatible embedding request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -257,6 +267,7 @@ export const withConfigOverride: { * * @see {@link Config} for available OpenAI-compatible embedding request configuration fields * + * @stability unstable * @category configuration * @since 4.0.0 */ diff --git a/packages/effect-ai-openai-compat/src/OpenAiError.ts b/packages/effect-ai-openai-compat/src/OpenAiError.ts index 88ba2dd..e89e40c 100644 --- a/packages/effect-ai-openai-compat/src/OpenAiError.ts +++ b/packages/effect-ai-openai-compat/src/OpenAiError.ts @@ -66,7 +66,7 @@ export type OpenAiRateLimitMetadata = OpenAiErrorMetadata & { readonly resetTokens: string | null } -declare module "effect/unstable/ai/AiError" { +declare module "effect/ai/AiError" { /** * Metadata attached to rate limit errors returned by OpenAI-compatible APIs. * diff --git a/packages/effect-ai-openai-compat/src/OpenAiLanguageModel.ts b/packages/effect-ai-openai-compat/src/OpenAiLanguageModel.ts index 1c5a2fd..227d84a 100644 --- a/packages/effect-ai-openai-compat/src/OpenAiLanguageModel.ts +++ b/packages/effect-ai-openai-compat/src/OpenAiLanguageModel.ts @@ -6,13 +6,23 @@ * or streaming chat completion results back into Effect AI response content and * metadata. * + * @stability unstable * @since 4.0.0 */ +import * as AiError from "effect/ai/AiError" +import * as LanguageModel from "effect/ai/LanguageModel" +import * as AiModel from "effect/ai/Model" +import { toCodecOpenAI } from "effect/ai/OpenAiStructuredOutput" +import type * as Prompt from "effect/ai/Prompt" +import type * as Response from "effect/ai/Response" +import * as Tool from "effect/ai/Tool" import * as Context from "effect/Context" import * as DateTime from "effect/DateTime" import * as Effect from "effect/Effect" -import * as Encoding from "effect/Encoding" +import * as Base64 from "effect/encoding/Base64" import { dual } from "effect/Function" +import type * as HttpClientRequest from "effect/http/HttpClientRequest" +import type * as HttpClientResponse from "effect/http/HttpClientResponse" import * as Layer from "effect/Layer" import * as Option from "effect/Option" import * as Predicate from "effect/Predicate" @@ -20,19 +30,9 @@ import * as Rec from "effect/Record" import * as Redactable from "effect/Redactable" import * as Schema from "effect/Schema" import * as AST from "effect/SchemaAST" -import * as SchemaIssue from "effect/SchemaIssue" import * as Stream from "effect/Stream" import type { Span } from "effect/Tracer" import type { DeepMutable, Simplify } from "effect/Types" -import * as AiError from "effect/unstable/ai/AiError" -import * as LanguageModel from "effect/unstable/ai/LanguageModel" -import * as AiModel from "effect/unstable/ai/Model" -import { toCodecOpenAI } from "effect/unstable/ai/OpenAiStructuredOutput" -import type * as Prompt from "effect/unstable/ai/Prompt" -import type * as Response from "effect/unstable/ai/Response" -import * as Tool from "effect/unstable/ai/Tool" -import type * as HttpClientRequest from "effect/unstable/http/HttpClientRequest" -import type * as HttpClientResponse from "effect/unstable/http/HttpClientResponse" import * as InternalUtilities from "./internal/utilities.ts" import { type Annotation, @@ -55,8 +55,6 @@ import { } from "./OpenAiClient.ts" import { addGenAIAnnotations } from "./OpenAiTelemetry.ts" -const formatIssue = SchemaIssue.makeFormatterDefault() - /** * Image detail level for vision requests. */ @@ -114,6 +112,7 @@ type ModelConfig = Omit & { readonly [x: string]: unknow * * @see {@link withConfigOverride} for scoping language model request overrides * + * @stability unstable * @category services * @since 4.0.0 */ @@ -126,10 +125,11 @@ export class Config extends Context.Service< // Provider Options / Metadata // ============================================================================= -declare module "effect/unstable/ai/Prompt" { +declare module "effect/ai/Prompt" { /** * OpenAI-compatible options for file prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -148,6 +148,7 @@ declare module "effect/unstable/ai/Prompt" { /** * OpenAI-compatible options for reasoning prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -172,6 +173,7 @@ declare module "effect/unstable/ai/Prompt" { /** * OpenAI-compatible options for assistant tool-call prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -194,6 +196,7 @@ declare module "effect/unstable/ai/Prompt" { /** * OpenAI-compatible options for tool-result prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -216,6 +219,7 @@ declare module "effect/unstable/ai/Prompt" { /** * OpenAI-compatible options for text prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -240,10 +244,11 @@ declare module "effect/unstable/ai/Prompt" { } } -declare module "effect/unstable/ai/Response" { +declare module "effect/ai/Response" { /** * OpenAI-compatible metadata attached to a complete text response part. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -276,6 +281,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata emitted when a streamed text part starts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -294,6 +300,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata emitted when a streamed text part ends. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -316,6 +323,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata attached to a complete reasoning response part. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -338,6 +346,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata emitted when a streamed reasoning part starts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -360,6 +369,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata emitted for a streamed reasoning delta. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -378,6 +388,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata emitted when a streamed reasoning part ends. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -400,6 +411,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata attached to tool-call response parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -418,6 +430,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata attached to document source citations. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -474,6 +487,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata attached to URL source citations. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -500,6 +514,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI-compatible metadata attached to finish response parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -531,6 +546,7 @@ declare module "effect/unstable/ai/Response" { * @see {@link layer} for creating a `LanguageModel.LanguageModel` layer directly * @see {@link make} for constructing the language model service effectfully * + * @stability unstable * @category constructors * @since 4.0.0 */ @@ -569,13 +585,14 @@ export const model = ( * @see {@link layer} for providing the service as a `Layer` * @see {@link model} for creating a model descriptor for `AiModel.provide` * + * @stability unstable * @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 { +}): Effect.fn.Return { const client = yield* OpenAiClient const makeConfig = Effect.contextWith((services: Context.Context) => @@ -678,6 +695,7 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig * @see {@link make} for constructing the language model service effectfully * @see {@link model} for creating an AI model descriptor * + * @stability unstable * @category layers * @since 4.0.0 */ @@ -702,6 +720,7 @@ export const layer = (options: { * * @see {@link Config} for the configuration shape * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -721,6 +740,7 @@ export const withConfigOverride: { * * @see {@link Config} for the configuration shape * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -740,6 +760,7 @@ export const withConfigOverride: { * * @see {@link Config} for the configuration shape * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -760,6 +781,7 @@ export const withConfigOverride: { * * @see {@link Config} for the configuration shape * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -779,6 +801,7 @@ export const withConfigOverride: { * * @see {@link Config} for the configuration shape * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -860,15 +883,14 @@ const prepareMessages = Effect.fnUntraced( if (typeof part.data === "string" && isFileId(part.data, config)) { content.push({ type: "input_image", file_id: part.data, detail }) - } - - if (part.data instanceof URL) { - content.push({ type: "input_image", image_url: part.data.toString(), detail }) - } - - if (part.data instanceof Uint8Array) { - const base64 = Encoding.encodeBase64(part.data) - const imageUrl = `data:${mediaType};base64,${base64}` + } else { + const imageUrl = part.data instanceof URL + ? part.data.toString() + : part.data instanceof Uint8Array + ? `data:${mediaType};base64,${Base64.encode(part.data)}` + : /^(data:|https?:\/\/)/i.test(part.data) + ? part.data + : `data:${mediaType};base64,${part.data}` content.push({ type: "input_image", image_url: imageUrl, detail }) } } else if (part.mediaType === "application/pdf") { @@ -881,7 +903,7 @@ const prepareMessages = Effect.fnUntraced( } if (part.data instanceof Uint8Array) { - const base64 = Encoding.encodeBase64(part.data) + const base64 = Base64.encode(part.data) const fileName = part.fileName ?? `part-${index}.pdf` const fileData = `data:application/pdf;base64,${base64}` content.push({ type: "input_file", filename: fileName, file_data: fileData }) @@ -1169,7 +1191,6 @@ const makeResponse = Effect.fnUntraced( method: "makeResponse", reason: new AiError.ToolParameterValidationError({ toolName, - toolParams: {}, description: `Failed to securely JSON parse tool parameters: ${cause}` }) }) @@ -1262,7 +1283,6 @@ const makeStreamResponse = Effect.fnUntraced( method: "makeStreamResponse", reason: new AiError.ToolParameterValidationError({ toolName: toolCall.name, - toolParams: {}, description: `Failed to securely JSON parse tool parameters: ${cause}` }) }) @@ -1521,22 +1541,21 @@ const transformToolCallParams = Effect.fnUntraced(function* - ).pipe(Effect.mapError((error) => - AiError.make({ - module: "OpenAiLanguageModel", - method: "makeResponse", - reason: new AiError.ToolParameterValidationError({ - toolName, - toolParams, - description: formatIssue(error.issue) - }) - }) - )) + Schema.decodeEffect(codec)(toolParams) as Effect.Effect + ).pipe( + Effect.flatMap((decoded) => + Schema.encodeUnknownEffect(tool.parametersSchema)(decoded) as Effect.Effect + ), + Effect.orElseSucceed(() => toolParams) + ) }) const prepareTools = Effect.fnUntraced(function*>({ diff --git a/packages/effect-ai-openai-compat/src/OpenAiTelemetry.ts b/packages/effect-ai-openai-compat/src/OpenAiTelemetry.ts index 21ab20e..1974931 100644 --- a/packages/effect-ai-openai-compat/src/OpenAiTelemetry.ts +++ b/packages/effect-ai-openai-compat/src/OpenAiTelemetry.ts @@ -6,11 +6,11 @@ * * @since 4.0.0 */ +import * as Telemetry from "effect/ai/Telemetry" 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 diff --git a/packages/effect-ai-openai-compat/src/index.ts b/packages/effect-ai-openai-compat/src/index.ts index 7a5cd7f..3b5e537 100644 --- a/packages/effect-ai-openai-compat/src/index.ts +++ b/packages/effect-ai-openai-compat/src/index.ts @@ -5,6 +5,7 @@ // @barrel: Auto-generated exports. Do not edit manually. /** + * @stability unstable * @since 4.0.0 */ export * as OpenAiClient from "./OpenAiClient.ts" @@ -15,6 +16,7 @@ export * as OpenAiClient from "./OpenAiClient.ts" export * as OpenAiConfig from "./OpenAiConfig.ts" /** + * @stability unstable * @since 4.0.0 */ export * as OpenAiEmbeddingModel from "./OpenAiEmbeddingModel.ts" @@ -25,6 +27,7 @@ export * as OpenAiEmbeddingModel from "./OpenAiEmbeddingModel.ts" export * as OpenAiError from "./OpenAiError.ts" /** + * @stability unstable * @since 4.0.0 */ export * as OpenAiLanguageModel from "./OpenAiLanguageModel.ts" diff --git a/packages/effect-ai-openai-compat/src/internal/errors.ts b/packages/effect-ai-openai-compat/src/internal/errors.ts index 500289c..4fef55b 100644 --- a/packages/effect-ai-openai-compat/src/internal/errors.ts +++ b/packages/effect-ai-openai-compat/src/internal/errors.ts @@ -1,19 +1,19 @@ +import * as AiError from "effect/ai/AiError" +import type * as Response from "effect/ai/Response" import * as Arr from "effect/Array" import * as Duration from "effect/Duration" import * as Effect from "effect/Effect" +import type * as Sse from "effect/encoding/Sse" import { dual } from "effect/Function" +import type * as HttpClientError from "effect/http/HttpClientError" +import type * as HttpClientRequest from "effect/http/HttpClientRequest" +import type * as HttpClientResponse from "effect/http/HttpClientResponse" 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 Sse from "effect/unstable/encoding/Sse" -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 */ diff --git a/packages/effect-ai-openai-compat/src/internal/utilities.ts b/packages/effect-ai-openai-compat/src/internal/utilities.ts index 75daf6b..19247aa 100644 --- a/packages/effect-ai-openai-compat/src/internal/utilities.ts +++ b/packages/effect-ai-openai-compat/src/internal/utilities.ts @@ -1,4 +1,4 @@ -import type * as Response from "effect/unstable/ai/Response" +import type * as Response from "effect/ai/Response" const finishReasonMap: Record = { content_filter: "content-filter", diff --git a/packages/effect-ai-openai/README.md b/packages/effect-ai-openai/README.md index f520827..cd53311 100644 --- a/packages/effect-ai-openai/README.md +++ b/packages/effect-ai-openai/README.md @@ -5,7 +5,7 @@ An [OpenAI](https://openai.com) provider for the Effect AI modules. Includes a t ## Installation ```sh -npm install effect@4.0.0-rc.112 @humanlayer/effect-ai-openai +npm install effect@4.0.0 @humanlayer/effect-ai-openai ``` ## Documentation diff --git a/packages/effect-ai-openai/UPSTREAM.md b/packages/effect-ai-openai/UPSTREAM.md index 04ecf23..acc12fa 100644 --- a/packages/effect-ai-openai/UPSTREAM.md +++ b/packages/effect-ai-openai/UPSTREAM.md @@ -5,11 +5,11 @@ This directory is a vendored source snapshot of the published Effect OpenAI prov | Field | Value | | ---------------- | ------------------------------------------------------------------------------------------------- | -| Upstream package | `@effect/ai-openai@4.0.0-rc.112` | -| Source artifact | `https://registry.npmjs.org/@effect/ai-openai/-/ai-openai-4.0.0-rc.112.tgz` | -| npm integrity | `sha512-j2X86xvgpAtNiusyESADHZn3PUzMVatE1zWXd0No2aybx/euKiVBVWZOtzq7ntJ5KvPHRBOFXTGPADdApQrwug==` | -| Tarball SHA-256 | `26902ae06ec9118172f8033e84d4bffa19c0a6d3be56a42bc1147a6a131e4e43` | -| Imported at | `2026-09-03` | +| Upstream package | `@effect/ai-openai@4.0.0` | +| Source artifact | `https://registry.npmjs.org/@effect/ai-openai/-/ai-openai-4.0.0.tgz` | +| npm integrity | `sha512-WjLvyFW4urzXkNy+Ki1YQE912yOxMYHps5gbiPfiUDghuHz0hfA+jzprGL8vj4fTwZI56TIwkviKRqfQNwka7w==` | +| Tarball SHA-256 | `6b261f75d60d41d47d71a5405fdd06e3af3ed0e3a754e54bbdd629c4001e403a` | +| Imported at | `2026-10-03` | | Imported inputs | `src/**`, `README.md`, and `LICENSE` | | License | MIT; copied to [`LICENSE`](./LICENSE) | diff --git a/packages/effect-ai-openai/src/Generated.ts b/packages/effect-ai-openai/src/Generated.ts index d51b312..4d5918b 100644 --- a/packages/effect-ai-openai/src/Generated.ts +++ b/packages/effect-ai-openai/src/Generated.ts @@ -1,17 +1,18 @@ /** + * @stability unstable * @since 1.0.0 */ import * as Data from "effect/Data" import * as Effect from "effect/Effect" +import * as Sse from "effect/encoding/Sse" +import * as HttpClient from "effect/http/HttpClient" +import * as HttpClientError from "effect/http/HttpClientError" +import * as HttpClientRequest from "effect/http/HttpClientRequest" +import * as HttpClientResponse from "effect/http/HttpClientResponse" import type { SchemaError } from "effect/Schema" import * as Schema from "effect/Schema" import * as Stream from "effect/Stream" -import * as Sse from "effect/unstable/encoding/Sse" -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" // non-recursive definitions export type AddUploadPartRequest = { readonly "data": string } export const AddUploadPartRequest = Schema.Struct({ @@ -8405,13 +8406,15 @@ export const WebSearchLocation = Schema.Struct({ export type WebSearchToolCall = { readonly "id": string readonly "type": "web_search_call" - readonly "status": "in_progress" | "searching" | "completed" | "failed" - readonly "action": + readonly "status": "in_progress" | "searching" | "completed" | "failed" | "incomplete" + readonly "action"?: | { readonly "type": "search" readonly "query"?: string readonly "queries"?: ReadonlyArray - readonly "sources"?: ReadonlyArray<{ readonly "type": "url"; readonly "url": string }> + readonly "sources"?: ReadonlyArray< + { readonly "type": "url"; readonly "url": string } | { readonly "type": "api"; readonly "name": string } + > } | { readonly "type": "open_page"; readonly "url"?: string | null } | { readonly "type": "find_in_page"; readonly "url": string; readonly "pattern": string } @@ -8421,10 +8424,10 @@ export const WebSearchToolCall = Schema.Struct({ "type": Schema.Literal("web_search_call").annotate({ "description": "The type of the web search tool call. Always `web_search_call`.\n" }), - "status": Schema.Literals(["in_progress", "searching", "completed", "failed"]).annotate({ + "status": Schema.Literals(["in_progress", "searching", "completed", "failed", "incomplete"]).annotate({ "description": "The status of the web search tool call.\n" }), - "action": Schema.Union([ + "action": Schema.optionalKey(Schema.Union([ Schema.Struct({ "type": Schema.Literal("search").annotate({ "description": "The action type.\n" }), "query": Schema.optionalKey(Schema.String.annotate({ "description": "[DEPRECATED] The search query.\n" })), @@ -8436,10 +8439,18 @@ export const WebSearchToolCall = Schema.Struct({ ), "sources": Schema.optionalKey( Schema.Array( - Schema.Struct({ - "type": Schema.Literal("url").annotate({ "description": "The type of source. Always `url`.\n" }), - "url": Schema.String.annotate({ "description": "The URL of the source.\n", "format": "uri" }) - }).annotate({ "title": "Web search source", "description": "A source used in the search.\n" }) + Schema.Union([ + Schema.Struct({ + "type": Schema.Literal("url").annotate({ "description": "The type of source. Always `url`.\n" }), + "url": Schema.String.annotate({ "description": "The URL of the source.\n", "format": "uri" }) + }).annotate({ "title": "Web search source", "description": "A source used in the search.\n" }), + Schema.Struct({ + "type": Schema.Literal("api").annotate({ "description": "The type of source. Always `api`.\n" }), + "name": Schema.String.annotate({ + "description": "The name of the API source, such as `oai-weather`, `oai-sports`, or `oai-finance`.\n" + }) + }).annotate({ "title": "Web search API source", "description": "An API source used in the search.\n" }) + ]) ).annotate({ "title": "Web search sources", "description": "The sources used in the search.\n" }) ) }).annotate({ @@ -8471,7 +8482,7 @@ export const WebSearchToolCall = Schema.Struct({ "description": "An object describing the specific action taken in this web search call.\nIncludes details on how the model used the web (search, open_page, find_in_page).\n" }) - ], { mode: "oneOf" }) + ], { mode: "oneOf" })) }).annotate({ "title": "Web search tool call", "description": @@ -22767,13 +22778,15 @@ export type InputItem = | { readonly "id": string readonly "type": "web_search_call" - readonly "status": "in_progress" | "searching" | "completed" | "failed" - readonly "action": + readonly "status": "in_progress" | "searching" | "completed" | "failed" | "incomplete" + readonly "action"?: | { readonly "type": "search" readonly "query"?: string readonly "queries"?: ReadonlyArray - readonly "sources"?: ReadonlyArray<{ readonly "type": "url"; readonly "url": string }> + readonly "sources"?: ReadonlyArray< + { readonly "type": "url"; readonly "url": string } | { readonly "type": "api"; readonly "name": string } + > } | { readonly "type": "open_page"; readonly "url"?: string | null } | { readonly "type": "find_in_page"; readonly "url": string; readonly "pattern": string } @@ -23052,10 +23065,10 @@ export const InputItem = Schema.Union([ "type": Schema.Literal("web_search_call").annotate({ "description": "The type of the web search tool call. Always `web_search_call`.\n" }), - "status": Schema.Literals(["in_progress", "searching", "completed", "failed"]).annotate({ + "status": Schema.Literals(["in_progress", "searching", "completed", "failed", "incomplete"]).annotate({ "description": "The status of the web search tool call.\n" }), - "action": Schema.Union([ + "action": Schema.optionalKey(Schema.Union([ Schema.Struct({ "type": Schema.Literal("search").annotate({ "description": "The action type.\n" }), "query": Schema.optionalKey(Schema.String.annotate({ "description": "[DEPRECATED] The search query.\n" })), @@ -23067,10 +23080,19 @@ export const InputItem = Schema.Union([ ), "sources": Schema.optionalKey( Schema.Array( - Schema.Struct({ - "type": Schema.Literal("url").annotate({ "description": "The type of source. Always `url`.\n" }), - "url": Schema.String.annotate({ "description": "The URL of the source.\n", "format": "uri" }) - }).annotate({ "title": "Web search source", "description": "A source used in the search.\n" }) + Schema.Union([ + Schema.Struct({ + "type": Schema.Literal("url").annotate({ "description": "The type of source. Always `url`.\n" }), + "url": Schema.String.annotate({ "description": "The URL of the source.\n", "format": "uri" }) + }).annotate({ "title": "Web search source", "description": "A source used in the search.\n" }), + Schema.Struct({ + "type": Schema.Literal("api").annotate({ "description": "The type of source. Always `api`.\n" }), + "name": Schema.String.annotate({ + "description": + "The name of the API source, such as `oai-weather`, `oai-sports`, or `oai-finance`.\n" + }) + }).annotate({ "title": "Web search API source", "description": "An API source used in the search.\n" }) + ]) ).annotate({ "title": "Web search sources", "description": "The sources used in the search.\n" }) ) }).annotate({ @@ -23102,7 +23124,7 @@ export const InputItem = Schema.Union([ "description": "An object describing the specific action taken in this web search call.\nIncludes details on how the model used the web (search, open_page, find_in_page).\n" }) - ], { mode: "oneOf" }) + ], { mode: "oneOf" })) }).annotate({ "title": "Web search tool call", "description": "Content item used to generate a response.\n" }), Schema.Struct({ "id": Schema.optionalKey(Schema.String.annotate({ "description": "The unique ID of the function tool call.\n" })), diff --git a/packages/effect-ai-openai/src/OpenAiClient.ts b/packages/effect-ai-openai/src/OpenAiClient.ts index c4feeee..233946d 100644 --- a/packages/effect-ai-openai/src/OpenAiClient.ts +++ b/packages/effect-ai-openai/src/OpenAiClient.ts @@ -6,14 +6,24 @@ * WebSocket response streams, and embeddings, and maps transport or decoding * failures into `AiError`. * + * @stability unstable * @since 4.0.0 */ +import * as AiError from "effect/ai/AiError" +import * as ResponseIdTracker from "effect/ai/ResponseIdTracker" import * as Array from "effect/Array" +import * as Cause from "effect/Cause" import type * as Config from "effect/Config" import * as Context from "effect/Context" import * as Effect from "effect/Effect" +import * as Sse from "effect/encoding/Sse" import { identity } from "effect/Function" import * as Function from "effect/Function" +import * as Headers from "effect/http/Headers" +import * as HttpBody from "effect/http/HttpBody" +import * as HttpClient from "effect/http/HttpClient" +import * as HttpClientRequest from "effect/http/HttpClientRequest" +import * as HttpClientResponse from "effect/http/HttpClientResponse" import * as Layer from "effect/Layer" import * as Predicate from "effect/Predicate" import * as Queue from "effect/Queue" @@ -22,16 +32,8 @@ 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 Socket from "effect/socket/Socket" 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" @@ -47,6 +49,7 @@ import * as OpenAiSchema from "./OpenAiSchema.ts" * * 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`. * + * @stability unstable * @category services * @since 4.0.0 */ @@ -108,6 +111,7 @@ export interface Service { * @see {@link layer} for providing a client from explicit options * @see {@link layerConfig} for providing a client from `Config` * + * @stability unstable * @category services * @since 4.0.0 */ @@ -122,6 +126,7 @@ export class OpenAiClient extends Context.Service()( /** * Options for configuring the OpenAI client. * + * @stability unstable * @category options * @since 4.0.0 */ @@ -214,6 +219,7 @@ const authenticateRequest = (options: Options) => { * @see {@link layer} for providing this client from explicit options * @see {@link layerConfig} for loading client settings from `Config` * + * @stability unstable * @category constructors * @since 4.0.0 */ @@ -380,6 +386,7 @@ export const make = Effect.fnUntraced( * @see {@link make} for constructing the client service effectfully * @see {@link layerConfig} for loading client settings from `Config` * + * @stability unstable * @category layers * @since 4.0.0 */ @@ -403,6 +410,7 @@ export const layer = (options: Options): Layer.Layer Effect.Effect - readonly incoming: Queue.Dequeue - } - > = yield* RcRef.make({ + // The response currently in flight, or undefined between turns. Each turn + // owns its queue; the reader ends or fails it, so a turn that is still + // current when its consumer leaves was abandoned mid-response. + type Turn = Queue.Queue + type SocketConnection = { + readonly send: (message: typeof OpenAiSchema.CreateResponse.Encoded) => Effect.Effect + current: Turn | undefined + } + + const queueRef: RcRef.RcRef = yield* RcRef.make({ idleTimeToLive: 60_000, acquire: Effect.gen(function*() { const scope = yield* Effect.scope @@ -553,77 +567,119 @@ const makeSocket = Effect.gen(function*() { Effect.provideService(Socket.WebSocketConstructor, (url) => makeWebSocket(url, { headers: request.headers - } as any)) + })) ) - const write = yield* socket.writer + const writer = yield* socket.writer yield* Scope.addFinalizerExit(scope, () => { tracker.clearUnsafe() return Effect.void }) - const incoming = yield* Queue.unbounded() - 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: errorHeaders - }, - 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( + const connection: SocketConnection = { + current: undefined, + send: (message) => + writer.write(JSON.stringify({ + type: "response.create", + ...message + })).pipe( + Effect.mapError((_error) => AiError.make({ module: "OpenAiClient", method: "createResponseStream", - reason: AiError.reasonFromHttpStatus({ - description: json, - status: isNaN(status) ? - Object.hasOwn(errorTypeToStatus, error.type) - ? errorTypeToStatus[error.type] - : 500 : - status, - metadata: error as any, - http: { - body: json, - request: { - method: "POST", - url: request.url, - urlParams: [], - hash: undefined, + reason: new AiError.NetworkError({ + reason: "TransportError", + request: { + method: "POST", + url: request.url, + urlParams: [], + hash: undefined, headers: errorHeaders - } - } + }, + description: "Failed to send message over WebSocket" }) }) ) + ) + } + + const handleMessage = (msg: Uint8Array | string): void => { + const turn = connection.current + if (turn === undefined) return + let event: typeof AllEvents.Type + try { + event = decodeEvent(typeof msg === "string" ? msg : decoder.decode(msg)) + } catch { + return + } + if (event.type === "error") { + const status = "status" in event ? Number(event.status) : NaN + const error = ("error" in event ? event.error : event) as { + readonly type?: string + readonly code?: string + readonly message: string + } + const errorType = error.code ?? + (error.type === "api_error" && /^gRPC error: Response with id=\S+ not found$/.test(error.message) + ? "previous_response_not_found" + : error.type ?? "unknown") + const json = JSON.stringify(error) + // LanguageModel retries `previous_response_not_found` with the full + // prompt on this socket. Other errors leave the turn current so its + // finalizer invalidates the connection, preserving the existing policy. + if (errorType === "previous_response_not_found") { + connection.current = undefined + } + Queue.failCauseUnsafe( + turn, + Cause.fail(AiError.make({ + module: "OpenAiClient", + method: "createResponseStream", + reason: AiError.reasonFromHttpStatus({ + description: json, + status: errorType === "previous_response_not_found" + ? 400 + : isNaN(status) + ? Object.hasOwn(errorTypeToStatus, errorType) + ? errorTypeToStatus[errorType] + : 500 + : status, + metadata: error as any, + http: { + body: json, + request: { + method: "POST", + url: request.url, + urlParams: [], + hash: undefined, + headers: errorHeaders + } + } + }) + })) + ) + return + } + Queue.offerUnsafe(turn, event) + if ( + event.type === "response.completed" || event.type === "response.incomplete" || + event.type === "response.failed" + ) { + connection.current = undefined + Queue.endUnsafe(turn) + } + } + + yield* Effect.gen(function*() { + const { pull } = yield* socket.reader + while (true) { + const messages = yield* pull + for (let i = 0; i < messages.length; i++) { + handleMessage(messages[i]) } - Queue.offerUnsafe(incoming, event) - } catch {} + } }).pipe( + Effect.scoped, Effect.catchTag("SocketError", (error) => AiError.make({ module: "OpenAiClient", @@ -640,14 +696,16 @@ const makeSocket = Effect.gen(function*() { description: error.message }) })), - Effect.catchCause((cause) => Queue.failCause(incoming, cause)), + Effect.catchCause((cause) => + connection.current === undefined ? Effect.void : Queue.failCause(connection.current, cause) + ), Effect.ensuring(Effect.forkIn(RcRef.invalidate(queueRef), socketScope, { startImmediately: true })), Effect.forkScoped({ startImmediately: true }) ) - return { send, incoming } as const + return connection }) }) @@ -667,24 +725,22 @@ const makeSocket = Effect.gen(function*() { () => semaphore.release(1), { interruptible: true } ) - const { send, incoming } = yield* RcRef.get(queueRef) - let done = false + const connection = yield* RcRef.get(queueRef) + const turn: Turn = yield* Queue.unbounded() + connection.current = turn + // Leaving while the response is still streaming makes the socket + // unusable for the next turn. yield* Scope.addFinalizerExit( scope, - () => done ? Effect.void : RcRef.invalidate(queueRef) + () => connection.current === turn ? RcRef.invalidate(queueRef) : Effect.void ) - yield* send(options).pipe( + yield* connection.send(options).pipe( Effect.forkScoped({ startImmediately: true }) ) - return Stream.fromQueue(incoming).pipe( - Stream.takeUntil((e) => { - done = e.type === "response.completed" || e.type === "response.incomplete" || e.type === "response.failed" - return done - }) - ) + return Stream.fromQueue(turn) })) return Effect.succeed([ @@ -698,12 +754,14 @@ const makeSocket = Effect.gen(function*() { }) const ErrorEvent = Schema.Struct({ - type: Schema.Literal("error"), - status: Schema.Int.pipe( - Schema.withDecodingDefault(Effect.succeed(500)) + type: Schema.Literal("error").pipe( + Schema.withDecodingDefault(Effect.succeed("error" as const)) ), + status: Schema.optionalKey(Schema.Int), + // xAI sends `code` in place of `type`, e.g. `previous_response_not_found` error: Schema.Struct({ - type: Schema.String, + type: Schema.optional(Schema.String), + code: Schema.optional(Schema.String), message: Schema.String }) }) @@ -740,6 +798,7 @@ const decodeEvent = Schema.decodeUnknownSync(Schema.fromJsonString(AllEvents)) * @see {@link layerWebSocketMode} for providing WebSocket mode through a layer * @see {@link OpenAiSocket} for direct access to the WebSocket-backed streaming service * + * @stability unstable * @category providing services * @since 4.0.0 */ @@ -777,6 +836,7 @@ export const withWebSocketMode = ( * * @see {@link withWebSocketMode} for enabling WebSocket mode around a single effect * + * @stability unstable * @category layers * @since 4.0.0 */ diff --git a/packages/effect-ai-openai/src/OpenAiClientGenerated.ts b/packages/effect-ai-openai/src/OpenAiClientGenerated.ts index ca41345..77cbc0b 100644 --- a/packages/effect-ai-openai/src/OpenAiClientGenerated.ts +++ b/packages/effect-ai-openai/src/OpenAiClientGenerated.ts @@ -1,4 +1,5 @@ /** + * @stability unstable * @since 4.0.0 */ import * as Array from "effect/Array" @@ -7,12 +8,12 @@ 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 Headers from "effect/http/Headers" +import * as HttpClient from "effect/http/HttpClient" +import * as HttpClientRequest from "effect/http/HttpClientRequest" 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" @@ -24,6 +25,7 @@ import { OpenAiConfig } from "./OpenAiConfig.ts" * Service identifier for the generated OpenAI client. * * @since 4.0.0 + * @stability unstable * @category service */ export class OpenAiClientGenerated extends Context.Service()( @@ -38,6 +40,7 @@ export class OpenAiClientGenerated extends Context.Service => @@ -150,6 +155,7 @@ export const layer = (options: Options): Layer.Layer | undefined -}): Effect.fn.Return { +}): Effect.fn.Return { const client = yield* OpenAiClient const makeConfig = Effect.contextWith((services: Context.Context) => @@ -161,6 +166,7 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig * @see {@link make} for constructing the embedding model service effectfully * @see {@link model} for creating an `AiModel` that also provides embedding dimensions * + * @stability unstable * @category layers * @since 4.0.0 */ @@ -186,6 +192,7 @@ export const layer = (options: { * * @see {@link Config} for the scoped embedding request configuration service * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -206,6 +213,7 @@ export const withConfigOverride: { * * @see {@link Config} for the scoped embedding request configuration service * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -226,6 +234,7 @@ export const withConfigOverride: { * * @see {@link Config} for the scoped embedding request configuration service * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -247,6 +256,7 @@ export const withConfigOverride: { * * @see {@link Config} for the scoped embedding request configuration service * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -267,6 +277,7 @@ export const withConfigOverride: { * * @see {@link Config} for the scoped embedding request configuration service * + * @stability unstable * @category configuration * @since 4.0.0 */ diff --git a/packages/effect-ai-openai/src/OpenAiError.ts b/packages/effect-ai-openai/src/OpenAiError.ts index 5e2a96d..a0568d6 100644 --- a/packages/effect-ai-openai/src/OpenAiError.ts +++ b/packages/effect-ai-openai/src/OpenAiError.ts @@ -58,7 +58,7 @@ export type OpenAiRateLimitMetadata = OpenAiErrorMetadata & { readonly resetTokens: string | null } -declare module "effect/unstable/ai/AiError" { +declare module "effect/ai/AiError" { /** * OpenAI metadata attached to `RateLimitError` values. * diff --git a/packages/effect-ai-openai/src/OpenAiLanguageModel.ts b/packages/effect-ai-openai/src/OpenAiLanguageModel.ts index 2566203..da03f11 100644 --- a/packages/effect-ai-openai/src/OpenAiLanguageModel.ts +++ b/packages/effect-ai-openai/src/OpenAiLanguageModel.ts @@ -6,48 +6,47 @@ * non-streaming or streaming response results back into Effect AI response * content and metadata. * + * @stability unstable * @since 4.0.0 */ +import * as AiError from "effect/ai/AiError" +import * as IdGenerator from "effect/ai/IdGenerator" +import * as LanguageModel from "effect/ai/LanguageModel" +import * as AiModel from "effect/ai/Model" +import { toCodecOpenAI } from "effect/ai/OpenAiStructuredOutput" +import * as Prompt from "effect/ai/Prompt" +import type * as Response from "effect/ai/Response" +import * as Tool from "effect/ai/Tool" import * as Context from "effect/Context" import * as DateTime from "effect/DateTime" import * as Effect from "effect/Effect" -import * as Encoding from "effect/Encoding" +import * as Base64 from "effect/encoding/Base64" import { dual } from "effect/Function" +import type * as HttpClientRequest from "effect/http/HttpClientRequest" +import type * as HttpClientResponse from "effect/http/HttpClientResponse" import * as Layer from "effect/Layer" 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 AST from "effect/SchemaAST" -import * as SchemaIssue from "effect/SchemaIssue" import * as Stream from "effect/Stream" import type { Span } from "effect/Tracer" import type { DeepMutable, Mutable, Simplify } from "effect/Types" -import * as AiError from "effect/unstable/ai/AiError" -import * as IdGenerator from "effect/unstable/ai/IdGenerator" -import * as LanguageModel from "effect/unstable/ai/LanguageModel" -import * as AiModel from "effect/unstable/ai/Model" -import { toCodecOpenAI } from "effect/unstable/ai/OpenAiStructuredOutput" -import * as Prompt from "effect/unstable/ai/Prompt" -import type * as Response from "effect/unstable/ai/Response" -import * as Tool from "effect/unstable/ai/Tool" -import type * as HttpClientRequest from "effect/unstable/http/HttpClientRequest" -import type * as HttpClientResponse from "effect/unstable/http/HttpClientResponse" import * as Generated from "./Generated.ts" import * as InternalUtilities from "./internal/utilities.ts" -import { OpenAiClient } from "./OpenAiClient.ts" +import { OpenAiClient, OpenAiSocket } from "./OpenAiClient.ts" import type * as OpenAiSchema from "./OpenAiSchema.ts" import { addGenAIAnnotations } from "./OpenAiTelemetry.ts" import type * as OpenAiTool from "./OpenAiTool.ts" -const formatIssue = SchemaIssue.makeFormatterDefault() - const ResponseModelIds = Generated.ModelIdsResponses.members[1] const SharedModelIds = Generated.ModelIdsShared.members[1] /** * OpenAI model identifiers supported by the Responses API language model. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -79,6 +78,7 @@ type PromptCacheBreakpoint = { readonly mode: "explicit" } * * @see {@link withConfigOverride} for scoping language model request overrides * + * @stability unstable * @category services * @since 4.0.0 */ @@ -120,6 +120,16 @@ export class Config extends Context.Service< * Defaults to `true`. */ readonly strictJsonSchema?: boolean | undefined + /** + * Whether stored response items should be sent as item references. + * + * Set to `false` for OpenAI-compatible providers that support response + * storage and `previous_response_id`, but require historical assistant + * content to be serialized inline. + * + * Defaults to `true` when `store` is `true`. + */ + readonly useItemReferences?: boolean | undefined } > >()("@humanlayer/effect-ai-openai/OpenAiLanguageModel/Config") {} @@ -128,10 +138,11 @@ export class Config extends Context.Service< // Provider Options / Metadata // ============================================================================= -declare module "effect/unstable/ai/Prompt" { +declare module "effect/ai/Prompt" { /** * OpenAI-specific options for system messages. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -153,6 +164,7 @@ declare module "effect/unstable/ai/Prompt" { /** * OpenAI-specific options for file prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -171,6 +183,7 @@ declare module "effect/unstable/ai/Prompt" { /** * OpenAI-specific options for reasoning prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -195,6 +208,7 @@ declare module "effect/unstable/ai/Prompt" { /** * OpenAI-specific options for assistant tool-call prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -221,6 +235,7 @@ declare module "effect/unstable/ai/Prompt" { /** * OpenAI-specific options for tool-result prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -247,6 +262,7 @@ declare module "effect/unstable/ai/Prompt" { /** * OpenAI-specific options for text prompt parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -278,10 +294,11 @@ declare module "effect/unstable/ai/Prompt" { } } -declare module "effect/unstable/ai/Response" { +declare module "effect/ai/Response" { /** * OpenAI metadata attached to a complete text response part. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -314,6 +331,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata emitted when a streamed text part starts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -332,6 +350,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata emitted when a streamed text part ends. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -354,6 +373,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata attached to a complete reasoning response part. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -376,6 +396,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata emitted when a streamed reasoning part starts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -398,6 +419,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata emitted for a streamed reasoning delta. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -416,6 +438,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata emitted when a streamed reasoning part ends. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -438,6 +461,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata attached to tool-call response parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -456,6 +480,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata attached to document source citations. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -512,6 +537,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata attached to URL source citations. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -538,6 +564,7 @@ declare module "effect/unstable/ai/Response" { /** * OpenAI metadata attached to finish response parts. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -570,6 +597,7 @@ declare module "effect/unstable/ai/Response" { * @see {@link layer} for creating a `LanguageModel.LanguageModel` layer directly * @see {@link make} for constructing the language model service effectfully * + * @stability unstable * @category constructors * @since 4.0.0 */ @@ -609,13 +637,14 @@ export const model = ( * @see {@link layer} for providing the service as a `Layer` * @see {@link model} for creating a model descriptor for `Effect.provide` * + * @stability unstable * @category constructors * @since 4.0.0 */ export const make = Effect.fnUntraced(function*({ model, config: providerConfig }: { readonly model: (string & {}) | Model readonly config?: Omit | undefined -}): Effect.fn.Return { +}): Effect.fn.Return { const client = yield* OpenAiClient const makeConfig = Effect.gen(function*() { @@ -647,7 +676,12 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig config, options }) - const { fileIdPrefixes: _fip, strictJsonSchema: _sjs, ...apiConfig } = config + const { + fileIdPrefixes: _fip, + strictJsonSchema: _sjs, + useItemReferences: _uir, + ...apiConfig + } = config const request: Mutable = { ...apiConfig, input: messages, @@ -729,6 +763,7 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig * @see {@link model} for creating a model descriptor for `Effect.provide` * @see {@link withConfigOverride} for scoped request configuration overrides * + * @stability unstable * @category layers * @since 4.0.0 */ @@ -756,6 +791,7 @@ export const layer = (options: { * * @see {@link Config} for the scoped configuration service consumed by this function * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -778,6 +814,7 @@ export const withConfigOverride: { * * @see {@link Config} for the scoped configuration service consumed by this function * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -800,6 +837,7 @@ export const withConfigOverride: { * * @see {@link Config} for the scoped configuration service consumed by this function * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -823,6 +861,7 @@ export const withConfigOverride: { * * @see {@link Config} for the scoped configuration service consumed by this function * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -845,6 +884,7 @@ export const withConfigOverride: { * * @see {@link Config} for the scoped configuration service consumed by this function * + * @stability unstable * @category configuration * @since 4.0.0 */ @@ -886,8 +926,12 @@ const prepareMessages = Effect.fnUntraced( readonly toolNameMapper: Tool.NameMapper }): Effect.fn.Return, AiError.AiError> { const processedApprovalIds = new Set() + const websocketMode = Option.isSome(yield* Effect.serviceOption(OpenAiSocket)) const hasConversation = Predicate.isNotNullish(config.conversation) + const useItemReferences = config.store === true && + config.useItemReferences !== false && + options.incrementalFallback !== true // Provider-Defined Tools const applyPatchTool = options.tools.find((tool): tool is ReturnType => @@ -913,7 +957,7 @@ const prepareMessages = Effect.fnUntraced( if (Predicate.isNotUndefined(config.top_logprobs)) { include.add("message.output_text.logprobs") } - if (config.store === false && capabilities.isReasoningModel) { + if ((websocketMode || !useItemReferences) && capabilities.isReasoningModel) { include.add("reasoning.encrypted_content") } if (codeInterpreterTool) { @@ -963,15 +1007,14 @@ const prepareMessages = Effect.fnUntraced( if (typeof part.data === "string" && isFileId(part.data, config)) { content.push({ type: "input_image", file_id: part.data, detail }) - } - - if (part.data instanceof URL) { - content.push({ type: "input_image", image_url: part.data.toString(), detail }) - } - - if (part.data instanceof Uint8Array) { - const base64 = Encoding.encodeBase64(part.data) - const imageUrl = `data:${mediaType};base64,${base64}` + } else { + const imageUrl = part.data instanceof URL + ? part.data.toString() + : part.data instanceof Uint8Array + ? `data:${mediaType};base64,${Base64.encode(part.data)}` + : /^(data:|https?:\/\/)/i.test(part.data) + ? part.data + : `data:${mediaType};base64,${part.data}` content.push({ type: "input_image", image_url: imageUrl, detail }) } } else if (part.mediaType === "application/pdf") { @@ -984,7 +1027,7 @@ const prepareMessages = Effect.fnUntraced( } if (part.data instanceof Uint8Array) { - const base64 = Encoding.encodeBase64(part.data) + const base64 = Base64.encode(part.data) const fileName = part.fileName ?? `part-${index}.pdf` const fileData = `data:application/pdf;base64,${base64}` content.push({ type: "input_file", filename: fileName, file_data: fileData }) @@ -1011,6 +1054,18 @@ const prepareMessages = Effect.fnUntraced( const reasoningMessages: Record> = Object .create(null) + const providerExecutedParts = message.content.filter((part) => + (part.type === "tool-call" || part.type === "tool-result") && part.providerExecuted + ) + const unreplayableProviderItem = (name: string, id: string) => + AiError.make({ + module: "OpenAiLanguageModel", + method: "prepareMessages", + reason: new AiError.InvalidRequestError({ + description: `Cannot replay provider-executed tool item '${name}' ('${id}') losslessly` + }) + }) + for (const part of message.content) { switch (part.type) { case "text": { @@ -1022,7 +1077,7 @@ const prepareMessages = Effect.fnUntraced( break } - if (config.store === true && Predicate.isNotNull(id)) { + if (useItemReferences && Predicate.isNotNull(id)) { messages.push({ type: "item_reference", id }) break } @@ -1054,7 +1109,7 @@ const prepareMessages = Effect.fnUntraced( if (Predicate.isNotNull(id)) { const message = reasoningMessages[id] - if (config.store === true) { + if (useItemReferences) { // Use item references to refer to reasoning (single reference) // when the first part is encountered if (Predicate.isUndefined(message)) { @@ -1108,12 +1163,101 @@ const prepareMessages = Effect.fnUntraced( break } - if (config.store && Predicate.isNotNull(id)) { + if (useItemReferences && Predicate.isNotNull(id)) { messages.push({ type: "item_reference", id }) break } if (part.providerExecuted) { + if ( + config.store !== true && options.incrementalFallback !== true + ) { + break + } + const result = providerExecutedParts.find((candidate) => + candidate.type === "tool-result" && candidate.id === part.id && candidate.name === part.name + ) + if (Predicate.isUndefined(result) || result.type !== "tool-result") { + return yield* unreplayableProviderItem(part.name, part.id) + } + if ( + Predicate.hasProperty(result.result, "type") && + result.result.type === "execution-denied" + ) { + break + } + + const itemId = getItemId(part) ?? getItemId(result) ?? part.id + switch (part.name) { + case "OpenAiWebSearch": + case "OpenAiWebSearchPreview": { + if (!Predicate.hasProperty(result.result, "status")) { + return yield* unreplayableProviderItem(part.name, part.id) + } + messages.push({ + type: "web_search_call", + id: itemId, + ...(Predicate.hasProperty(result.result, "action") + ? { action: result.result.action } + : undefined), + status: result.result.status as string + }) + break + } + case "OpenAiCodeInterpreter": { + if ( + !Predicate.hasProperty(part.params, "code") || + !Predicate.hasProperty(part.params, "container_id") || + !Predicate.hasProperty(result.result, "status") || + !Predicate.hasProperty(result.result, "outputs") + ) { + return yield* unreplayableProviderItem(part.name, part.id) + } + messages.push({ + type: "code_interpreter_call", + id: itemId, + code: part.params.code as string | null, + container_id: part.params.container_id as string, + status: result.result.status as any, + outputs: result.result.outputs as any + }) + break + } + case "OpenAiFileSearch": { + if ( + !Predicate.hasProperty(result.result, "status") || + !Predicate.hasProperty(result.result, "queries") || + !Predicate.hasProperty(result.result, "results") + ) { + return yield* unreplayableProviderItem(part.name, part.id) + } + messages.push({ + type: "file_search_call", + id: itemId, + status: result.result.status as string, + queries: result.result.queries as Array, + results: result.result.results + }) + break + } + case "OpenAiImageGeneration": { + if (!Predicate.hasProperty(result.result, "result")) { + return yield* unreplayableProviderItem(part.name, part.id) + } + messages.push({ + type: "image_generation_call", + id: itemId, + result: result.result.result as string | null, + status: (Predicate.hasProperty(result.result, "status") + ? result.result.status + : "completed") as any + }) + break + } + default: { + return yield* unreplayableProviderItem(part.name, part.id) + } + } break } @@ -1127,7 +1271,6 @@ const prepareMessages = Effect.fnUntraced( method: "prepareMessages", reason: new AiError.ToolParameterValidationError({ toolName: "local_shell", - toolParams: part.params as Schema.Json, description: error.message }) }) @@ -1153,7 +1296,6 @@ const prepareMessages = Effect.fnUntraced( method: "prepareMessages", reason: new AiError.ToolParameterValidationError({ toolName: "shell", - toolParams: part.params as Schema.Json, description: error.message }) }) @@ -1198,9 +1340,19 @@ const prepareMessages = Effect.fnUntraced( break } - if (config.store === true) { + if (useItemReferences) { const id = getItemId(part) ?? part.id messages.push({ type: "item_reference", id }) + } else if ( + part.providerExecuted && + (config.store === true || options.incrementalFallback === true) + ) { + const call = providerExecutedParts.find((candidate) => + candidate.type === "tool-call" && candidate.id === part.id && candidate.name === part.name + ) + if (Predicate.isUndefined(call)) { + return yield* unreplayableProviderItem(part.name, part.id) + } } } } @@ -1218,7 +1370,7 @@ const prepareMessages = Effect.fnUntraced( processedApprovalIds.add(part.approvalId) - if (config.store === true) { + if (useItemReferences) { messages.push({ type: "item_reference", id: part.approvalId }) } @@ -1311,7 +1463,7 @@ const prepareMessages = Effect.fnUntraced( } else if (outputPart.data instanceof Uint8Array) { output.push({ type: "input_image", - image_url: `data:${mediaType};base64,${Encoding.encodeBase64(outputPart.data)}`, + image_url: `data:${mediaType};base64,${Base64.encode(outputPart.data)}`, detail }) } else { @@ -1475,19 +1627,20 @@ const makeResponse = Effect.fnUntraced( case "code_interpreter_call": { const toolName = toolNameMapper.getCustomName("code_interpreter") + const status = part.status ?? "completed" parts.push({ type: "tool-call", id: part.id, name: toolName, - params: { code: part.code, container_id: part.container_id }, + params: { code: part.code ?? null, container_id: part.container_id }, providerExecuted: true }) parts.push({ type: "tool-result", id: part.id, name: toolName, - isFailure: false, - result: { outputs: part.outputs }, + isFailure: status !== "completed", + result: { status, outputs: part.outputs ?? null }, providerExecuted: true }) break @@ -1506,7 +1659,7 @@ const makeResponse = Effect.fnUntraced( type: "tool-result", id: part.id, name: toolName, - isFailure: false, + isFailure: part.status !== "completed", result: { status: part.status, queries: part.queries, @@ -1530,7 +1683,6 @@ const makeResponse = Effect.fnUntraced( method: "makeResponse", reason: new AiError.ToolParameterValidationError({ toolName, - toolParams: {}, description: `Faled to securely JSON parse tool parameters: ${cause}` }) }) @@ -1550,6 +1702,7 @@ const makeResponse = Effect.fnUntraced( case "image_generation_call": { const toolName = toolNameMapper.getCustomName("image_generation") + const status = part.status ?? "completed" parts.push({ type: "tool-call", id: part.id, @@ -1561,8 +1714,10 @@ const makeResponse = Effect.fnUntraced( type: "tool-result", id: part.id, name: toolName, - isFailure: false, - result: { result: part.result } + isFailure: status !== "completed", + result: status === "completed" + ? { result: part.result } + : { status, result: part.result } }) break } @@ -1602,7 +1757,7 @@ const makeResponse = Effect.fnUntraced( type: "tool-result", id: toolId, name: toolName, - isFailure: false, + isFailure: Predicate.isNotNullish(part.error), providerExecuted: true, result: { type: "mcp_call", @@ -1791,7 +1946,7 @@ const makeResponse = Effect.fnUntraced( type: "tool-call", id: part.id, name: toolName, - params: webSearchTool?.name === "OpenAiWebSearchPreview" + params: webSearchTool?.name === "OpenAiWebSearchPreview" || Predicate.isUndefined(part.action) ? {} : { action: part.action }, providerExecuted: true @@ -1800,8 +1955,11 @@ const makeResponse = Effect.fnUntraced( type: "tool-result", id: part.id, name: toolName, - isFailure: false, - result: { action: part.action, status: part.status }, + isFailure: part.status !== "completed", + result: { + ...(Predicate.isUndefined(part.action) ? undefined : { action: part.action }), + status: part.status + }, providerExecuted: true }) break @@ -1845,6 +2003,7 @@ const makeStreamResponse = Effect.fnUntraced( IdGenerator.IdGenerator > { const idGenerator = yield* IdGenerator.IdGenerator + const websocketMode = Option.isSome(yield* Effect.serviceOption(OpenAiSocket)) const approvalRequests = getApprovalRequestIdMapping(options.prompt) const streamApprovalRequests = new Map() @@ -1896,9 +2055,39 @@ const makeStreamResponse = Effect.fnUntraced( } readonly codeInterpreter?: { readonly containerId: string + hasCode: boolean + streamedCode: string } }> = {} + const finishCodeInterpreterCall = ( + outputIndex: number, + code: string | null, + parts: Array + ) => { + const toolCall = activeToolCalls[outputIndex] + if (Predicate.isUndefined(toolCall?.codeInterpreter)) { + return + } + parts.push({ + type: "tool-params-delta", + id: toolCall.id, + delta: toolCall.codeInterpreter.hasCode ? "\"}" : `${JSON.stringify(code)}}` + }) + parts.push({ type: "tool-params-end", id: toolCall.id }) + parts.push({ + type: "tool-call", + id: toolCall.id, + name: toolCall.name, + params: { + code: toolCall.codeInterpreter.hasCode ? toolCall.codeInterpreter.streamedCode : code, + container_id: toolCall.codeInterpreter.containerId + }, + providerExecuted: true + }) + delete activeToolCalls[outputIndex] + } + const webSearchTool = options.tools.find((tool) => Tool.isProviderDefined(tool) && (tool.name === "OpenAiWebSearch" || @@ -2010,7 +2199,7 @@ const makeStreamResponse = Effect.fnUntraced( activeToolCalls[event.output_index] = { id: event.item.id, name: toolName, - codeInterpreter: { containerId: event.item.container_id } + codeInterpreter: { containerId: event.item.container_id, hasCode: false, streamedCode: "" } } parts.push({ type: "tool-params-start", @@ -2021,7 +2210,7 @@ const makeStreamResponse = Effect.fnUntraced( parts.push({ type: "tool-params-delta", id: event.item.id, - delta: `{"containerId":"${event.item.container_id}","code":"` + delta: `{"container_id":${JSON.stringify(event.item.container_id)},"code":` }) break } @@ -2204,14 +2393,15 @@ const makeStreamResponse = Effect.fnUntraced( } case "code_interpreter_call": { - delete activeToolCalls[event.output_index] + finishCodeInterpreterCall(event.output_index, event.item.code ?? null, parts) const toolName = toolNameMapper.getCustomName("code_interpreter") + const status = event.item.status ?? "completed" parts.push({ type: "tool-result", id: event.item.id, name: toolName, - isFailure: false, - result: { outputs: event.item.outputs }, + isFailure: status !== "completed", + result: { status, outputs: event.item.outputs ?? null }, providerExecuted: true }) break @@ -2244,15 +2434,16 @@ const makeStreamResponse = Effect.fnUntraced( case "file_search_call": { delete activeToolCalls[event.output_index] const toolName = toolNameMapper.getCustomName("file_search") - const results = Predicate.isNotNullish(event.item.results) - ? { results: event.item.results } - : undefined parts.push({ type: "tool-result", id: event.item.id, name: toolName, - isFailure: false, - result: { ...results, status: event.item.status, queries: event.item.queries }, + isFailure: event.item.status !== "completed", + result: { + status: event.item.status, + queries: event.item.queries, + results: event.item.results ?? null + }, providerExecuted: true }) break @@ -2279,7 +2470,6 @@ const makeStreamResponse = Effect.fnUntraced( method: "makeStreamResponse", reason: new AiError.ToolParameterValidationError({ toolName, - toolParams: {}, description: `Failed securely JSON parse tool parameters: ${cause}` }) }) @@ -2305,12 +2495,15 @@ const makeStreamResponse = Effect.fnUntraced( case "image_generation_call": { const toolName = toolNameMapper.getCustomName("image_generation") + const status = event.item.status ?? "completed" parts.push({ type: "tool-result", id: event.item.id, name: toolName, - isFailure: false, - result: { result: event.item.result }, + isFailure: status !== "completed", + result: status === "completed" + ? { result: event.item.result } + : { status, result: event.item.result }, providerExecuted: true }) break @@ -2355,7 +2548,7 @@ const makeStreamResponse = Effect.fnUntraced( type: "tool-result", id: toolId, name: toolName, - isFailure: false, + isFailure: Predicate.isNotNullish(event.item.error), providerExecuted: true, result: { type: "mcp_call", @@ -2455,7 +2648,7 @@ const makeStreamResponse = Effect.fnUntraced( type: "tool-call", id: event.item.id, name: toolName, - params: { action: event.item.action }, + params: Predicate.isUndefined(event.item.action) ? {} : { action: event.item.action }, providerExecuted: true }) } @@ -2463,8 +2656,11 @@ const makeStreamResponse = Effect.fnUntraced( type: "tool-result", id: event.item.id, name: toolName, - isFailure: false, - result: { action: event.item.action, status: event.item.status }, + isFailure: event.item.status !== "completed", + result: { + ...(Predicate.isUndefined(event.item.action) ? undefined : { action: event.item.action }), + status: event.item.status + }, providerExecuted: true }) break @@ -2582,7 +2778,6 @@ const makeStreamResponse = Effect.fnUntraced( method: "makeStreamResponse", reason: new AiError.ToolParameterValidationError({ toolName: toolCall.name, - toolParams: {}, description: `Failed securely JSON parse tool parameters: ${cause}` }) }) @@ -2648,37 +2843,21 @@ const makeStreamResponse = Effect.fnUntraced( case "response.code_interpreter_call_code.delta": { const toolCall = activeToolCalls[event.output_index] - if (Predicate.isNotUndefined(toolCall)) { + if (Predicate.isNotUndefined(toolCall?.codeInterpreter)) { parts.push({ type: "tool-params-delta", id: toolCall.id, - delta: InternalUtilities.escapeJSONDelta(event.delta) + delta: (toolCall.codeInterpreter.hasCode ? "" : "\"") + + InternalUtilities.escapeJSONDelta(event.delta) }) + toolCall.codeInterpreter.hasCode = true + toolCall.codeInterpreter.streamedCode += event.delta } break } case "response.code_interpreter_call_code.done": { - const toolCall = activeToolCalls[event.output_index] - if (Predicate.isNotUndefined(toolCall) && Predicate.isNotUndefined(toolCall.codeInterpreter)) { - const toolName = toolNameMapper.getCustomName("code_interpreter") - parts.push({ - type: "tool-params-delta", - id: toolCall.id, - delta: "\"}" - }) - parts.push({ type: "tool-params-end", id: toolCall.id }) - parts.push({ - type: "tool-call", - id: toolCall.id, - name: toolName, - params: { - code: event.code, - container_id: toolCall.codeInterpreter.containerId - }, - providerExecuted: true - }) - } + finishCodeInterpreterCall(event.output_index, event.code, parts) break } @@ -2745,9 +2924,9 @@ const makeStreamResponse = Effect.fnUntraced( case "response.reasoning_summary_part.done": { const reasoningPart = getOrCreateReasoningPart(event.item_id) - // When OpenAI stores message data, we can immediately conclude the - // reasoning part given that we do not need the encrypted content - if (config.store === true) { + // HTTP requests using stored item references do not need encrypted + // content, so the reasoning part can be concluded immediately. + if (!websocketMode && config.store === true && config.useItemReferences !== false) { parts.push({ type: "reasoning-end", id: `${event.item_id}:${event.summary_index}`, @@ -3236,7 +3415,6 @@ const normalizeMcpToolCall = Effect.fnUntraced(function* - ).pipe(Effect.mapError((error) => - AiError.make({ - module: "OpenAiLanguageModel", - method: "makeResponse", - reason: new AiError.ToolParameterValidationError({ - toolName, - toolParams, - description: formatIssue(error.issue) - }) - }) - )) + Schema.decodeEffect(codec)(toolParams) as Effect.Effect + ).pipe( + Effect.flatMap((decoded) => + Schema.encodeUnknownEffect(tool.parametersSchema)(decoded) as Effect.Effect + ), + Effect.orElseSucceed(() => toolParams) + ) }) diff --git a/packages/effect-ai-openai/src/OpenAiSchema.ts b/packages/effect-ai-openai/src/OpenAiSchema.ts index 055b3c2..c7cb60f 100644 --- a/packages/effect-ai-openai/src/OpenAiSchema.ts +++ b/packages/effect-ai-openai/src/OpenAiSchema.ts @@ -4,6 +4,7 @@ * the transport boundary for JSON sent to and decoded from the Responses and * embeddings endpoints. * + * @stability unstable * @since 4.0.0 */ import * as Effect from "effect/Effect" @@ -34,6 +35,7 @@ const PromptCacheBreakpoint = Schema.Struct({ * sources. This schema enumerates the include values supported by this client * path. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -48,6 +50,7 @@ export const IncludeEnum = Schema.Literals([ /** * Type of optional `include` values accepted by OpenAI Responses requests. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -61,6 +64,7 @@ export type IncludeEnum = typeof IncludeEnum.Type * Accepted values are `"in_progress"`, `"completed"`, and `"incomplete"`. * This item-level status is used by message, reasoning, and tool-call shapes. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -73,6 +77,7 @@ export const MessageStatus = Schema.Literals(["in_progress", "completed", "incom * * Accepted values are `"in_progress"`, `"completed"`, and `"incomplete"`. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -108,6 +113,7 @@ const InputFileContent = Schema.Struct({ * * @see {@link InputItem} for request input item shapes that can contain these content blocks * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -124,6 +130,7 @@ export const InputContent = Schema.Union([ * * Accepted block variants are `input_text`, `input_image`, and `input_file`. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -139,6 +146,7 @@ export type InputContent = typeof InputContent.Type * * @see {@link ReasoningItem} for reasoning output items that contain summary text blocks * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -150,6 +158,7 @@ export const SummaryTextContent = Schema.Struct({ /** * Text content block used for model-provided reasoning summaries. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -214,6 +223,7 @@ const FilePathAnnotation = Schema.Struct({ * Accepts annotation objects discriminated by `type`: `file_citation`, * `url_citation`, `container_file_citation`, or `file_path`. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -232,6 +242,7 @@ export const Annotation = Schema.Union([ * Accepted annotation variants are `file_citation`, `url_citation`, * `container_file_citation`, and `file_path`. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -285,6 +296,7 @@ const OutputMessage = Schema.Struct({ * @see {@link InputItem} for request input items that can carry reasoning items * @see {@link IncludeEnum} for requesting encrypted reasoning content * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -315,6 +327,7 @@ export const ReasoningItem = Schema.Struct({ * `encrypted_content` is populated only when `reasoning.encrypted_content` is * requested through `include`. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -401,6 +414,39 @@ const RequestMessageItem = Schema.Struct({ ]) }) +const InputCodeInterpreterCall = Schema.Struct({ + id: Schema.String, + type: Schema.Literal("code_interpreter_call"), + code: Schema.optionalKey(Schema.NullOr(Schema.String)), + container_id: Schema.String, + outputs: Schema.optionalKey(Schema.NullOr(Schema.Array(Schema.Unknown))), + status: Schema.optionalKey( + Schema.Literals(["in_progress", "completed", "incomplete", "interpreting", "failed"]) + ) +}) + +const InputFileSearchCall = Schema.Struct({ + id: Schema.String, + type: Schema.Literal("file_search_call"), + status: Schema.optionalKey(Schema.String), + queries: Schema.optionalKey(Schema.Array(Schema.String)), + results: Schema.optionalKey(Schema.NullOr(Schema.Unknown)) +}) + +const InputImageGenerationCall = Schema.Struct({ + id: Schema.String, + type: Schema.Literal("image_generation_call"), + result: Schema.optionalKey(Schema.NullOr(Schema.String)), + status: Schema.optionalKey(Schema.Literals(["in_progress", "completed", "generating", "failed"])) +}) + +const InputWebSearchCall = Schema.Struct({ + id: Schema.String, + type: Schema.Literal("web_search_call"), + action: Schema.optionalKey(Schema.Unknown), + status: Schema.optionalKey(Schema.String) +}) + /** * Schema for item shapes accepted by an OpenAI Responses request `input` field. * @@ -417,6 +463,7 @@ const RequestMessageItem = Schema.Struct({ * @see {@link CreateResponse} for the request schema that consumes input items * @see {@link InputContent} for content blocks inside message items * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -432,7 +479,11 @@ export const InputItem = Schema.Union([ ShellCall, ShellCallOutput, ApplyPatchCallOutput, - McpApprovalResponse + McpApprovalResponse, + InputCodeInterpreterCall, + InputFileSearchCall, + InputImageGenerationCall, + InputWebSearchCall ]) /** @@ -448,6 +499,7 @@ export const InputItem = Schema.Union([ * function call output, reasoning items, item references, shell and local shell * calls and outputs, apply-patch output, and MCP approval responses. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -509,6 +561,7 @@ const ProviderDefinedTool = Schema.StructWithRest( * @see {@link ToolChoice} for selecting whether and which tools the model may call * @see {@link CreateResponse} for the request schema that consumes tools * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -521,6 +574,7 @@ export const Tool = Schema.Union([ /** * Tool definition that can be supplied to an OpenAI Responses request. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -542,6 +596,7 @@ export type Tool = typeof Tool.Type * @see {@link Tool} for tool definitions referenced by tool choices * @see {@link CreateResponse} for the request schema that consumes `tool_choice` * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -586,6 +641,7 @@ export const ToolChoice = Schema.Union([ * Accepted forms are `"none"`, `"auto"`, `"required"`, an allowed-tools set, * a named function or custom tool, or a provider-defined tool choice. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -610,6 +666,7 @@ export type ToolChoice = typeof ToolChoice.Type * * @see {@link CreateResponse} for the request schema that consumes text format configuration * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -628,6 +685,7 @@ export const TextResponseFormatConfiguration = Schema.Union([ /** * Text output format configuration for plain text, JSON object, or JSON Schema responses. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -655,6 +713,7 @@ export type TextResponseFormatConfiguration = typeof TextResponseFormatConfigura * @see {@link Response} for decoded non-streaming response objects * @see {@link ResponseStreamEvent} for decoded streaming event objects * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -708,6 +767,7 @@ export const CreateResponse = Schema.Struct({ /** * Request options used to create an OpenAI Responses API response. * + * @stability unstable * @category options * @since 4.0.0 */ @@ -722,6 +782,7 @@ export type CreateResponse = typeof CreateResponse.Type * `total_tokens`. Provider-specific token detail objects are preserved through * `input_tokens_details`, `output_tokens_details`, and additional fields. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -744,6 +805,7 @@ export const ResponseUsage = Schema.StructWithRest( * Includes total input, output, and combined token counts, with provider-specific * token detail fields preserved when present. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -766,10 +828,12 @@ const ApplyPatchCall = Schema.Struct({ const CodeInterpreterCall = Schema.Struct({ id: Schema.String, type: Schema.Literal("code_interpreter_call"), - code: Schema.optionalKey(Schema.String), + code: Schema.optionalKey(Schema.NullOr(Schema.String)), container_id: Schema.String, - outputs: Schema.optionalKey(Schema.Array(Schema.Unknown)), - status: Schema.optionalKey(MessageStatus) + outputs: Schema.optionalKey(Schema.NullOr(Schema.Array(Schema.Unknown))), + status: Schema.optionalKey( + Schema.Literals(["in_progress", "completed", "incomplete", "interpreting", "failed"]) + ) }) const ComputerCall = Schema.Struct({ @@ -862,6 +926,7 @@ const ResponseError = Schema.Struct({ * @see {@link ResponseUsage} for token accounting on responses * @see {@link ResponseStreamEvent} for streaming response events * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -897,6 +962,7 @@ export const Response = Schema.Struct({ * Response objects include metadata, output items, optional token usage, and * optional incomplete details. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -905,38 +971,38 @@ export type Response = typeof Response.Type const ResponseCreatedEvent = Schema.Struct({ type: Schema.Literal("response.created"), response: Response, - sequence_number: Schema.Int + sequence_number: Schema.optionalKey(Schema.Int) }) const ResponseCompletedEvent = Schema.Struct({ type: Schema.Literal("response.completed"), response: Response, - sequence_number: Schema.Int + sequence_number: Schema.optionalKey(Schema.Int) }) const ResponseIncompleteEvent = Schema.Struct({ type: Schema.Literal("response.incomplete"), response: Response, - sequence_number: Schema.Int + sequence_number: Schema.optionalKey(Schema.Int) }) const ResponseFailedEvent = Schema.Struct({ type: Schema.Literal("response.failed"), response: Response, - sequence_number: Schema.Int + sequence_number: Schema.optionalKey(Schema.Int) }) const ResponseOutputItemAddedEvent = Schema.Struct({ type: Schema.Literal("response.output_item.added"), output_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), item: OutputItem }) const ResponseOutputItemDoneEvent = Schema.Struct({ type: Schema.Literal("response.output_item.done"), output_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), item: OutputItem }) @@ -946,7 +1012,7 @@ const ResponseOutputTextDeltaEvent = Schema.Struct({ output_index: Schema.Int, content_index: Schema.Int, delta: Schema.String, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), logprobs: Schema.optionalKey(Schema.Array(Schema.Unknown)) }) @@ -956,7 +1022,7 @@ const ResponseOutputTextAnnotationAddedEvent = Schema.Struct({ output_index: Schema.Int, content_index: Schema.Int, annotation_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), annotation: Annotation }) @@ -965,7 +1031,7 @@ const ResponseReasoningSummaryPartAddedEvent = Schema.Struct({ item_id: Schema.String, output_index: Schema.Int, summary_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), part: SummaryTextContent }) @@ -974,7 +1040,7 @@ const ResponseReasoningSummaryPartDoneEvent = Schema.Struct({ item_id: Schema.String, output_index: Schema.Int, summary_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), part: SummaryTextContent }) @@ -984,14 +1050,14 @@ const ResponseReasoningSummaryTextDeltaEvent = Schema.Struct({ output_index: Schema.Int, summary_index: Schema.Int, delta: Schema.String, - sequence_number: Schema.Int + sequence_number: Schema.optionalKey(Schema.Int) }) const ResponseFunctionCallArgumentsDeltaEvent = Schema.Struct({ type: Schema.Literal("response.function_call_arguments.delta"), item_id: Schema.String, output_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), delta: Schema.String }) @@ -999,7 +1065,7 @@ const ResponseFunctionCallArgumentsDoneEvent = Schema.Struct({ type: Schema.Literal("response.function_call_arguments.done"), item_id: Schema.String, output_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), arguments: Schema.String }) @@ -1007,7 +1073,7 @@ const ResponseCodeInterpreterCallCodeDeltaEvent = Schema.Struct({ type: Schema.Literal("response.code_interpreter_call_code.delta"), item_id: Schema.String, output_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), delta: Schema.String }) @@ -1015,7 +1081,7 @@ const ResponseCodeInterpreterCallCodeDoneEvent = Schema.Struct({ type: Schema.Literal("response.code_interpreter_call_code.done"), item_id: Schema.String, output_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), code: Schema.String }) @@ -1023,7 +1089,7 @@ const ResponseApplyPatchCallOperationDiffDeltaEvent = Schema.Struct({ type: Schema.Literal("response.apply_patch_call_operation_diff.delta"), item_id: Schema.String, output_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), delta: Schema.String }) @@ -1031,7 +1097,7 @@ const ResponseApplyPatchCallOperationDiffDoneEvent = Schema.Struct({ type: Schema.Literal("response.apply_patch_call_operation_diff.done"), item_id: Schema.String, output_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), delta: Schema.optionalKey(Schema.String) }) @@ -1039,7 +1105,7 @@ const ResponseImageGenerationCallPartialImageEvent = Schema.Struct({ type: Schema.Literal("response.image_generation_call.partial_image"), item_id: Schema.String, output_index: Schema.Int, - sequence_number: Schema.Int, + sequence_number: Schema.optionalKey(Schema.Int), partial_image_b64: Schema.String }) @@ -1104,6 +1170,7 @@ const knownResponseStreamEventTypes = new Set([ /** * Fallback event shape for future or provider-specific response stream events. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1144,6 +1211,7 @@ const UnknownResponseStreamEvent = Schema.declare( * @see {@link Response} for complete response objects carried by lifecycle events * @see {@link UnknownResponseStreamEvent} for the fallback shape for future event types * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1183,6 +1251,7 @@ export const ResponseStreamEvent = Schema.Union([ * Includes known response stream events plus a fallback shape for unknown future * event types. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1206,6 +1275,7 @@ export type ResponseStreamEvent = typeof ResponseStreamEvent.Type * Callers that need numeric vectors must account for string embeddings, such as * base64-encoded embeddings returned for string encoding formats. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1226,6 +1296,7 @@ export const Embedding = Schema.Struct({ * Contains the item index and embedding payload. The embedding payload may be a * numeric vector or a string. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1251,6 +1322,7 @@ export type Embedding = typeof Embedding.Type * provider-side constraints such as non-empty input, integer token ids, input * size limits, positive dimensions, and model-specific dimension support. * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1270,6 +1342,7 @@ export const CreateEmbeddingRequest = Schema.Struct({ /** * Request payload sent to the OpenAI embeddings endpoint. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -1298,6 +1371,7 @@ export type CreateEmbeddingRequest = typeof CreateEmbeddingRequest.Type * @see {@link CreateEmbeddingRequest} for the request schema sent to the embeddings endpoint * @see {@link Embedding} for individual embedding items in the response * + * @stability unstable * @category schemas * @since 4.0.0 */ @@ -1325,6 +1399,7 @@ export const CreateEmbeddingResponse = Schema.Struct({ * Contains embedding items, the model name, optional list marker, and optional * token usage counts. * + * @stability unstable * @category models * @since 4.0.0 */ diff --git a/packages/effect-ai-openai/src/OpenAiTelemetry.ts b/packages/effect-ai-openai/src/OpenAiTelemetry.ts index 3d80a9e..e459740 100644 --- a/packages/effect-ai-openai/src/OpenAiTelemetry.ts +++ b/packages/effect-ai-openai/src/OpenAiTelemetry.ts @@ -7,11 +7,11 @@ * * @since 4.0.0 */ +import * as Telemetry from "effect/ai/Telemetry" 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 diff --git a/packages/effect-ai-openai/src/OpenAiTool.ts b/packages/effect-ai-openai/src/OpenAiTool.ts index 7d80c57..b74dec8 100644 --- a/packages/effect-ai-openai/src/OpenAiTool.ts +++ b/packages/effect-ai-openai/src/OpenAiTool.ts @@ -5,15 +5,17 @@ * shell-like local tools, including their provider names, configuration * arguments, call parameters, success schemas, and handler requirements. * + * @stability unstable * @since 4.0.0 */ +import * as Tool from "effect/ai/Tool" 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. * + * @stability unstable * @category models * @since 4.0.0 */ @@ -39,6 +41,7 @@ export type OpenAiTool = * delete, or update operations that your application executes through a local * handler. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -67,10 +70,12 @@ export const ApplyPatch = Tool.providerDefined({ * * **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. + * The tool is configured with a `container` argument. Results include `status` + * and `outputs`: logs, generated images, or `null` when unavailable. A `completed` + * status indicates success; omitted statuses default to it. Other statuses + * produce failure results that preserve any outputs. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -86,6 +91,13 @@ export const CodeInterpreter = Tool.providerDefined({ container_id: Generated.CodeInterpreterToolCall.fields.container_id }), success: Schema.Struct({ + status: Schema.Literal("completed"), + outputs: Generated.CodeInterpreterToolCall.fields.outputs + }), + failure: Schema.Struct({ + status: Schema.Literals( + Generated.CodeInterpreterToolCall.fields.status.literals.filter((status) => status !== "completed") + ), outputs: Generated.CodeInterpreterToolCall.fields.outputs }) }) @@ -102,9 +114,12 @@ export const CodeInterpreter = Tool.providerDefined({ * **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`. + * `max_num_results`, and `ranking_options`. Results include `queries` and a + * required `results` field containing matches or `null`. Only `completed` is + * successful; all other statuses produce failure results, preserving partial + * matches. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -119,9 +134,16 @@ export const FileSearch = Tool.providerDefined({ vector_store_ids: Generated.FileSearchTool.fields.vector_store_ids }), success: Schema.Struct({ - status: Generated.FileSearchToolCall.fields.status, + status: Schema.Literal("completed"), + queries: Generated.FileSearchToolCall.fields.queries, + results: Generated.FileSearchToolCall.fields.results.schema + }), + failure: Schema.Struct({ + status: Schema.Literals( + Generated.FileSearchToolCall.fields.status.literals.filter((status) => status !== "completed") + ), queries: Generated.FileSearchToolCall.fields.queries, - results: Generated.FileSearchToolCall.fields.results + results: Generated.FileSearchToolCall.fields.results.schema }) }) @@ -138,9 +160,12 @@ export const FileSearch = Tool.providerDefined({ * * 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`. + * and partial image settings. Successful calls expose `result` as base64 image + * data or `null`. Partial images are preliminary success results. Final results + * with a status other than `completed` are failures that include `status`. + * Omitted statuses default to `completed`. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -162,6 +187,12 @@ export const ImageGeneration = Tool.providerDefined({ }), success: Schema.Struct({ result: Generated.ImageGenToolCall.fields.result + }), + failure: Schema.Struct({ + status: Schema.Literals( + Generated.ImageGenToolCall.fields.status.literals.filter((status) => status !== "completed") + ), + result: Generated.ImageGenToolCall.fields.result }) }) @@ -181,6 +212,7 @@ export const ImageGeneration = Tool.providerDefined({ * handler-required, so applications must provide the command execution policy * and implementation. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -197,6 +229,14 @@ export const LocalShell = Tool.providerDefined({ }) }) +const McpResultFields = { + type: Generated.MCPToolCall.fields.type, + name: Generated.MCPToolCall.fields.name, + arguments: Generated.MCPToolCall.fields.arguments, + output: Generated.MCPToolCall.fields.output, + server_label: Generated.MCPToolCall.fields.server_label +} + /** * Defines the OpenAI MCP tool that gives the model access to additional tools via remote * Model Context Protocol (MCP) servers. @@ -210,13 +250,15 @@ export const LocalShell = Tool.providerDefined({ * 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. + * and server label. Calls that report an `error` produce failure results that + * include it; successful results omit `error`. * * **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. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -234,13 +276,10 @@ export const Mcp = Tool.providerDefined({ 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 + success: Schema.Struct(McpResultFields), + failure: Schema.Struct({ + ...McpResultFields, + error: Schema.String }) }) @@ -258,6 +297,7 @@ export const Mcp = Tool.providerDefined({ * handler-required, so applications must provide the command execution policy * and implementation. * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -274,6 +314,16 @@ export const Shell = Tool.providerDefined({ }) }) +const WebSearchSuccess = Schema.Struct({ + action: Generated.WebSearchToolCall.fields.action, + status: Schema.Literal("completed") +}) + +const WebSearchFailure = Schema.Struct({ + action: Generated.WebSearchToolCall.fields.action, + status: Schema.Literals(Generated.WebSearchToolCall.fields.status.literals.filter((status) => status !== "completed")) +}) + /** * Defines the OpenAI Web Search tool that enables the model to search the web for * information. @@ -285,10 +335,14 @@ export const Shell = Tool.providerDefined({ * **Details** * * The tool accepts optional filters, user location, and search context size. - * Successful calls expose the performed search action and status. + * Results include status and, when available, action. Only `completed` succeeds; + * other statuses produce failure results. + * Narrow search sources by `type` to read `url` for URL sources or `name` + * for API sources. * * @see {@link WebSearchPreview} for the preview web search provider tool * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -304,10 +358,8 @@ export const WebSearch = Tool.providerDefined({ parameters: Schema.Struct({ action: Generated.WebSearchToolCall.fields.action }), - success: Schema.Struct({ - action: Generated.WebSearchToolCall.fields.action, - status: Generated.WebSearchToolCall.fields.status - }) + success: WebSearchSuccess, + failure: WebSearchFailure }) /** @@ -319,11 +371,15 @@ export const WebSearch = Tool.providerDefined({ * * **Details** * - * The preview tool accepts optional user location and search context size, then - * exposes the performed search action and status in successful calls. + * The preview tool accepts optional user location and search context size. + * Results include status and, when available, action. Only `completed` succeeds; + * other statuses produce failure results. + * Narrow search sources by `type` to read `url` for URL sources or `name` + * for API sources. * * @see {@link WebSearch} for the stable web search provider tool * + * @stability unstable * @category tools * @since 4.0.0 */ @@ -335,8 +391,6 @@ export const WebSearchPreview = Tool.providerDefined({ 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 - }) + success: WebSearchSuccess, + failure: WebSearchFailure }) diff --git a/packages/effect-ai-openai/src/index.ts b/packages/effect-ai-openai/src/index.ts index b1758b6..77389e3 100644 --- a/packages/effect-ai-openai/src/index.ts +++ b/packages/effect-ai-openai/src/index.ts @@ -5,16 +5,19 @@ // @barrel: Auto-generated exports. Do not edit manually. /** + * @stability unstable * @since 1.0.0 */ export * as Generated from "./Generated.ts" /** + * @stability unstable * @since 4.0.0 */ export * as OpenAiClient from "./OpenAiClient.ts" /** + * @stability unstable * @since 4.0.0 */ export * as OpenAiClientGenerated from "./OpenAiClientGenerated.ts" @@ -25,6 +28,7 @@ export * as OpenAiClientGenerated from "./OpenAiClientGenerated.ts" export * as OpenAiConfig from "./OpenAiConfig.ts" /** + * @stability unstable * @since 4.0.0 */ export * as OpenAiEmbeddingModel from "./OpenAiEmbeddingModel.ts" @@ -35,11 +39,13 @@ export * as OpenAiEmbeddingModel from "./OpenAiEmbeddingModel.ts" export * as OpenAiError from "./OpenAiError.ts" /** + * @stability unstable * @since 4.0.0 */ export * as OpenAiLanguageModel from "./OpenAiLanguageModel.ts" /** + * @stability unstable * @since 4.0.0 */ export * as OpenAiSchema from "./OpenAiSchema.ts" @@ -50,6 +56,7 @@ export * as OpenAiSchema from "./OpenAiSchema.ts" export * as OpenAiTelemetry from "./OpenAiTelemetry.ts" /** + * @stability unstable * @since 4.0.0 */ export * as OpenAiTool from "./OpenAiTool.ts" diff --git a/packages/effect-ai-openai/src/internal/errors.ts b/packages/effect-ai-openai/src/internal/errors.ts index fc93181..4e2ec36 100644 --- a/packages/effect-ai-openai/src/internal/errors.ts +++ b/packages/effect-ai-openai/src/internal/errors.ts @@ -1,17 +1,17 @@ +import * as AiError from "effect/ai/AiError" +import type * as Response from "effect/ai/Response" import * as Duration from "effect/Duration" import * as Effect from "effect/Effect" +import type * as Sse from "effect/encoding/Sse" import { dual } from "effect/Function" +import type * as HttpClientError from "effect/http/HttpClientError" +import type * as HttpClientRequest from "effect/http/HttpClientRequest" +import type * as HttpClientResponse from "effect/http/HttpClientResponse" 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 Sse from "effect/unstable/encoding/Sse" -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" // ============================================================================= diff --git a/packages/effect-ai-openai/src/internal/utilities.ts b/packages/effect-ai-openai/src/internal/utilities.ts index 26cf670..7651401 100644 --- a/packages/effect-ai-openai/src/internal/utilities.ts +++ b/packages/effect-ai-openai/src/internal/utilities.ts @@ -1,4 +1,4 @@ -import type * as Response from "effect/unstable/ai/Response" +import type * as Response from "effect/ai/Response" const finishReasonMap: Record = { content_filter: "content-filter", diff --git a/packages/effect-ai-openai/test/HumanlayerFork.test.ts b/packages/effect-ai-openai/test/HumanlayerFork.test.ts index 3a0825a..8445ac8 100644 --- a/packages/effect-ai-openai/test/HumanlayerFork.test.ts +++ b/packages/effect-ai-openai/test/HumanlayerFork.test.ts @@ -1,8 +1,8 @@ import { assert, describe, it } from '@effect/vitest' import { OpenAiClient, OpenAiLanguageModel, OpenAiSchema } from '@humanlayer/effect-ai-openai' import { Config, Effect, Layer, Predicate, Redacted, Schema } from 'effect' -import { LanguageModel, Prompt } from 'effect/unstable/ai' -import { FetchHttpClient } from 'effect/unstable/http' +import { LanguageModel, Prompt } from 'effect/ai' +import { FetchHttpClient } from 'effect/http' const OpenAiResponse = { id: 'resp_humanlayer_provider_test', diff --git a/packages/effect-branded-id/src/index.ts b/packages/effect-branded-id/src/index.ts index 567ad21..83e6f48 100644 --- a/packages/effect-branded-id/src/index.ts +++ b/packages/effect-branded-id/src/index.ts @@ -125,7 +125,10 @@ const defaultBrandName = (prefix: string): string => .join('')}Id` /** Build the branded schema plus static helpers for one (prefix, brand) pair. */ -const makeBrandedIdSchema = (prefix: string, brand: Name) => { +/** A brand name `Schema.brand` accepts: one literal name, not a union or the whole of `string`. */ +type SingleBrandName = Parameters>[0] + +const makeBrandedIdSchema = (prefix: string, brand: SingleBrandName) => { // Validation function that checks both prefix and CUID const isValid = (input: string): boolean => parseId(input, prefix) !== null @@ -148,7 +151,7 @@ const makeBrandedIdSchema = (prefix: string, brand: N }) // String -> check with filter -> brand - const base = Schema.String.check(idFilter).pipe(Schema.brand(brand)) + const base = Schema.String.check(idFilter).pipe(Schema.brand(brand)) // The schema's own branded Type. For any concrete brand this is exactly `BrandedId`; // annotating against the schema type keeps `create`/`is` provable without assertions. @@ -201,7 +204,10 @@ export function makeBrandedId, ): BrandedIdSchema export function makeBrandedId(prefix: Prefix): BrandedIdSchema> -export function makeBrandedId(prefix: string, options?: BrandedIdOptions): BrandedIdSchema { +export function makeBrandedId( + prefix: string, + options?: BrandedIdOptions, +): BrandedIdSchema { // Validate prefix at schema creation time if (!isValidPrefix(prefix)) { throw new Error( @@ -209,7 +215,11 @@ export function makeBrandedId(prefix: string, options?: BrandedIdOptions ) } - return makeBrandedIdSchema(prefix, options?.brand ?? defaultBrandName(prefix)) + // SAFETY: `Schema.brand` only labels the type and keeps no name at runtime. Each overload fixes `Name` to the + // one literal brand this computes: the given `brand`, or the name derived from the prefix. + // oxlint-disable-next-line typescript/consistent-type-assertions, automation/no-type-assertion + const brand = (options?.brand ?? defaultBrandName(prefix)) as SingleBrandName + return makeBrandedIdSchema(prefix, brand) } // --------------------------------------------------------------------------- diff --git a/packages/fold-agent/examples/ConfigAgent.ts b/packages/fold-agent/examples/ConfigAgent.ts index 4256e0a..06cc41e 100644 --- a/packages/fold-agent/examples/ConfigAgent.ts +++ b/packages/fold-agent/examples/ConfigAgent.ts @@ -11,7 +11,7 @@ import * as NodeServices from '@effect/platform-node/NodeServices' */ import { layerLiveIdFactory } from '@humanlayer/fold-core' import { Console, Effect, Layer } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { configInit, launchSession, loadFoldConfigOrNull, Photon } from '../src/index' diff --git a/packages/fold-agent/examples/SkillsFromDisk.ts b/packages/fold-agent/examples/SkillsFromDisk.ts index a68885c..33461b3 100644 --- a/packages/fold-agent/examples/SkillsFromDisk.ts +++ b/packages/fold-agent/examples/SkillsFromDisk.ts @@ -14,7 +14,7 @@ import { join } from 'node:path' import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { anthropicModel, defineAgent, skillTool, startSession } from '@humanlayer/fold-core' import { Console, Effect, Layer } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { skillsFromDisk } from '../src/index' diff --git a/packages/fold-agent/scripts/update-managed-binaries.ts b/packages/fold-agent/scripts/update-managed-binaries.ts index 09dc8c3..ee2781e 100644 --- a/packages/fold-agent/scripts/update-managed-binaries.ts +++ b/packages/fold-agent/scripts/update-managed-binaries.ts @@ -13,7 +13,7 @@ import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { Array as Arr, Duration, Effect, Schema } from 'effect' -import { FetchHttpClient, HttpClient, HttpClientResponse } from 'effect/unstable/http' +import { FetchHttpClient, HttpClient, HttpClientResponse } from 'effect/http' import { MANAGED_BINARY_PLATFORMS, managedBinaryRegistry } from '../src/Bin/Registry' diff --git a/packages/fold-agent/scripts/update-model-catalog.ts b/packages/fold-agent/scripts/update-model-catalog.ts index 265e9e5..140a0ef 100644 --- a/packages/fold-agent/scripts/update-model-catalog.ts +++ b/packages/fold-agent/scripts/update-model-catalog.ts @@ -14,7 +14,7 @@ import { fileURLToPath } from 'node:url' import * as NodeRuntime from '@effect/platform-node/NodeRuntime' import type { ModelCatalogEntry, ModelPricing } from '@humanlayer/fold-core' import { Array as Arr, Effect, Schema } from 'effect' -import { FetchHttpClient, HttpClient, HttpClientResponse } from 'effect/unstable/http' +import { FetchHttpClient, HttpClient, HttpClientResponse } from 'effect/http' import { decodeModelsDevModels, ModelsDevPayload } from '../src/Catalog/ModelsDevSchema' import { modelCatalogEntriesFromModelsDev } from '../src/Catalog/Normalize' diff --git a/packages/fold-agent/src/Bin/ManagedBinaries.ts b/packages/fold-agent/src/Bin/ManagedBinaries.ts index 10fb587..81a0394 100644 --- a/packages/fold-agent/src/Bin/ManagedBinaries.ts +++ b/packages/fold-agent/src/Bin/ManagedBinaries.ts @@ -24,8 +24,8 @@ import { createHash } from 'node:crypto' import { join } from 'node:path' import { Cache, Cause, Config, Context, Data, Duration, Effect, FileSystem, Layer, Option, Stream } from 'effect' -import { HttpClient, HttpClientResponse } from 'effect/unstable/http' -import { ChildProcess, ChildProcessSpawner } from 'effect/unstable/process' +import { HttpClient, HttpClientResponse } from 'effect/http' +import { ChildProcess, ChildProcessSpawner } from 'effect/process' import { managedBinaryRegistry, type ManagedBinaryAsset, type ManagedBinaryDefinition } from './Registry' @@ -151,7 +151,7 @@ const assetFileName = (url: string): string => { /** Read one optional environment value through `Config`; absent or empty reads as null. */ const readEnv = (name: string): Effect.Effect => - Config.option(Config.string(name)).pipe( + Config.option(Config.String(name)).pipe( Effect.map((value) => Option.getOrElse( Option.filter(value, (text) => text !== ''), diff --git a/packages/fold-agent/src/Catalog/LoadCatalog.ts b/packages/fold-agent/src/Catalog/LoadCatalog.ts index f957628..31e503a 100644 --- a/packages/fold-agent/src/Catalog/LoadCatalog.ts +++ b/packages/fold-agent/src/Catalog/LoadCatalog.ts @@ -15,7 +15,7 @@ import { dirname, join } from 'node:path' import { ModelCatalogEntry } from '@humanlayer/fold-core' import { Array as Arr, Clock, Duration, Effect, FileSystem, Schema } from 'effect' -import { HttpClient, HttpClientResponse } from 'effect/unstable/http' +import { HttpClient, HttpClientResponse } from 'effect/http' import { bakedModelCatalog } from './BakedCatalog' import { decodeModelsDevModels, ModelsDevDecodeError, ModelsDevPayload } from './ModelsDevSchema' diff --git a/packages/fold-agent/src/Config/AgentModels.ts b/packages/fold-agent/src/Config/AgentModels.ts index 5a339eb..a8519a0 100644 --- a/packages/fold-agent/src/Config/AgentModels.ts +++ b/packages/fold-agent/src/Config/AgentModels.ts @@ -19,7 +19,7 @@ import type { ActiveModel, ModelCatalogEntry, ReasoningLevel, FoldModel } from ' import { DEFAULT_OPENCODE_MODEL_ID, openCodeModel } from '@humanlayer/fold-opencode' import { DEFAULT_XAI_MODEL_ID, xaiModel } from '@humanlayer/fold-xai' import { Effect, type FileSystem, Match, Redacted, Schema } from 'effect' -import type { HttpClient } from 'effect/unstable/http' +import type { HttpClient } from 'effect/http' import { ConfigRole, type ProviderConnection, type RoleBinding, type FoldConfig } from './ConfigSchema' diff --git a/packages/fold-agent/src/Config/ModelSelections.ts b/packages/fold-agent/src/Config/ModelSelections.ts index 84e9117..5c4d2ff 100644 --- a/packages/fold-agent/src/Config/ModelSelections.ts +++ b/packages/fold-agent/src/Config/ModelSelections.ts @@ -3,7 +3,7 @@ import { DEFAULT_ANTHROPIC_MODEL_ID, type ModelCatalogEntry, type FoldModel } fr import { DEFAULT_OPENCODE_MODEL_ID, GROK_BUILD_MODEL_ID } from '@humanlayer/fold-opencode' import { DEFAULT_XAI_MODEL_ID, XAI_FRONTIER_MODELS } from '@humanlayer/fold-xai' import { Data, Effect, type FileSystem, Match, Predicate } from 'effect' -import type { HttpClient } from 'effect/unstable/http' +import type { HttpClient } from 'effect/http' import { agentModelsFromConfig, type AgentModelsOptions, RoleResolutionError } from './AgentModels' import type { ConfigRole, ProfileConfig, ProfileModeName, RoleBinding, FoldConfig } from './ConfigSchema' diff --git a/packages/fold-agent/src/Mode/Launch.ts b/packages/fold-agent/src/Mode/Launch.ts index 55a7cdd..7bc3450 100644 --- a/packages/fold-agent/src/Mode/Launch.ts +++ b/packages/fold-agent/src/Mode/Launch.ts @@ -49,8 +49,8 @@ import { type Scope, type Path, } from 'effect' -import type { HttpClient } from 'effect/unstable/http' -import type { ChildProcessSpawner } from 'effect/unstable/process' +import type { HttpClient } from 'effect/http' +import type { ChildProcessSpawner } from 'effect/process' import { loadModelCatalog } from '../Catalog/LoadCatalog' import { agentModelsFromConfig, type EnvLookup, type RoleResolutionError } from '../Config/AgentModels' diff --git a/packages/fold-agent/src/Mode/Mode.ts b/packages/fold-agent/src/Mode/Mode.ts index dfa9204..12b570b 100644 --- a/packages/fold-agent/src/Mode/Mode.ts +++ b/packages/fold-agent/src/Mode/Mode.ts @@ -13,8 +13,8 @@ */ import { skillTool, subagentTool, type FoldTool } from '@humanlayer/fold-core' import type { FileSystem, Path } from 'effect' -import type { HttpClient } from 'effect/unstable/http' -import type { ChildProcessSpawner } from 'effect/unstable/process' +import type { HttpClient } from 'effect/http' +import type { ChildProcessSpawner } from 'effect/process' import type { ConfigRole } from '../Config/ConfigSchema' import type { OutputStore } from '../OutputStore/OutputStore' diff --git a/packages/fold-agent/src/Mode/Rpi.ts b/packages/fold-agent/src/Mode/Rpi.ts index 805cd0a..6623412 100644 --- a/packages/fold-agent/src/Mode/Rpi.ts +++ b/packages/fold-agent/src/Mode/Rpi.ts @@ -25,8 +25,8 @@ */ import { defineSubagent, subagentTool, type SubagentDefinition } from '@humanlayer/fold-core' import type { FileSystem, Path } from 'effect' -import type { HttpClient } from 'effect/unstable/http' -import type { ChildProcessSpawner } from 'effect/unstable/process' +import type { HttpClient } from 'effect/http' +import type { ChildProcessSpawner } from 'effect/process' import type { OutputStore } from '../OutputStore/OutputStore' import { bashTool } from '../Tools/BashTool' diff --git a/packages/fold-agent/src/Mode/Subagents.ts b/packages/fold-agent/src/Mode/Subagents.ts index 52a6232..279deda 100644 --- a/packages/fold-agent/src/Mode/Subagents.ts +++ b/packages/fold-agent/src/Mode/Subagents.ts @@ -29,8 +29,8 @@ import { type FoldTool, } from '@humanlayer/fold-core' import type { FileSystem, Path } from 'effect' -import type { HttpClient } from 'effect/unstable/http' -import type { ChildProcessSpawner } from 'effect/unstable/process' +import type { HttpClient } from 'effect/http' +import type { ChildProcessSpawner } from 'effect/process' import type { OutputStore } from '../OutputStore/OutputStore' import { skillsFromDisk } from '../Skills/DiskSkills' diff --git a/packages/fold-agent/src/Session/TitleGenerator.ts b/packages/fold-agent/src/Session/TitleGenerator.ts index 8db7ec9..fad5935 100644 --- a/packages/fold-agent/src/Session/TitleGenerator.ts +++ b/packages/fold-agent/src/Session/TitleGenerator.ts @@ -1,7 +1,7 @@ import type { AssistantMessageLogEntry, LogEntry, FoldModel, UserMessageLogEntry } from '@humanlayer/fold-core' import { encodedContentText, languageModelLayerFor } from '@humanlayer/fold-core' import { Predicate, Effect, Schema, type Scope } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' +import { LanguageModel } from 'effect/ai' const TitleResult = Schema.Struct({ title: Schema.String }) const MAX_TRANSCRIPT_CHARS = 12_000 diff --git a/packages/fold-agent/src/Tools/BashTool.ts b/packages/fold-agent/src/Tools/BashTool.ts index 5a4f24f..3b24cd8 100644 --- a/packages/fold-agent/src/Tools/BashTool.ts +++ b/packages/fold-agent/src/Tools/BashTool.ts @@ -27,7 +27,7 @@ import { type FoldTool, } from '@humanlayer/fold-core' import { Data, Duration, Effect, Fiber, FileSystem, Option, Path, Ref, Schema, Semaphore, Stream } from 'effect' -import { ChildProcess, ChildProcessSpawner } from 'effect/unstable/process' +import { ChildProcess, ChildProcessSpawner } from 'effect/process' import { resolveToCwd } from '../Fs/PathResolve' import { OutputStore } from '../OutputStore/OutputStore' diff --git a/packages/fold-agent/src/Tools/CodingTools.ts b/packages/fold-agent/src/Tools/CodingTools.ts index b91670c..29c807f 100644 --- a/packages/fold-agent/src/Tools/CodingTools.ts +++ b/packages/fold-agent/src/Tools/CodingTools.ts @@ -7,8 +7,8 @@ import * as NodeServices from '@effect/platform-node/NodeServices' import type { FoldTool } from '@humanlayer/fold-core' import { type FileSystem, Layer, type Path } from 'effect' -import { FetchHttpClient, type HttpClient } from 'effect/unstable/http' -import type { ChildProcessSpawner } from 'effect/unstable/process' +import { FetchHttpClient, type HttpClient } from 'effect/http' +import type { ChildProcessSpawner } from 'effect/process' import { layerOutputStore, type OutputStore } from '../OutputStore/OutputStore' import { bashTool, type BashToolOptions } from './BashTool' diff --git a/packages/fold-agent/src/Tools/WebFetchTool.ts b/packages/fold-agent/src/Tools/WebFetchTool.ts index cd209b8..8eb8a95 100644 --- a/packages/fold-agent/src/Tools/WebFetchTool.ts +++ b/packages/fold-agent/src/Tools/WebFetchTool.ts @@ -10,8 +10,8 @@ import { type ToolResultSuccess, } from '@humanlayer/fold-core' import { Duration, Effect, Option, Schema, Stream } from 'effect' -import { Headers, HttpClient } from 'effect/unstable/http' -import type { HttpClientResponse } from 'effect/unstable/http' +import { Headers, HttpClient } from 'effect/http' +import type { HttpClientResponse } from 'effect/http' import TurndownService from 'turndown' import { detectSupportedImageMimeType, imageSniffBytes } from './Image/Mime' diff --git a/packages/fold-agent/src/Tools/WebSearchTool.ts b/packages/fold-agent/src/Tools/WebSearchTool.ts index 4186962..a1f49ab 100644 --- a/packages/fold-agent/src/Tools/WebSearchTool.ts +++ b/packages/fold-agent/src/Tools/WebSearchTool.ts @@ -7,7 +7,7 @@ import { type FoldTool, } from '@humanlayer/fold-core' import { Data, Duration, Effect, Option, Schema } from 'effect' -import { HttpClient, HttpClientRequest } from 'effect/unstable/http' +import { HttpClient, HttpClientRequest } from 'effect/http' const defaultTimeoutMs = 25_000 const maxNumResults = 20 diff --git a/packages/fold-agent/src/Tools/WebTools.ts b/packages/fold-agent/src/Tools/WebTools.ts index 4b6b276..bd74689 100644 --- a/packages/fold-agent/src/Tools/WebTools.ts +++ b/packages/fold-agent/src/Tools/WebTools.ts @@ -1,5 +1,5 @@ import type { FoldTool } from '@humanlayer/fold-core' -import type { HttpClient } from 'effect/unstable/http' +import type { HttpClient } from 'effect/http' import type { Photon } from './Image/Photon' import { webFetchTool } from './WebFetchTool' diff --git a/packages/fold-agent/test/Bin/ManagedBinaries.vi.test.ts b/packages/fold-agent/test/Bin/ManagedBinaries.vi.test.ts index 0126db9..0157bf0 100644 --- a/packages/fold-agent/test/Bin/ManagedBinaries.vi.test.ts +++ b/packages/fold-agent/test/Bin/ManagedBinaries.vi.test.ts @@ -11,8 +11,8 @@ import { dirname, join } from 'node:path' import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { expect, it } from '@effect/vitest' import { ConfigProvider, Effect, FileSystem, Layer, Sink, Stream } from 'effect' -import { HttpClient, HttpClientResponse } from 'effect/unstable/http' -import { ChildProcess, ChildProcessSpawner } from 'effect/unstable/process' +import { HttpClient, HttpClientResponse } from 'effect/http' +import { ChildProcess, ChildProcessSpawner } from 'effect/process' import { ensureManagedBinaries, diff --git a/packages/fold-agent/test/Catalog/LoadCatalog.vi.test.ts b/packages/fold-agent/test/Catalog/LoadCatalog.vi.test.ts index a3fe354..c8d7884 100644 --- a/packages/fold-agent/test/Catalog/LoadCatalog.vi.test.ts +++ b/packages/fold-agent/test/Catalog/LoadCatalog.vi.test.ts @@ -8,7 +8,7 @@ import { expect, it } from '@effect/vitest' import type { ModelCatalogEntry } from '@humanlayer/fold-core' import { Effect, FileSystem, Layer, Ref } from 'effect' -import { HttpClient, HttpClientResponse } from 'effect/unstable/http' +import { HttpClient, HttpClientResponse } from 'effect/http' import { bakedModelCatalog, loadModelCatalog, modelCatalogCachePath, FOLD_DISABLE_MODELS_FETCH } from '../../src/index' import { memoryFileSystem } from '../TestHelpers' diff --git a/packages/fold-agent/test/Codex/CodexImageReadDelivery.vi.test.ts b/packages/fold-agent/test/Codex/CodexImageReadDelivery.vi.test.ts index e581651..509742d 100644 --- a/packages/fold-agent/test/Codex/CodexImageReadDelivery.vi.test.ts +++ b/packages/fold-agent/test/Codex/CodexImageReadDelivery.vi.test.ts @@ -9,8 +9,9 @@ import { join } from 'node:path' import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { expect, it } from '@effect/vitest' import { CodexAuthStore, CodexTokenData, layerCodexAuthStore, makeCodexLanguageModel } from '@humanlayer/fold-codex' -import { Effect, Encoding, Layer, Schema } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { Effect, Layer, Schema } from 'effect' +import { Base64 } from 'effect/encoding' +import { FetchHttpClient } from 'effect/http' import { type CapturedFetchRequest, makeCapturingFetch, runImageReadInference } from './SessionModelPathTestHarness' @@ -89,7 +90,7 @@ it.effect('sends an actual image read as input_image with zero inference tools', expect(promptFileParts).toHaveLength(1) const promptImage = promptFileParts[0] if (!(promptImage?.data instanceof Uint8Array)) throw new Error('expected decoded image bytes') - expect(Encoding.encodeBase64(promptImage.data)).toBe(fixture.sourceImageBase64) + expect(Base64.encode(promptImage.data)).toBe(fixture.sourceImageBase64) // Text and image stay correlated in the native multipart function output. const functionOutput = body.input.find((item) => item['type'] === 'function_call_output') diff --git a/packages/fold-agent/test/Codex/CodexLive.vi.test.ts b/packages/fold-agent/test/Codex/CodexLive.vi.test.ts index 95a19cb..9fe3440 100644 --- a/packages/fold-agent/test/Codex/CodexLive.vi.test.ts +++ b/packages/fold-agent/test/Codex/CodexLive.vi.test.ts @@ -12,7 +12,7 @@ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { describe, expect, it } from '@effect/vitest' import { makeCodexLanguageModel } from '@humanlayer/fold-codex' import { Effect, Layer, Option, Schema, Stream } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { expectedImageIdentification, runImageReadInference } from './SessionModelPathTestHarness' diff --git a/packages/fold-agent/test/Codex/EffectToolResultEncodingRepro.vi.test.ts b/packages/fold-agent/test/Codex/EffectToolResultEncodingRepro.vi.test.ts index 9620eb8..498fafa 100644 --- a/packages/fold-agent/test/Codex/EffectToolResultEncodingRepro.vi.test.ts +++ b/packages/fold-agent/test/Codex/EffectToolResultEncodingRepro.vi.test.ts @@ -5,8 +5,8 @@ import { assert, it } from '@effect/vitest' */ import { OpenAiClient, OpenAiLanguageModel } from '@humanlayer/effect-ai-openai' import { Effect, Layer, Predicate, Redacted, Schema } from 'effect' -import { LanguageModel, Prompt } from 'effect/unstable/ai' -import { FetchHttpClient } from 'effect/unstable/http' +import { LanguageModel, Prompt } from 'effect/ai' +import { FetchHttpClient } from 'effect/http' import { type CapturedFetchRequest, makeCapturingFetch } from './SessionModelPathTestHarness' @@ -32,7 +32,7 @@ const CapturedRequest = Schema.Struct({ input: Schema.Array(Schema.Record(Schema.String, Schema.Unknown)), }) -it.live('passes strings through and emits multipart client tool results in Effect 4.0.0-rc.112', () => +it.live('passes strings through and emits multipart client tool results in Effect 4.0.0', () => Effect.gen(function* () { const stringResult = 'PLAIN_TEXT_SENTINEL\n' const multipartResult = [ diff --git a/packages/fold-agent/test/Codex/SessionModelPathTestHarness.ts b/packages/fold-agent/test/Codex/SessionModelPathTestHarness.ts index 77ebb21..60a878f 100644 --- a/packages/fold-agent/test/Codex/SessionModelPathTestHarness.ts +++ b/packages/fold-agent/test/Codex/SessionModelPathTestHarness.ts @@ -18,7 +18,7 @@ import { type ToolResultLogEntry, } from '@humanlayer/fold-core' import { Effect, Predicate, Schema, Stream } from 'effect' -import { type LanguageModel, type Prompt, Toolkit } from 'effect/unstable/ai' +import { type LanguageModel, type Prompt, Toolkit } from 'effect/ai' import { readTool } from '../../src/index' import { callTool, runHandler } from '../TestHelpers' @@ -264,7 +264,7 @@ export const makeImageReadPromptFixture = makeTemporaryTestDirectory('fold-image * Run the exact model-call shape used by AgentRuntime: session-built prompt, streaming, an explicitly * empty active toolkit, and tool-call resolution disabled for runtime-owned settlement. */ -export const runImageReadInference = (model: LanguageModel.Service) => +export const runImageReadInference = (model: LanguageModel.LanguageModel) => Effect.gen(function* () { const fixture = yield* makeImageReadPromptFixture const emptyToolkit = yield* Toolkit.empty diff --git a/packages/fold-agent/test/Codex/ToolResultFormattingIntegration.vi.test.ts b/packages/fold-agent/test/Codex/ToolResultFormattingIntegration.vi.test.ts index 21d0ece..ae14521 100644 --- a/packages/fold-agent/test/Codex/ToolResultFormattingIntegration.vi.test.ts +++ b/packages/fold-agent/test/Codex/ToolResultFormattingIntegration.vi.test.ts @@ -9,8 +9,8 @@ import { join } from 'node:path' import { assert, it } from '@effect/vitest' import { OpenAiClient, OpenAiLanguageModel } from '@humanlayer/effect-ai-openai' import { Effect, Layer, Redacted, Schema } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' -import { FetchHttpClient } from 'effect/unstable/http' +import { LanguageModel } from 'effect/ai' +import { FetchHttpClient } from 'effect/http' import { bashTool, editTool, readTool, writeTool } from '../../src/index' import { diff --git a/packages/fold-agent/test/Mode/Launch.vi.test.ts b/packages/fold-agent/test/Mode/Launch.vi.test.ts index 58fe583..ea28a9c 100644 --- a/packages/fold-agent/test/Mode/Launch.vi.test.ts +++ b/packages/fold-agent/test/Mode/Launch.vi.test.ts @@ -11,7 +11,7 @@ import * as NodeServices from '@effect/platform-node/NodeServices' import { expect, it } from '@effect/vitest' import { customModel, layerLiveIdFactory, type ActiveModel, type FoldModel } from '@humanlayer/fold-core' import { Effect, Layer, Predicate, Stream } from 'effect' -import { LanguageModel, type Response } from 'effect/unstable/ai' +import { LanguageModel, type Response } from 'effect/ai' import { DEFAULT_CODING_PROMPT, diff --git a/packages/fold-agent/test/Mode/Rlm.vi.test.ts b/packages/fold-agent/test/Mode/Rlm.vi.test.ts index 2babf8c..d400428 100644 --- a/packages/fold-agent/test/Mode/Rlm.vi.test.ts +++ b/packages/fold-agent/test/Mode/Rlm.vi.test.ts @@ -13,7 +13,7 @@ import { type FoldTool, } from '@humanlayer/fold-core' import { Effect, Stream } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' +import { LanguageModel } from 'effect/ai' import { defaultCodingMode, diff --git a/packages/fold-agent/test/Mode/Rpi.vi.test.ts b/packages/fold-agent/test/Mode/Rpi.vi.test.ts index c31bf39..0762553 100644 --- a/packages/fold-agent/test/Mode/Rpi.vi.test.ts +++ b/packages/fold-agent/test/Mode/Rpi.vi.test.ts @@ -16,7 +16,7 @@ import { type FoldTool, } from '@humanlayer/fold-core' import { Effect, Stream } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' +import { LanguageModel } from 'effect/ai' import { AST_GREP_OUTLINE_GUIDANCE, diff --git a/packages/fold-agent/test/Mode/Subagents.vi.test.ts b/packages/fold-agent/test/Mode/Subagents.vi.test.ts index 06bd2ca..2505582 100644 --- a/packages/fold-agent/test/Mode/Subagents.vi.test.ts +++ b/packages/fold-agent/test/Mode/Subagents.vi.test.ts @@ -15,7 +15,7 @@ import { type FoldTool, } from '@humanlayer/fold-core' import { Effect, Stream } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' +import { LanguageModel } from 'effect/ai' import { AST_GREP_OUTLINE_GUIDANCE, defaultCodingMode, defaultSubagents, type ModeModels } from '../../src/index' diff --git a/packages/fold-agent/test/Session/SessionLayout.vi.test.ts b/packages/fold-agent/test/Session/SessionLayout.vi.test.ts index 7db076f..7536c28 100644 --- a/packages/fold-agent/test/Session/SessionLayout.vi.test.ts +++ b/packages/fold-agent/test/Session/SessionLayout.vi.test.ts @@ -12,7 +12,7 @@ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { expect, it } from '@effect/vitest' import { customModel, defineAgent, layerLiveIdFactory, SessionId, startSession } from '@humanlayer/fold-core' import { Effect, Predicate, Stream } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' +import { LanguageModel } from 'effect/ai' import { latestSessionLog, diff --git a/packages/fold-agent/test/Session/TitleGenerator.vi.test.ts b/packages/fold-agent/test/Session/TitleGenerator.vi.test.ts index d30ca69..d9555b2 100644 --- a/packages/fold-agent/test/Session/TitleGenerator.vi.test.ts +++ b/packages/fold-agent/test/Session/TitleGenerator.vi.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from '@effect/vitest' import { AgentId, customModel, EventId, MessageId, type LogEntry } from '@humanlayer/fold-core' import { Effect, Stream } from 'effect' -import { LanguageModel, type Response } from 'effect/unstable/ai' +import { LanguageModel, type Response } from 'effect/ai' import { fallbackSessionTitle, diff --git a/packages/fold-agent/test/TestHelpers.ts b/packages/fold-agent/test/TestHelpers.ts index 19c7adb..655a93f 100644 --- a/packages/fold-agent/test/TestHelpers.ts +++ b/packages/fold-agent/test/TestHelpers.ts @@ -25,8 +25,8 @@ import { type FoldTool, } from '@humanlayer/fold-core' import { Effect, FileSystem, Layer, type Path, PlatformError, Ref, Schema, type Scope } from 'effect' -import { HttpClient, HttpClientError } from 'effect/unstable/http' -import type { ChildProcessSpawner } from 'effect/unstable/process' +import { HttpClient, HttpClientError } from 'effect/http' +import type { ChildProcessSpawner } from 'effect/process' import { layerOutputStore, type OutputStore } from '../src/OutputStore/OutputStore' import { Photon } from '../src/Tools/Image/Photon' diff --git a/packages/fold-agent/test/Tools/BashTool.vi.test.ts b/packages/fold-agent/test/Tools/BashTool.vi.test.ts index 3849419..ba36d4e 100644 --- a/packages/fold-agent/test/Tools/BashTool.vi.test.ts +++ b/packages/fold-agent/test/Tools/BashTool.vi.test.ts @@ -9,7 +9,7 @@ import { join } from 'node:path' import { expect, it } from '@effect/vitest' import { Duration, Effect, Fiber } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { bashTool, codingTools, decodeBashOutputDelta } from '../../src/index' import { handlerOf, makeAmbientServices, messageOf, outputOf, runHandler, tempDir } from '../TestHelpers' diff --git a/packages/fold-agent/test/Tools/WebFetchTool.vi.test.ts b/packages/fold-agent/test/Tools/WebFetchTool.vi.test.ts index 0cf57e8..3cd766e 100644 --- a/packages/fold-agent/test/Tools/WebFetchTool.vi.test.ts +++ b/packages/fold-agent/test/Tools/WebFetchTool.vi.test.ts @@ -11,7 +11,7 @@ import { it } from '@effect/vitest' import { ToolResultMultipart, ToolResultText } from '@humanlayer/fold-core' import { Effect, Schema } from 'effect' import { constVoid } from 'effect/Function' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { afterAll, beforeAll, expect } from 'vitest' import { webFetchTool } from '../../src/index' diff --git a/packages/fold-agent/test/Tools/WebTimeouts.vi.test.ts b/packages/fold-agent/test/Tools/WebTimeouts.vi.test.ts index 51d9ced..97a8d05 100644 --- a/packages/fold-agent/test/Tools/WebTimeouts.vi.test.ts +++ b/packages/fold-agent/test/Tools/WebTimeouts.vi.test.ts @@ -1,8 +1,8 @@ import { it } from '@effect/vitest' import { webFetchToolContract, webSearchToolContract, type FoldTool } from '@humanlayer/fold-core' import { Effect, Fiber, Layer, Schema } from 'effect' +import { FetchHttpClient, type HttpClient } from 'effect/http' import { TestClock } from 'effect/testing' -import { FetchHttpClient, type HttpClient } from 'effect/unstable/http' import { expect } from 'vitest' import type { Photon } from '../../src/Tools/Image/Photon' diff --git a/packages/fold-cli/src/Commands.ts b/packages/fold-cli/src/Commands.ts index 1fa24db..feb415d 100644 --- a/packages/fold-cli/src/Commands.ts +++ b/packages/fold-cli/src/Commands.ts @@ -46,7 +46,7 @@ import { type XaiAuthOptions, } from '@humanlayer/fold-xai' import { Array as Arr, Clock, Console, Effect, Layer, Match, Option, Schema } from 'effect' -import { type CliError, Command, Flag } from 'effect/unstable/cli' +import { type CliError, Command, Flag } from 'effect/cli' import { jsonOutputRenderer, promptOutputRenderer, type JsonOutputMode } from './Renderer' import { ResumeTarget, runPrompt, type CliSessionOptions } from './Run' @@ -120,16 +120,16 @@ export const parseResumeFlag = (raw: string): Effect.Effect - Flag.string(name).pipe(Flag.withDescription(description), Flag.optional) + Flag.String(name).pipe(Flag.withDescription(description), Flag.optional) const optionalChoice = >( name: string, choices: Choices, description: string, -) => Flag.choice(name, choices).pipe(Flag.withDescription(description), Flag.optional) +) => Flag.Literals(name, choices).pipe(Flag.withDescription(description), Flag.optional) const optionalInteger = (name: string, description: string) => - Flag.integer(name).pipe(Flag.withDescription(description), Flag.optional) + Flag.Int(name).pipe(Flag.withDescription(description), Flag.optional) const codexLoginFlow = optionalChoice( 'flow', @@ -149,7 +149,7 @@ const commonFlags = { FOLD_MODE_NAMES, 'Agent mode: default (full coding toolset) or rlm (orchestrator that delegates to subagents)', ), - rpi: Flag.boolean('rpi').pipe( + rpi: Flag.Boolean('rpi').pipe( Flag.withDescription('Add the RPI specialist subagents (composable with any --mode)'), ), reasoning: optionalChoice( @@ -158,22 +158,22 @@ const commonFlags = { 'Reasoning level override', ), cwd: optionalString('cwd', 'Project working directory (defaults to process.cwd())'), - foldHome: Flag.string('fold-home').pipe( + foldHome: Flag.String('fold-home').pipe( Flag.withDescription('Fold home directory (defaults to ~/.fold)'), Flag.optional, ), - noColor: Flag.boolean('no-color').pipe(Flag.withDescription('Disable ANSI colors')), - verbose: Flag.boolean('verbose').pipe(Flag.withDescription('Stream full tool output/progress')), + noColor: Flag.Boolean('no-color').pipe(Flag.withDescription('Disable ANSI colors')), + verbose: Flag.Boolean('verbose').pipe(Flag.withDescription('Stream full tool output/progress')), output: optionalChoice( 'output', ['human', 'json', 'json-concise', 'json-verbose'] as const, 'Output format: human (default), json/json-concise (durable log rows), or json-verbose (rows + deltas)', ), - outputJson: Flag.boolean('output-json').pipe( + outputJson: Flag.Boolean('output-json').pipe( Flag.withDescription('Alias for --output json (newline-delimited durable log rows on stdout)'), ), - autoCompact: Flag.boolean('auto-compact').pipe(Flag.withDescription('Enable auto-compaction for this session')), - disableAutoCompact: Flag.boolean('disable-auto-compact').pipe( + autoCompact: Flag.Boolean('auto-compact').pipe(Flag.withDescription('Enable auto-compaction for this session')), + disableAutoCompact: Flag.Boolean('disable-auto-compact').pipe( Flag.withDescription('Disable auto-compaction even when config enables it'), ), compactionThreshold: optionalInteger('compaction-threshold', 'Context usage in tokens that triggers compaction'), @@ -518,13 +518,13 @@ const config = Command.make('config').pipe( Command.make( 'add', { - name: Flag.string('name').pipe( + name: Flag.String('name').pipe( Flag.withDescription('Provider profile name used by --provider'), ), - kind: Flag.choice('kind', ['anthropic', 'openai-compat'] as const).pipe( + kind: Flag.Literals('kind', ['anthropic', 'openai-compat'] as const).pipe( Flag.withDescription('Compatible API protocol'), ), - baseUrl: Flag.string('base-url').pipe(Flag.withDescription('Provider API base URL')), + baseUrl: Flag.String('base-url').pipe(Flag.withDescription('Provider API base URL')), apiKey: optionalString( 'api-key', 'Inline API key (visible in process arguments; prefer --api-key-env)', @@ -631,7 +631,7 @@ const openCodeCommands = Command.make('opencode').pipe( { provider: commonFlags.provider, foldHome: commonFlags.foldHome, - noOpen: Flag.boolean('no-open').pipe( + noOpen: Flag.Boolean('no-open').pipe( Flag.withDescription('Print the device authorization URL without opening it'), ), }, @@ -642,7 +642,7 @@ const openCodeCommands = Command.make('opencode').pipe( { provider: commonFlags.provider, foldHome: commonFlags.foldHome, - noOpen: Flag.boolean('no-open').pipe( + noOpen: Flag.Boolean('no-open').pipe( Flag.withDescription('Print the device authorization URL without opening it'), ), }, @@ -719,7 +719,7 @@ const xaiExplicitLoginCommand = (name: ResolvedCodexLoginFlow) => { provider: commonFlags.provider, foldHome: commonFlags.foldHome, - noOpen: Flag.boolean('no-open').pipe( + noOpen: Flag.Boolean('no-open').pipe( Flag.withDescription('Print the authorization URL without opening it'), ), }, @@ -734,7 +734,7 @@ const xaiCommands = Command.make('xai').pipe( { provider: commonFlags.provider, foldHome: commonFlags.foldHome, - noOpen: Flag.boolean('no-open').pipe( + noOpen: Flag.Boolean('no-open').pipe( Flag.withDescription('Print the authorization URL without opening it'), ), }, @@ -792,15 +792,15 @@ const auth = Command.make('auth').pipe( provider: commonFlags.provider, foldHome: commonFlags.foldHome, flow: codexLoginFlow, - device: Flag.boolean('device').pipe( + device: Flag.Boolean('device').pipe( Flag.withDescription('Use the headless device-code flow (legacy alias for --flow device)'), ), - browser: Flag.boolean('browser').pipe( + browser: Flag.Boolean('browser').pipe( Flag.withDescription( 'Use the loopback browser PKCE flow (legacy alias for --flow browser)', ), ), - noOpen: Flag.boolean('no-open').pipe( + noOpen: Flag.Boolean('no-open').pipe( Flag.withDescription('Print the browser authorization URL without opening it'), ), }, @@ -863,7 +863,7 @@ const auth = Command.make('auth').pipe( { provider: commonFlags.provider, foldHome: commonFlags.foldHome, - refresh: Flag.boolean('refresh').pipe( + refresh: Flag.Boolean('refresh').pipe( Flag.withDescription('Refresh an expired credential and persist the repaired token'), ), }, diff --git a/packages/fold-cli/src/Run.ts b/packages/fold-cli/src/Run.ts index 29e42fa..0dadc68 100644 --- a/packages/fold-cli/src/Run.ts +++ b/packages/fold-cli/src/Run.ts @@ -45,8 +45,8 @@ import { Stream, type Scope, } from 'effect' -import type { HttpClient } from 'effect/unstable/http' -import type { ChildProcessSpawner } from 'effect/unstable/process' +import type { HttpClient } from 'effect/http' +import type { ChildProcessSpawner } from 'effect/process' import { CredentialSummary, type OutputRenderer, type ResumeCommandFlag, type SessionHeader } from './Renderer' diff --git a/packages/fold-cli/src/cli.ts b/packages/fold-cli/src/cli.ts index fde4e5d..94e63da 100644 --- a/packages/fold-cli/src/cli.ts +++ b/packages/fold-cli/src/cli.ts @@ -4,7 +4,7 @@ import * as NodeServices from '@effect/platform-node/NodeServices' import { ManagedBinaries, Photon } from '@humanlayer/fold-agent' import { layerLiveIdFactory } from '@humanlayer/fold-core' import { Effect, Layer } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { main } from './Commands' diff --git a/packages/fold-cli/src/tui/HostedTuiSession.ts b/packages/fold-cli/src/tui/HostedTuiSession.ts index 87373cc..34bceb5 100644 --- a/packages/fold-cli/src/tui/HostedTuiSession.ts +++ b/packages/fold-cli/src/tui/HostedTuiSession.ts @@ -10,8 +10,8 @@ import { } from '@humanlayer/fold-agent' import { renderSkillContent, type FoldSession, type ModelCatalogEntry, type SessionId } from '@humanlayer/fold-core' import { Cause, Duration, Effect, type FileSystem, Layer, type Path, type Scope, Stream } from 'effect' -import { FetchHttpClient, type HttpClient } from 'effect/unstable/http' -import type { ChildProcessSpawner } from 'effect/unstable/process' +import { FetchHttpClient, type HttpClient } from 'effect/http' +import type { ChildProcessSpawner } from 'effect/process' import { batch, createSignal, type Accessor } from 'solid-js' import { createStore, reconcile } from 'solid-js/store' diff --git a/packages/fold-cli/src/tui/Shell.tsx b/packages/fold-cli/src/tui/Shell.tsx index 94b2cfa..05c2420 100644 --- a/packages/fold-cli/src/tui/Shell.tsx +++ b/packages/fold-cli/src/tui/Shell.tsx @@ -23,7 +23,7 @@ import { layerXaiAuth, layerXaiAuthStore, XaiAuth, XaiAuthStore } from '@humanla import { createCliRenderer } from '@opentui/core' import { render } from '@opentui/solid' import { Cause, Clock, Deferred, Effect, type FileSystem, Layer, Option, Schema, type Scope } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { batch, createEffect, createSignal, Show, type Accessor } from 'solid-js' import { TuiApp } from './App' diff --git a/packages/fold-cli/src/tui/TuiSessionWorkspace.ts b/packages/fold-cli/src/tui/TuiSessionWorkspace.ts index 439ce2a..2f6a26d 100644 --- a/packages/fold-cli/src/tui/TuiSessionWorkspace.ts +++ b/packages/fold-cli/src/tui/TuiSessionWorkspace.ts @@ -18,8 +18,8 @@ import { } from '@humanlayer/fold-agent' import { layerLiveIdFactory, lookupCatalogEntry, type FoldSession, type SessionId } from '@humanlayer/fold-core' import { Cause, Duration, Effect, type FileSystem, Layer, Match, Option, type Path, Scope } from 'effect' -import { FetchHttpClient, type HttpClient } from 'effect/unstable/http' -import type { ChildProcessSpawner } from 'effect/unstable/process' +import { FetchHttpClient, type HttpClient } from 'effect/http' +import type { ChildProcessSpawner } from 'effect/process' import { createSignal, type Accessor } from 'solid-js' import { contextUsedPercentForDisplay, contextWindowLimitForDisplay } from '../ContextWindow' diff --git a/packages/fold-codex/src/CodexAuth.ts b/packages/fold-codex/src/CodexAuth.ts index ad892a5..feb929d 100644 --- a/packages/fold-codex/src/CodexAuth.ts +++ b/packages/fold-codex/src/CodexAuth.ts @@ -13,7 +13,7 @@ import { arch, platform, release } from 'node:os' import * as NodeCrypto from '@effect/platform-node/NodeCrypto' import { Clock, Context, Effect, Layer, Option, Semaphore } from 'effect' -import { HttpClient, HttpClientError, HttpClientRequest } from 'effect/unstable/http' +import { HttpClient, HttpClientError, HttpClientRequest } from 'effect/http' import { CodexAuthStore, type CodexAuthStoreError, type CodexTokenData } from './AuthStore' import type { BrowserFlowOptions, DeviceCodePrompt } from './OAuthFlows' diff --git a/packages/fold-codex/src/CodexModel.ts b/packages/fold-codex/src/CodexModel.ts index da19162..fc31e0b 100644 --- a/packages/fold-codex/src/CodexModel.ts +++ b/packages/fold-codex/src/CodexModel.ts @@ -19,9 +19,9 @@ import { customModel, resolveCodexReasoning } from '@humanlayer/fold-core' import type { ReasoningLevel, FoldModel } from '@humanlayer/fold-core' import { Array as Arr, Match, Context, Duration, Effect, Layer, Option, Schedule, Schema, Stream } from 'effect' import type { FileSystem, Scope } from 'effect' -import { AiError, LanguageModel } from 'effect/unstable/ai' -import { HttpClient } from 'effect/unstable/http' -import type { HttpClientResponse } from 'effect/unstable/http' +import { AiError, LanguageModel } from 'effect/ai' +import { HttpClient } from 'effect/http' +import type { HttpClientResponse } from 'effect/http' import { layerCodexAuthStore, type CodexAuthStoreOptions } from './AuthStore' import type { CodexIdentityOptions } from './CodexAuth' @@ -271,7 +271,7 @@ const authLayerFor = (options: CodexModelOptions) => */ export const makeCodexLanguageModel = ( options: CodexModelOptions, -): Effect.Effect => +): Effect.Effect => Layer.build( Layer.effect( LanguageModel.LanguageModel, diff --git a/packages/fold-codex/src/Hardening.ts b/packages/fold-codex/src/Hardening.ts index e9e81cd..6073384 100644 --- a/packages/fold-codex/src/Hardening.ts +++ b/packages/fold-codex/src/Hardening.ts @@ -10,7 +10,7 @@ * when one arrives, so consumer-side processing time never counts against the stream. */ import { Data, Duration, Effect, Match, Option, Random, Stream } from 'effect' -import { AiError } from 'effect/unstable/ai' +import { AiError } from 'effect/ai' /** `AiError.module` value marking errors minted by this package. */ export const CODEX_ERROR_MODULE = 'fold-codex' diff --git a/packages/fold-codex/src/OAuthFlows.ts b/packages/fold-codex/src/OAuthFlows.ts index 0ce1c4c..ddf5a50 100644 --- a/packages/fold-codex/src/OAuthFlows.ts +++ b/packages/fold-codex/src/OAuthFlows.ts @@ -8,8 +8,9 @@ import { createServer } from 'node:http' import type { Server } from 'node:http' -import { Clock, Crypto, Deferred, Duration, Effect, Encoding, Option, Result, Schedule, Schema } from 'effect' -import { HttpClient, HttpClientRequest, HttpClientResponse } from 'effect/unstable/http' +import { Clock, Crypto, Deferred, Duration, Effect, Option, Result, Schedule, Schema } from 'effect' +import { Base64Url } from 'effect/encoding' +import { HttpClient, HttpClientRequest, HttpClientResponse } from 'effect/http' import { CodexTokenData } from './AuthStore' @@ -101,7 +102,7 @@ const decodeJwtPayload = (token: string): Option.Option => { const payload = parts[1] if (payload === undefined) return Option.none() - return Option.fromNullishOr(Result.getOrUndefined(Encoding.decodeBase64UrlString(payload))) + return Option.fromNullishOr(Result.getOrUndefined(Base64Url.decodeString(payload))) } /** Best-effort JWT claim parse - malformed tokens are `none`, never failures. */ diff --git a/packages/fold-codex/test/CodexAuth.vi.test.ts b/packages/fold-codex/test/CodexAuth.vi.test.ts index 7ce7db6..854f3b1 100644 --- a/packages/fold-codex/test/CodexAuth.vi.test.ts +++ b/packages/fold-codex/test/CodexAuth.vi.test.ts @@ -5,7 +5,7 @@ import { join } from 'node:path' import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { describe, expect, it } from '@effect/vitest' import { Effect, Layer, Option, Predicate } from 'effect' -import { FetchHttpClient, type HttpClient } from 'effect/unstable/http' +import { FetchHttpClient, type HttpClient } from 'effect/http' import { CodexAuth, diff --git a/packages/fold-codex/test/CodexModel.vi.test.ts b/packages/fold-codex/test/CodexModel.vi.test.ts index b7cb93d..ff60127 100644 --- a/packages/fold-codex/test/CodexModel.vi.test.ts +++ b/packages/fold-codex/test/CodexModel.vi.test.ts @@ -2,9 +2,9 @@ import { describe, expect, it } from '@effect/vitest' import type { OpenAiClient } from '@humanlayer/effect-ai-openai' import type * as OpenAiSchema from '@humanlayer/effect-ai-openai/OpenAiSchema' import { Context, Deferred, Duration, Effect, Fiber, Layer, Ref, Stream } from 'effect' +import { AiError } from 'effect/ai' +import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse } from 'effect/http' import { TestClock } from 'effect/testing' -import { AiError } from 'effect/unstable/ai' -import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse } from 'effect/unstable/http' import { codexModel, diff --git a/packages/fold-codex/test/CodexModelCredentials.vi.test.ts b/packages/fold-codex/test/CodexModelCredentials.vi.test.ts index ad67df8..886da7d 100644 --- a/packages/fold-codex/test/CodexModelCredentials.vi.test.ts +++ b/packages/fold-codex/test/CodexModelCredentials.vi.test.ts @@ -9,7 +9,7 @@ import { join } from 'node:path' import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { expect, it } from '@effect/vitest' import { Effect, Layer, Predicate } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { CodexAuthStore, CodexTokenData, layerCodexAuthStore, makeCodexLanguageModel } from '../src/index' diff --git a/packages/fold-codex/test/Hardening.vi.test.ts b/packages/fold-codex/test/Hardening.vi.test.ts index c400f9f..b008255 100644 --- a/packages/fold-codex/test/Hardening.vi.test.ts +++ b/packages/fold-codex/test/Hardening.vi.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from '@effect/vitest' import { Deferred, Duration, Effect, Fiber, Option, Predicate, Stream } from 'effect' +import { AiError } from 'effect/ai' import { TestClock } from 'effect/testing' -import { AiError } from 'effect/unstable/ai' import { firstEventRetryDelayMs, hardenCodexStream, withStallTimeouts } from '../src/index' import type { CodexRetryOptions, StreamRetryInfo } from '../src/index' diff --git a/packages/fold-core/examples/AnthropicAgent.ts b/packages/fold-core/examples/AnthropicAgent.ts index 08cee61..7732702 100644 --- a/packages/fold-core/examples/AnthropicAgent.ts +++ b/packages/fold-core/examples/AnthropicAgent.ts @@ -7,7 +7,7 @@ * Run: ANTHROPIC_API_KEY=... bun packages/fold-core/examples/AnthropicAgent.ts */ import { Console, Effect, Schema } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { anthropicModel, defineAgent, defineTool, startSession } from '../src/index' diff --git a/packages/fold-core/examples/AutoCompactAgent.ts b/packages/fold-core/examples/AutoCompactAgent.ts index 8f4d316..21726d8 100644 --- a/packages/fold-core/examples/AutoCompactAgent.ts +++ b/packages/fold-core/examples/AutoCompactAgent.ts @@ -11,7 +11,7 @@ * Run: OPENAI_API_KEY=... bun packages/fold-core/examples/AutoCompactAgent.ts */ import { Predicate, Console, Effect } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { defineAgent, openaiModel, startSession, type CompactionLogEntry } from '../src/index' diff --git a/packages/fold-core/examples/ModelSwitch.ts b/packages/fold-core/examples/ModelSwitch.ts index 5b17380..ad9e793 100644 --- a/packages/fold-core/examples/ModelSwitch.ts +++ b/packages/fold-core/examples/ModelSwitch.ts @@ -11,7 +11,7 @@ * Run: OPENAI_API_KEY=... ANTHROPIC_API_KEY=... bun packages/fold-core/examples/ModelSwitch.ts */ import { Console, Effect, Schema } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { anthropicModel, defineAgent, defineTool, openaiModel, startSession } from '../src/index' diff --git a/packages/fold-core/examples/OpenaiAgent.ts b/packages/fold-core/examples/OpenaiAgent.ts index e3fe044..011a98e 100644 --- a/packages/fold-core/examples/OpenaiAgent.ts +++ b/packages/fold-core/examples/OpenaiAgent.ts @@ -6,7 +6,7 @@ * Run: OPENAI_API_KEY=... bun packages/fold-core/examples/OpenaiAgent.ts */ import { Console, Effect, Schema } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { defineAgent, defineTool, openaiModel, startSession } from '../src/index' diff --git a/packages/fold-core/examples/SkillsAgent.ts b/packages/fold-core/examples/SkillsAgent.ts index d43587c..e53e11c 100644 --- a/packages/fold-core/examples/SkillsAgent.ts +++ b/packages/fold-core/examples/SkillsAgent.ts @@ -8,7 +8,7 @@ * Run: ANTHROPIC_API_KEY=... bun packages/fold-core/examples/SkillsAgent.ts */ import { Console, Effect } from 'effect' -import { FetchHttpClient } from 'effect/unstable/http' +import { FetchHttpClient } from 'effect/http' import { anthropicModel, defineAgent, skillsFromData, skillTool, startSession } from '../src/index' diff --git a/packages/fold-core/src/AgentRuntime/AgentRuntimeLayer.ts b/packages/fold-core/src/AgentRuntime/AgentRuntimeLayer.ts index c89046a..ae89b36 100644 --- a/packages/fold-core/src/AgentRuntime/AgentRuntimeLayer.ts +++ b/packages/fold-core/src/AgentRuntime/AgentRuntimeLayer.ts @@ -11,7 +11,7 @@ * agent-finished entries, never service failures. */ import { Array as Arr, Data, Effect, Layer, Predicate, Ref, Result, Schema, Stream } from 'effect' -import { LanguageModel, Prompt, type Response, type Tool, type Toolkit } from 'effect/unstable/ai' +import { LanguageModel, Prompt, type Response, type Toolkit } from 'effect/ai' import { AgentEvents } from '../AgentEvents/AgentEventsService' import { CompactionArchiveAccess } from '../Compaction/CompactionArchiveAccess' @@ -45,7 +45,7 @@ import { SystemPrompt } from '../SystemPrompt/SystemPromptService' import { StopController, type StopControllerService } from '../ToolRuntime/ToolContextServices' import { ToolRuntime } from '../ToolRuntime/ToolRuntimeService' import { ToolsetResolver } from '../ToolRuntime/ToolsetResolverService' -import { Toolset } from '../ToolRuntime/ToolsetService' +import { type AnyTool, Toolset } from '../ToolRuntime/ToolsetService' import { AgentRuntime, type AgentRuntimeService, @@ -359,7 +359,7 @@ export const liveAgentRuntimeLayer: Layer.Layer< const activeToolEntries = Object.entries(withHandler.tools).filter(([name]) => runtimeState.activeTools.includes(name), ) - const toolkit: Toolkit.WithHandler> = { + const toolkit: Toolkit.WithHandler> = { tools: Object.fromEntries(activeToolEntries), handle: withHandler.handle, } diff --git a/packages/fold-core/src/Api/ModelDescriptor.ts b/packages/fold-core/src/Api/ModelDescriptor.ts index 796c941..e999bf9 100644 --- a/packages/fold-core/src/Api/ModelDescriptor.ts +++ b/packages/fold-core/src/Api/ModelDescriptor.ts @@ -6,8 +6,8 @@ */ import { Data, Redacted } from 'effect' import type { Effect, Scope } from 'effect' -import type { LanguageModel } from 'effect/unstable/ai' -import type { HttpClient } from 'effect/unstable/http' +import type { LanguageModel } from 'effect/ai' +import type { HttpClient } from 'effect/http' import type { ActiveModel, OpenAiReasoningSummary, ReasoningLevel } from '../EventLog/Schemas' import { resolveAnthropicThinking, resolveOpenAiReasoning } from '../Model/ModelRequestSettings' @@ -45,7 +45,7 @@ export type FoldModel = { * Builds the model's LanguageModel service in the runtime's scope. `R` is the host services it needs * (an HttpClient for the built-in providers); `startSession` requires them from its caller. */ - readonly make: Effect.Effect + readonly make: Effect.Effect } const redact = (apiKey: string | Redacted.Redacted): Redacted.Redacted => @@ -132,7 +132,7 @@ export type CustomModelOptions = { * Builds the LanguageModel service implementation - the escape hatch for tests and custom providers. * Anything it needs from the host besides `Scope` becomes the model's `R`. */ - readonly make: Effect.Effect + readonly make: Effect.Effect } /** @@ -145,5 +145,5 @@ export const customModel = (options: CustomModelOptions): FoldMode // SAFETY: `Scope | R` and `Scope | Exclude` are the same set of services; TypeScript cannot // see that for a generic R. // oxlint-disable-next-line typescript/consistent-type-assertions, automation/no-type-assertion, effecttsgo/unsafe-effect-type-assertion - make: options.make as Effect.Effect>, + make: options.make as Effect.Effect>, }) diff --git a/packages/fold-core/src/Api/ProviderModels.ts b/packages/fold-core/src/Api/ProviderModels.ts index 5b95216..c8d4b0a 100644 --- a/packages/fold-core/src/Api/ProviderModels.ts +++ b/packages/fold-core/src/Api/ProviderModels.ts @@ -6,8 +6,8 @@ import { AnthropicClient, AnthropicLanguageModel } from '@humanlayer/effect-ai-anthropic' import { OpenAiClient, OpenAiLanguageModel } from '@humanlayer/effect-ai-openai' import { Context, Effect, Layer, type Redacted, type Scope, Stream } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' -import { HttpClient } from 'effect/unstable/http' +import { LanguageModel } from 'effect/ai' +import { HttpClient } from 'effect/http' const anthropicDecoderModelFor = (modelId: string): string | null => { const id = modelId.toLowerCase() @@ -54,7 +54,7 @@ const relaxAnthropicResponseModel = (modelId: string): ((client: HttpClient.Http /** Build the LanguageModel for one layer in the caller's scope. */ const languageModelFrom = ( layer: Layer.Layer, -): Effect.Effect => +): Effect.Effect => Layer.build(layer).pipe(Effect.map((context) => Context.get(context, LanguageModel.LanguageModel))) /** The LanguageModel for an OpenAI-compatible endpoint, over the host's HttpClient. */ @@ -63,7 +63,7 @@ export const openAiCompatibleLanguageModel = (connection: { readonly apiKey: Redacted.Redacted readonly apiKeyHeader: string | null readonly baseUrl: string | null -}): Effect.Effect => { +}): Effect.Effect => { const clientOptions = { apiKey: connection.apiKey, apiKeyHeader: connection.apiKeyHeader ?? undefined, @@ -80,7 +80,7 @@ export const anthropicLanguageModel = (connection: { readonly modelId: string readonly apiKey: Redacted.Redacted readonly baseUrl: string | null -}): Effect.Effect => { +}): Effect.Effect => { const clientOptions = { apiKey: connection.apiKey, apiUrl: connection.baseUrl ?? undefined, diff --git a/packages/fold-core/src/Api/Provisioning.ts b/packages/fold-core/src/Api/Provisioning.ts index a5ad329..080576d 100644 --- a/packages/fold-core/src/Api/Provisioning.ts +++ b/packages/fold-core/src/Api/Provisioning.ts @@ -16,8 +16,8 @@ */ import { Array as Arr, Context, Effect, Layer } from 'effect' import type { Scope } from 'effect' -import { LanguageModel, Toolkit } from 'effect/unstable/ai' -import type { Tool } from 'effect/unstable/ai' +import { LanguageModel, Toolkit } from 'effect/ai' +import type { Tool } from 'effect/ai' import { liveAgentRuntimeLayer } from '../AgentRuntime/AgentRuntimeLayer' import { AgentRuntime } from '../AgentRuntime/AgentRuntimeService' diff --git a/packages/fold-core/src/Api/StartSession.ts b/packages/fold-core/src/Api/StartSession.ts index 6f3f387..b5a98e5 100644 --- a/packages/fold-core/src/Api/StartSession.ts +++ b/packages/fold-core/src/Api/StartSession.ts @@ -44,7 +44,7 @@ import { Stream, Struct, } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import { toolEventSinkLayerFromAgentEvents, liveAgentEventsLayer } from '../AgentEvents/AgentEventsLayer' import type { FoldEvent } from '../AgentEvents/AgentEventsService' diff --git a/packages/fold-core/src/Api/ToolDefinition.ts b/packages/fold-core/src/Api/ToolDefinition.ts index 84fade8..e2c122c 100644 --- a/packages/fold-core/src/Api/ToolDefinition.ts +++ b/packages/fold-core/src/Api/ToolDefinition.ts @@ -12,7 +12,7 @@ * the same value across several agents' `tools` arrays shares one init (one scan, one snapshot). */ import { Effect, Schema, type Scope } from 'effect' -import { Tool } from 'effect/unstable/ai' +import { Tool } from 'effect/ai' import type { AgentEvents } from '../AgentEvents/AgentEventsService' import type { EventLog } from '../EventLog/EventLogService' diff --git a/packages/fold-core/src/Compaction/CompactionLayer.ts b/packages/fold-core/src/Compaction/CompactionLayer.ts index 0aee757..bc136cb 100644 --- a/packages/fold-core/src/Compaction/CompactionLayer.ts +++ b/packages/fold-core/src/Compaction/CompactionLayer.ts @@ -11,7 +11,7 @@ import { AnthropicLanguageModel } from '@humanlayer/effect-ai-anthropic' import { OpenAiLanguageModel } from '@humanlayer/effect-ai-openai' import { Array as Arr, Effect, Layer, Predicate, Stream } from 'effect' -import { LanguageModel, Prompt } from 'effect/unstable/ai' +import { LanguageModel, Prompt } from 'effect/ai' import { ModelCatalog } from '../Model/ModelCatalog' import { entriesForAgent, messagesForAgent, type ProjectedMessage } from '../Projection/Projection' diff --git a/packages/fold-core/src/EventLog/MessageContent.ts b/packages/fold-core/src/EventLog/MessageContent.ts index 3956efd..ec9476b 100644 --- a/packages/fold-core/src/EventLog/MessageContent.ts +++ b/packages/fold-core/src/EventLog/MessageContent.ts @@ -5,7 +5,7 @@ * the string/parts normalization lives in one place. */ import { Match, Option, Schema } from 'effect' -import type { Prompt } from 'effect/unstable/ai' +import type { Prompt } from 'effect/ai' /** Content of a persisted user, assistant, or tool message. */ export type EncodedMessageContent = diff --git a/packages/fold-core/src/EventLog/Schemas.ts b/packages/fold-core/src/EventLog/Schemas.ts index 27c71d4..fd30085 100644 --- a/packages/fold-core/src/EventLog/Schemas.ts +++ b/packages/fold-core/src/EventLog/Schemas.ts @@ -1,5 +1,5 @@ import { Data, Schema } from 'effect' -import { Prompt, Response } from 'effect/unstable/ai' +import { Prompt, Response } from 'effect/ai' import { AgentId, CompactionId, EventId, MessageId, SessionId, StateId, ToolCallId } from '../Ids' import { ForkAgentDefinitionId } from '../Subagents/ForkAgentDefinition' diff --git a/packages/fold-core/src/EventLog/Usage.ts b/packages/fold-core/src/EventLog/Usage.ts index db5af2e..aa1fa7c 100644 --- a/packages/fold-core/src/EventLog/Usage.ts +++ b/packages/fold-core/src/EventLog/Usage.ts @@ -1,5 +1,5 @@ import { Schema } from 'effect' -import type { Response } from 'effect/unstable/ai' +import type { Response } from 'effect/ai' /** Best-effort token count reported by a model provider. Providers may omit any usage field. */ export const UsageTokenCount = Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)).annotate({ diff --git a/packages/fold-core/src/HookRunner/Schema.ts b/packages/fold-core/src/HookRunner/Schema.ts index 3129f83..9c2b895 100644 --- a/packages/fold-core/src/HookRunner/Schema.ts +++ b/packages/fold-core/src/HookRunner/Schema.ts @@ -1,5 +1,5 @@ import { Schema } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import { AgentId, ToolCallId } from '../Ids' diff --git a/packages/fold-core/src/Model/RequestBuilder.ts b/packages/fold-core/src/Model/RequestBuilder.ts index 5631724..18f79ac 100644 --- a/packages/fold-core/src/Model/RequestBuilder.ts +++ b/packages/fold-core/src/Model/RequestBuilder.ts @@ -8,8 +8,9 @@ * metadata into history. The assistant tool-call params stay exactly as decoded from the persisted * assistant message, keeping already-sent prompt bytes stable across turns. */ -import { Array as Arr, Effect, Encoding, Match, Option, Predicate, Schema } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Array as Arr, Effect, Match, Option, Predicate, Schema } from 'effect' +import { Prompt } from 'effect/ai' +import { Base64, type EncodingError } from 'effect/encoding' import type { ProjectedMessage, ProjectedToolResult } from '../Projection/Projection' import { ToolResultOutput } from '../Tools/ToolResultContent' @@ -233,7 +234,7 @@ const markLatestUserSideCacheBreakpoint = (messages: ReadonlyArray => { +): Effect.Effect => { const decoded = decodeToolResultOutput(result) if (Option.isNone(decoded)) return Effect.succeed(result) @@ -247,7 +248,7 @@ const prepareToolResult = ( Match.tagsExhaustive({ 'text-part': ({ text }) => Effect.succeed(Prompt.textPart({ text })), 'image-part': ({ data, mediaType, fileName }) => - Effect.fromResult(Encoding.decodeBase64(data)).pipe( + Effect.fromResult(Base64.decode(data)).pipe( Effect.map((bytes) => Prompt.filePart({ data: bytes, mediaType, fileName })), ), }), @@ -258,8 +259,10 @@ const prepareToolResult = ( } /** Prepare each canonical result while retaining the surrounding tool message. */ -const prepareToolMessage = (message: Prompt.ToolMessage): Effect.Effect => - Effect.forEach(message.content, (part): Effect.Effect => +const prepareToolMessage = ( + message: Prompt.ToolMessage, +): Effect.Effect => + Effect.forEach(message.content, (part): Effect.Effect => part.type === 'tool-result' ? prepareToolResult(part.result).pipe( Effect.map((result) => diff --git a/packages/fold-core/src/StopConditions/StopConditions.ts b/packages/fold-core/src/StopConditions/StopConditions.ts index 5723b67..f236d3d 100644 --- a/packages/fold-core/src/StopConditions/StopConditions.ts +++ b/packages/fold-core/src/StopConditions/StopConditions.ts @@ -5,7 +5,7 @@ * before another model request. */ import { Array as Arr, Context, Equal } from 'effect' -import type { Prompt } from 'effect/unstable/ai' +import type { Prompt } from 'effect/ai' /** Doom-loop detector configuration. Omitted means disabled. */ export type DoomLoopStopCondition = diff --git a/packages/fold-core/src/Subagents/SubagentEngine.ts b/packages/fold-core/src/Subagents/SubagentEngine.ts index 4225ec5..a47b016 100644 --- a/packages/fold-core/src/Subagents/SubagentEngine.ts +++ b/packages/fold-core/src/Subagents/SubagentEngine.ts @@ -20,7 +20,7 @@ * tools that may call them again. Continue runs from the session handle, with no tool call. */ import { Array as Arr, Data, Match, Predicate, Cause, Effect, Exit, Fiber, Ref, Schema, Stream, Struct } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import type { FoldModel } from '../Api/ModelDescriptor' import { provisionAgentRuntime } from '../Api/Provisioning' diff --git a/packages/fold-core/src/ToolRuntime/ToolRuntimeLayer.ts b/packages/fold-core/src/ToolRuntime/ToolRuntimeLayer.ts index 9fc6f46..28152ba 100644 --- a/packages/fold-core/src/ToolRuntime/ToolRuntimeLayer.ts +++ b/packages/fold-core/src/ToolRuntime/ToolRuntimeLayer.ts @@ -5,7 +5,7 @@ * tool-result entry per call, including synthetic interruption results when a tool fiber is interrupted. */ import { Data, Equal, Match, Predicate, Cause, Effect, Layer, Ref, Schema, Stream, Struct } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import { EventLog } from '../EventLog/EventLogService' import { LogEntryInputs, type LogEntry, type ToolResultLogEntry } from '../EventLog/Schemas' diff --git a/packages/fold-core/src/ToolRuntime/ToolRuntimeService.ts b/packages/fold-core/src/ToolRuntime/ToolRuntimeService.ts index 07002bc..8c84978 100644 --- a/packages/fold-core/src/ToolRuntime/ToolRuntimeService.ts +++ b/packages/fold-core/src/ToolRuntime/ToolRuntimeService.ts @@ -6,7 +6,7 @@ */ import { Context } from 'effect' import type { Effect } from 'effect' -import type { Prompt } from 'effect/unstable/ai' +import type { Prompt } from 'effect/ai' import type { ToolResultLogEntry } from '../EventLog/Schemas' import type { AgentId } from '../Ids' diff --git a/packages/fold-core/src/ToolRuntime/ToolsetFactory.ts b/packages/fold-core/src/ToolRuntime/ToolsetFactory.ts index 4748127..75a2e8b 100644 --- a/packages/fold-core/src/ToolRuntime/ToolsetFactory.ts +++ b/packages/fold-core/src/ToolRuntime/ToolsetFactory.ts @@ -4,9 +4,9 @@ * without needing to know the toolkit's specific TypeScript shape. */ import { Effect, Layer, Stream } from 'effect' -import type { Tool, Toolkit } from 'effect/unstable/ai' +import type { Tool, Toolkit } from 'effect/ai' -import { Toolset, type ToolHandlerOutput } from './ToolsetService' +import { type AnyTool, Toolset, type ToolHandlerOutput } from './ToolsetService' /** Build a final failure output for a model-requested tool name that is not in the active Toolset. */ const unavailableToolFailureOutput = (name: string, names: ReadonlyArray): ToolHandlerOutput => ({ @@ -36,7 +36,7 @@ export const toolsetLayerFromToolkit = >( // cannot express dynamic dispatch over a heterogeneous toolkit; the library erases internally // for the same reason (Toolkit.ts: `handle: handle as any`). The one sanctioned assertion. // oxlint-disable-next-line typescript/consistent-type-assertions, automation/no-type-assertion, automation/no-banned-type-assertions, anti-slop/no-chained-type-assertions - const withHandlers = (yield* toolkit) as unknown as Toolkit.WithHandler> + const withHandlers = (yield* toolkit) as unknown as Toolkit.WithHandler> const names = Object.keys(toolkit.tools) return { diff --git a/packages/fold-core/src/ToolRuntime/ToolsetService.ts b/packages/fold-core/src/ToolRuntime/ToolsetService.ts index c6fdec2..cbe8a6a 100644 --- a/packages/fold-core/src/ToolRuntime/ToolsetService.ts +++ b/packages/fold-core/src/ToolRuntime/ToolsetService.ts @@ -3,12 +3,31 @@ * ToolRuntime live layer to execute tool handlers. The service keeps Effect AI's dynamic Toolkit boundary * contained so callers do not pass tool handlers around as arguments. */ -import { Context, type Effect, type Stream } from 'effect' -import type { Tool, Toolkit } from 'effect/unstable/ai' +import { Context, type Effect, type Schema, type Stream } from 'effect' +import type { Tool, Toolkit } from 'effect/ai' import type { CurrentAgent, CurrentToolCall, InterruptNote, StopController, ToolEvents } from './ToolContextServices' import type { ToolState } from './ToolStateService' +/** The services a tool handler may use, which ToolRuntime provides around each call. */ +export type ToolCallServices = ToolState | ToolEvents | StopController | CurrentAgent | CurrentToolCall | InterruptNote + +/** + * A tool erased for dispatch by name. Unlike Effect AI's `Tool.Any`, its schemas need no services to encode or + * decode, as none of fold's do, and its handler needs only {@link ToolCallServices}. With `Tool.Any` those + * services are unknown, and they reach every model request and handler call. + */ +export interface AnyTool extends Tool.Tool< + string, + { + readonly parameters: Schema.Codec + readonly success: Schema.Codec + readonly failure: Schema.Codec + readonly failureMode: Tool.FailureMode + }, + ToolCallServices +> {} + /** Type-erased handler output from Effect AI Toolkit. Preliminary outputs are UI/progress only. */ export type ToolHandlerOutput = { readonly result: unknown @@ -28,7 +47,7 @@ export type ToolsetService = { * `LanguageModel.streamText` with `disableToolCallResolution: true`, so the model sees the tool * schemas while tool execution stays owned by ToolRuntime. */ - readonly withHandler: Effect.Effect>> + readonly withHandler: Effect.Effect>> /** * Run one named handler with model-supplied parameters and stream its toolkit outputs. Handler * streams may consume the ambient per-call services (ToolState, ToolEvents, StopController, @@ -37,13 +56,7 @@ export type ToolsetService = { readonly handle: ( name: string, params: Tool.ParametersEncoded, - ) => Effect.Effect< - Stream.Stream< - ToolHandlerOutput, - unknown, - ToolState | ToolEvents | StopController | CurrentAgent | CurrentToolCall | InterruptNote - > - > + ) => Effect.Effect, never, ToolCallServices> } /** Active toolset shared by AgentRuntime and ToolRuntime. */ diff --git a/packages/fold-core/test/AgentRuntime/AgentRuntimeModelSettings.vi.test.ts b/packages/fold-core/test/AgentRuntime/AgentRuntimeModelSettings.vi.test.ts index 25db8a8..233cc98 100644 --- a/packages/fold-core/test/AgentRuntime/AgentRuntimeModelSettings.vi.test.ts +++ b/packages/fold-core/test/AgentRuntime/AgentRuntimeModelSettings.vi.test.ts @@ -1,8 +1,8 @@ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { expect, it } from '@effect/vitest' import { Predicate, Effect, Layer, Schema } from 'effect' -import { Tool, Toolkit } from 'effect/unstable/ai' -import type { LanguageModel } from 'effect/unstable/ai' +import { Tool, Toolkit } from 'effect/ai' +import type { LanguageModel } from 'effect/ai' import { AgentRuntime, diff --git a/packages/fold-core/test/AgentRuntime/AgentRuntimePrefix.vi.test.ts b/packages/fold-core/test/AgentRuntime/AgentRuntimePrefix.vi.test.ts index d8a43cc..0082502 100644 --- a/packages/fold-core/test/AgentRuntime/AgentRuntimePrefix.vi.test.ts +++ b/packages/fold-core/test/AgentRuntime/AgentRuntimePrefix.vi.test.ts @@ -1,6 +1,6 @@ import { expect, it } from '@effect/vitest' import { Array as Arr, Effect, Predicate, Schema } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import { AgentRuntime } from '../../src/index' import { makeScriptedLanguageModel, textTurn } from '../TestLayers/ScriptedLanguageModel' diff --git a/packages/fold-core/test/AgentRuntime/AgentRuntimeTestHelpers.ts b/packages/fold-core/test/AgentRuntime/AgentRuntimeTestHelpers.ts index 1806890..7c0f203 100644 --- a/packages/fold-core/test/AgentRuntime/AgentRuntimeTestHelpers.ts +++ b/packages/fold-core/test/AgentRuntime/AgentRuntimeTestHelpers.ts @@ -1,6 +1,6 @@ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { Layer } from 'effect' -import type { LanguageModel, Tool } from 'effect/unstable/ai' +import type { LanguageModel, Tool } from 'effect/ai' import { AgentId, diff --git a/packages/fold-core/test/AgentRuntime/AgentRuntimeToolRun.vi.test.ts b/packages/fold-core/test/AgentRuntime/AgentRuntimeToolRun.vi.test.ts index 0b4eb73..52ca21c 100644 --- a/packages/fold-core/test/AgentRuntime/AgentRuntimeToolRun.vi.test.ts +++ b/packages/fold-core/test/AgentRuntime/AgentRuntimeToolRun.vi.test.ts @@ -1,6 +1,6 @@ import { expect, it } from '@effect/vitest' import { Predicate, Effect, Ref } from 'effect' -import type { Prompt } from 'effect/unstable/ai' +import type { Prompt } from 'effect/ai' import { AgentRuntime, type AssistantMessageLogEntry, type ToolResultLogEntry } from '../../src/index' import { makeScriptedLanguageModel, textTurn, toolCallTurn } from '../TestLayers/ScriptedLanguageModel' diff --git a/packages/fold-core/test/Api/ApiTestHelpers.ts b/packages/fold-core/test/Api/ApiTestHelpers.ts index c67943d..3c2f2d7 100644 --- a/packages/fold-core/test/Api/ApiTestHelpers.ts +++ b/packages/fold-core/test/Api/ApiTestHelpers.ts @@ -4,7 +4,7 @@ * exactly what SDK callers write - with the scripted LanguageModel swapped in at the provider seam. */ import { Context, Effect, Layer, Ref, Schema } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' +import { LanguageModel } from 'effect/ai' import { customModel, diff --git a/packages/fold-core/test/Api/Provisioning.vi.test.ts b/packages/fold-core/test/Api/Provisioning.vi.test.ts index 8bbe604..d66b1c0 100644 --- a/packages/fold-core/test/Api/Provisioning.vi.test.ts +++ b/packages/fold-core/test/Api/Provisioning.vi.test.ts @@ -1,7 +1,7 @@ import { assert, it } from '@effect/vitest' import { Effect, Layer, Predicate, Schema } from 'effect' -import { LanguageModel, Prompt } from 'effect/unstable/ai' -import { FetchHttpClient } from 'effect/unstable/http' +import { LanguageModel, Prompt } from 'effect/ai' +import { FetchHttpClient } from 'effect/http' import { languageModelLayerFor, diff --git a/packages/fold-core/test/Api/ResumeSession.vi.test.ts b/packages/fold-core/test/Api/ResumeSession.vi.test.ts index bb684b5..22b2ba7 100644 --- a/packages/fold-core/test/Api/ResumeSession.vi.test.ts +++ b/packages/fold-core/test/Api/ResumeSession.vi.test.ts @@ -8,7 +8,7 @@ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' */ import { expect, it } from '@effect/vitest' import { Predicate, Cause, Context, Effect, Exit, Layer, Schema } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import { defineAgent, diff --git a/packages/fold-core/test/Api/SessionControlHarness.ts b/packages/fold-core/test/Api/SessionControlHarness.ts index 5add1a0..d02575b 100644 --- a/packages/fold-core/test/Api/SessionControlHarness.ts +++ b/packages/fold-core/test/Api/SessionControlHarness.ts @@ -6,8 +6,8 @@ * requests serve ordinary scripted turns. */ import { Predicate, Deferred, Effect, Ref, Schema, Stream } from 'effect' -import { AiError, LanguageModel } from 'effect/unstable/ai' -import type { Response } from 'effect/unstable/ai' +import { AiError, LanguageModel } from 'effect/ai' +import type { Response } from 'effect/ai' import { customModel, defineTool, type ActiveModel, type FoldModel, type FoldTool } from '../../src/index' import type { ScriptedTurn } from '../TestLayers/ScriptedLanguageModel' diff --git a/packages/fold-core/test/Compaction/CompactionEngine.vi.test.ts b/packages/fold-core/test/Compaction/CompactionEngine.vi.test.ts index 1a7e0b0..a25f50c 100644 --- a/packages/fold-core/test/Compaction/CompactionEngine.vi.test.ts +++ b/packages/fold-core/test/Compaction/CompactionEngine.vi.test.ts @@ -5,7 +5,7 @@ */ import { expect, it } from '@effect/vitest' import { Schema } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import { compactionUsableTokens, diff --git a/packages/fold-core/test/EventLog/Usage.vi.test.ts b/packages/fold-core/test/EventLog/Usage.vi.test.ts index 25a1b54..e08c4af 100644 --- a/packages/fold-core/test/EventLog/Usage.vi.test.ts +++ b/packages/fold-core/test/EventLog/Usage.vi.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from '@effect/vitest' -import type { Response } from 'effect/unstable/ai' +import type { Response } from 'effect/ai' import { usageFromResponseUsage } from '../../src/EventLog/Usage' diff --git a/packages/fold-core/test/HookRunner/PassThrough.vi.test.ts b/packages/fold-core/test/HookRunner/PassThrough.vi.test.ts index 2f7ca4a..7be1761 100644 --- a/packages/fold-core/test/HookRunner/PassThrough.vi.test.ts +++ b/packages/fold-core/test/HookRunner/PassThrough.vi.test.ts @@ -1,6 +1,6 @@ import { expect, it } from '@effect/vitest' import { Effect, Layer, Schema } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import { AgentId, diff --git a/packages/fold-core/test/HookRunner/PreRequestHook.vi.test.ts b/packages/fold-core/test/HookRunner/PreRequestHook.vi.test.ts index 09eb682..1fd07aa 100644 --- a/packages/fold-core/test/HookRunner/PreRequestHook.vi.test.ts +++ b/packages/fold-core/test/HookRunner/PreRequestHook.vi.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from '@effect/vitest' import { Effect } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import { AgentId, HookRunner, type PreRequestHook } from '../../src' import { runWithHookRunner } from '../TestLayers/HookRunnerTestHarness' diff --git a/packages/fold-core/test/Model/EffectAnthropicToolResultEncodingRepro.vi.test.ts b/packages/fold-core/test/Model/EffectAnthropicToolResultEncodingRepro.vi.test.ts index 068d6b6..e8fb64d 100644 --- a/packages/fold-core/test/Model/EffectAnthropicToolResultEncodingRepro.vi.test.ts +++ b/packages/fold-core/test/Model/EffectAnthropicToolResultEncodingRepro.vi.test.ts @@ -2,8 +2,8 @@ import { assert, it } from '@effect/vitest' /** Regression coverage for patched @humanlayer/effect-ai-anthropic client tool-result encoding. */ import { AnthropicClient, AnthropicLanguageModel } from '@humanlayer/effect-ai-anthropic' import { Effect, Layer, Predicate, Redacted, Schema } from 'effect' -import { LanguageModel, Prompt } from 'effect/unstable/ai' -import { HttpClient, type HttpClientError, HttpClientResponse } from 'effect/unstable/http' +import { LanguageModel, Prompt } from 'effect/ai' +import { HttpClient, type HttpClientError, HttpClientResponse } from 'effect/http' const CapturedRequest = Schema.Struct({ messages: Schema.Array( @@ -14,7 +14,7 @@ const CapturedRequest = Schema.Struct({ ), }) -it.effect('passes strings through and emits multipart client tool results in Effect 4.0.0-rc.112', () => +it.effect('passes strings through and emits multipart client tool results in Effect 4.0.0', () => Effect.gen(function* () { let requestBody: unknown = null const preprocess: HttpClient.HttpClient.Preprocess = Effect.succeed diff --git a/packages/fold-core/test/Model/RequestBuilder.vi.test.ts b/packages/fold-core/test/Model/RequestBuilder.vi.test.ts index 1f79e0e..83bcbaf 100644 --- a/packages/fold-core/test/Model/RequestBuilder.vi.test.ts +++ b/packages/fold-core/test/Model/RequestBuilder.vi.test.ts @@ -1,6 +1,6 @@ import { expect, it } from '@effect/vitest' import { Effect, Result } from 'effect' -import type { Prompt } from 'effect/unstable/ai' +import type { Prompt } from 'effect/ai' import { buildPrompt, diff --git a/packages/fold-core/test/Model/RequestBuilderImages.vi.test.ts b/packages/fold-core/test/Model/RequestBuilderImages.vi.test.ts index 6ffa322..bc0bc7b 100644 --- a/packages/fold-core/test/Model/RequestBuilderImages.vi.test.ts +++ b/packages/fold-core/test/Model/RequestBuilderImages.vi.test.ts @@ -1,6 +1,7 @@ import { expect, it } from '@effect/vitest' -import { Effect, Encoding } from 'effect' -import type { Prompt } from 'effect/unstable/ai' +import { Effect } from 'effect' +import type { Prompt } from 'effect/ai' +import { Base64 } from 'effect/encoding' import { buildPrompt, @@ -71,7 +72,7 @@ it.effect('lowers multipart results to text and file parts inside the original t const image = result[1] if (image?.type !== 'file' || !(image.data instanceof Uint8Array)) throw new Error('expected image bytes') expect(image.mediaType).toBe('image/png') - expect(Encoding.encodeBase64(image.data)).toBe(imageBase64) + expect(Base64.encode(image.data)).toBe(imageBase64) }), ) @@ -92,7 +93,7 @@ it.effect('preserves multiple image parts in result order', () => if (!Array.isArray(result)) throw new Error('expected multipart Prompt content') expect( result.map((part) => - part.type === 'file' && part.data instanceof Uint8Array ? Encoding.encodeBase64(part.data) : null, + part.type === 'file' && part.data instanceof Uint8Array ? Base64.encode(part.data) : null, ), ).toEqual(['Zmlyc3Q=', 'c2Vjb25k']) expect(result.map((part) => (part.type === 'file' ? part.mediaType : null))).toEqual([ diff --git a/packages/fold-core/test/Projection/Projection.vi.test.ts b/packages/fold-core/test/Projection/Projection.vi.test.ts index 1c1cb71..9f37acf 100644 --- a/packages/fold-core/test/Projection/Projection.vi.test.ts +++ b/packages/fold-core/test/Projection/Projection.vi.test.ts @@ -1,6 +1,6 @@ import { it, expect } from '@effect/vitest' import { Effect, Layer, Schema, Stream } from 'effect' -import { Prompt } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' import { EventLog, diff --git a/packages/fold-core/test/Session/SessionTestHelpers.ts b/packages/fold-core/test/Session/SessionTestHelpers.ts index c5611db..84bfb22 100644 --- a/packages/fold-core/test/Session/SessionTestHelpers.ts +++ b/packages/fold-core/test/Session/SessionTestHelpers.ts @@ -1,6 +1,6 @@ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { Layer } from 'effect' -import type { LanguageModel, Tool } from 'effect/unstable/ai' +import type { LanguageModel, Tool } from 'effect/ai' import { layerDefaultSystemPrompt, diff --git a/packages/fold-core/test/Subagents/DriveHarness.ts b/packages/fold-core/test/Subagents/DriveHarness.ts index c072e0a..99bacd2 100644 --- a/packages/fold-core/test/Subagents/DriveHarness.ts +++ b/packages/fold-core/test/Subagents/DriveHarness.ts @@ -8,7 +8,7 @@ */ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { Predicate, Deferred, Effect, Ref, Schema, Stream } from 'effect' -import { AiError, LanguageModel } from 'effect/unstable/ai' +import { AiError, LanguageModel } from 'effect/ai' import { dispatchSubagent, diff --git a/packages/fold-core/test/TestLayers/ScriptedLanguageModel.ts b/packages/fold-core/test/TestLayers/ScriptedLanguageModel.ts index 4b2c095..c64fdfa 100644 --- a/packages/fold-core/test/TestLayers/ScriptedLanguageModel.ts +++ b/packages/fold-core/test/TestLayers/ScriptedLanguageModel.ts @@ -12,7 +12,7 @@ import { AnthropicLanguageModel } from '@humanlayer/effect-ai-anthropic' import { OpenAiLanguageModel } from '@humanlayer/effect-ai-openai' import { Predicate, Effect, Layer, Ref, Stream } from 'effect' -import { AiError, LanguageModel, type Prompt, type Response } from 'effect/unstable/ai' +import { AiError, LanguageModel, type Prompt, type Response } from 'effect/ai' /** Optional shaping for a scripted turn's finish part. */ export type ScriptedFinishOptions = { diff --git a/packages/fold-core/test/TestLayers/ScriptedLanguageModelUsage.vi.test.ts b/packages/fold-core/test/TestLayers/ScriptedLanguageModelUsage.vi.test.ts index b460979..2026519 100644 --- a/packages/fold-core/test/TestLayers/ScriptedLanguageModelUsage.vi.test.ts +++ b/packages/fold-core/test/TestLayers/ScriptedLanguageModelUsage.vi.test.ts @@ -9,7 +9,7 @@ */ import { expect, it } from '@effect/vitest' import { Effect, Result, Stream } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' +import { LanguageModel } from 'effect/ai' import { failureTurn, makeScriptedLanguageModel, textTurn } from './ScriptedLanguageModel' diff --git a/packages/fold-core/test/TestLayers/TestTools.ts b/packages/fold-core/test/TestLayers/TestTools.ts index a58caab..31b3037 100644 --- a/packages/fold-core/test/TestLayers/TestTools.ts +++ b/packages/fold-core/test/TestLayers/TestTools.ts @@ -1,5 +1,5 @@ import { Effect, Ref, Schema } from 'effect' -import { Tool, Toolkit } from 'effect/unstable/ai' +import { Tool, Toolkit } from 'effect/ai' import { defineToolState, StopController, ToolEvents, ToolState } from '../../src/index' diff --git a/packages/fold-core/test/ToolRuntime/ToolRuntimeInterrupt.vi.test.ts b/packages/fold-core/test/ToolRuntime/ToolRuntimeInterrupt.vi.test.ts index c37f91c..bd3536c 100644 --- a/packages/fold-core/test/ToolRuntime/ToolRuntimeInterrupt.vi.test.ts +++ b/packages/fold-core/test/ToolRuntime/ToolRuntimeInterrupt.vi.test.ts @@ -1,7 +1,7 @@ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { expect, it } from '@effect/vitest' import { Predicate, Deferred, Effect, Fiber, Layer, Schema } from 'effect' -import { Prompt, Tool, Toolkit } from 'effect/unstable/ai' +import { Prompt, Tool, Toolkit } from 'effect/ai' import { layerInMemoryEventLog, diff --git a/packages/fold-core/test/ToolRuntime/ToolRuntimeStateSnapshot.vi.test.ts b/packages/fold-core/test/ToolRuntime/ToolRuntimeStateSnapshot.vi.test.ts index 25900a5..44fba62 100644 --- a/packages/fold-core/test/ToolRuntime/ToolRuntimeStateSnapshot.vi.test.ts +++ b/packages/fold-core/test/ToolRuntime/ToolRuntimeStateSnapshot.vi.test.ts @@ -1,7 +1,7 @@ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { describe, expect, it } from '@effect/vitest' import { Predicate, Deferred, Effect, Layer, Ref, Schema } from 'effect' -import { Prompt, Tool, Toolkit } from 'effect/unstable/ai' +import { Prompt, Tool, Toolkit } from 'effect/ai' import { defineToolState, diff --git a/packages/fold-core/test/ToolRuntime/ToolRuntimeTestHelpers.ts b/packages/fold-core/test/ToolRuntime/ToolRuntimeTestHelpers.ts index 5840556..6c1bc71 100644 --- a/packages/fold-core/test/ToolRuntime/ToolRuntimeTestHelpers.ts +++ b/packages/fold-core/test/ToolRuntime/ToolRuntimeTestHelpers.ts @@ -1,7 +1,7 @@ import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' import { Effect, Layer, Ref, Stream } from 'effect' -import { Prompt } from 'effect/unstable/ai' -import type { Tool } from 'effect/unstable/ai' +import { Prompt } from 'effect/ai' +import type { Tool } from 'effect/ai' import { AgentId, diff --git a/packages/fold-opencode/src/OpenCodeAuth.ts b/packages/fold-opencode/src/OpenCodeAuth.ts index 9d22832..eef1ef3 100644 --- a/packages/fold-opencode/src/OpenCodeAuth.ts +++ b/packages/fold-opencode/src/OpenCodeAuth.ts @@ -3,7 +3,7 @@ * MIT-licensed client implementation; see ../NOTICE and ../LICENSE.opencode. */ import { Clock, Context, Duration, Effect, Layer, Match, Option, Schema, Semaphore } from 'effect' -import { HttpClient, HttpClientError, HttpClientRequest, HttpClientResponse } from 'effect/unstable/http' +import { HttpClient, HttpClientError, HttpClientRequest, HttpClientResponse } from 'effect/http' import { OpenCodeAuthStore, OpenCodeTokenData } from './AuthStore' diff --git a/packages/fold-opencode/src/OpenCodeModel.ts b/packages/fold-opencode/src/OpenCodeModel.ts index 09a7c5a..53c31f0 100644 --- a/packages/fold-opencode/src/OpenCodeModel.ts +++ b/packages/fold-opencode/src/OpenCodeModel.ts @@ -11,8 +11,8 @@ import { customModel, resolveOpenAiReasoning } from '@humanlayer/fold-core' import type { FoldModel, ReasoningLevel } from '@humanlayer/fold-core' import { Match, Context, Effect, Layer, Option, Schema } from 'effect' import type { FileSystem, Scope } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' -import { HttpClient, HttpClientRequest, HttpClientResponse } from 'effect/unstable/http' +import { LanguageModel } from 'effect/ai' +import { HttpClient, HttpClientRequest, HttpClientResponse } from 'effect/http' import { layerOpenCodeAuthStore, type OpenCodeAuthStoreOptions } from './AuthStore' import { layerOpenCodeAuth, OPENCODE_CONSOLE_URL, OpenCodeAuth, openCodeAuthenticatedClient } from './OpenCodeAuth' @@ -125,7 +125,7 @@ const fetchRemoteProviders = (authenticated: HttpClient.HttpClient, server: stri /** Construct the Effect LanguageModel backed by stored OpenCode OAuth credentials. */ export const makeOpenCodeLanguageModel = ( options: OpenCodeModelOptions = {}, -): Effect.Effect => +): Effect.Effect => Layer.build( Layer.effect( LanguageModel.LanguageModel, diff --git a/packages/fold-opencode/test/OpenCodeAuth.vi.test.ts b/packages/fold-opencode/test/OpenCodeAuth.vi.test.ts index 1509f93..3d18ffa 100644 --- a/packages/fold-opencode/test/OpenCodeAuth.vi.test.ts +++ b/packages/fold-opencode/test/OpenCodeAuth.vi.test.ts @@ -1,6 +1,6 @@ import { describe, it } from '@effect/vitest' import { Effect, Layer } from 'effect' -import { HttpClient, HttpClientResponse } from 'effect/unstable/http' +import { HttpClient, HttpClientResponse } from 'effect/http' import { expect } from 'vitest' import { OpenCodeAuthStore, type OpenCodeAuthStoreService } from '../src/AuthStore' diff --git a/packages/fold-xai/src/OAuthFlows.ts b/packages/fold-xai/src/OAuthFlows.ts index b0c2f1b..ab50800 100644 --- a/packages/fold-xai/src/OAuthFlows.ts +++ b/packages/fold-xai/src/OAuthFlows.ts @@ -3,7 +3,7 @@ import { createServer } from 'node:http' import type { Server } from 'node:http' import { Clock, Crypto, Deferred, Duration, Effect, Result, Schedule, Schema } from 'effect' -import { HttpClient, HttpClientRequest, HttpClientResponse } from 'effect/unstable/http' +import { HttpClient, HttpClientRequest, HttpClientResponse } from 'effect/http' import { XaiTokenData } from './AuthStore' diff --git a/packages/fold-xai/src/XaiAuth.ts b/packages/fold-xai/src/XaiAuth.ts index afb4511..4b13853 100644 --- a/packages/fold-xai/src/XaiAuth.ts +++ b/packages/fold-xai/src/XaiAuth.ts @@ -1,7 +1,7 @@ /** Persistent, single-flight xAI OAuth credential service and authenticated HTTP decorator. */ import * as NodeCrypto from '@effect/platform-node/NodeCrypto' import { Clock, Context, Effect, Layer, Option, Semaphore } from 'effect' -import { HttpClient, HttpClientError, HttpClientRequest } from 'effect/unstable/http' +import { HttpClient, HttpClientError, HttpClientRequest } from 'effect/http' import { XaiAuthStore, type XaiAuthStoreError, type XaiTokenData } from './AuthStore' import type { XaiBrowserFlowOptions, XaiDevicePrompt } from './OAuthFlows' diff --git a/packages/fold-xai/src/XaiModel.ts b/packages/fold-xai/src/XaiModel.ts index 3c50452..b20b9ee 100644 --- a/packages/fold-xai/src/XaiModel.ts +++ b/packages/fold-xai/src/XaiModel.ts @@ -9,8 +9,8 @@ import { customModel, resolveOpenAiReasoning } from '@humanlayer/fold-core' import type { FoldModel, ReasoningLevel } from '@humanlayer/fold-core' import { Context, Effect, Layer, Match, Option, Predicate, Schema, Stream } from 'effect' import type { FileSystem, Scope } from 'effect' -import { LanguageModel } from 'effect/unstable/ai' -import { HttpClient } from 'effect/unstable/http' +import { LanguageModel } from 'effect/ai' +import { HttpClient } from 'effect/http' import { layerXaiAuthStore, type XaiAuthStoreOptions } from './AuthStore' import { layerXaiAuth, xaiAuthenticatedClient } from './XaiAuth' @@ -85,7 +85,7 @@ const authLayerFor = (options: XaiModelOptions) => /** Build xAI's stock OpenAI-compatible LanguageModel over the OAuth transport. */ export const makeXaiLanguageModel = ( options: XaiModelOptions, -): Effect.Effect => +): Effect.Effect => Layer.build( Layer.effect( LanguageModel.LanguageModel, diff --git a/scripts/release/fixtures/provider-consumer.mjs b/scripts/release/fixtures/provider-consumer.mjs index edab7c6..aab741b 100644 --- a/scripts/release/fixtures/provider-consumer.mjs +++ b/scripts/release/fixtures/provider-consumer.mjs @@ -1,8 +1,8 @@ import { AnthropicClient, AnthropicLanguageModel } from '@humanlayer/effect-ai-anthropic' import { OpenAiClient, OpenAiLanguageModel } from '@humanlayer/effect-ai-openai' import { Effect, Layer, Predicate, Redacted } from 'effect' -import { LanguageModel, Prompt } from 'effect/unstable/ai' -import { FetchHttpClient, HttpClient, HttpClientResponse } from 'effect/unstable/http' +import { LanguageModel, Prompt } from 'effect/ai' +import { FetchHttpClient, HttpClient, HttpClientResponse } from 'effect/http' const fail = (message) => { throw new Error(message) diff --git a/tsconfig.json b/tsconfig.json index f7fd1bd..97c5067 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,12 @@ { "compilerOptions": { - "plugins": [{ "name": "@effect/language-service" }], + "plugins": [ + { + "name": "@effect/language-service", + // Effect 4.0.0 marks its ai, http and other moved modules unstable, and fold is built on them. + "diagnosticSeverity": { "unstableApiUsage": "off" } + } + ], "target": "ESNext", "module": "ESNext", From da9d11b7e21fc6d7e35ee8ad49aa0f6a02d76e96 Mon Sep 17 00:00:00 2001 From: Kyle Mistele Date: Sat, 3 Oct 2026 14:23:27 -0700 Subject: [PATCH 2/2] test(agent): restore the cached log time exactly in the summary fast-path test Effect 4.0.0 reads file times as nanoseconds and drops the fraction of a millisecond. The test reset the log's time from Node's statSync Date, and utimesSync can store that a hair early, so Effect read the previous millisecond about half the time and the cache missed. Set the time half a millisecond past the recorded one instead. Co-Authored-By: Claude Opus 5.5 HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0f3fc-13b0-758f-a343-fae04e83a7a9 --- packages/fold-agent/test/Session/SessionLayout.vi.test.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/fold-agent/test/Session/SessionLayout.vi.test.ts b/packages/fold-agent/test/Session/SessionLayout.vi.test.ts index 7536c28..ca87920 100644 --- a/packages/fold-agent/test/Session/SessionLayout.vi.test.ts +++ b/packages/fold-agent/test/Session/SessionLayout.vi.test.ts @@ -5,7 +5,7 @@ * carries), and discovery lists a project's logs newest-first with the latest ready for * `resumeSession`. */ -import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync, appendFileSync, utimesSync } from 'node:fs' +import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync, utimesSync } from 'node:fs' import { join } from 'node:path' import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem' @@ -169,7 +169,9 @@ it.effect('session summary index is a full fast path and latest valid record win indexPath, `${JSON.stringify({ ...cached, summary: { ...cached.summary, title: 'Latest Wins' } })}\n`, ) - const mtime = statSync(prepared.path).mtime + // Put back the time the cache recorded. Effect reads times in nanoseconds and drops the fraction of a + // millisecond, and `utimesSync` can store a time a hair early, so aim half a millisecond in. + const mtime = (built.mtimeMs + 0.5) / 1000 const source = readFileSync(prepared.path, 'utf8') writeFileSync(prepared.path, 'x'.repeat(source.length)) utimesSync(prepared.path, mtime, mtime)