omni-cortex 1.7.1__tar.gz → 1.9.0__tar.gz

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.
Files changed (68) hide show
  1. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/.gitignore +2 -1
  2. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/PKG-INFO +33 -6
  3. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/README.md +31 -5
  4. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/database.py +3 -2
  5. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/main.py +61 -0
  6. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/models.py +10 -0
  7. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/__init__.py +1 -1
  8. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/pyproject.toml +2 -1
  9. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/LICENSE +0 -0
  10. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/.env.example +0 -0
  11. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/backfill_summaries.py +0 -0
  12. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/chat_service.py +0 -0
  13. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/image_service.py +0 -0
  14. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/logging_config.py +0 -0
  15. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/project_config.py +0 -0
  16. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/project_scanner.py +0 -0
  17. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/prompt_security.py +0 -0
  18. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/pyproject.toml +0 -0
  19. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/security.py +0 -0
  20. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/uv.lock +0 -0
  21. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/dashboard/backend/websocket_manager.py +0 -0
  22. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/hooks/post_tool_use.py +0 -0
  23. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/hooks/pre_tool_use.py +0 -0
  24. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/hooks/session_utils.py +0 -0
  25. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/hooks/stop.py +0 -0
  26. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/hooks/subagent_stop.py +0 -0
  27. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/categorization/__init__.py +0 -0
  28. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/categorization/auto_tags.py +0 -0
  29. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/categorization/auto_type.py +0 -0
  30. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/config.py +0 -0
  31. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/dashboard.py +0 -0
  32. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/database/__init__.py +0 -0
  33. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/database/connection.py +0 -0
  34. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/database/migrations.py +0 -0
  35. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/database/schema.py +0 -0
  36. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/database/sync.py +0 -0
  37. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/decay/__init__.py +0 -0
  38. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/decay/importance.py +0 -0
  39. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/embeddings/__init__.py +0 -0
  40. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/embeddings/local.py +0 -0
  41. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/models/__init__.py +0 -0
  42. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/models/activity.py +0 -0
  43. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/models/agent.py +0 -0
  44. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/models/memory.py +0 -0
  45. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/models/relationship.py +0 -0
  46. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/models/session.py +0 -0
  47. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/resources/__init__.py +0 -0
  48. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/search/__init__.py +0 -0
  49. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/search/hybrid.py +0 -0
  50. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/search/keyword.py +0 -0
  51. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/search/ranking.py +0 -0
  52. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/search/semantic.py +0 -0
  53. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/server.py +0 -0
  54. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/setup.py +0 -0
  55. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/tools/__init__.py +0 -0
  56. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/tools/activities.py +0 -0
  57. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/tools/memories.py +0 -0
  58. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/tools/sessions.py +0 -0
  59. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/tools/utilities.py +0 -0
  60. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/utils/__init__.py +0 -0
  61. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/utils/formatting.py +0 -0
  62. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/utils/ids.py +0 -0
  63. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/utils/timestamps.py +0 -0
  64. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/omni_cortex/utils/truncation.py +0 -0
  65. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/scripts/check-venv.py +0 -0
  66. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/scripts/import_ken_memories.py +0 -0
  67. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/scripts/populate_session_data.py +0 -0
  68. {omni_cortex-1.7.1 → omni_cortex-1.9.0}/scripts/setup.py +0 -0
@@ -157,6 +157,7 @@ memories.json
157
157
  .mcp.json
158
158
 
159
159
  # Personal/local files
160
- adws/
160
+ # adws/ - removed, now tracking ADW orchestrators
161
161
  specs/omni-cortex-adw-system.md
162
162
  nul
163
+ *.bak
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omni-cortex
3
- Version: 1.7.1
3
+ Version: 1.9.0
4
4
  Summary: Give Claude Code a perfect memory - auto-logs everything, searches smartly, and gets smarter over time
5
5
  Project-URL: Homepage, https://github.com/AllCytes/Omni-Cortex
6
6
  Project-URL: Repository, https://github.com/AllCytes/Omni-Cortex
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.13
21
21
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Requires-Python: >=3.10
24
+ Requires-Dist: claude-agent-sdk>=0.1.0
24
25
  Requires-Dist: httpx>=0.25.0
25
26
  Requires-Dist: mcp>=1.0.0
26
27
  Requires-Dist: pydantic>=2.0.0
@@ -154,10 +155,9 @@ omni-cortex-dashboard
154
155
 
155
156
  Or manually:
