agent-starter-pack 0.3.3__py3-none-any.whl → 0.21.0__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 (255) hide show
  1. agent_starter_pack/agents/README.md +7 -0
  2. agents/langgraph_base_react/template/.templateconfig.yaml → agent_starter_pack/agents/adk_a2a_base/.template/templateconfig.yaml +5 -10
  3. agent_starter_pack/agents/adk_a2a_base/README.md +37 -0
  4. src/deployment_targets/cloud_run/Dockerfile → agent_starter_pack/agents/adk_a2a_base/app/__init__.py +2 -14
  5. agent_starter_pack/agents/adk_a2a_base/app/agent.py +70 -0
  6. agent_starter_pack/agents/adk_a2a_base/notebooks/adk_a2a_app_testing.ipynb +583 -0
  7. agents/crewai_coding_crew/notebooks/evaluating_crewai_agent.ipynb → agent_starter_pack/agents/adk_a2a_base/notebooks/evaluating_adk_agent.ipynb +163 -199
  8. {agents/adk_base → agent_starter_pack/agents/adk_a2a_base}/tests/integration/test_agent.py +2 -2
  9. agents/adk_base/template/.templateconfig.yaml → agent_starter_pack/agents/adk_base/.template/templateconfig.yaml +4 -1
  10. {agents → agent_starter_pack/agents}/adk_base/README.md +1 -1
  11. agent_starter_pack/agents/adk_base/app/__init__.py +17 -0
  12. {agents → agent_starter_pack/agents}/adk_base/app/agent.py +5 -2
  13. {agents → agent_starter_pack/agents}/adk_base/notebooks/adk_app_testing.ipynb +128 -82
  14. agents/langgraph_base_react/notebooks/evaluating_langgraph_agent.ipynb → agent_starter_pack/agents/adk_base/notebooks/evaluating_adk_agent.ipynb +181 -207
  15. agent_starter_pack/agents/adk_base/tests/integration/test_agent.py +58 -0
  16. agents/crewai_coding_crew/template/.templateconfig.yaml → agent_starter_pack/agents/adk_live/.template/templateconfig.yaml +5 -9
  17. agent_starter_pack/agents/adk_live/README.md +32 -0
  18. agent_starter_pack/agents/adk_live/app/__init__.py +17 -0
  19. agent_starter_pack/agents/adk_live/app/agent.py +51 -0
  20. agent_starter_pack/agents/adk_live/tests/unit/test_dummy.py +38 -0
  21. agents/agentic_rag/template/.templateconfig.yaml → agent_starter_pack/agents/agentic_rag/.template/templateconfig.yaml +7 -3
  22. {agents → agent_starter_pack/agents}/agentic_rag/README.md +1 -1
  23. agent_starter_pack/agents/agentic_rag/app/__init__.py +17 -0
  24. {agents → agent_starter_pack/agents}/agentic_rag/app/agent.py +8 -4
  25. {agents → agent_starter_pack/agents}/agentic_rag/notebooks/adk_app_testing.ipynb +128 -82
  26. agent_starter_pack/agents/agentic_rag/notebooks/evaluating_adk_agent.ipynb +1535 -0
  27. {agents → agent_starter_pack/agents}/agentic_rag/tests/integration/test_agent.py +3 -3
  28. agent_starter_pack/agents/langgraph_base/.template/templateconfig.yaml +31 -0
  29. agent_starter_pack/agents/langgraph_base/README.md +30 -0
  30. agent_starter_pack/agents/langgraph_base/app/__init__.py +17 -0
  31. agent_starter_pack/agents/langgraph_base/app/agent.py +34 -0
  32. {agents/crewai_coding_crew → agent_starter_pack/agents/langgraph_base}/notebooks/evaluating_langgraph_agent.ipynb +30 -17
  33. {agents/langgraph_base_react → agent_starter_pack/agents/langgraph_base}/tests/integration/test_agent.py +2 -2
  34. {src → agent_starter_pack}/base_template/.gitignore +5 -3
  35. agent_starter_pack/base_template/GEMINI.md +5 -0
  36. agent_starter_pack/base_template/Makefile +339 -0
  37. agent_starter_pack/base_template/README.md +267 -0
  38. agent_starter_pack/base_template/deployment/README.md +11 -0
  39. {src → agent_starter_pack}/base_template/deployment/terraform/apis.tf +2 -2
  40. {src → agent_starter_pack}/base_template/deployment/terraform/dev/apis.tf +6 -1
  41. {src → agent_starter_pack}/base_template/deployment/terraform/dev/iam.tf +12 -11
  42. {src → agent_starter_pack}/base_template/deployment/terraform/dev/providers.tf +5 -1
  43. {src → agent_starter_pack}/base_template/deployment/terraform/dev/storage.tf +1 -1
  44. {src → agent_starter_pack}/base_template/deployment/terraform/dev/variables.tf +10 -10
  45. agent_starter_pack/base_template/deployment/terraform/dev/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +193 -0
  46. agent_starter_pack/base_template/deployment/terraform/github.tf +337 -0
  47. {src → agent_starter_pack}/base_template/deployment/terraform/iam.tf +20 -41
  48. {src → agent_starter_pack}/base_template/deployment/terraform/locals.tf +10 -3
  49. {src/resources/setup_cicd → agent_starter_pack/base_template/deployment/terraform}/providers.tf +8 -1
  50. {src → agent_starter_pack}/base_template/deployment/terraform/service_accounts.tf +7 -8
  51. agent_starter_pack/base_template/deployment/terraform/sql/completions.sql +138 -0
  52. {src → agent_starter_pack}/base_template/deployment/terraform/storage.tf +7 -16
  53. {src → agent_starter_pack}/base_template/deployment/terraform/variables.tf +61 -28
  54. {src → agent_starter_pack}/base_template/deployment/terraform/vars/env.tfvars +6 -1
  55. agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'github_actions' %}wif.tf{% else %}unused_wif.tf{% endif %} +43 -0
  56. src/base_template/deployment/terraform/build_triggers.tf → agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}build_triggers.tf{% else %}unused_build_triggers.tf{% endif %} +55 -38
  57. agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +206 -0
  58. {src → agent_starter_pack}/base_template/pyproject.toml +24 -37
  59. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/deploy-to-prod.yaml +132 -0
  60. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/pr_checks.yaml +65 -0
  61. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/staging.yaml +259 -0
  62. src/base_template/deployment/cd/deploy-to-prod.yaml → agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/deploy-to-prod.yaml +38 -30
  63. src/base_template/deployment/ci/pr_checks.yaml → agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/pr_checks.yaml +5 -5
  64. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/staging.yaml +322 -0
  65. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/telemetry.py +96 -0
  66. {src/base_template/app/utils → agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils}/typing.py +7 -9
  67. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}converters{% else %}unused_converters{% endif %}/__init__.py +25 -0
  68. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}converters{% else %}unused_converters{% endif %}/part_converter.py +138 -0
  69. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/__init__.py +13 -0
  70. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/a2a_agent_executor.py +265 -0
  71. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/task_result_aggregator.py +152 -0
  72. agent_starter_pack/cli/commands/create.py +1256 -0
  73. agent_starter_pack/cli/commands/enhance.py +611 -0
  74. agent_starter_pack/cli/commands/list.py +203 -0
  75. agent_starter_pack/cli/commands/register_gemini_enterprise.py +1070 -0
  76. agent_starter_pack/cli/commands/setup_cicd.py +862 -0
  77. {src → agent_starter_pack}/cli/main.py +10 -2
  78. {src → agent_starter_pack}/cli/utils/cicd.py +139 -48
  79. agent_starter_pack/cli/utils/gcp.py +263 -0
  80. agent_starter_pack/cli/utils/logging.py +103 -0
  81. agent_starter_pack/cli/utils/remote_template.py +677 -0
  82. agent_starter_pack/cli/utils/template.py +1466 -0
  83. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/components/process_data.py +1 -1
  84. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/submit_pipeline.py +20 -6
  85. {src → agent_starter_pack}/data_ingestion/pyproject.toml +1 -0
  86. {src → agent_starter_pack}/data_ingestion/uv.lock +602 -494
  87. agent_starter_pack/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +484 -0
  88. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/README.md +84 -0
  89. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/load_test.py +424 -0
  90. agent_starter_pack/deployment_targets/agent_engine/tests/{% if cookiecutter.is_a2a %}helpers.py{% else %}unused_helpers.py{% endif %} +138 -0
  91. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/agent_engine_app.py +263 -0
  92. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/app_utils/deploy.py +414 -0
  93. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_adk_live %}expose_app.py{% else %}unused_expose_app.py{% endif %} +519 -0
  94. agent_starter_pack/deployment_targets/cloud_run/Dockerfile +51 -0
  95. agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/dev/service.tf +243 -0
  96. agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/service.tf +417 -0
  97. agent_starter_pack/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +705 -0
  98. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +321 -0
  99. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/README.md +165 -0
  100. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/load_test.py +329 -0
  101. agent_starter_pack/deployment_targets/cloud_run/{{cookiecutter.agent_directory}}/fast_api_app.py +556 -0
  102. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/package-lock.json +79 -1044
  103. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/package.json +1 -9
  104. agent_starter_pack/frontends/adk_live_react/frontend/src/App.tsx +65 -0
  105. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/Logger.tsx +8 -3
  106. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/logger.scss +26 -0
  107. agent_starter_pack/frontends/adk_live_react/frontend/src/components/side-panel/SidePanel.tsx +516 -0
  108. agent_starter_pack/frontends/adk_live_react/frontend/src/components/side-panel/side-panel.scss +563 -0
  109. agent_starter_pack/frontends/adk_live_react/frontend/src/components/transcription-preview/TranscriptionPreview.tsx +106 -0
  110. agent_starter_pack/frontends/adk_live_react/frontend/src/components/transcription-preview/transcription-preview.scss +150 -0
  111. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-live-api.ts +8 -2
  112. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/multimodal-live-types.ts +40 -2
  113. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audio-recorder.ts +1 -1
  114. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audio-streamer.ts +1 -1
  115. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/multimodal-live-client.ts +210 -24
  116. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/utils.ts +27 -5
  117. agent_starter_pack/resources/docs/adk-cheatsheet.md +1628 -0
  118. agent_starter_pack/resources/locks/uv-adk_a2a_base-agent_engine.lock +4966 -0
  119. agent_starter_pack/resources/locks/uv-adk_a2a_base-cloud_run.lock +5011 -0
  120. agent_starter_pack/resources/locks/uv-adk_base-agent_engine.lock +4946 -0
  121. agent_starter_pack/resources/locks/uv-adk_base-cloud_run.lock +4991 -0
  122. agent_starter_pack/resources/locks/uv-adk_live-agent_engine.lock +4963 -0
  123. agent_starter_pack/resources/locks/uv-adk_live-cloud_run.lock +5006 -0
  124. agent_starter_pack/resources/locks/uv-agentic_rag-agent_engine.lock +5487 -0
  125. agent_starter_pack/resources/locks/uv-agentic_rag-cloud_run.lock +5532 -0
  126. agent_starter_pack/resources/locks/uv-langgraph_base-agent_engine.lock +5788 -0
  127. agent_starter_pack/resources/locks/uv-langgraph_base-cloud_run.lock +5811 -0
  128. {src → agent_starter_pack}/utils/generate_locks.py +15 -12
  129. {src → agent_starter_pack}/utils/lock_utils.py +4 -7
  130. {src → agent_starter_pack}/utils/watch_and_rebuild.py +2 -2
  131. agent_starter_pack-0.21.0.dist-info/METADATA +182 -0
  132. agent_starter_pack-0.21.0.dist-info/RECORD +171 -0
  133. agent_starter_pack-0.21.0.dist-info/entry_points.txt +2 -0
  134. llm.txt +362 -0
  135. agent_starter_pack-0.3.3.dist-info/METADATA +0 -164
  136. agent_starter_pack-0.3.3.dist-info/RECORD +0 -176
  137. agent_starter_pack-0.3.3.dist-info/entry_points.txt +0 -2
  138. agents/crewai_coding_crew/README.md +0 -34
  139. agents/crewai_coding_crew/app/agent.py +0 -86
  140. agents/crewai_coding_crew/app/crew/config/agents.yaml +0 -39
  141. agents/crewai_coding_crew/app/crew/config/tasks.yaml +0 -37
  142. agents/crewai_coding_crew/app/crew/crew.py +0 -71
  143. agents/crewai_coding_crew/tests/integration/test_agent.py +0 -47
  144. agents/langgraph_base_react/README.md +0 -9
  145. agents/langgraph_base_react/app/agent.py +0 -73
  146. agents/live_api/README.md +0 -37
  147. agents/live_api/app/agent.py +0 -78
  148. agents/live_api/app/server.py +0 -196
  149. agents/live_api/app/templates.py +0 -51
  150. agents/live_api/app/vector_store.py +0 -55
  151. agents/live_api/template/.templateconfig.yaml +0 -29
  152. agents/live_api/tests/integration/test_server_e2e.py +0 -254
  153. agents/live_api/tests/load_test/load_test.py +0 -40
  154. agents/live_api/tests/unit/test_server.py +0 -143
  155. src/base_template/Makefile +0 -72
  156. src/base_template/README.md +0 -208
  157. src/base_template/app/__init__.py +0 -3
  158. src/base_template/app/utils/tracing.py +0 -155
  159. src/base_template/deployment/README.md +0 -126
  160. src/base_template/deployment/cd/staging.yaml +0 -216
  161. src/base_template/deployment/terraform/dev/log_sinks.tf +0 -63
  162. src/base_template/deployment/terraform/log_sinks.tf +0 -70
  163. src/base_template/deployment/terraform/providers.tf +0 -37
  164. src/cli/commands/create.py +0 -664
  165. src/cli/commands/setup_cicd.py +0 -829
  166. src/cli/utils/gcp.py +0 -117
  167. src/cli/utils/logging.py +0 -51
  168. src/cli/utils/template.py +0 -737
  169. src/deployment_targets/agent_engine/app/agent_engine_app.py +0 -336
  170. src/deployment_targets/agent_engine/notebooks/intro_agent_engine.ipynb +0 -1025
  171. src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +0 -183
  172. src/deployment_targets/agent_engine/tests/load_test/README.md +0 -42
  173. src/deployment_targets/agent_engine/tests/load_test/load_test.py +0 -107
  174. src/deployment_targets/cloud_run/app/server.py +0 -154
  175. src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +0 -249
  176. src/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +0 -0
  177. src/deployment_targets/cloud_run/tests/load_test/README.md +0 -83
  178. src/deployment_targets/cloud_run/tests/load_test/load_test.py +0 -118
  179. src/deployment_targets/cloud_run/uv.lock +0 -6952
  180. src/frontends/live_api_react/frontend/src/App.tsx +0 -205
  181. src/frontends/live_api_react/frontend/src/components/control-tray/ControlTray.tsx +0 -217
  182. src/frontends/live_api_react/frontend/src/components/control-tray/control-tray.scss +0 -201
  183. src/frontends/live_api_react/frontend/src/components/side-panel/SidePanel.tsx +0 -161
  184. src/frontends/live_api_react/frontend/src/components/side-panel/side-panel.scss +0 -285
  185. src/frontends/streamlit/frontend/side_bar.py +0 -214
  186. src/frontends/streamlit/frontend/streamlit_app.py +0 -265
  187. src/frontends/streamlit/frontend/style/app_markdown.py +0 -37
  188. src/frontends/streamlit/frontend/utils/chat_utils.py +0 -67
  189. src/frontends/streamlit/frontend/utils/local_chat_history.py +0 -125
  190. src/frontends/streamlit/frontend/utils/message_editing.py +0 -59
  191. src/frontends/streamlit/frontend/utils/multimodal_utils.py +0 -217
  192. src/frontends/streamlit/frontend/utils/stream_handler.py +0 -301
  193. src/frontends/streamlit/frontend/utils/title_summary.py +0 -94
  194. src/frontends/streamlit_adk/frontend/side_bar.py +0 -214
  195. src/frontends/streamlit_adk/frontend/streamlit_app.py +0 -314
  196. src/frontends/streamlit_adk/frontend/style/app_markdown.py +0 -37
  197. src/frontends/streamlit_adk/frontend/utils/chat_utils.py +0 -84
  198. src/frontends/streamlit_adk/frontend/utils/local_chat_history.py +0 -110
  199. src/frontends/streamlit_adk/frontend/utils/message_editing.py +0 -61
  200. src/frontends/streamlit_adk/frontend/utils/multimodal_utils.py +0 -223
  201. src/frontends/streamlit_adk/frontend/utils/stream_handler.py +0 -311
  202. src/frontends/streamlit_adk/frontend/utils/title_summary.py +0 -129
  203. src/resources/containers/data_processing/Dockerfile +0 -27
  204. src/resources/containers/e2e-tests/Dockerfile +0 -19
  205. src/resources/idx/.idx/dev.nix +0 -57
  206. src/resources/idx/idx-template.json +0 -21
  207. src/resources/idx/idx-template.nix +0 -26
  208. src/resources/locks/uv-adk_base-agent_engine.lock +0 -5338
  209. src/resources/locks/uv-adk_base-cloud_run.lock +0 -5930
  210. src/resources/locks/uv-agentic_rag-agent_engine.lock +0 -5528
  211. src/resources/locks/uv-agentic_rag-cloud_run.lock +0 -6120
  212. src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +0 -6231
  213. src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +0 -6839
  214. src/resources/locks/uv-langgraph_base_react-agent_engine.lock +0 -5233
  215. src/resources/locks/uv-langgraph_base_react-cloud_run.lock +0 -5862
  216. src/resources/locks/uv-live_api-cloud_run.lock +0 -5832
  217. src/resources/setup_cicd/cicd_variables.tf +0 -41
  218. src/resources/setup_cicd/github.tf +0 -87
  219. {agents → agent_starter_pack/agents}/agentic_rag/app/retrievers.py +0 -0
  220. {agents → agent_starter_pack/agents}/agentic_rag/app/templates.py +0 -0
  221. {src → agent_starter_pack}/base_template/deployment/terraform/dev/vars/env.tfvars +0 -0
  222. {src → agent_starter_pack}/base_template/tests/unit/test_dummy.py +0 -0
  223. {src/deployment_targets/agent_engine/app/utils → agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils}/gcs.py +0 -0
  224. {src → agent_starter_pack}/cli/utils/__init__.py +0 -0
  225. {src → agent_starter_pack}/cli/utils/datastores.py +0 -0
  226. {src → agent_starter_pack}/cli/utils/version.py +0 -0
  227. {src → agent_starter_pack}/data_ingestion/README.md +0 -0
  228. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/components/ingest_data.py +0 -0
  229. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/pipeline.py +0 -0
  230. {src → agent_starter_pack}/deployment_targets/agent_engine/deployment_metadata.json +0 -0
  231. {src → agent_starter_pack}/deployment_targets/agent_engine/tests/load_test/.results/.placeholder +0 -0
  232. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/favicon.ico +0 -0
  233. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/index.html +0 -0
  234. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/robots.txt +0 -0
  235. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/App.scss +0 -0
  236. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/App.test.tsx +0 -0
  237. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/audio-pulse/AudioPulse.tsx +0 -0
  238. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/audio-pulse/audio-pulse.scss +0 -0
  239. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/mock-logs.ts +0 -0
  240. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/contexts/LiveAPIContext.tsx +0 -0
  241. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-media-stream-mux.ts +0 -0
  242. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-screen-capture.ts +0 -0
  243. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-webcam.ts +0 -0
  244. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/index.css +0 -0
  245. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/index.tsx +0 -0
  246. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/react-app-env.d.ts +0 -0
  247. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/reportWebVitals.ts +0 -0
  248. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/setupTests.ts +0 -0
  249. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audioworklet-registry.ts +0 -0
  250. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/store-logger.ts +0 -0
  251. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/worklets/audio-processing.ts +0 -0
  252. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/worklets/vol-meter.ts +0 -0
  253. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/tsconfig.json +0 -0
  254. {agent_starter_pack-0.3.3.dist-info → agent_starter_pack-0.21.0.dist-info}/WHEEL +0 -0
  255. {agent_starter_pack-0.3.3.dist-info → agent_starter_pack-0.21.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,583 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# 🧪 ADK with A2A Application Testing\n",
8
+ "\n",
9
+ "This notebook demonstrates how to test an ADK (Agent Development Kit) application that implements the Agent2Agent (A2A) protocol.\n",
10
+ "It covers both local and remote testing, both with Agent Engine and Cloud Run."
11
+ ]
12
+ },
13
+ {
14
+ "cell_type": "markdown",
15
+ "metadata": {},
16
+ "source": [
17
+ "## Set Up Your Environment\n",
18
+ "\n",
19
+ "> **Note:** For best results, use the same `.venv` created for local development with `uv` to ensure dependency compatibility and avoid environment-related issues."
20
+ ]
21
+ },
22
+ {
23
+ "cell_type": "code",
24
+ "execution_count": null,
25
+ "metadata": {},
26
+ "outputs": [],
27
+ "source": [
28
+ "# Uncomment the following lines if you're not using the virtual environment created by uv\n",
29
+ "# import sys\n",
30
+ "\n",
31
+ "# sys.path.append(\"../\")\n",
32
+ "# !pip install google-cloud-aiplatform a2a-sdk --upgrade"
33
+ ]
34
+ },
35
+ {
36
+ "cell_type": "markdown",
37
+ "metadata": {},
38
+ "source": [
39
+ "### Import libraries"
40
+ ]
41
+ },
42
+ {
43
+ "cell_type": "code",
44
+ "execution_count": null,
45
+ "metadata": {},
46
+ "outputs": [],
47
+ "source": [
48
+ "# ruff: noqa\n",
49
+ "import asyncio\n",
50
+ "import json\n",
51
+ "import os\n",
52
+ "import requests\n",
53
+ "import uuid\n",
54
+ "\n",
55
+ "import vertexai\n",
56
+ "from a2a.types import (\n",
57
+ " Message,\n",
58
+ " MessageSendParams,\n",
59
+ " Part,\n",
60
+ " Role,\n",
61
+ " SendStreamingMessageRequest,\n",
62
+ " TextPart,\n",
63
+ ")\n",
64
+ "from IPython.display import Markdown, display\n",
65
+ "from google.adk.artifacts import InMemoryArtifactService\n",
66
+ "from google.adk.sessions import InMemorySessionService\n",
67
+ "\n",
68
+ "from app.agent_engine_app import AgentEngineApp\n",
69
+ "from tests.helpers import (\n",
70
+ " build_get_request,\n",
71
+ " build_post_request,\n",
72
+ " poll_task_completion,\n",
73
+ ")"
74
+ ]
75
+ },
76
+ {
77
+ "cell_type": "markdown",
78
+ "metadata": {},
79
+ "source": [
80
+ "### Initialize Vertex AI Client"
81
+ ]
82
+ },
83
+ {
84
+ "cell_type": "code",
85
+ "execution_count": null,
86
+ "metadata": {},
87
+ "outputs": [],
88
+ "source": [
89
+ "# Initialize the Vertex AI client\n",
90
+ "LOCATION = \"us-central1\"\n",
91
+ "\n",
92
+ "client = vertexai.Client(\n",
93
+ " location=LOCATION,\n",
94
+ ")"
95
+ ]
96
+ },
97
+ {
98
+ "cell_type": "markdown",
99
+ "metadata": {},
100
+ "source": [
101
+ "## If you are using Agent Engine\n",
102
+ "See more documentation at [Agent Engine Overview](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview)"
103
+ ]
104
+ },
105
+ {
106
+ "cell_type": "markdown",
107
+ "metadata": {},
108
+ "source": [
109
+ "### Remote Testing"
110
+ ]
111
+ },
112
+ {
113
+ "cell_type": "code",
114
+ "execution_count": null,
115
+ "metadata": {},
116
+ "outputs": [],
117
+ "source": [
118
+ "# Set to None to auto-detect from ./deployment_metadata.json, or specify manually\n",
119
+ "# \"projects/PROJECT_ID/locations/us-central1/reasoningEngines/ENGINE_ID\"\n",
120
+ "REASONING_ENGINE_ID = None\n",
121
+ "\n",
122
+ "if REASONING_ENGINE_ID is None:\n",
123
+ " try:\n",
124
+ " with open(\"../deployment_metadata.json\") as f:\n",
125
+ " metadata = json.load(f)\n",
126
+ " REASONING_ENGINE_ID = metadata.get(\"remote_agent_engine_id\")\n",
127
+ " except (FileNotFoundError, json.JSONDecodeError):\n",
128
+ " pass\n",
129
+ "\n",
130
+ "print(f\"Using REASONING_ENGINE_ID: {REASONING_ENGINE_ID}\")\n",
131
+ "\n",
132
+ "# Extract project_id, location, and engine_id from REASONING_ENGINE_ID\n",
133
+ "parts = REASONING_ENGINE_ID.split(\"/\")\n",
134
+ "project_id = parts[1]\n",
135
+ "location = parts[3]\n",
136
+ "engine_id = parts[5]\n",
137
+ "\n",
138
+ "# Construct API endpoints\n",
139
+ "base_url = f\"https://{location}-aiplatform.googleapis.com\"\n",
140
+ "a2a_base_path = f\"/v1beta1/projects/{project_id}/locations/{location}/reasoningEngines/{engine_id}/a2a/v1\"\n",
141
+ "\n",
142
+ "print(f\"Base URL: {base_url}\")\n",
143
+ "print(f\"A2A base path: {a2a_base_path}\")"
144
+ ]
145
+ },
146
+ {
147
+ "cell_type": "markdown",
148
+ "metadata": {},
149
+ "source": [
150
+ "#### Fetch Agent Card"
151
+ ]
152
+ },
153
+ {
154
+ "cell_type": "code",
155
+ "execution_count": null,
156
+ "metadata": {},
157
+ "outputs": [],
158
+ "source": [
159
+ "# Fetch agent card using REST API\n",
160
+ "import google.auth\n",
161
+ "import google.auth.transport.requests\n",
162
+ "\n",
163
+ "# Get authentication token\n",
164
+ "creds, project = google.auth.default()\n",
165
+ "auth_req = google.auth.transport.requests.Request()\n",
166
+ "creds.refresh(auth_req)\n",
167
+ "\n",
168
+ "headers = {\"Content-Type\": \"application/json\", \"Authorization\": f\"Bearer {creds.token}\"}\n",
169
+ "\n",
170
+ "# GET request to fetch agent card\n",
171
+ "response = requests.get(\n",
172
+ " f\"{base_url}{a2a_base_path}/card\",\n",
173
+ " headers=headers,\n",
174
+ ")\n",
175
+ "\n",
176
+ "print(f\"Response status code: {response.status_code}\")\n",
177
+ "\n",
178
+ "if response.status_code == 200:\n",
179
+ " remote_a2a_agent_card = response.json()\n",
180
+ " print(f\"Agent: {remote_a2a_agent_card.get('name')}\")\n",
181
+ " print(f\"URL: {remote_a2a_agent_card.get('url')}\")\n",
182
+ " print(\n",
183
+ " f\"Skills: {[s.get('description') for s in remote_a2a_agent_card.get('skills', [])]}\"\n",
184
+ " )\n",
185
+ " print(f\"Protocol Version: {remote_a2a_agent_card.get('protocolVersion')}\")\n",
186
+ "else:\n",
187
+ " print(f\"Error: {response.text}\")"
188
+ ]
189
+ },
190
+ {
191
+ "cell_type": "markdown",
192
+ "metadata": {},
193
+ "source": [
194
+ "#### Send Message"
195
+ ]
196
+ },
197
+ {
198
+ "cell_type": "code",
199
+ "execution_count": null,
200
+ "metadata": {},
201
+ "outputs": [],
202
+ "source": [
203
+ "# Send the message using A2A REST API\n",
204
+ "import google.auth\n",
205
+ "import google.auth.transport.requests\n",
206
+ "\n",
207
+ "# Get authentication token\n",
208
+ "creds, project = google.auth.default()\n",
209
+ "auth_req = google.auth.transport.requests.Request()\n",
210
+ "creds.refresh(auth_req)\n",
211
+ "\n",
212
+ "headers = {\"Content-Type\": \"application/json\", \"Authorization\": f\"Bearer {creds.token}\"}\n",
213
+ "\n",
214
+ "data = {\n",
215
+ " \"message\": {\n",
216
+ " \"messageId\": f\"msg-{os.urandom(8).hex()}\",\n",
217
+ " \"content\": [{\"text\": \"What is the weather in New York?\"}],\n",
218
+ " \"role\": \"ROLE_USER\",\n",
219
+ " }\n",
220
+ "}\n",
221
+ "\n",
222
+ "# Send POST request to message:send endpoint\n",
223
+ "response = requests.post(\n",
224
+ " f\"{base_url}{a2a_base_path}/message:send\",\n",
225
+ " headers=headers,\n",
226
+ " json=data,\n",
227
+ ")\n",
228
+ "\n",
229
+ "print(f\"Response status code: {response.status_code}\")\n",
230
+ "\n",
231
+ "if response.status_code == 200:\n",
232
+ " response_data = response.json()\n",
233
+ " task_id = response_data[\"task\"][\"id\"]\n",
234
+ " print(f\"Task started: {task_id}\")\n",
235
+ "else:\n",
236
+ " print(f\"Error: {response.text}\")"
237
+ ]
238
+ },
239
+ {
240
+ "cell_type": "markdown",
241
+ "metadata": {},
242
+ "source": [
243
+ "#### Poll for response"
244
+ ]
245
+ },
246
+ {
247
+ "cell_type": "code",
248
+ "execution_count": null,
249
+ "metadata": {},
250
+ "outputs": [],
251
+ "source": [
252
+ "# Poll for task completion using REST API\n",
253
+ "max_attempts = 30\n",
254
+ "for attempt in range(max_attempts):\n",
255
+ " poll_response = requests.get(\n",
256
+ " f\"{base_url}{a2a_base_path}/tasks/{task_id}\",\n",
257
+ " headers=headers,\n",
258
+ " )\n",
259
+ "\n",
260
+ " if poll_response.status_code != 200:\n",
261
+ " print(f\"Poll failed with status code: {poll_response.status_code}\")\n",
262
+ " break\n",
263
+ "\n",
264
+ " result = poll_response.json()\n",
265
+ " task_state = result.get(\"status\", {}).get(\"state\")\n",
266
+ " print(f\"Attempt {attempt + 1}: {task_state}\")\n",
267
+ "\n",
268
+ " if task_state == \"TASK_STATE_COMPLETED\":\n",
269
+ " print(\"Task completed!\")\n",
270
+ " break\n",
271
+ " elif task_state in [\"TASK_STATE_FAILED\", \"TASK_STATE_CANCELLED\"]:\n",
272
+ " print(f\"Task failed: {result}\")\n",
273
+ " break\n",
274
+ "\n",
275
+ " await asyncio.sleep(1)\n",
276
+ "\n",
277
+ "# Extract and display artifacts\n",
278
+ "if \"artifacts\" in result and result[\"artifacts\"]:\n",
279
+ " for artifact in result[\"artifacts\"]:\n",
280
+ " if artifact.get(\"parts\"):\n",
281
+ " for part in artifact[\"parts\"]:\n",
282
+ " if \"text\" in part:\n",
283
+ " display(Markdown(f\"**Answer**:\\\\n {part['text']}\"))\n",
284
+ " else:\n",
285
+ " print(\"Could not extract text from artifact parts.\")\n",
286
+ "else:\n",
287
+ " print(\"No artifacts found in result\")"
288
+ ]
289
+ },
290
+ {
291
+ "cell_type": "markdown",
292
+ "metadata": {},
293
+ "source": [
294
+ "### Local Testing\n",
295
+ "\n",
296
+ "You can import directly the AgentEngineApp class within your environment. \n",
297
+ "To run the agent locally, follow these steps:\n",
298
+ "1. Make sure all required packages are installed in your environment\n",
299
+ "2. The recommended approach is to use the same virtual environment created by the 'uv' tool\n",
300
+ "3. You can set up this environment by running 'make install' from your agent's root directory\n",
301
+ "4. Then select this kernel (.venv folder in your project) in your Jupyter notebook to ensure all dependencies are available"
302
+ ]
303
+ },
304
+ {
305
+ "cell_type": "code",
306
+ "execution_count": null,
307
+ "metadata": {},
308
+ "outputs": [],
309
+ "source": [
310
+ "from app.agent_engine_app import agent_engine\n",
311
+ "\n",
312
+ "agent_engine.set_up()"
313
+ ]
314
+ },
315
+ {
316
+ "cell_type": "markdown",
317
+ "metadata": {},
318
+ "source": [
319
+ "#### Verify Custom Method is Registered"
320
+ ]
321
+ },
322
+ {
323
+ "cell_type": "code",
324
+ "execution_count": null,
325
+ "metadata": {},
326
+ "outputs": [],
327
+ "source": [
328
+ "test = agent_engine.register_operations()\n",
329
+ "print(test)"
330
+ ]
331
+ },
332
+ {
333
+ "cell_type": "markdown",
334
+ "metadata": {},
335
+ "source": [
336
+ "#### Fetch Agent Card"
337
+ ]
338
+ },
339
+ {
340
+ "cell_type": "code",
341
+ "execution_count": null,
342
+ "metadata": {},
343
+ "outputs": [],
344
+ "source": [
345
+ "request = build_get_request(None)\n",
346
+ "response = await agent_engine.handle_authenticated_agent_card(\n",
347
+ " request=request, context=None\n",
348
+ ")\n",
349
+ "print(response)"
350
+ ]
351
+ },
352
+ {
353
+ "cell_type": "markdown",
354
+ "metadata": {},
355
+ "source": [
356
+ "#### Send Message"
357
+ ]
358
+ },
359
+ {
360
+ "cell_type": "code",
361
+ "execution_count": null,
362
+ "metadata": {},
363
+ "outputs": [],
364
+ "source": [
365
+ "message_data = {\n",
366
+ " \"message\": {\n",
367
+ " \"messageId\": f\"msg-{os.urandom(8).hex()}\",\n",
368
+ " \"content\": [{\"text\": \"What is the weather in New York?\"}],\n",
369
+ " \"role\": \"ROLE_USER\",\n",
370
+ " },\n",
371
+ "}\n",
372
+ "\n",
373
+ "request = build_post_request(message_data)\n",
374
+ "\n",
375
+ "response = await agent_engine.on_message_send(request=request, context=None)\n",
376
+ "print(response)"
377
+ ]
378
+ },
379
+ {
380
+ "cell_type": "markdown",
381
+ "metadata": {},
382
+ "source": [
383
+ "#### Poll for response"
384
+ ]
385
+ },
386
+ {
387
+ "cell_type": "code",
388
+ "execution_count": null,
389
+ "metadata": {},
390
+ "outputs": [],
391
+ "source": [
392
+ "task_id = response[\"task\"][\"id\"]\n",
393
+ "print(f\"The Task ID is: {task_id}\")\n",
394
+ "\n",
395
+ "# Poll for completion using helper\n",
396
+ "final_response = await poll_task_completion(agent_engine, task_id)\n",
397
+ "\n",
398
+ "# Extract and display artifacts\n",
399
+ "for artifact in final_response[\"artifacts\"]:\n",
400
+ " if artifact[\"parts\"] and \"text\" in artifact[\"parts\"][0]:\n",
401
+ " display(Markdown(f\"**Answer**:\\n {artifact['parts'][0]['text']}\"))\n",
402
+ " else:\n",
403
+ " print(\"Could not extract text from artifact parts.\")"
404
+ ]
405
+ },
406
+ {
407
+ "cell_type": "markdown",
408
+ "metadata": {},
409
+ "source": [
410
+ "#### Register Feedback"
411
+ ]
412
+ },
413
+ {
414
+ "cell_type": "code",
415
+ "execution_count": null,
416
+ "metadata": {},
417
+ "outputs": [],
418
+ "source": "agent_engine.register_feedback(\n feedback={\n \"score\": 5,\n \"text\": \"Great response!\",\n \"user_id\": \"test-user-123\",\n \"session_id\": \"test-session-123\",\n }\n)"
419
+ },
420
+ {
421
+ "cell_type": "markdown",
422
+ "metadata": {},
423
+ "source": [
424
+ "## If you are using Cloud Run"
425
+ ]
426
+ },
427
+ {
428
+ "cell_type": "markdown",
429
+ "metadata": {},
430
+ "source": [
431
+ "### Remote Testing\n",
432
+ "\n",
433
+ "For more information about authenticating HTTPS requests to Cloud Run services, see:\n",
434
+ "[Cloud Run Authentication Documentation](https://cloud.google.com/run/docs/triggering/https-request)\n",
435
+ "\n",
436
+ "Remote testing involves using a deployed service URL instead of localhost.\n",
437
+ "\n",
438
+ "Authentication is handled using GCP identity tokens instead of local credentials."
439
+ ]
440
+ },
441
+ {
442
+ "cell_type": "code",
443
+ "execution_count": null,
444
+ "metadata": {},
445
+ "outputs": [],
446
+ "source": [
447
+ "ID_TOKEN = get_ipython().getoutput(\"gcloud auth print-identity-token -q\")[0]"
448
+ ]
449
+ },
450
+ {
451
+ "cell_type": "code",
452
+ "execution_count": null,
453
+ "metadata": {},
454
+ "outputs": [],
455
+ "source": [
456
+ "SERVICE_URL = \"YOUR_SERVICE_URL_HERE\" # Replace with your Cloud Run service URL"
457
+ ]
458
+ },
459
+ {
460
+ "cell_type": "markdown",
461
+ "metadata": {},
462
+ "source": [
463
+ "Send a message using A2A protocol"
464
+ ]
465
+ },
466
+ {
467
+ "cell_type": "code",
468
+ "execution_count": null,
469
+ "metadata": {},
470
+ "outputs": [],
471
+ "source": [
472
+ "# Create A2A message request\n",
473
+ "message = Message(\n",
474
+ " message_id=f\"msg-user-{uuid.uuid4()}\",\n",
475
+ " role=Role.user,\n",
476
+ " parts=[Part(root=TextPart(text=\"Hello! Weather in New York?\"))],\n",
477
+ ")\n",
478
+ "\n",
479
+ "request = SendStreamingMessageRequest(\n",
480
+ " id=f\"req-{uuid.uuid4()}\",\n",
481
+ " params=MessageSendParams(message=message),\n",
482
+ ")\n",
483
+ "\n",
484
+ "# Set up headers with authentication\n",
485
+ "headers = {\"Content-Type\": \"application/json\", \"Authorization\": f\"Bearer {ID_TOKEN}\"}\n",
486
+ "\n",
487
+ "# Send the streaming request to the A2A endpoint\n",
488
+ "response = requests.post(\n",
489
+ " f\"{SERVICE_URL}/a2a/app\",\n",
490
+ " headers=headers,\n",
491
+ " json=request.model_dump(mode=\"json\", exclude_none=True),\n",
492
+ " stream=True,\n",
493
+ " timeout=60,\n",
494
+ ")\n",
495
+ "\n",
496
+ "print(f\"Response status code: {response.status_code}\")\n",
497
+ "\n",
498
+ "# Parse streaming A2A responses\n",
499
+ "for line in response.iter_lines():\n",
500
+ " if line:\n",
501
+ " line_str = line.decode(\"utf-8\")\n",
502
+ " if line_str.startswith(\"data: \"):\n",
503
+ " event_json = line_str[6:]\n",
504
+ " event = json.loads(event_json)\n",
505
+ " print(f\"Received event: {event}\")"
506
+ ]
507
+ },
508
+ {
509
+ "cell_type": "markdown",
510
+ "metadata": {},
511
+ "source": [
512
+ "### Local Testing\n",
513
+ "\n",
514
+ "> You can run the application locally via the `make local-backend` command.\n",
515
+ "\n",
516
+ "Send a message to the local backend service using the A2A protocol and receive a streaming response."
517
+ ]
518
+ },
519
+ {
520
+ "cell_type": "code",
521
+ "execution_count": null,
522
+ "metadata": {},
523
+ "outputs": [],
524
+ "source": [
525
+ "# Create A2A message request\n",
526
+ "message = Message(\n",
527
+ " message_id=f\"msg-user-{uuid.uuid4()}\",\n",
528
+ " role=Role.user,\n",
529
+ " parts=[Part(root=TextPart(text=\"Hello! Weather in New York?\"))],\n",
530
+ ")\n",
531
+ "\n",
532
+ "request = SendStreamingMessageRequest(\n",
533
+ " id=f\"req-{uuid.uuid4()}\",\n",
534
+ " params=MessageSendParams(message=message),\n",
535
+ ")\n",
536
+ "\n",
537
+ "# Set up headers\n",
538
+ "headers = {\"Content-Type\": \"application/json\"}\n",
539
+ "\n",
540
+ "# Send the streaming request to the local A2A endpoint\n",
541
+ "response = requests.post(\n",
542
+ " \"http://127.0.0.1:8000/a2a/app\",\n",
543
+ " headers=headers,\n",
544
+ " json=request.model_dump(mode=\"json\", exclude_none=True),\n",
545
+ " stream=True,\n",
546
+ " timeout=60,\n",
547
+ ")\n",
548
+ "\n",
549
+ "print(f\"Response status code: {response.status_code}\")\n",
550
+ "\n",
551
+ "# Parse streaming A2A responses\n",
552
+ "for line in response.iter_lines():\n",
553
+ " if line:\n",
554
+ " line_str = line.decode(\"utf-8\")\n",
555
+ " if line_str.startswith(\"data: \"):\n",
556
+ " event_json = line_str[6:]\n",
557
+ " event = json.loads(event_json)\n",
558
+ " print(f\"Received event: {event}\")"
559
+ ]
560
+ }
561
+ ],
562
+ "metadata": {
563
+ "kernelspec": {
564
+ "display_name": "myagent-1761660603",
565
+ "language": "python",
566
+ "name": "python3"
567
+ },
568
+ "language_info": {
569
+ "codemirror_mode": {
570
+ "name": "ipython",
571
+ "version": 3
572
+ },
573
+ "file_extension": ".py",
574
+ "mimetype": "text/x-python",
575
+ "name": "python",
576
+ "nbconvert_exporter": "python",
577
+ "pygments_lexer": "ipython3",
578
+ "version": "3.12.9"
579
+ }
580
+ },
581
+ "nbformat": 4,
582
+ "nbformat_minor": 2
583
+ }