refactor(opencode): pass prepared request to native runtime
This commit is contained in:
parent
548446a990
commit
1ecf27f389
4 changed files with 29 additions and 43 deletions
|
|
@ -220,17 +220,8 @@ const live: Layer.Layer<
|
|||
provider: item,
|
||||
auth: info,
|
||||
llmClient,
|
||||
isOpenaiOauth: prepared.isOpenaiOauth,
|
||||
system: prepared.system,
|
||||
messages: prepared.messages,
|
||||
tools: prepared.tools,
|
||||
request: prepared,
|
||||
toolChoice: input.toolChoice,
|
||||
temperature: prepared.params.temperature,
|
||||
topP: prepared.params.topP,
|
||||
topK: prepared.params.topK,
|
||||
maxOutputTokens: prepared.params.maxOutputTokens,
|
||||
providerOptions: prepared.params.options,
|
||||
headers: prepared.headers,
|
||||
abort: input.abort,
|
||||
})
|
||||
if (native.type === "supported") {
|
||||
|
|
|
|||
|
|
@ -12,26 +12,25 @@ import {
|
|||
import type { ModelMessage } from "ai"
|
||||
import type { Provider } from "@/provider/provider"
|
||||
import { isRecord } from "@/util/record"
|
||||
import type { Prepared as PreparedRequest } from "./request"
|
||||
|
||||
type ToolInput = {
|
||||
readonly description?: string
|
||||
readonly inputSchema?: unknown
|
||||
}
|
||||
|
||||
export type RequestInput = {
|
||||
type GenerationInput = Omit<PreparedRequest["params"], "options">
|
||||
|
||||
export type RequestInput = GenerationInput & {
|
||||
readonly model: Provider.Model
|
||||
readonly apiKey?: string
|
||||
readonly baseURL?: string
|
||||
readonly system?: readonly string[]
|
||||
readonly messages: readonly ModelMessage[]
|
||||
readonly system?: PreparedRequest["system"]
|
||||
readonly messages: PreparedRequest["messages"]
|
||||
readonly tools?: Record<string, ToolInput>
|
||||
readonly toolChoice?: "auto" | "required" | "none"
|
||||
readonly temperature?: number
|
||||
readonly topP?: number
|
||||
readonly topK?: number
|
||||
readonly maxOutputTokens?: number
|
||||
readonly providerOptions?: LLMRequest["providerOptions"]
|
||||
readonly headers?: Record<string, string>
|
||||
readonly headers?: PreparedRequest["headers"]
|
||||
}
|
||||
|
||||
const providerMetadata = (value: unknown): ProviderMetadata | undefined => {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@ import type { Provider } from "@/provider/provider"
|
|||
import { ProviderTransform } from "@/provider/transform"
|
||||
import { errorMessage } from "@/util/error"
|
||||
import { isRecord } from "@/util/record"
|
||||
import { asSchema, type ModelMessage, type Tool } from "ai"
|
||||
import { asSchema, type Tool } from "ai"
|
||||
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 "./native-request"
|
||||
import type { Prepared as PreparedRequest } from "./request"
|
||||
|
||||
export type RuntimeStatus =
|
||||
| { readonly type: "supported"; readonly apiKey: string; readonly baseURL?: string }
|
||||
|
|
@ -22,17 +23,13 @@ type StreamInput = {
|
|||
readonly provider: Provider.Info
|
||||
readonly auth: Auth.Info | undefined
|
||||
readonly llmClient: LLMClientShape
|
||||
readonly isOpenaiOauth: boolean
|
||||
readonly system: string[]
|
||||
readonly messages: ModelMessage[]
|
||||
readonly tools: Record<string, Tool>
|
||||
readonly request: PreparedRequest
|
||||
readonly toolChoice?: "auto" | "required" | "none"
|
||||
readonly temperature?: number
|
||||
readonly topP?: number
|
||||
readonly topK?: number
|
||||
readonly maxOutputTokens?: number
|
||||
readonly providerOptions?: Record<string, any>
|
||||
readonly headers: Record<string, string>
|
||||
readonly abort: AbortSignal
|
||||
}
|
||||
|
||||
type ToolContext = {
|
||||
readonly messages: PreparedRequest["messages"]
|
||||
readonly abort: AbortSignal
|
||||
}
|
||||
|
||||
|
|
@ -68,17 +65,18 @@ export function stream(input: StreamInput): StreamResult {
|
|||
model: input.model,
|
||||
apiKey: current.apiKey,
|
||||
baseURL: current.baseURL,
|
||||
system: input.isOpenaiOauth ? input.system : [],
|
||||
messages: ProviderTransform.message(input.messages, input.model, input.providerOptions ?? {}),
|
||||
system: [],
|
||||
messages: ProviderTransform.message(input.request.messages, input.model, input.request.params.options),
|
||||
tools: input.request.tools,
|
||||
toolChoice: input.toolChoice,
|
||||
temperature: input.temperature,
|
||||
topP: input.topP,
|
||||
topK: input.topK,
|
||||
maxOutputTokens: input.maxOutputTokens,
|
||||
providerOptions: ProviderTransform.providerOptions(input.model, input.providerOptions ?? {}),
|
||||
headers: { ...providerHeaders(input.provider.options.headers), ...input.headers },
|
||||
temperature: input.request.params.temperature,
|
||||
topP: input.request.params.topP,
|
||||
topK: input.request.params.topK,
|
||||
maxOutputTokens: input.request.params.maxOutputTokens,
|
||||
providerOptions: ProviderTransform.providerOptions(input.model, input.request.params.options),
|
||||
headers: { ...providerHeaders(input.provider.options.headers), ...input.request.headers },
|
||||
}),
|
||||
tools: nativeTools(input.tools, input),
|
||||
tools: nativeTools(input.request.tools, { messages: input.request.messages, abort: input.abort }),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
@ -97,7 +95,7 @@ function nativeSchema(value: unknown): JsonSchema {
|
|||
return asSchema(value as Parameters<typeof asSchema>[0]).jsonSchema as JsonSchema
|
||||
}
|
||||
|
||||
export function nativeTools(tools: Record<string, Tool>, input: Pick<StreamInput, "messages" | "abort">) {
|
||||
export function nativeTools(tools: Record<string, Tool>, input: ToolContext) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(tools).map(([name, item]) => [
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ type PrepareInput = {
|
|||
}
|
||||
|
||||
export type Prepared = {
|
||||
readonly isOpenaiOauth: boolean
|
||||
readonly system: string[]
|
||||
readonly messages: ModelMessage[]
|
||||
readonly tools: Record<string, Tool>
|
||||
|
|
@ -123,7 +122,7 @@ export const prepare = Effect.fn("LLMRequestPrep.prepare")(function* (input: Pre
|
|||
},
|
||||
)
|
||||
|
||||
const { headers } = yield* input.plugin.trigger(
|
||||
const { headers: pluginHeaders } = yield* input.plugin.trigger(
|
||||
"chat.headers",
|
||||
{
|
||||
sessionID: input.sessionID,
|
||||
|
|
@ -161,7 +160,6 @@ export const prepare = Effect.fn("LLMRequestPrep.prepare")(function* (input: Pre
|
|||
: undefined
|
||||
|
||||
return {
|
||||
isOpenaiOauth,
|
||||
system,
|
||||
messages,
|
||||
tools: Object.fromEntries(Object.entries(tools).toSorted(([a], [b]) => a.localeCompare(b))),
|
||||
|
|
@ -182,7 +180,7 @@ export const prepare = Effect.fn("LLMRequestPrep.prepare")(function* (input: Pre
|
|||
"User-Agent": USER_AGENT,
|
||||
}),
|
||||
...input.model.headers,
|
||||
...headers,
|
||||
...pluginHeaders,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue