riffer-rig 0.4.0 → 0.5.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/lib/riffer/rig/cli.rb +6 -7
  4. data/lib/riffer/rig/coding_agent.rb +1 -6
  5. data/lib/riffer/rig/credentials.rb +7 -7
  6. data/lib/riffer/rig/extension.rb +31 -0
  7. data/lib/riffer/rig/host.rb +52 -0
  8. data/lib/riffer/rig/registrar.rb +23 -0
  9. data/lib/riffer/rig/repl.rb +39 -27
  10. data/lib/riffer/rig/runtime.rb +162 -0
  11. data/lib/riffer/rig/settings/document.rb +23 -0
  12. data/lib/riffer/rig/settings/pricing.rb +11 -0
  13. data/lib/riffer/rig/settings.rb +9 -17
  14. data/lib/riffer/rig/token_tally.rb +1 -1
  15. data/lib/riffer/rig/tools/bash.rb +1 -1
  16. data/lib/riffer/rig/tools/edit.rb +1 -1
  17. data/lib/riffer/rig/tools/read.rb +2 -2
  18. data/lib/riffer/rig/ui/animator.rb +6 -6
  19. data/lib/riffer/rig/ui/cursor.rb +4 -4
  20. data/lib/riffer/rig/ui/renderer.rb +9 -7
  21. data/lib/riffer/rig/ui/smoother.rb +4 -4
  22. data/lib/riffer/rig/ui/theme.rb +2 -2
  23. data/lib/riffer/rig/version.rb +1 -1
  24. data/lib/riffer/rig.rb +31 -0
  25. data/sig/generated/riffer/rig/cli.rbs +8 -8
  26. data/sig/generated/riffer/rig/credentials.rbs +4 -3
  27. data/sig/generated/riffer/rig/extension.rbs +28 -0
  28. data/sig/generated/riffer/rig/host.rbs +42 -0
  29. data/sig/generated/riffer/rig/registrar.rbs +17 -0
  30. data/sig/generated/riffer/rig/repl.rbs +21 -12
  31. data/sig/generated/riffer/rig/runtime.rbs +101 -0
  32. data/sig/generated/riffer/rig/settings/document.rbs +20 -0
  33. data/sig/generated/riffer/rig/settings/pricing.rbs +4 -0
  34. data/sig/generated/riffer/rig/settings.rbs +5 -5
  35. data/sig/generated/riffer/rig/token_tally.rbs +2 -2
  36. data/sig/generated/riffer/rig/tools/bash.rbs +2 -2
  37. data/sig/generated/riffer/rig/tools/edit.rbs +2 -2
  38. data/sig/generated/riffer/rig/tools/read.rbs +3 -3
  39. data/sig/generated/riffer/rig/ui/animator.rbs +8 -8
  40. data/sig/generated/riffer/rig/ui/cursor.rbs +4 -4
  41. data/sig/generated/riffer/rig/ui/renderer.rbs +13 -11
  42. data/sig/generated/riffer/rig/ui/smoother.rbs +4 -4
  43. data/sig/generated/riffer/rig/ui/theme.rbs +2 -2
  44. data/sig/generated/riffer/rig.rbs +19 -0
  45. data/sig/manual/riffer/rig.rbs +11 -0
  46. metadata +22 -5
@@ -23,15 +23,15 @@ class Riffer::Rig::UI::Animator
23
23
 
24
24
  REASONING_TICK_RANGE = (1..5) #: Range[Integer]
25
25
 
26
- # @rbs @io: untyped
26
+ # @rbs @io: IO
27
27
  # @rbs @theme: Riffer::Rig::UI::Theme
28
28
  # @rbs @thread: Thread?
29
29
  # @rbs @mode: Symbol
30
30
  # @rbs @phrase: String?
31
31
  # @rbs @stop: bool
32
32
 
33
- # @rbs io: untyped
34
- # @rbs ?theme: Riffer::Rig::UI::Theme
33
+ # @rbs io: IO
34
+ # @rbs theme: Riffer::Rig::UI::Theme
35
35
  # @rbs return: void
36
36
  def initialize(io: $stdout, theme: Riffer::Rig::UI::Theme.for(io))
37
37
  @io = io
