Class: Prescient::CLI

Inherits:
Object
  • Object
show all
Defined in:
lib/prescient/cli.rb

Overview

Command-line interface for common Prescient operations.

Defined Under Namespace

Classes: UsageError

Constant Summary collapse

FORMATS =

Supported output formats.

Returns:

  • (Array<String>)

    Output format names

['text', 'json'].freeze
CONFIGURATION_EXAMPLE =

Schema URL and annotated starter configuration for config example.

<<~YAML
  # yaml-language-server: $schema=https://raw.githubusercontent.com/kanutocd/prescient/refs/heads/main/schema/prescient.configuration.schema.json
  #
  # Prescient configuration example.
  #
  # Precedence, from lowest to highest:
  # 1. Built-in defaults and provider environment variables.
  # 2. Values in this YAML file.
  # 3. Per-operation CLI overrides such as --provider and --chat-model.
  #
  # Use `prescient config validate` after editing this file.
  # Keep credentials out of source control; use *_env references instead.
  version: 1

  # Global behavior.
  default_provider: ollama
  timeout: 30
  retry_attempts: 3
  retry_delay: 1.0
  fallback_providers: []
  sensitive_keys:
    - api_key
    - password
    - token
    - secret

  providers:
    # Local Ollama requires no API key.
    ollama:
      type: ollama
      url: http://localhost:11434
      embedding_model: nomic-embed-text
      chat_model: llama3.2:3b
      # prompt_templates:
      #   system_prompt: You are a concise assistant.
      #   no_context_template: "%<system_prompt>s\\n\\nUser: %<query>s"
      #   with_context_template: "%<system_prompt>s\\n\\nContext:\\n%<context>s\\n\\nUser: %<query>s"

    # Uncomment a cloud provider and set its credential in the environment.
    # openai:
    #   type: openai
    #   api_key_env: OPENAI_API_KEY
    #   embedding_model: text-embedding-3-small
    #   chat_model: gpt-4.1-mini
    #   prompt_templates:
    #     system_prompt: You are a concise assistant.
    #     no_context_template: "%<system_prompt>s\n\nUser: %<query>s"

    # anthropic:
    #   type: anthropic
    #   api_key_env: ANTHROPIC_API_KEY
    #   model: claude-sonnet-4-20250514

    # gemini:
    #   type: gemini
    #   api_key_env: GEMINI_API_KEY
    #   embedding_model: gemini-embedding-001
    #   chat_model: gemini-2.5-flash

    # mistral:
    #   type: mistral
    #   api_key_env: MISTRAL_API_KEY
    #   embedding_model: mistral-embed
    #   chat_model: mistral-large-latest

    # DeepSeek supports text generation, but not embeddings.
    # deepseek:
    #   type: deepseek
    #   api_key_env: DEEPSEEK_API_KEY
    #   chat_model: deepseek-v4-flash

    # xai:
    #   type: xai
    #   api_key_env: XAI_API_KEY
    #   chat_model: grok-4.5

    # huggingface:
    #   type: huggingface
    #   api_key_env: HUGGINGFACE_API_KEY
    #   embedding_model: sentence-transformers/all-MiniLM-L6-v2
    #   chat_model: google/gemma-2-2b-it
YAML

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arguments, input:, output:, errors:) ⇒ CLI

Initialize a CLI runner with injectable streams.

Parameters:

  • arguments (Array<String>)

    Command-line arguments

  • input (IO)

    Input stream used for stdin prompts

  • output (IO)

    Output stream for command results

  • errors (IO)

    Output stream for diagnostics



123
124
125
126
127
128
# File 'lib/prescient/cli.rb', line 123

def initialize(arguments, input:, output:, errors:)
  @arguments = arguments.dup
  @input = input
  @output = output
  @errors = errors
end

Class Method Details

.run(arguments, input: $stdin, output: $stdout, errors: $stderr) ⇒ Integer

Run the CLI and return a process exit status.

Parameters:

  • arguments (Array<String>)

    Command-line arguments

  • input (IO) (defaults to: $stdin)

    Input stream used for stdin prompts

  • output (IO) (defaults to: $stdout)

    Output stream for command results

  • errors (IO) (defaults to: $stderr)

    Output stream for diagnostics

Returns:

  • (Integer)

    Process exit status



107
108
109
110
111
112
113
114
115
# File 'lib/prescient/cli.rb', line 107

def self.run(arguments, input: $stdin, output: $stdout, errors: $stderr)
  new(arguments, input:, output:, errors:).run
rescue UsageError, OptionParser::ParseError => e
  errors.puts "prescient: #{e.message}"
  2
rescue Prescient::Error => e
  errors.puts "prescient: #{e.message}"
  1
end

Instance Method Details

#runInteger

Execute the CLI command and return its process status.

Returns:

  • (Integer)

    Process exit status



132
133
134
135
136
137
138
139
140
# File 'lib/prescient/cli.rb', line 132

def run
  config_path = extract_global_config_path
  Prescient.load_configuration(config_path) if config_path || ENV['PRESCIENT_CONFIG']

  command = @arguments.shift
  return print_help(2) unless command

  run_command(command)
end

#run_command(command) ⇒ Integer

Dispatch a parsed command to its handler.

Parameters:

  • command (String)

    Command name

Returns:

  • (Integer)

    Process exit status



145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/prescient/cli.rb', line 145

def run_command(command)
  case command
  when 'providers' then providers
  when 'health' then health
  when 'generate' then generate
  when 'embed' then embed
  when 'config' then config
  when 'help', '--help', '-h' then print_help(0)
  else
    raise UsageError, "unknown command #{command.inspect}; run 'prescient help'"
  end
end