langgraph-api 0.0.8__tar.gz → 0.0.9__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.0.8 → langgraph_api-0.0.9}/PKG-INFO +2 -2
- langgraph_api-0.0.9/langgraph_api/api/openapi.py +69 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/api/runs.py +70 -36
- langgraph_api-0.0.9/langgraph_api/auth/custom.py +520 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/auth/middleware.py +8 -3
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/cli.py +47 -1
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/config.py +24 -0
- langgraph_api-0.0.9/langgraph_api/cron_scheduler.py +65 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/graph.py +0 -11
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/models/run.py +77 -19
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/route.py +2 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/utils.py +32 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_storage/checkpoint.py +16 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_storage/database.py +17 -1
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_storage/ops.py +495 -69
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/pyproject.toml +4 -4
- langgraph_api-0.0.8/langgraph_api/api/openapi.py +0 -32
- langgraph_api-0.0.8/langgraph_api/cron_scheduler.py +0 -60
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/LICENSE +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/README.md +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/__init__.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/api/__init__.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/api/assistants.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/api/meta.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/api/store.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/api/threads.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/http.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/http_logger.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/client.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/package.json +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/server_sent_events.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/src/graph.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/src/hooks.mjs +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/src/parser/parser.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/src/parser/parser.worker.mjs +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/src/schema/types.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/src/schema/types.template.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/api.test.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/compose-postgres.yml +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/graphs/.gitignore +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/graphs/agent.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/graphs/error.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/graphs/langgraph.json +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/graphs/nested.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/graphs/package.json +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/graphs/weather.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/graphs/yarn.lock +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/parser.test.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/tests/utils.mts +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/js/yarn.lock +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/lifespan.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/metadata.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/queue.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/schema.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/server.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/state.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/stream.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_license/middleware.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_storage/__init__.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_storage/queue.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_storage/retry.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_storage/store.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/langgraph_storage/ttl_dict.py +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/logging.json +0 -0
- {langgraph_api-0.0.8 → langgraph_api-0.0.9}/openapi.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: langgraph-api
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.9
|
|
4
4
|
Summary:
|
|
5
5
|
License: Elastic-2.0
|
|
6
6
|
Author: Nuno Campos
|
|
@@ -16,7 +16,7 @@ Requires-Dist: jsonschema-rs (>=0.25.0,<0.26.0)
|
|
|
16
16
|
Requires-Dist: langchain-core (>=0.2.38,<0.4.0)
|
|
17
17
|
Requires-Dist: langgraph (>=0.2.56,<0.3.0)
|
|
18
18
|
Requires-Dist: langgraph-checkpoint (>=2.0.7,<3.0)
|
|
19
|
-
Requires-Dist: langsmith (>=0.1.63,<0.
|
|
19
|
+
Requires-Dist: langsmith (>=0.1.63,<0.3.0)
|
|
20
20
|
Requires-Dist: orjson (>=3.10.1)
|
|
21
21
|
Requires-Dist: pyjwt (>=2.9.0,<3.0.0)
|
|
22
22
|
Requires-Dist: sse-starlette (>=2.1.0,<3.0.0)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from functools import lru_cache
|
|
3
|
+
|
|
4
|
+
import orjson
|
|
5
|
+
|
|
6
|
+
from langgraph_api.config import LANGGRAPH_AUTH, LANGGRAPH_AUTH_TYPE
|
|
7
|
+
from langgraph_api.graph import GRAPHS
|
|
8
|
+
from langgraph_api.validation import openapi
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@lru_cache(maxsize=1)
|
|
14
|
+
def get_openapi_spec() -> str:
|
|
15
|
+
# patch the graph_id enums
|
|
16
|
+
graph_ids = list(GRAPHS.keys())
|
|
17
|
+
for schema in (
|
|
18
|
+
"Assistant",
|
|
19
|
+
"AssistantCreate",
|
|
20
|
+
"AssistantPatch",
|
|
21
|
+
"GraphSchema",
|
|
22
|
+
"AssistantSearchRequest",
|
|
23
|
+
):
|
|
24
|
+
openapi["components"]["schemas"][schema]["properties"]["graph_id"]["enum"] = (
|
|
25
|
+
graph_ids
|
|
26
|
+
)
|
|
27
|
+
# patch the auth schemes
|
|
28
|
+
if LANGGRAPH_AUTH_TYPE == "langsmith":
|
|
29
|
+
openapi["security"] = [
|
|
30
|
+
{"x-api-key": []},
|
|
31
|
+
]
|
|
32
|
+
openapi["components"]["securitySchemes"] = {
|
|
33
|
+
"x-api-key": {"type": "apiKey", "in": "header", "name": "x-api-key"}
|
|
34
|
+
}
|
|
35
|
+
elif LANGGRAPH_AUTH_TYPE == "custom":
|
|
36
|
+
# Allow user to specify OpenAPI security configuration
|
|
37
|
+
if isinstance(LANGGRAPH_AUTH, dict) and "openapi" in LANGGRAPH_AUTH:
|
|
38
|
+
openapi_config = LANGGRAPH_AUTH["openapi"]
|
|
39
|
+
if isinstance(openapi_config, dict):
|
|
40
|
+
# Add security schemes
|
|
41
|
+
if "securitySchemes" in openapi_config:
|
|
42
|
+
openapi["components"]["securitySchemes"] = openapi_config[
|
|
43
|
+
"securitySchemes"
|
|
44
|
+
]
|
|
45
|
+
elif "security_schemes" in openapi_config:
|
|
46
|
+
# For our sorry python users
|
|
47
|
+
openapi["components"]["securitySchemes"] = openapi_config[
|
|
48
|
+
"security_schemes"
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
# Add default security if specified
|
|
52
|
+
if "security" in openapi_config:
|
|
53
|
+
openapi["security"] = openapi_config["security"]
|
|
54
|
+
|
|
55
|
+
if "paths" in openapi_config:
|
|
56
|
+
for path, methods in openapi_config["paths"].items():
|
|
57
|
+
if path in openapi["paths"]:
|
|
58
|
+
openapi_path = openapi["paths"][path]
|
|
59
|
+
for method, security in methods.items():
|
|
60
|
+
method = method.lower()
|
|
61
|
+
if method in openapi_path:
|
|
62
|
+
openapi_path[method]["security"] = security
|
|
63
|
+
else:
|
|
64
|
+
logger.warning(
|
|
65
|
+
"Custom authentication is enabled but no OpenAPI security configuration was provided. "
|
|
66
|
+
"API documentation will not show authentication requirements. "
|
|
67
|
+
"Add 'openapi' section to auth section of your `langgraph.json` file to specify security schemes."
|
|
68
|
+
)
|
|
69
|
+
return orjson.dumps(openapi)
|
|
@@ -24,13 +24,6 @@ from langgraph_storage.ops import Crons, Runs, Threads
|
|
|
24
24
|
from langgraph_storage.retry import retry_db
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def get_user_id(request: ApiRequest) -> str | None:
|
|
28
|
-
try:
|
|
29
|
-
return request.user.display_name
|
|
30
|
-
except AssertionError:
|
|
31
|
-
return None
|
|
32
|
-
|
|
33
|
-
|
|
34
27
|
@retry_db
|
|
35
28
|
async def create_run(request: ApiRequest):
|
|
36
29
|
"""Create a run."""
|
|
@@ -41,7 +34,6 @@ async def create_run(request: ApiRequest):
|
|
|
41
34
|
conn,
|
|
42
35
|
thread_id,
|
|
43
36
|
payload,
|
|
44
|
-
get_user_id(request),
|
|
45
37
|
request.headers,
|
|
46
38
|
)
|
|
47
39
|
return ApiResponse(run)
|
|
@@ -53,7 +45,10 @@ async def create_stateless_run(request: ApiRequest):
|
|
|
53
45
|
payload = await request.json(RunCreateStateless)
|
|
54
46
|
async with connect() as conn:
|
|
55
47
|
run = await create_valid_run(
|
|
56
|
-
conn,
|
|
48
|
+
conn,
|
|
49
|
+
None,
|
|
50
|
+
payload,
|
|
51
|
+
request.headers,
|
|
57
52
|
)
|
|
58
53
|
return ApiResponse(run)
|
|
59
54
|
|
|
@@ -66,12 +61,15 @@ async def create_stateless_run_batch(request: ApiRequest):
|
|
|
66
61
|
barrier = asyncio.Barrier(len(batch_payload))
|
|
67
62
|
coros = [
|
|
68
63
|
create_valid_run(
|
|
69
|
-
conn,
|
|
64
|
+
conn,
|
|
65
|
+
None,
|
|
66
|
+
payload,
|
|
67
|
+
request.headers,
|
|
68
|
+
barrier,
|
|
70
69
|
)
|
|
71
70
|
for payload in batch_payload
|
|
72
71
|
]
|
|
73
72
|
runs = await asyncio.gather(*coros)
|
|
74
|
-
|
|
75
73
|
return ApiResponse(runs)
|
|
76
74
|
|
|
77
75
|
|
|
@@ -91,7 +89,6 @@ async def stream_run(
|
|
|
91
89
|
conn,
|
|
92
90
|
thread_id,
|
|
93
91
|
payload,
|
|
94
|
-
get_user_id(request),
|
|
95
92
|
request.headers,
|
|
96
93
|
run_id=run_id,
|
|
97
94
|
)
|
|
@@ -127,7 +124,6 @@ async def stream_run_stateless(
|
|
|
127
124
|
conn,
|
|
128
125
|
None,
|
|
129
126
|
payload,
|
|
130
|
-
get_user_id(request),
|
|
131
127
|
request.headers,
|
|
132
128
|
run_id=run_id,
|
|
133
129
|
)
|
|
@@ -165,7 +161,6 @@ async def wait_run(request: ApiRequest):
|
|
|
165
161
|
conn,
|
|
166
162
|
thread_id,
|
|
167
163
|
payload,
|
|
168
|
-
get_user_id(request),
|
|
169
164
|
request.headers,
|
|
170
165
|
run_id=run_id,
|
|
171
166
|
)
|
|
@@ -226,7 +221,6 @@ async def wait_run_stateless(request: ApiRequest):
|
|
|
226
221
|
conn,
|
|
227
222
|
None,
|
|
228
223
|
payload,
|
|
229
|
-
get_user_id(request),
|
|
230
224
|
request.headers,
|
|
231
225
|
run_id=run_id,
|
|
232
226
|
)
|
|
@@ -284,6 +278,7 @@ async def list_runs_http(
|
|
|
284
278
|
limit = int(request.query_params.get("limit", 10))
|
|
285
279
|
offset = int(request.query_params.get("offset", 0))
|
|
286
280
|
status = request.query_params.get("status")
|
|
281
|
+
|
|
287
282
|
async with connect() as conn, conn.pipeline():
|
|
288
283
|
thread, runs = await asyncio.gather(
|
|
289
284
|
Threads.get(conn, thread_id),
|
|
@@ -307,10 +302,15 @@ async def get_run_http(request: ApiRequest):
|
|
|
307
302
|
run_id = request.path_params["run_id"]
|
|
308
303
|
validate_uuid(thread_id, "Invalid thread ID: must be a UUID")
|
|
309
304
|
validate_uuid(run_id, "Invalid run ID: must be a UUID")
|
|
305
|
+
|
|
310
306
|
async with connect() as conn, conn.pipeline():
|
|
311
307
|
thread, run = await asyncio.gather(
|
|
312
308
|
Threads.get(conn, thread_id),
|
|
313
|
-
Runs.get(
|
|
309
|
+
Runs.get(
|
|
310
|
+
conn,
|
|
311
|
+
run_id,
|
|
312
|
+
thread_id=thread_id,
|
|
313
|
+
),
|
|
314
314
|
)
|
|
315
315
|
await fetchone(thread)
|
|
316
316
|
return ApiResponse(await fetchone(run))
|
|
@@ -323,7 +323,13 @@ async def join_run(request: ApiRequest):
|
|
|
323
323
|
run_id = request.path_params["run_id"]
|
|
324
324
|
validate_uuid(thread_id, "Invalid thread ID: must be a UUID")
|
|
325
325
|
validate_uuid(run_id, "Invalid run ID: must be a UUID")
|
|
326
|
-
|
|
326
|
+
|
|
327
|
+
return ApiResponse(
|
|
328
|
+
await Runs.join(
|
|
329
|
+
run_id,
|
|
330
|
+
thread_id=thread_id,
|
|
331
|
+
)
|
|
332
|
+
)
|
|
327
333
|
|
|
328
334
|
|
|
329
335
|
@retry_db
|
|
@@ -337,7 +343,9 @@ async def join_run_stream_endpoint(request: ApiRequest):
|
|
|
337
343
|
validate_uuid(run_id, "Invalid run ID: must be a UUID")
|
|
338
344
|
return EventSourceResponse(
|
|
339
345
|
Runs.Stream.join(
|
|
340
|
-
run_id,
|
|
346
|
+
run_id,
|
|
347
|
+
thread_id=thread_id,
|
|
348
|
+
cancel_on_disconnect=cancel_on_disconnect,
|
|
341
349
|
)
|
|
342
350
|
)
|
|
343
351
|
|
|
@@ -355,10 +363,19 @@ async def cancel_run(
|
|
|
355
363
|
wait = wait_str.lower() in {"true", "yes", "1"}
|
|
356
364
|
action_str = request.query_params.get("action", "interrupt")
|
|
357
365
|
action = action_str if action_str in {"interrupt", "rollback"} else "interrupt"
|
|
366
|
+
|
|
358
367
|
async with connect() as conn:
|
|
359
|
-
await Runs.cancel(
|
|
368
|
+
await Runs.cancel(
|
|
369
|
+
conn,
|
|
370
|
+
[run_id],
|
|
371
|
+
action=action,
|
|
372
|
+
thread_id=thread_id,
|
|
373
|
+
)
|
|
360
374
|
if wait:
|
|
361
|
-
await Runs.join(
|
|
375
|
+
await Runs.join(
|
|
376
|
+
run_id,
|
|
377
|
+
thread_id=thread_id,
|
|
378
|
+
)
|
|
362
379
|
return Response(status_code=204 if wait else 202)
|
|
363
380
|
|
|
364
381
|
|
|
@@ -369,8 +386,13 @@ async def delete_run(request: ApiRequest):
|
|
|
369
386
|
run_id = request.path_params["run_id"]
|
|
370
387
|
validate_uuid(thread_id, "Invalid thread ID: must be a UUID")
|
|
371
388
|
validate_uuid(run_id, "Invalid run ID: must be a UUID")
|
|
389
|
+
|
|
372
390
|
async with connect() as conn:
|
|
373
|
-
rid = await Runs.delete(
|
|
391
|
+
rid = await Runs.delete(
|
|
392
|
+
conn,
|
|
393
|
+
run_id,
|
|
394
|
+
thread_id=thread_id,
|
|
395
|
+
)
|
|
374
396
|
await fetchone(rid)
|
|
375
397
|
return Response(status_code=204)
|
|
376
398
|
|
|
@@ -383,7 +405,6 @@ async def create_cron(request: ApiRequest):
|
|
|
383
405
|
async with connect() as conn:
|
|
384
406
|
cron = await Crons.put(
|
|
385
407
|
conn,
|
|
386
|
-
user_id=get_user_id(request),
|
|
387
408
|
thread_id=None,
|
|
388
409
|
end_time=payload.get("end_time"),
|
|
389
410
|
schedule=payload.get("schedule"),
|
|
@@ -402,7 +423,6 @@ async def create_thread_cron(request: ApiRequest):
|
|
|
402
423
|
async with connect() as conn:
|
|
403
424
|
cron = await Crons.put(
|
|
404
425
|
conn,
|
|
405
|
-
user_id=get_user_id(request),
|
|
406
426
|
thread_id=thread_id,
|
|
407
427
|
end_time=payload.get("end_time"),
|
|
408
428
|
schedule=payload.get("schedule"),
|
|
@@ -418,7 +438,10 @@ async def delete_cron(request: ApiRequest):
|
|
|
418
438
|
validate_uuid(cron_id, "Invalid cron ID: must be a UUID")
|
|
419
439
|
|
|
420
440
|
async with connect() as conn:
|
|
421
|
-
cid = await Crons.delete(
|
|
441
|
+
cid = await Crons.delete(
|
|
442
|
+
conn,
|
|
443
|
+
cron_id=cron_id,
|
|
444
|
+
)
|
|
422
445
|
await fetchone(cid)
|
|
423
446
|
return Response(status_code=204)
|
|
424
447
|
|
|
@@ -431,6 +454,7 @@ async def search_crons(request: ApiRequest):
|
|
|
431
454
|
validate_uuid(assistant_id, "Invalid assistant ID: must be a UUID")
|
|
432
455
|
if thread_id := payload.get("thread_id"):
|
|
433
456
|
validate_uuid(thread_id, "Invalid thread ID: must be a UUID")
|
|
457
|
+
|
|
434
458
|
async with connect() as conn:
|
|
435
459
|
crons_iter = await Crons.search(
|
|
436
460
|
conn,
|
|
@@ -447,12 +471,16 @@ runs_routes = [
|
|
|
447
471
|
ApiRoute("/runs/wait", wait_run_stateless, methods=["POST"]),
|
|
448
472
|
ApiRoute("/runs", create_stateless_run, methods=["POST"]),
|
|
449
473
|
ApiRoute("/runs/batch", create_stateless_run_batch, methods=["POST"]),
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
474
|
+
(
|
|
475
|
+
ApiRoute("/runs/crons", create_cron, methods=["POST"])
|
|
476
|
+
if config.FF_CRONS_ENABLED and plus_features_enabled()
|
|
477
|
+
else None
|
|
478
|
+
),
|
|
479
|
+
(
|
|
480
|
+
ApiRoute("/runs/crons/search", search_crons, methods=["POST"])
|
|
481
|
+
if config.FF_CRONS_ENABLED and plus_features_enabled()
|
|
482
|
+
else None
|
|
483
|
+
),
|
|
456
484
|
ApiRoute("/threads/{thread_id}/runs/{run_id}/join", join_run, methods=["GET"]),
|
|
457
485
|
ApiRoute(
|
|
458
486
|
"/threads/{thread_id}/runs/{run_id}/stream",
|
|
@@ -465,13 +493,19 @@ runs_routes = [
|
|
|
465
493
|
ApiRoute("/threads/{thread_id}/runs/stream", stream_run, methods=["POST"]),
|
|
466
494
|
ApiRoute("/threads/{thread_id}/runs/wait", wait_run, methods=["POST"]),
|
|
467
495
|
ApiRoute("/threads/{thread_id}/runs", create_run, methods=["POST"]),
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
496
|
+
(
|
|
497
|
+
ApiRoute(
|
|
498
|
+
"/threads/{thread_id}/runs/crons", create_thread_cron, methods=["POST"]
|
|
499
|
+
)
|
|
500
|
+
if config.FF_CRONS_ENABLED and plus_features_enabled()
|
|
501
|
+
else None
|
|
502
|
+
),
|
|
471
503
|
ApiRoute("/threads/{thread_id}/runs", list_runs_http, methods=["GET"]),
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
504
|
+
(
|
|
505
|
+
ApiRoute("/runs/crons/{cron_id}", delete_cron, methods=["DELETE"])
|
|
506
|
+
if config.FF_CRONS_ENABLED and plus_features_enabled()
|
|
507
|
+
else None
|
|
508
|
+
),
|
|
475
509
|
]
|
|
476
510
|
|
|
477
511
|
runs_routes = [route for route in runs_routes if route is not None]
|