Module: Silas

Defined in:
lib/silas.rb,
lib/silas/eval.rb,
lib/silas/tool.rb,
lib/silas/agent.rb,
lib/silas/inbox.rb,
lib/silas/skill.rb,
lib/silas/slack.rb,
lib/silas/budget.rb,
lib/silas/engine.rb,
lib/silas/errors.rb,
lib/silas/ledger.rb,
lib/silas/channel.rb,
lib/silas/sandbox.rb,
lib/silas/version.rb,
lib/silas/eval/dsl.rb,
lib/silas/registry.rb,
lib/silas/schedule.rb,
lib/silas/connection.rb,
lib/silas/inbox/cost.rb,
lib/silas/mcp/client.rb,
lib/silas/mcp/server.rb,
app/models/silas/step.rb,
app/models/silas/turn.rb,
lib/silas/agent_scope.rb,
lib/silas/connections.rb,
lib/silas/eval/driver.rb,
lib/silas/eval/grader.rb,
lib/silas/eval/result.rb,
lib/silas/eval/runner.rb,
lib/silas/mcp/handler.rb,
lib/silas/step_runner.rb,
lib/silas/engines/base.rb,
lib/silas/instructions.rb,
lib/silas/sandbox/null.rb,
lib/silas/agent_sdk/cli.rb,
lib/silas/configuration.rb,
lib/silas/nested_runner.rb,
app/models/silas/session.rb,
lib/silas/sandbox/docker.rb,
lib/silas/tools/delegate.rb,
lib/silas/tools/run_code.rb,
lib/silas/eval/assertions.rb,
lib/silas/eval/transcript.rb,
lib/silas/message_builder.rb,
lib/silas/engines/ruby_llm.rb,
lib/silas/tools/load_skill.rb,
app/jobs/silas/schedule_job.rb,
lib/silas/engines/agent_sdk.rb,
lib/silas/schedule/compiler.rb,
lib/silas/subprocess_runner.rb,
app/jobs/silas/agent_loop_job.rb,
lib/silas/eval/scripted_engine.rb,
app/mailers/silas/channel_mailer.rb,
app/models/silas/tool_invocation.rb,
app/mailboxes/silas/agent_mailbox.rb,
lib/silas/agent_sdk/stream_parser.rb,
lib/silas/agent_sdk/version_guard.rb,
app/jobs/silas/channel_delivery_job.rb,
app/jobs/silas/dead_job_rescuer_job.rb,
app/models/silas/application_record.rb,
app/helpers/silas/inbox/trace_helper.rb,
app/controllers/silas/inbox/base_controller.rb,
app/models/concerns/silas/inbox/broadcastable.rb,
app/controllers/silas/channels/base_controller.rb,
lib/generators/silas/install/install_generator.rb,
app/controllers/silas/channels/slack_controller.rb,
app/controllers/silas/inbox/sessions_controller.rb,
app/controllers/silas/inbox/invocations_controller.rb,
app/controllers/silas/channels/approvals_controller.rb

Defined Under Namespace

Modules: AgentSdk, Budget, Channels, Engines, Eval, Generators, Inbox, Instructions, Ledger, Mcp, MessageBuilder, NestedRunner, Sandbox, Slack, StepRunner, SubprocessRunner, Tools Classes: Agent, AgentLoopJob, AgentMailbox, AgentScope, ApplicationRecord, BootGuardError, Channel, ChannelDeliveryJob, ChannelMailer, CheckpointInLedgerError, Configuration, Connection, Connections, DeadJobRescuerJob, Engine, Error, Event, NondeterminismError, Registry, SandboxDisabledError, SandboxError, Schedule, ScheduleJob, Session, Skill, Step, Tool, ToolInvocation, Turn, TurnInProgressError

Constant Summary collapse

VERSION =
"0.1.1"

Class Method Summary collapse

Class Method Details

.agentObject

The active agent definition. config.agent_override is set during a nested subagent run; otherwise it's the root app/agent.



112
113
114
# File 'lib/silas.rb', line 112

def agent
  config.agent_override || (@agent ||= Agent.load)
end

.configObject



47
48
49
# File 'lib/silas.rb', line 47

