code-graph-builder 0.2.0__py3-none-any.whl

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 (93) hide show
  1. code_graph_builder/__init__.py +82 -0
  2. code_graph_builder/builder.py +366 -0
  3. code_graph_builder/cgb_cli.py +32 -0
  4. code_graph_builder/cli.py +564 -0
  5. code_graph_builder/commands_cli.py +1288 -0
  6. code_graph_builder/config.py +340 -0
  7. code_graph_builder/constants.py +708 -0
  8. code_graph_builder/embeddings/__init__.py +40 -0
  9. code_graph_builder/embeddings/qwen3_embedder.py +573 -0
  10. code_graph_builder/embeddings/vector_store.py +584 -0
  11. code_graph_builder/examples/__init__.py +0 -0
  12. code_graph_builder/examples/example_configuration.py +276 -0
  13. code_graph_builder/examples/example_kuzu_usage.py +109 -0
  14. code_graph_builder/examples/example_semantic_search_full.py +347 -0
  15. code_graph_builder/examples/generate_wiki.py +915 -0
  16. code_graph_builder/examples/graph_export_example.py +100 -0
  17. code_graph_builder/examples/rag_example.py +206 -0
  18. code_graph_builder/examples/test_cli_demo.py +129 -0
  19. code_graph_builder/examples/test_embedding_api.py +153 -0
  20. code_graph_builder/examples/test_kuzu_local.py +190 -0
  21. code_graph_builder/examples/test_rag_redis.py +390 -0
  22. code_graph_builder/graph_updater.py +605 -0
  23. code_graph_builder/guidance/__init__.py +1 -0
  24. code_graph_builder/guidance/agent.py +123 -0
  25. code_graph_builder/guidance/prompts.py +74 -0
  26. code_graph_builder/guidance/toolset.py +264 -0
  27. code_graph_builder/language_spec.py +536 -0
  28. code_graph_builder/mcp/__init__.py +21 -0
  29. code_graph_builder/mcp/api_doc_generator.py +764 -0
  30. code_graph_builder/mcp/file_editor.py +207 -0
  31. code_graph_builder/mcp/pipeline.py +777 -0
  32. code_graph_builder/mcp/server.py +161 -0
  33. code_graph_builder/mcp/tools.py +1800 -0
  34. code_graph_builder/models.py +115 -0
  35. code_graph_builder/parser_loader.py +344 -0
  36. code_graph_builder/parsers/__init__.py +7 -0
  37. code_graph_builder/parsers/call_processor.py +306 -0
  38. code_graph_builder/parsers/call_resolver.py +139 -0
  39. code_graph_builder/parsers/definition_processor.py +796 -0
  40. code_graph_builder/parsers/factory.py +119 -0
  41. code_graph_builder/parsers/import_processor.py +293 -0
  42. code_graph_builder/parsers/structure_processor.py +145 -0
  43. code_graph_builder/parsers/type_inference.py +143 -0
  44. code_graph_builder/parsers/utils.py +134 -0
  45. code_graph_builder/rag/__init__.py +68 -0
  46. code_graph_builder/rag/camel_agent.py +429 -0
  47. code_graph_builder/rag/client.py +298 -0
  48. code_graph_builder/rag/config.py +239 -0
  49. code_graph_builder/rag/cypher_generator.py +67 -0
  50. code_graph_builder/rag/llm_backend.py +210 -0
  51. code_graph_builder/rag/markdown_generator.py +352 -0
  52. code_graph_builder/rag/prompt_templates.py +440 -0
  53. code_graph_builder/rag/rag_engine.py +640 -0
  54. code_graph_builder/rag/review_report.md +172 -0
  55. code_graph_builder/rag/tests/__init__.py +3 -0
  56. code_graph_builder/rag/tests/test_camel_agent.py +313 -0
  57. code_graph_builder/rag/tests/test_client.py +221 -0
  58. code_graph_builder/rag/tests/test_config.py +177 -0
  59. code_graph_builder/rag/tests/test_markdown_generator.py +240 -0
  60. code_graph_builder/rag/tests/test_prompt_templates.py +160 -0
  61. code_graph_builder/services/__init__.py +39 -0
  62. code_graph_builder/services/graph_service.py +465 -0
  63. code_graph_builder/services/kuzu_service.py +665 -0
  64. code_graph_builder/services/memory_service.py +171 -0
  65. code_graph_builder/settings.py +75 -0
  66. code_graph_builder/tests/ACCEPTANCE_CRITERIA_PHASE2.md +401 -0
  67. code_graph_builder/tests/__init__.py +1 -0
  68. code_graph_builder/tests/run_acceptance_check.py +378 -0
  69. code_graph_builder/tests/test_api_find.py +231 -0
  70. code_graph_builder/tests/test_api_find_integration.py +226 -0
  71. code_graph_builder/tests/test_basic.py +78 -0
  72. code_graph_builder/tests/test_c_api_extraction.py +388 -0
  73. code_graph_builder/tests/test_call_resolution_scenarios.py +504 -0
  74. code_graph_builder/tests/test_embedder.py +411 -0
  75. code_graph_builder/tests/test_integration_semantic.py +434 -0
  76. code_graph_builder/tests/test_mcp_protocol.py +298 -0
  77. code_graph_builder/tests/test_mcp_user_flow.py +190 -0
  78. code_graph_builder/tests/test_rag.py +404 -0
  79. code_graph_builder/tests/test_settings.py +135 -0
  80. code_graph_builder/tests/test_step1_graph_build.py +264 -0
  81. code_graph_builder/tests/test_step2_api_docs.py +323 -0
  82. code_graph_builder/tests/test_step3_embedding.py +278 -0
  83. code_graph_builder/tests/test_vector_store.py +552 -0
  84. code_graph_builder/tools/__init__.py +40 -0
  85. code_graph_builder/tools/graph_query.py +495 -0
  86. code_graph_builder/tools/semantic_search.py +387 -0
  87. code_graph_builder/types.py +333 -0
  88. code_graph_builder/utils/__init__.py +0 -0
  89. code_graph_builder/utils/path_utils.py +30 -0
  90. code_graph_builder-0.2.0.dist-info/METADATA +321 -0
  91. code_graph_builder-0.2.0.dist-info/RECORD +93 -0
  92. code_graph_builder-0.2.0.dist-info/WHEEL +4 -0
  93. code_graph_builder-0.2.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,172 @@
