Skip to main content
Glama
completer.py5.86 kB
"""Command completion functionality for the REPL.""" from typing import Dict from prompt_toolkit.completion import Completer, Completion from prompt_toolkit.document import Document from promptheus.config import Config from promptheus.history import get_history class CommandCompleter(Completer): """ Custom completer for slash commands. Shows completions when user types / with command descriptions. """ def __init__(self): self.commands = { 'about': 'Show version info', 'bug': 'Submit a bug report', 'clear-history': 'Clear all history', 'copy': 'Copy the last result to clipboard', 'exit': 'Exit Promptheus', 'help': 'Show available commands', 'history': 'View recent prompts', 'load': 'Load a prompt by number (e.g., /load 5)', 'quit': 'Exit Promptheus', 'set': 'Change provider or model (e.g., /set provider claude)', 'status': 'Show current session settings', 'toggle': 'Toggle refine or skip-questions mode (e.g., /toggle refine)', } def get_completions(self, document: Document, complete_event): """Generate completions for the current document.""" text = document.text_before_cursor # Only provide completions if text starts with / if not text.startswith('/'): return # Remove the leading / command_part = text[1:] # Split into parts, preserving empty strings parts = command_part.split() # Determine if we have a trailing space (indicates moving to next argument) has_trailing_space = command_part.endswith(' ') and command_part.strip() if not parts: # Just "/" typed, show all commands for cmd, description in self.commands.items(): yield Completion( cmd, start_position=0, display=cmd, display_meta=description, ) return command = parts[0].lower() if len(parts) == 1 and not has_trailing_space: # Completing the command itself search_term = command for cmd, description in self.commands.items(): if cmd.startswith(search_term): yield Completion( cmd, start_position=-len(search_term), display=cmd, display_meta=description, ) elif (len(parts) == 2 and has_trailing_space and command == 'set' and parts[1] == 'provider') or \ (len(parts) == 3 and command == 'set' and parts[1] == 'provider'): # Completing /set provider with available providers (must check before general case) try: config = Config() providers = config.get_configured_providers() search_term = parts[2] if len(parts) == 3 else '' for provider in providers: if provider.startswith(search_term): yield Completion( provider, start_position=-len(search_term), display=provider, display_meta=f'Switch to {provider}', ) except Exception: pass elif (len(parts) == 1 and has_trailing_space) or len(parts) == 2: # Completing first argument after command search_term = parts[1] if len(parts) == 2 else '' if command == 'load': # Completing /load with history indices try: history = get_history() recent = history.get_recent(20) for idx, entry in enumerate(recent, 1): idx_str = str(idx) if idx_str.startswith(search_term): preview = entry.original_prompt[:50] if len(entry.original_prompt) > 50: preview += "..." yield Completion( idx_str, start_position=-len(search_term), display=f"{idx_str}", display_meta=preview, ) except Exception: pass elif command == 'set': # Completing /set with 'provider' or 'model' subcommands = { 'provider': 'Change the AI provider', 'model': 'Change the model', } for subcmd, desc in subcommands.items(): if subcmd.startswith(search_term): yield Completion( subcmd, start_position=-len(search_term), display=subcmd, display_meta=desc, ) elif command == 'toggle': # Completing /toggle with 'refine' or 'skip-questions' subcommands = { 'refine': 'Toggle refine mode on/off', 'skip-questions': 'Toggle skip-questions mode on/off', } for subcmd, desc in subcommands.items(): if subcmd.startswith(search_term): yield Completion( subcmd, start_position=-len(search_term), display=subcmd, display_meta=desc, )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/abhichandra21/Promptheus'

If you have feedback or need assistance with the MCP directory API, please join our Discord server