@@ -60,7 +60,7 @@ class Riffer::Rig::UI::Animator
60
60
  end
61
61
  end
62
62
 
63
- # @rbs ?mode: Symbol
63
+ # @rbs mode: Symbol
64
64
  # @rbs return: void
65
65
  def start(mode = :neutral)
66
66
  return unless enabled?
@@ -88,7 +88,7 @@ class Riffer::Rig::UI::Animator
88
88
  end
89
89
 
90
90
  # @rbs tick: Integer
91
- # @rbs ?label: String
91
+ # @rbs label: String
92
92
  # @rbs return: String
93
93
  def equalizer(tick, label = NEUTRAL_LABEL)
94
94
  bars = Array.new(EQ_BARS) do |i|
@@ -141,6 +141,6 @@ class Riffer::Rig::UI::Animator
141
141
 
142
142
  # @rbs return: bool
143
143
  def enabled?
144
- @theme.enabled && @io.respond_to?(:tty?) && @io.tty?
144
+ @theme.enabled && @io.tty?
145
145
  end
146
146
  end
@@ -7,11 +7,11 @@ class Riffer::Rig::UI::Cursor
7
7
 
8
8
  SHOW = "\e[?25h" #: String
9
9
 
10
- # @rbs @io: untyped
10
+ # @rbs @io: IO
11
11
  # @rbs @theme: Riffer::Rig::UI::Theme
12
12
 
13
- # @rbs io: untyped
14
- # @rbs ?theme: Riffer::Rig::UI::Theme
13
+ # @rbs io: IO
14
+ # @rbs theme: Riffer::Rig::UI::Theme
15
15
  # @rbs return: void
16
16
  def initialize(io: $stdout, theme: Riffer::Rig::UI::Theme.for(io))
17
17
  @io = io
@@ -41,6 +41,6 @@ class Riffer::Rig::UI::Cursor
41
41
 
42
42
  # @rbs return: bool
43
43
  def enabled?
44
- @theme.enabled && @io.respond_to?(:tty?) && @io.tty?
44
+ @theme.enabled && @io.tty?
45
45
  end
46
46
  end
@@ -5,17 +5,17 @@ require 'json'
5
5
  class Riffer::Rig::UI::Renderer
6
6
  RESULT_PREVIEW_LIMIT = 200 #: Integer
7
7
 
8
- # @rbs @io: untyped
8
+ # @rbs @io: IO
9
9
  # @rbs @theme: Riffer::Rig::UI::Theme
10
10
  # @rbs @tally: Riffer::Rig::TokenTally?
11
11
  # @rbs @smoother: Riffer::Rig::UI::Smoother | PassThroughSmoother?
12
12
  # @rbs @deferred_usage: Riffer::Providers::TokenUsage?
13
13
  # @rbs @prose_gap_pending: bool
14
14
 
15
- # @rbs io: untyped
16
- # @rbs ?theme: Riffer::Rig::UI::Theme
17
- # @rbs ?tally: Riffer::Rig::TokenTally?
18
- # @rbs ?smoother: Riffer::Rig::UI::Smoother | PassThroughSmoother?
15
+ # @rbs io: IO
16
+ # @rbs theme: Riffer::Rig::UI::Theme
17
+ # @rbs tally: Riffer::Rig::TokenTally?
18
+ # @rbs smoother: Riffer::Rig::UI::Smoother | PassThroughSmoother?
19
19
  # @rbs return: void
20
20
  def initialize(io: $stdout, theme: Riffer::Rig::UI::Theme.for(io), tally: nil, smoother: nil)
21
21
  @io = io
@@ -92,6 +92,7 @@ class Riffer::Rig::UI::Renderer
92
92
  # so the next group opens with its own gap.
93
93
  #
94
94
  # @rbs indent: Integer
95
+ # @rbs &block: () -> String
95
96
  # @rbs return: void
96
97
  def render_block(indent, &)
97
98
  drain_smoother
@@ -116,6 +117,7 @@ class Riffer::Rig::UI::Renderer
116
117
  end
117
118
 
118
119
  # @rbs indent: Integer
120
+ # @rbs &block: () -> String
119
121
  # @rbs return: void
120
122
  def render_tool_activity(indent, &)
121
123
  open_tool_activity
