diff --git a/.claude/rules/module-docstring.md b/.claude/rules/module-docstring.md index 0d842910..ec9cf257 100644 --- a/.claude/rules/module-docstring.md +++ b/.claude/rules/module-docstring.md @@ -22,7 +22,7 @@ A good module docstring states: Example (abbreviated, from `memory/search/manager.py`): ```python -"""SearchManager — top-level orchestrator for POST /api/v1/memory/search. +"""SearchManager — top-level orchestrator for POST /api/v2/memory/search. Hard partition by owner_type: user → episodes (+ profiles), agent → agent_cases + agent_skills. The manager never writes to storage; it only diff --git a/CHANGELOG.md b/CHANGELOG.md index 546f1109..b121e070 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `metadata = {"method": ..., "calibrated": ...}` now, a structured field that can be split on, alongside the existing human-readable comment. Dashboards built on `recall_top_score` for keyword search need to switch to the new name. +- **Docs and examples now use `/api/v2`** — README, QUICKSTART, the `docs/` + reference set, the Langfuse example, and `everos demo --live` all call the + canonical `/api/v2` prefix instead of `/api/v1`. `/api/v1` keeps resolving + to the same handlers, so nothing breaks; it is now described as a **legacy + compatibility alias that may be removed in a future major release** rather + than a permanent one. New integrations should target `/api/v2`. + +### Fixed + +- **Broken table-of-contents links in `docs/api.md`** — the endpoint anchors + still pointed at the pre-1.2.0 `#post-apiv1…` slugs after the headings moved + to `/api/v2`, so all five endpoint links in the TOC were dead. ## [1.2.0] - 2026-07-24 @@ -26,8 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **`/api/v2` API prefix** — every business endpoint (`memory/*`, `ome/*`, `knowledge/*`) is now served under `/api/v2`, aligning the open-source API - with the EverOS Cloud contract. `/api/v1` is retained as a permanent, - backward-compatible alias: both prefixes resolve to the same handlers with + with the EverOS Cloud contract. `/api/v1` is retained as a legacy + compatibility alias: both prefixes resolve to the same handlers with identical request/response contracts, so existing integrations keep working unchanged. Infrastructure endpoints (`/health`, `/metrics`) stay unversioned. - **Native OpenTelemetry tracing** — memory operations (add / flush, memcell diff --git a/QUICKSTART.md b/QUICKSTART.md index 5d5f8ab7..9afe5470 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -123,11 +123,17 @@ Send messages to the server — one at a time or in batches. Each batch belongs to a `session_id`, which represents one conversation thread. Timestamps are Unix epoch in **milliseconds** (UTC). +> [!NOTE] +> Business endpoints live under `/api/v2`. The older `/api/v1` prefix still +> resolves to the same handlers so existing integrations keep working, but it +> is a legacy alias that may be removed in a future major release — write new +> code against `/api/v2`. + First, a chat about climbing: ```bash TS=$(($(date +%s)*1000)) -curl -X POST http://127.0.0.1:8000/api/v1/memory/add \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/add \ -H 'Content-Type: application/json' \ -d "{ \"session_id\": \"demo-001\", @@ -143,7 +149,7 @@ curl -X POST http://127.0.0.1:8000/api/v1/memory/add \ Now the topic shifts to work: ```bash -curl -X POST http://127.0.0.1:8000/api/v1/memory/add \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/add \ -H 'Content-Type: application/json' \ -d "{ \"session_id\": \"demo-001\", @@ -184,7 +190,7 @@ If you want to extract memory without waiting for a topic shift — for example at the end of a session — call `/flush`: ```bash -curl -X POST http://127.0.0.1:8000/api/v1/memory/flush \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/flush \ -H 'Content-Type: application/json' \ -d '{"session_id":"demo-001"}' ``` @@ -202,7 +208,7 @@ This forces extraction of whatever is still in the buffer. ## 6. Search ```bash -curl -X POST http://127.0.0.1:8000/api/v1/memory/search \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/search \ -H 'Content-Type: application/json' \ -d '{ "user_id": "alice", @@ -277,7 +283,7 @@ edit — no database driver needed. requests to partition memory spaces inside one server (defaults to `"default"` when omitted). - **Knowledge base** — upload documents via - `/api/v1/knowledge/documents` and search with hybrid retrieval. See + `/api/v2/knowledge/documents` and search with hybrid retrieval. See [docs/knowledge.md](docs/knowledge.md). - **Reflection** — offline memory consolidation; enable in `ome.toml`. See [docs/reflection.md](docs/reflection.md). diff --git a/README.md b/README.md index 385d81d0..388a9f22 100644 --- a/README.md +++ b/README.md @@ -195,18 +195,24 @@ everos demo --live ``` Live demo mode connects to the running server and performs the real -`/health` -> `/api/v1/memory/add` -> `/api/v1/memory/flush` -> -`/api/v1/memory/search` flow before opening the same memory sphere UI. Use +`/health` -> `/api/v2/memory/add` -> `/api/v2/memory/flush` -> +`/api/v2/memory/search` flow before opening the same memory sphere UI. Use `--server-url ` if your server is not on `http://127.0.0.1:8000`. ### 5. Try Your First Memory +> [!NOTE] +> Business endpoints live under `/api/v2`. The older `/api/v1` prefix still +> resolves to the same handlers so existing integrations keep working, but it +> is a legacy alias that may be removed in a future major release — write new +> code against `/api/v2`. + Add a tiny conversation: ```bash TS=$(($(date +%s)*1000)) -curl -X POST http://127.0.0.1:8000/api/v1/memory/add \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/add \ -H 'Content-Type: application/json' \ -d "{ \"session_id\": \"demo-001\", @@ -222,7 +228,7 @@ curl -X POST http://127.0.0.1:8000/api/v1/memory/add \ Force extraction for the local demo: ```bash -curl -X POST http://127.0.0.1:8000/api/v1/memory/flush \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/flush \ -H 'Content-Type: application/json' \ -d '{"session_id":"demo-001","app_id":"default","project_id":"default"}' ``` @@ -230,7 +236,7 @@ curl -X POST http://127.0.0.1:8000/api/v1/memory/flush \ Search it back: ```bash -curl -X POST http://127.0.0.1:8000/api/v1/memory/search \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/search \ -H 'Content-Type: application/json' \ -d '{ "user_id": "alice", @@ -258,7 +264,7 @@ For annotated responses and the Markdown files EverOS creates, see ### Optional: Ingest Multimodal Files To ingest non-text content (image / pdf / audio / office documents) -through `/api/v1/memory/add` `content` items, install the optional +through `/api/v2/memory/add` `content` items, install the optional extra: ```bash diff --git a/README.zh-CN.md b/README.zh-CN.md index c6f02bc3..2a15467e 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -212,18 +212,23 @@ everos demo --live ``` Live demo mode 会连接正在运行的 server,并在打开同一个 memory sphere UI -之前真实执行 `/health` -> `/api/v1/memory/add` -> `/api/v1/memory/flush` -> -`/api/v1/memory/search`。如果 server 不在 `http://127.0.0.1:8000`,可以使用 +之前真实执行 `/health` -> `/api/v2/memory/add` -> `/api/v2/memory/flush` -> +`/api/v2/memory/search`。如果 server 不在 `http://127.0.0.1:8000`,可以使用 `--server-url `。 ### 5. 试写第一条记忆 +> [!NOTE] +> 业务接口位于 `/api/v2`。旧的 `/api/v1` 前缀仍然指向同一批 handler,已有集成 +> 不会受影响;但它只是兼容用的 legacy alias,未来的大版本可能移除 —— 新代码请 +> 直接使用 `/api/v2`。 + 添加一个很小的 conversation: ```bash TS=$(($(date +%s)*1000)) -curl -X POST http://127.0.0.1:8000/api/v1/memory/add \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/add \ -H 'Content-Type: application/json' \ -d "{ \"session_id\": \"demo-001\", @@ -239,7 +244,7 @@ curl -X POST http://127.0.0.1:8000/api/v1/memory/add \ 为了本地 demo,手动触发一次 extraction: ```bash -curl -X POST http://127.0.0.1:8000/api/v1/memory/flush \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/flush \ -H 'Content-Type: application/json' \ -d '{"session_id":"demo-001","app_id":"default","project_id":"default"}' ``` @@ -247,7 +252,7 @@ curl -X POST http://127.0.0.1:8000/api/v1/memory/flush \ 再把这条记忆搜索回来: ```bash -curl -X POST http://127.0.0.1:8000/api/v1/memory/search \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/search \ -H 'Content-Type: application/json' \ -d '{ "user_id": "alice", @@ -271,7 +276,7 @@ Markdown 会同步写入,本地索引会在后台追上。 ### 可选:摄取多模态文件 -如果要通过 `/api/v1/memory/add` 的 `content` items 摄取非文本内容 +如果要通过 `/api/v2/memory/add` 的 `content` items 摄取非文本内容 (image / pdf / audio / office documents),安装可选 extra: ```bash diff --git a/docs/api.md b/docs/api.md index aea91d01..2d7c2548 100644 --- a/docs/api.md +++ b/docs/api.md @@ -26,11 +26,11 @@ business semantics the raw spec does not carry. - [SearchMethod](#searchmethod) - [GetMemoryType](#getmemorytype) - [Endpoints](#endpoints) - - [POST /api/v2/memory/add](#post-apiv1memoryadd) - - [POST /api/v2/memory/flush](#post-apiv1memoryflush) - - [POST /api/v2/memory/search](#post-apiv1memorysearch) - - [POST /api/v2/memory/get](#post-apiv1memoryget) - - [POST /api/v2/ome/trigger](#post-apiv1ometrigger) + - [POST /api/v2/memory/add](#post-apiv2memoryadd) + - [POST /api/v2/memory/flush](#post-apiv2memoryflush) + - [POST /api/v2/memory/search](#post-apiv2memorysearch) + - [POST /api/v2/memory/get](#post-apiv2memoryget) + - [POST /api/v2/ome/trigger](#post-apiv2ometrigger) - [Knowledge endpoints](#knowledge-endpoints) - [OpenAPI spec source](#openapi-spec-source) @@ -52,11 +52,13 @@ but are intentionally outside this reference — they are runtime probes for deployment, not part of the application contract. `/api/v2` is the canonical prefix, aligned with the EverOS Cloud API. Every -business endpoint is **also** served under `/api/v1`, which is retained as a -permanent, backward-compatible alias: the two prefixes resolve to the same -handlers with identical request/response contracts. Existing `/api/v1` -integrations keep working unchanged; new integrations should use `/api/v2`. -Swap the prefix in any example below to reach the same endpoint under v1. +business endpoint is **also** served under `/api/v1`, kept as a legacy +compatibility alias: the two prefixes resolve to the same handlers with +identical request/response contracts, so existing `/api/v1` integrations keep +working today. The alias carries no long-term guarantee — it may be removed in +a future major release, and it will be announced in the changelog with a +deprecation window before that happens. Write new integrations against +`/api/v2`, and migrate existing ones when convenient. ### Content type diff --git a/docs/everos-demo.md b/docs/everos-demo.md index 53b3c209..ab55ebbc 100644 --- a/docs/everos-demo.md +++ b/docs/everos-demo.md @@ -38,9 +38,9 @@ Live mode keeps the same TUI, but the memory lifecycle is backed by real server calls: 1. `GET /health` -2. `POST /api/v1/memory/add` -3. `POST /api/v1/memory/flush` -4. `POST /api/v1/memory/search` +2. `POST /api/v2/memory/add` +3. `POST /api/v2/memory/flush` +4. `POST /api/v2/memory/search` If your server is not running on `http://127.0.0.1:8000`, pass `--server-url `. diff --git a/docs/how-memory-works.md b/docs/how-memory-works.md index 1a813647..679b4815 100644 --- a/docs/how-memory-works.md +++ b/docs/how-memory-works.md @@ -302,7 +302,7 @@ The CLI ([cli.md](cli.md)) is intentionally small: `rm -rf /.index/lancedb`, restart — the cascade rebuilds from markdown. For an incremental catch-up, use `everos cascade sync`. - - **Flush** is an HTTP endpoint (`POST /api/v1/memory/flush`), not a + - **Flush** is an HTTP endpoint (`POST /api/v2/memory/flush`), not a CLI command — it forces *extraction* of the session buffer, which is a different thing from forcing *index sync* (`cascade sync`). diff --git a/docs/knowledge.md b/docs/knowledge.md index c2aa8169..d3ad92dd 100644 --- a/docs/knowledge.md +++ b/docs/knowledge.md @@ -13,14 +13,14 @@ and keeps the original file for reference. ```bash # Upload a document -curl -s -X POST http://localhost:8000/api/v1/knowledge/documents \ +curl -s -X POST http://localhost:8000/api/v2/knowledge/documents \ -F "file=@my-report.pdf" \ -F "title=Q1 Engineering Report" \ | jq .data # → { "doc_id": "d_a1b2c3d4e5f6", "category_id": "Technology", "topic_count": 8, ... } # Search -curl -s -X POST http://localhost:8000/api/v1/knowledge/search \ +curl -s -X POST http://localhost:8000/api/v2/knowledge/search \ -H "Content-Type: application/json" \ -d '{"query": "performance bottleneck", "method": "hybrid"}' \ | jq '.data.hits[:3] | .[] | {topic_name, score}' @@ -206,7 +206,7 @@ request to bypass LLM classification. ## API reference -All endpoints are under `/api/v1/knowledge`. Responses use the envelope +All endpoints are under `/api/v2/knowledge`. Responses use the envelope format `{"request_id": "...", "data": {...}}`. The `request_id` field is omitted from examples below for brevity. @@ -256,7 +256,7 @@ async def upload_document(file_path: str, title: str) -> dict: async with httpx.AsyncClient(base_url="http://localhost:8000") as client: with open(file_path, "rb") as f: resp = await client.post( - "/api/v1/knowledge/documents", + "/api/v2/knowledge/documents", files={"file": (Path(file_path).name, f)}, data={"title": title}, ) @@ -267,7 +267,7 @@ async def upload_document(file_path: str, title: str) -> dict: **Example — curl**: ```bash -curl -X POST http://localhost:8000/api/v1/knowledge/documents \ +curl -X POST http://localhost:8000/api/v2/knowledge/documents \ -F "file=@report.pdf" \ -F "title=Quarterly Report" \ -F "category_id=Finance" @@ -605,7 +605,7 @@ Storage paths, SQLite rows, and LanceDB indexes are all scoped by A complete workflow from upload to search: ```bash -BASE=http://localhost:8000/api/v1/knowledge +BASE=http://localhost:8000/api/v2/knowledge # 1. List available categories curl -s "$BASE/categories" | jq '[.data.categories[] | .category_id]' diff --git a/docs/multimodal.md b/docs/multimodal.md index 0dc9e4ce..eeb18181 100644 --- a/docs/multimodal.md +++ b/docs/multimodal.md @@ -29,7 +29,7 @@ result is fully retrievable with the same `/search` stack. ## How it works ``` -POST /api/v1/memory/add +POST /api/v2/memory/add messages[].content = [ ContentItem, ContentItem, ... ] │ │ text items → used verbatim @@ -157,7 +157,7 @@ way — only the parsed text is. ```bash TS=$(($(date +%s) * 1000)) # v1 contract: timestamp in ms -curl -X POST http://127.0.0.1:8000/api/v1/memory/add \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/add \ -H 'Content-Type: application/json' \ -d "{ \"session_id\": \"mm-001\", @@ -244,7 +244,7 @@ HTTP library: import httpx httpx.post( - "http://127.0.0.1:8000/api/v1/memory/add", + "http://127.0.0.1:8000/api/v2/memory/add", json={ "session_id": "mm-001", "messages": [ @@ -319,7 +319,7 @@ episodes and memory cells as text turns, every retrieval method works across multimodal-derived memory unchanged: ```bash -curl -X POST http://127.0.0.1:8000/api/v1/memory/search \ +curl -X POST http://127.0.0.1:8000/api/v2/memory/search \ -H 'Content-Type: application/json' \ -d '{ "user_id": "alice", diff --git a/docs/reflection.md b/docs/reflection.md index 94a56aec..63c09f1f 100644 --- a/docs/reflection.md +++ b/docs/reflection.md @@ -221,7 +221,7 @@ dedicated CLI command). ### Triggering a run ``` -POST /api/v1/ome/trigger +POST /api/v2/ome/trigger Content-Type: application/json ``` @@ -249,7 +249,7 @@ import httpx async def trigger_reflection() -> str: async with httpx.AsyncClient(base_url="http://localhost:8000") as client: resp = await client.post( - "/api/v1/ome/trigger", + "/api/v2/ome/trigger", json={"name": "reflect_episodes", "timeout": 120, "force": True}, ) resp.raise_for_status() @@ -259,7 +259,7 @@ async def trigger_reflection() -> str: **Example — curl**: ```bash -curl -X POST http://localhost:8000/api/v1/ome/trigger \ +curl -X POST http://localhost:8000/api/v2/ome/trigger \ -H "Content-Type: application/json" \ -d '{"name": "reflect_episodes", "timeout": 120, "force": true}' ``` @@ -327,7 +327,7 @@ real deployment, once enabled it runs automatically on schedule, so this step isn't needed. ```bash -BASE=http://localhost:8000/api/v1 +BASE=http://localhost:8000/api/v2 # 1. With Reflection enabled (set enabled = true in /ome.toml), # trigger a run by hand here (for the demo; in production it runs on schedule) diff --git a/examples/langfuse/README.md b/examples/langfuse/README.md index 2376bacd..e34f8e8c 100644 --- a/examples/langfuse/README.md +++ b/examples/langfuse/README.md @@ -42,11 +42,11 @@ zero tracing overhead. | EverOS operation | Langfuse observation | | --- | --- | -| `POST /api/v1/memory/add` · `flush` | span `everos.memory.add` / `everos.memory.flush` | +| `POST /api/v2/memory/add` · `flush` | span `everos.memory.add` / `everos.memory.flush` | | memcell boundary detection (LLM) | generation `everos.memcell.boundary` (model + tokens) | | episode extraction (LLM) | generation `everos.extract` | | markdown persistence | span `everos.persist.markdown` | -| `POST /api/v1/memory/search` | retriever `everos.memory.search` → `recall` / `rank` | +| `POST /api/v2/memory/search` | retriever `everos.memory.search` → `recall` / `rank` | | query / recall embedding | embedding `everos.embedding` | | OME reflection strategies | agent `everos.ome.` (linked to the triggering request's trace) | diff --git a/examples/langfuse/demo.py b/examples/langfuse/demo.py index ecf85420..c7bc7bce 100644 --- a/examples/langfuse/demo.py +++ b/examples/langfuse/demo.py @@ -39,7 +39,7 @@ def main() -> None: ts = int(time.time() * 1000) add = _post( - "/api/v1/memory/add", + "/api/v2/memory/add", { "session_id": SESSION, "messages": [ @@ -62,7 +62,7 @@ def main() -> None: ) print("add ->", add["data"]) - flush = _post("/api/v1/memory/flush", {"session_id": SESSION, "messages": []}) + flush = _post("/api/v2/memory/flush", {"session_id": SESSION, "messages": []}) print("flush ->", flush["data"]) print("waiting for async index sync ...") @@ -70,7 +70,7 @@ def main() -> None: for method in ("keyword", "hybrid", "agentic"): resp = _post( - "/api/v1/memory/search", + "/api/v2/memory/search", { "user_id": USER, "query": "which vector database did we move to and why", diff --git a/src/everos/entrypoints/api/app.py b/src/everos/entrypoints/api/app.py index 3eae0cd5..5d28ba03 100644 --- a/src/everos/entrypoints/api/app.py +++ b/src/everos/entrypoints/api/app.py @@ -125,13 +125,13 @@ def create_app( app.include_router(health.router) app.include_router(metrics.router) - # Business API — served under both /api/v2 (cloud-aligned name) and - # /api/v1 (retained as a permanent backward-compatible alias). The same - # router object is mounted twice, so both prefixes resolve to the exact - # same handlers; FastAPI's default operationId embeds the path, so the - # two copies get distinct OpenAPI ids automatically (no collision). + # Business API — served under both /api/v2 (canonical, cloud-aligned name) + # and /api/v1 (legacy compatibility alias, removable in a future major). + # The same router object is mounted twice, so both prefixes resolve to the + # exact same handlers; FastAPI's default operationId embeds the path, so + # the two copies get distinct OpenAPI ids automatically (no collision). # v1 and v2 stay identical by construction — see test_api_versioning. - # v1 first — retained alias, behavior identical. + # v1 first — legacy alias, behavior identical. app.include_router(memorize.router, prefix="/api/v1") app.include_router(search.router, prefix="/api/v1") app.include_router(get.router, prefix="/api/v1") diff --git a/src/everos/entrypoints/cli/commands/demo.py b/src/everos/entrypoints/cli/commands/demo.py index 12c3463a..8f111830 100644 --- a/src/everos/entrypoints/cli/commands/demo.py +++ b/src/everos/entrypoints/cli/commands/demo.py @@ -160,7 +160,7 @@ def _run_live_demo_flow( timestamp_ms = int(get_utc_now().timestamp() * 1000) request( "POST", - "/api/v1/memory/add", + "/api/v2/memory/add", base_url=base_url, json_body={ "session_id": LIVE_DEMO_SESSION_ID, @@ -179,7 +179,7 @@ def _run_live_demo_flow( ) request( "POST", - "/api/v1/memory/flush", + "/api/v2/memory/flush", base_url=base_url, json_body={ "session_id": LIVE_DEMO_SESSION_ID, @@ -199,7 +199,7 @@ def _run_live_demo_flow( for attempt in range(search_attempts): search = request( "POST", - "/api/v1/memory/search", + "/api/v2/memory/search", base_url=base_url, json_body=search_payload, timeout_seconds=timeout_seconds, diff --git a/tests/unit/test_entrypoints/test_api/test_api_versioning.py b/tests/unit/test_entrypoints/test_api/test_api_versioning.py index da67d908..6923a044 100644 --- a/tests/unit/test_entrypoints/test_api/test_api_versioning.py +++ b/tests/unit/test_entrypoints/test_api/test_api_versioning.py @@ -1,10 +1,10 @@ """API version aliasing — every business route is served under v1 and v2. -The ``/api/v2`` prefix is the cloud-aligned name; ``/api/v1`` is retained as a -permanent backward-compatible alias pointing to the *same* endpoint. These -tests are the completeness guard: they fail if any versioned route is exposed -under one prefix but not the other, or if the two prefixes ever diverge to -different handlers. Infrastructure endpoints (``/health``, ``/metrics``) are +The ``/api/v2`` prefix is the canonical, cloud-aligned name; ``/api/v1`` is a +legacy compatibility alias pointing to the *same* endpoint. These tests are +the completeness guard: they fail if any versioned route is exposed under one +prefix but not the other, or if the two prefixes ever diverge to different +handlers. Infrastructure endpoints (``/health``, ``/metrics``) are deliberately unversioned and must NOT be mirrored. Assertions run against ``app.openapi()["paths"]`` — the authoritative, diff --git a/tests/unit/test_entrypoints/test_cli/test_demo_command.py b/tests/unit/test_entrypoints/test_cli/test_demo_command.py index adc01d13..4af9fd0e 100644 --- a/tests/unit/test_entrypoints/test_cli/test_demo_command.py +++ b/tests/unit/test_entrypoints/test_cli/test_demo_command.py @@ -134,11 +134,11 @@ def fake_request( assert timeout_seconds == 3.0 if path == "/health": return {"status": "ok"} - if path == "/api/v1/memory/add": + if path == "/api/v2/memory/add": return {"message_count": 1, "status": "accumulated"} - if path == "/api/v1/memory/flush": + if path == "/api/v2/memory/flush": return {"message_count": 1, "status": "extracted"} - if path == "/api/v1/memory/search": + if path == "/api/v2/memory/search": return { "data": { "episodes": [ @@ -172,9 +172,9 @@ def fake_request( assert [path for _, path, _ in calls] == [ "/health", - "/api/v1/memory/add", - "/api/v1/memory/flush", - "/api/v1/memory/search", + "/api/v2/memory/add", + "/api/v2/memory/flush", + "/api/v2/memory/search", ] add_body = calls[1][2] assert add_body is not None