databricks-agentbricks 0.2.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.
- databricks_agentbricks/__init__.py +1 -0
- databricks_agentbricks/_group.py +217 -0
- databricks_agentbricks/agent_project.py +657 -0
- databricks_agentbricks/app_resources.py +139 -0
- databricks_agentbricks/cli/__init__.py +12 -0
- databricks_agentbricks/cli/app.py +108 -0
- databricks_agentbricks/cli/app_auth.py +198 -0
- databricks_agentbricks/cli/auth.py +142 -0
- databricks_agentbricks/cli/deploy.py +954 -0
- databricks_agentbricks/cli/dev.py +310 -0
- databricks_agentbricks/cli/endpoint.py +145 -0
- databricks_agentbricks/cli/endpoint_examples.py +33 -0
- databricks_agentbricks/cli/endpoint_output.py +53 -0
- databricks_agentbricks/cli/endpoint_request.py +71 -0
- databricks_agentbricks/cli/endpoint_transport.py +148 -0
- databricks_agentbricks/cli/help.py +467 -0
- databricks_agentbricks/cli/init.py +496 -0
- databricks_agentbricks/cli/mcp.py +75 -0
- databricks_agentbricks/cli/memory.py +520 -0
- databricks_agentbricks/cli/sandbox.py +823 -0
- databricks_agentbricks/cli/sessions.py +588 -0
- databricks_agentbricks/cli/tools.py +456 -0
- databricks_agentbricks/cli/tracing.py +724 -0
- databricks_agentbricks/databricks_cli.py +38 -0
- databricks_agentbricks/errors.py +114 -0
- databricks_agentbricks/lakebase_runtime_store.py +107 -0
- databricks_agentbricks/legacy_lakebase_runtime_store.py +74 -0
- databricks_agentbricks/project_config.py +157 -0
- databricks_agentbricks/project_types.py +55 -0
- databricks_agentbricks/py.typed +0 -0
- databricks_agentbricks/render.py +349 -0
- databricks_agentbricks/templates/agent-bricks-migrate/SKILL.md +101 -0
- databricks_agentbricks/templates/agent-langgraph/.env.example +36 -0
- databricks_agentbricks/templates/agent-langgraph/.gitignore +199 -0
- databricks_agentbricks/templates/agent-langgraph/AGENTKIT_CONTRACT.md +95 -0
- databricks_agentbricks/templates/agent-langgraph/AGENTS.md +31 -0
- databricks_agentbricks/templates/agent-langgraph/CLAUDE.md +1 -0
- databricks_agentbricks/templates/agent-langgraph/README.md +141 -0
- databricks_agentbricks/templates/agent-langgraph/agent/__init__.py +0 -0
- databricks_agentbricks/templates/agent-langgraph/agent/agent.py +177 -0
- databricks_agentbricks/templates/agent-langgraph/agent/mcps.py +27 -0
- databricks_agentbricks/templates/agent-langgraph/agent/tools/__init__.py +24 -0
- databricks_agentbricks/templates/agent-langgraph/agent/tools/sample_tool.py +15 -0
- databricks_agentbricks/templates/agent-langgraph/agent/tools/send_message.py +17 -0
- databricks_agentbricks/templates/agent-langgraph/app.yaml +15 -0
- databricks_agentbricks/templates/agent-langgraph/pyproject.toml +42 -0
- databricks_agentbricks/templates/agent-langgraph/runtime/__init__.py +0 -0
- databricks_agentbricks/templates/agent-langgraph/runtime/adapter.py +144 -0
- databricks_agentbricks/templates/agent-langgraph/runtime/main.py +25 -0
- databricks_agentbricks/templates/agent-langgraph/tests/__init__.py +0 -0
- databricks_agentbricks/templates/agent-langgraph/tests/test_agent.py +211 -0
- databricks_agentbricks/templates/agent-langgraph/tests/test_runtime.py +19 -0
- databricks_agentbricks/templates/agent-langgraph/tests/test_workspace.py +28 -0
- databricks_agentbricks/templates/agent-openai/.env.example +37 -0
- databricks_agentbricks/templates/agent-openai/.gitignore +199 -0
- databricks_agentbricks/templates/agent-openai/AGENTKIT_CONTRACT.md +107 -0
- databricks_agentbricks/templates/agent-openai/AGENTS.md +76 -0
- databricks_agentbricks/templates/agent-openai/CLAUDE.md +1 -0
- databricks_agentbricks/templates/agent-openai/README.md +143 -0
- databricks_agentbricks/templates/agent-openai/agent/__init__.py +0 -0
- databricks_agentbricks/templates/agent-openai/agent/agent.py +205 -0
- databricks_agentbricks/templates/agent-openai/agent/mcps.py +28 -0
- databricks_agentbricks/templates/agent-openai/agent/tools/__init__.py +24 -0
- databricks_agentbricks/templates/agent-openai/agent/tools/sample_tool.py +15 -0
- databricks_agentbricks/templates/agent-openai/agent/tools/send_message.py +18 -0
- databricks_agentbricks/templates/agent-openai/app.yaml +15 -0
- databricks_agentbricks/templates/agent-openai/pyproject.toml +42 -0
- databricks_agentbricks/templates/agent-openai/runtime/__init__.py +0 -0
- databricks_agentbricks/templates/agent-openai/runtime/adapter.py +188 -0
- databricks_agentbricks/templates/agent-openai/runtime/main.py +25 -0
- databricks_agentbricks/templates/agent-openai/tests/__init__.py +0 -0
- databricks_agentbricks/templates/agent-openai/tests/test_agent.py +326 -0
- databricks_agentbricks/templates/agent-openai/tests/test_runtime.py +19 -0
- databricks_agentbricks/templates/agent-openai/tests/test_workspace.py +28 -0
- databricks_agentbricks/templates/custom-agent-langgraph/.env.example +1 -0
- databricks_agentbricks/templates/custom-agent-langgraph/.gitignore +11 -0
- databricks_agentbricks/templates/custom-agent-langgraph/README.md +22 -0
- databricks_agentbricks/templates/custom-agent-langgraph/agent/__init__.py +0 -0
- databricks_agentbricks/templates/custom-agent-langgraph/agent/agent.py +27 -0
- databricks_agentbricks/templates/custom-agent-langgraph/app.yaml +1 -0
- databricks_agentbricks/templates/custom-agent-langgraph/pyproject.toml +38 -0
- databricks_agentbricks/templates/custom-agent-langgraph/runtime/__init__.py +0 -0
- databricks_agentbricks/templates/custom-agent-langgraph/runtime/main.py +31 -0
- databricks_agentbricks/templates/custom-agent-langgraph/tests/test_runtime.py +29 -0
- databricks_agentbricks/templates/custom-agent-openai/.env.example +1 -0
- databricks_agentbricks/templates/custom-agent-openai/.gitignore +11 -0
- databricks_agentbricks/templates/custom-agent-openai/README.md +22 -0
- databricks_agentbricks/templates/custom-agent-openai/agent/__init__.py +0 -0
- databricks_agentbricks/templates/custom-agent-openai/agent/agent.py +29 -0
- databricks_agentbricks/templates/custom-agent-openai/app.yaml +1 -0
- databricks_agentbricks/templates/custom-agent-openai/pyproject.toml +38 -0
- databricks_agentbricks/templates/custom-agent-openai/runtime/__init__.py +0 -0
- databricks_agentbricks/templates/custom-agent-openai/runtime/main.py +31 -0
- databricks_agentbricks/templates/custom-agent-openai/tests/test_runtime.py +29 -0
- databricks_agentbricks/templates/sandbox_mcp.py +39 -0
- databricks_agentbricks/templates/sandbox_mcp_langgraph.py +39 -0
- databricks_agentbricks/templates/ui/agent-langgraph/CHAT_APP.md +49 -0
- databricks_agentbricks/templates/ui/agent-langgraph/runtime/main.py +26 -0
- databricks_agentbricks/templates/ui/agent-langgraph/runtime/ui.py +528 -0
- databricks_agentbricks/templates/ui/agent-langgraph/tests/test_demo_ui.py +542 -0
- databricks_agentbricks/templates/ui/agent-langgraph/ui/agentbricks-mark.png +0 -0
- databricks_agentbricks/templates/ui/agent-langgraph/ui/app.js +1464 -0
- databricks_agentbricks/templates/ui/agent-langgraph/ui/index.html +281 -0
- databricks_agentbricks/templates/ui/agent-langgraph/ui/styles.css +1913 -0
- databricks_agentbricks/templates/ui/agent-openai/CHAT_APP.md +54 -0
- databricks_agentbricks/templates/ui/agent-openai/runtime/main.py +26 -0
- databricks_agentbricks/templates/ui/agent-openai/runtime/ui.py +521 -0
- databricks_agentbricks/templates/ui/agent-openai/tests/test_demo_ui.py +512 -0
- databricks_agentbricks/templates/ui/agent-openai/ui/agentbricks-mark.png +0 -0
- databricks_agentbricks/templates/ui/agent-openai/ui/app.js +1428 -0
- databricks_agentbricks/templates/ui/agent-openai/ui/index.html +281 -0
- databricks_agentbricks/templates/ui/agent-openai/ui/styles.css +1913 -0
- databricks_agentbricks/theme.py +72 -0
- databricks_agentbricks-0.2.0.dist-info/METADATA +897 -0
- databricks_agentbricks-0.2.0.dist-info/RECORD +159 -0
- databricks_agentbricks-0.2.0.dist-info/WHEEL +4 -0
- databricks_agentbricks-0.2.0.dist-info/entry_points.txt +2 -0
- databricks_agentbricks-0.2.0.dist-info/licenses/NOTICE +39 -0
- databricks_agentkit/__init__.py +67 -0
- databricks_agentkit/_api_client.py +673 -0
- databricks_agentkit/_pagination.py +25 -0
- databricks_agentkit/client.py +31 -0
- databricks_agentkit/langgraph/__init__.py +98 -0
- databricks_agentkit/langgraph/genie.py +50 -0
- databricks_agentkit/langgraph/mcp.py +216 -0
- databricks_agentkit/langgraph/memory.py +67 -0
- databricks_agentkit/langgraph/session_store.py +485 -0
- databricks_agentkit/memory_store.py +371 -0
- databricks_agentkit/models.py +330 -0
- databricks_agentkit/openai/__init__.py +93 -0
- databricks_agentkit/openai/genie.py +50 -0
- databricks_agentkit/openai/mcp.py +189 -0
- databricks_agentkit/openai/memory.py +67 -0
- databricks_agentkit/openai/sessions.py +157 -0
- databricks_agentkit/py.typed +0 -0
- databricks_agentkit/runtime/ARCHITECTURE.md +64 -0
- databricks_agentkit/runtime/README.md +184 -0
- databricks_agentkit/runtime/__init__.py +69 -0
- databricks_agentkit/runtime/app.py +316 -0
- databricks_agentkit/runtime/auth.py +149 -0
- databricks_agentkit/runtime/durability/__init__.py +1 -0
- databricks_agentkit/runtime/durability/execution.py +133 -0
- databricks_agentkit/runtime/durability/heartbeat.py +64 -0
- databricks_agentkit/runtime/durability/lakebase_runtime_store.py +648 -0
- databricks_agentkit/runtime/durability/recovery.py +70 -0
- databricks_agentkit/runtime/durability/store.py +33 -0
- databricks_agentkit/runtime/execution.py +160 -0
- databricks_agentkit/runtime/genie.py +224 -0
- databricks_agentkit/runtime/mcp_auth.py +114 -0
- databricks_agentkit/runtime/model_services.py +90 -0
- databricks_agentkit/runtime/runtime.py +273 -0
- databricks_agentkit/runtime/session_store_client.py +120 -0
- databricks_agentkit/runtime/store.py +287 -0
- databricks_agentkit/runtime/tool_manifest.py +223 -0
- databricks_agentkit/runtime/tracing.py +71 -0
- databricks_agentkit/runtime/types.py +118 -0
- databricks_agentkit/runtime/workspace.py +27 -0
- databricks_agentkit/session_store.py +434 -0
- databricks_agentkit/timefmt.py +85 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"""Typed managed-memory resources and operations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterator
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import TYPE_CHECKING, Any, List, Optional
|
|
9
|
+
|
|
10
|
+
from databricks_agentkit._pagination import validate_limit, validate_page_size
|
|
11
|
+
from databricks_agentkit.timefmt import parse_timestamp
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from databricks_agentkit._api_client import _AgentBricksApiClient
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _resource_id(name: str) -> str:
|
|
18
|
+
return name.rsplit("/", 1)[-1]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True, kw_only=True)
|
|
22
|
+
class Memory:
|
|
23
|
+
name: str
|
|
24
|
+
actor_id: str
|
|
25
|
+
path: str
|
|
26
|
+
session_id: Optional[str] = None
|
|
27
|
+
content: Optional[str] = None
|
|
28
|
+
description: Optional[str] = None
|
|
29
|
+
source_type: Optional[str] = None
|
|
30
|
+
create_time: Optional[datetime] = None
|
|
31
|
+
update_time: Optional[datetime] = None
|
|
32
|
+
_store: MemoryStore = field(repr=False, compare=False)
|
|
33
|
+
_client: MemoryStores = field(repr=False, compare=False)
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def id(self) -> str:
|
|
37
|
+
return _resource_id(self.name)
|
|
38
|
+
|
|
39
|
+
def update(
|
|
40
|
+
self,
|
|
41
|
+
*,
|
|
42
|
+
content: Optional[str] = None,
|
|
43
|
+
description: Optional[str] = None,
|
|
44
|
+
) -> Memory:
|
|
45
|
+
return self._client._update_memory(
|
|
46
|
+
self._store,
|
|
47
|
+
memory_id=self.id,
|
|
48
|
+
content=content,
|
|
49
|
+
description=description,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def delete(self) -> None:
|
|
53
|
+
self._client._delete_memory(self._store, memory_id=self.id)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass(frozen=True)
|
|
57
|
+
class MemorySearchResult:
|
|
58
|
+
memory: Memory
|
|
59
|
+
score: Optional[float] = None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(frozen=True, kw_only=True)
|
|
63
|
+
class MemoryStore:
|
|
64
|
+
name: str
|
|
65
|
+
display_name: str
|
|
66
|
+
workspace_id: Optional[int] = None
|
|
67
|
+
storage_backend: Optional[dict[str, Any]] = None
|
|
68
|
+
owner_user_id: Optional[str] = None
|
|
69
|
+
create_time: Optional[datetime] = None
|
|
70
|
+
update_time: Optional[datetime] = None
|
|
71
|
+
description: Optional[str] = None
|
|
72
|
+
_client: MemoryStores = field(repr=False, compare=False)
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def id(self) -> str:
|
|
76
|
+
return _resource_id(self.name)
|
|
77
|
+
|
|
78
|
+
def update(
|
|
79
|
+
self,
|
|
80
|
+
*,
|
|
81
|
+
display_name: Optional[str] = None,
|
|
82
|
+
description: Optional[str] = None,
|
|
83
|
+
) -> MemoryStore:
|
|
84
|
+
return self._client._update_store(
|
|
85
|
+
self,
|
|
86
|
+
display_name=display_name,
|
|
87
|
+
description=description,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def delete(self) -> None:
|
|
91
|
+
self._client._delete_store(self)
|
|
92
|
+
|
|
93
|
+
def add(
|
|
94
|
+
self,
|
|
95
|
+
*,
|
|
96
|
+
actor_id: str,
|
|
97
|
+
path: str,
|
|
98
|
+
content: str,
|
|
99
|
+
session_id: Optional[str] = None,
|
|
100
|
+
description: Optional[str] = None,
|
|
101
|
+
source_type: Optional[str] = None,
|
|
102
|
+
write_mode: Optional[str] = None,
|
|
103
|
+
) -> Memory:
|
|
104
|
+
return self._client._add_memory(
|
|
105
|
+
self,
|
|
106
|
+
actor_id=actor_id,
|
|
107
|
+
path=path,
|
|
108
|
+
content=content,
|
|
109
|
+
session_id=session_id,
|
|
110
|
+
description=description,
|
|
111
|
+
source_type=source_type,
|
|
112
|
+
write_mode=write_mode,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
def list(
|
|
116
|
+
self,
|
|
117
|
+
*,
|
|
118
|
+
actor_id: str,
|
|
119
|
+
path_prefix: Optional[str] = None,
|
|
120
|
+
session_id: Optional[str] = None,
|
|
121
|
+
page_size: Optional[int] = None,
|
|
122
|
+
read_mask: Optional[str] = None,
|
|
123
|
+
) -> Iterator[Memory]:
|
|
124
|
+
return self._client._list_memories(
|
|
125
|
+
self,
|
|
126
|
+
actor_id=actor_id,
|
|
127
|
+
path_prefix=path_prefix,
|
|
128
|
+
session_id=session_id,
|
|
129
|
+
page_size=page_size,
|
|
130
|
+
read_mask=read_mask,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
def get(
|
|
134
|
+
self,
|
|
135
|
+
memory_id: str,
|
|
136
|
+
*,
|
|
137
|
+
read_mask: Optional[str] = None,
|
|
138
|
+
) -> Memory:
|
|
139
|
+
return self._client._get_memory(self, memory_id=memory_id, read_mask=read_mask)
|
|
140
|
+
|
|
141
|
+
def search(
|
|
142
|
+
self,
|
|
143
|
+
*,
|
|
144
|
+
actor_id: str,
|
|
145
|
+
query: str,
|
|
146
|
+
limit: Optional[int] = None,
|
|
147
|
+
path_prefix: Optional[str] = None,
|
|
148
|
+
session_id: Optional[str] = None,
|
|
149
|
+
read_mask: Optional[str] = None,
|
|
150
|
+
) -> List[MemorySearchResult]:
|
|
151
|
+
return self._client._search_memories(
|
|
152
|
+
self,
|
|
153
|
+
actor_id=actor_id,
|
|
154
|
+
query=query,
|
|
155
|
+
limit=limit,
|
|
156
|
+
path_prefix=path_prefix,
|
|
157
|
+
session_id=session_id,
|
|
158
|
+
read_mask=read_mask,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
def grant_permission(self, principal_id: str, *, permission: str = "WRITE") -> None:
|
|
162
|
+
"""Grant a service principal READ/WRITE access to this memory store.
|
|
163
|
+
|
|
164
|
+
``principal_id`` is the service principal's application (client) id. The grant is applied
|
|
165
|
+
server-side, so the caller needs neither store ownership nor Lakebase MANAGE.
|
|
166
|
+
"""
|
|
167
|
+
self._client._grant_permission(self, principal_id, permission=permission)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class MemoryStores:
|
|
171
|
+
def __init__(self, api: _AgentBricksApiClient):
|
|
172
|
+
self._api = api
|
|
173
|
+
|
|
174
|
+
def create(
|
|
175
|
+
self,
|
|
176
|
+
display_name: str,
|
|
177
|
+
*,
|
|
178
|
+
description: Optional[str] = None,
|
|
179
|
+
) -> MemoryStore:
|
|
180
|
+
response = self._api.create_memory_store(display_name, description)
|
|
181
|
+
return self._store_from_response(response)
|
|
182
|
+
|
|
183
|
+
def list(self, *, page_size: Optional[int] = None) -> Iterator[MemoryStore]:
|
|
184
|
+
validate_page_size(page_size)
|
|
185
|
+
page_token = None
|
|
186
|
+
while True:
|
|
187
|
+
response = self._api.list_memory_stores(
|
|
188
|
+
page_size=page_size,
|
|
189
|
+
page_token=page_token,
|
|
190
|
+
)
|
|
191
|
+
for store in response.get("managed_memory_stores", []):
|
|
192
|
+
yield self._store_from_response(store)
|
|
193
|
+
page_token = response.get("next_page_token")
|
|
194
|
+
if not page_token:
|
|
195
|
+
return
|
|
196
|
+
|
|
197
|
+
def get(self, store_id: str) -> MemoryStore:
|
|
198
|
+
return self._store_from_response(self._api.get_memory_store(store_id))
|
|
199
|
+
|
|
200
|
+
def _update_store(
|
|
201
|
+
self,
|
|
202
|
+
store: MemoryStore,
|
|
203
|
+
*,
|
|
204
|
+
display_name: Optional[str] = None,
|
|
205
|
+
description: Optional[str] = None,
|
|
206
|
+
) -> MemoryStore:
|
|
207
|
+
if display_name is None and description is None:
|
|
208
|
+
raise ValueError("at least one of display_name and description is required")
|
|
209
|
+
response = self._api.update_memory_store(
|
|
210
|
+
store.id,
|
|
211
|
+
display_name=display_name,
|
|
212
|
+
description=description,
|
|
213
|
+
)
|
|
214
|
+
return self._store_from_response(response)
|
|
215
|
+
|
|
216
|
+
def _delete_store(self, store: MemoryStore) -> None:
|
|
217
|
+
self._api.delete_memory_store(store.id)
|
|
218
|
+
|
|
219
|
+
def _grant_permission(self, store: MemoryStore, principal_id: str, *, permission: str) -> None:
|
|
220
|
+
self._api.grant_memory_store_permission(store.id, principal_id, permission=permission)
|
|
221
|
+
|
|
222
|
+
def _add_memory(
|
|
223
|
+
self,
|
|
224
|
+
store: MemoryStore,
|
|
225
|
+
*,
|
|
226
|
+
actor_id: str,
|
|
227
|
+
path: str,
|
|
228
|
+
content: str,
|
|
229
|
+
session_id: Optional[str] = None,
|
|
230
|
+
description: Optional[str] = None,
|
|
231
|
+
source_type: Optional[str] = None,
|
|
232
|
+
write_mode: Optional[str] = None,
|
|
233
|
+
) -> Memory:
|
|
234
|
+
response = self._api.create_memory_entry(
|
|
235
|
+
store.id,
|
|
236
|
+
actor_id,
|
|
237
|
+
path,
|
|
238
|
+
content=content,
|
|
239
|
+
description=description,
|
|
240
|
+
session_id=session_id,
|
|
241
|
+
source_type=source_type,
|
|
242
|
+
write_mode=write_mode,
|
|
243
|
+
)
|
|
244
|
+
return self._memory_from_response(response, store)
|
|
245
|
+
|
|
246
|
+
def _list_memories(
|
|
247
|
+
self,
|
|
248
|
+
store: MemoryStore,
|
|
249
|
+
*,
|
|
250
|
+
actor_id: str,
|
|
251
|
+
path_prefix: Optional[str] = None,
|
|
252
|
+
session_id: Optional[str] = None,
|
|
253
|
+
page_size: Optional[int] = None,
|
|
254
|
+
read_mask: Optional[str] = None,
|
|
255
|
+
) -> Iterator[Memory]:
|
|
256
|
+
validate_page_size(page_size)
|
|
257
|
+
page_token = None
|
|
258
|
+
while True:
|
|
259
|
+
response = self._api.list_memory_entries(
|
|
260
|
+
store.id,
|
|
261
|
+
actor_id,
|
|
262
|
+
path_prefix=path_prefix,
|
|
263
|
+
session_id=session_id,
|
|
264
|
+
page_size=page_size,
|
|
265
|
+
page_token=page_token,
|
|
266
|
+
read_mask=read_mask,
|
|
267
|
+
)
|
|
268
|
+
for memory in response.get("managed_memory_entries", []):
|
|
269
|
+
yield self._memory_from_response(memory, store)
|
|
270
|
+
page_token = response.get("next_page_token")
|
|
271
|
+
if not page_token:
|
|
272
|
+
return
|
|
273
|
+
|
|
274
|
+
def _get_memory(
|
|
275
|
+
self,
|
|
276
|
+
store: MemoryStore,
|
|
277
|
+
*,
|
|
278
|
+
memory_id: str,
|
|
279
|
+
read_mask: Optional[str] = None,
|
|
280
|
+
) -> Memory:
|
|
281
|
+
response = self._api.get_memory_entry(
|
|
282
|
+
store.id,
|
|
283
|
+
memory_id,
|
|
284
|
+
read_mask=read_mask,
|
|
285
|
+
)
|
|
286
|
+
return self._memory_from_response(response, store)
|
|
287
|
+
|
|
288
|
+
def _search_memories(
|
|
289
|
+
self,
|
|
290
|
+
store: MemoryStore,
|
|
291
|
+
*,
|
|
292
|
+
actor_id: str,
|
|
293
|
+
query: str,
|
|
294
|
+
limit: Optional[int] = None,
|
|
295
|
+
path_prefix: Optional[str] = None,
|
|
296
|
+
session_id: Optional[str] = None,
|
|
297
|
+
read_mask: Optional[str] = None,
|
|
298
|
+
) -> List[MemorySearchResult]:
|
|
299
|
+
effective_limit = 100 if limit is None else limit
|
|
300
|
+
validate_limit(effective_limit)
|
|
301
|
+
response = self._api.search_memory_entries(
|
|
302
|
+
store.id,
|
|
303
|
+
actor_id,
|
|
304
|
+
query,
|
|
305
|
+
page_size=effective_limit,
|
|
306
|
+
path_prefix=path_prefix,
|
|
307
|
+
session_id=session_id,
|
|
308
|
+
read_mask=read_mask,
|
|
309
|
+
)
|
|
310
|
+
results = response.get("results")
|
|
311
|
+
if results is not None:
|
|
312
|
+
return [
|
|
313
|
+
MemorySearchResult(
|
|
314
|
+
memory=self._memory_from_response(result["managed_memory_entry"], store),
|
|
315
|
+
score=result.get("score"),
|
|
316
|
+
)
|
|
317
|
+
for result in results
|
|
318
|
+
]
|
|
319
|
+
return [
|
|
320
|
+
MemorySearchResult(memory=self._memory_from_response(memory, store))
|
|
321
|
+
for memory in response.get("managed_memory_entries", [])
|
|
322
|
+
]
|
|
323
|
+
|
|
324
|
+
def _update_memory(
|
|
325
|
+
self,
|
|
326
|
+
store: MemoryStore,
|
|
327
|
+
*,
|
|
328
|
+
memory_id: str,
|
|
329
|
+
content: Optional[str] = None,
|
|
330
|
+
description: Optional[str] = None,
|
|
331
|
+
) -> Memory:
|
|
332
|
+
if content is None and description is None:
|
|
333
|
+
raise ValueError("at least one of content and description is required")
|
|
334
|
+
response = self._api.update_memory_entry(
|
|
335
|
+
store.id,
|
|
336
|
+
memory_id,
|
|
337
|
+
content=content,
|
|
338
|
+
description=description,
|
|
339
|
+
)
|
|
340
|
+
return self._memory_from_response(response, store)
|
|
341
|
+
|
|
342
|
+
def _delete_memory(self, store: MemoryStore, *, memory_id: str) -> None:
|
|
343
|
+
self._api.delete_memory_entry(store.id, memory_id)
|
|
344
|
+
|
|
345
|
+
def _store_from_response(self, response: dict[str, Any]) -> MemoryStore:
|
|
346
|
+
return MemoryStore(
|
|
347
|
+
name=response["name"],
|
|
348
|
+
display_name=response["display_name"],
|
|
349
|
+
workspace_id=response.get("workspace_id"),
|
|
350
|
+
storage_backend=response.get("storage_backend"),
|
|
351
|
+
owner_user_id=response.get("owner_user_id"),
|
|
352
|
+
create_time=parse_timestamp(response.get("created_at") or response.get("create_time")),
|
|
353
|
+
update_time=parse_timestamp(response.get("updated_at") or response.get("update_time")),
|
|
354
|
+
description=response.get("description"),
|
|
355
|
+
_client=self,
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
def _memory_from_response(self, response: dict[str, Any], store: MemoryStore) -> Memory:
|
|
359
|
+
return Memory(
|
|
360
|
+
name=response["name"],
|
|
361
|
+
actor_id=response["actor_id"],
|
|
362
|
+
session_id=response.get("session_id"),
|
|
363
|
+
path=response["path"],
|
|
364
|
+
content=response.get("content"),
|
|
365
|
+
description=response.get("description"),
|
|
366
|
+
source_type=response.get("source_type"),
|
|
367
|
+
create_time=parse_timestamp(response.get("create_time")),
|
|
368
|
+
update_time=parse_timestamp(response.get("update_time")),
|
|
369
|
+
_store=store,
|
|
370
|
+
_client=self,
|
|
371
|
+
)
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
"""Typed, forward-compatible views over 2.0 agents JSON responses.
|
|
2
|
+
|
|
3
|
+
Every model subclasses `dict` and holds the complete raw response, so mapping
|
|
4
|
+
access (`store["name"]`), `json.dumps`, and any new/unknown server fields keep
|
|
5
|
+
working. Subclasses add typed `@property` accessors as a convenience layer;
|
|
6
|
+
they never mutate the stored data, so nothing is lost as the preview API grows.
|
|
7
|
+
|
|
8
|
+
Accessors are intentionally named to avoid shadowing `dict` methods (e.g. list
|
|
9
|
+
models expose `.stores` / `.session_items`, never `.items`).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import Any, Optional
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class _Model(dict):
|
|
18
|
+
"""A dict-backed API response with typed accessors over the raw JSON."""
|
|
19
|
+
|
|
20
|
+
def to_dict(self) -> dict:
|
|
21
|
+
"""A plain-dict shallow copy of the raw response."""
|
|
22
|
+
return dict(self)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _wrap(value: Any, cls: type) -> Any:
|
|
26
|
+
return cls(value) if isinstance(value, dict) else None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _wrap_list(value: Any, cls: type) -> list:
|
|
30
|
+
return [cls(v) for v in value if isinstance(v, dict)] if isinstance(value, list) else []
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class StorageBackend(_Model):
|
|
34
|
+
@property
|
|
35
|
+
def backend_type(self) -> Optional[str]:
|
|
36
|
+
return self.get("backend_type")
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def backend_id(self) -> Optional[str]:
|
|
40
|
+
return self.get("backend_id")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class RuntimeStoreLakebaseBackend(_Model):
|
|
44
|
+
@property
|
|
45
|
+
def project_id(self) -> Optional[str]:
|
|
46
|
+
return self.get("project_id")
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def branch(self) -> Optional[str]:
|
|
50
|
+
return self.get("branch")
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def database_id(self) -> Optional[str]:
|
|
54
|
+
return self.get("database_id")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class RuntimeStoreAppOwner(_Model):
|
|
58
|
+
@property
|
|
59
|
+
def name(self) -> Optional[str]:
|
|
60
|
+
return self.get("name")
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def service_principal_id(self) -> Optional[str]:
|
|
64
|
+
return self.get("service_principal_id")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class RuntimeStoreOwner(_Model):
|
|
68
|
+
@property
|
|
69
|
+
def app(self) -> Optional[RuntimeStoreAppOwner]:
|
|
70
|
+
return _wrap(self.get("app"), RuntimeStoreAppOwner)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class RuntimeStoreStorageBackend(_Model):
|
|
74
|
+
@property
|
|
75
|
+
def lakebase(self) -> Optional[RuntimeStoreLakebaseBackend]:
|
|
76
|
+
return _wrap(self.get("lakebase"), RuntimeStoreLakebaseBackend)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class RuntimeStore(_Model):
|
|
80
|
+
@property
|
|
81
|
+
def name(self) -> Optional[str]:
|
|
82
|
+
return self.get("name")
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def owner(self) -> Optional[RuntimeStoreOwner]:
|
|
86
|
+
return _wrap(self.get("owner"), RuntimeStoreOwner)
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def storage_backend(self) -> Optional[RuntimeStoreStorageBackend]:
|
|
90
|
+
return _wrap(self.get("storage_backend"), RuntimeStoreStorageBackend)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class MemoryStore(_Model):
|
|
94
|
+
@property
|
|
95
|
+
def name(self) -> Optional[str]:
|
|
96
|
+
return self.get("name")
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def display_name(self) -> Optional[str]:
|
|
100
|
+
return self.get("display_name")
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def workspace_id(self) -> Optional[str]:
|
|
104
|
+
return self.get("workspace_id")
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def owner_user_id(self) -> Optional[str]:
|
|
108
|
+
return self.get("owner_user_id")
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def description(self) -> Optional[str]:
|
|
112
|
+
return self.get("description")
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def storage_backend(self) -> Optional[StorageBackend]:
|
|
116
|
+
return _wrap(self.get("storage_backend"), StorageBackend)
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def create_time(self) -> Optional[str]:
|
|
120
|
+
return self.get("create_time")
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def update_time(self) -> Optional[str]:
|
|
124
|
+
return self.get("update_time")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class MemoryEntry(_Model):
|
|
128
|
+
@property
|
|
129
|
+
def name(self) -> Optional[str]:
|
|
130
|
+
return self.get("name")
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def actor_id(self) -> Optional[str]:
|
|
134
|
+
return self.get("actor_id")
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def path(self) -> Optional[str]:
|
|
138
|
+
return self.get("path")
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def content(self) -> Optional[str]:
|
|
142
|
+
return self.get("content")
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def description(self) -> Optional[str]:
|
|
146
|
+
return self.get("description")
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def session_id(self) -> Optional[str]:
|
|
150
|
+
return self.get("session_id")
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def source_type(self) -> Optional[str]:
|
|
154
|
+
return self.get("source_type")
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def create_time(self) -> Optional[str]:
|
|
158
|
+
return self.get("create_time")
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def update_time(self) -> Optional[str]:
|
|
162
|
+
return self.get("update_time")
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class MemoryStoreList(_Model):
|
|
166
|
+
@property
|
|
167
|
+
def stores(self) -> list[MemoryStore]:
|
|
168
|
+
return _wrap_list(self.get("managed_memory_stores"), MemoryStore)
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def next_page_token(self) -> Optional[str]:
|
|
172
|
+
return self.get("next_page_token")
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class MemoryEntryList(_Model):
|
|
176
|
+
@property
|
|
177
|
+
def entries(self) -> list[MemoryEntry]:
|
|
178
|
+
return _wrap_list(self.get("managed_memory_entries"), MemoryEntry)
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def next_page_token(self) -> Optional[str]:
|
|
182
|
+
return self.get("next_page_token")
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class ExtractMemoriesResponse(_Model):
|
|
186
|
+
@property
|
|
187
|
+
def name(self) -> Optional[str]:
|
|
188
|
+
return self.get("name")
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def entries(self) -> list[MemoryEntry]:
|
|
192
|
+
return _wrap_list(self.get("entries"), MemoryEntry)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class MemorySearchHit(_Model):
|
|
196
|
+
@property
|
|
197
|
+
def entry(self) -> Optional[MemoryEntry]:
|
|
198
|
+
return _wrap(self.get("managed_memory_entry"), MemoryEntry)
|
|
199
|
+
|
|
200
|
+
@property
|
|
201
|
+
def score(self) -> Optional[float]:
|
|
202
|
+
return self.get("score")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class MemorySearchResult(_Model):
|
|
206
|
+
@property
|
|
207
|
+
def entries(self) -> list[MemoryEntry]:
|
|
208
|
+
return _wrap_list(self.get("managed_memory_entries"), MemoryEntry)
|
|
209
|
+
|
|
210
|
+
@property
|
|
211
|
+
def results(self) -> list[MemorySearchHit]:
|
|
212
|
+
return _wrap_list(self.get("results"), MemorySearchHit)
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
def next_page_token(self) -> Optional[str]:
|
|
216
|
+
return self.get("next_page_token")
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class SessionStore(_Model):
|
|
220
|
+
@property
|
|
221
|
+
def session_store_name(self) -> Optional[str]:
|
|
222
|
+
return self.get("session_store_name")
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def session_store_id(self) -> Optional[str]:
|
|
226
|
+
return self.get("session_store_id")
|
|
227
|
+
|
|
228
|
+
@property
|
|
229
|
+
def creator_user_id(self) -> Optional[str]:
|
|
230
|
+
return self.get("creator_user_id")
|
|
231
|
+
|
|
232
|
+
@property
|
|
233
|
+
def description(self) -> Optional[str]:
|
|
234
|
+
return self.get("description")
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def create_time(self) -> Optional[str]:
|
|
238
|
+
return self.get("create_time")
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
def update_time(self) -> Optional[str]:
|
|
242
|
+
return self.get("update_time")
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class SessionStoreList(_Model):
|
|
246
|
+
@property
|
|
247
|
+
def stores(self) -> list[SessionStore]:
|
|
248
|
+
return _wrap_list(self.get("session_stores"), SessionStore)
|
|
249
|
+
|
|
250
|
+
@property
|
|
251
|
+
def next_page_token(self) -> Optional[str]:
|
|
252
|
+
return self.get("next_page_token")
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class Session(_Model):
|
|
256
|
+
@property
|
|
257
|
+
def session_store_name(self) -> Optional[str]:
|
|
258
|
+
return self.get("session_store_name")
|
|
259
|
+
|
|
260
|
+
@property
|
|
261
|
+
def session_id(self) -> Optional[str]:
|
|
262
|
+
return self.get("session_id")
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def actor_id(self) -> Optional[str]:
|
|
266
|
+
return self.get("actor_id")
|
|
267
|
+
|
|
268
|
+
@property
|
|
269
|
+
def root_session_id(self) -> Optional[str]:
|
|
270
|
+
return self.get("root_session_id")
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
def parent_session_id(self) -> Optional[str]:
|
|
274
|
+
return self.get("parent_session_id")
|
|
275
|
+
|
|
276
|
+
@property
|
|
277
|
+
def metadata(self) -> Optional[dict]:
|
|
278
|
+
return self.get("metadata")
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def create_time(self) -> Optional[str]:
|
|
282
|
+
return self.get("create_time")
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def update_time(self) -> Optional[str]:
|
|
286
|
+
return self.get("update_time")
|
|
287
|
+
|
|
288
|
+
@property
|
|
289
|
+
def last_activity_time(self) -> Optional[str]:
|
|
290
|
+
return self.get("last_activity_time")
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class SessionList(_Model):
|
|
294
|
+
@property
|
|
295
|
+
def sessions(self) -> list[Session]:
|
|
296
|
+
return _wrap_list(self.get("sessions"), Session)
|
|
297
|
+
|
|
298
|
+
@property
|
|
299
|
+
def next_page_token(self) -> Optional[str]:
|
|
300
|
+
return self.get("next_page_token")
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
class SessionItem(_Model):
|
|
304
|
+
@property
|
|
305
|
+
def item_id(self) -> Optional[str]:
|
|
306
|
+
return self.get("item_id")
|
|
307
|
+
|
|
308
|
+
@property
|
|
309
|
+
def data(self) -> Any:
|
|
310
|
+
return self.get("data")
|
|
311
|
+
|
|
312
|
+
@property
|
|
313
|
+
def create_time(self) -> Optional[str]:
|
|
314
|
+
return self.get("create_time")
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
class SessionItemList(_Model):
|
|
318
|
+
@property
|
|
319
|
+
def session_items(self) -> list[SessionItem]:
|
|
320
|
+
return _wrap_list(self.get("session_items"), SessionItem)
|
|
321
|
+
|
|
322
|
+
@property
|
|
323
|
+
def next_page_token(self) -> Optional[str]:
|
|
324
|
+
return self.get("next_page_token")
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
class PoppedSessionItem(_Model):
|
|
328
|
+
@property
|
|
329
|
+
def item(self) -> Optional[SessionItem]:
|
|
330
|
+
return _wrap(self.get("item"), SessionItem)
|