@@ -158,9 +160,9 @@ class Riffer::Rig::UI::Renderer
158
160
  # Stand-in when no smoother is injected, so a bare Riffer::Rig::UI::Renderer still prints
159
161
  # synchronously.
160
162
  class PassThroughSmoother
161
- # @rbs @io: untyped
163
+ # @rbs @io: IO
162
164
 
163
- # @rbs io: untyped
165
+ # @rbs io: IO
164
166
  # @rbs return: void
165
167
  def initialize(io) = @io = io
166
168
 
@@ -17,7 +17,7 @@ class Riffer::Rig::UI::Smoother
17
17
 
18
18
  MIN_CHARS_PER_TICK = Rational(1, 6) #: Rational
19
19
 
20
- # @rbs @io: untyped
20
+ # @rbs @io: IO
21
21
  # @rbs @theme: Riffer::Rig::UI::Theme
22
22
  # @rbs @clock: singleton(Kernel)
23
23
  # @rbs @backlog: String
@@ -27,8 +27,8 @@ class Riffer::Rig::UI::Smoother
27
27
  # @rbs @stop: bool
28
28
  # @rbs @newline_pending: bool
29
29
 
30
- # @rbs io: untyped
31
- # @rbs ?theme: Riffer::Rig::UI::Theme
30
+ # @rbs io: IO
31
+ # @rbs theme: Riffer::Rig::UI::Theme
32
32
  # @rbs clock: singleton(Kernel)
33
33
  # @rbs return: void
34
34
  def initialize(io: $stdout, theme: Riffer::Rig::UI::Theme.for(io), clock: Kernel)
@@ -129,6 +129,6 @@ class Riffer::Rig::UI::Smoother
129
129
 
130
130
  # @rbs return: bool
131
131
  def enabled?
132
- @theme.enabled && @io.respond_to?(:tty?) && @io.tty?
132
+ @theme.enabled && @io.tty?
133
133
  end
134
134
  end
@@ -15,10 +15,10 @@ class Riffer::Rig::UI::Theme
15
15
  @enabled = enabled
16
16
  end
17
17
 
18
- # @rbs io: untyped
18
+ # @rbs io: IO
19
19
  # @rbs return: Riffer::Rig::UI::Theme
20
20
  def self.for(io)
21
- new(enabled: io.respond_to?(:tty?) && io.tty? && !ENV.key?('NO_COLOR'))
21
+ new(enabled: io.tty? && !ENV.key?('NO_COLOR'))
22
22
  end
23
23
 
24
24
  # @rbs text: String
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Riffer
4
4
  module Rig
5
- VERSION = '0.4.0'
5
+ VERSION = '0.5.0'
6
6
  end
7
7
  end
data/lib/riffer/rig.rb CHANGED
@@ -8,3 +8,34 @@ loader = Zeitwerk::Loader.for_gem_extension(Riffer)
8
8
  loader.ignore("#{__dir__}/rig/version.rb")
9
9
  loader.inflector.inflect('cli' => 'CLI', 'repl' => 'REPL', 'ui' => 'UI')
10
10
  loader.setup
11
+
12
+ module Riffer::Rig
13
+ # @rbs self.@extensions: Hash[String, Riffer::Rig::Extension]
14
+ @extensions = {} #: Hash[String, Riffer::Rig::Extension]
15
+
16
+ # Records an extension block in the process registry and returns the
17
+ # extension object. Re-recording a name replaces the block.
18
+ #
19
+ # Riffer::Rig.extension('git') do |rig|
20
+ # rig.tool GitLog
21
+ # end
22
+ #
23
+ # @rbs name: String
24
+ # @rbs requires: String?
25
+ # @rbs &block: (::Riffer::Rig::Registrar) -> void
26
+ # @rbs return: Riffer::Rig::Extension
27
+ def self.extension(name, requires: nil, &)
28
+ ext = Extension.new(name, requires: requires, &)
29
+ if ext.requires && !ext.requires.satisfied_by?(Gem::Version.new(Riffer::Rig::VERSION))
30
+ raise Riffer::ArgumentError,
31
+ "extension #{name} requires riffer-rig #{ext.requires}, found #{Riffer::Rig::VERSION}"
32
+ end
33
+
34
+ @extensions[name] = ext
35
+ end
36
+
37
+ # @rbs return: Hash[String, Riffer::Rig::Extension]
38
+ def self.extensions
39
+ @extensions.dup
40
+ end
41
+ end
@@ -3,10 +3,10 @@
3
3
  module Riffer::Rig::CLI
