ymq 6f72e777da fix(agent): 角色 agent 实例 id——created_by 存真实 id 不再拼字符串
- pipeline_agent_instances 表(项目×角色→稳定实例 ag.xxxx), 幂等注册
- agent/pm/qc 三 poller 派单改用实例 id(原 poller-{role} 拼接, 33字符撞32列宽→1406)
- DDL: 新表 + pipeline_deliverables.created_by 加宽64兜底
2026-09-01 09:26:46 +08:00

74 lines
3.1 KiB
Python
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.

# -*- coding: utf-8 -*-
"""角色 agent 实例注册2026-09-01项目 × 角色 → 稳定实例 id。
背景poller 派单时 agent_id 是 `poller-{role}` 拼出来的字符串——
1. 不是身份,审计/落库查不到「哪个 agent 实例干的」;
2. `poller-agent.bid_writer_technical` 达 33 字符,超过
pipeline_deliverables.created_by varchar(32) → 1406 连环失败,
技术章节交付件全部落不了库(商务写者恰好 32 字符没事)。
规则(角色规范名约定:处理方 = role + agentid
- 每个项目 × 角色第一次派单时注册一个实例id 形如 `ag.{12位}`15 字符,
任何 32 宽字段都放得下),此后复用;
- `created_by`/审计 `agent_id` 一律存实例 id
- pm/qc poller 同走此解析(角色 agent.pm / agent.qc
"""
import logging
logger = logging.getLogger("pipeline.agent_instance")
async def resolve_agent_instance(project_id, role):
"""解析(必要时注册)项目 × 角色的 agent 实例 id。幂等。
失败兜底返回 `agent.{role}`规范角色名≤32 字符),保证调用方不炸。
"""
role = (role or "").strip()
if not role:
return ""
fallback = ("agent." + role) if not role.startswith("agent.") else role
try:
from sqlor.dbpools import DBPools
from appPublic.uniqueID import getID
db = DBPools()
async with db.sqlorContext("pipeline") as sor:
recs = await sor.sqlExe(
"SELECT agent_id FROM pipeline_agent_instances "
"WHERE project_id=${p}$ AND role=${r}$ AND status='active' LIMIT 1",
{"p": project_id or "", "r": role})
await sor.sqlExe("COMMIT", {})
if recs:
aid = getattr(recs[0], "agent_id", "") or ""
if aid:
return aid
aid = "ag." + getID()[:12]
await sor.C("pipeline_agent_instances", {
"id": getID(),
"project_id": project_id or "",
"role": role,
"agent_id": aid,
"status": "active",
})
await sor.sqlExe("COMMIT", {})
logger.info("agent instance registered: project=%s role=%s id=%s",
project_id, role, aid)
return aid
except Exception as e:
# 并发注册撞唯一键 → 重查一次;仍失败用规范角色名兜底
try:
from sqlor.dbpools import DBPools
db = DBPools()
async with db.sqlorContext("pipeline") as sor:
recs = await sor.sqlExe(
"SELECT agent_id FROM pipeline_agent_instances "
"WHERE project_id=${p}$ AND role=${r}$ AND status='active' LIMIT 1",
{"p": project_id or "", "r": role})
await sor.sqlExe("COMMIT", {})
if recs and (getattr(recs[0], "agent_id", "") or ""):
return recs[0].agent_id
except Exception:
pass
logger.warning("resolve_agent_instance fallback role=%s err=%s", role, str(e)[:120])
return fallback[:32]