remdb 0.2.6__py3-none-any.whl → 0.3.118__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 +500 -0
- rem/agentic/context.py +28 -22
- rem/agentic/llm_provider_models.py +301 -0
- rem/agentic/mcp/tool_wrapper.py +29 -3
- rem/agentic/otel/setup.py +92 -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 +454 -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 +152 -16
- rem/api/routers/chat/models.py +7 -3
- rem/api/routers/chat/sse_events.py +526 -0
- rem/api/routers/chat/streaming.py +608 -45
- rem/api/routers/dev.py +81 -0
- rem/api/routers/feedback.py +148 -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 +15 -11
- rem/cli/commands/cluster.py +1300 -0
- rem/cli/commands/configure.py +170 -97
- rem/cli/commands/db.py +396 -139
- rem/cli/commands/experiments.py +278 -96
- 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 +37 -6
- rem/config.py +2 -2
- 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 +115 -24
- 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 +252 -19
- 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 +17 -1
- rem/services/session/reload.py +1 -1
- rem/services/user_service.py +98 -0
- rem/settings.py +169 -22
- 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 +284 -21
- 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 +2 -1
- rem/workers/db_maintainer.py +74 -0
- rem/workers/unlogged_maintainer.py +463 -0
- {remdb-0.2.6.dist-info → remdb-0.3.118.dist-info}/METADATA +598 -171
- {remdb-0.2.6.dist-info → remdb-0.3.118.dist-info}/RECORD +102 -73
- {remdb-0.2.6.dist-info → remdb-0.3.118.dist-info}/WHEEL +1 -1
- rem/sql/002_install_models.sql +0 -1068
- rem/sql/install_models.sql +0 -1038
- {remdb-0.2.6.dist-info → remdb-0.3.118.dist-info}/entry_points.txt +0 -0
rem/cli/commands/README.md
CHANGED
|
@@ -1,5 +1,191 @@
|
|
|
1
1
|
# REM CLI Commands
|
|
2
2
|
|
|
3
|
+
## Database Management (`rem db`)
|
|
4
|
+
|
|
5
|
+
REM uses a **code-as-source-of-truth** approach to database schema management. Pydantic models define the schema, and the database is kept in sync via diff-based migrations.
|
|
6
|
+
|
|
7
|
+
### Quick Reference
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
rem db schema generate # Regenerate schema SQL from registered models
|
|
11
|
+
rem db diff # Compare models vs database (detect drift)
|
|
12
|
+
rem db diff --check # CI mode: exit 1 if drift detected
|
|
13
|
+
rem db apply <file> # Apply SQL file to database
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Schema Management Workflow
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
20
|
+
│ Source of Truth │
|
|
21
|
+
│ │
|
|
22
|
+
│ Pydantic Models (CoreModel subclasses) │
|
|
23
|
+
│ └── src/rem/models/entities/*.py │
|
|
24
|
+
│ │
|
|
25
|
+
│ Model Registry │
|
|
26
|
+
│ └── Core models auto-registered │
|
|
27
|
+
│ └── Custom models via @rem.register_model │
|
|
28
|
+
└─────────────────────────────────────────────────────────────┘
|
|
29
|
+
│
|
|
30
|
+
▼
|
|
31
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
32
|
+
│ rem db schema generate │
|
|
33
|
+
│ │
|
|
34
|
+
│ Generates SQL from registry → 002_install_models.sql │
|
|
35
|
+
└─────────────────────────────────────────────────────────────┘
|
|
36
|
+
│
|
|
37
|
+
▼
|
|
38
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
39
|
+
│ rem db diff │
|
|
40
|
+
│ │
|
|
41
|
+
│ Compares models ↔ database using Alembic autogenerate │
|
|
42
|
+
│ Shows: + additions, - removals, ~ modifications │
|
|
43
|
+
└─────────────────────────────────────────────────────────────┘
|
|
44
|
+
│
|
|
45
|
+
▼
|
|
46
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
47
|
+
│ rem db apply │
|
|
48
|
+
│ │
|
|
49
|
+
│ Executes SQL directly against database │
|
|
50
|
+
│ Optionally logs to rem_migrations (audit only) │
|
|
51
|
+
└─────────────────────────────────────────────────────────────┘
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### File Structure
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
src/rem/sql/
|
|
58
|
+
├── migrations/
|
|
59
|
+
│ ├── 001_install.sql # Core infrastructure (manual)
|
|
60
|
+
│ └── 002_install_models.sql # Entity tables (auto-generated)
|
|
61
|
+
└── background_indexes.sql # HNSW vector indexes (optional)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Key principle**: Only two migration files. No incremental `003_`, `004_` files. The models file is always regenerated to match code.
|
|
65
|
+
|
|
66
|
+
### Commands
|
|
67
|
+
|
|
68
|
+
#### `rem db schema generate`
|
|
69
|
+
|
|
70
|
+
Regenerate `002_install_models.sql` from the model registry:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
rem db schema generate
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This reads all registered models (core + custom) and generates:
|
|
77
|
+
- CREATE TABLE statements for each entity
|
|
78
|
+
- Embeddings tables (`embeddings_<table>`)
|
|
79
|
+
- KV_STORE triggers for cache maintenance
|
|
80
|
+
- Foreground indexes (GIN for JSONB, B-tree for lookups)
|
|
81
|
+
|
|
82
|
+
#### `rem db diff`
|
|
83
|
+
|
|
84
|
+
Compare Pydantic models against the live database:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Show differences
|
|
88
|
+
rem db diff
|
|
89
|
+
|
|
90
|
+
# CI mode: exit 1 if drift detected
|
|
91
|
+
rem db diff --check
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Output shows:
|
|
95
|
+
- `+ ADD COLUMN` - Column exists in model but not in DB
|
|
96
|
+
- `- DROP COLUMN` - Column exists in DB but not in model
|
|
97
|
+
- `~ ALTER COLUMN` - Column type or constraints differ
|
|
98
|
+
- `+ CREATE TABLE` - Table exists in model but not in DB
|
|
99
|
+
- `- DROP TABLE` - Table exists in DB but not in model
|
|
100
|
+
|
|
101
|
+
#### `rem db apply`
|
|
102
|
+
|
|
103
|
+
Apply a SQL file directly to the database:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Apply with audit logging (default)
|
|
107
|
+
rem db apply src/rem/sql/migrations/002_install_models.sql
|
|
108
|
+
|
|
109
|
+
# Preview without executing
|
|
110
|
+
rem db apply --dry-run src/rem/sql/migrations/002_install_models.sql
|
|
111
|
+
|
|
112
|
+
# Apply without logging to rem_migrations
|
|
113
|
+
rem db apply --no-log src/rem/sql/migrations/002_install_models.sql
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Typical Workflows
|
|
117
|
+
|
|
118
|
+
#### Initial Setup
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# 1. Generate schema from models
|
|
122
|
+
rem db schema generate
|
|
123
|
+
|
|
124
|
+
# 2. Apply infrastructure (extensions, kv_store)
|
|
125
|
+
rem db apply src/rem/sql/migrations/001_install.sql
|
|
126
|
+
|
|
127
|
+
# 3. Apply entity tables
|
|
128
|
+
rem db apply src/rem/sql/migrations/002_install_models.sql
|
|
129
|
+
|
|
130
|
+
# 4. Verify no drift
|
|
131
|
+
rem db diff
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### Adding a New Entity
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# 1. Create model in src/rem/models/entities/
|
|
138
|
+
# 2. Register in src/rem/registry.py (add to core_models list)
|
|
139
|
+
# 3. Regenerate schema
|
|
140
|
+
rem db schema generate
|
|
141
|
+
|
|
142
|
+
# 4. Check what changed
|
|
143
|
+
rem db diff
|
|
144
|
+
|
|
145
|
+
# 5. Apply changes
|
|
146
|
+
rem db apply src/rem/sql/migrations/002_install_models.sql
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### Modifying an Existing Entity
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# 1. Modify model in src/rem/models/entities/
|
|
153
|
+
# 2. Regenerate schema
|
|
154
|
+
rem db schema generate
|
|
155
|
+
|
|
156
|
+
# 3. Check what changed
|
|
157
|
+
rem db diff
|
|
158
|
+
|
|
159
|
+
# 4. Apply changes (idempotent - uses IF NOT EXISTS)
|
|
160
|
+
rem db apply src/rem/sql/migrations/002_install_models.sql
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### CI/CD Pipeline
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# Fail build if schema drift detected
|
|
167
|
+
rem db diff --check
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Registering Custom Models
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
import rem
|
|
174
|
+
from rem.models.core import CoreModel
|
|
175
|
+
|
|
176
|
+
@rem.register_model
|
|
177
|
+
class MyEntity(CoreModel):
|
|
178
|
+
name: str
|
|
179
|
+
description: str # Auto-embeds (content field)
|
|
180
|
+
|
|
181
|
+
# Or with options:
|
|
182
|
+
@rem.register_model(table_name="custom_table")
|
|
183
|
+
class AnotherEntity(CoreModel):
|
|
184
|
+
title: str
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
3
189
|
## Configuration (`rem configure`)
|
|
4
190
|
|
|
5
191
|
Interactive configuration wizard for REM setup.
|
|
@@ -13,114 +199,101 @@ rem configure
|
|
|
13
199
|
# Configure + install database tables
|
|
14
200
|
rem configure --install
|
|
15
201
|
|
|
16
|
-
# Configure + install + register with Claude Desktop
|
|
17
|
-
rem configure --install --claude-desktop
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
### Managing Configuration
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
202
|
# View current configuration
|
|
24
203
|
rem configure --show
|
|
25
204
|
|
|
26
205
|
# Edit configuration file
|
|
27
|
-
rem configure --edit
|
|
28
|
-
|
|
29
|
-
# Or edit manually
|
|
30
|
-
vim ~/.rem/config.yaml
|
|
206
|
+
rem configure --edit
|
|
31
207
|
```
|
|
32
208
|
|
|
33
|
-
### Configuration File
|
|
209
|
+
### Configuration File
|
|
34
210
|
|
|
35
211
|
`~/.rem/config.yaml`:
|
|
36
212
|
|
|
37
213
|
```yaml
|
|
38
214
|
postgres:
|
|
39
215
|
connection_string: postgresql://user:pass@localhost:5432/rem
|
|
40
|
-
pool_min_size: 5
|
|
41
|
-
pool_max_size: 20
|
|
42
216
|
|
|
43
217
|
llm:
|
|
44
218
|
default_model: anthropic:claude-sonnet-4-5-20250929
|
|
45
|
-
default_temperature: 0.5
|
|
46
219
|
openai_api_key: sk-...
|
|
47
220
|
anthropic_api_key: sk-ant-...
|
|
48
221
|
|
|
49
222
|
s3:
|
|
50
223
|
bucket_name: rem-storage
|
|
51
224
|
region: us-east-1
|
|
52
|
-
# Optional: for MinIO/LocalStack
|
|
53
|
-
endpoint_url: http://localhost:9000
|
|
54
|
-
access_key_id: minioadmin
|
|
55
|
-
secret_access_key: minioadmin
|
|
56
225
|
```
|
|
57
226
|
|
|
58
227
|
### Environment Variables
|
|
59
228
|
|
|
60
|
-
All configuration can be overridden via environment variables
|
|
229
|
+
All configuration can be overridden via environment variables:
|
|
61
230
|
|
|
62
231
|
```bash
|
|
63
|
-
# Postgres
|
|
64
232
|
export POSTGRES__CONNECTION_STRING=postgresql://user:pass@host:5432/db
|
|
65
|
-
export POSTGRES__POOL_MIN_SIZE=5
|
|
66
|
-
export POSTGRES__POOL_MAX_SIZE=20
|
|
67
|
-
|
|
68
|
-
# LLM
|
|
69
233
|
export LLM__DEFAULT_MODEL=anthropic:claude-sonnet-4-5-20250929
|
|
70
234
|
export LLM__OPENAI_API_KEY=sk-...
|
|
71
|
-
export LLM__ANTHROPIC_API_KEY=sk-ant-...
|
|
72
|
-
|
|
73
|
-
# S3
|
|
74
|
-
export S3__BUCKET_NAME=rem-storage
|
|
75
|
-
export S3__REGION=us-east-1
|
|
76
235
|
```
|
|
77
236
|
|
|
78
|
-
|
|
237
|
+
**Precedence**: Environment variables > Config file > Defaults
|
|
79
238
|
|
|
80
|
-
|
|
81
|
-
2. **Configuration file** (`~/.rem/config.yaml`)
|
|
82
|
-
3. **Default values** (from `rem/settings.py`)
|
|
239
|
+
---
|
|
83
240
|
|
|
84
|
-
|
|
241
|
+
## Cluster Management (`rem cluster`)
|
|
85
242
|
|
|
86
|
-
|
|
243
|
+
Commands for deploying REM to Kubernetes.
|
|
87
244
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
245
|
+
### Quick Reference
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
rem cluster init # Initialize cluster config
|
|
249
|
+
rem cluster generate # Generate all manifests (ArgoCD, ConfigMaps, etc.)
|
|
250
|
+
rem cluster setup-ssm # Create required SSM parameters in AWS
|
|
251
|
+
rem cluster validate # Validate deployment prerequisites
|
|
252
|
+
rem cluster env check # Validate .env for cluster deployment
|
|
96
253
|
```
|
|
97
254
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
stringData:
|
|
105
|
-
POSTGRES__CONNECTION_STRING: postgresql://rem:rem@postgres:5432/rem
|
|
106
|
-
LLM__OPENAI_API_KEY: sk-...
|
|
255
|
+
### `rem cluster generate`
|
|
256
|
+
|
|
257
|
+
Generates all Kubernetes manifests from cluster config:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
rem cluster generate
|
|
107
261
|
```
|
|
108
262
|
|
|
263
|
+
This generates/updates:
|
|
264
|
+
- ArgoCD Application manifests
|
|
265
|
+
- ClusterSecretStore configurations
|
|
266
|
+
- SQL init ConfigMap (from `rem/sql/migrations/*.sql`)
|
|
267
|
+
|
|
268
|
+
The SQL ConfigMap is used by CloudNativePG for database initialization on first cluster bootstrap.
|
|
269
|
+
|
|
270
|
+
### `rem cluster env`
|
|
271
|
+
|
|
272
|
+
Environment configuration management:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
rem cluster env check # Validate .env for staging
|
|
276
|
+
rem cluster env check --env prod # Validate for production
|
|
277
|
+
rem cluster env generate # Generate ConfigMap from .env
|
|
278
|
+
rem cluster env diff # Compare .env with cluster ConfigMap
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
109
283
|
## Other Commands
|
|
110
284
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
- **`rem experiments`** - Experiment management (datasets, prompts, traces, runs)
|
|
285
|
+
| Command | Description |
|
|
286
|
+
|---------|-------------|
|
|
287
|
+
| `rem ask` | Interactive chat with REM agents |
|
|
288
|
+
| `rem serve` | Start FastAPI server |
|
|
289
|
+
| `rem mcp` | MCP server commands |
|
|
290
|
+
| `rem dreaming` | Background knowledge processing |
|
|
291
|
+
| `rem process` | File processing utilities |
|
|
119
292
|
|
|
120
|
-
Run `rem COMMAND --help` for detailed usage
|
|
293
|
+
Run `rem COMMAND --help` for detailed usage.
|
|
121
294
|
|
|
122
295
|
## See Also
|
|
123
296
|
|
|
124
|
-
- [README.md](../../../../../README.md) - Main documentation
|
|
297
|
+
- [rem/README.md](../../../../../README.md) - Main documentation
|
|
125
298
|
- [CLAUDE.md](../../../../../CLAUDE.md) - Architecture overview
|
|
126
|
-
- [
|
|
299
|
+
- [postgres/README.md](../../services/postgres/README.md) - Database service details
|
rem/cli/commands/ask.py
CHANGED
|
@@ -89,8 +89,8 @@ async def run_agent_streaming(
|
|
|
89
89
|
context: Optional AgentContext for session persistence
|
|
90
90
|
max_iterations: Maximum iterations/requests (from agent schema or settings)
|
|
91
91
|
"""
|
|
92
|
-
from datetime import datetime, timezone
|
|
93
92
|
from pydantic_ai import UsageLimits
|
|
93
|
+
from rem.utils.date_utils import to_iso_with_z, utc_now
|
|
94
94
|
|
|
95
95
|
logger.info("Running agent in streaming mode...")
|
|
96
96
|
|
|
@@ -151,13 +151,13 @@ async def run_agent_streaming(
|
|
|
151
151
|
user_message = {
|
|
152
152
|
"role": "user",
|
|
153
153
|
"content": user_message_content,
|
|
154
|
-
"timestamp":
|
|
154
|
+
"timestamp": to_iso_with_z(utc_now()),
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
assistant_message = {
|
|
158
158
|
"role": "assistant",
|
|
159
159
|
"content": "".join(assistant_response_parts),
|
|
160
|
-
"timestamp":
|
|
160
|
+
"timestamp": to_iso_with_z(utc_now()),
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
# Store messages with compression
|
|
@@ -200,8 +200,8 @@ async def run_agent_non_streaming(
|
|
|
200
200
|
Returns:
|
|
201
201
|
Output data if successful, None otherwise
|
|
202
202
|
"""
|
|
203
|
-
from datetime import datetime, timezone
|
|
204
203
|
from pydantic_ai import UsageLimits
|
|
204
|
+
from rem.utils.date_utils import to_iso_with_z, utc_now
|
|
205
205
|
|
|
206
206
|
logger.info("Running agent in non-streaming mode...")
|
|
207
207
|
|
|
@@ -248,13 +248,13 @@ async def run_agent_non_streaming(
|
|
|
248
248
|
user_message = {
|
|
249
249
|
"role": "user",
|
|
250
250
|
"content": user_message_content,
|
|
251
|
-
"timestamp":
|
|
251
|
+
"timestamp": to_iso_with_z(utc_now()),
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
assistant_message = {
|
|
255
255
|
"role": "assistant",
|
|
256
256
|
"content": assistant_content,
|
|
257
|
-
"timestamp":
|
|
257
|
+
"timestamp": to_iso_with_z(utc_now()),
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
# Store messages with compression
|
|
@@ -357,8 +357,8 @@ async def _save_output_file(file_path: Path, data: dict[str, Any]) -> None:
|
|
|
357
357
|
)
|
|
358
358
|
@click.option(
|
|
359
359
|
"--user-id",
|
|
360
|
-
default=
|
|
361
|
-
help="User ID for context (default: test
|
|
360
|
+
default=None,
|
|
361
|
+
help="User ID for context (default: from settings.test.effective_user_id)",
|
|
362
362
|
)
|
|
363
363
|
@click.option(
|
|
364
364
|
"--session-id",
|
|
@@ -393,7 +393,7 @@ def ask(
|
|
|
393
393
|
max_turns: int,
|
|
394
394
|
version: str | None,
|
|
395
395
|
stream: bool,
|
|
396
|
-
user_id: str,
|
|
396
|
+
user_id: str | None,
|
|
397
397
|
session_id: str | None,
|
|
398
398
|
input_file: Path | None,
|
|
399
399
|
output_file: Path | None,
|
|
@@ -434,6 +434,9 @@ def ask(
|
|
|
434
434
|
# Two arguments provided
|
|
435
435
|
name = name_or_query
|
|
436
436
|
|
|
437
|
+
# Resolve user_id from settings if not provided
|
|
438
|
+
effective_user_id = user_id or settings.test.effective_user_id
|
|
439
|
+
|
|
437
440
|
asyncio.run(
|
|
438
441
|
_ask_async(
|
|
439
442
|
name=name,
|
|
@@ -443,7 +446,7 @@ def ask(
|
|
|
443
446
|
max_turns=max_turns,
|
|
444
447
|
version=version,
|
|
445
448
|
stream=stream,
|
|
446
|
-
user_id=
|
|
449
|
+
user_id=effective_user_id,
|
|
447
450
|
session_id=session_id,
|
|
448
451
|
input_file=input_file,
|
|
449
452
|
output_file=output_file,
|
|
@@ -486,9 +489,10 @@ async def _ask_async(
|
|
|
486
489
|
|
|
487
490
|
# Load schema using centralized utility
|
|
488
491
|
# Handles both file paths and schema names automatically
|
|
492
|
+
# Falls back to database LOOKUP if not found in filesystem
|
|
489
493
|
logger.info(f"Loading schema: {name} (version: {version or 'latest'})")
|
|
490
494
|
try:
|
|
491
|
-
schema = load_agent_schema(name)
|
|
495
|
+
schema = load_agent_schema(name, user_id=user_id)
|
|
492
496
|
except FileNotFoundError as e:
|
|
493
497
|
logger.error(str(e))
|
|
494
498
|
sys.exit(1)
|