AbstractRuntime 0.4.10__tar.gz → 0.4.11__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.4.10 → abstractruntime-0.4.11}/CHANGELOG.md +10 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/PKG-INFO +8 -8
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/pyproject.toml +8 -8
- abstractruntime-0.4.11/release-notes.md +6 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/effect_handlers.py +43 -2
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/llm_client.py +18 -2
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/visual/executor.py +17 -6
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_client_media_artifacts.py +8 -3
- abstractruntime-0.4.11/tests/test_media_artifact_resolution.py +66 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_multimodal_abstractcore_integration.py +8 -1
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_session_attachments_registry_and_open_tool.py +9 -1
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_media_nodes.py +18 -2
- abstractruntime-0.4.10/release-notes.md +0 -6
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/.github/workflows/ci.yml +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/.github/workflows/release.yml +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/.gitignore +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/ACKNOWLEDGMENTS.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/CONTRIBUTING.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/LICENSE +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/README.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/ROADMAP.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/SECURITY.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/README.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/adr/0001_layered_coupling_with_abstractcore.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/adr/0002_execution_modes_local_remote_hybrid.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/adr/0003_provenance_tamper_evident_hash_chain.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/adr/README.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/api.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/architecture.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/README.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/001_runtime_kernel.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/002_persistence_and_ledger.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/003_wait_primitives.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/004_scheduler_driver.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/005_abstractcore_integration.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/006_snapshots_bookmarks.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/007_provenance_hash_chain.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/009_artifact_store.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/010_examples_and_composition.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/011_subworkflow_support.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/012_run_store_query_and_scheduler_support.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/013_effect_retries_and_idempotency.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/016_runtime_aware_parameters.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/001_integrations_abstractcore.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/001_runtime_kernel.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/002_persistence_and_ledger.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/002_snapshots_bookmarks.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/003_provenance_ledger_chain.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/003_wait_resume_and_scheduler.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/004_effect_handlers_and_integrations.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/004_tests.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/005_docs_updates.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/005_examples_and_composition.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/006_ai_fingerprint_and_provenance.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/DEPRECATED_README.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/README.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/abstractruntime_docs_final_02a7373b.plan.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/planned/008_signatures_and_keys.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/planned/014_remote_tool_worker_executor.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/planned/015_agent_integration_improvements.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/planned/017_limit_warnings_and_observability.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/planned/018_workspace_access_policy_for_media_and_tools.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/proposed/2026-05-08_runtime_gateway_env_namespace_cleanup.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/proposed/2026-05-08_runtime_gateway_install_boundary.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/proposed/2026-05-09_runtime_retention_and_purge_contract.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/evidence.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/faq.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/getting-started.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/integrations/abstractcore.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/limits.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/manual_testing.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/mcp-worker.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/proposal.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/provenance.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/snapshots.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/tools-comms.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/workflow-bundles.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/emails.config.example.yaml +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/examples/01_hello_world.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/examples/02_ask_user.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/examples/03_wait_until.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/examples/04_multi_step.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/examples/05_persistence.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/examples/06_llm_integration.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/examples/07_react_agent.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/examples/README.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/llms-full.txt +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/llms.txt +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/mkdocs.yml +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/pytest.ini +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/core/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/core/config.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/core/event_keys.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/core/models.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/core/policy.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/core/runtime.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/core/spec.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/core/vars.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/evidence/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/evidence/recorder.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/history_bundle.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/identity/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/identity/fingerprint.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/constants.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/default_tools.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/embeddings_client.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/factory.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/logging.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/mcp_worker.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/observability.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/output_specs.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/session_attachments.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/summarizer.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/tool_executor.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractcore/workspace_scoped_tools.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractmemory/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/integrations/abstractmemory/effect_handlers.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/memory/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/memory/active_context.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/memory/active_memory.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/memory/compaction.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/memory/kg_packets.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/memory/memact_composer.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/memory/recall_levels.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/memory/token_budget.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/rendering/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/rendering/agent_trace_report.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/rendering/json_stringify.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/scheduler/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/scheduler/convenience.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/scheduler/registry.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/scheduler/scheduler.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/artifacts.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/base.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/commands.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/in_memory.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/json_files.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/ledger_chain.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/observable.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/offloading.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/snapshots.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/storage/sqlite.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/agent_adapter.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/context_adapter.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/control_adapter.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/effect_adapter.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/event_adapter.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/function_adapter.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/memact_adapter.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/subflow_adapter.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/adapters/variable_adapter.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/compiler.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/flow.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/visual/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/visual/agent_ids.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/visual/builtins.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/visual/code_executor.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/visual/models.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/visualflow_compiler/visual/multi_entry_lowering.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/workflow_bundle/__init__.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/workflow_bundle/models.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/workflow_bundle/packer.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/workflow_bundle/reader.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/src/abstractruntime/workflow_bundle/registry.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/README.md +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/conftest.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_active_context_policy.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_active_memory.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_answer_user_effect.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_artifacts.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_chat_summarizer_integration.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_command_store.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_compaction_helpers.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_control_adapter_while.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_default_tools_comms_gating.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_default_tools_include_skim_files.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_default_tools_include_skim_folders.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_default_tools_search_files_executor.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_durable_toolsets.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_e2e_tool_calls_idempotency_lmstudio.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_emit_event_without_workflow_registry.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_evidence_recorder.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_factory_timeouts_default_to_abstractcore_config.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_integration_abstractcore.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_integrations_abstractcore.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_json_file_run_store_children_index.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_jsonl_ledger_recovery.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_kg_learn_and_recall_contract.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_ledger_chain.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_ledger_subscription.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_call_media_artifact_refs.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_call_media_artifact_refs_persist_across_restart.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_call_media_uses_source_path_label.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_call_requires_prompt.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_call_response_schema_normalization.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_call_structured_output_fallback.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_call_truncation_retry_contract.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_call_use_context_appends_turn.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_call_verbatim_payload_capture.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_client_system_context.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_llm_client_tool_call_parsing.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_local_runtime_timeout_kwarg_policy.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_mcp_remote_tool_executor.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_mcp_worker_logging.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_mcp_worker_security.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_mcp_worker_stdio.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memact_composer_from_kg_result.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_kg_assert_attributes_defaults.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_kg_packets.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_kg_predicate_aliasing.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_kg_query_packetization_restart.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_kg_query_recall_level_policy.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_kg_semantic_query_ranking.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_note_effect.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_query_effect.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_query_rich_filters.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_scope_and_rehydrate_effect.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_memory_tag_effect.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_mlx_generation_serialization.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_offloading.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_packaging_extras.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_pause_resume.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_prompt_cache_modules.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_queryable_run_store.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_read_file_fallback_to_session_attachments.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_real_integration.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_recall_levels_policy.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_remote_llm_client.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_rendering_agent_trace_report.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_rendering_json_stringify.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_retry_idempotency.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_run_history_bundle.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_runtime_config_max_output_tokens_fallback.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_runtime_install_boundary.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_runtime_llm_call_grounding_in_ledger.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_runtime_node_traces.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_runtime_start_seeds_tool_support.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_scheduler.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_snapshots.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_sqlite_ledger_store.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_start_subworkflow_async_wait.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_start_subworkflow_inherit_context_merges_messages.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_start_subworkflow_workspace_inheritance.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_structured_output_schema_enum.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_subworkflow.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_terminal_effect_completion.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_terminal_resume_appends_ledger_completion.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tick_completion_includes_output_in_ledger.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_approval_executor.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_approval_resume_executes.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_calls_idempotency_keys.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_executor_argument_sanitization.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_executor_error_output_detection.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_executor_filename_alias.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_executor_kwarg_canonicalization.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_executor_read_file_aliases.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_executor_timeout.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_tool_wait_allowlist_safety.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_trace_context_propagation.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_vars_query_effect.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_agent_output_context_includes_messages.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_agent_tool_observations_persist_across_restart.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_agent_use_context_inherits_attachments.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_agent_use_context_persists_tool_observations.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_agent_use_context_persists_turn.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_llm_call_schema_ref_resolution.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_memact_compose_node.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_memory_kg_query_outputs_propagate.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_memory_kg_resolve_outputs_propagate.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visual_multi_entry_loop_overrides.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_add_message_builtin.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_add_message_node_appends_to_active_context.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_call_tool_node.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_compiler_basic.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_context_and_builder_nodes.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_get_element_node.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_get_random_element_node.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_has_tools_builtin.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_llm_call_context_attachments_map_to_media.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_llm_call_multimodal_output.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_make_object_node.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_memory_effect_nodes.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_memory_source_pins.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_prompt_only.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_random_nodes.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_string_contains_replace.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_visualflow_tool_parameters_node.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_wait_event_prompt_metadata.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_workflow_bundle_registry.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_workspace_policy_allowlist_mode.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_workspace_policy_mount_virtual_paths.py +0 -0
- {abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_workspace_policy_tool_calls_persist_across_restart.py +0 -0
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.11] - 2026-05-13
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- AbstractCore effect-handler media materialization now preserves artifact `content_type`, media `type`, artifact ids, and safe filename extensions instead of dropping artifact-backed media to bare paths. This keeps generated WAV artifacts valid for downstream transcription nodes.
|
|
14
|
+
- Added explicit MIME extension aliases for common generated media types such as `audio/wav`, `image/png`, and `video/mp4` so platform MIME table differences do not create extensionless temp files.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Minimum AbstractCore optional dependency floor is now `abstractcore>=2.13.14`.
|
|
18
|
+
|
|
19
|
+
|
|
10
20
|
## [0.4.10] - 2026-05-12
|
|
11
21
|
|
|
12
22
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: AbstractRuntime
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.11
|
|
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
|
|
@@ -23,23 +23,23 @@ Requires-Python: >=3.10
|
|
|
23
23
|
Requires-Dist: abstractmemory>=0.2.6
|
|
24
24
|
Requires-Dist: abstractsemantics>=0.0.3
|
|
25
25
|
Provides-Extra: abstractcore
|
|
26
|
-
Requires-Dist: abstractcore>=2.13.
|
|
26
|
+
Requires-Dist: abstractcore>=2.13.14; extra == 'abstractcore'
|
|
27
27
|
Provides-Extra: all-apple
|
|
28
|
-
Requires-Dist: abstractcore[all-apple]>=2.13.
|
|
28
|
+
Requires-Dist: abstractcore[all-apple]>=2.13.14; extra == 'all-apple'
|
|
29
29
|
Provides-Extra: all-gpu
|
|
30
|
-
Requires-Dist: abstractcore[all-gpu]>=2.13.
|
|
30
|
+
Requires-Dist: abstractcore[all-gpu]>=2.13.14; extra == 'all-gpu'
|
|
31
31
|
Provides-Extra: apple
|
|
32
|
-
Requires-Dist: abstractcore[apple]>=2.13.
|
|
32
|
+
Requires-Dist: abstractcore[apple]>=2.13.14; extra == 'apple'
|
|
33
33
|
Provides-Extra: docs
|
|
34
34
|
Requires-Dist: mkdocs-material>=9.0.0; extra == 'docs'
|
|
35
35
|
Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
|
|
36
36
|
Requires-Dist: pymdown-extensions>=10.0; extra == 'docs'
|
|
37
37
|
Provides-Extra: gpu
|
|
38
|
-
Requires-Dist: abstractcore[gpu]>=2.13.
|
|
38
|
+
Requires-Dist: abstractcore[gpu]>=2.13.14; extra == 'gpu'
|
|
39
39
|
Provides-Extra: mcp-worker
|
|
40
|
-
Requires-Dist: abstractcore[tools]>=2.13.
|
|
40
|
+
Requires-Dist: abstractcore[tools]>=2.13.14; extra == 'mcp-worker'
|
|
41
41
|
Provides-Extra: multimodal
|
|
42
|
-
Requires-Dist: abstractcore[audio,media,openai,vision,voice]>=2.13.
|
|
42
|
+
Requires-Dist: abstractcore[audio,media,openai,vision,voice]>=2.13.14; extra == 'multimodal'
|
|
43
43
|
Provides-Extra: test
|
|
44
44
|
Requires-Dist: pytest>=7.0.0; extra == 'test'
|
|
45
45
|
Description-Content-Type: text/markdown
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "AbstractRuntime"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.11"
|
|
8
8
|
description = "AbstractRuntime: a durable graph runner designed to pair with AbstractCore."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -46,34 +46,34 @@ dependencies = [
|
|
|
46
46
|
[project.optional-dependencies]
|
|
47
47
|
# Enables `abstractruntime.integrations.abstractcore.*` imports.
|
|
48
48
|
abstractcore = [
|
|
49
|
-
"abstractcore>=2.13.
|
|
49
|
+
"abstractcore>=2.13.14",
|
|
50
50
|
]
|
|
51
51
|
|
|
52
52
|
apple = [
|
|
53
|
-
"abstractcore[apple]>=2.13.
|
|
53
|
+
"abstractcore[apple]>=2.13.14",
|
|
54
54
|
]
|
|
55
55
|
|
|
56
56
|
gpu = [
|
|
57
|
-
"abstractcore[gpu]>=2.13.
|
|
57
|
+
"abstractcore[gpu]>=2.13.14",
|
|
58
58
|
]
|
|
59
59
|
|
|
60
60
|
all-apple = [
|
|
61
|
-
"abstractcore[all-apple]>=2.13.
|
|
61
|
+
"abstractcore[all-apple]>=2.13.14",
|
|
62
62
|
]
|
|
63
63
|
|
|
64
64
|
all-gpu = [
|
|
65
|
-
"abstractcore[all-gpu]>=2.13.
|
|
65
|
+
"abstractcore[all-gpu]>=2.13.14",
|
|
66
66
|
]
|
|
67
67
|
|
|
68
68
|
# Enables AbstractCore multimodal generation helpers with common OpenAI-backed
|
|
69
69
|
# image/voice capability packages.
|
|
70
70
|
multimodal = [
|
|
71
|
-
"abstractcore[media,openai,vision,voice,audio]>=2.13.
|
|
71
|
+
"abstractcore[media,openai,vision,voice,audio]>=2.13.14",
|
|
72
72
|
]
|
|
73
73
|
|
|
74
74
|
# Enables `abstractruntime-mcp-worker` with the default toolsets (includes bs4/lxml).
|
|
75
75
|
mcp-worker = [
|
|
76
|
-
"abstractcore[tools]>=2.13.
|
|
76
|
+
"abstractcore[tools]>=2.13.14",
|
|
77
77
|
]
|
|
78
78
|
|
|
79
79
|
# CI/test dependencies. The workflow runs the basic contract suite plus focused
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
### Fixed
|
|
2
|
+
- AbstractCore effect-handler media materialization now preserves artifact `content_type`, media `type`, artifact ids, and safe filename extensions instead of dropping artifact-backed media to bare paths. This keeps generated WAV artifacts valid for downstream transcription nodes.
|
|
3
|
+
- Added explicit MIME extension aliases for common generated media types such as `audio/wav`, `image/png`, and `video/mp4` so platform MIME table differences do not create extensionless temp files.
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Minimum AbstractCore optional dependency floor is now `abstractcore>=2.13.14`.
|
|
@@ -63,6 +63,23 @@ def _guess_ext_from_content_type(content_type: str) -> str:
|
|
|
63
63
|
ct = str(content_type or "").strip().lower()
|
|
64
64
|
if not ct:
|
|
65
65
|
return ""
|
|
66
|
+
explicit = {
|
|
67
|
+
"audio/wav": ".wav",
|
|
68
|
+
"audio/wave": ".wav",
|
|
69
|
+
"audio/x-wav": ".wav",
|
|
70
|
+
"audio/mpeg": ".mp3",
|
|
71
|
+
"audio/mp3": ".mp3",
|
|
72
|
+
"audio/ogg": ".ogg",
|
|
73
|
+
"audio/flac": ".flac",
|
|
74
|
+
"image/jpeg": ".jpg",
|
|
75
|
+
"image/jpg": ".jpg",
|
|
76
|
+
"image/png": ".png",
|
|
77
|
+
"image/webp": ".webp",
|
|
78
|
+
"video/mp4": ".mp4",
|
|
79
|
+
"video/quicktime": ".mov",
|
|
80
|
+
}
|
|
81
|
+
if ct in explicit:
|
|
82
|
+
return explicit[ct]
|
|
66
83
|
ext = mimetypes.guess_extension(ct) or ""
|
|
67
84
|
if ext == ".jpe":
|
|
68
85
|
return ".jpg"
|
|
@@ -679,9 +696,21 @@ def _resolve_llm_call_media(
|
|
|
679
696
|
raw_name = source_path or item.get("filename") or item.get("name")
|
|
680
697
|
if isinstance(raw_name, str) and raw_name.strip():
|
|
681
698
|
filename = raw_name.strip()
|
|
699
|
+
content_type = ""
|
|
700
|
+
if isinstance(item, dict):
|
|
701
|
+
for key in ("content_type", "mime_type", "mimeType", "mime"):
|
|
702
|
+
raw_ct = item.get(key)
|
|
703
|
+
if isinstance(raw_ct, str) and raw_ct.strip():
|
|
704
|
+
content_type = raw_ct.strip()
|
|
705
|
+
break
|
|
706
|
+
if not content_type:
|
|
707
|
+
raw_artifact_ct = getattr(artifact, "content_type", None)
|
|
708
|
+
if isinstance(raw_artifact_ct, str) and raw_artifact_ct.strip():
|
|
709
|
+
content_type = raw_artifact_ct.strip()
|
|
710
|
+
|
|
682
711
|
ext = Path(filename).suffix if filename else ""
|
|
683
712
|
if not ext:
|
|
684
|
-
ct = str(getattr(getattr(artifact, "metadata", None), "content_type", "") or "")
|
|
713
|
+
ct = content_type or str(getattr(getattr(artifact, "metadata", None), "content_type", "") or "")
|
|
685
714
|
ext = _guess_ext_from_content_type(ct)
|
|
686
715
|
|
|
687
716
|
desired = source_path or filename or artifact_id
|
|
@@ -691,7 +720,19 @@ def _resolve_llm_call_media(
|
|
|
691
720
|
p.write_bytes(bytes(content))
|
|
692
721
|
except Exception as e:
|
|
693
722
|
return None, f"Failed to materialize artifact '{artifact_id}': {e}"
|
|
694
|
-
|
|
723
|
+
resolved: Dict[str, Any] = {"file_path": str(p), "$artifact": str(artifact_id), "artifact_id": str(artifact_id)}
|
|
724
|
+
if content_type:
|
|
725
|
+
resolved["content_type"] = content_type
|
|
726
|
+
base_type = content_type.split(";", 1)[0].strip().lower()
|
|
727
|
+
if base_type.startswith("audio/"):
|
|
728
|
+
resolved["type"] = "audio"
|
|
729
|
+
elif base_type.startswith("image/"):
|
|
730
|
+
resolved["type"] = "image"
|
|
731
|
+
elif base_type.startswith("video/"):
|
|
732
|
+
resolved["type"] = "video"
|
|
733
|
+
elif base_type.startswith("text/"):
|
|
734
|
+
resolved["type"] = "text"
|
|
735
|
+
out.append(resolved)
|
|
695
736
|
|
|
696
737
|
return (out or None), None
|
|
697
738
|
|
|
@@ -842,8 +842,24 @@ def _resolve_media_artifacts(
|
|
|
842
842
|
file_path = ""
|
|
843
843
|
|
|
844
844
|
if file_path:
|
|
845
|
-
#
|
|
846
|
-
|
|
845
|
+
# Preserve content type alongside the resolved path. Artifact stores
|
|
846
|
+
# often use extensionless content paths, so a raw path can lose the
|
|
847
|
+
# modality and make downstream transcription reject valid audio.
|
|
848
|
+
resolved: Dict[str, Any] = {"file_path": str(file_path)}
|
|
849
|
+
if content_type:
|
|
850
|
+
resolved["content_type"] = str(content_type)
|
|
851
|
+
base_type = str(content_type).split(";", 1)[0].strip().lower()
|
|
852
|
+
if base_type.startswith("audio/"):
|
|
853
|
+
resolved["type"] = "audio"
|
|
854
|
+
elif base_type.startswith("image/"):
|
|
855
|
+
resolved["type"] = "image"
|
|
856
|
+
elif base_type.startswith("video/"):
|
|
857
|
+
resolved["type"] = "video"
|
|
858
|
+
elif base_type.startswith("text/"):
|
|
859
|
+
resolved["type"] = "text"
|
|
860
|
+
resolved["artifact_id"] = str(aid)
|
|
861
|
+
resolved["$artifact"] = str(aid)
|
|
862
|
+
out.append(resolved)
|
|
847
863
|
continue
|
|
848
864
|
|
|
849
865
|
raise ValueError(f"Unable to resolve artifact '{aid}' to provider-ready media content.")
|
|
@@ -1580,8 +1580,8 @@ def visual_to_flow(visual: VisualFlow) -> Flow:
|
|
|
1580
1580
|
output_spec["extra"] = dict(extra)
|
|
1581
1581
|
image_provider = _nonempty_str(_input_or_config(payload, config, "image_provider", "imageProvider"))
|
|
1582
1582
|
image_model = _nonempty_str(_input_or_config(payload, config, "image_model", "imageModel"))
|
|
1583
|
-
legacy_provider = _nonempty_str(
|
|
1584
|
-
legacy_model = _nonempty_str(
|
|
1583
|
+
legacy_provider = _nonempty_str(config.get("provider"))
|
|
1584
|
+
legacy_model = _nonempty_str(config.get("model"))
|
|
1585
1585
|
runtime_provider = _nonempty_str(
|
|
1586
1586
|
_input_or_config(payload, config, "runtime_provider", "runtimeProvider", "llm_provider", "llmProvider")
|
|
1587
1587
|
)
|
|
@@ -1622,8 +1622,12 @@ def visual_to_flow(visual: VisualFlow) -> Flow:
|
|
|
1622
1622
|
value = _input_or_config(payload, config, key)
|
|
1623
1623
|
if isinstance(value, str) and value.strip():
|
|
1624
1624
|
output_spec[key] = value.strip()
|
|
1625
|
-
tts_provider = _nonempty_str(_input_or_config(payload, config, "tts_provider", "ttsProvider"
|
|
1626
|
-
tts_model = _nonempty_str(_input_or_config(payload, config, "tts_model", "ttsModel"
|
|
1625
|
+
tts_provider = _nonempty_str(_input_or_config(payload, config, "tts_provider", "ttsProvider"))
|
|
1626
|
+
tts_model = _nonempty_str(_input_or_config(payload, config, "tts_model", "ttsModel"))
|
|
1627
|
+
if not tts_provider:
|
|
1628
|
+
tts_provider = _nonempty_str(config.get("provider"))
|
|
1629
|
+
if not tts_model:
|
|
1630
|
+
tts_model = _nonempty_str(config.get("model"))
|
|
1627
1631
|
runtime_provider = _nonempty_str(
|
|
1628
1632
|
_input_or_config(payload, config, "runtime_provider", "runtimeProvider", "llm_provider", "llmProvider")
|
|
1629
1633
|
)
|
|
@@ -1665,8 +1669,12 @@ def visual_to_flow(visual: VisualFlow) -> Flow:
|
|
|
1665
1669
|
value = _input_or_config(payload, config, key)
|
|
1666
1670
|
if isinstance(value, str) and value.strip():
|
|
1667
1671
|
output_spec[key] = value.strip()
|
|
1668
|
-
stt_provider = _nonempty_str(_input_or_config(payload, config, "stt_provider", "sttProvider"
|
|
1669
|
-
stt_model = _nonempty_str(_input_or_config(payload, config, "stt_model", "sttModel"
|
|
1672
|
+
stt_provider = _nonempty_str(_input_or_config(payload, config, "stt_provider", "sttProvider"))
|
|
1673
|
+
stt_model = _nonempty_str(_input_or_config(payload, config, "stt_model", "sttModel"))
|
|
1674
|
+
if not stt_provider:
|
|
1675
|
+
stt_provider = _nonempty_str(config.get("provider"))
|
|
1676
|
+
if not stt_model:
|
|
1677
|
+
stt_model = _nonempty_str(config.get("model"))
|
|
1670
1678
|
runtime_provider = _nonempty_str(
|
|
1671
1679
|
_input_or_config(payload, config, "runtime_provider", "runtimeProvider", "llm_provider", "llmProvider")
|
|
1672
1680
|
)
|
|
@@ -1709,6 +1717,9 @@ def visual_to_flow(visual: VisualFlow) -> Flow:
|
|
|
1709
1717
|
language = _input_or_config(payload, config, "language")
|
|
1710
1718
|
if isinstance(language, str) and language.strip():
|
|
1711
1719
|
details["language"] = language.strip()
|
|
1720
|
+
stt_model = _nonempty_str(_input_or_config(payload, config, "stt_model", "sttModel", "model"))
|
|
1721
|
+
if stt_model:
|
|
1722
|
+
details["model"] = stt_model
|
|
1712
1723
|
max_duration_s = _coerce_float(_input_or_config(payload, config, "max_duration_s", "maxDurationS"))
|
|
1713
1724
|
if max_duration_s is not None:
|
|
1714
1725
|
details["max_duration_s"] = max_duration_s
|
|
@@ -21,6 +21,11 @@ def test_resolve_media_artifact_creates_file_path() -> None:
|
|
|
21
21
|
assert isinstance(resolved, list)
|
|
22
22
|
assert resolved
|
|
23
23
|
item = resolved[0]
|
|
24
|
-
assert isinstance(item,
|
|
25
|
-
assert
|
|
26
|
-
|
|
24
|
+
assert isinstance(item, dict)
|
|
25
|
+
assert item.get("$artifact") == meta.artifact_id
|
|
26
|
+
assert item.get("artifact_id") == meta.artifact_id
|
|
27
|
+
assert item.get("content_type") == "image/png"
|
|
28
|
+
assert item.get("type") == "image"
|
|
29
|
+
path = str(item.get("file_path") or "")
|
|
30
|
+
assert os.path.exists(path)
|
|
31
|
+
os.remove(path)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_resolved_audio_artifact_preserves_content_type_for_transcription(tmp_path: Path) -> None:
|
|
7
|
+
from abstractcore.providers.base import BaseProvider
|
|
8
|
+
from abstractruntime.integrations.abstractcore.llm_client import _is_audio_media_item, _resolve_media_artifacts
|
|
9
|
+
|
|
10
|
+
content_path = tmp_path / "artifact-content-without-extension"
|
|
11
|
+
content_path.write_bytes(b"RIFF\x00\x00\x00\x00WAVE")
|
|
12
|
+
|
|
13
|
+
class Store:
|
|
14
|
+
def _content_path(self, artifact_id: str) -> Path:
|
|
15
|
+
assert artifact_id == "audio-1"
|
|
16
|
+
return content_path
|
|
17
|
+
|
|
18
|
+
resolved = _resolve_media_artifacts(
|
|
19
|
+
[{"$artifact": "audio-1", "content_type": "audio/wav"}],
|
|
20
|
+
artifact_store=Store(),
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
assert isinstance(resolved, list)
|
|
24
|
+
assert resolved == [
|
|
25
|
+
{
|
|
26
|
+
"$artifact": "audio-1",
|
|
27
|
+
"artifact_id": "audio-1",
|
|
28
|
+
"content_type": "audio/wav",
|
|
29
|
+
"file_path": str(content_path),
|
|
30
|
+
"type": "audio",
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
assert _is_audio_media_item(resolved[0]) is True
|
|
34
|
+
assert BaseProvider._media_type(resolved[0]) == "audio"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_effect_handler_materialized_audio_artifact_preserves_content_type(tmp_path: Path) -> None:
|
|
38
|
+
from abstractcore.providers.base import BaseProvider
|
|
39
|
+
from abstractruntime.integrations.abstractcore.effect_handlers import _resolve_llm_call_media
|
|
40
|
+
|
|
41
|
+
class Artifact:
|
|
42
|
+
content = b"RIFF\x00\x00\x00\x00WAVE"
|
|
43
|
+
content_type = None
|
|
44
|
+
metadata = None
|
|
45
|
+
|
|
46
|
+
class Store:
|
|
47
|
+
def load(self, artifact_id: str) -> Artifact:
|
|
48
|
+
assert artifact_id == "audio-1"
|
|
49
|
+
return Artifact()
|
|
50
|
+
|
|
51
|
+
resolved, error = _resolve_llm_call_media(
|
|
52
|
+
[{"$artifact": "audio-1", "content_type": "audio/wav"}],
|
|
53
|
+
artifact_store=Store(),
|
|
54
|
+
temp_dir=tmp_path,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
assert error is None
|
|
58
|
+
assert isinstance(resolved, list)
|
|
59
|
+
assert len(resolved) == 1
|
|
60
|
+
item = resolved[0]
|
|
61
|
+
assert item["$artifact"] == "audio-1"
|
|
62
|
+
assert item["artifact_id"] == "audio-1"
|
|
63
|
+
assert item["content_type"] == "audio/wav"
|
|
64
|
+
assert item["type"] == "audio"
|
|
65
|
+
assert Path(item["file_path"]).suffix == ".wav"
|
|
66
|
+
assert BaseProvider._media_type(item) == "audio"
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/tests/test_multimodal_abstractcore_integration.py
RENAMED
|
@@ -205,7 +205,14 @@ def test_llm_call_allows_media_only_transcription_output_and_augments_output_spe
|
|
|
205
205
|
|
|
206
206
|
assert state.output["llm"]["content"] == "transcribed text"
|
|
207
207
|
assert seen["prompt"] == ""
|
|
208
|
-
assert isinstance(seen["media"], list)
|
|
208
|
+
assert isinstance(seen["media"], list)
|
|
209
|
+
media_item = seen["media"][0]
|
|
210
|
+
assert isinstance(media_item, dict)
|
|
211
|
+
assert media_item.get("$artifact") == meta.artifact_id
|
|
212
|
+
assert media_item.get("artifact_id") == meta.artifact_id
|
|
213
|
+
assert media_item.get("content_type") == "audio/wav"
|
|
214
|
+
assert media_item.get("type") == "audio"
|
|
215
|
+
assert str(media_item.get("file_path") or "").endswith(".wav")
|
|
209
216
|
output = seen["params"]["output"]
|
|
210
217
|
assert output["modality"] == "text"
|
|
211
218
|
assert output["run_id"] == run_id
|
|
@@ -434,7 +434,15 @@ def test_tool_calls_open_attachment_binary_enqueues_pending_media_and_llm_call_c
|
|
|
434
434
|
# Validate that the resolved media file exists during the call.
|
|
435
435
|
media = kwargs.get("media")
|
|
436
436
|
assert isinstance(media, list) and len(media) == 1
|
|
437
|
-
|
|
437
|
+
item = media[0]
|
|
438
|
+
if isinstance(item, dict):
|
|
439
|
+
assert item.get("$artifact") == meta.artifact_id
|
|
440
|
+
assert item.get("artifact_id") == meta.artifact_id
|
|
441
|
+
assert item.get("content_type") == "image/jpeg"
|
|
442
|
+
assert item.get("type") == "image"
|
|
443
|
+
p = Path(str(item.get("file_path") or ""))
|
|
444
|
+
else:
|
|
445
|
+
p = Path(str(item))
|
|
438
446
|
assert p.exists()
|
|
439
447
|
assert p.read_bytes() == content
|
|
440
448
|
return {"content": "ok", "metadata": {}}
|
|
@@ -4,7 +4,7 @@ from abstractruntime.core.models import EffectType, RunState, RunStatus
|
|
|
4
4
|
from abstractruntime.visualflow_compiler import compile_visualflow
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def _plan_for_node(node_type: str, effect_config: dict) -> object:
|
|
7
|
+
def _plan_for_node(node_type: str, effect_config: dict, input_data: dict | None = None) -> object:
|
|
8
8
|
spec = compile_visualflow(
|
|
9
9
|
{
|
|
10
10
|
"id": f"vf_{node_type}",
|
|
@@ -27,7 +27,7 @@ def _plan_for_node(node_type: str, effect_config: dict) -> object:
|
|
|
27
27
|
current_node="node",
|
|
28
28
|
vars={"_temp": {}},
|
|
29
29
|
)
|
|
30
|
-
return spec.nodes["node"](run,
|
|
30
|
+
return spec.nodes["node"](run, input_data)
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
def test_generate_image_node_compiles_to_llm_call_output_selector() -> None:
|
|
@@ -82,6 +82,20 @@ def test_generate_image_legacy_provider_model_stay_in_output_spec() -> None:
|
|
|
82
82
|
assert output["model"] == "flux-test"
|
|
83
83
|
|
|
84
84
|
|
|
85
|
+
def test_generate_image_does_not_treat_runtime_provider_input_as_image_provider() -> None:
|
|
86
|
+
plan = _plan_for_node(
|
|
87
|
+
"generate_image",
|
|
88
|
+
{"prompt": "a horse", "image_model": "gpt-image-1-mini"},
|
|
89
|
+
{"provider": "lmstudio", "model": "chat-model"},
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
assert plan.effect is not None
|
|
93
|
+
payload = dict(plan.effect.payload or {})
|
|
94
|
+
output = dict(payload.get("output") or {})
|
|
95
|
+
assert "provider" not in output
|
|
96
|
+
assert output["model"] == "gpt-image-1-mini"
|
|
97
|
+
|
|
98
|
+
|
|
85
99
|
def test_generate_voice_node_compiles_to_llm_call_tts_selector() -> None:
|
|
86
100
|
plan = _plan_for_node(
|
|
87
101
|
"generate_voice",
|
|
@@ -143,6 +157,7 @@ def test_listen_voice_node_compiles_to_voice_wait_event() -> None:
|
|
|
143
157
|
"prompt": "Say your answer",
|
|
144
158
|
"wait_key": "voice_answer",
|
|
145
159
|
"language": "fr",
|
|
160
|
+
"stt_model": "whisper-test",
|
|
146
161
|
"max_duration_s": 12,
|
|
147
162
|
},
|
|
148
163
|
)
|
|
@@ -156,4 +171,5 @@ def test_listen_voice_node_compiles_to_voice_wait_event() -> None:
|
|
|
156
171
|
assert payload["allow_free_text"] is True
|
|
157
172
|
assert details["input_mode"] == "voice"
|
|
158
173
|
assert details["language"] == "fr"
|
|
174
|
+
assert details["model"] == "whisper-test"
|
|
159
175
|
assert details["max_duration_s"] == 12.0
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
### Fixed
|
|
2
|
-
- Generated media VisualFlow nodes now keep media model selection in the output spec and reserve LLM `provider`/`model` routing for explicit `runtime_provider`/`runtime_model` overrides.
|
|
3
|
-
- Legacy `provider`/`model` pins on image, TTS, and STT media nodes remain accepted as media selector fallbacks for existing flows.
|
|
4
|
-
|
|
5
|
-
### Changed
|
|
6
|
-
- Minimum AbstractCore optional dependency floor is now `abstractcore>=2.13.13` so generated media and audio catalog contracts stay aligned.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/001_runtime_kernel.md
RENAMED
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/003_wait_primitives.md
RENAMED
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/004_scheduler_driver.md
RENAMED
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/006_snapshots_bookmarks.md
RENAMED
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/009_artifact_store.md
RENAMED
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/completed/011_subworkflow_support.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/001_runtime_kernel.md
RENAMED
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/002_snapshots_bookmarks.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/005_docs_updates.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/deprecated/DEPRECATED_README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abstractruntime-0.4.10 → abstractruntime-0.4.11}/docs/backlog/planned/008_signatures_and_keys.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|