Skip to content

Fix Tavily tool SecretRef runtime config#78610

Merged
vincentkoc merged 1 commit intoopenclaw:mainfrom
VACInc:tavily-secretref-runtime-config
May 7, 2026
Merged

Fix Tavily tool SecretRef runtime config#78610
vincentkoc merged 1 commit intoopenclaw:mainfrom
VACInc:tavily-secretref-runtime-config

Conversation

@VACInc
Copy link
Copy Markdown
Contributor

@VACInc VACInc commented May 6, 2026

Summary

  • register Tavily's dedicated tools as runtime-context factories instead of one-time objects bound to plugin-load config
  • resolve tavily_search and tavily_extract credentials from the active runtime config snapshot when available
  • add a regression test for raw exec SecretRef source config plus resolved runtime config

Real Behavior Proof

Behavior or issue addressed: Dedicated Tavily tools were created from plugin-load api.config, so a configured exec SecretRef could remain raw even when the active runtime snapshot already had the resolved Tavily API key.

Real environment tested: Separate temp OpenClaw worktree at /tmp/openclaw-tavily-secretref.ILwex2, Node 25.9.0, pnpm 10.33.2, branch tavily-secretref-runtime-config, using the real resolvePluginTools path with a raw source config and a resolved runtime config snapshot.

Exact steps or command run after this patch: Ran the real plugin tool resolver with env -u TAVILY_API_KEY pnpm exec tsx -e ..., where source config contained plugins.entries.tavily.config.webSearch.apiKey = { source: "exec", provider: "default", id: "printf resolved-key" } and runtime config contained apiKey: "resolved-key" plus baseUrl: "https://api.tavily.test".

Evidence after fix: Copied terminal output from the after-fix probe:

error getaddrinfo ENOTFOUND api.tavily.test

Observed result after fix: The previous unresolved SecretRef exception no longer occurs. The dedicated tavily_search tool reads the resolved runtime snapshot, including the runtime-only fake Tavily base URL, and advances to the request path; the DNS error is expected because api.tavily.test is deliberately not a real host.

What was not tested: A live Tavily API request was not run because TAVILY_API_KEY is not present in ~/.profile in this environment.

Before evidence optional: Before the fix, the same resolver path failed before making any request:

{"toolNames":["tavily_search","tavily_extract"]}
error plugins.entries.tavily.config.webSearch.apiKey: unresolved SecretRef "exec:default:printf resolved-key". Resolve this command against an active gateway runtime snapshot before reading it.

Verification

  • pnpm test extensions/tavily/src/tavily-tools.test.ts -- --reporter=verbose
  • pnpm exec oxfmt --check --threads=1 extensions/tavily/index.ts extensions/tavily/src/tavily-extract-tool.ts extensions/tavily/src/tavily-search-tool.ts extensions/tavily/src/tavily-tools.test.ts
  • git diff --check
  • pnpm check:changed
  • pnpm test:changed

@openclaw-barnacle openclaw-barnacle Bot added extensions: tavily size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 6, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 6, 2026

Codex review: needs maintainer review before merge.

Summary
This PR converts Tavily's dedicated search/extract tools to runtime-context factories, resolves credentials from the active runtime config snapshot, and adds regression coverage plus a changelog entry.

Reproducibility: yes. Current main can be source-reproduced by resolving Tavily plugin tools with raw source config containing an exec SecretRef and a runtime snapshot containing the resolved key; the dedicated tools still read api.config, which strict SecretRef normalization rejects.

Real behavior proof
Sufficient (terminal): The PR body includes after-fix terminal output from the real resolver path showing the tool advances past unresolved SecretRef handling to the expected fake-host DNS error.

Next step before merge
No ClawSweeper repair lane is needed because the PR is review-clean and should proceed through normal maintainer and CI gating.

Security
Cleared: The diff changes Tavily secret lookup timing without adding dependencies, workflow changes, permission expansion, or new secret exposure paths.

Review details

Best possible solution:

Merge the Tavily-owned factory binding fix with its regression coverage and changelog once required checks pass.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main can be source-reproduced by resolving Tavily plugin tools with raw source config containing an exec SecretRef and a runtime snapshot containing the resolved key; the dedicated tools still read api.config, which strict SecretRef normalization rejects.

Is this the best way to solve the issue?

