refactor(llm): organize runtime adapters

This commit is contained in:
Kit Langton
2026-05-12 22:06:17 -04:00
parent 326b79a6b0
commit 2f7791c0f3
6 changed files with 24 additions and 8 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -231,4 +231,4 @@ export function toLLMEvents(
}
}
export * as LLMAISDK from "./llm-ai-sdk"
export * as LLMAISDK from "./ai-sdk"

View File

@@ -185,4 +185,4 @@ export const request = (input: RequestInput) => {
})
}
export * as LLMNative from "./llm-native"
export * as LLMNative from "./native-request"

View File

@@ -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<string, Tool>, input: Pick<StreamInput, "mess
)
}
export * as LLMNativeRuntime from "./llm-native-runtime"
export * as LLMNativeRuntime from "./native-runtime"

View File

@@ -2,8 +2,8 @@ import { describe, expect, test } from "bun:test"
import { LLMClient, RequestExecutor } from "@opencode-ai/llm/route"
import { jsonSchema, tool, type ModelMessage } from "ai"
import { Effect } from "effect"
import { LLMNative } from "@/session/llm-native"
import { LLMNativeRuntime } from "@/session/llm-native-runtime"
import { LLMNative } from "@/session/llm/native-request"
import { LLMNativeRuntime } from "@/session/llm/native-runtime"
import type { Provider } from "@/provider/provider"
import { ModelID, ProviderID } from "@/provider/schema"