156
157
  ```bash
157
- # Terminal 1: Backend
158
+ # Terminal 1: Backend (uses dashboard's own venv)
158
159
  cd dashboard/backend
159
- pip install -e .
160
- uvicorn main:app --host 0.0.0.0 --port 8765 --reload
160
+ .venv/Scripts/python -m uvicorn main:app --host 127.0.0.1 --port 8765 --reload
161
161
 
162
162
  # Terminal 2: Frontend
163
163
  cd dashboard/frontend
@@ -167,6 +167,8 @@ npm run dev
167
167
 
168
168
  Open http://localhost:5173 in your browser.
169
169
 
170
+ **Note:** The dashboard has its own virtual environment at `dashboard/backend/.venv` with FastAPI and other web dependencies. This is separate from the project root `.venv` which contains the MCP server package.
171
+
170
172
  ### Troubleshooting
171
173
 
172
174
  <details>
@@ -485,8 +487,12 @@ git clone https://github.com/AllCytes/Omni-Cortex.git
485
487
  cd Omni-Cortex
486
488
  pip install -e .
487
489
 
488
- # Install dashboard dependencies
489
- cd dashboard/backend && pip install -r requirements.txt
490
+ # Dashboard backend has its own venv (already included in repo)
491
+ # If missing, set it up:
492
+ cd dashboard/backend
493
+ python -m venv .venv
494
+ .venv/Scripts/pip install -r requirements.txt # Windows
495
+ # .venv/bin/pip install -r requirements.txt # macOS/Linux
490
496
  cd ../frontend && npm install
491
497
  cd ../..
492
498
 
@@ -497,6 +503,27 @@ omni-cortex-dashboard --help
497
503
 
498
504
  **Important**: Always use `pip install -e .` (editable mode) so changes are immediately reflected without reinstalling.
499
505
 
506
+ ### Project Structure
507
+
508
+ ```
509
+ omni-cortex/
510
+ ├── .venv/ # Project root venv (omni-cortex MCP package)
511
+ ├── src/omni_cortex/ # MCP server source code
512
+ ├── dashboard/
513
+ │ ├── backend/
514
+ │ │ ├── .venv/ # Dashboard backend venv (FastAPI, uvicorn)
515
+ │ │ ├── main.py # FastAPI application
516
+ │ │ └── database.py # Database queries
517
+ │ └── frontend/ # Vue 3 + Vite frontend
518
+ ├── adws/ # Agentic Development Workflows
519
+ ├── specs/ # Implementation plans
520
+ │ ├── todo/ # Plans waiting to be built
521
+ │ └── done/ # Completed plans
522
+ └── tests/ # Unit tests
523
+ ```
524
+
525
+ **Why two venvs?** The dashboard is a standalone web application that can be packaged/deployed separately from the MCP server. They have different dependencies (MCP server needs `mcp`, dashboard needs `fastapi`).
526
+
500
527
  ### Running Tests
501
528
 
502
529
  ```bash
@@ -116,10 +116,9 @@ omni-cortex-dashboard
116
116
 
117
117
  Or manually:
118
118
  ```bash
119
- # Terminal 1: Backend
119
+ # Terminal 1: Backend (uses dashboard's own venv)
120
120
  cd dashboard/backend
121
- pip install -e .
122
- uvicorn main:app --host 0.0.0.0 --port 8765 --reload
121
+ .venv/Scripts/python -m uvicorn main:app --host 127.0.0.1 --port 8765 --reload
123
122
 
124
123
  # Terminal 2: Frontend
125
124
  cd dashboard/frontend
@@ -129,6 +128,8 @@ npm run dev
129
128
 
130
129
  Open http://localhost:5173 in your browser.
131
130
 
131
+ **Note:** The dashboard has its own virtual environment at `dashboard/backend/.venv` with FastAPI and other web dependencies. This is separate from the project root `.venv` which contains the MCP server package.
132
+
132
133
  ### Troubleshooting
133
134
 
134
135
  <details>
@@ -447,8 +448,12 @@ git clone https://github.com/AllCytes/Omni-Cortex.git
447
448
  cd Omni-Cortex
448
449
  pip install -e .
449
450
 
450
- # Install dashboard dependencies
451
- cd dashboard/backend && pip install -r requirements.txt
451
+ # Dashboard backend has its own venv (already included in repo)
452
+ # If missing, set it up:
453
+ cd dashboard/backend
454
+ python -m venv .venv
455
+ .venv/Scripts/pip install -r requirements.txt # Windows
456
+ # .venv/bin/pip install -r requirements.txt # macOS/Linux
452
457
  cd ../frontend && npm install
453
458
  cd ../..
454
459
 
@@ -459,6 +464,27 @@ omni-cortex-dashboard --help
459
464
 
460
465
  **Important**: Always use `pip install -e .` (editable mode) so changes are immediately reflected without reinstalling.
461
466
 
467
+ ### Project Structure
468
+
469
+ ```
470
+ omni-cortex/
471
+ ├── .venv/ # Project root venv (omni-cortex MCP package)
472
+ ├── src/omni_cortex/ # MCP server source code
473
+ ├── dashboard/
474
+ │ ├── backend/
475
+ │ │ ├── .venv/ # Dashboard backend venv (FastAPI, uvicorn)
476
+ │ │ ├── main.py # FastAPI application
477
+ │ │ └── database.py # Database queries
478
+ │ └── frontend/ # Vue 3 + Vite frontend
479
+ ├── adws/ # Agentic Development Workflows
480
+ ├── specs/ # Implementation plans
481
+ │ ├── todo/ # Plans waiting to be built
482
+ │ └── done/ # Completed plans
483
+ └── tests/ # Unit tests
484
+ ```
485
+
486
+ **Why two venvs?** The dashboard is a standalone web application that can be packaged/deployed separately from the MCP server. They have different dependencies (MCP server needs `mcp`, dashboard needs `fastapi`).
487
+
462
488
  ### Running Tests
463
489
 
464
490
  ```bash
