acp-sdk 0.3.0__tar.gz → 0.3.1__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 (44) hide show
  1. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/PKG-INFO +2 -14
  2. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/README.md +1 -13
  3. acp_sdk-0.3.1/examples/servers/awaiting.py +28 -0
  4. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/pyproject.toml +1 -1
  5. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/models/models.py +10 -4
  6. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/app.py +10 -0
  7. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/bundle.py +2 -0
  8. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/types.py +1 -1
  9. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/tests/e2e/fixtures/server.py +5 -3
  10. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/tests/e2e/test_suites/test_runs.py +5 -4
  11. acp_sdk-0.3.0/examples/servers/awaiting.py +0 -25
  12. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/.gitignore +0 -0
  13. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/.python-version +0 -0
  14. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/examples/clients/advanced.py +0 -0
  15. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/examples/clients/session.py +0 -0
  16. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/examples/clients/simple.py +0 -0
  17. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/examples/clients/stream.py +0 -0
  18. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/examples/servers/echo.py +0 -0
  19. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/examples/servers/standalone.py +0 -0
  20. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/pytest.ini +0 -0
  21. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/__init__.py +0 -0
  22. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/client/__init__.py +0 -0
  23. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/client/client.py +0 -0
  24. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/instrumentation.py +0 -0
  25. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/models/__init__.py +0 -0
  26. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/models/errors.py +0 -0
  27. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/models/schemas.py +0 -0
  28. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/py.typed +0 -0
  29. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/__init__.py +0 -0
  30. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/agent.py +0 -0
  31. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/context.py +0 -0
  32. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/errors.py +0 -0
  33. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/logging.py +0 -0
  34. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/server.py +0 -0
  35. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/session.py +0 -0
  36. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/telemetry.py +0 -0
  37. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/server/utils.py +0 -0
  38. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/src/acp_sdk/version.py +0 -0
  39. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/tests/conftest.py +0 -0
  40. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/tests/e2e/__init__.py +0 -0
  41. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/tests/e2e/config.py +0 -0
  42. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/tests/e2e/fixtures/__init__.py +0 -0
  43. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/tests/e2e/fixtures/client.py +0 -0
  44. {acp_sdk-0.3.0 → acp_sdk-0.3.1}/tests/e2e/test_suites/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: acp-sdk
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: Agent Communication Protocol SDK
5
5
  Author: IBM Corp.
6
6
  Maintainer-email: Tomas Pilar <thomas7pilar@gmail.com>
@@ -28,19 +28,7 @@ Agent Communication Protocol SDK for Python provides allows developers to serve
28
28
 
29
29
  ## Installation
30
30
 
31
- Install to use client:
32
-
33
- ```shell
34
- pip install acp-sdk[client]
35
- ```
36
-
37
- Install to use server:
38
-
39
- ```shell
40
- pip install acp-sdk[server]
41
- ```
42
-
43
- Install to use models only:
31
+ Install with:
44
32
 
45
33
  ```shell
46
34
  pip install acp-sdk
@@ -8,19 +8,7 @@ Agent Communication Protocol SDK for Python provides allows developers to serve
8
8
 
9
9
  ## Installation
10
10
 
11
- Install to use client:
12
-
13
- ```shell
14
- pip install acp-sdk[client]
15
- ```
16
-
17
- Install to use server:
18
-
19
- ```shell
20
- pip install acp-sdk[server]
21
- ```
22
-
23
- Install to use models only:
11
+ Install with:
24
12
 
25
13
  ```shell
26
14
  pip install acp-sdk
@@ -0,0 +1,28 @@
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!", content_type="text/plain")
19
+ resume = yield MessageAwaitRequest(
20
+ message=Message(
21
+ parts=[MessagePart(content="Can you provide me with additional configuration?", content_type="text/plain")]
22
+ )
23
+ )
24
+ assert isinstance(resume, MessageAwaitResume)
25
+ yield MessagePart(content=f"Thanks for config: {resume.message}", content_type="text/plain")
26
+
27
+
28
+ server.run()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "acp-sdk"
3
- version = "0.3.0"
3
+ version = "0.3.1"
4
4
  description = "Agent Communication Protocol SDK"
5
5
  license = "Apache-2.0"
6
6
  readme = "README.md"
@@ -75,12 +75,18 @@ class RunStatus(str, Enum):
75
75
  return self in terminal_states
76
76
 
77
77
 
78
- class AwaitRequest(BaseModel):
79
- type: Literal["placeholder"] = "placeholder"
78
+ class MessageAwaitRequest(BaseModel):
79
+ type: Literal["message"] = "message"
80
+ message: Message
81
+
82
+
83
+ class MessageAwaitResume(BaseModel):
84
+ type: Literal["message"] = "message"
85
+ message: Message
80
86
 
81
87
 
82
- class AwaitResume(BaseModel):
83
- pass
88
+ AwaitRequest = Union[MessageAwaitRequest]
89
+ AwaitResume = Union[MessageAwaitResume]
84
90
 
85
91
 
86
92
  class Run(BaseModel):
@@ -144,6 +144,16 @@ def create_app(*agents: Agent) -> FastAPI:
144
144
  @app.post("/runs/{run_id}")
145
145
  async def resume_run(run_id: RunId, request: RunResumeRequest) -> RunResumeResponse:
146
146
  bundle = find_run_bundle(run_id)
