remdb 0.3.0__py3-none-any.whl → 0.3.127__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.
- 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 +29 -3
- rem/agentic/otel/setup.py +93 -4
- rem/agentic/providers/phoenix.py +32 -43
- rem/agentic/providers/pydantic_ai.py +168 -24
- rem/agentic/schema.py +358 -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 +293 -73
- 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/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 +94 -140
- 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 +313 -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.0.dist-info → remdb-0.3.127.dist-info}/METADATA +464 -289
- {remdb-0.3.0.dist-info → remdb-0.3.127.dist-info}/RECORD +104 -73
- {remdb-0.3.0.dist-info → remdb-0.3.127.dist-info}/WHEEL +1 -1
- rem/sql/002_install_models.sql +0 -1068
- rem/sql/install_models.sql +0 -1038
- {remdb-0.3.0.dist-info → remdb-0.3.127.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.127
|
|
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
|
|
@@ -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:
|
|
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==0.3.1
|
|
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
|
|
@@ -102,32 +101,30 @@ Cloud-native unified memory infrastructure for agentic AI systems built with Pyd
|
|
|
102
101
|
- **Database Layer**: PostgreSQL 18 with pgvector for multi-index memory (KV + Vector + Graph)
|
|
103
102
|
- **REM Query Dialect**: Custom query language with O(1) lookups, semantic search, graph traversal
|
|
104
103
|
- **Ingestion & Dreaming**: Background workers for content extraction and progressive index enrichment (0% → 100% answerable)
|
|
105
|
-
- **Observability & Evals**: OpenTelemetry tracing
|
|
104
|
+
- **Observability & Evals**: OpenTelemetry tracing supporting LLM-as-a-Judge evaluation frameworks
|
|
106
105
|
|
|
107
106
|
## Features
|
|
108
107
|
|
|
109
108
|
| Feature | Description | Benefits |
|
|
110
109
|
|---------|-------------|----------|
|
|
111
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.) |
|
|
112
|
-
| **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 |
|
|
113
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 |
|
|
114
113
|
| **Dreaming Workers** | Background workers for entity extraction, moment generation, and affinity matching | Automatic knowledge graph construction from resources (0% → 100% query answerable) |
|
|
115
114
|
| **PostgreSQL + pgvector** | CloudNativePG with PostgreSQL 18, pgvector extension, streaming replication | Production-ready vector search, no external vector DB needed |
|
|
116
115
|
| **AWS EKS Recipe** | Complete infrastructure-as-code with Pulumi, Karpenter, ArgoCD | Deploy to production EKS in minutes with auto-scaling and GitOps |
|
|
117
116
|
| **JSON Schema Agents** | Dynamic agent creation from YAML schemas via Pydantic AI factory | Define agents declaratively, version control schemas, load dynamically |
|
|
118
|
-
| **Content Providers** | Audio transcription (Whisper), vision (
|
|
119
|
-
| **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 |
|
|
120
119
|
| **Multi-Tenancy** | Tenant isolation at database level with automatic scoping | SaaS-ready with complete data separation per tenant |
|
|
121
|
-
| **Streaming Everything** | SSE for chat, background workers for embeddings, async throughout | Real-time responses, non-blocking operations, scalable |
|
|
122
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 |
|
|
123
121
|
|
|
124
122
|
## Quick Start
|
|
125
123
|
|
|
126
124
|
Choose your path:
|
|
127
125
|
|
|
128
|
-
- **Option 1: Package Users with Example Data** (Recommended
|
|
129
|
-
- **Option 2:
|
|
130
|
-
- **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
|
|
131
128
|
|
|
132
129
|
---
|
|
133
130
|
|
|
@@ -136,169 +133,78 @@ Choose your path:
|
|
|
136
133
|
**Best for**: First-time users who want to explore REM with curated example datasets.
|
|
137
134
|
|
|
138
135
|
```bash
|
|
136
|
+
# Install system dependencies (tesseract for OCR)
|
|
137
|
+
brew install tesseract # macOS (Linux/Windows: see tesseract-ocr.github.io)
|
|
138
|
+
|
|
139
139
|
# Install remdb
|
|
140
|
-
pip install remdb[all]
|
|
140
|
+
pip install "remdb[all]"
|
|
141
141
|
|
|
142
142
|
# Clone example datasets
|
|
143
143
|
git clone https://github.com/Percolation-Labs/remstack-lab.git
|
|
144
144
|
cd remstack-lab
|
|
145
145
|
|
|
146
|
-
#
|
|
147
|
-
|
|
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
|
|
148
149
|
|
|
149
|
-
#
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
-e POSTGRES_USER=rem \
|
|
153
|
-
-e POSTGRES_PASSWORD=rem \
|
|
154
|
-
-e POSTGRES_DB=rem \
|
|
155
|
-
-p 5050:5432 \
|
|
156
|
-
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
|
|
157
153
|
|
|
158
154
|
# Load quickstart dataset
|
|
159
|
-
rem db load
|
|
155
|
+
rem db load datasets/quickstart/sample_data.yaml
|
|
160
156
|
|
|
161
157
|
# Ask questions
|
|
162
|
-
rem ask
|
|
163
|
-
rem ask
|
|
158
|
+
rem ask "What documents exist in the system?"
|
|
159
|
+
rem ask "Show me meetings about API design"
|
|
160
|
+
|
|
161
|
+
# Ingest files (PDF, DOCX, images, etc.)
|
|
162
|
+
rem process ingest datasets/formats/files/bitcoin_whitepaper.pdf --category research --tags bitcoin,whitepaper
|
|
164
163
|
|
|
165
|
-
#
|
|
166
|
-
rem
|
|
167
|
-
rem ask --user-id my-company "Show me candidates with Python experience"
|
|
164
|
+
# Query ingested content
|
|
165
|
+
rem ask "What is the Bitcoin whitepaper about?"
|
|
168
166
|
```
|
|
169
167
|
|
|
170
168
|
**What you get:**
|
|
171
169
|
- Quickstart: 3 users, 3 resources, 3 moments, 4 messages
|
|
172
170
|
- Domain datasets: recruitment, legal, enterprise, misc
|
|
173
171
|
- Format examples: engrams, documents, conversations, files
|
|
174
|
-
- Jupyter notebooks and experiments
|
|
175
172
|
|
|
176
173
|
**Learn more**: [remstack-lab repository](https://github.com/Percolation-Labs/remstack-lab)
|
|
177
174
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
## Option 2: Package Users (No Example Data)
|
|
181
|
-
|
|
182
|
-
**Best for**: Using REM as a service (API + CLI) without modifying code, bringing your own data.
|
|
175
|
+
### Using the API
|
|
183
176
|
|
|
184
|
-
|
|
177
|
+
Once configured, you can also use the OpenAI-compatible chat completions API:
|
|
185
178
|
|
|
186
179
|
```bash
|
|
187
|
-
#
|
|
188
|
-
mkdir my-rem-project && cd my-rem-project
|
|
189
|
-
|
|
190
|
-
# Download docker-compose file from public gist
|
|
191
|
-
curl -O https://gist.githubusercontent.com/percolating-sirsh/d117b673bc0edfdef1a5068ccd3cf3e5/raw/docker-compose.prebuilt.yml
|
|
192
|
-
|
|
193
|
-
# IMPORTANT: Export API keys BEFORE running docker compose
|
|
194
|
-
# Docker Compose reads env vars at startup - exporting them after won't work!
|
|
195
|
-
|
|
196
|
-
# Required: OpenAI for embeddings (text-embedding-3-small)
|
|
197
|
-
export OPENAI_API_KEY="sk-..."
|
|
198
|
-
|
|
199
|
-
# Recommended: At least one chat completion provider
|
|
200
|
-
export ANTHROPIC_API_KEY="sk-ant-..." # Claude Sonnet 4.5 (high quality)
|
|
201
|
-
export CEREBRAS_API_KEY="csk-..." # Cerebras (fast, cheap inference)
|
|
202
|
-
|
|
203
|
-
# Start PostgreSQL + API
|
|
180
|
+
# Start the API server (if not using docker-compose for API)
|
|
204
181
|
docker compose -f docker-compose.prebuilt.yml up -d
|
|
205
182
|
|
|
206
|
-
#
|
|
207
|
-
curl http://localhost:8000/
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
### Step 2: Install and Configure CLI (REQUIRED)
|
|
216
|
-
|
|
217
|
-
**This step is required** before you can use REM - it installs the database schema and configures your LLM API keys.
|
|
218
|
-
|
|
219
|
-
```bash
|
|
220
|
-
# Install remdb package from PyPI
|
|
221
|
-
pip install remdb[all]
|
|
222
|
-
|
|
223
|
-
# Configure REM (defaults to port 5051 for package users)
|
|
224
|
-
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
|
+
}'
|
|
225
192
|
```
|
|
226
193
|
|
|
227
|
-
The interactive wizard will:
|
|
228
|
-
1. **Configure PostgreSQL**: Defaults to `postgresql://rem:rem@localhost:5051/rem` (prebuilt docker-compose)
|
|
229
|
-
- Just press Enter to accept defaults
|
|
230
|
-
- Custom database: Enter your own host/port/credentials
|
|
231
|
-
2. **Configure LLM providers**: Enter your OpenAI/Anthropic API keys
|
|
232
|
-
3. **Install database tables**: Creates schema, functions, indexes (**required for CLI/API to work**)
|
|
233
|
-
4. **Register with Claude Desktop**: Adds REM MCP server to Claude
|
|
234
|
-
|
|
235
|
-
Configuration saved to `~/.rem/config.yaml` (can edit with `rem configure --edit`)
|
|
236
|
-
|
|
237
194
|
**Port Guide:**
|
|
238
195
|
- **5051**: Package users with `docker-compose.prebuilt.yml` (pre-built image)
|
|
239
196
|
- **5050**: Developers with `docker-compose.yml` (local build)
|
|
240
|
-
- **Custom**: Your own PostgreSQL database
|
|
241
197
|
|
|
242
198
|
**Next Steps:**
|
|
243
199
|
- See [CLI Reference](#cli-reference) for all available commands
|
|
244
200
|
- See [REM Query Dialect](#rem-query-dialect) for query examples
|
|
245
201
|
- See [API Endpoints](#api-endpoints) for OpenAI-compatible API usage
|
|
246
202
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
**Option A: Clone example datasets** (Recommended - works with all README examples)
|
|
250
|
-
|
|
251
|
-
```bash
|
|
252
|
-
# Clone datasets repository
|
|
253
|
-
git clone https://github.com/Percolation-Labs/remstack-lab.git
|
|
254
|
-
|
|
255
|
-
# Load quickstart dataset
|
|
256
|
-
rem db load --file remstack-lab/datasets/quickstart/sample_data.yaml --user-id demo-user
|
|
257
|
-
|
|
258
|
-
# Test with sample queries
|
|
259
|
-
rem ask --user-id demo-user "What documents exist in the system?"
|
|
260
|
-
rem ask --user-id demo-user "Show me meetings about API design"
|
|
261
|
-
rem ask --user-id demo-user "Who is Sarah Chen?"
|
|
262
|
-
|
|
263
|
-
# Try domain-specific datasets
|
|
264
|
-
rem db load --file remstack-lab/datasets/domains/recruitment/scenarios/candidate_pipeline/data.yaml --user-id my-company
|
|
265
|
-
rem ask --user-id my-company "Show me candidates with Python experience"
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
**Option B: Bring your own data**
|
|
269
|
-
|
|
270
|
-
```bash
|
|
271
|
-
# Ingest your own files
|
|
272
|
-
echo "REM is a bio-inspired memory system for agentic AI workloads." > test-doc.txt
|
|
273
|
-
rem process ingest test-doc.txt --user-id test-user --category documentation --tags rem,ai
|
|
274
|
-
|
|
275
|
-
# Query your ingested data
|
|
276
|
-
rem ask --user-id test-user "What do you know about REM from my knowledge base?"
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Step 4: Test the API
|
|
280
|
-
|
|
281
|
-
```bash
|
|
282
|
-
# Test the OpenAI-compatible chat completions API
|
|
283
|
-
curl -X POST http://localhost:8000/api/v1/chat/completions \
|
|
284
|
-
-H "Content-Type: application/json" \
|
|
285
|
-
-H "X-User-Id: demo-user" \
|
|
286
|
-
-d '{
|
|
287
|
-
"model": "anthropic:claude-sonnet-4-5-20250929",
|
|
288
|
-
"messages": [{"role": "user", "content": "What documents did Sarah Chen author?"}],
|
|
289
|
-
"stream": false
|
|
290
|
-
}'
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
**Available Commands:**
|
|
294
|
-
- `rem ask` - Natural language queries to REM
|
|
295
|
-
- `rem process ingest <file>` - Full ingestion pipeline (storage + parsing + embedding + database)
|
|
296
|
-
- `rem process uri <file>` - READ-ONLY parsing (no database storage, useful for testing parsers)
|
|
297
|
-
- `rem db load --file <yaml>` - Load structured datasets directly
|
|
203
|
+
---
|
|
298
204
|
|
|
299
205
|
## Example Datasets
|
|
300
206
|
|
|
301
|
-
|
|
207
|
+
Clone [remstack-lab](https://github.com/Percolation-Labs/remstack-lab) for curated datasets organized by domain and format.
|
|
302
208
|
|
|
303
209
|
**What's included:**
|
|
304
210
|
- **Quickstart**: Minimal dataset (3 users, 3 resources, 3 moments) - perfect for first-time users
|
|
@@ -311,13 +217,10 @@ curl -X POST http://localhost:8000/api/v1/chat/completions \
|
|
|
311
217
|
cd remstack-lab
|
|
312
218
|
|
|
313
219
|
# Load any dataset
|
|
314
|
-
rem db load --file datasets/quickstart/sample_data.yaml
|
|
220
|
+
rem db load --file datasets/quickstart/sample_data.yaml
|
|
315
221
|
|
|
316
222
|
# Explore formats
|
|
317
|
-
rem db load --file datasets/formats/engrams/scenarios/team_meeting/team_standup_meeting.yaml
|
|
318
|
-
|
|
319
|
-
# Try domain-specific examples
|
|
320
|
-
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
|
|
321
224
|
```
|
|
322
225
|
|
|
323
226
|
## See Also
|
|
@@ -411,30 +314,24 @@ json_schema_extra:
|
|
|
411
314
|
```bash
|
|
412
315
|
# Ingest the schema (stores in database schemas table)
|
|
413
316
|
rem process ingest my-research-assistant.yaml \
|
|
414
|
-
--user-id my-user \
|
|
415
317
|
--category agents \
|
|
416
318
|
--tags custom,research
|
|
417
319
|
|
|
418
320
|
# Verify schema is in database (should show schema details)
|
|
419
|
-
rem ask "LOOKUP 'my-research-assistant' FROM schemas"
|
|
321
|
+
rem ask "LOOKUP 'my-research-assistant' FROM schemas"
|
|
420
322
|
```
|
|
421
323
|
|
|
422
324
|
**Step 3: Use Your Custom Agent**
|
|
423
325
|
|
|
424
326
|
```bash
|
|
425
327
|
# Run a query with your custom agent
|
|
426
|
-
rem ask research-assistant "Find documents about machine learning architecture"
|
|
427
|
-
--user-id my-user
|
|
328
|
+
rem ask research-assistant "Find documents about machine learning architecture"
|
|
428
329
|
|
|
429
330
|
# With streaming
|
|
430
|
-
rem ask research-assistant "Summarize recent API design documents"
|
|
431
|
-
--user-id my-user \
|
|
432
|
-
--stream
|
|
331
|
+
rem ask research-assistant "Summarize recent API design documents" --stream
|
|
433
332
|
|
|
434
333
|
# With session continuity
|
|
435
|
-
rem ask research-assistant "What did we discuss about ML?"
|
|
436
|
-
--user-id my-user \
|
|
437
|
-
--session-id abc-123
|
|
334
|
+
rem ask research-assistant "What did we discuss about ML?" --session-id c3d4e5f6-a7b8-9012-cdef-345678901234
|
|
438
335
|
```
|
|
439
336
|
|
|
440
337
|
### Agent Schema Structure
|
|
@@ -477,38 +374,25 @@ REM provides **4 built-in MCP tools** your agents can use:
|
|
|
477
374
|
|
|
478
375
|
### Multi-User Isolation
|
|
479
376
|
|
|
480
|
-
|
|
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:
|
|
481
378
|
|
|
482
379
|
```bash
|
|
483
|
-
#
|
|
484
|
-
rem process ingest my-agent.yaml --user-id
|
|
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)
|
|
380
|
+
# Create agent for specific tenant
|
|
381
|
+
rem process ingest my-agent.yaml --user-id tenant-a --category agents
|
|
489
382
|
|
|
490
|
-
#
|
|
491
|
-
rem ask my-agent "test" --user-id
|
|
492
|
-
# ✅ Works - LOOKUP finds schema for user-a
|
|
383
|
+
# Query with tenant context
|
|
384
|
+
rem ask my-agent "test" --user-id tenant-a
|
|
493
385
|
```
|
|
494
386
|
|
|
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
387
|
### Troubleshooting
|
|
504
388
|
|
|
505
389
|
**Schema not found error:**
|
|
506
390
|
```bash
|
|
507
391
|
# Check if schema was ingested correctly
|
|
508
|
-
rem ask "SEARCH 'my-agent' FROM schemas"
|
|
392
|
+
rem ask "SEARCH 'my-agent' FROM schemas"
|
|
509
393
|
|
|
510
|
-
# List all schemas
|
|
511
|
-
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"
|
|
512
396
|
```
|
|
513
397
|
|
|
514
398
|
**Agent not loading tools:**
|
|
@@ -533,15 +417,15 @@ REM provides a custom query language designed for **LLM-driven iterated retrieva
|
|
|
533
417
|
Unlike traditional single-shot SQL queries, the REM dialect is optimized for **multi-turn exploration** where LLMs participate in query planning:
|
|
534
418
|
|
|
535
419
|
- **Iterated Queries**: Queries return partial results that LLMs use to refine subsequent queries
|
|
536
|
-
- **Composable WITH Syntax**: Chain operations together (e.g., `TRAVERSE
|
|
420
|
+
- **Composable WITH Syntax**: Chain operations together (e.g., `TRAVERSE edge_type WITH LOOKUP "..."`)
|
|
537
421
|
- **Mixed Indexes**: Combines exact lookups (O(1)), semantic search (vector), and graph traversal
|
|
538
422
|
- **Query Planner Participation**: Results include metadata for LLMs to decide next steps
|
|
539
423
|
|
|
540
424
|
**Example Multi-Turn Flow**:
|
|
541
425
|
```
|
|
542
426
|
Turn 1: LOOKUP "sarah-chen" → Returns entity + available edge types
|
|
543
|
-
Turn 2: TRAVERSE
|
|
544
|
-
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
|
|
545
429
|
```
|
|
546
430
|
|
|
547
431
|
This enables LLMs to **progressively build context** rather than requiring perfect queries upfront.
|
|
@@ -594,8 +478,8 @@ SEARCH "contract disputes" FROM resources WHERE tags @> ARRAY['legal'] LIMIT 5
|
|
|
594
478
|
Follow `graph_edges` relationships across the knowledge graph.
|
|
595
479
|
|
|
596
480
|
```sql
|
|
597
|
-
TRAVERSE
|
|
598
|
-
TRAVERSE
|
|
481
|
+
TRAVERSE authored_by WITH LOOKUP "sarah-chen" DEPTH 2
|
|
482
|
+
TRAVERSE references,depends_on WITH LOOKUP "api-design-v2" DEPTH 3
|
|
599
483
|
```
|
|
600
484
|
|
|
601
485
|
**Features**:
|
|
@@ -688,7 +572,7 @@ SEARCH "API migration planning" FROM resources LIMIT 5
|
|
|
688
572
|
LOOKUP "tidb-migration-spec" FROM resources
|
|
689
573
|
|
|
690
574
|
# Query 3: Find related people
|
|
691
|
-
TRAVERSE
|
|
575
|
+
TRAVERSE authored_by,reviewed_by WITH LOOKUP "tidb-migration-spec" DEPTH 1
|
|
692
576
|
|
|
693
577
|
# Query 4: Recent activity
|
|
694
578
|
SELECT * FROM moments WHERE
|
|
@@ -705,7 +589,7 @@ All queries automatically scoped by `user_id` for complete data isolation:
|
|
|
705
589
|
SEARCH "contracts" FROM resources LIMIT 10
|
|
706
590
|
|
|
707
591
|
-- No cross-user data leakage
|
|
708
|
-
TRAVERSE
|
|
592
|
+
TRAVERSE references WITH LOOKUP "project-x" DEPTH 3
|
|
709
593
|
```
|
|
710
594
|
|
|
711
595
|
## API Endpoints
|
|
@@ -717,8 +601,8 @@ POST /api/v1/chat/completions
|
|
|
717
601
|
```
|
|
718
602
|
|
|
719
603
|
**Headers**:
|
|
720
|
-
- `X-
|
|
721
|
-
- `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)
|
|
722
606
|
- `X-Session-Id`: Session/conversation identifier
|
|
723
607
|
- `X-Agent-Schema`: Agent schema URI to use
|
|
724
608
|
|
|
@@ -857,81 +741,144 @@ rem serve --log-level debug
|
|
|
857
741
|
|
|
858
742
|
### Database Management
|
|
859
743
|
|
|
860
|
-
|
|
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.
|
|
745
|
+
|
|
746
|
+
#### Schema Management Philosophy
|
|
861
747
|
|
|
862
|
-
|
|
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.
|
|
863
757
|
|
|
864
758
|
```bash
|
|
865
|
-
#
|
|
866
|
-
rem db
|
|
759
|
+
# Regenerate from model registry
|
|
760
|
+
rem db schema generate
|
|
867
761
|
|
|
868
|
-
#
|
|
869
|
-
|
|
762
|
+
# Output: src/rem/sql/migrations/002_install_models.sql
|
|
763
|
+
```
|
|
870
764
|
|
|
871
|
-
|
|
872
|
-
|
|
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)
|
|
873
770
|
|
|
874
|
-
|
|
875
|
-
rem db migrate --background-indexes
|
|
771
|
+
#### `rem db diff` - Detect Schema Drift
|
|
876
772
|
|
|
877
|
-
|
|
878
|
-
rem db migrate --connection "postgresql://user:pass@host:5432/db"
|
|
773
|
+
Compare Pydantic models against the live database using Alembic autogenerate.
|
|
879
774
|
|
|
880
|
-
|
|
881
|
-
|
|
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
|
|
784
|
+
|
|
785
|
+
# CI mode: exit 1 if drift detected
|
|
786
|
+
rem db diff --check
|
|
787
|
+
|
|
788
|
+
# Generate migration SQL for changes
|
|
789
|
+
rem db diff --generate
|
|
882
790
|
```
|
|
883
791
|
|
|
884
|
-
|
|
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)) |
|
|
798
|
+
|
|
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
|
|
885
804
|
|
|
886
|
-
|
|
805
|
+
#### `rem db apply` - Apply SQL Directly
|
|
806
|
+
|
|
807
|
+
Apply a SQL file directly to the database (bypasses migration tracking).
|
|
887
808
|
|
|
888
809
|
```bash
|
|
889
|
-
|
|
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
|
|
890
818
|
```
|
|
891
819
|
|
|
892
|
-
#### `rem db
|
|
820
|
+
#### `rem db migrate` - Initial Setup
|
|
893
821
|
|
|
894
|
-
|
|
822
|
+
Apply standard migrations (001 + 002). Use for initial setup only.
|
|
895
823
|
|
|
896
824
|
```bash
|
|
897
|
-
|
|
825
|
+
# Apply infrastructure + entity tables
|
|
826
|
+
rem db migrate
|
|
827
|
+
|
|
828
|
+
# Include background indexes (HNSW for vectors)
|
|
829
|
+
rem db migrate --background-indexes
|
|
898
830
|
```
|
|
899
831
|
|
|
900
|
-
|
|
832
|
+
#### Database Workflows
|
|
833
|
+
|
|
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
|
+
```
|
|
901
840
|
|
|
902
|
-
|
|
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
|
+
```
|
|
903
849
|
|
|
904
|
-
|
|
850
|
+
**CI/CD Pipeline:**
|
|
851
|
+
```bash
|
|
852
|
+
rem db diff --check # Fail build if drift detected
|
|
853
|
+
```
|
|
905
854
|
|
|
855
|
+
**Remote Database (Production/Staging):**
|
|
906
856
|
```bash
|
|
907
|
-
#
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
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
|
|
911
862
|
|
|
912
|
-
#
|
|
913
|
-
rem
|
|
914
|
-
|
|
915
|
-
--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
|
|
916
866
|
```
|
|
917
867
|
|
|
918
|
-
#### `rem db
|
|
868
|
+
#### `rem db rebuild-cache` - Rebuild KV Cache
|
|
919
869
|
|
|
920
|
-
|
|
870
|
+
Rebuild KV_STORE cache from entity tables (after database restart or bulk imports).
|
|
921
871
|
|
|
922
872
|
```bash
|
|
923
|
-
|
|
924
|
-
rem db schema indexes \
|
|
925
|
-
--models src/rem/models/entities \
|
|
926
|
-
--output rem/src/rem/sql/background_indexes.sql
|
|
873
|
+
rem db rebuild-cache
|
|
927
874
|
```
|
|
928
875
|
|
|
929
876
|
#### `rem db schema validate` - Validate Models
|
|
930
877
|
|
|
931
|
-
Validate Pydantic models for schema generation.
|
|
878
|
+
Validate registered Pydantic models for schema generation.
|
|
932
879
|
|
|
933
880
|
```bash
|
|
934
|
-
rem db schema validate
|
|
881
|
+
rem db schema validate
|
|
935
882
|
```
|
|
936
883
|
|
|
937
884
|
### File Processing
|
|
@@ -941,22 +888,14 @@ rem db schema validate --models src/rem/models/entities
|
|
|
941
888
|
Process files with optional custom extractor (ontology extraction).
|
|
942
889
|
|
|
943
890
|
```bash
|
|
944
|
-
# Process all completed files
|
|
945
|
-
rem process files
|
|
946
|
-
--tenant-id acme-corp \
|
|
947
|
-
--status completed \
|
|
948
|
-
--limit 10
|
|
891
|
+
# Process all completed files
|
|
892
|
+
rem process files --status completed --limit 10
|
|
949
893
|
|
|
950
894
|
# Process with custom extractor
|
|
951
|
-
rem process files
|
|
952
|
-
--tenant-id acme-corp \
|
|
953
|
-
--extractor cv-parser-v1 \
|
|
954
|
-
--limit 50
|
|
895
|
+
rem process files --extractor cv-parser-v1 --limit 50
|
|
955
896
|
|
|
956
|
-
# Process files
|
|
957
|
-
rem process files
|
|
958
|
-
--tenant-id acme-corp \
|
|
959
|
-
--lookback-hours 168
|
|
897
|
+
# Process files for specific user
|
|
898
|
+
rem process files --user-id user-123 --status completed
|
|
960
899
|
```
|
|
961
900
|
|
|
962
901
|
#### `rem process ingest` - Ingest File into REM
|
|
@@ -964,14 +903,13 @@ rem process files \
|
|
|
964
903
|
Ingest a file into REM with full pipeline (storage + parsing + embedding + database).
|
|
965
904
|
|
|
966
905
|
```bash
|
|
967
|
-
# Ingest local file
|
|
906
|
+
# Ingest local file with metadata
|
|
968
907
|
rem process ingest /path/to/document.pdf \
|
|
969
|
-
--user-id user-123 \
|
|
970
908
|
--category legal \
|
|
971
909
|
--tags contract,2024
|
|
972
910
|
|
|
973
911
|
# Ingest with minimal options
|
|
974
|
-
rem process ingest ./meeting-notes.md
|
|
912
|
+
rem process ingest ./meeting-notes.md
|
|
975
913
|
```
|
|
976
914
|
|
|
977
915
|
#### `rem process uri` - Parse File (Read-Only)
|
|
@@ -996,28 +934,17 @@ rem process uri s3://bucket/key.docx --output text
|
|
|
996
934
|
Run full dreaming workflow: extractors → moments → affinity → user model.
|
|
997
935
|
|
|
998
936
|
```bash
|
|
999
|
-
# Full workflow
|
|
1000
|
-
rem dreaming full
|
|
1001
|
-
--user-id user-123 \
|
|
1002
|
-
--tenant-id acme-corp
|
|
937
|
+
# Full workflow (uses default user from settings)
|
|
938
|
+
rem dreaming full
|
|
1003
939
|
|
|
1004
940
|
# Skip ontology extractors
|
|
1005
|
-
rem dreaming full
|
|
1006
|
-
--user-id user-123 \
|
|
1007
|
-
--tenant-id acme-corp \
|
|
1008
|
-
--skip-extractors
|
|
941
|
+
rem dreaming full --skip-extractors
|
|
1009
942
|
|
|
1010
943
|
# Process last 24 hours only
|
|
1011
|
-
rem dreaming full
|
|
1012
|
-
--user-id user-123 \
|
|
1013
|
-
--tenant-id acme-corp \
|
|
1014
|
-
--lookback-hours 24
|
|
944
|
+
rem dreaming full --lookback-hours 24
|
|
1015
945
|
|
|
1016
|
-
# Limit resources processed
|
|
1017
|
-
rem dreaming full
|
|
1018
|
-
--user-id user-123 \
|
|
1019
|
-
--tenant-id acme-corp \
|
|
1020
|
-
--limit 100
|
|
946
|
+
# Limit resources processed for specific user
|
|
947
|
+
rem dreaming full --user-id user-123 --limit 100
|
|
1021
948
|
```
|
|
1022
949
|
|
|
1023
950
|
#### `rem dreaming custom` - Custom Extractor
|
|
@@ -1025,16 +952,11 @@ rem dreaming full \
|
|
|
1025
952
|
Run specific ontology extractor on user's data.
|
|
1026
953
|
|
|
1027
954
|
```bash
|
|
1028
|
-
# Run CV parser on
|
|
1029
|
-
rem dreaming custom
|
|
1030
|
-
--user-id user-123 \
|
|
1031
|
-
--tenant-id acme-corp \
|
|
1032
|
-
--extractor cv-parser-v1
|
|
955
|
+
# Run CV parser on files
|
|
956
|
+
rem dreaming custom --extractor cv-parser-v1
|
|
1033
957
|
|
|
1034
|
-
# Process last week's files
|
|
958
|
+
# Process last week's files with limit
|
|
1035
959
|
rem dreaming custom \
|
|
1036
|
-
--user-id user-123 \
|
|
1037
|
-
--tenant-id acme-corp \
|
|
1038
960
|
--extractor contract-analyzer-v1 \
|
|
1039
961
|
--lookback-hours 168 \
|
|
1040
962
|
--limit 50
|
|
@@ -1045,17 +967,11 @@ rem dreaming custom \
|
|
|
1045
967
|
Extract temporal narratives from resources.
|
|
1046
968
|
|
|
1047
969
|
```bash
|
|
1048
|
-
# Generate moments
|
|
1049
|
-
rem dreaming moments
|
|
1050
|
-
--user-id user-123 \
|
|
1051
|
-
--tenant-id acme-corp \
|
|
1052
|
-
--limit 50
|
|
970
|
+
# Generate moments
|
|
971
|
+
rem dreaming moments --limit 50
|
|
1053
972
|
|
|
1054
973
|
# Process last 7 days
|
|
1055
|
-
rem dreaming moments
|
|
1056
|
-
--user-id user-123 \
|
|
1057
|
-
--tenant-id acme-corp \
|
|
1058
|
-
--lookback-hours 168
|
|
974
|
+
rem dreaming moments --lookback-hours 168
|
|
1059
975
|
```
|
|
1060
976
|
|
|
1061
977
|
#### `rem dreaming affinity` - Build Relationships
|
|
@@ -1063,17 +979,11 @@ rem dreaming moments \
|
|
|
1063
979
|
Build semantic relationships between resources using embeddings.
|
|
1064
980
|
|
|
1065
981
|
```bash
|
|
1066
|
-
# Build affinity graph
|
|
1067
|
-
rem dreaming affinity
|
|
1068
|
-
--user-id user-123 \
|
|
1069
|
-
--tenant-id acme-corp \
|
|
1070
|
-
--limit 100
|
|
982
|
+
# Build affinity graph
|
|
983
|
+
rem dreaming affinity --limit 100
|
|
1071
984
|
|
|
1072
985
|
# Process recent resources only
|
|
1073
|
-
rem dreaming affinity
|
|
1074
|
-
--user-id user-123 \
|
|
1075
|
-
--tenant-id acme-corp \
|
|
1076
|
-
--lookback-hours 24
|
|
986
|
+
rem dreaming affinity --lookback-hours 24
|
|
1077
987
|
```
|
|
1078
988
|
|
|
1079
989
|
#### `rem dreaming user-model` - Update User Model
|
|
@@ -1082,9 +992,7 @@ Update user model from recent activity (preferences, interests, patterns).
|
|
|
1082
992
|
|
|
1083
993
|
```bash
|
|
1084
994
|
# Update user model
|
|
1085
|
-
rem dreaming user-model
|
|
1086
|
-
--user-id user-123 \
|
|
1087
|
-
--tenant-id acme-corp
|
|
995
|
+
rem dreaming user-model
|
|
1088
996
|
```
|
|
1089
997
|
|
|
1090
998
|
### Evaluation & Experiments
|
|
@@ -1176,14 +1084,11 @@ Test Pydantic AI agent with natural language queries.
|
|
|
1176
1084
|
# Ask a question
|
|
1177
1085
|
rem ask "What documents did Sarah Chen author?"
|
|
1178
1086
|
|
|
1179
|
-
# With context headers
|
|
1180
|
-
rem ask "Find all resources about API design" \
|
|
1181
|
-
--user-id user-123 \
|
|
1182
|
-
--tenant-id acme-corp
|
|
1183
|
-
|
|
1184
1087
|
# Use specific agent schema
|
|
1185
|
-
rem ask "Analyze this contract"
|
|
1186
|
-
|
|
1088
|
+
rem ask contract-analyzer "Analyze this contract"
|
|
1089
|
+
|
|
1090
|
+
# Stream response
|
|
1091
|
+
rem ask "Find all resources about API design" --stream
|
|
1187
1092
|
```
|
|
1188
1093
|
|
|
1189
1094
|
### Global Options
|
|
@@ -1231,7 +1136,7 @@ export API__RELOAD=true
|
|
|
1231
1136
|
rem serve
|
|
1232
1137
|
```
|
|
1233
1138
|
|
|
1234
|
-
## Development (For Contributors)
|
|
1139
|
+
## Option 2: Development (For Contributors)
|
|
1235
1140
|
|
|
1236
1141
|
**Best for**: Contributing to REM or customizing the codebase.
|
|
1237
1142
|
|
|
@@ -1335,6 +1240,30 @@ S3__BUCKET_NAME=rem-storage
|
|
|
1335
1240
|
S3__REGION=us-east-1
|
|
1336
1241
|
```
|
|
1337
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
|
+
|
|
1338
1267
|
### Production Deployment (Optional)
|
|
1339
1268
|
|
|
1340
1269
|
For production deployment to AWS EKS with Kubernetes, see the main repository README:
|
|
@@ -1450,6 +1379,252 @@ TraverseQuery ::= TRAVERSE [<edge_types:list>] WITH <initial_query:Query> [DEPTH
|
|
|
1450
1379
|
|
|
1451
1380
|
**Stage 4** (100% answerable): Mature graph with rich historical data. All query types fully functional with high-quality results.
|
|
1452
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
|
+
|
|
1453
1628
|
## License
|
|
1454
1629
|
|
|
1455
1630
|
MIT
|