Poe Python Reference

The following is an API reference for the Poe Python library. This library is auto-imported to the poe namespace on Poe Python interpreter startup. The reference assumes that you used import fastapi_poe as fp. See also fastapi_poe: Python API Reference for more low-level functionality.

poe.Sender

A simple dataclass representing an author/sender of a message in chat.

Fields:

  • role (Literal["user", "bot", "system", "tool"]): a string representing the sender's role. The only allowed values are user, bot, system, or tool.
  • id (str | None = None): a unique identifier of a bot or user.
  • name (str | None = None): a display name of a user or bot.

poe.Attachment

A class representing a message attachment. Attachments are stored in Poe's infrastructure and are accessible to users and bots in the chat. You can create an attachment by specifying either its content or a URL (but not both):

one_attachment = poe.Attachment(
    name="report.csv", contents=b"a,b,c\n1,2,3",
)
other_attachment = poe.Attachment(
    name="tiger",
    url="http://my.hosting.com/tiger.jpg",
    content_type="image/jpeg",
    is_inline=True,
)

Parameters:

  • name (str): name of the attachment file (required).
  • contents (bytes | None = None): contents of the attachment encoded as bytes.
  • url (str | None = None): a URL of the attachment. For third-party URLs, the attachment will be downloaded, and re-uploaded to Poe's infrastructure.
  • content_type (str | None = None): content type of the attachment as a MIME string (e.g. image/jpeg). If not provided, Poe backend will attempt to infer the content type from the contents.
  • is_inline (bool = False): whether this attachment should be rendered inline, or at the end of the message. This is only supported for image attachments in Markdown messages.

