lex-openai 0.1.3 → 0.1.4

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: b8f5858ed3e18e95299a0e2c0df9069c4a96bff7bb1a72051dcc0e6e9ae0265a
4
- data.tar.gz: bd6977abff97ae0e1428b3f2c2dace21a1c8bd817f3b2814ba46531f8cf8781c
3
+ metadata.gz: 7860eea429195b6d8c2e6c7d882bcd654bf14c5ce8d8439e7c07278da1e9cbb3
4
+ data.tar.gz: 9ba1592c7e995a699658c6180a218295516c3d0149533264b3b22c23df063de6
5
5
  SHA512:
6
- metadata.gz: e093b207dc65fee0d62c6b17a8dd75b00b11a307ec893540f79942e522115c7f8eb8d6cafbbfdb2cbf54ea1ff999f16c61fed2d35e58a036bf4f024ebd6c92ec
7
- data.tar.gz: e4b5f51079d5ea17effab271dd879665cf2fc03f2678fbd3f9f1d8d3504a05f235b825f6cdc99fd491a2b80ae751b11994e0355d09b117a8249c595ed80445b2
6
+ metadata.gz: f7c0f52678c76c3d59e6b6f154cb33107055377c0509da9450a76e984b4cd4623745c788da90804723650a06d5970f3a1fb71ff63cd7f30a2e953e57986e1ef7
7
+ data.tar.gz: ab3a7fe72ece42b0821af4966e618148907c222bcf0faf0caf5b48fd4547e154dc9c474f44c2cf592fc8f936dca4b5b594869446f16d6fce9ba785b304039649
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.4] - 2026-03-31
4
+
5
+ ### Added
6
+ - add standardized usage tracking to all runner responses; all methods now return a `usage:` hash with `input_tokens`, `output_tokens`, `cache_read_tokens`, and `cache_write_tokens` keys compatible with legion-llm's CostEstimator (#2)
7
+
3
8
  ## [0.1.3] - 2026-03-30
4
9
 
5
10
  ### Changed
@@ -14,7 +14,15 @@ module Legion
14
14
  body[:speed] = speed if speed
15
15
 
16
16
  response = client(api_key: api_key, **).post('/v1/audio/speech', body)
17
- { result: response.body }
17
+ {
18
+ result: response.body,
19
+ usage: {
20
+ input_tokens: 0,
21
+ output_tokens: 0,
22
+ cache_read_tokens: 0,
23
+ cache_write_tokens: 0
24
+ }
25
+ }
18
26
  end
19
27
 
20
28
  def transcribe(file:, api_key:, model: 'whisper-1', language: nil, prompt: nil, response_format: nil, **)
@@ -27,7 +35,15 @@ module Legion
27
35
  payload[:response_format] = response_format if response_format
28
36
 
29
37
  response = client(api_key: api_key, **).post('/v1/audio/transcriptions', payload)
30
- { result: response.body }
38
+ {
39
+ result: response.body,
40
+ usage: {
41
+ input_tokens: 0,
42
+ output_tokens: 0,
43
+ cache_read_tokens: 0,
44
+ cache_write_tokens: 0
45
+ }
46
+ }
31
47
  end
32
48
 
33
49
  def translate(file:, api_key:, model: 'whisper-1', prompt: nil, response_format: nil, **)
@@ -39,7 +55,15 @@ module Legion
39
55
  payload[:response_format] = response_format if response_format
40
56
 
41
57
  response = client(api_key: api_key, **).post('/v1/audio/translations', payload)
42
- { result: response.body }
58
+ {
59
+ result: response.body,
60
+ usage: {
61
+ input_tokens: 0,
62
+ output_tokens: 0,
63
+ cache_read_tokens: 0,
64
+ cache_write_tokens: 0
65
+ }
66
+ }
43
67
  end
44
68
 
45
69
  include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
@@ -20,7 +20,16 @@ module Legion
20
20
  body[:stop] = stop if stop
21
21
 
22
22
  response = client(api_key: api_key, **).post('/v1/chat/completions', body)
