AbstractRuntime 0.9.0__tar.gz → 0.10.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/CHANGELOG.md +38 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/PKG-INFO +5 -5
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/README.md +1 -1
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/README.md +1 -1
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/api.md +1 -1
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/architecture.md +2 -1
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/automations.md +33 -4
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/faq.md +1 -1
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/integrations/abstractcore.md +9 -2
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/llms-full.txt +48 -11
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/llms.txt +2 -2
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/pyproject.toml +8 -4
- abstractruntime-0.10.0/release-notes.md +20 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/__init__.py +4 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/config_facade.py +25 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/run_facade.py +117 -114
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/workspace_scoped_tools.py +7 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/triggers/__init__.py +4 -1
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/triggers/registry.py +18 -2
- abstractruntime-0.10.0/src/abstractruntime/triggers/schedule.py +553 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/variable_adapter.py +79 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/compiler.py +18 -2
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/builtins.py +15 -1
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/executor.py +124 -4
- abstractruntime-0.10.0/src/abstractruntime/visualflow_compiler/visual/loop_back_check.py +104 -0
- abstractruntime-0.10.0/src/abstractruntime/visualflow_compiler/visual/loop_limit_lowering.py +154 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/models.py +5 -0
- abstractruntime-0.10.0/src/abstractruntime/visualflow_compiler/visual/reroute_lowering.py +127 -0
- abstractruntime-0.10.0/tests/fixtures/schedule_v1_corpus.json +6662 -0
- abstractruntime-0.10.0/tests/test_automation_calendar_schedule.py +76 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_browser_probe_target_walling.py +15 -0
- abstractruntime-0.10.0/tests/test_config_facade_voice_input_hint.py +54 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_packaging_extras.py +3 -3
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_r12_workspace_sandbox.py +36 -2
- abstractruntime-0.10.0/tests/test_schedule_v1_corpus.py +46 -0
- abstractruntime-0.10.0/tests/test_schedule_v2_calendar.py +286 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_trigger_registry.py +10 -6
- abstractruntime-0.10.0/tests/test_visual_loop_back_out_of_body.py +117 -0
- abstractruntime-0.10.0/tests/test_visual_loop_limit_and_list_nodes.py +254 -0
- abstractruntime-0.10.0/tests/test_visual_loop_limit_on_wire.py +177 -0
- abstractruntime-0.10.0/tests/test_visual_reroute_lowering.py +125 -0
- abstractruntime-0.10.0/tests/test_visual_set_vars_pins.py +70 -0
- abstractruntime-0.10.0/tests/test_voice_stream_is_not_a_wait.py +256 -0
- abstractruntime-0.9.0/release-notes.md +0 -23
- abstractruntime-0.9.0/src/abstractruntime/triggers/schedule.py +0 -249
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/.github/workflows/ci.yml +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/.github/workflows/release.yml +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/.gitignore +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/ACKNOWLEDGMENTS.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/CODE_OF_CONDUCT.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/CONTRIBUTING.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/LICENSE +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/ROADMAP.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/SECURITY.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/adr/0001_layered_coupling_with_abstractcore.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/adr/0002_execution_modes_local_remote_hybrid.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/adr/0003_provenance_tamper_evident_hash_chain.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/adr/0004_runtime_owns_run_scoped_media_execution_truth.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/adr/0005_runtime_owns_abstractcore_host_discovery_queries.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/adr/0006_runtime_owns_durable_abstractcore_bloc_prompt_cache.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/adr/0007_runtime_relays_core_owned_model_residency_truth.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/adr/README.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/artifacts.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/README.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/001_runtime_kernel.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/002_persistence_and_ledger.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0030_runtime_host_facades_for_comms_telegram_and_tool_specs.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0032_runtime_durable_outbound_comms_truth.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0033_runtime_host_local_prompt_cache_export_import_surface.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0035_model_residency_provider_truth_for_local_http_clients.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0037_visualflow_generate_music_node_compiler_parity.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0039_runtime_music_structure_prompt_bool_contract.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/003_wait_primitives.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0040_task_agnostic_local_residency_listing.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0041_runtime_hardware_extras_avoid_nonpermissive_document_stacks.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0042_core_vision_upscale_and_parameter_surface.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0043_runtime_vision_adapter_and_batch_surface.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/004_scheduler_driver.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/005_abstractcore_integration.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/006_snapshots_bookmarks.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/007_provenance_hash_chain.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/009_artifact_store.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/010_examples_and_composition.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/011_subworkflow_support.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/012_run_store_query_and_scheduler_support.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/013_effect_retries_and_idempotency.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/016_runtime_aware_parameters.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/019_runtime_host_facade_for_core_operator_surfaces.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/020_runtime_gateway_install_boundary.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/021_runtime_gateway_env_namespace_cleanup.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/022_model_residency_control_plane.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/023_truthful_local_media_residency_boundaries.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/024_runtime_owned_run_scoped_media_execution.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/026_runtime_host_discovery_facade_for_core_catalogs.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/027_runtime_durable_bloc_prompt_cache_facade.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/028_runtime_bloc_kv_lifecycle_and_pruning.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/029_runtime_music_generation_and_discovery_via_abstractcore.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0846_mlx_instance_scheduling_and_execution_controls.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/completed/0847_automations_v1_controller_contracts_occurrences_triggers.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/001_integrations_abstractcore.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/001_runtime_kernel.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/002_persistence_and_ledger.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/002_snapshots_bookmarks.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/0034_agent_runtime_convenience_constructor.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/003_provenance_ledger_chain.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/003_wait_resume_and_scheduler.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/004_effect_handlers_and_integrations.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/004_tests.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/005_docs_updates.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/005_examples_and_composition.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/006_ai_fingerprint_and_provenance.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/DEPRECATED_README.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/README.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/deprecated/abstractruntime_docs_final_02a7373b.plan.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/0070_standalone_wui_browser_session_security_contract.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/008_signatures_and_keys.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/014_remote_tool_worker_executor.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/017_limit_warnings_and_observability.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/018_workspace_access_policy_for_media_and_tools.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/0233_real_run_cancellation.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/025_runtime_retention_and_purge_contract.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/026_context_checkpoint_self_compression.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/027_quote_provenance_discipline.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/028_selective_artifact_rehydration.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/0845_session_prompt_cache_resume_and_purge_contract.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/0848_automations_v2_external_event_inbox_and_run_triggers.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_portability/0065_portable_process_and_lock_layer.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_portability/0066_portable_io_and_media_reader.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_portability/README.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0044_meta_analysis_record.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0045_crash_replay_harness_and_ordering_invariant.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0046_per_run_driver_exclusion.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0047_indexed_idempotency_lookup.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0048_durable_io_unification.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0049_llm_client_mechanical_split.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0050_control_sidecar_all_writers.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0051_runtime_owned_durable_event_mailbox.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0052_sync_store_event_loop_tripwire.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0053_bounded_run_vars_growth.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0054_runtime_health_counters.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0055_jsonl_store_honesty.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0064_prompt_cache_fingerprint_stability.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0067_durable_write_discipline.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/0068_hot_path_store_reads.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/planned/runtime_systemic_reliability/README.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/0031_runtime_tool_spec_adapters_for_gateway_and_mcp.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/0036_local_media_residency_bridge_to_core_residency.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/0038_core_server_pool_residency_affinity.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/0069_document_renderer_professional_figures.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/runtime_systemic_reliability/0056_schema_version_and_quarantine_loading.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/runtime_systemic_reliability/0057_trust_boundary_stamp_registry.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/runtime_systemic_reliability/0058_terminal_run_archival_helper.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/runtime_systemic_reliability/0059_memory_span_handler_extraction.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/runtime_systemic_reliability/0060_visualflow_compiler_decomposition.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/runtime_systemic_reliability/0061_root_api_deprecation_machinery.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/runtime_systemic_reliability/0062_dependency_honesty_extras.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/runtime_systemic_reliability/0063_b3_envelope_lane_unification.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/backlog/proposed/runtime_systemic_reliability/README.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/email.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/entity-runtime.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/evidence.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/getting-started.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/limits.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/manual_testing.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/mcp-worker.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/proposal.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/provenance.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/snapshots.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/tool-approval.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/tools-comms.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/troubleshooting.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/docs/workflow-bundles.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/examples/01_hello_world.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/examples/02_ask_user.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/examples/03_wait_until.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/examples/04_multi_step.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/examples/05_persistence.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/examples/06_llm_integration.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/examples/07_react_agent.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/examples/README.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/mkdocs.yml +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/pytest.ini +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/scripts/backfill_diary_edges.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/scripts/generate_llms_full.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automation_queries.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/adapters.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/attention.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/bundle.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/bundles/automation-controller/flows/controller.json +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/bundles/automation-controller/manifest.json +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/commands.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/controller.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/ledger.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/models.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/automations/service.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/config.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/effect_cancellation.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/event_keys.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/health.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/live_deltas.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/models.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/policy.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/progress_channel.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/run_attribution.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/run_identity.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/run_lifecycle.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/runtime.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/spec.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/tool_scope.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/core/vars.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/documents/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/documents/charts.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/documents/docx.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/documents/pdf.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/email/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/email/actions.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/email/automations.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/email/binding.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/email/feeder.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/email/frame.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/email/inbox.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/evidence/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/evidence/recorder.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/history_bundle.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/act_only.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/chat.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/communities.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/diary.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/digest.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/entity_runtime.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/fingerprint.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/lease.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/life.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/memory_reader.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/night_voice.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/phase_graph.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/phase_spec.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/prelude.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/prompt_overlay.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/reflection.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/spec/entity_phases.vendored.json +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/substrate.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/tool_effects.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/tool_policy.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/tools.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/identity/visit_workflow.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/agora_tools.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/command_sandbox_host.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/comms_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/constants.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/data_registry_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/default_tools.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/discovery_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/discovery_queries.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/effect_handlers.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/email_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/embeddings_client.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/factory.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/host_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/llm_client.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/local_helper_tools.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/logging.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/mcp_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/mcp_worker.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/media_subprocess.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/observability.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/output_specs.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/server_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/session_attachments.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/structured_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/summarizer.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/telegram_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/tool_effects.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/tool_executor.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractcore/tool_inventory_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractmemory/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractmemory/brain_handlers.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractmemory/effect_handlers.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractmemory/identity_support.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/integrations/abstractmemory/seam_handlers.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/memory/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/memory/active_context.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/memory/active_memory.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/memory/compaction.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/memory/kg_packets.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/memory/memact_composer.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/memory/recall_levels.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/memory/token_budget.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/rendering/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/rendering/agent_trace_report.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/rendering/json_stringify.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/scheduler/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/scheduler/convenience.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/scheduler/multi_store.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/scheduler/registry.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/scheduler/scheduler.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/session_history.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/session_turns.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/artifacts.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/base.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/commands.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/in_memory.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/json_files.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/lease.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/ledger_chain.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/ledger_slim.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/observable.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/offloading.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/serialize.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/snapshots.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/sqlite.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/storage/steer_sidecar.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/triggers/email_received.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/triggers/manual.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/triggers/protocol.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/turn_grounding.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/utils/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/utils/atomic_files.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/utils/file_filters.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/utils/workspace_paths.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/agent_adapter.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/context_adapter.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/control_adapter.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/effect_adapter.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/event_adapter.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/function_adapter.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/memact_adapter.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/adapters/subflow_adapter.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/flow.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/agent_ids.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/code_executor.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/execution_metrics.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/function_library.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/multi_entry_lowering.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/visualflow_compiler/visual/pin_expressions.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/workflow_bundle/__init__.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/workflow_bundle/models.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/workflow_bundle/packer.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/workflow_bundle/reader.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/src/abstractruntime/workflow_bundle/registry.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/README.md +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/automation_harness.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/conftest.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/email_wp2_support.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/live_email/conftest.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/live_email/live_email_support.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/live_email/test_email_live_runtime.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_abstractcore_comms_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_abstractcore_discovery_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_abstractcore_host_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_abstractcore_run_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_abstractcore_server_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_abstractcore_structured_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_abstractcore_telegram_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_active_context_policy.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_active_memory.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_agora_agent_alias_identity.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_agora_tools_http.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_analyze_media_addressing_and_walling.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_answer_user_effect.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_artifacts.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_commands.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_controller.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_controller_recovery.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_definition.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_discussion_isolation.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_email_results.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_growing_context.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_index.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_next_fire.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_occurrence_input_resolver.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_occurrence_recovery.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_replay_read_only.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_retry.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_session_turns.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_status.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_automation_tool_approval.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_budget_law_no_unrequested_caps.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_capability_default_reasoning.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_chat_summarizer_integration.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_code_node_restricted_python.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_command_sandbox_host_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_command_store.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_compaction_helpers.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_compaction_summarizer_route.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_config_facade_models_engines.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_control_adapter_while.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_controller_bundle_packaged.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_crash_ordering_inversions.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_create_if_absent.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_data_registry_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_default_tools_camera_gating.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_default_tools_comms_gating.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_default_tools_include_skim_files.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_default_tools_include_skim_folders.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_default_tools_include_skim_web.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_default_tools_search_files_executor.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_diary_capture.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_diary_write_rescue.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_directory_lease.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_disabled_toolsets_seam.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_discovery_survives_unbuildable_default.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_discovery_tts_unavailable_reason.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_discovery_voice_openai_api_key.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_discussion_session_anchor.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_document_markdown_tables.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_document_renderers_hr_quote.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_durable_toolsets.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_durable_write_discipline.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_e2e_tool_calls_idempotency_lmstudio.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_effect_cancellation.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_effect_issuance_idempotency.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_effect_payload_stays_json_serializable.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_election_consequence_teaching.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_email_binding_and_refiner.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_email_gate_fixes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_email_inbox_and_trigger.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_email_regate_fixes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_email_review_fixes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_email_self_trigger_loop.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_email_toolset_and_walls.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_emergence_experiment.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_emit_event_uses_wait_index.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_emit_event_without_workflow_registry.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_endpoint_profile_route_context.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_awake_memory_fixes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_brain_effects.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_chat_driver.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_chat_tools_reflection.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_diary.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_execute_tool.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_fetch_url_tool.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_history_window.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_life_loop.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_memory_richness.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_phase_graph_conformance.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_react_visit_window.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_recent_memories.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_runtime.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_search_memory.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_sleep_bound_and_yield_attribution.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_substrate_resolution.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_visit_honesty.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_workspace_cap.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_entity_workspace_tools.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_event_wait_index.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_every_path_bearing_tool_is_walled.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_evidence_recorder.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_evidence_recorder_post_policy_envelope.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_execute_command_output_offload.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_execution_capability_discovery.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_explicit_eject_other_clients.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_factory_default_retry_policy.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_factory_timeouts_default_to_abstractcore_config.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_format_repair_nudge.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_fresh_install_no_provider.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_gateway_facades_c4899.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_git_read_only_refiner.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_hf_process_residency_merge.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_history_window_multimodal.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_hot_path_store_reads.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_indexed_idempotency_lookup.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_integration_abstractcore.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_integrations_abstractcore.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_json_file_run_store_children_index.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_json_run_cache_bound.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_json_store_scan_memo.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_jsonl_ledger_recovery.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_kg_learn_and_recall_contract.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_ledger_chain.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_ledger_record_slimming.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_ledger_subscription.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_live_token_deltas.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_media_artifact_refs.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_media_artifact_refs_persist_across_restart.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_media_uses_source_path_label.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_payload_shape_refusal.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_requires_prompt.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_response_schema_normalization.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_structured_output_fallback.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_text_phase_progress.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_truncation_retry_contract.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_use_context_appends_turn.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_call_verbatim_payload_capture.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_client_grounding_tail.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_client_media_artifacts.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_client_system_context.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_client_tool_call_parsing.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_retry_classification.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_llm_streaming_on_token.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_local_helper_tool_exposure.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_local_residency_host_sweep.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_local_runtime_timeout_kwarg_policy.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_max_iterations_ceiling.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_mcp_remote_tool_executor.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_mcp_runs_untrusted_and_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_mcp_worker_logging.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_mcp_worker_security.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_mcp_worker_stdio.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_media_artifact_resolution.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_media_capability_default_routing.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_media_only_requests_skip_text_client.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_media_subprocess.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memact_composer_from_kg_result.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_appraise_handler.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_communities.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_kg_assert_attributes_defaults.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_kg_packets.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_kg_predicate_aliasing.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_kg_query_packetization_restart.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_kg_query_recall_level_policy.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_kg_semantic_query_ranking.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_note_effect.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_query_effect.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_query_rich_filters.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_scope_and_rehydrate_effect.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_seam_handlers.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_seam_sqlite_durability.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_memory_tag_effect.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_mlx_generation_serialization.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_mlx_process_residency_merge.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_model_eject_cancel.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_model_residency_clean_switch.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_model_residency_control_plane.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_model_residency_lock_and_context_estimate.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_multi_store_scheduler.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_multimodal_abstractcore_integration.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_native_mlx_application_wiring.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_native_mlx_execution_controls_live.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_native_tool_channel.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_night_voice.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_no_default_provider_refusal_ux.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_offload_answer_chain_c4978.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_offloaded_node_traces_report_unknown_not_zero.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_offloading.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_parallel_readonly_tool_execution.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_pause_resume.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_pdf_unicode_rendering.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_personal_cycle.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_phantom_attachment_index.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_phase_graph_artifact_control.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_phase_graph_obedience.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_phase_vocabulary_migration.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_pooled_client_strips_construction_cache_key.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_prompt_cache_export_import.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_prompt_cache_fingerprint_stability.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_prompt_cache_modules.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_prompt_cache_posture_inheritance.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_prompt_cache_thinking_and_prompt_only.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_prompt_overlay.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_provider_endpoint_profile_resolution.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_provider_pin_routing_isolation.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_queryable_run_store.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_read_file_fallback_to_session_attachments.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_read_idle_threading.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_readoption_experiment.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_real_integration.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_realize_election.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_recall_levels_policy.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_remote_client_cancel.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_remote_llm_client.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_remote_speculation_defaults.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_rendering_agent_trace_report.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_rendering_json_stringify.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_report_branding.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_resident_media_generation.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_resume_concurrent_same_wait.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_retry_idempotency.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_run_history_bundle.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_run_index_workspace_root.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_run_mutation_lock.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_run_scoped_tool_policy.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_run_tool_scope_ceiling.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_browser_session_boundary.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_config_max_output_tokens_fallback.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_default_provider_model_refresh.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_effect_invocation_trace.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_health_and_bounded_vars.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_install_boundary.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_llm_call_grounding_in_ledger.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_node_traces.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_start_seeds_tool_support.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_runtime_tick_step_gate.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_scheduler.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_send_email_refiner.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_send_email_self_default_policy.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_session_attachments_registry_and_open_tool.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_session_history.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_session_prompt_cache_attribution.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_session_prompt_cache_visibility.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_session_route_stamp.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_session_start_cost.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_shell_tool_exposure.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_snapshots.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_speculation_inheritance.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_speculation_reaches_provider_construction.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_sqlite_ledger_store.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_start_subworkflow_async_wait.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_start_subworkflow_inherit_context_merges_messages.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_start_subworkflow_workspace_inheritance.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_steer_sidecar.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_storage_deletion.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_structured_output_schema_enum.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_subworkflow.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_terminal_effect_completion.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_terminal_resume_appends_ledger_completion.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_thinking_inheritance.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tick_completion_includes_output_in_ledger.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_approval_executor.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_approval_resume_executes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_approval_wait_key_identity.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_calls_idempotency_keys.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_catalog.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_descriptor_registry.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_executor_argument_sanitization.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_executor_error_output_detection.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_executor_filename_alias.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_executor_kwarg_canonicalization.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_executor_read_file_aliases.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_executor_timeout.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_inventory_facade.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_invoke_effect.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_policy_and_mounts.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_tool_wait_allowlist_safety.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_topic_election_world_model.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_trace_context_propagation.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_trigger_schedule_math.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_turn_grounding_byte_stability.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_turn_grounding_carriers_a3.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_vars_query_effect.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visit_ab_fixture.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visit_midturn_elections.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visit_midturn_resume.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visit_workflow.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_agent_output_context_includes_messages.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_agent_skills_block_passthrough.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_agent_tool_observations_persist_across_restart.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_agent_use_context_inherits_attachments.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_agent_use_context_persists_tool_observations.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_agent_use_context_persists_turn.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_entity_memory_nodes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_flow_end_effect_only_persistence.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_llm_call_partial_override.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_llm_call_schema_ref_resolution.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_memact_compose_node.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_memory_kg_query_outputs_propagate.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_memory_kg_resolve_outputs_propagate.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_multi_entry_loop_overrides.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_unknown_node_type_refuses.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visual_wait_event_deadline_passthrough.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_add_message_builtin.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_add_message_node_appends_to_active_context.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_agora_react_agent.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_call_tool_node.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_capability_routes_and_thinking.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_compiler_basic.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_context_and_builder_nodes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_continue_on_error.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_edit_json_schema_node.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_event_inbox_react_agent.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_file_nodes_workspace.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_function_library.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_get_element_node.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_get_random_element_node.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_get_var_node.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_has_tools_builtin.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_llm_call_context_attachments_map_to_media.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_llm_call_multimodal_output.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_make_object_node.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_media_nodes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_memory_effect_nodes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_memory_source_pins.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_pin_expressions.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_prompt_only.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_random_nodes.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_schema_enum_switch.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_string_contains_replace.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_visualflow_tool_parameters_node.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_voice_openai_api_key_path.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_w4_feelings_lens.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_wait_event_deadline.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_wait_event_prompt_metadata.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_wait_until_streak.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_wait_until_utc_normalization.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workflow_bundle_registry.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workspace_builtin_deny.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workspace_context_allowed_workspaces.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workspace_policy_absolute_reanchor.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workspace_policy_allowlist_mode.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workspace_policy_mount_virtual_paths.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workspace_policy_tool_calls_persist_across_restart.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workspace_prompt_context.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workspace_read_only.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_workspace_writable_paths.py +0 -0
- {abstractruntime-0.9.0 → abstractruntime-0.10.0}/tests/test_write_chart.py +0 -0
|
@@ -5,6 +5,44 @@ 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
|
+
## [0.10.0] - 2026-10-15
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Trigger source `schedule@2`: `{kind: "daily", at: "HH:MM"}`, `{kind: "weekly", days: [...], at}` and `{kind: "monthly", day: 1..31 | "last", at}` evaluated on wall time in the config's `time_zone` (IANA, converted with `zoneinfo`: a skipped wall time runs at the shifted instant, a repeated one runs once; a day beyond the month's length runs on its last day), plus `{kind: "every"}` and `{kind: "once"}` with `schedule@1`'s meaning (a `once` may give a wall time `at` in `time_zone`). Same coalescing and pause policy as `schedule@1`; event ids `schedule@2:<binding_id>:<tick>`. `validate_time_zone(name)` and `time_zone_names()` are exported from `abstractruntime.triggers`. See `docs/automations.md`.
|
|
13
|
+
- `integrations.abstractcore.config_facade.voice_input_hint(route, host=None)`: AbstractCore's served one-line hint for a configured speech-input route (`abstractcore.config.recommendations.voice_input_hint`, AbstractCore >= 2.26.0), so a host such as AbstractGateway serves it without importing AbstractCore itself. The AbstractCore floor is 2.26.0.
|
|
14
|
+
- A limit on an execution wire: `edge.data.loopLimit = {"max": N}` (the editor's ↺N badge on a wire that makes execution repeat). Before compile, `visual/loop_limit_lowering.py` turns it into a `loop_limit` node on that wire (`again` to the wire's target; `limit_reached` to the other branch when the wire leaves an If/Else and that branch is not itself a limited wire, else nothing: the path ends at the limit), re-keying the target's per-path values and entry list. A run tree shows the lowered node as "Loop limit N". `VisualEdge` now carries `data` (older runtimes never read it, so a limited flow runs unlimited there).
|
|
15
|
+
- VisualFlow `get_vars` node (Get Variables): a data node with one output per variable, its pin id the variable name (dotted paths allowed); each output reads the run variable's current value, or null when it is not set.
|
|
16
|
+
- VisualFlow `loop_limit` node (Loop Limit): exec outputs `again` (taken while fewer than `max` passes were let through) and `limit_reached` (then the count starts again from 0), data output `count` (the pass number). The count lives in `run.vars._temp.loop_limits.<node id>`, so it survives pause/resume. It belongs to the current iteration of the enclosing ForEach / For / While (each item, and each new entry of that loop, starts from 0); with no enclosing loop, to the run. Its `max` comes only from its own pin, never from the previous step's output.
|
|
17
|
+
- VisualFlow `add_to_list` node (Add to List Variable): `name`, `item` (added as one element), `items` (each element added); a missing or null variable starts as `[]`; a variable that holds something else, or `items` that is not a list, fails the step naming it; reads and writes in one step; output `list`.
|
|
18
|
+
- String Template: a placeholder reads an input pin of its name, then the `vars` object, then the run variable (top-level names not starting with `_`). A list or object with no filter is written as JSON (it was Python's `str()`).
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- An execution wire that loops back out of a ForEach / For / While body (from inside the body to the loop node itself or to anything before it) is refused when the flow compiles: "Wire <source>.<pin> -> <target> goes back out of <loop>'s loop body: the run would never end. A path inside a loop body can only repeat within the body; to repeat the whole loop, wire the loop-back after the loop's done." Such a wire re-entered the loop with its frame still on the control stack, so the stack grew by one frame per pass and the run never ended (a Loop Limit on it never reached its max). A loop-back that goes through the loop's `done`, or that stays inside the body, is unchanged (`visual/loop_back_check.py`).
|
|
23
|
+
- `schedule@1` is unchanged: its configs normalize byte for byte as before and existing automations keep their tick grid (`tests/test_schedule_v1_corpus.py` freezes the 0.9.1 answers on real automation configs).
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- Set Variables (and Add to List Variable) only take what their own pins carry (a wire, a value set on the node, an expression). Before, keys of the previous step's output were written as variables too.
|
|
28
|
+
- Set Variables (`set_vars`): every data input pin besides `updates` is one variable, written under the pin's id (dotted paths nest) with its value: a wire, else the pin's default. These win over the same name in the `updates` object. AbstractFlow edits them as rows (name, type, value), so one node initialises several variables, wired or literal. A flow using such rows needs this runtime: an older one writes only `updates`. Test: `tests/test_visual_set_vars_pins.py`.
|
|
29
|
+
- VisualFlow reroute ("relay") nodes: a dot in AbstractFlow that lets one output feed several inputs along a tidy path. They are visual only: before compiling, every chain `source -> reroute (-> reroute ...) -> target` is rewired `source -> target` and the reroutes are removed (`visualflow_compiler/visual/reroute_lowering.py`, run before the multi-entry lowering). A reroute with no source feeds nothing (its targets keep their defaults); per-path values that name a reroute point at its real source. Data wires only: an execution wire through a reroute, a second input into one, or a cycle of reroutes is refused with a message naming the wire. A flow with a connected reroute needs this runtime (older ones refuse the unknown node type). Test: `tests/test_visual_reroute_lowering.py`.
|
|
30
|
+
|
|
31
|
+
## [0.9.1] - 2026-10-08
|
|
32
|
+
|
|
33
|
+
### Security
|
|
34
|
+
|
|
35
|
+
- `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`.
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- `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.
|
|
40
|
+
- `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.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- 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.
|
|
45
|
+
|
|
8
46
|
## [0.9.0] - 2026-10-05
|
|
9
47
|
|
|
10
48
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: AbstractRuntime
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
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.26.0
|
|
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.26.0; 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.26.0; 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'
|
|
@@ -159,7 +159,7 @@ Kernel (import-light):
|
|
|
159
159
|
- Stop that reaches the running effect: `Runtime.cancel_run(...)` signals the in-flight model or tool call, which ends as a `cancelled` ledger record (never retried); a model unload stops the calls using that model first (`docs/api.md`)
|
|
160
160
|
- host pause at step boundaries: `Runtime.tick(..., step_gate=...)`
|
|
161
161
|
- run-tree tool ceiling: an explicit `allowed_tools` list can only narrow across child runs, and approval policy never widens it
|
|
162
|
-
- automations: run a workflow on a schedule (`schedule@1
|
|
162
|
+
- automations: run a workflow on a schedule (`schedule@1` fixed UTC intervals; `schedule@2` adds daily, weekly and monthly rules at a wall time in an IANA time zone), when mail arrives (`email.received@1`, `docs/email.md`) or on request (`manual@1`) as a durable controller run whose occurrences are deterministic child runs and session turns, with commands, independent or growing context, discussions forked at any occurrence (own workspace, automation workspace mounted read-only), tool approval, typed waits and quiet-by-default notifications (`docs/automations.md`)
|
|
163
163
|
- explicit run ids: `Runtime.start(..., run_id=...)` creates a run only if the id is free (`RunStore.create_if_absent`), and `run_mutation_lock(run_id)` serializes a run's writers in a process
|
|
164
164
|
|
|
165
165
|
Durability + storage:
|
|
@@ -108,7 +108,7 @@ Kernel (import-light):
|
|
|
108
108
|
- Stop that reaches the running effect: `Runtime.cancel_run(...)` signals the in-flight model or tool call, which ends as a `cancelled` ledger record (never retried); a model unload stops the calls using that model first (`docs/api.md`)
|
|
109
109
|
- host pause at step boundaries: `Runtime.tick(..., step_gate=...)`
|
|
110
110
|
- run-tree tool ceiling: an explicit `allowed_tools` list can only narrow across child runs, and approval policy never widens it
|
|
111
|
-
- automations: run a workflow on a schedule (`schedule@1
|
|
111
|
+
- automations: run a workflow on a schedule (`schedule@1` fixed UTC intervals; `schedule@2` adds daily, weekly and monthly rules at a wall time in an IANA time zone), when mail arrives (`email.received@1`, `docs/email.md`) or on request (`manual@1`) as a durable controller run whose occurrences are deterministic child runs and session turns, with commands, independent or growing context, discussions forked at any occurrence (own workspace, automation workspace mounted read-only), tool approval, typed waits and quiet-by-default notifications (`docs/automations.md`)
|
|
112
112
|
- explicit run ids: `Runtime.start(..., run_id=...)` creates a run only if the id is free (`RunStore.create_if_absent`), and `run_mutation_lock(run_id)` serializes a run's writers in a process
|
|
113
113
|
|
|
114
114
|
Durability + storage:
|
|
@@ -36,7 +36,7 @@ In this repo, the AbstractCore wiring lives under `src/abstractruntime/integrati
|
|
|
36
36
|
|
|
37
37
|
## Features (reference)
|
|
38
38
|
|
|
39
|
-
- `automations.md` — automations: a workflow run on a schedule or on request as a durable controller run; triggers (`schedule@1`, `manual@1`, `email.received@1`, entry-point sources), commands, independent or growing context, discussions forked at any occurrence (own writable workspace, the automation's workspace mounted read-only), tool approval, typed waits, notifications and retries, and the storage guarantees (create-if-absent, per-run lock, turn roots, session kinds, one writer process per store)
|
|
39
|
+
- `automations.md` — automations: a workflow run on a schedule or on request as a durable controller run; triggers (`schedule@1`, `schedule@2` calendar rules in a time zone, `manual@1`, `email.received@1`, entry-point sources), commands, independent or growing context, discussions forked at any occurrence (own writable workspace, the automation's workspace mounted read-only), tool approval, typed waits, notifications and retries, and the storage guarantees (create-if-absent, per-run lock, turn roots, session kinds, one writer process per store)
|
|
40
40
|
- `entity-runtime.md` — per-entity runtimes for summoned entities: homes, the one-writer lease, act-only diary privacy (`$act_only` refs), durable visit waits with deadlines
|
|
41
41
|
- `evidence.md` — artifact-backed evidence capture for external-boundary tools
|
|
42
42
|
- `mcp-worker.md` — MCP worker CLI (`abstractruntime-mcp-worker`)
|
|
@@ -241,7 +241,7 @@ from abstractruntime.triggers import get_trigger_adapter, trigger_sources
|
|
|
241
241
|
- reads: `get_automation(run_store, id)`, `list_occurrences(runtime, id, cursor=, limit=)`, `list_attention(ledger_store, id, after_seq=, cursor=, limit=)`, `pending_waits(run_store, id, limit=)` with typed waits (`ask_user`, `tool_approval`, `event`) and `ANSWER_PAYLOADS`; `list_automations(run_store, status=, cursor=, limit=)`, `automation_summary(run)`, `latest_occurrence(run_store, id)`
|
|
242
242
|
- `start_discussion(runtime, *, automation_id, occurrence_index, request_id, prompt, workspace_root, actor_id=None)`: a separate conversation forked at any occurrence N, seeded with the automation's whole timeline 1..N, working in its own writable `workspace_root` with the automation's workspace mounted read-only
|
|
243
243
|
- controller bundle: `register_controller_bundle(registry)`, `controller_workflow_spec()`, `controller_bundle_path()`; `CONTROLLER_WORKFLOW_ID` is `abstractframework.automation-controller@1.0.0:controller`
|
|
244
|
-
- trigger sources: `trigger_sources()`, `get_trigger_adapter(id, version)`, built-ins `schedule@1`, `manual@1` and `email.received@1`, third-party sources through the `abstractruntime.trigger_sources` entry-point group
|
|
244
|
+
- trigger sources: `trigger_sources()`, `get_trigger_adapter(id, version)`, built-ins `schedule@1`, `schedule@2` (daily/weekly/monthly rules in an IANA time zone; `validate_time_zone`, `time_zone_names`), `manual@1` and `email.received@1`, third-party sources through the `abstractruntime.trigger_sources` entry-point group
|
|
245
245
|
- definition v2: `policy.email_allowed_recipients` (default `["self"]`), `policy.untrusted_input_tools` (default `[]`) and `notify.channels` (default `["console"]`); attention items carry `channels`
|
|
246
246
|
|
|
247
247
|
## Email
|
|
@@ -332,7 +332,7 @@ flowchart LR
|
|
|
332
332
|
subgraph Automations["automations/ + triggers/"]
|
|
333
333
|
Commands["apply_automation_command"]
|
|
334
334
|
Controller["controller run<br/>(automation-controller@1.0.0)"]
|
|
335
|
-
Triggers["trigger registry<br/>schedule@1, manual@1
|
|
335
|
+
Triggers["trigger registry<br/>schedule@1, schedule@2, manual@1,<br/>email.received@1, entry-point sources"]
|
|
336
336
|
Inbox["event inbox<br/>(email/, filled by the host's watcher)"]
|
|
337
337
|
Queries["get_automation / list_occurrences /<br/>list_attention / pending_waits /<br/>list_automations"]
|
|
338
338
|
end
|
|
@@ -403,6 +403,7 @@ Invariants the design rests on:
|
|
|
403
403
|
|
|
404
404
|
AbstractRuntime includes a compiler and a portable bundle format:
|
|
405
405
|
- VisualFlow compiler: `src/abstractruntime/visualflow_compiler/*` (VisualFlow JSON -> `WorkflowSpec`)
|
|
406
|
+
- Reroute (relay) nodes are lowered first and disappear: each chain `source -> reroute (-> reroute) -> target` becomes `source -> target` (`visualflow_compiler/visual/reroute_lowering.py`), so the editor's dots are visual only. Data wires only; an execution wire through a reroute, two inputs into one, or a cycle of reroutes is refused when the flow compiles. A flow with a connected reroute needs this runtime: older ones refuse the unknown node type.
|
|
406
407
|
- Multi-entry VisualFlow authoring routes are lowered into internal `join_exec` and `path_mux` nodes when a target has multiple incoming `exec-in` edges plus per-route input overrides. This keeps authoring JSON clean while making runtime behavior explicit and restart-safe. See `workflow-bundles.md` for the concrete metadata shape.
|
|
407
408
|
- VisualFlow document nodes include `read_pdf`, `write_pdf`, and `write_docx`.
|
|
408
409
|
They use workspace-scoped paths, keep document bytes out of checkpoints, and
|
|
@@ -33,7 +33,7 @@ sources), `abstractruntime.automation_queries` (listing), `abstractruntime.sessi
|
|
|
33
33
|
|
|
34
34
|
```mermaid
|
|
35
35
|
flowchart LR
|
|
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"]
|
|
36
|
+
Trigger["Trigger source<br/>schedule@1 / schedule@2 / manual@1"] -->|"due tick or run now"| Controller["Controller run<br/>(automation id)<br/>vars._meta.automation<br/>vars._runtime.automation"]
|
|
37
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"]
|
|
@@ -172,6 +172,35 @@ Config: `{start_at?, every?, until?, count?, anchor?}`.
|
|
|
172
172
|
- The event id of a scheduled tick is `schedule@1:<binding_id>:<tick>`. A revision that changes the trigger gets a
|
|
173
173
|
new `binding_id`, so the new schedule never reuses an old event id.
|
|
174
174
|
|
|
175
|
+
### `schedule@2`
|
|
176
|
+
|
|
177
|
+
`schedule@2` adds calendar rules on wall time in a time zone. `schedule@1` stays registered and unchanged: its
|
|
178
|
+
configs normalize byte for byte as before and its automations keep their tick grid. Use `schedule@2` for new
|
|
179
|
+
automations.
|
|
180
|
+
|
|
181
|
+
Config: `{kind, at?, days?, day?, time_zone?, start_at?, every?, until?, count?}`. The normalized config always
|
|
182
|
+
carries `kind`, then the rule fields, `time_zone`, `start_at`, `anchor` (= `start_at`) and the bounds.
|
|
183
|
+
|
|
184
|
+
| `kind` | Rule fields | Meaning |
|
|
185
|
+
| --- | --- | --- |
|
|
186
|
+
| `every` | `every` (`8h`, `7d`, ...) | Exactly `schedule@1`'s fixed UTC interval from `start_at`. `time_zone` is optional and only labels the schedule. |
|
|
187
|
+
| `once` | `start_at`, or `at: "YYYY-MM-DDTHH:MM"` with `time_zone` | One run. A wall time `at` is converted to `start_at` in `time_zone`. |
|
|
188
|
+
| `daily` | `at: "HH:MM"` | Every day at that wall time. |
|
|
189
|
+
| `weekly` | `days` (non-empty subset of `mon`..`sun`), `at` | Those weekdays at that wall time. `days` is normalized to Monday-first order without duplicates. |
|
|
190
|
+
| `monthly` | `day` (1..31 or `"last"`), `at` | That day of each month; a day beyond the month's length runs on the month's last day (day 31 runs on 28 or 29 February). |
|
|
191
|
+
|
|
192
|
+
- Calendar rules (`daily`, `weekly`, `monthly`) require `time_zone`, an IANA name such as `Europe/Paris`
|
|
193
|
+
(`validate_time_zone(name)`; `time_zone_names()` lists the names the host knows). They take no `every`.
|
|
194
|
+
- Wall times convert to UTC with `zoneinfo`. A wall time that does not exist that day (spring forward) runs at the
|
|
195
|
+
shifted instant: a 02:30 rule runs at 03:30 on that day and at 02:30 afterwards. A wall time that happens twice
|
|
196
|
+
(fall back) runs once, at its first occurrence. A daily 08:00 stays at 08:00 local time across both transitions.
|
|
197
|
+
- Tick 0 is the first rule time at or after `start_at` (default: the creation time). `count` and `until` bound the
|
|
198
|
+
ticks as in `schedule@1`.
|
|
199
|
+
- Missed ticks coalesce and a resume after a pause skips the ticks that passed, exactly as in `schedule@1`. The event
|
|
200
|
+
id of a tick is `schedule@2:<binding_id>:<tick>`.
|
|
201
|
+
- Every instant is computed from its tick index in constant time, so an automation that was down for years catches up
|
|
202
|
+
with one occurrence without walking the missed ticks.
|
|
203
|
+
|
|
175
204
|
### `manual@1`
|
|
176
205
|
|
|
177
206
|
Config: `{}`. The automation runs only when asked with `automation.run_now`. A manual run of any automation, whatever
|
|
@@ -680,9 +709,9 @@ receives its result directly.
|
|
|
680
709
|
|
|
681
710
|
## Limits in v1
|
|
682
711
|
|
|
683
|
-
- Schedules are fixed UTC intervals (`
|
|
684
|
-
|
|
685
|
-
- The shipped trigger sources are `schedule@1`, `manual@1` and `email.received@1`. There is no generic external
|
|
712
|
+
- Schedules are fixed UTC intervals (`schedule@1`, `schedule@2` `every`) or daily, weekly and monthly wall-time rules
|
|
713
|
+
in an IANA time zone (`schedule@2`). There are no cron expressions, and `anchor` must equal `start_at`.
|
|
714
|
+
- The shipped trigger sources are `schedule@1`, `schedule@2`, `manual@1` and `email.received@1`. There is no generic external
|
|
686
715
|
event source yet.
|
|
687
716
|
- Occurrences run one at a time (`serial`), missed ticks coalesce, and a failed occurrence never stops the
|
|
688
717
|
automation (`failure: "continue"`). These policies cannot be changed.
|
|
@@ -49,7 +49,7 @@ Docs: `getting-started.md`. Code: `src/abstractruntime/core/runtime.py`, `src/ab
|
|
|
49
49
|
## How do I run a workflow on a schedule or on request?
|
|
50
50
|
|
|
51
51
|
Create an automation. An automation is a durable controller run that starts the target workflow as a child run (an
|
|
52
|
-
occurrence) on each trigger: `schedule@1` (fixed UTC intervals such as `5m` or `24h`) or `manual@1` (run now only).
|
|
52
|
+
occurrence) on each trigger: `schedule@1` (fixed UTC intervals such as `5m` or `24h`), `schedule@2` (the same intervals plus daily, weekly and monthly rules at a wall time in an IANA time zone, daylight-saving correct) or `manual@1` (run now only).
|
|
53
53
|
`create_automation(...)` creates it, `apply_automation_command(...)` pauses, resumes, runs now, edits, stops the
|
|
54
54
|
current occurrence, archives it or unarchives it (it comes back paused with its history), and the host drives it
|
|
55
55
|
like any run (`drive_automation` does this in-process). Nothing is deleted: an archived automation keeps its
|
|
@@ -506,6 +506,7 @@ Lists accept a JSON array, a JSON array pasted as a string, or newline-separated
|
|
|
506
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
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
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.
|
|
509
510
|
|
|
510
511
|
## Prompt-cache control plane and durable blocs
|
|
511
512
|
|
|
@@ -1048,8 +1049,14 @@ Public durable entry points:
|
|
|
1048
1049
|
These helpers create child runs under an existing parent run and execute the real
|
|
1049
1050
|
`LLM_CALL`, `TOOL_CALLS`, or stream finalization through Runtime rather than
|
|
1050
1051
|
doing external work in host/controller code. `stream_voice(...)` yields TTS
|
|
1051
|
-
stream events for progressive playback
|
|
1052
|
-
|
|
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=...)`.
|
|
1053
1060
|
|
|
1054
1061
|
Example:
|
|
1055
1062
|
|
|
@@ -157,7 +157,7 @@ Kernel (import-light):
|
|
|
157
157
|
- Stop that reaches the running effect: `Runtime.cancel_run(...)` signals the in-flight model or tool call, which ends as a `cancelled` ledger record (never retried); a model unload stops the calls using that model first (`docs/api.md`)
|
|
158
158
|
- host pause at step boundaries: `Runtime.tick(..., step_gate=...)`
|
|
159
159
|
- run-tree tool ceiling: an explicit `allowed_tools` list can only narrow across child runs, and approval policy never widens it
|
|
160
|
-
- automations: run a workflow on a schedule (`schedule@1
|
|
160
|
+
- automations: run a workflow on a schedule (`schedule@1` fixed UTC intervals; `schedule@2` adds daily, weekly and monthly rules at a wall time in an IANA time zone), when mail arrives (`email.received@1`, `docs/email.md`) or on request (`manual@1`) as a durable controller run whose occurrences are deterministic child runs and session turns, with commands, independent or growing context, discussions forked at any occurrence (own workspace, automation workspace mounted read-only), tool approval, typed waits and quiet-by-default notifications (`docs/automations.md`)
|
|
161
161
|
- explicit run ids: `Runtime.start(..., run_id=...)` creates a run only if the id is free (`RunStore.create_if_absent`), and `run_mutation_lock(run_id)` serializes a run's writers in a process
|
|
162
162
|
|
|
163
163
|
Durability + storage:
|
|
@@ -763,7 +763,7 @@ flowchart LR
|
|
|
763
763
|
subgraph Automations["automations/ + triggers/"]
|
|
764
764
|
Commands["apply_automation_command"]
|
|
765
765
|
Controller["controller run<br/>(automation-controller@1.0.0)"]
|
|
766
|
-
Triggers["trigger registry<br/>schedule@1, manual@1
|
|
766
|
+
Triggers["trigger registry<br/>schedule@1, schedule@2, manual@1,<br/>email.received@1, entry-point sources"]
|
|
767
767
|
Inbox["event inbox<br/>(email/, filled by the host's watcher)"]
|
|
768
768
|
Queries["get_automation / list_occurrences /<br/>list_attention / pending_waits /<br/>list_automations"]
|
|
769
769
|
end
|
|
@@ -834,6 +834,7 @@ Invariants the design rests on:
|
|
|
834
834
|
|
|
835
835
|
AbstractRuntime includes a compiler and a portable bundle format:
|
|
836
836
|
- VisualFlow compiler: `src/abstractruntime/visualflow_compiler/*` (VisualFlow JSON -> `WorkflowSpec`)
|
|
837
|
+
- Reroute (relay) nodes are lowered first and disappear: each chain `source -> reroute (-> reroute) -> target` becomes `source -> target` (`visualflow_compiler/visual/reroute_lowering.py`), so the editor's dots are visual only. Data wires only; an execution wire through a reroute, two inputs into one, or a cycle of reroutes is refused when the flow compiles. A flow with a connected reroute needs this runtime: older ones refuse the unknown node type.
|
|
837
838
|
- Multi-entry VisualFlow authoring routes are lowered into internal `join_exec` and `path_mux` nodes when a target has multiple incoming `exec-in` edges plus per-route input overrides. This keeps authoring JSON clean while making runtime behavior explicit and restart-safe. See `workflow-bundles.md` for the concrete metadata shape.
|
|
838
839
|
- VisualFlow document nodes include `read_pdf`, `write_pdf`, and `write_docx`.
|
|
839
840
|
They use workspace-scoped paths, keep document bytes out of checkpoints, and
|
|
@@ -1106,7 +1107,7 @@ from abstractruntime.triggers import get_trigger_adapter, trigger_sources
|
|
|
1106
1107
|
- reads: `get_automation(run_store, id)`, `list_occurrences(runtime, id, cursor=, limit=)`, `list_attention(ledger_store, id, after_seq=, cursor=, limit=)`, `pending_waits(run_store, id, limit=)` with typed waits (`ask_user`, `tool_approval`, `event`) and `ANSWER_PAYLOADS`; `list_automations(run_store, status=, cursor=, limit=)`, `automation_summary(run)`, `latest_occurrence(run_store, id)`
|
|
1107
1108
|
- `start_discussion(runtime, *, automation_id, occurrence_index, request_id, prompt, workspace_root, actor_id=None)`: a separate conversation forked at any occurrence N, seeded with the automation's whole timeline 1..N, working in its own writable `workspace_root` with the automation's workspace mounted read-only
|
|
1108
1109
|
- controller bundle: `register_controller_bundle(registry)`, `controller_workflow_spec()`, `controller_bundle_path()`; `CONTROLLER_WORKFLOW_ID` is `abstractframework.automation-controller@1.0.0:controller`
|
|
1109
|
-
- trigger sources: `trigger_sources()`, `get_trigger_adapter(id, version)`, built-ins `schedule@1`, `manual@1` and `email.received@1`, third-party sources through the `abstractruntime.trigger_sources` entry-point group
|
|
1110
|
+
- trigger sources: `trigger_sources()`, `get_trigger_adapter(id, version)`, built-ins `schedule@1`, `schedule@2` (daily/weekly/monthly rules in an IANA time zone; `validate_time_zone`, `time_zone_names`), `manual@1` and `email.received@1`, third-party sources through the `abstractruntime.trigger_sources` entry-point group
|
|
1110
1111
|
- definition v2: `policy.email_allowed_recipients` (default `["self"]`), `policy.untrusted_input_tools` (default `[]`) and `notify.channels` (default `["console"]`); attention items carry `channels`
|
|
1111
1112
|
|
|
1112
1113
|
## Email
|
|
@@ -1323,7 +1324,7 @@ Docs: `getting-started.md`. Code: `src/abstractruntime/core/runtime.py`, `src/ab
|
|
|
1323
1324
|
## How do I run a workflow on a schedule or on request?
|
|
1324
1325
|
|
|
1325
1326
|
Create an automation. An automation is a durable controller run that starts the target workflow as a child run (an
|
|
1326
|
-
occurrence) on each trigger: `schedule@1` (fixed UTC intervals such as `5m` or `24h`) or `manual@1` (run now only).
|
|
1327
|
+
occurrence) on each trigger: `schedule@1` (fixed UTC intervals such as `5m` or `24h`), `schedule@2` (the same intervals plus daily, weekly and monthly rules at a wall time in an IANA time zone, daylight-saving correct) or `manual@1` (run now only).
|
|
1327
1328
|
`create_automation(...)` creates it, `apply_automation_command(...)` pauses, resumes, runs now, edits, stops the
|
|
1328
1329
|
current occurrence, archives it or unarchives it (it comes back paused with its history), and the host drives it
|
|
1329
1330
|
like any run (`drive_automation` does this in-process). Nothing is deleted: an archived automation keeps its
|
|
@@ -2480,6 +2481,7 @@ Lists accept a JSON array, a JSON array pasted as a string, or newline-separated
|
|
|
2480
2481
|
- 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
2482
|
- **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
2483
|
- **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.
|
|
2484
|
+
- **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.
|
|
2483
2485
|
|
|
2484
2486
|
## Prompt-cache control plane and durable blocs
|
|
2485
2487
|
|
|
@@ -3022,8 +3024,14 @@ Public durable entry points:
|
|
|
3022
3024
|
These helpers create child runs under an existing parent run and execute the real
|
|
3023
3025
|
`LLM_CALL`, `TOOL_CALLS`, or stream finalization through Runtime rather than
|
|
3024
3026
|
doing external work in host/controller code. `stream_voice(...)` yields TTS
|
|
3025
|
-
stream events for progressive playback
|
|
3026
|
-
|
|
3027
|
+
stream events for progressive playback; it is never a wait: nothing durable
|
|
3028
|
+
exists while audio streams, and when the stream ends (done, error, cancel or
|
|
3029
|
+
the consumer closing it) the child run is created already completed with the
|
|
3030
|
+
outcome (the final audio artifact on success). The child's id is announced up
|
|
3031
|
+
front in the `runtime_start` event (`child_run_id`). A host that finds a
|
|
3032
|
+
streamed-speech wait left by a runtime before this behaviour
|
|
3033
|
+
(`is_interrupted_voice_stream_wait`) closes it with
|
|
3034
|
+
`close_interrupted_voice_stream(child_run_id, reason=...)`.
|
|
3027
3035
|
|
|
3028
3036
|
Example:
|
|
3029
3037
|
|
|
@@ -3599,7 +3607,7 @@ sources), `abstractruntime.automation_queries` (listing), `abstractruntime.sessi
|
|
|
3599
3607
|
|
|
3600
3608
|
```mermaid
|
|
3601
3609
|
flowchart LR
|
|
3602
|
-
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"]
|
|
3610
|
+
Trigger["Trigger source<br/>schedule@1 / schedule@2 / manual@1"] -->|"due tick or run now"| Controller["Controller run<br/>(automation id)<br/>vars._meta.automation<br/>vars._runtime.automation"]
|
|
3603
3611
|
Commands["apply_automation_command<br/>pause / resume / run_now /<br/>revise / stop_current / archive / unarchive"] -->|"decision + wake"| Controller
|
|
3604
3612
|
Controller -->|"START_SUBWORKFLOW<br/>deterministic run_id"| Occurrence["Occurrence run<br/>role: occurrence<br/>(a session turn)"]
|
|
3605
3613
|
Occurrence --> Descendants["Descendant runs<br/>role: descendant"]
|
|
@@ -3738,6 +3746,35 @@ Config: `{start_at?, every?, until?, count?, anchor?}`.
|
|
|
3738
3746
|
- The event id of a scheduled tick is `schedule@1:<binding_id>:<tick>`. A revision that changes the trigger gets a
|
|
3739
3747
|
new `binding_id`, so the new schedule never reuses an old event id.
|
|
3740
3748
|
|
|
3749
|
+
### `schedule@2`
|
|
3750
|
+
|
|
3751
|
+
`schedule@2` adds calendar rules on wall time in a time zone. `schedule@1` stays registered and unchanged: its
|
|
3752
|
+
configs normalize byte for byte as before and its automations keep their tick grid. Use `schedule@2` for new
|
|
3753
|
+
automations.
|
|
3754
|
+
|
|
3755
|
+
Config: `{kind, at?, days?, day?, time_zone?, start_at?, every?, until?, count?}`. The normalized config always
|
|
3756
|
+
carries `kind`, then the rule fields, `time_zone`, `start_at`, `anchor` (= `start_at`) and the bounds.
|
|
3757
|
+
|
|
3758
|
+
| `kind` | Rule fields | Meaning |
|
|
3759
|
+
| --- | --- | --- |
|
|
3760
|
+
| `every` | `every` (`8h`, `7d`, ...) | Exactly `schedule@1`'s fixed UTC interval from `start_at`. `time_zone` is optional and only labels the schedule. |
|
|
3761
|
+
| `once` | `start_at`, or `at: "YYYY-MM-DDTHH:MM"` with `time_zone` | One run. A wall time `at` is converted to `start_at` in `time_zone`. |
|
|
3762
|
+
| `daily` | `at: "HH:MM"` | Every day at that wall time. |
|
|
3763
|
+
| `weekly` | `days` (non-empty subset of `mon`..`sun`), `at` | Those weekdays at that wall time. `days` is normalized to Monday-first order without duplicates. |
|
|
3764
|
+
| `monthly` | `day` (1..31 or `"last"`), `at` | That day of each month; a day beyond the month's length runs on the month's last day (day 31 runs on 28 or 29 February). |
|
|
3765
|
+
|
|
3766
|
+
- Calendar rules (`daily`, `weekly`, `monthly`) require `time_zone`, an IANA name such as `Europe/Paris`
|
|
3767
|
+
(`validate_time_zone(name)`; `time_zone_names()` lists the names the host knows). They take no `every`.
|
|
3768
|
+
- Wall times convert to UTC with `zoneinfo`. A wall time that does not exist that day (spring forward) runs at the
|
|
3769
|
+
shifted instant: a 02:30 rule runs at 03:30 on that day and at 02:30 afterwards. A wall time that happens twice
|
|
3770
|
+
(fall back) runs once, at its first occurrence. A daily 08:00 stays at 08:00 local time across both transitions.
|
|
3771
|
+
- Tick 0 is the first rule time at or after `start_at` (default: the creation time). `count` and `until` bound the
|
|
3772
|
+
ticks as in `schedule@1`.
|
|
3773
|
+
- Missed ticks coalesce and a resume after a pause skips the ticks that passed, exactly as in `schedule@1`. The event
|
|
3774
|
+
id of a tick is `schedule@2:<binding_id>:<tick>`.
|
|
3775
|
+
- Every instant is computed from its tick index in constant time, so an automation that was down for years catches up
|
|
3776
|
+
with one occurrence without walking the missed ticks.
|
|
3777
|
+
|
|
3741
3778
|
### `manual@1`
|
|
3742
3779
|
|
|
3743
3780
|
Config: `{}`. The automation runs only when asked with `automation.run_now`. A manual run of any automation, whatever
|
|
@@ -4246,9 +4283,9 @@ receives its result directly.
|
|
|
4246
4283
|
|
|
4247
4284
|
## Limits in v1
|
|
4248
4285
|
|
|
4249
|
-
- Schedules are fixed UTC intervals (`
|
|
4250
|
-
|
|
4251
|
-
- The shipped trigger sources are `schedule@1`, `manual@1` and `email.received@1`. There is no generic external
|
|
4286
|
+
- Schedules are fixed UTC intervals (`schedule@1`, `schedule@2` `every`) or daily, weekly and monthly wall-time rules
|
|
4287
|
+
in an IANA time zone (`schedule@2`). There are no cron expressions, and `anchor` must equal `start_at`.
|
|
4288
|
+
- The shipped trigger sources are `schedule@1`, `schedule@2`, `manual@1` and `email.received@1`. There is no generic external
|
|
4252
4289
|
event source yet.
|
|
4253
4290
|
- Occurrences run one at a time (`serial`), missed ticks coalesce, and a failed occurrence never stops the
|
|
4254
4291
|
automation (`failure: "continue"`). These policies cannot be changed.
|
|
@@ -5887,7 +5924,7 @@ In this repo, the AbstractCore wiring lives under `src/abstractruntime/integrati
|
|
|
5887
5924
|
|
|
5888
5925
|
## Features (reference)
|
|
5889
5926
|
|
|
5890
|
-
- `automations.md` — automations: a workflow run on a schedule or on request as a durable controller run; triggers (`schedule@1`, `manual@1`, `email.received@1`, entry-point sources), commands, independent or growing context, discussions forked at any occurrence (own writable workspace, the automation's workspace mounted read-only), tool approval, typed waits, notifications and retries, and the storage guarantees (create-if-absent, per-run lock, turn roots, session kinds, one writer process per store)
|
|
5927
|
+
- `automations.md` — automations: a workflow run on a schedule or on request as a durable controller run; triggers (`schedule@1`, `schedule@2` calendar rules in a time zone, `manual@1`, `email.received@1`, entry-point sources), commands, independent or growing context, discussions forked at any occurrence (own writable workspace, the automation's workspace mounted read-only), tool approval, typed waits, notifications and retries, and the storage guarantees (create-if-absent, per-run lock, turn roots, session kinds, one writer process per store)
|
|
5891
5928
|
- `entity-runtime.md` — per-entity runtimes for summoned entities: homes, the one-writer lease, act-only diary privacy (`$act_only` refs), durable visit waits with deadlines
|
|
5892
5929
|
- `evidence.md` — artifact-backed evidence capture for external-boundary tools
|
|
5893
5930
|
- `mcp-worker.md` — MCP worker CLI (`abstractruntime-mcp-worker`)
|
|
@@ -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.9.
|
|
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`)
|
|
@@ -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, 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
|
|
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), `schedule@2` (the same plus daily/weekly/monthly wall-time rules in an IANA time zone, DST-correct) 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.10.0"
|
|
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,11 @@ 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
|
+
# 2.26.0: `abstractcore.config.recommendations.voice_input_hint`, served through
|
|
59
|
+
# `config_facade.voice_input_hint` (the speech-input row's hint; round 16).
|
|
60
|
+
"abstractcore>=2.26.0",
|
|
57
61
|
"openai<3.0.0,>=1.109.1",
|
|
58
62
|
"httpx<1.0.0,>=0.28.1",
|
|
59
63
|
"anyio<5.0.0,>=4.12.1",
|
|
@@ -70,12 +74,12 @@ dependencies = [
|
|
|
70
74
|
|
|
71
75
|
[project.optional-dependencies]
|
|
72
76
|
apple = [
|
|
73
|
-
"abstractcore[apple]>=2.
|
|
77
|
+
"abstractcore[apple]>=2.26.0",
|
|
74
78
|
"setuptools<82.0.0,>=80.10.2",
|
|
75
79
|
]
|
|
76
80
|
|
|
77
81
|
gpu = [
|
|
78
|
-
"abstractcore[gpu]>=2.
|
|
82
|
+
"abstractcore[gpu]>=2.26.0",
|
|
79
83
|
# vLLM 0.9-0.19 caps setuptools below 80; 77.0.3 is still a modern floor.
|
|
80
84
|
"setuptools<82.0.0,>=77.0.3",
|
|
81
85
|
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
### Added
|
|
2
|
+
|
|
3
|
+
- Trigger source `schedule@2`: `{kind: "daily", at: "HH:MM"}`, `{kind: "weekly", days: [...], at}` and `{kind: "monthly", day: 1..31 | "last", at}` evaluated on wall time in the config's `time_zone` (IANA, converted with `zoneinfo`: a skipped wall time runs at the shifted instant, a repeated one runs once; a day beyond the month's length runs on its last day), plus `{kind: "every"}` and `{kind: "once"}` with `schedule@1`'s meaning (a `once` may give a wall time `at` in `time_zone`). Same coalescing and pause policy as `schedule@1`; event ids `schedule@2:<binding_id>:<tick>`. `validate_time_zone(name)` and `time_zone_names()` are exported from `abstractruntime.triggers`. See `docs/automations.md`.
|
|
4
|
+
- `integrations.abstractcore.config_facade.voice_input_hint(route, host=None)`: AbstractCore's served one-line hint for a configured speech-input route (`abstractcore.config.recommendations.voice_input_hint`, AbstractCore >= 2.26.0), so a host such as AbstractGateway serves it without importing AbstractCore itself. The AbstractCore floor is 2.26.0.
|
|
5
|
+
- A limit on an execution wire: `edge.data.loopLimit = {"max": N}` (the editor's ↺N badge on a wire that makes execution repeat). Before compile, `visual/loop_limit_lowering.py` turns it into a `loop_limit` node on that wire (`again` to the wire's target; `limit_reached` to the other branch when the wire leaves an If/Else and that branch is not itself a limited wire, else nothing: the path ends at the limit), re-keying the target's per-path values and entry list. A run tree shows the lowered node as "Loop limit N". `VisualEdge` now carries `data` (older runtimes never read it, so a limited flow runs unlimited there).
|
|
6
|
+
- VisualFlow `get_vars` node (Get Variables): a data node with one output per variable, its pin id the variable name (dotted paths allowed); each output reads the run variable's current value, or null when it is not set.
|
|
7
|
+
- VisualFlow `loop_limit` node (Loop Limit): exec outputs `again` (taken while fewer than `max` passes were let through) and `limit_reached` (then the count starts again from 0), data output `count` (the pass number). The count lives in `run.vars._temp.loop_limits.<node id>`, so it survives pause/resume. It belongs to the current iteration of the enclosing ForEach / For / While (each item, and each new entry of that loop, starts from 0); with no enclosing loop, to the run. Its `max` comes only from its own pin, never from the previous step's output.
|
|
8
|
+
- VisualFlow `add_to_list` node (Add to List Variable): `name`, `item` (added as one element), `items` (each element added); a missing or null variable starts as `[]`; a variable that holds something else, or `items` that is not a list, fails the step naming it; reads and writes in one step; output `list`.
|
|
9
|
+
- String Template: a placeholder reads an input pin of its name, then the `vars` object, then the run variable (top-level names not starting with `_`). A list or object with no filter is written as JSON (it was Python's `str()`).
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- An execution wire that loops back out of a ForEach / For / While body (from inside the body to the loop node itself or to anything before it) is refused when the flow compiles: "Wire <source>.<pin> -> <target> goes back out of <loop>'s loop body: the run would never end. A path inside a loop body can only repeat within the body; to repeat the whole loop, wire the loop-back after the loop's done." Such a wire re-entered the loop with its frame still on the control stack, so the stack grew by one frame per pass and the run never ended (a Loop Limit on it never reached its max). A loop-back that goes through the loop's `done`, or that stays inside the body, is unchanged (`visual/loop_back_check.py`).
|
|
14
|
+
- `schedule@1` is unchanged: its configs normalize byte for byte as before and existing automations keep their tick grid (`tests/test_schedule_v1_corpus.py` freezes the 0.9.1 answers on real automation configs).
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Set Variables (and Add to List Variable) only take what their own pins carry (a wire, a value set on the node, an expression). Before, keys of the previous step's output were written as variables too.
|
|
19
|
+
- Set Variables (`set_vars`): every data input pin besides `updates` is one variable, written under the pin's id (dotted paths nest) with its value: a wire, else the pin's default. These win over the same name in the `updates` object. AbstractFlow edits them as rows (name, type, value), so one node initialises several variables, wired or literal. A flow using such rows needs this runtime: an older one writes only `updates`. Test: `tests/test_visual_set_vars_pins.py`.
|
|
20
|
+
- VisualFlow reroute ("relay") nodes: a dot in AbstractFlow that lets one output feed several inputs along a tidy path. They are visual only: before compiling, every chain `source -> reroute (-> reroute ...) -> target` is rewired `source -> target` and the reroutes are removed (`visualflow_compiler/visual/reroute_lowering.py`, run before the multi-entry lowering). A reroute with no source feeds nothing (its targets keep their defaults); per-path values that name a reroute point at its real source. Data wires only: an execution wire through a reroute, a second input into one, or a cycle of reroutes is refused with a message naming the wire. A flow with a connected reroute needs this runtime (older ones refuse the unknown node type). Test: `tests/test_visual_reroute_lowering.py`.
|
|
@@ -46,8 +46,10 @@ from .discovery_facade import (
|
|
|
46
46
|
get_abstractcore_discovery_facade,
|
|
47
47
|
)
|
|
48
48
|
from .run_facade import (
|
|
49
|
+
LEGACY_VOICE_STREAM_WAIT_KEY_PREFIX,
|
|
49
50
|
AbstractCoreRunFacade,
|
|
50
51
|
get_abstractcore_run_facade,
|
|
52
|
+
is_interrupted_voice_stream_wait,
|
|
51
53
|
)
|
|
52
54
|
from .telegram_facade import (
|
|
53
55
|
TelegramTdlibNotAvailable,
|
|
@@ -108,6 +110,8 @@ __all__ = [
|
|
|
108
110
|
"ResponseFormatError",
|
|
109
111
|
"get_global_telegram_client",
|
|
110
112
|
"get_abstractcore_run_facade",
|
|
113
|
+
"is_interrupted_voice_stream_wait",
|
|
114
|
+
"LEGACY_VOICE_STREAM_WAIT_KEY_PREFIX",
|
|
111
115
|
"create_local_runtime",
|
|
112
116
|
"create_remote_runtime",
|
|
113
117
|
"create_hybrid_runtime",
|
|
@@ -11,6 +11,7 @@ Scope:
|
|
|
11
11
|
use scoped per-principal config files)
|
|
12
12
|
- resolve the effective AbstractCore config file path
|
|
13
13
|
- enumerate capability-default route specs (the catalog of known routes)
|
|
14
|
+
- the served speech-input hint for a configured route (`voice_input_hint`, AbstractCore >= 2.26.0)
|
|
14
15
|
- read a provider API key from a specific AbstractCore config file
|
|
15
16
|
- read AbstractCore's stored mail (IMAP/SMTP) and maintenance-triage settings
|
|
16
17
|
- model weights: availability probes and single downloads (`model_materializer`)
|
|
@@ -221,6 +222,30 @@ def recommended_capability_selectors() -> List[str]:
|
|
|
221
222
|
return []
|
|
222
223
|
|
|
223
224
|
|
|
225
|
+
def voice_input_hint(
|
|
226
|
+
route: Dict[str, Any], host: Optional[Dict[str, Any]] = None
|
|
227
|
+
) -> Optional[Dict[str, Any]]:
|
|
228
|
+
"""AbstractCore's served one-line hint for a CONFIGURED speech-input route, or None.
|
|
229
|
+
|
|
230
|
+
`abstractcore.config.recommendations.voice_input_hint` (AbstractCore >= 2.26.0):
|
|
231
|
+
THE sentence clients show next to the Voice input row, verbatim -- for example
|
|
232
|
+
a faster-whisper route on Apple silicon runs on the processor while mlx-whisper
|
|
233
|
+
runs the same model on the GPU. Computed from the host and the installed
|
|
234
|
+
engines, never in a client; it never changes the route. Raises when
|
|
235
|
+
AbstractCore is too old: a host serving the speech-input row without its hint
|
|
236
|
+
would be a silent regression.
|
|
237
|
+
"""
|
|
238
|
+
try:
|
|
239
|
+
from abstractcore.config.recommendations import voice_input_hint as _core_voice_input_hint
|
|
240
|
+
except Exception as exc:
|
|
241
|
+
raise RuntimeError(
|
|
242
|
+
"AbstractCore's speech-input hint is unavailable "
|
|
243
|
+
"(abstractcore.config.recommendations.voice_input_hint needs AbstractCore >= 2.26.0)."
|
|
244
|
+
) from exc
|
|
245
|
+
answer = _core_voice_input_hint(dict(route), host)
|
|
246
|
+
return dict(answer) if answer else None
|
|
247
|
+
|
|
248
|
+
|
|
224
249
|
def capability_default_specs() -> Dict[str, Dict[str, Any]]:
|
|
225
250
|
"""Return {route_key -> spec dict} for all known capability-default routes."""
|
|
226
251
|
try:
|