diff --git a/packages/opencode/src/session/llm.ts b/packages/opencode/src/session/llm.ts index a6aea4ffbc..87d2e3973d 100644 --- a/packages/opencode/src/session/llm.ts +++ b/packages/opencode/src/session/llm.ts @@ -27,8 +27,8 @@ import { InstallationVersion } from "@opencode-ai/core/installation/version" import { EffectBridge } from "@/effect/bridge" import * as Option from "effect/Option" import * as OtelTracer from "@effect/opentelemetry/Tracer" -import { LLMAISDK } from "./llm-ai-sdk" -import { LLMNativeRuntime } from "./llm-native-runtime" +import { LLMAISDK } from "./llm/ai-sdk" +import { LLMNativeRuntime } from "./llm/native-runtime" const log = Log.create({ service: "llm" }) export const OUTPUT_TOKEN_MAX = ProviderTransform.OUTPUT_TOKEN_MAX diff --git a/packages/opencode/src/session/llm/README.md b/packages/opencode/src/session/llm/README.md new file mode 100644 index 0000000000..139db3a52e --- /dev/null +++ b/packages/opencode/src/session/llm/README.md @@ -0,0 +1,16 @@ +# Session LLM Runtime Boundaries + +`../llm.ts` is the opencode session LLM service. It owns opencode concerns: auth, config, model/provider resolution, plugins, permissions, telemetry headers, and runtime selection. + +This folder contains adapters behind that service boundary: + +- `ai-sdk.ts` converts AI SDK `fullStream` parts into `@opencode-ai/llm` `LLMEvent`s. This is the default runtime path. +- `native-request.ts` converts opencode's normalized session input into a native `@opencode-ai/llm` `LLMRequest`. It does not execute requests. +- `native-runtime.ts` is the opt-in native runtime adapter. It decides whether a selected model is supported, builds the native request, bridges opencode tools into native executable tools, and delegates transport to `LLMClient` / `RequestExecutor`. + +Safety boundary: + +- AI SDK remains the default. +- `OPENCODE_LLM_RUNTIME=native` is an opt-in hint, not a global replacement. +- Native execution currently runs only for OpenAI API-key auth via `@ai-sdk/openai`. +- Unsupported providers, OpenAI OAuth, and missing API-key cases fall back to AI SDK. diff --git a/packages/opencode/src/session/llm-ai-sdk.ts b/packages/opencode/src/session/llm/ai-sdk.ts similarity index 99% rename from packages/opencode/src/session/llm-ai-sdk.ts rename to packages/opencode/src/session/llm/ai-sdk.ts index 3c1b38cda5..8c428add65 100644 --- a/packages/opencode/src/session/llm-ai-sdk.ts +++ b/packages/opencode/src/session/llm/ai-sdk.ts @@ -231,4 +231,4 @@ export function toLLMEvents( } } -export * as LLMAISDK from "./llm-ai-sdk" +export * as LLMAISDK from "./ai-sdk" diff --git a/packages/opencode/src/session/llm-native.ts b/packages/opencode/src/session/llm/native-request.ts similarity index 99% rename from packages/opencode/src/session/llm-native.ts rename to packages/opencode/src/session/llm/native-request.ts index 22725e9e76..ca3ddef173 100644 --- a/packages/opencode/src/session/llm-native.ts +++ b/packages/opencode/src/session/llm/native-request.ts @@ -185,4 +185,4 @@ export const request = (input: RequestInput) => { }) } -export * as LLMNative from "./llm-native" +export * as LLMNative from "./native-request" diff --git a/packages/opencode/src/session/llm-native-runtime.ts b/packages/opencode/src/session/llm/native-runtime.ts similarity index 97% rename from packages/opencode/src/session/llm-native-runtime.ts rename to packages/opencode/src/session/llm/native-runtime.ts index ba2f1a648e..a57a84c7cc 100644 --- a/packages/opencode/src/session/llm-native-runtime.ts +++ b/packages/opencode/src/session/llm/native-runtime.ts @@ -7,7 +7,7 @@ import { Effect } from "effect" import * as Stream from "effect/Stream" import { tool as nativeTool, ToolFailure, type JsonSchema, type LLMEvent } from "@opencode-ai/llm" import type { LLMClientShape } from "@opencode-ai/llm/route" -import { LLMNative } from "./llm-native" +import { LLMNative } from "./native-request" export type RuntimeStatus = | { readonly type: "supported"; readonly apiKey: string; readonly baseURL?: string } @@ -112,4 +112,4 @@ function nativeTools(tools: Record, input: Pick