From 5ceed021dcd2bb8ecac43cdf8db0c3849dd43aa2 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Mon, 30 Mar 2026 10:57:30 -0700 Subject: [PATCH] feat(gateway): skill-aware slash commands, paginated /commands, Telegram 100-cap (#3934) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(gateway): skill-aware slash commands, paginated /commands, Telegram 100-cap Map active skills to Telegram's slash command menu so users can discover and invoke skills directly. Three changes: 1. Telegram menu now includes active skill commands alongside built-in commands, capped at 100 entries (Telegram Bot API limit). Overflow commands remain callable but hidden from the picker. Logged at startup when cap is hit. 2. New /commands [page] gateway command for paginated browsing of all commands + skills. /help now shows first 10 skill commands and points to /commands for the full list. 3. When a user types a slash command that matches a disabled or uninstalled skill, they get actionable guidance: - Disabled: 'Enable it with: hermes skills config' - Optional (not installed): 'Install with: hermes skills install official/' Built on ideas from PR #3921 by @kshitijk4poor. * chore: move 21 niche skills to optional-skills Move specialized/niche skills from built-in (skills/) to optional (optional-skills/) to reduce the default skill count. Users can install them with: hermes skills install official// Moved skills (21): - mlops: accelerate, chroma, faiss, flash-attention, hermes-atropos-environments, huggingface-tokenizers, instructor, lambda-labs, llava, nemo-curator, pinecone, pytorch-lightning, qdrant, saelens, simpo, slime, tensorrt-llm, torchtitan - research: domain-intel, duckduckgo-search - devops: inference-sh cli Built-in skills: 96 → 75 Optional skills: 22 → 43 * fix: only include repo built-in skills in Telegram menu, not user-installed User-installed skills (from hub or manually added) stay accessible via /skills and by typing the command directly, but don't get registered in the Telegram slash command picker. Only skills whose SKILL.md is under the repo's skills/ directory are included in the menu. This keeps the Telegram menu focused on the curated built-in set while user-installed skills remain discoverable through /skills and /commands. --- gateway/platforms/telegram.py | 10 +- gateway/run.py | 114 +++++++++++++++++- hermes_cli/commands.py | 43 +++++++ .../devops}/cli/SKILL.md | 0 .../devops}/cli/references/app-discovery.md | 0 .../devops}/cli/references/authentication.md | 0 .../devops}/cli/references/cli-reference.md | 0 .../devops}/cli/references/running-apps.md | 0 .../mlops}/accelerate/SKILL.md | 0 .../accelerate/references/custom-plugins.md | 0 .../references/megatron-integration.md | 0 .../accelerate/references/performance.md | 0 .../mlops}/chroma/SKILL.md | 0 .../mlops}/chroma/references/integration.md | 0 .../mlops}/faiss/SKILL.md | 0 .../mlops}/faiss/references/index_types.md | 0 .../mlops}/flash-attention/SKILL.md | 0 .../flash-attention/references/benchmarks.md | 0 .../references/transformers-integration.md | 0 .../hermes-atropos-environments/SKILL.md | 0 .../references/agentresult-fields.md | 0 .../references/atropos-base-env.md | 0 .../references/usage-patterns.md | 0 .../mlops}/huggingface-tokenizers/SKILL.md | 0 .../references/algorithms.md | 0 .../references/integration.md | 0 .../references/pipeline.md | 0 .../references/training.md | 0 .../mlops}/instructor/SKILL.md | 0 .../mlops}/instructor/references/examples.md | 0 .../mlops}/instructor/references/providers.md | 0 .../instructor/references/validation.md | 0 .../mlops}/lambda-labs/SKILL.md | 0 .../lambda-labs/references/advanced-usage.md | 0 .../lambda-labs/references/troubleshooting.md | 0 .../mlops}/llava/SKILL.md | 0 .../mlops}/llava/references/training.md | 0 .../mlops}/nemo-curator/SKILL.md | 0 .../nemo-curator/references/deduplication.md | 0 .../nemo-curator/references/filtering.md | 0 .../mlops}/pinecone/SKILL.md | 0 .../mlops}/pinecone/references/deployment.md | 0 .../mlops}/pytorch-lightning/SKILL.md | 0 .../pytorch-lightning/references/callbacks.md | 0 .../references/distributed.md | 0 .../references/hyperparameter-tuning.md | 0 .../mlops}/qdrant/SKILL.md | 0 .../qdrant/references/advanced-usage.md | 0 .../qdrant/references/troubleshooting.md | 0 .../mlops}/saelens/SKILL.md | 0 .../mlops}/saelens/references/README.md | 0 .../mlops}/saelens/references/api.md | 0 .../mlops}/saelens/references/tutorials.md | 0 .../mlops}/simpo/SKILL.md | 0 .../mlops}/simpo/references/datasets.md | 0 .../simpo/references/hyperparameters.md | 0 .../mlops}/simpo/references/loss-functions.md | 0 .../mlops}/slime/SKILL.md | 0 .../mlops}/slime/references/api-reference.md | 0 .../slime/references/troubleshooting.md | 0 .../mlops}/tensorrt-llm/SKILL.md | 0 .../tensorrt-llm/references/multi-gpu.md | 0 .../tensorrt-llm/references/optimization.md | 0 .../mlops}/tensorrt-llm/references/serving.md | 0 .../mlops}/torchtitan/SKILL.md | 0 .../torchtitan/references/checkpoint.md | 0 .../torchtitan/references/custom-models.md | 0 .../mlops}/torchtitan/references/float8.md | 0 .../mlops}/torchtitan/references/fsdp.md | 0 .../research/domain-intel/SKILL.md | 0 .../domain-intel/scripts/domain_intel.py | 0 .../research/duckduckgo-search/SKILL.md | 0 .../duckduckgo-search/scripts/duckduckgo.sh | 0 73 files changed, 163 insertions(+), 4 deletions(-) rename {skills/inference-sh => optional-skills/devops}/cli/SKILL.md (100%) rename {skills/inference-sh => optional-skills/devops}/cli/references/app-discovery.md (100%) rename {skills/inference-sh => optional-skills/devops}/cli/references/authentication.md (100%) rename {skills/inference-sh => optional-skills/devops}/cli/references/cli-reference.md (100%) rename {skills/inference-sh => optional-skills/devops}/cli/references/running-apps.md (100%) rename {skills/mlops/training => optional-skills/mlops}/accelerate/SKILL.md (100%) rename {skills/mlops/training => optional-skills/mlops}/accelerate/references/custom-plugins.md (100%) rename {skills/mlops/training => optional-skills/mlops}/accelerate/references/megatron-integration.md (100%) rename {skills/mlops/training => optional-skills/mlops}/accelerate/references/performance.md (100%) rename {skills/mlops/vector-databases => optional-skills/mlops}/chroma/SKILL.md (100%) rename {skills/mlops/vector-databases => optional-skills/mlops}/chroma/references/integration.md (100%) rename {skills/mlops/vector-databases => optional-skills/mlops}/faiss/SKILL.md (100%) rename {skills/mlops/vector-databases => optional-skills/mlops}/faiss/references/index_types.md (100%) rename {skills/mlops/training => optional-skills/mlops}/flash-attention/SKILL.md (100%) rename {skills/mlops/training => optional-skills/mlops}/flash-attention/references/benchmarks.md (100%) rename {skills/mlops/training => optional-skills/mlops}/flash-attention/references/transformers-integration.md (100%) rename {skills/mlops/training => optional-skills/mlops}/hermes-atropos-environments/SKILL.md (100%) rename {skills/mlops/training => optional-skills/mlops}/hermes-atropos-environments/references/agentresult-fields.md (100%) rename {skills/mlops/training => optional-skills/mlops}/hermes-atropos-environments/references/atropos-base-env.md (100%) rename {skills/mlops/training => optional-skills/mlops}/hermes-atropos-environments/references/usage-patterns.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/huggingface-tokenizers/SKILL.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/huggingface-tokenizers/references/algorithms.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/huggingface-tokenizers/references/integration.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/huggingface-tokenizers/references/pipeline.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/huggingface-tokenizers/references/training.md (100%) rename {skills/mlops/inference => optional-skills/mlops}/instructor/SKILL.md (100%) rename {skills/mlops/inference => optional-skills/mlops}/instructor/references/examples.md (100%) rename {skills/mlops/inference => optional-skills/mlops}/instructor/references/providers.md (100%) rename {skills/mlops/inference => optional-skills/mlops}/instructor/references/validation.md (100%) rename {skills/mlops/cloud => optional-skills/mlops}/lambda-labs/SKILL.md (100%) rename {skills/mlops/cloud => optional-skills/mlops}/lambda-labs/references/advanced-usage.md (100%) rename {skills/mlops/cloud => optional-skills/mlops}/lambda-labs/references/troubleshooting.md (100%) rename {skills/mlops/models => optional-skills/mlops}/llava/SKILL.md (100%) rename {skills/mlops/models => optional-skills/mlops}/llava/references/training.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/nemo-curator/SKILL.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/nemo-curator/references/deduplication.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/nemo-curator/references/filtering.md (100%) rename {skills/mlops/vector-databases => optional-skills/mlops}/pinecone/SKILL.md (100%) rename {skills/mlops/vector-databases => optional-skills/mlops}/pinecone/references/deployment.md (100%) rename {skills/mlops/training => optional-skills/mlops}/pytorch-lightning/SKILL.md (100%) rename {skills/mlops/training => optional-skills/mlops}/pytorch-lightning/references/callbacks.md (100%) rename {skills/mlops/training => optional-skills/mlops}/pytorch-lightning/references/distributed.md (100%) rename {skills/mlops/training => optional-skills/mlops}/pytorch-lightning/references/hyperparameter-tuning.md (100%) rename {skills/mlops/vector-databases => optional-skills/mlops}/qdrant/SKILL.md (100%) rename {skills/mlops/vector-databases => optional-skills/mlops}/qdrant/references/advanced-usage.md (100%) rename {skills/mlops/vector-databases => optional-skills/mlops}/qdrant/references/troubleshooting.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/saelens/SKILL.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/saelens/references/README.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/saelens/references/api.md (100%) rename {skills/mlops/evaluation => optional-skills/mlops}/saelens/references/tutorials.md (100%) rename {skills/mlops/training => optional-skills/mlops}/simpo/SKILL.md (100%) rename {skills/mlops/training => optional-skills/mlops}/simpo/references/datasets.md (100%) rename {skills/mlops/training => optional-skills/mlops}/simpo/references/hyperparameters.md (100%) rename {skills/mlops/training => optional-skills/mlops}/simpo/references/loss-functions.md (100%) rename {skills/mlops/training => optional-skills/mlops}/slime/SKILL.md (100%) rename {skills/mlops/training => optional-skills/mlops}/slime/references/api-reference.md (100%) rename {skills/mlops/training => optional-skills/mlops}/slime/references/troubleshooting.md (100%) rename {skills/mlops/inference => optional-skills/mlops}/tensorrt-llm/SKILL.md (100%) rename {skills/mlops/inference => optional-skills/mlops}/tensorrt-llm/references/multi-gpu.md (100%) rename {skills/mlops/inference => optional-skills/mlops}/tensorrt-llm/references/optimization.md (100%) rename {skills/mlops/inference => optional-skills/mlops}/tensorrt-llm/references/serving.md (100%) rename {skills/mlops/training => optional-skills/mlops}/torchtitan/SKILL.md (100%) rename {skills/mlops/training => optional-skills/mlops}/torchtitan/references/checkpoint.md (100%) rename {skills/mlops/training => optional-skills/mlops}/torchtitan/references/custom-models.md (100%) rename {skills/mlops/training => optional-skills/mlops}/torchtitan/references/float8.md (100%) rename {skills/mlops/training => optional-skills/mlops}/torchtitan/references/fsdp.md (100%) rename {skills => optional-skills}/research/domain-intel/SKILL.md (100%) rename {skills => optional-skills}/research/domain-intel/scripts/domain_intel.py (100%) rename {skills => optional-skills}/research/duckduckgo-search/SKILL.md (100%) rename {skills => optional-skills}/research/duckduckgo-search/scripts/duckduckgo.sh (100%) diff --git a/gateway/platforms/telegram.py b/gateway/platforms/telegram.py index e17d104a6..91223d7b7 100644 --- a/gateway/platforms/telegram.py +++ b/gateway/platforms/telegram.py @@ -622,10 +622,16 @@ class TelegramAdapter(BasePlatformAdapter): # gateway command there automatically adds it to the Telegram menu. try: from telegram import BotCommand - from hermes_cli.commands import telegram_bot_commands + from hermes_cli.commands import telegram_menu_commands + menu_commands, hidden_count = telegram_menu_commands(max_commands=100) await self._bot.set_my_commands([ - BotCommand(name, desc) for name, desc in telegram_bot_commands() + BotCommand(name, desc) for name, desc in menu_commands ]) + if hidden_count: + logger.info( + "[%s] Telegram menu: %d commands registered, %d hidden (over 100 limit). Use /commands for full list.", + self.name, len(menu_commands), hidden_count, + ) except Exception as e: logger.warning( "[%s] Could not register Telegram command menu: %s", diff --git a/gateway/run.py b/gateway/run.py index 3b5193042..2bd623b62 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -301,6 +301,50 @@ def _resolve_runtime_agent_kwargs() -> dict: } +def _check_unavailable_skill(command_name: str) -> str | None: + """Check if a command matches a known-but-inactive skill. + + Returns a helpful message if the skill exists but is disabled or only + available as an optional install. Returns None if no match found. + """ + # Normalize: command uses hyphens, skill names may use hyphens or underscores + normalized = command_name.lower().replace("_", "-") + try: + from tools.skills_tool import SKILLS_DIR, _get_disabled_skill_names + disabled = _get_disabled_skill_names() + + # Check disabled built-in skills + for skill_md in SKILLS_DIR.rglob("SKILL.md"): + if any(part in ('.git', '.github', '.hub') for part in skill_md.parts): + continue + name = skill_md.parent.name.lower().replace("_", "-") + if name == normalized and name in disabled: + return ( + f"The **{command_name}** skill is installed but disabled.\n" + f"Enable it with: `hermes skills config`" + ) + + # Check optional skills (shipped with repo but not installed) + from hermes_constants import get_hermes_home + repo_root = Path(__file__).resolve().parent.parent + optional_dir = repo_root / "optional-skills" + if optional_dir.exists(): + for skill_md in optional_dir.rglob("SKILL.md"): + name = skill_md.parent.name.lower().replace("_", "-") + if name == normalized: + # Build install path: official// + rel = skill_md.parent.relative_to(optional_dir) + parts = list(rel.parts) + install_path = f"official/{'/'.join(parts)}" + return ( + f"The **{command_name}** skill is available but not installed.\n" + f"Install it with: `hermes skills install {install_path}`" + ) + except Exception: + pass + return None + + def _platform_config_key(platform: "Platform") -> str: """Map a Platform enum to its config.yaml key (LOCAL→"cli", rest→enum value).""" return "cli" if platform == Platform.LOCAL else platform.value @@ -1817,6 +1861,9 @@ class GatewayRunner: if canonical == "help": return await self._handle_help_command(event) + + if canonical == "commands": + return await self._handle_commands_command(event) if canonical == "status": return await self._handle_status_command(event) @@ -1974,6 +2021,12 @@ class GatewayRunner: if msg: event.text = msg # Fall through to normal message processing with skill content + else: + # Not an active skill — check if it's a known-but-disabled or + # uninstalled skill and give actionable guidance. + _unavail_msg = _check_unavailable_skill(command) + if _unavail_msg: + return _unavail_msg except Exception as e: logger.debug("Skill command check failed (non-fatal): %s", e) @@ -3065,12 +3118,69 @@ class GatewayRunner: from agent.skill_commands import get_skill_commands skill_cmds = get_skill_commands() if skill_cmds: - lines.append(f"\n⚡ **Skill Commands** ({len(skill_cmds)} installed):") - for cmd in sorted(skill_cmds): + lines.append(f"\n⚡ **Skill Commands** ({len(skill_cmds)} active):") + # Show first 10, then point to /commands for the rest + sorted_cmds = sorted(skill_cmds) + for cmd in sorted_cmds[:10]: lines.append(f"`{cmd}` — {skill_cmds[cmd]['description']}") + if len(sorted_cmds) > 10: + lines.append(f"\n... and {len(sorted_cmds) - 10} more. Use `/commands` for the full paginated list.") except Exception: pass return "\n".join(lines) + + async def _handle_commands_command(self, event: MessageEvent) -> str: + """Handle /commands [page] - paginated list of all commands and skills.""" + from hermes_cli.commands import gateway_help_lines + + raw_args = event.get_command_args().strip() + if raw_args: + try: + requested_page = int(raw_args) + except ValueError: + return "Usage: `/commands [page]`" + else: + requested_page = 1 + + # Build combined entry list: built-in commands + skill commands + entries = list(gateway_help_lines()) + try: + from agent.skill_commands import get_skill_commands + skill_cmds = get_skill_commands() + if skill_cmds: + entries.append("") + entries.append("⚡ **Skill Commands**:") + for cmd in sorted(skill_cmds): + desc = skill_cmds[cmd].get("description", "").strip() or "Skill command" + entries.append(f"`{cmd}` — {desc}") + except Exception: + pass + + if not entries: + return "No commands available." + + from gateway.config import Platform + page_size = 15 if event.source.platform == Platform.TELEGRAM else 20 + total_pages = max(1, (len(entries) + page_size - 1) // page_size) + page = max(1, min(requested_page, total_pages)) + start = (page - 1) * page_size + page_entries = entries[start:start + page_size] + + lines = [ + f"📚 **Commands** ({len(entries)} total, page {page}/{total_pages})", + "", + *page_entries, + ] + if total_pages > 1: + nav_parts = [] + if page > 1: + nav_parts.append(f"`/commands {page - 1}` ← prev") + if page < total_pages: + nav_parts.append(f"next → `/commands {page + 1}`") + lines.extend(["", " | ".join(nav_parts)]) + if page != requested_page: + lines.append(f"_(Requested page {requested_page} was out of range, showing page {page}.)_") + return "\n".join(lines) async def _handle_provider_command(self, event: MessageEvent) -> str: """Handle /provider command - show available providers.""" diff --git a/hermes_cli/commands.py b/hermes_cli/commands.py index d442f7f94..b115dd6ca 100644 --- a/hermes_cli/commands.py +++ b/hermes_cli/commands.py @@ -118,6 +118,8 @@ COMMAND_REGISTRY: list[CommandDef] = [ "Tools & Skills", cli_only=True), # Info + CommandDef("commands", "Browse all commands and skills (paginated)", "Info", + gateway_only=True, args_hint="[page]"), CommandDef("help", "Show available commands", "Info"), CommandDef("usage", "Show token usage for the current session", "Info"), CommandDef("insights", "Show usage insights and analytics", "Info", @@ -361,6 +363,47 @@ def telegram_bot_commands() -> list[tuple[str, str]]: return result +def telegram_menu_commands(max_commands: int = 100) -> tuple[list[tuple[str, str]], int]: + """Return Telegram menu commands (built-in + active skills), capped to the Bot API limit. + + Built-in commands come first, then active skill commands. Commands beyond + ``max_commands`` remain callable in the gateway; they are just omitted from + Telegram's native slash-command picker. + + Returns: + (menu_commands, hidden_count) where hidden_count is the number of + commands omitted due to the cap. + """ + all_commands = list(telegram_bot_commands()) + + # Append active BUILT-IN skill commands only (not user-installed hub skills). + # User-installed skills stay accessible via /skills and by typing the command + # directly, but don't clutter the Telegram menu. + try: + from agent.skill_commands import get_skill_commands + from pathlib import Path + # The repo's built-in skills live under /skills/ + _repo_skills_dir = str(Path(__file__).resolve().parent.parent / "skills") + skill_cmds = get_skill_commands() + for cmd_key in sorted(skill_cmds): + info = skill_cmds[cmd_key] + # Only include skills whose SKILL.md is in the repo's skills/ dir + skill_path = info.get("skill_md_path", "") + if not skill_path.startswith(_repo_skills_dir): + continue + name = cmd_key.lstrip("/").replace("-", "_") + desc = info.get("description", "") + # Telegram descriptions max 256 chars + if len(desc) > 256: + desc = desc[:253] + "..." + all_commands.append((name, desc)) + except Exception: + pass + + hidden_count = max(0, len(all_commands) - max_commands) + return all_commands[:max_commands], hidden_count + + def slack_subcommand_map() -> dict[str, str]: """Return subcommand -> /command mapping for Slack /hermes handler. diff --git a/skills/inference-sh/cli/SKILL.md b/optional-skills/devops/cli/SKILL.md similarity index 100% rename from skills/inference-sh/cli/SKILL.md rename to optional-skills/devops/cli/SKILL.md diff --git a/skills/inference-sh/cli/references/app-discovery.md b/optional-skills/devops/cli/references/app-discovery.md similarity index 100% rename from skills/inference-sh/cli/references/app-discovery.md rename to optional-skills/devops/cli/references/app-discovery.md diff --git a/skills/inference-sh/cli/references/authentication.md b/optional-skills/devops/cli/references/authentication.md similarity index 100% rename from skills/inference-sh/cli/references/authentication.md rename to optional-skills/devops/cli/references/authentication.md diff --git a/skills/inference-sh/cli/references/cli-reference.md b/optional-skills/devops/cli/references/cli-reference.md similarity index 100% rename from skills/inference-sh/cli/references/cli-reference.md rename to optional-skills/devops/cli/references/cli-reference.md diff --git a/skills/inference-sh/cli/references/running-apps.md b/optional-skills/devops/cli/references/running-apps.md similarity index 100% rename from skills/inference-sh/cli/references/running-apps.md rename to optional-skills/devops/cli/references/running-apps.md diff --git a/skills/mlops/training/accelerate/SKILL.md b/optional-skills/mlops/accelerate/SKILL.md similarity index 100% rename from skills/mlops/training/accelerate/SKILL.md rename to optional-skills/mlops/accelerate/SKILL.md diff --git a/skills/mlops/training/accelerate/references/custom-plugins.md b/optional-skills/mlops/accelerate/references/custom-plugins.md similarity index 100% rename from skills/mlops/training/accelerate/references/custom-plugins.md rename to optional-skills/mlops/accelerate/references/custom-plugins.md diff --git a/skills/mlops/training/accelerate/references/megatron-integration.md b/optional-skills/mlops/accelerate/references/megatron-integration.md similarity index 100% rename from skills/mlops/training/accelerate/references/megatron-integration.md rename to optional-skills/mlops/accelerate/references/megatron-integration.md diff --git a/skills/mlops/training/accelerate/references/performance.md b/optional-skills/mlops/accelerate/references/performance.md similarity index 100% rename from skills/mlops/training/accelerate/references/performance.md rename to optional-skills/mlops/accelerate/references/performance.md diff --git a/skills/mlops/vector-databases/chroma/SKILL.md b/optional-skills/mlops/chroma/SKILL.md similarity index 100% rename from skills/mlops/vector-databases/chroma/SKILL.md rename to optional-skills/mlops/chroma/SKILL.md diff --git a/skills/mlops/vector-databases/chroma/references/integration.md b/optional-skills/mlops/chroma/references/integration.md similarity index 100% rename from skills/mlops/vector-databases/chroma/references/integration.md rename to optional-skills/mlops/chroma/references/integration.md diff --git a/skills/mlops/vector-databases/faiss/SKILL.md b/optional-skills/mlops/faiss/SKILL.md similarity index 100% rename from skills/mlops/vector-databases/faiss/SKILL.md rename to optional-skills/mlops/faiss/SKILL.md diff --git a/skills/mlops/vector-databases/faiss/references/index_types.md b/optional-skills/mlops/faiss/references/index_types.md similarity index 100% rename from skills/mlops/vector-databases/faiss/references/index_types.md rename to optional-skills/mlops/faiss/references/index_types.md diff --git a/skills/mlops/training/flash-attention/SKILL.md b/optional-skills/mlops/flash-attention/SKILL.md similarity index 100% rename from skills/mlops/training/flash-attention/SKILL.md rename to optional-skills/mlops/flash-attention/SKILL.md diff --git a/skills/mlops/training/flash-attention/references/benchmarks.md b/optional-skills/mlops/flash-attention/references/benchmarks.md similarity index 100% rename from skills/mlops/training/flash-attention/references/benchmarks.md rename to optional-skills/mlops/flash-attention/references/benchmarks.md diff --git a/skills/mlops/training/flash-attention/references/transformers-integration.md b/optional-skills/mlops/flash-attention/references/transformers-integration.md similarity index 100% rename from skills/mlops/training/flash-attention/references/transformers-integration.md rename to optional-skills/mlops/flash-attention/references/transformers-integration.md diff --git a/skills/mlops/training/hermes-atropos-environments/SKILL.md b/optional-skills/mlops/hermes-atropos-environments/SKILL.md similarity index 100% rename from skills/mlops/training/hermes-atropos-environments/SKILL.md rename to optional-skills/mlops/hermes-atropos-environments/SKILL.md diff --git a/skills/mlops/training/hermes-atropos-environments/references/agentresult-fields.md b/optional-skills/mlops/hermes-atropos-environments/references/agentresult-fields.md similarity index 100% rename from skills/mlops/training/hermes-atropos-environments/references/agentresult-fields.md rename to optional-skills/mlops/hermes-atropos-environments/references/agentresult-fields.md diff --git a/skills/mlops/training/hermes-atropos-environments/references/atropos-base-env.md b/optional-skills/mlops/hermes-atropos-environments/references/atropos-base-env.md similarity index 100% rename from skills/mlops/training/hermes-atropos-environments/references/atropos-base-env.md rename to optional-skills/mlops/hermes-atropos-environments/references/atropos-base-env.md diff --git a/skills/mlops/training/hermes-atropos-environments/references/usage-patterns.md b/optional-skills/mlops/hermes-atropos-environments/references/usage-patterns.md similarity index 100% rename from skills/mlops/training/hermes-atropos-environments/references/usage-patterns.md rename to optional-skills/mlops/hermes-atropos-environments/references/usage-patterns.md diff --git a/skills/mlops/evaluation/huggingface-tokenizers/SKILL.md b/optional-skills/mlops/huggingface-tokenizers/SKILL.md similarity index 100% rename from skills/mlops/evaluation/huggingface-tokenizers/SKILL.md rename to optional-skills/mlops/huggingface-tokenizers/SKILL.md diff --git a/skills/mlops/evaluation/huggingface-tokenizers/references/algorithms.md b/optional-skills/mlops/huggingface-tokenizers/references/algorithms.md similarity index 100% rename from skills/mlops/evaluation/huggingface-tokenizers/references/algorithms.md rename to optional-skills/mlops/huggingface-tokenizers/references/algorithms.md diff --git a/skills/mlops/evaluation/huggingface-tokenizers/references/integration.md b/optional-skills/mlops/huggingface-tokenizers/references/integration.md similarity index 100% rename from skills/mlops/evaluation/huggingface-tokenizers/references/integration.md rename to optional-skills/mlops/huggingface-tokenizers/references/integration.md diff --git a/skills/mlops/evaluation/huggingface-tokenizers/references/pipeline.md b/optional-skills/mlops/huggingface-tokenizers/references/pipeline.md similarity index 100% rename from skills/mlops/evaluation/huggingface-tokenizers/references/pipeline.md rename to optional-skills/mlops/huggingface-tokenizers/references/pipeline.md diff --git a/skills/mlops/evaluation/huggingface-tokenizers/references/training.md b/optional-skills/mlops/huggingface-tokenizers/references/training.md similarity index 100% rename from skills/mlops/evaluation/huggingface-tokenizers/references/training.md rename to optional-skills/mlops/huggingface-tokenizers/references/training.md diff --git a/skills/mlops/inference/instructor/SKILL.md b/optional-skills/mlops/instructor/SKILL.md similarity index 100% rename from skills/mlops/inference/instructor/SKILL.md rename to optional-skills/mlops/instructor/SKILL.md diff --git a/skills/mlops/inference/instructor/references/examples.md b/optional-skills/mlops/instructor/references/examples.md similarity index 100% rename from skills/mlops/inference/instructor/references/examples.md rename to optional-skills/mlops/instructor/references/examples.md diff --git a/skills/mlops/inference/instructor/references/providers.md b/optional-skills/mlops/instructor/references/providers.md similarity index 100% rename from skills/mlops/inference/instructor/references/providers.md rename to optional-skills/mlops/instructor/references/providers.md diff --git a/skills/mlops/inference/instructor/references/validation.md b/optional-skills/mlops/instructor/references/validation.md similarity index 100% rename from skills/mlops/inference/instructor/references/validation.md rename to optional-skills/mlops/instructor/references/validation.md diff --git a/skills/mlops/cloud/lambda-labs/SKILL.md b/optional-skills/mlops/lambda-labs/SKILL.md similarity index 100% rename from skills/mlops/cloud/lambda-labs/SKILL.md rename to optional-skills/mlops/lambda-labs/SKILL.md diff --git a/skills/mlops/cloud/lambda-labs/references/advanced-usage.md b/optional-skills/mlops/lambda-labs/references/advanced-usage.md similarity index 100% rename from skills/mlops/cloud/lambda-labs/references/advanced-usage.md rename to optional-skills/mlops/lambda-labs/references/advanced-usage.md diff --git a/skills/mlops/cloud/lambda-labs/references/troubleshooting.md b/optional-skills/mlops/lambda-labs/references/troubleshooting.md similarity index 100% rename from skills/mlops/cloud/lambda-labs/references/troubleshooting.md rename to optional-skills/mlops/lambda-labs/references/troubleshooting.md diff --git a/skills/mlops/models/llava/SKILL.md b/optional-skills/mlops/llava/SKILL.md similarity index 100% rename from skills/mlops/models/llava/SKILL.md rename to optional-skills/mlops/llava/SKILL.md diff --git a/skills/mlops/models/llava/references/training.md b/optional-skills/mlops/llava/references/training.md similarity index 100% rename from skills/mlops/models/llava/references/training.md rename to optional-skills/mlops/llava/references/training.md diff --git a/skills/mlops/evaluation/nemo-curator/SKILL.md b/optional-skills/mlops/nemo-curator/SKILL.md similarity index 100% rename from skills/mlops/evaluation/nemo-curator/SKILL.md rename to optional-skills/mlops/nemo-curator/SKILL.md diff --git a/skills/mlops/evaluation/nemo-curator/references/deduplication.md b/optional-skills/mlops/nemo-curator/references/deduplication.md similarity index 100% rename from skills/mlops/evaluation/nemo-curator/references/deduplication.md rename to optional-skills/mlops/nemo-curator/references/deduplication.md diff --git a/skills/mlops/evaluation/nemo-curator/references/filtering.md b/optional-skills/mlops/nemo-curator/references/filtering.md similarity index 100% rename from skills/mlops/evaluation/nemo-curator/references/filtering.md rename to optional-skills/mlops/nemo-curator/references/filtering.md diff --git a/skills/mlops/vector-databases/pinecone/SKILL.md b/optional-skills/mlops/pinecone/SKILL.md similarity index 100% rename from skills/mlops/vector-databases/pinecone/SKILL.md rename to optional-skills/mlops/pinecone/SKILL.md diff --git a/skills/mlops/vector-databases/pinecone/references/deployment.md b/optional-skills/mlops/pinecone/references/deployment.md similarity index 100% rename from skills/mlops/vector-databases/pinecone/references/deployment.md rename to optional-skills/mlops/pinecone/references/deployment.md diff --git a/skills/mlops/training/pytorch-lightning/SKILL.md b/optional-skills/mlops/pytorch-lightning/SKILL.md similarity index 100% rename from skills/mlops/training/pytorch-lightning/SKILL.md rename to optional-skills/mlops/pytorch-lightning/SKILL.md diff --git a/skills/mlops/training/pytorch-lightning/references/callbacks.md b/optional-skills/mlops/pytorch-lightning/references/callbacks.md similarity index 100% rename from skills/mlops/training/pytorch-lightning/references/callbacks.md rename to optional-skills/mlops/pytorch-lightning/references/callbacks.md diff --git a/skills/mlops/training/pytorch-lightning/references/distributed.md b/optional-skills/mlops/pytorch-lightning/references/distributed.md similarity index 100% rename from skills/mlops/training/pytorch-lightning/references/distributed.md rename to optional-skills/mlops/pytorch-lightning/references/distributed.md diff --git a/skills/mlops/training/pytorch-lightning/references/hyperparameter-tuning.md b/optional-skills/mlops/pytorch-lightning/references/hyperparameter-tuning.md similarity index 100% rename from skills/mlops/training/pytorch-lightning/references/hyperparameter-tuning.md rename to optional-skills/mlops/pytorch-lightning/references/hyperparameter-tuning.md diff --git a/skills/mlops/vector-databases/qdrant/SKILL.md b/optional-skills/mlops/qdrant/SKILL.md similarity index 100% rename from skills/mlops/vector-databases/qdrant/SKILL.md rename to optional-skills/mlops/qdrant/SKILL.md diff --git a/skills/mlops/vector-databases/qdrant/references/advanced-usage.md b/optional-skills/mlops/qdrant/references/advanced-usage.md similarity index 100% rename from skills/mlops/vector-databases/qdrant/references/advanced-usage.md rename to optional-skills/mlops/qdrant/references/advanced-usage.md diff --git a/skills/mlops/vector-databases/qdrant/references/troubleshooting.md b/optional-skills/mlops/qdrant/references/troubleshooting.md similarity index 100% rename from skills/mlops/vector-databases/qdrant/references/troubleshooting.md rename to optional-skills/mlops/qdrant/references/troubleshooting.md diff --git a/skills/mlops/evaluation/saelens/SKILL.md b/optional-skills/mlops/saelens/SKILL.md similarity index 100% rename from skills/mlops/evaluation/saelens/SKILL.md rename to optional-skills/mlops/saelens/SKILL.md diff --git a/skills/mlops/evaluation/saelens/references/README.md b/optional-skills/mlops/saelens/references/README.md similarity index 100% rename from skills/mlops/evaluation/saelens/references/README.md rename to optional-skills/mlops/saelens/references/README.md diff --git a/skills/mlops/evaluation/saelens/references/api.md b/optional-skills/mlops/saelens/references/api.md similarity index 100% rename from skills/mlops/evaluation/saelens/references/api.md rename to optional-skills/mlops/saelens/references/api.md diff --git a/skills/mlops/evaluation/saelens/references/tutorials.md b/optional-skills/mlops/saelens/references/tutorials.md similarity index 100% rename from skills/mlops/evaluation/saelens/references/tutorials.md rename to optional-skills/mlops/saelens/references/tutorials.md diff --git a/skills/mlops/training/simpo/SKILL.md b/optional-skills/mlops/simpo/SKILL.md similarity index 100% rename from skills/mlops/training/simpo/SKILL.md rename to optional-skills/mlops/simpo/SKILL.md diff --git a/skills/mlops/training/simpo/references/datasets.md b/optional-skills/mlops/simpo/references/datasets.md similarity index 100% rename from skills/mlops/training/simpo/references/datasets.md rename to optional-skills/mlops/simpo/references/datasets.md diff --git a/skills/mlops/training/simpo/references/hyperparameters.md b/optional-skills/mlops/simpo/references/hyperparameters.md similarity index 100% rename from skills/mlops/training/simpo/references/hyperparameters.md rename to optional-skills/mlops/simpo/references/hyperparameters.md diff --git a/skills/mlops/training/simpo/references/loss-functions.md b/optional-skills/mlops/simpo/references/loss-functions.md similarity index 100% rename from skills/mlops/training/simpo/references/loss-functions.md rename to optional-skills/mlops/simpo/references/loss-functions.md diff --git a/skills/mlops/training/slime/SKILL.md b/optional-skills/mlops/slime/SKILL.md similarity index 100% rename from skills/mlops/training/slime/SKILL.md rename to optional-skills/mlops/slime/SKILL.md diff --git a/skills/mlops/training/slime/references/api-reference.md b/optional-skills/mlops/slime/references/api-reference.md similarity index 100% rename from skills/mlops/training/slime/references/api-reference.md rename to optional-skills/mlops/slime/references/api-reference.md diff --git a/skills/mlops/training/slime/references/troubleshooting.md b/optional-skills/mlops/slime/references/troubleshooting.md similarity index 100% rename from skills/mlops/training/slime/references/troubleshooting.md rename to optional-skills/mlops/slime/references/troubleshooting.md diff --git a/skills/mlops/inference/tensorrt-llm/SKILL.md b/optional-skills/mlops/tensorrt-llm/SKILL.md similarity index 100% rename from skills/mlops/inference/tensorrt-llm/SKILL.md rename to optional-skills/mlops/tensorrt-llm/SKILL.md diff --git a/skills/mlops/inference/tensorrt-llm/references/multi-gpu.md b/optional-skills/mlops/tensorrt-llm/references/multi-gpu.md similarity index 100% rename from skills/mlops/inference/tensorrt-llm/references/multi-gpu.md rename to optional-skills/mlops/tensorrt-llm/references/multi-gpu.md diff --git a/skills/mlops/inference/tensorrt-llm/references/optimization.md b/optional-skills/mlops/tensorrt-llm/references/optimization.md similarity index 100% rename from skills/mlops/inference/tensorrt-llm/references/optimization.md rename to optional-skills/mlops/tensorrt-llm/references/optimization.md diff --git a/skills/mlops/inference/tensorrt-llm/references/serving.md b/optional-skills/mlops/tensorrt-llm/references/serving.md similarity index 100% rename from skills/mlops/inference/tensorrt-llm/references/serving.md rename to optional-skills/mlops/tensorrt-llm/references/serving.md diff --git a/skills/mlops/training/torchtitan/SKILL.md b/optional-skills/mlops/torchtitan/SKILL.md similarity index 100% rename from skills/mlops/training/torchtitan/SKILL.md rename to optional-skills/mlops/torchtitan/SKILL.md diff --git a/skills/mlops/training/torchtitan/references/checkpoint.md b/optional-skills/mlops/torchtitan/references/checkpoint.md similarity index 100% rename from skills/mlops/training/torchtitan/references/checkpoint.md rename to optional-skills/mlops/torchtitan/references/checkpoint.md diff --git a/skills/mlops/training/torchtitan/references/custom-models.md b/optional-skills/mlops/torchtitan/references/custom-models.md similarity index 100% rename from skills/mlops/training/torchtitan/references/custom-models.md rename to optional-skills/mlops/torchtitan/references/custom-models.md diff --git a/skills/mlops/training/torchtitan/references/float8.md b/optional-skills/mlops/torchtitan/references/float8.md similarity index 100% rename from skills/mlops/training/torchtitan/references/float8.md rename to optional-skills/mlops/torchtitan/references/float8.md diff --git a/skills/mlops/training/torchtitan/references/fsdp.md b/optional-skills/mlops/torchtitan/references/fsdp.md similarity index 100% rename from skills/mlops/training/torchtitan/references/fsdp.md rename to optional-skills/mlops/torchtitan/references/fsdp.md diff --git a/skills/research/domain-intel/SKILL.md b/optional-skills/research/domain-intel/SKILL.md similarity index 100% rename from skills/research/domain-intel/SKILL.md rename to optional-skills/research/domain-intel/SKILL.md diff --git a/skills/research/domain-intel/scripts/domain_intel.py b/optional-skills/research/domain-intel/scripts/domain_intel.py similarity index 100% rename from skills/research/domain-intel/scripts/domain_intel.py rename to optional-skills/research/domain-intel/scripts/domain_intel.py diff --git a/skills/research/duckduckgo-search/SKILL.md b/optional-skills/research/duckduckgo-search/SKILL.md similarity index 100% rename from skills/research/duckduckgo-search/SKILL.md rename to optional-skills/research/duckduckgo-search/SKILL.md diff --git a/skills/research/duckduckgo-search/scripts/duckduckgo.sh b/optional-skills/research/duckduckgo-search/scripts/duckduckgo.sh similarity index 100% rename from skills/research/duckduckgo-search/scripts/duckduckgo.sh rename to optional-skills/research/duckduckgo-search/scripts/duckduckgo.sh