kdeps workflow
A deterministic YAML pipeline. A request arrives, resources execute in dependency order, the result is returned - same input, same execution path, every time. Auditable, testable, safe to run unattended. Serve it as an HTTP API, a bot, or a file processor.
kdeps run ./my-agent/ # run once / serve on :3000Not this? For an autonomous agent that decides what to do next, use kdeps agent. To run several workflows/agents as one system, kdeps agencies. To ship this pipeline as an appliance, kdeps deploy.
Run with:
kdeps run workflow.yaml # or kdeps run ./my-agent/ to point at a directory containing workflow.yamlIf the workflow has no chat: resource, kdeps does not download a model or start an LLM server. /health binds immediately. Models download on the first chat request.
How it works
requires: is like an import - the resource won't run until its dependencies have output. Resources with no shared dependency path run concurrently.
When to use workflow mode
- You need a deterministic, auditable pipeline.
- You are building a REST API, bot, or file-processing service.
- You want full control over which resources run and in what order.
- You need validation, early-exit, and explicit error handling.
Comparison with agent mode
Workflow mode (kdeps run) | Agent mode (kdeps [path]) | |
|---|---|---|
| Execution | DAG, deterministic | LLM loop, tool-driven |
| Entry point | metadata.targetActionId | User prompt |
| Unit of work | Individual resources | Whole workflows |
| Tools | Functions in chat.tools | One per workflow + one per component + built-ins |
| Input | One workflow path | Optional file or folder |
| Conversation | Single run | Multi-turn, persistent JSONL |
Minimal example
workflow.yaml:
# workflow.yaml
apiVersion: kdeps.io/v1
kind: Workflow
metadata:
name: chat-api
version: "1.0.0"
targetActionId: response
settings:
apiServer:
hostIp: "127.0.0.1"
portNum: 16395
routes:
- path: /api/v1/chat
methods: [POST]resources/llm.yaml:
# resources/llm.yaml
actionId: llm
validations:
check:
- get('q') != ''
error:
code: 400
message: "'q' is required"
chat:
model: llama3.2:1b
role: user
prompt: "{{ get('q') }}"
timeout: 60sresources/response.yaml:
# resources/response.yaml
actionId: response
requires: [llm]
apiResponse:
success: true
response:
# chat output is the raw response object; the reply text is at .message.content
answer: get('llm').message.contentRun:
export KDEPS_API_AUTH_TOKEN=dev-token
kdeps run workflow.yaml
curl -X POST http://localhost:16395/api/v1/chat \
-H "Authorization: Bearer $KDEPS_API_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"q": "What is entropy?"}'/health is exempt. /_kdeps/* management routes use KDEPS_MANAGEMENT_TOKEN instead. See Security reference.
Input sources
Workflow mode supports three input sources configured in settings:
# API (default) - starts an HTTP server
settings:
apiServer:
portNum: 16395
routes:
- path: /api/v1/chat
methods: [POST]
# Bot - connects to a chat platform; blocks until SIGINT
# Credentials go in ~/.kdeps/config.yaml bot_connections, not here
settings:
input:
sources: [bot]
bot:
executionType: polling # polling = persistent; stateless = one message then exit
discord: {} # presence enables the platform
# File - reads one file from disk or stdin, runs once, exits
settings:
input:
sources: [file]
file:
path: /data/input.txtSee Input sources for full configuration.
Agent memory (--memory)
Workflow mode can use the same persistent memory facilities as agent mode. Pass --memory to enable:
kdeps run workflow.yaml --memory
kdeps exec my-agent --memoryWhen enabled, four expression functions become available in resource YAML:
| Function | Description |
|---|---|
memory_save(key, value) | Save a key-value pair to persistent memory |
memory_search(query) | Search memory entries by content (returns JSON array) |
memory_list() | List all memory keys |
memory_delete(key) | Delete a memory entry by key |
Memory persists across workflow runs in ~/.kdeps/memory/. Use it to carry state between invocations:
# resources/llm.yaml
actionId: llm
before:
- memory_save('last_query', get('q'))
chat:
model: llama3.2:1b
prompt: |
Previous context: {{ memory_search('user preference') }}
Answer: {{ get('q') }}# resources/response.yaml
actionId: response
requires: [llm]
before:
- memory_save('last_response', get('llm').message.content)
apiResponse:
success: true
response:
answer: get('llm').message.contentMemory entries are automatically linked into a relationship graph showing the chain from prompt to tool calls to results.
See also
- Workflow configuration - Full
workflow.yamlreference - Resources overview - Resource types and fields
- Agent mode - Autonomous LLM loop
