langgraph-api 0.1.8__py3-none-any.whl → 0.1.12__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 langgraph-api might be problematic. Click here for more details.
- langgraph_api/__init__.py +1 -1
- langgraph_api/cli.py +33 -2
- langgraph_api/config.py +1 -0
- langgraph_api/js/package.json +1 -1
- langgraph_api/js/tests/api.test.mts +29 -0
- langgraph_api/js/tests/graphs/agent_simple.mts +23 -2
- langgraph_api/js/yarn.lock +4 -4
- langgraph_api/metadata.py +15 -11
- langgraph_api/server.py +0 -2
- langgraph_api/tunneling/cloudflare.py +119 -0
- {langgraph_api-0.1.8.dist-info → langgraph_api-0.1.12.dist-info}/METADATA +1 -1
- {langgraph_api-0.1.8.dist-info → langgraph_api-0.1.12.dist-info}/RECORD +16 -16
- langgraph_license/validation.py +11 -0
- langgraph_license/middleware.py +0 -21
- {langgraph_api-0.1.8.dist-info → langgraph_api-0.1.12.dist-info}/LICENSE +0 -0
- {langgraph_api-0.1.8.dist-info → langgraph_api-0.1.12.dist-info}/WHEEL +0 -0
- {langgraph_api-0.1.8.dist-info → langgraph_api-0.1.12.dist-info}/entry_points.txt +0 -0
langgraph_api/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.12"
|
langgraph_api/cli.py
CHANGED
|
@@ -122,6 +122,7 @@ def run_server(
|
|
|
122
122
|
n_jobs_per_worker: int | None = None,
|
|
123
123
|
env_file: str | None = None,
|
|
124
124
|
open_browser: bool = False,
|
|
125
|
+
tunnel: bool = False,
|
|
125
126
|
debug_port: int | None = None,
|
|
126
127
|
wait_for_client: bool = False,
|
|
127
128
|
env: str | pathlib.Path | Mapping[str, str] | None = None,
|
|
@@ -189,9 +190,33 @@ def run_server(
|
|
|
189
190
|
debugpy.wait_for_client()
|
|
190
191
|
logger.info("Debugger attached. Starting server...")
|
|
191
192
|
|
|
192
|
-
|
|
193
|
+
# Determine local or tunneled URL
|
|
194
|
+
upstream_url = f"http://{host}:{port}"
|
|
193
195
|
if mount_prefix:
|
|
194
|
-
|
|
196
|
+
upstream_url += mount_prefix
|
|
197
|
+
if tunnel:
|
|
198
|
+
logger.info("Starting Cloudflare Tunnel...")
|
|
199
|
+
from concurrent.futures import TimeoutError as FutureTimeoutError
|
|
200
|
+
|
|
201
|
+
from langgraph_api.tunneling.cloudflare import start_tunnel
|
|
202
|
+
|
|
203
|
+
tunnel_obj = start_tunnel(port)
|
|
204
|
+
try:
|
|
205
|
+
public_url = tunnel_obj.url.result(timeout=30)
|
|
206
|
+
except FutureTimeoutError:
|
|
207
|
+
logger.warning(
|
|
208
|
+
"Timed out waiting for Cloudflare Tunnel URL; using local URL %s",
|
|
209
|
+
upstream_url,
|
|
210
|
+
)
|
|
211
|
+
public_url = upstream_url
|
|
212
|
+
except Exception as e:
|
|
213
|
+
tunnel_obj.process.kill()
|
|
214
|
+
raise RuntimeError("Failed to start Cloudflare Tunnel") from e
|
|
215
|
+
local_url = public_url
|
|
216
|
+
if mount_prefix:
|
|
217
|
+
local_url += mount_prefix
|
|
218
|
+
else:
|
|
219
|
+
local_url = upstream_url
|
|
195
220
|
to_patch = dict(
|
|
196
221
|
MIGRATIONS_PATH="__inmem",
|
|
197
222
|
DATABASE_URI=":memory:",
|
|
@@ -361,6 +386,11 @@ def main():
|
|
|
361
386
|
action="store_true",
|
|
362
387
|
help="Whether to break and wait for a debugger to attach",
|
|
363
388
|
)
|
|
389
|
+
parser.add_argument(
|
|
390
|
+
"--tunnel",
|
|
391
|
+
action="store_true",
|
|
392
|
+
help="Expose the server via Cloudflare Tunnel",
|
|
393
|
+
)
|
|
364
394
|
|
|
365
395
|
args = parser.parse_args()
|
|
366
396
|
|
|
@@ -378,6 +408,7 @@ def main():
|
|
|
378
408
|
graphs,
|
|
379
409
|
n_jobs_per_worker=args.n_jobs_per_worker,
|
|
380
410
|
open_browser=not args.no_browser,
|
|
411
|
+
tunnel=args.tunnel,
|
|
381
412
|
debug_port=args.debug_port,
|
|
382
413
|
wait_for_client=args.wait_for_client,
|
|
383
414
|
env=config_data.get("env", None),
|
langgraph_api/config.py
CHANGED
|
@@ -159,6 +159,7 @@ REDIS_URI = env("REDIS_URI", cast=str)
|
|
|
159
159
|
REDIS_CLUSTER = env("REDIS_CLUSTER", cast=bool, default=False)
|
|
160
160
|
REDIS_MAX_CONNECTIONS = env("REDIS_MAX_CONNECTIONS", cast=int, default=500)
|
|
161
161
|
REDIS_CONNECT_TIMEOUT = env("REDIS_CONNECT_TIMEOUT", cast=float, default=10.0)
|
|
162
|
+
REDIS_KEY_PREFIX = env("REDIS_KEY_PREFIX", cast=str, default="")
|
|
162
163
|
|
|
163
164
|
# server
|
|
164
165
|
ALLOW_PRIVATE_NETWORK = env("ALLOW_PRIVATE_NETWORK", cast=bool, default=False)
|
langgraph_api/js/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"@hono/node-server": "^1.12.0",
|
|
11
11
|
"@hono/zod-validator": "^0.2.2",
|
|
12
12
|
"@langchain/core": "^0.3.44",
|
|
13
|
-
"@langchain/langgraph": "^0.2.
|
|
13
|
+
"@langchain/langgraph": "^0.2.65",
|
|
14
14
|
"@langchain/langgraph-checkpoint": "^0.0.17",
|
|
15
15
|
"@types/json-schema": "^7.0.15",
|
|
16
16
|
"@typescript/vfs": "^1.6.0",
|
|
@@ -2078,6 +2078,7 @@ it("custom routes - mutate request body", async () => {
|
|
|
2078
2078
|
messages: expect.arrayContaining([
|
|
2079
2079
|
expect.objectContaining({ content: "end: extra-client" }),
|
|
2080
2080
|
]),
|
|
2081
|
+
prompts: [],
|
|
2081
2082
|
});
|
|
2082
2083
|
});
|
|
2083
2084
|
|
|
@@ -2094,6 +2095,34 @@ it("custom routes - langgraph", async () => {
|
|
|
2094
2095
|
messages: expect.arrayContaining([
|
|
2095
2096
|
expect.objectContaining({ content: "input" }),
|
|
2096
2097
|
]),
|
|
2098
|
+
prompts: [],
|
|
2099
|
+
},
|
|
2100
|
+
});
|
|
2101
|
+
});
|
|
2102
|
+
|
|
2103
|
+
it("send map-reduce", async () => {
|
|
2104
|
+
const assistant = await client.assistants.create({ graphId: "agent_simple" });
|
|
2105
|
+
const thread = await client.threads.create();
|
|
2106
|
+
|
|
2107
|
+
const chunks = await gatherIterator(
|
|
2108
|
+
client.runs.stream(thread.thread_id, assistant.assistant_id, {
|
|
2109
|
+
input: { messages: [{ role: "human", content: "input" }] },
|
|
2110
|
+
config: { configurable: { "map-reduce": true } },
|
|
2111
|
+
}),
|
|
2112
|
+
);
|
|
2113
|
+
|
|
2114
|
+
expect(chunks.filter((i) => i.event === "error")).toEqual([]);
|
|
2115
|
+
expect(findLast(chunks, (i) => i.event === "values")).toMatchObject({
|
|
2116
|
+
data: {
|
|
2117
|
+
messages: [
|
|
2118
|
+
{ type: "human", content: "input" },
|
|
2119
|
+
{ type: "human", content: "map-reduce" },
|
|
2120
|
+
],
|
|
2121
|
+
prompts: [
|
|
2122
|
+
{ type: "ai", content: "first" },
|
|
2123
|
+
{ type: "ai", content: "second" },
|
|
2124
|
+
{ type: "ai", content: "third" },
|
|
2125
|
+
],
|
|
2097
2126
|
},
|
|
2098
2127
|
});
|
|
2099
2128
|
});
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
START,
|
|
8
8
|
LangGraphRunnableConfig,
|
|
9
9
|
} from "@langchain/langgraph";
|
|
10
|
-
import { BaseMessage, ToolMessage } from "@langchain/core/messages";
|
|
10
|
+
import { AIMessage, BaseMessage, ToolMessage } from "@langchain/core/messages";
|
|
11
11
|
import { FakeListChatModel } from "@langchain/core/utils/testing";
|
|
12
12
|
|
|
13
13
|
const getStableModel = (() => {
|
|
@@ -25,6 +25,7 @@ const AgentState = Annotation.Root({
|
|
|
25
25
|
key_two: Annotation<string>(),
|
|
26
26
|
sleep: Annotation<number>(),
|
|
27
27
|
messages: MessagesAnnotation.spec.messages,
|
|
28
|
+
prompts: MessagesAnnotation.spec.messages,
|
|
28
29
|
});
|
|
29
30
|
|
|
30
31
|
async function callModel(
|
|
@@ -47,6 +48,10 @@ async function callModel(
|
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
if (config.configurable?.["map-reduce"] != null) {
|
|
52
|
+
return { messages: ["map-reduce"] };
|
|
53
|
+
}
|
|
54
|
+
|
|
50
55
|
const model = getStableModel(config.configurable?.thread_id ?? "$");
|
|
51
56
|
const existing = await config.store?.get([userId ?? "ALL"], "key_one");
|
|
52
57
|
if (!existing) {
|
|
@@ -68,15 +73,31 @@ async function callTool(
|
|
|
68
73
|
return { messages: [response] };
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
function shouldContinue(
|
|
76
|
+
function shouldContinue(
|
|
77
|
+
state: typeof AgentState.State,
|
|
78
|
+
): typeof END | Send | Send[] {
|
|
72
79
|
const lastMessage = state.messages.at(-1);
|
|
73
80
|
if ((lastMessage?.content as string).startsWith("end")) return END;
|
|
81
|
+
if ((lastMessage?.content as string).includes("map-reduce")) {
|
|
82
|
+
return [
|
|
83
|
+
new Send("map-reduce", { messages: [new AIMessage("first")] }),
|
|
84
|
+
new Send("map-reduce", { messages: [new AIMessage("second")] }),
|
|
85
|
+
new Send("map-reduce", { messages: [new AIMessage("third")] }),
|
|
86
|
+
];
|
|
87
|
+
}
|
|
74
88
|
return new Send("tool", lastMessage);
|
|
75
89
|
}
|
|
76
90
|
|
|
91
|
+
function callMapReduce(state: {
|
|
92
|
+
messages: BaseMessage[];
|
|
93
|
+
}): typeof AgentState.Update {
|
|
94
|
+
return { prompts: state.messages.slice(-1) };
|
|
95
|
+
}
|
|
96
|
+
|
|
77
97
|
const workflow = new StateGraph(AgentState)
|
|
78
98
|
.addNode("agent", callModel)
|
|
79
99
|
.addNode("tool", callTool)
|
|
100
|
+
.addNode("map-reduce", callMapReduce)
|
|
80
101
|
.addEdge(START, "agent")
|
|
81
102
|
.addConditionalEdges("agent", shouldContinue)
|
|
82
103
|
.addEdge("tool", "agent");
|
langgraph_api/js/yarn.lock
CHANGED
|
@@ -256,10 +256,10 @@
|
|
|
256
256
|
esbuild-plugin-tailwindcss "^2.0.1"
|
|
257
257
|
zod "^3.23.8"
|
|
258
258
|
|
|
259
|
-
"@langchain/langgraph@^0.2.
|
|
260
|
-
version "0.2.
|
|
261
|
-
resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-0.2.
|
|
262
|
-
integrity sha512-
|
|
259
|
+
"@langchain/langgraph@^0.2.65":
|
|
260
|
+
version "0.2.65"
|
|
261
|
+
resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-0.2.65.tgz#f080add1c26a3eb3744af2ef23b8b53eddbf5cb2"
|
|
262
|
+
integrity sha512-g/Xap2KSEaEBXMJXGZTh31fd0qrdfaWA1l8NJzweJg6AkvVSf+d6DmMk9DtzGW8W1H1qQ2I6FWZ3AdP61Kkaig==
|
|
263
263
|
dependencies:
|
|
264
264
|
"@langchain/langgraph-checkpoint" "~0.0.17"
|
|
265
265
|
"@langchain/langgraph-sdk" "~0.0.32"
|
langgraph_api/metadata.py
CHANGED
|
@@ -40,7 +40,10 @@ RUN_COUNTER = 0
|
|
|
40
40
|
NODE_COUNTER = 0
|
|
41
41
|
FROM_TIMESTAMP = datetime.now(UTC).isoformat()
|
|
42
42
|
|
|
43
|
-
if
|
|
43
|
+
if (
|
|
44
|
+
"api.smith.langchain.com" in LANGSMITH_AUTH_ENDPOINT
|
|
45
|
+
and not LANGGRAPH_CLOUD_LICENSE_KEY
|
|
46
|
+
):
|
|
44
47
|
METADATA_ENDPOINT = LANGSMITH_AUTH_ENDPOINT.rstrip("/") + "/v1/metadata/submit"
|
|
45
48
|
else:
|
|
46
49
|
METADATA_ENDPOINT = "https://api.smith.langchain.com/v1/metadata/submit"
|
|
@@ -100,20 +103,21 @@ async def metadata_loop() -> None:
|
|
|
100
103
|
"from_timestamp": from_timestamp,
|
|
101
104
|
"to_timestamp": to_timestamp,
|
|
102
105
|
"tags": {
|
|
106
|
+
# Tag values must be strings.
|
|
103
107
|
"langgraph.python.version": langgraph.version.__version__,
|
|
104
|
-
"langgraph_api.version": __version__,
|
|
105
|
-
"langgraph.platform.revision": REVISION,
|
|
106
|
-
"langgraph.platform.variant": VARIANT,
|
|
108
|
+
"langgraph_api.version": __version__ or "",
|
|
109
|
+
"langgraph.platform.revision": REVISION or "",
|
|
110
|
+
"langgraph.platform.variant": VARIANT or "",
|
|
107
111
|
"langgraph.platform.host": HOST,
|
|
108
|
-
"langgraph.platform.tenant_id": TENANT_ID,
|
|
109
|
-
"langgraph.platform.project_id": PROJECT_ID,
|
|
112
|
+
"langgraph.platform.tenant_id": TENANT_ID or "",
|
|
113
|
+
"langgraph.platform.project_id": PROJECT_ID or "",
|
|
110
114
|
"langgraph.platform.plan": PLAN,
|
|
111
115
|
# user app features
|
|
112
|
-
"user_app.uses_indexing": USES_INDEXING,
|
|
113
|
-
"user_app.uses_custom_app": USES_CUSTOM_APP,
|
|
114
|
-
"user_app.uses_custom_auth": USES_CUSTOM_AUTH,
|
|
115
|
-
"user_app.uses_thread_ttl": USES_THREAD_TTL,
|
|
116
|
-
"user_app.uses_store_ttl": USES_STORE_TTL,
|
|
116
|
+
"user_app.uses_indexing": str(USES_INDEXING or ""),
|
|
117
|
+
"user_app.uses_custom_app": str(USES_CUSTOM_APP or ""),
|
|
118
|
+
"user_app.uses_custom_auth": str(USES_CUSTOM_AUTH),
|
|
119
|
+
"user_app.uses_thread_ttl": str(USES_THREAD_TTL),
|
|
120
|
+
"user_app.uses_store_ttl": str(USES_STORE_TTL),
|
|
117
121
|
},
|
|
118
122
|
"measures": {
|
|
119
123
|
"langgraph.platform.runs": runs,
|
langgraph_api/server.py
CHANGED
|
@@ -30,7 +30,6 @@ from langgraph_runtime.lifespan import lifespan
|
|
|
30
30
|
from langgraph_api.middleware.http_logger import AccessLoggerMiddleware
|
|
31
31
|
from langgraph_api.middleware.private_network import PrivateNetworkMiddleware
|
|
32
32
|
from langgraph_api.utils import SchemaGenerator
|
|
33
|
-
from langgraph_license.middleware import LicenseValidationMiddleware
|
|
34
33
|
from langgraph_runtime.retry import OVERLOADED_EXCEPTIONS
|
|
35
34
|
from langgraph_api.js.base import is_js_path
|
|
36
35
|
from langgraph_sdk.client import configure_loopback_transports
|
|
@@ -68,7 +67,6 @@ middleware.extend(
|
|
|
68
67
|
**config.CORS_CONFIG,
|
|
69
68
|
)
|
|
70
69
|
),
|
|
71
|
-
Middleware(LicenseValidationMiddleware),
|
|
72
70
|
Middleware(AccessLoggerMiddleware, logger=logger),
|
|
73
71
|
]
|
|
74
72
|
)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import atexit
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
import platform as _platform
|
|
5
|
+
import re
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
import tarfile
|
|
10
|
+
import tempfile
|
|
11
|
+
import threading
|
|
12
|
+
import urllib.request
|
|
13
|
+
from concurrent.futures import Future
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
CLOUDFLARED_VERSION = os.environ.get("LANGGRAPH_CLOUDFLARED_VERSION", "2025.2.1")
|
|
19
|
+
CACHE_DIR = (
|
|
20
|
+
Path(os.path.expanduser("~"))
|
|
21
|
+
/ ".langgraph_api"
|
|
22
|
+
/ "cloudflared"
|
|
23
|
+
/ CLOUDFLARED_VERSION
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_platform_arch():
|
|
28
|
+
plat = sys.platform
|
|
29
|
+
if plat.startswith("darwin"):
|
|
30
|
+
plat = "darwin"
|
|
31
|
+
elif plat.startswith("linux"):
|
|
32
|
+
plat = "linux"
|
|
33
|
+
elif plat.startswith("win"):
|
|
34
|
+
plat = "windows"
|
|
35
|
+
else:
|
|
36
|
+
raise RuntimeError(f"Unsupported platform: {sys.platform}")
|
|
37
|
+
arch = _platform.machine().lower()
|
|
38
|
+
if arch in ("x86_64", "amd64"):
|
|
39
|
+
arch = "amd64"
|
|
40
|
+
elif arch in ("arm64", "aarch64"):
|
|
41
|
+
arch = "arm64"
|
|
42
|
+
elif arch in ("i386", "i686", "x86"):
|
|
43
|
+
arch = "386"
|
|
44
|
+
else:
|
|
45
|
+
raise RuntimeError(f"Unsupported architecture: {_platform.machine()}")
|
|
46
|
+
return plat, arch
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def ensure_cloudflared() -> Path:
|
|
50
|
+
plat, arch = get_platform_arch()
|
|
51
|
+
# determine file names and if archive
|
|
52
|
+
if plat == "windows":
|
|
53
|
+
file_name = f"cloudflared-windows-{arch}.exe"
|
|
54
|
+
is_archive = False
|
|
55
|
+
elif plat == "darwin":
|
|
56
|
+
file_name = f"cloudflared-darwin-{arch}.tgz"
|
|
57
|
+
is_archive = True
|
|
58
|
+
else: # linux
|
|
59
|
+
file_name = f"cloudflared-linux-{arch}"
|
|
60
|
+
is_archive = False
|
|
61
|
+
|
|
62
|
+
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
|
63
|
+
binary_name = "cloudflared" if is_archive else file_name
|
|
64
|
+
target_bin = CACHE_DIR / binary_name
|
|
65
|
+
if not target_bin.exists():
|
|
66
|
+
url = f"https://github.com/cloudflare/cloudflared/releases/download/{CLOUDFLARED_VERSION}/{file_name}"
|
|
67
|
+
logger.info(f"Downloading cloudflared from {url}")
|
|
68
|
+
with urllib.request.urlopen(url) as resp:
|
|
69
|
+
data = resp.read()
|
|
70
|
+
with tempfile.TemporaryDirectory() as tmpd:
|
|
71
|
+
tmpd = Path(tmpd)
|
|
72
|
+
path = tmpd / file_name
|
|
73
|
+
path.write_bytes(data)
|
|
74
|
+
if is_archive:
|
|
75
|
+
with tarfile.open(path) as tf:
|
|
76
|
+
tf.extractall(tmpd)
|
|
77
|
+
src = tmpd / "cloudflared"
|
|
78
|
+
else:
|
|
79
|
+
src = path
|
|
80
|
+
shutil.move(str(src), str(target_bin))
|
|
81
|
+
target_bin.chmod(0o755)
|
|
82
|
+
return target_bin
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class CloudflareTunnel:
|
|
86
|
+
def __init__(self, process: subprocess.Popen, url_future: Future[str]):
|
|
87
|
+
self.process = process
|
|
88
|
+
self.url = url_future
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def start_tunnel(port: int) -> CloudflareTunnel:
|
|
92
|
+
bin_path = ensure_cloudflared()
|
|
93
|
+
cmd = [str(bin_path), "tunnel", "--url", f"http://localhost:{port}"]
|
|
94
|
+
proc = subprocess.Popen(
|
|
95
|
+
cmd,
|
|
96
|
+
stdout=subprocess.PIPE,
|
|
97
|
+
stderr=subprocess.PIPE,
|
|
98
|
+
text=True,
|
|
99
|
+
bufsize=1,
|
|
100
|
+
)
|
|
101
|
+
atexit.register(proc.kill)
|
|
102
|
+
|
|
103
|
+
url_future: Future[str] = Future()
|
|
104
|
+
|
|
105
|
+
def _reader(stream):
|
|
106
|
+
for line in stream:
|
|
107
|
+
line = line.strip()
|
|
108
|
+
logger.info(f"[cloudflared] {line}")
|
|
109
|
+
if not url_future.done():
|
|
110
|
+
# match any trycloudflare.com host with optional subdomains
|
|
111
|
+
pattern = re.compile(r"(https://[A-Za-z0-9.-]+\.trycloudflare\.com)")
|
|
112
|
+
m = pattern.search(line)
|
|
113
|
+
if m:
|
|
114
|
+
url_future.set_result(m.group(1))
|
|
115
|
+
|
|
116
|
+
threading.Thread(target=_reader, args=(proc.stdout,), daemon=True).start()
|
|
117
|
+
threading.Thread(target=_reader, args=(proc.stderr,), daemon=True).start()
|
|
118
|
+
|
|
119
|
+
return CloudflareTunnel(proc, url_future)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
|
|
2
|
-
langgraph_api/__init__.py,sha256=
|
|
2
|
+
langgraph_api/__init__.py,sha256=LcIlFjHZFfiF9Rd4UHoakmombOFkxIYk00I181frGBM,23
|
|
3
3
|
langgraph_api/api/__init__.py,sha256=IKKMrC5gCHTzjprbg8jgZDrAJRuqJfSUgEkZAgh3l-M,5771
|
|
4
4
|
langgraph_api/api/assistants.py,sha256=i-nxkScUB2g8bTVGtQIp1psABXlaY1aVx9pkB_UiRH8,14353
|
|
5
5
|
langgraph_api/api/mcp.py,sha256=KbR19dtFCpJEiKYj3IfepAuJij8YZVELuVp7JY_yu_o,13754
|
|
@@ -18,9 +18,9 @@ langgraph_api/auth/langsmith/client.py,sha256=eKchvAom7hdkUXauD8vHNceBDDUijrFgdT
|
|
|
18
18
|
langgraph_api/auth/middleware.py,sha256=jDA4t41DUoAArEY_PNoXesIUBJ0nGhh85QzRdn5EPD0,1916
|
|
19
19
|
langgraph_api/auth/noop.py,sha256=Bk6Nf3p8D_iMVy_OyfPlyiJp_aEwzL-sHrbxoXpCbac,586
|
|
20
20
|
langgraph_api/auth/studio_user.py,sha256=FzFQRROKDlA9JjtBuwyZvk6Mbwno5M9RVYjDO6FU3F8,186
|
|
21
|
-
langgraph_api/cli.py,sha256=
|
|
21
|
+
langgraph_api/cli.py,sha256=9Ou3tGDDY_VVLt5DFle8UviJdpI4ZigC5hElYvq2-To,14519
|
|
22
22
|
langgraph_api/command.py,sha256=3O9v3i0OPa96ARyJ_oJbLXkfO8rPgDhLCswgO9koTFA,768
|
|
23
|
-
langgraph_api/config.py,sha256=
|
|
23
|
+
langgraph_api/config.py,sha256=GWXgIDVPtpY7MBiAQMg7iluDzl7z6VYUsX_I1payq4k,10618
|
|
24
24
|
langgraph_api/cron_scheduler.py,sha256=i87j4pJrcsmsqMKeKUs69gaAjrGaSM3pM3jnXdN5JDQ,2630
|
|
25
25
|
langgraph_api/errors.py,sha256=Bu_i5drgNTyJcLiyrwVE_6-XrSU50BHf9TDpttki9wQ,1690
|
|
26
26
|
langgraph_api/graph.py,sha256=OMvYH6xO5KXwPxTSZ3e_yQZXDmT8nVsa0iqOWqKqYaw,21477
|
|
@@ -34,7 +34,7 @@ langgraph_api/js/client.http.mts,sha256=AGA-p8J85IcNh2oXZjDxHQ4PnQdJmt-LPcpZp6j0
|
|
|
34
34
|
langgraph_api/js/client.mts,sha256=7v5BcWsR5w6wGCsxhm6xryBgI-5vfu2Or1YmT-GdKyY,28766
|
|
35
35
|
langgraph_api/js/errors.py,sha256=Cm1TKWlUCwZReDC5AQ6SgNIVGD27Qov2xcgHyf8-GXo,361
|
|
36
36
|
langgraph_api/js/global.d.ts,sha256=j4GhgtQSZ5_cHzjSPcHgMJ8tfBThxrH-pUOrrJGteOU,196
|
|
37
|
-
langgraph_api/js/package.json,sha256=
|
|
37
|
+
langgraph_api/js/package.json,sha256=RTeBG4ubSdvB_zp2Nh_Cp2tCDZn7eFXCcJgFEYkQ3Mk,1289
|
|
38
38
|
langgraph_api/js/remote.py,sha256=pnyq3oGtMX3kGaBLU-lhMf_kKvc1a1324Z3e_KIKAD0,35117
|
|
39
39
|
langgraph_api/js/schema.py,sha256=7idnv7URlYUdSNMBXQcw7E4SxaPxCq_Oxwnlml8q5ik,408
|
|
40
40
|
langgraph_api/js/src/graph.mts,sha256=g86jOvbHj1B0o1jatBc2X5_JEZW2DSNwgUJ_kw1k8Cw,3569
|
|
@@ -48,7 +48,7 @@ langgraph_api/js/src/utils/importMap.mts,sha256=pX4TGOyUpuuWF82kXcxcv3-8mgusRezO
|
|
|
48
48
|
langgraph_api/js/src/utils/pythonSchemas.mts,sha256=98IW7Z_VP7L_CHNRMb3_MsiV3BgLE2JsWQY_PQcRR3o,685
|
|
49
49
|
langgraph_api/js/src/utils/serde.mts,sha256=OuyyO9btvwWd55rU_H4x91dFEJiaPxL-lL9O6Zgo908,742
|
|
50
50
|
langgraph_api/js/sse.py,sha256=lsfp4nyJyA1COmlKG9e2gJnTttf_HGCB5wyH8OZBER8,4105
|
|
51
|
-
langgraph_api/js/tests/api.test.mts,sha256=
|
|
51
|
+
langgraph_api/js/tests/api.test.mts,sha256=Zbnbyzy6xZwcM2r-_dTV8u9tAT592QK8pJ4JdI0xO9k,67694
|
|
52
52
|
langgraph_api/js/tests/auth.test.mts,sha256=A8JXfEep6S4jzduoSZeRQkqq9WsFbVE8Bvi3Hj_zx2w,21600
|
|
53
53
|
langgraph_api/js/tests/compose-postgres.auth.yml,sha256=iPfJbCeYZdV6GiRLiDn_f7qgpG4TyyGaQ4lV-ZXr6Qk,1768
|
|
54
54
|
langgraph_api/js/tests/compose-postgres.yml,sha256=w4B3YRS0QEnTcZH2-MY0DYvR_c5GcER0uDa1Ga_knf8,1960
|
|
@@ -56,7 +56,7 @@ langgraph_api/js/tests/graphs/.gitignore,sha256=26J8MarZNXh7snXD5eTpV3CPFTht5Znv
|
|
|
56
56
|
langgraph_api/js/tests/graphs/agent.css,sha256=QgcOC0W7IBsrg4pSqqpull-WTgtULZfx_lF_5ZxLdag,23
|
|
57
57
|
langgraph_api/js/tests/graphs/agent.mts,sha256=E9WMv0alMv0njUEECqEsqoRk9NXJUgXW7SyQJ3GOZ8k,5396
|
|
58
58
|
langgraph_api/js/tests/graphs/agent.ui.tsx,sha256=JDFJdpdIS6rglkXTaROSb1Is0j1kt5wN9ML8W4cuht8,175
|
|
59
|
-
langgraph_api/js/tests/graphs/agent_simple.mts,sha256=
|
|
59
|
+
langgraph_api/js/tests/graphs/agent_simple.mts,sha256=EDaQXM5x73HhcHoujezOX5C27uZdGdtfMVBE9o4hleE,2998
|
|
60
60
|
langgraph_api/js/tests/graphs/auth.mts,sha256=kF2TZP3n_urWigf0qgejZqTe93-341_Mhqe_qnBO_Io,3195
|
|
61
61
|
langgraph_api/js/tests/graphs/command.mts,sha256=YO1_cEs_n9VsH_-IediLnI4Yc8KRlp4qrprUZXpAlwM,1163
|
|
62
62
|
langgraph_api/js/tests/graphs/delay.mts,sha256=CFneKxqI4bGGK0lYjSbe80QirowPQlsRSuhDUKfydhk,703
|
|
@@ -71,9 +71,9 @@ langgraph_api/js/tests/graphs/yarn.lock,sha256=GwbaZr7inRbWzuuvrQKLHT72zYDKwteng
|
|
|
71
71
|
langgraph_api/js/tests/parser.test.mts,sha256=dEC8KTqKygeb1u39ZvpPqCT4HtfPD947nLmITt2buxA,27883
|
|
72
72
|
langgraph_api/js/tests/utils.mts,sha256=q1V9gvT63v95onlfK9W4iv3n9ZJO3h-0RD9TdDYuRyY,439
|
|
73
73
|
langgraph_api/js/ui.py,sha256=XNT8iBcyT8XmbIqSQUWd-j_00HsaWB2vRTVabwFBkik,2439
|
|
74
|
-
langgraph_api/js/yarn.lock,sha256=
|
|
74
|
+
langgraph_api/js/yarn.lock,sha256=_J3wSh92WUu6rBwTE5x2V22TZLWXGbkCSybjteB4tz0,83379
|
|
75
75
|
langgraph_api/logging.py,sha256=JJIzbNIgLCN6ClQ3tA-Mm5ffuBGvpRDSZsEvnIlsuu4,3693
|
|
76
|
-
langgraph_api/metadata.py,sha256=
|
|
76
|
+
langgraph_api/metadata.py,sha256=ptaxwmzdx2bUBSc1KRhqgF-Xnm-Zh2gqwSiHpl8LD9c,4482
|
|
77
77
|
langgraph_api/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
78
78
|
langgraph_api/middleware/http_logger.py,sha256=aj4mdisRobFePkD3Iy6-w_Mujwx4TQRaEhPvSd6HgLk,3284
|
|
79
79
|
langgraph_api/middleware/private_network.py,sha256=eYgdyU8AzU2XJu362i1L8aSFoQRiV7_aLBPw7_EgeqI,2111
|
|
@@ -84,23 +84,23 @@ langgraph_api/queue_entrypoint.py,sha256=gjtajZfnDXhsi7JElfmkY-p0ENBiKBDJ4Ugiw-e
|
|
|
84
84
|
langgraph_api/route.py,sha256=fM4qYCGbmH0a3_cV8uKocb1sLklehxO6HhdRXqLK6OM,4421
|
|
85
85
|
langgraph_api/schema.py,sha256=Frh_YOC3S1cDAMPUVanNi78ooSXK2WFpu9YkIVz5h14,5433
|
|
86
86
|
langgraph_api/serde.py,sha256=TVsx2QQtepf8Wsgsabcku1NV4Vbugu4Oujmdnq4qMS0,3964
|
|
87
|
-
langgraph_api/server.py,sha256=
|
|
87
|
+
langgraph_api/server.py,sha256=gluUa9L822atoMuAOxnlgSkHuuluT5vjW_u0EV5XL2o,6544
|
|
88
88
|
langgraph_api/sse.py,sha256=2wNodCOP2eg7a9mpSu0S3FQ0CHk2BBV_vv0UtIgJIcc,4034
|
|
89
89
|
langgraph_api/state.py,sha256=8jx4IoTCOjTJuwzuXJKKFwo1VseHjNnw_CCq4x1SW14,2284
|
|
90
90
|
langgraph_api/stream.py,sha256=SN96CLJ5QnSQ2YWRrkQb4K8XkdoSbloyFRj8N1vKcs8,11369
|
|
91
91
|
langgraph_api/thread_ttl.py,sha256=4vch4nu1UOiYcqYRd7bTHsfs0Ei_lXuy9nBQ0uVJLyo,1765
|
|
92
|
+
langgraph_api/tunneling/cloudflare.py,sha256=iKb6tj-VWPlDchHFjuQyep2Dpb-w2NGfJKt-WJG9LH0,3650
|
|
92
93
|
langgraph_api/utils.py,sha256=92mSti9GfGdMRRWyESKQW5yV-75Z9icGHnIrBYvdypU,3619
|
|
93
94
|
langgraph_api/validation.py,sha256=zMuKmwUEBjBgFMwAaeLZmatwGVijKv2sOYtYg7gfRtc,4950
|
|
94
95
|
langgraph_api/webhook.py,sha256=1ncwO0rIZcj-Df9sxSnFEzd1gP1bfS4okeZQS8NSRoE,1382
|
|
95
96
|
langgraph_api/worker.py,sha256=DX_EZZs47cfb4_1owBkjiq-Mrr2vUoeGjotWvKY21uc,11290
|
|
96
97
|
langgraph_license/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
97
|
-
langgraph_license/
|
|
98
|
-
langgraph_license/validation.py,sha256=Uu_G8UGO_WTlLsBEY0gTVWjRR4czYGfw5YAD3HLZoj0,203
|
|
98
|
+
langgraph_license/validation.py,sha256=ZKraAVJArAABKqrmHN-EN18ncoNUmRm500Yt1Sc7tUA,537
|
|
99
99
|
langgraph_runtime/__init__.py,sha256=O4GgSmu33c-Pr8Xzxj_brcK5vkm70iNTcyxEjICFZxA,1075
|
|
100
100
|
logging.json,sha256=3RNjSADZmDq38eHePMm1CbP6qZ71AmpBtLwCmKU9Zgo,379
|
|
101
101
|
openapi.json,sha256=YW4ND-N3adriEoNwxw7UD9endO2xUZoodCtwVIfa2dU,132261
|
|
102
|
-
langgraph_api-0.1.
|
|
103
|
-
langgraph_api-0.1.
|
|
104
|
-
langgraph_api-0.1.
|
|
105
|
-
langgraph_api-0.1.
|
|
106
|
-
langgraph_api-0.1.
|
|
102
|
+
langgraph_api-0.1.12.dist-info/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
|
|
103
|
+
langgraph_api-0.1.12.dist-info/METADATA,sha256=tHjMcJDzWDlUf_b1lDt4szCHsPsktPZey48MG7m-ZoI,4120
|
|
104
|
+
langgraph_api-0.1.12.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
105
|
+
langgraph_api-0.1.12.dist-info/entry_points.txt,sha256=3EYLgj89DfzqJHHYGxPH4A_fEtClvlRbWRUHaXO7hj4,77
|
|
106
|
+
langgraph_api-0.1.12.dist-info/RECORD,,
|
langgraph_license/validation.py
CHANGED
|
@@ -9,3 +9,14 @@ async def get_license_status() -> bool:
|
|
|
9
9
|
def plus_features_enabled() -> bool:
|
|
10
10
|
"""Always return false"""
|
|
11
11
|
return False
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
async def check_license_periodically(_: int = 60):
|
|
15
|
+
"""
|
|
16
|
+
Periodically re-verify the license.
|
|
17
|
+
If the license ever fails, you could decide to log,
|
|
18
|
+
raise an exception, or attempt a graceful shutdown.
|
|
19
|
+
"""
|
|
20
|
+
raise NotImplementedError(
|
|
21
|
+
"This is a noop license middleware. No license check is performed."
|
|
22
|
+
)
|
langgraph_license/middleware.py
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"""Middleware for license validation."""
|
|
2
|
-
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
from starlette.middleware.base import BaseHTTPMiddleware
|
|
6
|
-
from starlette.requests import Request
|
|
7
|
-
from starlette.responses import Response
|
|
8
|
-
from starlette.types import ASGIApp
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class LicenseValidationMiddleware(BaseHTTPMiddleware):
|
|
12
|
-
"""Noop license middleware"""
|
|
13
|
-
|
|
14
|
-
def __init__(self, app: ASGIApp):
|
|
15
|
-
"""Initialize middleware."""
|
|
16
|
-
super().__init__(app)
|
|
17
|
-
|
|
18
|
-
async def dispatch(self, request: Request, call_next: Any) -> Response:
|
|
19
|
-
"""Noop middleware."""
|
|
20
|
-
response = await call_next(request)
|
|
21
|
-
return response
|
|
File without changes
|
|
File without changes
|
|
File without changes
|