pipeline-sdlc/wwwroot/api/cockpit_agent.dspy

126 lines
5.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# cockpit_agent.dspy — Agent control: start/stop, status, deliverables
# POST: action=start_agent | agent_status | list_deliverables | review_deliverable
import aiohttp
action = (params_kw or {}).get('action', 'agent_status')
dbname = get_module_dbname('pipeline-sdlc')
uid = await get_user()
org_id = await get_userorgid() or '0'
session_id = (params_kw or {}).get('session_id', '')
async def _get_context(sor, uid, session_id=''):
pid, iid = await get_session_context(sor, uid, session_id)
return {'project_id': pid, 'iteration_id': iid}
if action == 'start_agent':
async with DBPools().sqlorContext(dbname) as sor:
ctx = await _get_context(sor, uid, session_id)
pid = ctx['project_id']
if not pid:
return json.dumps({"success": False, "error": "请先选择项目"}, ensure_ascii=False)
model_id = (params_kw or {}).get('model_id', '')
role = (params_kw or {}).get('role', 'develop')
# model_id 兼容 id / vendor_model_id / 注册名 → 统一走模型治理模块解析
# pipeline_llm.selection.resolve_model_name唯一解析点不再各模块自查表
# capabilities='chat':角色 agent 只接受对话能力t2t/i2t/m2t2026-09-06
if model_id:
_resolved = await llm_resolve_model_name(model_id, org_id=org_id,
capabilities='chat')
if _resolved:
model_id = _resolved
# Ensure agent config exists
existing = await sor.sqlExe(
"SELECT id FROM pipeline_project_agents WHERE project_id=${pid}$ AND role_name=${role}$",
{"pid": pid, "role": role})
if not existing:
await sor.C('pipeline_project_agents', {
'id': getID(), 'project_id': pid, 'role_name': role,
'model_name': model_id, 'status': 'running'
})
else:
await sor.sqlExe(
"UPDATE pipeline_project_agents SET status='running', model_name=${mid}$ WHERE project_id=${pid}$ AND role_name=${role}$",
{"pid": pid, "role": role, "mid": model_id})
# Run one iteration synchronously
try:
result = await run_agent_loop(pid, role, model_id or None)
return json.dumps({"success": True, "result": result}, ensure_ascii=False)
except Exception as e:
return json.dumps({"success": False, "error": str(e)[:200]}, ensure_ascii=False)
elif action == 'agent_status':
async with DBPools().sqlorContext(dbname) as sor:
ctx = await _get_context(sor, uid, session_id)
pid = ctx['project_id']
agents = []
if pid:
recs = await sor.sqlExe(
"SELECT role_name, status, model_name FROM pipeline_project_agents WHERE project_id=${pid}$",
{"pid": pid})
agents = [{'role': getattr(r, 'role_name', ''), 'status': getattr(r, 'status', ''),
'model': getattr(r, 'model_name', '')} for r in recs]
# Recent deliverables
delivs = []
if pid:
drecs = await sor.sqlExe(
"SELECT id, title, deliverable_type, quality_score, review_status, created_by, created_at "
"FROM pipeline_deliverables WHERE project_id=${pid}$ ORDER BY created_at DESC LIMIT 10",
{"pid": pid})
delivs = [{'id': d.id, 'title': d.title, 'type': d.deliverable_type,
'score': d.quality_score, 'review': d.review_status,
'by': d.created_by, 'at': str(d.created_at)[:16]} for d in drecs]
return json.dumps({"success": True, "agents": agents, "deliverables": delivs,
"project_name": ctx.get('project_name', '')}, ensure_ascii=False)
elif action == 'list_deliverables':
async with DBPools().sqlorContext(dbname) as sor:
ctx = await _get_context(sor, uid, session_id)
pid = ctx['project_id']
if not pid:
return json.dumps([], ensure_ascii=False)
drecs = await sor.sqlExe(
"SELECT id, task_id, title, deliverable_type, quality_score, review_status, "
"LEFT(content,200) as preview, created_by, created_at "
"FROM pipeline_deliverables WHERE project_id=${pid}$ ORDER BY created_at DESC LIMIT 50",
{"pid": pid})
rows = []
for d in drecs:
rows.append({
'id': d.id, 'task_id': d.task_id, 'title': d.title,
'type': d.deliverable_type, 'score': d.quality_score,
'review': d.review_status, 'preview': getattr(d, 'preview', ''),
'by': d.created_by, 'at': str(d.created_at)[:16]
})
return json.dumps(rows, ensure_ascii=False)
elif action == 'review_deliverable':
did = (params_kw or {}).get('id', '')
status = (params_kw or {}).get('status', 'approved')
comment = (params_kw or {}).get('comment', '')
if not did:
return json.dumps({"success": False, "error": "缺少id"}, ensure_ascii=False)
async with DBPools().sqlorContext(dbname) as sor:
await sor.sqlExe(
"UPDATE pipeline_deliverables SET review_status=${st}$, reviewed_by=${uid}$, review_comment=${cm}$ WHERE id=${did}$",
{"st": status, "uid": uid, "cm": comment, "did": did})
return json.dumps({"success": True}, ensure_ascii=False)
else:
return json.dumps({"success": False, "error": f"Unknown action: {action}"}, ensure_ascii=False)