Chat
Audience:
Low-code EngineersSkill Prerequisites:
Actions,Tokens,Connectors
Sends a message to an OpenAI chat model and stores the reply in a token. You can give the model instructions, pass the earlier messages of a conversation, ask for a JSON reply, and let the model run your workflows as tools.
The action works with OpenAI directly or with Microsoft Azure OpenAI. The sign-in details come from a connector.
This action is part of the PlantAnApp.OpenAi add-on. The add-on is installed separately and requires the AI feature package to be licensed. If it isn't licensed, the action fails with a not-licensed error. The OpenAI and Microsoft Azure OpenAI connector types need the same license.
Typical Use Cases
- Answer a user's question in a support chat, with your own instructions for tone and scope
- Continue a conversation by passing the earlier messages back to the model
- Turn free text into structured JSON, for example pull the name, date and amount out of an email
- Let the model run a workflow to look something up, for example an order status, before it answers
- Stream the reply word by word to a Conversation View
Don't use it to
- Send data you aren't allowed to share with OpenAI or Microsoft. Everything in the message, instructions and history leaves your server.
- Make decisions that must always be correct, such as approvals or calculations. Check the reply, or use normal actions and SQL.
- Summarize long content or write articles in bulk. Use Summarize Content or Create Articles instead.
- Send images or files. The action sends text only.
Related Actions
| Action Name | Description |
|---|---|
| Aws AI Chat | Chats with models on Amazon Bedrock. |
| VertexAI Chat | Chats with Google Vertex AI models. |
| Summarize Content | Summarizes long content with OpenAI. |
| Create Articles | Writes articles with OpenAI. |
| Count Tokens | Counts the tokens in a text for an OpenAI model, for example to check a prompt's size. |
| Speech to Text (Whisper) | Turns an audio file into text with OpenAI. |
| Add Connector | Creates a connector, for example an OpenAI connector. |
| Test Connector | Checks that a connector's details work. |
Comparing the chat actions
| Chat | Aws AI Chat | VertexAI Chat | |
|---|---|---|---|
| Provider | OpenAI or Microsoft Azure OpenAI | Amazon Bedrock | Google Vertex AI |
| Connector type | OpenAI (openAi) or Microsoft Azure OpenAI (azure.openAi) | Amazon Bedrock AI (plantanapp.aws.bedrock) | Google VertexAI (vertexAi) |
| Models | OpenAI: picked from PAA's model list. Azure: your deployment. | Claude, Llama or Titan, in fixed versions | Gemini and older PaLM models from PAA's list, or any model ID with an expression |
| Temperature and maximum length | Yes | No, fixed per model | Yes |
| JSON or JSON Schema reply | Yes | No | No |
| Workflows as tools | Yes | Claude and Llama only | No |
| Streaming | Optional | Optional | Required for Gemini, not possible for PaLM |
| Ignore Errors and On Error | Yes | No | Yes |
Connecting to OpenAI
Create a connector first, in the Connectors area or with Add Connector. See Connectors.
| Connector type | Field | Description |
|---|---|---|
OpenAI (openAi) | API Key | A secret key from your OpenAI account. |
Microsoft Azure OpenAI (azure.openAi) | Resource Name | The name of your Azure OpenAI resource. PAA calls https://<Resource Name>.openai.azure.com. |
Microsoft Azure OpenAI (azure.openAi) | API Key | A key for that resource. |
For Azure, you pick the model by deploying it in Azure first. You then enter the deployment name in the action's Deployment Id. PAA uses Azure OpenAI API version 2024-10-21.
Test Connector checks both types by asking the service for its list of models.
Input Parameter Reference
| Parameter | Description | Supports Tokens | Default | Required |
|---|---|---|---|---|
| Provider | OpenAI or Azure. Decides which connector and model fields are shown. | No | OpenAI | Yes |
| OpenAI Connector | The OpenAI connector with your API key. Shown when Provider is OpenAI. You can also switch to an expression and use a token that holds the connector ID. | Yes | empty | Yes |
| Azure Connector | The Microsoft Azure OpenAI connector. Shown when Provider is Azure. | Yes | empty | Yes |
| Deployment Id | The name of your model deployment in Azure. Shown when Provider is Azure. | Yes | empty string | Yes |
| Model | The OpenAI model, for example gpt-4o. Shown when Provider is OpenAI. The list comes from PAA's AI model table. With an expression, the model name must still be one from that list. See Models. | Yes | empty string | Yes |
| Stream Response | Streams the reply to a Conversation View while it's being written. See Streaming. | No | false | No |
| Live Stream Name | The name of the live stream. It must be unique across the site. Shown when Stream Response is on. | Yes | empty string | With streaming |
| Message Stream ID | The ID of this message in the live stream. It must be unique within the live stream. Shown when Stream Response is on. | Yes | empty string | With streaming |
| Instructions | The system message. Tells the model how to behave, for example You are a helpful support assistant for [CompanyName]. Answer in one short paragraph. | Yes | empty string | No |
| Previous Messages | The earlier messages of the conversation, as a JSON array. See Messages and history. | Yes | empty string | No |
| Message | The new user message, for example [Question]. It's always sent as one user message, as plain text. | Yes | empty string | Yes |
| Workflows | Workflows the model may run as tools. Pick them from the list, or use an expression with the workflow ID or GUID. See Workflows as tools. | Yes | empty | No |
| Dynamic Workflows | More workflow IDs or GUIDs, separated by commas or new lines. They're added to Workflows. | Yes | empty string | No |
| Response Format | Text, JSON or JSON Schema. With an expression, use text, json_object or json_schema. See JSON replies. | Yes | empty | No |
| JSON Schema | The schema the reply must follow. Used only when Response Format is JSON Schema. | Yes | empty string | No |
| Temperature | How random the reply is, from 0 to 2, for example 0.2. Lower values give more focused and repeatable answers. If empty, OpenAI's default is used. | No | empty | No |
| Maximum Length | The maximum number of tokens the model may write in its reply. If the limit is reached, the reply is cut off. If empty, the model's own limit applies. | No | empty | No |
| Resource ID | A label saved with PAA's usage record for this call, so you can see where the usage came from. For example Acme/Conversation/[ConversationId]/response. | Yes | empty string | No |
| Ignore Errors | If on, an error doesn't stop the actions that follow. The error is written to the site's event log. On Error still runs. | No | false | No |
| On Error | Actions to run when the call fails. They can use [ErrorMessage], [ErrorCode] and [ErrorJson]. See Errors. | No | empty | No |
Output Parameters Reference
| Parameter | Description |
|---|---|
| Store Output Message | The token that gets the model's reply as text. With a JSON response format, the text is the JSON. |
| Store Entire Conversation JSON | The token that gets the whole conversation as a JSON array, including the new message and the reply. You can pass it back as Previous Messages in the next call. The system message isn't included. |
| Store Entire Output | The token that gets OpenAI's full JSON response, including the usage token counts and finish_reason. Not available when Stream Response is on. If the model ran workflows, it's the last response. |
| Store AI Debug Payloads JSON | The token that gets a JSON array with every request sent and response received, with timestamps. Useful for troubleshooting. Your API key isn't included. |
| Store Usage ID | The token that gets the ID (a GUID) of PAA's usage record for this call. |
Models
With the OpenAI provider, the Model list comes from PAA's AI model table. In 1.28 it has these models: gpt-3.5-turbo, gpt-3.5-turbo-0125, gpt-3.5-turbo-0301, gpt-3.5-turbo-0613, gpt-3.5-turbo-1106, gpt-3.5-turbo-16k, gpt-3.5-turbo-16k-0613, gpt-3.5-turbo-instruct, gpt-4, gpt-4-0125-preview, gpt-4-0613, gpt-4-1106-preview, gpt-4-32k, gpt-4-32k-0613, gpt-4-turbo, gpt-4-turbo-preview, gpt-4-vision-preview, gpt-4o and gpt-4o-2024-05-13.
- PAA records usage for every call, so the model must be in this list. A model name that isn't in the list fails, even when you use an expression.
- Some of these models have been retired by OpenAI, and
gpt-3.5-turbo-instructisn't a chat model. If you aren't sure, usegpt-4o.
With the Azure provider, the model is whatever you deployed. The model name Azure reports back must be in PAA's Azure list (gpt-35-turbo, gpt-35-turbo-16k, gpt-4, gpt-4-32k, gpt-4o, gpt-4o-2024-05-13). Otherwise the action fails after the reply arrives, because the usage record can't be saved.
Messages and history
Each call sends, in this order:
- The
Instructionsas asystemmessage. - The messages in
Previous Messages, if any. - The
Messageas ausermessage.
Previous Messages uses OpenAI's message format. Roles are system, user, assistant and tool:
[
{ "role": "user", "content": "Hi, my printer won't print." },
{ "role": "assistant", "content": "Sorry to hear that. Is it showing an error light?" }
]
The easiest way to keep a conversation going is to store Store Entire Conversation JSON in a token and pass that token back as Previous Messages next time. The stored JSON uses Role and Content keys and has a few extra keys, such as tool_calls. That's fine, you can pass it back unchanged. If the model ran workflows, the tool calls and their results are part of it.
If Previous Messages isn't valid JSON, the action fails with The Previous Messages parameter is not valid JSON.
JSON replies
Response Format asks the model for a specific format:
| Value | Result |
|---|---|
Text (text) | A normal text reply. |
JSON (json_object) | The reply is a valid JSON object. OpenAI requires the word "JSON" in your instructions or message, so say what JSON you want. |
JSON Schema (json_schema) | The reply follows the schema in JSON Schema. |
JSON Schema holds OpenAI's json_schema object: a name, the schema itself and, optionally, "strict": true. For example:
{
"name": "invoice",
"strict": true,
"schema": {
"type": "object",
"properties": {
"customer": { "type": "string" },
"total": { "type": "number" }
},
"required": ["customer", "total"],
"additionalProperties": false
}
}
Keep these limits in mind:
- PAA only sends
Response Formatfor these models:gpt-4o,gpt-4o-2024-08-06,gpt-4o-mini,gpt-4o-mini-2024-07-18,gpt-4-0125-preview,gpt-4-turbo-preview,gpt-4-1106-preview,gpt-3.5-turbo,gpt-3.5-turbo-0125andgpt-3.5-turbo-1106. For other models, and for the Azure provider, it's ignored and you get a text reply. JSON Schemaneeds a model that supports structured outputs, such asgpt-4o. Older models return an error.- The reply is text in
Store Output Message. Parse it with a JSON action before you use its values.
Workflows as tools
Add workflows in Workflows or Dynamic Workflows to let the model run them. The model decides whether to run one, based on the question.
- PAA describes each workflow to the model with its name, its description and its input fields. Give them clear names and descriptions. Characters other than letters, numbers,
_and-are removed from the name. - When the model asks for a workflow, PAA runs it in a new, separate context. The model's arguments become tokens named after the input fields. Tokens from the calling action aren't available.
- The workflow's output fields go back to the model as text, for example
Status: Shipped. The model can call more workflows, then writes its final reply. - Each workflow call is another request to OpenAI and adds to the cost.
See Workflows for how to set up input and output fields.
Streaming
With Stream Response on, the reply is sent to a live stream while the model writes it. The action still waits for the full reply and stores it in Store Output Message.
Streaming is meant for the Conversation View:
- Fill in
Live Stream NameandMessage Stream ID, and use the same values in the Conversation View. - Add a
Statuscolumn in the Conversation View settings. It can beprocessing,doneorerror(not case-sensitive), or0,1or2. - Set the status to
processingbefore the Chat action runs. Set it todoneorerrorafter it.
Store Entire Output isn't available when streaming.
Errors
When the call fails, for example because of a wrong API key or an unknown model, On Error runs with these tokens:
| Token | Value |
|---|---|
[ErrorMessage] | The error message, from OpenAI when there is one. |
[ErrorCode] | The HTTP status code from OpenAI, for example 401. Empty for errors inside PAA. |
[ErrorJson] | OpenAI's error response as JSON. Empty for errors inside PAA. |
After On Error:
- If an
On Erroraction stops execution, that result is used. - Otherwise, if
Ignore Errorsis off, the action fails with the error. - If
Ignore Errorsis on, the error is logged and the next action runs.
If you set Store Entire Conversation JSON or Store AI Debug Payloads JSON, they're filled in even when the call fails.
Retries and timeouts:
- If OpenAI answers
Too Many Requests, PAA waits 20 seconds and tries again. It keeps trying until the call succeeds or fails with another error. - Each request times out after 5 minutes. A timed-out request is sent again.
Considerations
- Data privacy. The instructions, history, message and workflow results are sent to OpenAI or Microsoft. Don't send personal or confidential data unless your agreement with the provider allows it.
- Cost. You pay the provider for every token sent and received. Long histories and workflow calls add up. Use
Maximum Lengthand Count Tokens to keep calls small. - Replies can be wrong. Check important answers before you act on them.
- Building JSON with tokens. Token values aren't escaped when they're placed in JSON. If you build
Previous MessagesorJSON Schemaby hand, a quote or line break in a token value breaks the JSON. Prefer passing backStore Entire Conversation JSONunchanged. - Usage records. PAA saves a usage record for each call, with the model, the token and word counts, the timing, any workflow calls and any error code.
Resource IDandStore Usage IDhelp you find it. - Conditions. In the action's
Condition, token values are placed in quotes, for example[Question] != "". See Common Parameters.
Examples
To understand how to use the below examples, please see Running Examples.
Replace the connector ID 00000000-0000-0000-0000-000000000000 with the ID of your own connector, or select the connector after you import the action.
1. Answer a support question
This action sends the user's question to gpt-4o with short instructions and stores the answer in Answer. It runs only when Question has a value.
{
"Title": "Chat",
"ActionType": "OpenAi.Chat",
"Description": "Answer the support question",
"Condition": "[Question] != \"\"",
"Parameters": {
"Provider": "openAi",
"OpenAiConnector": {
"Entry": "00000000-0000-0000-0000-000000000000"
},
"Model": "gpt-4o",
"Instructions": "You are a helpful support assistant for [CompanyName]. Answer in one short paragraph. If you don't know, say so.",
"Message": "[Question]",
"Temperature": 0.3,
"MaxTokens": 400,
"StoreMessage": "Answer"
}
}
2. Continue a conversation
This action passes the stored conversation back as history, sends the new message, and saves the updated conversation in the same token. If the call fails, the error is logged and the user gets a fallback answer.
{
"Title": "Chat",
"ActionType": "OpenAi.Chat",
"Description": "Reply in the ongoing conversation",
"Parameters": {
"Provider": "openAi",
"OpenAiConnector": {
"Entry": "00000000-0000-0000-0000-000000000000"
},
"Model": "gpt-4o",
"Instructions": "You are a friendly assistant for our booking site.",
"PreviousMessageJson": "[ConversationJson]",
"Message": "[UserMessage]",
"ResourceId": "Booking/Conversation/[ConversationId]/response",
"StoreMessage": "Answer",
"StoreEntireConversationJson": "ConversationJson",
"IgnoreErrors": true,
"OnError": [
{
"Title": "Log Error",
"ActionType": "LogError",
"Parameters": {
"Message": "Chat failed ([ErrorCode]): [ErrorMessage]"
}
}
]
}
}
3. Extract structured data from an email
This action asks for a reply that follows a JSON schema, then stores the JSON in InvoiceJson.
{
"Title": "Chat",
"ActionType": "OpenAi.Chat",
"Description": "Extract invoice details",
"Parameters": {
"Provider": "openAi",
"OpenAiConnector": {
"Entry": "00000000-0000-0000-0000-000000000000"
},
"Model": "gpt-4o",
"Instructions": "Extract the customer name and the invoice total from the email.",
"Message": "[EmailBody]",
"ResponseFormat": "json_schema",
"JsonSchema": "{ \"name\": \"invoice\", \"strict\": true, \"schema\": { \"type\": \"object\", \"properties\": { \"customer\": { \"type\": \"string\" }, \"total\": { \"type\": \"number\" } }, \"required\": [\"customer\", \"total\"], \"additionalProperties\": false } }",
"Temperature": 0,
"StoreMessage": "InvoiceJson"
}
}
4. Let the model look up an order
This action gives the model a workflow it can run, for example one with an OrderNumber input and a Status output. The model runs it when the user asks about an order. It uses an Azure deployment.
{
"Title": "Chat",
"ActionType": "OpenAi.Chat",
"Description": "Answer order questions with the lookup workflow",
"Parameters": {
"Provider": "azure.openAi",
"AzureOpenAiConnector": {
"Entry": "00000000-0000-0000-0000-000000000000"
},
"DeploymentId": "support-gpt-4o",
"Instructions": "You help customers with their orders. Use the tools to look up order details. Never guess an order status.",
"Message": "[Question]",
"DynamicWorkflows": "[OrderLookupWorkflowId]",
"StoreMessage": "Answer",
"StoreAiDebugPayloads": "ChatDebug"
}
}
Revised 09/27/2026