class LittleGhost::Configuration
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.
Public Class Methods
Source
# 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
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.
Public Instance Methods
Source
# 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
Looks up an arbitrary setting by symbol or string-compatible name.
Source
# 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
Adds or replaces an arbitrary setting.
Source
# 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
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.
# 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
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.
# File lib/little_ghost/configuration.rb, line 260 def blocking_pool_capacity=(value) blocking_pool_capacity(value) end
Sets the same process-wide worker limit as blocking_pool_capacity.
Source
# 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
Adds an explicit catalog source. Sources refresh only when callers invoke ModelResolver#refresh!.
Source
# File lib/little_ghost/configuration.rb, line 271 def code_mode = configuration_values[:code_mode]
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.
Source
# 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
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.
Source
# 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
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
Source
# File lib/little_ghost/configuration.rb, line 231 def concurrency_backend=(value) concurrency_backend(value) end
Replaces the concurrency backend for subsequently built runtimes.
Source
# File lib/little_ghost/configuration.rb, line 138 def configure change_configuration { yield self } if block_given? self end
Yields this builder for setup and returns the same instance.
# 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
Fallback logical role for the default resolver.
Source
# File lib/little_ghost/configuration.rb, line 327 def default_model=(value) default_model(value) end
Replaces the fallback logical role and normalizes it to a String.
Source
# 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
Adds an Instrumentation::Subscriber to each new runtime and returns it.
# File lib/little_ghost/configuration.rb, line 42
The request envelope class used to parse application payloads.
Source
# File lib/little_ghost/configuration.rb, line 65
Replaces the request envelope class for subsequently built runtimes.
# 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
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.
Source
# File lib/little_ghost/configuration.rb, line 547 def log_events_to=(destination) log_events_to(destination) end
Replaces the console destination for structured framework events.
# 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
Installs a complete resolver override for subsequently built runtimes.
# File lib/little_ghost/configuration.rb, line 71
Replaces the model resolver declaration for subsequently built runtimes.
Source
# 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
Logical model profiles for the default resolver. Role names cannot contain a colon because that syntax identifies a canonical model target.
Source
# File lib/little_ghost/configuration.rb, line 311 def models=(value) models(value) end
Replaces logical model profiles for subsequently built runtimes.
# File lib/little_ghost/configuration.rb, line 342 def models_path(value = :__read__) = configuration_path(:models_path, "models.yml", value)
Model YAML path. The conventional path is optional; an explicitly set path must exist when a runtime is built.
Source
# File lib/little_ghost/configuration.rb, line 345 def models_path=(value) models_path(value) end
Replaces the model YAML path for subsequently built runtimes.
Source
# File lib/little_ghost/configuration.rb, line 626 def prompt_paths = configuration_values[:prompt_paths]
Prompt lookup paths in precedence order. The Array is mutable until the shared Runtime is built.
Source
# File lib/little_ghost/configuration.rb, line 629 def prompt_paths=(value) change_configuration { configuration_values[:prompt_paths] = Array(value) } end
Replaces prompt lookup paths with value converted to an Array.
# 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
Registers a provider adapter factory under name.
# 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
Installs a trusted callable that returns credential options for a named provider connection when each executable model is constructed.
# 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
Trusted provider connections for the default or custom resolver.
Source
# File lib/little_ghost/configuration.rb, line 292 def providers=(value) providers(value) end
Replaces trusted provider connections for subsequently built runtimes.
# File lib/little_ghost/configuration.rb, line 333 def providers_path(value = :__read__) = configuration_path(:providers_path, "providers.yml", value)
Provider YAML path. The conventional path is optional; an explicitly set path must exist when a runtime is built.
Source
# File lib/little_ghost/configuration.rb, line 336 def providers_path=(value) providers_path(value) end
Replaces the provider YAML path for subsequently built runtimes.
# 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
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.
Source
# File lib/little_ghost/configuration.rb, line 515 def root=(value) root(value) end
Replaces the application root after resolving it to a stable real path.
Source
# 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
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.
Source
# 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
Adds a Runtime::Hook subclass to each new runtime and returns it.
Source
# File lib/little_ghost/configuration.rb, line 267 def sandbox = configuration_values[:sandbox]
Sandbox declaration used for subsequently built runtimes.
Source
# File lib/little_ghost/configuration.rb, line 454 def sandbox=(value) change_configuration do @configuration_values[:sandbox] = component_declaration(value, Sandbox, :sandbox) end end
Selects the Sandbox provider instantiated around each run’s workspace. LittleGhost does not fall back to unrestricted execution when an explicit backend is unavailable.
# 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
The low-cardinality service name attached to instrumentation.
Source
# File lib/little_ghost/configuration.rb, line 81 CONFIGURATION_KEYS.each do |name| define_method("#{name}=") { |value| public_send(name, value) } end
Replaces the service name attached to telemetry from new runtimes.
Source
# 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
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.
Source
# File lib/little_ghost/configuration.rb, line 273 def session_store = configuration_values[:session_store]
Session-store declaration used for subsequently built runtimes.
Source
# 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
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.
Source
# File lib/little_ghost/configuration.rb, line 635 def skill_paths = configuration_values[:skill_paths]
Skill lookup paths in precedence order. The Array is mutable until the shared Runtime is built.
Source
# File lib/little_ghost/configuration.rb, line 638 def skill_paths=(value) change_configuration { configuration_values[:skill_paths] = Array(value) } end
Replaces skill lookup paths with value converted to an Array.
Source
# File lib/little_ghost/configuration.rb, line 648 def skill_resource_root = configuration_values[:skill_resource_root]
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.
Source
# 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
Replaces and validates the skill resource root for new runtimes.
Source
# File lib/little_ghost/configuration.rb, line 265 def workspace = configuration_values[:workspace]
Workspace declaration used for subsequently built runtimes.
Source
# File lib/little_ghost/configuration.rb, line 445 def workspace=(value) change_configuration do @configuration_values[:workspace] = component_declaration(value, Workspace, :workspace) end end
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.