diff --git a/wwwroot/api/cockpit_chat.dspy b/wwwroot/api/cockpit_chat.dspy index 30fb53b..7ad2866 100644 --- a/wwwroot/api/cockpit_chat.dspy +++ b/wwwroot/api/cockpit_chat.dspy @@ -17,14 +17,12 @@ dbname = get_module_dbname('pipeline-sdlc') AGENT_PROMPT = """你是开发产线驾驶舱 Agent。用工具获取数据,用 reply 回复。 ## 核心原则 -- 环境信息中已显示当前项目。绝大多数操作在当前项目内完成,不要切换 -- 仅当用户明确说出不同的项目名时才切换(如"切换到 XXX 项目") -- list_projects 仅当用户要求"列出项目"或需要切换但不知道项目名时才调用 -- 不要主动 list_projects 或 switch_project +- 环境信息中已显示当前项目。所有操作在当前项目内完成,绝不切换 +- 仅当用户明确说"切换到 XXX 项目"才调用 switch_project +- 不要调用 switch_project 去"确认"或"查看"项目——环境信息已经告诉你了 ## 工作流 -- 项目操作:当前项目已在环境信息中。如果已在目标项目,直接操作,不需要切换 -- 切换项目:仅当需要切换时才 list_projects → switch_project +- 切换项目:用户说"切换到XXX" → switch_project("XXX")。不知道项目名 → switch_project(不传参数)看列表 - 创建项目:不存在则 create_project - 删除项目:delete_project → 看到确认提示后,用户回复「确认删除 xxx」→ 再调 _sys_delete_project - 查看进度:list_tasks / task_detail / list_deliverables @@ -43,8 +41,7 @@ AGENT_PROMPT = """你是开发产线驾驶舱 Agent。用工具获取数据, 环境: __ENV__""" TOOLS = [ - {"name":"list_projects","description":"列出所有可用项目","params":{}}, - {"name":"switch_project","description":"切换到指定项目(需先list_projects确认项目名)","params":{"project":"项目名称"}}, + {"name":"switch_project","description":"切换到指定项目。如果项目名不确定,不传project参数可返回可用项目列表","params":{"project":"项目名称(可选,不传列出可用项目)"}}, {"name":"create_project","description":"创建新项目","params":{"name":"项目名称","description":"项目描述(可选)"}}, {"name":"delete_project","description":"删除项目(返回确认提示,用户确认后再调用_sys_delete_project执行)","params":{"project":"项目名称"}}, {"name":"list_tasks","description":"列出当前项目任务","params":{"state":"状态(可选)"}}, @@ -142,20 +139,12 @@ 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 = {'list_projects':'列出项目','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':'执行命令'} +_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 {} try: - if tool == 'list_projects': - allp = await sor.sqlExe("SELECT id,name,description,workspace_dir FROM sd_projects ORDER BY created_at DESC LIMIT 30",{}) - if not allp: return '无项目' - lines = [] - for r in allp: - marker = '★' if getattr(r,'id','') == ctx['pid'] else ' ' - lines.append(f"{marker} {getattr(r,'name','')} | {getattr(r,'description','') or ''} | ws:{getattr(r,'workspace_dir','') or ''}") - return '\n'.join(lines) - elif tool == 'create_project': + if tool == 'create_project': name = (p.get('name','') or '').strip() if not name: return 'FAIL: 需要项目名称' ex = await sor.sqlExe("SELECT id FROM sd_projects WHERE name=${n}$",{"n":name}) @@ -201,7 +190,17 @@ async def _exec_tool(sor, tool, params, ctx, uid, org_id): ctx['pid'] = ''; ctx['pname'] = ''; ctx['ws'] = ''; ctx['repos'] = [] return f'OK: 已删除「{name}」及其所有关联数据' elif tool == 'switch_project': - proj = await _find_project(sor, p.get('project','')) + name = (p.get('project','') or '').strip() + if not name: + # No project specified — return available projects + allp = await sor.sqlExe("SELECT id,name FROM sd_projects ORDER BY created_at DESC LIMIT 20",{}) + if not allp: return '无可用项目' + lines = [] + for r in allp: + marker = '★' if getattr(r,'id','') == ctx['pid'] else ' ' + lines.append(f"{marker} {getattr(r,'name','')}") + return '可用项目:\n'+'\n'.join(lines) + proj = await _find_project(sor, name) if not proj: allp = await sor.sqlExe("SELECT name FROM sd_projects ORDER BY created_at DESC LIMIT 15",{}) return 'FAIL: 未找到。可用: '+', '.join([getattr(r,'name','') for r in (allp or [])])