Skip to content

feat(plugins): add unified provider system with capabilities#52995

Closed
kesor wants to merge 14 commits into
openclaw:mainfrom
kesor:feat/more-plugin-hooks
Closed

feat(plugins): add unified provider system with capabilities#52995
kesor wants to merge 14 commits into
openclaw:mainfrom
kesor:feat/more-plugin-hooks

Conversation

@kesor
Copy link
Copy Markdown
Contributor

@kesor kesor commented Mar 23, 2026

For some reason #41496 was accidentally closed by the bot :(

Summary

This PR adds a unified registerProvider API with capabilities to the plugin system, allowing plugins to provide custom providers for:

  • Chat/LLM - Standard model providers (existing)
  • Embeddings (embed, embedBatch, embedBatchInputs for multimodal)
  • ASR/Audio transcription (transcribeAudio)
  • Image understanding (describeImage)
  • Video understanding (describeVideo)
  • Text-to-speech (textToSpeech)

Key Changes

  1. Unified Provider API: Single registerProvider() method with optional capabilities array: ["chat", "embedding", "audio", "image", "video", "tts"]

  2. Embedding Support: Plugins can provide embedding providers with embed, embedBatch, and embedBatchInputs (multimodal) methods. Supports custom provider IDs beyond built-ins.

  3. Media Provider Support: Plugins can provide audio transcription, image/video understanding, and TTS with full access to API keys, baseUrl, headers, and proxy-aware fetchFn.

  4. Type Definitions: Added capability types and method signatures to plugin-sdk. Includes plugin-specific request types (PluginImageDescriptionRequest, PluginAudioTranscriptionRequest, PluginVideoDescriptionRequest).

  5. Plugin SDK Exports: New types exported for plugin authors:

    • PluginImageDescriptionRequest
    • PluginAudioTranscriptionRequest
    • PluginVideoDescriptionRequest
    • EmbeddingProviderRequest / EmbeddingProviderFallback (now supports custom string IDs)
  6. Provider ID Normalization: Uses normalizeProviderId() consistently for provider lookups to handle aliases (e.g., "z.ai" → "zai")

  7. Telephony TTS: Plugins can override built-in TTS providers for telephony with automatic fallback to built-in on failure

  8. Configuration Fallthrough: TTS plugins receive configured model/voice/headers from config when not overridden by directives

Architecture

  • Capability-based routing: getPluginProvidersByCapability() filters plugins by capability
  • Plugin registry: Normalized provider IDs stored in registry for consistent lookups
  • Graceful fallback: Built-in providers used when plugins fail or are unavailable

Risk Assessment

Low Risk:

  • Plugin providers only affect requests when plugins are loaded
  • Built-in providers remain unchanged
  • Additive only - doesn't modify existing behavior

Change Type

  • Feature

Scope

  • Gateway / orchestration
  • Integrations (plugin system)
  • API / contracts (plugin API)
  • Docs

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • Data access scope changed? No

Compatibility

  • Backward compatible? Yes - existing built-in providers unchanged
  • Config changes? None
  • Migration needed? No

@kesor kesor changed the title Feat/more plugin hooks feat(plugins): add unified provider system with capabilities Mar 23, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 23, 2026

Greptile Summary

This PR introduces a unified registerProvider() API with a routingCapabilities array, allowing plugins to declare support for embeddings, TTS, audio transcription, image/video understanding alongside existing chat/LLM routing. The implementation is additive — built-in providers are unchanged and plugin paths only activate when a matching plugin is loaded.

Key areas of the change:

  • src/plugins/runtime.ts — new getPluginProvidersByCapability helper is the backbone of all capability routing; it correctly guards against null/object-shaped capabilities.
  • src/memory/embeddings.ts — plugin embedding providers are resolved and ordered after built-ins in auto mode.
  • src/media-understanding/provider-registry.ts — integrates plugin-sourced media providers into the existing registry with a module-level cache for performance.
  • src/tts/tts.ts / src/tts/providers.ts — plugin TTS providers are wired into both the standard and telephony synthesis paths; the prior concern about duplicated telephony blocks has been addressed with the extracted invokePluginTelephonyTts helper.
  • src/config/validation.ts — tightens memorySearch provider/fallback validation by pushing unknown IDs to issues (not warnings), which makes the new regression tests work correctly.

