refactor: validate provider plugin metadata

This commit is contained in:
Peter Steinberger
2026-03-13 01:15:00 +00:00
parent 87ad1ce9b1
commit c80da4e72f
4 changed files with 414 additions and 13 deletions

View File

@@ -771,18 +771,22 @@ are not just "OAuth helpers" anymore.
### Provider plugin lifecycle
A provider plugin can participate in four distinct phases:
A provider plugin can participate in five distinct phases:
1. **Auth**
`auth[].run(ctx)` performs OAuth, API-key capture, device code, or custom
setup and returns auth profiles plus optional config patches.
2. **Wizard integration**
2. **Non-interactive setup**
`auth[].runNonInteractive(ctx)` handles `openclaw onboard --non-interactive`
without prompts. Use this when the provider needs custom headless setup
beyond the built-in simple API-key paths.
3. **Wizard integration**
`wizard.onboarding` adds an entry to `openclaw onboard`.
`wizard.modelPicker` adds a setup entry to the model picker.
3. **Implicit discovery**
4. **Implicit discovery**
`discovery.run(ctx)` can contribute provider config automatically during
model resolution/listing.
4. **Post-selection follow-up**
5. **Post-selection follow-up**
`onModelSelected(ctx)` runs after a model is chosen. Use this for provider-
specific work such as downloading a local model.
@@ -790,6 +794,7 @@ This is the recommended split because these phases have different lifecycle
requirements:
- auth is interactive and writes credentials/config
- non-interactive setup is flag/env-driven and must not prompt
- wizard metadata is static and UI-facing
- discovery should be safe, quick, and failure-tolerant
- post-select hooks are side effects tied to the chosen model
@@ -814,6 +819,32 @@ Core then:
That means a provider plugin owns the provider-specific setup logic, while core
owns the generic persistence and config-merge path.
### Provider non-interactive contract
`auth[].runNonInteractive(ctx)` is optional. Implement it when the provider
needs headless setup that cannot be expressed through the built-in generic
API-key flows.
The non-interactive context includes:
- the current and base config
- parsed onboarding CLI options
- runtime logging/error helpers
- agent/workspace dirs
- `resolveApiKey(...)` to read provider keys from flags, env, or existing auth
profiles while honoring `--secret-input-mode`
- `toApiKeyCredential(...)` to convert a resolved key into an auth-profile
credential with the right plaintext vs secret-ref storage
Use this surface for providers such as:
- self-hosted OpenAI-compatible runtimes that need `--custom-base-url` +
`--custom-model-id`
- provider-specific non-interactive verification or config synthesis
Do not prompt from `runNonInteractive`. Reject missing inputs with actionable
errors instead.
### Provider wizard metadata
`wizard.onboarding` controls how the provider appears in grouped onboarding:
@@ -836,6 +867,13 @@ entry in model selection:
When a provider has multiple auth methods, the wizard can either point at one
explicit method or let OpenClaw synthesize per-method choices.
OpenClaw validates provider wizard metadata when the plugin registers:
- duplicate or blank auth-method ids are rejected
- wizard metadata is ignored when the provider has no auth methods
- invalid `methodId` bindings are downgraded to warnings and fall back to the
provider's remaining auth methods
### Provider discovery contract
`discovery.run(ctx)` returns one of:
@@ -970,6 +1008,9 @@ Notes:
- `run` receives a `ProviderAuthContext` with `prompter`, `runtime`,
`openUrl`, and `oauth.createVpsAwareHandlers` helpers.
- `runNonInteractive` receives a `ProviderAuthMethodNonInteractiveContext`
with `opts`, `resolveApiKey`, and `toApiKeyCredential` helpers for
headless onboarding.
- Return `configPatch` when you need to add default models or provider config.
- Return `defaultModel` so `--set-default` can update agent defaults.
- `wizard.onboarding` adds a provider choice to `openclaw onboard`.