agent-coderag 1.3.2__tar.gz → 1.3.4__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 (97) hide show
  1. {agent_coderag-1.3.2/agent_coderag.egg-info → agent_coderag-1.3.4}/PKG-INFO +29 -1
  2. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/README.md +27 -0
  3. {agent_coderag-1.3.2 → agent_coderag-1.3.4/agent_coderag.egg-info}/PKG-INFO +29 -1
  4. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/SOURCES.txt +29 -0
  5. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/requires.txt +1 -0
  6. agent_coderag-1.3.4/code_rag/__init__.py +16 -0
  7. agent_coderag-1.3.4/code_rag/api/__init__.py +6 -0
  8. agent_coderag-1.3.4/code_rag/api/client.py +110 -0
  9. agent_coderag-1.3.4/code_rag/api/models.py +26 -0
  10. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/constants.py +4 -0
  11. agent_coderag-1.3.4/code_rag/core/interfaces.py +113 -0
  12. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/manager.py +102 -34
  13. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/entry/cli.py +186 -142
  14. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/intelligence/distiller.py +30 -1
  15. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/intelligence/embedder.py +55 -11
  16. agent_coderag-1.3.4/code_rag/intelligence/factory.py +33 -0
  17. agent_coderag-1.3.4/code_rag/intelligence/openai_embedder.py +86 -0
  18. agent_coderag-1.3.4/code_rag/services/config.py +118 -0
  19. agent_coderag-1.3.4/code_rag/services/discovery_api.py +8 -0
  20. agent_coderag-1.3.4/code_rag/services/factory.py +30 -0
  21. agent_coderag-1.3.4/code_rag/services/search.py +6 -0
  22. agent_coderag-1.3.4/code_rag/services/setup.py +72 -0
  23. agent_coderag-1.3.4/code_rag/services/sync.py +115 -0
  24. agent_coderag-1.3.4/code_rag/storage/duckdb_impl.py +490 -0
  25. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/pyproject.toml +2 -1
  26. agent_coderag-1.3.4/tests/test_api_client.py +159 -0
  27. agent_coderag-1.3.4/tests/test_api_models.py +42 -0
  28. agent_coderag-1.3.4/tests/test_api_rebuild_wipe.py +171 -0
  29. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_cli.py +41 -29
  30. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_cli_detailed.py +158 -7
  31. agent_coderag-1.3.4/tests/test_cli_embeddings.py +221 -0
  32. agent_coderag-1.3.4/tests/test_cli_json_parity.py +105 -0
  33. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_code_rag_simple.py +5 -34
  34. agent_coderag-1.3.4/tests/test_distiller_config_embedding.py +192 -0
  35. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_embedder_detailed.py +6 -2
  36. agent_coderag-1.3.4/tests/test_embedder_factory.py +69 -0
  37. agent_coderag-1.3.4/tests/test_embedder_interface.py +74 -0
  38. agent_coderag-1.3.4/tests/test_embedder_stubs.py +26 -0
  39. agent_coderag-1.3.4/tests/test_factory_async.py +95 -0
  40. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_interfaces.py +33 -3
  41. agent_coderag-1.3.4/tests/test_local_onnx_embedder.py +236 -0
  42. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_manager_detailed.py +8 -2
  43. agent_coderag-1.3.4/tests/test_manager_embeddings.py +277 -0
  44. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_manager_extra.py +15 -2
  45. agent_coderag-1.3.4/tests/test_openai_embedder.py +182 -0
  46. agent_coderag-1.3.4/tests/test_readme_library_usage.py +8 -0
  47. agent_coderag-1.3.4/tests/test_readme_offline_embeddings.py +11 -0
  48. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_storage_detailed.py +41 -7
  49. agent_coderag-1.3.4/tests/test_storage_embeddings.py +446 -0
  50. agent_coderag-1.3.4/tests/test_sync_worker_errors.py +250 -0
  51. agent_coderag-1.3.2/code_rag/core/interfaces.py +0 -63
  52. agent_coderag-1.3.2/code_rag/storage/duckdb_impl.py +0 -311
  53. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/LICENSE +0 -0
  54. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/NOTICE +0 -0
  55. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/dependency_links.txt +0 -0
  56. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/entry_points.txt +0 -0
  57. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/top_level.txt +0 -0
  58. {agent_coderag-1.3.2/code_rag → agent_coderag-1.3.4/code_rag/core}/__init__.py +0 -0
  59. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/exceptions.py +0 -0
  60. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/models.py +0 -0
  61. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/utils.py +0 -0
  62. {agent_coderag-1.3.2/code_rag/core → agent_coderag-1.3.4/code_rag/discovery}/__init__.py +0 -0
  63. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/dependency.py +0 -0
  64. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/java_discovery.py +0 -0
  65. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/manager.py +0 -0
  66. {agent_coderag-1.3.2/code_rag/discovery → agent_coderag-1.3.4/code_rag/discovery/providers}/__init__.py +0 -0
  67. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/base.py +0 -0
  68. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/csharp.py +0 -0
  69. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/go.py +0 -0
  70. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/java.py +0 -0
  71. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/javascript.py +0 -0
  72. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/python.py +0 -0
  73. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/rust.py +0 -0
  74. {agent_coderag-1.3.2/code_rag/discovery/providers → agent_coderag-1.3.4/code_rag/entry}/__init__.py +0 -0
  75. {agent_coderag-1.3.2/code_rag/entry → agent_coderag-1.3.4/code_rag/intelligence}/__init__.py +0 -0
  76. {agent_coderag-1.3.2/code_rag/intelligence → agent_coderag-1.3.4/code_rag/parsers}/__init__.py +0 -0
  77. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/parsers/languages.py +0 -0
  78. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/parsers/multi_parser.py +0 -0
  79. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/parsers/tree_sitter.py +0 -0
  80. {agent_coderag-1.3.2/code_rag/parsers → agent_coderag-1.3.4/code_rag/services}/__init__.py +0 -0
  81. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/storage/__init__.py +0 -0
  82. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/setup.cfg +0 -0
  83. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_csharp_discovery_detailed.py +0 -0
  84. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_dependency_discovery.py +0 -0
  85. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_discovery_manager_detailed.py +0 -0
  86. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_discovery_providers_extra.py +0 -0
  87. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_discovery_python.py +0 -0
  88. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_distiller.py +0 -0
  89. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_distiller_extra.py +0 -0
  90. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_embedder.py +0 -0
  91. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_js_discovery_detailed.py +0 -0
  92. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_languages.py +0 -0
  93. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_models.py +0 -0
  94. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_multi_parser.py +0 -0
  95. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_rust_discovery_detailed.py +0 -0
  96. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_tree_sitter_parser.py +0 -0
  97. {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_utils_detailed.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-coderag
3
- Version: 1.3.2
3
+ Version: 1.3.4
4
4
  Summary: Lightweight semantic code search and distillation utility for AI coding agents. It solves the API knowledge gap via real-time local signature extraction and intent analysis without PyTorch. Optimized for token efficiency, it compresses codebase context into compact semantic summaries stored in a local DuckDB vector similarity index.
5
5
  Author-email: Igor Boloban <naranor@gmail.com>
6
6
  License: MIT
@@ -29,6 +29,7 @@ Requires-Dist: onnxruntime
29
29
  Requires-Dist: tokenizers
30
30
  Requires-Dist: pydantic
31
31
  Requires-Dist: httpx
32
+ Requires-Dist: requests
32
33
  Requires-Dist: aiofiles
33
34
  Requires-Dist: pathspec
34
35
  Requires-Dist: tree-sitter
@@ -118,6 +119,18 @@ If you don't configure an LLM provider, agent-coderag works in **100% Offline Mo
118
119
  - **Search:** Remains fast and accurate.
119
120
  - **Distillation:** Instead of AI-generated summaries, the system uses code signatures and entity names as fallback metadata. No data ever leaves your machine.
120
121
 
122
+ Remote embeddings are **not** 100% Offline Mode. If you set `embedding_base` + `embedding_model`, `sync` / `search` / `rebuild` need the network. Embedder choice is process-global (`config.json`); after a remote model or dimension change, run `agent-coderag rebuild` (or delete that `--db`) for **each** project index.
123
+
124
+ ```bash
125
+ agent-coderag config \
126
+ --embedding-url "http://localhost:8081/v1" \
127
+ --embedding-model "text-embedding-3-small" \
128
+ --embedding-key "your-api-key" \
129
+ --embedding-provider "openai"
130
+
131
+ agent-coderag config --clear-embedding
132
+ ```
133
+
121
134
  ### First Sync & Search
122
135
  ```bash
123
136
  # Index your entire project (respects .gitignore automatically)
@@ -148,6 +161,21 @@ agent-coderag api fmt
148
161
 
149
162
  ---
150
163
 
164
+ ## Library Usage
165
+
166
+ ```python
167
+ from code_rag import CodeRAG
168
+
169
+ async def main():
170
+ async with CodeRAG(db="code_rag.db") as rag:
171
+ await rag.setup()
172
+ await rag.sync(index_all=True)
173
+ hits = await rag.search("authentication middleware", limit=5)
174
+ report = await rag.api("pydantic", lang="python")
175
+ ```
176
+
177
+ ---
178
+
151
179
  ## Supported Ecosystems (Discovery)
152
180
 
153
181
  | Language | Method | Discovery Source |
@@ -73,6 +73,18 @@ If you don't configure an LLM provider, agent-coderag works in **100% Offline Mo
73
73
  - **Search:** Remains fast and accurate.
74
74
  - **Distillation:** Instead of AI-generated summaries, the system uses code signatures and entity names as fallback metadata. No data ever leaves your machine.
75
75
 
76
+ Remote embeddings are **not** 100% Offline Mode. If you set `embedding_base` + `embedding_model`, `sync` / `search` / `rebuild` need the network. Embedder choice is process-global (`config.json`); after a remote model or dimension change, run `agent-coderag rebuild` (or delete that `--db`) for **each** project index.
77
+
78
+ ```bash
79
+ agent-coderag config \
80
+ --embedding-url "http://localhost:8081/v1" \
81
+ --embedding-model "text-embedding-3-small" \
82
+ --embedding-key "your-api-key" \
83
+ --embedding-provider "openai"
84
+
85
+ agent-coderag config --clear-embedding
86
+ ```
87
+
76
88
  ### First Sync & Search
77
89
  ```bash
78
90
  # Index your entire project (respects .gitignore automatically)
@@ -103,6 +115,21 @@ agent-coderag api fmt
103
115
 
104
116
  ---
105
117
 
118
+ ## Library Usage
119
+
120
+ ```python
121
+ from code_rag import CodeRAG
122
+
123
+ async def main():
124
+ async with CodeRAG(db="code_rag.db") as rag:
125
+ await rag.setup()
126
+ await rag.sync(index_all=True)
127
+ hits = await rag.search("authentication middleware", limit=5)
128
+ report = await rag.api("pydantic", lang="python")
129
+ ```
130
+
131
+ ---
132
+
106
133
  ## Supported Ecosystems (Discovery)
107
134
 
108
135
  | Language | Method | Discovery Source |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-coderag
3
- Version: 1.3.2
3
+ Version: 1.3.4
4
4
  Summary: Lightweight semantic code search and distillation utility for AI coding agents. It solves the API knowledge gap via real-time local signature extraction and intent analysis without PyTorch. Optimized for token efficiency, it compresses codebase context into compact semantic summaries stored in a local DuckDB vector similarity index.
5
5
  Author-email: Igor Boloban <naranor@gmail.com>
6
6
  License: MIT
@@ -29,6 +29,7 @@ Requires-Dist: onnxruntime
29
29
  Requires-Dist: tokenizers
30
30
  Requires-Dist: pydantic
31
31
  Requires-Dist: httpx
32
+ Requires-Dist: requests
32
33
  Requires-Dist: aiofiles
33
34
  Requires-Dist: pathspec
34
35
  Requires-Dist: tree-sitter
@@ -118,6 +119,18 @@ If you don't configure an LLM provider, agent-coderag works in **100% Offline Mo
118
119
  - **Search:** Remains fast and accurate.
119
120
  - **Distillation:** Instead of AI-generated summaries, the system uses code signatures and entity names as fallback metadata. No data ever leaves your machine.
120
121
 
122
+ Remote embeddings are **not** 100% Offline Mode. If you set `embedding_base` + `embedding_model`, `sync` / `search` / `rebuild` need the network. Embedder choice is process-global (`config.json`); after a remote model or dimension change, run `agent-coderag rebuild` (or delete that `--db`) for **each** project index.
123
+
124
+ ```bash
125
+ agent-coderag config \
126
+ --embedding-url "http://localhost:8081/v1" \
127
+ --embedding-model "text-embedding-3-small" \
128
+ --embedding-key "your-api-key" \
129
+ --embedding-provider "openai"
130
+
131
+ agent-coderag config --clear-embedding
132
+ ```
133
+
121
134
  ### First Sync & Search
122
135
  ```bash
123
136
  # Index your entire project (respects .gitignore automatically)
@@ -148,6 +161,21 @@ agent-coderag api fmt
148
161
 
149
162
  ---
150
163
 
164
+ ## Library Usage
165
+
166
+ ```python
167
+ from code_rag import CodeRAG
168
+
169
+ async def main():
170
+ async with CodeRAG(db="code_rag.db") as rag:
171
+ await rag.setup()
172
+ await rag.sync(index_all=True)
173
+ hits = await rag.search("authentication middleware", limit=5)
174
+ report = await rag.api("pydantic", lang="python")
175
+ ```
176
+
177
+ ---
178
+
151
179
  ## Supported Ecosystems (Discovery)
152
180
 
153
181
  | Language | Method | Discovery Source |
@@ -9,6 +9,9 @@ agent_coderag.egg-info/entry_points.txt
9
9
  agent_coderag.egg-info/requires.txt
10
10
  agent_coderag.egg-info/top_level.txt
11
11
  code_rag/__init__.py
12
+ code_rag/api/__init__.py
13
+ code_rag/api/client.py
14
+ code_rag/api/models.py
12
15
  code_rag/core/__init__.py
13
16
  code_rag/core/constants.py
14
17
  code_rag/core/exceptions.py
@@ -33,14 +36,28 @@ code_rag/entry/cli.py
33
36
  code_rag/intelligence/__init__.py
34
37
  code_rag/intelligence/distiller.py
35
38
  code_rag/intelligence/embedder.py
39
+ code_rag/intelligence/factory.py
40
+ code_rag/intelligence/openai_embedder.py
36
41
  code_rag/parsers/__init__.py
37
42
  code_rag/parsers/languages.py
38
43
  code_rag/parsers/multi_parser.py
39
44
  code_rag/parsers/tree_sitter.py
45
+ code_rag/services/__init__.py
46
+ code_rag/services/config.py
47
+ code_rag/services/discovery_api.py
48
+ code_rag/services/factory.py
49
+ code_rag/services/search.py
50
+ code_rag/services/setup.py
51
+ code_rag/services/sync.py
40
52
  code_rag/storage/__init__.py
41
53
  code_rag/storage/duckdb_impl.py
54
+ tests/test_api_client.py
55
+ tests/test_api_models.py
56
+ tests/test_api_rebuild_wipe.py
42
57
  tests/test_cli.py
43
58
  tests/test_cli_detailed.py
59
+ tests/test_cli_embeddings.py
60
+ tests/test_cli_json_parity.py
44
61
  tests/test_code_rag_simple.py
45
62
  tests/test_csharp_discovery_detailed.py
46
63
  tests/test_dependency_discovery.py
@@ -48,17 +65,29 @@ tests/test_discovery_manager_detailed.py
48
65
  tests/test_discovery_providers_extra.py
49
66
  tests/test_discovery_python.py
50
67
  tests/test_distiller.py
68
+ tests/test_distiller_config_embedding.py
51
69
  tests/test_distiller_extra.py
52
70
  tests/test_embedder.py
53
71
  tests/test_embedder_detailed.py
72
+ tests/test_embedder_factory.py
73
+ tests/test_embedder_interface.py
74
+ tests/test_embedder_stubs.py
75
+ tests/test_factory_async.py
54
76
  tests/test_interfaces.py
55
77
  tests/test_js_discovery_detailed.py
56
78
  tests/test_languages.py
79
+ tests/test_local_onnx_embedder.py
57
80
  tests/test_manager_detailed.py
81
+ tests/test_manager_embeddings.py
58
82
  tests/test_manager_extra.py
59
83
  tests/test_models.py
60
84
  tests/test_multi_parser.py
85
+ tests/test_openai_embedder.py
86
+ tests/test_readme_library_usage.py
87
+ tests/test_readme_offline_embeddings.py
61
88
  tests/test_rust_discovery_detailed.py
62
89
  tests/test_storage_detailed.py
90
+ tests/test_storage_embeddings.py
91
+ tests/test_sync_worker_errors.py
63
92
  tests/test_tree_sitter_parser.py
64
93
  tests/test_utils_detailed.py
@@ -5,6 +5,7 @@ onnxruntime
5
5
  tokenizers
6
6
  pydantic
7
7
  httpx
8
+ requests
8
9
  aiofiles
9
10
  pathspec
10
11
  tree-sitter
@@ -0,0 +1,16 @@
1
+ from code_rag.api.client import CodeRAG
2
+ from code_rag.api.models import SyncResult, ApiReport, SetupResult
3
+ from code_rag.core.models import KnowledgeUnit, UnitKind
4
+ from code_rag.intelligence.distiller import DistillerConfig
5
+ from code_rag.core.exceptions import CodeRAGError
6
+
7
+ __all__ = [
8
+ "CodeRAG",
9
+ "SyncResult",
10
+ "ApiReport",
11
+ "SetupResult",
12
+ "KnowledgeUnit",
13
+ "UnitKind",
14
+ "DistillerConfig",
15
+ "CodeRAGError",
16
+ ]
@@ -0,0 +1,6 @@
1
+ """Public API package for CodeRAG.
2
+
3
+ `CodeRAG` lives in `code_rag.api.client` and is re-exported from top-level
4
+ `code_rag`. Import models from `code_rag.api.models` directly; this package
5
+ init stays empty to avoid circular imports with `code_rag.services.*`.
6
+ """
@@ -0,0 +1,110 @@
1
+ from pathlib import Path
2
+ from typing import Optional, Union
3
+
4
+ from code_rag.api.models import ApiReport, SetupResult, SyncResult
5
+ from code_rag.core.manager import CodeRAGManager
6
+ from code_rag.core.models import KnowledgeUnit
7
+ from code_rag.intelligence.distiller import DistillerConfig
8
+ from code_rag.services.config import load_or_update_config
9
+ from code_rag.services.discovery_api import run_api
10
+ from code_rag.services.factory import create_manager
11
+ from code_rag.services.search import run_search
12
+ from code_rag.services.setup import run_setup
13
+ from code_rag.services.sync import run_rebuild, run_sync
14
+
15
+
16
+ class CodeRAG:
17
+ """Public async facade over CodeRAG services and the storage/search manager."""
18
+
19
+ def __init__(
20
+ self,
21
+ db: str = "code_rag.db",
22
+ onnx: Optional[str] = None,
23
+ *,
24
+ root: Optional[Union[str, Path]] = None,
25
+ allow_build_execution: bool = False,
26
+ ):
27
+ self._db = db
28
+ self._onnx = onnx
29
+ self._root = Path(root) if root is not None else Path.cwd()
30
+ self._allow_build_execution = allow_build_execution
31
+ self._manager: Optional[CodeRAGManager] = None
32
+
33
+ async def __aenter__(self) -> "CodeRAG":
34
+ return self
35
+
36
+ async def __aexit__(self, *_exc) -> None:
37
+ await self.close()
38
+
39
+ async def close(self) -> None:
40
+ if self._manager is not None:
41
+ await self._manager.close()
42
+ self._manager = None
43
+
44
+ async def _ensure_manager(self, wipe: bool = False):
45
+ if wipe and self._manager is not None:
46
+ await self.close()
47
+ if self._manager is None:
48
+ self._manager = await create_manager(
49
+ self._db,
50
+ self._onnx,
51
+ allow_build_execution=self._allow_build_execution,
52
+ wipe=wipe,
53
+ )
54
+ return self._manager
55
+
56
+ async def config( # pylint: disable=too-many-arguments
57
+ self,
58
+ *,
59
+ url: Optional[str] = None,
60
+ key: Optional[str] = None,
61
+ model: Optional[str] = None,
62
+ provider: Optional[str] = None,
63
+ embedding_url: Optional[str] = None,
64
+ embedding_key: Optional[str] = None,
65
+ embedding_model: Optional[str] = None,
66
+ embedding_provider: Optional[str] = None,
67
+ clear_embedding: bool = False,
68
+ ) -> DistillerConfig:
69
+ return load_or_update_config(
70
+ url=url,
71
+ key=key,
72
+ model=model,
73
+ provider=provider,
74
+ embedding_url=embedding_url,
75
+ embedding_key=embedding_key,
76
+ embedding_model=embedding_model,
77
+ embedding_provider=embedding_provider,
78
+ clear_embedding=clear_embedding,
79
+ )
80
+
81
+ async def setup(self, *, force: bool = False) -> SetupResult:
82
+ return await run_setup(force=force)
83
+
84
+ async def sync(
85
+ self,
86
+ path: Optional[str] = None,
87
+ *,
88
+ index_all: bool = False,
89
+ force: bool = False,
90
+ ) -> SyncResult:
91
+ if path is None and not index_all:
92
+ return SyncResult(status="success", indexed_files=0)
93
+ return await run_sync(
94
+ await self._ensure_manager(),
95
+ root=self._root,
96
+ path=path,
97
+ index_all=index_all,
98
+ force=force,
99
+ )
100
+
101
+ async def search(self, query: str, *, limit: int = 5) -> list[KnowledgeUnit]:
102
+ return await run_search(await self._ensure_manager(), query, limit=limit)
103
+
104
+ async def api(self, library: str, *, lang: Optional[str] = None) -> ApiReport:
105
+ return await run_api(await self._ensure_manager(), library, lang=lang)
106
+
107
+ async def rebuild(self) -> SyncResult:
108
+ await self.close()
109
+ manager = await self._ensure_manager(wipe=True)
110
+ return await run_rebuild(manager, root=self._root)
@@ -0,0 +1,26 @@
1
+ from pydantic import BaseModel, ConfigDict, Field
2
+
3
+
4
+ class SyncFileError(BaseModel):
5
+ file: str
6
+ message: str
7
+
8
+
9
+ class SyncResult(BaseModel):
10
+ status: str
11
+ indexed_files: int
12
+ errors: list[SyncFileError] = Field(default_factory=list)
13
+
14
+
15
+ class ApiReport(BaseModel):
16
+ library: str
17
+ language: str
18
+ report: str
19
+
20
+
21
+ class SetupResult(BaseModel):
22
+ model_config = ConfigDict(protected_namespaces=())
23
+
24
+ model_dir: str
25
+ downloaded: list[str]
26
+ skipped: list[str]
@@ -4,6 +4,10 @@ Central location for project-wide constants.
4
4
 
5
5
  # Embedding Model Constants
6
6
  EMBEDDING_DIM = 384
7
+ EMBEDDING_BATCH_SIZE = 32
8
+ EMBEDDING_REQUEST_TIMEOUT = 30
9
+ EMBEDDING_PROBE_TEXT = "probe"
10
+ LOCAL_EMBEDDING_MODEL_ID = "local:mini-lm"
7
11
  MAX_TOKEN_LENGTH = 512
8
12
  PAD_ID = 0
9
13
  PAD_TOKEN = "[PAD]" # nosec B105
@@ -0,0 +1,113 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import List, Optional
3
+ from .models import KnowledgeUnit, Relation
4
+
5
+
6
+ class IParser(ABC):
7
+ """Interface for extracting structure from code."""
8
+
9
+ @abstractmethod
10
+ async def distill_file(self, file_path: str) -> List[KnowledgeUnit]:
11
+ pass # pragma: no cover
12
+
13
+
14
+ class IEmbedder(ABC):
15
+ """Port for local ONNX and remote OpenAI-compatible embedders."""
16
+
17
+ @property
18
+ @abstractmethod
19
+ def dimension(self) -> int:
20
+ """Bound embedding width. No IO. Raise if unbound.""" # pragma: no cover
21
+
22
+ @property
23
+ @abstractmethod
24
+ def model_id(self) -> str:
25
+ """Stable id written to index_meta (local:mini-lm or remote model).""" # pragma: no cover
26
+
27
+ @abstractmethod
28
+ def bind_dimension(self, dim: int) -> None:
29
+ """Record the index dimension before search/upsert.""" # pragma: no cover
30
+
31
+ @abstractmethod
32
+ async def aembed(self, texts: list[str]) -> list[list[float]]:
33
+ """Return len(texts) L2-normalized rows, 1:1 with input order.""" # pragma: no cover
34
+
35
+ @abstractmethod
36
+ async def close(self) -> None:
37
+ """Release ONNX session and/or HTTP resources.""" # pragma: no cover
38
+
39
+
40
+ class IStorage(ABC):
41
+ """Interface for storing the index."""
42
+
43
+ @abstractmethod
44
+ async def upsert_unit(
45
+ self, unit: KnowledgeUnit, vector: Optional[List[float]] = None
46
+ ):
47
+ pass # pragma: no cover
48
+
49
+ @abstractmethod
50
+ async def has_embedding(self, unit_id: str) -> bool:
51
+ pass # pragma: no cover
52
+
53
+ @abstractmethod
54
+ async def list_units(self) -> List[KnowledgeUnit]:
55
+ pass # pragma: no cover
56
+
57
+ @abstractmethod
58
+ async def mark_embedding_model_synced(self) -> None:
59
+ pass # pragma: no cover
60
+
61
+ @property
62
+ @abstractmethod
63
+ def embedding_model_dirty(self) -> bool:
64
+ pass # pragma: no cover
65
+
66
+ @property
67
+ @abstractmethod
68
+ def embedder(self) -> IEmbedder:
69
+ """Bound embedder used for vector search and upsert.""" # pragma: no cover
70
+
71
+ @abstractmethod
72
+ async def get_unit(self, unit_id: str) -> Optional[KnowledgeUnit]:
73
+ pass # pragma: no cover
74
+
75
+ @abstractmethod
76
+ async def search_units(self, query: str, limit: int = 5) -> List[KnowledgeUnit]:
77
+ pass # pragma: no cover
78
+
79
+ @abstractmethod
80
+ async def upsert_relation(self, relation: Relation):
81
+ pass # pragma: no cover
82
+
83
+ @abstractmethod
84
+ async def get_relations(
85
+ self, unit_id: str, direction: str = "out"
86
+ ) -> List[Relation]:
87
+ pass # pragma: no cover
88
+
89
+ @abstractmethod
90
+ async def set_dependency_path(self, lib_name: str, path: str) -> None:
91
+ """Caches the absolute path to a library's JAR/binary."""
92
+
93
+ @abstractmethod
94
+ async def get_dependency_path(self, lib_name: str) -> Optional[str]:
95
+ """Retrieves the cached path for a library."""
96
+
97
+ @abstractmethod
98
+ async def delete_stale_units(
99
+ self, file_path: str, current_unit_ids: List[str]
100
+ ) -> None:
101
+ """Removes units that are no longer present in the given file."""
102
+
103
+ @abstractmethod
104
+ async def close(self) -> None:
105
+ """Closes the storage connection and releases resources."""
106
+
107
+
108
+ class IIntelligence(ABC):
109
+ """Interface for LLM-based analysis (distillation, embeddings)."""
110
+
111
+ @abstractmethod
112
+ async def summarize(self, code: str, unit_name: str) -> str:
113
+ pass # pragma: no cover