@@ -1049,8 +1049,8 @@ def create_memory(
1049
1049
  # Insert memory
1050
1050
  conn.execute(
1051
1051
  """
1052
- INSERT INTO memories (id, content, context, type, status, importance_score, access_count, created_at, last_accessed, tags)
1053
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1052
+ INSERT INTO memories (id, content, context, type, status, importance_score, access_count, created_at, last_accessed, updated_at, tags)
1053
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1054
1054
  """,
1055
1055
  (
1056
1056
  memory_id,
@@ -1062,6 +1062,7 @@ def create_memory(
1062
1062
  0,
1063
1063
  now,
1064
1064
  now,
1065
+ now,
1065
1066
  json.dumps(tags) if tags else None,
1066
1067
  ),
1067
1068
  )
@@ -31,6 +31,7 @@ except ImportError:
31
31
 
32
32
  from database import (
33
33
  bulk_update_memory_status,
34
+ create_memory,
34
35
  delete_memory,
35
36
  ensure_migrations,
36
37
  get_activities,
@@ -62,6 +63,7 @@ from models import (
62
63
  ConversationSaveRequest,
63
64
  ConversationSaveResponse,
64
65
  FilterParams,
66
+ MemoryCreateRequest,
65
67
  MemoryUpdate,
66
68
  ProjectInfo,
67
69
  ProjectRegistration,
@@ -230,6 +232,20 @@ if RATE_LIMITING_AVAILABLE:
230
232
  else:
231
233
  limiter = None
232
234
 
235
+
236
+ def rate_limit(limit_string: str):
237
+ """Decorator for conditional rate limiting.
238
+
239
+ Returns the actual limiter decorator if available, otherwise a no-op.
240
+ Usage: @rate_limit("10/minute")
241
+ """
242
+ if limiter is not None:
243
+ return limiter.limit(limit_string)
244
+ # No-op decorator when rate limiting is not available
245
+ def noop_decorator(func):
246
+ return func
247
+ return noop_decorator
248
+
233
249
  # CORS configuration (environment-aware)
234
250
  cors_config = get_cors_config()
235
251
  app.add_middleware(
@@ -333,6 +349,7 @@ async def refresh_projects():
333
349
 
334
350
 
335
351
  @app.get("/api/memories")
352
+ @rate_limit("100/minute")
336
353
  async def list_memories(
337
354
  project: str = Query(..., description="Path to the database file"),
338
355
  memory_type: Optional[str] = Query(None, alias="type"),
@@ -373,6 +390,46 @@ async def list_memories(
373
390
  raise
374
391
 
375
392
 
393
+ @app.post("/api/memories")
394
+ @rate_limit("30/minute")
395
+ async def create_memory_endpoint(
396
+ request: MemoryCreateRequest,
397
+ project: str = Query(..., description="Path to the database file"),
398
+ ):
399
+ """Create a new memory."""
400
+ try:
401
+ if not Path(project).exists():
402
+ log_error("/api/memories POST", FileNotFoundError("Database not found"), project=project)
403
+ raise HTTPException(status_code=404, detail="Database not found")
404
+
405
+ # Create the memory
406
+ memory_id = create_memory(
407
+ db_path=project,
408
+ content=request.content,
409
+ memory_type=request.memory_type,
410
+ context=request.context,
411
+ tags=request.tags if request.tags else None,
412
+ importance_score=request.importance_score,
413
+ )
414
+
415
+ # Fetch the created memory to return it
416
+ created_memory = get_memory_by_id(project, memory_id)
417
+
418
+ # Broadcast to WebSocket clients
419
+ await manager.broadcast("memory_created", created_memory.model_dump(by_alias=True))
420
+
421
+ log_success("/api/memories POST", memory_id=memory_id, type=request.memory_type)
422
+ return created_memory
423
+ except HTTPException:
424
+ raise
425
+ except Exception as e:
426
+ import traceback
427
+ print(f"[DEBUG] create_memory_endpoint error: {type(e).__name__}: {e}")
428
+ traceback.print_exc()
429
+ log_error("/api/memories POST", e, project=project)
430
+ raise
431
+
432
+
376
433
  # NOTE: These routes MUST be defined before /api/memories/{memory_id} to avoid path conflicts
377
434
  @app.get("/api/memories/needs-review")
378
435
  async def get_memories_needing_review_endpoint(
@@ -744,6 +801,7 @@ async def chat_status():
744
801
 
745
802
 
746
803
  @app.post("/api/chat", response_model=ChatResponse)
804
+ @rate_limit("10/minute")
747
805
  async def chat_with_memories(
748
806
  request: ChatRequest,
749
807
  project: str = Query(..., description="Path to the database file"),
@@ -770,6 +828,7 @@ async def chat_with_memories(
770
828
 
771
829
 
772
830
  @app.get("/api/chat/stream")
831
+ @rate_limit("10/minute")
773
832
  async def stream_chat(
774
833
  project: str = Query(..., description="Path to the database file"),
775
834
  question: str = Query(..., description="The question to ask"),
@@ -846,6 +905,7 @@ async def get_image_presets():
846
905
 
847
906
 
848
907
  @app.post("/api/image/generate-batch", response_model=BatchImageGenerationResponse)
908
+ @rate_limit("5/minute")
849
909
  async def generate_images_batch(
850
910
  request: BatchImageGenerationRequest,
851
911
  db_path: str = Query(..., alias="project", description="Path to the database file"),
@@ -903,6 +963,7 @@ async def generate_images_batch(
903
963
 
904
964
 
905
965
  @app.post("/api/image/refine", response_model=SingleImageResponseModel)
966
+ @rate_limit("5/minute")
906
967
  async def refine_image(request: ImageRefineRequest):
907
968
  """Refine an existing generated image with a new prompt."""
908
969
  result = await image_service.refine_image(
@@ -128,6 +128,16 @@ class FilterParams(BaseModel):
128
128
  offset: int = 0
129
129
 
130
130
 
131
+ class MemoryCreateRequest(BaseModel):
132
+ """Create request for a new memory."""
133
+
134
+ content: str = Field(..., min_length=1, max_length=50000)
135
+ memory_type: str = Field(default="general")
136
+ context: Optional[str] = None
137
+ importance_score: int = Field(default=50, ge=1, le=100)
138
+ tags: list[str] = Field(default_factory=list)
139
+
140
+
131
141
  class MemoryUpdate(BaseModel):
132
142
  """Update request for a memory."""
133
143
 
@@ -1,3 +1,3 @@
1
1
  """Omni Cortex MCP - Universal Memory System for Claude Code."""
2
2
 
3
- __version__ = "1.7.1"
3
+ __version__ = "1.9.0"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "omni-cortex"
7
- version = "1.7.1"
7
+ version = "1.9.0"
8
8
  description = "Give Claude Code a perfect memory - auto-logs everything, searches smartly, and gets smarter over time"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -32,6 +32,7 @@ dependencies = [
32
32
  "httpx>=0.25.0",
33
33
  "pyyaml>=6.0.0",
34
34
  "python-dotenv>=1.0.0",
35
+ "claude-agent-sdk>=0.1.0",
35
36
  ]
36
37
 
37
38
  [project.urls]
File without changes
File without changes