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,124 @@
1
+ # LangChain models: `init_chat_model` and provider switching
2
+
3
+ The agent never names a provider in code. `app/app_utils/model.py` reads the environment and calls
4
+ `init_chat_model`; the same function builds the judge from `JUDGE_*`.
5
+
6
+ ## Provider table
7
+
8
+ | `MODEL_PROVIDER` | LangChain provider | Key variable | Extra variables | Notes |
9
+ |---|---|---|---|---|
10
+ | `openai` | `openai` | `OPENAI_API_KEY` | | default under `-y` |
11
+ | `anthropic` | `anthropic` | `ANTHROPIC_API_KEY` | | |
12
+ | `gemini` | `google_genai` | `GOOGLE_API_KEY` | | the AI Studio API-key path only |
13
+ | `openai-compatible` | `openai` with `base_url` | `MODEL_API_KEY` (sent as the OpenAI key) | `OPENAI_BASE_URL` | Ollama, vLLM, TGI, OpenRouter, any OpenAI-compatible server |
14
+ | `fake` | the template's deterministic `FakeChatModel` (`app/app_utils/model.py`) | none | | tests and CI only; never offered by `create`; replies depend only on the input (greeting, a request mentioning a bound tool -> a call of it, judge prompt -> JSON verdict) |
15
+
16
+ Default model names per provider are recorded by `create` in `.env` and the manifest
17
+ (`create_params.model`). They are placeholders to verify at release time; do not replace them
18
+ from memory.
19
+
20
+ ## `get_model()` shape (as `app/app_utils/model.py` implements it)
21
+
22
+ ```python
23
+ from langchain.chat_models import init_chat_model # imported lazily, inside build_model
24
+
25
+ PROVIDER_TO_LANGCHAIN = {
26
+ "openai": "openai",
27
+ "anthropic": "anthropic",
28
+ "gemini": "google_genai",
29
+ "openai-compatible": "openai",
30
+ }
31
+ PROVIDER_KEY_VARS = {
32
+ "openai": "OPENAI_API_KEY",
33
+ "anthropic": "ANTHROPIC_API_KEY",
34
+ "gemini": "GOOGLE_API_KEY",
35
+ "openai-compatible": "MODEL_API_KEY",
36
+ }
37
+
38
+
39
+ def model_settings(*, judge=False) -> dict:
40
+ # MODEL_PROVIDER (default "openai"), MODEL_NAME, OPENAI_BASE_URL, the provider's key variable;
41
+ # with judge=True each is overridden by JUDGE_MODEL_PROVIDER / JUDGE_MODEL_NAME / JUDGE_BASE_URL /
42
+ # JUDGE_API_KEY when set. Read at CALL time, so tests and the eval judge runner can set them late.
43
+ ...
44
+
45
+
46
+ def build_model(provider, name, *, base_url=None, api_key=None, **kwargs):
47
+ if provider == "fake":
48
+ return FakeChatModel(**kwargs)
49
+ # unknown provider -> ValueError; empty MODEL_NAME -> ValueError;
50
+ # openai-compatible without OPENAI_BASE_URL -> ValueError
51
+ return init_chat_model(
52
+ name, model_provider=PROVIDER_TO_LANGCHAIN[provider], api_key=..., base_url=..., **kwargs
53
+ )
54
+
55
+
56
+ def get_model(**kwargs): # the agent's model
57
+ return build_model(**model_settings(), **kwargs)
58
+
59
+
60
+ def get_judge_model(**kwargs): # the judge; JUDGE_* with the agent's values as defaults
61
+ return build_model(**model_settings(judge=True), **kwargs)
62
+
63
+
64
+ def model_label(*, judge=False) -> str: # "<provider>/<model>", recorded in run records and traces
65
+ ...
66
+ ```
67
+
68
+ `get_judge_model()` takes no provider or model arguments; `eval grade --judge-provider/--judge-model`
69
+ reach it through `JUDGE_MODEL_PROVIDER` / `JUDGE_MODEL_NAME` in the judge runner's environment.
70
+
71
+ ## OpenAI-API models: reasoning effort and the Responses API
72
+
73
+ For `openai` and `openai-compatible` only (set for another provider, the app refuses to start):
74
+
75
+ | Variable | Values | Effect |
76
+ |---|---|---|
77
+ | `MODEL_REASONING_EFFORT` | `none`, `minimal`, `low`, `medium`, `high`, `xhigh`; unset = the model's default | `reasoning_effort` on Chat Completions, `reasoning.effort` on the Responses API |
78
+ | `MODEL_USE_RESPONSES_API` | `true`, `false`; unset = langchain-openai chooses | `true`: every request to `/v1/responses`; `false`: `/v1/chat/completions` |
79
+
80
+ `build_model` passes them to `init_chat_model` as `reasoning_effort` and `use_responses_api`
81
+ (an explicit argument wins). Unset, langchain-openai uses Chat Completions except for the
82
+ models its own list says need the Responses API. A model that refuses function tools with a
83
+ reasoning effort on Chat Completions fails its first call with a 400 naming `/v1/responses`:
84
+ set `MODEL_USE_RESPONSES_API=true` (or `MODEL_REASONING_EFFORT=none`). Keep it `false` or unset
85
+ for an OpenAI-compatible server without `/v1/responses`. The judge reads
86
+ `JUDGE_REASONING_EFFORT` / `JUDGE_USE_RESPONSES_API`, defaulting to the agent's when the judge
87
+ is an OpenAI-API model too. Tools, streaming and token usage work on both APIs.
88
+
89
+ ## Switching providers
90
+
91
+ Edit `.env` (locally) and the chart `env:` plus the Secret (deployed):
92
+
93
+ ```bash
94
+ # hosted -> on-network vLLM
95
+ MODEL_PROVIDER=openai-compatible
96
+ MODEL_NAME=Qwen/Qwen2.5-14B-Instruct
97
+ OPENAI_BASE_URL=http://vllm.models.svc:8000/v1
98
+ MODEL_API_KEY=none
99
+ ```
100
+
101
+ Then update the manifest's `secrets.keys` if the provider key variable changed (the allow-list
102
+ names the variable `secrets apply` exports), and re-run `secrets apply` and `deploy --restart`.
103
+ `scaffold enhance` can rewrite `create_params.model_provider` and the allow-list for you.
104
+
105
+ ## Tool calling on open models
106
+
107
+ `create_agent` and `ToolNode` depend on native function calling. Use Llama 3.1+, Qwen 2.5+, or
108
+ Mistral families served with tool-call parsing enabled (vLLM: `--enable-auto-tool-choice
109
+ --tool-call-parser <parser>`; Ollama: a model tagged with tools). Small or older models loop or
110
+ emit malformed calls; the eval gate (`expect.tool_calls`) catches this.
111
+
112
+ ## Judge model
113
+
114
+ The judge is a chat model like any other, built from `JUDGE_MODEL_PROVIDER`, `JUDGE_MODEL_NAME`,
115
+ `JUDGE_BASE_URL`, and `JUDGE_API_KEY`, defaulting to the agent's configuration. In the
116
+ disconnected profile it points at an on-network OpenAI-compatible server, possibly the same one.
117
+ `eval_config.yaml` `judge: {provider, model}` overrides the environment for a run.
118
+
119
+ ## Egress
120
+
121
+ Selecting a hosted provider sends prompts, tool results, and any context the agent assembles to
122
+ that provider. That is a policy decision the consuming project makes explicitly (and publishes a
123
+ privacy notice for) before connecting a hosted model. Local hosting alone does not make data local
124
+ if traces or evals are exported elsewhere; see `/graph-agents-cli-observability`.
@@ -0,0 +1,235 @@
1
+ # LangGraph patterns used by the template
2
+
3
+ Patterns below are the ones the template and its tests rely on. For anything else, fetch the
4
+ upstream LangGraph docs; do not guess API names from memory.
5
+
6
+ ## `create_agent` (default)
7
+
8
+ ```python
9
+ from langchain.agents import create_agent
10
+ from app.app_utils.model import get_model
11
+ from app.tools import TOOLS
12
+
13
+ graph = create_agent(model=get_model(), tools=TOOLS, system_prompt=SYSTEM_PROMPT)
14
+ ```
15
+
16
+ A ReAct loop: model -> tool calls -> tool node -> model until no tool call remains. State is
17
+ `MessagesState` (`{"messages": [...]}`). Unbound; the app binds the checkpointer.
18
+
19
+ ## Explicit `StateGraph`
20
+
21
+ ```python
22
+ from typing import Annotated, TypedDict
23
+ from langchain_core.messages import AnyMessage
24
+ from langgraph.graph import StateGraph, START, END, MessagesState, add_messages
25
+ from langgraph.prebuilt import ToolNode, tools_condition
26
+
27
+
28
+ class State(MessagesState):
29
+ site_id: str | None # extra keys beside messages
30
+
31
+
32
+ def call_model(state: State):
33
+ model = get_model().bind_tools(TOOLS)
34
+ return {"messages": [model.invoke([SystemMessage(SYSTEM_PROMPT), *state["messages"]])]}
35
+
36
+
37
+ builder = StateGraph(State)
38
+ builder.add_node("model", call_model)
39
+ builder.add_node("tools", ToolNode(TOOLS))
40
+ builder.add_edge(START, "model")
41
+ builder.add_conditional_edges("model", tools_condition, {"tools": "tools", END: END})
42
+ builder.add_edge("tools", "model")
43
+
44
+ graph = builder.compile() # still unbound
45
+ ```
46
+
47
+ Use an explicit graph for fixed stages (classify -> retrieve -> answer), branching by state, or a
48
+ human-approval node. Keep the export `graph`.
49
+
50
+ ## Tools
51
+
52
+ ```python
53
+ from langchain_core.tools import tool
54
+
55
+ API_CALLS = [
56
+ {"api": "sites", "method": "GET", "operation_id": "getSite", "path": "/sites/{site_id}"},
57
+ {"api": "sites", "method": "PATCH", "operation_id": "renameSite", "path": "/sites/{site_id}"},
58
+ ]
59
+
60
+
61
+ @tool
62
+ async def get_site(site_id: str) -> str:
63
+ """Return the site record for SITE_ID."""
64
+ ...
65
+ ```
66
+
67
+ - The docstring is the model's description of the tool; write it for the model.
68
+ - Typed parameters become the schema; keep them simple (str, int, bool, small models).
69
+ - Return strings or JSON-serialisable data; long payloads bloat the context and the trace.
70
+ - Tools that call an external API use `get_client("<api>")` from `app_utils.api_client` and
71
+ declare `API_CALLS`.
72
+ - Tools that need the caller's identity read it from the run context the app sets
73
+ (`runtime: ToolRuntime[Any]` parameter, `runtime.context`: `principal_id`, `roles`,
74
+ `attributes`; or `current_caller(runtime.context)` from `app_utils.api_client`); never from a
75
+ global. Parameterise `ToolRuntime`: the bare form makes pydantic warn with the run context
76
+ (which may hold credentials) on every call.
77
+ - Tool results are untrusted data: write tools act only on ids the user named
78
+ (`require_user_mentioned`) and on the caller's own records (`require_owner`); see section 2a
79
+ of the skill.
80
+
81
+ ## Checkpointers and `thread_id`
82
+
83
+ The app (not `agent.py`) does:
84
+
85
+ ```python
86
+ # app/app_utils/checkpointer.py
87
+ def get_checkpointer():
88
+ if os.environ.get("CHECKPOINTER", "memory") == "postgres":
89
+ from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
90
+
91
+ saver = AsyncPostgresSaver.from_conn_string(os.environ["POSTGRES_DSN"])
92
+ await saver.setup()
93
+ return saver
94
+ from langgraph.checkpoint.memory import InMemorySaver
95
+
96
+ return InMemorySaver()
97
+
98
+
99
+ # app/fast_api_app.py
100
+ runnable = graph.with_config(...) # or graph rebuilt with checkpointer=get_checkpointer()
101
+ config = {"configurable": {"thread_id": thread_id, "principal": principal}}
102
+ ```
103
+
104
+ - `thread_id` selects the checkpoint namespace; each `/chat` call on the same id continues the
105
+ conversation.
106
+ - Under `memory`, state lives only in the process. Under `postgres`, it survives restarts and is
107
+ shared across replicas.
108
+ - Under `langgraph-server`, the server creates and persists threads from `DATABASE_URI`; the app's
109
+ `/chat` route uses the server's thread.
110
+
111
+ ## Streaming
112
+
113
+ ```python
114
+ async for event in runnable.astream_events(
115
+ {"messages": [HumanMessage(text)]}, config, version="v2"
116
+ ):
117
+ kind = event["event"]
118
+ if kind == "on_chat_model_stream":
119
+ yield sse("message.delta", {"text": event["data"]["chunk"].content})
120
+ elif kind == "on_tool_start":
121
+ yield sse(
122
+ "tool.call",
123
+ {"id": event["run_id"], "name": event["name"], "args": event["data"].get("input")},
124
+ )
125
+ elif kind == "on_tool_end":
126
+ yield sse(
127
+ "tool.result",
128
+ {
129
+ "id": event["run_id"],
130
+ "name": event["name"],
131
+ "result": str(event["data"].get("output")),
132
+ "is_error": False,
133
+ },
134
+ )
135
+ ```
136
+
137
+ The app applies `TRACE_CAPTURE` before emitting `args` and `result` to a non-owner. Nodes should
138
+ not `print` or log prompt text; the telemetry layer handles capture.
139
+
140
+ ## Human-in-the-loop (interrupts)
141
+
142
+ For API calls, use the policy's approval gate: `graph-agents-cli api approval NAME ...` makes the
143
+ API client itself call `interrupt()` before a gated call, `/chat` ends with `message.end` status
144
+ `awaiting_approval`, and `POST /threads/{thread_id}/approvals/{approval_id}` resumes the run (see
145
+ SKILL.md section 5). Nothing in the graph changes.
146
+
147
+ The general LangGraph pattern is below for reference. **The scaffolded chat API does not expose
148
+ your own interrupts:** there is no status for a graph paused elsewhere and no `metadata.resume`
149
+ request convention, so a node that calls `interrupt()` outside the API client stalls the `/chat`
150
+ stream. Use such interrupts only under `playground --graph` (LangGraph Studio).
151
+
152
+ ```python
153
+ from langgraph.types import interrupt, Command
154
+
155
+
156
+ def confirm_action(state: State):
157
+ decision = interrupt(
158
+ {"question": "Approve closing incident?", "incident_id": state["incident_id"]}
159
+ )
160
+ if decision != "approve":
161
+ return {"messages": [AIMessage("Cancelled.")]}
162
+ return {"approved": True}
163
+ ```
164
+
165
+ - Requires a checkpointer (any); the thread pauses at the interrupt and is resumed with
166
+ `graph.invoke(Command(resume="approve"), config)` on the same `thread_id`. On resume the
167
+ interrupted node runs again from its start (`interrupt()` then returns the resume value), so
168
+ the code before it must be safe to repeat.
169
+ - Not wired to `/chat` outside the API client's approval gate: the app does not report such a
170
+ paused graph and does not translate a request `metadata.resume` into `Command(resume=...)`. Adding that is a scaffolding change to
171
+ `app/app_utils/chat.py` and `fast_api_app.py`, which `upgrade` 3-way merges; ask before doing it.
172
+ - `interrupt_before=["tools"]` at compile time pauses before every tool call; same caveat.
173
+
174
+ ## Subgraphs
175
+
176
+ ```python
177
+ sub = StateGraph(SubState)
178
+ ...
179
+ sub_graph = sub.compile() # unbound
180
+
181
+
182
+ def run_sub(state: State):
183
+ result = sub_graph.invoke({"query": state["messages"][-1].content})
184
+ return {"messages": [AIMessage(result["answer"])]}
185
+
186
+
187
+ builder.add_node(
188
+ "research", run_sub
189
+ ) # or builder.add_node("research", sub_graph) when schemas share keys
190
+ ```
191
+
192
+ Subgraphs inherit the parent's checkpointer and `thread_id`; interrupts inside a subgraph surface
193
+ through the parent.
194
+
195
+ ## Testing with the `fake` provider
196
+
197
+ ```python
198
+ # tests/unit/conftest.py
199
+ import pytest
200
+
201
+
202
+ @pytest.fixture(autouse=True)
203
+ def fake_model(monkeypatch):
204
+ monkeypatch.setenv("MODEL_PROVIDER", "fake")
205
+ monkeypatch.setenv("MODEL_NAME", "fake")
206
+ monkeypatch.setenv("CHECKPOINTER", "memory")
207
+ monkeypatch.setenv("AUTH_POLICY", "shared-bearer")
208
+ monkeypatch.setenv("API_KEY", "test-key")
209
+ ```
210
+
211
+ `get_model()` returns the template's deterministic `FakeChatModel` (`app/app_utils/model.py`):
212
+ `hi` -> `Hello! How can I help you today?`; a request that mentions a bound tool (its name, or a
213
+ distinctive word of it: `What is the weather in Paris?` with `get_weather` bound) -> a call of that
214
+ tool with every required argument filled (text arguments get the request's subject, `Paris`), then
215
+ `Here is what I found: <tool result>`; a prompt mentioning "score" and "json" -> the JSON judge
216
+ verdict `{"score": 5, ...}`; anything else -> `I am a fake model. I can use these tools: ... You
217
+ said: <text>`. There is no scripted-response list or `FAKE_MODEL_RESPONSES` variable. The
218
+ template's `tests/conftest.py` keeps `.env` and the shell's app settings out of the tests and
219
+ offers `use_test_tools(tool, ...)`, which serves the graph with test-only tools, so plumbing tests
220
+ never depend on the project's own tools. Use it to test:
221
+
222
+ - the SSE mapping (`/chat` returns `message.start`, deltas, `tool.call`/`tool.result`,
223
+ `message.end`);
224
+ - tool routing (with a test-only tool) and the middleware turning `ApiPolicyError` / `ApiCallError`
225
+ into a tool error;
226
+ - policy enforcement (401 without the bearer, 403 on a foreign thread under a per-user policy
227
+ such as `jwt` or an implemented `custom`).
228
+
229
+ Never test model behaviour here; that is `graph-agents-cli eval`.
230
+
231
+ ## Prompts and graph modules
232
+
233
+ `app/prompts/**` and `app/graph/**` are reserved agent-code directories: `upgrade` never touches
234
+ them. Put system prompts in `app/prompts/` as Python constants or text files loaded at import;
235
+ put a large explicit graph in `app/graph/` and import it from `agent.py`.