Compare commits

..
Author SHA1 Message Date
mintlify[bot] 2a87b506e8 Fix broken link to removed expiration-date page
Generated-By: mintlify-agent
2026-04-17 00:08:29 +00:00
191 changed files with 16922 additions and 9392 deletions
-40
View File
@@ -14,48 +14,8 @@ on:
- 'mem0/**' - 'mem0/**'
- 'tests/**' - 'tests/**'
- 'embedchain/**' - 'embedchain/**'
- 'pyproject.toml'
jobs: jobs:
changelog_check:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Require CHANGELOG entry when Python SDK version changes
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
extract_version() {
python3 -c "import sys, re; m = re.search(r'^\s*version\s*=\s*\"([^\"]+)\"', sys.stdin.read(), re.M); print(m.group(1) if m else '')"
}
base_version=$(git show "$BASE_SHA:pyproject.toml" 2>/dev/null | extract_version || echo "")
head_version=$(extract_version < pyproject.toml)
echo "Base version: ${base_version:-<unknown>}"
echo "Head version: $head_version"
if [ -z "$base_version" ] || [ "$base_version" = "$head_version" ]; then
echo "pyproject.toml version unchanged — no CHANGELOG entry required."
exit 0
fi
echo "Detected version bump ${base_version} -> ${head_version}. Checking docs/changelog/sdk.mdx…"
if git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- docs/changelog/sdk.mdx | grep -q .; then
echo "Changelog update present in docs/changelog/sdk.mdx ✅"
else
echo "::error file=pyproject.toml::pyproject.toml version changed from ${base_version} to ${head_version} but docs/changelog/sdk.mdx was not updated in this PR. Add a new <Update> entry under the Python tab for v${head_version}."
exit 1
fi
check_changes: check_changes:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
-45
View File
@@ -1,45 +0,0 @@
name: docs - llms.txt check
# Blocks PRs that introduce new .mdx pages without a matching entry in
# docs/llms.txt, or that link to pages that no longer exist. Contributors
# must update docs/llms.txt in the same PR. Run locally with:
# python scripts/check-llms-txt-coverage.py # read-only
# python scripts/check-llms-txt-coverage.py --write # scaffold placeholders
on:
pull_request:
paths:
- 'docs/**/*.mdx'
- 'docs/llms.txt'
- 'scripts/check-llms-txt-coverage.py'
- 'scripts/llms-txt-ignore.txt'
workflow_dispatch: {}
permissions:
contents: read
jobs:
check-llms-txt:
runs-on: ubuntu-24.04-arm
timeout-minutes: 2
steps:
- uses: actions/checkout@v4
- name: Verify docs/llms.txt coverage
run: |
if ! python3 scripts/check-llms-txt-coverage.py; then
echo ""
echo "::error title=llms.txt out of sync::docs/llms.txt does not match docs/**/*.mdx."
echo ""
echo "To fix:"
echo " 1. Run locally: python scripts/check-llms-txt-coverage.py --write"
echo " This appends placeholder entries under '## Unclassified - needs triage'."
echo " 2. For each placeholder:"
echo " - replace [TODO: Platform|OSS|Both] with the correct scope tag"
echo " - rewrite the description as 'Use when ...'"
echo " - move the entry into the appropriate section"
echo " - delete the '## Unclassified - needs triage' heading once empty"
echo " 3. Resolve any stale URLs listed above by updating or removing the link."
echo " 4. Commit the updated docs/llms.txt to this PR."
exit 1
fi
-36
View File
@@ -24,42 +24,6 @@ jobs:
ts_sdk: ts_sdk:
- 'mem0-ts/**' - 'mem0-ts/**'
changelog_check:
needs: check_changes
if: github.event_name == 'pull_request' && needs.check_changes.outputs.ts_sdk_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Require CHANGELOG entry when SDK version changes
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
base_version=$(git show "$BASE_SHA:mem0-ts/package.json" 2>/dev/null | jq -r .version || echo "")
head_version=$(jq -r .version mem0-ts/package.json)
echo "Base version: ${base_version:-<unknown>}"
echo "Head version: $head_version"
if [ -z "$base_version" ] || [ "$base_version" = "$head_version" ]; then
echo "mem0-ts/package.json version unchanged — no CHANGELOG entry required."
exit 0
fi
echo "Detected version bump ${base_version} -> ${head_version}. Checking docs/changelog/sdk.mdx…"
if git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- docs/changelog/sdk.mdx | grep -q .; then
echo "Changelog update present in docs/changelog/sdk.mdx ✅"
else
echo "::error file=mem0-ts/package.json::mem0-ts/package.json version changed from ${base_version} to ${head_version} but docs/changelog/sdk.mdx was not updated in this PR. Add a new <Update> entry under the TypeScript tab for v${head_version}."
exit 1
fi
build_ts_sdk: build_ts_sdk:
needs: check_changes needs: check_changes
if: needs.check_changes.outputs.ts_sdk_changed == 'true' if: needs.check_changes.outputs.ts_sdk_changed == 'true'
-3
View File
@@ -35,7 +35,6 @@ This is a **polyglot monorepo** containing Python and TypeScript packages, CLIs,
| `cookbooks/` | Jupyter notebooks — customer support chatbot, AutoGen integration | | `cookbooks/` | Jupyter notebooks — customer support chatbot, AutoGen integration |
| `embedchain/` | Legacy Embedchain RAG framework (maintained separately, Poetry-based) | | `embedchain/` | Legacy Embedchain RAG framework (maintained separately, Poetry-based) |
| `pr-reviews/` | Pull request review materials | | `pr-reviews/` | Pull request review materials |
| `scripts/` | Repo-wide utility scripts (e.g., `check-llms-txt-coverage.py` for docs/llms.txt sync) |
### Core Package Dependencies ### Core Package Dependencies
@@ -434,7 +433,6 @@ To add a new LLM, embedding, vector store, or reranker provider:
|----------|------|---------| |----------|------|---------|
| Issue Labeler | `issue-labeler.yml` | Automatic issue labeling | | Issue Labeler | `issue-labeler.yml` | Automatic issue labeling |
| Stale Bot | `stale.yml` | Marks stale issues and PRs | | Stale Bot | `stale.yml` | Marks stale issues and PRs |
| llms.txt Check | `docs-llms-txt-check.yml` | Blocks PRs touching `docs/**/*.mdx` when `docs/llms.txt` is out of sync. Fix locally with `python scripts/check-llms-txt-coverage.py --write`. |
## Task Completion Guidelines ## Task Completion Guidelines
@@ -453,7 +451,6 @@ These guidelines outline typical artifacts for different task types. Use judgmen
2. **Unit tests**: Comprehensive test coverage for new functionality 2. **Unit tests**: Comprehensive test coverage for new functionality
3. **Documentation**: Update relevant docs in `docs/` for public APIs 3. **Documentation**: Update relevant docs in `docs/` for public APIs
4. **Examples**: Add usage examples if the feature introduces new user-facing behavior 4. **Examples**: Add usage examples if the feature introduces new user-facing behavior
5. **llms.txt**: Any new `.mdx` page under `docs/` must be linked in `docs/llms.txt` with a scope tag (`[Platform]` / `[OSS]` / `[Both]`) and a `Use when ...` description. The `docs-llms-txt-check.yml` workflow runs on every PR that touches docs and **fails the check** if the index is out of sync. To fix: run `python scripts/check-llms-txt-coverage.py --write` locally to scaffold placeholders under `## Unclassified - needs triage`, then replace the `[TODO: ...]` tags, rewrite descriptions as `Use when ...`, move entries into the right section, and delete the triage heading when empty.
### New Provider (LLM / Embedding / Vector Store / Reranker) ### New Provider (LLM / Embedding / Vector Store / Reranker)
+3
View File
@@ -42,6 +42,9 @@ clean:
test: test:
hatch run test hatch run test
test-py-3.9:
hatch run dev_py_3_9:test
test-py-3.10: test-py-3.10:
hatch run dev_py_3_10:test hatch run dev_py_3_10:test
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@mem0/cli", "name": "@mem0/cli",
"version": "0.2.4", "version": "0.2.3",
"description": "The official CLI for mem0 — the memory layer for AI agents", "description": "The official CLI for mem0 — the memory layer for AI agents",
"type": "module", "type": "module",
"bin": { "bin": {
+3
View File
@@ -15,6 +15,7 @@ export interface AddOptions {
infer?: boolean; infer?: boolean;
expires?: string; expires?: string;
categories?: string[]; categories?: string[];
enableGraph?: boolean;
} }
export interface SearchOptions { export interface SearchOptions {
@@ -28,6 +29,7 @@ export interface SearchOptions {
keyword?: boolean; keyword?: boolean;
filters?: Record<string, unknown>; filters?: Record<string, unknown>;
fields?: string[]; fields?: string[];
enableGraph?: boolean;
} }
export interface ListOptions { export interface ListOptions {
@@ -40,6 +42,7 @@ export interface ListOptions {
category?: string; category?: string;
after?: string; after?: string;
before?: string; before?: string;
enableGraph?: boolean;
} }
export interface DeleteOptions { export interface DeleteOptions {
+6 -3
View File
@@ -115,9 +115,10 @@ export class PlatformBackend implements Backend {
if (opts.infer === false) payload.infer = false; if (opts.infer === false) payload.infer = false;
if (opts.expires) payload.expiration_date = opts.expires; if (opts.expires) payload.expiration_date = opts.expires;
if (opts.categories) payload.categories = opts.categories; if (opts.categories) payload.categories = opts.categories;
if (opts.enableGraph) payload.enable_graph = true;
payload.source = "CLI"; payload.source = "CLI";
return (await this._request("POST", "/v3/memories/add/", { return (await this._request("POST", "/v1/memories/", {
json: payload, json: payload,
})) as Record<string, unknown>; })) as Record<string, unknown>;
} }
@@ -175,9 +176,10 @@ export class PlatformBackend implements Backend {
if (opts.rerank) payload.rerank = true; if (opts.rerank) payload.rerank = true;
if (opts.keyword) payload.keyword_search = true; if (opts.keyword) payload.keyword_search = true;
if (opts.fields) payload.fields = opts.fields; if (opts.fields) payload.fields = opts.fields;
if (opts.enableGraph) payload.enable_graph = true;
payload.source = "CLI"; payload.source = "CLI";
const result = (await this._request("POST", "/v3/memories/search/", { const result = (await this._request("POST", "/v2/memories/search/", {
json: payload, json: payload,
})) as unknown; })) as unknown;
if (Array.isArray(result)) return result; if (Array.isArray(result)) return result;
@@ -225,9 +227,10 @@ export class PlatformBackend implements Backend {
extraFilters: Object.keys(extra).length > 0 ? extra : undefined, extraFilters: Object.keys(extra).length > 0 ? extra : undefined,
}); });
if (apiFilters) payload.filters = apiFilters; if (apiFilters) payload.filters = apiFilters;
if (opts.enableGraph) payload.enable_graph = true;
payload.source = "CLI"; payload.source = "CLI";
const result = (await this._request("POST", "/v3/memories/", { const result = (await this._request("POST", "/v2/memories/", {
json: payload, json: payload,
params, params,
})) as unknown; })) as unknown;
+2
View File
@@ -29,6 +29,7 @@ export function cmdConfigShow(opts: { output?: string } = {}): void {
agent_id: config.defaults.agentId || null, agent_id: config.defaults.agentId || null,
app_id: config.defaults.appId || null, app_id: config.defaults.appId || null,
run_id: config.defaults.runId || null, run_id: config.defaults.runId || null,
enable_graph: config.defaults.enableGraph,
}, },
platform: { platform: {
api_key: redactKey(config.platform.apiKey), api_key: redactKey(config.platform.apiKey),
@@ -55,6 +56,7 @@ export function cmdConfigShow(opts: { output?: string } = {}): void {
]); ]);
table.push(["defaults.app_id", config.defaults.appId || dim("(not set)")]); table.push(["defaults.app_id", config.defaults.appId || dim("(not set)")]);
table.push(["defaults.run_id", config.defaults.runId || dim("(not set)")]); table.push(["defaults.run_id", config.defaults.runId || dim("(not set)")]);
table.push(["defaults.enable_graph", String(config.defaults.enableGraph)]);
table.push(["", ""]); table.push(["", ""]);
// Platform // Platform
+6
View File
@@ -49,6 +49,7 @@ export async function cmdAdd(
noInfer: boolean; noInfer: boolean;
expires?: string; expires?: string;
categories?: string; categories?: string;
enableGraph: boolean;
output: string; output: string;
}, },
): Promise<void> { ): Promise<void> {
@@ -139,6 +140,7 @@ export async function cmdAdd(
infer: !opts.noInfer, infer: !opts.noInfer,
expires: opts.expires, expires: opts.expires,
categories: cats, categories: cats,
enableGraph: opts.enableGraph,
}); });
}); });
} catch (e) { } catch (e) {
@@ -223,6 +225,7 @@ export async function cmdSearch(
keyword: boolean; keyword: boolean;
filterJson?: string; filterJson?: string;
fields?: string; fields?: string;
enableGraph: boolean;
output: string; output: string;
}, },
): Promise<void> { ): Promise<void> {
@@ -271,6 +274,7 @@ export async function cmdSearch(
keyword: opts.keyword, keyword: opts.keyword,
filters, filters,
fields: fieldList, fields: fieldList,
enableGraph: opts.enableGraph,
}); });
}); });
} catch (e) { } catch (e) {
@@ -364,6 +368,7 @@ export async function cmdList(
category?: string; category?: string;
after?: string; after?: string;
before?: string; before?: string;
enableGraph: boolean;
output: string; output: string;
}, },
): Promise<void> { ): Promise<void> {
@@ -391,6 +396,7 @@ export async function cmdList(
category: opts.category, category: opts.category,
after: opts.after, after: opts.after,
before: opts.before, before: opts.before,
enableGraph: opts.enableGraph,
}); });
}); });
} catch (e) { } catch (e) {
+13
View File
@@ -28,6 +28,7 @@ export interface DefaultsConfig {
agentId: string; agentId: string;
appId: string; appId: string;
runId: string; runId: string;
enableGraph: boolean;
} }
export interface TelemetryConfig { export interface TelemetryConfig {
@@ -49,6 +50,7 @@ export function createDefaultConfig(): Mem0Config {
agentId: "", agentId: "",
appId: "", appId: "",
runId: "", runId: "",
enableGraph: false,
}, },
platform: { platform: {
apiKey: "", apiKey: "",
@@ -85,6 +87,8 @@ export function loadConfig(): Mem0Config {
config.defaults.agentId = defaults.agent_id ?? ""; config.defaults.agentId = defaults.agent_id ?? "";
config.defaults.appId = defaults.app_id ?? ""; config.defaults.appId = defaults.app_id ?? "";
config.defaults.runId = defaults.run_id ?? ""; config.defaults.runId = defaults.run_id ?? "";
config.defaults.enableGraph = defaults.enable_graph ?? false;
const telemetry = data.telemetry ?? {}; const telemetry = data.telemetry ?? {};
config.telemetry.anonymousId = telemetry.anonymous_id ?? ""; config.telemetry.anonymousId = telemetry.anonymous_id ?? "";
} }
@@ -100,6 +104,12 @@ export function loadConfig(): Mem0Config {
config.defaults.agentId = process.env.MEM0_AGENT_ID; config.defaults.agentId = process.env.MEM0_AGENT_ID;
if (process.env.MEM0_APP_ID) config.defaults.appId = process.env.MEM0_APP_ID; if (process.env.MEM0_APP_ID) config.defaults.appId = process.env.MEM0_APP_ID;
if (process.env.MEM0_RUN_ID) config.defaults.runId = process.env.MEM0_RUN_ID; if (process.env.MEM0_RUN_ID) config.defaults.runId = process.env.MEM0_RUN_ID;
if (process.env.MEM0_ENABLE_GRAPH) {
config.defaults.enableGraph = ["true", "1", "yes"].includes(
process.env.MEM0_ENABLE_GRAPH.toLowerCase(),
);
}
return config; return config;
} }
@@ -113,6 +123,7 @@ export function saveConfig(config: Mem0Config): void {
agent_id: config.defaults.agentId, agent_id: config.defaults.agentId,
app_id: config.defaults.appId, app_id: config.defaults.appId,
run_id: config.defaults.runId, run_id: config.defaults.runId,
enable_graph: config.defaults.enableGraph,
}, },
platform: { platform: {
api_key: config.platform.apiKey, api_key: config.platform.apiKey,
@@ -143,6 +154,7 @@ const KEY_MAP: Record<string, [keyof Mem0Config, string]> = {
"defaults.agent_id": ["defaults", "agentId"], "defaults.agent_id": ["defaults", "agentId"],
"defaults.app_id": ["defaults", "appId"], "defaults.app_id": ["defaults", "appId"],
"defaults.run_id": ["defaults", "runId"], "defaults.run_id": ["defaults", "runId"],
"defaults.enable_graph": ["defaults", "enableGraph"],
// Short-form aliases // Short-form aliases
api_key: ["platform", "apiKey"], api_key: ["platform", "apiKey"],
base_url: ["platform", "baseUrl"], base_url: ["platform", "baseUrl"],
@@ -151,6 +163,7 @@ const KEY_MAP: Record<string, [keyof Mem0Config, string]> = {
agent_id: ["defaults", "agentId"], agent_id: ["defaults", "agentId"],
app_id: ["defaults", "appId"], app_id: ["defaults", "appId"],
run_id: ["defaults", "runId"], run_id: ["defaults", "runId"],
enable_graph: ["defaults", "enableGraph"],
}; };
export function getNestedValue(config: Mem0Config, dottedKey: string): unknown { export function getNestedValue(config: Mem0Config, dottedKey: string): unknown {
+24 -1
View File
@@ -134,6 +134,18 @@ function resolveIds(
}; };
} }
/**
* Resolve graph tri-state: --no-graph > --graph > config default.
*/
function resolveGraph(
config: Mem0Config,
opts: { graph?: boolean; noGraph?: boolean },
): boolean {
if (opts.noGraph) return false;
if (opts.graph) return true;
return config.defaults.enableGraph;
}
// ── Main program ────────────────────────────────────────────────────────── // ── Main program ──────────────────────────────────────────────────────────
program program
@@ -224,6 +236,8 @@ program
.option("--no-infer", "Skip inference, store raw.") .option("--no-infer", "Skip inference, store raw.")
.option("--expires <date>", "Expiration date (YYYY-MM-DD).") .option("--expires <date>", "Expiration date (YYYY-MM-DD).")
.option("--categories <value>", "Categories (JSON array or comma-separated).") .option("--categories <value>", "Categories (JSON array or comma-separated).")
.option("--graph", "Enable graph memory extraction.", false)
.option("--no-graph", "Disable graph memory extraction.")
.option("-o, --output <format>", "Output format: text, json, quiet.", "text") .option("-o, --output <format>", "Output format: text, json, quiet.", "text")
.option("--api-key <key>", "Override API key.") .option("--api-key <key>", "Override API key.")
.option("--base-url <url>", "Override API base URL.") .option("--base-url <url>", "Override API base URL.")
@@ -239,8 +253,9 @@ program
opts.baseUrl, opts.baseUrl,
); );
const ids = resolveIds(config, opts); const ids = resolveIds(config, opts);
const enableGraph = resolveGraph(config, opts);
const output = isAgent ? "agent" : opts.output; const output = isAgent ? "agent" : opts.output;
await cmdAdd(backend, text, { ...ids, ...opts, output }); await cmdAdd(backend, text, { ...ids, ...opts, enableGraph, output });
}); });
// ── Memory: search ──────────────────────────────────────────────────────── // ── Memory: search ────────────────────────────────────────────────────────
@@ -270,6 +285,8 @@ program
.option("--keyword", "Use keyword search.", false) .option("--keyword", "Use keyword search.", false)
.option("--filter <json>", "Advanced filter expression (JSON).") .option("--filter <json>", "Advanced filter expression (JSON).")
.option("--fields <list>", "Specific fields to return (comma-separated).") .option("--fields <list>", "Specific fields to return (comma-separated).")
.option("--graph", "Enable graph in search.", false)
.option("--no-graph", "Disable graph in search.")
.option("-o, --output <format>", "Output: text, json, table.", "text") .option("-o, --output <format>", "Output: text, json, table.", "text")
.option("--api-key <key>", "Override API key.") .option("--api-key <key>", "Override API key.")
.option("--base-url <url>", "Override API base URL.") .option("--base-url <url>", "Override API base URL.")
@@ -293,6 +310,7 @@ program
opts.baseUrl, opts.baseUrl,
); );
const ids = resolveIds(config, opts); const ids = resolveIds(config, opts);
const enableGraph = resolveGraph(config, opts);
const output = isAgent ? "agent" : opts.output; const output = isAgent ? "agent" : opts.output;
await cmdSearch(backend, resolvedQuery, { await cmdSearch(backend, resolvedQuery, {
...ids, ...ids,
@@ -302,6 +320,7 @@ program
keyword: opts.keyword, keyword: opts.keyword,
filterJson: opts.filter, filterJson: opts.filter,
fields: opts.fields, fields: opts.fields,
enableGraph,
output, output,
}); });
}); });
@@ -345,6 +364,8 @@ program
.option("--category <name>", "Filter by category.") .option("--category <name>", "Filter by category.")
.option("--after <date>", "Created after (YYYY-MM-DD).") .option("--after <date>", "Created after (YYYY-MM-DD).")
.option("--before <date>", "Created before (YYYY-MM-DD).") .option("--before <date>", "Created before (YYYY-MM-DD).")
.option("--graph", "Enable graph in listing.", false)
.option("--no-graph", "Disable graph in listing.")
.option("-o, --output <format>", "Output: text, json, table.", "table") .option("-o, --output <format>", "Output: text, json, table.", "table")
.option("--api-key <key>", "Override API key.") .option("--api-key <key>", "Override API key.")
.option("--base-url <url>", "Override API base URL.") .option("--base-url <url>", "Override API base URL.")
@@ -360,6 +381,7 @@ program
opts.baseUrl, opts.baseUrl,
); );
const ids = resolveIds(config, opts); const ids = resolveIds(config, opts);
const enableGraph = resolveGraph(config, opts);
const output = isAgent ? "agent" : opts.output; const output = isAgent ? "agent" : opts.output;
await cmdList(backend, { await cmdList(backend, {
...ids, ...ids,
@@ -368,6 +390,7 @@ program
category: opts.category, category: opts.category,
after: opts.after, after: opts.after,
before: opts.before, before: opts.before,
enableGraph,
output, output,
}); });
}); });
+6 -6
View File
@@ -107,22 +107,22 @@ describe("CLI Integration — help and version", () => {
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
}); });
it("add help has --output flag", () => { it("add help has --graph flag", () => {
const result = run(["add", "--help"]); const result = run(["add", "--help"]);
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.stdout).toContain("--output"); expect(result.stdout).toContain("--graph");
}); });
it("search help has --rerank flag", () => { it("search help has --graph flag", () => {
const result = run(["search", "--help"]); const result = run(["search", "--help"]);
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.stdout).toContain("--rerank"); expect(result.stdout).toContain("--graph");
}); });
it("list help has --category flag", () => { it("list help has --graph flag", () => {
const result = run(["list", "--help"]); const result = run(["list", "--help"]);
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.stdout).toContain("--category"); expect(result.stdout).toContain("--graph");
}); });
}); });
+15 -15
View File
@@ -42,7 +42,7 @@ describe("cmdAdd", () => {
userId: "alice", userId: "alice",
immutable: false, immutable: false,
noInfer: false, noInfer: false,
enableGraph: false,
output: "text", output: "text",
}); });
expect(mockBackend.add).toHaveBeenCalledOnce(); expect(mockBackend.add).toHaveBeenCalledOnce();
@@ -55,7 +55,7 @@ describe("cmdAdd", () => {
messages: JSON.stringify([{ role: "user", content: "I love Python" }]), messages: JSON.stringify([{ role: "user", content: "I love Python" }]),
immutable: false, immutable: false,
noInfer: false, noInfer: false,
enableGraph: false,
output: "text", output: "text",
}); });
expect(mockBackend.add).toHaveBeenCalledOnce(); expect(mockBackend.add).toHaveBeenCalledOnce();
@@ -67,7 +67,7 @@ describe("cmdAdd", () => {
userId: "alice", userId: "alice",
immutable: false, immutable: false,
noInfer: false, noInfer: false,
enableGraph: false,
output: "json", output: "json",
}); });
expect(output).toContain("results"); expect(output).toContain("results");
@@ -79,7 +79,7 @@ describe("cmdAdd", () => {
userId: "alice", userId: "alice",
immutable: false, immutable: false,
noInfer: false, noInfer: false,
enableGraph: false,
output: "quiet", output: "quiet",
}); });
expect(output).not.toContain("dark mode"); expect(output).not.toContain("dark mode");
@@ -101,7 +101,7 @@ describe("cmdAdd deduplicates PENDING", () => {
userId: "alice", userId: "alice",
immutable: false, immutable: false,
noInfer: false, noInfer: false,
enableGraph: false,
output: "text", output: "text",
}); });
expect(output.match(/Queued/g)?.length).toBe(1); expect(output.match(/Queued/g)?.length).toBe(1);
@@ -114,7 +114,7 @@ describe("cmdAdd deduplicates PENDING", () => {
userId: "alice", userId: "alice",
immutable: false, immutable: false,
noInfer: false, noInfer: false,
enableGraph: false,
output: "json", output: "json",
}); });
const data = JSON.parse(output); const data = JSON.parse(output);
@@ -130,7 +130,7 @@ describe("cmdAdd deduplicates PENDING", () => {
userId: "alice", userId: "alice",
immutable: false, immutable: false,
noInfer: false, noInfer: false,
enableGraph: false,
output: "agent", output: "agent",
}); });
const data = JSON.parse(output); const data = JSON.parse(output);
@@ -148,7 +148,7 @@ describe("cmdSearch", () => {
threshold: 0.3, threshold: 0.3,
rerank: false, rerank: false,
keyword: false, keyword: false,
enableGraph: false,
output: "text", output: "text",
}); });
expect(output).toContain("Found 2"); expect(output).toContain("Found 2");
@@ -162,7 +162,7 @@ describe("cmdSearch", () => {
threshold: 0.3, threshold: 0.3,
rerank: false, rerank: false,
keyword: false, keyword: false,
enableGraph: false,
output: "json", output: "json",
}); });
expect(output).toContain("memory"); expect(output).toContain("memory");
@@ -177,7 +177,7 @@ describe("cmdSearch", () => {
threshold: 0.3, threshold: 0.3,
rerank: false, rerank: false,
keyword: false, keyword: false,
enableGraph: false,
output: "text", output: "text",
}); });
expect(errOutput).toContain("No memories found"); expect(errOutput).toContain("No memories found");
@@ -205,7 +205,7 @@ describe("cmdList", () => {
userId: "alice", userId: "alice",
page: 1, page: 1,
pageSize: 100, pageSize: 100,
enableGraph: false,
output: "table", output: "table",
}); });
expect(output).toContain("dark mode"); expect(output).toContain("dark mode");
@@ -218,7 +218,7 @@ describe("cmdList", () => {
userId: "alice", userId: "alice",
page: 1, page: 1,
pageSize: 100, pageSize: 100,
enableGraph: false,
output: "text", output: "text",
}); });
expect(errOutput).toContain("No memories found"); expect(errOutput).toContain("No memories found");
@@ -316,7 +316,7 @@ describe("agent mode", () => {
userId: "alice", userId: "alice",
immutable: false, immutable: false,
noInfer: false, noInfer: false,
enableGraph: false,
output: "agent", output: "agent",
}); });
const parsed = JSON.parse(output.trim()); const parsed = JSON.parse(output.trim());
@@ -336,7 +336,7 @@ describe("agent mode", () => {
threshold: 0.3, threshold: 0.3,
rerank: false, rerank: false,
keyword: false, keyword: false,
enableGraph: false,
output: "agent", output: "agent",
}); });
const parsed = JSON.parse(output.trim()); const parsed = JSON.parse(output.trim());
@@ -361,7 +361,7 @@ describe("agent mode", () => {
userId: "alice", userId: "alice",
page: 1, page: 1,
pageSize: 100, pageSize: 100,
enableGraph: false,
output: "agent", output: "agent",
}); });
const parsed = JSON.parse(output.trim()); const parsed = JSON.parse(output.trim());
+6
View File
@@ -64,6 +64,7 @@ describe("createDefaultConfig", () => {
expect(config.platform.baseUrl).toBe("https://api.mem0.ai"); expect(config.platform.baseUrl).toBe("https://api.mem0.ai");
expect(config.platform.apiKey).toBe(""); expect(config.platform.apiKey).toBe("");
expect(config.defaults.userId).toBe(""); expect(config.defaults.userId).toBe("");
expect(config.defaults.enableGraph).toBe(false);
}); });
}); });
@@ -104,4 +105,9 @@ describe("setNestedValue", () => {
expect(config.defaults.userId).toBe("bob"); expect(config.defaults.userId).toBe("bob");
}); });
it("coerces boolean for enable_graph", () => {
const config = createDefaultConfig();
expect(setNestedValue(config, "defaults.enable_graph", "true")).toBe(true);
expect(config.defaults.enableGraph).toBe(true);
});
}); });
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "mem0-cli" name = "mem0-cli"
version = "0.2.4" version = "0.2.3"
description = "The official CLI for mem0 — the memory layer for AI agents" description = "The official CLI for mem0 — the memory layer for AI agents"
readme = "README.md" readme = "README.md"
license = "Apache-2.0" license = "Apache-2.0"
+1 -1
View File
@@ -1,3 +1,3 @@
"""mem0 CLI — the command-line interface for the mem0 memory layer.""" """mem0 CLI — the command-line interface for the mem0 memory layer."""
__version__ = "0.2.4" __version__ = "0.2.3"
+38
View File
@@ -267,6 +267,8 @@ def add(
categories: str | None = typer.Option( categories: str | None = typer.Option(
None, "--categories", help="Categories (JSON array or comma-separated)." None, "--categories", help="Categories (JSON array or comma-separated)."
), ),
graph: bool = typer.Option(False, "--graph", help="Enable graph memory extraction."),
no_graph: bool = typer.Option(False, "--no-graph", help="Disable graph memory extraction."),
output: str = typer.Option( output: str = typer.Option(
"text", "--output", "-o", help="Output format: text, json, quiet.", rich_help_panel="Output" "text", "--output", "-o", help="Output format: text, json, quiet.", rich_help_panel="Output"
), ),
@@ -293,6 +295,13 @@ def add(
backend, config = _get_backend_and_config(api_key, base_url) backend, config = _get_backend_and_config(api_key, base_url)
ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id) ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id)
if no_graph:
graph_enabled = False
elif graph:
graph_enabled = True
else:
graph_enabled = config.defaults.enable_graph
cmd_add( cmd_add(
backend, backend,
text, text,
@@ -304,6 +313,7 @@ def add(
no_infer=no_infer, no_infer=no_infer,
expires=expires, expires=expires,
categories=categories, categories=categories,
enable_graph=graph_enabled,
output=output, output=output,
) )
@@ -347,6 +357,12 @@ def search(
help="Specific fields to return (comma-separated).", help="Specific fields to return (comma-separated).",
rich_help_panel="Search", rich_help_panel="Search",
), ),
graph: bool = typer.Option(
False, "--graph", help="Enable graph in search.", rich_help_panel="Search"
),
no_graph: bool = typer.Option(
False, "--no-graph", help="Disable graph in search.", rich_help_panel="Search"
),
output: str = typer.Option( output: str = typer.Option(
"text", "--output", "-o", help="Output: text, json, table.", rich_help_panel="Output" "text", "--output", "-o", help="Output: text, json, table.", rich_help_panel="Output"
), ),
@@ -380,6 +396,13 @@ def search(
backend, config = _get_backend_and_config(api_key, base_url) backend, config = _get_backend_and_config(api_key, base_url)
ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id) ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id)
if no_graph:
graph_enabled = False
elif graph:
graph_enabled = True
else:
graph_enabled = config.defaults.enable_graph
cmd_search( cmd_search(
backend, backend,
query, query,
@@ -390,6 +413,7 @@ def search(
keyword=keyword, keyword=keyword,
filter_json=filter_json, filter_json=filter_json,
fields=fields, fields=fields,
enable_graph=graph_enabled,
output=output, output=output,
) )
@@ -456,6 +480,12 @@ def list_cmd(
before: str | None = typer.Option( before: str | None = typer.Option(
None, "--before", help="Created before (YYYY-MM-DD).", rich_help_panel="Filters" None, "--before", help="Created before (YYYY-MM-DD).", rich_help_panel="Filters"
), ),
graph: bool = typer.Option(
False, "--graph", help="Enable graph in listing.", rich_help_panel="Filters"
),
no_graph: bool = typer.Option(
False, "--no-graph", help="Disable graph in listing.", rich_help_panel="Filters"
),
output: str = typer.Option( output: str = typer.Option(
"table", "--output", "-o", help="Output: text, json, table.", rich_help_panel="Output" "table", "--output", "-o", help="Output: text, json, table.", rich_help_panel="Output"
), ),
@@ -481,6 +511,13 @@ def list_cmd(
backend, config = _get_backend_and_config(api_key, base_url) backend, config = _get_backend_and_config(api_key, base_url)
ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id) ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id)
if no_graph:
graph_enabled = False
elif graph:
graph_enabled = True
else:
graph_enabled = config.defaults.enable_graph
cmd_list( cmd_list(
backend, backend,
**ids, **ids,
@@ -489,6 +526,7 @@ def list_cmd(
category=category, category=category,
after=after, after=after,
before=before, before=before,
enable_graph=graph_enabled,
output=output, output=output,
) )
+3
View File
@@ -26,6 +26,7 @@ class Backend(ABC):
infer: bool = True, infer: bool = True,
expires: str | None = None, expires: str | None = None,
categories: list[str] | None = None, categories: list[str] | None = None,
enable_graph: bool = False,
) -> dict: ... ) -> dict: ...
@abstractmethod @abstractmethod
@@ -43,6 +44,7 @@ class Backend(ABC):
keyword: bool = False, keyword: bool = False,
filters: dict | None = None, filters: dict | None = None,
fields: list[str] | None = None, fields: list[str] | None = None,
enable_graph: bool = False,
) -> list[dict]: ... ) -> list[dict]: ...
@abstractmethod @abstractmethod
@@ -61,6 +63,7 @@ class Backend(ABC):
category: str | None = None, category: str | None = None,
after: str | None = None, after: str | None = None,
before: str | None = None, before: str | None = None,
enable_graph: bool = False,
) -> list[dict]: ... ) -> list[dict]: ...
@abstractmethod @abstractmethod
+14 -5
View File
@@ -64,6 +64,7 @@ class PlatformBackend(Backend):
infer: bool = True, infer: bool = True,
expires: str | None = None, expires: str | None = None,
categories: list[str] | None = None, categories: list[str] | None = None,
enable_graph: bool = False,
) -> dict: ) -> dict:
payload: dict[str, Any] = {} payload: dict[str, Any] = {}
@@ -90,9 +91,11 @@ class PlatformBackend(Backend):
payload["expiration_date"] = expires payload["expiration_date"] = expires
if categories: if categories:
payload["categories"] = categories payload["categories"] = categories
if enable_graph:
payload["enable_graph"] = True
payload["source"] = "CLI" payload["source"] = "CLI"
return self._request("POST", "/v3/memories/add/", json=payload) return self._request("POST", "/v1/memories/", json=payload)
def _build_filters( def _build_filters(
self, self,
@@ -103,7 +106,7 @@ class PlatformBackend(Backend):
run_id: str | None = None, run_id: str | None = None,
extra_filters: dict | None = None, extra_filters: dict | None = None,
) -> dict | None: ) -> dict | None:
"""Build a filters dict for v3 API endpoints. """Build a filters dict for v2 API endpoints.
Entity IDs are ANDed (all provided IDs must match). Entity IDs are ANDed (all provided IDs must match).
Extra filters (date ranges, categories) are also ANDed. Extra filters (date ranges, categories) are also ANDed.
@@ -149,6 +152,7 @@ class PlatformBackend(Backend):
keyword: bool = False, keyword: bool = False,
filters: dict | None = None, filters: dict | None = None,
fields: list[str] | None = None, fields: list[str] | None = None,
enable_graph: bool = False,
) -> list[dict]: ) -> list[dict]:
payload: dict[str, Any] = {"query": query, "top_k": top_k, "threshold": threshold} payload: dict[str, Any] = {"query": query, "top_k": top_k, "threshold": threshold}
@@ -167,9 +171,11 @@ class PlatformBackend(Backend):
payload["keyword_search"] = True payload["keyword_search"] = True
if fields: if fields:
payload["fields"] = fields payload["fields"] = fields
if enable_graph:
payload["enable_graph"] = True
payload["source"] = "CLI" payload["source"] = "CLI"
result = self._request("POST", "/v3/memories/search/", json=payload) result = self._request("POST", "/v2/memories/search/", json=payload)
return ( return (
result result
if isinstance(result, list) if isinstance(result, list)
@@ -191,11 +197,12 @@ class PlatformBackend(Backend):
category: str | None = None, category: str | None = None,
after: str | None = None, after: str | None = None,
before: str | None = None, before: str | None = None,
enable_graph: bool = False,
) -> list[dict]: ) -> list[dict]:
payload: dict[str, Any] = {} payload: dict[str, Any] = {}
params = {"page": str(page), "page_size": str(page_size)} params = {"page": str(page), "page_size": str(page_size)}
# Build filters — entity IDs and date filters go inside "filters" # Build filters for v2 API — entity IDs and date filters go inside "filters"
extra: dict[str, Any] = {} extra: dict[str, Any] = {}
if category: if category:
extra["categories"] = {"contains": category} extra["categories"] = {"contains": category}
@@ -213,9 +220,11 @@ class PlatformBackend(Backend):
) )
if api_filters: if api_filters:
payload["filters"] = api_filters payload["filters"] = api_filters
if enable_graph:
payload["enable_graph"] = True
payload["source"] = "CLI" payload["source"] = "CLI"
result = self._request("POST", "/v3/memories/", json=payload, params=params) result = self._request("POST", "/v2/memories/", json=payload, params=params)
return ( return (
result result
if isinstance(result, list) if isinstance(result, list)
@@ -39,6 +39,7 @@ def cmd_config_show(*, output: str = "text") -> None:
"agent_id": config.defaults.agent_id or None, "agent_id": config.defaults.agent_id or None,
"app_id": config.defaults.app_id or None, "app_id": config.defaults.app_id or None,
"run_id": config.defaults.run_id or None, "run_id": config.defaults.run_id or None,
"enable_graph": config.defaults.enable_graph,
}, },
"platform": { "platform": {
"api_key": redact_key(config.platform.api_key), "api_key": redact_key(config.platform.api_key),
@@ -72,6 +73,10 @@ def cmd_config_show(*, output: str = "text") -> None:
"defaults.run_id", "defaults.run_id",
config.defaults.run_id or f"[{DIM_COLOR}](not set)[/]", config.defaults.run_id or f"[{DIM_COLOR}](not set)[/]",
) )
table.add_row(
"defaults.enable_graph",
str(config.defaults.enable_graph).lower(),
)
table.add_row("", "") table.add_row("", "")
# Platform # Platform
@@ -62,6 +62,7 @@ def cmd_add(
no_infer: bool, no_infer: bool,
expires: str | None, expires: str | None,
categories: str | None, categories: str | None,
enable_graph: bool = False,
output: str = "text", output: str = "text",
) -> None: ) -> None:
"""Add a memory.""" """Add a memory."""
@@ -144,6 +145,7 @@ def cmd_add(
infer=not no_infer, infer=not no_infer,
expires=expires, expires=expires,
categories=cats, categories=cats,
enable_graph=enable_graph,
) )
except Exception as e: except Exception as e:
ts.error_msg = str(e) ts.error_msg = str(e)
@@ -224,6 +226,7 @@ def cmd_search(
keyword: bool, keyword: bool,
filter_json: str | None, filter_json: str | None,
fields: str | None, fields: str | None,
enable_graph: bool = False,
output: str = "text", output: str = "text",
) -> None: ) -> None:
"""Search memories.""" """Search memories."""
@@ -266,6 +269,7 @@ def cmd_search(
keyword=keyword, keyword=keyword,
filters=filters, filters=filters,
fields=field_list, fields=field_list,
enable_graph=enable_graph,
) )
except Exception as e: except Exception as e:
print_error(err_console, str(e)) print_error(err_console, str(e))
@@ -352,6 +356,7 @@ def cmd_list(
category: str | None, category: str | None,
after: str | None, after: str | None,
before: str | None, before: str | None,
enable_graph: bool = False,
output: str = "table", output: str = "table",
) -> None: ) -> None:
"""List memories.""" """List memories."""
@@ -380,6 +385,7 @@ def cmd_list(
category=category, category=category,
after=after, after=after,
before=before, before=before,
enable_graph=enable_graph,
) )
except Exception as e: except Exception as e:
print_error(err_console, str(e)) print_error(err_console, str(e))
+9
View File
@@ -36,6 +36,7 @@ class DefaultsConfig:
agent_id: str = "" agent_id: str = ""
app_id: str = "" app_id: str = ""
run_id: str = "" run_id: str = ""
enable_graph: bool = False
@dataclass @dataclass
@@ -59,6 +60,7 @@ SHORT_KEY_ALIASES: dict[str, str] = {
"agent_id": "defaults.agent_id", "agent_id": "defaults.agent_id",
"app_id": "defaults.app_id", "app_id": "defaults.app_id",
"run_id": "defaults.run_id", "run_id": "defaults.run_id",
"enable_graph": "defaults.enable_graph",
} }
@@ -89,6 +91,8 @@ def load_config() -> Mem0Config:
config.defaults.agent_id = defaults.get("agent_id", "") config.defaults.agent_id = defaults.get("agent_id", "")
config.defaults.app_id = defaults.get("app_id", "") config.defaults.app_id = defaults.get("app_id", "")
config.defaults.run_id = defaults.get("run_id", "") config.defaults.run_id = defaults.get("run_id", "")
config.defaults.enable_graph = defaults.get("enable_graph", False)
telemetry = data.get("telemetry", {}) telemetry = data.get("telemetry", {})
config.telemetry.anonymous_id = telemetry.get("anonymous_id", "") config.telemetry.anonymous_id = telemetry.get("anonymous_id", "")
@@ -117,6 +121,10 @@ def load_config() -> Mem0Config:
if env_run_id: if env_run_id:
config.defaults.run_id = env_run_id config.defaults.run_id = env_run_id
env_graph = os.environ.get("MEM0_ENABLE_GRAPH")
if env_graph:
config.defaults.enable_graph = env_graph.lower() in ("true", "1", "yes")
return config return config
@@ -131,6 +139,7 @@ def save_config(config: Mem0Config) -> None:
"agent_id": config.defaults.agent_id, "agent_id": config.defaults.agent_id,
"app_id": config.defaults.app_id, "app_id": config.defaults.app_id,
"run_id": config.defaults.run_id, "run_id": config.defaults.run_id,
"enable_graph": config.defaults.enable_graph,
}, },
"platform": { "platform": {
"api_key": config.platform.api_key, "api_key": config.platform.api_key,
+13 -2
View File
@@ -224,13 +224,24 @@ class TestCLIIsolated:
class TestCLINewFeatures: class TestCLINewFeatures:
"""Tests for MCP parity features: --limit, entities delete.""" """Tests for MCP parity features: --graph, --limit, entities delete."""
def test_search_help_has_limit(self): def test_add_help_has_graph(self):
result = _run(["add", "--help"])
assert result.returncode == 0
assert "--graph" in result.stdout
def test_search_help_has_graph_and_limit(self):
result = _run(["search", "--help"]) result = _run(["search", "--help"])
assert result.returncode == 0 assert result.returncode == 0
assert "--graph" in result.stdout
assert "--limit" in result.stdout assert "--limit" in result.stdout
def test_list_help_has_graph(self):
result = _run(["list", "--help"])
assert result.returncode == 0
assert "--graph" in result.stdout
def test_delete_entity_via_delete_flag(self): def test_delete_entity_via_delete_flag(self):
"""delete --entity should appear in help output.""" """delete --entity should appear in help output."""
result = _run(["delete", "--help"]) result = _run(["delete", "--help"])
+79
View File
@@ -997,6 +997,85 @@ class TestEntitiesDeleteCommand:
mock_backend.delete_entities.assert_not_called() mock_backend.delete_entities.assert_not_called()
class TestEnableGraph:
def test_add_with_graph(self, mock_backend):
console, _buf = _make_console()
err_console, _err_buf = _make_err_console()
with (
patch("mem0_cli.commands.memory.console", console),
patch("mem0_cli.commands.memory.err_console", err_console),
):
cmd_add(
mock_backend,
"test",
user_id="alice",
agent_id=None,
app_id=None,
run_id=None,
messages=None,
file=None,
metadata=None,
immutable=False,
no_infer=False,
expires=None,
categories=None,
enable_graph=True,
output="text",
)
call_kwargs = mock_backend.add.call_args
assert call_kwargs.kwargs.get("enable_graph") is True
def test_search_with_graph(self, mock_backend):
console, _buf = _make_console()
err_console, _err_buf = _make_err_console()
with (
patch("mem0_cli.commands.memory.console", console),
patch("mem0_cli.commands.memory.err_console", err_console),
):
cmd_search(
mock_backend,
"test",
user_id="alice",
agent_id=None,
app_id=None,
run_id=None,
top_k=10,
threshold=0.3,
rerank=False,
keyword=False,
filter_json=None,
fields=None,
enable_graph=True,
output="text",
)
call_kwargs = mock_backend.search.call_args
assert call_kwargs.kwargs.get("enable_graph") is True
def test_list_with_graph(self, mock_backend):
console, _buf = _make_console()
err_console, _err_buf = _make_err_console()
with (
patch("mem0_cli.commands.memory.console", console),
patch("mem0_cli.commands.memory.err_console", err_console),
):
cmd_list(
mock_backend,
user_id="alice",
agent_id=None,
app_id=None,
run_id=None,
page=1,
page_size=100,
category=None,
after=None,
before=None,
enable_graph=True,
output="table",
)
call_kwargs = mock_backend.list_memories.call_args
assert call_kwargs.kwargs.get("enable_graph") is True
class TestEventCommands: class TestEventCommands:
def test_event_list_table(self, mock_backend): def test_event_list_table(self, mock_backend):
console, buf = _make_console() console, buf = _make_console()
+45
View File
@@ -121,6 +121,46 @@ class TestConfig:
assert config.defaults.agent_id == "" assert config.defaults.agent_id == ""
assert config.defaults.app_id == "" assert config.defaults.app_id == ""
assert config.defaults.run_id == "" assert config.defaults.run_id == ""
assert config.defaults.enable_graph is False
def test_enable_graph_save_and_load(self, isolate_config):
config = Mem0Config()
config.defaults.enable_graph = True
save_config(config)
loaded = load_config()
assert loaded.defaults.enable_graph is True
def test_enable_graph_env_var_true(self, isolate_config, monkeypatch):
monkeypatch.setenv("MEM0_ENABLE_GRAPH", "true")
loaded = load_config()
assert loaded.defaults.enable_graph is True
def test_enable_graph_env_var_false(self, isolate_config, monkeypatch):
config = Mem0Config()
config.defaults.enable_graph = True
save_config(config)
monkeypatch.setenv("MEM0_ENABLE_GRAPH", "false")
loaded = load_config()
assert loaded.defaults.enable_graph is False
def test_backward_compat_no_enable_graph_key(self, isolate_config):
"""Old config files without 'enable_graph' key should default to False."""
import json
from mem0_cli.config import CONFIG_FILE, ensure_config_dir
ensure_config_dir()
data = {
"version": 1,
"defaults": {"user_id": "alice"},
"platform": {"api_key": "m0-test", "base_url": "https://api.mem0.ai"},
}
with open(CONFIG_FILE, "w") as f:
json.dump(data, f)
loaded = load_config()
assert loaded.defaults.enable_graph is False
assert loaded.defaults.user_id == "alice"
class TestNestedAccess: class TestNestedAccess:
@@ -152,6 +192,11 @@ class TestNestedAccess:
assert set_nested_value(config, "defaults.user_id", "bob") assert set_nested_value(config, "defaults.user_id", "bob")
assert config.defaults.user_id == "bob" assert config.defaults.user_id == "bob"
def test_set_defaults_enable_graph(self):
config = Mem0Config()
assert set_nested_value(config, "defaults.enable_graph", "true")
assert config.defaults.enable_graph is True
class TestResolveIds: class TestResolveIds:
def test_cli_flag_overrides_default(self): def test_cli_flag_overrides_default(self):
+3
View File
@@ -0,0 +1,3 @@
<Note type="info">
<strong>🎉 Mem0 1.0.0 is here!</strong> Enhanced filtering, reranking, and smarter memory management.
</Note>
-34
View File
@@ -4,40 +4,6 @@ description: "Release notes for the OpenClaw plugin and agent harness."
mode: "wide" mode: "wide"
--- ---
<Update label="2026-04-21" description="v1.0.8">
**New Features:**
- **OSS Onboarding Wizard:** New guided 4-step interactive setup for open-source mode — walks through LLM provider, embedding provider, vector store, and user ID selection with prefilled defaults
- **Agent-Friendly CLI:** Added `--json` flag to all 16 CLI commands for machine-readable output. Agents can call `openclaw mem0 help --json` to discover every command and flag
- **Non-Interactive OSS Setup:** Added `--mode open-source` with `--oss-llm`, `--oss-embedder`, `--oss-vector` flags for fully automated OSS configuration without prompts
- **JSON Helpers Module:** New `cli/json-helpers.ts` with `jsonOut`, `jsonErr`, and `redactSecrets` utilities for consistent structured output
**Improvements:**
- **Init Flow Redesigned:** Replaced 3-option flat menu with 2-level structure: Platform (email login or API key) and Open Source (guided wizard)
- **Provider Selection:** LLM providers: OpenAI, Ollama, Anthropic. Embedding providers: OpenAI, Ollama. Vector stores: Qdrant, PGVector
- **Input Prefill:** All prompts with defaults (base URL, user ID) now prefill the input field instead of showing defaults in brackets
- **Smart Reuse:** When LLM and embedder use the same provider, API key and base URL are automatically reused from the LLM step
- **Default Model:** Updated default LLM model to `gpt-5-mini`
- **Manifest Compliance:** Removed undocumented fields, aligned env var declarations between SKILL.md and manifest, fixed `configSchema.required` for clean installs
**Tests:**
- 404 tests across 15 test files (+3 new: `json-helpers.test.ts`, `oss-wizard.test.ts`, `cli-commands.test.ts`)
</Update>
<Update label="2026-04-20" description="v1.0.7">
**New Features:**
- **Chat-Based Setup:** Added chat-based Platform setup flow — users can now configure the plugin conversationally instead of editing config files manually
- **Installation Docs Rewrite:** Rewrote README and integration docs with chat-first setup, numbered manual steps.
**Improvements:**
- **SDK Upgrade:** Bumped `mem0ai` dependency to 3.0.1 for V3 API compatibility
- **Config Cleanup:** Dropped deprecated `orgId`, `projectId`, `enableGraph` config options; updated CLI prompts ([#4734](https://github.com/mem0ai/mem0/pull/4734), [#4764](https://github.com/mem0ai/mem0/pull/4764))
- **Noise Filtering:** Expanded noise patterns in memory add tool; handle leading text in JSON extraction
</Update>
<Update label="2026-04-11" description="v1.0.6"> <Update label="2026-04-11" description="v1.0.6">
**Bug Fixes:** **Bug Fixes:**
-17
View File
@@ -893,13 +893,6 @@ See the [OSS v1 to v2 migration guide](https://docs.mem0.ai/migration/oss-v1-to-
</Tab> </Tab>
<Tab title="TypeScript"> <Tab title="TypeScript">
<Update label="2026-04-20" description="v3.0.1">
**Bug Fixes:**
- **Telemetry:** SDK version is now injected into telemetry at build time via esbuild's `define`, replacing the two hardcoded version strings in `src/client/telemetry.ts` and `src/oss/src/utils/telemetry.ts`. Previously these were stuck at `2.1.36` and `2.1.34` while the published package was on `3.x`, so every telemetry event was reporting the wrong `client_version`. The placeholder is substituted with a string literal at bundle time — no runtime `require("./package.json")` in the shipped bundle ([#4897](https://github.com/mem0ai/mem0/pull/4897)).
</Update>
<Update label="2026-04-14" description="v3.0.0"> <Update label="2026-04-14" description="v3.0.0">
**Major Release** — TypeScript SDK with V3 memory pipeline, camelCase parameters, and cleaned-up API surface. **Major Release** — TypeScript SDK with V3 memory pipeline, camelCase parameters, and cleaned-up API surface.
@@ -1269,16 +1262,6 @@ See the [TypeScript SDK migration guide](https://docs.mem0.ai/migration/ts-v2-to
<Tab title="CLI"> <Tab title="CLI">
<Update label="2026-04-22" description="Python v0.2.4 / Node v0.2.4">
**New Features:**
- **V3 API Routes:** Migrated `add`, `search`, and `list` commands from v1/v2 to v3 API endpoints — `POST /v3/memories/add/`, `POST /v3/memories/search/`, `POST /v3/memories/`. Aligns both CLIs with the Python and TypeScript SDKs which already use v3 ([#4916](https://github.com/mem0ai/mem0/pull/4916))
**Breaking Changes:**
- **`--graph` / `--no-graph` removed:** The `enable_graph` config option, `--graph` and `--no-graph` CLI flags, and `MEM0_ENABLE_GRAPH` environment variable have been removed from both CLIs. Graph memory is now a project-level setting on the Platform ([#4916](https://github.com/mem0ai/mem0/pull/4916))
</Update>
<Update label="2026-04-11" description="Python v0.2.3 / Node v0.2.3"> <Update label="2026-04-11" description="Python v0.2.3 / Node v0.2.3">
**Bug Fixes:** **Bug Fixes:**
@@ -54,6 +54,7 @@ config = {
"embedding_model_dims": 3072, "embedding_model_dims": 3072,
} }
}, },
"version": "v1.1",
} }
class PersonalTravelAssistant: class PersonalTravelAssistant:
@@ -153,7 +154,7 @@ class PersonalTravelAssistant:
return answer return answer
def get_memories(self, user_id): def get_memories(self, user_id):
memories = self.memory.get_all(filters={"user_id": user_id}) memories = self.memory.get_all(user_id=user_id)
return [m['memory'] for m in memories.get('results', [])] return [m['memory'] for m in memories.get('results', [])]
def search_memories(self, query, user_id): def search_memories(self, query, user_id):
+1 -1
View File
@@ -42,7 +42,7 @@ This sets up Mem0 with:
```python ```python
import boto3 import boto3
from opensearchpy import RequestsHttpConnection, AWSV4SignerAuth from opensearchpy import RequestsHttpConnection, AWSV4SignerAuth
from mem0 import Memory from mem0.memory.main import Memory
region = 'us-west-2' region = 'us-west-2'
service = 'aoss' service = 'aoss'
@@ -216,7 +216,7 @@ memory.delete_all(user_id="alice")
## Put it into practice ## Put it into practice
- Review the <Link href="/api-reference/memory/delete-memory">Delete Memory API reference</Link>, plus <Link href="/api-reference/memory/batch-delete">Batch Delete</Link> and <Link href="/api-reference/memory/delete-memories">Filtered Delete</Link>. - Review the <Link href="/api-reference/memory/delete-memory">Delete Memory API reference</Link>, plus <Link href="/api-reference/memory/batch-delete">Batch Delete</Link> and <Link href="/api-reference/memory/delete-memories">Filtered Delete</Link>.
- Pair deletes with <Link href="/platform/features/platform-overview">Expiration Policies</Link> to automate retention. - Pair deletes with <Link href="/platform/features/entity-scoped-memory">Entity-Scoped Memory</Link> to manage retention per user, agent, or session.
## See it live ## See it live
@@ -233,9 +233,9 @@ memory.delete_all(user_id="alice")
href="/core-concepts/memory-operations/add" href="/core-concepts/memory-operations/add"
/> />
<Card <Card
title="Enable Expiration Policies" title="Scope memories by entity"
description="Automate retention with the platform’s expiration feature." description="Manage retention per user, agent, or session with entity-scoped memory."
icon="clock" icon="clock"
href="/platform/features/platform-overview" href="/platform/features/entity-scoped-memory"
/> />
</CardGroup> </CardGroup>
+1 -1
View File
@@ -49,7 +49,7 @@ Import necessary modules and configure Mem0:
```python ```python
import boto3 import boto3
from opensearchpy import OpenSearch, RequestsHttpConnection, AWSV4SignerAuth from opensearchpy import OpenSearch, RequestsHttpConnection, AWSV4SignerAuth
from mem0 import Memory from mem0.memory.main import Memory
region = 'us-west-2' region = 'us-west-2'
service = 'aoss' service = 'aoss'
+5 -12
View File
@@ -32,19 +32,12 @@ export MEM0_API_KEY="m0-your-api-key"
### Option A — Plugin Marketplace (Recommended) ### Option A — Plugin Marketplace (Recommended)
Install the full plugin including MCP server, lifecycle hooks, and SDK skill. Install the full plugin including MCP server, lifecycle hooks, and SDK skill:
1. Add the Mem0 marketplace: ```
/plugin marketplace add mem0ai/mem0
``` /plugin install mem0@mem0-plugins
/plugin marketplace add mem0ai/mem0 ```
```
2. Install the plugin:
```
/plugin install mem0@mem0-plugins
```
**Claude Cowork desktop app:** Open the Cowork tab, click **Customize** in the sidebar, click **Browse plugins**, and install Mem0. **Claude Cowork desktop app:** Open the Cowork tab, click **Customize** in the sidebar, click **Browse plugins**, and install Mem0.
+2 -2
View File
@@ -24,7 +24,7 @@ You can get your Mem0 API key from the <a href="https://app.mem0.ai/" rel="nofol
Install the necessary libraries: Install the necessary libraries:
```bash ```bash
pip install mem0ai keywordsai-sdk pip install mem0 keywordsai-sdk
``` ```
Set up your environment variables: Set up your environment variables:
@@ -65,7 +65,7 @@ config = {
} }
# Initialize Memory # Initialize Memory
memory = Memory.from_config(config) memory = Memory.from_config(config_dict=config)
# Add a memory # Add a memory
result = memory.add( result = memory.add(
+1
View File
@@ -92,6 +92,7 @@ config = {
"provider": "openai", "provider": "openai",
"config": {"model": "text-embedding-3-small"}, "config": {"model": "text-embedding-3-small"},
}, },
"version": "v1.1",
} }
``` ```
+1 -1
View File
@@ -214,7 +214,7 @@ Customize memory behavior:
# Configure memory search # Configure memory search
memories = mem0.search( memories = mem0.search(
query="travel preferences", query="travel preferences",
filters={"user_id": "alex"}, user_id="alex",
top_k=5 # Number of memories to retrieve top_k=5 # Number of memories to retrieve
) )
+52 -363
View File
@@ -14,36 +14,15 @@ Add long-term memory to [OpenClaw](https://github.com/openclaw/openclaw) agents
The plugin provides: The plugin provides:
1. **Auto-Recall** — Before the agent responds, memories matching the current message are injected into context 1. **Auto-Recall** — Before the agent responds, memories matching the current message are injected into context
2. **Auto-Capture** — After the agent responds, the exchange is sent to Mem0 which decides what's worth keeping 2. **Auto-Capture** — After the agent responds, the exchange is sent to Mem0 which decides what's worth keeping
3. **Agent Tools** — Eight tools for explicit memory operations during conversations 3. **Agent Tools** — Five tools for explicit memory operations during conversations
Both auto-recall and auto-capture are opt-in (`autoRecall: true`, `autoCapture: true` in config). Once enabled, they run silently with no manual intervention required. Both auto-recall and auto-capture run silently with no manual configuration required.
## Requirements
Check your OpenClaw version:
```bash
openclaw --version
# OpenClaw 2026.4.15 (041266a)
```
| OpenClaw Version | Plugin Support |
|------------------|----------------|
| `>= 2026.4.15` | Fully supported |
## Installation ## Installation
The fastest way is to install directly from your OpenClaw chat, no CLI or config editing needed. ```bash
openclaw plugins install @mem0/openclaw-mem0
**Copy and paste this into your OpenClaw chat**; Telegram, WhatsApp, default chat, or any channel where your agent lives:
``` ```
Setup Mem0 from mem0.ai/claw-setup
```
OpenClaw installs the plugin, prompts you for your email, and connects your Mem0 account with OTP verification. See [Chat Setup](#option-1-chat-setup-recommended) below for the full walkthrough.
If you prefer the OpenClaw CLI, or are setting up self-hosted / open-source mode, see [Manual Config](#option-2-manual-config) and [Open-Source Mode](#open-source-mode-self-hosted) below.
## Setup and Configuration ## Setup and Configuration
@@ -57,213 +36,51 @@ Pick any stable, unique identifier for the user. Common choices:
- A UUID (e.g. `"550e8400-e29b-41d4-a716-446655440000"`) - A UUID (e.g. `"550e8400-e29b-41d4-a716-446655440000"`)
- A simple username (e.g. `"alice"`) - A simple username (e.g. `"alice"`)
All memories are scoped to this `userId` — different values create separate memory namespaces. If you don't set it, it defaults to your OS username. All memories are scoped to this `userId` — different values create separate memory namespaces. If you don't set it, it defaults to `"default"`, which means all users share the same memory space.
<Tip>In a multi-user application, set `userId` dynamically per user (e.g. from your auth system) rather than hardcoding a single value.</Tip> <Tip>In a multi-user application, set `userId` dynamically per user (e.g. from your auth system) rather than hardcoding a single value.</Tip>
### Platform Mode (Mem0 Cloud) ### Platform Mode (Mem0 Cloud)
There are two ways to set up `@mem0/openclaw-mem0` on the Mem0 platform: <Note>Get your API key from <a href="https://app.mem0.ai" rel="nofollow">app.mem0.ai</a>.</Note>
- **Chat setup (recommended)** — run the setup inside any OpenClaw chat. No config editing, no API key handling. Add to your `openclaw.json`:
- **Manual config** — edit `openclaw.json` directly.
#### Option 1: Chat Setup (Recommended)
You no longer need manual config editing to get started. Everything happens inside the OpenClaw chat itself.
<Steps>
<Step title="Send the setup command to your OpenClaw agent">
Open any OpenClaw channel — Telegram, WhatsApp, your default chat, wherever your agent lives. Paste and send this command:
```
Setup Mem0 from mem0.ai/claw-setup
```
OpenClaw responds with a Mem0 setup card and immediately asks:
> "What's your email address? I'll send you a verification code to connect your Mem0 account."
</Step>
<Step title="Enter your email">
Type your email address and send it. Mem0 sends back:
> "Check your email for a 6-digit code and paste it here."
</Step>
<Step title="Paste the OTP">
Copy the 6-digit code from your email inbox and paste it into the chat.
You'll see the confirmation:
> "Connected to Mem0."
</Step>
</Steps>
That's it. No API key, no config file editing, no environment variables. The plugin is now active and auto-capture and auto-recall are running on every turn.
<Note>The chat flow uses the same underlying config as manual setup — it writes `apiKey` and `userId` into `openclaw.json` for you. You can still open the file to inspect or override values afterward.</Note>
#### Option 2: Manual Config
<Steps>
<Step title="Install the plugin via the OpenClaw CLI">
```bash
openclaw plugins install @mem0/openclaw-mem0
```
</Step>
<Step title="Get your API key">
Get your API key from <a href="https://app.mem0.ai?utm_source=mem0-docs" rel="nofollow">app.mem0.ai</a>.
</Step>
<Step title="Select the plugin as your memory backend in `openclaw.json`">
Add the full config to your `openclaw.json`:
```json5
{
"plugins": {
"slots": {
"memory": "openclaw-mem0"
},
"entries": {
"openclaw-mem0": {
"enabled": true,
"config": {
"apiKey": "${MEM0_API_KEY}",
"userId": "alice" // any unique identifier you choose for this user
}
}
}
}
}
```
</Step>
</Steps>
<Warning>
OpenClaw treats memory plugins as an exclusive slot. Installing the plugin alone does **not** activate it — you must also set `plugins.slots.memory` as shown above.
</Warning>
### Open-Source Mode (Self-hosted)
No Mem0 key needed. Defaults use OpenAI (`gpt-5-mini` for LLM, `text-embedding-3-small` for embeddings) — requires `OPENAI_API_KEY`. For a fully local setup, use Ollama for both.
#### Option 1: Interactive Wizard (Recommended)
Run the guided 4-step wizard:
```bash
openclaw mem0 init --mode open-source
```
The wizard walks you through:
<Steps>
<Step title="LLM provider">
Choose OpenAI (`gpt-5-mini`), Ollama (`llama3.1:8b`, fully local), or Anthropic (`claude-sonnet-4-5-20250514`). Provide an API key or base URL as needed.
</Step>
<Step title="Embedding provider">
Choose OpenAI (`text-embedding-3-small`) or Ollama (`nomic-embed-text`, local). If the same provider was chosen for LLM, the API key and URL are reused automatically.
</Step>
<Step title="Vector store">
Choose Qdrant (`http://localhost:6333`) or PGVector (PostgreSQL). Connectivity is verified before proceeding.
</Step>
<Step title="User ID">
Set your memory namespace identifier.
</Step>
</Steps>
#### Option 2: Non-Interactive Setup
For CI/CD, scripts, or agent-driven setup — pass all options as flags:
```bash
# Fully local with Ollama + Qdrant
openclaw mem0 init --mode open-source \
--oss-llm ollama --oss-embedder ollama --oss-vector qdrant
# OpenAI + Qdrant
openclaw mem0 init --mode open-source \
--oss-llm openai --oss-llm-key <key> \
--oss-embedder openai --oss-embedder-key <key> \
--oss-vector qdrant
# Anthropic LLM + OpenAI embeddings + PGVector
openclaw mem0 init --mode open-source \
--oss-llm anthropic --oss-llm-key <key> \
--oss-embedder openai --oss-embedder-key <key> \
--oss-vector pgvector --oss-vector-user postgres --oss-vector-password secret
```
Add `--json` for machine-readable output (useful when an LLM agent is driving the setup).
<Accordion title="All --oss-* flags">
| Flag | Description |
|------|-------------|
| `--oss-llm <provider>` | `openai`, `ollama`, or `anthropic` |
| `--oss-llm-key <key>` | API key for LLM provider |
| `--oss-llm-model <model>` | Override default LLM model |
| `--oss-llm-url <url>` | Base URL (Ollama only) |
| `--oss-embedder <provider>` | `openai` or `ollama` |
| `--oss-embedder-key <key>` | API key for embedder |
| `--oss-embedder-model <model>` | Override default embedder model |
| `--oss-embedder-url <url>` | Base URL (Ollama only) |
| `--oss-vector <provider>` | `qdrant` or `pgvector` |
| `--oss-vector-url <url>` | Qdrant server URL (default: `http://localhost:6333`) |
| `--oss-vector-host <host>` | PGVector host |
| `--oss-vector-port <port>` | PGVector port |
| `--oss-vector-user <user>` | PGVector user |
| `--oss-vector-password <pw>` | PGVector password |
| `--oss-vector-dbname <db>` | PGVector database name |
| `--oss-vector-dims <n>` | Override embedding dimensions |
</Accordion>
#### Option 3: Manual Config
Minimal config — uses OpenAI defaults:
```json5 ```json5
{ // plugins.entries
"plugins": { "openclaw-mem0": {
"slots": { "enabled": true,
"memory": "openclaw-mem0" "config": {
}, "apiKey": "${MEM0_API_KEY}",
"entries": { "userId": "alice" // any unique identifier you choose for this user
"openclaw-mem0": {
"enabled": true,
"config": {
"mode": "open-source",
"userId": "alice" // any unique identifier you choose for this user
}
}
}
} }
} }
``` ```
To customize providers: ### Open-Source Mode (Self-hosted)
No Mem0 key needed. Requires `OPENAI_API_KEY` for default embeddings/LLM.
```json5 ```json5
{ "openclaw-mem0": {
"plugins": { "enabled": true,
"slots": { "config": {
"memory": "openclaw-mem0" "mode": "open-source",
}, "userId": "alice" // any unique identifier you choose for this user
"entries": { }
"openclaw-mem0": { }
"enabled": true, ```
"config": {
"mode": "open-source", Sensible defaults work out of the box. To customize the embedder, vector store, or LLM:
"userId": "your-user-id",
"oss": { ```json5
"embedder": { "provider": "openai", "config": { "model": "text-embedding-3-small" } }, "config": {
"vectorStore": { "provider": "qdrant", "config": { "url": "http://localhost:6333" } }, "mode": "open-source",
"llm": { "provider": "openai", "config": { "model": "gpt-5-mini" } } "userId": "your-user-id",
} "oss": {
} "embedder": { "provider": "openai", "config": { "model": "text-embedding-3-small" } },
} "vectorStore": { "provider": "qdrant", "config": { "host": "localhost", "port": 6333 } },
} "llm": { "provider": "openai", "config": { "model": "gpt-4o" } }
} }
} }
``` ```
@@ -276,31 +93,26 @@ Memories are organized into two scopes:
- **Session (short-term)** — Auto-capture stores memories scoped to the current session via Mem0's `run_id` / `runId` parameter. These are contextual to the ongoing conversation. - **Session (short-term)** — Auto-capture stores memories scoped to the current session via Mem0's `run_id` / `runId` parameter. These are contextual to the ongoing conversation.
- **User (long-term)** — The agent can explicitly store long-term memories using the `memory_add` tool (with `longTerm: true`, the default). These persist across all sessions for the user. - **User (long-term)** — The agent can explicitly store long-term memories using the `memory_store` tool (with `longTerm: true`, the default). These persist across all sessions for the user.
During **auto-recall**, the plugin searches both scopes and presents them separately — long-term memories first, then session memories — so the agent has full context. During **auto-recall**, the plugin searches both scopes and presents them separately — long-term memories first, then session memories — so the agent has full context.
## Agent Tools ## Agent Tools
The agent gets eight tools it can call during conversations: The agent gets five tools it can call during conversations:
| Tool | Description | | Tool | Description |
|------|-------------| |------|-------------|
| `memory_search` | Search memories by natural language query. Supports `scope`, `categories`, `filters`. | | `memory_search` | Search memories by natural language |
| `memory_add` | Store facts. Accepts `text` or `facts` array, `category`, `importance`, `metadata`. | | `memory_list` | List all stored memories for a user |
| `memory_get` | Retrieve a single memory by ID | | `memory_store` | Explicitly save a fact |
| `memory_list` | List all memories. Filter by `userId`, `agentId`, `scope`. | | `memory_get` | Retrieve a memory by ID |
| `memory_update` | Update a memory's text in place. Preserves history. | | `memory_forget` | Delete by ID or by query |
| `memory_delete` | Delete by `memoryId`, `query` (search-and-delete), or `all: true`. |
| `memory_event_list` | List recent background processing events (platform mode only). |
| `memory_event_status` | Get status of a specific event by ID (platform mode only). |
The `memory_search` and `memory_list` tools accept a `scope` parameter (`"session"`, `"long-term"`, or `"all"`) to control which memories are queried. The `memory_search` and `memory_list` tools accept a `scope` parameter (`"session"`, `"long-term"`, or `"all"`) to control which memories are queried. The `memory_store` tool accepts a `longTerm` boolean (default: `true`) to choose where to store.
## CLI Commands ## CLI Commands
All commands support `--json` for machine-readable output — useful when an LLM agent drives the CLI programmatically. Run `openclaw mem0 help --json` to discover every command and flag.
```bash ```bash
# Search all memories (long-term + session) # Search all memories (long-term + session)
openclaw mem0 search "what languages does the user know" openclaw mem0 search "what languages does the user know"
@@ -311,13 +123,8 @@ openclaw mem0 search "what languages does the user know" --scope long-term
# Search only session/short-term memories # Search only session/short-term memories
openclaw mem0 search "what languages does the user know" --scope session openclaw mem0 search "what languages does the user know" --scope session
# List all memories # View stats
openclaw mem0 list openclaw mem0 stats
openclaw mem0 list --user-id alice --top-k 20
# JSON output (any command)
openclaw mem0 search "preferences" --json
openclaw mem0 status --json
``` ```
## Configuration Options ## Configuration Options
@@ -327,9 +134,9 @@ openclaw mem0 status --json
| Key | Type | Default | Description | | Key | Type | Default | Description |
|-----|------|---------|-------------| |-----|------|---------|-------------|
| `mode` | `"platform"` \| `"open-source"` | `"platform"` | Which backend to use | | `mode` | `"platform"` \| `"open-source"` | `"platform"` | Which backend to use |
| `userId` | `string` | OS username | Scope memories per user | | `userId` | `string` | `"default"` | Scope memories per user |
| `autoRecall` | `boolean` | `false` | Inject memories before each turn (opt-in) | | `autoRecall` | `boolean` | `true` | Inject memories before each turn |
| `autoCapture` | `boolean` | `false` | Store facts after each turn (opt-in) | | `autoCapture` | `boolean` | `true` | Store facts after each turn |
| `topK` | `number` | `5` | Max memories per recall | | `topK` | `number` | `5` | Max memories per recall |
| `searchThreshold` | `number` | `0.3` | Min similarity (0–1) | | `searchThreshold` | `number` | `0.3` | Min similarity (0–1) |
@@ -338,6 +145,8 @@ openclaw mem0 status --json
| Key | Type | Default | Description | | Key | Type | Default | Description |
|-----|------|---------|-------------| |-----|------|---------|-------------|
| `apiKey` | `string` | — | **Required.** Mem0 API key (supports `${MEM0_API_KEY}`) | | `apiKey` | `string` | — | **Required.** Mem0 API key (supports `${MEM0_API_KEY}`) |
| `orgId` | `string` | — | Organization ID |
| `projectId` | `string` | — | Project ID |
| `customInstructions` | `string` | *(built-in)* | Extraction rules — what to store, how to format | | `customInstructions` | `string` | *(built-in)* | Extraction rules — what to store, how to format |
| `customCategories` | `object` | *(12 defaults)* | Category name → description map for tagging | | `customCategories` | `object` | *(12 defaults)* | Category name → description map for tagging |
@@ -353,135 +162,15 @@ openclaw mem0 status --json
| `oss.llm.provider` | `string` | `"openai"` | LLM provider (`"openai"`, `"anthropic"`, `"ollama"`, etc.) | | `oss.llm.provider` | `string` | `"openai"` | LLM provider (`"openai"`, `"anthropic"`, `"ollama"`, etc.) |
| `oss.llm.config` | `object` | — | Provider config: `apiKey`, `model`, `baseURL`, `temperature` | | `oss.llm.config` | `object` | — | Provider config: `apiKey`, `model`, `baseURL`, `temperature` |
| `oss.historyDbPath` | `string` | — | SQLite path for memory edit history | | `oss.historyDbPath` | `string` | — | SQLite path for memory edit history |
| `oss.disableHistory` | `boolean` | `false` | Disable memory edit history tracking |
Everything inside `oss` is optional — defaults use OpenAI embeddings (`text-embedding-3-small`), in-memory vector store, and OpenAI LLM (`gpt-5-mini`). Everything inside `oss` is optional — defaults use OpenAI embeddings (`text-embedding-3-small`), in-memory vector store, and OpenAI LLM.
## Plugin Management
### Updating the Plugin
```bash
openclaw plugins update @mem0/openclaw-mem0
```
<Note>Use the npm package name (`@mem0/openclaw-mem0`) for plugin management commands, not the plugin ID (`openclaw-mem0`).</Note>
### Checking Plugin Status
```bash
openclaw plugins list
openclaw plugins inspect openclaw-mem0
```
## Troubleshooting
### "plugins.allow excludes mem0" Error
If you see an error like:
```
[openclaw] Failed to start CLI: Error: The `openclaw mem0` command is unavailable
because `plugins.allow` excludes "mem0". Add "mem0" to `plugins.allow` if you want
that bundled plugin CLI surface.
```
Add `mem0` to your `plugins.allow` list in `openclaw.json`:
```json5
{
"plugins": {
"allow": ["mem0"],
"slots": {
"memory": "openclaw-mem0"
}
}
}
```
### Plugin Not Activating
If the plugin installs but doesn't work:
1. Verify `plugins.slots.memory` is set to `"openclaw-mem0"` (not the npm package name)
2. Check `openclaw plugins list --enabled` to confirm the plugin is loaded
3. Run `openclaw mem0 status` to verify configuration
### Plugin Update Not Working
If `openclaw plugins update` fails:
1. Use the full npm package name: `openclaw plugins update @mem0/openclaw-mem0`
2. If that fails, uninstall and reinstall:
```bash
openclaw plugins uninstall openclaw-mem0
openclaw plugins install @mem0/openclaw-mem0
```
## Privacy & Security
### Data Flow
| Mode | Where data goes | Storage |
|------|----------------|---------|
| **Platform** | Conversations sent to `api.mem0.ai` for extraction and storage | Mem0 cloud |
| **Open-source** | Embeddings generated via configured provider (default: OpenAI API). Vectors stored locally. | `~/.mem0/vector_store.db` (SQLite) |
### Enabling Auto-Capture and Auto-Recall
Auto-capture and auto-recall are disabled by default (opt-in). To enable either or both:
```json5
{
"plugins": {
"entries": {
"openclaw-mem0": {
"config": {
"autoCapture": true, // send conversations to Mem0 for extraction
"autoRecall": true // inject relevant memories into context
}
}
}
}
}
```
Without these enabled, the agent can still use memory tools (`memory_add`, `memory_search`, etc.) explicitly — only the automatic background behavior is off.
### Credential Protection
The plugin never stores API keys, tokens, or secrets as memories. Five independent layers enforce this:
1. **Triage gate** — The extraction prompt rejects values matching known credential patterns (`sk-`, `m0-`, `ghp_`, `AKIA`, `Bearer`, `password=`, `token=`, `secret=`)
2. **Dream cleanup** — Periodic memory consolidation deletes any memories that slipped through containing credential patterns
3. **Extraction instructions** — Default extraction rules explicitly instruct the model to store only that a credential was configured, never the value
4. **Configurable patterns** — Add custom credential patterns via `skills.triage.credentialPatterns`
5. **CLI redaction** — `openclaw mem0 config show` redacts sensitive fields (`apiKey`, `oss.*.config.apiKey`)
### API Key Storage
Plugin config is stored in `~/.openclaw/openclaw.json` with file permissions `0o600` (owner-read-only). For production deployments, use environment variable references (`${MEM0_API_KEY}`) or SecretRef objects instead of plaintext keys.
### Telemetry
Anonymous usage telemetry (PostHog) is enabled by default to help improve the plugin. No conversation content or memory values are included — only event counts (recall, capture, tool usage, CLI commands).
To opt out, set the environment variable:
```bash
export MEM0_TELEMETRY=false
```
### System Prompt Context
The plugin injects memory-related instructions into the agent's system context via OpenClaw's `prependSystemContext` mechanism. This includes the memory triage protocol and recalled memories. This is the standard OpenClaw plugin SDK pattern for memory backends — no user-facing prompts are modified.
## Key Features ## Key Features
1. **Zero Configuration** — Auto-recall and auto-capture work out of the box with no prompting required 1. **Zero Configuration** — Auto-recall and auto-capture work out of the box with no prompting required
2. **Dual Memory Scopes** — Session-scoped short-term and user-scoped long-term memories 2. **Dual Memory Scopes** — Session-scoped short-term and user-scoped long-term memories
3. **Flexible Backend** — Use Mem0 Cloud for managed service or self-host with open-source mode 3. **Flexible Backend** — Use Mem0 Cloud for managed service or self-host with open-source mode
4. **Rich Tool Suite** — Eight agent tools for explicit memory operations when needed 4. **Rich Tool Suite** — Five agent tools for explicit memory operations when needed
## Conclusion ## Conclusion
+248 -420
View File
@@ -1,474 +1,302 @@
# Mem0 # Mem0
> Mem0 is a memory layer for LLM agents - persistent, self-improving context that survives across sessions. Two products share one mental model: Mem0 Platform (managed) and Mem0 Open Source (self-hosted). Every link below is tagged `[Platform]`, `[OSS]`, or `[Both]` so you can load only what the current user needs. > Mem0 is a self-improving memory layer for LLM applications, enabling personalized AI experiences that retain context across sessions, adapt over time, and reduce costs by intelligently storing and retrieving relevant information.
## For agents reading this file Mem0 provides both a managed platform and open-source solutions for adding persistent memory to AI agents and applications. Unlike traditional RAG systems that are stateless, Mem0 creates stateful agents that remember user preferences, learn from interactions, and evolve behavior over time.
- Use `MemoryClient` (Python) / `mem0ai` (npm) when the user has a Mem0 Platform API key. Docs under `/platform/` and `/api-reference/` apply; the managed product handles providers server-side, so you can ignore `## Optional` below. Key differentiators:
- Use `Memory` (Python) / `mem0ai/oss` (npm) when the user self-hosts. Docs under `/open-source/` and `/components/` apply; Platform-only features (entity filters v2, custom categories, webhooks, advanced retrieval) may not be available. - **Stateful vs Stateless**: Retains context across sessions rather than forgetting after each interaction
- Scope tag reference: `[Platform]` = managed only, `[OSS]` = self-hosted only, `[Both]` = same API surface on both. - **Intelligent Memory Management**: Uses LLMs to extract, filter, and organize relevant information
- OpenAPI spec: https://docs.mem0.ai/openapi.json - **Dual Storage Architecture**: Combines vector embeddings with graph databases for comprehensive memory
- Live MCP server: https://mcp.mem0.ai (see `platform/mem0-mcp`). - **Sub-50ms Retrieval**: Lightning-fast memory lookups for real-time applications
- Source repo: https://github.com/mem0ai/mem0 - **Multimodal Support**: Handles text, images, and documents seamlessly
## Install
- Python SDK: `pip install mem0ai`
- Node SDK: `npm install mem0ai`
- Python CLI: `pip install mem0-cli`
- Node CLI: `npm install -g @mem0/cli`
## Identify the User's Setup
Look at the user's imports first - they determine which product (Platform vs OSS) and which language you should quote docs from. **Mem0 Platform (managed) is the recommended path** - 4-line integration, sub-50ms retrieval, no infra. Route to OSS only when the user has an explicit self-hosting requirement.
### Platform - Python [Platform]
Import signature: `from mem0 import MemoryClient`
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
# Create
client.add(
[{"role": "user", "content": "I love hiking on weekends"}],
user_id="alice",
)
# Read
client.search("What does Alice like to do?", user_id="alice")
client.get_all(user_id="alice")
client.get(memory_id="<id>")
# Update
client.update(memory_id="<id>", data="Alice loves mountain hiking")
# Delete
client.delete(memory_id="<id>")
client.delete_all(user_id="alice")
```
Relevant docs: `platform/quickstart`, `platform/features/*`, `api-reference/*`.
### Platform - TypeScript / JavaScript [Platform]
Import signature: `import MemoryClient from "mem0ai"`
```ts
import MemoryClient from "mem0ai";
const client = new MemoryClient({ apiKey: "your-api-key" });
// Create
await client.add(
[{ role: "user", content: "I love hiking on weekends" }],
{ user_id: "alice" },
);
// Read
await client.search("What does Alice like to do?", { user_id: "alice" });
await client.getAll({ user_id: "alice" });
await client.get("<memory_id>");
// Update
await client.update("<memory_id>", { text: "Alice loves mountain hiking" });
// Delete
await client.delete("<memory_id>");
await client.deleteAll({ user_id: "alice" });
```
Relevant docs: same as Platform Python.
### OSS - Python [OSS]
Import signature: `from mem0 import Memory`
```python
from mem0 import Memory
m = Memory() # needs OPENAI_API_KEY; see components/ for custom providers
# Create
m.add("I love hiking on weekends", user_id="alice")
# Read
m.search("What does Alice like to do?", user_id="alice")
m.get_all(user_id="alice")
m.get(memory_id="<id>")
# Update
m.update(memory_id="<id>", data="Alice loves mountain hiking")
# Delete
m.delete(memory_id="<id>")
m.delete_all(user_id="alice")
```
Relevant docs: `open-source/*` plus provider pages under `## Optional`.
### OSS - Node [OSS]
Import signature: `import { Memory } from "mem0ai/oss"`
```ts
import { Memory } from "mem0ai/oss";
const memory = new Memory();
// Create
await memory.add("I love hiking on weekends", { userId: "alice" });
// Read
await memory.search("What does Alice like to do?", { userId: "alice" });
await memory.getAll({ userId: "alice" });
await memory.get("<memory_id>");
// Update
await memory.update("<memory_id>", "Alice loves mountain hiking");
// Delete
await memory.delete("<memory_id>");
await memory.deleteAll({ userId: "alice" });
```
Relevant docs: same as OSS Python.
### Version Probes
Once you know which product, check the installed version - v2 vs v3 APIs differ in both OSS and Platform. Current published versions: Python `mem0ai` 2.x, TypeScript `mem0ai` 3.x, Node CLI `@mem0/cli` 0.2.x.
```bash
pip show mem0ai | grep -i ^version
npm list mem0ai --depth 0 2>/dev/null | grep mem0ai
mem0 --version # Python or Node CLI, whichever is on PATH
```
If the user is on a pre-current major (Python < 2, TS < 3, or Platform `output_format: "v1.1"`), route them through the matching migration guide in the Platform section before quoting current docs. If no Mem0 package is installed, recommend `pip install mem0ai` or `npm install mem0ai` and the corresponding quickstart above.
## Getting Started ## Getting Started
- [Introduction](https://docs.mem0.ai/introduction) [Both]: Use when the user wants a one-page overview of how memory fits between the LLM and the app. - [Introduction](https://docs.mem0.ai/introduction): Overview of Mem0's memory layer for AI agents, including stateless vs stateful agents and how memory fits in the agent stack
- [Vibe Code with Mem0](https://docs.mem0.ai/vibecoding) [Both]: Use when the user is in Claude Code, Cursor, or Windsurf and wants memory wired into their editor. - [Platform Overview](https://docs.mem0.ai/platform/overview): Managed solution with 4-line integration, sub-50ms latency, and intuitive dashboard
- [Platform Overview](https://docs.mem0.ai/platform/overview) [Platform]: Use when the user picks the managed product - 4-line integration, sub-50ms retrieval, dashboard. - [Vibe Code with Mem0](https://docs.mem0.ai/vibecoding): Single entry point for developers using AI coding tools (Claude Code, Cursor, Windsurf) with Mem0
- [Platform vs Open Source](https://docs.mem0.ai/platform/platform-vs-oss) [Both]: Use when the user is deciding between managed and self-hosted. - [Mem0 MCP Server](https://docs.mem0.ai/platform/mem0-mcp): Model Context Protocol server for integrating Mem0 with AI coding assistants
- [Platform Quickstart](https://docs.mem0.ai/platform/quickstart) [Platform]: Use for the first Platform integration - API key plus `MemoryClient.add/search`. - [Platform vs Open Source](https://docs.mem0.ai/platform/platform-vs-oss): Compare managed platform vs self-hosted options
- [Platform CLI](https://docs.mem0.ai/platform/cli) [Platform]: Use when the user wants to manage Platform memories from the terminal. - [Platform Quickstart](https://docs.mem0.ai/platform/quickstart): Get started with Mem0 Platform (managed) in minutes
- [Mem0 MCP Server](https://docs.mem0.ai/platform/mem0-mcp) [Platform]: Use when connecting memory to AI coding tools over MCP. - [Open Source Overview](https://docs.mem0.ai/open-source/overview): Self-hosted solution with full infrastructure control and customization
- [Open Source Overview](https://docs.mem0.ai/open-source/overview) [OSS]: Use when the user needs full infra control and custom provider wiring. - [Open Source Python Quickstart](https://docs.mem0.ai/open-source/python-quickstart): Get started with Mem0 Open Source using Python
- [Open Source Configuration](https://docs.mem0.ai/open-source/configuration) [OSS]: Use when configuring `Memory` - LLM, embedder, vector store, graph store. - [Open Source Node.js Quickstart](https://docs.mem0.ai/open-source/node-quickstart): Get started with Mem0 Open Source using Node.js
- [Open Source Python Quickstart](https://docs.mem0.ai/open-source/python-quickstart) [OSS]: Use for the first self-hosted Python integration.
- [Open Source Node.js Quickstart](https://docs.mem0.ai/open-source/node-quickstart) [OSS]: Use for the first self-hosted Node integration.
## Core Concepts ## Core Concepts
- [Memory Types](https://docs.mem0.ai/core-concepts/memory-types) [Both]: Use when explaining working, factual, episodic, and semantic memory distinctions. - [Memory Types](https://docs.mem0.ai/core-concepts/memory-types): Working memory (short-term session awareness), factual memory (structured knowledge), episodic memory (past conversations), and semantic memory (general knowledge)
- [Memory Operations - Add](https://docs.mem0.ai/core-concepts/memory-operations/add) [Both]: Use when explaining how `add()` extracts facts, resolves conflicts, and writes to both stores. - [Memory Operations - Add](https://docs.mem0.ai/core-concepts/memory-operations/add): How Mem0 processes conversations through information extraction, conflict resolution, and dual storage
- [Memory Operations - Search](https://docs.mem0.ai/core-concepts/memory-operations/search) [Both]: Use when explaining how queries are processed and ranked. - [Memory Operations - Search](https://docs.mem0.ai/core-concepts/memory-operations/search): Retrieval of relevant memories using semantic search with query processing and result ranking
- [Memory Operations - Update](https://docs.mem0.ai/core-concepts/memory-operations/update) [Both]: Use when memories need to be edited in place or reconciled against new info. - [Memory Operations - Update](https://docs.mem0.ai/core-concepts/memory-operations/update): Modifying existing memories when new information conflicts or supplements stored data
- [Memory Operations - Delete](https://docs.mem0.ai/core-concepts/memory-operations/delete) [Both]: Use when outdated memories must be removed. - [Memory Operations - Delete](https://docs.mem0.ai/core-concepts/memory-operations/delete): Removing outdated or irrelevant memories to maintain memory quality
- [Memory Evaluation](https://docs.mem0.ai/core-concepts/memory-evaluation) [Both]: Use when benchmarking memory quality or comparing against baselines.
## Platform ## Platform Features
### Features - Essential - [Platform Features Overview](https://docs.mem0.ai/platform/features/platform-overview): High-level overview of all Mem0 Platform capabilities
- [Platform Features Overview](https://docs.mem0.ai/platform/features/platform-overview) [Platform]: Use when surveying what managed offers beyond CRUD. - [Advanced Memory Operations](https://docs.mem0.ai/platform/advanced-memory-operations): Sophisticated memory management techniques for complex applications
- [V2 Memory Filters](https://docs.mem0.ai/platform/features/v2-memory-filters) [Platform]: Use when compound filters (AND/OR on metadata, entity, time) are needed at search.
- [Entity-Scoped Memory](https://docs.mem0.ai/platform/features/entity-scoped-memory) [Platform]: Use when partitioning memories by user, agent, app, or run.
- [Async Client](https://docs.mem0.ai/platform/features/async-client) [Platform]: Use when the app issues many concurrent Mem0 calls and needs non-blocking I/O.
- [Multimodal Support](https://docs.mem0.ai/platform/features/multimodal-support) [Platform]: Use when storing images or PDFs as memory input.
- [Custom Categories](https://docs.mem0.ai/platform/features/custom-categories) [Platform]: Use when the default categories do not match the domain.
### Features - Advanced Retrieval ### Essential Features
- [Advanced Retrieval](https://docs.mem0.ai/platform/features/advanced-retrieval) [Platform]: Use when the user needs keyword search, reranking, or hybrid retrieval. - [V2 Memory Filters](https://docs.mem0.ai/platform/features/v2-memory-filters): Advanced filtering and querying capabilities for memories
- [Criteria-Based Retrieval](https://docs.mem0.ai/platform/features/criteria-retrieval) [Platform]: Use when targeting memories by custom criteria, not just semantic similarity. - [Entity-Scoped Memory](https://docs.mem0.ai/platform/features/entity-scoped-memory): Organize memories by user, agent, app, and session identifiers
- [Contextual Add](https://docs.mem0.ai/platform/features/contextual-add) [Platform]: Use when `add()` should consider the surrounding conversation, not just the latest turn. - [Async Client](https://docs.mem0.ai/platform/features/async-client): Non-blocking operations for high-concurrency applications
- [Custom Instructions](https://docs.mem0.ai/platform/features/custom-instructions) [Platform]: Use when tailoring what Mem0 extracts and stores on Platform. - [Async Mode Default Changes](https://docs.mem0.ai/platform/features/async-mode-default-change): Understanding new async behavior defaults
- [Advanced Memory Operations](https://docs.mem0.ai/platform/advanced-memory-operations) [Platform]: Use when basic CRUD is not enough - batch ops, complex filters, workflows. - [Multimodal Support](https://docs.mem0.ai/platform/features/multimodal-support): Integration of images and documents (JPG, PNG, MDX, TXT, PDF) via URLs or Base64
- [Custom Categories](https://docs.mem0.ai/platform/features/custom-categories): Define domain-specific categories to improve memory organization
### Features - Data Management ### Advanced Features
- [Direct Import](https://docs.mem0.ai/platform/features/direct-import) [Platform]: Use when seeding a Mem0 project from existing data. - [Graph Threshold](https://docs.mem0.ai/platform/features/graph-threshold): Configure graph relationship sensitivity and strength
- [Memory Export](https://docs.mem0.ai/platform/features/memory-export) [Platform]: Use when exporting memories via a Pydantic schema. - [Advanced Retrieval](https://docs.mem0.ai/platform/features/advanced-retrieval): Enhanced search with keyword search, reranking, and filtering capabilities
- [Timestamp Support](https://docs.mem0.ai/platform/features/timestamp) [Platform]: Use when temporal queries or time-based filtering matter. - [Criteria-Based Retrieval](https://docs.mem0.ai/platform/features/criteria-retrieval): Targeted memory retrieval using custom criteria
- [Contextual Add](https://docs.mem0.ai/platform/features/contextual-add): Add memories with enhanced context awareness
- [Custom Instructions](https://docs.mem0.ai/platform/features/custom-instructions): Customize how Mem0 processes and stores information
### Features - Integration & Ops ### Data Management
- [Webhooks](https://docs.mem0.ai/platform/features/webhooks) [Platform]: Use when another system needs to react to memory changes in real time. - [Direct Import](https://docs.mem0.ai/platform/features/direct-import): Bulk import existing data into Mem0 memory
- [Feedback Mechanism](https://docs.mem0.ai/platform/features/feedback-mechanism) [Platform]: Use when capturing user feedback to improve memory quality. - [Memory Export](https://docs.mem0.ai/platform/features/memory-export): Export memories in structured formats using customizable Pydantic schemas
- [Group Chat Support](https://docs.mem0.ai/platform/features/group-chat) [Platform]: Use when the conversation has multiple participants. - [Timestamp Support](https://docs.mem0.ai/platform/features/timestamp): Temporal memory management with time-based queries
- [MCP Integration](https://docs.mem0.ai/platform/features/mcp-integration) [Platform]: Use when wiring Mem0 into Claude/Cursor/other MCP clients. - [Expiration Dates](https://docs.mem0.ai/platform/features/expiration-date): Automatic memory cleanup with configurable expiration
### Integration Features
- [Webhooks](https://docs.mem0.ai/platform/features/webhooks): Real-time notifications for memory events
- [Feedback Mechanism](https://docs.mem0.ai/platform/features/feedback-mechanism): Improve memory quality through user feedback
- [Group Chat Support](https://docs.mem0.ai/platform/features/group-chat): Multi-conversation memory management
- [MCP Integration](https://docs.mem0.ai/platform/features/mcp-integration): Model Context Protocol integration for AI coding tools
### Support & Migration ### Support & Migration
- [FAQs](https://docs.mem0.ai/platform/faqs) [Platform]: Use when answering common Platform questions. - [FAQs](https://docs.mem0.ai/platform/faqs): Frequently asked questions about Mem0 Platform
- [Contribute to Platform](https://docs.mem0.ai/platform/contribute) [Platform]: Use when a user wants to contribute to Platform docs or code. - [Contribute Guide](https://docs.mem0.ai/platform/contribute): Contributing to Mem0 Platform development
- [OSS to Platform Migration](https://docs.mem0.ai/migration/oss-to-platform) [Both]: Use when moving from self-hosted to managed. - [OSS to Platform Migration](https://docs.mem0.ai/migration/oss-to-platform): Guide for migrating from open-source to managed platform
- [OSS v2 to v3 Migration](https://docs.mem0.ai/migration/oss-v2-to-v3) [OSS]: Use when upgrading a self-hosted deployment across major versions. - [V0 to V1 Migration](https://docs.mem0.ai/migration/v0-to-v1): Upgrading from Mem0 v0 to v1
- [Platform v2 to v3 Migration](https://docs.mem0.ai/migration/platform-v2-to-v3) [Platform]: Use when upgrading a Platform integration across major versions. - [Breaking Changes](https://docs.mem0.ai/migration/breaking-changes): List of breaking changes across versions
- [API Changes](https://docs.mem0.ai/migration/api-changes) [Both]: Use when the upgrade involves API surface changes. - [API Changes](https://docs.mem0.ai/migration/api-changes): Detailed API changes and migration paths
- [Changelog](https://docs.mem0.ai/changelog/highlights) [Both]: Use when the user asks what shipped recently.
## Open Source ## Open Source
- [Open Source Features Overview](https://docs.mem0.ai/open-source/features/overview) [OSS]: Use when surveying OSS-only capabilities. ### Getting Started
- [Metadata Filtering](https://docs.mem0.ai/open-source/features/metadata-filtering) [OSS]: Use when filtering by custom metadata fields in self-hosted. - [Python Quickstart](https://docs.mem0.ai/open-source/python-quickstart): Installation, configuration, and usage examples for Python SDK
- [Reranker Search](https://docs.mem0.ai/open-source/features/reranker-search) [OSS]: Use when improving OSS search quality with a reranker. - [Node.js Quickstart](https://docs.mem0.ai/open-source/node-quickstart): Installation, configuration, and usage examples for Node.js SDK
- [Reranking](https://docs.mem0.ai/open-source/features/reranking) [OSS]: Use when configuring reranking end-to-end in OSS. - [Configuration Guide](https://docs.mem0.ai/open-source/configuration): Complete configuration options for self-hosted deployment
- [Async Memory](https://docs.mem0.ai/open-source/features/async-memory) [OSS]: Use when the self-hosted app needs `AsyncMemory`.
- [OSS Multimodal Support (features)](https://docs.mem0.ai/open-source/features/multimodal-support) [OSS]: Use when handling images and PDFs self-hosted (feature guide). ### Open Source Features
- [OSS Multimodal Support](https://docs.mem0.ai/open-source/multimodal-support) [OSS]: Use when handling images and PDFs self-hosted (concept overview). - [Features Overview](https://docs.mem0.ai/open-source/features/overview): Overview of all open-source features
- [Custom Instructions (OSS)](https://docs.mem0.ai/open-source/features/custom-instructions) [OSS]: Use when tailoring extraction prompts in OSS. - [Metadata Filtering](https://docs.mem0.ai/open-source/features/metadata-filtering): Advanced filtering using custom metadata fields
- [REST API Server](https://docs.mem0.ai/open-source/features/rest-api) [OSS]: Use when exposing a self-hosted Mem0 as a FastAPI service. - [Reranker Search](https://docs.mem0.ai/open-source/features/reranker-search): Enhanced search results with reranking models
- [OpenAI Compatibility](https://docs.mem0.ai/open-source/features/openai_compatibility) [OSS]: Use when hitting an OpenAI-compatible endpoint with self-hosted. - [Async Memory](https://docs.mem0.ai/open-source/features/async-memory): Asynchronous memory operations for better performance
- [Multimodal Support](https://docs.mem0.ai/open-source/features/multimodal-support): Handle text, images, and documents in self-hosted setup
- [Custom Instructions](https://docs.mem0.ai/open-source/features/custom-instructions): Tailor information extraction for specific use cases
- [Custom Memory Update Prompt](https://docs.mem0.ai/open-source/features/custom-update-memory-prompt): Customize how memories are updated and merged
- [REST API Server](https://docs.mem0.ai/open-source/features/rest-api): FastAPI-based server with core operations and OpenAPI documentation
- [OpenAI Compatibility](https://docs.mem0.ai/open-source/features/openai_compatibility): Seamless integration with OpenAI-compatible APIs
## Components
### LLMs
- [LLM Overview](https://docs.mem0.ai/components/llms/overview): Comprehensive guide to Large Language Model integration and configuration options
- [LLM Configuration](https://docs.mem0.ai/components/llms/config): Configuration reference for LLM providers
- [OpenAI](https://docs.mem0.ai/components/llms/models/openai): Integration with OpenAI models including GPT-4
- [Anthropic](https://docs.mem0.ai/components/llms/models/anthropic): Claude model integration with advanced reasoning capabilities
- [Azure OpenAI](https://docs.mem0.ai/components/llms/models/azure_openai): Microsoft Azure hosted OpenAI models for enterprise environments
- [Ollama](https://docs.mem0.ai/components/llms/models/ollama): Local model deployment for privacy-focused applications
- [Together](https://docs.mem0.ai/components/llms/models/together): Open-source model inference platform
- [Groq](https://docs.mem0.ai/components/llms/models/groq): High-performance LPU optimized models for fast inference
- [LiteLLM](https://docs.mem0.ai/components/llms/models/litellm): Unified LLM interface and proxy
- [Mistral AI](https://docs.mem0.ai/components/llms/models/mistral_AI): Mistral model integration
- [Google AI](https://docs.mem0.ai/components/llms/models/google_AI): Gemini model integration for multimodal applications
- [AWS Bedrock](https://docs.mem0.ai/components/llms/models/aws_bedrock): Enterprise-grade AWS managed model integration
- [DeepSeek](https://docs.mem0.ai/components/llms/models/deepseek): Advanced reasoning models
- [MiniMax](https://docs.mem0.ai/components/llms/models/minimax): MiniMax model integration
- [xAI](https://docs.mem0.ai/components/llms/models/xAI): xAI Grok models integration
- [Sarvam](https://docs.mem0.ai/components/llms/models/sarvam): Indian language models
- [LM Studio](https://docs.mem0.ai/components/llms/models/lmstudio): Local model management and deployment
- [LangChain LLM](https://docs.mem0.ai/components/llms/models/langchain): LangChain LLM integration
- [vLLM](https://docs.mem0.ai/components/llms/models/vllm): High-performance inference framework
### Vector Databases
- [Vector Database Overview](https://docs.mem0.ai/components/vectordbs/overview): Guide to supported vector databases for semantic memory storage
- [Vector Database Configuration](https://docs.mem0.ai/components/vectordbs/config): Configuration reference for vector database providers
- [Qdrant](https://docs.mem0.ai/components/vectordbs/dbs/qdrant): High-performance vector similarity search engine
- [Chroma](https://docs.mem0.ai/components/vectordbs/dbs/chroma): AI-native open-source vector database optimized for speed
- [PGVector](https://docs.mem0.ai/components/vectordbs/dbs/pgvector): PostgreSQL extension for vector similarity search
- [Milvus](https://docs.mem0.ai/components/vectordbs/dbs/milvus): Open-source vector database for AI applications at scale
- [Pinecone](https://docs.mem0.ai/components/vectordbs/dbs/pinecone): Managed vector database with serverless and pod deployment options
- [MongoDB](https://docs.mem0.ai/components/vectordbs/dbs/mongodb): Document database with vector search capabilities
- [Azure AI Search](https://docs.mem0.ai/components/vectordbs/dbs/azure): Microsoft's enterprise search service
- [Azure MySQL](https://docs.mem0.ai/components/vectordbs/dbs/azure_mysql): Azure Database for MySQL with vector search
- [Redis](https://docs.mem0.ai/components/vectordbs/dbs/redis): Real-time vector storage and search with Redis Stack
- [Valkey](https://docs.mem0.ai/components/vectordbs/dbs/valkey): Open-source Redis alternative with vector search
- [Elasticsearch](https://docs.mem0.ai/components/vectordbs/dbs/elasticsearch): Distributed search and analytics engine
- [OpenSearch](https://docs.mem0.ai/components/vectordbs/dbs/opensearch): Open-source search and analytics platform
- [Supabase](https://docs.mem0.ai/components/vectordbs/dbs/supabase): Open-source Firebase alternative with vector support
- [Upstash Vector](https://docs.mem0.ai/components/vectordbs/dbs/upstash-vector): Serverless vector database
- [Vectorize](https://docs.mem0.ai/components/vectordbs/dbs/vectorize): Vectorize vector database integration
- [Vertex AI Vector Search](https://docs.mem0.ai/components/vectordbs/dbs/vertex_ai): Google Cloud's vector search service
- [Weaviate](https://docs.mem0.ai/components/vectordbs/dbs/weaviate): Open-source vector search engine with built-in ML capabilities
- [FAISS](https://docs.mem0.ai/components/vectordbs/dbs/faiss): Facebook AI Similarity Search library
- [LangChain Vector Store](https://docs.mem0.ai/components/vectordbs/dbs/langchain): LangChain vector store integration
- [Baidu](https://docs.mem0.ai/components/vectordbs/dbs/baidu): Baidu vector database integration
- [Cassandra](https://docs.mem0.ai/components/vectordbs/dbs/cassandra): Apache Cassandra with vector search capabilities
- [S3 Vectors](https://docs.mem0.ai/components/vectordbs/dbs/s3_vectors): Amazon S3 Vectors integration
- [Databricks](https://docs.mem0.ai/components/vectordbs/dbs/databricks): Delta Lake integration for vector search
- [Neptune Analytics](https://docs.mem0.ai/components/vectordbs/dbs/neptune_analytics): AWS Neptune Analytics for graph and vector search
- [Turbopuffer](https://docs.mem0.ai/components/vectordbs/dbs/turbopuffer): High-performance serverless vector database
### Embedding Models
- [Embeddings Overview](https://docs.mem0.ai/components/embedders/overview): Embedding model configuration for semantic understanding
- [Embeddings Configuration](https://docs.mem0.ai/components/embedders/config): Configuration reference for embedding providers
- [OpenAI Embeddings](https://docs.mem0.ai/components/embedders/models/openai): High-quality text embeddings with customizable dimensions
- [Azure OpenAI Embeddings](https://docs.mem0.ai/components/embedders/models/azure_openai): Enterprise Azure-hosted embedding models
- [Ollama Embeddings](https://docs.mem0.ai/components/embedders/models/ollama): Local embedding models for privacy-focused applications
- [Hugging Face Embeddings](https://docs.mem0.ai/components/embedders/models/huggingface): Open-source embedding models for local deployment
- [Vertex AI Embeddings](https://docs.mem0.ai/components/embedders/models/vertexai): Google Cloud's enterprise embedding models
- [Google AI Embeddings](https://docs.mem0.ai/components/embedders/models/google_AI): Gemini embedding models
- [LM Studio Embeddings](https://docs.mem0.ai/components/embedders/models/lmstudio): Local model embeddings
- [Together Embeddings](https://docs.mem0.ai/components/embedders/models/together): Open-source model embeddings
- [LangChain Embeddings](https://docs.mem0.ai/components/embedders/models/langchain): LangChain embedder integration
- [AWS Bedrock Embeddings](https://docs.mem0.ai/components/embedders/models/aws_bedrock): Amazon embedding models through Bedrock
### Rerankers
- [Reranker Overview](https://docs.mem0.ai/components/rerankers/overview): Guide to reranking models for improving search result quality
- [Reranker Configuration](https://docs.mem0.ai/components/rerankers/config): Configuration reference for reranker providers
- [Reranker Optimization](https://docs.mem0.ai/components/rerankers/optimization): Performance tuning and optimization strategies for rerankers
- [Custom Reranker Prompts](https://docs.mem0.ai/components/rerankers/custom-prompts): Customize reranker behavior with custom prompts
- [Cohere Reranker](https://docs.mem0.ai/components/rerankers/models/cohere): Cohere reranking model integration
- [Sentence Transformer Reranker](https://docs.mem0.ai/components/rerankers/models/sentence_transformer): Cross-encoder reranking with sentence transformers
- [Hugging Face Reranker](https://docs.mem0.ai/components/rerankers/models/huggingface): Hugging Face reranking models
- [LLM Reranker](https://docs.mem0.ai/components/rerankers/models/llm_reranker): Use LLMs as rerankers for flexible relevance scoring
- [Zero Entropy Reranker](https://docs.mem0.ai/components/rerankers/models/zero_entropy): Zero Entropy reranking model
## Integrations ## Integrations
- [Integrations Overview](https://docs.mem0.ai/integrations) [Both]: Use when surveying every available integration. - [Integrations Overview](https://docs.mem0.ai/integrations): Overview of all available Mem0 integrations
### Agent Frameworks ### Agent Frameworks
- [LangChain](https://docs.mem0.ai/integrations/langchain) [Both]: Use when the user is on LangChain. - [LangChain](https://docs.mem0.ai/integrations/langchain): Seamless integration with LangChain framework for enhanced agent capabilities
- [LangGraph](https://docs.mem0.ai/integrations/langgraph) [Both]: Use when building stateful multi-actor LangGraph apps. - [LangGraph](https://docs.mem0.ai/integrations/langgraph): Build stateful, multi-actor applications with persistent memory
- [LangChain Tools](https://docs.mem0.ai/integrations/langchain-tools) [Both]: Use when Mem0 should be exposed as a LangChain tool. - [LlamaIndex](https://docs.mem0.ai/integrations/llama-index): Enhanced RAG applications with intelligent memory layer
- [LlamaIndex](https://docs.mem0.ai/integrations/llama-index) [Both]: Use when layering memory on a LlamaIndex RAG app. - [CrewAI](https://docs.mem0.ai/integrations/crewai): Multi-agent systems with shared and individual memory capabilities
- [CrewAI](https://docs.mem0.ai/integrations/crewai) [Both]: Use when building CrewAI multi-agent systems. - [AutoGen](https://docs.mem0.ai/integrations/autogen): Microsoft's multi-agent conversation framework with memory
- [AutoGen](https://docs.mem0.ai/integrations/autogen) [Both]: Use when the user is on Microsoft AutoGen. - [Agno](https://docs.mem0.ai/integrations/agno): Agno framework integration with persistent memory
- [Agno](https://docs.mem0.ai/integrations/agno) [Both]: Use when the user is on Agno. - [Camel AI](https://docs.mem0.ai/integrations/camel-ai): Camel AI multi-agent framework with memory support
- [Camel AI](https://docs.mem0.ai/integrations/camel-ai) [Both]: Use when the user is on Camel AI. - [OpenClaw](https://docs.mem0.ai/integrations/openclaw): OpenClaw framework integration
- [ChatDev](https://docs.mem0.ai/integrations/chatdev) [Both]: Use when the user is on ChatDev. - [OpenAI Agents SDK](https://docs.mem0.ai/integrations/openai-agents-sdk): OpenAI's agent framework with Mem0 memory
- [Hermes](https://docs.mem0.ai/integrations/hermes) [Both]: Use when the user is on Hermes. - [Google AI ADK](https://docs.mem0.ai/integrations/google-ai-adk): Google AI Agent Development Kit with persistent memory
- [OpenAI Agents SDK](https://docs.mem0.ai/integrations/openai-agents-sdk) [Both]: Use when the user is on the OpenAI Agents SDK. - [Mastra](https://docs.mem0.ai/integrations/mastra): Mastra TypeScript agent framework integration
- [Google AI ADK](https://docs.mem0.ai/integrations/google-ai-adk) [Both]: Use when the user is on Google's Agent Development Kit. - [Vercel AI SDK](https://docs.mem0.ai/integrations/vercel-ai-sdk): Build AI-powered web applications with persistent memory
- [Mastra](https://docs.mem0.ai/integrations/mastra) [Both]: Use when the user is on Mastra (TypeScript).
- [OpenClaw](https://docs.mem0.ai/integrations/openclaw) [Both]: Use when wiring Mem0 into Claude Code or editors via OpenClaw.
- [Vercel AI SDK](https://docs.mem0.ai/integrations/vercel-ai-sdk) [Both]: Use when the user is on the Vercel AI SDK.
### AI Coding Tools
- [Claude Code](https://docs.mem0.ai/integrations/claude-code) [Both]: Use when wiring memory into Claude Code.
- [Cursor](https://docs.mem0.ai/integrations/cursor) [Both]: Use when wiring memory into Cursor.
- [Codex](https://docs.mem0.ai/integrations/codex) [Both]: Use when wiring memory into Codex / other editor assistants.
### Voice & Real-time ### Voice & Real-time
- [LiveKit](https://docs.mem0.ai/integrations/livekit) [Both]: Use when building real-time voice/video with memory. - [LiveKit](https://docs.mem0.ai/integrations/livekit): Real-time voice and video AI with persistent memory
- [Pipecat](https://docs.mem0.ai/integrations/pipecat) [Both]: Use when the voice pipeline is Pipecat. - [Pipecat](https://docs.mem0.ai/integrations/pipecat): Voice AI pipeline framework with memory capabilities
- [ElevenLabs](https://docs.mem0.ai/integrations/elevenlabs) [Both]: Use when voice synthesis uses ElevenLabs. - [ElevenLabs](https://docs.mem0.ai/integrations/elevenlabs): Voice synthesis integration with conversational memory
### Cloud & Infrastructure ### Cloud & Infrastructure
- [AWS Bedrock](https://docs.mem0.ai/integrations/aws-bedrock) [Both]: Use when the user is on AWS Bedrock managed AI services. - [AWS Bedrock](https://docs.mem0.ai/integrations/aws-bedrock): Enterprise AWS integration for managed AI services
### Developer Tools ### Developer Tools
- [Dify](https://docs.mem0.ai/integrations/dify) [Both]: Use when the user is on Dify LLMOps. - [Dify](https://docs.mem0.ai/integrations/dify): LLMOps platform integration for production AI applications
- [Flowise](https://docs.mem0.ai/integrations/flowise) [Both]: Use when the user is on Flowise no-code. - [Flowise](https://docs.mem0.ai/integrations/flowise): No-code LLM workflow builder with memory capabilities
- [AgentOps](https://docs.mem0.ai/integrations/agentops) [Both]: Use when tracking agent observability with memory metadata. - [LangChain Tools](https://docs.mem0.ai/integrations/langchain-tools): Use Mem0 as a LangChain tool for agents
- [Keywords AI](https://docs.mem0.ai/integrations/keywords) [Both]: Use when monitoring with Keywords AI. - [AgentOps](https://docs.mem0.ai/integrations/agentops): Agent observability and monitoring with memory tracking
- [Raycast](https://docs.mem0.ai/integrations/raycast) [Both]: Use when the user wants quick memory access via Raycast. - [Keywords AI](https://docs.mem0.ai/integrations/keywords): Keywords AI integration for LLM monitoring
- [Raycast](https://docs.mem0.ai/integrations/raycast): Raycast extension for quick memory access
## Cookbooks ## Cookbooks and Examples
- [Cookbooks Overview](https://docs.mem0.ai/cookbooks/overview) [Both]: Use when surveying all reference examples. - [Cookbooks Overview](https://docs.mem0.ai/cookbooks/overview): Complete guide to Mem0 examples and implementation patterns
### Essentials ### Essential Guides
- [Building an AI Companion](https://docs.mem0.ai/cookbooks/essentials/building-ai-companion) [Both]: Use when starting a companion app from scratch. - [Building AI Companion](https://docs.mem0.ai/cookbooks/essentials/building-ai-companion): Core patterns for building AI agents with memory
- [Partition Memories by Entity](https://docs.mem0.ai/cookbooks/essentials/entity-partitioning-playbook) [Both]: Use when isolating multi-tenant memories. - [Partition Memories by Entity](https://docs.mem0.ai/cookbooks/essentials/entity-partitioning-playbook): Keep multi-tenant assistants isolated by tagging user, agent, app, and session identifiers
- [Controlling Memory Ingestion](https://docs.mem0.ai/cookbooks/essentials/controlling-memory-ingestion) [Both]: Use when deciding what to store and what to skip. - [Controlling Memory Ingestion](https://docs.mem0.ai/cookbooks/essentials/controlling-memory-ingestion): Fine-tune what gets stored in memory and when
- [Tagging and Organizing Memories](https://docs.mem0.ai/cookbooks/essentials/tagging-and-organizing-memories) [Both]: Use when memory taxonomy matters. - [Tagging and Organizing Memories](https://docs.mem0.ai/cookbooks/essentials/tagging-and-organizing-memories): Advanced memory organization and categorization
- [Exporting Memories](https://docs.mem0.ai/cookbooks/essentials/exporting-memories) [Both]: Use when backing up or migrating memory data. - [Exporting Memories](https://docs.mem0.ai/cookbooks/essentials/exporting-memories): Backup and transfer memory data between systems
### AI Companions ### AI Companion Examples
- [Quickstart Demo](https://docs.mem0.ai/cookbooks/companions/quickstart-demo) [Both]: Use when showing the smallest end-to-end companion. - [Quickstart Demo](https://docs.mem0.ai/cookbooks/companions/quickstart-demo): Quick demo of building an AI companion with memory
- [Node.js Companion](https://docs.mem0.ai/cookbooks/companions/nodejs-companion) [Both]: Use when the companion is in JavaScript/TypeScript. - [Node.js Companion](https://docs.mem0.ai/cookbooks/companions/nodejs-companion): JavaScript-based AI companion applications
- [AI Tutor](https://docs.mem0.ai/cookbooks/companions/ai-tutor) [Both]: Use when the agent adapts to a learner over time. - [AI Tutor](https://docs.mem0.ai/cookbooks/companions/ai-tutor): Educational AI that adapts to learning progress
- [Travel Assistant](https://docs.mem0.ai/cookbooks/companions/travel-assistant) [Both]: Use when the agent learns travel preferences. - [Travel Assistant](https://docs.mem0.ai/cookbooks/companions/travel-assistant): Travel planning agent that learns preferences
- [YouTube Research Assistant](https://docs.mem0.ai/cookbooks/companions/youtube-research) [Both]: Use when building an agent that ingests video content over sessions. - [YouTube Research Assistant](https://docs.mem0.ai/cookbooks/companions/youtube-research): AI that researches and learns from video content
- [Voice Companion (OpenAI)](https://docs.mem0.ai/cookbooks/companions/voice-companion-openai) [Both]: Use when the companion is voice-first with OpenAI Realtime. - [Voice Companion](https://docs.mem0.ai/cookbooks/companions/voice-companion-openai): Voice-enabled AI with conversational memory
- [Local Companion (Ollama)](https://docs.mem0.ai/cookbooks/companions/local-companion-ollama) [OSS]: Use when the companion must run entirely on local models. - [Local Companion](https://docs.mem0.ai/cookbooks/companions/local-companion-ollama): Privacy-focused companion using local models
### Operations & Automation ### Operations & Automation
- [Support Inbox](https://docs.mem0.ai/cookbooks/operations/support-inbox) [Both]: Use when a support agent needs conversation history across tickets. - [Support Inbox](https://docs.mem0.ai/cookbooks/operations/support-inbox): Customer service agents with conversation history
- [Email Automation](https://docs.mem0.ai/cookbooks/operations/email-automation) [Both]: Use when processing email with contextual memory. - [Email Automation](https://docs.mem0.ai/cookbooks/operations/email-automation): Smart email processing with contextual memory
- [Content Writing](https://docs.mem0.ai/cookbooks/operations/content-writing) [Both]: Use when an AI writer must maintain brand voice across sessions. - [Content Writing](https://docs.mem0.ai/cookbooks/operations/content-writing): AI writers that maintain brand voice and style
- [Deep Research](https://docs.mem0.ai/cookbooks/operations/deep-research) [Both]: Use when research agents build on previous findings. - [Deep Research](https://docs.mem0.ai/cookbooks/operations/deep-research): Research assistants that build on previous findings
- [Team Task Agent](https://docs.mem0.ai/cookbooks/operations/team-task-agent) [Both]: Use when collaborative agents share project memory. - [Team Task Agent](https://docs.mem0.ai/cookbooks/operations/team-task-agent): Collaborative AI agents with shared project memory
### Integration Examples ### Integration Examples
- [Agents SDK Tool](https://docs.mem0.ai/cookbooks/integrations/agents-sdk-tool) [Platform]: Use when exposing Mem0 as a tool in OpenAI Agents SDK. - [Agents SDK Tool](https://docs.mem0.ai/cookbooks/integrations/agents-sdk-tool): Using Mem0 as a tool with OpenAI Agents SDK
- [OpenAI Tool Calls](https://docs.mem0.ai/cookbooks/integrations/openai-tool-calls) [Platform]: Use when hooking Mem0 into OpenAI function calling. - [OpenAI Tool Calls](https://docs.mem0.ai/cookbooks/integrations/openai-tool-calls): Mem0 integrated with OpenAI function calling
- [Mastra Agent](https://docs.mem0.ai/cookbooks/integrations/mastra-agent) [Both]: Use when the agent is built in Mastra. - [Mastra Agent](https://docs.mem0.ai/cookbooks/integrations/mastra-agent): Mastra framework integration with memory
- [Healthcare Google ADK](https://docs.mem0.ai/cookbooks/integrations/healthcare-google-adk) [Both]: Use when the domain is medical and the framework is Google ADK. - [Healthcare Google ADK](https://docs.mem0.ai/cookbooks/integrations/healthcare-google-adk): Medical AI applications with memory
- [AWS Bedrock](https://docs.mem0.ai/cookbooks/integrations/aws-bedrock) [Both]: Use when deploying with AWS managed model services. - [AWS Bedrock](https://docs.mem0.ai/cookbooks/integrations/aws-bedrock): Enterprise memory with AWS managed services
- [Tavily Search](https://docs.mem0.ai/cookbooks/integrations/tavily-search) [Both]: Use when the agent layers web search on memory. - [Neptune Analytics](https://docs.mem0.ai/cookbooks/integrations/neptune-analytics): Graph and vector search with AWS Neptune
- [Tavily Search](https://docs.mem0.ai/cookbooks/integrations/tavily-search): Web search with persistent memory of results
### Framework Examples ### Framework Examples
- [LlamaIndex React](https://docs.mem0.ai/cookbooks/frameworks/llamaindex-react) [Both]: Use when building a React UI with LlamaIndex and memory. - [LlamaIndex React](https://docs.mem0.ai/cookbooks/frameworks/llamaindex-react): React applications with LlamaIndex and memory
- [LlamaIndex Multiagent](https://docs.mem0.ai/cookbooks/frameworks/llamaindex-multiagent) [Both]: Use when running LlamaIndex multi-agent systems with shared memory. - [LlamaIndex Multiagent](https://docs.mem0.ai/cookbooks/frameworks/llamaindex-multiagent): Multi-agent systems with shared memory
- [Multimodal Retrieval](https://docs.mem0.ai/cookbooks/frameworks/multimodal-retrieval) [Both]: Use when memory must handle text, images, and docs together. - [Multimodal Retrieval](https://docs.mem0.ai/cookbooks/frameworks/multimodal-retrieval): Memory systems handling text, images, and documents
- [Eliza OS Character](https://docs.mem0.ai/cookbooks/frameworks/eliza-os-character) [Both]: Use when building a character-based agent with persistent personality. - [Eliza OS Character](https://docs.mem0.ai/cookbooks/frameworks/eliza-os-character): Character-based AI with persistent personality
- [Gemini with Mem0 MCP](https://docs.mem0.ai/cookbooks/frameworks/gemini-3-with-mem0-mcp) [Platform]: Use when Gemini connects to Mem0 over MCP. - [Gemini with Mem0 MCP](https://docs.mem0.ai/cookbooks/frameworks/gemini-3-with-mem0-mcp): Google Gemini integration using MCP server
## API Reference ## API Reference
All API Reference docs describe Mem0 Platform REST endpoints (requires API key). - [API Reference Overview](https://docs.mem0.ai/api-reference): REST API overview with authentication and quick start guide
- [Organizations & Projects](https://docs.mem0.ai/api-reference/organizations-projects): Managing organizations and projects for multi-tenant setups
- [API Reference Overview](https://docs.mem0.ai/api-reference) [Platform]: Use when explaining authentication and the general request/response shape. ### Core Memory APIs
- [Organizations & Projects](https://docs.mem0.ai/api-reference/organizations-projects) [Platform]: Use when the user needs multi-tenant isolation. - [Add Memories](https://docs.mem0.ai/api-reference/memory/add-memories): REST API for storing new memories with detailed request/response formats
- [Get All Memories](https://docs.mem0.ai/api-reference/memory/get-memories): Retrieve all memories with pagination and filtering options
- [Search Memories](https://docs.mem0.ai/api-reference/memory/search-memories): Advanced search API with filtering and ranking capabilities
- [Update Memory](https://docs.mem0.ai/api-reference/memory/update-memory): Modify existing memories with conflict resolution
- [Delete Memory](https://docs.mem0.ai/api-reference/memory/delete-memory): Remove a specific memory by ID
### Core Memory ### Additional Memory APIs
- [Add Memories](https://docs.mem0.ai/api-reference/memory/add-memories) [Platform]: Use when writing one or more memories. - [Create Memory Export](https://docs.mem0.ai/api-reference/memory/create-memory-export): Export memories in bulk
- [Get All Memories](https://docs.mem0.ai/api-reference/memory/get-memories) [Platform]: Use when paginating memories for a user/agent. - [Feedback](https://docs.mem0.ai/api-reference/memory/feedback): Submit feedback on memory quality
- [Get Memory](https://docs.mem0.ai/api-reference/memory/get-memory) [Platform]: Use when fetching one memory by ID. - [Get Memory](https://docs.mem0.ai/api-reference/memory/get-memory): Retrieve a single memory by ID
- [Search Memories](https://docs.mem0.ai/api-reference/memory/search-memories) [Platform]: Use when running a semantic query with filters. - [Memory History](https://docs.mem0.ai/api-reference/memory/history-memory): View the history of changes to a memory
- [Update Memory](https://docs.mem0.ai/api-reference/memory/update-memory) [Platform]: Use when editing a memory in place. - [Get Memory Export](https://docs.mem0.ai/api-reference/memory/get-memory-export): Retrieve a previously created memory export
- [Delete Memory](https://docs.mem0.ai/api-reference/memory/delete-memory) [Platform]: Use when removing one memory. - [Batch Update](https://docs.mem0.ai/api-reference/memory/batch-update): Update multiple memories in a single request
- [Delete All Memories](https://docs.mem0.ai/api-reference/memory/delete-memories) [Platform]: Use when purging memories matching a scope. - [Batch Delete](https://docs.mem0.ai/api-reference/memory/batch-delete): Delete multiple memories in a single request
- [Batch Update](https://docs.mem0.ai/api-reference/memory/batch-update) [Platform]: Use when updating many memories in one call. - [Delete All Memories](https://docs.mem0.ai/api-reference/memory/delete-memories): Remove all memories matching criteria
- [Batch Delete](https://docs.mem0.ai/api-reference/memory/batch-delete) [Platform]: Use when deleting many memories in one call.
- [Memory History](https://docs.mem0.ai/api-reference/memory/history-memory) [Platform]: Use when the user needs the change log for a memory.
- [Feedback](https://docs.mem0.ai/api-reference/memory/feedback) [Platform]: Use when capturing user signals on memory quality.
- [Create Memory Export](https://docs.mem0.ai/api-reference/memory/create-memory-export) [Platform]: Use when kicking off an async export job.
- [Get Memory Export](https://docs.mem0.ai/api-reference/memory/get-memory-export) [Platform]: Use when fetching the result of an export job.
### Events ### Events APIs
- [Get Events](https://docs.mem0.ai/api-reference/events/get-events) [Platform]: Use when listing async memory operation events. - [Get Events](https://docs.mem0.ai/api-reference/events/get-events): List asynchronous memory operation events
- [Get Event](https://docs.mem0.ai/api-reference/events/get-event) [Platform]: Use when fetching one event by ID. - [Get Event](https://docs.mem0.ai/api-reference/events/get-event): Retrieve details of a specific event
### Entities ### Entities APIs
- [Get Users](https://docs.mem0.ai/api-reference/entities/get-users) [Platform]: Use when listing users, agents, or apps known to a project. - [Get Users](https://docs.mem0.ai/api-reference/entities/get-users): List all entities (users, agents, apps)
- [Delete User](https://docs.mem0.ai/api-reference/entities/delete-user) [Platform]: Use when removing an entity and all its memories. - [Delete User](https://docs.mem0.ai/api-reference/entities/delete-user): Remove an entity and all associated memories
### Organizations ### Organizations APIs
- [Create Organization](https://docs.mem0.ai/api-reference/organization/create-org) [Platform]: Use when setting up a new org. - [Create Organization](https://docs.mem0.ai/api-reference/organization/create-org): Create a new organization
- [Get Organizations](https://docs.mem0.ai/api-reference/organization/get-orgs) [Platform]: Use when listing orgs. - [Get Organizations](https://docs.mem0.ai/api-reference/organization/get-orgs): List all organizations
- [Get Organization](https://docs.mem0.ai/api-reference/organization/get-org) [Platform]: Use when fetching one org. - [Get Organization](https://docs.mem0.ai/api-reference/organization/get-org): Retrieve organization details
- [Get Organization Members](https://docs.mem0.ai/api-reference/organization/get-org-members) [Platform]: Use when listing org members. - [Get Organization Members](https://docs.mem0.ai/api-reference/organization/get-org-members): List organization members
- [Add Organization Member](https://docs.mem0.ai/api-reference/organization/add-org-member) [Platform]: Use when inviting a member to an org. - [Add Organization Member](https://docs.mem0.ai/api-reference/organization/add-org-member): Add a member to an organization
- [Delete Organization](https://docs.mem0.ai/api-reference/organization/delete-org) [Platform]: Use when removing an org. - [Delete Organization](https://docs.mem0.ai/api-reference/organization/delete-org): Remove an organization
### Projects ### Project APIs
- [Create Project](https://docs.mem0.ai/api-reference/project/create-project) [Platform]: Use when creating a project inside an org. - [Create Project](https://docs.mem0.ai/api-reference/project/create-project): Create a new project within an organization
- [Get Projects](https://docs.mem0.ai/api-reference/project/get-projects) [Platform]: Use when listing projects. - [Get Projects](https://docs.mem0.ai/api-reference/project/get-projects): List all projects
- [Get Project](https://docs.mem0.ai/api-reference/project/get-project) [Platform]: Use when fetching one project. - [Get Project](https://docs.mem0.ai/api-reference/project/get-project): Retrieve project details
- [Get Project Members](https://docs.mem0.ai/api-reference/project/get-project-members) [Platform]: Use when listing project members. - [Get Project Members](https://docs.mem0.ai/api-reference/project/get-project-members): List project members
- [Add Project Member](https://docs.mem0.ai/api-reference/project/add-project-member) [Platform]: Use when inviting a member to a project. - [Add Project Member](https://docs.mem0.ai/api-reference/project/add-project-member): Add a member to a project
- [Delete Project](https://docs.mem0.ai/api-reference/project/delete-project) [Platform]: Use when removing a project. - [Delete Project](https://docs.mem0.ai/api-reference/project/delete-project): Remove a project
### Webhooks ### Webhook APIs
- [Create Webhook](https://docs.mem0.ai/api-reference/webhook/create-webhook) [Platform]: Use when registering a webhook endpoint. - [Create Webhook](https://docs.mem0.ai/api-reference/webhook/create-webhook): Register a new webhook endpoint
- [Get Webhook](https://docs.mem0.ai/api-reference/webhook/get-webhook) [Platform]: Use when fetching webhook config. - [Get Webhook](https://docs.mem0.ai/api-reference/webhook/get-webhook): Retrieve webhook configuration
- [Update Webhook](https://docs.mem0.ai/api-reference/webhook/update-webhook) [Platform]: Use when modifying webhook settings. - [Update Webhook](https://docs.mem0.ai/api-reference/webhook/update-webhook): Modify webhook settings
- [Delete Webhook](https://docs.mem0.ai/api-reference/webhook/delete-webhook) [Platform]: Use when removing a webhook. - [Delete Webhook](https://docs.mem0.ai/api-reference/webhook/delete-webhook): Remove a webhook
## Skills & Plugins
Mem0 ships first-class integrations for AI coding editors and MCP-aware tools. When the user is in Claude Code, Cursor, Codex, or any MCP client, load this section first.
### Claude Code Skills (in-repo, not on docs.mem0.ai)
Source: https://github.com/mem0ai/mem0/tree/main/skills
- **skills/mem0** - Default Mem0 skill. Trigger on mentions of `MemoryClient`, "memory layer", personalization, or adding long-term memory to chatbots/agents. Covers Python SDK, TS SDK, and every framework integration.
- **skills/mem0-cli** - Trigger on CLI / terminal / shell usage of Mem0.
- **skills/mem0-vercel-ai-sdk** - Trigger when the stack includes `@mem0/vercel-ai-provider` or `createMem0`.
Each subdirectory is a Claude Code Skill (`SKILL.md` + supporting assets). Load only the one that matches the user's stack.
### Editor Plugin (shared glue)
Source: https://github.com/mem0ai/mem0/tree/main/mem0-plugin
The `mem0-plugin/` directory provides MCP server connection, lifecycle hooks, and skill bundling for Claude Code, Cursor, and Codex. It exposes 9 MCP tools: `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities`.
Editor-specific setup docs (already listed above under `## Integrations > AI Coding Tools`):
- `integrations/claude-code` [Both]
- `integrations/cursor` [Both]
- `integrations/codex` [Both]
- `integrations/openclaw` [Both]
### MCP Endpoints
- Hosted MCP server: `https://mcp.mem0.ai` - requires Platform API key. See `platform/mem0-mcp`.
- Self-hosted MCP server: ships with `openmemory/api/` (FastAPI) - runs against your own Qdrant + LLM stack.
## Community & Support ## Community & Support
- [Contributing - Development](https://docs.mem0.ai/contributing/development) [Both]: Use when the user wants to contribute code. - [Contributing - Development](https://docs.mem0.ai/contributing/development): Guidelines for contributing to Mem0's open-source development
- [Contributing - Documentation](https://docs.mem0.ai/contributing/documentation) [Both]: Use when the user wants to contribute docs. - [Contributing - Documentation](https://docs.mem0.ai/contributing/documentation): Guidelines for contributing to Mem0's documentation
- [Changelog](https://docs.mem0.ai/changelog): Detailed product updates and version history
## Optional
Everything below is OSS-only provider configuration. Skip this entire section when the user is on Mem0 Platform (providers are managed server-side). When the user is self-hosting, load only the subsection that matches the provider they are configuring.
### LLM Providers [OSS]
- [LLM Overview](https://docs.mem0.ai/components/llms/overview) [OSS]: Use when the user is choosing an LLM for memory extraction.
- [LLM Configuration](https://docs.mem0.ai/components/llms/config) [OSS]: Use for the `llm` config schema.
- [OpenAI](https://docs.mem0.ai/components/llms/models/openai) [OSS]: Use when the extraction LLM is OpenAI.
- [Anthropic](https://docs.mem0.ai/components/llms/models/anthropic) [OSS]: Use when the extraction LLM is Claude.
- [Azure OpenAI](https://docs.mem0.ai/components/llms/models/azure_openai) [OSS]: Use when the user is on Azure-hosted OpenAI.
- [AWS Bedrock](https://docs.mem0.ai/components/llms/models/aws_bedrock) [OSS]: Use when the LLM runs through Bedrock.
- [Google AI](https://docs.mem0.ai/components/llms/models/google_AI) [OSS]: Use when the LLM is Gemini.
- [Groq](https://docs.mem0.ai/components/llms/models/groq) [OSS]: Use when the user wants Groq's low-latency inference.
- [DeepSeek](https://docs.mem0.ai/components/llms/models/deepseek) [OSS]: Use when the LLM is DeepSeek.
- [Mistral AI](https://docs.mem0.ai/components/llms/models/mistral_AI) [OSS]: Use when the LLM is Mistral.
- [MiniMax](https://docs.mem0.ai/components/llms/models/minimax) [OSS]: Use when the LLM is MiniMax.
- [xAI](https://docs.mem0.ai/components/llms/models/xAI) [OSS]: Use when the LLM is xAI Grok.
- [Sarvam](https://docs.mem0.ai/components/llms/models/sarvam) [OSS]: Use for Indian-language Sarvam models.
- [Together](https://docs.mem0.ai/components/llms/models/together) [OSS]: Use when the LLM runs on Together.
- [Ollama](https://docs.mem0.ai/components/llms/models/ollama) [OSS]: Use when the LLM is a local Ollama model.
- [LM Studio](https://docs.mem0.ai/components/llms/models/lmstudio) [OSS]: Use when the LLM is served from LM Studio.
- [LiteLLM](https://docs.mem0.ai/components/llms/models/litellm) [OSS]: Use when multiplexing many providers behind LiteLLM.
- [vLLM](https://docs.mem0.ai/components/llms/models/vllm) [OSS]: Use when self-hosting inference with vLLM.
- [LangChain LLM](https://docs.mem0.ai/components/llms/models/langchain) [OSS]: Use when the LLM is wrapped behind a LangChain adapter.
### Embedding Providers [OSS]
- [Embeddings Overview](https://docs.mem0.ai/components/embedders/overview) [OSS]: Use when choosing an embedding model.
- [Embeddings Configuration](https://docs.mem0.ai/components/embedders/config) [OSS]: Use for the `embedder` config schema.
- [OpenAI Embeddings](https://docs.mem0.ai/components/embedders/models/openai) [OSS]: Use when embeddings come from OpenAI.
- [Azure OpenAI Embeddings](https://docs.mem0.ai/components/embedders/models/azure_openai) [OSS]: Use for Azure-hosted OpenAI embeddings.
- [AWS Bedrock Embeddings](https://docs.mem0.ai/components/embedders/models/aws_bedrock) [OSS]: Use for Bedrock-hosted embeddings.
- [Google AI Embeddings](https://docs.mem0.ai/components/embedders/models/google_AI) [OSS]: Use for Gemini embeddings.
- [Vertex AI Embeddings](https://docs.mem0.ai/components/embedders/models/vertexai) [OSS]: Use for Google Cloud Vertex AI embeddings.
- [Hugging Face Embeddings](https://docs.mem0.ai/components/embedders/models/huggingface) [OSS]: Use for open-source HF embedding models.
- [Ollama Embeddings](https://docs.mem0.ai/components/embedders/models/ollama) [OSS]: Use when embeddings run through local Ollama.
- [LM Studio Embeddings](https://docs.mem0.ai/components/embedders/models/lmstudio) [OSS]: Use when embeddings run through LM Studio.
- [Together Embeddings](https://docs.mem0.ai/components/embedders/models/together) [OSS]: Use when embeddings run on Together.
- [LangChain Embeddings](https://docs.mem0.ai/components/embedders/models/langchain) [OSS]: Use when embeddings are wrapped behind a LangChain adapter.
### Vector Databases [OSS]
- [Vector Database Overview](https://docs.mem0.ai/components/vectordbs/overview) [OSS]: Use when choosing a vector store.
- [Vector Database Configuration](https://docs.mem0.ai/components/vectordbs/config) [OSS]: Use for the `vector_store` config schema.
- [Qdrant](https://docs.mem0.ai/components/vectordbs/dbs/qdrant) [OSS]: Use as the default self-hosted vector store (best-tested).
- [Chroma](https://docs.mem0.ai/components/vectordbs/dbs/chroma) [OSS]: Use when the user wants a lightweight embedded store.
- [PGVector](https://docs.mem0.ai/components/vectordbs/dbs/pgvector) [OSS]: Use when Postgres is already in the stack.
- [Milvus](https://docs.mem0.ai/components/vectordbs/dbs/milvus) [OSS]: Use for large-scale Milvus deployments.
- [Pinecone](https://docs.mem0.ai/components/vectordbs/dbs/pinecone) [OSS]: Use when the user is on Pinecone managed.
- [MongoDB](https://docs.mem0.ai/components/vectordbs/dbs/mongodb) [OSS]: Use when Mongo Atlas Vector Search is the backing store.
- [Azure AI Search](https://docs.mem0.ai/components/vectordbs/dbs/azure) [OSS]: Use when the user is on Azure AI Search.
- [Azure MySQL](https://docs.mem0.ai/components/vectordbs/dbs/azure_mysql) [OSS]: Use when vector search runs on Azure Database for MySQL.
- [Redis](https://docs.mem0.ai/components/vectordbs/dbs/redis) [OSS]: Use when Redis Stack is the backing store.
- [Valkey](https://docs.mem0.ai/components/vectordbs/dbs/valkey) [OSS]: Use when the user is on Valkey (Redis fork).
- [Elasticsearch](https://docs.mem0.ai/components/vectordbs/dbs/elasticsearch) [OSS]: Use when Elasticsearch is the backing store.
- [OpenSearch](https://docs.mem0.ai/components/vectordbs/dbs/opensearch) [OSS]: Use when OpenSearch is the backing store.
- [Supabase](https://docs.mem0.ai/components/vectordbs/dbs/supabase) [OSS]: Use when Supabase with pgvector is the backing store.
- [Upstash Vector](https://docs.mem0.ai/components/vectordbs/dbs/upstash-vector) [OSS]: Use for serverless Upstash Vector.
- [Vectorize](https://docs.mem0.ai/components/vectordbs/dbs/vectorize) [OSS]: Use when the store is Cloudflare Vectorize.
- [Vertex AI Vector Search](https://docs.mem0.ai/components/vectordbs/dbs/vertex_ai) [OSS]: Use when the store is Google Cloud Vertex Vector Search.
- [Weaviate](https://docs.mem0.ai/components/vectordbs/dbs/weaviate) [OSS]: Use when Weaviate is the backing store.
- [FAISS](https://docs.mem0.ai/components/vectordbs/dbs/faiss) [OSS]: Use for local FAISS-based similarity search.
- [LangChain Vector Store](https://docs.mem0.ai/components/vectordbs/dbs/langchain) [OSS]: Use when the vector store is wrapped behind LangChain.
- [Baidu](https://docs.mem0.ai/components/vectordbs/dbs/baidu) [OSS]: Use when the user is on Baidu Cloud vector service.
- [Cassandra](https://docs.mem0.ai/components/vectordbs/dbs/cassandra) [OSS]: Use when Cassandra is the backing store.
- [S3 Vectors](https://docs.mem0.ai/components/vectordbs/dbs/s3_vectors) [OSS]: Use for AWS S3 Vectors.
- [Databricks](https://docs.mem0.ai/components/vectordbs/dbs/databricks) [OSS]: Use when the user is on Databricks with Delta Lake.
- [Neptune Analytics](https://docs.mem0.ai/components/vectordbs/dbs/neptune_analytics) [OSS]: Use when the user is on AWS Neptune Analytics (graph + vector).
- [Turbopuffer](https://docs.mem0.ai/components/vectordbs/dbs/turbopuffer) [OSS]: Use when the user is on Turbopuffer serverless.
### Rerankers [OSS]
- [Reranker Overview](https://docs.mem0.ai/components/rerankers/overview) [OSS]: Use when the user wants to improve OSS search result quality.
- [Reranker Configuration](https://docs.mem0.ai/components/rerankers/config) [OSS]: Use for the `reranker` config schema.
- [Reranker Optimization](https://docs.mem0.ai/components/rerankers/optimization) [OSS]: Use when tuning reranker performance.
- [Custom Reranker Prompts](https://docs.mem0.ai/components/rerankers/custom-prompts) [OSS]: Use when rewriting reranker prompts.
- [Cohere Reranker](https://docs.mem0.ai/components/rerankers/models/cohere) [OSS]: Use for Cohere Rerank.
- [Sentence Transformer Reranker](https://docs.mem0.ai/components/rerankers/models/sentence_transformer) [OSS]: Use for local cross-encoder rerankers.
- [Hugging Face Reranker](https://docs.mem0.ai/components/rerankers/models/huggingface) [OSS]: Use for HF-hosted reranker models.
- [LLM Reranker (prompt)](https://docs.mem0.ai/components/rerankers/models/llm) [OSS]: Use when the reranker is a prompted LLM (config guide).
- [LLM Reranker](https://docs.mem0.ai/components/rerankers/models/llm_reranker) [OSS]: Use when the reranker is a prompted LLM (implementation reference).
- [Zero Entropy Reranker](https://docs.mem0.ai/components/rerankers/models/zero_entropy) [OSS]: Use for the Zero Entropy reranker.
@@ -115,15 +115,17 @@ config = {
} }
}, },
"custom_instructions": custom_instructions, "custom_instructions": custom_instructions,
"version": "v1.1"
} }
m = Memory.from_config(config) m = Memory.from_config(config_dict=config)
``` ```
```ts TypeScript ```ts TypeScript
import { Memory } from "mem0ai/oss"; import { Memory } from "mem0ai/oss";
const config = { const config = {
version: "v1.1",
llm: { llm: {
provider: "openai", provider: "openai",
config: { config: {
@@ -51,7 +51,8 @@ m = Memory()
# Search with simple metadata filters # Search with simple metadata filters
results = m.search( results = m.search(
"What are my preferences?", "What are my preferences?",
filters={"user_id": "alice", "category": "preferences"} user_id="alice",
filters={"category": "preferences"}
) )
``` ```
@@ -67,8 +68,8 @@ Layer greater-than/less-than comparisons to rank results by score, confidence, o
# Greater than / Less than # Greater than / Less than
results = m.search( results = m.search(
"recent activities", "recent activities",
user_id="alice",
filters={ filters={
"user_id": "alice",
"score": {"gt": 0.8}, "score": {"gt": 0.8},
"priority": {"gte": 5}, "priority": {"gte": 5},
"confidence": {"lt": 0.9}, "confidence": {"lt": 0.9},
@@ -79,8 +80,8 @@ results = m.search(
# Equality operators # Equality operators
results = m.search( results = m.search(
"specific content", "specific content",
user_id="alice",
filters={ filters={
"user_id": "alice",
"status": {"eq": "active"}, "status": {"eq": "active"},
"archived": {"ne": True} "archived": {"ne": True}
} }
@@ -95,8 +96,8 @@ Use `in` and `nin` when you want to pre-approve or exclude specific values witho
# In / Not in operators # In / Not in operators
results = m.search( results = m.search(
"multi-category search", "multi-category search",
user_id="alice",
filters={ filters={
"user_id": "alice",
"category": {"in": ["food", "travel", "entertainment"]}, "category": {"in": ["food", "travel", "entertainment"]},
"status": {"nin": ["deleted", "archived"]} "status": {"nin": ["deleted", "archived"]}
} }
@@ -115,8 +116,8 @@ results = m.search(
# Text matching operators # Text matching operators
results = m.search( results = m.search(
"content search", "content search",
user_id="alice",
filters={ filters={
"user_id": "alice",
"title": {"contains": "meeting"}, "title": {"contains": "meeting"},
"description": {"icontains": "important"}, "description": {"icontains": "important"},
"tags": {"contains": "urgent"} "tags": {"contains": "urgent"}
@@ -132,8 +133,8 @@ Allow any value for a field while still requiring the field to exist—handy whe
# Match any value for a field # Match any value for a field
results = m.search( results = m.search(
"all with category", "all with category",
user_id="alice",
filters={ filters={
"user_id": "alice",
"category": "*" "category": "*"
} }
) )
@@ -147,9 +148,9 @@ Combine filters with `AND`, `OR`, and `NOT` to express complex decision trees. N
# Logical AND # Logical AND
results = m.search( results = m.search(
"complex query", "complex query",
user_id="alice",
filters={ filters={
"AND": [ "AND": [
{"user_id": "alice"},
{"category": "work"}, {"category": "work"},
{"priority": {"gte": 7}}, {"priority": {"gte": 7}},
{"status": {"ne": "completed"}} {"status": {"ne": "completed"}}
@@ -160,16 +161,12 @@ results = m.search(
# Logical OR # Logical OR
results = m.search( results = m.search(
"flexible query", "flexible query",
user_id="alice",
filters={ filters={
"AND": [ "OR": [
{"user_id": "alice"}, {"category": "urgent"},
{ {"priority": {"gte": 9}},
"OR": [ {"deadline": {"contains": "today"}}
{"category": "urgent"},
{"priority": {"gte": 9}},
{"deadline": {"contains": "today"}}
]
}
] ]
} }
) )
@@ -177,15 +174,11 @@ results = m.search(
# Logical NOT # Logical NOT
results = m.search( results = m.search(
"exclusion query", "exclusion query",
user_id="alice",
filters={ filters={
"AND": [ "NOT": [
{"user_id": "alice"}, {"category": "archived"},
{ {"status": "deleted"}
"NOT": [
{"category": "archived"},
{"status": "deleted"}
]
}
] ]
} }
) )
@@ -193,9 +186,9 @@ results = m.search(
# Complex nested logic # Complex nested logic
results = m.search( results = m.search(
"advanced query", "advanced query",
user_id="alice",
filters={ filters={
"AND": [ "AND": [
{"user_id": "alice"},
{ {
"OR": [ "OR": [
{"category": "work"}, {"category": "work"},
@@ -295,15 +288,16 @@ Vector store support varies. Confirm operator coverage before shipping:
# Before (v0.x) - simple key-value filtering only # Before (v0.x) - simple key-value filtering only
results = m.search( results = m.search(
"query", "query",
filters={"user_id": "alice", "category": "work", "status": "active"} user_id="alice",
filters={"category": "work", "status": "active"}
) )
# After (v1.0.0) - enhanced filtering with operators # After (v1.0.0) - enhanced filtering with operators
results = m.search( results = m.search(
"query", "query",
user_id="alice",
filters={ filters={
"AND": [ "AND": [
{"user_id": "alice"},
{"category": "work"}, {"category": "work"},
{"status": {"ne": "archived"}}, {"status": {"ne": "archived"}},
{"priority": {"gte": 5}} {"priority": {"gte": 5}}
@@ -326,9 +320,9 @@ results = m.search(
# Find high-priority active tasks # Find high-priority active tasks
results = m.search( results = m.search(
"What tasks need attention?", "What tasks need attention?",
user_id="project_manager",
filters={ filters={
"AND": [ "AND": [
{"user_id": "project_manager"},
{"project": {"in": ["alpha", ""]}}, {"project": {"in": ["alpha", ""]}},
{"priority": {"gte": 8}}, {"priority": {"gte": 8}},
{"status": {"ne": "completed"}}, {"status": {"ne": "completed"}},
@@ -353,9 +347,9 @@ results = m.search(
# Find recent unresolved tickets # Find recent unresolved tickets
results = m.search( results = m.search(
"pending support issues", "pending support issues",
agent_id="support_bot",
filters={ filters={
"AND": [ "AND": [
{"agent_id": "support_bot"},
{"ticket_status": {"ne": "resolved"}}, {"ticket_status": {"ne": "resolved"}},
{"priority": {"in": ["high", "critical"]}}, {"priority": {"in": ["high", "critical"]}},
{"created_date": {"gte": "2024-01-01"}}, {"created_date": {"gte": "2024-01-01"}},
@@ -370,7 +364,7 @@ results = m.search(
``` ```
<Tip> <Tip>
Pair agent ID filters with ticket-specific metadata so shared support bots return only the tickets they can act on in the current session. Pair `agent_id` filters with ticket-specific metadata so shared support bots return only the tickets they can act on in the current session.
</Tip> </Tip>
### Content recommendation filtering ### Content recommendation filtering
@@ -379,9 +373,9 @@ results = m.search(
# Personalized content filtering # Personalized content filtering
results = m.search( results = m.search(
"recommend content", "recommend content",
user_id="reader123",
filters={ filters={
"AND": [ "AND": [
{"user_id": "reader123"},
{ {
"OR": [ "OR": [
{"genre": {"in": ["sci-fi", "fantasy"]}}, {"genre": {"in": ["sci-fi", "fantasy"]}},
@@ -406,8 +400,8 @@ results = m.search(
try: try:
results = m.search( results = m.search(
"test query", "test query",
user_id="alice",
filters={ filters={
"user_id": "alice",
"invalid_operator": {"unknown": "value"} "invalid_operator": {"unknown": "value"}
} }
) )
@@ -415,7 +409,8 @@ except ValueError as e:
print(f"Filter error: {e}") print(f"Filter error: {e}")
results = m.search( results = m.search(
"test query", "test query",
filters={"user_id": "alice", "category": "general"} user_id="alice",
filters={"category": "general"}
) )
``` ```
+10 -8
View File
@@ -189,7 +189,7 @@ async_memory = AsyncMemory.from_config(config)
async def search_with_rerank(): async def search_with_rerank():
return await async_memory.search( return await async_memory.search(
"What are my preferences?", "What are my preferences?",
filters={"user_id": "alice"}, user_id="alice",
rerank=True rerank=True
) )
@@ -272,7 +272,7 @@ results = m.search("query", filters={"user_id": "alice"})
```python ```python
results = m.search( results = m.search(
"What are my food preferences?", "What are my food preferences?",
filters={"user_id": "alice"} user_id="alice"
) )
for result in results["results"]: for result in results["results"]:
@@ -289,13 +289,13 @@ for result in results["results"]:
```python ```python
results_with_rerank = m.search( results_with_rerank = m.search(
"What movies do I like?", "What movies do I like?",
filters={"user_id": "alice"}, user_id="alice",
rerank=True rerank=True
) )
results_without_rerank = m.search( results_without_rerank = m.search(
"What movies do I like?", "What movies do I like?",
filters={"user_id": "alice"}, user_id="alice",
rerank=False rerank=False
) )
``` ```
@@ -313,9 +313,9 @@ results_without_rerank = m.search(
```python ```python
results = m.search( results = m.search(
"important work tasks", "important work tasks",
user_id="alice",
filters={ filters={
"AND": [ "AND": [
{"user_id": "alice"},
{"category": "work"}, {"category": "work"},
{"priority": {"gte": 7}} {"priority": {"gte": 7}}
] ]
@@ -348,7 +348,8 @@ m = Memory.from_config(config)
results = m.search( results = m.search(
"customer having login issues with mobile app", "customer having login issues with mobile app",
filters={"agent_id": "support_bot", "category": "technical_support"}, agent_id="support_bot",
filters={"category": "technical_support"},
rerank=True rerank=True
) )
``` ```
@@ -362,7 +363,8 @@ results = m.search(
```python ```python
results = m.search( results = m.search(
"science fiction books with space exploration themes", "science fiction books with space exploration themes",
filters={"user_id": "reader123", "content_type": "book_recommendation"}, user_id="reader123",
filters={"content_type": "book_recommendation"},
rerank=True, rerank=True,
top_k=10 top_k=10
) )
@@ -381,9 +383,9 @@ for result in results["results"]:
```python ```python
results = m.search( results = m.search(
"What restaurants did I enjoy last month that had good vegetarian options?", "What restaurants did I enjoy last month that had good vegetarian options?",
user_id="foodie_user",
filters={ filters={
"AND": [ "AND": [
{"user_id": "foodie_user"},
{"category": "dining"}, {"category": "dining"},
{"rating": {"gte": 4}}, {"rating": {"gte": 4}},
{"date": {"gte": "2024-01-01"}} {"date": {"gte": "2024-01-01"}}
+3
View File
@@ -76,6 +76,7 @@ By default the Node SDK uses local-friendly settings (OpenAI `gpt-5-mini`, `text
import { Memory } from "mem0ai/oss"; import { Memory } from "mem0ai/oss";
const memory = new Memory({ const memory = new Memory({
version: "v1.1",
embedder: { embedder: {
provider: "openai", provider: "openai",
config: { config: {
@@ -220,6 +221,7 @@ Mem0 offers granular configuration across vector stores, LLMs, embedders, and hi
| Parameter | Description | Default | | Parameter | Description | Default |
| --- | --- | --- | | --- | --- | --- |
| `historyDbPath` | Path to history database | `"{mem0_dir}/history.db"` | | `historyDbPath` | Path to history database | `"{mem0_dir}/history.db"` |
| `version` | API version | `"v1.0"` |
| `customInstructions` | Custom processing prompt | `undefined` | | `customInstructions` | Custom processing prompt | `undefined` |
</Accordion> </Accordion>
<Accordion title="History store"> <Accordion title="History store">
@@ -232,6 +234,7 @@ Mem0 offers granular configuration across vector stores, LLMs, embedders, and hi
<Accordion title="Complete config example"> <Accordion title="Complete config example">
```ts ```ts
const config = { const config = {
version: "v1.1",
embedder: { embedder: {
provider: "openai", provider: "openai",
config: { config: {
+4
View File
@@ -8,6 +8,10 @@ icon: "house"
Mem0 Open Source delivers the same adaptive memory engine as the platform, but packaged for teams that need to run everything on their own infrastructure. You own the stack, the data, and the customizations. Mem0 Open Source delivers the same adaptive memory engine as the platform, but packaged for teams that need to run everything on their own infrastructure. You own the stack, the data, and the customizations.
<Tip>
Mem0 v1.0.0 brought rerankers, async-by-default clients, and Azure OpenAI support. See the <Link href="/changelog">release notes</Link> for the full rundown before upgrading.
</Tip>
## What Mem0 OSS provides ## What Mem0 OSS provides
- **Full control**: Tune every component, from LLMs to vector stores, inside your environment. - **Full control**: Tune every component, from LLMs to vector stores, inside your environment.
+2
View File
@@ -3,6 +3,8 @@ title: Group Chat
description: 'Enable multi-participant conversations with automatic memory attribution to individual speakers' description: 'Enable multi-participant conversations with automatic memory attribution to individual speakers'
--- ---
<Snippet file="paper-release.mdx" />
## Overview ## Overview
The Group Chat feature enables Mem0 to process conversations involving multiple participants and automatically attribute memories to individual speakers. This allows for precise tracking of each participant's preferences, characteristics, and contributions in collaborative discussions, team meetings, or multi-agent conversations. The Group Chat feature enables Mem0 to process conversations involving multiple participants and automatically attribute memories to individual speakers. This allows for precise tracking of each participant's preferences, characteristics, and contributions in collaborative discussions, team meetings, or multi-agent conversations.
@@ -15,6 +15,10 @@ When working with large-scale memory stores, you need precise control over which
* **Time-based queries**: Retrieve memories within specific date ranges * **Time-based queries**: Retrieve memories within specific date ranges
* **Performance optimization**: Reduce query complexity by pre-filtering * **Performance optimization**: Reduce query complexity by pre-filtering
<Callout type="info" icon="info-circle" color="#7A5DFF">
Filters were introduced in v1.0.0 to provide precise control over memory retrieval.
</Callout>
## Filter structure ## Filter structure
Filters use a nested JSON structure with logical operators at the root: Filters use a nested JSON structure with logical operators at the root:
+4
View File
@@ -8,6 +8,10 @@ icon: "cloud"
Mem0 is the memory engine that keeps conversations contextual so users never repeat themselves and your agents respond with continuity. Mem0 Platform delivers that experience as a fully managed service—scaling, securing, and enriching memories without any infrastructure work on your side. Mem0 is the memory engine that keeps conversations contextual so users never repeat themselves and your agents respond with continuity. Mem0 Platform delivers that experience as a fully managed service—scaling, securing, and enriching memories without any infrastructure work on your side.
<Tip>
Mem0 v1.0.0 shipped rerankers, async-by-default behavior, and Azure OpenAI support. Catch the full list of changes in the <Link href="/changelog">release notes</Link>.
</Tip>
## Why it matters ## Why it matters
- **Personalized replies**: Memories persist across users and agents, cutting prompt bloat and repeat questions. - **Personalized replies**: Memories persist across users and agents, cutting prompt bloat and repeat questions.
+57
View File
@@ -0,0 +1,57 @@
---
title: 'Full Stack'
---
The Full Stack app example can be found [here](https://github.com/mem0ai/mem0/tree/main/embedchain/examples/full_stack).
This guide will help you setup the full stack app on your local machine.
### 🐳 Docker Setup
- Create a `docker-compose.yml` file and paste the following code in it.
```yaml
version: "3.9"
services:
backend:
container_name: embedchain-backend
restart: unless-stopped
build:
context: backend
dockerfile: Dockerfile
image: embedchain/backend
ports:
- "8000:8000"
frontend:
container_name: embedchain-frontend
restart: unless-stopped
build:
context: frontend
dockerfile: Dockerfile
image: embedchain/frontend
ports:
- "3000:3000"
depends_on:
- "backend"
```
- Run the following command,
```bash
docker-compose up
```
📝 Note: The build command might take a while to install all the packages depending on your system resources.
![Fullstack App](https://github.com/embedchain/embedchain/assets/73601258/c7c04bbb-9be7-4669-a6af-039e7e972a13)
### 🚀 Usage Instructions
- Go to [http://localhost:3000/](http://localhost:3000/) in your browser to view the dashboard.
- Add your `OpenAI API key` 🔑 in the Settings.
- Create a new bot and you'll be navigated to its page.
- Here you can add your data sources and then chat with the bot.
🎉 Happy Chatting! 🎉
+1
View File
@@ -182,6 +182,7 @@
"examples/rest-api/check-status" "examples/rest-api/check-status"
] ]
}, },
"examples/full_stack",
"examples/openai-assistant", "examples/openai-assistant",
"examples/opensource-assistant", "examples/opensource-assistant",
"examples/nextjs-assistant", "examples/nextjs-assistant",
+3
View File
@@ -17,6 +17,9 @@ Chatbots, especially those powered by Large Language Models (LLMs), have a wide
Embedchain provides the right set of tools to create chatbots for the above use cases. Refer to the following examples of chatbots on and you can built on top of these examples: Embedchain provides the right set of tools to create chatbots for the above use cases. Refer to the following examples of chatbots on and you can built on top of these examples:
<CardGroup cols={2}> <CardGroup cols={2}>
<Card title="Full Stack Chatbot" href="/examples/full_stack" icon="link">
Learn to integrate a chatbot within a full-stack application.
</Card>
<Card title="Custom GPT Creation" href="https://app.embedchain.ai/create-your-gpt/" target="_blank" icon="link"> <Card title="Custom GPT Creation" href="https://app.embedchain.ai/create-your-gpt/" target="_blank" icon="link">
Build a tailored GPT chatbot suited for your specific needs. Build a tailored GPT chatbot suited for your specific needs.
</Card> </Card>
@@ -1,2 +1,2 @@
gradio>=4.14.0 gradio==4.11.0
embedchain embedchain
@@ -1,2 +1,2 @@
chainlit==0.7.700 chainlit==0.7.700
embedchain==0.1.57 embedchain==0.1.31
@@ -1,3 +1,3 @@
discord==2.3.1 discord==2.3.1
embedchain==0.1.57 embedchain==0.0.58
python-dotenv==1.0.0 python-dotenv==1.0.0
@@ -0,0 +1 @@
.git
+18
View File
@@ -0,0 +1,18 @@
## 🐳 Docker Setup
- To setup full stack app using docker, run the following command inside this folder using your terminal.
```bash
docker-compose up --build
```
📝 Note: The build command might take a while to install all the packages depending on your system resources.
## 🚀 Usage Instructions
- Go to [http://localhost:3000/](http://localhost:3000/) in your browser to view the dashboard.
- Add your `OpenAI API key` 🔑 in the Settings.
- Create a new bot and you'll be navigated to its page.
- Here you can add your data sources and then chat with the bot.
🎉 Happy Chatting! 🎉
@@ -0,0 +1,7 @@
__pycache__/
database
pyenv
venv
.env
.git
trash_files/
@@ -0,0 +1,6 @@
__pycache__
database
pyenv
venv
.env
trash_files/
@@ -0,0 +1,11 @@
FROM python:3.11-slim AS backend
WORKDIR /usr/src/app/backend
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "server.py"]
@@ -0,0 +1,14 @@
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class APIKey(db.Model):
id = db.Column(db.Integer, primary_key=True)
key = db.Column(db.String(255), nullable=False)
class BotList(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), nullable=False)
slug = db.Column(db.String(255), nullable=False, unique=True)
@@ -0,0 +1,5 @@
import os
ROOT_DIRECTORY = os.getcwd()
DB_DIRECTORY_OPEN_AI = os.path.join(os.getcwd(), "database", "open_ai")
DB_DIRECTORY_OPEN_SOURCE = os.path.join(os.getcwd(), "database", "open_source")
@@ -0,0 +1,32 @@
import os
from flask import Blueprint, jsonify, make_response, request
from models import APIKey
from paths import DB_DIRECTORY_OPEN_AI
from embedchain import App
chat_response_bp = Blueprint("chat_response", __name__)
# Chat Response for user query
@chat_response_bp.route("/api/get_answer", methods=["POST"])
def get_answer():
try:
data = request.get_json()
query = data.get("query")
embedding_model = data.get("embedding_model")
app_type = data.get("app_type")
if embedding_model == "open_ai":
os.chdir(DB_DIRECTORY_OPEN_AI)
api_key = APIKey.query.first().key
os.environ["OPENAI_API_KEY"] = api_key
if app_type == "app":
chat_bot = App()
response = chat_bot.chat(query)
return make_response(jsonify({"response": response}), 200)
except Exception as e:
return make_response(jsonify({"error": str(e)}), 400)
@@ -0,0 +1,72 @@
from flask import Blueprint, jsonify, make_response, request
from models import APIKey, BotList, db
dashboard_bp = Blueprint("dashboard", __name__)
# Set Open AI Key
@dashboard_bp.route("/api/set_key", methods=["POST"])
def set_key():
data = request.get_json()
api_key = data["openAIKey"]
existing_key = APIKey.query.first()
if existing_key:
existing_key.key = api_key
else:
new_key = APIKey(key=api_key)
db.session.add(new_key)
db.session.commit()
return make_response(jsonify(message="API key saved successfully"), 200)
# Check OpenAI Key
@dashboard_bp.route("/api/check_key", methods=["GET"])
def check_key():
existing_key = APIKey.query.first()
if existing_key:
return make_response(jsonify(status="ok", message="OpenAI Key exists"), 200)
else:
return make_response(jsonify(status="fail", message="No OpenAI Key present"), 200)
# Create a bot
@dashboard_bp.route("/api/create_bot", methods=["POST"])
def create_bot():
data = request.get_json()
name = data["name"]
slug = name.lower().replace(" ", "_")
existing_bot = BotList.query.filter_by(slug=slug).first()
if existing_bot:
return (make_response(jsonify(message="Bot already exists"), 400),)
new_bot = BotList(name=name, slug=slug)
db.session.add(new_bot)
db.session.commit()
return make_response(jsonify(message="Bot created successfully"), 200)
# Delete a bot
@dashboard_bp.route("/api/delete_bot", methods=["POST"])
def delete_bot():
data = request.get_json()
slug = data.get("slug")
bot = BotList.query.filter_by(slug=slug).first()
if bot:
db.session.delete(bot)
db.session.commit()
return make_response(jsonify(message="Bot deleted successfully"), 200)
return make_response(jsonify(message="Bot not found"), 400)
# Get the list of bots
@dashboard_bp.route("/api/get_bots", methods=["GET"])
def get_bots():
bots = BotList.query.all()
bot_list = []
for bot in bots:
bot_list.append(
{
"name": bot.name,
"slug": bot.slug,
}
)
return jsonify(bot_list)
@@ -0,0 +1,27 @@
import os
from flask import Blueprint, jsonify, make_response, request
from models import APIKey
from paths import DB_DIRECTORY_OPEN_AI
from embedchain import App
sources_bp = Blueprint("sources", __name__)
# API route to add data sources
@sources_bp.route("/api/add_sources", methods=["POST"])
def add_sources():
try:
embedding_model = request.json.get("embedding_model")
name = request.json.get("name")
value = request.json.get("value")
if embedding_model == "open_ai":
os.chdir(DB_DIRECTORY_OPEN_AI)
api_key = APIKey.query.first().key
os.environ["OPENAI_API_KEY"] = api_key
chat_bot = App()
chat_bot.add(name, value)
return make_response(jsonify(message="Sources added successfully"), 200)
except Exception as e:
return make_response(jsonify(message=f"Error adding sources: {str(e)}"), 400)
@@ -0,0 +1,27 @@
import os
from flask import Flask
from models import db
from paths import DB_DIRECTORY_OPEN_AI, ROOT_DIRECTORY
from routes.chat_response import chat_response_bp
from routes.dashboard import dashboard_bp
from routes.sources import sources_bp
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + os.path.join(ROOT_DIRECTORY, "database", "user_data.db")
app.register_blueprint(dashboard_bp)
app.register_blueprint(sources_bp)
app.register_blueprint(chat_response_bp)
# Initialize the app on startup
def load_app():
os.makedirs(DB_DIRECTORY_OPEN_AI, exist_ok=True)
db.init_app(app)
with app.app_context():
db.create_all()
if __name__ == "__main__":
load_app()
app.run(host="0.0.0.0", debug=True, port=8000)
@@ -0,0 +1,24 @@
version: "3.9"
services:
backend:
container_name: embedchain-backend
restart: unless-stopped
build:
context: backend
dockerfile: Dockerfile
image: embedchain/backend
ports:
- "8000:8000"
frontend:
container_name: embedchain-frontend
restart: unless-stopped
build:
context: frontend
dockerfile: Dockerfile
image: embedchain/frontend
ports:
- "3000:3000"
depends_on:
- "backend"
@@ -0,0 +1,7 @@
node_modules/
build
dist
.env
.git
.next/
trash_files/
@@ -0,0 +1,3 @@
{
"extends": ["next/babel", "next/core-web-vitals"]
}
@@ -0,0 +1,38 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
vscode/
trash_files/
@@ -0,0 +1,14 @@
FROM node:18-slim AS frontend
WORKDIR /usr/src/app/frontend
COPY package.json .
COPY package-lock.json .
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}
@@ -0,0 +1,26 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: "/api/:path*",
destination: "http://backend:8000/api/:path*",
},
];
},
reactStrictMode: true,
experimental: {
proxyTimeout: 6000000,
},
webpack(config) {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ["@svgr/webpack"],
});
return config;
},
};
module.exports = nextConfig;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,25 @@
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"autoprefixer": "^10.4.14",
"eslint": "8.44.0",
"eslint-config-next": "13.4.9",
"flowbite": "^1.7.0",
"next": "13.4.9",
"postcss": "8.4.25",
"react": "18.2.0",
"react-dom": "18.2.0",
"tailwindcss": "3.3.2"
},
"devDependencies": {
"@svgr/webpack": "^8.0.1"
}
}
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,20 @@
<svg
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M14 2C14 2.74028 13.5978 3.38663 13 3.73244V4H20C21.6569 4 23 5.34315 23 7V19C23 20.6569 21.6569 22 20 22H4C2.34315 22 1 20.6569 1 19V7C1 5.34315 2.34315 4 4 4H11V3.73244C10.4022 3.38663 10 2.74028 10 2C10 0.895431 10.8954 0 12 0C13.1046 0 14 0.895431 14 2ZM4 6H11H13H20C20.5523 6 21 6.44772 21 7V19C21 19.5523 20.5523 20 20 20H4C3.44772 20 3 19.5523 3 19V7C3 6.44772 3.44772 6 4 6ZM15 11.5C15 10.6716 15.6716 10 16.5 10C17.3284 10 18 10.6716 18 11.5C18 12.3284 17.3284 13 16.5 13C15.6716 13 15 12.3284 15 11.5ZM16.5 8C14.567 8 13 9.567 13 11.5C13 13.433 14.567 15 16.5 15C18.433 15 20 13.433 20 11.5C20 9.567 18.433 8 16.5 8ZM7.5 10C6.67157 10 6 10.6716 6 11.5C6 12.3284 6.67157 13 7.5 13C8.32843 13 9 12.3284 9 11.5C9 10.6716 8.32843 10 7.5 10ZM4 11.5C4 9.567 5.567 8 7.5 8C9.433 8 11 9.567 11 11.5C11 13.433 9.433 15 7.5 15C5.567 15 4 13.433 4 11.5ZM10.8944 16.5528C10.6474 16.0588 10.0468 15.8586 9.55279 16.1056C9.05881 16.3526 8.85858 16.9532 9.10557 17.4472C9.68052 18.5971 10.9822 19 12 19C13.0178 19 14.3195 18.5971 14.8944 17.4472C15.1414 16.9532 14.9412 16.3526 14.4472 16.1056C13.9532 15.8586 13.3526 16.0588 13.1056 16.5528C13.0139 16.7362 12.6488 17 12 17C11.3512 17 10.9861 16.7362 10.8944 16.5528Z"
fill="currentColor"
></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,14 @@
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 14 14"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"
/>
</svg>

After

Width:  |  Height:  |  Size: 252 B

@@ -0,0 +1,15 @@
<svg
fill="currentColor"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<path d="M18.8,16l5.5-5.5c0.8-0.8,0.8-2,0-2.8l0,0C24,7.3,23.5,7,23,7c-0.5,0-1,0.2-1.4,0.6L16,13.2l-5.5-5.5 c-0.8-0.8-2.1-0.8-2.8,0C7.3,8,7,8.5,7,9.1s0.2,1,0.6,1.4l5.5,5.5l-5.5,5.5C7.3,21.9,7,22.4,7,23c0,0.5,0.2,1,0.6,1.4 C8,24.8,8.5,25,9,25c0.5,0,1-0.2,1.4-0.6l5.5-5.5l5.5,5.5c0.8,0.8,2.1,0.8,2.8,0c0.8-0.8,0.8-2.1,0-2.8L18.8,16z"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 625 B

@@ -0,0 +1,9 @@
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 22 21"
>
<path d="M16.975 11H10V4.025a1 1 0 0 0-1.066-.998 8.5 8.5 0 1 0 9.039 9.039.999.999 0 0 0-1-1.066h.002Z" />
<path d="M12.5 0c-.157 0-.311.01-.565.027A1 1 0 0 0 11 1.02V10h8.975a1 1 0 0 0 1-.935c.013-.188.028-.374.028-.565A8.51 8.51 0 0 0 12.5 0Z" />
</svg>

After

Width:  |  Height:  |  Size: 369 B

@@ -0,0 +1,15 @@
<svg
fill="currentColor"
viewBox="0 0 56 56"
xmlns="http://www.w3.org/2000/svg"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<path d="M 15.5547 53.125 L 40.4453 53.125 C 45.2969 53.125 47.7109 50.6640 47.7109 45.7890 L 47.7109 24.5078 L 30.7422 24.5078 C 27.7422 24.5078 26.3359 23.0781 26.3359 20.0781 L 26.3359 2.8750 L 15.5547 2.8750 C 10.7266 2.8750 8.2891 5.3594 8.2891 10.2344 L 8.2891 45.7890 C 8.2891 50.6875 10.7266 53.125 15.5547 53.125 Z M 30.8125 21.2969 L 47.4531 21.2969 C 47.2891 20.3359 46.6094 19.3984 45.5078 18.2500 L 32.5703 5.1015 C 31.4922 3.9766 30.5078 3.2969 29.5234 3.1328 L 29.5234 20.0313 C 29.5234 20.875 29.9687 21.2969 30.8125 21.2969 Z M 18.9766 34.6562 C 18.0156 34.6562 17.3359 33.9766 17.3359 33.0625 C 17.3359 32.1484 18.0156 31.4687 18.9766 31.4687 L 37.0469 31.4687 C 37.9844 31.4687 38.7109 32.1484 38.7109 33.0625 C 38.7109 33.9766 37.9844 34.6562 37.0469 34.6562 Z M 18.9766 43.5859 C 18.0156 43.5859 17.3359 42.9062 17.3359 41.9922 C 17.3359 41.0781 18.0156 40.3984 18.9766 40.3984 L 37.0469 40.3984 C 37.9844 40.3984 38.7109 41.0781 38.7109 41.9922 C 38.7109 42.9062 37.9844 43.5859 37.0469 43.5859 Z"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,12 @@
<svg
aria-hidden="true"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
fill-rule="evenodd"
d="M2 4.75A.75.75 0 012.75 4h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 4.75zm0 10.5a.75.75 0 01.75-.75h7.5a.75.75 0 010 1.5h-7.5a.75.75 0 01-.75-.75zM2 10a.75.75 0 01.75-.75h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 10z"
></path>
</svg>

After

Width:  |  Height:  |  Size: 415 B

@@ -0,0 +1,14 @@
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 10 6"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m1 1 4 4 4-4"
/>
</svg>

After

Width:  |  Height:  |  Size: 230 B

@@ -0,0 +1,14 @@
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 10 6"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5 5 1 1 5"
/>
</svg>

After

Width:  |  Height:  |  Size: 254 B

@@ -0,0 +1,39 @@
<svg
viewBox="0 0 20 20"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
fill="currentColor"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<title>github [#142]</title> <desc>Created with Sketch.</desc>
<defs> </defs>
<g
id="Page-1"
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd"
>
<g
id="Dribbble-Light-Preview"
transform="translate(-140.000000, -7559.000000)"
fill="currentColor"
>
<g id="icons" transform="translate(56.000000, 160.000000)">
<path
d="M94,7399 C99.523,7399 104,7403.59 104,7409.253 C104,7413.782 101.138,7417.624 97.167,7418.981 C96.66,7419.082 96.48,7418.762 96.48,7418.489 C96.48,7418.151 96.492,7417.047 96.492,7415.675 C96.492,7414.719 96.172,7414.095 95.813,7413.777 C98.04,7413.523 100.38,7412.656 100.38,7408.718 C100.38,7407.598 99.992,7406.684 99.35,7405.966 C99.454,7405.707 99.797,7404.664 99.252,7403.252 C99.252,7403.252 98.414,7402.977 96.505,7404.303 C95.706,7404.076 94.85,7403.962 94,7403.958 C93.15,7403.962 92.295,7404.076 91.497,7404.303 C89.586,7402.977 88.746,7403.252 88.746,7403.252 C88.203,7404.664 88.546,7405.707 88.649,7405.966 C88.01,7406.684 87.619,7407.598 87.619,7408.718 C87.619,7412.646 89.954,7413.526 92.175,7413.785 C91.889,7414.041 91.63,7414.493 91.54,7415.156 C90.97,7415.418 89.522,7415.871 88.63,7414.304 C88.63,7414.304 88.101,7413.319 87.097,7413.247 C87.097,7413.247 86.122,7413.234 87.029,7413.87 C87.029,7413.87 87.684,7414.185 88.139,7415.37 C88.139,7415.37 88.726,7417.2 91.508,7416.58 C91.513,7417.437 91.522,7418.245 91.522,7418.489 C91.522,7418.76 91.338,7419.077 90.839,7418.982 C86.865,7417.627 84,7413.783 84,7409.253 C84,7403.59 88.478,7399 94,7399"
id="github-[#142]"
>
</path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -0,0 +1,17 @@
<svg
fill="currentColor"
viewBox="0 0 32 32"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<title>linkedin</title>
<path d="M28.778 1.004h-25.56c-0.008-0-0.017-0-0.027-0-1.199 0-2.172 0.964-2.186 2.159v25.672c0.014 1.196 0.987 2.161 2.186 2.161 0.010 0 0.019-0 0.029-0h25.555c0.008 0 0.018 0 0.028 0 1.2 0 2.175-0.963 2.194-2.159l0-0.002v-25.67c-0.019-1.197-0.994-2.161-2.195-2.161-0.010 0-0.019 0-0.029 0h0.001zM9.9 26.562h-4.454v-14.311h4.454zM7.674 10.293c-1.425 0-2.579-1.155-2.579-2.579s1.155-2.579 2.579-2.579c1.424 0 2.579 1.154 2.579 2.578v0c0 0.001 0 0.002 0 0.004 0 1.423-1.154 2.577-2.577 2.577-0.001 0-0.002 0-0.003 0h0zM26.556 26.562h-4.441v-6.959c0-1.66-0.034-3.795-2.314-3.795-2.316 0-2.669 1.806-2.669 3.673v7.082h-4.441v-14.311h4.266v1.951h0.058c0.828-1.395 2.326-2.315 4.039-2.315 0.061 0 0.121 0.001 0.181 0.003l-0.009-0c4.5 0 5.332 2.962 5.332 6.817v7.855z"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,28 @@
<svg
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<path
d="M3.5 8H3V7H3.5C3.77614 7 4 7.22386 4 7.5C4 7.77614 3.77614 8 3.5 8Z"
fill="currentColor"
></path>
<path
d="M7 10V7H7.5C7.77614 7 8 7.22386 8 7.5V9.5C8 9.77614 7.77614 10 7.5 10H7Z"
fill="currentColor"
></path>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M1 1.5C1 0.671573 1.67157 0 2.5 0H10.7071L14 3.29289V13.5C14 14.3284 13.3284 15 12.5 15H2.5C1.67157 15 1 14.3284 1 13.5V1.5ZM3.5 6H2V11H3V9H3.5C4.32843 9 5 8.32843 5 7.5C5 6.67157 4.32843 6 3.5 6ZM7.5 6H6V11H7.5C8.32843 11 9 10.3284 9 9.5V7.5C9 6.67157 8.32843 6 7.5 6ZM10 11V6H13V7H11V8H12V9H11V11H10Z"
fill="currentColor"
></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 947 B

@@ -0,0 +1,13 @@
<svg
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M12 6v6m0 0v6m0-6h6m-6 0H6"
/>
</svg>

After

Width:  |  Height:  |  Size: 227 B

@@ -0,0 +1,57 @@
<svg
viewBox="-0.5 0 25 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
{" "}
<path
d="M12 7.82001H22"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
></path>{" "}
<path
d="M2 7.82001H4"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
></path>{" "}
<path
d="M20 16.82H22"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
></path>{" "}
<path
d="M2 16.82H12"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
></path>{" "}
<path
d="M8 11.82C10.2091 11.82 12 10.0291 12 7.82001C12 5.61087 10.2091 3.82001 8 3.82001C5.79086 3.82001 4 5.61087 4 7.82001C4 10.0291 5.79086 11.82 8 11.82Z"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
></path>{" "}
<path
d="M16 20.82C18.2091 20.82 20 19.0291 20 16.82C20 14.6109 18.2091 12.82 16 12.82C13.7909 12.82 12 14.6109 12 16.82C12 19.0291 13.7909 20.82 16 20.82Z"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
></path>{" "}
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,61 @@
<svg
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<rect
height="4"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
width="4"
x="10"
y="4"
></rect>
<rect
height="4"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
width="4"
x="10"
y="16"
></rect>
<rect
height="4"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
width="4"
x="3"
y="16"
></rect>
<rect
height="4"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
width="4"
x="17"
y="16"
></rect>
<path
d="M12 8V12M12 16V12M12 12H17C18.1046 12 19 12.8954 19 14V16M12 12H7C5.89543 12 5 12.8954 5 14V16"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,21 @@
<svg
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<path
d="M12 3V21M9 21H15M19 6V3H5V6"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 445 B

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="svg5" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1668.56 1221.19"
style="enable-background:new 0 0 1668.56 1221.19;" xml:space="preserve">
<g id="layer1" transform="translate(52.390088,-25.058597)">
<path id="path1009" d="M283.94,167.31l386.39,516.64L281.5,1104h87.51l340.42-367.76L984.48,1104h297.8L874.15,558.3l361.92-390.99
h-87.51l-313.51,338.7l-253.31-338.7H283.94z M412.63,231.77h136.81l604.13,807.76h-136.81L412.63,231.77z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 722 B

@@ -0,0 +1,20 @@
<svg
fill="currentColor"
version="1.1"
id="Layer_1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 24 24"
enable-background="new 0 0 24 24"
xml:space="preserve"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<path d="M18.41,0.01H4V9h2V2.01h10v6h6v14H4v2h20V5.6L18.41,0.01z M18,2.43l3.59,3.59H18V2.43z M21,18v2h-1h-1h-1v-8h2v6H21z M7,12 H6v2h1v6h2v-6h1v-2H9H7z M15,12l-1,1.61L13,12v0h-2v8h2v-4.21l1,1.61l1-1.61V20h2v-8L15,12L15,12z M3,15H2v-3H0v8h2v-3h1v3h2v-8H3 V15z"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 689 B

@@ -0,0 +1,39 @@
<svg
viewBox="0 -3 20 20"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
fill="currentColor"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g>
<g id="SVGRepo_iconCarrier">
<title>youtube [#168]</title> <desc>Created with Sketch.</desc>
<defs> </defs>
<g
id="Page-1"
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd"
>
<g
id="Dribbble-Light-Preview"
transform="translate(-300.000000, -7442.000000)"
fill="currentColor"
>
<g id="icons" transform="translate(56.000000, 160.000000)">
<path
d="M251.988432,7291.58588 L251.988432,7285.97425 C253.980638,7286.91168 255.523602,7287.8172 257.348463,7288.79353 C255.843351,7289.62824 253.980638,7290.56468 251.988432,7291.58588 M263.090998,7283.18289 C262.747343,7282.73013 262.161634,7282.37809 261.538073,7282.26141 C259.705243,7281.91336 248.270974,7281.91237 246.439141,7282.26141 C245.939097,7282.35515 245.493839,7282.58153 245.111335,7282.93357 C243.49964,7284.42947 244.004664,7292.45151 244.393145,7293.75096 C244.556505,7294.31342 244.767679,7294.71931 245.033639,7294.98558 C245.376298,7295.33761 245.845463,7295.57995 246.384355,7295.68865 C247.893451,7296.0008 255.668037,7296.17532 261.506198,7295.73552 C262.044094,7295.64178 262.520231,7295.39147 262.895762,7295.02447 C264.385932,7293.53455 264.28433,7285.06174 263.090998,7283.18289"
id="youtube-[#168]"
>
</path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

@@ -0,0 +1,9 @@
export default function PageWrapper({ children }) {
return (
<>
<div className="flex pt-4 px-4 sm:ml-64 min-h-screen">
<div className="flex-grow pt-4 px-4 rounded-lg">{children}</div>
</div>
</>
);
}
@@ -0,0 +1,16 @@
export default function BotWrapper({ children }) {
return (
<>
<div className="rounded-lg">
<div className="flex flex-row items-center">
<div className="flex items-center justify-center h-10 w-10 rounded-full bg-black text-white flex-shrink-0">
B
</div>
<div className="ml-3 text-sm bg-white py-2 px-4 shadow-lg rounded-xl">
<div>{children}</div>
</div>
</div>
</div>
</>
);
}
@@ -0,0 +1,16 @@
export default function HumanWrapper({ children }) {
return (
<>
<div className="rounded-lg">
<div className="flex items-center justify-start flex-row-reverse">
<div className="flex items-center justify-center h-10 w-10 rounded-full bg-blue-800 text-white flex-shrink-0">
H
</div>
<div className="mr-3 text-sm bg-blue-200 py-2 px-4 shadow-lg rounded-xl">
<div>{children}</div>
</div>
</div>
</div>
</>
);
}
@@ -0,0 +1,73 @@
import { useState } from "react";
import { useRouter } from "next/router";
export default function CreateBot() {
const [botName, setBotName] = useState("");
const [status, setStatus] = useState("");
const router = useRouter();
const handleCreateBot = async (e) => {
e.preventDefault();
const data = {
name: botName,
};
const response = await fetch("/api/create_bot", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
if (response.ok) {
const botSlug = botName.toLowerCase().replace(/\s+/g, "_");
router.push(`/${botSlug}/app`);
} else {
setBotName("");
setStatus("fail");
setTimeout(() => {
setStatus("");
}, 3000);
}
};
return (
<>
<div className="w-full">
{/* Create Bot */}
<h2 className="text-xl font-bold text-gray-800">CREATE BOT</h2>
<form className="py-2" onSubmit={handleCreateBot}>
<label
htmlFor="bot_name"
className="block mb-2 text-sm font-medium text-gray-900"
>
Name of Bot
</label>
<div className="flex flex-col sm:flex-row gap-x-4 gap-y-4">
<input
type="text"
id="bot_name"
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="Eg. Naval Ravikant"
required
value={botName}
onChange={(e) => setBotName(e.target.value)}
/>
<button
type="submit"
className="h-fit text-white bg-black hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center"
>
Submit
</button>
</div>
{status === "fail" && (
<div className="text-red-600 text-sm font-bold py-1">
An error occurred while creating your bot!
</div>
)}
</form>
</div>
</>
);
}
@@ -0,0 +1,71 @@
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
export default function DeleteBot() {
const [bots, setBots] = useState([]);
const router = useRouter();
useEffect(() => {
const fetchBots = async () => {
const response = await fetch("/api/get_bots");
const data = await response.json();
setBots(data);
};
fetchBots();
}, []);
const handleDeleteBot = async (event) => {
event.preventDefault();
const selectedBotSlug = event.target.bot_name.value;
if (selectedBotSlug === "none") {
return;
}
const response = await fetch("/api/delete_bot", {
method: "POST",
body: JSON.stringify({ slug: selectedBotSlug }),
headers: {
"Content-Type": "application/json",
},
});
if (response.ok) {
router.reload();
}
};
return (
<>
{bots.length !== 0 && (
<div className="w-full">
{/* Delete Bot */}
<h2 className="text-xl font-bold text-gray-800">DELETE BOTS</h2>
<form className="py-2" onSubmit={handleDeleteBot}>
<label className="block mb-2 text-sm font-medium text-gray-900">
List of Bots
</label>
<div className="flex flex-col sm:flex-row gap-x-4 gap-y-4">
<select
name="bot_name"
defaultValue="none"
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
>
<option value="none">Select a Bot</option>
{bots.map((bot) => (
<option key={bot.slug} value={bot.slug}>
{bot.name}
</option>
))}
</select>
<button
type="submit"
className="h-fit text-white bg-red-600 hover:bg-red-600/90 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center"
>
Delete
</button>
</div>
</form>
</div>
)}
</>
);
}

Some files were not shown because too many files have changed in this diff Show More