phronomy 0.27.0 → 0.28.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 +9 -3
- 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/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/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/features.md +8 -3
- data/docs/getting-started.md +9 -6
- 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/persistence-backends.md +38 -21
- data/docs/runtime-and-concurrency.md +26 -1
- 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/{lifecycle_contract/agent_purged_error.rb → agent_purged_error.rb} +1 -1
- data/lib/phronomy/{recovery → agent/api}/execution_rehydration_required_error.rb +1 -1
- data/lib/phronomy/agent/async_event_api.rb +37 -32
- data/lib/phronomy/agent/base.rb +74 -72
- data/lib/phronomy/agent/before_llm_input.rb +64 -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 +44 -23
- data/lib/phronomy/agent/execution/execution_cancellation.rb +8 -4
- data/lib/phronomy/agent/execution/execution_coordinator.rb +214 -395
- data/lib/phronomy/agent/execution/execution_metadata.rb +1 -0
- data/lib/phronomy/agent/execution/execution_outcome_committer.rb +70 -126
- 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 +18 -116
- 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 +7 -7
- 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 +182 -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/ownership_registry.rb +18 -23
- 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 +10 -9
- data/lib/phronomy/agent/recovery/recovery_coordinator/installation.rb +27 -27
- data/lib/phronomy/agent/recovery/recovery_coordinator/resolution.rb +19 -21
- data/lib/phronomy/agent/recovery/recovery_coordinator.rb +23 -16
- data/lib/phronomy/agent/recovery/recovery_rules.rb +119 -0
- data/lib/phronomy/agent/recovery/recovery_support.rb +8 -11
- 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} +1 -1
- 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/configuration/runtime_settings.rb +49 -0
- 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 +202 -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/backends/ruby_llm_embeddings.rb +48 -0
- data/lib/phronomy/embeddings/base.rb +43 -0
- data/lib/phronomy/embeddings/invalid_result_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/execution/execution_receiver.rb +78 -0
- data/lib/phronomy/execution/execution_scope_state.rb +35 -0
- 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 +3 -3
- data/lib/phronomy/execution/wait_policy.rb +24 -0
- data/lib/phronomy/filter/{contract/filter_block_error.rb → filter_block_error.rb} +1 -1
- 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/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 +58 -42
- 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_coordinator.rb +83 -74
- 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/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 +549 -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 +1 -1
- data/lib/phronomy/tracing/observation.rb +37 -0
- 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 +7 -7
- 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 +27 -0
- data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +3 -5
- data/lib/phronomy/workflow/execution/workflow_runner.rb +58 -79
- data/lib/phronomy/workflow/execution/workflow_settings.rb +28 -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 +38 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_phase_machine_builder.rb +156 -0
- data/lib/phronomy/workflow/{execution → runtime_binding}/workflow_terminal_policy.rb +4 -4
- data/lib/phronomy.rb +57 -16
- data/scripts/api_snapshot.rb +35 -15
- 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/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.rbs +14 -138
- 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 +17 -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 +0 -21
- data/sig/phronomy/handoff.rbs +10 -4
- 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.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} +2 -16
- 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 +14 -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 +1 -1
- data/sig/phronomy.rbs +0 -49
- metadata +318 -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}/execution_cancellation_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/execution_timeout_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)
|
|
@@ -108,14 +94,10 @@ module Phronomy
|
|
|
108
94
|
@agent.send(:__assert_live_agent!)
|
|
109
95
|
@agent.send(:_reject_removed_generic_identity_keys!, config)
|
|
110
96
|
result_task = Phronomy::TaskResult.deferred(name: "agent-#{@agent.agent_id}-#{mode}")
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
)
|
|
116
|
-
binding.bind(result_task)
|
|
117
|
-
config = config.merge(cancellation_token: binding.token)
|
|
118
|
-
end
|
|
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
|
|
|
@@ -155,12 +138,12 @@ module Phronomy
|
|
|
155
138
|
config: config.dup.freeze,
|
|
156
139
|
result_task: result_task
|
|
157
140
|
)
|
|
158
|
-
unless post_control(
|
|
141
|
+
unless post_control(@agent.__execution_environment, command)
|
|
159
142
|
fail_task(result_task, runtime_rejected_error(:resume))
|
|
160
143
|
end
|
|
161
144
|
result_task
|
|
162
145
|
rescue => error
|
|
163
|
-
fail_task(result_task,
|
|
146
|
+
fail_task(result_task, error) if defined?(result_task) && result_task
|
|
164
147
|
result_task
|
|
165
148
|
end
|
|
166
149
|
|
|
@@ -178,7 +161,7 @@ module Phronomy
|
|
|
178
161
|
submit_provider_dispatch_preparation(operation)
|
|
179
162
|
nil
|
|
180
163
|
rescue => error
|
|
181
|
-
event_sink.post(:llm_setup_failed,
|
|
164
|
+
event_sink.post(:llm_setup_failed, error)
|
|
182
165
|
nil
|
|
183
166
|
end
|
|
184
167
|
|
|
@@ -193,13 +176,13 @@ module Phronomy
|
|
|
193
176
|
submit_tool_dispatch_preparation(operation)
|
|
194
177
|
nil
|
|
195
178
|
rescue => error
|
|
196
|
-
event_sink.post(:tool_setup_failed,
|
|
179
|
+
event_sink.post(:tool_setup_failed, error)
|
|
197
180
|
nil
|
|
198
181
|
end
|
|
199
182
|
|
|
200
183
|
def submit_provider_dispatch_preparation(operation)
|
|
201
|
-
|
|
202
|
-
task =
|
|
184
|
+
environment = @agent.__execution_environment
|
|
185
|
+
task = environment.submit(on_full: :raise) do
|
|
203
186
|
@dispatch_preparation.prepare_provider(operation)
|
|
204
187
|
end
|
|
205
188
|
task.on_complete do |result, error|
|
|
@@ -209,8 +192,8 @@ module Phronomy
|
|
|
209
192
|
result: result,
|
|
210
193
|
error: error
|
|
211
194
|
)
|
|
212
|
-
unless post_control(
|
|
213
|
-
Phronomy.
|
|
195
|
+
unless post_control(environment, ready)
|
|
196
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
214
197
|
"[Phronomy] EventLoop rejected Provider dispatch preparation result for " \
|
|
215
198
|
"#{operation.execution_id}"
|
|
216
199
|
)
|
|
@@ -219,8 +202,8 @@ module Phronomy
|
|
|
219
202
|
end
|
|
220
203
|
|
|
221
204
|
def submit_tool_dispatch_preparation(operation)
|
|
222
|
-
|
|
223
|
-
task =
|
|
205
|
+
environment = @agent.__execution_environment
|
|
206
|
+
task = environment.submit(on_full: :raise) do
|
|
224
207
|
@dispatch_preparation.prepare_tools(operation)
|
|
225
208
|
end
|
|
226
209
|
task.on_complete do |result, error|
|
|
@@ -230,8 +213,8 @@ module Phronomy
|
|
|
230
213
|
result: result,
|
|
231
214
|
error: error
|
|
232
215
|
)
|
|
233
|
-
unless post_control(
|
|
234
|
-
Phronomy.
|
|
216
|
+
unless post_control(environment, ready)
|
|
217
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
235
218
|
"[Phronomy] EventLoop rejected Tool dispatch preparation result for " \
|
|
236
219
|
"#{operation.execution_id}"
|
|
237
220
|
)
|
|
@@ -239,70 +222,12 @@ module Phronomy
|
|
|
239
222
|
end
|
|
240
223
|
end
|
|
241
224
|
|
|
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
225
|
# Every control message is delivered by EventLoop. This method is the only
|
|
301
226
|
# coordinator entry point allowed to advance Phronomy-managed live state.
|
|
302
227
|
# @api private
|
|
303
228
|
def deliver_on_event_loop(command)
|
|
304
|
-
|
|
305
|
-
assert_event_loop!(
|
|
229
|
+
environment = @agent.__execution_environment
|
|
230
|
+
assert_event_loop!(environment)
|
|
306
231
|
|
|
307
232
|
case command
|
|
308
233
|
when StartCommand
|
|
@@ -322,10 +247,6 @@ module Phronomy
|
|
|
322
247
|
apply_provider_dispatch_preparation_on_event_loop(command)
|
|
323
248
|
when ToolDispatchPreparationReady
|
|
324
249
|
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
250
|
when ResumeCommand
|
|
330
251
|
begin_resume_on_event_loop(command)
|
|
331
252
|
when ResumeCommitReady
|
|
@@ -346,13 +267,8 @@ module Phronomy
|
|
|
346
267
|
# ----------------------------------------------------------------------
|
|
347
268
|
|
|
348
269
|
def begin_start_on_event_loop(request)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
scope = request.config[:invocation_context]&.__execution_scope
|
|
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
|
|
270
|
+
environment = @agent.__execution_environment
|
|
271
|
+
request.controls.check_start!
|
|
356
272
|
root = @agent.agent_root
|
|
357
273
|
if root.lifecycle_status == :closed
|
|
358
274
|
deliver_start_failure_on_event_loop(
|
|
@@ -365,7 +281,7 @@ module Phronomy
|
|
|
365
281
|
@agent.send(:__assert_live_agent!)
|
|
366
282
|
admitted = false
|
|
367
283
|
submitted = false
|
|
368
|
-
|
|
284
|
+
environment.registry.admit_agent_execution(
|
|
369
285
|
@agent.agent_id,
|
|
370
286
|
owner_token: request.admission_token
|
|
371
287
|
)
|
|
@@ -378,7 +294,7 @@ module Phronomy
|
|
|
378
294
|
@agent.send(:__assert_live_agent!)
|
|
379
295
|
|
|
380
296
|
operation = capture_initial_preparation(request, root)
|
|
381
|
-
task =
|
|
297
|
+
task = environment.submit(on_full: :raise) do
|
|
382
298
|
@initial_preparation.prepare(operation)
|
|
383
299
|
end
|
|
384
300
|
submitted = true
|
|
@@ -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 &&
|
|
@@ -608,7 +522,7 @@ module Phronomy
|
|
|
608
522
|
root: @agent.agent_root,
|
|
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
|
|
@@ -827,7 +742,8 @@ module Phronomy
|
|
|
827
742
|
root: @agent.agent_root,
|
|
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,13 +911,13 @@ 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
|
|
@@ -1100,17 +930,17 @@ module Phronomy
|
|
|
1100
930
|
error: error
|
|
1101
931
|
)
|
|
1102
932
|
fail_task(request.result_task, runtime_rejected_error(:resume_commit)) unless
|
|
1103
|
-
post_control(
|
|
933
|
+
post_control(environment, ready)
|
|
1104
934
|
end
|
|
1105
935
|
rescue => error
|
|
1106
936
|
if resume_transition_started
|
|
1107
|
-
|
|
937
|
+
environment.registry.mark_agent_execution_admission(
|
|
1108
938
|
@agent.agent_id,
|
|
1109
939
|
execution_id: state.execution_id,
|
|
1110
940
|
state: submitted ? :recovery_required : :suspended
|
|
1111
941
|
)
|
|
1112
942
|
end
|
|
1113
|
-
fail_task(request.result_task,
|
|
943
|
+
fail_task(request.result_task, error)
|
|
1114
944
|
raise unless resume_transition_started
|
|
1115
945
|
end
|
|
1116
946
|
|
|
@@ -1134,8 +964,8 @@ module Phronomy
|
|
|
1134
964
|
def apply_resume_commit_on_event_loop(ready)
|
|
1135
965
|
request = ready.request
|
|
1136
966
|
operation = ready.operation
|
|
1137
|
-
|
|
1138
|
-
state =
|
|
967
|
+
environment = @agent.__execution_environment
|
|
968
|
+
state = environment.registry.agent_execution_state(operation.execution_id)
|
|
1139
969
|
unless state && state.agent.equal?(@agent) &&
|
|
1140
970
|
state.execution.execution_revision == operation.expected_execution_revision &&
|
|
1141
971
|
state.execution.status == :suspended
|
|
@@ -1149,23 +979,23 @@ module Phronomy
|
|
|
1149
979
|
end
|
|
1150
980
|
|
|
1151
981
|
if ready.error
|
|
1152
|
-
|
|
982
|
+
environment.registry.mark_agent_execution_admission(
|
|
1153
983
|
@agent.agent_id,
|
|
1154
984
|
execution_id: operation.execution_id,
|
|
1155
985
|
state: :recovery_required
|
|
1156
986
|
)
|
|
1157
|
-
fail_task(request.result_task,
|
|
987
|
+
fail_task(request.result_task, ready.error)
|
|
1158
988
|
return
|
|
1159
989
|
end
|
|
1160
990
|
|
|
1161
|
-
install_resumed_execution_on_event_loop(ready,
|
|
991
|
+
install_resumed_execution_on_event_loop(ready, environment)
|
|
1162
992
|
observe_resumed_execution(ready, state)
|
|
1163
|
-
execution_session_runner(
|
|
993
|
+
execution_session_runner(@agent.__execution_environment).resume_approval(
|
|
1164
994
|
state.invocation, request.result_task,
|
|
1165
995
|
approved: request.approved, config: request.config
|
|
1166
996
|
)
|
|
1167
997
|
rescue => error
|
|
1168
|
-
state =
|
|
998
|
+
state = environment.registry.agent_execution_state(operation.execution_id) if environment&.executing?
|
|
1169
999
|
if state
|
|
1170
1000
|
begin_terminal_commit_on_event_loop(
|
|
1171
1001
|
state,
|
|
@@ -1175,24 +1005,24 @@ module Phronomy
|
|
|
1175
1005
|
fsm_session_id: state.fsm_session_id
|
|
1176
1006
|
)
|
|
1177
1007
|
else
|
|
1178
|
-
fail_task(request.result_task,
|
|
1008
|
+
fail_task(request.result_task, error)
|
|
1179
1009
|
end
|
|
1180
1010
|
end
|
|
1181
1011
|
|
|
1182
|
-
def install_resumed_execution_on_event_loop(ready,
|
|
1012
|
+
def install_resumed_execution_on_event_loop(ready, environment)
|
|
1183
1013
|
request = ready.request
|
|
1184
1014
|
operation = ready.operation
|
|
1185
1015
|
apply_agent_live_state(root: ready.result.root, appended_records: [])
|
|
1186
|
-
|
|
1016
|
+
environment.registry.mark_agent_execution_admission(
|
|
1187
1017
|
@agent.agent_id,
|
|
1188
1018
|
execution_id: operation.execution_id,
|
|
1189
1019
|
state: :executing
|
|
1190
1020
|
)
|
|
1191
|
-
|
|
1021
|
+
environment.registry.replace_agent_execution(
|
|
1192
1022
|
operation.execution_id,
|
|
1193
1023
|
execution: ready.result.execution
|
|
1194
1024
|
)
|
|
1195
|
-
|
|
1025
|
+
environment.registry.register_agent_completion_waiter(
|
|
1196
1026
|
operation.execution_id,
|
|
1197
1027
|
request.result_task
|
|
1198
1028
|
)
|
|
@@ -1227,20 +1057,20 @@ module Phronomy
|
|
|
1227
1057
|
raise Phronomy::ExecutionRehydrationRequiredError,
|
|
1228
1058
|
"initial preparation continuation requires a :preparing execution"
|
|
1229
1059
|
end
|
|
1230
|
-
|
|
1060
|
+
@agent.__execution_environment.registry.mark_agent_execution_admission(
|
|
1231
1061
|
@agent.agent_id, execution_id: state.execution_id, state: :executing
|
|
1232
1062
|
)
|
|
1233
1063
|
start_initial_preparation_recovery_on_event_loop(
|
|
1234
1064
|
state.execution, command.result_task, load_completion: command.load_completion
|
|
1235
1065
|
)
|
|
1236
1066
|
rescue => error
|
|
1237
|
-
fail_task(command.result_task,
|
|
1238
|
-
command.load_completion.fail(
|
|
1067
|
+
fail_task(command.result_task, error)
|
|
1068
|
+
command.load_completion.fail(error)
|
|
1239
1069
|
end
|
|
1240
1070
|
|
|
1241
1071
|
def continue_recovered_on_event_loop(command)
|
|
1242
|
-
|
|
1243
|
-
registry =
|
|
1072
|
+
environment = @agent.__execution_environment
|
|
1073
|
+
registry = environment.registry
|
|
1244
1074
|
state = recovered_execution_state!(command)
|
|
1245
1075
|
validate_recovered_continuation!(state.execution, command.continuation)
|
|
1246
1076
|
invocation = command.invocation
|
|
@@ -1265,7 +1095,7 @@ module Phronomy
|
|
|
1265
1095
|
registry.mark_agent_execution_admission(@agent.agent_id,
|
|
1266
1096
|
execution_id: state.execution_id, state: :executing)
|
|
1267
1097
|
registry.register_agent_completion_waiter(state.execution_id, command.result_task)
|
|
1268
|
-
runner = execution_session_runner(
|
|
1098
|
+
runner = execution_session_runner(environment)
|
|
1269
1099
|
case command.continuation
|
|
1270
1100
|
when :approval_rejection
|
|
1271
1101
|
runner.resume_approval(invocation, command.result_task, approved: false, config: {})
|
|
@@ -1281,7 +1111,7 @@ module Phronomy
|
|
|
1281
1111
|
end
|
|
1282
1112
|
|
|
1283
1113
|
def recovered_execution_state!(command)
|
|
1284
|
-
state =
|
|
1114
|
+
state = @agent.__execution_environment.registry.agent_execution_state(command.execution_id)
|
|
1285
1115
|
unless command.coordinator.equal?(self) && state && state.agent.equal?(@agent) &&
|
|
1286
1116
|
state.coordinator.equal?(self) && state.execution.active? &&
|
|
1287
1117
|
state.execution.execution_revision == command.expected_execution_revision &&
|
|
@@ -1292,8 +1122,8 @@ module Phronomy
|
|
|
1292
1122
|
state
|
|
1293
1123
|
end
|
|
1294
1124
|
|
|
1295
|
-
def execution_session_runner(
|
|
1296
|
-
ExecutionSessionRunner.new(
|
|
1125
|
+
def execution_session_runner(environment)
|
|
1126
|
+
ExecutionSessionRunner.new(environment: environment, on_complete: ->(**result) {
|
|
1297
1127
|
deliver_on_event_loop(SessionFinishedCommand.new(coordinator: self, **result))
|
|
1298
1128
|
})
|
|
1299
1129
|
end
|
|
@@ -1327,9 +1157,9 @@ module Phronomy
|
|
|
1327
1157
|
# ----------------------------------------------------------------------
|
|
1328
1158
|
|
|
1329
1159
|
def finish_on_event_loop(execution_id, result_task, invocation, error, fsm_session_id:)
|
|
1330
|
-
|
|
1331
|
-
assert_event_loop!(
|
|
1332
|
-
state =
|
|
1160
|
+
environment = @agent.__execution_environment
|
|
1161
|
+
assert_event_loop!(environment)
|
|
1162
|
+
state = environment.registry.agent_execution_state(execution_id)
|
|
1333
1163
|
return fail_task(result_task, runtime_rejected_error(:terminal)) unless state
|
|
1334
1164
|
|
|
1335
1165
|
unless state.agent.equal?(@agent) && state.coordinator.equal?(self) &&
|
|
@@ -1342,15 +1172,15 @@ module Phronomy
|
|
|
1342
1172
|
end
|
|
1343
1173
|
|
|
1344
1174
|
terminal_error = error || invocation&.error
|
|
1345
|
-
unless
|
|
1175
|
+
unless environment.registry.agent_execution_quiescent?(execution_id)
|
|
1346
1176
|
wait_state = quiescence_sensitive_terminal_error?(terminal_error) ?
|
|
1347
1177
|
:cancelling : :terminalizing
|
|
1348
|
-
|
|
1178
|
+
environment.registry.mark_agent_execution_admission(
|
|
1349
1179
|
@agent.agent_id,
|
|
1350
1180
|
execution_id: execution_id,
|
|
1351
1181
|
state: wait_state
|
|
1352
1182
|
)
|
|
1353
|
-
|
|
1183
|
+
environment.registry.defer_agent_terminal_until_quiescent(
|
|
1354
1184
|
execution_id,
|
|
1355
1185
|
DeferredTerminalCommand.new(
|
|
1356
1186
|
coordinator: self,
|
|
@@ -1374,18 +1204,18 @@ module Phronomy
|
|
|
1374
1204
|
end
|
|
1375
1205
|
|
|
1376
1206
|
def resume_deferred_terminal_on_event_loop(command)
|
|
1377
|
-
|
|
1378
|
-
state =
|
|
1207
|
+
environment = @agent.__execution_environment
|
|
1208
|
+
state = environment.registry.agent_execution_state(command.execution_id)
|
|
1379
1209
|
unless state && state.agent.equal?(@agent) &&
|
|
1380
1210
|
state.fsm_session_id.to_s == command.fsm_session_id.to_s &&
|
|
1381
1211
|
state.invocation.equal?(command.invocation)
|
|
1382
|
-
Phronomy.
|
|
1212
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1383
1213
|
"[Phronomy] Dropped stale deferred terminal for #{command.execution_id}"
|
|
1384
1214
|
)
|
|
1385
1215
|
return
|
|
1386
1216
|
end
|
|
1387
1217
|
|
|
1388
|
-
unless
|
|
1218
|
+
unless environment.registry.agent_execution_quiescent?(command.execution_id)
|
|
1389
1219
|
raise Phronomy::Error,
|
|
1390
1220
|
"deferred terminal resumed before quiescence for #{command.execution_id}"
|
|
1391
1221
|
end
|
|
@@ -1442,7 +1272,7 @@ module Phronomy
|
|
|
1442
1272
|
end
|
|
1443
1273
|
|
|
1444
1274
|
def begin_terminal_without_session_on_event_loop(request:, prepared:, error:)
|
|
1445
|
-
return deliver_start_failure_on_event_loop(request,
|
|
1275
|
+
return deliver_start_failure_on_event_loop(request, error) unless prepared&.execution
|
|
1446
1276
|
|
|
1447
1277
|
operation = build_terminal_operation(
|
|
1448
1278
|
execution: prepared.execution,
|
|
@@ -1481,7 +1311,8 @@ module Phronomy
|
|
|
1481
1311
|
execution: execution,
|
|
1482
1312
|
runtime_snapshot: invocation ? invocation.runtime_snapshot : empty_runtime_snapshot,
|
|
1483
1313
|
terminal_view: terminal_view(invocation, source_error),
|
|
1484
|
-
state_required: state_required
|
|
1314
|
+
state_required: state_required,
|
|
1315
|
+
wiring: (invocation ? invocation.config : @agent.__execution_wiring).dup.freeze
|
|
1485
1316
|
)
|
|
1486
1317
|
end
|
|
1487
1318
|
|
|
@@ -1490,20 +1321,19 @@ module Phronomy
|
|
|
1490
1321
|
end
|
|
1491
1322
|
|
|
1492
1323
|
def submit_terminal_operation(operation, delivery)
|
|
1493
|
-
|
|
1494
|
-
event_loop = runtime.event_loop
|
|
1324
|
+
environment = @agent.__execution_environment
|
|
1495
1325
|
terminal_transition_started = false
|
|
1496
|
-
|
|
1326
|
+
environment.registry.mark_agent_execution_admission(
|
|
1497
1327
|
@agent.agent_id,
|
|
1498
1328
|
execution_id: operation.execution_id,
|
|
1499
1329
|
state: :terminalizing
|
|
1500
1330
|
)
|
|
1501
1331
|
terminal_transition_started = true
|
|
1502
|
-
|
|
1332
|
+
environment.registry.register_agent_completion_waiter(
|
|
1503
1333
|
operation.execution_id,
|
|
1504
1334
|
delivery.result_task
|
|
1505
1335
|
)
|
|
1506
|
-
task =
|
|
1336
|
+
task = environment.submit(on_full: :raise) do
|
|
1507
1337
|
# Only the operation-specific immutable durable snapshot crosses the
|
|
1508
1338
|
# worker boundary. TaskResult/listener delivery state stays outside it.
|
|
1509
1339
|
@outcome_committer.commit_outcome(operation)
|
|
@@ -1517,23 +1347,23 @@ module Phronomy
|
|
|
1517
1347
|
error: error
|
|
1518
1348
|
)
|
|
1519
1349
|
fail_task(delivery.result_task, runtime_rejected_error(:terminal_apply)) unless
|
|
1520
|
-
post_control(
|
|
1350
|
+
post_control(environment, ready)
|
|
1521
1351
|
end
|
|
1522
1352
|
rescue => error
|
|
1523
1353
|
if terminal_transition_started
|
|
1524
|
-
|
|
1354
|
+
environment.registry.mark_agent_execution_admission(
|
|
1525
1355
|
@agent.agent_id,
|
|
1526
1356
|
execution_id: operation.execution_id,
|
|
1527
1357
|
state: :recovery_required
|
|
1528
1358
|
)
|
|
1529
|
-
Phronomy.
|
|
1359
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1530
1360
|
"[Phronomy] Agent terminal transition requires recovery for " \
|
|
1531
1361
|
"#{operation.execution_id}: #{error.class}: #{error.message}"
|
|
1532
1362
|
)
|
|
1533
1363
|
return
|
|
1534
1364
|
end
|
|
1535
1365
|
|
|
1536
|
-
fail_task(delivery.result_task,
|
|
1366
|
+
fail_task(delivery.result_task, error)
|
|
1537
1367
|
raise
|
|
1538
1368
|
end
|
|
1539
1369
|
|
|
@@ -1555,20 +1385,7 @@ module Phronomy
|
|
|
1555
1385
|
)
|
|
1556
1386
|
end
|
|
1557
1387
|
|
|
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
|
|
1388
|
+
def handoff_terminal_view(request) = request
|
|
1572
1389
|
|
|
1573
1390
|
def empty_runtime_snapshot
|
|
1574
1391
|
{llm_results: [].freeze, runtime_events: [].freeze, active_call: nil}.freeze
|
|
@@ -1577,14 +1394,14 @@ module Phronomy
|
|
|
1577
1394
|
def apply_terminal_commit_on_event_loop(ready)
|
|
1578
1395
|
operation = ready.operation
|
|
1579
1396
|
delivery = ready.delivery
|
|
1580
|
-
|
|
1581
|
-
state =
|
|
1397
|
+
environment = @agent.__execution_environment
|
|
1398
|
+
state = environment.registry.agent_execution_state(operation.execution_id)
|
|
1582
1399
|
|
|
1583
1400
|
if operation.state_required
|
|
1584
1401
|
unless state && state.agent.equal?(@agent) &&
|
|
1585
1402
|
state.execution.execution_revision == operation.expected_execution_revision &&
|
|
1586
1403
|
state.fsm_session_id.to_s == operation.fsm_session_id.to_s
|
|
1587
|
-
Phronomy.
|
|
1404
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1588
1405
|
"[Phronomy] Dropped stale Agent terminal result for #{operation.execution_id}"
|
|
1589
1406
|
)
|
|
1590
1407
|
return
|
|
@@ -1592,23 +1409,23 @@ module Phronomy
|
|
|
1592
1409
|
end
|
|
1593
1410
|
|
|
1594
1411
|
if ready.error
|
|
1595
|
-
handle_terminal_commit_error_on_event_loop(ready, state,
|
|
1412
|
+
handle_terminal_commit_error_on_event_loop(ready, state, environment)
|
|
1596
1413
|
return
|
|
1597
1414
|
end
|
|
1598
1415
|
|
|
1599
|
-
apply_terminal_outcome_state_on_event_loop(ready, state,
|
|
1416
|
+
apply_terminal_outcome_state_on_event_loop(ready, state, environment)
|
|
1600
1417
|
outcome = ready.outcome
|
|
1601
1418
|
case outcome.type
|
|
1602
1419
|
when :coordination_wait
|
|
1603
|
-
release_coordination_wait_on_event_loop(ready, state,
|
|
1420
|
+
release_coordination_wait_on_event_loop(ready, state, environment)
|
|
1604
1421
|
when :suspended
|
|
1605
|
-
suspend_execution_on_event_loop(ready, state,
|
|
1422
|
+
suspend_execution_on_event_loop(ready, state, environment)
|
|
1606
1423
|
when :completed
|
|
1607
|
-
deliver_completed_execution_on_event_loop(ready, state,
|
|
1424
|
+
deliver_completed_execution_on_event_loop(ready, state, environment)
|
|
1608
1425
|
when :handed_off
|
|
1609
|
-
deliver_handoff_on_event_loop(ready, state,
|
|
1426
|
+
deliver_handoff_on_event_loop(ready, state, environment)
|
|
1610
1427
|
when :failed
|
|
1611
|
-
deliver_failed_execution_on_event_loop(ready, state,
|
|
1428
|
+
deliver_failed_execution_on_event_loop(ready, state, environment)
|
|
1612
1429
|
else
|
|
1613
1430
|
fail_task(
|
|
1614
1431
|
delivery.result_task,
|
|
@@ -1617,28 +1434,28 @@ module Phronomy
|
|
|
1617
1434
|
end
|
|
1618
1435
|
end
|
|
1619
1436
|
|
|
1620
|
-
def handle_terminal_commit_error_on_event_loop(ready, state,
|
|
1437
|
+
def handle_terminal_commit_error_on_event_loop(ready, state, environment)
|
|
1621
1438
|
operation = ready.operation
|
|
1622
1439
|
delivery = ready.delivery
|
|
1623
|
-
if operation.execution.metadata["
|
|
1624
|
-
release_terminal_ownership(
|
|
1625
|
-
|
|
1440
|
+
if operation.execution.metadata["reservation"] || operation.execution.metadata["execution_extension"]
|
|
1441
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1442
|
+
environment.registry.take_agent_completion_waiters(operation.execution_id, fallback: delivery.result_task).each do |task|
|
|
1626
1443
|
task.fail(ready.error)
|
|
1627
1444
|
end
|
|
1628
1445
|
return
|
|
1629
1446
|
end
|
|
1630
|
-
|
|
1447
|
+
environment.registry.mark_agent_execution_admission(
|
|
1631
1448
|
@agent.agent_id,
|
|
1632
1449
|
execution_id: operation.execution_id,
|
|
1633
1450
|
state: :recovery_required
|
|
1634
1451
|
)
|
|
1635
|
-
Phronomy.
|
|
1452
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1636
1453
|
"[Phronomy] Agent terminal durable outcome requires recovery for " \
|
|
1637
1454
|
"#{operation.execution_id}: #{ready.error.class}: #{ready.error.message}"
|
|
1638
1455
|
)
|
|
1639
1456
|
end
|
|
1640
1457
|
|
|
1641
|
-
def apply_terminal_outcome_state_on_event_loop(ready, state,
|
|
1458
|
+
def apply_terminal_outcome_state_on_event_loop(ready, state, environment)
|
|
1642
1459
|
operation = ready.operation
|
|
1643
1460
|
outcome = ready.outcome
|
|
1644
1461
|
apply_agent_live_state(
|
|
@@ -1647,7 +1464,7 @@ module Phronomy
|
|
|
1647
1464
|
)
|
|
1648
1465
|
if state
|
|
1649
1466
|
state.invocation&.acknowledge_runtime_snapshot(operation.runtime_snapshot)
|
|
1650
|
-
|
|
1467
|
+
environment.registry.replace_agent_execution(
|
|
1651
1468
|
operation.execution_id,
|
|
1652
1469
|
execution: outcome.execution,
|
|
1653
1470
|
fsm_session_id: (outcome.type == :suspended) ? nil : state.fsm_session_id
|
|
@@ -1655,19 +1472,19 @@ module Phronomy
|
|
|
1655
1472
|
end
|
|
1656
1473
|
end
|
|
1657
1474
|
|
|
1658
|
-
def release_coordination_wait_on_event_loop(ready, state,
|
|
1475
|
+
def release_coordination_wait_on_event_loop(ready, state, environment)
|
|
1659
1476
|
operation = ready.operation
|
|
1660
1477
|
delivery = ready.delivery
|
|
1661
1478
|
outcome = ready.outcome
|
|
1662
|
-
release_terminal_ownership(
|
|
1663
|
-
|
|
1479
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1480
|
+
environment.registry.take_agent_completion_waiters(operation.execution_id, fallback: delivery.result_task).each { |task| task.fail(outcome.error) }
|
|
1664
1481
|
end
|
|
1665
1482
|
|
|
1666
|
-
def suspend_execution_on_event_loop(ready, state,
|
|
1483
|
+
def suspend_execution_on_event_loop(ready, state, environment)
|
|
1667
1484
|
operation = ready.operation
|
|
1668
1485
|
delivery = ready.delivery
|
|
1669
1486
|
outcome = ready.outcome
|
|
1670
|
-
|
|
1487
|
+
environment.registry.mark_agent_execution_admission(
|
|
1671
1488
|
@agent.agent_id,
|
|
1672
1489
|
execution_id: operation.execution_id,
|
|
1673
1490
|
state: :suspended
|
|
@@ -1688,39 +1505,39 @@ module Phronomy
|
|
|
1688
1505
|
end
|
|
1689
1506
|
end
|
|
1690
1507
|
|
|
1691
|
-
def deliver_completed_execution_on_event_loop(ready, state,
|
|
1508
|
+
def deliver_completed_execution_on_event_loop(ready, state, environment)
|
|
1692
1509
|
operation = ready.operation
|
|
1693
1510
|
delivery = ready.delivery
|
|
1694
1511
|
outcome = ready.outcome
|
|
1695
|
-
release_terminal_ownership(
|
|
1512
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1696
1513
|
callback_error = deliver_terminal(delivery.application_listener, :done, outcome.result)
|
|
1697
1514
|
settle_execution_waiters(
|
|
1698
|
-
|
|
1515
|
+
environment, operation.execution_id, delivery.result_task,
|
|
1699
1516
|
callback_error, :done, outcome.result
|
|
1700
1517
|
)
|
|
1701
1518
|
end
|
|
1702
1519
|
|
|
1703
|
-
def deliver_handoff_on_event_loop(ready, state,
|
|
1520
|
+
def deliver_handoff_on_event_loop(ready, state, environment)
|
|
1704
1521
|
operation = ready.operation
|
|
1705
1522
|
delivery = ready.delivery
|
|
1706
1523
|
outcome = ready.outcome
|
|
1707
|
-
release_terminal_ownership(
|
|
1524
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1708
1525
|
result = outcome.result.merge(
|
|
1709
1526
|
handoff_request: delivery.handoff_request,
|
|
1710
1527
|
_phronomy_handoff_manifest: delivery.handoff_manifest
|
|
1711
1528
|
).freeze
|
|
1712
1529
|
callback_error = deliver_terminal(delivery.application_listener, :handoff, result)
|
|
1713
1530
|
settle_execution_waiters(
|
|
1714
|
-
|
|
1531
|
+
environment, operation.execution_id, delivery.result_task,
|
|
1715
1532
|
callback_error, :handoff, result
|
|
1716
1533
|
)
|
|
1717
1534
|
end
|
|
1718
1535
|
|
|
1719
|
-
def deliver_failed_execution_on_event_loop(ready, state,
|
|
1536
|
+
def deliver_failed_execution_on_event_loop(ready, state, environment)
|
|
1720
1537
|
operation = ready.operation
|
|
1721
1538
|
delivery = ready.delivery
|
|
1722
1539
|
outcome = ready.outcome
|
|
1723
|
-
release_terminal_ownership(
|
|
1540
|
+
release_terminal_ownership(environment, operation.execution_id, state)
|
|
1724
1541
|
type = terminal_event_type(outcome.error)
|
|
1725
1542
|
callback_error = deliver_terminal(
|
|
1726
1543
|
delivery.application_listener,
|
|
@@ -1728,13 +1545,13 @@ module Phronomy
|
|
|
1728
1545
|
error: outcome.error
|
|
1729
1546
|
)
|
|
1730
1547
|
settle_execution_waiters(
|
|
1731
|
-
|
|
1548
|
+
environment, operation.execution_id, delivery.result_task,
|
|
1732
1549
|
callback_error, type, nil, outcome.error
|
|
1733
1550
|
)
|
|
1734
1551
|
end
|
|
1735
1552
|
|
|
1736
|
-
def release_terminal_ownership(
|
|
1737
|
-
registry =
|
|
1553
|
+
def release_terminal_ownership(environment, execution_id, state)
|
|
1554
|
+
registry = environment.registry
|
|
1738
1555
|
registry.release_agent_execution(execution_id) if state
|
|
1739
1556
|
registry.release_agent_execution_admission(@agent.agent_id, execution_id: execution_id)
|
|
1740
1557
|
end
|
|
@@ -1749,16 +1566,16 @@ module Phronomy
|
|
|
1749
1566
|
expected_execution_revision:,
|
|
1750
1567
|
expected_fsm_state:
|
|
1751
1568
|
)
|
|
1752
|
-
|
|
1753
|
-
state =
|
|
1569
|
+
environment = @agent.__execution_environment
|
|
1570
|
+
state = environment.registry.agent_execution_state(execution_id)
|
|
1754
1571
|
authoritative = state &&
|
|
1755
1572
|
state.agent.equal?(@agent) &&
|
|
1756
1573
|
state.execution.execution_revision == expected_execution_revision &&
|
|
1757
1574
|
state.fsm_session_id.to_s == fsm_session_id.to_s &&
|
|
1758
|
-
|
|
1575
|
+
environment.session_phase(fsm_session_id) == expected_fsm_state
|
|
1759
1576
|
return state if authoritative
|
|
1760
1577
|
|
|
1761
|
-
Phronomy.
|
|
1578
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1762
1579
|
"[Phronomy] Dropped stale Agent operation result: " \
|
|
1763
1580
|
"execution_id=#{execution_id} fsm_session_id=#{fsm_session_id}"
|
|
1764
1581
|
)
|
|
@@ -1777,14 +1594,14 @@ module Phronomy
|
|
|
1777
1594
|
end
|
|
1778
1595
|
|
|
1779
1596
|
def apply_agent_live_state(root:, appended_records:)
|
|
1780
|
-
|
|
1781
|
-
assert_event_loop!(
|
|
1597
|
+
environment = @agent.__execution_environment
|
|
1598
|
+
assert_event_loop!(environment)
|
|
1782
1599
|
@agent.send(:_append_journal_records, appended_records)
|
|
1783
1600
|
@agent.__replace_root(root)
|
|
1784
1601
|
end
|
|
1785
1602
|
|
|
1786
|
-
def assert_event_loop!(
|
|
1787
|
-
return if
|
|
1603
|
+
def assert_event_loop!(environment)
|
|
1604
|
+
return if environment.executing?
|
|
1788
1605
|
|
|
1789
1606
|
raise Phronomy::Error,
|
|
1790
1607
|
"ExecutionCoordinator live-state apply must run on EventLoop"
|
|
@@ -1803,20 +1620,26 @@ module Phronomy
|
|
|
1803
1620
|
def dispatch_approval_listener(listener, request)
|
|
1804
1621
|
return unless listener
|
|
1805
1622
|
|
|
1806
|
-
Phronomy::
|
|
1623
|
+
Phronomy::Blocking.call_async do
|
|
1807
1624
|
listener.call(request)
|
|
1625
|
+
end.on_complete do |_value, error|
|
|
1626
|
+
report_approval_dispatch_failure(error) if error
|
|
1808
1627
|
end
|
|
1809
1628
|
rescue => error
|
|
1810
|
-
|
|
1629
|
+
report_approval_dispatch_failure(error)
|
|
1630
|
+
end
|
|
1631
|
+
|
|
1632
|
+
def report_approval_dispatch_failure(error)
|
|
1633
|
+
Phronomy::RuntimeSettings.current.logger&.warn(
|
|
1811
1634
|
"[Phronomy] approval listener dispatch failed: #{error.class}: #{error.message}"
|
|
1812
1635
|
)
|
|
1813
1636
|
end
|
|
1814
1637
|
|
|
1815
1638
|
def settle_execution_waiters(
|
|
1816
|
-
|
|
1639
|
+
environment, execution_id, fallback_task, callback_error, event_type,
|
|
1817
1640
|
result, execution_error = nil
|
|
1818
1641
|
)
|
|
1819
|
-
waiters =
|
|
1642
|
+
waiters = environment.registry.take_agent_completion_waiters(
|
|
1820
1643
|
execution_id,
|
|
1821
1644
|
fallback: fallback_task
|
|
1822
1645
|
)
|
|
@@ -1835,7 +1658,7 @@ module Phronomy
|
|
|
1835
1658
|
callback_error,
|
|
1836
1659
|
event: StreamEvent.new(type: event_type, payload: result),
|
|
1837
1660
|
execution_id: result&.fetch(:execution_id, nil),
|
|
1838
|
-
callback_error_policy: Phronomy.
|
|
1661
|
+
callback_error_policy: Phronomy::Agent::Settings.current.stream_callback_error_policy
|
|
1839
1662
|
)
|
|
1840
1663
|
end
|
|
1841
1664
|
|
|
@@ -1847,7 +1670,7 @@ module Phronomy
|
|
|
1847
1670
|
execution_error = nil
|
|
1848
1671
|
)
|
|
1849
1672
|
if callback_error
|
|
1850
|
-
policy = Phronomy.
|
|
1673
|
+
policy = Phronomy::Agent::Settings.current.stream_callback_error_policy
|
|
1851
1674
|
@agent.send(
|
|
1852
1675
|
:_report_stream_callback_error,
|
|
1853
1676
|
callback_error,
|
|
@@ -1888,7 +1711,7 @@ module Phronomy
|
|
|
1888
1711
|
:error
|
|
1889
1712
|
end
|
|
1890
1713
|
|
|
1891
|
-
def post_control(
|
|
1714
|
+
def post_control(environment, command)
|
|
1892
1715
|
admission = command.is_a?(StartCommand) || command.is_a?(ResumeCommand)
|
|
1893
1716
|
completion = case command
|
|
1894
1717
|
when StartCommand, ResumeCommand then command.result_task
|
|
@@ -1897,7 +1720,7 @@ module Phronomy
|
|
|
1897
1720
|
when TerminalCommitReady then command.delivery.result_task
|
|
1898
1721
|
when DeferredTerminalCommand then command.result_task
|
|
1899
1722
|
end
|
|
1900
|
-
|
|
1723
|
+
environment.registry.post(command,
|
|
1901
1724
|
admission: admission, completion: completion)
|
|
1902
1725
|
rescue Phronomy::RuntimeShutdownError
|
|
1903
1726
|
false
|
|
@@ -1909,10 +1732,6 @@ module Phronomy
|
|
|
1909
1732
|
)
|
|
1910
1733
|
end
|
|
1911
1734
|
|
|
1912
|
-
def translated(error)
|
|
1913
|
-
@agent.send(:_translated_error, error)
|
|
1914
|
-
end
|
|
1915
|
-
|
|
1916
1735
|
def complete_task(task, result)
|
|
1917
1736
|
@agent.send(:_complete_result_task, task, result)
|
|
1918
1737
|
end
|