惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
人人都是产品经理
人人都是产品经理
V
Visual Studio Blog
Last Week in AI
Last Week in AI
V
V2EX
博客园_首页
IT之家
IT之家
Jina AI
Jina AI
博客园 - 叶小钗
The Cloudflare Blog
T
Tailwind CSS Blog
腾讯CDC
B
Blog
D
Docker
L
LangChain Blog
博客园 - 司徒正美
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
GbyAI
GbyAI

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
Fix Ollama cloud API key discovery (#85091) · openclaw/op...
clawsweeper · 2026-05-22 · via Recent Commits to openclaw:main

@@ -57,7 +57,11 @@ describe("Ollama provider", () => {

5757

}

5858

}

595960-

async function runOllamaCatalog(params: { config?: OpenClawConfig; env?: NodeJS.ProcessEnv }) {

60+

async function runOllamaCatalog(params: {

61+

config?: OpenClawConfig;

62+

env?: NodeJS.ProcessEnv;

63+

resolveProviderApiKey?: () => { apiKey: string | undefined; discoveryApiKey?: string };

64+

}) {

6165

const env: NodeJS.ProcessEnv = {

6266

...process.env,

6367

VITEST: "1",

@@ -68,9 +72,11 @@ describe("Ollama provider", () => {

6872

config: params.config ?? {},

6973

agentDir: createAgentDir(),

7074

env,

71-

resolveProviderApiKey: () => ({

72-

apiKey: env.OLLAMA_API_KEY?.trim() ? env.OLLAMA_API_KEY : undefined,

73-

}),

75+

resolveProviderApiKey:

76+

params.resolveProviderApiKey ??

77+

(() => ({

78+

apiKey: env.OLLAMA_API_KEY?.trim() ? env.OLLAMA_API_KEY : undefined,

79+

})),

7480

resolveProviderAuth: () => ({

7581

apiKey: env.OLLAMA_API_KEY?.trim() ? env.OLLAMA_API_KEY : undefined,

7682

mode: env.OLLAMA_API_KEY?.trim() ? "api_key" : "none",

@@ -480,6 +486,131 @@ describe("Ollama provider", () => {

480486

});

481487

});

482488489+

it("uses resolved discovery api key when configured cloud apiKey is an env marker", async () => {

490+

await withoutAmbientOllamaEnv(async () => {

491+

const fetchMock = vi.fn();

492+

vi.stubGlobal("fetch", withFetchPreconnect(fetchMock));

493+494+

const provider = await runOllamaCatalog({

495+

config: {

496+

models: {

497+

providers: {

498+

ollama: {

499+

baseUrl: "https://ollama.com/v1",

500+

models: [

501+

{

502+

id: "gpt-oss:20b",

503+

name: "GPT-OSS 20B",

504+

reasoning: false,

505+

input: ["text"],

506+

cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

507+

contextWindow: 8192,

508+

maxTokens: 81920,

509+

},

510+

],

511+

apiKey: "OLLAMA_API_KEY",

512+

},

513+

},

514+

},

515+

},

516+

env: { OLLAMA_API_KEY: "real-secret", VITEST: "", NODE_ENV: "development" },

517+

resolveProviderApiKey: () => ({

518+

apiKey: "OLLAMA_API_KEY",

519+

discoveryApiKey: "real-secret",

520+

}),

521+

});

522+523+

expect(fetchMock).not.toHaveBeenCalled();

524+

expect(provider?.baseUrl).toBe("https://ollama.com");

525+

expect(provider?.api).toBe("ollama");

526+

expect(provider?.apiKey).toBe("real-secret");

527+

expect(provider?.models).toHaveLength(1);

528+

});

529+

});

530+531+

it("uses resolved discovery api key for configured cloud providers without apiKey", async () => {

532+

await withoutAmbientOllamaEnv(async () => {

533+

const fetchMock = vi.fn();

534+

vi.stubGlobal("fetch", withFetchPreconnect(fetchMock));

535+536+

const provider = await runOllamaCatalog({

537+

config: {

538+

models: {

539+

providers: {

540+

ollama: {

541+

baseUrl: "https://ollama.com/v1",

542+

models: [

543+

{

544+

id: "gpt-oss:20b",

545+

name: "GPT-OSS 20B",

546+

reasoning: false,

547+

input: ["text"],

548+

cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

549+

contextWindow: 8192,

550+

maxTokens: 81920,

551+

},

552+

],

553+

},

554+

},

555+

},

556+

},

557+

env: { OLLAMA_API_KEY: "real-secret", VITEST: "", NODE_ENV: "development" },

558+

resolveProviderApiKey: () => ({

559+

apiKey: "OLLAMA_API_KEY",

560+

discoveryApiKey: "real-secret",

561+

}),

562+

});

563+564+

expect(fetchMock).not.toHaveBeenCalled();

565+

expect(provider?.baseUrl).toBe("https://ollama.com");

566+

expect(provider?.api).toBe("ollama");

567+

expect(provider?.apiKey).toBe("real-secret");

568+

expect(provider?.models).toHaveLength(1);

569+

});

570+

});

571+572+

it("keeps synthetic local auth when a local provider also has a discovery key", async () => {

573+

await withoutAmbientOllamaEnv(async () => {

574+

const fetchMock = vi.fn();

575+

vi.stubGlobal("fetch", withFetchPreconnect(fetchMock));

576+577+

const provider = await runOllamaCatalog({

578+

config: {

579+

models: {

580+

providers: {

581+

ollama: {

582+

baseUrl: "http://127.0.0.1:11434/v1",

583+

models: [

584+

{

585+

id: "gpt-oss:20b",

586+

name: "GPT-OSS 20B",

587+

reasoning: false,

588+

input: ["text"],

589+

cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

590+

contextWindow: 8192,

591+

maxTokens: 81920,

592+

},

593+

],

594+

apiKey: "OLLAMA_API_KEY",

595+

},

596+

},

597+

},

598+

},

599+

env: { OLLAMA_API_KEY: "real-secret", VITEST: "", NODE_ENV: "development" },

600+

resolveProviderApiKey: () => ({

601+

apiKey: "OLLAMA_API_KEY",

602+

discoveryApiKey: "real-secret",

603+

}),

604+

});

605+606+

expect(fetchMock).not.toHaveBeenCalled();

607+

expect(provider?.baseUrl).toBe("http://127.0.0.1:11434");

608+

expect(provider?.api).toBe("ollama");

609+

expect(provider?.apiKey).toBe(OLLAMA_LOCAL_AUTH_MARKER);

610+

expect(provider?.models).toHaveLength(1);

611+

});

612+

});

613+483614

it("should preserve explicit apiKey from configured remote providers", async () => {

484615

await withoutAmbientOllamaEnv(async () => {

485616

const fetchMock = vi.fn(async (input: unknown) => {