One concrete bug found:

  • buildMediaUnderstandingRegistry (provider-registry.ts line 171) writes to the shared module-level cache even when cfg is provided. The cache-read guard already requires !cfg, but the write guard only checks !overrides. In production, runtime.ts and image-tool.ts both call buildProviderRegistry(undefined, cfg), which writes a cfg-specific registry to the shared cache. Any subsequent no-cfg call at the same plugin-registry version returns the contaminated result instead of rebuilding.

Confidence Score: 3/5

  • Needs one targeted fix before merge — the media registry cache-write guard does not exclude cfg-flavoured calls, which can pollute shared state in the production hot path.
  • The PR is a well-structured, additive feature with good test coverage and prior review concerns largely addressed (duplicated telephony block extracted, EmbeddingProviderRequest widened correctly with string & {}, config regression tests now push to issues not warnings). However, the cache-contamination bug in buildMediaUnderstandingRegistry is a real production correctness issue: runtime.ts and image-tool.ts both call buildProviderRegistry(undefined, cfg) in the hot path, which writes a cfg-specific registry to the shared module-level cache. Subsequent no-cfg callers (apply.ts, audio-transcription-runner.ts) at the same plugin-registry version receive the wrong cached result. A one-line fix (!overrides && !cfg) resolves it.
  • src/media-understanding/provider-registry.ts (cache-write guard at line 171)

Comments Outside Diff (1)

  1. src/media-understanding/runner.entries.ts, line 1193-1198 (link)

    P1 Non-normalized provider config lookup in auth fallback

    When resolveApiKeyForProvider returns nothing (e.g. a keyless plugin) the fallback path uses a direct bracket lookup:

    providerConfig: params.cfg.models?.providers?.[params.providerId],

    params.providerId is already normalized (lowercased, aliased), but users may write their provider key in the config with mixed casing (e.g. "MyPlugin" or "Z.AI"). The bracket lookup will silently return undefined in those cases, so baseUrl and headers from models.providers are never surfaced to the plugin.

    Consider using the findNormalizedProviderValue helper that is already available in this file for consistent case-insensitive lookups:

    providerConfig: findNormalizedProviderValue(params.cfg.models?.providers, params.providerId),
    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/media-understanding/runner.entries.ts
    Line: 1193-1198
    
    Comment:
    **Non-normalized provider config lookup in auth fallback**
    
    When `resolveApiKeyForProvider` returns nothing (e.g. a keyless plugin) the fallback path uses a direct bracket lookup:
    
    ```typescript
    providerConfig: params.cfg.models?.providers?.[params.providerId],
    ```
    
    `params.providerId` is already normalized (lowercased, aliased), but users may write their provider key in the config with mixed casing (e.g. `"MyPlugin"` or `"Z.AI"`). The bracket lookup will silently return `undefined` in those cases, so `baseUrl` and `headers` from `models.providers` are never surfaced to the plugin.
    
    Consider using the `findNormalizedProviderValue` helper that is already available in this file for consistent case-insensitive lookups:
    
    ```typescript
    providerConfig: findNormalizedProviderValue(params.cfg.models?.providers, params.providerId),
    ```
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/media-understanding/provider-registry.ts
Line: 171-174

Comment:
**Cfg-specific registry contaminates shared cache**

The cache-write guard at line 171 only checks `!overrides`, so a call with `cfg` but no overrides also writes to the module-level `mediaUnderstandingRegistryCache`. This means the *next* no-cfg call (e.g. from `apply.ts` or `audio-transcription-runner.ts`) will hit the cache and receive the cfg-specific registry rather than the config-neutral one — even if those callers rely on a different set of loaded plugins.

