Summary
When agents.defaults.memorySearch.provider selects a plugin-owned memory embedding provider (for example "openai"), Gateway startup planning does not load the plugin that owns that provider. As a result active-memory can start without a registered memory embedding provider and silently drops to keyword/FTS-only recall.
Environment
- Component: Gateway startup plugin planning
- Config:
agents.defaults.memorySearch.provider = "openai"
Steps to reproduce
- Configure semantic memory with a plugin-owned remote embedding provider:
- Start the Gateway with no other config that would independently pull the OpenAI plugin into the startup plan (no
openai/* model, speech/image/voice provider, etc.).
- Inspect loaded plugins / memory status.
Expected
The plugin that declares contracts.memoryEmbeddingProviders: ["openai"] (the OpenAI plugin) is included in the Gateway startup plugin set, registers openAiMemoryEmbeddingProviderAdapter via api.registerMemoryEmbeddingProvider(...), and semantic recall uses embeddings.
Actual
Startup planning only pulls provider plugins into the plan for speech / web search / model / image / voice providers. There is no capability-specific startup loading keyed on agents.*.memorySearch.provider against contracts.memoryEmbeddingProviders. The OpenAI plugin is therefore not started, no memory embedding provider is registered, and active-memory falls back to keyword/FTS-only search with no clear signal to the operator.
Root cause
src/plugins/gateway-startup-plugin-ids.ts collects configured provider ids and matches them against manifest contracts for several capabilities (speechProviders, webSearchProviders, model providers, imageGenerationProviders/videoGenerationProviders/musicGenerationProviders, voice providers) inside resolveGatewayStartupPluginPlanFromRegistry, and mirrors that in the metadata-scope fast path (resolveGatewayStartupMetadataPluginIds). Memory embedding providers are absent from both paths, so a configured memorySearch.provider never pulls its owning plugin into the startup plan.
Proposed fix
Add capability-specific startup loading for memory embedding providers, analogous to the existing speech/web/model/image/voice provider startup loading:
- Collect
agents.*.memorySearch.provider (defaults + per-agent), ignoring sentinel values (auto/local/none) and disabled memory-search blocks.
- Match configured ids against plugin
contracts.memoryEmbeddingProviders.
- Include the owning plugin in the Gateway startup plugin ids, respecting plugin allow/deny/enabled policy exactly like the neighboring provider-startup functions.
- Add a health warning at Gateway startup when
memorySearch.provider=<x> is configured but no loaded plugin registered memory embedding provider <x> (so the silent keyword/FTS fallback is diagnosable).
Summary
When
agents.defaults.memorySearch.providerselects a plugin-owned memory embedding provider (for example"openai"), Gateway startup planning does not load the plugin that owns that provider. As a resultactive-memorycan start without a registered memory embedding provider and silently drops to keyword/FTS-only recall.Environment
agents.defaults.memorySearch.provider = "openai"Steps to reproduce
{ "agents": { "defaults": { "memorySearch": { "provider": "openai" } } } }openai/*model, speech/image/voice provider, etc.).Expected
The plugin that declares
contracts.memoryEmbeddingProviders: ["openai"](the OpenAI plugin) is included in the Gateway startup plugin set, registersopenAiMemoryEmbeddingProviderAdapterviaapi.registerMemoryEmbeddingProvider(...), and semantic recall uses embeddings.Actual
Startup planning only pulls provider plugins into the plan for speech / web search / model / image / voice providers. There is no capability-specific startup loading keyed on
agents.*.memorySearch.provideragainstcontracts.memoryEmbeddingProviders. The OpenAI plugin is therefore not started, no memory embedding provider is registered, andactive-memoryfalls back to keyword/FTS-only search with no clear signal to the operator.Root cause
src/plugins/gateway-startup-plugin-ids.tscollects configured provider ids and matches them against manifest contracts for several capabilities (speechProviders,webSearchProviders, model providers,imageGenerationProviders/videoGenerationProviders/musicGenerationProviders, voice providers) insideresolveGatewayStartupPluginPlanFromRegistry, and mirrors that in the metadata-scope fast path (resolveGatewayStartupMetadataPluginIds). Memory embedding providers are absent from both paths, so a configuredmemorySearch.providernever pulls its owning plugin into the startup plan.Proposed fix
Add capability-specific startup loading for memory embedding providers, analogous to the existing speech/web/model/image/voice provider startup loading:
agents.*.memorySearch.provider(defaults + per-agent), ignoring sentinel values (auto/local/none) and disabled memory-search blocks.contracts.memoryEmbeddingProviders.memorySearch.provider=<x>is configured but no loaded plugin registered memory embedding provider<x>(so the silent keyword/FTS fallback is diagnosable).