Properties:

  • name (str): name of the attachment.
  • content_type (str): attachment content type (provided or inferred).
  • url (str): attachment URL (this will always points to Poe's storage).
  • inline_ref (str | None): a string with Markdown reference for this attachment. If is_inline=False was specified in the constructor, this will be set to None.

Attachment.get_contents

Fetch (if needed) and return the content of the attachment.

Returns:

  • bytes: attachment content encoded as a Python bytes object.

Attachment.copy

Return a (possibly modified) copy of the attachment. Attachments are immutable objects, so this should be used in situations where you want to modify some fields of an existing attachment object.

Parameters:

  • name (str = ...): new name of the attachment file. If not provided, the original name will be used.
  • is_inline (bool = ...): new value of the inline status of the attachment. If not provided, the original inline status is used.

Returns:

  • poe.Attachment: new attachment object copied from the original.

Attachment.from_protocol_attachment

Convert a low-level fastapi_poe attachment object into an equivalent poe.Attachment object.

Parameters:

  • a (fp.Attachment): a low-level attachment object to convert.

Returns:

  • poe.Attachment: an attachment object equivalent to the low-level input.

Attachment.to_protocol_attachment

Converts the poe.Attachment object into a low-level fastapi_poe attachment object.

Returns:

  • fp.Attachment: new fastapi_poe attachment object equivalent to the original attachment.

Attachment.__add__ and Attachment.__radd__

Attachments support the + operator to easily transform a string into a message with the attachment or to add the attachment to an existing message. For example:

message = poe.Message(text="Here's my report")

# Create an attachment in another message.
with poe.start_message() as other_message:
    attachment = other_message.attach_file(
        name="data.csv",
        contents=b"a,b,c\n1,2,3",
    )

# Combine the message with the attachment.
message_with_attachment = message + attachment
# The opposite order works as well.
message_with_attachment = attachment + message

Parameters:

  • other (str | poe.Message): the second operand for + can be either a plain Python string, or a message object.

Returns:

  • poe.Message: a new message with the attachment appended or prepended.

poe.Message

A class representing a message in a chat. It is essentially an extended version of Python string. Although it supports incremental construction, it is handled as immutable in most contexts. To create a mutable message, pass in_progress=True to the constructor. This will enable various methods modifying the message (see below). It is recommended to call msg.finish() when modifications are not needed anymore.

Parameters:

  • text (str): text of the message.
  • sender (poe.Sender | Literal["user", "bot", "system", "tool"] = "user"): sender of the message. You can provide either a poe.Sender object or a plain string. In the latter case, it will be converted to poe.Sender(role=sender, id=None, author=None).
  • content_type (Literal["text/markdown", "text/plain"] = "text/markdown"): content type of the message. Currently plain text and Markdown messages are supported.
  • attachments (list[poe.Attachment] | None = None): a list of attachments to include in the message.
  • in_progress (bool = False): if True, allow updating content of the message. This may be useful when streaming a response from a bot. It is recommended to call msg.finish() as soon as you don't expect more updates.
  • is_tool_call (bool = False): if True this message is created for the purpose of tool calling protocol. Its content should be a serialized JSON and not human readable. Only use this flag if you want to control tool call loop manually.
  • parameters (dict[str, Any] | None = None): a JSON dictionary with any bot-specific parameters for this message.

Properties:

  • text (str): text of the message.
  • role (Literal["user", "bot", "system", "tool"]): role of the message author. This is an alias to msg.sender.role.
  • sender (poe.Sender): sender of this message.
  • content_type (Literal["text/markdown", "text/plain"]): content type of the message.
  • attachments (tuple[poe.Attachment, ...]): attachments attached to this message as an (immutable) tuple.
  • is_tool_call (bool): if True this message is created for the purpose of tool calling protocol.
  • parameters (dict[str, Any]): a JSON dictionary with any bot-specific parameters for this message.

Message.write

Append a string to the message text. This method will raise a ValueError exception if the message was created with in_progress=False, or after a call to msg.finish().

Parameters:

  • text (str): a string to append to the message text.

Returns: None

Message.overwrite

Overwrite message text with a new value. This method will raise a ValueError exception if the message was created with in_progress=False, or after a call to msg.finish(). For example:

import time

msg = poe.Message(text="thinking...", in_progress=True)
time.sleep(5)
msg.overwrite("No solutions found!")

Parameters:

  • text (str): a new value of the message text.

Returns: None

Message.add_attachment

Add an existing attachment object to this message. If the message content type is Markdown and the attachment is inline, an inline reference to the attachment will be (optionally) appended to the message text. This method will raise a ValueError exception if the message was created with in_progress=False, or after a call to msg.finish().

Parameters:

  • attachment (poe.Attachment): an attachment to add to the message.
  • add_inline_ref (bool = True): if True (default) automatically append a Markdown reference to the message text if the attachment is inline.

Returns: None

Message.update

Update the message as specified by a fp.PartialResponse object. This will call msg.write(), msg.overwrite(), and/or msg.add_attachment() automatically. This method will raise a ValueError exception if the message was created with in_progress=False, or after a call to msg.finish().

Parameters:

  • part (fp.PartialResponse): an item in the response stream from a bot.

Returns: None

Message.attach_file

Create a new attachment with the specified content, and attach it to the message. This is a convenience helper that calls poe.Attachment(...) followed by msg.add_attachment(). This method will raise a ValueError exception if the message was created with in_progress=False, or after a call to msg.finish().

Parameters:

  • name (str): name of the attachment file.
  • contents (bytes): contents of the attachment encoded as bytes.
  • content_type (str | None = None): content type of the attachment, if not provided, Poe backend will attempt to infer the content type from the contents.
  • is_inline (bool = False): whether this attachment should be rendered inline, or at the end of the message. This is only supported for image attachments in Markdown messages.

Returns:

  • poe.Attachment: a newly created attachment object that was added to the message.

Message.finish

Calling this method will prevent any future updates to the message. This method will raise a ValueError exception if the message was created with in_progress=False, or if it was already called before.

Returns: None

Message.copy

Return a (possibly modified) shallow copy of the message. Finished messages are immutable objects, so this should be used in situations where you want to modify some fields of an existing message object. You cannot copy a message that is still in progress. This method will raise a ValueError exception if the message was created with in_progress=True and msg.finish() was not called.

Parameters:

  • text (str = ...): If not provided, the original text will be used.
  • sender (poe.Sender | Literal["user", "bot", "system", "tool"] = ...): If not provided, the original sender will be used.
  • attachments (list[poe.Attachment] = ...): If not provided, the original attachments will be used.
  • parameters (dict[str, Any] = ...): If not provided, the original parameters will be used.

Returns:

  • poe.Message: new message object copied from the original.

Message.from_protocol_message

Convert a low-level fastapi_poe message object into an equivalent poe.Message object.

Parameters:

  • m (fp.ProtocolMessage): a low-level message object to convert.

Returns:

  • poe.Message: a message object equivalent to the low-level input.

Message.to_protocol_message

Converts the poe.Message object into a low-level fastapi_poe message object.

Returns:

  • fp.ProtocolMessage: new fastapi_poe message object equivalent to the original attachment.

Message.__add__ and Message.__radd__

Messages support the + operator to easily concatenate two messages, add a string to the message text, or add some attachment(s).

# Combine messages with strings.
greeting = poe.Message(text="Hello, ")
name = "Alice"
full_greeting = greeting + name

# Combine multiple messages.
question = poe.Message(text="What is ")
topic = poe.Message(text="quantum computing")
question_mark = "?"
full_question = question + topic + question_mark

Note: If both operands are messages, the fields of the right operand will take precedence when merging. The parameters field will be shallow merged with the precedence of the right values for colliding keys.

Parameters:

  • other (str | poe.Message | poe.Attachment | list[poe.Attachment]): the other operand of the + operator. This can be a string, another message, an attachment, or a list of attachments.

Returns:

  • poe.Message: a new message object that represents the concatenation of the operands.

Message.__enter__

The poe.Message class implements context manager protocol, that will call msg.finish() when exiting context manager. It is recommended to use the context manager syntax instead of calling msg.finish() manually.

Returns:

  • poe.Message: the original message object.

Message.__contains__

Messages support the Python in operator and will check if the given substring is present in the message text. So that some_text in msg is a shorthand for some_text in msg.text.

Parameters:

  • item (str): a substring to search in the message text.

Message.__format__

Messages can be used in f-strings directly, their text will be used automatically:

# No need to use message.text below.
message = poe.Message(text="Attention!")
bold_text = f"**{message}**"

poe.Chat(Sequence[poe.Message])

This class represents a chat, a sequence of messages. This may be an abstract sequence of messages, not necessarily the one you see in Poe chat UI. This class implements full Python sequence protocol.

Parameters:

  • *args (str | poe.Message | poe.Chat): all positional arguments should be either a string, a message, or another chat. They will be flattened and available as a messages field.
  • initial_length (int | None = None): all messages after this number are considered new messages. If not provided, this is set to number of messages used in constructor. This can be used to track which messages were added by which bot calls, for example using Chat.make_child() and/or Chat.new_messages().
  • quiet (bool = True): If False, each message added to this chat after its creation will be echoed to the Poe chat UI.

Properties:

  • last (poe.Message): last message in chat. This an alias to chat.messages[-1].
  • text (str): text of all messages in chat concatenated using newline. Messages with is_tool_call=True are not included.

Chat.add_message

Add a new message to chat. If chat was created with quiet=False this will also echo the message in Poe chat UI.

Parameters:

  • message (poe.Message | str): a message to add to the chat. A string will be converted to poe.Message(text=message).

Returns: None

Chat.add_messages

Add multiple messages to chat. If quiet=False this will also echo the messages in Poe chat UI.

Parameters:

  • messages (Iterable[poe.Message | str]): messages to add to chat. Each string will be converted to poe.Message(text=message).

Returns: None

Chat.start_message

Create a new empty message with in_progress=True and call chat.add_message() using it as argument. Since poe.Message objects implement context manager protocol, you can use the context manager pattern (recommended). For example:

chat = poe.Chat(quiet=False)
with chat.start_message() as msg:
    msg.write("Hello!")

Parameters:

  • sender (poe.Sender | Literal["user", "bot", "system", "tool"] | None = None): sender of the new message. A plain string will be converted to poe.Sender(role=sender). The default value None is converted to a sender representing the current bot poe.Sender(role="bot", name=poe.bot_name).
  • content_type (Literal["text/markdown", "text/plain"] = "text/markdown"): content type of the new message.

Returns:

  • poe.Message: the newly created message.

Chat.make_child

Creates a copy of the chat with initial_length set to the current number of messages. You can use this method to create multiple independent continuations of the current chat and track which messages were added to each child chat.

Returns:

  • poe.Chat: the newly created chat.

Chat.copy

Creates a copy of the chat, optionally with modified quiet status.

Parameters:

  • quiet (bool | None = None): quiet status for the copy. If not provided, the original quiet status will be used.

Returns:

  • poe.Chat: the newly created chat.

Chat.new_messages

Return a list of new messages in chat. That is all messages after initial_length. This gives easy access to messages that were added by bot calls after Chat object creation (i.e. without the initial prompts).

Returns:

  • list[poe.Message]: new messages in chat.

Chat.summarize

A short, human readable summary of messages in chat.

Returns:

  • str: the chat summary.

Chat.__iadd__

Chats support += operator that will add a message or messages in place.

Parameters:

  • other (poe.Message | str | Iterable[poe.Message | str]): the right operand to += operator. This can be either a message, or a list of messages.

Chat.__contains__

Chats support Python in operator. Its semantics depends on the type of left operand: if it is a string, this will return True if the string is contained in any of the chat messages. If left operand is a message, this will return True only if an equal message appears in the chat. For example:

test_chat = poe.Chat("testing...")
assert "test" in test_chat
assert poe.Message(text="test") not in test_chat
assert poe.Message(text="testing...") in test_chat

Parameters:

  • item(poe.Message | str): the left operand of the in operator.

Chat.__enter__

Chat class implements the context manager protocol, that will temporarily replace poe.default_chat with the current chat.

Returns:

  • poe.Chat: the chat object itself.

Chat.__format__

Similar to messages, chat can be used in f-strings directly. If it appears in an f-string, the value of text property will be used.


poe.call

Call a Poe bot.

Parameters:

  • bot_name (str): the name of the bot to call. The initial "@" character will be stripped from the name if present.
  • *prompts (str | poe.Message | poe.Chat): each positional argument should be either a string, a message, or a chat. All positional arguments will be normalized to a single list of messages.
  • output (poe.Chat | None = None): a chat to which bot response will be written. The responses will be streamed to the output, so that the user can see the response before the call returns.
  • tools (Sequence[Callable[..., Any]] = ()): Python functions to make available to the bot to call. Each function must have a docstring, and each argument must have a poe.Doc annotation.
  • temperature (float | None = None): temperature input to be used for model inference. This parameter controls how "creative" the LLM should be. The smaller the value, the more predictable the bot is. If not provided, the default value for the given LLM will be used.
  • debug_show_chat (bool = False): if True, print a message summarizing the chat content that will be sent to the bot.
  • adopt_current_bot_name (bool = False): Whether the called bot should identify as itself, or adopt the identity of the script bot that is executing the script. Use True when you want the bot to respond as if it is the script, rather than being aware it's a separate bot being consulted by the script. This flag is useful to replicate a prompt bot functionality.

Returns:

  • poe.Chat: a chat that contains messages returned by the bot.

poe.stream

Call a Poe bot and stream the responses as they become available.

Parameters:

  • bot_name (str): the name of the bot to call. The initial "@" character will be stripped from the name if present.
  • *prompts (str | poe.Message | poe.Chat): each positional argument should be either a string, a message, or a chat. All positional arguments will be normalized to a single list of messages.
  • tools (Sequence[Callable[..., Any]] = ()): Python functions to make available to the bot to call. Each function must have a docstring, and each argument must have a poe.Doc annotation.
  • temperature (float | None = None): temperature input to be used for model inference. This parameter controls how "creative" the LLM should be. The smaller the value, the more predictable the bot is. If not provided, the default value for the given LLM will be used.
  • adopt_current_bot_name (bool = False): Whether the called bot should identify as itself, or adopt the identity of the script bot that is executing the script. Use True when you want the bot to respond as if it is the script, rather than being aware it's a separate bot being consulted by the script. This flag is useful to replicate a prompt bot functionality.

Returns:

  • Iterator[fp.PartialResponse]: an iterator that yields response parts as soon as they become available.

poe.parallel

Execute multiple function calls in parallel. This also handles concurrent chat writes, so it can be used to make parallel bot calls. Exceptions are either raised, returned, or ignored. Only one of return_exceptions and skip_exceptions can be True.

Note: Functions are executed by a fixed size thread pool, so it is not guaranteed that all calls will be parallel. The current size of the pool is 21 threads and may change in the future.

Parameters:

  • *tasks (Callable[[], T]): each positional argument is a function that takes no arguments.
  • return_exceptions (bool = False): if True any exception raised during a function execution will be returned as a value of that function.
  • skip_exceptions (bool = False): if True all exceptions are ignored. In this case the list of results may be shorter than the number of positional arguments.

Returns:

  • list[T | BaseException]: a list of function results.

poe.repeat

Execute the same function that takes no arguments multiple times in parallel. All exceptions are ignored.

Note: The function is executed by a fixed size thread pool, so it is not guaranteed that all calls will be parallel. The current size of the pool is 21 threads and may change in the future.

Parameters:

  • n (int): the number of times to execute the function.
  • func (Callable[[], T]): the function to call multiple times in parallel.

Returns:

  • list[T]: a list of function results.

poe.start_message

This is an alias to poe.default_chat.start_message.

Parameters:

  • sender (poe.Sender | Literal["user", "bot", "system", "tool"] = "user"): sender of the new message. A plain string will be converted to poe.Sender(role=sender).
  • content_type (Literal["text/markdown", "text/plain"] = "text/markdown"): content type of the new message.

Returns:

  • poe.Message: the newly created message.

poe.call_tools

Execute tool calls requested by an LLM.

Parameters:

  • tool_call_request (poe.Message): a message object with the tool call request as a serialized JSON list of fp.ToolCallDefinition objects.
  • tools (Sequence[Callable[..., Any]]): a sequence of Python functions.

Returns:

  • poe.Message: a message with tool call results. The message text is a serialized JSON list of corresponding fp.ToolResultDefinition objects.

poe.update_tool_calls

Aggregate tool call deltas from a stream of LLM partial responses. This is handy, since usually LLMs stream tool call requests incrementally, as some details of the desired tool call become available.

Note: An LLM may request multiple tool calls, in this case they will be identified by unique integer identifiers for each call request.

Parameters:

  • tool_calls (dict[int, fp.ToolCallDefinition]): a dictionary of aggregated tool call requests. The keys are call request ids. This dictionary is updated in place by the function.
  • tool_calls_deltas (list[fp.ToolCallDefinitionDelta]): a list of tool call deltas from an LLM.

Returns: None


poe.query

This is a poe.Message object with a user message that triggered this script execution. If execution was started manually, accessing this property will raise a ValueError exception.


poe.default_chat

This is a poe.Chat object with quiet flag set to False that is primed with the content of the chat UI at the moment the script execution started.

Note: This chat object is not updated if someone posts to chat UI during script execution.


poe.bot_name

A str object with the name of the current bot executing this script.


poe.Doc

This is an annotation to use for argument types in functions passed as tools in bot calls. For example:

def get_weather(
    location: poe.Doc[str, "City name or location to get weather for"]
) -> str:
    """Get current weather information for a specified location"""
    ...

poe.BotError

A custom exception class to indicate an error during script execution. For example:

if "cat" not in poe.query:
    raise poe.BotError("I only talk about cats!")

Fields:

  • message (str): an error message to show to the user.

poe.set_query

A context manager to temporarily override content of poe.query. This may be useful for testing your script. For example:

with poe.set_query("Testing..."):
    assert poe.query.text == "Testing..."

Parameters:

  • query (poe.Message | str): a new message to set as a user query. A plain string will be converted to poe.Message(text=query).

builtins.print

The Python builtin print() function is modified to post a message to Poe chat UI instead of printing to the standard output.


builtins.input

The Python builtin input() function is not supported yet, and will raise a NotImplementedError exception if called.