remdb 0.3.7__py3-none-any.whl → 0.3.133__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.
- rem/__init__.py +129 -2
- rem/agentic/README.md +76 -0
- rem/agentic/__init__.py +15 -0
- rem/agentic/agents/__init__.py +16 -2
- rem/agentic/agents/sse_simulator.py +502 -0
- rem/agentic/context.py +51 -25
- rem/agentic/llm_provider_models.py +301 -0
- rem/agentic/mcp/tool_wrapper.py +112 -17
- rem/agentic/otel/setup.py +93 -4
- rem/agentic/providers/phoenix.py +314 -132
- rem/agentic/providers/pydantic_ai.py +215 -26
- rem/agentic/schema.py +361 -21
- rem/agentic/tools/rem_tools.py +3 -3
- rem/api/README.md +238 -1
- rem/api/deps.py +255 -0
- rem/api/main.py +154 -37
- rem/api/mcp_router/resources.py +1 -1
- rem/api/mcp_router/server.py +26 -5
- rem/api/mcp_router/tools.py +465 -7
- rem/api/middleware/tracking.py +172 -0
- rem/api/routers/admin.py +494 -0
- rem/api/routers/auth.py +124 -0
- rem/api/routers/chat/completions.py +402 -20
- rem/api/routers/chat/models.py +88 -10
- rem/api/routers/chat/otel_utils.py +33 -0
- rem/api/routers/chat/sse_events.py +542 -0
- rem/api/routers/chat/streaming.py +642 -45
- rem/api/routers/dev.py +81 -0
- rem/api/routers/feedback.py +268 -0
- rem/api/routers/messages.py +473 -0
- rem/api/routers/models.py +78 -0
- rem/api/routers/query.py +360 -0
- rem/api/routers/shared_sessions.py +406 -0
- rem/auth/middleware.py +126 -27
- rem/cli/commands/README.md +237 -64
- rem/cli/commands/ask.py +13 -10
- rem/cli/commands/cluster.py +1808 -0
- rem/cli/commands/configure.py +5 -6
- rem/cli/commands/db.py +396 -139
- rem/cli/commands/experiments.py +469 -74
- rem/cli/commands/process.py +22 -15
- rem/cli/commands/scaffold.py +47 -0
- rem/cli/commands/schema.py +97 -50
- rem/cli/main.py +29 -6
- rem/config.py +10 -3
- rem/models/core/core_model.py +7 -1
- rem/models/core/experiment.py +54 -0
- rem/models/core/rem_query.py +5 -2
- rem/models/entities/__init__.py +21 -0
- rem/models/entities/domain_resource.py +38 -0
- rem/models/entities/feedback.py +123 -0
- rem/models/entities/message.py +30 -1
- rem/models/entities/session.py +83 -0
- rem/models/entities/shared_session.py +180 -0
- rem/models/entities/user.py +10 -3
- rem/registry.py +373 -0
- rem/schemas/agents/rem.yaml +7 -3
- rem/services/content/providers.py +92 -133
- rem/services/content/service.py +92 -20
- rem/services/dreaming/affinity_service.py +2 -16
- rem/services/dreaming/moment_service.py +2 -15
- rem/services/embeddings/api.py +24 -17
- rem/services/embeddings/worker.py +16 -16
- rem/services/phoenix/EXPERIMENT_DESIGN.md +3 -3
- rem/services/phoenix/client.py +302 -28
- rem/services/postgres/README.md +159 -15
- rem/services/postgres/__init__.py +2 -1
- rem/services/postgres/diff_service.py +531 -0
- rem/services/postgres/pydantic_to_sqlalchemy.py +427 -129
- rem/services/postgres/repository.py +132 -0
- rem/services/postgres/schema_generator.py +291 -9
- rem/services/postgres/service.py +6 -6
- rem/services/rate_limit.py +113 -0
- rem/services/rem/README.md +14 -0
- rem/services/rem/parser.py +44 -9
- rem/services/rem/service.py +36 -2
- rem/services/session/compression.py +24 -1
- rem/services/session/reload.py +1 -1
- rem/services/user_service.py +98 -0
- rem/settings.py +399 -29
- rem/sql/background_indexes.sql +21 -16
- rem/sql/migrations/001_install.sql +387 -54
- rem/sql/migrations/002_install_models.sql +2320 -393
- rem/sql/migrations/003_optional_extensions.sql +326 -0
- rem/sql/migrations/004_cache_system.sql +548 -0
- rem/utils/__init__.py +18 -0
- rem/utils/constants.py +97 -0
- rem/utils/date_utils.py +228 -0
- rem/utils/embeddings.py +17 -4
- rem/utils/files.py +167 -0
- rem/utils/mime_types.py +158 -0
- rem/utils/model_helpers.py +156 -1
- rem/utils/schema_loader.py +282 -35
- rem/utils/sql_paths.py +146 -0
- rem/utils/sql_types.py +3 -1
- rem/utils/vision.py +9 -14
- rem/workers/README.md +14 -14
- rem/workers/__init__.py +3 -1
- rem/workers/db_listener.py +579 -0
- rem/workers/db_maintainer.py +74 -0
- rem/workers/unlogged_maintainer.py +463 -0
- {remdb-0.3.7.dist-info → remdb-0.3.133.dist-info}/METADATA +460 -303
- {remdb-0.3.7.dist-info → remdb-0.3.133.dist-info}/RECORD +105 -74
- {remdb-0.3.7.dist-info → remdb-0.3.133.dist-info}/WHEEL +1 -1
- rem/sql/002_install_models.sql +0 -1068
- rem/sql/install_models.sql +0 -1038
- {remdb-0.3.7.dist-info → remdb-0.3.133.dist-info}/entry_points.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: remdb
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.133
|
|
4
4
|
Summary: Resources Entities Moments - Bio-inspired memory system for agentic AI workloads
|
|
5
5
|
Project-URL: Homepage, https://github.com/Percolation-Labs/reminiscent
|
|
6
6
|
Project-URL: Documentation, https://github.com/Percolation-Labs/reminiscent/blob/main/README.md
|
|
@@ -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
|
|
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
|
|
@@ -48,7 +47,6 @@ Requires-Dist: requests>=2.32.0
|
|
|
48
47
|
Requires-Dist: semchunk>=2.2.0
|
|
49
48
|
Requires-Dist: tenacity>=9.0.0
|
|
50
49
|
Requires-Dist: tiktoken>=0.5.0
|
|
51
|
-
Requires-Dist: torch>=2.0.0
|
|
52
50
|
Requires-Dist: uvicorn[standard]>=0.32.0
|
|
53
51
|
Provides-Extra: all
|
|
54
52
|
Requires-Dist: ipdb>=0.13.0; extra == 'all'
|
|
@@ -103,32 +101,30 @@ Cloud-native unified memory infrastructure for agentic AI systems built with Pyd
|
|
|
103
101
|
- **Database Layer**: PostgreSQL 18 with pgvector for multi-index memory (KV + Vector + Graph)
|
|
104
102
|
- **REM Query Dialect**: Custom query language with O(1) lookups, semantic search, graph traversal
|
|
105
103
|
- **Ingestion & Dreaming**: Background workers for content extraction and progressive index enrichment (0% → 100% answerable)
|
|
106
|
-
- **Observability & Evals**: OpenTelemetry tracing
|
|
104
|
+
- **Observability & Evals**: OpenTelemetry tracing supporting LLM-as-a-Judge evaluation frameworks
|
|
107
105
|
|
|
108
106
|
## Features
|
|
109
107
|
|
|
110
108
|
| Feature | Description | Benefits |
|
|
111
109
|
|---------|-------------|----------|
|
|
112
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.) |
|
|
113
|
-
| **Built-in MCP Server** | FastMCP server with 4 tools +
|
|
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 |
|
|
114
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 |
|
|
115
113
|
| **Dreaming Workers** | Background workers for entity extraction, moment generation, and affinity matching | Automatic knowledge graph construction from resources (0% → 100% query answerable) |
|
|
116
114
|
| **PostgreSQL + pgvector** | CloudNativePG with PostgreSQL 18, pgvector extension, streaming replication | Production-ready vector search, no external vector DB needed |
|
|
117
115
|
| **AWS EKS Recipe** | Complete infrastructure-as-code with Pulumi, Karpenter, ArgoCD | Deploy to production EKS in minutes with auto-scaling and GitOps |
|
|
118
116
|
| **JSON Schema Agents** | Dynamic agent creation from YAML schemas via Pydantic AI factory | Define agents declaratively, version control schemas, load dynamically |
|
|
119
|
-
| **Content Providers** | Audio transcription (Whisper), vision (
|
|
120
|
-
| **Configurable Embeddings** |
|
|
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 |
|
|
121
119
|
| **Multi-Tenancy** | Tenant isolation at database level with automatic scoping | SaaS-ready with complete data separation per tenant |
|
|
122
|
-
| **Streaming Everything** | SSE for chat, background workers for embeddings, async throughout | Real-time responses, non-blocking operations, scalable |
|
|
123
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 |
|
|
124
121
|
|
|
125
122
|
## Quick Start
|
|
126
123
|
|
|
127
124
|
Choose your path:
|
|
128
125
|
|
|
129
|
-
- **Option 1: Package Users with Example Data** (Recommended
|
|
130
|
-
- **Option 2:
|
|
131
|
-
- **Option 3: Developers** - Clone repo, local development with uv
|
|
126
|
+
- **Option 1: Package Users with Example Data** (Recommended) - PyPI + example datasets
|
|
127
|
+
- **Option 2: Developers** - Clone repo, local development with uv
|
|
132
128
|
|
|
133
129
|
---
|
|
134
130
|
|
|
@@ -137,186 +133,78 @@ Choose your path:
|
|
|
137
133
|
**Best for**: First-time users who want to explore REM with curated example datasets.
|
|
138
134
|
|
|
139
135
|
```bash
|
|
140
|
-
# Install system dependencies
|
|
141
|
-
# macOS:
|
|
142
|
-
brew install tesseract
|
|
143
|
-
|
|
144
|
-
# Linux:
|
|
145
|
-
sudo apt-get install tesseract-ocr
|
|
136
|
+
# Install system dependencies (tesseract for OCR)
|
|
137
|
+
brew install tesseract # macOS (Linux/Windows: see tesseract-ocr.github.io)
|
|
146
138
|
|
|
147
139
|
# Install remdb
|
|
148
|
-
pip install remdb[all]
|
|
140
|
+
pip install "remdb[all]"
|
|
149
141
|
|
|
150
142
|
# Clone example datasets
|
|
151
143
|
git clone https://github.com/Percolation-Labs/remstack-lab.git
|
|
152
144
|
cd remstack-lab
|
|
153
145
|
|
|
154
|
-
#
|
|
155
|
-
|
|
146
|
+
# Start PostgreSQL with docker-compose
|
|
147
|
+
curl -O https://gist.githubusercontent.com/percolating-sirsh/d117b673bc0edfdef1a5068ccd3cf3e5/raw/docker-compose.prebuilt.yml
|
|
148
|
+
docker compose -f docker-compose.prebuilt.yml up -d postgres
|
|
156
149
|
|
|
157
|
-
#
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
-e POSTGRES_USER=rem \
|
|
161
|
-
-e POSTGRES_PASSWORD=rem \
|
|
162
|
-
-e POSTGRES_DB=rem \
|
|
163
|
-
-p 5050:5432 \
|
|
164
|
-
pgvector/pgvector:pg18
|
|
150
|
+
# Configure REM (creates ~/.rem/config.yaml and installs database schema)
|
|
151
|
+
# Add --claude-desktop to register with Claude Desktop app
|
|
152
|
+
rem configure --install --claude-desktop
|
|
165
153
|
|
|
166
154
|
# Load quickstart dataset
|
|
167
|
-
rem db load datasets/quickstart/sample_data.yaml
|
|
168
|
-
|
|
169
|
-
# Optional: Set default LLM provider via environment variable
|
|
170
|
-
# export LLM__DEFAULT_MODEL="openai:gpt-4.1-nano" # Fast and cheap
|
|
171
|
-
# export LLM__DEFAULT_MODEL="anthropic:claude-sonnet-4-5-20250929" # High quality (default)
|
|
155
|
+
rem db load datasets/quickstart/sample_data.yaml
|
|
172
156
|
|
|
173
157
|
# Ask questions
|
|
174
|
-
rem ask
|
|
175
|
-
rem ask
|
|
158
|
+
rem ask "What documents exist in the system?"
|
|
159
|
+
rem ask "Show me meetings about API design"
|
|
176
160
|
|
|
177
|
-
# Ingest files (PDF, DOCX, images, etc.)
|
|
178
|
-
rem process ingest datasets/formats/files/bitcoin_whitepaper.pdf --
|
|
161
|
+
# Ingest files (PDF, DOCX, images, etc.)
|
|
162
|
+
rem process ingest datasets/formats/files/bitcoin_whitepaper.pdf --category research --tags bitcoin,whitepaper
|
|
179
163
|
|
|
180
164
|
# Query ingested content
|
|
181
|
-
rem ask
|
|
182
|
-
|
|
183
|
-
# Try other datasets
|
|
184
|
-
rem db load --file datasets/domains/recruitment/scenarios/candidate_pipeline/data.yaml --user-id my-company
|
|
185
|
-
rem ask --user-id my-company "Show me candidates with Python experience"
|
|
165
|
+
rem ask "What is the Bitcoin whitepaper about?"
|
|
186
166
|
```
|
|
187
167
|
|
|
188
168
|
**What you get:**
|
|
189
169
|
- Quickstart: 3 users, 3 resources, 3 moments, 4 messages
|
|
190
170
|
- Domain datasets: recruitment, legal, enterprise, misc
|
|
191
171
|
- Format examples: engrams, documents, conversations, files
|
|
192
|
-
- Jupyter notebooks and experiments
|
|
193
172
|
|
|
194
173
|
**Learn more**: [remstack-lab repository](https://github.com/Percolation-Labs/remstack-lab)
|
|
195
174
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
## Option 2: Package Users (No Example Data)
|
|
175
|
+
### Using the API
|
|
199
176
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
### Step 1: Start Database and API with Docker Compose
|
|
177
|
+
Once configured, you can also use the OpenAI-compatible chat completions API:
|
|
203
178
|
|
|
204
179
|
```bash
|
|
205
|
-
#
|
|
206
|
-
mkdir my-rem-project && cd my-rem-project
|
|
207
|
-
|
|
208
|
-
# Download docker-compose file from public gist
|
|
209
|
-
curl -O https://gist.githubusercontent.com/percolating-sirsh/d117b673bc0edfdef1a5068ccd3cf3e5/raw/docker-compose.prebuilt.yml
|
|
210
|
-
|
|
211
|
-
# IMPORTANT: Export API keys BEFORE running docker compose
|
|
212
|
-
# Docker Compose reads env vars at startup - exporting them after won't work!
|
|
213
|
-
|
|
214
|
-
# Required: OpenAI for embeddings (text-embedding-3-small)
|
|
215
|
-
export OPENAI_API_KEY="sk-..."
|
|
216
|
-
|
|
217
|
-
# Recommended: At least one chat completion provider
|
|
218
|
-
export ANTHROPIC_API_KEY="sk-ant-..." # Claude Sonnet 4.5 (high quality)
|
|
219
|
-
export CEREBRAS_API_KEY="csk-..." # Cerebras (fast, cheap inference)
|
|
220
|
-
|
|
221
|
-
# Start PostgreSQL + API
|
|
180
|
+
# Start the API server (if not using docker-compose for API)
|
|
222
181
|
docker compose -f docker-compose.prebuilt.yml up -d
|
|
223
182
|
|
|
224
|
-
#
|
|
225
|
-
curl http://localhost:8000/
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
### Step 2: Install and Configure CLI (REQUIRED)
|
|
234
|
-
|
|
235
|
-
**This step is required** before you can use REM - it installs the database schema and configures your LLM API keys.
|
|
236
|
-
|
|
237
|
-
```bash
|
|
238
|
-
# Install remdb package from PyPI
|
|
239
|
-
pip install remdb[all]
|
|
240
|
-
|
|
241
|
-
# Configure REM (defaults to port 5051 for package users)
|
|
242
|
-
rem configure --install --claude-desktop
|
|
183
|
+
# Test the API
|
|
184
|
+
curl -X POST http://localhost:8000/api/v1/chat/completions \
|
|
185
|
+
-H "Content-Type: application/json" \
|
|
186
|
+
-H "X-Session-Id: a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
|
|
187
|
+
-d '{
|
|
188
|
+
"model": "anthropic:claude-sonnet-4-5-20250929",
|
|
189
|
+
"messages": [{"role": "user", "content": "What documents did Sarah Chen author?"}],
|
|
190
|
+
"stream": false
|
|
191
|
+
}'
|
|
243
192
|
```
|
|
244
193
|
|
|
245
|
-
The interactive wizard will:
|
|
246
|
-
1. **Configure PostgreSQL**: Defaults to `postgresql://rem:rem@localhost:5051/rem` (prebuilt docker-compose)
|
|
247
|
-
- Just press Enter to accept defaults
|
|
248
|
-
- Custom database: Enter your own host/port/credentials
|
|
249
|
-
2. **Configure LLM providers**: Enter your OpenAI/Anthropic API keys
|
|
250
|
-
3. **Install database tables**: Creates schema, functions, indexes (**required for CLI/API to work**)
|
|
251
|
-
4. **Register with Claude Desktop**: Adds REM MCP server to Claude
|
|
252
|
-
|
|
253
|
-
Configuration saved to `~/.rem/config.yaml` (can edit with `rem configure --edit`)
|
|
254
|
-
|
|
255
194
|
**Port Guide:**
|
|
256
195
|
- **5051**: Package users with `docker-compose.prebuilt.yml` (pre-built image)
|
|
257
196
|
- **5050**: Developers with `docker-compose.yml` (local build)
|
|
258
|
-
- **Custom**: Your own PostgreSQL database
|
|
259
197
|
|
|
260
198
|
**Next Steps:**
|
|
261
199
|
- See [CLI Reference](#cli-reference) for all available commands
|
|
262
200
|
- See [REM Query Dialect](#rem-query-dialect) for query examples
|
|
263
201
|
- See [API Endpoints](#api-endpoints) for OpenAI-compatible API usage
|
|
264
202
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
**Option A: Clone example datasets** (Recommended - works with all README examples)
|
|
268
|
-
|
|
269
|
-
```bash
|
|
270
|
-
# Clone datasets repository
|
|
271
|
-
git clone https://github.com/Percolation-Labs/remstack-lab.git
|
|
272
|
-
|
|
273
|
-
# Load quickstart dataset
|
|
274
|
-
rem db load --file remstack-lab/datasets/quickstart/sample_data.yaml --user-id demo-user
|
|
275
|
-
|
|
276
|
-
# Test with sample queries
|
|
277
|
-
rem ask --user-id demo-user "What documents exist in the system?"
|
|
278
|
-
rem ask --user-id demo-user "Show me meetings about API design"
|
|
279
|
-
rem ask --user-id demo-user "Who is Sarah Chen?"
|
|
280
|
-
|
|
281
|
-
# Try domain-specific datasets
|
|
282
|
-
rem db load --file remstack-lab/datasets/domains/recruitment/scenarios/candidate_pipeline/data.yaml --user-id my-company
|
|
283
|
-
rem ask --user-id my-company "Show me candidates with Python experience"
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
**Option B: Bring your own data**
|
|
287
|
-
|
|
288
|
-
```bash
|
|
289
|
-
# Ingest your own files
|
|
290
|
-
echo "REM is a bio-inspired memory system for agentic AI workloads." > test-doc.txt
|
|
291
|
-
rem process ingest test-doc.txt --user-id test-user --category documentation --tags rem,ai
|
|
292
|
-
|
|
293
|
-
# Query your ingested data
|
|
294
|
-
rem ask --user-id test-user "What do you know about REM from my knowledge base?"
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
### Step 4: Test the API
|
|
298
|
-
|
|
299
|
-
```bash
|
|
300
|
-
# Test the OpenAI-compatible chat completions API
|
|
301
|
-
curl -X POST http://localhost:8000/api/v1/chat/completions \
|
|
302
|
-
-H "Content-Type: application/json" \
|
|
303
|
-
-H "X-User-Id: demo-user" \
|
|
304
|
-
-d '{
|
|
305
|
-
"model": "anthropic:claude-sonnet-4-5-20250929",
|
|
306
|
-
"messages": [{"role": "user", "content": "What documents did Sarah Chen author?"}],
|
|
307
|
-
"stream": false
|
|
308
|
-
}'
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
**Available Commands:**
|
|
312
|
-
- `rem ask` - Natural language queries to REM
|
|
313
|
-
- `rem process ingest <file>` - Full ingestion pipeline (storage + parsing + embedding + database)
|
|
314
|
-
- `rem process uri <file>` - READ-ONLY parsing (no database storage, useful for testing parsers)
|
|
315
|
-
- `rem db load --file <yaml>` - Load structured datasets directly
|
|
203
|
+
---
|
|
316
204
|
|
|
317
205
|
## Example Datasets
|
|
318
206
|
|
|
319
|
-
|
|
207
|
+
Clone [remstack-lab](https://github.com/Percolation-Labs/remstack-lab) for curated datasets organized by domain and format.
|
|
320
208
|
|
|
321
209
|
**What's included:**
|
|
322
210
|
- **Quickstart**: Minimal dataset (3 users, 3 resources, 3 moments) - perfect for first-time users
|
|
@@ -329,13 +217,10 @@ curl -X POST http://localhost:8000/api/v1/chat/completions \
|
|
|
329
217
|
cd remstack-lab
|
|
330
218
|
|
|
331
219
|
# Load any dataset
|
|
332
|
-
rem db load --file datasets/quickstart/sample_data.yaml
|
|
220
|
+
rem db load --file datasets/quickstart/sample_data.yaml
|
|
333
221
|
|
|
334
222
|
# Explore formats
|
|
335
|
-
rem db load --file datasets/formats/engrams/scenarios/team_meeting/team_standup_meeting.yaml
|
|
336
|
-
|
|
337
|
-
# Try domain-specific examples
|
|
338
|
-
rem db load --file datasets/domains/recruitment/scenarios/candidate_pipeline/data.yaml --user-id acme-corp
|
|
223
|
+
rem db load --file datasets/formats/engrams/scenarios/team_meeting/team_standup_meeting.yaml
|
|
339
224
|
```
|
|
340
225
|
|
|
341
226
|
## See Also
|
|
@@ -429,30 +314,24 @@ json_schema_extra:
|
|
|
429
314
|
```bash
|
|
430
315
|
# Ingest the schema (stores in database schemas table)
|
|
431
316
|
rem process ingest my-research-assistant.yaml \
|
|
432
|
-
--user-id my-user \
|
|
433
317
|
--category agents \
|
|
434
318
|
--tags custom,research
|
|
435
319
|
|
|
436
320
|
# Verify schema is in database (should show schema details)
|
|
437
|
-
rem ask "LOOKUP 'my-research-assistant' FROM schemas"
|
|
321
|
+
rem ask "LOOKUP 'my-research-assistant' FROM schemas"
|
|
438
322
|
```
|
|
439
323
|
|
|
440
324
|
**Step 3: Use Your Custom Agent**
|
|
441
325
|
|
|
442
326
|
```bash
|
|
443
327
|
# Run a query with your custom agent
|
|
444
|
-
rem ask research-assistant "Find documents about machine learning architecture"
|
|
445
|
-
--user-id my-user
|
|
328
|
+
rem ask research-assistant "Find documents about machine learning architecture"
|
|
446
329
|
|
|
447
330
|
# With streaming
|
|
448
|
-
rem ask research-assistant "Summarize recent API design documents"
|
|
449
|
-
--user-id my-user \
|
|
450
|
-
--stream
|
|
331
|
+
rem ask research-assistant "Summarize recent API design documents" --stream
|
|
451
332
|
|
|
452
333
|
# With session continuity
|
|
453
|
-
rem ask research-assistant "What did we discuss about ML?"
|
|
454
|
-
--user-id my-user \
|
|
455
|
-
--session-id abc-123
|
|
334
|
+
rem ask research-assistant "What did we discuss about ML?" --session-id c3d4e5f6-a7b8-9012-cdef-345678901234
|
|
456
335
|
```
|
|
457
336
|
|
|
458
337
|
### Agent Schema Structure
|
|
@@ -495,38 +374,25 @@ REM provides **4 built-in MCP tools** your agents can use:
|
|
|
495
374
|
|
|
496
375
|
### Multi-User Isolation
|
|
497
376
|
|
|
498
|
-
|
|
377
|
+
For multi-tenant deployments, custom agents are **scoped by `user_id`**, ensuring complete data isolation. Use `--user-id` flag when you need tenant separation:
|
|
499
378
|
|
|
500
379
|
```bash
|
|
501
|
-
#
|
|
502
|
-
rem process ingest my-agent.yaml --user-id
|
|
380
|
+
# Create agent for specific tenant
|
|
381
|
+
rem process ingest my-agent.yaml --user-id tenant-a --category agents
|
|
503
382
|
|
|
504
|
-
#
|
|
505
|
-
rem ask my-agent "test" --user-id
|
|
506
|
-
# ❌ Error: Schema not found (LOOKUP returns no results for user-b)
|
|
507
|
-
|
|
508
|
-
# User A can use their agent
|
|
509
|
-
rem ask my-agent "test" --user-id user-a
|
|
510
|
-
# ✅ Works - LOOKUP finds schema for user-a
|
|
383
|
+
# Query with tenant context
|
|
384
|
+
rem ask my-agent "test" --user-id tenant-a
|
|
511
385
|
```
|
|
512
386
|
|
|
513
|
-
### Advanced: Ontology Extractors
|
|
514
|
-
|
|
515
|
-
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:
|
|
516
|
-
- Multi-provider testing (`provider_configs`)
|
|
517
|
-
- Semantic search configuration (`embedding_fields`)
|
|
518
|
-
- File matching rules (`OntologyConfig`)
|
|
519
|
-
- Dreaming workflow integration
|
|
520
|
-
|
|
521
387
|
### Troubleshooting
|
|
522
388
|
|
|
523
389
|
**Schema not found error:**
|
|
524
390
|
```bash
|
|
525
391
|
# Check if schema was ingested correctly
|
|
526
|
-
rem ask "SEARCH 'my-agent' FROM schemas"
|
|
392
|
+
rem ask "SEARCH 'my-agent' FROM schemas"
|
|
527
393
|
|
|
528
|
-
# List all schemas
|
|
529
|
-
rem ask "SELECT name, category, created_at FROM schemas ORDER BY created_at DESC LIMIT 10"
|
|
394
|
+
# List all schemas
|
|
395
|
+
rem ask "SELECT name, category, created_at FROM schemas ORDER BY created_at DESC LIMIT 10"
|
|
530
396
|
```
|
|
531
397
|
|
|
532
398
|
**Agent not loading tools:**
|
|
@@ -551,15 +417,15 @@ REM provides a custom query language designed for **LLM-driven iterated retrieva
|
|
|
551
417
|
Unlike traditional single-shot SQL queries, the REM dialect is optimized for **multi-turn exploration** where LLMs participate in query planning:
|
|
552
418
|
|
|
553
419
|
- **Iterated Queries**: Queries return partial results that LLMs use to refine subsequent queries
|
|
554
|
-
- **Composable WITH Syntax**: Chain operations together (e.g., `TRAVERSE
|
|
420
|
+
- **Composable WITH Syntax**: Chain operations together (e.g., `TRAVERSE edge_type WITH LOOKUP "..."`)
|
|
555
421
|
- **Mixed Indexes**: Combines exact lookups (O(1)), semantic search (vector), and graph traversal
|
|
556
422
|
- **Query Planner Participation**: Results include metadata for LLMs to decide next steps
|
|
557
423
|
|
|
558
424
|
**Example Multi-Turn Flow**:
|
|
559
425
|
```
|
|
560
426
|
Turn 1: LOOKUP "sarah-chen" → Returns entity + available edge types
|
|
561
|
-
Turn 2: TRAVERSE
|
|
562
|
-
Turn 3: SEARCH "architecture decisions"
|
|
427
|
+
Turn 2: TRAVERSE authored_by WITH LOOKUP "sarah-chen" DEPTH 1 → Returns connected documents
|
|
428
|
+
Turn 3: SEARCH "architecture decisions" → Semantic search, then explore graph from results
|
|
563
429
|
```
|
|
564
430
|
|
|
565
431
|
This enables LLMs to **progressively build context** rather than requiring perfect queries upfront.
|
|
@@ -612,8 +478,8 @@ SEARCH "contract disputes" FROM resources WHERE tags @> ARRAY['legal'] LIMIT 5
|
|
|
612
478
|
Follow `graph_edges` relationships across the knowledge graph.
|
|
613
479
|
|
|
614
480
|
```sql
|
|
615
|
-
TRAVERSE
|
|
616
|
-
TRAVERSE
|
|
481
|
+
TRAVERSE authored_by WITH LOOKUP "sarah-chen" DEPTH 2
|
|
482
|
+
TRAVERSE references,depends_on WITH LOOKUP "api-design-v2" DEPTH 3
|
|
617
483
|
```
|
|
618
484
|
|
|
619
485
|
**Features**:
|
|
@@ -706,7 +572,7 @@ SEARCH "API migration planning" FROM resources LIMIT 5
|
|
|
706
572
|
LOOKUP "tidb-migration-spec" FROM resources
|
|
707
573
|
|
|
708
574
|
# Query 3: Find related people
|
|
709
|
-
TRAVERSE
|
|
575
|
+
TRAVERSE authored_by,reviewed_by WITH LOOKUP "tidb-migration-spec" DEPTH 1
|
|
710
576
|
|
|
711
577
|
# Query 4: Recent activity
|
|
712
578
|
SELECT * FROM moments WHERE
|
|
@@ -723,7 +589,7 @@ All queries automatically scoped by `user_id` for complete data isolation:
|
|
|
723
589
|
SEARCH "contracts" FROM resources LIMIT 10
|
|
724
590
|
|
|
725
591
|
-- No cross-user data leakage
|
|
726
|
-
TRAVERSE
|
|
592
|
+
TRAVERSE references WITH LOOKUP "project-x" DEPTH 3
|
|
727
593
|
```
|
|
728
594
|
|
|
729
595
|
## API Endpoints
|
|
@@ -735,8 +601,8 @@ POST /api/v1/chat/completions
|
|
|
735
601
|
```
|
|
736
602
|
|
|
737
603
|
**Headers**:
|
|
738
|
-
- `X-
|
|
739
|
-
- `X-
|
|
604
|
+
- `X-User-Id`: User identifier (required for data isolation, uses default if not provided)
|
|
605
|
+
- `X-Tenant-Id`: Deprecated - use `X-User-Id` instead (kept for backwards compatibility)
|
|
740
606
|
- `X-Session-Id`: Session/conversation identifier
|
|
741
607
|
- `X-Agent-Schema`: Agent schema URI to use
|
|
742
608
|
|
|
@@ -875,81 +741,144 @@ rem serve --log-level debug
|
|
|
875
741
|
|
|
876
742
|
### Database Management
|
|
877
743
|
|
|
878
|
-
|
|
744
|
+
REM uses a **code-as-source-of-truth** approach for database schema management. Pydantic models define the schema, and the database is kept in sync via diff-based migrations.
|
|
879
745
|
|
|
880
|
-
|
|
746
|
+
#### Schema Management Philosophy
|
|
747
|
+
|
|
748
|
+
**Two migration files only:**
|
|
749
|
+
- `001_install.sql` - Core infrastructure (extensions, functions, KV store)
|
|
750
|
+
- `002_install_models.sql` - Entity tables (auto-generated from Pydantic models)
|
|
751
|
+
|
|
752
|
+
**No incremental migrations** (003, 004, etc.) - the models file is always regenerated to match code.
|
|
753
|
+
|
|
754
|
+
#### `rem db schema generate` - Regenerate Schema SQL
|
|
755
|
+
|
|
756
|
+
Generate `002_install_models.sql` from registered Pydantic models.
|
|
881
757
|
|
|
882
758
|
```bash
|
|
883
|
-
#
|
|
884
|
-
rem db
|
|
759
|
+
# Regenerate from model registry
|
|
760
|
+
rem db schema generate
|
|
761
|
+
|
|
762
|
+
# Output: src/rem/sql/migrations/002_install_models.sql
|
|
763
|
+
```
|
|
885
764
|
|
|
886
|
-
|
|
887
|
-
|
|
765
|
+
This generates:
|
|
766
|
+
- CREATE TABLE statements for each registered entity
|
|
767
|
+
- Embeddings tables (`embeddings_<table>`)
|
|
768
|
+
- KV_STORE triggers for cache maintenance
|
|
769
|
+
- Foreground indexes (GIN for JSONB, B-tree for lookups)
|
|
888
770
|
|
|
889
|
-
|
|
890
|
-
rem db migrate --models
|
|
771
|
+
#### `rem db diff` - Detect Schema Drift
|
|
891
772
|
|
|
892
|
-
|
|
893
|
-
|
|
773
|
+
Compare Pydantic models against the live database using Alembic autogenerate.
|
|
774
|
+
|
|
775
|
+
```bash
|
|
776
|
+
# Show additive changes only (default, safe for production)
|
|
777
|
+
rem db diff
|
|
778
|
+
|
|
779
|
+
# Show all changes including drops
|
|
780
|
+
rem db diff --strategy full
|
|
781
|
+
|
|
782
|
+
# Show additive + safe type widenings
|
|
783
|
+
rem db diff --strategy safe
|
|
894
784
|
|
|
895
|
-
#
|
|
896
|
-
rem db
|
|
785
|
+
# CI mode: exit 1 if drift detected
|
|
786
|
+
rem db diff --check
|
|
897
787
|
|
|
898
|
-
#
|
|
899
|
-
rem db
|
|
788
|
+
# Generate migration SQL for changes
|
|
789
|
+
rem db diff --generate
|
|
900
790
|
```
|
|
901
791
|
|
|
902
|
-
|
|
792
|
+
**Migration Strategies:**
|
|
793
|
+
| Strategy | Description |
|
|
794
|
+
|----------|-------------|
|
|
795
|
+
| `additive` | Only ADD columns/tables/indexes (safe, no data loss) - **default** |
|
|
796
|
+
| `full` | All changes including DROPs (use with caution) |
|
|
797
|
+
| `safe` | Additive + safe column type widenings (e.g., VARCHAR(50) → VARCHAR(256)) |
|
|
903
798
|
|
|
904
|
-
|
|
799
|
+
**Output shows:**
|
|
800
|
+
- `+ ADD COLUMN` - Column in model but not in DB
|
|
801
|
+
- `- DROP COLUMN` - Column in DB but not in model (only with `--strategy full`)
|
|
802
|
+
- `~ ALTER COLUMN` - Column type or constraints differ
|
|
803
|
+
- `+ CREATE TABLE` / `- DROP TABLE` - Table additions/removals
|
|
804
|
+
|
|
805
|
+
#### `rem db apply` - Apply SQL Directly
|
|
806
|
+
|
|
807
|
+
Apply a SQL file directly to the database (bypasses migration tracking).
|
|
905
808
|
|
|
906
809
|
```bash
|
|
907
|
-
|
|
810
|
+
# Apply with audit logging (default)
|
|
811
|
+
rem db apply src/rem/sql/migrations/002_install_models.sql
|
|
812
|
+
|
|
813
|
+
# Preview without executing
|
|
814
|
+
rem db apply --dry-run src/rem/sql/migrations/002_install_models.sql
|
|
815
|
+
|
|
816
|
+
# Apply without audit logging
|
|
817
|
+
rem db apply --no-log src/rem/sql/migrations/002_install_models.sql
|
|
908
818
|
```
|
|
909
819
|
|
|
910
|
-
#### `rem db
|
|
820
|
+
#### `rem db migrate` - Initial Setup
|
|
911
821
|
|
|
912
|
-
|
|
822
|
+
Apply standard migrations (001 + 002). Use for initial setup only.
|
|
913
823
|
|
|
914
824
|
```bash
|
|
915
|
-
|
|
825
|
+
# Apply infrastructure + entity tables
|
|
826
|
+
rem db migrate
|
|
827
|
+
|
|
828
|
+
# Include background indexes (HNSW for vectors)
|
|
829
|
+
rem db migrate --background-indexes
|
|
916
830
|
```
|
|
917
831
|
|
|
918
|
-
|
|
832
|
+
#### Database Workflows
|
|
919
833
|
|
|
920
|
-
|
|
834
|
+
**Initial Setup (Local):**
|
|
835
|
+
```bash
|
|
836
|
+
rem db schema generate # Generate from models
|
|
837
|
+
rem db migrate # Apply 001 + 002
|
|
838
|
+
rem db diff # Verify no drift
|
|
839
|
+
```
|
|
921
840
|
|
|
922
|
-
|
|
841
|
+
**Adding/Modifying Models:**
|
|
842
|
+
```bash
|
|
843
|
+
# 1. Edit models in src/rem/models/entities/
|
|
844
|
+
# 2. Register new models in src/rem/registry.py
|
|
845
|
+
rem db schema generate # Regenerate schema
|
|
846
|
+
rem db diff # See what changed
|
|
847
|
+
rem db apply src/rem/sql/migrations/002_install_models.sql
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
**CI/CD Pipeline:**
|
|
851
|
+
```bash
|
|
852
|
+
rem db diff --check # Fail build if drift detected
|
|
853
|
+
```
|
|
923
854
|
|
|
855
|
+
**Remote Database (Production/Staging):**
|
|
924
856
|
```bash
|
|
925
|
-
#
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
857
|
+
# Port-forward to cluster database
|
|
858
|
+
kubectl port-forward -n <namespace> svc/rem-postgres-rw 5433:5432 &
|
|
859
|
+
|
|
860
|
+
# Override connection for diff check
|
|
861
|
+
POSTGRES__CONNECTION_STRING="postgresql://rem:rem@localhost:5433/rem" rem db diff
|
|
929
862
|
|
|
930
|
-
#
|
|
931
|
-
rem
|
|
932
|
-
|
|
933
|
-
--output rem/src/rem/sql/migrations/003_add_fields.sql
|
|
863
|
+
# Apply changes if needed
|
|
864
|
+
POSTGRES__CONNECTION_STRING="postgresql://rem:rem@localhost:5433/rem" \
|
|
865
|
+
rem db apply src/rem/sql/migrations/002_install_models.sql
|
|
934
866
|
```
|
|
935
867
|
|
|
936
|
-
#### `rem db
|
|
868
|
+
#### `rem db rebuild-cache` - Rebuild KV Cache
|
|
937
869
|
|
|
938
|
-
|
|
870
|
+
Rebuild KV_STORE cache from entity tables (after database restart or bulk imports).
|
|
939
871
|
|
|
940
872
|
```bash
|
|
941
|
-
|
|
942
|
-
rem db schema indexes \
|
|
943
|
-
--models src/rem/models/entities \
|
|
944
|
-
--output rem/src/rem/sql/background_indexes.sql
|
|
873
|
+
rem db rebuild-cache
|
|
945
874
|
```
|
|
946
875
|
|
|
947
876
|
#### `rem db schema validate` - Validate Models
|
|
948
877
|
|
|
949
|
-
Validate Pydantic models for schema generation.
|
|
878
|
+
Validate registered Pydantic models for schema generation.
|
|
950
879
|
|
|
951
880
|
```bash
|
|
952
|
-
rem db schema validate
|
|
881
|
+
rem db schema validate
|
|
953
882
|
```
|
|
954
883
|
|
|
955
884
|
### File Processing
|
|
@@ -959,22 +888,14 @@ rem db schema validate --models src/rem/models/entities
|
|
|
959
888
|
Process files with optional custom extractor (ontology extraction).
|
|
960
889
|
|
|
961
890
|
```bash
|
|
962
|
-
# Process all completed files
|
|
963
|
-
rem process files
|
|
964
|
-
--tenant-id acme-corp \
|
|
965
|
-
--status completed \
|
|
966
|
-
--limit 10
|
|
891
|
+
# Process all completed files
|
|
892
|
+
rem process files --status completed --limit 10
|
|
967
893
|
|
|
968
894
|
# Process with custom extractor
|
|
969
|
-
rem process files
|
|
970
|
-
--tenant-id acme-corp \
|
|
971
|
-
--extractor cv-parser-v1 \
|
|
972
|
-
--limit 50
|
|
895
|
+
rem process files --extractor cv-parser-v1 --limit 50
|
|
973
896
|
|
|
974
|
-
# Process files
|
|
975
|
-
rem process files
|
|
976
|
-
--tenant-id acme-corp \
|
|
977
|
-
--lookback-hours 168
|
|
897
|
+
# Process files for specific user
|
|
898
|
+
rem process files --user-id user-123 --status completed
|
|
978
899
|
```
|
|
979
900
|
|
|
980
901
|
#### `rem process ingest` - Ingest File into REM
|
|
@@ -982,14 +903,13 @@ rem process files \
|
|
|
982
903
|
Ingest a file into REM with full pipeline (storage + parsing + embedding + database).
|
|
983
904
|
|
|
984
905
|
```bash
|
|
985
|
-
# Ingest local file
|
|
906
|
+
# Ingest local file with metadata
|
|
986
907
|
rem process ingest /path/to/document.pdf \
|
|
987
|
-
--user-id user-123 \
|
|
988
908
|
--category legal \
|
|
989
909
|
--tags contract,2024
|
|
990
910
|
|
|
991
911
|
# Ingest with minimal options
|
|
992
|
-
rem process ingest ./meeting-notes.md
|
|
912
|
+
rem process ingest ./meeting-notes.md
|
|
993
913
|
```
|
|
994
914
|
|
|
995
915
|
#### `rem process uri` - Parse File (Read-Only)
|
|
@@ -1014,28 +934,17 @@ rem process uri s3://bucket/key.docx --output text
|
|
|
1014
934
|
Run full dreaming workflow: extractors → moments → affinity → user model.
|
|
1015
935
|
|
|
1016
936
|
```bash
|
|
1017
|
-
# Full workflow
|
|
1018
|
-
rem dreaming full
|
|
1019
|
-
--user-id user-123 \
|
|
1020
|
-
--tenant-id acme-corp
|
|
937
|
+
# Full workflow (uses default user from settings)
|
|
938
|
+
rem dreaming full
|
|
1021
939
|
|
|
1022
940
|
# Skip ontology extractors
|
|
1023
|
-
rem dreaming full
|
|
1024
|
-
--user-id user-123 \
|
|
1025
|
-
--tenant-id acme-corp \
|
|
1026
|
-
--skip-extractors
|
|
941
|
+
rem dreaming full --skip-extractors
|
|
1027
942
|
|
|
1028
943
|
# Process last 24 hours only
|
|
1029
|
-
rem dreaming full
|
|
1030
|
-
--user-id user-123 \
|
|
1031
|
-
--tenant-id acme-corp \
|
|
1032
|
-
--lookback-hours 24
|
|
944
|
+
rem dreaming full --lookback-hours 24
|
|
1033
945
|
|
|
1034
|
-
# Limit resources processed
|
|
1035
|
-
rem dreaming full
|
|
1036
|
-
--user-id user-123 \
|
|
1037
|
-
--tenant-id acme-corp \
|
|
1038
|
-
--limit 100
|
|
946
|
+
# Limit resources processed for specific user
|
|
947
|
+
rem dreaming full --user-id user-123 --limit 100
|
|
1039
948
|
```
|
|
1040
949
|
|
|
1041
950
|
#### `rem dreaming custom` - Custom Extractor
|
|
@@ -1043,16 +952,11 @@ rem dreaming full \
|
|
|
1043
952
|
Run specific ontology extractor on user's data.
|
|
1044
953
|
|
|
1045
954
|
```bash
|
|
1046
|
-
# Run CV parser on
|
|
1047
|
-
rem dreaming custom
|
|
1048
|
-
--user-id user-123 \
|
|
1049
|
-
--tenant-id acme-corp \
|
|
1050
|
-
--extractor cv-parser-v1
|
|
955
|
+
# Run CV parser on files
|
|
956
|
+
rem dreaming custom --extractor cv-parser-v1
|
|
1051
957
|
|
|
1052
|
-
# Process last week's files
|
|
958
|
+
# Process last week's files with limit
|
|
1053
959
|
rem dreaming custom \
|
|
1054
|
-
--user-id user-123 \
|
|
1055
|
-
--tenant-id acme-corp \
|
|
1056
960
|
--extractor contract-analyzer-v1 \
|
|
1057
961
|
--lookback-hours 168 \
|
|
1058
962
|
--limit 50
|
|
@@ -1063,17 +967,11 @@ rem dreaming custom \
|
|
|
1063
967
|
Extract temporal narratives from resources.
|
|
1064
968
|
|
|
1065
969
|
```bash
|
|
1066
|
-
# Generate moments
|
|
1067
|
-
rem dreaming moments
|
|
1068
|
-
--user-id user-123 \
|
|
1069
|
-
--tenant-id acme-corp \
|
|
1070
|
-
--limit 50
|
|
970
|
+
# Generate moments
|
|
971
|
+
rem dreaming moments --limit 50
|
|
1071
972
|
|
|
1072
973
|
# Process last 7 days
|
|
1073
|
-
rem dreaming moments
|
|
1074
|
-
--user-id user-123 \
|
|
1075
|
-
--tenant-id acme-corp \
|
|
1076
|
-
--lookback-hours 168
|
|
974
|
+
rem dreaming moments --lookback-hours 168
|
|
1077
975
|
```
|
|
1078
976
|
|
|
1079
977
|
#### `rem dreaming affinity` - Build Relationships
|
|
@@ -1081,17 +979,11 @@ rem dreaming moments \
|
|
|
1081
979
|
Build semantic relationships between resources using embeddings.
|
|
1082
980
|
|
|
1083
981
|
```bash
|
|
1084
|
-
# Build affinity graph
|
|
1085
|
-
rem dreaming affinity
|
|
1086
|
-
--user-id user-123 \
|
|
1087
|
-
--tenant-id acme-corp \
|
|
1088
|
-
--limit 100
|
|
982
|
+
# Build affinity graph
|
|
983
|
+
rem dreaming affinity --limit 100
|
|
1089
984
|
|
|
1090
985
|
# Process recent resources only
|
|
1091
|
-
rem dreaming affinity
|
|
1092
|
-
--user-id user-123 \
|
|
1093
|
-
--tenant-id acme-corp \
|
|
1094
|
-
--lookback-hours 24
|
|
986
|
+
rem dreaming affinity --lookback-hours 24
|
|
1095
987
|
```
|
|
1096
988
|
|
|
1097
989
|
#### `rem dreaming user-model` - Update User Model
|
|
@@ -1100,9 +992,7 @@ Update user model from recent activity (preferences, interests, patterns).
|
|
|
1100
992
|
|
|
1101
993
|
```bash
|
|
1102
994
|
# Update user model
|
|
1103
|
-
rem dreaming user-model
|
|
1104
|
-
--user-id user-123 \
|
|
1105
|
-
--tenant-id acme-corp
|
|
995
|
+
rem dreaming user-model
|
|
1106
996
|
```
|
|
1107
997
|
|
|
1108
998
|
### Evaluation & Experiments
|
|
@@ -1194,14 +1084,11 @@ Test Pydantic AI agent with natural language queries.
|
|
|
1194
1084
|
# Ask a question
|
|
1195
1085
|
rem ask "What documents did Sarah Chen author?"
|
|
1196
1086
|
|
|
1197
|
-
# With context headers
|
|
1198
|
-
rem ask "Find all resources about API design" \
|
|
1199
|
-
--user-id user-123 \
|
|
1200
|
-
--tenant-id acme-corp
|
|
1201
|
-
|
|
1202
1087
|
# Use specific agent schema
|
|
1203
|
-
rem ask "Analyze this contract"
|
|
1204
|
-
|
|
1088
|
+
rem ask contract-analyzer "Analyze this contract"
|
|
1089
|
+
|
|
1090
|
+
# Stream response
|
|
1091
|
+
rem ask "Find all resources about API design" --stream
|
|
1205
1092
|
```
|
|
1206
1093
|
|
|
1207
1094
|
### Global Options
|
|
@@ -1249,7 +1136,7 @@ export API__RELOAD=true
|
|
|
1249
1136
|
rem serve
|
|
1250
1137
|
```
|
|
1251
1138
|
|
|
1252
|
-
## Development (For Contributors)
|
|
1139
|
+
## Option 2: Development (For Contributors)
|
|
1253
1140
|
|
|
1254
1141
|
**Best for**: Contributing to REM or customizing the codebase.
|
|
1255
1142
|
|
|
@@ -1353,6 +1240,30 @@ S3__BUCKET_NAME=rem-storage
|
|
|
1353
1240
|
S3__REGION=us-east-1
|
|
1354
1241
|
```
|
|
1355
1242
|
|
|
1243
|
+
### Building Docker Images
|
|
1244
|
+
|
|
1245
|
+
We tag Docker images with three labels for traceability:
|
|
1246
|
+
1. `latest` - Always points to most recent build
|
|
1247
|
+
2. `<git-sha>` - Short commit hash for exact version tracing
|
|
1248
|
+
3. `<version>` - Semantic version from `pyproject.toml`
|
|
1249
|
+
|
|
1250
|
+
```bash
|
|
1251
|
+
# Build and push multi-platform image to Docker Hub
|
|
1252
|
+
VERSION=$(grep '^version' pyproject.toml | cut -d'"' -f2) && \
|
|
1253
|
+
docker buildx build --platform linux/amd64,linux/arm64 \
|
|
1254
|
+
-t percolationlabs/rem:latest \
|
|
1255
|
+
-t percolationlabs/rem:$(git rev-parse --short HEAD) \
|
|
1256
|
+
-t percolationlabs/rem:$VERSION \
|
|
1257
|
+
--push \
|
|
1258
|
+
-f Dockerfile .
|
|
1259
|
+
|
|
1260
|
+
# Load locally for testing (single platform, no push)
|
|
1261
|
+
docker buildx build --platform linux/arm64 \
|
|
1262
|
+
-t percolationlabs/rem:latest \
|
|
1263
|
+
--load \
|
|
1264
|
+
-f Dockerfile .
|
|
1265
|
+
```
|
|
1266
|
+
|
|
1356
1267
|
### Production Deployment (Optional)
|
|
1357
1268
|
|
|
1358
1269
|
For production deployment to AWS EKS with Kubernetes, see the main repository README:
|
|
@@ -1468,6 +1379,252 @@ TraverseQuery ::= TRAVERSE [<edge_types:list>] WITH <initial_query:Query> [DEPTH
|
|
|
1468
1379
|
|
|
1469
1380
|
**Stage 4** (100% answerable): Mature graph with rich historical data. All query types fully functional with high-quality results.
|
|
1470
1381
|
|
|
1382
|
+
## Troubleshooting
|
|
1383
|
+
|
|
1384
|
+
### Apple Silicon Mac: "Failed to build kreuzberg" Error
|
|
1385
|
+
|
|
1386
|
+
**Problem**: Installation fails with `ERROR: Failed building wheel for kreuzberg` on Apple Silicon Macs.
|
|
1387
|
+
|
|
1388
|
+
**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.
|
|
1389
|
+
|
|
1390
|
+
**Solution**: Use ARM64 (native) Python instead of x86_64 Python.
|
|
1391
|
+
|
|
1392
|
+
**Step 1: Verify your Python architecture**
|
|
1393
|
+
|
|
1394
|
+
```bash
|
|
1395
|
+
python3 -c "import platform; print(f'Machine: {platform.machine()}')"
|
|
1396
|
+
```
|
|
1397
|
+
|
|
1398
|
+
- **Correct**: `Machine: arm64` (native ARM Python)
|
|
1399
|
+
- **Wrong**: `Machine: x86_64` (Intel Python under Rosetta)
|
|
1400
|
+
|
|
1401
|
+
**Step 2: Install ARM Python via Homebrew** (if not already installed)
|
|
1402
|
+
|
|
1403
|
+
```bash
|
|
1404
|
+
# Install ARM Python
|
|
1405
|
+
brew install python@3.12
|
|
1406
|
+
|
|
1407
|
+
# Verify it's ARM
|
|
1408
|
+
/opt/homebrew/bin/python3.12 -c "import platform; print(platform.machine())"
|
|
1409
|
+
# Should output: arm64
|
|
1410
|
+
```
|
|
1411
|
+
|
|
1412
|
+
**Step 3: Create venv with ARM Python**
|
|
1413
|
+
|
|
1414
|
+
```bash
|
|
1415
|
+
# Use full path to ARM Python
|
|
1416
|
+
/opt/homebrew/bin/python3.12 -m venv .venv
|
|
1417
|
+
|
|
1418
|
+
# Activate and install
|
|
1419
|
+
source .venv/bin/activate
|
|
1420
|
+
pip install "remdb[all]"
|
|
1421
|
+
```
|
|
1422
|
+
|
|
1423
|
+
**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`.
|
|
1424
|
+
|
|
1425
|
+
**Verification**: After successful installation, you should see:
|
|
1426
|
+
```
|
|
1427
|
+
Using cached kreuzberg-4.0.0rc1-cp310-abi3-macosx_14_0_arm64.whl (19.8 MB)
|
|
1428
|
+
Successfully installed ... kreuzberg-4.0.0rc1 ... remdb-0.3.10
|
|
1429
|
+
```
|
|
1430
|
+
|
|
1431
|
+
## Using REM as a Library
|
|
1432
|
+
|
|
1433
|
+
REM wraps FastAPI - extend it exactly as you would any FastAPI app.
|
|
1434
|
+
|
|
1435
|
+
### Recommended Project Structure
|
|
1436
|
+
|
|
1437
|
+
REM auto-detects `./agents/` and `./models/` folders - no configuration needed:
|
|
1438
|
+
|
|
1439
|
+
```
|
|
1440
|
+
my-rem-app/
|
|
1441
|
+
├── agents/ # Auto-detected for agent schemas
|
|
1442
|
+
│ ├── my-agent.yaml # Custom agent (rem ask my-agent "query")
|
|
1443
|
+
│ └── another-agent.yaml
|
|
1444
|
+
├── models/ # Auto-detected if __init__.py exists
|
|
1445
|
+
│ └── __init__.py # Register models with @rem.register_model
|
|
1446
|
+
├── routers/ # Custom FastAPI routers
|
|
1447
|
+
│ └── custom.py
|
|
1448
|
+
├── main.py # Entry point
|
|
1449
|
+
└── pyproject.toml
|
|
1450
|
+
```
|
|
1451
|
+
|
|
1452
|
+
### Quick Start
|
|
1453
|
+
|
|
1454
|
+
```python
|
|
1455
|
+
# main.py
|
|
1456
|
+
from rem import create_app
|
|
1457
|
+
from fastapi import APIRouter
|
|
1458
|
+
|
|
1459
|
+
# Create REM app (auto-detects ./agents/ and ./models/)
|
|
1460
|
+
app = create_app()
|
|
1461
|
+
|
|
1462
|
+
# Add custom router
|
|
1463
|
+
router = APIRouter(prefix="/custom", tags=["custom"])
|
|
1464
|
+
|
|
1465
|
+
@router.get("/hello")
|
|
1466
|
+
async def hello():
|
|
1467
|
+
return {"message": "Hello from custom router!"}
|
|
1468
|
+
|
|
1469
|
+
app.include_router(router)
|
|
1470
|
+
|
|
1471
|
+
# Add custom MCP tool
|
|
1472
|
+
@app.mcp_server.tool()
|
|
1473
|
+
async def my_tool(query: str) -> dict:
|
|
1474
|
+
"""Custom MCP tool available to agents."""
|
|
1475
|
+
return {"result": query}
|
|
1476
|
+
```
|
|
1477
|
+
|
|
1478
|
+
### Custom Models (Auto-Detected)
|
|
1479
|
+
|
|
1480
|
+
```python
|
|
1481
|
+
# models/__init__.py
|
|
1482
|
+
import rem
|
|
1483
|
+
from rem.models.core import CoreModel
|
|
1484
|
+
from pydantic import Field
|
|
1485
|
+
|
|
1486
|
+
@rem.register_model
|
|
1487
|
+
class MyEntity(CoreModel):
|
|
1488
|
+
"""Custom entity - auto-registered for schema generation."""
|
|
1489
|
+
name: str = Field(description="Entity name")
|
|
1490
|
+
status: str = Field(default="active")
|
|
1491
|
+
```
|
|
1492
|
+
|
|
1493
|
+
Run `rem db schema generate` to include your models in the database schema.
|
|
1494
|
+
|
|
1495
|
+
### Custom Agents (Auto-Detected)
|
|
1496
|
+
|
|
1497
|
+
```yaml
|
|
1498
|
+
# agents/my-agent.yaml
|
|
1499
|
+
type: object
|
|
1500
|
+
description: |
|
|
1501
|
+
You are a helpful assistant that...
|
|
1502
|
+
|
|
1503
|
+
properties:
|
|
1504
|
+
answer:
|
|
1505
|
+
type: string
|
|
1506
|
+
description: Your response
|
|
1507
|
+
|
|
1508
|
+
required:
|
|
1509
|
+
- answer
|
|
1510
|
+
|
|
1511
|
+
json_schema_extra:
|
|
1512
|
+
kind: agent
|
|
1513
|
+
name: my-agent
|
|
1514
|
+
version: "1.0.0"
|
|
1515
|
+
tools:
|
|
1516
|
+
- search_rem
|
|
1517
|
+
```
|
|
1518
|
+
|
|
1519
|
+
Test with: `rem ask my-agent "Hello!"`
|
|
1520
|
+
|
|
1521
|
+
### Example Custom Router
|
|
1522
|
+
|
|
1523
|
+
```python
|
|
1524
|
+
# routers/analytics.py
|
|
1525
|
+
from fastapi import APIRouter, Depends
|
|
1526
|
+
from rem.services.postgres import get_postgres_service
|
|
1527
|
+
|
|
1528
|
+
router = APIRouter(prefix="/analytics", tags=["analytics"])
|
|
1529
|
+
|
|
1530
|
+
@router.get("/stats")
|
|
1531
|
+
async def get_stats():
|
|
1532
|
+
"""Get database statistics."""
|
|
1533
|
+
db = get_postgres_service()
|
|
1534
|
+
if not db:
|
|
1535
|
+
return {"error": "Database not available"}
|
|
1536
|
+
|
|
1537
|
+
await db.connect()
|
|
1538
|
+
try:
|
|
1539
|
+
result = await db.execute(
|
|
1540
|
+
"SELECT COUNT(*) as count FROM resources"
|
|
1541
|
+
)
|
|
1542
|
+
return {"resource_count": result[0]["count"]}
|
|
1543
|
+
finally:
|
|
1544
|
+
await db.disconnect()
|
|
1545
|
+
|
|
1546
|
+
@router.get("/recent")
|
|
1547
|
+
async def get_recent(limit: int = 10):
|
|
1548
|
+
"""Get recent resources."""
|
|
1549
|
+
db = get_postgres_service()
|
|
1550
|
+
if not db:
|
|
1551
|
+
return {"error": "Database not available"}
|
|
1552
|
+
|
|
1553
|
+
await db.connect()
|
|
1554
|
+
try:
|
|
1555
|
+
result = await db.execute(
|
|
1556
|
+
f"SELECT label, category, created_at FROM resources ORDER BY created_at DESC LIMIT {limit}"
|
|
1557
|
+
)
|
|
1558
|
+
return {"resources": result}
|
|
1559
|
+
finally:
|
|
1560
|
+
await db.disconnect()
|
|
1561
|
+
```
|
|
1562
|
+
|
|
1563
|
+
Include in main.py:
|
|
1564
|
+
|
|
1565
|
+
```python
|
|
1566
|
+
from routers.analytics import router as analytics_router
|
|
1567
|
+
app.include_router(analytics_router)
|
|
1568
|
+
```
|
|
1569
|
+
|
|
1570
|
+
### Running the App
|
|
1571
|
+
|
|
1572
|
+
```bash
|
|
1573
|
+
# Development (auto-reload)
|
|
1574
|
+
uv run uvicorn main:app --reload --port 8000
|
|
1575
|
+
|
|
1576
|
+
# Or use rem serve
|
|
1577
|
+
uv run rem serve --reload
|
|
1578
|
+
|
|
1579
|
+
# Test agent
|
|
1580
|
+
uv run rem ask my-agent "What can you help me with?"
|
|
1581
|
+
|
|
1582
|
+
# Test custom endpoint
|
|
1583
|
+
curl http://localhost:8000/analytics/stats
|
|
1584
|
+
```
|
|
1585
|
+
|
|
1586
|
+
### Extension Points
|
|
1587
|
+
|
|
1588
|
+
| Extension | How |
|
|
1589
|
+
|-----------|-----|
|
|
1590
|
+
| **Routes** | `app.include_router(router)` or `@app.get()` |
|
|
1591
|
+
| **MCP Tools** | `@app.mcp_server.tool()` decorator or `app.mcp_server.add_tool(fn)` |
|
|
1592
|
+
| **MCP Resources** | `@app.mcp_server.resource("uri://...")` or `app.mcp_server.add_resource(fn)` |
|
|
1593
|
+
| **MCP Prompts** | `@app.mcp_server.prompt()` or `app.mcp_server.add_prompt(fn)` |
|
|
1594
|
+
| **Models** | `rem.register_models(Model)` then `rem db schema generate` |
|
|
1595
|
+
| **Agent Schemas** | `rem.register_schema_path("./schemas")` or `SCHEMA__PATHS` env var |
|
|
1596
|
+
| **SQL Migrations** | Place in `sql/migrations/` (auto-detected) |
|
|
1597
|
+
|
|
1598
|
+
### Custom Migrations
|
|
1599
|
+
|
|
1600
|
+
REM automatically discovers migrations from two sources:
|
|
1601
|
+
|
|
1602
|
+
1. **Package migrations** (001-099): Built-in migrations from the `remdb` package
|
|
1603
|
+
2. **User migrations** (100+): Your custom migrations in `./sql/migrations/`
|
|
1604
|
+
|
|
1605
|
+
**Convention**: Place custom SQL files in `sql/migrations/` relative to your project root:
|
|
1606
|
+
|
|
1607
|
+
```
|
|
1608
|
+
my-rem-app/
|
|
1609
|
+
├── sql/
|
|
1610
|
+
│ └── migrations/
|
|
1611
|
+
│ ├── 100_custom_table.sql # Runs after package migrations
|
|
1612
|
+
│ ├── 101_add_indexes.sql
|
|
1613
|
+
│ └── 102_custom_functions.sql
|
|
1614
|
+
└── ...
|
|
1615
|
+
```
|
|
1616
|
+
|
|
1617
|
+
**Numbering**: Use 100+ for user migrations to ensure they run after package migrations (001-099). All migrations are sorted by filename, so proper numbering ensures correct execution order.
|
|
1618
|
+
|
|
1619
|
+
**Running migrations**:
|
|
1620
|
+
```bash
|
|
1621
|
+
# Apply all migrations (package + user)
|
|
1622
|
+
rem db migrate
|
|
1623
|
+
|
|
1624
|
+
# Apply with background indexes (for production)
|
|
1625
|
+
rem db migrate --background-indexes
|
|
1626
|
+
```
|
|
1627
|
+
|
|
1471
1628
|
## License
|
|
1472
1629
|
|
|
1473
1630
|
MIT
|