Skip to content

revamp README - #1

Open
phraakture wants to merge 1 commit into
mainfrom
readme
Open

phraakture wants to merge 1 commit into
mainfrom
readme

Conversation

@phraakture

@phraakture phraakture commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Cleaner structure, badges, condensed API reference, simplified quickstart.

Summary by CodeRabbit

  • Documentation
    • Restructured the README with streamlined installation and quickstart guidance.
    • Added a consolidated API reference covering configuration, memory operations, table creation, and environment variables.
    • Added updated chat and server examples, including search and Docker usage.
    • Documented the processing pipeline, bubble-linking behavior, and time-to-live handling.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

README.md was reorganized to document installation, quickstart usage, the public API, memory processing, chat integration, and server operation with updated examples and configuration details.

Changes

README documentation

Layer / File(s) Summary
Installation and API reference
README.md
Install commands, quickstart usage, API methods, table creation, and environment-variable settings were rewritten.
Memory processing and chat examples
README.md
The processing pipeline, bubble linking and TTL behavior, and chat memory search/storage flow were documented with new examples.
Server usage documentation
README.md
Server installation, endpoints, and Docker Compose instructions were streamlined and updated.

Estimated code review effort: 1 (Trivial) | ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: a broad README revamp.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch readme

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8be0e4722f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread README.md
Comment on lines +113 to +114
hits = memory.search(query=message, conversation_id=conv_id, limit=5)
memories = "\n".join(f"- [{h['type']}] {h['memory']}" for h in hits["results"])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make the chat helper await memory calls

In the chat example, Memory.search and Memory.add are async methods, but respond is synchronous and calls memory.search without await; when copied as a normal helper this makes hits a coroutine, so hits["results"] raises TypeError and the later memory.add call is never awaited or persisted. Make respond async and await both memory calls, or explicitly run them on an event loop.

Useful? React with 👍 / 👎.

Comment thread README.md
| `GET /health` | Health check |
| `POST /conversations` | Create conversation |
| `POST /memories` | Add memories from a turn |
| `GET /memories/search?q=&conv=` | Vector search |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Document the actual search query parameters

The documented URL uses q and conv, but the FastAPI handler requires query parameters named query and conversation_id; a user following this endpoint shape will get a validation error instead of search results. Update the example to /memories/search?query=...&conversation_id=... so it matches search_memories in src/eidetic/api/app.py.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Line 82: Update the fenced diagram block in README.md by adding an appropriate
language identifier, such as text, to its opening fence while preserving the
diagram content.
- Around line 133-156: Update the README endpoint table’s GET /memories/search
example to use the actual FastAPI query parameters query and conversation_id
instead of q and conv. Keep the endpoint path and vector-search description
unchanged.
- Around line 99-131: Update the README Chat example’s respond function to be
asynchronous and await both memory.search() and memory.add(). Preserve the
existing search, LLM response, and persistence flow while ensuring hits contains
the resolved search result before accessing results.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f0385b63-b04a-40ad-b7e8-58ccdba699ac

📥 Commits

Reviewing files that changed from the base of the PR and between da37484 and 8be0e47.

📒 Files selected for processing (1)
  • README.md

Comment thread README.md
eidetic serve
## How it works

```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Specify a language for the fenced diagram block.

Add a language identifier such as text after the opening fence so markdownlint does not report MD040.

🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 82-82: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 82, Update the fenced diagram block in README.md by adding
an appropriate language identifier, such as text, to its opening fence while
preserving the diagram content.

Source: Linters/SAST tools

Comment thread README.md
Comment on lines +99 to 131
## Chat example

### Docker
```python
from openai import OpenAI
from eidetic import configure, Memory, create_table

```bash
docker compose up --build
```
configure(openrouter_api_key="sk-or-v1-...", llm_provider="openrouter")
chat = OpenAI(api_key="sk-or-v1-...", base_url="https://openrouter.ai/api/v1")
await create_table()
memory = Memory()

Set API keys via environment variables (see `.env.example`).

## CLI
def respond(message: str, conv_id: int = 1) -> str:
# 1. Retrieve relevant memories
hits = memory.search(query=message, conversation_id=conv_id, limit=5)
memories = "\n".join(f"- [{h['type']}] {h['memory']}" for h in hits["results"])

