LLM

September 21, 2026 · View on GitHub

The LLM node processes text with a language model or generates images. It supports text generation, vision (image input), image generation, structured JSON output, and provider-native Batch API execution for supported text models.

Overview

PropertyValue
Inputs1
Outputs1, plus optional batchStatus when batch mode is enabled
Output$nodeLabel.text (text), $nodeLabel.image (image), or batch result fields such as $nodeLabel.results

Parameters

Credential & Model

ParameterTypeDescription
credentialIdUUIDLLM credential from Credentials
modelstringModel name (e.g. gpt-4o, gemini-2.5-flash-lite, nanobanana for images)
fallbackCredentialIdUUID (optional)Fallback credential when primary fails
fallbackModelstring (optional)Fallback model when primary fails

If the primary credential or model returns an error, the node automatically retries with the fallback credential and model before failing.

Heym also checks batch capability from the selected credential and model. Batch mode is available for:

  • OpenAI credentials
  • Custom / OpenAI-compatible credentials whose endpoint exposes the required /v1/files and /v1/batches APIs

If the selected provider or model does not support batch execution, the Properties panel shows that directly and disables the toggle.

Prompts (text mode)

ParameterTypeDescription
systemInstructionstringSystem prompt. Supports expressions.
userMessagestringUser message. Default: $input.text
temperaturenumber0.0–2.0 (default: 0.7)
maxTokensnumberMax response tokens (optional)
requestTimeoutSecondsnumberMax seconds to wait for the model response before timing out (default: 60). Raise it for slow or self-hosted providers (LiteLLM, vLLM, local models).

Image & Output

ParameterTypeDescription
outputType"text" | "image"Text or image generation
imageInputEnabledbooleanInclude image with user message (vision)
imageInputexpressionBase64 data URL or image URL
jsonOutputEnabledbooleanStructured JSON output
jsonOutputSchemastringJSON Schema for structured output
extraBodyEnabledbooleanSend provider-specific request parameters (default: false)
extraBodystringJSON object merged into the API request body

Reasoning models (o1, o3)

ParameterTypeDescription
isReasoningModelbooleanEnable for reasoning models
reasoningEffort"low" | "medium" | "high"Reasoning depth

Batch Mode

ParameterTypeDescription
batchModeEnabledbooleanUse the provider-native Batch API instead of single-request execution

Batch mode is available only on the LLM node. It does not apply to the Agent Node.

When batch mode is enabled:

  • outputType must stay text
  • imageInputEnabled must stay false
  • userMessage must resolve to an array
  • each array item must resolve to a string or primitive value

Typical examples:

  • $input.items.map("item.text")
  • $vars.promptList

If the expression resolves to a single string instead of an array, the run fails with a validation error before the provider call starts.

Batch Status Branch

When batch mode is enabled, the LLM node exposes a second output handle: batchStatus.

Use that branch for notifications, logging, Slack messages, or side effects while the batch is still running. The branch fires whenever the provider status meaningfully changes, including normalized states such as:

  • pending
  • processing
  • completed
  • failed

The status branch payload is available as $input inside downstream nodes and includes:

  • $input.batchId
  • $input.batchStatus
  • $input.status
  • $input.rawStatus
  • $input.total
  • $input.completed
  • $input.failed
  • $input.requestCounts.total
  • $input.requestCounts.completed
  • $input.requestCounts.failed
  • $input.provider
  • $input.model

Example edge:

{
  "id": "edge-status",
  "source": "batchLlmNode",
  "sourceHandle": "batchStatus",
  "target": "notifyProgress"
}

Example status mapper:

{
  "type": "set",
  "data": {
    "label": "notifyProgress",
    "mappings": [
      { "key": "status", "value": "$input.batchStatus" },
      { "key": "completed", "value": "$input.completed" },
      { "key": "total", "value": "$input.total" }
    ]
  }
}

Batch Result Shape

On successful completion, the main LLM output contains:

  • $nodeLabel.text – concatenated successful texts
  • $nodeLabel.batchId
  • $nodeLabel.status
  • $nodeLabel.rawStatus
  • $nodeLabel.requestCounts
  • $nodeLabel.total
  • $nodeLabel.completed
  • $nodeLabel.failed
  • $nodeLabel.results – per-item results in original order
  • $nodeLabel.usage

Each item in $nodeLabel.results includes fields such as:

  • index
  • customId
  • status
  • statusCode
  • text
  • error
  • usage