1
+ # RAG + CAMEL 集成代码审查报告
2
+
3
+ ## 审查概述
4
+
5
+ **审查日期**: 2026-02-22
6
+ **审查模块**: `code_graph_builder/rag/`
7
+ **审查人**: QA Reviewer Agent
8
+
9
+ ## 文件清单
10
+
11
+ 1. `__init__.py` - 模块初始化
12
+ 2. `config.py` - 配置管理
13
+ 3. `client.py` - LLM API 客户端
14
+ 4. `prompt_templates.py` - 提示词模板
15
+ 5. `markdown_generator.py` - Markdown 生成器
16
+ 6. `rag_engine.py` - RAG 引擎
17
+ 7. `camel_agent.py` - CAMEL Agent 封装
18
+
19
+ ---
20
+
21
+ ## 审查结果
22
+
23
+ ### 1. 代码风格 (Code Style)
24
+
25
+ **状态**: 通过
26
+
27
+ **优点**:
28
+ - 遵循项目代码风格,使用 `from __future__ import annotations`
29
+ - 使用 dataclass 定义数据类
30
+ - 文档字符串完整,包含 Args/Returns/Examples
31
+ - 使用类型注解
32
+
33
+ **建议**:
34
+ - 所有文件都符合项目标准
35
+
36
+ ### 2. 类型注解 (Type Annotations)
37
+
38
+ **状态**: 通过
39
+
40
+ **优点**:
41
+ - 全面的类型注解
42
+ - 使用 `|` 语法 (Python 3.10+)
43
+ - 正确使用 `TYPE_CHECKING` 避免循环导入
44
+ - Protocol 定义清晰
45
+
46
+ ### 3. 错误处理 (Error Handling)
47
+
48
+ **状态**: 通过,有改进建议
49
+
50
+ **优点**:
51
+ - `client.py` 有完善的异常处理 (HTTPError, Timeout)
52
+ - 使用 try-except 包裹 API 调用
53
+ - 使用 loguru 记录错误日志
54
+
55
+ **建议改进**:
56
+ 1. `rag_engine.py` 第 527-530 行: 异常处理可以返回更友好的错误信息
57
+ 2. `camel_agent.py` 第 154-160 行: 已正确处理异常
58
+
59
+ ### 4. API Key 安全性
60
+
61
+ **状态**: 通过
62
+
63
+ **优点**:
64
+ - 使用环境变量加载 API key (`MOONSHOT_API_KEY`)
65
+ - `config.py` 第 51-52 行: `__post_init__` 从环境变量加载
66
+ - 不硬编码敏感信息
67
+
68
+ ### 5. 日志记录
69
+
70
+ **状态**: 通过
71
+
72
+ **优点**:
73
+ - 使用 `loguru` 进行日志记录
74
+ - 适当的日志级别 (info, debug, warning, error)
75
+ - 关键操作都有日志记录
76
+
77
+ ### 6. 代码结构
78
+
79
+ **状态**: 通过
80
+
81
+ **优点**:
82
+ - 模块化设计清晰
83
+ - 职责分离明确
84
+ - 工厂函数便于创建实例
85
+ - 与现有 code_graph_builder 功能集成良好
86
+
87
+ ---
88
+
89
+ ## 测试计划
90
+
91
+ ### 单元测试
92
+
93
+ 需要编写以下测试文件:
94
+
95
+ 1. `tests/test_rag_config.py` - 配置类测试
96
+ 2. `tests/test_client.py` - LLM 客户端测试 (mock API)
97
+ 3. `tests/test_prompt_templates.py` - 提示词模板测试
98
+ 4. `tests/test_markdown_generator.py` - Markdown 生成器测试
99
+ 5. `tests/test_rag_engine.py` - RAG 引擎测试
100
+ 6. `tests/test_camel_agent.py` - CAMEL Agent 测试
101
+
102
+ ### 集成测试
103
+
104
+ 使用 tinycc 代码库进行端到端测试:
105
+
106
+ 1. 构建 tinycc 代码图
107
+ 2. 执行语义搜索
108
+ 3. 验证 RAG 查询流程
109
+ 4. 验证 Markdown 输出
110
+
111
+ ---
112
+
113
+ ## 问题清单
114
+
115
+ ### 已发现问题
116
+
117
+ 1. **无重大问题**
118
+
119
+ ### 建议改进
120
+
121
+ 1. **文档完善**: 建议添加更多使用示例到 README
122
+ 2. **配置验证**: `config.py` 中的验证可以更加全面
123
+ 3. **测试覆盖**: 需要补充单元测试
124
+
125
+ ---
126
+
127
+ ## 测试执行
128
+
129
+ ### 基础导入测试
130
+
131
+ ```bash
132
+ python -c "from code_graph_builder.rag import RAGConfig, create_rag_engine; print('OK')"
133
+ # 结果: 通过
134
+ ```
135
+
136
+ ### 配置测试
137
+
138
+ ```bash
139
+ python -c "from code_graph_builder.rag.config import RAGConfig; c = RAGConfig.from_env(); print('OK')"
140
+ # 结果: 通过
141
+ ```
142
+
143
+ ### 单元测试
144
+
145
+ ```bash
146
+ pytest code_graph_builder/rag/tests/ -v
147
+ # 结果: 78 passed in 0.11s
148
+ ```
149
+
150
+ 测试覆盖:
151
+ - `test_config.py`: 17 tests - 配置类测试
152
+ - `test_prompt_templates.py`: 14 tests - 提示词模板测试
153
+ - `test_markdown_generator.py`: 18 tests - Markdown 生成器测试
154
+ - `test_client.py`: 14 tests - LLM 客户端测试 (含 mock)
155
+ - `test_camel_agent.py`: 15 tests - CAMEL Agent 测试
156
+
157
+ ---
158
+
159
+ ## 总结
160
+
161
+ **总体评价**: 通过
162
+
163
+ **代码质量**: 高
164
+
165
+ **测试状态**: 78/78 通过
166
+
167
+ **完成情况**:
168
+ 1. 单元测试 - 已完成 (78 tests)
169
+ 2. 集成测试 - 建议后续添加 (需要 tinycc 代码库)
170
+ 3. 文档 - 代码文档完整
171
+
172
+ 所有核心功能模块都已实现,代码风格符合项目标准,测试全部通过,可以合并到主分支。
@@ -0,0 +1,3 @@
1
+ """Tests for RAG module."""
2
+
3
+ from __future__ import annotations
@@ -0,0 +1,313 @@
1
+ """Tests for CAMEL agent."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from unittest.mock import Mock, patch
6
+
7
+ import pytest
8
+
9
+ from code_graph_builder.rag.camel_agent import (
10
+ CamelAgent,
11
+ CamelAgentResponse,
12
+ MultiAgentRAG,
13
+ create_camel_agent,
14
+ )
15
+ from code_graph_builder.rag.client import ChatResponse
16
+
17
+
18
+ class TestCamelAgentResponse:
19
+ """Tests for CamelAgentResponse."""
20
+
21
+ def test_creation(self):
22
+ """Test basic creation."""
23
+ response = CamelAgentResponse(
24
+ content="Test response",
25
+ metadata={"key": "value"},
26
+ role="Analyst",
27
+ )
28
+ assert response.content == "Test response"
29
+ assert response.metadata["key"] == "value"
30
+ assert response.role == "Analyst"
31
+
32
+ def test_default_role(self):
33
+ """Test default role."""
34
+ response = CamelAgentResponse(content="Test")
35
+ assert response.role == "agent"
36
+
37
+
38
+ class TestCamelAgent:
39
+ """Tests for CamelAgent."""
40
+
41
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
42
+ def test_init(self, mock_create_client):
43
+ """Test initialization."""
44
+ mock_client = Mock()
45
+ mock_create_client.return_value = mock_client
46
+
47
+ agent = CamelAgent(
48
+ role="Code Analyst",
49
+ goal="Analyze code",
50
+ backstory="Expert programmer",
51
+ )
52
+ assert agent.role == "Code Analyst"
53
+ assert agent.goal == "Analyze code"
54
+ assert agent.backstory == "Expert programmer"
55
+ assert "Code Analyst" in agent.system_prompt
56
+
57
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
58
+ def test_build_system_prompt(self, mock_create_client):
59
+ """Test system prompt building."""
60
+ mock_client = Mock()
61
+ mock_create_client.return_value = mock_client
62
+
63
+ agent = CamelAgent(
64
+ role="Tester",
65
+ goal="Test things",
66
+ backstory="Testing expert",
67
+ )
68
+ prompt = agent.system_prompt
69
+ assert "Tester" in prompt
70
+ assert "Test things" in prompt
71
+ assert "Testing expert" in prompt
72
+
73
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
74
+ def test_analyze(self, mock_create_client):
75
+ """Test analyze method."""
76
+ mock_client = Mock()
77
+ mock_client.chat_with_messages.return_value = ChatResponse(
78
+ content="Analysis result",
79
+ usage={},
80
+ model="kimi-k2.5",
81
+ finish_reason="stop",
82
+ )
83
+ mock_create_client.return_value = mock_client
84
+
85
+ agent = CamelAgent(
86
+ role="Analyst",
87
+ goal="Analyze",
88
+ backstory="Expert",
89
+ llm_client=mock_client,
90
+ )
91
+ response = agent.analyze("Review this code", code="def foo(): pass")
92
+
93
+ assert isinstance(response, CamelAgentResponse)
94
+ assert response.content == "Analysis result"
95
+ assert response.role == "Analyst"
96
+
97
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
98
+ def test_analyze_error(self, mock_create_client):
99
+ """Test analyze method with error."""
100
+ mock_client = Mock()
101
+ mock_client.chat_with_messages.side_effect = Exception("API error")
102
+ mock_create_client.return_value = mock_client
103
+
104
+ agent = CamelAgent(
105
+ role="Analyst",
106
+ goal="Analyze",
107
+ backstory="Expert",
108
+ llm_client=mock_client,
109
+ )
110
+ response = agent.analyze("Review this")
111
+
112
+ assert "Error" in response.content
113
+ assert "error" in response.metadata
114
+
115
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
116
+ def test_review_code_general(self, mock_create_client):
117
+ """Test general code review."""
118
+ mock_client = Mock()
119
+ mock_client.chat_with_messages.return_value = ChatResponse(
120
+ content="Review result",
121
+ usage={},
122
+ model="kimi-k2.5",
123
+ finish_reason="stop",
124
+ )
125
+ mock_create_client.return_value = mock_client
126
+
127
+ agent = CamelAgent(
128
+ role="Reviewer",
129
+ goal="Review code",
130
+ backstory="Code reviewer",
131
+ llm_client=mock_client,
132
+ )
133
+ response = agent.review_code("def foo(): pass", review_type="general")
134
+
135
+ assert isinstance(response, CamelAgentResponse)
136
+ mock_client.chat_with_messages.assert_called_once()
137
+
138
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
139
+ def test_review_code_security(self, mock_create_client):
140
+ """Test security code review."""
141
+ mock_client = Mock()
142
+ mock_client.chat_with_messages.return_value = ChatResponse(
143
+ content="Security review",
144
+ usage={},
145
+ model="kimi-k2.5",
146
+ finish_reason="stop",
147
+ )
148
+ mock_create_client.return_value = mock_client
149
+
150
+ agent = CamelAgent(
151
+ role="Security Expert",
152
+ goal="Find vulnerabilities",
153
+ backstory="Security specialist",
154
+ llm_client=mock_client,
155
+ )
156
+ response = agent.review_code("def foo(): pass", review_type="security")
157
+
158
+ assert isinstance(response, CamelAgentResponse)
159
+ call_args = mock_client.chat_with_messages.call_args
160
+ messages = call_args[0][0]
161
+ assert any("security" in msg["content"].lower() for msg in messages)
162
+
163
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
164
+ def test_explain_code_brief(self, mock_create_client):
165
+ """Test brief code explanation."""
166
+ mock_client = Mock()
167
+ mock_client.chat_with_messages.return_value = ChatResponse(
168
+ content="Brief explanation",
169
+ usage={},
170
+ model="kimi-k2.5",
171
+ finish_reason="stop",
172
+ )
173
+ mock_create_client.return_value = mock_client
174
+
175
+ agent = CamelAgent(
176
+ role="Explainer",
177
+ goal="Explain code",
178
+ backstory="Teacher",
179
+ llm_client=mock_client,
180
+ )
181
+ response = agent.explain_code("def foo(): pass", detail_level="brief")
182
+
183
+ assert isinstance(response, CamelAgentResponse)
184
+ call_args = mock_client.chat_with_messages.call_args
185
+ messages = call_args[0][0]
186
+ assert any("brief" in msg["content"].lower() for msg in messages)
187
+
188
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
189
+ def test_suggest_improvements(self, mock_create_client):
190
+ """Test improvement suggestions."""
191
+ mock_client = Mock()
192
+ mock_client.chat_with_messages.return_value = ChatResponse(
193
+ content="Suggestions",
194
+ usage={},
195
+ model="kimi-k2.5",
196
+ finish_reason="stop",
197
+ )
198
+ mock_create_client.return_value = mock_client
199
+
200
+ agent = CamelAgent(
201
+ role="Improver",
202
+ goal="Suggest improvements",
203
+ backstory="Optimizer",
204
+ llm_client=mock_client,
205
+ )
206
+ response = agent.suggest_improvements(
207
+ "def foo(): pass",
208
+ focus_areas=["readability", "performance"],
209
+ )
210
+
211
+ assert isinstance(response, CamelAgentResponse)
212
+ call_args = mock_client.chat_with_messages.call_args
213
+ messages = call_args[0][0]
214
+ assert any("readability" in msg["content"] for msg in messages)
215
+
216
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
217
+ def test_answer_question(self, mock_create_client):
218
+ """Test answering questions."""
219
+ mock_client = Mock()
220
+ mock_client.chat_with_messages.return_value = ChatResponse(
221
+ content="Answer",
222
+ usage={},
223
+ model="kimi-k2.5",
224
+ finish_reason="stop",
225
+ )
226
+ mock_create_client.return_value = mock_client
227
+
228
+ agent = CamelAgent(
229
+ role="Helper",
230
+ goal="Answer questions",
231
+ backstory="Assistant",
232
+ llm_client=mock_client,
233
+ )
234
+ response = agent.answer_question("What is this?", code_context="def foo(): pass")
235
+
236
+ assert isinstance(response, CamelAgentResponse)
237
+ assert response.content == "Answer"
238
+
239
+
240
+ class TestMultiAgentRAG:
241
+ """Tests for MultiAgentRAG."""
242
+
243
+ @patch("code_graph_builder.rag.camel_agent.CamelAgent")
244
+ def test_init(self, mock_agent_class):
245
+ """Test initialization."""
246
+ mock_rag_engine = Mock()
247
+ mock_agent_instance = Mock()
248
+ mock_agent_class.return_value = mock_agent_instance
249
+
250
+ multi_agent = MultiAgentRAG(mock_rag_engine)
251
+
252
+ assert multi_agent.rag_engine == mock_rag_engine
253
+ # Should create 4 agents
254
+ assert mock_agent_class.call_count == 4
255
+
256
+ @patch("code_graph_builder.rag.camel_agent.CamelAgent")
257
+ def test_analyze(self, mock_agent_class):
258
+ """Test multi-agent analysis."""
259
+ mock_rag_engine = Mock()
260
+ mock_rag_engine.query.return_value = Mock(
261
+ contexts=[Mock(format_context=Mock(return_value="context"))],
262
+ )
263
+
264
+ mock_agent = Mock()
265
+ mock_agent.analyze.return_value = CamelAgentResponse(content="Analysis")
266
+ mock_agent_class.return_value = mock_agent
267
+
268
+ multi_agent = MultiAgentRAG(mock_rag_engine)
269
+ results = multi_agent.analyze("Test query", analysis_types=["architecture"])
270
+
271
+ assert "architecture" in results
272
+ mock_rag_engine.query.assert_called_once_with("Test query")
273
+
274
+ @patch("code_graph_builder.rag.camel_agent.CamelAgent")
275
+ def test_comprehensive_review(self, mock_agent_class):
276
+ """Test comprehensive review."""
277
+ mock_rag_engine = Mock()
278
+ mock_rag_engine.explain_code.return_value = Mock(
279
+ contexts=[Mock(source_code="def foo(): pass")],
280
+ )
281
+
282
+ mock_agent = Mock()
283
+ mock_agent.analyze.return_value = CamelAgentResponse(content="Analysis")
284
+ mock_agent.review_code.return_value = CamelAgentResponse(content="Review")
285
+ mock_agent.explain_code.return_value = CamelAgentResponse(content="Explanation")
286
+ mock_agent_class.return_value = mock_agent
287
+
288
+ multi_agent = MultiAgentRAG(mock_rag_engine)
289
+ results = multi_agent.comprehensive_review("test.foo")
290
+
291
+ assert "architecture" in results
292
+ assert "security" in results
293
+ assert "performance" in results
294
+ assert "documentation" in results
295
+
296
+
297
+ class TestCreateCamelAgent:
298
+ """Tests for create_camel_agent factory function."""
299
+
300
+ @patch("code_graph_builder.rag.camel_agent.create_llm_client")
301
+ def test_create_agent(self, mock_create_client):
302
+ """Test creating agent."""
303
+ mock_client = Mock()
304
+ mock_create_client.return_value = mock_client
305
+
306
+ agent = create_camel_agent(
307
+ role="Tester",
308
+ goal="Test things",
309
+ backstory="Testing expert",
310
+ )
311
+
312
+ assert isinstance(agent, CamelAgent)
313
+ assert agent.role == "Tester"