AI API

Prefix: /api/v1/ai Authentication: Not required (public route)


Table of Contents

  1. POST /ai/generate
  2. POST /ai/chat

1. Generate

Generate code, payloads, or configurations using AI models.

POST /api/v1/ai/generate

Description

Loads the chat catalog item identified by chat_laui, extracts its codeblock (the AI module) and connection (LLM credentials), then invokes the module's run() function with the given prompt and context. Returns structured generated_content keyed by field name.

An optional connection_laui can override the connection embedded in the chat item.

Request Body

FieldTypeRequiredDefaultDescription
promptstringYesUser's generation prompt
chat_lauiObjectIdYesLAUI of the chat catalog item whose codeblock and connection are used
item_typeenumYes"action", "operator", "payload", "agent", "generate"
ai_providerstringYesAI provider (currently "anthropic")
include_guide_docboolNofalseInclude guide documentation in context
include_install_guideboolNofalseInclude install guide in context
messagesarrayNonullConversation history for multi-turn generation
generated_contentobjectNonullPreviously generated content (for refinement)
skill_contentstringNonullSkill text to prepend to system prompt
session_idObjectIdNonullSession identifier — reuses cached temp module when provided
connection_lauiObjectIdNonullOverride the connection inside the chat item

ChatMessage Schema

{
  "role": "user",
  "content": "Create a Python operator that reads from S3"
}

Required Generated Fields by Item Type

Item TypeRequired Fields
actioncodeblock, bashblock
agentcodeblock, bashblock
chatcodeblock, bashblock
operatorcodeblock, bashblock, payload, connection
payloadpayload

Variation 1: Generate Operator

{
  "prompt": "Create a Python operator that reads CSV files from S3 and writes to PostgreSQL",
  "chat_laui": "60d5ecb54b24a67d8c8b4567",
  "item_type": "operator",
  "ai_provider": "anthropic"
}

Variation 2: Generate Action

{
  "prompt": "Create an action that sends a Slack notification with task results",
  "chat_laui": "60d5ecb54b24a67d8c8b4567",
  "item_type": "action",
  "ai_provider": "anthropic"
}

Variation 3: Generate Payload

{
  "prompt": "Generate a SQL query payload that aggregates daily sales by region",
  "chat_laui": "60d5ecb54b24a67d8c8b4567",
  "item_type": "payload",
  "ai_provider": "anthropic"
}

Variation 4: Multi-Turn Conversation

{
  "prompt": "Add error handling and retry logic to the S3 reader",
  "chat_laui": "60d5ecb54b24a67d8c8b4567",
  "item_type": "operator",
  "ai_provider": "anthropic",
  "messages": [
    {
      "role": "user",
      "content": "Create a Python operator that reads CSV files from S3"
    },
    {
      "role": "assistant",
      "content": "Here is an S3 CSV reader operator..."
    }
  ],
  "generated_content": {
    "codeblock": {
      "completed": true,
      "content": "import boto3\n\ndef run(context):\n    ...",
      "language": "python"
    },
    "bashblock": {
      "completed": true,
      "content": "pip install boto3 pandas"
    }
  }
}

Variation 5: With Guide Docs and Skill Content

{
  "prompt": "Create an operator following the S3 best practices guide",
  "chat_laui": "60d5ecb54b24a67d8c8b4567",
  "item_type": "operator",
  "ai_provider": "anthropic",
  "include_guide_doc": true,
  "include_install_guide": true,
  "skill_content": "You are an expert AWS data engineer. Always use boto3 session-based credentials. Always implement exponential backoff for retries."
}

Variation 6: With Session and Connection Override

{
  "prompt": "Refine the codeblock to handle empty files gracefully",
  "chat_laui": "60d5ecb54b24a67d8c8b4567",
  "item_type": "operator",
  "ai_provider": "anthropic",
  "session_id": "60d5ecb54b24a67d8c8b9999",
  "connection_laui": "60d5ecb54b24a67d8c8b1234"
}

Success Response

Status: 200 OK

{
  "message": "Generation complete",
  "generated_content": {
    "codeblock": {
      "completed": true,
      "content": "import boto3\nimport pandas as pd\n\ndef initialize(context):\n    session = boto3.Session()\n    context['s3_client'] = session.client('s3')\n\ndef run(context):\n    s3 = context['s3_client']\n    bucket = context['connection']['bucket']\n    key = context['payload']['s3_key']\n    obj = s3.get_object(Bucket=bucket, Key=key)\n    df = pd.read_csv(obj['Body'])\n    return {'rows_read': len(df)}\n\ndef check_completion(context):\n    return True\n\ndef finish(context):\n    pass",
      "language": "python"
    },
    "bashblock": {
      "completed": true,
      "content": "pip install boto3 pandas"
    },
    "payload": {
      "completed": true,
      "content": "{\"s3_key\": \"data/input.csv\"}"
    },
    "connection": {
      "completed": true,
      "content": "{\"bucket\": \"my-data-bucket\", \"region\": \"us-east-1\"}"
    }
  },
  "token_limit_exceeded": false,
  "partial_generation": false,
  "temp_file_path": "/tmp/leastaction_ai_actions/session_60d5ecb54b24a67d8c8b9999.py",
  "validation": {
    "valid": true,
    "errors": [],
    "warnings": []
  }
}

AIResponse fields

FieldTypeDescription
messagestringStatus message
generated_contentobjectGenerated fields keyed by name (structure depends on item_type)
token_limit_exceededboolWhether the AI hit its token limit
partial_generationboolWhether generation was incomplete
temp_file_pathstring | nullPath to the cached temp module; pass session_id on subsequent calls to reuse
validationValidationResult | nullStatic codeblock validation result (operators and actions only)

ValidationResult fields

FieldTypeDescription
validbooltrue if no errors found
errorsarrayList of CodeblockValidationEntry objects
warningsarrayList of CodeblockValidationEntry (non-fatal)

Partial Generation Response

Status: 206 Partial Content

Returned when the AI generation was interrupted (token limit, context window exceeded).

{
  "message": "Token limit exceeded - generation incomplete",
  "generated_content": {
    "codeblock": {
      "completed": true,
      "content": "import boto3\n..."
    },
    "bashblock": {
      "completed": false,
      "content": ""
    }
  },
  "token_limit_exceeded": true,
  "partial_generation": true,
  "temp_file_path": null,
  "validation": null
}

Error Responses

422 Unprocessable Entity — Invalid item_type

{"detail": "Invalid item_type. Must be one of: action, operator, payload, chat, agent"}

500 Internal Server Error — AI provider failure

{"detail": "Internal server error: Anthropic API error: rate limit exceeded"}

500 Internal Server Error — Chat item not found or missing credentials

{"detail": "Internal server error: Connection not found or missing API key"}

Generated Content Schema

GeneratedContent Object

Each field in generated_content follows this structure:

FieldTypeDescription
completedboolWhether this field was fully generated
contentstringThe generated text content
languagestringProgramming language (for codeblock)

Additional fields may be present depending on the content type (the model uses extra="allow").

Schema by Item Type

Action (ActionPromptSchema):

  • codeblock — Python code
  • bashblock — Bash setup
  • connection — Connection sample
  • action_variables — Variables sample
  • guide — Guide documentation
  • install_guide — Install documentation

Agent (ActionPromptSchema):

  • codeblock — Python code with run(connection, messages, tools=None) signature
  • bashblock — Bash setup
  • connection — LLM credentials (api_key, model, token_limit)

Chat (ActionPromptSchema):

  • codeblock — Python code with run(connection, messages) signature
  • bashblock — Bash setup
  • connection — LLM credentials (api_key, model, token_limit)

Operator (OperatorPromptSchema):

  • codeblock — Python code (must implement run(), initialize(), check_completion(), finish())
  • bashblock — Bash setup
  • payload — Payload sample
  • connection — Connection sample (required)
  • guide — Guide documentation
  • install_guide — Install documentation

Payload (PayloadPromptSchema):

  • payload — Payload content

2. Chat

Send a conversational message to an AI chat item, optionally with MCP tool use.

POST /api/v1/ai/agent

Description

Loads the chat catalog item identified by chat_laui, extracts its codeblock module and connection, then runs a conversational loop. If enable_tools is true and an MCP server is configured, the AI can invoke tools during the loop (up to 50 iterations). Returns the final text response.

Request Body

FieldTypeRequiredDefaultDescription
promptstringYesUser's chat message
chat_lauiObjectIdYesLAUI of the chat catalog item to use
messagesarrayNonullConversation history (ChatMessage objects)
connection_lauiObjectIdNonullOverride the connection inside the chat item
enable_toolsboolNotrueEnable MCP tool calling during the agent loop
skill_contentstringNonullSkill text prepended to the system prompt

Examples

Simple chat

POST /api/v1/ai/agent

{
  "prompt": "What tasks are currently in error state?",
  "chat_laui": "60d5ecb54b24a67d8c8b4567"
}

Multi-turn with tool calling disabled

{
  "prompt": "Summarize the previous answer in one sentence",
  "chat_laui": "60d5ecb54b24a67d8c8b4567",
  "enable_tools": false,
  "messages": [
    {
      "role": "user",
      "content": "What tasks are currently in error state?"
    },
    {
      "role": "assistant",
      "content": "There are 3 tasks in error state: transform-events, load-warehouse, and archive-logs."
    }
  ]
}

With skill context

{
  "prompt": "Generate a SQL query for monthly revenue by product",
  "chat_laui": "60d5ecb54b24a67d8c8b4567",
  "skill_content": "You are a SQL expert. Always use CTEs. Prefer window functions over subqueries."
}

Success Response

Status: 200 OK

{
  "message": "There are 3 tasks in error state across 2 projects. The most recent failure was transform-events at 07:01 UTC.",
  "tool_calls_made": ["catalog_search", "get_task_logs"],
  "content_type": "text"
}

AgentResponse fields

FieldTypeDescription
messagestringThe AI's response text
tool_calls_madeList[string] | nullNames of MCP tools invoked during the agent loop
content_typestringDetected content type: "text", "html", or "markdown"

The content_type is either "text" (default) or parsed from a [content_type:X] marker the AI may embed in its response.

Error Responses

500 Internal Server Error — AI provider failure

{"detail": "Internal server error: Anthropic API error: rate limit exceeded"}

500 Internal Server Error — Chat item not found

{"detail": "Internal server error: Connection not found or missing API key"}