23
- { result: response.body }
23
+ resp_body = response.body
24
+ {
25
+ result: resp_body,
26
+ usage: {
27
+ input_tokens: resp_body.dig('usage', 'prompt_tokens') || 0,
28
+ output_tokens: resp_body.dig('usage', 'completion_tokens') || 0,
29
+ cache_read_tokens: resp_body.dig('usage', 'prompt_tokens_details', 'cached_tokens') || 0,
30
+ cache_write_tokens: 0
31
+ }
32
+ }
24
33
  end
25
34
 
26
35
  include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
@@ -15,7 +15,16 @@ module Legion
15
15
  body[:dimensions] = dimensions if dimensions
16
16
 
17
17
  response = client(api_key: api_key, **).post('/v1/embeddings', body)
18
- { result: response.body }
18
+ resp_body = response.body
19
+ {
20
+ result: resp_body,
21
+ usage: {
22
+ input_tokens: resp_body.dig('usage', 'prompt_tokens') || 0,
23
+ output_tokens: resp_body.dig('usage', 'completion_tokens') || 0,
24
+ cache_read_tokens: resp_body.dig('usage', 'prompt_tokens_details', 'cached_tokens') || 0,
25
+ cache_write_tokens: 0
26
+ }
27
+ }
19
28
  end
20
29
 
21
30
  include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
@@ -14,7 +14,15 @@ module Legion
14
14
  path += "?purpose=#{purpose}" if purpose
15
15
 
16
16
  response = client(api_key: api_key, **).get(path)
17
- { result: response.body }
17
+ {
18
+ result: response.body,
19
+ usage: {
20
+ input_tokens: 0,
21
+ output_tokens: 0,
22
+ cache_read_tokens: 0,
23
+ cache_write_tokens: 0
24
+ }
25
+ }
18
26
  end
19
27
 
20
28
  def upload(file:, purpose:, api_key:, **)
@@ -24,22 +32,54 @@ module Legion
24
32
  }
25
33
 
26
34
  response = client(api_key: api_key, **).post('/v1/files', payload)
27
- { result: response.body }
35
+ {
36
+ result: response.body,
37
+ usage: {
38
+ input_tokens: 0,
39
+ output_tokens: 0,
40
+ cache_read_tokens: 0,
41
+ cache_write_tokens: 0
42
+ }
43
+ }
28
44
  end
29
45
 
30
46
  def retrieve(file_id:, api_key:, **)
31
47
  response = client(api_key: api_key, **).get("/v1/files/#{file_id}")
32
- { result: response.body }
48
+ {
49
+ result: response.body,
50
+ usage: {
51
+ input_tokens: 0,
52
+ output_tokens: 0,
53
+ cache_read_tokens: 0,
54
+ cache_write_tokens: 0
55
+ }
56
+ }
33
57
  end
34
58
 
35
59
  def delete(file_id:, api_key:, **)
36
60
  response = client(api_key: api_key, **).delete("/v1/files/#{file_id}")
37
- { result: response.body }
61
+ {
62
+ result: response.body,
63
+ usage: {
64
+ input_tokens: 0,
65
+ output_tokens: 0,
66
+ cache_read_tokens: 0,
67
+ cache_write_tokens: 0
68
+ }
69
+ }
38
70
  end
39
71
 
40
72
  def content(file_id:, api_key:, **)
41
73
  response = client(api_key: api_key, **).get("/v1/files/#{file_id}/content")
42
- { result: response.body }
74
+ {
75
+ result: response.body,
76
+ usage: {
77
+ input_tokens: 0,
78
+ output_tokens: 0,
79
+ cache_read_tokens: 0,
80
+ cache_write_tokens: 0
81
+ }
82
+ }
43
83
  end
44
84
 
45
85
  include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
@@ -17,7 +17,15 @@ module Legion
17
17
  body[:response_format] = response_format if response_format
18
18
 
19
19
  response = client(api_key: api_key, **).post('/v1/images/generations', body)
