silas 0.2.0 → 0.3.1
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 +83 -1
- data/README.md +44 -0
- data/app/controllers/concerns/silas/api/serialization.rb +63 -0
- data/app/controllers/silas/api/base_controller.rb +24 -0
- data/app/controllers/silas/api/v1/approvals_controller.rb +35 -0
- data/app/controllers/silas/api/v1/sessions_controller.rb +39 -0
- data/app/controllers/silas/api/v1/streams_controller.rb +117 -0
- data/app/controllers/silas/api/v1/turns_controller.rb +32 -0
- data/app/controllers/silas/inbox/sessions_controller.rb +16 -3
- data/app/controllers/silas/inbox/turns_controller.rb +19 -0
- data/app/helpers/silas/inbox/trace_helper.rb +5 -0
- data/app/models/silas/session.rb +6 -0
- data/app/models/silas/turn.rb +9 -0
- data/app/views/layouts/silas/inbox.html.erb +6 -0
- data/app/views/silas/inbox/invocations/_invocation.html.erb +2 -2
- data/app/views/silas/inbox/sessions/index.html.erb +11 -3
- data/app/views/silas/inbox/steps/_step.html.erb +3 -0
- data/app/views/silas/inbox/turns/_header.html.erb +12 -1
- data/config/routes.rb +23 -1
- data/db/migrate/20260725000001_add_provider_to_silas_steps.rb +13 -0
- data/lib/generators/silas/install/install_generator.rb +1 -0
- data/lib/generators/silas/install/templates/agent.yml +10 -1
- data/lib/generators/silas/install/templates/initializer.rb +5 -4
- data/lib/generators/silas/install/templates/ruby_llm.rb +6 -0
- data/lib/silas/agent.rb +4 -0
- data/lib/silas/chat.rb +2 -0
- data/lib/silas/configuration.rb +30 -34
- data/lib/silas/doctor.rb +155 -0
- data/lib/silas/engines/ruby_llm.rb +13 -2
- data/lib/silas/eval/assertions.rb +18 -0
- data/lib/silas/eval/transcript.rb +1 -0
- data/lib/silas/inbox/cost.rb +37 -13
- data/lib/silas/ledger.rb +8 -1
- data/lib/silas/message_builder.rb +9 -2
- data/lib/silas/named_agent.rb +1 -0
- data/lib/silas/registry.rb +18 -8
- data/lib/silas/step_runner.rb +12 -0
- data/lib/silas/version.rb +1 -1
- data/lib/silas.rb +9 -0
- data/lib/tasks/silas_doctor.rake +17 -0
- metadata +11 -2
data/lib/silas/registry.rb
CHANGED
|
@@ -100,13 +100,20 @@ module Silas
|
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
# Stable across boots for the same agent definition; changes when any tool
|
|
103
|
-
# schema (incl. the delegate roster + remote connection tools),
|
|
104
|
-
# description, changes.
|
|
103
|
+
# schema (incl. the delegate roster + remote connection tools), skill
|
|
104
|
+
# description, or final_answer schema changes.
|
|
105
|
+
#
|
|
106
|
+
# final_answer is appended ONLY when present: schema-less agents keep a
|
|
107
|
+
# byte-identical digest across upgrades, so turns parked over a deploy
|
|
108
|
+
# never fail NondeterminismError for a key they don't use.
|
|
105
109
|
def digest
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
payload = { tools: definitions, skills: skills.map { |s| [ s.name, s.description ] } }
|
|
111
|
+
payload[:final_answer] = root_agent.final_answer if root_agent.final_answer.present?
|
|
112
|
+
Digest::SHA256.hexdigest(JSON.generate(payload))
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def root_agent
|
|
116
|
+
@root_agent ||= Silas::Agent.load(root: @root)
|
|
110
117
|
end
|
|
111
118
|
|
|
112
119
|
# --- named agents (app/agents/<name>/ — the staff pattern) ---------------
|
|
@@ -192,9 +199,12 @@ module Silas
|
|
|
192
199
|
builtins["handoff"] = Silas::Tools::Handoff if named && named_agent_dirs.size > 1
|
|
193
200
|
resolver = ->(n) { (tools[n] || builtins.fetch(n)).new }
|
|
194
201
|
definitions = (tools.values + builtins.values).map(&:schema)
|
|
195
|
-
|
|
202
|
+
loaded_agent = agent || Silas::Agent.load(dir: dir)
|
|
203
|
+
payload = { tools: definitions, skills: skills.map { |s| [ s.name, s.description ] } }
|
|
204
|
+
payload[:final_answer] = loaded_agent.final_answer if loaded_agent.final_answer.present?
|
|
205
|
+
digest = Digest::SHA256.hexdigest(JSON.generate(payload))
|
|
196
206
|
|
|
197
|
-
Silas::AgentScope.new(name: name, dir: dir, agent:
|
|
207
|
+
Silas::AgentScope.new(name: name, dir: dir, agent: loaded_agent,
|
|
198
208
|
resolver: resolver, definitions: definitions, digest: digest, skills: skills)
|
|
199
209
|
end
|
|
200
210
|
end
|
data/lib/silas/step_runner.rb
CHANGED
|
@@ -22,6 +22,7 @@ module Silas
|
|
|
22
22
|
stop_reason: result.stop_reason,
|
|
23
23
|
terminal: result.terminal?,
|
|
24
24
|
model: turn_model(turn),
|
|
25
|
+
provider: provider_for(turn_model(turn)),
|
|
25
26
|
input_tokens: result.usage&.dig(:input_tokens),
|
|
26
27
|
output_tokens: result.usage&.dig(:output_tokens)
|
|
27
28
|
)
|
|
@@ -58,6 +59,7 @@ module Silas
|
|
|
58
59
|
messages: MessageBuilder.call(turn, upto_index: index),
|
|
59
60
|
tools: Silas.tool_definitions,
|
|
60
61
|
model: turn_model(turn),
|
|
62
|
+
final_answer: Silas.agent.final_answer,
|
|
61
63
|
limits: { max_steps: Silas.agent.max_steps }
|
|
62
64
|
}
|
|
63
65
|
|
|
@@ -109,5 +111,15 @@ module Silas
|
|
|
109
111
|
def turn_model(_turn)
|
|
110
112
|
Silas.agent.model
|
|
111
113
|
end
|
|
114
|
+
|
|
115
|
+
# The provider RubyLLM's own resolution picks for this model id, stamped
|
|
116
|
+
# on the row so cost lookups price against (model, provider) forever
|
|
117
|
+
# after — the registry's tie-break can change; the row shouldn't. nil for
|
|
118
|
+
# ids the installed registry doesn't know (fakes, custom engines).
|
|
119
|
+
def provider_for(model)
|
|
120
|
+
::RubyLLM.models.find(model).provider
|
|
121
|
+
rescue StandardError
|
|
122
|
+
nil
|
|
123
|
+
end
|
|
112
124
|
end
|
|
113
125
|
end
|
data/lib/silas/version.rb
CHANGED
data/lib/silas.rb
CHANGED
|
@@ -43,6 +43,7 @@ require "silas/instructions"
|
|
|
43
43
|
require "silas/step_runner"
|
|
44
44
|
require "silas/eval" # after engines (ScriptedEngine < Engines::Base)
|
|
45
45
|
require "silas/chat"
|
|
46
|
+
require "silas/doctor"
|
|
46
47
|
|
|
47
48
|
module Silas
|
|
48
49
|
class << self
|
|
@@ -50,9 +51,17 @@ module Silas
|
|
|
50
51
|
@config ||= Configuration.new
|
|
51
52
|
end
|
|
52
53
|
|
|
54
|
+
# Reconfiguring re-resolves the engine and sandbox. Without this the
|
|
55
|
+
# memos below outlive the config that produced them: a second
|
|
56
|
+
# `Silas.configure { |c| c.engine = ... }` in one process kept serving the
|
|
57
|
+
# FIRST engine. That silently broke multi-scenario `silas:eval` runs —
|
|
58
|
+
# every scenario after the first ran the first one's script and still
|
|
59
|
+
# reported pass/fail as if it hadn't. Re-resolution is cheap (one `.new`).
|
|
53
60
|
def configure
|
|
54
61
|
yield config
|
|
55
62
|
config.validate!
|
|
63
|
+
@resolved_engine = nil
|
|
64
|
+
@resolved_sandbox = nil
|
|
56
65
|
config
|
|
57
66
|
end
|
|
58
67
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
namespace :silas do
|
|
2
|
+
desc "Diagnose common Silas misconfigurations (provider key, queue adapter, model, migrations, tools, rescuer, cable, auth)"
|
|
3
|
+
task doctor: :environment do
|
|
4
|
+
glyph = { pass: "\e[32m✓\e[0m", warn: "\e[33m!\e[0m", fail: "\e[31m✗\e[0m" }
|
|
5
|
+
checks = Silas::Doctor.run
|
|
6
|
+
|
|
7
|
+
puts "silas:doctor — #{Silas::VERSION}"
|
|
8
|
+
checks.each do |check|
|
|
9
|
+
puts " #{glyph[check.status]} #{check.label}#{" — #{check.detail}" if check.detail.present?}"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
failed = checks.count { |c| c.status == :fail }
|
|
13
|
+
warned = checks.count { |c| c.status == :warn }
|
|
14
|
+
puts "\n#{failed} failure(s), #{warned} warning(s)"
|
|
15
|
+
exit 1 if failed.positive?
|
|
16
|
+
end
|
|
17
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: silas
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel St Paul
|
|
@@ -103,7 +103,7 @@ description: 'An agent framework where your Rails app is the chassis: app/agent/
|
|
|
103
103
|
convention, durable runs on Active Job Continuations, exactly-once tool execution
|
|
104
104
|
via a transactional ledger, approvals that park at zero compute.'
|
|
105
105
|
email:
|
|
106
|
-
-
|
|
106
|
+
- danielstpaul@hotmail.com
|
|
107
107
|
executables: []
|
|
108
108
|
extensions: []
|
|
109
109
|
extra_rdoc_files: []
|
|
@@ -111,6 +111,12 @@ files:
|
|
|
111
111
|
- CHANGELOG.md
|
|
112
112
|
- LICENSE
|
|
113
113
|
- README.md
|
|
114
|
+
- app/controllers/concerns/silas/api/serialization.rb
|
|
115
|
+
- app/controllers/silas/api/base_controller.rb
|
|
116
|
+
- app/controllers/silas/api/v1/approvals_controller.rb
|
|
117
|
+
- app/controllers/silas/api/v1/sessions_controller.rb
|
|
118
|
+
- app/controllers/silas/api/v1/streams_controller.rb
|
|
119
|
+
- app/controllers/silas/api/v1/turns_controller.rb
|
|
114
120
|
- app/controllers/silas/channels/approvals_controller.rb
|
|
115
121
|
- app/controllers/silas/channels/base_controller.rb
|
|
116
122
|
- app/controllers/silas/channels/slack_controller.rb
|
|
@@ -154,6 +160,7 @@ files:
|
|
|
154
160
|
- db/migrate/20260716000002_add_cancel_requested_to_silas_turns.rb
|
|
155
161
|
- db/migrate/20260721000001_create_silas_memories.rb
|
|
156
162
|
- db/migrate/20260724000001_drop_agent_sdk_columns_from_silas_turns.rb
|
|
163
|
+
- db/migrate/20260725000001_add_provider_to_silas_steps.rb
|
|
157
164
|
- lib/generators/silas/install/install_generator.rb
|
|
158
165
|
- lib/generators/silas/install/templates/agent.yml
|
|
159
166
|
- lib/generators/silas/install/templates/bin_ci
|
|
@@ -176,6 +183,7 @@ files:
|
|
|
176
183
|
- lib/silas/connection.rb
|
|
177
184
|
- lib/silas/connections.rb
|
|
178
185
|
- lib/silas/delta_buffer.rb
|
|
186
|
+
- lib/silas/doctor.rb
|
|
179
187
|
- lib/silas/engine.rb
|
|
180
188
|
- lib/silas/engines/base.rb
|
|
181
189
|
- lib/silas/engines/ruby_llm.rb
|
|
@@ -218,6 +226,7 @@ files:
|
|
|
218
226
|
- lib/silas/tools/run_code.rb
|
|
219
227
|
- lib/silas/version.rb
|
|
220
228
|
- lib/tasks/silas_chat.rake
|
|
229
|
+
- lib/tasks/silas_doctor.rake
|
|
221
230
|
- lib/tasks/silas_eval.rake
|
|
222
231
|
- lib/tasks/silas_schedules.rake
|
|
223
232
|
homepage: https://github.com/danielstpaul/silas
|