acp-sdk 0.11.0__py3-none-any.whl → 0.12.1__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/models/models.py CHANGED
@@ -8,7 +8,8 @@ from typing import Any, Literal, Optional, Union
8
8
  from pydantic import AnyUrl, BaseModel, ConfigDict, Field
9
9
 
10
10
  from acp_sdk.models.errors import ACPError, Error
11
- from acp_sdk.models.types import AgentName, ResourceId, ResourceUrl, RunId, SessionId
11
+ from acp_sdk.models.platform import PlatformUIAnnotation
12
+ from acp_sdk.models.types import AgentName, ResourceUrl, RunId, SessionId
12
13
  from acp_sdk.shared import ResourceLoader, ResourceStore
13
14
 
14
15
 
@@ -56,8 +57,13 @@ class Capability(BaseModel):
56
57
  description: str
57
58
 
58
59
 
60
+ class Annotations(BaseModel):
61
+ beeai_ui: PlatformUIAnnotation | None = None
62
+ model_config = ConfigDict(extra="allow")
63
+
64
+
59
65
  class Metadata(BaseModel):
60
- annotations: AnyModel | None = None
66
+ annotations: Annotations | None = None
61
67
  documentation: str | None = None
62
68
  license: str | None = None
63
69
  programming_language: str | None = None
@@ -351,6 +357,6 @@ class Session(BaseModel):
351
357
  if not store:
352
358
  raise ValueError("Store must be specified")
353
359
 
354
- id = ResourceId()
360
+ id = uuid.uuid4()
355
361
  await store.store(id, data)
356
362
  return await store.url(id)
@@ -0,0 +1,22 @@
1
+ from enum import Enum
2
+
3
+ from pydantic import BaseModel, ConfigDict
4
+
5
+
6
+ class PlatformUIType(str, Enum):
7
+ CHAT = "chat"
8
+ HANDSOFF = "hands-off"
9
+
10
+
11
+ class AgentToolInfo(BaseModel):
12
+ name: str
13
+ description: str | None = None
14
+ model_config = ConfigDict(extra="allow")
15
+
16
+
17
+ class PlatformUIAnnotation(BaseModel):
18
+ ui_type: PlatformUIType
19
+ user_greeting: str | None = None
20
+ display_name: str | None = None
21
+ tools: list[AgentToolInfo] = []
22
+ model_config = ConfigDict(extra="allow")
acp_sdk/server/app.py CHANGED
@@ -51,6 +51,7 @@ from acp_sdk.server.errors import (
51
51
  validation_exception_handler,
52
52
  )
53
53
  from acp_sdk.server.executor import CancelData, Executor, RunData
54
+ from acp_sdk.server.resources import ServerResourceLoader
54
55
  from acp_sdk.server.store import MemoryStore, Store
55
56
  from acp_sdk.server.utils import stream_sse, wait_util_stop
56
57
  from acp_sdk.shared import ResourceLoader, ResourceStore
