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

推荐订阅源

美团技术团队
N
Netflix TechBlog - Medium
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
J
Java Code Geeks
V
Visual Studio Blog
H
Help Net Security
Engineering at Meta
Engineering at Meta
Hugging Face - Blog
Hugging Face - Blog
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
博客园 - 【当耐特】
B
Blog
Stack Overflow Blog
Stack Overflow Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
GbyAI
GbyAI
博客园 - 司徒正美
博客园 - 叶小钗
Y
Y Combinator Blog
MyScale Blog
MyScale Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell

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(secrets): skip optional web fetch discovery before bi...
steipete · 2026-04-30 · via Recent Commits to openclaw:main

@@ -300,24 +300,6 @@ function readProviderKey(config: OpenClawConfig, provider: ProviderUnderTest): u

300300

return pluginConfig?.webSearch?.apiKey;

301301

}

302302303-

function expectInactiveWebFetchProviderSecretRef(params: {

304-

resolveSpy: ReturnType<typeof vi.spyOn>;

305-

metadata: Awaited<ReturnType<typeof runRuntimeWebTools>>["metadata"];

306-

context: Awaited<ReturnType<typeof runRuntimeWebTools>>["context"];

307-

}) {

308-

expect(params.resolveSpy).not.toHaveBeenCalled();

309-

expect(params.metadata.fetch.selectedProvider).toBeUndefined();

310-

expect(params.metadata.fetch.selectedProviderKeySource).toBeUndefined();

311-

expect(params.context.warnings).toEqual(

312-

expect.arrayContaining([

313-

expect.objectContaining({

314-

code: "SECRETS_REF_IGNORED_INACTIVE_SURFACE",

315-

path: "plugins.entries.firecrawl.config.webFetch.apiKey",

316-

}),

317-

]),

318-

);

319-

}

320-321303

describe("runtime web tools resolution", () => {

322304

beforeAll(async () => {

323305

secretResolve = await import("./resolve.js");

@@ -416,6 +398,105 @@ describe("runtime web tools resolution", () => {

416398

expect(resolvePluginWebFetchProvidersMock).not.toHaveBeenCalled();

417399

});

418400401+

it("skips fetch provider discovery when web fetch only configures runtime limits", async () => {

402+

const { metadata } = await runRuntimeWebTools({

403+

config: asConfig({

404+

tools: {

405+

web: {

406+

fetch: {

407+

enabled: true,

408+

maxChars: 200_000,

409+

maxCharsCap: 2_000_000,

410+

},

411+

},

412+

},

413+

plugins: {

414+

enabled: true,

415+

allow: [],

416+

entries: {},

417+

},

418+

}),

419+

env: {

420+

FIRECRAWL_API_KEY: "firecrawl-key-should-not-resolve", // pragma: allowlist secret

421+

},

422+

});

423+424+

expect(metadata.fetch.providerSource).toBe("none");

425+

expect(metadata.fetch.selectedProvider).toBeUndefined();

426+

expect(resolveBundledExplicitWebFetchProvidersFromPublicArtifactsMock).not.toHaveBeenCalled();

427+

expect(resolveBundledWebFetchProvidersFromPublicArtifactsMock).not.toHaveBeenCalled();

428+

expect(resolvePluginWebFetchProvidersMock).not.toHaveBeenCalled();

429+

});

430+431+

it("skips fetch provider discovery when web fetch is explicitly disabled", async () => {

432+

const { metadata } = await runRuntimeWebTools({

433+

config: asConfig({

434+

tools: {

435+

web: {

436+

fetch: {

437+

enabled: false,

438+

provider: "firecrawl",

439+

},

440+

},

441+

},

442+

plugins: {

443+

entries: {

444+

firecrawl: {

445+

config: {

446+

webFetch: {

447+

apiKey: { source: "env", provider: "default", id: "FIRECRAWL_API_KEY" },

448+

},

449+

},

450+

},

451+

},

452+

},

453+

}),

454+

env: {

455+

FIRECRAWL_API_KEY: "firecrawl-key-should-not-resolve", // pragma: allowlist secret

456+

},

457+

});

458+459+

expect(metadata.fetch.providerSource).toBe("none");

460+

expect(metadata.fetch.selectedProvider).toBeUndefined();

461+

expect(resolveBundledExplicitWebFetchProvidersFromPublicArtifactsMock).not.toHaveBeenCalled();

462+

expect(resolveBundledWebFetchProvidersFromPublicArtifactsMock).not.toHaveBeenCalled();

463+

expect(resolvePluginWebFetchProvidersMock).not.toHaveBeenCalled();

464+

});

465+466+

it("keeps active fetch provider SecretRefs on the discovery path", async () => {

467+

const { metadata } = await runRuntimeWebTools({

468+

config: asConfig({

469+

tools: {

470+

web: {

471+

fetch: {

472+

provider: "firecrawl",

473+

},

474+

},

475+

},

476+

plugins: {

477+

entries: {

478+

firecrawl: {

479+

config: {

480+

webFetch: {

481+

apiKey: { source: "env", provider: "default", id: "FIRECRAWL_API_KEY" },

482+

},

483+

},

484+

},

485+

},

486+

},

487+

}),

488+

env: {

489+

FIRECRAWL_API_KEY: "firecrawl-key", // pragma: allowlist secret

490+

},

491+

});

492+493+

expect(metadata.fetch.providerSource).toBe("configured");

494+

expect(metadata.fetch.selectedProvider).toBe("firecrawl");

495+

expect(resolveBundledExplicitWebFetchProvidersFromPublicArtifactsMock).toHaveBeenCalledWith({

496+

onlyPluginIds: ["firecrawl"],

497+

});

498+

});

499+419500

it("auto-selects a keyless provider when no credentials are configured", async () => {

420501

const { metadata } = await runRuntimeWebTools({

421502

config: asConfig({

@@ -969,7 +1050,13 @@ describe("runtime web tools resolution", () => {

9691050

}),

9701051

});

9711052972-

expectInactiveWebFetchProviderSecretRef({ resolveSpy, metadata, context });

1053+

expect(resolveSpy).not.toHaveBeenCalled();

1054+

expect(metadata.fetch.selectedProvider).toBeUndefined();

1055+

expect(metadata.fetch.selectedProviderKeySource).toBeUndefined();

1056+

expect(context.warnings).toEqual([]);

1057+

expect(resolveBundledExplicitWebFetchProvidersFromPublicArtifactsMock).not.toHaveBeenCalled();

1058+

expect(resolveBundledWebFetchProvidersFromPublicArtifactsMock).not.toHaveBeenCalled();

1059+

expect(resolvePluginWebFetchProvidersMock).not.toHaveBeenCalled();

9731060

});

97410619751062

it("keeps configured provider metadata and inactive warnings when search is disabled", async () => {

@@ -1151,17 +1238,18 @@ describe("runtime web tools resolution", () => {

1151123811521239

const { metadata } = await runRuntimeWebTools({

11531240

config: asConfig({

1154-

tools: {

1155-

web: {

1156-

fetch: {

1157-

enabled: true,

1241+

plugins: {

1242+

entries: {

1243+

firecrawl: {

1244+

config: {

1245+

webFetch: {

1246+

apiKey: "firecrawl-config-key",

1247+

},

1248+

},

11581249

},

11591250

},

11601251

},

11611252

}),

1162-

env: {

1163-

FIRECRAWL_API_KEY: "firecrawl-key", // pragma: allowlist secret

1164-

},

11651253

});

1166125411671255

expect(metadata.fetch.selectedProvider).toBe("firecrawl");