AbstractRuntime 0.4.18__tar.gz → 0.4.19__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.
Files changed (326) hide show
  1. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/CHANGELOG.md +13 -1
  2. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/PKG-INFO +4 -4
  3. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/README.md +3 -3
  4. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/api.md +2 -1
  5. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/architecture.md +1 -1
  6. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/faq.md +4 -0
  7. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/integrations/abstractcore.md +8 -0
  8. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/tools-comms.md +1 -1
  9. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/llms-full.txt +2 -2
  10. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/llms.txt +2 -2
  11. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/pyproject.toml +1 -1
  12. abstractruntime-0.4.19/release-notes.md +8 -0
  13. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/__init__.py +12 -1
  14. abstractruntime-0.4.19/src/abstractruntime/integrations/abstractcore/comms_facade.py +127 -0
  15. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/host_facade.py +4 -5
  16. abstractruntime-0.4.19/tests/test_abstractcore_comms_facade.py +179 -0
  17. abstractruntime-0.4.18/release-notes.md +0 -14
  18. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/.github/workflows/ci.yml +0 -0
  19. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/.github/workflows/release.yml +0 -0
  20. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/.gitignore +0 -0
  21. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/ACKNOWLEDGMENTS.md +0 -0
  22. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/CONTRIBUTING.md +0 -0
  23. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/LICENSE +0 -0
  24. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/ROADMAP.md +0 -0
  25. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/SECURITY.md +0 -0
  26. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/README.md +0 -0
  27. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/adr/0001_layered_coupling_with_abstractcore.md +0 -0
  28. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/adr/0002_execution_modes_local_remote_hybrid.md +0 -0
  29. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/adr/0003_provenance_tamper_evident_hash_chain.md +0 -0
  30. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/adr/0004_runtime_owns_run_scoped_media_execution_truth.md +0 -0
  31. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/adr/0005_runtime_owns_abstractcore_host_discovery_queries.md +0 -0
  32. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/adr/0006_runtime_owns_durable_abstractcore_bloc_prompt_cache.md +0 -0
  33. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/adr/README.md +0 -0
  34. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/README.md +0 -0
  35. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/001_runtime_kernel.md +0 -0
  36. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/002_persistence_and_ledger.md +0 -0
  37. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/0030_runtime_host_facades_for_comms_telegram_and_tool_specs.md +0 -0
  38. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/0032_runtime_durable_outbound_comms_truth.md +0 -0
  39. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/003_wait_primitives.md +0 -0
  40. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/004_scheduler_driver.md +0 -0
  41. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/005_abstractcore_integration.md +0 -0
  42. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/006_snapshots_bookmarks.md +0 -0
  43. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/007_provenance_hash_chain.md +0 -0
  44. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/009_artifact_store.md +0 -0
  45. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/010_examples_and_composition.md +0 -0
  46. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/011_subworkflow_support.md +0 -0
  47. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/012_run_store_query_and_scheduler_support.md +0 -0
  48. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/013_effect_retries_and_idempotency.md +0 -0
  49. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/016_runtime_aware_parameters.md +0 -0
  50. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/019_runtime_host_facade_for_core_operator_surfaces.md +0 -0
  51. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/020_runtime_gateway_install_boundary.md +0 -0
  52. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/021_runtime_gateway_env_namespace_cleanup.md +0 -0
  53. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/022_model_residency_control_plane.md +0 -0
  54. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/023_truthful_local_media_residency_boundaries.md +0 -0
  55. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/024_runtime_owned_run_scoped_media_execution.md +0 -0
  56. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/026_runtime_host_discovery_facade_for_core_catalogs.md +0 -0
  57. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/027_runtime_durable_bloc_prompt_cache_facade.md +0 -0
  58. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/028_runtime_bloc_kv_lifecycle_and_pruning.md +0 -0
  59. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/completed/029_runtime_music_generation_and_discovery_via_abstractcore.md +0 -0
  60. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/001_integrations_abstractcore.md +0 -0
  61. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/001_runtime_kernel.md +0 -0
  62. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/002_persistence_and_ledger.md +0 -0
  63. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/002_snapshots_bookmarks.md +0 -0
  64. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/003_provenance_ledger_chain.md +0 -0
  65. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/003_wait_resume_and_scheduler.md +0 -0
  66. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/004_effect_handlers_and_integrations.md +0 -0
  67. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/004_tests.md +0 -0
  68. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/005_docs_updates.md +0 -0
  69. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/005_examples_and_composition.md +0 -0
  70. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/006_ai_fingerprint_and_provenance.md +0 -0
  71. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/DEPRECATED_README.md +0 -0
  72. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/README.md +0 -0
  73. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/deprecated/abstractruntime_docs_final_02a7373b.plan.md +0 -0
  74. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/planned/008_signatures_and_keys.md +0 -0
  75. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/planned/014_remote_tool_worker_executor.md +0 -0
  76. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/planned/017_limit_warnings_and_observability.md +0 -0
  77. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/planned/018_workspace_access_policy_for_media_and_tools.md +0 -0
  78. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/planned/025_runtime_retention_and_purge_contract.md +0 -0
  79. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/proposed/0031_runtime_tool_spec_adapters_for_gateway_and_mcp.md +0 -0
  80. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/proposed/2026-05-20_agent_runtime_convenience_constructor.md +0 -0
  81. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/backlog/proposed/2026-05-20_runtime_local_admin_prompt_cache_save_load.md +0 -0
  82. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/evidence.md +0 -0
  83. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/getting-started.md +0 -0
  84. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/limits.md +0 -0
  85. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/manual_testing.md +0 -0
  86. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/mcp-worker.md +0 -0
  87. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/proposal.md +0 -0
  88. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/provenance.md +0 -0
  89. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/snapshots.md +0 -0
  90. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/docs/workflow-bundles.md +0 -0
  91. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/emails.config.example.yaml +0 -0
  92. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/examples/01_hello_world.py +0 -0
  93. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/examples/02_ask_user.py +0 -0
  94. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/examples/03_wait_until.py +0 -0
  95. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/examples/04_multi_step.py +0 -0
  96. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/examples/05_persistence.py +0 -0
  97. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/examples/06_llm_integration.py +0 -0
  98. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/examples/07_react_agent.py +0 -0
  99. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/examples/README.md +0 -0
  100. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/mkdocs.yml +0 -0
  101. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/pytest.ini +0 -0
  102. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/__init__.py +0 -0
  103. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/core/__init__.py +0 -0
  104. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/core/config.py +0 -0
  105. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/core/event_keys.py +0 -0
  106. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/core/models.py +0 -0
  107. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/core/policy.py +0 -0
  108. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/core/runtime.py +0 -0
  109. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/core/spec.py +0 -0
  110. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/core/vars.py +0 -0
  111. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/evidence/__init__.py +0 -0
  112. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/evidence/recorder.py +0 -0
  113. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/history_bundle.py +0 -0
  114. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/identity/__init__.py +0 -0
  115. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/identity/fingerprint.py +0 -0
  116. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/__init__.py +0 -0
  117. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/constants.py +0 -0
  118. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/default_tools.py +0 -0
  119. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/discovery_facade.py +0 -0
  120. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/discovery_queries.py +0 -0
  121. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/effect_handlers.py +0 -0
  122. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/embeddings_client.py +0 -0
  123. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/factory.py +0 -0
  124. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/llm_client.py +0 -0
  125. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/logging.py +0 -0
  126. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/mcp_worker.py +0 -0
  127. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/media_subprocess.py +0 -0
  128. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/observability.py +0 -0
  129. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/output_specs.py +0 -0
  130. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/run_facade.py +0 -0
  131. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/session_attachments.py +0 -0
  132. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/summarizer.py +0 -0
  133. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/telegram_facade.py +0 -0
  134. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/tool_executor.py +0 -0
  135. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractcore/workspace_scoped_tools.py +0 -0
  136. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractmemory/__init__.py +0 -0
  137. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/integrations/abstractmemory/effect_handlers.py +0 -0
  138. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/memory/__init__.py +0 -0
  139. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/memory/active_context.py +0 -0
  140. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/memory/active_memory.py +0 -0
  141. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/memory/compaction.py +0 -0
  142. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/memory/kg_packets.py +0 -0
  143. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/memory/memact_composer.py +0 -0
  144. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/memory/recall_levels.py +0 -0
  145. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/memory/token_budget.py +0 -0
  146. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/rendering/__init__.py +0 -0
  147. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/rendering/agent_trace_report.py +0 -0
  148. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/rendering/json_stringify.py +0 -0
  149. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/scheduler/__init__.py +0 -0
  150. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/scheduler/convenience.py +0 -0
  151. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/scheduler/registry.py +0 -0
  152. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/scheduler/scheduler.py +0 -0
  153. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/__init__.py +0 -0
  154. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/artifacts.py +0 -0
  155. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/base.py +0 -0
  156. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/commands.py +0 -0
  157. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/in_memory.py +0 -0
  158. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/json_files.py +0 -0
  159. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/ledger_chain.py +0 -0
  160. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/observable.py +0 -0
  161. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/offloading.py +0 -0
  162. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/snapshots.py +0 -0
  163. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/storage/sqlite.py +0 -0
  164. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/__init__.py +0 -0
  165. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/__init__.py +0 -0
  166. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/agent_adapter.py +0 -0
  167. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/context_adapter.py +0 -0
  168. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/control_adapter.py +0 -0
  169. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/effect_adapter.py +0 -0
  170. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/event_adapter.py +0 -0
  171. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/function_adapter.py +0 -0
  172. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/memact_adapter.py +0 -0
  173. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/subflow_adapter.py +0 -0
  174. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/adapters/variable_adapter.py +0 -0
  175. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/compiler.py +0 -0
  176. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/flow.py +0 -0
  177. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/visual/__init__.py +0 -0
  178. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/visual/agent_ids.py +0 -0
  179. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/visual/builtins.py +0 -0
  180. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/visual/code_executor.py +0 -0
  181. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/visual/executor.py +0 -0
  182. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/visual/models.py +0 -0
  183. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/visualflow_compiler/visual/multi_entry_lowering.py +0 -0
  184. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/workflow_bundle/__init__.py +0 -0
  185. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/workflow_bundle/models.py +0 -0
  186. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/workflow_bundle/packer.py +0 -0
  187. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/workflow_bundle/reader.py +0 -0
  188. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/src/abstractruntime/workflow_bundle/registry.py +0 -0
  189. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/README.md +0 -0
  190. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/conftest.py +0 -0
  191. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_abstractcore_discovery_facade.py +0 -0
  192. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_abstractcore_host_facade.py +0 -0
  193. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_abstractcore_run_facade.py +0 -0
  194. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_abstractcore_telegram_facade.py +0 -0
  195. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_active_context_policy.py +0 -0
  196. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_active_memory.py +0 -0
  197. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_answer_user_effect.py +0 -0
  198. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_artifacts.py +0 -0
  199. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_chat_summarizer_integration.py +0 -0
  200. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_command_store.py +0 -0
  201. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_compaction_helpers.py +0 -0
  202. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_control_adapter_while.py +0 -0
  203. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_default_tools_comms_gating.py +0 -0
  204. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_default_tools_include_skim_files.py +0 -0
  205. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_default_tools_include_skim_folders.py +0 -0
  206. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_default_tools_search_files_executor.py +0 -0
  207. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_durable_toolsets.py +0 -0
  208. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_e2e_tool_calls_idempotency_lmstudio.py +0 -0
  209. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_emit_event_without_workflow_registry.py +0 -0
  210. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_evidence_recorder.py +0 -0
  211. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_factory_timeouts_default_to_abstractcore_config.py +0 -0
  212. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_integration_abstractcore.py +0 -0
  213. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_integrations_abstractcore.py +0 -0
  214. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_json_file_run_store_children_index.py +0 -0
  215. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_jsonl_ledger_recovery.py +0 -0
  216. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_kg_learn_and_recall_contract.py +0 -0
  217. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_ledger_chain.py +0 -0
  218. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_ledger_subscription.py +0 -0
  219. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_call_media_artifact_refs.py +0 -0
  220. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_call_media_artifact_refs_persist_across_restart.py +0 -0
  221. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_call_media_uses_source_path_label.py +0 -0
  222. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_call_requires_prompt.py +0 -0
  223. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_call_response_schema_normalization.py +0 -0
  224. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_call_structured_output_fallback.py +0 -0
  225. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_call_truncation_retry_contract.py +0 -0
  226. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_call_use_context_appends_turn.py +0 -0
  227. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_call_verbatim_payload_capture.py +0 -0
  228. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_client_media_artifacts.py +0 -0
  229. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_client_system_context.py +0 -0
  230. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_llm_client_tool_call_parsing.py +0 -0
  231. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_local_runtime_timeout_kwarg_policy.py +0 -0
  232. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_mcp_remote_tool_executor.py +0 -0
  233. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_mcp_worker_logging.py +0 -0
  234. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_mcp_worker_security.py +0 -0
  235. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_mcp_worker_stdio.py +0 -0
  236. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_media_artifact_resolution.py +0 -0
  237. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memact_composer_from_kg_result.py +0 -0
  238. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_kg_assert_attributes_defaults.py +0 -0
  239. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_kg_packets.py +0 -0
  240. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_kg_predicate_aliasing.py +0 -0
  241. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_kg_query_packetization_restart.py +0 -0
  242. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_kg_query_recall_level_policy.py +0 -0
  243. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_kg_semantic_query_ranking.py +0 -0
  244. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_note_effect.py +0 -0
  245. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_query_effect.py +0 -0
  246. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_query_rich_filters.py +0 -0
  247. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_scope_and_rehydrate_effect.py +0 -0
  248. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_memory_tag_effect.py +0 -0
  249. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_mlx_generation_serialization.py +0 -0
  250. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_model_residency_control_plane.py +0 -0
  251. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_multimodal_abstractcore_integration.py +0 -0
  252. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_offloading.py +0 -0
  253. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_packaging_extras.py +0 -0
  254. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_pause_resume.py +0 -0
  255. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_prompt_cache_modules.py +0 -0
  256. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_queryable_run_store.py +0 -0
  257. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_read_file_fallback_to_session_attachments.py +0 -0
  258. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_real_integration.py +0 -0
  259. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_recall_levels_policy.py +0 -0
  260. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_remote_llm_client.py +0 -0
  261. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_rendering_agent_trace_report.py +0 -0
  262. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_rendering_json_stringify.py +0 -0
  263. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_retry_idempotency.py +0 -0
  264. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_run_history_bundle.py +0 -0
  265. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_runtime_config_max_output_tokens_fallback.py +0 -0
  266. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_runtime_install_boundary.py +0 -0
  267. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_runtime_llm_call_grounding_in_ledger.py +0 -0
  268. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_runtime_node_traces.py +0 -0
  269. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_runtime_start_seeds_tool_support.py +0 -0
  270. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_scheduler.py +0 -0
  271. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_session_attachments_registry_and_open_tool.py +0 -0
  272. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_snapshots.py +0 -0
  273. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_sqlite_ledger_store.py +0 -0
  274. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_start_subworkflow_async_wait.py +0 -0
  275. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_start_subworkflow_inherit_context_merges_messages.py +0 -0
  276. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_start_subworkflow_workspace_inheritance.py +0 -0
  277. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_structured_output_schema_enum.py +0 -0
  278. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_subworkflow.py +0 -0
  279. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_terminal_effect_completion.py +0 -0
  280. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_terminal_resume_appends_ledger_completion.py +0 -0
  281. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tick_completion_includes_output_in_ledger.py +0 -0
  282. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_approval_executor.py +0 -0
  283. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_approval_resume_executes.py +0 -0
  284. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_calls_idempotency_keys.py +0 -0
  285. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_executor_argument_sanitization.py +0 -0
  286. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_executor_error_output_detection.py +0 -0
  287. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_executor_filename_alias.py +0 -0
  288. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_executor_kwarg_canonicalization.py +0 -0
  289. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_executor_read_file_aliases.py +0 -0
  290. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_executor_timeout.py +0 -0
  291. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_tool_wait_allowlist_safety.py +0 -0
  292. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_trace_context_propagation.py +0 -0
  293. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_vars_query_effect.py +0 -0
  294. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_agent_output_context_includes_messages.py +0 -0
  295. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_agent_tool_observations_persist_across_restart.py +0 -0
  296. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_agent_use_context_inherits_attachments.py +0 -0
  297. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_agent_use_context_persists_tool_observations.py +0 -0
  298. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_agent_use_context_persists_turn.py +0 -0
  299. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_llm_call_schema_ref_resolution.py +0 -0
  300. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_memact_compose_node.py +0 -0
  301. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_memory_kg_query_outputs_propagate.py +0 -0
  302. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_memory_kg_resolve_outputs_propagate.py +0 -0
  303. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visual_multi_entry_loop_overrides.py +0 -0
  304. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_add_message_builtin.py +0 -0
  305. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_add_message_node_appends_to_active_context.py +0 -0
  306. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_call_tool_node.py +0 -0
  307. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_compiler_basic.py +0 -0
  308. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_context_and_builder_nodes.py +0 -0
  309. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_get_element_node.py +0 -0
  310. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_get_random_element_node.py +0 -0
  311. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_has_tools_builtin.py +0 -0
  312. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_llm_call_context_attachments_map_to_media.py +0 -0
  313. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_llm_call_multimodal_output.py +0 -0
  314. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_make_object_node.py +0 -0
  315. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_media_nodes.py +0 -0
  316. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_memory_effect_nodes.py +0 -0
  317. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_memory_source_pins.py +0 -0
  318. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_prompt_only.py +0 -0
  319. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_random_nodes.py +0 -0
  320. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_string_contains_replace.py +0 -0
  321. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_visualflow_tool_parameters_node.py +0 -0
  322. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_wait_event_prompt_metadata.py +0 -0
  323. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_workflow_bundle_registry.py +0 -0
  324. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_workspace_policy_allowlist_mode.py +0 -0
  325. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_workspace_policy_mount_virtual_paths.py +0 -0
  326. {abstractruntime-0.4.18 → abstractruntime-0.4.19}/tests/test_workspace_policy_tool_calls_persist_across_restart.py +0 -0
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.19] - 2026-05-21
11
+
12
+ ### Added
13
+ - Runtime now ships the missed standalone email comms wrapper/export layer for host-local operator surfaces:
14
+ - `abstractruntime.integrations.abstractcore.comms_facade`
15
+ - package-level email helper exports from `abstractruntime.integrations.abstractcore`
16
+
17
+ ### Changed
18
+ - Host-facade email helpers now delegate through Runtime's own comms facade instead of importing `abstractcore.tools.comms_tools` directly in the facade method body.
19
+ - Runtime docs and AI-readable `llms.txt` / `llms-full.txt` now describe the standalone email comms facade/export layer alongside the existing host facade, Telegram wrappers, and durable run-owned comms sends.
20
+
10
21
  ## [0.4.18] - 2026-05-21
