Skip to content

Commit d268c47

Browse files
author
Kiran
committed
尝试使用五阶段debug流程
1 parent 384e923 commit d268c47

File tree

8 files changed

+682
-138
lines changed

8 files changed

+682
-138
lines changed

apps/codexgraph_agent/pages/components/page.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def get_llm_config(llm_name):
2121

2222
llm_config = {
2323
'model': 'deepseek-coder',
24-
'api_base': 'https://api.deepseek.com',
24+
'api_base': 'https://jeniya.cn/v1',
2525
'model_server': 'openai'
2626
}
2727

apps/codexgraph_agent/setting.json

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"setting": {
33
"prompt_path": "apps/codexgraph_agent/prompt",
4-
"repo_path": "C:\\Users\\LENOVO\\Desktop\\testcode\\tinyhttpd-master",
4+
"repo_path": "C:\\Users\\34862\\Desktop\\test\\lrzip",
55
"llm_model_name": "deepseek-coder",
66
"llm_temperature": 1.0,
77
"max_iterations": 5,
@@ -10,19 +10,21 @@
1010
"code_comment",
1111
"code_debug",
1212
"code_generate",
13-
"code_unittest"
13+
"code_unittest",
14+
"111",
15+
"test"
1416
],
15-
"project_id": "code_chat",
17+
"project_id": "test",
1618
"env_path_dict": {
17-
"env_path": "F:\\python\\Anaconda\\envs\\mybuild\\python.exe",
18-
"working_directory": "C:\\Users\\LENOVO\\Desktop\\CodeXGraph\\ms-agent\\modelscope_agent\\environment\\graph_database\\indexer"
19+
"env_path": "D:\\Anaconda\\envs\\mybuild\\python.exe",
20+
"working_directory": "D:\\GitHub\\CodeXGraph\\ms-agent\\modelscope_agent\\environment\\graph_database\\indexer"
1921
},
2022
"neo4j": {
2123
"url": "bolt://localhost:7687",
2224
"user": "neo4j",
23-
"password": "GuoGuo0532",
25+
"password": "neo4j1231",
2426
"database_name": "neo4j"
2527
},
26-
"language": "Python"
28+
"language": "C"
2729
}
2830
}

modelscope_agent/agents/codexgraph_agent/task/code_debugger.py

Lines changed: 506 additions & 114 deletions
Large diffs are not rendered by default.

