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.
Files changed (291) hide show
  1. graph_agents_cli/__init__.py +26 -0
  2. graph_agents_cli/_api_policy.py +2145 -0
  3. graph_agents_cli/_approvals.py +400 -0
  4. graph_agents_cli/_build.py +186 -0
  5. graph_agents_cli/_build_info.json +7 -0
  6. graph_agents_cli/_chat_client.py +462 -0
  7. graph_agents_cli/_click.py +157 -0
  8. graph_agents_cli/_defaults.py +139 -0
  9. graph_agents_cli/_experiments.py +64 -0
  10. graph_agents_cli/_http.py +192 -0
  11. graph_agents_cli/_output.py +83 -0
  12. graph_agents_cli/_project.py +462 -0
  13. graph_agents_cli/_remote.py +220 -0
  14. graph_agents_cli/_response_schema.py +264 -0
  15. graph_agents_cli/_runner.py +319 -0
  16. graph_agents_cli/_skills_check.py +274 -0
  17. graph_agents_cli/_tools.py +189 -0
  18. graph_agents_cli/_trust.py +66 -0
  19. graph_agents_cli/api/__init__.py +15 -0
  20. graph_agents_cli/api/_changes.py +506 -0
  21. graph_agents_cli/api/_files.py +658 -0
  22. graph_agents_cli/api/cmd_api.py +2480 -0
  23. graph_agents_cli/deploy/__init__.py +15 -0
  24. graph_agents_cli/deploy/_config.py +171 -0
  25. graph_agents_cli/deploy/_image.py +128 -0
  26. graph_agents_cli/deploy/_kube.py +286 -0
  27. graph_agents_cli/deploy/_modes.py +234 -0
  28. graph_agents_cli/deploy/_preflight.py +370 -0
  29. graph_agents_cli/deploy/_values.py +168 -0
  30. graph_agents_cli/deploy/cmd_deploy.py +1866 -0
  31. graph_agents_cli/deploy/gitops.py +562 -0
  32. graph_agents_cli/deploy/local_load.py +273 -0
  33. graph_agents_cli/dev/__init__.py +13 -0
  34. graph_agents_cli/dev/cmd_build.py +131 -0
  35. graph_agents_cli/dev/cmd_install.py +78 -0
  36. graph_agents_cli/dev/cmd_lint.py +119 -0
  37. graph_agents_cli/dev/cmd_playground.py +297 -0
  38. graph_agents_cli/dev/policy_check.py +1287 -0
  39. graph_agents_cli/eval/__init__.py +22 -0
  40. graph_agents_cli/eval/_client.py +670 -0
  41. graph_agents_cli/eval/_common.py +177 -0
  42. graph_agents_cli/eval/_judge.py +168 -0
  43. graph_agents_cli/eval/_judge_runner.py +238 -0
  44. graph_agents_cli/eval/_paths.py +212 -0
  45. graph_agents_cli/eval/checks.py +581 -0
  46. graph_agents_cli/eval/cmd_analyze.py +278 -0
  47. graph_agents_cli/eval/cmd_compare.py +284 -0
  48. graph_agents_cli/eval/cmd_eval_group.py +80 -0
  49. graph_agents_cli/eval/cmd_generate.py +558 -0
  50. graph_agents_cli/eval/cmd_grade.py +466 -0
  51. graph_agents_cli/eval/cmd_metric.py +156 -0
  52. graph_agents_cli/eval/cmd_run.py +370 -0
  53. graph_agents_cli/eval/cmd_submit.py +400 -0
  54. graph_agents_cli/eval/config.py +435 -0
  55. graph_agents_cli/eval/dataset.py +350 -0
  56. graph_agents_cli/eval/gate.py +420 -0
  57. graph_agents_cli/eval/transcript.py +192 -0
  58. graph_agents_cli/extension/__init__.py +13 -0
  59. graph_agents_cli/extension/_compat.py +86 -0
  60. graph_agents_cli/extension/_loader.py +293 -0
  61. graph_agents_cli/extension/_manifest.py +135 -0
  62. graph_agents_cli/extension/_overrides.py +195 -0
  63. graph_agents_cli/extension/_paths.py +91 -0
  64. graph_agents_cli/extension/_refs.py +193 -0
  65. graph_agents_cli/extension/_resolver.py +453 -0
  66. graph_agents_cli/extension/_schema.py +106 -0
  67. graph_agents_cli/extension/_spec.py +253 -0
  68. graph_agents_cli/extension/_sync.py +102 -0
  69. graph_agents_cli/extension/_trust.py +58 -0
  70. graph_agents_cli/extension/cmd_extension_add.py +259 -0
  71. graph_agents_cli/extension/cmd_extension_group.py +57 -0
  72. graph_agents_cli/extension/cmd_extension_list.py +56 -0
  73. graph_agents_cli/extension/cmd_extension_remove.py +61 -0
  74. graph_agents_cli/extension/cmd_extension_update.py +195 -0
  75. graph_agents_cli/info/__init__.py +13 -0
  76. graph_agents_cli/info/cmd_info.py +222 -0
  77. graph_agents_cli/infra/__init__.py +15 -0
  78. graph_agents_cli/infra/checks.py +1169 -0
  79. graph_agents_cli/infra/cmd_infra.py +103 -0
  80. graph_agents_cli/main.py +591 -0
  81. graph_agents_cli/peer/__init__.py +15 -0
  82. graph_agents_cli/peer/_generate.py +254 -0
  83. graph_agents_cli/peer/cmd_peer.py +1151 -0
  84. graph_agents_cli/run/__init__.py +13 -0
  85. graph_agents_cli/run/_local_server.py +1157 -0
  86. graph_agents_cli/run/_signals.py +141 -0
  87. graph_agents_cli/run/cmd_approvals.py +530 -0
  88. graph_agents_cli/run/cmd_run.py +1421 -0
  89. graph_agents_cli/scaffold/__init__.py +19 -0
  90. graph_agents_cli/scaffold/agents/README.md +24 -0
  91. graph_agents_cli/scaffold/agents/empty_py/.template/templateconfig.yaml +22 -0
  92. graph_agents_cli/scaffold/agents/langgraph/.env.example +292 -0
  93. graph_agents_cli/scaffold/agents/langgraph/.template/templateconfig.yaml +28 -0
  94. graph_agents_cli/scaffold/agents/langgraph/Dockerfile +59 -0
  95. graph_agents_cli/scaffold/agents/langgraph/Dockerfile.langgraph-server +59 -0
  96. graph_agents_cli/scaffold/agents/langgraph/README.md +571 -0
  97. graph_agents_cli/scaffold/agents/langgraph/api-policy.yaml +60 -0
  98. graph_agents_cli/scaffold/agents/langgraph/app/__init__.py +20 -0
  99. graph_agents_cli/scaffold/agents/langgraph/app/agent.py +174 -0
  100. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/__init__.py +15 -0
  101. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a.py +2162 -0
  102. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a_client.py +1167 -0
  103. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/api_client.py +4220 -0
  104. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/approvals.py +1349 -0
  105. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/auth.py +1986 -0
  106. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/chat.py +2962 -0
  107. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/checkpointer.py +432 -0
  108. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/content.py +569 -0
  109. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/db.py +580 -0
  110. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/limits.py +203 -0
  111. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/metrics.py +231 -0
  112. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/middleware.py +361 -0
  113. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/model.py +611 -0
  114. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/playground.py +230 -0
  115. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/run_locks.py +459 -0
  116. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/structured.py +755 -0
  117. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/telemetry.py +681 -0
  118. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/threads.py +493 -0
  119. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/token_exchange.py +959 -0
  120. graph_agents_cli/scaffold/agents/langgraph/app/fast_api_app.py +770 -0
  121. graph_agents_cli/scaffold/agents/langgraph/app/policies/__init__.py +55 -0
  122. graph_agents_cli/scaffold/agents/langgraph/app/policies/custom.py +97 -0
  123. graph_agents_cli/scaffold/agents/langgraph/app/tools/__init__.py +46 -0
  124. graph_agents_cli/scaffold/agents/langgraph/app/tools/example_api.py +92 -0
  125. graph_agents_cli/scaffold/agents/langgraph/app/tools/weather.py +33 -0
  126. graph_agents_cli/scaffold/agents/langgraph/langgraph.json +14 -0
  127. graph_agents_cli/scaffold/agents/langgraph/pyproject.toml +78 -0
  128. graph_agents_cli/scaffold/agents/langgraph/tests/conftest.py +376 -0
  129. graph_agents_cli/scaffold/agents/langgraph/tests/eval/datasets/basic-dataset.json +53 -0
  130. graph_agents_cli/scaffold/agents/langgraph/tests/eval/eval_config.yaml +32 -0
  131. graph_agents_cli/scaffold/agents/langgraph/tests/integration/approval_graph.py +137 -0
  132. graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_issuer.py +216 -0
  133. graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_openai.py +357 -0
  134. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_outcomes.py +569 -0
  135. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_relay.py +479 -0
  136. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_api_surface.py +812 -0
  137. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals.py +1367 -0
  138. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals_server.py +794 -0
  139. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor.py +497 -0
  140. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor_server.py +247 -0
  141. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_history_repair.py +278 -0
  142. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_model_apis.py +242 -0
  143. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_postgres.py +637 -0
  144. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_resilience_postgres.py +770 -0
  145. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_runtime_guardrails.py +854 -0
  146. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_e2e.py +340 -0
  147. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_runtime.py +989 -0
  148. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_answers.py +584 -0
  149. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_server.py +222 -0
  150. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_token_exchange_issuer.py +650 -0
  151. graph_agents_cli/scaffold/agents/langgraph/tests/load_test/.results/.placeholder +0 -0
  152. graph_agents_cli/scaffold/agents/langgraph/tests/load_test/README.md +22 -0
  153. graph_agents_cli/scaffold/agents/langgraph/tests/load_test/conftest.py +21 -0
  154. graph_agents_cli/scaffold/agents/langgraph/tests/load_test/load_test.py +81 -0
  155. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_client.py +824 -0
  156. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_scoping.py +724 -0
  157. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client.py +1214 -0
  158. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client_hardening.py +716 -0
  159. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_policy_rpc.py +767 -0
  160. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_approval_ledger.py +1536 -0
  161. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_fake_model.py +115 -0
  162. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_jwt_policy.py +991 -0
  163. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_limits.py +310 -0
  164. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging.py +148 -0
  165. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging_hardening.py +271 -0
  166. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_policy.py +378 -0
  167. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_resilience.py +610 -0
  168. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_server_auth.py +702 -0
  169. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_structured.py +673 -0
  170. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_telemetry.py +404 -0
  171. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_thread_listing.py +255 -0
  172. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_threads.py +268 -0
  173. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_token_exchange.py +1320 -0
  174. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_untrusted_content.py +393 -0
  175. graph_agents_cli/scaffold/agents/langgraph/uv-fastapi.lock +2084 -0
  176. graph_agents_cli/scaffold/agents/langgraph/uv-langgraph-server.lock +2106 -0
  177. graph_agents_cli/scaffold/agents/langgraph/{{cookiecutter.agent_guidance_filename}} +129 -0
  178. graph_agents_cli/scaffold/base_templates/_shared/graph-agents-cli-manifest.yaml +36 -0
  179. graph_agents_cli/scaffold/base_templates/python/.dockerignore +32 -0
  180. graph_agents_cli/scaffold/base_templates/python/.github/CODEOWNERS +30 -0
  181. graph_agents_cli/scaffold/base_templates/python/.github/agent.env +7 -0
  182. graph_agents_cli/scaffold/base_templates/python/.github/workflows/pr_checks.yaml +214 -0
  183. graph_agents_cli/scaffold/base_templates/python/.gitignore +209 -0
  184. graph_agents_cli/scaffold/base_templates/python/tests/unit/test_dummy.py +23 -0
  185. graph_agents_cli/scaffold/base_templates/python/{{cookiecutter.agent_guidance_filename}} +35 -0
  186. graph_agents_cli/scaffold/cmd_scaffold_group.py +49 -0
  187. graph_agents_cli/scaffold/commands/__init__.py +13 -0
  188. graph_agents_cli/scaffold/commands/create.py +1424 -0
  189. graph_agents_cli/scaffold/commands/enhance.py +1652 -0
  190. graph_agents_cli/scaffold/commands/upgrade.py +570 -0
  191. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/agent.env +12 -0
  192. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/promote-to-prod.yaml +371 -0
  193. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/staging.yaml +450 -0
  194. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-dev.yaml +43 -0
  195. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-prod.yaml +41 -0
  196. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-staging.yaml +43 -0
  197. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/.helmignore +14 -0
  198. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/Chart.yaml +21 -0
  199. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/examples/networkpolicy.yaml +103 -0
  200. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/NOTES.txt +48 -0
  201. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/_helpers.tpl +189 -0
  202. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/certificate.yaml +15 -0
  203. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/configmap.yaml +10 -0
  204. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/deployment.yaml +199 -0
  205. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/hpa.yaml +22 -0
  206. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/httproute.yaml +30 -0
  207. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/ingress.yaml +39 -0
  208. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/networkpolicy.yaml +48 -0
  209. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/pdb.yaml +13 -0
  210. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/postgresql-secret.yaml +37 -0
  211. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/service.yaml +15 -0
  212. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/serviceaccount.yaml +13 -0
  213. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/servicemonitor.yaml +42 -0
  214. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-dev.yaml +22 -0
  215. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-prod.yaml +45 -0
  216. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-staging.yaml +29 -0
  217. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values.yaml +396 -0
  218. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/tests/integration/test_chart.py +269 -0
  219. graph_agents_cli/scaffold/deployment_targets/none/README.md +5 -0
  220. graph_agents_cli/scaffold/deployment_targets/none/python/README.md +6 -0
  221. graph_agents_cli/scaffold/utils/__init__.py +13 -0
  222. graph_agents_cli/scaffold/utils/backup.py +212 -0
  223. graph_agents_cli/scaffold/utils/build_record.py +257 -0
  224. graph_agents_cli/scaffold/utils/cli_options.py +184 -0
  225. graph_agents_cli/scaffold/utils/fs.py +83 -0
  226. graph_agents_cli/scaffold/utils/generate_locks.py +214 -0
  227. graph_agents_cli/scaffold/utils/generation_metadata.py +88 -0
  228. graph_agents_cli/scaffold/utils/keyedit.py +768 -0
  229. graph_agents_cli/scaffold/utils/keymerge.py +537 -0
  230. graph_agents_cli/scaffold/utils/language.py +138 -0
  231. graph_agents_cli/scaffold/utils/lock_utils.py +94 -0
  232. graph_agents_cli/scaffold/utils/logging.py +77 -0
  233. graph_agents_cli/scaffold/utils/manifest.py +292 -0
  234. graph_agents_cli/scaffold/utils/merge.py +970 -0
  235. graph_agents_cli/scaffold/utils/merge3.py +216 -0
  236. graph_agents_cli/scaffold/utils/openapi_seed.py +199 -0
  237. graph_agents_cli/scaffold/utils/remote_template.py +376 -0
  238. graph_agents_cli/scaffold/utils/template.py +1352 -0
  239. graph_agents_cli/scaffold/utils/upgrade.py +894 -0
  240. graph_agents_cli/scaffold/utils/version.py +438 -0
  241. graph_agents_cli/secrets/__init__.py +15 -0
  242. graph_agents_cli/secrets/_apply.py +954 -0
  243. graph_agents_cli/secrets/_required.py +188 -0
  244. graph_agents_cli/secrets/cmd_secrets.py +211 -0
  245. graph_agents_cli/setup/__init__.py +13 -0
  246. graph_agents_cli/setup/_antigravity.py +221 -0
  247. graph_agents_cli/setup/cmd_auth.py +1030 -0
  248. graph_agents_cli/setup/cmd_dev_token.py +513 -0
  249. graph_agents_cli/setup/cmd_setup.py +428 -0
  250. graph_agents_cli/setup/cmd_update.py +140 -0
  251. graph_agents_cli/skills/__init__.py +13 -0
  252. graph_agents_cli/skills/_bundle.py +65 -0
  253. graph_agents_cli/skills/data/README.md +19 -0
  254. graph_agents_cli/skills/data/graph-agents-cli-deploy/SKILL.md +357 -0
  255. graph_agents_cli/skills/data/graph-agents-cli-deploy/references/github-settings.md +113 -0
  256. graph_agents_cli/skills/data/graph-agents-cli-deploy/references/gitops.md +137 -0
  257. graph_agents_cli/skills/data/graph-agents-cli-deploy/references/kubernetes.md +315 -0
  258. graph_agents_cli/skills/data/graph-agents-cli-deploy/references/secrets.md +160 -0
  259. graph_agents_cli/skills/data/graph-agents-cli-eval/SKILL.md +303 -0
  260. graph_agents_cli/skills/data/graph-agents-cli-eval/references/dataset_schema.md +282 -0
  261. graph_agents_cli/skills/data/graph-agents-cli-eval/references/metrics-guide.md +143 -0
  262. graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/SKILL.md +659 -0
  263. graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langchain-models.md +124 -0
  264. graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langgraph.md +235 -0
  265. graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/template-contract.md +477 -0
  266. graph_agents_cli/skills/data/graph-agents-cli-observability/SKILL.md +231 -0
  267. graph_agents_cli/skills/data/graph-agents-cli-observability/references/langsmith.md +46 -0
  268. graph_agents_cli/skills/data/graph-agents-cli-observability/references/otel.md +59 -0
  269. graph_agents_cli/skills/data/graph-agents-cli-scaffold/SKILL.md +414 -0
  270. graph_agents_cli/skills/data/graph-agents-cli-scaffold/references/flags.md +134 -0
  271. graph_agents_cli/skills/data/graph-agents-cli-workflow/SKILL.md +478 -0
  272. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/brainstorming.md +118 -0
  273. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/commands.md +419 -0
  274. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/extension.md +156 -0
  275. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/internals.md +67 -0
  276. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/spec-template.md +56 -0
  277. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/terminology.md +119 -0
  278. graph_agents_cli/system/__init__.py +15 -0
  279. graph_agents_cli/system/_apply.py +519 -0
  280. graph_agents_cli/system/_checks.py +1023 -0
  281. graph_agents_cli/system/_deploy.py +215 -0
  282. graph_agents_cli/system/_model.py +363 -0
  283. graph_agents_cli/system/_system.py +664 -0
  284. graph_agents_cli/system/_views.py +208 -0
  285. graph_agents_cli/system/cmd_system.py +423 -0
  286. graph_agents_cli-0.3.1.dist-info/METADATA +162 -0
  287. graph_agents_cli-0.3.1.dist-info/RECORD +291 -0
  288. graph_agents_cli-0.3.1.dist-info/WHEEL +4 -0
  289. graph_agents_cli-0.3.1.dist-info/entry_points.txt +2 -0
  290. graph_agents_cli-0.3.1.dist-info/licenses/LICENSE +201 -0
  291. graph_agents_cli-0.3.1.dist-info/licenses/NOTICE +19 -0
