llama-github 0.4.0__tar.gz → 0.4.1__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.
- {llama_github-0.4.0 → llama_github-0.4.1}/CHANGELOG.md +25 -0
- llama_github-0.4.1/MANIFEST.in +6 -0
- {llama_github-0.4.0/llama_github.egg-info → llama_github-0.4.1}/PKG-INFO +31 -48
- {llama_github-0.4.0 → llama_github-0.4.1}/README.md +12 -34
- llama_github-0.4.1/llama_github/__init__.py +20 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/config/config.json +3 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/data_retrieval/github_api.py +181 -31
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/data_retrieval/github_entities.py +732 -145
- llama_github-0.4.1/llama_github/github_integration/__init__.py +13 -0
- llama_github-0.4.1/llama_github/github_integration/github_auth_manager.py +492 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/github_rag.py +43 -10
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/llm_integration/initial_load.py +41 -4
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/llm_integration/llm_handler.py +4 -4
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/rag_processing/rag_processor.py +36 -20
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/utils.py +28 -10
- llama_github-0.4.1/llama_github/version.py +1 -0
- {llama_github-0.4.0 → llama_github-0.4.1/llama_github.egg-info}/PKG-INFO +31 -48
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github.egg-info/SOURCES.txt +8 -0
- llama_github-0.4.1/llama_github.egg-info/requires.txt +23 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/pyproject.toml +19 -14
- llama_github-0.4.1/pytest.ini +6 -0
- llama_github-0.4.1/scripts/__init__.py +1 -0
- llama_github-0.4.1/scripts/verify_distribution_contents.py +78 -0
- llama_github-0.4.1/tests/__init__.py +2 -0
- llama_github-0.4.1/tests/conftest.py +95 -0
- llama_github-0.4.1/tests/test_data_retrieval.py +657 -0
- llama_github-0.4.1/tests/test_distribution_contents.py +39 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/tests/test_github_auth_manager.py +80 -2
- llama_github-0.4.1/tests/test_github_rag.py +78 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/tests/test_initial_load.py +62 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/tests/test_logger.py +2 -2
- llama_github-0.4.1/tests/test_logging_privacy.py +46 -0
- llama_github-0.4.1/tests/test_minimal_imports.py +33 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/tests/test_utils.py +14 -1
- llama_github-0.4.0/MANIFEST.in +0 -2
- llama_github-0.4.0/llama_github/__init__.py +0 -3
- llama_github-0.4.0/llama_github/github_integration/__init__.py +0 -7
- llama_github-0.4.0/llama_github/github_integration/github_auth_manager.py +0 -222
- llama_github-0.4.0/llama_github/version.py +0 -1
- llama_github-0.4.0/llama_github.egg-info/requires.txt +0 -20
- llama_github-0.4.0/tests/test_data_retrieval.py +0 -118
- llama_github-0.4.0/tests/test_github_rag.py +0 -33
- {llama_github-0.4.0 → llama_github-0.4.1}/LICENSE +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/config/__init__.py +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/config/config.py +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/data_retrieval/__init__.py +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/llm_integration/__init__.py +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/logger.py +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github/rag_processing/__init__.py +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github.egg-info/dependency_links.txt +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/llama_github.egg-info/top_level.txt +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/setup.cfg +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/setup.py +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/tests/test_llm_handler.py +0 -0
- {llama_github-0.4.0 → llama_github-0.4.1}/tests/test_rag_processor.py +0 -0
|
@@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.1] - 2026-07-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Added status-aware code/issue search APIs that distinguish `ok`, `no_hit`, `partial`, and `error`
|
|
12
|
+
- Added bounded pagination metadata for PR files and comments, plus the captured PR `head_sha`
|
|
13
|
+
- Added exact-head, bounded CI refresh with independently typed status/check-run evidence
|
|
14
|
+
- Added explicit repository-pool shutdown and an option to disable its cleanup worker
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Made the public `GithubRAG` import lazy so retrieval-only consumers do not import the ML/RAG stack
|
|
18
|
+
- Added connect/read timeouts, bounded REST pagination, privacy-safe logging, and immutable revisions for built-in Jina models
|
|
19
|
+
- Bounded related-issue extraction and expansion with configurable limits and truncation metadata
|
|
20
|
+
- Limited related-issue discovery to PR title/body and top-level PR comments, while retaining bare `#123` references in long descriptions
|
|
21
|
+
- Preserved review summaries and every inline review comment as separate chronological interactions
|
|
22
|
+
- Reduced commit-status history to the newest result per logical context while preserving fetched/current counts
|
|
23
|
+
- Raised dependency security floors while keeping the full install and public high-level RAG API compatible
|
|
24
|
+
- Hardened release and secret-scanning workflows with pinned actions, full-history scanning, checksum verification, and job-scoped PyPI OIDC
|
|
25
|
+
- Added a release artifact allowlist that rejects stale or unexplained files in the built wheel
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- Prevented Python AST parsing from being selected for non-Python paths based only on repository language metadata
|
|
29
|
+
- Fixed repository-pool cleanup so expired entries are actually evicted instead of retaining empty objects
|
|
30
|
+
- Fixed `get_pr_content()` so already-fetched PR comments participate in related-issue discovery instead of being processed too late
|
|
31
|
+
|
|
8
32
|
## [0.4.0] - 2026-03-25
|
|
9
33
|
|
|
10
34
|
### Changed
|
|
@@ -157,6 +181,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
157
181
|
- Integration with LLM for processing and generating responses
|
|
158
182
|
|
|
159
183
|
[0.1.4]: https://github.com/JetXu-LLM/llama-github/compare/v0.1.3...v0.1.4
|
|
184
|
+
[0.4.1]: https://github.com/JetXu-LLM/llama-github/compare/v0.4.0...v0.4.1
|
|
160
185
|
[0.1.3]: https://github.com/JetXu-LLM/llama-github/compare/v0.1.2...v0.1.3
|
|
161
186
|
[0.1.2]: https://github.com/JetXu-LLM/llama-github/compare/v0.1.1...v0.1.2
|
|
162
187
|
[0.1.1]: https://github.com/JetXu-LLM/llama-github/compare/v0.1.0...v0.1.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: llama-github
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: GitHub retrieval and context generation utilities for coding assistants and AI developer workflows.
|
|
5
5
|
Author-email: Jet Xu <Voldemort.xu@foxmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -11,66 +11,38 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
16
|
Classifier: Operating System :: OS Independent
|
|
15
17
|
Requires-Python: >=3.10
|
|
16
18
|
Description-Content-Type: text/markdown
|
|
17
19
|
License-File: LICENSE
|
|
18
20
|
Requires-Dist: PyGithub<3,>=2.4
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist: langchain-
|
|
23
|
-
Requires-Dist: langchain-
|
|
24
|
-
Requires-Dist: langchain-
|
|
21
|
+
Requires-Dist: PyJWT[crypto]<3,>=2.13
|
|
22
|
+
Requires-Dist: aiohttp<4,>=3.14.1
|
|
23
|
+
Requires-Dist: ipython<9,>=8.10
|
|
24
|
+
Requires-Dist: langchain-core<2,>=1.3.3
|
|
25
|
+
Requires-Dist: langchain-mistralai<2,>=1.0
|
|
26
|
+
Requires-Dist: langchain-openai<2,>=1.1.14
|
|
27
|
+
Requires-Dist: langchain-text-splitters<2,>=1.1.2
|
|
25
28
|
Requires-Dist: nest-asyncio<2,>=1.6
|
|
26
|
-
Requires-Dist: numpy<3,>=1.
|
|
29
|
+
Requires-Dist: numpy<3,>=1.26.4
|
|
27
30
|
Requires-Dist: pydantic<3,>=2.10
|
|
28
31
|
Requires-Dist: python-dateutil<3,>=2.9
|
|
29
|
-
Requires-Dist: requests<3,>=2.
|
|
30
|
-
Requires-Dist: tokenizers<1,>=0.
|
|
31
|
-
Requires-Dist: transformers<6,>=
|
|
32
|
-
Requires-Dist: urllib3<3,>=2
|
|
32
|
+
Requires-Dist: requests<3,>=2.33
|
|
33
|
+
Requires-Dist: tokenizers<1,>=0.22.1
|
|
34
|
+
Requires-Dist: transformers<6,>=5.3
|
|
35
|
+
Requires-Dist: urllib3<3,>=2.7
|
|
33
36
|
Provides-Extra: dev
|
|
34
37
|
Requires-Dist: build<2,>=1.2; extra == "dev"
|
|
35
|
-
Requires-Dist:
|
|
36
|
-
Requires-Dist: pytest
|
|
38
|
+
Requires-Dist: pip-audit<3,>=2.10; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest<10,>=9.0.3; extra == "dev"
|
|
40
|
+
Requires-Dist: pytest-asyncio<2,>=1.3; extra == "dev"
|
|
41
|
+
Requires-Dist: twine<7,>=6.2; extra == "dev"
|
|
37
42
|
Dynamic: license-file
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
<div align="right">
|
|
41
|
-
<details>
|
|
42
|
-
<summary >🌐 Language</summary>
|
|
43
|
-
<div>
|
|
44
|
-
<div align="center">
|
|
45
|
-
<a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=en">English</a>
|
|
46
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=zh-CN">简体中文</a>
|
|
47
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=zh-TW">繁體中文</a>
|
|
48
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=ja">日本語</a>
|
|
49
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=ko">한국어</a>
|
|
50
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=hi">हिन्दी</a>
|
|
51
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=th">ไทย</a>
|
|
52
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=fr">Français</a>
|
|
53
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=de">Deutsch</a>
|
|
54
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=es">Español</a>
|
|
55
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=it">Italiano</a>
|
|
56
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=ru">Русский</a>
|
|
57
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=pt">Português</a>
|
|
58
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=nl">Nederlands</a>
|
|
59
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=pl">Polski</a>
|
|
60
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=ar">العربية</a>
|
|
61
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=fa">فارسی</a>
|
|
62
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=tr">Türkçe</a>
|
|
63
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=vi">Tiếng Việt</a>
|
|
64
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=id">Bahasa Indonesia</a>
|
|
65
|
-
</div>
|
|
66
|
-
</div>
|
|
67
|
-
</details>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
44
|
# llama-github
|
|
71
45
|
|
|
72
|
-
[Detail Document] https://deepwiki.com/JetXu-LLM/llama-github
|
|
73
|
-
|
|
74
46
|
[](https://badge.fury.io/py/llama-github)
|
|
75
47
|
[](https://pepy.tech/project/Llama-github)
|
|
76
48
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
@@ -87,7 +59,15 @@ If you like this project or believe it has potential, please give it a ⭐️. Y
|
|
|
87
59
|
pip install llama-github
|
|
88
60
|
```
|
|
89
61
|
|
|
90
|
-
Current maintained runtime target: Python `3.10
|
|
62
|
+
Current maintained runtime target: Python `3.10` through `3.14`.
|
|
63
|
+
|
|
64
|
+
Version `0.4.1` keeps the existing high-level API while allowing retrieval-only
|
|
65
|
+
integrations to import GitHub and diff helpers without loading the ML/RAG dependency
|
|
66
|
+
stack. Built-in Jina models are pinned to immutable revisions; custom remote-code
|
|
67
|
+
models should provide their own immutable revision. Pull-request retrieval now keeps
|
|
68
|
+
bounded fetch-health metadata, expands related issues only from PR conversation
|
|
69
|
+
evidence, and preserves review summaries plus each inline comment without collapsing
|
|
70
|
+
them together.
|
|
91
71
|
|
|
92
72
|
## Usage
|
|
93
73
|
|
|
@@ -112,6 +92,9 @@ contexts = github_rag.retrieve_context(
|
|
|
112
92
|
|
|
113
93
|
print(contexts[0]["url"])
|
|
114
94
|
print(contexts[0]["context"])
|
|
95
|
+
|
|
96
|
+
# Stop the optional repository-cache cleanup worker in long-lived applications.
|
|
97
|
+
github_rag.close()
|
|
115
98
|
```
|
|
116
99
|
|
|
117
100
|
`retrieve_context()` returns a list of context dictionaries. Each item contains at least `context` and `url`.
|
|
@@ -1,38 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
<div align="right">
|
|
3
|
-
<details>
|
|
4
|
-
<summary >🌐 Language</summary>
|
|
5
|
-
<div>
|
|
6
|
-
<div align="center">
|
|
7
|
-
<a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=en">English</a>
|
|
8
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=zh-CN">简体中文</a>
|
|
9
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=zh-TW">繁體中文</a>
|
|
10
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=ja">日本語</a>
|
|
11
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=ko">한국어</a>
|
|
12
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=hi">हिन्दी</a>
|
|
13
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=th">ไทย</a>
|
|
14
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=fr">Français</a>
|
|
15
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=de">Deutsch</a>
|
|
16
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=es">Español</a>
|
|
17
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=it">Italiano</a>
|
|
18
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=ru">Русский</a>
|
|
19
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=pt">Português</a>
|
|
20
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=nl">Nederlands</a>
|
|
21
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=pl">Polski</a>
|
|
22
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=ar">العربية</a>
|
|
23
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=fa">فارسی</a>
|
|
24
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=tr">Türkçe</a>
|
|
25
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=vi">Tiếng Việt</a>
|
|
26
|
-
| <a href="https://openaitx.github.io/view.html?user=JetXu-LLM&project=llama-github&lang=id">Bahasa Indonesia</a>
|
|
27
|
-
</div>
|
|
28
|
-
</div>
|
|
29
|
-
</details>
|
|
30
|
-
</div>
|
|
31
|
-
|
|
32
1
|
# llama-github
|
|
33
2
|
|
|
34
|
-
[Detail Document] https://deepwiki.com/JetXu-LLM/llama-github
|
|
35
|
-
|
|
36
3
|
[](https://badge.fury.io/py/llama-github)
|
|
37
4
|
[](https://pepy.tech/project/Llama-github)
|
|
38
5
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
@@ -49,7 +16,15 @@ If you like this project or believe it has potential, please give it a ⭐️. Y
|
|
|
49
16
|
pip install llama-github
|
|
50
17
|
```
|
|
51
18
|
|
|
52
|
-
Current maintained runtime target: Python `3.10
|
|
19
|
+
Current maintained runtime target: Python `3.10` through `3.14`.
|
|
20
|
+
|
|
21
|
+
Version `0.4.1` keeps the existing high-level API while allowing retrieval-only
|
|
22
|
+
integrations to import GitHub and diff helpers without loading the ML/RAG dependency
|
|
23
|
+
stack. Built-in Jina models are pinned to immutable revisions; custom remote-code
|
|
24
|
+
models should provide their own immutable revision. Pull-request retrieval now keeps
|
|
25
|
+
bounded fetch-health metadata, expands related issues only from PR conversation
|
|
26
|
+
evidence, and preserves review summaries plus each inline comment without collapsing
|
|
27
|
+
them together.
|
|
53
28
|
|
|
54
29
|
## Usage
|
|
55
30
|
|
|
@@ -74,6 +49,9 @@ contexts = github_rag.retrieve_context(
|
|
|
74
49
|
|
|
75
50
|
print(contexts[0]["url"])
|
|
76
51
|
print(contexts[0]["context"])
|
|
52
|
+
|
|
53
|
+
# Stop the optional repository-cache cleanup worker in long-lived applications.
|
|
54
|
+
github_rag.close()
|
|
77
55
|
```
|
|
78
56
|
|
|
79
57
|
`retrieve_context()` returns a list of context dictionaries. Each item contains at least `context` and `url`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Public package surface with heavyweight RAG imports loaded on demand."""
|
|
2
|
+
|
|
3
|
+
from .logger import configure_logging
|
|
4
|
+
from .version import __version__
|
|
5
|
+
|
|
6
|
+
__all__ = ["GithubRAG", "__version__", "configure_logging"]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def __getattr__(name: str):
|
|
10
|
+
"""Preserve ``from llama_github import GithubRAG`` without eager ML imports."""
|
|
11
|
+
if name == "GithubRAG":
|
|
12
|
+
from .github_rag import GithubRAG
|
|
13
|
+
|
|
14
|
+
return GithubRAG
|
|
15
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def __dir__():
|
|
19
|
+
"""Expose lazy public attributes to introspection tools."""
|
|
20
|
+
return sorted(set(globals()) | set(__all__))
|
|
@@ -10,12 +10,15 @@
|
|
|
10
10
|
"default_mistral_model": "mistral-small-latest",
|
|
11
11
|
"default_mistral_simple_model": "mistral-small-latest",
|
|
12
12
|
"default_embedding": "jinaai/jina-embeddings-v2-base-code",
|
|
13
|
+
"default_embedding_revision": "516f4baf13dec4ddddda8631e019b5737c8bc250",
|
|
13
14
|
"default_reranker": "jinaai/jina-reranker-v2-base-multilingual",
|
|
15
|
+
"default_reranker_revision": "9cfeff2df7d40d1b78e75e5e9cebec92a99813c9",
|
|
14
16
|
"min_stars_to_keep_result": 20,
|
|
15
17
|
"max_workers": 8,
|
|
16
18
|
"code_search_max_hits": 30,
|
|
17
19
|
"issue_search_max_hits": 30,
|
|
18
20
|
"repo_search_max_hits": 10,
|
|
21
|
+
"related_issue_max_hits": 20,
|
|
19
22
|
"chunk_size": 2000,
|
|
20
23
|
"issue_chunk_size": 7000,
|
|
21
24
|
"repo_chunk_size": 7000,
|
|
@@ -2,15 +2,19 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
4
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import Optional
|
|
6
6
|
|
|
7
7
|
from github import GithubException
|
|
8
8
|
|
|
9
9
|
from llama_github.config.config import config
|
|
10
|
-
from llama_github.github_integration.github_auth_manager import
|
|
10
|
+
from llama_github.github_integration.github_auth_manager import (
|
|
11
|
+
ExtendedGithub,
|
|
12
|
+
RetrievalOutcome,
|
|
13
|
+
RetrievalResult,
|
|
14
|
+
)
|
|
11
15
|
from llama_github.logger import logger
|
|
12
16
|
|
|
13
|
-
from .github_entities import
|
|
17
|
+
from .github_entities import RepositoryPool
|
|
14
18
|
|
|
15
19
|
|
|
16
20
|
class GitHubAPIHandler:
|
|
@@ -23,8 +27,21 @@ class GitHubAPIHandler:
|
|
|
23
27
|
):
|
|
24
28
|
"""Create a retrieval helper bound to one GitHub client and one repository pool."""
|
|
25
29
|
self._github = github_instance
|
|
30
|
+
self._owns_pool = pool is None
|
|
26
31
|
self.pool = pool if pool is not None else RepositoryPool(github_instance)
|
|
27
32
|
|
|
33
|
+
def close(self) -> None:
|
|
34
|
+
"""Close the internally-created pool; injected pools remain caller-owned."""
|
|
35
|
+
if self._owns_pool:
|
|
36
|
+
self.pool.close()
|
|
37
|
+
|
|
38
|
+
def __enter__(self):
|
|
39
|
+
return self
|
|
40
|
+
|
|
41
|
+
def __exit__(self, exc_type, exc_value, traceback):
|
|
42
|
+
self.close()
|
|
43
|
+
return False
|
|
44
|
+
|
|
28
45
|
def _require_github(self) -> ExtendedGithub:
|
|
29
46
|
"""Return the configured GitHub client or raise a clear runtime error."""
|
|
30
47
|
if self._github is None:
|
|
@@ -59,8 +76,12 @@ class GitHubAPIHandler:
|
|
|
59
76
|
)
|
|
60
77
|
)
|
|
61
78
|
return result
|
|
62
|
-
except
|
|
63
|
-
logger.
|
|
79
|
+
except Exception as exc:
|
|
80
|
+
logger.error(
|
|
81
|
+
"Repository search failed query_length=%s error_type=%s",
|
|
82
|
+
len(query or ""),
|
|
83
|
+
type(exc).__name__,
|
|
84
|
+
)
|
|
64
85
|
return []
|
|
65
86
|
|
|
66
87
|
def get_repository(self, full_repo_name, github_instance=None):
|
|
@@ -76,20 +97,41 @@ class GitHubAPIHandler:
|
|
|
76
97
|
file_content = repository_obj.get_file_content(code_search_result["path"])
|
|
77
98
|
return repository_obj, file_content
|
|
78
99
|
|
|
79
|
-
def
|
|
80
|
-
"""Search
|
|
100
|
+
def search_code_with_status(self, query, repo_full_name=None) -> RetrievalResult:
|
|
101
|
+
"""Search code and retain fetch status through content expansion."""
|
|
81
102
|
try:
|
|
82
103
|
github = self._require_github()
|
|
83
|
-
logger.debug("Searching code
|
|
104
|
+
logger.debug("Searching code query_length=%s", len(query or ""))
|
|
84
105
|
if repo_full_name:
|
|
85
106
|
query = f"{query} repo:{repo_full_name}"
|
|
86
107
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
108
|
+
status_search = getattr(github, "search_code_with_status", None)
|
|
109
|
+
raw_result = (
|
|
110
|
+
status_search(
|
|
111
|
+
query=query,
|
|
112
|
+
per_page=config.get("code_search_max_hits"),
|
|
113
|
+
)
|
|
114
|
+
if callable(status_search)
|
|
115
|
+
else None
|
|
90
116
|
)
|
|
117
|
+
if not isinstance(raw_result, RetrievalResult):
|
|
118
|
+
legacy_items = github.search_code(
|
|
119
|
+
query=query,
|
|
120
|
+
per_page=config.get("code_search_max_hits"),
|
|
121
|
+
)
|
|
122
|
+
raw_result = RetrievalResult(
|
|
123
|
+
items=list(legacy_items or []),
|
|
124
|
+
outcome=(
|
|
125
|
+
RetrievalOutcome.OK
|
|
126
|
+
if legacy_items
|
|
127
|
+
else RetrievalOutcome.NO_HIT
|
|
128
|
+
),
|
|
129
|
+
pages_fetched=1,
|
|
130
|
+
)
|
|
131
|
+
code_results = raw_result.items
|
|
91
132
|
|
|
92
133
|
results_with_index = []
|
|
134
|
+
content_failures = 0
|
|
93
135
|
with ThreadPoolExecutor(max_workers=config.get("max_workers")) as executor:
|
|
94
136
|
future_to_index = {
|
|
95
137
|
executor.submit(self._get_file_content_through_repository, code_result): index
|
|
@@ -117,12 +159,54 @@ class GitHubAPIHandler:
|
|
|
117
159
|
}
|
|
118
160
|
)
|
|
119
161
|
except Exception:
|
|
120
|
-
|
|
162
|
+
content_failures += 1
|
|
163
|
+
logger.error(
|
|
164
|
+
"Code-search content expansion failed result_index=%s",
|
|
165
|
+
index,
|
|
166
|
+
)
|
|
121
167
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
168
|
+
items = sorted(results_with_index, key=lambda item: item["index"])
|
|
169
|
+
missing_content = len(code_results) - len(items)
|
|
170
|
+
incomplete = raw_result.outcome in {
|
|
171
|
+
RetrievalOutcome.PARTIAL,
|
|
172
|
+
RetrievalOutcome.ERROR,
|
|
173
|
+
} or missing_content > 0
|
|
174
|
+
if incomplete:
|
|
175
|
+
outcome = (
|
|
176
|
+
RetrievalOutcome.ERROR
|
|
177
|
+
if raw_result.outcome is RetrievalOutcome.ERROR and not items
|
|
178
|
+
else RetrievalOutcome.PARTIAL
|
|
179
|
+
)
|
|
180
|
+
elif items:
|
|
181
|
+
outcome = RetrievalOutcome.OK
|
|
182
|
+
else:
|
|
183
|
+
outcome = RetrievalOutcome.NO_HIT
|
|
184
|
+
return RetrievalResult(
|
|
185
|
+
items=items,
|
|
186
|
+
outcome=outcome,
|
|
187
|
+
pages_fetched=raw_result.pages_fetched,
|
|
188
|
+
truncated=raw_result.truncated,
|
|
189
|
+
status_code=raw_result.status_code,
|
|
190
|
+
error_type=(
|
|
191
|
+
"content_fetch_incomplete"
|
|
192
|
+
if missing_content or content_failures
|
|
193
|
+
else raw_result.error_type
|
|
194
|
+
),
|
|
195
|
+
)
|
|
196
|
+
except Exception as exc:
|
|
197
|
+
logger.error(
|
|
198
|
+
"Code search failed query_length=%s error_type=%s",
|
|
199
|
+
len(query or ""),
|
|
200
|
+
type(exc).__name__,
|
|
201
|
+
)
|
|
202
|
+
return RetrievalResult(
|
|
203
|
+
outcome=RetrievalOutcome.ERROR,
|
|
204
|
+
error_type=type(exc).__name__,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
def search_code(self, query, repo_full_name=None):
|
|
208
|
+
"""Compatibility API returning expanded code-search items only."""
|
|
209
|
+
return self.search_code_with_status(query, repo_full_name).items
|
|
126
210
|
|
|
127
211
|
def _get_issue_content_through_repository(self, issue):
|
|
128
212
|
"""Resolve an issue search hit into the rendered issue-content text block."""
|
|
@@ -130,8 +214,7 @@ class GitHubAPIHandler:
|
|
|
130
214
|
match = re.search(r"https://api.github.com/repos/([^/]+/[^/]+)/issues/(\d+)", issue_url)
|
|
131
215
|
if not match:
|
|
132
216
|
logger.warning(
|
|
133
|
-
"Failed to extract
|
|
134
|
-
issue_url,
|
|
217
|
+
"Failed to extract repository and issue number from issue URL",
|
|
135
218
|
)
|
|
136
219
|
return None
|
|
137
220
|
|
|
@@ -140,18 +223,39 @@ class GitHubAPIHandler:
|
|
|
140
223
|
repository_obj = self.get_repository(repo_full_name, github_instance=self._github)
|
|
141
224
|
return repository_obj.get_issue_content(number=issue_number, issue=issue)
|
|
142
225
|
|
|
143
|
-
def
|
|
144
|
-
"""Search
|
|
226
|
+
def search_issues_with_status(self, query, repo_full_name=None) -> RetrievalResult:
|
|
227
|
+
"""Search issues and retain fetch status through content expansion."""
|
|
145
228
|
try:
|
|
146
229
|
github = self._require_github()
|
|
147
|
-
logger.debug("Searching issues
|
|
230
|
+
logger.debug("Searching issues query_length=%s", len(query or ""))
|
|
148
231
|
if repo_full_name:
|
|
149
232
|
query = f"{query} repo:{repo_full_name}"
|
|
150
233
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
234
|
+
status_search = getattr(github, "search_issues_with_status", None)
|
|
235
|
+
raw_result = (
|
|
236
|
+
status_search(
|
|
237
|
+
query=query,
|
|
238
|
+
per_page=config.get("issue_search_max_hits"),
|
|
239
|
+
)
|
|
240
|
+
if callable(status_search)
|
|
241
|
+
else None
|
|
154
242
|
)
|
|
243
|
+
if not isinstance(raw_result, RetrievalResult):
|
|
244
|
+
legacy_items = github.search_issues(
|
|
245
|
+
query=query,
|
|
246
|
+
per_page=config.get("issue_search_max_hits"),
|
|
247
|
+
)
|
|
248
|
+
raw_result = RetrievalResult(
|
|
249
|
+
items=list(legacy_items or []),
|
|
250
|
+
outcome=(
|
|
251
|
+
RetrievalOutcome.OK
|
|
252
|
+
if legacy_items
|
|
253
|
+
else RetrievalOutcome.NO_HIT
|
|
254
|
+
),
|
|
255
|
+
pages_fetched=1,
|
|
256
|
+
)
|
|
257
|
+
raw_issue_count = len(raw_result.items)
|
|
258
|
+
issue_results = raw_result.items
|
|
155
259
|
issue_results = [
|
|
156
260
|
issue
|
|
157
261
|
for issue in issue_results
|
|
@@ -159,6 +263,7 @@ class GitHubAPIHandler:
|
|
|
159
263
|
]
|
|
160
264
|
|
|
161
265
|
results_with_index = []
|
|
266
|
+
content_failures = 0
|
|
162
267
|
with ThreadPoolExecutor(max_workers=config.get("max_workers")) as executor:
|
|
163
268
|
future_to_index = {
|
|
164
269
|
executor.submit(self._get_issue_content_through_repository, issue): index
|
|
@@ -180,12 +285,54 @@ class GitHubAPIHandler:
|
|
|
180
285
|
}
|
|
181
286
|
)
|
|
182
287
|
except Exception:
|
|
183
|
-
|
|
288
|
+
content_failures += 1
|
|
289
|
+
logger.error(
|
|
290
|
+
"Issue-search content expansion failed result_index=%s",
|
|
291
|
+
index,
|
|
292
|
+
)
|
|
184
293
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
294
|
+
items = sorted(results_with_index, key=lambda item: item["index"])
|
|
295
|
+
missing_content = raw_issue_count - len(items)
|
|
296
|
+
incomplete = raw_result.outcome in {
|
|
297
|
+
RetrievalOutcome.PARTIAL,
|
|
298
|
+
RetrievalOutcome.ERROR,
|
|
299
|
+
} or missing_content > 0
|
|
300
|
+
if incomplete:
|
|
301
|
+
outcome = (
|
|
302
|
+
RetrievalOutcome.ERROR
|
|
303
|
+
if raw_result.outcome is RetrievalOutcome.ERROR and not items
|
|
304
|
+
else RetrievalOutcome.PARTIAL
|
|
305
|
+
)
|
|
306
|
+
elif items:
|
|
307
|
+
outcome = RetrievalOutcome.OK
|
|
308
|
+
else:
|
|
309
|
+
outcome = RetrievalOutcome.NO_HIT
|
|
310
|
+
return RetrievalResult(
|
|
311
|
+
items=items,
|
|
312
|
+
outcome=outcome,
|
|
313
|
+
pages_fetched=raw_result.pages_fetched,
|
|
314
|
+
truncated=raw_result.truncated,
|
|
315
|
+
status_code=raw_result.status_code,
|
|
316
|
+
error_type=(
|
|
317
|
+
"content_fetch_incomplete"
|
|
318
|
+
if missing_content or content_failures
|
|
319
|
+
else raw_result.error_type
|
|
320
|
+
),
|
|
321
|
+
)
|
|
322
|
+
except Exception as exc:
|
|
323
|
+
logger.error(
|
|
324
|
+
"Issue search failed query_length=%s error_type=%s",
|
|
325
|
+
len(query or ""),
|
|
326
|
+
type(exc).__name__,
|
|
327
|
+
)
|
|
328
|
+
return RetrievalResult(
|
|
329
|
+
outcome=RetrievalOutcome.ERROR,
|
|
330
|
+
error_type=type(exc).__name__,
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
def search_issues(self, query, repo_full_name=None):
|
|
334
|
+
"""Compatibility API returning expanded issue-search items only."""
|
|
335
|
+
return self.search_issues_with_status(query, repo_full_name).items
|
|
189
336
|
|
|
190
337
|
@staticmethod
|
|
191
338
|
def _categorize_github_url(url):
|
|
@@ -209,7 +356,7 @@ class GitHubAPIHandler:
|
|
|
209
356
|
"""Expand a GitHub repository / issue / file URL into text content for retrieval."""
|
|
210
357
|
try:
|
|
211
358
|
self._require_github()
|
|
212
|
-
logger.debug("Retrieving content from GitHub URL
|
|
359
|
+
logger.debug("Retrieving content from categorized GitHub URL")
|
|
213
360
|
content = None
|
|
214
361
|
category = GitHubAPIHandler._categorize_github_url(url)
|
|
215
362
|
if category == "repo":
|
|
@@ -239,5 +386,8 @@ class GitHubAPIHandler:
|
|
|
239
386
|
logger.warning("Unsupported GitHub URL category: %s", category)
|
|
240
387
|
return content
|
|
241
388
|
except (GithubException, RuntimeError) as exc:
|
|
242
|
-
logger.
|
|
389
|
+
logger.error(
|
|
390
|
+
"GitHub URL retrieval failed error_type=%s",
|
|
391
|
+
type(exc).__name__,
|
|
392
|
+
)
|
|
243
393
|
return None
|