remdb 0.2.6__py3-none-any.whl → 0.3.103__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of remdb might be problematic. Click here for more details.

Files changed (82) hide show
  1. rem/__init__.py +129 -2
  2. rem/agentic/README.md +76 -0
  3. rem/agentic/__init__.py +15 -0
  4. rem/agentic/agents/__init__.py +16 -2
  5. rem/agentic/agents/sse_simulator.py +500 -0
  6. rem/agentic/context.py +7 -5
  7. rem/agentic/llm_provider_models.py +301 -0
  8. rem/agentic/providers/phoenix.py +32 -43
  9. rem/agentic/providers/pydantic_ai.py +84 -10
  10. rem/api/README.md +238 -1
  11. rem/api/deps.py +255 -0
  12. rem/api/main.py +70 -22
  13. rem/api/mcp_router/server.py +8 -1
  14. rem/api/mcp_router/tools.py +80 -0
  15. rem/api/middleware/tracking.py +172 -0
  16. rem/api/routers/admin.py +277 -0
  17. rem/api/routers/auth.py +124 -0
  18. rem/api/routers/chat/completions.py +123 -14
  19. rem/api/routers/chat/models.py +7 -3
  20. rem/api/routers/chat/sse_events.py +526 -0
  21. rem/api/routers/chat/streaming.py +468 -45
  22. rem/api/routers/dev.py +81 -0
  23. rem/api/routers/feedback.py +455 -0
  24. rem/api/routers/messages.py +473 -0
  25. rem/api/routers/models.py +78 -0
  26. rem/api/routers/shared_sessions.py +406 -0
  27. rem/auth/middleware.py +126 -27
  28. rem/cli/commands/ask.py +15 -11
  29. rem/cli/commands/configure.py +169 -94
  30. rem/cli/commands/db.py +53 -7
  31. rem/cli/commands/experiments.py +278 -96
  32. rem/cli/commands/process.py +8 -7
  33. rem/cli/commands/scaffold.py +47 -0
  34. rem/cli/commands/schema.py +9 -9
  35. rem/cli/main.py +10 -0
  36. rem/config.py +2 -2
  37. rem/models/core/core_model.py +7 -1
  38. rem/models/entities/__init__.py +21 -0
  39. rem/models/entities/domain_resource.py +38 -0
  40. rem/models/entities/feedback.py +123 -0
  41. rem/models/entities/message.py +30 -1
  42. rem/models/entities/session.py +83 -0
  43. rem/models/entities/shared_session.py +206 -0
  44. rem/models/entities/user.py +10 -3
  45. rem/registry.py +367 -0
  46. rem/schemas/agents/rem.yaml +7 -3
  47. rem/services/content/providers.py +94 -140
  48. rem/services/content/service.py +85 -16
  49. rem/services/dreaming/affinity_service.py +2 -16
  50. rem/services/dreaming/moment_service.py +2 -15
  51. rem/services/embeddings/api.py +20 -13
  52. rem/services/phoenix/EXPERIMENT_DESIGN.md +3 -3
  53. rem/services/phoenix/client.py +252 -19
  54. rem/services/postgres/README.md +29 -10
  55. rem/services/postgres/repository.py +132 -0
  56. rem/services/postgres/schema_generator.py +86 -5
  57. rem/services/rate_limit.py +113 -0
  58. rem/services/rem/README.md +14 -0
  59. rem/services/session/compression.py +17 -1
  60. rem/services/user_service.py +98 -0
  61. rem/settings.py +115 -17
  62. rem/sql/background_indexes.sql +10 -0
  63. rem/sql/migrations/001_install.sql +152 -2
  64. rem/sql/migrations/002_install_models.sql +580 -231
  65. rem/sql/migrations/003_seed_default_user.sql +48 -0
  66. rem/utils/constants.py +97 -0
  67. rem/utils/date_utils.py +228 -0
  68. rem/utils/embeddings.py +17 -4
  69. rem/utils/files.py +167 -0
  70. rem/utils/mime_types.py +158 -0
  71. rem/utils/model_helpers.py +156 -1
  72. rem/utils/schema_loader.py +273 -14
  73. rem/utils/sql_types.py +3 -1
  74. rem/utils/vision.py +9 -14
  75. rem/workers/README.md +14 -14
  76. rem/workers/db_maintainer.py +74 -0
  77. {remdb-0.2.6.dist-info → remdb-0.3.103.dist-info}/METADATA +486 -132
  78. {remdb-0.2.6.dist-info → remdb-0.3.103.dist-info}/RECORD +80 -57
  79. {remdb-0.2.6.dist-info → remdb-0.3.103.dist-info}/WHEEL +1 -1
  80. rem/sql/002_install_models.sql +0 -1068
  81. rem/sql/install_models.sql +0 -1038
  82. {remdb-0.2.6.dist-info → remdb-0.3.103.dist-info}/entry_points.txt +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remdb
3
- Version: 0.2.6
3
+ Version: 0.3.103
4
4
  Summary: Resources Entities Moments - Bio-inspired memory system for agentic AI workloads
5
- Project-URL: Homepage, https://github.com/mr-saoirse/remstack
6
- Project-URL: Documentation, https://github.com/mr-saoirse/remstack/blob/main/README.md
7
- Project-URL: Repository, https://github.com/mr-saoirse/remstack
8
- Project-URL: Issues, https://github.com/mr-saoirse/remstack/issues
5
+ Project-URL: Homepage, https://github.com/Percolation-Labs/reminiscent
6
+ Project-URL: Documentation, https://github.com/Percolation-Labs/reminiscent/blob/main/README.md
7
+ Project-URL: Repository, https://github.com/Percolation-Labs/reminiscent
8
+ Project-URL: Issues, https://github.com/Percolation-Labs/reminiscent/issues
9
9
  Author-email: mr-saoirse <amartey@gmail.com>
10
10
  License: MIT
11
11
  Keywords: agents,ai,mcp,memory,postgresql,vector-search
@@ -14,7 +14,7 @@ Classifier: Intended Audience :: Developers
14
14
  Classifier: License :: OSI Approved :: MIT License
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
- Requires-Python: >=3.12
17
+ Requires-Python: <3.13,>=3.12
18
18
  Requires-Dist: aioboto3>=13.0.0
19
19
  Requires-Dist: arize-phoenix>=5.0.0
