phronomy 0.26.0 → 0.27.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -0
- data/README.md +4 -0
- data/VERIFY.sh +27 -27
- data/benchmark/bench_agent_invoke.rb +26 -22
- data/benchmark/bench_context_assembler.rb +4 -5
- data/docs/architecture/agent-chat-and-state-ownership.md +147 -0
- data/docs/architecture/agent-configuration-and-tool-binding.md +139 -0
- data/docs/architecture/agent-context.md +4 -2
- data/docs/architecture/agent-transition-ownership.md +89 -0
- data/docs/architecture/before-llm-input.md +6 -0
- data/docs/architecture/context-management.md +30 -0
- data/docs/architecture/context-preparation-steps.md +90 -0
- data/docs/architecture/entry-action-and-team-wording.md +72 -0
- data/docs/architecture/execution-metadata-and-values.md +80 -0
- data/docs/architecture/generator-verifier-ownership.md +111 -0
- data/docs/architecture/multi-agent-handoff.md +8 -2
- data/docs/architecture/persistence-refactoring-plan.md +50 -0
- data/docs/architecture/persistence.md +27 -4
- data/docs/architecture/refactoring-closure.md +334 -0
- data/docs/architecture/remaining-refactoring-plan.md +374 -0
- data/docs/architecture/rubyllm-2-token-ownership.md +82 -0
- data/docs/architecture/tool-schema-recording-gap.md +50 -0
- data/docs/architecture/tracing.md +1 -1
- data/docs/architecture/workflow-terminal-ownership-design.md +104 -0
- data/docs/architecture.md +209 -0
- data/docs/decisions/014-unified-persistence-durable-state.md +11 -0
- data/docs/decisions/024-event-loop-single-writer-agent-runtime.md +5 -1
- data/docs/decisions/025-process-local-agent-ownership-and-runtime-admission.md +13 -3
- data/docs/decisions/026-workflow-runtime-admission-and-durable-terminal-barrier.md +5 -1
- data/docs/decisions/030-agent-handoff-domain-and-durable-responsibility.md +5 -0
- data/docs/decisions/031-durable-multi-agent-coordination.md +5 -0
- data/docs/decisions/032-storage-backend-composition.md +80 -0
- data/docs/decisions/033-domain-persistence-ownership.md +79 -0
- data/docs/decisions/034-handoff-runner-coordination-ownership.md +76 -0
- data/docs/decisions/035-tool-executor-capability-ownership.md +68 -0
- data/docs/decisions/036-context-contract-ownership.md +86 -0
- data/docs/decisions/037-common-definition-ownership.md +62 -0
- data/docs/decisions/038-responsibility-based-source-layout.md +131 -0
- data/docs/decisions/039-runtime-configuration-lifecycle-ownership.md +74 -0
- data/docs/decisions/040-configuration-default-composition.md +94 -0
- data/docs/decisions/041-feature-owned-identity-registries.md +100 -0
- data/docs/decisions/042-feature-owned-execution-state.md +106 -0
- data/docs/decisions/043-storage-execution-constraint-notifications.md +75 -0
- data/docs/decisions/044-agent-default-and-one-shot-composition.md +106 -0
- data/docs/decisions/045-worker-input-restriction-ownership.md +100 -0
- data/docs/decisions/046-agent-responsibility-layout-and-shared-records.md +110 -0
- data/docs/decisions/047-recovered-execution-continuation-contract.md +116 -0
- data/docs/decisions/048-dispatch-preparation-worker-ownership.md +120 -0
- data/docs/decisions/049-initial-preparation-worker-ownership.md +111 -0
- data/docs/decisions/050-approval-resume-snapshot-and-commit-ownership.md +98 -0
- data/docs/decisions/051-execution-outcome-worker-ownership.md +151 -0
- data/docs/decisions/052-tool-invocation-restoration-ownership.md +92 -0
- data/docs/decisions/053-shared-state-coordination-ownership.md +71 -0
- data/docs/decisions/054-workflow-terminal-save-single-owner.md +76 -0
- data/docs/decisions/055-terminal-observer-failure-settlement.md +60 -0
- data/docs/decisions/056-workflow-terminal-policy-ownership.md +87 -0
- data/docs/decisions/057-storage-transaction-boundaries.md +73 -0
- data/docs/decisions/058-neutral-storage-primitives.md +78 -0
- data/docs/decisions/README.md +35 -6
- data/docs/design/durable-semantic-coordination/IMPLEMENTATION_DESIGN_V2.md +6 -0
- data/docs/design/durable-semantic-coordination/IMPLEMENTATION_REPORT.md +6 -0
- data/docs/features.md +9 -3
- data/docs/getting-started.md +4 -4
- data/docs/migrations/0.15.md +5 -0
- data/docs/migrations/durable-semantic-coordination-v2.md +6 -0
- data/docs/migrations/handoff-runner-multi-agent.md +35 -0
- data/docs/migrations/neutral-storage-spi.md +43 -0
- data/docs/migrations/parallel-tool-chat-removal.md +49 -0
- data/docs/migrations/shared-state-multi-agent.md +44 -0
- data/docs/migrations/storage-backend-composition.md +117 -0
- data/docs/migrations/storage-transaction-boundaries.md +74 -0
- data/docs/persistence-backends.md +162 -204
- data/docs/runtime-and-concurrency.md +117 -32
- data/lib/phronomy/agent/api/agent.rb +17 -0
- data/lib/phronomy/agent/async_event_api.rb +2 -2
- data/lib/phronomy/agent/base.rb +51 -241
- data/lib/phronomy/{agent.rb → agent/composition/run_once.rb} +4 -13
- data/lib/phronomy/agent/context/capability/base.rb +67 -26
- data/lib/phronomy/agent/context/capability/tool_executor.rb +62 -0
- data/lib/phronomy/agent/{context_assembler.rb → context_assembly/context_assembler.rb} +143 -88
- data/lib/phronomy/agent/{context_importer.rb → context_assembly/context_importer.rb} +2 -2
- data/lib/phronomy/agent/{ruby_llm_materializer.rb → context_assembly/ruby_llm_materializer.rb} +4 -7
- data/lib/phronomy/agent/context_assembly/runtime_chat_builder.rb +36 -0
- data/lib/phronomy/agent/context_assembly/saved_context_reader.rb +53 -0
- data/lib/phronomy/agent/context_assembly/state_writer.rb +165 -0
- data/lib/phronomy/agent/context_assembly/token_budget_resolver.rb +22 -0
- data/lib/phronomy/agent/{context_plan.rb → context_contract/context_plan.rb} +1 -1
- data/lib/phronomy/agent/{context_policy_input.rb → context_contract/context_policy_input.rb} +6 -6
- data/lib/phronomy/agent/{llm_input_build_context.rb → context_contract/llm_input_build_context.rb} +1 -1
- data/lib/phronomy/agent/{llm_input_manifest.rb → context_contract/llm_input_manifest.rb} +20 -20
- data/lib/phronomy/agent/{llm_input_patch.rb → context_contract/llm_input_patch.rb} +2 -2
- data/lib/phronomy/agent/{agent_execution.rb → execution/agent_execution.rb} +8 -4
- data/lib/phronomy/agent/{agent_invocation.rb → execution/agent_invocation.rb} +8 -13
- data/lib/phronomy/agent/{agent_invocation_session_builder.rb → execution/agent_invocation_session_builder.rb} +19 -95
- data/lib/phronomy/agent/execution/approval_resume_commit.rb +108 -0
- data/lib/phronomy/agent/execution/dispatch_preparation.rb +305 -0
- data/lib/phronomy/agent/{exact_execution.rb → execution/exact_execution.rb} +9 -10
- data/lib/phronomy/agent/{execution_cancellation.rb → execution/execution_cancellation.rb} +2 -3
- data/lib/phronomy/agent/execution/execution_coordinator.rb +1925 -0
- data/lib/phronomy/agent/execution/execution_failure.rb +30 -0
- data/lib/phronomy/agent/execution/execution_metadata.rb +53 -0
- data/lib/phronomy/agent/execution/execution_outcome_committer.rb +344 -0
- data/lib/phronomy/agent/execution/execution_registry.rb +459 -0
- data/lib/phronomy/agent/execution/execution_session_runner.rb +118 -0
- data/lib/phronomy/agent/execution/initial_preparation.rb +421 -0
- data/lib/phronomy/agent/execution/invocation_transitions.rb +86 -0
- data/lib/phronomy/agent/{phase_machine_builder.rb → execution/phase_machine_builder.rb} +20 -71
- data/lib/phronomy/agent/{provider_call_outcome.rb → execution/provider_call_outcome.rb} +9 -9
- data/lib/phronomy/agent/execution/runtime_record_encoder.rb +210 -0
- data/lib/phronomy/agent/{handoff_context.rb → handoff/handoff_context.rb} +2 -2
- data/lib/phronomy/agent/handoff/handoff_execution_coordinator.rb +15 -0
- data/lib/phronomy/agent/handoff/handoff_outcome_committer.rb +131 -0
- data/lib/phronomy/agent/{handoff_state.rb → handoff/handoff_state.rb} +1 -1
- data/lib/phronomy/agent/{journal_projection.rb → journal/journal_projection.rb} +4 -0
- data/lib/phronomy/agent/{journal_record.rb → journal/journal_record.rb} +3 -3
- data/lib/phronomy/agent/{llm_call_record.rb → journal/llm_call_record.rb} +2 -2
- data/lib/phronomy/agent/{agent_root.rb → lifecycle/agent_root.rb} +6 -2
- data/lib/phronomy/agent/lifecycle/default_persistence.rb +29 -0
- data/lib/phronomy/{engine/runtime/agent_ownership_registry.rb → agent/lifecycle/ownership_registry.rb} +24 -10
- data/lib/phronomy/{agent_already_exists_error.rb → agent/lifecycle_contract/agent_already_exists_error.rb} +2 -0
- data/lib/phronomy/{agent_busy_error.rb → agent/lifecycle_contract/agent_busy_error.rb} +2 -0
- data/lib/phronomy/{agent_purged_error.rb → agent/lifecycle_contract/agent_purged_error.rb} +2 -0
- data/lib/phronomy/agent/lifecycle_contract/handoff_error.rb +7 -0
- data/lib/phronomy/{stream_callback_error.rb → agent/lifecycle_contract/stream_callback_error.rb} +2 -0
- data/lib/phronomy/agent/persistence/agent_repository.rb +61 -0
- data/lib/phronomy/agent/persistence/codec.rb +358 -0
- data/lib/phronomy/agent/persistence/execution_repository.rb +108 -0
- data/lib/phronomy/agent/persistence/handoff_state_repository.rb +58 -0
- data/lib/phronomy/agent/persistence/journal_repository.rb +54 -0
- data/lib/phronomy/agent/persistence/queries.rb +61 -0
- data/lib/phronomy/agent/persistence/storage_schema.rb +24 -0
- data/lib/phronomy/agent/persistence/watermark.rb +27 -0
- data/lib/phronomy/agent/recovery/invocation_restorer.rb +132 -0
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/continuation.rb +21 -45
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/installation.rb +32 -37
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/resolution.rb +37 -40
- data/lib/phronomy/agent/{recovery_coordinator.rb → recovery/recovery_coordinator.rb} +6 -10
- data/lib/phronomy/agent/recovery/recovery_support.rb +227 -0
- data/lib/phronomy/agent/selection/candidate.rb +1 -1
- data/lib/phronomy/agent/{approval_evaluation_request.rb → tool_execution/approval_evaluation_request.rb} +1 -12
- data/lib/phronomy/agent/{tool_approval_request.rb → tool_execution/tool_approval_request.rb} +1 -10
- data/lib/phronomy/agent/tool_execution/tool_binding.rb +90 -0
- data/lib/phronomy/agent/{tool_call_intercepted.rb → tool_execution/tool_call_intercepted.rb} +2 -2
- data/lib/phronomy/agent/{tool_definition_set.rb → tool_execution/tool_definition_set.rb} +9 -4
- data/lib/phronomy/agent/{tool_invocation.rb → tool_execution/tool_invocation.rb} +69 -34
- data/lib/phronomy/common/configuration_error.rb +7 -0
- data/lib/phronomy/common/error.rb +5 -0
- data/lib/phronomy/{agent → common/values}/immutable.rb +9 -1
- data/lib/phronomy/common/values/serializable.rb +32 -0
- data/lib/phronomy/{configuration.rb → configuration/configuration.rb} +14 -5
- data/lib/phronomy/configuration/global_configuration.rb +26 -0
- data/lib/phronomy/content_store/storage_schema.rb +11 -0
- data/lib/phronomy/content_store/stored_contents.rb +43 -0
- data/lib/phronomy/engine/backpressure_error.rb +7 -0
- data/lib/phronomy/{blocking.rb → engine/blocking.rb} +1 -1
- data/lib/phronomy/engine/cancellation_error.rb +7 -0
- data/lib/phronomy/engine/concurrency/cancellation_token.rb +4 -0
- data/lib/phronomy/engine/concurrency/offload_pool.rb +4 -0
- data/lib/phronomy/engine/concurrency/operation_binding.rb +1 -1
- data/lib/phronomy/engine/concurrency/worker_input_restricted.rb +14 -0
- data/lib/phronomy/engine/event_loop.rb +158 -624
- data/lib/phronomy/engine/event_loop_reentrancy_error.rb +8 -0
- data/lib/phronomy/{execution.rb → engine/execution.rb} +0 -7
- data/lib/phronomy/{execution_cancellation_error.rb → engine/execution_cancellation_error.rb} +2 -0
- data/lib/phronomy/engine/execution_receiver.rb +65 -0
- data/lib/phronomy/{execution_timeout_error.rb → engine/execution_timeout_error.rb} +2 -0
- data/lib/phronomy/engine/fsm_protocol.rb +14 -0
- data/lib/phronomy/engine/fsm_session.rb +35 -28
- data/lib/phronomy/{invalid_async_entry_action_error.rb → engine/invalid_async_entry_action_error.rb} +2 -0
- data/lib/phronomy/{invalid_async_transition_action_error.rb → engine/invalid_async_transition_action_error.rb} +2 -0
- data/lib/phronomy/{invalid_async_workflow_action_error.rb → engine/invalid_async_workflow_action_error.rb} +2 -0
- data/lib/phronomy/engine/pool_shutdown_error.rb +7 -0
- data/lib/phronomy/engine/recursion_limit_error.rb +7 -0
- data/lib/phronomy/engine/runtime.rb +80 -84
- data/lib/phronomy/engine/runtime_shutdown_error.rb +7 -0
- data/lib/phronomy/engine/runtime_shutdown_reentrancy_error.rb +7 -0
- data/lib/phronomy/engine/scheduler_reentrancy_error.rb +9 -0
- data/lib/phronomy/engine/task_result.rb +4 -0
- data/lib/phronomy/engine/timeout_error.rb +7 -0
- data/lib/phronomy/filter/contract/filter_block_error.rb +14 -0
- data/lib/phronomy/generation/generator_verifier/agent_result_receiver.rb +89 -0
- data/lib/phronomy/generation/generator_verifier/pipeline_state.rb +57 -0
- data/lib/phronomy/generation/generator_verifier/workflow_builder.rb +112 -0
- data/lib/phronomy/generation/generator_verifier.rb +118 -0
- data/lib/phronomy/generation/low_confidence_error.rb +14 -0
- data/lib/phronomy/llm_context_window/token_budget.rb +6 -7
- data/lib/phronomy/llm_contract/authentication_error.rb +7 -0
- data/lib/phronomy/{context_budget_exceeded_error.rb → llm_contract/context_budget_exceeded_error.rb} +2 -0
- data/lib/phronomy/llm_contract/context_length_error.rb +7 -0
- data/lib/phronomy/llm_contract/rate_limit_error.rb +7 -0
- data/lib/phronomy/{token_usage.rb → llm_contract/token_usage.rb} +2 -2
- data/lib/phronomy/llm_contract/transport_error.rb +7 -0
- data/lib/phronomy/multi_agent/admission_registry.rb +22 -2
- data/lib/phronomy/multi_agent/durable_subagent_coordinator.rb +5 -5
- data/lib/phronomy/{agent → multi_agent}/handoff_runner.rb +18 -17
- data/lib/phronomy/multi_agent/orchestrator.rb +2 -2
- data/lib/phronomy/multi_agent/persistence/codec.rb +55 -0
- data/lib/phronomy/multi_agent/persistence/queries.rb +30 -0
- data/lib/phronomy/multi_agent/persistence/team_execution_repository.rb +108 -0
- data/lib/phronomy/multi_agent/persistence/team_repository.rb +61 -0
- data/lib/phronomy/{agent → multi_agent}/shared_state.rb +56 -39
- data/lib/phronomy/multi_agent/storage_contract/team_storage_schema.rb +15 -0
- data/lib/phronomy/multi_agent/team_coordinator.rb +21 -18
- data/lib/phronomy/multi_agent/team_execution.rb +1 -1
- data/lib/phronomy/{engine/runtime → multi_agent}/team_ownership_registry.rb +14 -4
- data/lib/phronomy/multi_agent/team_root.rb +1 -1
- data/lib/phronomy/output_parser/contract/parse_error.rb +7 -0
- data/lib/phronomy/persistence/api/persistence.rb +140 -0
- data/lib/phronomy/persistence/migration/initial_format_migration.rb +19 -19
- data/lib/phronomy/persistence_composition/repositories.rb +77 -0
- data/lib/phronomy/persistence_composition/storage_schema.rb +24 -0
- data/lib/phronomy/{execution_rehydration_required_error.rb → recovery/execution_rehydration_required_error.rb} +2 -0
- data/lib/phronomy/{recovery.rb → recovery/recovery.rb} +1 -1
- data/lib/phronomy/runtime_composition/agent_defaults.rb +7 -0
- data/lib/phronomy/runtime_composition/configuration_defaults.rb +9 -0
- data/lib/phronomy/runtime_composition/global_runtime.rb +19 -0
- data/lib/phronomy/storage/backend.rb +101 -0
- data/lib/phronomy/storage/backends/in_memory.rb +157 -0
- data/lib/phronomy/storage/blob_conflict_error.rb +10 -0
- data/lib/phronomy/storage/blobs.rb +31 -0
- data/lib/phronomy/storage/condition.rb +25 -0
- data/lib/phronomy/storage/condition_failed_error.rb +16 -0
- data/lib/phronomy/storage/conflict_error.rb +9 -0
- data/lib/phronomy/{persistence → storage}/durable_record.rb +12 -12
- data/lib/phronomy/storage/entry.rb +33 -0
- data/lib/phronomy/storage/guard_ref.rb +13 -0
- data/lib/phronomy/storage/not_found_error.rb +9 -0
- data/lib/phronomy/storage/record_codec.rb +177 -0
- data/lib/phronomy/storage/records.rb +61 -0
- data/lib/phronomy/storage/resource.rb +126 -0
- data/lib/phronomy/storage/scope.rb +25 -0
- data/lib/phronomy/storage/serialization_error.rb +9 -0
- data/lib/phronomy/storage/streams.rb +44 -0
- data/lib/phronomy/storage/transaction_error.rb +10 -0
- data/lib/phronomy/storage/unique_constraint_error.rb +17 -0
- data/lib/phronomy/storage/unsupported_backend_error.rb +9 -0
- data/lib/phronomy/storage/validation.rb +53 -0
- data/lib/phronomy/storage/view.rb +131 -0
- data/lib/phronomy/testing/persistence_contract/a_content_store.rb +1 -1
- data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +4 -4
- data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +10 -7
- data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +2 -2
- data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +6 -6
- data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +6 -6
- data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +8 -8
- data/lib/phronomy/testing/persistence_contract/neutral_storage_primitives.rb +263 -0
- data/lib/phronomy/testing/persistence_contract/storage_transaction_boundaries.rb +123 -0
- data/lib/phronomy/testing/persistence_contract.rb +4 -0
- data/lib/phronomy/tool/contract/tool_error.rb +7 -0
- data/lib/phronomy/tools/agent.rb +1 -1
- data/lib/phronomy/version.rb +1 -1
- data/lib/phronomy/{workflow.rb → workflow/execution/workflow.rb} +8 -6
- data/lib/phronomy/{workflow_context.rb → workflow/execution/workflow_context.rb} +4 -0
- data/lib/phronomy/workflow/execution/workflow_context_ownership_error.rb +7 -0
- data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +188 -0
- data/lib/phronomy/{workflow_runner.rb → workflow/execution/workflow_runner.rb} +122 -71
- data/lib/phronomy/workflow/execution/workflow_terminal_policy.rb +40 -0
- data/lib/phronomy/workflow/persistence/codec.rb +153 -0
- data/lib/phronomy/workflow/persistence/state_repository.rb +57 -0
- data/lib/phronomy/workflow/phase_machine_builder.rb +2 -2
- data/lib/phronomy/workflow/storage_contract/workflow_storage_schema.rb +9 -0
- data/lib/phronomy.rb +52 -94
- data/scripts/api_snapshot.rb +1 -1
- data/scripts/storage_spi_snapshot.rb +36 -0
- data/sig/phronomy/agent.rbs +0 -1
- data/sig/phronomy/execution_receiver.rbs +34 -0
- data/sig/phronomy/handoff.rbs +4 -2
- data/sig/phronomy/multi_agent.rbs +18 -0
- data/sig/phronomy/persistence.rbs +7 -91
- data/sig/phronomy/storage.rbs +174 -0
- data/sig/phronomy/tool.rbs +10 -1
- metadata +230 -99
- data/lib/phronomy/agent/execution_coordinator.rb +0 -3151
- data/lib/phronomy/agent/handoff_execution_coordinator.rb +0 -143
- data/lib/phronomy/agent/recovery_support.rb +0 -504
- data/lib/phronomy/agent/token_budget_resolver.rb +0 -70
- data/lib/phronomy/agent/tool_executor.rb +0 -55
- data/lib/phronomy/generator_verifier.rb +0 -369
- data/lib/phronomy/invalid_context_budget_configuration_error.rb +0 -8
- data/lib/phronomy/multi_agent/parallel_tool_chat.rb +0 -116
- data/lib/phronomy/persistence/durable_codec.rb +0 -706
- data/lib/phronomy/persistence/in_memory.rb +0 -690
- data/lib/phronomy/persistence/repository_facades.rb +0 -535
- data/lib/phronomy/persistence.rb +0 -276
- data/lib/phronomy/ruby_llm_patches.rb +0 -24
- data/lib/phronomy/workflow_recovery.rb +0 -123
- /data/lib/phronomy/agent/{context_candidate_resolver.rb → context_assembly/context_candidate_resolver.rb} +0 -0
- /data/lib/phronomy/agent/{context_policy_input_builder.rb → context_assembly/context_policy_input_builder.rb} +0 -0
- /data/lib/phronomy/agent/{context_plan_validator.rb → context_contract/context_plan_validator.rb} +0 -0
- /data/lib/phronomy/agent/{context_policy.rb → context_contract/context_policy.rb} +0 -0
- /data/lib/phronomy/agent/{llm_operation_result.rb → execution/llm_operation_result.rb} +0 -0
- /data/lib/phronomy/agent/{handoff.rb → handoff/handoff.rb} +0 -0
- /data/lib/phronomy/agent/{handoff_capability_factory.rb → handoff/handoff_capability_factory.rb} +0 -0
- /data/lib/phronomy/agent/{handoff_policy.rb → handoff/handoff_policy.rb} +0 -0
- /data/lib/phronomy/agent/{handoff_projection.rb → handoff/handoff_projection.rb} +0 -0
- /data/lib/phronomy/agent/{handoff_request.rb → handoff/handoff_request.rb} +0 -0
- /data/lib/phronomy/agent/{tool_invocation_session_builder.rb → tool_execution/tool_invocation_session_builder.rb} +0 -0
- /data/lib/phronomy/{canonical_json.rb → common/canonical_json.rb} +0 -0
- /data/lib/phronomy/{diagnostics.rb → engine/diagnostics.rb} +0 -0
- /data/lib/phronomy/{event.rb → engine/event.rb} +0 -0
- /data/lib/phronomy/{invocation_context.rb → engine/invocation_context.rb} +0 -0
- /data/lib/phronomy/{metrics.rb → engine/metrics.rb} +0 -0
- /data/lib/phronomy/{runnable.rb → engine/runnable.rb} +0 -0
|
@@ -14,10 +14,10 @@ module Phronomy
|
|
|
14
14
|
"name" => tool.name.to_s,
|
|
15
15
|
"description" => tool.description.to_s,
|
|
16
16
|
"parameters_schema" => normalize(
|
|
17
|
-
tool.
|
|
17
|
+
tool.parameters_schema
|
|
18
18
|
),
|
|
19
19
|
"provider_options" => normalize(
|
|
20
|
-
tool.
|
|
20
|
+
tool.provider_options
|
|
21
21
|
)
|
|
22
22
|
}
|
|
23
23
|
end.freeze
|
|
@@ -47,13 +47,13 @@ module Phronomy
|
|
|
47
47
|
|
|
48
48
|
def initialize(runtime_tools:, definitions:)
|
|
49
49
|
@runtime_tools = Array(runtime_tools).freeze
|
|
50
|
-
@definitions = Immutable.copy(definitions)
|
|
50
|
+
@definitions = Phronomy::Values::Immutable.copy(definitions)
|
|
51
51
|
validate_unique_names!
|
|
52
52
|
freeze
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def select_definitions(expected_definitions)
|
|
56
|
-
expected = Immutable.copy(Array(expected_definitions))
|
|
56
|
+
expected = Phronomy::Values::Immutable.copy(Array(expected_definitions))
|
|
57
57
|
current_by_name = definitions.each_with_index.to_h do |definition, index|
|
|
58
58
|
[definition.fetch("name"), [definition, runtime_tools.fetch(index)]]
|
|
59
59
|
end
|
|
@@ -70,6 +70,11 @@ module Phronomy
|
|
|
70
70
|
raise Phronomy::ConfigurationError,
|
|
71
71
|
"ContextPolicy selected Tool not present in current Agent configuration: #{name}"
|
|
72
72
|
end
|
|
73
|
+
if definition["parameters_schema"] == {} && current_definition["parameters_schema"] != {}
|
|
74
|
+
raise Phronomy::ConfigurationError,
|
|
75
|
+
"Saved Tool definition lacks a verifiable parameters_schema: #{name}; " \
|
|
76
|
+
"finish this in-flight execution on its original version before upgrading"
|
|
77
|
+
end
|
|
73
78
|
unless Phronomy::CanonicalJSON.dump(current_definition) ==
|
|
74
79
|
Phronomy::CanonicalJSON.dump(definition)
|
|
75
80
|
raise Phronomy::ConfigurationError,
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../../engine/concurrency/worker_input_restricted"
|
|
4
|
+
|
|
5
|
+
require "digest"
|
|
3
6
|
require "securerandom"
|
|
4
7
|
|
|
5
8
|
module Phronomy
|
|
6
9
|
module Agent
|
|
7
10
|
class ToolInvocation
|
|
11
|
+
include Phronomy::Concurrency::WorkerInputRestricted
|
|
12
|
+
|
|
8
13
|
AuthorizationOutcome = Data.define(
|
|
9
14
|
:tool_invocation_id, :decision, :facts, :reason, :error, :cancelled
|
|
10
15
|
) do
|
|
@@ -74,6 +79,20 @@ module Phronomy
|
|
|
74
79
|
:origin,
|
|
75
80
|
:metadata
|
|
76
81
|
|
|
82
|
+
# Stable identity used both before dispatch and when rebuilding facts.
|
|
83
|
+
# This does not construct, authorize, or execute a Tool invocation.
|
|
84
|
+
# @api private
|
|
85
|
+
def self.semantic_id(execution_id:, llm_call_id:, tool_call_id:, tool_name:)
|
|
86
|
+
source = [
|
|
87
|
+
"tool_invocation",
|
|
88
|
+
execution_id.to_s,
|
|
89
|
+
llm_call_id.to_s,
|
|
90
|
+
tool_call_id.to_s,
|
|
91
|
+
tool_name.to_s
|
|
92
|
+
].join("\0")
|
|
93
|
+
"tool_invocation-#{Digest::SHA256.hexdigest(source)}".freeze
|
|
94
|
+
end
|
|
95
|
+
|
|
77
96
|
def self.missing(
|
|
78
97
|
execution_id:,
|
|
79
98
|
agent:,
|
|
@@ -135,6 +154,16 @@ module Phronomy
|
|
|
135
154
|
@phase = phase
|
|
136
155
|
end
|
|
137
156
|
|
|
157
|
+
# Restores a newly constructed invocation from materialized saved facts.
|
|
158
|
+
# Recovery owns snapshot decoding and identity matching. This operation
|
|
159
|
+
# owns state application; it neither dispatches nor reevaluates approval.
|
|
160
|
+
# @api private
|
|
161
|
+
def restore_state!(status:, result: nil, approval_item: nil)
|
|
162
|
+
restore_saved_state!(status, result)
|
|
163
|
+
restore_approval_evidence!(approval_item)
|
|
164
|
+
self
|
|
165
|
+
end
|
|
166
|
+
|
|
138
167
|
def handle_fsm_event(event)
|
|
139
168
|
case event.type
|
|
140
169
|
when :authorization_completed
|
|
@@ -215,7 +244,7 @@ module Phronomy
|
|
|
215
244
|
cancellation_token: @config[:cancellation_token],
|
|
216
245
|
on_full: :raise
|
|
217
246
|
) { evaluator.send(:evaluate_authorization_command, command) }
|
|
218
|
-
runtime.event_loop.supervise_agent_operation(@execution_id, operation)
|
|
247
|
+
Phronomy::Agent::ExecutionRegistry.for(runtime.event_loop).supervise_agent_operation(@execution_id, operation)
|
|
219
248
|
operation.on_complete do |outcome, error|
|
|
220
249
|
callback.call(
|
|
221
250
|
error ? evaluator.send(:authorization_failure_result, tool_invocation_id, error) : outcome
|
|
@@ -259,7 +288,7 @@ module Phronomy
|
|
|
259
288
|
raise Phronomy::ToolError,
|
|
260
289
|
"Tool #{@tool.class.name}#call_async must return a completion handle"
|
|
261
290
|
end
|
|
262
|
-
runtime.event_loop.supervise_agent_operation(@execution_id, operation)
|
|
291
|
+
Phronomy::Agent::ExecutionRegistry.for(runtime.event_loop).supervise_agent_operation(@execution_id, operation)
|
|
263
292
|
|
|
264
293
|
evaluator = self.class
|
|
265
294
|
tool_invocation_id = @id.to_s.freeze
|
|
@@ -332,7 +361,7 @@ module Phronomy
|
|
|
332
361
|
end
|
|
333
362
|
|
|
334
363
|
def tool_schema
|
|
335
|
-
@tool&.respond_to?(:
|
|
364
|
+
@tool&.respond_to?(:parameters_schema) ? @tool.parameters_schema : {}
|
|
336
365
|
end
|
|
337
366
|
|
|
338
367
|
def display_arguments
|
|
@@ -345,6 +374,40 @@ module Phronomy
|
|
|
345
374
|
|
|
346
375
|
private
|
|
347
376
|
|
|
377
|
+
def restore_saved_state!(status, result)
|
|
378
|
+
case status
|
|
379
|
+
when :awaiting_approval
|
|
380
|
+
validate! unless terminal?
|
|
381
|
+
@final_decision = :require_approval
|
|
382
|
+
mark_awaiting_approval!
|
|
383
|
+
when :authorized
|
|
384
|
+
validate! unless terminal?
|
|
385
|
+
@final_decision = :allow
|
|
386
|
+
mark_authorized!
|
|
387
|
+
when :completed
|
|
388
|
+
@result = result
|
|
389
|
+
@status = :completed
|
|
390
|
+
when :rejected
|
|
391
|
+
mark_rejected!
|
|
392
|
+
when :failed
|
|
393
|
+
mark_framework_failed!(
|
|
394
|
+
Phronomy::ToolError.new("durably restored Tool preflight failure")
|
|
395
|
+
)
|
|
396
|
+
when :cancelled
|
|
397
|
+
mark_cancelled!
|
|
398
|
+
else
|
|
399
|
+
raise Phronomy::ExecutionRehydrationRequiredError,
|
|
400
|
+
"unsupported durable Tool snapshot state: #{status.inspect}"
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def restore_approval_evidence!(item)
|
|
405
|
+
return unless item
|
|
406
|
+
|
|
407
|
+
@facts = immutable_copy(item.facts)
|
|
408
|
+
@authorization_reason = item.reason
|
|
409
|
+
end
|
|
410
|
+
|
|
348
411
|
def authorization_command
|
|
349
412
|
definition = @agent.class.agent_definition
|
|
350
413
|
|
|
@@ -490,24 +553,7 @@ module Phronomy
|
|
|
490
553
|
private_class_method :immutable_command_copy
|
|
491
554
|
|
|
492
555
|
def self.phronomy_managed_live_domain_object?(value)
|
|
493
|
-
value.is_a?(Phronomy::
|
|
494
|
-
value.is_a?(Phronomy::Agent::AgentRoot) ||
|
|
495
|
-
value.is_a?(Phronomy::Agent::AgentExecution) ||
|
|
496
|
-
value.is_a?(Phronomy::Agent::AgentInvocation) ||
|
|
497
|
-
value.is_a?(Phronomy::Agent::ToolInvocation) ||
|
|
498
|
-
value.is_a?(Phronomy::Agent::JournalProjection) ||
|
|
499
|
-
value.is_a?(Phronomy::Agent::ExecutionCoordinator) ||
|
|
500
|
-
value.is_a?(Phronomy::Agent::Context::Capability::Base) ||
|
|
501
|
-
value.is_a?(Phronomy::Workflow) ||
|
|
502
|
-
value.is_a?(Phronomy::WorkflowRunner) ||
|
|
503
|
-
value.is_a?(Phronomy::WorkflowContext) ||
|
|
504
|
-
value.is_a?(Phronomy::Runtime) ||
|
|
505
|
-
value.is_a?(Phronomy::TaskResult) ||
|
|
506
|
-
value.is_a?(Phronomy::EventLoop) ||
|
|
507
|
-
value.is_a?(Phronomy::FSMSession) ||
|
|
508
|
-
value.is_a?(Phronomy::FSMSession::EventSink) ||
|
|
509
|
-
value.is_a?(Phronomy::Concurrency::CancellationToken) ||
|
|
510
|
-
value.is_a?(Phronomy::Concurrency::OffloadPool)
|
|
556
|
+
value.is_a?(Phronomy::Concurrency::WorkerInputRestricted)
|
|
511
557
|
end
|
|
512
558
|
private_class_method :phronomy_managed_live_domain_object?
|
|
513
559
|
|
|
@@ -551,7 +597,7 @@ module Phronomy
|
|
|
551
597
|
|
|
552
598
|
def start_async_tool_operation(runtime)
|
|
553
599
|
if uses_default_call_async?
|
|
554
|
-
Phronomy::Agent::ToolExecutor.call_async(
|
|
600
|
+
Phronomy::Agent::Context::Capability::ToolExecutor.call_async(
|
|
555
601
|
tool: @tool,
|
|
556
602
|
args: @arguments,
|
|
557
603
|
cancellation_token: @config[:cancellation_token],
|
|
@@ -665,18 +711,7 @@ module Phronomy
|
|
|
665
711
|
end
|
|
666
712
|
|
|
667
713
|
def immutable_copy(value)
|
|
668
|
-
|
|
669
|
-
when Hash
|
|
670
|
-
value.each_with_object({}) do |(key, item), result|
|
|
671
|
-
result[immutable_copy(key)] = immutable_copy(item)
|
|
672
|
-
end.freeze
|
|
673
|
-
when Array
|
|
674
|
-
value.map { |item| immutable_copy(item) }.freeze
|
|
675
|
-
when String
|
|
676
|
-
value.dup.freeze
|
|
677
|
-
else
|
|
678
|
-
value
|
|
679
|
-
end
|
|
714
|
+
Phronomy::Values::Immutable.copy(value)
|
|
680
715
|
end
|
|
681
716
|
|
|
682
717
|
def redact_for_display(value)
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../canonical_json"
|
|
4
|
+
|
|
3
5
|
module Phronomy
|
|
4
|
-
module
|
|
6
|
+
module Values
|
|
7
|
+
# Shared value operations for snapshots, recovery facts, and result views.
|
|
8
|
+
# Hash, Array, and String trees are copied and frozen; other values retain
|
|
9
|
+
# their identity. Canonical JSON validation is a separate operation.
|
|
10
|
+
# @api private
|
|
5
11
|
module Immutable
|
|
6
12
|
module_function
|
|
7
13
|
|
|
14
|
+
# @api private
|
|
8
15
|
def copy(value)
|
|
9
16
|
case value
|
|
10
17
|
when Hash
|
|
@@ -20,6 +27,7 @@ module Phronomy
|
|
|
20
27
|
end
|
|
21
28
|
end
|
|
22
29
|
|
|
30
|
+
# @api private
|
|
23
31
|
def validate_canonical_json!(value, label: "value")
|
|
24
32
|
Phronomy::CanonicalJSON.dump(value)
|
|
25
33
|
true
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Phronomy
|
|
4
|
+
module Values
|
|
5
|
+
# Prepares a Ruby value tree for JSON serialization. Hash keys and Symbol
|
|
6
|
+
# values become Strings; containers are rebuilt and scalar objects retained.
|
|
7
|
+
# This neither freezes values nor validates canonical JSON numbers/encoding.
|
|
8
|
+
# @api private
|
|
9
|
+
module Serializable
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
def convert(value, unsupported_message:)
|
|
13
|
+
case value
|
|
14
|
+
when Hash
|
|
15
|
+
value.to_h { |key, child| [key.to_s, convert(child, unsupported_message: unsupported_message)] }
|
|
16
|
+
when Array
|
|
17
|
+
value.map { |child| convert(child, unsupported_message: unsupported_message) }
|
|
18
|
+
when String, Integer, Float, TrueClass, FalseClass, NilClass
|
|
19
|
+
value
|
|
20
|
+
when Symbol
|
|
21
|
+
value.to_s
|
|
22
|
+
else
|
|
23
|
+
if value.respond_to?(:to_h)
|
|
24
|
+
convert(value.to_h, unsupported_message: unsupported_message)
|
|
25
|
+
else
|
|
26
|
+
raise ArgumentError, "#{unsupported_message}: #{value.class}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -6,13 +6,23 @@ module Phronomy
|
|
|
6
6
|
STREAM_CALLBACK_ERROR_POLICIES = %i[report fail_task].freeze
|
|
7
7
|
private_constant :STREAM_CALLBACK_ERROR_POLICIES
|
|
8
8
|
|
|
9
|
+
DEFAULT_FACTORIES = {}
|
|
10
|
+
private_constant :DEFAULT_FACTORIES
|
|
11
|
+
|
|
12
|
+
# Bind fresh-instance factories once during application loading. Concrete
|
|
13
|
+
# component selection belongs to runtime_composition, not configuration.
|
|
14
|
+
# Applications replace instances through the existing configuration writers.
|
|
15
|
+
# @api private
|
|
16
|
+
def self.install_default_factories(tracer:, llm_adapter:)
|
|
17
|
+
DEFAULT_FACTORIES.replace(tracer: tracer, llm_adapter: llm_adapter).freeze
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
|
|
9
21
|
attr_accessor :default_model
|
|
10
22
|
attr_accessor :default_embedding_model
|
|
11
23
|
attr_accessor :tracer
|
|
12
24
|
attr_accessor :before_llm_input
|
|
13
|
-
attr_accessor :default_output_reserve
|
|
14
25
|
attr_accessor :recursion_limit
|
|
15
|
-
attr_accessor :parallel_tool_execution
|
|
16
26
|
attr_accessor :trace_pii
|
|
17
27
|
attr_accessor :logger
|
|
18
28
|
attr_accessor :event_loop_stop_grace_seconds
|
|
@@ -40,11 +50,10 @@ module Phronomy
|
|
|
40
50
|
|
|
41
51
|
def initialize
|
|
42
52
|
@recursion_limit = 25
|
|
43
|
-
@tracer =
|
|
53
|
+
@tracer = DEFAULT_FACTORIES.fetch(:tracer).call
|
|
44
54
|
@trace_pii = false
|
|
45
|
-
@parallel_tool_execution = false
|
|
46
55
|
@event_loop_stop_grace_seconds = 5
|
|
47
|
-
@llm_adapter =
|
|
56
|
+
@llm_adapter = DEFAULT_FACTORIES.fetch(:llm_adapter).call
|
|
48
57
|
@event_loop_starvation_threshold_seconds = nil
|
|
49
58
|
@event_loop_dispatch_threshold_seconds = nil
|
|
50
59
|
@stream_callback_error_policy = :report
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Global configuration access, replacement, and scoped overrides.
|
|
4
|
+
# Explicitly loaded by the application entry point; not a common definition.
|
|
5
|
+
module Phronomy
|
|
6
|
+
class << self
|
|
7
|
+
def configuration
|
|
8
|
+
@configuration ||= Configuration.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def configure
|
|
12
|
+
yield configuration
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def reset_configuration!
|
|
16
|
+
@configuration = Configuration.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def with_configuration
|
|
20
|
+
original = @configuration&.dup
|
|
21
|
+
yield configuration
|
|
22
|
+
ensure
|
|
23
|
+
@configuration = original
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Phronomy
|
|
4
|
+
module ContentStore
|
|
5
|
+
# @api private
|
|
6
|
+
module StorageSchema
|
|
7
|
+
CONTENTS = Phronomy::Storage::Resource.new(id: "content.blobs", kind: :blobs,
|
|
8
|
+
attributes: {canonicalization_version: :integer})
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Phronomy
|
|
4
|
+
module ContentStore
|
|
5
|
+
# Content identity and digest validation belong to ContentStore, not Blobs.
|
|
6
|
+
# @api private
|
|
7
|
+
class StoredContents < Base
|
|
8
|
+
def initialize(view) = @view = view
|
|
9
|
+
|
|
10
|
+
def put(bytes, canonicalization_version:)
|
|
11
|
+
value = String(bytes).b
|
|
12
|
+
id = content_id_for(value)
|
|
13
|
+
@view.atomic do |bound|
|
|
14
|
+
blob = bound.blobs(StorageSchema::CONTENTS).put_if_absent(key: id, bytes: value,
|
|
15
|
+
attributes: {canonicalization_version: Integer(canonicalization_version)})
|
|
16
|
+
verify!(blob, id)
|
|
17
|
+
id
|
|
18
|
+
end
|
|
19
|
+
rescue Phronomy::Storage::BlobConflictError => error
|
|
20
|
+
raise IntegrityError, error.message
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def fetch(content_id)
|
|
24
|
+
id = content_id.to_s
|
|
25
|
+
@view.atomic do |bound|
|
|
26
|
+
blob = bound.blobs(StorageSchema::CONTENTS).fetch(id)
|
|
27
|
+
verify!(blob, id)
|
|
28
|
+
blob.bytes.dup
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def exist?(content_id) = @view.blobs(StorageSchema::CONTENTS).exist?(content_id.to_s)
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def verify!(blob, id)
|
|
37
|
+
unless blob.key == id && content_id_for(blob.bytes) == id
|
|
38
|
+
raise IntegrityError, "content digest mismatch: #{id}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -22,7 +22,7 @@ module Phronomy
|
|
|
22
22
|
|
|
23
23
|
begin
|
|
24
24
|
unless invocation_context.nil?
|
|
25
|
-
binding =
|
|
25
|
+
binding = Concurrency::OperationBinding.new(invocation_context: invocation_context,
|
|
26
26
|
cancellation_token: cancellation_token)
|
|
27
27
|
end
|
|
28
28
|
result = Phronomy::Runtime.instance.offload.submit(
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "worker_input_restricted"
|
|
4
|
+
|
|
3
5
|
module Phronomy
|
|
4
6
|
module Concurrency
|
|
5
7
|
# Cooperative cancellation token for Agent/Tool work.
|
|
6
8
|
class CancellationToken
|
|
9
|
+
include Phronomy::Concurrency::WorkerInputRestricted
|
|
10
|
+
|
|
7
11
|
# Creates a token that expires after +seconds+ measured with the monotonic clock.
|
|
8
12
|
# @api public
|
|
9
13
|
def self.timeout_after(seconds)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "worker_input_restricted"
|
|
4
|
+
|
|
3
5
|
module Phronomy
|
|
4
6
|
module Concurrency
|
|
5
7
|
# A bounded, observable thread pool for synchronous work that must not run on
|
|
@@ -41,6 +43,8 @@ module Phronomy
|
|
|
41
43
|
# task = pool.submit(timeout: 30, cancellation_token: token) { expensive_call }
|
|
42
44
|
# result = task.wait_result
|
|
43
45
|
class OffloadPool
|
|
46
|
+
include Phronomy::Concurrency::WorkerInputRestricted
|
|
47
|
+
|
|
44
48
|
# Private execution record for one submitted synchronous operation.
|
|
45
49
|
#
|
|
46
50
|
# Caller-facing completion is represented exclusively by {Phronomy::TaskResult}.
|
|
@@ -4,7 +4,7 @@ module Phronomy
|
|
|
4
4
|
module Concurrency
|
|
5
5
|
# Connects explicit invocation controls before operation admission. Its token
|
|
6
6
|
# is private: cancelling it never cancels the application's shared tokens.
|
|
7
|
-
# Used by
|
|
7
|
+
# Used by Agent, Blocking and Orchestrator admission; it owns no worker.
|
|
8
8
|
# @api private
|
|
9
9
|
class OperationBinding
|
|
10
10
|
attr_reader :token, :scope
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Phronomy
|
|
4
|
+
module Concurrency
|
|
5
|
+
# Marks framework-managed objects excluded from authorization worker value
|
|
6
|
+
# snapshots and application behavior handles. Each owning type opts in.
|
|
7
|
+
# This methodless contract does not validate arbitrary object graphs or
|
|
8
|
+
# restrict every OffloadPool command. Application-owned opaque values retain
|
|
9
|
+
# their existing contract (ADR-024/045).
|
|
10
|
+
# @api private
|
|
11
|
+
module WorkerInputRestricted
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|