smith-agents 0.4.5 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +264 -0
  3. data/README.md +191 -4
  4. data/docs/CONFIGURATION.md +4 -1
  5. data/docs/PATTERNS.md +7 -0
  6. data/docs/PERSISTENCE.md +347 -25
  7. data/lib/smith/agent/lifecycle.rb +19 -10
  8. data/lib/smith/agent/registry/execution_binding_capture.rb +26 -0
  9. data/lib/smith/agent/registry/mutation_boundary.rb +29 -0
  10. data/lib/smith/agent/registry.rb +8 -0
  11. data/lib/smith/agent.rb +37 -2
  12. data/lib/smith/budget/amount_contract.rb +67 -0
  13. data/lib/smith/budget/amount_representation.rb +43 -0
  14. data/lib/smith/budget/decimal_context.rb +18 -0
  15. data/lib/smith/budget/ledger.rb +110 -18
  16. data/lib/smith/budget/ledger_publication.rb +60 -0
  17. data/lib/smith/budget/ledger_state.rb +21 -0
  18. data/lib/smith/budget/ledger_state_transition.rb +72 -0
  19. data/lib/smith/budget/public_state_validator.rb +25 -0
  20. data/lib/smith/budget/reservation.rb +20 -0
  21. data/lib/smith/budget/reservation_contract.rb +34 -0
  22. data/lib/smith/context/observation_masking.rb +3 -1
  23. data/lib/smith/context/state_injection.rb +1 -1
  24. data/lib/smith/doctor/checks/persistence_capabilities.rb +18 -4
  25. data/lib/smith/error.rb +5 -0
  26. data/lib/smith/errors.rb +10 -0
  27. data/lib/smith/exponential_backoff.rb +128 -0
  28. data/lib/smith/persistence_adapters/active_record_exact_predicate.rb +43 -0
  29. data/lib/smith/persistence_adapters/active_record_exact_store.rb +62 -0
  30. data/lib/smith/persistence_adapters/active_record_exact_write.rb +40 -0
  31. data/lib/smith/persistence_adapters/active_record_store.rb +7 -4
  32. data/lib/smith/persistence_adapters/cache_store.rb +1 -0
  33. data/lib/smith/persistence_adapters/memory.rb +16 -1
  34. data/lib/smith/persistence_adapters/redis_client_access.rb +38 -0
  35. data/lib/smith/persistence_adapters/redis_exact_write.rb +44 -0
  36. data/lib/smith/persistence_adapters/redis_store.rb +28 -11
  37. data/lib/smith/persistence_adapters/retry.rb +22 -10
  38. data/lib/smith/persistence_adapters.rb +21 -18
  39. data/lib/smith/persistence_payload_conflict.rb +12 -0
  40. data/lib/smith/tool/budget_enforcement.rb +2 -2
  41. data/lib/smith/types.rb +1 -0
  42. data/lib/smith/version.rb +2 -1
  43. data/lib/smith/workflow/branch_env.rb +1 -1
  44. data/lib/smith/workflow/budget_integration.rb +21 -11
  45. data/lib/smith/workflow/composite/branch.rb +93 -0
  46. data/lib/smith/workflow/composite/branch_budget_contract.rb +41 -0
  47. data/lib/smith/workflow/composite/branch_contract.rb +102 -0
  48. data/lib/smith/workflow/composite/branch_execution.rb +124 -0
  49. data/lib/smith/workflow/composite/branch_failure.rb +91 -0
  50. data/lib/smith/workflow/composite/branch_outcome.rb +108 -0
  51. data/lib/smith/workflow/composite/budget_allocator.rb +78 -0
  52. data/lib/smith/workflow/composite/budget_math.rb +51 -0
  53. data/lib/smith/workflow/composite/contract.rb +100 -0
  54. data/lib/smith/workflow/composite/effects.rb +140 -0
  55. data/lib/smith/workflow/composite/effects_application.rb +36 -0
  56. data/lib/smith/workflow/composite/effects_baseline.rb +36 -0
  57. data/lib/smith/workflow/composite/effects_preflight.rb +102 -0
  58. data/lib/smith/workflow/composite/encoded_value_budget.rb +36 -0
  59. data/lib/smith/workflow/composite/enums.rb +27 -0
  60. data/lib/smith/workflow/composite/error.rb +54 -0
  61. data/lib/smith/workflow/composite/error_evidence.rb +61 -0
  62. data/lib/smith/workflow/composite/execution_contract.rb +73 -0
  63. data/lib/smith/workflow/composite/fanout_branch_contract.rb +61 -0
  64. data/lib/smith/workflow/composite/input.rb +53 -0
  65. data/lib/smith/workflow/composite/outcome_accumulator.rb +131 -0
  66. data/lib/smith/workflow/composite/outcome_set.rb +23 -0
  67. data/lib/smith/workflow/composite/payload.rb +128 -0
  68. data/lib/smith/workflow/composite/payload_digest.rb +28 -0
  69. data/lib/smith/workflow/composite/plan.rb +130 -0
  70. data/lib/smith/workflow/composite/plan_integrity.rb +52 -0
  71. data/lib/smith/workflow/composite/planner.rb +53 -0
  72. data/lib/smith/workflow/composite/preparation.rb +27 -0
  73. data/lib/smith/workflow/composite/reducer.rb +133 -0
  74. data/lib/smith/workflow/composite/reduction.rb +31 -0
  75. data/lib/smith/workflow/composite/value_budget.rb +90 -0
  76. data/lib/smith/workflow/composite_branch_execution_authorization.rb +52 -0
  77. data/lib/smith/workflow/deadline_enforcement.rb +22 -5
  78. data/lib/smith/workflow/definition_identity/class_methods.rb +48 -0
  79. data/lib/smith/workflow/definition_identity.rb +25 -0
  80. data/lib/smith/workflow/deterministic_step.rb +2 -2
  81. data/lib/smith/workflow/dsl.rb +73 -5
  82. data/lib/smith/workflow/durability.rb +1 -1
  83. data/lib/smith/workflow/evaluator_optimizer.rb +7 -11
  84. data/lib/smith/workflow/execution.rb +28 -30
  85. data/lib/smith/workflow/execution_binding_resolution.rb +16 -0
  86. data/lib/smith/workflow/execution_result_snapshot.rb +118 -0
  87. data/lib/smith/workflow/fanout_execution.rb +20 -19
  88. data/lib/smith/workflow/graph/diagnostic.rb +27 -1
  89. data/lib/smith/workflow/graph/diagnostic_path.rb +24 -0
  90. data/lib/smith/workflow/graph/execution_successors.rb +65 -0
  91. data/lib/smith/workflow/graph/identifier_projection.rb +13 -0
  92. data/lib/smith/workflow/graph/metrics.rb +1 -3
  93. data/lib/smith/workflow/graph/nested_readiness_diagnostics.rb +15 -16
  94. data/lib/smith/workflow/graph/optimization_contract.rb +2 -2
  95. data/lib/smith/workflow/graph/orchestration_contract.rb +3 -3
  96. data/lib/smith/workflow/graph/reachability.rb +19 -31
  97. data/lib/smith/workflow/graph/reachability_diagnostics.rb +17 -1
  98. data/lib/smith/workflow/graph/retry_policy_diagnostic.rb +36 -0
  99. data/lib/smith/workflow/graph/runtime_binding_diagnostics.rb +2 -2
  100. data/lib/smith/workflow/graph/runtime_readiness.rb +3 -44
  101. data/lib/smith/workflow/graph/runtime_readiness_metrics.rb +2 -2
  102. data/lib/smith/workflow/graph/runtime_readiness_report_builder.rb +47 -0
  103. data/lib/smith/workflow/graph/runtime_readiness_traversal.rb +108 -0
  104. data/lib/smith/workflow/graph/state_diagnostics.rb +2 -2
  105. data/lib/smith/workflow/graph/transition_contract.rb +47 -0
  106. data/lib/smith/workflow/graph/transition_contract_attributes.rb +73 -0
  107. data/lib/smith/workflow/graph/transition_contract_configurations.rb +100 -0
  108. data/lib/smith/workflow/graph/transition_diagnostics.rb +54 -12
  109. data/lib/smith/workflow/graph/transition_optimization_configuration.rb +62 -0
  110. data/lib/smith/workflow/graph/transition_snapshot.rb +4 -1
  111. data/lib/smith/workflow/graph/validator.rb +1 -1
  112. data/lib/smith/workflow/graph.rb +62 -4
  113. data/lib/smith/workflow/guardrail_integration.rb +23 -9
  114. data/lib/smith/workflow/identifier.rb +24 -0
  115. data/lib/smith/workflow/message_admission.rb +40 -0
  116. data/lib/smith/workflow/message_admission_boundary.rb +22 -0
  117. data/lib/smith/workflow/message_batch.rb +60 -0
  118. data/lib/smith/workflow/message_value_normalizer.rb +134 -0
  119. data/lib/smith/workflow/nested_execution.rb +10 -0
  120. data/lib/smith/workflow/orchestrator_worker.rb +3 -7
  121. data/lib/smith/workflow/parallel/cancellation_signal.rb +14 -5
  122. data/lib/smith/workflow/parallel/execution_context.rb +113 -0
  123. data/lib/smith/workflow/parallel/nested_execution.rb +124 -0
  124. data/lib/smith/workflow/parallel/root_execution.rb +91 -0
  125. data/lib/smith/workflow/parallel.rb +19 -22
  126. data/lib/smith/workflow/parallel_agent_binding.rb +24 -0
  127. data/lib/smith/workflow/parallel_execution.rb +46 -14
  128. data/lib/smith/workflow/persistence.rb +37 -8
  129. data/lib/smith/workflow/prepared_branch_execution.rb +31 -0
  130. data/lib/smith/workflow/prepared_step.rb +122 -0
  131. data/lib/smith/workflow/prepared_step_dispatch.rb +88 -0
  132. data/lib/smith/workflow/prepared_step_execution_authorization.rb +101 -0
  133. data/lib/smith/workflow/prepared_step_execution_result.rb +49 -0
  134. data/lib/smith/workflow/prepared_step_execution_scope.rb +111 -0
  135. data/lib/smith/workflow/prepared_step_recovery.rb +38 -0
  136. data/lib/smith/workflow/process_local.rb +33 -0
  137. data/lib/smith/workflow/retry_execution.rb +20 -11
  138. data/lib/smith/workflow/split_step_persistence/boundary.rb +35 -22
  139. data/lib/smith/workflow/split_step_persistence/boundary_reset.rb +50 -0
  140. data/lib/smith/workflow/split_step_persistence/canonical_payload_digest.rb +55 -0
  141. data/lib/smith/workflow/split_step_persistence/checkpoint.rb +3 -5
  142. data/lib/smith/workflow/split_step_persistence/composite_branch_authorization.rb +99 -0
  143. data/lib/smith/workflow/split_step_persistence/composite_branch_effects.rb +41 -0
  144. data/lib/smith/workflow/split_step_persistence/composite_branch_execution.rb +95 -0
  145. data/lib/smith/workflow/split_step_persistence/composite_branch_outcome.rb +36 -0
  146. data/lib/smith/workflow/split_step_persistence/composite_execution.rb +39 -0
  147. data/lib/smith/workflow/split_step_persistence/composite_preparation.rb +57 -0
  148. data/lib/smith/workflow/split_step_persistence/composite_reduction_execution.rb +122 -0
  149. data/lib/smith/workflow/split_step_persistence/definition_boundary.rb +19 -0
  150. data/lib/smith/workflow/split_step_persistence/dispatch_boundary.rb +16 -0
  151. data/lib/smith/workflow/split_step_persistence/dispatch_claim.rb +118 -0
  152. data/lib/smith/workflow/split_step_persistence/dispatch_confirmation.rb +70 -0
  153. data/lib/smith/workflow/split_step_persistence/dispatch_verification.rb +35 -0
  154. data/lib/smith/workflow/split_step_persistence/execution.rb +20 -64
  155. data/lib/smith/workflow/split_step_persistence/execution_authorization.rb +109 -0
  156. data/lib/smith/workflow/split_step_persistence/execution_authorization_issuance.rb +57 -0
  157. data/lib/smith/workflow/split_step_persistence/execution_binding_collector.rb +95 -0
  158. data/lib/smith/workflow/split_step_persistence/execution_binding_snapshot.rb +109 -0
  159. data/lib/smith/workflow/split_step_persistence/execution_lifecycle.rb +96 -0
  160. data/lib/smith/workflow/split_step_persistence/execution_result_capture.rb +48 -0
  161. data/lib/smith/workflow/split_step_persistence/execution_verification.rb +77 -0
  162. data/lib/smith/workflow/split_step_persistence/execution_workflow_snapshot.rb +77 -0
  163. data/lib/smith/workflow/split_step_persistence/inheritance.rb +3 -1
  164. data/lib/smith/workflow/split_step_persistence/payloads.rb +7 -3
  165. data/lib/smith/workflow/split_step_persistence/preparation.rb +30 -2
  166. data/lib/smith/workflow/split_step_persistence/preparation_claim.rb +38 -12
  167. data/lib/smith/workflow/split_step_persistence/preparation_payload.rb +25 -0
  168. data/lib/smith/workflow/split_step_persistence/preparation_recovery.rb +10 -2
  169. data/lib/smith/workflow/split_step_persistence/recovery.rb +125 -0
  170. data/lib/smith/workflow/split_step_persistence/recovery_boundary.rb +56 -0
  171. data/lib/smith/workflow/split_step_persistence/recovery_class_methods.rb +14 -0
  172. data/lib/smith/workflow/split_step_persistence/replace_exact_signature.rb +46 -0
  173. data/lib/smith/workflow/split_step_persistence/restart_safe_adapter.rb +42 -0
  174. data/lib/smith/workflow/split_step_persistence/subclass_boundary.rb +66 -0
  175. data/lib/smith/workflow/split_step_persistence/transaction_identity.rb +45 -0
  176. data/lib/smith/workflow/split_step_persistence.rb +50 -0
  177. data/lib/smith/workflow/step_completion.rb +31 -0
  178. data/lib/smith/workflow/step_context.rb +46 -0
  179. data/lib/smith/workflow/string_snapshot.rb +25 -0
  180. data/lib/smith/workflow/thread_context_snapshot.rb +103 -0
  181. data/lib/smith/workflow/transition.rb +137 -133
  182. data/lib/smith/workflow/transition_actionability.rb +22 -0
  183. data/lib/smith/workflow.rb +64 -18
  184. data/lib/smith.rb +44 -2
  185. data/sig/smith.rbs +1 -0
  186. metadata +155 -19
