langgraph-api 0.12.0.dev20__py3-none-any.whl → 0.12.0.dev22__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 CHANGED
@@ -1 +1 @@
1
- __version__ = "0.12.0.dev20"
1
+ __version__ = "0.12.0.dev22"
@@ -497,10 +497,14 @@ async def patch_assistant(
497
497
  @retry_db
498
498
  async def delete_assistant(request: ApiRequest) -> Response:
499
499
  """Delete an assistant by ID.
500
-
501
- Query params:
502
- delete_threads: If "true", delete all threads where
503
- metadata.assistant_id matches this assistant.
500
+ ---
501
+ summary: Delete an assistant by ID.
502
+ description: |
503
+ Delete an assistant by ID.
504
+
505
+ Query params:
506
+ delete_threads: If "true", delete all threads where
507
+ metadata.assistant_id matches this assistant.
504
508
  """
505
509
  assistant_id = request.path_params["assistant_id"]
506
510
  validate_uuid(assistant_id, "Invalid assistant ID: must be a UUID")
@@ -97,25 +97,27 @@ def _make_manager(thread_id: str, send_event: Any = None) -> ThreadRunManager:
97
97
 
98
98
  async def _thread_events(request: Request) -> Response:
99
99
  """SSE stream scoped to a thread.
100
+ ---
101
+ summary: SSE stream scoped to a thread.
102
+ description: |
103
+ Body is an ``EventStreamRequest``:
100
104
 
101
- Body is an ``EventStreamRequest``:
102
-
103
- {
104
- "channels": ["values", "messages", ...],
105
- "namespaces": [["ns1"], ["ns2", "child"]], // optional
106
- "depth": 2, // optional
107
- "since": 42 // optional seq
108
- }
109
-
110
- On reconnect, clients pass the last ``seq`` they received as
111
- ``since`` in the body. Buffered events with ``seq > since`` are
112
- replayed before the stream goes live. The endpoint is POST-only, so
113
- browser-native ``EventSource`` auto-resume (``Last-Event-ID``)
114
- doesn't apply clients drive resume explicitly via the body.
115
-
116
- The filter applies for the lifetime of the connection; closing the
117
- connection unsubscribes. No state is persisted server-side beyond the
118
- connection.
105
+ {
106
+ "channels": ["values", "messages", ...],
107
+ "namespaces": [["ns1"], ["ns2", "child"]], // optional
108
+ "depth": 2, // optional
109
+ "since": 42 // optional seq
110
+ }
111
+
112
+ On reconnect, clients pass the last ``seq`` they received as
113
+ ``since`` in the body. Buffered events with ``seq > since`` are
114
+ replayed before the stream goes live. The endpoint is POST-only, so
115
+ browser-native ``EventSource`` auto-resume (``Last-Event-ID``)
116
+ doesn't apply clients drive resume explicitly via the body.
117
+
118
+ The filter applies for the lifetime of the connection; closing the
119
+ connection unsubscribes. No state is persisted server-side beyond the
120
+ connection.
119
121
  """
120
122
  thread_id = request.path_params["thread_id"]
121
123
  try:
@@ -297,11 +299,13 @@ async def _thread_events(request: Request) -> Response:
297
299
 
298
300
  async def _thread_command(request: Request) -> Response:
299
301
  """Handle a single protocol command scoped to a thread.
300
-
301
- Commands are stateless in the HTTP transport: a fresh manager is
302
- created, the command is dispatched, and results are returned. For
303
- ``run.start`` this creates/resumes a run; subsequent event streaming
304
- happens over a separate ``POST .../stream`` connection.
302
+ ---
303
+ summary: Handle a single protocol command scoped to a thread.
304
+ description: |
305
+ Commands are stateless in the HTTP transport: a fresh manager is
306
+ created, the command is dispatched, and results are returned. For
307
+ ``run.start`` this creates/resumes a run; subsequent event streaming
308
+ happens over a separate ``POST .../stream`` connection.
305
309
  """
306
310
  thread_id = request.path_params["thread_id"]
307
311
  try:
@@ -35,11 +35,11 @@ def _validate_namespace(namespace: tuple[str, ...]) -> Response | None:
35
35
  async def handle_event(
36
36
  action: str,
37
37
  value: Any,
38
- ) -> None:
38
+ ) -> Auth.types.FilterType | None:
39
39
  ctx = get_auth_ctx()
40
40
  if not ctx:
41
- return
42
- await _handle_event(
41
+ return None
42
+ return await _handle_event(
43
43
  Auth.types.AuthContext(
44
44
  user=ctx.user,
45
45
  permissions=ctx.permissions,
@@ -143,7 +143,13 @@ async def search_items(request: ApiRequest):
143
143
  "query": query,
144
144
  "refresh_ttl": payload.get("refresh_ttl"),
145
145
  }
146
- await handle_event("search", handler_payload)
146
+ auth_filter = await handle_event("search", handler_payload)
147
+ if auth_filter:
148
+ existing = handler_payload.get("filter")
149
+ if existing:
150
+ handler_payload["filter"] = {"$and": [existing, auth_filter]}
151
+ else:
152
+ handler_payload["filter"] = auth_filter
147
153
  items = await (await get_store()).asearch(
148
154
  handler_payload["namespace"],
149
155
  filter=handler_payload["filter"],
langgraph_api/api/ui.py CHANGED
@@ -1,6 +1,8 @@
1
+ import html
1
2
  import json
2
3
  import os
3
4
  import re
5
+ from urllib.parse import quote
4
6
 
5
7
  from anyio import open_file
6
8
  from orjson import loads
@@ -21,6 +23,16 @@ class UiSchema(TypedDict):
21
23
  _UI_SCHEMAS_CACHE: dict[str, UiSchema] | None = None
22
24
 
23
25
 
26
+ def _quote_path_segment(value: str) -> str:
27
+ """Encode a dynamic URL path segment for safe HTML attribute use."""
28
+ return quote(value, safe="")
29
+
30
+
31
+ def _html_safe_json_arg(value: object) -> str:
32
+ """Serialize a value for a JavaScript argument inside an HTML attribute."""
33
+ return html.escape(json.dumps(value), quote=True)
34
+
35
+
24
36
  async def load_ui_schemas() -> dict[str, UiSchema]:
25
37
  """Load and cache UI schema mappings from JSON file."""
26
38
  global _UI_SCHEMAS_CACHE
@@ -40,7 +52,6 @@ async def load_ui_schemas() -> dict[str, UiSchema]:
40
52
  async def handle_ui(request: ApiRequest) -> Response:
41
53
  """Serve UI HTML with appropriate script/style tags."""
42
54
  graph_id = request.path_params["graph_id"]
43
- host = request.headers.get("host")
44
55
  message = await request.json(schema=None)
45
56
 
46
57
  # Load UI file paths from schema
@@ -54,24 +65,20 @@ async def handle_ui(request: ApiRequest) -> Response:
54
65
  basename = os.path.basename(filepath)
55
66
  ext = os.path.splitext(basename)[1]
56
67
 
57
- # Use http:// protocol if accessing a localhost service
58
- def is_host(needle: str) -> bool:
59
- if not isinstance(host, str):
60
- return False
61
- return host.startswith(needle + ":") or host == needle
62
-
63
- protocol = "http:" if is_host("localhost") or is_host("127.0.0.1") else ""
64
68
  valid_js_name = re.sub(r"[^a-zA-Z0-9]", "_", graph_id)
69
+ asset_url = (
70
+ f"/ui/{_quote_path_segment(graph_id)}/{_quote_path_segment(basename)}"
71
+ )
72
+ safe_asset_url = html.escape(asset_url, quote=True)
65
73
 
66
74
  if ext == ".css":
67
- result.append(
68
- f'<link rel="stylesheet" href="{protocol}//{host}/ui/{graph_id}/{basename}" />'
69
- )
75
+ result.append(f'<link rel="stylesheet" href="{safe_asset_url}" />')
70
76
  elif ext == ".js":
71
- safe_name = json.dumps(message["name"]).replace("'", "&#39;")
77
+ safe_name = _html_safe_json_arg(message["name"])
72
78
  result.append(
73
- f'<script src="{protocol}//{host}/ui/{graph_id}/{basename}" '
74
- f"onload='__LGUI_{valid_js_name}.render({safe_name}, \"{{{{shadowRootId}}}}\")'>"
79
+ f'<script src="{safe_asset_url}" '
80
+ f"onload='__LGUI_{valid_js_name}.render("
81
+ f'{safe_name}, "{{{{shadowRootId}}}}")\'>'
75
82
  "</script>"
76
83
  )
77
84
 
@@ -49,6 +49,7 @@ STATS_INTERVAL_SECS = env("STATS_INTERVAL_SECS", cast=int, default=60)
49
49
  DATABASE_URI: str | None = env(
50
50
  "DATABASE_URI", cast=str, default=getenv("POSTGRES_URI", None)
51
51
  )
52
+ POSTGRES_IAM_AUTH_PROVIDER = env("POSTGRES_IAM_AUTH_PROVIDER", cast=str, default="")
52
53
  # Not in public docs: infrastructure, set by platform
53
54
  MIGRATIONS_PATH = env("MIGRATIONS_PATH", cast=str, default="/storage/migrations")
54
55
  POSTGRES_POOL_MAX_SIZE = env("LANGGRAPH_POSTGRES_POOL_MAX_SIZE", cast=int, default=150)
@@ -155,6 +156,7 @@ LANGGRAPH_AES_JSON_KEYS: frozenset[str] | None = env(
155
156
  # Not in public docs: infrastructure, set by platform
156
157
  REDIS_URI = env("REDIS_URI_CUSTOM", cast=str, default="") or env("REDIS_URI", cast=str)
157
158
  REDIS_CLUSTER = env("REDIS_CLUSTER", cast=bool, default=False)
159
+ REDIS_IAM_AUTH_PROVIDER = env("REDIS_IAM_AUTH_PROVIDER", cast=str, default="")
158
160
  REDIS_MAX_CONNECTIONS = env("REDIS_MAX_CONNECTIONS", cast=int, default=2000)
159
161
  REDIS_CONNECT_TIMEOUT = env("REDIS_CONNECT_TIMEOUT", cast=float, default=10.0)
160
162
  REDIS_HEALTH_CHECK_INTERVAL = env(
@@ -623,6 +623,12 @@ class ThreadRunManager:
623
623
  "no_such_interrupt",
624
624
  "Interrupt namespace does not match the pending interrupt.",
625
625
  )
626
+ # WS can surface ``input.requested`` before postgres/gRPC
627
+ # persists the thread-row interrupt. Reuse the HTTP settle
628
+ # barrier before enqueueing the resume run.
629
+ if not thread_state_fetched:
630
+ thread_state_ids = await self._collect_settled_interrupt_ids()
631
+ thread_state_fetched = True
626
632
  continue
627
633
  # HTTP fallback: the persisted lookup surfaces interrupts by id
628
634
  # only, so trust the client-claimed namespace and validate by
@@ -40,7 +40,8 @@ const logger = createLogger({
40
40
  ],
41
41
  });
42
42
 
43
- const HTTP_PORT = 5557;
43
+ // Pinned by the Python parent (see remote.py); base port is the fallback.
44
+ const HTTP_PORT = Number(process.env.LANGGRAPH_JS_GRAPH_HTTP_PORT) || 5557;
44
45
 
45
46
  const wrapHonoApp = (app: Hono) => {
46
47
  // We do this to avoid importing Hono from server dependencies
@@ -221,8 +221,9 @@ async function getOrExtractSchema(graphId: string) {
221
221
  return GRAPH_SCHEMA[graphId];
222
222
  }
223
223
 
224
- const GRAPH_PORT = 5556;
225
- const REMOTE_PORT = 5555;
224
+ // Pinned by the Python parent (see remote.py); base ports are the fallback.
225
+ const GRAPH_PORT = Number(process.env.LANGGRAPH_JS_GRAPH_PORT) || 5556;
226
+ const REMOTE_PORT = Number(process.env.LANGGRAPH_JS_REMOTE_PORT) || 5555;
226
227
 
227
228
  const RunnableConfigSchema = z.object({
228
229
  tags: z.array(z.string()).optional(),
@@ -40,6 +40,7 @@ from starlette.exceptions import HTTPException
40
40
  from starlette.requests import HTTPConnection, Request
41
41
  from starlette.routing import Route
42
42
 
43
+ from langgraph_api import config as lg_config
43
44
  from langgraph_api import store as api_store
44
45
  from langgraph_api.auth.custom import DotDict, ProxyUser
45
46
  from langgraph_api.config import LANGGRAPH_AUTH, LANGGRAPH_AUTH_TYPE
@@ -53,9 +54,40 @@ from langgraph_api.utils import get_auth_ctx, get_user_id
53
54
 
54
55
  logger = structlog.stdlib.get_logger(__name__)
55
56
 
56
- REMOTE_PORT = 5555
57
- GRAPH_PORT = 5556
58
- GRAPH_HTTP_PORT = 5557
57
+ # Loopback ports between the Python parent and its JS subprocess. Containers
58
+ # colocated in one pod share a network namespace, so each entrypoint gets its
59
+ # own range (via the offset below); LANGGRAPH_JS_*_PORT overrides any port.
60
+ _BASE_REMOTE_PORT = 5555
61
+ _BASE_GRAPH_PORT = 5556
62
+ _BASE_GRAPH_HTTP_PORT = 5557
63
+
64
+
65
+ def _js_port_offset(*, is_queue: bool) -> int:
66
+ """Port offset per entrypoint so colocated containers don't collide.
67
+
68
+ The queue worker and API server can run as separate containers in a single
69
+ pod (shared network namespace), so the queue worker gets its own range.
70
+ """
71
+ return 10 if is_queue else 0
72
+
73
+
74
+ def _resolve_js_port(base: int, offset: int, override: str | None) -> int:
75
+ """Explicit env override wins; otherwise base port plus entrypoint offset."""
76
+ if override:
77
+ return int(override)
78
+ return base + offset
79
+
80
+
81
+ _JS_PORT_OFFSET = _js_port_offset(is_queue=lg_config.IS_QUEUE_ENTRYPOINT)
82
+ REMOTE_PORT = _resolve_js_port(
83
+ _BASE_REMOTE_PORT, _JS_PORT_OFFSET, os.getenv("LANGGRAPH_JS_REMOTE_PORT")
84
+ )
85
+ GRAPH_PORT = _resolve_js_port(
86
+ _BASE_GRAPH_PORT, _JS_PORT_OFFSET, os.getenv("LANGGRAPH_JS_GRAPH_PORT")
87
+ )
88
+ GRAPH_HTTP_PORT = _resolve_js_port(
89
+ _BASE_GRAPH_HTTP_PORT, _JS_PORT_OFFSET, os.getenv("LANGGRAPH_JS_GRAPH_HTTP_PORT")
90
+ )
59
91
  SSL = ssl.create_default_context(cafile=certifi.where())
60
92
 
61
93
  if (port := int(os.getenv("PORT", "8080"))) and port in (GRAPH_PORT, REMOTE_PORT):
@@ -510,6 +542,10 @@ async def run_js_process(paths_str: str | None, watch: bool = False):
510
542
  "NODE_ENV": "development" if watch else "production",
511
543
  "CHOKIDAR_USEPOLLING": "true",
512
544
  **os.environ,
545
+ # Pin the child to the parent's resolved ports.
546
+ "LANGGRAPH_JS_REMOTE_PORT": str(REMOTE_PORT),
547
+ "LANGGRAPH_JS_GRAPH_PORT": str(GRAPH_PORT),
548
+ "LANGGRAPH_JS_GRAPH_HTTP_PORT": str(GRAPH_HTTP_PORT),
513
549
  },
514
550
  )
515
551
  logger.info(
@@ -567,6 +603,10 @@ async def run_js_http_process(
567
603
  "NODE_ENV": "development" if watch else "production",
568
604
  "CHOKIDAR_USEPOLLING": "true",
569
605
  **os.environ,
606
+ # Pin the child to the parent's resolved ports.
607
+ "LANGGRAPH_JS_REMOTE_PORT": str(REMOTE_PORT),
608
+ "LANGGRAPH_JS_GRAPH_PORT": str(GRAPH_PORT),
609
+ "LANGGRAPH_JS_GRAPH_HTTP_PORT": str(GRAPH_HTTP_PORT),
570
610
  },
571
611
  )
572
612
 
@@ -11,6 +11,7 @@ from typing import TYPE_CHECKING, Any, Literal
11
11
  import structlog
12
12
 
13
13
  from langgraph_api import __version__, config, metadata
14
+ from langgraph_api.http_metrics_utils import HTTP_LATENCY_BUCKETS
14
15
 
15
16
  if TYPE_CHECKING:
16
17
  from opentelemetry.exporter.otlp.proto.http.metric_exporter import (
@@ -74,6 +75,15 @@ METRIC_TIER_INFO = 2
74
75
  METRIC_TIER_DEBUG = 3
75
76
  METRIC_TIER_DEEP_DEBUG = 4
76
77
 
78
+ # Legacy /metrics used HTTP_LATENCY_BUCKETS in seconds. OTLP record_latency()
79
+ # stores milliseconds, so convert (drop +Inf — OTel adds the overflow bucket).
80
+ # Apply to every latency metric: OTel defaults max out at 10000ms (~10s), which
81
+ # caps p95/p99 for long HTTP polls (/join), run queue waits (300s alerts), and
82
+ # run execution (30m alerts).
83
+ HTTP_LATENCY_BUCKETS_MS: tuple[float, ...] = tuple(
84
+ b * 1000 for b in HTTP_LATENCY_BUCKETS if b != float("inf")
85
+ )
86
+
77
87
  MetricType = Literal["counter", "histogram", "latency", "gauge"]
78
88
 
79
89
 
@@ -614,8 +624,17 @@ class OTelMetricsReporter:
614
624
  name=name, description=metric.description
615
625
  )
616
626
  elif metric.metric_type in {"histogram", "latency"}:
627
+ # All latency metrics use legacy second-scale buckets (as ms).
628
+ # Non-latency histograms (bytes, counts) keep OTel defaults.
629
+ advisory = (
630
+ list(HTTP_LATENCY_BUCKETS_MS)
631
+ if metric.metric_type == "latency"
632
+ else None
633
+ )
617
634
  instrument = self._meter.create_histogram(
618
- name=name, description=metric.description
635
+ name=name,
636
+ description=metric.description,
637
+ explicit_bucket_boundaries_advisory=advisory,
619
638
  )
620
639
  else:
621
640
  # Gauges are handled via observable instruments (see _set_gauge).
@@ -73,10 +73,13 @@ def compute_python_publish_tags(
73
73
  ecr_prefix: str,
74
74
  img_api_dh: str,
75
75
  img_svr_dh: str,
76
+ fips: bool = False,
76
77
  ) -> list[str]:
77
78
  """Compute Python publish tags with workflow-compatible behavior."""
78
79
  py_version = _require_non_empty("py_version", py_version)
79
80
  distro = _require_non_empty("distro", distro)
81
+ if fips and distro != "wolfi":
82
+ raise ValueError("fips is only supported for wolfi images")
80
83
  sha = _require_non_empty("sha", sha)
81
84
  ver_patch = _require_non_empty("ver_patch", ver_patch)
82
85
  ver_major = _require_non_empty("ver_major", ver_major)
@@ -92,6 +95,8 @@ def compute_python_publish_tags(
92
95
  raise ValueError("gcr_projects must include at least one project")
93
96
 
94
97
  suf = _python_suffix(distro)
98
+ if fips:
99
+ suf = f"{suf}-fips"
95
100
  pyfrag = f"py{py_version}"
96
101
  runtime_alias = (
97
102
  f"{py_version}{suf}" if channel == "stable" else f"{channel}-{pyfrag}{suf}"
@@ -184,9 +189,12 @@ def compute_js_publish_tags(
184
189
  ar_project: str,
185
190
  ecr_prefix: str,
186
191
  img_js_dh: str,
192
+ fips: bool = False,
187
193
  ) -> list[str]:
188
194
  """Compute JS publish tags with workflow-compatible behavior."""
189
195
  node_version = _require_non_empty("node_version", node_version)
196
+ if fips and tag_suffix != "wolfi":
197
+ raise ValueError("fips is only supported for wolfi images")
190
198
  sha = _require_non_empty("sha", sha)
191
199
  ver_patch = _require_non_empty("ver_patch", ver_patch)
192
200
  ar_project = _require_non_empty("ar_project", ar_project)
@@ -199,6 +207,8 @@ def compute_js_publish_tags(
199
207
  raise ValueError("gcr_projects must include at least one project")
200
208
 
201
209
  suffix = f"-{tag_suffix}" if tag_suffix else ""
210
+ if fips:
211
+ suffix = f"{suffix}-fips"
202
212
  repo_base = "langgraphjs-api" if licensed else "langgraphjs-api-unlicensed"
203
213
  runtime_alias = (
204
214
  f"{node_version}{suffix}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-api
3
- Version: 0.12.0.dev20
3
+ Version: 0.12.0.dev22
4
4
  Author-email: Will Fu-Hinthorn <will@langchain.dev>, Josh Rogers <josh@langchain.dev>, Parker Rule <parker@langchain.dev>
5
5
  License: Elastic-2.0
6
6
  License-File: LICENSE
@@ -1,4 +1,4 @@
1
- langgraph_api/__init__.py,sha256=TKIcjxx-9aUyZmSvMeXz-Ek1FK_EguTANVH7RKLIqQA,29
1
+ langgraph_api/__init__.py,sha256=31NPyKqDoZwGlri-MWZ1Lg9OcNtBiCIvIQsCjSMT7uE,29
2
2
  langgraph_api/_factory_utils.py,sha256=5JsiJbg_YocVSryN2jwoZTg03-eyymlWMK6sKCmXwz0,5756
3
3
  langgraph_api/asgi_transport.py,sha256=XApY3lIWBZTMbbsl8dDJzl0cLGirmAGE0SifqZUnXvs,11896
4
4
  langgraph_api/asyncio.py,sha256=smqyAoO9nIyPPQRw1IVSCh85fwoZP4PEo-5dDhxGruc,10676
@@ -15,11 +15,11 @@ langgraph_api/http_metrics_utils.py,sha256=sjxF7SYGTzY0Wz_G0dzatsYNnWr31S6ujej4J
15
15
  langgraph_api/logging.py,sha256=V1RCnqVLuMvJtrBiyMMLfaEdbS3k5A2M8Unhr4FUUdQ,6801
16
16
  langgraph_api/metadata.py,sha256=hXkF55cWxxnjAJ0MB_PhU_4NfVzpLuwU4xwFDaAgi7I,10314
17
17
  langgraph_api/metrics_collector.py,sha256=gMLHL18rJyYl985AOmu9eH7W1ttdRdkPHzeyczjCOBw,8280
18
- langgraph_api/metrics_otlp.py,sha256=t9oJrxfxY2O5jY4JW2gONPKoBiBuklhzCrnZvn1qTxQ,28730
18
+ langgraph_api/metrics_otlp.py,sha256=B2J7RyIng524MRjSOp0yBNKT5FZtq4XwUYH0fcoCk8U,29652
19
19
  langgraph_api/otel_context.py,sha256=DWFwW4Yu88QY4W2J0IRcURR450Th9J2DupvDDkSkMBA,7166
20
20
  langgraph_api/patch.py,sha256=ViUknYvyQWS6y0f5XuaEoci2qB_mQv8vZl-oaUxsI6M,1448
21
21
  langgraph_api/queue_entrypoint.py,sha256=-9YnY_GhmDxEiGCc3k-7UqRKK_M3dPriits2iGgYlgU,11327
22
- langgraph_api/release_tags.py,sha256=BjgGj2vFcA7I0MDRXLw1sUA4jquz-DaKVS0Eq-dYSjE,9091
22
+ langgraph_api/release_tags.py,sha256=Dd2L2Mdh7c5D7RhFvdGCXROLH3WI1QKXbEqgjITFFoQ,9437
23
23
  langgraph_api/route.py,sha256=_KE8A8Q-J-QfqjGlyM2Kc6n5cirmgt8xmI5-pI8kVEE,8837
24
24
  langgraph_api/schema.py,sha256=4VhH4V9RmvBqO9MMPbaKk80PUQrPFyTMjDTT8nAZZ6w,15257
25
25
  langgraph_api/self_hosted_logs.py,sha256=FoUkPdtpt-nuEhejne8o1Q2phE9CccoHdoR_PvXPcBU,4442
@@ -41,15 +41,15 @@ langgraph_api/_checkpointer/_adapter.py,sha256=1jJi0vXoNKeCwNP26W8bmYrwe-fOWFqep
41
41
  langgraph_api/_checkpointer/protocol.py,sha256=udgYKMNtKWG_eLDwYkHXV3b2bZLZg8Rsfm3fjkhU-rU,3635
42
42
  langgraph_api/api/__init__.py,sha256=Zu1ew3dxYZu7cLRAjn-6HcYmtuQBdihlVFMKMJ77Y3c,9269
43
43
  langgraph_api/api/a2a.py,sha256=VPllgqfoLUQD6Eqob3RjcegjtKgLhphNGTrTqbNLoIY,95135
44
- langgraph_api/api/assistants.py,sha256=4v1TpkeeSF7vFrbnOKIvh7BY4K0WamzEdMeTAzwRElE,20786
45
- langgraph_api/api/event_streaming.py,sha256=nvoaKz4QGklX5YUmY9WQ3vSwhQ1Q81QeQWNR8aEXUz8,17571
44
+ langgraph_api/api/assistants.py,sha256=ZYK2B4IFaIMvkfklmmQgrqhaI55M7k6QKb2cETnVP7A,20900
45
+ langgraph_api/api/event_streaming.py,sha256=jvoBp5qHI92JJHsx4f9LEpb0i0VE31G_qFhS5JQWtlA,17809
46
46
  langgraph_api/api/meta.py,sha256=5s017GfMs-Ghq6Z5K6yW4UjbVFzCsmeXKn4UEJmfs98,4757
47
47
  langgraph_api/api/openapi.py,sha256=Zkdlb9mjrQyHro1TtrDIWVuaBDovxx-uGWJ1fZMOg54,12604
48
48
  langgraph_api/api/profile.py,sha256=CA1ZkHALOuP8orYTICnEhcG_JnnA2wnyjbWyeb117jA,3455
49
49
  langgraph_api/api/runs.py,sha256=eqaeSUXg0mKROEyGTG7ur6RdSFHKIq6hMDEiYxO2R7Q,35197
50
- langgraph_api/api/store.py,sha256=Y5bMwi03nljlVCiiN91TGkiZj5iUITO68uyctBdYLhE,6656
50
+ langgraph_api/api/store.py,sha256=6ixv6VLIBSUQjEChZBx85DzSf__Yox9wlNd9hgdxsS4,6936
51
51
  langgraph_api/api/threads.py,sha256=atUJnC49tpdhx80OdyzT6NNV3J0pN1R1e4nq7qeXD6c,19778
52
- langgraph_api/api/ui.py,sha256=RalnZm1HArbC2X7fYCFtNeTJpSOQCzkLrdA0lcVmWQw,2695
52
+ langgraph_api/api/ui.py,sha256=A1cRxaMK_4pb192mrZ_LMxLSFb8NriYwwvjeDdNDD7k,2803
53
53
  langgraph_api/api/mcp/__init__.py,sha256=T9W88PH9OqQtnjP7eFFa_163pFulDGU_AXk_PYBfEJA,469
54
54
  langgraph_api/api/mcp/_constants.py,sha256=jmMn_H77KdXP3c5NXIGifFk72B8tK2pNE5ufvJ7RdtY,555
55
55
  langgraph_api/api/mcp/_handlers.py,sha256=245jg8yMAwEnXLSq2lwhW8ks0FgIXMbTbEuSejwrnh4,12416
@@ -65,7 +65,7 @@ langgraph_api/auth/studio_user.py,sha256=gNCicIo6cYaHmFj2sEdsvDYkKW7NWfGXGS2tTAM
65
65
  langgraph_api/auth/langsmith/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  langgraph_api/auth/langsmith/backend.py,sha256=Y6-VxD7zfV1jzGdjmQ66CgNa3SenLbo3d_375CcKZ9U,3770
67
67
  langgraph_api/auth/langsmith/client.py,sha256=79kwCVeHU64nsHsxWipfZhf44lM6vfs2nlfTxlJF6LU,4142
68
- langgraph_api/config/__init__.py,sha256=lSIVNfG_9LrJm2mKM1m46e1A8aaMwMqOEbGMgHcWY_Q,26300
68
+ langgraph_api/config/__init__.py,sha256=GiL2uV0ng-7vH1k5VJBWfSYgsMgbVM9qmocJ4gym11g,26464
69
69
  langgraph_api/config/_parse.py,sha256=RpfZgFAPJlRMv13AzGr3kAYbIrqHcgjzO8IgeboTw4A,3922
70
70
  langgraph_api/config/schemas.py,sha256=cHzVvepthpD7DDeWE2ytkOHah-iDNH7xRx9dSWUatQI,20864
71
71
  langgraph_api/encryption/__init__.py,sha256=gaCZ00CocSbqSqrDn6XJHaSp2CZCnC8qnrD9G4fbzyI,363
@@ -79,7 +79,7 @@ langgraph_api/event_streaming/capabilities.py,sha256=qjVbhCjl1VEQPGeiDxeJAhYGI_7
79
79
  langgraph_api/event_streaming/constants.py,sha256=eGsm-NvOlqV3gNxDO5vlr00FdngmgEQf59zuHSi_74E,1378
80
80
  langgraph_api/event_streaming/event_normalizers.py,sha256=5bVSqGPW-Uh7WX91qgTfwpK433pCSv_wchpbzW8TLi4,2794
81
81
  langgraph_api/event_streaming/namespace.py,sha256=aJDFt45Or2_bQdRpKJgdFhBgTDj6PYl7Coz5GzfbM84,1509
82
- langgraph_api/event_streaming/service.py,sha256=Ipm6LHwQFfEKT4BjeUex7R55bvKb97M8W9gCsKTNgmw,50119
82
+ langgraph_api/event_streaming/service.py,sha256=vn0l1Urly4kkFIhHmCWWM2zCu-of9m9wOIq1kPdbJJA,50504
83
83
  langgraph_api/event_streaming/session.py,sha256=8kx5nxJvJlfIu5fFzQCxEl-8UBJEtxftBLhCYgXMNwo,75947
84
84
  langgraph_api/event_streaming/state_normalizers.py,sha256=vgT4O4tJPr9VDBMn1EP994ieDGDYP43sROnOyLjkEAE,13659
85
85
  langgraph_api/event_streaming/types.py,sha256=RyZqfqgH-jmmmmAFQj5f6nH9M1rGK93zVG7nlmvqZgc,3647
@@ -101,12 +101,12 @@ langgraph_api/js/.prettierrc,sha256=0es3ovvyNIqIw81rPQsdt1zCQcOdBqyR_DMbFE4Ifms,
101
101
  langgraph_api/js/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
102
  langgraph_api/js/base.py,sha256=CJihwc51MwOVkis80f8zudRa1fQz_5jrom4rY8trww8,1133
103
103
  langgraph_api/js/build.mts,sha256=-LVN4xxh5tY0JvJFZKT8vE6uT-O4oXjQlgCp9NwmVnQ,3380
104
- langgraph_api/js/client.http.mts,sha256=0k9O9q_3xouymBrx50r_xQchvx-Wx7C0UHzExlScXBE,5884
105
- langgraph_api/js/client.mts,sha256=W37FC_u9qdT6nuo46OFqXQo-L-nrHaAJ-ICddwSt_EU,38793
104
+ langgraph_api/js/client.http.mts,sha256=ARlTJURLJamgvyaPlBCYEAHFnXQnPpzzUXWKwXiebnw,6011
105
+ langgraph_api/js/client.mts,sha256=WRNW6gfkkxR7RVSXfrPqD3yTlpWKpERCmtlxddupIm8,38965
106
106
  langgraph_api/js/errors.py,sha256=Cm1TKWlUCwZReDC5AQ6SgNIVGD27Qov2xcgHyf8-GXo,361
107
107
  langgraph_api/js/global.d.ts,sha256=j4GhgtQSZ5_cHzjSPcHgMJ8tfBThxrH-pUOrrJGteOU,196
108
108
  langgraph_api/js/package.json,sha256=Zb7p6aPftSGzlxp077CnUlgvb49SQqeKdp_ZCh7qUgY,1381
109
- langgraph_api/js/remote.py,sha256=R6JcRJoYnwjJJpUQklUzut5SHcidewqzy2R9OgK3dTQ,46027
109
+ langgraph_api/js/remote.py,sha256=bxIX-LQ35uyotRY-0M1k3Ir0boCYT6OoW65svHpKwuU,47836
110
110
  langgraph_api/js/schema.py,sha256=M4fLtr50O1jck8H1hm_0W4cZOGYGdkrB7riLyCes4oY,438
111
111
  langgraph_api/js/sse.py,sha256=IfcEpknyZeqqjYTOWRdijc6o2EBfatbWCZarGQQ0SQI,4088
112
112
  langgraph_api/js/traceblock.mts,sha256=QtGSN5VpzmGqDfbArrGXkMiONY94pMQ5CgzetT_bKYg,761
@@ -236,8 +236,8 @@ langgraph_grpc_common/proto/store_pb2.py,sha256=uAYM7OcdEOK12iRcPYihC2suSeCo_Qdb
236
236
  langgraph_grpc_common/proto/store_pb2.pyi,sha256=_dcxyxV8moR6H67qU42r2h2p_Ub-PZSHs3OoS9KMdSY,27782
237
237
  langgraph_grpc_common/proto/store_pb2_grpc.py,sha256=wSD65QgFkYTkPTHcf7VhyI2FQ7UH_RgIf3vQW3VYlsM,3324
238
238
  langgraph_grpc_common/proto/store_pb2_grpc.pyi,sha256=oS1h2cDoq2OjyM8xazcmc8LwRDC5oCAD0zto2QUmPQw,2027
239
- langgraph_api-0.12.0.dev20.dist-info/METADATA,sha256=gj9GSR38Lrc1p1cb1u0BJKG1oXzuYvvnxSWfdI3y99I,4631
240
- langgraph_api-0.12.0.dev20.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
241
- langgraph_api-0.12.0.dev20.dist-info/entry_points.txt,sha256=hGedv8n7cgi41PypMfinwS_HfCwA7xJIfS0jAp8htV8,78
242
- langgraph_api-0.12.0.dev20.dist-info/licenses/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
243
- langgraph_api-0.12.0.dev20.dist-info/RECORD,,
239
+ langgraph_api-0.12.0.dev22.dist-info/METADATA,sha256=M4jOTXtygUqW6Fe7xtPKiz8_i-DAB4lQRNUTtVKza6k,4631
240
+ langgraph_api-0.12.0.dev22.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
241
+ langgraph_api-0.12.0.dev22.dist-info/entry_points.txt,sha256=hGedv8n7cgi41PypMfinwS_HfCwA7xJIfS0jAp8htV8,78
242
+ langgraph_api-0.12.0.dev22.dist-info/licenses/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
243
+ langgraph_api-0.12.0.dev22.dist-info/RECORD,,