cli-memory-os 0.1.7__tar.gz → 0.1.8__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 (69) hide show
  1. {cli_memory_os-0.1.7/cli_memory_os.egg-info → cli_memory_os-0.1.8}/PKG-INFO +1 -1
  2. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8/cli_memory_os.egg-info}/PKG-INFO +1 -1
  3. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/core/context_builder.py +2 -1
  4. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/core/llm.py +35 -0
  5. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/pyproject.toml +1 -1
  6. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/tests/test_sync_ask_cli.py +30 -0
  7. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/LICENSE +0 -0
  8. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/MANIFEST.in +0 -0
  9. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/README.md +0 -0
  10. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/__init__.py +0 -0
  11. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/__init__.py +0 -0
  12. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/ask.py +0 -0
  13. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/benchmark.py +0 -0
  14. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/config_cmd.py +0 -0
  15. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/doctor.py +0 -0
  16. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/export.py +0 -0
  17. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/import_cmd.py +0 -0
  18. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/init.py +0 -0
  19. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/logs.py +0 -0
  20. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/monitor.py +0 -0
  21. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/plugins.py +0 -0
  22. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/restart.py +0 -0
  23. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/start.py +0 -0
  24. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/status.py +0 -0
  25. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/stop.py +0 -0
  26. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/sync.py +0 -0
  27. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/version.py +0 -0
  28. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/commands/workspace.py +0 -0
  29. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/main.py +0 -0
  30. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/parser.py +0 -0
  31. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/tui/__init__.py +0 -0
  32. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli/tui/app.py +0 -0
  33. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli_memory_os.egg-info/SOURCES.txt +0 -0
  34. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli_memory_os.egg-info/dependency_links.txt +0 -0
  35. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli_memory_os.egg-info/entry_points.txt +0 -0
  36. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli_memory_os.egg-info/requires.txt +0 -0
  37. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/cli_memory_os.egg-info/top_level.txt +0 -0
  38. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/connectors/__init__.py +0 -0
  39. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/connectors/base.py +0 -0
  40. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/connectors/github.py +0 -0
  41. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/connectors/gmail.py +0 -0
  42. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/connectors/notion.py +0 -0
  43. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/connectors/registry.py +0 -0
  44. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/core/__init__.py +0 -0
  45. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/core/chunker.py +0 -0
  46. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/core/embedder.py +0 -0
  47. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/core/vector_store.py +0 -0
  48. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/infrastructure/__init__.py +0 -0
  49. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/infrastructure/compose.py +0 -0
  50. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/infrastructure/config.py +0 -0
  51. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/infrastructure/docker.py +0 -0
  52. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/infrastructure/health.py +0 -0
  53. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/infrastructure/observability.py +0 -0
  54. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/infrastructure/workspace.py +0 -0
  55. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/models/__init__.py +0 -0
  56. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/models/memory.py +0 -0
  57. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/setup.cfg +0 -0
  58. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/storage/__init__.py +0 -0
  59. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/storage/db.py +0 -0
  60. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/storage/graph.py +0 -0
  61. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/storage/schema.sql +0 -0
  62. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/storage/tech_detector.py +0 -0
  63. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/tests/test_cli_integration.py +0 -0
  64. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/tests/test_commands_phase2.py +0 -0
  65. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/tests/test_compose_manager.py +0 -0
  66. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/tests/test_first_time_user_experience.py +0 -0
  67. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/tests/test_infrastructure_stabilization.py +0 -0
  68. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/tests/test_tui.py +0 -0
  69. {cli_memory_os-0.1.7 → cli_memory_os-0.1.8}/tests/test_v1_features.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-memory-os
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: CLI-based Personal Knowledge Operating System
5
5
  Author-email: Anirudh T <anirudh200584@gmail.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-memory-os
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: CLI-based Personal Knowledge Operating System
5
5
  Author-email: Anirudh T <anirudh200584@gmail.com>
6
6
  License-Expression: MIT
@@ -50,7 +50,8 @@ class ContextBuilder:
50
50
  return "Documentation Question"
51
51
 
52
52
  # 5. Cross Repository Question
53
- if "cross repository" in query_lower or "multiple repositories" in query_lower or "across all projects" in query_lower:
53
+ cross_keywords = ["projects", "repositories", "repos", "cross repository", "multiple repositories", "across all", "all my"]
54
+ if any(k in query_lower for k in cross_keywords) and not repo_filter:
54
55
  return "Cross Repository Question"
55
56
 
56
57
  # Default
