Skip to main content
Every scenario below has a runnable script in the SDK’s examples/ directory. Each snippet assumes you are inside an AsyncCominty context and have an AGENT_ID:
Run the examples from a checkout of the repo:
New to the SDK? Read Overview first for install, auth, and the core concepts (client, resources, runs, tools).

Stream progress events

Watch the agent work (tool calls, LLM steps, the result) as it happens. Iterating a run yields progress events only; the finished reply is captured for you.
▶ examples/01_stream_events.py

Fire and await the answer

No event handling. Just the final reply.
▶ examples/02_await_result.py

Continue the conversation

chat.send posts a follow-up in the same thread; the agent keeps context.
A thread handles one message at a time. Read the previous reply to the end (await run.text()), or cancel it, before you send the next message. A message you start and never read stays pending, and chat.send then fails with APIError (400, Cannot process multiple messages at the same time). See One message at a time.
▶ examples/03_follow_up.py

Answer questions from the agent

When the agent needs input, it ends its turn with questions (a prompt plus options) instead of a final answer. Answer with a normal follow-up.
▶ examples/04_answer_questions.py

Cap the tool rounds

max_steps limits how many tool rounds the agent runs for one message. When the cap is reached, the agent recaps and asks whether to continue. The message still ends with status="success". The cap applies to that message only, so pass it again on a follow-up. Sub-agents have their own counter. See Limiting agent steps.
▶ examples/10_max_steps.py

Stop a message

chat.cancel stops an assistant message that is still being generated. It returns the message with status set to cancelled. It is not idempotent: cancelling a message that already finished raises APIError (400). A “stop” button should treat that error as “too late”.
A cancelled message frees the thread: you can send the next message right away, without reading the cancelled message’s events. ▶ examples/12_cancel_message.py

Export a message as a document

chat.export renders a finished message to a PDF or a DOCX and returns the bytes. The server sends no file name, so pick one when you write the file.
A message with no content, for example one that is still running, raises APIError (400). Any format other than "pdf" or "docx" raises InvalidParams before a request is sent. ▶ examples/13_export_message.py

Give the agent files

chat.upload_file registers a file. Its id goes in file_ids on chat.start or chat.send, at most 5 files per message. Pass a pathlib.Path and the name and mimetype are inferred. Pass bytes with a filename. A plain str is rejected: wrap a path in Path(...).
A file is at most 500 MiB, held in memory. A bigger one raises InvalidParams before anything is sent. See the reference for the limits and errors. ▶ examples/14_upload_files.py

List and search threads

▶ examples/05_list_threads.py

Manage a thread

▶ examples/06_manage_thread.py

Store and recall a memory file

client.memory stores files in a namespace you choose. The same API key shares those files across user_id values. update is partial, and its required version guards against overwriting a concurrent change. A stale one raises ConflictError. To use the files in a conversation, pass a MemoryCapability in thread_capabilities to chat.start. The concepts are in Memory namespaces.
▶ examples/09_memory.py

Control what the agent can use

Capabilities decide which tools the agent can use: web search, document search, MCP connections, skills, media generation, and memory. Set them for a whole thread with thread_capabilities (on chat.start only), or for one message with message_scope (on chat.start and chat.send).
▶ examples/11_capabilities.py See Capabilities for the model, and Use cases for recipes.

Use a custom managed agent

A custom agent (its own model, failover order, and instructions, configured at platform.cominty.ai → Agents) is just another agent_id. Pass it to any chat call. This example feeds a jargon-heavy incident report to an agent instructed to reply with a clean, non-technical French executive summary.
▶ examples/07_custom_agent.py

Pull live context from an MCP server

MCP servers connected to an agent on the platform (for example Linear) work with no SDK change. Capabilities are on by default, and a message scope turns off what you don’t want. Here the custom agent reads the current Linear sprint and reports it in its French C-level voice. Linear tool calls appear in the stream as ToolCall events.
▶ examples/08_mcp_linear.py

List the MCP integrations

mcp.list returns the integrations your API key can use. A server’s name is the value McpCapability.connections stores. By default it keeps only the servers that are turned on.
requires_oauth_connect is True when someone must connect the integration on the platform first. If the manifest cannot be loaded, the SDK raises ServerError. ▶ examples/19_mcp_servers.py

Create a custom agent

Create an agent from code, with its own instructions and capabilities. The agent is owned by the user who created your API key. Chat with it like any other agent.
update is partial: None clears description, instructions, and capabilities, and a capabilities object is merged capability by capability. See Custom agents. ▶ examples/16_agents.py

Choose the agent’s models

agents.list_models gives the model ids. set_models replaces the agent’s chain: the first model answers, and the next ones take over when it fails.
On a built-in agent, set_models changes the chain of the whole organization.

Give an agent a skill

A skill is a folder with a SKILL.md. skills.create zips the folder and uploads it. Give it to an agent with SkillsCapability.
See Skills for the folder layout and the versions. ▶ examples/17_skills.py

Search your own files

sources.create turns local files into an indexed source in one call. Wait for it to be synced, then give its id to an agent. The chat must run with the key owner’s user_id, which is agent.owner.
source.pid (a string) goes to every client.sources method. source.id (an integer) goes to source_ids. See Sources. ▶ examples/15_sources.py

Resolve a citation

An answer cites documents as <cite document_id="2698#10778" .../>. documents.get resolves that id to the source and the file.
An unknown id raises NotFoundError. There is no call that lists documents.

Handle errors

See Exceptions for the full hierarchy.