riffer-rig 0.2.1 → 0.4.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/README.md +2 -2
  4. data/lib/riffer/rig/cli.rb +31 -2
  5. data/lib/riffer/rig/coding_agent.rb +35 -31
  6. data/lib/riffer/rig/credentials.rb +24 -4
  7. data/lib/riffer/rig/repl.rb +75 -22
  8. data/lib/riffer/rig/settings/pricing.rb +19 -0
  9. data/lib/riffer/rig/settings.rb +33 -8
  10. data/lib/riffer/rig/token_tally.rb +22 -6
  11. data/lib/riffer/rig/tools/bash.rb +23 -5
  12. data/lib/riffer/rig/tools/edit.rb +16 -2
  13. data/lib/riffer/rig/tools/read.rb +6 -1
  14. data/lib/riffer/rig/tools/write.rb +4 -0
  15. data/lib/riffer/rig/ui/animator.rb +51 -11
  16. data/lib/riffer/rig/ui/banner.rb +28 -4
  17. data/lib/riffer/rig/ui/cursor.rb +14 -2
  18. data/lib/riffer/rig/ui/palette.rb +13 -7
  19. data/lib/riffer/rig/ui/renderer.rb +137 -29
  20. data/lib/riffer/rig/ui/smoother.rb +56 -14
  21. data/lib/riffer/rig/ui/theme.rb +38 -7
  22. data/lib/riffer/rig/version.rb +1 -1
  23. data/sig/generated/riffer/rig/cli.rbs +41 -0
  24. data/sig/generated/riffer/rig/coding_agent.rbs +9 -0
  25. data/sig/generated/riffer/rig/credentials.rbs +55 -0
  26. data/sig/generated/riffer/rig/repl.rbs +68 -0
  27. data/sig/generated/riffer/rig/settings/pricing.rbs +23 -0
  28. data/sig/generated/riffer/rig/settings.rbs +92 -0
  29. data/sig/generated/riffer/rig/token_tally.rbs +61 -0
  30. data/sig/generated/riffer/rig/tools/bash.rbs +28 -0
  31. data/sig/generated/riffer/rig/tools/edit.rbs +11 -0
  32. data/sig/generated/riffer/rig/tools/read.rbs +12 -0
  33. data/sig/generated/riffer/rig/tools/write.rbs +9 -0
  34. data/sig/generated/riffer/rig/ui/animator.rbs +76 -0
  35. data/sig/generated/riffer/rig/ui/banner.rbs +42 -0
  36. data/sig/generated/riffer/rig/ui/cursor.rbs +33 -0
  37. data/sig/generated/riffer/rig/ui/palette.rbs +17 -0
  38. data/sig/generated/riffer/rig/ui/renderer.rbs +116 -0
  39. data/sig/generated/riffer/rig/ui/smoother.rbs +72 -0
  40. data/sig/generated/riffer/rig/ui/theme.rbs +60 -0
  41. data/sig/generated/riffer/rig/version.rbs +7 -0
  42. data/sig/generated/riffer/rig.rbs +2 -0
  43. data/sig/manual/riffer/rig/cli.rbs +8 -0
  44. data/sig/manual/riffer/rig/credentials.rbs +8 -0
  45. data/sig/manual/riffer/rig/settings.rbs +8 -0
  46. data/sig/manual/riffer/rig/tools.rbs +5 -0
  47. data/sig/manual/riffer/rig/ui/banner.rbs +8 -0
  48. data/sig/manual/riffer/rig/ui.rbs +5 -0
  49. metadata +31 -4
@@ -4,7 +4,7 @@
4
4
  # typing. On a non-TTY output it is transparent: writes pass through
5
5
  # synchronously and no thread ever runs.
6
6
  class Riffer::Rig::UI::Smoother
7
- TICK_SECONDS = 1.0 / 60.0
7
+ TICK_SECONDS = 1.0 / 60.0 #: Float
8
8
 
9
9
  # A frame removes only a sixtieth of the remaining backlog — an exponential
10
10
  # decay whose tail keeps text flowing for a second or more, so the reveal
@@ -12,9 +12,25 @@ class Riffer::Rig::UI::Smoother
12
12
  # releases so the effective rate can settle at the provider's throughput;
13
13
  # the floor is fractional (10 chars/s) so it can't over-drain a backlog
14
14
  # that's trickling in slower than 60 chars/s.
15
- BACKLOG_FRACTION_PER_TICK = Rational(1, 60)
16
- MIN_CHARS_PER_TICK = Rational(1, 6)
15
+ #
16
+ BACKLOG_FRACTION_PER_TICK = Rational(1, 60) #: Rational
17
17
 
18
+ MIN_CHARS_PER_TICK = Rational(1, 6) #: Rational
19
+
20
+ # @rbs @io: untyped
21
+ # @rbs @theme: Riffer::Rig::UI::Theme
22
+ # @rbs @clock: singleton(Kernel)
23
+ # @rbs @backlog: String
24
+ # @rbs @carry: Rational
25
+ # @rbs @mutex: Mutex
26
+ # @rbs @thread: Thread?
27
+ # @rbs @stop: bool
28
+ # @rbs @newline_pending: bool
29
+
30
+ # @rbs io: untyped
31
+ # @rbs ?theme: Riffer::Rig::UI::Theme
32
+ # @rbs clock: singleton(Kernel)
33
+ # @rbs return: void
18
34
  def initialize(io: $stdout, theme: Riffer::Rig::UI::Theme.for(io), clock: Kernel)
19
35
  @io = io
20
36
  @theme = theme
@@ -24,8 +40,10 @@ class Riffer::Rig::UI::Smoother
24
40
  @mutex = Mutex.new
25
41
  @thread = nil
26
42
  @stop = false
43
+ @newline_pending = false
27
44
  end
28
45
 
46
+ # @rbs return: void
29
47
  def start
30
48
  return unless enabled?
31
49
  return if @thread
@@ -39,17 +57,24 @@ class Riffer::Rig::UI::Smoother
39
57
  end
40
58
  end
41
59
 
60
+ # @rbs content: String
61
+ # @rbs return: self
42
62
  def <<(content)
43
- if enabled?
44
- @mutex.synchronize { @backlog << content }
45
- else
46
- @io.print(content)
47
- @io.flush
63
+ @mutex.synchronize do
64
+ if enabled?
65
+ @backlog << content
66
+ else
67
+ @io.print(content)
68
+ @io.flush
69
+ end
70
+ @newline_pending = !content.end_with?("\n")
48
71
  end
49
72
  self
50
73
  end
51
74
 
52
75
  # The write sits inside the mutex so a concurrent tick can't reorder a drain.
76
+ #
77
+ # @rbs return: void
53
78
  def tick
54
79
  @mutex.synchronize do
55
80
  return if @backlog.empty?
@@ -59,26 +84,42 @@ class Riffer::Rig::UI::Smoother
59
84
  return if count.zero?
60
85
 
61
86
  @carry -= count
62
- @io.print(@backlog.slice!(0, count))
87
+ chunk = @backlog.slice!(0, count) || ''
88
+ @newline_pending = !chunk.end_with?("\n")
89
+ @io.print(chunk)
63
90
  @io.flush
64
91
  end
65
92
  end
66
93
 
67
- # Called before non-delta output so printed order matches stream order.
94
+ # Called before non-prose output so printed order matches stream order. The
95
+ # backlog is flushed, then any partial prose block the model left without a
96
+ # trailing newline gets one, so block spacing never depends on the model's
97
+ # last character.
98
+ #
99
+ # @rbs return: void
68
100
  def drain
69
101
  @mutex.synchronize do
70
- return if @backlog.empty?
102
+ unless @backlog.empty?
103
+ backlog = @backlog.slice!(0, @backlog.length) || ''
104
+ @newline_pending = !backlog.end_with?("\n")
105
+ @io.print(backlog)
106
+ end
107
+ return unless @newline_pending
71
108
 
72
- @io.print(@backlog.slice!(0, @backlog.length))
109
+ @newline_pending = false
110
+ @io.print("\n")
73
111
  @io.flush
74
112
  end
75
113
  end
76
114
 
77
115
  # Idempotent: the REPL's ensure path runs it even after a happy-path finish.
116
+ #
117
+ # @rbs return: void
78
118
  def finish
79
- if @thread
119
+ thread = @thread
120
+ if thread
80
121
  @stop = true
81
- @thread.join
122
+ thread.join
82
123
  @thread = nil
83
124
  end
84
125
  drain
@@ -86,6 +127,7 @@ class Riffer::Rig::UI::Smoother
86
127
 
