ace-llm 0.39.2 → 0.40.0
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/.ace-defaults/llm/presets/codex/ro.yml +0 -1
- data/.ace-defaults/llm/presets/codex/rw.yml +2 -1
- data/.ace-defaults/llm/presets/pi/ro.yml +4 -0
- data/.ace-defaults/llm/thinking/pi/high.yml +3 -0
- data/.ace-defaults/llm/thinking/pi/low.yml +3 -0
- data/.ace-defaults/llm/thinking/pi/max.yml +3 -0
- data/.ace-defaults/llm/thinking/pi/medium.yml +3 -0
- data/.ace-defaults/llm/thinking/pi/xhigh.yml +3 -0
- data/CHANGELOG.md +11 -0
- data/README.md +2 -2
- data/lib/ace/llm/molecules/fallback_orchestrator.rb +2 -0
- data/lib/ace/llm/molecules/provider_model_parser.rb +1 -1
- data/lib/ace/llm/molecules/role_resolver.rb +1 -1
- data/lib/ace/llm/molecules/thinking_level_loader.rb +1 -1
- data/lib/ace/llm/query_interface.rb +62 -6
- data/lib/ace/llm/version.rb +1 -1
- data/lib/ace/llm.rb +2 -0
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48321c690b49c8d136a85e6f131328bbb4a6cfc55e504d1467c56d4d2a554092
|
|
4
|
+
data.tar.gz: 0af124c46785c2278cd5b1d10b4e5fee3b7f67ff6e446cd28e9bbe091abea429
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e13d32931c1e249cba948d8113e124fc7412462fbafd2d397f389c38effe2beadc8f7413ce7e196893680e9c27842cae15218bba6da1db5c3f5e9a085ec34aff
|
|
7
|
+
data.tar.gz: 73b5a3eab3ffeceab03a5c67631162ab245ff512e01262029b253a04bc7acad610926ce4e13c62944f618c9c03b19964ecf0af2ffd9adfec8d7fce23a5bca9f5
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.40.0] - 2026-09-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Update Codex CLI presets for the new `codex exec` interface: replace the
|
|
15
|
+
removed `--full-auto` flag with explicit `--sandbox read-only` (ro) and
|
|
16
|
+
`--sandbox workspace-write` (rw); `yolo` keeps
|
|
17
|
+
`--dangerously-bypass-approvals-and-sandbox`.
|
|
18
|
+
- Preserve resolved provider, model, preset and reasoning metadata for the executed request, including fallback targets.
|
|
19
|
+
- Accept `max` reasoning in selectors and Pi reasoning configuration.
|
|
20
|
+
|
|
10
21
|
## [0.39.2] - 2026-09-13
|
|
11
22
|
|
|
12
23
|
### Fixed
|
data/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Deterministic coverage lives in `test/fast/` and `test/feat/`. Scenario assets s
|
|
|
35
35
|
|
|
36
36
|
## How It Works
|
|
37
37
|
|
|
38
|
-
1. Select a model -- by alias, `provider:model`, with a thinking level suffix (`:low`/`:medium`/`:high`), or an `@preset` -- and submit a prompt.
|
|
38
|
+
1. Select a model -- by alias, `provider:model`, with a configured thinking level suffix (`:low`/`:medium`/`:high`/`:xhigh`/`:max`), or an `@preset` -- and submit a prompt.
|
|
39
39
|
2. The provider router resolves the target through [ace-llm-providers-cli](../ace-llm-providers-cli) adapters, applying fallback and retry rules from the [config cascade](../ace-support-config).
|
|
40
40
|
3. The response is returned as text, markdown, or JSON with optional token usage metadata.
|
|
41
41
|
|
|
@@ -43,7 +43,7 @@ Deterministic coverage lives in `test/fast/` and `test/feat/`. Scenario assets s
|
|
|
43
43
|
|
|
44
44
|
**Switch providers with aliases** - use short names like `gflash`, `sonnet`, `opus` instead of full `provider:model` notation. Aliases resolve through versioned YAML in [`.ace-defaults/`](docs/usage.md).
|
|
45
45
|
|
|
46
|
-
**Control reasoning depth** - append a thinking level (`codex:gpt:high`, `claude:sonnet:low`) to tune reasoning budgets. Supported CLI providers: `claude`, `codex` (
|
|
46
|
+
**Control reasoning depth** - append a thinking level (`codex:gpt:high`, `claude:sonnet:low`, `pi:glm5:max`) to tune reasoning budgets. Supported CLI providers: `claude`, `codex` (`low`, `medium`, `high`, `xhigh`) and `pi` (including `max`). Each provider/level pair requires a matching thinking configuration.
|
|
47
47
|
|
|
48
48
|
**Run preset-driven prompts** - apply execution profiles with `@preset` or `--preset`. Built-in presets for CLI providers: `@ro` (read-only), `@rw` (read-write), `@yolo` (full autonomy). Supported by: `claude`, `codex`, `gemini`, `opencode`, `pi`, `agy`.
|
|
49
49
|
|
|
@@ -33,6 +33,7 @@ module Ace
|
|
|
33
33
|
# @raise [Error] If all providers and retries exhausted
|
|
34
34
|
def execute(primary_provider:, registry:)
|
|
35
35
|
@start_time = Time.now
|
|
36
|
+
@primary_provider = primary_provider
|
|
36
37
|
@visited_providers.clear
|
|
37
38
|
|
|
38
39
|
# If fallback disabled, just execute with primary
|
|
@@ -84,6 +85,7 @@ module Ace
|
|
|
84
85
|
client = get_client(provider_name, registry)
|
|
85
86
|
return yield client, provider_name
|
|
86
87
|
rescue => error
|
|
88
|
+
raise if error.is_a?(Ace::LLM::ConfigurationError) && provider_name != @primary_provider
|
|
87
89
|
last_error = error
|
|
88
90
|
|
|
89
91
|
# Handle the error - returns :retry or :stop_and_fallback
|
|
@@ -10,7 +10,7 @@ module Ace
|
|
|
10
10
|
# ProviderModelParser handles parsing and validation of provider:model syntax
|
|
11
11
|
# for the unified LLM query interface.
|
|
12
12
|
class ProviderModelParser
|
|
13
|
-
THINKING_LEVELS = %w[low medium high xhigh].freeze
|
|
13
|
+
THINKING_LEVELS = %w[low medium high xhigh max].freeze
|
|
14
14
|
|
|
15
15
|
# Result object for parsed provider:model combinations.
|
|
16
16
|
ParseResult = Struct.new(:provider, :model, :preset, :thinking_level, :valid, :error,
|
|
@@ -8,7 +8,7 @@ module Ace
|
|
|
8
8
|
module Molecules
|
|
9
9
|
# RoleResolver maps role names to an available concrete selector.
|
|
10
10
|
class RoleResolver
|
|
11
|
-
THINKING_LEVELS = %w[low medium high xhigh].freeze
|
|
11
|
+
THINKING_LEVELS = %w[low medium high xhigh max].freeze
|
|
12
12
|
|
|
13
13
|
def initialize(registry: nil, configuration: nil)
|
|
14
14
|
@registry = registry || ClientRegistry.new
|
|
@@ -8,7 +8,7 @@ module Ace
|
|
|
8
8
|
module Molecules
|
|
9
9
|
# Loads provider-scoped thinking-level overrides from llm/thinking/*.yml.
|
|
10
10
|
class ThinkingLevelLoader
|
|
11
|
-
ALLOWED_LEVELS = %w[low medium high xhigh].freeze
|
|
11
|
+
ALLOWED_LEVELS = %w[low medium high xhigh max].freeze
|
|
12
12
|
|
|
13
13
|
class << self
|
|
14
14
|
def load_for_provider(provider, level)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "shellwords"
|
|
4
|
+
|
|
3
5
|
require_relative "molecules/client_registry"
|
|
4
6
|
require_relative "molecules/provider_model_parser"
|
|
5
7
|
require_relative "molecules/preset_loader"
|
|
@@ -145,10 +147,12 @@ module Ace
|
|
|
145
147
|
|
|
146
148
|
result = {
|
|
147
149
|
text: text_content,
|
|
148
|
-
model: final_model,
|
|
149
|
-
provider: parse_result.provider,
|
|
150
|
-
preset: resolved_preset,
|
|
151
|
-
thinking_level: parse_result.thinking_level,
|
|
150
|
+
model: response.dig(:execution, :model) || final_model,
|
|
151
|
+
provider: response.dig(:execution, :provider) || parse_result.provider,
|
|
152
|
+
preset: response.fetch(:execution, {}).fetch(:preset, resolved_preset),
|
|
153
|
+
thinking_level: response.fetch(:execution, {}).fetch(:thinking_level, parse_result.thinking_level),
|
|
154
|
+
execution: response[:execution],
|
|
155
|
+
requested_selector: provider_model,
|
|
152
156
|
usage: response[:usage],
|
|
153
157
|
metadata: response[:metadata]
|
|
154
158
|
}
|
|
@@ -364,7 +368,8 @@ module Ace
|
|
|
364
368
|
registry:, fallback_config:, timeout:, debug:, role_fallbacks: nil, preset: nil, thinking_level: nil, option_builder:)
|
|
365
369
|
if fallback_config.disabled?
|
|
366
370
|
client = registry.get_client(provider, model: model, timeout: timeout)
|
|
367
|
-
|
|
371
|
+
response = client.generate(messages, **generation_opts)
|
|
372
|
+
return response.merge(execution: execution_identity(provider, model, preset, thinking_level, response, generation_opts))
|
|
368
373
|
end
|
|
369
374
|
|
|
370
375
|
primary_provider_string = model ? "#{provider}:#{model}" : provider
|
|
@@ -391,9 +396,60 @@ module Ace
|
|
|
391
396
|
else
|
|
392
397
|
option_builder.call(target_selector)
|
|
393
398
|
end
|
|
394
|
-
|
|
399
|
+
parsed = Molecules::ProviderModelParser.new(registry: registry).parse(target_selector)
|
|
400
|
+
raise ConfigurationError, parsed.error unless parsed.valid?
|
|
401
|
+
primary = target_selector.to_s == primary_provider_string
|
|
402
|
+
response = client.generate(messages, **opts)
|
|
403
|
+
response.merge(execution: execution_identity(
|
|
404
|
+
parsed.provider, parsed.model,
|
|
405
|
+
primary ? preset : (parsed.preset || preset),
|
|
406
|
+
primary ? thinking_level : parsed.thinking_level,
|
|
407
|
+
response,
|
|
408
|
+
opts
|
|
409
|
+
))
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
# Transport identity records what ACE executed, not a provider attestation.
|
|
414
|
+
def self.execution_identity(provider, model, preset, thinking_level, response, options)
|
|
415
|
+
model ||= response.dig(:metadata, :model) || response.dig(:metadata, "model")
|
|
416
|
+
finish_reason = response.dig(:metadata, :finish_reason) || response.dig(:metadata, "finish_reason") ||
|
|
417
|
+
response.dig(:metadata, :stop_reason) || response.dig(:metadata, "stop_reason")
|
|
418
|
+
status = if Ace::LLM::SUCCESSFUL_FINISH_REASONS.include?(finish_reason.to_s.downcase)
|
|
419
|
+
"succeeded"
|
|
420
|
+
else
|
|
421
|
+
"incomplete"
|
|
422
|
+
end
|
|
423
|
+
{provider: provider, model: model, preset: preset, thinking_level: effective_thinking_level(provider, thinking_level, options),
|
|
424
|
+
identity_source: "resolved_request", status: status}
|
|
425
|
+
end
|
|
426
|
+
private_class_method :execution_identity
|
|
427
|
+
|
|
428
|
+
def self.effective_thinking_level(provider, default, options)
|
|
429
|
+
return default unless %w[pi codex].include?(provider)
|
|
430
|
+
|
|
431
|
+
args = Array(options[:cli_args]).flat_map { |arg| Shellwords.split(arg.to_s) }
|
|
432
|
+
effective = default
|
|
433
|
+
args.each_with_index do |arg, index|
|
|
434
|
+
if provider == "pi"
|
|
435
|
+
candidate = if arg == "--thinking"
|
|
436
|
+
args[index + 1]
|
|
437
|
+
elsif arg.start_with?("--thinking=")
|
|
438
|
+
arg.delete_prefix("--thinking=")
|
|
439
|
+
end
|
|
440
|
+
effective = candidate if %w[off minimal low medium high xhigh max].include?(candidate)
|
|
441
|
+
else
|
|
442
|
+
config = if %w[-c --config].include?(arg)
|
|
443
|
+
args[index + 1]
|
|
444
|
+
elsif arg.match?(/\A(?:-c|--config)=?model_reasoning_effort=/)
|
|
445
|
+
arg.sub(/\A(?:-c|--config)=?/, "")
|
|
446
|
+
end
|
|
447
|
+
effective = config.split("=", 2).last if config&.start_with?("model_reasoning_effort=")
|
|
448
|
+
end
|
|
395
449
|
end
|
|
450
|
+
effective
|
|
396
451
|
end
|
|
452
|
+
private_class_method :effective_thinking_level
|
|
397
453
|
|
|
398
454
|
def self.extract_text_content(response)
|
|
399
455
|
if response[:text]
|
data/lib/ace/llm/version.rb
CHANGED
data/lib/ace/llm.rb
CHANGED
|
@@ -55,6 +55,8 @@ module Ace
|
|
|
55
55
|
class ConfigurationError < Error; end
|
|
56
56
|
class AuthenticationError < Error; end
|
|
57
57
|
|
|
58
|
+
SUCCESSFUL_FINISH_REASONS = %w[success stop end_turn complete completed stop_sequence].freeze
|
|
59
|
+
|
|
58
60
|
# Define module namespaces
|
|
59
61
|
module Atoms; end
|
|
60
62
|
module Molecules; end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-llm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.40.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michal Czyz
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-09-
|
|
10
|
+
date: 2026-09-24 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ace-support-cli
|
|
@@ -266,6 +266,11 @@ files:
|
|
|
266
266
|
- ".ace-defaults/llm/thinking/codex/low.yml"
|
|
267
267
|
- ".ace-defaults/llm/thinking/codex/medium.yml"
|
|
268
268
|
- ".ace-defaults/llm/thinking/codex/xhigh.yml"
|
|
269
|
+
- ".ace-defaults/llm/thinking/pi/high.yml"
|
|
270
|
+
- ".ace-defaults/llm/thinking/pi/low.yml"
|
|
271
|
+
- ".ace-defaults/llm/thinking/pi/max.yml"
|
|
272
|
+
- ".ace-defaults/llm/thinking/pi/medium.yml"
|
|
273
|
+
- ".ace-defaults/llm/thinking/pi/xhigh.yml"
|
|
269
274
|
- ".ace-defaults/nav/protocols/guide-sources/ace-llm.yml"
|
|
270
275
|
- CHANGELOG.md
|
|
271
276
|
- LICENSE
|