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
|
@@ -1,217 +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 base64
|
|
16
|
-
from typing import Any
|
|
17
|
-
from urllib.parse import quote
|
|
18
|
-
|
|
19
|
-
from google.cloud import storage
|
|
20
|
-
|
|
21
|
-
HELP_MESSAGE_MULTIMODALITY = (
|
|
22
|
-
"For Gemini models to access the URIs you provide, store them in "
|
|
23
|
-
"Google Cloud Storage buckets within the same project used by Gemini."
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
HELP_GCS_CHECKBOX = (
|
|
27
|
-
"Enabling GCS upload will increase the app observability by avoiding"
|
|
28
|
-
" forwarding and logging large byte strings within the app."
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def format_content(content: str | list[dict[str, Any]]) -> str:
|
|
33
|
-
"""Formats content as a string, handling both text and multimedia inputs."""
|
|
34
|
-
if isinstance(content, str):
|
|
35
|
-
return content
|
|
36
|
-
if len(content) == 1 and content[0]["type"] == "text":
|
|
37
|
-
return content[0]["text"]
|
|
38
|
-
markdown = """Media:
|
|
39
|
-
"""
|
|
40
|
-
text = ""
|
|
41
|
-
for part in content:
|
|
42
|
-
if part["type"] == "text":
|
|
43
|
-
text = part["text"]
|
|
44
|
-
# Local Images:
|
|
45
|
-
if part["type"] == "image_url":
|
|
46
|
-
image_url = part["image_url"]["url"]
|
|
47
|
-
image_markdown = f'<img src="{image_url}" width="100">'
|
|
48
|
-
markdown = (
|
|
49
|
-
markdown
|
|
50
|
-
+ f"""
|
|
51
|
-
- {image_markdown}
|
|
52
|
-
"""
|
|
53
|
-
)
|
|
54
|
-
if part["type"] == "media":
|
|
55
|
-
# Local other media
|
|
56
|
-
if "data" in part:
|
|
57
|
-
markdown = markdown + f"- Local media: {part['file_name']}\n"
|
|
58
|
-
# From GCS:
|
|
59
|
-
if "file_uri" in part:
|
|
60
|
-
# GCS images
|
|
61
|
-
if "image" in part["mime_type"]:
|
|
62
|
-
image_url = gs_uri_to_https_url(part["file_uri"])
|
|
63
|
-
image_markdown = f'<img src="{image_url}" width="100">'
|
|
64
|
-
markdown = (
|
|
65
|
-
markdown
|
|
66
|
-
+ f"""
|
|
67
|
-
- {image_markdown}
|
|
68
|
-
"""
|
|
69
|
-
)
|
|
70
|
-
# GCS other media
|
|
71
|
-
else:
|
|
72
|
-
image_url = gs_uri_to_https_url(part["file_uri"])
|
|
73
|
-
markdown = (
|
|
74
|
-
markdown + f"- Remote media: "
|
|
75
|
-
f"[{part['file_uri']}]({image_url})\n"
|
|
76
|
-
)
|
|
77
|
-
markdown = (
|
|
78
|
-
markdown
|
|
79
|
-
+ f"""
|
|
80
|
-
|
|
81
|
-
{text}"""
|
|
82
|
-
)
|
|
83
|
-
return markdown
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def get_gcs_blob_mime_type(gcs_uri: str) -> str | None:
|
|
87
|
-
"""Fetches the MIME type (content type) of a Google Cloud Storage blob.
|
|
88
|
-
|
|
89
|
-
Args:
|
|
90
|
-
gcs_uri (str): The GCS URI of the blob in the format "gs://bucket-name/object-name".
|
|
91
|
-
|
|
92
|
-
Returns:
|
|
93
|
-
str: The MIME type of the blob (e.g., "image/jpeg", "text/plain") if found,
|
|
94
|
-
or None if the blob does not exist or an error occurs.
|
|
95
|
-
"""
|
|
96
|
-
storage_client = storage.Client()
|
|
97
|
-
|
|
98
|
-
try:
|
|
99
|
-
bucket_name, object_name = gcs_uri.replace("gs://", "").split("/", 1)
|
|
100
|
-
|
|
101
|
-
bucket = storage_client.bucket(bucket_name)
|
|
102
|
-
blob = bucket.blob(object_name)
|
|
103
|
-
blob.reload()
|
|
104
|
-
return blob.content_type
|
|
105
|
-
except Exception as e:
|
|
106
|
-
print(f"Error retrieving MIME type for {gcs_uri}: {e}")
|
|
107
|
-
return None # Indicate failure
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def get_parts_from_files(
|
|
111
|
-
upload_gcs_checkbox: bool, uploaded_files: list[Any], gcs_uris: str
|
|
112
|
-
) -> list[dict[str, Any]]:
|
|
113
|
-
"""Processes uploaded files and GCS URIs to create a list of content parts."""
|
|
114
|
-
parts = []
|
|
115
|
-
# read from local directly
|
|
116
|
-
if not upload_gcs_checkbox:
|
|
117
|
-
for uploaded_file in uploaded_files:
|
|
118
|
-
im_bytes = uploaded_file.read()
|
|
119
|
-
if "image" in uploaded_file.type:
|
|
120
|
-
content = {
|
|
121
|
-
"type": "image_url",
|
|
122
|
-
"image_url": {
|
|
123
|
-
"url": f"data:{uploaded_file.type};base64,"
|
|
124
|
-
f"{base64.b64encode(im_bytes).decode('utf-8')}"
|
|
125
|
-
},
|
|
126
|
-
"file_name": uploaded_file.name,
|
|
127
|
-
}
|
|
128
|
-
else:
|
|
129
|
-
content = {
|
|
130
|
-
"type": "media",
|
|
131
|
-
"data": base64.b64encode(im_bytes).decode("utf-8"),
|
|
132
|
-
"file_name": uploaded_file.name,
|
|
133
|
-
"mime_type": uploaded_file.type,
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
parts.append(content)
|
|
137
|
-
if gcs_uris != "":
|
|
138
|
-
for uri in gcs_uris.split(","):
|
|
139
|
-
content = {
|
|
140
|
-
"type": "media",
|
|
141
|
-
"file_uri": uri,
|
|
142
|
-
"mime_type": get_gcs_blob_mime_type(uri),
|
|
143
|
-
}
|
|
144
|
-
parts.append(content)
|
|
145
|
-
return parts
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def upload_bytes_to_gcs(
|
|
149
|
-
bucket_name: str,
|
|
150
|
-
blob_name: str,
|
|
151
|
-
file_bytes: bytes,
|
|
152
|
-
content_type: str | None = None,
|
|
153
|
-
) -> str:
|
|
154
|
-
"""Uploads a bytes object to Google Cloud Storage and returns the GCS URI.
|
|
155
|
-
|
|
156
|
-
Args:
|
|
157
|
-
bucket_name: The name of the GCS bucket.
|
|
158
|
-
blob_name: The desired name for the uploaded file in GCS.
|
|
159
|
-
file_bytes: The file's content as a bytes object.
|
|
160
|
-
content_type (optional): The MIME type of the file (e.g., "image/png").
|
|
161
|
-
If not provided, GCS will try to infer it.
|
|
162
|
-
|
|
163
|
-
Returns:
|
|
164
|
-
str: The GCS URI (gs://bucket_name/blob_name) of the uploaded file.
|
|
165
|
-
|
|
166
|
-
Raises:
|
|
167
|
-
GoogleCloudError: If there's an issue with the GCS operation.
|
|
168
|
-
"""
|
|
169
|
-
storage_client = storage.Client()
|
|
170
|
-
bucket = storage_client.bucket(bucket_name)
|
|
171
|
-
blob = bucket.blob(blob_name)
|
|
172
|
-
blob.upload_from_string(data=file_bytes, content_type=content_type)
|
|
173
|
-
# Construct and return the GCS URI
|
|
174
|
-
gcs_uri = f"gs://{bucket_name}/{blob_name}"
|
|
175
|
-
return gcs_uri
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def gs_uri_to_https_url(gs_uri: str) -> str:
|
|
179
|
-
"""Converts a GS URI to an HTTPS URL without authentication.
|
|
180
|
-
|
|
181
|
-
Args:
|
|
182
|
-
gs_uri: The GS URI in the format gs://<bucket>/<object>.
|
|
183
|
-
|
|
184
|
-
Returns:
|
|
185
|
-
The corresponding HTTPS URL, or None if the GS URI is invalid.
|
|
186
|
-
"""
|
|
187
|
-
|
|
188
|
-
if not gs_uri.startswith("gs://"):
|
|
189
|
-
raise ValueError("Invalid GS URI format")
|
|
190
|
-
|
|
191
|
-
gs_uri = gs_uri[5:]
|
|
192
|
-
|
|
193
|
-
# Extract bucket and object names, then URL encode the object name
|
|
194
|
-
bucket_name, object_name = gs_uri.split("/", 1)
|
|
195
|
-
object_name = quote(object_name)
|
|
196
|
-
|
|
197
|
-
# Construct the HTTPS URL
|
|
198
|
-
https_url = f"https://storage.mtls.cloud.google.com/{bucket_name}/{object_name}"
|
|
199
|
-
return https_url
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
def upload_files_to_gcs(st: Any, bucket_name: str, files_to_upload: list[Any]) -> None:
|
|
203
|
-
"""Upload multiple files to Google Cloud Storage and store URIs in session state."""
|
|
204
|
-
bucket_name = bucket_name.replace("gs://", "")
|
|
205
|
-
uploaded_uris = []
|
|
206
|
-
for file in files_to_upload:
|
|
207
|
-
if file:
|
|
208
|
-
file_bytes = file.read()
|
|
209
|
-
gcs_uri = upload_bytes_to_gcs(
|
|
210
|
-
bucket_name=bucket_name,
|
|
211
|
-
blob_name=file.name,
|
|
212
|
-
file_bytes=file_bytes,
|
|
213
|
-
content_type=file.type,
|
|
214
|
-
)
|
|
215
|
-
uploaded_uris.append(gcs_uri)
|
|
216
|
-
st.session_state.uploader_key += 1
|
|
217
|
-
st.session_state["gcs_uris_to_be_sent"] = ",".join(uploaded_uris)
|
|
@@ -1,301 +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
|
-
# mypy: disable-error-code="unreachable"
|
|
16
|
-
import importlib
|
|
17
|
-
import json
|
|
18
|
-
import uuid
|
|
19
|
-
from collections.abc import Generator
|
|
20
|
-
from typing import Any
|
|
21
|
-
from urllib.parse import urljoin
|
|
22
|
-
|
|
23
|
-
import google.auth
|
|
24
|
-
import google.auth.transport.requests
|
|
25
|
-
import google.oauth2.id_token
|
|
26
|
-
import requests
|
|
27
|
-
import streamlit as st
|
|
28
|
-
import vertexai
|
|
29
|
-
from google.auth.exceptions import DefaultCredentialsError
|
|
30
|
-
from langchain_core.messages import AIMessage, ToolMessage
|
|
31
|
-
from vertexai import agent_engines
|
|
32
|
-
|
|
33
|
-
from frontend.utils.multimodal_utils import format_content
|
|
34
|
-
|
|
35
|
-
st.cache_resource.clear()
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@st.cache_resource
|
|
39
|
-
def get_remote_agent(remote_agent_engine_id: str) -> Any:
|
|
40
|
-
"""Get cached remote agent instance."""
|
|
41
|
-
# Extract location and engine ID from the full resource ID.
|
|
42
|
-
parts = remote_agent_engine_id.split("/")
|
|
43
|
-
project_id = parts[1]
|
|
44
|
-
location = parts[3]
|
|
45
|
-
vertexai.init(project=project_id, location=location)
|
|
46
|
-
return agent_engines.AgentEngine(remote_agent_engine_id)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@st.cache_resource
|
|
50
|
-
def get_remote_url_config(url: str, authenticate_request: bool) -> dict[str, Any]:
|
|
51
|
-
"""Get cached remote URL agent configuration."""
|
|
52
|
-
stream_url = urljoin(url, "stream_messages")
|
|
53
|
-
creds, _ = google.auth.default()
|
|
54
|
-
id_token = None
|
|
55
|
-
if authenticate_request:
|
|
56
|
-
auth_req = google.auth.transport.requests.Request()
|
|
57
|
-
try:
|
|
58
|
-
id_token = google.oauth2.id_token.fetch_id_token(auth_req, stream_url)
|
|
59
|
-
except DefaultCredentialsError:
|
|
60
|
-
creds.refresh(auth_req)
|
|
61
|
-
id_token = creds.id_token
|
|
62
|
-
return {
|
|
63
|
-
"url": stream_url,
|
|
64
|
-
"authenticate_request": authenticate_request,
|
|
65
|
-
"creds": creds,
|
|
66
|
-
"id_token": id_token,
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@st.cache_resource()
|
|
71
|
-
def get_local_agent(agent_callable_path: str) -> Any:
|
|
72
|
-
"""Get cached local agent instance."""
|
|
73
|
-
module_path, class_name = agent_callable_path.rsplit(".", 1)
|
|
74
|
-
module = importlib.import_module(module_path)
|
|
75
|
-
agent = getattr(module, class_name)()
|
|
76
|
-
agent.set_up()
|
|
77
|
-
return agent
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class Client:
|
|
81
|
-
"""A client for streaming events from a server."""
|
|
82
|
-
|
|
83
|
-
def __init__(
|
|
84
|
-
self,
|
|
85
|
-
agent_callable_path: str | None = None,
|
|
86
|
-
remote_agent_engine_id: str | None = None,
|
|
87
|
-
url: str | None = None,
|
|
88
|
-
authenticate_request: bool = False,
|
|
89
|
-
) -> None:
|
|
90
|
-
"""Initialize the Client with appropriate configuration.
|
|
91
|
-
|
|
92
|
-
Args:
|
|
93
|
-
agent_callable_path: Path to local agent class
|
|
94
|
-
remote_agent_engine_id: ID of remote Agent engine
|
|
95
|
-
url: URL for remote service
|
|
96
|
-
authenticate_request: Whether to authenticate requests to remote URL
|
|
97
|
-
"""
|
|
98
|
-
if url:
|
|
99
|
-
remote_config = get_remote_url_config(url, authenticate_request)
|
|
100
|
-
self.url = remote_config["url"]
|
|
101
|
-
self.authenticate_request = remote_config["authenticate_request"]
|
|
102
|
-
self.creds = remote_config["creds"]
|
|
103
|
-
self.id_token = remote_config["id_token"]
|
|
104
|
-
self.agent = None
|
|
105
|
-
elif remote_agent_engine_id:
|
|
106
|
-
self.agent = get_remote_agent(remote_agent_engine_id)
|
|
107
|
-
self.url = None
|
|
108
|
-
else:
|
|
109
|
-
self.url = None
|
|
110
|
-
if agent_callable_path is None:
|
|
111
|
-
raise ValueError("agent_callable_path cannot be None")
|
|
112
|
-
self.agent = get_local_agent(agent_callable_path)
|
|
113
|
-
|
|
114
|
-
def log_feedback(self, feedback_dict: dict[str, Any], run_id: str) -> None:
|
|
115
|
-
"""Log user feedback for a specific run."""
|
|
116
|
-
score = feedback_dict["score"]
|
|
117
|
-
if score == "😞":
|
|
118
|
-
score = 0.0
|
|
119
|
-
elif score == "🙁":
|
|
120
|
-
score = 0.25
|
|
121
|
-
elif score == "😐":
|
|
122
|
-
score = 0.5
|
|
123
|
-
elif score == "🙂":
|
|
124
|
-
score = 0.75
|
|
125
|
-
elif score == "😀":
|
|
126
|
-
score = 1.0
|
|
127
|
-
feedback_dict["score"] = score
|
|
128
|
-
feedback_dict["run_id"] = run_id
|
|
129
|
-
feedback_dict["log_type"] = "feedback"
|
|
130
|
-
feedback_dict.pop("type")
|
|
131
|
-
url = urljoin(self.url, "feedback")
|
|
132
|
-
headers = {
|
|
133
|
-
"Content-Type": "application/json",
|
|
134
|
-
}
|
|
135
|
-
if self.url:
|
|
136
|
-
url = urljoin(self.url, "feedback")
|
|
137
|
-
headers = {
|
|
138
|
-
"Content-Type": "application/json",
|
|
139
|
-
}
|
|
140
|
-
if self.authenticate_request:
|
|
141
|
-
headers["Authorization"] = f"Bearer {self.id_token}"
|
|
142
|
-
requests.post(
|
|
143
|
-
url, data=json.dumps(feedback_dict), headers=headers, timeout=10
|
|
144
|
-
)
|
|
145
|
-
elif self.agent is not None:
|
|
146
|
-
self.agent.register_feedback(feedback=feedback_dict)
|
|
147
|
-
else:
|
|
148
|
-
raise ValueError("No agent or URL configured for feedback logging")
|
|
149
|
-
|
|
150
|
-
def stream_messages(
|
|
151
|
-
self, data: dict[str, Any]
|
|
152
|
-
) -> Generator[dict[str, Any], None, None]:
|
|
153
|
-
"""Stream events from the server, yielding parsed event data."""
|
|
154
|
-
if self.url:
|
|
155
|
-
headers = {
|
|
156
|
-
"Content-Type": "application/json",
|
|
157
|
-
"Accept": "text/event-stream",
|
|
158
|
-
}
|
|
159
|
-
if self.authenticate_request:
|
|
160
|
-
headers["Authorization"] = f"Bearer {self.id_token}"
|
|
161
|
-
with requests.post(
|
|
162
|
-
self.url, json=data, headers=headers, stream=True, timeout=60
|
|
163
|
-
) as response:
|
|
164
|
-
for line in response.iter_lines():
|
|
165
|
-
if line:
|
|
166
|
-
try:
|
|
167
|
-
event = json.loads(line.decode("utf-8"))
|
|
168
|
-
yield event
|
|
169
|
-
except json.JSONDecodeError:
|
|
170
|
-
print(f"Failed to parse event: {line.decode('utf-8')}")
|
|
171
|
-
elif self.agent is not None:
|
|
172
|
-
yield from self.agent.stream_query(**data)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
class StreamHandler:
|
|
176
|
-
"""Handles streaming updates to a Streamlit interface."""
|
|
177
|
-
|
|
178
|
-
def __init__(self, st: Any, initial_text: str = "") -> None:
|
|
179
|
-
"""Initialize the StreamHandler with Streamlit context and initial text."""
|
|
180
|
-
self.st = st
|
|
181
|
-
self.tool_expander = st.expander("Tool Calls:", expanded=False)
|
|
182
|
-
self.container = st.empty()
|
|
183
|
-
self.text = initial_text
|
|
184
|
-
self.tools_logs = initial_text
|
|
185
|
-
|
|
186
|
-
def new_token(self, token: str) -> None:
|
|
187
|
-
"""Add a new token to the main text display."""
|
|
188
|
-
self.text += token
|
|
189
|
-
self.container.markdown(format_content(self.text), unsafe_allow_html=True)
|
|
190
|
-
|
|
191
|
-
def new_status(self, status_update: str) -> None:
|
|
192
|
-
"""Add a new status update to the tool calls expander."""
|
|
193
|
-
self.tools_logs += status_update
|
|
194
|
-
self.tool_expander.markdown(status_update)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
class EventProcessor:
|
|
198
|
-
"""Processes events from the stream and updates the UI accordingly."""
|
|
199
|
-
|
|
200
|
-
def __init__(self, st: Any, client: Client, stream_handler: StreamHandler) -> None:
|
|
201
|
-
"""Initialize the EventProcessor with Streamlit context, client, and stream handler."""
|
|
202
|
-
self.st = st
|
|
203
|
-
self.client = client
|
|
204
|
-
self.stream_handler = stream_handler
|
|
205
|
-
self.final_content = ""
|
|
206
|
-
self.tool_calls: list[dict[str, Any]] = []
|
|
207
|
-
self.current_run_id: str | None = None
|
|
208
|
-
self.additional_kwargs: dict[str, Any] = {}
|
|
209
|
-
|
|
210
|
-
def process_events(self) -> None:
|
|
211
|
-
"""Process events from the stream, handling each event type appropriately."""
|
|
212
|
-
messages = self.st.session_state.user_chats[
|
|
213
|
-
self.st.session_state["session_id"]
|
|
214
|
-
]["messages"]
|
|
215
|
-
self.current_run_id = str(uuid.uuid4())
|
|
216
|
-
# Set run_id in session state at start of processing
|
|
217
|
-
self.st.session_state["run_id"] = self.current_run_id
|
|
218
|
-
stream = self.client.stream_messages(
|
|
219
|
-
data={
|
|
220
|
-
"input": {"messages": messages},
|
|
221
|
-
"config": {
|
|
222
|
-
"run_id": self.current_run_id,
|
|
223
|
-
"metadata": {
|
|
224
|
-
"user_id": self.st.session_state["user_id"],
|
|
225
|
-
"session_id": self.st.session_state["session_id"],
|
|
226
|
-
},
|
|
227
|
-
},
|
|
228
|
-
}
|
|
229
|
-
)
|
|
230
|
-
# Each event is a tuple message, metadata. https://langchain-ai.github.io/langgraph/how-tos/streaming/#messages
|
|
231
|
-
for message, _ in stream:
|
|
232
|
-
if isinstance(message, dict):
|
|
233
|
-
if message.get("type") == "constructor":
|
|
234
|
-
message = message["kwargs"]
|
|
235
|
-
|
|
236
|
-
# Handle tool calls
|
|
237
|
-
if message.get("tool_calls"):
|
|
238
|
-
tool_calls = message["tool_calls"]
|
|
239
|
-
ai_message = AIMessage(content="", tool_calls=tool_calls)
|
|
240
|
-
self.tool_calls.append(ai_message.model_dump())
|
|
241
|
-
for tool_call in tool_calls:
|
|
242
|
-
msg = f"\n\nCalling tool: `{tool_call['name']}` with args: `{tool_call['args']}`"
|
|
243
|
-
self.stream_handler.new_status(msg)
|
|
244
|
-
|
|
245
|
-
# Handle tool responses
|
|
246
|
-
elif message.get("tool_call_id"):
|
|
247
|
-
content = message["content"]
|
|
248
|
-
tool_call_id = message["tool_call_id"]
|
|
249
|
-
tool_message = ToolMessage(
|
|
250
|
-
content=content, type="tool", tool_call_id=tool_call_id
|
|
251
|
-
).model_dump()
|
|
252
|
-
self.tool_calls.append(tool_message)
|
|
253
|
-
msg = f"\n\nTool response: `{content}`"
|
|
254
|
-
self.stream_handler.new_status(msg)
|
|
255
|
-
|
|
256
|
-
# Handle AI responses
|
|
257
|
-
elif content := message.get("content"):
|
|
258
|
-
self.final_content += content
|
|
259
|
-
self.stream_handler.new_token(content)
|
|
260
|
-
|
|
261
|
-
# Handle end of stream
|
|
262
|
-
if self.final_content:
|
|
263
|
-
final_message = AIMessage(
|
|
264
|
-
content=self.final_content,
|
|
265
|
-
id=self.current_run_id,
|
|
266
|
-
additional_kwargs=self.additional_kwargs,
|
|
267
|
-
).model_dump()
|
|
268
|
-
session = self.st.session_state["session_id"]
|
|
269
|
-
self.st.session_state.user_chats[session]["messages"] = (
|
|
270
|
-
self.st.session_state.user_chats[session]["messages"] + self.tool_calls
|
|
271
|
-
)
|
|
272
|
-
self.st.session_state.user_chats[session]["messages"].append(final_message)
|
|
273
|
-
self.st.session_state.run_id = self.current_run_id
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
def get_chain_response(st: Any, client: Client, stream_handler: StreamHandler) -> None:
|
|
277
|
-
"""Process the chain response update the Streamlit UI.
|
|
278
|
-
|
|
279
|
-
This function initiates the event processing for a chain of operations,
|
|
280
|
-
involving an AI model's response generation and potential tool calls.
|
|
281
|
-
It creates an EventProcessor instance and starts the event processing loop.
|
|
282
|
-
|
|
283
|
-
Args:
|
|
284
|
-
st (Any): The Streamlit app instance, used for accessing session state
|
|
285
|
-
and updating the UI.
|
|
286
|
-
client (Client): An instance of the Client class used to stream events
|
|
287
|
-
from the server.
|
|
288
|
-
stream_handler (StreamHandler): An instance of the StreamHandler class
|
|
289
|
-
used to update the Streamlit UI with
|
|
290
|
-
streaming content.
|
|
291
|
-
|
|
292
|
-
Returns:
|
|
293
|
-
None
|
|
294
|
-
|
|
295
|
-
Side effects:
|
|
296
|
-
- Updates the Streamlit UI with streaming tokens and tool call information.
|
|
297
|
-
- Modifies the session state to include the final AI message and run ID.
|
|
298
|
-
- Handles various events like chain starts/ends, tool calls, and model outputs.
|
|
299
|
-
"""
|
|
300
|
-
processor = EventProcessor(st, client, stream_handler)
|
|
301
|
-
processor.process_events()
|
|
@@ -1,94 +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
|
-
# mypy: disable-error-code="assignment"
|
|
16
|
-
import os
|
|
17
|
-
from typing import Any
|
|
18
|
-
|
|
19
|
-
import google.auth
|
|
20
|
-
from langchain_core.messages import AIMessage
|
|
21
|
-
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
|
22
|
-
from langchain_google_vertexai import ChatVertexAI
|
|
23
|
-
|
|
24
|
-
title_template = ChatPromptTemplate.from_messages(
|
|
25
|
-
[
|
|
26
|
-
(
|
|
27
|
-
"system",
|
|
28
|
-
"""Given a list of messages between a human and AI, come up with a short and relevant title for the conversation. Use up to 10 words. The title needs to be concise.
|
|
29
|
-
Examples:
|
|
30
|
-
**Input:**
|
|
31
|
-
```
|
|
32
|
-
Human: hi, what is the best italian dish?
|
|
33
|
-
AI: That's a tough one! Italy has so many amazing dishes, it's hard to pick just one "best." To help me give you a great suggestion, tell me a little more about what you're looking for.
|
|
34
|
-
```
|
|
35
|
-
**Output:** Best italian dish
|
|
36
|
-
|
|
37
|
-
**Input:**
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
Human: How to fix a broken laptop screen?
|
|
41
|
-
AI: Fixing a broken laptop screen can be tricky and often requires professional help. However, there are a few things you can try at home before resorting to a repair shop.
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
**Output:** Fixing a broken laptop screen
|
|
45
|
-
|
|
46
|
-
**Input:**
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
Human: Can you write me a poem about the beach?
|
|
50
|
-
AI: As the sun dips down below the horizon
|
|
51
|
-
And the waves gently kiss the shore,
|
|
52
|
-
I sit here and watch the ocean
|
|
53
|
-
And feel its power evermore.
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
**Output:** Poem about the beach
|
|
57
|
-
|
|
58
|
-
**Input:**
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
Human: What's the best way to learn to code?
|
|
62
|
-
AI: There are many ways to learn to code, and the best method for you will depend on your learning style and goals.
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
**Output:** How to learn to code
|
|
66
|
-
|
|
67
|
-
If there's not enough context in the conversation to create a meaningful title, create a generic title like "New Conversation", or "A simple greeting".
|
|
68
|
-
|
|
69
|
-
""",
|
|
70
|
-
),
|
|
71
|
-
MessagesPlaceholder(variable_name="messages"),
|
|
72
|
-
]
|
|
73
|
-
)
|
|
74
|
-
try:
|
|
75
|
-
# Initialize Vertex AI with default project credentials
|
|
76
|
-
_, project_id = google.auth.default()
|
|
77
|
-
|
|
78
|
-
llm = ChatVertexAI(
|
|
79
|
-
model_name="gemini-2.0-flash-001",
|
|
80
|
-
temperature=0,
|
|
81
|
-
project=project_id,
|
|
82
|
-
location=os.getenv("LOCATION", "us-central1"),
|
|
83
|
-
)
|
|
84
|
-
chain_title = title_template | llm
|
|
85
|
-
|
|
86
|
-
except Exception:
|
|
87
|
-
# Fallback to a simple title generator when Vertex AI is unavailable
|
|
88
|
-
print("WARNING: Failed to initialize Vertex AI. Using dummy LLM instead.")
|
|
89
|
-
|
|
90
|
-
class DummyChain:
|
|
91
|
-
def invoke(*args: Any, **kwargs: Any) -> AIMessage:
|
|
92
|
-
return AIMessage(content="conversation")
|
|
93
|
-
|
|
94
|
-
chain_title = DummyChain()
|