langgraph-api 0.2.69__tar.gz → 0.2.70__tar.gz
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 langgraph-api might be problematic. Click here for more details.
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/PKG-INFO +1 -1
- langgraph_api-0.2.70/langgraph_api/__init__.py +1 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/errors.py +6 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/worker.py +60 -86
- langgraph_api-0.2.69/langgraph_api/__init__.py +0 -1
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/.gitignore +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/LICENSE +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/Makefile +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/README.md +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/benchmark/.gitignore +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/benchmark/Makefile +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/benchmark/README.md +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/benchmark/burst.js +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/benchmark/weather.js +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/constraints.txt +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/forbidden.txt +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/healthcheck.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/api/__init__.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/api/assistants.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/api/mcp.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/api/meta.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/api/runs.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/api/store.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/api/threads.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/api/ui.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/asgi_transport.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/auth/custom.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/cli.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/command.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/config.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/cron_scheduler.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/graph.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/http.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/.prettierrc +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/__init__.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/client.http.mts +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/client.mts +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/package.json +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/src/graph.mts +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/src/load.hooks.mjs +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/src/preload.mjs +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/src/utils/files.mts +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/sse.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/tsconfig.json +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/ui.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/js/yarn.lock +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/metadata.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/middleware/__init__.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/middleware/request_id.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/models/run.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/queue_entrypoint.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/route.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/schema.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/server.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/state.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/store.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/stream.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/thread_ttl.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/tunneling/cloudflare.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/utils.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_api/webhook.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_runtime/__init__.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_runtime/checkpoint.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_runtime/database.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_runtime/lifespan.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_runtime/metrics.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_runtime/ops.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_runtime/queue.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_runtime/retry.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/langgraph_runtime/store.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/logging.json +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/openapi.json +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/pyproject.toml +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/scripts/create_license.py +0 -0
- {langgraph_api-0.2.69 → langgraph_api-0.2.70}/uv.lock +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.70"
|
|
@@ -50,3 +50,9 @@ class UserInterrupt(Exception):
|
|
|
50
50
|
class UserRollback(UserInterrupt):
|
|
51
51
|
def __init__(self):
|
|
52
52
|
super().__init__("User requested rollback of the run")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class UserTimeout(Exception):
|
|
56
|
+
def __init__(self, timeout_error: TimeoutError):
|
|
57
|
+
super().__init__(timeout_error)
|
|
58
|
+
self.timeout_error = timeout_error
|
|
@@ -16,12 +16,12 @@ from langgraph_api.config import (
|
|
|
16
16
|
BG_JOB_MAX_RETRIES,
|
|
17
17
|
BG_JOB_TIMEOUT_SECS,
|
|
18
18
|
)
|
|
19
|
-
from langgraph_api.errors import UserInterrupt, UserRollback
|
|
19
|
+
from langgraph_api.errors import UserInterrupt, UserRollback, UserTimeout
|
|
20
20
|
from langgraph_api.js.errors import RemoteException
|
|
21
21
|
from langgraph_api.metadata import incr_runs
|
|
22
22
|
from langgraph_api.schema import Run
|
|
23
23
|
from langgraph_api.state import state_snapshot_to_thread_state
|
|
24
|
-
from langgraph_api.stream import astream_state, consume
|
|
24
|
+
from langgraph_api.stream import AnyStream, astream_state, consume
|
|
25
25
|
from langgraph_api.utils import with_user
|
|
26
26
|
from langgraph_runtime.database import connect
|
|
27
27
|
from langgraph_runtime.ops import Runs, Threads
|
|
@@ -79,8 +79,11 @@ async def worker(
|
|
|
79
79
|
"__request_start_time_ms__"
|
|
80
80
|
)
|
|
81
81
|
after_seconds = run["kwargs"]["config"]["configurable"].get("__after_seconds__", 0)
|
|
82
|
+
run_started_at_dt = datetime.now(UTC)
|
|
83
|
+
run_started_at = run_started_at_dt.isoformat()
|
|
84
|
+
run_ended_at_dt: datetime | None = None
|
|
82
85
|
run_ended_at: str | None = None
|
|
83
|
-
|
|
86
|
+
|
|
84
87
|
# Note that "created_at" is inclusive of the `after_seconds`
|
|
85
88
|
run_creation_ms = (
|
|
86
89
|
int(
|
|
@@ -103,13 +106,13 @@ async def worker(
|
|
|
103
106
|
"request_id": _get_request_id(run),
|
|
104
107
|
}
|
|
105
108
|
)
|
|
106
|
-
|
|
109
|
+
run_stream_started_at_dt = datetime.now(UTC)
|
|
107
110
|
await logger.ainfo(
|
|
108
111
|
"Starting background run",
|
|
109
|
-
run_started_at=run_started_at
|
|
112
|
+
run_started_at=run_started_at,
|
|
110
113
|
run_creation_ms=run_creation_ms,
|
|
111
|
-
run_queue_ms=ms(
|
|
112
|
-
run_stream_start_ms=ms(
|
|
114
|
+
run_queue_ms=ms(run_started_at_dt, run["created_at"]),
|
|
115
|
+
run_stream_start_ms=ms(run_stream_started_at_dt, run_started_at_dt),
|
|
113
116
|
)
|
|
114
117
|
|
|
115
118
|
def on_checkpoint(checkpoint_arg: CheckpointPayload):
|
|
@@ -123,6 +126,21 @@ async def worker(
|
|
|
123
126
|
task.update(task_result)
|
|
124
127
|
break
|
|
125
128
|
|
|
129
|
+
# Wrap the graph execution to separate user errors from server errors
|
|
130
|
+
async def wrap_user_errors(stream: AnyStream, run_id: str, resumable: bool):
|
|
131
|
+
try:
|
|
132
|
+
await consume(stream, run_id, resumable)
|
|
133
|
+
except Exception as e:
|
|
134
|
+
logger.info(
|
|
135
|
+
f"Run encountered an error in graph: {type(e)}({e})",
|
|
136
|
+
exc_info=e,
|
|
137
|
+
)
|
|
138
|
+
# TimeoutError is a special case where we rely on asyncio.wait_for to timeout runs
|
|
139
|
+
# Convert user TimeoutErrors to a custom class so we can distinguish and later convert back
|
|
140
|
+
if isinstance(e, TimeoutError):
|
|
141
|
+
raise UserTimeout(e) from e
|
|
142
|
+
raise
|
|
143
|
+
|
|
126
144
|
async with Runs.enter(run_id, main_loop) as done:
|
|
127
145
|
# attempt the run
|
|
128
146
|
try:
|
|
@@ -163,25 +181,9 @@ async def worker(
|
|
|
163
181
|
on_task_result=on_task_result,
|
|
164
182
|
)
|
|
165
183
|
await asyncio.wait_for(
|
|
166
|
-
|
|
184
|
+
wrap_user_errors(stream, run_id, resumable),
|
|
167
185
|
BG_JOB_TIMEOUT_SECS,
|
|
168
186
|
)
|
|
169
|
-
run_ended_at_dt = datetime.now(UTC)
|
|
170
|
-
run_ended_at = run_ended_at_dt.isoformat()
|
|
171
|
-
await logger.ainfo(
|
|
172
|
-
"Background run succeeded",
|
|
173
|
-
run_id=str(run_id),
|
|
174
|
-
run_attempt=attempt,
|
|
175
|
-
run_created_at=run_created_at,
|
|
176
|
-
run_started_at=run_started_at.isoformat(),
|
|
177
|
-
run_ended_at=run_ended_at,
|
|
178
|
-
run_exec_ms=ms(run_ended_at_dt, run_started_at),
|
|
179
|
-
run_completed_in_ms=(
|
|
180
|
-
int((run_ended_at_dt.timestamp() * 1_000) - request_created_at)
|
|
181
|
-
if request_created_at is not None
|
|
182
|
-
else None
|
|
183
|
-
),
|
|
184
|
-
)
|
|
185
187
|
except (Exception, asyncio.CancelledError) as ee:
|
|
186
188
|
exception = ee
|
|
187
189
|
except BaseException as eee:
|
|
@@ -192,11 +194,33 @@ async def worker(
|
|
|
192
194
|
exception=str(eee),
|
|
193
195
|
)
|
|
194
196
|
raise
|
|
197
|
+
finally:
|
|
198
|
+
run_ended_at_dt = datetime.now(UTC)
|
|
199
|
+
run_ended_at = run_ended_at_dt.isoformat()
|
|
195
200
|
|
|
196
201
|
# handle exceptions and set status
|
|
197
202
|
async with connect() as conn:
|
|
203
|
+
log_info = {
|
|
204
|
+
"run_id": str(run_id),
|
|
205
|
+
"run_attempt": attempt,
|
|
206
|
+
"run_created_at": run_created_at,
|
|
207
|
+
"run_started_at": run_started_at,
|
|
208
|
+
"run_ended_at": run_ended_at,
|
|
209
|
+
"run_exec_ms": ms(run_ended_at_dt, run_started_at_dt),
|
|
210
|
+
"run_completed_in_ms": (
|
|
211
|
+
int((run_ended_at_dt.timestamp() * 1_000) - request_created_at)
|
|
212
|
+
if request_created_at is not None
|
|
213
|
+
else None
|
|
214
|
+
),
|
|
215
|
+
}
|
|
216
|
+
|
|
198
217
|
if exception is None:
|
|
199
218
|
status = "success"
|
|
219
|
+
|
|
220
|
+
await logger.ainfo(
|
|
221
|
+
"Background run succeeded",
|
|
222
|
+
**log_info,
|
|
223
|
+
)
|
|
200
224
|
# If a stateful run succeeded but no checkpoint was returned, likely
|
|
201
225
|
# there was a retriable exception that resumed right at the end
|
|
202
226
|
if checkpoint is None and not temporary:
|
|
@@ -222,56 +246,28 @@ async def worker(
|
|
|
222
246
|
)
|
|
223
247
|
elif isinstance(exception, TimeoutError):
|
|
224
248
|
status = "timeout"
|
|
225
|
-
run_ended_at = datetime.now(UTC).isoformat()
|
|
226
249
|
await logger.awarning(
|
|
227
250
|
"Background run timed out",
|
|
228
|
-
|
|
229
|
-
run_attempt=attempt,
|
|
230
|
-
run_created_at=run_created_at,
|
|
231
|
-
run_started_at=run_started_at.isoformat(),
|
|
232
|
-
run_ended_at=run_ended_at,
|
|
233
|
-
run_exec_ms=ms(datetime.now(UTC), run_started_at),
|
|
234
|
-
run_completed_in_ms=(
|
|
235
|
-
int((run_ended_at_dt.timestamp() * 1_000) - request_created_at)
|
|
236
|
-
if request_created_at is not None
|
|
237
|
-
else None
|
|
238
|
-
),
|
|
251
|
+
**log_info,
|
|
239
252
|
)
|
|
240
253
|
await Threads.set_joint_status(
|
|
241
254
|
conn, run["thread_id"], run_id, status, checkpoint=checkpoint
|
|
242
255
|
)
|
|
243
256
|
elif isinstance(exception, UserRollback):
|
|
244
257
|
status = "rollback"
|
|
245
|
-
run_ended_at_dt = datetime.now(UTC)
|
|
246
|
-
run_ended_at = run_ended_at_dt.isoformat()
|
|
247
258
|
try:
|
|
248
259
|
await Threads.set_joint_status(
|
|
249
260
|
conn, run["thread_id"], run_id, status, checkpoint=checkpoint
|
|
250
261
|
)
|
|
251
262
|
await logger.ainfo(
|
|
252
263
|
"Background run rolled back",
|
|
253
|
-
|
|
254
|
-
run_attempt=attempt,
|
|
255
|
-
run_created_at=run_created_at,
|
|
256
|
-
run_started_at=run_started_at.isoformat(),
|
|
257
|
-
run_ended_at=run_ended_at,
|
|
258
|
-
run_exec_ms=ms(run_ended_at_dt, run_started_at),
|
|
259
|
-
run_completed_in_ms=(
|
|
260
|
-
int(
|
|
261
|
-
(run_ended_at_dt.timestamp() * 1_000)
|
|
262
|
-
- request_created_at
|
|
263
|
-
)
|
|
264
|
-
if request_created_at is not None
|
|
265
|
-
else None
|
|
266
|
-
),
|
|
264
|
+
**log_info,
|
|
267
265
|
)
|
|
268
266
|
except HTTPException as e:
|
|
269
267
|
if e.status_code == 404:
|
|
270
268
|
await logger.ainfo(
|
|
271
269
|
"Ignoring rollback error for missing run",
|
|
272
|
-
|
|
273
|
-
run_attempt=attempt,
|
|
274
|
-
run_created_at=run_created_at,
|
|
270
|
+
**log_info,
|
|
275
271
|
)
|
|
276
272
|
else:
|
|
277
273
|
raise
|
|
@@ -279,54 +275,32 @@ async def worker(
|
|
|
279
275
|
checkpoint = None # reset the checkpoint
|
|
280
276
|
elif isinstance(exception, UserInterrupt):
|
|
281
277
|
status = "interrupted"
|
|
282
|
-
run_ended_at_dt = datetime.now(UTC)
|
|
283
|
-
run_ended_at = run_ended_at_dt.isoformat()
|
|
284
278
|
await logger.ainfo(
|
|
285
279
|
"Background run interrupted",
|
|
286
|
-
|
|
287
|
-
run_attempt=attempt,
|
|
288
|
-
run_created_at=run_created_at,
|
|
289
|
-
run_started_at=run_started_at.isoformat(),
|
|
290
|
-
run_ended_at=run_ended_at,
|
|
291
|
-
run_exec_ms=ms(run_ended_at_dt, run_started_at),
|
|
292
|
-
run_completed_in_ms=(
|
|
293
|
-
int((run_ended_at_dt.timestamp() * 1_000) - request_created_at)
|
|
294
|
-
if request_created_at is not None
|
|
295
|
-
else None
|
|
296
|
-
),
|
|
280
|
+
**log_info,
|
|
297
281
|
)
|
|
298
282
|
await Threads.set_joint_status(
|
|
299
283
|
conn, run["thread_id"], run_id, status, checkpoint, exception
|
|
300
284
|
)
|
|
301
285
|
elif isinstance(exception, ALL_RETRIABLE_EXCEPTIONS):
|
|
302
286
|
status = "retry"
|
|
303
|
-
run_ended_at_dt = datetime.now(UTC)
|
|
304
|
-
run_ended_at = run_ended_at_dt.isoformat()
|
|
305
287
|
await logger.awarning(
|
|
306
288
|
f"Background run failed, will retry. Exception: {type(exception)}({exception})",
|
|
307
|
-
|
|
308
|
-
run_id=str(run_id),
|
|
309
|
-
run_attempt=attempt,
|
|
310
|
-
run_created_at=run_created_at,
|
|
311
|
-
run_started_at=run_started_at.isoformat(),
|
|
312
|
-
run_ended_at=run_ended_at,
|
|
313
|
-
run_exec_ms=ms(run_ended_at_dt, run_started_at),
|
|
289
|
+
**log_info,
|
|
314
290
|
)
|
|
315
291
|
# Don't update thread status yet.
|
|
316
292
|
await Runs.set_status(conn, run_id, "pending")
|
|
317
293
|
else:
|
|
318
294
|
status = "error"
|
|
319
|
-
|
|
320
|
-
|
|
295
|
+
|
|
296
|
+
# Convert UserTimeout to TimeoutError for customers
|
|
297
|
+
if isinstance(exception, UserTimeout):
|
|
298
|
+
exception = exception.timeout_error
|
|
299
|
+
|
|
321
300
|
await logger.aexception(
|
|
322
301
|
f"Background run failed. Exception: {type(exception)}({exception})",
|
|
323
302
|
exc_info=not isinstance(exception, RemoteException),
|
|
324
|
-
|
|
325
|
-
run_attempt=attempt,
|
|
326
|
-
run_created_at=run_created_at,
|
|
327
|
-
run_started_at=run_started_at.isoformat(),
|
|
328
|
-
run_ended_at=run_ended_at,
|
|
329
|
-
run_exec_ms=ms(run_ended_at_dt, run_started_at),
|
|
303
|
+
**log_info,
|
|
330
304
|
)
|
|
331
305
|
await Threads.set_joint_status(
|
|
332
306
|
conn, run["thread_id"], run_id, status, checkpoint, exception
|
|
@@ -363,7 +337,7 @@ async def worker(
|
|
|
363
337
|
exception=exception,
|
|
364
338
|
run=run,
|
|
365
339
|
webhook=webhook,
|
|
366
|
-
run_started_at=run_started_at
|
|
340
|
+
run_started_at=run_started_at,
|
|
367
341
|
run_ended_at=run_ended_at,
|
|
368
342
|
)
|
|
369
343
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.69"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|