11
22
 
12
23
  ### Added
@@ -478,7 +489,8 @@ AbstractRuntime is the durable execution substrate designed to pair with Abstrac
478
489
 
479
490
  Initial development version with basic proof-of-concept features.
480
491
 
481
- [Unreleased]: https://github.com/lpalbou/abstractruntime/compare/v0.4.18...HEAD
492
+ [Unreleased]: https://github.com/lpalbou/abstractruntime/compare/v0.4.19...HEAD
493
+ [0.4.19]: https://github.com/lpalbou/abstractruntime/compare/v0.4.18...v0.4.19
482
494
  [0.4.18]: https://github.com/lpalbou/abstractruntime/compare/v0.4.17...v0.4.18
483
495
  [0.4.17]: https://github.com/lpalbou/abstractruntime/compare/v0.4.16...v0.4.17
484
496
  [0.4.16]: https://github.com/lpalbou/abstractruntime/compare/v0.4.15...v0.4.16
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AbstractRuntime
3
- Version: 0.4.18
3
+ Version: 0.4.19
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
@@ -81,7 +81,7 @@ Description-Content-Type: text/markdown
81
81
 
82
82
  It is designed for long-running workflows that must survive restarts and explicitly model blocking (human input, timers, external events, subworkflows) without keeping Python stacks alive.
