### Install Dependencies with uv Source: https://github.com/i-am-bee/acp/blob/main/CONTRIBUTING.md Install project dependencies using the uv package manager. Refer to the uv Quickstart guide for more information. ```bash uv sync ``` -------------------------------- ### Install uv on Linux with pipx Source: https://github.com/i-am-bee/acp/blob/main/docs/introduction/uv-primer.mdx On Linux, install pipx first, ensure its path is set, and then install uv. Replace 'apt' with your distribution's package manager if necessary. ```bash sudo apt install pipx && pipx ensurepath && pipx install uv ``` -------------------------------- ### Install uv on Windows with winget Source: https://github.com/i-am-bee/acp/blob/main/docs/introduction/uv-primer.mdx Use the Windows Package Manager (winget) to install uv on Windows systems. ```bash winget install --id=astral-sh.uv -e ``` -------------------------------- ### Run Phoenix Docker Container Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/debug.mdx Starts a Phoenix (Arize AI observability) Docker container, mapping port 4318 to 6006. Ensure Phoenix is running before starting the example. ```bash docker run -p 4318:6006 -i -t arizephoenix/phoenix ``` -------------------------------- ### Install uv with Homebrew Source: https://github.com/i-am-bee/acp/blob/main/docs/introduction/uv-primer.mdx Use this command to install uv on macOS or Linux systems that have Homebrew installed. ```bash brew install uv ``` -------------------------------- ### Run Jaeger Docker Container Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/debug.mdx Starts a Jaeger all-in-one Docker container. Ensure Jaeger is running before starting the example. ```bash docker run --rm \ -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ -p 16686:16686 \ -p 4317:4317 \ -p 4318:4318 \ -p 9411:9411 \ jaegertracing/all-in-one:latest ``` -------------------------------- ### Python Prompt Chaining Example with ACP Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/compose-agents.mdx Demonstrates chaining two agents sequentially: one for marketing copy generation and another for translation. The `run_agent` function facilitates remote agent invocation. This example uses a single ACP server for simplicity, but distributed architectures are common in practice. ```python from collections.abc import AsyncGenerator import beeai_framework from acp_sdk import Message from acp_sdk.client import Client from acp_sdk.models import MessagePart from acp_sdk.server import Context, Server from beeai_framework.backend.chat import ChatModel from beeai_framework.agents.react import ReActAgent from beeai_framework.memory import TokenMemory server = Server() async def run_agent(agent: str, input: str) -> list[Message]: async with Client(base_url="http://localhost:8000") as client: run = await client.run_sync( agent=agent, input=[Message(parts=[MessagePart(content=input, content_type="text/plain")])] ) return run.output @server.agent(name="translation") async def translation_agent(input: list[Message]) -> AsyncGenerator: llm = ChatModel.from_name("ollama:llama3.1:8b") agent = ReActAgent(llm=llm, tools=[], memory=TokenMemory(llm)) response = await agent.run(prompt="Translate the given text to Spanish. The text is: " + str(input)) yield MessagePart(content=response.result.text) @server.agent(name="marketing_copy") async def marketing_copy_agent(input: list[Message]) -> AsyncGenerator: llm = ChatModel.from_name("ollama:llama3.1:8b") agent = ReActAgent(llm=llm, tools=[], memory=TokenMemory(llm)) response = await agent.run(prompt="You are able to generate punchy headlines for a marketing campaign. Provide punchy headline to sell the specified product on users eshop. The product is: " + str(input)) yield MessagePart(content=response.result.text) @server.agent(name="assistant") async def main_agent(input: list[Message], context: Context) -> AsyncGenerator: marketing_copy = await run_agent("marketing_copy", str(input)) translated_marketing_copy = await run_agent("translation", str(marketing_copy)) yield MessagePart(content=str(marketing_copy[0])) yield MessagePart(content=str(translated_marketing_copy[0])) server.run() ``` -------------------------------- ### Basic Agent Echo Example Source: https://github.com/i-am-bee/acp/blob/main/docs/community-calls/20-05-2025.md Demonstrates a simple server-side agent that echoes received messages and a client that invokes it. ```python # server.py @server.agent(name="echo_bot") async def echo(input: list[Message]): """Echoes everything""" for message in input: yield message ``` ```python # client.py async with Client(base_url="http://acpserver") as client: run = await client.run_sync("Hello!", agent="echo_bot") for message in run.output: print(message) ``` -------------------------------- ### Start ACP Server Source: https://github.com/i-am-bee/acp/blob/main/README.md Run the agent script using `uv run` to start the ACP server. The server will be accessible at http://localhost:8000. ```bash uv run agent.py ``` -------------------------------- ### ACP Client Example Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/debug.mdx An asynchronous client that connects to a local ACP server, runs an agent named 'lang_graph_agent' with specific input, and prints the received output. Ensure the telemetry setup is called before client initialization. ```python import asyncio from acp_sdk.client import Client from acp_sdk.models import ( Message, MessagePart, ) from telemetry import setup_tracer setup_tracer() async def client() -> None: async with Client(base_url="http://localhost:8000") as client, client.session() as session: run_milan = await session.run_sync( agent="lang_graph_agent", input=[Message(parts=[MessagePart(content="Milan", content_type="text/plain")])] ) print(run_milan.output[0].parts[0].content) if __name__ == "__main__": asyncio.run(client()) ``` -------------------------------- ### Python Citation Agent Example Source: https://github.com/i-am-bee/acp/blob/main/docs/community-calls/17-06-2025.md Demonstrates how to yield MessageParts with citation metadata. Ensure CitationMetadata is correctly imported and used. ```python async def citation_agent(input: list[Message], context: Context) -> AsyncGenerator: yield MessagePart( content="If you are bored, you can try tipping a cow.", ) yield MessagePart( metadata=CitationMetadata( url="https://en.wikipedia.org/wiki/Cow_tipping", start_index=30, end_index=43 ) ) ``` -------------------------------- ### Setup OpenTelemetry Tracer Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/debug.mdx Configures the OpenTelemetry tracer provider with a service name and an OTLP HTTP exporter for sending trace data. ```python from opentelemetry.sdk.resources import Resource from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter def setup_tracer(): resource = Resource.create(attributes={ "service.name": "acp-client", }) provider = TracerProvider(resource=resource) processor = BatchSpanProcessor(OTLPSpanExporter()) provider.add_span_processor(processor) trace.set_tracer_provider(provider) ``` -------------------------------- ### Copy .env file Source: https://github.com/i-am-bee/acp/blob/main/examples/python/acp-agent-generator/README.md Copy the example .env file to .env. Edit the .env file to include at least one API Key and update the model and/or provider if desired. ```bash cp .env.example .env ``` -------------------------------- ### Initiate Asynchronous Agent Run Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/agent-run-lifecycle.mdx Use `run_async` to start an agent run that returns a `run_id`. You must poll the `/runs/{run_id}` endpoint to get the result. ```python run = await client.run_async(agent="echo", input=[Message(parts=[MessagePart(content="Howdy!")])]) ``` ```bash curl -X POST http://localhost:8000/runs \ -H "Content-Type: application/json" \ -d '{ "agent_name": "echo", "input": [{"role": "user", "parts": [{"content": "Howdy!"}]}], "mode": "async" }' ``` -------------------------------- ### Install a package with uv Source: https://github.com/i-am-bee/acp/blob/main/docs/introduction/uv-primer.mdx Add a new package to your project's dependencies using uv. This command is equivalent to 'pip install '. ```bash uv add ``` -------------------------------- ### Server with Telemetry and Custom Configuration Source: https://context7.com/i-am-bee/acp/llms.txt Enable OpenTelemetry for observability and configure advanced server options like logging and worker count. This example defines an AI assistant agent with metadata. ```python from acp_sdk.models import Message, MessagePart, Metadata, Capability from acp_sdk.server import Server server = Server() @server.agent( name="assistant", description="AI assistant with multiple capabilities", metadata=Metadata( framework="acp-sdk", tags=["assistant", "chat"], capabilities=[ Capability(name="Conversation", description="Handles multi-turn conversations"), Capability(name="Q&A", description="Answers questions based on context") ], recommended_models=["llama3.1:8b", "gpt-4"] ) ) async def assistant(input: list[Message]): """AI assistant that processes user queries""" user_message = str(input[0]) if input else "" yield MessagePart(content=f"You said: {user_message}") server.run( host="0.0.0.0", port=8000, configure_logger=True, configure_telemetry=True, workers=4 ) ``` -------------------------------- ### Initialize LangGraph Agent Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/debug.mdx Initializes a LangGraph agent with observability instrumentation. This setup is for agents that will be integrated with LangGraph. ```python from collections.abc import AsyncGenerator from functools import reduce from datetime import datetime from typing import TypedDict from openinference.instrumentation.langchain import LangChainInstrumentor from acp_sdk.models.models import MessagePart from acp_sdk.models import Message from acp_sdk.server import RunYield, RunYieldResume, Server from langchain_core.runnables import RunnableLambda from langgraph.graph import StateGraph LangChainInstrumentor().instrument() class AgentState(TypedDict): name: str final_response: str hour: int greeting: str def get_current_hour(state: AgentState): now = datetime.now() return {"hour": now.hour} def decide_greeting(state: AgentState): hour = state["hour"] if 6 <= hour < 12: return {"greeting": "Good morning"} elif 12 <= hour < 18: return {"greeting": "Good afternoon"} else: return {"greeting": "Good evening"} def format_response(state: AgentState): return {"final_response": f'{state["greeting"]} {state["name"]} '} # create graph workflow = StateGraph(AgentState) # add nodes workflow.add_node("get_time", RunnableLambda(get_current_hour)) workflow.add_node("decide_greeting", RunnableLambda(decide_greeting)) workflow.add_node("format_response", RunnableLambda(format_response)) ``` -------------------------------- ### Create a Simple LLM Agent with Memory and Tools Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/wrap-existing-agent.mdx Wrap an LLM agent using the `beeai-framework` by integrating memory and tools. The agent processes inputs, maintains conversation history, and generates responses. Ensure the SDK and framework are installed. ```python from collections.abc import AsyncGenerator from acp_sdk.models import Message, MessagePart from acp_sdk.server import RunYield, RunYieldResume, Server from beeai_framework.agents.react import ReActAgent from beeai_framework.backend.chat import ChatModel from beeai_framework.backend.message import UserMessage from beeai_framework.memory.token_memory import TokenMemory server = Server() @server.agent() async def llm(inputs: list[Message]) -> AsyncGenerator[RunYield, RunYieldResume]: """LLM agent that processes inputs and returns a response""" # Create a llm instance llm = ChatModel.from_name("ollama:llama3.1") # Create a memory instance memory = TokenMemory(llm) # Add messages to memory for message in inputs: await memory.add(UserMessage(str(message))) # Create agent with memory and tools agent = ReActAgent(llm=llm, tools=[], memory=memory) # Run the agent with the memory response = await agent.run() # Yield the response yield MessagePart(content=response.result.text) server.run() ``` -------------------------------- ### Conventional Commit Examples Source: https://github.com/i-am-bee/acp/blob/main/CONTRIBUTING.md Examples of commit messages following the Conventional Commits specification. Use clear and descriptive messages to explain the changes. ```git feat(server): add support for agent timeouts ``` ```git docs: update contributing guidelines ``` -------------------------------- ### Connect to ACP Server and Run Agent Source: https://github.com/i-am-bee/acp/blob/main/python/README.md Connect to an existing ACP server and run a registered agent. This example demonstrates sending a message and printing the response. ```python async with Client(base_url="http://localhost:8000") as client: run = await client.run_sync(agent="echo", input=[Message(parts=[MessagePart(content="Howdy!")])]) print(run) ``` -------------------------------- ### Run ACP-MCP Adapter using PyPI Source: https://github.com/i-am-bee/acp/blob/main/docs/integrations/mcp-adapter.mdx Use this command to run the adapter if you have the PyPI package installed. Replace `` with the actual URL of your ACP server. ```sh uvx acp-mcp # e.g. http://localhost:8000 ``` -------------------------------- ### Serve Agents with Standalone ASGI Application Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/production-grade.mdx This example demonstrates how to serve ACP agents using an external ASGI server by creating an application factory. It separates agent definition from server implementation for deployment flexibility. ```python from collections.abc import AsyncGenerator from acp_sdk.models import ( Message, ) from acp_sdk.server import RunYield, RunResume, agent, create_app # This example demonstrates how to serve agents with you own server @agent() async def echo(input: list[Message]) -> AsyncGenerator[RunYield, RunResume]: """Echoes everything""" for message in input: yield message app = create_app(echo) # The app can now be used with any ASGI server # Run with # 1. fastapi run examples/servers/standalone.py # 2. uvicorn examples.servers.standalone:app # ... # Source: python/examples/servers/standalone.py ``` -------------------------------- ### Example Citation Metadata in Python SDK Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/message-metadata.mdx Shows how to construct a message part with citation metadata using the Python SDK, including source URL, title, description, and text range. ```python yield MessagePart( content="According to recent studies, AI adoption has increased by 40% this year.", metadata=CitationMetadata( url="https://example.com/ai-study-2024", title="AI Adoption Report 2024", description="Comprehensive analysis of AI adoption trends across industries", start_index=15, end_index=27 ) ) ``` -------------------------------- ### Example Trajectory Metadata in Python SDK Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/message-metadata.mdx Shows how to add trajectory metadata to a message part using the Python SDK, specifying the tool, input, and output. ```python yield MessagePart( content="It's currently 72°F and sunny in San Francisco.", metadata=TrajectoryMetadata( tool_name="weather_api", tool_input={"location": "San Francisco, CA"}, tool_output={"temperature": 72, "condition": "sunny"} ) ) ``` -------------------------------- ### Run ACP Client Example Source: https://github.com/i-am-bee/acp/blob/main/README.md This Python script initializes an ACP client, sends a message to the 'echo' agent, and prints the received output. Ensure the ACP server is running locally on port 8000. ```python import asyncio from acp_sdk.client import Client from acp_sdk.models import Message, MessagePart async def example() -> None: async with Client(base_url="http://localhost:8000") as client: run = await client.run_sync( agent="echo", input=[ Message( role="user", parts=[MessagePart(content="Howdy to echo from client!!", content_type="text/plain")] ) ], ) print(run.output) if __name__ == "__main__": asyncio.run(example()) ``` -------------------------------- ### Discover Agents with Python SDK Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/agent-discovery.mdx This Python script uses the ACP SDK to connect to an ACP server and list available agents. Ensure the SDK is installed and the base URL is correct. ```python import asyncio from acp_sdk.client import Client async def main(): client = Client(base_url="http://localhost:8000") async for agent in client.agents(): print(agent.name, agent.description) asyncio.run(main()) ``` -------------------------------- ### Invoke Router Agent with Translation Tool Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/compose-agents.mdx This example shows how to invoke the `router` agent, which utilizes a `TranslationTool` to select and call either `translation_french` or `translation_spanish` agents based on user input. It requires the `router` agent to be configured with these translation agents. ```bash curl -X POST http://localhost:8000/runs \ -H "Content-Type: application/json" \ -d '{ "agent_name": "router", "input": [ { "role": "user", "parts": [ { "content_type": "text/plain", "content": "Translate text \"Hello world\" to Spanish." } ] } ] }' ``` -------------------------------- ### Asynchronous agent execution using Python SDK Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/discover-and-run-agent.mdx Start an asynchronous agent run with the Python SDK's `run_async` method. Store the returned run ID to later fetch the results using `run_status`. ```python import asyncio from acp_sdk.client import Client from acp_sdk.models import Message, MessagePart async def run_async(): async with Client(base_url="http://localhost:8000") as client: run = await client.run_async( agent="echo", input=[Message(parts=[MessagePart(content="Hello")])] ) print("Run ID:", run.run_id) # Later, retrieve results result = await client.run_status(run_id=run.run_id) print(result) if __name__ == "__main__": asyncio.run(run_async()) ``` -------------------------------- ### TypeScript Streaming Client Source: https://context7.com/i-am-bee/acp/llms.txt Shows how to process streaming events from an agent in TypeScript. This example iterates over events, logs their types, and extracts content from message parts until the run is completed. Requires the `acp-sdk` package. ```typescript import { Client } from "acp-sdk"; const client = new Client({ baseUrl: "http://localhost:8000" }); // Run with streaming for await (const event of client.runStream("echo", "Stream this!")) { console.log(`Event: ${event.type}`); if (event.type === "message.part") { console.log(` Content: ${event.part.content}`); } if (event.type === "run.completed") { console.log("Run completed successfully"); } } ``` -------------------------------- ### Initialize ACP Project Source: https://github.com/i-am-bee/acp/blob/main/README.md Use `uv init` to create a new project with a specified Python version. Navigate into the project directory. ```bash uv init --python '>=3.11' my_acp_project cd my_acp_project ``` -------------------------------- ### Initialize Project with uv Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/debug.mdx Initializes a new Python project using uv, adds the acp-sdk, and navigates into the project directory. Requires Python 3.11 or newer. ```bash uv init --python '>=3.11' my_acp_project cd my_acp_project uv add acp-sdk ``` -------------------------------- ### Copy Environment Sample Source: https://github.com/i-am-bee/acp/blob/main/examples/python/beeai-slack-mcp/README.md Copy the sample environment file to .env. Remember to edit .env with your Slack bot token and Team ID. ```bash cp .env.sample .env ``` -------------------------------- ### Initialize a new Python project with uv Source: https://github.com/i-am-bee/acp/blob/main/docs/introduction/uv-primer.mdx Initialize a new project with a specific Python version. ACP SDK requires Python 3.11 or higher. ```bash uv init --python '>=3.11' ``` -------------------------------- ### Python SDK - Server: Creating Agents with Await (Human-in-the-Loop) Source: https://context7.com/i-am-bee/acp/llms.txt Shows how to create agents that pause execution for human input. ```python from collections.abc import AsyncGenerator from acp_sdk.models import Message, MessageAwaitRequest, MessageAwaitResume, MessagePart from acp_sdk.server import Context, Server from acp_sdk.server.types import RunYield, RunYieldResume server = Server() @server.agent() async def approval_agent( input: list[Message], context: Context ) -> AsyncGenerator[RunYield, RunYieldResume]: """Request approval and respond to user's confirmation.""" # Pause execution and wait for external confirmation response = yield MessageAwaitRequest( message=Message(parts=[ MessagePart(content="I can generate a password for you. Do you want me to do that?") ]) ) # Check the user's response if str(response.message) == "yes": yield MessagePart(content="Generating password...") import secrets import string password = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(16)) yield Message(parts=[MessagePart(content=f"Your password is: {password}")]) else: yield MessagePart(content="Password generation declined.") server.run() ``` -------------------------------- ### Basic TypeScript Client Usage Source: https://context7.com/i-am-bee/acp/llms.txt Demonstrates basic synchronous agent execution using the TypeScript SDK. Initializes a client and runs an agent, then logs its output. Requires the `acp-sdk` package. ```typescript import { Client } from "acp-sdk"; // Create client instance const client = new Client({ baseUrl: "http://localhost:8000" }); // Run agent synchronously const run = await client.runSync("echo", "Hello from TypeScript!"); run.output.forEach((message) => { console.log("Output:", message); }); // Expected output: // Output: { role: 'agent/echo', parts: [{ content: 'Hello from TypeScript!' }] } ``` -------------------------------- ### GET /runs/{run_id} Source: https://context7.com/i-am-bee/acp/llms.txt Retrieves the status of a specific run. ```APIDOC ## GET /runs/{run_id} ### Description Retrieves the status of a specific run. ### Method GET ### Endpoint /runs/{run_id} ### Parameters #### Path Parameters - **run_id** (string) - Required - The unique identifier of the run. ### Response #### Success Response (200) - **run_id** (string) - The unique identifier of the run. - **agent_name** (string) - The name of the agent that executed the run. - **status** (string) - The current status of the run (e.g., "completed", "running", "failed"). - **output** (array) - The output generated by the run. - **created_at** (string) - Timestamp when the run was created. - **finished_at** (string) - Timestamp when the run finished. #### Response Example ```json { "run_id": "550e8400-e29b-41d4-a716-446655440000", "agent_name": "echo", "status": "completed", "output": [...], "created_at": "2025-01-15T10:30:00Z", "finished_at": "2025-01-15T10:30:01Z" } ``` ``` -------------------------------- ### GET /sessions/{session_id} Source: https://context7.com/i-am-bee/acp/llms.txt Retrieves details of a session including history and state. ```APIDOC ## GET /sessions/{session_id} ### Description Retrieves details of a session including history and state for distributed deployments. ### Method GET ### Endpoint /sessions/{session_id} ### Parameters #### Path Parameters - **session_id** (string) - Required - The unique identifier of the session. ### Response #### Success Response (200) - **id** (string) - The unique identifier of the session. - **history** (array) - An array of resource identifiers for the session's history. - **state** (string) - A resource identifier for the session's state. #### Response Example ```json { "id": "b30b1946-6010-4974-bd35-89a2bb0ce844", "history": ["resource://messages/msg1", "resource://messages/msg2"], "state": "resource://state/session-state" } ``` ``` -------------------------------- ### Session Management for Multiple Runs Source: https://github.com/i-am-bee/acp/blob/main/docs/community-calls/20-05-2025.md Demonstrates how to use a client session to execute multiple runs sequentially, maintaining context between them. ```python # client.py async with Client(base_url="http://acpserver") as client, client.session() as session: run = await session.run_sync("Howdy, my name is Tom!", agent="chat_bot") for message in run.output: print(message) run = await session.run_sync("What's my name again?", agent="same_or_another_chat_bot") for message in run.output: print(message) ``` -------------------------------- ### Get Agent - Agent Manifest API Source: https://context7.com/i-am-bee/acp/llms.txt Retrieves the manifest of a specific agent by its name. ```APIDOC ## GET /agents/{agent_name} ### Description Retrieves the manifest of a specific agent by name, including its capabilities and metadata. ### Method GET ### Endpoint /agents/{agent_name} ### Path Parameters - **agent_name** (string) - Required - The name of the agent to retrieve. ### Request Example ```bash curl http://localhost:8000/agents/echo ``` ### Response #### Success Response (200) - **name** (string) - The name of the agent. - **description** (string) - A brief description of the agent. - **metadata** (object) - Additional metadata about the agent, including framework, tags, and capabilities. - **input_content_types** (array of strings) - Supported input content types. - **output_content_types** (array of strings) - Supported output content types. #### Response Example ```json { "name": "echo", "description": "Echoes everything", "metadata": { "framework": "acp-sdk", "tags": ["utility"], "capabilities": [ {"name": "Echo", "description": "Returns input messages unchanged"} ] }, "input_content_types": ["*/*"], "output_content_types": ["*/*"] } ``` ``` -------------------------------- ### GET /runs/{run_id} Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/agent-run-lifecycle.mdx Retrieves the current state and details of a specific agent run. ```APIDOC ## GET /runs/{run_id} ### Description Retrieves the current state and details of a specific agent run using its unique ID. ### Method GET ### Endpoint /runs/{run_id} ### Parameters #### Path Parameters - **run_id** (string) - Required - The unique identifier of the run. ### Response #### Success Response (200) - **Run** (object) - The current state and details of the agent run. ``` -------------------------------- ### GET /runs/{run_id}/events Source: https://context7.com/i-am-bee/acp/llms.txt Retrieves all events emitted by a run for debugging or audit purposes. ```APIDOC ## GET /runs/{run_id}/events ### Description Retrieves all events emitted by a run for debugging or audit purposes. ### Method GET ### Endpoint /runs/{run_id}/events ### Parameters #### Path Parameters - **run_id** (string) - Required - The unique identifier of the run. ### Response #### Success Response (200) - **events** (array) - An array of events emitted by the run. - **type** (string) - The type of the event (e.g., "run.created", "message.part", "run.completed"). - **run** (object) - Details of the run associated with the event (if applicable). - **part** (object) - Details of the message part associated with the event (if applicable). #### Response Example ```json { "events": [ {"type": "run.created", "run": {...}}, {"type": "message.part", "part": {...}}, {"type": "run.completed", "run": {...}} ] } ``` ``` -------------------------------- ### Initiate Synchronous Agent Run Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/agent-run-lifecycle.mdx Use `run_sync` to execute an agent and wait for the complete response. This is suitable for immediate results. ```python run = await client.run_sync(agent="echo", input=[Message(parts=[MessagePart(content="Howdy!")])]) ``` ```bash curl -X POST http://localhost:8000/runs \ -H "Content-Type: application/json" \ -d '{ "agent_name": "echo", "input": [{"role": "user", "parts": [{"content": "Howdy!"}]}], "mode": "sync" }' ``` -------------------------------- ### Get Run Status API Source: https://context7.com/i-am-bee/acp/llms.txt Retrieves the current status and details of an existing agent run. ```APIDOC ## GET /runs/{run_id} ### Description Retrieves the current status and details of an existing run. ### Method GET ### Endpoint /runs/{run_id} ### Path Parameters - **run_id** (string) - Required - The unique identifier of the run to retrieve. ### Request Example ```bash curl http://localhost:8000/runs/550e8400-e29b-41d4-a716-446655440000 ``` ### Response #### Success Response (200) - **run_id** (string) - The unique identifier for the run. - **agent_name** (string) - The name of the agent that executed the run. - **session_id** (string) - The session ID associated with the run (if applicable). - **status** (string) - The current status of the run (e.g., 'completed', 'in-progress', 'failed'). - **output** (array) - The output messages from the agent (if the run is completed). - **role** (string) - The role of the message sender. - **parts** (array) - An array of message parts. - **content** (string) - The message content. - **content_type** (string) - The content type of the message. - **error** (object or null) - Details about any error that occurred during the run. #### Response Example ```json { "run_id": "550e8400-e29b-41d4-a716-446655440000", "agent_name": "echo", "session_id": null, "status": "completed", "output": [ { "role": "agent/echo", "parts": [{"content": "Process this later", "content_type": "text/plain"}] } ], "error": null } ``` ``` -------------------------------- ### List and Discover Agents in Python Source: https://context7.com/i-am-bee/acp/llms.txt Shows how to discover available agents on an ACP server and retrieve their details using the Python SDK. Requires the `acp_sdk` library. ```python import asyncio from acp_sdk.client import Client async def discover_agents(): async with Client(base_url="http://localhost:8000") as client: # List all available agents print("Available agents:") async for agent in client.agents(): print(f" - {agent.name}: {agent.description}") print(f" Input types: {agent.input_content_types}") print(f" Output types: {agent.output_content_types}") # Get specific agent details echo_agent = await client.agent(name="echo") print(f"\nAgent details: {echo_agent.model_dump()}") if __name__ == "__main__": asyncio.run(discover_agents()) ``` -------------------------------- ### Get Specific Agent Manifest Source: https://context7.com/i-am-bee/acp/llms.txt Fetch the detailed manifest for a particular agent, including its metadata and supported content types. ```bash # Get details for a specific agent curl http://localhost:8000/agents/echo # Response: # { # "name": "echo", # "description": "Echoes everything", # "metadata": { # "framework": "acp-sdk", # "tags": ["utility"], # "capabilities": [ # {"name": "Echo", "description": "Returns input messages unchanged"} # ] # }, # "input_content_types": ["*/*"], # "output_content_types": ["*/*"] # } ``` -------------------------------- ### Get Run Status Source: https://context7.com/i-am-bee/acp/llms.txt Retrieve the current status and details of a previously initiated agent run using its unique run ID. ```bash curl http://localhost:8000/runs/550e8400-e29b-41d4-a716-446655440000 ``` -------------------------------- ### POST /runs Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/agent-run-lifecycle.mdx Initiates a new agent run. Supports synchronous, asynchronous, and streaming modes. ```APIDOC ## POST /runs ### Description Initiates a new agent run. Requires `agent_name` and `input`. Optional parameters include `session_id` and `mode` (`sync`, `async`, `stream`). The response contains the initial `Run` object or a stream of events. ### Method POST ### Endpoint /runs ### Parameters #### Request Body - **agent_name** (string) - Required - The name of the agent to run. - **input** (array) - Required - The input messages for the agent. - **session_id** (string) - Optional - The ID of the session to associate with the run. - **mode** (string) - Optional - The execution mode. Allowed values: `sync`, `async`, `stream`. ### Request Example ```json { "agent_name": "echo", "input": [ {"role": "user", "parts": [{"content": "Howdy!"}]} ], "mode": "sync" } ``` ### Response #### Success Response (200) - **Run** (object) - The initial Run object or stream of events. ``` -------------------------------- ### Execute Agent Asynchronously Source: https://context7.com/i-am-bee/acp/llms.txt Start an asynchronous agent run. The API returns immediately with a run ID, allowing for subsequent status polling. ```bash # Run an agent asynchronously (returns immediately) curl -X POST http://localhost:8000/runs \ -H "Content-Type: application/json" \ -d '{ "agent_name": "echo", "mode": "async", "input": [ { "role": "user", "parts": [{"content": "Process this later", "content_type": "text/plain"}] } ] }' # Response (run_id returned immediately): # { # "run_id": "550e8400-e29b-41d4-a716-446655440000", # "agent_name": "echo", # "status": "in-progress" # } # Poll for status curl http://localhost:8000/runs/550e8400-e29b-41d4-a716-446655440000 ``` -------------------------------- ### Handle Agent Await/Resume in Python Source: https://context7.com/i-am-bee/acp/llms.txt Demonstrates how to handle agents that pause for human input by detecting 'run.awaiting' events and resuming the agent with a response. Requires the `acp_sdk` library. ```python import asyncio from acp_sdk.client import Client from acp_sdk.models import Message, MessageAwaitResume, MessagePart async def handle_await_example(): async with Client(base_url="http://localhost:8000") as client: initial_message = Message(parts=[ MessagePart(content="Can you generate a password for me?") ]) async for event in client.run_stream(agent="approval_agent", input=[initial_message]): print(f"Event: {event.type}") if event.type == "run.awaiting": # Agent is waiting for user input print(f"Agent asks: {event.run.await_request.message}") # Resume with user's approval async for resume_event in client.run_resume_stream( run_id=event.run.run_id, await_resume=MessageAwaitResume( message=Message(parts=[MessagePart(content="yes")]) ) ): print(f"Resume event: {resume_event.type}") if resume_event.type == "run.completed": print(f"Final output: {resume_event.run.output[-1]}") if __name__ == "__main__": asyncio.run(handle_await_example()) ``` -------------------------------- ### History-Aware Agent in Python Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/distributed-sessions.mdx An example of an agent that loads and processes historical messages from a session, including messages from all servers, before processing new input. ```python @agent() async def history_aware_agent(input: list[Message], context: Context): # This automatically resolves URIs from other servers async for message in context.session.load_history(): yield message # Includes messages from all servers # Process new input with full context for message in input: yield message ``` -------------------------------- ### Example Trajectory Metadata in JSON Message Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/message-metadata.mdx Demonstrates including trajectory metadata in a JSON message, detailing the tool used, its input, and output. ```json { "role": "agent/assistant", "parts": [ { "content_type": "text/plain", "content": "It's currently 72°F and sunny in San Francisco.", "metadata": { "kind": "trajectory", "tool_name": "weather_api", "tool_input": {"location": "San Francisco, CA"}, "tool_output": {"temperature": 72, "condition": "sunny"} } } ] } ``` -------------------------------- ### Get Session Details Source: https://context7.com/i-am-bee/acp/llms.txt Retrieves details of a session, including its history and state. This is particularly useful for distributed deployments where session management is critical. ```bash # Get session details curl http://localhost:8000/sessions/b30b1946-6010-4974-bd35-89a2bb0ce844 ``` -------------------------------- ### List available agents using REST API Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/discover-and-run-agent.mdx Send a GET request to the /agents endpoint to list available agents. This is useful for simple interactions. ```bash curl http://localhost:8000/agents ``` ```json { "agents": [ { "name": "echo", "description": "Echoes everything", "metadata": {} } ] } ``` -------------------------------- ### Initiate Streaming Agent Run Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/agent-run-lifecycle.mdx Use `run_stream` to receive incremental updates as the agent processes the input. This is ideal for real-time feedback. ```python async for event in client.run_stream(agent="echo", input=[Message(parts=[MessagePart(content="Howdy!")])]): print(event) ``` ```bash curl -X POST http://localhost:8000/runs \ -H "Content-Type: application/json" \ -d '{ "agent_name": "echo", "input": [{"role": "user", "parts": [{"content": "Howdy!"}]}], "mode": "stream" }' ``` -------------------------------- ### Example Citation Metadata in JSON Message Source: https://github.com/i-am-bee/acp/blob/main/docs/core-concepts/message-metadata.mdx Illustrates how to include citation metadata within a JSON message part, specifying source details and text range. ```json { "role": "agent/researcher", "parts": [ { "content_type": "text/plain", "content": "According to a recent study, AI adoption has increased by 40% this year.", "metadata": { "kind": "citation", "url": "https://example.com/ai-study-2024", "title": "AI Adoption Report 2024", "description": "Comprehensive analysis of AI adoption trends across industries", "start_index": 15, "end_index": 27 } } ] } ``` -------------------------------- ### Create ACP Server with Agent Decorator Source: https://context7.com/i-am-bee/acp/llms.txt Demonstrates how to create an ACP server and register agents using the `@server.agent` decorator. Agents are defined as async generators yielding messages or message parts. ```python import asyncio from collections.abc import AsyncGenerator from acp_sdk.models import Message, MessagePart from acp_sdk.server import Context, RunYield, RunYieldResume, Server server = Server() @server.agent( name="echo", description="Echoes everything back to the user", input_content_types=["text/plain"], output_content_types=["text/plain"] ) async def echo( input: list[Message], context: Context ) -> AsyncGenerator[RunYield, RunYieldResume]: """Echoes everything, including session history""" # Access session history async for message in context.session.load_history(): yield message # Process input messages for message in input: await asyncio.sleep(0.5) # Yield intermediate thought yield {"thought": "I should echo everything"} await asyncio.sleep(0.5) # Yield the actual message yield message # Run the server server.run(host="127.0.0.1", port=8000) ``` -------------------------------- ### Build an ACP client in Python Source: https://github.com/i-am-bee/acp/blob/main/docs/introduction/quickstart.mdx Create a Python client using `acp_sdk.client.Client` to asynchronously interact with the ACP server. The `run_sync` method sends input and retrieves the agent's output. ```python import asyncio from acp_sdk.client import Client from acp_sdk.models import Message, MessagePart async def example() -> None: async with Client(base_url="http://localhost:8000") as client: run = await client.run_sync( agent="echo", input=[ Message( parts=[MessagePart(content="Howdy to echo from client!", content_type="text/plain")] ) ], ) print(run.output) if __name__ == "__main__": asyncio.run(example()) ``` -------------------------------- ### ACP Agent Server Setup Source: https://github.com/i-am-bee/acp/blob/main/docs/how-to/compose-agents.mdx Sets up ACP agents for translation and routing. The router agent uses specialized translation agents and a translation tool to dynamically translate text. ```python from collections.abc import AsyncGenerator from acp_sdk import Message from acp_sdk.models import MessagePart from acp_sdk.server import Context, Server from beeai_framework.backend.chat import ChatModel from beeai_framework.agents.react import ReActAgent from beeai_framework.memory import TokenMemory from beeai_framework.utils.dicts import exclude_none from translation_tool import TranslationTool server = Server() @server.agent(name="translation_spanish") async def translation_spanish_agent(input: list[Message]) -> AsyncGenerator: llm = ChatModel.from_name("ollama:llama3.1:8b") print("Translation Spanish agent") agent = ReActAgent(llm=llm, tools=[], memory=TokenMemory(llm)) response = await agent.run(prompt="Translate the given text to Spanish. The text is: " + str(input)) yield MessagePart(content=response.result.text) @server.agent(name="translation_french") async def translation_french_agent(input: list[Message]) -> AsyncGenerator: llm = ChatModel.from_name("ollama:llama3.1:8b") agent = ReActAgent(llm=llm, tools=[], memory=TokenMemory(llm)) response = await agent.run(prompt="Translate the given text to French. The text is: " + str(input)) yield MessagePart(content=response.result.text) @server.agent(name="router") async def main_agent(input: list[Message], context: Context) -> AsyncGenerator: llm = ChatModel.from_name("ollama:llama3.1:8b") agent = ReActAgent( llm=llm, tools=[TranslationTool()], templates={ "system": lambda template: template.update( defaults=exclude_none({ "instructions": """ Translate the given text to either Spanish or French using the translation tool. Return only the result from the tool as it is, don't change it. """, "role": "system" }) ) }, memory=TokenMemory(llm) ) prompt = (str(input[0])) response = await agent.run(prompt) yield MessagePart(content=response.result.text) server.run() ``` -------------------------------- ### Markdown Template for Enhancement Proposal Source: https://github.com/i-am-bee/acp/blob/main/docs/about/contribute.mdx Use this Markdown template when starting a GitHub Discussion to propose enhancements to the ACP. It helps focus the discussion on motivation, specification, implementation, and potential drawbacks. ```markdown # Title Enhancement - [short summary] ## Motivation Why this matters for ACP. ## Specification Sketch of API, data model, or architecture. ## Implementation Plan Who’s championing it & how you’d tackle it. ## Drawbacks / Open Questions Points for the community to weigh in on. ``` -------------------------------- ### TypeScript Agent Discovery and Error Handling Source: https://context7.com/i-am-bee/acp/llms.txt Demonstrates how to discover agents, ping the server for health, and handle potential `ACPError` exceptions gracefully in TypeScript. Requires the `acp-sdk` package. ```typescript import { Client, ACPError } from "acp-sdk"; const client = new Client({ baseUrl: "http://localhost:8000" }); try { // Ping server await client.ping(); console.log("Server is healthy"); // List all agents const agents = await client.agents(); console.log("Available agents:"); agents.forEach((agent) => { console.log(` - ${agent.name}: ${agent.description}`); }); // Get specific agent const echoAgent = await client.agent("echo"); console.log("Echo agent metadata:", echoAgent.metadata); } catch (error) { if (error instanceof ACPError) { console.error(`ACP Error: ${error.error.code} - ${error.error.message}`); } else { console.error("Unexpected error:", error); } } ```