API Reference
Agent
An Agent performs all the RunLLM actions in a support workflow.
The Agent class provides methods to interact with various integrations like Slack and Zendesk, and leverages RunLLM's AI capabilities for tasks such as answering questions, summarizing content, learning new information, tagging conversations, and more.
Note
The Agent is typically instantiated automatically by the RunLLM framework and passed to your task functions. You will never need to create instances manually.
answer
answer(target: Conversation) -> AssistantChatMessage
Generates an answer to the last user question in the conversation.
This method uses RunLLM's AI to generate a response to the user's most recent message.
The response is not automatically sent to any surface - you must explicitly send it
using methods like send_to_slack_thread() or send_to_zendesk_ticket().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
Conversation
|
The conversation to respond to. Must have a non-null |
required |
Returns:
| Type | Description |
|---|---|
AssistantChatMessage
|
An AssistantChatMessage containing the AI-generated response. |
Example
# Respond to a user's question in a Slack thread.
response = agent.answer(event.conversation)
slack_thread = agent.create_or_get_slack_thread(
event.conversation, "T123", "C456"
)
apply_tag
apply_tag(tag: str, to: Conversation) -> None
Applies a tag to the specified conversation.
This method manually adds a tag to a conversation. The tag will be associated with the conversation for tracking and categorization purposes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tag
|
str
|
The tag name to apply to the conversation. |
required |
to
|
Conversation
|
The conversation to tag. |
required |
Note
Tags are automatically attached to conversations in the RunLLM system.
You can view, search, filter, aggregate these tags in the RunLLM dashboard.
All the tags on a conversation can also be programmatically accessed
through conversation.tags.
Example
# Apply urgent tag
agent.apply_tag("urgent", event.conversation)
# Apply additional context tags
agent.apply_tag("escalated", event.conversation)
agent.apply_tag("vip-customer", event.conversation)
# Create high-priority ticket in Zendesk.
ticket = agent.create_zendesk_ticket(
event.conversation,
tags=["urgent", "escalated"],
title="URGENT: VIP Customer Issue"
)
categorize
categorize(
conversation: Conversation,
categories: Dict[str, str],
default: str,
guidelines: str | None = None,
apply_as_tag: bool = False,
) -> str
Categorizes a conversation by selecting the best-matching category.
This method analyzes the conversation content and selects the single category
that best represents the conversation's nature. Unlike tag(), this method
selects only one category and doesn't automatically apply it as a tag.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conversation
|
Conversation
|
The conversation to categorize. |
required |
categories
|
Dict[str, str]
|
Dictionary mapping category names to their descriptions. The AI will evaluate each category against the conversation. |
required |
default
|
str
|
The fallback category to return if no other category is a good match. |
required |
guidelines
|
str | None
|
Optional instructions to guide the categorization process. |
None
|
apply_as_tag
|
bool
|
Whether to apply the category as a tag. This also "pins" this group of categories to this conversation, such that only one can be applied on this conversation at a time. This is useful for triaging, for example, as priorities change over the course of the conversation. |
False
|
Returns:
| Type | Description |
|---|---|
str
|
The name of the category that best matches the conversation. |
Note
This method only returns the category name - it doesn't apply it as a tag.
Use agent.apply_tag() if you want to tag the conversation with the result.
Example
def route_conversation(agent: Agent, event: Event) -> None:
categories = {
"support": "Technical support questions and troubleshooting",
"sales": "Questions about products, pricing, or purchasing",
"billing": "Billing, invoicing, or payment-related inquiries",
"feedback": "Product feedback, feature requests, or complaints"
}
category = agent.categorize(
event.conversation,
categories=categories,
default="general",
guidelines="Consider the primary intent of the customer"
)
# Apply the category as a tag
agent.apply_tag(category, event.conversation)
# Route based on category
if category == "billing":
# Route to billing team
billing_slack = agent.create_or_get_slack_thread(
event.conversation, "T123", "C_BILLING"
)
elif category == "support":
# Create support ticket
agent.create_zendesk_ticket(
event.conversation,
tags=["support", category]
)
chat
chat(conversation: Conversation) -> AssistantChatMessage
Generates an AI response using advanced reasoning capabilities.
This method leverages RunLLM's next-generation reasoning agent to provide
more sophisticated and contextually aware responses compared to the basic
answer() method. It's ideal for complex queries that require deeper analysis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conversation
|
Conversation
|
The conversation to generate a response for. |
required |
Returns:
| Type | Description |
|---|---|
AssistantChatMessage
|
An AssistantChatMessage containing the AI-generated response. |
Note
This is the more powerful version of answer() with enhanced reasoning
capabilities. Use this for complex scenarios requiring deeper understanding.
Example
# Use advanced reasoning for complex technical questions
response = agent.chat(event.conversation)
# Send to appropriate surface
slack_thread = agent.create_or_get_slack_thread(
event.conversation, "T123", "C456"
)
agent.send_to_slack_thread(
response, slack_thread,
prefix="🤖 Advanced Analysis:"
)
create_discord_thread
create_discord_thread(
guild_id: str, channel_id: str
) -> DiscordThread
Creates a new Discord thread in the specified channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
guild_id
|
str
|
The Discord guild (server) ID. |
required |
channel_id
|
str
|
The Discord channel ID where the thread should be created. |
required |
Returns:
| Type | Description |
|---|---|
DiscordThread
|
A DiscordThread object representing the newly created thread. |
create_or_get_discord_thread
create_or_get_discord_thread(
conversation: Conversation,
guild_id: str,
channel_id: str,
) -> DiscordThread
Creates or retrieves a Discord thread for the given conversation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conversation
|
Conversation
|
The conversation to associate with the Discord thread. |
required |
guild_id
|
str
|
The Discord guild (server) ID. |
required |
channel_id
|
str
|
The Discord channel ID where the thread should exist. |
required |
Returns:
| Type | Description |
|---|---|
DiscordThread
|
A DiscordThread object for this conversation. |
create_or_get_slack_thread
create_or_get_slack_thread(
convo: Conversation, team_id: str, channel_id: str
) -> SlackThread
Creates or retrieves a Slack thread for the given conversation.
This method ensures that each conversation session is consistently mapped to the same Slack thread. If a thread already exists for the session, it returns the existing thread; otherwise, it creates a new one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
convo
|
Conversation
|
The conversation to associate with the Slack thread. This ensures the conversation will always be pinned to the same Slack thread. |
required |
team_id
|
str
|
The Slack team (workspace) ID (e.g., "T0123456789"). |
required |
channel_id
|
str
|
The Slack channel ID where the thread should be created (e.g., "C0123456789"). |
required |
Returns:
| Type | Description |
|---|---|
SlackThread
|
A SlackThread object representing the thread for this conversation. |
Example
@entrypoint(listeners=[widget_listener])
def handle_question(agent: Agent, event: Event) -> None:
# Create or get existing thread
slack_thread = agent.create_or_get_slack_thread(
event.conversation,
team_id="T1234567890",
channel_id="C0987654321"
)
# Generate and send response
response = agent.answer(event.conversation)
agent.send_to_slack_thread(response, slack_thread)
create_slack_thread
create_slack_thread(
team_id: str, channel_id: str
) -> SlackThread
Creates a new Slack thread in the specified channel.
Creates a fresh Slack thread without associating it with an existing conversation. This differs from create_or_get_slack_thread which maintains session consistency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
team_id
|
str
|
The Slack team (workspace) ID (e.g., "T0123456789"). |
required |
channel_id
|
str
|
The Slack channel ID where the thread should be created (e.g., "C0123456789"). |
required |
Returns:
| Type | Description |
|---|---|
SlackThread
|
A SlackThread object representing the newly created thread. |
create_zendesk_ticket
create_zendesk_ticket(
conversation: Conversation,
tags: List[str] | None = None,
title: str | None = None,
description: str | None = None,
) -> ZendeskTicket
Creates a Zendesk support ticket for the given conversation.
This method creates a new Zendesk ticket with the conversation content, allowing support teams to track and manage customer issues.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conversation
|
Conversation
|
The conversation to create a ticket for. |
required |
tags
|
List[str] | None
|
Optional list of tags to apply to the ticket for categorization. |
None
|
title
|
str | None
|
Optional custom title for the ticket. If not provided, uses the first user message as the title. |
None
|
description
|
str | None
|
Optional template for the ticket body. Use
|
None
|
Returns:
| Type | Description |
|---|---|
ZendeskTicket
|
A ZendeskTicket object representing the newly created ticket. |
Example
Basic ticket creation:
ticket = agent.create_zendesk_ticket(
event.conversation,
tags=["urgent", "billing"],
title="Billing Issue - Customer Escalation"
)
print(f"Created ticket: {ticket.ticket_id}")
Custom description template:
ticket = agent.create_zendesk_ticket(
event.conversation,
title="Technical Support Request",
description='Customer reported issue via chat widget: {conversation}'
)
learn
learn(conversation: Conversation) -> str
Instructs the Agent to learn from this conversation.
The agent will learn from the new knowledge extracted from this conversation, provided by other users. It will not learn new conversation patterns or anything behavioral.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conversation
|
Conversation
|
The conversation to learn from. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A string representing summarizing what the agent has learned. |
listen
listen(
on: List[ChatSurface],
handler: TaskWrapper,
triggers: List[Trigger] | None = None,
) -> None
Transitions to a new task and begins listening for events on specified surfaces.
This is a state transition method that allows workflows to move between different tasks based on user interactions. The agent will stop executing the current task and transition to the specified handler task, which will be invoked whenever events occur on the monitored surfaces.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
on
|
List[ChatSurface]
|
List of chat surfaces to monitor for events. When events occur on these surfaces, the handler task will be invoked. |
required |
handler
|
TaskWrapper
|
The task function (decorated with |
required |
triggers
|
List[Trigger] | None
|
Optional list of custom triggers for each surface. If not provided, default triggers will be used based on surface type. |
None
|
Note
If you only need to passively sync a conversation between multiple surfaces,
use agent.terminate(keep_in_sync=[...]) instead.
Note
Default triggers by surface type:
- Slack: AllMessages
- Zendesk: TicketComment
- Chat Widget: AllMessages
Example
@entrypoint(listeners=[widget_listener])
def initial_handler(agent: Agent, event: Event) -> None:
response = agent.answer(event.conversation)
widget = event.conversation.surface
# Create surfaces to monitor
slack_thread = agent.create_or_get_slack_thread(
event.conversation, "T123", "C456"
)
zendesk_ticket = agent.create_zendesk_ticket(event.conversation)
# Transition to follow-up task. Control will be ceded to `follow_up_handler`.
agent.listen(
on=[slack_thread, zendesk_ticket, widget],
handler=follow_up_handler
)
@task()
def follow_up_handler(
agent: Agent,
event: Event,
slack_thread: SlackThread,
zendesk_ticket: ZendeskTicket,
widget: ChatWidget,
) -> None:
# Handle the follow-up...
send_to_admin_console
send_to_admin_console(
message: ChatMessage, to: AdminConsole
) -> None
Sends a message to an admin console.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
ChatMessage
|
The message to send to the admin console. |
required |
to
|
AdminConsole
|
The admin console to send the message to. |
required |
send_to_chat_widget
send_to_chat_widget(
message: ChatMessage, to: ChatWidget
) -> None
Sends a message to the chat widget.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
ChatMessage
|
The message to send to the chat widget. |
required |
to
|
ChatWidget
|
The chat widget to send the message to. |
required |
send_to_discord_thread
send_to_discord_thread(
message: ChatMessage, to: DiscordThread
) -> None
Sends a message to a Discord thread.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
ChatMessage
|
The message to send to the Discord thread. |
required |
to
|
DiscordThread
|
The Discord thread to send the message to. |
required |
send_to_slack_thread
send_to_slack_thread(
message: ChatMessage,
to: SlackThread,
ephemeral: bool = False,
prefix: str | None = None,
enable_feedback: bool = True,
blocks: List[Dict[str, Any]] | None = None,
block_until_button_clicked: bool = False,
) -> ButtonClicked | None
Sends a chat message to a Slack thread.
This method sends messages to Slack threads with support for interactive elements like buttons. Messages can be ephemeral (visible only to the user) or public.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
ChatMessage
|
The chat message to send to the Slack thread. |
required |
to
|
SlackThread
|
The target Slack thread. |
required |
ephemeral
|
bool
|
If True, sends as an ephemeral message visible only to the user. |
False
|
prefix
|
str | None
|
Optional text to prepend to the message. |
None
|
enable_feedback
|
bool
|
If True, includes feedback buttons below the message. |
True
|
blocks
|
List[Dict[str, Any]] | None
|
Additional Slack blocks following the Slack Block Kit format, with RunLLM-specific button extensions for interactive elements. |
None
|
block_until_button_clicked
|
bool
|
If True, suspends execution until a button is clicked, then returns the clicked button information. |
False
|
Returns:
| Type | Description |
|---|---|
ButtonClicked | None
|
ButtonClicked object if a button was clicked and |
Note
For markdown blocks, verbatim = True is automatically set.
Example
Basic message sending:
response = agent.answer(event.conversation)
slack_thread = agent.create_or_get_slack_thread(
event.conversation, "T123", "C456"
)
agent.send_to_slack_thread(response, slack_thread)
Interactive buttons:
blocks = [{
"type": "buttons",
"buttons": [
{"id": "approve", "style": "primary", "text": "Approve"},
{"id": "reject", "style": "danger", "text": "Reject"}
]
}]
button_clicked = agent.send_to_slack_thread(
response, slack_thread,
blocks=blocks,
block_until_button_clicked=True
)
if button_clicked.id == "approve":
# Handle approval
pass
send_to_zendesk_ticket
send_to_zendesk_ticket(
message: ChatMessage, to: ZendeskTicket
) -> None
Sends a message to an existing Zendesk ticket as a comment.
This method adds a comment to a Zendesk ticket, allowing agents to provide updates or additional information to support representatives.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
ChatMessage
|
The message to add as a comment to the ticket. |
required |
to
|
ZendeskTicket
|
The Zendesk ticket to send the message to. |
required |
Example
@task()
def update_ticket(agent: Agent, event: Event) -> None:
# Create or get existing ticket
ticket = agent.create_zendesk_ticket(event.conversation)
# Generate an update message
update = agent.answer(event.conversation)
# Send update to the ticket
agent.send_to_zendesk_ticket(update, ticket)
stream_answer
stream_answer(convo: Conversation) -> AssistantChatMessage
Streams an answer directly to the conversation's surface in real-time.
This method generates and streams an AI response directly to the user's interface.
Unlike answer(), the response is automatically sent to the user without requiring
additional send methods.
Note
Only Chat Widgets and Admin consoles are supported. This method will raise an exception if called on other surface types.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
convo
|
Conversation
|
The conversation to respond to. Must originate from a Chat Widget. |
required |
Returns:
| Type | Description |
|---|---|
AssistantChatMessage
|
An AssistantChatMessage that has already been streamed to the user. |
Example
@entrypoint(listeners=[WidgetListener(...)])
def handle_widget_question(agent: Agent, event: Event) -> None:
# Stream response back to the chat widget.
response = agent.stream_answer(event.conversation)
print(f"Streamed response: {response.content}")
sync_conversation
sync_conversation(
conversation: Conversation, to: ChatSurface
) -> None
Backfills the entire conversation history into the target surface.
This method copies all messages from the current conversation to another surface, allowing users to see the complete conversation history in different locations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conversation
|
Conversation
|
The conversation containing the message history to copy. |
required |
to
|
ChatSurface
|
The target surface where the conversation should be replicated. |
required |
Example
chat_widget = event.conversation.surface
# Create Slack thread
slack_thread = agent.create_or_get_slack_thread(
event.conversation, "T123", "C456"
)
# Copy entire conversation history to a Slack thread.
agent.sync_conversation(event.conversation, slack_thread)
tag
tag(
conversation: Conversation,
options: Dict[str, str],
guidelines: str | None = None,
) -> List[str]
Automatically applies relevant tags to a conversation using AI reasoning.
This method analyzes the conversation content and applies appropriate tags based on the provided tag options and their descriptions. Only tags that aren't already applied to the conversation will be evaluated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conversation
|
Conversation
|
The conversation to analyze and tag. |
required |
options
|
Dict[str, str]
|
Dictionary mapping tag names to their descriptions. The AI will evaluate each tag description against the conversation content. |
required |
guidelines
|
str | None
|
Optional instructions to guide the AI's tagging decisions. |
None
|
Returns:
| Type | Description |
|---|---|
List[str]
|
List of tag names that were applied to the conversation. |
Note
Tags are automatically attached to conversations in the RunLLM system.
You can view, search, filter, aggregate these tags in the RunLLM dashboard.
All the tags on a conversation can also be programmatically accessed
through conversation.tags.
Example
def categorize_conversation(agent: Agent, event: Event) -> None:
tag_options = {
"billing": "Questions about invoices, payments, or pricing",
"technical": "Technical issues, bugs, or feature requests",
"urgent": "Issues requiring immediate attention",
"feedback": "Customer feedback, suggestions, or complaints"
}
agent.tag(
event.conversation,
options=tag_options,
guidelines="Focus on the primary intent of the customer's message"
)
print(f"Applied tags: {applied_tags}")
terminate
terminate(
keep_in_sync: List[ChatSurface] | None = None,
) -> None
Terminates the agent and stops listening to any new events.
This method ends the current workflow execution and stops the agent from responding to new events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keep_in_sync
|
List[ChatSurface] | None
|
Optional list of chat surfaces that will passively be kept in sync even after the agent terminates. Messages will be copied between these surfaces automatically. |
None
|
Example
chat_widget = event.conversation.surface
# Create Slack thread for record keeping
slack_thread = agent.create_or_get_slack_thread(
event.conversation, "T123", "C456"
)
agent.send_to_slack_thread(response, slack_thread)
# Terminate but keep widget and Slack in sync
agent.terminate(keep_in_sync=[chat_widget, slack_thread])
update_zendesk_ticket
update_zendesk_ticket(
tags: List[str], status: str, to: ZendeskTicket
) -> None
Updates a Zendesk ticket's metadata and status.
This method allows you to modify ticket properties such as tags and status based on the conversation progress or resolution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tags
|
List[str]
|
List of tags to apply to the ticket for categorization. |
required |
status
|
str
|
The new status for the ticket. Valid values are "new", "open", "pending", "on-hold", "solved", or "closed". |
required |
to
|
ZendeskTicket
|
The Zendesk ticket object to update. |
required |
Core
Conversation
Represents a conversation between users and the RunLLM agent.
A Conversation contains the context and metadata for a user interaction, including the user's message, the surface where the conversation is taking place, and any tags that have been applied for categorization.
Attributes:
| Name | Type | Description |
|---|---|---|
new_message |
UserChatMessage
|
The most recent message from the user that triggered this conversation. |
surface |
ChatSurface
|
The communication surface (Slack, Zendesk, Chat Widget) where the conversation is taking place. |
tags |
List[str]
|
A list of tags that have been applied to this conversation for categorization and tracking purposes. |
session_id
property
session_id: int
Get the unique session identifier for this conversation.
Returns:
| Type | Description |
|---|---|
int
|
The unique session identifier as an integer. |
Event
Represents an event that triggers a RunLLM support workflow or task.
An Event is the primary input to your workflow functions and contains all the context needed to handle a user interaction. It encapsulates the conversation data and serves as the entry point for your workflow logic.
Attributes:
| Name | Type | Description |
|---|---|---|
conversation |
Conversation
|
The conversation context that triggered this event, containing the user's message, surface information, and conversation metadata. |
trigger |
Trigger
|
The trigger on the listener that caused this event to occur. |
Note
Events are automatically created by the RunLLM system when users interact with your configured surfaces (chat widgets, Slack, Zendesk). You don't need to create Event objects manually.
Listeners
Listener
module-attribute
Listener = Union[
SlackListener,
WidgetListener,
DiscordListener,
AdminConsoleListener,
]
Type alias for all supported listener types.
This union type represents any valid listener configuration that can be used with the @entrypoint decorator to define where your workflow should listen for events.
This union type includes:
SlackListener: Listens for events in Slack channels and threadsWidgetListener: Listens for events from chat widgets embedded on web pagesDiscordListener: Listens for events in Discord channels and threadsAdminConsoleListener: Listens for events from the RunLLM admin console
AdminConsoleListener
Configures a workflow to listen for events from the RunLLM admin console.
This listener enables your RunLLM workflow to respond to interactions and events originating from the RunLLM admin console interface, allowing for administrative workflows and monitoring.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Literal[ADMIN_CONSOLE]
|
Always set to ADMIN_CONSOLE. |
agent_id |
int
|
The agent ID in the RunLLM dashboard. You can find this by looking at the URL of the agent's overview page. For example, if the agent's ID is 123, the URL will be: https://app.runllm.com/agent/123/overview |
DiscordChannel
Represents a specific Discord channel that a workflow monitors.
This class defines the configuration for listening to events in a specific Discord channel, including custom triggers that determine when the workflow should be activated.
Attributes:
| Name | Type | Description |
|---|---|---|
channel_id |
str
|
The Discord channel ID (e.g., "123456789012345678"). |
trigger |
Optional[Union[Trigger, List[Trigger]]]
|
Optional custom trigger(s) for this specific channel. If not provided, the listener's default trigger will be used. |
DiscordListener
Configures a workflow to listen for events in Discord.
This listener enables your RunLLM workflow to respond to messages, mentions, and other events within Discord servers. You can configure it to listen to specific channels or all channels the bot has access to.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Literal[DISCORD_THREAD]
|
Always set to DISCORD_THREAD. |
guild_id |
str
|
The Discord guild (server) ID (e.g., "123456789012345678"). |
channels |
Optional[List[DiscordChannel]]
|
Optional list of specific channels to monitor. If empty, the listener will monitor all channels the RunLLM bot has access to. |
default_trigger |
Union[Trigger, List[Trigger]]
|
The default trigger to use for channels not explicitly configured in the channels list. Defaults to Mention(). |
ListenerType
Enumerates the different types of listeners available for support workflows.
Listeners define where and how your RunLLM workflow will be triggered. Each listener type corresponds to a different communication platform or surface.
Attributes:
| Name | Type | Description |
|---|---|---|
SLACK_THREAD |
Listens for events in Slack channels or threads. |
|
WIDGET |
Listens for events from chat widgets embedded on web pages. |
|
DISCORD_THREAD |
Listens for events in Discord channels or threads. |
|
ADMIN_CONSOLE |
Listens for events from the RunLLM admin console. |
SlackChannel
Represents a specific Slack channel that a workflow monitors.
This class defines the configuration for listening to events in a specific Slack channel, including custom triggers that determine when the workflow should be activated.
Attributes:
| Name | Type | Description |
|---|---|---|
channel_id |
str
|
The Slack channel ID (e.g., "C0123456789"). |
trigger |
Optional[Union[Trigger, List[Trigger]]]
|
Optional custom trigger(s) for this specific channel. If not provided, the listener's default trigger will be used. |
SlackListener
Configures a workflow to listen for events in Slack.
This listener enables your RunLLM workflow to respond to messages, mentions, and other events within Slack workspaces. You can configure it to listen to specific channels or all channels the bot has access to.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Literal[SLACK_THREAD]
|
Always set to SLACK_THREAD. |
team_id |
str
|
The Slack team (workspace) ID (e.g., "T0123456789"). |
channels |
Optional[List[SlackChannel]]
|
Optional list of specific channels to monitor. If empty, the listener will monitor all channels in the workspace the RunLLM Slack bot has access to. |
default_trigger |
Union[Trigger, List[Trigger]]
|
The default trigger to use for channels not explicitly configured in the channels list. Defaults to Mention(). |
WidgetListener
Configures a workflow to listen for events from chat widgets.
This listener enables your RunLLM workflow to respond to messages from chat widgets embedded on web pages. The listener is configured to monitor widgets on a specific domain.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Literal[WIDGET]
|
Always set to WIDGET. |
domain |
str
|
The domain where the chat widget is hosted (e.g., "example.com"). |
Surfaces
ChatMessage
module-attribute
ChatMessage: TypeAlias = Union[
str, AssistantChatMessage, UserChatMessage
]
Type alias for all supported chat message types.
Represents any message that can be sent through the RunLLM system, including plain strings, assistant messages, and user messages.
This union type includes:
str: Plain text messagesAssistantChatMessage: Structured messages from the AI assistantUserChatMessage: Structured messages from users
ChatSurface
module-attribute
ChatSurface: TypeAlias = Union[
SlackThread,
ZendeskTicket,
ChatWidget,
DiscordThread,
AdminConsole,
]
Type alias for all supported chat surface types.
Represents any communication surface where users can interact with the RunLLM assistant, including web widgets, Slack threads, Zendesk tickets, Discord threads, and admin consoles.
This union type includes:
SlackThread: Slack channels and message threadsZendeskTicket: Zendesk support tickets and commentsChatWidget: Web-based chat widgets embedded on websitesDiscordThread: Discord channels and message threadsAdminConsole: RunLLM admin console interface
AdminConsole
Represents an admin console surface.
Admin consoles are management interfaces within the RunLLM dashboard where administrators can interact with and monitor the assistant.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Literal[ADMIN_CONSOLE]
|
Always set to ADMIN_CONSOLE. |
config |
AdminConsoleConfig
|
Admin console-specific configuration including agent ID. |
AdminConsoleConfig
Configuration for admin console surfaces.
Contains the configuration for interactions through the RunLLM admin console.
Attributes:
| Name | Type | Description |
|---|---|---|
agent_id |
int
|
The agent ID in the RunLLM dashboard. You can find this by looking at the URL of the agent's overview page in the RunLLM dashboard. For example, if the agent's ID is 123, the URL will be: https://app.runllm.com/agent/123/overview |
ChatWidget
Represents a chat widget surface on a web page.
Chat widgets are embedded components that allow users to interact with the RunLLM assistant directly on websites.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Literal[CHAT_WIDGET]
|
Always set to CHAT_WIDGET. |
config |
ChatWidgetConfig
|
Widget-specific configuration including conversation ID and context. |
ChatWidgetConfig
Configuration for chat widget surfaces.
Contains the configuration and context information for interactions happening through embedded chat widgets on web pages.
Attributes:
| Name | Type | Description |
|---|---|---|
convo_identifier |
str
|
Unique UUID identifier for the current conversation. |
chat_user_id |
str | None
|
Optional identifier for the user interacting with the widget. |
context |
Dict[str, Any] | None
|
Optional page context including page_title, page_content, and url. |
DiscordThread
Represents a Discord thread surface.
Discord threads are conversation threads within Discord channels where users can interact with the RunLLM assistant.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Literal[DISCORD_THREAD]
|
Always set to DISCORD_THREAD. |
config |
DiscordThreadConfig
|
Discord-specific configuration including guild, channel, and thread info. |
DiscordThreadConfig
Configuration for Discord thread surfaces.
Contains the necessary information to identify and interact with a specific Discord thread within a channel.
Attributes:
| Name | Type | Description |
|---|---|---|
guild_id |
str
|
The Discord guild (server) ID. |
channel_id |
str
|
The Discord channel ID where the thread exists. |
thread_id |
str
|
The unique identifier of the Discord thread. |
SlackThread
Represents a Slack thread surface.
Slack threads are conversation threads within Slack channels where users can interact with the RunLLM assistant.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Literal[SLACK_THREAD]
|
Always set to SLACK_THREAD. |
config |
SlackThreadConfig
|
Slack-specific configuration including team ID, channel, and thread info. |
link
link() -> str
Gets the link to the thread.
SlackThreadConfig
Configuration for Slack thread surfaces.
Contains all the necessary information to identify and interact with a specific Slack thread within a channel.
Attributes:
| Name | Type | Description |
|---|---|---|
bot_conn_token |
str
|
The bot connection token for API access. |
team_id |
str
|
The Slack team (workspace) ID. |
channel |
str
|
The Slack channel ID where the thread exists. |
thread_ts |
Optional[str]
|
The timestamp of the thread's parent message. None if the thread hasn't been created yet. |
chat_ts |
Optional[str]
|
The timestamp of a specific message to update on the next send operation. Gets cleared after use. |
SurfaceType
Enumerates the different types of communication surfaces.
Each surface type represents a different platform or channel where users can interact with the RunLLM system.
Attributes:
| Name | Type | Description |
|---|---|---|
CHAT_WIDGET |
Web-based chat widgets embedded on websites. |
|
SLACK_THREAD |
Slack channels and message threads. |
|
ZENDESK_TICKET |
Zendesk support tickets and comments. |
|
DISCORD_THREAD |
Discord channels and message threads. |
|
ADMIN_CONSOLE |
RunLLM admin console interface. |
ZendeskTicket
Represents a Zendesk ticket surface.
Zendesk tickets are support tickets where agents and customers can exchange messages and track issue resolution.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Literal[ZENDESK_TICKET]
|
Always set to ZENDESK_TICKET. |
config |
ZendeskTicketConfig
|
Zendesk-specific configuration including subdomain and ticket ID. |
id
property
id: str
Get the unique ticket identifier.
Returns:
| Type | Description |
|---|---|
str
|
The Zendesk ticket ID as a string. |
subdomain
property
subdomain: str
Get the Zendesk subdomain.
Returns:
| Type | Description |
|---|---|
str
|
The Zendesk subdomain (e.g., "company" for company.zendesk.com). |
ZendeskTicketConfig
Configuration for Zendesk ticket surfaces.
Contains the necessary information to identify and interact with a specific Zendesk support ticket.
Attributes:
| Name | Type | Description |
|---|---|---|
subdomain |
str
|
The Zendesk subdomain (e.g., "company" for company.zendesk.com). |
id |
str
|
The unique identifier of the Zendesk ticket. |
Triggers
Trigger
module-attribute
Trigger: TypeAlias = Union[
Mention, Emoji, AllMessages, TicketComment
]
Type alias for all supported trigger types.
Represents any valid trigger configuration that can be used to define when your RunLLM workflow should be activated on different surfaces.
This union type includes:
Mention: Triggers when the bot is mentioned in Slack.Emoji: Triggers when a specific emoji reaction is added in Slack.AllMessages: Triggers on any message on the surface.TicketComment: Triggers on any comment in Zendesk tickets.
AllMessages
Triggers on any message posted to a Slack channel.
This trigger activates your workflow for every message posted in the monitored Slack channel or thread, regardless of content or author. Only supported for Slack surfaces.
Emoji
Triggers when a specific emoji reaction is added to a Slack message.
This trigger activates your workflow when users add a specific emoji reaction to messages. Only triggers on the last message in a conversation thread. Only supported for Slack surfaces.
Attributes:
| Name | Type | Description |
|---|---|---|
exclude_replies |
bool
|
If True, excludes emoji reactions on user replies. Defaults to True. |
shortcode |
str
|
The emoji shortcode without colons (e.g., "ticket" for ":ticket:"). |
Mention
Triggers when the RunLLM bot is mentioned in a Slack message.
This trigger activates your workflow whenever a user mentions the bot using @botname in a Slack channel or thread. Only supported for Slack surfaces.
TicketComment
Triggers on any comment added to a Zendesk ticket.
This trigger activates your workflow whenever a new comment is added to a Zendesk support ticket, whether from an agent or customer. Only supported for Zendesk surfaces.
TriggerType
Enumerates all different triggering conditions across communication surfaces.
Triggers define the specific events or conditions that will activate your RunLLM workflow. Different surface types support different trigger types.
Attributes:
| Name | Type | Description |
|---|---|---|
MENTION |
Triggers when the bot is mentioned (Slack only). |
|
EMOJI |
Triggers when a specific emoji reaction is added (Slack only). |
|
ALL_MESSAGES |
Triggers on any new message (All surfaces). |
|
TICKET_COMMENT |
Triggers on any comment in a ticket (Zendesk only). |
Message Types
ChatMessage
module-attribute
ChatMessage: TypeAlias = Union[
str, AssistantChatMessage, UserChatMessage
]
Type alias for all supported message types.
Represents any message that can be processed by the RunLLM system, including plain strings, structured assistant messages, and user messages.
This union type includes:
str: Simple text messagesAssistantChatMessage: Messages generated by the AI assistant with metadataUserChatMessage: Messages from users with identifying information and attachments
AnswerCategory
Categorizes the quality and relevance of agent responses.
Every response generated by the RunLLM agent is automatically tagged with one of these categories to indicate the confidence level and relevance of the answer.
Attributes:
| Name | Type | Description |
|---|---|---|
IRRELEVANT |
The user's question is not relevant to the agent's capabilities. |
|
UNANSWERED |
The agent was unable to answer due to missing information or documentation. |
|
LOW_CONFIDENCE |
The agent provided an answer but had significantly less confidence in its accuracy. |
|
ANSWERED |
The agent provided a confident and relevant answer. |
AssistantChatMessage
Represents a message generated by the RunLLM assistant.
Contains the assistant's response along with metadata about the quality and confidence level of the answer.
Attributes:
| Name | Type | Description |
|---|---|---|
text |
str
|
The actual content of the assistant's message. |
chat_id |
int
|
Unique identifier for this message. |
category |
Optional[AnswerCategory]
|
The quality category of the response (answered, unanswered, etc.). |
MessageType
Enumerates the different types of messages in a conversation.
Distinguishes between messages sent by the AI assistant and those sent by human users.
Attributes:
| Name | Type | Description |
|---|---|---|
ASSISTANT |
Messages generated by the RunLLM assistant. |
|
USER |
Messages sent by human users. |
UserChatMessage
Represents a message sent by a user to the RunLLM assistant.
Contains the user's message content along with identifying information and any file attachments.
Attributes:
| Name | Type | Description |
|---|---|---|
text |
str
|
The actual content of the user's message. |
chat_id |
Optional[int]
|
Optional unique identifier for this message. |
user_identifier |
Optional[str]
|
Platform-specific user identifier. Format varies by source:
- Chat widget: Client-generated UUID
- Slack: |
attachments |
Optional[List[Dict[str, Any]]]
|
Optional list of file attachments included with the message. |
Buttons
ButtonClicked
Represents the result of a user clicking an interactive button.
This class is returned when a user clicks on interactive buttons that were sent via Slack blocks. It contains information about which button was clicked, allowing your workflow to respond appropriately to user interactions.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
The unique identifier of the button that was clicked. This corresponds to the "id" field specified when creating the button in Slack blocks. |
Example
Using interactive buttons with send_to_slack_thread():
# Define interactive buttons
approval_blocks = [{
"type": "buttons",
"buttons": [
{
"id": "approve",
"style": "primary",
"text": "✅ Approve"
},
{
"id": "reject",
"style": "danger",
"text": "❌ Reject"
},
]
}]
# Send message with buttons and wait for user interaction
button_clicked = agent.send_to_slack_thread(
response,
slack_thread,
blocks=approval_blocks,
block_until_button_clicked=True
)
# Handle user's choice
if button_clicked.id == "approve":
# Process approval
agent.send_to_slack_thread(
"Request approved! Processing now...",
slack_thread
)
elif button_clicked.id == "reject":
# Handle rejection
agent.send_to_slack_thread(
"Request rejected. Please provide feedback.",
slack_thread
)
Client
Client for publishing and managing RunLLM workflows.
Attributes:
| Name | Type | Description |
|---|---|---|
server_address |
The optional URL of the RunLLM server to connect to. |
|
api_key |
Your API key, for authentication with the RunLLM service.
You can also set it as the |
Example
from runllm import Client
from runllm.decorators import entrypoint
from runllm.bridge.listeners import WidgetListener
# Initialize client
client = Client(api_key="your-api-key")
# Define workflow
@entrypoint(listeners=[WidgetListener(domain="example.com")])
def my_workflow(agent: Agent, event: Event) -> None:
response = agent.answer(event.conversation)
agent.stream_answer(event.conversation)
# Publish workflow
client.publish("customer_support", my_workflow)
# Wait for the workflow to finish deploying.
client.watch("customer_support")
publish
publish(
name: str,
entrypoint: EntrypointWrapper,
tasks: List[TaskWrapper] | None = None,
) -> None
Publishes a workflow to the RunLLM service.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A unique name for the workflow. This identifies your workflow in the RunLLM dashboard and logs. |
required |
entrypoint
|
EntrypointWrapper
|
The main entry point function decorated with @entrypoint. This function will be called when events occur on the configured surfaces. |
required |
tasks
|
List[TaskWrapper] | None
|
Optional list of task functions decorated with @task that can be transitioned to from the entrypoint or other tasks. Include all tasks that your workflow might transition to using agent.listen(). |
None
|
watch
watch(name: str) -> None
Waits for the workflow to be fully deployed.
Prints a progress indicator while the workflow is deploying. When the workflow is ready, the function will return.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the workflow to monitor, as specified in publish(). |
required |
Decorators
entrypoint
entrypoint(
*, listeners: List[Listener], name: str | None = None
) -> Callable[[EntrypointFunction], EntrypointWrapper]
Decorator to mark a function as the entry point for a RunLLM workflow.
The entrypoint decorator defines the starting point of your RunLLM support workflow. It specifies which listeners (Slack, Chat Widget, etc.) will trigger this function and configures how the workflow should respond to user interactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
listeners
|
List[Listener]
|
List of listener configurations that define where and how this workflow should be triggered. Can include SlackListener, WidgetListener, or other supported listener types. |
required |
name
|
str | None
|
Optional custom name for this entrypoint. If not provided, uses the decorated function's name. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[[EntrypointFunction], EntrypointWrapper]
|
A decorator function that wraps the entrypoint function with RunLLM-specific configuration. |
Example
@entrypoint(
listeners=[
WidgetListener(domain="example.com"),
SlackListener(team_id="T123456789")
],
name="customer_support"
)
def handle_customer_support(agent: Agent, event: Event) -> None:
conversation = event.conversation
# Handle the customer support conversation here.
...
task
task(
*, name: str | None = None
) -> Callable[[TaskFunction], TaskWrapper]
Decorator to mark a function as a task within a RunLLM workflow.
Tasks are functions that can be transitioned to from entrypoints or other tasks using the agent.listen() method. They handle specific parts of your workflow and can be reused across different conversation flows. Once a workflow has transitioned to a task, it will become the handler for all new events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
Optional custom name for this task. If not provided, uses the decorated function's name. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[[TaskFunction], TaskWrapper]
|
A decorator function that wraps the task function with RunLLM-specific configuration. |
Example
@task()
def bidirectional_sync(
agent: Agent,
event: Event,
chat_widget: ChatWidget,
slack_thread: SlackThread,
):
# Sync messages between Slack and the Widget.
if isinstance(event.conversation.surface, SlackThread):
agent.send_to_zendesk_ticket(
event.conversation.new_message,
to=zendesk_ticket,
)
else:
response = agent.answer(event.conversation)
agent.send_to_slack_thread(response, to=slack_thread)
@entrypoint(listeners=[WidgetListener(domain="example.com")])
def handle_widget_chat(agent: Agent, event: Event) -> None:
chat_widget = event.conversation.surface
...
# Listen for new messages on the Widget and Slack.
agent.listen([chat_widget, slack_thread], bidirectional_sync)