4
4
  PROVIDER_URLS: Hash[String, String]
5
5
 
6
- # @rbs output: untyped
7
- # @rbs input: untyped
6
+ # @rbs output: IO
7
+ # @rbs input: IO
8
8
  # @rbs return: Integer
9
- def start: (?output: untyped, ?input: untyped) -> Integer
9
+ def start: (?output: IO, ?input: IO) -> Integer
10
10
 
11
11
  private
12
12
 
@@ -17,18 +17,18 @@ module Riffer::Rig::CLI
17
17
 
18
18
  # @rbs provider: String?
19
19
  # @rbs theme: Riffer::Rig::UI::Theme
20
- # @rbs output: untyped
21
- # @rbs input: untyped
20
+ # @rbs output: IO
21
+ # @rbs input: IO
22
22
  # @rbs return: String?
23
- def onboard: (String? provider, Riffer::Rig::UI::Theme theme, output: untyped, input: untyped) -> String?
23
+ def onboard: (String? provider, Riffer::Rig::UI::Theme theme, output: IO, input: IO) -> String?
24
24
 
25
25
  # @rbs provider: String?
26
26
  # @rbs return: String
27
27
  def env_var_for: (String? provider) -> String
28
28
 
29
- # @rbs input: untyped
29
+ # @rbs input: IO
30
30
  # @rbs return: String?
31
- def read_secret: (untyped input) -> String?
31
+ def read_secret: (IO input) -> String?
32
32
 
33
33
  # @rbs theme: Riffer::Rig::UI::Theme
34
34
  # @rbs animator: Riffer::Rig::UI::Animator
@@ -47,9 +47,10 @@ module Riffer::Rig::Credentials
47
47
  def key_from_file: (String? provider, String path) -> String?
48
48
 
49
49
  # The parsed auth file, or an empty hash when the file is absent or
50
- # malformed.
50
+ # malformed. Non-string values can't be keys, so they're dropped here rather
51
+ # than re-checked by every reader.
51
52
  #
52
53
  # @rbs path: String
53
- # @rbs return: Hash[String, untyped]
54
- def read: (String path) -> Hash[String, untyped]
54
+ # @rbs return: Hash[String, String]
55
+ def read: (String path) -> Hash[String, String]
55
56
  end
