Execution Flow
How kdeps resolves, orders, and runs resources in a workflow.
Overview
When you run kdeps run workflow.yaml or call POST /api/v1/run, the engine:
- Parses the workflow and builds a dependency graph from
requiresfields - Detects cycles (fails fast if any exist)
- Finds the
targetActionIdresource and walks its transitive dependencies - Topologically sorts resources so dependencies run before dependents
- Executes resources in order -- resources without shared dependencies can run concurrently
Execution Order
Dependency Graph
How requires works
# workflow.yaml (conceptual)
metadata:
targetActionId: respond # engine walks backward from here
resources:
- actionId: fetchData
httpClient:
url: https://api.example.com/data
- actionId: analyzeData
requires: [fetchData] # runs only after fetchData succeeds
chat:
prompt: "Analyze: {{ output('fetchData') }}"
- actionId: respond
requires: [analyzeData] # runs only after analyzeData succeeds
apiResponse:
response: "{{ output('analyzeData') }}"Execution order: fetchData -> analyzeData -> respond
Transitive dependencies
The engine resolves the full transitive closure. If A requires B, and B requires C, then C runs before both:
# resources/example.yaml
- actionId: C
exec:
command: echo "first"
- actionId: B
requires: [C]
chat:
prompt: "Build on: {{ output('C') }}"
- actionId: A
requires: [B]
apiResponse:
response: "{{ output('B') }}"Execution order: C -> B -> A
Independent resources
Resources that don't depend on each other (neither directly nor transitively) can run concurrently:
# resources/example.yaml
- actionId: fetchUsers
httpClient:
url: https://api.example.com/users
- actionId: fetchProducts # no requires -- independent of fetchUsers
httpClient:
url: https://api.example.com/products
- actionId: merge
requires: [fetchUsers, fetchProducts] # waits for both
chat:
prompt: "Users: {{ output('fetchUsers') }}, Products: {{ output('fetchProducts') }}"fetchUsers and fetchProducts run concurrently. merge waits for both.
Cycle Detection
The engine detects cycles during graph construction and fails fast with ErrCodeDependencyCycle:
# This creates a cycle and will fail:
- actionId: A
requires: [B]
- actionId: B
requires: [A] # cycle: A -> B -> ASkip vs Check
Both run before the main action, but they behave differently:
| skip | check | |
|---|---|---|
| Logic | ANY expression true triggers skip | ALL expressions must be true |
| On failure | Resource skipped silently, workflow continues | Workflow stops, error returned |
| Error code | N/A | Configurable via validations.error.code |
| Use case | Conditional execution, optional resources | Input validation, preconditions |
Skip example
# resources/example.yaml
validations:
skip:
- get('q') == '' # if query is empty, skip this resourceCheck example
# resources/example.yaml
validations:
check:
- get('apiKey') != nil # must have API key
- len(get('q')) <= 500 # query must be under 500 chars
error:
code: 400
message: Missing API key or query too longLoop Execution
When a resource has a loop config, the engine runs the full resource cycle (before -> check -> action -> after) repeatedly:
See Loop for full details.
Agent Mode Execution
In agent mode (kdeps serve), the execution model differs:
- Each workflow is registered as one tool (tool name =
metadata.name) - Each agency is registered as one tool (tool name =
agency.metadata.name); internal agents are not exposed individually - Components from each loaded workflow are also registered as individual callable tools
- The LLM receives the user prompt and decides which tool to invoke
- Workflow tool calls run the full DAG -- all
requires:dependencies execute in order;apiResponse.responseis returned to the LLM - Agency tool calls run the agency's entry-point pipeline; internal
agent:resources resolve against the agency's agent map - Component tool calls run the component in isolation with inputs mapped to its interface fields
- The LLM may call more tools or produce a final answer
Pointing at a single file registers one tool. Pointing at a folder registers one tool per workflow/agency found recursively (plus components). Resources are never registered as individual tools.
See Also
- Workflow Mode -- deterministic DAG pipelines
- Agent Mode -- LLM-driven tool calling
- Validation & Control Flow -- skip, check, and error handling
- Loop -- while-loop iteration