87
128
  private
88
129
 
130
+ # @rbs return: bool
89
131
  def enabled?
90
132
  @theme.enabled && @io.respond_to?(:tty?) && @io.tty?
91
133
  end
@@ -2,43 +2,74 @@
2
2
 
3
3
  # +enabled+ gates every escape so the same code path emits plain, escape-free
4
4
  # text when piped or tested.
5
- Riffer::Rig::UI::Theme = Data.define(:enabled)
6
-
7
- # Behaviour lives in a reopened class (rather than the `Data.define` block) so
8
- # the type checker can analyse the methods.
9
5
  class Riffer::Rig::UI::Theme
6
+ # @rbs @enabled: bool
7
+
8
+ # @rbs return: bool
9
+ # @dynamic enabled
10
+ attr_reader :enabled #: bool
11
+
12
+ # @rbs enabled: bool
13
+ # @rbs return: void
14
+ def initialize(enabled:)
15
+ @enabled = enabled
16
+ end
17
+
18
+ # @rbs io: untyped
19
+ # @rbs return: Riffer::Rig::UI::Theme
10
20
  def self.for(io)
11
21
  new(enabled: io.respond_to?(:tty?) && io.tty? && !ENV.key?('NO_COLOR'))
12
22
  end
13
23
 
24
+ # @rbs text: String
25
+ # @rbs rgb: Array[Integer]
26
+ # @rbs return: String
14
27
  def paint(text, rgb)
15
- return text.to_s unless enabled
28
+ return text unless enabled
16
29
 
17
30
  "\e[38;2;#{rgb[0]};#{rgb[1]};#{rgb[2]}m#{text}\e[0m"
18
31
  end
19
32
 
33
+ # @rbs text: String
34
+ # @rbs return: String
20
35
  def pink(text) = paint(text, Riffer::Rig::UI::Palette::PINK)
21
36
 
37
+ # @rbs text: String
38
+ # @rbs return: String
22
39
  def magenta(text) = paint(text, Riffer::Rig::UI::Palette::MAGENTA)
23
40
 
41
+ # @rbs text: String
42
+ # @rbs return: String
24
43
  def purple(text) = paint(text, Riffer::Rig::UI::Palette::PURPLE)
25
44
 
45
+ # @rbs text: String
46
+ # @rbs return: String
26
47
  def blue(text) = paint(text, Riffer::Rig::UI::Palette::BLUE)
27
48
 
49
+ # @rbs text: String
50
+ # @rbs return: String
28
51
  def cyan(text) = paint(text, Riffer::Rig::UI::Palette::CYAN)
29
52
 
53
+ # @rbs text: String
54
+ # @rbs return: String
30
55
  def grey(text) = paint(text, Riffer::Rig::UI::Palette::GREY)
31
56
 
57
+ # @rbs text: String
58
+ # @rbs return: String
32
59
  def red(text) = paint(text, Riffer::Rig::UI::Palette::RED)
33
60
 
61
+ # @rbs text: String
62
+ # @rbs return: String
34
63
  def dim(text)
35
- return text.to_s unless enabled
64
+ return text unless enabled
36
65
 
37
66
  "\e[2m#{text}\e[0m"
38
67
  end
39
68
 
69
+ # @rbs text: String
70
+ # @rbs return: String
40
71
  def bold(text)
41
- return text.to_s unless enabled
72
+ return text unless enabled
42
73
 
43
74
  "\e[1m#{text}\e[0m"
44
75
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Riffer
4
4
  module Rig
