remdb 0.3.103__py3-none-any.whl → 0.3.141__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.

Files changed (74) hide show
  1. rem/agentic/agents/sse_simulator.py +2 -0
  2. rem/agentic/context.py +51 -27
  3. rem/agentic/mcp/tool_wrapper.py +155 -18
  4. rem/agentic/otel/setup.py +93 -4
  5. rem/agentic/providers/phoenix.py +371 -108
  6. rem/agentic/providers/pydantic_ai.py +195 -46
  7. rem/agentic/schema.py +361 -21
  8. rem/agentic/tools/rem_tools.py +3 -3
  9. rem/api/main.py +85 -16
  10. rem/api/mcp_router/resources.py +1 -1
  11. rem/api/mcp_router/server.py +18 -4
  12. rem/api/mcp_router/tools.py +394 -16
  13. rem/api/routers/admin.py +218 -1
  14. rem/api/routers/chat/completions.py +280 -7
  15. rem/api/routers/chat/models.py +81 -7
  16. rem/api/routers/chat/otel_utils.py +33 -0
  17. rem/api/routers/chat/sse_events.py +17 -1
  18. rem/api/routers/chat/streaming.py +177 -3
  19. rem/api/routers/feedback.py +142 -329
  20. rem/api/routers/query.py +360 -0
  21. rem/api/routers/shared_sessions.py +13 -13
  22. rem/cli/commands/README.md +237 -64
  23. rem/cli/commands/cluster.py +1808 -0
  24. rem/cli/commands/configure.py +4 -7
  25. rem/cli/commands/db.py +354 -143
  26. rem/cli/commands/experiments.py +436 -30
  27. rem/cli/commands/process.py +14 -8
  28. rem/cli/commands/schema.py +92 -45
  29. rem/cli/commands/session.py +336 -0
  30. rem/cli/dreaming.py +2 -2
  31. rem/cli/main.py +29 -6
  32. rem/config.py +8 -1
  33. rem/models/core/experiment.py +54 -0
  34. rem/models/core/rem_query.py +5 -2
  35. rem/models/entities/ontology.py +1 -1
  36. rem/models/entities/ontology_config.py +1 -1
  37. rem/models/entities/shared_session.py +2 -28
  38. rem/registry.py +10 -4
  39. rem/schemas/agents/examples/contract-analyzer.yaml +1 -1
  40. rem/schemas/agents/examples/contract-extractor.yaml +1 -1
  41. rem/schemas/agents/examples/cv-parser.yaml +1 -1
  42. rem/services/content/service.py +30 -8
  43. rem/services/embeddings/api.py +4 -4
  44. rem/services/embeddings/worker.py +16 -16
  45. rem/services/phoenix/client.py +59 -18
  46. rem/services/postgres/README.md +151 -26
  47. rem/services/postgres/__init__.py +2 -1
  48. rem/services/postgres/diff_service.py +531 -0
  49. rem/services/postgres/pydantic_to_sqlalchemy.py +427 -129
  50. rem/services/postgres/schema_generator.py +205 -4
  51. rem/services/postgres/service.py +6 -6
  52. rem/services/rem/parser.py +44 -9
  53. rem/services/rem/service.py +36 -2
  54. rem/services/session/compression.py +7 -0
  55. rem/services/session/reload.py +1 -1
  56. rem/settings.py +288 -16
  57. rem/sql/background_indexes.sql +19 -24
  58. rem/sql/migrations/001_install.sql +252 -69
  59. rem/sql/migrations/002_install_models.sql +2197 -619
  60. rem/sql/migrations/003_optional_extensions.sql +326 -0
  61. rem/sql/migrations/004_cache_system.sql +548 -0
  62. rem/utils/__init__.py +18 -0
  63. rem/utils/date_utils.py +2 -2
  64. rem/utils/schema_loader.py +110 -15
  65. rem/utils/sql_paths.py +146 -0
  66. rem/utils/vision.py +1 -1
  67. rem/workers/__init__.py +3 -1
  68. rem/workers/db_listener.py +579 -0
  69. rem/workers/unlogged_maintainer.py +463 -0
  70. {remdb-0.3.103.dist-info → remdb-0.3.141.dist-info}/METADATA +300 -215
  71. {remdb-0.3.103.dist-info → remdb-0.3.141.dist-info}/RECORD +73 -64
  72. rem/sql/migrations/003_seed_default_user.sql +0 -48
  73. {remdb-0.3.103.dist-info → remdb-0.3.141.dist-info}/WHEEL +0 -0
  74. {remdb-0.3.103.dist-info → remdb-0.3.141.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,326 @@
1
+ -- REM Optional Extensions
2
+ -- Description: Optional PostgreSQL extensions that enhance functionality but are not required
3
+ -- Version: 1.0.0
4
+ -- Date: 2025-11-29
5
+ --
6
+ -- These extensions are installed with try/catch - failures are logged but don't break the install.
7
+ -- This allows the same migration to work on:
8
+ -- - Custom images with extensions baked in (percolationlabs/rem-pg:18)
9
+ -- - Standard PostgreSQL images (extensions will be skipped)
10
+ --
11
+ -- Extensions:
12
+ -- - pg_net: Async HTTP/HTTPS requests from triggers and functions (Supabase)
13
+
14
+ -- ============================================================================
15
+ -- pg_net: Async HTTP Extension
16
+ -- ============================================================================
17
+ -- Enables PostgreSQL to make non-blocking HTTP requests from triggers and functions.
18
+ -- Requires: Custom image with pg_net compiled, shared_preload_libraries='pg_net'
19
+ --
20
+ -- Use cases:
21
+ -- - Webhook notifications on data changes
22
+ -- - Async event publishing to external APIs
23
+ -- - Background HTTP requests from triggers
24
+
25
+ DO $$
26
+ BEGIN
27
+ -- Attempt to create pg_net extension
28
+ CREATE EXTENSION IF NOT EXISTS pg_net;
29
+ RAISE NOTICE ' pg_net extension installed successfully';
30
+ EXCEPTION
31
+ WHEN OTHERS THEN
32
+ RAISE NOTICE ' pg_net extension not available (this is OK if using standard PostgreSQL image)';
33
+ RAISE NOTICE ' Error: %', SQLERRM;
34
+ END $$;
35
+
36
+ -- ============================================================================
37
+ -- pg_net Helper Functions (only created if extension exists)
38
+ -- ============================================================================
39
+ -- Wrapper functions for common HTTP operations with sensible defaults
40
+
41
+ DO $$
42
+ BEGIN
43
+ -- Only create helpers if pg_net is available
44
+ IF EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_net') THEN
45
+
46
+ -- Helper: POST JSON to a URL with standard headers
47
+ EXECUTE $func$
48
+ CREATE OR REPLACE FUNCTION rem_http_post(
49
+ p_url TEXT,
50
+ p_body JSONB,
51
+ p_headers JSONB DEFAULT '{}'::jsonb
52
+ )
53
+ RETURNS BIGINT AS $inner$
54
+ DECLARE
55
+ merged_headers JSONB;
56
+ request_id BIGINT;
57
+ BEGIN
58
+ -- Merge default headers with provided headers
59
+ merged_headers := '{"Content-Type": "application/json"}'::jsonb || p_headers;
60
+
61
+ SELECT net.http_post(
62
+ url := p_url,
63
+ headers := merged_headers,
64
+ body := p_body
65
+ ) INTO request_id;
66
+
67
+ RETURN request_id;
68
+ END;
69
+ $inner$ LANGUAGE plpgsql;
70
+ $func$;
71
+
72
+ RAISE NOTICE ' rem_http_post helper function created';
73
+
74
+ -- Helper: GET from a URL
75
+ EXECUTE $func$
76
+ CREATE OR REPLACE FUNCTION rem_http_get(
77
+ p_url TEXT,
78
+ p_headers JSONB DEFAULT '{}'::jsonb
79
+ )
80
+ RETURNS BIGINT AS $inner$
81
+ DECLARE
82
+ request_id BIGINT;
83
+ BEGIN
84
+ SELECT net.http_get(
85
+ url := p_url,
86
+ headers := p_headers
87
+ ) INTO request_id;
88
+
89
+ RETURN request_id;
90
+ END;
91
+ $inner$ LANGUAGE plpgsql;
92
+ $func$;
93
+
94
+ RAISE NOTICE ' rem_http_get helper function created';
95
+
96
+ -- ====================================================================
97
+ -- REM Query Function
98
+ -- ====================================================================
99
+ -- Executes REM queries via the REM API using pg_net
100
+ --
101
+ -- Default API host: rem-api (works in K8s same namespace)
102
+ -- For local Docker testing: Add "host.docker.internal rem-api" to /etc/hosts
103
+ -- Or override with p_api_host parameter
104
+ --
105
+ -- Example:
106
+ -- SELECT rem_query('LOOKUP sarah-chen', 'user123');
107
+ -- SELECT rem_query('SEARCH resources ''API design'' LIMIT 5', 'user123');
108
+
109
+ EXECUTE $func$
110
+ CREATE OR REPLACE FUNCTION rem_query(
111
+ p_query TEXT,
112
+ p_user_id TEXT,
113
+ p_api_host TEXT DEFAULT 'rem-api',
114
+ p_api_port INTEGER DEFAULT 8000,
115
+ p_mode TEXT DEFAULT 'rem-dialect'
116
+ )
117
+ RETURNS BIGINT AS $inner$
118
+ DECLARE
119
+ api_url TEXT;
120
+ request_body JSONB;
121
+ request_headers JSONB;
122
+ request_id BIGINT;
123
+ BEGIN
124
+ -- Build API URL
125
+ -- Default: http://rem-api:8000/api/v1/query (K8s same namespace)
126
+ api_url := format('http://%s:%s/api/v1/query', p_api_host, p_api_port);
127
+
128
+ -- Build request body
129
+ request_body := jsonb_build_object(
130
+ 'query', p_query,
131
+ 'mode', p_mode
132
+ );
133
+
134
+ -- Build headers with user ID
135
+ request_headers := jsonb_build_object(
136
+ 'Content-Type', 'application/json',
137
+ 'X-User-Id', p_user_id
138
+ );
139
+
140
+ -- Make async HTTP POST request
141
+ SELECT net.http_post(
142
+ url := api_url,
143
+ headers := request_headers,
144
+ body := request_body
145
+ ) INTO request_id;
146
+
147
+ RETURN request_id;
148
+ END;
149
+ $inner$ LANGUAGE plpgsql;
150
+ $func$;
151
+
152
+ RAISE NOTICE ' rem_query() function created';
153
+
154
+ -- Helper to get query results (waits for async response)
155
+ -- NOTE: pg_net is async by design. This function polls for the response.
156
+ -- For best results, use rem_query() and check results later, or use longer timeouts.
157
+ EXECUTE $func$
158
+ CREATE OR REPLACE FUNCTION rem_query_result(
159
+ p_request_id BIGINT,
160
+ p_timeout_ms INTEGER DEFAULT 10000
161
+ )
162
+ RETURNS JSONB AS $inner$
163
+ DECLARE
164
+ v_status_code INTEGER;
165
+ v_content TEXT;
166
+ v_found BOOLEAN;
167
+ start_time TIMESTAMP;
168
+ elapsed_ms INTEGER;
169
+ BEGIN
170
+ start_time := clock_timestamp();
171
+
172
+ -- Poll for response with timeout
173
+ -- Each iteration starts a new query to see committed data from background worker
174
+ LOOP
175
+ -- Check if response exists (background worker commits independently)
176
+ SELECT true, status_code, content::text
177
+ INTO v_found, v_status_code, v_content
178
+ FROM net._http_response
179
+ WHERE id = p_request_id;
180
+
181
+ -- Found response
182
+ IF v_found THEN
183
+ IF v_status_code = 200 THEN
184
+ RETURN v_content::jsonb;
185
+ ELSE
186
+ RETURN jsonb_build_object(
187
+ 'error', true,
188
+ 'status_code', v_status_code,
189
+ 'content', v_content
190
+ );
191
+ END IF;
192
+ END IF;
193
+
194
+ -- Check timeout
195
+ elapsed_ms := EXTRACT(EPOCH FROM (clock_timestamp() - start_time)) * 1000;
196
+ IF elapsed_ms >= p_timeout_ms THEN
197
+ RETURN jsonb_build_object(
198
+ 'error', true,
199
+ 'message', 'Request timeout - pg_net is async, response may arrive later',
200
+ 'request_id', p_request_id,
201
+ 'hint', 'Check net._http_response table or increase timeout'
202
+ );
203
+ END IF;
204
+
205
+ -- Wait 500ms before next poll (pg_net worker runs every 100ms)
206
+ PERFORM pg_sleep(0.5);
207
+ END LOOP;
208
+ END;
209
+ $inner$ LANGUAGE plpgsql;
210
+ $func$;
211
+
212
+ RAISE NOTICE ' rem_query_result() function created';
213
+
214
+ -- Convenience function: execute query and wait for result
215
+ -- WARNING: Due to PostgreSQL transaction isolation, this may timeout even when
216
+ -- the request succeeds. The background worker commits separately and the polling
217
+ -- loop may not see the response. Use rem_query() + check net._http_response for
218
+ -- more reliable async operation.
219
+ EXECUTE $func$
220
+ CREATE OR REPLACE FUNCTION rem_query_sync(
221
+ p_query TEXT,
222
+ p_user_id TEXT,
223
+ p_api_host TEXT DEFAULT 'rem-api',
224
+ p_api_port INTEGER DEFAULT 8000,
225
+ p_mode TEXT DEFAULT 'rem-dialect',
226
+ p_timeout_ms INTEGER DEFAULT 10000
227
+ )
228
+ RETURNS JSONB AS $inner$
229
+ DECLARE
230
+ request_id BIGINT;
231
+ v_status_code INTEGER;
232
+ v_content TEXT;
233
+ v_found BOOLEAN := false;
234
+ start_time TIMESTAMP;
235
+ elapsed_ms INTEGER;
236
+ BEGIN
237
+ -- Execute query - this queues the HTTP request
238
+ request_id := rem_query(p_query, p_user_id, p_api_host, p_api_port, p_mode);
239
+
240
+ -- Wait for response with explicit snapshot refresh attempts
241
+ start_time := clock_timestamp();
242
+ LOOP
243
+ -- Query in separate subtransaction-like context
244
+ SELECT true, status_code, content::text
245
+ INTO v_found, v_status_code, v_content
246
+ FROM net._http_response
247
+ WHERE id = request_id;
248
+
249
+ IF v_found THEN
250
+ IF v_status_code = 200 THEN
251
+ RETURN v_content::jsonb;
252
+ ELSE
253
+ RETURN jsonb_build_object('error', true, 'status_code', v_status_code, 'content', v_content);
254
+ END IF;
255
+ END IF;
256
+
257
+ elapsed_ms := EXTRACT(EPOCH FROM (clock_timestamp() - start_time)) * 1000;
258
+ IF elapsed_ms >= p_timeout_ms THEN
259
+ -- Return info about the async request so caller can check later
260
+ RETURN jsonb_build_object(
261
+ 'pending', true,
262
+ 'request_id', request_id,
263
+ 'message', 'Request queued but response not yet visible due to transaction isolation',
264
+ 'hint', 'Query net._http_response WHERE id = ' || request_id || ' after this transaction commits'
265
+ );
266
+ END IF;
267
+
268
+ PERFORM pg_sleep(0.3);
269
+ END LOOP;
270
+ END;
271
+ $inner$ LANGUAGE plpgsql;
272
+ $func$;
273
+
274
+ RAISE NOTICE ' rem_query_sync() function created (async pattern recommended)';
275
+
276
+ ELSE
277
+ RAISE NOTICE ' Skipping pg_net helper functions (extension not installed)';
278
+ END IF;
279
+ END $$;
280
+
281
+ -- ============================================================================
282
+ -- RECORD INSTALLATION
283
+ -- ============================================================================
284
+
285
+ DO $$
286
+ BEGIN
287
+ -- Only record if migrations table exists
288
+ IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'rem_migrations') THEN
289
+ INSERT INTO rem_migrations (name, type, version)
290
+ VALUES ('003_optional_extensions.sql', 'install', '1.0.0')
291
+ ON CONFLICT (name) DO UPDATE
292
+ SET applied_at = CURRENT_TIMESTAMP,
293
+ applied_by = CURRENT_USER;
294
+ END IF;
295
+ END $$;
296
+
297
+ -- ============================================================================
298
+ -- COMPLETION
299
+ -- ============================================================================
300
+
301
+ DO $$
302
+ DECLARE
303
+ pg_net_installed BOOLEAN;
304
+ BEGIN
305
+ SELECT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_net') INTO pg_net_installed;
306
+
307
+ RAISE NOTICE '============================================================';
308
+ RAISE NOTICE 'Optional Extensions Installation Complete';
309
+ RAISE NOTICE '============================================================';
310
+ RAISE NOTICE '';
311
+ IF pg_net_installed THEN
312
+ RAISE NOTICE 'Installed:';
313
+ RAISE NOTICE ' pg_net (async HTTP/HTTPS requests)';
314
+ RAISE NOTICE ' rem_http_post() - POST JSON to URL';
315
+ RAISE NOTICE ' rem_http_get() - GET from URL';
316
+ RAISE NOTICE ' rem_query() - Execute REM query (async)';
317
+ RAISE NOTICE ' rem_query_result() - Get async query result';
318
+ RAISE NOTICE ' rem_query_sync() - Execute and wait for result';
319
+ ELSE
320
+ RAISE NOTICE 'Skipped (not available in this PostgreSQL image):';
321
+ RAISE NOTICE ' pg_net';
322
+ RAISE NOTICE '';
323
+ RAISE NOTICE 'To enable pg_net, use the custom image: percolationlabs/rem-pg:18';
324
+ END IF;
325
+ RAISE NOTICE '============================================================';
326
+ END $$;