graph-agents-cli 0.3.1__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.
- graph_agents_cli/__init__.py +26 -0
- graph_agents_cli/_api_policy.py +2145 -0
- graph_agents_cli/_approvals.py +400 -0
- graph_agents_cli/_build.py +186 -0
- graph_agents_cli/_build_info.json +7 -0
- graph_agents_cli/_chat_client.py +462 -0
- graph_agents_cli/_click.py +157 -0
- graph_agents_cli/_defaults.py +139 -0
- graph_agents_cli/_experiments.py +64 -0
- graph_agents_cli/_http.py +192 -0
- graph_agents_cli/_output.py +83 -0
- graph_agents_cli/_project.py +462 -0
- graph_agents_cli/_remote.py +220 -0
- graph_agents_cli/_response_schema.py +264 -0
- graph_agents_cli/_runner.py +319 -0
- graph_agents_cli/_skills_check.py +274 -0
- graph_agents_cli/_tools.py +189 -0
- graph_agents_cli/_trust.py +66 -0
- graph_agents_cli/api/__init__.py +15 -0
- graph_agents_cli/api/_changes.py +506 -0
- graph_agents_cli/api/_files.py +658 -0
- graph_agents_cli/api/cmd_api.py +2480 -0
- graph_agents_cli/deploy/__init__.py +15 -0
- graph_agents_cli/deploy/_config.py +171 -0
- graph_agents_cli/deploy/_image.py +128 -0
- graph_agents_cli/deploy/_kube.py +286 -0
- graph_agents_cli/deploy/_modes.py +234 -0
- graph_agents_cli/deploy/_preflight.py +370 -0
- graph_agents_cli/deploy/_values.py +168 -0
- graph_agents_cli/deploy/cmd_deploy.py +1866 -0
- graph_agents_cli/deploy/gitops.py +562 -0
- graph_agents_cli/deploy/local_load.py +273 -0
- graph_agents_cli/dev/__init__.py +13 -0
- graph_agents_cli/dev/cmd_build.py +131 -0
- graph_agents_cli/dev/cmd_install.py +78 -0
- graph_agents_cli/dev/cmd_lint.py +119 -0
- graph_agents_cli/dev/cmd_playground.py +297 -0
- graph_agents_cli/dev/policy_check.py +1287 -0
- graph_agents_cli/eval/__init__.py +22 -0
- graph_agents_cli/eval/_client.py +670 -0
- graph_agents_cli/eval/_common.py +177 -0
- graph_agents_cli/eval/_judge.py +168 -0
- graph_agents_cli/eval/_judge_runner.py +238 -0
- graph_agents_cli/eval/_paths.py +212 -0
- graph_agents_cli/eval/checks.py +581 -0
- graph_agents_cli/eval/cmd_analyze.py +278 -0
- graph_agents_cli/eval/cmd_compare.py +284 -0
- graph_agents_cli/eval/cmd_eval_group.py +80 -0
- graph_agents_cli/eval/cmd_generate.py +558 -0
- graph_agents_cli/eval/cmd_grade.py +466 -0
- graph_agents_cli/eval/cmd_metric.py +156 -0
- graph_agents_cli/eval/cmd_run.py +370 -0
- graph_agents_cli/eval/cmd_submit.py +400 -0
- graph_agents_cli/eval/config.py +435 -0
- graph_agents_cli/eval/dataset.py +350 -0
- graph_agents_cli/eval/gate.py +420 -0
- graph_agents_cli/eval/transcript.py +192 -0
- graph_agents_cli/extension/__init__.py +13 -0
- graph_agents_cli/extension/_compat.py +86 -0
- graph_agents_cli/extension/_loader.py +293 -0
- graph_agents_cli/extension/_manifest.py +135 -0
- graph_agents_cli/extension/_overrides.py +195 -0
- graph_agents_cli/extension/_paths.py +91 -0
- graph_agents_cli/extension/_refs.py +193 -0
- graph_agents_cli/extension/_resolver.py +453 -0
- graph_agents_cli/extension/_schema.py +106 -0
- graph_agents_cli/extension/_spec.py +253 -0
- graph_agents_cli/extension/_sync.py +102 -0
- graph_agents_cli/extension/_trust.py +58 -0
- graph_agents_cli/extension/cmd_extension_add.py +259 -0
- graph_agents_cli/extension/cmd_extension_group.py +57 -0
- graph_agents_cli/extension/cmd_extension_list.py +56 -0
- graph_agents_cli/extension/cmd_extension_remove.py +61 -0
- graph_agents_cli/extension/cmd_extension_update.py +195 -0
- graph_agents_cli/info/__init__.py +13 -0
- graph_agents_cli/info/cmd_info.py +222 -0
- graph_agents_cli/infra/__init__.py +15 -0
- graph_agents_cli/infra/checks.py +1169 -0
- graph_agents_cli/infra/cmd_infra.py +103 -0
- graph_agents_cli/main.py +591 -0
- graph_agents_cli/peer/__init__.py +15 -0
- graph_agents_cli/peer/_generate.py +254 -0
- graph_agents_cli/peer/cmd_peer.py +1151 -0
- graph_agents_cli/run/__init__.py +13 -0
- graph_agents_cli/run/_local_server.py +1157 -0
- graph_agents_cli/run/_signals.py +141 -0
- graph_agents_cli/run/cmd_approvals.py +530 -0
- graph_agents_cli/run/cmd_run.py +1421 -0
- graph_agents_cli/scaffold/__init__.py +19 -0
- graph_agents_cli/scaffold/agents/README.md +24 -0
- graph_agents_cli/scaffold/agents/empty_py/.template/templateconfig.yaml +22 -0
- graph_agents_cli/scaffold/agents/langgraph/.env.example +292 -0
- graph_agents_cli/scaffold/agents/langgraph/.template/templateconfig.yaml +28 -0
- graph_agents_cli/scaffold/agents/langgraph/Dockerfile +59 -0
- graph_agents_cli/scaffold/agents/langgraph/Dockerfile.langgraph-server +59 -0
- graph_agents_cli/scaffold/agents/langgraph/README.md +571 -0
- graph_agents_cli/scaffold/agents/langgraph/api-policy.yaml +60 -0
- graph_agents_cli/scaffold/agents/langgraph/app/__init__.py +20 -0
- graph_agents_cli/scaffold/agents/langgraph/app/agent.py +174 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/__init__.py +15 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a.py +2162 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a_client.py +1167 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/api_client.py +4220 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/approvals.py +1349 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/auth.py +1986 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/chat.py +2962 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/checkpointer.py +432 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/content.py +569 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/db.py +580 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/limits.py +203 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/metrics.py +231 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/middleware.py +361 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/model.py +611 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/playground.py +230 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/run_locks.py +459 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/structured.py +755 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/telemetry.py +681 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/threads.py +493 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/token_exchange.py +959 -0
- graph_agents_cli/scaffold/agents/langgraph/app/fast_api_app.py +770 -0
- graph_agents_cli/scaffold/agents/langgraph/app/policies/__init__.py +55 -0
- graph_agents_cli/scaffold/agents/langgraph/app/policies/custom.py +97 -0
- graph_agents_cli/scaffold/agents/langgraph/app/tools/__init__.py +46 -0
- graph_agents_cli/scaffold/agents/langgraph/app/tools/example_api.py +92 -0
- graph_agents_cli/scaffold/agents/langgraph/app/tools/weather.py +33 -0
- graph_agents_cli/scaffold/agents/langgraph/langgraph.json +14 -0
- graph_agents_cli/scaffold/agents/langgraph/pyproject.toml +78 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/conftest.py +376 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/eval/datasets/basic-dataset.json +53 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/eval/eval_config.yaml +32 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/approval_graph.py +137 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_issuer.py +216 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_openai.py +357 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_outcomes.py +569 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_relay.py +479 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_api_surface.py +812 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals.py +1367 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals_server.py +794 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor.py +497 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor_server.py +247 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_history_repair.py +278 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_model_apis.py +242 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_postgres.py +637 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_resilience_postgres.py +770 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_runtime_guardrails.py +854 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_e2e.py +340 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_runtime.py +989 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_answers.py +584 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_server.py +222 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_token_exchange_issuer.py +650 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/.results/.placeholder +0 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/README.md +22 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/conftest.py +21 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/load_test.py +81 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_client.py +824 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_scoping.py +724 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client.py +1214 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client_hardening.py +716 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_policy_rpc.py +767 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_approval_ledger.py +1536 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_fake_model.py +115 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_jwt_policy.py +991 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_limits.py +310 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging.py +148 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging_hardening.py +271 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_policy.py +378 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_resilience.py +610 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_server_auth.py +702 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_structured.py +673 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_telemetry.py +404 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_thread_listing.py +255 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_threads.py +268 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_token_exchange.py +1320 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_untrusted_content.py +393 -0
- graph_agents_cli/scaffold/agents/langgraph/uv-fastapi.lock +2084 -0
- graph_agents_cli/scaffold/agents/langgraph/uv-langgraph-server.lock +2106 -0
- graph_agents_cli/scaffold/agents/langgraph/{{cookiecutter.agent_guidance_filename}} +129 -0
- graph_agents_cli/scaffold/base_templates/_shared/graph-agents-cli-manifest.yaml +36 -0
- graph_agents_cli/scaffold/base_templates/python/.dockerignore +32 -0
- graph_agents_cli/scaffold/base_templates/python/.github/CODEOWNERS +30 -0
- graph_agents_cli/scaffold/base_templates/python/.github/agent.env +7 -0
- graph_agents_cli/scaffold/base_templates/python/.github/workflows/pr_checks.yaml +214 -0
- graph_agents_cli/scaffold/base_templates/python/.gitignore +209 -0
- graph_agents_cli/scaffold/base_templates/python/tests/unit/test_dummy.py +23 -0
- graph_agents_cli/scaffold/base_templates/python/{{cookiecutter.agent_guidance_filename}} +35 -0
- graph_agents_cli/scaffold/cmd_scaffold_group.py +49 -0
- graph_agents_cli/scaffold/commands/__init__.py +13 -0
- graph_agents_cli/scaffold/commands/create.py +1424 -0
- graph_agents_cli/scaffold/commands/enhance.py +1652 -0
- graph_agents_cli/scaffold/commands/upgrade.py +570 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/agent.env +12 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/promote-to-prod.yaml +371 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/staging.yaml +450 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-dev.yaml +43 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-prod.yaml +41 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-staging.yaml +43 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/.helmignore +14 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/Chart.yaml +21 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/examples/networkpolicy.yaml +103 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/NOTES.txt +48 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/_helpers.tpl +189 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/certificate.yaml +15 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/configmap.yaml +10 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/deployment.yaml +199 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/hpa.yaml +22 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/httproute.yaml +30 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/ingress.yaml +39 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/networkpolicy.yaml +48 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/pdb.yaml +13 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/postgresql-secret.yaml +37 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/service.yaml +15 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/serviceaccount.yaml +13 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/servicemonitor.yaml +42 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-dev.yaml +22 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-prod.yaml +45 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-staging.yaml +29 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values.yaml +396 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/tests/integration/test_chart.py +269 -0
- graph_agents_cli/scaffold/deployment_targets/none/README.md +5 -0
- graph_agents_cli/scaffold/deployment_targets/none/python/README.md +6 -0
- graph_agents_cli/scaffold/utils/__init__.py +13 -0
- graph_agents_cli/scaffold/utils/backup.py +212 -0
- graph_agents_cli/scaffold/utils/build_record.py +257 -0
- graph_agents_cli/scaffold/utils/cli_options.py +184 -0
- graph_agents_cli/scaffold/utils/fs.py +83 -0
- graph_agents_cli/scaffold/utils/generate_locks.py +214 -0
- graph_agents_cli/scaffold/utils/generation_metadata.py +88 -0
- graph_agents_cli/scaffold/utils/keyedit.py +768 -0
- graph_agents_cli/scaffold/utils/keymerge.py +537 -0
- graph_agents_cli/scaffold/utils/language.py +138 -0
- graph_agents_cli/scaffold/utils/lock_utils.py +94 -0
- graph_agents_cli/scaffold/utils/logging.py +77 -0
- graph_agents_cli/scaffold/utils/manifest.py +292 -0
- graph_agents_cli/scaffold/utils/merge.py +970 -0
- graph_agents_cli/scaffold/utils/merge3.py +216 -0
- graph_agents_cli/scaffold/utils/openapi_seed.py +199 -0
- graph_agents_cli/scaffold/utils/remote_template.py +376 -0
- graph_agents_cli/scaffold/utils/template.py +1352 -0
- graph_agents_cli/scaffold/utils/upgrade.py +894 -0
- graph_agents_cli/scaffold/utils/version.py +438 -0
- graph_agents_cli/secrets/__init__.py +15 -0
- graph_agents_cli/secrets/_apply.py +954 -0
- graph_agents_cli/secrets/_required.py +188 -0
- graph_agents_cli/secrets/cmd_secrets.py +211 -0
- graph_agents_cli/setup/__init__.py +13 -0
- graph_agents_cli/setup/_antigravity.py +221 -0
- graph_agents_cli/setup/cmd_auth.py +1030 -0
- graph_agents_cli/setup/cmd_dev_token.py +513 -0
- graph_agents_cli/setup/cmd_setup.py +428 -0
- graph_agents_cli/setup/cmd_update.py +140 -0
- graph_agents_cli/skills/__init__.py +13 -0
- graph_agents_cli/skills/_bundle.py +65 -0
- graph_agents_cli/skills/data/README.md +19 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/SKILL.md +357 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/github-settings.md +113 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/gitops.md +137 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/kubernetes.md +315 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/secrets.md +160 -0
- graph_agents_cli/skills/data/graph-agents-cli-eval/SKILL.md +303 -0
- graph_agents_cli/skills/data/graph-agents-cli-eval/references/dataset_schema.md +282 -0
- graph_agents_cli/skills/data/graph-agents-cli-eval/references/metrics-guide.md +143 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/SKILL.md +659 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langchain-models.md +124 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langgraph.md +235 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/template-contract.md +477 -0
- graph_agents_cli/skills/data/graph-agents-cli-observability/SKILL.md +231 -0
- graph_agents_cli/skills/data/graph-agents-cli-observability/references/langsmith.md +46 -0
- graph_agents_cli/skills/data/graph-agents-cli-observability/references/otel.md +59 -0
- graph_agents_cli/skills/data/graph-agents-cli-scaffold/SKILL.md +414 -0
- graph_agents_cli/skills/data/graph-agents-cli-scaffold/references/flags.md +134 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/SKILL.md +478 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/brainstorming.md +118 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/commands.md +419 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/extension.md +156 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/internals.md +67 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/spec-template.md +56 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/terminology.md +119 -0
- graph_agents_cli/system/__init__.py +15 -0
- graph_agents_cli/system/_apply.py +519 -0
- graph_agents_cli/system/_checks.py +1023 -0
- graph_agents_cli/system/_deploy.py +215 -0
- graph_agents_cli/system/_model.py +363 -0
- graph_agents_cli/system/_system.py +664 -0
- graph_agents_cli/system/_views.py +208 -0
- graph_agents_cli/system/cmd_system.py +423 -0
- graph_agents_cli-0.3.1.dist-info/METADATA +162 -0
- graph_agents_cli-0.3.1.dist-info/RECORD +291 -0
- graph_agents_cli-0.3.1.dist-info/WHEEL +4 -0
- graph_agents_cli-0.3.1.dist-info/entry_points.txt +2 -0
- graph_agents_cli-0.3.1.dist-info/licenses/LICENSE +201 -0
- graph_agents_cli-0.3.1.dist-info/licenses/NOTICE +19 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# Copyright 2026 Google LLC
|
|
2
|
+
# Modifications Copyright 2026 graph-agents-cli contributors
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
"""graph-agents-cli playground command: run the application with reload.
|
|
17
|
+
|
|
18
|
+
The playground exercises the selected application, not a substitute.
|
|
19
|
+
``fastapi`` -> ``uvicorn <agent_dir>.fast_api_app:app --reload`` with
|
|
20
|
+
``APP_ENV=dev`` so the app serves ``/playground``; ``langgraph-server`` ->
|
|
21
|
+
``langgraph dev --no-browser`` (the server *is* the application and mounts
|
|
22
|
+
``/chat`` and ``/playground``). ``--graph`` runs ``langgraph dev`` for
|
|
23
|
+
LangGraph Studio under either runtime and bypasses the policy adapter.
|
|
24
|
+
|
|
25
|
+
The port is checked before anything starts: a port already answering on
|
|
26
|
+
127.0.0.1, or bound on all interfaces by another process (which a loopback
|
|
27
|
+
server would silently shadow on macOS), is refused with exit 3 and a hint. The
|
|
28
|
+
server runs as a child process: Ctrl-C, SIGTERM or SIGHUP stops it and every
|
|
29
|
+
process it started (``uv`` -> reloader -> worker), never leaving one listening.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
import os
|
|
35
|
+
import shlex
|
|
36
|
+
import signal
|
|
37
|
+
import subprocess
|
|
38
|
+
import threading
|
|
39
|
+
import time
|
|
40
|
+
import webbrowser
|
|
41
|
+
from pathlib import Path
|
|
42
|
+
from typing import NamedTuple
|
|
43
|
+
|
|
44
|
+
import click
|
|
45
|
+
import psutil
|
|
46
|
+
from rich.panel import Panel
|
|
47
|
+
|
|
48
|
+
from graph_agents_cli import _runner
|
|
49
|
+
from graph_agents_cli._output import Console
|
|
50
|
+
from graph_agents_cli._project import (
|
|
51
|
+
chdir_project_root,
|
|
52
|
+
read_project_config,
|
|
53
|
+
require_agent_directory,
|
|
54
|
+
)
|
|
55
|
+
from graph_agents_cli.run._local_server import PortUnavailableError, dotenv_settings, port_problem
|
|
56
|
+
from graph_agents_cli.run._signals import shielded, terminate_like_interrupt
|
|
57
|
+
|
|
58
|
+
_console = Console()
|
|
59
|
+
|
|
60
|
+
DEFAULT_PORT = 8000
|
|
61
|
+
HOST = "127.0.0.1"
|
|
62
|
+
RUNTIME_FASTAPI = "fastapi"
|
|
63
|
+
RUNTIME_LANGGRAPH_SERVER = "langgraph-server"
|
|
64
|
+
_OPEN_TIMEOUT = 60.0
|
|
65
|
+
# Seconds the server gets to stop on SIGTERM before it (and its children) are killed.
|
|
66
|
+
_STOP_GRACE = 5.0
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class PlaygroundPlan(NamedTuple):
|
|
70
|
+
"""The command to run, the env it needs, and the page to open."""
|
|
71
|
+
|
|
72
|
+
args: list[str]
|
|
73
|
+
env: dict[str, str]
|
|
74
|
+
url: str
|
|
75
|
+
# URL polled before the browser opens; None when the tool opens it itself.
|
|
76
|
+
ready_url: str | None
|
|
77
|
+
label: str
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def build_plan(
|
|
81
|
+
*,
|
|
82
|
+
agent_dir: str,
|
|
83
|
+
runtime: str,
|
|
84
|
+
port: int,
|
|
85
|
+
graph: bool,
|
|
86
|
+
open_browser: bool,
|
|
87
|
+
) -> PlaygroundPlan:
|
|
88
|
+
"""Decide what to run for the manifest ``runtime`` and the flags."""
|
|
89
|
+
base = f"http://{HOST}:{port}"
|
|
90
|
+
if graph:
|
|
91
|
+
args = ["uv", "run", "langgraph", "dev", "--port", str(port)]
|
|
92
|
+
if not open_browser:
|
|
93
|
+
args.append("--no-browser")
|
|
94
|
+
return PlaygroundPlan(
|
|
95
|
+
args=args,
|
|
96
|
+
env={"APP_ENV": "dev"},
|
|
97
|
+
url=f"https://smith.langchain.com/studio/?baseUrl={base}",
|
|
98
|
+
ready_url=None, # langgraph dev opens Studio itself.
|
|
99
|
+
label="LangGraph Studio (graph debugging, bypasses the auth policy)",
|
|
100
|
+
)
|
|
101
|
+
if runtime == RUNTIME_FASTAPI:
|
|
102
|
+
args = [
|
|
103
|
+
"uv",
|
|
104
|
+
"run",
|
|
105
|
+
"uvicorn",
|
|
106
|
+
f"{agent_dir}.fast_api_app:app",
|
|
107
|
+
"--reload",
|
|
108
|
+
"--host",
|
|
109
|
+
HOST,
|
|
110
|
+
"--port",
|
|
111
|
+
str(port),
|
|
112
|
+
]
|
|
113
|
+
label = "FastAPI application with reload"
|
|
114
|
+
elif runtime == RUNTIME_LANGGRAPH_SERVER:
|
|
115
|
+
args = ["uv", "run", "langgraph", "dev", "--no-browser", "--port", str(port)]
|
|
116
|
+
label = "LangGraph Server (langgraph dev) with the mounted app"
|
|
117
|
+
else:
|
|
118
|
+
raise click.ClickException(
|
|
119
|
+
f"Unsupported runtime {runtime!r} in graph-agents-cli-manifest.yaml.\n"
|
|
120
|
+
f" Expected one of: {RUNTIME_FASTAPI}, {RUNTIME_LANGGRAPH_SERVER}"
|
|
121
|
+
)
|
|
122
|
+
return PlaygroundPlan(
|
|
123
|
+
args=args,
|
|
124
|
+
env={"APP_ENV": "dev"},
|
|
125
|
+
url=f"{base}/playground",
|
|
126
|
+
ready_url=f"{base}/health",
|
|
127
|
+
label=label,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _wait_and_open(url: str, ready_url: str, timeout: float = _OPEN_TIMEOUT) -> bool:
|
|
132
|
+
"""Poll ``ready_url`` until it answers, then open ``url`` in the browser."""
|
|
133
|
+
import httpx
|
|
134
|
+
|
|
135
|
+
from graph_agents_cli import _http
|
|
136
|
+
|
|
137
|
+
deadline = time.monotonic() + timeout
|
|
138
|
+
while time.monotonic() < deadline:
|
|
139
|
+
try:
|
|
140
|
+
# The local server: never through a proxy from the environment.
|
|
141
|
+
resp = _http.get(ready_url, timeout=1.0)
|
|
142
|
+
if resp.status_code < 500:
|
|
143
|
+
webbrowser.open(url)
|
|
144
|
+
return True
|
|
145
|
+
except httpx.HTTPError:
|
|
146
|
+
pass
|
|
147
|
+
time.sleep(0.5)
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _open_when_ready(plan: PlaygroundPlan) -> threading.Thread | None:
|
|
152
|
+
if plan.ready_url is None:
|
|
153
|
+
return None
|
|
154
|
+
thread = threading.Thread(
|
|
155
|
+
target=_wait_and_open, args=(plan.url, plan.ready_url), daemon=True, name="open-playground"
|
|
156
|
+
)
|
|
157
|
+
thread.start()
|
|
158
|
+
return thread
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@click.command("playground")
|
|
162
|
+
@click.option(
|
|
163
|
+
"--port",
|
|
164
|
+
default=DEFAULT_PORT,
|
|
165
|
+
show_default=True,
|
|
166
|
+
type=click.IntRange(1, 65535),
|
|
167
|
+
help="Port the application listens on (refused when already in use).",
|
|
168
|
+
)
|
|
169
|
+
@click.option(
|
|
170
|
+
"--graph",
|
|
171
|
+
is_flag=True,
|
|
172
|
+
default=False,
|
|
173
|
+
help="Run `langgraph dev` for LangGraph Studio graph debugging (bypasses the auth policy).",
|
|
174
|
+
)
|
|
175
|
+
@click.option(
|
|
176
|
+
"--no-open",
|
|
177
|
+
"no_open",
|
|
178
|
+
is_flag=True,
|
|
179
|
+
default=False,
|
|
180
|
+
help="Do not open the browser.",
|
|
181
|
+
)
|
|
182
|
+
def cmd_playground(port: int, graph: bool, no_open: bool) -> None:
|
|
183
|
+
"""Start the application locally with reload and the dev chat page.
|
|
184
|
+
|
|
185
|
+
\b
|
|
186
|
+
fastapi uv run uvicorn <agent_dir>.fast_api_app:app --reload (APP_ENV=dev)
|
|
187
|
+
langgraph-server uv run langgraph dev --no-browser
|
|
188
|
+
--graph uv run langgraph dev (LangGraph Studio) under either runtime
|
|
189
|
+
|
|
190
|
+
The chat page at /playground talks to the same /chat endpoint and auth
|
|
191
|
+
policy that `run` and `eval generate` use.
|
|
192
|
+
"""
|
|
193
|
+
chdir_project_root()
|
|
194
|
+
cfg = read_project_config()
|
|
195
|
+
require_agent_directory(cfg)
|
|
196
|
+
runtime = getattr(cfg, "runtime", RUNTIME_FASTAPI) or RUNTIME_FASTAPI
|
|
197
|
+
|
|
198
|
+
plan = build_plan(
|
|
199
|
+
agent_dir=cfg.agent_directory,
|
|
200
|
+
runtime=runtime,
|
|
201
|
+
port=port,
|
|
202
|
+
graph=graph,
|
|
203
|
+
open_browser=not no_open,
|
|
204
|
+
)
|
|
205
|
+
problem = port_problem(port, HOST)
|
|
206
|
+
if problem:
|
|
207
|
+
raise PortUnavailableError(
|
|
208
|
+
f"Cannot start the playground on port {port}: {problem}.\n"
|
|
209
|
+
" Pick a free one with --port (for example --port "
|
|
210
|
+
f"{_suggest_port(port)})."
|
|
211
|
+
)
|
|
212
|
+
_print_banner(plan)
|
|
213
|
+
if not no_open:
|
|
214
|
+
_open_when_ready(plan)
|
|
215
|
+
code = _run_foreground(plan.args, plan.env)
|
|
216
|
+
if code != 0:
|
|
217
|
+
raise click.ClickException(f"Failed to start playground (exit code {code})")
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def _suggest_port(port: int, attempts: int = 20) -> int:
|
|
221
|
+
"""A nearby free port for the hint (the next ones up), or ``port + 1``."""
|
|
222
|
+
for candidate in range(port + 1, min(port + 1 + attempts, 65536)):
|
|
223
|
+
if port_problem(candidate, HOST) is None:
|
|
224
|
+
return candidate
|
|
225
|
+
return port + 1
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _run_foreground(args: list[str], env: dict[str, str]) -> int:
|
|
229
|
+
"""Run the server in the foreground and return its exit code.
|
|
230
|
+
|
|
231
|
+
On Ctrl-C, SIGTERM or SIGHUP the whole process tree is stopped: ``uv``
|
|
232
|
+
gets SIGTERM (it forwards it), then anything still running after
|
|
233
|
+
``_STOP_GRACE`` seconds (a reloader's worker, say) is killed.
|
|
234
|
+
"""
|
|
235
|
+
# .env reaches the server from its start, below the environment (as
|
|
236
|
+
# load_dotenv does); the playground's own settings (APP_ENV=dev) win.
|
|
237
|
+
dotenv = dotenv_settings(Path.cwd() / ".env")
|
|
238
|
+
proc = _runner.popen_resolved(args, env={**dotenv, **os.environ, **env})
|
|
239
|
+
try:
|
|
240
|
+
with terminate_like_interrupt():
|
|
241
|
+
return proc.wait()
|
|
242
|
+
except BaseException:
|
|
243
|
+
# A second Ctrl-C or SIGTERM must not cut the stop short (it would leave
|
|
244
|
+
# the reloader's worker listening): it is handled once the tree is gone.
|
|
245
|
+
with shielded():
|
|
246
|
+
_stop_tree(proc)
|
|
247
|
+
raise
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def _stop_tree(proc: subprocess.Popen) -> None:
|
|
251
|
+
try:
|
|
252
|
+
children = psutil.Process(proc.pid).children(recursive=True)
|
|
253
|
+
except psutil.NoSuchProcess:
|
|
254
|
+
children = []
|
|
255
|
+
if proc.poll() is None:
|
|
256
|
+
try:
|
|
257
|
+
proc.send_signal(signal.SIGTERM)
|
|
258
|
+
except OSError:
|
|
259
|
+
pass
|
|
260
|
+
# Every descendant too: a child whose parent died first is not told by anyone.
|
|
261
|
+
for child in children:
|
|
262
|
+
try:
|
|
263
|
+
child.terminate()
|
|
264
|
+
except psutil.NoSuchProcess:
|
|
265
|
+
pass
|
|
266
|
+
_gone, alive = psutil.wait_procs(
|
|
267
|
+
[p for p in (_as_psutil(proc.pid), *children) if p is not None], timeout=_STOP_GRACE
|
|
268
|
+
)
|
|
269
|
+
for leftover in alive:
|
|
270
|
+
try:
|
|
271
|
+
leftover.kill()
|
|
272
|
+
except psutil.NoSuchProcess:
|
|
273
|
+
pass
|
|
274
|
+
try:
|
|
275
|
+
proc.wait(timeout=1)
|
|
276
|
+
except (subprocess.TimeoutExpired, OSError):
|
|
277
|
+
pass
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def _as_psutil(pid: int) -> psutil.Process | None:
|
|
281
|
+
try:
|
|
282
|
+
return psutil.Process(pid)
|
|
283
|
+
except psutil.NoSuchProcess:
|
|
284
|
+
return None
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def _print_banner(plan: PlaygroundPlan) -> None:
|
|
288
|
+
"""Print a styled banner with a clickable URL pointing at the page."""
|
|
289
|
+
cmd_str = shlex.join(plan.args)
|
|
290
|
+
env_str = " ".join(f"{k}={v}" for k, v in plan.env.items())
|
|
291
|
+
body = (
|
|
292
|
+
f"[bold cyan]Starting {plan.label}...[/]\n"
|
|
293
|
+
"\n"
|
|
294
|
+
f"[bold]Running command:[/] {env_str} {cmd_str}\n"
|
|
295
|
+
f"[bold]Will be available at:[/] [green underline]{plan.url}[/]"
|
|
296
|
+
)
|
|
297
|
+
_console.print(Panel(body, border_style="cyan"))
|