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,138 @@
1
+ # Copyright 2025 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
+ # http://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
+ """Converters between A2A Parts and LangChain message content."""
16
+
17
+ from __future__ import annotations
18
+
19
+ import logging
20
+ from typing import Any
21
+
22
+ from a2a.types import FilePart, FileWithBytes, FileWithUri, Part, TextPart
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ LangChainContent = str | list[str | dict[str, Any]]
28
+ LangChainContentDict = dict[str, Any]
29
+
30
+
31
+ def convert_a2a_part_to_langchain_content(part: Part) -> LangChainContentDict | str:
32
+ """Convert an A2A Part to LangChain message content format."""
33
+
34
+ root = part.root
35
+
36
+ if isinstance(root, TextPart):
37
+ return {"type": "text", "text": root.text}
38
+
39
+ elif isinstance(root, FilePart):
40
+ file_data = root.file
41
+ mime_type = file_data.mime_type if hasattr(file_data, "mime_type") else None
42
+
43
+ # Determine media type from mime_type
44
+ media_type = "image" # default
45
+ if mime_type:
46
+ if mime_type.startswith("audio/"):
47
+ media_type = "audio"
48
+ elif mime_type.startswith("video/"):
49
+ media_type = "video"
50
+
51
+ if isinstance(file_data, FileWithUri):
52
+ return {"type": media_type, "url": file_data.uri}
53
+ else:
54
+ # Base64 data should already be encoded
55
+ return {
56
+ "type": media_type,
57
+ "base64": file_data.bytes,
58
+ "mime_type": mime_type or "application/octet-stream",
59
+ }
60
+
61
+ else:
62
+ import json
63
+
64
+ data_str = json.dumps(root.data, indent=2)
65
+ return {"type": "text", "text": f"[Structured Data]\n{data_str}"}
66
+
67
+
68
+ def convert_langchain_content_to_a2a_part(content: Any) -> Part:
69
+ """Convert LangChain message content to an A2A Part."""
70
+
71
+ if isinstance(content, str):
72
+ return Part(root=TextPart(text=content))
73
+
74
+ if isinstance(content, dict):
75
+ content_type = content.get("type")
76
+
77
+ if content_type == "text":
78
+ text = content.get("text", "")
79
+ return Part(root=TextPart(text=text))
80
+
81
+ elif content_type in ("image", "audio", "video"):
82
+ # Handle URL-based media
83
+ if "url" in content:
84
+ return Part(root=FilePart(file=FileWithUri(uri=content["url"])))
85
+
86
+ # Handle base64-encoded media
87
+ elif "base64" in content:
88
+ mime_type = content.get("mime_type")
89
+ return Part(
90
+ root=FilePart(
91
+ file=FileWithBytes(bytes=content["base64"], mime_type=mime_type)
92
+ )
93
+ )
94
+
95
+ # Handle file_id-based media
96
+ elif "file_id" in content:
97
+ return Part(
98
+ root=FilePart(file=FileWithUri(uri=f"file://{content['file_id']}"))
99
+ )
100
+
101
+ else:
102
+ import json
103
+
104
+ text = json.dumps(content)
105
+ logger.warning(f"Unknown content type '{content_type}', converting to text")
106
+ return Part(root=TextPart(text=text))
107
+
108
+ logger.warning(f"Unknown content type: {type(content)}, converting to text")
109
+ return Part(root=TextPart(text=str(content)))
110
+
111
+
112
+ def convert_a2a_parts_to_langchain_content(parts: list[Part]) -> LangChainContent:
113
+ """Convert a list of A2A Parts to LangChain message content."""
114
+
115
+ if not parts:
116
+ return ""
117
+
118
+ converted: list[str | dict[str, Any]] = []
119
+ for part in parts:
120
+ result = convert_a2a_part_to_langchain_content(part)
121
+ converted.append(result)
122
+
123
+ if len(converted) == 1 and isinstance(converted[0], str):
124
+ return converted[0]
125
+
126
+ return converted
127
+
128
+
129
+ def convert_langchain_content_to_a2a_parts(content: LangChainContent) -> list[Part]:
130
+ """Convert LangChain message content to a list of A2A Parts."""
131
+
132
+ if isinstance(content, str):
133
+ return [Part(root=TextPart(text=content))]
134
+
135
+ result: list[Part] = []
136
+ for item in content:
137
+ result.append(convert_langchain_content_to_a2a_part(item))
138
+ return result
@@ -0,0 +1,13 @@
1
+ # Copyright 2025 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
+ # http://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.
@@ -0,0 +1,265 @@
1
+ # Copyright 2025 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
+ # http://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
+ from __future__ import annotations
16
+
17
+ import logging
18
+ import uuid
19
+ from datetime import datetime, timezone
20
+
21
+ from a2a.server.agent_execution import AgentExecutor, RequestContext
22
+ from a2a.server.events import EventQueue
23
+ from a2a.types import (
24
+ Artifact,
25
+ Message,
26
+ Part,
27
+ Role,
28
+ TaskArtifactUpdateEvent,
29
+ TaskState,
30
+ TaskStatus,
31
+ TaskStatusUpdateEvent,
32
+ TextPart,
33
+ UnsupportedOperationError,
34
+ )
35
+ from a2a.utils.errors import ServerError
36
+ from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
37
+ from langgraph.graph.state import CompiledStateGraph
38
+ from pydantic import BaseModel
39
+ from typing_extensions import override
40
+
41
+ from ..converters import (
42
+ convert_a2a_parts_to_langchain_content,
43
+ convert_langchain_content_to_a2a_parts,
44
+ )
45
+ from .task_result_aggregator import LangGraphTaskResultAggregator
46
+
47
+ logging.basicConfig(level=logging.INFO)
48
+ logger = logging.getLogger(__name__)
49
+
50
+
51
+ class LangGraphAgentExecutorConfig(BaseModel):
52
+ """Configuration for the LangGraphAgentExecutor."""
53
+
54
+ enable_streaming: bool = True
55
+
56
+
57
+ class LangGraphAgentExecutor(AgentExecutor):
58
+ """An AgentExecutor that runs a LangGraph agent against an A2A request and
59
+ publishes updates to an event queue."""
60
+
61
+ def __init__(
62
+ self,
63
+ *,
64
+ graph: CompiledStateGraph,
65
+ config: LangGraphAgentExecutorConfig | None = None,
66
+ ):
67
+ super().__init__()
68
+ self._graph = graph
69
+ self._config = config or LangGraphAgentExecutorConfig()
70
+
71
+ @override
72
+ async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
73
+ """Cancel the execution."""
74
+ # TODO: Implement proper cancellation logic if needed
75
+ raise ServerError(error=UnsupportedOperationError())
76
+
77
+ @override
78
+ async def execute(
79
+ self,
80
+ context: RequestContext,
81
+ event_queue: EventQueue,
82
+ ) -> None:
83
+ """Executes an A2A request and publishes updates to the event queue."""
84
+
85
+ if not context.message:
86
+ raise ValueError("A2A request must have a message")
87
+
88
+ if not context.task_id:
89
+ raise ValueError("task_id is required")
90
+ if not context.context_id:
91
+ raise ValueError("context_id is required")
92
+
93
+ task_id = context.task_id
94
+ context_id = context.context_id
95
+
96
+ if not context.current_task:
97
+ await event_queue.enqueue_event(
98
+ TaskStatusUpdateEvent(
99
+ task_id=task_id,
100
+ status=TaskStatus(
101
+ state=TaskState.submitted,
102
+ message=context.message,
103
+ timestamp=datetime.now(timezone.utc).isoformat(),
104
+ ),
105
+ context_id=context_id,
106
+ final=False,
107
+ )
108
+ )
109
+
110
+ try:
111
+ await self._handle_request(context, event_queue)
112
+ except Exception as e:
113
+ logger.error("Error handling A2A request: %s", e, exc_info=True)
114
+ try:
115
+ await event_queue.enqueue_event(
116
+ TaskStatusUpdateEvent(
117
+ task_id=task_id,
118
+ status=TaskStatus(
119
+ state=TaskState.failed,
120
+ timestamp=datetime.now(timezone.utc).isoformat(),
121
+ message=Message(
122
+ message_id=str(uuid.uuid4()),
123
+ role=Role.agent,
124
+ parts=[Part(root=TextPart(text=str(e)))],
125
+ ),
126
+ ),
127
+ context_id=context_id,
128
+ final=True,
129
+ )
130
+ )
131
+ except Exception as enqueue_error:
132
+ logger.error(
133
+ "Failed to publish failure event: %s", enqueue_error, exc_info=True
134
+ )
135
+
136
+ async def _handle_request(
137
+ self,
138
+ context: RequestContext,
139
+ event_queue: EventQueue,
140
+ ) -> None:
141
+ """Handle the A2A request and publish events."""
142
+
143
+ graph = self._graph
144
+
145
+ if not context.task_id:
146
+ raise ValueError("task_id is required")
147
+ if not context.context_id:
148
+ raise ValueError("context_id is required")
149
+
150
+ task_id = context.task_id
151
+ context_id = context.context_id
152
+
153
+ await event_queue.enqueue_event(
154
+ TaskStatusUpdateEvent(
155
+ task_id=task_id,
156
+ status=TaskStatus(
157
+ state=TaskState.working,
158
+ timestamp=datetime.now(timezone.utc).isoformat(),
159
+ ),
160
+ context_id=context_id,
161
+ final=False,
162
+ )
163
+ )
164
+
165
+ # Convert A2A message parts to LangChain content
166
+ message_content = (
167
+ convert_a2a_parts_to_langchain_content(context.message.parts)
168
+ if context.message
169
+ else ""
170
+ )
171
+ messages = [HumanMessage(content=message_content)]
172
+ input_dict = {"messages": messages}
173
+
174
+ task_result_aggregator = LangGraphTaskResultAggregator()
175
+
176
+ try:
177
+ if self._config.enable_streaming:
178
+ async for chunk in graph.astream(input_dict, stream_mode="messages"):
179
+ if isinstance(chunk, tuple) and len(chunk) > 0:
180
+ message = chunk[0]
181
+
182
+ # Process AIMessage chunks
183
+ if isinstance(message, AIMessage) and message.content:
184
+ task_result_aggregator.process_message(message)
185
+
186
+ parts = convert_langchain_content_to_a2a_parts(
187
+ message.content
188
+ )
189
+ await event_queue.enqueue_event(
190
+ TaskStatusUpdateEvent(
191
+ task_id=task_id,
192
+ status=TaskStatus(
193
+ state=TaskState.working,
194
+ timestamp=datetime.now(
195
+ timezone.utc
196
+ ).isoformat(),
197
+ message=Message(
198
+ message_id=str(uuid.uuid4()),
199
+ role=Role.agent,
200
+ parts=parts,
201
+ ),
202
+ ),
203
+ context_id=context_id,
204
+ final=False,
205
+ )
206
+ )
207
+
208
+ # Process ToolMessage chunks (for multimodal content)
209
+ elif isinstance(message, ToolMessage):
210
+ task_result_aggregator.process_message(message)
211
+ else:
212
+ result = await graph.ainvoke(input_dict)
213
+ if "messages" in result:
214
+ for msg in result["messages"]:
215
+ if isinstance(msg, (AIMessage, ToolMessage)) and msg.content:
216
+ task_result_aggregator.process_message(msg)
217
+ if (
218
+ task_result_aggregator.task_state == TaskState.working
219
+ and task_result_aggregator.task_status_message is not None
220
+ and task_result_aggregator.task_status_message.parts
221
+ ):
222
+ # Publish the artifact update event as the final result
223
+ await event_queue.enqueue_event(
224
+ TaskArtifactUpdateEvent(
225
+ task_id=task_id,
226
+ last_chunk=True,
227
+ context_id=context_id,
228
+ artifact=Artifact(
229
+ artifact_id=str(uuid.uuid4()),
230
+ parts=task_result_aggregator.get_final_parts(),
231
+ ),
232
+ )
233
+ )
234
+ # Publish the final status update event
235
+ await event_queue.enqueue_event(
236
+ TaskStatusUpdateEvent(
237
+ task_id=task_id,
238
+ status=TaskStatus(
239
+ state=TaskState.completed,
240
+ timestamp=datetime.now(timezone.utc).isoformat(),
241
+ ),
242
+ context_id=context_id,
243
+ final=True,
244
+ )
245
+ )
246
+ else:
247
+ # Publish final status with current task_state and message
248
+ await event_queue.enqueue_event(
249
+ TaskStatusUpdateEvent(
250
+ task_id=task_id,
251
+ status=TaskStatus(
252
+ state=task_result_aggregator.task_state,
253
+ timestamp=datetime.now(timezone.utc).isoformat(),
254
+ message=task_result_aggregator.task_status_message,
255
+ ),
256
+ context_id=context_id,
257
+ final=True,
258
+ )
259
+ )
260
+
261
+ except Exception as e:
262
+ logger.error("Error during graph execution: %s", e, exc_info=True)
263
+ # Update task state to failed using aggregator
264
+ task_result_aggregator.set_failed(str(e))
265
+ raise
@@ -0,0 +1,152 @@
1
+ # Copyright 2025 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
+ # http://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
+ from __future__ import annotations
16
+
17
+ from a2a.types import (
18
+ FilePart,
19
+ FileWithBytes,
20
+ FileWithUri,
21
+ Message,
22
+ Part,
23
+ Role,
24
+ TaskState,
25
+ TextPart,
26
+ )
27
+ from langchain_core.messages import AIMessage, ToolMessage
28
+
29
+
30
+ class LangGraphTaskResultAggregator:
31
+ """Aggregates streaming LangGraph messages into a final consolidated result."""
32
+
33
+ def __init__(self) -> None:
34
+ self._task_state = TaskState.working
35
+ self._accumulated_content = "" # Accumulate text content across chunks
36
+ self._task_status_message: Message | None = None
37
+ self._media_parts: list[Part] = [] # Track media parts from tool responses
38
+
39
+ def process_message(self, message: AIMessage | ToolMessage) -> None:
40
+ """Process a streaming message chunk from LangGraph."""
41
+
42
+ # Handle tool responses to extract media
43
+ if isinstance(message, ToolMessage):
44
+ self._extract_media_from_tool_response(message)
45
+ return
46
+
47
+ if not message.content:
48
+ return
49
+
50
+ if isinstance(message.content, str):
51
+ self._accumulated_content += message.content
52
+
53
+ elif isinstance(message.content, list):
54
+ for item in message.content:
55
+ if isinstance(item, str):
56
+ self._accumulated_content += item
57
+ elif isinstance(item, dict) and item.get("type") == "text":
58
+ self._accumulated_content += item.get("text", "")
59
+
60
+ # Update the task status message with current accumulated content
61
+ if self._accumulated_content or self._media_parts:
62
+ parts = []
63
+ if self._accumulated_content:
64
+ parts.append(Part(root=TextPart(text=self._accumulated_content)))
65
+ parts.extend(self._media_parts)
66
+
67
+ self._task_status_message = Message(
68
+ message_id="aggregated",
69
+ role=Role.agent,
70
+ parts=parts,
71
+ )
72
+
73
+ def _extract_media_from_tool_response(self, message: ToolMessage) -> None:
74
+ """Extract media parts from a ToolMessage."""
75
+
76
+ if not message.content:
77
+ return
78
+
79
+ if isinstance(message.content, list):
80
+ for item in message.content:
81
+ if isinstance(item, dict):
82
+ content_type = item.get("type")
83
+ if content_type == "image":
84
+ self._media_parts.append(
85
+ self._convert_media_to_a2a_part(item, "image")
86
+ )
87
+ elif content_type == "audio":
88
+ self._media_parts.append(
89
+ self._convert_media_to_a2a_part(item, "audio")
90
+ )
91
+ elif content_type == "video":
92
+ self._media_parts.append(
93
+ self._convert_media_to_a2a_part(item, "video")
94
+ )
95
+
96
+ def _convert_media_to_a2a_part(
97
+ self, content: dict[str, str], media_type: str
98
+ ) -> Part:
99
+ """Convert a media content block to an A2A Part."""
100
+
101
+ mime_type = content.get("mime_type")
102
+
103
+ if "url" in content:
104
+ return Part(
105
+ root=FilePart(file=FileWithUri(uri=content["url"], mime_type=mime_type))
106
+ )
107
+ elif "base64" in content:
108
+ return Part(
109
+ root=FilePart(
110
+ file=FileWithBytes(bytes=content["base64"], mime_type=mime_type)
111
+ )
112
+ )
113
+ elif "file_id" in content:
114
+ # For now, store file_id as a URI
115
+ return Part(
116
+ root=FilePart(
117
+ file=FileWithUri(
118
+ uri=f"file://{content['file_id']}", mime_type=mime_type
119
+ )
120
+ )
121
+ )
122
+
123
+ # Fallback to empty text part
124
+ return Part(root=TextPart(text=f"[{media_type} content]"))
125
+
126
+ def get_final_parts(self) -> list[Part]:
127
+ """Get the final consolidated parts for the artifact."""
128
+
129
+ parts = []
130
+ if self._accumulated_content:
131
+ parts.append(Part(root=TextPart(text=self._accumulated_content)))
132
+ parts.extend(self._media_parts)
133
+ return parts if parts else []
134
+
135
+ @property
136
+ def task_state(self) -> TaskState:
137
+ """Get the current task state."""
138
+ return self._task_state
139
+
140
+ @property
141
+ def task_status_message(self) -> Message | None:
142
+ """Get the current task status message with accumulated content."""
143
+ return self._task_status_message
144
+
145
+ def set_failed(self, error_message: str) -> None:
146
+ """Set the task state to failed."""
147
+ self._task_state = TaskState.failed
148
+ self._task_status_message = Message(
149
+ message_id="error",
150
+ role=Role.agent,
151
+ parts=[Part(root=TextPart(text=error_message))],
152
+ )