acp-sdk 0.2.3__py3-none-any.whl → 0.2.5__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 +21 -12
- acp_sdk/instrumentation.py +7 -0
- acp_sdk/server/bundle.py +3 -1
- acp_sdk/server/errors.py +3 -1
- acp_sdk/server/telemetry.py +0 -4
- {acp_sdk-0.2.3.dist-info → acp_sdk-0.2.5.dist-info}/METADATA +1 -1
- {acp_sdk-0.2.3.dist-info → acp_sdk-0.2.5.dist-info}/RECORD +8 -7
- {acp_sdk-0.2.3.dist-info → acp_sdk-0.2.5.dist-info}/WHEEL +0 -0
acp_sdk/client/client.py
CHANGED
@@ -9,6 +9,7 @@ from httpx_sse import EventSource, aconnect_sse
|
|
9
9
|
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
|
10
10
|
from pydantic import TypeAdapter
|
11
11
|
|
12
|
+
from acp_sdk.instrumentation import get_tracer
|
12
13
|
from acp_sdk.models import (
|
13
14
|
ACPError,
|
14
15
|
Agent,
|
@@ -37,17 +38,20 @@ class Client:
|
|
37
38
|
self,
|
38
39
|
*,
|
39
40
|
base_url: httpx.URL | str = "",
|
41
|
+
timeout: httpx.Timeout | None = None,
|
40
42
|
session_id: SessionId | None = None,
|
41
43
|
client: httpx.AsyncClient | None = None,
|
42
44
|
instrument: bool = True,
|
43
45
|
) -> None:
|
44
|
-
self.
|
45
|
-
self.
|
46
|
-
|
47
|
-
self._client = client or httpx.AsyncClient(base_url=self.base_url)
|
46
|
+
self._session_id = session_id
|
47
|
+
self._client = client or httpx.AsyncClient(base_url=base_url, timeout=timeout)
|
48
48
|
if instrument:
|
49
49
|
HTTPXClientInstrumentor.instrument_client(self._client)
|
50
50
|
|
51
|
+
@property
|
52
|
+
def client(self) -> httpx.AsyncClient:
|
53
|
+
return self._client
|
54
|
+
|
51
55
|
async def __aenter__(self) -> Self:
|
52
56
|
await self._client.__aenter__()
|
53
57
|
return self
|
@@ -62,7 +66,9 @@ class Client:
|
|
62
66
|
|
63
67
|
@asynccontextmanager
|
64
68
|
async def session(self, session_id: SessionId | None = None) -> AsyncGenerator[Self]:
|
65
|
-
|
69
|
+
session_id = session_id or uuid.uuid4()
|
70
|
+
with get_tracer().start_as_current_span("session", attributes={"acp.session": str(session_id)}):
|
71
|
+
yield Client(client=self._client, session_id=session_id, instrument=False)
|
66
72
|
|
67
73
|
async def agents(self) -> AsyncIterator[Agent]:
|
68
74
|
response = await self._client.get("/agents")
|
@@ -82,7 +88,7 @@ class Client:
|
|
82
88
|
agent_name=agent,
|
83
89
|
inputs=inputs,
|
84
90
|
mode=RunMode.SYNC,
|
85
|
-
session_id=self.
|
91
|
+
session_id=self._session_id,
|
86
92
|
).model_dump_json(),
|
87
93
|
)
|
88
94
|
self._raise_error(response)
|
@@ -97,7 +103,7 @@ class Client:
|
|
97
103
|
agent_name=agent,
|
98
104
|
inputs=inputs,
|
99
105
|
mode=RunMode.ASYNC,
|
100
|
-
session_id=self.
|
106
|
+
session_id=self._session_id,
|
101
107
|
).model_dump_json(),
|
102
108
|
)
|
103
109
|
self._raise_error(response)
|
@@ -114,7 +120,7 @@ class Client:
|
|
114
120
|
agent_name=agent,
|
115
121
|
inputs=inputs,
|
116
122
|
mode=RunMode.STREAM,
|
117
|
-
session_id=self.
|
123
|
+
session_id=self._session_id,
|
118
124
|
).model_dump_json(),
|
119
125
|
) as event_source:
|
120
126
|
async for event in self._validate_stream(event_source):
|
@@ -135,7 +141,7 @@ class Client:
|
|
135
141
|
async def run_resume_sync(self, *, run_id: RunId, await_resume: AwaitResume) -> Run:
|
136
142
|
response = await self._client.post(
|
137
143
|
f"/runs/{run_id}",
|
138
|
-
|
144
|
+
content=RunResumeRequest(await_resume=await_resume, mode=RunMode.SYNC).model_dump_json(),
|
139
145
|
)
|
140
146
|
self._raise_error(response)
|
141
147
|
return RunResumeResponse.model_validate(response.json())
|
@@ -143,7 +149,7 @@ class Client:
|
|
143
149
|
async def run_resume_async(self, *, run_id: RunId, await_resume: AwaitResume) -> Run:
|
144
150
|
response = await self._client.post(
|
145
151
|
f"/runs/{run_id}",
|
146
|
-
|
152
|
+
content=RunResumeRequest(await_resume=await_resume, mode=RunMode.ASYNC).model_dump_json(),
|
147
153
|
)
|
148
154
|
self._raise_error(response)
|
149
155
|
return RunResumeResponse.model_validate(response.json())
|
@@ -153,7 +159,7 @@ class Client:
|
|
153
159
|
self._client,
|
154
160
|
"POST",
|
155
161
|
f"/runs/{run_id}",
|
156
|
-
|
162
|
+
content=RunResumeRequest(await_resume=await_resume, mode=RunMode.STREAM).model_dump_json(),
|
157
163
|
) as event_source:
|
158
164
|
async for event in self._validate_stream(event_source):
|
159
165
|
yield event
|
@@ -162,6 +168,9 @@ class Client:
|
|
162
168
|
self,
|
163
169
|
event_source: EventSource,
|
164
170
|
) -> AsyncIterator[Event]:
|
171
|
+
if event_source.response.is_error:
|
172
|
+
await event_source.response.aread()
|
173
|
+
self._raise_error(event_source.response)
|
165
174
|
async for event in event_source.aiter_sse():
|
166
175
|
event = TypeAdapter(Event).validate_json(event.data)
|
167
176
|
yield event
|
@@ -173,4 +182,4 @@ class Client:
|
|
173
182
|
raise ACPError(Error.model_validate(response.json()))
|
174
183
|
|
175
184
|
def _set_session(self, run: Run) -> None:
|
176
|
-
self.
|
185
|
+
self._session_id = run.session_id
|
acp_sdk/server/bundle.py
CHANGED
@@ -5,6 +5,7 @@ from concurrent.futures import ThreadPoolExecutor
|
|
5
5
|
|
6
6
|
from pydantic import ValidationError
|
7
7
|
|
8
|
+
from acp_sdk.instrumentation import get_tracer
|
8
9
|
from acp_sdk.models import (
|
9
10
|
ACPError,
|
10
11
|
AnyModel,
|
@@ -30,7 +31,6 @@ from acp_sdk.models import (
|
|
30
31
|
)
|
31
32
|
from acp_sdk.server.agent import Agent
|
32
33
|
from acp_sdk.server.logging import logger
|
33
|
-
from acp_sdk.server.telemetry import get_tracer
|
34
34
|
|
35
35
|
|
36
36
|
class RunBundle:
|
@@ -127,6 +127,8 @@ class RunBundle:
|
|
127
127
|
await_resume = await self.await_()
|
128
128
|
await self.emit(RunInProgressEvent(run=self.run))
|
129
129
|
run_logger.info("Run resumed")
|
130
|
+
elif isinstance(next, Error):
|
131
|
+
raise ACPError(error=next)
|
130
132
|
else:
|
131
133
|
try:
|
132
134
|
generic = AnyModel.model_validate(next)
|
acp_sdk/server/errors.py
CHANGED
@@ -32,7 +32,9 @@ def status_code_to_error_code(status_code: int) -> ErrorCode:
|
|
32
32
|
|
33
33
|
async def acp_error_handler(request: Request, exc: ACPError, *, status_code: int | None = None) -> JSONResponse:
|
34
34
|
error = exc.error
|
35
|
-
return JSONResponse(
|
35
|
+
return JSONResponse(
|
36
|
+
status_code=status_code or error_code_to_status_code(error.code), content=error.model_dump_json()
|
37
|
+
)
|
36
38
|
|
37
39
|
|
38
40
|
async def http_exception_handler(request: Request, exc: StarletteHTTPException) -> JSONResponse:
|
acp_sdk/server/telemetry.py
CHANGED
@@ -51,7 +51,3 @@ def configure_telemetry() -> None:
|
|
51
51
|
processor = BatchLogRecordProcessor(OTLPLogExporter())
|
52
52
|
logger_provider.add_log_record_processor(processor)
|
53
53
|
root_logger.addHandler(LoggingHandler(logger_provider=logger_provider))
|
54
|
-
|
55
|
-
|
56
|
-
def get_tracer() -> trace.Tracer:
|
57
|
-
return trace.get_tracer("acp-sdk", __version__)
|
@@ -1,8 +1,9 @@
|
|
1
1
|
acp_sdk/__init__.py,sha256=tXdAUM9zcmdSKCAkVrOCrGcXcuVS-yuvQUoQwTe9pek,98
|
2
|
+
acp_sdk/instrumentation.py,sha256=JqSyvILN3sGAfOZrmckQq4-M_4_5alyPn95DK0o5lfA,161
|
2
3
|
acp_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
4
|
acp_sdk/version.py,sha256=Niy83rgvigB4hL_rR-O4ySvI7dj6xnqkyOe_JTymi9s,73
|
4
5
|
acp_sdk/client/__init__.py,sha256=Bca1DORrswxzZsrR2aUFpATuNG2xNSmYvF1Z2WJaVbc,51
|
5
|
-
acp_sdk/client/client.py,sha256=
|
6
|
+
acp_sdk/client/client.py,sha256=lEUs0Oc7MZbKkTF2E6e8Wn3dTW5cMVj6fD8TbuEOMDk,6584
|
6
7
|
acp_sdk/models/__init__.py,sha256=numSDBDT1QHx7n_Y3Deb5VOvKWcUBxbOEaMwQBSRHxc,151
|
7
8
|
acp_sdk/models/errors.py,sha256=rEyaMVvQuBi7fwWe_d0PGGySYsD3FZTluQ-SkC0yhAs,444
|
8
9
|
acp_sdk/models/models.py,sha256=Z8qgURpz18uPXpYDYmlbMQ3Du9-hrJUE3GVPf7ufdUY,3994
|
@@ -10,15 +11,15 @@ acp_sdk/models/schemas.py,sha256=Kj7drJSR8d-N3KHzu_qTnLdagrMtAyhid5swluuhHTw,645
|
|
10
11
|
acp_sdk/server/__init__.py,sha256=mxBBBFaZuMEUENRMLwp1XZkuLeT9QghcFmNvjnqvAAU,377
|
11
12
|
acp_sdk/server/agent.py,sha256=fGky5MIuknw-Gy-THqhWLt9I9-gUyNIar8qEAvZb3uQ,6195
|
12
13
|
acp_sdk/server/app.py,sha256=qLeQ1STgX8_7cRtG-7Be6V5vS9ooBq6O89cQryqBdII,5903
|
13
|
-
acp_sdk/server/bundle.py,sha256=
|
14
|
+
acp_sdk/server/bundle.py,sha256=VchPUW8URH83-qJo9kRQsYCBcuLKbxGXHB3sw9CK0cc,6178
|
14
15
|
acp_sdk/server/context.py,sha256=MgnLV6qcDIhc_0BjW7r4Jj1tHts4ZuwpdTGIBnz2Mgo,1036
|
15
|
-
acp_sdk/server/errors.py,sha256=
|
16
|
+
acp_sdk/server/errors.py,sha256=IGtpPpb2ChtYvCac8kf_P-RkcY71gBvX0yq97uZWa-w,2104
|
16
17
|
acp_sdk/server/logging.py,sha256=Oc8yZigCsuDnHHPsarRzu0RX3NKaLEgpELM2yovGKDI,411
|
17
18
|
acp_sdk/server/server.py,sha256=-eT3fmnEsBUN44Spi2EP2eV0l4RAlKa8bzqxnhz16SM,5399
|
18
19
|
acp_sdk/server/session.py,sha256=0cDr924HC5x2bBNbK9NSKVHAt5A_mi5dK8P4jP_ugq0,629
|
19
|
-
acp_sdk/server/telemetry.py,sha256=
|
20
|
+
acp_sdk/server/telemetry.py,sha256=1BUxNg-xL_Vqgs27PDWNc3HikrQW2lidAtT_FKlp_Qk,1833
|
20
21
|
acp_sdk/server/types.py,sha256=1bqMCjwZM3JzvJ1h4aBHWzjbldMQ45HqcezBD6hUoYo,175
|
21
22
|
acp_sdk/server/utils.py,sha256=EfrF9VCyVk3AM_ao-BIB9EzGbfTrh4V2Bz-VFr6f6Sg,351
|
22
|
-
acp_sdk-0.2.
|
23
|
-
acp_sdk-0.2.
|
24
|
-
acp_sdk-0.2.
|
23
|
+
acp_sdk-0.2.5.dist-info/METADATA,sha256=ovtFlDH-TAiF1iW3-elh0-69d9A5h-Poaw1yheSrFvM,3463
|
24
|
+
acp_sdk-0.2.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
25
|
+
acp_sdk-0.2.5.dist-info/RECORD,,
|
File without changes
|