llm
Run a chat-style request against OpenAI, OpenAI-compatible, Azure, or custom endpoints using one node and one consistent output shape.
Parameters
- providerstringdefault "openai"
- Provider backend:
"openai","openai_compatible","azure","custom" - modestringdefault "chat"
- Request mode:
"chat","responses", or"auto" - modelstringdefault provider-dependent
- Model name (for Azure, defaults to deployment when available)
- toolsarray
- OpenAI-style tool definitions, provided as a Lua table
- tool_choicestring/objectdefault "auto"
- Tool selection behavior (
"auto","required", or explicit object) - promptstring
- Direct prompt text for user content
- input_keystringdefault "prompt"
- Context key for prompt text when
promptis not set - messagesarray
- Chat-style message objects (
role,content) for chat mode - system_promptstring
- System message used when building chat
messagesautomatically - systemstring
- Alias for
system_prompt - temperaturenumber
- Sampling temperature
- max_tokensnumber
- OpenAI chat
max_tokens(mapped tomax_tokensfor chat andmax_output_tokensfor responses) - max_output_tokensnumber
- Output-token limit. Mapped to
max_completion_tokensfor chat mode andmax_output_tokensfor responses mode. - response_formatobject
- OpenAI-compatible response format override. Useful aliases:
{ type = "json_object" }or{ type = "json_schema", json_schema = { ... } } - extraobject
- Extra request fields merged into payload
- output_keystringdefault "llm"
- Prefix for output context keys
- timeoutnumberdefault 30
- Request timeout in seconds
- max_response_bytesnumber/stringdefault IRONFLOW_LLM_MAX_RESPONSE_BYTES / 26214400
- Maximum provider response body size before failing.
- azure_endpointstringconditionaldefault AZURE_OPENAI_ENDPOINT
- Azure endpoint URL
- azure_api_versionstringdefault AZURE_OPENAI_API_VERSION
- Azure API version
- azure_chat_deploymentstringconditionaldefault AZURE_OPENAI_CHAT_DEPLOYMENT
- Azure deployment for chat mode
- azure_responses_deploymentstringconditionaldefault AZURE_OPENAI_RESPONSES_DEPLOYMENT
- Azure deployment for responses mode
- api_keystringconditionaldefault provider env var
- API key or auth token
- base_urlstringconditionaldefault provider env var
- Base URL for OpenAI-compatible/custom providers
- auth_typestringdefault "bearer"
- Custom-provider auth type:
bearer,api_key, ornone - auth_headerstringdefault "x-api-key" for api_key auth
- Header used when
auth_type = "api_key" - chat_pathstringdefault "/chat/completions"
- Custom provider endpoint path for chat
- responses_pathstringdefault "/responses"
- Custom provider endpoint path for responses
auto mode will use chat by default and switch to responses only when responses_input = true.
Environment Variable Fallbacks
| Config Key | Environment Variable | Provider |
|---|---|---|
api_key | OPENAI_API_KEY | openai |
base_url | OPENAI_BASE_URL | openai |
base_url | OPENAI_COMPATIBLE_BASE_URL | openai_compatible |
base_url | LLM_BASE_URL | openai_compatible/custom |
azure_endpoint | AZURE_OPENAI_ENDPOINT | azure |
azure_api_version | AZURE_OPENAI_API_VERSION | azure |
azure_chat_deployment | AZURE_OPENAI_CHAT_DEPLOYMENT | azure |
azure_responses_deployment | AZURE_OPENAI_RESPONSES_DEPLOYMENT | azure |
api_key | AZURE_OPENAI_API_KEY | azure |
max_response_bytes | IRONFLOW_LLM_MAX_RESPONSE_BYTES | all providers |
Context Output
{output_key}_text— extracted model response text{output_key}_raw— raw provider response as JSON{output_key}_model— model used in request{output_key}_provider— resolved provider name{output_key}_mode— selected mode (chatorresponses){output_key}_status— HTTP status code{output_key}_success—trueon success{output_key}_usage— token usage section when available{output_key}_tool_calls— parsed tool call objects (if any){output_key}_tool_call_needed—truewhen model returned one or more tool calls{output_key}_tool_call_names— list of called function names{output_key}_tool_calls_normalized— provider-neutral tool calls with parsed arguments:{ id, index, type, name, arguments, raw_arguments, raw_call }
Provider response bodies are streamed with a hard byte cap before JSON parsing. Set IRONFLOW_LLM_MAX_RESPONSE_BYTES=0 to disable the global cap, or use per-node max_response_bytes for a specific trusted workflow.
Examples
OpenAI Chat (simple)
flow:step("chat", nodes.llm({
provider = "openai",
model = "gpt-5-mini",
prompt = "Hello",
temperature = 0.3,
output_key = "chat"
}))
Azure Chat
flow:step("chat", nodes.llm({
provider = "azure",
mode = "chat",
model = "gpt-5",
prompt = "Hello",
temperature = 0.3,
output_key = "azure_chat"
}))
OpenAI-compatible Responses
flow:step("responses", nodes.llm({
provider = "openai_compatible",
mode = "responses",
model = "gpt-5-mini",
prompt = "Hello",
output_key = "responses"
}))
Gemini (custom provider)
flow:step("chat", nodes.llm({
provider = "custom",
mode = "chat",
model = "gemini-3-flash-preview",
prompt = "Hello",
base_url = "https://generativelanguage.googleapis.com/v1beta/openai",
auth_type = "bearer",
api_key = env("GEMINI_API_KEY"),
output_key = "gemini_chat"
}))
OpenAI response_format: json_object and json_schema
flow:step("json_object", nodes.llm({
provider = "openai",
model = "gpt-5-mini",
temperature = 0.0,
prompt = "Return a JSON object with keys `language` and `topic`.",
output_key = "openai_json_object",
extra = {
response_format = {
type = "json_object",
}
}
}))
flow:step("json_schema", nodes.llm({
provider = "openai",
model = "gpt-5-mini",
temperature = 0.0,
prompt = "Return JSON with sentiment and confidence.",
output_key = "openai_json_schema",
extra = {
response_format = {
type = "json_schema",
json_schema = {
name = "sentiment_schema",
strict = true,
schema = {
type = "object",
properties = {
sentiment = { type = "string", enum = { "positive", "neutral", "negative" } },
confidence = { type = "number", minimum = 0, maximum = 1 },
},
required = { "sentiment", "confidence" },
additionalProperties = false,
},
},
}
}
}))
OpenAI Responses internal tools (web search)
flow:step("search", nodes.llm({
provider = "openai",
mode = "responses",
model = "gpt-4o-mini",
prompt = "Use web search to find ...",
output_key = "search",
extra = {
tools = {
{ type = "web_search_preview" }
},
tool_choice = "auto"
}
}))
OpenAI function calling with Lua-defined function tools
flow:step("ask", nodes.llm({
provider = "openai",
mode = "chat",
model = "gpt-5-mini",
messages = {
{ role = "user", content = "What is the current weather in Paris?" },
},
tools = {
{
type = "function",
function = {
name = "get_weather",
description = "Get the current weather for a city.",
parameters = {
type = "object",
properties = {
city = {
type = "string",
description = "City name requested by the user.",
},
},
required = { "city" },
additionalProperties = false,
},
},
},
},
tool_choice = "required",
output_key = "weather_tool",
}))
-- `weather_tool_tool_calls` contains the raw provider tool call payload:
-- {
-- {
-- id = "call_xxx",
-- type = "function",
-- function = { name = "get_weather", arguments = '{"city":"Paris"}' }
-- }
-- }
--
-- `weather_tool_tool_calls_normalized` contains the easier dispatch shape:
-- {
-- {
-- id = "call_xxx",
-- index = 0,
-- type = "function",
-- name = "get_weather",
-- arguments = { city = "Paris" },
-- raw_arguments = '{"city":"Paris"}',
-- raw_call = { ... }
-- }
-- }
llm exposes tool-calling details as {output_key}_tool_calls, {output_key}_tool_calls_normalized, {output_key}_tool_call_needed, and {output_key}_tool_call_names. Use tool_dispatch to execute returned tool calls through mapped subworkflows.
llm also merges extra into the request body as-is for providers that do not yet expose all fields in this table.
For reasoning-style chat models whose names start with gpt-5, o1, or o3, explicit temperature is omitted because those providers commonly require default sampling behavior.