Skip to content

feat: make @youdotcom-oss/openclaw a real OpenClaw 2.0 plugin - #55

Open
brainsparker wants to merge 1 commit into
mainfrom
dx-805-convert-youdotcom-ossopenclaw-from-a-runtime-free-bundle
Open

feat: make @youdotcom-oss/openclaw a real OpenClaw 2.0 plugin#55
brainsparker wants to merge 1 commit into
mainfrom
dx-805-convert-youdotcom-ossopenclaw-from-a-runtime-free-bundle

Conversation

@brainsparker

Copy link
Copy Markdown
Contributor

Closes DX-805.

@youdotcom-oss/openclaw shipped as a skill and setup-metadata bundle, not a plugin. Its runtime was literally register: () => {}, its config schema was empty, and it declared no capability contracts — so OpenClaw knew a plugin with some skills existed, but had no way to know You.com is a search engine. This is the blocker for the rest of the milestone: OpenClaw 2.0's Agent Plugin bundle contract keeps providers, configuration schemas, and runtime entry points outside the bundle, so no amount of skill work reaches the provider picker.

This is the plumbing that makes providers registerable. Actual provider implementations stay in DX-806 / DX-807.

Manifest

  • contracts.webSearchProviders: ["you", "you-free"] and contracts.webFetchProviders: ["you"]. This is what OpenClaw validates provider ids against, and resolveManifestDeclaredWebProviderCandidatePluginIds uses it to pick which plugin runtimes to load when a web capability is requested.
  • activation.onStartup: false. 2.0 stopped startup-loading implicitly and asks every plugin to set this intentionally; we're inert at startup, and the contracts above are the load trigger.
  • Real configSchema: apiKey, baseUrl, timeoutMs, crawlTimeoutSeconds, count, safesearch, country, freshness, extractionMode — bounded and patterned, with defaults.
  • configContracts.secretInputs routes apiKey through SecretRef with ownerKind: "capability", so a stale credential fails cold rather than staying active. uiHints marks it sensitive.
  • setup.providers[].authMethods: ["api-key"]. Skills and YDC_API_KEY metadata are unchanged.

Runtime

  • plugin.ts builds its runtime config schema from the manifest through buildJsonPluginConfigSchema, so the JSON Schema has one home. register(api) resolves settings, warns when no credential is reachable, and debug-logs a redacted summary. The DX-806/807 provider registrations slot into the same closure.
  • settings.ts is the shared normalizer those tickets consume. Credentials go through the SDK's resolveSecretInputString (openclaw/plugin-sdk/secret-input) in inspect mode, so a configured-but-unresolved SecretRef reports itself instead of throwing. A non-http(s) baseUrl throws — that's where the API key gets sent, so it fails loud and lands in plugins doctor instead of quietly redirecting the credential.

Packaging

Built against 2026.8.1, not the retired July/August SDK paths: openclaw.compat.pluginApi, openclaw.install.minHostVersion (replacing the undocumented compat.minGatewayVersion), and the openclaw peer dependency. Root bun.lock resolves openclaw@2026.8.1.

No semver-release.ts change needed: packages/openclaw/** already matches by path prefix, and openclaw.plugin.json is already version-bumped in lockstep on apply.

Verification

Against the real 2026.8.1 CLI with an isolated OPENCLAW_STATE_DIR / OPENCLAW_CONFIG_PATH, plugin loaded via plugins.load.paths:

  • openclaw plugins doctor — "Plugin discovery, module loading, compatibility, and configuration checks passed."
  • openclaw plugins inspect youStatus: loaded, Shape: hybrid-capability, web-search: you, you-free, web-fetch: you
  • openclaw health (loopback gateway, since stopped) — ok: true, plugins.errors: [], unavailable: []. you is deliberately absent from plugins.loaded: that's onStartup: false working, not a failure.
  • openclaw skills list — all five You.com skills ✓ ready
  • Schema is live end to end: count: 0 is rejected with plugins.entries.you.config.count: invalid config: must be >= 1
  • bun test packages/openclaw — 21 pass. tsc --noEmit, biome check, format-package --check clean.

bun test at the repo root has one failure, Pi extension > … from real endpoints (duplicate you-search-free), which also fails on a clean checkout of main — live-endpoint test, unrelated. Python checks were skipped: nothing Python changed.

One deviation

The ticket asks to use "the shared Plugin SDK stream and SecretRef utilities." plugin-sdk/provider-stream is the LLM-inference stream-wrapper surface — nothing in a web search or fetch provider consumes it, so it's left out. The SecretRef half is done via plugin-sdk/secret-input.

🤖 Generated with Claude Code

The package shipped `register: () => {}` with an empty config schema and no
capability contracts, so OpenClaw could see skills but had no way to know
You.com is a search engine. Declare the capability ownership and wire a real
runtime entry, built against the 2026.8.1 plugin SDK.

Manifest:
- contracts.webSearchProviders ["you", "you-free"], webFetchProviders ["you"]
- activation.onStartup false; 2.0 no longer startup-loads implicitly, and the
  contracts above are the capability-triggered load path
- full configSchema: apiKey, baseUrl, timeouts, count, safesearch, country,
  freshness, extractionMode
- configContracts.secretInputs routes apiKey through SecretRef with
  ownerKind "capability", plus sensitive uiHints

Runtime:
- plugin.ts builds its config schema from the manifest via
  buildJsonPluginConfigSchema, resolves settings, warns on a missing
  credential, and debug-logs a redacted summary
- settings.ts normalizes plugin config for the providers DX-806/DX-807 add,
  reading credentials through the SDK's resolveSecretInputString and
  rejecting a non-http(s) baseUrl instead of falling back silently

Packaging targets 2026.8.1 via compat.pluginApi, install.minHostVersion, and
the openclaw peer dependency.

Verified with the 2026.8.1 CLI against an isolated state dir: `plugins doctor`
passes, `plugins inspect you` reports the plugin loaded with web-search
"you, you-free" and web-fetch "you", `health` returns ok with no plugin errors,
all five skills stay ready, and out-of-range config is rejected by the schema.

Refs DX-805

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@brainsparker
brainsparker requested a review from a team as a code owner August 31, 2026 19:05
@factory-droid

factory-droid Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Droid finished @brainsparker's task —— View job


Code review complete

Status: approved — no high-confidence actionable issues found.

The PR cleanly converts @youdotcom-oss/openclaw into a real OpenClaw 2.0 plugin: provider contracts (webSearchProviders/webFetchProviders), a bounded and patterned config schema with defaults, SecretRef-routed apiKey, and a runtime register() backed by a well-tested settings normalizer. readBaseUrl rejects non-http(s) schemes to prevent credential redirection, credentials are never logged (describeYouSettings emits only credentialSource), and schema defaults are asserted in sync with runtime fallbacks by a dedicated test.

No inline review comments were posted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant