remdb 0.2.6__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 (187) hide show
  1. rem/__init__.py +2 -0
  2. rem/agentic/README.md +650 -0
  3. rem/agentic/__init__.py +39 -0
  4. rem/agentic/agents/README.md +155 -0
  5. rem/agentic/agents/__init__.py +8 -0
  6. rem/agentic/context.py +148 -0
  7. rem/agentic/context_builder.py +329 -0
  8. rem/agentic/mcp/__init__.py +0 -0
  9. rem/agentic/mcp/tool_wrapper.py +107 -0
  10. rem/agentic/otel/__init__.py +5 -0
  11. rem/agentic/otel/setup.py +151 -0
  12. rem/agentic/providers/phoenix.py +674 -0
  13. rem/agentic/providers/pydantic_ai.py +572 -0
  14. rem/agentic/query.py +117 -0
  15. rem/agentic/query_helper.py +89 -0
  16. rem/agentic/schema.py +396 -0
  17. rem/agentic/serialization.py +245 -0
  18. rem/agentic/tools/__init__.py +5 -0
  19. rem/agentic/tools/rem_tools.py +231 -0
  20. rem/api/README.md +420 -0
  21. rem/api/main.py +324 -0
  22. rem/api/mcp_router/prompts.py +182 -0
  23. rem/api/mcp_router/resources.py +536 -0
  24. rem/api/mcp_router/server.py +213 -0
  25. rem/api/mcp_router/tools.py +584 -0
  26. rem/api/routers/auth.py +229 -0
  27. rem/api/routers/chat/__init__.py +5 -0
  28. rem/api/routers/chat/completions.py +281 -0
  29. rem/api/routers/chat/json_utils.py +76 -0
  30. rem/api/routers/chat/models.py +124 -0
  31. rem/api/routers/chat/streaming.py +185 -0
  32. rem/auth/README.md +258 -0
  33. rem/auth/__init__.py +26 -0
  34. rem/auth/middleware.py +100 -0
  35. rem/auth/providers/__init__.py +13 -0
  36. rem/auth/providers/base.py +376 -0
  37. rem/auth/providers/google.py +163 -0
  38. rem/auth/providers/microsoft.py +237 -0
  39. rem/cli/README.md +455 -0
  40. rem/cli/__init__.py +8 -0
  41. rem/cli/commands/README.md +126 -0
  42. rem/cli/commands/__init__.py +3 -0
  43. rem/cli/commands/ask.py +565 -0
  44. rem/cli/commands/configure.py +423 -0
  45. rem/cli/commands/db.py +493 -0
  46. rem/cli/commands/dreaming.py +324 -0
  47. rem/cli/commands/experiments.py +1124 -0
  48. rem/cli/commands/mcp.py +66 -0
  49. rem/cli/commands/process.py +245 -0
  50. rem/cli/commands/schema.py +183 -0
  51. rem/cli/commands/serve.py +106 -0
  52. rem/cli/dreaming.py +363 -0
  53. rem/cli/main.py +88 -0
  54. rem/config.py +237 -0
  55. rem/mcp_server.py +41 -0
  56. rem/models/core/__init__.py +49 -0
  57. rem/models/core/core_model.py +64 -0
  58. rem/models/core/engram.py +333 -0
  59. rem/models/core/experiment.py +628 -0
  60. rem/models/core/inline_edge.py +132 -0
  61. rem/models/core/rem_query.py +243 -0
  62. rem/models/entities/__init__.py +43 -0
  63. rem/models/entities/file.py +57 -0
  64. rem/models/entities/image_resource.py +88 -0
  65. rem/models/entities/message.py +35 -0
  66. rem/models/entities/moment.py +123 -0
  67. rem/models/entities/ontology.py +191 -0
  68. rem/models/entities/ontology_config.py +131 -0
  69. rem/models/entities/resource.py +95 -0
  70. rem/models/entities/schema.py +87 -0
  71. rem/models/entities/user.py +85 -0
  72. rem/py.typed +0 -0
  73. rem/schemas/README.md +507 -0
  74. rem/schemas/__init__.py +6 -0
  75. rem/schemas/agents/README.md +92 -0
  76. rem/schemas/agents/core/moment-builder.yaml +178 -0
  77. rem/schemas/agents/core/rem-query-agent.yaml +226 -0
  78. rem/schemas/agents/core/resource-affinity-assessor.yaml +99 -0
  79. rem/schemas/agents/core/simple-assistant.yaml +19 -0
  80. rem/schemas/agents/core/user-profile-builder.yaml +163 -0
  81. rem/schemas/agents/examples/contract-analyzer.yaml +317 -0
  82. rem/schemas/agents/examples/contract-extractor.yaml +134 -0
  83. rem/schemas/agents/examples/cv-parser.yaml +263 -0
  84. rem/schemas/agents/examples/hello-world.yaml +37 -0
  85. rem/schemas/agents/examples/query.yaml +54 -0
  86. rem/schemas/agents/examples/simple.yaml +21 -0
  87. rem/schemas/agents/examples/test.yaml +29 -0
  88. rem/schemas/agents/rem.yaml +128 -0
  89. rem/schemas/evaluators/hello-world/default.yaml +77 -0
  90. rem/schemas/evaluators/rem/faithfulness.yaml +219 -0
  91. rem/schemas/evaluators/rem/lookup-correctness.yaml +182 -0
  92. rem/schemas/evaluators/rem/retrieval-precision.yaml +199 -0
  93. rem/schemas/evaluators/rem/retrieval-recall.yaml +211 -0
  94. rem/schemas/evaluators/rem/search-correctness.yaml +192 -0
  95. rem/services/__init__.py +16 -0
  96. rem/services/audio/INTEGRATION.md +308 -0
  97. rem/services/audio/README.md +376 -0
  98. rem/services/audio/__init__.py +15 -0
  99. rem/services/audio/chunker.py +354 -0
  100. rem/services/audio/transcriber.py +259 -0
  101. rem/services/content/README.md +1269 -0
  102. rem/services/content/__init__.py +5 -0
  103. rem/services/content/providers.py +806 -0
  104. rem/services/content/service.py +657 -0
  105. rem/services/dreaming/README.md +230 -0
  106. rem/services/dreaming/__init__.py +53 -0
  107. rem/services/dreaming/affinity_service.py +336 -0
  108. rem/services/dreaming/moment_service.py +264 -0
  109. rem/services/dreaming/ontology_service.py +54 -0
  110. rem/services/dreaming/user_model_service.py +297 -0
  111. rem/services/dreaming/utils.py +39 -0
  112. rem/services/embeddings/__init__.py +11 -0
  113. rem/services/embeddings/api.py +120 -0
  114. rem/services/embeddings/worker.py +421 -0
  115. rem/services/fs/README.md +662 -0
  116. rem/services/fs/__init__.py +62 -0
  117. rem/services/fs/examples.py +206 -0
  118. rem/services/fs/examples_paths.py +204 -0
  119. rem/services/fs/git_provider.py +935 -0
  120. rem/services/fs/local_provider.py +760 -0
  121. rem/services/fs/parsing-hooks-examples.md +172 -0
  122. rem/services/fs/paths.py +276 -0
  123. rem/services/fs/provider.py +460 -0
  124. rem/services/fs/s3_provider.py +1042 -0
  125. rem/services/fs/service.py +186 -0
  126. rem/services/git/README.md +1075 -0
  127. rem/services/git/__init__.py +17 -0
  128. rem/services/git/service.py +469 -0
  129. rem/services/phoenix/EXPERIMENT_DESIGN.md +1146 -0
  130. rem/services/phoenix/README.md +453 -0
  131. rem/services/phoenix/__init__.py +46 -0
  132. rem/services/phoenix/client.py +686 -0
  133. rem/services/phoenix/config.py +88 -0
  134. rem/services/phoenix/prompt_labels.py +477 -0
  135. rem/services/postgres/README.md +575 -0
  136. rem/services/postgres/__init__.py +23 -0
  137. rem/services/postgres/migration_service.py +427 -0
  138. rem/services/postgres/pydantic_to_sqlalchemy.py +232 -0
  139. rem/services/postgres/register_type.py +352 -0
  140. rem/services/postgres/repository.py +337 -0
  141. rem/services/postgres/schema_generator.py +379 -0
  142. rem/services/postgres/service.py +802 -0
  143. rem/services/postgres/sql_builder.py +354 -0
  144. rem/services/rem/README.md +304 -0
  145. rem/services/rem/__init__.py +23 -0
  146. rem/services/rem/exceptions.py +71 -0
  147. rem/services/rem/executor.py +293 -0
  148. rem/services/rem/parser.py +145 -0
  149. rem/services/rem/queries.py +196 -0
  150. rem/services/rem/query.py +371 -0
  151. rem/services/rem/service.py +527 -0
  152. rem/services/session/README.md +374 -0
  153. rem/services/session/__init__.py +6 -0
  154. rem/services/session/compression.py +360 -0
  155. rem/services/session/reload.py +77 -0
  156. rem/settings.py +1235 -0
  157. rem/sql/002_install_models.sql +1068 -0
  158. rem/sql/background_indexes.sql +42 -0
  159. rem/sql/install_models.sql +1038 -0
  160. rem/sql/migrations/001_install.sql +503 -0
  161. rem/sql/migrations/002_install_models.sql +1202 -0
  162. rem/utils/AGENTIC_CHUNKING.md +597 -0
  163. rem/utils/README.md +583 -0
  164. rem/utils/__init__.py +43 -0
  165. rem/utils/agentic_chunking.py +622 -0
  166. rem/utils/batch_ops.py +343 -0
  167. rem/utils/chunking.py +108 -0
  168. rem/utils/clip_embeddings.py +276 -0
  169. rem/utils/dict_utils.py +98 -0
  170. rem/utils/embeddings.py +423 -0
  171. rem/utils/examples/embeddings_example.py +305 -0
  172. rem/utils/examples/sql_types_example.py +202 -0
  173. rem/utils/markdown.py +16 -0
  174. rem/utils/model_helpers.py +236 -0
  175. rem/utils/schema_loader.py +229 -0
  176. rem/utils/sql_types.py +348 -0
  177. rem/utils/user_id.py +81 -0
  178. rem/utils/vision.py +330 -0
  179. rem/workers/README.md +506 -0
  180. rem/workers/__init__.py +5 -0
  181. rem/workers/dreaming.py +502 -0
  182. rem/workers/engram_processor.py +312 -0
  183. rem/workers/sqs_file_processor.py +193 -0
  184. remdb-0.2.6.dist-info/METADATA +1191 -0
  185. remdb-0.2.6.dist-info/RECORD +187 -0
  186. remdb-0.2.6.dist-info/WHEEL +4 -0
  187. remdb-0.2.6.dist-info/entry_points.txt +2 -0
rem/api/main.py ADDED
@@ -0,0 +1,324 @@
1
+ """
2
+ REM API Server - FastAPI application with integrated MCP server.
3
+
4
+ Design Pattern:
5
+ 1. Create FastMCP server with create_mcp_server()
6
+ 2. Get HTTP app with mcp.http_app(path="/", transport="http", stateless_http=True)
7
+ 3. Mount on FastAPI at /api/v1/mcp
8
+ 4. Add middleware in specific order (sessions, logging, auth, CORS)
9
+ 5. Register API routers for v1 endpoints
10
+
11
+ Key Architecture Decisions
12
+ - MCP mounted at /api/v1/mcp (not /mcp) for consistency
13
+ - Stateless HTTP prevents stale session errors across pod restarts
14
+ - Auth middleware excludes /api/auth and /api/v1/mcp/auth paths
15
+ - CORS added LAST so it runs FIRST (middleware runs in reverse)
16
+ - Combined lifespan for proper initialization order
17
+
18
+ Middleware Order (runs in reverse):
19
+ 1. CORS (runs first - adds headers to all responses)
20
+ 2. Auth (protects /api/v1/* paths)
21
+ 3. Logging (logs all requests)
22
+ 4. Sessions (OAuth state management)
23
+
24
+ Endpoints:
25
+ - / : API information
26
+ - /health : Health check
27
+ - /api/v1/mcp : MCP endpoint (HTTP transport)
28
+ - /api/v1/chat/completions : OpenAI-compatible chat completions (streaming & non-streaming)
29
+ - /api/v1/query : REM query execution (TODO)
30
+ - /api/v1/resources : Resource CRUD (TODO)
31
+ - /api/v1/moments : Moment CRUD (TODO)
32
+ - /api/auth/* : OAuth/OIDC authentication (TODO)
33
+ - /docs : OpenAPI documentation
34
+
35
+ Headers → AgentContext Mapping:
36
+ The following HTTP headers are automatically mapped to AgentContext fields:
37
+ - X-User-Id → context.user_id (user identifier)
38
+ - X-Tenant-Id → context.tenant_id (tenant identifier, required for REM)
39
+ - X-Session-Id → context.session_id (session/conversation identifier)
40
+ - X-Agent-Schema → context.agent_schema_uri (agent schema to use)
41
+
42
+ Example:
43
+ POST /api/v1/chat/completions
44
+ X-Tenant-Id: acme-corp
45
+ X-User-Id: user123
46
+ X-Agent-Schema: rem-agents-query-agent
47
+
48
+ {
49
+ "model": "anthropic:claude-sonnet-4-5-20250929",
50
+ "messages": [{"role": "user", "content": "Find Sarah's documents"}],
51
+ "stream": true
52
+ }
53
+
54
+ Running:
55
+ # Development (auto-reload)
56
+ uv run python -m rem.api.main
57
+
58
+ # Production (Docker with hypercorn)
59
+ hypercorn rem.api.main:app --bind 0.0.0.0:8000
60
+ """
61
+
62
+ import secrets
63
+ import time
64
+ from contextlib import asynccontextmanager
65
+
66
+ from fastapi import FastAPI, Request
67
+ from fastapi.middleware.cors import CORSMiddleware
68
+ from fastapi.responses import JSONResponse
69
+ from loguru import logger
70
+ from starlette.middleware.base import BaseHTTPMiddleware
71
+ from starlette.middleware.sessions import SessionMiddleware
72
+
73
+ from .mcp_router.server import create_mcp_server
74
+ from ..settings import settings
75
+
76
+
77
+ class RequestLoggingMiddleware(BaseHTTPMiddleware):
78
+ """
79
+ Log all incoming HTTP requests and responses.
80
+
81
+ Design Pattern:
82
+ - Logs request method, path, client, user-agent
83
+ - Logs response status, content-type, duration
84
+ - Essential for debugging OAuth flow and MCP sessions
85
+ """
86
+
87
+ async def dispatch(self, request: Request, call_next):
88
+ start_time = time.time()
89
+
90
+ # Log incoming request
91
+ client_host = request.client.host if request.client else "unknown"
92
+ logger.info(
93
+ f"→ REQUEST: {request.method} {request.url.path} | "
94
+ f"Client: {client_host} | "
95
+ f"User-Agent: {request.headers.get('user-agent', 'unknown')[:100]}"
96
+ )
97
+
98
+ # Process request
99
+ response = await call_next(request)
100
+
101
+ # Log response
102
+ duration_ms = (time.time() - start_time) * 1000
103
+ logger.info(
104
+ f"← RESPONSE: {request.method} {request.url.path} | "
105
+ f"Status: {response.status_code} | "
106
+ f"Duration: {duration_ms:.2f}ms"
107
+ )
108
+
109
+ return response
110
+
111
+
112
+ class SSEBufferingMiddleware(BaseHTTPMiddleware):
113
+ """
114
+ Disable proxy buffering for SSE responses.
115
+
116
+ Adds X-Accel-Buffering: no header to prevent Nginx/Traefik
117
+ from buffering Server-Sent Events (critical for MCP SSE transport).
118
+ """
119
+
120
+ async def dispatch(self, request: Request, call_next):
121
+ response = await call_next(request)
122
+
123
+ # Disable buffering for SSE responses
124
+ content_type = response.headers.get("content-type", "")
125
+ if "text/event-stream" in content_type:
126
+ response.headers["X-Accel-Buffering"] = "no"
127
+ response.headers["Cache-Control"] = "no-cache"
128
+
129
+ return response
130
+
131
+
132
+ @asynccontextmanager
133
+ async def lifespan(app: FastAPI):
134
+ """
135
+ Application lifespan manager.
136
+
137
+ Handles startup and shutdown tasks.
138
+ OTEL instrumentation must be initialized at startup before any agents are created.
139
+ """
140
+ logger.info(f"Starting REM API ({settings.environment})")
141
+
142
+ # Initialize OTEL instrumentation if enabled
143
+ # Must be done at startup to instrument Pydantic AI before any agents are created
144
+ if settings.otel.enabled:
145
+ from ..agentic.otel.setup import setup_instrumentation
146
+
147
+ setup_instrumentation()
148
+
149
+ # Check database configuration
150
+ if not settings.postgres.enabled:
151
+ logger.warning(
152
+ "Running in NO-DATABASE mode - database connection disabled. "
153
+ "Agent execution works with file-based schemas, but session storage "
154
+ "and history lookups are unavailable. Enable database with POSTGRES__ENABLED=true"
155
+ )
156
+ else:
157
+ logger.info(f"Database enabled: {settings.postgres.connection_string}")
158
+
159
+ yield
160
+
161
+ logger.info("Shutting down REM API")
162
+
163
+
164
+ def create_app() -> FastAPI:
165
+ """
166
+ Create and configure the FastAPI application.
167
+
168
+ Design Pattern:
169
+ 1. Create MCP server
170
+ 2. Get HTTP app with stateless_http=True
171
+ 3. Combine lifespans (app + MCP)
172
+ 4. Create FastAPI with combined lifespan
173
+ 5. Add middleware (sessions, logging, auth, CORS) in specific order
174
+ 6. Define health endpoints
175
+ 7. Register API routers
176
+ 8. Mount MCP app
177
+
178
+ Returns:
179
+ Configured FastAPI application
180
+ """
181
+ # Create MCP server and get HTTP app
182
+ # path="/" creates routes at root, then mount at /api/v1/mcp
183
+ # transport="http" for MCP HTTP protocol
184
+ # stateless_http=True prevents stale session errors (pods can restart)
185
+ mcp_server = create_mcp_server()
186
+ mcp_app = mcp_server.http_app(path="/", transport="http", stateless_http=True)
187
+
188
+ # Disable trailing slash redirects (prevents 307 redirects that strip auth headers)
189
+ if hasattr(mcp_app, "router"):
190
+ mcp_app.router.redirect_slashes = False
191
+
192
+ # Combine MCP and API lifespans
193
+ # Explicit nesting ensures proper initialization order
194
+ @asynccontextmanager
195
+ async def combined_lifespan(app: FastAPI):
196
+ async with lifespan(app):
197
+ async with mcp_app.lifespan(app):
198
+ yield
199
+
200
+ app = FastAPI(
201
+ title="REM API",
202
+ description="Resources Entities Moments system for agentic AI",
203
+ version="0.1.0",
204
+ lifespan=combined_lifespan,
205
+ root_path=settings.root_path if settings.root_path else "",
206
+ redirect_slashes=False, # Don't redirect /mcp/ -> /mcp
207
+ )
208
+
209
+ # Add session middleware for OAuth state management
210
+ session_secret = settings.auth.session_secret or secrets.token_hex(32)
211
+ if not settings.auth.session_secret:
212
+ logger.warning(
213
+ "AUTH__SESSION_SECRET not set - using generated key "
214
+ "(sessions won't persist across restarts)"
215
+ )
216
+
217
+ app.add_middleware(
218
+ SessionMiddleware,
219
+ secret_key=session_secret,
220
+ session_cookie="rem_session",
221
+ max_age=3600, # 1 hour
222
+ same_site="lax",
223
+ https_only=settings.environment == "production",
224
+ )
225
+
226
+ # Add request logging middleware
227
+ app.add_middleware(RequestLoggingMiddleware)
228
+
229
+ # Add SSE buffering middleware (for MCP SSE transport)
230
+ app.add_middleware(SSEBufferingMiddleware)
231
+
232
+ # Add authentication middleware (if enabled)
233
+ if settings.auth.enabled:
234
+ from ..auth.middleware import AuthMiddleware
235
+
236
+ app.add_middleware(
237
+ AuthMiddleware,
238
+ protected_paths=["/api/v1"],
239
+ excluded_paths=["/api/auth", "/api/v1/mcp/auth"],
240
+ )
241
+
242
+ # Add CORS middleware LAST (runs first in middleware chain)
243
+ # Must expose mcp-session-id header for MCP session management
244
+ CORS_ORIGIN_WHITELIST = [
245
+ "http://localhost:5173", # Local development (Vite)
246
+ "http://localhost:3000", # Local development (React)
247
+ ]
248
+
249
+ app.add_middleware(
250
+ CORSMiddleware,
251
+ allow_origins=CORS_ORIGIN_WHITELIST,
252
+ allow_credentials=True,
253
+ allow_methods=["*"],
254
+ allow_headers=["*", "mcp-protocol-version", "mcp-session-id", "authorization"],
255
+ expose_headers=["mcp-session-id"],
256
+ )
257
+
258
+ # Root endpoint
259
+ @app.get("/")
260
+ async def root():
261
+ """API information endpoint."""
262
+ # TODO: If auth enabled and no user, return 401 with WWW-Authenticate
263
+ return {
264
+ "name": "REM API",
265
+ "version": "0.1.0",
266
+ "mcp_endpoint": "/api/v1/mcp",
267
+ "docs": "/docs",
268
+ }
269
+
270
+ # Health check endpoint
271
+ @app.get("/health")
272
+ async def health():
273
+ """Health check endpoint."""
274
+ return {"status": "healthy", "version": "0.1.0"}
275
+
276
+ # Register API routers
277
+ from .routers.chat import router as chat_router
278
+
279
+ app.include_router(chat_router)
280
+
281
+ # Register auth router (if enabled)
282
+ if settings.auth.enabled:
283
+ from .routers.auth import router as auth_router
284
+
285
+ app.include_router(auth_router)
286
+
287
+ # TODO: Register additional routers
288
+ # from .routers.query import router as query_router
289
+ # from .routers.resources import router as resources_router
290
+ # from .routers.moments import router as moments_router
291
+ #
292
+ # app.include_router(query_router)
293
+ # app.include_router(resources_router)
294
+ # app.include_router(moments_router)
295
+
296
+ # Add middleware to rewrite /api/v1/mcp to /api/v1/mcp/
297
+ @app.middleware("http")
298
+ async def mcp_path_rewrite_middleware(request: Request, call_next):
299
+ """Rewrite /api/v1/mcp to /api/v1/mcp/ to handle Claude Desktop requests."""
300
+ if request.url.path == "/api/v1/mcp":
301
+ request.scope["path"] = "/api/v1/mcp/"
302
+ request.scope["raw_path"] = b"/api/v1/mcp/"
303
+ return await call_next(request)
304
+
305
+ # Mount MCP app at /api/v1/mcp
306
+ app.mount("/api/v1/mcp", mcp_app)
307
+
308
+ return app
309
+
310
+
311
+ # Create application instance
312
+ app = create_app()
313
+
314
+
315
+ # Main entry point for uvicorn
316
+ if __name__ == "__main__":
317
+ import uvicorn
318
+
319
+ uvicorn.run(
320
+ "rem.api.main:app",
321
+ host="0.0.0.0",
322
+ port=8000,
323
+ reload=True,
324
+ )
@@ -0,0 +1,182 @@
1
+ """
2
+ MCP Prompts for REM operations.
3
+
4
+ Prompts are interactive templates that help users perform complex tasks.
5
+ """
6
+
7
+ from fastmcp import FastMCP
8
+
9
+
10
+ CREATEAGENT_PROMPT = """
11
+ Create a custom REM agent schema.
12
+
13
+ I'll help you create an agent schema that can be uploaded to REM and automatically processed.
14
+
15
+ ## What I need from you:
16
+
17
+ 1. **Agent purpose**: What should this agent do? What domain knowledge does it need?
18
+ 2. **Short name**: Lowercase with hyphens (e.g., "cv-parser", "contract-analyzer")
19
+ 3. **Version**: Semantic version (e.g., "1.0.0")
20
+ 4. **Structured output fields**: What data should the agent extract?
21
+
22
+ ## Agent Schema Format
23
+
24
+ REM agents use JSON Schema format with these sections:
25
+
26
+ ```yaml
27
+ ---
28
+ type: object
29
+ description: |
30
+ System prompt with LLM instructions.
31
+
32
+ Provide clear, detailed guidance on what the agent should do.
33
+
34
+ properties:
35
+ field_name:
36
+ type: string
37
+ description: Field description
38
+
39
+ required:
40
+ - required_field
41
+
42
+ json_schema_extra:
43
+ kind: agent
44
+ name: your-agent
45
+ version: "1.0.0"
46
+ tags: [domain, category]
47
+
48
+ # Optional: Fields to embed for semantic search
49
+ embedding_fields:
50
+ - field1
51
+ - field2
52
+ ```
53
+
54
+ ## Example: CV Parser
55
+
56
+ ```yaml
57
+ ---
58
+ type: object
59
+ description: |
60
+ Parse CV/resume documents to extract candidate information.
61
+
62
+ Extract:
63
+ - Candidate details (name, contact, summary)
64
+ - Work experience with dates
65
+ - Education history
66
+ - Skills and competencies
67
+ - Seniority level assessment
68
+
69
+ properties:
70
+ candidate_name:
71
+ type: string
72
+ description: Full name of the candidate
73
+
74
+ skills:
75
+ type: array
76
+ items:
77
+ type: string
78
+ description: Technical and professional skills
79
+
80
+ experience:
81
+ type: array
82
+ items:
83
+ type: object
84
+ properties:
85
+ company: {type: string}
86
+ title: {type: string}
87
+ start_date: {type: string}
88
+ end_date: {type: string}
89
+ description: Work experience history
90
+
91
+ seniority_level:
92
+ type: string
93
+ enum: ["junior", "mid-level", "senior", "lead", "executive"]
94
+ description: Assessed seniority level
95
+
96
+ required:
97
+ - candidate_name
98
+ - skills
99
+
100
+ json_schema_extra:
101
+ kind: agent
102
+ name: cv-parser
103
+ version: "1.0.0"
104
+
105
+ tags: [recruitment, ontology-extractor]
106
+
107
+ embedding_fields:
108
+ - candidate_name
109
+ - skills
110
+
111
+ category: ontology-extractor
112
+ ```
113
+
114
+ ## Upload Process
115
+
116
+ After creating your schema:
117
+
118
+ 1. **Save to local file system**: `~/.rem/fs/my-agent.yaml` or request an upload path for remote servers.
119
+
120
+ 2. **Upload via ingest_file**:
121
+ ```python
122
+ ingest_file(
123
+ file_uri="LOCAL PATH for local servers or remote S3 path for remote servers",
124
+ category="agent"
125
+ )
126
+ ```
127
+
128
+ 3. **Automatic processing**:
129
+ - File detected by worker
130
+ - Schema validated and stored in schemas table
131
+ - Available for immediate use
132
+
133
+ ## Ready?
134
+
135
+ Tell me:
136
+ 1. What should your agent do?
137
+ 2. What data should it extract?
138
+ 3. What should we name it?
139
+
140
+ I'll generate the complete schema for you!
141
+ """
142
+
143
+
144
+ def register_prompts(mcp: FastMCP):
145
+ """
146
+ Register MCP prompts.
147
+
148
+ Args:
149
+ mcp: FastMCP server instance
150
+ """
151
+
152
+ @mcp.prompt()
153
+ def create_agent(
154
+ purpose: str = "",
155
+ short_name: str = "",
156
+ version: str = "1.0.0",
157
+ ) -> str:
158
+ """
159
+ Interactive prompt for creating custom REM agent schemas.
160
+
161
+ Guides users through creating agent schemas with domain knowledge,
162
+ structured output definitions, and upload instructions.
163
+
164
+ Args:
165
+ purpose: Agent purpose and domain (optional, will prompt if empty)
166
+ short_name: Agent short name in kebab-case (optional, will suggest)
167
+ version: Semantic version (default: "1.0.0")
168
+
169
+ Returns:
170
+ Interactive prompt with examples and upload instructions
171
+ """
172
+ prompt = CREATEAGENT_PROMPT
173
+
174
+ # Add context if parameters provided
175
+ if purpose:
176
+ prompt += f"\n\nYou mentioned: \"{purpose}\"\n"
177
+ if short_name:
178
+ prompt += f"Short name: {short_name}\n"
179
+ if version != "1.0.0":
180
+ prompt += f"Version: {version}\n"
181
+
182
+ return prompt