@@ -161,14 +162,30 @@ def create_app(
161
162
  if request.session_id and request.session and request.session_id != request.session.id:
162
163
  raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Session ID mismatch")
163
164
 
165
+ def create_resource_url_forwarded(id: ResourceId) -> ResourceUrl:
166
+ if not forward_resources:
167
+ raise RuntimeError("Resource forwarding disabled")
168
+ return ResourceUrl(url=str(req.url_for("get_resource", resource_id=id)))
169
+
170
+ async def create_resource_url(id: ResourceId) -> ResourceUrl:
171
+ if forward_resources:
172
+ return create_resource_url_forwarded(id)
173
+ else:
174
+ return await resource_store.url(id)
175
+
176
+ server_resource_loader = ServerResourceLoader(
177
+ loader=resource_loader,
178
+ store=resource_store,
179
+ create_resource_url=create_resource_url_forwarded if forward_resources else None,
180
+ )
181
+
164
182
  session = request.session or (
165
- (
166
- await session_store.get(request.session_id)
167
- or Session(id=request.session_id, loader=resource_loader, store=resource_store)
168
- )
183
+ (await session_store.get(request.session_id) or Session(id=request.session_id))
169
184
  if request.session_id
170
- else Session(loader=resource_loader, store=resource_store)
185
+ else Session()
171
186
  )
187
+ session.loader = server_resource_loader
188
+ session.store = resource_store
172
189
 
173
190
  nonlocal executor
174
191
  run_data = RunData(
@@ -183,12 +200,6 @@ def create_app(
183
200
  headers = {Headers.RUN_ID: str(run_data.run.run_id)}
184
201
  ready = asyncio.Event()
185
202
 
186
- async def create_resource_url(id: ResourceId) -> ResourceUrl:
187
- if forward_resources:
188
- return ResourceUrl(url=str(req.url_for("get_resource", resource_id=id)))
189
- else:
190
- return await resource_store.url(id)
191
-
192
203
  Executor(
193
204
  agent=agent,
194
205
  run_data=run_data,
@@ -200,7 +211,7 @@ def create_app(
200
211
  executor=executor,
201
212
  request=req,
202
213
  resource_store=resource_store,
203
- resource_loader=resource_loader,
214
+ resource_loader=server_resource_loader,
204
215
  create_resource_url=create_resource_url,
205
216
  ).execute(request.input, wait=ready)
206
217
 
@@ -0,0 +1,38 @@
1
+ import re
2
+ import uuid
3
+ from typing import Callable
4
+
5
+ import cachetools
6
+
7
+ from acp_sdk.models import ResourceUrl
8
+ from acp_sdk.models.types import ResourceId
9
+ from acp_sdk.shared.resources import ResourceLoader, ResourceStore
10
+
11
+
12
+ class ServerResourceLoader(ResourceLoader):
13
+ def __init__(
14
+ self,
15
+ *,
16
+ loader: ResourceLoader,
17
+ store: ResourceStore,
18
+ create_resource_url: Callable[[ResourceId], ResourceUrl] | None,
19
+ ) -> None:
20
+ self._loader = loader
21
+ self._store = store
22
+
23
+ placeholder_id = uuid.uuid4()
24
+ self._url_pattern = (
25
+ re.escape(str(create_resource_url(placeholder_id))).replace(re.escape(str(placeholder_id)), r"([^/?&#]+)")
26
+ if create_resource_url
27
+ else None
28
+ )
29
+
30
+ @cachetools.func.lfu_cache
31
+ async def load(self, url: ResourceUrl) -> bytes:
32
+ if self._url_pattern:
33
+ match = re.match(self._url_pattern, str(url))
34
+ if match:
35
+ id = ResourceId(match.group(1))
36
+ result = await self._store.load(id)
37
+ return (await result.bytes_async()).to_bytes()
38
+ return await self._loader.load(url)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: acp-sdk
3
- Version: 0.11.0
3
+ Version: 0.12.1
4
4
  Summary: Agent Communication Protocol SDK
5
5
  Author: IBM Corp.
6
6
  Maintainer-email: Tomas Pilar <thomas7pilar@gmail.com>
@@ -8,16 +8,18 @@ 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=_XDSvUwlHeRsqUayAxHusJ5s8Z1jWXV1ZcUKlJakOt4,200
10
10
  acp_sdk/models/errors.py,sha256=rEyaMVvQuBi7fwWe_d0PGGySYsD3FZTluQ-SkC0yhAs,444
11
- acp_sdk/models/models.py,sha256=0ODyzANVo4t1TOsTZPE-eKyxw9pLDCkMHzqGoTa49LQ,10635
11
+ acp_sdk/models/models.py,sha256=-ORIe32MOWVVh22njH596lKeQQQCRsXzKLvOk1dQJB8,10809
12
+ acp_sdk/models/platform.py,sha256=qgQhBZZNPG9XLlytEZmuv1LTkejbklmlj7YpnpUV_DE,497
12
13
  acp_sdk/models/schemas.py,sha256=Vu3aO-6M0IW71I9thxAiphLGXXMvyZXFMJCdj7euUmc,915
13
14
  acp_sdk/models/types.py,sha256=tH79qqpW3DrPJggZD1KFlLtGE_ZKT6eLtwiR3p3x2QM,145
14
15
  acp_sdk/server/__init__.py,sha256=TfTOOI7G2nejjOB6RZB5ujynyh3bFeH51pfDIMzv3N4,627
15
16
  acp_sdk/server/agent.py,sha256=tzdk9bXb4aKBKD3F1-QfI7zrjMZYEg6qm3gGRWJGC1E,3739
16
- acp_sdk/server/app.py,sha256=KKjZcVxJxQvxAEP_cQna4f9ed1O5mN9Ldo1X_tXfFfI,11107
17
+ acp_sdk/server/app.py,sha256=dugceYPELl6N1_OQQ6JP5VCfVSm0rcanFtjDpscOy6o,11586
17
18
  acp_sdk/server/context.py,sha256=Xz1am_HLNTgEvG0IPtS0tRJcPk-rEhLtNyTQGUAvLQw,1271
18
19
  acp_sdk/server/errors.py,sha256=GSO8yYIqEeX8Y4Lz86ks35dMTHiQiXuOrLYYx0eXsbI,2110
19
20
  acp_sdk/server/executor.py,sha256=ktM1FCwixtbjsU60VM7PHxwF_Saz15M_9fNXN4mItrU,12607
20
21
  acp_sdk/server/logging.py,sha256=Oc8yZigCsuDnHHPsarRzu0RX3NKaLEgpELM2yovGKDI,411
22
+ acp_sdk/server/resources.py,sha256=g9C2Xr_SyvAFsV1uHQLEe1H7CgLIjfQZ51Nj3n-w0f4,1174
21
23
  acp_sdk/server/server.py,sha256=HJOub1ynHiJTQrfKq_bq0r9aqgL1kQeboZH_ArZcuh0,14651
22
24
  acp_sdk/server/telemetry.py,sha256=lbB2ppijUcqbHUOn0e-15LGcVvT_qrMguq8qBokICac,2016
23
25
  acp_sdk/server/types.py,sha256=gLb5wCkMYhmu2laj_ymK-TPfN9LSjRgKOP1H_893UzA,304
@@ -30,6 +32,6 @@ acp_sdk/server/store/store.py,sha256=jGmYy9oiuVjhYYJY8QRo4g2J2Qyt1HLTmq_eHy4aI7c
30
32
  acp_sdk/server/store/utils.py,sha256=JumEOMs1h1uGlnHnUGeguee-srGzT7_Y2NVEYt01QuY,92
31
33
  acp_sdk/shared/__init__.py,sha256=vZuhdQ6lrWVdyYPmIyXpPvs5eMnzemhNek3gfYPA3Bc,138
32
34
  acp_sdk/shared/resources.py,sha256=3oPvevYv2B1YaHyoMH85B7fcHVyhgZDUaDCBVEflTlA,1592
33
- acp_sdk-0.11.0.dist-info/METADATA,sha256=cVzemGKHjihYYsjeO30x9ff08TvrsJjVSTb6ug3k9N8,1713
34
- acp_sdk-0.11.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
35
- acp_sdk-0.11.0.dist-info/RECORD,,
35
+ acp_sdk-0.12.1.dist-info/METADATA,sha256=MRAqSfZU7kiGP1mmHqXMcPVxfDVhsQBUbPJVOhaIxYw,1713
36
+ acp_sdk-0.12.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
37
+ acp_sdk-0.12.1.dist-info/RECORD,,