@@ -4,17 +4,46 @@ require "digest"
4
4
  require "json"
5
5
  require "securerandom"
6
6
 
7
+ require_relative "prepared_step"
8
+ require_relative "prepared_step_dispatch"
9
+ require_relative "prepared_step_execution_authorization"
10
+ require_relative "prepared_step_execution_result"
11
+ require_relative "prepared_step_recovery"
7
12
  require_relative "split_step_persistence/subclass_boundary"
8
13
  require_relative "split_step_persistence/inheritance"
14
+ require_relative "split_step_persistence/recovery_class_methods"
9
15
  require_relative "split_step_persistence/transition_contract_structured_values"
10
16
  require_relative "split_step_persistence/transition_contract_signature"
11
17
  require_relative "split_step_persistence/transition_contract_freezer"
12
18
  require_relative "split_step_persistence/transition_contract"
19
+ require_relative "split_step_persistence/transaction_identity"
20
+ require_relative "split_step_persistence/canonical_payload_digest"
21
+ require_relative "split_step_persistence/definition_boundary"
13
22
  require_relative "split_step_persistence/boundary"
23
+ require_relative "split_step_persistence/boundary_reset"
14
24
  require_relative "split_step_persistence/state_snapshot"
15
25
  require_relative "split_step_persistence/preparation_claim"
