AbstractRuntime 0.8.5__tar.gz → 0.9.1__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.
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/.github/workflows/ci.yml +53 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/CHANGELOG.md +39 -2
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/PKG-INFO +4 -4
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/README.md +1 -1
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/api.md +7 -1
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/automations.md +3 -2
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/faq.md +6 -4
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/integrations/abstractcore.md +31 -7
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/llms-full.txt +48 -15
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/llms.txt +3 -3
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/pyproject.toml +6 -4
- abstractruntime-0.9.1/release-notes.md +12 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/commands.py +39 -1
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/controller.py +14 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/runtime.py +15 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/tools.py +28 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/__init__.py +18 -0
- abstractruntime-0.9.1/src/abstractruntime/integrations/abstractcore/command_sandbox_host.py +29 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/effect_handlers.py +4 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/local_helper_tools.py +28 -3
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/run_facade.py +117 -114
- abstractruntime-0.9.1/src/abstractruntime/integrations/abstractcore/structured_facade.py +51 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/tool_executor.py +30 -4
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/workspace_scoped_tools.py +168 -23
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/utils/workspace_paths.py +48 -2
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/compiler.py +10 -1
- abstractruntime-0.9.1/tests/test_abstractcore_structured_facade.py +54 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_commands.py +38 -0
- abstractruntime-0.9.1/tests/test_automation_occurrence_input_resolver.py +92 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_tool_approval.py +4 -1
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_browser_probe_target_walling.py +15 -0
- abstractruntime-0.9.1/tests/test_command_sandbox_host_facade.py +27 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_packaging_extras.py +3 -3
- abstractruntime-0.9.1/tests/test_r12_workspace_sandbox.py +407 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_shell_tool_exposure.py +3 -1
- abstractruntime-0.9.1/tests/test_voice_stream_is_not_a_wait.py +256 -0
- abstractruntime-0.9.1/tests/test_workspace_context_allowed_workspaces.py +75 -0
- abstractruntime-0.9.1/tests/test_workspace_writable_paths.py +69 -0
- abstractruntime-0.8.5/release-notes.md +0 -1
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/.github/workflows/release.yml +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/.gitignore +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/ACKNOWLEDGMENTS.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/CODE_OF_CONDUCT.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/CONTRIBUTING.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/LICENSE +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/ROADMAP.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/SECURITY.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/adr/0001_layered_coupling_with_abstractcore.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/adr/0002_execution_modes_local_remote_hybrid.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/adr/0003_provenance_tamper_evident_hash_chain.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/adr/0004_runtime_owns_run_scoped_media_execution_truth.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/adr/0005_runtime_owns_abstractcore_host_discovery_queries.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/adr/0006_runtime_owns_durable_abstractcore_bloc_prompt_cache.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/adr/0007_runtime_relays_core_owned_model_residency_truth.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/adr/README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/architecture.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/artifacts.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/001_runtime_kernel.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/002_persistence_and_ledger.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0030_runtime_host_facades_for_comms_telegram_and_tool_specs.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0032_runtime_durable_outbound_comms_truth.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0033_runtime_host_local_prompt_cache_export_import_surface.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0035_model_residency_provider_truth_for_local_http_clients.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0037_visualflow_generate_music_node_compiler_parity.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0039_runtime_music_structure_prompt_bool_contract.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/003_wait_primitives.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0040_task_agnostic_local_residency_listing.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0041_runtime_hardware_extras_avoid_nonpermissive_document_stacks.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0042_core_vision_upscale_and_parameter_surface.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0043_runtime_vision_adapter_and_batch_surface.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/004_scheduler_driver.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/005_abstractcore_integration.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/006_snapshots_bookmarks.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/007_provenance_hash_chain.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/009_artifact_store.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/010_examples_and_composition.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/011_subworkflow_support.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/012_run_store_query_and_scheduler_support.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/013_effect_retries_and_idempotency.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/016_runtime_aware_parameters.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/019_runtime_host_facade_for_core_operator_surfaces.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/020_runtime_gateway_install_boundary.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/021_runtime_gateway_env_namespace_cleanup.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/022_model_residency_control_plane.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/023_truthful_local_media_residency_boundaries.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/024_runtime_owned_run_scoped_media_execution.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/026_runtime_host_discovery_facade_for_core_catalogs.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/027_runtime_durable_bloc_prompt_cache_facade.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/028_runtime_bloc_kv_lifecycle_and_pruning.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/029_runtime_music_generation_and_discovery_via_abstractcore.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0846_mlx_instance_scheduling_and_execution_controls.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/completed/0847_automations_v1_controller_contracts_occurrences_triggers.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/001_integrations_abstractcore.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/001_runtime_kernel.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/002_persistence_and_ledger.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/002_snapshots_bookmarks.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/0034_agent_runtime_convenience_constructor.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/003_provenance_ledger_chain.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/003_wait_resume_and_scheduler.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/004_effect_handlers_and_integrations.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/004_tests.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/005_docs_updates.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/005_examples_and_composition.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/006_ai_fingerprint_and_provenance.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/DEPRECATED_README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/deprecated/abstractruntime_docs_final_02a7373b.plan.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/0070_standalone_wui_browser_session_security_contract.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/008_signatures_and_keys.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/014_remote_tool_worker_executor.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/017_limit_warnings_and_observability.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/018_workspace_access_policy_for_media_and_tools.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/0233_real_run_cancellation.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/025_runtime_retention_and_purge_contract.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/026_context_checkpoint_self_compression.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/027_quote_provenance_discipline.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/028_selective_artifact_rehydration.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/0845_session_prompt_cache_resume_and_purge_contract.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/0848_automations_v2_external_event_inbox_and_run_triggers.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_portability/0065_portable_process_and_lock_layer.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_portability/0066_portable_io_and_media_reader.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_portability/README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0044_meta_analysis_record.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0045_crash_replay_harness_and_ordering_invariant.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0046_per_run_driver_exclusion.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0047_indexed_idempotency_lookup.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0048_durable_io_unification.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0049_llm_client_mechanical_split.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0050_control_sidecar_all_writers.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0051_runtime_owned_durable_event_mailbox.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0052_sync_store_event_loop_tripwire.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0053_bounded_run_vars_growth.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0054_runtime_health_counters.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0055_jsonl_store_honesty.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0064_prompt_cache_fingerprint_stability.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0067_durable_write_discipline.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/0068_hot_path_store_reads.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/planned/runtime_systemic_reliability/README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/0031_runtime_tool_spec_adapters_for_gateway_and_mcp.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/0036_local_media_residency_bridge_to_core_residency.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/0038_core_server_pool_residency_affinity.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/0069_document_renderer_professional_figures.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/runtime_systemic_reliability/0056_schema_version_and_quarantine_loading.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/runtime_systemic_reliability/0057_trust_boundary_stamp_registry.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/runtime_systemic_reliability/0058_terminal_run_archival_helper.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/runtime_systemic_reliability/0059_memory_span_handler_extraction.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/runtime_systemic_reliability/0060_visualflow_compiler_decomposition.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/runtime_systemic_reliability/0061_root_api_deprecation_machinery.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/runtime_systemic_reliability/0062_dependency_honesty_extras.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/runtime_systemic_reliability/0063_b3_envelope_lane_unification.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/backlog/proposed/runtime_systemic_reliability/README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/email.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/entity-runtime.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/evidence.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/getting-started.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/limits.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/manual_testing.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/mcp-worker.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/proposal.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/provenance.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/snapshots.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/tool-approval.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/tools-comms.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/troubleshooting.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/docs/workflow-bundles.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/examples/01_hello_world.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/examples/02_ask_user.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/examples/03_wait_until.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/examples/04_multi_step.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/examples/05_persistence.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/examples/06_llm_integration.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/examples/07_react_agent.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/examples/README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/mkdocs.yml +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/pytest.ini +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/scripts/backfill_diary_edges.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/scripts/generate_llms_full.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automation_queries.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/adapters.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/attention.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/bundle.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/bundles/automation-controller/flows/controller.json +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/bundles/automation-controller/manifest.json +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/ledger.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/models.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/automations/service.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/config.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/effect_cancellation.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/event_keys.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/health.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/live_deltas.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/models.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/policy.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/progress_channel.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/run_attribution.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/run_identity.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/run_lifecycle.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/spec.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/tool_scope.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/core/vars.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/documents/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/documents/charts.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/documents/docx.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/documents/pdf.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/email/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/email/actions.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/email/automations.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/email/binding.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/email/feeder.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/email/frame.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/email/inbox.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/evidence/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/evidence/recorder.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/history_bundle.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/act_only.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/chat.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/communities.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/diary.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/digest.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/entity_runtime.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/fingerprint.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/lease.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/life.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/memory_reader.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/night_voice.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/phase_graph.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/phase_spec.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/prelude.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/prompt_overlay.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/reflection.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/spec/entity_phases.vendored.json +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/substrate.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/tool_effects.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/tool_policy.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/identity/visit_workflow.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/agora_tools.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/comms_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/config_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/constants.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/data_registry_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/default_tools.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/discovery_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/discovery_queries.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/email_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/embeddings_client.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/factory.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/host_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/llm_client.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/logging.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/mcp_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/mcp_worker.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/media_subprocess.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/observability.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/output_specs.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/server_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/session_attachments.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/summarizer.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/telegram_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/tool_effects.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractcore/tool_inventory_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractmemory/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractmemory/brain_handlers.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractmemory/effect_handlers.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractmemory/identity_support.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/integrations/abstractmemory/seam_handlers.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/memory/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/memory/active_context.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/memory/active_memory.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/memory/compaction.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/memory/kg_packets.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/memory/memact_composer.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/memory/recall_levels.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/memory/token_budget.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/rendering/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/rendering/agent_trace_report.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/rendering/json_stringify.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/scheduler/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/scheduler/convenience.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/scheduler/multi_store.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/scheduler/registry.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/scheduler/scheduler.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/session_history.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/session_turns.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/artifacts.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/base.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/commands.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/in_memory.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/json_files.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/lease.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/ledger_chain.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/ledger_slim.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/observable.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/offloading.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/serialize.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/snapshots.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/sqlite.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/storage/steer_sidecar.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/triggers/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/triggers/email_received.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/triggers/manual.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/triggers/protocol.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/triggers/registry.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/triggers/schedule.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/turn_grounding.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/utils/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/utils/atomic_files.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/utils/file_filters.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/agent_adapter.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/context_adapter.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/control_adapter.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/effect_adapter.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/event_adapter.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/function_adapter.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/memact_adapter.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/subflow_adapter.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/adapters/variable_adapter.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/flow.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/agent_ids.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/builtins.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/code_executor.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/execution_metrics.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/executor.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/function_library.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/models.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/multi_entry_lowering.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/visualflow_compiler/visual/pin_expressions.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/workflow_bundle/__init__.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/workflow_bundle/models.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/workflow_bundle/packer.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/workflow_bundle/reader.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/src/abstractruntime/workflow_bundle/registry.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/README.md +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/automation_harness.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/conftest.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/email_wp2_support.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/live_email/conftest.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/live_email/live_email_support.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/live_email/test_email_live_runtime.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_abstractcore_comms_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_abstractcore_discovery_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_abstractcore_host_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_abstractcore_run_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_abstractcore_server_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_abstractcore_telegram_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_active_context_policy.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_active_memory.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_agora_agent_alias_identity.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_agora_tools_http.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_analyze_media_addressing_and_walling.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_answer_user_effect.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_artifacts.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_controller.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_controller_recovery.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_definition.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_discussion_isolation.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_email_results.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_growing_context.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_index.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_next_fire.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_occurrence_recovery.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_replay_read_only.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_retry.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_session_turns.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_automation_status.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_budget_law_no_unrequested_caps.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_capability_default_reasoning.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_chat_summarizer_integration.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_code_node_restricted_python.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_command_store.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_compaction_helpers.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_compaction_summarizer_route.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_config_facade_models_engines.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_control_adapter_while.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_controller_bundle_packaged.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_crash_ordering_inversions.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_create_if_absent.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_data_registry_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_default_tools_camera_gating.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_default_tools_comms_gating.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_default_tools_include_skim_files.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_default_tools_include_skim_folders.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_default_tools_include_skim_web.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_default_tools_search_files_executor.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_diary_capture.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_diary_write_rescue.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_directory_lease.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_disabled_toolsets_seam.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_discovery_survives_unbuildable_default.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_discovery_tts_unavailable_reason.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_discovery_voice_openai_api_key.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_discussion_session_anchor.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_document_markdown_tables.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_document_renderers_hr_quote.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_durable_toolsets.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_durable_write_discipline.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_e2e_tool_calls_idempotency_lmstudio.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_effect_cancellation.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_effect_issuance_idempotency.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_effect_payload_stays_json_serializable.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_election_consequence_teaching.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_email_binding_and_refiner.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_email_gate_fixes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_email_inbox_and_trigger.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_email_regate_fixes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_email_review_fixes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_email_self_trigger_loop.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_email_toolset_and_walls.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_emergence_experiment.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_emit_event_uses_wait_index.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_emit_event_without_workflow_registry.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_endpoint_profile_route_context.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_awake_memory_fixes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_brain_effects.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_chat_driver.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_chat_tools_reflection.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_diary.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_execute_tool.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_fetch_url_tool.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_history_window.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_life_loop.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_memory_richness.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_phase_graph_conformance.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_react_visit_window.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_recent_memories.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_runtime.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_search_memory.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_sleep_bound_and_yield_attribution.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_substrate_resolution.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_visit_honesty.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_workspace_cap.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_entity_workspace_tools.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_event_wait_index.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_every_path_bearing_tool_is_walled.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_evidence_recorder.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_evidence_recorder_post_policy_envelope.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_execute_command_output_offload.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_execution_capability_discovery.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_explicit_eject_other_clients.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_factory_default_retry_policy.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_factory_timeouts_default_to_abstractcore_config.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_format_repair_nudge.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_fresh_install_no_provider.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_gateway_facades_c4899.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_git_read_only_refiner.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_hf_process_residency_merge.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_history_window_multimodal.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_hot_path_store_reads.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_indexed_idempotency_lookup.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_integration_abstractcore.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_integrations_abstractcore.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_json_file_run_store_children_index.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_json_run_cache_bound.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_json_store_scan_memo.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_jsonl_ledger_recovery.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_kg_learn_and_recall_contract.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_ledger_chain.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_ledger_record_slimming.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_ledger_subscription.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_live_token_deltas.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_media_artifact_refs.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_media_artifact_refs_persist_across_restart.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_media_uses_source_path_label.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_payload_shape_refusal.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_requires_prompt.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_response_schema_normalization.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_structured_output_fallback.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_text_phase_progress.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_truncation_retry_contract.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_use_context_appends_turn.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_call_verbatim_payload_capture.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_client_grounding_tail.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_client_media_artifacts.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_client_system_context.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_client_tool_call_parsing.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_retry_classification.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_llm_streaming_on_token.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_local_helper_tool_exposure.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_local_residency_host_sweep.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_local_runtime_timeout_kwarg_policy.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_max_iterations_ceiling.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_mcp_remote_tool_executor.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_mcp_runs_untrusted_and_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_mcp_worker_logging.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_mcp_worker_security.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_mcp_worker_stdio.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_media_artifact_resolution.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_media_capability_default_routing.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_media_only_requests_skip_text_client.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_media_subprocess.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memact_composer_from_kg_result.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_appraise_handler.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_communities.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_kg_assert_attributes_defaults.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_kg_packets.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_kg_predicate_aliasing.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_kg_query_packetization_restart.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_kg_query_recall_level_policy.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_kg_semantic_query_ranking.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_note_effect.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_query_effect.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_query_rich_filters.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_scope_and_rehydrate_effect.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_seam_handlers.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_seam_sqlite_durability.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_memory_tag_effect.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_mlx_generation_serialization.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_mlx_process_residency_merge.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_model_eject_cancel.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_model_residency_clean_switch.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_model_residency_control_plane.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_model_residency_lock_and_context_estimate.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_multi_store_scheduler.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_multimodal_abstractcore_integration.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_native_mlx_application_wiring.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_native_mlx_execution_controls_live.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_native_tool_channel.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_night_voice.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_no_default_provider_refusal_ux.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_offload_answer_chain_c4978.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_offloaded_node_traces_report_unknown_not_zero.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_offloading.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_parallel_readonly_tool_execution.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_pause_resume.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_pdf_unicode_rendering.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_personal_cycle.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_phantom_attachment_index.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_phase_graph_artifact_control.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_phase_graph_obedience.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_phase_vocabulary_migration.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_pooled_client_strips_construction_cache_key.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_prompt_cache_export_import.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_prompt_cache_fingerprint_stability.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_prompt_cache_modules.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_prompt_cache_posture_inheritance.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_prompt_cache_thinking_and_prompt_only.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_prompt_overlay.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_provider_endpoint_profile_resolution.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_provider_pin_routing_isolation.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_queryable_run_store.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_read_file_fallback_to_session_attachments.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_read_idle_threading.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_readoption_experiment.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_real_integration.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_realize_election.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_recall_levels_policy.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_remote_client_cancel.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_remote_llm_client.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_remote_speculation_defaults.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_rendering_agent_trace_report.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_rendering_json_stringify.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_report_branding.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_resident_media_generation.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_resume_concurrent_same_wait.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_retry_idempotency.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_run_history_bundle.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_run_index_workspace_root.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_run_mutation_lock.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_run_scoped_tool_policy.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_run_tool_scope_ceiling.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_browser_session_boundary.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_config_max_output_tokens_fallback.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_default_provider_model_refresh.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_effect_invocation_trace.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_health_and_bounded_vars.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_install_boundary.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_llm_call_grounding_in_ledger.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_node_traces.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_start_seeds_tool_support.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_runtime_tick_step_gate.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_scheduler.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_send_email_refiner.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_send_email_self_default_policy.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_session_attachments_registry_and_open_tool.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_session_history.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_session_prompt_cache_attribution.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_session_prompt_cache_visibility.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_session_route_stamp.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_session_start_cost.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_snapshots.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_speculation_inheritance.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_speculation_reaches_provider_construction.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_sqlite_ledger_store.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_start_subworkflow_async_wait.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_start_subworkflow_inherit_context_merges_messages.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_start_subworkflow_workspace_inheritance.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_steer_sidecar.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_storage_deletion.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_structured_output_schema_enum.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_subworkflow.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_terminal_effect_completion.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_terminal_resume_appends_ledger_completion.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_thinking_inheritance.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tick_completion_includes_output_in_ledger.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_approval_executor.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_approval_resume_executes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_approval_wait_key_identity.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_calls_idempotency_keys.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_catalog.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_descriptor_registry.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_executor_argument_sanitization.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_executor_error_output_detection.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_executor_filename_alias.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_executor_kwarg_canonicalization.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_executor_read_file_aliases.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_executor_timeout.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_inventory_facade.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_invoke_effect.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_policy_and_mounts.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_tool_wait_allowlist_safety.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_topic_election_world_model.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_trace_context_propagation.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_trigger_registry.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_trigger_schedule_math.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_turn_grounding_byte_stability.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_turn_grounding_carriers_a3.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_vars_query_effect.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visit_ab_fixture.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visit_midturn_elections.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visit_midturn_resume.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visit_workflow.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_agent_output_context_includes_messages.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_agent_skills_block_passthrough.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_agent_tool_observations_persist_across_restart.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_agent_use_context_inherits_attachments.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_agent_use_context_persists_tool_observations.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_agent_use_context_persists_turn.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_entity_memory_nodes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_flow_end_effect_only_persistence.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_llm_call_partial_override.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_llm_call_schema_ref_resolution.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_memact_compose_node.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_memory_kg_query_outputs_propagate.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_memory_kg_resolve_outputs_propagate.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_multi_entry_loop_overrides.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_unknown_node_type_refuses.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visual_wait_event_deadline_passthrough.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_add_message_builtin.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_add_message_node_appends_to_active_context.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_agora_react_agent.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_call_tool_node.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_capability_routes_and_thinking.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_compiler_basic.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_context_and_builder_nodes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_continue_on_error.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_edit_json_schema_node.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_event_inbox_react_agent.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_file_nodes_workspace.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_function_library.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_get_element_node.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_get_random_element_node.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_get_var_node.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_has_tools_builtin.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_llm_call_context_attachments_map_to_media.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_llm_call_multimodal_output.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_make_object_node.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_media_nodes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_memory_effect_nodes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_memory_source_pins.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_pin_expressions.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_prompt_only.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_random_nodes.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_schema_enum_switch.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_string_contains_replace.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_visualflow_tool_parameters_node.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_voice_openai_api_key_path.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_w4_feelings_lens.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_wait_event_deadline.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_wait_event_prompt_metadata.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_wait_until_streak.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_wait_until_utc_normalization.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_workflow_bundle_registry.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_workspace_builtin_deny.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_workspace_policy_absolute_reanchor.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_workspace_policy_allowlist_mode.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_workspace_policy_mount_virtual_paths.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_workspace_policy_tool_calls_persist_across_restart.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_workspace_prompt_context.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_workspace_read_only.py +0 -0
- {abstractruntime-0.8.5 → abstractruntime-0.9.1}/tests/test_write_chart.py +0 -0
|
@@ -69,6 +69,59 @@ jobs:
|
|
|
69
69
|
tests/test_trigger_registry.py \
|
|
70
70
|
tests/test_workspace_read_only.py
|
|
71
71
|
|
|
72
|
+
# The command sandbox end to end on Linux: run vars -> TOOL_CALLS handler ->
|
|
73
|
+
# `_sandbox` stamp -> AbstractCore's spawning tools inside bubblewrap. The
|
|
74
|
+
# end-to-end tests in tests/test_r12_workspace_sandbox.py skip with their
|
|
75
|
+
# reason on a host without an OS sandbox, so the job above proves nothing
|
|
76
|
+
# about Linux. This job installs bubblewrap, lets it create user namespaces
|
|
77
|
+
# (Ubuntu 24.04 restricts them through AppArmor by default), and FAILS unless
|
|
78
|
+
# every sandbox test ran and passed: a skip here is a red job, never a green one.
|
|
79
|
+
linux-sandbox:
|
|
80
|
+
name: Linux command sandbox (bubblewrap)
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@v4
|
|
84
|
+
- uses: actions/setup-python@v5
|
|
85
|
+
with:
|
|
86
|
+
python-version: "3.12"
|
|
87
|
+
cache: pip
|
|
88
|
+
- name: Install bubblewrap
|
|
89
|
+
run: |
|
|
90
|
+
sudo apt-get update
|
|
91
|
+
sudo apt-get install -y bubblewrap
|
|
92
|
+
# bwrap is not setuid on Ubuntu: it needs unprivileged user namespaces.
|
|
93
|
+
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
|
|
94
|
+
bwrap --version
|
|
95
|
+
bwrap --ro-bind / / --dev /dev --proc /proc -- /bin/true
|
|
96
|
+
uname -r
|
|
97
|
+
- name: Install
|
|
98
|
+
run: |
|
|
99
|
+
python -m pip install -U pip
|
|
100
|
+
python -m pip install -e ".[test]"
|
|
101
|
+
- name: Pytest (sandbox tests must run, not skip)
|
|
102
|
+
run: |
|
|
103
|
+
python -m pytest -rs -p no:cacheprovider \
|
|
104
|
+
tests/test_r12_workspace_sandbox.py tests/test_command_sandbox_host_facade.py \
|
|
105
|
+
--junitxml=sandbox-junit.xml
|
|
106
|
+
- name: Assert the sandbox tests ran
|
|
107
|
+
run: |
|
|
108
|
+
python - <<'PY'
|
|
109
|
+
import sys
|
|
110
|
+
import xml.etree.ElementTree as ET
|
|
111
|
+
|
|
112
|
+
cases = list(ET.parse("sandbox-junit.xml").getroot().iter("testcase"))
|
|
113
|
+
skipped = [c for c in cases if c.find("skipped") is not None]
|
|
114
|
+
failed = [c for c in cases if c.find("failure") is not None or c.find("error") is not None]
|
|
115
|
+
e2e = [c for c in cases if (c.get("name") or "").startswith("test_e2e_")]
|
|
116
|
+
e2e_passed = [c for c in e2e if c not in skipped and c not in failed]
|
|
117
|
+
passed = len(cases) - len(skipped) - len(failed)
|
|
118
|
+
print(f"sandbox tests: {len(cases)} collected, {passed} passed, {len(skipped)} skipped, {len(failed)} failed; end-to-end passed {len(e2e_passed)}/{len(e2e)}")
|
|
119
|
+
for c in skipped:
|
|
120
|
+
print("SKIPPED:", c.get("name"), "-", (c.find("skipped").get("message") or ""))
|
|
121
|
+
if len(e2e) < 7 or len(e2e_passed) != len(e2e) or skipped or failed:
|
|
122
|
+
sys.exit("The sandbox tests did not all run and pass inside bubblewrap on this Linux host.")
|
|
123
|
+
PY
|
|
124
|
+
|
|
72
125
|
build:
|
|
73
126
|
name: Build distributions
|
|
74
127
|
runs-on: ubuntu-latest
|
|
@@ -5,9 +5,46 @@ All notable changes to AbstractRuntime will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [0.9.1] - 2026-10-08
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
### Security
|
|
11
|
+
|
|
12
|
+
- `browser_probe`: a local target (path or `file://` URL) now carries the run's `_sandbox` stamp, the same scope the commands get. AbstractCore 2.25.1 serves the page from a loopback origin limited to that scope instead of `file://`, so a page cannot load refused files as subresources. Needs AbstractCore 2.25.1 (an older `browser_probe` refuses the unknown argument and runs nothing). Test: `tests/test_browser_probe_target_walling.py`.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- `stream_voice(...)` is never a wait. It used to start the child run parked on `WAIT_EVENT abstractcore.voice.tts.stream:<uuid>` for the whole stream: hosts folded that waiting record into the CALLER'S run (a Read aloud during a live turn read as "Waiting for an event"), and a host that died mid-stream left the child waiting forever. Now nothing durable exists while audio streams; when the stream ends (done, error, cancel or the consumer closing it) the child run is created already COMPLETED with the outcome. Its id is allocated up front: `runtime_start` carries it as `child_run_id` (schema `abstractruntime.tts_stream.start.v2`, no `wait_key`), as does the trace metadata. A stream cut by a crash leaves no run.
|
|
17
|
+
- `AbstractCoreRunFacade.close_interrupted_voice_stream(child_run_id, *, reason)` finishes a legacy streamed-speech wait left by an older process (completed, `errors[0] = {"code": "interrupted", "message": reason}`); `is_interrupted_voice_stream_wait(waiting)` and `LEGACY_VOICE_STREAM_WAIT_KEY_PREFIX` recognise one (exported from `integrations.abstractcore`). AbstractGateway calls it at startup.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Requires AbstractCore 2.25.1 or newer (`abstractcore>=2.25.1` in the base install and the `[apple]`/`[gpu]` extras): the Linux command sandbox reaches an allowed folder inside a refused one, and `browser_probe` accepts the run's `_sandbox` stamp.
|
|
22
|
+
|
|
23
|
+
## [0.9.0] - 2026-10-05
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- `Runtime.set_occurrence_input_resolver(fn)`: a host hook called at each automation occurrence's admission, as `fn(definition, input_data) -> input_data`. Its answer is frozen into the occurrence's prepared inputs, so replays stay byte-identical; a non-dict answer fails the admission; with no resolver set nothing changes. AbstractGateway uses it to resolve the workspaces of an automation that follows its owner's default at each run, instead of a snapshot taken at save time. Test: `tests/test_automation_occurrence_input_resolver.py`.
|
|
28
|
+
|
|
29
|
+
- Command sandbox: `execute_command`, `shell_exec`, `local_helper_start` and AbstractAgent's `execute_python` (0.3.18 or newer; an older one fails on the unknown argument and runs nothing) receive the run's effective workspace set as the hidden `_sandbox` argument (`sandbox_stamp(scope)`, built on every call from the same workspace vars the file tools read; `execute_python` starts in the stamp's private workspace; a model- or payload-supplied `_sandbox` is always replaced or dropped), and run inside AbstractCore's OS sandbox (`abstractcore.tools.sandbox`: macOS `sandbox-exec`, Linux `bwrap` or Landlock). `local_helper_start` and the entity exec tool apply it themselves (the entity's workspace and whitelisted mounts). With no sandbox on the host, or an AbstractCore without the sandbox module, the call is refused with one sentence before anything runs and the run continues.
|
|
30
|
+
|
|
31
|
+
- `integrations.abstractcore.command_sandbox_host`: hosts configure the command sandbox through the runtime (`configure_host`, `host_policy`, `host_sandbox_kind`, `KIND_LABELS`, `KIND_NONE`, `reset_host_for_tests`; pure re-exports of `abstractcore.tools.sandbox`), so a host never imports AbstractCore directly. Used by AbstractGateway's `serve`.
|
|
32
|
+
- `MappingToolExecutor` never drops the `_sandbox` stamp: a tool whose signature cannot take it (an AbstractAgent older than 0.3.18) gets a failed result naming the stamp and does not run. Its argument-name normalization never maps a model key (`sandbox`, `registry_namespace`, ...) onto a hidden `_`-prefixed parameter.
|
|
33
|
+
- CI: a `linux-sandbox` job installs bubblewrap on Ubuntu and runs the command-sandbox tests end to end inside it (the end-to-end tests now run inside the host's OS sandbox: macOS `sandbox-exec` or Linux bubblewrap); the job fails when any of them is skipped.
|
|
34
|
+
- `workspace_writable_paths`: writable exceptions inside read-only roots (`workspace_read_only_paths`), the more specific rule winning. The tool scope, `path_is_read_only` and VisualFlow writers honour them; child runs and file nodes inherit the parent's exactly and never add one. Used by AbstractGateway 0.13.0 for "Allow everything, refuse listed workspaces" with a read-only default.
|
|
35
|
+
- `integrations.abstractcore.structured_facade` (also flat from `integrations.abstractcore`): `parse_response_format` and AbstractCore's own `ResponseFormatError`, so hosts check an OpenAI `response_format` without importing AbstractCore. Used by AbstractGateway 0.13.0's `/v1/chat/completions`.
|
|
36
|
+
- Workspace context of a tool-using `LLM_CALL`: after the default working directory (the run's own workspace), `Allowed workspaces:` lists each allowed workspace outside it with its mode (`(read-only)` / `(read & write)`, from `workspace_read_only_paths` and `workspace_writable_paths`), and under `all_except_ignored` `Everything else: (…)`; refused paths are never listed as allowed. Used by AbstractGateway 0.13.0 on every run start.
|
|
37
|
+
- `automation.unarchive`: an archived automation comes back paused with its history intact; a controller that ended because it was archived restarts and parks on its wake wait (observation `automation.unarchived`).
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- Workspace nesting: the most specific row wins. Among `workspace_root`, `workspace_allowed_paths` and `workspace_ignored_paths`, the longest real-path prefix of a path decides (a refusal wins a tie); a refused folder no longer refuses an allowed workspace inside it, and a refused folder inside an allowed one still refuses its subtree. Built-in protection stays absolute. Same rule as AbstractGateway's validation and the sandbox profile.
|
|
42
|
+
- The workspace context now says "Shell commands run inside an OS sandbox limited to these workspaces." and describes refused paths as "Excluded paths (a more specific allowed workspace inside one stays reachable)".
|
|
43
|
+
- Requires AbstractCore 2.25.0 or newer (`abstractcore>=2.25.0` in the base install and the `[apple]`/`[gpu]` extras): the command sandbox and `structured_facade` use it.
|
|
44
|
+
|
|
45
|
+
### Removed
|
|
46
|
+
|
|
47
|
+
- `workspace_shared_path` / `SHARED_WORKSPACE_KEY` / `shared_workspace_path` (added during 0.9.0 development, never released): AbstractGateway 0.13.0 has no shared workspace any more (round 11), so the workspace context names no "Shared workspace"; the allowed workspaces and their modes are listed as before. A stale key in a run's vars is ignored.
|
|
11
48
|
|
|
12
49
|
## [0.8.5] - 2026-10-03
|
|
13
50
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: AbstractRuntime
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: AbstractRuntime: a durable graph runner designed to pair with AbstractCore.
|
|
5
5
|
Project-URL: AbstractCore (website), https://www.abstractcore.ai/
|
|
6
6
|
Project-URL: AbstractRuntime (GitHub), https://github.com/lpalbou/abstractruntime
|
|
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
22
|
Requires-Python: >=3.10
|
|
23
|
-
Requires-Dist: abstractcore>=2.
|
|
23
|
+
Requires-Dist: abstractcore>=2.25.1
|
|
24
24
|
Requires-Dist: abstractmemory>=0.3.0
|
|
25
25
|
Requires-Dist: abstractsemantics>=0.0.5
|
|
26
26
|
Requires-Dist: anyio<5.0.0,>=4.12.1
|
|
@@ -35,14 +35,14 @@ Requires-Dist: reportlab<5.0.0,>=4.0.0
|
|
|
35
35
|
Requires-Dist: restrictedpython>=7.0
|
|
36
36
|
Requires-Dist: unstructured[docx,odt,pptx,rtf,xlsx]<0.19.0,>=0.18.32
|
|
37
37
|
Provides-Extra: apple
|
|
38
|
-
Requires-Dist: abstractcore[apple]>=2.
|
|
38
|
+
Requires-Dist: abstractcore[apple]>=2.25.1; extra == 'apple'
|
|
39
39
|
Requires-Dist: setuptools<82.0.0,>=80.10.2; extra == 'apple'
|
|
40
40
|
Provides-Extra: docs
|
|
41
41
|
Requires-Dist: mkdocs-material>=9.0.0; extra == 'docs'
|
|
42
42
|
Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
|
|
43
43
|
Requires-Dist: pymdown-extensions>=10.0; extra == 'docs'
|
|
44
44
|
Provides-Extra: gpu
|
|
45
|
-
Requires-Dist: abstractcore[gpu]>=2.
|
|
45
|
+
Requires-Dist: abstractcore[gpu]>=2.25.1; extra == 'gpu'
|
|
46
46
|
Requires-Dist: setuptools<82.0.0,>=77.0.3; extra == 'gpu'
|
|
47
47
|
Provides-Extra: test
|
|
48
48
|
Requires-Dist: aiosmtpd<2.0.0,>=1.4.4; extra == 'test'
|
|
@@ -26,7 +26,7 @@ In this repo, the AbstractCore wiring lives under `src/abstractruntime/integrati
|
|
|
26
26
|
- `faq.md` — common questions (recommended)
|
|
27
27
|
- `manual_testing.md` — manual smoke tests and how to run the test suite
|
|
28
28
|
- `artifacts.md` — Runtime artifact identity, descriptors, provenance, catalog search, and access stats
|
|
29
|
-
- `integrations/abstractcore.md` — wiring `LLM_CALL` / `TOOL_CALLS`, the `config_facade` models/engines/host-jobs passthroughs for hosts, cached sessions with per-session prompt-cache listing/clearing, host memory snapshots, model-residency listings, locks and model switching, live token streaming, workspace-scoped tools, durable bloc prompt-cache control, media inputs, generated media outputs, video progress events, and tool approval waits via AbstractCore
|
|
29
|
+
- `integrations/abstractcore.md` — wiring `LLM_CALL` / `TOOL_CALLS`, the `config_facade` models/engines/host-jobs passthroughs for hosts, the `structured_facade` response_format check for hosts, cached sessions with per-session prompt-cache listing/clearing, host memory snapshots, model-residency listings, locks and model switching, live token streaming, workspace-scoped tools, durable bloc prompt-cache control, media inputs, generated media outputs, video progress events, and tool approval waits via AbstractCore
|
|
30
30
|
- `tools-comms.md` — enabling the optional comms toolset (email/WhatsApp/Telegram)
|
|
31
31
|
- `email.md` — email for each user: run-scoped account binding and the host resolver, sending without asking (self and pre-authorised recipients), the durable event inbox and mail feeder, the `email.received@1` trigger, and the send-email action
|
|
32
32
|
- `tool-approval.md` — tool risk tiers, the run-policy rank ceiling, and per-call refiners (the `send_email` recipient rule: self and pre-authorised recipients)
|
|
@@ -221,7 +221,7 @@ Deep dive: [automations.md](automations.md).
|
|
|
221
221
|
|
|
222
222
|
```python
|
|
223
223
|
from abstractruntime.automations import (
|
|
224
|
-
apply_automation_command, # pause / resume / run_now / revise / stop_current / archive
|
|
224
|
+
apply_automation_command, # pause / resume / run_now / revise / stop_current / archive / unarchive
|
|
225
225
|
create_automation, # -> (automation_id, revision)
|
|
226
226
|
drive_automation, # standalone run loop
|
|
227
227
|
get_automation,
|
|
@@ -262,6 +262,7 @@ from abstractruntime.email import (
|
|
|
262
262
|
|
|
263
263
|
- `Runtime.set_email_context_resolver(fn)`: `fn(binding, *, use) -> EmailContext | None` (`use` is `"agent_tool"` or `"action"`; `fn(binding)` also accepted), per runtime, memory only
|
|
264
264
|
- `Runtime.set_email_binding(binding | None)` / `Runtime.email_binding`: the account occurrences are bound to
|
|
265
|
+
- `Runtime.set_occurrence_input_resolver(fn | None)` / `Runtime.occurrence_input_resolver`: `fn(definition, input_data) -> input_data`, called at each automation occurrence's admission (its run start) and frozen with the occurrence's inputs (a replayed dispatch stays identical); a non-dict answer fails the admission. The gateway re-resolves an automation's "Use my default" workspaces here. None (default): the definition's inputs as stored
|
|
265
266
|
- `Runtime.set_event_inbox(inbox)` / `Runtime.event_inbox`: required by `email.received@1`
|
|
266
267
|
- `EmailInboxFeeder(inbox, account_ref=...).poll(ctx, *, now=None, force=False) -> PollReport` and `.status()`
|
|
267
268
|
- toolsets: `get_default_toolsets(..., email_enabled=True)` (also `list_default_tool_specs`, `build_default_tool_map`, `list_tool_catalog`); no env flag; `list_tool_catalog(email_enabled=False, email_off_reason="not_connected" | "admin_disabled" | "not_available" | "agent_tools_off")`
|
|
@@ -269,6 +270,7 @@ from abstractruntime.email import (
|
|
|
269
270
|
- approval: the `send_email_recipient@v2` refiner ([tool-approval.md](tool-approval.md#per-call-refiners))
|
|
270
271
|
- `adopt_legacy_schedule_projection(run)`: read-only summary of a legacy gateway `scheduled:*` root
|
|
271
272
|
- read-only mounts: `_runtime.workspace_read_only_paths` (absolute folders; file write tools and VisualFlow writers refused inside, reads and command/code tools allowed); helpers `read_only_paths(vars)`, `path_is_read_only(vars, path)` and `READ_ONLY_PATHS_KEY` in `abstractruntime.utils.workspace_paths`
|
|
273
|
+
- writable exceptions inside read-only roots: `workspace_writable_paths` (top-level or `_runtime`; absolute folders). A path is read-only when a read-only root contains it and no writable path inside that root contains it, so the more specific rule wins (a host sets `/` read-only plus the run's folder and its read & write folders for a read-only default). Child runs and VisualFlow file nodes get the parent's exceptions exactly; a child never adds one. Helpers: `writable_paths(vars)`, `is_read_only_target(path, read_only_roots, writable_roots)`, `WRITABLE_PATHS_KEY`.
|
|
272
274
|
- read-only workspaces: run vars `workspace_read_only: true` (or `_runtime.workspace_read_only: true`); `abstractruntime.integrations.abstractcore.tool_effects.TOOL_EFFECT_CLASSES` classifies every exposable tool as `read`, `write`, `exec`, `delegate`, `comms` or `memory-write`
|
|
273
275
|
|
|
274
276
|
## Sessions and history
|
|
@@ -395,3 +397,7 @@ This provides handlers for `MEMORY_KG_*` effects (opt-in wiring layer).
|
|
|
395
397
|
### Host ASGI serving
|
|
396
398
|
|
|
397
399
|
`abstractruntime.integrations.abstractcore.server_facade.serve_core_request(scope, receive, send, *, token: str, allow_unauthenticated: bool = False)` delegates host-admitted ASGI requests with request-scoped Core authentication. See [host-managed serving](integrations/abstractcore.md#host-managed-serving) for network and credential responsibilities.
|
|
400
|
+
|
|
401
|
+
### Structured-output checks
|
|
402
|
+
|
|
403
|
+
`abstractruntime.integrations.abstractcore.structured_facade.parse_response_format(raw) -> (kind, schema, name)` checks an OpenAI `response_format` and raises `ResponseFormatError` (AbstractCore's own class, with `.param`) for an unusable one. Both are also exported flat from `abstractruntime.integrations.abstractcore`. Requires AbstractCore 2.25.0 or newer. See [structured-output checks for hosts](integrations/abstractcore.md#structured-output-checks-for-hosts-structured-facade).
|
|
@@ -34,7 +34,7 @@ sources), `abstractruntime.automation_queries` (listing), `abstractruntime.sessi
|
|
|
34
34
|
```mermaid
|
|
35
35
|
flowchart LR
|
|
36
36
|
Trigger["Trigger source<br/>schedule@1 / manual@1"] -->|"due tick or run now"| Controller["Controller run<br/>(automation id)<br/>vars._meta.automation<br/>vars._runtime.automation"]
|
|
37
|
-
Commands["apply_automation_command<br/>pause / resume / run_now /<br/>revise / stop_current / archive"] -->|"decision + wake"| Controller
|
|
37
|
+
Commands["apply_automation_command<br/>pause / resume / run_now /<br/>revise / stop_current / archive / unarchive"] -->|"decision + wake"| Controller
|
|
38
38
|
Controller -->|"START_SUBWORKFLOW<br/>deterministic run_id"| Occurrence["Occurrence run<br/>role: occurrence<br/>(a session turn)"]
|
|
39
39
|
Occurrence --> Descendants["Descendant runs<br/>role: descendant"]
|
|
40
40
|
Occurrence -->|"output: answer, notify"| Controller
|
|
@@ -292,6 +292,7 @@ expected_revision=None, now=None)` is the only way to change an automation. It r
|
|
|
292
292
|
| `automation.revise` | `payload.changes = {title?, target?, trigger?, context?, policy?}` (at least one). `title`, `target`, `trigger` and `context` are replaced whole; `policy` fields are merged, so a field you do not send keeps its value. The next revision applies from the controller's next step. A changed trigger gets a new binding and is re-armed after now, so no past tick fires; an unchanged trigger keeps its binding. | `invalid_state` when archived or finished; the definition's own reason codes for invalid changes |
|
|
293
293
|
| `automation.stop_current` | Cancels the running occurrence tree, or its pending retry. The occurrence completes as `cancelled`, quietly. | `invalid_state` when nothing is running |
|
|
294
294
|
| `automation.archive` | Stops further admissions; the current occurrence finishes and the controller then ends. History is kept and the automation stays listed. Archiving twice is an applied no-op. | — |
|
|
295
|
+
| `automation.unarchive` | Lifts the archive mark and brings the automation back **paused** (send `automation.resume` to re-arm its trigger). A controller that ended because it was archived restarts at `read_definition` and parks on its wake wait; occurrences, ledger and history are untouched. An exhausted or failed automation only loses the archive mark and keeps its status. Unarchiving an automation that is not archived is an applied no-op. | — |
|
|
295
296
|
|
|
296
297
|
Every command can also be rejected with:
|
|
297
298
|
|
|
@@ -305,7 +306,7 @@ Commands are idempotent per `command_id`. A `command_id` is tied to its whole co
|
|
|
305
306
|
`expected_revision`). The `automation.command_result` record, keyed
|
|
306
307
|
`automation:command_result:<automation_id>:<command_id>`, is the decision. Sending the same command again returns the
|
|
307
308
|
recorded result with `duplicate: true` and repeats only the follow-ups that are safe to repeat: the observation
|
|
308
|
-
record (`automation.paused`, `automation.resumed`, `automation.revised`, `automation.archived`), waking the
|
|
309
|
+
record (`automation.paused`, `automation.resumed`, `automation.revised`, `automation.archived`, `automation.unarchived`), waking the
|
|
309
310
|
controller, and cancelling the stopped child. A host that fails to carry out a command itself records the failure
|
|
310
311
|
with `record_automation_command_result(...)`, passing the same `payload` and `expected_revision` so a later replay is
|
|
311
312
|
recognized.
|
|
@@ -51,7 +51,9 @@ Docs: `getting-started.md`. Code: `src/abstractruntime/core/runtime.py`, `src/ab
|
|
|
51
51
|
Create an automation. An automation is a durable controller run that starts the target workflow as a child run (an
|
|
52
52
|
occurrence) on each trigger: `schedule@1` (fixed UTC intervals such as `5m` or `24h`) or `manual@1` (run now only).
|
|
53
53
|
`create_automation(...)` creates it, `apply_automation_command(...)` pauses, resumes, runs now, edits, stops the
|
|
54
|
-
current occurrence or
|
|
54
|
+
current occurrence, archives it or unarchives it (it comes back paused with its history), and the host drives it
|
|
55
|
+
like any run (`drive_automation` does this in-process). Nothing is deleted: an archived automation keeps its
|
|
56
|
+
occurrences and history and stays listed with status `archived`.
|
|
55
57
|
|
|
56
58
|
The `Scheduler` is different: it is a driver loop that resumes due waits of existing runs. It does not create runs.
|
|
57
59
|
|
|
@@ -97,9 +99,9 @@ Docs: `automations.md#tool-approval`, `automations.md#waits-on-a-person`.
|
|
|
97
99
|
|
|
98
100
|
Not through its file tools. A discussion works in its own writable workspace and sees the automation's workspace as
|
|
99
101
|
a read-only mount (`_runtime.workspace_read_only_paths`): file tools and VisualFlow writers that target a path inside
|
|
100
|
-
the mount are refused, reads work. Commands and code (`execute_command`, `
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
the mount are refused, reads work. Commands and code (`execute_command`, `shell_exec`, `local_helper_start`,
|
|
103
|
+
AbstractAgent's `execute_python`) run inside an OS sandbox built from the same workspaces (macOS `sandbox-exec`, Linux
|
|
104
|
+
`bwrap`/Landlock), so they cannot write into the mount either; on a host with no sandbox they are refused. Every later turn in the discussion session keeps the same setup, whoever starts it, and
|
|
103
105
|
the discussion never writes back into the automation's session, state or ledger.
|
|
104
106
|
|
|
105
107
|
Docs: `automations.md#discussions`, `automations.md#read-only-mounts`.
|
|
@@ -494,16 +494,19 @@ When a run sets `workspace_root` in its vars, file tools (`read_file`, `write_fi
|
|
|
494
494
|
| --- | --- |
|
|
495
495
|
| `workspace_root` | Base folder for relative paths and the shell's starting folder. Relative roots resolve against `ABSTRACT_WORKSPACE_BASE_DIR` when set. |
|
|
496
496
|
| `workspace_access_mode` | `workspace_only` (default: paths stay under the root), `workspace_or_allowed` (also under `workspace_allowed_paths`), or `all_except_ignored` (anywhere except `workspace_ignored_paths`). |
|
|
497
|
-
| `workspace_allowed_paths` |
|
|
498
|
-
| `workspace_ignored_paths` |
|
|
497
|
+
| `workspace_allowed_paths` | Additional workspaces a `workspace_or_allowed` run may use. |
|
|
498
|
+
| `workspace_ignored_paths` | Refused workspaces. A more specific allowed workspace inside one stays reachable (see *Nesting* below). |
|
|
499
499
|
| `workspace_builtin_deny_prefixes` | The host's own protected folders (for example a gateway's data folder and credential folders), as path prefixes. Anything under one is refused. |
|
|
500
500
|
| `workspace_builtin_allow` | Exceptions inside the host's protected folders (for example the run's own folder inside the data folder). The operator's `workspace_ignored_paths` still win over them. |
|
|
501
|
+
| `workspace_read_only_paths` / `workspace_writable_paths` | Read-only roots and the writable exceptions inside them (`"/"` = a read-only default). The more specific rule wins. |
|
|
501
502
|
|
|
502
503
|
Lists accept a JSON array, a JSON array pasted as a string, or newline-separated entries.
|
|
503
504
|
|
|
504
|
-
- When an `LLM_CALL` offers tools and the run has a workspace scope, the runtime appends a short description of the scope to the system prompt: the root
|
|
505
|
-
- Child runs (subworkflows and agent delegation) inherit
|
|
506
|
-
-
|
|
505
|
+
- When an `LLM_CALL` offers tools and the run has a workspace scope, the runtime appends a short description of the scope to the system prompt: the root (the run's default working directory); each allowed workspace outside the root with its mode (`(read-only)` or `(read & write)`, from `workspace_read_only_paths` and `workspace_writable_paths`); under `all_except_ignored` the mode of everything else (`Everything else: (read-only)`); the access mode; the authorized roots and the operator's `workspace_ignored_paths`. The host's built-in deny prefixes and allow entries are enforced but never described to the model, so the system prompt stays identical from turn to turn while the host's folders change, and the prompt cache stays warm. A refused path is reported as `Path is not accessible (protected by the host)` without listing the host's rules.
|
|
506
|
+
- Child runs (subworkflows and agent delegation) inherit the workspace vars unless they set their own; VisualFlow file and document nodes (`read_file`, `write_file`, `read_pdf`, `write_pdf`, `write_docx`, `write_chart`) apply the same scope.
|
|
507
|
+
- **Nesting (most specific row wins).** For a path P (symlinks resolved), the candidates are `workspace_root` (read & write), `workspace_allowed_paths` (not under `workspace_only`) and `workspace_ignored_paths`. The longest candidate that contains P decides: a refused entry refuses, the root or an allowed entry allows; a tie between a refused entry and an allowed one (or the root) at the same path refuses; no candidate falls back to the access mode (`all_except_ignored` allows, the others refuse). The host's built-in protection is absolute: under a `workspace_builtin_deny_prefixes` entry and not under a `workspace_builtin_allow` entry is refused whatever the rows say. So refusing `/Users/me` and allowing `/Users/me/project` makes the project reachable and the rest of `/Users/me` refused; a refused folder inside an allowed one refuses that subtree. AbstractGateway applies the same rule when it validates and computes a run's workspaces.
|
|
508
|
+
- **Command sandbox.** `execute_command`, `shell_exec` (the whole persistent session), `local_helper_start` and AbstractAgent's `execute_python` (0.3.18 or newer) start in the workspace and run inside an OS sandbox built from the SAME scope (`sandbox_stamp(scope)`, stamped on every call as the hidden `_sandbox` argument; a model- or payload-supplied value is always replaced). AbstractCore (`abstractcore.tools.sandbox`) applies it: macOS `sandbox-exec`, Linux `bwrap`, or Linux Landlock for "Deny everything, allow listed workspaces". Mapping: `all_except_ignored` → "Allow everything, refuse listed workspaces" (`any_except_denied`), otherwise "Deny everything, allow listed workspaces" (`allowed_only`); a `"/"` read-only root → read-only default; each allowed workspace with its mode; refused paths and the built-in protection as they are. The command string is never parsed — `cd ..`, absolute paths, `$(…)`, symlinks and scripts are stopped by the kernel. With no sandbox on the host, or an AbstractCore without `abstractcore.tools.sandbox`, the command is refused with one sentence and the run continues. The entity exec tool runs inside a sandbox limited to the entity's workspace and its whitelisted mounts. The tool result carries `sandbox: {kind, …}` and a `Sandbox: …` line; the stamp rides the tool call in the run's evidence. Hosts set the host policy (the scrubbed environment commands start from, and whether unsandboxed commands are allowed on a host with no sandbox) once at boot through `abstractruntime.integrations.abstractcore.command_sandbox_host` (`configure_host`, `host_policy`, `host_sandbox_kind`), never by importing AbstractCore.
|
|
509
|
+
- **Browser probe.** A local `browser_probe` target (a path or a `file://` URL) is walled like `read_file`'s path and carries the same `_sandbox` stamp: AbstractCore 2.25.1 serves the page to the browser from a loopback origin that answers only for files this scope can read (never `file://`). Remote `http(s)://` targets carry no stamp.
|
|
507
510
|
|
|
508
511
|
## Prompt-cache control plane and durable blocs
|
|
509
512
|
|
|
@@ -1046,8 +1049,14 @@ Public durable entry points:
|
|
|
1046
1049
|
These helpers create child runs under an existing parent run and execute the real
|
|
1047
1050
|
`LLM_CALL`, `TOOL_CALLS`, or stream finalization through Runtime rather than
|
|
1048
1051
|
doing external work in host/controller code. `stream_voice(...)` yields TTS
|
|
1049
|
-
stream events for progressive playback
|
|
1050
|
-
|
|
1052
|
+
stream events for progressive playback; it is never a wait: nothing durable
|
|
1053
|
+
exists while audio streams, and when the stream ends (done, error, cancel or
|
|
1054
|
+
the consumer closing it) the child run is created already completed with the
|
|
1055
|
+
outcome (the final audio artifact on success). The child's id is announced up
|
|
1056
|
+
front in the `runtime_start` event (`child_run_id`). A host that finds a
|
|
1057
|
+
streamed-speech wait left by a runtime before this behaviour
|
|
1058
|
+
(`is_interrupted_voice_stream_wait`) closes it with
|
|
1059
|
+
`close_interrupted_voice_stream(child_run_id, reason=...)`.
|
|
1051
1060
|
|
|
1052
1061
|
Example:
|
|
1053
1062
|
|
|
@@ -1184,3 +1193,18 @@ Provide a nonempty token even for open access: absent Authorization is allowed w
|
|
|
1184
1193
|
Anonymous callers cannot use server-held cloud credentials; explicit provider
|
|
1185
1194
|
keys use `X-AbstractCore-Provider-API-Key`. This serving facade does not create
|
|
1186
1195
|
durable Runtime runs. The AbstractCore server dependencies must be installed.
|
|
1196
|
+
|
|
1197
|
+
## Structured-output checks for hosts (structured facade)
|
|
1198
|
+
|
|
1199
|
+
A host that accepts an OpenAI `response_format` checks it before any model sees it with
|
|
1200
|
+
`abstractruntime.integrations.abstractcore.structured_facade` (also exported flat from
|
|
1201
|
+
`abstractruntime.integrations.abstractcore`):
|
|
1202
|
+
|
|
1203
|
+
- `parse_response_format(raw)` returns `(kind, schema, name)`, where kind is `"text"`,
|
|
1204
|
+
`"json_object"` or `"json_schema"` and schema is `None` unless kind is `"json_schema"`.
|
|
1205
|
+
- `ResponseFormatError` is AbstractCore's own error class, so `except ResponseFormatError`
|
|
1206
|
+
catches exactly what Core raises; `.param` names the offending field
|
|
1207
|
+
(`"response_format"` or a nested name such as `"response_format.type"`).
|
|
1208
|
+
|
|
1209
|
+
AbstractCore is imported on first use; it needs AbstractCore 2.25.0 or newer. AbstractGateway's
|
|
1210
|
+
`/v1/chat/completions` uses this facade, so the gateway never imports AbstractCore itself.
|
|
@@ -1086,7 +1086,7 @@ Deep dive: [automations.md](automations.md).
|
|
|
1086
1086
|
|
|
1087
1087
|
```python
|
|
1088
1088
|
from abstractruntime.automations import (
|
|
1089
|
-
apply_automation_command, # pause / resume / run_now / revise / stop_current / archive
|
|
1089
|
+
apply_automation_command, # pause / resume / run_now / revise / stop_current / archive / unarchive
|
|
1090
1090
|
create_automation, # -> (automation_id, revision)
|
|
1091
1091
|
drive_automation, # standalone run loop
|
|
1092
1092
|
get_automation,
|
|
@@ -1127,6 +1127,7 @@ from abstractruntime.email import (
|
|
|
1127
1127
|
|
|
1128
1128
|
- `Runtime.set_email_context_resolver(fn)`: `fn(binding, *, use) -> EmailContext | None` (`use` is `"agent_tool"` or `"action"`; `fn(binding)` also accepted), per runtime, memory only
|
|
1129
1129
|
- `Runtime.set_email_binding(binding | None)` / `Runtime.email_binding`: the account occurrences are bound to
|
|
1130
|
+
- `Runtime.set_occurrence_input_resolver(fn | None)` / `Runtime.occurrence_input_resolver`: `fn(definition, input_data) -> input_data`, called at each automation occurrence's admission (its run start) and frozen with the occurrence's inputs (a replayed dispatch stays identical); a non-dict answer fails the admission. The gateway re-resolves an automation's "Use my default" workspaces here. None (default): the definition's inputs as stored
|
|
1130
1131
|
- `Runtime.set_event_inbox(inbox)` / `Runtime.event_inbox`: required by `email.received@1`
|
|
1131
1132
|
- `EmailInboxFeeder(inbox, account_ref=...).poll(ctx, *, now=None, force=False) -> PollReport` and `.status()`
|
|
1132
1133
|
- toolsets: `get_default_toolsets(..., email_enabled=True)` (also `list_default_tool_specs`, `build_default_tool_map`, `list_tool_catalog`); no env flag; `list_tool_catalog(email_enabled=False, email_off_reason="not_connected" | "admin_disabled" | "not_available" | "agent_tools_off")`
|
|
@@ -1134,6 +1135,7 @@ from abstractruntime.email import (
|
|
|
1134
1135
|
- approval: the `send_email_recipient@v2` refiner ([tool-approval.md](tool-approval.md#per-call-refiners))
|
|
1135
1136
|
- `adopt_legacy_schedule_projection(run)`: read-only summary of a legacy gateway `scheduled:*` root
|
|
1136
1137
|
- read-only mounts: `_runtime.workspace_read_only_paths` (absolute folders; file write tools and VisualFlow writers refused inside, reads and command/code tools allowed); helpers `read_only_paths(vars)`, `path_is_read_only(vars, path)` and `READ_ONLY_PATHS_KEY` in `abstractruntime.utils.workspace_paths`
|
|
1138
|
+
- writable exceptions inside read-only roots: `workspace_writable_paths` (top-level or `_runtime`; absolute folders). A path is read-only when a read-only root contains it and no writable path inside that root contains it, so the more specific rule wins (a host sets `/` read-only plus the run's folder and its read & write folders for a read-only default). Child runs and VisualFlow file nodes get the parent's exceptions exactly; a child never adds one. Helpers: `writable_paths(vars)`, `is_read_only_target(path, read_only_roots, writable_roots)`, `WRITABLE_PATHS_KEY`.
|
|
1137
1139
|
- read-only workspaces: run vars `workspace_read_only: true` (or `_runtime.workspace_read_only: true`); `abstractruntime.integrations.abstractcore.tool_effects.TOOL_EFFECT_CLASSES` classifies every exposable tool as `read`, `write`, `exec`, `delegate`, `comms` or `memory-write`
|
|
1138
1140
|
|
|
1139
1141
|
## Sessions and history
|
|
@@ -1261,6 +1263,10 @@ This provides handlers for `MEMORY_KG_*` effects (opt-in wiring layer).
|
|
|
1261
1263
|
|
|
1262
1264
|
`abstractruntime.integrations.abstractcore.server_facade.serve_core_request(scope, receive, send, *, token: str, allow_unauthenticated: bool = False)` delegates host-admitted ASGI requests with request-scoped Core authentication. See [host-managed serving](integrations/abstractcore.md#host-managed-serving) for network and credential responsibilities.
|
|
1263
1265
|
|
|
1266
|
+
### Structured-output checks
|
|
1267
|
+
|
|
1268
|
+
`abstractruntime.integrations.abstractcore.structured_facade.parse_response_format(raw) -> (kind, schema, name)` checks an OpenAI `response_format` and raises `ResponseFormatError` (AbstractCore's own class, with `.param`) for an unusable one. Both are also exported flat from `abstractruntime.integrations.abstractcore`. Requires AbstractCore 2.25.0 or newer. See [structured-output checks for hosts](integrations/abstractcore.md#structured-output-checks-for-hosts-structured-facade).
|
|
1269
|
+
|
|
1264
1270
|
|
|
1265
1271
|
==============================================================================
|
|
1266
1272
|
# FILE: docs/faq.md
|
|
@@ -1319,7 +1325,9 @@ Docs: `getting-started.md`. Code: `src/abstractruntime/core/runtime.py`, `src/ab
|
|
|
1319
1325
|
Create an automation. An automation is a durable controller run that starts the target workflow as a child run (an
|
|
1320
1326
|
occurrence) on each trigger: `schedule@1` (fixed UTC intervals such as `5m` or `24h`) or `manual@1` (run now only).
|
|
1321
1327
|
`create_automation(...)` creates it, `apply_automation_command(...)` pauses, resumes, runs now, edits, stops the
|
|
1322
|
-
current occurrence or
|
|
1328
|
+
current occurrence, archives it or unarchives it (it comes back paused with its history), and the host drives it
|
|
1329
|
+
like any run (`drive_automation` does this in-process). Nothing is deleted: an archived automation keeps its
|
|
1330
|
+
occurrences and history and stays listed with status `archived`.
|
|
1323
1331
|
|
|
1324
1332
|
The `Scheduler` is different: it is a driver loop that resumes due waits of existing runs. It does not create runs.
|
|
1325
1333
|
|
|
@@ -1365,9 +1373,9 @@ Docs: `automations.md#tool-approval`, `automations.md#waits-on-a-person`.
|
|
|
1365
1373
|
|
|
1366
1374
|
Not through its file tools. A discussion works in its own writable workspace and sees the automation's workspace as
|
|
1367
1375
|
a read-only mount (`_runtime.workspace_read_only_paths`): file tools and VisualFlow writers that target a path inside
|
|
1368
|
-
the mount are refused, reads work. Commands and code (`execute_command`, `
|
|
1369
|
-
|
|
1370
|
-
|
|
1376
|
+
the mount are refused, reads work. Commands and code (`execute_command`, `shell_exec`, `local_helper_start`,
|
|
1377
|
+
AbstractAgent's `execute_python`) run inside an OS sandbox built from the same workspaces (macOS `sandbox-exec`, Linux
|
|
1378
|
+
`bwrap`/Landlock), so they cannot write into the mount either; on a host with no sandbox they are refused. Every later turn in the discussion session keeps the same setup, whoever starts it, and
|
|
1371
1379
|
the discussion never writes back into the automation's session, state or ledger.
|
|
1372
1380
|
|
|
1373
1381
|
Docs: `automations.md#discussions`, `automations.md#read-only-mounts`.
|
|
@@ -2460,16 +2468,19 @@ When a run sets `workspace_root` in its vars, file tools (`read_file`, `write_fi
|
|
|
2460
2468
|
| --- | --- |
|
|
2461
2469
|
| `workspace_root` | Base folder for relative paths and the shell's starting folder. Relative roots resolve against `ABSTRACT_WORKSPACE_BASE_DIR` when set. |
|
|
2462
2470
|
| `workspace_access_mode` | `workspace_only` (default: paths stay under the root), `workspace_or_allowed` (also under `workspace_allowed_paths`), or `all_except_ignored` (anywhere except `workspace_ignored_paths`). |
|
|
2463
|
-
| `workspace_allowed_paths` |
|
|
2464
|
-
| `workspace_ignored_paths` |
|
|
2471
|
+
| `workspace_allowed_paths` | Additional workspaces a `workspace_or_allowed` run may use. |
|
|
2472
|
+
| `workspace_ignored_paths` | Refused workspaces. A more specific allowed workspace inside one stays reachable (see *Nesting* below). |
|
|
2465
2473
|
| `workspace_builtin_deny_prefixes` | The host's own protected folders (for example a gateway's data folder and credential folders), as path prefixes. Anything under one is refused. |
|
|
2466
2474
|
| `workspace_builtin_allow` | Exceptions inside the host's protected folders (for example the run's own folder inside the data folder). The operator's `workspace_ignored_paths` still win over them. |
|
|
2475
|
+
| `workspace_read_only_paths` / `workspace_writable_paths` | Read-only roots and the writable exceptions inside them (`"/"` = a read-only default). The more specific rule wins. |
|
|
2467
2476
|
|
|
2468
2477
|
Lists accept a JSON array, a JSON array pasted as a string, or newline-separated entries.
|
|
2469
2478
|
|
|
2470
|
-
- When an `LLM_CALL` offers tools and the run has a workspace scope, the runtime appends a short description of the scope to the system prompt: the root
|
|
2471
|
-
- Child runs (subworkflows and agent delegation) inherit
|
|
2472
|
-
-
|
|
2479
|
+
- When an `LLM_CALL` offers tools and the run has a workspace scope, the runtime appends a short description of the scope to the system prompt: the root (the run's default working directory); each allowed workspace outside the root with its mode (`(read-only)` or `(read & write)`, from `workspace_read_only_paths` and `workspace_writable_paths`); under `all_except_ignored` the mode of everything else (`Everything else: (read-only)`); the access mode; the authorized roots and the operator's `workspace_ignored_paths`. The host's built-in deny prefixes and allow entries are enforced but never described to the model, so the system prompt stays identical from turn to turn while the host's folders change, and the prompt cache stays warm. A refused path is reported as `Path is not accessible (protected by the host)` without listing the host's rules.
|
|
2480
|
+
- Child runs (subworkflows and agent delegation) inherit the workspace vars unless they set their own; VisualFlow file and document nodes (`read_file`, `write_file`, `read_pdf`, `write_pdf`, `write_docx`, `write_chart`) apply the same scope.
|
|
2481
|
+
- **Nesting (most specific row wins).** For a path P (symlinks resolved), the candidates are `workspace_root` (read & write), `workspace_allowed_paths` (not under `workspace_only`) and `workspace_ignored_paths`. The longest candidate that contains P decides: a refused entry refuses, the root or an allowed entry allows; a tie between a refused entry and an allowed one (or the root) at the same path refuses; no candidate falls back to the access mode (`all_except_ignored` allows, the others refuse). The host's built-in protection is absolute: under a `workspace_builtin_deny_prefixes` entry and not under a `workspace_builtin_allow` entry is refused whatever the rows say. So refusing `/Users/me` and allowing `/Users/me/project` makes the project reachable and the rest of `/Users/me` refused; a refused folder inside an allowed one refuses that subtree. AbstractGateway applies the same rule when it validates and computes a run's workspaces.
|
|
2482
|
+
- **Command sandbox.** `execute_command`, `shell_exec` (the whole persistent session), `local_helper_start` and AbstractAgent's `execute_python` (0.3.18 or newer) start in the workspace and run inside an OS sandbox built from the SAME scope (`sandbox_stamp(scope)`, stamped on every call as the hidden `_sandbox` argument; a model- or payload-supplied value is always replaced). AbstractCore (`abstractcore.tools.sandbox`) applies it: macOS `sandbox-exec`, Linux `bwrap`, or Linux Landlock for "Deny everything, allow listed workspaces". Mapping: `all_except_ignored` → "Allow everything, refuse listed workspaces" (`any_except_denied`), otherwise "Deny everything, allow listed workspaces" (`allowed_only`); a `"/"` read-only root → read-only default; each allowed workspace with its mode; refused paths and the built-in protection as they are. The command string is never parsed — `cd ..`, absolute paths, `$(…)`, symlinks and scripts are stopped by the kernel. With no sandbox on the host, or an AbstractCore without `abstractcore.tools.sandbox`, the command is refused with one sentence and the run continues. The entity exec tool runs inside a sandbox limited to the entity's workspace and its whitelisted mounts. The tool result carries `sandbox: {kind, …}` and a `Sandbox: …` line; the stamp rides the tool call in the run's evidence. Hosts set the host policy (the scrubbed environment commands start from, and whether unsandboxed commands are allowed on a host with no sandbox) once at boot through `abstractruntime.integrations.abstractcore.command_sandbox_host` (`configure_host`, `host_policy`, `host_sandbox_kind`), never by importing AbstractCore.
|
|
2483
|
+
- **Browser probe.** A local `browser_probe` target (a path or a `file://` URL) is walled like `read_file`'s path and carries the same `_sandbox` stamp: AbstractCore 2.25.1 serves the page to the browser from a loopback origin that answers only for files this scope can read (never `file://`). Remote `http(s)://` targets carry no stamp.
|
|
2473
2484
|
|
|
2474
2485
|
## Prompt-cache control plane and durable blocs
|
|
2475
2486
|
|
|
@@ -3012,8 +3023,14 @@ Public durable entry points:
|
|
|
3012
3023
|
These helpers create child runs under an existing parent run and execute the real
|
|
3013
3024
|
`LLM_CALL`, `TOOL_CALLS`, or stream finalization through Runtime rather than
|
|
3014
3025
|
doing external work in host/controller code. `stream_voice(...)` yields TTS
|
|
3015
|
-
stream events for progressive playback
|
|
3016
|
-
|
|
3026
|
+
stream events for progressive playback; it is never a wait: nothing durable
|
|
3027
|
+
exists while audio streams, and when the stream ends (done, error, cancel or
|
|
3028
|
+
the consumer closing it) the child run is created already completed with the
|
|
3029
|
+
outcome (the final audio artifact on success). The child's id is announced up
|
|
3030
|
+
front in the `runtime_start` event (`child_run_id`). A host that finds a
|
|
3031
|
+
streamed-speech wait left by a runtime before this behaviour
|
|
3032
|
+
(`is_interrupted_voice_stream_wait`) closes it with
|
|
3033
|
+
`close_interrupted_voice_stream(child_run_id, reason=...)`.
|
|
3017
3034
|
|
|
3018
3035
|
Example:
|
|
3019
3036
|
|
|
@@ -3151,6 +3168,21 @@ Anonymous callers cannot use server-held cloud credentials; explicit provider
|
|
|
3151
3168
|
keys use `X-AbstractCore-Provider-API-Key`. This serving facade does not create
|
|
3152
3169
|
durable Runtime runs. The AbstractCore server dependencies must be installed.
|
|
3153
3170
|
|
|
3171
|
+
## Structured-output checks for hosts (structured facade)
|
|
3172
|
+
|
|
3173
|
+
A host that accepts an OpenAI `response_format` checks it before any model sees it with
|
|
3174
|
+
`abstractruntime.integrations.abstractcore.structured_facade` (also exported flat from
|
|
3175
|
+
`abstractruntime.integrations.abstractcore`):
|
|
3176
|
+
|
|
3177
|
+
- `parse_response_format(raw)` returns `(kind, schema, name)`, where kind is `"text"`,
|
|
3178
|
+
`"json_object"` or `"json_schema"` and schema is `None` unless kind is `"json_schema"`.
|
|
3179
|
+
- `ResponseFormatError` is AbstractCore's own error class, so `except ResponseFormatError`
|
|
3180
|
+
catches exactly what Core raises; `.param` names the offending field
|
|
3181
|
+
(`"response_format"` or a nested name such as `"response_format.type"`).
|
|
3182
|
+
|
|
3183
|
+
AbstractCore is imported on first use; it needs AbstractCore 2.25.0 or newer. AbstractGateway's
|
|
3184
|
+
`/v1/chat/completions` uses this facade, so the gateway never imports AbstractCore itself.
|
|
3185
|
+
|
|
3154
3186
|
|
|
3155
3187
|
==============================================================================
|
|
3156
3188
|
# FILE: docs/proposal.md
|
|
@@ -3575,7 +3607,7 @@ sources), `abstractruntime.automation_queries` (listing), `abstractruntime.sessi
|
|
|
3575
3607
|
```mermaid
|
|
3576
3608
|
flowchart LR
|
|
3577
3609
|
Trigger["Trigger source<br/>schedule@1 / manual@1"] -->|"due tick or run now"| Controller["Controller run<br/>(automation id)<br/>vars._meta.automation<br/>vars._runtime.automation"]
|
|
3578
|
-
Commands["apply_automation_command<br/>pause / resume / run_now /<br/>revise / stop_current / archive"] -->|"decision + wake"| Controller
|
|
3610
|
+
Commands["apply_automation_command<br/>pause / resume / run_now /<br/>revise / stop_current / archive / unarchive"] -->|"decision + wake"| Controller
|
|
3579
3611
|
Controller -->|"START_SUBWORKFLOW<br/>deterministic run_id"| Occurrence["Occurrence run<br/>role: occurrence<br/>(a session turn)"]
|
|
3580
3612
|
Occurrence --> Descendants["Descendant runs<br/>role: descendant"]
|
|
3581
3613
|
Occurrence -->|"output: answer, notify"| Controller
|
|
@@ -3833,6 +3865,7 @@ expected_revision=None, now=None)` is the only way to change an automation. It r
|
|
|
3833
3865
|
| `automation.revise` | `payload.changes = {title?, target?, trigger?, context?, policy?}` (at least one). `title`, `target`, `trigger` and `context` are replaced whole; `policy` fields are merged, so a field you do not send keeps its value. The next revision applies from the controller's next step. A changed trigger gets a new binding and is re-armed after now, so no past tick fires; an unchanged trigger keeps its binding. | `invalid_state` when archived or finished; the definition's own reason codes for invalid changes |
|
|
3834
3866
|
| `automation.stop_current` | Cancels the running occurrence tree, or its pending retry. The occurrence completes as `cancelled`, quietly. | `invalid_state` when nothing is running |
|
|
3835
3867
|
| `automation.archive` | Stops further admissions; the current occurrence finishes and the controller then ends. History is kept and the automation stays listed. Archiving twice is an applied no-op. | — |
|
|
3868
|
+
| `automation.unarchive` | Lifts the archive mark and brings the automation back **paused** (send `automation.resume` to re-arm its trigger). A controller that ended because it was archived restarts at `read_definition` and parks on its wake wait; occurrences, ledger and history are untouched. An exhausted or failed automation only loses the archive mark and keeps its status. Unarchiving an automation that is not archived is an applied no-op. | — |
|
|
3836
3869
|
|
|
3837
3870
|
Every command can also be rejected with:
|
|
3838
3871
|
|
|
@@ -3846,7 +3879,7 @@ Commands are idempotent per `command_id`. A `command_id` is tied to its whole co
|
|
|
3846
3879
|
`expected_revision`). The `automation.command_result` record, keyed
|
|
3847
3880
|
`automation:command_result:<automation_id>:<command_id>`, is the decision. Sending the same command again returns the
|
|
3848
3881
|
recorded result with `duplicate: true` and repeats only the follow-ups that are safe to repeat: the observation
|
|
3849
|
-
record (`automation.paused`, `automation.resumed`, `automation.revised`, `automation.archived`), waking the
|
|
3882
|
+
record (`automation.paused`, `automation.resumed`, `automation.revised`, `automation.archived`, `automation.unarchived`), waking the
|
|
3850
3883
|
controller, and cancelling the stopped child. A host that fails to carry out a command itself records the failure
|
|
3851
3884
|
with `record_automation_command_result(...)`, passing the same `payload` and `expected_revision` so a later replay is
|
|
3852
3885
|
recognized.
|
|
@@ -5851,7 +5884,7 @@ In this repo, the AbstractCore wiring lives under `src/abstractruntime/integrati
|
|
|
5851
5884
|
- `faq.md` — common questions (recommended)
|
|
5852
5885
|
- `manual_testing.md` — manual smoke tests and how to run the test suite
|
|
5853
5886
|
- `artifacts.md` — Runtime artifact identity, descriptors, provenance, catalog search, and access stats
|
|
5854
|
-
- `integrations/abstractcore.md` — wiring `LLM_CALL` / `TOOL_CALLS`, the `config_facade` models/engines/host-jobs passthroughs for hosts, cached sessions with per-session prompt-cache listing/clearing, host memory snapshots, model-residency listings, locks and model switching, live token streaming, workspace-scoped tools, durable bloc prompt-cache control, media inputs, generated media outputs, video progress events, and tool approval waits via AbstractCore
|
|
5887
|
+
- `integrations/abstractcore.md` — wiring `LLM_CALL` / `TOOL_CALLS`, the `config_facade` models/engines/host-jobs passthroughs for hosts, the `structured_facade` response_format check for hosts, cached sessions with per-session prompt-cache listing/clearing, host memory snapshots, model-residency listings, locks and model switching, live token streaming, workspace-scoped tools, durable bloc prompt-cache control, media inputs, generated media outputs, video progress events, and tool approval waits via AbstractCore
|
|
5855
5888
|
- `tools-comms.md` — enabling the optional comms toolset (email/WhatsApp/Telegram)
|
|
5856
5889
|
- `email.md` — email for each user: run-scoped account binding and the host resolver, sending without asking (self and pre-authorised recipients), the durable event inbox and mail feeder, the `email.received@1` trigger, and the send-email action
|
|
5857
5890
|
- `tool-approval.md` — tool risk tiers, the run-policy rank ceiling, and per-call refiners (the `send_email` recipient rule: self and pre-authorised recipients)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> Durable workflow runtime (interrupt → checkpoint → resume) with an append-only execution ledger.
|
|
4
4
|
|
|
5
5
|
- Python: 3.10+ (see `pyproject.toml`)
|
|
6
|
-
- Version: 0.
|
|
6
|
+
- Version: 0.9.1
|
|
7
7
|
- Ecosystem: [AbstractFramework](https://github.com/lpalbou/AbstractFramework) umbrella, integrates with [AbstractCore](https://github.com/lpalbou/abstractcore)
|
|
8
8
|
- Hard invariant: `RunState.vars` must be JSON-serializable (`src/abstractruntime/core/models.py`)
|
|
9
9
|
- Current AbstractCore baseline: base `abstractruntime` requires AbstractCore 2.24.0 or newer with its light install (remote providers, tools and the MCP worker, media routing); `abstractruntime[apple]` and `abstractruntime[gpu]` require AbstractCore's `apple` and `gpu` settings (`pyproject.toml`)
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
- [Cancellation, pause and tool ceiling](docs/api.md#runtime-start--tick--resume): `Runtime.cancel_run(...)` stops the in-flight effect (recorded `cancelled`, never retried), a model unload cancels the calls using it first, `tick(..., step_gate=...)` pauses at step boundaries, and an explicit `allowed_tools` list is a run-tree ceiling approval policy cannot widen.
|
|
40
40
|
- [Live token streaming](docs/integrations/abstractcore.md#live-token-streaming): `Runtime.set_live_delta_sink(sink)` plus run input `_runtime.stream: true` delivers `llm.delta` / `llm.delta_end` events (content and reasoning channels, `parent_run_id`) while an answer is generated; nothing reaches the ledger, children inherit the switch, and every call that cannot stream with a complete record says why (`reason: unavailable` + `detail`).
|
|
41
41
|
- [Unloading and switching models](docs/integrations/abstractcore.md#unloading-and-switching-models): a default switch unloads the previous in-process model (MLX, HuggingFace, embeddings) unless another owner in the process claims it (pool, override, lock, building, default); a model still generating is unloaded when its call ends; diagnostics `pending_ejects` / `last_switch_ejects`; any listed row unloads by `runtime_id` (`local:<task>:<provider>:<model>`, including `local:embedding:<provider>:<model>`); `ttl_s` / `keep_alive` on in-process or already-loaded models are reported under `unsupported_options`.
|
|
42
|
-
- [Workspace-scoped tools](docs/integrations/abstractcore.md#workspace-scoped-tools): `workspace_root`, `workspace_access_mode`, `workspace_allowed_paths`, `workspace_ignored_paths`, and the host-only `workspace_builtin_deny_prefixes` / `workspace_builtin_allow` (enforced, never shown to the model) scope file and shell tools; child runs inherit them.
|
|
42
|
+
- [Workspace-scoped tools](docs/integrations/abstractcore.md#workspace-scoped-tools): `workspace_root`, `workspace_access_mode`, `workspace_allowed_paths`, `workspace_ignored_paths`, and the host-only `workspace_builtin_deny_prefixes` / `workspace_builtin_allow` (enforced, never shown to the model) scope file and shell tools; the most specific row wins (longest real-path prefix, a refusal wins a tie, built-ins absolute); `execute_command`/`shell_exec`/`local_helper_start`/`execute_python` get the same set stamped as the hidden `_sandbox` arg and run inside AbstractCore's OS sandbox (refused when the host has none); child runs inherit them.
|
|
43
43
|
- [Execution controls](docs/integrations/abstractcore.md#execution-controls-and-local-concurrency): inherited run/node MTP controls, scoped Core defaults, actual-host execution discovery, instance-aware scheduling, per-response outcomes and cache-group batching limits.
|
|
44
44
|
|
|
45
45
|
- [AbstractCore integration](docs/integrations/abstractcore.md): `LLM_CALL` / `TOOL_CALLS` / `MODEL_RESIDENCY`, local/remote/hybrid, prompt-cache and residency host controls, host memory snapshots and per-session prompt-cache listing/clearing, host-wide provider-server rows in residency listings, model-residency locks (residency-required: locking a non-resident pair refuses with `model_not_resident`; unlock never requires residency) with `force`-gated unload and context-estimate relays, modality/host-identity fields and truthful `pinned`-aliases-`locked` lock state on local residency rows, local-only prompt-cache export/import admin, durable bloc/KV prompt-cache controls, discovery snapshot queries including `list_provider_models(..., capability_route=...)` and `list_vision_adapters(...)`, durable run-scoped image/edit-image/upscale-image/text-to-video/image-to-video/voice/streamed-voice/music/STT execution, batch `count`/`n`, `seeds`, ordered `lora_adapters`, video `flow_shift`, media inputs, generated media outputs, progress ledger events, provider-key headers, host endpoint-profile resolver hooks, and tool approval waits
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
- [MCP worker](docs/mcp-worker.md): `abstractruntime-mcp-worker` CLI (stdio/HTTP)
|
|
58
58
|
- [Comms toolset](docs/tools-comms.md): email enabled by the host (`email_enabled=True`, no env flag); WhatsApp/Telegram env gating
|
|
59
59
|
- [Email](docs/email.md): one user, one runtime, one mailbox: `_runtime.email_account` binding resolved at call time through `Runtime.set_email_context_resolver` (credentials never in vars, ledger or results), `send_email_recipient@v2` (unattended only to self or to the definition's `policy.email_allowed_recipients`), the resolver's `use` (`agent_tool` / `action`) so a host's agent-tools switch gates agent tools only, large structured tool outputs offloaded to attachments, durable event inbox (`JsonFileEventInbox`, retention 90 days / 10,000 events via `prune_email_inbox`) filled by `EmailInboxFeeder.poll` (read-only, per-message cursor, UIDVALIDITY resync, typed failures with backoff), the `email.received@1` trigger (typed filters, batches every `every`, each message once, untrusted input: messages and framed prompt stored as artifacts (refs only in the controller's records), frame markers with a per-occurrence random boundary, and "allow all tools" granting by kind only (no network egress beyond configured services, no execution, no messaging, no writes outside the workspace (the memory-writing tools included), no delegation; anything else only when named in `policy.untrusted_input_tools`, sending tools never; under "ask" nothing runs unasked but the named tools, and the executor's static defaults never decide for an untrusted run or its children)) and the send-email action (fixed-placeholder templates)
|
|
60
|
-
- [Automations](docs/automations.md): configurable growing-context budgets and result email; an automation is a durable controller run that starts its target as deterministic child runs (occurrences) on `schedule@1` (fixed UTC intervals, coalesced missed ticks) or `manual@1`; `create_automation`, `apply_automation_command` (pause, resume, run_now, revise, stop_current, archive; idempotent per `command_id`), independent or growing context, `start_discussion` (fork at any occurrence N, seeded with the timeline 1..N, own writable workspace, the automation's workspace mounted read-only via `_runtime.workspace_read_only_paths`: file writes refused inside, reads and commands allowed), `policy.tool_approval` (`auto` or `ask`), `policy.email_allowed_recipients`, `notify.channels`, the `email.received@1` trigger, typed `pending_waits`, `notify` attention items and retries; storage guarantees: `create_if_absent`, `run_mutation_lock`, turn roots and `session_kind` in the run index, one writer process per store, `Runtime.start` refusing session starts it cannot attribute
|
|
60
|
+
- [Automations](docs/automations.md): configurable growing-context budgets and result email; an automation is a durable controller run that starts its target as deterministic child runs (occurrences) on `schedule@1` (fixed UTC intervals, coalesced missed ticks) or `manual@1`; `create_automation`, `apply_automation_command` (pause, resume, run_now, revise, stop_current, archive, unarchive — back paused with its history, nothing deleted; idempotent per `command_id`), independent or growing context, `start_discussion` (fork at any occurrence N, seeded with the timeline 1..N, own writable workspace, the automation's workspace mounted read-only via `_runtime.workspace_read_only_paths`: file writes refused inside, reads and commands allowed), `policy.tool_approval` (`auto` or `ask`), `policy.email_allowed_recipients`, `notify.channels`, the `email.received@1` trigger, typed `pending_waits`, `notify` attention items and retries; storage guarantees: `create_if_absent`, `run_mutation_lock`, turn roots and `session_kind` in the run index, one writer process per store, `Runtime.start` refusing session starts it cannot attribute
|
|
61
61
|
- [Tool approval](docs/tool-approval.md): tool risk tiers, the run-policy rank ceiling, and per-call refiners
|
|
62
62
|
- [Entity runtime](docs/entity-runtime.md): per-entity runtimes, homes, the one-writer lease, act-only diary privacy, and durable visit waits
|
|
63
63
|
- [Models, engines and host jobs](docs/integrations/abstractcore.md#models-engines-and-host-jobs-config-facade): `config_facade` passthroughs for hosts; `host_job_cancel(job_id, *, by="api", user=None)` records who cancelled a job
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "AbstractRuntime"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.9.1"
|
|
8
8
|
description = "AbstractRuntime: a durable graph runner designed to pair with AbstractCore."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -53,7 +53,9 @@ dependencies = [
|
|
|
53
53
|
# plugins) without selecting local inference engines. 2.19.2 floors
|
|
54
54
|
# abstractvision>=0.3.33, whose resident loads report `loaded_new` and whose
|
|
55
55
|
# unload frees the pipeline (the resident media path relies on both).
|
|
56
|
-
|
|
56
|
+
# 2.25.1: the Linux bwrap profile binds an allowed child of a refused folder,
|
|
57
|
+
# and browser_probe takes the _sandbox stamp (scoped loopback origin).
|
|
58
|
+
"abstractcore>=2.25.1",
|
|
57
59
|
"openai<3.0.0,>=1.109.1",
|
|
58
60
|
"httpx<1.0.0,>=0.28.1",
|
|
59
61
|
"anyio<5.0.0,>=4.12.1",
|
|
@@ -70,12 +72,12 @@ dependencies = [
|
|
|
70
72
|
|
|
71
73
|
[project.optional-dependencies]
|
|
72
74
|
apple = [
|
|
73
|
-
"abstractcore[apple]>=2.
|
|
75
|
+
"abstractcore[apple]>=2.25.1",
|
|
74
76
|
"setuptools<82.0.0,>=80.10.2",
|
|
75
77
|
]
|
|
76
78
|
|
|
77
79
|
gpu = [
|
|
78
|
-
"abstractcore[gpu]>=2.
|
|
80
|
+
"abstractcore[gpu]>=2.25.1",
|
|
79
81
|
# vLLM 0.9-0.19 caps setuptools below 80; 77.0.3 is still a modern floor.
|
|
80
82
|
"setuptools<82.0.0,>=77.0.3",
|
|
81
83
|
]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
### Security
|
|
2
|
+
|
|
3
|
+
- `browser_probe`: a local target (path or `file://` URL) now carries the run's `_sandbox` stamp, the same scope the commands get. AbstractCore 2.25.1 serves the page from a loopback origin limited to that scope instead of `file://`, so a page cannot load refused files as subresources. Needs AbstractCore 2.25.1 (an older `browser_probe` refuses the unknown argument and runs nothing). Test: `tests/test_browser_probe_target_walling.py`.
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- `stream_voice(...)` is never a wait. It used to start the child run parked on `WAIT_EVENT abstractcore.voice.tts.stream:<uuid>` for the whole stream: hosts folded that waiting record into the CALLER'S run (a Read aloud during a live turn read as "Waiting for an event"), and a host that died mid-stream left the child waiting forever. Now nothing durable exists while audio streams; when the stream ends (done, error, cancel or the consumer closing it) the child run is created already COMPLETED with the outcome. Its id is allocated up front: `runtime_start` carries it as `child_run_id` (schema `abstractruntime.tts_stream.start.v2`, no `wait_key`), as does the trace metadata. A stream cut by a crash leaves no run.
|
|
8
|
+
- `AbstractCoreRunFacade.close_interrupted_voice_stream(child_run_id, *, reason)` finishes a legacy streamed-speech wait left by an older process (completed, `errors[0] = {"code": "interrupted", "message": reason}`); `is_interrupted_voice_stream_wait(waiting)` and `LEGACY_VOICE_STREAM_WAIT_KEY_PREFIX` recognise one (exported from `integrations.abstractcore`). AbstractGateway calls it at startup.
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Requires AbstractCore 2.25.1 or newer (`abstractcore>=2.25.1` in the base install and the `[apple]`/`[gpu]` extras): the Linux command sandbox reaches an allowed folder inside a refused one, and `browser_probe` accepts the run's `_sandbox` stamp.
|