duckflux Documentation

website·Indexed 31 days ago

https://docs.duckflux.openvibes.tech

A deterministic workflow orchestration framework for building agentic pipelines. duckflux uses YAML-based workflow files and CEL expressions for dynamic values, supporting parallel execution, loops, and event-driven communication via emit and wait primitives. It provides a TypeScript embeddable runtime (@duckflux/core), a CLI runner (quack), and a web server UI for inspecting execution traces.

Tokens
28.1K
Snippets
166
Records
195
Agent score
49%

What's inside duckflux

  1. Overview of DuckFlux Event Hub Backends

    DuckFlux provides three event hub backends for emit and wait steps. All backends implement the same EventHub interface, allowing them to be swapped without changing workflow YAML.

    BackendPackageInfrastructureReplayCross-process
    In-memory@duckflux/core (built-in)NoneYesNo
    NATS JetStream@duckflux/hub-natsNATS serverNoYes
    Redis Streams@duckflux/hub-redisRedis serverYesYes
  2. Overview of duckflux vs Claude Sub-agents

    Claude Sub-agents rely on LLM inference to decide when to delegate tasks, which sub-agent to spawn, and how to sequence work, leading to non-determinism. duckflux is a declarative, YAML-based workflow DSL that separates orchestration from execution. In duckflux, the execution order, retry logic, and quality gates are defined deterministically in configuration, while the LLM is used only for the creative work within each individual step.
  3. Overview of duckflux design principles

    duckflux is a runtime-agnostic workflow orchestration tool designed for simple, declarative specifications. Its core design principles include:

    • Readability: Flows should be understandable at a glance without indirection or implicit ordering.
    • Minimalism: Features are added only when necessary to resist complexity.
    • Convention over Configuration: Sensible defaults are provided; explicit overrides are used only when needed.
    • Unified Interface: All participants (scripts, HTTP calls, approvals, sub-workflows) follow a consistent "input in, output out" pattern.
    • String-based Communication: By default, participants exchange strings (similar to stdin/stdout), supporting plain text, JSON, XML, or binary.
    • Runtime Agnostic: The DSL defines what happens and in what order, while the runtime determines how it is executed.
    • Deterministic Flow: Execution order is explicit and predictable.
    • Standardized: Uses Google CEL for expressions, JSON Schema for data validation, and YAML for the specification format.
  4. Overview of duckflux for AI agent orchestration

    duckflux is a declarative, YAML-based workflow DSL designed to replace imperative bash loops for AI coding agents. It provides structured execution, observability, and composability. Key features include native loop constructs with CEL expressions for completion conditions, built-in retry and error handling, parallel execution without manual PID management, and structured execution tracing of all inputs and outputs.
  5. Overview of migrating from Ralph Orchestrator to duckflux

    Migrating from Ralph Orchestrator to duckflux involves moving from an event-driven, emergent flow model (where agents decide the execution path via event emission) to an explicit flow model (where the sequence is declared top-to-bottom). While Ralph uses 'hats' and 'typed events' to coordinate, duckflux uses a declarative YAML-based workflow DSL with explicit control flow constructs (loop, parallel, if, when) and an optional native event system (emit and wait) for asynchronous signaling.
  6. Use CEL expressions for dynamic values in duckflux workflows

    All dynamic values in duckflux workflows—including conditions, guard clauses, input mappings, and payload values—are written using the Common Expression Language (CEL). The runtime supports the full CEL standard library for strings, lists, maps, macros, type conversions, and timestamps.
    // String checks
    workflow.inputs.branch.startsWith("feat/")
    workflow.inputs.env == "production"
    
    // String concatenation
    "Bearer " + env.API_TOKEN
    
    // Collection checks
    reviewer.output.tags.size() > 0
    "admin" in reviewer.output.roles
    workflow.inputs.targets.filter(t, t.startsWith("prod"))
    
    // Type conversions
    int(reviewer.output.score)
    string(execution.number)
    timestamp(workflow.inputs.scheduledAt)
    
    // Timestamps and durations
    now >= timestamp("2026-06-01T09:00:00Z")
    execution.startedAt + duration("1h")
    deploy.finishedAt - deploy.startedAt
  7. Implement a hybrid orchestration approach

    The most effective architecture uses duckflux for deterministic orchestration (sequencing, retries, gating) while using Claude Sub-agents for the actual reasoning tasks. By calling claude --agent within a duckflux exec step, you maintain the sub-agent's isolated context and specialized prompts while gaining the reliability of a YAML-defined pipeline.
    participants:
      plan:
        type: exec
        run: claude --agent planner --print "$(cat SPEC.md)"
      code:
        type: exec
        run: claude --agent coder --print "Implement the plan in PLAN.md"
        onError: retry
        retry:
          max: 3
      test:
        type: exec
        run: npm test
      lint:
        type: exec
        run: npm run lint
      review:
        type: exec
        run: claude --agent reviewer --print "Review the implementation"
    flow:
      - plan
      - loop:
          until: review.output.approved == true
          max: 5
          steps:
            - code
            - test
            - lint
            - review
  8. Manage execution metadata and shared state

    The execution variable contains metadata about the current run. execution.context is the only writable shared state available across the workflow, which can be modified using the set construct.
    # Example: Using shared context for conditional logic
    flow:
      - loop:
          max: 5
          steps:
            - coder
            - reviewer:
                when: execution.context.lastScore < 8
  9. Understand duckflux data flow principles

    duckflux uses a "string by default, schema on demand" principle for data flow. Every participant receives and returns a string unless a schema is explicitly defined. This means workflows can function without any input/output configuration, and schemas (using JSON Schema syntax in YAML) are only added when validation or typed access is required.
  10. Use CEL expressions for dynamic workflow values

    All dynamic values in a duckflux workflow—including conditions, guard clauses, input mappings, and payload values—are written using Common Expression Language (CEL). CEL is a fast, safe expression language used for logic and data referencing at runtime.
  11. Implement multi-step branching with if/then/else

    The if block in duckflux evaluates a CEL expression to route execution. It supports a then branch (executed if true) and an optional else branch (executed if false). If the else branch is omitted and the condition is false, execution proceeds to the next step following the if block. Branches can contain multiple steps or nested control flow constructs.
    flow:
      - runTests
      - if:
          condition: runTests.output.passed == true
          then:
            - buildArtifact
            - if:
                condition: workflow.inputs.env == "production"
                then:
                  - deployProd
                else:
                  - deployStaging
            - notifySuccess
          else:
            - notifyFailure
            - openIssue
  12. Start the duckflux web server UI

    The quack server command launches a local development tool for executing and observing workflows visually. If @duckflux/server is not installed, the CLI will prompt to install it automatically using bun add @duckflux/server -D (or npm install).
    quack server [flags]
    
    # Example: Start with trace output directory
    quack server --trace-dir ./traces
    
    # Example: Custom workflow directory and port
    quack server --trace-dir ./traces --workflow-dir ./workflows --port 8080