Files
xiaoqu_mcp_service/xiaoqu-agent-service/AGENTS.md
T

5.1 KiB
Raw Blame History

xiaoqu-agent-service 项目指引

ai-proj 关联信息

  • ai-proj 项目 ID:224(项目名 xiaoqu_agent_service)。本仓所有需求/任务创建后应挂到该项目,关联任务前确保任务也在项目 224。
  • 近期需求示例:REQ-20260924-0009(id 5806,人流量统计工具+统计类限一个月,implementation 完成)→ 任务 22405;REQ-20260924-0003(id 5800,设备生命周期查询工具,implementation 完成)→ 任务 22391;REQ-20260921-0007(id 5778,设备电量消息查询工具,released)→ 任务 22306;REQ-20260919-0003(id 5747,出入库工具复查修复,released)→ 任务 22123。

ai-proj MCP 已知限制与真实契约

  • MCP update_requirement 不支持改 project_id/owner;改归属必须走 REST 两步:
    1. POST /api/v1/requirements/{id}/reassignment/preflight,body={operation_id:"<uuid>", expected_version:<当前sync_version>, target_project_id:224, target_owner_id?/clear_owner?}
    2. POST /api/v1/requirements/{id}/reassignment/confirm,body={operation_id, preflight_token}(两个字段缺一不可;preflight_token 一次性,confirm 失败即作废,必须在同一条命令里 preflight+confirm 原子执行)
  • REST base 推导:mcp.json 里 ai-proj 的 url 去掉尾部 /mcp/sse(即 https://ai.pipexerp.com/api/v1),认证头 X-API-Key 同 mcp.json。
  • ⚠️ 本机 shell(Bash 工具)直读 ~/.kimi-code/mcp.json 会被托管层拦截("local Shell bypass is disabled for a managed MCP route");用 Read 工具读取不受限。
  • 任务跨项目用 move_task,再 link_tasks_to_requirement(role=implementation)。
  • REST 建需求/任务实测(2026-09-24):POST /requirements 与 POST /tasks 的 body 带 project_id:224 会创建失败/被忽略,先裸建再走 reassignment;关联用 POST /requirements/{id}/tasks body={task_id, role:"implementation"};更新用 PUT /requirements/{id}(不支持 PATCH),delivery_stage/reviewer_id 为只读(PUT 静默忽略);POST /requirements/{id}/submit 可推进 draft→pending 并自动分配评审人,POST /requirements/{id}/review 仅评审人可调用;released 由 CLI sync 或评审/界面流转。
  • 本机无 ai-proj CLI,远程同步需在有 CLI 的机器执行 ai-proj sync requirement --id <id> --direction to_remote。

生产 ES 集群关键坑

  • 生产两个 ES 集群(cloud/local,app.es.cloud/local.*)均为 ES 7.7.1:elasticsearch-java 7.17 高阶客户端(ElasticsearchClient)的 vendor Content-Type(application/vnd.elasticsearch+json; compatible-with=7)被 406 拒绝,且其 X-Elastic-Product 响应头校验(7.14 才引入)过不了——业务 ES 查询一律注入低阶 esCloudRestClient/esLocalRestClient(RestClient)bean,不要注入 esCloudClient/esLocalClient(EsClientConfig 里仅为兼容保留)。
  • 低阶 org.elasticsearch.client.Response 构造器包私有且参数是 HttpResponse,测试里用 mock(Response.class) + stub getEntity() 构造;注意 thenReturn(esResponse(...)) 里嵌套 when() 会触发 UnfinishedStubbingException,必须先创建好 Response 再 stub。
  • electricitymessage 索引(电量消息类):createTime 是 date 类型(format strict_date_optional_time||epoch_millis),range 必须发 epoch 毫秒(yyyy-MM-dd HH:mm:ss 字符串 400);_source 里 value 是文本("28"/"100")、createTime 是 ISO 文本(2026-09-21T10:00:00.000+08:00),读取时都要归一。老系统能跑是因为 transport 客户端把 Date 序列化成 epoch 毫秒、Jackson 把字符串 value 反序列化进 Integer 字段。
  • paperuselog 索引(换纸日志):rfid 是 text 类型(mapping 有 ignore_above=256 的 keyword 子字段),terms 聚合必须用 rfid.keyword,直接聚合 text 字段被 7.7.1 以 400 "Text fields are not optimised for aggregations" 拒绝(2026-09-22 生产实测修复);老系统不做 ES 聚合,而是翻页拉全量文档后在 Java 侧按 P_{positionsId}_{snCode}_{rfid}/T_{toiletId}_{snCode}_{rfid} 复合 key 去重,MCP 用 terms 聚合近似(语义差异见设计文档)。
  • curl 直连 MCP 冒烟:JSON body 务必 -d @file(行内 -d 长 JSON 经网关会被截断报 "Invalid message format");响应是 SSE,sed -n 's/^data://p' 取 JSON。
  • 托管 MCP 工具(mcp__xiaoqu__*)在服务重启后 session 失效会报 AI_PROJ_MCP_SEND_OUTCOME_UNKNOWN,改走上面 curl 直连即可。

生产部署要点

  • ./deploy/deploy.sh remote-deploy(SSH 别名 xiaoqu-prd,目录 /data/xiaoqu-agent-service)。
  • 部署前必须先把 main 推 origin:出现过本地 main 领先 origin 1 个修复提交、他人从 origin 构建部署导致生产跑到旧代码的情况(2026-09-22 paperuselog terms 结构 400)。
  • 新工具上线后必须幂等绑 prod scope(svc 库 MySQL,tool 表唯一标识列是 name;scope 表是 agent_scope):hardware/district 系列惯例绑 scope 1(test)/2(operation)/3(xiaoqu-ai)/5(ops-query),工单/仓库系列只绑 scope 1。
  • prod AK 的 Authorization 头值本身已含 "Bearer " 前缀,不要再拼。