20
20
  Requires-Dist: asyncpg>=0.30.0
@@ -23,11 +23,10 @@ Requires-Dist: click>=8.1.0
23
23
  Requires-Dist: fastapi>=0.115.0
24
24
  Requires-Dist: fastmcp>=0.5.0
25
25
  Requires-Dist: gitpython>=3.1.45
26
- Requires-Dist: gmft
27
26
  Requires-Dist: hypercorn>=0.17.0
28
27
  Requires-Dist: itsdangerous>=2.0.0
29
28
  Requires-Dist: json-schema-to-pydantic>=0.2.0
30
- Requires-Dist: kreuzberg[gmft]>=3.21.0
29
+ Requires-Dist: kreuzberg<4.0.0,>=3.21.0
31
30
  Requires-Dist: loguru>=0.7.0
32
31
  Requires-Dist: openinference-instrumentation-pydantic-ai>=0.1.0
33
32
  Requires-Dist: opentelemetry-api>=1.28.0
@@ -91,32 +90,9 @@ Cloud-native unified memory infrastructure for agentic AI systems built with Pyd
91
90
 
92
91
  ## Architecture Overview
93
92
 
94
- ```mermaid
95
- graph TD
96
- API[FastAPI<br/>Chat + MCP] --> AGENTS[JSON Schema<br/>Agents]
97
- AGENTS --> TOOLS[MCP Tools<br/>5 Tools]
98
-
99
- TOOLS --> QUERY[REM Query<br/>Dialect]
100
- QUERY --> DB[(PostgreSQL<br/>+pgvector)]
101
-
102
- FILES[File Processor] --> DREAM[Dreaming<br/>Workers]
103
- DREAM --> DB
104
-
105
- AGENTS --> OTEL[OpenTelemetry]
106
- OTEL --> PHOENIX[Arize<br/>Phoenix]
107
-
108
- EVAL[Evaluation<br/>Framework] --> PHOENIX
109
-
110
- classDef api fill:#4A90E2,stroke:#2E5C8A,color:#fff
111
- classDef agent fill:#7B68EE,stroke:#483D8B,color:#fff
112
- classDef db fill:#50C878,stroke:#2E7D4E,color:#fff
113
- classDef obs fill:#9B59B6,stroke:#6C3483,color:#fff
114
-
115
- class API,TOOLS api
116
- class AGENTS agent
117
- class DB,QUERY db
118
- class OTEL,PHOENIX,EVAL obs
119
- ```
93
+ <p align="center">
94
+ <img src="https://mermaid.ink/img/Z3JhcGggVEQKICAgIEFQSVtGYXN0QVBJPGJyLz5DaGF0ICsgTUNQXSAtLT4gQUdFTlRTW0pTT04gU2NoZW1hPGJyLz5BZ2VudHNdCiAgICBBR0VOVFMgLS0-IFRPT0xTW01DUCBUb29sczxici8-NSBUb29sc10KCiAgICBUT09MUyAtLT4gUVVFUllbUkVNIFF1ZXJ5PGJyLz5EaWFsZWN0XQogICAgUVVFUlkgLS0-IERCWyhQb3N0Z3JlU1FMPGJyLz4rcGd2ZWN0b3IpXQoKICAgIEZJTEVTW0ZpbGUgUHJvY2Vzc29yXSAtLT4gRFJFQU1bRHJlYW1pbmc8YnIvPldvcmtlcnNdCiAgICBEUkVBTSAtLT4gREIKCiAgICBBR0VOVFMgLS0-IE9URUxbT3BlblRlbGVtZXRyeV0KICAgIE9URUwgLS0-IFBIT0VOSVhbQXJpemU8YnIvPlBob2VuaXhdCgogICAgRVZBTFtFdmFsdWF0aW9uPGJyLz5GcmFtZXdvcmtdIC0tPiBQSE9FTklYCgogICAgY2xhc3NEZWYgYXBpIGZpbGw6IzRBOTBFMixzdHJva2U6IzJFNUM4QSxjb2xvcjojZmZmCiAgICBjbGFzc0RlZiBhZ2VudCBmaWxsOiM3QjY4RUUsc3Ryb2tlOiM0ODNEOEIsY29sb3I6I2ZmZgogICAgY2xhc3NEZWYgZGIgZmlsbDojNTBDODc4LHN0cm9rZTojMkU3RDRFLGNvbG9yOiNmZmYKICAgIGNsYXNzRGVmIG9icyBmaWxsOiM5QjU5QjYsc3Ryb2tlOiM2QzM0ODMsY29sb3I6I2ZmZgoKICAgIGNsYXNzIEFQSSxUT09MUyBhcGkKICAgIGNsYXNzIEFHRU5UUyBhZ2VudAogICAgY2xhc3MgREIsUVVFUlkgZGIKICAgIGNsYXNzIE9URUwsUEhPRU5JWCxFVkFMIG9icwo=" alt="REM Architecture" width="700">
95
+ </p>
120
96
 
121
97
  **Key Components:**
122
98
 
@@ -125,37 +101,91 @@ graph TD
125
101
  - **Database Layer**: PostgreSQL 18 with pgvector for multi-index memory (KV + Vector + Graph)
126
102
  - **REM Query Dialect**: Custom query language with O(1) lookups, semantic search, graph traversal
127
103
  - **Ingestion & Dreaming**: Background workers for content extraction and progressive index enrichment (0% → 100% answerable)
128
- - **Observability & Evals**: OpenTelemetry tracing + Arize Phoenix + LLM-as-a-Judge evaluation framework
104
+ - **Observability & Evals**: OpenTelemetry tracing supporting LLM-as-a-Judge evaluation frameworks
129
105
 
130
106
  ## Features
131
107
 
132
108
  | Feature | Description | Benefits |
133
109
  |---------|-------------|----------|
134
110
  | **OpenAI-Compatible Chat API** | Drop-in replacement for OpenAI chat completions API with streaming support | Use with existing OpenAI clients, switch models across providers (OpenAI, Anthropic, etc.) |
135
- | **Built-in MCP Server** | FastMCP server with 5 tools + 3 resources for memory operations | Export memory to Claude Desktop, Cursor, or any MCP-compatible host |
111
+ | **Built-in MCP Server** | FastMCP server with 4 tools + 5 resources for memory operations | Export memory to Claude Desktop, Cursor, or any MCP-compatible host |
136
112
  | **REM Query Engine** | Multi-index query system (LOOKUP, FUZZY, SEARCH, SQL, TRAVERSE) with custom dialect | O(1) lookups, semantic search, graph traversal - all tenant-isolated |
