Class: LittleGhost::Configuration

Inherits:
Object
  • Object
show all
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

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!.

Raises:

  • (ArgumentError)


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_modeObject

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

#configureObject

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.

Raises:

  • (ArgumentError)


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

#nameObject

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_pathsObject

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.

Raises:

  • (ArgumentError)


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

#runtimeObject

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

#sandboxObject

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.

Raises:

  • (ArgumentError)


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_storeObject

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_pathsObject

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_rootObject

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

#workspaceObject

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