@@ -0,0 +1,28 @@
1
+ # Generated from lib/riffer/rig/extension.rb with RBS::Inline
2
+
3
+ # An extension recorded by <tt>Riffer::Rig.extension</tt>: a name, an optional
4
+ # Gem::Requirement on riffer-rig, and the block that runs against a Runtime's
5
+ # registrar. The process registry holds these objects; Runtime.new runs their
6
+ # blocks.
7
+ class Riffer::Rig::Extension
8
+ @name: String
9
+
10
+ @requires: Gem::Requirement?
11
+
12
+ @block: ^(::Riffer::Rig::Registrar) -> void
13
+
14
+ # @dynamic name, requires
15
+ attr_reader name: String
16
+
17
+ attr_reader requires: Gem::Requirement?
18
+
19
+ # @rbs name: String
20
+ # @rbs requires: String?
21
+ # @rbs &block: (::Riffer::Rig::Registrar) -> void
22
+ # @rbs return: void
23
+ def initialize: (String name, ?requires: String?) { (::Riffer::Rig::Registrar) -> void } -> void
24
+
25
+ # @rbs registrar: Riffer::Rig::Registrar
26
+ # @rbs return: void
27
+ def run: (Riffer::Rig::Registrar registrar) -> void
28
+ end
@@ -0,0 +1,42 @@
1
+ # Generated from lib/riffer/rig/host.rb with RBS::Inline
2
+
3
+ # A host receives questions and out-of-band messages from a Runtime. It is
4
+ # duck-typed: any object with #ask, #confirm, #notify, #progress and
5
+ # #capabilities is a host.
6
+ #
7
+ # class HeadlessHost
8
+ # def capabilities = Set[:notify, :progress].freeze
9
+ # def ask(*) = nil
10
+ # def confirm(*) = false
11
+ # def notify(message, level:) = warn("[#{level}] #{message}")
12
+ # def progress(label) = yield
13
+ # end
14
+ #
15
+ # Callers check #capabilities before asking, so a host that declines a
16
+ # capability is never asked and the caller takes the declined path.
17
+ # The do-nothing host: the default +host:+ for a Runtime. Every capability is
18
+ # declined, so callers take the declined path without any UI attempt.
19
+ class Riffer::Rig::Host
20
+ # @rbs return: Set[Symbol]
21
+ def capabilities: () -> Set[Symbol]
22
+
23
+ # @rbs _question: String?
24
+ # @rbs options: Array[String]?
25
+ # @rbs secret: bool
26
+ # @rbs return: String?
27
+ def ask: (?untyped _question, ?options: Array[String]?, ?secret: bool) -> String?
28
+
29
+ # @rbs _question: String?
30
+ # @rbs return: bool
31
+ def confirm: (?untyped _question) -> bool
32
+
33
+ # @rbs _message: String?
34
+ # @rbs level: Symbol
35
+ # @rbs return: void
36
+ def notify: (?untyped _message, ?level: Symbol) -> void
37
+
38
+ # @rbs _label: String?
39
+ # @rbs &block: ^() -> void
40
+ # @rbs return: void
41
+ def progress: (?untyped _label) ?{ (?) -> untyped } -> void
42
+ end
@@ -0,0 +1,17 @@
1
+ # Generated from lib/riffer/rig/registrar.rb with RBS::Inline
2
+
3
+ # The per-Runtime registrar extension blocks run against. Seams are added one
4
+ # at a time; today only #tool exists.
5
+ class Riffer::Rig::Registrar
6
+ @tools: Array[singleton(Riffer::Tool)]
7
+
8
+ # @rbs return: void
9
+ def initialize: () -> void
10
+
11
+ # @rbs klass: singleton(Riffer::Tool)
12
+ # @rbs return: void
13
+ def tool: (singleton(Riffer::Tool) klass) -> void
14
+
15
+ # @rbs return: Array[singleton(Riffer::Tool)]
16
+ def tools: () -> Array[singleton(Riffer::Tool)]
17
+ end
@@ -5,9 +5,9 @@ class Riffer::Rig::REPL
5
5
 
6
6
  SKILL_COMMAND: Regexp
7
7
 
8
- @output: untyped
8
+ @output: IO
9
9
 
10
- @input: untyped
10
+ @input: IO
11
11
 
12
12
  @theme: Riffer::Rig::UI::Theme
13
13
 
@@ -21,16 +21,16 @@ class Riffer::Rig::REPL
21
21
 
22
22
  @agent: Riffer::Agent
23
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
24
+ # @rbs agent: Riffer::Agent
25
+ # @rbs renderer: Riffer::Rig::UI::Renderer
26
+ # @rbs input: IO
27
+ # @rbs output: IO
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
32
  # @rbs return: void
33
- def initialize: (agent: untyped, renderer: untyped, ?input: untyped, ?output: untyped, ?theme: untyped, ?animator: untyped, ?smoother: untyped, ?cursor: untyped) -> void
33
+ def initialize: (agent: Riffer::Agent, renderer: Riffer::Rig::UI::Renderer, ?input: IO, ?output: IO, ?theme: Riffer::Rig::UI::Theme, ?animator: Riffer::Rig::UI::Animator, ?smoother: Riffer::Rig::UI::Smoother, ?cursor: Riffer::Rig::UI::Cursor) -> void
34
34
 
35
35
  # @rbs return: Symbol
36
36
  def run: () -> Symbol
@@ -59,10 +59,19 @@ class Riffer::Rig::REPL
59
59
  # their line with a newline but leave the renderer's tool-group state alone —
60
60
  # they can only follow prose, never mid-group.
61
61
  #
62
+ # @rbs &block: () -> String
62
63
  # @rbs return: void
63
- def print_block: () ?{ (?) -> untyped } -> void
64
+ def print_block: () { () -> String } -> void
64
65
 