The production hot-path confirms this: `runtime.ts` calls `buildProviderRegistry(undefined, params.cfg)` (translating to `buildMediaUnderstandingRegistry(undefined, cfg)`). With `!overrides === true`, the cfg-flavoured registry is written to the shared cache. Any later `buildProviderRegistry()` call that happens to run at the same registry version returns the wrong result.

The cache-write guard needs the same `!cfg` condition as the cache-read guard:

```suggestion
  if (!overrides && !cfg) {
    cachedRegistryVersion = getActivePluginRegistryVersion();
    mediaUnderstandingRegistryCache = registry;
  }
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/tts/tts.ts
Line: 991

Comment:
**`"microsoft"` missing from telephony builtin set**

`builtinSet` in `synthesizeSpeech` (line 768) explicitly adds `"microsoft"` alongside the mapped `TTS_PROVIDERS` entries. The equivalent set in `textToSpeechTelephony` does not:

```typescript
// synthesizeSpeech (correct)
const builtinSet = new Set<string>([...TTS_PROVIDERS.map((p) => p.toLowerCase()), "microsoft"]);

// textToSpeechTelephony (missing "microsoft")
const builtinSetTelephony = new Set<string>(TTS_PROVIDERS.map((p) => p.toLowerCase()));
```

If `"microsoft"` ever surfaces in the provider list unresolved (e.g. when `normalizeSpeechProviderId` returns `null`), a plugin override for `"microsoft"` that throws will have `isBuiltin === false`, causing the telephony path to `continue` and skip the built-in fallback rather than falling through to it.

```suggestion
  const builtinSetTelephony = new Set<string>([...TTS_PROVIDERS.map((p) => p.toLowerCase()), "microsoft"]);
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/media-understanding/runner.entries.ts
Line: 1193-1198

Comment:
**Non-normalized provider config lookup in auth fallback**

When `resolveApiKeyForProvider` returns nothing (e.g. a keyless plugin) the fallback path uses a direct bracket lookup:

```typescript
providerConfig: params.cfg.models?.providers?.[params.providerId],
```

`params.providerId` is already normalized (lowercased, aliased), but users may write their provider key in the config with mixed casing (e.g. `"MyPlugin"` or `"Z.AI"`). The bracket lookup will silently return `undefined` in those cases, so `baseUrl` and `headers` from `models.providers` are never surfaced to the plugin.

Consider using the `findNormalizedProviderValue` helper that is already available in this file for consistent case-insensitive lookups:

```typescript
providerConfig: findNormalizedProviderValue(params.cfg.models?.providers, params.providerId),
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (4): Last reviewed commit: "fix: address review comments S1-S4" | Re-trigger Greptile

Comment thread src/memory/embeddings.ts
Comment thread src/media-understanding/provider-registry.ts
Comment thread src/memory/embeddings.ts
Comment thread src/tts/tts.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c6db4db64

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/media-understanding/runner.entries.ts Outdated
Comment thread src/media-understanding/provider-registry.ts
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation gateway Gateway runtime commands Command implementations agents Agent runtime and tooling size: XL labels Mar 23, 2026
@kesor kesor force-pushed the feat/more-plugin-hooks branch from 456f76d to 64d14b7 Compare March 23, 2026 17:40
Add plugin support for media providers (TTS, STT, image, video) and embedding
providers through a unified registerProvider API with capabilities.

Key changes:
- Add capabilities array to ProviderPlugin: chat, embedding, audio, image, video, tts
- Add embed/embedBatch methods for embedding providers
- Add transcribeAudio, describeImage, describeVideo, textToSpeech for media
- Remove separate registerMediaProvider (now unified)
- Simplify by removing complex caching system

This allows plugins to provide any combination of AI capabilities through
a single registration API.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 64d14b7cc3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/memory/embeddings.ts Outdated
Comment thread src/tts/tts.ts Outdated
…fallback

- Fix N1: auto-mode crash when plugin exists but has no API key
- Remove dead code in TTS telephony (identical if/else branches)
- Remove complex plugin TTS integration tests that require deep mocking
- Add tests for resolveTtsApiKey custom provider lookup
- Regenerate schema.base.generated.ts

Refs: PR-52995
@kesor kesor force-pushed the feat/more-plugin-hooks branch from 64d14b7 to b133670 Compare March 23, 2026 18:16
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b1336704f4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/memory/embeddings.ts
Comment thread src/tts/tts.ts Outdated
kesor added 2 commits March 23, 2026 20:49
- G8: Respect disableFallback when assembling plugin TTS provider order
  Only add custom plugin providers to fallback list when fallback is allowed
- G10: Preserve MIME type when checking plugin voice-note compatibility
  Pass contentType to isVoiceCompatibleAudio instead of relying on filename
- G5/G6: Exclude legacy media providers from plugin-image dispatch
  Only search providers array (new unified system) for plugin-style handlers
  Legacy providers in mediaUnderstandingProviders now correctly use cfg-based request

Refs: PR-52995
- A1: Verify cache invalidation works via version check (no changes needed)
  The version-based cache invalidation in buildMediaUnderstandingRegistry
  correctly handles registry changes via setActivePluginRegistry
- A3: Export ProviderCapability and embedding types from plugin-sdk
  Added exports for ProviderCapability, ProviderEmbedRequest, ProviderEmbedResult,
  ProviderEmbedBatchRequest, ProviderEmbedBatchResult
- A5: Deduplicate capabilities when merging providers
  Use Set to remove duplicate capabilities in merged providers

Refs: PR-52995
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dba5c17a65

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/validation.ts Outdated
Comment thread src/memory/embeddings.ts
… plugin viability in auto mode

- N1: Remove loaded plugin shortcut from validation
  The shortcut trusted in-memory plugin registry state which could be stale.
  Now uses manifest registry which validates against the config being validated.
- N2: Check custom plugin API keys before returning in auto mode
  Instead of returning first custom plugin, iterate and check API key viability.
  Skip plugins without valid API key and try next one.

Refs: PR-52995
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80a4f6ed8f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/memory/embeddings.ts Outdated
Comment thread src/memory/embeddings.ts Outdated
kesor added 2 commits March 23, 2026 21:29
- N3: Check apiKey !== undefined instead of truthy to allow keyless plugins
  Empty string is a valid API key for local/self-hosted plugins
- N4: Pass agentDir when probing plugin API keys in auto mode
  This ensures agent-scoped credentials are considered during provider selection

Refs: PR-52995
…d return empty on no viable providers

- P1: web-search - return empty string when no viable provider found instead of returning first without credential check
- P2: runner.ts - add checkAllRegistryProviders() to iterate through all registry providers for capability match before returning null

This ensures custom plugin providers are considered as fallbacks and prevents returning providers without valid credentials.

Refs: PR-52995
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bf3100affe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/validation.ts Outdated
Comment thread src/media-understanding/provider-registry.ts Outdated
Comment thread docs/tools/plugin.md
- N1: validation.ts - Remove manifest-based embedding validation
  Cannot validate embedding capability from manifest since it only lists provider IDs
  without capability info. Fall through to runtime validation.
- N2: provider-registry.ts - Bypass cache when cfg is provided
  Include config in cache bypass logic to prevent stale providers.
- N4: tts.ts - Restore provider normalization in resolveTtsApiKey
  Add normalizeSpeechProviderId at function start to handle mixed-case inputs.
- N5: plugins/types.ts - Remove duplicate type definition
  Make PluginTextToSpeechRequest a re-export alias of TextToSpeechRequest.

Refs: PR-52995
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 594c186a52

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/validation.ts Outdated
Comment thread src/media-understanding/runner.entries.ts Outdated
Let plugin providers try without upfront API key validation.
This allows keyless plugins to work and delegates error handling to runtime.
The existing fallback mechanism will handle failures appropriately.

Refs: PR-52995
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 64ee3ef49f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/media-understanding/runner.ts Outdated
Comment thread src/media-understanding/runner.entries.ts Outdated
kesor added 2 commits March 23, 2026 22:53
- Q1: Add warning for unknown memorySearch providers/fallbacks
  Warn instead of silently accepting unknown providers to catch typos
- Q2: Gate image dispatch on declared image capability
  Check routingCapabilities includes 'image' before treating as plugin handler
- Q3: Assign default model when auto-selecting image provider from registry
  Use DEFAULT_IMAGE_MODELS[providerId] for image capability fallback
- Q4: Gate audio plugin detection on declared audio capability
  Check routingCapabilities includes 'audio' before treating as plugin handler

Refs: PR-52995
Also check routingCapabilities.includes('video') before treating as plugin video handler.
This was missed in the previous fix - video was not covered by Q4.

Refs: PR-52995
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2e3f83f960

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/tts/tts.ts Outdated
Comment thread src/memory/embeddings.ts Outdated
…lookup

- R1: Remove 'microsoft' from TTS_PROVIDERS since 'edge' is canonical
  Both would normalize to 'microsoft' causing duplicate provider in fallback
- R2: Use findNormalizedProviderValue for plugin embedding config lookup
  This handles alias normalization (e.g., 'z.ai' -> 'zai') correctly

Refs: PR-52995
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1256528a01

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/media-understanding/runner.ts Outdated
Comment thread src/tts/tts.ts Outdated
Comment thread src/config/config.schema-regressions.test.ts
- S1: Fix missing backtick in docs/tools/plugin.md
- S2: Skip auth check for keyless plugin media providers
  Registry providers may be keyless - return entry directly without auth precheck
- S3: Add microsoft to builtinSet for plugin TTS fallback
  Edge normalizes to microsoft, so microsoft must be in builtin set
- S4: Push to issues not warnings for unknown memory providers
  This catches typos like 'olama' and enforces validation

Refs: PR-52995
Comment thread src/media-understanding/provider-registry.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 426b6e009c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +398 to +399
const model = cap === "image" ? DEFAULT_IMAGE_MODELS[providerId] : undefined;
return { type: "provider" as const, provider: providerId, model };
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Iterate auto media candidates instead of returning first match

checkAllRegistryProviders returns on the first provider that exposes the capability, without any viability check. Because buildMediaUnderstandingRegistry inserts built-ins first (groq/deepgram), auto audio with no credentials will pick a built-in provider and never consider later keyless plugin providers, then fail in runProviderEntry when API key enforcement kicks in. Fresh evidence in this patch is the unconditional early return inside the new helper, which makes provider order—not capability/readiness—determine selection.

Useful? React with 👍 / 👎.

- T1: provider-registry.ts - cfg contaminates shared cache
  Add !cfg check to cache-write guard
- T2: runner.ts - iterate plugin providers not built-ins for auto
  Only use plugin providers as fallback, skip built-ins
- T3: runner.entries.ts - use findNormalizedProviderValue for auth fallback
  Normalized lookup handles mixed-case provider keys

Refs: PR-52995
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e28aa0ae3f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/validation.ts
Comment on lines +529 to +533
if (knownMemoryProviders.has(provider)) {
return;
}
// Reject unknown providers - catches typos and enforces validation
issues.push({
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Allow plugin embedding IDs in memorySearch validation

This validator hard-codes a built-in provider allowlist and unconditionally flags any other memorySearch.provider as unknown, which blocks the new plugin embedding provider flow added in this commit. With provider/fallback now typed as free-form strings and createEmbeddingProvider supporting plugin IDs, configs like agents.defaults.memorySearch.provider: "my-plugin" fail validation before plugin loading, so plugin-backed memory search cannot be configured at all.

Useful? React with 👍 / 👎.

@kesor kesor closed this Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling commands Command implementations docs Improvements or additions to documentation gateway Gateway runtime size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant