remdb 0.3.242__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 -0
- rem/agentic/README.md +760 -0
- rem/agentic/__init__.py +54 -0
- rem/agentic/agents/README.md +155 -0
- rem/agentic/agents/__init__.py +38 -0
- rem/agentic/agents/agent_manager.py +311 -0
- rem/agentic/agents/sse_simulator.py +502 -0
- rem/agentic/context.py +425 -0
- rem/agentic/context_builder.py +360 -0
- rem/agentic/llm_provider_models.py +301 -0
- rem/agentic/mcp/__init__.py +0 -0
- rem/agentic/mcp/tool_wrapper.py +273 -0
- rem/agentic/otel/__init__.py +5 -0
- rem/agentic/otel/setup.py +240 -0
- rem/agentic/providers/phoenix.py +926 -0
- rem/agentic/providers/pydantic_ai.py +854 -0
- rem/agentic/query.py +117 -0
- rem/agentic/query_helper.py +89 -0
- rem/agentic/schema.py +737 -0
- rem/agentic/serialization.py +245 -0
- rem/agentic/tools/__init__.py +5 -0
- rem/agentic/tools/rem_tools.py +242 -0
- rem/api/README.md +657 -0
- rem/api/deps.py +253 -0
- rem/api/main.py +460 -0
- rem/api/mcp_router/prompts.py +182 -0
- rem/api/mcp_router/resources.py +820 -0
- rem/api/mcp_router/server.py +243 -0
- rem/api/mcp_router/tools.py +1605 -0
- rem/api/middleware/tracking.py +172 -0
- rem/api/routers/admin.py +520 -0
- rem/api/routers/auth.py +898 -0
- rem/api/routers/chat/__init__.py +5 -0
- rem/api/routers/chat/child_streaming.py +394 -0
- rem/api/routers/chat/completions.py +702 -0
- rem/api/routers/chat/json_utils.py +76 -0
- rem/api/routers/chat/models.py +202 -0
- rem/api/routers/chat/otel_utils.py +33 -0
- rem/api/routers/chat/sse_events.py +546 -0
- rem/api/routers/chat/streaming.py +950 -0
- rem/api/routers/chat/streaming_utils.py +327 -0
- rem/api/routers/common.py +18 -0
- rem/api/routers/dev.py +87 -0
- rem/api/routers/feedback.py +276 -0
- rem/api/routers/messages.py +620 -0
- rem/api/routers/models.py +86 -0
- rem/api/routers/query.py +362 -0
- rem/api/routers/shared_sessions.py +422 -0
- rem/auth/README.md +258 -0
- rem/auth/__init__.py +36 -0
- rem/auth/jwt.py +367 -0
- rem/auth/middleware.py +318 -0
- rem/auth/providers/__init__.py +16 -0
- rem/auth/providers/base.py +376 -0
- rem/auth/providers/email.py +215 -0
- rem/auth/providers/google.py +163 -0
- rem/auth/providers/microsoft.py +237 -0
- rem/cli/README.md +517 -0
- rem/cli/__init__.py +8 -0
- rem/cli/commands/README.md +299 -0
- rem/cli/commands/__init__.py +3 -0
- rem/cli/commands/ask.py +549 -0
- rem/cli/commands/cluster.py +1808 -0
- rem/cli/commands/configure.py +495 -0
- rem/cli/commands/db.py +828 -0
- rem/cli/commands/dreaming.py +324 -0
- rem/cli/commands/experiments.py +1698 -0
- rem/cli/commands/mcp.py +66 -0
- rem/cli/commands/process.py +388 -0
- rem/cli/commands/query.py +109 -0
- rem/cli/commands/scaffold.py +47 -0
- rem/cli/commands/schema.py +230 -0
- rem/cli/commands/serve.py +106 -0
- rem/cli/commands/session.py +453 -0
- rem/cli/dreaming.py +363 -0
- rem/cli/main.py +123 -0
- rem/config.py +244 -0
- rem/mcp_server.py +41 -0
- rem/models/core/__init__.py +49 -0
- rem/models/core/core_model.py +70 -0
- rem/models/core/engram.py +333 -0
- rem/models/core/experiment.py +672 -0
- rem/models/core/inline_edge.py +132 -0
- rem/models/core/rem_query.py +246 -0
- rem/models/entities/__init__.py +68 -0
- rem/models/entities/domain_resource.py +38 -0
- rem/models/entities/feedback.py +123 -0
- rem/models/entities/file.py +57 -0
- rem/models/entities/image_resource.py +88 -0
- rem/models/entities/message.py +64 -0
- rem/models/entities/moment.py +123 -0
- rem/models/entities/ontology.py +181 -0
- rem/models/entities/ontology_config.py +131 -0
- rem/models/entities/resource.py +95 -0
- rem/models/entities/schema.py +87 -0
- rem/models/entities/session.py +84 -0
- rem/models/entities/shared_session.py +180 -0
- rem/models/entities/subscriber.py +175 -0
- rem/models/entities/user.py +93 -0
- rem/py.typed +0 -0
- rem/registry.py +373 -0
- rem/schemas/README.md +507 -0
- rem/schemas/__init__.py +6 -0
- rem/schemas/agents/README.md +92 -0
- rem/schemas/agents/core/agent-builder.yaml +235 -0
- rem/schemas/agents/core/moment-builder.yaml +178 -0
- rem/schemas/agents/core/rem-query-agent.yaml +226 -0
- rem/schemas/agents/core/resource-affinity-assessor.yaml +99 -0
- rem/schemas/agents/core/simple-assistant.yaml +19 -0
- rem/schemas/agents/core/user-profile-builder.yaml +163 -0
- rem/schemas/agents/examples/contract-analyzer.yaml +317 -0
- rem/schemas/agents/examples/contract-extractor.yaml +134 -0
- rem/schemas/agents/examples/cv-parser.yaml +263 -0
- rem/schemas/agents/examples/hello-world.yaml +37 -0
- rem/schemas/agents/examples/query.yaml +54 -0
- rem/schemas/agents/examples/simple.yaml +21 -0
- rem/schemas/agents/examples/test.yaml +29 -0
- rem/schemas/agents/rem.yaml +132 -0
- rem/schemas/evaluators/hello-world/default.yaml +77 -0
- rem/schemas/evaluators/rem/faithfulness.yaml +219 -0
- rem/schemas/evaluators/rem/lookup-correctness.yaml +182 -0
- rem/schemas/evaluators/rem/retrieval-precision.yaml +199 -0
- rem/schemas/evaluators/rem/retrieval-recall.yaml +211 -0
- rem/schemas/evaluators/rem/search-correctness.yaml +192 -0
- rem/services/__init__.py +18 -0
- rem/services/audio/INTEGRATION.md +308 -0
- rem/services/audio/README.md +376 -0
- rem/services/audio/__init__.py +15 -0
- rem/services/audio/chunker.py +354 -0
- rem/services/audio/transcriber.py +259 -0
- rem/services/content/README.md +1269 -0
- rem/services/content/__init__.py +5 -0
- rem/services/content/providers.py +760 -0
- rem/services/content/service.py +762 -0
- rem/services/dreaming/README.md +230 -0
- rem/services/dreaming/__init__.py +53 -0
- rem/services/dreaming/affinity_service.py +322 -0
- rem/services/dreaming/moment_service.py +251 -0
- rem/services/dreaming/ontology_service.py +54 -0
- rem/services/dreaming/user_model_service.py +297 -0
- rem/services/dreaming/utils.py +39 -0
- rem/services/email/__init__.py +10 -0
- rem/services/email/service.py +522 -0
- rem/services/email/templates.py +360 -0
- rem/services/embeddings/__init__.py +11 -0
- rem/services/embeddings/api.py +127 -0
- rem/services/embeddings/worker.py +435 -0
- rem/services/fs/README.md +662 -0
- rem/services/fs/__init__.py +62 -0
- rem/services/fs/examples.py +206 -0
- rem/services/fs/examples_paths.py +204 -0
- rem/services/fs/git_provider.py +935 -0
- rem/services/fs/local_provider.py +760 -0
- rem/services/fs/parsing-hooks-examples.md +172 -0
- rem/services/fs/paths.py +276 -0
- rem/services/fs/provider.py +460 -0
- rem/services/fs/s3_provider.py +1042 -0
- rem/services/fs/service.py +186 -0
- rem/services/git/README.md +1075 -0
- rem/services/git/__init__.py +17 -0
- rem/services/git/service.py +469 -0
- rem/services/phoenix/EXPERIMENT_DESIGN.md +1146 -0
- rem/services/phoenix/README.md +453 -0
- rem/services/phoenix/__init__.py +46 -0
- rem/services/phoenix/client.py +960 -0
- rem/services/phoenix/config.py +88 -0
- rem/services/phoenix/prompt_labels.py +477 -0
- rem/services/postgres/README.md +757 -0
- rem/services/postgres/__init__.py +49 -0
- rem/services/postgres/diff_service.py +599 -0
- rem/services/postgres/migration_service.py +427 -0
- rem/services/postgres/programmable_diff_service.py +635 -0
- rem/services/postgres/pydantic_to_sqlalchemy.py +562 -0
- rem/services/postgres/register_type.py +353 -0
- rem/services/postgres/repository.py +481 -0
- rem/services/postgres/schema_generator.py +661 -0
- rem/services/postgres/service.py +802 -0
- rem/services/postgres/sql_builder.py +355 -0
- rem/services/rate_limit.py +113 -0
- rem/services/rem/README.md +318 -0
- rem/services/rem/__init__.py +23 -0
- rem/services/rem/exceptions.py +71 -0
- rem/services/rem/executor.py +293 -0
- rem/services/rem/parser.py +180 -0
- rem/services/rem/queries.py +196 -0
- rem/services/rem/query.py +371 -0
- rem/services/rem/service.py +608 -0
- rem/services/session/README.md +374 -0
- rem/services/session/__init__.py +13 -0
- rem/services/session/compression.py +488 -0
- rem/services/session/pydantic_messages.py +310 -0
- rem/services/session/reload.py +85 -0
- rem/services/user_service.py +130 -0
- rem/settings.py +1877 -0
- rem/sql/background_indexes.sql +52 -0
- rem/sql/migrations/001_install.sql +983 -0
- rem/sql/migrations/002_install_models.sql +3157 -0
- rem/sql/migrations/003_optional_extensions.sql +326 -0
- rem/sql/migrations/004_cache_system.sql +282 -0
- rem/sql/migrations/005_schema_update.sql +145 -0
- rem/sql/migrations/migrate_session_id_to_uuid.sql +45 -0
- rem/utils/AGENTIC_CHUNKING.md +597 -0
- rem/utils/README.md +628 -0
- rem/utils/__init__.py +61 -0
- rem/utils/agentic_chunking.py +622 -0
- rem/utils/batch_ops.py +343 -0
- rem/utils/chunking.py +108 -0
- rem/utils/clip_embeddings.py +276 -0
- rem/utils/constants.py +97 -0
- rem/utils/date_utils.py +228 -0
- rem/utils/dict_utils.py +98 -0
- rem/utils/embeddings.py +436 -0
- rem/utils/examples/embeddings_example.py +305 -0
- rem/utils/examples/sql_types_example.py +202 -0
- rem/utils/files.py +323 -0
- rem/utils/markdown.py +16 -0
- rem/utils/mime_types.py +158 -0
- rem/utils/model_helpers.py +492 -0
- rem/utils/schema_loader.py +649 -0
- rem/utils/sql_paths.py +146 -0
- rem/utils/sql_types.py +350 -0
- rem/utils/user_id.py +81 -0
- rem/utils/vision.py +325 -0
- rem/workers/README.md +506 -0
- rem/workers/__init__.py +7 -0
- rem/workers/db_listener.py +579 -0
- rem/workers/db_maintainer.py +74 -0
- rem/workers/dreaming.py +502 -0
- rem/workers/engram_processor.py +312 -0
- rem/workers/sqs_file_processor.py +193 -0
- rem/workers/unlogged_maintainer.py +463 -0
- remdb-0.3.242.dist-info/METADATA +1632 -0
- remdb-0.3.242.dist-info/RECORD +235 -0
- remdb-0.3.242.dist-info/WHEEL +4 -0
- remdb-0.3.242.dist-info/entry_points.txt +2 -0
rem/workers/README.md
ADDED
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
# REM Dreaming Worker
|
|
2
|
+
|
|
3
|
+
Background worker for building the REM knowledge graph through memory indexing and insight extraction.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The dreaming worker processes user content to construct the REM knowledge graph through four core operations:
|
|
8
|
+
|
|
9
|
+
1. **Ontology Extraction**: Run custom extractors on files/resources for domain-specific knowledge
|
|
10
|
+
2. **User Model Updates**: Extract and update user profiles from activity
|
|
11
|
+
3. **Moment Construction**: Identify temporal narratives from resources
|
|
12
|
+
4. **Resource Affinity**: Build semantic relationships between resources
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
16
|
+
│ Dreaming Worker │
|
|
17
|
+
├─────────────────────────────────────────────────────────────┤
|
|
18
|
+
│ │
|
|
19
|
+
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
|
|
20
|
+
│ │ User Model │ │ Moment │ │ Resource │ │
|
|
21
|
+
│ │ Updater │ │ Constructor │ │ Affinity │ │
|
|
22
|
+
│ └───────┬───────┘ └───────┬───────┘ └───────┬───────┘ │
|
|
23
|
+
│ │ │ │ │
|
|
24
|
+
│ └──────────────────┼──────────────────┘ │
|
|
25
|
+
│ │ │
|
|
26
|
+
│ ┌───────▼───────┐ │
|
|
27
|
+
│ │ REM Services │ │
|
|
28
|
+
│ │ - Repository │ │
|
|
29
|
+
│ │ - Query │ │
|
|
30
|
+
│ │ - Embedding │ │
|
|
31
|
+
│ └───────────────┘ │
|
|
32
|
+
└─────────────────────────────────────────────────────────────┘
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Design Philosophy
|
|
36
|
+
|
|
37
|
+
**Lean Implementation**: Push complex utilities to services
|
|
38
|
+
- Worker focuses on orchestration and coordination
|
|
39
|
+
- Complex operations delegated to REM services
|
|
40
|
+
- Minimal business logic in worker code
|
|
41
|
+
|
|
42
|
+
**REM-First**: Use REM system for all reads and writes
|
|
43
|
+
- Query API for resource retrieval
|
|
44
|
+
- PostgresService/Repository for entity persistence
|
|
45
|
+
- Embedding API for vector operations
|
|
46
|
+
- Chat completions for LLM operations
|
|
47
|
+
|
|
48
|
+
**Modular**: Each operation is independent and composable
|
|
49
|
+
- User model updates can run independently
|
|
50
|
+
- Moment construction doesn't depend on affinity
|
|
51
|
+
- Affinity can use different modes (semantic vs LLM)
|
|
52
|
+
|
|
53
|
+
**Observable**: Rich logging and metrics
|
|
54
|
+
- Structured JSON logs for parsing
|
|
55
|
+
- Metrics for resources processed, moments created, edges added
|
|
56
|
+
- OpenTelemetry traces for distributed tracing
|
|
57
|
+
|
|
58
|
+
**Cloud-Native**: Designed for Kubernetes CronJob execution
|
|
59
|
+
- Stateless workers (no shared state)
|
|
60
|
+
- Spot instance tolerant
|
|
61
|
+
- Resource limits enforced
|
|
62
|
+
- Completion tracking
|
|
63
|
+
|
|
64
|
+
## Operations
|
|
65
|
+
|
|
66
|
+
### Ontology Extraction
|
|
67
|
+
|
|
68
|
+
Runs custom extractors on user's files and resources to extract domain-specific structured knowledge.
|
|
69
|
+
|
|
70
|
+
**What is an Ontology?**
|
|
71
|
+
|
|
72
|
+
An ontology is domain-specific knowledge extracted from files using custom agent schemas. Unlike generic chunking and embedding:
|
|
73
|
+
- **Structured**: Extracts specific fields (e.g., candidate skills, contract terms, medical diagnoses)
|
|
74
|
+
- **Validated**: Uses JSON Schema for output structure
|
|
75
|
+
- **Searchable**: Semantic search on extracted fields
|
|
76
|
+
- **Queryable**: Direct queries on structured data
|
|
77
|
+
|
|
78
|
+
**Examples:**
|
|
79
|
+
- **Recruitment**: Extract candidate skills, experience, education from CVs
|
|
80
|
+
- **Legal**: Extract parties, obligations, financial terms from contracts
|
|
81
|
+
- **Medical**: Extract diagnoses, medications, treatments from health records
|
|
82
|
+
- **Financial**: Extract metrics, risks, forecasts from reports
|
|
83
|
+
|
|
84
|
+
**How It Works:**
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
88
|
+
│ 1. Load User's Files/Resources (lookback window) │
|
|
89
|
+
│ - Query files WHERE user_id=X AND updated > cutoff │
|
|
90
|
+
│ - Filter by processing_status='completed' │
|
|
91
|
+
└──────────────────┬───────────────────────────────────────────────┘
|
|
92
|
+
│
|
|
93
|
+
┌──────────────────▼───────────────────────────────────────────────┐
|
|
94
|
+
│ 2. Load Matching Extractor Schemas │
|
|
95
|
+
│ - Find schemas with category='ontology-extractor' │
|
|
96
|
+
│ - Check user's OntologyConfig rules (MIME type, tags, etc.) │
|
|
97
|
+
└──────────────────┬───────────────────────────────────────────────┘
|
|
98
|
+
│
|
|
99
|
+
┌──────────────────▼───────────────────────────────────────────────┐
|
|
100
|
+
│ 3. Run Extraction (for each file + schema pair) │
|
|
101
|
+
│ - Load schema from database │
|
|
102
|
+
│ - Create agent: create_pydantic_ai_agent(schema.spec) │
|
|
103
|
+
│ - Run agent: result = await agent.run(file.content) │
|
|
104
|
+
│ - Serialize: serialize_agent_result(result.output) │
|
|
105
|
+
└──────────────────┬───────────────────────────────────────────────┘
|
|
106
|
+
│
|
|
107
|
+
┌──────────────────▼───────────────────────────────────────────────┐
|
|
108
|
+
│ 4. Generate Embeddings │
|
|
109
|
+
│ - Extract fields: extract_fields_for_embedding() │
|
|
110
|
+
│ - Generate embedding: generate_embeddings() │
|
|
111
|
+
└──────────────────┬───────────────────────────────────────────────┘
|
|
112
|
+
│
|
|
113
|
+
┌──────────────────▼───────────────────────────────────────────────┐
|
|
114
|
+
│ 5. Store Ontology Entity │
|
|
115
|
+
│ - Ontology(extracted_data=..., embedding_text=...) │
|
|
116
|
+
│ - Save via ontology_repo.upsert() │
|
|
117
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Key Principle: No Separate Service**
|
|
121
|
+
|
|
122
|
+
Ontology extraction is NOT a separate service. It's just:
|
|
123
|
+
- Load schema (existing repository)
|
|
124
|
+
- Run agent (existing `create_pydantic_ai_agent()`)
|
|
125
|
+
- Serialize result (existing `serialize_agent_result()`)
|
|
126
|
+
- Extract embedding text (util: `extract_fields_for_embedding()`)
|
|
127
|
+
- Generate embedding (existing `generate_embeddings()`)
|
|
128
|
+
- Store ontology (existing repository)
|
|
129
|
+
|
|
130
|
+
All logic lives in the dreaming worker. Maximum DRY.
|
|
131
|
+
|
|
132
|
+
**Process:**
|
|
133
|
+
1. Query user's files/resources (lookback window)
|
|
134
|
+
2. For each file, find matching extractor schemas
|
|
135
|
+
3. Run agent extraction on file content
|
|
136
|
+
4. Extract embedding text from configured fields
|
|
137
|
+
5. Generate embeddings for semantic search
|
|
138
|
+
6. Store Ontology entity
|
|
139
|
+
|
|
140
|
+
**Output:**
|
|
141
|
+
- Ontology entities with:
|
|
142
|
+
- `extracted_data`: Arbitrary structured JSON (the gold!)
|
|
143
|
+
- `file_id`: Link to source file
|
|
144
|
+
- `agent_schema_id`: Which agent extracted this
|
|
145
|
+
- `provider_name`, `model_name`: LLM used
|
|
146
|
+
- `confidence_score`: Optional quality metric (0.0-1.0)
|
|
147
|
+
- `embedding_text`: Text for semantic search
|
|
148
|
+
|
|
149
|
+
**CLI:**
|
|
150
|
+
```bash
|
|
151
|
+
# Run custom extractor on user's data
|
|
152
|
+
rem dreaming custom --user-id user-123 --extractor cv-parser-v1
|
|
153
|
+
|
|
154
|
+
# With lookback and limit
|
|
155
|
+
rem dreaming custom --user-id user-123 --extractor contract-analyzer-v1 \\
|
|
156
|
+
--lookback-hours 168 --limit 50
|
|
157
|
+
|
|
158
|
+
# Override provider
|
|
159
|
+
rem dreaming custom --user-id user-123 --extractor cv-parser-v1 \\
|
|
160
|
+
--provider anthropic --model claude-sonnet-4-5
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Frequency:** On-demand or as part of full workflow
|
|
164
|
+
|
|
165
|
+
**Example Extractors:**
|
|
166
|
+
|
|
167
|
+
**CV Parser** (`cv-parser-v1.yaml`):
|
|
168
|
+
```yaml
|
|
169
|
+
Extracts: candidate_name, email, skills, experience, education, certifications
|
|
170
|
+
Use case: Recruitment consultants processing resumes
|
|
171
|
+
Embedding fields: candidate_name, professional_summary, skills, experience
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Contract Analyzer** (`contract-analyzer-v1.yaml`):
|
|
175
|
+
```yaml
|
|
176
|
+
Extracts: parties, financial_terms, key_obligations, risk_flags
|
|
177
|
+
Use case: Legal teams analyzing supplier/partnership agreements
|
|
178
|
+
Embedding fields: contract_title, contract_type, parties, key_obligations
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Creating Custom Extractors:**
|
|
182
|
+
|
|
183
|
+
1. Define JSON Schema with output structure
|
|
184
|
+
2. Add system prompt in `description` field
|
|
185
|
+
3. Specify `embedding_fields` in `json_schema_extra`
|
|
186
|
+
4. Optionally specify `provider_configs` for multi-provider testing
|
|
187
|
+
5. Save to database as Schema entity
|
|
188
|
+
6. Create OntologyConfig rules (MIME type, URI pattern, tags)
|
|
189
|
+
|
|
190
|
+
See `rem/schemas/ontology_extractors/` for examples.
|
|
191
|
+
|
|
192
|
+
### User Model Updates
|
|
193
|
+
|
|
194
|
+
Reads recent activity to generate comprehensive user profiles.
|
|
195
|
+
|
|
196
|
+
**Process:**
|
|
197
|
+
1. Query REM for recent sessions, moments, resources
|
|
198
|
+
2. Generate user summary using LLM
|
|
199
|
+
3. Update User entity with summary and metadata
|
|
200
|
+
4. Add graph edges to key resources and moments
|
|
201
|
+
|
|
202
|
+
**Output:**
|
|
203
|
+
- Updated User entity with summary field
|
|
204
|
+
- Graph edges to recent resources (rel_type="engaged_with")
|
|
205
|
+
- Activity level classification (active, moderate, inactive)
|
|
206
|
+
- Interest and topic extraction
|
|
207
|
+
|
|
208
|
+
**CLI:**
|
|
209
|
+
```bash
|
|
210
|
+
rem-dreaming user-model
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Frequency:** Daily (runs as part of full workflow)
|
|
214
|
+
|
|
215
|
+
### Moment Construction
|
|
216
|
+
|
|
217
|
+
Extracts temporal narratives from resources.
|
|
218
|
+
|
|
219
|
+
**Process:**
|
|
220
|
+
1. Query REM for recent resources (lookback window)
|
|
221
|
+
2. Use LLM to extract temporal narratives
|
|
222
|
+
3. Create Moment entities with temporal boundaries
|
|
223
|
+
4. Link moments to source resources via graph edges
|
|
224
|
+
5. Generate embeddings for moment content
|
|
225
|
+
|
|
226
|
+
**Output:**
|
|
227
|
+
- Moment entities with:
|
|
228
|
+
- Temporal boundaries (starts_timestamp, ends_timestamp)
|
|
229
|
+
- Present persons
|
|
230
|
+
- Emotion tags (focused, excited, concerned)
|
|
231
|
+
- Topic tags (sprint-planning, api-design)
|
|
232
|
+
- Natural language summaries
|
|
233
|
+
- Graph edges to source resources (rel_type="extracted_from")
|
|
234
|
+
|
|
235
|
+
**CLI:**
|
|
236
|
+
```bash
|
|
237
|
+
# Process last 24 hours
|
|
238
|
+
rem-dreaming moments
|
|
239
|
+
|
|
240
|
+
# Custom lookback
|
|
241
|
+
rem-dreaming moments --lookback-hours=48
|
|
242
|
+
|
|
243
|
+
# Limit resources processed
|
|
244
|
+
rem-dreaming moments --limit=100
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Frequency:** Daily or on-demand
|
|
248
|
+
|
|
249
|
+
### Resource Affinity
|
|
250
|
+
|
|
251
|
+
Builds semantic relationships between resources.
|
|
252
|
+
|
|
253
|
+
**Modes:**
|
|
254
|
+
|
|
255
|
+
**Semantic Mode (Fast)**
|
|
256
|
+
- Vector similarity search
|
|
257
|
+
- Creates edges for similar resources (threshold: 0.7)
|
|
258
|
+
- No LLM calls, pure vector math
|
|
259
|
+
- Cheap and fast
|
|
260
|
+
- Good for frequent updates (every 6 hours)
|
|
261
|
+
|
|
262
|
+
**LLM Mode (Intelligent)**
|
|
263
|
+
- LLM assessment of relationship context
|
|
264
|
+
- Rich metadata in edge properties
|
|
265
|
+
- Expensive (many LLM calls)
|
|
266
|
+
- ALWAYS use --limit to control costs
|
|
267
|
+
- Good for deep weekly analysis
|
|
268
|
+
|
|
269
|
+
**Process:**
|
|
270
|
+
1. Query REM for recent resources
|
|
271
|
+
2. For each resource:
|
|
272
|
+
- Semantic: Query similar resources by vector
|
|
273
|
+
- LLM: Assess relationships using LLM
|
|
274
|
+
3. Create graph edges via REM repository
|
|
275
|
+
4. Update resource entities with affinity edges
|
|
276
|
+
|
|
277
|
+
**Output:**
|
|
278
|
+
- Graph edges between resources with:
|
|
279
|
+
- rel_type: semantic_similar, references, builds_on, etc.
|
|
280
|
+
- weight: Relationship strength (0.0-1.0)
|
|
281
|
+
- properties: Rich metadata (confidence, context)
|
|
282
|
+
|
|
283
|
+
**CLI:**
|
|
284
|
+
```bash
|
|
285
|
+
# Semantic mode (fast, cheap)
|
|
286
|
+
rem-dreaming affinity
|
|
287
|
+
|
|
288
|
+
# LLM mode (intelligent, expensive)
|
|
289
|
+
rem-dreaming affinity --use-llm --limit=100
|
|
290
|
+
|
|
291
|
+
# Custom lookback
|
|
292
|
+
rem-dreaming affinity --lookback-hours=168
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Frequency:**
|
|
296
|
+
- Semantic: Every 6 hours
|
|
297
|
+
- LLM: Weekly (Sundays)
|
|
298
|
+
|
|
299
|
+
### Full Workflow
|
|
300
|
+
|
|
301
|
+
Runs all operations in sequence.
|
|
302
|
+
|
|
303
|
+
**Process:**
|
|
304
|
+
1. Update user model
|
|
305
|
+
2. Construct moments
|
|
306
|
+
3. Build resource affinity
|
|
307
|
+
|
|
308
|
+
**CLI:**
|
|
309
|
+
```bash
|
|
310
|
+
# Single tenant
|
|
311
|
+
rem-dreaming full
|
|
312
|
+
|
|
313
|
+
# All active tenants (daily cron)
|
|
314
|
+
rem-dreaming full --all-tenants
|
|
315
|
+
|
|
316
|
+
# Use LLM affinity mode
|
|
317
|
+
rem-dreaming full --use-llm-affinity
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Frequency:** Daily at 3 AM UTC
|
|
321
|
+
|
|
322
|
+
## Environment Variables
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# REM Configuration
|
|
326
|
+
REM_API_URL=http://rem-api:8000 # REM API endpoint
|
|
327
|
+
REM_EMBEDDING_PROVIDER=text-embedding-3-small # Embedding provider
|
|
328
|
+
REM_DEFAULT_MODEL=gpt-4o # LLM model
|
|
329
|
+
REM_LOOKBACK_HOURS=24 # Default lookback window
|
|
330
|
+
|
|
331
|
+
# API Keys
|
|
332
|
+
OPENAI_API_KEY=sk-... # OpenAI API key
|
|
333
|
+
ANTHROPIC_API_KEY=sk-ant-... # Anthropic API key (optional)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Kubernetes Deployment
|
|
337
|
+
|
|
338
|
+
### CronJobs
|
|
339
|
+
|
|
340
|
+
**Daily Full Workflow** (3 AM UTC)
|
|
341
|
+
```yaml
|
|
342
|
+
schedule: "0 3 * * *"
|
|
343
|
+
command: rem-dreaming full --all-tenants
|
|
344
|
+
resources: 256Mi memory, 250m CPU
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Frequent Affinity Updates** (Every 6 hours)
|
|
348
|
+
```yaml
|
|
349
|
+
schedule: "0 */6 * * *"
|
|
350
|
+
command: rem-dreaming affinity --all-tenants --lookback-hours=6
|
|
351
|
+
resources: 256Mi memory, 250m CPU
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**Weekly LLM Affinity** (Sundays 2 AM)
|
|
355
|
+
```yaml
|
|
356
|
+
schedule: "0 2 * * 0"
|
|
357
|
+
command: rem-dreaming affinity --all-tenants --use-llm --limit=500
|
|
358
|
+
resources: 512Mi memory, 500m CPU
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Deployment
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
# Apply via Kustomize
|
|
365
|
+
kubectl apply -k manifests/application/rem-stack/base
|
|
366
|
+
|
|
367
|
+
# Or via ArgoCD
|
|
368
|
+
kubectl apply -f manifests/application/rem-stack/argocd-staging.yaml
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Monitoring
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
# List CronJobs
|
|
375
|
+
kubectl get cronjobs -n rem-app
|
|
376
|
+
|
|
377
|
+
# List Jobs
|
|
378
|
+
kubectl get jobs -n rem-app
|
|
379
|
+
|
|
380
|
+
# Follow logs
|
|
381
|
+
kubectl logs -f -l app=rem-dreaming -n rem-app
|
|
382
|
+
|
|
383
|
+
# Manual trigger
|
|
384
|
+
kubectl create job dreaming-manual-$(date +%s) \
|
|
385
|
+
--from=cronjob/rem-dreaming-worker \
|
|
386
|
+
-n rem-app
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Cost Management
|
|
390
|
+
|
|
391
|
+
### Semantic Mode (Cheap)
|
|
392
|
+
- Only embedding costs (if generating new embeddings)
|
|
393
|
+
- Vector similarity is computational, not API calls
|
|
394
|
+
- Good for frequent updates
|
|
395
|
+
|
|
396
|
+
### LLM Mode (Expensive)
|
|
397
|
+
- Each resource pair = 1 LLM API call
|
|
398
|
+
- 100 resources = potentially 5,000 API calls
|
|
399
|
+
- ALWAYS use --limit to control costs
|
|
400
|
+
- Monitor costs in LLM provider dashboard
|
|
401
|
+
|
|
402
|
+
### Best Practices
|
|
403
|
+
1. Use semantic mode for frequent updates (6 hours)
|
|
404
|
+
2. Use LLM mode sparingly (weekly)
|
|
405
|
+
3. Always use --limit with LLM mode
|
|
406
|
+
4. Start with small lookback windows (24-48 hours)
|
|
407
|
+
5. Monitor embedding/LLM costs regularly
|
|
408
|
+
|
|
409
|
+
## Error Handling
|
|
410
|
+
|
|
411
|
+
**Graceful Degradation**
|
|
412
|
+
- Continue on partial failures
|
|
413
|
+
- Don't fail entire job if one tenant fails
|
|
414
|
+
- Log errors with context for debugging
|
|
415
|
+
|
|
416
|
+
**Retry Logic**
|
|
417
|
+
- Exponential backoff for transient errors
|
|
418
|
+
- Retry up to 3 times for API failures
|
|
419
|
+
- Don't retry on validation errors
|
|
420
|
+
|
|
421
|
+
**Job Status**
|
|
422
|
+
- Save success/failure status to database
|
|
423
|
+
- Include error messages and stack traces
|
|
424
|
+
- Enable post-mortem debugging
|
|
425
|
+
|
|
426
|
+
## Performance
|
|
427
|
+
|
|
428
|
+
**Batch Operations**
|
|
429
|
+
- Minimize round trips to REM API
|
|
430
|
+
- Batch entity creation (upsert multiple)
|
|
431
|
+
- Batch embedding generation
|
|
432
|
+
|
|
433
|
+
**Streaming**
|
|
434
|
+
- Process large result sets incrementally
|
|
435
|
+
- Don't load all resources into memory
|
|
436
|
+
- Use cursor-based pagination
|
|
437
|
+
|
|
438
|
+
**Parallelization**
|
|
439
|
+
- Use asyncio for concurrent operations
|
|
440
|
+
- Process multiple tenants in parallel
|
|
441
|
+
- Limit concurrency to avoid overwhelming API
|
|
442
|
+
|
|
443
|
+
**Caching**
|
|
444
|
+
- Cache embeddings (REM handles this)
|
|
445
|
+
- Cache LLM responses when possible
|
|
446
|
+
- Use etags for conditional requests
|
|
447
|
+
|
|
448
|
+
## Development
|
|
449
|
+
|
|
450
|
+
### Local Testing
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
# Set environment variables
|
|
454
|
+
export REM_API_URL=http://localhost:8000
|
|
455
|
+
export OPENAI_API_KEY=sk-...
|
|
456
|
+
|
|
457
|
+
# Run user model update
|
|
458
|
+
python -m rem.cli.dreaming user-model
|
|
459
|
+
|
|
460
|
+
# Run moment construction
|
|
461
|
+
python -m rem.cli.dreaming moments --lookback-hours=24
|
|
462
|
+
|
|
463
|
+
# Run affinity (semantic mode)
|
|
464
|
+
python -m rem.cli.dreaming affinity
|
|
465
|
+
|
|
466
|
+
# Run full workflow
|
|
467
|
+
python -m rem.cli.dreaming full
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### Testing with Docker
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
# Build image
|
|
474
|
+
docker build -t rem-stack:latest -f Dockerfile .
|
|
475
|
+
|
|
476
|
+
# Run worker
|
|
477
|
+
docker run --rm \
|
|
478
|
+
-e REM_API_URL=http://host.docker.internal:8000 \
|
|
479
|
+
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
|
480
|
+
rem-stack:latest \
|
|
481
|
+
python -m rem.cli.dreaming full
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
## Architecture Decisions
|
|
485
|
+
|
|
486
|
+
### Why Lean?
|
|
487
|
+
Complex operations belong in services (postgres, embeddings, etc.), not workers. Workers orchestrate, services execute.
|
|
488
|
+
|
|
489
|
+
### Why REM-First?
|
|
490
|
+
Using REM APIs ensures consistency, observability, and reusability. No direct database access in workers.
|
|
491
|
+
|
|
492
|
+
### Why Separate Modes?
|
|
493
|
+
Semantic mode is cheap and fast (frequent updates). LLM mode is expensive and intelligent (deep analysis).
|
|
494
|
+
|
|
495
|
+
### Why CronJob?
|
|
496
|
+
Batch processing is more efficient than continuous streaming. Daily indexing provides fresh insights without constant load.
|
|
497
|
+
|
|
498
|
+
### Why Spot Instances?
|
|
499
|
+
Workers are fault-tolerant and can restart. Spot instances reduce costs by 70% with minimal impact.
|
|
500
|
+
|
|
501
|
+
## Related Documentation
|
|
502
|
+
|
|
503
|
+
- [Engram Specification](../../models/core/engram.py) - Core memory model
|
|
504
|
+
- [REM Query API](../../api/) - Query interface
|
|
505
|
+
- [PostgresService & Repository](../../services/postgres/) - Entity persistence
|
|
506
|
+
- [CLAUDE.md](../../../../CLAUDE.md) - Overall architecture
|
rem/workers/__init__.py
ADDED