acp-sdk 0.7.3__py3-none-any.whl → 0.8.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.
- acp_sdk/client/client.py +12 -2
- acp_sdk/models/models.py +11 -3
- acp_sdk/models/schemas.py +9 -1
- acp_sdk/server/app.py +10 -3
- acp_sdk/server/bundle.py +12 -3
- {acp_sdk-0.7.3.dist-info → acp_sdk-0.8.0.dist-info}/METADATA +1 -1
- {acp_sdk-0.7.3.dist-info → acp_sdk-0.8.0.dist-info}/RECORD +8 -8
- {acp_sdk-0.7.3.dist-info → acp_sdk-0.8.0.dist-info}/WHEEL +0 -0
acp_sdk/client/client.py
CHANGED
@@ -23,10 +23,12 @@ from acp_sdk.models import (
|
|
23
23
|
AwaitResume,
|
24
24
|
Error,
|
25
25
|
Event,
|
26
|
+
PingResponse,
|
26
27
|
Run,
|
27
28
|
RunCancelResponse,
|
28
29
|
RunCreateRequest,
|
29
30
|
RunCreateResponse,
|
31
|
+
RunEventsListResponse,
|
30
32
|
RunId,
|
31
33
|
RunMode,
|
32
34
|
RunResumeRequest,
|
@@ -120,9 +122,10 @@ class Client:
|
|
120
122
|
return Agent(**response.model_dump())
|
121
123
|
|
122
124
|
async def ping(self) -> bool:
|
123
|
-
response = await self._client.get("/
|
125
|
+
response = await self._client.get("/ping")
|
124
126
|
self._raise_error(response)
|
125
|
-
|
127
|
+
PingResponse.model_validate(response.json())
|
128
|
+
return
|
126
129
|
|
127
130
|
async def run_sync(self, input: Input, *, agent: AgentName) -> Run:
|
128
131
|
response = await self._client.post(
|
@@ -172,6 +175,13 @@ class Client:
|
|
172
175
|
self._raise_error(response)
|
173
176
|
return Run.model_validate(response.json())
|
174
177
|
|
178
|
+
async def run_events(self, *, run_id: RunId) -> AsyncIterator[Event]:
|
179
|
+
response = await self._client.get(f"/runs/{run_id}/events")
|
180
|
+
self._raise_error(response)
|
181
|
+
response = RunEventsListResponse.model_validate(response.json())
|
182
|
+
for event in response.events:
|
183
|
+
yield event
|
184
|
+
|
175
185
|
async def run_cancel(self, *, run_id: RunId) -> Run:
|
176
186
|
response = await self._client.post(f"/runs/{run_id}/cancel")
|
177
187
|
self._raise_error(response)
|
acp_sdk/models/models.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import uuid
|
2
|
-
from datetime import datetime
|
2
|
+
from datetime import datetime, timezone
|
3
3
|
from enum import Enum
|
4
4
|
from typing import Any, Literal, Optional, Union
|
5
5
|
|
@@ -95,11 +95,17 @@ class Artifact(MessagePart):
|
|
95
95
|
|
96
96
|
class Message(BaseModel):
|
97
97
|
parts: list[MessagePart]
|
98
|
+
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
99
|
+
completed_at: datetime | None = Field(default_factory=lambda: datetime.now(timezone.utc))
|
98
100
|
|
99
101
|
def __add__(self, other: "Message") -> "Message":
|
100
102
|
if not isinstance(other, Message):
|
101
103
|
raise TypeError(f"Cannot concatenate Message with {type(other).__name__}")
|
102
|
-
return Message(
|
104
|
+
return Message(
|
105
|
+
parts=self.parts + other.parts,
|
106
|
+
created_at=min(self.created_at, other.created_at),
|
107
|
+
completed_at=max(self.completed_at, other.completed_at),
|
108
|
+
)
|
103
109
|
|
104
110
|
def __str__(self) -> str:
|
105
111
|
return "".join(
|
@@ -134,7 +140,7 @@ class Message(BaseModel):
|
|
134
140
|
parts[-1] = join(parts[-1], part)
|
135
141
|
else:
|
136
142
|
parts.append(part)
|
137
|
-
return Message(parts=parts)
|
143
|
+
return Message(parts=parts, created_at=self.created_at, completed_at=self.completed_at)
|
138
144
|
|
139
145
|
|
140
146
|
AgentName = str
|
@@ -185,6 +191,8 @@ class Run(BaseModel):
|
|
185
191
|
await_request: AwaitRequest | None = None
|
186
192
|
output: list[Message] = []
|
187
193
|
error: Error | None = None
|
194
|
+
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
195
|
+
finished_at: datetime | None = None
|
188
196
|
|
189
197
|
|
190
198
|
class MessageCreatedEvent(BaseModel):
|
acp_sdk/models/schemas.py
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
from pydantic import BaseModel
|
2
2
|
|
3
|
-
from acp_sdk.models.models import Agent, AgentName, AwaitResume, Message, Run, RunMode, SessionId
|
3
|
+
from acp_sdk.models.models import Agent, AgentName, AwaitResume, Event, Message, Run, RunMode, SessionId
|
4
|
+
|
5
|
+
|
6
|
+
class PingResponse(BaseModel):
|
7
|
+
pass
|
4
8
|
|
5
9
|
|
6
10
|
class AgentsListResponse(BaseModel):
|
@@ -37,3 +41,7 @@ class RunReadResponse(Run):
|
|
37
41
|
|
38
42
|
class RunCancelResponse(Run):
|
39
43
|
pass
|
44
|
+
|
45
|
+
|
46
|
+
class RunEventsListResponse(BaseModel):
|
47
|
+
events: list[Event]
|
acp_sdk/server/app.py
CHANGED
@@ -21,6 +21,7 @@ from acp_sdk.models import (
|
|
21
21
|
RunCancelResponse,
|
22
22
|
RunCreateRequest,
|
23
23
|
RunCreateResponse,
|
24
|
+
RunEventsListResponse,
|
24
25
|
RunId,
|
25
26
|
RunMode,
|
26
27
|
RunReadResponse,
|
@@ -29,6 +30,7 @@ from acp_sdk.models import (
|
|
29
30
|
SessionId,
|
30
31
|
)
|
31
32
|
from acp_sdk.models.errors import ACPError
|
33
|
+
from acp_sdk.models.schemas import PingResponse
|
32
34
|
from acp_sdk.server.agent import Agent
|
33
35
|
from acp_sdk.server.bundle import RunBundle
|
34
36
|
from acp_sdk.server.errors import (
|
@@ -104,9 +106,9 @@ def create_app(
|
|
104
106
|
agent = find_agent(name)
|
105
107
|
return AgentModel(name=agent.name, description=agent.description, metadata=agent.metadata)
|
106
108
|
|
107
|
-
@app.get("/
|
108
|
-
async def
|
109
|
-
return
|
109
|
+
@app.get("/ping")
|
110
|
+
async def ping() -> PingResponse:
|
111
|
+
return PingResponse()
|
110
112
|
|
111
113
|
@app.post("/runs")
|
112
114
|
async def create_run(request: RunCreateRequest) -> RunCreateResponse:
|
@@ -155,6 +157,11 @@ def create_app(
|
|
155
157
|
bundle = find_run_bundle(run_id)
|
156
158
|
return bundle.run
|
157
159
|
|
160
|
+
@app.get("/runs/{run_id}/events")
|
161
|
+
async def list_run_events(run_id: RunId) -> RunEventsListResponse:
|
162
|
+
bundle = find_run_bundle(run_id)
|
163
|
+
return RunEventsListResponse(events=bundle.events)
|
164
|
+
|
158
165
|
@app.post("/runs/{run_id}")
|
159
166
|
async def resume_run(run_id: RunId, request: RunResumeRequest) -> RunResumeResponse:
|
160
167
|
bundle = find_run_bundle(run_id)
|
acp_sdk/server/bundle.py
CHANGED
@@ -2,6 +2,7 @@ import asyncio
|
|
2
2
|
import logging
|
3
3
|
from collections.abc import AsyncGenerator
|
4
4
|
from concurrent.futures import ThreadPoolExecutor
|
5
|
+
from datetime import datetime, timezone
|
5
6
|
|
6
7
|
from pydantic import BaseModel, ValidationError
|
7
8
|
|
@@ -43,6 +44,7 @@ class RunBundle:
|
|
43
44
|
self.history = history
|
44
45
|
|
45
46
|
self.stream_queue: asyncio.Queue[Event] = asyncio.Queue()
|
47
|
+
self.events: list[Event] = []
|
46
48
|
|
47
49
|
self.await_queue: asyncio.Queue[AwaitResume] = asyncio.Queue(maxsize=1)
|
48
50
|
self.await_or_terminate_event = asyncio.Event()
|
@@ -58,7 +60,9 @@ class RunBundle:
|
|
58
60
|
self.stream_queue.task_done()
|
59
61
|
|
60
62
|
async def emit(self, event: Event) -> None:
|
61
|
-
|
63
|
+
freeze = event.model_copy(deep=True)
|
64
|
+
self.events.append(freeze)
|
65
|
+
await self.stream_queue.put(freeze)
|
62
66
|
|
63
67
|
async def await_(self) -> AwaitResume:
|
64
68
|
await self.stream_queue.put(None)
|
@@ -92,7 +96,9 @@ class RunBundle:
|
|
92
96
|
async def flush_message() -> None:
|
93
97
|
nonlocal in_message
|
94
98
|
if in_message:
|
95
|
-
|
99
|
+
message = self.run.output[-1]
|
100
|
+
message.completed_at = datetime.now(timezone.utc)
|
101
|
+
await self.emit(MessageCompletedEvent(message=message))
|
96
102
|
in_message = False
|
97
103
|
|
98
104
|
try:
|
@@ -114,7 +120,7 @@ class RunBundle:
|
|
114
120
|
if isinstance(next, str):
|
115
121
|
next = MessagePart(content=next)
|
116
122
|
if not in_message:
|
117
|
-
self.run.output.append(Message(parts=[]))
|
123
|
+
self.run.output.append(Message(parts=[], completed_at=None))
|
118
124
|
in_message = True
|
119
125
|
await self.emit(MessageCreatedEvent(message=self.run.output[-1]))
|
120
126
|
self.run.output[-1].parts.append(next)
|
@@ -149,10 +155,12 @@ class RunBundle:
|
|
149
155
|
except StopAsyncIteration:
|
150
156
|
await flush_message()
|
151
157
|
self.run.status = RunStatus.COMPLETED
|
158
|
+
self.run.finished_at = datetime.now(timezone.utc)
|
152
159
|
await self.emit(RunCompletedEvent(run=self.run))
|
153
160
|
run_logger.info("Run completed")
|
154
161
|
except asyncio.CancelledError:
|
155
162
|
self.run.status = RunStatus.CANCELLED
|
163
|
+
self.run.finished_at = datetime.now(timezone.utc)
|
156
164
|
await self.emit(RunCancelledEvent(run=self.run))
|
157
165
|
run_logger.info("Run cancelled")
|
158
166
|
except Exception as e:
|
@@ -161,6 +169,7 @@ class RunBundle:
|
|
161
169
|
else:
|
162
170
|
self.run.error = Error(code=ErrorCode.SERVER_ERROR, message=str(e))
|
163
171
|
self.run.status = RunStatus.FAILED
|
172
|
+
self.run.finished_at = datetime.now(timezone.utc)
|
164
173
|
await self.emit(RunFailedEvent(run=self.run))
|
165
174
|
run_logger.exception("Run failed")
|
166
175
|
raise
|
@@ -3,17 +3,17 @@ acp_sdk/instrumentation.py,sha256=JqSyvILN3sGAfOZrmckQq4-M_4_5alyPn95DK0o5lfA,16
|
|
3
3
|
acp_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
acp_sdk/version.py,sha256=Niy83rgvigB4hL_rR-O4ySvI7dj6xnqkyOe_JTymi9s,73
|
5
5
|
acp_sdk/client/__init__.py,sha256=Bca1DORrswxzZsrR2aUFpATuNG2xNSmYvF1Z2WJaVbc,51
|
6
|
-
acp_sdk/client/client.py,sha256=
|
6
|
+
acp_sdk/client/client.py,sha256=GnkbhCoEghI9A0_Otmzb18V4ot1uNz0hEXNjIAPNHOE,8599
|
7
7
|
acp_sdk/client/types.py,sha256=_H6zYt-2OHOOYRtssRnbDIiwmgsl2-KIXc9lb-mJLFA,133
|
8
8
|
acp_sdk/client/utils.py,sha256=2jhJyrPJmVFRoDJh0q_JMqOMlC3IxCh-6HXed-PIZS8,924
|
9
9
|
acp_sdk/models/__init__.py,sha256=numSDBDT1QHx7n_Y3Deb5VOvKWcUBxbOEaMwQBSRHxc,151
|
10
10
|
acp_sdk/models/errors.py,sha256=rEyaMVvQuBi7fwWe_d0PGGySYsD3FZTluQ-SkC0yhAs,444
|
11
|
-
acp_sdk/models/models.py,sha256=
|
12
|
-
acp_sdk/models/schemas.py,sha256=
|
11
|
+
acp_sdk/models/models.py,sha256=6OEkTMdMsl3_IbiFmFG2ChEqY_KYTf3Bi_MW5p168GQ,7183
|
12
|
+
acp_sdk/models/schemas.py,sha256=_ah7_zHsQJGxDXvnzsBvASdRsQHVphFQ7Sum6A04iRw,759
|
13
13
|
acp_sdk/server/__init__.py,sha256=mxBBBFaZuMEUENRMLwp1XZkuLeT9QghcFmNvjnqvAAU,377
|
14
14
|
acp_sdk/server/agent.py,sha256=wvwpi83osmW7zQWxVnzyVMXIvzOswAfhKWHscVIldhA,6245
|
15
|
-
acp_sdk/server/app.py,sha256=
|
16
|
-
acp_sdk/server/bundle.py,sha256=
|
15
|
+
acp_sdk/server/app.py,sha256=1S1mxECioL5NeGjGo5C8u94x7Ybvj79L_Aauu2352vA,7117
|
16
|
+
acp_sdk/server/bundle.py,sha256=5Rq6E4WgmuwPQ4u-sViaHeu5loCLEUgojWav9LAghX4,7036
|
17
17
|
acp_sdk/server/context.py,sha256=MgnLV6qcDIhc_0BjW7r4Jj1tHts4ZuwpdTGIBnz2Mgo,1036
|
18
18
|
acp_sdk/server/errors.py,sha256=GSO8yYIqEeX8Y4Lz86ks35dMTHiQiXuOrLYYx0eXsbI,2110
|
19
19
|
acp_sdk/server/logging.py,sha256=Oc8yZigCsuDnHHPsarRzu0RX3NKaLEgpELM2yovGKDI,411
|
@@ -22,6 +22,6 @@ acp_sdk/server/session.py,sha256=ekz1o6Sy1tQZlpaoS_VgbvFuUQh2qpiHG71mvBdvhgc,662
|
|
22
22
|
acp_sdk/server/telemetry.py,sha256=1BUxNg-xL_Vqgs27PDWNc3HikrQW2lidAtT_FKlp_Qk,1833
|
23
23
|
acp_sdk/server/types.py,sha256=teBNRWSks8XP1SCQKGEtbNWQahVD3RAOPnysTxcQPxI,292
|
24
24
|
acp_sdk/server/utils.py,sha256=y-DDWv_QI25OJJYP5cni2FzfolKXtH3S2SYOm6OL_gc,1835
|
25
|
-
acp_sdk-0.
|
26
|
-
acp_sdk-0.
|
27
|
-
acp_sdk-0.
|
25
|
+
acp_sdk-0.8.0.dist-info/METADATA,sha256=Inaa0idYypuECgh9JWdUVxIwJDRhslH7-YwAW6lupMg,1651
|
26
|
+
acp_sdk-0.8.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
27
|
+
acp_sdk-0.8.0.dist-info/RECORD,,
|
File without changes
|