langgraph-cli 0.4.32.dev0__py3-none-any.whl → 0.4.33__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_cli/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.4.32.dev0"
1
+ __version__ = "0.4.33"
langgraph_cli/config.py CHANGED
@@ -6,6 +6,7 @@ import re
6
6
  import shlex
7
7
  import textwrap
8
8
  from collections import Counter
9
+ from collections.abc import Iterable
9
10
  from typing import Literal, NamedTuple
10
11
 
11
12
  import click
@@ -36,6 +37,10 @@ DISALLOWED_BUILD_COMMAND_CHARS = [
36
37
  # This blocks background execution (cmd &) while allowing command
37
38
  # chaining (cmd1 && cmd2) which is common in build commands.
38
39
  _SINGLE_AMPERSAND_RE = re.compile(r"(?<!&)&(?:&&)*(?!&)")
40
+ _GIT_HTTP_AUTHORITY_RES = (
41
+ re.compile(r"git\+https?://(?P<authority>[^/\s\"']+)", re.I),
42
+ re.compile(r"\bgit\s*=\s*[\"']https?://(?P<authority>[^/\s\"']+)", re.I),
43
+ )
39
44
  _API_VERSION_PATTERN = re.compile(
40
45
  r"^(?P<major>\d+)"
41
46
  r"(?:\.(?P<minor>\d+))?"
@@ -78,6 +83,62 @@ def has_disallowed_build_command_content(command: str) -> bool:
78
83
  return False
79
84
 
80
85
 
86
+ def _has_git_http_url_userinfo(dependency: str) -> bool:
87
+ """Check whether a Git HTTP URL contains userinfo."""
88
+ return any(
89
+ "@" in match.group("authority")
90
+ for pattern in _GIT_HTTP_AUTHORITY_RES
91
+ for match in pattern.finditer(dependency)
92
+ )
93
+
94
+
95
+ def _validate_git_http_url_userinfo(
96
+ values: Iterable[str], *, source: pathlib.Path | None = None
97
+ ) -> None:
98
+ """Reject credential-bearing Git HTTP URLs without echoing their values."""
99
+ if not any(_has_git_http_url_userinfo(value) for value in values):
100
+ return
101
+ message = (
102
+ "Git dependency URLs must not contain credentials or other URL "
103
+ "userinfo because generated Dockerfiles and image layers can retain "
104
+ "them. Use a credential-free Git URL and provide short-lived "
105
+ "credentials through your build environment's secret-backed Git "
106
+ "credential helper."
107
+ )
108
+ if source is not None:
109
+ message += f" Found in: {source}"
110
+ raise click.UsageError(message)
111
+
112
+
113
+ def _validate_git_http_url_userinfo_files(paths: Iterable[pathlib.Path]) -> None:
114
+ """Reject credential-bearing Git HTTP URLs in dependency files."""
115
+ for path in paths:
116
+ path = path.resolve()
117
+ if not path.is_file():
118
+ continue
119
+ try:
120
+ contents = path.read_text(encoding="utf-8", errors="replace")
121
+ except OSError:
122
+ raise click.UsageError(
123
+ f"Could not inspect dependency file for embedded credentials: {path}"
124
+ ) from None
125
+ _validate_git_http_url_userinfo([contents], source=path)
126
+
127
+
128
+ def _validate_local_dependency_files(config_path: pathlib.Path, config: Config) -> None:
129
+ """Validate dependency files copied into a non-uv Python image."""
130
+ paths: list[pathlib.Path] = []
131
+ for dependency in config["dependencies"]:
132
+ if not isinstance(dependency, str) or not dependency.startswith("."):
133
+ continue
134
+ root = (config_path.parent / dependency).resolve()
135
+ paths.extend(
136
+ root / name
137
+ for name in ("requirements.txt", "pyproject.toml", "setup.py", "setup.cfg")
138
+ )
139
+ _validate_git_http_url_userinfo_files(paths)
140
+
141
+
81
142
  MIN_PYTHON_VERSION = "3.11"
82
143
  DEFAULT_PYTHON_VERSION = "3.11"
83
144
 
@@ -320,7 +381,9 @@ def _get_source_kind(config: Config) -> str | None:
320
381
  return kind if isinstance(kind, str) else None
321
382
 
322
383
 
323
- def validate_config(config: Config) -> Config:
384
+ def validate_config(
385
+ config: Config, *, source_path: pathlib.Path | None = None
386
+ ) -> Config:
324
387
  """Validate a configuration dictionary."""
325
388
 
326
389
  graphs = config.get("graphs", {})
@@ -415,6 +478,15 @@ def validate_config(config: Config) -> Config:
415
478
  ' "source": {"kind": "uv", "root": ".."}'
416
479
  )
417
480
 
481
+ _validate_git_http_url_userinfo(
482
+ (
483
+ dependency
484
+ for dependency in config["dependencies"]
485
+ if isinstance(dependency, str)
486
+ ),
487
+ source=source_path,
488
+ )
489
+
418
490
  source = config.get("source")
419
491
  source_kind = _get_source_kind(config)
420
492
  if source is not None and not isinstance(source, dict):
@@ -609,7 +681,7 @@ def validate_config_file(config_path: pathlib.Path) -> Config:
609
681
  """Load and validate a configuration file."""
610
682
  with open(config_path) as f:
611
683
  config = json.load(f)
612
- validated = validate_config(config)
684
+ validated = validate_config(config, source_path=config_path.resolve())
613
685
  # Enforce the package.json doesn't enforce an
614
686
  # incompatible Node.js version
615
687
  if validated.get("node_version"):
@@ -1280,6 +1352,7 @@ def python_config_to_docker(
1280
1352
  api_version=api_version,
1281
1353
  build_tools_to_uninstall=build_tools_to_uninstall,
1282
1354
  )
1355
+ _validate_local_dependency_files(config_path, config)
1283
1356
  if pip_installer == "auto":
1284
1357
  if _image_supports_uv(base_image):
1285
1358
  pip_installer = "uv"
@@ -1490,7 +1563,18 @@ def node_config_to_docker(
1490
1563
  ) -> tuple[str, dict[str, str]]:
1491
1564
  # Calculate paths for monorepo support
1492
1565
  install_root = (
1493
- pathlib.Path(build_context).resolve() if build_context else config_path.parent
1566
+ pathlib.Path(build_context).resolve()
1567
+ if build_context
1568
+ else config_path.parent.resolve()
1569
+ )
1570
+ config_root = config_path.parent.resolve()
1571
+ dependency_roots = (
1572
+ (install_root, config_root) if install_root != config_root else (install_root,)
1573
+ )
1574
+ _validate_git_http_url_userinfo_files(
1575
+ root / name
1576
+ for root in dependency_roots
1577
+ for name in ("package.json", "package-lock.json", "yarn.lock", "pnpm-lock.yaml")
1494
1578
  )
1495
1579
  install_cmd = install_command or _get_node_pm_install_cmd(install_root)
1496
1580
  if build_context:
langgraph_cli/deploy.py CHANGED
@@ -32,7 +32,7 @@ from langgraph_cli.host_backend import (
32
32
  HostBackendError,
33
33
  SourceName,
34
34
  )
35
- from langgraph_cli.image_reference import ImageReference
35
+ from langgraph_cli.image_reference import DIGEST_SEPARATOR, ImageReference
36
36
  from langgraph_cli.progress import Progress
37
37
  from langgraph_cli.util import warn_non_wolfi_distro
38
38
 
@@ -624,6 +624,41 @@ def format_deployments_table(deployments: Sequence[dict[str, object]]) -> str:
624
624
  return "\n".join(lines)
625
625
 
626
626
 
627
+ def _extract_listener_namespaces(listener: dict[str, object]) -> str:
628
+ compute_config = listener.get("compute_config")
629
+ namespaces = (
630
+ compute_config.get("k8s_namespaces")
631
+ if isinstance(compute_config, dict)
632
+ else None
633
+ )
634
+ if isinstance(namespaces, list) and namespaces:
635
+ return ", ".join(str(namespace) for namespace in namespaces)
636
+ return "-"
637
+
638
+
639
+ def format_listeners_table(listeners: Sequence[dict[str, object]]) -> str:
640
+ headers = ("Listener ID", "Compute ID", "Namespaces")
641
+ rows = [
642
+ (
643
+ str(listener.get("id", "-") or "-"),
644
+ str(listener.get("compute_id", "-") or "-"),
645
+ _extract_listener_namespaces(listener),
646
+ )
647
+ for listener in listeners
648
+ ]
649
+ widths = [
650
+ max(len(headers[index]), *(len(row[index]) for row in rows))
651
+ for index in range(len(headers))
652
+ ]
653
+
654
+ def format_row(row: Sequence[str]) -> str:
655
+ return " ".join(value.ljust(widths[index]) for index, value in enumerate(row))
656
+
657
+ lines = [format_row(headers), format_row(tuple("-" * width for width in widths))]
658
+ lines.extend(format_row(row) for row in rows)
659
+ return "\n".join(lines)
660
+
661
+
627
662
  def format_revisions_table(revisions: Sequence[dict[str, object]]) -> str:
628
663
  headers = ("Revision ID", "Status", "Created At")
629
664
  latest_deployed_seen = False
@@ -1544,9 +1579,9 @@ def _ensure_customer_registry_source(existing: ExistingDeployment) -> None:
1544
1579
  if existing.source != _CUSTOMER_REGISTRY_SOURCE:
1545
1580
  raise click.UsageError(
1546
1581
  f"Deployment {existing.id} was not created from an external image "
1547
- "and cannot be updated with --push-to. Run without --push-to to keep "
1548
- "its current build mode, or use a different --name to create a new "
1549
- "deployment."
1582
+ "and cannot be updated with --push-to or --image-uri. Run without "
1583
+ "either flag to keep its current build mode, or use a different "
1584
+ "--name to create a new deployment."
1550
1585
  )
1551
1586
 
1552
1587
 
@@ -1599,9 +1634,22 @@ class RemoteBuildSource:
1599
1634
 
1600
1635
 
1601
1636
  @dataclass(frozen=True, slots=True)
1602
- class CustomerRegistrySource:
1637
+ class BuildAndPush:
1603
1638
  reference: ImageReference
1604
1639
  prebuilt_image: str | None
1640
+
1641
+
1642
+ @dataclass(frozen=True, slots=True)
1643
+ class PublishedImage:
1644
+ image_uri: str
1645
+
1646
+
1647
+ ImageSource = BuildAndPush | PublishedImage
1648
+
1649
+
1650
+ @dataclass(frozen=True, slots=True)
1651
+ class CustomerRegistrySource:
1652
+ image: ImageSource
1605
1653
  requested_placement: RequestedPlacement
1606
1654
 
1607
1655
  def run(self, ctx: DeployContext) -> DeployOutcome:
@@ -1686,16 +1734,22 @@ class CustomerRegistrySource:
1686
1734
  )
1687
1735
 
1688
1736
  def _publish(self, ctx: DeployContext, step: int) -> tuple[str, int]:
1689
- image = str(self.reference)
1737
+ if isinstance(self.image, PublishedImage):
1738
+ return self.image.image_uri, step
1739
+ image = str(self.image.reference)
1690
1740
  with Runner() as runner:
1691
- if self.prebuilt_image:
1692
- _log_deploy_step(step, f"Validating image {self.prebuilt_image}")
1741
+ if self.image.prebuilt_image:
1742
+ _log_deploy_step(step, f"Validating image {self.image.prebuilt_image}")
1693
1743
  _validate_prebuilt_image(
1694
- runner, self.prebuilt_image, verbose=ctx.verbose
1744
+ runner, self.image.prebuilt_image, verbose=ctx.verbose
1695
1745
  )
1696
1746
  runner.run(
1697
1747
  subp_exec(
1698
- "docker", "tag", self.prebuilt_image, image, verbose=ctx.verbose
1748
+ "docker",
1749
+ "tag",
1750
+ self.image.prebuilt_image,
1751
+ image,
1752
+ verbose=ctx.verbose,
1699
1753
  )
1700
1754
  )
1701
1755
  else:
@@ -1733,20 +1787,35 @@ def _push_reference(push_to: str, tag: str | None) -> ImageReference:
1733
1787
  return reference.with_tag(normalize_image_tag(tag or _DEFAULT_IMAGE_TAG))
1734
1788
 
1735
1789
 
1790
+ def _validate_image_uri(image_uri: str) -> str:
1791
+ value = image_uri.strip()
1792
+ if not value:
1793
+ raise click.UsageError("--image-uri must not be empty.")
1794
+ if DIGEST_SEPARATOR not in value:
1795
+ raise click.UsageError(
1796
+ "--image-uri must pin a digest, e.g. "
1797
+ f"repository{DIGEST_SEPARATOR}<sha256 hex>. Kubernetes can cache "
1798
+ "images by tag, so redeploying a mutable tag may silently keep "
1799
+ "running the previous image."
1800
+ )
1801
+ return value
1802
+
1803
+
1736
1804
  def _select_source(
1737
1805
  *,
1738
1806
  push_to: str | None,
1739
1807
  image: str | None,
1808
+ image_uri: str | None,
1740
1809
  image_name: str | None,
1741
1810
  tag: str | None,
1742
1811
  remote_build_flag: bool | None,
1743
1812
  placement: RequestedPlacement,
1744
1813
  selector: DeploymentSelector,
1745
1814
  ) -> DeploymentSource:
1746
- if push_to is None and placement.requested:
1815
+ if push_to is None and image_uri is None and placement.requested:
1747
1816
  raise click.UsageError(
1748
1817
  "--listener-id and --k8s-namespace only apply when creating a "
1749
- "deployment with --push-to."
1818
+ "deployment with --push-to or --image-uri."
1750
1819
  )
