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,186 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Phronomy
|
|
4
|
-
# Small private Recovery semantic/primitives layer shared by Agent and
|
|
5
|
-
# Workflow recovery. Entity-specific orchestration remains outside this module.
|
|
6
|
-
# @api private
|
|
7
|
-
module Recovery
|
|
8
|
-
RESUMABLE = :resumable
|
|
9
|
-
RECONCILABLE = :reconcilable
|
|
10
|
-
RESOLUTION_REQUIRED = :resolution_required
|
|
11
|
-
DISPOSITIONS = [RESUMABLE, RECONCILABLE, RESOLUTION_REQUIRED].freeze
|
|
12
|
-
|
|
13
|
-
ALLOWED_OUTCOMES = %i[succeeded failed not_performed].freeze
|
|
14
|
-
# Internal shorthand used by the Agent Recovery implementation. This is not
|
|
15
|
-
# a public API constant; both names refer to the same frozen value.
|
|
16
|
-
OUTCOMES = ALLOWED_OUTCOMES
|
|
17
|
-
|
|
18
|
-
MISSING = Object.new.freeze
|
|
19
|
-
|
|
20
|
-
Classification = Data.define(
|
|
21
|
-
:disposition, :reason, :subject, :allowed_outcomes, :facts
|
|
22
|
-
) do
|
|
23
|
-
def initialize(
|
|
24
|
-
disposition:,
|
|
25
|
-
reason:,
|
|
26
|
-
subject: nil,
|
|
27
|
-
allowed_outcomes: [],
|
|
28
|
-
facts: {}
|
|
29
|
-
)
|
|
30
|
-
normalized = disposition.to_sym
|
|
31
|
-
unless Phronomy::Recovery::DISPOSITIONS.include?(normalized)
|
|
32
|
-
raise ArgumentError, "unknown Recovery disposition: #{disposition.inspect}"
|
|
33
|
-
end
|
|
34
|
-
super(
|
|
35
|
-
disposition: normalized,
|
|
36
|
-
reason: reason.to_sym,
|
|
37
|
-
subject: subject && Phronomy::Recovery.normalize_subject(subject),
|
|
38
|
-
allowed_outcomes: Array(allowed_outcomes).map(&:to_sym).freeze,
|
|
39
|
-
facts: Phronomy::Values::Immutable.copy(facts || {})
|
|
40
|
-
)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
module_function
|
|
45
|
-
|
|
46
|
-
def normalize_outcome(outcome)
|
|
47
|
-
normalized = outcome.to_sym
|
|
48
|
-
unless OUTCOMES.include?(normalized)
|
|
49
|
-
raise ArgumentError, "unsupported Recovery outcome: #{outcome.inspect}"
|
|
50
|
-
end
|
|
51
|
-
normalized
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def validate_resolution_material!(outcome:, result_present:, error_present:)
|
|
55
|
-
normalized = normalize_outcome(outcome)
|
|
56
|
-
case normalized
|
|
57
|
-
when :succeeded
|
|
58
|
-
raise ArgumentError, "Recovery :succeeded requires result:" unless result_present
|
|
59
|
-
raise ArgumentError, "Recovery :succeeded forbids error:" if error_present
|
|
60
|
-
when :failed
|
|
61
|
-
raise ArgumentError, "Recovery :failed requires error:" unless error_present
|
|
62
|
-
raise ArgumentError, "Recovery :failed forbids result:" if result_present
|
|
63
|
-
when :not_performed
|
|
64
|
-
if result_present || error_present
|
|
65
|
-
raise ArgumentError, "Recovery :not_performed accepts neither result: nor error:"
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
true
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def normalize_subject(subject)
|
|
72
|
-
hash = subject.to_h.transform_keys(&:to_sym)
|
|
73
|
-
type = hash.fetch(:type).to_sym
|
|
74
|
-
normalized = {type: type}
|
|
75
|
-
case type
|
|
76
|
-
when :llm_call
|
|
77
|
-
normalized[:llm_call_id] = required_id(hash, :llm_call_id)
|
|
78
|
-
when :tool_invocation
|
|
79
|
-
normalized[:tool_invocation_id] = required_id(hash, :tool_invocation_id)
|
|
80
|
-
when :persistence_operation
|
|
81
|
-
# Persistence operation references are structural only. Do not introduce
|
|
82
|
-
# a generic durable operation/recovery identity here.
|
|
83
|
-
normalized[:entity] = hash.fetch(:entity).to_sym
|
|
84
|
-
else
|
|
85
|
-
raise ArgumentError, "unsupported Recovery subject type: #{type.inspect}"
|
|
86
|
-
end
|
|
87
|
-
normalized.freeze
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def subject_key(subject)
|
|
91
|
-
normalized = normalize_subject(subject)
|
|
92
|
-
case normalized.fetch(:type)
|
|
93
|
-
when :llm_call
|
|
94
|
-
"llm_call:#{normalized.fetch(:llm_call_id)}"
|
|
95
|
-
when :tool_invocation
|
|
96
|
-
"tool_invocation:#{normalized.fetch(:tool_invocation_id)}"
|
|
97
|
-
when :persistence_operation
|
|
98
|
-
"persistence_operation:#{normalized.fetch(:entity)}"
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def subject_equal?(left, right)
|
|
103
|
-
normalize_subject(left) == normalize_subject(right)
|
|
104
|
-
rescue ArgumentError, KeyError
|
|
105
|
-
false
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# Compare authoritative current state with a known pre/post revision pair.
|
|
109
|
-
# This is deliberately small: callers still validate entity-specific content.
|
|
110
|
-
def compare_revisions(current_revision:, expected_pre_revision:, intended_post_revision:)
|
|
111
|
-
current = current_revision
|
|
112
|
-
return :post_state if current == intended_post_revision
|
|
113
|
-
return :pre_state if current == expected_pre_revision
|
|
114
|
-
|
|
115
|
-
:conflict
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Generic F1 helper for revisioned snapshot repositories such as Workflow.
|
|
119
|
-
# Some repositories return a newly allocated revision only after save, so
|
|
120
|
-
# callers may not know the intended post revision in advance. In that case
|
|
121
|
-
# the intended snapshot plus a revision different from the expected pre
|
|
122
|
-
# revision identifies the post-state.
|
|
123
|
-
def compare_revisioned_snapshot(
|
|
124
|
-
record:,
|
|
125
|
-
expected_pre_revision:,
|
|
126
|
-
intended_snapshot:,
|
|
127
|
-
intended_post_revision: nil
|
|
128
|
-
)
|
|
129
|
-
return :pre_state if record.nil? && expected_pre_revision.nil?
|
|
130
|
-
return :conflict if record.nil?
|
|
131
|
-
|
|
132
|
-
revision = fetch_value(record, :revision)
|
|
133
|
-
snapshot = fetch_value(record, :snapshot)
|
|
134
|
-
normalized_snapshot = normalize_value(snapshot)
|
|
135
|
-
normalized_intended = normalize_value(intended_snapshot)
|
|
136
|
-
|
|
137
|
-
if intended_post_revision
|
|
138
|
-
if revision == intended_post_revision &&
|
|
139
|
-
normalized_snapshot == normalized_intended
|
|
140
|
-
return :post_state
|
|
141
|
-
end
|
|
142
|
-
elsif normalized_snapshot == normalized_intended &&
|
|
143
|
-
revision != expected_pre_revision
|
|
144
|
-
return :post_state
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
return :pre_state if revision == expected_pre_revision
|
|
148
|
-
|
|
149
|
-
:conflict
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def normalize_value(value)
|
|
153
|
-
case value
|
|
154
|
-
when Hash
|
|
155
|
-
value.each_with_object({}) do |(key, child), result|
|
|
156
|
-
result[key.to_s] = normalize_value(child)
|
|
157
|
-
end
|
|
158
|
-
when Array
|
|
159
|
-
value.map { |child| normalize_value(child) }
|
|
160
|
-
when Symbol
|
|
161
|
-
value.to_s
|
|
162
|
-
else
|
|
163
|
-
value
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def fetch_value(record, key)
|
|
168
|
-
return nil unless record
|
|
169
|
-
return record.public_send(key) if record.respond_to?(key)
|
|
170
|
-
return record[key] if record.respond_to?(:key?) && record.key?(key)
|
|
171
|
-
string_key = key.to_s
|
|
172
|
-
return record[string_key] if record.respond_to?(:key?) && record.key?(string_key)
|
|
173
|
-
|
|
174
|
-
nil
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def required_id(hash, key)
|
|
178
|
-
value = hash.fetch(key)
|
|
179
|
-
text = value.to_s
|
|
180
|
-
raise ArgumentError, "#{key} must not be empty" if text.empty?
|
|
181
|
-
|
|
182
|
-
text.freeze
|
|
183
|
-
end
|
|
184
|
-
private_class_method :required_id
|
|
185
|
-
end
|
|
186
|
-
end
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Phronomy
|
|
4
|
-
module VectorStore
|
|
5
|
-
module Embeddings
|
|
6
|
-
# Public extension SPI for embedding adapters.
|
|
7
|
-
#
|
|
8
|
-
# Concrete implementations override {#embed}. Phronomy owns the async
|
|
9
|
-
# bridge: {#embed_async} routes the synchronous implementation through the
|
|
10
|
-
# bounded OffloadPool and returns a {Phronomy::TaskResult}.
|
|
11
|
-
#
|
|
12
|
-
# @api public
|
|
13
|
-
class Base
|
|
14
|
-
# Embed the given text and return a vector representation.
|
|
15
|
-
#
|
|
16
|
-
# @param text [String] the text to embed
|
|
17
|
-
# @param cancellation_token [Phronomy::Concurrency::CancellationToken, nil]
|
|
18
|
-
# @return [Array<Float>] the embedding vector
|
|
19
|
-
# @api public
|
|
20
|
-
def embed(text, cancellation_token = nil)
|
|
21
|
-
cancellation_token&.raise_if_cancelled!
|
|
22
|
-
raise NotImplementedError, "#{self.class}#embed is not implemented"
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Submits an {#embed} call to {OffloadPool}.
|
|
26
|
-
#
|
|
27
|
-
# @param text [String]
|
|
28
|
-
# @param cancellation_token [Phronomy::Concurrency::CancellationToken, nil]
|
|
29
|
-
# @param timeout [Numeric, nil] operation-wide submit timeout
|
|
30
|
-
# @return [Phronomy::TaskResult]
|
|
31
|
-
# @api public
|
|
32
|
-
def embed_async(text, cancellation_token = nil, timeout: nil)
|
|
33
|
-
Phronomy::Runtime.instance.offload.submit(
|
|
34
|
-
timeout: timeout,
|
|
35
|
-
cancellation_token: cancellation_token,
|
|
36
|
-
on_full: :raise
|
|
37
|
-
) do
|
|
38
|
-
embed(text, cancellation_token)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Phronomy
|
|
4
|
-
module VectorStore
|
|
5
|
-
module Embeddings
|
|
6
|
-
# Embeddings adapter backed by RubyLLM.
|
|
7
|
-
#
|
|
8
|
-
# Delegates to +RubyLLM.embed+ and returns the resulting vector as an
|
|
9
|
-
# +Array<Float>+.
|
|
10
|
-
#
|
|
11
|
-
# @example Default model
|
|
12
|
-
# embeddings = Phronomy::VectorStore::Embeddings::RubyLLMEmbeddings.new
|
|
13
|
-
# vector = embeddings.embed("Hello, world!")
|
|
14
|
-
#
|
|
15
|
-
# @example Explicit model
|
|
16
|
-
# embeddings = Phronomy::VectorStore::Embeddings::RubyLLMEmbeddings.new(model: "text-embedding-3-small")
|
|
17
|
-
# vector = embeddings.embed("Hello, world!")
|
|
18
|
-
class RubyLLMEmbeddings < Base
|
|
19
|
-
# @param model [String, nil] embedding model identifier; nil uses the RubyLLM default
|
|
20
|
-
# @param provider [Symbol, nil] provider override (e.g. :openai); nil uses the RubyLLM default
|
|
21
|
-
# @param assume_model_exists [Boolean] when true, skips RubyLLM model-registry validation
|
|
22
|
-
# (useful for locally hosted models not in the registry)
|
|
23
|
-
# @api public
|
|
24
|
-
def initialize(model: nil, provider: nil, assume_model_exists: false)
|
|
25
|
-
@model = model
|
|
26
|
-
@provider = provider
|
|
27
|
-
@assume_model_exists = assume_model_exists
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Embed text via RubyLLM.
|
|
31
|
-
#
|
|
32
|
-
# @param text [String]
|
|
33
|
-
# @param cancellation_token [Phronomy::Concurrency::CancellationToken, nil] optional; raises CancellationError when cancelled
|
|
34
|
-
# @return [Array<Float>]
|
|
35
|
-
# @api public
|
|
36
|
-
def embed(text, cancellation_token = nil)
|
|
37
|
-
cancellation_token&.raise_if_cancelled!
|
|
38
|
-
opts = {}
|
|
39
|
-
opts[:model] = @model if @model
|
|
40
|
-
opts[:provider] = @provider if @provider
|
|
41
|
-
opts[:assume_model_exists] = true if @assume_model_exists
|
|
42
|
-
RubyLLM.embed(text, **opts).vectors
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "state_machines"
|
|
4
|
-
|
|
5
|
-
module Phronomy
|
|
6
|
-
class Workflow
|
|
7
|
-
# Builds the anonymous state-machine Class used by WorkflowRunner.
|
|
8
|
-
#
|
|
9
|
-
# This class compiles Workflow topology into state_machines declarations.
|
|
10
|
-
# It intentionally does not await Tasks, register completion callbacks,
|
|
11
|
-
# cancel external work, or interpret application event payloads.
|
|
12
|
-
#
|
|
13
|
-
# @api private
|
|
14
|
-
class PhaseMachineBuilder
|
|
15
|
-
def initialize(
|
|
16
|
-
entry_point:,
|
|
17
|
-
declared_states:,
|
|
18
|
-
wait_state_names:,
|
|
19
|
-
external_events:,
|
|
20
|
-
entry_actions:,
|
|
21
|
-
auto_transitions:,
|
|
22
|
-
exit_actions:
|
|
23
|
-
)
|
|
24
|
-
@entry_point = entry_point
|
|
25
|
-
@declared_states = declared_states
|
|
26
|
-
@wait_state_names = wait_state_names
|
|
27
|
-
@external_events = external_events
|
|
28
|
-
@entry_actions = entry_actions
|
|
29
|
-
@auto_transitions = auto_transitions
|
|
30
|
-
@exit_actions = exit_actions
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def build
|
|
34
|
-
entry = @entry_point
|
|
35
|
-
all_states = (@declared_states + @wait_state_names + [FSMProtocol::FINISH]).uniq
|
|
36
|
-
auto_transitions = @auto_transitions
|
|
37
|
-
external_events = @external_events
|
|
38
|
-
entry_actions = @entry_actions
|
|
39
|
-
exit_actions = @exit_actions
|
|
40
|
-
condition_builder = method(:build_transition_condition)
|
|
41
|
-
entry_callback_builder = method(:build_entry_callback)
|
|
42
|
-
exit_callback_builder = method(:build_exit_callback)
|
|
43
|
-
transition_callback = build_transition_action_callback
|
|
44
|
-
|
|
45
|
-
Class.new do
|
|
46
|
-
attr_accessor(
|
|
47
|
-
:context,
|
|
48
|
-
:current_event,
|
|
49
|
-
:selected_transition_action,
|
|
50
|
-
:selected_transition_metadata
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
state_machine :phase, initial: entry do
|
|
54
|
-
all_states.each { |state_name| state state_name }
|
|
55
|
-
|
|
56
|
-
event :state_completed do
|
|
57
|
-
auto_transitions.each do |transition_definition|
|
|
58
|
-
transition(
|
|
59
|
-
transition_definition[:from] => transition_definition[:to],
|
|
60
|
-
:if => condition_builder.call(transition_definition)
|
|
61
|
-
)
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
external_events.each do |event_name, transitions|
|
|
66
|
-
event event_name do
|
|
67
|
-
transitions.each do |transition_definition|
|
|
68
|
-
transition(
|
|
69
|
-
transition_definition[:from] => transition_definition[:to],
|
|
70
|
-
:if => condition_builder.call(transition_definition)
|
|
71
|
-
)
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
entry_actions.each do |state_name, callables|
|
|
77
|
-
callables.each do |callable|
|
|
78
|
-
after_transition(
|
|
79
|
-
to: state_name,
|
|
80
|
-
&entry_callback_builder.call(callable, state_name)
|
|
81
|
-
)
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# Both source exit callbacks and the transition action are
|
|
86
|
-
# before_transition callbacks. Register exits first to preserve the
|
|
87
|
-
# required exit -> transition action -> entry ordering.
|
|
88
|
-
exit_actions.each do |state_name, callables|
|
|
89
|
-
callables.each do |callable|
|
|
90
|
-
before_transition(
|
|
91
|
-
from: state_name,
|
|
92
|
-
&exit_callback_builder.call(callable, state_name)
|
|
93
|
-
)
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
before_transition(&transition_callback)
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
rescue => error
|
|
101
|
-
raise ArgumentError, "Failed to build phase machine: #{error.message}"
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
private
|
|
105
|
-
|
|
106
|
-
def build_transition_condition(transition_definition)
|
|
107
|
-
guard = transition_definition[:guard]
|
|
108
|
-
action = transition_definition[:action]
|
|
109
|
-
metadata = {
|
|
110
|
-
from: transition_definition[:from],
|
|
111
|
-
event: transition_definition[:event],
|
|
112
|
-
to: public_destination(transition_definition[:to])
|
|
113
|
-
}.freeze
|
|
114
|
-
|
|
115
|
-
->(machine) {
|
|
116
|
-
matched =
|
|
117
|
-
guard.nil? ||
|
|
118
|
-
call_with_optional_event(
|
|
119
|
-
guard,
|
|
120
|
-
machine.context,
|
|
121
|
-
machine.current_event
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
if matched
|
|
125
|
-
machine.selected_transition_action = action
|
|
126
|
-
machine.selected_transition_metadata = metadata
|
|
127
|
-
end
|
|
128
|
-
matched
|
|
129
|
-
}
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def build_transition_action_callback
|
|
133
|
-
->(machine) {
|
|
134
|
-
callable = machine.selected_transition_action
|
|
135
|
-
unless callable.nil?
|
|
136
|
-
metadata = machine.selected_transition_metadata || {}
|
|
137
|
-
result = call_with_optional_event(
|
|
138
|
-
callable,
|
|
139
|
-
machine.context,
|
|
140
|
-
machine.current_event
|
|
141
|
-
)
|
|
142
|
-
if result.is_a?(Phronomy::TaskResult)
|
|
143
|
-
raise Phronomy::InvalidAsyncTransitionActionError,
|
|
144
|
-
transition_task_error_message(metadata)
|
|
145
|
-
end
|
|
146
|
-
machine.context = result if workflow_context_result?(result)
|
|
147
|
-
end
|
|
148
|
-
}
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def build_entry_callback(callable, state_name)
|
|
152
|
-
->(machine) {
|
|
153
|
-
result = callable.call(machine.context)
|
|
154
|
-
if result.is_a?(Phronomy::TaskResult)
|
|
155
|
-
raise Phronomy::InvalidAsyncEntryActionError,
|
|
156
|
-
"Entry action for state #{state_name.inspect} returned Phronomy::TaskResult. " \
|
|
157
|
-
"Start the asynchronous operation, register its callback/listener, " \
|
|
158
|
-
"and return the WorkflowContext or nil."
|
|
159
|
-
end
|
|
160
|
-
machine.context = result if workflow_context_result?(result)
|
|
161
|
-
}
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def build_exit_callback(callable, state_name)
|
|
165
|
-
->(machine) {
|
|
166
|
-
result = callable.call(machine.context)
|
|
167
|
-
if result.is_a?(Phronomy::TaskResult)
|
|
168
|
-
raise Phronomy::InvalidAsyncEntryActionError,
|
|
169
|
-
"Exit action for state #{state_name.inspect} returned Phronomy::TaskResult. " \
|
|
170
|
-
"Exit actions are synchronous Run-to-Completion callbacks."
|
|
171
|
-
end
|
|
172
|
-
}
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def call_with_optional_event(callable, context, event)
|
|
176
|
-
parameters =
|
|
177
|
-
if callable.respond_to?(:parameters)
|
|
178
|
-
callable.parameters
|
|
179
|
-
else
|
|
180
|
-
callable.method(:call).parameters
|
|
181
|
-
end
|
|
182
|
-
accepts_event = parameters.length >= 2
|
|
183
|
-
accepts_event ? callable.call(context, event) : callable.call(context)
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def workflow_context_result?(result)
|
|
187
|
-
result.respond_to?(:set_graph_metadata)
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def public_destination(destination)
|
|
191
|
-
return :__finish__ if destination == FSMProtocol::FINISH
|
|
192
|
-
|
|
193
|
-
destination
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
def transition_task_error_message(metadata)
|
|
197
|
-
"Transition action " \
|
|
198
|
-
"#{metadata[:from].inspect} --#{metadata[:event].inspect}--> " \
|
|
199
|
-
"#{metadata[:to].inspect} returned Phronomy::TaskResult. " \
|
|
200
|
-
"Start the asynchronous operation, register its callback/listener, " \
|
|
201
|
-
"and return the WorkflowContext or nil."
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Phronomy
|
|
4
|
-
# Domain-owned Workflow metadata, loadable without the Workflow runtime.
|
|
5
|
-
# @api private
|
|
6
|
-
module WorkflowStorageSchema
|
|
7
|
-
STATES = Phronomy::Storage::Resource.new(id: "workflow.states", kind: :records)
|
|
8
|
-
end
|
|
9
|
-
end
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
module Phronomy
|
|
2
|
-
# Internal Engine contract (ADR-042); not an application extension SPI.
|
|
3
|
-
class ExecutionReceiver
|
|
4
|
-
def self.for: (EventLoop event_loop) -> instance
|
|
5
|
-
def self.existing_for: (Runtime runtime) -> instance?
|
|
6
|
-
def initialize: (event_loop: EventLoop) -> void
|
|
7
|
-
def __bound_to?: (EventLoop event_loop) -> bool
|
|
8
|
-
def idle?: () -> bool
|
|
9
|
-
def deliver: (untyped message) -> untyped
|
|
10
|
-
def shutdown: (error: Exception?) -> untyped
|
|
11
|
-
def session_retired: (String fsm_session_id, reason: Symbol) -> untyped
|
|
12
|
-
|
|
13
|
-
private
|
|
14
|
-
|
|
15
|
-
def synchronize: [V] () { () -> V } -> V
|
|
16
|
-
def admit: [V] () { () -> V } -> V
|
|
17
|
-
def post_message: (untyped message, ?admission: bool, ?completion: TaskResult[untyped]?) -> bool
|
|
18
|
-
def assert_event_loop_thread!: () -> void
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
class EventLoop
|
|
22
|
-
def __execution_receiver: (key: untyped) -> ExecutionReceiver?
|
|
23
|
-
def __register_execution_receiver: (key: untyped, receiver: ExecutionReceiver) -> ExecutionReceiver
|
|
24
|
-
def __synchronize_execution_state: [V] () { () -> V } -> V
|
|
25
|
-
def __admit_execution: [V] (ExecutionReceiver receiver) { () -> V } -> V
|
|
26
|
-
def __post_execution: (ExecutionReceiver receiver, untyped message, ?admission: bool, ?completion: TaskResult[untyped]?) -> bool
|
|
27
|
-
def __route_execution_event: (ExecutionReceiver receiver) { () -> untyped } -> bool
|
|
28
|
-
def __receiver_cleanup_complete?: () -> bool
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
class Runtime
|
|
32
|
-
def __event_loop_if_initialized: () -> EventLoop?
|
|
33
|
-
end
|
|
34
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
module Phronomy
|
|
2
|
-
module LLMAdapter
|
|
3
|
-
class Base
|
|
4
|
-
def complete: (untyped chat, String? message, ?config: Hash[untyped, untyped]) -> untyped
|
|
5
|
-
def stream: (untyped chat, String? message, ?config: Hash[untyped, untyped]) { (untyped chunk) -> void } -> untyped
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
class RubyLLM < Base
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
data/sig/phronomy/runtime.rbs
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
module Phronomy
|
|
2
|
-
class TaskResult[A]
|
|
3
|
-
class Outcome[V]
|
|
4
|
-
attr_reader index: Integer
|
|
5
|
-
attr_reader status: (:completed | :failed | :cancelled | :unfinished)
|
|
6
|
-
attr_reader value: V?
|
|
7
|
-
attr_reader error: Exception?
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.completed: [V] (V value, ?name: String?) -> TaskResult[V]
|
|
11
|
-
| (?name: String?) -> TaskResult[nil]
|
|
12
|
-
def self.failed: (Exception error, ?name: String?) -> TaskResult[untyped]
|
|
13
|
-
def self.all_settled: [V] (Array[TaskResult[V]] results) -> TaskResult[Array[Outcome[V]]]
|
|
14
|
-
attr_reader name: String?
|
|
15
|
-
attr_reader parent: TaskResult[untyped]?
|
|
16
|
-
|
|
17
|
-
def status: () -> (:pending | :completed | :failed | :cancelled)
|
|
18
|
-
def done?: () -> bool
|
|
19
|
-
def alive?: () -> bool
|
|
20
|
-
def wait_result: (?timeout: Numeric?) -> A
|
|
21
|
-
def on_complete: () { (A?, Exception?) -> void } -> self
|
|
22
|
-
def map: [B] () { (A) -> B } -> TaskResult[B]
|
|
23
|
-
def flat_map: [B] () { (A) -> TaskResult[B] } -> TaskResult[B]
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
class Execution
|
|
27
|
-
attr_reader invocation_context: InvocationContext
|
|
28
|
-
|
|
29
|
-
def self.run_async: [I, V] (Array[I] inputs, ?timeout: Numeric?, ?cancellation_token: Concurrency::CancellationToken?, ?invocation_context: InvocationContext?) { (I, Execution) -> TaskResult[V] } -> TaskResult[Array[TaskResult::Outcome[V]]]
|
|
30
|
-
def self.run: [I, V] (Array[I] inputs, ?timeout: Numeric?, ?cancellation_token: Concurrency::CancellationToken?, ?invocation_context: InvocationContext?) { (I, Execution) -> TaskResult[V] } -> Array[TaskResult::Outcome[V]]
|
|
31
|
-
def observe: [V] (TaskResult[V] source_result) -> TaskResult[V]
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
class ExecutionTimeoutError < TimeoutError
|
|
35
|
-
attr_reader outcomes: Array[TaskResult::Outcome[untyped]]
|
|
36
|
-
def initialize: (?String message, outcomes: Array[TaskResult::Outcome[untyped]]) -> void
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
class ExecutionCancellationError < CancellationError
|
|
40
|
-
attr_reader outcomes: Array[TaskResult::Outcome[untyped]]
|
|
41
|
-
def initialize: (?String message, outcomes: Array[TaskResult::Outcome[untyped]]) -> void
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
module Concurrency
|
|
45
|
-
class CancellationToken
|
|
46
|
-
def self.timeout_after: (Numeric seconds) -> CancellationToken
|
|
47
|
-
def initialize: (?monotonic_deadline: Float?) -> void
|
|
48
|
-
def remaining_monotonic_seconds: () -> Float?
|
|
49
|
-
def on_cancel: () { () -> void } -> self
|
|
50
|
-
def cancel!: () -> self
|
|
51
|
-
def cancelled?: () -> bool
|
|
52
|
-
def raise_if_cancelled!: (?String message) -> nil
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
module Phronomy
|
|
58
|
-
class InvocationContext
|
|
59
|
-
attr_reader user_id: String?
|
|
60
|
-
attr_reader cancellation_token: Concurrency::CancellationToken?
|
|
61
|
-
attr_reader deadline: untyped
|
|
62
|
-
attr_reader token_budget: Integer?
|
|
63
|
-
attr_reader approval_policy: untyped
|
|
64
|
-
attr_reader redaction_policy: untyped
|
|
65
|
-
attr_reader task_id: String?
|
|
66
|
-
attr_reader parent_task_id: String?
|
|
67
|
-
|
|
68
|
-
def initialize: (?user_id: String?, ?cancellation_token: Concurrency::CancellationToken?, ?deadline: untyped, ?token_budget: Integer?, ?approval_policy: untyped, ?redaction_policy: untyped, ?task_id: String?, ?parent_task_id: String?) -> void
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
module Phronomy
|
|
73
|
-
module Blocking
|
|
74
|
-
def self.call_async: [V] (?timeout: Numeric?, ?cancellation_token: Concurrency::CancellationToken?, ?invocation_context: InvocationContext?) { () -> V } -> TaskResult[V]
|
|
75
|
-
end
|
|
76
|
-
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|