acp-sdk 0.0.6__py3-none-any.whl → 0.1.0__py3-none-any.whl

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 (79) hide show
  1. acp_sdk/__init__.py +2 -0
  2. acp_sdk/client/__init__.py +1 -0
  3. acp_sdk/client/client.py +178 -0
  4. acp_sdk/models/__init__.py +3 -0
  5. acp_sdk/models/errors.py +23 -0
  6. acp_sdk/models/models.py +192 -0
  7. acp_sdk/models/schemas.py +41 -0
  8. acp_sdk/server/__init__.py +7 -0
  9. acp_sdk/server/agent.py +178 -0
  10. acp_sdk/server/app.py +176 -0
  11. acp_sdk/server/bundle.py +146 -0
  12. acp_sdk/server/context.py +33 -0
  13. acp_sdk/server/errors.py +54 -0
  14. acp_sdk/server/logging.py +16 -0
  15. acp_sdk/server/server.py +166 -0
  16. acp_sdk/server/session.py +21 -0
  17. acp_sdk/server/telemetry.py +57 -0
  18. acp_sdk/server/types.py +6 -0
  19. acp_sdk/server/utils.py +14 -0
  20. acp_sdk/version.py +3 -0
  21. acp_sdk-0.1.0.dist-info/METADATA +113 -0
  22. acp_sdk-0.1.0.dist-info/RECORD +24 -0
  23. acp/__init__.py +0 -138
  24. acp/cli/__init__.py +0 -6
  25. acp/cli/claude.py +0 -139
  26. acp/cli/cli.py +0 -471
  27. acp/client/__init__.py +0 -0
  28. acp/client/__main__.py +0 -79
  29. acp/client/session.py +0 -372
  30. acp/client/sse.py +0 -145
  31. acp/client/stdio.py +0 -153
  32. acp/server/__init__.py +0 -3
  33. acp/server/__main__.py +0 -50
  34. acp/server/highlevel/__init__.py +0 -9
  35. acp/server/highlevel/agents/__init__.py +0 -5
  36. acp/server/highlevel/agents/agent_manager.py +0 -110
  37. acp/server/highlevel/agents/base.py +0 -20
  38. acp/server/highlevel/agents/templates.py +0 -21
  39. acp/server/highlevel/context.py +0 -185
  40. acp/server/highlevel/exceptions.py +0 -25
  41. acp/server/highlevel/prompts/__init__.py +0 -4
  42. acp/server/highlevel/prompts/base.py +0 -167
  43. acp/server/highlevel/prompts/manager.py +0 -50
  44. acp/server/highlevel/prompts/prompt_manager.py +0 -33
  45. acp/server/highlevel/resources/__init__.py +0 -23
  46. acp/server/highlevel/resources/base.py +0 -48
  47. acp/server/highlevel/resources/resource_manager.py +0 -94
  48. acp/server/highlevel/resources/templates.py +0 -80
  49. acp/server/highlevel/resources/types.py +0 -185
  50. acp/server/highlevel/server.py +0 -705
  51. acp/server/highlevel/tools/__init__.py +0 -4
  52. acp/server/highlevel/tools/base.py +0 -83
  53. acp/server/highlevel/tools/tool_manager.py +0 -53
  54. acp/server/highlevel/utilities/__init__.py +0 -1
  55. acp/server/highlevel/utilities/func_metadata.py +0 -210
  56. acp/server/highlevel/utilities/logging.py +0 -43
  57. acp/server/highlevel/utilities/types.py +0 -54
  58. acp/server/lowlevel/__init__.py +0 -3
  59. acp/server/lowlevel/helper_types.py +0 -9
  60. acp/server/lowlevel/server.py +0 -643
  61. acp/server/models.py +0 -17
  62. acp/server/session.py +0 -315
  63. acp/server/sse.py +0 -175
  64. acp/server/stdio.py +0 -83
  65. acp/server/websocket.py +0 -61
  66. acp/shared/__init__.py +0 -0
  67. acp/shared/context.py +0 -14
  68. acp/shared/exceptions.py +0 -14
  69. acp/shared/memory.py +0 -87
  70. acp/shared/progress.py +0 -40
  71. acp/shared/session.py +0 -413
  72. acp/shared/version.py +0 -3
  73. acp/types.py +0 -1258
  74. acp_sdk-0.0.6.dist-info/METADATA +0 -46
  75. acp_sdk-0.0.6.dist-info/RECORD +0 -57
  76. acp_sdk-0.0.6.dist-info/entry_points.txt +0 -2
  77. acp_sdk-0.0.6.dist-info/licenses/LICENSE +0 -22
  78. {acp → acp_sdk}/py.typed +0 -0
  79. {acp_sdk-0.0.6.dist-info → acp_sdk-0.1.0.dist-info}/WHEEL +0 -0
acp_sdk/version.py ADDED
@@ -0,0 +1,3 @@
1
+ from importlib.metadata import version
2
+
3
+ __version__ = version("acp-sdk")
@@ -0,0 +1,113 @@
1
+ Metadata-Version: 2.4
2
+ Name: acp-sdk
3
+ Version: 0.1.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: opentelemetry-api>=1.31.1
10
+ Requires-Dist: pydantic>=2.11.1
11
+ Provides-Extra: client
12
+ Requires-Dist: httpx-sse>=0.4.0; extra == 'client'
13
+ Requires-Dist: httpx>=0.28.1; extra == 'client'
14
+ Requires-Dist: opentelemetry-instrumentation-httpx>=0.52b1; extra == 'client'
15
+ Provides-Extra: server
16
+ Requires-Dist: fastapi[standard]>=0.115.8; extra == 'server'
17
+ Requires-Dist: janus>=2.0.0; extra == 'server'
18
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.31.1; extra == 'server'
19
+ Requires-Dist: opentelemetry-instrumentation-fastapi>=0.52b1; extra == 'server'
20
+ Requires-Dist: opentelemetry-sdk>=1.31.1; extra == 'server'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Agent Communication Protocol SDK for Python
24
+
25
+ Agent Communication Protocol SDK for Python provides allows developers to serve and consume agents over the Agent Communication Protocol.
26
+
27
+ ## Prerequisites
28
+
29
+ ✅ Python >= 3.11
30
+
31
+ ## Installation
32
+
33
+ Install to use client:
34
+
35
+ ```shell
36
+ pip install acp-sdk[client]
37
+ ```
38
+
39
+ Install to use server:
40
+
41
+ ```shell
42
+ pip install acp-sdk[server]
43
+ ```
44
+
45
+ Install to use models only:
46
+
47
+ ```shell
48
+ pip install acp-sdk
49
+ ```
50
+
51
+ ## Overview
52
+
53
+ ### Core
54
+
55
+ The core of the SDK exposes [pydantic](https://docs.pydantic.dev/) data models corresponding to REST API requests, responses, resources, events and errors.
56
+
57
+
58
+ ### Client
59
+
60
+ The `client` submodule exposes [httpx](https://www.python-httpx.org/) based client with simple methods for communication over ACP.
61
+
62
+ ```python
63
+ async with Client(base_url="http://localhost:8000") as client:
64
+ run = await client.run_sync(agent="echo", inputs=[Message(parts=[MessagePart(content="Howdy!")])])
65
+ print(run)
66
+
67
+ ```
68
+
69
+ ### Server
70
+
71
+ 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.
72
+
73
+ ```python
74
+ server = Server()
75
+
76
+ @server.agent()
77
+ async def echo(inputs: list[Message], context: Context) -> AsyncGenerator[RunYield, RunYieldResume]:
78
+ """Echoes everything"""
79
+ for message in inputs:
80
+ yield {"thought": "I should echo everyting"}
81
+ await asyncio.sleep(0.5)
82
+ yield message
83
+
84
+
85
+ server.run()
86
+ ```
87
+
88
+ ➡️ Explore more in our [examples library](/python/examples).
89
+
90
+ ## Architecture
91
+
92
+ The architecture of the SDK is outlined in the following segment. It focuses on central parts of the SDK without going into much detail.
93
+
94
+ ### Models
95
+
96
+ 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.
97
+
98
+ ### Server
99
+
100
+ The server module consists of 3 parts:
101
+
102
+ 1. Agent interface
103
+ 2. FastAPI application factory
104
+ 3. Uvicorn based server
105
+
106
+ 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.
107
+
108
+ ### Client
109
+
110
+ 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.
111
+
112
+
113
+
@@ -0,0 +1,24 @@
1
+ acp_sdk/__init__.py,sha256=tXdAUM9zcmdSKCAkVrOCrGcXcuVS-yuvQUoQwTe9pek,98
2
+ acp_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ acp_sdk/version.py,sha256=Niy83rgvigB4hL_rR-O4ySvI7dj6xnqkyOe_JTymi9s,73
4
+ acp_sdk/client/__init__.py,sha256=Bca1DORrswxzZsrR2aUFpATuNG2xNSmYvF1Z2WJaVbc,51
5
+ acp_sdk/client/client.py,sha256=phsFdVMdVmTcfmzUQUgqzzvq4zNvmEUgW2eL9cFJY2g,6140
6
+ acp_sdk/models/__init__.py,sha256=numSDBDT1QHx7n_Y3Deb5VOvKWcUBxbOEaMwQBSRHxc,151
7
+ acp_sdk/models/errors.py,sha256=rEyaMVvQuBi7fwWe_d0PGGySYsD3FZTluQ-SkC0yhAs,444
8
+ acp_sdk/models/models.py,sha256=kxCbWoukCYrUseJZF0xUOgGc-3cS32VBSXggHroZ-H0,4676
9
+ acp_sdk/models/schemas.py,sha256=LNs3oN1pQ4GD0ceV3-k6X6R39eu33nsAfnW6uEgOP0c,735
10
+ acp_sdk/server/__init__.py,sha256=mxBBBFaZuMEUENRMLwp1XZkuLeT9QghcFmNvjnqvAAU,377
11
+ acp_sdk/server/agent.py,sha256=fGky5MIuknw-Gy-THqhWLt9I9-gUyNIar8qEAvZb3uQ,6195
12
+ acp_sdk/server/app.py,sha256=Ys5EN4MzmrwrpBGvycEP5dKEIYkDZmeBMMV1Aq58AU0,5897
13
+ acp_sdk/server/bundle.py,sha256=VUOqzBhwsADkoyPWqXSZ2KG59S3q4LMDfpFVAssnGSM,5386
14
+ acp_sdk/server/context.py,sha256=MgnLV6qcDIhc_0BjW7r4Jj1tHts4ZuwpdTGIBnz2Mgo,1036
15
+ acp_sdk/server/errors.py,sha256=fWlgVsQ5hs_AXwzc-wvy6QgoDWEMRUBlSrfJfhHHMyE,2085
16
+ acp_sdk/server/logging.py,sha256=Oc8yZigCsuDnHHPsarRzu0RX3NKaLEgpELM2yovGKDI,411
17
+ acp_sdk/server/server.py,sha256=-eT3fmnEsBUN44Spi2EP2eV0l4RAlKa8bzqxnhz16SM,5399
18
+ acp_sdk/server/session.py,sha256=0cDr924HC5x2bBNbK9NSKVHAt5A_mi5dK8P4jP_ugq0,629
19
+ acp_sdk/server/telemetry.py,sha256=WIEHK8syOTG9SyWi3Y-cos7CsCF5-IHGiyL9bCaUN0E,1921
20
+ acp_sdk/server/types.py,sha256=2yJPkfUzjVIhHmc0SegGTMqDROe2uFgycb-7CATvYVw,161
21
+ acp_sdk/server/utils.py,sha256=EfrF9VCyVk3AM_ao-BIB9EzGbfTrh4V2Bz-VFr6f6Sg,351
22
+ acp_sdk-0.1.0.dist-info/METADATA,sha256=I2gNsDG4Zskh5oddVAYBttUiGIKExdIfFNA8Br6fioQ,3463
23
+ acp_sdk-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
24
+ acp_sdk-0.1.0.dist-info/RECORD,,
acp/__init__.py DELETED
@@ -1,138 +0,0 @@
1
- from .client.session import ClientSession
2
- from .client.stdio import StdioServerParameters, stdio_client
3
- from .server.session import ServerSession
4
- from .server.stdio import stdio_server
5
- from .shared.exceptions import McpError
6
- from .types import (
7
- Agent,
8
- AgentTemplate,
9
- CallToolRequest,
10
- ClientCapabilities,
11
- ClientNotification,
12
- ClientRequest,
13
- ClientResult,
14
- CompleteRequest,
15
- CreateAgentRequest,
16
- CreateAgentResult,
17
- CreateMessageRequest,
18
- CreateMessageResult,
19
- DestroyAgentRequest,
20
- DestroyAgentResult,
21
- ErrorData,
22
- GetPromptRequest,
23
- GetPromptResult,
24
- Implementation,
25
- IncludeContext,
26
- InitializedNotification,
27
- InitializeRequest,
28
- InitializeResult,
29
- JSONRPCError,
30
- JSONRPCRequest,
31
- JSONRPCResponse,
32
- ListAgentsRequest,
33
- ListAgentsResult,
34
- ListAgentTemplatesRequest,
35
- ListAgentTemplatesResult,
36
- ListPromptsRequest,
37
- ListPromptsResult,
38
- ListResourcesRequest,
39
- ListResourcesResult,
40
- ListToolsResult,
41
- LoggingLevel,
42
- LoggingMessageNotification,
43
- Notification,
44
- PingRequest,
45
- ProgressNotification,
46
- PromptsCapability,
47
- ReadResourceRequest,
48
- ReadResourceResult,
49
- Resource,
50
- ResourcesCapability,
51
- ResourceUpdatedNotification,
52
- RootsCapability,
53
- RunAgentRequest,
54
- RunAgentResult,
55
- SamplingMessage,
56
- ServerCapabilities,
57
- ServerNotification,
58
- ServerRequest,
59
- ServerResult,
60
- SetLevelRequest,
61
- StopReason,
62
- SubscribeRequest,
63
- Tool,
64
- ToolsCapability,
65
- UnsubscribeRequest,
66
- )
67
- from .types import (
68
- Role as SamplingRole,
69
- )
70
-
71
- __all__ = [
72
- "CallToolRequest",
73
- "ClientCapabilities",
74
- "ClientNotification",
75
- "ClientRequest",
76
- "ClientResult",
77
- "ClientSession",
78
- "CreateMessageRequest",
79
- "CreateMessageResult",
80
- "ErrorData",
81
- "GetPromptRequest",
82
- "GetPromptResult",
83
- "Implementation",
84
- "IncludeContext",
85
- "InitializeRequest",
86
- "InitializeResult",
87
- "InitializedNotification",
88
- "JSONRPCError",
89
- "JSONRPCRequest",
90
- "ListPromptsRequest",
91
- "ListPromptsResult",
92
- "ListResourcesRequest",
93
- "ListResourcesResult",
94
- "ListToolsResult",
95
- "LoggingLevel",
96
- "LoggingMessageNotification",
97
- "McpError",
98
- "Notification",
99
- "PingRequest",
100
- "ProgressNotification",
101
- "PromptsCapability",
102
- "ReadResourceRequest",
103
- "ReadResourceResult",
104
- "ResourcesCapability",
105
- "ResourceUpdatedNotification",
106
- "Resource",
107
- "RootsCapability",
108
- "SamplingMessage",
109
- "SamplingRole",
110
- "ServerCapabilities",
111
- "ServerNotification",
112
- "ServerRequest",
113
- "ServerResult",
114
- "ServerSession",
115
- "SetLevelRequest",
116
- "StdioServerParameters",
117
- "StopReason",
118
- "SubscribeRequest",
119
- "Tool",
120
- "ToolsCapability",
121
- "UnsubscribeRequest",
122
- "stdio_client",
123
- "stdio_server",
124
- "CompleteRequest",
125
- "JSONRPCResponse",
126
- "AgentTemplate",
127
- "ListAgentTemplatesRequest",
128
- "ListAgentTemplatesResult",
129
- "Agent",
130
- "ListAgentsRequest",
131
- "ListAgentsResult",
132
- "CreateAgentRequest",
133
- "CreateAgentResult",
134
- "DestroyAgentRequest",
135
- "DestroyAgentResult",
136
- "RunAgentRequest",
137
- "RunAgentResult",
138
- ]
acp/cli/__init__.py DELETED
@@ -1,6 +0,0 @@
1
- """FastMCP CLI package."""
2
-
3
- from .cli import app
4
-
5
- if __name__ == "__main__":
6
- app()
acp/cli/claude.py DELETED
@@ -1,139 +0,0 @@
1
- """Claude app integration utilities."""
2
-
3
- import json
4
- import sys
5
- from pathlib import Path
6
-
7
- from acp.server.highlevel.utilities.logging import get_logger
8
-
9
- logger = get_logger(__name__)
10
-
11
- MCP_PACKAGE = "acp[cli]"
12
-
13
-
14
- def get_claude_config_path() -> Path | None:
15
- """Get the Claude config directory based on platform."""
16
- if sys.platform == "win32":
17
- path = Path(Path.home(), "AppData", "Roaming", "Claude")
18
- elif sys.platform == "darwin":
19
- path = Path(Path.home(), "Library", "Application Support", "Claude")
20
- else:
21
- return None
22
-
23
- if path.exists():
24
- return path
25
- return None
26
-
27
-
28
- def update_claude_config(
29
- file_spec: str,
30
- server_name: str,
31
- *,
32
- with_editable: Path | None = None,
33
- with_packages: list[str] | None = None,
34
- env_vars: dict[str, str] | None = None,
35
- ) -> bool:
36
- """Add or update a FastMCP server in Claude's configuration.
37
-
38
- Args:
39
- file_spec: Path to the server file, optionally with :object suffix
40
- server_name: Name for the server in Claude's config
41
- with_editable: Optional directory to install in editable mode
42
- with_packages: Optional list of additional packages to install
43
- env_vars: Optional dictionary of environment variables. These are merged with
44
- any existing variables, with new values taking precedence.
45
-
46
- Raises:
47
- RuntimeError: If Claude Desktop's config directory is not found, indicating
48
- Claude Desktop may not be installed or properly set up.
49
- """
50
- config_dir = get_claude_config_path()
51
- if not config_dir:
52
- raise RuntimeError(
53
- "Claude Desktop config directory not found. Please ensure Claude Desktop"
54
- " is installed and has been run at least once to initialize its config."
55
- )
56
-
57
- config_file = config_dir / "claude_desktop_config.json"
58
- if not config_file.exists():
59
- try:
60
- config_file.write_text("{}")
61
- except Exception as e:
62
- logger.error(
63
- "Failed to create Claude config file",
64
- extra={
65
- "error": str(e),
66
- "config_file": str(config_file),
67
- },
68
- )
69
- return False
70
-
71
- try:
72
- config = json.loads(config_file.read_text())
73
- if "mcpServers" not in config:
74
- config["mcpServers"] = {}
75
-
76
- # Always preserve existing env vars and merge with new ones
77
- if (
78
- server_name in config["mcpServers"]
79
- and "env" in config["mcpServers"][server_name]
80
- ):
81
- existing_env = config["mcpServers"][server_name]["env"]
82
- if env_vars:
83
- # New vars take precedence over existing ones
84
- env_vars = {**existing_env, **env_vars}
85
- else:
86
- env_vars = existing_env
87
-
88
- # Build uv run command
89
- args = ["run"]
90
-
91
- # Collect all packages in a set to deduplicate
92
- packages = {MCP_PACKAGE}
93
- if with_packages:
94
- packages.update(pkg for pkg in with_packages if pkg)
95
-
96
- # Add all packages with --with
97
- for pkg in sorted(packages):
98
- args.extend(["--with", pkg])
99
-
100
- if with_editable:
101
- args.extend(["--with-editable", str(with_editable)])
102
-
103
- # Convert file path to absolute before adding to command
104
- # Split off any :object suffix first
105
- if ":" in file_spec:
106
- file_path, server_object = file_spec.rsplit(":", 1)
107
- file_spec = f"{Path(file_path).resolve()}:{server_object}"
108
- else:
109
- file_spec = str(Path(file_spec).resolve())
110
-
111
- # Add fastmcp run command
112
- args.extend(["acp", "run", file_spec])
113
-
114
- server_config = {
115
- "command": "uv",
116
- "args": args,
117
- }
118
-
119
- # Add environment variables if specified
120
- if env_vars:
121
- server_config["env"] = env_vars
122
-
123
- config["mcpServers"][server_name] = server_config
124
-
125
- config_file.write_text(json.dumps(config, indent=2))
126
- logger.info(
127
- f"Added server '{server_name}' to Claude config",
128
- extra={"config_file": str(config_file)},
129
- )
130
- return True
131
- except Exception as e:
132
- logger.error(
133
- "Failed to update Claude config",
134
- extra={
135
- "error": str(e),
136
- "config_file": str(config_file),
137
- },
138
- )
139
- return False