modelscope_agent/environment/graph_database/indexer/method_description_generator.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def _get_default_config(self) -> Dict[str, Any]:
6060
return {
6161
'model_name': setting_data.get('llm_model_name', 'deepseek-coder'),
6262
'api_key': os.getenv('OPENAI_API_KEY', 'sk-aabc879cff054d9fac7025eb491ef163'),
63-
'base_url': os.getenv('OPENAI_BASE_URL', 'https://api.deepseek.com'),
63+
'base_url': os.getenv('OPENAI_BASE_URL', 'https://jeniya.cn/v1'),
6464
'max_tokens': 200,
6565
'temperature': setting_data.get('llm_temperature', 0.3)
6666
}
@@ -71,7 +71,7 @@ def _get_default_config(self) -> Dict[str, Any]:
7171
return {
7272
'model_name': 'deepseek-coder', # 默认使用deepseek-coder
7373
'api_key': os.getenv('OPENAI_API_KEY', 'sk-aabc879cff054d9fac7025eb491ef163'),
74-
'base_url': os.getenv('OPENAI_BASE_URL', 'https://api.deepseek.com'),
74+
'base_url': os.getenv('OPENAI_BASE_URL', 'https://jeniya.cn/v1'),
7575
'max_tokens': 200,
7676
'temperature': 0.3
7777
}
@@ -154,11 +154,17 @@ def _build_prompt(self, method_code: str, method_name: str,
154154

155155
def _call_llm(self, prompt: str) -> str:
156156
"""调用大模型API"""
157+
# 检查是否有有效的API key
158+
api_key = self.llm_config.get('api_key', '').strip()
159+
if not api_key or api_key == 'sk-aabc879cff054d9fac7025eb491ef163':
160+
print(f"警告: 未配置有效的API Key,自动使用模拟描述生成")
161+
return self._generate_mock_description(prompt)
162+
157163
try:
158164
print(f"尝试调用LLM API...")
159165
print(f"模型: {self.llm_config['model_name']}")
160166
print(f"API Base: {self.llm_config['base_url']}")
161-
print(f"API Key: {self.llm_config['api_key'][:10]}..." if self.llm_config['api_key'] else "无API Key")
167+
print(f"API Key: {api_key[:10]}...")
162168

163169
# 使用统一的LLM调用方式,兼容不同的API
164170
from modelscope_agent.llm import get_chat_model
@@ -167,7 +173,7 @@ def _call_llm(self, prompt: str) -> str:
167173
llm_config = {
168174
'model': self.llm_config['model_name'],
169175
'api_base': self.llm_config['base_url'],
170-
'api_key': self.llm_config['api_key'],
176+
'api_key': api_key,
171177
'model_server': 'openai'
172178
}
173179

@@ -177,7 +183,7 @@ def _call_llm(self, prompt: str) -> str:
177183
llm = get_chat_model(
178184
model=self.llm_config['model_name'],
179185
model_server='openai',
180-
api_key=self.llm_config['api_key'],
186+
api_key=api_key,
181187
api_base=self.llm_config['base_url']
182188
)
183189
print(f"LLM实例创建成功: {type(llm)}")
@@ -201,11 +207,18 @@ def _call_llm(self, prompt: str) -> str:
201207
print(f"警告: 未安装相关库,使用模拟描述: {e}")
202208
return self._generate_mock_description(prompt)
203209
except Exception as e:
204-
print(f"调用大模型API失败: {e}")
205-
import traceback
206-
traceback.print_exc()
207-
# 返回包含错误信息的描述
208-
return f"LLM调用失败: {str(e)}"
210+
error_str = str(e)
211+
# 检查是否是认证错误
212+
if 'Authentication' in error_str or '401' in error_str or 'Unauthorized' in error_str:
213+
print(f"警告: API认证失败,自动降级到模拟描述生成。错误: {error_str}")
214+
return self._generate_mock_description(prompt)
215+
else:
216+
print(f"调用大模型API失败: {e}")
217+
import traceback
218+
traceback.print_exc()
219+
# 对于其他错误,也使用模拟描述而不是返回错误信息
220+
print(f"自动使用模拟描述作为备选方案")
221+
return self._generate_mock_description(prompt)
209222

210223
def _generate_mock_description(self, prompt: str) -> str:
211224
"""生成模拟描述(用于测试)"""

modelscope_agent/llm/openai.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def __init__(
4444
)
4545
else:
4646
default_api_base = os.getenv('OPENAI_API_BASE',
47-
'https://api.openai.com/v1')
47+
'https://jeniya.cn/v1')
4848
api_base = kwargs.get('api_base', default_api_base).strip()
4949
api_key = kwargs.get('api_key',
5050
os.getenv('OPENAI_API_KEY',

replace/ast_visitor_client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ def get_kind_priority(kind_str):
315315
node_parms['signature'] = self.symbol_data[full_name]['signature']
316316
if 'code' in self.symbol_data[full_name]:
317317
node_parms['code'] = self.symbol_data[full_name]['code']
318+
# Include return_type and parameters if they exist in data
319+
if 'return_type' in data:
320+
node_parms['return_type'] = data['return_type']
321+
if 'parameters' in data:
322+
node_parms['parameters'] = data['parameters']
318323

319324
self.graphDB.add_node(label=kind, full_name=full_name, parms=node_parms)
320325

replace/c_ast_traverser.py

Lines changed: 136 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,109 @@ def extract_function_name_from_call(function_node: Node):
170170
return None
171171

172172

173+
def extract_function_return_type(function_node: Node):
174+
"""
175+
从函数定义或声明节点中提取返回类型。
176+
函数定义的结构:type declarator body
177+
函数声明的结构:type declarator;
178+
"""
179+
if not function_node:
180+
return None
181+
182+
# 支持 function_definition 和 declaration 两种节点类型
183+
if function_node.type not in ['function_definition', 'declaration']:
184+
return None
185+
186+
type_node = function_node.child_by_field_name('type')
187+
if not type_node:
188+
return 'void' # 默认返回类型
189+
190+
# 提取类型文本
191+
return_type_text = type_node.text.decode('utf8', errors='ignore').strip()
192+
return return_type_text if return_type_text else 'void'
193+
194+
195+
def extract_function_parameters(function_node: Node):
196+
"""
197+
从函数定义节点中提取参数列表。
198+
返回参数列表的字符串表示,格式如: "int a, char *b, void"
199+
"""
200+
if not function_node:
201+
return []
202+
203+
# 获取 declarator
204+
declarator = None
205+
if function_node.type == 'function_definition':
206+
declarator = function_node.child_by_field_name('declarator')
207+
elif function_node.type == 'declaration':
208+
declarator = function_node.child_by_field_name('declarator')
209+
210+
if not declarator:
211+
return []
212+
213+
# 查找 function_declarator
214+
def find_function_declarator(n, depth=0, max_depth=10):
215+
"""递归查找 function_declarator 节点"""
216+
if depth > max_depth:
217+
return None
218+
if n.type == 'function_declarator':
219+
return n
220+
for child in n.children:
221+
result = find_function_declarator(child, depth + 1, max_depth)
222+
if result:
223+
return result
224+
return None
225+
226+
func_declarator = find_function_declarator(declarator)
227+
if not func_declarator:
228+
return []
229+
230+
# 获取 parameter_list
231+
param_list = func_declarator.child_by_field_name('parameters')
232+
if not param_list:
233+
return []
234+
235+
# 提取参数
236+
parameters = []
237+
for child in param_list.children:
238+
if child.type == 'parameter_declaration':
239+
# 提取参数类型和名称
240+
param_type_node = child.child_by_field_name('type')
241+
param_declarator = child.child_by_field_name('declarator')
242+
243+
param_type = param_type_node.text.decode('utf8', errors='ignore').strip() if param_type_node else ''
244+
245+
# 提取参数名
246+
param_name = None
247+
if param_declarator:
248+
# 查找 identifier
249+
def find_identifier_in_declarator(n, depth=0, max_depth=5):
250+
if depth > max_depth:
251+
return None
252+
if n.type == 'identifier':
253+
return n.text.decode('utf8', errors='ignore')
254+
for c in n.children:
255+
result = find_identifier_in_declarator(c, depth + 1, max_depth)
256+
if result:
257+
return result
258+
return None
259+
260+
param_name = find_identifier_in_declarator(param_declarator)
261+
262+
# 构建参数字符串
263+
if param_name:
264+
param_str = f"{param_type} {param_name}".strip()
265+
else:
266+
param_str = param_type if param_type else 'void'
267+
268+
if param_str:
269+
parameters.append(param_str)
270+
elif child.type == 'variadic_parameter':
271+
parameters.append('...')
272+
273+
return parameters
274+
275+
173276
def traverse_c_ast_and_record(client: AstVisitorClient, file_path: str):
174277
"""
175278
解析 C 代码文件并使用 Tree-sitter 的 cursor 进行深度优先遍历,
@@ -264,6 +367,10 @@ def find_identifier_in_node(n, depth=0, max_depth=10):
264367
# 直接记录整个函数定义(包含签名和函数体)到 code 属性
265368
func_text = node.text.decode('utf8', errors='ignore')
266369

370+
# 提取返回类型和参数列表
371+
return_type = extract_function_return_type(node)
372+
parameters = extract_function_parameters(node)
373+
267374
name_hierarchy = NameHierarchy(func_name_short, client.current_context_name())
268375
symbol_id = client.recordSymbol(
269376
name_hierarchy,
@@ -275,11 +382,16 @@ def find_identifier_in_node(n, depth=0, max_depth=10):
275382
full_name = client.symbolId_to_Name[symbol_id]
276383
client.symbol_data[full_name]['code'] = func_text
277384

278-
# 标记为用户自定义函数并创建图节点
385+
# 标记为用户自定义函数并创建图节点,包含返回类型和参数列表
386+
attributes = {
387+
'category': FunctionCategory.USER_DEFINED.value,
388+
'return_type': return_type,
389+
'parameters': parameters
390+
}
279391
client.recordSymbolKind(
280392
symbol_id,
281393
srctrl.SymbolKind.FUNCTION,
282-
{'category': FunctionCategory.USER_DEFINED.value}
394+
attributes
283395
)
284396

285397
# 将作用域范围记录为整个函数(含签名),确保 code 包含签名
@@ -353,6 +465,10 @@ def has_function_body(n, depth=0, max_depth=10):
353465
# 提取完整的函数定义文本(包括返回类型、函数名、参数列表和函数体)
354466
func_text = node.text.decode('utf8', errors='ignore')
355467

468+
# 提取返回类型和参数列表
469+
return_type = extract_function_return_type(node)
470+
parameters = extract_function_parameters(node)
471+
356472
name_hierarchy = NameHierarchy(func_name_short, client.current_context_name())
357473
symbol_id = client.recordSymbol(name_hierarchy, node_path=file_path, tree_node=node, kind_hint=symbolKindToString(srctrl.SymbolKind.FUNCTION)) # <--- 修改
358474

@@ -377,7 +493,14 @@ def has_function_body(n, depth=0, max_depth=10):
377493
signature_text = func_text
378494

379495
client.symbol_data[full_name]['signature'] = signature_text
380-
client.recordSymbolKind(symbol_id, srctrl.SymbolKind.FUNCTION) # <--- 修改
496+
497+
# 创建属性字典,包含返回类型和参数列表
498+
attributes = {
499+
'signature': signature_text,
500+
'return_type': return_type,
501+
'parameters': parameters
502+
}
503+
client.recordSymbolKind(symbol_id, srctrl.SymbolKind.FUNCTION, attributes) # <--- 修改
381504

382505
# 记录函数的作用域位置
383506
client.recordSymbolScopeLocation(symbol_id, source_range)
@@ -393,14 +516,23 @@ def has_function_body(n, depth=0, max_depth=10):
393516
# 提取完整的函数声明文本(包括返回类型、函数名、参数列表)
394517
declaration_text = node.text.decode('utf8', errors='ignore')
395518

519+
# 提取返回类型和参数列表
520+
return_type = extract_function_return_type(node)
521+
parameters = extract_function_parameters(node)
522+
396523
name_hierarchy = NameHierarchy(func_name_short, client.current_context_name())
397524
symbol_id = client.recordSymbol(name_hierarchy, node_path=file_path, tree_node=node, kind_hint=symbolKindToString(srctrl.SymbolKind.FUNCTION_DECLARATION)) # <--- 修改
398525

399526
# 将完整的函数声明文本存储到 code 属性
400527
full_name = client.symbolId_to_Name[symbol_id]
401528
client.symbol_data[full_name]['code'] = declaration_text
402529

403-
client.recordSymbolKind(symbol_id, srctrl.SymbolKind.FUNCTION_DECLARATION) # <--- 修改
530+
# 创建属性字典,包含返回类型和参数列表
531+
attributes = {
532+
'return_type': return_type,
533+
'parameters': parameters
534+
}
535+
client.recordSymbolKind(symbol_id, srctrl.SymbolKind.FUNCTION_DECLARATION, attributes) # <--- 修改
404536
# print(f" [CLIENT] Recorded FUNCTION_DECLARATION: {client.symbolId_to_Name[symbol_id]} in {file_name}")
405537

406538
elif declarator.type == 'init_declarator' or declarator.type == 'declarator': # 变量声明 (可能带初始化)

scripts/request.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"llm_config": {
88
"model": "deepseek-coder",
99
"model_server": "openai",
10-
"api_base": "https://api.deepseek.com",
10+
"api_base": "https://jeniya.cn/v1",
1111
"api_key": "sk-d6462958a57b4922ac0974c6521809d9",
1212
"generate_config": {
1313
"temperature": 0.2

0 commit comments

Comments
 (0)