Dashboard › opencode › Distillation
8a118686-cb44-4335-b19c-a8e21ed77228["lore_tm_v1_TSAiNS_UueifPVqIBsFWp6Mkiui9wzgn8-ftfJtvqGE","lore_tm_v1_5L_MnM1wkMa-Z8wnvRsIsklJJSdScDVZP-ttF_tcc_o","lore_tm_v1_IJEzG-xIlQmKVKqIbvA9AoqMhCCvnP3N5jfF1dg_xGc"]
AIError wraps a union of tagged reason errors, stores only reason, derives message from that reason, and exposes the reason as its cause.AIError reason owns its readable message, category-specific fields, optional body, optional http, and any underlying exception in cause.reason.body is the sole field for the original response or triggering-event payload; original text must be preserved before schema decoding removes fields, and implementations must not replace the complete event with only its nested error.reason.http represents an observed HTTP response and requires url, status, and response headers; implementations must not invent status codes or derive a separate request ID from headers.body, HTTP context, and underlying cause. Because message and cause are non-enumerable, they must be copied explicitly when enriching a reason through its constructor or AIErrorReason.make.LLMEvent streams with camelCase LLMEvent.is.* guards, e.g. events.filter(LLMEvent.is.toolCall). LLMEvent.guards["tool-call"] remains supported, but is not preferred for new code.Protocol in src/route/protocol.ts as the semantic API contract responsible for request-body construction via body.from, body validation through body.schema, streaming-event decoding through stream.event, and the event-to-LLMEvent state machine in stream.step. Route.make(...) validates and JSON-encodes using body.schema and decodes frames using stream.event. Examples: OpenAIChat.protocol, OpenResponses.protocol, OpenAIResponses.protocol, AnthropicMessages.protocol, Gemini.protocol, and BedrockConverse.protocol.Endpoint in src/route/endpoint.ts as URL construction, owning the host, path, and route query. The common form is Endpoint.path("/chat/completions", { baseURL }); function paths are used when the path embeds a model ID or body field, e.g. Endpoint.path(({ body }) => \/model/${body.modelId}/converse-stream`)`.Auth in src/route/auth.ts as per-request transport authentication. Provider facades normally configure credentials with Auth.bearer(apiKey) or Auth.header(name, apiKey) before model selection; Bedrock SigV4, future Vertex IAM, and Azure AAD routes use a function-form Auth that signs the body and merges signed headers.Framing in src/route/framing.ts as bytes-to-frames conversion. Framing.sse is shared, while Bedrock keeps AWS event-stream framing as a typed Framing<object> value alongside its protocol.headers, limits, generation, providerOptions, and http; endpoint host/query belongs on the route endpoint.LanguageModel values contain only the model ID, provider ID, and configured route value. Model capability/catalog metadata lives outside the package, while protocol support is enforced through request lowering and typed AIErrors.ProviderID.make(...) and ModelID.make(...) where IDs are constructed directly.model represents the default API path, while provider-native alternatives use named methods such as OpenAI responses and chat..configure(...) and rejects adding model(id, overrides) as a duplicate construction path.routes arrays should be exported separately only when advanced internal wiring requires them.apiKey as provider-specific sugar and auth as the explicit override; provider option types must keep them mutually exclusive using ProviderAuthOption.apiKey to Auth using AuthOptions.bearer(options, "<PROVIDER>_API_KEY"). It honors explicit auth, otherwise falls back to Auth.config(envVar), ensuring missing keys produce a typed Authentication error rather than a runtime crash.CloudflareAIGateway and CloudflareWorkersAI.@opencode/ai; these are internal entrypoints within one npm package, not separately published provider packages.ProviderPackage.Definition and exposes model(modelID, settings), where settings contains serializable provider configuration plus common headers, body, and limits overlays.chat and responses.StreamOptions without changing model or route identity.providers/*.ts imports protocol routes and auth-option utilities; protocol modules import endpoint, auth, framing, and transport pieces; protocols do not import provider facades; lower-level modules know nothing about provider catalog metadata.OpenAIResponses composes the provider-neutral OpenResponses protocol, and the baseline never imports the OpenAI extension.request.tools without a runtime entry. The matching route must lower each tool definition into the provider-native representation; Anthropic currently accepts web_search, code_execution, and web_fetch, while OpenAI Responses accepts its hosted tool names.RECORD=true records fresh cassettes locally and requires the listed environment variables; CI must be unset before recording because CI always forces replay; cassettes are pretty-printed JSON to keep multi-interaction diffs reviewable./home/byk/Code/opencode-v2-pilot/packages/plugin/src/app.ts defines export interface App with 3 readonly string fields: name, version, and channel; the file is 5 lines long./home/byk/Code/opencode-lore: packages/gateway/src/server.ts lines 766 and 1300 (stop); packages/gateway/src/pipeline.ts lines 1268, 5623, 5822, 5831, and 5921 (expectedUnowned); packages/gateway/src/cli/start.ts lines 108, 112, 865, 868, 982, 1010, 1239, and 1268 (GatewayHandle, owned, startGateway); packages/gateway/src/cli/main.ts line 436 (stop migration comment); packages/gateway/src/cli/app.ts line 117 (stopCommand); packages/gateway/src/cli/run.ts line 404 (let owned: boolean); packages/gateway/src/cli/login.ts lines 514 and 571 (done.close); and packages/gateway/src/translate/types.ts line 785 (gateway-owned body encoding).