Yes. The patch uses the existing plugin-tool factory context (runtimeConfig/getRuntimeConfig) and keeps the fix inside the Tavily plugin instead of adding new core secret-resolution policy.

What I checked:

  • Current-main bug path: Current main registers tavily_search and tavily_extract as already-created tool objects, so their execute closures keep using plugin-load api.config. (extensions/tavily/index.ts:12, a74b459f7a74)
  • Current-main config source: Both dedicated Tavily tool implementations pass cfg: api.config into the Tavily client instead of the runtime-resolved config snapshot. (extensions/tavily/src/tavily-search-tool.ts:72, a74b459f7a74)
  • SecretRef failure contract: normalizeResolvedSecretInputString uses strict secret resolution, and unresolved SecretRefs throw the same active-runtime-snapshot error described in the PR body. (src/config/types.secrets.ts:151, a74b459f7a74)
  • Existing SDK seam: Plugin tool factories receive runtimeConfig and getRuntimeConfig, and registerTool already accepts factories with declared names, so the PR uses an existing extension seam rather than changing core secret semantics. (src/plugins/tool-types.ts:8, a74b459f7a74)
  • Runtime context wiring: The agent plugin-tool resolver passes both a resolved runtime config and a getter into resolvePluginTools, which supports the PR's late-binding approach. (src/agents/openclaw-plugin-tools.ts:76, a74b459f7a74)
  • PR diff review: The fetched PR diff changes Tavily registration to named factories, adds runtime-config fallback helpers in both dedicated tools, adds a regression test, and includes a changelog entry. (extensions/tavily/index.ts:12, f6ea284003d4)

Likely related people:

  • steipete: Local blame points the current Tavily tool files to recent maintainer work, and GitHub path history shows recent plugin SDK/config-runtime maintenance including refactor: tighten plugin sdk entry surface and fix(agents): avoid secrets snapshot clones in plugin tool prep. (role: recent maintainer; confidence: high; commits: 2e10ffe8130d, bfcfc17a8bac, 5be66ca648e1; files: extensions/tavily/index.ts, extensions/tavily/src/tavily-search-tool.ts, src/agents/openclaw-plugin-tools.ts)
  • lakshyaag-tavily: GitHub path history shows the bundled Tavily plugin and dedicated tools were introduced in feat: add Tavily as a bundled web search plugin with search and extract tools. (role: introduced behavior; confidence: high; commits: b36e456b0916; files: extensions/tavily/index.ts, extensions/tavily/src/tavily-search-tool.ts, extensions/tavily/src/tavily-extract-tool.ts)
  • vincentkoc: GitHub path history shows recent work on plugin tool context and resolution seams touched by this PR's fix path, including delivery context splits and plugin tool denylist handling. (role: adjacent owner; confidence: medium; commits: 2028fd53f077, 543c14a4edd1, 571d75aab351; files: src/plugins/tool-types.ts, src/agents/openclaw-plugin-tools.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against a74b459f7a74.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 6, 2026
Copy link
Copy Markdown

@byungskers byungskers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch on the SecretRef resolution path. The fallback chain in resolveTavilyToolConfig (getRuntimeConfigruntimeConfigconfigapi.config) is exactly the right priority order for runtime config resolution.

One small suggestion: if there's already a test exercising the tool registration path via the plugin entry point, it might be worth adding an assertion that verifies the ctx object is actually passed through to the factory. Otherwise this looks ready to go.

@vincentkoc vincentkoc self-assigned this May 7, 2026
@vincentkoc vincentkoc force-pushed the tavily-secretref-runtime-config branch from f6ea284 to 1555165 Compare May 7, 2026 09:39
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 7, 2026
@vincentkoc vincentkoc merged commit 8de5a55 into openclaw:main May 7, 2026
72 of 82 checks passed
steipete pushed a commit that referenced this pull request May 7, 2026
Resolve Tavily dedicated tool credential lookup against the active runtime config snapshot.

PR: #78610
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
Resolve Tavily dedicated tool credential lookup against the active runtime config snapshot.

PR: openclaw#78610
rogerdigital pushed a commit to rogerdigital/openclaw that referenced this pull request May 9, 2026
Resolve Tavily dedicated tool credential lookup against the active runtime config snapshot.

PR: openclaw#78610
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: tavily proof: supplied External PR includes structured after-fix real behavior proof. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants