tupiflow registry /plugins/workflow-builder/1.3.0

workflow-builder @ 1.3.0

Internal tools that let an AI agent introspect this app: agents, actions, workflows, executions, connections, tools, plus core meta-actions like human-takeover.

Publisher / author
tupiflow
Type
workflow-builder
Signing key
kid-20260520-e5fe9257

Bundle

Download signed bundle verifies against kid-20260520-e5fe9257

Signed manifest (spec)

Byte-for-byte signed payload. Hash with RFC 8785 canonical JSON, verify the Ed25519 signature against the public key for kid-20260520-e5fe9257.

{
  "icon": {
    "kind": "svg",
    "path": "icon.svg"
  },
  "bundle": {
    "sha256": "03202e98449c38eec43a636a5dfb836655ac3a1fa538708b85bcf2377f4176da",
    "sizeBytes": 28654
  },
  "actions": [
    {
      "slug": "create-workflow",
      "tool": {
        "name": "create_workflow",
        "description": "Create a new workflow in the app from a natural-language description. Use this when the user asks to build, generate, or create a workflow. The `workflowDescription` must be complete and self-contained: capture the trigger, actions, integrations, and conditions discussed in the conversation.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"workflowDescription\":{\"type\":\"string\",\"minLength\":1,\"description\":\"A full description of the workflow to generate, incorporating any relevant details from the conversation so it stands on its own.\"}},\"required\":[\"workflowDescription\"],\"additionalProperties\":false}"
      },
      "label": "Create Workflow",
      "category": "Workflow Builder",
      "description": "Generate a new workflow in this app from a natural-language description.",
      "configFields": [
        {
          "key": "workflowDescription",
          "type": "template-textarea",
          "label": "Workflow description",
          "required": true
        }
      ],
      "outputFields": [
        {
          "field": "id",
          "description": "New workflow id"
        },
        {
          "field": "name",
          "description": "Workflow name"
        },
        {
          "field": "description",
          "description": "Workflow description"
        },
        {
          "field": "url",
          "description": "Path to open the workflow editor"
        }
      ],
      "stepFunction": "wfCreateWorkflowStep"
    },
    {
      "slug": "list-workflows",
      "tool": {
        "name": "list_workflows",
        "description": "List workflows owned by the current user. Each entry includes a `trigger` summary with `type` (Manual | Schedule | Webhook | Chat Message), `acceptsInput` (true for Manual and Webhook), and optional `inputSchema` describing the fields execute_workflow can pass.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"search\":{\"type\":\"string\",\"description\":\"Optional case-insensitive substring on workflow name.\"}},\"additionalProperties\":false}"
      },
      "label": "List Workflows",
      "category": "Workflow Builder",
      "description": "List all workflows owned by the calling user.",
      "configFields": [
        {
          "key": "search",
          "type": "template-input",
          "label": "Search"
        }
      ],
      "outputFields": [
        {
          "field": "workflows",
          "description": "Array of workflow summaries"
        },
        {
          "field": "count",
          "description": "Number of workflows"
        }
      ],
      "stepFunction": "wfListWorkflowsStep"
    },
    {
      "slug": "get-workflow",
      "tool": {
        "name": "get_workflow",
        "description": "Fetch a single workflow by id with full structure: nodes (with action config), edges, name, description, visibility, timestamps, and a `trigger` summary. The trigger summary reports `type`, `acceptsInput` (Manual/Webhook), and optional `inputSchema` listing the fields execute_workflow can pass.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"workflowId\":{\"type\":\"string\",\"description\":\"Workflow id to fetch.\"}},\"required\":[\"workflowId\"],\"additionalProperties\":false}"
      },
      "label": "Get Workflow",
      "category": "Workflow Builder",
      "description": "Return full workflow data (nodes, edges, structure) by workflowId.",
      "configFields": [
        {
          "key": "workflowId",
          "type": "template-input",
          "label": "Workflow ID",
          "required": true
        }
      ],
      "outputFields": [
        {
          "field": "id",
          "description": "Workflow id"
        },
        {
          "field": "name",
          "description": "Workflow name"
        },
        {
          "field": "description",
          "description": "Workflow description"
        },
        {
          "field": "visibility",
          "description": "private | public"
        },
        {
          "field": "isSystem",
          "description": "System workflow flag"
        },
        {
          "field": "nodeCount",
          "description": "Number of nodes"
        },
        {
          "field": "edgeCount",
          "description": "Number of edges"
        },
        {
          "field": "nodes",
          "description": "Array of React Flow nodes"
        },
        {
          "field": "edges",
          "description": "Array of React Flow edges"
        },
        {
          "field": "trigger",
          "description": "Trigger summary { type, acceptsInput, inputSchema? } describing how this workflow can be triggered."
        },
        {
          "field": "createdAt",
          "description": "ISO timestamp"
        },
        {
          "field": "updatedAt",
          "description": "ISO timestamp"
        }
      ],
      "stepFunction": "wfGetWorkflowStep"
    },
    {
      "slug": "execute-workflow",
      "tool": {
        "name": "execute_workflow",
        "description": "Execute a workflow by id with an optional input payload. Only workflows with Manual or Webhook triggers accept input; for Schedule or Chat Message triggers, omit `input`. If unsure what fields the workflow expects, call get_workflow first and read `trigger.inputSchema`. Fire-and-forget: returns the executionId immediately. Poll get_workflow_executions to inspect results.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"workflowId\":{\"type\":\"string\",\"description\":\"Workflow id to execute.\"},\"input\":{\"type\":\"object\",\"additionalProperties\":true,\"description\":\"Trigger input. Each top-level key becomes available downstream as {{Trigger.<key>}}. Match the keys to the workflow's trigger.inputSchema.\"}},\"required\":[\"workflowId\"],\"additionalProperties\":false}"
      },
      "label": "Execute Workflow",
      "category": "Workflow Builder",
      "description": "Trigger a workflow execution with an optional input payload. Returns immediately with the executionId.",
      "configFields": [
        {
          "key": "workflowId",
          "type": "template-input",
          "label": "Workflow ID",
          "required": true
        },
        {
          "key": "input",
          "type": "template-textarea",
          "label": "Trigger input (JSON)"
        }
      ],
      "outputFields": [
        {
          "field": "executionId",
          "description": "Execution row id"
        },
        {
          "field": "workflowId",
          "description": "Workflow id executed"
        },
        {
          "field": "status",
          "description": "Always 'running' on success"
        }
      ],
      "stepFunction": "wfExecuteWorkflowStep"
    },
    {
      "slug": "get-workflow-executions",
      "tool": {
        "name": "get_workflow_executions",
        "description": "Fetch recent executions for a workflow (by workflowId) with status, input/output, error, and per-node execution logs.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"workflowId\":{\"type\":\"string\",\"description\":\"Workflow id to inspect.\"},\"limit\":{\"type\":\"integer\",\"minimum\":1,\"maximum\":50,\"description\":\"Max executions to return (1-50, default 10).\"}},\"required\":[\"workflowId\"],\"additionalProperties\":false}"
      },
      "label": "Get Workflow Executions",
      "category": "Workflow Builder",
      "description": "Return recent executions for a workflow plus per-node logs.",
      "configFields": [
        {
          "key": "workflowId",
          "type": "template-input",
          "label": "Workflow ID",
          "required": true
        },
        {
          "key": "limit",
          "type": "number",
          "label": "Limit"
        }
      ],
      "outputFields": [
        {
          "field": "executions",
          "description": "Array of executions with logs"
        },
        {
          "field": "count",
          "description": "Number of executions returned"
        }
      ],
      "stepFunction": "wfGetWorkflowExecutionsStep"
    },
    {
      "slug": "list-agents",
      "tool": {
        "name": "list_agents",
        "description": "List every agent (system prompt file under /agents). Returns slug, name, description, provider, model.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{},\"additionalProperties\":false}"
      },
      "label": "List Agents",
      "category": "Workflow Builder",
      "description": "List all agents defined on this host.",
      "configFields": [],
      "outputFields": [
        {
          "field": "agents",
          "description": "Array of agents (slug, name, ...)"
        },
        {
          "field": "count",
          "description": "Number of agents"
        }
      ],
      "stepFunction": "wfListAgentsStep"
    },
    {
      "slug": "create-agent",
      "tool": {
        "name": "create_agent",
        "description": "Create a new agent. Slug must be unique (lowercase letters, digits, hyphens; must start alphanumeric). Use list_tools first to discover valid `tools[].actionId` values. `tools` are built-in actions (full actionId, e.g. 'workflow-builder/list-actions'). `mcpTools` whitelists raw tool names per MCP integration; use list_integrations to find MCP integration ids and list_tools on them to discover names. `kbCollectionIds` grants kb_search/kb_get_document/kb_get_page access to those collections. `approvalTargetIntegrationId` + `approvalTargetChatId` redirect human-approval requests to a private chat instead of the conversation that triggered the run.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"slug\":{\"type\":\"string\",\"description\":\"Unique kebab-case slug for the agent.\"},\"name\":{\"type\":\"string\",\"description\":\"Human-readable name.\"},\"description\":{\"type\":\"string\"},\"provider\":{\"type\":\"string\"},\"model\":{\"type\":\"string\"},\"body\":{\"type\":\"string\"},\"historyLimit\":{\"type\":\"integer\",\"minimum\":1},\"maxToolSteps\":{\"type\":\"integer\",\"minimum\":1},\"showToolTrace\":{\"type\":\"boolean\"},\"showReasoning\":{\"type\":\"boolean\"},\"approvalTargetIntegrationId\":{\"type\":\"string\"},\"approvalTargetChatId\":{\"type\":\"string\"},\"tools\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"actionId\":{\"type\":\"string\",\"description\":\"Full actionId (e.g. 'workflow-builder/list-actions').\"},\"enabled\":{\"type\":\"boolean\",\"description\":\"Defaults to true.\"},\"integrationId\":{\"type\":\"string\",\"description\":\"Pin tool to a specific integration row.\"},\"requireApproval\":{\"type\":\"boolean\",\"description\":\"Pause for human approval each call.\"},\"triggerKeywords\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"description\":\"Inbound-chat keywords that auto-invoke this tool.\"},\"override\":{\"type\":\"object\",\"description\":\"Per-tool overrides shadowing plugin defaults at runtime.\",\"properties\":{\"name\":{\"type\":\"string\",\"description\":\"Custom tool name.\"},\"description\":{\"type\":\"string\",\"description\":\"Custom description.\"},\"inputSchemaJson\":{\"type\":\"string\",\"description\":\"Custom JSON Schema (stringified).\"}},\"additionalProperties\":false}},\"required\":[\"actionId\"],\"additionalProperties\":false}},\"mcpTools\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"integrationId\":{\"type\":\"string\",\"description\":\"Id of an MCP-type integration row.\"},\"toolNames\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"description\":\"Raw tool names the agent is allowed to invoke.\"},\"approvalToolNames\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"description\":\"Subset of toolNames that pause for human approval.\"},\"overrides\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\",\"properties\":{\"description\":{\"type\":\"string\"},\"inputSchemaJson\":{\"type\":\"string\"}},\"additionalProperties\":false},\"description\":\"Per-tool overrides keyed by raw tool name.\"}},\"required\":[\"integrationId\",\"toolNames\"],\"additionalProperties\":false}},\"kbCollectionIds\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}},\"required\":[\"slug\",\"name\"],\"additionalProperties\":false}"
      },
      "label": "Create Agent",
      "category": "Workflow Builder",
      "description": "Create a new agent with system prompt, provider/model, and optional tools, MCP whitelist, KB collections, and run-time settings.",
      "configFields": [
        {
          "key": "slug",
          "type": "template-input",
          "label": "Slug",
          "required": true
        },
        {
          "key": "name",
          "type": "template-input",
          "label": "Name",
          "required": true
        },
        {
          "key": "description",
          "type": "template-textarea",
          "label": "Description"
        },
        {
          "key": "provider",
          "type": "text",
          "label": "Provider"
        },
        {
          "key": "model",
          "type": "text",
          "label": "Model"
        },
        {
          "key": "body",
          "type": "template-textarea",
          "label": "System prompt"
        },
        {
          "key": "historyLimit",
          "type": "number",
          "label": "History limit"
        },
        {
          "key": "maxToolSteps",
          "type": "number",
          "label": "Max tool steps"
        }
      ],
      "outputFields": [
        {
          "field": "slug",
          "description": "Agent slug"
        },
        {
          "field": "name",
          "description": "Agent name"
        },
        {
          "field": "toolCount",
          "description": "Number of built-in tools attached"
        },
        {
          "field": "mcpToolCount",
          "description": "Total raw MCP tool names whitelisted across selections"
        },
        {
          "field": "kbCollectionCount",
          "description": "Number of KB collections attached"
        },
        {
          "field": "updatedAt",
          "description": "ISO timestamp"
        }
      ],
      "stepFunction": "wfCreateAgentStep"
    },
    {
      "slug": "update-agent",
      "tool": {
        "name": "update_agent",
        "description": "Update an existing agent. Only fields you pass are changed; omitted fields are retained. List-shaped fields REPLACE on update — passing `tools`, `mcpTools`, or `kbCollectionIds` overwrites the current list, so include any entries you want to keep. Pass `[]` to clear a list. For nullable scalars (`historyLimit`, `maxToolSteps`, `approvalTargetIntegrationId`, `approvalTargetChatId`), pass `null` to clear, omit to leave unchanged.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"slug\":{\"type\":\"string\",\"description\":\"Existing agent slug.\"},\"name\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"provider\":{\"type\":\"string\"},\"model\":{\"type\":\"string\"},\"body\":{\"type\":\"string\"},\"historyLimit\":{\"type\":[\"integer\",\"null\"],\"minimum\":1},\"maxToolSteps\":{\"type\":[\"integer\",\"null\"],\"minimum\":1},\"showToolTrace\":{\"type\":\"boolean\"},\"showReasoning\":{\"type\":\"boolean\"},\"approvalTargetIntegrationId\":{\"type\":[\"string\",\"null\"]},\"approvalTargetChatId\":{\"type\":[\"string\",\"null\"]},\"tools\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"actionId\":{\"type\":\"string\",\"description\":\"Full actionId (e.g. 'workflow-builder/list-actions').\"},\"enabled\":{\"type\":\"boolean\",\"description\":\"Defaults to true.\"},\"integrationId\":{\"type\":\"string\",\"description\":\"Pin tool to a specific integration row.\"},\"requireApproval\":{\"type\":\"boolean\",\"description\":\"Pause for human approval each call.\"},\"triggerKeywords\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"description\":\"Inbound-chat keywords that auto-invoke this tool.\"},\"override\":{\"type\":\"object\",\"description\":\"Per-tool overrides shadowing plugin defaults at runtime.\",\"properties\":{\"name\":{\"type\":\"string\",\"description\":\"Custom tool name.\"},\"description\":{\"type\":\"string\",\"description\":\"Custom description.\"},\"inputSchemaJson\":{\"type\":\"string\",\"description\":\"Custom JSON Schema (stringified).\"}},\"additionalProperties\":false}},\"required\":[\"actionId\"],\"additionalProperties\":false}},\"mcpTools\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"integrationId\":{\"type\":\"string\",\"description\":\"Id of an MCP-type integration row.\"},\"toolNames\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"description\":\"Raw tool names the agent is allowed to invoke.\"},\"approvalToolNames\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"description\":\"Subset of toolNames that pause for human approval.\"},\"overrides\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\",\"properties\":{\"description\":{\"type\":\"string\"},\"inputSchemaJson\":{\"type\":\"string\"}},\"additionalProperties\":false},\"description\":\"Per-tool overrides keyed by raw tool name.\"}},\"required\":[\"integrationId\",\"toolNames\"],\"additionalProperties\":false}},\"kbCollectionIds\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}},\"required\":[\"slug\"],\"additionalProperties\":false}"
      },
      "label": "Update Agent",
      "category": "Workflow Builder",
      "description": "Update an existing agent's metadata, system prompt, tools, MCP whitelist, KB collections, or run-time settings.",
      "configFields": [
        {
          "key": "slug",
          "type": "template-input",
          "label": "Slug",
          "required": true
        },
        {
          "key": "name",
          "type": "template-input",
          "label": "Name"
        },
        {
          "key": "description",
          "type": "template-textarea",
          "label": "Description"
        },
        {
          "key": "provider",
          "type": "text",
          "label": "Provider"
        },
        {
          "key": "model",
          "type": "text",
          "label": "Model"
        },
        {
          "key": "body",
          "type": "template-textarea",
          "label": "System prompt"
        },
        {
          "key": "historyLimit",
          "type": "number",
          "label": "History limit"
        },
        {
          "key": "maxToolSteps",
          "type": "number",
          "label": "Max tool steps"
        }
      ],
      "outputFields": [
        {
          "field": "slug",
          "description": "Agent slug"
        },
        {
          "field": "name",
          "description": "Agent name"
        },
        {
          "field": "toolCount",
          "description": "Number of built-in tools attached"
        },
        {
          "field": "mcpToolCount",
          "description": "Total raw MCP tool names whitelisted across selections"
        },
        {
          "field": "kbCollectionCount",
          "description": "Number of KB collections attached"
        },
        {
          "field": "updatedAt",
          "description": "ISO timestamp"
        }
      ],
      "stepFunction": "wfUpdateAgentStep"
    },
    {
      "slug": "delete-agent",
      "tool": {
        "name": "delete_agent",
        "description": "Delete an agent by slug. The 'default' agent is protected and the call will fail if you target it.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"slug\":{\"type\":\"string\",\"description\":\"Agent slug to delete.\"}},\"required\":[\"slug\"],\"additionalProperties\":false}"
      },
      "label": "Delete Agent",
      "category": "Workflow Builder",
      "description": "Delete an agent by slug. The 'default' agent is protected and cannot be deleted.",
      "configFields": [
        {
          "key": "slug",
          "type": "template-input",
          "label": "Slug",
          "required": true
        }
      ],
      "outputFields": [
        {
          "field": "slug",
          "description": "Slug deleted"
        },
        {
          "field": "deleted",
          "description": "Always true on success"
        }
      ],
      "stepFunction": "wfDeleteAgentStep"
    },
    {
      "slug": "launch-agent",
      "tool": {
        "name": "launch_agent",
        "description": "Run a subagent (multimodal) by slug with a prompt. Pass imageUrls/fileUrls/audioUrls/videoUrls as arrays of https or data URLs. Returns the assistant text plus the resolved provider/model/agentSlug.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"agentSlug\":{\"type\":\"string\",\"description\":\"Agent slug to launch (defaults to 'default').\"},\"userPrompt\":{\"type\":\"string\",\"description\":\"Message to send to the subagent.\"},\"systemPromptOverride\":{\"type\":\"string\"},\"providerOverride\":{\"type\":\"string\"},\"modelOverride\":{\"type\":\"string\"},\"imageUrls\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"fileUrls\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"audioUrls\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"videoUrls\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}},\"required\":[\"userPrompt\"],\"additionalProperties\":false}"
      },
      "label": "Launch Agent",
      "category": "Workflow Builder",
      "description": "Invoke an agent (subagent call) with a prompt and optional multimodal attachments.",
      "configFields": [
        {
          "key": "agentSlug",
          "type": "text",
          "label": "Agent slug"
        },
        {
          "key": "userPrompt",
          "type": "template-textarea",
          "label": "Prompt",
          "required": true
        },
        {
          "key": "imageUrls",
          "type": "template-textarea",
          "label": "Image URLs"
        },
        {
          "key": "fileUrls",
          "type": "template-textarea",
          "label": "File URLs"
        },
        {
          "key": "audioUrls",
          "type": "template-textarea",
          "label": "Audio URLs"
        },
        {
          "key": "videoUrls",
          "type": "template-textarea",
          "label": "Video URLs"
        }
      ],
      "outputFields": [
        {
          "field": "text",
          "description": "Assistant response text"
        },
        {
          "field": "model",
          "description": "Model id used"
        },
        {
          "field": "provider",
          "description": "Provider id used"
        },
        {
          "field": "agentSlug",
          "description": "Agent slug used"
        }
      ],
      "stepFunction": "wfLaunchAgentStep"
    },
    {
      "slug": "list-actions",
      "tool": {
        "name": "list_actions",
        "description": "List all workflow actions (plugin + system) the AI agent workflow creator can add to a graph. Each entry includes actionId, label, category, integration, and config field keys.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"category\":{\"type\":\"string\",\"description\":\"Case-insensitive category filter (e.g. GitHub, AI).\"}},\"additionalProperties\":false}"
      },
      "label": "List Actions",
      "category": "Workflow Builder",
      "description": "List every action available in the workflow registry (plugin + system).",
      "configFields": [
        {
          "key": "category",
          "type": "text",
          "label": "Category filter"
        }
      ],
      "outputFields": [
        {
          "field": "actions",
          "description": "Array of actions"
        },
        {
          "field": "count",
          "description": "Number of actions"
        }
      ],
      "stepFunction": "wfListActionsStep"
    },
    {
      "slug": "list-integrations",
      "tool": {
        "name": "list_integrations",
        "description": "List the calling user's configured integrations. Each entry includes integrationId, name, type, label, isManaged, and the actions exposed by that integration plugin (actionId, slug, label, category, isTool). Use this to know which actions the agent can wire into a workflow for the current user's connected services.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"type\":{\"type\":\"string\",\"description\":\"Optional case-insensitive exact match on type.\"}},\"additionalProperties\":false}"
      },
      "label": "List Integrations",
      "category": "Workflow Builder",
      "description": "List integrations the user has configured, with their available actions.",
      "configFields": [
        {
          "key": "type",
          "type": "text",
          "label": "Type filter"
        }
      ],
      "outputFields": [
        {
          "field": "integrations",
          "description": "Array of integrations with action lists"
        },
        {
          "field": "count",
          "description": "Number of integrations"
        }
      ],
      "stepFunction": "wfListIntegrationsStep"
    },
    {
      "slug": "list-connections",
      "tool": {
        "name": "list_connections",
        "description": "List connection integrations (chat bots etc.) configured for the current user. Returns integrationId, type, label, and trigger metadata.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{},\"additionalProperties\":false}"
      },
      "label": "List Connections",
      "category": "Workflow Builder",
      "description": "List available chat-style connections (Telegram, WhatsApp, etc.) for the calling user.",
      "configFields": [],
      "outputFields": [
        {
          "field": "connections",
          "description": "Array of connection integrations"
        },
        {
          "field": "count",
          "description": "Number of connections"
        }
      ],
      "stepFunction": "wfListConnectionsStep"
    },
    {
      "slug": "list-tools",
      "tool": {
        "name": "list_tools",
        "description": "Search the AI Agent tool registry. Use slim=true for cheap discovery (omits inputSchema; pair with limit to page through results). Use slim=false (default) when you've narrowed to the tool you want and need its full inputSchema. Matches on name/description/actionId/category/integration.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"},\"category\":{\"type\":\"string\"},\"integration\":{\"type\":\"string\"},\"slim\":{\"type\":\"boolean\"},\"limit\":{\"type\":\"integer\",\"minimum\":1,\"maximum\":200},\"offset\":{\"type\":\"integer\",\"minimum\":0}},\"additionalProperties\":false}"
      },
      "label": "List/Search Tools",
      "category": "Workflow Builder",
      "description": "Search the AI Agent tool registry. Two modes: lean discovery (slim=true, paginated, no schemas) and full lookup (default, returns inputSchema for each match).",
      "configFields": [
        {
          "key": "query",
          "type": "template-input",
          "label": "Search query"
        },
        {
          "key": "category",
          "type": "template-input",
          "label": "Category filter (exact, case-insensitive)"
        },
        {
          "key": "integration",
          "type": "template-input",
          "label": "Integration filter (exact, case-insensitive)"
        },
        {
          "key": "slim",
          "type": "select",
          "label": "Slim mode (omit inputSchema)"
        },
        {
          "key": "limit",
          "type": "number",
          "label": "Limit"
        },
        {
          "key": "offset",
          "type": "number",
          "label": "Offset"
        }
      ],
      "outputFields": [
        {
          "field": "tools",
          "description": "Page of tool entries"
        },
        {
          "field": "count",
          "description": "Number of rows in this page"
        },
        {
          "field": "total",
          "description": "Total matches after filtering"
        },
        {
          "field": "offset",
          "description": "Echoed offset"
        },
        {
          "field": "limit",
          "description": "Echoed limit (null when unpaged)"
        },
        {
          "field": "hasMore",
          "description": "True when more pages remain"
        }
      ],
      "stepFunction": "wfListToolsStep"
    },
    {
      "slug": "fetch",
      "tool": {
        "name": "fetch",
        "description": "Make an HTTP request to any URL. By default sends real Mac Chrome browser headers (User-Agent, Accept, sec-ch-ua, Sec-Fetch-*, etc.) so requests look like a normal browser and avoid generic bot checks. Auto-parses JSON responses. Body can be a string (sent as-is) or an object (JSON-encoded with Content-Type: application/json). Set disableBrowserHeaders=true for raw API calls where the spoofed headers would interfere.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"url\":{\"type\":\"string\",\"format\":\"uri\",\"description\":\"Absolute URL to fetch.\"},\"method\":{\"type\":\"string\",\"enum\":[\"GET\",\"POST\",\"PUT\",\"PATCH\",\"DELETE\",\"HEAD\",\"OPTIONS\"]},\"headers\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}},\"query\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}},\"body\":{\"description\":\"Request body (string or object). Ignored for GET/HEAD.\"},\"responseType\":{\"type\":\"string\",\"enum\":[\"auto\",\"json\",\"text\"]},\"timeoutMs\":{\"type\":\"integer\",\"minimum\":1,\"maximum\":120000},\"disableBrowserHeaders\":{\"type\":\"boolean\"}},\"required\":[\"url\"],\"additionalProperties\":false}"
      },
      "label": "HTTP Fetch",
      "category": "Workflow Builder",
      "description": "Make an HTTP request to a URL and return the parsed response. Generic fetch tool for agents.",
      "configFields": [
        {
          "key": "url",
          "type": "template-input",
          "label": "URL",
          "required": true
        },
        {
          "key": "method",
          "type": "text",
          "label": "Method"
        },
        {
          "key": "headers",
          "type": "template-textarea",
          "label": "Headers (JSON object)"
        },
        {
          "key": "query",
          "type": "template-textarea",
          "label": "Query params (JSON object)"
        },
        {
          "key": "body",
          "type": "template-textarea",
          "label": "Body (string or JSON)"
        },
        {
          "key": "responseType",
          "type": "text",
          "label": "Response type"
        },
        {
          "key": "timeoutMs",
          "type": "number",
          "label": "Timeout (ms)"
        },
        {
          "key": "disableBrowserHeaders",
          "type": "select",
          "label": "Disable browser headers"
        }
      ],
      "outputFields": [
        {
          "field": "status",
          "description": "HTTP status code"
        },
        {
          "field": "statusText",
          "description": "HTTP status text"
        },
        {
          "field": "ok",
          "description": "True when status is 2xx"
        },
        {
          "field": "headers",
          "description": "Response headers"
        },
        {
          "field": "body",
          "description": "Parsed JSON or raw text"
        },
        {
          "field": "contentType",
          "description": "Response content-type"
        },
        {
          "field": "url",
          "description": "Final URL after redirects"
        }
      ],
      "stepFunction": "wfFetchStep"
    },
    {
      "slug": "compute-hash",
      "tool": {
        "name": "compute_hash",
        "description": "Compute the SHA-256 hex digest of a string using an isolated worker thread. Use for deduplication keys, content fingerprinting, or deterministic identifiers. Returns hex string (64 chars).",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"input\":{\"type\":\"string\",\"minLength\":0,\"description\":\"String to hash. Empty string is valid; returns the sha256 of empty.\"}},\"required\":[\"input\"],\"additionalProperties\":false}"
      },
      "label": "Compute Hash (SHA-256)",
      "category": "Workflow Builder",
      "description": "Compute the SHA-256 hex digest of a string in an isolated worker thread. Demonstrates the api.runTask worker contract (pure compute, no network).",
      "configFields": [
        {
          "key": "input",
          "type": "template-input",
          "label": "Input string",
          "required": true
        }
      ],
      "outputFields": [
        {
          "field": "hash",
          "description": "SHA-256 hex digest of the input string"
        },
        {
          "field": "algorithm",
          "description": "Always 'sha256'"
        },
        {
          "field": "inputLength",
          "description": "Byte length of the input string"
        }
      ],
      "stepFunction": "wfComputeHashStep"
    },
    {
      "slug": "fetch-article",
      "tool": {
        "name": "fetch_article",
        "description": "Fetch ONE page's readable article body as markdown (Readability + Turndown). Single page only — no crawl, no link-follow. Use for blog posts, news, docs, wiki, READMEs. NOT for homepages, sitemaps, dashboards, or site structure (returns `not_article` — use `fetch` for raw HTML). Runs in an isolated worker thread (jsdom stays off the request thread). Returns markdown + title/byline/excerpt/length, or reason: `not_article`|`http_error`|`timeout`|`unsupported_content_type`|`response_too_large`|`fetch_failed`.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"url\":{\"type\":\"string\",\"format\":\"uri\",\"description\":\"Absolute http(s) URL of the article/doc page to read.\"},\"timeoutMs\":{\"type\":\"integer\",\"minimum\":1,\"maximum\":60000,\"description\":\"Request timeout in ms (default 15000, max 60000).\"},\"disableBrowserHeaders\":{\"type\":\"boolean\",\"description\":\"Set true to send a raw request without the default Mac Chrome browser headers. Default false.\"}},\"required\":[\"url\"],\"additionalProperties\":false}"
      },
      "label": "Fetch Article (Readable)",
      "category": "Workflow Builder",
      "description": "Fetch ONE URL and return the readable article body as markdown. Single-page extraction only — does not crawl, does not follow links, does not dump site structure.",
      "configFields": [
        {
          "key": "url",
          "type": "template-input",
          "label": "URL",
          "required": true
        },
        {
          "key": "timeoutMs",
          "type": "number",
          "label": "Timeout (ms)"
        },
        {
          "key": "disableBrowserHeaders",
          "type": "select",
          "label": "Disable browser headers"
        }
      ],
      "outputFields": [
        {
          "field": "markdown",
          "description": "Article body converted to markdown"
        },
        {
          "field": "title",
          "description": "Extracted article title (may be null)"
        },
        {
          "field": "byline",
          "description": "Extracted byline/author (may be null)"
        },
        {
          "field": "excerpt",
          "description": "Short summary from Readability (may be null)"
        },
        {
          "field": "length",
          "description": "Length of markdown in characters"
        },
        {
          "field": "contentType",
          "description": "Response content-type header"
        },
        {
          "field": "url",
          "description": "URL that was requested"
        },
        {
          "field": "finalUrl",
          "description": "URL after redirects"
        }
      ],
      "stepFunction": "wfFetchArticleStep"
    },
    {
      "slug": "fetch-models",
      "tool": {
        "name": "fetch_models",
        "description": "List the models available on an AI provider integration. Pass an `integrationId` whose type begins with `agents_` (e.g. agents_ai-gateway, agents_openai, agents_anthropic) — obtain ids from list_integrations. Returns chat models by default; pass modelType=\"embeddings\" for embedding models. `source` is \"live\" when fetched from the provider, \"fallback\" when the static built-in list was used (live fetch failed or no API key). Errors with a clear message if the integration is not an agents_* provider.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"modelIntegrationId\":{\"type\":\"string\",\"minLength\":1},\"modelType\":{\"type\":\"string\",\"enum\":[\"chat\",\"embeddings\"]}},\"required\":[\"modelIntegrationId\"],\"additionalProperties\":false}"
      },
      "label": "Fetch Models (AI Provider)",
      "category": "Workflow Builder",
      "description": "List the chat or embedding models exposed by an AI provider integration (type prefix `agents_*`).",
      "configFields": [
        {
          "key": "modelIntegrationId",
          "type": "template-input",
          "label": "AI Provider Integration ID",
          "required": true
        },
        {
          "key": "modelType",
          "type": "select",
          "label": "Model type"
        }
      ],
      "outputFields": [
        {
          "field": "models",
          "description": "Array of { id, label } model entries"
        },
        {
          "field": "source",
          "description": "'live' if fetched from the provider API, 'fallback' otherwise"
        },
        {
          "field": "providerId",
          "description": "Provider slug (e.g. ai-gateway, openai)"
        },
        {
          "field": "integrationType",
          "description": "Resolved integration type (agents_<providerId>)"
        },
        {
          "field": "integrationId",
          "description": "Echoes the input id"
        },
        {
          "field": "modelType",
          "description": "Echoes the requested model type"
        },
        {
          "field": "warning",
          "description": "Present when live fetch failed and the fallback list is returned"
        }
      ],
      "stepFunction": "wfFetchModelsStep"
    },
    {
      "slug": "run-js",
      "tool": {
        "name": "run_js",
        "description": "Run a JS snippet in a sandboxed runtime. Use for data transformation, parsing (JSON, CSV, dates), formatting, math, regex, filtering, or aggregation that no other tool covers. The `data` input auto-resolves handle refs (`ref_xxx`), so this is the cheapest way to reshape large tool outputs before passing them on. Sandbox has NO network, NO I/O, NO library imports, and only `JSON` / `Math` / `Date` / `console.log` globals — do NOT use it to send email, write DB, call APIs, or replace a real action tool. Snippet must `return` a JSON-serializable value. Result wraps as a new handle if large, else returns inline.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"code\":{\"type\":\"string\",\"minLength\":1},\"data\":{},\"timeoutMs\":{\"type\":\"integer\",\"minimum\":1,\"maximum\":10000}},\"required\":[\"code\"],\"additionalProperties\":false}"
      },
      "label": "Run JS",
      "category": "Workflow Builder",
      "description": "Run a JS snippet in a sandboxed runtime (no network, no I/O, no library imports). Useful for data transformation, parsing, formatting, math, regex, filtering, aggregation.",
      "configFields": [
        {
          "key": "code",
          "type": "template-textarea",
          "label": "Code",
          "required": true
        },
        {
          "key": "data",
          "type": "template-textarea",
          "label": "Data (template or JSON)"
        },
        {
          "key": "timeoutMs",
          "type": "number",
          "label": "Timeout (ms)"
        }
      ],
      "outputFields": [
        {
          "field": "value",
          "description": "Whatever the snippet returns (must be JSON-serializable)."
        },
        {
          "field": "logs",
          "description": "console.log lines captured inside the sandbox (each clipped at 64 KB)."
        }
      ],
      "stepFunction": "wfRunJsStep"
    },
    {
      "slug": "send-error-notification",
      "tool": {
        "name": "send_error_notification",
        "description": "Manually fire the configured workflow error notification channels (webhook, ntfy, Telegram/WhatsApp). Bypasses the per-workflow cooldown — use only when the user explicitly asked for a notification.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"message\":{\"type\":\"string\",\"minLength\":1},\"workflowName\":{\"type\":\"string\"},\"workflowId\":{\"type\":\"string\"},\"executionId\":{\"type\":\"string\"}},\"required\":[\"message\"],\"additionalProperties\":false}"
      },
      "label": "Send Error Notification",
      "category": "Workflow Builder",
      "description": "Manually fire the configured error notification channels (webhook, ntfy, Telegram/WhatsApp connection).",
      "configFields": [
        {
          "key": "message",
          "type": "template-textarea",
          "label": "Message",
          "required": true
        },
        {
          "key": "workflowName",
          "type": "template-input",
          "label": "Workflow name (optional)"
        },
        {
          "key": "workflowId",
          "type": "template-input",
          "label": "Workflow id (optional)"
        },
        {
          "key": "executionId",
          "type": "template-input",
          "label": "Execution id (optional)"
        }
      ],
      "outputFields": [
        {
          "field": "dispatched",
          "description": "True when at least one channel accepted the message. False with a `reason` when no channel is configured."
        },
        {
          "field": "reason",
          "description": "Explanation when dispatched is false"
        }
      ],
      "stepFunction": "wfSendErrorNotificationStep"
    },
    {
      "slug": "request-human-takeover",
      "tool": {
        "name": "request_human_takeover",
        "description": "Hand this chat conversation over to a human operator. Call when you cannot help further (sensitive topic, escalation, refund decision, ambiguous request) or when the user explicitly asks for a human. After this returns, do NOT keep replying — the operator will take it from here. The thread's AI replies are suppressed until release.",
        "inputSchemaJson": "{\"type\":\"object\",\"properties\":{\"reason\":{\"type\":\"string\",\"description\":\"Short operator-facing summary (1-3 sentences) of what the user wants and why a human is needed. Shown as a banner in /chat-connections so the operator can act without reading scrollback. Also posted verbatim to the user's chat when notifyMessage is empty — keep it neutral and respectful.\"},\"notifyMessage\":{\"type\":\"string\",\"description\":\"Optional override for the notice posted to the chat user.\"}},\"required\":[\"reason\"],\"additionalProperties\":false}"
      },
      "label": "Request Human Takeover",
      "category": "Workflow Builder",
      "description": "Hand the conversation over to a human operator. Suppresses AI replies on this thread until the operator releases control from /chat-connections.",
      "configFields": [
        {
          "key": "integrationId",
          "type": "template-input",
          "label": "Connection Integration ID"
        },
        {
          "key": "threadId",
          "type": "template-input",
          "label": "Thread ID"
        },
        {
          "key": "reason",
          "type": "template-textarea",
          "label": "Reason"
        },
        {
          "key": "notifyMessage",
          "type": "template-textarea",
          "label": "Notification message"
        }
      ],
      "outputFields": [
        {
          "field": "humanControl",
          "description": "Always true on success"
        },
        {
          "field": "notified",
          "description": "True if a notice was posted to the chat thread"
        },
        {
          "field": "message",
          "description": "Human-readable status string"
        }
      ],
      "stepFunction": "requestHumanTakeoverStep"
    }
  ],
  "runtime": {
    "minTupiflowVersion": "0.0.0"
  },
  "workers": [
    {
      "id": "compute-hash",
      "entry": "workers/compute-hash.mjs",
      "timeoutMs": 5000,
      "memLimitMb": 64
    },
    {
      "id": "fetch-article",
      "entry": "workers/fetch-article.mjs",
      "timeoutMs": 90000,
      "memLimitMb": 256
    }
  ],
  "identity": {
    "name": "workflow-builder",
    "type": "workflow-builder",
    "version": "1.3.0",
    "publisher": "tupiflow",
    "description": "Internal tools that let an AI agent introspect this app: agents, actions, workflows, executions, connections, tools, plus core meta-actions like human-takeover."
  },
  "entrypoint": "bundle.mjs",
  "capabilities": [
    "takeover.register",
    "workflow.read",
    "workflow.write",
    "db.read",
    "db.write",
    "llm.call",
    "secrets.read",
    "net.fetch",
    "worker.run",
    "code.sandbox",
    "connection.send",
    "agent.launch",
    "notifications.send"
  ],
  "requiredNpmDeps": {
    "jsdom": "^29.1.1",
    "turndown": "^7.2.4",
    "@mozilla/readability": "^0.6.0"
  },
  "takeoverTargets": [
    {
      "label": "Request human takeover",
      "actionId": "workflow-builder/request-human-takeover",
      "description": "Hand the conversation over to a human operator from a chat connection workflow."
    }
  ]
}

Signature

WQOWu2jaKN4UT1Pzbdsj4FIGTnsQshv0ISMioo41EeTU68Je3QrOtdaqouZtLs1fAIz4GH5eA5iaSa2qIUloBg==