Class: LittleGhost::RunContext
- Inherits:
-
Object
- Object
- LittleGhost::RunContext
- Defined in:
- lib/little_ghost/run_context.rb
Overview
RunContext gives tools and workflows one place for shared state, cancellation, deadlines, checkpoints, and accumulated usage. It travels with work inside a run without becoming global process state.
Tools and workflows use it to share JSON-like state, check cancellation and deadlines, checkpoint messages, and accumulate usage. Access to framework-managed fields is thread-safe.
Instance Attribute Summary collapse
-
#agent_operation_id ⇒ Object
readonly
Active Agent operation identifier, after the context is bound.
-
#cancellation_token ⇒ Object
readonly
Token used to cooperatively stop the current work.
-
#conversation_id ⇒ Object
readonly
Durable subagent conversation identifier, when present.
-
#deadline ⇒ Object
readonly
Wall-clock deadline for the current work, when present.
-
#metadata ⇒ Object
readonly
Framework metadata attached to this context.
-
#state ⇒ Object
readonly
Mutable DataMap state supplied to this invocation.
Instance Method Summary collapse
-
#activate_interjection(metadata:, ids:) ⇒ Object
:nodoc:.
-
#bind_agent_operation_id(operation_id) ⇒ Object
:nodoc:.
-
#check! ⇒ Object
Raises LittleGhost::CancelledError or LittleGhost::DeadlineExceededError when execution should stop.
-
#checkpoint(messages) ⇒ Object
Sends
messagesand current state to the configured checkpoint callback. -
#initialize(state: {}, cancellation_token: Support::CancellationToken.new, deadline: nil, metadata: {}, checkpoint: nil, conversation_id: nil, interjection_metadata: nil, interjection_ids: []) ⇒ RunContext
constructor
Creates a context with optional checkpoint and interjection state.
-
#interjection_ids ⇒ Object
:nodoc:.
-
#interjection_metadata ⇒ Object
:nodoc:.
-
#record_usage(value) ⇒ Object
Adds
valueto accumulated model usage. -
#remaining_time(maximum = nil) ⇒ Object
Calculates seconds remaining before the deadline.
-
#structured_result ⇒ Object
Finds the latest validated structured result, if any.
-
#submit_structured_result(result) ⇒ Object
Stores a validated LittleGhost::StructuredResult and returns it.
-
#usage ⇒ Object
Takes a snapshot of accumulated usage.
Constructor Details
#initialize(state: {}, cancellation_token: Support::CancellationToken.new, deadline: nil, metadata: {}, checkpoint: nil, conversation_id: nil, interjection_metadata: nil, interjection_ids: []) ⇒ RunContext
Creates a context with optional checkpoint and interjection state.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/little_ghost/run_context.rb', line 31 def initialize( state: {}, cancellation_token: Support::CancellationToken.new, deadline: nil, metadata: {}, checkpoint: nil, conversation_id: nil, interjection_metadata: nil, interjection_ids: [] ) if conversation_id conversation_id = String(conversation_id) raise ArgumentError, "conversation_id cannot be empty" if conversation_id.empty? conversation_id = conversation_id.dup.freeze end @state = DataMap.new(state) @cancellation_token = cancellation_token @deadline = deadline @metadata = .freeze @checkpoint = checkpoint @conversation_id = conversation_id @usage = Usage.new @usage_mutex = Mutex.new @structured_result = nil @structured_result_mutex = Mutex.new @agent_operation_id = nil @agent_operation_id_mutex = Mutex.new @interjection_mutex = Mutex.new @interjection_metadata = &.to_h @interjection_ids = Array(interjection_ids).map { |id| String(id).dup.freeze }.freeze end |
Instance Attribute Details
#agent_operation_id ⇒ Object (readonly)
Active Agent operation identifier, after the context is bound.
26 27 28 |
# File 'lib/little_ghost/run_context.rb', line 26 def agent_operation_id @agent_operation_id end |
#cancellation_token ⇒ Object (readonly)
Token used to cooperatively stop the current work.
20 21 22 |
# File 'lib/little_ghost/run_context.rb', line 20 def cancellation_token @cancellation_token end |
#conversation_id ⇒ Object (readonly)
Durable subagent conversation identifier, when present.
28 29 30 |
# File 'lib/little_ghost/run_context.rb', line 28 def conversation_id @conversation_id end |
#deadline ⇒ Object (readonly)
Wall-clock deadline for the current work, when present.
22 23 24 |
# File 'lib/little_ghost/run_context.rb', line 22 def deadline @deadline end |
#metadata ⇒ Object (readonly)
Framework metadata attached to this context.
24 25 26 |
# File 'lib/little_ghost/run_context.rb', line 24 def @metadata end |
#state ⇒ Object (readonly)
Mutable DataMap state supplied to this invocation. A top-level Run starts with restored Session state merged with current Invocation context; child Assemblies may receive copied, mapped, or empty state. Application code must synchronize mutations when parallel Tools share this map, or use exclusive Tools. String and Symbol keys address the same value; persisted snapshots use canonical String keys.
18 19 20 |
# File 'lib/little_ghost/run_context.rb', line 18 def state @state end |
Instance Method Details
#activate_interjection(metadata:, ids:) ⇒ Object
:nodoc:
123 124 125 126 127 128 129 130 |
# File 'lib/little_ghost/run_context.rb', line 123 def activate_interjection(metadata:, ids:) # :nodoc: value = &.to_h values = Array(ids).map { |id| String(id).dup.freeze }.freeze @interjection_mutex.synchronize do @interjection_metadata = value @interjection_ids = values end end |
#bind_agent_operation_id(operation_id) ⇒ Object
:nodoc:
132 133 134 135 136 137 138 139 140 |
# File 'lib/little_ghost/run_context.rb', line 132 def bind_agent_operation_id(operation_id) # :nodoc: @agent_operation_id_mutex.synchronize do if @agent_operation_id && @agent_operation_id != operation_id raise Error, "run context is already bound to an agent operation" end @agent_operation_id ||= operation_id end end |
#check! ⇒ Object
Raises LittleGhost::CancelledError or LittleGhost::DeadlineExceededError when execution should stop.
65 66 67 68 |
# File 'lib/little_ghost/run_context.rb', line 65 def check! cancellation_token.raise_if_cancelled! raise DeadlineExceededError, "The run deadline was reached" if deadline && Time.now >= deadline end |
#checkpoint(messages) ⇒ Object
Sends messages and current state to the configured checkpoint callback.
With no checkpoint callback, this method does nothing and returns nil.
72 73 74 75 76 77 78 79 80 |
# File 'lib/little_ghost/run_context.rb', line 72 def checkpoint() return unless @checkpoint if agent_operation_id @checkpoint.call(messages:, state:, parent_operation_id: agent_operation_id) else @checkpoint.call(messages:, state:) end end |
#interjection_ids ⇒ Object
:nodoc:
119 120 121 |
# File 'lib/little_ghost/run_context.rb', line 119 def interjection_ids # :nodoc: @interjection_mutex.synchronize { @interjection_ids } end |
#interjection_metadata ⇒ Object
:nodoc:
115 116 117 |
# File 'lib/little_ghost/run_context.rb', line 115 def # :nodoc: @interjection_mutex.synchronize { @interjection_metadata } end |
#record_usage(value) ⇒ Object
Adds value to accumulated model usage.
83 84 85 |
# File 'lib/little_ghost/run_context.rb', line 83 def record_usage(value) @usage_mutex.synchronize { @usage += value } end |
#remaining_time(maximum = nil) ⇒ Object
Calculates seconds remaining before the deadline.
When maximum is provided, the result is capped at that value. With no
deadline, returns maximum.
96 97 98 99 100 101 102 |
# File 'lib/little_ghost/run_context.rb', line 96 def remaining_time(maximum = nil) check! return maximum unless deadline remaining = deadline - Time.now maximum ? [remaining, maximum].min : remaining end |
#structured_result ⇒ Object
Finds the latest validated structured result, if any.
111 112 113 |
# File 'lib/little_ghost/run_context.rb', line 111 def structured_result @structured_result_mutex.synchronize { @structured_result } end |
#submit_structured_result(result) ⇒ Object
Stores a validated LittleGhost::StructuredResult and returns it.
105 106 107 108 |
# File 'lib/little_ghost/run_context.rb', line 105 def submit_structured_result(result) @structured_result_mutex.synchronize { @structured_result = result } result end |
#usage ⇒ Object
Takes a snapshot of accumulated usage.
88 89 90 |
# File 'lib/little_ghost/run_context.rb', line 88 def usage @usage_mutex.synchronize { @usage } end |