TurfAITurfAI Developers
Api_syncedReference

TurfAI Task Types Reference

Synced from the source repositories. Do not edit by hand.

Complete reference for all available task types in TurfAI workflows.


Overview

Task types are the building blocks of TurfAI workflows. Each task type performs a specific operation and can be connected to form complex automation pipelines.

API Endpoint: GET /api/workflows/task-types


Categories

CategoryDescriptionTask Types
AI OperationsML-powered document processingclassification, extraction, llm, summarization, classify_and_extract, rag_enable, rag_query
Google IntegrationsGoogle Drive/Gmail operationsgoogle_drive_fetch
External IntegrationsHTTP API callsrest_api
CommunicationEmail/notificationsemail_send
Workflow ControlFlow control primitivesdecision, wait

Core Integration Tasks

These are the most commonly used task types for workflow integrations.


google_drive_fetch_task

Fetch files from Google Drive and import to GCS.

Processor: google_drive_fetch

Use Cases:

  • Fetch job descriptions from shared folders
  • Download resumes submitted via forms
  • Import policy documents for RAG indexing

Configuration

{
  "task_type": "google_drive_fetch_task",
  "config": {
    "file_id": "1ABC123xyz"
  }
}

Config Options:

FieldTypeRequiredDescription
file_idstringOne ofDirect Google Drive file ID
folder_idstringOne ofFolder ID for search mode
file_namestringWith folder_idFile name to search for

Modes:

  1. Direct: Provide file_id to fetch specific file
  2. Search: Provide folder_id + file_name to find file in folder

Output

{
  "file_url": "gs://turfdms/documents/123/file.pdf",
  "file_id": "1ABC123xyz",
  "file_name": "Resume_JohnDoe.pdf",
  "mime_type": "application/pdf",
  "size": 245789,
  "document_id": 123
}

Example Node

{
  "id": "fetch-resume",
  "type": "google_drive_fetch_task",
  "data": {
    "label": "Fetch Resume from Drive",
    "task_type": "google_drive_fetch_task",
    "config": {
      "file_id": "{{resume_file_id}}"
    }
  }
}

rest_api_task

Make HTTP requests to external APIs with template variable support.

Processor: rest_api

Use Cases:

  • Fetch configuration from external services
  • Post results to external systems
  • Integrate with third-party APIs
  • Call internal TurfAI endpoints

Configuration

{
  "task_type": "rest_api_task",
  "config": {
    "url": "http://localhost:9005/roles/{{role_id}}",
    "method": "GET",
    "timeout": 30,
    "output_mapping": {
      "jd_file_id": "$.data.jd_file_id",
      "hiring_manager_email": "$.data.hiring_manager_email"
    }
  }
}

Config Options:

FieldTypeRequiredDefaultDescription
urlstringYes-API URL (supports {{variable}} templates)
methodstringNoGETHTTP method
headersobjectNo{}Request headers (supports templates)
bodyobjectNo-Request body for POST/PUT/PATCH
timeoutnumberNo30Timeout in seconds
output_mappingobjectNo-JSONPath mappings for response extraction

Template Variables

URLs, headers, and body values support {{variable}} syntax:

{
  "url": "https://api.example.com/users/{{user_id}}/documents",
  "headers": {
    "Authorization": "Bearer {{api_token}}"
  },
  "body": {
    "name": "{{candidate_name}}",
    "email": "{{email}}"
  }
}

Output Mapping (JSONPath)

Extract specific fields from the response:

{
  "output_mapping": {
    "extracted_name": "$.data.user.name",
    "first_item": "$.items[0].id",
    "nested_value": "$.response.metadata.count"
  }
}

Output

{
  "data": {
    "jd_file_id": "1ABC123xyz",
    "hiring_manager_email": "manager@company.com"
  },
  "status_code": 200,
  "_raw_response": { ... }
}

Example: Fetch Role Configuration

{
  "id": "fetch-role-config",
  "type": "rest_api_task",
  "data": {
    "label": "Fetch Role Configuration",
    "task_type": "rest_api_task",
    "config": {
      "url": "http://localhost:9005/roles/{{role_id}}",
      "method": "GET",
      "output_mapping": {
        "jd_file_id": "$.data.jd_file_id",
        "hiring_manager_email": "$.data.hiring_manager_email",
        "hr_email": "$.data.hr_email"
      }
    }
  }
}

email_send_task

Send emails with HTML support and template variables.

Processor: email_send

Use Cases:

  • Send job match notifications
  • Deliver workflow results
  • Send policy update confirmations
  • Notify stakeholders

Configuration

{
  "task_type": "email_send_task",
  "config": {
    "to": ["{{hiring_manager_email}}", "hr@company.com"],
    "cc": ["{{recruiter_email}}"],
    "subject": "New Application: {{candidate_name}} for {{position}}",
    "body": "<h2>Application Received</h2><p>Candidate: {{candidate_name}}</p><p>Match Score: {{match_score}}%</p>",
    "html": true
  }
}

Config Options:

FieldTypeRequiredDefaultDescription
fromstringNoSystem defaultSender email
toarrayYes-Recipient emails (supports templates)
ccarrayNo[]CC recipients
bccarrayNo[]BCC recipients
subjectstringYes-Email subject (supports templates)
bodystringYes-Email body (supports templates)
htmlbooleanNotrueSend as HTML

Output

{
  "sent": true,
  "recipients": ["manager@company.com", "hr@company.com"],
  "timestamp": "2024-11-24T10:30:00.000Z"
}

Example: Notification Email

{
  "id": "send-notification",
  "type": "email_send_task",
  "data": {
    "label": "Send Match Notification",
    "task_type": "email_send_task",
    "config": {
      "to": ["{{hiring_manager_email}}"],
      "subject": "New Application Match: {{candidate_name}}",
      "body": "<h2>New Job Application</h2><p><strong>Candidate:</strong> {{candidate_name}}</p><p><strong>Position:</strong> {{position}}</p><p><strong>Match Score:</strong> {{match_score}}%</p><h3>Summary</h3><p>{{ai_summary}}</p>",
      "html": true
    }
  }
}

wait_task

Poll an endpoint until a condition is met. Generic async wait primitive.

Processor: wait

Use Cases:

  • Wait for RAG indexing to complete
  • Poll external job status
  • Wait for approval workflows
  • Monitor async processing

Configuration

{
  "task_type": "wait_task",
  "config": {
    "endpoint": "/api/internal/documents/{{document_id}}/rag-status",
    "method": "GET",
    "watch_field": "rag_processing_status",
    "success_value": "completed",
    "failure_values": ["failed", "error"],
    "poll_interval": 3,
    "timeout": 120
  }
}

Config Options:

FieldTypeRequiredDefaultDescription
endpointstringYes-URL to poll (supports templates)
methodstringNoGETHTTP method
watch_fieldstringYes-Field to monitor (dot notation supported)
success_valuestringNo"completed"Value indicating success
failure_valuesarrayNo["failed", "error"]Values indicating failure
poll_intervalnumberNo3Seconds between polls
timeoutnumberNo120Maximum wait time in seconds

Output

{
  "status": "success",
  "final_value": "completed",
  "response": { ... },
  "elapsed_seconds": 45
}

Example: Wait for RAG Indexing

{
  "id": "wait-for-rag",
  "type": "wait_task",
  "data": {
    "label": "Wait for RAG Completion",
    "task_type": "wait_task",
    "config": {
      "endpoint": "/api/internal/documents/{{document_id}}/rag-status",
      "watch_field": "rag_processing_status",
      "success_value": "completed",
      "failure_values": ["failed"],
      "poll_interval": 5,
      "timeout": 300
    }
  }
}

AI Operations Tasks


classification_task

Classify documents into categories using AI.

Processor: classification

Configuration

FieldTypeDefaultDescription
classification_typestring"document_type"Type: document_type, sentiment, topic
include_confidencebooleantrueInclude confidence scores
return_multiplebooleanfalseReturn multiple classifications

Input

FieldTypeRequiredDescription
file_urlstringYesGCS URL of document
metadataobjectNoAdditional context

Output

{
  "prompt_title": "Resume Classification",
  "section": "HR Documents",
  "confidence": 0.95,
  "classification": {
    "type": "resume",
    "subtype": "technical"
  }
}

extraction_task

Extract structured data from documents.

Processor: document_extraction

Configuration

FieldTypeDefaultDescription
prompt_idstring-Prompt ID to use
model_typestring"vertex"LLM: vertex, openai, anthropic
output_formatstring"json"Output: json, text
use_classification_promptbooleanfalseUse prompt from classification

Input

FieldTypeRequiredDescription
file_urlstringYesGCS URL of document
prompt_dataobjectNoPrompt override

Output