20
- { result: response.body }
20
+ {
21
+ result: response.body,
22
+ usage: {
23
+ input_tokens: 0,
24
+ output_tokens: 0,
25
+ cache_read_tokens: 0,
26
+ cache_write_tokens: 0
27
+ }
28
+ }
21
29
  end
22
30
 
23
31
  def edit(image:, prompt:, api_key:, model: 'dall-e-2', mask: nil, n: 1, size: '1024x1024', **)
@@ -31,7 +39,15 @@ module Legion
31
39
  payload[:mask] = Faraday::Multipart::FilePart.new(mask, 'image/png') if mask
32
40
 
33
41
  response = client(api_key: api_key, **).post('/v1/images/edits', payload)
34
- { result: response.body }
42
+ {
43
+ result: response.body,
44
+ usage: {
45
+ input_tokens: 0,
46
+ output_tokens: 0,
47
+ cache_read_tokens: 0,
48
+ cache_write_tokens: 0
49
+ }
50
+ }
35
51
  end
36
52
 
37
53
  def variation(image:, api_key:, model: 'dall-e-2', n: 1, size: '1024x1024', **)
@@ -43,7 +59,15 @@ module Legion
43
59
  }
44
60
 
45
61
  response = client(api_key: api_key, **).post('/v1/images/variations', payload)
46
- { result: response.body }
62
+ {
63
+ result: response.body,
64
+ usage: {
65
+ input_tokens: 0,
66
+ output_tokens: 0,
67
+ cache_read_tokens: 0,
68
+ cache_write_tokens: 0
69
+ }
70
+ }
47
71
  end
48
72
 
49
73
  include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
@@ -11,17 +11,41 @@ module Legion
11
11
 
12
12
  def list(api_key:, **)
13
13
  response = client(api_key: api_key, **).get('/v1/models')
14
- { result: response.body }
14
+ {
15
+ result: response.body,
16
+ usage: {
17
+ input_tokens: 0,
18
+ output_tokens: 0,
19
+ cache_read_tokens: 0,
20
+ cache_write_tokens: 0
21
+ }
22
+ }
15
23
  end
16
24
 
17
25
  def retrieve(model:, api_key:, **)
18
26
  response = client(api_key: api_key, **).get("/v1/models/#{model}")
19
- { result: response.body }
27
+ {
28
+ result: response.body,
29
+ usage: {
30
+ input_tokens: 0,
31
+ output_tokens: 0,
32
+ cache_read_tokens: 0,
33
+ cache_write_tokens: 0
34
+ }
35
+ }
20
36
  end
21
37
 
22
38
  def delete(model:, api_key:, **)
23
39
  response = client(api_key: api_key, **).delete("/v1/models/#{model}")
24
- { result: response.body }
40
+ {
41
+ result: response.body,
42
+ usage: {
43
+ input_tokens: 0,
44
+ output_tokens: 0,
45
+ cache_read_tokens: 0,
46
+ cache_write_tokens: 0
47
+ }
48
+ }
25
49
  end
26
50
 
27
51
  include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
@@ -14,7 +14,16 @@ module Legion
14
14
  body[:model] = model if model
15
15
 
16
16
  response = client(api_key: api_key, **).post('/v1/moderations', body)
17
- { result: response.body }
17
+ resp_body = response.body
18
+ {
19
+ result: resp_body,
20
+ usage: {
21
+ input_tokens: resp_body.dig('usage', 'prompt_tokens') || 0,
22
+ output_tokens: resp_body.dig('usage', 'completion_tokens') || 0,
23
+ cache_read_tokens: resp_body.dig('usage', 'prompt_tokens_details', 'cached_tokens') || 0,
24
+ cache_write_tokens: 0
25
+ }
26
+ }
18
27
  end
19
28
 
20
29
  include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
@@ -3,7 +3,7 @@
3
3
  module Legion
4
4
  module Extensions
5
5
  module Openai
6
- VERSION = '0.1.3'
6
+ VERSION = '0.1.4'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-openai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity