acp-sdk 0.3.3__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. acp_sdk-0.4.0/PKG-INFO +63 -0
  2. acp_sdk-0.4.0/README.md +43 -0
  3. acp_sdk-0.4.0/docs/_sidebar.md +7 -0
  4. acp_sdk-0.4.0/docs/client.md +99 -0
  5. acp_sdk-0.4.0/docs/index.html +104 -0
  6. acp_sdk-0.4.0/docs/models.md +45 -0
  7. acp_sdk-0.4.0/docs/server.md +103 -0
  8. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/pyproject.toml +1 -1
  9. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/errors.py +1 -1
  10. acp_sdk-0.3.3/PKG-INFO +0 -99
  11. acp_sdk-0.3.3/README.md +0 -79
  12. acp_sdk-0.3.3/examples/clients/advanced.py +0 -21
  13. acp_sdk-0.3.3/examples/clients/session.py +0 -18
  14. acp_sdk-0.3.3/examples/clients/simple.py +0 -17
  15. acp_sdk-0.3.3/examples/clients/stream.py +0 -14
  16. acp_sdk-0.3.3/examples/servers/awaiting.py +0 -26
  17. acp_sdk-0.3.3/examples/servers/echo.py +0 -22
  18. acp_sdk-0.3.3/examples/servers/standalone.py +0 -25
  19. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/.gitignore +0 -0
  20. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/.python-version +0 -0
  21. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/pytest.ini +0 -0
  22. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/__init__.py +0 -0
  23. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/client/__init__.py +0 -0
  24. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/client/client.py +0 -0
  25. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/instrumentation.py +0 -0
  26. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/models/__init__.py +0 -0
  27. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/models/errors.py +0 -0
  28. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/models/models.py +0 -0
  29. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/models/schemas.py +0 -0
  30. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/py.typed +0 -0
  31. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/__init__.py +0 -0
  32. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/agent.py +0 -0
  33. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/app.py +0 -0
  34. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/bundle.py +0 -0
  35. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/context.py +0 -0
  36. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/logging.py +0 -0
  37. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/server.py +0 -0
  38. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/session.py +0 -0
  39. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/telemetry.py +0 -0
  40. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/types.py +0 -0
  41. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/server/utils.py +0 -0
  42. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/src/acp_sdk/version.py +0 -0
  43. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/conftest.py +0 -0
  44. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/e2e/__init__.py +0 -0
  45. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/e2e/config.py +0 -0
  46. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/e2e/fixtures/__init__.py +0 -0
  47. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/e2e/fixtures/client.py +0 -0
  48. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/e2e/fixtures/server.py +0 -0
  49. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/e2e/test_suites/__init__.py +0 -0
  50. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/e2e/test_suites/test_runs.py +0 -0
  51. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/unit/models/__init__.py +0 -0
  52. {acp_sdk-0.3.3 → acp_sdk-0.4.0}/tests/unit/models/test_models.py +0 -0
