Skip to content

Defining Workflows

Workflows in Adaptive Sentience are policy-enforced execution contracts that orchestrate tool calls across distributed edge nodes.


What is a Workflow?

A workflow is a structured sequence of tool invocations with:

  • Clear input/output contracts (JSON schemas)
  • Policy enforcement (privacy, validation, constraints)
  • Execution path tracking (audit trail)
  • Failover and retry (resilience)

Workflows are not arbitrary code. They are declarative compositions of pre-defined tools.


Workflow Structure

Basic Workflow

{
  "workflow_id": "feedback_safe_summary",
  "steps": [
    {
      "step_id": "validate",
      "tool_name": "validate_schema",
      "tool_args": {
        "data": "{{input.feedback}}",
        "schema": "feedback_v1"
      },
      "required_capabilities": ["tool:validate_schema"]
    },
    {
      "step_id": "redact",
      "tool_name": "pii_redact",
      "tool_args": {
        "text": "{{steps.validate.output.data}}"
      },
      "required_capabilities": ["tool:pii_redact"]
    },
    {
      "step_id": "summarize",
      "tool_name": "summarize",
      "tool_args": {
        "text": "{{steps.redact.output.redacted_text}}"
      },
      "required_capabilities": ["tool:summarize"]
    }
  ],
  "policies": ["privacy_strict", "schema_strict"]
}

Workflow Components

1. Steps

Each step represents a single tool invocation:

{
  "step_id": "unique_identifier",
  "tool_name": "tool_to_execute",
  "tool_args": { /* input arguments */ },
  "required_capabilities": ["tool:name"],
  "target": { "kind": "local" },  // Optional: specific node
  "retry": { "max_attempts": 3, "backoff_ms": 1000 }
}

Fields:

  • step_id: Unique identifier for referencing in later steps
  • tool_name: Name of the tool to execute
  • tool_args: Input arguments (can reference previous steps)
  • required_capabilities: Capabilities needed to execute
  • target: (Optional) Node targeting strategy
  • retry: (Optional) Retry configuration

2. Variable References

Steps can reference:

  • Input data: {{input.field_name}}
  • Previous step outputs: {{steps.step_id.output.field_name}}
  • Environment variables: {{env.VAR_NAME}}

Example:

{
  "tool_args": {
    "text": "{{steps.redact.output.redacted_text}}",
    "max_length": "{{input.summary_length}}"
  }
}

3. Policies

Policies enforce constraints across the workflow:

{
  "policies": [
    "privacy_strict",      // Require PII redaction before summarization
    "schema_strict",       // Validate all inputs/outputs
    "offline_capable",     // Must work without internet
    "audit_full"          // Complete execution trace
  ]
}

See Policy Enforcement for details.


Execution Flow

1. Workflow Submission

curl -X POST http://127.0.0.1:8787/v1/orchestrate \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "feedback_safe_summary",
    "input": {
      "feedback": "Contact me at john@example.com"
    }
  }'

2. Planning Phase

The orchestrator:

  1. Validates workflow definition
  2. Checks policies can be satisfied
  3. Resolves tool availability
  4. Plans execution order

3. Execution Phase

For each step:

  1. Resolve variable references
  2. Check capability tokens
  3. Target appropriate node(s)
  4. Execute tool with retries
  5. Verify output schema
  6. Record execution evidence

4. Result Aggregation

{
  "ok": true,
  "verified": true,
  "result": {
    "summary": "User requesting contact information"
  },
  "execution_path": ["local:abc123", "local:def456"],
  "degraded": false,
  "trace_id": "trace-2024-01-27-xyz"
}

Natural Language Workflows

Use the UX CLI to define workflows in plain English:

python3 ux/ux_nl_cli.py --text \
  "Redact PII and summarize: Contact me at john@example.com"

The planner:

  1. Parses natural language intent
  2. Generates workflow definition
  3. Logs chain-of-thought reasoning
  4. Executes the workflow
  5. Returns human-readable results

Chain-of-Thought Logging

Internal reasoning is logged to audit/audit.log:

{
  "timestamp": "2024-01-27T10:30:00Z",
  "trace_id": "trace-xyz",
  "cot": "User provided text with PII. First redact, then summarize.",
  "plan": ["validate", "pii_redact", "summarize"]
}

This enables auditability without exposing sensitive reasoning in API responses.


Workflow Examples

Example 1: Field Report Pipeline

{
  "workflow_id": "field_report_privacy_pipeline",
  "steps": [
    {
      "step_id": "validate",
      "tool_name": "validate_schema",
      "tool_args": {
        "data": "{{input.report}}",
        "schema": "hipaa_field_report"
      }
    },
    {
      "step_id": "redact",
      "tool_name": "pii_redact",
      "tool_args": {
        "text": "{{steps.validate.output.data}}"
      }
    },
    {
      "step_id": "summarize",
      "tool_name": "summarize",
      "tool_args": {
        "text": "{{steps.redact.output.redacted_text}}"
      }
    }
  ],
  "policies": ["privacy_strict", "schema_strict", "audit_full"]
}

Example 2: Unit Conversion

{
  "workflow_id": "unit_convert_demo",
  "steps": [
    {
      "step_id": "convert",
      "tool_name": "unit_convert",
      "tool_args": {
        "value": "{{input.value}}",
        "from_unit": "{{input.from_unit}}",
        "to_unit": "{{input.to_unit}}"
      }
    }
  ],
  "policies": []
}

Best Practices

1. Keep Steps Atomic

Each step should do one thing:

Good: Separate validate, redact, summarize steps ❌ Bad: Single "process_feedback" mega-tool

2. Use Explicit Schemas

Define clear input/output contracts:

{
  "input_schema": {
    "type": "object",
    "properties": {
      "feedback": { "type": "string" }
    },
    "required": ["feedback"]
  }
}

3. Enforce Policies

Don't rely on developer discipline—enforce at runtime:

{
  "policies": [
    "privacy_strict",  // Blocks unredacted PII in summaries
    "schema_strict"    // Validates all inputs
  ]
}

4. Plan for Failure

Configure retries and fallbacks:

{
  "retry": {
    "max_attempts": 3,
    "backoff_ms": 1000
  },
  "fallback": {
    "on_failure": "use_cached_result"
  }
}

Next Steps