16
26
  require_relative "split_step_persistence/preparation_recovery"
17
27
  require_relative "split_step_persistence/preparation"
28
+ require_relative "split_step_persistence/restart_safe_adapter"
29
+ require_relative "split_step_persistence/recovery"
30
+ require_relative "split_step_persistence/recovery_boundary"
31
+ require_relative "split_step_persistence/preparation_payload"
32
+ require_relative "split_step_persistence/dispatch_boundary"
33
+ require_relative "split_step_persistence/dispatch_claim"
34
+ require_relative "split_step_persistence/dispatch_verification"
35
+ require_relative "split_step_persistence/dispatch_confirmation"
36
+ require_relative "split_step_persistence/execution_verification"
37
+ require_relative "split_step_persistence/execution_binding_snapshot"
38
+ require_relative "split_step_persistence/execution_authorization"
39
+ require_relative "split_step_persistence/execution_authorization_issuance"
40
+ require_relative "split_step_persistence/execution_result_capture"
41
+ require_relative "split_step_persistence/execution_lifecycle"
42
+ require_relative "split_step_persistence/composite_preparation"
43
+ require_relative "split_step_persistence/composite_branch_authorization"
44
+ require_relative "split_step_persistence/composite_branch_execution"
45
+ require_relative "split_step_persistence/composite_reduction_execution"
46
+ require_relative "split_step_persistence/composite_execution"
18
47
  require_relative "split_step_persistence/execution"
