mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 11:31:23 +00:00
Merge PR #8868: add Baidu Qianfan support (thanks @ide-rea)
This commit is contained in:
@@ -257,6 +257,30 @@ describe("getApiKeyForModel", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("resolves Qianfan API key from env", async () => {
|
||||
const previous = process.env.QIANFAN_API_KEY;
|
||||
|
||||
try {
|
||||
process.env.QIANFAN_API_KEY = "qianfan-test-key";
|
||||
|
||||
vi.resetModules();
|
||||
const { resolveApiKeyForProvider } = await import("./model-auth.js");
|
||||
|
||||
const resolved = await resolveApiKeyForProvider({
|
||||
provider: "qianfan",
|
||||
store: { version: 1, profiles: {} },
|
||||
});
|
||||
expect(resolved.apiKey).toBe("qianfan-test-key");
|
||||
expect(resolved.source).toContain("QIANFAN_API_KEY");
|
||||
} finally {
|
||||
if (previous === undefined) {
|
||||
delete process.env.QIANFAN_API_KEY;
|
||||
} else {
|
||||
process.env.QIANFAN_API_KEY = previous;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("resolves Vercel AI Gateway API key from env", async () => {
|
||||
const previousGatewayKey = process.env.AI_GATEWAY_API_KEY;
|
||||
|
||||
|
||||
@@ -302,6 +302,7 @@ export function resolveEnvApiKey(provider: string): EnvApiKeyResult | null {
|
||||
venice: "VENICE_API_KEY",
|
||||
mistral: "MISTRAL_API_KEY",
|
||||
opencode: "OPENCODE_API_KEY",
|
||||
qianfan: "QIANFAN_API_KEY",
|
||||
ollama: "OLLAMA_API_KEY",
|
||||
};
|
||||
const envVar = envMap[normalized];
|
||||
|
||||
25
src/agents/models-config.providers.qianfan.test.ts
Normal file
25
src/agents/models-config.providers.qianfan.test.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { mkdtempSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveImplicitProviders } from "./models-config.providers.js";
|
||||
|
||||
describe("Qianfan provider", () => {
|
||||
it("should include qianfan when QIANFAN_API_KEY is configured", async () => {
|
||||
const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-"));
|
||||
const previous = process.env.QIANFAN_API_KEY;
|
||||
process.env.QIANFAN_API_KEY = "test-key";
|
||||
|
||||
try {
|
||||
const providers = await resolveImplicitProviders({ agentDir });
|
||||
expect(providers?.qianfan).toBeDefined();
|
||||
expect(providers?.qianfan?.apiKey).toBe("QIANFAN_API_KEY");
|
||||
} finally {
|
||||
if (previous === undefined) {
|
||||
delete process.env.QIANFAN_API_KEY;
|
||||
} else {
|
||||
process.env.QIANFAN_API_KEY = previous;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -80,6 +80,17 @@ const OLLAMA_DEFAULT_COST = {
|
||||
cacheWrite: 0,
|
||||
};
|
||||
|
||||
export const QIANFAN_BASE_URL = "https://qianfan.baidubce.com/v2";
|
||||
export const QIANFAN_DEFAULT_MODEL_ID = "deepseek-v3.2";
|
||||
const QIANFAN_DEFAULT_CONTEXT_WINDOW = 98304;
|
||||
const QIANFAN_DEFAULT_MAX_TOKENS = 32768;
|
||||
const QIANFAN_DEFAULT_COST = {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
};
|
||||
|
||||
interface OllamaModel {
|
||||
name: string;
|
||||
modified_at: string;
|
||||
@@ -403,6 +414,33 @@ async function buildOllamaProvider(): Promise<ProviderConfig> {
|
||||
};
|
||||
}
|
||||
|
||||
export function buildQianfanProvider(): ProviderConfig {
|
||||
return {
|
||||
baseUrl: QIANFAN_BASE_URL,
|
||||
api: "openai-completions",
|
||||
models: [
|
||||
{
|
||||
id: QIANFAN_DEFAULT_MODEL_ID,
|
||||
name: "DEEPSEEK V3.2",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: QIANFAN_DEFAULT_COST,
|
||||
contextWindow: QIANFAN_DEFAULT_CONTEXT_WINDOW,
|
||||
maxTokens: QIANFAN_DEFAULT_MAX_TOKENS,
|
||||
},
|
||||
{
|
||||
id: "ernie-5.0-thinking-preview",
|
||||
name: "ERNIE-5.0-Thinking-Preview",
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
cost: QIANFAN_DEFAULT_COST,
|
||||
contextWindow: 119000,
|
||||
maxTokens: 64000,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export async function resolveImplicitProviders(params: {
|
||||
agentDir: string;
|
||||
}): Promise<ModelsConfig["providers"]> {
|
||||
@@ -498,6 +536,13 @@ export async function resolveImplicitProviders(params: {
|
||||
providers.ollama = { ...(await buildOllamaProvider()), apiKey: ollamaKey };
|
||||
}
|
||||
|
||||
const qianfanKey =
|
||||
resolveEnvApiKeyVarName("qianfan") ??
|
||||
resolveApiKeyFromProfiles({ provider: "qianfan", store: authStore });
|
||||
if (qianfanKey) {
|
||||
providers.qianfan = { ...buildQianfanProvider(), apiKey: qianfanKey };
|
||||
}
|
||||
|
||||
return providers;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user