65
66
  # @rbs message: Riffer::Messages::Base
66
67
  # @rbs return: void
67
68
  def render_tool_result: (Riffer::Messages::Base message) -> void
69
+
70
+ # Every animator start sits behind a smoother drain: the smoother's backlog
71
+ # may still be trickling out from streamed prose, and spinner frames drawn
72
+ # mid-drain would carve `\r…\e[K` through a half-printed sentence.
73
+ #
74
+ # @rbs mode: Symbol
75
+ # @rbs return: void
76
+ def start_animator: (?Symbol mode) -> void
68
77
  end
@@ -0,0 +1,101 @@
1
+ # Generated from lib/riffer/rig/runtime.rb with RBS::Inline
2
+
3
+ # One Runtime builds its own Riffer::Agent from a per-instance
4
+ # Riffer::Agent::Config and runs a prompt: streamed as events, or run to
5
+ # completion and returned as riffer's Agent::Response.
6
+ #
7
+ # runtime = Riffer::Rig::Runtime.new('mock/x')
8
+ # runtime.prompt('hello') { |event| ... } # yields riffer StreamEvents
9
+ # runtime.prompt('hello').each { |event| } # an Enumerator without a block
10
+ # response = runtime.ask('hello') # a Riffer::Agent::Response
11
+ #
12
+ # Two Runtimes in one process share nothing but the process-wide extension
13
+ # registry and riffer's provider repository. One prompt runs at a time; a
14
+ # second while one is running raises Riffer::Rig::Runtime::BusyError. The
15
+ # Runtime never renders, never prints, never reads the filesystem.
16
+ class Riffer::Rig::Runtime
17
+ # Raised when a second prompt, ask or registrar build runs while one is
18
+ # already running on this Runtime.
19
+ class BusyError < StandardError
20
+ end
21
+
22
+ BASE_PROMPT_TEMPLATE: ::String
23
+
24
+ DEFAULT_NAME: ::String
25
+
26
+ # The legacy CodingAgent's default: an unlimited agent loop. riffer's own
27
+ # default (16) is too small for a general-purpose harness.
28
+ DEFAULT_MAX_STEPS: Integer?
29
+
30
+ interface _Host
31
+ def ask: (?String, ?options: Array[String]?, ?secret: bool) -> String?
32
+
33
+ def confirm: (?String) -> bool
34
+
35
+ def notify: (?String, ?level: Symbol) -> void
36
+
37
+ def progress: (?String) { () -> void } -> void
38
+
39
+ def capabilities: () -> Set[Symbol]
40
+ end
41
+
42
+ @registrar: Riffer::Rig::Registrar
43
+
44
+ @busy: bool
45
+
46
+ @settings: Hash[Symbol, untyped]
47
+
48
+ @host: _Host
49
+
50
+ @cwd: String
51
+
52
+ @agent: Riffer::Agent
53
+
54
+ # @dynamic agent, cwd, host, settings
55
+ attr_reader agent: Riffer::Agent
56
+
57
+ attr_reader cwd: String
58
+
59
+ attr_reader host: _Host
60
+
61
+ attr_reader settings: Hash[Symbol, untyped]
62
+
63
+ # @rbs model: String
64
+ # @rbs extensions: Array[Riffer::Rig::Extension]
65
+ # @rbs tools: Array[String]?
66
+ # @rbs settings: Hash[Symbol, untyped]
67
+ # @rbs host: _Host
68
+ # @rbs cwd: String?
69
+ # @rbs name: String
70
+ # @rbs instructions: String?
71
+ # @rbs credentials: Hash[String, String]
72
+ # @rbs pricing: Hash[String, Riffer::Rig::Settings::Pricing]
73
+ # @rbs max_steps: Integer?
74
+ # @rbs snapshot: Hash[Symbol, untyped]?
75
+ # @rbs return: void
76
+ def initialize: (String model, ?extensions: Array[Riffer::Rig::Extension], ?tools: Array[String]?, ?settings: Hash[Symbol, untyped], ?host: _Host, ?cwd: String?, ?name: String, ?instructions: String?, ?credentials: Hash[String, String], ?pricing: Hash[String, Riffer::Rig::Settings::Pricing], ?max_steps: Integer?, ?snapshot: Hash[Symbol, untyped]?) -> void
77
+
78
+ # @rbs text: String
79
+ # @rbs &block: ?(Riffer::StreamEvents::Base) -> void
80
+ # @rbs return: (nil | Enumerator[Riffer::StreamEvents::Base, void])
81
+ def prompt: (String text) ?{ (Riffer::StreamEvents::Base) -> void } -> (nil | Enumerator[Riffer::StreamEvents::Base, void])
82
+
83
+ # @rbs text: String
84
+ # @rbs return: Riffer::Agent::Response
85
+ def ask: (String text) -> Riffer::Agent::Response
86
+
87
+ private
88
+
89
+ # @rbs extensions: Array[Riffer::Rig::Extension]
90
+ # @rbs return: Riffer::Rig::Registrar
91
+ def build_registrar: (Array[Riffer::Rig::Extension] extensions) -> Riffer::Rig::Registrar
92
+
93
+ # @rbs registered: Array[singleton(Riffer::Tool)]
94
+ # @rbs allowlist: Array[String]?
95
+ # @rbs return: Array[singleton(Riffer::Tool)]
96
+ def select_tools: (Array[singleton(Riffer::Tool)] registered, Array[String]? allowlist) -> Array[singleton(Riffer::Tool)]
97
+
98
+ # @rbs base_prompt: String
99
+ # @rbs return: String
100
+ def system_prompt: (String base_prompt) -> String
101
+ end
@@ -0,0 +1,20 @@
1
+ # Generated from lib/riffer/rig/settings/document.rb with RBS::Inline
2
+
3
+ class Riffer::Rig::Settings::Document
4
+ @model: String?
5
+
6
+ @reasoning: String?
7
+
8
+ @models: Hash[String, Riffer::Rig::Settings::Pricing]
9
+
10
+ # @dynamic model, reasoning, models
11
+ attr_reader model: String?
12
+
13
+ attr_reader reasoning: String?
14
+
15
+ attr_reader models: Hash[String, Riffer::Rig::Settings::Pricing]
16
+
17
+ # @rbs source: untyped
18
+ # @rbs return: void
19
+ def initialize: (untyped source) -> void
20
+ end
@@ -14,6 +14,10 @@ class Riffer::Rig::Settings::Pricing
14
14
  # @dynamic input, output, cache_write, cache_read
