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,48 @@
|
|
|
1
|
+
{{- /*
|
|
2
|
+
Optional NetworkPolicy for the agent pods (networkPolicy.enabled, off by
|
|
3
|
+
default). Ingress: the http port only, from networkPolicy.ingressFrom (empty:
|
|
4
|
+
any source). Egress stays open unless networkPolicy.restrictEgress is true;
|
|
5
|
+
then only DNS and networkPolicy.egressTo are allowed. Kubelet probes are not
|
|
6
|
+
subject to NetworkPolicy.
|
|
7
|
+
*/ -}}
|
|
8
|
+
{{- if .Values.networkPolicy.enabled }}
|
|
9
|
+
apiVersion: networking.k8s.io/v1
|
|
10
|
+
kind: NetworkPolicy
|
|
11
|
+
metadata:
|
|
12
|
+
name: {{ include "agent.fullname" . }}
|
|
13
|
+
labels:
|
|
14
|
+
{{- include "agent.labels" . | nindent 4 }}
|
|
15
|
+
spec:
|
|
16
|
+
podSelector:
|
|
17
|
+
matchLabels:
|
|
18
|
+
{{- include "agent.selectorLabels" . | nindent 6 }}
|
|
19
|
+
policyTypes:
|
|
20
|
+
- Ingress
|
|
21
|
+
{{- if .Values.networkPolicy.restrictEgress }}
|
|
22
|
+
- Egress
|
|
23
|
+
{{- end }}
|
|
24
|
+
ingress:
|
|
25
|
+
- ports:
|
|
26
|
+
- port: http
|
|
27
|
+
protocol: TCP
|
|
28
|
+
{{- with .Values.networkPolicy.ingressFrom }}
|
|
29
|
+
from:
|
|
30
|
+
{{- toYaml . | nindent 8 }}
|
|
31
|
+
{{- end }}
|
|
32
|
+
{{- if .Values.networkPolicy.restrictEgress }}
|
|
33
|
+
egress:
|
|
34
|
+
- to:
|
|
35
|
+
- namespaceSelector: {}
|
|
36
|
+
podSelector:
|
|
37
|
+
matchLabels:
|
|
38
|
+
k8s-app: kube-dns
|
|
39
|
+
ports:
|
|
40
|
+
- port: 53
|
|
41
|
+
protocol: UDP
|
|
42
|
+
- port: 53
|
|
43
|
+
protocol: TCP
|
|
44
|
+
{{- with .Values.networkPolicy.egressTo }}
|
|
45
|
+
{{- toYaml . | nindent 4 }}
|
|
46
|
+
{{- end }}
|
|
47
|
+
{{- end }}
|
|
48
|
+
{{- end }}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{{- if .Values.pdb.enabled }}
|
|
2
|
+
apiVersion: policy/v1
|
|
3
|
+
kind: PodDisruptionBudget
|
|
4
|
+
metadata:
|
|
5
|
+
name: {{ include "agent.fullname" . }}
|
|
6
|
+
labels:
|
|
7
|
+
{{- include "agent.labels" . | nindent 4 }}
|
|
8
|
+
spec:
|
|
9
|
+
minAvailable: {{ .Values.pdb.minAvailable }}
|
|
10
|
+
selector:
|
|
11
|
+
matchLabels:
|
|
12
|
+
{{- include "agent.selectorLabels" . | nindent 6 }}
|
|
13
|
+
{{- end }}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{{- /*
|
|
2
|
+
Credentials of the bundled (dev) Postgres, read by the subchart through
|
|
3
|
+
postgresql.auth.existingSecret and by the agent (POSTGRES_PASSWORD).
|
|
4
|
+
|
|
5
|
+
The database volume keeps the password it was initialised with, so this Secret
|
|
6
|
+
must never change once created: `helm upgrade` reuses the live values (lookup),
|
|
7
|
+
the Secret is kept on uninstall (the volume outlives the release too), and the
|
|
8
|
+
dev Argo CD Application, which renders without cluster access, ignores its data
|
|
9
|
+
after the first sync (ignoreDifferences + RespectIgnoreDifferences). A release
|
|
10
|
+
whose subchart generated its own "<release>-postgresql" Secret (charts from
|
|
11
|
+
before this one) carries those passwords over on its first upgrade.
|
|
12
|
+
*/ -}}
|
|
13
|
+
{{- /* An empty existingSecret hands the Secret back to the subchart (generated per render). */ -}}
|
|
14
|
+
{{- if and .Values.postgresql.enabled .Values.postgresqlSecret.create .Values.postgresql.auth.existingSecret }}
|
|
15
|
+
{{- $name := include "agent.postgresql.secretName" . }}
|
|
16
|
+
{{- $live := lookup "v1" "Secret" .Release.Namespace $name }}
|
|
17
|
+
{{- $previous := lookup "v1" "Secret" .Release.Namespace (printf "%s-postgresql" .Release.Name) }}
|
|
18
|
+
{{- $data := dict }}
|
|
19
|
+
{{- if and $live $live.data }}
|
|
20
|
+
{{- $data = $live.data }}
|
|
21
|
+
{{- else if and $previous $previous.data }}
|
|
22
|
+
{{- $data = $previous.data }}
|
|
23
|
+
{{- end }}
|
|
24
|
+
apiVersion: v1
|
|
25
|
+
kind: Secret
|
|
26
|
+
metadata:
|
|
27
|
+
name: {{ $name }}
|
|
28
|
+
labels:
|
|
29
|
+
{{- include "agent.labels" . | nindent 4 }}
|
|
30
|
+
annotations:
|
|
31
|
+
helm.sh/resource-policy: keep
|
|
32
|
+
argocd.argoproj.io/sync-options: Delete=false
|
|
33
|
+
type: Opaque
|
|
34
|
+
data:
|
|
35
|
+
password: {{ index $data "password" | default (randAlphaNum 32 | b64enc) }}
|
|
36
|
+
postgres-password: {{ index $data "postgres-password" | default (randAlphaNum 32 | b64enc) }}
|
|
37
|
+
{{- end }}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: Service
|
|
3
|
+
metadata:
|
|
4
|
+
name: {{ include "agent.fullname" . }}
|
|
5
|
+
labels:
|
|
6
|
+
{{- include "agent.labels" . | nindent 4 }}
|
|
7
|
+
spec:
|
|
8
|
+
type: ClusterIP
|
|
9
|
+
ports:
|
|
10
|
+
- port: {{ .Values.service.port }}
|
|
11
|
+
targetPort: http
|
|
12
|
+
protocol: TCP
|
|
13
|
+
name: http
|
|
14
|
+
selector:
|
|
15
|
+
{{- include "agent.selectorLabels" . | nindent 4 }}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{{- if .Values.serviceAccount.create }}
|
|
2
|
+
apiVersion: v1
|
|
3
|
+
kind: ServiceAccount
|
|
4
|
+
metadata:
|
|
5
|
+
name: {{ include "agent.serviceAccountName" . }}
|
|
6
|
+
labels:
|
|
7
|
+
{{- include "agent.labels" . | nindent 4 }}
|
|
8
|
+
{{- with .Values.serviceAccount.annotations }}
|
|
9
|
+
annotations:
|
|
10
|
+
{{- toYaml . | nindent 4 }}
|
|
11
|
+
{{- end }}
|
|
12
|
+
automountServiceAccountToken: false
|
|
13
|
+
{{- end }}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{{- /*
|
|
2
|
+
Optional Prometheus Operator ServiceMonitor for /metrics
|
|
3
|
+
(metrics.serviceMonitor.enabled, off by default; needs the monitoring.coreos.com
|
|
4
|
+
CRDs). It scrapes the Service's http port inside the cluster: /metrics is never
|
|
5
|
+
published by the HTTPRoute / Ingress. With METRICS_TOKEN set in the app,
|
|
6
|
+
metrics.serviceMonitor.bearerToken.enabled makes Prometheus send it (the
|
|
7
|
+
endpoint's `authorization` field), read from <release>-metrics, a Secret that
|
|
8
|
+
holds only that token (written by `graph-agents-cli secrets apply`), never
|
|
9
|
+
from the app Secret with every other credential.
|
|
10
|
+
*/ -}}
|
|
11
|
+
{{- if .Values.metrics.serviceMonitor.enabled }}
|
|
12
|
+
apiVersion: monitoring.coreos.com/v1
|
|
13
|
+
kind: ServiceMonitor
|
|
14
|
+
metadata:
|
|
15
|
+
name: {{ include "agent.fullname" . }}
|
|
16
|
+
labels:
|
|
17
|
+
{{- include "agent.labels" . | nindent 4 }}
|
|
18
|
+
{{- with .Values.metrics.serviceMonitor.labels }}
|
|
19
|
+
{{- toYaml . | nindent 4 }}
|
|
20
|
+
{{- end }}
|
|
21
|
+
spec:
|
|
22
|
+
selector:
|
|
23
|
+
matchLabels:
|
|
24
|
+
{{- include "agent.selectorLabels" . | nindent 6 }}
|
|
25
|
+
endpoints:
|
|
26
|
+
- port: http
|
|
27
|
+
path: /metrics
|
|
28
|
+
{{- with .Values.metrics.serviceMonitor.interval }}
|
|
29
|
+
interval: {{ . }}
|
|
30
|
+
{{- end }}
|
|
31
|
+
{{- with .Values.metrics.serviceMonitor.scrapeTimeout }}
|
|
32
|
+
scrapeTimeout: {{ . }}
|
|
33
|
+
{{- end }}
|
|
34
|
+
{{- $bearer := .Values.metrics.serviceMonitor.bearerToken | default dict }}
|
|
35
|
+
{{- if $bearer.enabled }}
|
|
36
|
+
authorization:
|
|
37
|
+
type: Bearer
|
|
38
|
+
credentials:
|
|
39
|
+
name: {{ $bearer.secretName | default (printf "%s-metrics" (include "agent.fullname" .)) | quote }}
|
|
40
|
+
key: {{ $bearer.key | default "METRICS_TOKEN" | quote }}
|
|
41
|
+
{{- end }}
|
|
42
|
+
{{- end }}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# dev: a local-load cluster or a dev namespace. Bundled Postgres, no gateway.
|
|
2
|
+
env:
|
|
3
|
+
APP_ENV: dev
|
|
4
|
+
# The pods start even before the app Secret exists (staging and prod require it).
|
|
5
|
+
secretOptional: true
|
|
6
|
+
postgresql:
|
|
7
|
+
enabled: true
|
|
8
|
+
{%- if cookiecutter.runtime == 'langgraph-server' %}
|
|
9
|
+
redis:
|
|
10
|
+
enabled: true
|
|
11
|
+
{%- endif %}
|
|
12
|
+
gateway:
|
|
13
|
+
enabled: false
|
|
14
|
+
image:
|
|
15
|
+
# Set per deploy (`graph-agents-cli deploy --env dev` passes the tag it built;
|
|
16
|
+
# in argocd mode it writes it here, quoted). Empty until then: the chart
|
|
17
|
+
# refuses to render without a tag rather than roll out an image that was
|
|
18
|
+
# never pushed.
|
|
19
|
+
tag: ""
|
|
20
|
+
pullPolicy: IfNotPresent
|
|
21
|
+
tracing:
|
|
22
|
+
enabled: false
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# prod: external Postgres (POSTGRES_DSN / DATABASE_URI from the Secret), gateway on.
|
|
2
|
+
# Changes to this file reach the cluster only through a reviewed pull request.
|
|
3
|
+
env:
|
|
4
|
+
APP_ENV: prod
|
|
5
|
+
# The app Secret is required: without it the pods do not start (no keys).
|
|
6
|
+
secretOptional: false
|
|
7
|
+
postgresql:
|
|
8
|
+
enabled: false
|
|
9
|
+
{%- if cookiecutter.runtime == 'langgraph-server' %}
|
|
10
|
+
redis:
|
|
11
|
+
enabled: false # REDIS_URI from the Secret
|
|
12
|
+
{%- endif %}
|
|
13
|
+
gateway:
|
|
14
|
+
enabled: true
|
|
15
|
+
hostname: ""
|
|
16
|
+
parentRef:
|
|
17
|
+
name: ""
|
|
18
|
+
namespace: ""
|
|
19
|
+
image:
|
|
20
|
+
# Promoted by promote-to-prod (argocd mode) or passed with `deploy --image` (helm-push).
|
|
21
|
+
# Empty until the first promotion: the chart refuses to render without a tag.
|
|
22
|
+
tag: ""
|
|
23
|
+
replicaCount: 2
|
|
24
|
+
pdb:
|
|
25
|
+
enabled: true
|
|
26
|
+
minAvailable: 1
|
|
27
|
+
topologySpread:
|
|
28
|
+
enabled: true
|
|
29
|
+
resources:
|
|
30
|
+
requests:
|
|
31
|
+
cpu: 250m
|
|
32
|
+
memory: 512Mi
|
|
33
|
+
limits:
|
|
34
|
+
memory: 1Gi
|
|
35
|
+
# CPU autoscaling (needs metrics-server). While enabled the HPA owns the
|
|
36
|
+
# replica count; minReplicas stays above pdb.minAvailable so node drains can
|
|
37
|
+
# proceed:
|
|
38
|
+
# hpa:
|
|
39
|
+
# enabled: true
|
|
40
|
+
# minReplicas: 2
|
|
41
|
+
# maxReplicas: 10
|
|
42
|
+
# targetCPU: 70
|
|
43
|
+
# Network isolation (off): examples/networkpolicy.yaml is a worked NetworkPolicy
|
|
44
|
+
# for this environment (DNS, the database, the model endpoint, the APIs in
|
|
45
|
+
# api-policy.yaml); copy its networkPolicy block here and set the addresses.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# staging: external Postgres (POSTGRES_DSN / DATABASE_URI from the Secret), gateway on.
|
|
2
|
+
env:
|
|
3
|
+
APP_ENV: staging
|
|
4
|
+
# The app Secret is required: without it the pods do not start (no keys).
|
|
5
|
+
secretOptional: false
|
|
6
|
+
postgresql:
|
|
7
|
+
enabled: false
|
|
8
|
+
{%- if cookiecutter.runtime == 'langgraph-server' %}
|
|
9
|
+
redis:
|
|
10
|
+
enabled: false # REDIS_URI from the Secret
|
|
11
|
+
{%- endif %}
|
|
12
|
+
gateway:
|
|
13
|
+
enabled: true
|
|
14
|
+
hostname: ""
|
|
15
|
+
parentRef:
|
|
16
|
+
name: ""
|
|
17
|
+
namespace: ""
|
|
18
|
+
image:
|
|
19
|
+
# Written by CI (argocd mode) or passed with `deploy --image` (helm-push / direct).
|
|
20
|
+
# Empty until the first staging build: the chart refuses to render without a tag.
|
|
21
|
+
tag: ""
|
|
22
|
+
replicaCount: 1
|
|
23
|
+
# Requests and limits come from values.yaml; override them here, for example:
|
|
24
|
+
# resources:
|
|
25
|
+
# requests: {cpu: 250m, memory: 512Mi}
|
|
26
|
+
# limits: {memory: 1Gi}
|
|
27
|
+
# Network isolation (off): examples/networkpolicy.yaml is a worked NetworkPolicy
|
|
28
|
+
# for this environment (DNS, the database, the model endpoint, the APIs in
|
|
29
|
+
# api-policy.yaml); copy its networkPolicy block here and set the addresses.
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
# Default values for {{cookiecutter.project_name}}.
|
|
2
|
+
# Per-environment overrides live in values-dev.yaml, values-staging.yaml and
|
|
3
|
+
# values-prod.yaml; `graph-agents-cli deploy --env <env>` passes both files.
|
|
4
|
+
# Helm merges maps key by key, so an environment file only lists what differs
|
|
5
|
+
# (set a key to null there to drop a default, e.g. `resources.limits: null`).
|
|
6
|
+
|
|
7
|
+
image:
|
|
8
|
+
repository: {{cookiecutter.registry}}/{{cookiecutter.project_name}}
|
|
9
|
+
# Always an immutable build tag, never a default: `graph-agents-cli deploy`
|
|
10
|
+
# passes it on the command line, and in argocd mode CI (staging) or `deploy`
|
|
11
|
+
# (prod) writes it into values-<env>.yaml. The chart refuses to render while
|
|
12
|
+
# it is empty, so nothing rolls out an image that was never pushed. Keep it a
|
|
13
|
+
# quoted string ("0123456"): an unquoted number loses digits in YAML (0123456
|
|
14
|
+
# reads as octal), so the chart refuses one.
|
|
15
|
+
tag: ""
|
|
16
|
+
pullPolicy: IfNotPresent
|
|
17
|
+
|
|
18
|
+
# Names of existing image pull secrets in the namespace (operator-provided).
|
|
19
|
+
imagePullSecrets: []
|
|
20
|
+
|
|
21
|
+
replicaCount: 1
|
|
22
|
+
|
|
23
|
+
# Informational: selects the variable names for the subchart-derived
|
|
24
|
+
# connection strings (fastapi -> POSTGRES_DSN, langgraph-server -> DATABASE_URI + REDIS_URI).
|
|
25
|
+
runtime: {{cookiecutter.runtime}}
|
|
26
|
+
|
|
27
|
+
# Non-secret environment (becomes a ConfigMap mounted with envFrom). Secret
|
|
28
|
+
# values (provider key, API_KEY, POSTGRES_DSN/DATABASE_URI/REDIS_URI when the
|
|
29
|
+
# subcharts are disabled, LANGSMITH_API_KEY, ...) come from `existingSecret`.
|
|
30
|
+
env:
|
|
31
|
+
APP_ENV: prod
|
|
32
|
+
MODEL_PROVIDER: {{cookiecutter.model_provider}}
|
|
33
|
+
MODEL_NAME: {{cookiecutter.model}}
|
|
34
|
+
{%- if cookiecutter.model_provider == 'openai-compatible' %}
|
|
35
|
+
OPENAI_BASE_URL: http://CHANGE-ME:11434/v1
|
|
36
|
+
{%- endif %}
|
|
37
|
+
{%- if cookiecutter.model_provider in ['openai', 'openai-compatible'] %}
|
|
38
|
+
# Reasoning effort (none | minimal | low | medium | high | xhigh) and the API: "true" for
|
|
39
|
+
# the Responses API, "false" for Chat Completions. Unset: the model's default effort, and
|
|
40
|
+
# langchain-openai chooses the API. A model that refuses function tools with an effort on
|
|
41
|
+
# Chat Completions needs MODEL_USE_RESPONSES_API: "true".
|
|
42
|
+
# MODEL_REASONING_EFFORT: ""
|
|
43
|
+
# MODEL_USE_RESPONSES_API: ""
|
|
44
|
+
{%- endif %}
|
|
45
|
+
# Structured answers (only with the agent's response_schema.json): auto | provider | tool.
|
|
46
|
+
# RESPONSE_FORMAT_STRATEGY: auto
|
|
47
|
+
{%- if cookiecutter.runtime == 'fastapi' %}
|
|
48
|
+
CHECKPOINTER: postgres
|
|
49
|
+
{%- endif %}
|
|
50
|
+
AUTH_POLICY: {{cookiecutter.auth_policy}}
|
|
51
|
+
{%- if cookiecutter.auth_policy == 'jwt' %}
|
|
52
|
+
# Verified OIDC/JWT tokens: set a JWKS URL (or AUTH_JWT_PUBLIC_KEY), the issuer
|
|
53
|
+
# and the audience; outside APP_ENV=dev the pod refuses to start without them.
|
|
54
|
+
AUTH_JWT_JWKS_URL: ""
|
|
55
|
+
AUTH_JWT_ISSUER: ""
|
|
56
|
+
AUTH_JWT_AUDIENCE: ""
|
|
57
|
+
{%- endif %}
|
|
58
|
+
AUTH_READ_ACROSS_ROLES: ""
|
|
59
|
+
AUTH_ADMIN_ROLES: ""
|
|
60
|
+
{%- if cookiecutter.has_api_policy %}
|
|
61
|
+
# Base URLs of the APIs in api-policy.yaml (tokens come from the Secret).
|
|
62
|
+
{%- for api in cookiecutter.apis %}
|
|
63
|
+
{{ api.base_url_env }}: http://CHANGE-ME
|
|
64
|
+
{%- endfor %}
|
|
65
|
+
{%- if cookiecutter.apis | selectattr('auth', 'equalto', 'exchange') | list %}
|
|
66
|
+
# Token exchange (RFC 8693) for the auth: exchange APIs (the client secret comes from the Secret).
|
|
67
|
+
TOKEN_EXCHANGE_URL: http://CHANGE-ME
|
|
68
|
+
TOKEN_EXCHANGE_CLIENT_ID: {{ cookiecutter.project_name }}
|
|
69
|
+
{%- endif %}
|
|
70
|
+
{%- endif %}
|
|
71
|
+
A2A_NAME: {{cookiecutter.agent_directory}}
|
|
72
|
+
# What the A2A agent card (and its chat skill) says the agent does; empty: a
|
|
73
|
+
# generic description. The card's version is AGENT_VERSION (default 0.1.0).
|
|
74
|
+
A2A_DESCRIPTION: ""
|
|
75
|
+
PORT: "8000"
|
|
76
|
+
|
|
77
|
+
# Kubernetes Secret with the allow-listed keys (created by `graph-agents-cli
|
|
78
|
+
# secrets apply`, never by this chart). Empty means "<release>-app".
|
|
79
|
+
existingSecret: ""
|
|
80
|
+
# Whether the pods may start without that Secret. false (staging, prod): a
|
|
81
|
+
# missing Secret keeps the pods in CreateContainerConfigError instead of
|
|
82
|
+
# running without their keys. values-dev.yaml sets true, so a dev cluster can
|
|
83
|
+
# run (the fake model, say) before any Secret exists.
|
|
84
|
+
secretOptional: false
|
|
85
|
+
|
|
86
|
+
service:
|
|
87
|
+
port: 80
|
|
88
|
+
targetPort: 8000
|
|
89
|
+
|
|
90
|
+
# Public base URL advertised in the A2A agent card (APP_URL). Empty derives
|
|
91
|
+
# https://<gateway.hostname> (or the ingress hostname, http without TLS) when
|
|
92
|
+
# a hostname is set; with neither, the pod falls back to its bind address and
|
|
93
|
+
# warns, and remote A2A clients cannot dial the card's URL. `env.APP_URL`
|
|
94
|
+
# (the ConfigMap) is honoured when this is empty.
|
|
95
|
+
appUrl: ""
|
|
96
|
+
|
|
97
|
+
# Traffic entry: Gateway API HTTPRoute (default) or a legacy Ingress.
|
|
98
|
+
gateway:
|
|
99
|
+
enabled: true
|
|
100
|
+
className: "" # informational; the parentRef selects the Gateway
|
|
101
|
+
hostname: ""
|
|
102
|
+
parentRef:
|
|
103
|
+
name: ""
|
|
104
|
+
namespace: ""
|
|
105
|
+
|
|
106
|
+
ingress:
|
|
107
|
+
enabled: false
|
|
108
|
+
className: ""
|
|
109
|
+
hostname: ""
|
|
110
|
+
annotations: {}
|
|
111
|
+
|
|
112
|
+
# The paths the HTTPRoute (or Ingress) publishes: the agent's API and nothing
|
|
113
|
+
# else. /health and /ready stay inside the cluster (the kubelet probes the pod
|
|
114
|
+
# directly) and so does /metrics (see `metrics`). A request for any other path
|
|
115
|
+
# gets the Gateway's (or ingress controller's) 404. Each entry is a `path` and a
|
|
116
|
+
# `type`: PathPrefix (the path and everything below it, whole segments only:
|
|
117
|
+
# /threads covers /threads/<id>/messages, never /threadsX) or Exact. With a
|
|
118
|
+
# Gateway or Ingress on, the chart refuses an empty list: a Gateway API rule
|
|
119
|
+
# without matches would publish every path.
|
|
120
|
+
route:
|
|
121
|
+
publicPaths:
|
|
122
|
+
# POST /chat (SSE).
|
|
123
|
+
- path: /chat
|
|
124
|
+
type: Exact
|
|
125
|
+
# GET /threads, GET /threads/<id>/messages, DELETE /threads/<id>.
|
|
126
|
+
{%- if cookiecutter.runtime == 'langgraph-server' %}
|
|
127
|
+
# Under LangGraph Server this prefix also publishes the server's native
|
|
128
|
+
# thread routes (search, state, runs of a thread), which the auth handler
|
|
129
|
+
# limits to the caller's own threads; a run started there skips this app's
|
|
130
|
+
# /chat guardrails (run timeout, one run per thread, run records).
|
|
131
|
+
{%- endif %}
|
|
132
|
+
- path: /threads
|
|
133
|
+
type: PathPrefix
|
|
134
|
+
# The A2A agent card (<path>/.well-known/agent-card.json) and JSON-RPC
|
|
135
|
+
# endpoint. Keep it in step with env.A2A_NAME (/a2a/<A2A_NAME>).
|
|
136
|
+
- path: /a2a/{{cookiecutter.agent_directory}}
|
|
137
|
+
type: PathPrefix
|
|
138
|
+
{%- if cookiecutter.runtime == 'langgraph-server' %}
|
|
139
|
+
# LangGraph Server's other native APIs are not published. The auth handler
|
|
140
|
+
# protects them too (assistants, crons and store writes need a role in
|
|
141
|
+
# AUTH_ADMIN_ROLES; store reads are not per user), but runs started through
|
|
142
|
+
# them skip this app's /chat guardrails and run records. Add what your
|
|
143
|
+
# clients need, for example the LangGraph SDK's:
|
|
144
|
+
# - path: /assistants
|
|
145
|
+
# type: PathPrefix
|
|
146
|
+
# - path: /runs
|
|
147
|
+
# type: PathPrefix
|
|
148
|
+
# - path: /store
|
|
149
|
+
# type: PathPrefix
|
|
150
|
+
# - path: /crons
|
|
151
|
+
# type: PathPrefix
|
|
152
|
+
{%- endif %}
|
|
153
|
+
# Published as well while env.APP_ENV is dev, the only environment where the
|
|
154
|
+
# app serves them.
|
|
155
|
+
devPaths:
|
|
156
|
+
- path: /playground
|
|
157
|
+
type: Exact
|
|
158
|
+
- path: /docs
|
|
159
|
+
type: Exact
|
|
160
|
+
- path: /openapi.json
|
|
161
|
+
type: Exact
|
|
162
|
+
|
|
163
|
+
# Prometheus scraping of /metrics (served on the http port unless
|
|
164
|
+
# env.METRICS_ENABLED is false; never published by the route). Off by default.
|
|
165
|
+
metrics:
|
|
166
|
+
# prometheus.io/scrape, /path and /port annotations on the pods, for a
|
|
167
|
+
# Prometheus that discovers pods by annotation. Annotations cannot carry a
|
|
168
|
+
# token: with METRICS_TOKEN set, give that Prometheus's scrape job the token
|
|
169
|
+
# (`authorization.credentials_file`) or use the ServiceMonitor below.
|
|
170
|
+
scrapeAnnotations: false
|
|
171
|
+
# A ServiceMonitor for the Prometheus Operator (needs its CRDs installed).
|
|
172
|
+
serviceMonitor:
|
|
173
|
+
enabled: false
|
|
174
|
+
interval: 30s
|
|
175
|
+
scrapeTimeout: 10s
|
|
176
|
+
# Extra labels, e.g. `release: kube-prometheus-stack`, so the Prometheus's
|
|
177
|
+
# serviceMonitorSelector picks it up.
|
|
178
|
+
labels: {}
|
|
179
|
+
# With METRICS_TOKEN in the app Secret, /metrics answers only
|
|
180
|
+
# `Authorization: Bearer <token>`: enable this so the ServiceMonitor sends
|
|
181
|
+
# it. Prometheus reads the token from a Secret of its own, <release>-metrics,
|
|
182
|
+
# which `graph-agents-cli secrets apply` (and a direct `deploy`) writes from
|
|
183
|
+
# METRICS_TOKEN (add it to secrets.keys): grant Prometheus read access to
|
|
184
|
+
# that Secret only, never to the app Secret, which also holds the provider
|
|
185
|
+
# key, the API tokens and the database DSN. `secretName` / `key` select a
|
|
186
|
+
# Secret you manage yourself (same namespace).
|
|
187
|
+
bearerToken:
|
|
188
|
+
enabled: false
|
|
189
|
+
secretName: "" # default: <release>-metrics
|
|
190
|
+
key: METRICS_TOKEN
|
|
191
|
+
|
|
192
|
+
tls:
|
|
193
|
+
existingSecret: "" # operator-provided certificate Secret
|
|
194
|
+
certManager:
|
|
195
|
+
enabled: false # adds a cert-manager Certificate (requires cert-manager)
|
|
196
|
+
issuerRef:
|
|
197
|
+
name: ""
|
|
198
|
+
kind: ClusterIssuer
|
|
199
|
+
|
|
200
|
+
# Bundled Postgres and Redis (Bitnami subcharts, pinned in Chart.yaml) are for
|
|
201
|
+
# dev only; staging and prod read the connection strings from the Secret.
|
|
202
|
+
#
|
|
203
|
+
# The Bitnami catalogue: since August 2025 Bitnami publishes its free images
|
|
204
|
+
# only as `latest` (meant for development) under docker.io/bitnami; versioned
|
|
205
|
+
# tags need a Broadcom subscription and the old tags were frozen, without
|
|
206
|
+
# updates, under docker.io/bitnamilegacy. So the images below are pinned by
|
|
207
|
+
# digest: renders are reproducible and `latest` moving never changes a running
|
|
208
|
+
# dev database. To refresh a pin, look up the current digest
|
|
209
|
+
# (`docker buildx imagetools inspect docker.io/bitnami/postgresql:latest`).
|
|
210
|
+
# To use something else, either set postgresql.enabled / redis.enabled to false
|
|
211
|
+
# and put POSTGRES_DSN (fastapi) or DATABASE_URI + REDIS_URI (langgraph-server)
|
|
212
|
+
# in the Secret, pointing at a managed database, an operator such as
|
|
213
|
+
# CloudNativePG or any other chart; or swap the dependency in Chart.yaml for a
|
|
214
|
+
# chart that serves <release>-postgresql:5432 (and <release>-redis-master:6379),
|
|
215
|
+
# the addresses this chart derives.
|
|
216
|
+
postgresql:
|
|
217
|
+
enabled: false
|
|
218
|
+
image:
|
|
219
|
+
registry: registry-1.docker.io
|
|
220
|
+
repository: bitnami/postgresql
|
|
221
|
+
tag: latest
|
|
222
|
+
digest: "sha256:7d77a46bbf200709237318c27dec0eaeae2520e403dd18fdebde2be7a6b04993"
|
|
223
|
+
auth:
|
|
224
|
+
database: agent
|
|
225
|
+
username: agent
|
|
226
|
+
# Holds `password` (the agent's user) and `postgres-password`. This chart
|
|
227
|
+
# creates it (postgresqlSecret.create) with random values the first time
|
|
228
|
+
# and then keeps them, so the password stays the one the database volume
|
|
229
|
+
# was initialised with, across upgrades, re-renders and Argo CD syncs.
|
|
230
|
+
existingSecret: {{cookiecutter.project_name}}-postgresql-auth
|
|
231
|
+
primary:
|
|
232
|
+
persistence:
|
|
233
|
+
size: 8Gi
|
|
234
|
+
# A restart or rollout of the dev database shuts Postgres down in "fast"
|
|
235
|
+
# mode: open sessions (the agent's pooled connections) are closed and the
|
|
236
|
+
# data is checkpointed, so the pod stops in about a second. Without it,
|
|
237
|
+
# Kubernetes' SIGTERM asks Postgres for a "smart" shutdown, which waits for
|
|
238
|
+
# every client to disconnect, and the pod is killed after 30 s and needs
|
|
239
|
+
# crash recovery on the next start. (pg_ctl signals the server and returns;
|
|
240
|
+
# the SIGTERM that follows cannot slow a fast shutdown down.)
|
|
241
|
+
lifecycleHooks:
|
|
242
|
+
preStop:
|
|
243
|
+
exec:
|
|
244
|
+
command: ["/bin/sh", "-c", "pg_ctl -D \"$PGDATA\" -m fast --no-wait stop"]
|
|
245
|
+
|
|
246
|
+
# The bundled Postgres's credentials Secret (postgresql.auth.existingSecret):
|
|
247
|
+
# created by this chart when the subchart is enabled, reused on upgrade (helm
|
|
248
|
+
# lookup), kept on uninstall and ignored by Argo CD after the first sync (the
|
|
249
|
+
# Applications ignore its data). Set create: false to provide your own Secret
|
|
250
|
+
# under that name (keys `password` and `postgres-password`).
|
|
251
|
+
postgresqlSecret:
|
|
252
|
+
create: true
|
|
253
|
+
|
|
254
|
+
# Bundled Redis (Bitnami subchart), langgraph-server only.
|
|
255
|
+
redis:
|
|
256
|
+
enabled: false
|
|
257
|
+
architecture: standalone
|
|
258
|
+
image:
|
|
259
|
+
registry: registry-1.docker.io
|
|
260
|
+
repository: bitnami/redis
|
|
261
|
+
tag: latest
|
|
262
|
+
digest: "sha256:ef8442c1ec2e28cef662999f348a4369c22343dc0c86c3bc23041fad22f13ca1"
|
|
263
|
+
auth:
|
|
264
|
+
enabled: false
|
|
265
|
+
|
|
266
|
+
# Health probes. Liveness and startup ask whether the process answers
|
|
267
|
+
# (/health); readiness asks whether the database (and run store) answer within
|
|
268
|
+
# 2 s (/ready), so a pod that loses its database leaves the Service endpoints
|
|
269
|
+
# instead of being restarted. Liveness and readiness start after the startup
|
|
270
|
+
# probe passes (up to failureThreshold x periodSeconds for the first boot).
|
|
271
|
+
probes:
|
|
272
|
+
liveness:
|
|
273
|
+
path: /health
|
|
274
|
+
periodSeconds: 15
|
|
275
|
+
timeoutSeconds: 3
|
|
276
|
+
failureThreshold: 3
|
|
277
|
+
readiness:
|
|
278
|
+
path: /ready
|
|
279
|
+
periodSeconds: 10
|
|
280
|
+
timeoutSeconds: 3
|
|
281
|
+
failureThreshold: 3
|
|
282
|
+
startup:
|
|
283
|
+
path: /health
|
|
284
|
+
periodSeconds: 5
|
|
285
|
+
timeoutSeconds: 3
|
|
286
|
+
failureThreshold: 30
|
|
287
|
+
|
|
288
|
+
# Requests reserve capacity (and are what the HPA's CPU target is a percentage
|
|
289
|
+
# of); the memory limit stops a leaking pod before it starves its node. No CPU
|
|
290
|
+
# limit by default: throttling hurts latency more than it protects neighbours.
|
|
291
|
+
# Override per environment in values-<env>.yaml.
|
|
292
|
+
resources:
|
|
293
|
+
requests:
|
|
294
|
+
cpu: 100m
|
|
295
|
+
memory: 256Mi
|
|
296
|
+
limits:
|
|
297
|
+
memory: 1Gi
|
|
298
|
+
|
|
299
|
+
# CPU-based autoscaling (needs metrics-server). The HPA owns the replica count
|
|
300
|
+
# while enabled (replicaCount is ignored); the chart refuses to render it
|
|
301
|
+
# without resources.requests.cpu. Keep minReplicas above pdb.minAvailable so
|
|
302
|
+
# node drains can proceed.
|
|
303
|
+
hpa:
|
|
304
|
+
enabled: false
|
|
305
|
+
minReplicas: 2
|
|
306
|
+
maxReplicas: 5
|
|
307
|
+
targetCPU: 70
|
|
308
|
+
|
|
309
|
+
pdb:
|
|
310
|
+
enabled: false
|
|
311
|
+
minAvailable: 1
|
|
312
|
+
|
|
313
|
+
# Spread the replicas over nodes when possible (never blocks scheduling).
|
|
314
|
+
topologySpread:
|
|
315
|
+
enabled: false
|
|
316
|
+
topologyKey: kubernetes.io/hostname
|
|
317
|
+
|
|
318
|
+
# Graceful shutdown (rollouts, `deploy --restart`, scale-down, node drains).
|
|
319
|
+
# A stopping pod first keeps serving for `preStopSleepSeconds`, while the
|
|
320
|
+
# Service endpoints, kube-proxy and the Gateway stop sending it new
|
|
321
|
+
# connections: without that pause a rolling restart refuses connections. Then
|
|
322
|
+
# it gets SIGTERM and has `drainSeconds` to finish in-flight requests and
|
|
323
|
+
# streams: uvicorn's graceful-shutdown timeout under the fastapi runtime
|
|
324
|
+
# (UVICORN_TIMEOUT_GRACEFUL_SHUTDOWN), the background-run grace period under
|
|
325
|
+
# langgraph-server (BG_JOB_SHUTDOWN_GRACE_PERIOD_SECS). A /chat stream still
|
|
326
|
+
# running after that is cut off. Kubernetes kills the pod
|
|
327
|
+
# terminationGracePeriodSeconds after it started stopping, pause included, so
|
|
328
|
+
# the chart refuses a grace period that is not longer than
|
|
329
|
+
# preStopSleepSeconds + drainSeconds. For long runs (RUN_TIMEOUT_S) raise
|
|
330
|
+
# drainSeconds and terminationGracePeriodSeconds together.
|
|
331
|
+
shutdown:
|
|
332
|
+
preStopSleepSeconds: 5 # 0: no pause
|
|
333
|
+
drainSeconds: 20 # 0: no limit of its own (the grace period still applies)
|
|
334
|
+
terminationGracePeriodSeconds: 30
|
|
335
|
+
|
|
336
|
+
serviceAccount:
|
|
337
|
+
create: true
|
|
338
|
+
name: ""
|
|
339
|
+
annotations: {}
|
|
340
|
+
|
|
341
|
+
# Tracing. Off unless enabled; capture defaults to metadata (no prompt or
|
|
342
|
+
# completion text leaves the pod).
|
|
343
|
+
tracing:
|
|
344
|
+
enabled: false
|
|
345
|
+
capture: metadata # metadata | full
|
|
346
|
+
otlpEndpoint: "" # OTLP/HTTP collector, used when no LANGSMITH_API_KEY is in the Secret
|
|
347
|
+
langsmith:
|
|
348
|
+
project: "{{cookiecutter.project_name}}"
|
|
349
|
+
|
|
350
|
+
podAnnotations: {}
|
|
351
|
+
# Restricted Pod Security Standard: non-root uid/gid 1000 (the image's user),
|
|
352
|
+
# no privilege escalation, no capabilities, the runtime's default seccomp
|
|
353
|
+
# profile, a read-only root filesystem and no service account token.
|
|
354
|
+
podSecurityContext:
|
|
355
|
+
runAsNonRoot: true
|
|
356
|
+
runAsUser: 1000
|
|
357
|
+
runAsGroup: 1000
|
|
358
|
+
fsGroup: 1000
|
|
359
|
+
seccompProfile:
|
|
360
|
+
type: RuntimeDefault
|
|
361
|
+
securityContext:
|
|
362
|
+
allowPrivilegeEscalation: false
|
|
363
|
+
privileged: false
|
|
364
|
+
runAsNonRoot: true
|
|
365
|
+
capabilities:
|
|
366
|
+
drop: ["ALL"]
|
|
367
|
+
readOnlyRootFilesystem: true
|
|
368
|
+
|
|
369
|
+
# The only writable path with a read-only root filesystem: an emptyDir at
|
|
370
|
+
# /tmp (HOME points there too, for libraries that cache under ~). Mount more
|
|
371
|
+
# with extraVolumes / extraVolumeMounts.
|
|
372
|
+
tmpVolume:
|
|
373
|
+
sizeLimit: 256Mi
|
|
374
|
+
medium: "" # "Memory" for a tmpfs (counts against the memory limit)
|
|
375
|
+
extraVolumes: []
|
|
376
|
+
extraVolumeMounts: []
|
|
377
|
+
|
|
378
|
+
# Optional NetworkPolicy for the agent pods (off by default; needs a CNI that
|
|
379
|
+
# enforces NetworkPolicy). When enabled, ingress is limited to the http port,
|
|
380
|
+
# from the sources in ingressFrom (empty: from anywhere, but only that port;
|
|
381
|
+
# list the Gateway's namespace and, for /metrics, your Prometheus's).
|
|
382
|
+
# With restrictEgress the pods may only reach DNS (pods labelled
|
|
383
|
+
# k8s-app=kube-dns; add a node-local DNS cache address yourself) plus egressTo:
|
|
384
|
+
# the database, the model endpoint and every API in api-policy.yaml.
|
|
385
|
+
# examples/networkpolicy.yaml is a worked staging/prod example to copy into
|
|
386
|
+
# values-<env>.yaml.
|
|
387
|
+
networkPolicy:
|
|
388
|
+
enabled: false
|
|
389
|
+
ingressFrom: []
|
|
390
|
+
# - namespaceSelector: {matchLabels: {kubernetes.io/metadata.name: gateway-system}}
|
|
391
|
+
restrictEgress: false
|
|
392
|
+
egressTo: []
|
|
393
|
+
|
|
394
|
+
nodeSelector: {}
|
|
395
|
+
tolerations: []
|
|
396
|
+
affinity: {}
|