@@ -0,0 +1,129 @@
1
+ process: {{ cookiecutter.process if cookiecutter.process else 'null' }}
2
+
3
+ # Coding Agent Guide for {{cookiecutter.project_name}}
4
+
5
+ This is a LangGraph project scaffolded by graph-agents-cli. `{{cookiecutter.agent_directory}}/agent.py`
6
+ exports `graph`, a compiled LangGraph agent with no checkpointer bound;
7
+ `{{cookiecutter.agent_directory}}/fast_api_app.py` exports `app`, the FastAPI application that serves
8
+ `POST /chat` (SSE), `GET /threads`, `GET /threads/{id}/messages`, `DELETE /threads/{id}`,
9
+ the approvals of gated API calls (`GET /threads/{id}/approvals`, `GET /approvals`,
10
+ `POST /threads/{id}/approvals/{approval_id}`), `GET /health` (liveness), `GET /ready` (readiness),
11
+ `GET /metrics`, `GET /playground` (dev only) and the A2A protocol under `/a2a/{{cookiecutter.agent_directory}}`.
12
+ Runtime: `{{cookiecutter.runtime}}`. Model provider: `{{cookiecutter.model_provider}}` (`MODEL_PROVIDER` in `.env`).
13
+ Auth policy: `{{cookiecutter.auth_policy}}` (`AUTH_POLICY`). Every setting and its default is in
14
+ `.env.example`; `README.md` explains the API, the auth policies and the deploy rules.
15
+
16
+ ## Governing process
17
+
18
+ The `process:` line at the top of this file names the process document that
19
+ governs this project. When it is not `null`, follow that process's gates and
20
+ approvals instead of the generic spec-before-code gate of the
21
+ `graph-agents-cli-workflow` skill, and treat the generic gate as satisfied only
22
+ by that process's approvals. When it is `null`, the generic gate applies:
23
+ write `.graph-agents-cli-spec.md` and get it approved before writing code.
24
+
25
+ ## The loop
26
+
27
+ 1. Build in `{{cookiecutter.agent_directory}}/`. Tools live in `{{cookiecutter.agent_directory}}/tools/`; every tool module
28
+ (subpackages included) declares `API_CALLS` as one literal list (empty when it calls no
29
+ external API) and reaches an external API only through `get_client("<api>")` of
30
+ `{{cookiecutter.agent_directory}}/app_utils/api_client.py`, which enforces `api-policy.yaml` and fails closed.
31
+ Keep `graph` unbound (no checkpointer) and keep its `recursion_limit` config and its
32
+ middleware (`SurfaceApiErrors`, `AnswerInvalidToolCalls`, which answers tool calls whose
33
+ arguments are not valid JSON, and `UntrustedToolResults`, which fences tool results as
34
+ untrusted data).
35
+ 2. Try it: `cp .env.example .env` and `graph-agents-cli login --write-env` once, then
36
+ `graph-agents-cli playground` (the app with `/playground`), or `graph-agents-cli run "prompt"`. `graph-agents-cli playground --graph` opens
37
+ LangGraph Studio against the graph directly (bypasses the auth policy).
38
+ {%- if cookiecutter.auth_policy == 'jwt' %}
39
+ This project's policy is `jwt`: before `run` or `eval run`, put a local token in the variable
40
+ they send, `export GRAPH_AGENTS_CLI_API_KEY="$(graph-agents-cli auth dev-token --sub <user> --roles <roles>)"`
41
+ (dev key, `APP_ENV=dev` only). Never put a token on the command line (`--header`).
42
+ {%- endif %}
43
+ 3. Write eval cases by hand in `tests/eval/datasets/`, then `graph-agents-cli eval run`
44
+ until the gate passes. `eval compare` shows regressions; `eval analyze` clusters failures.
45
+ 4. `uv run pytest` and `graph-agents-cli lint` before deploying.
46
+ {%- if cookiecutter.deployment_target != 'kubernetes' %}
47
+ 5. No deployment target yet: `graph-agents-cli scaffold enhance --deployment-target kubernetes`
48
+ adds the chart and the deploy commands, only when the user asks for it.
49
+ {%- else %}
50
+ 5. `graph-agents-cli deploy --env dev` **only after the user approves it.**
51
+ {%- endif %}
52
+ {%- if cookiecutter.deployment_target != 'kubernetes' %}
53
+ {%- elif cookiecutter.cd == 'skip' %}
54
+ With `cd: skip` staging and production are direct deploys too (`deploy --env staging|prod`):
55
+ the kube context must be recorded in the manifest or passed with `--context`, and secrets come
56
+ from `.env.<env>`, never `.env`.
57
+ {%- else %}
58
+ Staging and production go through the CI/CD path recorded in the manifest (`cd: {{cookiecutter.cd}}`);
59
+ outside `dev` the kube context must be recorded in the manifest or passed with `--context`, and
60
+ secrets come from `.env.<env>`, never `.env`.
61
+ {%- endif %}
62
+
63
+ ## Commands
64
+
65
+ | Command | Purpose |
66
+ |---|---|
67
+ | `graph-agents-cli playground` | Run the app with reload and open the dev chat page |
68
+ | `graph-agents-cli run "prompt"` | One-shot chat (`--mode a2a` for the A2A path, `--url` for a deployed agent) |
69
+ | `uv run pytest` | Unit and integration tests (fake model, in-memory checkpointer; they read neither `.env` nor your tools) |
70
+ {%- if cookiecutter.auth_policy == 'jwt' %}
71
+ | `graph-agents-cli auth dev-token --sub <user>` | A JWT for local runs, printed for `GRAPH_AGENTS_CLI_API_KEY` |
72
+ {%- endif %}
73
+ | `graph-agents-cli eval run` | Generate traces and grade them against the gate |
74
+ | `graph-agents-cli lint` | ruff plus the API-policy check of every tool |
75
+ | `graph-agents-cli api show` / `api check` | The outbound API policy and each tool's declared calls / the policy check alone |
76
+ | `graph-agents-cli approvals list` | Gated API calls waiting for a person's approval (deciding one is the user's, not yours) |
77
+ | `graph-agents-cli build` | Build the container image from the runtime's Dockerfile |
78
+ | `graph-agents-cli deploy --env <env>` | Deploy (direct modes) or open the desired-state PR (argocd) |
79
+ | `graph-agents-cli secrets apply --env <env>` | Create or update the environment's app Secret from `.env.<env>` |
80
+ | `graph-agents-cli secrets status --env <env>` | Which keys the Secret holds (never values); exit 1 on a missing required key |
81
+ | `graph-agents-cli infra check --env <env>` | Read-only report of cluster and GitHub prerequisites |
82
+
83
+ ## Rules
84
+
85
+ - **Spec before code** unless the governing process says otherwise (see above).
86
+ - **Change only what was asked.** Preserve surrounding code, comments, config values and formatting.
87
+ - **Never change the model** (`MODEL_PROVIDER`, `MODEL_NAME`) unless explicitly asked.
88
+ A model 404 means the name is wrong for the provider or the endpoint; fix the
89
+ configuration in `.env`, not `{{cookiecutter.agent_directory}}/agent.py`.
90
+ - **Human approval before deploy.** Never run `graph-agents-cli deploy` without the user's explicit go-ahead,
91
+ and never pass `--yes` (accepting the kubeconfig's current context) or `--rotate-api-key` on your own.
92
+ - **Run Python through uv**: `uv run python script.py`, after `uv sync`.
93
+ - **Three strikes.** The same error three times means fix the cause, not retry.
94
+ - **The example tool is yours to replace.** `tools/weather.py` (and its eval case) only show the
95
+ pattern; the tests under `tests/` use their own test tool, so removing it breaks no test.
96
+ - **Tools declare their API calls.** Add an `API_CALLS` entry (`api`, `method`,
97
+ `operation_id` and/or `path`) for every external API call a tool makes;
98
+ `graph-agents-cli lint` refuses undeclared or disallowed calls. Use the
99
+ `operation_id` the API's spec gives the call, the same in `API_CALLS` and on the
100
+ call; never relabel a call to get it past `lint` (a denial holds on the path
101
+ anyway). Never bypass `api_client.py` with a raw HTTP client.
102
+ - **Change `api-policy.yaml` only when the user asks**, with `graph-agents-cli api`
103
+ (`add`, `access`, `allow`, `deny`, `revoke`, `limits`, `approval`, `remove`; show the
104
+ user the printed diff, use `--dry-run` first). The policy is a security boundary: never
105
+ widen access (more methods or operations, a lifted denial, a raised limit, a removed
106
+ or loosened `approval` gate, `requester` added to a four-eyes gate) on your own. When
107
+ a tool needs a call the policy refuses, `lint` prints the command that would allow it:
108
+ propose it, do not run it unasked. Widening goes through a pull request reviewed by the
109
+ code owners. Proposing an `approval` gate for write calls is welcome; adding one is
110
+ still the user's decision.
111
+ - **Gated calls pause for a person.** A call the policy's `approval` gates waits for an
112
+ approver: never approve or reject one yourself (the approvals routes,
113
+ `graph-agents-cli approvals`), unless the user explicitly tells you to decide that one.
114
+ A tool makes at most one gated call per tool call, and code before it runs again on
115
+ resume, so keep other side effects after it; pass `redact=[...]` for fields an approver
116
+ need not read. Tests of gated tools run inside a graph (see `tests/unit/test_approval_ledger.py`).
117
+ - **A response schema is a contract.** When `{{cookiecutter.agent_directory}}/response_schema.json`
118
+ exists, clients read the agent's final answer as that JSON (`message.end`
119
+ `structured_response`): change it only when the user asks, keep `response_format=` and
120
+ `StructuredAnswer()` (last) in `agent.py`, and run `graph-agents-cli lint` after an edit.
121
+ - **Never edit `graph-agents-cli-manifest.yaml` or `values-prod.yaml`** unless the
122
+ user asks: production desired state changes only through a pull request reviewed
123
+ by the code owners.
124
+ - **Do not export prompts or user data** to a hosted tracing destination unless
125
+ the user has decided so (`TRACING_ENABLED`, `TRACE_CAPTURE=full`).
126
+ - **Never log credentials, prompts or tool arguments**, and keep secrets out of
127
+ `Principal.attributes` except under `attributes["credentials"]`.
128
+ - **Respect the guardrails** (`RUN_TIMEOUT_S`, `RECURSION_LIMIT`, the one-run-per-thread 409):
129
+ fix a tool or graph that hits them instead of raising the limits, unless the user asks.
@@ -0,0 +1,36 @@
1
+ # Project manifest written by `graph-agents-cli create`.
2
+ # Authoritative for `info`, `upgrade`, `deploy` and `secrets`; edit deliberately.
3
+ name: '{{cookiecutter.project_name}}'
4
+ cli_version: '{{cookiecutter.package_version}}'
5
+ agent_directory: '{{cookiecutter.agent_directory}}'
6
+ base_template: '{{cookiecutter.recorded_base_template}}'
7
+ generated_at: '{{cookiecutter.generated_at}}'
8
+ language: '{{cookiecutter.language or "python"}}'
9
+ create_params:
10
+ deployment_target: '{{cookiecutter.deployment_target}}'
11
+ runtime: '{{cookiecutter.runtime}}'
12
+ model_provider: '{{cookiecutter.model_provider}}'
13
+ model: '{{cookiecutter.model}}'
14
+ checkpointer: '{{cookiecutter.checkpointer}}'
15
+ registry: '{{cookiecutter.registry}}'
16
+ cd: '{{cookiecutter.cd}}'
17
+ auth_policy: '{{cookiecutter.auth_policy}}'
18
+ # false while the custom auth policy stub is in place; deploy --env staging|prod refuses until true
19
+ auth_policy_implemented: {{ 'false' if cookiecutter.auth_policy == 'custom' else 'true' }}
20
+ agent_guidance_filename: '{{cookiecutter.agent_guidance_filename}}'
21
+ {%- if cookiecutter.deployment_target == 'kubernetes' %}
22
+ environments:
23
+ dev: { context: "", namespace: {{cookiecutter.project_name}}-dev }
24
+ staging: { context: "", namespace: {{cookiecutter.project_name}}-staging }
25
+ prod: { context: "", namespace: {{cookiecutter.project_name}}-prod }
26
+ {%- endif %}
27
+ secrets:
28
+ # Only these keys are exported from an env file into the environment's Secret.
29
+ keys: [{{ cookiecutter.secret_keys | join(', ') }}]
30
+ # Team or role responsible for provisioning and rotating the Secret (free text).
31
+ owner: ""
32
+ {%- if cookiecutter.has_api_policy %}
33
+ api_policy:
34
+ policy_file: api-policy.yaml
35
+ {%- endif %}
36
+ process: {{ cookiecutter.process if cookiecutter.process else 'null' }}
@@ -0,0 +1,32 @@
1
+ # Build context exclusions for `graph-agents-cli build` / `deploy` (context `.`).
2
+ # Docker does not read .gitignore: without this file the image (and the
3
+ # registry it is pushed to) would carry .env with the API keys, the virtualenv,
4
+ # .git (with a CI checkout token), artifacts and the local run state.
5
+ .git
6
+ .github
7
+ .env
8
+ .env.*
9
+ !.env.example
10
+ .venv
11
+ .venv*
12
+ .graph-agents-cli/
13
+ .langgraph_api/
14
+ artifacts/
15
+ deployment/
16
+ tests/
17
+ docs/
18
+ __pycache__/
19
+ *.py[cod]
20
+ .pytest_cache/
21
+ .ruff_cache/
22
+ .mypy_cache/
23
+ .saved_chats
24
+ .locust_env
25
+ .persist_vector_store
26
+ *.pem
27
+ *-key.json
28
+ credentials*.json
29
+ .vscode/
30
+ .idea/
31
+ Dockerfile*
32
+ .dockerignore
@@ -0,0 +1,30 @@
1
+ # Everything that decides what runs in production, or what the CI gate checks,
2
+ # changes only through a pull request reviewed by these owners (the production
3
+ # gate). Replace the placeholder with the team or users who approve production
4
+ # changes (GitHub ignores an owner that does not exist, which silently removes
5
+ # the gate; `graph-agents-cli infra check` reports a leftover placeholder).
6
+ # Branch protection on main must require code-owner review, dismiss stale
7
+ # approvals and prevent self-approval.
8
+ #
9
+ {%- if cookiecutter.deployment_target == 'kubernetes' %}
10
+ # Deployment: the chart, the shared and prod values and the Argo CD Applications.
11
+ /deployment/ @CHANGE-ME/production-approvers
12
+ # ...except the dev and staging values: the staging workflow's image-tag PR
13
+ # merges automatically once pr_checks passes (a line without owners leaves
14
+ # the file unowned, so ordinary review applies).
15
+ /deployment/helm/*/values-dev.yaml
16
+ /deployment/helm/*/values-staging.yaml
17
+ {%- endif %}
18
+ # CI/CD: the workflows, their settings (.github/agent.env) and this file.
19
+ /.github/ @CHANGE-ME/production-approvers
20
+ # The outbound API access policy the running agent enforces.
21
+ /api-policy.yaml @CHANGE-ME/production-approvers
22
+ # The eval gate's datasets and thresholds.
23
+ /tests/eval/ @CHANGE-ME/production-approvers
24
+ # Project extensions, which can replace CLI commands (including lint and eval),
25
+ # and the CLI's local state directory (gitignored; covered should it be committed).
26
+ /graph-agents-cli-extensions.yaml @CHANGE-ME/production-approvers
27
+ /extensions/ @CHANGE-ME/production-approvers
28
+ /.graph-agents-cli/ @CHANGE-ME/production-approvers
29
+ # Project settings the CLI reads for every command (runtime, CD mode, Secret keys).
30
+ /graph-agents-cli-manifest.yaml @CHANGE-ME/production-approvers
@@ -0,0 +1,7 @@
1
+ # Project settings for the GitHub workflows (which are copied verbatim, not
2
+ # rendered). Read as data, never sourced by a shell: one NAME=VALUE per line,
3
+ # no quoting needed even when a value contains spaces; lines starting with #
4
+ # are comments. Only known settings are accepted (the workflows refuse any
5
+ # other name, so this file cannot change how their steps run).
6
+ # Where the workflows install graph-agents-cli from (uvx --from "$GRAPH_AGENTS_CLI_SPEC").
7
+ GRAPH_AGENTS_CLI_SPEC={{cookiecutter.cli_install_spec}}
@@ -0,0 +1,214 @@
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
+ # CI for every pull request (make it a required status check on main): lint,
17
+ # unit and integration tests, the API-policy check, and the eval gate when a
18
+ # dataset exists. This file is copied verbatim (not rendered); project settings,
19
+ # including where graph-agents-cli is installed from (GRAPH_AGENTS_CLI_SPEC),
20
+ # come from .github/agent.env.
21
+ #
22
+ # Models: the tests always run against the deterministic fake model. The eval
23
+ # gate uses the project's real provider (create_params in
24
+ # graph-agents-cli-manifest.yaml) when that provider's key is a repository
25
+ # secret, or the MODEL_PROVIDER / MODEL_NAME repository variables when set;
26
+ # JUDGE_MODEL_PROVIDER / JUDGE_MODEL_NAME / JUDGE_BASE_URL variables and a
27
+ # JUDGE_API_KEY secret pick a separate judge. On the fake model the gate only
28
+ # checks the plumbing, and the run says so with a warning.
29
+ #
30
+ # The gate steps run the CLI's own `lint` and `eval run`: extensions (project
31
+ # or user scope) cannot override them here (GRAPH_AGENTS_CLI_DISABLE_OVERRIDES=1
32
+ # for the whole job).
33
+
34
+ name: pr_checks
35
+
36
+ on:
37
+ pull_request:
38
+ branches:
39
+ - main
40
+
41
+ jobs:
42
+ checks:
43
+ runs-on: ubuntu-latest
44
+ permissions:
45
+ contents: read
46
+ env:
47
+ MODEL_PROVIDER: fake
48
+ MODEL_NAME: fake
49
+ CHECKPOINTER: memory
50
+ AUTH_POLICY: shared-bearer
51
+ API_KEY: ci-test-key
52
+ GRAPH_AGENTS_CLI_API_KEY: ci-test-key
53
+ APP_ENV: ci
54
+ TRACING_ENABLED: "false"
55
+ GRAPH_AGENTS_CLI_NO_UPDATE_CHECK: "1"
56
+ # Every graph-agents-cli command of this job is the CLI's own: a project
57
+ # (or runner-wide) extension cannot replace the gate's lint or eval.
58
+ GRAPH_AGENTS_CLI_DISABLE_OVERRIDES: "1"
59
+ steps:
60
+ - name: Checkout code
61
+ uses: actions/checkout@v4
62
+
63
+ - name: Load project settings
64
+ run: |
65
+ # .github/agent.env is data and is never sourced: each NAME=VALUE line is
66
+ # checked and copied to GITHUB_ENV, so a value may hold spaces or shell
67
+ # metacharacters (a PEP 508 install spec, for example). Only the settings
68
+ # listed in `known` are accepted: any other name (BASH_ENV, SHELLOPTS, PS4,
69
+ # PATH, PYTHONPATH, ...) could change how later steps run. To add a setting,
70
+ # extend `known` in all three workflows. Comment and blank lines are skipped;
71
+ # blanks around the value, one pair of quotes around it and a trailing
72
+ # " # comment" are dropped (no escapes, no expansion). Nothing reaches
73
+ # GITHUB_ENV unless the whole file is valid.
74
+ file=.github/agent.env
75
+ known="IMAGE_REPOSITORY RELEASE_NAME CHART_PATH RUNTIME CD GRAPH_AGENTS_CLI_SPEC"
76
+ if [ ! -f "$file" ]; then
77
+ echo "::error file=$file::$file is missing: it holds the project settings these workflows read." >&2
78
+ exit 1
79
+ fi
80
+ lineno=0
81
+ seen=" "
82
+ settings=()
83
+ while IFS= read -r line || [ -n "$line" ]; do
84
+ lineno=$((lineno + 1))
85
+ line="${line%$'\r'}"
86
+ if [ "$lineno" -eq 1 ]; then
87
+ line="${line#$'\xef\xbb\xbf'}"
88
+ fi
89
+ if [[ "$line" =~ ^[[:space:]]*(#|$) ]]; then
90
+ continue
91
+ fi
92
+ if ! [[ "$line" =~ ^[[:space:]]*([A-Za-z_][A-Za-z0-9_]*)[[:space:]]*=(.*)$ ]]; then
93
+ echo "::error file=$file,line=$lineno::expected NAME=VALUE, got: $line" >&2
94
+ exit 1
95
+ fi
96
+ name="${BASH_REMATCH[1]}"
97
+ value="${BASH_REMATCH[2]}"
98
+ case " $known " in
99
+ *" $name "*) ;;
100
+ *)
101
+ hint=""
102
+ if [ "$name" = CLI_VERSION_PIN ]; then
103
+ hint=" (replaced by GRAPH_AGENTS_CLI_SPEC=<install spec>)"
104
+ fi
105
+ echo "::error file=$file,line=$lineno::$name is not a setting these workflows read${hint}; known: $known." >&2
106
+ exit 1
107
+ ;;
108
+ esac
109
+ case "$seen" in
110
+ *" $name "*)
111
+ echo "::error file=$file,line=$lineno::$name is set twice." >&2
112
+ exit 1
113
+ ;;
114
+ esac
115
+ seen="$seen$name "
116
+ value="${value#"${value%%[![:space:]]*}"}"
117
+ quote="${value:0:1}"
118
+ if [ "$quote" = '"' ] || [ "$quote" = "'" ]; then
119
+ rest="${value:1}"
120
+ if [[ "$rest" != *"$quote"* ]]; then
121
+ echo "::error file=$file,line=$lineno::$name: unterminated $quote quote." >&2
122
+ exit 1
123
+ fi
124
+ value="${rest%%"$quote"*}"
125
+ else
126
+ value="${value%%[[:space:]]#*}"
127
+ value="${value%"${value##*[![:space:]]}"}"
128
+ fi
129
+ if [[ "$value" == *[[:cntrl:]]* ]]; then
130
+ echo "::error file=$file,line=$lineno::$name: control characters are not allowed in a value." >&2
131
+ exit 1
132
+ fi
133
+ settings+=("$name=$value")
134
+ done < "$file"
135
+ if [ "${#settings[@]}" -gt 0 ]; then
136
+ printf '%s\n' "${settings[@]}" >> "$GITHUB_ENV"
137
+ fi
138
+
139
+ - name: Install uv
140
+ uses: astral-sh/setup-uv@v6
141
+ with:
142
+ python-version: "3.12"
143
+
144
+ - name: Install dependencies
145
+ run: uv sync --locked
146
+
147
+ - name: Lint (ruff)
148
+ run: uv run ruff check .
149
+
150
+ - name: Unit and integration tests
151
+ run: uv run pytest tests/unit tests/integration -q
152
+
153
+ - name: graph-agents-cli lint (code and API-policy check)
154
+ run: |
155
+ : "${GRAPH_AGENTS_CLI_SPEC:?GRAPH_AGENTS_CLI_SPEC is not set in .github/agent.env}"
156
+ uvx --from "$GRAPH_AGENTS_CLI_SPEC" graph-agents-cli lint
157
+
158
+ - name: Eval gate
159
+ env:
160
+ REPO_MODEL_PROVIDER: ${{ vars.MODEL_PROVIDER }}
161
+ REPO_MODEL_NAME: ${{ vars.MODEL_NAME }}
162
+ OPENAI_BASE_URL: ${{ vars.OPENAI_BASE_URL }}
163
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
164
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
165
+ GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
166
+ MODEL_API_KEY: ${{ secrets.MODEL_API_KEY }}
167
+ JUDGE_MODEL_PROVIDER: ${{ vars.JUDGE_MODEL_PROVIDER }}
168
+ JUDGE_MODEL_NAME: ${{ vars.JUDGE_MODEL_NAME }}
169
+ JUDGE_BASE_URL: ${{ vars.JUDGE_BASE_URL }}
170
+ JUDGE_API_KEY: ${{ secrets.JUDGE_API_KEY }}
171
+ run: |
172
+ : "${GRAPH_AGENTS_CLI_SPEC:?GRAPH_AGENTS_CLI_SPEC is not set in .github/agent.env}"
173
+ if ! ls tests/eval/datasets/*.json >/dev/null 2>&1; then
174
+ echo "No dataset under tests/eval/datasets; skipping the eval gate."
175
+ exit 0
176
+ fi
177
+ manifest=graph-agents-cli-manifest.yaml
178
+ project_provider="$(yq -r '.create_params.model_provider // ""' "$manifest")"
179
+ project_model="$(yq -r '.create_params.model // ""' "$manifest")"
180
+ provider="${REPO_MODEL_PROVIDER:-$project_provider}"
181
+ model="$REPO_MODEL_NAME"
182
+ if [ -z "$model" ] && [ "$provider" = "$project_provider" ]; then
183
+ model="$project_model"
184
+ fi
185
+ case "$provider" in
186
+ openai) key_var=OPENAI_API_KEY ;;
187
+ anthropic) key_var=ANTHROPIC_API_KEY ;;
188
+ gemini) key_var=GOOGLE_API_KEY ;;
189
+ openai-compatible) key_var=MODEL_API_KEY ;;
190
+ *) key_var="" ;;
191
+ esac
192
+ # A provider named by the repository variable is used as is (a local
193
+ # openai-compatible server may need no key); the project's own
194
+ # provider only when its key secret is present.
195
+ if [ "$provider" != fake ] && { [ -n "$REPO_MODEL_PROVIDER" ] || { [ -n "$key_var" ] && [ -n "${!key_var:-}" ]; }; }; then
196
+ if [ -z "$model" ]; then
197
+ echo "::error::Set the MODEL_NAME repository variable: MODEL_PROVIDER=$provider differs from the project's provider ($project_provider)." >&2
198
+ exit 1
199
+ fi
200
+ export MODEL_PROVIDER="$provider" MODEL_NAME="$model"
201
+ fi
202
+ judge="$(yq -r '.judge.provider // ""' tests/eval/eval_config.yaml 2>/dev/null || true)"
203
+ judge="${judge:-${JUDGE_MODEL_PROVIDER:-$MODEL_PROVIDER}}"
204
+ echo "Eval gate: agent model ${MODEL_PROVIDER}/${MODEL_NAME}, judge provider ${judge}."
205
+ if [ "$MODEL_PROVIDER" = fake ] || [ "$judge" = fake ]; then
206
+ message="The eval gate ran on the fake model (agent: ${MODEL_PROVIDER}, judge: ${judge}): it checks the plumbing, not answer quality. Add the ${key_var:-provider key} repository secret (or set the MODEL_PROVIDER / JUDGE_MODEL_PROVIDER variables) for a real quality gate."
207
+ echo "::warning title=Eval gate is not a quality signal::${message}"
208
+ {
209
+ echo "### :warning: Eval gate is not a quality signal"
210
+ echo
211
+ echo "$message"
212
+ } >> "$GITHUB_STEP_SUMMARY"
213
+ fi
214
+ uvx --from "$GRAPH_AGENTS_CLI_SPEC" graph-agents-cli eval run
@@ -0,0 +1,209 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyc
5
+ *$py.class
6
+ **/dist
7
+ /tmp
8
+ /out-tsc
9
+ /bazel-out
10
+
11
+ # C extensions
12
+ *.so
13
+
14
+ # Distribution / packaging
15
+ .Python
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
27
+ wheels/
28
+ pip-wheel-metadata/
29
+ share/python-wheels/
30
+ *.egg-info/
31
+ .installed.cfg
32
+ *.egg
33
+ MANIFEST
34
+
35
+ # PyInstaller
36
+ # Usually these files are written by a python script from a template
37
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
38
+ *.manifest
39
+ *.spec
40
+
41
+ # Installer logs
42
+ pip-log.txt
43
+ pip-delete-this-directory.txt
44
+
45
+ # Unit test / coverage reports
46
+ htmlcov/
47
+ .tox/
48
+ .nox/
49
+ .coverage
50
+ .coverage.*
51
+ .cache
52
+ nosetests.xml
53
+ coverage.xml
54
+ *.cover
55
+ *.py,cover
56
+ .hypothesis/
57
+ .pytest_cache/
58
+
59
+ # Translations
60
+ *.mo
61
+ *.pot
62
+
63
+ # Django stuff:
64
+ *.log
65
+ local_settings.py
66
+ db.sqlite3
67
+ db.sqlite3-journal
68
+
69
+ # Flask stuff:
70
+ instance/
71
+ .webassets-cache
72
+
73
+ # Scrapy stuff:
74
+ .scrapy
75
+
76
+ # Sphinx documentation
77
+ docs/_build/
78
+
79
+ # PyBuilder
80
+ target/
81
+
82
+ # IPython
83
+ profile_default/
84
+ ipython_config.py
85
+
86
+ # pyenv
87
+ .python-version
88
+
89
+ # pipenv
90
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
92
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
93
+ # install all needed dependencies.
94
+ Pipfile.lock
95
+ Pipfile
96
+
97
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
98
+ __pypackages__/
99
+
100
+ # Celery stuff
101
+ celerybeat-schedule
102
+ celerybeat.pid
103
+
104
+ # SageMath parsed files
105
+ *.sage.py
106
+
107
+ # Environments
108
+ .env
109
+ !.env.example
110
+ .venv
111
+ .venv*
112
+ env/
113
+ venv/
114
+ ENV/
115
+ env.bak/
116
+ venv.bak/
117
+
118
+ # Spyder project settings
119
+ .spyderproject
120
+ .spyproject
121
+
122
+ # Rope project settings
123
+ .ropeproject
124
+
125
+ # mkdocs documentation
126
+ /site
127
+
128
+ # mypy (legacy, kept for compatibility)
129
+ .mypy_cache/
130
+ .dmypy.json
131
+ dmypy.json
132
+
133
+ # ty (Astral's type checker)
134
+ .ty/
135
+
136
+ # Pyre type checker
137
+ .pyre/
138
+
139
+ # macOS
140
+ .DS_Store
141
+
142
+ # PyCharm
143
+ .idea
144
+
145
+ tmp*
146
+ .graph-agents-cli-scripts/
147
+
148
+ # Node
149
+ **/node_modules
150
+ npm-debug.log
151
+ yarn-error.log
152
+
153
+ # IDEs and editors
154
+ .idea/
155
+ .project
156
+ .classpath
157
+ .c9/
158
+ *.launch
159
+ .settings/
160
+ *.sublime-workspace
161
+
162
+ # Visual Studio Code
163
+ .vscode/*
164
+ !.vscode/settings.json
165
+ !.vscode/tasks.json
166
+ !.vscode/launch.json
167
+ !.vscode/extensions.json
168
+ .history/*
169
+
170
+ # Miscellaneous
171
+ **/.angular/*
172
+ /.angular/cache
173
+ .sass-cache/
174
+ /connect.lock
175
+ /coverage
176
+ /libpeerconnection.log
177
+ testem.log
178
+ /typings
179
+
180
+ # System files
181
+ .DS_Store
182
+ Thumbs.db
183
+ *.vscode*
184
+ # graph-agents-cli specific
185
+ artifacts/
186
+ .persist_vector_store
187
+ tests/load_test/.results/*.html
188
+ tests/load_test/.results/*.csv
189
+ .locust_env
190
+ .saved_chats
191
+ .env
192
+ .graph-agents-cli/
193
+ .env.*
194
+ !.env.example
195
+ # The local `langgraph dev` server's threads and the app's approvals (conversation content)
196
+ .langgraph_api/
197
+
198
+ # A2A Inspector
199
+ tools/a2a-inspector/
200
+
201
+ # Credentials and private keys
202
+ *.pem
203
+ *-key.json
204
+ credentials*.json
205
+
206
+ # Helm dependency downloads and their lock (rebuilt by `helm dependency build`, which
207
+ # `deploy` and the chart tests run; Chart.yaml pins the versions)
208
+ deployment/helm/*/charts/
209
+ deployment/helm/*/Chart.lock
@@ -0,0 +1,23 @@
1
+ # Copyright 2026 Google LLC
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
+ You can add your unit tests here.
16
+ This is where you test your business logic, including agent functionality,
17
+ data processing, and other core components of your application.
18
+ """
19
+
20
+
21
+ def test_dummy() -> None:
22
+ """Placeholder - replace with real tests."""
23
+ assert 1 == 1