""" pipeline-service: slash_commands — 通用 slash 命令(core 内核,产线无关) handler 签名:async def handler(args, ctx) -> str ctx = {project_id, user_id, pipeline_id, workspace_dir, model_name, config, executor} 通用 slash 命令(任何产线都可用):/help /status /reset /tools /skills /model 产线 slash 命令(SDLC 的 /tasks /diagnose 等)在 sdlc_ability 注册。 """ import json import logging from pipeline_core import SlashCommand, register_slash_command, get_slash_commands logger = logging.getLogger("pipeline.slash_commands") async def _h_help(args, ctx): visible = get_slash_commands(ctx.get("pipeline_id", ""), ctx.get("role", "")) lines = ["可用命令:"] for name in sorted(visible): cmd = visible[name] hint = f" {cmd.args_hint}" if cmd.args_hint else "" lines.append(f" /{name}{hint} — {cmd.description}") return "\n".join(lines) async def _h_status(args, ctx): executor = ctx.get("executor") if not executor: return "ERROR: 无 executor 上下文" # 复用能力包诊断工具(SDLC 产线 → diagnose_project;其他产线 → 通用状态) r = await executor._execute_ability_tool("diagnose_project", {}) if r is None: r = await executor._execute_ability_tool("check_progress", {}) if r is None: return "当前项目无状态诊断工具" return r async def _h_reset(args, ctx): executor = ctx.get("executor") if not executor: return "ERROR: 无 executor 上下文" executor._msgs = [] executor._turn_count = 0 executor._tool_call_count = 0 executor._todos = [] return "OK: 会话已重置(清空历史 + 任务清单)" async def _h_tools(args, ctx): cfg = ctx.get("config") if not cfg: return "无工具配置" lines = ["可用工具:"] for t in cfg.tools: if getattr(t, "enabled", True): params = ", ".join(f"{k}" for k in (t.parameters or {}).keys()) lines.append(f" - {t.name}({params}) — {t.description}") return "\n".join(lines) async def _h_skills(args, ctx): executor = ctx.get("executor") if not executor or not executor._skill_loader: return "技能系统未启用" merged = executor._skill_loader.get_merged( pipeline_id=ctx.get("pipeline_id", ""), role=ctx.get("role", ""), project_id=ctx.get("project_id", ""), org_id=executor.org_id, user_id=ctx.get("user_id", ""), ) if not merged: return "暂无可用技能" # 限数量:只列前 20 个(按 scope + 名字排序),提示总数,避免 216 个全倒出来 items = sorted(merged.items(), key=lambda kv: (kv[1].scope, kv[0])) lines = [f"可用技能(共 {len(items)} 个,仅列前 20,按需用 load_skill 加载正文):"] for name, s in items[:20]: lines.append(f" - [{s.scope}] {name} — {s.description[:100]}") return "\n".join(lines) async def _h_model(args, ctx): return f"当前模型: {ctx.get('model_name', '未知')}" # ── 注册通用 slash 命令 ── def register_general_slash_commands(): for cmd in [ SlashCommand("help", "列出可用命令", _h_help, "global"), SlashCommand("status", "诊断当前项目状态", _h_status, "global"), SlashCommand("reset", "重置会话(清空历史)", _h_reset, "global"), SlashCommand("tools", "列出可用工具", _h_tools, "global"), SlashCommand("skills", "列出可用技能", _h_skills, "global"), SlashCommand("model", "显示当前模型", _h_model, "global"), ]: register_slash_command(cmd) register_general_slash_commands()