agentstack-sdk 0.5.2rc2__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 (76) hide show
  1. agentstack_sdk/__init__.py +6 -0
  2. agentstack_sdk/a2a/__init__.py +2 -0
  3. agentstack_sdk/a2a/extensions/__init__.py +8 -0
  4. agentstack_sdk/a2a/extensions/auth/__init__.py +5 -0
  5. agentstack_sdk/a2a/extensions/auth/oauth/__init__.py +4 -0
  6. agentstack_sdk/a2a/extensions/auth/oauth/oauth.py +151 -0
  7. agentstack_sdk/a2a/extensions/auth/oauth/storage/__init__.py +5 -0
  8. agentstack_sdk/a2a/extensions/auth/oauth/storage/base.py +11 -0
  9. agentstack_sdk/a2a/extensions/auth/oauth/storage/memory.py +38 -0
  10. agentstack_sdk/a2a/extensions/auth/secrets/__init__.py +4 -0
  11. agentstack_sdk/a2a/extensions/auth/secrets/secrets.py +77 -0
  12. agentstack_sdk/a2a/extensions/base.py +205 -0
  13. agentstack_sdk/a2a/extensions/common/__init__.py +4 -0
  14. agentstack_sdk/a2a/extensions/common/form.py +149 -0
  15. agentstack_sdk/a2a/extensions/exceptions.py +11 -0
  16. agentstack_sdk/a2a/extensions/interactions/__init__.py +4 -0
  17. agentstack_sdk/a2a/extensions/interactions/approval.py +125 -0
  18. agentstack_sdk/a2a/extensions/services/__init__.py +8 -0
  19. agentstack_sdk/a2a/extensions/services/embedding.py +106 -0
  20. agentstack_sdk/a2a/extensions/services/form.py +54 -0
  21. agentstack_sdk/a2a/extensions/services/llm.py +100 -0
  22. agentstack_sdk/a2a/extensions/services/mcp.py +193 -0
  23. agentstack_sdk/a2a/extensions/services/platform.py +141 -0
  24. agentstack_sdk/a2a/extensions/tools/__init__.py +5 -0
  25. agentstack_sdk/a2a/extensions/tools/call.py +114 -0
  26. agentstack_sdk/a2a/extensions/tools/exceptions.py +6 -0
  27. agentstack_sdk/a2a/extensions/ui/__init__.py +10 -0
  28. agentstack_sdk/a2a/extensions/ui/agent_detail.py +54 -0
  29. agentstack_sdk/a2a/extensions/ui/canvas.py +71 -0
  30. agentstack_sdk/a2a/extensions/ui/citation.py +78 -0
  31. agentstack_sdk/a2a/extensions/ui/error.py +223 -0
  32. agentstack_sdk/a2a/extensions/ui/form_request.py +52 -0
  33. agentstack_sdk/a2a/extensions/ui/settings.py +73 -0
  34. agentstack_sdk/a2a/extensions/ui/trajectory.py +70 -0
  35. agentstack_sdk/a2a/types.py +104 -0
  36. agentstack_sdk/platform/__init__.py +12 -0
  37. agentstack_sdk/platform/client.py +123 -0
  38. agentstack_sdk/platform/common.py +37 -0
  39. agentstack_sdk/platform/configuration.py +47 -0
  40. agentstack_sdk/platform/context.py +291 -0
  41. agentstack_sdk/platform/file.py +295 -0
  42. agentstack_sdk/platform/model_provider.py +131 -0
  43. agentstack_sdk/platform/provider.py +219 -0
  44. agentstack_sdk/platform/provider_build.py +190 -0
  45. agentstack_sdk/platform/types.py +45 -0
  46. agentstack_sdk/platform/user.py +70 -0
  47. agentstack_sdk/platform/user_feedback.py +42 -0
  48. agentstack_sdk/platform/variables.py +44 -0
  49. agentstack_sdk/platform/vector_store.py +217 -0
  50. agentstack_sdk/py.typed +0 -0
  51. agentstack_sdk/server/__init__.py +4 -0
  52. agentstack_sdk/server/agent.py +594 -0
  53. agentstack_sdk/server/app.py +87 -0
  54. agentstack_sdk/server/constants.py +9 -0
  55. agentstack_sdk/server/context.py +68 -0
  56. agentstack_sdk/server/dependencies.py +117 -0
  57. agentstack_sdk/server/exceptions.py +3 -0
  58. agentstack_sdk/server/middleware/__init__.py +3 -0
  59. agentstack_sdk/server/middleware/platform_auth_backend.py +131 -0
  60. agentstack_sdk/server/server.py +376 -0
  61. agentstack_sdk/server/store/__init__.py +3 -0
  62. agentstack_sdk/server/store/context_store.py +35 -0
  63. agentstack_sdk/server/store/memory_context_store.py +59 -0
  64. agentstack_sdk/server/store/platform_context_store.py +58 -0
  65. agentstack_sdk/server/telemetry.py +53 -0
  66. agentstack_sdk/server/utils.py +26 -0
  67. agentstack_sdk/types.py +15 -0
  68. agentstack_sdk/util/__init__.py +4 -0
  69. agentstack_sdk/util/file.py +260 -0
  70. agentstack_sdk/util/httpx.py +18 -0
  71. agentstack_sdk/util/logging.py +63 -0
  72. agentstack_sdk/util/resource_context.py +44 -0
  73. agentstack_sdk/util/utils.py +47 -0
  74. agentstack_sdk-0.5.2rc2.dist-info/METADATA +120 -0
  75. agentstack_sdk-0.5.2rc2.dist-info/RECORD +76 -0
  76. agentstack_sdk-0.5.2rc2.dist-info/WHEEL +4 -0
