Class: LittleGhost::Configuration
- Inherits:
-
Object
- Object
- LittleGhost::Configuration
- Defined in:
- lib/little_ghost/configuration.rb
Overview
Configure shared services and lookup rules before agents start. A configuration collects model profiles, persistence, paths, instrumentation, and runtime hooks for an application.
LittleGhost.configure do |config|
config.default_model :customer_support
config.service_name "support-api"
end
LittleGhost.configuration.default_model # => "customer_support"
LittleGhost.configuration.service_name # => "support-api"
Prompt and skill lookup paths default to app/prompts and app/skills
under the application root. Applications may append shared roots or replace
the arrays entirely.
Configuration is a mutable application builder until its shared Runtime is first used. A successful #runtime call locks the builder so standalone Agents and Assemblies keep one stable setup. Configure the application before its first entrypoint call. Explicit Runtime construction remains an advanced way to take an independent snapshot without selecting the shared default.
Multi-tenant applications should derive Session actor identity from state established after authentication, not from an unverified request field.
Constant Summary collapse
- FILE_LOAD_MUTEX =
:nodoc:
Mutex.new
- CONFIGURATION_KEYS =
:nodoc:
%i[invocation service_name].freeze
- RUNTIME_BUILD_CONTEXT_KEY =
:nodoc:
:little_ghost_runtime_build_context- DEFAULT_PROMPT_PATHS =
:nodoc:
["app/prompts"].freeze
- DEFAULT_SKILL_PATHS =
:nodoc:
["app/skills"].freeze
Instance Method Summary collapse
-
#[](name) ⇒ Object
Looks up an arbitrary setting by symbol or string-compatible name.
-
#[]=(name, value) ⇒ Object
Adds or replaces an arbitrary setting.
-
#artifacts(&resolver) ⇒ Object
Stores input attachments, Tool artifacts, and oversized successful Tool values under the conventional
:artifactsWorkspace path. -
#blocking_pool_capacity(value = :__read__) ⇒ Object
Returns or sets the maximum number of process-wide workers available to LittleGhost.offload_blocking, certificate generation, and Filesystem SessionStore transactions when they run from scheduled fibers.
-
#blocking_pool_capacity=(value) ⇒ Object
Sets the same process-wide worker limit as
blocking_pool_capacity. -
#catalog_source(source) ⇒ Object
Adds an explicit catalog source.
-
#code_mode ⇒ Object
Default code-mode declaration for enabled Agents.
-
#code_mode=(value) ⇒ Object
Configures application defaults for code-mode Agents.
-
#concurrency_backend(value = :__read__) ⇒ Object
Selects how subsequently built runtimes start independent work such as parallel Tool calls and Workflow branches.
-
#concurrency_backend=(value) ⇒ Object
Replaces the concurrency backend for subsequently built runtimes.
-
#configure ⇒ Object
Yields this builder for setup and returns the same instance.
-
#default_model(value = :__read__) ⇒ Object
Fallback logical role for the default resolver.
-
#default_model=(value) ⇒ Object
Replaces the fallback logical role and normalizes it to a String.
-
#initialize(values = {}) ⇒ Configuration
constructor
Starts a mutable builder with optional
values. -
#instrument(subscriber) ⇒ Object
Adds an Instrumentation::Subscriber to each new runtime and returns it.
-
#load_file!(root: nil) ⇒ Object
:nodoc:.
-
#log_events_to(destination = :__read__) ⇒ Object
:call-seq: log_events_to() -> :stdout, :stderr, nil log_events_to(destination) -> destination.
-
#log_events_to=(destination) ⇒ Object
Replaces the console destination for structured framework events.
-
#model_resolver(value = :__read__) ⇒ Object
Installs a complete resolver override for subsequently built runtimes.
- #model_resolver=(value) ⇒ Object
-
#models(value = :__read__) ⇒ Object
Logical model profiles for the default resolver.
-
#models=(value) ⇒ Object
Replaces logical model profiles for subsequently built runtimes.
-
#models_path(value = :__read__) ⇒ Object
Model YAML path.
-
#models_path=(value) ⇒ Object
Replaces the model YAML path for subsequently built runtimes.
-
#name ⇒ Object
Replaces the service name attached to telemetry from new runtimes.
-
#prompt_paths ⇒ Object
Prompt lookup paths in precedence order.
-
#prompt_paths=(value) ⇒ Object
Replaces prompt lookup paths with
valueconverted to an Array. -
#provider_adapter(name, callable = nil, &factory) ⇒ Object
Registers a provider adapter factory under
name. -
#provider_credentials(callable = nil, &resolver) ⇒ Object
Installs a trusted callable that returns credential options for a named provider connection when each executable model is constructed.
-
#providers(value = :__read__) ⇒ Object
Trusted provider connections for the default or custom resolver.
-
#providers=(value) ⇒ Object
Replaces trusted provider connections for subsequently built runtimes.
-
#providers_path(value = :__read__) ⇒ Object
Provider YAML path.
-
#providers_path=(value) ⇒ Object
Replaces the provider YAML path for subsequently built runtimes.
-
#root(value = :__read__) ⇒ Object
:call-seq: root() -> Pathname root(path) -> Pathname.
-
#root=(value) ⇒ Object
Replaces the application root after resolving it to a stable real path.
-
#runtime ⇒ Object
Returns the shared Runtime for this configuration, building it on first use.
-
#runtime_hook(hook_class) ⇒ Object
Adds a Runtime::Hook subclass to each new runtime and returns it.
-
#sandbox ⇒ Object
Sandbox declaration used for subsequently built runtimes.
-
#sandbox=(value) ⇒ Object
Selects the Sandbox provider instantiated around each run's workspace.
-
#session_actor(value = :__read__, &resolver) ⇒ Object
:call-seq: session_actor() -> callable, nil session_actor(callable) -> callable session_actor { |invocation| ... } -> callable.
-
#session_store ⇒ Object
Session-store declaration used for subsequently built runtimes.
-
#session_store=(value) ⇒ Object
Selects session persistence with a
:providerand its constructor options. -
#settings(root: nil) ⇒ Object
:nodoc:.
-
#skill_paths ⇒ Object
Skill lookup paths in precedence order.
-
#skill_paths=(value) ⇒ Object
Replaces skill lookup paths with
valueconverted to an Array. -
#skill_resource_root ⇒ Object
Optional model-facing root used for skill locations and resources.
-
#skill_resource_root=(value) ⇒ Object
Replaces and validates the skill resource root for new runtimes.
-
#workspace ⇒ Object
Workspace declaration used for subsequently built runtimes.
-
#workspace=(value) ⇒ Object
Selects the Workspace provider instantiated for each run.
Constructor Details
#initialize(values = {}) ⇒ Configuration
Starts a mutable builder with optional values.
Prompt paths default to app/prompts and skill paths to app/skills.
Collection settings are copied so callers can safely reuse their input
arrays after construction.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/little_ghost/configuration.rb', line 90 def initialize(values = {}) @lifecycle_monitor = Monitor.new @runtime_condition = @lifecycle_monitor.new_cond @configuration_values = { prompt_paths: DEFAULT_PROMPT_PATHS.dup, skill_paths: DEFAULT_SKILL_PATHS.dup, skill_resource_root: nil, workspace: nil, sandbox: nil, code_mode: nil, instrumentation_subscribers: [], runtime_hooks: [], concurrency_backend: :auto }.merge(values) @configuration_values[:concurrency_backend] = normalize_concurrency_backend( @configuration_values[:concurrency_backend] ) if values.key?(:blocking_pool_capacity) Support::Executor.blocking.runner.capacity = normalize_blocking_pool_capacity( values[:blocking_pool_capacity] ) @configuration_values.delete(:blocking_pool_capacity) end @configuration_values[:prompt_paths] = Array(@configuration_values[:prompt_paths]).dup @configuration_values[:skill_paths] = Array(@configuration_values[:skill_paths]).dup @configuration_values[:skill_resource_root] = Skills::ResourceRoot.normalize( @configuration_values[:skill_resource_root] ) @configuration_values[:instrumentation_subscribers] = Array( @configuration_values[:instrumentation_subscribers] ).dup @configuration_values[:runtime_hooks] = Array(@configuration_values[:runtime_hooks]).dup @configuration_values[:provider_adapters] = @configuration_values.fetch(:provider_adapters, {}).dup @configuration_values[:catalog_sources] = Array(@configuration_values[:catalog_sources]).dup @configuration_values[:provider_credentials] ||= nil if @configuration_values[:workspace] @configuration_values[:workspace] = component_declaration( @configuration_values[:workspace], Workspace, :workspace ) end if @configuration_values[:sandbox] @configuration_values[:sandbox] = component_declaration( @configuration_values[:sandbox], Sandbox, :sandbox ) end end |
Instance Method Details
#[](name) ⇒ Object
Looks up an arbitrary setting by symbol or string-compatible name.
490 491 492 493 494 |
# File 'lib/little_ghost/configuration.rb', line 490 def [](name) return blocking_pool_capacity if name.to_sym == :blocking_pool_capacity configuration_values.fetch(name.to_sym) end |
#[]=(name, value) ⇒ Object
Adds or replaces an arbitrary setting.
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
# File 'lib/little_ghost/configuration.rb', line 497 def []=(name, value) case name.to_sym when :workspace self.workspace = value when :sandbox self.sandbox = value when :code_mode self.code_mode = value when :concurrency_backend self.concurrency_backend = value when :blocking_pool_capacity self.blocking_pool_capacity = value else change_configuration { configuration_values[name.to_sym] = value } end end |
#artifacts(&resolver) ⇒ Object
Stores input attachments, Tool artifacts, and oversized successful Tool
values under the conventional :artifacts Workspace path. An optional
block receives deferred Artifacts and may load their bytes for the current
Run. It may return a String, an inline Artifact, or nil.
The block is application code. It must authorize each reference using identity established by the application and limit any file or network read before returning bytes. LittleGhost applies its storage limits afterward.
:call-seq:
artifacts() -> Class<Runtime::Hook>
artifacts { |artifact, run:| bytes_or_artifact_or_nil } -> Class<Runtime::Hook>
574 575 576 577 578 579 580 581 582 583 584 |
# File 'lib/little_ghost/configuration.rb', line 574 def artifacts(&resolver) hook = Runtime::Hooks::Artifacts.configured(resolver:) ensure_configuration_open! change_configuration do configuration_values[:runtime_hooks].reject! do |configured| configured <= Runtime::Hooks::Artifacts end configuration_values[:runtime_hooks] << hook end hook end |
#blocking_pool_capacity(value = :__read__) ⇒ Object
Returns or sets the maximum number of process-wide workers available to LittleGhost.offload_blocking, certificate generation, and Filesystem SessionStore transactions when they run from scheduled fibers. Workers are created lazily. The default is 2. Every Configuration reads and writes the same process-wide value.
Configure this during process startup, before any operation can start the
pool. value must be a positive Integer. Raises ArgumentError for an
invalid value and ConfigurationError when changing the value after the
pool has started.
:call-seq:
blocking_pool_capacity() -> integer
blocking_pool_capacity(value) -> integer
249 250 251 252 253 254 255 256 257 |
# File 'lib/little_ghost/configuration.rb', line 249 def blocking_pool_capacity(value = :__read__) return Support::Executor.blocking.runner.capacity if value == :__read__ normalized = normalize_blocking_pool_capacity(value) change_configuration do Support::Executor.blocking.runner.capacity = normalized end normalized end |
#blocking_pool_capacity=(value) ⇒ Object
Sets the same process-wide worker limit as blocking_pool_capacity.
260 261 262 |
# File 'lib/little_ghost/configuration.rb', line 260 def blocking_pool_capacity=(value) blocking_pool_capacity(value) end |
#catalog_source(source) ⇒ Object
Adds an explicit catalog source. Sources refresh only when callers invoke ModelResolver#refresh!.
416 417 418 419 420 421 422 423 424 425 |
# File 'lib/little_ghost/configuration.rb', line 416 def catalog_source(source) ensure_configuration_open! raise ArgumentError, "catalog source must be a Models::Catalog::Source" unless source.is_a?(Models::Catalog::Source) change_configuration do configuration_values[:catalog_sources] << source @resolved_model_resolver = nil end source end |
#code_mode ⇒ Object
Default code-mode declaration for enabled Agents. The Hash may select an
:engine and :sandbox, override :limits, and name Tools to keep in the
conversation with :except.
271 272 |
# File 'lib/little_ghost/configuration.rb', line 271 def code_mode = configuration_values[:code_mode] # Session-store declaration used for subsequently built runtimes. |
#code_mode=(value) ⇒ Object
Configures application defaults for code-mode Agents. The Hash may select
an :engine and :sandbox, override :limits, and name ordinary Tools
that remain in the conversation with :except.
463 464 465 466 467 468 469 |
# File 'lib/little_ghost/configuration.rb', line 463 def code_mode=(value) change_configuration do raise ArgumentError, "code_mode must be a Hash" unless value.nil? || value.is_a?(Hash) @configuration_values[:code_mode] = value&.transform_keys(&:to_sym)&.freeze end end |
#concurrency_backend(value = :__read__) ⇒ Object
Selects how subsequently built runtimes start independent work such as parallel Tool calls and Workflow branches.
The default, :auto, uses fibers when the caller is already running in a
scheduled fiber and uses threads otherwise. :thread always uses threads.
:fiber raises ConfigurationError when the caller is not in a scheduled
fiber. The application's scheduler must support Fiber.schedule. Any other
value raises ArgumentError.
LittleGhost.configure do |config|
config.concurrency_backend = :thread
end
:call-seq:
concurrency_backend() -> :auto, :thread, :fiber
concurrency_backend(value) -> :auto, :thread, :fiber
222 223 224 225 226 227 228 |
# File 'lib/little_ghost/configuration.rb', line 222 def concurrency_backend(value = :__read__) return configuration_values[:concurrency_backend] if value == :__read__ normalized = normalize_concurrency_backend(value) change_configuration { configuration_values[:concurrency_backend] = normalized } normalized end |
#concurrency_backend=(value) ⇒ Object
Replaces the concurrency backend for subsequently built runtimes.
231 232 233 |
# File 'lib/little_ghost/configuration.rb', line 231 def concurrency_backend=(value) concurrency_backend(value) end |
#configure ⇒ Object
Yields this builder for setup and returns the same instance.
138 139 140 141 |
# File 'lib/little_ghost/configuration.rb', line 138 def configure change_configuration { yield self } if block_given? self end |
#default_model(value = :__read__) ⇒ Object
Fallback logical role for the default resolver.
316 317 318 319 320 321 322 323 324 |
# File 'lib/little_ghost/configuration.rb', line 316 def default_model(value = :__read__) return configuration_values[:default_model] if value == :__read__ change_configuration do configuration_values[:default_model] = value.to_s reset_model_resolver end value.to_s end |
#default_model=(value) ⇒ Object
Replaces the fallback logical role and normalizes it to a String.
327 328 329 |
# File 'lib/little_ghost/configuration.rb', line 327 def default_model=(value) default_model(value) end |
#instrument(subscriber) ⇒ Object
Adds an Instrumentation::Subscriber to each new runtime and returns it.
520 521 522 523 524 525 526 527 528 |
# File 'lib/little_ghost/configuration.rb', line 520 def instrument(subscriber) ensure_configuration_open! unless subscriber.is_a?(Instrumentation::Subscriber) raise ArgumentError, "instrumentation subscriber must be a LittleGhost::Instrumentation::Subscriber" end change_configuration { configuration_values[:instrumentation_subscribers] << subscriber } subscriber end |
#load_file!(root: nil) ⇒ Object
:nodoc:
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 |
# File 'lib/little_ghost/configuration.rb', line 670 def load_file!(root: nil) # :nodoc: requested_root = canonical_root(root || self.root) FILE_LOAD_MUTEX.synchronize do (@configuration_file_mutex ||= Mutex.new).synchronize do if @configuration_file_root return self if @configuration_file_root == requested_root raise ConfigurationError, "configuration file is already loaded for #{@configuration_file_root}" end path = File.join(requested_root, "config/little_ghost.rb") load_configuration_file(path) if File.file?(path) @configuration_file_root = requested_root end end self end |
#log_events_to(destination = :__read__) ⇒ Object
:call-seq:
log_events_to() -> :stdout, :stderr, nil
log_events_to(destination) -> destination
Sends structured framework events to :stdout or :stderr. This setting
controls the process-wide Events console destination; the most recent
setting replaces it without changing other event listeners. By default,
events have no console destination. Passing nil disables console output.
The console listener redacts sensitive values and writes one JSON object
per line.
540 541 542 543 544 |
# File 'lib/little_ghost/configuration.rb', line 540 def log_events_to(destination = :__read__) return Events.console_output if destination == :__read__ change_configuration { Events.console_output = destination } end |
#log_events_to=(destination) ⇒ Object
Replaces the console destination for structured framework events.
547 548 549 |
# File 'lib/little_ghost/configuration.rb', line 547 def log_events_to=(destination) log_events_to(destination) end |
#model_resolver(value = :__read__) ⇒ Object
Installs a complete resolver override for subsequently built runtimes.
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
# File 'lib/little_ghost/configuration.rb', line 350 def model_resolver(value = :__read__) if value != :__read__ ensure_configuration_open! validate_model_resolver_class!(value) change_configuration do configuration_values[:model_resolver] = value @resolved_model_resolver = nil end return value end @model_resolver_mutex ||= Mutex.new @model_resolver_mutex.synchronize do @resolved_model_resolver ||= begin providers = resolved_providers credential_resolver = configuration_values[:provider_credentials] || providers&.method(:credentials) configured = configuration_values[:model_resolver] if configured validate_model_resolver_configuration! configured.new( providers:, provider_adapters: configuration_values[:provider_adapters], catalog_sources: configuration_values[:catalog_sources], credential_resolver: ) else profiles, file_default = resolved_models ModelResolver.new( providers:, profiles:, default_model: configuration_values.fetch(:default_model, file_default), provider_adapters: configuration_values[:provider_adapters], catalog_sources: configuration_values[:catalog_sources], credential_resolver: ) end end end end |
#model_resolver=(value) ⇒ Object
391 392 393 |
# File 'lib/little_ghost/configuration.rb', line 391 def model_resolver=(value) model_resolver(value) end |
#models(value = :__read__) ⇒ Object
Logical model profiles for the default resolver. Role names cannot contain a colon because that syntax identifies a canonical model target.
298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/little_ghost/configuration.rb', line 298 def models(value = :__read__) return configuration_values[:models] if value == :__read__ ensure_configuration_open! raise ArgumentError, "models must be a Hash" unless value.is_a?(Hash) change_configuration do configuration_values[:models] = value reset_model_resolver end value end |
#models=(value) ⇒ Object
Replaces logical model profiles for subsequently built runtimes.
311 312 313 |
# File 'lib/little_ghost/configuration.rb', line 311 def models=(value) models(value) end |
#models_path(value = :__read__) ⇒ Object
Model YAML path. The conventional path is optional; an explicitly set path must exist when a runtime is built.
342 |
# File 'lib/little_ghost/configuration.rb', line 342 def models_path(value = :__read__) = configuration_path(:models_path, "models.yml", value) |
#models_path=(value) ⇒ Object
Replaces the model YAML path for subsequently built runtimes.
345 346 347 |
# File 'lib/little_ghost/configuration.rb', line 345 def models_path=(value) models_path(value) end |
#name ⇒ Object
Replaces the service name attached to telemetry from new runtimes. :method: service_name= :call-seq:
service_name=(value) -> value
55 56 57 58 59 60 61 |
# File 'lib/little_ghost/configuration.rb', line 55 CONFIGURATION_KEYS.each do |name| define_method(name) do |value = :__read__| return configuration_values[name] if value == :__read__ change_configuration { configuration_values[name] = value } end end |
#prompt_paths ⇒ Object
Prompt lookup paths in precedence order. The Array is mutable until the shared Runtime is built.
626 |
# File 'lib/little_ghost/configuration.rb', line 626 def prompt_paths = configuration_values[:prompt_paths] |
#prompt_paths=(value) ⇒ Object
Replaces prompt lookup paths with value converted to an Array.
629 630 631 |
# File 'lib/little_ghost/configuration.rb', line 629 def prompt_paths=(value) change_configuration { configuration_values[:prompt_paths] = Array(value) } end |
#provider_adapter(name, callable = nil, &factory) ⇒ Object
Registers a provider adapter factory under name.
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/little_ghost/configuration.rb', line 396 def provider_adapter(name, callable = nil, &factory) ensure_configuration_open! implementation = factory || callable if implementation.is_a?(Class) unless implementation <= Providers::Base raise ArgumentError, "provider adapter class must inherit LittleGhost::Providers::Base" end elsif !implementation.respond_to?(:call) raise ArgumentError, "provider adapter must be a Providers::Base class or callable factory" end change_configuration do configuration_values[:provider_adapters][name.to_s] = implementation @resolved_model_resolver = nil end implementation end |
#provider_credentials(callable = nil, &resolver) ⇒ Object
Installs a trusted callable that returns credential options for a named provider connection when each executable model is constructed.
429 430 431 432 433 434 435 436 437 438 439 440 |
# File 'lib/little_ghost/configuration.rb', line 429 def provider_credentials(callable = nil, &resolver) value = resolver || callable return configuration_values[:provider_credentials] unless value ensure_configuration_open! raise ArgumentError, "provider credential resolver must be callable" unless value.respond_to?(:call) change_configuration do configuration_values[:provider_credentials] = value @resolved_model_resolver = nil end value end |
#providers(value = :__read__) ⇒ Object
Trusted provider connections for the default or custom resolver.
276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/little_ghost/configuration.rb', line 276 def providers(value = :__read__) return configuration_values[:providers] if value == :__read__ ensure_configuration_open! unless value.is_a?(Hash) || value.is_a?(Providers::Configuration) raise ArgumentError, "providers must be a Hash or LittleGhost::Providers::Configuration" end change_configuration do configuration_values[:providers] = value reset_model_resolver end value end |
#providers=(value) ⇒ Object
Replaces trusted provider connections for subsequently built runtimes.
292 293 294 |
# File 'lib/little_ghost/configuration.rb', line 292 def providers=(value) providers(value) end |
#providers_path(value = :__read__) ⇒ Object
Provider YAML path. The conventional path is optional; an explicitly set path must exist when a runtime is built.
333 |
# File 'lib/little_ghost/configuration.rb', line 333 def providers_path(value = :__read__) = configuration_path(:providers_path, "providers.yml", value) |
#providers_path=(value) ⇒ Object
Replaces the provider YAML path for subsequently built runtimes.
336 337 338 |
# File 'lib/little_ghost/configuration.rb', line 336 def providers_path=(value) providers_path(value) end |
#root(value = :__read__) ⇒ Object
:call-seq:
root() -> Pathname
root(path) -> Pathname
The resolved application root, defaulting to Dir.pwd.
Setting or reading an invalid root raises ConfigurationError. Symlinks are resolved so runtimes and lookup paths use the same canonical directory.
615 616 617 618 619 620 621 622 |
# File 'lib/little_ghost/configuration.rb', line 615 def root(value = :__read__) if value != :__read__ return change_configuration { configuration_values[:root] = canonical_root(value) } end configured = configuration_values[:root] configured ? canonical_root(configured) : inferred_root end |
#root=(value) ⇒ Object
Replaces the application root after resolving it to a stable real path.
515 516 517 |
# File 'lib/little_ghost/configuration.rb', line 515 def root=(value) root(value) end |
#runtime ⇒ Object
Returns the shared Runtime for this configuration, building it on first use. Once construction succeeds, the configuration is locked so every standalone entrypoint continues to use one stable application setup. The conventional configuration file may finish loading during construction; other writes are rejected. A failed build leaves the configuration editable for a later attempt.
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/little_ghost/configuration.rb', line 149 def runtime build_generation, build_context = @lifecycle_monitor.synchronize do loop do return @default_runtime if @default_runtime if @runtime_building if current_runtime_build_context.equal?(@runtime_build_context) raise ConfigurationError, "LittleGhost.runtime cannot be called while the shared Runtime is starting" end waiting_generation = @runtime_generation @runtime_condition.wait return @default_runtime if @default_runtime if @runtime_failure_generation == waiting_generation raise @runtime_failure end else sealed_values = freeze_configuration_copy(@configuration_values) @runtime_generation = @runtime_generation.to_i + 1 @runtime_building = true @runtime_build_context = Object.new @configuration_values = sealed_values break [@runtime_generation, @runtime_build_context] end end end ExecutionState.with(RUNTIME_BUILD_CONTEXT_KEY => build_context) do runtime_root = root load_file!(root: runtime_root) runtime_settings = settings(root: runtime_root) built = Runtime.new(configuration: self, settings: runtime_settings) @lifecycle_monitor.synchronize do configuration_values.freeze @default_runtime = built end built rescue => error editable_values = if @configuration_values.frozen? copy_configuration_value(@configuration_values) else @configuration_values end @lifecycle_monitor.synchronize do @configuration_values = editable_values @runtime_failure = error @runtime_failure_generation = build_generation end raise ensure @lifecycle_monitor.synchronize do @runtime_building = false @runtime_build_context = nil @runtime_condition.broadcast end end end |
#runtime_hook(hook_class) ⇒ Object
Adds a Runtime::Hook subclass to each new runtime and returns it.
552 553 554 555 556 557 558 559 560 |
# File 'lib/little_ghost/configuration.rb', line 552 def runtime_hook(hook_class) ensure_configuration_open! unless hook_class.is_a?(Class) && hook_class <= Runtime::Hook raise ArgumentError, "runtime_hook must be a LittleGhost::Runtime::Hook class" end change_configuration { configuration_values[:runtime_hooks] << hook_class } hook_class end |
#sandbox ⇒ Object
Sandbox declaration used for subsequently built runtimes.
267 268 269 270 |
# File 'lib/little_ghost/configuration.rb', line 267 def sandbox = configuration_values[:sandbox] # Default code-mode declaration for enabled Agents. The Hash may select an # +:engine+ and +:sandbox+, override +:limits+, and name Tools to keep in the # conversation with +:except+. |
#sandbox=(value) ⇒ Object
Selects the Sandbox provider instantiated around each run's workspace. LittleGhost does not fall back to unrestricted execution when an explicit backend is unavailable.
454 455 456 457 458 |
# File 'lib/little_ghost/configuration.rb', line 454 def sandbox=(value) change_configuration do @configuration_values[:sandbox] = component_declaration(value, Sandbox, :sandbox) end end |
#session_actor(value = :__read__, &resolver) ⇒ Object
:call-seq:
session_actor() -> callable, nil
session_actor(callable) -> callable
session_actor { |invocation| ... } -> callable
The callable that derives the persistence actor for each invocation.
Pass either a callable or a block. The configured resolver should use trusted authenticated identity in multi-tenant applications.
595 596 597 598 599 600 601 602 603 604 605 |
# File 'lib/little_ghost/configuration.rb', line 595 def session_actor(value = :__read__, &resolver) return configuration_values[:session_actor] if value == :__read__ && !resolver ensure_configuration_open! raise ArgumentError, "Provide a session actor resolver or a block, not both" if value != :__read__ && resolver configured = resolver || value raise ArgumentError, "session_actor must be callable" unless configured.respond_to?(:call) change_configuration { configuration_values[:session_actor] = configured } end |
#session_store ⇒ Object
Session-store declaration used for subsequently built runtimes.
273 |
# File 'lib/little_ghost/configuration.rb', line 273 def session_store = configuration_values[:session_store] |
#session_store=(value) ⇒ Object
Selects session persistence with a :provider and its constructor options.
The provider must be a SessionStore subclass. Runtime construction creates and owns the store instance.
475 476 477 478 479 480 481 482 483 484 485 486 487 |
# File 'lib/little_ghost/configuration.rb', line 475 def session_store=(value) ensure_configuration_open! unless value.is_a?(Hash) raise ArgumentError, "session_store must be a hash with a provider" end provider = value[:provider] change_configuration do @configuration_values[:session_store] = value.merge( provider: component_class(provider, SessionStore, :session_store) ) end end |
#settings(root: nil) ⇒ Object
:nodoc:
657 658 659 660 661 662 663 664 665 666 667 668 |
# File 'lib/little_ghost/configuration.rb', line 657 def settings(root: nil) # :nodoc: requested_root = root && canonical_root(root) values = configuration_values.dup values[:prompt_paths] = Array(values[:prompt_paths]).dup values[:skill_paths] = Array(values[:skill_paths]).dup values[:instrumentation_subscribers] = Array(values[:instrumentation_subscribers]).dup values[:runtime_hooks] = Array(values[:runtime_hooks]).dup values[:model_resolver] = model_resolver values[:default_model] = values[:model_resolver].default_model values[:root] = requested_root || values[:root] || self.root values end |
#skill_paths ⇒ Object
Skill lookup paths in precedence order. The Array is mutable until the shared Runtime is built.
635 |
# File 'lib/little_ghost/configuration.rb', line 635 def skill_paths = configuration_values[:skill_paths] |
#skill_paths=(value) ⇒ Object
Replaces skill lookup paths with value converted to an Array.
638 639 640 |
# File 'lib/little_ghost/configuration.rb', line 638 def skill_paths=(value) change_configuration { configuration_values[:skill_paths] = Array(value) } end |
#skill_resource_root ⇒ Object
Optional model-facing root used for skill locations and resources. The value may be an absolute process-visible path. A workspace://name reference must map to the configured skill path through a read-only file grant in each Run's Workspace and Sandbox. The application must not expose the same files through another writable bind mount.
648 |
# File 'lib/little_ghost/configuration.rb', line 648 def skill_resource_root = configuration_values[:skill_resource_root] |
#skill_resource_root=(value) ⇒ Object
Replaces and validates the skill resource root for new runtimes.
651 652 653 654 655 |
# File 'lib/little_ghost/configuration.rb', line 651 def skill_resource_root=(value) change_configuration do configuration_values[:skill_resource_root] = Skills::ResourceRoot.normalize(value) end end |
#workspace ⇒ Object
Workspace declaration used for subsequently built runtimes.
265 266 |
# File 'lib/little_ghost/configuration.rb', line 265 def workspace = configuration_values[:workspace] # Sandbox declaration used for subsequently built runtimes. |
#workspace=(value) ⇒ Object
Selects the Workspace provider instantiated for each run. A declaration
may be a registered provider symbol, callable, or a Hash containing a
:provider and constructor options.
445 446 447 448 449 |
# File 'lib/little_ghost/configuration.rb', line 445 def workspace=(value) change_configuration do @configuration_values[:workspace] = component_declaration(value, Workspace, :workspace) end end |