agent-starter-pack 0.0.1b0__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.
Potentially problematic release.
This version of agent-starter-pack might be problematic. Click here for more details.
- agent_starter_pack-0.0.1b0.dist-info/METADATA +143 -0
- agent_starter_pack-0.0.1b0.dist-info/RECORD +162 -0
- agent_starter_pack-0.0.1b0.dist-info/WHEEL +4 -0
- agent_starter_pack-0.0.1b0.dist-info/entry_points.txt +2 -0
- agent_starter_pack-0.0.1b0.dist-info/licenses/LICENSE +201 -0
- agents/agentic_rag_vertexai_search/README.md +22 -0
- agents/agentic_rag_vertexai_search/app/agent.py +145 -0
- agents/agentic_rag_vertexai_search/app/retrievers.py +79 -0
- agents/agentic_rag_vertexai_search/app/templates.py +53 -0
- agents/agentic_rag_vertexai_search/notebooks/evaluating_langgraph_agent.ipynb +1561 -0
- agents/agentic_rag_vertexai_search/template/.templateconfig.yaml +14 -0
- agents/agentic_rag_vertexai_search/tests/integration/test_agent.py +57 -0
- agents/crewai_coding_crew/README.md +34 -0
- agents/crewai_coding_crew/app/agent.py +86 -0
- agents/crewai_coding_crew/app/crew/config/agents.yaml +39 -0
- agents/crewai_coding_crew/app/crew/config/tasks.yaml +37 -0
- agents/crewai_coding_crew/app/crew/crew.py +71 -0
- agents/crewai_coding_crew/notebooks/evaluating_crewai_agent.ipynb +1571 -0
- agents/crewai_coding_crew/notebooks/evaluating_langgraph_agent.ipynb +1561 -0
- agents/crewai_coding_crew/template/.templateconfig.yaml +12 -0
- agents/crewai_coding_crew/tests/integration/test_agent.py +47 -0
- agents/langgraph_base_react/README.md +9 -0
- agents/langgraph_base_react/app/agent.py +73 -0
- agents/langgraph_base_react/notebooks/evaluating_langgraph_agent.ipynb +1561 -0
- agents/langgraph_base_react/template/.templateconfig.yaml +13 -0
- agents/langgraph_base_react/tests/integration/test_agent.py +48 -0
- agents/multimodal_live_api/README.md +50 -0
- agents/multimodal_live_api/app/agent.py +86 -0
- agents/multimodal_live_api/app/server.py +193 -0
- agents/multimodal_live_api/app/templates.py +51 -0
- agents/multimodal_live_api/app/vector_store.py +55 -0
- agents/multimodal_live_api/template/.templateconfig.yaml +15 -0
- agents/multimodal_live_api/tests/integration/test_server_e2e.py +254 -0
- agents/multimodal_live_api/tests/load_test/load_test.py +40 -0
- agents/multimodal_live_api/tests/unit/test_server.py +143 -0
- src/base_template/.gitignore +197 -0
- src/base_template/Makefile +37 -0
- src/base_template/README.md +91 -0
- src/base_template/app/utils/tracing.py +143 -0
- src/base_template/app/utils/typing.py +115 -0
- src/base_template/deployment/README.md +123 -0
- src/base_template/deployment/cd/deploy-to-prod.yaml +98 -0
- src/base_template/deployment/cd/staging.yaml +215 -0
- src/base_template/deployment/ci/pr_checks.yaml +51 -0
- src/base_template/deployment/terraform/apis.tf +34 -0
- src/base_template/deployment/terraform/build_triggers.tf +122 -0
- src/base_template/deployment/terraform/dev/apis.tf +42 -0
- src/base_template/deployment/terraform/dev/iam.tf +90 -0
- src/base_template/deployment/terraform/dev/log_sinks.tf +66 -0
- src/base_template/deployment/terraform/dev/providers.tf +29 -0
- src/base_template/deployment/terraform/dev/storage.tf +76 -0
- src/base_template/deployment/terraform/dev/variables.tf +126 -0
- src/base_template/deployment/terraform/dev/vars/env.tfvars +21 -0
- src/base_template/deployment/terraform/iam.tf +130 -0
- src/base_template/deployment/terraform/locals.tf +50 -0
- src/base_template/deployment/terraform/log_sinks.tf +72 -0
- src/base_template/deployment/terraform/providers.tf +35 -0
- src/base_template/deployment/terraform/service_accounts.tf +42 -0
- src/base_template/deployment/terraform/storage.tf +100 -0
- src/base_template/deployment/terraform/variables.tf +202 -0
- src/base_template/deployment/terraform/vars/env.tfvars +43 -0
- src/base_template/pyproject.toml +113 -0
- src/base_template/tests/unit/test_utils/test_tracing_exporter.py +140 -0
- src/cli/commands/create.py +534 -0
- src/cli/commands/setup_cicd.py +730 -0
- src/cli/main.py +35 -0
- src/cli/utils/__init__.py +35 -0
- src/cli/utils/cicd.py +662 -0
- src/cli/utils/gcp.py +120 -0
- src/cli/utils/logging.py +51 -0
- src/cli/utils/template.py +644 -0
- src/data_ingestion/README.md +79 -0
- src/data_ingestion/data_ingestion_pipeline/components/ingest_data.py +175 -0
- src/data_ingestion/data_ingestion_pipeline/components/process_data.py +321 -0
- src/data_ingestion/data_ingestion_pipeline/pipeline.py +58 -0
- src/data_ingestion/data_ingestion_pipeline/submit_pipeline.py +184 -0
- src/data_ingestion/pyproject.toml +17 -0
- src/data_ingestion/uv.lock +999 -0
- src/deployment_targets/agent_engine/app/agent_engine_app.py +238 -0
- src/deployment_targets/agent_engine/app/utils/gcs.py +42 -0
- src/deployment_targets/agent_engine/deployment_metadata.json +4 -0
- src/deployment_targets/agent_engine/notebooks/intro_reasoning_engine.ipynb +869 -0
- src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +120 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/.placeholder +0 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/report.html +264 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/results_exceptions.csv +1 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/results_failures.csv +1 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/results_stats.csv +3 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/results_stats_history.csv +22 -0
- src/deployment_targets/agent_engine/tests/load_test/README.md +42 -0
- src/deployment_targets/agent_engine/tests/load_test/load_test.py +100 -0
- src/deployment_targets/agent_engine/tests/unit/test_dummy.py +22 -0
- src/deployment_targets/cloud_run/Dockerfile +29 -0
- src/deployment_targets/cloud_run/app/server.py +128 -0
- src/deployment_targets/cloud_run/deployment/terraform/artifact_registry.tf +22 -0
- src/deployment_targets/cloud_run/deployment/terraform/dev/service_accounts.tf +20 -0
- src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +192 -0
- src/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +0 -0
- src/deployment_targets/cloud_run/tests/load_test/README.md +79 -0
- src/deployment_targets/cloud_run/tests/load_test/load_test.py +85 -0
- src/deployment_targets/cloud_run/tests/unit/test_server.py +142 -0
- src/deployment_targets/cloud_run/uv.lock +6952 -0
- src/frontends/live_api_react/frontend/package-lock.json +19405 -0
- src/frontends/live_api_react/frontend/package.json +56 -0
- src/frontends/live_api_react/frontend/public/favicon.ico +0 -0
- src/frontends/live_api_react/frontend/public/index.html +62 -0
- src/frontends/live_api_react/frontend/public/robots.txt +3 -0
- src/frontends/live_api_react/frontend/src/App.scss +189 -0
- src/frontends/live_api_react/frontend/src/App.test.tsx +25 -0
- src/frontends/live_api_react/frontend/src/App.tsx +205 -0
- src/frontends/live_api_react/frontend/src/components/audio-pulse/AudioPulse.tsx +64 -0
- src/frontends/live_api_react/frontend/src/components/audio-pulse/audio-pulse.scss +68 -0
- src/frontends/live_api_react/frontend/src/components/control-tray/ControlTray.tsx +217 -0
- src/frontends/live_api_react/frontend/src/components/control-tray/control-tray.scss +201 -0
- src/frontends/live_api_react/frontend/src/components/logger/Logger.tsx +241 -0
- src/frontends/live_api_react/frontend/src/components/logger/logger.scss +133 -0
- src/frontends/live_api_react/frontend/src/components/logger/mock-logs.ts +151 -0
- src/frontends/live_api_react/frontend/src/components/side-panel/SidePanel.tsx +161 -0
- src/frontends/live_api_react/frontend/src/components/side-panel/side-panel.scss +285 -0
- src/frontends/live_api_react/frontend/src/contexts/LiveAPIContext.tsx +48 -0
- src/frontends/live_api_react/frontend/src/hooks/use-live-api.ts +115 -0
- src/frontends/live_api_react/frontend/src/hooks/use-media-stream-mux.ts +23 -0
- src/frontends/live_api_react/frontend/src/hooks/use-screen-capture.ts +72 -0
- src/frontends/live_api_react/frontend/src/hooks/use-webcam.ts +69 -0
- src/frontends/live_api_react/frontend/src/index.css +28 -0
- src/frontends/live_api_react/frontend/src/index.tsx +35 -0
- src/frontends/live_api_react/frontend/src/multimodal-live-types.ts +242 -0
- src/frontends/live_api_react/frontend/src/react-app-env.d.ts +17 -0
- src/frontends/live_api_react/frontend/src/reportWebVitals.ts +31 -0
- src/frontends/live_api_react/frontend/src/setupTests.ts +21 -0
- src/frontends/live_api_react/frontend/src/utils/audio-recorder.ts +111 -0
- src/frontends/live_api_react/frontend/src/utils/audio-streamer.ts +270 -0
- src/frontends/live_api_react/frontend/src/utils/audioworklet-registry.ts +43 -0
- src/frontends/live_api_react/frontend/src/utils/multimodal-live-client.ts +329 -0
- src/frontends/live_api_react/frontend/src/utils/store-logger.ts +64 -0
- src/frontends/live_api_react/frontend/src/utils/utils.ts +86 -0
- src/frontends/live_api_react/frontend/src/utils/worklets/audio-processing.ts +73 -0
- src/frontends/live_api_react/frontend/src/utils/worklets/vol-meter.ts +65 -0
- src/frontends/live_api_react/frontend/tsconfig.json +25 -0
- src/frontends/streamlit/frontend/side_bar.py +213 -0
- src/frontends/streamlit/frontend/streamlit_app.py +263 -0
- src/frontends/streamlit/frontend/style/app_markdown.py +37 -0
- src/frontends/streamlit/frontend/utils/chat_utils.py +67 -0
- src/frontends/streamlit/frontend/utils/local_chat_history.py +125 -0
- src/frontends/streamlit/frontend/utils/message_editing.py +59 -0
- src/frontends/streamlit/frontend/utils/multimodal_utils.py +217 -0
- src/frontends/streamlit/frontend/utils/stream_handler.py +282 -0
- src/frontends/streamlit/frontend/utils/title_summary.py +77 -0
- src/resources/containers/data_processing/Dockerfile +25 -0
- src/resources/locks/uv-agentic_rag_vertexai_search-agent_engine.lock +4684 -0
- src/resources/locks/uv-agentic_rag_vertexai_search-cloud_run.lock +5799 -0
- src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +5509 -0
- src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +6688 -0
- src/resources/locks/uv-langgraph_base_react-agent_engine.lock +4595 -0
- src/resources/locks/uv-langgraph_base_react-cloud_run.lock +5710 -0
- src/resources/locks/uv-multimodal_live_api-cloud_run.lock +5665 -0
- src/resources/setup_cicd/cicd_variables.tf +36 -0
- src/resources/setup_cicd/github.tf +85 -0
- src/resources/setup_cicd/providers.tf +39 -0
- src/utils/generate_locks.py +135 -0
- src/utils/lock_utils.py +82 -0
- src/utils/watch_and_rebuild.py +190 -0
|
@@ -0,0 +1,202 @@
|
|
|
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
|
+
variable "prod_project_id" {
|
|
16
|
+
type = string
|
|
17
|
+
description = "**Production** Google Cloud Project ID for resource deployment."
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
variable "staging_project_id" {
|
|
21
|
+
type = string
|
|
22
|
+
description = "**Staging** Google Cloud Project ID for resource deployment."
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
variable "cicd_runner_project_id" {
|
|
26
|
+
type = string
|
|
27
|
+
description = "Google Cloud Project ID where CI/CD pipelines will execute."
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
variable "region" {
|
|
31
|
+
type = string
|
|
32
|
+
description = "Google Cloud region for resource deployment."
|
|
33
|
+
default = "us-central1"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
variable "host_connection_name" {
|
|
37
|
+
description = "Name of the host connection you created in Cloud Build"
|
|
38
|
+
type = string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
variable "repository_name" {
|
|
42
|
+
description = "Name of the repository you'd like to connect to Cloud Build"
|
|
43
|
+
type = string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
variable "telemetry_bigquery_dataset_id" {
|
|
47
|
+
type = string
|
|
48
|
+
description = "BigQuery dataset ID for telemetry data export."
|
|
49
|
+
default = "telemetry_genai_app_sample_sink"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
variable "feedback_bigquery_dataset_id" {
|
|
53
|
+
type = string
|
|
54
|
+
description = "BigQuery dataset ID for feedback data export."
|
|
55
|
+
default = "feedback_genai_app_sample_sink"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
variable "telemetry_logs_filter" {
|
|
59
|
+
type = string
|
|
60
|
+
description = "Log Sink filter for capturing telemetry data. Captures logs with the `traceloop.association.properties.log_type` attribute set to `tracing`."
|
|
61
|
+
default = "jsonPayload.attributes.\"traceloop.association.properties.log_type\"=\"tracing\" jsonPayload.resource.attributes.\"service.name\"=\"Sample Chatbot Application\""
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
variable "feedback_logs_filter" {
|
|
65
|
+
type = string
|
|
66
|
+
description = "Log Sink filter for capturing feedback data. Captures logs where the `log_type` field is `feedback`."
|
|
67
|
+
default = "jsonPayload.log_type=\"feedback\""
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
variable "telemetry_sink_name" {
|
|
71
|
+
type = string
|
|
72
|
+
description = "Name of the telemetry data Log Sink."
|
|
73
|
+
default = "telemetry_logs_genai_app_sample"
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
variable "feedback_sink_name" {
|
|
77
|
+
type = string
|
|
78
|
+
description = "Name of the feedback data Log Sink."
|
|
79
|
+
default = "feedback_logs_genai_app_sample"
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
variable "cicd_runner_sa_name" {
|
|
83
|
+
description = "Service account name to be used for the CICD processes"
|
|
84
|
+
type = string
|
|
85
|
+
default = "cicd-runner"
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
variable "suffix_bucket_name_load_test_results" {
|
|
89
|
+
description = "Suffix Name of the bucket that will be used to store the results of the load test. Prefix will be project id."
|
|
90
|
+
type = string
|
|
91
|
+
default = "cicd-load-test-results"
|
|
92
|
+
}
|
|
93
|
+
{%- if cookiecutter.deployment_target == 'cloud_run' %}
|
|
94
|
+
variable "cloud_run_app_sa_name" {
|
|
95
|
+
description = "Service account name to be used for the Cloud Run service"
|
|
96
|
+
type = string
|
|
97
|
+
default = "{{cookiecutter.project_name}}-cr"
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
variable "artifact_registry_repo_name" {
|
|
101
|
+
description = "Name of the Artifact registry repository to be used to push containers"
|
|
102
|
+
type = string
|
|
103
|
+
default = "genai-containers"
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
variable "cloud_run_app_roles" {
|
|
107
|
+
description = "List of roles to assign to the Cloud Run app service account"
|
|
108
|
+
{%- elif cookiecutter.deployment_target == 'agent_engine' %}
|
|
109
|
+
variable "agentengine_sa_roles" {
|
|
110
|
+
description = "List of roles to assign to the Agent Engine service account"
|
|
111
|
+
{%- endif %}
|
|
112
|
+
type = list(string)
|
|
113
|
+
default = [
|
|
114
|
+
{%- if cookiecutter.deployment_target == 'cloud_run' %}
|
|
115
|
+
"roles/run.invoker",
|
|
116
|
+
{%- endif %}
|
|
117
|
+
"roles/aiplatform.user",
|
|
118
|
+
"roles/discoveryengine.editor",
|
|
119
|
+
"roles/logging.logWriter",
|
|
120
|
+
"roles/cloudtrace.agent",
|
|
121
|
+
"roles/storage.admin"
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
variable "cicd_roles" {
|
|
126
|
+
description = "List of roles to assign to the CICD runner service account in the CICD project"
|
|
127
|
+
type = list(string)
|
|
128
|
+
default = [
|
|
129
|
+
{%- if cookiecutter.deployment_target == 'cloud_run' %}
|
|
130
|
+
"roles/run.invoker",
|
|
131
|
+
{%- endif %}
|
|
132
|
+
"roles/storage.admin",
|
|
133
|
+
"roles/aiplatform.user",
|
|
134
|
+
"roles/discoveryengine.editor",
|
|
135
|
+
"roles/logging.logWriter",
|
|
136
|
+
"roles/cloudtrace.agent",
|
|
137
|
+
"roles/artifactregistry.writer",
|
|
138
|
+
"roles/cloudbuild.builds.builder"
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
variable "cicd_sa_deployment_required_roles" {
|
|
143
|
+
description = "List of roles to assign to the CICD runner service account for the Staging and Prod projects."
|
|
144
|
+
type = list(string)
|
|
145
|
+
default = [
|
|
146
|
+
{%- if cookiecutter.deployment_target == 'cloud_run' %}
|
|
147
|
+
"roles/run.developer",
|
|
148
|
+
{%- endif %}
|
|
149
|
+
"roles/iam.serviceAccountUser",
|
|
150
|
+
"roles/aiplatform.user",
|
|
151
|
+
"roles/storage.admin"
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
{%- if cookiecutter.data_ingestion %}
|
|
156
|
+
variable "vertexai_pipeline_sa_name" {
|
|
157
|
+
description = "Service account name to be used for the Vertex AI service"
|
|
158
|
+
type = string
|
|
159
|
+
default = "data-ingestion-vertexai-sa"
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
variable "pipeline_cron_schedule" {
|
|
163
|
+
type = string
|
|
164
|
+
description = "Cron expression defining the schedule for automated data ingestion."
|
|
165
|
+
default = "0 0 * * 0" # Run at 00:00 UTC every Sunday
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
variable "data_store_region" {
|
|
169
|
+
type = string
|
|
170
|
+
description = "Google Cloud region for resource deployment."
|
|
171
|
+
default = "us"
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
variable "pipelines_roles" {
|
|
175
|
+
description = "List of roles to assign to the Vertex AI Pipelines service account"
|
|
176
|
+
type = list(string)
|
|
177
|
+
default = [
|
|
178
|
+
"roles/storage.admin",
|
|
179
|
+
"roles/aiplatform.user",
|
|
180
|
+
"roles/discoveryengine.admin",
|
|
181
|
+
"roles/logging.logWriter",
|
|
182
|
+
"roles/artifactregistry.writer",
|
|
183
|
+
"roles/bigquery.dataEditor",
|
|
184
|
+
"roles/bigquery.jobUser",
|
|
185
|
+
"roles/bigquery.readSessionUser",
|
|
186
|
+
"roles/bigquery.connectionAdmin",
|
|
187
|
+
"roles/resourcemanager.projectIamAdmin"
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
variable "datastore_name" {
|
|
192
|
+
description = "The name of the datastore"
|
|
193
|
+
type = string
|
|
194
|
+
default = "sample-datastore"
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
variable "search_engine_name" {
|
|
198
|
+
description = "The name of the search engine"
|
|
199
|
+
type = string
|
|
200
|
+
default = "sample-search-engine"
|
|
201
|
+
}
|
|
202
|
+
{%- endif %}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Your Production Google Cloud project id
|
|
2
|
+
prod_project_id = "your-production-project-id"
|
|
3
|
+
|
|
4
|
+
# Your Staging / Test Google Cloud project id
|
|
5
|
+
staging_project_id = "your-staging-project-id"
|
|
6
|
+
|
|
7
|
+
# Your Google Cloud project ID that will be used to host the Cloud Build pipelines.
|
|
8
|
+
cicd_runner_project_id = "your-cicd-project-id"
|
|
9
|
+
|
|
10
|
+
# Name of the host connection you created in Cloud Build
|
|
11
|
+
host_connection_name = "your-host-connection-name"
|
|
12
|
+
|
|
13
|
+
# Name of the repository you added to Cloud Build
|
|
14
|
+
repository_name = "your-repository-name"
|
|
15
|
+
|
|
16
|
+
# The Google Cloud region you will use to deploy the infrastructure
|
|
17
|
+
region = "us-central1"
|
|
18
|
+
|
|
19
|
+
{%- if cookiecutter.deployment_target == 'cloud_run' %}
|
|
20
|
+
cloud_run_app_sa_name = "{{cookiecutter.project_name}}-cr"
|
|
21
|
+
{%- endif %}
|
|
22
|
+
|
|
23
|
+
telemetry_bigquery_dataset_id = "telemetry_genai_app_sample_sink"
|
|
24
|
+
telemetry_sink_name = "telemetry_logs_genai_app_sample"
|
|
25
|
+
telemetry_logs_filter = "jsonPayload.attributes.\"traceloop.association.properties.log_type\"=\"tracing\" jsonPayload.resource.attributes.\"service.name\"=\"Sample Chatbot Application\""
|
|
26
|
+
|
|
27
|
+
feedback_bigquery_dataset_id = "feedback_genai_app_sample_sink"
|
|
28
|
+
feedback_sink_name = "feedback_logs_genai_app_sample"
|
|
29
|
+
feedback_logs_filter = "jsonPayload.log_type=\"feedback\""
|
|
30
|
+
|
|
31
|
+
cicd_runner_sa_name = "cicd-runner"
|
|
32
|
+
|
|
33
|
+
suffix_bucket_name_load_test_results = "cicd-load-test-results"
|
|
34
|
+
|
|
35
|
+
{%- if cookiecutter.data_ingestion %}
|
|
36
|
+
search_engine_name = "sample-search-engine"
|
|
37
|
+
datastore_name = "sample-datastore"
|
|
38
|
+
vertexai_pipeline_sa_name = "vertexai-pipelines-sa"
|
|
39
|
+
pipeline_cron_schedule = "0 0 * * 0"
|
|
40
|
+
|
|
41
|
+
#The value can only be one of "global", "us" and "eu".
|
|
42
|
+
data_store_region = "us"
|
|
43
|
+
{%- endif %}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "{{cookiecutter.project_name}}"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = ""
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "Your Name", email = "your@email.com"},
|
|
7
|
+
]
|
|
8
|
+
dependencies = [
|
|
9
|
+
{%- for dep in cookiecutter.extra_dependencies %}
|
|
10
|
+
"{{ dep }}",
|
|
11
|
+
{%- endfor %}
|
|
12
|
+
"langchain-core~=0.3.9",
|
|
13
|
+
"opentelemetry-exporter-gcp-trace~=1.9.0",
|
|
14
|
+
"traceloop-sdk~=0.38.7",
|
|
15
|
+
"google-cloud-logging~=3.11.4",
|
|
16
|
+
{%- if cookiecutter.deployment_target == 'cloud_run' %}
|
|
17
|
+
"google-cloud-aiplatform[evaluation]~=1.80.0",
|
|
18
|
+
"fastapi~=0.115.8",
|
|
19
|
+
"uvicorn~=0.34.0"
|
|
20
|
+
{%- elif cookiecutter.deployment_target == 'agent_engine' %}
|
|
21
|
+
"google-cloud-aiplatform[evaluation,langchain,reasoningengine]~=1.77.0"
|
|
22
|
+
{%- endif %}
|
|
23
|
+
]
|
|
24
|
+
{% if cookiecutter.deployment_target == 'cloud_run' %}
|
|
25
|
+
requires-python = ">=3.10,<=3.13"
|
|
26
|
+
{% elif cookiecutter.deployment_target == 'agent_engine' %}
|
|
27
|
+
requires-python = ">=3.10,<=3.11"
|
|
28
|
+
{%- endif %}
|
|
29
|
+
|
|
30
|
+
[dependency-groups]
|
|
31
|
+
dev = [
|
|
32
|
+
"pytest>=8.3.4",
|
|
33
|
+
"pytest-asyncio>=0.23.8",
|
|
34
|
+
"nest-asyncio>=1.6.0",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
streamlit = [
|
|
39
|
+
"streamlit~=1.42.0",
|
|
40
|
+
"streamlit-extras~=0.4.3",
|
|
41
|
+
"extra-streamlit-components~=0.1.71",
|
|
42
|
+
"streamlit-feedback~=0.1.3",
|
|
43
|
+
]
|
|
44
|
+
jupyter = [
|
|
45
|
+
"jupyter~=1.0.0",
|
|
46
|
+
]
|
|
47
|
+
lint = [
|
|
48
|
+
"ruff>=0.4.6",
|
|
49
|
+
"mypy~=1.15.0",
|
|
50
|
+
"codespell~=2.2.0",
|
|
51
|
+
"types-pyyaml~=6.0.12.20240917",
|
|
52
|
+
"types-requests~=2.32.0.20240914",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[tool.ruff]
|
|
56
|
+
line-length = 88
|
|
57
|
+
target-version = "py310"
|
|
58
|
+
|
|
59
|
+
[tool.ruff.lint]
|
|
60
|
+
select = [
|
|
61
|
+
"E", # pycodestyle
|
|
62
|
+
"F", # pyflakes
|
|
63
|
+
"W", # pycodestyle warnings
|
|
64
|
+
"I", # isort
|
|
65
|
+
"C", # flake8-comprehensions
|
|
66
|
+
"B", # flake8-bugbear
|
|
67
|
+
"UP", # pyupgrade
|
|
68
|
+
"RUF", # ruff specific rules
|
|
69
|
+
]
|
|
70
|
+
ignore = ["E501", "C901"] # ignore line too long, too complex
|
|
71
|
+
|
|
72
|
+
[tool.ruff.lint.isort]
|
|
73
|
+
known-first-party = ["app", "frontend"]
|
|
74
|
+
|
|
75
|
+
[tool.mypy]
|
|
76
|
+
disallow_untyped_calls = true
|
|
77
|
+
disallow_untyped_defs = true
|
|
78
|
+
disallow_incomplete_defs = true
|
|
79
|
+
no_implicit_optional = true
|
|
80
|
+
check_untyped_defs = true
|
|
81
|
+
disallow_subclassing_any = true
|
|
82
|
+
warn_incomplete_stub = true
|
|
83
|
+
warn_redundant_casts = true
|
|
84
|
+
warn_unused_ignores = true
|
|
85
|
+
warn_unreachable = true
|
|
86
|
+
follow_imports = "silent"
|
|
87
|
+
ignore_missing_imports = true
|
|
88
|
+
explicit_package_bases = true
|
|
89
|
+
disable_error_code = ["misc", "no-untyped-call", "no-any-return"]
|
|
90
|
+
{% if cookiecutter.agent_name == 'multimodal_live_api' %}
|
|
91
|
+
exclude = [".venv","./frontend"]
|
|
92
|
+
{% else %}
|
|
93
|
+
exclude = [".venv"]
|
|
94
|
+
{%- endif %}
|
|
95
|
+
|
|
96
|
+
[tool.codespell]
|
|
97
|
+
ignore-words-list = "rouge"
|
|
98
|
+
{% if cookiecutter.agent_name == 'multimodal_live_api' %}
|
|
99
|
+
skip = "./locust_env/*,uv.lock,.venv,./frontend"
|
|
100
|
+
{% else %}
|
|
101
|
+
skip = "./locust_env/*,uv.lock,.venv"
|
|
102
|
+
{%- endif %}
|
|
103
|
+
|
|
104
|
+
[build-system]
|
|
105
|
+
requires = ["hatchling"]
|
|
106
|
+
build-backend = "hatchling.build"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
[tool.pytest.ini_options]
|
|
110
|
+
pythonpath = "."
|
|
111
|
+
|
|
112
|
+
[tool.hatch.build.targets.wheel]
|
|
113
|
+
packages = ["app","frontend"]
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Copyright 2025 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from collections.abc import Generator
|
|
16
|
+
from typing import Any
|
|
17
|
+
from unittest.mock import Mock, patch
|
|
18
|
+
|
|
19
|
+
import pytest
|
|
20
|
+
from google.cloud import logging as google_cloud_logging
|
|
21
|
+
from google.cloud import storage
|
|
22
|
+
from opentelemetry.sdk.trace import ReadableSpan
|
|
23
|
+
|
|
24
|
+
from app.utils.tracing import CloudTraceLoggingSpanExporter
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@pytest.fixture
|
|
28
|
+
def mock_logging_client() -> Mock:
|
|
29
|
+
"""Create a mock logging client."""
|
|
30
|
+
return Mock(spec=google_cloud_logging.Client)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@pytest.fixture
|
|
34
|
+
def mock_storage_client() -> Mock:
|
|
35
|
+
"""Create a mock storage client."""
|
|
36
|
+
return Mock(spec=storage.Client)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@pytest.fixture
|
|
40
|
+
def mock_credentials() -> Any:
|
|
41
|
+
"""Create mock credentials."""
|
|
42
|
+
return Mock()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@pytest.fixture
|
|
46
|
+
def patch_auth(mock_credentials: Any) -> Generator[Mock, None, None]:
|
|
47
|
+
"""Patch the google.auth.default function."""
|
|
48
|
+
with patch(
|
|
49
|
+
"google.auth.default", return_value=(mock_credentials, "project")
|
|
50
|
+
) as mock_auth:
|
|
51
|
+
yield mock_auth
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@pytest.fixture
|
|
55
|
+
def patch_clients(
|
|
56
|
+
mock_logging_client: Mock, mock_storage_client: Mock
|
|
57
|
+
) -> Generator[None, None, None]:
|
|
58
|
+
"""Patch the logging and storage clients."""
|
|
59
|
+
with patch("google.cloud.logging.Client", return_value=mock_logging_client):
|
|
60
|
+
with patch("google.cloud.storage.Client", return_value=mock_storage_client):
|
|
61
|
+
yield
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@pytest.fixture
|
|
65
|
+
def exporter(
|
|
66
|
+
mock_logging_client: Mock,
|
|
67
|
+
mock_storage_client: Mock,
|
|
68
|
+
patch_auth: Any,
|
|
69
|
+
mock_credentials: Any,
|
|
70
|
+
patch_clients: Any,
|
|
71
|
+
) -> CloudTraceLoggingSpanExporter:
|
|
72
|
+
"""Create a CloudTraceLoggingSpanExporter instance for testing."""
|
|
73
|
+
exporter = CloudTraceLoggingSpanExporter(
|
|
74
|
+
project_id="test-project",
|
|
75
|
+
logging_client=mock_logging_client,
|
|
76
|
+
storage_client=mock_storage_client,
|
|
77
|
+
bucket_name="test-bucket",
|
|
78
|
+
)
|
|
79
|
+
return exporter
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_init(exporter: CloudTraceLoggingSpanExporter) -> None:
|
|
83
|
+
"""Test the initialization of CloudTraceLoggingSpanExporter."""
|
|
84
|
+
assert exporter.project_id == "test-project"
|
|
85
|
+
assert exporter.bucket_name == "test-bucket"
|
|
86
|
+
assert exporter.debug is False
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_store_in_gcs(exporter: CloudTraceLoggingSpanExporter) -> None:
|
|
90
|
+
"""Test the store_in_gcs method of CloudTraceLoggingSpanExporter."""
|
|
91
|
+
span_id = "test-span-id"
|
|
92
|
+
content = "test-content"
|
|
93
|
+
uri = exporter.store_in_gcs(content, span_id)
|
|
94
|
+
assert uri == f"gs://test-bucket/spans/{span_id}.json"
|
|
95
|
+
exporter.bucket.blob.assert_called_once_with(f"spans/{span_id}.json")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@patch("json.dumps")
|
|
99
|
+
def test_process_large_attributes_small_payload(
|
|
100
|
+
mock_json_dumps: Mock, exporter: CloudTraceLoggingSpanExporter
|
|
101
|
+
) -> None:
|
|
102
|
+
"""Test processing of small payload attributes."""
|
|
103
|
+
mock_json_dumps.return_value = "a" * 100 # Small payload
|
|
104
|
+
span_dict = {"attributes": {"key": "value"}}
|
|
105
|
+
result = exporter._process_large_attributes(span_dict, "span-id")
|
|
106
|
+
assert result == span_dict
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@patch("json.dumps")
|
|
110
|
+
def test_process_large_attributes_large_payload(
|
|
111
|
+
mock_json_dumps: Mock, exporter: CloudTraceLoggingSpanExporter
|
|
112
|
+
) -> None:
|
|
113
|
+
"""Test processing of large payload attributes."""
|
|
114
|
+
mock_json_dumps.return_value = "a" * (400 * 1024 + 1) # Large payload
|
|
115
|
+
span_dict = {
|
|
116
|
+
"attributes": {
|
|
117
|
+
"key1": "value1",
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
result = exporter._process_large_attributes(span_dict, "span-id")
|
|
121
|
+
assert "uri_payload" in result["attributes"]
|
|
122
|
+
assert "url_payload" in result["attributes"]
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@patch.object(CloudTraceLoggingSpanExporter, "_process_large_attributes")
|
|
126
|
+
def test_export(
|
|
127
|
+
mock_process_large_attributes: Mock, exporter: CloudTraceLoggingSpanExporter
|
|
128
|
+
) -> None:
|
|
129
|
+
"""Test the export method of CloudTraceLoggingSpanExporter."""
|
|
130
|
+
mock_span = Mock(spec=ReadableSpan)
|
|
131
|
+
mock_span.get_span_context.return_value.trace_id = 123
|
|
132
|
+
mock_span.get_span_context.return_value.span_id = 456
|
|
133
|
+
mock_span.to_json.return_value = '{"key": "value"}'
|
|
134
|
+
|
|
135
|
+
mock_process_large_attributes.return_value = {"processed": "data"}
|
|
136
|
+
|
|
137
|
+
exporter.export([mock_span])
|
|
138
|
+
|
|
139
|
+
mock_process_large_attributes.assert_called_once()
|
|
140
|
+
exporter.logger.log_struct.assert_called_once()
|