@@ -0,0 +1,42 @@
1
+ # Copyright 2025 © BeeAI a Series of LF Projects, LLC
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from datetime import datetime
5
+ from uuid import UUID
6
+
7
+ import pydantic
8
+
9
+ from agentstack_sdk.platform.client import PlatformClient, get_platform_client
10
+ from agentstack_sdk.platform.common import PaginatedResult
11
+ from agentstack_sdk.util.utils import filter_dict
12
+
13
+
14
+ class UserFeedback(pydantic.BaseModel):
15
+ id: UUID
16
+ provider_id: UUID
17
+ task_id: UUID
18
+ context_id: UUID
19
+ rating: int
20
+ message: str
21
+ comment: str | None = None
22
+ comment_tags: list[str] | None = None
23
+ created_at: datetime
24
+ agent_name: str
25
+
26
+ @staticmethod
27
+ async def list(
28
+ *,
29
+ provider_id: str | None = None,
30
+ limit: int = 50,
31
+ after_cursor: str | None = None,
32
+ client: PlatformClient | None = None,
33
+ ) -> "ListUserFeedbackResponse":
34
+ async with client or get_platform_client() as client:
35
+ params = filter_dict({"provider_id": provider_id, "limit": limit, "after_cursor": after_cursor})
36
+ return pydantic.TypeAdapter(ListUserFeedbackResponse).validate_python(
37
+ (await client.get(url="/api/v1/user_feedback", params=params)).raise_for_status().json()
38
+ )
39
+
40
+
41
+ class ListUserFeedbackResponse(PaginatedResult[UserFeedback]):
42
+ pass
@@ -0,0 +1,44 @@
1
+ # Copyright 2025 © BeeAI a Series of LF Projects, LLC
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from __future__ import annotations
5
+
6
+ from agentstack_sdk.platform.client import PlatformClient, get_platform_client
7
+
8
+
9
+ class Variables(dict[str, str]):
10
+ async def save(
11
+ self: Variables | dict[str, str | None] | dict[str, str],
12
+ *,
13
+ client: PlatformClient | None = None,
14
+ ) -> None:
15
+ """
16
+ Save variables to the Agent Stack platform. Does not delete keys unless explicitly set to None.
17
+
18
+ Can be used as a class method: Variables.save({"key": "value", ...})
19
+ ...or as an instance method: variables.save()
20
+ """
21
+ async with client or get_platform_client() as client:
22
+ _ = (
23
+ await client.put(
24
+ url="/api/v1/variables",
25
+ json={"variables": self},
26
+ )
27
+ ).raise_for_status()
28
+
29
+ async def load(self: Variables | None = None, *, client: PlatformClient | None = None) -> Variables:
30
+ """
31
+ Load variables from the Agent Stack platform.
32
+
33
+ Can be used as a class method: variables = Variables.load()
34
+ ...or as an instance method to update the instance: variables.load()
35
+ """
36
+ async with client or get_platform_client() as client:
37
+ new_variables: dict[str, str] = (
38
+ (await client.get(url="/api/v1/variables")).raise_for_status().json()["variables"]
39
+ )
40
+ if isinstance(self, Variables):
41
+ self.clear()
42
+ self.update(new_variables)
43
+ return self
44
+ return Variables(new_variables)
@@ -0,0 +1,217 @@
1
+ # Copyright 2025 © BeeAI a Series of LF Projects, LLC
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from __future__ import annotations
5
+
6
+ import typing
7
+ import uuid
8
+ from typing import Literal, Self
9
+
10
+ import pydantic
11
+
12
+ from agentstack_sdk.platform.client import PlatformClient, get_platform_client
13
+ from agentstack_sdk.platform.types import Metadata
14
+
15
+
16
+ class VectorStoreStats(pydantic.BaseModel):
17
+ usage_bytes: int
18
+ num_documents: int
19
+
20
+
21
+ class VectorStoreDocument(pydantic.BaseModel):
22
+ id: str
23
+ vector_store_id: str
24
+ file_id: str | None = None
25
+ usage_bytes: int | None = None
26
+ created_at: pydantic.AwareDatetime
27
+
28
+
29
+ class VectorStoreItem(pydantic.BaseModel):
30
+ id: str = pydantic.Field(default_factory=lambda: uuid.uuid4().hex)
31
+ document_id: str
32
+ document_type: typing.Literal["platform_file", "external"] | None = "platform_file"
33
+ model_id: str | typing.Literal["platform"] = "platform"
34
+ text: str
35
+ embedding: list[float]
36
+ metadata: Metadata | None = None
37
+
38
+ @pydantic.model_validator(mode="after")
39
+ def validate_document_id(self) -> Self:
40
+ """Validate that document_id is a valid UUID when document_type is platform_file."""
41
+ if self.document_type == "platform_file":
42
+ try:
43
+ _ = uuid.UUID(self.document_id)
44
+ except ValueError as ex:
45
+ raise ValueError(
46
+ f"document_id must be a valid UUID when document_type is platform_file, got: {self.document_id}"
47
+ ) from ex
48
+ return self
49
+
50
+
51
+ class VectorStoreSearchResult(pydantic.BaseModel):
52
+ item: VectorStoreItem
53
+ score: float
54
+
55
+
56
+ class VectorStore(pydantic.BaseModel):
57
+ id: str
58
+ name: str | None = None
59
+ model_id: str
60
+ dimension: int
61
+ created_at: pydantic.AwareDatetime
62
+ last_active_at: pydantic.AwareDatetime
63
+ created_by: str
64
+ stats: VectorStoreStats | None = None
65
+
66
+ @staticmethod
67
+ async def create(
68
+ *,
69
+ name: str,
70
+ dimension: int,
71
+ model_id: str,
72
+ client: PlatformClient | None = None,
73
+ context_id: str | None | Literal["auto"] = "auto",
74
+ ) -> VectorStore:
75
+ async with client or get_platform_client() as platform_client:
76
+ context_id = platform_client.context_id if context_id == "auto" else context_id
77
+ return pydantic.TypeAdapter(VectorStore).validate_json(
78
+ (
79
+ await platform_client.post(
80
+ url="/api/v1/vector_stores",
81
+ json={"name": name, "dimension": dimension, "model_id": model_id},
82
+ params=context_id and {"context_id": context_id},
83
+ )
84
+ )
85
+ .raise_for_status()
86
+ .content
87
+ )
88
+
89
+ async def get(
90
+ self: VectorStore | str,
91
+ /,
92
+ *,
93
+ client: PlatformClient | None = None,
94
+ context_id: str | None | Literal["auto"] = "auto",
95
+ ) -> VectorStore:
96
+ # `self` has a weird type so that you can call both `instance.get()` to update an instance, or `VectorStore.get("123")` to obtain a new instance
97
+ vector_store_id = self if isinstance(self, str) else self.id
98
+ async with client or get_platform_client() as platform_client:
99
+ context_id = platform_client.context_id if context_id == "auto" else context_id
100
+ result = pydantic.TypeAdapter(VectorStore).validate_json(
101
+ (
102
+ await platform_client.get(
103
+ url=f"/api/v1/vector_stores/{vector_store_id}",
104
+ params=context_id and {"context_id": context_id},
105
+ )
106
+ )
107
+ .raise_for_status()
108
+ .content
109
+ )
110
+ if isinstance(self, VectorStore):
111
+ self.__dict__.update(result.__dict__)
112
+ return self
113
+ return result
114
+
115
+ async def delete(
116
+ self: VectorStore | str,
117
+ /,
118
+ *,
119
+ client: PlatformClient | None = None,
120
+ context_id: str | None | Literal["auto"] = "auto",
121
+ ) -> None:
122
+ # `self` has a weird type so that you can call both `instance.delete()` or `VectorStore.delete("123")`
123
+ vector_store_id = self if isinstance(self, str) else self.id
124
+ async with client or get_platform_client() as platform_client:
125
+ context_id = platform_client.context_id if context_id == "auto" else context_id
126
+ _ = (
127
+ await platform_client.delete(
128
+ url=f"/api/v1/vector_stores/{vector_store_id}",
129
+ params=context_id and {"context_id": context_id},
130
+ )
131
+ ).raise_for_status()
132
+
133
+ async def add_documents(
134
+ self: VectorStore | str,
135
+ /,
136
+ items: list[VectorStoreItem],
137
+ *,
138
+ client: PlatformClient | None = None,
139
+ context_id: str | None | Literal["auto"] = "auto",
140
+ ) -> None:
141
+ # `self` has a weird type so that you can call both `instance.add_documents()` or `VectorStore.add_documents("123", items)`
142
+ vector_store_id = self if isinstance(self, str) else self.id
143
+ async with client or get_platform_client() as platform_client:
144
+ context_id = platform_client.context_id if context_id == "auto" else context_id
145
+ _ = (
146
+ await platform_client.put(
147
+ url=f"/api/v1/vector_stores/{vector_store_id}",
148
+ json=[item.model_dump(mode="json") for item in items],
149
+ params=context_id and {"context_id": context_id},
150
+ )
151
+ ).raise_for_status()
152
+
153
+ async def search(
154
+ self: VectorStore | str,
155
+ /,
156
+ query_vector: list[float],
157
+ *,
158
+ limit: int = 10,
159
+ client: PlatformClient | None = None,
160
+ context_id: str | None | Literal["auto"] = "auto",
161
+ ) -> list[VectorStoreSearchResult]:
162
+ # `self` has a weird type so that you can call both `instance.search()` to search within an instance, or `VectorStore.search("123", query_vector)`
163
+ vector_store_id = self if isinstance(self, str) else self.id
164
+ async with client or get_platform_client() as platform_client:
165
+ context_id = platform_client.context_id if context_id == "auto" else context_id
166
+ return pydantic.TypeAdapter(list[VectorStoreSearchResult]).validate_python(
167
+ (
168
+ await platform_client.post(
169
+ url=f"/api/v1/vector_stores/{vector_store_id}/search",
170
+ json={"query_vector": query_vector, "limit": limit},
171
+ params=context_id and {"context_id": context_id},
172
+ )
173
+ )
174
+ .raise_for_status()
175
+ .json()["items"]
176
+ )
177
+
178
+ async def list_documents(
179
+ self: VectorStore | str,
180
+ /,
181
+ *,
182
+ client: PlatformClient | None = None,
183
+ context_id: str | None | Literal["auto"] = "auto",
184
+ ) -> list[VectorStoreDocument]:
185
+ # `self` has a weird type so that you can call both `instance.list_documents()` to list documents in an instance, or `VectorStore.list_documents("123")`
186
+ vector_store_id = self if isinstance(self, str) else self.id
187
+ async with client or get_platform_client() as platform_client:
188
+ context_id = platform_client.context_id if context_id == "auto" else context_id
189
+ return pydantic.TypeAdapter(list[VectorStoreDocument]).validate_python(
190
+ (
191
+ await platform_client.get(
192
+ url=f"/api/v1/vector_stores/{vector_store_id}/documents",
193
+ params=context_id and {"context_id": context_id},
194
+ )
195
+ )
196
+ .raise_for_status()
197
+ .json()["items"]
198
+ )
199
+
200
+ async def delete_document(
201
+ self: VectorStore | str,
202
+ /,
203
+ document_id: str,
204
+ *,
205
+ client: PlatformClient | None = None,
206
+ context_id: str | None | Literal["auto"] = "auto",
207
+ ) -> None:
208
+ # `self` has a weird type so that you can call both `instance.delete_document()` or `VectorStore.delete_document("123", "456")`
209
+ vector_store_id = self if isinstance(self, str) else self.id
210
+ async with client or get_platform_client() as platform_client:
211
+ context_id = platform_client.context_id if context_id == "auto" else context_id
212
+ _ = (
213
+ await platform_client.delete(
214
+ url=f"/api/v1/vector_stores/{vector_store_id}/documents/{document_id}",
215
+ params=context_id and {"context_id": context_id},
216
+ )
217
+ ).raise_for_status()
File without changes
@@ -0,0 +1,4 @@
1
+ # Copyright 2025 © BeeAI a Series of LF Projects, LLC
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from agentstack_sdk.server.server import Server as Server