refactor(llm): simplify provider resolver defaults
This commit is contained in:
@@ -8,7 +8,7 @@ export interface ProviderResolution {
|
||||
readonly provider: ProviderIDType
|
||||
readonly protocol: Protocol
|
||||
readonly baseURL?: string
|
||||
readonly auth?: ProviderAuth
|
||||
readonly auth: ProviderAuth
|
||||
readonly capabilities?: CapabilitiesInput
|
||||
}
|
||||
|
||||
@@ -26,10 +26,11 @@ export interface ProviderResolver {
|
||||
export const make = (
|
||||
provider: string | ProviderIDType,
|
||||
protocol: Protocol,
|
||||
options: Omit<ProviderResolution, "provider" | "protocol"> = {},
|
||||
options: Partial<Omit<ProviderResolution, "provider" | "protocol">> = {},
|
||||
): ProviderResolution => ({
|
||||
provider: ProviderID.make(provider),
|
||||
protocol,
|
||||
auth: options.auth ?? "bearer",
|
||||
...options,
|
||||
})
|
||||
|
||||
@@ -38,7 +39,7 @@ export const define = (input: ProviderResolver): ProviderResolver => input
|
||||
export const fixed = (
|
||||
provider: string | ProviderIDType,
|
||||
protocol: Protocol,
|
||||
options: Omit<ProviderResolution, "provider" | "protocol"> = {},
|
||||
options: Partial<Omit<ProviderResolution, "provider" | "protocol">> = {},
|
||||
): ProviderResolver => {
|
||||
const resolution = make(provider, protocol, options)
|
||||
return define({ id: resolution.provider, resolve: () => resolution })
|
||||
|
||||
@@ -18,8 +18,15 @@ export const byProvider: Record<string, ProviderFamily> = Object.fromEntries(
|
||||
Object.values(families).map((family) => [family.provider, family]),
|
||||
)
|
||||
|
||||
const resolutions = Object.fromEntries(
|
||||
Object.values(families).map((family) => [
|
||||
family.provider,
|
||||
ProviderResolver.make(family.provider, "openai-compatible-chat", { baseURL: family.baseURL }),
|
||||
]),
|
||||
)
|
||||
|
||||
export const resolve = (provider: string) =>
|
||||
ProviderResolver.make(provider, "openai-compatible-chat", { baseURL: byProvider[provider]?.baseURL, auth: "bearer" })
|
||||
resolutions[provider] ?? ProviderResolver.make(provider, "openai-compatible-chat")
|
||||
|
||||
export const resolver = ProviderResolver.define({
|
||||
id: ProviderResolver.make("openai-compatible", "openai-compatible-chat").provider,
|
||||
|
||||
@@ -65,7 +65,7 @@ const baseURL = (input: Input, resolution: ProviderResolution, options: Record<s
|
||||
return resolution.baseURL
|
||||
}
|
||||
|
||||
const authHeader = (auth: ProviderAuth | undefined, apiKey: string | undefined): Record<string, string> => {
|
||||
const authHeader = (auth: ProviderAuth, apiKey: string | undefined): Record<string, string> => {
|
||||
if (!apiKey) return {}
|
||||
if (auth === "none") return {}
|
||||
if (auth === "anthropic-api-key") return { "x-api-key": apiKey }
|
||||
@@ -87,7 +87,7 @@ const reasoningEfforts = (input: Input) =>
|
||||
REASONING_EFFORTS.has(effort as ReasoningEffort),
|
||||
)
|
||||
|
||||
const mergeCapabilities = (base: CapabilitiesInput, override: CapabilitiesInput | undefined): CapabilitiesInput => ({
|
||||
const mergeCapabilities = (base: CapabilitiesInput, override: CapabilitiesInput): CapabilitiesInput => ({
|
||||
input: { ...base.input, ...override?.input },
|
||||
output: { ...base.output, ...override?.output },
|
||||
tools: { ...base.tools, ...override?.tools },
|
||||
@@ -95,41 +95,38 @@ const mergeCapabilities = (base: CapabilitiesInput, override: CapabilitiesInput
|
||||
reasoning: { ...base.reasoning, ...override?.reasoning },
|
||||
})
|
||||
|
||||
const capabilities = (input: Input, resolution: ProviderResolution) =>
|
||||
LLM.capabilities(
|
||||
mergeCapabilities(
|
||||
{
|
||||
input: {
|
||||
text: input.model.capabilities.input.text,
|
||||
image: input.model.capabilities.input.image,
|
||||
audio: input.model.capabilities.input.audio,
|
||||
video: input.model.capabilities.input.video,
|
||||
pdf: input.model.capabilities.input.pdf,
|
||||
},
|
||||
output: {
|
||||
text: input.model.capabilities.output.text,
|
||||
reasoning: input.model.capabilities.reasoning,
|
||||
},
|
||||
tools: {
|
||||
calls: input.model.capabilities.toolcall,
|
||||
streamingInput: resolution.protocol !== "gemini" && input.model.capabilities.toolcall,
|
||||
},
|
||||
cache: {
|
||||
// Both Anthropic Messages and Bedrock Converse honour positional cache
|
||||
// markers — Anthropic via `cache_control` on content blocks, Bedrock via
|
||||
// its `cachePoint` marker block (added to BedrockConverse in 9d7d518ac).
|
||||
prompt: ["anthropic-messages", "bedrock-converse"].includes(resolution.protocol),
|
||||
contentBlocks: ["anthropic-messages", "bedrock-converse"].includes(resolution.protocol),
|
||||
},
|
||||
reasoning: {
|
||||
efforts: reasoningEfforts(input),
|
||||
summaries: resolution.protocol === "openai-responses",
|
||||
encryptedContent: resolution.protocol === "openai-responses" || resolution.protocol === "anthropic-messages",
|
||||
},
|
||||
},
|
||||
resolution.capabilities,
|
||||
),
|
||||
)
|
||||
const capabilities = (input: Input, resolution: ProviderResolution) => {
|
||||
const base: CapabilitiesInput = {
|
||||
input: {
|
||||
text: input.model.capabilities.input.text,
|
||||
image: input.model.capabilities.input.image,
|
||||
audio: input.model.capabilities.input.audio,
|
||||
video: input.model.capabilities.input.video,
|
||||
pdf: input.model.capabilities.input.pdf,
|
||||
},
|
||||
output: {
|
||||
text: input.model.capabilities.output.text,
|
||||
reasoning: input.model.capabilities.reasoning,
|
||||
},
|
||||
tools: {
|
||||
calls: input.model.capabilities.toolcall,
|
||||
streamingInput: resolution.protocol !== "gemini" && input.model.capabilities.toolcall,
|
||||
},
|
||||
cache: {
|
||||
// Both Anthropic Messages and Bedrock Converse honour positional cache
|
||||
// markers — Anthropic via `cache_control` on content blocks, Bedrock via
|
||||
// its `cachePoint` marker block (added to BedrockConverse in 9d7d518ac).
|
||||
prompt: ["anthropic-messages", "bedrock-converse"].includes(resolution.protocol),
|
||||
contentBlocks: ["anthropic-messages", "bedrock-converse"].includes(resolution.protocol),
|
||||
},
|
||||
reasoning: {
|
||||
efforts: reasoningEfforts(input),
|
||||
summaries: resolution.protocol === "openai-responses",
|
||||
encryptedContent: resolution.protocol === "openai-responses" || resolution.protocol === "anthropic-messages",
|
||||
},
|
||||
}
|
||||
return LLM.capabilities(resolution.capabilities ? mergeCapabilities(base, resolution.capabilities) : base)
|
||||
}
|
||||
|
||||
export const toModelRef = (input: Input): ModelRef | undefined => {
|
||||
const options = { ...input.provider.options, ...input.model.options }
|
||||
|
||||
Reference in New Issue
Block a user