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
src/cli/utils/template.py DELETED
@@ -1,737 +0,0 @@
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
- import logging
16
- import os
17
- import pathlib
18
- import shutil
19
- import tempfile
20
- from dataclasses import dataclass
21
- from typing import Any
22
-
23
- import yaml
24
- from cookiecutter.main import cookiecutter
25
- from rich.console import Console
26
- from rich.prompt import Prompt
27
-
28
- from src.cli.utils.version import get_current_version
29
-
30
- from .datastores import DATASTORES
31
-
32
- ADK_FILES = ["app/__init__.py"]
33
- NON_ADK_FILES: list[str] = []
34
-
35
-
36
- @dataclass
37
- class TemplateConfig:
38
- name: str
39
- description: str
40
- settings: dict[str, bool | list[str]]
41
-
42
- @classmethod
43
- def from_file(cls, config_path: pathlib.Path) -> "TemplateConfig":
44
- """Load template config from file with validation"""
45
- try:
46
- with open(config_path) as f:
47
- data = yaml.safe_load(f)
48
-
49
- if not isinstance(data, dict):
50
- raise ValueError(f"Invalid template config format in {config_path}")
51
-
52
- required_fields = ["name", "description", "settings"]
53
- missing_fields = [f for f in required_fields if f not in data]
54
- if missing_fields:
55
- raise ValueError(
56
- f"Missing required fields in template config: {missing_fields}"
57
- )
58
-
59
- return cls(
60
- name=data["name"],
61
- description=data["description"],
62
- settings=data["settings"],
63
- )
64
- except yaml.YAMLError as err:
65
- raise ValueError(f"Invalid YAML in template config: {err}") from err
66
- except Exception as err:
67
- raise ValueError(f"Error loading template config: {err}") from err
68
-
69
-
70
- OVERWRITE_FOLDERS = ["app", "frontend", "tests", "notebooks"]
71
- TEMPLATE_CONFIG_FILE = ".templateconfig.yaml"
72
- DEPLOYMENT_FOLDERS = ["cloud_run", "agent_engine"]
73
- DEFAULT_FRONTEND = "streamlit"
74
-
75
-
76
- def get_available_agents(deployment_target: str | None = None) -> dict:
77
- """Dynamically load available agents from the agents directory.
78
-
79
- Args:
80
- deployment_target: Optional deployment target to filter agents
81
- """
82
- # Define priority agents that should appear first
83
- PRIORITY_AGENTS = ["adk_base", "agentic_rag", "langgraph_base_react"]
84
-
85
- agents_list = []
86
- priority_agents_dict = dict.fromkeys(PRIORITY_AGENTS) # Track priority agents
87
- agents_dir = pathlib.Path(__file__).parent.parent.parent.parent / "agents"
88
-
89
- for agent_dir in agents_dir.iterdir():
90
- if agent_dir.is_dir() and not agent_dir.name.startswith("__"):
91
- template_config_path = agent_dir / "template" / ".templateconfig.yaml"
92
- if template_config_path.exists():
93
- try:
94
- with open(template_config_path) as f:
95
- config = yaml.safe_load(f)
96
- agent_name = agent_dir.name
97
-
98
- # Skip if deployment target specified and agent doesn't support it
99
- if deployment_target:
100
- targets = config.get("settings", {}).get(
101
- "deployment_targets", []
102
- )
103
- if isinstance(targets, str):
104
- targets = [targets]
105
- if deployment_target not in targets:
106
- continue
107
-
108
- description = config.get("description", "No description available")
109
- agent_info = {"name": agent_name, "description": description}
110
-
111
- # Add to priority list or regular list based on agent name
112
- if agent_name in PRIORITY_AGENTS:
113
- priority_agents_dict[agent_name] = agent_info
114
- else:
115
- agents_list.append(agent_info)
116
- except Exception as e:
117
- logging.warning(f"Could not load agent from {agent_dir}: {e}")
118
-
119
- # Sort the non-priority agents
120
- agents_list.sort(key=lambda x: x["name"])
121
-
122
- # Create priority agents list in the exact order specified
123
- priority_agents = [
124
- info for name, info in priority_agents_dict.items() if info is not None
125
- ]
126
-
127
- # Combine priority agents with regular agents
128
- combined_agents = priority_agents + agents_list
129
-
130
- # Convert to numbered dictionary starting from 1
131
- agents = {i + 1: agent for i, agent in enumerate(combined_agents)}
132
-
133
- return agents
134
-
135
-
136
- def load_template_config(template_dir: pathlib.Path) -> dict[str, Any]:
137
- """Read .templateconfig.yaml file to get agent configuration."""
138
- config_file = template_dir / TEMPLATE_CONFIG_FILE
139
- if not config_file.exists():
140
- return {}
141
-
142
- try:
143
- with open(config_file) as f:
144
- config = yaml.safe_load(f)
145
- return config if config else {}
146
- except Exception as e:
147
- logging.error(f"Error loading template config: {e}")
148
- return {}
149
-
150
-
151
- def get_deployment_targets(agent_name: str) -> list:
152
- """Get available deployment targets for the selected agent."""
153
- template_path = (
154
- pathlib.Path(__file__).parent.parent.parent.parent
155
- / "agents"
156
- / agent_name
157
- / "template"
158
- )
159
- config = load_template_config(template_path)
160
-
161
- if not config:
162
- return []
163
-
164
- targets = config.get("settings", {}).get("deployment_targets", [])
165
- return targets if isinstance(targets, list) else [targets]
166
-
167
-
168
- def prompt_deployment_target(agent_name: str) -> str:
169
- """Ask user to select a deployment target for the agent."""
170
- targets = get_deployment_targets(agent_name)
171
-
172
- # Define deployment target friendly names and descriptions
173
- TARGET_INFO = {
174
- "agent_engine": {
175
- "display_name": "Vertex AI Agent Engine",
176
- "description": "Vertex AI Managed platform for scalable agent deployments",
177
- },
178
- "cloud_run": {
179
- "display_name": "Cloud Run",
180
- "description": "GCP Serverless container execution",
181
- },
182
- }
183
-
184
- if not targets:
185
- return ""
186
-
187
- console = Console()
188
- console.print("\n> Please select a deployment target:")
189
- for idx, target in enumerate(targets, 1):
190
- info = TARGET_INFO.get(target, {})
191
- display_name = info.get("display_name", target)
192
- description = info.get("description", "")
193
- console.print(f"{idx}. [bold]{display_name}[/] - [dim]{description}[/]")
194
-
195
- from rich.prompt import IntPrompt
196
-
197
- choice = IntPrompt.ask(
198
- "\nEnter the number of your deployment target choice",
199
- default=1,
200
- show_default=True,
201
- )
202
- return targets[choice - 1]
203
-
204
-
205
- def prompt_datastore_selection(
206
- agent_name: str, from_cli_flag: bool = False
207
- ) -> str | None:
208
- """Ask user to select a datastore type if the agent supports data ingestion.
209
-
210
- Args:
211
- agent_name: Name of the agent
212
- from_cli_flag: Whether this is being called due to explicit --include-data-ingestion flag
213
- """
214
- console = Console()
215
-
216
- # If this is from CLI flag, skip the "would you like to include" prompt
217
- if from_cli_flag:
218
- console.print("\n> Please select a datastore type for your data:")
219
-
220
- # Display options with descriptions
221
- for i, (_key, info) in enumerate(DATASTORES.items(), 1):
222
- console.print(
223
- f"{i}. [bold]{info['name']}[/] - [dim]{info['description']}[/]"
224
- )
225
-
226
- choice = Prompt.ask(
227
- "\nEnter the number of your choice",
228
- choices=[str(i) for i in range(1, len(DATASTORES) + 1)],
229
- default="1",
230
- )
231
-
232
- # Convert choice number to datastore type
233
- datastore_type = list(DATASTORES.keys())[int(choice) - 1]
234
- return datastore_type
235
-
236
- # Otherwise, proceed with normal flow
237
- template_path = (
238
- pathlib.Path(__file__).parent.parent.parent.parent
239
- / "agents"
240
- / agent_name
241
- / "template"
242
- )
243
- config = load_template_config(template_path)
244
-
245
- if config:
246
- # If requires_data_ingestion is true, prompt for datastore type without asking if they want it
247
- if config.get("settings", {}).get("requires_data_ingestion"):
248
- console.print("\n> This agent includes a data ingestion pipeline.")
249
- console.print("> Please select a datastore type for your data:")
250
-
251
- # Display options with descriptions
252
- for i, (_key, info) in enumerate(DATASTORES.items(), 1):
253
- console.print(
254
- f"{i}. [bold]{info['name']}[/] - [dim]{info['description']}[/]"
255
- )
256
- choice = Prompt.ask(
257
- "\nEnter the number of your choice",
258
- choices=[str(i) for i in range(1, len(DATASTORES) + 1)],
259
- default="1",
260
- )
261
-
262
- # Convert choice number to datastore type
263
- datastore_type = list(DATASTORES.keys())[int(choice) - 1]
264
- return datastore_type
265
-
266
- # Only prompt if the agent has optional data ingestion support
267
- if "requires_data_ingestion" in config.get("settings", {}):
268
- include = (
269
- Prompt.ask(
270
- "\n> This agent supports data ingestion. Would you like to include a data pipeline?",
271
- choices=["y", "n"],
272
- default="n",
273
- ).lower()
274
- == "y"
275
- )
276
-
277
- if include:
278
- console.print("\n> Please select a datastore type for your data:")
279
-
280
- # Display options with descriptions
281
- for i, (_key, info) in enumerate(DATASTORES.items(), 1):
282
- console.print(
283
- f"{i}. [bold]{info['name']}[/] - [dim]{info['description']}[/]"
284
- )
285
-
286
- choice = Prompt.ask(
287
- "\nEnter the number of your choice",
288
- choices=[str(i) for i in range(1, len(DATASTORES) + 1)],
289
- default="1",
290
- )
291
-
292
- # Convert choice number to datastore type
293
- datastore_type = list(DATASTORES.keys())[int(choice) - 1]
294
- return datastore_type
295
-
296
- # If we get here, we need to prompt for datastore selection for explicit --include-data-ingestion flag
297
- console.print(
298
- "\n> Please select a datastore type for your data ingestion pipeline:"
299
- )
300
- # Display options with descriptions
301
- for i, (_key, info) in enumerate(DATASTORES.items(), 1):
302
- console.print(f"{i}. [bold]{info['name']}[/] - [dim]{info['description']}[/]")
303
-
304
- choice = Prompt.ask(
305
- "\nEnter the number of your choice",
306
- choices=[str(i) for i in range(1, len(DATASTORES) + 1)],
307
- default="1",
308
- )
309
-
310
- # Convert choice number to datastore type
311
- datastore_type = list(DATASTORES.keys())[int(choice) - 1]
312
- return datastore_type
313
-
314
-
315
- def get_template_path(agent_name: str, debug: bool = False) -> pathlib.Path:
316
- """Get the absolute path to the agent template directory."""
317
- current_dir = pathlib.Path(__file__).parent.parent.parent.parent
318
- template_path = current_dir / "agents" / agent_name / "template"
319
- if debug:
320
- logging.debug(f"Looking for template in: {template_path}")
321
- logging.debug(f"Template exists: {template_path.exists()}")
322
- if template_path.exists():
323
- logging.debug(f"Template contents: {list(template_path.iterdir())}")
324
-
325
- if not template_path.exists():
326
- raise ValueError(f"Template directory not found at {template_path}")
327
-
328
- return template_path
329
-
330
-
331
- def copy_data_ingestion_files(
332
- project_template: pathlib.Path, datastore_type: str
333
- ) -> None:
334
- """Copy data processing files to the project template for cookiecutter templating.
335
-
336
- Args:
337
- project_template: Path to the project template directory
338
- datastore_type: Type of datastore to use for data ingestion
339
- """
340
- data_ingestion_src = pathlib.Path(__file__).parent.parent.parent / "data_ingestion"
341
- data_ingestion_dst = project_template / "data_ingestion"
342
-
343
- if data_ingestion_src.exists():
344
- logging.debug(
345
- f"Copying data processing files from {data_ingestion_src} to {data_ingestion_dst}"
346
- )
347
-
348
- copy_files(data_ingestion_src, data_ingestion_dst, overwrite=True)
349
-
350
- logging.debug(f"Data ingestion files prepared for datastore: {datastore_type}")
351
- else:
352
- logging.warning(
353
- f"Data processing source directory not found at {data_ingestion_src}"
354
- )
355
-
356
-
357
- def process_template(
358
- agent_name: str,
359
- template_dir: pathlib.Path,
360
- project_name: str,
361
- deployment_target: str | None = None,
362
- include_data_ingestion: bool = False,
363
- datastore: str | None = None,
364
- output_dir: pathlib.Path | None = None,
365
- ) -> None:
366
- """Process the template directory and create a new project.
367
-
368
- Args:
369
- agent_name: Name of the agent template to use
370
- template_dir: Directory containing the template files
371
- project_name: Name of the project to create
372
- deployment_target: Optional deployment target (agent_engine or cloud_run)
373
- include_data_ingestion: Whether to include data pipeline components
374
- output_dir: Optional output directory path, defaults to current directory
375
- """
376
- logging.debug(f"Processing template from {template_dir}")
377
- logging.debug(f"Project name: {project_name}")
378
- logging.debug(f"Include pipeline: {datastore}")
379
- logging.debug(f"Output directory: {output_dir}")
380
-
381
- # Get paths
382
- agent_path = template_dir.parent # Get parent of template dir
383
- logging.debug(f"agent path: {agent_path}")
384
- logging.debug(f"agent path exists: {agent_path.exists()}")
385
- logging.debug(
386
- f"agent path contents: {list(agent_path.iterdir()) if agent_path.exists() else 'N/A'}"
387
- )
388
-
389
- base_template_path = pathlib.Path(__file__).parent.parent.parent / "base_template"
390
-
391
- # Use provided output_dir or current directory
392
- destination_dir = output_dir if output_dir else pathlib.Path.cwd()
393
-
394
- # Create output directory if it doesn't exist
395
- if not destination_dir.exists():
396
- destination_dir.mkdir(parents=True)
397
-
398
- # Create a new temporary directory and use it as our working directory
399
- with tempfile.TemporaryDirectory() as temp_dir:
400
- temp_path = pathlib.Path(temp_dir)
401
-
402
- # Important: Store the original working directory
403
- original_dir = pathlib.Path.cwd()
404
-
405
- try:
406
- os.chdir(temp_path) # Change to temp directory
407
-
408
- # Create the cookiecutter template structure
409
- cookiecutter_template = temp_path / "template"
410
- cookiecutter_template.mkdir(parents=True)
411
- project_template = cookiecutter_template / "{{cookiecutter.project_name}}"
412
- project_template.mkdir(parents=True)
413
-
414
- # 1. First copy base template files
415
- base_template_path = (
416
- pathlib.Path(__file__).parent.parent.parent / "base_template"
417
- )
418
- copy_files(base_template_path, project_template, agent_name, overwrite=True)
419
- logging.debug(f"1. Copied base template from {base_template_path}")
420
-
421
- # 2. Process deployment target if specified
422
- if deployment_target and deployment_target in DEPLOYMENT_FOLDERS:
423
- deployment_path = (
424
- pathlib.Path(__file__).parent.parent.parent
425
- / "deployment_targets"
426
- / deployment_target
427
- )
428
- if deployment_path.exists():
429
- copy_files(
430
- deployment_path,
431
- project_template,
432
- agent_name=agent_name,
433
- overwrite=True,
434
- )
435
- logging.debug(
436
- f"2. Processed deployment files for target: {deployment_target}"
437
- )
438
-
439
- # 3. Copy data ingestion files if needed
440
- if include_data_ingestion and datastore:
441
- logging.debug(
442
- f"3. Including data processing files with datastore: {datastore}"
443
- )
444
- copy_data_ingestion_files(project_template, datastore)
445
-
446
- # 4. Process frontend files
447
- # Load template config
448
- template_config = load_template_config(pathlib.Path(template_dir))
449
- frontend_type = template_config.get("settings", {}).get(
450
- "frontend_type", DEFAULT_FRONTEND
451
- )
452
- copy_frontend_files(frontend_type, project_template)
453
- logging.debug(f"4. Processed frontend files for type: {frontend_type}")
454
-
455
- # 5. Finally, copy agent-specific files to override everything else
456
- if agent_path.exists():
457
- for folder in OVERWRITE_FOLDERS:
458
- agent_folder = agent_path / folder
459
- project_folder = project_template / folder
460
- if agent_folder.exists():
461
- logging.debug(f"5. Copying agent folder {folder} with override")
462
- copy_files(
463
- agent_folder, project_folder, agent_name, overwrite=True
464
- )
465
-
466
- # Copy agent README.md if it exists
467
- agent_readme = agent_path / "README.md"
468
- if agent_readme.exists():
469
- agent_readme_dest = project_template / "agent_README.md"
470
- shutil.copy2(agent_readme, agent_readme_dest)
471
- logging.debug(
472
- f"Copied agent README from {agent_readme} to {agent_readme_dest}"
473
- )
474
-
475
- # Load and validate template config first
476
- template_path = pathlib.Path(template_dir)
477
- config = load_template_config(template_path)
478
- if not config:
479
- raise ValueError(f"Could not load template config from {template_path}")
480
-
481
- # Validate deployment target
482
- available_targets = config.get("settings", {}).get("deployment_targets", [])
483
- if isinstance(available_targets, str):
484
- available_targets = [available_targets]
485
-
486
- if deployment_target and deployment_target not in available_targets:
487
- raise ValueError(
488
- f"Invalid deployment target '{deployment_target}'. Available targets: {available_targets}"
489
- )
490
-
491
- # Load template config
492
- template_config = load_template_config(pathlib.Path(template_dir))
493
-
494
- # Check if data processing should be included
495
- if include_data_ingestion and datastore:
496
- logging.debug(
497
- f"Including data processing files with datastore: {datastore}"
498
- )
499
- copy_data_ingestion_files(project_template, datastore)
500
-
501
- # Create cookiecutter.json in the template root
502
- # Process extra dependencies
503
- extra_deps = template_config.get("settings", {}).get(
504
- "extra_dependencies", []
505
- )
506
- # Get frontend type from template config
507
- frontend_type = template_config.get("settings", {}).get(
508
- "frontend_type", DEFAULT_FRONTEND
509
- )
510
- tags = template_config.get("settings", {}).get("tags", ["None"])
511
- cookiecutter_config = {
512
- "project_name": "my-project",
513
- "agent_name": agent_name,
514
- "package_version": get_current_version(),
515
- "agent_description": template_config.get("description", ""),
516
- "tags": tags,
517
- "deployment_target": deployment_target or "",
518
- "frontend_type": frontend_type,
519
- "extra_dependencies": [extra_deps],
520
- "data_ingestion": include_data_ingestion, # Use explicit flag for cookiecutter
521
- "datastore_type": datastore if datastore else "",
522
- "_copy_without_render": [
523
- "*.ipynb", # Don't render notebooks
524
- "*.json", # Don't render JSON files
525
- "frontend/*", # Don't render frontend directory
526
- # "tests/*", # Don't render tests directory
527
- "notebooks/*", # Don't render notebooks directory
528
- ".git/*", # Don't render git directory
529
- "__pycache__/*", # Don't render cache
530
- "**/__pycache__/*",
531
- ".pytest_cache/*",
532
- ".venv/*",
533
- "*templates.py", # Don't render templates files
534
- "!*.py", # render Python files
535
- "!Makefile", # DO render Makefile
536
- "!README.md", # DO render README.md
537
- ],
538
- }
539
-
540
- with open(cookiecutter_template / "cookiecutter.json", "w") as f:
541
- import json
542
-
543
- json.dump(cookiecutter_config, f, indent=4)
544
-
545
- logging.debug(f"Template structure created at {cookiecutter_template}")
546
- logging.debug(
547
- f"Directory contents: {list(cookiecutter_template.iterdir())}"
548
- )
549
-
550
- # Process the template
551
- cookiecutter(
552
- str(cookiecutter_template),
553
- no_input=True,
554
- extra_context={
555
- "project_name": project_name,
556
- "agent_name": agent_name,
557
- },
558
- )
559
- logging.debug("Template processing completed successfully")
560
-
561
- # Move the generated project to the final destination
562
- output_dir = temp_path / project_name
563
- final_destination = destination_dir / project_name
564
-
565
- logging.debug(f"Moving project from {output_dir} to {final_destination}")
566
-
567
- if output_dir.exists():
568
- if final_destination.exists():
569
- shutil.rmtree(final_destination)
570
- shutil.copytree(output_dir, final_destination, dirs_exist_ok=True)
571
- logging.debug(f"Project successfully created at {final_destination}")
572
-
573
- # Delete appropriate files based on ADK tag
574
- if "adk" in tags:
575
- files_to_delete = [final_destination / f for f in NON_ADK_FILES]
576
- else:
577
- files_to_delete = [final_destination / f for f in ADK_FILES]
578
-
579
- for file_path in files_to_delete:
580
- if file_path.exists():
581
- file_path.unlink()
582
- logging.debug(f"Deleted {file_path}")
583
-
584
- # After copying template files, handle the lock file
585
- if deployment_target:
586
- # Get the source lock file path
587
- lock_path = (
588
- pathlib.Path(__file__).parent.parent.parent.parent
589
- / "src"
590
- / "resources"
591
- / "locks"
592
- / f"uv-{agent_name}-{deployment_target}.lock"
593
- )
594
- logging.debug(f"Looking for lock file at: {lock_path}")
595
- logging.debug(f"Lock file exists: {lock_path.exists()}")
596
- if not lock_path.exists():
597
- raise FileNotFoundError(f"Lock file not found: {lock_path}")
598
- # Copy and rename to uv.lock in the project directory
599
- shutil.copy2(lock_path, final_destination / "uv.lock")
600
- logging.debug(
601
- f"Copied lock file from {lock_path} to {final_destination}/uv.lock"
602
- )
603
-
604
- # Replace cookiecutter project name with actual project name in lock file
605
- lock_file_path = final_destination / "uv.lock"
606
- with open(lock_file_path, "r+", encoding="utf-8") as f:
607
- content = f.read()
608
- f.seek(0)
609
- f.write(
610
- content.replace(
611
- "{{cookiecutter.project_name}}", project_name
612
- )
613
- )
614
- f.truncate()
615
- logging.debug(
616
- f"Updated project name in lock file at {lock_file_path}"
617
- )
618
- else:
619
- logging.error(f"Generated project directory not found at {output_dir}")
620
- raise FileNotFoundError(
621
- f"Generated project directory not found at {output_dir}"
622
- )
623
-
624
- except Exception as e:
625
- logging.error(f"Failed to process template: {e!s}")
626
- raise
627
-
628
- finally:
629
- # Always restore the original working directory
630
- os.chdir(original_dir)
631
-
632
-
633
- def should_exclude_path(path: pathlib.Path, agent_name: str) -> bool:
634
- """Determine if a path should be excluded based on the agent type."""
635
- if agent_name == "live_api":
636
- # Exclude the unit test utils folder and app/utils folder for live_api
637
- if "tests/unit/test_utils" in str(path) or "app/utils" in str(path):
638
- logging.debug(f"Excluding path for live_api: {path}")
639
- return True
640
- return False
641
-
642
-
643
- def copy_files(
644
- src: pathlib.Path,
645
- dst: pathlib.Path,
646
- agent_name: str | None = None,
647
- overwrite: bool = False,
648
- ) -> None:
649
- """
650
- Copy files with configurable behavior for exclusions and overwrites.
651
-
652
- Args:
653
- src: Source path
654
- dst: Destination path
655
- agent_name: Name of the agent (for agent-specific exclusions)
656
- overwrite: Whether to overwrite existing files (True) or skip them (False)
657
- """
658
-
659
- def should_skip(path: pathlib.Path) -> bool:
660
- """Determine if a file/directory should be skipped during copying."""
661
- if path.suffix in [".pyc"]:
662
- return True
663
- if "__pycache__" in str(path) or path.name == "__pycache__":
664
- return True
665
- if agent_name is not None and should_exclude_path(path, agent_name):
666
- return True
667
- return False
668
-
669
- if src.is_dir():
670
- if not dst.exists():
671
- dst.mkdir(parents=True)
672
- for item in src.iterdir():
673
- if should_skip(item):
674
- logging.debug(f"Skipping file/directory: {item}")
675
- continue
676
- d = dst / item.name
677
- if item.is_dir():
678
- copy_files(item, d, agent_name, overwrite)
679
- else:
680
- if overwrite or not d.exists():
681
- logging.debug(f"Copying file: {item} -> {d}")
682
- shutil.copy2(item, d)
683
- else:
684
- logging.debug(f"Skipping existing file: {d}")
685
- else:
686
- if not should_skip(src):
687
- if overwrite or not dst.exists():
688
- shutil.copy2(src, dst)
689
-
690
-
691
- def copy_frontend_files(frontend_type: str, project_template: pathlib.Path) -> None:
692
- """Copy files from the specified frontend folder directly to project root."""
693
- # Skip copying if frontend_type is "None"
694
- if frontend_type == "None":
695
- logging.debug("Frontend type is 'None', skipping frontend files")
696
- return
697
-
698
- # Use default frontend if none specified
699
- frontend_type = frontend_type or DEFAULT_FRONTEND
700
-
701
- # Get the frontends directory path
702
- frontends_path = (
703
- pathlib.Path(__file__).parent.parent.parent / "frontends" / frontend_type
704
- )
705
-
706
- if frontends_path.exists():
707
- logging.debug(f"Copying frontend files from {frontends_path}")
708
- # Copy frontend files directly to project root instead of a nested frontend directory
709
- copy_files(frontends_path, project_template, overwrite=True)
710
- else:
711
- logging.warning(f"Frontend type directory not found: {frontends_path}")
712
- if frontend_type != DEFAULT_FRONTEND:
713
- logging.info(f"Falling back to default frontend: {DEFAULT_FRONTEND}")
714
- copy_frontend_files(DEFAULT_FRONTEND, project_template)
715
-
716
-
717
- def copy_deployment_files(
718
- deployment_target: str, agent_name: str, project_template: pathlib.Path
719
- ) -> None:
720
- """Copy files from the specified deployment target folder."""
721
- if not deployment_target:
722
- return
723
-
724
- deployment_path = (
725
- pathlib.Path(__file__).parent.parent.parent
726
- / "deployment_targets"
727
- / deployment_target
728
- )
729
-
730
- if deployment_path.exists():
731
- logging.debug(f"Copying deployment files from {deployment_path}")
732
- # Pass agent_name to respect agent-specific exclusions
733
- copy_files(
734
- deployment_path, project_template, agent_name=agent_name, overwrite=True
735
- )
736
- else:
737
- logging.warning(f"Deployment target directory not found: {deployment_path}")