mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-21 17:54:23 +01:00
add provider_list
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
import { App } from "../app";
|
||||
import { Log } from "../util/log";
|
||||
import { mergeDeep } from "remeda";
|
||||
import path from "node:path";
|
||||
|
||||
import { createAnthropic } from "@ai-sdk/anthropic";
|
||||
import type { LanguageModel, Provider } from "ai";
|
||||
import { NoSuchModelError } from "ai";
|
||||
import type { Config } from "../app/config";
|
||||
import { BunProc } from "../bun";
|
||||
import { Global } from "../global";
|
||||
|
||||
export namespace LLM {
|
||||
const log = Log.create({ service: "llm" });
|
||||
@@ -14,17 +18,67 @@ export namespace LLM {
|
||||
}
|
||||
}
|
||||
|
||||
const state = App.state("llm", async (app) => {
|
||||
const providers: Provider[] = [];
|
||||
const NATIVE_PROVIDERS: Record<string, Config.Provider> = {
|
||||
anthropic: {
|
||||
models: {
|
||||
"claude-sonnet-4-20250514": {
|
||||
name: "Claude 4 Sonnet",
|
||||
cost: {
|
||||
input: 3.0,
|
||||
inputCached: 3.75,
|
||||
output: 15.0,
|
||||
outputCached: 0.3,
|
||||
},
|
||||
contextWindow: 200000,
|
||||
maxTokens: 50000,
|
||||
attachment: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (process.env["ANTHROPIC_API_KEY"] || app.config.providers?.anthropic) {
|
||||
log.info("loaded anthropic");
|
||||
const provider = createAnthropic({
|
||||
apiKey: app.config.providers?.anthropic?.apiKey,
|
||||
baseURL: app.config.providers?.anthropic?.baseURL,
|
||||
headers: app.config.providers?.anthropic?.headers,
|
||||
});
|
||||
providers.push(provider);
|
||||
const AUTODETECT: Record<string, string[]> = {
|
||||
anthropic: ["ANTHROPIC_API_KEY"],
|
||||
};
|
||||
|
||||
const state = App.state("llm", async (app) => {
|
||||
const providers: Record<
|
||||
string,
|
||||
{
|
||||
info: Config.Provider;
|
||||
instance: Provider;
|
||||
}
|
||||
> = {};
|
||||
|
||||
const list = mergeDeep(NATIVE_PROVIDERS, app.config.providers ?? {});
|
||||
|
||||
for (const [providerID, providerInfo] of Object.entries(list)) {
|
||||
if (
|
||||
!app.config.providers?.[providerID] &&
|
||||
!AUTODETECT[providerID]?.some((env) => process.env[env])
|
||||
)
|
||||
continue;
|
||||
const dir = path.join(
|
||||
Global.cache(),
|
||||
`node_modules`,
|
||||
`@ai-sdk`,
|
||||
providerID,
|
||||
);
|
||||
if (!(await Bun.file(path.join(dir, "package.json")).exists())) {
|
||||
BunProc.run(["add", "--exact", `@ai-sdk/${providerID}@alpha`], {
|
||||
cwd: Global.cache(),
|
||||
});
|
||||
}
|
||||
const mod = await import(
|
||||
path.join(Global.cache(), `node_modules`, `@ai-sdk`, providerID)
|
||||
);
|
||||
const fn = mod[Object.keys(mod).find((key) => key.startsWith("create"))!];
|
||||
const loaded = fn(providerInfo.options);
|
||||
log.info("loaded", { provider: providerID });
|
||||
providers[providerID] = {
|
||||
info: providerInfo,
|
||||
instance: loaded,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -37,23 +91,24 @@ export namespace LLM {
|
||||
return state().then((state) => state.providers);
|
||||
}
|
||||
|
||||
export async function findModel(model: string) {
|
||||
export async function findModel(providerID: string, modelID: string) {
|
||||
const key = `${providerID}/${modelID}`;
|
||||
const s = await state();
|
||||
if (s.models.has(model)) {
|
||||
return s.models.get(model)!;
|
||||
if (s.models.has(key)) return s.models.get(key)!;
|
||||
const provider = s.providers[providerID];
|
||||
if (!provider) throw new ModelNotFoundError(modelID);
|
||||
log.info("loading", {
|
||||
providerID,
|
||||
modelID,
|
||||
});
|
||||
try {
|
||||
const match = provider.instance.languageModel(modelID);
|
||||
log.info("found", { providerID, modelID });
|
||||
s.models.set(key, match);
|
||||
return match;
|
||||
} catch (e) {
|
||||
if (e instanceof NoSuchModelError) throw new ModelNotFoundError(modelID);
|
||||
throw e;
|
||||
}
|
||||
log.info("loading", { model });
|
||||
for (const provider of s.providers) {
|
||||
try {
|
||||
const match = provider.languageModel(model);
|
||||
log.info("found", { model });
|
||||
s.models.set(model, match);
|
||||
return match;
|
||||
} catch (e) {
|
||||
if (e instanceof NoSuchModelError) continue;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
throw new ModelNotFoundError(model);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user