ace-llm-providers-cli 0.34.1 → 0.35.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: 9aee773ea6aac47cb8aeaa00ca6926a81f5d9eaac29f9b968ba098d81da0117d
4
- data.tar.gz: ac05f84f681e6316ac4662750e923e06a03692ee88201456f56da5afae904079
3
+ metadata.gz: f25fb8b3c59151cc9e4e46f49cd9eae4d2d06b6fca7052422a60b1ab0129cc24
4
+ data.tar.gz: 4f37a1d94452b1f3fb06f37d47d3407c2c3e1c3e0e8cf40eb2d38756f1920b16
5
5
  SHA512:
6
- metadata.gz: 707c07914d35d16e3e868b4891a0be562930edd9ce5d79a41eb0a99f6628bc90b3cc5eff2f9ad7adc122b3e674431e4825ae2a2602354e0386bd1c0cf737e0d7
7
- data.tar.gz: d10514be9fbb31940a1cd96c7ba35807eddedaa047aacf8fd09d35085d82c4e742db8efdf6261889236839056493305ec6f781836f38180a69fc3c9af2332c18
6
+ metadata.gz: 2124492c17917caf053a5ad03014087c5c1fe75c3336cb9e44777d6858829ff6b1e02cf1552c05b1f2c9c4afed6b573f83b1df61c6bf06c444435b171731d35d
7
+ data.tar.gz: a77c73150b6f49caa994f793a6608c4be21d6c2bc46f30d0b475078568c6f0e7e35345cb974c2aa4ddeef0b17d0ad2cbdc2c372862ad4375aa401965d2f9aac3
data/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.35.0] - 2026-09-27
11
+
12
+ ### Changed
13
+
14
+ - Pi client reports measured per-model token usage — input, output, cached (`cacheRead`) and total (`totalTokens`) — instead of character-based estimates. When the CLI supplies no usage, the session records an explicit `usage_status: unavailable` (with the pi version when known) and no fabricated token counts; measured zeros are preserved and absent fields stay absent.
15
+
10
16
  ## [0.34.1] - 2026-09-24
11
17
 
12
18
  ### Fixed
@@ -297,21 +297,48 @@ module Ace
297
297
  }
298
298
  end
299
299
 
300
+ # Measured usage only. When the pi CLI supplies usage the token counts
301
+ # are recorded as-is (cached 0 means "no cache read", distinct from
302
+ # absent); when it does not, tokens are absent entirely and the
303
+ # session records an explicit "unavailable" state — never an estimate.
300
304
  def build_metadata(response, text, prompt, options)
301
305
  usage = response["usage"] || {}
302
306
 
303
- prompt_tokens = usage["input_tokens"] || (prompt.to_s.length / 4).round
304
- output_tokens = usage["output_tokens"] || (text.length / 4).round
305
-
306
- {
307
+ metadata = {
307
308
  provider: "pi",
308
309
  model: @model || DEFAULT_MODEL,
309
- input_tokens: prompt_tokens,
310
- output_tokens: output_tokens,
311
- total_tokens: prompt_tokens + output_tokens,
312
310
  finish_reason: response["finish_reason"] || "success",
313
311
  timestamp: Time.now.utc.iso8601
314
312
  }
313
+
314
+ if usage["input_tokens"] || usage["output_tokens"]
315
+ metadata[:input_tokens] = usage["input_tokens"] unless usage["input_tokens"].nil?
316
+ metadata[:output_tokens] = usage["output_tokens"] unless usage["output_tokens"].nil?
317
+ metadata[:cached_tokens] = usage["cached_tokens"] if usage.key?("cached_tokens")
318
+ metadata[:total_tokens] = usage["total_tokens"] ||
319
+ (usage["input_tokens"].to_i + usage["output_tokens"].to_i)
320
+ metadata[:usage_status] = "measured"
321
+ else
322
+ metadata[:usage_status] = "unavailable"
323
+ version = pi_version
324
+ metadata[:pi_version] = version if version
325
+ end
326
+
327
+ metadata
328
+ end
329
+
330
+ # Best-effort pi CLI version for the usage-unavailable record. Runs
331
+ # outside SafeCapture (a bare --version probe) and is memoized per
332
+ # instance so retries don't re-spawn the process.
333
+ def pi_version
334
+ return @pi_version if defined?(@pi_version)
335
+
336
+ @pi_version = begin
337
+ stdout, _stderr, status = Open3.capture3("pi", "--version")
338
+ status.success? ? stdout.strip : nil
339
+ rescue StandardError
340
+ nil
341
+ end
315
342
  end
316
343
 
317
344
  # Parse NDJSON output from Pi CLI when --mode json is used.
@@ -385,7 +412,10 @@ module Ace
385
412
  end
386
413
 
387
414
  # Normalize Pi usage field names to our standard format.
388
- # Pi uses "input"/"output", we normalize to "input_tokens"/"output_tokens".
415
+ # Pi reports input/output/cacheRead/cacheWrite/totalTokens on the
416
+ # assistant message; we map them to *_tokens keys. A measured zero
417
+ # cacheRead is kept (distinguishing "no cache" from "unknown"); a
418
+ # missing key stays missing.
389
419
  #
390
420
  # @param usage [Hash] Raw usage hash from Pi response
391
421
  # @return [Hash] Normalized usage hash
@@ -393,7 +423,9 @@ module Ace
393
423
  return {} unless usage
394
424
  {
395
425
  "input_tokens" => usage["input"] || usage["input_tokens"],
396
- "output_tokens" => usage["output"] || usage["output_tokens"]
426
+ "output_tokens" => usage["output"] || usage["output_tokens"],
427
+ "cached_tokens" => (usage["cacheRead"] if usage.key?("cacheRead")),
428
+ "total_tokens" => (usage["totalTokens"] if usage.key?("totalTokens"))
397
429
  }.compact
398
430
  end
399
431
 
@@ -4,7 +4,7 @@ module Ace
4
4
  module LLM
5
5
  module Providers
6
6
  module CLI
7
- VERSION = "0.34.1"
7
+ VERSION = "0.35.0"
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ace-llm-providers-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.34.1
4
+ version: 0.35.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Czyz
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-09-24 00:00:00.000000000 Z
10
+ date: 2026-09-27 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: ace-llm
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '0.40'
18
+ version: '0.41'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '0.40'
25
+ version: '0.41'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rake
28
28
  requirement: !ruby/object:Gem::Requirement