147
+
148
+ if bundle.run.await_request is None:
149
+ raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=f"Run {run_id} has no await request")
150
+
151
+ if bundle.run.await_request.type != request.await_resume.type:
152
+ raise HTTPException(
153
+ status_code=status.HTTP_403_FORBIDDEN,
154
+ detail=f"Run {run_id} is expecting resume of type {bundle.run.await_request.type}",
155
+ )
156
+
147
157
  await bundle.resume(request.await_resume)
148
158
  match request.mode:
149
159
  case RunMode.STREAM:
@@ -129,6 +129,8 @@ class RunBundle:
129
129
  run_logger.info("Run resumed")
130
130
  elif isinstance(next, Error):
131
131
  raise ACPError(error=next)
132
+ elif next is None:
133
+ pass # Do nothing
132
134
  else:
133
135
  try:
134
136
  generic = AnyModel.model_validate(next)
@@ -2,5 +2,5 @@ from typing import Any
2
2
 
3
3
  from acp_sdk.models import AwaitRequest, AwaitResume, Message
4
4
 
5
- RunYield = Message | AwaitRequest | dict[str | Any]
5
+ RunYield = Message | AwaitRequest | dict[str | Any] | None
6
6
  RunYieldResume = AwaitResume | None
@@ -4,7 +4,7 @@ from collections.abc import AsyncGenerator, AsyncIterator, Generator
4
4
  from threading import Thread
5
5
 
6
6
  import pytest
7
- from acp_sdk.models import Artifact, AwaitRequest, AwaitResume, Error, ErrorCode, Message, MessagePart
7
+ from acp_sdk.models import Artifact, AwaitResume, Error, ErrorCode, Message, MessageAwaitRequest, MessagePart
8
8
  from acp_sdk.server import Context, Server
9
9
 
10
10
  from e2e.config import Config
@@ -20,8 +20,10 @@ def server() -> Generator[None]:
20
20
  yield message
21
21
 
22
22
  @server.agent()
23
- async def awaiter(inputs: list[Message], context: Context) -> AsyncGenerator[Message | AwaitRequest, AwaitResume]:
24
- yield AwaitRequest()
23
+ async def awaiter(
24
+ inputs: list[Message], context: Context
25
+ ) -> AsyncGenerator[Message | MessageAwaitRequest, AwaitResume]:
26
+ yield MessageAwaitRequest(message=Message(parts=[]))
25
27
  yield MessagePart(content="empty", content_type="text/plain")
26
28
 
27
29
  @server.agent()
@@ -4,9 +4,9 @@ import pytest
4
4
  from acp_sdk.client import Client
5
5
  from acp_sdk.models import (
6
6
  ArtifactEvent,
7
- AwaitResume,
8
7
  ErrorCode,
9
8
  Message,
9
+ MessageAwaitResume,
10
10
  MessageCreatedEvent,
11
11
  MessagePart,
12
12
  RunCompletedEvent,
@@ -17,6 +17,7 @@ from acp_sdk.models import (
17
17
  from acp_sdk.server import Server
18
18
 
19
19
  inputs = [Message(parts=[MessagePart(content="Hello!", content_type="text/plain")])]
20
+ await_resume = MessageAwaitResume(message=Message(parts=[]))
20
21
 
21
22
 
22
23
  @pytest.mark.asyncio
@@ -69,7 +70,7 @@ async def test_run_resume_sync(server: Server, client: Client) -> None:
69
70
  assert run.status == RunStatus.AWAITING
70
71
  assert run.await_request is not None
71
72
 
72
- run = await client.run_resume_sync(run_id=run.run_id, await_resume=AwaitResume())
73
+ run = await client.run_resume_sync(run_id=run.run_id, await_resume=await_resume)
73
74
  assert run.status == RunStatus.COMPLETED
74
75
 
75
76
 
@@ -79,7 +80,7 @@ async def test_run_resume_async(server: Server, client: Client) -> None:
79
80
  assert run.status == RunStatus.AWAITING
80
81
  assert run.await_request is not None
81
82
 
82
- run = await client.run_resume_async(run_id=run.run_id, await_resume=AwaitResume())
83
+ run = await client.run_resume_async(run_id=run.run_id, await_resume=await_resume)
83
84
  assert run.status == RunStatus.IN_PROGRESS
84
85
 
85
86
 
@@ -89,7 +90,7 @@ async def test_run_resume_stream(server: Server, client: Client) -> None:
89
90
  assert run.status == RunStatus.AWAITING
90
91
  assert run.await_request is not None
91
92
 
92
- event_stream = [event async for event in client.run_resume_stream(run_id=run.run_id, await_resume=AwaitResume())]
93
+ event_stream = [event async for event in client.run_resume_stream(run_id=run.run_id, await_resume=await_resume)]
93
94
  assert isinstance(event_stream[0], RunInProgressEvent)
94
95
  assert isinstance(event_stream[-1], RunCompletedEvent)
95
96
 
@@ -1,25 +0,0 @@
1
- from collections.abc import AsyncGenerator
2
- from typing import Any
3
-
4
- from acp_sdk.models import (
5
- AwaitRequest,
6
- AwaitResume,
7
- Message,
8
- MessagePart,
9
- )
10
- from acp_sdk.server import Context, Server
11
-
12
- server = Server()
13
-
14
-
15
- @server.agent()
16
- async def awaiting(
17
- inputs: list[Message], context: Context
18
- ) -> AsyncGenerator[Message | AwaitRequest | Any, AwaitResume]:
19
- """Greets and awaits for more data"""
20
- yield MessagePart(content="Hello!", content_type="text/plain")
21
- data = yield AwaitRequest()
22
- yield MessagePart(content=f"Thanks for {data}", content_type="text/plain")
23
-
24
-
25
- server.run()
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