Skip to content

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 new_message field.

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 {conversation} to include the full conversation content. Defaults to

Conversation:

{conversation}
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 @task) to transition to.

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 block_until_button_clicked is True, otherwise None.

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 threads
  • WidgetListener: Listens for events from chat widgets embedded on web pages
  • DiscordListener: Listens for events in Discord channels and threads
  • AdminConsoleListener: 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 messages
  • AssistantChatMessage: Structured messages from the AI assistant
  • UserChatMessage: 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 threads
  • ZendeskTicket: Zendesk support tickets and comments
  • ChatWidget: Web-based chat widgets embedded on websites
  • DiscordThread: Discord channels and message threads
  • AdminConsole: 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() -> 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 messages
  • AssistantChatMessage: Messages generated by the AI assistant with metadata
  • UserChatMessage: 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: : - Discord: Discord user ID

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 RUNLLM_API_KEY environment variable instead.

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)