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.
- agent_starter_pack/agents/README.md +7 -0
- agents/langgraph_base_react/template/.templateconfig.yaml → agent_starter_pack/agents/adk_a2a_base/.template/templateconfig.yaml +5 -10
- agent_starter_pack/agents/adk_a2a_base/README.md +37 -0
- src/deployment_targets/cloud_run/Dockerfile → agent_starter_pack/agents/adk_a2a_base/app/__init__.py +2 -14
- agent_starter_pack/agents/adk_a2a_base/app/agent.py +70 -0
- agent_starter_pack/agents/adk_a2a_base/notebooks/adk_a2a_app_testing.ipynb +583 -0
- agents/crewai_coding_crew/notebooks/evaluating_crewai_agent.ipynb → agent_starter_pack/agents/adk_a2a_base/notebooks/evaluating_adk_agent.ipynb +163 -199
- {agents/adk_base → agent_starter_pack/agents/adk_a2a_base}/tests/integration/test_agent.py +2 -2
- agents/adk_base/template/.templateconfig.yaml → agent_starter_pack/agents/adk_base/.template/templateconfig.yaml +4 -1
- {agents → agent_starter_pack/agents}/adk_base/README.md +1 -1
- agent_starter_pack/agents/adk_base/app/__init__.py +17 -0
- {agents → agent_starter_pack/agents}/adk_base/app/agent.py +5 -2
- {agents → agent_starter_pack/agents}/adk_base/notebooks/adk_app_testing.ipynb +128 -82
- agents/langgraph_base_react/notebooks/evaluating_langgraph_agent.ipynb → agent_starter_pack/agents/adk_base/notebooks/evaluating_adk_agent.ipynb +181 -207
- agent_starter_pack/agents/adk_base/tests/integration/test_agent.py +58 -0
- agents/crewai_coding_crew/template/.templateconfig.yaml → agent_starter_pack/agents/adk_live/.template/templateconfig.yaml +5 -9
- agent_starter_pack/agents/adk_live/README.md +32 -0
- agent_starter_pack/agents/adk_live/app/__init__.py +17 -0
- agent_starter_pack/agents/adk_live/app/agent.py +51 -0
- agent_starter_pack/agents/adk_live/tests/unit/test_dummy.py +38 -0
- agents/agentic_rag/template/.templateconfig.yaml → agent_starter_pack/agents/agentic_rag/.template/templateconfig.yaml +7 -3
- {agents → agent_starter_pack/agents}/agentic_rag/README.md +1 -1
- agent_starter_pack/agents/agentic_rag/app/__init__.py +17 -0
- {agents → agent_starter_pack/agents}/agentic_rag/app/agent.py +8 -4
- {agents → agent_starter_pack/agents}/agentic_rag/notebooks/adk_app_testing.ipynb +128 -82
- agent_starter_pack/agents/agentic_rag/notebooks/evaluating_adk_agent.ipynb +1535 -0
- {agents → agent_starter_pack/agents}/agentic_rag/tests/integration/test_agent.py +3 -3
- agent_starter_pack/agents/langgraph_base/.template/templateconfig.yaml +31 -0
- agent_starter_pack/agents/langgraph_base/README.md +30 -0
- agent_starter_pack/agents/langgraph_base/app/__init__.py +17 -0
- agent_starter_pack/agents/langgraph_base/app/agent.py +34 -0
- {agents/crewai_coding_crew → agent_starter_pack/agents/langgraph_base}/notebooks/evaluating_langgraph_agent.ipynb +30 -17
- {agents/langgraph_base_react → agent_starter_pack/agents/langgraph_base}/tests/integration/test_agent.py +2 -2
- {src → agent_starter_pack}/base_template/.gitignore +5 -3
- agent_starter_pack/base_template/GEMINI.md +5 -0
- agent_starter_pack/base_template/Makefile +339 -0
- agent_starter_pack/base_template/README.md +267 -0
- agent_starter_pack/base_template/deployment/README.md +11 -0
- {src → agent_starter_pack}/base_template/deployment/terraform/apis.tf +2 -2
- {src → agent_starter_pack}/base_template/deployment/terraform/dev/apis.tf +6 -1
- {src → agent_starter_pack}/base_template/deployment/terraform/dev/iam.tf +12 -11
- {src → agent_starter_pack}/base_template/deployment/terraform/dev/providers.tf +5 -1
- {src → agent_starter_pack}/base_template/deployment/terraform/dev/storage.tf +1 -1
- {src → agent_starter_pack}/base_template/deployment/terraform/dev/variables.tf +10 -10
- agent_starter_pack/base_template/deployment/terraform/dev/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +193 -0
- agent_starter_pack/base_template/deployment/terraform/github.tf +337 -0
- {src → agent_starter_pack}/base_template/deployment/terraform/iam.tf +20 -41
- {src → agent_starter_pack}/base_template/deployment/terraform/locals.tf +10 -3
- {src/resources/setup_cicd → agent_starter_pack/base_template/deployment/terraform}/providers.tf +8 -1
- {src → agent_starter_pack}/base_template/deployment/terraform/service_accounts.tf +7 -8
- agent_starter_pack/base_template/deployment/terraform/sql/completions.sql +138 -0
- {src → agent_starter_pack}/base_template/deployment/terraform/storage.tf +7 -16
- {src → agent_starter_pack}/base_template/deployment/terraform/variables.tf +61 -28
- {src → agent_starter_pack}/base_template/deployment/terraform/vars/env.tfvars +6 -1
- agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'github_actions' %}wif.tf{% else %}unused_wif.tf{% endif %} +43 -0
- 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
- agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +206 -0
- {src → agent_starter_pack}/base_template/pyproject.toml +24 -37
- agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/deploy-to-prod.yaml +132 -0
- agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/pr_checks.yaml +65 -0
- agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/staging.yaml +259 -0
- 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
- 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
- agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/staging.yaml +322 -0
- agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/telemetry.py +96 -0
- {src/base_template/app/utils → agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils}/typing.py +7 -9
- 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
- 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
- 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
- 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
- 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
- agent_starter_pack/cli/commands/create.py +1256 -0
- agent_starter_pack/cli/commands/enhance.py +611 -0
- agent_starter_pack/cli/commands/list.py +203 -0
- agent_starter_pack/cli/commands/register_gemini_enterprise.py +1070 -0
- agent_starter_pack/cli/commands/setup_cicd.py +862 -0
- {src → agent_starter_pack}/cli/main.py +10 -2
- {src → agent_starter_pack}/cli/utils/cicd.py +139 -48
- agent_starter_pack/cli/utils/gcp.py +263 -0
- agent_starter_pack/cli/utils/logging.py +103 -0
- agent_starter_pack/cli/utils/remote_template.py +677 -0
- agent_starter_pack/cli/utils/template.py +1466 -0
- {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/components/process_data.py +1 -1
- {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/submit_pipeline.py +20 -6
- {src → agent_starter_pack}/data_ingestion/pyproject.toml +1 -0
- {src → agent_starter_pack}/data_ingestion/uv.lock +602 -494
- agent_starter_pack/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +484 -0
- agent_starter_pack/deployment_targets/agent_engine/tests/load_test/README.md +84 -0
- agent_starter_pack/deployment_targets/agent_engine/tests/load_test/load_test.py +424 -0
- agent_starter_pack/deployment_targets/agent_engine/tests/{% if cookiecutter.is_a2a %}helpers.py{% else %}unused_helpers.py{% endif %} +138 -0
- agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/agent_engine_app.py +263 -0
- agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/app_utils/deploy.py +414 -0
- 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
- agent_starter_pack/deployment_targets/cloud_run/Dockerfile +51 -0
- agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/dev/service.tf +243 -0
- agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/service.tf +417 -0
- agent_starter_pack/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +705 -0
- agent_starter_pack/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +321 -0
- agent_starter_pack/deployment_targets/cloud_run/tests/load_test/README.md +165 -0
- agent_starter_pack/deployment_targets/cloud_run/tests/load_test/load_test.py +329 -0
- agent_starter_pack/deployment_targets/cloud_run/{{cookiecutter.agent_directory}}/fast_api_app.py +556 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/package-lock.json +79 -1044
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/package.json +1 -9
- agent_starter_pack/frontends/adk_live_react/frontend/src/App.tsx +65 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/Logger.tsx +8 -3
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/logger.scss +26 -0
- agent_starter_pack/frontends/adk_live_react/frontend/src/components/side-panel/SidePanel.tsx +516 -0
- agent_starter_pack/frontends/adk_live_react/frontend/src/components/side-panel/side-panel.scss +563 -0
- agent_starter_pack/frontends/adk_live_react/frontend/src/components/transcription-preview/TranscriptionPreview.tsx +106 -0
- agent_starter_pack/frontends/adk_live_react/frontend/src/components/transcription-preview/transcription-preview.scss +150 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-live-api.ts +8 -2
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/multimodal-live-types.ts +40 -2
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audio-recorder.ts +1 -1
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audio-streamer.ts +1 -1
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/multimodal-live-client.ts +210 -24
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/utils.ts +27 -5
- agent_starter_pack/resources/docs/adk-cheatsheet.md +1628 -0
- agent_starter_pack/resources/locks/uv-adk_a2a_base-agent_engine.lock +4966 -0
- agent_starter_pack/resources/locks/uv-adk_a2a_base-cloud_run.lock +5011 -0
- agent_starter_pack/resources/locks/uv-adk_base-agent_engine.lock +4946 -0
- agent_starter_pack/resources/locks/uv-adk_base-cloud_run.lock +4991 -0
- agent_starter_pack/resources/locks/uv-adk_live-agent_engine.lock +4963 -0
- agent_starter_pack/resources/locks/uv-adk_live-cloud_run.lock +5006 -0
- agent_starter_pack/resources/locks/uv-agentic_rag-agent_engine.lock +5487 -0
- agent_starter_pack/resources/locks/uv-agentic_rag-cloud_run.lock +5532 -0
- agent_starter_pack/resources/locks/uv-langgraph_base-agent_engine.lock +5788 -0
- agent_starter_pack/resources/locks/uv-langgraph_base-cloud_run.lock +5811 -0
- {src → agent_starter_pack}/utils/generate_locks.py +15 -12
- {src → agent_starter_pack}/utils/lock_utils.py +4 -7
- {src → agent_starter_pack}/utils/watch_and_rebuild.py +2 -2
- agent_starter_pack-0.21.0.dist-info/METADATA +182 -0
- agent_starter_pack-0.21.0.dist-info/RECORD +171 -0
- agent_starter_pack-0.21.0.dist-info/entry_points.txt +2 -0
- llm.txt +362 -0
- agent_starter_pack-0.3.3.dist-info/METADATA +0 -164
- agent_starter_pack-0.3.3.dist-info/RECORD +0 -176
- agent_starter_pack-0.3.3.dist-info/entry_points.txt +0 -2
- agents/crewai_coding_crew/README.md +0 -34
- agents/crewai_coding_crew/app/agent.py +0 -86
- agents/crewai_coding_crew/app/crew/config/agents.yaml +0 -39
- agents/crewai_coding_crew/app/crew/config/tasks.yaml +0 -37
- agents/crewai_coding_crew/app/crew/crew.py +0 -71
- agents/crewai_coding_crew/tests/integration/test_agent.py +0 -47
- agents/langgraph_base_react/README.md +0 -9
- agents/langgraph_base_react/app/agent.py +0 -73
- agents/live_api/README.md +0 -37
- agents/live_api/app/agent.py +0 -78
- agents/live_api/app/server.py +0 -196
- agents/live_api/app/templates.py +0 -51
- agents/live_api/app/vector_store.py +0 -55
- agents/live_api/template/.templateconfig.yaml +0 -29
- agents/live_api/tests/integration/test_server_e2e.py +0 -254
- agents/live_api/tests/load_test/load_test.py +0 -40
- agents/live_api/tests/unit/test_server.py +0 -143
- src/base_template/Makefile +0 -72
- src/base_template/README.md +0 -208
- src/base_template/app/__init__.py +0 -3
- src/base_template/app/utils/tracing.py +0 -155
- src/base_template/deployment/README.md +0 -126
- src/base_template/deployment/cd/staging.yaml +0 -216
- src/base_template/deployment/terraform/dev/log_sinks.tf +0 -63
- src/base_template/deployment/terraform/log_sinks.tf +0 -70
- src/base_template/deployment/terraform/providers.tf +0 -37
- src/cli/commands/create.py +0 -664
- src/cli/commands/setup_cicd.py +0 -829
- src/cli/utils/gcp.py +0 -117
- src/cli/utils/logging.py +0 -51
- src/cli/utils/template.py +0 -737
- src/deployment_targets/agent_engine/app/agent_engine_app.py +0 -336
- src/deployment_targets/agent_engine/notebooks/intro_agent_engine.ipynb +0 -1025
- src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +0 -183
- src/deployment_targets/agent_engine/tests/load_test/README.md +0 -42
- src/deployment_targets/agent_engine/tests/load_test/load_test.py +0 -107
- src/deployment_targets/cloud_run/app/server.py +0 -154
- src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +0 -249
- src/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +0 -0
- src/deployment_targets/cloud_run/tests/load_test/README.md +0 -83
- src/deployment_targets/cloud_run/tests/load_test/load_test.py +0 -118
- src/deployment_targets/cloud_run/uv.lock +0 -6952
- src/frontends/live_api_react/frontend/src/App.tsx +0 -205
- src/frontends/live_api_react/frontend/src/components/control-tray/ControlTray.tsx +0 -217
- src/frontends/live_api_react/frontend/src/components/control-tray/control-tray.scss +0 -201
- src/frontends/live_api_react/frontend/src/components/side-panel/SidePanel.tsx +0 -161
- src/frontends/live_api_react/frontend/src/components/side-panel/side-panel.scss +0 -285
- src/frontends/streamlit/frontend/side_bar.py +0 -214
- src/frontends/streamlit/frontend/streamlit_app.py +0 -265
- src/frontends/streamlit/frontend/style/app_markdown.py +0 -37
- src/frontends/streamlit/frontend/utils/chat_utils.py +0 -67
- src/frontends/streamlit/frontend/utils/local_chat_history.py +0 -125
- src/frontends/streamlit/frontend/utils/message_editing.py +0 -59
- src/frontends/streamlit/frontend/utils/multimodal_utils.py +0 -217
- src/frontends/streamlit/frontend/utils/stream_handler.py +0 -301
- src/frontends/streamlit/frontend/utils/title_summary.py +0 -94
- src/frontends/streamlit_adk/frontend/side_bar.py +0 -214
- src/frontends/streamlit_adk/frontend/streamlit_app.py +0 -314
- src/frontends/streamlit_adk/frontend/style/app_markdown.py +0 -37
- src/frontends/streamlit_adk/frontend/utils/chat_utils.py +0 -84
- src/frontends/streamlit_adk/frontend/utils/local_chat_history.py +0 -110
- src/frontends/streamlit_adk/frontend/utils/message_editing.py +0 -61
- src/frontends/streamlit_adk/frontend/utils/multimodal_utils.py +0 -223
- src/frontends/streamlit_adk/frontend/utils/stream_handler.py +0 -311
- src/frontends/streamlit_adk/frontend/utils/title_summary.py +0 -129
- src/resources/containers/data_processing/Dockerfile +0 -27
- src/resources/containers/e2e-tests/Dockerfile +0 -19
- src/resources/idx/.idx/dev.nix +0 -57
- src/resources/idx/idx-template.json +0 -21
- src/resources/idx/idx-template.nix +0 -26
- src/resources/locks/uv-adk_base-agent_engine.lock +0 -5338
- src/resources/locks/uv-adk_base-cloud_run.lock +0 -5930
- src/resources/locks/uv-agentic_rag-agent_engine.lock +0 -5528
- src/resources/locks/uv-agentic_rag-cloud_run.lock +0 -6120
- src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +0 -6231
- src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +0 -6839
- src/resources/locks/uv-langgraph_base_react-agent_engine.lock +0 -5233
- src/resources/locks/uv-langgraph_base_react-cloud_run.lock +0 -5862
- src/resources/locks/uv-live_api-cloud_run.lock +0 -5832
- src/resources/setup_cicd/cicd_variables.tf +0 -41
- src/resources/setup_cicd/github.tf +0 -87
- {agents → agent_starter_pack/agents}/agentic_rag/app/retrievers.py +0 -0
- {agents → agent_starter_pack/agents}/agentic_rag/app/templates.py +0 -0
- {src → agent_starter_pack}/base_template/deployment/terraform/dev/vars/env.tfvars +0 -0
- {src → agent_starter_pack}/base_template/tests/unit/test_dummy.py +0 -0
- {src/deployment_targets/agent_engine/app/utils → agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils}/gcs.py +0 -0
- {src → agent_starter_pack}/cli/utils/__init__.py +0 -0
- {src → agent_starter_pack}/cli/utils/datastores.py +0 -0
- {src → agent_starter_pack}/cli/utils/version.py +0 -0
- {src → agent_starter_pack}/data_ingestion/README.md +0 -0
- {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/components/ingest_data.py +0 -0
- {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/pipeline.py +0 -0
- {src → agent_starter_pack}/deployment_targets/agent_engine/deployment_metadata.json +0 -0
- {src → agent_starter_pack}/deployment_targets/agent_engine/tests/load_test/.results/.placeholder +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/favicon.ico +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/index.html +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/robots.txt +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/App.scss +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/App.test.tsx +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/audio-pulse/AudioPulse.tsx +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/audio-pulse/audio-pulse.scss +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/mock-logs.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/contexts/LiveAPIContext.tsx +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-media-stream-mux.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-screen-capture.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-webcam.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/index.css +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/index.tsx +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/react-app-env.d.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/reportWebVitals.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/setupTests.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audioworklet-registry.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/store-logger.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/worklets/audio-processing.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/worklets/vol-meter.ts +0 -0
- {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/tsconfig.json +0 -0
- {agent_starter_pack-0.3.3.dist-info → agent_starter_pack-0.21.0.dist-info}/WHEEL +0 -0
- {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}")
|