AbstractRuntime 0.0.1__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. abstractruntime-0.4.0/CHANGELOG.md +240 -0
  2. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/PKG-INFO +5 -1
  3. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/ROADMAP.md +13 -12
  4. abstractruntime-0.4.0/docs/architecture.md +165 -0
  5. abstractruntime-0.4.0/docs/backlog/completed/010_examples_and_composition.md +59 -0
  6. abstractruntime-0.4.0/docs/backlog/completed/016_runtime_aware_parameters.md +240 -0
  7. abstractruntime-0.4.0/docs/backlog/planned/015_agent_integration_improvements.md +111 -0
  8. abstractruntime-0.4.0/docs/backlog/planned/017_limit_warnings_and_observability.md +141 -0
  9. abstractruntime-0.4.0/docs/limits.md +266 -0
  10. abstractruntime-0.4.0/examples/01_hello_world.py +60 -0
  11. abstractruntime-0.4.0/examples/02_ask_user.py +134 -0
  12. abstractruntime-0.4.0/examples/03_wait_until.py +94 -0
  13. abstractruntime-0.4.0/examples/04_multi_step.py +100 -0
  14. abstractruntime-0.4.0/examples/05_persistence.py +173 -0
  15. abstractruntime-0.4.0/examples/06_llm_integration.py +102 -0
  16. abstractruntime-0.4.0/examples/07_react_agent.py +124 -0
  17. abstractruntime-0.4.0/examples/README.md +45 -0
  18. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/pyproject.toml +15 -3
  19. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/__init__.py +7 -2
  20. abstractruntime-0.4.0/src/abstractruntime/core/__init__.py +26 -0
  21. abstractruntime-0.4.0/src/abstractruntime/core/config.py +114 -0
  22. abstractruntime-0.4.0/src/abstractruntime/core/event_keys.py +62 -0
  23. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/core/models.py +55 -1
  24. abstractruntime-0.4.0/src/abstractruntime/core/runtime.py +3166 -0
  25. abstractruntime-0.4.0/src/abstractruntime/core/vars.py +189 -0
  26. abstractruntime-0.4.0/src/abstractruntime/evidence/__init__.py +10 -0
  27. abstractruntime-0.4.0/src/abstractruntime/evidence/recorder.py +325 -0
  28. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/integrations/abstractcore/__init__.py +9 -2
  29. abstractruntime-0.4.0/src/abstractruntime/integrations/abstractcore/constants.py +19 -0
  30. abstractruntime-0.4.0/src/abstractruntime/integrations/abstractcore/default_tools.py +134 -0
  31. abstractruntime-0.4.0/src/abstractruntime/integrations/abstractcore/effect_handlers.py +368 -0
  32. abstractruntime-0.4.0/src/abstractruntime/integrations/abstractcore/factory.py +272 -0
  33. abstractruntime-0.4.0/src/abstractruntime/integrations/abstractcore/llm_client.py +801 -0
  34. abstractruntime-0.4.0/src/abstractruntime/integrations/abstractcore/mcp_worker.py +586 -0
  35. abstractruntime-0.4.0/src/abstractruntime/integrations/abstractcore/observability.py +80 -0
  36. abstractruntime-0.4.0/src/abstractruntime/integrations/abstractcore/summarizer.py +154 -0
  37. abstractruntime-0.4.0/src/abstractruntime/integrations/abstractcore/tool_executor.py +625 -0
  38. abstractruntime-0.4.0/src/abstractruntime/memory/__init__.py +21 -0
  39. abstractruntime-0.4.0/src/abstractruntime/memory/active_context.py +746 -0
  40. abstractruntime-0.4.0/src/abstractruntime/memory/active_memory.py +452 -0
  41. abstractruntime-0.4.0/src/abstractruntime/memory/compaction.py +105 -0
  42. abstractruntime-0.4.0/src/abstractruntime/rendering/__init__.py +17 -0
  43. abstractruntime-0.4.0/src/abstractruntime/rendering/agent_trace_report.py +256 -0
  44. abstractruntime-0.4.0/src/abstractruntime/rendering/json_stringify.py +136 -0
  45. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/scheduler/scheduler.py +93 -2
  46. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/storage/__init__.py +3 -1
  47. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/storage/artifacts.py +51 -5
  48. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/storage/json_files.py +16 -3
  49. abstractruntime-0.4.0/src/abstractruntime/storage/observable.py +99 -0
  50. abstractruntime-0.4.0/tests/conftest.py +38 -0
  51. abstractruntime-0.4.0/tests/test_active_context_policy.py +217 -0
  52. abstractruntime-0.4.0/tests/test_active_memory.py +157 -0
  53. abstractruntime-0.4.0/tests/test_answer_user_effect.py +63 -0
  54. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_artifacts.py +56 -0
  55. abstractruntime-0.4.0/tests/test_chat_summarizer_integration.py +146 -0
  56. abstractruntime-0.4.0/tests/test_compaction_helpers.py +42 -0
  57. abstractruntime-0.4.0/tests/test_durable_toolsets.py +75 -0
  58. abstractruntime-0.4.0/tests/test_evidence_recorder.py +136 -0
  59. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_integration_abstractcore.py +6 -0
  60. abstractruntime-0.4.0/tests/test_ledger_subscription.py +87 -0
  61. abstractruntime-0.4.0/tests/test_llm_call_verbatim_payload_capture.py +31 -0
  62. abstractruntime-0.4.0/tests/test_llm_client_tool_call_parsing.py +250 -0
  63. abstractruntime-0.4.0/tests/test_mcp_remote_tool_executor.py +214 -0
  64. abstractruntime-0.4.0/tests/test_mcp_worker_logging.py +92 -0
  65. abstractruntime-0.4.0/tests/test_mcp_worker_security.py +89 -0
  66. abstractruntime-0.4.0/tests/test_mcp_worker_stdio.py +44 -0
  67. abstractruntime-0.4.0/tests/test_memory_note_effect.py +235 -0
  68. abstractruntime-0.4.0/tests/test_memory_query_effect.py +115 -0
  69. abstractruntime-0.4.0/tests/test_memory_query_rich_filters.py +250 -0
  70. abstractruntime-0.4.0/tests/test_memory_scope_and_rehydrate_effect.py +336 -0
  71. abstractruntime-0.4.0/tests/test_memory_tag_effect.py +122 -0
  72. abstractruntime-0.4.0/tests/test_packaging_extras.py +33 -0
  73. abstractruntime-0.4.0/tests/test_pause_resume.py +197 -0
  74. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_remote_llm_client.py +20 -0
  75. abstractruntime-0.4.0/tests/test_rendering_agent_trace_report.py +72 -0
  76. abstractruntime-0.4.0/tests/test_rendering_json_stringify.py +28 -0
  77. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_retry_idempotency.py +23 -0
  78. abstractruntime-0.4.0/tests/test_runtime_config_max_output_tokens_fallback.py +19 -0
  79. abstractruntime-0.4.0/tests/test_runtime_node_traces.py +65 -0
  80. abstractruntime-0.4.0/tests/test_runtime_start_seeds_tool_support.py +37 -0
  81. abstractruntime-0.4.0/tests/test_start_subworkflow_async_wait.py +61 -0
  82. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_subworkflow.py +20 -0
  83. abstractruntime-0.4.0/tests/test_terminal_effect_completion.py +48 -0
  84. abstractruntime-0.4.0/tests/test_tool_executor_argument_sanitization.py +28 -0
  85. abstractruntime-0.4.0/tests/test_tool_executor_error_output_detection.py +28 -0
  86. abstractruntime-0.4.0/tests/test_tool_executor_filename_alias.py +30 -0
  87. abstractruntime-0.4.0/tests/test_tool_executor_kwarg_canonicalization.py +58 -0
  88. abstractruntime-0.4.0/tests/test_tool_executor_read_file_aliases.py +65 -0
  89. abstractruntime-0.4.0/tests/test_tool_executor_timeout.py +45 -0
  90. abstractruntime-0.4.0/tests/test_tool_wait_allowlist_safety.py +152 -0
  91. abstractruntime-0.4.0/tests/test_trace_context_propagation.py +108 -0
  92. abstractruntime-0.4.0/tests/test_vars_query_effect.py +109 -0
  93. abstractruntime-0.4.0/tests/test_wait_event_prompt_metadata.py +61 -0
  94. abstractruntime-0.0.1/docs/backlog/planned/010_examples_and_composition.md +0 -29
  95. abstractruntime-0.0.1/src/abstractruntime/core/__init__.py +0 -19
  96. abstractruntime-0.0.1/src/abstractruntime/core/runtime.py +0 -581
  97. abstractruntime-0.0.1/src/abstractruntime/integrations/abstractcore/effect_handlers.py +0 -89
  98. abstractruntime-0.0.1/src/abstractruntime/integrations/abstractcore/factory.py +0 -150
  99. abstractruntime-0.0.1/src/abstractruntime/integrations/abstractcore/llm_client.py +0 -296
  100. abstractruntime-0.0.1/src/abstractruntime/integrations/abstractcore/tool_executor.py +0 -89
  101. abstractruntime-0.0.1/tests/conftest.py +0 -20
  102. abstractruntime-0.0.1/tests/test_pause_resume.py +0 -98
  103. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/.gitignore +0 -0
  104. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/LICENSE +0 -0
  105. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/README.md +0 -0
  106. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/adr/0001_layered_coupling_with_abstractcore.md +0 -0
  107. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/adr/0002_execution_modes_local_remote_hybrid.md +0 -0
  108. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/adr/0003_provenance_tamper_evident_hash_chain.md +0 -0
  109. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/adr/README.md +0 -0
  110. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/README.md +0 -0
  111. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/001_runtime_kernel.md +0 -0
  112. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/002_persistence_and_ledger.md +0 -0
  113. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/003_wait_primitives.md +0 -0
  114. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/004_scheduler_driver.md +0 -0
  115. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/005_abstractcore_integration.md +0 -0
  116. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/006_snapshots_bookmarks.md +0 -0
  117. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/007_provenance_hash_chain.md +0 -0
  118. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/009_artifact_store.md +0 -0
  119. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/011_subworkflow_support.md +0 -0
  120. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/012_run_store_query_and_scheduler_support.md +0 -0
  121. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/completed/013_effect_retries_and_idempotency.md +0 -0
  122. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/001_integrations_abstractcore.md +0 -0
  123. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/001_runtime_kernel.md +0 -0
  124. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/002_persistence_and_ledger.md +0 -0
  125. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/002_snapshots_bookmarks.md +0 -0
  126. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/003_provenance_ledger_chain.md +0 -0
  127. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/003_wait_resume_and_scheduler.md +0 -0
  128. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/004_effect_handlers_and_integrations.md +0 -0
  129. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/004_tests.md +0 -0
  130. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/005_docs_updates.md +0 -0
  131. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/005_examples_and_composition.md +0 -0
  132. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/006_ai_fingerprint_and_provenance.md +0 -0
  133. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/DEPRECATED_README.md +0 -0
  134. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/README.md +0 -0
  135. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/deprecated/abstractruntime_docs_final_02a7373b.plan.md +0 -0
  136. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/planned/008_signatures_and_keys.md +0 -0
  137. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/backlog/planned/014_remote_tool_worker_executor.md +0 -0
  138. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/integrations/abstractcore.md +0 -0
  139. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/manual_testing.md +0 -0
  140. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/proposal.md +0 -0
  141. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/provenance.md +0 -0
  142. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/docs/snapshots.md +0 -0
  143. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/core/policy.py +0 -0
  144. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/core/spec.py +0 -0
  145. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/identity/__init__.py +0 -0
  146. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/identity/fingerprint.py +0 -0
  147. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/integrations/__init__.py +0 -0
  148. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/integrations/abstractcore/logging.py +0 -0
  149. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/scheduler/__init__.py +0 -0
  150. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/scheduler/convenience.py +0 -0
  151. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/scheduler/registry.py +0 -0
  152. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/storage/base.py +0 -0
  153. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/storage/in_memory.py +0 -0
  154. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/storage/ledger_chain.py +0 -0
  155. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/src/abstractruntime/storage/snapshots.py +0 -0
  156. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/README.md +0 -0
  157. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_integrations_abstractcore.py +0 -0
  158. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_ledger_chain.py +0 -0
  159. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_queryable_run_store.py +0 -0
  160. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_real_integration.py +0 -0
  161. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_scheduler.py +0 -0
  162. {abstractruntime-0.0.1 → abstractruntime-0.4.0}/tests/test_snapshots.py +0 -0
