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.
- {agent_coderag-1.3.2/agent_coderag.egg-info → agent_coderag-1.3.4}/PKG-INFO +29 -1
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/README.md +27 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4/agent_coderag.egg-info}/PKG-INFO +29 -1
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/SOURCES.txt +29 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/requires.txt +1 -0
- agent_coderag-1.3.4/code_rag/__init__.py +16 -0
- agent_coderag-1.3.4/code_rag/api/__init__.py +6 -0
- agent_coderag-1.3.4/code_rag/api/client.py +110 -0
- agent_coderag-1.3.4/code_rag/api/models.py +26 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/constants.py +4 -0
- agent_coderag-1.3.4/code_rag/core/interfaces.py +113 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/manager.py +102 -34
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/entry/cli.py +186 -142
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/intelligence/distiller.py +30 -1
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/intelligence/embedder.py +55 -11
- agent_coderag-1.3.4/code_rag/intelligence/factory.py +33 -0
- agent_coderag-1.3.4/code_rag/intelligence/openai_embedder.py +86 -0
- agent_coderag-1.3.4/code_rag/services/config.py +118 -0
- agent_coderag-1.3.4/code_rag/services/discovery_api.py +8 -0
- agent_coderag-1.3.4/code_rag/services/factory.py +30 -0
- agent_coderag-1.3.4/code_rag/services/search.py +6 -0
- agent_coderag-1.3.4/code_rag/services/setup.py +72 -0
- agent_coderag-1.3.4/code_rag/services/sync.py +115 -0
- agent_coderag-1.3.4/code_rag/storage/duckdb_impl.py +490 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/pyproject.toml +2 -1
- agent_coderag-1.3.4/tests/test_api_client.py +159 -0
- agent_coderag-1.3.4/tests/test_api_models.py +42 -0
- agent_coderag-1.3.4/tests/test_api_rebuild_wipe.py +171 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_cli.py +41 -29
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_cli_detailed.py +158 -7
- agent_coderag-1.3.4/tests/test_cli_embeddings.py +221 -0
- agent_coderag-1.3.4/tests/test_cli_json_parity.py +105 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_code_rag_simple.py +5 -34
- agent_coderag-1.3.4/tests/test_distiller_config_embedding.py +192 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_embedder_detailed.py +6 -2
- agent_coderag-1.3.4/tests/test_embedder_factory.py +69 -0
- agent_coderag-1.3.4/tests/test_embedder_interface.py +74 -0
- agent_coderag-1.3.4/tests/test_embedder_stubs.py +26 -0
- agent_coderag-1.3.4/tests/test_factory_async.py +95 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_interfaces.py +33 -3
- agent_coderag-1.3.4/tests/test_local_onnx_embedder.py +236 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_manager_detailed.py +8 -2
- agent_coderag-1.3.4/tests/test_manager_embeddings.py +277 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_manager_extra.py +15 -2
- agent_coderag-1.3.4/tests/test_openai_embedder.py +182 -0
- agent_coderag-1.3.4/tests/test_readme_library_usage.py +8 -0
- agent_coderag-1.3.4/tests/test_readme_offline_embeddings.py +11 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_storage_detailed.py +41 -7
- agent_coderag-1.3.4/tests/test_storage_embeddings.py +446 -0
- agent_coderag-1.3.4/tests/test_sync_worker_errors.py +250 -0
- agent_coderag-1.3.2/code_rag/core/interfaces.py +0 -63
- agent_coderag-1.3.2/code_rag/storage/duckdb_impl.py +0 -311
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/LICENSE +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/NOTICE +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/dependency_links.txt +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/entry_points.txt +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/agent_coderag.egg-info/top_level.txt +0 -0
- {agent_coderag-1.3.2/code_rag → agent_coderag-1.3.4/code_rag/core}/__init__.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/exceptions.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/models.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/core/utils.py +0 -0
- {agent_coderag-1.3.2/code_rag/core → agent_coderag-1.3.4/code_rag/discovery}/__init__.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/dependency.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/java_discovery.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/manager.py +0 -0
- {agent_coderag-1.3.2/code_rag/discovery → agent_coderag-1.3.4/code_rag/discovery/providers}/__init__.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/base.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/csharp.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/go.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/java.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/javascript.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/python.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/discovery/providers/rust.py +0 -0
- {agent_coderag-1.3.2/code_rag/discovery/providers → agent_coderag-1.3.4/code_rag/entry}/__init__.py +0 -0
- {agent_coderag-1.3.2/code_rag/entry → agent_coderag-1.3.4/code_rag/intelligence}/__init__.py +0 -0
- {agent_coderag-1.3.2/code_rag/intelligence → agent_coderag-1.3.4/code_rag/parsers}/__init__.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/parsers/languages.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/parsers/multi_parser.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/parsers/tree_sitter.py +0 -0
- {agent_coderag-1.3.2/code_rag/parsers → agent_coderag-1.3.4/code_rag/services}/__init__.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/code_rag/storage/__init__.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/setup.cfg +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_csharp_discovery_detailed.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_dependency_discovery.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_discovery_manager_detailed.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_discovery_providers_extra.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_discovery_python.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_distiller.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_distiller_extra.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_embedder.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_js_discovery_detailed.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_languages.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_models.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_multi_parser.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_rust_discovery_detailed.py +0 -0
- {agent_coderag-1.3.2 → agent_coderag-1.3.4}/tests/test_tree_sitter_parser.py +0 -0
- {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.
|
|
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.
|
|
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
|
|
@@ -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
|