1751
1820
  if placement.requested and isinstance(selector, ById):
1752
1821
  raise click.UsageError(
@@ -1754,6 +1823,19 @@ def _select_source(
1754
1823
  "they cannot be set for an existing --deployment-id. Drop them, or "
1755
1824
  "create a new deployment with --name."
1756
1825
  )
1826
+ if image_uri is not None:
1827
+ if push_to is not None:
1828
+ raise click.UsageError("--image-uri cannot be combined with --push-to.")
1829
+ if image is not None:
1830
+ raise click.UsageError("--image-uri cannot be combined with --image.")
1831
+ if tag is not None:
1832
+ raise click.UsageError("--image-uri cannot be combined with --tag.")
1833
+ if remote_build_flag is not None:
1834
+ raise click.UsageError("--image-uri cannot be combined with --remote.")
1835
+ return CustomerRegistrySource(
1836
+ image=PublishedImage(_validate_image_uri(image_uri)),
1837
+ requested_placement=placement,
1838
+ )
1757
1839
  if push_to is not None:
1758
1840
  if remote_build_flag is True:
1759
1841
  raise click.UsageError("--push-to cannot be combined with --remote.")
@@ -1761,8 +1843,7 @@ def _select_source(
1761
1843
  if image is None:
1762
1844
  _require_local_docker()
1763
1845
  return CustomerRegistrySource(
1764
- reference=reference,
1765
- prebuilt_image=image,
1846
+ image=BuildAndPush(reference=reference, prebuilt_image=image),
1766
1847
  requested_placement=placement,
1767
1848
  )
1768
1849
  if image and remote_build_flag is True:
@@ -2075,19 +2156,30 @@ def _deploy_base_options(
2075
2156
  "Give the tag here or with --tag (default: latest)."
2076
2157
  ),
2077
2158
  ),
2159
+ click.option(
2160
+ "--image-uri",
2161
+ help=(
2162
+ "Deploy an image that's already in a registry you manage, "
2163
+ "without building, retagging, or pushing anything. For "
2164
+ "self-hosted and hybrid LangSmith. Give the full reference, "
2165
+ "e.g. 123456789.dkr.ecr.us-east-1.amazonaws.com/agents/"
2166
+ "my-agent:v1.2.3 or ...@sha256:<digest>. Cannot be combined "
2167
+ "with --push-to, --image, --tag, or --remote."
2168
+ ),
2169
+ ),
2078
2170
  click.option(
2079
2171
  "--listener-id",
2080
2172
  help=(
2081
2173
  "Listener that will run the deployment, for workspaces that "
2082
2174
  "deploy through a listener in your own cluster. Only used when "
2083
- "creating a deployment with --push-to."
2175
+ "creating a deployment with --push-to or --image-uri."
2084
2176
  ),
2085
2177
  ),
2086
2178
  click.option(
2087
2179
  "--k8s-namespace",
2088
2180
  help=(
2089
2181
  "Kubernetes namespace the listener deploys into. Only used when "
2090
- "creating a deployment with --push-to."
2182
+ "creating a deployment with --push-to or --image-uri."
2091
2183
  ),
2092
2184
  ),
2093
2185
  click.option(
@@ -2200,6 +2292,7 @@ def _deploy_cmd(
2200
2292
  image_name: str | None,
2201
2293
  image: str | None,
2202
2294
  push_to: str | None,
2295
+ image_uri: str | None,
2203
2296
  listener_id: str | None,
2204
2297
  k8s_namespace: str | None,
2205
2298
  tag: str | None,
@@ -2273,6 +2366,7 @@ def _deploy_cmd(
2273
2366
  source = _select_source(
2274
2367
  push_to=push_to,
2275
2368
  image=image,
2369
+ image_uri=image_uri,
2276
2370
  image_name=image_name,
2277
2371
  tag=tag,
2278
2372
  remote_build_flag=remote_build_flag,
@@ -2408,6 +2502,41 @@ def deploy_list(
2408
2502
  click.echo(format_deployments_table(deployments))
2409
2503
 
2410
2504
 
2505
+ # ---------------------------------------------------------------------------
2506
+ # deploy listeners
2507
+ # ---------------------------------------------------------------------------
2508
+
2509
+
2510
+ @deploy.group(
2511
+ "listeners",
2512
+ cls=NestedHelpGroup,
2513
+ help="[Beta] Inspect listeners available to this workspace.",
2514
+ )
2515
+ def deploy_listeners() -> None:
2516
+ pass
2517
+
2518
+
2519
+ @OPT_HOST_API_KEY
2520
+ @OPT_HOST_URL
2521
+ @deploy_listeners.command(
2522
+ "list",
2523
+ help=(
2524
+ "[Beta] List listeners available to this workspace.\n\n"
2525
+ "Pass a listener's id to `langgraph deploy --push-to ... "
2526
+ "--listener-id <id>` to deploy through it."
2527
+ ),
2528
+ )
2529
+ def deploy_listeners_list(api_key: str | None, host_url: str | None) -> None:
2530
+ client = _create_host_backend_client(host_url, api_key)
2531
+ listeners = _call_host_backend_with_optional_tenant(
2532
+ client, lambda c: c.list_listeners()
2533
+ )
2534
+ if not listeners:
2535
+ click.echo("No listeners found for this workspace.")
2536
+ return
2537
+ click.echo(format_listeners_table(listeners))
2538
+
2539
+
2411
2540
  # ---------------------------------------------------------------------------
2412
2541
  # deploy revisions
2413
2542
  # ---------------------------------------------------------------------------
langgraph_cli/schemas.py CHANGED
@@ -650,7 +650,8 @@ class Config(TypedDict, total=False):
650
650
 
651
651
  pip_config_file: str | None
652
652
  """Optional. Path to a pip config file (e.g., "/etc/pip.conf" or "pip.ini") for controlling
653
- package installation (custom indices, credentials, etc.).
653
+ package installation (custom indices, timeouts, etc.). The file is copied into the
654
+ generated image, so it must not contain credentials or other secrets.
654
655
 
655
656
  Only relevant if Python dependencies are installed via pip. If omitted, default pip settings are used.
656
657
  """
@@ -689,6 +690,9 @@ class Config(TypedDict, total=False):
689
690
  - "." or "./src" if you have a local Python package
690
691
  - str (aka "anthropic") for a PyPI package
691
692
  - "git+https://github.com/org/repo.git@main" for a Git-based package
693
+ Git HTTP URLs must not contain userinfo such as a username or token. For private
694
+ dependencies, provide short-lived credentials through the build environment's
695
+ secret-backed Git credential helper.
692
696
  Defaults to an empty list, meaning no additional packages installed beyond your base environment.
693
697
 
694
698
  This field is not supported when `source.kind` is `uv`.
langgraph_cli/uv_lock.py CHANGED
@@ -880,6 +880,7 @@ def python_config_to_docker_uv_lock(
880
880
  _get_node_pm_install_cmd,
881
881
  _get_pip_cleanup_lines,
882
882
  _image_supports_uv,
883
+ _validate_git_http_url_userinfo_files,
883
884
  docker_tag,
884
885
  )
885
886
 
@@ -890,11 +891,20 @@ def python_config_to_docker_uv_lock(
890
891
  )
891
892
 
892
893
  config_root = config_path.parent.resolve()
894
+ source_root = config["source"].get("root", ".")
895
+ project_root = (config_root / source_root).resolve()
896
+ _validate_git_http_url_userinfo_files(
897
+ [project_root / "pyproject.toml", project_root / "uv.lock"]
898
+ )
899
+
893
900
  install_cmd = "uv pip install --system"
894
901
  _, global_reqs_pip_install, pip_config_file_str = _build_python_install_commands(
895
902
  config, install_cmd
896
903
  )
897
904
  plan = _plan_uv_lock_workspace(config_path, config)
905
+ _validate_git_http_url_userinfo_files(
906
+ package.pyproject_path for package in plan.install_order
907
+ )
898
908
 
899
909
  _update_uv_lock_graph_paths(config_path, config, plan)
900
910
  for section, key in [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: langgraph-cli
3
- Version: 0.4.32.dev0
3
+ Version: 0.4.33
4
4
  Summary: CLI for interacting with LangGraph API
5
5
  Project-URL: Source, https://github.com/langchain-ai/langgraph/tree/main/libs/cli
6
6
  Project-URL: Twitter, https://x.com/langchain_oss
@@ -125,6 +125,8 @@ The CLI uses a `langgraph.json` configuration file with these key settings:
125
125
  }
126
126
  ```
127
127
 
128
+ Git dependencies should use credential-free URLs. The CLI conservatively scans direct `langgraph.json` dependencies, common Python package files, uv project and lock files, and common Node.js package and lock files for HTTP Git URLs with userinfo. This check is not exhaustive: generated Docker builds can copy other files, including nested requirement or constraint files, into image layers without scanning them. For private dependencies, provide short-lived credentials through your build environment's secret-backed Git credential helper. Do not store credentials in copied files such as `langgraph.json` or `pip_config_file`.
129
+
128
130
  See the [full documentation](https://reference.langchain.com/python/langgraph-cli) for detailed configuration options.
129
131
 
130
132
  ## Development
@@ -1,26 +1,26 @@
1
- langgraph_cli/__init__.py,sha256=I9TqmokZP63vuEYFZAIL7-QidDgmqJW1iaf5M72vi34,28
1
+ langgraph_cli/__init__.py,sha256=O_0xE0g6EcJfkv7qWx5tmF2cs2K3UCW8uX8xzUqd7Rs,23
2
2
  langgraph_cli/__main__.py,sha256=8hDtWlaFZK24KhfNq_ZKgtXqYHsDQDetukOCMlsbW0Q,59
3
3
  langgraph_cli/_ignore.py,sha256=lh1JyfPtl0CbpCGtQuZ0ba2Cedsbblc2qLp-dmqdaRs,4193
4
4
  langgraph_cli/analytics.py,sha256=z0KGKtSToqR7Q9aFoVOPAoQt6kIQsiPDk1N9i8wkT98,2706
5
5
  langgraph_cli/archive.py,sha256=wmf5yXGU17Z8w5ZfIbRquXCaZ8W9OEH_BVfsJjGnZDI,4808
6
6
  langgraph_cli/cli.py,sha256=Q4kpglojg3rkRVFIuodIUrtxoQyDv6ZKzXAV_k5UONg,34316
7
- langgraph_cli/config.py,sha256=_M2PqcQ2dmt0ud9on7T9Ub8Va-E9DUWhufFMTYOBTSY,66742
7
+ langgraph_cli/config.py,sha256=pK-du8Qb9g0Dn0ojo8Rku_kB10MPtJJ1U87QJTsCr9g,69880
8
8
  langgraph_cli/constants.py,sha256=iSE-4HZJRd4CXzOmPZPKgPLWDDw1v__5s3AnwZtMMIg,362
9
9
  langgraph_cli/dependency_tracking.py,sha256=VaE5taa7qWP4McHhKJATcAXEC1XPPDrcPdj_gg9a8V0,4544
10
- langgraph_cli/deploy.py,sha256=2GKDcmNF2IzPjHcJXYQ0hpc6MU53bcxxGyf-0salleE,92025
10
+ langgraph_cli/deploy.py,sha256=vg2krqtYxWlisG-uib5s033MuWcMYlzLI7fbx7DRY24,96595
11
11
  langgraph_cli/docker.py,sha256=rVeC60lXpXQ9AoGn50LfW6bfS0bFvzWGXo_4SO2HW_8,12888
12
12
  langgraph_cli/exec.py,sha256=vDtFhf2C_5jTTOZbV6cV1z2ioa947uBQvLj80eYXWH0,5343
13
13
  langgraph_cli/host_backend.py,sha256=vyeYZxWG46xwBTXel2a7mCg3EExgzftf-PetO9Jkl-E,12134
14
14
  langgraph_cli/image_reference.py,sha256=xX2VZ6tk9RRk-QjbWnDD38kIt-jTVFAMxB0pkYkxW-g,1107
15
15
  langgraph_cli/progress.py,sha256=YBWJ2TAScNt2Jv8sd3suWu-QkySPvQb4q7HFg9iJ3wU,3412
16
16
  langgraph_cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- langgraph_cli/schemas.py,sha256=w8K3xC78G_3xKrOv38FXqdEFbhKcYkgo3whz1Ignjn0,27283
17
+ langgraph_cli/schemas.py,sha256=sf2Z-X53KpuBSqHW6jUKm94OVIEn_iDcba2vqx2Ndkg,27590
18
18
  langgraph_cli/templates.py,sha256=SPu0R1DIYOiNb8JxhKJX78zpakHiqoW9ddZRqRGRcu4,6978
19
19
  langgraph_cli/util.py,sha256=tDJBts8zF-F15icCsRjX2OfpjKBF-CAADj2Z8qW-BuU,1619
20
- langgraph_cli/uv_lock.py,sha256=gJ-s8iSUhrT73FrGKsthFX87hDfTJGXAZ2Uud3rQmgU,38521
20
+ langgraph_cli/uv_lock.py,sha256=t3CnL2rY5t6ThfGidqdY046O_FkbzHFwsmbvnqIWWN0,38909
21
21
  langgraph_cli/version.py,sha256=7oakgfTwsJJz0D5Sso_XKXkUzfLdN3fyVwgMTncms-A,308
22
- langgraph_cli-0.4.32.dev0.dist-info/METADATA,sha256=so9r_8HKAbYeNzjqPTcO5tm3RxL3SlWabxfIq7386Bk,5160
23
- langgraph_cli-0.4.32.dev0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
24
- langgraph_cli-0.4.32.dev0.dist-info/entry_points.txt,sha256=qNTLVRQfXrOI4SWPyBueUpAu_6-sZFNmj1Xkum0o0yY,52
25
- langgraph_cli-0.4.32.dev0.dist-info/licenses/LICENSE,sha256=2btS8uNUDWD_UNjw9ba6ZJt_00aUjEw9CGyK-xIHY8c,1072
26
- langgraph_cli-0.4.32.dev0.dist-info/RECORD,,
22
+ langgraph_cli-0.4.33.dist-info/METADATA,sha256=q4CkWBIbdayUdLFoAzShA0WkZKXURClTEs3EP1A90Vo,5787
23
+ langgraph_cli-0.4.33.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
24
+ langgraph_cli-0.4.33.dist-info/entry_points.txt,sha256=qNTLVRQfXrOI4SWPyBueUpAu_6-sZFNmj1Xkum0o0yY,52
25
+ langgraph_cli-0.4.33.dist-info/licenses/LICENSE,sha256=2btS8uNUDWD_UNjw9ba6ZJt_00aUjEw9CGyK-xIHY8c,1072
26
+ langgraph_cli-0.4.33.dist-info/RECORD,,