Class: LanguageOperator::Client::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/language_operator/client/config.rb

Overview

Configuration management for Langop MCP Client

Handles loading configuration from YAML files or environment variables, with automatic provider detection and sensible defaults.

Examples:

Load from YAML file

config = Config.load('/path/to/config.yaml')

Load from environment variables

config = Config.from_env

Load with fallback

config = Config.load_with_fallback('/path/to/config.yaml')

Class Method Summary collapse

Class Method Details

.default_model_from_envString

Get default model for detected provider

Returns:

  • Default model name



98
99
100
101
102
103
104
# File 'lib/language_operator/client/config.rb', line 98

def self.default_model_from_env
  {
    'openai' => 'gpt-4',
    'openai_compatible' => 'gpt-3.5-turbo',
    'anthropic' => 'claude-3-5-sonnet-20241022'
  }[detect_provider_from_env]
end

.detect_provider_from_envString

Detect LLM provider from environment variables

Returns:

  • Provider name (openai_compatible, openai, or anthropic)

Raises:

  • If no API key or endpoint is found



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/language_operator/client/config.rb', line 82

def self.detect_provider_from_env
  if LanguageOperator::Config.set?('OPENAI_ENDPOINT', 'MODEL_ENDPOINTS')
    'openai_compatible'
  elsif LanguageOperator::Config.set?('OPENAI_API_KEY')
    'openai'
  elsif LanguageOperator::Config.set?('ANTHROPIC_API_KEY')
    'anthropic'
  else
    raise 'No API key or endpoint found. Set OPENAI_ENDPOINT or MODEL_ENDPOINTS for local LLM, ' \
          'or OPENAI_API_KEY/ANTHROPIC_API_KEY for cloud providers.'
  end
end

.from_envHash

Load configuration from environment variables

Returns:

  • Configuration hash built from ENV



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/language_operator/client/config.rb', line 36

def self.from_env
  {
    'llm' => {
      'provider' => detect_provider_from_env,
      'model' => LanguageOperator::Config.get('LLM_MODEL', default: default_model_from_env),
      'endpoint' => parse_model_endpoint_from_env,
      'api_key' => LanguageOperator::Config.get('OPENAI_API_KEY', 'ANTHROPIC_API_KEY',
                                                default: 'dummy-key-for-local-proxy')
    },
    'mcp_servers' => parse_mcp_servers_from_env,
    'debug' => LanguageOperator::Config.get_bool('DEBUG', default: false)
  }
end

.load(path) ⇒ Hash

Load configuration from a YAML file

Parameters:

  • Path to YAML configuration file

Returns:

  • Configuration hash

Raises:

  • If file doesn't exist



26
27
28
29
30
31
# File 'lib/language_operator/client/config.rb', line 26

def self.load(path)
  config = YAML.safe_load_file(path, permitted_classes: [Symbol], aliases: true)
  # Normalize structure to ensure defaults
  config['mcp_servers'] ||= []
  config
end

.load_with_fallback(path) ⇒ Hash

Load configuration with automatic fallback to environment variables

Parameters:

  • Path to YAML configuration file

Returns:

  • Configuration hash



68
69
70
71
72
73
74
75
76
# File 'lib/language_operator/client/config.rb', line 68

def self.load_with_fallback(path)
  return from_env unless File.exist?(path)

  load(path)
rescue StandardError => e
  warn "⚠️  Error loading config from #{path}: #{e.message}"
  warn 'Using environment variable fallback mode...'
  from_env
end

.parse_mcp_servers_from_envArray<Hash>

Parse MCP servers from environment variables

Supports MCP_SERVERS env var as comma-separated URLs or single MCP_URL

Returns:

  • Array of MCP server configurations



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/language_operator/client/config.rb', line 111

def self.parse_mcp_servers_from_env
  # Support both MCP_SERVERS (comma-separated) and legacy MCP_URL
  servers = LanguageOperator::Config.get_array('MCP_SERVERS')

  if !servers.empty?
    # Parse comma-separated URLs
    servers.map.with_index do |url, index|
      {
        'name' => "default-tools-#{index}",
        'url' => url,
        'transport' => 'streamable',
        'enabled' => true
      }
    end
  elsif (url = LanguageOperator::Config.get('MCP_URL'))
    [{
      'name' => 'default-tools',
      'url' => url,
      'transport' => 'streamable',
      'enabled' => true
    }]
  else
    []
  end
end

.parse_model_endpoint_from_envString?

Parse model endpoint from environment variable

Supports both MODEL_ENDPOINTS (comma-separated, uses first) and OPENAI_ENDPOINT

Returns:

  • Model endpoint URL



55
56
57
58
59
60
61
62
# File 'lib/language_operator/client/config.rb', line 55

def self.parse_model_endpoint_from_env
  # Support MODEL_ENDPOINTS (operator sets this) - take first from comma-separated list
  endpoints = LanguageOperator::Config.get_array('MODEL_ENDPOINTS')
  return endpoints.first unless endpoints.empty?

  # Fallback to legacy OPENAI_ENDPOINT
  LanguageOperator::Config.get('OPENAI_ENDPOINT')
end