power-loop 9.0.0__tar.gz → 9.1.0__tar.gz
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.
- {power_loop-9.0.0 → power_loop-9.1.0}/PKG-INFO +17 -1
- {power_loop-9.0.0 → power_loop-9.1.0}/README.md +16 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/__init__.py +1 -1
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/agent/stateful_loop.py +1 -1
- power_loop-9.1.0/power_loop/core/control.py +14 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/core/pipeline.py +10 -3
- power_loop-9.1.0/power_loop/runtime/invocation.py +58 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/jobs.py +4 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop.egg-info/PKG-INFO +17 -1
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop.egg-info/SOURCES.txt +1 -0
- power_loop-9.0.0/power_loop/runtime/invocation.py +0 -24
- {power_loop-9.0.0 → power_loop-9.1.0}/LICENSE +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/__init__.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/__init__.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/anthropic_factory.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/attempt_scope.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/capabilities.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/interface.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/llm_factory.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/llm_tooling.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/llm_utils.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/multimodal.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/_vendor/llm_client/proxy_fallback.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/agent/__init__.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/agent/follow_up.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/agent/sink.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/agent/system_prompt.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/agent/types.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/__init__.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/context_policy.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/errors.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/event_payloads.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/events.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/handlers.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/hook_contexts.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/hooks.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/messages.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/protocols.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contracts/tools.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contrib/__init__.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contrib/_redact.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contrib/jsonl_sink.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contrib/logging_sink.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contrib/mcp.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contrib/metrics_sink.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/contrib/otel_sink.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/core/agent_context.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/core/events.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/core/hooks.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/core/pass_turn.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/core/phase.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/core/runner.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/core/state.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/py.typed +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/_tagged_processes.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/abort_outcomes.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/background.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/bash_capture.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/blackboard.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/budget.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/budget_contracts.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/budget_revisions.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/budget_scopes.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/cancellation.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/capability_probe.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/compact.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/completion.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/completion_windows.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/context_window_probe.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/controller_handoff.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/controller_recovery.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/controller_retirement.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/controller_task_exit.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/delegation.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/env.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/exec_backend.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/execution_membership.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/execution_roles.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/executor_lifecycle.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/executor_registry.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/finalization.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/fold.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/fold_adapter.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/fold_calls.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/history_projector.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/history_sanitize.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/host_send_steps.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/human_input.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/image_recall.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/input_dispositions.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/lineage.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/managed_claim.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/managed_completion.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/managed_delivery.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/managed_effects.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/memory.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/message_ref.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/model_attempt_query.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/model_attempts.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/model_budgets.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/model_calls.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/model_exit.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/native_returns.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/nested_tools.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/node_inputs.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/node_resume.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/notes.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/nudges.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/original_owner_review.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/owner_waits.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/pending_calls.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/pending_native.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/pending_owner.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/pricing.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/process_control.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/processing.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/provider.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/recall.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/representation.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/response_capture.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/result_payloads.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/result_proof.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/result_revisions.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/retry.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/review_tools.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/root_context.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/root_control.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/runtime_state.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/send_receipt.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/session_store.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/skills.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/spec.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/steer.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/stop_policy.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/__init__.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/backends/__init__.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/backends/mysql.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/backends/postgres.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/backends/sqlite.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/capabilities.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/context_cache.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/db.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/dialect.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/factory.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/schema.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/store.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/task_schema.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/store/types.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/structured.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/stub_provider.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/subagent_output.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/subagent_resume.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/task_control.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/task_events.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/task_history.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/task_inspection.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/task_query.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/task_runtime.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/task_sessions.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/timer_backend.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/timer_waits.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/timers.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/todos.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/tool_archive.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/tool_attempts.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/tool_billing.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/tool_call_abort.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/tool_call_plans.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/tool_context.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/tool_contracts.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/tool_truncation.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/usage_estimate.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/wait_decisions.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/wait_dispositions.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/wait_effects.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/wait_notifications.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/wait_reviews.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/wait_terminal.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_controller.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_profile.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_resources.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_restore.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_restore_execution.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_restore_resources.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_restore_runner.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_results.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_resume.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/runtime/workflow_tasks.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/__init__.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/background_contract.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/blackboard.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/command_policy.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/command_rules.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/default_manifest.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/default_tools.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/jobs.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/registry.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/shell_contract.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/skill_contract.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/spawn_agent.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/tools/wait_handoff.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/__init__.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/_process_guard.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/admission.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/api.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/continuation.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/control.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/engine.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/facade.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/introspect.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/journal.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/legacy_history.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/result.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/resume.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/runner.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/spec.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/subprocess_executor.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/tool.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/worker.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop/workflow/yaml.py +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop.egg-info/dependency_links.txt +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop.egg-info/requires.txt +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/power_loop.egg-info/top_level.txt +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/pyproject.toml +0 -0
- {power_loop-9.0.0 → power_loop-9.1.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: power-loop
|
|
3
|
-
Version: 9.
|
|
3
|
+
Version: 9.1.0
|
|
4
4
|
Summary: Embeddable agent execution kernel — LLM loop, hooks, events, tools, dynamic sub-agents.
|
|
5
5
|
Author-email: zhangran <zhangran24@126.com>
|
|
6
6
|
License: MIT
|
|
@@ -418,3 +418,19 @@ After the exact charge is locally durable, API delivery failure leaves a pending
|
|
|
418
418
|
budget submission and preserves the real tool result. Reconciliation never calls
|
|
419
419
|
the handler again or reads a replacement price. Managed recovery sources without
|
|
420
420
|
an ordinary callback checkpoint still need a separate adapter.
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
### Host lifecycle extensions
|
|
424
|
+
|
|
425
|
+
Hosts can raise `power_loop.core.control.ControlledLoopStop(reason, message=...)`
|
|
426
|
+
from session-entry or round-start hooks. The pipeline records a controlled stop,
|
|
427
|
+
keeps completed work, and skips memory summarization on that exit. Hosts own
|
|
428
|
+
quota policy and settlement; the SDK has no application currency or user model.
|
|
429
|
+
|
|
430
|
+
`power_loop.runtime.invocation.register_invocation_scope(name, factory, exporter=...)`
|
|
431
|
+
installs a synchronous context manager around each actual tool invocation. The
|
|
432
|
+
factory receives `session_id`, `assistant_seq`, `tool_call_id`, and `tool_name`.
|
|
433
|
+
An optional exporter returns a small JSON snapshot which is saved as
|
|
434
|
+
`host_contexts[name]` on original job creation. Replay retains the original saved
|
|
435
|
+
snapshot; hosts restore it when recovering a child job. Business snapshots do not
|
|
436
|
+
carry execution authority and do not replace the SDK's signed task request.
|
|
@@ -340,3 +340,19 @@ After the exact charge is locally durable, API delivery failure leaves a pending
|
|
|
340
340
|
budget submission and preserves the real tool result. Reconciliation never calls
|
|
341
341
|
the handler again or reads a replacement price. Managed recovery sources without
|
|
342
342
|
an ordinary callback checkpoint still need a separate adapter.
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
### Host lifecycle extensions
|
|
346
|
+
|
|
347
|
+
Hosts can raise `power_loop.core.control.ControlledLoopStop(reason, message=...)`
|
|
348
|
+
from session-entry or round-start hooks. The pipeline records a controlled stop,
|
|
349
|
+
keeps completed work, and skips memory summarization on that exit. Hosts own
|
|
350
|
+
quota policy and settlement; the SDK has no application currency or user model.
|
|
351
|
+
|
|
352
|
+
`power_loop.runtime.invocation.register_invocation_scope(name, factory, exporter=...)`
|
|
353
|
+
installs a synchronous context manager around each actual tool invocation. The
|
|
354
|
+
factory receives `session_id`, `assistant_seq`, `tool_call_id`, and `tool_name`.
|
|
355
|
+
An optional exporter returns a small JSON snapshot which is saved as
|
|
356
|
+
`host_contexts[name]` on original job creation. Replay retains the original saved
|
|
357
|
+
snapshot; hosts restore it when recovering a child job. Business snapshots do not
|
|
358
|
+
carry execution authority and do not replace the SDK's signed task request.
|
|
@@ -15,7 +15,7 @@ Stability tiers
|
|
|
15
15
|
无版本承诺,可随时变更或删除。
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
__version__ = "9.
|
|
18
|
+
__version__ = "9.1.0"
|
|
19
19
|
|
|
20
20
|
# Public LLM contract (SDK-free) re-exported so callers (e.g. writing llm.* hooks or
|
|
21
21
|
# a custom LLMService) don't reach into the internal vendored transport package (H3.4).
|
|
@@ -1737,7 +1737,7 @@ class StatefulAgentLoop:
|
|
|
1737
1737
|
else:
|
|
1738
1738
|
try:
|
|
1739
1739
|
from power_loop.runtime.invocation import invocation_context
|
|
1740
|
-
with invocation_context(sid, pending.get("assistant_seq"), cid):
|
|
1740
|
+
with invocation_context(sid, pending.get("assistant_seq"), cid, name):
|
|
1741
1741
|
raw = await self.tool_registry.invoke_async(name, args)
|
|
1742
1742
|
if not isinstance(raw, str):
|
|
1743
1743
|
raw = json.dumps(raw, ensure_ascii=False)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Host-controlled stops at lifecycle boundaries, separate from business errors."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ControlledLoopStop(Exception):
|
|
5
|
+
"""A host hook requests a terminal result without another model request."""
|
|
6
|
+
|
|
7
|
+
def __init__(self, reason: str, *, message: str = "", status: str = "budget_exceeded"):
|
|
8
|
+
if not reason or status not in ("budget_exceeded", "cancelled", "degraded"):
|
|
9
|
+
raise ValueError("invalid controlled loop stop")
|
|
10
|
+
self.reason = reason
|
|
11
|
+
self.message = message
|
|
12
|
+
self.status = status
|
|
13
|
+
super().__init__(reason)
|
|
14
|
+
|
|
@@ -768,7 +768,7 @@ class AgentPipeline:
|
|
|
768
768
|
# ── Helper: finalize session ──
|
|
769
769
|
|
|
770
770
|
async def _finalize(self, reason: str, *, final_text: str | None = None,
|
|
771
|
-
rounds: int | None = None) -> None:
|
|
771
|
+
rounds: int | None = None, remember: bool = True) -> None:
|
|
772
772
|
if self._finalized:
|
|
773
773
|
return # idempotent: SESSION_ENDED fires exactly once per run
|
|
774
774
|
self._finalized = True
|
|
@@ -780,7 +780,8 @@ class AgentPipeline:
|
|
|
780
780
|
)
|
|
781
781
|
await self.hooks.run_typed_async(HookPoint.SESSION_END, ctx)
|
|
782
782
|
self._emit(AgentEventType.SESSION_ENDED, SessionEndedPayload(reason=reason))
|
|
783
|
-
|
|
783
|
+
if remember:
|
|
784
|
+
await self._maybe_remember(reason=reason, final_text=final_text or "")
|
|
784
785
|
|
|
785
786
|
async def _emit_error_terminal(self, exc: BaseException) -> None:
|
|
786
787
|
"""Emit the ``AGENT_ERROR`` channel + a terminal ``SESSION_ENDED`` after an
|
|
@@ -1605,7 +1606,7 @@ class AgentPipeline:
|
|
|
1605
1606
|
from power_loop.runtime.invocation import invocation_context
|
|
1606
1607
|
with invocation_context(self.session_id,
|
|
1607
1608
|
assistant_seq if assistant_seq is not None else getattr(self.sink, "persisted_assistant_seq", None),
|
|
1608
|
-
tool_call_id):
|
|
1609
|
+
tool_call_id, tool_name):
|
|
1609
1610
|
from power_loop.runtime.task_runtime import check_tool_dispatch
|
|
1610
1611
|
registered = await check_tool_dispatch(self.session_id, tool_name, self.tool_registry, tool_args)
|
|
1611
1612
|
from power_loop.runtime.tool_contracts import validate_registration
|
|
@@ -1668,12 +1669,18 @@ class AgentPipeline:
|
|
|
1668
1669
|
async def run(self, messages: list[LoopMessage]) -> AgentLoopResult:
|
|
1669
1670
|
"""Run the full agent loop. Returns when done, cancelled, or hit round limit."""
|
|
1670
1671
|
from power_loop.core import pass_turn as _pass
|
|
1672
|
+
from power_loop.core.control import ControlledLoopStop
|
|
1671
1673
|
|
|
1672
1674
|
token = _pass.begin() # pass_turn 的状态按 send 隔离(子 agent 内联跑也不串)
|
|
1673
1675
|
self._pass_state = _pass.current()
|
|
1674
1676
|
self._step_texts: list[dict[str, Any]] = []
|
|
1675
1677
|
try:
|
|
1676
1678
|
return await self._run(messages)
|
|
1679
|
+
except ControlledLoopStop as stop:
|
|
1680
|
+
await self._finalize(stop.reason, final_text=stop.message,
|
|
1681
|
+
rounds=self._completed_rounds, remember=False)
|
|
1682
|
+
return self._make_result(stop.status, final_text=stop.message,
|
|
1683
|
+
rounds=self._completed_rounds)
|
|
1677
1684
|
finally:
|
|
1678
1685
|
try:
|
|
1679
1686
|
from power_loop.runtime.task_runtime import preserve_model_usage
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Identity of the actual persisted assistant call currently invoking a tool."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from contextlib import ExitStack, contextmanager
|
|
6
|
+
from contextvars import ContextVar
|
|
7
|
+
|
|
8
|
+
_INVOCATION: ContextVar[tuple[str | None, int | None, str | None] | None] = ContextVar(
|
|
9
|
+
"power_loop_tool_invocation", default=None
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
_SCOPE_FACTORIES = {}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def register_invocation_scope(name, factory, *, exporter=None):
|
|
17
|
+
"""Install a trusted host context manager around each actual invocation."""
|
|
18
|
+
if not isinstance(name, str) or not name or not callable(factory):
|
|
19
|
+
raise ValueError("invalid invocation scope provider")
|
|
20
|
+
_SCOPE_FACTORIES[name] = (factory, exporter)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@contextmanager
|
|
24
|
+
def invocation_context(session_id, assistant_seq, tool_call_id, tool_name=None):
|
|
25
|
+
token = _INVOCATION.set((session_id, assistant_seq, tool_call_id))
|
|
26
|
+
try:
|
|
27
|
+
with ExitStack() as scopes:
|
|
28
|
+
for factory, _exporter in tuple(_SCOPE_FACTORIES.values()):
|
|
29
|
+
scopes.enter_context(
|
|
30
|
+
factory(
|
|
31
|
+
session_id=session_id,
|
|
32
|
+
assistant_seq=assistant_seq,
|
|
33
|
+
tool_call_id=tool_call_id,
|
|
34
|
+
tool_name=tool_name,
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
yield
|
|
38
|
+
finally:
|
|
39
|
+
_INVOCATION.reset(token)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def current_invocation(session_id):
|
|
43
|
+
current = _INVOCATION.get()
|
|
44
|
+
# A child's model run inherits ContextVars but must not inherit its parent's
|
|
45
|
+
# tool identity. A real child tool invocation will install its own context.
|
|
46
|
+
return current[1:] if current and current[0] == session_id else (None, None)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def capture_host_contexts():
|
|
50
|
+
"""Audit-only host snapshots; never part of task authority or request input."""
|
|
51
|
+
import json
|
|
52
|
+
|
|
53
|
+
values = {}
|
|
54
|
+
for name, (_factory, exporter) in tuple(_SCOPE_FACTORIES.items()):
|
|
55
|
+
value = exporter() if exporter is not None else None
|
|
56
|
+
if value is not None:
|
|
57
|
+
values[name] = json.loads(json.dumps(value, allow_nan=False))
|
|
58
|
+
return values
|
|
@@ -727,6 +727,10 @@ class JobManager:
|
|
|
727
727
|
payload["request"] = request_data
|
|
728
728
|
if wait_binding is not None:
|
|
729
729
|
payload["wait_binding"] = wait_binding
|
|
730
|
+
from .invocation import capture_host_contexts
|
|
731
|
+
host_contexts = capture_host_contexts()
|
|
732
|
+
if host_contexts:
|
|
733
|
+
payload["host_contexts"] = host_contexts
|
|
730
734
|
operation = await self._insert_operation(tx, job_id=job_id, version=1, actor=actor, action="create",
|
|
731
735
|
key=key, fingerprint=fingerprint, call_ref=call_ref, tool_call_id=tool_call_id,
|
|
732
736
|
payload=payload)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: power-loop
|
|
3
|
-
Version: 9.
|
|
3
|
+
Version: 9.1.0
|
|
4
4
|
Summary: Embeddable agent execution kernel — LLM loop, hooks, events, tools, dynamic sub-agents.
|
|
5
5
|
Author-email: zhangran <zhangran24@126.com>
|
|
6
6
|
License: MIT
|
|
@@ -418,3 +418,19 @@ After the exact charge is locally durable, API delivery failure leaves a pending
|
|
|
418
418
|
budget submission and preserves the real tool result. Reconciliation never calls
|
|
419
419
|
the handler again or reads a replacement price. Managed recovery sources without
|
|
420
420
|
an ordinary callback checkpoint still need a separate adapter.
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
### Host lifecycle extensions
|
|
424
|
+
|
|
425
|
+
Hosts can raise `power_loop.core.control.ControlledLoopStop(reason, message=...)`
|
|
426
|
+
from session-entry or round-start hooks. The pipeline records a controlled stop,
|
|
427
|
+
keeps completed work, and skips memory summarization on that exit. Hosts own
|
|
428
|
+
quota policy and settlement; the SDK has no application currency or user model.
|
|
429
|
+
|
|
430
|
+
`power_loop.runtime.invocation.register_invocation_scope(name, factory, exporter=...)`
|
|
431
|
+
installs a synchronous context manager around each actual tool invocation. The
|
|
432
|
+
factory receives `session_id`, `assistant_seq`, `tool_call_id`, and `tool_name`.
|
|
433
|
+
An optional exporter returns a small JSON snapshot which is saved as
|
|
434
|
+
`host_contexts[name]` on original job creation. Replay retains the original saved
|
|
435
|
+
snapshot; hosts restore it when recovering a child job. Business snapshots do not
|
|
436
|
+
carry execution authority and do not replace the SDK's signed task request.
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"""Identity of the actual persisted assistant call currently invoking a tool."""
|
|
2
|
-
from __future__ import annotations
|
|
3
|
-
|
|
4
|
-
from contextlib import contextmanager
|
|
5
|
-
from contextvars import ContextVar
|
|
6
|
-
|
|
7
|
-
_INVOCATION: ContextVar[tuple[str | None, int | None, str | None] | None] = ContextVar(
|
|
8
|
-
"power_loop_tool_invocation", default=None)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@contextmanager
|
|
12
|
-
def invocation_context(session_id, assistant_seq, tool_call_id):
|
|
13
|
-
token = _INVOCATION.set((session_id, assistant_seq, tool_call_id))
|
|
14
|
-
try:
|
|
15
|
-
yield
|
|
16
|
-
finally:
|
|
17
|
-
_INVOCATION.reset(token)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def current_invocation(session_id):
|
|
21
|
-
current = _INVOCATION.get()
|
|
22
|
-
# A child's model run inherits ContextVars but must not inherit its parent's
|
|
23
|
-
# tool identity. A real child tool invocation will install its own context.
|
|
24
|
-
return current[1:] if current and current[0] == session_id else (None, None)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|