{
  "extraction_result": {
    "name": "John Doe",
    "email": "john@example.com",
    "skills": ["Python", "Machine Learning"],
    "experience_years": 5
  },
  "confidence": 0.92,
  "tokens_used": 1250
}

llm_task

Generic LLM-powered text processing.

Processor: llm_task

Configuration

FieldTypeDefaultDescription
prompt_idstring-Use predefined prompt
prompt_textstring-Custom prompt text
model_typestring"vertex"LLM provider
process_combined_inputsbooleantrueCombine all inputs
output_formatstring"json"Output format

Input

FieldTypeRequiredDescription
file_urlstringNoDocument URL
prompt_dataobjectNoPrompt variables
text_inputstringNoDirect text input

Output

{
  "result": { ... },
  "tokens_used": 850
}

summarization_task

Generate document summaries.

Processor: summarization

Configuration

FieldTypeDefaultDescription
summary_typestring"brief"Type: brief, detailed, bullet_points
max_lengthnumber500Max words

Output

{
  "summary": "This resume belongs to a senior software engineer with 5 years of experience in Python and machine learning...",
  "word_count": 150
}

classify_and_extract

Combined classification and extraction in one step.

Processor: classify_and_extract

Configuration

FieldTypeDefaultDescription
classification_typestring"document_type"Classification type
extract_after_classifybooleantrueRun extraction after

Output

{
  "classification": {
    "type": "resume",
    "confidence": 0.95
  },
  "extraction_result": {
    "name": "John Doe",
    "skills": ["Python", "ML"]
  }
}

rag_enable_task

Enable RAG indexing for a document.

Processor: rest_api (calls internal endpoint)

Configuration

Default configuration calls /api/internal/rag/enable:

{
  "url": "http://localhost:1338/api/internal/rag/enable",
  "method": "POST",
  "body": {
    "document_id": "{{document_id}}",
    "user_id": "{{user_id}}",
    "force_reprocess": false
  }
}

Input

FieldTypeRequiredDescription
document_idnumberYesFrom previous node (e.g., drive fetch)
user_idnumberYesFrom workflow context

Output

{
  "rag_status": "queued",
  "rag_job_id": "rag-embed-123-1700000000"
}

rag_query_task

Query the RAG knowledge base.

Processor: rest_api (calls internal endpoint)

Configuration

Default configuration calls /api/internal/rag/query:

{
  "url": "http://localhost:1338/api/internal/rag/query",
  "method": "POST",
  "body": {
    "query": "{{query}}",
    "user_id": "{{user_id}}",
    "top_k": 5
  }
}

Input

FieldTypeRequiredDescription
querystringYesSearch query
user_idnumberYesFrom workflow context

Output

{
  "answer": "According to the Remote Work Policy document, employees can work remotely up to 3 days per week...",
  "sources": [
    {
      "document_id": 45,
      "document_name": "Remote Work Policy.pdf",
      "snippet": "...employees may work from home up to three days...",
      "score": 0.92
    }
  ],
  "session_id": "sess-abc123"
}

Workflow Examples

F1: Job Application Notification

{
  "nodes": [
    {
      "id": "1",
      "type": "rest_api_task",
      "data": {
        "label": "Fetch Role Config",
        "config": {
          "url": "http://localhost:9005/roles/{{role_id}}",
          "output_mapping": {
            "jd_file_id": "$.data.jd_file_id",
            "hiring_manager_email": "$.data.hiring_manager_email"
          }
        }
      }
    },
    {
      "id": "2",
      "type": "google_drive_fetch_task",
      "data": {
        "label": "Fetch JD",
        "config": { "file_id": "{{jd_file_id}}" }
      }
    },
    {
      "id": "3",
      "type": "google_drive_fetch_task",
      "data": {
        "label": "Fetch Resume",
        "config": { "file_id": "{{resume_file_id}}" }
      }
    },
    {
      "id": "4",
      "type": "extraction_task",
      "data": {
        "label": "Extract Resume",
        "config": { "output_format": "json" }
      }
    },
    {
      "id": "5",
      "type": "llm_task",
      "data": {
        "label": "Calculate Match",
        "config": {
          "prompt_text": "Compare this resume to the job description and provide a match score..."
        }
      }
    },
    {
      "id": "6",
      "type": "email_send_task",
      "data": {
        "label": "Notify Hiring Manager",
        "config": {
          "to": ["{{hiring_manager_email}}"],
          "subject": "New Application: {{candidate_name}}",
          "body": "<h2>Match Score: {{match_score}}%</h2>..."
        }
      }
    }
  ]
}

F4-A: HR Policy Ingestion

{
  "nodes": [
    {
      "id": "1",
      "type": "google_drive_fetch_task",
      "data": {
        "label": "Fetch Policy Doc",
        "config": { "file_id": "{{policy_file_id}}" }
      }
    },
    {
      "id": "2",
      "type": "rag_enable_task",
      "data": {
        "label": "Enable RAG"
      }
    },
    {
      "id": "3",
      "type": "wait_task",
      "data": {
        "label": "Wait for Indexing",
        "config": {
          "endpoint": "/api/internal/documents/{{document_id}}/rag-status",
          "watch_field": "rag_processing_status",
          "success_value": "completed",
          "timeout": 300
        }
      }
    },
    {
      "id": "4",
      "type": "email_send_task",
      "data": {
        "label": "Send Confirmation",
        "config": {
          "to": ["{{notification_email}}"],
          "subject": "Policy Indexed: {{policy_name}}",
          "body": "The policy document has been indexed and is now searchable."
        }
      }
    }
  ]
}

F4-B: Employee Q&A

{
  "nodes": [
    {
      "id": "1",
      "type": "rag_query_task",
      "data": {
        "label": "Query Knowledge Base",
        "config": {
          "body": {
            "query": "{{question}}",
            "user_id": "{{user_id}}",
            "top_k": 5
          }
        }
      }
    },
    {
      "id": "2",
      "type": "email_send_task",
      "data": {
        "label": "Send Answer",
        "config": {
          "to": ["{{employee_email}}"],
          "subject": "Answer to your question",
          "body": "<p>{{answer}}</p><h3>Sources</h3>{{sources}}"
        }
      }
    }
  ]
}

Template Variables

All task types support {{variable}} template syntax for dynamic values.

Sources of Variables

  1. Webhook Payload: Data sent to trigger endpoint
  2. Previous Node Outputs: Results from upstream nodes
  3. Workflow Context: user_id, execution_id, etc.

Example Flow

Webhook payload: { "candidate_name": "John", "role_id": "engineer" }

Node 1 (rest_api_task): Uses {{role_id}} → outputs { "jd_file_id": "ABC123" }

Node 2 (google_drive_fetch_task): Uses {{jd_file_id}} → outputs { "file_url": "gs://..." }

Node 3 (email_send_task): Uses {{candidate_name}}, {{file_url}}

Error Handling

Task Failure

When a task fails, the workflow execution status becomes failed:

{
  "status": "failed",
  "error": "REST API call failed: 404 Not Found",
  "failed_node": "fetch-role-config",
  "task_states": {
    "fetch-role-config": {
      "status": "failed",
      "error": "404 Not Found"
    }
  }
}

Timeout Handling

The wait_task returns failure status on timeout:

{
  "status": "failure",
  "final_value": "processing",
  "elapsed_seconds": 120,
  "error": "Timeout waiting for completion"
}

Control Flow Tasks

decision

NEW in v1.1 - Conditional branching based on runtime evaluation.

Evaluates a condition and directs workflow execution down one of two paths (true or false). Enables dynamic workflow behavior based on previous task outputs.

Processor: decision (alias: decision_task)

Use Cases:

  • Route documents based on classification results
  • Handle different document types with separate processing paths
  • Conditional approval workflows
  • Dynamic email routing based on content analysis
  • Skip processing steps based on validation results

Configuration

{
  "task_type": "decision",
  "config": {
    "operator": "==",
    "left_operand": "$.classification.type",
    "right_operand": "Invoice",
    "true_label": "true",
    "false_label": "false"
  }
}

Config Options:

FieldTypeRequiredDescription
operatorstringYesComparison operator: ==, !=, >, <, >=, <=, in, contains, matches
left_operandstringYesJSONPath expression (e.g., $.classification.type) or literal value
right_operandstring/number/booleanYesValue to compare against (can be literal or JSONPath)
true_labelstringNoLabel for true path (default: "true")
false_labelstringNoLabel for false path (default: "false")

Supported Operators:

OperatorDescriptionExample
==Equals$.type == "Invoice"
!=Not equals$.status != "processed"
>Greater than$.amount > 1000
<Less than$.confidence < 0.8
>=Greater or equal$.score >= 90
<=Less or equal$.priority <= 5
inLeft in right (array/string)"pdf" in $.allowed_types
containsRight in left (array/string)$.tags contains "urgent"
matchesRegex match$.email matches ".*@company.com"

JSONPath Support

Use JSONPath expressions to reference outputs from previous tasks:

$.task_name.field_name

Examples:

  • $.classification.type - Access classification result
  • $.extraction.invoice_amount - Access extracted field
  • $.email.to - Access email configuration
  • Literal values: "Invoice", 1000, true

Output

{
  "result": true,
  "branch": "true",
  "decision": "true",
  "active_path": "true",
  "condition": {
    "operator": "==",
    "left_operand": "$.classification.type",
    "right_operand": "Invoice",
    "left_value": "Invoice",
    "right_value": "Invoice"
  }
}

Output Fields:

FieldTypeDescription
resultbooleanCondition evaluation result
branchstringSelected branch label
decisionstring"true" or "false"
active_pathstringPath taken by execution
conditionobjectDetails about evaluated condition

Edge Configuration

Decision nodes MUST have exactly 2 outgoing edges:

  1. True Edge: Label = "true" (or custom true_label)
  2. False Edge: Label = "false" (or custom false_label)

Frontend: When connecting edges from a decision node:

  1. Click the edge to select it
  2. Set the edge label property to "true" or "false"
  3. The workflow executor uses this label to activate/deactivate paths

Example: Document Type Routing

{
  "nodes": [
    {
      "id": "classify",
      "type": "classification_task",
      "data": {
        "label": "Classify Document",
        "task_type": "classification_task",
        "config": {
          "category": "document_type"
        }
      }
    },
    {
      "id": "decision",
      "type": "decision",
      "data": {
        "label": "Is Invoice?",
        "task_type": "decision",
        "config": {
          "operator": "==",
          "left_operand": "$.classify.type",
          "right_operand": "Invoice"
        }
      }
    },
    {
      "id": "process-invoice",
      "type": "extraction_task",
      "data": {
        "label": "Extract Invoice Data",
        "task_type": "extraction_task",
        "config": {
          "prompt_id": 42
        }
      }
    },
    {
      "id": "process-other",
      "type": "summarization_task",
      "data": {
        "label": "Summarize Document",
        "task_type": "summarization_task",
        "config": {
          "type": "brief"
        }
      }
    }
  ],
  "edges": [
    { "source": "classify", "target": "decision" },
    {
      "source": "decision",
      "target": "process-invoice",
      "sourceHandle": "true",
      "label": "true"
    },
    {
      "source": "decision",
      "target": "process-other",
      "sourceHandle": "false",
      "label": "false"
    }
  ]
}

Workflow Execution Behavior

  1. Decision node executes - Evaluates condition
  2. Edge activation - Marks one edge as active based on result
  3. Path execution - Only nodes on active path execute
  4. Skipped nodes - Nodes on inactive path get status: "skipped"
  5. Convergence - Paths can merge back together downstream

Important: The workflow remains a DAG (Directed Acyclic Graph). Decision nodes create diverging paths, not loops.

Advanced Examples

Numeric Comparison:

{
  "operator": ">",
  "left_operand": "$.extraction.invoice_amount",
  "right_operand": "10000"
}

Array Contains:

{
  "operator": "contains",
  "left_operand": "$.classification.tags",
  "right_operand": "urgent"
}

Regex Match:

{
  "operator": "matches",
  "left_operand": "$.extraction.email",
  "right_operand": ".*@approved-domain\\.com$"
}

Nested Field Access:

{
  "operator": "==",
  "left_operand": "$.rest_api.response.data.status",
  "right_operand": "approved"
}

Validation Rules

Backend validation (workflow-validation.js) enforces:

  1. Decision nodes must have exactly 2 outgoing edges
  2. Both edges must have labels
  3. One edge must be labeled "true", one "false"
  4. Config must include: operator, left_operand, right_operand

Validation errors will prevent workflow execution.

Frontend Component

  • Node Type: Diamond-shaped with orange gradient
  • Handles:
    • Top: Target (incoming)
    • Left: Source (true path, green)
    • Right: Source (false path, red)
  • Config Panel: Dropdown operators, JSONPath hints, condition preview

Limitations (Phase 1)

  • ⚠️ No loops: Workflow must remain acyclic (no cycles allowed)
  • ⚠️ Binary branches: Only true/false (multi-way branching not supported)
  • ⚠️ Simple conditions: No AND/OR/NOT logic (single comparison only)

Workaround for complex conditions: Chain multiple decision nodes


See Also

On this page