Relevant source files
The following files were used as context for generating this wiki page:
- integrations/openclaw/index.ts
- integrations/openclaw/cli/commands.ts
- integrations/openclaw/tools/index.ts
- integrations/hermes-plugin-mem0/init.py
- integrations/opencode-plugin/opencode-mem0.ts
- integrations/openclaw/tools/memory-list.ts
- integrations/pi-agent-plugin/src/memory/tools.ts
- integrations/openclaw/tools/memory-delete.ts
- integrations/openclaw/tools/memory-get.ts
- integrations/openclaw/tools/memory-update.ts
- integrations/openclaw/openclaw.plugin.json
- integrations/openclaw/tools/memory-add.ts
- integrations/claude-code-plugin/core/memory_cli.py
- integrations/openclaw/tools/memory-search.ts
- integrations/openclaw/providers.ts
- integrations/openclaw/tools/memory-event-list.ts
- integrations/openclaw/isolation.ts
- integrations/openclaw/openclaw-plugin-sdk.d.ts
- integrations/deepseek-plugin/src/index.ts
- cli/node/src/index.ts
- integrations/kimi-plugin/core/memory_cli.py
- integrations/codex-plugin/core/memory_cli.py
- integrations/antigravity-plugin/core/memory_cli.py
- integrations/openclaw/cli/config-file.ts
- integrations/openclaw/cli/oss-wizard.ts
- integrations/openclaw/recall.ts
- integrations/openclaw/fs-safe.ts
Overview
The OpenClaw Integration binds Mem0 memory management into the OpenClaw agent runtime, supporting both cloud-hosted Mem0 platform backends and self-hosted open-source deployments. It solves the problem of stateless agent turns by providing automated context injection and fact extraction alongside granular tool execution. Key design decisions include per-agent session namespacing to isolate state, token-budgeted and category-ranked recall engines, and robust CLI authentication helpers that persist credentials safely within local configuration files.
Sources: integrations/openclaw/openclaw.plugin.json:4-5, integrations/openclaw/index.ts:90-105, integrations/openclaw/recall.ts:1-10
Plugin Lifecycle and Hook Registration
The memoryPlugin entry point orchestrates plugin bootstrapping, configuration validation, and backend initialization within the OpenClaw execution environment. Upon registration through definePluginEntry, the register method initializes telemetry flags and reads persistent authentication state from configuration artifacts. It validates settings using mem0ConfigSchema against api.pluginConfig combined with file-based credentials, determining whether the host runs in cli-metadata registration mode or standard execution.
Sources: integrations/openclaw/index.ts:90-184
Warning
If cfg.needsSetup evaluates to true due to a missing API key, full memory capabilities are disabled, logging a warning instructing operators to run openclaw mem0 init. Even in this unauthenticated state, the plugin registers CLI commands and a waiting service so the initialization flow remains accessible.
Sources: integrations/openclaw/index.ts:137-167
When fully configured, createProvider instantiates either a PlatformProvider for cloud-hosted backends or an OSSProvider for self-hosted instances. The lifecycle manager begins a new session, and a Backend instance is selected: PlatformBackend is assigned when cfg.mode === "platform", while providerToBackend wraps local providers for open-source mode.
const provider = createProvider(cfg, api);
const lifecycle = createMemoryLifecycle();
lifecycle.beginSession();
// Create Backend instance — PlatformBackend for platform mode, providerToBackend adapter for OSS
let backend: Backend;
if (cfg.mode === "platform") {
backend = new PlatformBackend({
apiKey: cfg.apiKey!,
baseUrl: cfg.baseUrl ?? "https://api.mem0.ai",
});
} else {
backend = providerToBackend(provider, cfg.userId);
}
Sources: integrations/openclaw/index.ts:170-184, integrations/openclaw/providers.ts:530-584
Per-Agent Isolation and Scoping
Session Trigger Filtering and Subagent Detection
Multi-agent memory boundary enforcement relies on deriving structured user identifiers from session keys, ensuring distinct agent workspaces do not pollute shared storage namespaces. The isolation engine processes OpenClaw session keys to detect system automation triggers, identify ephemeral subagent runs, and extract specific agent identifiers.
System-initiated execution loops such as cron jobs, heartbeats, automation pipelines, and schedules are filtered out using isNonInteractiveTrigger to prevent automated prompts from contaminating long-term user memory stores. This function checks explicit trigger names against the SKIP_TRIGGERS set and falls back to inspecting the session key pattern for :cron: or :heartbeat: tokens.
*/
const SKIP_TRIGGERS = new Set(["cron", "heartbeat", "automation", "schedule"]);
/**
* Returns true if the session trigger is non-interactive and memory
* hooks should be skipped entirely.
*
* Also detects cron-style session keys (e.g. "agent:main:cron:<id>")
* as a fallback when the trigger field is not set.
*/
export function isNonInteractiveTrigger(
trigger: string | undefined,
sessionKey: string | undefined,
): boolean {
if (trigger && SKIP_TRIGGERS.has(trigger.toLowerCase())) return true;
// Fallback: detect cron/heartbeat from the session key pattern
if (sessionKey) {
if (/:cron:/i.test(sessionKey) || /:heartbeat:/i.test(sessionKey))
return true;
}
return false;
}Sources: integrations/openclaw/isolation.ts:16-39
Warning
Ephemeral subagent sessions identified by isSubagentSession through the :subagent: pattern evaluate to empty namespaces during memory recall and leave orphaned data after capture because their random UUIDs change with every spawn.
Sources: integrations/openclaw/isolation.ts:46-49
User Identification Resolution and Session Parsing
Session keys follow specific formats that determine how the agent extracts isolation boundaries. The extractAgentId function parses subagent UUIDs, named agent identifiers, and primary main sessions.
| Session Key Pattern | Example Format | Extracted Agent ID Result |
|---|---|---|
| Main Agent Session | agent:main:main | undefined (falls back to base user ID) |
| Subagent Session | agent:main:subagent:d3b07384 | subagent-d3b07384 |
| Named Agent Session | agent:researcher:main | researcher |
Sources: integrations/openclaw/isolation.ts:53-77
The resolution hierarchy implemented in resolveUserId enforces priority rules when determining the active namespace for memory reads and writes. Explicit parameter overrides take precedence over session context, which in turn overrides base configuration settings.
Sources: integrations/openclaw/isolation.ts:98-107
Memory Tool Execution and CRUD
Tool Registration and Execution Lifecycle
The plugin exposes a comprehensive set of capabilities for managing stored memories through the OpenClaw tool registration framework. The registerAllTools function registers eight distinct tool handlers using the plugin API with optional: false settings, ensuring that memory management tools are always available during agent execution loops.
export function registerAllTools(deps: ToolDeps): void {
const { api } = deps;
const nonOptional = { optional: false };
api.registerTool(createMemorySearchTool(deps), nonOptional);
api.registerTool(createMemoryAddTool(deps), nonOptional);
api.registerTool(createMemoryGetTool(deps), nonOptional);
api.registerTool(createMemoryListTool(deps), nonOptional);
api.registerTool(createMemoryUpdateTool(deps), nonOptional);
api.registerTool(createMemoryDeleteTool(deps), nonOptional);
api.registerTool(createMemoryEventListTool(deps), nonOptional);
api.registerTool(createMemoryEventStatusTool(deps), nonOptional);
}Sources: integrations/openclaw/tools/index.ts:29-41
| Tool Name | Creating Function | Description / Purpose |
|---|---|---|
memory_search | createMemorySearchTool | Retrieves memories relevant to a query using semantic search with rank ordering. |
memory_add | createMemoryAddTool | Saves preferences, facts, decisions, rules, or technical notes to long-term memory. |
memory_get | createMemoryGetTool | Fetches a single memory by exact ID to inspect its full content and metadata. |
memory_list | createMemoryListTool | Lists all stored memories for auditing purposes without requiring a query string. |
memory_update | createMemoryUpdateTool | Modifies an existing memory's text in-place while preserving its ID and update history. |
memory_delete | createMemoryDeleteTool | Deletes memories via explicit ID, query search, or bulk deletion (all: true). |
memory_event_list | createMemoryEventListTool | Lists recent background processing events from the platform backend. |
memory_event_status | createMemoryEventStatusTool | Inspects status and telemetry of specific background memory processing events. |
Sources: integrations/openclaw/tools/index.ts:5-12, integrations/openclaw/tools/memory-list.ts:9-11, integrations/openclaw/tools/memory-add.ts:11-14, integrations/openclaw/tools/memory-get.ts:8-10, integrations/openclaw/tools/memory-update.ts:9-11, integrations/openclaw/tools/memory-delete.ts:9-11, integrations/openclaw/tools/memory-event-list.ts:6-9
Search, Retrieval, and Listing Handlers
The memory_search tool accepts queries, result limits, scoping filters (session, long-term, all), categories, and advanced search metadata filters. When scope is set to session, it queries specifically against the current session's run ID; when set to all, it combines long-term results with session-scoped items while deduplicating records by memory ID.
if (scope === "session") {
if (currentSessionId) {
results = await provider.search(query, applyFilters(buildSearchOptions(uid, limit, undefined, currentSessionId)));
}
} else if (scope === "long-term") {
results = await provider.search(query, applyFilters(buildSearchOptions(uid, limit)));
} else {
const longTerm = await provider.search(query, applyFilters(buildSearchOptions(uid, limit)));
let session: MemoryItem[] = [];
if (currentSessionId) {
session = await provider.search(query, applyFilters(buildSearchOptions(uid, limit, undefined, currentSessionId)));
}
const seen = new Set(longTerm.map((r) => r.id));
results = [...longTerm, ...session.filter((r) => !seen.has(r.id))];
}Sources: integrations/openclaw/tools/memory-search.ts:49-63
The memory_get tool calls provider.get(memoryId) directly and formats the output with creation and update timestamps, whereas memory_list returns an itemized audit listing without semantic scoring.
try {
const memory = await provider.get(memoryId);
deps.captureToolEvent("memory_get", { success: true, latency_ms: Date.now() - start });
return {
content: [{ type: "text", text: `Memory ${memory.id}:\n${memory.memory}\n\nCreated: ${memory.created_at ?? "unknown"}\nUpdated: ${memory.updated_at ?? "unknown"}` }],
details: { memory },
};Sources: integrations/openclaw/tools/memory-get.ts:18-24, integrations/openclaw/tools/memory-list.ts:33-43
Note
memory_list de-duplicates entries when scope is "all" by collecting long-term results first and filtering out any session-scoped items sharing an existing record ID.
Sources: integrations/openclaw/tools/memory-list.ts:37-43
Storage, Mutation, and Deletion Safeguards
The memory_add tool supports single-fact strings or arrays of facts via the facts parameter. Before storage, incoming content passes through stripNoiseFromContent and isNoiseMessage validation filters.
const allFacts = rawFacts
.map((f) => stripNoiseFromContent(f))
.filter((f) => f.length > 0 && !isNoiseMessage(f));
if (allFacts.length === 0) {
return { content: [{ type: "text", text: "All provided facts were filtered as noise. Nothing stored." }], details: { error: "all_noise" } };
}Sources: integrations/openclaw/tools/memory-add.ts:38-44
Mutative tools implement strict safety guardrails. Both memory_update and memory_delete check isSubagentSession(getCurrentSessionId()) upon execution and immediately reject requests made within ephemeral subagent sessions.
if (isSubagentSession(getCurrentSessionId())) {
return { content: [{ type: "text", text: "Memory update is not available in subagent sessions." }], details: { error: "subagent_blocked" } };
}Sources: integrations/openclaw/tools/memory-update.ts:21-23, integrations/openclaw/tools/memory-delete.ts:29-31
Warning
Bulk memory deletion (memory_delete with all: true) requires both the all: true flag and explicit confirm: true parameters to proceed; otherwise, execution aborts and returns an error details payload.
Sources: integrations/openclaw/tools/memory-delete.ts:58-61
Token-Budgeted Category-Ranked Recall Engine
Query Sanitization and Vector Retrieval
The recall engine processes raw prompt inputs by stripping untrusted sender metadata prefixes and bracketed tags via sanitizeQuery before executing search operations. It then queries the memory provider using SearchOptions configured with an over-fetched top_k value of maxMemories * 2 and a custom score threshold.
export function sanitizeQuery(raw: string): string {
let cleaned = raw.replace(
/Sender\s*\(untrusted metadata\):\s*```json[\s\S]*?```\s*/gi,
"",
);
cleaned = cleaned.replace(/^\[.*?\]\s*/g, "");
cleaned = cleaned.trim();
return cleaned || raw;
}
// ============================================================================
// Public API
// ============================================================================
/**
* Perform token-budgeted, category-ranked recall.
*/
export async function recall(
provider: Mem0Provider,
query: string,
userId: string,
config: SkillsConfig = {},
sessionId?: string,
): Promise<RecallResult> {
const recallConfig = config.recall ?? {};
const tokenBudget = recallConfig.tokenBudget ?? DEFAULT_TOKEN_BUDGET;
const maxMemories = recallConfig.maxMemories ?? DEFAULT_MAX_MEMORIES;
const threshold = recallConfig.threshold ?? DEFAULT_THRESHOLD;
const categoryOrder = recallConfig.categoryOrder ?? DEFAULT_CATEGORY_ORDER;
const identityAlwaysInclude = recallConfig.identityAlwaysInclude !== false;
// Build search options (v3.0.0: keyword_search, reranking, filter_memories removed)
const searchOpts: SearchOptions = {
user_id: userId,
top_k: maxMemories * 2, // Over-fetch for ranking
threshold,
source: "OPENCLAW",
};
Sources: integrations/openclaw/recall.ts:225-263
When a sessionId is present, the engine performs a secondary search against session memories using run_id filtering, and subsequently deduplicates any items already retrieved in the long-term memory set.
// Search session memories if we have a session
let sessionMemories: MemoryItem[] = [];
if (sessionId) {
try {
sessionMemories = await provider.search(cleanQuery, {
...searchOpts,
run_id: sessionId,
top_k: 5,
});
} catch {
// Session search failure is non-critical
}
}
// Deduplicate: session memories that are also in long-term
const longTermIds = new Set(longTermMemories.map((m) => m.id));
const uniqueSession = sessionMemories.filter((m) => !longTermIds.has(m.id));
Sources: integrations/openclaw/recall.ts:279-296
Note
sanitizeQuery removes framework noise like sender metadata blocks and timestamps, leaving conversational query rewriting explicitly to the agent layer via its skill protocol.
Sources: integrations/openclaw/recall.ts:219-224
Category Ranking and Importance Defaults
Retrieved memories are categorized by inspecting item metadata categories or mem0 extraction categories, falling back to "uncategorized". Memories are sorted using a multi-tiered comparator that prioritizes category configuration order, falls back to importance scores, and resolves ties using search relevance.
function getMemoryCategory(memory: MemoryItem): string {
// Check metadata first (skill-stored memories have explicit category)
if (
memory.metadata?.category &&
typeof memory.metadata.category === "string"
) {
return memory.metadata.category;
}
// Check categories array (mem0-extracted memories)
if (memory.categories?.length) {
return memory.categories[0];
}
return "uncategorized";
}
function getMemoryImportance(memory: MemoryItem): number {
if (
memory.metadata?.importance &&
typeof memory.metadata.importance === "number"
) {
return memory.metadata.importance;
}
// Default importance by category
const cat = getMemoryCategory(memory);
const defaults: Record<string, number> = {
identity: 0.95,
configuration: 0.95,
rule: 0.9,
preference: 0.85,
decision: 0.8,
technical: 0.8,
relationship: 0.75,
project: 0.75,
operational: 0.6,
};
return defaults[cat] ?? 0.5;
}Sources: integrations/openclaw/recall.ts:57-93
function rankMemories(
memories: MemoryItem[],
categoryOrder: string[],
): MemoryItem[] {
const orderMap = new Map(categoryOrder.map((cat, i) => [cat, i]));
return [...memories].sort((a, b) => {
const catA = getMemoryCategory(a);
const catB = getMemoryCategory(b);
const orderA = orderMap.get(catA) ?? 999;
const orderB = orderMap.get(catB) ?? 999;
// Primary sort: category priority
if (orderA !== orderB) return orderA - orderB;
// Secondary sort: importance (higher first)
const impA = getMemoryImportance(a);
const impB = getMemoryImportance(b);
if (impA !== impB) return impB - impA;
// Tertiary sort: search relevance score
return (b.score ?? 0) - (a.score ?? 0);
});
}Sources: integrations/openclaw/recall.ts:107-130
| Category Name | Default Importance | Category Priority Index |
|---|---|---|
identity | 0.95 | 0 (Highest) |
configuration | 0.95 | 1 |
rule | 0.9 | 2 |
preference | 0.85 | 3 |
decision | 0.8 | 4 |
technical | 0.8 | 5 |
relationship | 0.75 | 6 |
project | 0.75 | 7 |
operational | 0.6 | 8 |
Sources: integrations/openclaw/recall.ts:25-35, integrations/openclaw/recall.ts:81-91
Token Budgeting and Formatting
The budgeting step iterates through ranked memories to select items under a configured character-derived token estimation (CHARS_PER_TOKEN = 4), respecting the maxMemories limit and token constraints.
// Rough token estimate: ~4 chars per token for English text
const CHARS_PER_TOKEN = 4;Sources: integrations/openclaw/recall.ts:37-38
function budgetMemories(
rankedMemories: MemoryItem[],
tokenBudget: number,
maxMemories: number,
identityAlwaysInclude: boolean,
): MemoryItem[] {
const selected: MemoryItem[] = [];
let usedTokens = 0;
for (const memory of rankedMemories) {
if (selected.length >= maxMemories) break;
const memTokens = estimateTokens(memory.memory);
const isIdentity =
getMemoryCategory(memory) === "identity" ||
getMemoryCategory(memory) === "configuration";
// Identity/config always included if flag is set
if (identityAlwaysInclude && isIdentity) {
selected.push(memory);
usedTokens += memTokens;
continue;
}
// Budget check for non-identity memories
if (usedTokens + memTokens > tokenBudget) continue;
selected.push(memory);
usedTokens += memTokens;
}
return selected;
}Sources: integrations/openclaw/recall.ts:136-168
Warning
When identityAlwaysInclude is enabled (default), items categorized under identity or configuration bypass the token budget ceiling and are unconditionally forced into the selected context set.
Sources: integrations/openclaw/recall.ts:149-158, integrations/openclaw/recall.ts:254
CLI Subcommands and Authentication Helpers
Command Subsections and Configuration Persistence
The OpenClaw CLI registers subcommands under openclaw mem0 to handle memory operations and plugin management. Management tasks include platform authentication (init), connectivity checks (status), and configuration queries (config show, config get, config set, event list, event status).
* Registers all `openclaw mem0 <subcommand>` commands:
*
* Memory:
* - add : Add a memory from text (--user-id, --agent-id)
* - search : Search memories (--top-k, --scope, --agent-id, --user-id)
* - get : Get a specific memory by ID
* - list : List memories with optional filters (--user-id, --agent-id, --top-k)
* - update : Update a memory's text
* - delete : Delete a memory or all memories (--all, --confirm)
* - import : Import memories from a JSON file
*
* Management:
* - init : Authenticate with Mem0 Platform (email or API key)
* - status : Check API connectivity and show current config
* - config show : Display current plugin configuration
* - config get : Get a single config value
* - config set : Update a plugin config field
* - event list : List recent background events
* - event status: Get status of a specific event
*Sources: integrations/openclaw/cli/commands.ts:4-23
Configuration settings and authentication credentials are saved in ~/.openclaw/openclaw.json under plugins.entries.openclaw-mem0.config. The filesystem operations rely on safe wrappers in fs-safe.ts to isolate file I/O from network calls and comply with security scanners.
* Plugin auth and settings are stored in ~/.openclaw/openclaw.json under
* plugins.entries.openclaw-mem0.config — the single source of truth.
*
* Uses fs-safe.ts for all filesystem operations to pass the OpenClaw
* code_safety scanner.
*/Sources: integrations/openclaw/cli/config-file.ts:4-9
| Config Field | Type | Default Value | Purpose |
|---|---|---|---|
apiKey | string | undefined | Platform authentication token |
baseUrl | string | https://api.mem0.ai | Mem0 API base URL |
userId | string | undefined | Default user identity scope |
userEmail | string | undefined | Authenticated user email address |
mode | string | undefined | Operating mode for the plugin |
autoRecall | boolean | undefined | Automatically inject memories into prompts |
autoCapture | boolean | undefined | Automatically extract and save memories |
topK | number | undefined | Default retrieval count for searches |
anonymousTelemetryId | string | undefined | Telemetry tracking identifier |
keyFingerprint | string | undefined | SHA-256 prefix of the active API key |
Sources: integrations/openclaw/cli/config-file.ts:28-40, integrations/openclaw/cli/config-file.ts:19
Warning
readFullConfig throws an error on JSON parse failures. This fail-closed behavior prevents writeFullConfig from overwriting a corrupted config file with an empty state.
Sources: integrations/openclaw/cli/config-file.ts:50-51, integrations/openclaw/cli/config-file.ts:70-77
Credential Resolution and Execution Trace
When executing commands, configuration values and authentication states are resolved through a sequence of file checks. The execution walkthrough follows the exact verified call chain registerCliCommands → readPluginAuth → readFullConfig → exists.
registerCliCommandsstarts command setup inintegrations/openclaw/cli/commands.ts. Sources: integrations/openclaw/cli/commands.ts:398readPluginAuthis called inintegrations/openclaw/cli/config-file.tsto load stored credentials. Sources: integrations/openclaw/cli/config-file.ts:126-144readFullConfigis invoked to read the persistent JSON config store. Sources: integrations/openclaw/cli/config-file.ts:52-78existschecks whether~/.openclaw/openclaw.jsonexists on disk viafs-safe.ts. Sources: integrations/openclaw/fs-safe.ts:15-17
Similarly, when reading configuration text, the call trace flows from registerCliCommands → readPluginAuth → readFullConfig → readText:
registerCliCommandsinitializes command bindings. Sources: integrations/openclaw/cli/commands.ts:398readPluginAuthcallsreadFullConfig. Sources: integrations/openclaw/cli/config-file.ts:126-144readFullConfigcallsreadTextto load file data. Sources: integrations/openclaw/cli/config-file.ts:52-78readTextreads the file as UTF-8 text viafs-safe.ts. Sources: integrations/openclaw/fs-safe.ts:10-12
Sources: integrations/openclaw/cli/commands.ts:398, integrations/openclaw/cli/config-file.ts:52-144, integrations/openclaw/fs-safe.ts:10-17
Tip
writeFullConfig re-reads disk content immediately before writing to deep-merge OpenClaw-managed fields (installs, slots), preventing concurrent processes from clobbering gateway state.
Sources: integrations/openclaw/cli/config-file.ts:87-116
Interactive Open Source Setup Wizard
OSS Provider Configurations and Builders
The OpenClaw setup wizard defines provider definitions, config builders, and flag validation logic in integrations/openclaw/cli/oss-wizard.ts. Three distinct categories of providers are supported: LLM providers, embedder providers, and vector store providers. Each provider definition specifies default models, URLs, API key requirements, and environment variables.
| Provider Category | Supported Identifiers | Default Model / Port | Key Requirements |
|---|---|---|---|
| LLM | openai, ollama, anthropic | gpt-5-mini, llama3.1:8b, claude-sonnet-4-5-20250514 | Requires API key for OpenAI and Anthropic; ollama requires a base URL. |
| Embedder | openai, ollama | text-embedding-3-small, nomic-embed-text | Requires API key for OpenAI; ollama defaults to http://localhost:11434. |
| Vector Store | qdrant, pgvector | Ports 6333 (Qdrant) and 5432 (PostgreSQL) | qdrant configures onDisk: true; pgvector requires user, password, and database name. |
Sources: integrations/openclaw/cli/oss-wizard.ts:25-52
Config builders process user inputs or command-line flags to assemble configuration objects. buildOssLlmConfig validates the provider ID against LLM_PROVIDERS and returns the provider name alongside a config record containing the selected model and optional API key or Ollama URL.
Sources: integrations/openclaw/cli/oss-wizard.ts:78-93
export function buildOssLlmConfig(
providerId: string,
input: LlmConfigInput,
): { provider: string; config: Record<string, unknown> } {
const def = LLM_PROVIDERS.find((p) => p.id === providerId);
if (!def) throw new Error(`Unknown LLM provider: ${providerId}`);
const config: Record<string, unknown> = {
model: input.model || def.defaultModel,
};
if (input.apiKey) config.apiKey = input.apiKey;
if (providerId === "ollama") {
config.url = input.url || def.defaultUrl;
}
return { provider: providerId, config };
}Sources: integrations/openclaw/cli/oss-wizard.ts:78-93
Embedding Dimension Calculation and Vector Connectivity
Embedding dimensions are resolved dynamically using KNOWN_EMBEDDER_DIMS or fall back to the provider default dimensions. The collection name is derived using collectionNameForDims, which formats the dimension count into a standard string.
Sources: integrations/openclaw/cli/oss-wizard.ts:54-66
export const KNOWN_EMBEDDER_DIMS: Record<string, number> = {
"text-embedding-3-small": 1536,
"text-embedding-3-large": 3072,
"text-embedding-ada-002": 1536,
"nomic-embed-text": 768,
"mxbai-embed-large": 1024,
"all-minilm": 384,
"snowflake-arctic-embed": 1024,
};
export function collectionNameForDims(dims: number): string {
return `mem0_${dims}d`;
}Sources: integrations/openclaw/cli/oss-wizard.ts:54-66
buildOssVectorConfig assigns vector store parameters, setting dimension, embeddingModelDims, and the computed collectionName when dimensions are provided.
Sources: integrations/openclaw/cli/oss-wizard.ts:131-155
export function buildOssVectorConfig(
providerId: string,
input: VectorConfigInput,
): { provider: string; config: Record<string, unknown> } {
const config: Record<string, unknown> = {};
if (providerId === "qdrant") {
config.url = input.url || "http://localhost:6333";
config.onDisk = true;
if (input.apiKey) config.apiKey = input.apiKey;
} else if (providerId === "pgvector") {
config.host = input.host || "localhost";
config.port = parseInt(input.port || "5432", 10);
if (input.user) config.user = input.user;
if (input.password) config.password = input.password;
config.dbname = input.dbname || "postgres";
}
if (input.dims) {
config.dimension = input.dims;
config.embeddingModelDims = input.dims;
config.collectionName = collectionNameForDims(input.dims);
}
return { provider: providerId, config };
}Sources: integrations/openclaw/cli/oss-wizard.ts:131-155
Connectivity verification functions test network reachability with a 3000ms timeout. checkOllamaConnectivity pings /api/tags, checkQdrantConnectivity requests /healthz, and checkPgConnectivity attempts a TCP socket connection using node:net.
Sources: integrations/openclaw/cli/oss-wizard.ts:157-186
export async function checkOllamaConnectivity(url: string): Promise<{ ok: boolean; error?: string }> {
try {
const resp = await fetch(`${url.replace(/\/+$/, "")}/api/tags`, { signal: AbortSignal.timeout(3000) });
if (resp.ok) return { ok: true };
return { ok: false, error: `Ollama returned HTTP ${resp.status}` };
} catch {
return { ok: false, error: `Cannot reach Ollama at ${url}. Install: https://ollama.com/download` };
}
}
export async function checkPgConnectivity(host: string, port: number): Promise<{ ok: boolean; error?: string }> {
return new Promise((resolve) => {
import("node:net").then(({ createConnection }) => {
const sock = createConnection({ host, port, timeout: 3000 });
sock.once("connect", () => { sock.destroy(); resolve({ ok: true }); });
sock.once("timeout", () => { sock.destroy(); resolve({ ok: false, error: `PostgreSQL not reachable at ${host}:${port}` }); });
sock.once("error", () => { sock.destroy(); resolve({ ok: false, error: `PostgreSQL not reachable at ${host}:${port}. Ensure PostgreSQL with pgvector extension is running.` }); });
});
});
}
export async function checkQdrantConnectivity(url: string): Promise<{ ok: boolean; error?: string }> {
try {
const resp = await fetch(`${url.replace(/\/+$/, "")}/healthz`, { signal: AbortSignal.timeout(3000) });
if (resp.ok) return { ok: true };
return { ok: false, error: `Qdrant returned HTTP ${resp.status}` };
} catch (err) {
return { ok: false, error: `Cannot reach Qdrant at ${url}. Start it with: docker run -d -p 6333:6333 qdrant/qdrant` };
}
}Sources: integrations/openclaw/cli/oss-wizard.ts:157-186
Warning
validateOssFlags enforces strict parameter dependencies: if an LLM or embedder provider requires an API key (needsApiKey), omitting --oss-llm-key or --oss-embedder-key returns an immediate validation error. Similarly, configuring pgvector without specifying --oss-vector-user causes validation to fail.
Sources: integrations/openclaw/cli/oss-wizard.ts:211-238
Related
On This Page
OverviewPlugin Lifecycle and Hook RegistrationPer-Agent Isolation and ScopingSession Trigger Filtering and Subagent DetectionUser Identification Resolution and Session ParsingMemory Tool Execution and CRUDTool Registration and Execution LifecycleSearch, Retrieval, and Listing HandlersStorage, Mutation, and Deletion SafeguardsToken-Budgeted Category-Ranked Recall EngineQuery Sanitization and Vector RetrievalCategory Ranking and Importance DefaultsToken Budgeting and FormattingCLI Subcommands and Authentication HelpersCommand Subsections and Configuration PersistenceCredential Resolution and Execution TraceInteractive Open Source Setup WizardOSS Provider Configurations and BuildersEmbedding Dimension Calculation and Vector ConnectivityRelated