diff --git a/wwwroot/api/cockpit_chat.dspy b/wwwroot/api/cockpit_chat.dspy index 3f87d48..d29db7f 100644 --- a/wwwroot/api/cockpit_chat.dspy +++ b/wwwroot/api/cockpit_chat.dspy @@ -18,11 +18,10 @@ AGENT_PROMPT = """你是开发产线驾驶舱 Agent。用工具获取数据, ## 核心原则 - 环境信息中已显示当前项目。所有操作在当前项目内完成 -- 项目切换由系统自动处理,你不需要也不能切换项目 -- 如果用户问"有哪些项目",直接根据环境信息回答,不需要调用任何工具 +- 如果用户没提其他项目名,不要切换项目 ## 工作流 -- 创建项目:不存在则 create_project +- 切换项目:用户说"切换到XXX项目" → switch_project - 删除项目:delete_project → 看到确认提示后,用户回复「确认删除 xxx」→ 再调 _sys_delete_project - 查看进度:list_tasks / task_detail / list_deliverables - 提交任务:先确保在正确项目,再 create_task @@ -40,6 +39,7 @@ AGENT_PROMPT = """你是开发产线驾驶舱 Agent。用工具获取数据, 环境: __ENV__""" TOOLS = [ + {"name":"switch_project","description":"切换到指定项目","params":{"project":"项目名称"}}, {"name":"create_project","description":"创建新项目","params":{"name":"项目名称","description":"项目描述(可选)"}}, {"name":"delete_project","description":"删除项目(返回确认提示,用户确认后再调用_sys_delete_project执行)","params":{"project":"项目名称"}}, {"name":"list_tasks","description":"列出当前项目任务","params":{"state":"状态(可选)"}}, @@ -143,7 +143,7 @@ def _w_card(title, body, kind="success"): ]} def _w_progress(text): return {"widgettype":"Text","options":{"text":text,"style":{"color":"#f59e0b","fontSize":"12px","padding":"2px 8px"},"halign":"left"}} -_tool_labels = {'create_project':'创建项目','delete_project':'删除项目','list_tasks':'查询任务','task_detail':'任务详情','list_deliverables':'查看交付件','view_deliverable':'交付件内容','list_questions':'查看问题','answer_question':'回答问题','create_task':'创建任务','start_agents':'启动角色Agent','diagnose_project':'项目诊断','check_progress':'检查进度','add_repo':'关联仓库','list_repos':'查看仓库','clone_repo':'克隆仓库','add_bug':'报告Bug','run_command':'执行命令'} +_tool_labels = {'switch_project':'切换项目','create_project':'创建项目','delete_project':'删除项目','list_tasks':'查询任务','task_detail':'任务详情','list_deliverables':'查看交付件','view_deliverable':'交付件内容','list_questions':'查看问题','answer_question':'回答问题','create_task':'创建任务','start_agents':'启动角色Agent','diagnose_project':'项目诊断','check_progress':'检查进度','add_repo':'关联仓库','list_repos':'查看仓库','clone_repo':'克隆仓库','add_bug':'报告Bug','run_command':'执行命令'} async def _exec_tool(sor, tool, params, ctx, uid, org_id): p = params or {} @@ -445,23 +445,16 @@ if action == 'send_message': return repos_str = ', '.join([r['n'] for r in ctx['repos']]) or '无' - # Pre-processing: detect switch request and execute before LLM runs - import re as _re - switch_m = _re.search(r'切换到\s*(.+)', message_text) - if switch_m: - target = switch_m.group(1).strip().rstrip('项目') - proj = await _find_project(sor, target) - if proj and proj.id != ctx['pid']: - await _save_ctx(sor, uid, proj.id) - ctx['pid'] = proj.id; ctx['pname'] = proj.name - repos = await sor.sqlExe("SELECT repo_name,repo_url FROM sd_project_repos WHERE project_id=${p}$",{"p":proj.id}) - ctx['repos'] = [{'n':r.repo_name,'u':r.repo_url} for r in (repos or [])] - repos_str = ', '.join([r['n'] for r in ctx['repos']]) or '无' env_text = f"【当前项目: {ctx['pname'] or '未选择'}】— 所有操作在当前项目内完成\n工作空间: {ctx['ws'] or '未设置'} | 仓库: {repos_str}" system = AGENT_PROMPT.replace('__TOOLS__',TOOLS_TEXT).replace('__ENV__',env_text) msgs = [{"role":"system","content":system}] for h in (await sor.sqlExe("SELECT role,content FROM pipeline_conversations WHERE created_by=${u}$ ORDER BY created_at ASC LIMIT 20",{"u":uid}) or []): - msgs.append({"role":'user' if getattr(h,'role','')=='user' else 'assistant',"content":getattr(h,'content','')}) + c = getattr(h,'content','') or '' + r = getattr(h,'role','') or '' + # Skip raw tool_call JSON — prevents LLM from mimicking old tool calls + if c.startswith('{"action":"tool_call"') or c.startswith('{"action": "tool_call"'): + continue + msgs.append({"role":'user' if r=='user' else 'assistant',"content":c}) msgs.append({"role":"user","content":message_text}) await sor.C('pipeline_conversations',{'id':getID(),'role':'user','content':message_text,'msg_type':'text','org_id':org_id,'created_by':uid}) @@ -490,7 +483,7 @@ if action == 'send_message': d = json.dumps(_w_card(label, _w_text(result), "success" if ok else "error"), ensure_ascii=False)+'\n' debug(f"YIELD result: {d[:60]}") yield d - msgs.append({"role":"assistant","content":raw}) + msgs.append({"role":"assistant","content":f"已调用 {tool}"}) msgs.append({"role":"user","content":f"工具 {tool} 结果:\n{result}"}) continue agent_reply = raw; break