137
113
  | **Dreaming Workers** | Background workers for entity extraction, moment generation, and affinity matching | Automatic knowledge graph construction from resources (0% → 100% query answerable) |
138
114
  | **PostgreSQL + pgvector** | CloudNativePG with PostgreSQL 18, pgvector extension, streaming replication | Production-ready vector search, no external vector DB needed |
139
115
  | **AWS EKS Recipe** | Complete infrastructure-as-code with Pulumi, Karpenter, ArgoCD | Deploy to production EKS in minutes with auto-scaling and GitOps |
140
116
  | **JSON Schema Agents** | Dynamic agent creation from YAML schemas via Pydantic AI factory | Define agents declaratively, version control schemas, load dynamically |
141
- | **Content Providers** | Audio transcription (Whisper), vision (GPT-4V, Claude), PDFs, DOCX, images | Multimodal ingestion out of the box with format detection |
142
- | **Configurable Embeddings** | Provider-agnostic embedding system (OpenAI, Cohere, Jina) | Switch embedding providers via env vars, no code changes |
117
+ | **Content Providers** | Audio transcription (Whisper), vision (OpenAI, Anthropic, Gemini), PDFs, DOCX, PPTX, XLSX, images | Multimodal ingestion out of the box with format detection |
118
+ | **Configurable Embeddings** | OpenAI embedding system (text-embedding-3-small) | Production-ready embeddings, additional providers planned |
143
119
  | **Multi-Tenancy** | Tenant isolation at database level with automatic scoping | SaaS-ready with complete data separation per tenant |
144
- | **Streaming Everything** | SSE for chat, background workers for embeddings, async throughout | Real-time responses, non-blocking operations, scalable |
145
120
  | **Zero Vendor Lock-in** | Raw HTTP clients (no OpenAI SDK), swappable providers, open standards | Not tied to any vendor, easy to migrate, full control |
146
121
 
147
122
  ## Quick Start
148
123
 
149
124
  Choose your path:
150
125
 
151
- - **Option 1: Package Users** (Recommended for non-developers) - PyPI package + dockerized database
152
- - **Option 2: Developers** - Clone repo, local development with uv
126
+ - **Option 1: Package Users with Example Data** (Recommended for first-time users) - PyPI + example datasets
127
+ - **Option 2: Package Users** (Recommended for non-developers) - PyPI package + dockerized database
128
+ - **Option 3: Developers** - Clone repo, local development with uv
153
129
 
154
130
  ---
155
131
 