def config
  @config ||= Configuration.new
end

.configure {|config| ... } ⇒ Object

Yields:



51
52
53
54
55
# File 'lib/silas.rb', line 51

def configure
  yield config
  config.validate!
  config
end

.reset_agent_memo!Object

after Registry.install! swaps dirs



80
# File 'lib/silas.rb', line 80

def reset_agent_memo! = (@agent = nil) # after Registry.install! swaps dirs

.reset_configuration!Object

for specs



57
58
59
60
61
62
# File 'lib/silas.rb', line 57

def reset_configuration! # for specs
  @config = nil
  @resolved_engine = nil
  @resolved_sandbox = nil
  @agent = nil
end

.resolved_engineObject

The inference adapter instance. config.engine may be a symbol (:ruby_llm, :agent_sdk) or any object responding to #execute_step (specs, custom).



84
85
86
87
88
89
90
91
92
# File 'lib/silas.rb', line 84

def resolved_engine
  @resolved_engine ||=
    case config.engine
    when :ruby_llm then Engines::RubyLLM.new
    when :agent_sdk then Engines::AgentSdk.new
    when Symbol then raise Error, "unknown engine #{config.engine.inspect}"
    else config.engine
    end
end

.resolved_sandboxObject



66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/silas.rb', line 66

def resolved_sandbox
  @resolved_sandbox ||=
    case config.sandbox
    when :none, nil then Sandbox::Null.new
    when :docker
      Sandbox::Docker.new(image: config.sandbox_image, network: config.sandbox_network,
                          memory: config.sandbox_memory, cpus: config.sandbox_cpus,
                          pids: config.sandbox_pids, workdir: config.sandbox_workdir,
                          docker_bin: config.sandbox_docker_bin)
    when Symbol then raise Error, "unknown sandbox #{config.sandbox.inspect}"
    else config.sandbox
    end
end

.sandbox_enabled?Boolean

Returns:

  • (Boolean)


64
# File 'lib/silas.rb', line 64

def sandbox_enabled? = ![ :none, nil ].include?(config.sandbox)

.schedulesObject



106
107
108
# File 'lib/silas.rb', line 106

def schedules
  config.schedules&.call || []
end

.skillsObject



102
103
104
# File 'lib/silas.rb', line 102

def skills
  config.skills&.call || []
end

.subagent?(name) ⇒ Boolean

Returns:

  • (Boolean)


119
# File 'lib/silas.rb', line 119

def subagent?(name) = subagent_index.any? { |n, _| n == name.to_s }

.subagent_indexObject

Subagent roster: [[name, description], ...] (model-visible, so it's in the root digest via Delegate.description).



118
# File 'lib/silas.rb', line 118

def subagent_index = config.subagent_index&.call || []

.subagent_scope(name) ⇒ Object



120
# File 'lib/silas.rb', line 120

def subagent_scope(name) = config.subagent_scopes&.call&.fetch(name.to_s)

.tool_definitionsObject



98
99
100
# File 'lib/silas.rb', line 98

def tool_definitions
  config.tool_definitions&.call || []
end

.tool_resolverObject



94
95
96
# File 'lib/silas.rb', line 94

def tool_resolver
  config.tool_resolver or raise Error, "no tool resolver configured (Registry boots one; specs must inject)"
end

.with_agent_scope(scope) ⇒ Object

Run a block with a subagent's scope swapped in as the active globals, restoring afterward. Synchronous/depth-1 — safe because delegation runs inline on one thread while the parent loop is paused in the delegate tool.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/silas.rb', line 125

def with_agent_scope(scope)
  saved = {
    tool_resolver: config.tool_resolver, tool_definitions: config.tool_definitions,
    definitions_digest: config.definitions_digest, skills: config.skills,
    agent_override: config.agent_override, instructions_dir: config.instructions_dir
  }
  config.tool_resolver = scope.resolver
  config.tool_definitions = -> { scope.definitions }
  config.definitions_digest = -> { scope.digest }
  config.skills = -> { scope.skills }
  config.agent_override = scope.agent
  config.instructions_dir = scope.dir
  yield
ensure
  saved.each { |k, v| config.public_send("#{k}=", v) }
end