diff --git a/pipeline_service/capability_tools.py b/pipeline_service/capability_tools.py index 6dd2860..c3aa3a3 100644 --- a/pipeline_service/capability_tools.py +++ b/pipeline_service/capability_tools.py @@ -278,7 +278,13 @@ async def exec_capability_tool(tool_name, params, ctx): p.setdefault("task_id", ctx.get("task_id", "")) try: - mod = importlib.import_module(f"pipeline_service.{schema['module']}") + # module 支持两种写法:裸名(如 'feature_capability',pipeline-service 包内) + # 或全路径(如 'pipeline_bidding.bid_tender_capability',产线自有能力包)。 + # 产线能力模块放自己仓库:宿主不装该产线就零接触,不污染引擎包。 + modname = schema['module'] + if '.' not in modname: + modname = "pipeline_service." + modname + mod = importlib.import_module(modname) fn = getattr(mod, tool_name) sig = inspect.signature(fn) kwargs = {k: v for k, v in p.items() if k in sig.parameters} diff --git a/pipeline_service/shared_ability.py b/pipeline_service/shared_ability.py new file mode 100644 index 0000000..7cc8da5 --- /dev/null +++ b/pipeline_service/shared_ability.py @@ -0,0 +1,60 @@ +"""引擎级共享能力:跨产线通用的任务/交付件/问答/项目生命周期工具集合。 + +这些 handler 操作的都是**通用表**(pipeline_tasks / pipeline_deliverables / +pipeline_agent_questions / sd_projects),与具体产线无关。历史原因它们的实现落在 +sdlc_ability.py 里;本模块把「通用那部分」聚合出来,供任意产线能力包复用: + + from pipeline_service.shared_ability import SHARED_TOOLS, SHARED_HANDLERS + +这样新产线(如投标产线 bidding_general)不必复制 700 行任务管理代码,也不必反向依赖 +另一个产线的能力包。零行为变更:只是引用,不移动实现。 + +后续可把这些 handler 的实现物理迁移到本模块,sdlc_ability 改为从这里 import。 +""" + +import logging + +logger = logging.getLogger("pipeline.shared_ability") + +# 通用工具名单(产线无关)。凡涉及 sd_iterations / sd_features / sd_bugs / +# sd_test_* / sd_deploy_envs 的 SDLC 专属工具都不在此列。 +_GENERIC_TOOL_NAMES = [ + # 任务 + "create_task", "list_tasks", "task_detail", "reset_task_retry", + "approve_task", "complete_task", "cancel_task", + # agent 运行 / 诊断 + "start_agents", "diagnose_project", "check_progress", + # 交付件 + "list_deliverables", "view_deliverable", + "submit_deliverable", "approve_deliverable", "reject_deliverable", + # 问答冒泡 + "list_questions", "answer_question", "escalate_question", + # 项目生命周期 + "list_projects", "start_project", "complete_project", "archive_project", + "reopen_project", "pause_project", "resume_project", "backup_project", + # 角色模型 + "list_role_models", "set_role_model", +] + +SHARED_TOOLS = [] +SHARED_HANDLERS = {} + + +def _build(): + global SHARED_TOOLS, SHARED_HANDLERS + try: + from .sdlc_ability import SDL_TOOLS, SDL_HANDLERS + except Exception as e: + logger.warning("shared_ability: 无法加载通用 handler 源: %s", str(e)[:160]) + return + names = set(_GENERIC_TOOL_NAMES) + SHARED_TOOLS = [t for t in SDL_TOOLS if getattr(t, "name", "") in names] + SHARED_HANDLERS = {k: v for k, v in SDL_HANDLERS.items() if k in names} + missing = names - set(SHARED_HANDLERS) + if missing: + logger.info("shared_ability: 以下通用工具未找到 handler(跳过): %s", sorted(missing)) + logger.info("shared_ability: %d tools / %d handlers 可复用", + len(SHARED_TOOLS), len(SHARED_HANDLERS)) + + +_build()