riffer-rig 0.6.0 → 0.7.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 +4 -4
- data/CHANGELOG.md +36 -0
- data/README.md +37 -4
- data/exe/riffer +1 -1
- data/lib/riffer/rig/bundled/agents_md.rb +7 -0
- data/lib/riffer/rig/bundled/bash.rb +5 -0
- data/lib/riffer/rig/bundled/edit.rb +5 -0
- data/lib/riffer/rig/bundled/mcp.rb +9 -0
- data/lib/riffer/rig/bundled/read.rb +5 -0
- data/lib/riffer/rig/bundled/skills.rb +10 -0
- data/lib/riffer/rig/bundled/write.rb +5 -0
- data/lib/riffer/rig/bundled.rb +7 -0
- data/lib/riffer/rig/cli/flags.rb +77 -0
- data/lib/riffer/rig/cli.rb +69 -106
- data/lib/riffer/rig/command/context.rb +70 -0
- data/lib/riffer/rig/command.rb +29 -0
- data/lib/riffer/rig/commands/model.rb +54 -0
- data/lib/riffer/rig/commands/skill.rb +27 -0
- data/lib/riffer/rig/commands.rb +4 -0
- data/lib/riffer/rig/credentials.rb +2 -2
- data/lib/riffer/rig/directories.rb +20 -0
- data/lib/riffer/rig/env/invalid.rb +13 -0
- data/lib/riffer/rig/env.rb +12 -1
- data/lib/riffer/rig/events/after_response.rb +25 -0
- data/lib/riffer/rig/events/after_tool_call.rb +31 -0
- data/lib/riffer/rig/events/before_prompt.rb +25 -0
- data/lib/riffer/rig/events/before_request.rb +25 -0
- data/lib/riffer/rig/events/before_tool_call.rb +28 -0
- data/lib/riffer/rig/events/command_output.rb +3 -2
- data/lib/riffer/rig/events/notify.rb +3 -2
- data/lib/riffer/rig/events/session_end.rb +3 -2
- data/lib/riffer/rig/events/session_start.rb +3 -2
- data/lib/riffer/rig/events/skill_activated.rb +3 -2
- data/lib/riffer/rig/events/turn_end.rb +3 -2
- data/lib/riffer/rig/extension/failure.rb +16 -0
- data/lib/riffer/rig/extension.rb +16 -1
- data/lib/riffer/rig/hosts/mirror.rb +6 -7
- data/lib/riffer/rig/hosts/null.rb +1 -1
- data/lib/riffer/rig/loader.rb +163 -0
- data/lib/riffer/rig/mcp/declaration.rb +23 -0
- data/lib/riffer/rig/mcp/server.rb +16 -0
- data/lib/riffer/rig/mcp.rb +12 -0
- data/lib/riffer/rig/prompts/agents_md.rb +32 -0
- data/lib/riffer/rig/prompts.rb +4 -0
- data/lib/riffer/rig/registrar.rb +120 -5
- data/lib/riffer/rig/runtime/blocked.rb +13 -0
- data/lib/riffer/rig/runtime/hooks.rb +78 -0
- data/lib/riffer/rig/runtime/request_guardrail.rb +24 -0
- data/lib/riffer/rig/runtime/tool_runtime.rb +44 -0
- data/lib/riffer/rig/runtime.rb +506 -57
- data/lib/riffer/rig/settings/document.rb +27 -16
- data/lib/riffer/rig/settings/pricing.rb +16 -5
- data/lib/riffer/rig/settings.rb +73 -43
- data/lib/riffer/rig/skills/sources.rb +28 -0
- data/lib/riffer/rig/skills.rb +12 -0
- data/lib/riffer/rig/{events/event.rb → support/equatable.rb} +2 -11
- data/lib/riffer/rig/{ui → terminal}/animator.rb +4 -4
- data/lib/riffer/rig/{ui → terminal}/banner.rb +17 -21
- data/lib/riffer/rig/{ui → terminal}/cursor.rb +4 -4
- data/lib/riffer/rig/terminal/host.rb +85 -0
- data/lib/riffer/rig/{ui → terminal}/palette.rb +1 -1
- data/lib/riffer/rig/{ui → terminal}/renderer.rb +115 -66
- data/lib/riffer/rig/{ui → terminal}/smoother.rb +4 -4
- data/lib/riffer/rig/{ui → terminal}/theme.rb +12 -12
- data/lib/riffer/rig/terminal.rb +207 -0
- data/lib/riffer/rig/tools/bash.rb +6 -4
- data/lib/riffer/rig/tools/edit.rb +3 -2
- data/lib/riffer/rig/tools/read.rb +3 -2
- data/lib/riffer/rig/tools/write.rb +3 -2
- data/lib/riffer/rig/version.rb +1 -1
- data/lib/riffer/rig.rb +8 -8
- data/sig/generated/riffer/rig/bundled/agents_md.rbs +5 -0
- data/sig/generated/riffer/rig/bundled/bash.rbs +5 -0
- data/sig/generated/riffer/rig/bundled/edit.rbs +5 -0
- data/sig/generated/riffer/rig/bundled/mcp.rbs +5 -0
- data/sig/generated/riffer/rig/bundled/read.rbs +5 -0
- data/sig/generated/riffer/rig/bundled/skills.rbs +5 -0
- data/sig/generated/riffer/rig/bundled/write.rbs +5 -0
- data/sig/generated/riffer/rig/bundled.rbs +5 -0
- data/sig/generated/riffer/rig/cli/flags.rbs +40 -0
- data/sig/generated/riffer/rig/cli.rbs +30 -35
- data/sig/generated/riffer/rig/command/context.rbs +50 -0
- data/sig/generated/riffer/rig/command.rbs +23 -0
- data/sig/generated/riffer/rig/commands/model.rbs +27 -0
- data/sig/generated/riffer/rig/commands/skill.rbs +12 -0
- data/sig/generated/riffer/rig/commands.rbs +4 -0
- data/sig/generated/riffer/rig/credentials.rbs +4 -4
- data/sig/generated/riffer/rig/directories.rbs +11 -0
- data/sig/generated/riffer/rig/env/invalid.rbs +10 -0
- data/sig/generated/riffer/rig/env.rbs +7 -1
- data/sig/generated/riffer/rig/events/after_response.rbs +18 -0
- data/sig/generated/riffer/rig/events/after_tool_call.rbs +24 -0
- data/sig/generated/riffer/rig/events/before_prompt.rbs +18 -0
- data/sig/generated/riffer/rig/events/before_request.rbs +18 -0
- data/sig/generated/riffer/rig/events/before_tool_call.rbs +21 -0
- data/sig/generated/riffer/rig/events/command_output.rbs +3 -1
- data/sig/generated/riffer/rig/events/notify.rbs +3 -1
- data/sig/generated/riffer/rig/events/session_end.rbs +3 -1
- data/sig/generated/riffer/rig/events/session_start.rbs +3 -1
- data/sig/generated/riffer/rig/events/skill_activated.rbs +3 -1
- data/sig/generated/riffer/rig/events/turn_end.rbs +3 -1
- data/sig/generated/riffer/rig/extension/failure.rbs +13 -0
- data/sig/generated/riffer/rig/extension.rbs +14 -1
- data/sig/generated/riffer/rig/hosts/mirror.rbs +9 -9
- data/sig/generated/riffer/rig/hosts/null.rbs +1 -1
- data/sig/generated/riffer/rig/loader.rbs +77 -0
- data/sig/generated/riffer/rig/mcp/declaration.rbs +18 -0
- data/sig/generated/riffer/rig/mcp/server.rbs +13 -0
- data/sig/generated/riffer/rig/mcp.rbs +8 -0
- data/sig/generated/riffer/rig/prompts/agents_md.rbs +19 -0
- data/sig/generated/riffer/rig/prompts.rbs +4 -0
- data/sig/generated/riffer/rig/registrar.rbs +78 -4
- data/sig/generated/riffer/rig/runtime/blocked.rbs +10 -0
- data/sig/generated/riffer/rig/runtime/hooks.rbs +49 -0
- data/sig/generated/riffer/rig/runtime/request_guardrail.rbs +16 -0
- data/sig/generated/riffer/rig/runtime/tool_runtime.rbs +23 -0
- data/sig/generated/riffer/rig/runtime.rbs +225 -22
- data/sig/generated/riffer/rig/settings/document.rbs +11 -11
- data/sig/generated/riffer/rig/settings/pricing.rbs +7 -2
- data/sig/generated/riffer/rig/settings.rbs +36 -23
- data/sig/generated/riffer/rig/skills/sources.rbs +18 -0
- data/sig/generated/riffer/rig/skills.rbs +7 -0
- data/sig/generated/riffer/rig/support/equatable.rbs +15 -0
- data/sig/generated/riffer/rig/{ui → terminal}/animator.rbs +5 -5
- data/sig/generated/riffer/rig/terminal/banner.rbs +39 -0
- data/sig/generated/riffer/rig/{ui → terminal}/cursor.rbs +5 -5
- data/sig/generated/riffer/rig/terminal/host.rbs +50 -0
- data/sig/generated/riffer/rig/{ui → terminal}/palette.rbs +2 -2
- data/sig/generated/riffer/rig/terminal/renderer.rbs +126 -0
- data/sig/generated/riffer/rig/{ui → terminal}/smoother.rbs +5 -5
- data/sig/generated/riffer/rig/{ui → terminal}/theme.rbs +5 -5
- data/sig/generated/riffer/rig/terminal.rbs +85 -0
- data/sig/generated/riffer/rig/tools/bash.rbs +2 -1
- data/sig/generated/riffer/rig.rbs +4 -0
- data/sig/manual/riffer/rig/commands/model.rbs +6 -0
- data/sig/manual/riffer/rig/commands/skill.rbs +6 -0
- data/sig/manual/riffer/rig/directories.rbs +6 -0
- data/sig/manual/riffer/rig/events.rbs +6 -0
- data/sig/manual/riffer/rig/hosts.rbs +7 -0
- data/sig/manual/riffer/rig/mcp.rbs +11 -0
- data/sig/manual/riffer/rig/prompts/agents_md.rbs +6 -0
- data/sig/manual/riffer/rig/{ui/banner.rbs → skills.rbs} +2 -2
- data/sig/manual/riffer/rig/support.rbs +8 -0
- data/sig/manual/riffer/rig/terminal/banner.rbs +6 -0
- metadata +140 -27
- data/lib/riffer/rig/coding_agent.rb +0 -53
- data/lib/riffer/rig/hosts/base.rb +0 -36
- data/lib/riffer/rig/repl.rb +0 -188
- data/lib/riffer/rig/token_tally.rb +0 -54
- data/sig/generated/riffer/rig/coding_agent.rbs +0 -9
- data/sig/generated/riffer/rig/events/event.rbs +0 -20
- data/sig/generated/riffer/rig/hosts/base.rbs +0 -26
- data/sig/generated/riffer/rig/repl.rbs +0 -69
- data/sig/generated/riffer/rig/token_tally.rbs +0 -42
- data/sig/generated/riffer/rig/ui/banner.rbs +0 -42
- data/sig/generated/riffer/rig/ui/renderer.rbs +0 -94
- data/sig/manual/riffer/rig/ui.rbs +0 -5
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Riffer::Rig::Commands::Skill
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
# @rbs skill: Riffer::Skills::Frontmatter
|
|
7
|
+
# @rbs return: Riffer::Rig::Command
|
|
8
|
+
def command(skill)
|
|
9
|
+
Riffer::Rig::Command.new("skill:#{skill.name}", description: skill.description, extension: 'core') do |ctx|
|
|
10
|
+
run(ctx, skill)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @rbs ctx: Riffer::Rig::Command::Context
|
|
15
|
+
# @rbs skill: Riffer::Skills::Frontmatter
|
|
16
|
+
# @rbs return: void
|
|
17
|
+
def run(ctx, skill)
|
|
18
|
+
skills = ctx.runtime.agent.context.skills
|
|
19
|
+
return ctx.host.notify("Skill #{skill.name} is no longer available", level: :error) unless skills
|
|
20
|
+
|
|
21
|
+
# Context#read, not #activate: a skill the user runs stays in the model's
|
|
22
|
+
# catalog, and only the model's own activations are recorded.
|
|
23
|
+
content = skills.adapter.render_activation(skill, skills.read(skill.name))
|
|
24
|
+
ctx.emit(Riffer::Rig::Events::SkillActivated.new(skill.name))
|
|
25
|
+
ctx.prompt([content, ctx.args.strip].reject(&:empty?).join("\n\n"))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -12,7 +12,7 @@ module Riffer::Rig::Credentials
|
|
|
12
12
|
ENTRY_TYPE = 'api_key'
|
|
13
13
|
|
|
14
14
|
# @rbs identifier: String | Symbol
|
|
15
|
-
# @rbs host: Riffer::Rig::Hosts::
|
|
15
|
+
# @rbs host: Riffer::Rig::Hosts::_Host
|
|
16
16
|
# @rbs setup: Riffer::Rig::ProviderSetup
|
|
17
17
|
# @rbs env: Riffer::Rig::Env
|
|
18
18
|
# @rbs auth_path: String
|
|
@@ -106,7 +106,7 @@ module Riffer::Rig::Credentials
|
|
|
106
106
|
|
|
107
107
|
# @rbs fields: Array[Riffer::Rig::ProviderSetup::Field]
|
|
108
108
|
# @rbs identifier: String | Symbol
|
|
109
|
-
# @rbs host: Riffer::Rig::Hosts::
|
|
109
|
+
# @rbs host: Riffer::Rig::Hosts::_Host
|
|
110
110
|
# @rbs return: Hash[Symbol, String]
|
|
111
111
|
def ask_for(fields, identifier, host)
|
|
112
112
|
fields.to_h do |field|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Riffer::Rig::Directories
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
# @rbs dir: String
|
|
7
|
+
# @rbs return: Array[String]
|
|
8
|
+
def ancestors(dir)
|
|
9
|
+
parent = File.dirname(dir)
|
|
10
|
+
parent == dir ? [dir] : [dir, *ancestors(parent)]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @rbs cwd: String
|
|
14
|
+
# @rbs return: Array[String]
|
|
15
|
+
def up_to_repo_root(cwd)
|
|
16
|
+
dirs = ancestors(File.expand_path(cwd))
|
|
17
|
+
root = dirs.index { |dir| File.exist?(File.join(dir, '.git')) } || 0
|
|
18
|
+
dirs.take(root + 1)
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/riffer/rig/env.rb
CHANGED
|
@@ -3,14 +3,25 @@
|
|
|
3
3
|
class Riffer::Rig::Env
|
|
4
4
|
# @rbs @source: Hash[String, String]
|
|
5
5
|
|
|
6
|
-
# @dynamic no_color
|
|
6
|
+
# @dynamic no_color, model
|
|
7
7
|
attr_reader :no_color #: bool
|
|
8
|
+
attr_reader :model #: String?
|
|
9
|
+
|
|
10
|
+
# @rbs source: Hash[String, String]
|
|
11
|
+
# @rbs return: Riffer::Rig::Env | Riffer::Rig::Env::Invalid
|
|
12
|
+
def self.load(source = ENV.to_h)
|
|
13
|
+
env = new(source)
|
|
14
|
+
model = env.model
|
|
15
|
+
rejection = model && Riffer::Rig::Settings.rejection(model)
|
|
16
|
+
rejection ? Invalid.new("RIFFER_MODEL: #{rejection}") : env
|
|
17
|
+
end
|
|
8
18
|
|
|
9
19
|
# @rbs source: Hash[String, String]
|
|
10
20
|
# @rbs return: void
|
|
11
21
|
def initialize(source = ENV.to_h)
|
|
12
22
|
@source = source.freeze
|
|
13
23
|
@no_color = @source.key?('NO_COLOR')
|
|
24
|
+
@model = self['RIFFER_MODEL']
|
|
14
25
|
freeze
|
|
15
26
|
end
|
|
16
27
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Riffer::Rig::Events::AfterResponse
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
6
|
+
# @dynamic message
|
|
7
|
+
attr_reader :message #: ::Riffer::Messages::Assistant
|
|
8
|
+
|
|
9
|
+
# @rbs message: ::Riffer::Messages::Assistant
|
|
10
|
+
# @rbs return: void
|
|
11
|
+
def initialize(message)
|
|
12
|
+
@message = message
|
|
13
|
+
freeze
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @rbs return: Symbol
|
|
17
|
+
def type
|
|
18
|
+
:after_response
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @rbs return: Hash[Symbol, untyped]
|
|
22
|
+
def to_h
|
|
23
|
+
{ type: type, message: message }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Riffer::Rig::Events::AfterToolCall
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
6
|
+
# @dynamic tool, args, result
|
|
7
|
+
attr_reader :tool #: String
|
|
8
|
+
attr_reader :args #: Hash[Symbol, untyped]
|
|
9
|
+
attr_reader :result #: ::Riffer::Tools::Response
|
|
10
|
+
|
|
11
|
+
# @rbs tool: String
|
|
12
|
+
# @rbs args: Hash[Symbol, untyped]
|
|
13
|
+
# @rbs result: ::Riffer::Tools::Response
|
|
14
|
+
# @rbs return: void
|
|
15
|
+
def initialize(tool, args, result)
|
|
16
|
+
@tool = tool
|
|
17
|
+
@args = args.dup.freeze
|
|
18
|
+
@result = result
|
|
19
|
+
freeze
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @rbs return: Symbol
|
|
23
|
+
def type
|
|
24
|
+
:after_tool_call
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @rbs return: Hash[Symbol, untyped]
|
|
28
|
+
def to_h
|
|
29
|
+
{ type: type, tool: tool, args: args, result: result }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Riffer::Rig::Events::BeforePrompt
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
6
|
+
# @dynamic text
|
|
7
|
+
attr_reader :text #: String
|
|
8
|
+
|
|
9
|
+
# @rbs text: String
|
|
10
|
+
# @rbs return: void
|
|
11
|
+
def initialize(text)
|
|
12
|
+
@text = text
|
|
13
|
+
freeze
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @rbs return: Symbol
|
|
17
|
+
def type
|
|
18
|
+
:before_prompt
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @rbs return: Hash[Symbol, untyped]
|
|
22
|
+
def to_h
|
|
23
|
+
{ type: type, text: text }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Riffer::Rig::Events::BeforeRequest
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
6
|
+
# @dynamic messages
|
|
7
|
+
attr_reader :messages #: Array[::Riffer::Messages::Base]
|
|
8
|
+
|
|
9
|
+
# @rbs messages: Array[::Riffer::Messages::Base]
|
|
10
|
+
# @rbs return: void
|
|
11
|
+
def initialize(messages)
|
|
12
|
+
@messages = messages.dup.freeze
|
|
13
|
+
freeze
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @rbs return: Symbol
|
|
17
|
+
def type
|
|
18
|
+
:before_request
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @rbs return: Hash[Symbol, untyped]
|
|
22
|
+
def to_h
|
|
23
|
+
{ type: type, messages: messages }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Riffer::Rig::Events::BeforeToolCall
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
6
|
+
# @dynamic tool, args
|
|
7
|
+
attr_reader :tool #: String
|
|
8
|
+
attr_reader :args #: Hash[Symbol, untyped]
|
|
9
|
+
|
|
10
|
+
# @rbs tool: String
|
|
11
|
+
# @rbs args: Hash[Symbol, untyped]
|
|
12
|
+
# @rbs return: void
|
|
13
|
+
def initialize(tool, args)
|
|
14
|
+
@tool = tool
|
|
15
|
+
@args = args.dup.freeze
|
|
16
|
+
freeze
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @rbs return: Symbol
|
|
20
|
+
def type
|
|
21
|
+
:before_tool_call
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @rbs return: Hash[Symbol, untyped]
|
|
25
|
+
def to_h
|
|
26
|
+
{ type: type, tool: tool, args: args }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class Riffer::Rig::Events::CommandOutput
|
|
3
|
+
class Riffer::Rig::Events::CommandOutput
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
4
6
|
# @dynamic command, text
|
|
5
7
|
attr_reader :command #: String
|
|
6
8
|
attr_reader :text #: String
|
|
@@ -9,7 +11,6 @@ class Riffer::Rig::Events::CommandOutput < Riffer::Rig::Events::Event
|
|
|
9
11
|
# @rbs text: String
|
|
10
12
|
# @rbs return: void
|
|
11
13
|
def initialize(command, text)
|
|
12
|
-
super()
|
|
13
14
|
@command = command
|
|
14
15
|
@text = text
|
|
15
16
|
freeze
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class Riffer::Rig::Events::Notify
|
|
3
|
+
class Riffer::Rig::Events::Notify
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
4
6
|
# @dynamic message, level
|
|
5
7
|
attr_reader :message #: String?
|
|
6
8
|
attr_reader :level #: Symbol
|
|
@@ -9,7 +11,6 @@ class Riffer::Rig::Events::Notify < Riffer::Rig::Events::Event
|
|
|
9
11
|
# @rbs level: Symbol
|
|
10
12
|
# @rbs return: void
|
|
11
13
|
def initialize(message, level)
|
|
12
|
-
super()
|
|
13
14
|
@message = message
|
|
14
15
|
@level = level
|
|
15
16
|
freeze
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class Riffer::Rig::Events::SessionEnd
|
|
3
|
+
class Riffer::Rig::Events::SessionEnd
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
4
6
|
# @dynamic reason
|
|
5
7
|
attr_reader :reason #: Symbol
|
|
6
8
|
|
|
7
9
|
# @rbs reason: Symbol
|
|
8
10
|
# @rbs return: void
|
|
9
11
|
def initialize(reason)
|
|
10
|
-
super()
|
|
11
12
|
@reason = reason
|
|
12
13
|
freeze
|
|
13
14
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class Riffer::Rig::Events::SessionStart
|
|
3
|
+
class Riffer::Rig::Events::SessionStart
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
4
6
|
# @dynamic id, reason
|
|
5
7
|
attr_reader :id #: String
|
|
6
8
|
attr_reader :reason #: Symbol
|
|
@@ -9,7 +11,6 @@ class Riffer::Rig::Events::SessionStart < Riffer::Rig::Events::Event
|
|
|
9
11
|
# @rbs reason: Symbol
|
|
10
12
|
# @rbs return: void
|
|
11
13
|
def initialize(id, reason)
|
|
12
|
-
super()
|
|
13
14
|
@id = id
|
|
14
15
|
@reason = reason
|
|
15
16
|
freeze
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class Riffer::Rig::Events::SkillActivated
|
|
3
|
+
class Riffer::Rig::Events::SkillActivated
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
4
6
|
# @dynamic name
|
|
5
7
|
attr_reader :name #: String
|
|
6
8
|
|
|
7
9
|
# @rbs name: String
|
|
8
10
|
# @rbs return: void
|
|
9
11
|
def initialize(name)
|
|
10
|
-
super()
|
|
11
12
|
@name = name
|
|
12
13
|
freeze
|
|
13
14
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class Riffer::Rig::Events::TurnEnd
|
|
3
|
+
class Riffer::Rig::Events::TurnEnd
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
4
6
|
# @dynamic stop_reason, usage
|
|
5
7
|
attr_reader :stop_reason #: Symbol
|
|
6
8
|
attr_reader :usage #: ::Riffer::Providers::TokenUsage?
|
|
@@ -9,7 +11,6 @@ class Riffer::Rig::Events::TurnEnd < Riffer::Rig::Events::Event
|
|
|
9
11
|
# @rbs usage: ::Riffer::Providers::TokenUsage?
|
|
10
12
|
# @rbs return: void
|
|
11
13
|
def initialize(stop_reason, usage)
|
|
12
|
-
super()
|
|
13
14
|
@stop_reason = stop_reason
|
|
14
15
|
@usage = usage
|
|
15
16
|
freeze
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Riffer::Rig::Extension::Failure
|
|
4
|
+
# @dynamic extension, error
|
|
5
|
+
attr_reader :extension #: Riffer::Rig::Extension
|
|
6
|
+
attr_reader :error #: StandardError
|
|
7
|
+
|
|
8
|
+
# @rbs extension: Riffer::Rig::Extension
|
|
9
|
+
# @rbs error: StandardError
|
|
10
|
+
# @rbs return: void
|
|
11
|
+
def initialize(extension:, error:)
|
|
12
|
+
@extension = extension
|
|
13
|
+
@error = error
|
|
14
|
+
freeze
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/riffer/rig/extension.rb
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Riffer::Rig::Extension
|
|
4
|
+
class RequirementError < StandardError; end
|
|
5
|
+
|
|
4
6
|
# @rbs @name: String
|
|
5
7
|
# @rbs @requires: Gem::Requirement?
|
|
8
|
+
# @rbs @mismatch: RequirementError?
|
|
6
9
|
# @rbs @block: ^(::Riffer::Rig::Registrar) -> void
|
|
7
10
|
|
|
8
|
-
# @dynamic name, requires
|
|
11
|
+
# @dynamic name, requires, mismatch
|
|
9
12
|
attr_reader :name #: String
|
|
10
13
|
attr_reader :requires #: Gem::Requirement?
|
|
14
|
+
attr_reader :mismatch #: RequirementError?
|
|
11
15
|
|
|
12
16
|
# @rbs name: String
|
|
13
17
|
# @rbs requires: String?
|
|
@@ -16,6 +20,7 @@ class Riffer::Rig::Extension
|
|
|
16
20
|
def initialize(name, requires: nil, &block)
|
|
17
21
|
@name = name
|
|
18
22
|
@requires = requires && Gem::Requirement.new(requires)
|
|
23
|
+
@mismatch = check(@requires)
|
|
19
24
|
@block = block
|
|
20
25
|
end
|
|
21
26
|
|
|
@@ -24,4 +29,14 @@ class Riffer::Rig::Extension
|
|
|
24
29
|
def run(registrar)
|
|
25
30
|
@block.call(registrar)
|
|
26
31
|
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
# @rbs requirement: Gem::Requirement?
|
|
36
|
+
# @rbs return: RequirementError?
|
|
37
|
+
def check(requirement)
|
|
38
|
+
return if requirement.nil? || requirement.satisfied_by?(Gem::Version.new(Riffer::Rig::VERSION))
|
|
39
|
+
|
|
40
|
+
RequirementError.new("extension #{@name} requires riffer-rig #{requirement}, found #{Riffer::Rig::VERSION}")
|
|
41
|
+
end
|
|
27
42
|
end
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class Riffer::Rig::Hosts::Mirror
|
|
4
|
-
# @rbs @host: Riffer::Rig::Hosts::
|
|
5
|
-
# @rbs @queue: Array[Riffer::Rig::Events::
|
|
3
|
+
class Riffer::Rig::Hosts::Mirror
|
|
4
|
+
# @rbs @host: Riffer::Rig::Hosts::_Host
|
|
5
|
+
# @rbs @queue: Array[Riffer::Rig::Events::_Event]
|
|
6
6
|
|
|
7
7
|
# @dynamic capabilities
|
|
8
8
|
attr_reader :capabilities #: Set[Symbol]
|
|
9
9
|
|
|
10
|
-
# @rbs host: Riffer::Rig::Hosts::
|
|
10
|
+
# @rbs host: Riffer::Rig::Hosts::_Host
|
|
11
11
|
# @rbs return: void
|
|
12
12
|
def initialize(host)
|
|
13
|
-
super()
|
|
14
13
|
@host = host
|
|
15
14
|
@capabilities = host.capabilities
|
|
16
15
|
@queue = []
|
|
@@ -45,13 +44,13 @@ class Riffer::Rig::Hosts::Mirror < Riffer::Rig::Hosts::Base
|
|
|
45
44
|
@host.progress(label) { block&.call }
|
|
46
45
|
end
|
|
47
46
|
|
|
48
|
-
# @rbs event: Riffer::Rig::Events::
|
|
47
|
+
# @rbs event: Riffer::Rig::Events::_Event
|
|
49
48
|
# @rbs return: void
|
|
50
49
|
def queue(event)
|
|
51
50
|
@queue << event
|
|
52
51
|
end
|
|
53
52
|
|
|
54
|
-
# @rbs return: Array[Riffer::Rig::Events::
|
|
53
|
+
# @rbs return: Array[Riffer::Rig::Events::_Event]
|
|
55
54
|
def drain
|
|
56
55
|
queued = @queue
|
|
57
56
|
@queue = []
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Riffer::Rig::Loader
|
|
4
|
+
class ConfigurationError < StandardError; end
|
|
5
|
+
|
|
6
|
+
PROVIDER_LIST = Riffer::Rig::Settings::PROVIDERS.join(', ') #: String
|
|
7
|
+
|
|
8
|
+
ONBOARDING_QUESTION = 'Which model should riffer use? Enter provider/name, ' \
|
|
9
|
+
"with a provider from: #{PROVIDER_LIST}".freeze #: String
|
|
10
|
+
|
|
11
|
+
NO_MODEL = 'No model is set: pass --model provider/name, set RIFFER_MODEL, or set "model" in ' \
|
|
12
|
+
"~/.riffer/settings.json, with a provider from: #{PROVIDER_LIST}".freeze #: String
|
|
13
|
+
|
|
14
|
+
private_constant :PROVIDER_LIST, :ONBOARDING_QUESTION, :NO_MODEL
|
|
15
|
+
|
|
16
|
+
# @rbs @cwd: String
|
|
17
|
+
# @rbs @host: Riffer::Rig::Hosts::_Host
|
|
18
|
+
# @rbs @env: Riffer::Rig::Env
|
|
19
|
+
# @rbs @home: String
|
|
20
|
+
# @rbs @riffer_config: Riffer::Config
|
|
21
|
+
|
|
22
|
+
# @rbs cwd: String
|
|
23
|
+
# @rbs host: Riffer::Rig::Hosts::_Host
|
|
24
|
+
# @rbs env: Riffer::Rig::Env | Riffer::Rig::Env::Invalid
|
|
25
|
+
# @rbs home: String
|
|
26
|
+
# @rbs riffer_config: Riffer::Config
|
|
27
|
+
# @rbs model: String?
|
|
28
|
+
# @rbs extensions: bool
|
|
29
|
+
# @rbs skills: bool
|
|
30
|
+
# @rbs agents_md: bool
|
|
31
|
+
# @rbs tools: Array[String]?
|
|
32
|
+
# @rbs max_steps: Integer?
|
|
33
|
+
# @rbs return: Riffer::Rig::Runtime
|
|
34
|
+
def self.runtime(
|
|
35
|
+
cwd:,
|
|
36
|
+
host:,
|
|
37
|
+
env: Riffer::Rig::Env.load,
|
|
38
|
+
home: Dir.home,
|
|
39
|
+
riffer_config: Riffer.config,
|
|
40
|
+
model: nil,
|
|
41
|
+
extensions: true,
|
|
42
|
+
skills: true,
|
|
43
|
+
agents_md: true,
|
|
44
|
+
tools: nil,
|
|
45
|
+
max_steps: Riffer::Rig::Runtime::DEFAULT_MAX_STEPS
|
|
46
|
+
)
|
|
47
|
+
new(cwd:, host:, env:, home:, riffer_config:).runtime(model:, extensions:, skills:, agents_md:, tools:, max_steps:)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @rbs cwd: String
|
|
51
|
+
# @rbs host: Riffer::Rig::Hosts::_Host
|
|
52
|
+
# @rbs env: Riffer::Rig::Env | Riffer::Rig::Env::Invalid
|
|
53
|
+
# @rbs home: String
|
|
54
|
+
# @rbs riffer_config: Riffer::Config
|
|
55
|
+
# @rbs return: void
|
|
56
|
+
def initialize(cwd:, host:, env: Riffer::Rig::Env.load, home: Dir.home, riffer_config: Riffer.config)
|
|
57
|
+
raise ConfigurationError, env.message if env.is_a?(Riffer::Rig::Env::Invalid)
|
|
58
|
+
|
|
59
|
+
@cwd = cwd
|
|
60
|
+
@host = host
|
|
61
|
+
@env = env
|
|
62
|
+
@home = home
|
|
63
|
+
@riffer_config = riffer_config
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @rbs model: String?
|
|
67
|
+
# @rbs extensions: bool
|
|
68
|
+
# @rbs skills: bool
|
|
69
|
+
# @rbs agents_md: bool
|
|
70
|
+
# @rbs tools: Array[String]?
|
|
71
|
+
# @rbs max_steps: Integer?
|
|
72
|
+
# @rbs return: Riffer::Rig::Runtime
|
|
73
|
+
def runtime(
|
|
74
|
+
model: nil,
|
|
75
|
+
extensions: true,
|
|
76
|
+
skills: true,
|
|
77
|
+
agents_md: true,
|
|
78
|
+
tools: nil,
|
|
79
|
+
max_steps: Riffer::Rig::Runtime::DEFAULT_MAX_STEPS
|
|
80
|
+
)
|
|
81
|
+
settings = Riffer::Rig::Settings.merge(
|
|
82
|
+
Riffer::Rig::Settings.read(home_settings_path),
|
|
83
|
+
Riffer::Rig::Settings.read(File.join(@cwd, '.riffer', 'settings.json'))
|
|
84
|
+
)
|
|
85
|
+
document = Riffer::Rig::Settings::Document.new(settings)
|
|
86
|
+
selected = select_model(model || @env.model || document.model)
|
|
87
|
+
provider = Riffer::Rig::Settings.provider_for(selected).to_s
|
|
88
|
+
credentials = { provider.to_sym => credentials_for(provider) }
|
|
89
|
+
stripped = { skills: skills, agents_md: agents_md }.reject { |_name, kept| kept }.keys
|
|
90
|
+
|
|
91
|
+
Riffer::Rig::Runtime.new(
|
|
92
|
+
selected,
|
|
93
|
+
extensions: Riffer::Rig::Bundled::BY_NAME.except(*document.disabled.map(&:to_sym), *stripped).values,
|
|
94
|
+
tools: tools,
|
|
95
|
+
settings: settings,
|
|
96
|
+
host: @host,
|
|
97
|
+
cwd: @cwd,
|
|
98
|
+
max_steps: max_steps,
|
|
99
|
+
credentials: credentials,
|
|
100
|
+
pricing: document.models,
|
|
101
|
+
riffer_config: @riffer_config,
|
|
102
|
+
model_options: Riffer::Rig::Settings.model_options(selected, document.reasoning)
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
# @rbs configured: String?
|
|
109
|
+
# @rbs return: String
|
|
110
|
+
def select_model(configured)
|
|
111
|
+
model = configured || ask_for_model
|
|
112
|
+
rejection = Riffer::Rig::Settings.rejection(model)
|
|
113
|
+
raise ConfigurationError, rejection if rejection
|
|
114
|
+
|
|
115
|
+
Riffer::Rig::Settings.store_model(model, path: home_settings_path) unless configured
|
|
116
|
+
model
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# @rbs return: String
|
|
120
|
+
def ask_for_model
|
|
121
|
+
answer = asking_host.ask(ONBOARDING_QUESTION).to_s.strip
|
|
122
|
+
raise ConfigurationError, NO_MODEL if answer.empty?
|
|
123
|
+
|
|
124
|
+
answer
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# @rbs provider: String
|
|
128
|
+
# @rbs return: Hash[Symbol, String]
|
|
129
|
+
def credentials_for(provider)
|
|
130
|
+
resolution = Riffer::Rig::Credentials.resolve(
|
|
131
|
+
provider,
|
|
132
|
+
host: asking_host,
|
|
133
|
+
env: @env,
|
|
134
|
+
auth_path: File.join(@home, '.riffer', 'auth.json'),
|
|
135
|
+
settings_path: home_settings_path
|
|
136
|
+
)
|
|
137
|
+
raise ConfigurationError, missing_credentials(provider, resolution.missing) unless resolution.missing.empty?
|
|
138
|
+
|
|
139
|
+
Riffer::Rig::Credentials.apply(provider, resolution.values, config: @riffer_config)
|
|
140
|
+
resolution.values
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @rbs provider: String
|
|
144
|
+
# @rbs missing: Array[Symbol]
|
|
145
|
+
# @rbs return: String
|
|
146
|
+
def missing_credentials(provider, missing)
|
|
147
|
+
setup = Riffer::Rig::ProviderSetup.for(provider)
|
|
148
|
+
fields = setup.fields.select { |field| missing.include?(field.name) }
|
|
149
|
+
wanted = fields.map { |field| "#{field.name} (#{field.env.join(' or ')})" }.join(', ')
|
|
150
|
+
"#{provider} has no #{wanted}; set it in the environment or run riffer interactively to paste it" \
|
|
151
|
+
"#{" (create one at #{setup.url})" if setup.url}"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# @rbs return: Riffer::Rig::Hosts::_Host
|
|
155
|
+
def asking_host
|
|
156
|
+
@host.capabilities.include?(:ask) ? @host : Riffer::Rig::Hosts::Null.new
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# @rbs return: String
|
|
160
|
+
def home_settings_path
|
|
161
|
+
File.join(@home, '.riffer', 'settings.json')
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Riffer::Rig::Mcp::Declaration
|
|
4
|
+
include Riffer::Rig::Support::Equatable
|
|
5
|
+
|
|
6
|
+
# @dynamic url, headers
|
|
7
|
+
attr_reader :url #: String
|
|
8
|
+
attr_reader :headers #: Hash[String, String]
|
|
9
|
+
|
|
10
|
+
# @rbs url: String
|
|
11
|
+
# @rbs headers: Hash[String, String]
|
|
12
|
+
# @rbs return: void
|
|
13
|
+
def initialize(url:, headers:)
|
|
14
|
+
@url = url
|
|
15
|
+
@headers = headers
|
|
16
|
+
freeze
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @rbs return: Hash[Symbol, untyped]
|
|
20
|
+
def to_h
|
|
21
|
+
{ url: url, headers: headers }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Riffer::Rig::Mcp::Server
|
|
4
|
+
# @dynamic declaration, registration
|
|
5
|
+
attr_reader :declaration #: Riffer::Rig::Mcp::Declaration
|
|
6
|
+
attr_reader :registration #: Riffer::Mcp::Registration
|
|
7
|
+
|
|
8
|
+
# @rbs declaration: Riffer::Rig::Mcp::Declaration
|
|
9
|
+
# @rbs registration: Riffer::Mcp::Registration
|
|
10
|
+
# @rbs return: void
|
|
11
|
+
def initialize(declaration:, registration:)
|
|
12
|
+
@declaration = declaration
|
|
13
|
+
@registration = registration
|
|
14
|
+
freeze
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Riffer::Rig::Mcp
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
# @rbs home: Hash[Symbol, untyped]
|
|
7
|
+
# @rbs project: Hash[Symbol, untyped]
|
|
8
|
+
# @rbs return: Hash[Symbol, untyped]
|
|
9
|
+
def merge(home, project)
|
|
10
|
+
home.merge(project, servers: home[:servers].to_h.merge(project[:servers].to_h))
|
|
11
|
+
end
|
|
12
|
+
end
|