phronomy 0.27.0 → 0.29.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/.mutant.yml +9 -9
- data/CHANGELOG.md +52 -0
- data/CONTRIBUTING.md +8 -8
- data/README.md +28 -7
- data/benchmark/bench_agent_invoke.rb +25 -50
- data/benchmark/bench_context_assembler.rb +14 -11
- data/benchmark/bench_regression.rb +1 -1
- data/benchmark/bench_tool_schema.rb +1 -1
- data/docs/application-recipes.md +229 -0
- data/docs/architecture/agent-chat-and-state-ownership.md +7 -1
- data/docs/architecture/agent-transition-ownership.md +13 -89
- data/docs/architecture/backend-groups.md +152 -0
- data/docs/architecture/before-llm-input.md +3 -3
- data/docs/architecture/context-management.md +1 -1
- data/docs/architecture/dx05-agent-scope.md +119 -0
- data/docs/architecture/dx05-workflow-task-state.md +134 -0
- data/docs/architecture/error-api-review.md +245 -0
- data/docs/architecture/execution-abstraction-review.md +88 -0
- data/docs/architecture/execution-boundaries.md +28 -0
- data/docs/architecture/execution-metadata-and-values.md +6 -0
- data/docs/architecture/multi-agent-handoff.md +6 -5
- data/docs/architecture/persistence.md +27 -9
- data/docs/architecture/r8-unit1.md +104 -0
- data/docs/architecture/r8-unit10.md +72 -0
- data/docs/architecture/r8-unit11.md +71 -0
- data/docs/architecture/r8-unit12.md +67 -0
- data/docs/architecture/r8-unit13.md +61 -0
- data/docs/architecture/r8-unit14.md +72 -0
- data/docs/architecture/r8-unit15.md +65 -0
- data/docs/architecture/r8-unit16.md +54 -0
- data/docs/architecture/r8-unit17.md +73 -0
- data/docs/architecture/r8-unit18.md +92 -0
- data/docs/architecture/r8-unit19.md +61 -0
- data/docs/architecture/r8-unit2.md +55 -0
- data/docs/architecture/r8-unit20.md +51 -0
- data/docs/architecture/r8-unit21.md +79 -0
- data/docs/architecture/r8-unit22.md +74 -0
- data/docs/architecture/r8-unit23.md +81 -0
- data/docs/architecture/r8-unit3.md +130 -0
- data/docs/architecture/r8-unit4.md +79 -0
- data/docs/architecture/r8-unit5.md +115 -0
- data/docs/architecture/r8-unit6.md +71 -0
- data/docs/architecture/r8-unit7.md +70 -0
- data/docs/architecture/r8-unit8.md +78 -0
- data/docs/architecture/r8-unit9.md +73 -0
- data/docs/architecture/refactoring-closure.md +10 -1
- data/docs/architecture/remaining-refactoring-plan.md +16 -0
- data/docs/architecture/storage-execution-boundaries.md +54 -0
- data/docs/architecture/tool-schema-recording-gap.md +6 -0
- data/docs/architecture/tracing.md +1 -1
- data/docs/architecture/workflow-terminal-ownership-design.md +2 -2
- data/docs/architecture.md +24 -11
- data/docs/decisions/015-tool-public-facade-and-rbs-boundary.md +3 -3
- data/docs/decisions/027-llm-adapter-provider-boundary.md +2 -0
- data/docs/decisions/030-agent-handoff-domain-and-durable-responsibility.md +2 -0
- data/docs/decisions/031-durable-multi-agent-coordination.md +2 -0
- data/docs/decisions/032-storage-backend-composition.md +5 -0
- data/docs/decisions/034-handoff-runner-coordination-ownership.md +2 -0
- data/docs/decisions/035-tool-executor-capability-ownership.md +1 -1
- data/docs/decisions/038-responsibility-based-source-layout.md +14 -0
- data/docs/decisions/039-runtime-configuration-lifecycle-ownership.md +8 -0
- data/docs/decisions/040-configuration-default-composition.md +12 -1
- data/docs/decisions/045-worker-input-restriction-ownership.md +4 -0
- data/docs/decisions/051-execution-outcome-worker-ownership.md +2 -0
- data/docs/decisions/056-workflow-terminal-policy-ownership.md +1 -1
- data/docs/decisions/058-neutral-storage-primitives.md +5 -0
- data/docs/decisions/059-backend-contracts-and-async-clients.md +74 -0
- data/docs/decisions/060-runtime-settings-and-application-configuration.md +86 -0
- data/docs/decisions/061-persistence-failure-contracts.md +89 -0
- data/docs/decisions/062-content-store-service.md +52 -0
- data/docs/decisions/063-execution-contracts-and-services.md +88 -0
- data/docs/decisions/064-agent-execution-and-multi-agent-responsibility.md +36 -0
- data/docs/decisions/065-vector-and-embeddings-common-operations.md +38 -0
- data/docs/decisions/066-llm-and-tool-operation-contracts.md +20 -0
- data/docs/decisions/067-agent-progress-and-engine-connection.md +29 -0
- data/docs/decisions/068-agent-tool-child-progress-and-tool-operation.md +36 -0
- data/docs/decisions/README.md +18 -1
- data/docs/execution-boundaries-preview.md +45 -0
- data/docs/failure-reason-codes.md +45 -0
- data/docs/features.md +12 -4
- data/docs/getting-started.md +52 -48
- data/docs/migrations/0.22.md +2 -2
- data/docs/migrations/durable-semantic-coordination-v2.md +2 -0
- data/docs/migrations/handoff-runner-multi-agent.md +2 -0
- data/docs/migrations/persistence-failure-contracts.md +67 -0
- data/docs/migrations/r8-unit10.md +36 -0
- data/docs/migrations/r8-unit11.md +33 -0
- data/docs/migrations/r8-unit12.md +31 -0
- data/docs/migrations/r8-unit13.md +36 -0
- data/docs/migrations/r8-unit14.md +31 -0
- data/docs/migrations/r8-unit15.md +31 -0
- data/docs/migrations/r8-unit16.md +26 -0
- data/docs/migrations/r8-unit17.md +28 -0
- data/docs/migrations/r8-unit18.md +29 -0
- data/docs/migrations/r8-unit19.md +28 -0
- data/docs/migrations/r8-unit20.md +24 -0
- data/docs/migrations/r8-unit21.md +28 -0
- data/docs/migrations/r8-unit22.md +29 -0
- data/docs/migrations/r8-unit23.md +20 -0
- data/docs/migrations/r8-unit4.md +67 -0
- data/docs/migrations/r8-unit5.md +75 -0
- data/docs/migrations/r8-unit6.md +109 -0
- data/docs/migrations/r8-unit7.md +31 -0
- data/docs/migrations/r8-unit8.md +33 -0
- data/docs/migrations/r8-unit9.md +28 -0
- data/docs/migrations/storage-async-client.md +103 -0
- data/docs/migrations/vector-async-clients.md +110 -0
- data/docs/ordered-event-delivery.md +54 -0
- data/docs/persistence-backends.md +38 -21
- data/docs/runtime-and-concurrency.md +26 -1
- data/docs/workflow-completion.md +92 -0
- data/gemfiles/http_minimum.gemfile +5 -0
- data/lib/phronomy/agent/admission.rb +78 -0
- data/lib/phronomy/agent/{lifecycle_contract/agent_already_exists_error.rb → agent_already_exists_error.rb} +1 -1
- data/lib/phronomy/agent/{lifecycle_contract/agent_busy_error.rb → agent_busy_error.rb} +1 -1
- data/lib/phronomy/agent/agent_not_found_error.rb +16 -0
- data/lib/phronomy/agent/{lifecycle_contract/agent_purged_error.rb → agent_purged_error.rb} +1 -1
- data/lib/phronomy/agent/agent_unloaded_error.rb +14 -0
- data/lib/phronomy/agent/api/agent.rb +13 -0
- data/lib/phronomy/{recovery → agent/api}/execution_rehydration_required_error.rb +1 -1
- data/lib/phronomy/agent/async_event_api.rb +132 -103
- data/lib/phronomy/agent/base.rb +146 -113
- data/lib/phronomy/agent/before_llm_input.rb +70 -0
- data/lib/phronomy/agent/composition/run_once.rb +1 -1
- data/lib/phronomy/agent/{context_assembly/context_candidate_resolver.rb → context_candidate_resolver.rb} +2 -2
- data/lib/phronomy/agent/{context_assembly/context_assembler.rb → context_preparation.rb} +35 -221
- data/lib/phronomy/agent/control_request.rb +21 -0
- data/lib/phronomy/agent/execution/agent_execution.rb +1 -1
- data/lib/phronomy/agent/execution/agent_invocation.rb +27 -53
- data/lib/phronomy/agent/execution/approval_resume_commit.rb +1 -1
- data/lib/phronomy/agent/execution/dispatch_preparation.rb +17 -127
- data/lib/phronomy/agent/execution/exact_execution.rb +55 -32
- data/lib/phronomy/agent/execution/execution_cancellation.rb +8 -4
- data/lib/phronomy/agent/execution/execution_coordinator.rb +229 -407
- data/lib/phronomy/agent/execution/execution_metadata.rb +1 -0
- data/lib/phronomy/agent/execution/execution_outcome_committer.rb +71 -127
- data/lib/phronomy/agent/execution/execution_registry.rb +6 -2
- data/lib/phronomy/agent/execution/execution_session_runner.rb +22 -27
- data/lib/phronomy/agent/execution/initial_preparation.rb +19 -120
- data/lib/phronomy/agent/execution/{agent_invocation_session_builder.rb → invocation_actions.rb} +54 -194
- data/lib/phronomy/agent/execution/invocation_transitions.rb +39 -1
- data/lib/phronomy/agent/execution/runtime_record_encoder.rb +8 -11
- data/lib/phronomy/agent/execution_change.rb +161 -0
- data/lib/phronomy/agent/execution_environment.rb +36 -0
- data/lib/phronomy/agent/execution_extension_state.rb +21 -0
- data/lib/phronomy/agent/execution_observation.rb +35 -0
- data/lib/phronomy/agent/filterable.rb +188 -0
- data/lib/phronomy/agent/handoff/{handoff_context.rb → transfer_context.rb} +4 -4
- data/lib/phronomy/agent/handoff/{handoff_projection.rb → transfer_projection.rb} +14 -33
- data/lib/phronomy/{llm_contract/transport_error.rb → agent/handoff_error.rb} +1 -1
- data/lib/phronomy/agent/journal/journal_projection.rb +1 -1
- data/lib/phronomy/agent/knowledge_item.rb +13 -0
- data/lib/phronomy/agent/lifecycle/agent_root.rb +1 -1
- data/lib/phronomy/agent/lifecycle/lifetime_api.rb +76 -0
- data/lib/phronomy/agent/lifecycle/operation_lease.rb +33 -0
- data/lib/phronomy/agent/lifecycle/operation_result.rb +53 -0
- data/lib/phronomy/agent/lifecycle/ownership_registry.rb +117 -31
- data/lib/phronomy/agent/lifecycle/scope.rb +198 -0
- data/lib/phronomy/agent/lifecycle/scope_cleanup_error.rb +19 -0
- data/lib/phronomy/agent/lifecycle/unload_transition.rb +78 -0
- data/lib/phronomy/agent/persistence/agent_repository.rb +29 -21
- data/lib/phronomy/agent/persistence/cancellation_repository.rb +51 -0
- data/lib/phronomy/agent/persistence/codec.rb +1 -21
- data/lib/phronomy/agent/persistence/execution_repository.rb +57 -41
- data/lib/phronomy/agent/persistence/journal_repository.rb +27 -18
- data/lib/phronomy/agent/persistence/records.rb +33 -0
- data/lib/phronomy/agent/persistence/retention_repository.rb +70 -0
- data/lib/phronomy/agent/persistence/storage_schema.rb +7 -2
- data/lib/phronomy/agent/persistence/watermark.rb +13 -11
- data/lib/phronomy/agent/recovery/invocation_restorer.rb +13 -21
- data/lib/phronomy/agent/recovery/recovery_coordinator/continuation.rb +13 -12
- data/lib/phronomy/agent/recovery/recovery_coordinator/installation.rb +34 -34
- data/lib/phronomy/agent/recovery/recovery_coordinator/resolution.rb +33 -39
- data/lib/phronomy/agent/recovery/recovery_coordinator.rb +28 -25
- data/lib/phronomy/agent/recovery/recovery_rules.rb +119 -0
- data/lib/phronomy/agent/recovery/recovery_support.rb +10 -19
- data/lib/phronomy/agent/reserved_execution.rb +16 -0
- data/lib/phronomy/agent/retention.rb +17 -0
- data/lib/phronomy/agent/runtime_binding/engine_environment.rb +60 -0
- data/lib/phronomy/agent/runtime_binding/engine_session_builder.rb +34 -0
- data/lib/phronomy/agent/runtime_binding/phase_machine_builder.rb +64 -0
- data/lib/phronomy/agent/runtime_binding/tool_session_builder.rb +34 -0
- data/lib/phronomy/agent/{context_assembly/ruby_llm_materializer.rb → runtime_input.rb} +18 -35
- data/lib/phronomy/agent/{context_assembly/saved_context_reader.rb → saved_context_reader.rb} +6 -4
- data/lib/phronomy/agent/settings.rb +47 -0
- data/lib/phronomy/agent/{context_assembly/state_writer.rb → state_writer.rb} +4 -3
- data/lib/phronomy/agent/store.rb +253 -0
- data/lib/phronomy/agent/{lifecycle_contract/stream_callback_error.rb → stream_callback_error.rb} +3 -3
- data/lib/phronomy/agent/tool_execution/tool_binding.rb +4 -64
- data/lib/phronomy/agent/tool_execution/tool_invocation.rb +50 -219
- data/lib/phronomy/agent/tool_execution/tool_invocation_actions.rb +107 -0
- data/lib/phronomy/agent/tool_execution/tool_invocation_transitions.rb +70 -0
- data/lib/phronomy/common/error.rb +65 -1
- data/lib/phronomy/configuration/runtime_settings.rb +49 -0
- data/lib/phronomy/content_store/base.rb +7 -2
- data/lib/phronomy/content_store/storage_schema.rb +1 -0
- data/lib/phronomy/content_store/stored_contents.rb +2 -1
- data/lib/phronomy/context/assembly.rb +195 -0
- data/lib/phronomy/{llm_contract/context_budget_exceeded_error.rb → context/budget_exceeded_error.rb} +3 -1
- data/lib/phronomy/context/candidate.rb +51 -0
- data/lib/phronomy/context/constraint.rb +47 -0
- data/lib/phronomy/{agent/context_contract → context}/context_plan.rb +1 -1
- data/lib/phronomy/{agent/context_contract → context}/context_plan_validator.rb +3 -3
- data/lib/phronomy/{agent/context_contract → context}/context_policy.rb +1 -1
- data/lib/phronomy/{agent/context_contract → context}/context_policy_input.rb +1 -1
- data/lib/phronomy/{agent/context_assembly → context}/context_policy_input_builder.rb +1 -1
- data/lib/phronomy/context/default_policy.rb +140 -0
- data/lib/phronomy/context/final_budget_validator.rb +33 -0
- data/lib/phronomy/{agent/context_contract → context}/llm_input_build_context.rb +1 -1
- data/lib/phronomy/{agent/context_contract → context}/llm_input_manifest.rb +19 -19
- data/lib/phronomy/{agent/context_contract → context}/llm_input_patch.rb +1 -1
- data/lib/phronomy/context/manifest_error.rb +10 -0
- data/lib/phronomy/context/prompt_template.rb +98 -0
- data/lib/phronomy/{vector_store → documents}/loader/base.rb +1 -1
- data/lib/phronomy/{vector_store → documents}/loader/csv_loader.rb +2 -2
- data/lib/phronomy/{vector_store → documents}/loader/markdown_loader.rb +3 -3
- data/lib/phronomy/{vector_store → documents}/loader/plain_text_loader.rb +2 -2
- data/lib/phronomy/{vector_store → documents}/splitter/base.rb +1 -1
- data/lib/phronomy/{vector_store → documents}/splitter/fixed_size_splitter.rb +2 -2
- data/lib/phronomy/{vector_store → documents}/splitter/recursive_splitter.rb +2 -2
- data/lib/phronomy/embeddings/async/async_client.rb +44 -0
- data/lib/phronomy/embeddings/authentication_error.rb +11 -0
- data/lib/phronomy/embeddings/backends/ruby_llm_embeddings.rb +52 -0
- data/lib/phronomy/embeddings/base.rb +43 -0
- data/lib/phronomy/embeddings/invalid_result_error.rb +11 -0
- data/lib/phronomy/embeddings/rate_limit_error.rb +11 -0
- data/lib/phronomy/embeddings/transport_error.rb +11 -0
- data/lib/phronomy/engine/concurrency/offload_pool.rb +36 -21
- data/lib/phronomy/engine/concurrency/pool_registry.rb +47 -12
- data/lib/phronomy/engine/diagnostics.rb +1 -1
- data/lib/phronomy/engine/event_loop.rb +7 -7
- data/lib/phronomy/engine/execution_binding.rb +23 -0
- data/lib/phronomy/engine/execution_receiver_binding.rb +43 -0
- data/lib/phronomy/engine/fsm_protocol.rb +1 -6
- data/lib/phronomy/engine/fsm_session.rb +3 -3
- data/lib/phronomy/engine/metrics.rb +16 -14
- data/lib/phronomy/engine/runtime/timer_queue.rb +1 -1
- data/lib/phronomy/engine/runtime.rb +25 -12
- data/lib/phronomy/engine/terminal_decision.rb +7 -0
- data/lib/phronomy/execution/async_operation.rb +41 -0
- data/lib/phronomy/{engine → execution}/blocking.rb +2 -2
- data/lib/phronomy/{engine → execution}/concurrency/cancellation_token.rb +1 -1
- data/lib/phronomy/{engine → execution}/concurrency/deadline.rb +0 -17
- data/lib/phronomy/{engine → execution}/concurrency/physical_completion_task.rb +1 -1
- data/lib/phronomy/{engine → execution}/concurrency/result_collector.rb +1 -1
- data/lib/phronomy/{engine → execution}/concurrency/result_composition.rb +33 -12
- data/lib/phronomy/{engine/concurrency/subscriptions.rb → execution/concurrency/result_subscriptions.rb} +14 -18
- data/lib/phronomy/execution/concurrency/subscriptions.rb +25 -0
- data/lib/phronomy/{engine → execution}/execution.rb +61 -27
- data/lib/phronomy/{engine → execution}/execution_cancellation_error.rb +2 -2
- data/lib/phronomy/execution/execution_receiver.rb +78 -0
- data/lib/phronomy/execution/execution_scope_state.rb +35 -0
- data/lib/phronomy/{engine → execution}/execution_timeout_error.rb +2 -2
- data/lib/phronomy/{engine → execution}/invocation_context.rb +0 -15
- data/lib/phronomy/execution/invocation_controls.rb +73 -0
- data/lib/phronomy/execution/runnable.rb +24 -0
- data/lib/phronomy/{engine → execution}/task_result.rb +9 -4
- data/lib/phronomy/execution/wait_policy.rb +24 -0
- data/lib/phronomy/filter/{contract/filter_block_error.rb → filter_block_error.rb} +3 -3
- data/lib/phronomy/generation/generator_verifier/agent_operation.rb +65 -0
- data/lib/phronomy/generation/generator_verifier/default_parser.rb +27 -0
- data/lib/phronomy/generation/generator_verifier/workflow_builder.rb +2 -2
- data/lib/phronomy/generation/generator_verifier.rb +7 -7
- data/lib/phronomy/generation/low_confidence_error.rb +2 -2
- data/lib/phronomy/integrations/ordered_event_delivery.rb +208 -0
- data/lib/phronomy/llm_adapter/async/async_client.rb +47 -0
- data/lib/phronomy/{llm_contract → llm_adapter}/authentication_error.rb +3 -1
- data/lib/phronomy/llm_adapter/backends/ruby_llm.rb +183 -0
- data/lib/phronomy/llm_adapter/base.rb +49 -68
- data/lib/phronomy/{llm_contract → llm_adapter}/context_length_error.rb +3 -1
- data/lib/phronomy/llm_adapter/invalid_result_error.rb +10 -0
- data/lib/phronomy/llm_adapter/message.rb +62 -0
- data/lib/phronomy/{llm_contract → llm_adapter}/rate_limit_error.rb +3 -1
- data/lib/phronomy/llm_adapter/request.rb +79 -0
- data/lib/phronomy/llm_adapter/response.rb +36 -0
- data/lib/phronomy/llm_adapter/stream_chunk.rb +18 -0
- data/lib/phronomy/llm_adapter/token_usage.rb +64 -0
- data/lib/phronomy/llm_adapter/transport_error.rb +9 -0
- data/lib/phronomy/llm_adapter.rb +3 -16
- data/lib/phronomy/multi_agent/admission_registry.rb +1 -8
- data/lib/phronomy/multi_agent/durable_subagent_coordinator.rb +108 -84
- data/lib/phronomy/multi_agent/execution_environment.rb +29 -0
- data/lib/phronomy/{agent/handoff → multi_agent}/handoff.rb +2 -2
- data/lib/phronomy/{agent/handoff → multi_agent}/handoff_capability_factory.rb +21 -2
- data/lib/phronomy/multi_agent/handoff_participant.rb +79 -0
- data/lib/phronomy/{agent/handoff → multi_agent}/handoff_policy.rb +1 -1
- data/lib/phronomy/multi_agent/handoff_runner.rb +77 -100
- data/lib/phronomy/{agent/handoff → multi_agent}/handoff_state.rb +1 -1
- data/lib/phronomy/multi_agent/orchestrator.rb +61 -75
- data/lib/phronomy/multi_agent/persistence/codec.rb +20 -0
- data/lib/phronomy/multi_agent/persistence/handoff_state_repository.rb +77 -0
- data/lib/phronomy/multi_agent/persistence/records.rb +27 -0
- data/lib/phronomy/multi_agent/persistence/storage_schema.rb +21 -0
- data/lib/phronomy/multi_agent/persistence/team_execution_repository.rb +60 -44
- data/lib/phronomy/multi_agent/persistence/team_repository.rb +29 -21
- data/lib/phronomy/multi_agent/reserved_child_admission.rb +88 -0
- data/lib/phronomy/multi_agent/runtime_binding/engine_environment.rb +35 -0
- data/lib/phronomy/multi_agent/shared_state.rb +2 -2
- data/lib/phronomy/multi_agent/store.rb +156 -0
- data/lib/phronomy/multi_agent/team_busy_error.rb +18 -0
- data/lib/phronomy/multi_agent/team_coordinator.rb +99 -77
- data/lib/phronomy/multi_agent/team_not_found_error.rb +18 -0
- data/lib/phronomy/multi_agent/team_ownership_registry.rb +2 -12
- data/lib/phronomy/output_parser/parse_error.rb +7 -0
- data/lib/phronomy/persistence/content_repository.rb +26 -0
- data/lib/phronomy/persistence/errors.rb +16 -0
- data/lib/phronomy/persistence/migration/initial_format_migration.rb +2 -2
- data/lib/phronomy/persistence/persistence.rb +23 -0
- data/lib/phronomy/persistence/save_outcome.rb +24 -0
- data/lib/phronomy/persistence/snapshot_comparison.rb +81 -0
- data/lib/phronomy/persistence/storage_boundary.rb +32 -0
- data/lib/phronomy/persistence/transaction.rb +86 -0
- data/lib/phronomy/persistence_composition/storage_schema.rb +9 -4
- data/lib/phronomy/persistence_composition/stores.rb +34 -0
- data/lib/phronomy/persistence_composition/unit4_migration.rb +276 -0
- data/lib/phronomy/runtime_composition/agent_defaults.rb +5 -1
- data/lib/phronomy/runtime_composition/configuration.rb +146 -0
- data/lib/phronomy/runtime_composition/evaluation_defaults.rb +7 -0
- data/lib/phronomy/runtime_composition/execution_defaults.rb +5 -0
- data/lib/phronomy/runtime_composition/generation_defaults.rb +6 -0
- data/lib/phronomy/runtime_composition/global_configuration.rb +38 -0
- data/lib/phronomy/runtime_composition/multi_agent_defaults.rb +9 -0
- data/lib/phronomy/runtime_composition/workflow_defaults.rb +4 -0
- data/lib/phronomy/storage/async/async_client.rb +60 -0
- data/lib/phronomy/storage/backend.rb +8 -2
- data/lib/phronomy/storage/condition_failed_error.rb +2 -2
- data/lib/phronomy/storage/unique_constraint_error.rb +2 -2
- data/lib/phronomy/testing/eval/metrics.rb +1 -1
- data/lib/phronomy/testing/eval/scorer/llm_judge.rb +19 -3
- data/lib/phronomy/testing/persistence_contract/a_content_store.rb +2 -2
- data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +6 -6
- data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +55 -52
- data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +3 -3
- data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +7 -7
- data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +11 -11
- data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +57 -51
- data/lib/phronomy/testing/persistence_contract/neutral_storage_primitives.rb +1 -1
- data/lib/phronomy/testing/persistence_contract/storage_transaction_boundaries.rb +23 -22
- data/lib/phronomy/tool/authorization.rb +77 -0
- data/lib/phronomy/tool/base.rb +551 -9
- data/lib/phronomy/tool/call_request.rb +40 -0
- data/lib/phronomy/{agent/tool_execution/tool_definition_set.rb → tool/definition_set.rb} +7 -8
- data/lib/phronomy/tool/operation.rb +88 -0
- data/lib/phronomy/tool/schema.rb +214 -0
- data/lib/phronomy/tool/settings.rb +31 -0
- data/lib/phronomy/tool/tool_error.rb +7 -0
- data/lib/phronomy/tool/tool_executor.rb +58 -0
- data/lib/phronomy/tools/agent.rb +22 -90
- data/lib/phronomy/tools/mcp.rb +21 -14
- data/lib/phronomy/tools/vector_search.rb +4 -4
- data/lib/phronomy/tracing/automatic.rb +11 -6
- data/lib/phronomy/tracing/base.rb +36 -7
- data/lib/phronomy/tracing/observation.rb +37 -0
- data/lib/phronomy/tracing/open_telemetry_tracer.rb +4 -29
- data/lib/phronomy/tracing/settings.rb +36 -0
- data/lib/phronomy/vector_store/{async_backend.rb → async/async_client.rb} +35 -29
- data/lib/phronomy/vector_store/{in_memory.rb → backends/in_memory.rb} +12 -10
- data/lib/phronomy/vector_store/{pgvector.rb → backends/pgvector.rb} +44 -16
- data/lib/phronomy/vector_store/{redis_search.rb → backends/redis_search.rb} +74 -37
- data/lib/phronomy/vector_store/base.rb +118 -49
- data/lib/phronomy/vector_store/invalid_result_error.rb +12 -0
- data/lib/phronomy/vector_store.rb +2 -17
- data/lib/phronomy/version.rb +1 -1
- data/lib/phronomy/workflow/completion.rb +11 -0
- data/lib/phronomy/workflow/execution/workflow.rb +37 -9
- data/lib/phronomy/workflow/execution/workflow_action_rules.rb +67 -0
- data/lib/phronomy/workflow/execution/workflow_context.rb +2 -2
- data/lib/phronomy/workflow/execution/workflow_execution_environment.rb +28 -0
- data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +77 -8
- data/lib/phronomy/workflow/execution/workflow_runner.rb +105 -92
- data/lib/phronomy/workflow/execution/workflow_settings.rb +28 -0
- data/lib/phronomy/workflow/execution/workflow_task_execution.rb +153 -0
- data/lib/phronomy/workflow/execution/workflow_task_reception.rb +72 -0
- data/lib/phronomy/workflow/execution/workflow_task_resume_error.rb +14 -0
- data/lib/phronomy/workflow/persistence/state_repository.rb +28 -22
- data/lib/phronomy/workflow/persistence/storage_schema.rb +13 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_engine_environment.rb +61 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_phase_machine_builder.rb +158 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_task_session.rb +76 -0
- data/lib/phronomy/workflow/{execution → runtime_binding}/workflow_terminal_policy.rb +4 -4
- data/lib/phronomy.rb +63 -16
- data/scripts/api_snapshot.rb +47 -15
- data/scripts/check_readme_ruby.rb +24 -29
- data/scripts/check_readme_runnable.rb +92 -81
- data/sig/_private/phronomy/agent/settings.rbs +19 -0
- data/sig/_private/phronomy/configuration/runtime_settings.rbs +20 -0
- data/sig/_private/phronomy/llm_adapter/async/async_client.rbs +10 -0
- data/sig/_private/phronomy/multi_agent/store.rbs +8 -0
- data/sig/_private/phronomy/persistence/storage_boundary.rbs +7 -0
- data/sig/_private/phronomy/tool/settings.rbs +13 -0
- data/sig/_private/phronomy/tracing/settings.rbs +15 -0
- data/sig/_private/phronomy/workflow/execution/workflow_settings.rbs +13 -0
- data/sig/phronomy/agent/admission.rbs +19 -0
- data/sig/phronomy/agent/agent_not_found_error.rbs +6 -0
- data/sig/phronomy/agent/agent_unloaded_error.rbs +6 -0
- data/sig/phronomy/agent/execution_contract.rbs +132 -0
- data/sig/phronomy/agent/execution_environment.rbs +20 -0
- data/sig/phronomy/agent/store.rbs +73 -0
- data/sig/phronomy/agent/stream_callback_error.rbs +8 -0
- data/sig/phronomy/agent.rbs +29 -135
- data/sig/phronomy/common.rbs +7 -0
- data/sig/phronomy/content_store/contracts.rbs +13 -0
- data/sig/phronomy/context.rbs +152 -0
- data/sig/phronomy/embeddings/async/async_client.rbs +9 -0
- data/sig/phronomy/embeddings/base.rbs +23 -0
- data/sig/phronomy/engine/concurrency/timer_bindings.rbs +22 -0
- data/sig/phronomy/engine/control_bindings.rbs +11 -0
- data/sig/phronomy/engine/control_protocols.rbs +23 -0
- data/sig/phronomy/engine/execution_binding.rbs +6 -0
- data/sig/phronomy/engine/execution_receiver.rbs +15 -0
- data/sig/phronomy/engine/observability.rbs +13 -0
- data/sig/phronomy/execution/async_operation.rbs +7 -0
- data/sig/phronomy/execution/blocking.rbs +5 -0
- data/sig/phronomy/execution/concurrency/cancellation_token.rbs +13 -0
- data/sig/phronomy/execution/concurrency/deadline.rbs +10 -0
- data/sig/phronomy/execution/concurrency/result_composition.rbs +7 -0
- data/sig/phronomy/execution/control_protocols.rbs +18 -0
- data/sig/phronomy/execution/errors.rbs +7 -0
- data/sig/phronomy/execution/execution.rbs +41 -0
- data/sig/phronomy/execution/execution_receiver.rbs +40 -0
- data/sig/phronomy/execution/execution_scope_state.rbs +9 -0
- data/sig/phronomy/execution/invocation_context.rbs +18 -0
- data/sig/phronomy/execution/invocation_controls.rbs +13 -0
- data/sig/phronomy/execution/task_result.rbs +29 -0
- data/sig/phronomy/extensions.rbs +1 -21
- data/sig/phronomy/filter/filter_block_error.rbs +6 -0
- data/sig/phronomy/generation/low_confidence_error.rbs +6 -0
- data/sig/phronomy/handoff.rbs +10 -4
- data/sig/phronomy/integrations.rbs +14 -0
- data/sig/phronomy/llm_adapter/backends/ruby_llm.rbs +6 -0
- data/sig/phronomy/llm_adapter/base.rbs +14 -0
- data/sig/phronomy/llm_adapter/usage.rbs +14 -0
- data/sig/phronomy/llm_adapter/values.rbs +43 -0
- data/sig/phronomy/llm_context_window.rbs +10 -0
- data/sig/phronomy/multi_agent/reserved_child_admission.rbs +8 -0
- data/sig/phronomy/multi_agent/store.rbs +54 -0
- data/sig/phronomy/multi_agent/team_busy_error.rbs +8 -0
- data/sig/phronomy/multi_agent/team_not_found_error.rbs +8 -0
- data/sig/phronomy/multi_agent.rbs +6 -3
- data/sig/phronomy/persistence/errors.rbs +18 -0
- data/sig/phronomy/persistence/migration.rbs +13 -0
- data/sig/phronomy/persistence/transaction.rbs +19 -0
- data/sig/phronomy/persistence.rbs +1 -99
- data/sig/phronomy/persistence_composition.rbs +19 -0
- data/sig/phronomy/runtime_composition/configuration.rbs +36 -0
- data/sig/phronomy/storage/async/async_client.rbs +8 -0
- data/sig/phronomy/storage/backends/in_memory.rbs +9 -0
- data/sig/phronomy/{storage.rbs → storage/contracts.rbs} +4 -18
- data/sig/phronomy/tool.rbs +48 -4
- data/sig/phronomy/tracing/observation.rbs +7 -0
- data/sig/phronomy/vector_store/async/async_client.rbs +13 -0
- data/sig/phronomy/vector_store/base.rbs +23 -0
- data/sig/phronomy/workflow/execution/workflow_execution_environment.rbs +15 -0
- data/sig/phronomy/workflow/runtime_binding/workflow_terminal_policy.rbs +7 -0
- data/sig/phronomy/workflow/store.rbs +8 -0
- data/sig/phronomy/workflow.rbs +5 -1
- data/sig/phronomy.rbs +4 -49
- metadata +365 -117
- data/lib/phronomy/agent/concerns/before_llm_input.rb +0 -66
- data/lib/phronomy/agent/concerns/error_translation.rb +0 -45
- data/lib/phronomy/agent/concerns/filterable.rb +0 -184
- data/lib/phronomy/agent/context/capability/base.rb +0 -548
- data/lib/phronomy/agent/context/capability/tool_executor.rb +0 -62
- data/lib/phronomy/agent/context/instruction/prompt_template.rb +0 -102
- data/lib/phronomy/agent/context_assembly/runtime_chat_builder.rb +0 -36
- data/lib/phronomy/agent/context_assembly/token_budget_resolver.rb +0 -22
- data/lib/phronomy/agent/context_parts/validators/final_budget_validator.rb +0 -37
- data/lib/phronomy/agent/context_policies/default.rb +0 -142
- data/lib/phronomy/agent/execution/phase_machine_builder.rb +0 -101
- data/lib/phronomy/agent/execution/provider_call_outcome.rb +0 -106
- data/lib/phronomy/agent/handoff/handoff_execution_coordinator.rb +0 -15
- data/lib/phronomy/agent/handoff/handoff_outcome_committer.rb +0 -131
- data/lib/phronomy/agent/handoff/handoff_request.rb +0 -45
- data/lib/phronomy/agent/lifecycle_contract/handoff_error.rb +0 -7
- data/lib/phronomy/agent/persistence/handoff_state_repository.rb +0 -58
- data/lib/phronomy/agent/persistence/queries.rb +0 -61
- data/lib/phronomy/agent/selection/candidate.rb +0 -53
- data/lib/phronomy/agent/selection/constraint.rb +0 -49
- data/lib/phronomy/agent/tool_execution/tool_call_intercepted.rb +0 -29
- data/lib/phronomy/agent/tool_execution/tool_invocation_session_builder.rb +0 -276
- data/lib/phronomy/configuration/configuration.rb +0 -68
- data/lib/phronomy/configuration/global_configuration.rb +0 -26
- data/lib/phronomy/engine/concurrency/cancellation_scope.rb +0 -124
- data/lib/phronomy/engine/concurrency/operation_binding.rb +0 -43
- data/lib/phronomy/engine/execution_receiver.rb +0 -65
- data/lib/phronomy/engine/runnable.rb +0 -54
- data/lib/phronomy/llm_adapter/ruby_llm.rb +0 -47
- data/lib/phronomy/llm_contract/token_usage.rb +0 -85
- data/lib/phronomy/multi_agent/persistence/queries.rb +0 -30
- data/lib/phronomy/multi_agent/storage_contract/team_storage_schema.rb +0 -15
- data/lib/phronomy/output_parser/contract/parse_error.rb +0 -7
- data/lib/phronomy/persistence/api/persistence.rb +0 -140
- data/lib/phronomy/persistence_composition/repositories.rb +0 -77
- data/lib/phronomy/recovery/recovery.rb +0 -186
- data/lib/phronomy/tool/contract/tool_error.rb +0 -7
- data/lib/phronomy/vector_store/embeddings/base.rb +0 -44
- data/lib/phronomy/vector_store/embeddings/ruby_llm_embeddings.rb +0 -47
- data/lib/phronomy/workflow/phase_machine_builder.rb +0 -205
- data/lib/phronomy/workflow/storage_contract/workflow_storage_schema.rb +0 -9
- data/sig/phronomy/execution_receiver.rbs +0 -34
- data/sig/phronomy/llm_adapter.rbs +0 -11
- data/sig/phronomy/runtime.rbs +0 -76
- /data/lib/phronomy/agent/{context_assembly/context_importer.rb → context_importer.rb} +0 -0
- /data/lib/phronomy/{engine → execution}/backpressure_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/cancellation_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/concurrency/worker_input_restricted.rb +0 -0
- /data/lib/phronomy/{engine → execution}/event_loop_reentrancy_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/invalid_async_entry_action_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/invalid_async_transition_action_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/invalid_async_workflow_action_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/pool_shutdown_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/recursion_limit_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/runtime_shutdown_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/runtime_shutdown_reentrancy_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/scheduler_reentrancy_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/timeout_error.rb +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../../
|
|
3
|
+
require_relative "../../execution/concurrency/worker_input_restricted"
|
|
4
4
|
|
|
5
5
|
require "time"
|
|
6
6
|
require "securerandom"
|
|
@@ -14,7 +14,7 @@ module Phronomy
|
|
|
14
14
|
StartCommand = Data.define(
|
|
15
15
|
:coordinator, :input, :config, :mode,
|
|
16
16
|
:approval_policy, :approval_listener, :on_event, :result_task,
|
|
17
|
-
:admission_token
|
|
17
|
+
:admission_token, :controls
|
|
18
18
|
)
|
|
19
19
|
ResumeCommand = Data.define(
|
|
20
20
|
:coordinator, :execution_id, :approval_request_id,
|
|
@@ -39,10 +39,7 @@ module Phronomy
|
|
|
39
39
|
InitialPreparationCommand = InitialPreparation::Command
|
|
40
40
|
ProviderDispatchPreparationCommand = DispatchPreparation::ProviderCommand
|
|
41
41
|
ToolDispatchPreparationCommand = DispatchPreparation::ToolCommand
|
|
42
|
-
ProviderDispatchPreparationReconciliationCommand = DispatchPreparation::ProviderReconciliationCommand
|
|
43
|
-
ToolDispatchPreparationReconciliationCommand = DispatchPreparation::ToolReconciliationCommand
|
|
44
42
|
ResumeCommitCommand = ApprovalResumeCommit::Command
|
|
45
|
-
HandoffTerminalView = ExecutionOutcomeCommitter::HandoffTerminalView
|
|
46
43
|
TerminalView = ExecutionOutcomeCommitter::TerminalView
|
|
47
44
|
TerminalCommitCommand = ExecutionOutcomeCommitter::Command
|
|
48
45
|
TerminalDelivery = Data.define(
|
|
@@ -55,8 +52,6 @@ module Phronomy
|
|
|
55
52
|
InitialPreparationResult = InitialPreparation::Result
|
|
56
53
|
ProviderDispatchPreparationResult = DispatchPreparation::ProviderResult
|
|
57
54
|
ToolDispatchPreparationResult = DispatchPreparation::ToolResult
|
|
58
|
-
ProviderDispatchPreparationReconciliationResult = DispatchPreparation::ProviderReconciliationResult
|
|
59
|
-
ToolDispatchPreparationReconciliationResult = DispatchPreparation::ToolReconciliationResult
|
|
60
55
|
ResumeCommitResult = ApprovalResumeCommit::Result
|
|
61
56
|
TerminalOutcome = ExecutionOutcomeCommitter::Outcome
|
|
62
57
|
|
|
@@ -73,12 +68,6 @@ module Phronomy
|
|
|
73
68
|
ToolDispatchPreparationReady = Data.define(
|
|
74
69
|
:coordinator, :operation, :result, :error
|
|
75
70
|
)
|
|
76
|
-
ProviderDispatchPreparationReconciliationReady = Data.define(
|
|
77
|
-
:coordinator, :command, :result, :error
|
|
78
|
-
)
|
|
79
|
-
ToolDispatchPreparationReconciliationReady = Data.define(
|
|
80
|
-
:coordinator, :command, :result, :error
|
|
81
|
-
)
|
|
82
71
|
ResumeCommitReady = Data.define(
|
|
83
72
|
:coordinator, :request, :operation, :result, :error
|
|
84
73
|
)
|
|
@@ -90,9 +79,6 @@ module Phronomy
|
|
|
90
79
|
:source_error, :fsm_session_id
|
|
91
80
|
)
|
|
92
81
|
|
|
93
|
-
PreparationOutcomeUnknownError = DispatchPreparation::OutcomeUnknownError
|
|
94
|
-
private_constant :PreparationOutcomeUnknownError
|
|
95
|
-
|
|
96
82
|
def initialize(agent)
|
|
97
83
|
@agent = agent
|
|
98
84
|
@initial_preparation = InitialPreparation.new(agent: agent, persistence: agent.persistence)
|
|
@@ -107,15 +93,11 @@ module Phronomy
|
|
|
107
93
|
)
|
|
108
94
|
@agent.send(:__assert_live_agent!)
|
|
109
95
|
@agent.send(:_reject_removed_generic_identity_keys!, config)
|
|
110
|
-
result_task =
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
)
|
|
116
|
-
binding.bind(result_task)
|
|
117
|
-
config = config.merge(cancellation_token: binding.token)
|
|
118
|
-
end
|
|
96
|
+
result_task = OperationResult.new(agent: @agent, name: "agent-#{@agent.agent_id}-#{mode}")
|
|
97
|
+
controls = Phronomy::InvocationControls.attach(result_task,
|
|
98
|
+
invocation_context: config[:invocation_context],
|
|
99
|
+
cancellation_token: config[:cancellation_token])
|
|
100
|
+
config = config.merge(cancellation_token: controls.token)
|
|
119
101
|
command = StartCommand.new(
|
|
120
102
|
coordinator: self,
|
|
121
103
|
input: input,
|
|
@@ -125,14 +107,15 @@ module Phronomy
|
|
|
125
107
|
approval_listener: approval_listener,
|
|
126
108
|
on_event: on_event,
|
|
127
109
|
result_task: result_task,
|
|
128
|
-
admission_token: Object.new.freeze
|
|
110
|
+
admission_token: Object.new.freeze,
|
|
111
|
+
controls: controls
|
|
129
112
|
)
|
|
130
|
-
unless post_control(
|
|
113
|
+
unless post_control(@agent.__execution_environment, command)
|
|
131
114
|
fail_task(result_task, runtime_rejected_error(:start))
|
|
132
115
|
end
|
|
133
116
|
result_task
|
|
134
117
|
rescue => error
|
|
135
|
-
fail_task(result_task,
|
|
118
|
+
fail_task(result_task, error) if defined?(result_task) && result_task
|
|
136
119
|
result_task
|
|
137
120
|
end
|
|
138
121
|
|
|
@@ -144,9 +127,8 @@ module Phronomy
|
|
|
144
127
|
)
|
|
145
128
|
@agent.send(:__assert_live_agent!)
|
|
146
129
|
@agent.send(:_reject_removed_generic_identity_keys!, config)
|
|
147
|
-
result_task =
|
|
148
|
-
name: "agent-approval-resume:#{execution_id}"
|
|
149
|
-
)
|
|
130
|
+
result_task = OperationResult.new(agent: @agent,
|
|
131
|
+
name: "agent-approval-resume:#{execution_id}")
|
|
150
132
|
command = ResumeCommand.new(
|
|
151
133
|
coordinator: self,
|
|
152
134
|
execution_id: execution_id.to_s.freeze,
|
|
@@ -155,12 +137,12 @@ module Phronomy
|
|
|
155
137
|
config: config.dup.freeze,
|
|
156
138
|
result_task: result_task
|
|
157
139
|
)
|
|
158
|
-
unless post_control(
|
|
140
|
+
unless post_control(@agent.__execution_environment, command)
|
|
159
141
|
fail_task(result_task, runtime_rejected_error(:resume))
|
|
160
142
|
end
|
|
161
143
|
result_task
|
|
162
144
|
rescue => error
|
|
163
|
-
fail_task(result_task,
|
|
145
|
+
fail_task(result_task, error) if defined?(result_task) && result_task
|
|
164
146
|
result_task
|
|
165
147
|
end
|
|
166
148
|
|
|
@@ -178,7 +160,7 @@ module Phronomy
|
|
|
178
160
|
submit_provider_dispatch_preparation(operation)
|
|
179
161
|
nil
|
|
180
162
|
rescue => error
|
|
181
|
-
event_sink.post(:llm_setup_failed,
|
|
163
|
+
event_sink.post(:llm_setup_failed, error)
|
|
182
164
|
nil
|
|
183
165
|
end
|
|
184
166
|
|
|
@@ -193,13 +175,13 @@ module Phronomy
|
|
|
193
175
|
submit_tool_dispatch_preparation(operation)
|
|
194
176
|
nil
|
|
195
177
|
rescue => error
|
|
196
|
-
event_sink.post(:tool_setup_failed,
|
|
178
|
+
event_sink.post(:tool_setup_failed, error)
|
|
197
179
|
nil
|
|
198
180
|
end
|
|
199
181
|
|
|
200
182
|
def submit_provider_dispatch_preparation(operation)
|
|
201
|
-
|
|
202
|
-
task =
|
|
183
|
+
environment = @agent.__execution_environment
|
|
184
|
+
task = environment.submit(on_full: :raise) do
|
|
203
185
|
@dispatch_preparation.prepare_provider(operation)
|
|
204
186
|
end
|
|
205
187
|
task.on_complete do |result, error|
|
|
@@ -209,8 +191,8 @@ module Phronomy
|
|
|
209
191
|
result: result,
|
|
210
192
|
error: error
|
|
211
193
|
)
|
|
212
|
-
unless post_control(
|
|
213
|
-
Phronomy.
|
|
194
|
+
unless post_control(environment, ready)
|
|
195
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
214
196
|
"[Phronomy] EventLoop rejected Provider dispatch preparation result for " \
|
|
215
197
|
"#{operation.execution_id}"
|
|
216
198
|
)
|
|
@@ -219,8 +201,8 @@ module Phronomy
|
|
|
219
201
|
end
|
|
220
202
|
|
|
221
203
|
def submit_tool_dispatch_preparation(operation)
|
|
222
|
-
|
|
223
|
-
task =
|
|
204
|
+
environment = @agent.__execution_environment
|
|
205
|
+
task = environment.submit(on_full: :raise) do
|
|
224
206
|
@dispatch_preparation.prepare_tools(operation)
|
|
225
207
|
end
|
|
226
208
|
task.on_complete do |result, error|
|
|
@@ -230,8 +212,8 @@ module Phronomy
|
|
|
230
212
|
result: result,
|
|
231
213
|
error: error
|
|
232
214
|
)
|
|
233
|
-
unless post_control(
|
|
234
|
-
Phronomy.
|
|
215
|
+
unless post_control(environment, ready)
|
|
216
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
235
217
|
"[Phronomy] EventLoop rejected Tool dispatch preparation result for " \
|
|
236
218
|
"#{operation.execution_id}"
|
|
237
219
|
)
|
|
@@ -239,70 +221,12 @@ module Phronomy
|
|
|
239
221
|
end
|
|
240
222
|
end
|
|
241
223
|
|
|
242
|
-
def submit_provider_dispatch_preparation_reconciliation(operation, uncertainty)
|
|
243
|
-
# simplecov:disable
|
|
244
|
-
runtime = Phronomy::Runtime.instance
|
|
245
|
-
command = ProviderDispatchPreparationReconciliationCommand.new(
|
|
246
|
-
operation: operation,
|
|
247
|
-
intended_result: uncertainty.intended_result,
|
|
248
|
-
original_error: uncertainty.original_error
|
|
249
|
-
)
|
|
250
|
-
task = runtime.offload.submit(on_full: :raise) do
|
|
251
|
-
@dispatch_preparation.reconcile_provider(command)
|
|
252
|
-
end
|
|
253
|
-
task.on_complete do |result, error|
|
|
254
|
-
ready = ProviderDispatchPreparationReconciliationReady.new(
|
|
255
|
-
coordinator: self,
|
|
256
|
-
command: command,
|
|
257
|
-
result: result,
|
|
258
|
-
error: error
|
|
259
|
-
)
|
|
260
|
-
unless post_control(runtime, ready)
|
|
261
|
-
Phronomy.configuration.logger&.warn(
|
|
262
|
-
"[Phronomy] EventLoop rejected Provider dispatch reconciliation result for #{operation.execution_id}"
|
|
263
|
-
)
|
|
264
|
-
end
|
|
265
|
-
end
|
|
266
|
-
rescue => error
|
|
267
|
-
mark_barrier_recovery_required(operation, error)
|
|
268
|
-
# simplecov:enable
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
def submit_tool_dispatch_preparation_reconciliation(operation, uncertainty)
|
|
272
|
-
# simplecov:disable
|
|
273
|
-
runtime = Phronomy::Runtime.instance
|
|
274
|
-
command = ToolDispatchPreparationReconciliationCommand.new(
|
|
275
|
-
operation: operation,
|
|
276
|
-
intended_result: uncertainty.intended_result,
|
|
277
|
-
original_error: uncertainty.original_error
|
|
278
|
-
)
|
|
279
|
-
task = runtime.offload.submit(on_full: :raise) do
|
|
280
|
-
@dispatch_preparation.reconcile_tools(command)
|
|
281
|
-
end
|
|
282
|
-
task.on_complete do |result, error|
|
|
283
|
-
ready = ToolDispatchPreparationReconciliationReady.new(
|
|
284
|
-
coordinator: self,
|
|
285
|
-
command: command,
|
|
286
|
-
result: result,
|
|
287
|
-
error: error
|
|
288
|
-
)
|
|
289
|
-
unless post_control(runtime, ready)
|
|
290
|
-
Phronomy.configuration.logger&.warn(
|
|
291
|
-
"[Phronomy] EventLoop rejected Tool dispatch reconciliation result for #{operation.execution_id}"
|
|
292
|
-
)
|
|
293
|
-
end
|
|
294
|
-
end
|
|
295
|
-
rescue => error
|
|
296
|
-
mark_barrier_recovery_required(operation, error)
|
|
297
|
-
# simplecov:enable
|
|
298
|
-
end
|
|
299
|
-
|
|
300
224
|
# Every control message is delivered by EventLoop. This method is the only
|
|
301
225
|
# coordinator entry point allowed to advance Phronomy-managed live state.
|
|
302
226
|
# @api private
|
|
303
227
|
def deliver_on_event_loop(command)
|
|
304
|
-
|
|
305
|
-
assert_event_loop!(
|
|
228
|
+
environment = @agent.__execution_environment
|
|
229
|
+
assert_event_loop!(environment)
|
|
306
230
|
|
|
307
231
|
case command
|
|
308
232
|
when StartCommand
|
|
@@ -322,10 +246,6 @@ module Phronomy
|
|
|
322
246
|
apply_provider_dispatch_preparation_on_event_loop(command)
|
|
323
247
|
when ToolDispatchPreparationReady
|
|
324
248
|
apply_tool_dispatch_preparation_on_event_loop(command)
|
|
325
|
-
when ProviderDispatchPreparationReconciliationReady
|
|
326
|
-
apply_provider_dispatch_preparation_reconciliation_on_event_loop(command)
|
|
327
|
-
when ToolDispatchPreparationReconciliationReady
|
|
328
|
-
apply_tool_dispatch_preparation_reconciliation_on_event_loop(command)
|
|
329
249
|
when ResumeCommand
|
|
330
250
|
begin_resume_on_event_loop(command)
|
|
331
251
|
when ResumeCommitReady
|
|
@@ -346,14 +266,9 @@ module Phronomy
|
|
|
346
266
|
# ----------------------------------------------------------------------
|
|
347
267
|
|
|
348
268
|
def begin_start_on_event_loop(request)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if scope && (!scope.__open? || request.config[:cancellation_token]&.cancelled?)
|
|
353
|
-
deliver_start_failure_on_event_loop(request, scope.__cancellation_error)
|
|
354
|
-
return
|
|
355
|
-
end
|
|
356
|
-
root = @agent.agent_root
|
|
269
|
+
environment = @agent.__execution_environment
|
|
270
|
+
request.controls.check_start!
|
|
271
|
+
root = @agent.send(:__root_for_operation)
|
|
357
272
|
if root.lifecycle_status == :closed
|
|
358
273
|
deliver_start_failure_on_event_loop(
|
|
359
274
|
request,
|
|
@@ -365,7 +280,7 @@ module Phronomy
|
|
|
365
280
|
@agent.send(:__assert_live_agent!)
|
|
366
281
|
admitted = false
|
|
367
282
|
submitted = false
|
|
368
|
-
|
|
283
|
+
environment.registry.admit_agent_execution(
|
|
369
284
|
@agent.agent_id,
|
|
370
285
|
owner_token: request.admission_token
|
|
371
286
|
)
|
|
@@ -378,10 +293,11 @@ module Phronomy
|
|
|
378
293
|
@agent.send(:__assert_live_agent!)
|
|
379
294
|
|
|
380
295
|
operation = capture_initial_preparation(request, root)
|
|
381
|
-
task =
|
|
296
|
+
task = environment.submit(on_full: :raise) do
|
|
382
297
|
@initial_preparation.prepare(operation)
|
|
383
298
|
end
|
|
384
299
|
submitted = true
|
|
300
|
+
request.result_task.track(task) if request.result_task.respond_to?(:track)
|
|
385
301
|
task.on_complete do |result, error|
|
|
386
302
|
ready = InitialPreparationReady.new(
|
|
387
303
|
coordinator: self,
|
|
@@ -390,23 +306,23 @@ module Phronomy
|
|
|
390
306
|
error: error
|
|
391
307
|
)
|
|
392
308
|
fail_task(request.result_task, runtime_rejected_error(:initial_preparation)) unless
|
|
393
|
-
post_control(
|
|
309
|
+
post_control(environment, ready)
|
|
394
310
|
end
|
|
395
311
|
rescue => error
|
|
396
312
|
if admitted
|
|
397
313
|
if submitted
|
|
398
|
-
|
|
314
|
+
environment.registry.mark_agent_admission_recovery_required(
|
|
399
315
|
@agent.agent_id,
|
|
400
316
|
owner_token: request.admission_token
|
|
401
317
|
)
|
|
402
318
|
else
|
|
403
|
-
|
|
319
|
+
environment.registry.release_agent_execution_admission(
|
|
404
320
|
@agent.agent_id,
|
|
405
321
|
owner_token: request.admission_token
|
|
406
322
|
)
|
|
407
323
|
end
|
|
408
324
|
end
|
|
409
|
-
deliver_start_failure_on_event_loop(request,
|
|
325
|
+
deliver_start_failure_on_event_loop(request, error)
|
|
410
326
|
end
|
|
411
327
|
|
|
412
328
|
def capture_initial_preparation(request, root)
|
|
@@ -426,9 +342,9 @@ module Phronomy
|
|
|
426
342
|
def initial_preparation_replayable?(input, config, approval_policy)
|
|
427
343
|
return false unless input.is_a?(String)
|
|
428
344
|
return false unless approval_policy.nil?
|
|
429
|
-
if config.key?(:
|
|
430
|
-
config.key?(:
|
|
431
|
-
return false unless config[:
|
|
345
|
+
if config.key?(:phronomy_control_bindings) ||
|
|
346
|
+
config.key?(:phronomy_transfer_context)
|
|
347
|
+
return false unless config[:phronomy_execution_participant]
|
|
432
348
|
end
|
|
433
349
|
|
|
434
350
|
invocation_context = config[:invocation_context]
|
|
@@ -442,40 +358,40 @@ module Phronomy
|
|
|
442
358
|
|
|
443
359
|
def apply_initial_preparation_on_event_loop(ready)
|
|
444
360
|
request = ready.request
|
|
445
|
-
|
|
361
|
+
environment = @agent.__execution_environment
|
|
446
362
|
if ready.error
|
|
447
|
-
|
|
363
|
+
environment.registry.mark_agent_admission_recovery_required(
|
|
448
364
|
@agent.agent_id,
|
|
449
365
|
owner_token: request.admission_token
|
|
450
366
|
)
|
|
451
|
-
deliver_start_failure_on_event_loop(request,
|
|
367
|
+
deliver_start_failure_on_event_loop(request, ready.error)
|
|
452
368
|
return
|
|
453
369
|
end
|
|
454
370
|
|
|
455
371
|
result = ready.result
|
|
456
372
|
case result.admission_outcome
|
|
457
373
|
when :not_established
|
|
458
|
-
|
|
374
|
+
environment.registry.release_agent_execution_admission(
|
|
459
375
|
@agent.agent_id,
|
|
460
376
|
owner_token: request.admission_token
|
|
461
377
|
)
|
|
462
378
|
deliver_start_failure_on_event_loop(request, result.error)
|
|
463
379
|
return
|
|
464
380
|
when :outcome_unknown, :recovery_required
|
|
465
|
-
|
|
381
|
+
environment.registry.mark_agent_admission_recovery_required(
|
|
466
382
|
@agent.agent_id,
|
|
467
383
|
owner_token: request.admission_token
|
|
468
384
|
)
|
|
469
385
|
deliver_start_failure_on_event_loop(request, result.error)
|
|
470
386
|
return
|
|
471
387
|
when :active, :terminal
|
|
472
|
-
|
|
388
|
+
environment.registry.bind_agent_execution_admission(
|
|
473
389
|
@agent.agent_id,
|
|
474
390
|
owner_token: request.admission_token,
|
|
475
391
|
execution_id: result.execution.execution_id
|
|
476
392
|
)
|
|
477
393
|
else
|
|
478
|
-
|
|
394
|
+
environment.registry.mark_agent_admission_recovery_required(
|
|
479
395
|
@agent.agent_id,
|
|
480
396
|
owner_token: request.admission_token
|
|
481
397
|
)
|
|
@@ -488,7 +404,7 @@ module Phronomy
|
|
|
488
404
|
appended_records: result.appended_records
|
|
489
405
|
)
|
|
490
406
|
if result.admission_outcome == :terminal
|
|
491
|
-
|
|
407
|
+
environment.registry.release_agent_execution_admission(
|
|
492
408
|
@agent.agent_id,
|
|
493
409
|
execution_id: result.execution.execution_id
|
|
494
410
|
)
|
|
@@ -508,8 +424,7 @@ module Phronomy
|
|
|
508
424
|
end
|
|
509
425
|
|
|
510
426
|
def register_initial_session_on_event_loop(request, prepared)
|
|
511
|
-
|
|
512
|
-
event_loop = runtime.event_loop
|
|
427
|
+
environment = @agent.__execution_environment
|
|
513
428
|
Phronomy::Tracing::Automatic.observe_task(
|
|
514
429
|
request.result_task,
|
|
515
430
|
"agent.execution",
|
|
@@ -525,17 +440,17 @@ module Phronomy
|
|
|
525
440
|
phronomy_filtered_input: prepared.filtered_input,
|
|
526
441
|
execution_id: prepared.execution.execution_id
|
|
527
442
|
)
|
|
528
|
-
|
|
443
|
+
invocation = Agent::AgentInvocation.new(
|
|
529
444
|
agent: @agent,
|
|
530
445
|
input: prepared.filtered_input,
|
|
531
446
|
config: effective_config,
|
|
532
447
|
approval_policy: request.approval_policy,
|
|
533
448
|
approval_listener: request.approval_listener,
|
|
534
449
|
mode: request.mode,
|
|
535
|
-
|
|
536
|
-
runtime: runtime
|
|
450
|
+
event_listener: request.on_event
|
|
537
451
|
)
|
|
538
|
-
|
|
452
|
+
session = environment.build_agent_session(invocation: invocation)
|
|
453
|
+
environment.registry.install_agent_execution(
|
|
539
454
|
execution_id: prepared.execution.execution_id,
|
|
540
455
|
agent: @agent,
|
|
541
456
|
coordinator: self,
|
|
@@ -545,17 +460,17 @@ module Phronomy
|
|
|
545
460
|
invocation: session.context,
|
|
546
461
|
fsm_session_id: session.id
|
|
547
462
|
)
|
|
548
|
-
|
|
463
|
+
environment.registry.register_agent_completion_waiter(
|
|
549
464
|
prepared.execution.execution_id,
|
|
550
465
|
request.result_task
|
|
551
466
|
)
|
|
552
|
-
execution_session_runner(
|
|
467
|
+
execution_session_runner(environment).register(
|
|
553
468
|
session, request.result_task
|
|
554
469
|
)
|
|
555
470
|
# simplecov:disable
|
|
556
471
|
rescue => _error
|
|
557
|
-
|
|
558
|
-
|
|
472
|
+
environment.registry.release_agent_execution(prepared.execution.execution_id) if
|
|
473
|
+
environment&.executing? && environment.registry.agent_execution_state(prepared.execution.execution_id)
|
|
559
474
|
raise
|
|
560
475
|
end
|
|
561
476
|
# simplecov:enable
|
|
@@ -587,10 +502,9 @@ module Phronomy
|
|
|
587
502
|
result_task,
|
|
588
503
|
load_completion:
|
|
589
504
|
)
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(execution.execution_id)
|
|
505
|
+
environment = @agent.__execution_environment
|
|
506
|
+
assert_event_loop!(environment)
|
|
507
|
+
state = environment.registry.agent_execution_state(execution.execution_id)
|
|
594
508
|
unless state && state.agent.equal?(@agent) &&
|
|
595
509
|
state.execution.execution_revision == execution.execution_revision &&
|
|
596
510
|
state.execution.status == :preparing &&
|
|
@@ -605,10 +519,10 @@ module Phronomy
|
|
|
605
519
|
|
|
606
520
|
operation = InitialPreparation::RecoveryCommand.new(
|
|
607
521
|
execution: execution,
|
|
608
|
-
root: @agent.
|
|
522
|
+
root: @agent.send(:__root_for_operation),
|
|
609
523
|
journal_records: @agent.send(:_journal_records_snapshot)
|
|
610
524
|
)
|
|
611
|
-
task =
|
|
525
|
+
task = environment.submit(on_full: :raise) do
|
|
612
526
|
@initial_preparation.recover(operation)
|
|
613
527
|
end
|
|
614
528
|
task.on_complete do |result, error|
|
|
@@ -621,7 +535,7 @@ module Phronomy
|
|
|
621
535
|
result: result,
|
|
622
536
|
error: error
|
|
623
537
|
)
|
|
624
|
-
unless post_control(
|
|
538
|
+
unless post_control(environment, ready)
|
|
625
539
|
rejected = runtime_rejected_error(:initial_preparation_recovery)
|
|
626
540
|
fail_task(result_task, rejected)
|
|
627
541
|
load_completion.fail(rejected)
|
|
@@ -630,24 +544,24 @@ module Phronomy
|
|
|
630
544
|
rescue => error
|
|
631
545
|
# simplecov:disable
|
|
632
546
|
begin
|
|
633
|
-
if defined?(
|
|
547
|
+
if defined?(environment) && environment.executing?
|
|
634
548
|
release_initial_preparation_recovery_runtime_state(
|
|
635
|
-
|
|
549
|
+
environment,
|
|
636
550
|
execution.execution_id
|
|
637
551
|
)
|
|
638
552
|
end
|
|
639
553
|
rescue
|
|
640
554
|
nil
|
|
641
555
|
end
|
|
642
|
-
translated_error =
|
|
556
|
+
translated_error = error
|
|
643
557
|
fail_task(result_task, translated_error)
|
|
644
558
|
load_completion.fail(translated_error)
|
|
645
559
|
# simplecov:enable
|
|
646
560
|
end
|
|
647
561
|
|
|
648
562
|
def apply_initial_preparation_recovery_on_event_loop(ready)
|
|
649
|
-
|
|
650
|
-
state =
|
|
563
|
+
environment = @agent.__execution_environment
|
|
564
|
+
state = environment.registry.agent_execution_state(ready.execution_id)
|
|
651
565
|
unless state && state.agent.equal?(@agent) &&
|
|
652
566
|
state.execution.execution_revision == ready.expected_execution_revision &&
|
|
653
567
|
state.execution.status == :preparing &&
|
|
@@ -662,10 +576,10 @@ module Phronomy
|
|
|
662
576
|
|
|
663
577
|
if ready.error
|
|
664
578
|
release_initial_preparation_recovery_runtime_state(
|
|
665
|
-
|
|
579
|
+
environment,
|
|
666
580
|
ready.execution_id
|
|
667
581
|
)
|
|
668
|
-
error =
|
|
582
|
+
error = ready.error
|
|
669
583
|
fail_task(ready.result_task, error)
|
|
670
584
|
ready.load_completion.fail(error)
|
|
671
585
|
return
|
|
@@ -674,17 +588,17 @@ module Phronomy
|
|
|
674
588
|
result = ready.result
|
|
675
589
|
case result.admission_outcome
|
|
676
590
|
when :terminal
|
|
677
|
-
settle_failed_preparation_recovery_on_event_loop(ready,
|
|
591
|
+
settle_failed_preparation_recovery_on_event_loop(ready, environment)
|
|
678
592
|
ready.load_completion.complete(@agent)
|
|
679
593
|
when :active
|
|
680
|
-
restart_prepared_execution_on_event_loop(ready,
|
|
594
|
+
restart_prepared_execution_on_event_loop(ready, environment)
|
|
681
595
|
ready.load_completion.complete(@agent)
|
|
682
596
|
else
|
|
683
597
|
error = Phronomy::ExecutionRehydrationRequiredError.new(
|
|
684
598
|
"unexpected initial preparation Recovery outcome: #{result.admission_outcome.inspect}"
|
|
685
599
|
)
|
|
686
600
|
release_initial_preparation_recovery_runtime_state(
|
|
687
|
-
|
|
601
|
+
environment,
|
|
688
602
|
ready.execution_id
|
|
689
603
|
)
|
|
690
604
|
fail_task(ready.result_task, error)
|
|
@@ -694,30 +608,30 @@ module Phronomy
|
|
|
694
608
|
# simplecov:disable
|
|
695
609
|
begin
|
|
696
610
|
release_initial_preparation_recovery_runtime_state(
|
|
697
|
-
|
|
611
|
+
environment,
|
|
698
612
|
ready.execution_id
|
|
699
613
|
)
|
|
700
614
|
rescue
|
|
701
615
|
nil
|
|
702
616
|
end
|
|
703
|
-
translated_error =
|
|
617
|
+
translated_error = error
|
|
704
618
|
fail_task(ready.result_task, translated_error)
|
|
705
619
|
ready.load_completion.fail(translated_error)
|
|
706
620
|
# simplecov:enable
|
|
707
621
|
end
|
|
708
622
|
|
|
709
|
-
def settle_failed_preparation_recovery_on_event_loop(ready,
|
|
623
|
+
def settle_failed_preparation_recovery_on_event_loop(ready, environment)
|
|
710
624
|
result = ready.result
|
|
711
625
|
apply_agent_live_state(
|
|
712
626
|
root: result.root,
|
|
713
627
|
appended_records: result.appended_records
|
|
714
628
|
)
|
|
715
|
-
|
|
629
|
+
environment.registry.replace_agent_execution(
|
|
716
630
|
ready.execution_id,
|
|
717
631
|
execution: result.execution
|
|
718
632
|
)
|
|
719
|
-
|
|
720
|
-
|
|
633
|
+
environment.registry.release_agent_execution(ready.execution_id)
|
|
634
|
+
environment.registry.release_agent_execution_admission(
|
|
721
635
|
@agent.agent_id,
|
|
722
636
|
execution_id: ready.execution_id
|
|
723
637
|
)
|
|
@@ -736,13 +650,13 @@ module Phronomy
|
|
|
736
650
|
)
|
|
737
651
|
end
|
|
738
652
|
|
|
739
|
-
def restart_prepared_execution_on_event_loop(ready,
|
|
653
|
+
def restart_prepared_execution_on_event_loop(ready, environment)
|
|
740
654
|
result = ready.result
|
|
741
655
|
apply_agent_live_state(
|
|
742
656
|
root: result.root,
|
|
743
657
|
appended_records: result.appended_records
|
|
744
658
|
)
|
|
745
|
-
|
|
659
|
+
environment.registry.release_agent_execution(ready.execution_id)
|
|
746
660
|
mode = (
|
|
747
661
|
result.execution.metadata[ExecutionMetadata::INVOCATION_MODE_KEY] ||
|
|
748
662
|
"invoke"
|
|
@@ -756,7 +670,8 @@ module Phronomy
|
|
|
756
670
|
approval_listener: nil,
|
|
757
671
|
on_event: @agent.send(:_phronomy_event_listener),
|
|
758
672
|
result_task: ready.result_task,
|
|
759
|
-
admission_token: Object.new.freeze
|
|
673
|
+
admission_token: Object.new.freeze,
|
|
674
|
+
controls: nil
|
|
760
675
|
)
|
|
761
676
|
begin
|
|
762
677
|
register_initial_session_on_event_loop(request, result)
|
|
@@ -770,12 +685,12 @@ module Phronomy
|
|
|
770
685
|
end
|
|
771
686
|
|
|
772
687
|
def release_initial_preparation_recovery_runtime_state(
|
|
773
|
-
|
|
688
|
+
environment,
|
|
774
689
|
execution_id
|
|
775
690
|
)
|
|
776
|
-
state =
|
|
777
|
-
|
|
778
|
-
|
|
691
|
+
state = environment.registry.agent_execution_state(execution_id)
|
|
692
|
+
environment.registry.release_agent_execution(execution_id) if state
|
|
693
|
+
environment.registry.release_agent_execution_admission(
|
|
779
694
|
@agent.agent_id,
|
|
780
695
|
execution_id: execution_id
|
|
781
696
|
)
|
|
@@ -786,11 +701,11 @@ module Phronomy
|
|
|
786
701
|
# ----------------------------------------------------------------------
|
|
787
702
|
|
|
788
703
|
def dispatch_preparation_state!(invocation, event_sink, phase:, kind:)
|
|
789
|
-
|
|
790
|
-
assert_event_loop!(
|
|
791
|
-
state =
|
|
704
|
+
environment = @agent.__execution_environment
|
|
705
|
+
assert_event_loop!(environment)
|
|
706
|
+
state = environment.registry.agent_execution_state(invocation.execution_id)
|
|
792
707
|
validate_live_session!(state, invocation, event_sink.fsm_session_id)
|
|
793
|
-
unless
|
|
708
|
+
unless environment.session_phase(event_sink.fsm_session_id) == phase
|
|
794
709
|
raise Phronomy::Error,
|
|
795
710
|
"#{kind} dispatch preparation requires the owning FSMSession to be in #{phase.inspect}"
|
|
796
711
|
end
|
|
@@ -802,7 +717,7 @@ module Phronomy
|
|
|
802
717
|
execution_id: state.execution_id,
|
|
803
718
|
fsm_session_id: fsm_session_id.to_s.freeze,
|
|
804
719
|
expected_execution_revision: state.execution.execution_revision,
|
|
805
|
-
root: @agent.
|
|
720
|
+
root: @agent.send(:__root_for_operation),
|
|
806
721
|
journal_records: @agent.send(:_journal_records_snapshot),
|
|
807
722
|
execution: state.execution,
|
|
808
723
|
base_manifest: state.base_manifest,
|
|
@@ -824,10 +739,11 @@ module Phronomy
|
|
|
824
739
|
execution_id: state.execution_id,
|
|
825
740
|
fsm_session_id: fsm_session_id.to_s.freeze,
|
|
826
741
|
expected_execution_revision: state.execution.execution_revision,
|
|
827
|
-
root: @agent.
|
|
742
|
+
root: @agent.send(:__root_for_operation),
|
|
828
743
|
execution: state.execution,
|
|
829
744
|
runtime_snapshot: invocation.runtime_snapshot,
|
|
830
|
-
tool_batch_snapshot: tool_batch_snapshot
|
|
745
|
+
tool_batch_snapshot: tool_batch_snapshot,
|
|
746
|
+
invocation_config: invocation.config.dup.freeze
|
|
831
747
|
)
|
|
832
748
|
end
|
|
833
749
|
|
|
@@ -842,13 +758,10 @@ module Phronomy
|
|
|
842
758
|
return unless state
|
|
843
759
|
|
|
844
760
|
if ready.error
|
|
845
|
-
if ready.error.is_a?(
|
|
846
|
-
|
|
847
|
-
operation,
|
|
848
|
-
ready.error
|
|
849
|
-
)
|
|
761
|
+
if ready.error.is_a?(Phronomy::ExecutionRehydrationRequiredError)
|
|
762
|
+
mark_barrier_recovery_required(operation, ready.error)
|
|
850
763
|
else
|
|
851
|
-
state.invocation.event_sink.post(:llm_setup_failed,
|
|
764
|
+
state.invocation.event_sink.post(:llm_setup_failed, ready.error)
|
|
852
765
|
end
|
|
853
766
|
return
|
|
854
767
|
end
|
|
@@ -859,7 +772,7 @@ module Phronomy
|
|
|
859
772
|
state
|
|
860
773
|
)
|
|
861
774
|
rescue => error
|
|
862
|
-
state&.invocation&.event_sink&.post(:llm_setup_failed,
|
|
775
|
+
state&.invocation&.event_sink&.post(:llm_setup_failed, error)
|
|
863
776
|
end
|
|
864
777
|
|
|
865
778
|
def apply_tool_dispatch_preparation_on_event_loop(ready)
|
|
@@ -873,13 +786,10 @@ module Phronomy
|
|
|
873
786
|
return unless state
|
|
874
787
|
|
|
875
788
|
if ready.error
|
|
876
|
-
if ready.error.is_a?(
|
|
877
|
-
|
|
878
|
-
operation,
|
|
879
|
-
ready.error
|
|
880
|
-
)
|
|
789
|
+
if ready.error.is_a?(Phronomy::ExecutionRehydrationRequiredError)
|
|
790
|
+
mark_barrier_recovery_required(operation, ready.error)
|
|
881
791
|
else
|
|
882
|
-
state.invocation.event_sink.post(:tool_setup_failed,
|
|
792
|
+
state.invocation.event_sink.post(:tool_setup_failed, ready.error)
|
|
883
793
|
end
|
|
884
794
|
return
|
|
885
795
|
end
|
|
@@ -890,7 +800,7 @@ module Phronomy
|
|
|
890
800
|
state
|
|
891
801
|
)
|
|
892
802
|
rescue => error
|
|
893
|
-
state&.invocation&.event_sink&.post(:tool_setup_failed,
|
|
803
|
+
state&.invocation&.event_sink&.post(:tool_setup_failed, error)
|
|
894
804
|
end
|
|
895
805
|
|
|
896
806
|
def apply_confirmed_provider_dispatch_preparation_on_event_loop(
|
|
@@ -898,15 +808,15 @@ module Phronomy
|
|
|
898
808
|
result,
|
|
899
809
|
state
|
|
900
810
|
)
|
|
901
|
-
|
|
811
|
+
environment = @agent.__execution_environment
|
|
902
812
|
if result.runtime_projection
|
|
903
|
-
|
|
813
|
+
environment.registry.replace_agent_execution(
|
|
904
814
|
operation.execution_id,
|
|
905
815
|
execution: result.execution,
|
|
906
816
|
runtime_projection: result.runtime_projection
|
|
907
817
|
)
|
|
908
818
|
else
|
|
909
|
-
|
|
819
|
+
environment.registry.replace_agent_execution(
|
|
910
820
|
operation.execution_id,
|
|
911
821
|
execution: result.execution
|
|
912
822
|
)
|
|
@@ -914,13 +824,13 @@ module Phronomy
|
|
|
914
824
|
state.invocation.acknowledge_runtime_snapshot(operation.runtime_snapshot)
|
|
915
825
|
|
|
916
826
|
if result.error
|
|
917
|
-
state.invocation.event_sink.post(:llm_setup_failed,
|
|
827
|
+
state.invocation.event_sink.post(:llm_setup_failed, result.error)
|
|
918
828
|
return
|
|
919
829
|
end
|
|
920
830
|
|
|
921
|
-
Agent::
|
|
831
|
+
Agent::InvocationActions.start_prepared_provider_call(
|
|
922
832
|
agent: @agent,
|
|
923
|
-
|
|
833
|
+
environment: @agent.__execution_environment,
|
|
924
834
|
event_sink: state.invocation.event_sink,
|
|
925
835
|
invocation: state.invocation,
|
|
926
836
|
projection: result.runtime_projection,
|
|
@@ -933,106 +843,27 @@ module Phronomy
|
|
|
933
843
|
result,
|
|
934
844
|
state
|
|
935
845
|
)
|
|
936
|
-
|
|
937
|
-
|
|
846
|
+
environment = @agent.__execution_environment
|
|
847
|
+
environment.registry.replace_agent_execution(
|
|
938
848
|
operation.execution_id,
|
|
939
849
|
execution: result.execution
|
|
940
850
|
)
|
|
941
851
|
state.invocation.acknowledge_runtime_snapshot(operation.runtime_snapshot)
|
|
942
|
-
Agent::
|
|
943
|
-
|
|
852
|
+
Agent::InvocationActions.start_prepared_tool_dispatch(
|
|
853
|
+
environment: @agent.__execution_environment,
|
|
944
854
|
event_sink: state.invocation.event_sink,
|
|
945
855
|
invocation: state.invocation
|
|
946
856
|
)
|
|
947
857
|
end
|
|
948
858
|
|
|
949
|
-
def apply_provider_dispatch_preparation_reconciliation_on_event_loop(ready)
|
|
950
|
-
command = ready.command
|
|
951
|
-
operation = command.operation
|
|
952
|
-
state = authoritative_state_for_operation(
|
|
953
|
-
execution_id: operation.execution_id,
|
|
954
|
-
fsm_session_id: operation.fsm_session_id,
|
|
955
|
-
expected_execution_revision: operation.expected_execution_revision,
|
|
956
|
-
expected_fsm_state: :calling_llm
|
|
957
|
-
)
|
|
958
|
-
return unless state
|
|
959
|
-
|
|
960
|
-
if ready.error
|
|
961
|
-
mark_barrier_recovery_required(operation, ready.error)
|
|
962
|
-
return
|
|
963
|
-
end
|
|
964
|
-
|
|
965
|
-
case ready.result.disposition
|
|
966
|
-
when :committed
|
|
967
|
-
apply_confirmed_provider_dispatch_preparation_on_event_loop(
|
|
968
|
-
operation,
|
|
969
|
-
ready.result.preparation_result,
|
|
970
|
-
state
|
|
971
|
-
)
|
|
972
|
-
when :not_committed
|
|
973
|
-
state.invocation.event_sink.post(
|
|
974
|
-
:llm_setup_failed,
|
|
975
|
-
translated(command.original_error)
|
|
976
|
-
)
|
|
977
|
-
when :conflict
|
|
978
|
-
mark_barrier_recovery_required(operation, command.original_error)
|
|
979
|
-
else
|
|
980
|
-
raise Phronomy::Error,
|
|
981
|
-
"unknown Provider dispatch reconciliation disposition: " \
|
|
982
|
-
"#{ready.result.disposition.inspect}"
|
|
983
|
-
end
|
|
984
|
-
rescue => error
|
|
985
|
-
mark_barrier_recovery_required(operation, error)
|
|
986
|
-
end
|
|
987
|
-
|
|
988
|
-
def apply_tool_dispatch_preparation_reconciliation_on_event_loop(ready)
|
|
989
|
-
command = ready.command
|
|
990
|
-
operation = command.operation
|
|
991
|
-
state = authoritative_state_for_operation(
|
|
992
|
-
execution_id: operation.execution_id,
|
|
993
|
-
fsm_session_id: operation.fsm_session_id,
|
|
994
|
-
expected_execution_revision: operation.expected_execution_revision,
|
|
995
|
-
expected_fsm_state: :dispatching_tools
|
|
996
|
-
)
|
|
997
|
-
return unless state
|
|
998
|
-
|
|
999
|
-
if ready.error
|
|
1000
|
-
mark_barrier_recovery_required(operation, ready.error)
|
|
1001
|
-
return
|
|
1002
|
-
end
|
|
1003
|
-
|
|
1004
|
-
case ready.result.disposition
|
|
1005
|
-
when :committed
|
|
1006
|
-
apply_confirmed_tool_dispatch_preparation_on_event_loop(
|
|
1007
|
-
operation,
|
|
1008
|
-
ready.result.preparation_result,
|
|
1009
|
-
state
|
|
1010
|
-
)
|
|
1011
|
-
when :not_committed
|
|
1012
|
-
state.invocation.event_sink.post(
|
|
1013
|
-
:tool_setup_failed,
|
|
1014
|
-
translated(command.original_error)
|
|
1015
|
-
)
|
|
1016
|
-
when :conflict
|
|
1017
|
-
mark_barrier_recovery_required(operation, command.original_error)
|
|
1018
|
-
else
|
|
1019
|
-
raise Phronomy::Error,
|
|
1020
|
-
"unknown Tool dispatch reconciliation disposition: " \
|
|
1021
|
-
"#{ready.result.disposition.inspect}"
|
|
1022
|
-
end
|
|
1023
|
-
rescue => error
|
|
1024
|
-
mark_barrier_recovery_required(operation, error)
|
|
1025
|
-
# simplecov:enable
|
|
1026
|
-
end
|
|
1027
|
-
|
|
1028
859
|
def mark_barrier_recovery_required(operation, error)
|
|
1029
|
-
|
|
1030
|
-
|
|
860
|
+
environment = @agent.__execution_environment
|
|
861
|
+
environment.registry.mark_agent_execution_admission(
|
|
1031
862
|
@agent.agent_id,
|
|
1032
863
|
execution_id: operation.execution_id,
|
|
1033
864
|
state: :recovery_required
|
|
1034
865
|
)
|
|
1035
|
-
Phronomy.
|
|
866
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1036
867
|
"[Phronomy] causal durable barrier requires recovery for " \
|
|
1037
868
|
"#{operation.execution_id}: #{error.class}: #{error.message}"
|
|
1038
869
|
)
|
|
@@ -1043,9 +874,8 @@ module Phronomy
|
|
|
1043
874
|
# ----------------------------------------------------------------------
|
|
1044
875
|
|
|
1045
876
|
def begin_resume_on_event_loop(request)
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(request.execution_id)
|
|
877
|
+
environment = @agent.__execution_environment
|
|
878
|
+
state = environment.registry.agent_execution_state(request.execution_id)
|
|
1049
879
|
unless state
|
|
1050
880
|
fail_task(
|
|
1051
881
|
request.result_task,
|
|
@@ -1081,16 +911,17 @@ module Phronomy
|
|
|
1081
911
|
operation = capture_approval_resume(state, request)
|
|
1082
912
|
resume_transition_started = false
|
|
1083
913
|
submitted = false
|
|
1084
|
-
|
|
914
|
+
environment.registry.mark_agent_execution_admission(
|
|
1085
915
|
@agent.agent_id,
|
|
1086
916
|
execution_id: state.execution_id,
|
|
1087
917
|
state: :resuming
|
|
1088
918
|
)
|
|
1089
919
|
resume_transition_started = true
|
|
1090
|
-
task =
|
|
920
|
+
task = environment.submit(on_full: :raise) do
|
|
1091
921
|
@approval_resume_commit.commit(operation)
|
|
1092
922
|
end
|
|
1093
923
|
submitted = true
|
|
924
|
+
request.result_task.track(task) if request.result_task.respond_to?(:track)
|
|
1094
925
|
task.on_complete do |result, error|
|
|
1095
926
|
ready = ResumeCommitReady.new(
|
|
1096
927
|
coordinator: self,
|
|
@@ -1100,17 +931,17 @@ module Phronomy
|
|
|
1100
931
|
error: error
|
|
1101
932
|
)
|
|
1102
933
|
fail_task(request.result_task, runtime_rejected_error(:resume_commit)) unless
|
|
1103
|
-
post_control(
|
|
934
|
+
post_control(environment, ready)
|
|
1104
935
|
end
|
|
1105
936
|
rescue => error
|
|
1106
937
|
if resume_transition_started
|
|
1107
|
-
|
|
938
|
+
environment.registry.mark_agent_execution_admission(
|
|
1108
939
|
@agent.agent_id,
|
|
1109
940
|
execution_id: state.execution_id,
|
|
1110
941
|
state: submitted ? :recovery_required : :suspended
|
|
1111
942
|
)
|
|
1112
943
|
end
|
|
1113
|
-
fail_task(request.result_task,
|
|
944
|
+
fail_task(request.result_task, error)
|
|
1114
945
|
raise unless resume_transition_started
|
|
1115
946
|
end
|
|
1116
947
|
|
|
@@ -1123,7 +954,7 @@ module Phronomy
|
|
|
1123
954
|
ResumeCommitCommand.new(
|
|
1124
955
|
execution_id: state.execution_id,
|
|
1125
956
|
expected_execution_revision: state.execution.execution_revision,
|
|
1126
|
-
root: @agent.
|
|
957
|
+
root: @agent.send(:__root_for_operation),
|
|
1127
958
|
execution: state.execution,
|
|
1128
959
|
approval_request_id: request.approval_request_id,
|
|
1129
960
|
approved: request.approved,
|
|
@@ -1134,8 +965,8 @@ module Phronomy
|
|
|
1134
965
|
def apply_resume_commit_on_event_loop(ready)
|
|
1135
966
|
request = ready.request
|
|
1136
967
|
operation = ready.operation
|
|
1137
|
-
|
|
1138
|
-
state =
|
|
968
|
+
environment = @agent.__execution_environment
|
|
969
|
+
state = environment.registry.agent_execution_state(operation.execution_id)
|
|
1139
970
|
unless state && state.agent.equal?(@agent) &&
|
|
1140
971
|
state.execution.execution_revision == operation.expected_execution_revision &&
|
|
1141
972
|
state.execution.status == :suspended
|
|
@@ -1149,23 +980,23 @@ module Phronomy
|
|
|
1149
980
|
end
|
|
1150
981
|
|
|
1151
982
|
if ready.error
|
|
1152
|
-
|
|
983
|
+
environment.registry.mark_agent_execution_admission(
|
|
1153
984
|
@agent.agent_id,
|
|
1154
985
|
execution_id: operation.execution_id,
|
|
1155
986
|
state: :recovery_required
|
|
1156
987
|
)
|
|
1157
|
-
fail_task(request.result_task,
|
|
988
|
+
fail_task(request.result_task, ready.error)
|
|
1158
989
|
return
|
|
1159
990
|
end
|
|
1160
991
|
|
|
1161
|
-
install_resumed_execution_on_event_loop(ready,
|
|
992
|
+
install_resumed_execution_on_event_loop(ready, environment)
|
|
1162
993
|
observe_resumed_execution(ready, state)
|
|
1163
|
-
execution_session_runner(
|
|
994
|
+
execution_session_runner(@agent.__execution_environment).resume_approval(
|
|
1164
995
|
state.invocation, request.result_task,
|
|
1165
996
|
approved: request.approved, config: request.config
|
|
1166
997
|
)
|
|
1167
998
|
rescue => error
|
|
1168
|
-
state =
|
|
999
|
+
state = environment.registry.agent_execution_state(operation.execution_id) if environment&.executing?
|
|
1169
1000
|
if state
|
|
1170
1001
|
begin_terminal_commit_on_event_loop(
|
|
1171
1002
|
state,
|
|
@@ -1175,24 +1006,24 @@ module Phronomy
|
|
|
1175
1006
|
fsm_session_id: state.fsm_session_id
|
|
1176
1007
|
)
|
|
1177
1008
|
else
|
|
1178
|
-
fail_task(request.result_task,
|
|
1009
|
+
fail_task(request.result_task, error)
|
|
1179
1010
|
end
|
|
1180
1011
|
end
|
|
1181
1012
|
|
|
1182
|
-
def install_resumed_execution_on_event_loop(ready,
|
|
1013
|
+
def install_resumed_execution_on_event_loop(ready, environment)
|
|
1183
1014
|
request = ready.request
|
|
1184
1015
|
operation = ready.operation
|
|
1185
1016
|
apply_agent_live_state(root: ready.result.root, appended_records: [])
|
|
1186
|
-
|
|
1017
|
+
environment.registry.mark_agent_execution_admission(
|
|
1187
1018
|
@agent.agent_id,
|
|
1188
1019
|
execution_id: operation.execution_id,
|
|
1189
1020
|
state: :executing
|
|
1190
1021
|
)
|
|
1191
|
-
|
|
1022
|
+
environment.registry.replace_agent_execution(
|
|
1192
1023
|
operation.execution_id,
|
|
1193
1024
|
execution: ready.result.execution
|
|
1194
1025
|
)
|
|
1195
|
-
|
|
1026
|
+
environment.registry.register_agent_completion_waiter(
|
|
1196
1027
|
operation.execution_id,
|
|
1197
1028
|
request.result_task
|
|
1198
1029
|
)
|
|
@@ -1227,20 +1058,20 @@ module Phronomy
|
|
|
1227
1058
|
raise Phronomy::ExecutionRehydrationRequiredError,
|
|
1228
1059
|
"initial preparation continuation requires a :preparing execution"
|
|
1229
1060
|
end
|
|
1230
|
-
|
|
1061
|
+
@agent.__execution_environment.registry.mark_agent_execution_admission(
|
|
1231
1062
|
@agent.agent_id, execution_id: state.execution_id, state: :executing
|
|
1232
1063
|
)
|
|
1233
1064
|
start_initial_preparation_recovery_on_event_loop(
|
|
1234
1065
|
state.execution, command.result_task, load_completion: command.load_completion
|
|
1235
1066
|
)
|
|
1236
1067
|
rescue => error
|
|
1237
|
-
fail_task(command.result_task,
|
|
1238
|
-
command.load_completion.fail(
|
|
1068
|
+
fail_task(command.result_task, error)
|
|
1069
|
+
command.load_completion.fail(error)
|
|
1239
1070
|
end
|
|
1240
1071
|
|
|
1241
1072
|
def continue_recovered_on_event_loop(command)
|
|
1242
|
-
|
|
1243
|
-
registry =
|
|
1073
|
+
environment = @agent.__execution_environment
|
|
1074
|
+
registry = environment.registry
|
|
1244
1075
|
state = recovered_execution_state!(command)
|
|
1245
1076
|
validate_recovered_continuation!(state.execution, command.continuation)
|
|
1246
1077
|
invocation = command.invocation
|
|
@@ -1265,7 +1096,7 @@ module Phronomy
|
|
|
1265
1096
|
registry.mark_agent_execution_admission(@agent.agent_id,
|
|
1266
1097
|
execution_id: state.execution_id, state: :executing)
|
|
1267
1098
|
registry.register_agent_completion_waiter(state.execution_id, command.result_task)
|
|
1268
|
-
runner = execution_session_runner(
|
|
1099
|
+
runner = execution_session_runner(environment)
|
|
1269
1100
|
case command.continuation
|
|
1270
1101
|
when :approval_rejection
|
|
1271
1102
|
runner.resume_approval(invocation, command.result_task, approved: false, config: {})
|
|
@@ -1281,7 +1112,7 @@ module Phronomy
|
|
|
1281
1112
|
end
|
|
1282
1113
|
|
|
1283
1114
|
def recovered_execution_state!(command)
|
|
1284
|
-
state =
|
|
1115
|
+
state = @agent.__execution_environment.registry.agent_execution_state(command.execution_id)
|
|
1285
1116
|
unless command.coordinator.equal?(self) && state && state.agent.equal?(@agent) &&
|
|
1286
1117
|
state.coordinator.equal?(self) && state.execution.active? &&
|
|
1287
1118
|
state.execution.execution_revision == command.expected_execution_revision &&
|
|
@@ -1292,8 +1123,8 @@ module Phronomy
|
|
|
1292
1123
|
state
|
|
1293
1124
|
end
|
|
1294
1125
|
|
|
1295
|
-
def execution_session_runner(
|
|
1296
|
-
ExecutionSessionRunner.new(
|
|
1126
|
+
def execution_session_runner(environment)
|
|
1127
|
+
ExecutionSessionRunner.new(environment: environment, on_complete: ->(**result) {
|
|
1297
1128
|
deliver_on_event_loop(SessionFinishedCommand.new(coordinator: self, **result))
|
|
1298
1129
|
})
|
|
1299
1130
|
end
|
|
@@ -1327,9 +1158,9 @@ module Phronomy
|
|
|
1327
1158
|
# ----------------------------------------------------------------------
|
|
1328
1159
|
|
|
1329
1160
|
def finish_on_event_loop(execution_id, result_task, invocation, error, fsm_session_id:)
|
|
1330
|
-
|
|
1331
|
-
assert_event_loop!(
|
|
1332
|
-
state =
|
|
1161
|
+
environment = @agent.__execution_environment
|
|
1162
|
+
assert_event_loop!(environment)
|
|
1163
|
+
state = environment.registry.agent_execution_state(execution_id)
|
|
1333
1164
|
return fail_task(result_task, runtime_rejected_error(:terminal)) unless state
|
|
1334
1165
|
|
|
1335
1166
|
unless state.agent.equal?(@agent) && state.coordinator.equal?(self) &&
|
|
@@ -1342,15 +1173,15 @@ module Phronomy
|
|
|
1342
1173
|
end
|
|
1343
1174
|
|
|
1344
1175
|
terminal_error = error || invocation&.error
|
|
1345
|
-
unless
|
|
1176
|
+
unless environment.registry.agent_execution_quiescent?(execution_id)
|
|
1346
1177
|
wait_state = quiescence_sensitive_terminal_error?(terminal_error) ?
|
|
1347
1178
|
:cancelling : :terminalizing
|
|
1348
|
-
|
|
1179
|
+
environment.registry.mark_agent_execution_admission(
|
|
1349
1180
|
@agent.agent_id,
|
|
1350
1181
|
execution_id: execution_id,
|
|
1351
1182
|
state: wait_state
|
|
1352
1183
|
)
|
|
1353
|
-
|
|
1184
|
+
environment.registry.defer_agent_terminal_until_quiescent(
|
|
1354
1185
|
execution_id,
|
|
1355
1186
|
DeferredTerminalCommand.new(
|
|
1356
1187
|
coordinator: self,
|
|
@@ -1374,18 +1205,18 @@ module Phronomy
|
|
|
1374
1205
|
end
|
|
1375
1206
|
|
|
1376
1207
|
def resume_deferred_terminal_on_event_loop(command)
|
|
1377
|
-
|
|
1378
|
-
state =
|
|
1208
|
+
environment = @agent.__execution_environment
|
|
1209
|
+
state = environment.registry.agent_execution_state(command.execution_id)
|
|
1379
1210
|
unless state && state.agent.equal?(@agent) &&
|
|
1380
1211
|
state.fsm_session_id.to_s == command.fsm_session_id.to_s &&
|
|
1381
1212
|
state.invocation.equal?(command.invocation)
|
|
1382
|
-
Phronomy.
|
|
1213
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1383
1214
|
"[Phronomy] Dropped stale deferred terminal for #{command.execution_id}"
|
|
1384
1215
|
)
|
|
1385
1216
|
return
|
|
1386
1217
|
end
|
|
1387
1218
|
|
|
1388
|
-
unless
|
|
1219
|
+
unless environment.registry.agent_execution_quiescent?(command.execution_id)
|
|
1389
1220
|
raise Phronomy::Error,
|
|
1390
1221
|
"deferred terminal resumed before quiescence for #{command.execution_id}"
|
|
1391
1222
|
end
|
|
@@ -1424,7 +1255,7 @@ module Phronomy
|
|
|
1424
1255
|
|
|
1425
1256
|
operation = build_terminal_operation(
|
|
1426
1257
|
execution: state.execution,
|
|
1427
|
-
root: @agent.
|
|
1258
|
+
root: @agent.send(:__root_for_operation),
|
|
1428
1259
|
journal_records: @agent.send(:_journal_records_snapshot),
|
|
1429
1260
|
invocation: invocation,
|
|
1430
1261
|
source_error: source_error,
|
|
@@ -1442,7 +1273,7 @@ module Phronomy
|
|
|
1442
1273
|
end
|
|
1443
1274
|
|
|
1444
1275
|
def begin_terminal_without_session_on_event_loop(request:, prepared:, error:)
|
|
1445
|
-
return deliver_start_failure_on_event_loop(request,
|
|
1276
|
+
return deliver_start_failure_on_event_loop(request, error) unless prepared&.execution
|
|
1446
1277
|
|
|
1447
1278
|
operation = build_terminal_operation(
|
|
1448
1279
|
execution: prepared.execution,
|
|
@@ -1481,7 +1312,8 @@ module Phronomy
|
|
|
1481
1312
|
execution: execution,
|
|
1482
1313
|
runtime_snapshot: invocation ? invocation.runtime_snapshot : empty_runtime_snapshot,
|
|
1483
1314
|
terminal_view: terminal_view(invocation, source_error),
|
|
1484
|
-
state_required: state_required
|
|
1315
|
+
state_required: state_required,
|
|
1316
|
+
wiring: (invocation ? invocation.config : @agent.__execution_wiring).dup.freeze
|
|
1485
1317
|
)
|
|
1486
1318
|
end
|
|
1487
1319
|
|
|
@@ -1490,24 +1322,24 @@ module Phronomy
|
|
|
1490
1322
|
end
|
|
1491
1323
|
|
|
1492
1324
|
def submit_terminal_operation(operation, delivery)
|
|
1493
|
-
|
|
1494
|
-
event_loop = runtime.event_loop
|
|
1325
|
+
environment = @agent.__execution_environment
|
|
1495
1326
|
terminal_transition_started = false
|
|
1496
|
-
|
|
1327
|
+
environment.registry.mark_agent_execution_admission(
|
|
1497
1328
|
@agent.agent_id,
|
|
1498
1329
|
execution_id: operation.execution_id,
|
|
1499
1330
|
state: :terminalizing
|
|
1500
1331
|
)
|
|
1501
1332
|
terminal_transition_started = true
|
|
1502
|
-
|
|
1333
|
+
environment.registry.register_agent_completion_waiter(
|
|
1503
1334
|
operation.execution_id,
|
|
1504
1335
|
delivery.result_task
|
|
1505
1336
|
)
|
|
1506
|
-
task =
|
|
1337
|
+
task = environment.submit(on_full: :raise) do
|
|
1507
1338
|
# Only the operation-specific immutable durable snapshot crosses the
|
|
1508
1339
|
# worker boundary. TaskResult/listener delivery state stays outside it.
|
|
1509
1340
|
@outcome_committer.commit_outcome(operation)
|
|
1510
1341
|
end
|
|
1342
|
+
delivery.result_task.track(task) if delivery.result_task.respond_to?(:track)
|
|
1511
1343
|
task.on_complete do |outcome, error|
|
|
1512
1344
|
ready = TerminalCommitReady.new(
|
|
1513
1345
|
coordinator: self,
|
|
@@ -1517,23 +1349,23 @@ module Phronomy
|
|
|
1517
1349
|
error: error
|
|
1518
1350
|
)
|
|
1519
1351
|
fail_task(delivery.result_task, runtime_rejected_error(:terminal_apply)) unless
|
|
1520
|
-
post_control(
|
|
1352
|
+
post_control(environment, ready)
|
|
1521
1353
|
end
|
|
1522
1354
|
rescue => error
|
|
1523
1355
|
if terminal_transition_started
|
|
1524
|
-
|
|
1356
|
+
environment.registry.mark_agent_execution_admission(
|
|
1525
1357
|
@agent.agent_id,
|
|
1526
1358
|
execution_id: operation.execution_id,
|
|
1527
1359
|
state: :recovery_required
|
|
1528
1360
|
)
|
|
1529
|
-
Phronomy.
|
|
1361
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1530
1362
|
"[Phronomy] Agent terminal transition requires recovery for " \
|
|
1531
1363
|
"#{operation.execution_id}: #{error.class}: #{error.message}"
|
|
1532
1364
|
)
|
|
1533
1365
|
return
|
|
1534
1366
|
end
|
|
1535
1367
|
|
|
1536
|
-
fail_task(delivery.result_task,
|
|
1368
|
+
fail_task(delivery.result_task, error)
|
|
1537
1369
|
raise
|
|
1538
1370
|
end
|
|
1539
1371
|
|
|
@@ -1555,20 +1387,7 @@ module Phronomy
|
|
|
1555
1387
|
)
|
|
1556
1388
|
end
|
|
1557
1389
|
|
|
1558
|
-
def handoff_terminal_view(request)
|
|
1559
|
-
return unless request
|
|
1560
|
-
|
|
1561
|
-
HandoffTerminalView.new(
|
|
1562
|
-
target_agent_id: request.handoff.target_agent.agent_id.to_s.freeze,
|
|
1563
|
-
responsibility: request.responsibility.to_s.freeze,
|
|
1564
|
-
selection_intent: request.selection_intent.to_h do |category, included|
|
|
1565
|
-
[category.to_s.freeze, !!included]
|
|
1566
|
-
end.freeze,
|
|
1567
|
-
llm_call_id: request.llm_call_id&.to_s&.freeze,
|
|
1568
|
-
tool_call_id: request.tool_call_id&.to_s&.freeze,
|
|
1569
|
-
policy: Phronomy::Values::Immutable.copy(request.handoff.policy.to_h)
|
|
1570
|
-
)
|
|
1571
|
-
end
|
|
1390
|
+
def handoff_terminal_view(request) = request
|
|
1572
1391
|
|
|
1573
1392
|
def empty_runtime_snapshot
|
|
1574
1393
|
{llm_results: [].freeze, runtime_events: [].freeze, active_call: nil}.freeze
|
|
@@ -1577,14 +1396,14 @@ module Phronomy
|
|
|
1577
1396
|
def apply_terminal_commit_on_event_loop(ready)
|
|
1578
1397
|
operation = ready.operation
|
|
1579
1398
|
delivery = ready.delivery
|
|
1580
|
-
|
|
1581
|
-
state =
|
|
1399
|
+
environment = @agent.__execution_environment
|
|
1400
|
+
state = environment.registry.agent_execution_state(operation.execution_id)
|
|
1582
1401
|
|
|
1583
1402
|
if operation.state_required
|
|
1584
1403
|
unless state && state.agent.equal?(@agent) &&
|
|
1585
1404
|
state.execution.execution_revision == operation.expected_execution_revision &&
|
|
1586
1405
|
state.fsm_session_id.to_s == operation.fsm_session_id.to_s
|
|
1587
|
-
Phronomy.
|
|
1406
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1588
1407
|
"[Phronomy] Dropped stale Agent terminal result for #{operation.execution_id}"
|
|
1589
1408
|
)
|
|
1590
1409
|
return
|
|
@@ -1592,23 +1411,23 @@ module Phronomy
|
|
|
1592
1411
|
end
|
|
1593
1412
|
|
|
1594
1413
|
if ready.error
|
|
1595
|
-
handle_terminal_commit_error_on_event_loop(ready, state,
|
|
1414
|
+
handle_terminal_commit_error_on_event_loop(ready, state, environment)
|
|
1596
1415
|
return
|
|
1597
1416
|
end
|
|
1598
1417
|
|
|
1599
|
-
apply_terminal_outcome_state_on_event_loop(ready, state,
|
|
1418
|
+
apply_terminal_outcome_state_on_event_loop(ready, state, environment)
|
|
1600
1419
|
outcome = ready.outcome
|
|
1601
1420
|
case outcome.type
|
|
1602
1421
|
when :coordination_wait
|
|
1603
|
-
release_coordination_wait_on_event_loop(ready, state,
|
|
1422
|
+
release_coordination_wait_on_event_loop(ready, state, environment)
|
|
1604
1423
|
when :suspended
|
|
1605
|
-
suspend_execution_on_event_loop(ready, state,
|
|
1424
|
+
suspend_execution_on_event_loop(ready, state, environment)
|
|
1606
1425
|
when :completed
|
|
1607
|
-
deliver_completed_execution_on_event_loop(ready, state,
|
|
1426
|
+
deliver_completed_execution_on_event_loop(ready, state, environment)
|
|
1608
1427
|
when :handed_off
|
|
1609
|
-
deliver_handoff_on_event_loop(ready, state,
|
|
1428
|
+
deliver_handoff_on_event_loop(ready, state, environment)
|
|
1610
1429
|
when :failed
|
|
1611
|
-
deliver_failed_execution_on_event_loop(ready, state,
|
|
1430
|
+
deliver_failed_execution_on_event_loop(ready, state, environment)
|
|
1612
1431
|
else
|
|
1613
1432
|
fail_task(
|
|
1614
1433
|
delivery.result_task,
|
|
@@ -1617,28 +1436,28 @@ module Phronomy
|
|
|
1617
1436
|
end
|
|
1618
1437
|
end
|
|
1619
1438
|
|
|
1620
|
-
def handle_terminal_commit_error_on_event_loop(ready, state,
|
|
1439
|
+
def handle_terminal_commit_error_on_event_loop(ready, state, environment)
|
|
1621
1440
|
operation = ready.operation
|
|
1622
1441
|
delivery = ready.delivery
|
|
1623
|
-
if operation.execution.metadata["
|
|
1624
|
-
release_terminal_ownership(
|
|
1625
|
-
|
|
1626
|
-
task
|
|
1442
|
+
if operation.execution.metadata["reservation"] || operation.execution.metadata["execution_extension"]
|
|
1443
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1444
|
+
environment.registry.take_agent_completion_waiters(operation.execution_id, fallback: delivery.result_task).each do |task|
|
|
1445
|
+
fail_task(task, ready.error)
|
|
1627
1446
|
end
|
|
1628
1447
|
return
|
|
1629
1448
|
end
|
|
1630
|
-
|
|
1449
|
+
environment.registry.mark_agent_execution_admission(
|
|
1631
1450
|
@agent.agent_id,
|
|
1632
1451
|
execution_id: operation.execution_id,
|
|
1633
1452
|
state: :recovery_required
|
|
1634
1453
|
)
|
|
1635
|
-
Phronomy.
|
|
1454
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1636
1455
|
"[Phronomy] Agent terminal durable outcome requires recovery for " \
|
|
1637
1456
|
"#{operation.execution_id}: #{ready.error.class}: #{ready.error.message}"
|
|
1638
1457
|
)
|
|
1639
1458
|
end
|
|
1640
1459
|
|
|
1641
|
-
def apply_terminal_outcome_state_on_event_loop(ready, state,
|
|
1460
|
+
def apply_terminal_outcome_state_on_event_loop(ready, state, environment)
|
|
1642
1461
|
operation = ready.operation
|
|
1643
1462
|
outcome = ready.outcome
|
|
1644
1463
|
apply_agent_live_state(
|
|
@@ -1647,7 +1466,7 @@ module Phronomy
|
|
|
1647
1466
|
)
|
|
1648
1467
|
if state
|
|
1649
1468
|
state.invocation&.acknowledge_runtime_snapshot(operation.runtime_snapshot)
|
|
1650
|
-
|
|
1469
|
+
environment.registry.replace_agent_execution(
|
|
1651
1470
|
operation.execution_id,
|
|
1652
1471
|
execution: outcome.execution,
|
|
1653
1472
|
fsm_session_id: (outcome.type == :suspended) ? nil : state.fsm_session_id
|
|
@@ -1655,19 +1474,19 @@ module Phronomy
|
|
|
1655
1474
|
end
|
|
1656
1475
|
end
|
|
1657
1476
|
|
|
1658
|
-
def release_coordination_wait_on_event_loop(ready, state,
|
|
1477
|
+
def release_coordination_wait_on_event_loop(ready, state, environment)
|
|
1659
1478
|
operation = ready.operation
|
|
1660
1479
|
delivery = ready.delivery
|
|
1661
1480
|
outcome = ready.outcome
|
|
1662
|
-
release_terminal_ownership(
|
|
1663
|
-
|
|
1481
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1482
|
+
environment.registry.take_agent_completion_waiters(operation.execution_id, fallback: delivery.result_task).each { |task| fail_task(task, outcome.error) }
|
|
1664
1483
|
end
|
|
1665
1484
|
|
|
1666
|
-
def suspend_execution_on_event_loop(ready, state,
|
|
1485
|
+
def suspend_execution_on_event_loop(ready, state, environment)
|
|
1667
1486
|
operation = ready.operation
|
|
1668
1487
|
delivery = ready.delivery
|
|
1669
1488
|
outcome = ready.outcome
|
|
1670
|
-
|
|
1489
|
+
environment.registry.mark_agent_execution_admission(
|
|
1671
1490
|
@agent.agent_id,
|
|
1672
1491
|
execution_id: operation.execution_id,
|
|
1673
1492
|
state: :suspended
|
|
@@ -1684,43 +1503,43 @@ module Phronomy
|
|
|
1684
1503
|
outcome.result
|
|
1685
1504
|
)
|
|
1686
1505
|
Array(state&.invocation&.config&.fetch(:phronomy_exact_observers, [])).each do |task|
|
|
1687
|
-
task
|
|
1506
|
+
fail_task(task, Phronomy::ExecutionRehydrationRequiredError.new("Execution #{operation.execution_id} requires approval"))
|
|
1688
1507
|
end
|
|
1689
1508
|
end
|
|
1690
1509
|
|
|
1691
|
-
def deliver_completed_execution_on_event_loop(ready, state,
|
|
1510
|
+
def deliver_completed_execution_on_event_loop(ready, state, environment)
|
|
1692
1511
|
operation = ready.operation
|
|
1693
1512
|
delivery = ready.delivery
|
|
1694
1513
|
outcome = ready.outcome
|
|
1695
|
-
release_terminal_ownership(
|
|
1514
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1696
1515
|
callback_error = deliver_terminal(delivery.application_listener, :done, outcome.result)
|
|
1697
1516
|
settle_execution_waiters(
|
|
1698
|
-
|
|
1517
|
+
environment, operation.execution_id, delivery.result_task,
|
|
1699
1518
|
callback_error, :done, outcome.result
|
|
1700
1519
|
)
|
|
1701
1520
|
end
|
|
1702
1521
|
|
|
1703
|
-
def deliver_handoff_on_event_loop(ready, state,
|
|
1522
|
+
def deliver_handoff_on_event_loop(ready, state, environment)
|
|
1704
1523
|
operation = ready.operation
|
|
1705
1524
|
delivery = ready.delivery
|
|
1706
1525
|
outcome = ready.outcome
|
|
1707
|
-
release_terminal_ownership(
|
|
1526
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1708
1527
|
result = outcome.result.merge(
|
|
1709
1528
|
handoff_request: delivery.handoff_request,
|
|
1710
1529
|
_phronomy_handoff_manifest: delivery.handoff_manifest
|
|
1711
1530
|
).freeze
|
|
1712
1531
|
callback_error = deliver_terminal(delivery.application_listener, :handoff, result)
|
|
1713
1532
|
settle_execution_waiters(
|
|
1714
|
-
|
|
1533
|
+
environment, operation.execution_id, delivery.result_task,
|
|
1715
1534
|
callback_error, :handoff, result
|
|
1716
1535
|
)
|
|
1717
1536
|
end
|
|
1718
1537
|
|
|
1719
|
-
def deliver_failed_execution_on_event_loop(ready, state,
|
|
1538
|
+
def deliver_failed_execution_on_event_loop(ready, state, environment)
|
|
1720
1539
|
operation = ready.operation
|
|
1721
1540
|
delivery = ready.delivery
|
|
1722
1541
|
outcome = ready.outcome
|
|
1723
|
-
release_terminal_ownership(
|
|
1542
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1724
1543
|
type = terminal_event_type(outcome.error)
|
|
1725
1544
|
callback_error = deliver_terminal(
|
|
1726
1545
|
delivery.application_listener,
|
|
@@ -1728,13 +1547,13 @@ module Phronomy
|
|
|
1728
1547
|
error: outcome.error
|
|
1729
1548
|
)
|
|
1730
1549
|
settle_execution_waiters(
|
|
1731
|
-
|
|
1550
|
+
environment, operation.execution_id, delivery.result_task,
|
|
1732
1551
|
callback_error, type, nil, outcome.error
|
|
1733
1552
|
)
|
|
1734
1553
|
end
|
|
1735
1554
|
|
|
1736
|
-
def release_terminal_ownership(
|
|
1737
|
-
registry =
|
|
1555
|
+
def release_terminal_ownership(environment, execution_id, state)
|
|
1556
|
+
registry = environment.registry
|
|
1738
1557
|
registry.release_agent_execution(execution_id) if state
|
|
1739
1558
|
registry.release_agent_execution_admission(@agent.agent_id, execution_id: execution_id)
|
|
1740
1559
|
end
|
|
@@ -1749,16 +1568,16 @@ module Phronomy
|
|
|
1749
1568
|
expected_execution_revision:,
|
|
1750
1569
|
expected_fsm_state:
|
|
1751
1570
|
)
|
|
1752
|
-
|
|
1753
|
-
state =
|
|
1571
|
+
environment = @agent.__execution_environment
|
|
1572
|
+
state = environment.registry.agent_execution_state(execution_id)
|
|
1754
1573
|
authoritative = state &&
|
|
1755
1574
|
state.agent.equal?(@agent) &&
|
|
1756
1575
|
state.execution.execution_revision == expected_execution_revision &&
|
|
1757
1576
|
state.fsm_session_id.to_s == fsm_session_id.to_s &&
|
|
1758
|
-
|
|
1577
|
+
environment.session_phase(fsm_session_id) == expected_fsm_state
|
|
1759
1578
|
return state if authoritative
|
|
1760
1579
|
|
|
1761
|
-
Phronomy.
|
|
1580
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1762
1581
|
"[Phronomy] Dropped stale Agent operation result: " \
|
|
1763
1582
|
"execution_id=#{execution_id} fsm_session_id=#{fsm_session_id}"
|
|
1764
1583
|
)
|
|
@@ -1777,14 +1596,14 @@ module Phronomy
|
|
|
1777
1596
|
end
|
|
1778
1597
|
|
|
1779
1598
|
def apply_agent_live_state(root:, appended_records:)
|
|
1780
|
-
|
|
1781
|
-
assert_event_loop!(
|
|
1599
|
+
environment = @agent.__execution_environment
|
|
1600
|
+
assert_event_loop!(environment)
|
|
1782
1601
|
@agent.send(:_append_journal_records, appended_records)
|
|
1783
1602
|
@agent.__replace_root(root)
|
|
1784
1603
|
end
|
|
1785
1604
|
|
|
1786
|
-
def assert_event_loop!(
|
|
1787
|
-
return if
|
|
1605
|
+
def assert_event_loop!(environment)
|
|
1606
|
+
return if environment.executing?
|
|
1788
1607
|
|
|
1789
1608
|
raise Phronomy::Error,
|
|
1790
1609
|
"ExecutionCoordinator live-state apply must run on EventLoop"
|
|
@@ -1803,20 +1622,26 @@ module Phronomy
|
|
|
1803
1622
|
def dispatch_approval_listener(listener, request)
|
|
1804
1623
|
return unless listener
|
|
1805
1624
|
|
|
1806
|
-
Phronomy::
|
|
1625
|
+
Phronomy::Blocking.call_async do
|
|
1807
1626
|
listener.call(request)
|
|
1627
|
+
end.on_complete do |_value, error|
|
|
1628
|
+
report_approval_dispatch_failure(error) if error
|
|
1808
1629
|
end
|
|
1809
1630
|
rescue => error
|
|
1810
|
-
|
|
1631
|
+
report_approval_dispatch_failure(error)
|
|
1632
|
+
end
|
|
1633
|
+
|
|
1634
|
+
def report_approval_dispatch_failure(error)
|
|
1635
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1811
1636
|
"[Phronomy] approval listener dispatch failed: #{error.class}: #{error.message}"
|
|
1812
1637
|
)
|
|
1813
1638
|
end
|
|
1814
1639
|
|
|
1815
1640
|
def settle_execution_waiters(
|
|
1816
|
-
|
|
1641
|
+
environment, execution_id, fallback_task, callback_error, event_type,
|
|
1817
1642
|
result, execution_error = nil
|
|
1818
1643
|
)
|
|
1819
|
-
waiters =
|
|
1644
|
+
waiters = environment.registry.take_agent_completion_waiters(
|
|
1820
1645
|
execution_id,
|
|
1821
1646
|
fallback: fallback_task
|
|
1822
1647
|
)
|
|
@@ -1835,7 +1660,7 @@ module Phronomy
|
|
|
1835
1660
|
callback_error,
|
|
1836
1661
|
event: StreamEvent.new(type: event_type, payload: result),
|
|
1837
1662
|
execution_id: result&.fetch(:execution_id, nil),
|
|
1838
|
-
callback_error_policy: Phronomy.
|
|
1663
|
+
callback_error_policy: Phronomy::Agent::Settings.current.stream_callback_error_policy
|
|
1839
1664
|
)
|
|
1840
1665
|
end
|
|
1841
1666
|
|
|
@@ -1847,7 +1672,7 @@ module Phronomy
|
|
|
1847
1672
|
execution_error = nil
|
|
1848
1673
|
)
|
|
1849
1674
|
if callback_error
|
|
1850
|
-
policy = Phronomy.
|
|
1675
|
+
policy = Phronomy::Agent::Settings.current.stream_callback_error_policy
|
|
1851
1676
|
@agent.send(
|
|
1852
1677
|
:_report_stream_callback_error,
|
|
1853
1678
|
callback_error,
|
|
@@ -1872,6 +1697,7 @@ module Phronomy
|
|
|
1872
1697
|
end
|
|
1873
1698
|
if execution_error
|
|
1874
1699
|
if execution_error.is_a?(Phronomy::CancellationError)
|
|
1700
|
+
result_task.finish_operation! if result_task.respond_to?(:finish_operation!)
|
|
1875
1701
|
result_task.cancel!(execution_error)
|
|
1876
1702
|
else
|
|
1877
1703
|
fail_task(result_task, execution_error)
|
|
@@ -1888,7 +1714,7 @@ module Phronomy
|
|
|
1888
1714
|
:error
|
|
1889
1715
|
end
|
|
1890
1716
|
|
|
1891
|
-
def post_control(
|
|
1717
|
+
def post_control(environment, command)
|
|
1892
1718
|
admission = command.is_a?(StartCommand) || command.is_a?(ResumeCommand)
|
|
1893
1719
|
completion = case command
|
|
1894
1720
|
when StartCommand, ResumeCommand then command.result_task
|
|
@@ -1897,7 +1723,7 @@ module Phronomy
|
|
|
1897
1723
|
when TerminalCommitReady then command.delivery.result_task
|
|
1898
1724
|
when DeferredTerminalCommand then command.result_task
|
|
1899
1725
|
end
|
|
1900
|
-
|
|
1726
|
+
environment.registry.post(command,
|
|
1901
1727
|
admission: admission, completion: completion)
|
|
1902
1728
|
rescue Phronomy::RuntimeShutdownError
|
|
1903
1729
|
false
|
|
@@ -1909,10 +1735,6 @@ module Phronomy
|
|
|
1909
1735
|
)
|
|
1910
1736
|
end
|
|
1911
1737
|
|
|
1912
|
-
def translated(error)
|
|
1913
|
-
@agent.send(:_translated_error, error)
|
|
1914
|
-
end
|
|
1915
|
-
|
|
1916
1738
|
def complete_task(task, result)
|
|
1917
1739
|
@agent.send(:_complete_result_task, task, result)
|
|
1918
1740
|
end
|