366 Commits

Author SHA1 Message Date
ymq
88a361a50e fix(agent): 交付件类型守卫+本体文件清单——deliverable_type照抄示例值零校验(pbls需求交付被标design_doc),RoleSpec.deliverable_types声明合法清单,deliver拦截校验(native+文本双路径)非法拒绝回填清单,唯一合法类型缺省自动填充;交付件快照文件名清洗(getID '-'开头难用);新增files_json本体文件清单列(write_file实写+deliver files),PM/QC审核输入随附清单+强制read_file本体核对(只看6000字摘要索引误判产出规模) 2026-09-15 00:11:56 +08:00
ymq
7f3ce26295 fix(agent): 任务族工具被capability路由劫持FAIL + LLM超时误判永久错误致任务链暂停
pbls 项目事故(2026-09-14)四条根因一次修复:
- v2 _execute_tool 1.5步加 TOOL_SCHEMAS 双守卫(对齐 v1 _exec_agent_tool):
  task 技能 frontmatter 声明的任务状态机工具(reset_task_retry/claim_task/
  approve_task等)不在概念工具 schema 表,此前被劫持返回 FAIL:未注册的能力工具,
  能力包真实 handler(第2步)永远到不了——主 agent 无法恢复失败任务
- llm_bridge 如实区分超时/连接失败: TimeoutError(str为空)不再误报
  「端点不可达:。」(冒号后空白),超时文案明确瞬时故障可重试
- _classify_failure 补中文提示词(超时/不可达/瞬时等): 中文报错不再
  误判永久错误跳过重试直接 pause_project+fault_report
- role_agent_run 客户端单次调用超时缺省330→570(_LLM_CLIENT_TIMEOUT),
  与外层600硬超时衔接;实测368s长生成不再被提前掐断
- fault_report 文案区分「重试耗尽」与「判定永久错误(未触发自动重试)」,
  消除 retry_count=0 却报「重复0次已达上限(3)」的自相矛盾
