Class: GitFit::LLM::Client
- Inherits:
-
Object
- Object
- GitFit::LLM::Client
- Defined in:
- lib/git_fit/llm/client.rb
Overview
OpenAI-compatible chat-completions client (POST #endpoint/chat/completions).
Provider-agnostic: endpoint / model / api key all come from the config
ai: section — the gem never hardcodes a vendor. Non-streaming (P1);
SSE can be layered later without changing call sites.
Instance Attribute Summary collapse
-
#endpoint ⇒ Object
readonly
Returns the value of attribute endpoint.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
Class Method Summary collapse
-
.from_config(config) ⇒ Object
Builds a client from GitFit::Config.
Instance Method Summary collapse
-
#chat(messages:, temperature: nil) ⇒ Object
messages: [{ 'role' => 'system'|'user', 'content' => '...' }, ...] Returns the assistant content string.
-
#initialize(endpoint:, model:, api_key:, timeout: 60) ⇒ Client
constructor
A new instance of Client.
Constructor Details
#initialize(endpoint:, model:, api_key:, timeout: 60) ⇒ Client
Returns a new instance of Client.
43 44 45 46 47 48 |
# File 'lib/git_fit/llm/client.rb', line 43 def initialize(endpoint:, model:, api_key:, timeout: 60) @endpoint = endpoint.to_s.sub(%r{/+\z}, '') @model = model @api_key = api_key @timeout = timeout.is_a?(Numeric) ? timeout : 60 end |
Instance Attribute Details
#endpoint ⇒ Object (readonly)
Returns the value of attribute endpoint.
14 15 16 |
# File 'lib/git_fit/llm/client.rb', line 14 def endpoint @endpoint end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
14 15 16 |
# File 'lib/git_fit/llm/client.rb', line 14 def model @model end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
14 15 16 |
# File 'lib/git_fit/llm/client.rb', line 14 def timeout @timeout end |
Class Method Details
.from_config(config) ⇒ Object
Builds a client from GitFit::Config. Returns nil when ai.enabled is false (caller decides to warn+skip); raises ConfigError with a Fix: hint when enabled but misconfigured.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/git_fit/llm/client.rb', line 19 def self.from_config(config) ai = config.ai_config return nil unless ai['enabled'] missing = %w[endpoint model].select { |k| ai[k].to_s.strip.empty? } unless missing.empty? raise ConfigError, "LLM: ai.#{missing.join(', ai.')} not configured\n" \ ' Fix: set ai.endpoint / ai.model in config.yml ' \ '(e.g. https://open.bigmodel.cn/api/paas/v4 + glm-4-flash)' end key_env = ai['api_key_env'].to_s.strip key_env = 'AI_API_KEY' if key_env.empty? api_key = ENV[key_env].to_s if api_key.empty? raise ConfigError, "LLM: env #{key_env} is empty\n" \ " Fix: export #{key_env}=<your-api-key> (local: add to .env.local and source it)" end new(endpoint: ai['endpoint'], model: ai['model'], api_key: api_key, timeout: ai['timeout']) end |
Instance Method Details
#chat(messages:, temperature: nil) ⇒ Object
messages: [{ 'role' => 'system'|'user', 'content' => '...' }, ...] Returns the assistant content string.
52 53 54 55 56 57 |
# File 'lib/git_fit/llm/client.rb', line 52 def chat(messages:, temperature: nil) payload = { model: @model, messages: } payload[:temperature] = temperature if temperature status, body = http_post(chat_completions_url, JSON.generate(payload)) parse_content(status, body) end |