miniswen 1.2.0 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de70dca3df1d5d69b884c838142ecf6143714e4160df12cd70ffd9d82d9cd823
4
- data.tar.gz: 9fc776f43acb75cd49b0b02a45dbaf2017927c2a5a9d0ac53589925b5be6cb99
3
+ metadata.gz: afa0b16ea68fbeb7398d93abdd9d1d0de12acca6979b2a201b67d4f1665b9271
4
+ data.tar.gz: 2008101aa41d05d537a06e46693572fc9e40be838973f72ad98fadf9c16dc76b
5
5
  SHA512:
6
- metadata.gz: b65975d0c54ef1588a896917dc7ee86b1c87c7a6c750d0354e6d1d8681743e20c2561890ebeefbce3cae2d96981ac5b41c26a6411b2d350653bce026ca9e730c
7
- data.tar.gz: c067f93043fd5f056a243200b08e5d92bd3c4d25356bc961ae8a377e2dc86ef91600ce9d468747f5b18daa746be2f50e87122f5ad9ea4de6827b0fb1e1727b84
6
+ metadata.gz: d54057d81a357cf52f76056a6b5a74d66a6374e0258909bb3f62e3e3e3b564ca737af5dff8e1993d4be6e55c59cf9b2b9580f94715efdf4f9b2ea3514a9e7fca
7
+ data.tar.gz: 4cfa2b0502e9ed81f9e383c9b29536f0aa529a930c1a2ac881f9f1a821265085bfc675229a4340269df64644d4276ed9aff47cf30d18875f2c7d7ce1f0550a77
data/README.md CHANGED
@@ -142,7 +142,7 @@ A minimal task example—checking whether an agent can write "Hello, world" into
142
142
  +Hello, world
143
143
  ```
144
144
 
145
- - `verification_test.rb`: a Ruby test that grades the solution (pass → 1, fail → 0; for partial credit, write a float in 0.0..1.0 to `$LOGS/reward.txt` instead). A check worth recording but not grading goes into `allow_failure { ... }` (`include LemansReport::Assertions`): a failed assertion inside lands in `checks.json` as `fail (allowed)` with its message and leaves the reward alone, while errors and skips stay hard failures. We use Minitest:
145
+ - `verification_test.rb`: a Ruby test that grades the solution (pass → 1, fail → 0; for partial credit, write a float in 0.0..1.0 to `$LOGS/reward.txt` instead). A check worth recording but not grading goes into `allow_failure { ... }` (`include LemansReport::Assertions`): a failed assertion inside lands in `checks.json` as `fail (allowed)` with its message and leaves the reward alone, while errors and skips stay hard failures (a test may call `allow_failure` once). For fractional credit next to the reward, say what passing the required checks alone is worth (`LemansReport.base_credit = 0.7`) and weight the allowed failures (`allow_failure(points: 2) { ... }`, 1 by default): the trial's `credit` is the base credit plus the remainder scaled by the share of extra points passed, rounded to two digits — 0 whenever the suite fails, and simply the reward when no `base_credit` is set. We use Minitest:
146
146
 
147
147
  ```ruby
148
148
  require "minitest/autorun"
@@ -222,7 +222,7 @@ ar-archive-book-access miniswen-installed gpt-5.6-luna 1 completed 0.0
222
222
 
223
223
  Each trial writes a flat `runs/<model>/<task>__<id>/` directory:
224
224
 
225
- - `result.json`: reward, outcome (completed, error, etc.), usage, timings, tags, digests
225
+ - `result.json`: reward, credit, outcome (completed, error, etc.), usage, timings, tags, digests
226
226
  - `trajectory.json`: [ATIF](https://www.harborframework.com/docs/agents/trajectory-format) trajectory of the agent's session
227
227
  - `agent.patch`: the agent's work as one diff against the sealed baseline
228
228
  - `verifier.log`, `checks.json`, etc.: additional logs captured during the verification phase.
@@ -254,7 +254,7 @@ gpt-5.6-luna ar-archive-book-access 2/2 2m 23s $0.0132 12.5 156905
254
254
  | `lemans init` | Scaffold a new bench directory: an annotated `bench.yml` and two example tasks |
255
255
  | `lemans tasks` | List the tasks in a bench (`--tag` to filter) |
256
256
  | `lemans run` | Run tasks and grade them (`--task`, `--tag`, `--agent`, `--model`, `-k`, `-c`, `--resume`) |
257
- | `lemans report` | Summarize `runs/` as a table or CSV (`--tag`, `-A [task-agent-model]` to aggregate, `-S <column>` to sort); repeated attempts add pass@k per model × task |
257
+ | `lemans report` | Summarize `runs/` as a table or CSV (`--task`, `--tag`, `--metadata key:value` to filter, `-A [task-agent-model]` to aggregate, `-S <column>` to sort); repeated attempts add pass@k per model × task, fractional grading a `credit` column |
258
258
  | `lemans clobber` | Delete run results (`--task`, `--ttl 10m\|2h\|1d`, `--invalid`, `-f` to skip the confirmation) |
259
259
 
260
260
  ## miniswen
@@ -27,6 +27,11 @@ module Miniswen
27
27
  # The breakpoint marker Anthropic reads, shaped the way OpenRouter forwards it.
28
28
  CACHE_CONTROL = { type: "ephemeral" }.freeze
29
29
 
30
+ # Left unset, the provider reserves the model's advertised maximum output
31
+ # ahead of the prompt (qwen3.8-27b: 128K of a 256K window), halving the
32
+ # history an agent turn of a few hundred tokens can build on.
33
+ MAX_OUTPUT_TOKENS = 32_768
34
+
30
35
  EXEC_ENV = {
31
36
  "PAGER" => "cat",
32
37
  "MANPAGER" => "cat",
@@ -224,7 +229,7 @@ module Miniswen
224
229
  end
225
230
 
226
231
  CostSource = Data.define(:name, :model, :priced_as, :registry) do
227
- def to_h = { name: name, model: model, priced_as: priced_as, registry: registry }.compact
232
+ def to_h = { name:, model:, priced_as:, registry: }.compact
228
233
  end
229
234
 
230
235
  attr_reader :messages, :environment
@@ -503,7 +508,7 @@ module Miniswen
503
508
  tools: { bash: @bash_tool },
504
509
  temperature: nil,
505
510
  model: model_info,
506
- params: routing_params,
511
+ params: routing_params.merge(output_cap_params(model_info)),
507
512
  thinking: (RubyLLM::Thinking::Config.new(effort: @effort) if @effort)
508
513
  )
509
514
  payload(response)
@@ -543,6 +548,20 @@ module Miniswen
543
548
 
544
549
  def provider_order = ENV["LEMANS_PROVIDER_ORDER"] || ENV["OPENROUTER_PROVIDER_ORDER"]
545
550
 
551
+ # OpenAI itself retired `max_tokens` for its reasoning models; the
552
+ # OpenAI-compatible providers and Anthropic still read it.
553
+ def output_cap_params(model_info)
554
+ cap = [ info&.max_tokens, MAX_OUTPUT_TOKENS ].compact.min
555
+ provider_class = RubyLLM::Provider.providers[model_info.provider.to_sym]
556
+ if [ RubyLLM::Providers::OpenAI, RubyLLM::Providers::Azure ].include?(provider_class)
557
+ { max_completion_tokens: cap }
558
+ elsif provider_class <= RubyLLM::Providers::OpenAI || provider_class <= RubyLLM::Providers::Anthropic
559
+ { max_tokens: cap }
560
+ else
561
+ {}
562
+ end
563
+ end
564
+
546
565
  def cost_source
547
566
  if local?
548
567
  return CostSource.new(name: :local_provider, model: @model,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Miniswen
4
- VERSION = "1.2.0"
4
+ VERSION = "1.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miniswen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Svyatoslav Kryukov