Skip to content

feat(effect): add Effect bridge spike package - #145

Merged
ThomasK33 merged 6 commits into
mainfrom
issue-144-effect-bridge-spike
Aug 30, 2026
Merged

feat(effect): add Effect bridge spike package#145
ThomasK33 merged 6 commits into
mainfrom
issue-144-effect-bridge-spike

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Part of #144 (Phase 1 spike — do not close the tracking issue).

Adds packages/effect (@coder/ai-sdk-effect): an experimental Effect bridge over the existing SDK packages. The package is private: true, is not published, is not in the release-please config/manifest (verified: config packages map and manifest list only sandbox/agent/provider), and is automatically excluded from the publint/attw publish-hygiene scripts (they filter to sandbox+provider).

What's in the spike

  • LanguageModel over Coder AI Gateway (CoderLanguageModel): implements @effect/ai's LanguageModel.make contract on top of @coder/ai-sdk-provider. generateText, generateObject, and streamText work; construct from CoderProviderSettings or an existing CoderProvider (both auth modes preserved). The bridge core fromModel(model: LanguageModelV4) adapts any AI SDK v4-spec model, which is how the unit tests drive it with fakes.
  • Typed error taxonomy: AI SDK errors are mapped losslessly into @effect/ai's AiError union (status/headers/body preserved on HttpResponseError); classifyError recovers auth | rate-limit | provider-unavailable | malformed-response | transport | unknown, and isTransient plugs into Effect.retry.
  • Schema interop (toAiSdkSchema, toJsonSchema): Effect Schema → the AI SDK's Schema container (JSON schema derived via the same helper @effect/ai uses + validation through Effect Schema decode), accepted by tool() / generateObject.
  • Scoped sandbox Layers (acquireWorkspace/layerWorkspace, acquireSession/layerSession): ensureCoderWorkspace and createCoderWorkspace().createSession() as Effect.acquireRelease, with teardown policies that never delete a workspace the acquisition merely attached to, and release on scope close including interruption.
  • 40 unit tests (prompt/response mapping, error taxonomy, schema round-trips incl. a decode-transforming schema, acquire/release incl. release-on-interrupt and stream-abort-on-interrupt), examples that double as live scripts, package README with pinned surface + caveats, one root-README line.

Exact pins: effect@3.22.1, @effect/ai@0.37.0, @ai-sdk/provider@4.0.8.

API deltas vs. the issue sketch (implemented against @effect/ai 0.37.0 reality)

  1. AiError is a closed union (HttpRequestError | HttpResponseError | MalformedInput | MalformedOutput | UnknownError) and LanguageModel.make implementations must fail with exactly those types — the sketch's "typed AiError hierarchy (auth, quota, provider-unavailable, malformed-response)" cannot be expressed as subclasses. Instead the bridge maps into the standard union without losing information and ships classifyError/isTransient to recover that taxonomy (unit-tested both directions).
  2. Standard Schema alone is not enough for tool(): Schema.standardSchemaV1 emits no ~standard.jsonSchema converter, and AI SDK v7 throws Standard schema vendor 'effect' does not support JSON Schema conversion for it (pinned by a test). The bridge therefore emits the AI SDK's own Schema container via jsonSchema() + Effect decode instead of a bare Standard Schema.
  3. The spike depends on the published @coder/ai-sdk-* releases (exact pins), not workspace:*: this would be the repo's first cross-package workspace dependency, and CI runs typecheck/test before build, so workspace:* would break fresh-clone pnpm check. Moving to workspace:* is part of the Phase 2 publishing decision (noted in the README).
  4. JSON-mode prompt injection: the gateway's OpenAI-compatible surface falls back to schema-less json_object (rejects requests whose messages don't mention JSON). Discovered in live validation; the bridge injects the schema as a leading system instruction, the same strategy the AI SDK's own generateObject uses.
  5. Unsupported inputs fail loudly with MalformedInput (provider-defined tools, oneOf tool choice); response parts with no @effect/ai equivalent are dropped (custom, reasoning-file, tool-approval-request, non-data file payloads). Documented in the README.

Verification tiers

  • Verified live against dev.coder.com (temporary token issue-144-live, created and expired per run): generateText (text + finishReason=stop + usage), generateObject (schema-decoded object round-trip), streamText (text deltas + finish part), and error taxonomy (bogus token → real 401 → HttpResponseError classified auth).
  • Verified against source / unit tests with fakes: prompt & response mapping for all part types, tool-definition wire format, toolChoice mapping, stream part mapping, stream failure on error parts, abort-signal firing on fiber interruption, schema round-trips, and sandbox acquire/release semantics including release-on-interrupt.
  • Unit-level only (documented gap): sandbox Layers are exercised against an in-memory CoderTransport fake, not a live workspace — live provisioning costs minutes of workspace churn on dev.coder.com and the acquisition path is the sandbox package's own (already-released) ensureCoderWorkspace.

Repo touches outside packages/effect

  • .github/workflows/pr-title.yml: added effect to the allowed scopes (this PR's own title uses it).
  • pnpm-workspace.yaml: explicit msgpackr-extract: false build-script denial (optional native accelerator pulled in transitively by @effect/ai's type peers; never loaded at runtime).
  • Root README.md: one experimental-package pointer line.

📋 Phase 1 checklist mapping (issue #144)
  • packages/effect scaffold (private, excluded from release-please until graduation)
  • Effect LanguageModel implementation over @coder/ai-sdk-provider (AI Gateway): Prompt/Response mapping + typed AiError mapping for HTTP errors (closed-union delta above)
  • Standard Schema / Effect Schema interop helpers for tool definitions and structured outputs (Standard-Schema delta above)
  • Scoped Layers for workspace sandbox lifecycle (ensureCoderWorkspace + session as Effect.acquireRelease)
  • Unit tests + live validation against dev.coder.com (sandbox layers unit-level, documented gap)

Generated with mux • Model: anthropic:claude-fable-5 • Thinking: xhigh

Change-Id: I848f10cb6eb2d03e8f39c0ffb1aa813c6264a797
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I3855ff7f38213b954d3fd375ebd797ec48f84e20
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-30T12:12:27.067979Z a81f80f Manual request
🔒 Security Review Completed 2026-08-30T12:14:03.503002Z a81f80f Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: bd74e7ec5d

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bd74e7ec5d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/effect/src/sandbox.ts Outdated
Comment thread packages/effect/src/errors.ts Outdated
Comment thread packages/effect/src/language-model.ts Outdated
Change-Id: Idb5cd17a17155b9a717ccc11761a36e8e48ba472
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 7c27e84575

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7c27e84575

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/effect/src/sandbox.ts Outdated
Comment thread packages/effect/src/sandbox.ts Outdated
Comment thread packages/effect/package.json
Change-Id: I33abee1aa6bd669a0bc53db79f541f14e5d6010b
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I8c0153dc7019315ae73ad8a50246aafd4363d42c
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 4e7f24a66a

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4e7f24a66a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/pr-title.yml
Change-Id: Ia9c2a5c63ffe6795d2cd67c2d4375911ac9763fb
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: a81f80fb02

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: a81f80fb02

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33
ThomasK33 added this pull request to the merge queue Aug 30, 2026
Merged via the queue into main with commit 1dce33f Aug 30, 2026
6 checks passed
@ThomasK33
ThomasK33 deleted the issue-144-effect-bridge-spike branch August 30, 2026 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant