Skip to content

Latest commit

 

History

History
584 lines (453 loc) · 16.5 KB

File metadata and controls

584 lines (453 loc) · 16.5 KB

workflow push — Deploy Workflows to Platform

Push local .workflow.yaml files to the Agents Platform, creating new workflows or updating existing ones using idempotent operations.

Usage

# Push a workflow file
workflow push my-workflow.workflow.yaml

# First push creates, subsequent pushes update
workflow push my-workflow.workflow.yaml  # Creates workflow
workflow push my-workflow.workflow.yaml  # Updates same workflow (idempotent)

Options

Option Short Description
FILE Path to .workflow.yaml file to push

How It Works

The push command follows a multi-stage workflow:

  1. Load & Validate — Loads YAML and runs all validation checks (same as workflow validate)
  2. Check Lockfile — Reads .workflow.lock to determine create vs. update mode
  3. Resolve Dependencies — Converts human-friendly names to UUIDs using a 3-tier strategy:
    1. UUID passthrough — if the value is already a UUID, use it as-is (no API call)
    2. Lockfile cache — if a previous push cached the mapping, reuse it (no API call)
    3. API lookup — query the platform for agent_nameagentId, knowledge_base_nameknowledgeBaseId
  4. Convert to API Payload — Transforms WDF format to platform API format
  5. Generate Layout — Auto-generates node positions for visual editor
  6. Push to Platform — Calls atomic save endpoint (single transaction)
  7. Write Lockfile — Saves .workflow.lock with server-assigned UUIDs

Lockfile (.workflow.lock)

The lockfile enables idempotent push operations by tracking:

  • workflow_id — Server-assigned workflow UUID
  • organization_id — Organization UUID
  • nodes — Mapping of node slug → server-assigned node UUID
  • edges — Mapping of edge "source→target" → server-assigned edge ID
  • dependencies — Cached name-to-UUID mappings for agents and knowledge bases (keys use agent:{name} or kb:{name} format)
  • pushed_at — Timestamp of last successful push
  • instance — Platform instance URL

Example lockfile:

# Auto-generated by workflow CLI. Do not edit manually.
version: 1
workflow_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
organization_id: 11111111-2222-3333-4444-555555555555
instance: https://api.sb.allogy.com
pushed_at: '2025-02-18T10:30:45.123456Z'
nodes:
  input: 22222222-3333-4444-5555-666666666666
  llm: 33333333-4444-5555-6666-777777777777
  output: 44444444-5555-6666-7777-888888888888
edges:
  input->llm: 10001
  llm->output: 10002
dependencies:
  agent:Customer Support Agent: 8cc8beec-11b2-4d35-a88b-424727111d6a
  kb:Company Policies: 6c26048d-2f9c-4177-a126-f2ed8cd02a0e

Lockfile behavior:

  • Lockfile is automatically created on first push
  • Lockfile is automatically updated on subsequent pushes
  • Lockfile should be committed to version control for team collaboration
  • Lockfile enables idempotent updates (same command creates or updates)

Dependency Resolution

The push command resolves human-friendly names (agent_name, knowledge_base_name, knowledge_base_names) to platform UUIDs using a 3-tier strategy (checked in order):

  1. UUID passthrough — If the value is already a valid UUID (e.g., e0b3bdc6-9fcb-45ee-8833-26aa5cd1d2e0), it is used directly. No API call is made.
  2. Lockfile cache — If a previous push already resolved this name and cached the UUID in the .workflow.lock file's dependencies section, the cached value is reused. No API call is made.
  3. API lookup — The platform API is queried to find the resource by name (case-insensitive). On failure, the error lists all available resources of that type in the organization.

Resolved mappings are automatically cached in the lockfile after each successful push, so subsequent pushes avoid redundant API calls.

Agent References

When your workflow uses agent nodes, you can reference agents by name:

Before resolution (in .workflow.yaml):

nodes:
  my_agent:
    type: agent
    execution_mode: MESSAGES
    label: My Agent
    config:
      agent_name: Customer Support Agent  # Human-friendly name
      primaryInput: "{{input.output.text}}"

After resolution (in API payload):

{
  "config": {
    "agentId": "a1b2c3d4-...",  // Resolved UUID
    "primaryInput": "{{<uuid>.output.text}}"
  }
}

Knowledge Base References

When your workflow uses retrieval nodes, you can reference knowledge bases by name:

Before resolution (in .workflow.yaml):

nodes:
  retrieval:
    type: retrieve
    execution_mode: FLOW
    label: Document Search
    config:
      knowledge_base_name: Company Policies  # Human-friendly name
      topK: 5
      scoreThreshold: 0.7

After resolution (in API payload):

{
  "config": {
    "knowledgeBaseId": "b2c3d4e5-...",  // Resolved UUID
    "topK": 5,
    "scoreThreshold": 0.7
  }
}

UUID Passthrough

If you already have a platform UUID (e.g., from a lockfile or the platform UI), you can use it directly in place of a name. The push command detects UUID strings and passes them through without making any API call:

nodes:
  my_agent:
    type: agent
    execution_mode: MESSAGES
    label: My Agent
    config:
      agent_name: e0b3bdc6-9fcb-45ee-8833-26aa5cd1d2e0  # UUID used as-is

This is useful for pinning a workflow to a specific resource or working in environments where name-based lookup is not desired.

Multiple Knowledge Bases

RAG agent nodes (rag_agent) can reference multiple knowledge bases using the knowledge_base_names list:

nodes:
  rag:
    type: rag_agent
    execution_mode: MESSAGES
    label: RAG Agent
    config:
      agent_name: Data Analyst Agent
      knowledge_base_names:         # List of KB references
        - Company Policies
        - Industry Standards

Each entry in the list is resolved independently using the same 3-tier strategy. You can also mix names and UUIDs within the list.

Variable References in Templates

Variable references use the format {{slug.output.field}} to access outputs from upstream nodes. The .output. delimiter and a specific field path are required — using just {{slug.output}} without a field will fail at runtime.

Structured Input Nodes (structured_input)

Structured input data is stored with each form field accessible at {{slug.output.field_name}}:

nodes:
  form:
    type: structured_input
    execution_mode: INPUT
    config:
      schema:
        type: object
        properties:
          name: { type: string }
          topic: { type: string }

  process:
    type: llm_call
    execution_mode: MESSAGES
    config:
      model: us.anthropic.claude-sonnet-4-20250514-v1:0
      # Correct: reference specific fields
      template: "Name: {{form.output.name}}\nTopic: {{form.output.topic}}"
      # WRONG: {{form.output}} — will fail with "Invalid reference format"

Retrieve / Vector Search Nodes (retrieve)

Retrieve node results are accessible at {{slug.output.results}} (array of documents):

nodes:
  search:
    type: retrieve
    execution_mode: FLOW
    config:
      knowledge_base_name: my_kb
      topK: 5
      searchQuery: "{{form.output.topic}}"

  summarize:
    type: llm_call
    execution_mode: MESSAGES
    config:
      model: us.anthropic.claude-sonnet-4-20250514-v1:0
      # Correct: reference the results array
      template: "Context: {{search.output.results}}\n\nSummarize the above."
      # WRONG: {{search.output}} — will fail with "Invalid reference format"

Common Output Fields by Node Type

Node Type Primary Output Path Description
structured_input {{slug.output.field_name}} Individual form fields
plain_txt_input {{slug.output.text}} Text content
llm_call {{slug.output.text}} Generated text
agent {{slug.output.response}} Agent response text
retrieve {{slug.output.results}} Retrieved documents array
structured_output {{slug.output.structured}} Structured JSON output
file_upload {{slug.output.text}} Extracted text from files

Resolution Errors

If an agent or knowledge base cannot be found, the push fails with a helpful error listing available alternatives:

Cannot resolve agent 'Customer Support Agent'. Available agents: Data Analyst Agent, Code Assistant Agent, OpenAI Test Agent
Cannot resolve knowledge base 'Company Policies'. Available knowledge bases: standards, industry, whitelisted

If no resources of that type exist in the organization:

Cannot resolve agent 'My Agent'. No agents available in this organization.

Node Layout Generation

The push command auto-generates node positions for the visual workflow editor using a simple vertical layout algorithm:

  • Entry nodes at top (y=100)
  • Subsequent nodes spaced vertically (y += 150)
  • All nodes horizontally centered (x=200)

This ensures workflows are immediately viewable in the platform's visual editor without manual positioning.

Create vs. Update Mode

The push command automatically detects whether to create or update based on lockfile presence:

Create Mode (No Lockfile)

# First push - no lockfile exists
workflow push customer-support.workflow.yaml

# Output:
# ✓ Loaded workflow: Customer Support Workflow
# ✓ Validation passed (all checks passed)
# ✓ Resolved dependencies: 1 agent, 0 knowledge bases
# ✓ Pushed workflow (created)
# ✓ Lockfile saved: customer-support.workflow.lock

Update Mode (Lockfile Exists)

# Subsequent push - lockfile exists
workflow push customer-support.workflow.yaml

# Output:
# ✓ Loaded workflow: Customer Support Workflow
# ✓ Validation passed (all checks passed)
# ✓ Resolved dependencies: 1 agent, 0 knowledge bases
# ✓ Pushed workflow (updated: a1b2c3d4-...)
# ✓ Lockfile updated: customer-support.workflow.lock

Configuration

The push command requires CLI configuration (same as other commands):

Environment variables:

export WORKFLOW_API_HOST=https://api.sb.allogy.com
export WORKFLOW_API_KEY=your-api-key
export WORKFLOW_ORG_ID=your-org-uuid
# Optional: send a user JWT as a Bearer token for endpoints that reject
# API-key auth (e.g. workflow creation on some environments).
export WORKFLOW_JWT=your-jwt-access-token

Or config file (~/.workflow/config.yaml):

host: https://api.sb.allogy.com
api_key: your-api-key
org_id: your-org-uuid

Or CLI flags:

workflow push my-workflow.workflow.yaml \
  --host https://api.sb.allogy.com \
  --api-key your-api-key \
  --org your-org-uuid

See README.md for full configuration details.

Examples

Simple Workflow (No Dependencies)

# Create workflow file
workflow init --template text-to-agent -o simple.workflow.yaml

# Push to platform
workflow push simple.workflow.yaml

# Output:
# ✓ Loaded workflow: Text to Agent
# ✓ Validation passed
# ✓ Pushed workflow (created)
# ✓ Lockfile saved: simple.workflow.lock

Workflow with Agent Reference

# customer-support.workflow.yaml
name: Customer Support
nodes:
  input:
    type: plain_txt_input
    execution_mode: INPUT
    config:
      placeholder: Enter customer question
  agent:
    type: agent
    execution_mode: MESSAGES
    config:
      agent_name: Customer Support Agent  # Resolved automatically
      primaryInput: "{{input.output.text}}"
edges:
  - from: input
    to: agent
entry: input
exit: agent
# Push resolves agent_name to UUID automatically
workflow push customer-support.workflow.yaml

# Output:
# ✓ Loaded workflow: Customer Support
# ✓ Validation passed
# ✓ Resolved dependencies: 1 agent
# ✓ Pushed workflow (created)

Workflow with Knowledge Base Reference

# document-qa.workflow.yaml
name: Document Q&A
nodes:
  input:
    type: plain_txt_input
    execution_mode: INPUT
    config:
      placeholder: Ask a question
  retrieval:
    type: retrieve
    execution_mode: FLOW
    config:
      knowledge_base_name: Company Policies  # Resolved automatically
      topK: 5
  llm:
    type: llm_call
    execution_mode: MESSAGES
    config:
      model: anthropic.claude-3-5-sonnet-20241022-v2:0
      template: "Context: {{retrieval.output.text}}\n\nQuestion: {{input.output.text}}"
edges:
  - from: input
    to: retrieval
  - from: retrieval
    to: llm
entry: input
exit: llm
# Push resolves knowledge_base_name to UUID automatically
workflow push document-qa.workflow.yaml

# Output:
# ✓ Loaded workflow: Document Q&A
# ✓ Validation passed
# ✓ Resolved dependencies: 0 agents, 1 knowledge base
# ✓ Pushed workflow (created)

Update Workflow

# Edit workflow file
vim customer-support.workflow.yaml

# Push updates (lockfile determines update mode)
workflow push customer-support.workflow.yaml

# Output:
# ✓ Loaded workflow: Customer Support (updated)
# ✓ Validation passed
# ✓ Resolved dependencies: 1 agent
# ✓ Pushed workflow (updated: a1b2c3d4-...)
# ✓ Lockfile updated

Error Handling

Validation Errors

Push command runs full validation before any API calls:

workflow push broken-workflow.workflow.yaml

# Output:
# ✗ Validation failed: Cycle detected: a -> b -> a
# Push aborted (fix validation errors first)

Fix: Run workflow validate to see all validation errors, then fix them.

Dependency Resolution Errors

workflow push customer-support.workflow.yaml

# Output:
# ✓ Loaded workflow: Customer Support
# ✓ Validation passed
# ✗ Cannot resolve agent 'Customer Support Agent'. Available agents: Data Analyst Agent, Code Assistant Agent
# Push aborted

Fix: Ensure the agent or knowledge base name matches an existing resource in your organization. Use workflow push to see the list of available alternatives in the error message. You can also use a UUID directly instead of a name to bypass the lookup.

API Errors

workflow push my-workflow.workflow.yaml

# Output:
# ✓ Loaded workflow: My Workflow
# ✓ Validation passed
# ✓ Resolved dependencies
# ✗ API Error: 403 Forbidden - Insufficient permissions

Fix: Check your API key permissions, ensure you have write access to workflows in your organization.

Network Errors

workflow push my-workflow.workflow.yaml

# Output:
# ✓ Loaded workflow: My Workflow
# ✓ Validation passed
# ✗ Network Error: Connection timeout
# Push aborted (workflow not created)

Fix: Check your network connection and platform instance URL.

Integration with Other Commands

Complete Workflow

# 1. Scaffold from template
workflow init --template rag-qa -o qa.workflow.yaml

# 2. Validate before push
workflow validate qa.workflow.yaml

# 3. Push to platform
workflow push qa.workflow.yaml

# 4. Update and re-push
vim qa.workflow.yaml
workflow validate qa.workflow.yaml
workflow push qa.workflow.yaml

CI/CD Pipeline

#!/bin/bash
# .github/workflows/deploy-workflows.sh

set -e

# Validate all workflows
for workflow in workflows/*.workflow.yaml; do
  echo "Validating $workflow..."
  uv run workflow validate "$workflow"
done

# Push all workflows
for workflow in workflows/*.workflow.yaml; do
  echo "Pushing $workflow..."
  uv run workflow push "$workflow"
done

echo "All workflows deployed successfully!"

Best Practices

  1. Always validate before pushing — Catch errors early with workflow validate
  2. Commit lockfiles to version control — Track workflow UUIDs alongside code
  3. Use descriptive names for dependencies — Makes workflows more readable
  4. Test in dev environment first — Use separate API keys for dev/staging/prod
  5. Review lockfile after first push — Verify workflow_id matches expected org

Troubleshooting

Lockfile Out of Sync

If lockfile references a workflow that was deleted on the platform:

# Delete lockfile to force create mode
rm my-workflow.workflow.lock

# Push creates new workflow
workflow push my-workflow.workflow.yaml

Multiple Organizations

When working with multiple organizations, use CLI flags or separate config files:

# Push to org A
workflow push --org org-a-uuid my-workflow.workflow.yaml

# Push to org B
workflow push --org org-b-uuid my-workflow.workflow.yaml

Reference

  • Jira Ticket: RAG-951 (Push Command), RAG-949 (Lockfile Management), RAG-950 (Dependency Resolution)
  • Related Commands: workflow validate, workflow init
  • Lockfile Format: See src/cli/lockfile.py for schema
  • API Endpoint: POST /api/v1/workflows/complete (atomic save)
  • WDF Schema: See docs/validate-command.md for node types