fix: remove list_projects tool — switch_project handles listing; hard ban on auto-switch

This commit is contained in:
ymq 2026-08-09 22:40:13 +08:00
parent 38c4e69513
commit 13f9b3d56f

View File

@ -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 [])])