15
15
  attr_reader cache_read: Float
16
16
 
17
+ # @rbs entry: Hash[String, untyped]
18
+ # @rbs return: ::Riffer::Rig::Settings::Pricing
19
+ def self.from: (Hash[String, untyped] entry) -> ::Riffer::Rig::Settings::Pricing
20
+
17
21
  # @rbs input: Float
18
22
  # @rbs output: Float
19
23
  # @rbs cache_write: Float
@@ -71,9 +71,9 @@ module Riffer::Rig::Settings
71
71
  def base_options: (String? provider) -> Hash[Symbol, untyped]
72
72
 
73
73
  # @rbs path: String
74
- # @rbs ?provider: String?
74
+ # @rbs provider: String?
75
75
  # @rbs return: String?
76
- def reasoning_for: (?path: String, ?provider: untyped) -> String?
76
+ def reasoning_for: (?path: String, ?provider: String?) -> String?
77
77
 
78
78
  # Maps a reasoning level to the provider-specific model option hash expected
79
79
  # by Riffer. Returns an empty hash when +level+ is +nil+.
@@ -83,10 +83,10 @@ module Riffer::Rig::Settings
83
83
  # @rbs return: Hash[Symbol, untyped]
84
84
  def reasoning_options: (String? level, String? provider) -> Hash[Symbol, untyped]
85
85
 
86
- # The parsed settings file, or an empty hash when the file is absent or
86
+ # The parsed settings file, or an empty document when the file is absent or
87
87
  # malformed.
88
88
  #
89
89
  # @rbs path: String
90
- # @rbs return: Hash[String, untyped]
91
- def read: (String path) -> Hash[String, untyped]
90
+ # @rbs return: Document
91
+ def read: (String path) -> Document
92
92
  end
@@ -34,9 +34,9 @@ class Riffer::Rig::TokenTally
34
34
  # @dynamic input_tokens, output_tokens, cache_write_tokens, cache_read_tokens