```
eidetic create-conversation create a new conversation
eidetic add <conv_id> <user> <asst> add memories from one turn
eidetic search <conv_id> <query> search stored memories
eidetic expire-bubbles [conv_id] run bubble TTL expiry
# 2. Call LLM with memory context
reply = chat.chat.completions.create(
model="anthropic/claude-sonnet-4.5",
messages=[
{"role": "system", "content": f"User memories:\n{memories or 'None yet.'}"},
{"role": "user", "content": message},
],
).choices[0].message.content

# 3. Store new facts from this exchange
memory.add(
messages=[{"role": "user", "content": message}, {"role": "assistant", "content": reply}],
conversation_id=conv_id,
)
return reply
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Await the asynchronous memory APIs.

Memory.search() and Memory.add() are async, but respond() is synchronous and neither call is awaited. As written, hits["results"] operates on a coroutine and the new facts are never persisted.

Proposed fix
-def respond(message: str, conv_id: int = 1) -> str:
+async def respond(message: str, conv_id: int = 1) -> str:
     # 1. Retrieve relevant memories
-    hits = memory.search(query=message, conversation_id=conv_id, limit=5)
+    hits = await memory.search(query=message, conversation_id=conv_id, limit=5)
     memories = "\n".join(f"- [{h['type']}] {h['memory']}" for h in hits["results"])
...
-    memory.add(
+    await memory.add(
         messages=[{"role": "user", "content": message}, {"role": "assistant", "content": reply}],
         conversation_id=conv_id,
     )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Chat example
### Docker
```python
from openai import OpenAI
from eidetic import configure, Memory, create_table
```bash
docker compose up --build
```
configure(openrouter_api_key="sk-or-v1-...", llm_provider="openrouter")
chat = OpenAI(api_key="sk-or-v1-...", base_url="https://openrouter.ai/api/v1")
await create_table()
memory = Memory()
Set API keys via environment variables (see `.env.example`).
## CLI
def respond(message: str, conv_id: int = 1) -> str:
# 1. Retrieve relevant memories
hits = memory.search(query=message, conversation_id=conv_id, limit=5)
memories = "\n".join(f"- [{h['type']}] {h['memory']}" for h in hits["results"])
```
eidetic create-conversation create a new conversation
eidetic add <conv_id> <user> <asst> add memories from one turn
eidetic search <conv_id> <query> search stored memories
eidetic expire-bubbles [conv_id] run bubble TTL expiry
# 2. Call LLM with memory context
reply = chat.chat.completions.create(
model="anthropic/claude-sonnet-4.5",
messages=[
{"role": "system", "content": f"User memories:\n{memories or 'None yet.'}"},
{"role": "user", "content": message},
],
).choices[0].message.content
# 3. Store new facts from this exchange
memory.add(
messages=[{"role": "user", "content": message}, {"role": "assistant", "content": reply}],
conversation_id=conv_id,
)
return reply
```
## Chat example
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 99 - 131, Update the README Chat example’s respond
function to be asynchronous and await both memory.search() and memory.add().
Preserve the existing search, LLM response, and persistence flow while ensuring
hits contains the resolved search result before accessing results.

Comment thread README.md
Comment on lines +133 to +156
## Server

```
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ FastAPI │───▶│ MemoryService │───▶│ Extractor │
│ (HTTP) │ │ (orchestr.) │ │ (LLM) │
└─────────────┘ └──────┬───────┘ └──────────────┘
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│Classifier│ │ Bubble │ │ Summary │
│ (LLM) │ │ Creator │ │ Service │
└──────────┘ └──────────┘ └──────────┘
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ FAISS │ │ SQLite │ │ LLM / │
│ Index │ │ DB │ │ Embedding │
└──────────┘ └──────────┘ └──────────┘
```bash
pip install 'eidetic-ai[server]'
eidetic serve # http://localhost:8000
```

**Memory types:**
- **Semantic** — stable long-term facts about the user (name, preferences, skills). Deduplicated and updated via an LLM classifier (ADD / UPDATE / REPLACE / DELETE / NOOP).
- **Bubbles (episodic)** — time-bound significant moments. Linked bidirectionally to related memories via FAISS similarity. Automatically expired after a configurable TTL.
| Endpoint | Description |
|----------|-------------|
| `GET /health` | Health check |
| `POST /conversations` | Create conversation |
| `POST /memories` | Add memories from a turn |
| `GET /memories/search?q=&conv=` | Vector search |
| `PUT /memories/{id}` | Update memory text |
| `DELETE /memories/{id}` | Soft-delete |
| `POST /bubbles/expire` | Expire stale bubbles |

## Config
Full OpenAPI docs at `/docs`.

All configuration via environment variables with prefix `EIDETIC_` or via the `configure()` function:
### Docker

| Variable / kwarg | Default | Description |
|---|---|---|
| `EIDETIC_OPENAI_API_KEY` | — | OpenAI API key |
| `EIDETIC_OPENROUTER_API_KEY` | — | OpenRouter API key |
| `EIDETIC_LLM_PROVIDER` | `openai` | `openai` or `openrouter` |
| `EIDETIC_LLM_MODEL` | `gpt-4o-mini` | LLM model name |
| `EIDETIC_EMBEDDING_MODEL` | `text-embedding-3-small` | Embedding model name |
| `EIDETIC_DATABASE_URL` | `~/.eidetic/eidetic.db` | SQLAlchemy async DB URL |
| `EIDETIC_DEBUG` | `false` | Enable debug logging |
| `EIDETIC_BUBBLE_TTL_DAYS` | `30` | Bubble expiry in days (0 = never) |
| `EIDETIC_CONNECTION_THRESHOLD` | `0.6` | Min similarity for bubble links |
| `EIDETIC_MAX_CONNECTIONS_PER_BUBBLE` | `5` | Max bidirectional links per bubble |
```bash
docker compose up --build
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Document the actual search query parameters.

