langgraph-cli 0.4.16__tar.gz → 0.4.18__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.
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/PKG-INFO +1 -1
- langgraph_cli-0.4.18/langgraph_cli/__init__.py +1 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/cli.py +37 -17
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/templates.py +19 -55
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/test_deploy_helpers.py +92 -0
- langgraph_cli-0.4.16/langgraph_cli/__init__.py +0 -1
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/.gitignore +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/LICENSE +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/Makefile +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/README.md +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/.env.example +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/.gitignore +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/Makefile +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs/agent.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs/deps/additional_deps/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs/deps/zuper_deps/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs_fail/agent.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs_fail/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs_fail/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs/agent.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs/storm.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/graphs_submod/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/graphs_submod/agent.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/graphs_submod/subprompt.txt +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/hello.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/prompt.txt +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/requirements.txt +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_b/graphs_submod/agent.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_b/graphs_submod/subprompt.txt +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_b/hello.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_b/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_b/prompt.txt +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_b/requirements.txt +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_b/utils/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_b/utils/greeter.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/my_app.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/pipconf.txt +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/poetry.lock +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/generate_schema.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/.dockerignore +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/.editorconfig +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/.env.example +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/.eslintrc.cjs +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/.gitignore +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/LICENSE +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/README.md +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/jest.config.js +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/package.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/src/agent/graph.ts +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/src/agent/state.ts +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/static/studio.png +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/tests/agent.test.ts +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/tests/graph.int.test.ts +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/tsconfig.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-examples/yarn.lock +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/.eslintrc.cjs +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/apps/agent/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/apps/agent/package.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/apps/agent/src/graph.ts +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/apps/agent/src/state.ts +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/apps/agent/tsconfig.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/libs/shared/package.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/libs/shared/src/index.ts +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/libs/shared/tsconfig.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/package.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/tsconfig.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/turbo.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/js-monorepo-example/yarn.lock +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/__main__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/analytics.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/config.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/constants.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/docker.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/exec.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/helpers.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/host_backend.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/progress.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/py.typed +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/schemas.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/util.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/langgraph_cli/version.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/.env.example +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/src/agent/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/src/agent/graph.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/src/agent/state.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/libs/common/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/libs/common/helpers.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/libs/shared/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/libs/shared/src/shared/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/libs/shared/src/shared/utils.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/schemas/schema.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/schemas/schema.v0.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/schemas/version.schema.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/integration_tests/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/integration_tests/test_cli.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/agent.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/cli/__init__.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/cli/langgraph.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/cli/pyproject.toml +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/cli/test_cli.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/cli/test_templates.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/conftest.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/graphs/agent.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/helpers.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/multiplatform/js.mts +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/multiplatform/python.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/pipconfig.txt +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/test_config.json +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/test_config.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/test_docker.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/test_host_backend.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/test_logs_helpers.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/tests/unit_tests/test_util.py +0 -0
- {langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/uv.lock +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.18"
|
|
@@ -764,7 +764,7 @@ def _deploy_base_options(
|
|
|
764
764
|
@cli.group(
|
|
765
765
|
cls=DeployGroup,
|
|
766
766
|
help=(
|
|
767
|
-
"[Beta] Build and deploy a LangGraph image to LangSmith
|
|
767
|
+
"[Beta] Build and deploy a LangGraph image to LangSmith Deployment.\n\n"
|
|
768
768
|
"This command is in beta and under active development. "
|
|
769
769
|
"Expect frequent updates and improvements.\n\n"
|
|
770
770
|
"Run from the root of your LangGraph project (where langgraph.json "
|
|
@@ -1122,7 +1122,7 @@ def _deploy(
|
|
|
1122
1122
|
)
|
|
1123
1123
|
else:
|
|
1124
1124
|
click.secho(
|
|
1125
|
-
" Check status in the LangSmith
|
|
1125
|
+
" Check status in the LangSmith Deployment dashboard.",
|
|
1126
1126
|
fg="yellow",
|
|
1127
1127
|
)
|
|
1128
1128
|
|
|
@@ -1165,22 +1165,42 @@ def _call_host_backend_with_optional_tenant(
|
|
|
1165
1165
|
in-place so all subsequent calls through the same instance are
|
|
1166
1166
|
tenant-aware.
|
|
1167
1167
|
"""
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
click.secho(
|
|
1173
|
-
"Your API key is org-scoped and requires a workspace ID.",
|
|
1174
|
-
fg="yellow",
|
|
1175
|
-
)
|
|
1176
|
-
click.secho(
|
|
1177
|
-
"Find your workspace ID in LangSmith under Settings > Workspaces.",
|
|
1178
|
-
fg="yellow",
|
|
1179
|
-
)
|
|
1180
|
-
tenant_id = click.prompt("Workspace ID")
|
|
1181
|
-
client._client.headers["X-Tenant-ID"] = tenant_id
|
|
1168
|
+
prompted_for_tenant = False
|
|
1169
|
+
|
|
1170
|
+
while True:
|
|
1171
|
+
try:
|
|
1182
1172
|
return operation(client)
|
|
1183
|
-
|
|
1173
|
+
except HostBackendError as err:
|
|
1174
|
+
if (
|
|
1175
|
+
not prompted_for_tenant
|
|
1176
|
+
and err.status_code == 403
|
|
1177
|
+
and "requires workspace specification" in err.message
|
|
1178
|
+
):
|
|
1179
|
+
click.secho(
|
|
1180
|
+
"Your API key is org-scoped and requires a workspace ID.",
|
|
1181
|
+
fg="yellow",
|
|
1182
|
+
)
|
|
1183
|
+
click.secho(
|
|
1184
|
+
"Find your workspace ID in LangSmith under Settings > Workspaces.",
|
|
1185
|
+
fg="yellow",
|
|
1186
|
+
)
|
|
1187
|
+
client._client.headers["X-Tenant-ID"] = click.prompt("Workspace ID")
|
|
1188
|
+
prompted_for_tenant = True
|
|
1189
|
+
continue
|
|
1190
|
+
if err.status_code == 403 and "not enabled" in err.message.lower():
|
|
1191
|
+
from urllib.parse import urlparse
|
|
1192
|
+
|
|
1193
|
+
smith_host = "smith.langchain.com"
|
|
1194
|
+
parsed = urlparse(client._base_url)
|
|
1195
|
+
if (parsed.hostname or "").startswith("eu."):
|
|
1196
|
+
smith_host = "eu.smith.langchain.com"
|
|
1197
|
+
raise HostBackendError(
|
|
1198
|
+
"LangSmith Deployment is not enabled for this organization. "
|
|
1199
|
+
f"Enable it at https://{smith_host}/host/deployments"
|
|
1200
|
+
" (ensure this matches the organization for your API key).",
|
|
1201
|
+
status_code=403,
|
|
1202
|
+
) from None
|
|
1203
|
+
raise
|
|
1184
1204
|
|
|
1185
1205
|
|
|
1186
1206
|
@OPT_HOST_API_KEY
|
|
@@ -8,31 +8,20 @@ from zipfile import ZipFile
|
|
|
8
8
|
import click
|
|
9
9
|
|
|
10
10
|
TEMPLATES: dict[str, dict[str, str]] = {
|
|
11
|
+
"Deep Agent": {
|
|
12
|
+
"description": "An opinionated deployment template for a Deep Agent.",
|
|
13
|
+
"python": "https://github.com/langchain-ai/deep-agent-template/archive/refs/heads/main.zip",
|
|
14
|
+
"js": "https://github.com/langchain-ai/deep-agent-template-js/archive/refs/heads/main.zip",
|
|
15
|
+
},
|
|
16
|
+
"Agent": {
|
|
17
|
+
"description": "A simple agent that can be flexibly extended to many tools.",
|
|
18
|
+
"python": "https://github.com/langchain-ai/simple-agent-template/archive/refs/heads/main.zip",
|
|
19
|
+
},
|
|
11
20
|
"New LangGraph Project": {
|
|
12
21
|
"description": "A simple, minimal chatbot with memory.",
|
|
13
22
|
"python": "https://github.com/langchain-ai/new-langgraph-project/archive/refs/heads/main.zip",
|
|
14
23
|
"js": "https://github.com/langchain-ai/new-langgraphjs-project/archive/refs/heads/main.zip",
|
|
15
24
|
},
|
|
16
|
-
"ReAct Agent": {
|
|
17
|
-
"description": "A simple agent that can be flexibly extended to many tools.",
|
|
18
|
-
"python": "https://github.com/langchain-ai/react-agent/archive/refs/heads/main.zip",
|
|
19
|
-
"js": "https://github.com/langchain-ai/react-agent-js/archive/refs/heads/main.zip",
|
|
20
|
-
},
|
|
21
|
-
"Memory Agent": {
|
|
22
|
-
"description": "A ReAct-style agent with an additional tool to store memories for use across conversational threads.",
|
|
23
|
-
"python": "https://github.com/langchain-ai/memory-agent/archive/refs/heads/main.zip",
|
|
24
|
-
"js": "https://github.com/langchain-ai/memory-agent-js/archive/refs/heads/main.zip",
|
|
25
|
-
},
|
|
26
|
-
"Retrieval Agent": {
|
|
27
|
-
"description": "An agent that includes a retrieval-based question-answering system.",
|
|
28
|
-
"python": "https://github.com/langchain-ai/retrieval-agent-template/archive/refs/heads/main.zip",
|
|
29
|
-
"js": "https://github.com/langchain-ai/retrieval-agent-template-js/archive/refs/heads/main.zip",
|
|
30
|
-
},
|
|
31
|
-
"Data-enrichment Agent": {
|
|
32
|
-
"description": "An agent that performs web searches and organizes its findings into a structured format.",
|
|
33
|
-
"python": "https://github.com/langchain-ai/data-enrichment/archive/refs/heads/main.zip",
|
|
34
|
-
"js": "https://github.com/langchain-ai/data-enrichment-js/archive/refs/heads/main.zip",
|
|
35
|
-
},
|
|
36
25
|
}
|
|
37
26
|
|
|
38
27
|
# Generate TEMPLATE_IDS programmatically
|
|
@@ -78,19 +67,25 @@ def _choose_template() -> str:
|
|
|
78
67
|
click.secho("❌ Invalid choice. Please try again.", fg="red")
|
|
79
68
|
return _choose_template()
|
|
80
69
|
|
|
81
|
-
|
|
70
|
+
template_info = TEMPLATES[selected_template]
|
|
71
|
+
available_langs = [lang for lang in ("python", "js") if lang in template_info]
|
|
72
|
+
|
|
82
73
|
click.secho(
|
|
83
|
-
f"\nYou selected: {selected_template} - {
|
|
74
|
+
f"\nYou selected: {selected_template} - {template_info['description']}",
|
|
84
75
|
fg="green",
|
|
85
76
|
)
|
|
77
|
+
|
|
78
|
+
if len(available_langs) == 1:
|
|
79
|
+
return template_info[available_langs[0]]
|
|
80
|
+
|
|
86
81
|
version_choice: int = click.prompt(
|
|
87
82
|
"Choose language (1 for Python 🐍, 2 for JS/TS 🌐)", type=int
|
|
88
83
|
)
|
|
89
84
|
|
|
90
85
|
if version_choice == 1:
|
|
91
|
-
return
|
|
86
|
+
return template_info["python"]
|
|
92
87
|
elif version_choice == 2:
|
|
93
|
-
return
|
|
88
|
+
return template_info["js"]
|
|
94
89
|
else:
|
|
95
90
|
click.secho("❌ Invalid choice. Please try again.", fg="red")
|
|
96
91
|
return _choose_template()
|
|
@@ -130,37 +125,6 @@ def _download_repo_with_requests(repo_url: str, path: str) -> None:
|
|
|
130
125
|
sys.exit(1)
|
|
131
126
|
|
|
132
127
|
|
|
133
|
-
def _get_template_url(template_name: str) -> str | None:
|
|
134
|
-
"""
|
|
135
|
-
Retrieves the template URL based on the provided template name.
|
|
136
|
-
|
|
137
|
-
Args:
|
|
138
|
-
template_name: The name of the template.
|
|
139
|
-
|
|
140
|
-
Returns:
|
|
141
|
-
Optional[str]: The URL of the template if found, else None.
|
|
142
|
-
"""
|
|
143
|
-
if template_name in TEMPLATES:
|
|
144
|
-
click.secho(f"Template selected: {template_name}", fg="green")
|
|
145
|
-
version_choice: int = click.prompt(
|
|
146
|
-
"Choose version (1 for Python 🐍, 2 for JS/TS 🌐)", type=int
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
if version_choice == 1:
|
|
150
|
-
return TEMPLATES[template_name]["python"]
|
|
151
|
-
elif version_choice == 2:
|
|
152
|
-
return TEMPLATES[template_name]["js"]
|
|
153
|
-
else:
|
|
154
|
-
click.secho("❌ Invalid choice. Please try again.", fg="red")
|
|
155
|
-
return None
|
|
156
|
-
else:
|
|
157
|
-
click.secho(
|
|
158
|
-
f"Template '{template_name}' not found. Please select from the available options.",
|
|
159
|
-
fg="red",
|
|
160
|
-
)
|
|
161
|
-
return None
|
|
162
|
-
|
|
163
|
-
|
|
164
128
|
def create_new(path: str | None, template: str | None) -> None:
|
|
165
129
|
"""Create a new LangGraph project at the specified PATH using the chosen TEMPLATE.
|
|
166
130
|
|
|
@@ -3,14 +3,17 @@ import json
|
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
5
|
import click
|
|
6
|
+
import httpx
|
|
6
7
|
import pytest
|
|
7
8
|
|
|
8
9
|
from langgraph_cli.cli import (
|
|
10
|
+
_call_host_backend_with_optional_tenant,
|
|
9
11
|
_docker_config_for_token,
|
|
10
12
|
_normalize_image_name,
|
|
11
13
|
_normalize_image_tag,
|
|
12
14
|
_parse_env_from_config,
|
|
13
15
|
)
|
|
16
|
+
from langgraph_cli.host_backend import HostBackendClient, HostBackendError
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
class TestDockerConfigForToken:
|
|
@@ -132,3 +135,92 @@ class TestParseEnvFromConfig:
|
|
|
132
135
|
assert result["GOOD"] == "value"
|
|
133
136
|
# EMPTY= gives empty string, not None, so it should be present
|
|
134
137
|
assert result["EMPTY"] == ""
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class TestCallHostBackendWithOptionalTenant:
|
|
141
|
+
def _make_client(self, handler):
|
|
142
|
+
c = HostBackendClient("https://api.example.com", "test-key")
|
|
143
|
+
c._client = httpx.Client(
|
|
144
|
+
base_url="https://api.example.com",
|
|
145
|
+
transport=httpx.MockTransport(handler),
|
|
146
|
+
headers={"X-Api-Key": "test-key", "Accept": "application/json"},
|
|
147
|
+
timeout=30,
|
|
148
|
+
)
|
|
149
|
+
return c
|
|
150
|
+
|
|
151
|
+
def _make_eu_client(self, handler):
|
|
152
|
+
c = HostBackendClient("https://eu.api.host.langchain.com", "test-key")
|
|
153
|
+
c._client = httpx.Client(
|
|
154
|
+
base_url="https://eu.api.host.langchain.com",
|
|
155
|
+
transport=httpx.MockTransport(handler),
|
|
156
|
+
headers={"X-Api-Key": "test-key", "Accept": "application/json"},
|
|
157
|
+
timeout=30,
|
|
158
|
+
)
|
|
159
|
+
return c
|
|
160
|
+
|
|
161
|
+
def test_success_passes_through(self):
|
|
162
|
+
client = self._make_client(lambda req: httpx.Response(200, json={"ok": True}))
|
|
163
|
+
result = _call_host_backend_with_optional_tenant(
|
|
164
|
+
client, lambda c: c.list_deployments()
|
|
165
|
+
)
|
|
166
|
+
assert result == {"ok": True}
|
|
167
|
+
|
|
168
|
+
def test_403_not_enabled_gives_actionable_error(self):
|
|
169
|
+
detail = (
|
|
170
|
+
'{"detail":"LangSmith Deployment is not enabled for this organization"}'
|
|
171
|
+
)
|
|
172
|
+
client = self._make_client(lambda req: httpx.Response(403, text=detail))
|
|
173
|
+
with pytest.raises(HostBackendError, match="not enabled") as exc_info:
|
|
174
|
+
_call_host_backend_with_optional_tenant(
|
|
175
|
+
client, lambda c: c.list_deployments()
|
|
176
|
+
)
|
|
177
|
+
assert exc_info.value.status_code == 403
|
|
178
|
+
assert "smith.langchain.com" in exc_info.value.message
|
|
179
|
+
|
|
180
|
+
def test_403_not_enabled_eu_url(self):
|
|
181
|
+
detail = (
|
|
182
|
+
'{"detail":"LangSmith Deployment is not enabled for this organization"}'
|
|
183
|
+
)
|
|
184
|
+
client = self._make_eu_client(lambda req: httpx.Response(403, text=detail))
|
|
185
|
+
with pytest.raises(HostBackendError, match="not enabled") as exc_info:
|
|
186
|
+
_call_host_backend_with_optional_tenant(
|
|
187
|
+
client, lambda c: c.list_deployments()
|
|
188
|
+
)
|
|
189
|
+
assert "eu.smith.langchain.com" in exc_info.value.message
|
|
190
|
+
|
|
191
|
+
def test_workspace_retry_then_not_enabled_gives_actionable_error(self, monkeypatch):
|
|
192
|
+
requires_workspace = '{"detail":"requires workspace specification"}'
|
|
193
|
+
not_enabled = (
|
|
194
|
+
'{"detail":"LangSmith Deployment is not enabled for this organization"}'
|
|
195
|
+
)
|
|
196
|
+
seen_tenant_ids = []
|
|
197
|
+
|
|
198
|
+
def handler(req):
|
|
199
|
+
seen_tenant_ids.append(req.headers.get("X-Tenant-ID"))
|
|
200
|
+
if len(seen_tenant_ids) == 1:
|
|
201
|
+
return httpx.Response(403, text=requires_workspace)
|
|
202
|
+
if len(seen_tenant_ids) == 2:
|
|
203
|
+
return httpx.Response(403, text=not_enabled)
|
|
204
|
+
raise AssertionError("unexpected extra request")
|
|
205
|
+
|
|
206
|
+
monkeypatch.setattr(click, "prompt", lambda _text: "workspace-123")
|
|
207
|
+
client = self._make_client(handler)
|
|
208
|
+
|
|
209
|
+
with pytest.raises(HostBackendError, match="not enabled") as exc_info:
|
|
210
|
+
_call_host_backend_with_optional_tenant(
|
|
211
|
+
client, lambda c: c.list_deployments()
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
assert exc_info.value.status_code == 403
|
|
215
|
+
assert "smith.langchain.com" in exc_info.value.message
|
|
216
|
+
assert seen_tenant_ids == [None, "workspace-123"]
|
|
217
|
+
assert client._client.headers["X-Tenant-ID"] == "workspace-123"
|
|
218
|
+
|
|
219
|
+
def test_other_403_re_raises_original(self):
|
|
220
|
+
client = self._make_client(
|
|
221
|
+
lambda req: httpx.Response(403, text='{"detail":"some other error"}')
|
|
222
|
+
)
|
|
223
|
+
with pytest.raises(HostBackendError, match="some other error"):
|
|
224
|
+
_call_host_backend_with_optional_tenant(
|
|
225
|
+
client, lambda c: c.list_deployments()
|
|
226
|
+
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.4.16"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs_fail/langgraph.json
RENAMED
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graph_prerelease_reqs_fail/pyproject.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/graphs_submod/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_a/graphs_submod/subprompt.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/examples/graphs_reqs_b/graphs_submod/subprompt.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/.env.example
RENAMED
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/langgraph.json
RENAMED
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/pyproject.toml
RENAMED
|
File without changes
|
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/src/agent/graph.py
RENAMED
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/apps/agent/src/agent/state.py
RENAMED
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/libs/common/__init__.py
RENAMED
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/libs/common/helpers.py
RENAMED
|
File without changes
|
{langgraph_cli-0.4.16 → langgraph_cli-0.4.18}/python-monorepo-example/libs/shared/pyproject.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|