@@ -86,6 +86,39 @@ def query_llm_with_retry(messages: list, model: str = None, max_retries: int = 3
86
86
  time.sleep(0.5)
87
87
  return ""
88
88
 
89
+ def inject_repository_summary_chunk(formatted_chunks: list, query_class: str) -> list:
90
+ """If the query is a cross-repository query, pre-append a summary chunk listing all repos."""
91
+ if query_class != "Cross Repository Question":
92
+ return formatted_chunks
93
+
94
+ try:
95
+ from storage.db import get_connection
96
+ conn = get_connection()
97
+ cursor = conn.cursor()
98
+ cursor.execute("SELECT repo_name, description, language FROM repositories")
99
+ all_repos = cursor.fetchall()
100
+ conn.close()
101
+
102
+ if all_repos:
103
+ repo_list_lines = ["All Connected Repositories:"]
104
+ for r in all_repos:
105
+ desc_str = f" - Description: {r[1]}" if r[1] else ""
106
+ lang_str = f" (Language: {r[2]})" if r[2] else ""
107
+ repo_list_lines.append(f"- {r[0]}{lang_str}{desc_str}")
108
+ repo_list_str = "\n".join(repo_list_lines)
109
+
110
+ # Pre-append to formatted_chunks with a high score to prevent trimming
111
+ formatted_chunks.insert(0, {
112
+ "text": repo_list_str,
113
+ "score": 999.0,
114
+ "type": "repository_summary"
115
+ })
116
+ except Exception as e:
117
+ import logging
118
+ logging.getLogger("llm").error(f"Failed to generate repository summary context chunk: {e}")
119
+
120
+ return formatted_chunks
121
+
89
122
  def run_hybrid_rag(question: str) -> dict:
90
123
  import time
91
124
  import logging
@@ -155,6 +188,7 @@ def run_hybrid_rag(question: str) -> dict:
155
188
  formatted_chunks, sources, repos, num_vector, num_keyword, num_graph, after_dedup = builder.build_context(
156
189
  question, vector_results, keyword_results, graph_results, repo_filter=repo_filter, query_class=query_class
157
190
  )
191
+ formatted_chunks = inject_repository_summary_chunk(formatted_chunks, query_class)
158
192
 
159
193
  system_prompt = (
160
194
  "You are an assistant answering ONLY from the supplied retrieved context.\n\n"
@@ -408,6 +442,7 @@ def run_hybrid_rag_stream(question: str):
408
442
  formatted_chunks, sources, repos, num_vector, num_keyword, num_graph, after_dedup = builder.build_context(
409
443
  question, vector_results, keyword_results, graph_results, repo_filter=repo_filter, query_class=query_class
410
444
  )
445
+ formatted_chunks = inject_repository_summary_chunk(formatted_chunks, query_class)
411
446
 
412
447
  system_prompt = (
413
448
  "You are an assistant answering ONLY from the supplied retrieved context.\n\n"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cli-memory-os"
3
- version = "0.1.7"
3
+ version = "0.1.8"
4
4
  description = "CLI-based Personal Knowledge Operating System"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -106,6 +106,36 @@ class TestSyncAskCLI(unittest.TestCase):
106
106
  # Verify that natural language query gets routed to ask and calls run_and_print_ask
107
107
  mock_run_and_print_ask.assert_called_once_with("What projects use Python?")
108
108
 
109
+ @patch("storage.db.get_connection")
110
+ def test_inject_repository_summary_chunk(self, mock_get_connection):
111
+ """Test repository summary chunk is injected for cross-repository questions."""
112
+ from core.llm import inject_repository_summary_chunk
113
+
114
+ # Mock database cursor to return some repositories
115
+ mock_conn = MagicMock()
116
+ mock_cursor = MagicMock()
117
+ mock_cursor.fetchall.return_value = [
118
+ ("Bug-Tracker", "Bug tracking system", "JavaScript"),
119
+ ("Memory-OS", "PKOS", "Python")
120
+ ]
121
+ mock_conn.cursor.return_value = mock_cursor
122
+ mock_get_connection.return_value = mock_conn
123
+
124
+ formatted_chunks = [
125
+ {"text": "Some chunk text", "score": 0.5, "type": "document"}
126
+ ]
127
+
128
+ # Calling with non-cross-repository query class should do nothing
129
+ res1 = inject_repository_summary_chunk(list(formatted_chunks), "General Knowledge Question")
130
+ self.assertEqual(len(res1), 1)
131
+
132
+ # Calling with Cross Repository Question should inject summary chunk
133
+ res2 = inject_repository_summary_chunk(list(formatted_chunks), "Cross Repository Question")
134
+ self.assertEqual(len(res2), 2)
135
+ self.assertEqual(res2[0]["type"], "repository_summary")
136
+ self.assertIn("Bug-Tracker", res2[0]["text"])
137
+ self.assertIn("Memory-OS", res2[0]["text"])
138
+
109
139
 
110
140
  if __name__ == "__main__":
111
141
  unittest.main()
File without changes
File without changes
File without changes
File without changes
File without changes