Provider packages in @opencode-ai/llm/providers/* now implement a uniform ProviderPackage contract: model(modelID, settings) => Model. SessionRunnerModel becomes provider-agnostic: it resolves a package specifier, folds catalog settings, credentials, and transport overlays into one Settings object, and delegates request construction to the package. - llm: add ProviderPackage (Settings, Definition, define), flat model(id, config) constructors on the openai-responses, anthropic-messages, and openai-compatible-chat protocols, contract-shaped model exports on the openai, anthropic, and openai-compatible providers, and a new providers/openai/codex entry point that targets the ChatGPT codex backend and sets the chatgpt-account-id header from settings.accountID. - schema: Provider.Native gains optional package. - core: SessionRunnerModel loads packages through a static built-in map (dynamic import for foreign specifiers) and applies one settings fold; the ChatGPT conditional is deleted from the runner. The OpenAI plugin's catalog transform now assigns the codex package to eligible models when a ChatGPT connection is active, alongside the existing eligibility and cost rewrites. - llm schema: hoist ToolResultValue union out of its Object.assign self reference; the previous shape only typechecked under lucky check ordering and broke under core's typecheck with the new import graph. Closes #34765
@opencode-ai/client
Private generation target for clients derived directly from OpenCode's authoritative Effect HttpApi.
Entrypoints
@opencode-ai/client: zero-Effect Promise client usingfetch.@opencode-ai/client/effect: rich Effect network client using an environment-providedHttpClient.
The generated surface includes every standard HTTP group from Server's concrete API. The build compiler reads @opencode-ai/server/api; the generated Effect runtime imports a client-local projection built from Protocol, with a generation-equivalence test preventing transport drift. Custom transports such as the PTY WebSocket connection remain outside the generic HTTP client. Run bun run generate after changing the contract and bun run check:generated to detect committed-output drift.
The Effect entrypoint uses canonical decoded values such as Session.ID, Location.Ref, and Prompt. These datatypes come from the lightweight @opencode-ai/schema package and are re-exported so callers depend only on the client surface. Protocol owns endpoint construction and middleware placement; Server supplies the concrete middleware keys used by the build-time API.
The Promise root remains structural and has no Core or Effect runtime dependency. /effect depends only on Effect, Schema, and Protocol and is browser-bundle safe. Bundle-boundary tests enforce both import graphs.
Effect consumers construct canonical decoded inputs:
import { AbsolutePath, Location, OpenCode, Prompt } from "@opencode-ai/client/effect"
const client = yield * OpenCode.make({ baseUrl: "https://opencode.example" })
yield *
client.sessions.create({
location: Location.Ref.make({ directory: AbsolutePath.make("/workspace") }),
})
yield * client.sessions.prompt({ sessionID, prompt: Prompt.make({ text: "Hello" }) })