openclaw - 💡(How to fix) Fix Feature: separate fallback remote config for memorySearch [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#43760Fetched 2026-04-08 00:17:46
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Participants

Root Cause

When using provider: "gemini" as the primary memorySearch embedding provider, the remote config (baseUrl, apiKey) is shared between primary and fallback. This makes it impossible to configure a different provider (e.g., OpenAI-compatible SiliconFlow with bge-m3) as a fallback, because the Gemini provider picks up the fallback's remote.baseUrl and fails with 404.

Fix Action

Workaround

Currently running with fallback: "none" and remote: { baseUrl: "", apiKey: "" } since there is no way to isolate provider configs. The Gemini provider correctly uses env.GEMINI_API_KEY when remote is empty.

Code Example

"memorySearch": {
  "provider": "gemini",
  "model": "gemini-embedding-2-preview",
  "fallback": "openai",
  "remote": {
    "baseUrl": "https://api.siliconflow.cn/v1",
    "apiKey": "sk-xxx"
  }
}

---

"memorySearch": {
  "provider": "gemini",
  "model": "gemini-embedding-2-preview",
  "fallback": {
    "provider": "openai",
    "model": "BAAI/bge-m3",
    "remote": {
      "baseUrl": "https://api.siliconflow.cn/v1",
      "apiKey": "sk-xxx"
    }
  }
}
RAW_BUFFERClick to expand / collapse

Problem

When using provider: "gemini" as the primary memorySearch embedding provider, the remote config (baseUrl, apiKey) is shared between primary and fallback. This makes it impossible to configure a different provider (e.g., OpenAI-compatible SiliconFlow with bge-m3) as a fallback, because the Gemini provider picks up the fallback's remote.baseUrl and fails with 404.

Current behavior

"memorySearch": {
  "provider": "gemini",
  "model": "gemini-embedding-2-preview",
  "fallback": "openai",
  "remote": {
    "baseUrl": "https://api.siliconflow.cn/v1",
    "apiKey": "sk-xxx"
  }
}

Result: Gemini provider uses SiliconFlow's baseUrl → 404. The remote config is shared between primary and fallback providers.

Expected behavior

Support a separate fallback remote config so primary and fallback providers can have independent endpoints. For example:

"memorySearch": {
  "provider": "gemini",
  "model": "gemini-embedding-2-preview",
  "fallback": {
    "provider": "openai",
    "model": "BAAI/bge-m3",
    "remote": {
      "baseUrl": "https://api.siliconflow.cn/v1",
      "apiKey": "sk-xxx"
    }
  }
}

Or alternatively, fallbackRemote and fallbackModel as top-level keys.

Environment

  • OpenClaw version: 2026.3.11
  • Primary provider: gemini (gemini-embedding-2-preview)
  • Desired fallback: openai-compatible (SiliconFlow BAAI/bge-m3)

Workaround

Currently running with fallback: "none" and remote: { baseUrl: "", apiKey: "" } since there is no way to isolate provider configs. The Gemini provider correctly uses env.GEMINI_API_KEY when remote is empty.

extent analysis

Fix Summary

Add a nested fallback object to the memorySearch schema and update the provider‑initialisation logic so that each provider (primary + fallback) reads its own remote settings. Keep the old flat fallback: "openai" syntax for backward compatibility.


1. Configuration Schema Change

// src/config/types.ts
export interface RemoteConfig {
  baseUrl?: string;
  apiKey?: string;
}

export interface ProviderConfig {
  provider: string;          // e.g. "gemini" | "openai"
  model: string;             // model name
  remote?: RemoteConfig;     // optional – defaults to env vars
}

export interface MemorySearchConfig {
  provider: string;          // primary provider name (kept for legacy)
  model: string;             // primary model name
  remote?: RemoteConfig;     // primary remote (legacy flat form)

  // NEW – either a string (legacy) or a full object
  fallback?: string | ProviderConfig;
}
  • The old flat form (fallback: "openai") still works.
  • The new form (fallback: { provider, model, remote }) gives a completely independent remote block.

2. Provider Factory Update

// src/memorySearch/providerFactory.ts
import { RemoteConfig, ProviderConfig, MemorySearchConfig } from '../config/types';
import { GeminiProvider } from './gemini';
import { OpenAIProvider } from './openai';

// Helper to resolve a RemoteConfig → actual endpoint + key
function resolveRemote(remote?: RemoteConfig, providerName?: string): RemoteConfig {
  if (remote && remote.baseUrl) return remote;               // explicit config
  // fall back to env vars per provider
  switch (providerName) {
    case 'gemini':
      return { baseUrl: 'https://generativelanguage.googleapis.com', apiKey: process.env.GEMINI_API_KEY };
    case 'openai':
      return { baseUrl: process.env.OPENAI_BASE_URL, apiKey: process.env.OPENAI_API_KEY };
    default:
      return {};
  }
}

// Build a concrete provider instance from a ProviderConfig
function buildProvider(cfg: ProviderConfig): any {
  const remote = resolveRemote(cfg.remote, cfg.provider);
  switch (cfg.provider) {
    case 'gemini':
      return new GeminiProvider({ model: cfg.model, remote });
    case 'openai':
      return new OpenAI

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Support a separate fallback remote config so primary and fallback providers can have independent endpoints. For example:

"memorySearch": {
  "provider": "gemini",
  "model": "gemini-embedding-2-preview",
  "fallback": {
    "provider": "openai",
    "model": "BAAI/bge-m3",
    "remote": {
      "baseUrl": "https://api.siliconflow.cn/v1",
      "apiKey": "sk-xxx"
    }
  }
}

Or alternatively, fallbackRemote and fallbackModel as top-level keys.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Feature: separate fallback remote config for memorySearch [1 participants]