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.
Files changed (159) hide show
  1. databricks_agentbricks/__init__.py +1 -0
  2. databricks_agentbricks/_group.py +217 -0
  3. databricks_agentbricks/agent_project.py +657 -0
  4. databricks_agentbricks/app_resources.py +139 -0
  5. databricks_agentbricks/cli/__init__.py +12 -0
  6. databricks_agentbricks/cli/app.py +108 -0
  7. databricks_agentbricks/cli/app_auth.py +198 -0
  8. databricks_agentbricks/cli/auth.py +142 -0
  9. databricks_agentbricks/cli/deploy.py +954 -0
  10. databricks_agentbricks/cli/dev.py +310 -0
  11. databricks_agentbricks/cli/endpoint.py +145 -0
  12. databricks_agentbricks/cli/endpoint_examples.py +33 -0
  13. databricks_agentbricks/cli/endpoint_output.py +53 -0
  14. databricks_agentbricks/cli/endpoint_request.py +71 -0
  15. databricks_agentbricks/cli/endpoint_transport.py +148 -0
  16. databricks_agentbricks/cli/help.py +467 -0
  17. databricks_agentbricks/cli/init.py +496 -0
  18. databricks_agentbricks/cli/mcp.py +75 -0
  19. databricks_agentbricks/cli/memory.py +520 -0
  20. databricks_agentbricks/cli/sandbox.py +823 -0
  21. databricks_agentbricks/cli/sessions.py +588 -0
  22. databricks_agentbricks/cli/tools.py +456 -0
  23. databricks_agentbricks/cli/tracing.py +724 -0
  24. databricks_agentbricks/databricks_cli.py +38 -0
  25. databricks_agentbricks/errors.py +114 -0
  26. databricks_agentbricks/lakebase_runtime_store.py +107 -0
  27. databricks_agentbricks/legacy_lakebase_runtime_store.py +74 -0
  28. databricks_agentbricks/project_config.py +157 -0
  29. databricks_agentbricks/project_types.py +55 -0
  30. databricks_agentbricks/py.typed +0 -0
  31. databricks_agentbricks/render.py +349 -0
  32. databricks_agentbricks/templates/agent-bricks-migrate/SKILL.md +101 -0
  33. databricks_agentbricks/templates/agent-langgraph/.env.example +36 -0
  34. databricks_agentbricks/templates/agent-langgraph/.gitignore +199 -0
  35. databricks_agentbricks/templates/agent-langgraph/AGENTKIT_CONTRACT.md +95 -0
  36. databricks_agentbricks/templates/agent-langgraph/AGENTS.md +31 -0
  37. databricks_agentbricks/templates/agent-langgraph/CLAUDE.md +1 -0
  38. databricks_agentbricks/templates/agent-langgraph/README.md +141 -0
  39. databricks_agentbricks/templates/agent-langgraph/agent/__init__.py +0 -0
  40. databricks_agentbricks/templates/agent-langgraph/agent/agent.py +177 -0
  41. databricks_agentbricks/templates/agent-langgraph/agent/mcps.py +27 -0
  42. databricks_agentbricks/templates/agent-langgraph/agent/tools/__init__.py +24 -0
  43. databricks_agentbricks/templates/agent-langgraph/agent/tools/sample_tool.py +15 -0
  44. databricks_agentbricks/templates/agent-langgraph/agent/tools/send_message.py +17 -0
  45. databricks_agentbricks/templates/agent-langgraph/app.yaml +15 -0
  46. databricks_agentbricks/templates/agent-langgraph/pyproject.toml +42 -0
  47. databricks_agentbricks/templates/agent-langgraph/runtime/__init__.py +0 -0
  48. databricks_agentbricks/templates/agent-langgraph/runtime/adapter.py +144 -0
  49. databricks_agentbricks/templates/agent-langgraph/runtime/main.py +25 -0
  50. databricks_agentbricks/templates/agent-langgraph/tests/__init__.py +0 -0
  51. databricks_agentbricks/templates/agent-langgraph/tests/test_agent.py +211 -0
  52. databricks_agentbricks/templates/agent-langgraph/tests/test_runtime.py +19 -0
  53. databricks_agentbricks/templates/agent-langgraph/tests/test_workspace.py +28 -0
  54. databricks_agentbricks/templates/agent-openai/.env.example +37 -0
  55. databricks_agentbricks/templates/agent-openai/.gitignore +199 -0
  56. databricks_agentbricks/templates/agent-openai/AGENTKIT_CONTRACT.md +107 -0
  57. databricks_agentbricks/templates/agent-openai/AGENTS.md +76 -0
  58. databricks_agentbricks/templates/agent-openai/CLAUDE.md +1 -0
  59. databricks_agentbricks/templates/agent-openai/README.md +143 -0
  60. databricks_agentbricks/templates/agent-openai/agent/__init__.py +0 -0
  61. databricks_agentbricks/templates/agent-openai/agent/agent.py +205 -0
  62. databricks_agentbricks/templates/agent-openai/agent/mcps.py +28 -0
  63. databricks_agentbricks/templates/agent-openai/agent/tools/__init__.py +24 -0
  64. databricks_agentbricks/templates/agent-openai/agent/tools/sample_tool.py +15 -0
  65. databricks_agentbricks/templates/agent-openai/agent/tools/send_message.py +18 -0
  66. databricks_agentbricks/templates/agent-openai/app.yaml +15 -0
  67. databricks_agentbricks/templates/agent-openai/pyproject.toml +42 -0
  68. databricks_agentbricks/templates/agent-openai/runtime/__init__.py +0 -0
  69. databricks_agentbricks/templates/agent-openai/runtime/adapter.py +188 -0
  70. databricks_agentbricks/templates/agent-openai/runtime/main.py +25 -0
  71. databricks_agentbricks/templates/agent-openai/tests/__init__.py +0 -0
  72. databricks_agentbricks/templates/agent-openai/tests/test_agent.py +326 -0
  73. databricks_agentbricks/templates/agent-openai/tests/test_runtime.py +19 -0
  74. databricks_agentbricks/templates/agent-openai/tests/test_workspace.py +28 -0
  75. databricks_agentbricks/templates/custom-agent-langgraph/.env.example +1 -0
  76. databricks_agentbricks/templates/custom-agent-langgraph/.gitignore +11 -0
  77. databricks_agentbricks/templates/custom-agent-langgraph/README.md +22 -0
  78. databricks_agentbricks/templates/custom-agent-langgraph/agent/__init__.py +0 -0
  79. databricks_agentbricks/templates/custom-agent-langgraph/agent/agent.py +27 -0
  80. databricks_agentbricks/templates/custom-agent-langgraph/app.yaml +1 -0
  81. databricks_agentbricks/templates/custom-agent-langgraph/pyproject.toml +38 -0
  82. databricks_agentbricks/templates/custom-agent-langgraph/runtime/__init__.py +0 -0
  83. databricks_agentbricks/templates/custom-agent-langgraph/runtime/main.py +31 -0
  84. databricks_agentbricks/templates/custom-agent-langgraph/tests/test_runtime.py +29 -0
  85. databricks_agentbricks/templates/custom-agent-openai/.env.example +1 -0
  86. databricks_agentbricks/templates/custom-agent-openai/.gitignore +11 -0
  87. databricks_agentbricks/templates/custom-agent-openai/README.md +22 -0
  88. databricks_agentbricks/templates/custom-agent-openai/agent/__init__.py +0 -0
  89. databricks_agentbricks/templates/custom-agent-openai/agent/agent.py +29 -0
  90. databricks_agentbricks/templates/custom-agent-openai/app.yaml +1 -0
  91. databricks_agentbricks/templates/custom-agent-openai/pyproject.toml +38 -0
  92. databricks_agentbricks/templates/custom-agent-openai/runtime/__init__.py +0 -0
  93. databricks_agentbricks/templates/custom-agent-openai/runtime/main.py +31 -0
  94. databricks_agentbricks/templates/custom-agent-openai/tests/test_runtime.py +29 -0
  95. databricks_agentbricks/templates/sandbox_mcp.py +39 -0
  96. databricks_agentbricks/templates/sandbox_mcp_langgraph.py +39 -0
  97. databricks_agentbricks/templates/ui/agent-langgraph/CHAT_APP.md +49 -0
  98. databricks_agentbricks/templates/ui/agent-langgraph/runtime/main.py +26 -0
  99. databricks_agentbricks/templates/ui/agent-langgraph/runtime/ui.py +528 -0
  100. databricks_agentbricks/templates/ui/agent-langgraph/tests/test_demo_ui.py +542 -0
  101. databricks_agentbricks/templates/ui/agent-langgraph/ui/agentbricks-mark.png +0 -0
  102. databricks_agentbricks/templates/ui/agent-langgraph/ui/app.js +1464 -0
  103. databricks_agentbricks/templates/ui/agent-langgraph/ui/index.html +281 -0
  104. databricks_agentbricks/templates/ui/agent-langgraph/ui/styles.css +1913 -0
  105. databricks_agentbricks/templates/ui/agent-openai/CHAT_APP.md +54 -0
  106. databricks_agentbricks/templates/ui/agent-openai/runtime/main.py +26 -0
  107. databricks_agentbricks/templates/ui/agent-openai/runtime/ui.py +521 -0
  108. databricks_agentbricks/templates/ui/agent-openai/tests/test_demo_ui.py +512 -0
  109. databricks_agentbricks/templates/ui/agent-openai/ui/agentbricks-mark.png +0 -0
  110. databricks_agentbricks/templates/ui/agent-openai/ui/app.js +1428 -0
  111. databricks_agentbricks/templates/ui/agent-openai/ui/index.html +281 -0
  112. databricks_agentbricks/templates/ui/agent-openai/ui/styles.css +1913 -0
  113. databricks_agentbricks/theme.py +72 -0
  114. databricks_agentbricks-0.2.0.dist-info/METADATA +897 -0
  115. databricks_agentbricks-0.2.0.dist-info/RECORD +159 -0
  116. databricks_agentbricks-0.2.0.dist-info/WHEEL +4 -0
  117. databricks_agentbricks-0.2.0.dist-info/entry_points.txt +2 -0
  118. databricks_agentbricks-0.2.0.dist-info/licenses/NOTICE +39 -0
  119. databricks_agentkit/__init__.py +67 -0
  120. databricks_agentkit/_api_client.py +673 -0
  121. databricks_agentkit/_pagination.py +25 -0
  122. databricks_agentkit/client.py +31 -0
  123. databricks_agentkit/langgraph/__init__.py +98 -0
  124. databricks_agentkit/langgraph/genie.py +50 -0
  125. databricks_agentkit/langgraph/mcp.py +216 -0
  126. databricks_agentkit/langgraph/memory.py +67 -0
  127. databricks_agentkit/langgraph/session_store.py +485 -0
  128. databricks_agentkit/memory_store.py +371 -0
  129. databricks_agentkit/models.py +330 -0
  130. databricks_agentkit/openai/__init__.py +93 -0
  131. databricks_agentkit/openai/genie.py +50 -0
  132. databricks_agentkit/openai/mcp.py +189 -0
  133. databricks_agentkit/openai/memory.py +67 -0
  134. databricks_agentkit/openai/sessions.py +157 -0
  135. databricks_agentkit/py.typed +0 -0
  136. databricks_agentkit/runtime/ARCHITECTURE.md +64 -0
  137. databricks_agentkit/runtime/README.md +184 -0
  138. databricks_agentkit/runtime/__init__.py +69 -0
  139. databricks_agentkit/runtime/app.py +316 -0
  140. databricks_agentkit/runtime/auth.py +149 -0
  141. databricks_agentkit/runtime/durability/__init__.py +1 -0
  142. databricks_agentkit/runtime/durability/execution.py +133 -0
  143. databricks_agentkit/runtime/durability/heartbeat.py +64 -0
  144. databricks_agentkit/runtime/durability/lakebase_runtime_store.py +648 -0
  145. databricks_agentkit/runtime/durability/recovery.py +70 -0
  146. databricks_agentkit/runtime/durability/store.py +33 -0
  147. databricks_agentkit/runtime/execution.py +160 -0
  148. databricks_agentkit/runtime/genie.py +224 -0
  149. databricks_agentkit/runtime/mcp_auth.py +114 -0
  150. databricks_agentkit/runtime/model_services.py +90 -0
  151. databricks_agentkit/runtime/runtime.py +273 -0
  152. databricks_agentkit/runtime/session_store_client.py +120 -0
  153. databricks_agentkit/runtime/store.py +287 -0
  154. databricks_agentkit/runtime/tool_manifest.py +223 -0
  155. databricks_agentkit/runtime/tracing.py +71 -0
  156. databricks_agentkit/runtime/types.py +118 -0
  157. databricks_agentkit/runtime/workspace.py +27 -0
  158. databricks_agentkit/session_store.py +434 -0
  159. 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)