langgraph-cli 0.1.74__tar.gz → 0.1.76__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langgraph-cli
3
- Version: 0.1.74
3
+ Version: 0.1.76
4
4
  Summary: CLI for interacting with LangGraph API
5
5
  Home-page: https://www.github.com/langchain-ai/langgraph
6
6
  License: MIT
@@ -3,7 +3,7 @@ import os
3
3
  import pathlib
4
4
  import textwrap
5
5
  from collections import Counter
6
- from typing import NamedTuple, Optional, TypedDict, Union
6
+ from typing import Any, NamedTuple, Optional, TypedDict, Union
7
7
 
8
8
  import click
9
9
 
@@ -11,13 +11,37 @@ MIN_NODE_VERSION = "20"
11
11
  MIN_PYTHON_VERSION = "3.11"
12
12
 
13
13
 
14
+ class TTLConfig(TypedDict, total=False):
15
+ """Configuration for TTL (time-to-live) behavior in the store."""
16
+
17
+ refresh_on_read: bool
18
+ """Default behavior for refreshing TTLs on read operations (GET and SEARCH).
19
+
20
+ If True, TTLs will be refreshed on read operations (get/search) by default.
21
+ This can be overridden per-operation by explicitly setting refresh_ttl.
22
+ Defaults to True if not configured.
23
+ """
24
+ default_ttl: Optional[float]
25
+ """Optional. Default TTL (time-to-live) in minutes for new items.
26
+
27
+ If provided, all new items will have this TTL unless explicitly overridden.
28
+ If omitted, items will have no TTL by default.
29
+ """
30
+
31
+
14
32
  class IndexConfig(TypedDict, total=False):
15
- """Configuration for indexing documents for semantic search in the store."""
33
+ """Configuration for indexing documents for semantic search in the store.
34
+
35
+ This governs how text is converted into embeddings and stored for vector-based lookups.
36
+ """
16
37
 
17
38
  dims: int
18
- """Number of dimensions in the embedding vectors.
39
+ """Required. Dimensionality of the embedding vectors you will store.
19
40
 
20
- Common embedding models have the following dimensions:
41
+ Must match the output dimension of your selected embedding model or custom embed function.
42
+ If mismatched, you will likely encounter shape/size errors when inserting or querying vectors.
43
+
44
+ Common embedding model output dimensions:
21
45
  - openai:text-embedding-3-large: 3072
22
46
  - openai:text-embedding-3-small: 1536
23
47
  - openai:text-embedding-ada-002: 1536
@@ -28,42 +52,130 @@ class IndexConfig(TypedDict, total=False):
28
52
  """
29
53
 
30
54
  embed: str
31
- """Optional model (string) to generate embeddings from text or path to model or function.
55
+ """Required. Identifier or reference to the embedding model or a custom embedding function.
32
56
 
33
- Examples:
57
+ The format can vary:
58
+ - "<provider>:<model_name>" for recognized providers (e.g., "openai:text-embedding-3-large")
59
+ - "path/to/module.py:function_name" for your own local embedding function
60
+ - "my_custom_embed" if it's a known alias in your system
61
+
62
+ Examples:
34
63
  - "openai:text-embedding-3-large"
35
64
  - "cohere:embed-multilingual-v3.0"
36
- - "src/app.py:embeddings
65
+ - "src/app.py:embeddings"
66
+
67
+ Note: Must return embeddings of dimension `dims`.
37
68
  """
38
69
 
39
70
  fields: Optional[list[str]]
40
- """Fields to extract text from for embedding generation.
71
+ """Optional. List of JSON fields to extract before generating embeddings.
72
+
73
+ Defaults to ["$"], which means the entire JSON object is embedded as one piece of text.
74
+ If you provide multiple fields (e.g. ["title", "content"]), each is extracted and embedded separately,
75
+ often saving token usage if you only care about certain parts of the data.
41
76
 
42
- Defaults to the root ["$"], which embeds the json object as a whole.
77
+ Example:
78
+ fields=["title", "abstract", "author.biography"]
43
79
  """
44
80
 
45
81
 
46
82
  class StoreConfig(TypedDict, total=False):
47
- embed: Optional[IndexConfig]
48
- """Configuration for vector embeddings in store."""
83
+ """Configuration for the built-in long-term memory store.
84
+
85
+ This store can optionally perform semantic search. If you omit `index`,
86
+ the store will just handle traditional (non-embedded) data without vector lookups.
87
+ """
88
+
89
+ index: Optional[IndexConfig]
90
+ """Optional. Defines the vector-based semantic search configuration.
91
+
92
+ If provided, the store will:
93
+ - Generate embeddings according to `index.embed`
94
+ - Enforce the embedding dimension given by `index.dims`
95
+ - Embed only specified JSON fields (if any) from `index.fields`
96
+
97
+ If omitted, no vector index is initialized.
98
+ """
99
+
100
+ ttl: Optional[TTLConfig]
101
+ """Optional. Defines the TTL (time-to-live) behavior configuration.
102
+
103
+ If provided, the store will apply TTL settings according to the configuration.
104
+ If omitted, no TTL behavior is configured.
105
+ """
49
106
 
50
107
 
51
108
  class SecurityConfig(TypedDict, total=False):
52
- securitySchemes: dict
53
- security: list
109
+ """Configuration for OpenAPI security definitions and requirements.
110
+
111
+ Useful for specifying global or path-level authentication and authorization flows
112
+ (e.g., OAuth2, API key headers, etc.).
113
+ """
114
+
115
+ securitySchemes: dict[str, dict[str, Any]]
116
+ """Required. Dict describing each security scheme recognized by your OpenAPI spec.
117
+
118
+ Keys are scheme names (e.g. "OAuth2", "ApiKeyAuth") and values are their definitions.
119
+ Example:
120
+ {
121
+ "OAuth2": {
122
+ "type": "oauth2",
123
+ "flows": {
124
+ "password": {
125
+ "tokenUrl": "/token",
126
+ "scopes": {"read": "Read data", "write": "Write data"}
127
+ }
128
+ }
129
+ }
130
+ }
131
+ """
132
+ security: list[dict[str, list[str]]]
133
+ """Optional. Global security requirements across all endpoints.
134
+
135
+ Each element in the list maps a security scheme (e.g. "OAuth2") to a list of scopes (e.g. ["read", "write"]).
136
+ Example:
137
+ [
138
+ {"OAuth2": ["read", "write"]},
139
+ {"ApiKeyAuth": []}
140
+ ]
141
+ """
54
142
  # path => {method => security}
55
- paths: dict[str, dict[str, list]]
143
+ paths: dict[str, dict[str, list[dict[str, list[str]]]]]
144
+ """Optional. Path-specific security overrides.
145
+
146
+ Keys are path templates (e.g., "/items/{item_id}"), mapping to:
147
+ - Keys that are HTTP methods (e.g., "GET", "POST"),
148
+ - Values are lists of security definitions (just like `security`) for that method.
149
+
150
+ Example:
151
+ {
152
+ "/private_data": {
153
+ "GET": [{"OAuth2": ["read"]}],
154
+ "POST": [{"OAuth2": ["write"]}]
155
+ }
156
+ }
157
+ """
56
158
 
57
159
 
58
160
  class AuthConfig(TypedDict, total=False):
161
+ """Configuration for custom authentication logic and how it integrates into the OpenAPI spec."""
162
+
59
163
  path: str
60
- """Path to the authentication function in a Python file."""
164
+ """Required. Path to an instance of the Auth() class that implements custom authentication.
165
+
166
+ Format: "path/to/file.py:my_auth"
167
+ """
61
168
  disable_studio_auth: bool
62
- """Whether to disable auth when connecting from the LangSmith Studio."""
169
+ """Optional. Whether to disable LangSmith API-key authentication for requests originating the Studio.
170
+
171
+ Defaults to False, meaning that if a particular header is set, the server will verify the `x-api-key` header
172
+ value is a valid API key for the deployment's workspace. If True, all requests will go through your custom
173
+ authentication logic, regardless of origin of the request.
174
+ """
63
175
  openapi: SecurityConfig
64
- """The schema to use for updating the openapi spec.
65
-
66
- Example:
176
+ """Required. Detailed security configuration that merges into your deployment's OpenAPI spec.
177
+
178
+ Example (OAuth2):
67
179
  {
68
180
  "securitySchemes": {
69
181
  "OAuth2": {
@@ -71,88 +183,185 @@ class AuthConfig(TypedDict, total=False):
71
183
  "flows": {
72
184
  "password": {
73
185
  "tokenUrl": "/token",
74
- "scopes": {
75
- "me": "Read information about the current user",
76
- "items": "Access to create and manage items"
77
- }
186
+ "scopes": {"me": "Read user info", "items": "Manage items"}
78
187
  }
79
188
  }
80
189
  }
81
190
  },
82
191
  "security": [
83
- {"OAuth2": ["me"]} # Default security requirement for all endpoints
192
+ {"OAuth2": ["me"]}
84
193
  ]
85
194
  }
86
195
  """
87
196
 
88
197
 
89
198
  class CorsConfig(TypedDict, total=False):
199
+ """Specifies Cross-Origin Resource Sharing (CORS) rules for your server.
200
+
201
+ If omitted, defaults are typically very restrictive (often no cross-origin requests).
202
+ Configure carefully if you want to allow usage from browsers hosted on other domains.
203
+ """
204
+
90
205
  allow_origins: list[str]
206
+ """Optional. List of allowed origins (e.g., "https://example.com").
207
+
208
+ Default is often an empty list (no external origins).
209
+ Use "*" only if you trust all origins, as that bypasses most restrictions.
210
+ """
91
211
  allow_methods: list[str]
212
+ """Optional. HTTP methods permitted for cross-origin requests (e.g. ["GET", "POST"]).
213
+
214
+ Default might be ["GET", "POST", "OPTIONS"] depending on your server framework.
215
+ """
92
216
  allow_headers: list[str]
217
+ """Optional. HTTP headers that can be used in cross-origin requests (e.g. ["Content-Type", "Authorization"])."""
93
218
  allow_credentials: bool
219
+ """Optional. If True, cross-origin requests can include credentials (cookies, auth headers).
220
+
221
+ Default False to avoid accidentally exposing secured endpoints to untrusted sites.
222
+ """
94
223
  allow_origin_regex: str
224
+ """Optional. A regex pattern for matching allowed origins, used if you have dynamic subdomains.
225
+
226
+ Example: "^https://.*\.mycompany\.com$"
227
+ """
95
228
  expose_headers: list[str]
229
+ """Optional. List of headers that browsers are allowed to read from the response in cross-origin contexts."""
96
230
  max_age: int
231
+ """Optional. How many seconds the browser may cache preflight responses.
232
+
233
+ Default might be 600 (10 minutes). Larger values reduce preflight requests but can cause stale configurations.
234
+ """
97
235
 
98
236
 
99
237
  class HttpConfig(TypedDict, total=False):
238
+ """Configuration for the built-in HTTP server that powers your deployment's routes and endpoints."""
239
+
100
240
  app: str
101
- """Import path for a custom Starlette/FastAPI app to mount"""
241
+ """Optional. Import path to a custom Starlette/FastAPI application to mount.
242
+
243
+ Format: "path/to/module.py:app_var"
244
+ If provided, it can override or extend the default routes.
245
+ """
102
246
  disable_assistants: bool
103
- """Disable /assistants routes"""
247
+ """Optional. If True, /assistants routes are removed from the server.
248
+
249
+ Default is False (meaning /assistants is enabled).
250
+ """
104
251
  disable_threads: bool
105
- """Disable /threads routes"""
252
+ """Optional. If True, /threads routes are removed.
253
+
254
+ Default is False.
255
+ """
106
256
  disable_runs: bool
107
- """Disable /runs routes"""
257
+ """Optional. If True, /runs routes are removed.
258
+
259
+ Default is False.
260
+ """
108
261
  disable_store: bool
109
- """Disable /store routes"""
262
+ """Optional. If True, /store routes are removed, disabling direct store interactions via HTTP.
263
+
264
+ Default is False.
265
+ """
110
266
  disable_meta: bool
111
- """Disable /ok, /info, /metrics, and /docs routes"""
267
+ """Optional. If True, all meta endpoints (/ok, /info, /metrics, /docs) are disabled.
268
+
269
+ Default is False.
270
+ """
112
271
  cors: Optional[CorsConfig]
113
- """Cross-Origin Resource Sharing (CORS) configuration"""
272
+ """Optional. Defines CORS restrictions. If omitted, no special rules are set and
273
+ cross-origin behavior depends on default server settings.
274
+ """
114
275
 
115
276
 
116
277
  class Config(TypedDict, total=False):
117
- """Configuration for langgraph-cli."""
278
+ """Top-level config for langgraph-cli or similar deployment tooling."""
118
279
 
119
280
  python_version: str
120
- """Python version to use."""
281
+ """Optional. Python version in 'major.minor' format (e.g. '3.11').
282
+ Must be at least 3.11 or greater for this deployment to function properly.
283
+ """
121
284
 
122
285
  node_version: Optional[str]
123
- """Node.js version to use."""
286
+ """Optional. Node.js version as a major version (e.g. '20'), if your deployment needs Node.
287
+ Must be >= 20 if provided.
288
+ """
124
289
 
125
290
  pip_config_file: Optional[str]
126
- """Path to a pip configuration file."""
291
+ """Optional. Path to a pip config file (e.g., "/etc/pip.conf" or "pip.ini") for controlling
292
+ package installation (custom indices, credentials, etc.).
293
+
294
+ Only relevant if Python dependencies are installed via pip. If omitted, default pip settings are used.
295
+ """
127
296
 
128
297
  dockerfile_lines: list[str]
129
- """Additional lines to add to the Dockerfile."""
298
+ """Optional. Additional Docker instructions that will be appended to your base Dockerfile.
299
+
300
+ Useful for installing OS packages, setting environment variables, etc.
301
+ Example:
302
+ dockerfile_lines=[
303
+ "RUN apt-get update && apt-get install -y libmagic-dev",
304
+ "ENV MY_CUSTOM_VAR=hello_world"
305
+ ]
306
+ """
130
307
 
131
308
  dependencies: list[str]
132
- """Additional Python dependencies to install."""
309
+ """List of Python dependencies to install, either from PyPI or local paths.
310
+
311
+ Examples:
312
+ - "." or "./src" if you have a local Python package
313
+ - str (aka "anthropic") for a PyPI package
314
+ - "git+https://github.com/org/repo.git@main" for a Git-based package
315
+ Defaults to an empty list, meaning no additional packages installed beyond your base environment.
316
+ """
133
317
 
134
318
  graphs: dict[str, str]
135
- """Mapping of graph names to their definitions."""
136
-
137
- env: Union[dict[str, str], str]
138
- """Environment variables to set.
319
+ """Optional. Named definitions of graphs, each pointing to a Python object.
139
320
 
140
- If a dictionary is provided, the keys are environment variable names
141
- and the values are the corresponding environment variable values.
321
+
322
+ Graphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context
323
+ managers that accept a single configuration argument (of type RunnableConfig) and return a pregel object
324
+ (instance of Stategraph, etc.).
325
+
326
+ Keys are graph names, values are "path/to/file.py:object_name".
327
+ Example:
328
+ {
329
+ "mygraph": "graphs/my_graph.py:graph_definition",
330
+ "anothergraph": "graphs/another.py:get_graph"
331
+ }
332
+ """
142
333
 
143
- If a string is provided, it is interpreted as a path to a file containing
144
- environment variables in the format KEY=VALUE, with one environment variable
145
- per line.
334
+ env: Union[dict[str, str], str]
335
+ """Optional. Environment variables to set for your deployment.
336
+
337
+ - If given as a dict, keys are variable names and values are their values.
338
+ - If given as a string, it must be a path to a file containing lines in KEY=VALUE format.
339
+
340
+ Example as a dict:
341
+ env={"API_TOKEN": "abc123", "DEBUG": "true"}
342
+ Example as a file path:
343
+ env=".env"
146
344
  """
147
345
 
148
346
  store: Optional[StoreConfig]
149
- """Configuration for vector embeddings in store."""
347
+ """Optional. Configuration for the built-in long-term memory store, including semantic search indexing.
348
+
349
+ If omitted, no vector index is set up (the object store will still be present, however).
350
+ """
150
351
 
151
352
  auth: Optional[AuthConfig]
152
- """Configuration for authentication."""
353
+ """Optional. Custom authentication config, including the path to your Python auth logic and
354
+ the OpenAPI security definitions it uses.
355
+ """
153
356
 
154
357
  http: Optional[HttpConfig]
155
- """Configuration for HTTP server."""
358
+ """Optional. Configuration for the built-in HTTP server, controlling which custom routes are exposed
359
+ and how cross-origin requests are handled.
360
+ """
361
+
362
+ ui: Optional[dict[str, str]]
363
+ """Optional. Named definitions of UI components emitted by the agent, each pointing to a JS/TS file.
364
+ """
156
365
 
157
366
 
158
367
  def _parse_version(version_str: str) -> tuple[int, int]:
@@ -189,6 +398,7 @@ def validate_config(config: Config) -> Config:
189
398
  "store": config.get("store"),
190
399
  "auth": config.get("auth"),
191
400
  "http": config.get("http"),
401
+ "ui": config.get("ui"),
192
402
  }
193
403
  if config.get("node_version")
194
404
  else {
@@ -201,6 +411,7 @@ def validate_config(config: Config) -> Config:
201
411
  "store": config.get("store"),
202
412
  "auth": config.get("auth"),
203
413
  "http": config.get("http"),
414
+ "ui": config.get("ui"),
204
415
  }
205
416
  )
206
417
 
@@ -687,9 +898,11 @@ def python_config_to_docker(
687
898
  pip_pkgs_str = f"RUN {pip_install} {' '.join(pypi_deps)}" if pypi_deps else ""
688
899
  if local_deps.pip_reqs:
689
900
  pip_reqs_str = os.linesep.join(
690
- f"COPY --from=__outer_{reqpath.name} requirements.txt {destpath}"
691
- if reqpath.parent in local_deps.additional_contexts
692
- else f"ADD {reqpath.relative_to(config_path.parent)} {destpath}"
901
+ (
902
+ f"COPY --from=__outer_{reqpath.name} requirements.txt {destpath}"
903
+ if reqpath.parent in local_deps.additional_contexts
904
+ else f"ADD {reqpath.relative_to(config_path.parent)} {destpath}"
905
+ )
693
906
  for reqpath, destpath in local_deps.pip_reqs
694
907
  )
695
908
  pip_reqs_str += f'{os.linesep}RUN {pip_install} {" ".join("-r " + r for _,r in local_deps.pip_reqs)}'
@@ -724,13 +937,15 @@ RUN set -ex && \\
724
937
  )
725
938
 
726
939
  local_pkgs_str = os.linesep.join(
727
- f"""# -- Adding local package {relpath} --
940
+ (
941
+ f"""# -- Adding local package {relpath} --
728
942
  COPY --from={name} . /deps/{name}
729
943
  # -- End of local package {relpath} --"""
730
- if fullpath in local_deps.additional_contexts
731
- else f"""# -- Adding local package {relpath} --
944
+ if fullpath in local_deps.additional_contexts
945
+ else f"""# -- Adding local package {relpath} --
732
946
  ADD {relpath} /deps/{name}
733
947
  # -- End of local package {relpath} --"""
948
+ )
734
949
  for fullpath, (relpath, name) in local_deps.real_pkgs.items()
735
950
  )
736
951
 
@@ -845,6 +1060,7 @@ ADD . {faux_path}
845
1060
  RUN cd {faux_path} && {install_cmd}
846
1061
  {env_additional_config}
847
1062
  ENV LANGSERVE_GRAPHS='{json.dumps(config["graphs"])}'
1063
+ {f"ENV LANGGRAPH_UI='{json.dumps(config['ui'])}'" if config.get("ui") else ""}
848
1064
 
849
1065
  WORKDIR {faux_path}
850
1066
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langgraph-cli"
3
- version = "0.1.74"
3
+ version = "0.1.76"
4
4
  description = "CLI for interacting with LangGraph API"
5
5
  authors = []
6
6
  license = "MIT"
@@ -25,6 +25,7 @@ pytest-asyncio = "^0.21.1"
25
25
  pytest-mock = "^3.11.1"
26
26
  pytest-watch = "^4.2.0"
27
27
  mypy = "^1.10.0"
28
+ msgspec = "^0.19.0"
28
29
 
29
30
  [tool.poetry.extras]
30
31
  inmem = ["langgraph-api", "python-dotenv"]
File without changes
File without changes