35
35
  attr_reader cache_read_tokens: untyped
36
36
 
37
- # @rbs ?pricing: Riffer::Rig::Settings::Pricing?
37
+ # @rbs pricing: Riffer::Rig::Settings::Pricing?
38
38
  # @rbs return: void
39
- def initialize: (?pricing: untyped) -> void
39
+ def initialize: (?pricing: Riffer::Rig::Settings::Pricing?) -> void
40
40
 
41
41
  # Accumulates token counts from a +Riffer::Providers::TokenUsage+ object.
42
42
  #
@@ -7,9 +7,9 @@ class Riffer::Rig::Tools::Bash < Riffer::Tool
7
7
 
8
8
  # @rbs context: Riffer::Agent::Context?
9
9
  # @rbs command: String
10
- # @rbs ?timeout_ms: Integer
10
+ # @rbs timeout_ms: Integer
11
11
  # @rbs return: Riffer::Tools::Response
12
- def call: (context: Riffer::Agent::Context?, command: String, ?timeout_ms: untyped) -> Riffer::Tools::Response
12
+ def call: (context: Riffer::Agent::Context?, command: String, ?timeout_ms: Integer) -> Riffer::Tools::Response
13
13
 
14
14
  private
15
15
 
@@ -5,7 +5,7 @@ class Riffer::Rig::Tools::Edit < Riffer::Tool
5
5
  # @rbs path: String
6
6
  # @rbs old_string: String
7
7
  # @rbs new_string: String
8
- # @rbs ?replace_all: bool
8
+ # @rbs replace_all: bool
9
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
10
+ def call: (context: Riffer::Agent::Context?, path: String, old_string: String, new_string: String, ?replace_all: bool) -> Riffer::Tools::Response
11
11
  end
@@ -5,8 +5,8 @@ class Riffer::Rig::Tools::Read < Riffer::Tool
5
5
 
6
6
  # @rbs context: Riffer::Agent::Context?
7
7
  # @rbs path: String
8
- # @rbs ?offset: Integer?
9
- # @rbs ?limit: Integer
8
+ # @rbs offset: Integer?
9
+ # @rbs limit: Integer
10
10
  # @rbs return: Riffer::Tools::Response
11
- def call: (context: Riffer::Agent::Context?, path: String, ?offset: untyped, ?limit: untyped) -> Riffer::Tools::Response
11
+ def call: (context: Riffer::Agent::Context?, path: String, ?offset: Integer?, ?limit: Integer) -> Riffer::Tools::Response
12
12
  end
@@ -27,12 +27,12 @@ class Riffer::Rig::UI::Animator
27
27
 
28
28
  @theme: Riffer::Rig::UI::Theme
29
29
 
30
- @io: untyped
30
+ @io: IO
31
31
 
32
- # @rbs io: untyped
33
- # @rbs ?theme: Riffer::Rig::UI::Theme
32
+ # @rbs io: IO
33
+ # @rbs theme: Riffer::Rig::UI::Theme
34
34
  # @rbs return: void
35
- def initialize: (?io: untyped, ?theme: untyped) -> void
35
+ def initialize: (?io: IO, ?theme: Riffer::Rig::UI::Theme) -> void
36
36
 
37
37
  # When not on a TTY, prints the final frame once instead of animating.
38
38
  #
@@ -40,17 +40,17 @@ class Riffer::Rig::UI::Animator
40
40
  # @rbs return: void
41
41
  def reveal: (Array[Array[String]] frames) -> void
42
42
 
43
- # @rbs ?mode: Symbol
43
+ # @rbs mode: Symbol
44
44
  # @rbs return: void
45
- def start: (?untyped mode) -> void
45
+ def start: (?Symbol mode) -> void
46
46
 
47
47
  # @rbs return: void
48
48
  def stop: () -> void
49
49
 
50
50
  # @rbs tick: Integer
51
- # @rbs ?label: String
51
+ # @rbs label: String
52
52
  # @rbs return: String
53
- def equalizer: (Integer tick, ?untyped label) -> String
53
+ def equalizer: (Integer tick, ?String label) -> String
54
54
 
55
55
  private
56
56