5
- VERSION = '0.2.1'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
@@ -0,0 +1,41 @@
1
+ # Generated from lib/riffer/rig/cli.rb with RBS::Inline
2
+
3
+ module Riffer::Rig::CLI
4
+ PROVIDER_URLS: Hash[String, String]
5
+
6
+ # @rbs output: untyped
7
+ # @rbs input: untyped
8
+ # @rbs return: Integer
9
+ def start: (?output: untyped, ?input: untyped) -> Integer
10
+
11
+ private
12
+
13
+ # @rbs provider: String?
14
+ # @rbs api_key: String
15
+ # @rbs return: void
16
+ def configure_provider: (String? provider, String api_key) -> void
17
+
18
+ # @rbs provider: String?
19
+ # @rbs theme: Riffer::Rig::UI::Theme
20
+ # @rbs output: untyped
21
+ # @rbs input: untyped
22
+ # @rbs return: String?
23
+ def onboard: (String? provider, Riffer::Rig::UI::Theme theme, output: untyped, input: untyped) -> String?
24
+
25
+ # @rbs provider: String?
26
+ # @rbs return: String
27
+ def env_var_for: (String? provider) -> String
28
+
29
+ # @rbs input: untyped
30
+ # @rbs return: String?
31
+ def read_secret: (untyped input) -> String?
32
+
33
+ # @rbs theme: Riffer::Rig::UI::Theme
34
+ # @rbs animator: Riffer::Rig::UI::Animator
35
+ # @rbs model: String
36
+ # @rbs return: void
37
+ def reveal_banner: (Riffer::Rig::UI::Theme theme, Riffer::Rig::UI::Animator animator, String model) -> void
38
+
39
+ # @rbs return: String
40
+ def count_skills: () -> String
41
+ end
@@ -0,0 +1,9 @@
1
+ # Generated from lib/riffer/rig/coding_agent.rb with RBS::Inline
2
+
3
+ class Riffer::Rig::CodingAgent < Riffer::Agent
4
+ GLOBAL_AGENTS_FILE: String
5
+
6
+ GLOBAL_SKILLS_DIR: String
7
+
8
+ PROJECT_SKILLS_DIR: ^() -> String
9
+ end
@@ -0,0 +1,55 @@
1
+ # Generated from lib/riffer/rig/credentials.rb with RBS::Inline
2
+
3
+ # Reads and writes API keys for each supported provider in
4
+ # <tt>~/.riffer/auth.json</tt>.
5
+ #
6
+ # Keys are stored under the provider name, e.g.:
7
+ #
8
+ # {
9
+ # "anthropic": "sk-ant-...",
10
+ # "openai": "sk-...",
11
+ # "gemini": "...",
12
+ # "openrouter": "sk-or-..."
13
+ # }
14
+ #
15
+ # The environment variable checked per provider:
16
+ #
17
+ # anthropic → ANTHROPIC_API_KEY
18
+ # openai → OPENAI_API_KEY
19
+ # gemini → GEMINI_API_KEY
20
+ # openrouter → OPENROUTER_API_KEY
21
+ module Riffer::Rig::Credentials
22
+ PATH: String
23
+
24
+ PROVIDER_ENV_VARS: Hash[String, String]
25
+
26
+ # Returns the API key for +provider+, checking the environment variable first,
27
+ # then the stored file. Returns +nil+ if no key is available.
28
+ #
29
+ # @rbs provider: String?
30
+ # @rbs path: String
31
+ # @rbs return: String?
32
+ def api_key_for: (String? provider, ?path: String) -> String?
33
+
34
+ # Saves an API key for +provider+ to the auth file with 0600 permissions.
35
+ #
36
+ # @rbs provider: String
37
+ # @rbs key: String
38
+ # @rbs path: String
39
+ # @rbs return: String
40
+ def save_api_key: (String provider, String key, ?path: String) -> String
41
+
42
+ private
43
+
44
+ # @rbs provider: String?
45
+ # @rbs path: String
46
+ # @rbs return: String?
47
+ def key_from_file: (String? provider, String path) -> String?
48
+
49
+ # The parsed auth file, or an empty hash when the file is absent or
50
+ # malformed.
51
+ #
52
+ # @rbs path: String
53
+ # @rbs return: Hash[String, untyped]
54
+ def read: (String path) -> Hash[String, untyped]
55
+ end
@@ -0,0 +1,68 @@
1
+ # Generated from lib/riffer/rig/repl.rb with RBS::Inline
2
+
3
+ class Riffer::Rig::REPL
4
+ EXIT_COMMANDS: Array[String]
5
+
6
+ SKILL_COMMAND: Regexp
7
+
8
+ @output: untyped
9
+
10
+ @input: untyped
11
+
12
+ @theme: Riffer::Rig::UI::Theme
13
+
14
+ @cursor: Riffer::Rig::UI::Cursor
15
+
16
+ @smoother: Riffer::Rig::UI::Smoother
17
+
18
+ @animator: Riffer::Rig::UI::Animator
19
+
20
+ @renderer: Riffer::Rig::UI::Renderer
21
+
22
+ @agent: Riffer::Agent
23
+
24
+ # @rbs ?agent: Riffer::Agent
25
+ # @rbs ?renderer: Riffer::Rig::UI::Renderer
26
+ # @rbs input: untyped
27
+ # @rbs output: untyped
28
+ # @rbs ?theme: Riffer::Rig::UI::Theme
29
+ # @rbs ?animator: Riffer::Rig::UI::Animator
30
+ # @rbs ?smoother: Riffer::Rig::UI::Smoother
31
+ # @rbs ?cursor: Riffer::Rig::UI::Cursor
32
+ # @rbs return: void
33
+ def initialize: (agent: untyped, renderer: untyped, ?input: untyped, ?output: untyped, ?theme: untyped, ?animator: untyped, ?smoother: untyped, ?cursor: untyped) -> void
34
+
35
+ # @rbs return: Symbol
36
+ def run: () -> Symbol
37
+
38
+ private
39
+
40
+ # @rbs prompt: String
41
+ # @rbs return: void
42
+ def run_turn: (String prompt) -> void
43
+
44
+ # @rbs name: String
45
+ # @rbs args: String
46
+ # @rbs return: void
47
+ def run_skill_command: (String name, String args) -> void
48
+
49
+ # @rbs name: String
50
+ # @rbs return: String?
51
+ def activate_skill: (String name) -> String?
52
+
53
+ # @rbs name: String
54
+ # @rbs body: String
55
+ # @rbs return: String
56
+ def skill_block: (String name, String body) -> String
57
+
58
+ # Chrome lines that never pass through the renderer (errors, exit line) end
59
+ # their line with a newline but leave the renderer's tool-group state alone —
60
+ # they can only follow prose, never mid-group.
61
+ #
62
+ # @rbs return: void
63
+ def print_block: () ?{ (?) -> untyped } -> void
64
+
65
+ # @rbs message: Riffer::Messages::Base
66
+ # @rbs return: void
67
+ def render_tool_result: (Riffer::Messages::Base message) -> void
68
+ end
@@ -0,0 +1,23 @@
1
+ # Generated from lib/riffer/rig/settings/pricing.rb with RBS::Inline
2
+
3
+ # USD per million tokens, parsed from a model's entry in the settings file.
4
+ class Riffer::Rig::Settings::Pricing
5
+ # @dynamic input, output, cache_write, cache_read
6
+ attr_reader input: Float
7
+
8
+ # @dynamic input, output, cache_write, cache_read
9
+ attr_reader output: Float
10
+
11
+ # @dynamic input, output, cache_write, cache_read
12
+ attr_reader cache_write: Float
13
+
14
+ # @dynamic input, output, cache_write, cache_read
15
+ attr_reader cache_read: Float
16
+
17
+ # @rbs input: Float
18
+ # @rbs output: Float
19
+ # @rbs cache_write: Float
20
+ # @rbs cache_read: Float
21
+ # @rbs return: void
22
+ def initialize: (input: Float, output: Float, cache_write: Float, cache_read: Float) -> void
23
+ end
@@ -0,0 +1,92 @@
1
+ # Generated from lib/riffer/rig/settings.rb with RBS::Inline
2
+
3
+ # Reads and writes the riffer-rig user settings file at
4
+ # <tt>~/.riffer/settings.json</tt>.
5
+ #
6
+ # Example file:
7
+ #
8
+ # {
9
+ # "model": "anthropic/claude-sonnet-4-6",
10
+ # "reasoning": "low",
11
+ # "models": {
12
+ # "anthropic/claude-sonnet-4-6": {
13
+ # "input": 3.0,
14
+ # "output": 15.0,
15
+ # "cache_write": 3.75,
16
+ # "cache_read": 0.3
17
+ # }
18
+ # }
19
+ # }
20
+ #
21
+ # All keys are optional. Missing pricing means cost display is suppressed.
22
+ # <tt>"reasoning"</tt> is translated to the appropriate provider-specific
23
+ # parameter on each API call; accepted values depend on the provider:
24
+ #
25
+ # - Anthropic: <tt>"low"</tt>, <tt>"medium"</tt>, <tt>"high"</tt>,
26
+ # <tt>"xhigh"</tt>, <tt>"max"</tt>
27
+ # - OpenAI / OpenRouter: <tt>"low"</tt>, <tt>"medium"</tt>, <tt>"high"</tt>,
28
+ # <tt>"xhigh"</tt>
29
+ #
30
+ # Omitting the key (or supplying an unrecognised value) leaves the model's
31
+ # default reasoning behaviour unchanged.
32
+ module Riffer::Rig::Settings
33
+ PATH: String
34
+
35
+ DEFAULT_MODEL: ::String
36
+
37
+ REASONING_LEVELS_BY_PROVIDER: Hash[String, Array[String]]
38
+
39
+ # Returns the configured model string, or +DEFAULT_MODEL+ if not set.
40
+ #
41
+ # @rbs path: String
42
+ # @rbs return: String
43
+ def model: (?path: String) -> String
44
+
45
+ # Returns model options for the configured model and reasoning level, ready
46
+ # to pass directly to the Riffer agent's +model_options+.
47
+ #
48
+ # @rbs path: String
49
+ # @rbs return: Hash[Symbol, untyped]
50
+ def model_options: (?path: String) -> Hash[Symbol, untyped]
51
+
52
+ # Returns the provider prefix for +model_string+, e.g. <tt>"anthropic"</tt>
53
+ # for <tt>"anthropic/claude-sonnet-4-6"</tt>. Returns +nil+ if the model
54
+ # string contains no slash.
55
+ #
56
+ # @rbs model_string: String
57
+ # @rbs return: String?
58
+ def provider_for: (String model_string) -> String?
59
+
60
+ # Returns the pricing for +model+, or +nil+ if not configured.
61
+ #
62
+ # @rbs model: String
63
+ # @rbs path: String
64
+ # @rbs return: Pricing?
65
+ def pricing_for: (String model, ?path: String) -> Pricing?
66
+
67
+ private
68
+
69
+ # @rbs provider: String?
70
+ # @rbs return: Hash[Symbol, untyped]
71
+ def base_options: (String? provider) -> Hash[Symbol, untyped]
72
+
73
+ # @rbs path: String
74
+ # @rbs ?provider: String?
75
+ # @rbs return: String?
76
+ def reasoning_for: (?path: String, ?provider: untyped) -> String?
77
+
78
+ # Maps a reasoning level to the provider-specific model option hash expected
79
+ # by Riffer. Returns an empty hash when +level+ is +nil+.
80
+ #
81
+ # @rbs level: String?
82
+ # @rbs provider: String?
83
+ # @rbs return: Hash[Symbol, untyped]
84
+ def reasoning_options: (String? level, String? provider) -> Hash[Symbol, untyped]
85
+
86
+ # The parsed settings file, or an empty hash when the file is absent or
87
+ # malformed.
88
+ #
89
+ # @rbs path: String
90
+ # @rbs return: Hash[String, untyped]
91
+ def read: (String path) -> Hash[String, untyped]
92
+ end
@@ -0,0 +1,61 @@
1
+ # Generated from lib/riffer/rig/token_tally.rb with RBS::Inline
2
+
3
+ # Accumulates token usage across multiple turns in a session and computes an
4
+ # estimated cost based on a pricing object sourced from
5
+ # +Riffer::Rig::Settings+.
6
+ #
7
+ # Instantiate once per REPL session, call +add+ after each turn, then read
8
+ # +total_tokens+ and +estimated_cost+ for display.
9
+ #
10
+ # pricing = Riffer::Rig::Settings.pricing_for('anthropic/claude-sonnet-4-6')
11
+ # tally = Riffer::Rig::TokenTally.new(pricing: pricing)
12
+ # tally.add(usage)
13
+ # tally.estimated_cost # => 0.000042 (USD), or nil if pricing is nil
14
+ class Riffer::Rig::TokenTally
15
+ @input_tokens: Integer
16
+
17
+ @output_tokens: Integer
18
+
19
+ @cache_write_tokens: Integer
20
+
21
+ @cache_read_tokens: Integer
22
+
23
+ @pricing: Riffer::Rig::Settings::Pricing?
24
+
25
+ # @dynamic input_tokens, output_tokens, cache_write_tokens, cache_read_tokens
26
+ attr_reader input_tokens: untyped
27
+
28
+ # @dynamic input_tokens, output_tokens, cache_write_tokens, cache_read_tokens
29
+ attr_reader output_tokens: untyped
30
+
31
+ # @dynamic input_tokens, output_tokens, cache_write_tokens, cache_read_tokens
32
+ attr_reader cache_write_tokens: untyped
33
+
34
+ # @dynamic input_tokens, output_tokens, cache_write_tokens, cache_read_tokens
35
+ attr_reader cache_read_tokens: untyped
36
+
37
+ # @rbs ?pricing: Riffer::Rig::Settings::Pricing?
38
+ # @rbs return: void
39
+ def initialize: (?pricing: untyped) -> void
40
+
41
+ # Accumulates token counts from a +Riffer::Providers::TokenUsage+ object.
42
+ #
43
+ # @rbs usage: Riffer::Providers::TokenUsage
44
+ # @rbs return: void
45
+ def add: (Riffer::Providers::TokenUsage usage) -> void
46
+
47
+ # Returns the total token count across all categories.
48
+ #
49
+ # @rbs return: Integer
50
+ def total_tokens: () -> Integer
51
+
52
+ # Returns +true+ if any tokens have been counted.
53
+ #
54
+ # @rbs return: bool
55
+ def any?: () -> bool
56
+
57
+ # Returns the estimated cost in USD, or +nil+ if no pricing was provided.
58
+ #
59
+ # @rbs return: Float?
60
+ def estimated_cost: () -> Float?
61
+ end
@@ -0,0 +1,28 @@
1
+ # Generated from lib/riffer/rig/tools/bash.rb with RBS::Inline
2
+
3
+ class Riffer::Rig::Tools::Bash < Riffer::Tool
4
+ DEFAULT_TIMEOUT_MS: Integer
5
+
6
+ MAX_OUTPUT_BYTES: Integer
7
+
8
+ # @rbs context: Riffer::Agent::Context?
9
+ # @rbs command: String
10
+ # @rbs ?timeout_ms: Integer
11
+ # @rbs return: Riffer::Tools::Response
12
+ def call: (context: Riffer::Agent::Context?, command: String, ?timeout_ms: untyped) -> Riffer::Tools::Response
13
+
14
+ private
15
+
16
+ # @rbs command: String
17
+ # @rbs timeout_seconds: Float
18
+ # @rbs return: [String, Integer]
19
+ def run: (String command, Float timeout_seconds) -> [ String, Integer ]
20
+
21
+ # @rbs pid: Integer
22
+ # @rbs return: Integer
23
+ def kill_group: (Integer pid) -> Integer
24
+
25
+ # @rbs output: String
26
+ # @rbs return: String
27
+ def truncate: (String output) -> String
28
+ end
@@ -0,0 +1,11 @@
1
+ # Generated from lib/riffer/rig/tools/edit.rb with RBS::Inline
2
+
3
+ class Riffer::Rig::Tools::Edit < Riffer::Tool
4
+ # @rbs context: Riffer::Agent::Context?
5
+ # @rbs path: String
6
+ # @rbs old_string: String
7
+ # @rbs new_string: String
8
+ # @rbs ?replace_all: bool
9
+ # @rbs return: Riffer::Tools::Response
10
+ def call: (context: Riffer::Agent::Context?, path: String, old_string: String, new_string: String, ?replace_all: untyped) -> Riffer::Tools::Response
11
+ end
@@ -0,0 +1,12 @@
1
+ # Generated from lib/riffer/rig/tools/read.rb with RBS::Inline
2
+
3
+ class Riffer::Rig::Tools::Read < Riffer::Tool
4
+ DEFAULT_LIMIT: Integer
5
+
6
+ # @rbs context: Riffer::Agent::Context?
7
+ # @rbs path: String
8
+ # @rbs ?offset: Integer?
9
+ # @rbs ?limit: Integer
10
+ # @rbs return: Riffer::Tools::Response
11
+ def call: (context: Riffer::Agent::Context?, path: String, ?offset: untyped, ?limit: untyped) -> Riffer::Tools::Response
12
+ end
@@ -0,0 +1,9 @@
1
+ # Generated from lib/riffer/rig/tools/write.rb with RBS::Inline
2
+
3
+ class Riffer::Rig::Tools::Write < Riffer::Tool
4
+ # @rbs context: Riffer::Agent::Context?
5
+ # @rbs path: String
6
+ # @rbs content: String
7
+ # @rbs return: Riffer::Tools::Response
8
+ def call: (context: Riffer::Agent::Context?, path: String, content: String) -> Riffer::Tools::Response
9
+ end