remdb 0.3.181__py3-none-any.whl → 0.3.223__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/agentic/README.md +262 -2
- rem/agentic/context.py +173 -0
- rem/agentic/context_builder.py +12 -2
- rem/agentic/mcp/tool_wrapper.py +2 -2
- rem/agentic/providers/pydantic_ai.py +1 -1
- rem/agentic/schema.py +2 -2
- rem/api/main.py +1 -1
- rem/api/mcp_router/server.py +4 -0
- rem/api/mcp_router/tools.py +542 -170
- rem/api/routers/admin.py +30 -4
- rem/api/routers/auth.py +106 -10
- rem/api/routers/chat/completions.py +66 -18
- rem/api/routers/chat/sse_events.py +7 -3
- rem/api/routers/chat/streaming.py +254 -22
- rem/api/routers/common.py +18 -0
- rem/api/routers/dev.py +7 -1
- rem/api/routers/feedback.py +9 -1
- rem/api/routers/messages.py +176 -38
- rem/api/routers/models.py +9 -1
- rem/api/routers/query.py +12 -1
- rem/api/routers/shared_sessions.py +16 -0
- rem/auth/jwt.py +19 -4
- rem/auth/middleware.py +42 -28
- rem/cli/README.md +62 -0
- rem/cli/commands/db.py +33 -19
- rem/cli/commands/process.py +171 -43
- rem/models/entities/ontology.py +18 -20
- rem/schemas/agents/rem.yaml +1 -1
- rem/services/content/service.py +18 -5
- rem/services/postgres/__init__.py +28 -3
- rem/services/postgres/diff_service.py +57 -5
- rem/services/postgres/programmable_diff_service.py +635 -0
- rem/services/postgres/pydantic_to_sqlalchemy.py +2 -2
- rem/services/postgres/register_type.py +11 -10
- rem/services/postgres/repository.py +14 -4
- rem/services/session/__init__.py +8 -1
- rem/services/session/compression.py +40 -2
- rem/services/session/pydantic_messages.py +276 -0
- rem/settings.py +28 -0
- rem/sql/migrations/001_install.sql +125 -7
- rem/sql/migrations/002_install_models.sql +136 -126
- rem/sql/migrations/004_cache_system.sql +7 -275
- rem/sql/migrations/migrate_session_id_to_uuid.sql +45 -0
- rem/utils/schema_loader.py +6 -6
- {remdb-0.3.181.dist-info → remdb-0.3.223.dist-info}/METADATA +1 -1
- {remdb-0.3.181.dist-info → remdb-0.3.223.dist-info}/RECORD +48 -44
- {remdb-0.3.181.dist-info → remdb-0.3.223.dist-info}/WHEEL +0 -0
- {remdb-0.3.181.dist-info → remdb-0.3.223.dist-info}/entry_points.txt +0 -0
|
@@ -5,12 +5,17 @@ Uses Alembic autogenerate to detect differences between:
|
|
|
5
5
|
- Target schema (derived from Pydantic models)
|
|
6
6
|
- Current database schema
|
|
7
7
|
|
|
8
|
+
Also compares programmable objects (functions, triggers, views) which
|
|
9
|
+
Alembic does not track.
|
|
10
|
+
|
|
8
11
|
This enables:
|
|
9
12
|
1. Local development: See what would change before applying migrations
|
|
10
13
|
2. CI validation: Detect drift between code and database (--check mode)
|
|
11
14
|
3. Migration generation: Create incremental migration files
|
|
12
15
|
"""
|
|
13
16
|
|
|
17
|
+
import asyncio
|
|
18
|
+
import re
|
|
14
19
|
from dataclasses import dataclass, field
|
|
15
20
|
from pathlib import Path
|
|
16
21
|
from typing import Optional
|
|
@@ -51,11 +56,14 @@ class SchemaDiff:
|
|
|
51
56
|
sql: str = ""
|
|
52
57
|
upgrade_ops: Optional[ops.UpgradeOps] = None
|
|
53
58
|
filtered_count: int = 0 # Number of operations filtered out by strategy
|
|
59
|
+
# Programmable objects (functions, triggers, views)
|
|
60
|
+
programmable_summary: list[str] = field(default_factory=list)
|
|
61
|
+
programmable_sql: str = ""
|
|
54
62
|
|
|
55
63
|
@property
|
|
56
64
|
def change_count(self) -> int:
|
|
57
65
|
"""Total number of detected changes."""
|
|
58
|
-
return len(self.summary)
|
|
66
|
+
return len(self.summary) + len(self.programmable_summary)
|
|
59
67
|
|
|
60
68
|
|
|
61
69
|
class DiffService:
|
|
@@ -127,10 +135,13 @@ class DiffService:
|
|
|
127
135
|
# These are now generated in pydantic_to_sqlalchemy
|
|
128
136
|
return True
|
|
129
137
|
|
|
130
|
-
def compute_diff(self) -> SchemaDiff:
|
|
138
|
+
def compute_diff(self, include_programmable: bool = True) -> SchemaDiff:
|
|
131
139
|
"""
|
|
132
140
|
Compare Pydantic models against database and return differences.
|
|
133
141
|
|
|
142
|
+
Args:
|
|
143
|
+
include_programmable: If True, also diff functions/triggers/views
|
|
144
|
+
|
|
134
145
|
Returns:
|
|
135
146
|
SchemaDiff with detected changes
|
|
136
147
|
"""
|
|
@@ -167,21 +178,62 @@ class DiffService:
|
|
|
167
178
|
for op in filtered_ops:
|
|
168
179
|
summary.extend(self._describe_operation(op))
|
|
169
180
|
|
|
170
|
-
has_changes = len(summary) > 0
|
|
171
|
-
|
|
172
181
|
# Generate SQL if there are changes
|
|
173
182
|
sql = ""
|
|
174
|
-
if
|
|
183
|
+
if summary and upgrade_ops:
|
|
175
184
|
sql = self._render_sql(upgrade_ops, engine)
|
|
176
185
|
|
|
186
|
+
# Programmable objects diff (functions, triggers, views)
|
|
187
|
+
programmable_summary = []
|
|
188
|
+
programmable_sql = ""
|
|
189
|
+
if include_programmable:
|
|
190
|
+
prog_summary, prog_sql = self._compute_programmable_diff()
|
|
191
|
+
programmable_summary = prog_summary
|
|
192
|
+
programmable_sql = prog_sql
|
|
193
|
+
|
|
194
|
+
has_changes = len(summary) > 0 or len(programmable_summary) > 0
|
|
195
|
+
|
|
177
196
|
return SchemaDiff(
|
|
178
197
|
has_changes=has_changes,
|
|
179
198
|
summary=summary,
|
|
180
199
|
sql=sql,
|
|
181
200
|
upgrade_ops=upgrade_ops,
|
|
182
201
|
filtered_count=filtered_count,
|
|
202
|
+
programmable_summary=programmable_summary,
|
|
203
|
+
programmable_sql=programmable_sql,
|
|
183
204
|
)
|
|
184
205
|
|
|
206
|
+
def _compute_programmable_diff(self) -> tuple[list[str], str]:
|
|
207
|
+
"""
|
|
208
|
+
Compute diff for programmable objects (functions, triggers, views).
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
Tuple of (summary_lines, sync_sql)
|
|
212
|
+
"""
|
|
213
|
+
from .programmable_diff_service import ProgrammableDiffService
|
|
214
|
+
|
|
215
|
+
service = ProgrammableDiffService()
|
|
216
|
+
|
|
217
|
+
# Run async diff in sync context
|
|
218
|
+
try:
|
|
219
|
+
loop = asyncio.get_event_loop()
|
|
220
|
+
except RuntimeError:
|
|
221
|
+
loop = asyncio.new_event_loop()
|
|
222
|
+
asyncio.set_event_loop(loop)
|
|
223
|
+
|
|
224
|
+
result = loop.run_until_complete(service.compute_diff())
|
|
225
|
+
|
|
226
|
+
summary = []
|
|
227
|
+
for diff in result.diffs:
|
|
228
|
+
if diff.status == "missing":
|
|
229
|
+
summary.append(f"+ {diff.object_type.value.upper()} {diff.name} (missing)")
|
|
230
|
+
elif diff.status == "different":
|
|
231
|
+
summary.append(f"~ {diff.object_type.value.upper()} {diff.name} (different)")
|
|
232
|
+
elif diff.status == "extra":
|
|
233
|
+
summary.append(f"- {diff.object_type.value.upper()} {diff.name} (extra in db)")
|
|
234
|
+
|
|
235
|
+
return summary, result.sync_sql
|
|
236
|
+
|
|
185
237
|
def _filter_operations(self, operations: list) -> tuple[list, int]:
|
|
186
238
|
"""
|
|
187
239
|
Filter operations based on migration strategy.
|