agent-lab-sdk 0.1.35.dev1__py3-none-any.whl → 0.1.37__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.
Potentially problematic release.
This version of agent-lab-sdk might be problematic. Click here for more details.
- agent_lab_sdk/langgraph/checkpoint/agw_saver.py +163 -107
- {agent_lab_sdk-0.1.35.dev1.dist-info → agent_lab_sdk-0.1.37.dist-info}/METADATA +1 -1
- {agent_lab_sdk-0.1.35.dev1.dist-info → agent_lab_sdk-0.1.37.dist-info}/RECORD +6 -6
- {agent_lab_sdk-0.1.35.dev1.dist-info → agent_lab_sdk-0.1.37.dist-info}/WHEEL +0 -0
- {agent_lab_sdk-0.1.35.dev1.dist-info → agent_lab_sdk-0.1.37.dist-info}/licenses/LICENSE +0 -0
- {agent_lab_sdk-0.1.35.dev1.dist-info → agent_lab_sdk-0.1.37.dist-info}/top_level.txt +0 -0
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import orjson
|
|
4
|
+
from random import random
|
|
5
|
+
from langgraph.checkpoint.serde.types import ChannelProtocol
|
|
3
6
|
import asyncio
|
|
4
7
|
import base64
|
|
5
8
|
import logging
|
|
6
9
|
import os
|
|
7
10
|
from contextlib import asynccontextmanager
|
|
8
|
-
from random import random
|
|
9
11
|
from typing import Any, AsyncIterator, Dict, Iterator, Optional, Sequence, Tuple
|
|
10
12
|
|
|
11
13
|
import httpx
|
|
12
|
-
import orjson
|
|
13
14
|
from langchain_core.runnables import RunnableConfig
|
|
14
15
|
|
|
15
16
|
from langgraph.checkpoint.base import (
|
|
@@ -23,7 +24,7 @@ from langgraph.checkpoint.base import (
|
|
|
23
24
|
)
|
|
24
25
|
from langgraph.checkpoint.serde.base import SerializerProtocol
|
|
25
26
|
from langgraph.checkpoint.serde.encrypted import EncryptedSerializer
|
|
26
|
-
|
|
27
|
+
|
|
27
28
|
from .serde import Serializer
|
|
28
29
|
|
|
29
30
|
__all__ = ["AsyncAGWCheckpointSaver"]
|
|
@@ -33,17 +34,22 @@ logger = logging.getLogger(__name__)
|
|
|
33
34
|
TYPED_KEYS = ("type", "blob")
|
|
34
35
|
|
|
35
36
|
|
|
36
|
-
def
|
|
37
|
-
return base64.b64encode(b).decode() if b is not None else None
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def _b64decode_strict(s: str) -> bytes | None:
|
|
41
|
-
"""Возвращает bytes только если строка действительно корректная base64."""
|
|
37
|
+
def _b64decode_strict(value: str) -> bytes | None:
|
|
42
38
|
try:
|
|
43
|
-
return base64.b64decode(
|
|
39
|
+
return base64.b64decode(value, validate=True)
|
|
44
40
|
except Exception:
|
|
45
41
|
return None
|
|
46
42
|
|
|
43
|
+
# ------------------------------------------------------------------ #
|
|
44
|
+
# helpers for Py < 3.10
|
|
45
|
+
# ------------------------------------------------------------------ #
|
|
46
|
+
try:
|
|
47
|
+
anext # type: ignore[name-defined]
|
|
48
|
+
except NameError: # pragma: no cover
|
|
49
|
+
|
|
50
|
+
async def anext(it):
|
|
51
|
+
return await it.__anext__()
|
|
52
|
+
|
|
47
53
|
|
|
48
54
|
class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
49
55
|
"""Persist checkpoints in Agent-Gateway с помощью `httpx` async client."""
|
|
@@ -61,15 +67,14 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
61
67
|
):
|
|
62
68
|
if not serde:
|
|
63
69
|
base_serde: SerializerProtocol = Serializer()
|
|
64
|
-
|
|
65
|
-
_aes_key = (
|
|
70
|
+
aes_key = (
|
|
66
71
|
os.getenv("LANGGRAPH_AES_KEY")
|
|
67
72
|
or os.getenv("AGW_AES_KEY")
|
|
68
73
|
or os.getenv("AES_KEY")
|
|
69
74
|
)
|
|
70
|
-
if
|
|
75
|
+
if aes_key:
|
|
71
76
|
base_serde = EncryptedSerializer.from_pycryptodome_aes(
|
|
72
|
-
base_serde, key=
|
|
77
|
+
base_serde, key=aes_key
|
|
73
78
|
)
|
|
74
79
|
serde = base_serde
|
|
75
80
|
super().__init__(serde=serde)
|
|
@@ -91,7 +96,7 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
91
96
|
headers=self.headers,
|
|
92
97
|
timeout=self.timeout,
|
|
93
98
|
verify=verify,
|
|
94
|
-
trust_env=True
|
|
99
|
+
trust_env=True
|
|
95
100
|
)
|
|
96
101
|
|
|
97
102
|
async def __aenter__(self): # noqa: D401
|
|
@@ -100,63 +105,105 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
100
105
|
async def __aexit__(self, exc_type, exc, tb): # noqa: D401
|
|
101
106
|
await self._client.aclose()
|
|
102
107
|
|
|
103
|
-
# -----------------------
|
|
104
|
-
def
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if b64 is None:
|
|
116
|
-
return self.serde.loads_typed((t, None))
|
|
117
|
-
if isinstance(b64, str):
|
|
118
|
-
b = _b64decode_strict(b64)
|
|
119
|
-
if b is not None:
|
|
120
|
-
return self.serde.loads_typed((t, b))
|
|
121
|
-
# если невалидно — падаем ниже на общую обработку
|
|
122
|
-
|
|
123
|
-
# Допускаем tuple/list вида [type, base64] — только при валидной base64
|
|
124
|
-
if isinstance(obj, (list, tuple)) and len(obj) == 2 and isinstance(obj[0], str):
|
|
125
|
-
t, b64 = obj
|
|
126
|
-
if b64 is None and t == "empty":
|
|
127
|
-
return self.serde.loads_typed((t, None))
|
|
128
|
-
if isinstance(b64, str):
|
|
129
|
-
b = _b64decode_strict(b64)
|
|
130
|
-
if b is not None:
|
|
131
|
-
return self.serde.loads_typed((t, b))
|
|
132
|
-
# иначе это не typed-пара
|
|
133
|
-
|
|
134
|
-
# Если это строка — пробуем как base64 строго, затем как JSON-строку
|
|
135
|
-
if isinstance(obj, str):
|
|
136
|
-
b = _b64decode_strict(obj)
|
|
137
|
-
if b is not None:
|
|
138
|
-
try:
|
|
139
|
-
return self.serde.loads(b)
|
|
140
|
-
except Exception:
|
|
141
|
-
pass
|
|
108
|
+
# ----------------------- universal dump/load ---------------------
|
|
109
|
+
# def _safe_dump(self, obj: Any) -> Any:
|
|
110
|
+
# """self.serde.dump → гарантированная JSON-строка."""
|
|
111
|
+
# dumped = self.serde.dumps(obj)
|
|
112
|
+
# if isinstance(dumped, (bytes, bytearray)):
|
|
113
|
+
# return base64.b64encode(dumped).decode() # str
|
|
114
|
+
# return dumped # уже json-совместимо
|
|
115
|
+
|
|
116
|
+
def _safe_dump(self, obj: Any) -> Any:
|
|
117
|
+
"""bytes → python-object; fallback base64 для реально бинарных данных."""
|
|
118
|
+
dumped = self.serde.dumps(obj)
|
|
119
|
+
if isinstance(dumped, (bytes, bytearray)):
|
|
142
120
|
try:
|
|
143
|
-
|
|
121
|
+
# 1) bytes → str
|
|
122
|
+
s = dumped.decode()
|
|
123
|
+
# 2) str JSON → python (list/dict/scalar)
|
|
124
|
+
return orjson.loads(s)
|
|
125
|
+
except (UnicodeDecodeError, orjson.JSONDecodeError):
|
|
126
|
+
# не UTF-8 или не JSON → base64
|
|
127
|
+
return base64.b64encode(dumped).decode()
|
|
128
|
+
return dumped
|
|
129
|
+
|
|
130
|
+
def _safe_load(self, obj: Any) -> Any:
|
|
131
|
+
if obj is None:
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
if isinstance(obj, dict):
|
|
135
|
+
if all(k in obj for k in TYPED_KEYS):
|
|
136
|
+
t = obj.get("type")
|
|
137
|
+
blob = obj.get("blob")
|
|
138
|
+
if blob is None:
|
|
139
|
+
try:
|
|
140
|
+
return self.serde.loads_typed((t, None))
|
|
141
|
+
except Exception:
|
|
142
|
+
return obj
|
|
143
|
+
if isinstance(blob, str):
|
|
144
|
+
payload = _b64decode_strict(blob)
|
|
145
|
+
if payload is not None:
|
|
146
|
+
try:
|
|
147
|
+
return self.serde.loads_typed((t, payload))
|
|
148
|
+
except Exception:
|
|
149
|
+
# fall back to generic handling below
|
|
150
|
+
pass
|
|
151
|
+
try:
|
|
152
|
+
return self.serde.loads(orjson.dumps(obj))
|
|
144
153
|
except Exception:
|
|
145
154
|
return obj
|
|
146
155
|
|
|
147
|
-
|
|
148
|
-
|
|
156
|
+
if isinstance(obj, (list, tuple)):
|
|
157
|
+
if (
|
|
158
|
+
len(obj) == 2
|
|
159
|
+
and isinstance(obj[0], str)
|
|
160
|
+
and (obj[1] is None or isinstance(obj[1], str))
|
|
161
|
+
):
|
|
162
|
+
blob = obj[1]
|
|
163
|
+
if blob is None:
|
|
164
|
+
try:
|
|
165
|
+
return self.serde.loads_typed((obj[0], None))
|
|
166
|
+
except Exception:
|
|
167
|
+
pass
|
|
168
|
+
elif isinstance(blob, str):
|
|
169
|
+
payload = _b64decode_strict(blob)
|
|
170
|
+
if payload is not None:
|
|
171
|
+
try:
|
|
172
|
+
return self.serde.loads_typed((obj[0], payload))
|
|
173
|
+
except Exception:
|
|
174
|
+
pass
|
|
149
175
|
try:
|
|
150
|
-
return self.serde.loads(orjson.dumps(obj))
|
|
176
|
+
return self.serde.loads(orjson.dumps(list(obj)))
|
|
151
177
|
except Exception:
|
|
152
178
|
return obj
|
|
153
179
|
|
|
154
|
-
|
|
180
|
+
if isinstance(obj, str):
|
|
181
|
+
try:
|
|
182
|
+
return self.serde.loads(obj.encode())
|
|
183
|
+
except Exception:
|
|
184
|
+
payload = _b64decode_strict(obj)
|
|
185
|
+
if payload is not None:
|
|
186
|
+
try:
|
|
187
|
+
return self.serde.loads(payload)
|
|
188
|
+
except Exception:
|
|
189
|
+
pass
|
|
190
|
+
return obj
|
|
191
|
+
|
|
155
192
|
try:
|
|
156
193
|
return self.serde.loads(obj)
|
|
157
194
|
except Exception:
|
|
158
195
|
return obj
|
|
159
196
|
|
|
197
|
+
# def _safe_load(self, obj: Any) -> Any:
|
|
198
|
+
# """Обратная операция к _safe_dump."""
|
|
199
|
+
# if isinstance(obj, str):
|
|
200
|
+
# try:
|
|
201
|
+
# return self.serde.load(base64.b64decode(obj))
|
|
202
|
+
# except Exception:
|
|
203
|
+
# # не base64 — обычная строка
|
|
204
|
+
# return self.serde.load(obj)
|
|
205
|
+
# return self.serde.load(obj)
|
|
206
|
+
|
|
160
207
|
# ----------------------- config <-> api --------------------------
|
|
161
208
|
def _to_api_config(self, cfg: RunnableConfig | None) -> Dict[str, Any]:
|
|
162
209
|
if not cfg:
|
|
@@ -174,47 +221,44 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
174
221
|
|
|
175
222
|
# --------------------- checkpoint (de)ser ------------------------
|
|
176
223
|
def _encode_cp(self, cp: Checkpoint) -> Dict[str, Any]:
|
|
177
|
-
|
|
178
|
-
k: self._encode_typed(v) for k, v in cp.get("channel_values", {}).items()
|
|
179
|
-
}
|
|
180
|
-
pending = []
|
|
224
|
+
pending: list[Any] = []
|
|
181
225
|
for item in cp.get("pending_sends", []) or []:
|
|
182
226
|
try:
|
|
183
227
|
channel, value = item
|
|
184
|
-
pending.append({"channel": channel, **self._encode_typed(value)})
|
|
185
228
|
except Exception:
|
|
229
|
+
pending.append(item)
|
|
186
230
|
continue
|
|
231
|
+
pending.append([channel, self._safe_dump(value)])
|
|
187
232
|
return {
|
|
188
233
|
"v": cp["v"],
|
|
189
234
|
"id": cp["id"],
|
|
190
235
|
"ts": cp["ts"],
|
|
191
|
-
"channelValues": channel_values,
|
|
236
|
+
"channelValues": {k: self._safe_dump(v) for k, v in cp["channel_values"].items()},
|
|
192
237
|
"channelVersions": cp["channel_versions"],
|
|
193
238
|
"versionsSeen": cp["versions_seen"],
|
|
194
239
|
"pendingSends": pending,
|
|
195
240
|
}
|
|
196
241
|
|
|
197
242
|
def _decode_cp(self, raw: Dict[str, Any]) -> Checkpoint:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
ps_raw = raw.get("pendingSends") or []
|
|
201
|
-
pending_sends = []
|
|
202
|
-
for obj in ps_raw:
|
|
203
|
-
# ожидаем {channel, type, blob}
|
|
243
|
+
pending_sends: list[Tuple[str, Any]] = []
|
|
244
|
+
for obj in raw.get("pendingSends", []) or []:
|
|
204
245
|
if isinstance(obj, dict) and "channel" in obj:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
246
|
+
channel = obj["channel"]
|
|
247
|
+
value_payload: Any = obj.get("value")
|
|
248
|
+
if value_payload is None and all(k in obj for k in TYPED_KEYS):
|
|
249
|
+
value_payload = {k: obj[k] for k in TYPED_KEYS}
|
|
250
|
+
pending_sends.append((channel, self._safe_load(value_payload)))
|
|
251
|
+
elif isinstance(obj, (list, tuple)) and len(obj) >= 2:
|
|
252
|
+
channel = obj[0]
|
|
253
|
+
value_payload = obj[1]
|
|
254
|
+
pending_sends.append((channel, self._safe_load(value_payload)))
|
|
255
|
+
else:
|
|
256
|
+
pending_sends.append(obj) # сохраняем как есть, если формат неизвестен
|
|
213
257
|
return Checkpoint(
|
|
214
258
|
v=raw["v"],
|
|
215
259
|
id=raw["id"],
|
|
216
260
|
ts=raw["ts"],
|
|
217
|
-
channel_values=
|
|
261
|
+
channel_values={k: self._safe_load(v) for k, v in raw["channelValues"].items()},
|
|
218
262
|
channel_versions=raw["channelVersions"],
|
|
219
263
|
versions_seen=raw["versionsSeen"],
|
|
220
264
|
pending_sends=pending_sends,
|
|
@@ -238,15 +282,22 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
238
282
|
"thread_id": raw.get("threadId"),
|
|
239
283
|
"thread_ts": raw.get("threadTs"),
|
|
240
284
|
"checkpoint_ns": raw.get("checkpointNs"),
|
|
241
|
-
"checkpoint_id": raw.get("checkpointId")
|
|
285
|
+
"checkpoint_id": raw.get("checkpointId")
|
|
242
286
|
}
|
|
243
287
|
|
|
244
|
-
# metadata (de)ser
|
|
288
|
+
# metadata (de)ser
|
|
245
289
|
def _enc_meta(self, md: CheckpointMetadata) -> CheckpointMetadata:
|
|
246
|
-
|
|
290
|
+
if not md:
|
|
291
|
+
return {}
|
|
292
|
+
out: CheckpointMetadata = {}
|
|
293
|
+
for k, v in md.items():
|
|
294
|
+
out[k] = self._enc_meta(v) if isinstance(v, dict) else self._safe_dump(v) # type: ignore[assignment]
|
|
295
|
+
return out
|
|
247
296
|
|
|
248
297
|
def _dec_meta(self, md: Any) -> Any:
|
|
249
|
-
|
|
298
|
+
if isinstance(md, dict):
|
|
299
|
+
return {k: self._dec_meta(v) for k, v in md.items()}
|
|
300
|
+
return self._safe_load(md)
|
|
250
301
|
|
|
251
302
|
# ------------------------ HTTP wrapper ---------------------------
|
|
252
303
|
async def _http(self, method: str, path: str, **kw) -> httpx.Response:
|
|
@@ -254,36 +305,39 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
254
305
|
payload = kw.pop("json")
|
|
255
306
|
kw["data"] = orjson.dumps(payload)
|
|
256
307
|
logger.debug("AGW HTTP payload: %s", kw["data"].decode())
|
|
308
|
+
|
|
257
309
|
return await self._client.request(method, path, **kw)
|
|
258
310
|
|
|
259
311
|
# -------------------- api -> CheckpointTuple ----------------------
|
|
260
312
|
def _to_tuple(self, node: Dict[str, Any]) -> CheckpointTuple:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
313
|
+
pending = None
|
|
314
|
+
if node.get("pendingWrites"):
|
|
315
|
+
pending = []
|
|
316
|
+
for w in node["pendingWrites"]:
|
|
317
|
+
if isinstance(w, dict):
|
|
318
|
+
first = w.get("first")
|
|
319
|
+
second = w.get("second")
|
|
320
|
+
third = w.get("third")
|
|
321
|
+
if third is None and isinstance(second, dict) and all(
|
|
322
|
+
k in second for k in TYPED_KEYS
|
|
323
|
+
):
|
|
324
|
+
third = second
|
|
325
|
+
pending.append((first, second, self._safe_load(third)))
|
|
273
326
|
elif isinstance(w, (list, tuple)):
|
|
274
|
-
|
|
275
|
-
first,
|
|
276
|
-
|
|
277
|
-
|
|
327
|
+
if len(w) == 3:
|
|
328
|
+
first, second, third = w
|
|
329
|
+
elif len(w) == 2:
|
|
330
|
+
first, second = w
|
|
331
|
+
third = None
|
|
332
|
+
else:
|
|
278
333
|
continue
|
|
279
|
-
|
|
280
|
-
|
|
334
|
+
pending.append((first, second, self._safe_load(third)))
|
|
281
335
|
return CheckpointTuple(
|
|
282
336
|
config=self._decode_config(node.get("config")),
|
|
283
337
|
checkpoint=self._decode_cp(node["checkpoint"]),
|
|
284
338
|
metadata=self._dec_meta(node.get("metadata")),
|
|
285
339
|
parent_config=self._decode_config(node.get("parentConfig")),
|
|
286
|
-
pending_writes=
|
|
340
|
+
pending_writes=pending,
|
|
287
341
|
)
|
|
288
342
|
|
|
289
343
|
# =================================================================
|
|
@@ -292,7 +346,7 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
292
346
|
async def aget_tuple(self, cfg: RunnableConfig) -> CheckpointTuple | None:
|
|
293
347
|
cid = get_checkpoint_id(cfg)
|
|
294
348
|
api_cfg = self._to_api_config(cfg)
|
|
295
|
-
tid = api_cfg
|
|
349
|
+
tid = api_cfg["threadId"]
|
|
296
350
|
|
|
297
351
|
if cid:
|
|
298
352
|
path = f"/checkpoint/{tid}/{cid}"
|
|
@@ -304,7 +358,9 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
304
358
|
resp = await self._http("GET", path, params=params)
|
|
305
359
|
logger.debug("AGW aget_tuple response: %s", resp.text)
|
|
306
360
|
|
|
307
|
-
if not resp.text
|
|
361
|
+
if not resp.text:
|
|
362
|
+
return None
|
|
363
|
+
if resp.status_code in (404, 406):
|
|
308
364
|
return None
|
|
309
365
|
resp.raise_for_status()
|
|
310
366
|
return self._to_tuple(resp.json())
|
|
@@ -339,7 +395,7 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
339
395
|
payload = {
|
|
340
396
|
"config": self._to_api_config(cfg),
|
|
341
397
|
"checkpoint": self._encode_cp(cp),
|
|
342
|
-
"metadata": get_checkpoint_metadata(cfg, metadata),
|
|
398
|
+
"metadata": self._enc_meta(get_checkpoint_metadata(cfg, metadata)),
|
|
343
399
|
"newVersions": new_versions,
|
|
344
400
|
}
|
|
345
401
|
resp = await self._http("POST", "/checkpoint", json=payload)
|
|
@@ -354,7 +410,7 @@ class AsyncAGWCheckpointSaver(BaseCheckpointSaver):
|
|
|
354
410
|
task_id: str,
|
|
355
411
|
task_path: str = "",
|
|
356
412
|
) -> None:
|
|
357
|
-
enc = [{"first": ch, "second": self.
|
|
413
|
+
enc = [{"first": ch, "second": self._safe_dump(v)} for ch, v in writes]
|
|
358
414
|
payload = {
|
|
359
415
|
"config": self._to_api_config(cfg),
|
|
360
416
|
"writes": enc,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
agent_lab_sdk/__init__.py,sha256=1Dlmv-wuz1QuciymKtYtX7jXzr_fkeGTe7aENfEDl3E,108
|
|
2
2
|
agent_lab_sdk/langgraph/checkpoint/__init__.py,sha256=DnKwR1LwbaQ3qhb124lE-tnojrUIVcCdNzHEHwgpL5M,86
|
|
3
|
-
agent_lab_sdk/langgraph/checkpoint/agw_saver.py,sha256=
|
|
3
|
+
agent_lab_sdk/langgraph/checkpoint/agw_saver.py,sha256=K07scbnVV_PT2zbn0kH2lk-Jl36ZVQDng_Nl16sR8Nc,18144
|
|
4
4
|
agent_lab_sdk/langgraph/checkpoint/serde.py,sha256=UTSYbTbhBeL1CAr-XMbaH3SSIx9TeiC7ak22duXvqkw,5175
|
|
5
5
|
agent_lab_sdk/llm/__init__.py,sha256=Yo9MbYdHS1iX05A9XiJGwWN1Hm4IARGav9mNFPrtDeA,376
|
|
6
6
|
agent_lab_sdk/llm/agw_token_manager.py,sha256=_bPPI8muaEa6H01P8hHQOJHiiivaLd8N_d3OT9UT_80,4787
|
|
@@ -14,8 +14,8 @@ agent_lab_sdk/schema/input_types.py,sha256=e75nRW7Dz_RHk5Yia8DkFfbqMafsLQsQrJPfz
|
|
|
14
14
|
agent_lab_sdk/schema/log_message.py,sha256=nadi6lZGRuDSPmfbYs9QPpRJUT9Pfy8Y7pGCvyFF5Mw,638
|
|
15
15
|
agent_lab_sdk/storage/__init__.py,sha256=ik1_v1DMTwehvcAEXIYxuvLuCjJCa3y5qAuJqoQpuSA,81
|
|
16
16
|
agent_lab_sdk/storage/storage.py,sha256=ELpt7GRwFD-aWa6ctinfA_QwcvzWLvKS0Wz8FlxVqAs,2075
|
|
17
|
-
agent_lab_sdk-0.1.
|
|
18
|
-
agent_lab_sdk-0.1.
|
|
19
|
-
agent_lab_sdk-0.1.
|
|
20
|
-
agent_lab_sdk-0.1.
|
|
21
|
-
agent_lab_sdk-0.1.
|
|
17
|
+
agent_lab_sdk-0.1.37.dist-info/licenses/LICENSE,sha256=_TRXHkF3S9ilWBPdZcHLI_S-PRjK0L_SeOb2pcPAdV4,417
|
|
18
|
+
agent_lab_sdk-0.1.37.dist-info/METADATA,sha256=XTRYyQQVXpDXxU4BkZvuAnsbZJsr-S5RuPKiDP0WKTc,17911
|
|
19
|
+
agent_lab_sdk-0.1.37.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
20
|
+
agent_lab_sdk-0.1.37.dist-info/top_level.txt,sha256=E1efqkJ89KNmPBWdLzdMHeVtH0dYyCo4fhnSb81_15I,14
|
|
21
|
+
agent_lab_sdk-0.1.37.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|