Module: Smith::Tool::ScopedContext
- Included in:
- Smith::Tool
- Defined in:
- lib/smith/tool/scoped_context.rb
Constant Summary collapse
- CONTEXT_KEYS =
{ current_guardrails: :smith_tool_guardrails, current_deadline: :smith_tool_deadline, current_ledger: :smith_tool_ledger, current_tool_call_allowance: :smith_tool_call_allowance, current_tool_execution_tracker: :smith_tool_execution_tracker, current_tool_dispatch_claim: :smith_tool_dispatch_claim, current_tool_dispatch_start_handler: :smith_tool_dispatch_start_handler, current_tool_result_collector: :smith_tool_result_collector, current_invocation_context: :smith_tool_invocation_context, current_invocation_batch_admitter: :smith_tool_invocation_batch_admitter, current_invocation_failure_handler: :smith_tool_invocation_failure_handler, current_invocation_sequence: :smith_tool_invocation_sequence, current_invocation: :smith_tool_invocation }.freeze
Class Method Summary collapse
Instance Method Summary collapse
- #with_call_budget(budget, on_exhaustion: :raise, &block) ⇒ Object
- #with_invocation_context(value, invocation_sequence: InvocationSequence.new, batch_admitter: nil, failure_handler: nil, &block) ⇒ Object
Class Method Details
.around(values, &block) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/smith/tool/scoped_context.rb', line 43 def self.around(values, &block) raise ArgumentError, "block required" unless block validate!(values) previous = capture Thread.handle_interrupt(Object => :never) do install(values) begin Thread.handle_interrupt(Object => :immediate, &block) ensure install(previous) end end end |
.capture ⇒ Object
39 40 41 |
# File 'lib/smith/tool/scoped_context.rb', line 39 def self.capture CONTEXT_KEYS.to_h { |reader, key| [reader, Thread.current[key]] }.freeze end |
Instance Method Details
#with_call_budget(budget, on_exhaustion: :raise, &block) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/smith/tool/scoped_context.rb', line 81 def with_call_budget(budget, on_exhaustion: :raise, &block) raise ArgumentError, "block required" unless block previous = current_tool_call_allowance if previous && !previous.is_a?(CallAllowance) raise ArgumentError, "a scoped tool call budget cannot nest under a legacy Hash tool call allowance" end allowance = previous ? previous.scope(budget, on_exhaustion:) : CallAllowance.new(budget, on_exhaustion:) Thread.handle_interrupt(Object => :never) do self.current_tool_call_allowance = allowance begin Thread.handle_interrupt(Object => :immediate, &block) ensure self.current_tool_call_allowance = previous end end end |
#with_invocation_context(value, invocation_sequence: InvocationSequence.new, batch_admitter: nil, failure_handler: nil, &block) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/smith/tool/scoped_context.rb', line 58 def with_invocation_context(value, invocation_sequence: InvocationSequence.new, batch_admitter: nil, failure_handler: nil, &block) raise ArgumentError, "block required" unless block unless invocation_sequence.is_a?(InvocationSequence) raise ArgumentError, "invocation sequence must be a Smith::Tool::InvocationSequence" end validate_callback!(batch_admitter, "batch admitter") validate_callback!(failure_handler, "failure handler") if batch_admitter && !failure_handler raise ArgumentError, "invocation failure handler is required when a batch admitter is configured" end values = ScopedContext.capture.merge( current_invocation_context: value, current_invocation_batch_admitter: batch_admitter, current_invocation_failure_handler: failure_handler, current_invocation_sequence: invocation_sequence, current_invocation: nil ).freeze ScopedContext.around(values, &block) end |