83
83
 
84
- **Version:** 0.4.18 • **Python:** 3.10+
84
+ **Version:** 0.4.19 • **Python:** 3.10+
85
85
 
86
86
  **Status:** pre-1.0 (API may evolve). For production use, pin versions and follow `CHANGELOG.md`.
87
87
 
@@ -169,7 +169,7 @@ state = rt.resume(
169
169
  assert state.status.value == "completed"
170
170
  ```
171
171
 
172
- ## What’s included (v0.4.18)
172
+ ## What’s included (v0.4.19)
173
173
 
174
174
  Kernel (dependency-light):
175
175
  - workflow graphs: `WorkflowSpec` (`src/abstractruntime/core/spec.py`)
@@ -194,7 +194,7 @@ Drivers + distribution:
194
194
 
195
195
  Optional integrations:
196
196
  - AbstractCore (LLM + tools, `MODEL_RESIDENCY`, public discovery/host/run facades, cached sessions, durable bloc prompt-cache controls, bindings, lifecycle operations, generated image/voice/music outputs, host email helpers, Telegram host wrappers, and tool approval waits): `docs/integrations/abstractcore.md`
197
- - For outbound comms, use the durable run facade when the send belongs to a run: `get_abstractcore_run_facade(...).send_email(...)` / `send_telegram_message(...)`. If that child run pauses for approval or passthrough execution, resume it through `resume_tool_calls(...)`. Direct host-facade send helpers remain host-local and nondurable.
197
+ - For outbound comms, use the durable run facade when the send belongs to a run: `get_abstractcore_run_facade(...).send_email(...)` / `send_telegram_message(...)`. If that child run pauses for approval or passthrough execution, resume it through `resume_tool_calls(...)`. Direct host-facade send helpers and the standalone email comms facade remain host-local and nondurable.
198
198
  - AbstractMemory TripleStore integration for `MEMORY_KG_*` effects. Runtime
199
199
  depends on the light AbstractMemory contract; hosts choose storage backends
200
200
  such as LanceDB, SQLite, or in-memory stores.
@@ -4,7 +4,7 @@
4
4
 
5
5
  It is designed for long-running workflows that must survive restarts and explicitly model blocking (human input, timers, external events, subworkflows) without keeping Python stacks alive.
6
6
 
7
- **Version:** 0.4.18 • **Python:** 3.10+
7
+ **Version:** 0.4.19 • **Python:** 3.10+
8
8
 
9
9
  **Status:** pre-1.0 (API may evolve). For production use, pin versions and follow `CHANGELOG.md`.
10
10
 
@@ -92,7 +92,7 @@ state = rt.resume(
92
92
  assert state.status.value == "completed"
93
93
  ```
94
94
 
95
- ## What’s included (v0.4.18)
95
+ ## What’s included (v0.4.19)
96
96
 
97
97
  Kernel (dependency-light):
98
98
  - workflow graphs: `WorkflowSpec` (`src/abstractruntime/core/spec.py`)
@@ -117,7 +117,7 @@ Drivers + distribution:
117
117
 
118
118
  Optional integrations:
119
119
  - AbstractCore (LLM + tools, `MODEL_RESIDENCY`, public discovery/host/run facades, cached sessions, durable bloc prompt-cache controls, bindings, lifecycle operations, generated image/voice/music outputs, host email helpers, Telegram host wrappers, and tool approval waits): `docs/integrations/abstractcore.md`
120
- - For outbound comms, use the durable run facade when the send belongs to a run: `get_abstractcore_run_facade(...).send_email(...)` / `send_telegram_message(...)`. If that child run pauses for approval or passthrough execution, resume it through `resume_tool_calls(...)`. Direct host-facade send helpers remain host-local and nondurable.
120
+ - For outbound comms, use the durable run facade when the send belongs to a run: `get_abstractcore_run_facade(...).send_email(...)` / `send_telegram_message(...)`. If that child run pauses for approval or passthrough execution, resume it through `resume_tool_calls(...)`. Direct host-facade send helpers and the standalone email comms facade remain host-local and nondurable.
121
121
  - AbstractMemory TripleStore integration for `MEMORY_KG_*` effects. Runtime
122
122
  depends on the light AbstractMemory contract; hosts choose storage backends
123
123
  such as LanceDB, SQLite, or in-memory stores.
@@ -184,13 +184,14 @@ Entry points:
184
184
  - `create_local_runtime(...)`, `create_remote_runtime(...)`, `create_hybrid_runtime(...)` (`src/abstractruntime/integrations/abstractcore/factory.py`)
185
185
  - public discovery facade: `AbstractCoreDiscoveryFacade`, `get_abstractcore_discovery_facade(...)` (`src/abstractruntime/integrations/abstractcore/discovery_facade.py`)
186
186
  - public host facade: `AbstractCoreHostFacade`, `get_abstractcore_host_facade(...)` (`src/abstractruntime/integrations/abstractcore/host_facade.py`)
187
+ - public email comms wrappers: `list_email_accounts(...)`, `list_emails(...)`, `read_email(...)`, `send_email(...)` (`src/abstractruntime/integrations/abstractcore/comms_facade.py`)
187
188
  - public Telegram host wrappers: `TelegramTdlibNotAvailable`, `bootstrap_telegram_auth_from_env(...)`, `get_global_telegram_client(...)`, `stop_global_telegram_client()`, `send_telegram_message(...)` (`src/abstractruntime/integrations/abstractcore/telegram_facade.py`)
188
189
  - public durable run facade: `AbstractCoreRunFacade`, `get_abstractcore_run_facade(...)` (`src/abstractruntime/integrations/abstractcore/run_facade.py`)
189
190
  - effect handler wiring: `build_effect_handlers(...)` (`src/abstractruntime/integrations/abstractcore/effect_handlers.py`)
190
191
  - tool executors: `MappingToolExecutor`, `AbstractCoreToolExecutor`, `PassthroughToolExecutor`, `ApprovalToolExecutor`, `ToolApprovalPolicy` (`src/abstractruntime/integrations/abstractcore/tool_executor.py`)
191
192
  - discovery-facade delegation is implemented by the configured AbstractCore LLM clients in `src/abstractruntime/integrations/abstractcore/llm_client.py` (`list_providers`, `list_provider_models`, `get_voice_catalog`, `list_tts_models`, `list_stt_models`, `list_music_providers`, `list_music_models`, `list_vision_provider_models`, `list_cached_vision_models`)
192
193
  - host-facade client delegation is implemented by the configured AbstractCore LLM clients in `src/abstractruntime/integrations/abstractcore/llm_client.py` (`get_prompt_cache_capabilities`, `get_prompt_cache_stats`, `prompt_cache_set`, `prompt_cache_update`, `prompt_cache_fork`, `prompt_cache_clear`, `prompt_cache_prepare_modules`, `upsert_text_bloc`, `get_bloc_record`, `list_blocs`, `get_bloc_kv_manifest`, `ensure_bloc_kv_artifact`, `load_bloc_kv_artifact`, `list_bloc_kv_artifacts`, `delete_bloc_kv_artifact`, `prune_bloc_kv_artifacts`, `delete_bloc`, `list_model_residency`, `load_model_residency`, `unload_model_residency`)
193
- - host-facade email helpers remain host-local wrappers over AbstractCore's public comms helpers (`list_email_accounts`, `list_emails`, `read_email`, `send_email`)
194
+ - host-facade email helpers delegate to Runtime's host-local comms facade/export layer (`list_email_accounts`, `list_emails`, `read_email`, `send_email`)
194
195
  - run-facade helpers create and resume durable child runs for existing runs (`execute_llm_call`, `execute_tool_calls`, `resume_tool_calls`, `generate_image`, `generate_voice`, `generate_music`, `transcribe_audio`, `send_email`, `send_telegram_message`)
195
196
 
196
197
  `LLM_CALL` payloads are JSON-safe effect payloads. Common fields:
@@ -1,7 +1,7 @@
1
1
  # AbstractRuntime — Architecture
2
2
 
3
3
  > Updated: 2026-05-21
4
- > Version: 0.4.18
4
+ > Version: 0.4.19
5
5
  > Scope: this describes **what is implemented in this repository**.
6
6
 
7
7
  AbstractRuntime is a **durable workflow runtime**: it executes workflow graphs as a persisted state machine with explicit waits (user, time, events, jobs, subworkflows). A run can pause for hours/days and resume **without** keeping Python stacks/coroutines alive.
@@ -169,6 +169,10 @@ No. For the remaining host/operator paths, use Runtime's public wrappers instead
169
169
  - `...list_emails(...)`
170
170
  - `...read_email(...)`
171
171
  - `...send_email(...)`
172
+ - `abstractruntime.integrations.abstractcore.list_email_accounts(...)`
173
+ - `...list_emails(...)`
174
+ - `...read_email(...)`
175
+ - `...send_email(...)`
172
176
  - `abstractruntime.integrations.abstractcore.telegram_facade.bootstrap_telegram_auth_from_env(...)`
173
177
  - `...get_global_telegram_client(...)`
174
178
  - `...stop_global_telegram_client()`
@@ -493,6 +493,11 @@ email and Telegram:
493
493
  - `list_emails(...)`
494
494
  - `read_email(...)`
495
495
  - `send_email(...)`
496
+ - `abstractruntime.integrations.abstractcore.comms_facade` also exposes:
497
+ - `list_email_accounts(...)`
498
+ - `list_emails(...)`
499
+ - `read_email(...)`
500
+ - `send_email(...)`
496
501
  - `abstractruntime.integrations.abstractcore.telegram_facade` exposes:
497
502
  - `TelegramTdlibNotAvailable`
498
503
  - `bootstrap_telegram_auth_from_env(...)`
@@ -504,6 +509,9 @@ Contract notes:
504
509
 
505
510
  - These are **host-local** wrappers over current public AbstractCore tool
506
511
  modules. They do not proxy through the remote AbstractCore server.
512
+ - The host facade email methods and the standalone `comms_facade` functions use
513
+ the same Runtime-owned email wrapper layer; choose whichever is more natural
514
+ for the host surface you are building.
507
515
  - They are intentionally **nondurable**. They do not write Runtime run history
508
516
  on their own.
509
517
  - Direct `send_email(...)` on the host facade and direct
@@ -48,7 +48,7 @@ Notes:
48
48
  - In untrusted deployments, prefer passthrough tools so a host/worker boundary approves and executes tool calls (`PassthroughToolExecutor` in `src/abstractruntime/integrations/abstractcore/tool_executor.py`).
49
49
  - For local bridge-owned delivery flows, `ApprovalToolExecutor` can auto-run the Telegram send tools while requiring approval for email, WhatsApp, unknown tools, and write/command-style tools by default.
50
50
  - Separate from the durable `TOOL_CALLS` path, Runtime also exposes **host wrappers** for operator-owned email and Telegram surfaces:
51
- - email helpers on `get_abstractcore_host_facade(runtime)`
51
+ - email helpers on `get_abstractcore_host_facade(runtime)` and `abstractruntime.integrations.abstractcore.comms_facade`
52
52
  - Telegram lifecycle/send wrappers in `abstractruntime.integrations.abstractcore.telegram_facade`
53
53
  - read/bootstrap helpers stay host-local and do not create run history by themselves
54
54
  - if an outbound send belongs to a run, prefer the durable run facade:
@@ -10,7 +10,7 @@ This file is an **agent-oriented build guide** for the AbstractRuntime *library*
10
10
 
11
11
  Quick facts:
12
12
  - Python: 3.10+ (`pyproject.toml`)
13
- - Version: 0.4.18
13
+ - Version: 0.4.19
14
14
  - Ecosystem: [AbstractFramework](https://github.com/lpalbou/AbstractFramework) umbrella; pairs with [AbstractCore](https://github.com/lpalbou/abstractcore)
15
15
  - Public export surface (source of truth): `src/abstractruntime/__init__.py`
16
16
  - Optional AbstractCore baseline: `abstractruntime[abstractcore]` installs `abstractcore>=2.13.24`
@@ -222,7 +222,7 @@ Notes:
222
222
  - Use `ApprovalToolExecutor(delegate=..., policy=ToolApprovalPolicy())` when a local host should auto-run safe tools but pause for user approval before write/command/unknown tools.
223
223
  - Remote `params.api_key` and `params.provider_api_key` are compatibility inputs; runtime converts them to `X-AbstractCore-Provider-API-Key` headers for current AbstractCore servers.
224
224
  - Gateway/hosts choose Core server URLs, Core server auth headers, provider/model defaults, tool executors, artifact stores, and any Gateway env/config translation before Runtime sees the call.
225
- - Hosts should bind `get_abstractcore_host_facade(rt)` for prompt-cache, durable bloc/KV, model-residency, and host-local email helper operations instead of reaching through the private `_abstractcore_llm_client` attachment directly.
225
+ - Hosts should bind `get_abstractcore_host_facade(rt)` for prompt-cache, durable bloc/KV, and model-residency control operations, and use the Runtime-owned email wrapper layer (`get_abstractcore_host_facade(rt)` or `abstractruntime.integrations.abstractcore.comms_facade`) for host-local email helper operations instead of importing `abstractcore.tools.comms_tools` directly.
226
226
  - Hosts should use `abstractruntime.integrations.abstractcore.telegram_facade` for Telegram TDLib bootstrap/global-client/send helpers instead of importing `abstractcore.tools.telegram_tdlib` or `abstractcore.tools.telegram_tools` directly. These wrappers remain host-local and do not proxy through a remote Core server.
227
227
  - If an outbound email or Telegram send belongs to a run, hosts should prefer `get_abstractcore_run_facade(rt).send_email(...)` or `send_telegram_message(...)`. Those are durable `TOOL_CALLS` child runs: Runtime records the request and outcome, and replay should reuse the recorded result instead of resending the message. If the child run waits for approval or passthrough host execution, resume it through the same public boundary with `resume_tool_calls(...)`.
228
228
  - Use `pip install "abstractruntime[multimodal]"` for common AbstractCore media, vision, voice, audio, and music dependencies.
@@ -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.4.18
6
+ - Version: 0.4.19
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: `abstractruntime[abstractcore]` installs `abstractcore>=2.13.24`
@@ -38,7 +38,7 @@
38
38
  - Prompt-cache tracks: use `LLM_CALL.params.prompt_cache_key`, `run.vars["_runtime"]["prompt_cache"]`, or `ABSTRACTRUNTIME_PROMPT_CACHE` for best-effort session reuse; use `LLM_CALL.params.prompt_cache_binding` for durable exact bloc-backed reuse. Local Runtime stores one content-addressed bloc per root plus provider/model-specific derived KV artifacts. Gateway prompt-cache env belongs in Gateway.
39
39
  - Durable bloc lifecycle: Runtime exposes `list_blocs(...)`, `list_bloc_kv_artifacts(...)`, `delete_bloc_kv_artifact(...)`, `prune_bloc_kv_artifacts(...)`, and `delete_bloc(...)`, with `dry_run`, `clear_loaded`, and `force` safety controls on the host facade.
40
40
  - Runtime-owned Core surfaces: `get_abstractcore_discovery_facade(...)`, `get_abstractcore_host_facade(...)`, and `get_abstractcore_run_facade(...)`
41
- - Host-local operator wrappers: the host facade now also wraps email helpers (`list_email_accounts`, `list_emails`, `read_email`, `send_email`), and `abstractruntime.integrations.abstractcore.telegram_facade` exposes Telegram bootstrap/global-client/send wrappers without requiring hosts to import AbstractCore directly.
41
+ - Host-local operator wrappers: the host facade and `abstractruntime.integrations.abstractcore.comms_facade` expose email helpers (`list_email_accounts`, `list_emails`, `read_email`, `send_email`), and `abstractruntime.integrations.abstractcore.telegram_facade` exposes Telegram bootstrap/global-client/send wrappers without requiring hosts to import AbstractCore directly.
42
42
  - Durable outbound comms: when an email or Telegram send belongs to a run, use `get_abstractcore_run_facade(...).send_email(...)` or `send_telegram_message(...)` so Runtime records the request and outcome in a child run; replay should show the recorded result, not resend the message. If the child run waits for approval or passthrough execution, resume it through `resume_tool_calls(...)`.
43
43
  - [Artifacts](docs/api.md#artifacts-store-by-reference): JSON-safe refs for large payloads; generated images/audio/voice/music are stored here rather than embedded in `RunState.vars`
44
44
  - Remote multimodal guardrail: remote/hybrid media generation uses AbstractCore Server endpoints, does not inherit the chat model for media endpoints, rejects unsupported input media and non-file STT inputs instead of ignoring them, and redacts data URLs from persisted provider-request metadata
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "AbstractRuntime"
7
- version = "0.4.18"
7
+ version = "0.4.19"
8
8
  description = "AbstractRuntime: a durable graph runner designed to pair with AbstractCore."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -0,0 +1,8 @@
1
+ ### Added
2
+ - Runtime now ships the missed standalone email comms wrapper/export layer for host-local operator surfaces:
3
+ - `abstractruntime.integrations.abstractcore.comms_facade`
4
+ - package-level email helper exports from `abstractruntime.integrations.abstractcore`
5
+
6
+ ### Changed
7
+ - Host-facade email helpers now delegate through Runtime's own comms facade instead of importing `abstractcore.tools.comms_tools` directly in the facade method body.
8
+ - Runtime docs and AI-readable `llms.txt` / `llms-full.txt` now describe the standalone email comms facade/export layer alongside the existing host facade, Telegram wrappers, and durable run-owned comms sends.
@@ -8,7 +8,8 @@ Provides:
8
8
  - Effect handlers wiring
9
9
  - Convenience runtime factories for local/remote/hybrid modes
10
10
  - Public discovery facade for provider/media/catalog snapshot queries
11
- - Public host facade for prompt-cache, durable bloc/KV, model-residency, and host-local email control operations
11
+ - Public host facade for prompt-cache, durable bloc/KV, and model-residency control operations
12
+ - Public comms facade for host-local email helper operations
12
13
  - Public Telegram host wrappers for TDLib bootstrap/global-client/send parity
13
14
  - Public durable run facade for run-scoped AbstractCore LLM/tool child runs, including outbound comms sends
14
15
  - RuntimeConfig for limits and model capabilities
@@ -29,6 +30,12 @@ from .host_facade import (
29
30
  AbstractCoreHostFacade,
30
31
  get_abstractcore_host_facade,
31
32
  )
33
+ from .comms_facade import (
34
+ list_email_accounts,
35
+ list_emails,
36
+ read_email,
37
+ send_email,
38
+ )
32
39
  from .discovery_facade import (
33
40
  AbstractCoreDiscoveryFacade,
34
41
  get_abstractcore_discovery_facade,
@@ -86,6 +93,9 @@ __all__ = [
86
93
  "bootstrap_telegram_auth_from_env",
87
94
  "get_abstractcore_discovery_facade",
88
95
  "get_abstractcore_host_facade",
96
+ "list_email_accounts",
97
+ "list_emails",
98
+ "read_email",
89
99
  "get_global_telegram_client",
90
100
  "get_abstractcore_run_facade",
91
101
  "create_local_runtime",
@@ -93,6 +103,7 @@ __all__ = [
93
103
  "create_hybrid_runtime",
94
104
  "create_local_file_runtime",
95
105
  "create_remote_file_runtime",
106
+ "send_email",
96
107
  "send_telegram_message",
97
108
  "stop_global_telegram_client",
98
109
  "attach_global_event_bus_bridge",
@@ -0,0 +1,127 @@
1
+ """Runtime-owned email/comms wrapper surface for AbstractCore-backed hosts.
2
+
3
+ Hosts should import this module instead of reaching into
4
+ `abstractcore.tools.comms_tools` directly.
5
+
6
+ Scope:
7
+ - host-local email account listing
8
+ - host-local email inbox listing/reading
9
+ - host-local email sends
10
+
11
+ Non-goals:
12
+ - durable Runtime effect execution
13
+ - run-scoped Runtime history
14
+ - arbitrary browser-supplied SMTP/IMAP credentials
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from typing import Any, Callable, Dict, Optional, Tuple
20
+
21
+
22
+ def _load_comms_helpers() -> Tuple[Callable[..., Dict[str, Any]], Callable[..., Dict[str, Any]], Callable[..., Dict[str, Any]], Callable[..., Dict[str, Any]]]:
23
+ try:
24
+ from abstractcore.tools.comms_tools import list_email_accounts, list_emails, read_email, send_email
25
+ except Exception as exc: # pragma: no cover - exercised through facade behavior tests
26
+ raise RuntimeError(
27
+ "Email helpers are unavailable. Install a Runtime environment with "
28
+ "AbstractCore's comms tools support."
29
+ ) from exc
30
+ return list_email_accounts, list_emails, read_email, send_email
31
+
32
+
33
+ def _dependency_error(exc: Exception) -> Dict[str, Any]:
34
+ return {
35
+ "success": False,
36
+ "code": "dependency_missing",
37
+ "error": str(exc),
38
+ }
39
+
40
+
41
+ def list_email_accounts() -> Dict[str, Any]:
42
+ try:
43
+ helper, _list_emails, _read_email, _send_email = _load_comms_helpers()
44
+ except Exception as exc:
45
+ return _dependency_error(exc)
46
+ return helper()
47
+
48
+
49
+ def list_emails(
50
+ *,
51
+ account: Optional[str] = None,
52
+ mailbox: Optional[str] = None,
53
+ since: Optional[str] = None,
54
+ status: str = "all",
55
+ limit: int = 20,
56
+ timeout_s: float = 30.0,
57
+ ) -> Dict[str, Any]:
58
+ try:
59
+ _list_email_accounts, helper, _read_email, _send_email = _load_comms_helpers()
60
+ except Exception as exc:
61
+ return _dependency_error(exc)
62
+ return helper(
63
+ account=account,
64
+ mailbox=mailbox,
65
+ since=since,
66
+ status=status,
67
+ limit=limit,
68
+ timeout_s=timeout_s,
69
+ )
70
+
71
+
72
+ def read_email(
73
+ *,
74
+ uid: str,
75
+ account: Optional[str] = None,
76
+ mailbox: Optional[str] = None,
77
+ timeout_s: float = 30.0,
78
+ max_body_chars: int = 20000,
79
+ ) -> Dict[str, Any]:
80
+ try:
81
+ _list_email_accounts, _list_emails, helper, _send_email = _load_comms_helpers()
82
+ except Exception as exc:
83
+ return _dependency_error(exc)
84
+ return helper(
85
+ uid=uid,
86
+ account=account,
87
+ mailbox=mailbox,
88
+ timeout_s=timeout_s,
89
+ max_body_chars=max_body_chars,
90
+ )
91
+
92
+
93
+ def send_email(
94
+ to: Any,
95
+ subject: str,
96
+ *,
97
+ account: Optional[str] = None,
98
+ body_text: Optional[str] = None,
99
+ body_html: Optional[str] = None,
100
+ cc: Any = None,
101
+ bcc: Any = None,
102
+ timeout_s: float = 30.0,
103
+ headers: Optional[Dict[str, str]] = None,
104
+ ) -> Dict[str, Any]:
105
+ try:
106
+ _list_email_accounts, _list_emails, _read_email, helper = _load_comms_helpers()
107
+ except Exception as exc:
108
+ return _dependency_error(exc)
109
+ return helper(
110
+ to=to,
111
+ subject=subject,
112
+ account=account,
113
+ body_text=body_text,
114
+ body_html=body_html,
115
+ cc=cc,
116
+ bcc=bcc,
117
+ timeout_s=timeout_s,
118
+ headers=headers,
119
+ )
120
+
121
+
122
+ __all__ = [
123
+ "list_email_accounts",
124
+ "list_emails",
125
+ "read_email",
126
+ "send_email",
127
+ ]
@@ -657,7 +657,7 @@ class AbstractCoreHostFacade:
657
657
  )
658
658
 
659
659
  def list_email_accounts(self) -> Dict[str, Any]:
660
- from abstractcore.tools.comms_tools import list_email_accounts
660
+ from .comms_facade import list_email_accounts
661
661
 
662
662
  return list_email_accounts()
663
663
 
@@ -671,7 +671,7 @@ class AbstractCoreHostFacade:
671
671
  limit: int = 20,
672
672
  timeout_s: float = 30.0,
673
673
  ) -> Dict[str, Any]:
674
- from abstractcore.tools.comms_tools import list_emails
674
+ from .comms_facade import list_emails
675
675
 
676
676
  return list_emails(
677
677
  account=account,
@@ -691,7 +691,7 @@ class AbstractCoreHostFacade:
691
691
  timeout_s: float = 30.0,
692
692
  max_body_chars: int = 20000,
693
693
  ) -> Dict[str, Any]:
694
- from abstractcore.tools.comms_tools import read_email
694
+ from .comms_facade import read_email
695
695
 
696
696
  return read_email(
697
697
  uid=uid,
@@ -720,8 +720,7 @@ class AbstractCoreHostFacade:
720
720
  `get_abstractcore_run_facade(runtime).send_email(...)` instead so
721
721
  Runtime authors the durable child-run truth.
722
722
  """
723
-
724
- from abstractcore.tools.comms_tools import send_email
723
+ from .comms_facade import send_email
725
724
 
726
725
  return send_email(
727
726
  to=to,
@@ -0,0 +1,179 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict
4
+
5
+ import pytest
6
+
7
+ from abstractruntime.integrations import abstractcore
8
+ from abstractruntime.integrations.abstractcore import comms_facade
9
+ from abstractruntime.integrations.abstractcore.comms_facade import (
10
+ list_email_accounts,
11
+ list_emails,
12
+ read_email,
13
+ send_email,
14
+ )
15
+
16
+
17
+ def test_public_comms_facade_exports_are_available() -> None:
18
+ assert abstractcore.list_email_accounts is list_email_accounts
19
+ assert abstractcore.list_emails is list_emails
20
+ assert abstractcore.read_email is read_email
21
+ assert abstractcore.send_email is send_email
22
+ assert "list_email_accounts" in abstractcore.__all__
23
+ assert "list_emails" in abstractcore.__all__
24
+ assert "read_email" in abstractcore.__all__
25
+ assert "send_email" in abstractcore.__all__
26
+ assert "list_email_accounts" in comms_facade.__all__
27
+ assert "list_emails" in comms_facade.__all__
28
+ assert "read_email" in comms_facade.__all__
29
+ assert "send_email" in comms_facade.__all__
30
+
31
+
32
+ def test_list_email_accounts_delegates_to_core_helper(monkeypatch: pytest.MonkeyPatch) -> None:
33
+ monkeypatch.setattr(
34
+ comms_facade,
35
+ "_load_comms_helpers",
36
+ lambda: (
37
+ lambda: {"success": True, "accounts": [{"account": "default"}]},
38
+ lambda **_kwargs: {},
39
+ lambda **_kwargs: {},
40
+ lambda **_kwargs: {},
41
+ ),
42
+ )
43
+
44
+ payload = list_email_accounts()
45
+
46
+ assert payload == {"success": True, "accounts": [{"account": "default"}]}
47
+
48
+
49
+ def test_list_emails_delegates_to_core_helper(monkeypatch: pytest.MonkeyPatch) -> None:
50
+ recorded: Dict[str, Any] = {}
51
+
52
+ def _list_emails(**kwargs: Any) -> Dict[str, Any]:
53
+ recorded.update(kwargs)
54
+ return {"success": True, "messages": []}
55
+
56
+ monkeypatch.setattr(
57
+ comms_facade,
58
+ "_load_comms_helpers",
59
+ lambda: (
60
+ lambda: {},
61
+ _list_emails,
62
+ lambda **_kwargs: {},
63
+ lambda **_kwargs: {},
64
+ ),
65
+ )
66
+
67
+ payload = list_emails(account="default", mailbox="INBOX", since="7d", status="unread", limit=5, timeout_s=9)
68
+
69
+ assert payload == {"success": True, "messages": []}
70
+ assert recorded == {
71
+ "account": "default",
72
+ "mailbox": "INBOX",
73
+ "since": "7d",
74
+ "status": "unread",
75
+ "limit": 5,
76
+ "timeout_s": 9,
77
+ }
78
+
79
+
80
+ def test_read_email_delegates_to_core_helper(monkeypatch: pytest.MonkeyPatch) -> None:
81
+ recorded: Dict[str, Any] = {}
82
+
83
+ def _read_email(**kwargs: Any) -> Dict[str, Any]:
84
+ recorded.update(kwargs)
85
+ return {"success": True, "uid": kwargs["uid"]}
86
+
87
+ monkeypatch.setattr(
88
+ comms_facade,
89
+ "_load_comms_helpers",
90
+ lambda: (
91
+ lambda: {},
92
+ lambda **_kwargs: {},
93
+ _read_email,
94
+ lambda **_kwargs: {},
95
+ ),
96
+ )
97
+
98
+ payload = read_email(uid="123", account="default", mailbox="INBOX", timeout_s=11, max_body_chars=5000)
99
+
100
+ assert payload == {"success": True, "uid": "123"}
101
+ assert recorded == {
102
+ "uid": "123",
103
+ "account": "default",
104
+ "mailbox": "INBOX",
105
+ "timeout_s": 11,
106
+ "max_body_chars": 5000,
107
+ }
108
+
109
+
110
+ def test_send_email_delegates_to_core_helper(monkeypatch: pytest.MonkeyPatch) -> None:
111
+ recorded: Dict[str, Any] = {}
112
+
113
+ def _send_email(**kwargs: Any) -> Dict[str, Any]:
114
+ recorded.update(kwargs)
115
+ return {"success": True, "message_id": "<sent@example.com>"}
116
+
117
+ monkeypatch.setattr(
118
+ comms_facade,
119
+ "_load_comms_helpers",
120
+ lambda: (
121
+ lambda: {},
122
+ lambda **_kwargs: {},
123
+ lambda **_kwargs: {},
124
+ _send_email,
125
+ ),
126
+ )
127
+
128
+ payload = send_email(
129
+ ["a@example.com"],
130
+ "Hello",
131
+ account="ops",
132
+ body_text="Body",
133
+ cc=["c@example.com"],
134
+ bcc=["b@example.com"],
135
+ timeout_s=13,
136
+ headers={"X-Test": "1"},
137
+ )
138
+
139
+ assert payload == {"success": True, "message_id": "<sent@example.com>"}
140
+ assert recorded == {
141
+ "to": ["a@example.com"],
142
+ "subject": "Hello",
143
+ "account": "ops",
144
+ "body_text": "Body",
145
+ "body_html": None,
146
+ "cc": ["c@example.com"],
147
+ "bcc": ["b@example.com"],
148
+ "timeout_s": 13,
149
+ "headers": {"X-Test": "1"},
150
+ }
151
+
152
+
153
+ def test_comms_helpers_return_structured_dependency_error(monkeypatch: pytest.MonkeyPatch) -> None:
154
+ monkeypatch.setattr(
155
+ comms_facade,
156
+ "_load_comms_helpers",
157
+ lambda: (_ for _ in ()).throw(RuntimeError("email helper unavailable")),
158
+ )
159
+
160
+ assert list_email_accounts() == {
161
+ "success": False,
162
+ "code": "dependency_missing",
163
+ "error": "email helper unavailable",
164
+ }
165
+ assert list_emails() == {
166
+ "success": False,
167
+ "code": "dependency_missing",
168
+ "error": "email helper unavailable",
169
+ }
170
+ assert read_email(uid="123") == {
171
+ "success": False,
172
+ "code": "dependency_missing",
173
+ "error": "email helper unavailable",
174
+ }
175
+ assert send_email(["a@example.com"], "Hello") == {
176
+ "success": False,
177
+ "code": "dependency_missing",
178
+ "error": "email helper unavailable",
179
+ }
@@ -1,14 +0,0 @@
1
- ### Added
2
- - Runtime now exposes the remaining Gateway-facing comms/Telegram package boundary through public Runtime wrappers:
3
- - host-local email helpers on `get_abstractcore_host_facade(...)`
4
- - host-local Telegram TDLib/bootstrap/global-client wrappers in `abstractruntime.integrations.abstractcore.telegram_facade`
5
- - Outbound email and Telegram sends can now execute as durable Runtime-authored child runs through `get_abstractcore_run_facade(...)`:
6
- - `send_email(...)`
7
- - `send_telegram_message(...)`
8
- - `resume_tool_calls(...)` for approval-gated or passthrough tool waits
9
-
10
- ### Changed
11
- - Runtime docs and AI-readable `llms.txt` / `llms-full.txt` now distinguish clearly between:
12
- - host-local operator comms helpers
13
- - durable run-owned outbound comms execution and replay semantics
14
- - Outbound comms replay now follows the Runtime-owned truth model: recorded send requests and outcomes are replayed as data, not re-executed as external sends.