klieo-workflow 3.5.0

Declarative no-code workflow substrate for the klieo agent framework.
Documentation

klieo-workflow

Declarative no-code workflow substrate for the klieo agent framework.

Part of the klieo Rust agent framework.

Author an agent workflow as data (a WorkflowDef, typically JSON emitted by a visual builder) and lower it into a runnable klieo_flows::Flow with compile — no Rust compile step per workflow.

Usage

[dependencies]
klieo-workflow = "3"

Via the umbrella crate:

[dependencies]
klieo = { version = "3", features = ["workflow"] }

Envelope model

State is a single shared JSON object — the envelope — threaded through every node. Each node reads one named field (input_from) as its input and writes its result to another named field (output_to), returning the whole envelope. Downstream nodes read the fields their predecessors wrote. The compiled flow rejects a non-object run input with a typed error rather than silently coercing it.

Node palette

kind Runs Fields
agent A data-configured SimpleAgent against a registered model agent: { model, system_prompt, tools? }
tool A registered tool, dispatched by id through the context tool: <id>
subflow A prebuilt Flow registered under an id ref: <id>

Every node also carries input_from / output_to (agent and tool nodes).

The Registry is the authorization boundary

compile validates a WorkflowDef against a Registry — the allow-list of primitives a workflow may reference. A model id must be registered (with_model), a tool id must be allowed (with_tool), and a subflow id must be registered (with_subflow). Anything a def references that is not in the registry is rejected at compile time with a typed CompileError. This is the authorization boundary for no-code workflows: authoring data cannot reach a primitive an operator did not register.

Linear example

{
  "id": "greet",
  "entry": "greet",
  "nodes": [
    { "id": "greet", "kind": "agent", "input_from": "q", "output_to": "r1",
      "agent": { "model": "default", "system_prompt": "Greet the user." } },
    { "id": "elaborate", "kind": "agent", "input_from": "r1", "output_to": "r2",
      "agent": { "model": "default", "system_prompt": "Add a follow-up." } }
  ],
  "edges": [ { "from": "greet", "to": "elaborate" } ]
}

Branching example

An edge is either unconditional (to) or conditional (whenthen / else); the two forms are mutually exclusive. A when is a bounded comparison (eq | ne | gt | gte | lt | lte | exists | contains) over one envelope field.

{
  "id": "triage",
  "entry": "score",
  "nodes": [
    { "id": "score", "kind": "subflow", "ref": "risk_scorer" },
    { "id": "review", "kind": "subflow", "ref": "human_review" },
    { "id": "approve", "kind": "subflow", "ref": "auto_approve" }
  ],
  "edges": [
    { "from": "score",
      "when": { "field": "risk", "op": "gte", "value": 0.8 },
      "then": "review", "else": "approve" }
  ]
}

Limits

  • No human-in-the-loop, loop, or parallel node kinds; the palette is agent | tool | subflow.
  • At most one outgoing edge per node.
  • A per-node model must be registered in the Registry; there is no implicit default model.
  • The top-level run input must be a JSON object.

License

MIT