Class: Rubino::Config::Configuration
- Inherits:
-
Object
- Object
- Rubino::Config::Configuration
- Defined in:
- lib/rubino/config/configuration.rb
Overview
Central configuration object providing typed accessors for all config sections. Wraps the raw hash loaded by Config::Loader with convenient method access.
Instance Attribute Summary collapse
-
#raw ⇒ Object
readonly
Returns the value of attribute raw.
Instance Method Summary collapse
-
#agent_budget_extension_prompt? ⇒ Boolean
At the iteration cap, prompt to continue/summarize/abort (#399).
-
#agent_budget_extension_step ⇒ Object
The “+N” one budget extension grants.
- #agent_disabled_toolsets ⇒ Object
-
#agent_max_tool_iterations ⇒ Object
– Agent section – Iteration/time caps fall back to the built-in defaults when the config value is nil/missing (e.g. ‘config set agent.max_tool_iterations nil`, whose writer coerces “nil” -> nil).
- #agent_max_turn_seconds ⇒ Object
-
#api_allow_public_bind? ⇒ Boolean
– API section – Whether the HTTP API server may bind to a non-loopback address.
-
#approvals_readonly_commands ⇒ Object
Extra command names / leading-token prefixes merged into the built-in read-only set (Security::ReadonlyCommands::SAFE_COMMANDS).
-
#approvals_wait_timeout ⇒ Object
– Security section – Seconds a run blocks on a human approval/clarification before the gate gives up and AUTO-DENIES (freeing the worker thread).
-
#auto_allow_readonly? ⇒ Boolean
Auto-allow provably read-only shell commands (ls, cat, grep, git log, …) without an approval prompt.
-
#auxiliary_config(task) ⇒ Object
Generic accessor for auxiliary task config blocks.
-
#auxiliary_vision_config ⇒ Object
– Auxiliary section –.
-
#clarify_timeout ⇒ Object
Bound (seconds) an interactive ‘question`/clarify waits for the human to answer before it EXPIRES CLEANLY and the agent proceeds with its best judgement (#552).
-
#compression_enabled? ⇒ Boolean
– Compression section –.
- #compression_preserve_tool_pairs? ⇒ Boolean
-
#confirm_policy ⇒ Object
Effective shell prompt policy and SOLE source of truth (item 7): the legacy security.require_confirmation_for_shell alias was REMOVED — no back-compat mapping.
-
#database_path ⇒ Object
– Database section – Resolves the sqlite path.
-
#dig(*keys) ⇒ Object
– Generic access –.
-
#display_code_highlight? ⇒ Boolean
Syntax-highlight committed code blocks (display.code_highlight).
-
#display_input_max_rows ⇒ Object
Cap on the chat input’s visual rows (display.input_max_rows).
-
#display_live_markdown? ⇒ Boolean
Render the in-flight streamed block as formatted markdown in the live region (display.live_markdown).
-
#display_statusbar? ⇒ Boolean
The status bar under the chat input (display.statusbar, default true).
-
#display_streaming? ⇒ Boolean
– Display section –.
-
#display_synchronized_output? ⇒ Boolean
Wrap each live-region frame in DEC-2026 synchronized output (display.synchronized_output).
-
#display_tool_output_preview_lines ⇒ Object
Transcript preview budget for tool output (display.tool_output_preview_lines): head lines shown before the “… +N lines (full output → context)” marker.
-
#doom_loop_hard_stop? ⇒ Boolean
– Doom-loop guard (#414) – Default WARN-not-block (hard_stop false): a tripped detector surfaces a warning to the model but does not deny the call.
-
#doom_loop_threshold ⇒ Object
Identical-consecutive-call threshold.
-
#initialize(raw: nil, home_path: nil) ⇒ Configuration
constructor
A new instance of Configuration.
- #memory_auto_extract? ⇒ Boolean
-
#memory_auto_extract_interval ⇒ Object
Throttle interval (in turns) for memory.auto_extract (#412).
-
#memory_auto_summarize? ⇒ Boolean
Background session-summary aux-LLM job (SummarizeSessionJob).
-
#memory_enabled? ⇒ Boolean
– Memory section –.
-
#model_supports_vision? ⇒ Boolean
Returns true when the primary model can ingest images directly.
- #notifications_bell? ⇒ Boolean
- #notifications_command ⇒ Object
-
#notifications_enabled? ⇒ Boolean
– Notifications section (UI::Notifier: attention bell + hook) – enabled/bell are on unless explicitly false; command is nil unless a non-empty string is set; min_turn_seconds falls back to the default.
- #notifications_min_turn_seconds ⇒ Object
-
#paste_collapse_chars ⇒ Object
A paste with MORE than this many CHARACTERS also collapses to a placeholder, even on a single line — a big one-line paste (a long token, URL, minified JSON) would otherwise flood the composer because the line-count trigger never fired.
-
#paste_collapse_lines ⇒ Object
– Paste section (UI::PasteStore: the file-backed paste pipeline) – A paste with MORE than this many lines collapses to a “[Pasted text #N +M lines]” placeholder in the composer (expanded to the full body at send).
-
#paste_file_threshold_tokens ⇒ Object
A paste estimated above this many tokens (chars/4, the same rule compaction uses) overflows to <home>/sessions/<id>/paste_N.txt and the message carries a read-tool pointer instead of the content.
- #prompts_environment_enabled? ⇒ Boolean
- #prompts_environment_extra_utilities ⇒ Object
-
#prompts_override_for(role) ⇒ Object
Returns the override string for a given role name, or nil if the built-in default prompt should be used.
-
#prompts_preamble ⇒ Object
– Prompts section – The customer-facing preamble prepended to every assembled system prompt.
-
#provider_config(name) ⇒ Object
– Providers section –.
- #reload! ⇒ Object
-
#run_idle_event_timeout ⇒ Object
– Run lifecycle section – Returns Float seconds (or nil to disable).
-
#security_command_allowlist ⇒ Object
The pre-approved command allowlist, always returned as an Array.
- #set(*keys, value) ⇒ Object
-
#skills_auto_distill? ⇒ Boolean
Post-turn skill distillation.
-
#skills_auto_distill_interval ⇒ Object
Throttle interval (in turns) for skills.auto_distill (#414).
-
#streaming_enabled? ⇒ Boolean
– Streaming section –.
-
#tasks_max_children_per_node ⇒ Object
Maximum number of LIVE direct children a single node (the human/top-level or one subagent) may have at once.
-
#tasks_max_concurrent_total ⇒ Object
Hard global ceiling on the total number of LIVE subagents across the whole tree, so depth × fan-out cannot blow past the process’s thread/cost budget.
-
#tasks_max_depth ⇒ Object
– Tasks / nested-subagent caps – Maximum nesting depth for the ‘task` delegation tree.
-
#tasks_max_live_probes_per_child ⇒ Object
Per-child budget for BILLED live probes (‘probe(live:true)`).
-
#tool_enabled?(name) ⇒ Boolean
– Tools section –.
-
#tool_output_capture_max_bytes ⇒ Object
Hard RAM ceiling for the shell capture seam (#539).
- #tool_output_compression_code ⇒ Object
-
#tool_output_compression_code_languages ⇒ Object
Source languages the code skeletoner is enabled for (e.g. [“ruby”]).
-
#tool_output_compression_diff ⇒ Object
DIFF compression config.
-
#tool_output_compression_enabled? ⇒ Boolean
Deterministic, reversible compression of tool-read results (whole-file Ruby reads → skeleton).
-
#tool_output_compression_json ⇒ Object
JSON compression config.
-
#tool_output_compression_logs ⇒ Object
LOG/command-output compression config.
- #tool_output_compression_logs_enabled? ⇒ Boolean
-
#ui_verbose? ⇒ Boolean
– UI section –.
Constructor Details
#initialize(raw: nil, home_path: nil) ⇒ Configuration
Returns a new instance of Configuration.
10 11 12 13 |
# File 'lib/rubino/config/configuration.rb', line 10 def initialize(raw: nil, home_path: nil) @home_path = home_path @raw = raw || load_from_file end |
Instance Attribute Details
#raw ⇒ Object (readonly)
Returns the value of attribute raw.
8 9 10 |
# File 'lib/rubino/config/configuration.rb', line 8 def raw @raw end |
Instance Method Details
#agent_budget_extension_prompt? ⇒ Boolean
At the iteration cap, prompt to continue/summarize/abort (#399). Defaults to true; an explicit false forces the old always-summarize behaviour. Independent of TTY — the headless guarantee lives in @ui.select returning nil, not here.
166 167 168 169 |
# File 'lib/rubino/config/configuration.rb', line 166 def agent_budget_extension_prompt? v = dig("agent", "budget_extension_prompt") v.nil? ? Defaults.dig("agent", "budget_extension_prompt") : v == true end |
#agent_budget_extension_step ⇒ Object
The “+N” one budget extension grants. nil/blank ⇒ max_tool_iterations, so an extension doubles the per-turn runway (the Cline/Roo “reset the counter, keep context” amount). Coerced to a positive Integer; a bad value falls back to the iteration cap.
175 176 177 178 179 |
# File 'lib/rubino/config/configuration.rb', line 175 def agent_budget_extension_step raw = dig("agent", "budget_extension_step") n = Integer(raw, exception: false) n&.positive? ? n : agent_max_tool_iterations end |
#agent_disabled_toolsets ⇒ Object
181 182 183 |
# File 'lib/rubino/config/configuration.rb', line 181 def agent_disabled_toolsets dig("agent", "disabled_toolsets") || [] end |
#agent_max_tool_iterations ⇒ Object
– Agent section – Iteration/time caps fall back to the built-in defaults when the config value is nil/missing (e.g. ‘config set agent.max_tool_iterations nil`, whose writer coerces “nil” -> nil). A bare nil here would crash every turn in IterationBudget’s numeric comparisons (#139).
154 155 156 |
# File 'lib/rubino/config/configuration.rb', line 154 def agent_max_tool_iterations dig("agent", "max_tool_iterations") || Defaults.dig("agent", "max_tool_iterations") end |
#agent_max_turn_seconds ⇒ Object
158 159 160 |
# File 'lib/rubino/config/configuration.rb', line 158 def agent_max_turn_seconds dig("agent", "max_turn_seconds") || Defaults.dig("agent", "max_turn_seconds") end |
#api_allow_public_bind? ⇒ Boolean
– API section – Whether the HTTP API server may bind to a non-loopback address. SAFE BY DEFAULT (#577): false REFUSES a routable bind (the API runs shell tools); set true to deliberately publish the listener (use TLS + a strong key).
467 468 469 |
# File 'lib/rubino/config/configuration.rb', line 467 def api_allow_public_bind? dig("api", "allow_public_bind") == true end |
#approvals_readonly_commands ⇒ Object
Extra command names / leading-token prefixes merged into the built-in read-only set (Security::ReadonlyCommands::SAFE_COMMANDS).
400 401 402 |
# File 'lib/rubino/config/configuration.rb', line 400 def approvals_readonly_commands dig("approvals", "readonly_commands") || [] end |
#approvals_wait_timeout ⇒ Object
– Security section – Seconds a run blocks on a human approval/clarification before the gate gives up and AUTO-DENIES (freeing the worker thread). nil = wait indefinitely (interruptible only by an explicit stop). Used by ApprovalGate as its default await deadline so an abandoned approval never parks a server worker for the whole window (W1).
384 385 386 387 388 389 |
# File 'lib/rubino/config/configuration.rb', line 384 def approvals_wait_timeout raw = dig("approvals", "wait_timeout_seconds") return nil if raw.nil? raw.to_f end |
#auto_allow_readonly? ⇒ Boolean
Auto-allow provably read-only shell commands (ls, cat, grep, git log, …) without an approval prompt. Default ON (key absent = on); the hardline floor and permissions:deny still precede it.
394 395 396 |
# File 'lib/rubino/config/configuration.rb', line 394 def auto_allow_readonly? dig("approvals", "auto_allow_readonly") != false end |
#auxiliary_config(task) ⇒ Object
Generic accessor for auxiliary task config blocks. Returns {} when the task isn’t defined, so callers can chain .dig safely.
448 449 450 |
# File 'lib/rubino/config/configuration.rb', line 448 def auxiliary_config(task) dig("auxiliary", task.to_s) || {} end |
#auxiliary_vision_config ⇒ Object
– Auxiliary section –
442 443 444 |
# File 'lib/rubino/config/configuration.rb', line 442 def auxiliary_vision_config dig("auxiliary", "vision") || {} end |
#clarify_timeout ⇒ Object
Bound (seconds) an interactive ‘question`/clarify waits for the human to answer before it EXPIRES CLEANLY and the agent proceeds with its best judgement (#552). Mirrors the Hermes clarify_timeout convention — a generous upper bound (default 600s = 10 min, well above human reading/deliberation time), never the 30s stale-chunk window and never “forever”. An abandoned clarify self-heals into the NO_ANSWER outcome instead of hanging the run or being killed by the stale watchdog.
222 223 224 |
# File 'lib/rubino/config/configuration.rb', line 222 def clarify_timeout dig("clarify", "timeout") || Defaults.dig("clarify", "timeout") end |
#compression_enabled? ⇒ Boolean
– Compression section –
270 271 272 |
# File 'lib/rubino/config/configuration.rb', line 270 def compression_enabled? dig("compression", "enabled") == true end |
#compression_preserve_tool_pairs? ⇒ Boolean
274 275 276 |
# File 'lib/rubino/config/configuration.rb', line 274 def compression_preserve_tool_pairs? dig("compression", "preserve_tool_pairs") == true end |
#confirm_policy ⇒ Object
Effective shell prompt policy and SOLE source of truth (item 7): the legacy security.require_confirmation_for_shell alias was REMOVED — no back-compat mapping. :dangerous_only (DEFAULT — safe shell commands run unprompted; only DangerousPatterns matches prompt) or :confirm_all (every not-otherwise-allowed shell command prompts). An unset or unrecognized value falls back to the seeded :dangerous_only default. A config that still carries the removed key is NOT silently honored — Validator.warnings flags it at load + in ‘rubino doctor`.
412 413 414 415 416 417 |
# File 'lib/rubino/config/configuration.rb', line 412 def confirm_policy raw = dig("security", "confirm_policy") return raw.to_sym if %w[confirm_all dangerous_only].include?(raw.to_s) :dangerous_only end |
#database_path ⇒ Object
– Database section – Resolves the sqlite path. The DEFAULT (sentinel) follows the resolved home so RUBINO_HOME relocates the DB alongside config/.env/skills, avoiding the split brain where config went to the isolated home but the DB to the real ~/.rubino (issue #96). An EXPLICIT database.path in config.yml wins and is expanded verbatim.
21 22 23 24 25 26 27 28 |
# File 'lib/rubino/config/configuration.rb', line 21 def database_path path = dig("database", "path") if path == Defaults::DEFAULT_DATABASE_PATH File.join(resolved_home, "rubino.sqlite3") else File.(path) end end |
#dig(*keys) ⇒ Object
– Generic access –
472 473 474 |
# File 'lib/rubino/config/configuration.rb', line 472 def dig(*keys) @raw.dig(*keys) end |
#display_code_highlight? ⇒ Boolean
Syntax-highlight committed code blocks (display.code_highlight). Default true; only an explicit false falls back to plain (uncoloured) code.
79 80 81 |
# File 'lib/rubino/config/configuration.rb', line 79 def display_code_highlight? dig("display", "code_highlight") != false end |
#display_input_max_rows ⇒ Object
Cap on the chat input’s visual rows (display.input_max_rows). Falls back to the composer default for nil/zero/garbage so a bad value can never collapse or unbound the input block.
58 59 60 61 |
# File 'lib/rubino/config/configuration.rb', line 58 def display_input_max_rows value = dig("display", "input_max_rows").to_i value.positive? ? value : UI::BottomComposer::MAX_INPUT_ROWS end |
#display_live_markdown? ⇒ Boolean
Render the in-flight streamed block as formatted markdown in the live region (display.live_markdown). Default true; only an explicit false falls back to the legacy raw live tail.
66 67 68 |
# File 'lib/rubino/config/configuration.rb', line 66 def display_live_markdown? dig("display", "live_markdown") != false end |
#display_statusbar? ⇒ Boolean
The status bar under the chat input (display.statusbar, default true). Only an explicit false disables it.
42 43 44 |
# File 'lib/rubino/config/configuration.rb', line 42 def dig("display", "statusbar") != false end |
#display_streaming? ⇒ Boolean
– Display section –
36 37 38 |
# File 'lib/rubino/config/configuration.rb', line 36 def display_streaming? dig("display", "streaming") == true end |
#display_synchronized_output? ⇒ Boolean
Wrap each live-region frame in DEC-2026 synchronized output (display.synchronized_output). Default true; only an explicit false falls back to the legacy per-write frames.
73 74 75 |
# File 'lib/rubino/config/configuration.rb', line 73 def display_synchronized_output? dig("display", "synchronized_output") != false end |
#display_tool_output_preview_lines ⇒ Object
Transcript preview budget for tool output (display.tool_output_preview_lines): head lines shown before the “… +N lines (full output → context)” marker. 0 = no collapse (full dump). Display-only — the model-facing output is untouched.
50 51 52 53 |
# File 'lib/rubino/config/configuration.rb', line 50 def display_tool_output_preview_lines value = dig("display", "tool_output_preview_lines") value.nil? ? 3 : value.to_i end |
#doom_loop_hard_stop? ⇒ Boolean
– Doom-loop guard (#414) – Default WARN-not-block (hard_stop false): a tripped detector surfaces a warning to the model but does not deny the call.
138 139 140 |
# File 'lib/rubino/config/configuration.rb', line 138 def doom_loop_hard_stop? dig("doom_loop", "hard_stop") == true end |
#doom_loop_threshold ⇒ Object
Identical-consecutive-call threshold. Falls back to the detector default when absent/garbage so a bad config value can’t disable the guard.
144 145 146 147 |
# File 'lib/rubino/config/configuration.rb', line 144 def doom_loop_threshold n = Integer(dig("doom_loop", "threshold"), exception: false) n && n >= 2 ? n : Security::DoomLoopDetector::DEFAULT_THRESHOLD end |
#memory_auto_extract? ⇒ Boolean
283 284 285 |
# File 'lib/rubino/config/configuration.rb', line 283 def memory_auto_extract? dig("memory", "auto_extract") == true end |
#memory_auto_extract_interval ⇒ Object
Throttle interval (in turns) for memory.auto_extract (#412). Returns a positive Integer; nil/<=1 (or absent) ⇒ 1 = every turn. The lifecycle only enqueues ExtractMemoryJob when turns-since-last >= this.
298 299 300 |
# File 'lib/rubino/config/configuration.rb', line 298 def memory_auto_extract_interval positive_interval(dig("memory", "auto_extract_interval")) end |
#memory_auto_summarize? ⇒ Boolean
Background session-summary aux-LLM job (SummarizeSessionJob). Default ON (absent ⇒ true), so existing behaviour is unchanged; an explicit false turns it off — letting the whole background aux-LLM surface (extract/distill/summarize) be disabled together.
291 292 293 |
# File 'lib/rubino/config/configuration.rb', line 291 def memory_auto_summarize? dig("memory", "auto_summarize") != false end |
#memory_enabled? ⇒ Boolean
– Memory section –
279 280 281 |
# File 'lib/rubino/config/configuration.rb', line 279 def memory_enabled? dig("memory", "enabled") == true end |
#model_supports_vision? ⇒ Boolean
Returns true when the primary model can ingest images directly. Honours an explicit ‘model.supports_vision` override; otherwise falls back to ContentBuilder’s name-pattern heuristic. Used by VisionTool to decide whether to expose itself (no point delegating if the primary can see).
456 457 458 459 460 461 |
# File 'lib/rubino/config/configuration.rb', line 456 def model_supports_vision? raw = dig("model", "supports_vision") return raw == true unless raw.nil? LLM::ContentBuilder.supports_vision?(dig("model", "default").to_s) end |
#notifications_bell? ⇒ Boolean
116 117 118 |
# File 'lib/rubino/config/configuration.rb', line 116 def notifications_bell? dig("notifications", "bell") != false end |
#notifications_command ⇒ Object
120 121 122 123 |
# File 'lib/rubino/config/configuration.rb', line 120 def notifications_command value = dig("notifications", "command").to_s value.empty? ? nil : value end |
#notifications_enabled? ⇒ Boolean
– Notifications section (UI::Notifier: attention bell + hook) – enabled/bell are on unless explicitly false; command is nil unless a non-empty string is set; min_turn_seconds falls back to the default.
112 113 114 |
# File 'lib/rubino/config/configuration.rb', line 112 def notifications_enabled? dig("notifications", "enabled") != false end |
#notifications_min_turn_seconds ⇒ Object
125 126 127 128 |
# File 'lib/rubino/config/configuration.rb', line 125 def notifications_min_turn_seconds value = dig("notifications", "min_turn_seconds") (value.nil? ? Defaults.dig("notifications", "min_turn_seconds") : value).to_f end |
#paste_collapse_chars ⇒ Object
A paste with MORE than this many CHARACTERS also collapses to a placeholder, even on a single line — a big one-line paste (a long token, URL, minified JSON) would otherwise flood the composer because the line-count trigger never fired. Falls back for nil/zero/garbage.
96 97 98 99 |
# File 'lib/rubino/config/configuration.rb', line 96 def paste_collapse_chars value = dig("paste", "collapse_chars").to_i value.positive? ? value : UI::PasteStore::DEFAULT_COLLAPSE_CHARS end |
#paste_collapse_lines ⇒ Object
– Paste section (UI::PasteStore: the file-backed paste pipeline) – A paste with MORE than this many lines collapses to a “[Pasted text #N +M lines]” placeholder in the composer (expanded to the full body at send). Falls back for nil/zero/garbage.
87 88 89 90 |
# File 'lib/rubino/config/configuration.rb', line 87 def paste_collapse_lines value = dig("paste", "collapse_lines").to_i value.positive? ? value : UI::PasteStore::DEFAULT_COLLAPSE_LINES end |
#paste_file_threshold_tokens ⇒ Object
A paste estimated above this many tokens (chars/4, the same rule compaction uses) overflows to <home>/sessions/<id>/paste_N.txt and the message carries a read-tool pointer instead of the content.
104 105 106 107 |
# File 'lib/rubino/config/configuration.rb', line 104 def paste_file_threshold_tokens value = dig("paste", "file_threshold_tokens").to_i value.positive? ? value : UI::PasteStore::DEFAULT_THRESHOLD_TOKENS end |
#prompts_environment_enabled? ⇒ Boolean
237 238 239 240 241 242 |
# File 'lib/rubino/config/configuration.rb', line 237 def prompts_environment_enabled? # Default to on when the key is absent — env injection is the cheap # win we don't want a forgetful config.yml to disable accidentally. value = dig("prompts", "environment", "enabled") value.nil? || value == true end |
#prompts_environment_extra_utilities ⇒ Object
244 245 246 |
# File 'lib/rubino/config/configuration.rb', line 244 def prompts_environment_extra_utilities Array(dig("prompts", "environment", "extra_utilities")).map(&:to_s) end |
#prompts_override_for(role) ⇒ Object
Returns the override string for a given role name, or nil if the built-in default prompt should be used.
250 251 252 253 254 255 256 |
# File 'lib/rubino/config/configuration.rb', line 250 def prompts_override_for(role) value = dig("prompts", "overrides", role.to_s) return nil if value.nil? text = value.to_s.strip text.empty? ? nil : text end |
#prompts_preamble ⇒ Object
– Prompts section – The customer-facing preamble prepended to every assembled system prompt. nil/empty disables the layer.
229 230 231 232 233 234 235 |
# File 'lib/rubino/config/configuration.rb', line 229 def prompts_preamble value = dig("prompts", "preamble") return nil if value.nil? text = value.to_s.strip text.empty? ? nil : text end |
#provider_config(name) ⇒ Object
– Providers section –
437 438 439 |
# File 'lib/rubino/config/configuration.rb', line 437 def provider_config(name) dig("providers", name.to_s) || {} end |
#reload! ⇒ Object
485 486 487 |
# File 'lib/rubino/config/configuration.rb', line 485 def reload! @raw = load_from_file end |
#run_idle_event_timeout ⇒ Object
– Run lifecycle section – Returns Float seconds (or nil to disable). EventsOperation uses this to bound how long a “running” row can go without producing a new event before the watchdog promotes it to failed.
262 263 264 265 266 267 |
# File 'lib/rubino/config/configuration.rb', line 262 def run_idle_event_timeout raw = dig("run", "idle_event_timeout") return nil if raw.nil? raw.to_f end |
#security_command_allowlist ⇒ Object
The pre-approved command allowlist, always returned as an Array.
YAML lets a user write ‘command_allowlist: git status` (a scalar) where a sequence was meant. The matcher (CommandAllowlist#allowlist_token_lists) calls #filter_map on this value; a bare String would raise an unhandled NoMethodError out of the approval path (a crash, not the clean fail-closed contract — CFG-R3-1). Coerce a scalar to a single-entry array and drop any nil so the matcher always receives a well-formed list.
427 428 429 430 431 432 433 434 |
# File 'lib/rubino/config/configuration.rb', line 427 def security_command_allowlist raw = dig("security", "command_allowlist") case raw when Array then raw when nil then [] else [raw] end end |
#set(*keys, value) ⇒ Object
476 477 478 479 480 481 482 483 |
# File 'lib/rubino/config/configuration.rb', line 476 def set(*keys, value) hash = @raw keys[0..-2].each do |key| hash[key] ||= {} hash = hash[key] end hash[keys.last] = value end |
#skills_auto_distill? ⇒ Boolean
Post-turn skill distillation. Defaults to true (skills feature on + distill key absent ⇒ distill on), mirroring memory_auto_extract? as the gate for an aux-spending background job. Turning skills off disables it too, since there is no point distilling skills that won’t be loaded.
306 307 308 309 310 311 |
# File 'lib/rubino/config/configuration.rb', line 306 def skills_auto_distill? return false unless dig("skills", "enabled") != false value = dig("skills", "auto_distill") value.nil? || value == true end |
#skills_auto_distill_interval ⇒ Object
Throttle interval (in turns) for skills.auto_distill (#414). Mirrors memory_auto_extract_interval. nil/<=1 ⇒ every eligible turn.
315 316 317 |
# File 'lib/rubino/config/configuration.rb', line 315 def skills_auto_distill_interval positive_interval(dig("skills", "auto_distill_interval")) end |
#streaming_enabled? ⇒ Boolean
– Streaming section –
131 132 133 |
# File 'lib/rubino/config/configuration.rb', line 131 def streaming_enabled? dig("streaming", "enabled") == true end |
#tasks_max_children_per_node ⇒ Object
Maximum number of LIVE direct children a single node (the human/top-level or one subagent) may have at once. Default 3.
197 198 199 |
# File 'lib/rubino/config/configuration.rb', line 197 def tasks_max_children_per_node dig("tasks", "max_children_per_node") || Defaults.dig("tasks", "max_children_per_node") end |
#tasks_max_concurrent_total ⇒ Object
Hard global ceiling on the total number of LIVE subagents across the whole tree, so depth × fan-out cannot blow past the process’s thread/cost budget. Default 8.
204 205 206 |
# File 'lib/rubino/config/configuration.rb', line 204 def tasks_max_concurrent_total dig("tasks", "max_concurrent_total") || Defaults.dig("tasks", "max_concurrent_total") end |
#tasks_max_depth ⇒ Object
– Tasks / nested-subagent caps – Maximum nesting depth for the ‘task` delegation tree. depth 0 is a human/top-level-spawned child; the cap bounds how deep a chain of subagents-spawning-subagents may go. Default 2 ⇒ human→child→grandchild. Falls back to the built-in default when missing/nil so the numeric caps in BackgroundTask#reserve never crash on a bare nil.
191 192 193 |
# File 'lib/rubino/config/configuration.rb', line 191 def tasks_max_depth dig("tasks", "max_depth") || Defaults.dig("tasks", "max_depth") end |
#tasks_max_live_probes_per_child ⇒ Object
Per-child budget for BILLED live probes (‘probe(live:true)`). Over budget, the model is steered to the FREE live:false snapshot. Free snapshots are unlimited. Default 5.
211 212 213 |
# File 'lib/rubino/config/configuration.rb', line 211 def tasks_max_live_probes_per_child dig("tasks", "max_live_probes_per_child") || Defaults.dig("tasks", "max_live_probes_per_child") end |
#tool_enabled?(name) ⇒ Boolean
– Tools section –
320 321 322 |
# File 'lib/rubino/config/configuration.rb', line 320 def tool_enabled?(name) dig("tools", name.to_s) == true end |
#tool_output_capture_max_bytes ⇒ Object
Hard RAM ceiling for the shell capture seam (#539). Defaults via the defaults hash; coerced to a sane positive floor so a misconfig can’t disable the cap and re-open the unbounded-producer OOM.
327 328 329 330 |
# File 'lib/rubino/config/configuration.rb', line 327 def tool_output_capture_max_bytes value = dig("tool_output", "capture_max_bytes").to_i value.positive? ? value : 2_000_000 end |
#tool_output_compression_code ⇒ Object
339 340 341 |
# File 'lib/rubino/config/configuration.rb', line 339 def tool_output_compression_code dig("tool_output_compression", "code") || {} end |
#tool_output_compression_code_languages ⇒ Object
Source languages the code skeletoner is enabled for (e.g. [“ruby”]). A whole-file read whose language isn’t in this list passes through verbatim. Ruby uses the built-in Prism parser; later languages need their own parser registered before being added here.
347 348 349 |
# File 'lib/rubino/config/configuration.rb', line 347 def tool_output_compression_code_languages tool_output_compression_code["languages"] || [] end |
#tool_output_compression_diff ⇒ Object
DIFF compression config. Like ‘code`, it has NO own `enabled` sub-flag: it is active whenever the master `tool_output_compression.enabled` is on. The DiffCompressor’s saving guard (min_lines + min_saving) is the real gate — a small/tight diff passes through byte-identical on its own.
355 356 357 |
# File 'lib/rubino/config/configuration.rb', line 355 def tool_output_compression_diff dig("tool_output_compression", "diff") || {} end |
#tool_output_compression_enabled? ⇒ Boolean
Deterministic, reversible compression of tool-read results (whole-file Ruby reads → skeleton). OFF by default: when false the read tool is byte-for-byte unchanged. See Compression::Compressor.
335 336 337 |
# File 'lib/rubino/config/configuration.rb', line 335 def tool_output_compression_enabled? dig("tool_output_compression", "enabled") == true end |
#tool_output_compression_json ⇒ Object
JSON compression config. Like ‘code`/`diff`, it has NO own `enabled` sub-flag: it is active whenever the master `tool_output_compression.enabled` is on. The JsonCompressor’s saving + size guards are the real gate — small JSON the model wants verbatim passes through byte-identical on its own.
370 371 372 |
# File 'lib/rubino/config/configuration.rb', line 370 def tool_output_compression_json dig("tool_output_compression", "json") || {} end |
#tool_output_compression_logs ⇒ Object
LOG/command-output compression config. Independently gated from ‘code` via its own `enabled` flag, so we can flip the high-ROI log channel on without touching the code-skeleton channel.
362 363 364 |
# File 'lib/rubino/config/configuration.rb', line 362 def tool_output_compression_logs dig("tool_output_compression", "logs") || {} end |
#tool_output_compression_logs_enabled? ⇒ Boolean
374 375 376 |
# File 'lib/rubino/config/configuration.rb', line 374 def tool_output_compression_logs_enabled? tool_output_compression_logs["enabled"] == true end |
#ui_verbose? ⇒ Boolean
– UI section –
31 32 33 |
# File 'lib/rubino/config/configuration.rb', line 31 def ui_verbose? dig("ui", "verbose") == true end |