2026-09-14 20:20:12 +08:00
ymq
1febcd3acb feat(sdlc): PM编排与主agent场景说明对齐新职责划分——模块划分requirement初划(八原则四张图)+design定稿,所有角色交付件必附复杂度评估,PM审核/派发必读评估段据此编排,缺失按退回意见要求补充 2026-09-14 17:11:29 +08:00
ymq
c32ceaa920 fix(rag_client): params读写列不一致致重复行——_load_cached_key按id查但写入id=getID()随机值,缓存永远miss→每次发key新增一行(实测user-01堆12行);ON DUPLICATE KEY UPDATE因params_name无唯一索引永不触发。修:读改按params_name+读-改-写幂等(存在则更新首行删多余行) 2026-09-12 08:04:17 +08:00
ymq
78c89a0cce feat(rag_client): 新增 rag_embed_texts 批量向量化通道——调 rag /api/embed.dspy,按10条分块,任一块失败整体失败带块号(挖掘批次状态机需可行动报错,禁部分成功静默丢数据) 2026-09-11 22:12:58 +08:00
ymq
1b1f8dfa52 feat(service): SDLC menus删旧「📁 项目」项——入口上移core agent_menus.dspy硬编码(新建/切换弹窗,所有产线通用),防重复出现两个项目按钮 2026-09-11 18:29:30 +08:00
ymq
0964dd2864 fix(agent): 跨上游超时窗调参——主调用单次超时330s→180s(实测最长响应<60s留3倍余量,失败快速返回);会话级重试2→3次+退避15s(3×180+2×15≈9.5分钟跨度可跨分钟级超时窗);llm_call_msgs_native补timeout参数透传_http_chat;回退文本路径同接180s 2026-09-11 16:39:50 +08:00
ymq
458736d71e fix(agent): 续跑门禁——已有工作推进(tool_call_count>0)时纯文本短回复(<400字)视为中途意图句而非最终答案,注入续跑指令继续循环(上限2次防死循环);根治商机产线实测连续4会话在7~11次工具调用后模型输出意图句提前结束turn→循环误判终止→报告/总结从未产出 2026-09-11 16:18:58 +08:00
ymq
5c063ca588 feat(bridge): session_id会话粘性透传(2026-09-11用户定夺:同会话固定账号省上游缓存钱,跨会话轮询)——llm_bridge四函数(llm_call/llm_call_msgs/llm_call_msgs_native/llm_infer)加session_id参数经payload._session_id透传(不进token缓存键);agent_loop_v2七处调用点接self.session_id(主循环native+降级重试+文本回退/技能选择/项目匹配/历史摘要/invoke_model);agent_loop v1四处任务循环用task:{task_id}做粘性键(任务内30轮同前缀);platform_model_tools.tool_invoke_model透传 2026-09-11 15:30:30 +08:00
ymq
58853de72d fix(bridge): project_id透传补全——proxy_chat_completion委托chat_inference带token绑定的project_id;bug_flow的PM确认调用带project_id落流水(配套pipeline-llm 427cd7c,2026-09-10遗留) 2026-09-11 15:30:30 +08:00
ymq
2e05029568 fix(agent): 会话健壮性三修——①收尾门禁(_WRAP_UP_RESERVE=3,轮次将尽注入立即收尾指令,根治长任务撞穿max_turns静默退出只给中间句);②utility调用(压缩摘要/技能选择)显式钉model+短超时60s快速失败走兜底(根治上游抖动窗口内连烧15分钟卡死整轮);③主调用会话级重试(瞬时Timeout/ClientError重试1次+透出进度,不再单次失败即终止会话丢整轮工作) 2026-09-11 15:09:04 +08:00
ymq
1faa1c1d2f fix(agent): 工具结果回填上限——result_cap.py(12000字符默认+params可调+显式截断告知+缩小范围指引);v2两处/v1一处回填点全接;根治商机产线实测:8次数据工具全文回填~78K token超context_limit→压缩摘要自身超时3连败→会话零产出(对照实验:同模型小上下文3.4s正常) 2026-09-11 13:46:28 +08:00
ymq
2c35abfdab feat(service): 产线流程裁剪机制层——pipeline_flow_plans表+flow_plan_capability(propose六项硬校验/confirm-reject CAS/plan_stage_enabled/create_sub_tasks PM拆解)+shared_ability聚合会话三工具(show_flow_template/propose_flow_plan/get_flow_plan);agent_loop _get_next_role跳段泛化(_skip_trimmed_roles线性链自动跳过被裁角色)+_pm_create_tasks extra_params(继承skip_generic_qc);capability_tools注册create_sub_tasks schema;init导出env.flow_plan_* 2026-09-11 12:58:26 +08:00
ymq
4d2b3aa848 feat(models): 孤儿表归籍——pipeline_agent_instances/agent_settings/project_agents 三表补models定义(此前m0002建表未进models,新库部署缺表);project_capability清除sd_conversations全部4处引用(死表,m0027 DROP);README表清单补归籍说明 2026-09-10 19:05:27 +08:00
ymq
cc63f8822c docs: README 补第二批能力对齐(五级工具作用域接线/patch_file/原生视觉多模态链) 2026-09-10 18:53:49 +08:00
ymq
7dda635c9a feat(agent): 五级作用域工具门禁接线+patch_file+原生视觉多模态
1. _init_components 加第8步 _resolve_tool_scopes: 调 core.tool_sources 五级解析,
   registry 重建为解析后工具集 + capability 工具合成注册(路由 exec_capability_tool)
2. _execute_tool 加作用域执行门禁: LLM 幻觉调用作用域外工具名(generic喊create_task/
   A产线喊B产线工具)直接拒绝并回可行动提示,不只 schema 不给看;解析失败降级不拦截
3. patch_file handler(_t_patch_file): 唯一性校验+replace_all+原子写+越界防护+二进制拒绝
4. 原生视觉: run(image_parts) 构造多模态用户消息; _call_llm 含图失败剥离重试一次
   (_degrade_images_if_needed)+注入如实告知说明(绝不假装看过图); _estimate_tokens/
   _summarize 兼容 list content(_content_as_text); gateway.run_message 加 image_paths
   透传+build_image_parts+超限notes注入
2026-09-10 18:36:54 +08:00
ymq
057fbfc05c docs: README 补 Hermes 能力对齐四项(memory/manage_skill/后台进程/并行委派)实现说明 2026-09-10 17:43:34 +08:00
ymq
d8bc29de29 fix(agent): 撤销误带入的 llm_call project_id 参数(并行会话未完成改动)
上个提交 git add agent_loop_v2.py 时连带提交了并行会话「按项目记账」的
3 处 llm_call_msgs/native(project_id=...) 调用,但配套的 llm_bridge.py 签名
改动仍在对方工作树 dirty、未提交未部署——已部署的 llm_bridge 不认 project_id
→ 通用会话 llm_call_msgs() got unexpected keyword project_id 崩溃。

修复原则:只回退我自己提交的文件到与已部署 llm_bridge 一致,不替对方合并
未完成的记账工作。撤销 _llm_select_skills / _call_llm(native+fallback) 三处
project_id 实参;保留本任务的记忆注入 build_prompt_block(project_id=...) 等。
2026-09-10 17:27:06 +08:00
ymq
1c04efe1be feat(agent): 会话agent四项Hermes能力对齐(记忆写入/技能管理/后台进程/并行委派)
1. memory 工具(add/list/remove): 多租户写入门禁——org_id/user_id强制注入、
   scope白名单user/project/pipeline(global/org种子域禁写)、无身份拒写、
   remove仅本人条目; 记忆注入改可见性过滤版(修跨机构泄漏)
2. manage_skill(create/patch/write_file/remove_file/delete): skill_live扩展,
   只落本租户orgs/users目录, global原版fork-on-write(校验通过才fork,失败零残留),
   org+user双副本同步改, 产线层拒改, delete只删本租户副本+审计留痕
3. run_command background=true + process工具(poll/log/wait/kill): bg_jobs.py
   状态文件化(workspace/.bg/,跨worker可见), 沙箱档位与前台一致(generic强制
   strict+无bwrap拒绝), 超时SIGTERM进程组+stale心跳判活
4. delegate_subtask background + subagent工具(list/steer/stop/result):
   subagents.py 并行上限3/workspace, 深度限制1(子agent禁再委派),
   子会话session_isolation=none(不读父历史不写会话表), steer/stop文件传递
   每轮tool-loop边界消费, 结果流式落盘(stop即部分结果)
2026-09-10 17:09:45 +08:00
ymq
736a2dd579 feat(human_task): 待办提供者注册表register_todo_provider——平台待办开放给外部模块注入(工单模块首用)
- _TODO_PROVIDERS注册表: provider签名async fn(user_id, roles, limit)->[todo dict], dict须含source
- list_my_human_todos: db context外遍历providers union(逐个try/except,坏provider不拖垮列表)
- count_my_human_tasks: 仅全局角标(project_id空)计入providers——工单不属于产线项目
- 架构: 待办是平台级机制,各部分(产线任务/冒泡问题/工单)产生待办,本模块聚合;
  外部模块注册钩子注入,不跨模块读表(sage-module-scaffolding 7.3)
2026-09-10 16:14:20 +08:00
ymq
b8a2aeadb7 fix(models): pipeline_conversations 孤儿表归籍本模块——补models定义(13列与活表逐列对齐,唯一写入方agent_loop_v2._save_turn)+README数据表登记;字段顺序含m0003补列session_id在尾;task_id/step_name/attachments/msg_type/org_id为预留列(活表395行实测零写入),保留定义与活表一致 2026-09-10 15:30:40 +08:00
ymq
92cdafdd22 fix(ability): 项目/模型配置弹窗URL改/pipeline_core/**——三表页面迁归属(sdlc→core),旧路径/pipeline-sdlc/sd_projects与sd_project_role_models的index.ui随迁移删除,不改则弹窗404 2026-09-10 12:33:56 +08:00
ymq
ac82d2f32d fix(project): create_project默认project_type去SDLC语义(web_app→general)+补pipeline_id/default_model参数——pipeline_id必须与alloc_project_dir的space一致,此前目录按general建而pipeline_id走DB默认sdlc_general,工作空间解析space=pipeline_id错位;注:本函数当前无调用方(实建项目走agent_loop_v2._t_create_project与bidding直插),此修复为防御性,生效路径是m0018迁移改DB列默认值 2026-09-09 19:15:19 +08:00
ymq
655d50bde8 feat(skill): 技能提议实时生效——写机构技能目录orgs/{org_id}/按scope覆盖global,机构间隔离
用户需求变更(2026-09-08):propose_skill从人工审核链(pending→published)改为实时生效,
但只写提议者所属机构的skills目录,靠org scope(优先级3)同名覆盖global(0),不影响其他机构。

- 新增 skill_live.py: publish_skill_live 路由决策+路径穿越清洗+frontmatter scope剥离+原子写
  * 客户机构(org≠0)→orgs/{org_id}/{name}/实时生效
  * org 0陷阱:get_merged里orgs/0/是全机构共享缺省——org0+有user_id降级users/{uid}/(仅本人);
    org0无人值守(复盘poller)拒绝实时写,保持pending人工审核链(防agent自动影响全平台)
- v2 _t_propose_skill / v1 retrospective.propose_skill 接入:落库照写(成功=published+路径审计)
- v1 poller长进程配套:_reload_skills_throttled(30s TTL)接入_build_role_skills_block/_load_skill_by_name
  (v2每条消息executor init已reload,无需改)
- 工具描述三处同步:core GENERAL_TOOLS/capability_tools TOOL_SCHEMAS/RETRO prompt
2026-09-08 23:59:24 +08:00
ymq
84bef76401 feat(agent): 统一文件读取+联网检索+只读库查询+generic strict沙箱(对齐Hermes信息摄入能力)
- 新增 file_read.py: v1/v2 共用统一读取(分页续读+docx/pdf解析+显式截断告知)
  根治立项书76088字符只读到30000(v2)/12000硬截无提示(v1)的真实翻车
- 新增 web_tools.py: web_search(Bing RSS优先+HTML兜底)/fetch_url(超长落盘webcache+read_file续读)
  SSRF三层防护(公网域名/DNS私址拒绝/重定向逐跳)+不可信数据标注;
  修复 aiohttp content.read(n) 对 chunked 响应提前返回半截的坑(改 resp.read())
- 新增 db_query.py: query_project_data 只读白名单查询(强制project_id参数化+where/order_by注入校验+审计)
- agent_loop.py(v1角色agent): read_file 12000硬截→共享file_read分页; AGENT_TOOLS 加三工具(补required防全参必填);
  _run_shell 加 strict 档(通用会话:不挂平台目录+可写根收窄到用户专属目录); PM/QC/RETRO prompt 工具清单同步
- agent_loop_v2.py(v2会话agent): _t_read_file 改走共享模块; 新增三工具 handler; generic run_command 强制strict+无bwrap拒绝
2026-09-08 23:13:06 +08:00
ymq
0702640aba fix(gate): _gate_plan按(请求能力,模型能力)对规划门禁——显式t2i选中i2i或自动选型落到i2i且无媒体→t2i契约代码表判定;带媒体=真i2i走LLM层;修自动选型路径cap_req空不换算致LLM按i2i契约误拦(2026-09-08实测) 2026-09-08 17:26:46 +08:00
ymq
1fce2ceb03 fix(gate): 降级执行时完备性直接走代码表——LLM/模型技能层按模型自身i2i契约误判,实测拦截合法文生图任务(2026-09-08) 2026-09-08 17:23:32 +08:00
ymq
5bb22fe7df feat(gate): invoke_model完备性门禁接入能力降级换算——i2i/r2v模型无媒体输入时按t2i/t2v契约校验(否则i2i承接文生图被缺输入图误拦)(2026-09-08) 2026-09-08 17:20:40 +08:00
ymq
d8bd88ced7 feat(ws): load_workspace注册generic_workspace_dir到ServerEnv供dspy调用(2026-09-08) 2026-09-08 16:01:15 +08:00
ymq
e0efcfc7db feat(models): add 5 runtime table JSONs + pipeline_tasks retry_count/last_error 2026-09-08 15:24:31 +08:00
ymq
83d11772d5 feat(agent): 完备性判断改LLM裁决(2026-09-08用户定夺:判断归LLM,契约归数据,硬编码降级为兜底)
- judge_completeness:①模型有配套技能(skills/models/{model}/SKILL.md)→LLM按
  技能输入契约vs用户已给内容判断缺什么;②无技能→LLM按能力语义(输入→输出
  模态)判断;③LLM失败→_check_completeness_code能力表兜底(闸门不因裁决故障失效)
- load_model_skill读配套技能;_resolve_capability补返回description供裁决
- 裁决只在invoke_model(贵动作)发生,不是每条消息;宁放行不误拦,可选参数不拦
2026-09-08 12:31:22 +08:00
ymq
ba65d586b1 feat(agent): 完备性硬门禁(2026-09-08用户定夺一C+二A)
意图识别归主循环LLM(system prompt语义引导),完备性硬门禁归代码。
- invoke_model入口check_completeness按能力契约校验必备输入:
  t2i/t2v/tts要描述,i2v/i2i要输入图,asr要音频,r2v要参考媒体
- 缺失返回QUESTION前缀,不调上游零费用(在llm_infer之前)
- v1角色agent+v2会话agent四处工具循环QUESTION硬拦截转
  ask_user/ask_question,禁回填靠LLM自觉(deepseek类会空参硬试烧钱)
- 22例单测全PASS(齐备/缺失/字符串vs数组形态/未登记能力不误伤)
2026-09-08 11:58:39 +08:00
ymq
25c9e7cdb3 fix(gateway): run_message空输入守卫——空/纯空白消息绝不进LLM(2026-09-07实测:空prompt致LLM幻觉delete_project要确认/直接run_command执行python3 heredoc非危险命令绕过确认门);入口拦截覆盖generic+全通道 2026-09-07 18:04:43 +08:00
ymq
bf6cb5b24a feat(agent): 平台模型调用能力——invoke_model/list_platform_models工具(v1角色agent+v2会话agent,唯一实现platform_model_tools);llm_bridge.llm_infer通用推理透传全能力payload+超时参数化;角色prompt加配图节(禁字符画,生成真图嵌正文)(2026-09-07用户需求) 2026-09-07 17:31:29 +08:00
ymq
763e84681f fix(gateway): 项目模型持久化加对话能力守卫——白名单取pipeline_llm.selection.CHAT_CAPS(未装兜底t2t/i2t/m2t),非对话模型选中即无效走回退链(2026-09-06用户定夺) 2026-09-06 19:49:15 +08:00
ymq
2f6b9396e1 feat(agent): _build_ctx注入session_id——能力handler会话级隔离键(extract规格锚定防跨会话串数据) 2026-09-05 21:25:47 +08:00
ymq
83c6d7aa5d docs: README 补通用会话产线隔离 7 层纵深防御说明 2026-09-05 19:51:57 +08:00
ymq
874a14b6bb fix(isolation): session_search 通用会话只搜自身历史(与 _load_history 过滤对称)
第7层泄漏补刀:session_search 原按 iteration_id 过滤,通用会话 iteration_id=''
匹配到的是所有无项目对话;统一改为按 pipeline_id='' 过滤通用会话历史,
防止修复前落库的污染对话被搜出复述。
2026-09-05 15:29:44 +08:00
ymq
b93617feaf fix(isolation): 第7层泄漏——通用会话历史回放不过滤产线,跨产线对话进上下文
实测:工具/文件系统隔离生效后,通用助手仍复述出产线项目ID。
根因:_load_history 无 session_id 分支按 created_by 全量回放该用户
所有产线的最近对话(项目名称/ID 随历史泄漏)。

修复:通用会话只回放 pipeline_id='' 的历史(存库时 store_pl='' 与
此过滤对称);有 session_id 的分支同样加通用会话空产线过滤。
2026-09-05 15:27:00 +08:00
ymq
5c28fed040 fix(isolation): 第6层泄漏——通用会话工作空间总根可枚举所有产线项目
实测发现:工具层隔离生效后,LLM 改用 list_files/run_command 浏览
WORKSPACE_BASE 总根({base}/{org}/{产线}/…全量可见),从目录名
枚举出所有产线的全部项目。

修复:
- workspace.py 新增 generic_workspace_dir():通用会话专属目录 _general/{uid}
- agent_loop_v2: generic 会话文件根改专属目录(_resolve_ws_path 越界保护圈死)
- agent_loop_v2: run_command 对通用会话执行层拒绝(shell 无法圈禁在目录内)
- schema 层剔除 shell 类工具(配合 pipeline-core)
2026-09-05 15:21:35 +08:00
ymq
b99fb4cc13 fix(isolation): 通用助手会话泄漏产线项目工具——5层修复
根因:
1. tool_registry 全局单例跨会话污染:产线会话注册的工具(如 list_projects)
   永久残留,后续通用会话把全部工具塞给 LLM
2. generic 会话 pipeline_id 空被无条件回退 DEFAULT_ABILITY_ID(sdlc_general),
   _execute_ability_tool 拿到产线能力包直接执行
3. _h_list_projects 对 space='general' 不过滤,列出所有产线全部项目
4. GENERAL_TOOLS 本身含项目管理工具,通用会话无条件拿到

修复(纵深防御,schema 层+执行层双保险):
- agent_loop_v2: ToolRegistry 改每 executor 独立实例(禁全局单例)
- agent_loop_v2: generic 会话跳过默认产线回退
- agent_loop_v2: _execute_ability_tool 对 generic 直接返回 None
- agent_loop_v2: _dispatch_sdlc_tool 对 generic 拒绝项目类工具(含别名归一)
- agent_loop_v2: generic 记忆只读 global 域、技能只检索 global 层
- sdlc_ability: _h_list_projects 对 general 空间拒绝列项目

配套:pipeline-core load_agent_config generic 时剔除 category=project 工具
2026-09-05 12:43:33 +08:00
ymq
e88e0bfc37 feat(llm_bridge): llm_call/llm_call_msgs加timeout参数——_timeout经payload透传统一推理端点(提取等长任务超端点默认60秒) 2026-09-05 10:24:55 +08:00
ymq
03c79fe356 fix(rag-client): Authorization前缀被写入侧秘密扫描替换为***致401——运行时拼接 2026-09-04 19:49:39 +08:00
ymq
8a627b34a1 fix(rag-client): dapi返回值类型加固(失败可能返回字符串) 2026-09-04 19:36:13 +08:00
ymq
8a9d0f8294 fix(llm_bridge): 修复purpose碰撞——3个调用函数补purpose参数并塞payload._purpose(上轮重构收敛时丢失,4处调用点传purpose='utility'会TypeError) 2026-09-04 19:32:33 +08:00
ymq
25db66aa61 fix(llm_bridge): 自调用Bearer前缀用拼接构造——字面量被脱敏工具替换成***致Authorization头无效(401同根因) 2026-09-04 18:33:53 +08:00
ymq
f3f82dd448 refactor(llm): agent调用收敛到模型治理统一推理API——llm_bridge改HTTP自调用薄客户端(短期token+本进程端口),删旧llm表直查;llm_proxy委托chat_inference;gateway/agent_loop/bug_flow模型解析与缺省模型改走治理链/统一解析,清除写死模型名 2026-09-04 17:05:42 +08:00
ymq
0aa632dd28 fix(kb-ingest): 待办置完成改用suggestion_id精确匹配(防同名文件误伤) 2026-09-04 16:33:15 +08:00
ymq
ae3967c3b0 fix(rag-access): RC4加解密显式传key(对称约定)+会话agent通道挂检索工具(全产线共享) 2026-09-04 16:12:17 +08:00
ymq
21c8c16daa feat(rag-access): 产线接入知识库——全角色按项目owner权限检索(rag_search/rag_kb_list)+PM建议入库待办闭环+统一API模式 2026-09-04 15:57:41 +08:00