When JSON output is enabled together with batch mode, Heym parses each successful item separately. Parsed objects are exposed per item and collected on parsedResults.

Responses API

A Use Responses API checkbox routes the node's call through the Responses API instead of Chat Completions. It is off by default, and the node behaves the same either way: the same prompts, the same JSON output schema, the same result shape.

It works with an OpenAI credential, and with a custom credential whose gateway supports the endpoint, so a self-hosted or proxied setup can use it too. With a Google credential it stays disabled, and it cannot be combined with Batch mode - the node panel says where a given credential stands before you run anything.

If the endpoint turns out to be unavailable at run time, the node fails with a message naming the cause rather than quietly falling back, so a node configured for the Responses API is always running on it. To fall back to another credential or model deliberately, use the Fallback Credential and Fallback Model fields; they inherit this checkbox, so a fallback credential also needs to support the endpoint.

Image Generation

  • Models: nanobanana, gemini-2.0-flash-exp
  • Output: $nodeLabel.image (base64 data URL)
  • When using Input for the prompt, use $userPrompt.body.text in userMessage

JSON Output

When jsonOutputEnabled is true, the LLM returns JSON matching the schema. Access fields via $nodeLabel.fieldName.

Extra Body

Some providers accept request parameters that the standard OpenAI-compatible fields do not cover, such as disabling a model's thinking mode. Tick Send extra request body in the node properties and enter a JSON object. It is merged into every API request this node makes.

{
  "extraBodyEnabled": true,
  "extraBody": "{ \"thinking\": { \"type\": \"disabled\" } }"
}
  • Disabled by default. With the checkbox off, nothing extra is sent.
  • Must be a JSON object. An array, a scalar, or malformed text fails the node with Invalid extra body JSON rather than being silently dropped.
  • The Format button next to the checkbox reformats the JSON, and turns red reading Invalid when the text does not parse.
  • Applied to the main completion, the fallback model attempt, and batch mode requests. Not applied to image generation or to guardrail checks, which use a different request shape and a separate model.
  • $ expressions are resolved before parsing, so {"max_tokens": $prev.limit} works. Because this is textual substitution, a resolved value containing a double quote or a newline produces invalid JSON and fails the node.

Example – Text

{
  "type": "llm",
  "data": {
    "label": "generateResponse",
    "credentialId": "credential-uuid",
    "model": "gpt-4o",
    "systemInstruction": "You are a helpful assistant.",
    "userMessage": "$userInput.body.text"
  }
}

Example – Batch text

{
  "nodes": [
    {
      "id": "var_1",
      "type": "variable",
      "position": { "x": 120, "y": 180 },
      "data": {
        "label": "batchPrompts",
        "variableName": "promptList",
        "variableType": "array",
        "variableValue": "$array(\"Summarize this invoice\", \"Draft a follow-up email\", \"Classify the invoice status\")"
      }
    },
    {
      "id": "llm_1",
      "type": "llm",
      "position": { "x": 420, "y": 180 },
      "data": {
        "label": "batchLlm",
        "credentialId": "credential-uuid",
        "model": "gpt-4o-mini",
        "batchModeEnabled": true,
        "systemInstruction": "Answer each item briefly.",
        "userMessage": "$vars.promptList"
      }
    },
    {
      "id": "set_1",
      "type": "set",
      "position": { "x": 760, "y": 70 },
      "data": {
        "label": "progressUpdate",
        "mappings": [
          { "key": "status", "value": "$input.batchStatus" },
          { "key": "completed", "value": "$input.completed" }
        ]
      }
    },
    {
      "id": "out_1",
      "type": "output",
      "position": { "x": 760, "y": 280 },
      "data": {
        "label": "batchResult",
        "outputKey": "responses"
      }
    }
  ],
  "edges": [
    { "id": "e1", "source": "var_1", "target": "llm_1" },
    { "id": "e2", "source": "llm_1", "sourceHandle": "batchStatus", "target": "set_1" },
    { "id": "e3", "source": "llm_1", "target": "out_1" }
  ]
}

Example – Image generation

{
  "type": "llm",
  "data": {
    "label": "generateImage",
    "credentialId": "credential-uuid",
    "model": "nanobanana",
    "outputType": "image",
    "userMessage": "$userPrompt.body.text"
  }
}

Guardrails

Enable Guardrails in the node properties to block unsafe user messages before the LLM call. See Guardrails for the full reference.