langgraph-api 0.4.1__py3-none-any.whl → 0.7.3__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.
- langgraph_api/__init__.py +1 -1
- langgraph_api/api/__init__.py +111 -51
- langgraph_api/api/a2a.py +1610 -0
- langgraph_api/api/assistants.py +212 -89
- langgraph_api/api/mcp.py +3 -3
- langgraph_api/api/meta.py +52 -28
- langgraph_api/api/openapi.py +27 -17
- langgraph_api/api/profile.py +108 -0
- langgraph_api/api/runs.py +342 -195
- langgraph_api/api/store.py +19 -2
- langgraph_api/api/threads.py +209 -27
- langgraph_api/asgi_transport.py +14 -9
- langgraph_api/asyncio.py +14 -4
- langgraph_api/auth/custom.py +52 -37
- langgraph_api/auth/langsmith/backend.py +4 -3
- langgraph_api/auth/langsmith/client.py +13 -8
- langgraph_api/cli.py +230 -133
- langgraph_api/command.py +5 -3
- langgraph_api/config/__init__.py +532 -0
- langgraph_api/config/_parse.py +58 -0
- langgraph_api/config/schemas.py +431 -0
- langgraph_api/cron_scheduler.py +17 -1
- langgraph_api/encryption/__init__.py +15 -0
- langgraph_api/encryption/aes_json.py +158 -0
- langgraph_api/encryption/context.py +35 -0
- langgraph_api/encryption/custom.py +280 -0
- langgraph_api/encryption/middleware.py +632 -0
- langgraph_api/encryption/shared.py +63 -0
- langgraph_api/errors.py +12 -1
- langgraph_api/executor_entrypoint.py +11 -6
- langgraph_api/feature_flags.py +29 -0
- langgraph_api/graph.py +176 -76
- langgraph_api/grpc/client.py +313 -0
- langgraph_api/grpc/config_conversion.py +231 -0
- langgraph_api/grpc/generated/__init__.py +29 -0
- langgraph_api/grpc/generated/checkpointer_pb2.py +63 -0
- langgraph_api/grpc/generated/checkpointer_pb2.pyi +99 -0
- langgraph_api/grpc/generated/checkpointer_pb2_grpc.py +329 -0
- langgraph_api/grpc/generated/core_api_pb2.py +216 -0
- langgraph_api/grpc/generated/core_api_pb2.pyi +905 -0
- langgraph_api/grpc/generated/core_api_pb2_grpc.py +1621 -0
- langgraph_api/grpc/generated/engine_common_pb2.py +219 -0
- langgraph_api/grpc/generated/engine_common_pb2.pyi +722 -0
- langgraph_api/grpc/generated/engine_common_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_cancel_run_action_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_cancel_run_action_pb2.pyi +12 -0
- langgraph_api/grpc/generated/enum_cancel_run_action_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_control_signal_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_control_signal_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_control_signal_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_durability_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_durability_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_durability_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_multitask_strategy_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_multitask_strategy_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_multitask_strategy_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_run_status_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_run_status_pb2.pyi +22 -0
- langgraph_api/grpc/generated/enum_run_status_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_stream_mode_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_stream_mode_pb2.pyi +28 -0
- langgraph_api/grpc/generated/enum_stream_mode_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_thread_status_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_thread_status_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_thread_status_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_thread_stream_mode_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_thread_stream_mode_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_thread_stream_mode_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/errors_pb2.py +39 -0
- langgraph_api/grpc/generated/errors_pb2.pyi +21 -0
- langgraph_api/grpc/generated/errors_pb2_grpc.py +24 -0
- langgraph_api/grpc/ops/__init__.py +370 -0
- langgraph_api/grpc/ops/assistants.py +424 -0
- langgraph_api/grpc/ops/runs.py +792 -0
- langgraph_api/grpc/ops/threads.py +1013 -0
- langgraph_api/http.py +16 -5
- langgraph_api/http_metrics.py +15 -35
- langgraph_api/http_metrics_utils.py +38 -0
- langgraph_api/js/build.mts +1 -1
- langgraph_api/js/client.http.mts +13 -7
- langgraph_api/js/client.mts +2 -5
- langgraph_api/js/package.json +29 -28
- langgraph_api/js/remote.py +56 -30
- langgraph_api/js/src/graph.mts +20 -0
- langgraph_api/js/sse.py +2 -2
- langgraph_api/js/ui.py +1 -1
- langgraph_api/js/yarn.lock +1204 -1006
- langgraph_api/logging.py +29 -2
- langgraph_api/metadata.py +99 -28
- langgraph_api/middleware/http_logger.py +7 -2
- langgraph_api/middleware/private_network.py +7 -7
- langgraph_api/models/run.py +54 -93
- langgraph_api/otel_context.py +205 -0
- langgraph_api/patch.py +5 -3
- langgraph_api/queue_entrypoint.py +154 -65
- langgraph_api/route.py +47 -5
- langgraph_api/schema.py +88 -10
- langgraph_api/self_hosted_logs.py +124 -0
- langgraph_api/self_hosted_metrics.py +450 -0
- langgraph_api/serde.py +79 -37
- langgraph_api/server.py +138 -60
- langgraph_api/state.py +4 -3
- langgraph_api/store.py +25 -16
- langgraph_api/stream.py +80 -29
- langgraph_api/thread_ttl.py +31 -13
- langgraph_api/timing/__init__.py +25 -0
- langgraph_api/timing/profiler.py +200 -0
- langgraph_api/timing/timer.py +318 -0
- langgraph_api/utils/__init__.py +53 -8
- langgraph_api/utils/cache.py +47 -10
- langgraph_api/utils/config.py +2 -1
- langgraph_api/utils/errors.py +77 -0
- langgraph_api/utils/future.py +10 -6
- langgraph_api/utils/headers.py +76 -2
- langgraph_api/utils/retriable_client.py +74 -0
- langgraph_api/utils/stream_codec.py +315 -0
- langgraph_api/utils/uuids.py +29 -62
- langgraph_api/validation.py +9 -0
- langgraph_api/webhook.py +120 -6
- langgraph_api/worker.py +55 -24
- {langgraph_api-0.4.1.dist-info → langgraph_api-0.7.3.dist-info}/METADATA +16 -8
- langgraph_api-0.7.3.dist-info/RECORD +168 -0
- {langgraph_api-0.4.1.dist-info → langgraph_api-0.7.3.dist-info}/WHEEL +1 -1
- langgraph_runtime/__init__.py +1 -0
- langgraph_runtime/routes.py +11 -0
- logging.json +1 -3
- openapi.json +839 -478
- langgraph_api/config.py +0 -387
- langgraph_api/js/isolate-0x130008000-46649-46649-v8.log +0 -4430
- langgraph_api/js/isolate-0x138008000-44681-44681-v8.log +0 -4430
- langgraph_api/js/package-lock.json +0 -3308
- langgraph_api-0.4.1.dist-info/RECORD +0 -107
- /langgraph_api/{utils.py → grpc/__init__.py} +0 -0
- {langgraph_api-0.4.1.dist-info → langgraph_api-0.7.3.dist-info}/entry_points.txt +0 -0
- {langgraph_api-0.4.1.dist-info → langgraph_api-0.7.3.dist-info}/licenses/LICENSE +0 -0
langgraph_api/config.py
DELETED
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from os import environ, getenv
|
|
3
|
-
from typing import Literal
|
|
4
|
-
|
|
5
|
-
import orjson
|
|
6
|
-
from starlette.config import Config, undefined
|
|
7
|
-
from starlette.datastructures import CommaSeparatedStrings
|
|
8
|
-
from typing_extensions import TypedDict
|
|
9
|
-
|
|
10
|
-
from langgraph_api import traceblock
|
|
11
|
-
|
|
12
|
-
# types
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class CorsConfig(TypedDict, total=False):
|
|
16
|
-
allow_origins: list[str]
|
|
17
|
-
allow_methods: list[str]
|
|
18
|
-
allow_headers: list[str]
|
|
19
|
-
allow_credentials: bool
|
|
20
|
-
allow_origin_regex: str
|
|
21
|
-
expose_headers: list[str]
|
|
22
|
-
max_age: int
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class ConfigurableHeaders(TypedDict):
|
|
26
|
-
includes: list[str] | None
|
|
27
|
-
excludes: list[str] | None
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class HttpConfig(TypedDict, total=False):
|
|
31
|
-
app: str
|
|
32
|
-
"""Import path for a custom Starlette/FastAPI app to mount"""
|
|
33
|
-
disable_assistants: bool
|
|
34
|
-
"""Disable /assistants routes"""
|
|
35
|
-
disable_threads: bool
|
|
36
|
-
"""Disable /threads routes"""
|
|
37
|
-
disable_runs: bool
|
|
38
|
-
"""Disable /runs routes"""
|
|
39
|
-
disable_store: bool
|
|
40
|
-
"""Disable /store routes"""
|
|
41
|
-
disable_meta: bool
|
|
42
|
-
"""Disable /ok, /info, /metrics, and /docs routes"""
|
|
43
|
-
disable_webhooks: bool
|
|
44
|
-
"""Disable webhooks calls on run completion in all routes"""
|
|
45
|
-
cors: CorsConfig | None
|
|
46
|
-
"""CORS configuration"""
|
|
47
|
-
disable_ui: bool
|
|
48
|
-
"""Disable /ui routes"""
|
|
49
|
-
disable_mcp: bool
|
|
50
|
-
"""Disable /mcp routes"""
|
|
51
|
-
mount_prefix: str
|
|
52
|
-
"""Prefix for mounted routes. E.g., "/my-deployment/api"."""
|
|
53
|
-
configurable_headers: ConfigurableHeaders | None
|
|
54
|
-
logging_headers: ConfigurableHeaders | None
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class ThreadTTLConfig(TypedDict, total=False):
|
|
58
|
-
strategy: Literal["delete"]
|
|
59
|
-
default_ttl: float | None
|
|
60
|
-
sweep_interval_minutes: int | None
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class IndexConfig(TypedDict, total=False):
|
|
64
|
-
"""Configuration for indexing documents for semantic search in the store."""
|
|
65
|
-
|
|
66
|
-
dims: int
|
|
67
|
-
"""Number of dimensions in the embedding vectors.
|
|
68
|
-
|
|
69
|
-
Common embedding models have the following dimensions:
|
|
70
|
-
- OpenAI text-embedding-3-large: 256, 1024, or 3072
|
|
71
|
-
- OpenAI text-embedding-3-small: 512 or 1536
|
|
72
|
-
- OpenAI text-embedding-ada-002: 1536
|
|
73
|
-
- Cohere embed-english-v3.0: 1024
|
|
74
|
-
- Cohere embed-english-light-v3.0: 384
|
|
75
|
-
- Cohere embed-multilingual-v3.0: 1024
|
|
76
|
-
- Cohere embed-multilingual-light-v3.0: 384
|
|
77
|
-
"""
|
|
78
|
-
|
|
79
|
-
embed: str
|
|
80
|
-
"""Either a path to an embedding model (./path/to/file.py:embedding_model)
|
|
81
|
-
or a name of an embedding model (openai:text-embedding-3-small)
|
|
82
|
-
|
|
83
|
-
Note: LangChain is required to use the model format specification.
|
|
84
|
-
"""
|
|
85
|
-
|
|
86
|
-
fields: list[str] | None
|
|
87
|
-
"""Fields to extract text from for embedding generation.
|
|
88
|
-
|
|
89
|
-
Defaults to the root ["$"], which embeds the json object as a whole.
|
|
90
|
-
"""
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
class TTLConfig(TypedDict, total=False):
|
|
94
|
-
"""Configuration for TTL (time-to-live) behavior in the store."""
|
|
95
|
-
|
|
96
|
-
refresh_on_read: bool
|
|
97
|
-
"""Default behavior for refreshing TTLs on read operations (GET and SEARCH).
|
|
98
|
-
|
|
99
|
-
If True, TTLs will be refreshed on read operations (get/search) by default.
|
|
100
|
-
This can be overridden per-operation by explicitly setting refresh_ttl.
|
|
101
|
-
Defaults to True if not configured.
|
|
102
|
-
"""
|
|
103
|
-
default_ttl: float | None
|
|
104
|
-
"""Default TTL (time-to-live) in minutes for new items.
|
|
105
|
-
|
|
106
|
-
If provided, new items will expire after this many minutes after their last access.
|
|
107
|
-
The expiration timer refreshes on both read and write operations.
|
|
108
|
-
Defaults to None (no expiration).
|
|
109
|
-
"""
|
|
110
|
-
sweep_interval_minutes: int | None
|
|
111
|
-
"""Interval in minutes between TTL sweep operations.
|
|
112
|
-
|
|
113
|
-
If provided, the store will periodically delete expired items based on TTL.
|
|
114
|
-
Defaults to None (no sweeping).
|
|
115
|
-
"""
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
class StoreConfig(TypedDict, total=False):
|
|
119
|
-
path: str
|
|
120
|
-
index: IndexConfig
|
|
121
|
-
ttl: TTLConfig
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
class CheckpointerConfig(TypedDict, total=False):
|
|
125
|
-
"""Configuration for the built-in checkpointer, which handles checkpointing of state.
|
|
126
|
-
|
|
127
|
-
If omitted, no checkpointer is set up (the object store will still be present, however).
|
|
128
|
-
"""
|
|
129
|
-
|
|
130
|
-
ttl: ThreadTTLConfig | None
|
|
131
|
-
"""Optional. Defines the TTL (time-to-live) behavior configuration.
|
|
132
|
-
|
|
133
|
-
If provided, the checkpointer will apply TTL settings according to the configuration.
|
|
134
|
-
If omitted, no TTL behavior is configured.
|
|
135
|
-
"""
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
# env
|
|
139
|
-
|
|
140
|
-
env = Config()
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def _parse_json(json: str | None) -> dict | None:
|
|
144
|
-
if not json:
|
|
145
|
-
return None
|
|
146
|
-
parsed = orjson.loads(json)
|
|
147
|
-
if not parsed:
|
|
148
|
-
return None
|
|
149
|
-
return parsed
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
STATS_INTERVAL_SECS = env("STATS_INTERVAL_SECS", cast=int, default=60)
|
|
153
|
-
|
|
154
|
-
# storage
|
|
155
|
-
|
|
156
|
-
DATABASE_URI = env("DATABASE_URI", cast=str, default=getenv("POSTGRES_URI", undefined))
|
|
157
|
-
MIGRATIONS_PATH = env("MIGRATIONS_PATH", cast=str, default="/storage/migrations")
|
|
158
|
-
POSTGRES_POOL_MAX_SIZE = env("LANGGRAPH_POSTGRES_POOL_MAX_SIZE", cast=int, default=150)
|
|
159
|
-
RESUMABLE_STREAM_TTL_SECONDS = env(
|
|
160
|
-
"RESUMABLE_STREAM_TTL_SECONDS",
|
|
161
|
-
cast=int,
|
|
162
|
-
default=120, # 2 minutes
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def _get_encryption_key(key_str: str | None):
|
|
167
|
-
if not key_str:
|
|
168
|
-
return None
|
|
169
|
-
key = key_str.encode(encoding="utf-8")
|
|
170
|
-
if len(key) not in (16, 24, 32):
|
|
171
|
-
raise ValueError("LANGGRAPH_AES_KEY must be 16, 24, or 32 bytes long.")
|
|
172
|
-
return key
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
LANGGRAPH_AES_KEY = env("LANGGRAPH_AES_KEY", default=None, cast=_get_encryption_key)
|
|
176
|
-
|
|
177
|
-
# redis
|
|
178
|
-
REDIS_URI = env("REDIS_URI", cast=str)
|
|
179
|
-
REDIS_CLUSTER = env("REDIS_CLUSTER", cast=bool, default=False)
|
|
180
|
-
REDIS_MAX_CONNECTIONS = env("REDIS_MAX_CONNECTIONS", cast=int, default=2000)
|
|
181
|
-
REDIS_CONNECT_TIMEOUT = env("REDIS_CONNECT_TIMEOUT", cast=float, default=10.0)
|
|
182
|
-
REDIS_MAX_IDLE_TIME = env("REDIS_MAX_IDLE_TIME", cast=float, default=120.0)
|
|
183
|
-
REDIS_STREAM_TIMEOUT = env("REDIS_STREAM_TIMEOUT", cast=float, default=30.0)
|
|
184
|
-
REDIS_KEY_PREFIX = env("REDIS_KEY_PREFIX", cast=str, default="")
|
|
185
|
-
RUN_STATS_CACHE_SECONDS = env("RUN_STATS_CACHE_SECONDS", cast=int, default=60)
|
|
186
|
-
|
|
187
|
-
# server
|
|
188
|
-
ALLOW_PRIVATE_NETWORK = env("ALLOW_PRIVATE_NETWORK", cast=bool, default=False)
|
|
189
|
-
"""Only enable for langgraph dev when server is running on loopback address.
|
|
190
|
-
|
|
191
|
-
See https://developer.chrome.com/blog/private-network-access-update-2024-03
|
|
192
|
-
"""
|
|
193
|
-
|
|
194
|
-
HTTP_CONFIG: HttpConfig | None = env("LANGGRAPH_HTTP", cast=_parse_json, default=None)
|
|
195
|
-
STORE_CONFIG: StoreConfig | None = env(
|
|
196
|
-
"LANGGRAPH_STORE", cast=_parse_json, default=None
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
MOUNT_PREFIX: str | None = env("MOUNT_PREFIX", cast=str, default=None) or (
|
|
200
|
-
HTTP_CONFIG.get("mount_prefix") if HTTP_CONFIG else None
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
CORS_ALLOW_ORIGINS = env("CORS_ALLOW_ORIGINS", cast=CommaSeparatedStrings, default="*")
|
|
204
|
-
CORS_CONFIG: CorsConfig | None = env("CORS_CONFIG", cast=_parse_json, default=None) or (
|
|
205
|
-
HTTP_CONFIG.get("cors") if HTTP_CONFIG else None
|
|
206
|
-
)
|
|
207
|
-
"""
|
|
208
|
-
{
|
|
209
|
-
"type": "object",
|
|
210
|
-
"properties": {
|
|
211
|
-
"allow_origins": {
|
|
212
|
-
"type": "array",
|
|
213
|
-
"items": {"type": "string"},
|
|
214
|
-
"default": []
|
|
215
|
-
},
|
|
216
|
-
"allow_methods": {
|
|
217
|
-
"type": "array",
|
|
218
|
-
"items": {"type": "string"},
|
|
219
|
-
"default": ["GET"]
|
|
220
|
-
},
|
|
221
|
-
"allow_headers": {
|
|
222
|
-
"type": "array",
|
|
223
|
-
"items": {"type": "string"},
|
|
224
|
-
"default": []
|
|
225
|
-
},
|
|
226
|
-
"allow_credentials": {
|
|
227
|
-
"type": "boolean",
|
|
228
|
-
"default": false
|
|
229
|
-
},
|
|
230
|
-
"allow_origin_regex": {
|
|
231
|
-
"type": ["string", "null"],
|
|
232
|
-
"default": null
|
|
233
|
-
},
|
|
234
|
-
"expose_headers": {
|
|
235
|
-
"type": "array",
|
|
236
|
-
"items": {"type": "string"},
|
|
237
|
-
"default": []
|
|
238
|
-
},
|
|
239
|
-
"max_age": {
|
|
240
|
-
"type": "integer",
|
|
241
|
-
"default": 600
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
"""
|
|
246
|
-
if (
|
|
247
|
-
CORS_CONFIG is not None
|
|
248
|
-
and CORS_ALLOW_ORIGINS != "*"
|
|
249
|
-
and CORS_CONFIG.get("allow_origins") is None
|
|
250
|
-
):
|
|
251
|
-
CORS_CONFIG["allow_origins"] = CORS_ALLOW_ORIGINS
|
|
252
|
-
|
|
253
|
-
# queue
|
|
254
|
-
|
|
255
|
-
BG_JOB_HEARTBEAT = 120 # seconds
|
|
256
|
-
BG_JOB_INTERVAL = 30 # seconds
|
|
257
|
-
BG_JOB_MAX_RETRIES = 3
|
|
258
|
-
BG_JOB_ISOLATED_LOOPS = env("BG_JOB_ISOLATED_LOOPS", cast=bool, default=False)
|
|
259
|
-
BG_JOB_SHUTDOWN_GRACE_PERIOD_SECS = env(
|
|
260
|
-
"BG_JOB_SHUTDOWN_GRACE_PERIOD_SECS",
|
|
261
|
-
cast=int,
|
|
262
|
-
default=180, # 3 minutes
|
|
263
|
-
)
|
|
264
|
-
MAX_STREAM_CHUNK_SIZE_BYTES = env(
|
|
265
|
-
"MAX_STREAM_CHUNK_SIZE_BYTES", cast=int, default=1024 * 1024 * 128
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
def _parse_thread_ttl(value: str | None) -> ThreadTTLConfig | None:
|
|
270
|
-
if not value:
|
|
271
|
-
return None
|
|
272
|
-
if str(value).strip().startswith("{"):
|
|
273
|
-
return _parse_json(value.strip())
|
|
274
|
-
return {
|
|
275
|
-
"strategy": "delete",
|
|
276
|
-
# We permit float values mainly for testing purposes
|
|
277
|
-
"default_ttl": float(value),
|
|
278
|
-
"sweep_interval_minutes": 5.1,
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
CHECKPOINTER_CONFIG: CheckpointerConfig | None = env(
|
|
283
|
-
"LANGGRAPH_CHECKPOINTER", cast=_parse_json, default=None
|
|
284
|
-
)
|
|
285
|
-
THREAD_TTL: ThreadTTLConfig | None = env(
|
|
286
|
-
"LANGGRAPH_THREAD_TTL", cast=_parse_thread_ttl, default=None
|
|
287
|
-
)
|
|
288
|
-
if THREAD_TTL is None and CHECKPOINTER_CONFIG is not None:
|
|
289
|
-
THREAD_TTL = CHECKPOINTER_CONFIG.get("ttl")
|
|
290
|
-
|
|
291
|
-
N_JOBS_PER_WORKER = env("N_JOBS_PER_WORKER", cast=int, default=10)
|
|
292
|
-
BG_JOB_TIMEOUT_SECS = env("BG_JOB_TIMEOUT_SECS", cast=float, default=3600)
|
|
293
|
-
FF_CRONS_ENABLED = env("FF_CRONS_ENABLED", cast=bool, default=True)
|
|
294
|
-
FF_RICH_THREADS = env("FF_RICH_THREADS", cast=bool, default=True)
|
|
295
|
-
|
|
296
|
-
# auth
|
|
297
|
-
|
|
298
|
-
LANGGRAPH_AUTH_TYPE = env("LANGGRAPH_AUTH_TYPE", cast=str, default="noop")
|
|
299
|
-
LANGGRAPH_POSTGRES_EXTENSIONS: Literal["standard", "lite"] = env(
|
|
300
|
-
"LANGGRAPH_POSTGRES_EXTENSIONS", cast=str, default="standard"
|
|
301
|
-
)
|
|
302
|
-
if LANGGRAPH_POSTGRES_EXTENSIONS not in ("standard", "lite"):
|
|
303
|
-
raise ValueError(
|
|
304
|
-
f"Unknown LANGGRAPH_POSTGRES_EXTENSIONS value: {LANGGRAPH_POSTGRES_EXTENSIONS}"
|
|
305
|
-
)
|
|
306
|
-
LANGGRAPH_AUTH = env("LANGGRAPH_AUTH", cast=_parse_json, default=None)
|
|
307
|
-
LANGSMITH_TENANT_ID = env("LANGSMITH_TENANT_ID", cast=str, default=None)
|
|
308
|
-
LANGSMITH_AUTH_VERIFY_TENANT_ID = env(
|
|
309
|
-
"LANGSMITH_AUTH_VERIFY_TENANT_ID",
|
|
310
|
-
cast=bool,
|
|
311
|
-
default=LANGSMITH_TENANT_ID is not None,
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
if LANGGRAPH_AUTH_TYPE == "langsmith":
|
|
315
|
-
LANGSMITH_AUTH_ENDPOINT = env("LANGSMITH_AUTH_ENDPOINT", cast=str)
|
|
316
|
-
LANGSMITH_TENANT_ID = env("LANGSMITH_TENANT_ID", cast=str)
|
|
317
|
-
LANGSMITH_AUTH_VERIFY_TENANT_ID = env(
|
|
318
|
-
"LANGSMITH_AUTH_VERIFY_TENANT_ID", cast=bool, default=True
|
|
319
|
-
)
|
|
320
|
-
|
|
321
|
-
else:
|
|
322
|
-
LANGSMITH_AUTH_ENDPOINT = env(
|
|
323
|
-
"LANGSMITH_AUTH_ENDPOINT",
|
|
324
|
-
cast=str,
|
|
325
|
-
default=getenv(
|
|
326
|
-
"LANGCHAIN_ENDPOINT",
|
|
327
|
-
getenv("LANGSMITH_ENDPOINT", "https://api.smith.langchain.com"),
|
|
328
|
-
),
|
|
329
|
-
)
|
|
330
|
-
|
|
331
|
-
# license
|
|
332
|
-
|
|
333
|
-
LANGGRAPH_CLOUD_LICENSE_KEY = env("LANGGRAPH_CLOUD_LICENSE_KEY", cast=str, default="")
|
|
334
|
-
LANGSMITH_API_KEY = env(
|
|
335
|
-
"LANGSMITH_API_KEY", cast=str, default=getenv("LANGCHAIN_API_KEY", "")
|
|
336
|
-
)
|
|
337
|
-
|
|
338
|
-
# if langsmith api key is set, enable tracing unless explicitly disabled
|
|
339
|
-
|
|
340
|
-
if (
|
|
341
|
-
LANGSMITH_API_KEY
|
|
342
|
-
and not getenv("LANGCHAIN_TRACING_V2")
|
|
343
|
-
and not getenv("LANGCHAIN_TRACING")
|
|
344
|
-
and not getenv("LANGSMITH_TRACING_V2")
|
|
345
|
-
and not getenv("LANGSMITH_TRACING")
|
|
346
|
-
):
|
|
347
|
-
environ["LANGCHAIN_TRACING_V2"] = "true"
|
|
348
|
-
|
|
349
|
-
TRACING = (
|
|
350
|
-
env("LANGCHAIN_TRACING_V2", cast=bool, default=None)
|
|
351
|
-
or env("LANGCHAIN_TRACING", cast=bool, default=None)
|
|
352
|
-
or env("LANGSMITH_TRACING_V2", cast=bool, default=None)
|
|
353
|
-
or env("LANGSMITH_TRACING", cast=bool, default=None)
|
|
354
|
-
)
|
|
355
|
-
|
|
356
|
-
# if variant is "licensed", update to "local" if using LANGSMITH_API_KEY instead
|
|
357
|
-
|
|
358
|
-
if getenv("LANGSMITH_LANGGRAPH_API_VARIANT") == "licensed" and LANGSMITH_API_KEY:
|
|
359
|
-
environ["LANGSMITH_LANGGRAPH_API_VARIANT"] = "local"
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
# Metrics.
|
|
363
|
-
USES_INDEXING = (
|
|
364
|
-
STORE_CONFIG
|
|
365
|
-
and STORE_CONFIG.get("index")
|
|
366
|
-
and STORE_CONFIG.get("index").get("embed")
|
|
367
|
-
)
|
|
368
|
-
USES_CUSTOM_APP = HTTP_CONFIG and HTTP_CONFIG.get("app")
|
|
369
|
-
USES_CUSTOM_AUTH = bool(LANGGRAPH_AUTH)
|
|
370
|
-
USES_THREAD_TTL = bool(THREAD_TTL)
|
|
371
|
-
USES_STORE_TTL = bool(STORE_CONFIG and STORE_CONFIG.get("ttl"))
|
|
372
|
-
|
|
373
|
-
API_VARIANT = env("LANGSMITH_LANGGRAPH_API_VARIANT", cast=str, default="")
|
|
374
|
-
|
|
375
|
-
# UI
|
|
376
|
-
UI_USE_BUNDLER = env("LANGGRAPH_UI_BUNDLER", cast=bool, default=False)
|
|
377
|
-
IS_QUEUE_ENTRYPOINT = False
|
|
378
|
-
IS_EXECUTOR_ENTRYPOINT = False
|
|
379
|
-
ref_sha = None
|
|
380
|
-
if not os.getenv("LANGCHAIN_REVISION_ID") and (
|
|
381
|
-
ref_sha := os.getenv("LANGSMITH_LANGGRAPH_GIT_REF_SHA")
|
|
382
|
-
):
|
|
383
|
-
# This is respected by the langsmith SDK env inference
|
|
384
|
-
# https://github.com/langchain-ai/langsmith-sdk/blob/1b93e4c13b8369d92db891ae3babc3e2254f0e56/python/langsmith/env/_runtime_env.py#L190
|
|
385
|
-
os.environ["LANGCHAIN_REVISION_ID"] = ref_sha
|
|
386
|
-
|
|
387
|
-
traceblock.patch_requests()
|