@@ -0,0 +1,240 @@
1
+ # Changelog
2
+
3
+ All notable changes to AbstractRuntime will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+ - **Durable prompt metadata for EVENT waits**:
12
+ - `WAIT_EVENT` effects may include optional `prompt`, `choices`, and `allow_free_text` fields.
13
+ - The runtime persists these fields onto `WaitState` so hosts (including remote/thin clients) can render a durable ask+wait UX without relying on in-process callbacks.
14
+ - **Rendering utilities** (`abstractruntime.rendering`):
15
+ - `stringify_json(...)` + `JsonStringifyMode` to render JSON/JSON-ish values into strings with `none|beautify|minified` modes.
16
+ - `render_agent_trace_markdown(...)` to render runtime-owned `node_traces` scratchpads into a complete, review-friendly Markdown timeline (tool args + results untruncated).
17
+
18
+ ## [0.4.0] - 2025-01-06
19
+
20
+ ### Added
21
+
22
+ - **Active Memory System** (`abstractruntime.memory.active_memory`): Complete MemAct agent memory module
23
+ - Runtime-owned `ACTIVE_MEMORY_DELTA` effect for structured Active Memory updates (used by agents via `active_memory_delta` tool)
24
+ - JSON-safe durable storage in `run.vars["_runtime"]["active_memory"]`
25
+ - Memory modules: MY PERSONA, RELATIONSHIPS, MEMORY BLUEPRINTS, CURRENT TASKS, CURRENT CONTEXT, CRITICAL INSIGHTS, REFERENCES, HISTORY
26
+ - Active Memory v9 format with natural-language markdown rendering (not YAML) to reduce syntax contamination
27
+ - All components render into system prompt by default (prevents user-role pollution on native-tool providers)
28
+
29
+ - **MCP Worker** (`abstractruntime-mcp-worker`): Standalone stdio-based MCP server for AbstractRuntime tools
30
+ - Exposes AbstractRuntime's default toolsets as MCP tools via stdio transport
31
+ - Human-friendly logging to stderr with ANSI color support
32
+ - Security: allowlist-based command execution safety (`TOOL_WAIT` effect for dangerous commands)
33
+ - New optional dependency: `abstractruntime[mcp-worker]` (includes `abstractcore[tools]`)
34
+ - Entry point: `abstractruntime-mcp-worker` CLI script
35
+
36
+ - **Evidence Capture System** (`abstractruntime.evidence.recorder`): Always-on provenance-first evidence recording
37
+ - Automatically records evidence for external-boundary tools: `web_search`, `fetch_url`, `execute_command`
38
+ - Evidence stored as artifact-backed records indexed as `kind="evidence"` in `RunState.vars["_runtime"]["memory_spans"]`
39
+ - Runtime helpers: `Runtime.list_evidence(run_id)` and `Runtime.load_evidence(evidence_id)`
40
+ - Keeps RunState JSON-safe by storing large payloads in ArtifactStore with refs
41
+
42
+ - **Ledger Subscriptions**: Real-time step append events via `Runtime.subscribe_ledger()`
43
+ - `create_local_runtime`, `create_remote_runtime`, `create_hybrid_runtime` now wrap LedgerStore with `ObservableLedgerStore` by default
44
+ - Hosts can receive real-time notifications when steps are appended to ledger
45
+
46
+ - **Durable Custom Events (Signals)**:
47
+ - `EMIT_EVENT` effect to dispatch events and resume matching `WAIT_EVENT` runs
48
+ - Extended `WAIT_EVENT` to accept `{scope, name}` payloads (runtime computes stable `wait_key`)
49
+ - `Scheduler.emit_event(...)` host API for external event delivery (session-scoped by default)
50
+
51
+ - **Orchestrator-Owned Timeouts** (AbstractCore integration):
52
+ - Default **LLM timeout**: 7200s per `LLM_CALL` (not per-workflow), enforced by `create_*_runtime` factories
53
+ - Default **tool execution timeout**: 7200s per tool call (not per-workflow), enforced by ToolExecutor implementations
54
+
55
+ - **Tool Executor Enhancements** (`MappingToolExecutor`):
56
+ - **Argument canonicalization**: Maps common parameter name variations (e.g., `file_path`/`filepath`/`path`) to canonical names
57
+ - **Filename aliases**: Supports `target_file`, `file_path`, `filepath`, `path` as aliases for file operations
58
+ - **Error output detection**: Detects structured error responses (`{"success": false, ...}`) from tools
59
+ - **Argument sanitization**: Cleans and validates tool call arguments
60
+ - **Timeout support**: Per-tool execution timeouts with configurable limits
61
+
62
+ - **Memory Query Enhancements** (`MEMORY_QUERY` effect):
63
+ - Tag filters with **AND/OR** modes (`tags_mode=all|any`) and **multi-value** keys (`tags.person=["alice","bob"]`)
64
+ - Metadata filters for **authors** (`created_by`) and **locations** (`location`, `tags.location`)
65
+ - Span records now capture `created_by` for `conversation_span`, `active_memory_span`, `memory_note` when `actor_id` available
66
+ - `MEMORY_NOTE` accepts optional `location` field
67
+ - `MEMORY_NOTE` supports `keep_in_context=true` flag to immediately rehydrate stored note into `context.messages`
68
+
69
+ - **Package Dependencies**:
70
+ - New optional dependency: `abstractruntime[abstractcore]` (enables `abstractruntime.integrations.abstractcore.*`)
71
+ - New optional dependency: `abstractruntime[mcp-worker]` (includes `abstractcore[tools]>=2.6.8`)
72
+
73
+ ### Changed
74
+
75
+ - **LLM Client Enhancements**:
76
+ - Tool call parsing refactored for better robustness and error handling
77
+ - Streaming support with timing metrics (TTFT, generation time)
78
+ - Response normalization preserves JSON-safe `raw_response` for debugging
79
+ - Always attaches exact provider request payload under `result.metadata._provider_request` for every `LLM_CALL` step
80
+
81
+ - **Runtime Core** (902 lines changed):
82
+ - Enhanced resume handling for paused/cancelled runs
83
+ - Improved subworkflow execution with async+wait support
84
+ - Better observable ledger integration
85
+
86
+ ### Fixed
87
+
88
+ - **Cancellation is Terminal**: `Runtime.tick()` now treats `RunStatus.CANCELLED` as terminal and will not progress cancelled runs
89
+ - **Control-Plane Safety**: `Runtime.tick()` stops without overwriting externally persisted pause/cancel state (used by AbstractFlow Web)
90
+ - **Atomic Run Checkpoints**: `JsonFileRunStore.save()` writes via temp file + atomic rename to prevent partial/corrupt JSON under concurrent writes
91
+ - **START_SUBWORKFLOW async+wait**: Support for `async=true` + `wait=true` to start child run without blocking parent tick, while keeping parent in durable SUBWORKFLOW wait
92
+ - **ArtifactStore Run-Scoped Addressing**: Artifact IDs namespaced to run when `run_id` provided (prevents cross-run collisions, preserves purge-by-run semantics)
93
+ - **AbstractCore Integration Imports**: `LocalAbstractCoreLLMClient` imports `create_llm` robustly in monorepo namespace-package layouts
94
+ - **Token Limit Metadata**: `_limits.max_output_tokens` falls back to model capabilities when not configured (runtime surfaces explicit per-step output budget)
95
+ - **Token-Cap Normalization Boundary**: Removed local `max_tokens → max_output_tokens` aliasing from AbstractRuntime's AbstractCore client (AbstractCore providers own this mapping)
96
+
97
+ ### Testing
98
+
99
+ - **25 new/modified test files** covering:
100
+ - Active Memory functionality
101
+ - MCP worker (logging, security, stdio communication)
102
+ - Evidence recorder
103
+ - Memory query rich filters
104
+ - Tool executor (canonicalization, filename aliases, timeouts, error detection)
105
+ - LLM client tool call parsing
106
+ - Runtime configuration and subworkflow handling
107
+ - Packaging extras validation
108
+
109
+ ### Statistics
110
+
111
+ - **33 commits** improving memory systems, MCP integration, evidence capture, and tool execution
112
+ - **45 files changed**: 5,788 insertions, 286 deletions
113
+ - **6,074 total lines changed** across the codebase
114
+ - **3 new modules**: `active_memory.py`, `evidence/recorder.py`, `mcp_worker.py`
115
+
116
+ ## [0.2.0] - 2025-12-17
117
+
118
+ ### Added
119
+
120
+ #### Core Runtime Features
121
+ - **Durable Workflow Execution**: Start/tick/resume semantics for long-running workflows that survive process restarts
122
+ - **WorkflowSpec**: Graph-based workflow definitions with node handlers keyed by ID
123
+ - **RunState**: Durable state management (`current_node`, `vars`, `waiting`, `status`)
124
+ - **Effect System**: Side-effect requests including `LLM_CALL`, `TOOL_CALLS`, `ASK_USER`, `WAIT_EVENT`, `WAIT_UNTIL`, `START_SUBWORKFLOW`
125
+ - **StepPlan**: Node execution plans that define effects and state transitions
126
+ - **Explicit Waiting States**: First-class support for pausing execution (`WaitReason`, `WaitState`)
127
+
128
+ #### Scheduler & Automation
129
+ - **Built-in Scheduler**: Zero-config background scheduler with polling thread for automatic run resumption
130
+ - **WorkflowRegistry**: Mapping from workflow_id to WorkflowSpec for dynamic workflow resolution
131
+ - **ScheduledRuntime**: High-level wrapper combining Runtime + Scheduler with simplified API
132
+ - **create_scheduled_runtime()**: Factory function for zero-config scheduler creation
133
+ - **Event Ingestion**: Support for external event delivery via `scheduler.resume_event()`
134
+ - **Scheduler Stats**: Built-in statistics tracking and callback support
135
+
136
+ #### Storage & Persistence
137
+ - **Append-only Ledger**: Execution journal with `StepRecord` entries for audit/debug/provenance
138
+ - **InMemoryRunStore**: In-memory run state storage for development and testing
139
+ - **InMemoryLedgerStore**: In-memory ledger storage for development and testing
140
+ - **JsonFileRunStore**: File-based persistent run state storage (one file per run)
141
+ - **JsonlLedgerStore**: JSONL-based persistent ledger storage
142
+ - **QueryableRunStore**: Interface for listing and filtering runs by status, workflow_id, actor_id, and time range
143
+ - **Artifacts System**: Storage for large payloads (documents, images, tool outputs) to avoid bloating checkpoints
144
+ - `ArtifactStore` interface with in-memory and file-based implementations
145
+ - `ArtifactRef` type for referencing stored artifacts
146
+ - Helper functions: `artifact_ref()`, `is_artifact_ref()`, `get_artifact_id()`, `resolve_artifact()`, `compute_artifact_id()`
147
+
148
+ #### Snapshots & Bookmarks
149
+ - **Snapshot System**: Named, searchable checkpoints of run state for debugging and experimentation
150
+ - **SnapshotStore**: Storage interface for snapshots with metadata (name, description, tags, timestamps)
151
+ - **InMemorySnapshotStore**: In-memory snapshot storage for development
152
+ - **JsonSnapshotStore**: File-based snapshot storage (one file per snapshot)
153
+ - **Snapshot Search**: Filter by run_id, tag, or substring match in name/description
154
+
155
+ #### Provenance & Accountability
156
+ - **Hash-Chained Ledger**: Tamper-evident ledger with `prev_hash` and `record_hash` for each step
157
+ - **HashChainedLedgerStore**: Decorator for adding hash chain verification to any ledger store
158
+ - **verify_ledger_chain()**: Verification function that detects modifications or reordering of ledger records
159
+ - **Actor Identity**: `ActorFingerprint` for attribution of workflow execution to specific actors
160
+ - **actor_id tracking**: Support for actor_id in both RunState and StepRecord for accountability
161
+
162
+ #### AbstractCore Integration
163
+ - **LLM_CALL Effect Handler**: Execute LLM calls via AbstractCore providers
164
+ - **TOOL_CALLS Effect Handler**: Execute tool calls with support for multiple execution modes
165
+ - **Three Execution Modes**:
166
+ - **Local**: In-process AbstractCore providers with local tool execution
167
+ - **Remote**: HTTP to AbstractCore server (`/v1/chat/completions`) with tool passthrough
168
+ - **Hybrid**: Remote LLM calls with local tool execution
169
+ - **Convenience Factories**: `create_local_runtime()`, `create_remote_runtime()`, `create_hybrid_runtime()`
170
+ - **Tool Execution Modes**:
171
+ - Executed mode (trusted local) with results
172
+ - Passthrough mode (untrusted/server) with waiting semantics
173
+ - **Layered Coupling**: AbstractCore integration as opt-in module to keep kernel dependency-light
174
+
175
+ #### Effect Policies & Reliability
176
+ - **EffectPolicy Protocol**: Configurable retry and idempotency policies for effects
177
+ - **DefaultEffectPolicy**: Default implementation with no retries
178
+ - **RetryPolicy**: Configurable retry behavior with max_attempts and backoff
179
+ - **NoRetryPolicy**: Explicit no-retry policy
180
+ - **compute_idempotency_key()**: Ledger-based deduplication to prevent duplicate side effects after crashes
181
+
182
+ #### Examples & Documentation
183
+ - **7 Runnable Examples**:
184
+ - `01_hello_world.py`: Minimal workflow demonstration
185
+ - `02_ask_user.py`: Pause/resume with user input
186
+ - `03_wait_until.py`: Scheduled resumption with time-based waiting
187
+ - `04_multi_step.py`: Branching workflow with conditional logic
188
+ - `05_persistence.py`: File-based storage demonstration
189
+ - `06_llm_integration.py`: AbstractCore LLM call integration
190
+ - `07_react_agent.py`: Full ReAct agent implementation with tools
191
+ - **Comprehensive Documentation**:
192
+ - Architecture Decision Records (ADRs) for key design choices
193
+ - Integration guides for AbstractCore
194
+ - Detailed documentation for snapshots and provenance
195
+ - Limits and constraints documentation
196
+ - ROADMAP with prioritized next steps
197
+
198
+ ### Technical Details
199
+
200
+ #### Architecture
201
+ - **Layered Design**: Clear separation between kernel, storage, integrations, and identity
202
+ - **Dependency-Light Kernel**: Core runtime remains stable with minimal dependencies
203
+ - **Graph-Based Execution**: All workflows represented as state machines/graphs for visualization and composition
204
+ - **JSON-Serializable State**: All run state and vars must be JSON-serializable for persistence
205
+
206
+ #### Test Coverage
207
+ - **81% Overall Coverage**: Comprehensive test suite with 57+ tests
208
+ - **Integration Tests**: Tests for AbstractCore integration, subworkflows, trace propagation
209
+ - **Core Tests**: Scheduler, snapshots, artifacts, pause/resume, retry/idempotency, ledger chain
210
+ - **Storage Tests**: Queryable run store, durable toolsets
211
+
212
+ #### Compatibility
213
+ - **Python 3.10+**: Supports Python 3.10, 3.11, 3.12, and 3.13
214
+ - **Development Status**: Planning/Alpha (moving toward Beta with 0.2.0)
215
+
216
+ ### Known Limitations
217
+
218
+ - Snapshot restore does not guarantee safety if workflow spec or node code has changed
219
+ - Subworkflow support (`START_SUBWORKFLOW`) is implemented but undergoing refinement
220
+ - Cryptographic signatures (non-forgeability) not yet implemented - current hash chain provides tamper-evidence only
221
+ - Remote tool worker service not yet implemented
222
+
223
+ ### Design Decisions
224
+
225
+ - **Kernel stays dependency-light**: Enables portability, stability, and clear integration boundaries
226
+ - **AbstractCore integration is opt-in**: Layered coupling prevents kernel breakage when AbstractCore changes
227
+ - **Hash chain before signatures**: Provides immediate value without key management complexity
228
+ - **Built-in scheduler (not external)**: Zero-config UX for simple cases
229
+ - **Graph representation for all workflows**: Enables visualization, checkpointing, and composition
230
+
231
+ ### Notes
232
+
233
+ AbstractRuntime is the durable execution substrate designed to pair with AbstractCore, AbstractAgent, and AbstractFlow. It enables workflows to interrupt, checkpoint, and resume across process restarts, making it suitable for long-running agent workflows that need to wait for user input, scheduled events, or external job completion.
234
+
235
+ ## [0.0.1] - Initial Development
236
+
237
+ Initial development version with basic proof-of-concept features.
238
+
239
+ [0.2.0]: https://github.com/lpalbou/abstractruntime/releases/tag/v0.2.0
240
+ [0.0.1]: https://github.com/lpalbou/abstractruntime/releases/tag/v0.0.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AbstractRuntime
3
- Version: 0.0.1
3
+ Version: 0.4.0
4
4
  Summary: AbstractRuntime: a durable graph runner designed to pair with AbstractCore.
5
5
  Project-URL: AbstractCore (website), https://www.abstractcore.ai/
6
6
  Project-URL: AbstractCore (GitHub), https://github.com/lpalbou/abstractruntime
@@ -18,6 +18,10 @@ Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3.13
20
20
  Requires-Python: >=3.10
21
+ Provides-Extra: abstractcore
22
+ Requires-Dist: abstractcore>=2.6.8; extra == 'abstractcore'
23
+ Provides-Extra: mcp-worker
24
+ Requires-Dist: abstractcore[tools]>=2.6.8; extra == 'mcp-worker'
21
25
  Description-Content-Type: text/markdown
22
26
 
23
27
  ## AbstractRuntime
@@ -90,19 +90,20 @@ sr.stop()
90
90
 
91
91
  ---
92
92
 
93
- ### 2.2 Examples and Documentation
93
+ ### 2.2 Examples and Documentation ✅ COMPLETE
94
94
  **Priority: High** | **Effort: Low** | **Backlog: 010**
95
95
 
96
- **Why**: The MVP is functional but lacks concrete examples. Developers cannot understand how to build workflows without reading source code.
97
-
98
- **Deliverables**:
99
- - `examples/` directory with runnable workflows
100
- - ask_user interrupt example (pause for days, resume)
101
- - wait_until timer example
102
- - LLM call + tool execution example
103
- - Subworkflow composition example
96
+ **What shipped**:
97
+ - `examples/` directory with 7 runnable examples
98
+ - 01_hello_world.py - Minimal workflow
99
+ - 02_ask_user.py - Pause/resume with user input
100
+ - 03_wait_until.py - Scheduled resumption
101
+ - 04_multi_step.py - Branching workflow
102
+ - 05_persistence.py - File-based storage
103
+ - 06_llm_integration.py - AbstractCore LLM call
104
+ - 07_react_agent.py - Full ReAct agent with tools
104
105
 
105
- **Success criteria**: A developer can copy an example and have a working workflow in 5 minutes.
106
+ **Success criteria**: A developer can copy an example and have a working workflow in 5 minutes.
106
107
 
107
108
  ---
108
109
 
@@ -227,8 +228,8 @@ AbstractCore (LLM calls, tool execution, server API)
227
228
  | 4.2 | Remote Worker | 3-4 days |
228
229
 
229
230
  **Phase 1 (Core Completeness)**: ✅ Complete
230
- **Phase 2 (Composition)**: ~3-5 days
231
+ **Phase 2 (Composition)**: Examples complete, Subworkflow complete
231
232
  **Phase 3 (Production Readiness)**: ~1 week
232
233
  **Phase 4 (Advanced Features)**: ~2 weeks
233
234
 
234
- Remaining: ~3-4 weeks for full roadmap.
235
+ Remaining: ~2-3 weeks for full roadmap.
@@ -0,0 +1,165 @@
1
+ # AbstractRuntime — Architecture (Current)
2
+
3
+ > Updated: 2026-01-07
4
+ > Scope: this describes **what is implemented today** in this monorepo.
5
+
6
+ AbstractRuntime is the **durable execution kernel** of the AbstractFramework. It runs workflow graphs as a persisted state machine:
7
+ - **tick** a run forward until it completes or blocks
8
+ - persist **checkpoints** (RunState) + an append-only **ledger** (StepRecord)
9
+ - represent blocking as durable **WaitState** (USER / EVENT / UNTIL / SUBWORKFLOW)
10
+ - resume with an external payload (human input, event envelope, job completion)
11
+
12
+ AbstractRuntime is intentionally dependency-light in the core (`abstractruntime/core/*`):
13
+ - higher-level integrations (LLM providers, tool execution, event bus bridging) live in `abstractruntime/integrations/*`
14
+
15
+ ## High-level runtime loop (data flow)
16
+
17
+ ```
18
+ WorkflowSpec (in-memory handlers)
19
+
20
+
21
+ Runtime.tick(run_id)
22
+ │ loads + updates
23
+
24
+ RunStore (checkpoint RunState.vars + waiting)
25
+ │ append
26
+
27
+ LedgerStore (StepRecords: started/completed/waiting/failed)
28
+ │ large payloads
29
+
30
+ ArtifactStore (JSON blobs referenced from vars/ledger)
31
+ ```
32
+
33
+ ## Core Types (Durable, JSON-Safe)
34
+
35
+ Defined in `abstractruntime/src/abstractruntime/core/models.py`:
36
+
37
+ - `WorkflowSpec`
38
+ - `workflow_id`, `entry_node`, `nodes: Dict[node_id, handler]`
39
+ - `RunState`
40
+ - `run_id`, `workflow_id`, `status`, `current_node`
41
+ - `vars` (**JSON-safe** dictionary, persisted by RunStore)
42
+ - `waiting: WaitState | None`
43
+ - `output` / `error`
44
+ - optional provenance: `actor_id`, `session_id`, `parent_run_id`
45
+ - `StepPlan`
46
+ - returned by node handlers: `{effect?, next_node?, complete_output?}`
47
+ - `Effect` + `EffectType`
48
+ - requests for side effects / waits (LLM_CALL, TOOL_CALLS, ASK_USER, WAIT_EVENT, …)
49
+ - `WaitState` + `WaitReason`
50
+ - durable blocking representation
51
+ - `StepRecord`
52
+ - append-only audit log entries (STARTED/COMPLETED/WAITING/FAILED)
53
+
54
+ ## Runtime Semantics (start / tick / resume)
55
+
56
+ Implemented in `abstractruntime/src/abstractruntime/core/runtime.py`:
57
+
58
+ - `Runtime.start(workflow, vars, actor_id?, session_id?, parent_run_id?) -> run_id`
59
+ - creates a `RunState` checkpoint (RUNNING, current_node=entry)
60
+ - `Runtime.tick(workflow, run_id, max_steps=...) -> RunState`
61
+ - executes node handlers in a loop:
62
+ - handler returns `StepPlan`
63
+ - if `StepPlan.effect` exists → dispatch to the effect handler registry
64
+ - if effect outcome blocks → persist `RunState.waiting` and return WAITING
65
+ - if `next_node` exists → advance cursor and continue
66
+ - if `complete_output` exists → set run output and finish
67
+ - `Runtime.resume(workflow, run_id, wait_key, payload, max_steps=...) -> RunState`
68
+ - validates the run is waiting for `wait_key`
69
+ - writes `payload` to the waiting node’s `result_key`
70
+ - clears `waiting`, transitions to RUNNING, continues via `tick`
71
+
72
+ ### Run Control (pause/resume/cancel)
73
+ Run control is runtime-owned (also in `abstractruntime/core/runtime.py`):
74
+ - pause uses a synthetic WAIT_USER (`wait_key = pause:<run_id>`) and a durable flag in `vars["_runtime"]["control"]["paused"]`
75
+ - resume clears the pause wait and continues ticking
76
+ - cancel marks the run CANCELLED (and can cancel subflows via host orchestration)
77
+
78
+ ## Persistence Layer (RunStore / LedgerStore / ArtifactStore)
79
+
80
+ Storage interfaces are defined in `abstractruntime/src/abstractruntime/storage/base.py` and implemented in:
81
+ - `abstractruntime/src/abstractruntime/storage/in_memory.py` (in-memory stores)
82
+ - `abstractruntime/src/abstractruntime/storage/json_files.py` (file-based stores)
83
+ - `JsonFileRunStore`: `run_<run_id>.json`
84
+ - `JsonlLedgerStore`: `ledger_<run_id>.jsonl`
85
+ - `abstractruntime/src/abstractruntime/storage/artifacts.py`
86
+ - `ArtifactStore` + `FileArtifactStore` + helpers (`artifact_ref`, `resolve_artifact`, …)
87
+ - `abstractruntime/src/abstractruntime/storage/observable.py`
88
+ - `ObservableLedgerStore` adds subscriptions for live UI streaming
89
+
90
+ **Key invariant:** `RunState.vars` must remain JSON-safe. Large payloads should be stored in `ArtifactStore` and referenced.
91
+
92
+ ## Effect System (Handlers)
93
+
94
+ The runtime executes side effects by dispatching `EffectType` to handler callables. The core runtime ships with the effect protocol; hosts wire concrete handlers.
95
+
96
+ ### Memory effects (runtime-owned, durable)
97
+ The runtime ships a small, provenance-first memory surface (no embeddings):
98
+ - `EffectType.MEMORY_COMPACT`: archive older `context.messages` into an artifact + insert a summary handle
99
+ - `EffectType.MEMORY_NOTE`: store a durable note with tags + sources
100
+ - supports `payload.scope = run|session|global` (scope is routing: it selects the index-owner run)
101
+ - `EffectType.MEMORY_QUERY`: recall spans/notes by id/tags/time/query
102
+ - supports `payload.scope = run|session|global|all`
103
+ - supports `payload.return = rendered|meta|both` (meta enables deterministic workflows without parsing text)
104
+ - `EffectType.MEMORY_TAG`: apply/merge tags onto existing span index entries
105
+ - `EffectType.MEMORY_REHYDRATE`: rehydrate archived `conversation_span` artifacts into `context.messages` deterministically (deduped)
106
+
107
+ Global scope uses a stable run id (default `global_memory`, override via `ABSTRACTRUNTIME_GLOBAL_MEMORY_RUN_ID`, validated as filesystem-safe).
108
+
109
+ ### AbstractCore Integration (LLM + Tools)
110
+ `abstractruntime/src/abstractruntime/integrations/abstractcore/*` provides:
111
+ - an AbstractCore-backed LLM client (`llm_client.py`)
112
+ - tool execution boundary (`tool_executor.py`)
113
+ - `MappingToolExecutor` (recommended)
114
+ - `AbstractCoreToolExecutor` (legacy adapter path)
115
+ - `PassthroughToolExecutor` (host executes tools externally)
116
+ - effect handler wiring (`effect_handlers.py`)
117
+ - convenience factories (`factory.py`)
118
+ - `create_local_runtime(...)` (local execution)
119
+ - `create_remote_runtime(...)` (passthrough tools / host-mediated)
120
+
121
+ This keeps the kernel independent of AbstractCore while enabling LLM/tool workflows when a host opts in.
122
+
123
+ ## Observability (Ledger + Runtime-Owned Node Traces)
124
+
125
+ ### Ledger (Source of Truth)
126
+ Every node transition produces `StepRecord` entries appended to the `LedgerStore`.
127
+ When using `ObservableLedgerStore`, hosts can subscribe to appends for real-time UI updates.
128
+
129
+ ### Runtime-Owned Node Traces
130
+ In addition to the ledger, the runtime stores bounded, JSON-safe per-node traces under:
131
+ `run.vars["_runtime"]["node_traces"]` (see `abstractruntime/src/abstractruntime/core/runtime.py:_record_node_trace` and helpers in `abstractruntime/src/abstractruntime/core/vars.py`).
132
+
133
+ These traces support host UX needs (scratchpad/trace views) without inventing host-specific persistence formats.
134
+
135
+ ### Optional Event Bus Bridge
136
+ `abstractruntime.integrations.abstractcore.observability` can bridge ledger events to `abstractcore.events.GlobalEventBus` when desired.
137
+
138
+ ## Scheduling (Time-Based Waits)
139
+
140
+ Time-based waits (`WAIT_UNTIL`) are durable. To advance them, a host needs to tick due runs. AbstractRuntime provides:
141
+ - `create_scheduled_runtime(...)` and a `Scheduler` (`abstractruntime/src/abstractruntime/scheduler/*`)
142
+
143
+ Hosts can run a scheduler loop to periodically:
144
+ - query due `WAIT_UNTIL` runs (requires a queryable run store)
145
+ - tick them forward
146
+
147
+ ## Eventing (WAIT_EVENT / EMIT_EVENT)
148
+
149
+ Custom eventing is implemented as:
150
+ - listeners block on `WAIT_EVENT` (`WaitReason.EVENT`)
151
+ - emitters request `EffectType.EMIT_EVENT`, handled by the runtime (`Runtime._handle_emit_event`) which resumes matching `WAIT_EVENT` runs via `Runtime.resume(...)`
152
+ - requires a `QueryableRunStore` to find waiting runs and a `workflow_registry` to load target `WorkflowSpec`s
153
+
154
+ Notes:
155
+ - The emitted event **payload is normalized to a dict** for network-safe stability. If a non-dict is provided, it is wrapped as `{ "value": <payload> }`.
156
+ - `WAIT_EVENT` waits can optionally include UX metadata (`prompt`, `choices`, `allow_free_text`) so hosts can render interactive prompts while remaining fully durable.
157
+
158
+ For **host-driven external signals**, use the scheduler API:
159
+ - `Scheduler.emit_event(...)` (finds waiting runs and resumes them)
160
+
161
+ Event envelopes (scope/session/workflow) are encoded via stable wait keys (see `abstractruntime/src/abstractruntime/core/event_keys.py`).
162
+
163
+ ## Deviations / near-term work
164
+ - **Client-agnostic run history contract**: today, some hosts implement bespoke “ledger → UI events” replay logic. A runtime-owned, versioned `RunHistoryBundle` contract (planned: backlog 311) should become the shared format so any client can render consistent history and achieve stronger reproducibility.
165
+
@@ -0,0 +1,59 @@
1
+ ## 010_examples_and_composition (COMPLETED 2025-12-13)
2
+
3
+ ### Goal
4
+ Provide concrete, runnable examples demonstrating the simplified API:
5
+ - Zero-config setup with `create_scheduled_runtime()`
6
+ - `run()` and `respond()` for simple workflows
7
+ - `ask_user` interrupt (pause for user input)
8
+ - `wait_until` (scheduled resumption)
9
+ - Tool passthrough (for AbstractCore integration)
10
+ - Workflow-as-node composition (after 011 is complete)
11
+
12
+ ### Deliverables
13
+ - `examples/` directory with runnable Python scripts
14
+ - Each example should be self-contained and copy-pasteable
15
+
16
+ ### Proposed Examples
17
+
18
+ 1. **01_hello_world.py** — Minimal workflow with zero-config
19
+ 2. **02_ask_user.py** — Pause for user input, resume with response
20
+ 3. **03_wait_until.py** — Schedule a task for later
21
+ 4. **04_multi_step.py** — Multi-node workflow with branching
22
+ 5. **05_persistence.py** — File-based storage, survive restart
23
+ 6. **06_llm_integration.py** — AbstractCore LLM call (requires abstractcore)
24
+ 7. **07_react_agent.py** — Full ReAct agent with tools (requires abstractcore + abstractagent)
25
+
26
+ ### Acceptance criteria
27
+ - A developer can copy an example and have it running in < 5 minutes
28
+ - Examples use the simplified API (`run()`, `respond()`)
29
+ - Each example has clear comments explaining what's happening
30
+ - Examples 1-5 work without external dependencies
31
+ - Examples 6-7 require abstractcore/abstractagent but are clearly documented
32
+
33
+ ### Priority
34
+ **HIGH** - This is the most impactful improvement for adoption. Without examples, developers cannot understand how to use the library.
35
+
36
+ ---
37
+
38
+ ## Completion Notes
39
+
40
+ **Completed:** 2025-12-13
41
+
42
+ **Deliverables:**
43
+ - Created `examples/` directory with 7 runnable examples
44
+ - All examples tested and working
45
+
46
+ **Examples implemented:**
47
+ 1. `01_hello_world.py` - Minimal workflow with zero-config ✅
48
+ 2. `02_ask_user.py` - Pause for user input, resume with response ✅
49
+ 3. `03_wait_until.py` - Schedule a task for later ✅
50
+ 4. `04_multi_step.py` - Multi-node workflow with branching ✅
51
+ 5. `05_persistence.py` - File-based storage, survive restart ✅
52
+ 6. `06_llm_integration.py` - AbstractCore LLM call ✅
53
+ 7. `07_react_agent.py` - Full ReAct agent with tools ✅
54
+
55
+ **Additional improvements made:**
56
+ - AbstractAgent now uses TOOL_CALLS effect for ledger recording
57
+ - Created RegistryToolExecutor for agent-specific tool execution
58
+ - Added observe_node to ReAct workflow for proper effect-based architecture
59
+