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,376 @@
|
|
|
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
|
+
"""Remote template specs (``org/repo/path@ref``, browser URLs) and fetching."""
|
|
17
|
+
|
|
18
|
+
import logging
|
|
19
|
+
import os
|
|
20
|
+
import pathlib
|
|
21
|
+
import re
|
|
22
|
+
import shlex
|
|
23
|
+
import shutil
|
|
24
|
+
import subprocess
|
|
25
|
+
import sys
|
|
26
|
+
import tempfile
|
|
27
|
+
import tomllib
|
|
28
|
+
from dataclasses import dataclass
|
|
29
|
+
from typing import Any
|
|
30
|
+
|
|
31
|
+
import click
|
|
32
|
+
|
|
33
|
+
DEFAULT_BASE_TEMPLATE = "langgraph"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class RemoteTemplateSpec:
|
|
38
|
+
"""Parsed remote template specification."""
|
|
39
|
+
|
|
40
|
+
repo_url: str
|
|
41
|
+
template_path: str
|
|
42
|
+
git_ref: str
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def is_template_spec(value: str) -> bool:
|
|
46
|
+
"""True for a value naming a template to fetch rather than one this CLI ships."""
|
|
47
|
+
return value.startswith("local@") or parse_agent_spec(value) is not None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def parse_agent_spec(agent_spec: str) -> RemoteTemplateSpec | None:
|
|
51
|
+
"""Parse an agent specification; None when it names a bundled or local template."""
|
|
52
|
+
if agent_spec.startswith("local@"):
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
# GitHub /tree/ URL pattern
|
|
56
|
+
tree_pattern = r"^(https?://[^/]+/[^/]+/[^/]+)/tree/([^/]+)/(.*)$"
|
|
57
|
+
match = re.match(tree_pattern, agent_spec)
|
|
58
|
+
if match:
|
|
59
|
+
return RemoteTemplateSpec(
|
|
60
|
+
repo_url=match.group(1),
|
|
61
|
+
template_path=match.group(3).strip("/"),
|
|
62
|
+
git_ref=match.group(2),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# General remote pattern: <repo_url>[/<path>][@<ref>]
|
|
66
|
+
remote_pattern = r"^(https?://[^/]+/[^/]+/[^/@]+)(?:/(.*?))?(?:@([^/]+))?/?$"
|
|
67
|
+
match = re.match(remote_pattern, agent_spec)
|
|
68
|
+
if match:
|
|
69
|
+
repo_url = match.group(1)
|
|
70
|
+
template_path = match.group(2) or ""
|
|
71
|
+
git_ref = match.group(3) or "main"
|
|
72
|
+
|
|
73
|
+
if "@" in template_path:
|
|
74
|
+
path_parts = template_path.split("@")
|
|
75
|
+
template_path = path_parts[0]
|
|
76
|
+
git_ref = path_parts[1]
|
|
77
|
+
|
|
78
|
+
return RemoteTemplateSpec(
|
|
79
|
+
repo_url=repo_url,
|
|
80
|
+
template_path=template_path.strip("/"),
|
|
81
|
+
git_ref=git_ref,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# GitHub shorthand: <org>/<repo>[/<path>][@<ref>]
|
|
85
|
+
github_shorthand_pattern = r"^([^/]+)/([^/@]+)(?:/(.*?))?(?:@([^/]+))?/?$"
|
|
86
|
+
match = re.match(github_shorthand_pattern, agent_spec)
|
|
87
|
+
if match and "/" in agent_spec:
|
|
88
|
+
org = match.group(1)
|
|
89
|
+
repo = match.group(2)
|
|
90
|
+
return RemoteTemplateSpec(
|
|
91
|
+
repo_url=f"https://github.com/{org}/{repo}",
|
|
92
|
+
template_path=match.group(3) or "",
|
|
93
|
+
git_ref=match.group(4) or "main",
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def check_and_execute_with_version_lock(
|
|
100
|
+
template_dir: pathlib.Path,
|
|
101
|
+
original_agent_spec: str | None = None,
|
|
102
|
+
locked: bool = False,
|
|
103
|
+
project_name: str | None = None,
|
|
104
|
+
) -> bool:
|
|
105
|
+
"""Log a template's pinned graph-agents-cli version; always proceed with the running code.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Always False (proceed with the vendored code).
|
|
109
|
+
"""
|
|
110
|
+
if locked or os.environ.get("GRAPH_AGENTS_CLI_SKIP_VERSION_LOCK") == "1":
|
|
111
|
+
return False
|
|
112
|
+
|
|
113
|
+
version = parse_cli_version_from_lock(template_dir / "uv.lock")
|
|
114
|
+
if version:
|
|
115
|
+
logging.debug(
|
|
116
|
+
"Remote template specifies graph-agents-cli version %s; using the running code instead.",
|
|
117
|
+
version,
|
|
118
|
+
)
|
|
119
|
+
return False
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def fetch_remote_template(
|
|
123
|
+
spec: RemoteTemplateSpec,
|
|
124
|
+
original_agent_spec: str | None = None,
|
|
125
|
+
locked: bool = False,
|
|
126
|
+
project_name: str | None = None,
|
|
127
|
+
) -> tuple[pathlib.Path, pathlib.Path]:
|
|
128
|
+
"""Clone a remote template and return (template directory, temp directory to clean up)."""
|
|
129
|
+
temp_dir = tempfile.mkdtemp(prefix="gacli_remote_template_")
|
|
130
|
+
temp_path = pathlib.Path(temp_dir)
|
|
131
|
+
repo_path = temp_path / "repo"
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
clone_url = spec.repo_url
|
|
135
|
+
|
|
136
|
+
clone_cmd = [
|
|
137
|
+
"git",
|
|
138
|
+
"clone",
|
|
139
|
+
"--depth",
|
|
140
|
+
"1",
|
|
141
|
+
"--single-branch",
|
|
142
|
+
"--branch",
|
|
143
|
+
spec.git_ref,
|
|
144
|
+
clone_url,
|
|
145
|
+
str(repo_path),
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
from graph_agents_cli._runner import run_resolved
|
|
149
|
+
|
|
150
|
+
logging.debug("Attempting to clone remote template with Git: %s", shlex.join(clone_cmd))
|
|
151
|
+
# GIT_TERMINAL_PROMPT=0 prevents git from prompting for credentials
|
|
152
|
+
result = run_resolved(
|
|
153
|
+
clone_cmd,
|
|
154
|
+
capture_output=True,
|
|
155
|
+
text=True,
|
|
156
|
+
encoding="utf-8",
|
|
157
|
+
env={**os.environ, "GIT_TERMINAL_PROMPT": "0"},
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# If clone with --single-branch fails, retry without it (for tags)
|
|
161
|
+
if result.returncode != 0:
|
|
162
|
+
if "Remote branch" in result.stderr or "not found" in result.stderr:
|
|
163
|
+
logging.debug(
|
|
164
|
+
"Clone with --single-branch failed, retrying without it (git_ref '%s' is likely a tag)",
|
|
165
|
+
spec.git_ref,
|
|
166
|
+
)
|
|
167
|
+
clone_cmd_without_single_branch = [
|
|
168
|
+
"git",
|
|
169
|
+
"clone",
|
|
170
|
+
"--depth",
|
|
171
|
+
"1",
|
|
172
|
+
"--branch",
|
|
173
|
+
spec.git_ref,
|
|
174
|
+
clone_url,
|
|
175
|
+
str(repo_path),
|
|
176
|
+
]
|
|
177
|
+
run_resolved(
|
|
178
|
+
clone_cmd_without_single_branch,
|
|
179
|
+
capture_output=True,
|
|
180
|
+
text=True,
|
|
181
|
+
check=True,
|
|
182
|
+
encoding="utf-8",
|
|
183
|
+
env={**os.environ, "GIT_TERMINAL_PROMPT": "0"},
|
|
184
|
+
)
|
|
185
|
+
logging.debug("Git clone successful (without --single-branch).")
|
|
186
|
+
else:
|
|
187
|
+
raise subprocess.CalledProcessError(
|
|
188
|
+
result.returncode, clone_cmd, result.stdout, result.stderr
|
|
189
|
+
)
|
|
190
|
+
else:
|
|
191
|
+
logging.debug("Git clone successful.")
|
|
192
|
+
except subprocess.CalledProcessError as e:
|
|
193
|
+
shutil.rmtree(temp_path, ignore_errors=True)
|
|
194
|
+
raise RuntimeError(f"Git clone failed: {e.stderr.strip()}") from e
|
|
195
|
+
|
|
196
|
+
try:
|
|
197
|
+
template_dir = repo_path / spec.template_path if spec.template_path else repo_path
|
|
198
|
+
|
|
199
|
+
if not template_dir.exists():
|
|
200
|
+
raise FileNotFoundError(
|
|
201
|
+
f"Template path not found in the repository: {spec.template_path}"
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
if check_and_execute_with_version_lock(
|
|
205
|
+
template_dir, original_agent_spec, locked, project_name
|
|
206
|
+
):
|
|
207
|
+
shutil.rmtree(temp_path, ignore_errors=True)
|
|
208
|
+
sys.exit(0)
|
|
209
|
+
|
|
210
|
+
return template_dir, temp_path
|
|
211
|
+
except Exception as e:
|
|
212
|
+
shutil.rmtree(temp_path, ignore_errors=True)
|
|
213
|
+
raise RuntimeError(
|
|
214
|
+
f"An unexpected error occurred after fetching remote template: {e}"
|
|
215
|
+
) from e
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _detect_flat_structure(template_dir: pathlib.Path) -> bool:
|
|
219
|
+
"""True when ``agent.py`` sits in the template root with no agent subdirectory."""
|
|
220
|
+
if not (template_dir / "agent.py").exists():
|
|
221
|
+
return False
|
|
222
|
+
|
|
223
|
+
folder_name = template_dir.name.replace("-", "_")
|
|
224
|
+
for subdir in ("app", folder_name):
|
|
225
|
+
subdir_path = template_dir / subdir
|
|
226
|
+
if subdir_path.is_dir() and (subdir_path / "agent.py").exists():
|
|
227
|
+
return False
|
|
228
|
+
|
|
229
|
+
logging.debug(
|
|
230
|
+
"Detected flat structure in '%s': agent.py in root, no agent subdirectory",
|
|
231
|
+
template_dir,
|
|
232
|
+
)
|
|
233
|
+
return True
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def load_remote_template_config(
|
|
237
|
+
template_dir: pathlib.Path,
|
|
238
|
+
cli_overrides: dict[str, Any] | None = None,
|
|
239
|
+
) -> dict[str, Any]:
|
|
240
|
+
"""Load a fetched template's configuration with CLI overrides.
|
|
241
|
+
|
|
242
|
+
Sources, first found wins: ``.template/templateconfig.yaml``, the template's
|
|
243
|
+
``graph-agents-cli-manifest.yaml``, or a ``[tool.graph-agents-cli]`` section in
|
|
244
|
+
its ``pyproject.toml``. CLI overrides take precedence over all of them.
|
|
245
|
+
"""
|
|
246
|
+
config: dict[str, Any] = {
|
|
247
|
+
"base_template": DEFAULT_BASE_TEMPLATE,
|
|
248
|
+
"name": template_dir.name,
|
|
249
|
+
"description": "",
|
|
250
|
+
"agent_directory": "app",
|
|
251
|
+
}
|
|
252
|
+
has_explicit_config = False
|
|
253
|
+
|
|
254
|
+
template_config_path = template_dir / ".template" / "templateconfig.yaml"
|
|
255
|
+
manifest_path = template_dir / "graph-agents-cli-manifest.yaml"
|
|
256
|
+
pyproject_path = template_dir / "pyproject.toml"
|
|
257
|
+
|
|
258
|
+
if template_config_path.exists():
|
|
259
|
+
try:
|
|
260
|
+
import yaml
|
|
261
|
+
|
|
262
|
+
with open(template_config_path, encoding="utf-8") as f:
|
|
263
|
+
template_config = yaml.safe_load(f) or {}
|
|
264
|
+
has_explicit_config = bool(template_config)
|
|
265
|
+
if template_config:
|
|
266
|
+
config.update(template_config)
|
|
267
|
+
logging.debug("Found explicit .template/templateconfig.yaml configuration")
|
|
268
|
+
except Exception as e:
|
|
269
|
+
# ClickException so the commands that surface it print the template
|
|
270
|
+
# author's typo as an error rather than a traceback.
|
|
271
|
+
raise click.ClickException(f"{template_config_path.name} is not valid YAML: {e}") from e
|
|
272
|
+
elif manifest_path.exists():
|
|
273
|
+
try:
|
|
274
|
+
import yaml
|
|
275
|
+
|
|
276
|
+
with open(manifest_path, encoding="utf-8") as f:
|
|
277
|
+
manifest_config = yaml.safe_load(f) or {}
|
|
278
|
+
has_explicit_config = bool(manifest_config)
|
|
279
|
+
if manifest_config:
|
|
280
|
+
config.update(manifest_config)
|
|
281
|
+
logging.debug("Found explicit graph-agents-cli-manifest.yaml configuration")
|
|
282
|
+
except Exception as e:
|
|
283
|
+
logging.error(f"Error loading graph-agents-cli-manifest.yaml config: {e}")
|
|
284
|
+
elif pyproject_path.exists():
|
|
285
|
+
try:
|
|
286
|
+
with open(pyproject_path, "rb") as f:
|
|
287
|
+
pyproject_data = tomllib.load(f)
|
|
288
|
+
|
|
289
|
+
toml_config = pyproject_data.get("tool", {}).get("graph-agents-cli", {})
|
|
290
|
+
project_info = pyproject_data.get("project", {})
|
|
291
|
+
has_explicit_config = bool(toml_config)
|
|
292
|
+
|
|
293
|
+
if toml_config:
|
|
294
|
+
config.update(toml_config)
|
|
295
|
+
logging.debug("Found explicit [tool.graph-agents-cli] configuration")
|
|
296
|
+
|
|
297
|
+
if "name" not in toml_config and "name" in project_info:
|
|
298
|
+
config["name"] = project_info["name"]
|
|
299
|
+
|
|
300
|
+
if "description" not in toml_config and "description" in project_info:
|
|
301
|
+
config["description"] = project_info["description"]
|
|
302
|
+
|
|
303
|
+
logging.debug("Loaded template config from %s", pyproject_path)
|
|
304
|
+
except Exception as e:
|
|
305
|
+
logging.error(f"Error loading pyproject.toml config: {e}")
|
|
306
|
+
else:
|
|
307
|
+
logging.warning(
|
|
308
|
+
"%s declares no graph-agents-cli configuration, so it is treated as a "
|
|
309
|
+
"%s template. Add .template/templateconfig.yaml to say otherwise.",
|
|
310
|
+
template_dir.name,
|
|
311
|
+
DEFAULT_BASE_TEMPLATE,
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
# Flat structure: agent.py in the root with no subdirectory
|
|
315
|
+
if not has_explicit_config and _detect_flat_structure(template_dir):
|
|
316
|
+
folder_name = template_dir.name.replace("-", "_")
|
|
317
|
+
config.setdefault("settings", {})
|
|
318
|
+
config["settings"]["agent_directory"] = folder_name
|
|
319
|
+
config["settings"]["source_agent_directory"] = "."
|
|
320
|
+
config["is_flat_structure"] = True
|
|
321
|
+
logging.debug(
|
|
322
|
+
"Detected flat structure: source='.', target='%s'",
|
|
323
|
+
folder_name,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
config["has_explicit_config"] = bool(has_explicit_config)
|
|
327
|
+
|
|
328
|
+
if cli_overrides:
|
|
329
|
+
config = merge_template_configs(config, cli_overrides)
|
|
330
|
+
logging.debug("Applied CLI overrides: %s", cli_overrides)
|
|
331
|
+
|
|
332
|
+
return config
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def get_base_template_name(config: dict[str, Any]) -> str:
|
|
336
|
+
"""Base template name from a remote template config (default ``langgraph``)."""
|
|
337
|
+
return str(config.get("base_template") or DEFAULT_BASE_TEMPLATE)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def merge_template_configs(
|
|
341
|
+
base_config: dict[str, Any], remote_config: dict[str, Any]
|
|
342
|
+
) -> dict[str, Any]:
|
|
343
|
+
"""Deep-merge ``remote_config`` over a copy of ``base_config``."""
|
|
344
|
+
import copy
|
|
345
|
+
|
|
346
|
+
def deep_merge(d1: dict[str, Any], d2: dict[str, Any]) -> dict[str, Any]:
|
|
347
|
+
for k, v in d2.items():
|
|
348
|
+
if k in d1 and isinstance(d1[k], dict) and isinstance(v, dict):
|
|
349
|
+
d1[k] = deep_merge(d1[k], v)
|
|
350
|
+
else:
|
|
351
|
+
d1[k] = v
|
|
352
|
+
return d1
|
|
353
|
+
|
|
354
|
+
merged_config = copy.deepcopy(base_config)
|
|
355
|
+
return deep_merge(merged_config, remote_config)
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def parse_cli_version_from_lock(uv_lock_path: pathlib.Path) -> str | None:
|
|
359
|
+
"""Parse the graph-agents-cli version pinned in a ``uv.lock``, if any."""
|
|
360
|
+
if not uv_lock_path.exists():
|
|
361
|
+
return None
|
|
362
|
+
|
|
363
|
+
try:
|
|
364
|
+
with open(uv_lock_path, "rb") as f:
|
|
365
|
+
lock_data = tomllib.load(f)
|
|
366
|
+
|
|
367
|
+
for package in lock_data.get("package", []):
|
|
368
|
+
if package.get("name") == "graph-agents-cli":
|
|
369
|
+
version = package.get("version")
|
|
370
|
+
if version:
|
|
371
|
+
logging.debug("Found graph-agents-cli version %s in uv.lock", version)
|
|
372
|
+
return version
|
|
373
|
+
except Exception as e:
|
|
374
|
+
logging.warning(f"Error parsing uv.lock file {uv_lock_path}: {e}")
|
|
375
|
+
|
|
376
|
+
return None
|