19
48
  require_relative "split_step_persistence/checkpoint_state"
20
49
  require_relative "split_step_persistence/checkpoint"
@@ -27,13 +56,34 @@ module Smith
27
56
 
28
57
  def self.prepended(base)
29
58
  base.singleton_class.prepend(Inheritance)
59
+ base.extend(RecoveryClassMethods)
30
60
  end
31
61
 
32
62
  include Boundary
63
+ include BoundaryReset
64
+ include DefinitionBoundary
33
65
  include StateSnapshot
34
66
  include PreparationClaim
35
67
  include PreparationRecovery
36
68
  include Preparation
69
+ include RestartSafeAdapter
70
+ include Recovery
71
+ include RecoveryBoundary
72
+ include PreparationPayload
73
+ include DispatchBoundary
74
+ include DispatchClaim
75
+ include DispatchVerification
76
+ include DispatchConfirmation
77
+ include ExecutionVerification
78
+ include ExecutionAuthorization
79
+ include ExecutionAuthorizationIssuance
80
+ include ExecutionResultCapture
81
+ include ExecutionLifecycle
82
+ include CompositePreparation
83
+ include CompositeBranchAuthorization
84
+ include CompositeBranchExecution
85
+ include CompositeReductionExecution
86
+ include CompositeExecution
37
87
  include Execution