156
- ## Option 1: Package Users (Recommended)
132
+ ## Option 1: Package Users with Example Data (Recommended)
133
+
134
+ **Best for**: First-time users who want to explore REM with curated example datasets.
135
+
136
+ ```bash
137
+ # Install system dependencies (tesseract for OCR)
138
+ brew install tesseract # macOS (Linux/Windows: see tesseract-ocr.github.io)
139
+
140
+ # Install remdb
141
+ pip install "remdb[all]"
157
142
 
158
- **Best for**: Using REM as a service (API + CLI) without modifying code.
143
+ # Clone example datasets
144
+ git clone https://github.com/Percolation-Labs/remstack-lab.git
145
+ cd remstack-lab
146
+
147
+ # Optional: Set default LLM provider via environment variable
148
+ # export LLM__DEFAULT_MODEL="openai:gpt-4.1-nano" # Fast and cheap
149
+ # export LLM__DEFAULT_MODEL="anthropic:claude-sonnet-4-5-20250929" # High quality (default)
150
+
151
+ # Start PostgreSQL with docker-compose
152
+ curl -O https://gist.githubusercontent.com/percolating-sirsh/d117b673bc0edfdef1a5068ccd3cf3e5/raw/docker-compose.prebuilt.yml
153
+ docker compose -f docker-compose.prebuilt.yml up -d postgres
154
+
155
+ # Configure REM (creates ~/.rem/config.yaml and installs database schema)
156
+ # Add --claude-desktop to register with Claude Desktop app
157
+ rem configure --install --claude-desktop
158
+
159
+ # Load quickstart dataset (uses default user)
160
+ rem db load datasets/quickstart/sample_data.yaml
161
+
162
+ # Ask questions
163
+ rem ask "What documents exist in the system?"
164
+ rem ask "Show me meetings about API design"
165
+
166
+ # Ingest files (PDF, DOCX, images, etc.) - note: requires remstack-lab
167
+ rem process ingest datasets/formats/files/bitcoin_whitepaper.pdf --category research --tags bitcoin,whitepaper
168
+
169
+ # Query ingested content
170
+ rem ask "What is the Bitcoin whitepaper about?"
171
+
172
+ # Try other datasets (use --user-id for multi-tenant scenarios)
173
+ rem db load datasets/domains/recruitment/scenarios/candidate_pipeline/data.yaml --user-id acme-corp
174
+ rem ask --user-id acme-corp "Show me candidates with Python experience"
175
+ ```
176
+
177
+ **What you get:**
178
+ - Quickstart: 3 users, 3 resources, 3 moments, 4 messages
179
+ - Domain datasets: recruitment, legal, enterprise, misc
180
+ - Format examples: engrams, documents, conversations, files
181
+
182
+ **Learn more**: [remstack-lab repository](https://github.com/Percolation-Labs/remstack-lab)
183
+
184
+ ---
185
+
186
+ ## Option 2: Package Users (No Example Data)
187
+
188
+ **Best for**: Using REM as a service (API + CLI) without modifying code, bringing your own data.
159
189
 
160
190
  ### Step 1: Start Database and API with Docker Compose
161
191
 
@@ -220,43 +250,277 @@ Configuration saved to `~/.rem/config.yaml` (can edit with `rem configure --edit
220
250
  - See [REM Query Dialect](#rem-query-dialect) for query examples
221
251
  - See [API Endpoints](#api-endpoints) for OpenAI-compatible API usage
222
252
 
223
- ### Step 3: Test the Stack
253
+ ### Step 3: Load Sample Data (Optional but Recommended)
254
+
255
+ **Option A: Clone example datasets** (Recommended - works with all README examples)
256
+
257
+ ```bash
258
+ # Clone datasets repository
259
+ git clone https://github.com/Percolation-Labs/remstack-lab.git
260
+
261
+ # Load quickstart dataset (uses default user)
262
+ rem db load --file remstack-lab/datasets/quickstart/sample_data.yaml
263
+
264
+ # Test with sample queries
265
+ rem ask "What documents exist in the system?"
266
+ rem ask "Show me meetings about API design"
267
+ rem ask "Who is Sarah Chen?"
268
+
269
+ # Try domain-specific datasets (use --user-id for multi-tenant scenarios)
270
+ rem db load --file remstack-lab/datasets/domains/recruitment/scenarios/candidate_pipeline/data.yaml --user-id acme-corp
271
+ rem ask --user-id acme-corp "Show me candidates with Python experience"
272
+ ```
273
+
274
+ **Option B: Bring your own data**
224
275
 
225
276
  ```bash
226
- # Ingest a test file to populate your knowledge base
277
+ # Ingest your own files (uses default user)
227
278
  echo "REM is a bio-inspired memory system for agentic AI workloads." > test-doc.txt
228
- rem process ingest test-doc.txt --user-id test-user --category documentation --tags rem,ai
279
+ rem process ingest test-doc.txt --category documentation --tags rem,ai
229
280
 
230
281
  # Query your ingested data
231
- rem ask "What do you know about REM from my knowledge base?" --user-id test-user
282
+ rem ask "What do you know about REM from my knowledge base?"
283
+ ```
232
284
 
233
- # Test with a general query (uses agent's built-in knowledge + your data)
234
- rem ask "What is REM?" --user-id test-user
285
+ ### Step 4: Test the API
235
286
 
236
- # Test the API
287
+ ```bash
288
+ # Test the OpenAI-compatible chat completions API
237
289
  curl -X POST http://localhost:8000/api/v1/chat/completions \
238
290
  -H "Content-Type: application/json" \
239
- -H "X-User-Id: test-user" \
291
+ -H "X-User-Id: demo-user" \
240
292
  -d '{
241
293
  "model": "anthropic:claude-sonnet-4-5-20250929",
242
- "messages": [{"role": "user", "content": "What is REM?"}],
294
+ "messages": [{"role": "user", "content": "What documents did Sarah Chen author?"}],
243
295
  "stream": false
244
296
  }'
245
297
  ```
246
298
 
247
- **File Ingestion Commands:**
299
+ **Available Commands:**
300
+ - `rem ask` - Natural language queries to REM
248
301
  - `rem process ingest <file>` - Full ingestion pipeline (storage + parsing + embedding + database)
249
302
  - `rem process uri <file>` - READ-ONLY parsing (no database storage, useful for testing parsers)
303
+ - `rem db load --file <yaml>` - Load structured datasets directly
304
+
305
+ ## Example Datasets
306
+
307
+ 🎯 **Recommended**: Clone [remstack-lab](https://github.com/Percolation-Labs/remstack-lab) for curated datasets organized by domain and format.
308
+
309
+ **What's included:**
310
+ - **Quickstart**: Minimal dataset (3 users, 3 resources, 3 moments) - perfect for first-time users
311
+ - **Domains**: Recruitment (CV parsing), Legal (contracts), Enterprise (team collaboration)
312
+ - **Formats**: Engrams (voice memos), Documents (markdown/PDF), Conversations (chat logs)
313
+ - **Evaluation**: Golden datasets for Phoenix-based agent testing
250
314
 
315
+ **Working from remstack-lab:**
316
+ ```bash
317
+ cd remstack-lab
318
+
319
+ # Load any dataset (uses default user)
320
+ rem db load --file datasets/quickstart/sample_data.yaml
321
+
322
+ # Explore formats
323
+ rem db load --file datasets/formats/engrams/scenarios/team_meeting/team_standup_meeting.yaml
324
+
325
+ # Try domain-specific examples (use --user-id for multi-tenant scenarios)
326
+ rem db load --file datasets/domains/recruitment/scenarios/candidate_pipeline/data.yaml --user-id acme-corp
327
+ ```
251
328
 
252
329
  ## See Also
253
330
 
254
331
  - [REM Query Dialect](#rem-query-dialect) - LOOKUP, SEARCH, TRAVERSE, SQL query types
255
332
  - [API Endpoints](#api-endpoints) - OpenAI-compatible chat completions, MCP server
256
333
  - [CLI Reference](#cli-reference) - Complete command-line interface documentation
334
+ - [Bring Your Own Agent](#bring-your-own-agent) - Create custom agents with your own prompts and tools
257
335
  - [Production Deployment](#production-deployment) - AWS EKS with Kubernetes
336
+ - [Example Datasets](https://github.com/Percolation-Labs/remstack-lab) - Curated datasets by domain and format
337
+
338
+ ---
339
+
340
+ ## Bring Your Own Agent
341
+
342
+ REM allows you to create **custom agents** with your own system prompts, tools, and output schemas. Custom agents are stored in the database and dynamically loaded when referenced, enabling **no-code agent creation** without modifying the codebase.
343
+
344
+ ### How It Works
345
+
346
+ 1. **Define Agent Schema** - Create a YAML file with your agent's prompt, tools, and output structure
347
+ 2. **Ingest Schema** - Use `rem process ingest` to store the schema in the database
348
+ 3. **Use Your Agent** - Reference your agent by name with `rem ask <agent-name> "query"`
349
+
350
+ When you run `rem ask my-agent "query"`, REM:
351
+ 1. Checks if `my-agent` exists in the filesystem (`schemas/agents/`)
352
+ 2. If not found, performs a **LOOKUP** query on the `schemas` table in the database
353
+ 3. Loads the schema dynamically and creates a Pydantic AI agent
354
+ 4. Runs your query with the custom agent
355
+
356
+ ### Expected Behavior
357
+
358
+ **Schema Ingestion Flow** (`rem process ingest my-agent.yaml`):
359
+ - Parse YAML file to extract JSON Schema content
360
+ - Extract `json_schema_extra.kind` field → maps to `category` column
361
+ - Extract `json_schema_extra.provider_configs` → stores provider configurations
362
+ - Extract `json_schema_extra.embedding_fields` → stores semantic search fields
363
+ - Create `Schema` entity in `schemas` table with `user_id` scoping
364
+ - Schema is now queryable via `LOOKUP "my-agent" FROM schemas`
365
+
366
+ **Agent Loading Flow** (`rem ask my-agent "query"`):
367
+ 1. `load_agent_schema("my-agent")` checks filesystem cache → miss
368
+ 2. Falls back to database: `LOOKUP "my-agent" FROM schemas WHERE user_id = '<user-id>'`
369
+ 3. Returns `Schema.spec` (JSON Schema dict) from database
370
+ 4. `create_agent()` factory creates Pydantic AI agent from schema
371
+ 5. Agent runs with tools specified in `json_schema_extra.tools`
372
+ 6. Returns structured output defined in `properties` field
373
+
374
+ ### Quick Example
375
+
376
+ **Step 1: Create Agent Schema** (`my-research-assistant.yaml`)
377
+
378
+ ```yaml
379
+ type: object
380
+ description: |
381
+ You are a research assistant that helps users find and analyze documents.
382
+
383
+ Use the search_rem tool to find relevant documents, then analyze and summarize them.
384
+ Be concise and cite specific documents in your responses.
385
+
386
+ properties:
387
+ summary:
388
+ type: string
389
+ description: A concise summary of findings
390
+ sources:
391
+ type: array
392
+ items:
393
+ type: string
394
+ description: List of document labels referenced
395
+
396
+ required:
397
+ - summary
398
+ - sources
399
+
400
+ json_schema_extra:
401
+ kind: agent
402
+ name: research-assistant
403
+ version: 1.0.0
404
+ tools:
405
+ - search_rem
406
+ - ask_rem_agent
407
+ resources: []
408
+ ```
409
+
410
+ **For more examples**, see:
411
+ - Simple agent (no tools): `src/rem/schemas/agents/examples/simple.yaml`
412
+ - Agent with REM tools: `src/rem/schemas/agents/core/rem-query-agent.yaml`
413
+ - Ontology extractor: `src/rem/schemas/agents/examples/cv-parser.yaml`
414
+
415
+ **Step 2: Ingest Schema into Database**
416
+
417
+ ```bash
418
+ # Ingest the schema (stores in database schemas table)
419
+ rem process ingest my-research-assistant.yaml \
420
+ --category agents \
421
+ --tags custom,research
422
+
423
+ # Verify schema is in database (should show schema details)
424
+ rem ask "LOOKUP 'my-research-assistant' FROM schemas"
425
+ ```
426
+
427
+ **Step 3: Use Your Custom Agent**
428
+
429
+ ```bash
430
+ # Run a query with your custom agent
431
+ rem ask research-assistant "Find documents about machine learning architecture"
432
+
433
+ # With streaming
434
+ rem ask research-assistant "Summarize recent API design documents" --stream
435
+
436
+ # With session continuity
437
+ rem ask research-assistant "What did we discuss about ML?" --session-id abc-123
438
+ ```
439
+
440
+ ### Agent Schema Structure
441
+
442
+ Every agent schema must include:
443
+
444
+ **Required Fields:**
445
+ - `type: object` - JSON Schema type (always "object")
446
+ - `description` - System prompt with instructions for the agent
447
+ - `properties` - Output schema defining structured response fields
448
+
449
+ **Optional Metadata** (`json_schema_extra`):
450
+ - `kind` - Agent category ("agent", "evaluator", etc.) → maps to `Schema.category`
451
+ - `name` - Agent identifier (used for LOOKUP)
452
+ - `version` - Semantic version (e.g., "1.0.0")
453
+ - `tools` - List of MCP tools to load (e.g., `["search_rem", "lookup_rem"]`)
454
+ - `resources` - List of MCP resources to expose (e.g., `["user_profile"]`)
455
+ - `provider_configs` - Multi-provider testing configurations (for ontology extractors)
456
+ - `embedding_fields` - Fields to embed for semantic search (for ontology extractors)
457
+
458
+ ### Available MCP Tools
459
+
460
+ REM provides **4 built-in MCP tools** your agents can use:
461
+
462
+ | Tool | Purpose | Parameters |
463
+ |------|---------|------------|
464
+ | `search_rem` | Execute REM queries (LOOKUP, FUZZY, SEARCH, SQL, TRAVERSE) | `query_type`, `entity_key`, `query_text`, `table`, `sql_query`, `initial_query`, `edge_types`, `depth` |
465
+ | `ask_rem_agent` | Natural language to REM query via agent-driven reasoning | `query`, `agent_schema`, `agent_version` |
466
+ | `ingest_into_rem` | Full file ingestion pipeline (read → store → parse → chunk → embed) | `file_uri`, `category`, `tags`, `is_local_server` |
467
+ | `read_resource` | Access MCP resources (schemas, status) for Claude Desktop | `uri` |
468
+
469
+ **Tool Reference**: Tools are defined in `src/rem/api/mcp_router/tools.py`
470
+
471
+ **Note**: `search_rem` is a unified tool that handles all REM query types via the `query_type` parameter:
472
+ - `query_type="lookup"` - O(1) entity lookup by label
473
+ - `query_type="fuzzy"` - Fuzzy text matching with similarity threshold
474
+ - `query_type="search"` - Semantic vector search (table-specific)
475
+ - `query_type="sql"` - Direct SQL queries (WHERE clause)
476
+ - `query_type="traverse"` - Graph traversal with depth control
258
477
 
259
- **Sample Data**: Test data with users, resources, and moments is at `tests/data/seed/test-user-data.yaml`
478
+ ### Multi-User Isolation
479
+
480
+ Custom agents are **scoped by `user_id`**, ensuring complete data isolation:
481
+
482
+ ```bash
483
+ # User A creates a custom agent
484
+ rem process ingest my-agent.yaml --user-id user-a --category agents
485
+
486
+ # User B cannot see User A's agent
487
+ rem ask my-agent "test" --user-id user-b
488
+ # ❌ Error: Schema not found (LOOKUP returns no results for user-b)
489
+
490
+ # User A can use their agent
491
+ rem ask my-agent "test" --user-id user-a
492
+ # ✅ Works - LOOKUP finds schema for user-a
493
+ ```
494
+
495
+ ### Advanced: Ontology Extractors
496
+
497
+ Custom agents can also be used as **ontology extractors** to extract structured knowledge from files. See [CLAUDE.md](../CLAUDE.md#ontology-extraction-pattern) for details on:
498
+ - Multi-provider testing (`provider_configs`)
499
+ - Semantic search configuration (`embedding_fields`)
500
+ - File matching rules (`OntologyConfig`)
501
+ - Dreaming workflow integration
502
+
503
+ ### Troubleshooting
504
+
505
+ **Schema not found error:**
506
+ ```bash
507
+ # Check if schema was ingested correctly
508
+ rem ask "SEARCH 'my-agent' FROM schemas"
509
+
510
+ # List all schemas
511
+ rem ask "SELECT name, category, created_at FROM schemas ORDER BY created_at DESC LIMIT 10"
512
+ ```
513
+
514
+ **Agent not loading tools:**
515
+ - Verify `json_schema_extra.tools` lists correct tool names
516
+ - Valid tool names: `search_rem`, `ask_rem_agent`, `ingest_into_rem`, `read_resource`
517
+ - Check MCP tool names in `src/rem/api/mcp_router/tools.py`
518
+ - Tools are case-sensitive: use `search_rem`, not `Search_REM`
519
+
520
+ **Agent not returning structured output:**
521
+ - Ensure `properties` field defines all expected output fields
522
+ - Use `required` field to mark mandatory fields
523
+ - Check agent response with `--stream` disabled to see full JSON output
260
524
 
261
525
  ---
262
526
 
@@ -269,15 +533,15 @@ REM provides a custom query language designed for **LLM-driven iterated retrieva
269
533
  Unlike traditional single-shot SQL queries, the REM dialect is optimized for **multi-turn exploration** where LLMs participate in query planning:
270
534
 
271
535
  - **Iterated Queries**: Queries return partial results that LLMs use to refine subsequent queries
272
- - **Composable WITH Syntax**: Chain operations together (e.g., `TRAVERSE FROM ... WITH LOOKUP "..."`)
536
+ - **Composable WITH Syntax**: Chain operations together (e.g., `TRAVERSE edge_type WITH LOOKUP "..."`)
273
537
  - **Mixed Indexes**: Combines exact lookups (O(1)), semantic search (vector), and graph traversal
274
538
  - **Query Planner Participation**: Results include metadata for LLMs to decide next steps
275
539
 
276
540
  **Example Multi-Turn Flow**:
277
541
  ```
278
542
  Turn 1: LOOKUP "sarah-chen" → Returns entity + available edge types
279
- Turn 2: TRAVERSE FROM "sarah-chen" TYPE "authored_by" DEPTH 1 → Returns connected documents
280
- Turn 3: SEARCH "architecture decisions" WITH TRAVERSE FROM "sarah-chen" Combines semantic + graph
543
+ Turn 2: TRAVERSE authored_by WITH LOOKUP "sarah-chen" DEPTH 1 → Returns connected documents
544
+ Turn 3: SEARCH "architecture decisions" Semantic search, then explore graph from results
281
545
  ```
282
546
 
283
547
  This enables LLMs to **progressively build context** rather than requiring perfect queries upfront.
@@ -330,8 +594,8 @@ SEARCH "contract disputes" FROM resources WHERE tags @> ARRAY['legal'] LIMIT 5
330
594
  Follow `graph_edges` relationships across the knowledge graph.
331
595
 
332
596
  ```sql
333
- TRAVERSE FROM "sarah-chen" TYPE "authored_by" DEPTH 2
334
- TRAVERSE FROM "api-design-v2" TYPE "references,depends_on" DEPTH 3
597
+ TRAVERSE authored_by WITH LOOKUP "sarah-chen" DEPTH 2
598
+ TRAVERSE references,depends_on WITH LOOKUP "api-design-v2" DEPTH 3
335
599
  ```
336
600
 
337
601
  **Features**:
@@ -424,7 +688,7 @@ SEARCH "API migration planning" FROM resources LIMIT 5
424
688
  LOOKUP "tidb-migration-spec" FROM resources
425
689
 
426
690
  # Query 3: Find related people
427
- TRAVERSE FROM "tidb-migration-spec" TYPE "authored_by,reviewed_by" DEPTH 1
691
+ TRAVERSE authored_by,reviewed_by WITH LOOKUP "tidb-migration-spec" DEPTH 1
428
692
 
429
693
  # Query 4: Recent activity
430
694
  SELECT * FROM moments WHERE
@@ -441,7 +705,7 @@ All queries automatically scoped by `user_id` for complete data isolation:
441
705
  SEARCH "contracts" FROM resources LIMIT 10
442
706
 
443
707
  -- No cross-user data leakage
444
- TRAVERSE FROM "project-x" TYPE "references" DEPTH 3
708
+ TRAVERSE references WITH LOOKUP "project-x" DEPTH 3
445
709
  ```
446
710
 
447
711
  ## API Endpoints
@@ -637,20 +901,21 @@ rem db rebuild-cache
637
901
 
638
902
  #### `rem db schema generate` - Generate SQL Schema
639
903
 
640
- Generate database schema from Pydantic models.
904
+ Generate database schema from Pydantic models. Output goes directly to the migrations folder.
641
905
 
642
906
  ```bash
643
- # Generate install_models.sql from entity models
644
- rem db schema generate \
645
- --models src/rem/models/entities \
646
- --output rem/src/rem/sql/install_models.sql
907
+ # Generate 002_install_models.sql from entity models (default)
908
+ rem db schema generate --models src/rem/models/entities
647
909
 
648
- # Generate migration file
649
- rem db schema generate \
650
- --models src/rem/models/entities \
651
- --output rem/src/rem/sql/migrations/003_add_fields.sql
910
+ # This writes to: src/rem/sql/migrations/002_install_models.sql
911
+ # Then apply with: rem db migrate
652
912
  ```
653
913
 
914
+ **Workflow for adding new models:**
915
+ 1. Add/modify models in `src/rem/models/entities/`
916
+ 2. Run `rem db schema generate -m src/rem/models/entities`
917
+ 3. Run `rem db migrate` to apply changes
918
+
654
919
  #### `rem db schema indexes` - Generate Background Indexes
655
920
 
656
921
  Generate SQL for background index creation (HNSW for vectors).
@@ -677,22 +942,14 @@ rem db schema validate --models src/rem/models/entities
677
942
  Process files with optional custom extractor (ontology extraction).
678
943
 
679
944
  ```bash
680
- # Process all completed files for tenant
681
- rem process files \
682
- --tenant-id acme-corp \
683
- --status completed \
684
- --limit 10
945
+ # Process all completed files
946
+ rem process files --status completed --limit 10
685
947
 
686
948
  # Process with custom extractor
687
- rem process files \
688
- --tenant-id acme-corp \
689
- --extractor cv-parser-v1 \
690
- --limit 50
949
+ rem process files --extractor cv-parser-v1 --limit 50
691
950
 
692
- # Process files from the last 7 days
693
- rem process files \
694
- --tenant-id acme-corp \
695
- --lookback-hours 168
951
+ # Process files for specific user
952
+ rem process files --user-id user-123 --status completed
696
953
  ```
697
954
 
698
955
  #### `rem process ingest` - Ingest File into REM
@@ -700,14 +957,13 @@ rem process files \
700
957
  Ingest a file into REM with full pipeline (storage + parsing + embedding + database).
701
958
 
702
959
  ```bash
703
- # Ingest local file
960
+ # Ingest local file with metadata
704
961
  rem process ingest /path/to/document.pdf \
705
- --user-id user-123 \
706
962
  --category legal \
707
963
  --tags contract,2024
708
964
 
709
965
  # Ingest with minimal options
710
- rem process ingest ./meeting-notes.md --user-id user-123
966
+ rem process ingest ./meeting-notes.md
711
967
  ```
712
968
 
713
969
  #### `rem process uri` - Parse File (Read-Only)
@@ -732,28 +988,17 @@ rem process uri s3://bucket/key.docx --output text
732
988
  Run full dreaming workflow: extractors → moments → affinity → user model.
733
989
 
734
990
  ```bash
735
- # Full workflow for user
736
- rem dreaming full \
737
- --user-id user-123 \
738
- --tenant-id acme-corp
991
+ # Full workflow (uses default user from settings)
992
+ rem dreaming full
739
993
 
740
994
  # Skip ontology extractors
741
- rem dreaming full \
742
- --user-id user-123 \
743
- --tenant-id acme-corp \
744
- --skip-extractors
995
+ rem dreaming full --skip-extractors
745
996
 
746
997
  # Process last 24 hours only
747
- rem dreaming full \
748
- --user-id user-123 \
749
- --tenant-id acme-corp \
750
- --lookback-hours 24
998
+ rem dreaming full --lookback-hours 24
751
999
 
752
- # Limit resources processed
753
- rem dreaming full \
754
- --user-id user-123 \
755
- --tenant-id acme-corp \
756
- --limit 100
1000
+ # Limit resources processed for specific user
1001
+ rem dreaming full --user-id user-123 --limit 100
757
1002
  ```
758
1003
 
759
1004
  #### `rem dreaming custom` - Custom Extractor
@@ -761,16 +1006,11 @@ rem dreaming full \
761
1006
  Run specific ontology extractor on user's data.
762
1007
 
763
1008
  ```bash
764
- # Run CV parser on user's files
765
- rem dreaming custom \
766
- --user-id user-123 \
767
- --tenant-id acme-corp \
768
- --extractor cv-parser-v1
1009
+ # Run CV parser on files
1010
+ rem dreaming custom --extractor cv-parser-v1
769
1011
 
770
- # Process last week's files
1012
+ # Process last week's files with limit
771
1013
  rem dreaming custom \
772
- --user-id user-123 \
773
- --tenant-id acme-corp \
774
1014
  --extractor contract-analyzer-v1 \
775
1015
  --lookback-hours 168 \
776
1016
  --limit 50
@@ -781,17 +1021,11 @@ rem dreaming custom \
781
1021
  Extract temporal narratives from resources.
782
1022
 
783
1023
  ```bash
784
- # Generate moments for user
785
- rem dreaming moments \
786
- --user-id user-123 \
787
- --tenant-id acme-corp \
788
- --limit 50
1024
+ # Generate moments
1025
+ rem dreaming moments --limit 50
789
1026
 
790
1027
  # Process last 7 days
791
- rem dreaming moments \
792
- --user-id user-123 \
793
- --tenant-id acme-corp \
794
- --lookback-hours 168
1028
+ rem dreaming moments --lookback-hours 168
795
1029
  ```
796
1030
 
797
1031
  #### `rem dreaming affinity` - Build Relationships
@@ -799,17 +1033,11 @@ rem dreaming moments \
799
1033
  Build semantic relationships between resources using embeddings.
800
1034
 
801
1035
  ```bash
802
- # Build affinity graph for user
803
- rem dreaming affinity \
804
- --user-id user-123 \
805
- --tenant-id acme-corp \
806
- --limit 100
1036
+ # Build affinity graph
1037
+ rem dreaming affinity --limit 100
807
1038
 
808
1039
  # Process recent resources only
809
- rem dreaming affinity \
810
- --user-id user-123 \
811
- --tenant-id acme-corp \
812
- --lookback-hours 24
1040
+ rem dreaming affinity --lookback-hours 24
813
1041
  ```
814
1042
 
815
1043
  #### `rem dreaming user-model` - Update User Model
@@ -818,9 +1046,7 @@ Update user model from recent activity (preferences, interests, patterns).
818
1046
 
819
1047
  ```bash
820
1048
  # Update user model
821
- rem dreaming user-model \
822
- --user-id user-123 \
823
- --tenant-id acme-corp
1049
+ rem dreaming user-model
824
1050
  ```
825
1051
 
826
1052
  ### Evaluation & Experiments
@@ -1071,6 +1297,30 @@ S3__BUCKET_NAME=rem-storage
1071
1297
  S3__REGION=us-east-1
1072
1298
  ```
1073
1299
 
1300
+ ### Building Docker Images
1301
+
1302
+ We tag Docker images with three labels for traceability:
1303
+ 1. `latest` - Always points to most recent build
1304
+ 2. `<git-sha>` - Short commit hash for exact version tracing
1305
+ 3. `<version>` - Semantic version from `pyproject.toml`
1306
+
1307
+ ```bash
1308
+ # Build and push multi-platform image to Docker Hub
1309
+ VERSION=$(grep '^version' pyproject.toml | cut -d'"' -f2) && \
1310
+ docker buildx build --platform linux/amd64,linux/arm64 \
1311
+ -t percolationlabs/rem:latest \
1312
+ -t percolationlabs/rem:$(git rev-parse --short HEAD) \
1313
+ -t percolationlabs/rem:$VERSION \
1314
+ --push \
1315
+ -f Dockerfile .
1316
+
1317
+ # Load locally for testing (single platform, no push)
1318
+ docker buildx build --platform linux/arm64 \
1319
+ -t percolationlabs/rem:latest \
1320
+ --load \
1321
+ -f Dockerfile .
1322
+ ```
1323
+
1074
1324
  ### Production Deployment (Optional)
1075
1325
 
1076
1326
  For production deployment to AWS EKS with Kubernetes, see the main repository README:
@@ -1186,6 +1436,110 @@ TraverseQuery ::= TRAVERSE [<edge_types:list>] WITH <initial_query:Query> [DEPTH
1186
1436
 
1187
1437
  **Stage 4** (100% answerable): Mature graph with rich historical data. All query types fully functional with high-quality results.
1188
1438
 
1439
+ ## Troubleshooting
1440
+
1441
+ ### Apple Silicon Mac: "Failed to build kreuzberg" Error
1442
+
1443
+ **Problem**: Installation fails with `ERROR: Failed building wheel for kreuzberg` on Apple Silicon Macs.
1444
+
1445
+ **Root Cause**: REM uses `kreuzberg>=4.0.0rc1` for document parsing with native ONNX/Rust table extraction. Kreuzberg 4.0.0rc1 provides pre-built wheels for ARM64 macOS (`macosx_14_0_arm64.whl`) but NOT for x86_64 (Intel) macOS. If you're using an x86_64 Python binary (running under Rosetta 2), pip cannot find a compatible wheel and attempts to build from source, which fails.
1446
+
1447
+ **Solution**: Use ARM64 (native) Python instead of x86_64 Python.
1448
+
1449
+ **Step 1: Verify your Python architecture**
1450
+
1451
+ ```bash
1452
+ python3 -c "import platform; print(f'Machine: {platform.machine()}')"
1453
+ ```
1454
+
1455
+ - **Correct**: `Machine: arm64` (native ARM Python)
1456
+ - **Wrong**: `Machine: x86_64` (Intel Python under Rosetta)
1457
+
1458
+ **Step 2: Install ARM Python via Homebrew** (if not already installed)
1459
+
1460
+ ```bash
1461
+ # Install ARM Python
1462
+ brew install python@3.12
1463
+
1464
+ # Verify it's ARM
1465
+ /opt/homebrew/bin/python3.12 -c "import platform; print(platform.machine())"
1466
+ # Should output: arm64
1467
+ ```
1468
+
1469
+ **Step 3: Create venv with ARM Python**
1470
+
1471
+ ```bash
1472
+ # Use full path to ARM Python
1473
+ /opt/homebrew/bin/python3.12 -m venv .venv
1474
+
1475
+ # Activate and install
1476
+ source .venv/bin/activate
1477
+ pip install "remdb[all]"
1478
+ ```
1479
+
1480
+ **Why This Happens**: Some users have both Intel Homebrew (`/usr/local`) and ARM Homebrew (`/opt/homebrew`) installed. If your system `python3` points to the Intel version at `/usr/local/bin/python3`, you'll hit this issue. The fix is to explicitly use the ARM Python from `/opt/homebrew/bin/python3.12`.
1481
+
1482
+ **Verification**: After successful installation, you should see:
1483
+ ```
1484
+ Using cached kreuzberg-4.0.0rc1-cp310-abi3-macosx_14_0_arm64.whl (19.8 MB)
1485
+ Successfully installed ... kreuzberg-4.0.0rc1 ... remdb-0.3.10
1486
+ ```
1487
+
1488
+ ## Using REM as a Library
1489
+
1490
+ REM wraps FastAPI - extend it exactly as you would any FastAPI app.
1491
+
1492
+ ```python
1493
+ import rem
1494
+ from rem import create_app
1495
+ from rem.models.core import CoreModel
1496
+
1497
+ # 1. Register models (for schema generation)
1498
+ rem.register_models(MyModel, AnotherModel)
1499
+
1500
+ # 2. Register schema paths (for custom agents/evaluators)
1501
+ rem.register_schema_path("./schemas")
1502
+
1503
+ # 3. Create app
1504
+ app = create_app()
1505
+
1506
+ # 4. Extend like normal FastAPI
1507
+ app.include_router(my_router)
1508
+
1509
+ @app.mcp_server.tool()
1510
+ async def my_tool(query: str) -> dict:
1511
+ """Custom MCP tool."""
1512
+ return {"result": query}
1513
+ ```
1514
+
1515
+ ### Project Structure
1516
+
1517
+ ```
1518
+ my-rem-app/
1519
+ ├── my_app/
1520
+ │ ├── main.py # Entry point (create_app + extensions)
1521
+ │ ├── models.py # Custom models (inherit CoreModel)
1522
+ │ └── routers/ # Custom FastAPI routers
1523
+ ├── schemas/
1524
+ │ ├── agents/ # Custom agent YAML schemas
1525
+ │ └── evaluators/ # Custom evaluator schemas
1526
+ ├── sql/migrations/ # Custom SQL migrations
1527
+ └── pyproject.toml
1528
+ ```
1529
+
1530
+ Generate this structure with: `rem scaffold my-app`
1531
+
1532
+ ### Extension Points
1533
+
1534
+ | Extension | How |
1535
+ |-----------|-----|
1536
+ | **Routes** | `app.include_router(router)` or `@app.get()` |
1537
+ | **MCP Tools** | `@app.mcp_server.tool()` decorator or `app.mcp_server.add_tool(fn)` |
1538
+ | **MCP Resources** | `@app.mcp_server.resource("uri://...")` or `app.mcp_server.add_resource(fn)` |
1539
+ | **MCP Prompts** | `@app.mcp_server.prompt()` or `app.mcp_server.add_prompt(fn)` |
1540
+ | **Models** | `rem.register_models(Model)` then `rem db schema generate` |
1541
+ | **Agent Schemas** | `rem.register_schema_path("./schemas")` or `SCHEMA__PATHS` env var |
1542
+
1189
1543
  ## License
1190
1544
 
1191
1545
  MIT