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,15 @@
|
|
|
1
|
+
# Copyright 2026 graph-agents-cli contributors
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""``graph-agents-cli peer``: the other agents a project asks, over A2A (its peers)."""
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Copyright 2026 graph-agents-cli contributors
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""``<agent_dir>/tools/a2a_peers.py``, generated from ``api-policy.yaml`` alone.
|
|
16
|
+
|
|
17
|
+
Every ``protocol: a2a`` API that lets the agent send it a message is a peer.
|
|
18
|
+
Its name, the one the model picks it by, is the one the module already gives
|
|
19
|
+
that API (``PEERS``, read with ``ast``: ``peer add NAME --api-name ...`` records
|
|
20
|
+
it there), else the API's name without an ``_agent`` suffix (``orders_agent``
|
|
21
|
+
is ``orders``), else the API's name (a name another peer already took keeps
|
|
22
|
+
its API's name). Whether the agent
|
|
23
|
+
relays the person's approvals to it (``approvals: relay``) or never decides
|
|
24
|
+
them (``deny``) is read from the policy, as is its description. ``API_CALLS``
|
|
25
|
+
declares exactly the calls the client makes that the policy allows (the card,
|
|
26
|
+
``SendMessage``, a message that approves when relaying, one that rejects,
|
|
27
|
+
``GetTask``, ``CancelTask``, the approvals ledger), so the module always passes
|
|
28
|
+
``lint``. The module is data only: ``peer_tools`` builds the tools.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
import ast
|
|
34
|
+
import re
|
|
35
|
+
from collections.abc import Mapping
|
|
36
|
+
from dataclasses import dataclass, field
|
|
37
|
+
from pathlib import Path
|
|
38
|
+
from typing import Any
|
|
39
|
+
|
|
40
|
+
from graph_agents_cli._api_policy import (
|
|
41
|
+
A2A_APPROVE,
|
|
42
|
+
A2A_KEY,
|
|
43
|
+
A2A_OPERATION_KEY,
|
|
44
|
+
A2A_REJECT,
|
|
45
|
+
DESCRIPTION_KEY,
|
|
46
|
+
PROTOCOL_A2A,
|
|
47
|
+
RPC_METHOD_KEY,
|
|
48
|
+
api_protocol,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
MODULE_NAME = "a2a_peers.py"
|
|
52
|
+
MARKER = "# graph-agents-cli: generated peers v1"
|
|
53
|
+
HEADER = (
|
|
54
|
+
"# Generated by `graph-agents-cli peer` from api-policy.yaml (the protocol: a2a APIs). "
|
|
55
|
+
"Do not edit:\n"
|
|
56
|
+
"# `peer add|remove|sync` rewrite this file. Put custom peer behaviour in another tool "
|
|
57
|
+
"module\n"
|
|
58
|
+
"# that uses app_utils.a2a_client.\n"
|
|
59
|
+
f"{MARKER}\n"
|
|
60
|
+
)
|
|
61
|
+
AGENT_SUFFIX = "_agent"
|
|
62
|
+
CARD_SUFFIX = "/.well-known/agent-card.json"
|
|
63
|
+
CARD_OPERATION = "getAgentCard"
|
|
64
|
+
LEDGER_OPERATION = "listContextApprovals"
|
|
65
|
+
LEDGER_PATH = "/threads/{context_id}/approvals"
|
|
66
|
+
RELAY = "relay"
|
|
67
|
+
DENY = "deny"
|
|
68
|
+
PEER_NAME_RE = re.compile(r"^[a-z][a-z0-9_]{0,25}$")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class Peer:
|
|
73
|
+
"""One peer as the generated module declares it."""
|
|
74
|
+
|
|
75
|
+
name: str
|
|
76
|
+
api: str
|
|
77
|
+
approvals: str
|
|
78
|
+
description: str
|
|
79
|
+
path: str
|
|
80
|
+
calls: list[dict[str, str]] = field(default_factory=list)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def module_path(root: Path, agent_directory: str) -> Path:
|
|
84
|
+
return root / agent_directory / "tools" / MODULE_NAME
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def is_generated(text: str | None) -> bool:
|
|
88
|
+
"""Whether a module's text is the generated one (it carries the marker line)."""
|
|
89
|
+
return text is not None and MARKER in text.splitlines()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def peer_name_of(api: str, taken: set[str]) -> str:
|
|
93
|
+
"""The name a peer's API gives it: without ``_agent``, unless that name is taken."""
|
|
94
|
+
if api.endswith(AGENT_SUFFIX) and len(api) > len(AGENT_SUFFIX):
|
|
95
|
+
short = api[: -len(AGENT_SUFFIX)]
|
|
96
|
+
if short not in taken:
|
|
97
|
+
return short
|
|
98
|
+
return api
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def names_in(text: str | None) -> dict[str, str]:
|
|
102
|
+
"""The peer name the generated module gives each API (``PEERS``): API -> name."""
|
|
103
|
+
if not is_generated(text):
|
|
104
|
+
return {}
|
|
105
|
+
try:
|
|
106
|
+
tree = ast.parse(text or "")
|
|
107
|
+
except SyntaxError:
|
|
108
|
+
return {}
|
|
109
|
+
for node in tree.body:
|
|
110
|
+
if isinstance(node, ast.Assign) and any(
|
|
111
|
+
isinstance(t, ast.Name) and t.id == "PEERS" for t in node.targets
|
|
112
|
+
):
|
|
113
|
+
try:
|
|
114
|
+
peers = ast.literal_eval(node.value)
|
|
115
|
+
except ValueError:
|
|
116
|
+
return {}
|
|
117
|
+
if not isinstance(peers, dict):
|
|
118
|
+
return {}
|
|
119
|
+
return {
|
|
120
|
+
str(entry["api"]): str(name)
|
|
121
|
+
for name, entry in peers.items()
|
|
122
|
+
if isinstance(entry, dict)
|
|
123
|
+
and isinstance(entry.get("api"), str)
|
|
124
|
+
and PEER_NAME_RE.fullmatch(str(name))
|
|
125
|
+
}
|
|
126
|
+
return {}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _candidates(api: str, path: str) -> list[tuple[str, dict[str, str]]]:
|
|
130
|
+
"""Every call the A2A client may make to one peer, by what it is for."""
|
|
131
|
+
post = {"api": api, "method": "POST"}
|
|
132
|
+
return [
|
|
133
|
+
(
|
|
134
|
+
"card",
|
|
135
|
+
{
|
|
136
|
+
"api": api,
|
|
137
|
+
"method": "GET",
|
|
138
|
+
"operation_id": CARD_OPERATION,
|
|
139
|
+
"path": f"{path}{CARD_SUFFIX}",
|
|
140
|
+
},
|
|
141
|
+
),
|
|
142
|
+
("ask", {**post, RPC_METHOD_KEY: "SendMessage", "path": path}),
|
|
143
|
+
(
|
|
144
|
+
"approve",
|
|
145
|
+
{**post, RPC_METHOD_KEY: "SendMessage", A2A_OPERATION_KEY: A2A_APPROVE, "path": path},
|
|
146
|
+
),
|
|
147
|
+
(
|
|
148
|
+
"reject",
|
|
149
|
+
{**post, RPC_METHOD_KEY: "SendMessage", A2A_OPERATION_KEY: A2A_REJECT, "path": path},
|
|
150
|
+
),
|
|
151
|
+
("status", {**post, RPC_METHOD_KEY: "GetTask", "path": path}),
|
|
152
|
+
("cancel", {**post, RPC_METHOD_KEY: "CancelTask", "path": path}),
|
|
153
|
+
(
|
|
154
|
+
"ledger",
|
|
155
|
+
{"api": api, "method": "GET", "operation_id": LEDGER_OPERATION, "path": LEDGER_PATH},
|
|
156
|
+
),
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def peers_of(
|
|
161
|
+
document: Mapping[str, Any] | None, names: Mapping[str, str] | None = None
|
|
162
|
+
) -> list[Peer]:
|
|
163
|
+
"""The peers of a (valid) policy document, in the file's order.
|
|
164
|
+
|
|
165
|
+
``names``: the name to keep for an API (API -> name; `names_in` the module).
|
|
166
|
+
"""
|
|
167
|
+
from graph_agents_cli.dev.policy_check import STATUS_ALLOWED, DeclaredCall, check_call
|
|
168
|
+
|
|
169
|
+
apis = (document or {}).get("apis") or {}
|
|
170
|
+
peers: list[Peer] = []
|
|
171
|
+
kept = {api: name for api, name in (names or {}).items() if api in apis}
|
|
172
|
+
taken: set[str] = set()
|
|
173
|
+
for api in [str(n) for n, a in apis.items() if api_protocol(a) == PROTOCOL_A2A]:
|
|
174
|
+
settings = apis[api]
|
|
175
|
+
path = str((settings.get(A2A_KEY) or {}).get("path") or "")
|
|
176
|
+
allowed: dict[str, dict[str, str]] = {}
|
|
177
|
+
gated: set[str] = set()
|
|
178
|
+
for purpose, call in _candidates(api, path):
|
|
179
|
+
result = check_call(
|
|
180
|
+
DeclaredCall(
|
|
181
|
+
tool=MODULE_NAME,
|
|
182
|
+
api=api,
|
|
183
|
+
method=call["method"],
|
|
184
|
+
operation_id=call.get("operation_id"),
|
|
185
|
+
path=call["path"],
|
|
186
|
+
rpc_method=call.get(RPC_METHOD_KEY),
|
|
187
|
+
a2a_operation=call.get(A2A_OPERATION_KEY),
|
|
188
|
+
),
|
|
189
|
+
document,
|
|
190
|
+
)
|
|
191
|
+
if result.status == STATUS_ALLOWED:
|
|
192
|
+
allowed[purpose] = call
|
|
193
|
+
if result.gate is not None:
|
|
194
|
+
gated.add(purpose)
|
|
195
|
+
if "ask" not in allowed:
|
|
196
|
+
continue # an API the agent cannot send a message to is not a peer
|
|
197
|
+
wanted = kept.get(api)
|
|
198
|
+
others = {n for a, n in kept.items() if a != api} | taken
|
|
199
|
+
name = wanted if wanted and wanted not in taken else peer_name_of(api, others)
|
|
200
|
+
taken.add(name)
|
|
201
|
+
peers.append(
|
|
202
|
+
Peer(
|
|
203
|
+
name=name,
|
|
204
|
+
api=api,
|
|
205
|
+
approvals=RELAY if "approve" in allowed and "approve" in gated else DENY,
|
|
206
|
+
description=str(settings.get(DESCRIPTION_KEY) or ""),
|
|
207
|
+
path=path,
|
|
208
|
+
calls=list(allowed.values()),
|
|
209
|
+
)
|
|
210
|
+
)
|
|
211
|
+
return peers
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _py_str(value: str) -> str:
|
|
215
|
+
"""A Python string literal as ``ruff format`` writes it: double quotes, unless the text
|
|
216
|
+
holds more double quotes than single ones (fewer escapes). Policy text holds no control
|
|
217
|
+
characters (the schema refuses them), so only backslashes and the quote are escaped."""
|
|
218
|
+
quote = "'" if value.count('"') > value.count("'") else '"'
|
|
219
|
+
return quote + value.replace("\\", "\\\\").replace(quote, "\\" + quote) + quote
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def _dict_lines(entry: Mapping[str, str], indent: str) -> list[str]:
|
|
223
|
+
lines = [f"{indent}{{"]
|
|
224
|
+
lines.extend(f"{indent} {_py_str(k)}: {_py_str(str(v))}," for k, v in entry.items())
|
|
225
|
+
lines.append(f"{indent}}},")
|
|
226
|
+
return lines
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def module_text(peers: list[Peer], agent_directory: str) -> str | None:
|
|
230
|
+
"""The generated module for these peers (None: no peer, no module)."""
|
|
231
|
+
if not peers:
|
|
232
|
+
return None
|
|
233
|
+
lines = [
|
|
234
|
+
HEADER.rstrip("\n"),
|
|
235
|
+
"from __future__ import annotations",
|
|
236
|
+
"",
|
|
237
|
+
f"from {agent_directory}.app_utils.a2a_client import peer_tools",
|
|
238
|
+
"",
|
|
239
|
+
"PEERS = {",
|
|
240
|
+
]
|
|
241
|
+
for peer in peers:
|
|
242
|
+
lines.append(f" {_py_str(peer.name)}: {{")
|
|
243
|
+
lines.append(f' "api": {_py_str(peer.api)},')
|
|
244
|
+
lines.append(f' "approvals": {_py_str(peer.approvals)},')
|
|
245
|
+
lines.append(f' "description": {_py_str(peer.description)},')
|
|
246
|
+
lines.append(" },")
|
|
247
|
+
lines.append("}")
|
|
248
|
+
lines.append("API_CALLS = [")
|
|
249
|
+
for peer in peers:
|
|
250
|
+
for call in peer.calls:
|
|
251
|
+
lines.extend(_dict_lines(call, " "))
|
|
252
|
+
lines.append("]")
|
|
253
|
+
lines.append("TOOLS = peer_tools(PEERS)")
|
|
254
|
+
return "\n".join(lines) + "\n"
|