* Add xfailing test for concurrent step cancellation regression in 2.14.0
This test exposes a regression introduced in 2.14.0:
- In 2.13.1: A single asyncio.sleep(0) yield after stop_step returns is
sufficient for cancellation to propagate, blocking other_step's write.
- In 2.14.0: The yield is not enough - other_step's write still goes through.
Test sequence:
1. stop_step returns StopEvent
2. Single yield point (asyncio.sleep(0))
3. other_step writes to stream
In 2.13.1: write is blocked (PASS)
In 2.14.0: write goes through (FAIL)
The architectural change from asyncio.Queue to tick_buffer + wait_for_next_task
in commit 45e7614 ("Remove asyncio queue from control_loop #315") changed the
timing characteristics, requiring longer delays for cancellation to take effect.
In 2.13.1, workers immediately put ticks in the queue via queue_tick(), and
the continuous _pull() task meant quick processing. In 2.14.0, workers return
results collected by wait_for_next_task, adding overhead that delays cancellation.
Related: https://llama-index.slack.com/archives/C0A3TFERFHV/p1770391664693399https://claude.ai/code/session_01VWUvDsJ88uaVn4jT68Ny8X
* Fix concurrent step cancellation regression in 2.14.0
When a worker returns a StopEvent, immediately cancel other running
workers before adding the tick to the buffer. This restores the 2.13.1
behavior where a single asyncio.sleep(0) yield after stop_step returns
is sufficient for cancellation to propagate.
The regression was introduced in commit 45e7614 ("Remove asyncio queue
from control_loop #315") which changed the architecture from asyncio.Queue
to tick_buffer + wait_for_next_task. The new architecture had more overhead,
causing cancellation to take longer.
The fix checks if the completed worker's result contains a StopEvent, and
if so, calls cleanup_tasks() immediately to cancel other workers before
they can write to the event stream.
Also removes internal implementation references from comments.
Fixes: https://llama-index.slack.com/archives/C0A3TFERFHV/p1770391664693399https://claude.ai/code/session_01VWUvDsJ88uaVn4jT68Ny8X
* Add patch changeset for concurrent step cancellation fix
* fix lint
* Improve StopEvent cancellation speed for sibling steps
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Fix openapi generation script to use correct module path
The hatch script `server:openapi` was invoking `python -m workflows.server.server`,
but `workflows.server` is just a re-export shim with no `server.py` submodule.
The actual module with the `__main__` block lives at `llama_agents.server.server`.
* Move OpenAPI generation from workflows package to server package
The hatch openapi script and CI workflow were configured in the
llama-index-workflows package, which required a special hatch environment
with the `server` extra to access the server module. Since the actual
server code lives in llama-agents-server, move everything there where
all dependencies are already available directly.
- Add hatch config and openapi script to llama-agents-server pyproject.toml
- Remove hatch config and hatch dev dep from llama-index-workflows pyproject.toml
- Update publish_openapi.yml to run from packages/llama-agents-server
* chore: CI/testing improvements for parallel test execution
- Add workflows-dev pytest command with parallel test runner
- Add pytest-xdist for parallel test execution (-nauto)
- Add timeouts to prevent test hangs (--timeout=10/60/120)
- Use module-scoped async fixtures for faster tests
- Remove mypy in favor of basedpyright/ty type checking
- Add test-docker CI job for integration tests with testcontainers
- Exclude integration tests from Python 3.9/3.14 in CI matrix
* refact: introduce runtime plugin architecture and context separation
- Add Runtime abstract base class with BasicRuntime as default implementation
- Split context into external, internal, and pre-context modules
- Replace workflow_registry with workflow_tracker for workflow lifecycle management
- Remove broker.py in favor of runtime-managed execution
- Add plugins package with get_current_runtime() for context-aware runtime access
- Update handler and workflow to use new runtime interfaces
* prep packages
* wrong coverage detection I think
* add ts deps?
* extend path for namespaces
* the big move, import issues though
* llama_index.workflows
* llama_agents
* alias may be working
* add type checker ignores for workflows secondary namespace, update ty, and add re-exports
* Add descriptions to new client and server packages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Rather, commit the outputs
* keep the py files separate
* ignore examples deps
* Create afraid-books-own.md
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: Add resource and resource config validation to workflow validate()
Adds optional resource validation to validate():
- validate_resource_configs (default True): Validates config files exist
and match their Pydantic schemas
- validate_resources (default False): Resolves resource factories, also
catches circular dependencies via ResourceManager
Key implementation:
- _validate_resource_configs(): Stack-based traversal of all resources
and their dependencies, validates _ResourceConfig instances
- _validate_resources(): Resolves resources via ResourceManager.get()
- validate() now runs even with disable_validation=True when called
explicitly
- Python 3.9 compat: restore event loop after asyncio.run()
* Create smooth-donkeys-run.md
* Update test_resources.py
Kill off a silly extra test
---------
Co-authored-by: Claude <noreply@anthropic.com>
Modified sync_package_version_with_pyproject to return a boolean indicating
whether the pyproject.toml was changed. After syncing all packages, if any
pyproject.toml was updated, run uv sync in the root directory to update
the lock file.
* feat: add workflow class name to WorkflowGraph representation
Add a required `name` field to the WorkflowGraph model that contains
the workflow class name. This provides better identification of workflows
when viewing their graph representation or JSON output.
* feat: add dedicated StopEvent subclasses for workflow termination scenarios
Add WorkflowTerminationEvent base class and specific subclasses to provide
detailed information when workflows end abnormally:
- WorkflowTimedOutEvent: Published when workflow exceeds timeout, includes
timeout duration and list of active steps
- WorkflowCancelledEvent: Published when workflow is cancelled by user
- WorkflowFailedEvent: Published when a step fails permanently, includes
step name, exception type, and exception message
These events replace the empty StopEvent() instances that were previously
published, allowing consumers to understand why a workflow ended and take
appropriate action.
Closes: issue about providing exception information in StopEvent
* refactor: simplify termination events to inherit directly from StopEvent
* chore: add changeset
* feat: add traceback and fully qualified exception type to WorkflowFailedEvent
* feat: add retry info (attempts, elapsed_seconds) to WorkflowFailedEvent
Also fixes a bug where step_function.py used time.monotonic() instead of
time.time(), causing incompatible timestamps with first_attempt_at.
* fix lints/locks
* docs: add workflow termination events to streaming docs
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat: add resource nodes to workflow graph export
Add support for visualizing resource dependencies in workflow graphs:
- Enhanced _Resource class with source location metadata (file, line,
docstring, unique hash for deduplication)
- Added ResourceDefinition.type_annotation to capture the type from
Annotated[T, Resource(...)]
- Added WorkflowGraphResourceNode protocol model with full metadata
- Added DrawWorkflowResourceNode class for intermediate representation
- Updated DrawWorkflowEdge to support edge labels (variable names)
- Modified extract_workflow_structure to extract and deduplicate
resource nodes, connecting them to steps with labeled edges
- Updated Pyvis and Mermaid renderers to display resource nodes
(hexagon shape, plum color) with metadata tooltips
* test: add tests and example for resource nodes visualization
- Add tests for resource node extraction in test_representation_utils.py
- Add tests for resource rendering in test_drawing.py (Mermaid + Pyvis)
- Add workflow_with_resources fixture with multiple resources
- Add runnable example (examples/visualization/resource_nodes_example.py)
that generates both Mermaid and Pyvis output with resource nodes
* chore: add changeset for resource nodes feature
* fix: reverse resource edge direction to step -> resource
* refactor: unify DrawWorkflowNode and DrawWorkflowResourceNode
- Merge resource-specific fields into DrawWorkflowNode
- Add to_resource_response_model() for resource serialization
- Keep DrawWorkflowResourceNode as backwards compat alias
- Simplify type annotations in rendering code (remove unions)
- Remove isinstance checks since all nodes are now DrawWorkflowNode
* refactor: simplify _get_clean_node_id to use node_type prefix
* refactor: merge resource_nodes into nodes list
Unify resource nodes with the main nodes list instead of a separate
resource_nodes field. This simplifies the API and rendering code while
maintaining backwards compatibility through a property accessor.
- Remove resource_nodes field from DrawWorkflowGraph
- Add resource_nodes property for backwards compatibility
- Merge WorkflowGraphResourceNode fields into WorkflowGraphNode
- Simplify rendering loops to single iteration over nodes
* refactor: remove unnecessary backwards compatibility aliases
This is all new code in this PR - no need for backwards compat aliases.
Removes WorkflowGraphResourceNode, DrawWorkflowResourceNode,
to_resource_response_model, and resource_nodes property.
* perf: make resource metadata extraction lazy
Move expensive inspect operations (getfile, getsourcelines, getdoc)
and hash computation from Resource creation time to graph extraction
time. This avoids the overhead when resources are used at runtime
but visualization is not needed.
* test: remove unnecessary async from mermaid drawing tests
* consolidate types
* Split types
* feat: add description and schema fields to workflow graph nodes
- Add description field to WorkflowGraph (workflow class docstring)
- Add description field to WorkflowStepNode (step function docstring)
- Add event_schema field to WorkflowEventNode (Pydantic JSON schema)
- Rename WorkflowResourceNode.docstring to description for consistency
- Rename WorkflowGraphNodeEdges to WorkflowGraph
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* filter by node type
* Update add_resource_nodes.md
* remove resource hash
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat: Add draw_most_recent_execution_mermaid function
Co-authored-by: cecli (gemini/gemini-2.5-pro)
* Draw Mermaid: Refactored code. Not finished.
Draw Mermaid: More refactor
Draw Mermaid: More Refactor to clean up
Draw Mermaid: More refactor.
Draw Mermaid: Nicely Refactored
* Added mermaid code for draw_most_recent_execution_mermaid and test
test: Add tests for draw_most_recent_execution
Co-authored-by: cecli (gemini/gemini-2.5-pro)
Draw Mermaid: Added in the test case for draw_recent_execution_mermaid
* test case for draw_most_recent_execution_mermaid
* Moved import json to the top
* moved import json from second line to first line
* fix sort and bump lock
---------
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Adrian Lyjak <adrianlyjak@gmail.com>