38
88
  include CheckpointState
39
89
  include Checkpoint
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smith
4
+ class Workflow
5
+ module StepCompletion
6
+ private
7
+
8
+ def complete_step(transition, output)
9
+ step = { transition: transition.name, from: transition.from, to: transition.to, output: output }
10
+ result = SplitStepPersistence
11
+ .instance_method(:prepare_split_step_execution_result)
12
+ .bind_call(self, step)
13
+ StepCompletion.instance_method(:append_accepted_output).bind_call(self, output)
14
+ SplitStepPersistence
15
+ .instance_method(:commit_split_step_execution_result!)
16
+ .bind_call(self, result)
17
+ @state = transition.to
18
+ @next_transition_name = @router_next_transition || transition.success_transition
19
+ @router_next_transition = nil
20
+ emit_step_completed(transition, output)
21
+ step
22
+ end
23
+
24
+ def append_accepted_output(output)
25
+ return unless @session_messages && !output.nil?
26
+
27
+ @session_messages << { role: :assistant, content: output }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "thread_context_snapshot"
4
+
5
+ module Smith
6
+ class Workflow
7
+ module StepContext
8
+ private
9
+
10
+ def with_step_context(transition, &block)
11
+ ThreadContextSnapshot.new.around do
12
+ setup_step_context
13
+ Thread.handle_interrupt(Object => :immediate, &block)
14
+ rescue StandardError => e
15
+ @outcome = nil
16
+ GuardrailIntegration.instance_method(:handle_step_failure).bind_call(self, transition, e)
17
+ ensure
18
+ teardown_step_context
19
+ end
20
+ end
21
+
22
+ def within_raw_step_context(&block)
23
+ ThreadContextSnapshot.new.around do
24
+ setup_step_context
25
+ Thread.handle_interrupt(Object => :immediate, &block)
26
+ ensure
27
+ teardown_step_context
28
+ end
29
+ end
30
+
31
+ def setup_step_context
32
+ Tool.current_deadline = wall_clock_deadline
33
+ Tool.current_ledger = @ledger
34
+ Tool.current_tool_result_collector = tool_result_collector
35
+ end
36
+
37
+ def teardown_step_context
38
+ Tool.current_guardrails = nil
39
+ Tool.current_deadline = nil
40
+ Tool.current_ledger = nil
41
+ Tool.current_tool_result_collector = nil
42
+ Smith.scoped_artifacts = nil
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smith
4
+ class Workflow
5
+ class StringSnapshot
6
+ BYTESIZE = String.instance_method(:bytesize)
7
+ FREEZE = String.instance_method(:freeze)
8
+ INITIALIZE_COPY = String.instance_method(:initialize_copy)
9
+ private_constant :BYTESIZE, :FREEZE, :INITIALIZE_COPY
10
+
11
+ class << self
12
+ def bytesize(value)
13
+ BYTESIZE.bind_call(value)
14
+ end
15
+
16
+ def copy(value, freeze: false)
17
+ String.allocate.tap do |copy|
18
+ INITIALIZE_COPY.bind_call(copy, value)
19
+ FREEZE.bind_call(copy) if freeze
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry-initializer"
4
+
5
+ require_relative "process_local"
6
+
7
+ module Smith
8
+ class Workflow
9
+ class ThreadContextSnapshot
10
+ extend Dry::Initializer
11
+ include ProcessLocal
12
+
13
+ TOOL_ATTRIBUTES = %i[
14
+ current_guardrails
15
+ current_deadline
16
+ current_ledger
17
+ current_tool_call_allowance
18
+ current_tool_result_collector
19
+ ].freeze
20
+ THREAD_KEYS = %i[
21
+ smith_call_deadline
22
+ smith_call_ledger
23
+ smith_failed_agent_results
24
+ smith_last_agent_result
25
+ smith_parallel_agent_binding
26
+ ].freeze
27
+
28
+ option :tool_attributes, default: proc { TOOL_ATTRIBUTES }
29
+ option :thread_keys, default: proc { THREAD_KEYS }
30
+ option :scoped_artifacts, default: proc { true }
31
+
32
+ def initialize(...)
33
+ super
34
+ @tool_attributes = tool_attributes.dup.freeze
35
+ @thread_keys = thread_keys.dup.freeze
36
+ validate_selection!
37
+ @tool_values = capture_tool_values
38
+ @thread_values = capture_thread_values
39
+ @artifact_store = Smith.scoped_artifacts if scoped_artifacts
40
+ @process_id = Process.pid
41
+ @thread = Thread.current
42
+ @fiber = Fiber.current
43
+ @restored = false
44
+ end
45
+
46
+ def restore!
47
+ ensure_owner!
48
+ Thread.handle_interrupt(Object => :never) { restore_context! }
49
+ self
50
+ end
51
+
52
+ def around
53
+ ensure_owner!
54
+ Thread.handle_interrupt(Object => :never) do
55
+ raise WorkflowError, "thread context snapshot has already been restored" if @restored
56
+
57
+ begin
58
+ yield
59
+ ensure
60
+ restore_context!
61
+ end
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def restore_context!
68
+ raise WorkflowError, "thread context snapshot has already been restored" if @restored
69
+
70
+ @tool_values.each { |attribute, value| Tool.public_send("#{attribute}=", value) }
71
+ @thread_values.each { |key, value| Thread.current[key] = value }
72
+ Smith.scoped_artifacts = @artifact_store if scoped_artifacts
73
+ @restored = true
74
+ end
75
+
76
+ def capture_tool_values
77
+ tool_attributes.to_h { |attribute| [attribute, Tool.public_send(attribute)] }.freeze
78
+ end
79
+
80
+ def capture_thread_values
81
+ thread_keys.to_h { |key| [key, Thread.current[key]] }.freeze
82
+ end
83
+
84
+ def ensure_owner!
85
+ owner = @process_id == Process.pid && @thread.equal?(Thread.current) && @fiber.equal?(Fiber.current)
86
+ return if owner
87
+
88
+ raise WorkflowError, "thread context snapshot belongs to another process, thread, or fiber"
89
+ end
90
+
91
+ def validate_selection!
92
+ unless (tool_attributes - TOOL_ATTRIBUTES).empty?
93
+ raise ArgumentError, "thread context snapshot contains unsupported tool attributes"
94
+ end
95
+ return if (thread_keys - THREAD_KEYS).empty?
96
+
97
+ raise ArgumentError, "thread context snapshot contains unsupported thread keys"
98
+ end
99
+ end
100
+
101
+ private_constant :ThreadContextSnapshot
102
+ end
103
+ end