Skip to content

Commit 43ee01f

Browse files
authored
Merge 6443dc2 into 3e351b7
2 parents 3e351b7 + 6443dc2 commit 43ee01f

37 files changed

Lines changed: 2898 additions & 546 deletions

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
Docs: https://docs.openclaw.ai
44

5+
## Unreleased
6+
7+
### Changes
8+
9+
- Memory: add a core OpenAI-compatible embedding provider for local and hosted OpenAI-style endpoints, with config, doctor, and docs support. (#85269) Thanks @dutifulbob.
10+
511
## 2026.5.26
612

713
### Highlights

docs/concepts/active-memory.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -810,16 +810,16 @@ confirm `config.toolsAllow` names the tools that plugin actually registers.
810810

811811
<AccordionGroup>
812812
<Accordion title="Embedding provider switched or stopped working">
813-
If `memorySearch.provider` is unset, OpenClaw auto-detects the first
814-
available embedding provider. A new API key, quota exhaustion, or a
815-
rate-limited hosted provider can change which provider resolves between
816-
runs. If no provider resolves, `memory_search` may degrade to lexical-only
817-
retrieval; runtime failures after a provider is already selected do not
818-
fall back automatically.
819-
820-
Pin the provider (and an optional fallback) explicitly to make selection
821-
deterministic. See [Memory Search](/concepts/memory-search) for the full
822-
list of providers and pinning examples.
813+
If `memorySearch.provider` is unset, OpenClaw uses OpenAI embeddings. Set
814+
`memorySearch.provider` explicitly for local, Ollama, Gemini, Voyage,
815+
Mistral, DeepInfra, Bedrock, GitHub Copilot, or OpenAI-compatible
816+
embeddings. If the configured provider cannot run, `memory_search` may
817+
degrade to lexical-only retrieval; runtime failures after a provider is
818+
already selected do not fall back automatically.
819+
820+
Set an optional `memorySearch.fallback` only when you want a deliberate
821+
single fallback. See [Memory Search](/concepts/memory-search) for the full
822+
list of providers and examples.
823823

824824
</Accordion>
825825

docs/concepts/memory-builtin.md

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ a per-agent SQLite database and needs no extra dependencies to get started.
1919

2020
## Getting started
2121

22-
If you have an API key for OpenAI, Gemini, Voyage, Mistral, or DeepInfra, the builtin
23-
engine auto-detects it and enables vector search. No config needed.
22+
By default, the builtin engine uses OpenAI embeddings. If you already have
23+
`OPENAI_API_KEY` or `models.providers.openai.apiKey` configured, vector search
24+
works with no extra memory config.
2425

2526
To set a provider explicitly:
2627

@@ -60,18 +61,20 @@ at a GGUF file:
6061

6162
## Supported embedding providers
6263

63-
| Provider | ID | Auto-detected | Notes |
64-
| --------- | ----------- | ------------- | ----------------------------------- |
65-
| OpenAI | `openai` | Yes | Default: `text-embedding-3-small` |
66-
| Gemini | `gemini` | Yes | Supports multimodal (image + audio) |
67-
| Voyage | `voyage` | Yes | |
68-
| Mistral | `mistral` | Yes | |
69-
| DeepInfra | `deepinfra` | Yes | Default: `BAAI/bge-m3` |
70-
| Ollama | `ollama` | No | Local, set explicitly |
71-
| Local | `local` | Yes (first) | Optional `node-llama-cpp` runtime |
72-
73-
Auto-detection picks the first provider whose API key can be resolved, in the
74-
order shown. Set `memorySearch.provider` to override.
64+
| Provider | ID | Notes |
65+
| ----------------- | ------------------- | ----------------------------------- |
66+
| Bedrock | `bedrock` | Uses AWS credential chain |
67+
| DeepInfra | `deepinfra` | Default: `BAAI/bge-m3` |
68+
| Gemini | `gemini` | Supports multimodal (image + audio) |
69+
| GitHub Copilot | `github-copilot` | Uses Copilot subscription |
70+
| Local | `local` | Optional `node-llama-cpp` runtime |
71+
| Mistral | `mistral` | |
72+
| Ollama | `ollama` | Local/self-hosted |
73+
| OpenAI | `openai` | Default: `text-embedding-3-small` |
74+
| OpenAI-compatible | `openai-compatible` | Generic `/v1/embeddings` endpoint |
75+
| Voyage | `voyage` | |
76+
77+
Set `memorySearch.provider` to switch away from OpenAI.
7578

7679
## How indexing works
7780

@@ -120,8 +123,7 @@ openclaw memory index --force --agent main
120123
```
121124

122125
Both standalone CLI commands and the Gateway use the same `local` provider id.
123-
If the provider is set to `auto`, local embeddings are considered first only
124-
when `memorySearch.local.modelPath` points to an existing local file.
126+
Set `memorySearch.provider: "local"` when you want local embeddings.
125127

126128
**Stale results?** Run `openclaw memory index --force` to rebuild. The watcher
127129
may miss changes in rare edge cases.

docs/concepts/memory-search.md

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,24 @@ chunks and searching them using embeddings, keywords, or both.
1313

1414
## Quick start
1515

16-
If you have a GitHub Copilot subscription, OpenAI, Gemini, Voyage, or Mistral
17-
API key configured, memory search works automatically. To set a provider
18-
explicitly:
16+
Memory search uses OpenAI embeddings by default. To use another embedding
17+
backend, set a provider explicitly:
1918

2019
```json5
2120
{
2221
agents: {
2322
defaults: {
2423
memorySearch: {
25-
provider: "openai", // or "gemini", "local", "ollama", etc.
24+
provider: "openai", // or "gemini", "local", "ollama", "openai-compatible", etc.
2625
},
2726
},
2827
},
2928
}
3029
```
3130

32-
For multi-endpoint setups, `provider` can also be a custom
33-
`models.providers.<id>` entry, such as `ollama-5080`, when that provider sets
34-
`api: "ollama"` or another embedding adapter owner.
31+
For multi-endpoint setups with memory-specific providers, `provider` can also
32+
be a custom `models.providers.<id>` entry, such as `ollama-5080`, when that
33+
provider sets `api: "ollama"` or another memory embedding adapter owner.
3534

3635
For local embeddings with no API key, set `provider: "local"`. Source checkouts
3736
may still require native build approval: `pnpm approve-builds` then
@@ -44,16 +43,18 @@ for indexed chunks. Configure those with `memorySearch.queryInputType` and
4443

4544
## Supported providers
4645

47-
| Provider | ID | Needs API key | Notes |
48-
| -------------- | ---------------- | ------------- | ---------------------------------------------------- |
49-
| Bedrock | `bedrock` | No | Auto-detected when the AWS credential chain resolves |
50-
| Gemini | `gemini` | Yes | Supports image/audio indexing |
51-
| GitHub Copilot | `github-copilot` | No | Auto-detected, uses Copilot subscription |
52-
| Local | `local` | No | GGUF model, ~0.6 GB download |
53-
| Mistral | `mistral` | Yes | Auto-detected |
54-
| Ollama | `ollama` | No | Local, must set explicitly |
55-
| OpenAI | `openai` | Yes | Auto-detected, fast |
56-
| Voyage | `voyage` | Yes | Auto-detected |
46+
| Provider | ID | Needs API key | Notes |
47+
| ----------------- | ------------------- | ------------- | ----------------------------- |
48+
| Bedrock | `bedrock` | No | Uses AWS credential chain |
49+
| DeepInfra | `deepinfra` | Yes | Default: `BAAI/bge-m3` |
50+
| Gemini | `gemini` | Yes | Supports image/audio indexing |
51+
| GitHub Copilot | `github-copilot` | No | Uses Copilot subscription |
52+
| Local | `local` | No | GGUF model, ~0.6 GB download |
53+
| Mistral | `mistral` | Yes | |
54+
| Ollama | `ollama` | No | Local/self-hosted |
55+
| OpenAI | `openai` | Yes | Default |
56+
| OpenAI-compatible | `openai-compatible` | Usually | Generic `/v1/embeddings` |
57+
| Voyage | `voyage` | Yes | |
5758

5859
## How search works
5960

docs/concepts/memory.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,10 @@ search** — combining vector similarity (semantic meaning) with keyword matchin
144144
an API key for any supported provider.
145145

146146
<Info>
147-
OpenClaw auto-detects your embedding provider from available API keys. If you
148-
have an OpenAI, Gemini, Voyage, or Mistral key configured, memory search is
149-
enabled automatically.
147+
OpenClaw uses OpenAI embeddings by default. Set
148+
`agents.defaults.memorySearch.provider` explicitly to use Gemini, Voyage,
149+
Mistral, local, Ollama, Bedrock, GitHub Copilot, or OpenAI-compatible
150+
embeddings.
150151
</Info>
151152

152153
For details on how search works, tuning options, and provider setup, see

docs/gateway/doctor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ That stages grounded durable candidates into the short-term dreaming store while
517517
- **QMD backend**: probes whether the `qmd` binary is available and startable. If not, prints fix guidance including the npm package and a manual binary path option.
518518
- **Explicit local provider**: checks for a local model file or a recognized remote/downloadable model URL. If missing, suggests switching to a remote provider.
519519
- **Explicit remote provider** (`openai`, `voyage`, etc.): verifies an API key is present in the environment or auth store. Prints actionable fix hints if missing.
520-
- **Auto provider**: checks local model availability first, then tries each remote provider in auto-selection order.
520+
- **Legacy auto provider**: treats `memorySearch.provider: "auto"` as OpenAI and checks OpenAI readiness.
521521

522522
When a cached gateway probe result is available (gateway was healthy at the time of the check), doctor cross-references its result with the CLI-visible config and notes any discrepancy. Doctor does not start a fresh embedding ping on the default path; use the deep memory status command when you want a live provider check.
523523

docs/help/faq.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -523,20 +523,17 @@ lives on the [First-run FAQ](/help/faq-first-run).
523523
Codex CLI login)** does not help for semantic memory search. OpenAI embeddings
524524
still need a real API key (`OPENAI_API_KEY` or `models.providers.openai.apiKey`).
525525

526-
If you don't set a provider explicitly, OpenClaw auto-selects a provider when it
527-
can resolve an API key (auth profiles, `models.providers.*.apiKey`, or env vars).
528-
It prefers OpenAI if an OpenAI key resolves, otherwise Gemini if a Gemini key
529-
resolves, then Voyage, then Mistral. If no remote key is available, memory
530-
search stays disabled until you configure it. If you have a local model path
531-
configured and present, OpenClaw
532-
prefers `local`. Ollama is supported when you explicitly set
533-
`memorySearch.provider = "ollama"`.
526+
If you don't set a provider explicitly, OpenClaw uses OpenAI embeddings. Legacy
527+
configs that still say `memorySearch.provider = "auto"` resolve to OpenAI too.
528+
If no OpenAI API key is available, semantic memory search stays unavailable
529+
until you configure a key or choose another provider explicitly.
534530

535531
If you'd rather stay local, set `memorySearch.provider = "local"` (and optionally
536532
`memorySearch.fallback = "none"`). If you want Gemini embeddings, set
537533
`memorySearch.provider = "gemini"` and provide `GEMINI_API_KEY` (or
538-
`memorySearch.remote.apiKey`). We support **OpenAI, Gemini, Voyage, Mistral, Ollama, or local** embedding
539-
models - see [Memory](/concepts/memory) for the setup details.
534+
`memorySearch.remote.apiKey`). We support **OpenAI, OpenAI-compatible, Gemini,
535+
Voyage, Mistral, Bedrock, Ollama, LM Studio, GitHub Copilot, DeepInfra, or local**
536+
embedding models - see [Memory](/concepts/memory) for the setup details.
540537

541538
</Accordion>
542539
</AccordionGroup>

docs/plugins/adding-capabilities.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,10 @@ is intentionally broader than memory: tools, search, retrieval, importers, or
121121
future feature plugins can consume embeddings without depending on the memory
122122
engine.
123123

124-
For memory-engine-specific adapters, keep using `memoryEmbeddingProviders`.
125-
Those adapters own memory indexing details such as query/document split,
126-
runtime metadata, and local memory engine setup. Do not make a generic
127-
embedding provider depend on memory-owned modules unless the provider is only
128-
usable by memory.
124+
Memory search can consume generic `embeddingProviders`. The older
125+
`memoryEmbeddingProviders` contract remains for compatibility while existing
126+
memory-specific providers migrate, but new reusable embedding providers should
127+
use `embeddingProviders`.
129128

130129
## Review checklist
131130

docs/plugins/manifest.md

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -638,25 +638,25 @@ read without importing the plugin runtime.
638638

639639
Each list is optional:
640640

641-
| Field | Type | What it means |
642-
| -------------------------------- | ---------- | --------------------------------------------------------------------------------------------------- |
643-
| `embeddedExtensionFactories` | `string[]` | Codex app-server extension factory ids, currently `codex-app-server`. |
644-
| `agentToolResultMiddleware` | `string[]` | Runtime ids a bundled plugin may register tool-result middleware for. |
645-
| `externalAuthProviders` | `string[]` | Provider ids whose external auth profile hook this plugin owns. |
646-
| `embeddingProviders` | `string[]` | General embedding provider ids this plugin owns for reusable vector embedding use outside memory. |
647-
| `speechProviders` | `string[]` | Speech provider ids this plugin owns. |
648-
| `realtimeTranscriptionProviders` | `string[]` | Realtime-transcription provider ids this plugin owns. |
649-
| `realtimeVoiceProviders` | `string[]` | Realtime-voice provider ids this plugin owns. |
650-
| `memoryEmbeddingProviders` | `string[]` | Memory embedding provider ids this plugin owns. |
651-
| `mediaUnderstandingProviders` | `string[]` | Media-understanding provider ids this plugin owns. |
652-
| `transcriptSourceProviders` | `string[]` | Transcript source provider ids this plugin owns. |
653-
| `imageGenerationProviders` | `string[]` | Image-generation provider ids this plugin owns. |
654-
| `videoGenerationProviders` | `string[]` | Video-generation provider ids this plugin owns. |
655-
| `webFetchProviders` | `string[]` | Web-fetch provider ids this plugin owns. |
656-
| `webSearchProviders` | `string[]` | Web-search provider ids this plugin owns. |
657-
| `migrationProviders` | `string[]` | Import provider ids this plugin owns for `openclaw migrate`. |
658-
| `gatewayMethodDispatch` | `string[]` | Reserved entitlement for authenticated plugin HTTP routes that dispatch Gateway methods in-process. |
659-
| `tools` | `string[]` | Agent tool names this plugin owns. |
641+
| Field | Type | What it means |
642+
| -------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------- |
643+
| `embeddedExtensionFactories` | `string[]` | Codex app-server extension factory ids, currently `codex-app-server`. |
644+
| `agentToolResultMiddleware` | `string[]` | Runtime ids a bundled plugin may register tool-result middleware for. |
645+
| `externalAuthProviders` | `string[]` | Provider ids whose external auth profile hook this plugin owns. |
646+
| `embeddingProviders` | `string[]` | General embedding provider ids this plugin owns for reusable vector embedding use, including memory. |
647+
| `speechProviders` | `string[]` | Speech provider ids this plugin owns. |
648+
| `realtimeTranscriptionProviders` | `string[]` | Realtime-transcription provider ids this plugin owns. |
649+
| `realtimeVoiceProviders` | `string[]` | Realtime-voice provider ids this plugin owns. |
650+
| `memoryEmbeddingProviders` | `string[]` | Legacy memory embedding provider ids this plugin owns. |
651+
| `mediaUnderstandingProviders` | `string[]` | Media-understanding provider ids this plugin owns. |
652+
| `transcriptSourceProviders` | `string[]` | Transcript source provider ids this plugin owns. |
653+
| `imageGenerationProviders` | `string[]` | Image-generation provider ids this plugin owns. |
654+
| `videoGenerationProviders` | `string[]` | Video-generation provider ids this plugin owns. |
655+
| `webFetchProviders` | `string[]` | Web-fetch provider ids this plugin owns. |
656+
| `webSearchProviders` | `string[]` | Web-search provider ids this plugin owns. |
657+
| `migrationProviders` | `string[]` | Import provider ids this plugin owns for `openclaw migrate`. |
658+
| `gatewayMethodDispatch` | `string[]` | Reserved entitlement for authenticated plugin HTTP routes that dispatch Gateway methods in-process. |
659+
| `tools` | `string[]` | Agent tool names this plugin owns. |
660660

661661
`contracts.embeddedExtensionFactories` is retained for bundled Codex
662662
app-server-only extension factories. Bundled tool-result transforms should
@@ -674,17 +674,12 @@ Provider plugins that implement `resolveExternalAuthProfiles` should declare
674674
through a deprecated compatibility fallback, but that fallback is slower and
675675
will be removed after the migration window.
676676

677-
Bundled memory embedding providers should declare
678-
`contracts.memoryEmbeddingProviders` for every adapter id they expose, including
679-
built-in adapters such as `local`. Standalone CLI paths use this manifest
680-
contract to load only the owning plugin before the full Gateway runtime has
681-
registered providers.
682-
683677
General embedding providers should declare `contracts.embeddingProviders` for
684678
each adapter registered with `api.registerEmbeddingProvider(...)`. Use the
685-
general contract when vectors are meant to be consumed by multiple features,
686-
tools, or plugins. Keep `contracts.memoryEmbeddingProviders` for adapters whose
687-
shape and lifecycle are specific to OpenClaw memory indexing.
679+
general contract for reusable vector generation, including providers consumed by
680+
memory search. `contracts.memoryEmbeddingProviders` is the older
681+
memory-specific compatibility contract and remains while existing providers
682+
migrate to the generic embedding provider seam.
688683

689684
`contracts.gatewayMethodDispatch` currently accepts
690685
`"authenticated-request"`. It is an API hygiene gate for native plugin HTTP

0 commit comments

Comments
 (0)