Skip to content

Commit ba316a1

Browse files
mukhtharcmsteipete
authored andcommitted
feat: add remote config overrides to memorySearch
1 parent 4086408 commit ba316a1

8 files changed

Lines changed: 75 additions & 9 deletions

File tree

docs/concepts/memory.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,28 @@ Defaults:
8181

8282
Remote embeddings **require** an OpenAI API key (`OPENAI_API_KEY` or
8383
`models.providers.openai.apiKey`). Codex OAuth only covers chat/completions and
84-
does **not** satisfy embeddings for memory search. If you don't want to set an
85-
API key, use `memorySearch.provider = "local"` or set
84+
does **not** satisfy embeddings for memory search.
85+
86+
If you want to use a **custom OpenAI-compatible endpoint** (like Gemini, OpenRouter, or a proxy),
87+
you can use the `remote` configuration:
88+
89+
```json5
90+
agents: {
91+
defaults: {
92+
memorySearch: {
93+
provider: "openai",
94+
model: "text-embedding-3-small",
95+
remote: {
96+
baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai/",
97+
apiKey: "YOUR_GEMINI_API_KEY",
98+
headers: { "X-Custom-Header": "value" }
99+
}
100+
}
101+
}
102+
}
103+
```
104+
105+
If you don't want to set an API key, use `memorySearch.provider = "local"` or set
86106
`memorySearch.fallback = "none"`.
87107

88108
Config example:

docs/gateway/configuration-examples.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,14 @@ Save to `~/.clawdbot/clawdbot.json` and you can DM the bot from that number.
241241
prompt: "HEARTBEAT",
242242
ackMaxChars: 300
243243
},
244+
memorySearch: {
245+
provider: "openai",
246+
model: "text-embedding-004",
247+
remote: {
248+
baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai/",
249+
apiKey: "${GEMINI_API_KEY}"
250+
}
251+
},
244252
sandbox: {
245253
mode: "non-main",
246254
perSession: true,

src/agents/memory-search.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import { resolveAgentConfig } from "./agent-scope.js";
99
export type ResolvedMemorySearchConfig = {
1010
enabled: boolean;
1111
provider: "openai" | "local";
12+
remote?: {
13+
baseUrl?: string;
14+
apiKey?: string;
15+
headers?: Record<string, string>;
16+
};
1217
fallback: "openai" | "none";
1318
model: string;
1419
local: {
@@ -60,6 +65,7 @@ function mergeConfig(
6065
): ResolvedMemorySearchConfig {
6166
const enabled = overrides?.enabled ?? defaults?.enabled ?? true;
6267
const provider = overrides?.provider ?? defaults?.provider ?? "openai";
68+
const remote = overrides?.remote ?? defaults?.remote;
6369
const fallback = overrides?.fallback ?? defaults?.fallback ?? "openai";
6470
const model = overrides?.model ?? defaults?.model ?? DEFAULT_MODEL;
6571
const local = {
@@ -112,6 +118,7 @@ function mergeConfig(
112118
return {
113119
enabled,
114120
provider,
121+
remote,
115122
fallback,
116123
model,
117124
local,

src/config/schema.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ const FIELD_LABELS: Record<string, string> = {
118118
"agents.defaults.memorySearch": "Memory Search",
119119
"agents.defaults.memorySearch.enabled": "Enable Memory Search",
120120
"agents.defaults.memorySearch.provider": "Memory Search Provider",
121+
"agents.defaults.memorySearch.remote.baseUrl": "Remote Embedding Base URL",
122+
"agents.defaults.memorySearch.remote.apiKey": "Remote Embedding API Key",
121123
"agents.defaults.memorySearch.model": "Memory Search Model",
122124
"agents.defaults.memorySearch.fallback": "Memory Search Fallback",
123125
"agents.defaults.memorySearch.local.modelPath": "Local Embedding Model Path",
@@ -236,6 +238,10 @@ const FIELD_HELP: Record<string, string> = {
236238
"Vector search over MEMORY.md and memory/*.md (per-agent overrides supported).",
237239
"agents.defaults.memorySearch.provider":
238240
'Embedding provider ("openai" or "local").',
241+
"agents.defaults.memorySearch.remote.baseUrl":
242+
"Custom OpenAI-compatible base URL (e.g. for Gemini/OpenRouter proxies).",
243+
"agents.defaults.memorySearch.remote.apiKey":
244+
"Custom API key for the remote embedding provider.",
239245
"agents.defaults.memorySearch.local.modelPath":
240246
"Local GGUF model path or hf: URI (node-llama-cpp).",
241247
"agents.defaults.memorySearch.fallback":

src/config/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,11 @@ export type MemorySearchConfig = {
10111011
enabled?: boolean;
10121012
/** Embedding provider mode. */
10131013
provider?: "openai" | "local";
1014+
remote?: {
1015+
baseUrl?: string;
1016+
apiKey?: string;
1017+
headers?: Record<string, string>;
1018+
};
10141019
/** Fallback behavior when local embeddings fail. */
10151020
fallback?: "openai" | "none";
10161021
/** Embedding model id (remote) or alias (local). */

src/config/zod-schema.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,13 @@ const MemorySearchSchema = z
886886
.object({
887887
enabled: z.boolean().optional(),
888888
provider: z.union([z.literal("openai"), z.literal("local")]).optional(),
889+
remote: z
890+
.object({
891+
baseUrl: z.string().optional(),
892+
apiKey: z.string().optional(),
893+
headers: z.record(z.string(), z.string()).optional(),
894+
})
895+
.optional(),
889896
fallback: z.union([z.literal("openai"), z.literal("none")]).optional(),
890897
model: z.string().optional(),
891898
local: z

src/memory/embeddings.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ export type EmbeddingProviderOptions = {
2020
config: ClawdbotConfig;
2121
agentDir?: string;
2222
provider: "openai" | "local";
23+
remote?: {
24+
baseUrl?: string;
25+
apiKey?: string;
26+
headers?: Record<string, string>;
27+
};
2328
model: string;
2429
fallback: "openai" | "none";
2530
local?: {
@@ -42,16 +47,23 @@ function normalizeOpenAiModel(model: string): string {
4247
async function createOpenAiEmbeddingProvider(
4348
options: EmbeddingProviderOptions,
4449
): Promise<EmbeddingProvider> {
45-
const { apiKey } = await resolveApiKeyForProvider({
46-
provider: "openai",
47-
cfg: options.config,
48-
agentDir: options.agentDir,
49-
});
50+
const remote = options.config.agents?.defaults?.memorySearch?.remote;
51+
52+
const { apiKey } = remote?.apiKey
53+
? { apiKey: remote.apiKey }
54+
: await resolveApiKeyForProvider({
55+
provider: "openai",
56+
cfg: options.config,
57+
agentDir: options.agentDir,
58+
});
5059

5160
const providerConfig = options.config.models?.providers?.openai;
52-
const baseUrl = providerConfig?.baseUrl?.trim() || DEFAULT_OPENAI_BASE_URL;
61+
const baseUrl =
62+
remote?.baseUrl?.trim() ||
63+
providerConfig?.baseUrl?.trim() ||
64+
DEFAULT_OPENAI_BASE_URL;
5365
const url = `${baseUrl.replace(/\/$/, "")}/embeddings`;
54-
const headerOverrides = providerConfig?.headers ?? {};
66+
const headerOverrides = remote?.headers ?? providerConfig?.headers ?? {};
5567
const headers: Record<string, string> = {
5668
"Content-Type": "application/json",
5769
Authorization: `Bearer ${apiKey}`,

src/memory/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export class MemoryIndexManager {
8888
config: cfg,
8989
agentDir: resolveAgentDir(cfg, agentId),
9090
provider: settings.provider,
91+
remote: settings.remote,
9192
model: settings.model,
9293
fallback: settings.fallback,
9394
local: settings.local,

0 commit comments

Comments
 (0)