acp_sdk-0.4.0/PKG-INFO ADDED
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: acp-sdk
3
+ Version: 0.4.0
4
+ Summary: Agent Communication Protocol SDK
5
+ Author: IBM Corp.
6
+ Maintainer-email: Tomas Pilar <thomas7pilar@gmail.com>
7
+ License-Expression: Apache-2.0
8
+ Requires-Python: <4.0,>=3.11
9
+ Requires-Dist: fastapi[standard]>=0.115.8
10
+ Requires-Dist: httpx-sse>=0.4.0
11
+ Requires-Dist: httpx>=0.28.1
12
+ Requires-Dist: janus>=2.0.0
13
+ Requires-Dist: opentelemetry-api>=1.31.1
14
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.31.1
15
+ Requires-Dist: opentelemetry-instrumentation-fastapi>=0.52b1
16
+ Requires-Dist: opentelemetry-instrumentation-httpx>=0.52b1
17
+ Requires-Dist: opentelemetry-sdk>=1.31.1
18
+ Requires-Dist: pydantic>=2.11.1
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Agent Communication Protocol SDK for Python
22
+
23
+ Agent Communication Protocol SDK for Python provides allows developers to serve and consume agents over the Agent Communication Protocol.
24
+
25
+ ## Prerequisites
26
+
27
+ ✅ Python >= 3.11
28
+
29
+ ## Installation
30
+
31
+ Install with:
32
+
33
+ ```shell
34
+ pip install acp-sdk
35
+ ```
36
+
37
+ ## Quickstart
38
+
39
+ Register an agent and run the server:
40
+
41
+ ```py
42
+ server = Server()
43
+
44
+ @server.agent()
45
+ async def echo(inputs: list[Message]):
46
+ """Echoes everything"""
47
+ for message in inputs:
48
+ yield message
49
+
50
+ server.run(port=8000)
51
+ ```
52
+
53
+ From another process, connect to the server and run the agent:
54
+
55
+ ```py
56
+ async with Client(base_url="http://localhost:8000") as client:
57
+ run = await client.run_sync(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy!")])])
58
+ print(run)
59
+
60
+ ```
61
+
62
+
63
+ ➡️ Explore more in our [examples library](/examples/python).
@@ -0,0 +1,43 @@
1
+ # Agent Communication Protocol SDK for Python
2
+
3
+ Agent Communication Protocol SDK for Python provides allows developers to serve and consume agents over the Agent Communication Protocol.
4
+
5
+ ## Prerequisites
6
+
7
+ ✅ Python >= 3.11
8
+
9
+ ## Installation
10
+
11
+ Install with:
12
+
13
+ ```shell
14
+ pip install acp-sdk
15
+ ```
16
+
17
+ ## Quickstart
18
+
19
+ Register an agent and run the server:
20
+
21
+ ```py
22
+ server = Server()
23
+
24
+ @server.agent()
25
+ async def echo(inputs: list[Message]):
26
+ """Echoes everything"""
27
+ for message in inputs:
28
+ yield message
29
+
30
+ server.run(port=8000)
31
+ ```
32
+
33
+ From another process, connect to the server and run the agent:
34
+
35
+ ```py
36
+ async with Client(base_url="http://localhost:8000") as client:
37
+ run = await client.run_sync(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy!")])])
38
+ print(run)
39
+
40
+ ```
41
+
42
+
43
+ ➡️ Explore more in our [examples library](/examples/python).
@@ -0,0 +1,7 @@
1
+ - [Python](/python/)
2
+
3
+ - Modules
4
+
5
+ - [Client](client.md)
6
+ - [Server](server.md)
7
+ - [Models](models.md)
@@ -0,0 +1,99 @@
1
+ # Client
2
+
3
+ <!-- TOC -->
4
+ ## Table of Contents
5
+ - [Client](#client)
6
+ - [Table of Contents](#table-of-contents)
7
+ - [Overview](#overview)
8
+ - [Usage](#usage)
9
+ - [Setting up a client](#setting-up-a-client)
10
+ - [Performing discovery](#performing-discovery)
11
+ - [Running an agent](#running-an-agent)
12
+ - [Using sessions](#using-sessions)
13
+ <!-- /TOC -->
14
+
15
+ ---
16
+
17
+ ## Overview
18
+
19
+ The client module provides a thin ACP client that can be integrated into any application that needs to communicate with ACP agents. It provides the following advantages over raw HTTP client:
20
+
21
+ - Strong typing
22
+ - Error handling
23
+ - Stream decoding
24
+ - Session management
25
+ - Instrumentation
26
+
27
+ > [!NOTE]
28
+ >
29
+ > Location within the sdk: [client](/python/src/acp_sdk/client)
30
+
31
+ ## Usage
32
+
33
+ The client is based on the [httpx.AsyncClient](https://www.python-httpx.org/async/). The usage is very similar as demonstrated below.
34
+
35
+ ### Setting up a client
36
+
37
+ To set up a simple client, simply provide an URL:
38
+
39
+ ```py
40
+ async with Client(base_url="http://localhost:8000") as client:
41
+ ...
42
+ ```
43
+
44
+ To use advanced HTTP configuration, provide `httpx` async client:
45
+
46
+ ```py
47
+ async with Client(
48
+ client=httpx.AsyncClient(
49
+ base_url="http://localhost:8000",
50
+ headers={"token": "foobar"})
51
+ ) as client:
52
+ ...
53
+ ```
54
+
55
+ ### Performing discovery
56
+
57
+ To discover available agents:
58
+
59
+ ```py
60
+ async with Client(base_url="http://localhost:8000") as client:
61
+ async for agent in client.agents():
62
+ ...
63
+ ```
64
+
65
+ ### Running an agent
66
+
67
+ Agent run can be invoked in three modes:
68
+
69
+ ```py
70
+ async with Client(base_url="http://localhost:8000") as client:
71
+ message = Message(parts=[MessagePart(content="Hello")])
72
+
73
+ # Async
74
+ run = await client.run_async(agent_name="agent", inputs=[message])
75
+ print(run.status)
76
+
77
+ # Sync - waits for completion, failure, cancellation or await
78
+ run = await client.run_sync(agent_name="agent", inputs=[message])
79
+ print(run.outputs)
80
+
81
+ # Stream - as sync but also receives events
82
+ async for event in client.run_stream(agent_name="agent", inputs=[message])
83
+ print(event)
84
+ ```
85
+
86
+ ### Using sessions
87
+
88
+ Sessions are a mechanism to have multi-turn conversations with agents.
89
+
90
+ To enter a session, create one from the client:
91
+
92
+ ```py
93
+ async with Client(base_url="http://localhost:8000" as client:
94
+ agents = [agent async for agent in client.agents()]
95
+
96
+ async with client.session() as session:
97
+ for agent in agents:
98
+ await session.run_sync(agent_name=agent.name, inputs=[Message(parts=[MessagePart(content="Hello!")])])
99
+ ```
@@ -0,0 +1,104 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>ACP Docs</title>
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
7
+ <meta name="description" content="Description" />
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
9
+ <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css" />
10
+ <link
11
+ rel="stylesheet"
12
+ title="docsify-darklight-theme"
13
+ href="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/style.min.css"
14
+ />
15
+ <style>
16
+ aside.sidebar {
17
+ padding-top: 0;
18
+ }
19
+ .app-name-link img {
20
+ filter: invert(var(--docs-logo-color-invert));
21
+ }
22
+ </style>
23
+ </head>
24
+ <body>
25
+ <div id="app"></div>
26
+ <script>
27
+ function fixLinkFactory() {
28
+ var main = "https://github.com/i-am-bee/acp/tree/main";
29
+ var exampleRegex = /^[\/]{0,1}examples\/(.*)/;
30
+ var srcRegex = /^[\/]{0,1}src\/(.*)/;
31
+ var docsMatch = /^[\/]{0,1}docs\/(.*)/;
32
+
33
+ return function (url) {
34
+ if (url === "LICENSE") {
35
+ return main.concat("/LICENSE");
36
+ }
37
+ if (url.substring(0, 2) === "./") {
38
+ url = url.substring(2);
39
+ }
40
+ if (url.match(docsMatch)) {
41
+ url = url.replace(docsMatch, "$1");
42
+ }
43
+ if (url.match(exampleRegex) || url.match(srcRegex) || url === "/package.json") {
44
+ url = main.concat(url);
45
+ }
46
+ return url;
47
+ };
48
+ }
49
+
50
+ var fixLink = fixLinkFactory();
51
+ var basePath = window.location.pathname.replace(/index.html/gi, "").replace("/#/", "") || "/";
52
+
53
+ window.$docsify = {
54
+ "name": "ACP",
55
+ "basePath": basePath,
56
+ "darklightTheme": {
57
+ "defaultTheme": 'dark',
58
+ "light": {
59
+ 'docs-logo-color-invert': 0,
60
+ },
61
+ "dark": {
62
+ 'docs-logo-color-invert': 1,
63
+ }
64
+ },
65
+ "repo": "i-am-bee/acp",
66
+ "loadSidebar": true,
67
+ "subMaxLevel": 2,
68
+ "auto2top": true,
69
+ "search": {
70
+ depth: 6,
71
+ namespace: "acp",
72
+ },
73
+ "flexible-alerts": {
74
+ important: {
75
+ label: "Important",
76
+ icon: "icon-note",
77
+ className: "note",
78
+ },
79
+ },
80
+ "markdown": {
81
+ smartypants: true,
82
+ renderer: {
83
+ link: function (link, renderer, text) {
84
+ return this.origin.link.apply(this, [fixLink(link), renderer, text]);
85
+ },
86
+ html: function (html) {
87
+ var regex = /(src|href|srcset)\s*=\s*(['"])[\.]{0,1}\/docs\/(.+?)\2/gi;
88
+ html = html.replace(regex, "$1=$2" + basePath + "$3$2");
89
+ return html;
90
+ },
91
+ },
92
+ },
93
+ };
94
+ </script>
95
+ <script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
96
+ <script src="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/index.min.js"></script>
97
+ <script src="https://unpkg.com/docsify-plugin-flexible-alerts"></script>
98
+ <script src="https://unpkg.com/docsify-copy-code@3"></script>
99
+ <script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
100
+ <script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-python.min.js"></script>
101
+ <script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-sql.min.js"></script>
102
+ <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
103
+ </body>
104
+ </html>
@@ -0,0 +1,45 @@
1
+ # Models
2
+
3
+ <!-- TOC -->
4
+ ## Table of Contents
5
+ - [Models](#models)
6
+ - [Table of Contents](#table-of-contents)
7
+ - [Overview](#overview)
8
+ - [Core](#core)
9
+ - [Schemas](#schemas)
10
+ - [Errors](#errors)
11
+ <!-- /TOC -->
12
+
13
+ ---
14
+
15
+ ## Overview
16
+
17
+ The models module provides `pydantic` models describing ACP data structures.
18
+
19
+ > [!NOTE]
20
+ >
21
+ > Location within the sdk: [models](/python/src/acp_sdk/models)
22
+
23
+ ## Core
24
+
25
+ Core models are used directly by the SDK consumers. They describe ACP structures like `Message`, `MessagePart` or `Run`.
26
+
27
+ > [!NOTE]
28
+ >
29
+ > Location within the sdk: [models.models](/python/src/acp_sdk/models/models.py)
30
+
31
+ ## Schemas
32
+
33
+ Schema models are used by client and server implementations. They describe payloads of HTTP requests and responses.
34
+
35
+ > [!NOTE]
36
+ >
37
+ > Location within the sdk: [models.schemas](/python/src/acp_sdk/models/schemas.py)
38
+
39
+ ## Errors
40
+
41
+ Error model describes errors within the system. SDK consumers can encounter errors in various places, during a stream, as part of the `Run` model or raised inside the `ACPError` exception.
42
+
43
+ > [!NOTE]
44
+ >
45
+ > Location within the sdk: [models.errors](/python/src/acp_sdk/models/errors.py)
@@ -0,0 +1,103 @@
1
+ # Server
2
+
3
+ <!-- TOC -->
4
+ ## Table of Contents
5
+ - [Server](#server)
6
+ - [Table of Contents](#table-of-contents)
7
+ - [Overview](#overview)
8
+ - [Usage](#usage)
9
+ - [Running a server](#running-a-server)
10
+ - [Standalone application](#standalone-application)
11
+ <!-- /TOC -->
12
+
13
+ ---
14
+
15
+ ## Overview
16
+
17
+ The server module aims to expose arbitrary agents over the Agent Commucation Protocol. Consumers can use this module to avoid protocol-specific technicalities and focus on the agent itself. The modules provides Agent abstractions, FastAPI application factory and Uvicorn-based server.
18
+
19
+ > [!NOTE]
20
+ >
21
+ > Location within the sdk: [server](/python/src/acp_sdk/server).
22
+
23
+ ## Usage
24
+
25
+ The SDK provides `Agent` abstract class and `agent` decorator. Arbitrary agent can be created in by either inheritance from the class or by using the decorator on a generator, coroutine or a regular function.
26
+
27
+ > [!NOTE]
28
+ >
29
+ > Location within the sdk: [server.agent](/python/src/acp_sdk/server/agent.py).
30
+
31
+ ### Running a server
32
+
33
+ The SDK provides `Server` class as a convenience for developers to easily serve agents over ACP. The server allows to easily create and register agents. It sets up logging and optionally telemetry exporters.
34
+
35
+ <!-- embedme python/examples/servers/echo.py -->
36
+
37
+ ```py
38
+ import asyncio
39
+ from collections.abc import AsyncGenerator
40
+
41
+ from acp_sdk.models import (
42
+ Message,
43
+ )
44
+ from acp_sdk.server import Context, RunYield, RunYieldResume, Server
45
+
46
+ server = Server()
47
+
48
+
49
+ @server.agent()
50
+ async def echo(inputs: list[Message], context: Context) -> AsyncGenerator[RunYield, RunYieldResume]:
51
+ """Echoes everything"""
52
+ for message in inputs:
53
+ await asyncio.sleep(0.5)
54
+ yield {"thought": "I should echo everything"}
55
+ await asyncio.sleep(0.5)
56
+ yield message
57
+
58
+
59
+ server.run()
60
+ ```
61
+
62
+ > [!NOTE]
63
+ >
64
+ > Location within the sdk: [server.server](/python/src/acp_sdk/server/server.py).
65
+
66
+ ### Standalone application
67
+
68
+ The SDK provides `create_app` factory that turns agents into `FastAPI` application. The application implements route handlers, error handlers, unified execution environment and more. The application can be served with arbitrary ASGI compatible server.
69
+
70
+ <!-- embedme python/examples/servers/standalone.py -->
71
+
72
+ ```py
73
+ from collections.abc import AsyncGenerator
74
+
75
+ from acp_sdk.models import (
76
+ Message,
77
+ )
78
+ from acp_sdk.server import RunYield, RunYieldResume, agent, create_app
79
+
80
+ # This example demonstrates how to serve agents with you own server
81
+
82
+
83
+ @agent()
84
+ async def echo(inputs: list[Message]) -> AsyncGenerator[RunYield, RunYieldResume]:
85
+ """Echoes everything"""
86
+ for message in inputs:
87
+ yield message
88
+
89
+
90
+ app = create_app(echo)
91
+
92
+ # The app can now be used with any ASGI server
93
+
94
+ # Run with
95
+ # 1. fastapi run examples/servers/standalone.py
96
+ # 2. uvicorn examples.servers.standalone:app
97
+ # ...
98
+
99
+ ```
100
+
101
+ > [!NOTE]
102
+ >
103
+ > Location within the sdk: [server.app](/python/src/acp_sdk/server/app.py).
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "acp-sdk"
3
- version = "0.3.3"
3
+ version = "0.4.0"
4
4
  description = "Agent Communication Protocol SDK"
5
5
  license = "Apache-2.0"
6
6
  readme = "README.md"
@@ -33,7 +33,7 @@ def status_code_to_error_code(status_code: int) -> ErrorCode:
33
33
  async def acp_error_handler(request: Request, exc: ACPError, *, status_code: int | None = None) -> JSONResponse:
34
34
  error = exc.error
35
35
  return JSONResponse(
36
- status_code=status_code or error_code_to_status_code(error.code), content=error.model_dump_json()
36
+ status_code=status_code or error_code_to_status_code(error.code), content=error.model_dump(mode="json")
37
37
  )
38
38
 
39
39
 
acp_sdk-0.3.3/PKG-INFO DELETED
@@ -1,99 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: acp-sdk
3
- Version: 0.3.3
4
- Summary: Agent Communication Protocol SDK
5
- Author: IBM Corp.
6
- Maintainer-email: Tomas Pilar <thomas7pilar@gmail.com>
7
- License-Expression: Apache-2.0
8
- Requires-Python: <4.0,>=3.11
9
- Requires-Dist: fastapi[standard]>=0.115.8
10
- Requires-Dist: httpx-sse>=0.4.0
11
- Requires-Dist: httpx>=0.28.1
12
- Requires-Dist: janus>=2.0.0
13
- Requires-Dist: opentelemetry-api>=1.31.1
14
- Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.31.1
15
- Requires-Dist: opentelemetry-instrumentation-fastapi>=0.52b1
16
- Requires-Dist: opentelemetry-instrumentation-httpx>=0.52b1
17
- Requires-Dist: opentelemetry-sdk>=1.31.1
18
- Requires-Dist: pydantic>=2.11.1
19
- Description-Content-Type: text/markdown
20
-
21
- # Agent Communication Protocol SDK for Python
22
-
23
- Agent Communication Protocol SDK for Python provides allows developers to serve and consume agents over the Agent Communication Protocol.
24
-
25
- ## Prerequisites
26
-
27
- ✅ Python >= 3.11
28
-
29
- ## Installation
30
-
31
- Install with:
32
-
33
- ```shell
34
- pip install acp-sdk
35
- ```
36
-
37
- ## Overview
38
-
39
- ### Core
40
-
41
- The core of the SDK exposes [pydantic](https://docs.pydantic.dev/) data models corresponding to REST API requests, responses, resources, events and errors.
42
-
43
-
44
- ### Client
45
-
46
- The `client` submodule exposes [httpx](https://www.python-httpx.org/) based client with simple methods for communication over ACP.
47
-
48
- ```python
49
- async with Client(base_url="http://localhost:8000") as client:
50
- run = await client.run_sync(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy!")])])
51
- print(run)
52
-
53
- ```
54
-
55
- ### Server
56
-
57
- The `server` submodule exposes `Agent` class and `agent` decorator together with [fastapi](https://fastapi.tiangolo.com/) application factory, making it easy to expose agents over ACP. Additionaly, it exposes [uvicorn](https://www.uvicorn.org/) based server to serve agents with set up logging, [opentelemetry](https://opentelemetry.io/) and more.
58
-
59
- ```python
60
- server = Server()
61
-
62
- @server.agent()
63
- async def echo(inputs: list[Message], context: Context) -> AsyncGenerator[RunYield, RunYieldResume]:
64
- """Echoes everything"""
65
- for message in inputs:
66
- yield {"thought": "I should echo everything"}
67
- await asyncio.sleep(0.5)
68
- yield message
69
-
70
-
71
- server.run()
72
- ```
73
-
74
- ➡️ Explore more in our [examples library](/python/examples).
75
-
76
- ## Architecture
77
-
78
- The architecture of the SDK is outlined in the following segment. It focuses on central parts of the SDK without going into much detail.
79
-
80
- ### Models
81
-
82
- The core of the SDK contains pydantic models for requests, responses, resources, events and errors. Users of the SDK are meant to use these models directly or indirectly.
83
-
84
- ### Server
85
-
86
- The server module consists of 3 parts:
87
-
88
- 1. Agent interface
89
- 2. FastAPI application factory
90
- 3. Uvicorn based server
91
-
92
- Each part builds on top of the previous one. Not all parts need to be used, e.g. users are advised to bring their own ASGI server for production deployments.
93
-
94
- ### Client
95
-
96
- The client module consists of httpx based client with session support. The client is meant to be thin and mimic the REST API. Exception is session management which has been abstracted into a context manager.
97
-
98
-
99
-
acp_sdk-0.3.3/README.md DELETED
@@ -1,79 +0,0 @@
1
- # Agent Communication Protocol SDK for Python
2
-
3
- Agent Communication Protocol SDK for Python provides allows developers to serve and consume agents over the Agent Communication Protocol.
4
-
5
- ## Prerequisites
6
-
7
- ✅ Python >= 3.11
8
-
9
- ## Installation
10
-
11
- Install with:
12
-
13
- ```shell
14
- pip install acp-sdk
15
- ```
16
-
17
- ## Overview
18
-
19
- ### Core
20
-
21
- The core of the SDK exposes [pydantic](https://docs.pydantic.dev/) data models corresponding to REST API requests, responses, resources, events and errors.
22
-
23
-
24
- ### Client
25
-
26
- The `client` submodule exposes [httpx](https://www.python-httpx.org/) based client with simple methods for communication over ACP.
27
-
28
- ```python
29
- async with Client(base_url="http://localhost:8000") as client:
30
- run = await client.run_sync(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy!")])])
31
- print(run)
32
-
33
- ```
34
-
35
- ### Server
36
-
37
- The `server` submodule exposes `Agent` class and `agent` decorator together with [fastapi](https://fastapi.tiangolo.com/) application factory, making it easy to expose agents over ACP. Additionaly, it exposes [uvicorn](https://www.uvicorn.org/) based server to serve agents with set up logging, [opentelemetry](https://opentelemetry.io/) and more.
38
-
39
- ```python
40
- server = Server()
41
-
42
- @server.agent()
43
- async def echo(inputs: list[Message], context: Context) -> AsyncGenerator[RunYield, RunYieldResume]:
44
- """Echoes everything"""
45
- for message in inputs:
46
- yield {"thought": "I should echo everything"}
47
- await asyncio.sleep(0.5)
48
- yield message
49
-
50
-
51
- server.run()
52
- ```
53
-
54
- ➡️ Explore more in our [examples library](/python/examples).
55
-
56
- ## Architecture
57
-
58
- The architecture of the SDK is outlined in the following segment. It focuses on central parts of the SDK without going into much detail.
59
-
60
- ### Models
61
-
62
- The core of the SDK contains pydantic models for requests, responses, resources, events and errors. Users of the SDK are meant to use these models directly or indirectly.
63
-
64
- ### Server
65
-
66
- The server module consists of 3 parts:
67
-
68
- 1. Agent interface
69
- 2. FastAPI application factory
70
- 3. Uvicorn based server
71
-
72
- Each part builds on top of the previous one. Not all parts need to be used, e.g. users are advised to bring their own ASGI server for production deployments.
73
-
74
- ### Client
75
-
76
- The client module consists of httpx based client with session support. The client is meant to be thin and mimic the REST API. Exception is session management which has been abstracted into a context manager.
77
-
78
-
79
-
@@ -1,21 +0,0 @@
1
- import asyncio
2
-
3
- import httpx
4
- from acp_sdk.client.client import Client
5
- from acp_sdk.models import Message, MessagePart
6
-
7
-
8
- async def example() -> None:
9
- async with Client(
10
- client=httpx.AsyncClient(
11
- base_url="http://localhost:8000",
12
- auth=httpx.BasicAuth(username="username", password="password"),
13
- # Additional client configuration
14
- )
15
- ) as client:
16
- run = await client.run_sync(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy!")])])
17
- print(run)
18
-
19
-
20
- if __name__ == "__main__":
21
- asyncio.run(example())
@@ -1,18 +0,0 @@
1
- import asyncio
2
-
3
- from acp_sdk.client import Client
4
- from acp_sdk.models import (
5
- Message,
6
- MessagePart,
7
- )
8
-
9
-
10
- async def example() -> None:
11
- async with Client(base_url="http://localhost:8000") as client, client.session() as session:
12
- run = await session.run_sync(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy!")])])
13
- run = await session.run_sync(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy again!")])])
14
- print(run)
15
-
16
-
17
- if __name__ == "__main__":
18
- asyncio.run(example())
@@ -1,17 +0,0 @@
1
- import asyncio
2
-
3
- from acp_sdk.client import Client
4
- from acp_sdk.models import (
5
- Message,
6
- MessagePart,
7
- )
8
-
9
-
10
- async def example() -> None:
11
- async with Client(base_url="http://localhost:8000") as client:
12
- run = await client.run_sync(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy!")])])
13
- print(run)
14
-
15
-
16
- if __name__ == "__main__":
17
- asyncio.run(example())
@@ -1,14 +0,0 @@
1
- import asyncio
2
-
3
- from acp_sdk.client import Client
4
- from acp_sdk.models import Message, MessagePart
5
-
6
-
7
- async def example() -> None:
8
- async with Client(base_url="http://localhost:8000") as client:
9
- async for event in client.run_stream(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy!")])]):
10
- print(event)
11
-
12
-
13
- if __name__ == "__main__":
14
- asyncio.run(example())
@@ -1,26 +0,0 @@
1
- from collections.abc import AsyncGenerator
2
-
3
- from acp_sdk.models import (
4
- Message,
5
- MessageAwaitRequest,
6
- MessageAwaitResume,
7
- MessagePart,
8
- )
9
- from acp_sdk.server import Context, Server
10
- from acp_sdk.server.types import RunYield, RunYieldResume
11
-
12
- server = Server()
13
-
14
-
15
- @server.agent()
16
- async def awaiting(inputs: list[Message], context: Context) -> AsyncGenerator[RunYield, RunYieldResume]:
17
- """Greets and awaits for more data"""
18
- yield MessagePart(content="Hello!")
19
- resume = yield MessageAwaitRequest(
20
- message=Message(parts=[MessagePart(content="Can you provide me with additional configuration?")])
21
- )
22
- assert isinstance(resume, MessageAwaitResume)
23
- yield MessagePart(content=f"Thanks for config: {resume.message}")
24
-
25
-
26
- server.run()
@@ -1,22 +0,0 @@
1
- import asyncio
2
- from collections.abc import AsyncGenerator
3
-
4
- from acp_sdk.models import (
5
- Message,
6
- )
7
- from acp_sdk.server import Context, RunYield, RunYieldResume, Server
8
-
9
- server = Server()
10
-
11
-
12
- @server.agent()
13
- async def echo(inputs: list[Message], context: Context) -> AsyncGenerator[RunYield, RunYieldResume]:
14
- """Echoes everything"""
15
- for message in inputs:
16
- await asyncio.sleep(0.5)
17
- yield {"thought": "I should echo everything"}
18
- await asyncio.sleep(0.5)
19
- yield message
20
-
21
-
22
- server.run()
@@ -1,25 +0,0 @@
1
- from collections.abc import AsyncGenerator
2
-
3
- from acp_sdk.models import (
4
- Message,
5
- )
6
- from acp_sdk.server import RunYield, RunYieldResume, agent, create_app
7
-
8
- # This example demonstrates how to serve agents with you own server
9
-
10
-
11
- @agent()
12
- async def echo(inputs: list[Message]) -> AsyncGenerator[RunYield, RunYieldResume]:
13
- """Echoes everything"""
14
- for message in inputs:
15
- yield message
16
-
17
-
18
- app = create_app(echo)
19
-
20
- # The app can now be used with any ASGI server
21
-
22
- # Run with
23
- # 1. fastapi run examples/servers/standalone.py
24
- # 2. uvicorn examples.servers.standalone:app
25
- # ...
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes