Class: Rubino::CLI::Chat::CompletionBuilder
- Inherits:
-
Object
- Object
- Rubino::CLI::Chat::CompletionBuilder
- Defined in:
- lib/rubino/cli/chat/completion_builder.rb
Overview
Builds the composer’s CompletionSource: the ‘/command` + `@file` candidates plus the per-command ARGUMENT grammars (the dropdown that completes the argument of /skills, /agents, /mcp, /sessions, /memory, /config, … the same way it completes a command or a file). Extracted out of ChatCommand — a self-contained candidate/data-generation block (#17 collaborator pattern).
Given the command loader it needs; every source is best-effort (a DB or registry hiccup degrades to no candidates, never a broken prompt) and read lazily on each dropdown open so a /model, /config or skill change is reflected immediately.
Constant Summary collapse
- AGENTS_SUBCOMMANDS =
The /agents subcommand grammar offered by the dropdown (#39): first an id, then what you can do to it.
["steer", "probe", "--stop"].freeze
- MCP_SUBCOMMANDS =
The /mcp subcommand grammar (#182): configured server names + reload first, then the on/off verbs for a named server.
%w[on off].freeze
- SESSIONS_SUBCOMMANDS =
The /sessions subcommand grammar (#183): verbs + recent session ids first (bare id resumes, verb then id shows/deletes), then ids after a verb. Mirrors the /agents grammar so the picker teaches the surface.
["show", "delete", "--all"].freeze
- MEMORY_SUBCOMMANDS =
The /memory subcommand grammar (#184): verbs first, then recent fact ids after show/forget (short ids — the store resolves prefixes) or the registered backend names after backend.
["search", "show", "forget", "backend", "--all"].freeze
- SKILLS_SUBCOMMANDS =
The /skills grammar (#188): position one mixes the ‘✗ none` clear entry (CompletionSource keeps its special matching), the enable/disable verbs and the activate-by-name skill list; after a toggle verb, the names complete again. Activate-by-name and `✗ none` behave exactly as before.
%w[enable disable].freeze
- CONFIG_SUBCOMMANDS =
The /config grammar (#187): verbs + the known config keys first (a bare key gets, key+value sets), keys again after get/set.
%w[get set show path].freeze
Instance Method Summary collapse
- #build ⇒ Object
-
#initialize(cmd_loader) ⇒ CompletionBuilder
constructor
A new instance of CompletionBuilder.
Constructor Details
#initialize(cmd_loader) ⇒ CompletionBuilder
Returns a new instance of CompletionBuilder.
45 46 47 |
# File 'lib/rubino/cli/chat/completion_builder.rb', line 45 def initialize(cmd_loader) @cmd_loader = cmd_loader end |
Instance Method Details
#build ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/rubino/cli/chat/completion_builder.rb', line 49 def build custom = begin @cmd_loader.names rescue StandardError [] end names = (::Rubino::Commands::BuiltIns::NAMES + custom).uniq files = -> { Rubino::Workspace.primary_root } # ARGUMENT sources: the dropdown completes the argument of these commands # the same way it completes `/command` and `@file`. # * /skills <partial> — a skill name (lazily re-read each open so a # freshly-authored skill appears), TRUST-aligned with the prompt # assembler (#63) so the picker never offers a skill that won't pin. # * /agents (alias /tasks) — the live subagent ids, then the # steer/probe/--stop subcommand grammar, so the comm surface is # discoverable from the composer (#39). # * /reply — the ids of children blocked waiting on the human. # * /mcp — the configured server names (+ reload), then on/off for a # named server (#182), same grammar shape as /agents. # * /mode, /reasoning, /think — the closed enums (#185), via the # positional shape so no `✗ none` clear entry is injected (there # is no "clear" for a mode — see CompletionSource#initialize). # * /model — the ruby_llm-registry model ids for the active provider # (empty for custom backends like minimax/gateway, which aren't # enumerable — the dropdown just shows nothing extra there). # * /add-dir — filesystem DIRECTORY candidates from the typed # partial (#185), via the partial-aware two-arg shape. # * /sessions, /memory — verbs + recent ids (#183/#184), the same # per-position grammar /agents ships. # * /jobs — recent job ids (#187); /config — the get/set/show/path # verbs + the known config keys flattened from the defaults tree. # * /skills — the `✗ none` clear entry + the enable/disable verbs + # the skill names (#188); after a toggle verb, the names again. arg_sources = { "skills" => ->(args) { skills_arg_candidates(args) }, "agents" => ->(args) { agents_arg_candidates(args) }, "tasks" => ->(args) { agents_arg_candidates(args) }, "reply" => ->(args) { args.empty? ? blocked_subagent_ids : [] }, "mcp" => ->(args) { mcp_arg_candidates(args) }, "mode" => ->(args) { args.empty? ? Rubino::Modes::ALL.map(&:to_s) : [] }, "model" => ->(args) { args.empty? ? model_arg_candidates : [] }, "reasoning" => ->(args) { args.empty? ? Rubino::Config::ReasoningPrefs::RENDER_MODES.map(&:to_s) : [] }, "think" => ->(args) { args.empty? ? Rubino::Config::ReasoningPrefs::EFFORTS.map(&:to_s) : [] }, "add-dir" => lambda { |args, partial| args.empty? ? Rubino::UI::CompletionSource.directory_candidates(partial) : [] }, "sessions" => ->(args) { sessions_arg_candidates(args) }, "memory" => ->(args) { memory_arg_candidates(args) }, "jobs" => ->(args) { args.empty? ? recent_job_ids : [] }, "config" => ->(args) { config_arg_candidates(args) } } Rubino::UI::CompletionSource.new(commands: names, files: files, arg_sources: arg_sources, descriptions: completion_descriptions) end |