legion-llm 0.5.19 → 0.5.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -10
- data/lib/legion/llm/codex_config_loader.rb +93 -0
- data/lib/legion/llm/version.rb +1 -1
- data/lib/legion/llm.rb +3 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f51b096c53558665dbfc074fa203c8624aa79444324cb686759aee35cd568ca6
|
|
4
|
+
data.tar.gz: 95c6a41fa6839d476cff0d60a6b56a1fbc7ad5be4f914f290fc877e0198e50bc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 33a939afde771b78203d7c84f3fdb9ccbe226907037bc97f86a5650324c089e1034e9de3251ea1deb72d634680b3de6e263a48bbb933648621586598d1244f16
|
|
7
|
+
data.tar.gz: d0f98e6c6dfbee9040953991e8ab3a0de88cd37ed32a352b2d6d0ef52163e120756238d7d5f96c6f00d028b25e778a2076c9012550879fba1b98b06339d5a63e
|
data/CHANGELOG.md
CHANGED
|
@@ -2,18 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- `
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- `
|
|
13
|
-
- Layered
|
|
5
|
+
## [0.5.20] - 2026-03-30
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `CodexConfigLoader`: auto-imports OpenAI bearer token from `~/.codex/auth.json` when `auth_mode` is `chatgpt` and no existing OpenAI API key is configured (#15)
|
|
9
|
+
- JWT expiry validation — expired codex tokens are skipped with a debug log (#15)
|
|
10
|
+
- Non-JWT tokens (plain API keys) accepted without validation (#15)
|
|
11
|
+
- Falls back to vault/settings/env when codex auth file is absent or token is expired (#15)
|
|
12
|
+
- `Legion::LLM::Helper` module at `lib/legion/llm/helper.rb` — canonical helper following cache/transport pattern (#20)
|
|
13
|
+
- Layered defaults: `llm_default_model`, `llm_default_provider`, `llm_default_intent` (LEX-overridable) (#20)
|
|
14
|
+
- `llm_embed_batch` — batch embedding convenience (#20)
|
|
15
|
+
- `llm_structured` — structured JSON output convenience (#20)
|
|
16
|
+
- `llm_ask` — daemon-first single-shot convenience (#20)
|
|
17
|
+
- `llm_connected?` / `llm_can_embed?` / `llm_routing_enabled?` — status helpers (#20)
|
|
18
|
+
- `llm_cost_estimate` / `llm_cost_summary` / `llm_budget_remaining` — cost and budget helpers (#20)
|
|
19
|
+
- Layered model/provider/intent defaults applied to `llm_chat` and `llm_session` (#20)
|
|
14
20
|
|
|
15
21
|
### Changed
|
|
16
|
-
- `lib/legion/llm/helpers/llm.rb` is now a backward-compat shim that includes `Legion::LLM::Helper`
|
|
22
|
+
- `lib/legion/llm/helpers/llm.rb` is now a backward-compat shim that includes `Legion::LLM::Helper` (#20)
|
|
17
23
|
|
|
18
24
|
## [0.5.18] - 2026-03-29
|
|
19
25
|
|
|
@@ -58,6 +64,10 @@
|
|
|
58
64
|
## [0.5.14] - 2026-03-27
|
|
59
65
|
|
|
60
66
|
### Added
|
|
67
|
+
- `CodexConfigLoader`: auto-imports OpenAI bearer token from `~/.codex/auth.json` when `auth_mode` is `chatgpt` and no existing OpenAI API key is configured
|
|
68
|
+
- JWT expiry validation — expired codex tokens are skipped with a debug log
|
|
69
|
+
- Non-JWT tokens (plain API keys) accepted without validation
|
|
70
|
+
- Falls back to vault/settings/env when codex auth file is absent or token is expired
|
|
61
71
|
- `DaemonClient.inference` method for conversation-level routing — accepts a full `messages:` array and optional `tools:`, `model:`, `provider:`, and `timeout:` keyword args, posts to `POST /api/llm/inference`, and returns a structured `{ status: :ok, data: { content:, tool_calls:, stop_reason:, model:, input_tokens:, output_tokens: } }` hash on success
|
|
62
72
|
- `http_post` now accepts an optional `timeout:` keyword argument (default `DEFAULT_TIMEOUT = 60`) so callers like `inference` can pass a longer timeout (120s) without affecting existing `chat` calls
|
|
63
73
|
- `interpret_inference_response` private helper that maps the `/api/llm/inference` HTTP response — 200 returns `:ok` with structured fields, 4xx/5xx follow the same error handling as `interpret_response`
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module Legion
|
|
7
|
+
module LLM
|
|
8
|
+
module CodexConfigLoader
|
|
9
|
+
CODEX_AUTH = File.expand_path('~/.codex/auth.json')
|
|
10
|
+
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
def load
|
|
14
|
+
return unless File.exist?(CODEX_AUTH)
|
|
15
|
+
|
|
16
|
+
config = read_json(CODEX_AUTH)
|
|
17
|
+
return if config.empty?
|
|
18
|
+
|
|
19
|
+
apply_codex_config(config)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def read_json(path)
|
|
23
|
+
::JSON.parse(File.read(path), symbolize_names: true)
|
|
24
|
+
rescue StandardError => e
|
|
25
|
+
Legion::Logging.debug("CodexConfigLoader could not read #{path}: #{e.message}") if defined?(Legion::Logging)
|
|
26
|
+
{}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def apply_codex_config(config)
|
|
30
|
+
return unless config[:auth_mode] == 'chatgpt'
|
|
31
|
+
|
|
32
|
+
token = config.dig(:tokens, :access_token)
|
|
33
|
+
return unless token.is_a?(String) && !token.empty?
|
|
34
|
+
|
|
35
|
+
unless token_valid?(token)
|
|
36
|
+
Legion::Logging.debug 'CodexConfigLoader: access token is expired, skipping' if defined?(Legion::Logging)
|
|
37
|
+
return
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
providers = Legion::LLM.settings[:providers]
|
|
41
|
+
existing_raw = providers.dig(:openai, :api_key)
|
|
42
|
+
resolved_existing = resolve_env_api_key(existing_raw)
|
|
43
|
+
return unless resolved_existing.nil? || (resolved_existing.respond_to?(:empty?) && resolved_existing.empty?)
|
|
44
|
+
|
|
45
|
+
providers[:openai][:api_key] = token
|
|
46
|
+
Legion::Logging.debug 'Imported OpenAI API key from Codex auth config' if defined?(Legion::Logging)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def resolve_env_api_key(value)
|
|
50
|
+
return nil if value.nil?
|
|
51
|
+
|
|
52
|
+
if value.is_a?(String)
|
|
53
|
+
return nil if value.empty?
|
|
54
|
+
|
|
55
|
+
if value.start_with?('env://')
|
|
56
|
+
env_name = value.sub('env://', '')
|
|
57
|
+
env_value = ENV.fetch(env_name, nil)
|
|
58
|
+
return nil if env_value.nil? || env_value.empty?
|
|
59
|
+
|
|
60
|
+
return env_value
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
return value
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if value.is_a?(Array)
|
|
67
|
+
resolved = value.map { |v| resolve_env_api_key(v) }.compact
|
|
68
|
+
return nil if resolved.empty?
|
|
69
|
+
return resolved.first if resolved.length == 1
|
|
70
|
+
|
|
71
|
+
return resolved
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
value
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def token_valid?(token)
|
|
78
|
+
parts = token.split('.')
|
|
79
|
+
return true unless parts.length == 3
|
|
80
|
+
|
|
81
|
+
padded = parts[1] + ('=' * ((4 - (parts[1].length % 4)) % 4))
|
|
82
|
+
payload = ::JSON.parse(Base64.urlsafe_decode64(padded), symbolize_names: true)
|
|
83
|
+
exp = payload[:exp]
|
|
84
|
+
return true unless exp.is_a?(Integer)
|
|
85
|
+
|
|
86
|
+
exp > Time.now.to_i
|
|
87
|
+
rescue StandardError => e
|
|
88
|
+
Legion::Logging.debug("CodexConfigLoader: failed to parse access token for exp validation: #{e.class}: #{e.message}") if defined?(Legion::Logging)
|
|
89
|
+
true
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
data/lib/legion/llm/version.rb
CHANGED
data/lib/legion/llm.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: legion-llm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.20
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -214,6 +214,7 @@ files:
|
|
|
214
214
|
- lib/legion/llm/bedrock_bearer_auth.rb
|
|
215
215
|
- lib/legion/llm/cache.rb
|
|
216
216
|
- lib/legion/llm/claude_config_loader.rb
|
|
217
|
+
- lib/legion/llm/codex_config_loader.rb
|
|
217
218
|
- lib/legion/llm/compressor.rb
|
|
218
219
|
- lib/legion/llm/confidence_score.rb
|
|
219
220
|
- lib/legion/llm/confidence_scorer.rb
|