diff --git a/README.md b/README.md index bd6bd1f..aa9db97 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ | pipeline_step_types | 步骤类型注册 | | pipeline_session_settings | 会话设置(多 tab 项目上下文) | | pipeline_conversations | 平台会话消息(回放缓存;2026-09-10 归籍本模块——唯一写入方 agent_loop_v2._save_turn,此前是无 models 定义的孤儿表) | +| pipeline_agent_instances | 角色 agent 实例注册(项目×角色→稳定实例 id;唯一写入方 agent_instance.py;m0002 建表未进 models,2026-09-10 归籍) | +| pipeline_agent_settings | 用户 agent 偏好(每用户一行 uk_user:默认模型/当前项目指针;写入方 agent_loop_v2、set_agent_model.dspy、workspace.py;2026-09-10 归籍) | +| pipeline_project_agents | 项目角色 agent 配置(驾驶舱 v1 start_agent 链路;v2 已走 pipeline_agent_instances,保留至 v1 链路删除决议;2026-09-10 归籍) | ## 安装 diff --git a/models/pipeline_agent_instances.json b/models/pipeline_agent_instances.json new file mode 100644 index 0000000..b7d63d1 --- /dev/null +++ b/models/pipeline_agent_instances.json @@ -0,0 +1,22 @@ +{ + "summary": [ + { + "name": "pipeline_agent_instances", + "title": "角色agent实例注册表(项目×角色→稳定实例id;m0002建表未进models,2026-09-10归籍;唯一写入方agent_instance.py,44行活表)", + "primary": ["id"], + "catelog": "entity" + } + ], + "fields": [ + {"name": "id", "title": "主键ID", "type": "str", "length": 32, "nullable": "no"}, + {"name": "project_id", "title": "项目ID(空串=全局)", "type": "str", "length": 32, "nullable": "no", "default": ""}, + {"name": "role", "title": "角色名", "type": "str", "length": 64, "nullable": "no"}, + {"name": "agent_id", "title": "稳定agent实例ID", "type": "str", "length": 32, "nullable": "no"}, + {"name": "status", "title": "状态", "type": "str", "length": 16, "nullable": "no", "default": "active"}, + {"name": "created_at", "title": "创建时间", "type": "timestamp", "nullable": "no"}, + {"name": "updated_at", "title": "更新时间", "type": "timestamp", "nullable": "no"} + ], + "indexes": [ + {"name": "idx_pai_pr", "idxtype": "unique", "idxfields": ["project_id", "role"]} + ] +} diff --git a/models/pipeline_agent_settings.json b/models/pipeline_agent_settings.json new file mode 100644 index 0000000..2838b4a --- /dev/null +++ b/models/pipeline_agent_settings.json @@ -0,0 +1,26 @@ +{ + "summary": [ + { + "name": "pipeline_agent_settings", + "title": "用户agent偏好设置表(每用户一行uk_user;2026-09-10归籍;写入方agent_loop_v2/set_agent_model.dspy/workspace.py,6行活表;定义逐列对齐活表,float/raw如实呈现)", + "primary": ["id"], + "catelog": "entity" + } + ], + "fields": [ + {"name": "id", "title": "主键ID", "type": "str", "length": 32, "nullable": "no"}, + {"name": "user_id", "title": "用户ID", "type": "str", "length": 32, "nullable": "no"}, + {"name": "default_llm_id", "title": "默认模型ID(空=平台缺省)", "type": "str", "length": 32, "nullable": "yes", "default": ""}, + {"name": "system_prompt", "title": "自定义系统提示词", "type": "text", "nullable": "yes"}, + {"name": "temperature", "title": "温度(预留;活表bare float,新机渲染double(10,2)——平台模板约定,值域0-2无影响)", "type": "float", "length": 10, "dec": 2, "nullable": "yes", "default": "0.7"}, + {"name": "max_context_messages", "title": "上下文最大消息数(预留)", "type": "int", "nullable": "yes", "default": "30"}, + {"name": "current_project_id", "title": "当前项目ID指针(全局回退用)", "type": "str", "length": 32, "nullable": "yes", "default": ""}, + {"name": "current_iteration_id", "title": "当前迭代ID指针(预留)", "type": "str", "length": 32, "nullable": "yes", "default": ""}, + {"name": "workspace_dir", "title": "工作目录覆盖(预留)", "type": "str", "length": 500, "nullable": "yes", "default": ""}, + {"name": "created_at", "title": "创建时间", "type": "timestamp", "nullable": "no"}, + {"name": "updated_at", "title": "更新时间(活表有ON UPDATE,新机无——模板不支持,业务不依赖)", "type": "timestamp", "nullable": "no"} + ], + "indexes": [ + {"name": "uk_user", "idxtype": "unique", "idxfields": ["user_id"]} + ] +} diff --git a/models/pipeline_project_agents.json b/models/pipeline_project_agents.json new file mode 100644 index 0000000..9c3851c --- /dev/null +++ b/models/pipeline_project_agents.json @@ -0,0 +1,26 @@ +{ + "summary": [ + { + "name": "pipeline_project_agents", + "title": "项目角色agent配置表(驾驶舱v1 start_agent链路;2026-09-10归籍+补idx_ppa_project索引;v1入口cockpit_agent.dspy当前0调用方,v2走pipeline_agent_instances——保留至v1链路删除决议;定义逐列对齐活表,tinyint/raw如实呈现)", + "primary": ["id"], + "catelog": "entity" + } + ], + "fields": [ + {"name": "id", "title": "主键ID", "type": "str", "length": 32, "nullable": "no"}, + {"name": "project_id", "title": "项目ID", "type": "str", "length": 32, "nullable": "no"}, + {"name": "role_name", "title": "角色名", "type": "str", "length": 100, "nullable": "no", "default": "developer"}, + {"name": "agent_prompt", "title": "角色提示词", "type": "text", "nullable": "yes"}, + {"name": "task_filter", "title": "任务过滤条件JSON", "type": "text", "nullable": "yes"}, + {"name": "deliverable_dir", "title": "交付物目录", "type": "str", "length": 500, "nullable": "yes", "default": ""}, + {"name": "model_name", "title": "模型名", "type": "str", "length": 100, "nullable": "yes", "default": ""}, + {"name": "auto_start", "title": "自动启动(0/1)", "type": "tinyint(4)", "nullable": "yes", "default": "0"}, + {"name": "status", "title": "运行状态", "type": "str", "length": 20, "nullable": "yes", "default": "stopped"}, + {"name": "created_at", "title": "创建时间", "type": "timestamp", "nullable": "no"}, + {"name": "updated_at", "title": "更新时间(活表有ON UPDATE,新机无——模板不支持,业务不依赖)", "type": "timestamp", "nullable": "no"} + ], + "indexes": [ + {"name": "idx_ppa_project", "idxtype": "index", "idxfields": ["project_id"]} + ] +} diff --git a/pipeline_service/project_capability.py b/pipeline_service/project_capability.py index 6f3d9b0..492baf9 100644 --- a/pipeline_service/project_capability.py +++ b/pipeline_service/project_capability.py @@ -442,7 +442,6 @@ async def _dump_project_records(sor, project_id): 'sd_bugs': "SELECT * FROM sd_bugs WHERE iteration_id IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$)", 'sd_test_plans': "SELECT * FROM sd_test_plans WHERE iteration_id IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$)", 'sd_test_cases': "SELECT * FROM sd_test_cases WHERE plan_id IN (SELECT id FROM sd_test_plans WHERE iteration_id IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$))", - 'sd_conversations': "SELECT * FROM sd_conversations WHERE iteration_id COLLATE utf8mb4_unicode_ci IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$)", 'pipeline_conversations': "SELECT * FROM pipeline_conversations WHERE iteration_id COLLATE utf8mb4_unicode_ci=${pid}$ OR iteration_id COLLATE utf8mb4_unicode_ci IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$)", 'audit_log': "SELECT * FROM audit_log WHERE tenant_id COLLATE utf8mb4_unicode_ci=${pid}$ ORDER BY created_at ASC", } @@ -545,7 +544,6 @@ async def delete_project(project_id, who=None, agent_id=None, confirm=False): "DELETE FROM sd_test_cases WHERE plan_id IN (SELECT id FROM sd_test_plans WHERE iteration_id IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$))", "DELETE FROM sd_bugs WHERE iteration_id IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$)", "DELETE FROM sd_test_plans WHERE iteration_id IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$)", - "DELETE FROM sd_conversations WHERE iteration_id COLLATE utf8mb4_unicode_ci IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$)", "DELETE FROM pipeline_conversations WHERE iteration_id COLLATE utf8mb4_unicode_ci=${pid}$ OR iteration_id COLLATE utf8mb4_unicode_ci IN (SELECT id FROM sd_iterations WHERE project_id=${pid}$)", ] for sql in indirect: @@ -615,10 +613,10 @@ async def delete_project(project_id, who=None, agent_id=None, confirm=False): # # 孤儿判据 = 引用列【非空】且指向的主键在父表中已不存在。 # 注意:空串 '' 与 NULL 都表示「未挂载」(合法),不是孤儿——若不加 `<> ''` 守卫, -# `NOT IN` 会把空串当成孤儿误删(实测 sd_conversations 32 条 / sd_features 23 条 iteration_id='' 被误判)。 +# `NOT IN` 会把空串当成孤儿误删(实测 sd_features 23 条 iteration_id='' 被误判)。 # # 列 collation 不一(sd_projects.id / sd_iterations.id / pipeline_tasks.id 是 unicode_ci; -# sd_project_repos / pipeline_deliverables / sd_conversations 的引用列是 general_ci), +# sd_project_repos / pipeline_deliverables 的引用列是 general_ci), # 跨表比较处显式 COLLATE utf8mb4_unicode_ci 规避 1267。 # (label, 表, 引用列, 父表, 是否需 COLLATE) @@ -632,7 +630,6 @@ _ORPHAN_CLEANUPS = [ ("sd_features(无迭代)", "sd_features", "iteration_id", "sd_iterations", False), ("sd_bugs(无迭代)", "sd_bugs", "iteration_id", "sd_iterations", False), ("sd_test_plans(无迭代)", "sd_test_plans", "iteration_id", "sd_iterations", False), - ("sd_conversations(无迭代)", "sd_conversations", "iteration_id", "sd_iterations", True), ("pipeline_deliverables(无迭代)", "pipeline_deliverables", "iteration_id", "sd_iterations", True), ("sd_test_cases(无计划)", "sd_test_cases", "plan_id", "sd_test_plans", False), ("pipeline_deliverables(无任务)", "pipeline_deliverables", "task_id", "pipeline_tasks", True), @@ -642,7 +639,6 @@ _ORPHAN_CLEANUPS = [ ("pipeline_agent_questions(无任务)", "pipeline_agent_questions", "task_id", "pipeline_tasks", False), ("sd_features(无任务)", "sd_features", "task_id", "pipeline_tasks", False), ("sd_iterations(无任务)", "sd_iterations", "task_id", "pipeline_tasks", False), - ("sd_conversations(无任务)", "sd_conversations", "task_id", "pipeline_tasks", True), # 「当前项目」指针:指向已删项目的会话/全局设置记录。解析层已能自愈回退, # 这里清扫是存量脏数据的批量兜底(历史 CRUD 删除不清理指针留下的)。 ("pipeline_session_settings(无项目)", "pipeline_session_settings", "current_project_id", "sd_projects", True),