The FastAPI endpoint accepts query and conversation_id, but the README advertises q and conv; following this example results in a validation error.

-| `GET /memories/search?q=&conv=` | Vector search |
+| `GET /memories/search?query=&conversation_id=` | Vector search |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Server
```
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ FastAPI │───▶│ MemoryService │───▶│ Extractor │
│ (HTTP) │ │ (orchestr.) │ │ (LLM) │
└─────────────┘ └──────┬───────┘ └──────────────┘
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│Classifier│ │ Bubble │ │ Summary │
│ (LLM) │ │ Creator │ │ Service │
└──────────┘ └──────────┘ └──────────┘
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ FAISS │ │ SQLite │ │ LLM / │
│ Index │ │ DB │ │ Embedding │
└──────────┘ └──────────┘ └──────────┘
```bash
pip install 'eidetic-ai[server]'
eidetic serve # http://localhost:8000
```
**Memory types:**
- **Semantic** — stable long-term facts about the user (name, preferences, skills). Deduplicated and updated via an LLM classifier (ADD / UPDATE / REPLACE / DELETE / NOOP).
- **Bubbles (episodic)** — time-bound significant moments. Linked bidirectionally to related memories via FAISS similarity. Automatically expired after a configurable TTL.
| Endpoint | Description |
|----------|-------------|
| `GET /health` | Health check |
| `POST /conversations` | Create conversation |
| `POST /memories` | Add memories from a turn |
| `GET /memories/search?q=&conv=` | Vector search |
| `PUT /memories/{id}` | Update memory text |
| `DELETE /memories/{id}` | Soft-delete |
| `POST /bubbles/expire` | Expire stale bubbles |
## Config
Full OpenAPI docs at `/docs`.
All configuration via environment variables with prefix `EIDETIC_` or via the `configure()` function:
### Docker
| Variable / kwarg | Default | Description |
|---|---|---|
| `EIDETIC_OPENAI_API_KEY` || OpenAI API key |
| `EIDETIC_OPENROUTER_API_KEY` || OpenRouter API key |
| `EIDETIC_LLM_PROVIDER` | `openai` | `openai` or `openrouter` |
| `EIDETIC_LLM_MODEL` | `gpt-4o-mini` | LLM model name |
| `EIDETIC_EMBEDDING_MODEL` | `text-embedding-3-small` | Embedding model name |
| `EIDETIC_DATABASE_URL` | `~/.eidetic/eidetic.db` | SQLAlchemy async DB URL |
| `EIDETIC_DEBUG` | `false` | Enable debug logging |
| `EIDETIC_BUBBLE_TTL_DAYS` | `30` | Bubble expiry in days (0 = never) |
| `EIDETIC_CONNECTION_THRESHOLD` | `0.6` | Min similarity for bubble links |
| `EIDETIC_MAX_CONNECTIONS_PER_BUBBLE` | `5` | Max bidirectional links per bubble |
```bash
docker compose up --build
```
## Server
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 133 - 156, Update the README endpoint table’s GET
/memories/search example to use the actual FastAPI query parameters query and
conversation_id instead of q and conv. Keep the endpoint path and vector-search
description unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant