agent-starter-pack 0.6.4__py3-none-any.whl → 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. {agent_starter_pack-0.6.4.dist-info → agent_starter_pack-0.7.0.dist-info}/METADATA +15 -12
  2. {agent_starter_pack-0.6.4.dist-info → agent_starter_pack-0.7.0.dist-info}/RECORD +32 -29
  3. agents/adk_gemini_fullstack/app/agent.py +62 -8
  4. llm.txt +290 -0
  5. src/base_template/.gitignore +2 -1
  6. src/base_template/GEMINI.md +5 -0
  7. src/base_template/Makefile +20 -5
  8. src/base_template/deployment/cd/deploy-to-prod.yaml +3 -3
  9. src/base_template/deployment/cd/staging.yaml +4 -4
  10. src/base_template/deployment/ci/pr_checks.yaml +1 -1
  11. src/base_template/pyproject.toml +2 -2
  12. src/cli/utils/template.py +22 -9
  13. src/data_ingestion/uv.lock +97 -0
  14. src/frontends/adk_gemini_fullstack/frontend/package-lock.json +276 -0
  15. src/frontends/adk_gemini_fullstack/frontend/package.json +1 -0
  16. src/frontends/adk_gemini_fullstack/frontend/src/components/ChatMessagesView.tsx +5 -4
  17. src/frontends/adk_gemini_fullstack/frontend/vite.config.ts +4 -0
  18. src/resources/docs/adk-cheatsheet.md +1224 -0
  19. src/resources/locks/uv-adk_base-agent_engine.lock +14 -13
  20. src/resources/locks/uv-adk_base-cloud_run.lock +14 -13
  21. src/resources/locks/uv-adk_gemini_fullstack-agent_engine.lock +14 -13
  22. src/resources/locks/uv-adk_gemini_fullstack-cloud_run.lock +14 -13
  23. src/resources/locks/uv-agentic_rag-agent_engine.lock +78 -83
  24. src/resources/locks/uv-agentic_rag-cloud_run.lock +110 -119
  25. src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +130 -135
  26. src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +163 -172
  27. src/resources/locks/uv-langgraph_base_react-agent_engine.lock +87 -92
  28. src/resources/locks/uv-langgraph_base_react-cloud_run.lock +119 -128
  29. src/resources/locks/uv-live_api-cloud_run.lock +98 -107
  30. {agent_starter_pack-0.6.4.dist-info → agent_starter_pack-0.7.0.dist-info}/WHEEL +0 -0
  31. {agent_starter_pack-0.6.4.dist-info → agent_starter_pack-0.7.0.dist-info}/entry_points.txt +0 -0
  32. {agent_starter_pack-0.6.4.dist-info → agent_starter_pack-0.7.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,12 @@
1
+ # Install dependencies using uv package manager
1
2
  install:
2
3
  @command -v uv >/dev/null 2>&1 || { echo "uv is not installed. Installing uv..."; curl -LsSf https://astral.sh/uv/0.6.12/install.sh | sh; source $HOME/.local/bin/env; }
3
- uv sync --dev{% if cookiecutter.agent_name != 'live_api' and "adk" not in cookiecutter.tags %} --extra streamlit{%- endif %} --extra jupyter --frozen{% if cookiecutter.agent_name == 'live_api' %} && npm --prefix frontend install{%- endif %}
4
+ uv sync --dev{% if cookiecutter.agent_name != 'live_api' and "adk" not in cookiecutter.tags %} --extra streamlit{%- endif %} --extra jupyter{% if cookiecutter.agent_name == 'live_api' %} && npm --prefix frontend install{%- endif %}
4
5
  {%- if cookiecutter.settings.get("commands", {}).get("override", {}).get("install") %} && {{cookiecutter.settings.get("commands", {}).get("override", {}).get("install")}}{%- endif %}
5
6
  {%- if cookiecutter.settings.get("commands", {}).get("extra", {}) %}
6
7
  {%- for cmd_name, cmd_value in cookiecutter.settings.get("commands", {}).get("extra", {}).items() %}
7
8
 
9
+ # {{ cmd_value.get("description") }}
8
10
  {{ cmd_name }}:
9
11
  {%- if cmd_value is mapping %}
10
12
  {%- if cmd_value.command is mapping and cookiecutter.deployment_target in cmd_value.command %}
@@ -17,6 +19,7 @@ install:
17
19
  {%- endif %}
18
20
  {%- endfor %}{%- endif %}
19
21
 
22
+ # Launch local dev playground
20
23
  playground:
21
24
  {%- if cookiecutter.settings.get("commands", {}).get("override", {}).get("playground") %}
22
25
  {{cookiecutter.settings.get("commands", {}).get("override", {}).get("playground")}}
@@ -44,10 +47,14 @@ playground:
44
47
  {%- endif %}
45
48
  {%- endif %}
46
49
 
50
+ # Deploy the agent remotely
51
+ {%- if cookiecutter.deployment_target == 'cloud_run' %}
52
+ # Usage: make backend [IAP=true] [PORT=8080] - Set IAP=true to enable Identity-Aware Proxy, PORT to specify container port
53
+ {%- endif %}
47
54
  backend:
48
55
  {%- if cookiecutter.deployment_target == 'cloud_run' %}
49
56
  PROJECT_ID=$$(gcloud config get-value project) && \
50
- gcloud run deploy {{cookiecutter.project_name}} \
57
+ gcloud beta run deploy {{cookiecutter.project_name}} \
51
58
  --source . \
52
59
  --memory "4Gi" \
53
60
  --project $$PROJECT_ID \
@@ -55,31 +62,37 @@ backend:
55
62
  --no-allow-unauthenticated \
56
63
  --labels "created-by=adk" \
57
64
  --set-env-vars \
58
- "COMMIT_SHA=$(shell git rev-parse HEAD){%- if cookiecutter.data_ingestion %}{%- if cookiecutter.datastore_type == "vertex_ai_search" %},DATA_STORE_ID={{cookiecutter.project_name}}-datastore,DATA_STORE_REGION=us{%- elif cookiecutter.datastore_type == "vertex_ai_vector_search" %},VECTOR_SEARCH_INDEX={{cookiecutter.project_name}}-vector-search,VECTOR_SEARCH_INDEX_ENDPOINT={{cookiecutter.project_name}}-vector-search-endpoint,VECTOR_SEARCH_BUCKET=$$PROJECT_ID-{{cookiecutter.project_name}}-vs{%- endif %}{%- endif %}"
65
+ "COMMIT_SHA=$(shell git rev-parse HEAD){%- if cookiecutter.data_ingestion %}{%- if cookiecutter.datastore_type == "vertex_ai_search" %},DATA_STORE_ID={{cookiecutter.project_name}}-datastore,DATA_STORE_REGION=us{%- elif cookiecutter.datastore_type == "vertex_ai_vector_search" %},VECTOR_SEARCH_INDEX={{cookiecutter.project_name}}-vector-search,VECTOR_SEARCH_INDEX_ENDPOINT={{cookiecutter.project_name}}-vector-search-endpoint,VECTOR_SEARCH_BUCKET=$$PROJECT_ID-{{cookiecutter.project_name}}-vs{%- endif %}{%- endif %}" \
66
+ $(if $(IAP),--iap) \
67
+ $(if $(PORT),--port=$(PORT))
59
68
  {%- elif cookiecutter.deployment_target == 'agent_engine' %}
60
69
  # Export dependencies to requirements file using uv export.
61
- uv export --no-hashes --no-header --no-dev --no-emit-project --no-annotate --frozen > .requirements.txt 2>/dev/null || \
62
- uv export --no-hashes --no-header --no-dev --no-emit-project --frozen > .requirements.txt && uv run app/agent_engine_app.py
70
+ uv export --no-hashes --no-header --no-dev --no-emit-project --no-annotate > .requirements.txt 2>/dev/null || \
71
+ uv export --no-hashes --no-header --no-dev --no-emit-project > .requirements.txt && uv run app/agent_engine_app.py
63
72
  {%- endif %}
64
73
  {%- if cookiecutter.deployment_target == 'cloud_run' %}
65
74
 
75
+ # Launch local development server with hot-reload
66
76
  local-backend:
67
77
  uv run uvicorn app.server:app --host 0.0.0.0 --port 8000 --reload
68
78
  {%- endif %}
69
79
  {%- if cookiecutter.deployment_target == 'cloud_run' %}
70
80
  {%- if cookiecutter.agent_name == 'live_api' %}
71
81
 
82
+ # Start the frontend UI for development
72
83
  ui:
73
84
  PORT=8501 npm --prefix frontend start
74
85
  {%- endif %}
75
86
  {%- endif %}
76
87
 
88
+ # Set up development environment resources using Terraform
77
89
  setup-dev-env:
78
90
  PROJECT_ID=$$(gcloud config get-value project) && \
79
91
  (cd deployment/terraform/dev && terraform init && terraform apply --var-file vars/env.tfvars --var dev_project_id=$$PROJECT_ID --auto-approve)
80
92
 
81
93
  {%- if cookiecutter.data_ingestion %}
82
94
 
95
+ # Run the data ingestion pipeline for RAG capabilities
83
96
  data-ingestion:
84
97
  PROJECT_ID=$$(gcloud config get-value project) && \
85
98
  (cd data_ingestion && uv run data_ingestion_pipeline/submit_pipeline.py \
@@ -98,9 +111,11 @@ data-ingestion:
98
111
  --pipeline-name="data-ingestion-pipeline")
99
112
  {%- endif %}
100
113
 
114
+ # Run unit and integration tests
101
115
  test:
102
116
  uv run pytest tests/unit && uv run pytest tests/integration
103
117
 
118
+ # Run code quality checks (codespell, ruff, mypy)
104
119
  lint:
105
120
  uv run codespell
106
121
  uv run ruff check . --diff
@@ -21,7 +21,7 @@ steps:
21
21
  - -c
22
22
  - |
23
23
  cd data_ingestion && pip install uv==0.6.12 --user && cd data_ingestion_pipeline && \
24
- uv sync --frozen && uv run python submit_pipeline.py
24
+ uv sync --locked && uv run python submit_pipeline.py
25
25
  env:
26
26
  - "PIPELINE_ROOT=${_PIPELINE_GCS_ROOT}"
27
27
  - "REGION=${_REGION}"
@@ -78,7 +78,7 @@ steps:
78
78
  args:
79
79
  - "-c"
80
80
  - |
81
- pip install uv==0.6.12 --user && uv sync --frozen
81
+ pip install uv==0.6.12 --user && uv sync --locked
82
82
  env:
83
83
  - 'PATH=/usr/local/bin:/usr/bin:~/.local/bin'
84
84
 
@@ -88,7 +88,7 @@ steps:
88
88
  args:
89
89
  - "-c"
90
90
  - |
91
- uv export --no-hashes --no-sources --no-header --no-dev --no-emit-project --no-annotate --frozen > .requirements.txt
91
+ uv export --no-hashes --no-sources --no-header --no-dev --no-emit-project --no-annotate --locked > .requirements.txt
92
92
  uv run app/agent_engine_app.py \
93
93
  --project ${_PROD_PROJECT_ID} \
94
94
  --location ${_REGION} \
@@ -21,7 +21,7 @@ steps:
21
21
  - -c
22
22
  - |
23
23
  cd data_ingestion && pip install uv==0.6.12 --user && cd data_ingestion_pipeline && \
24
- uv sync --frozen && uv run python submit_pipeline.py
24
+ uv sync --locked && uv run python submit_pipeline.py
25
25
  env:
26
26
  - "PIPELINE_ROOT=${_PIPELINE_GCS_ROOT}"
27
27
  - "REGION=${_REGION}"
@@ -111,7 +111,7 @@ steps:
111
111
  args:
112
112
  - "-c"
113
113
  - |
114
- pip install uv==0.6.12 --user && uv sync --frozen
114
+ pip install uv==0.6.12 --user && uv sync --locked
115
115
  env:
116
116
  - 'PATH=/usr/local/bin:/usr/bin:~/.local/bin'
117
117
 
@@ -121,7 +121,7 @@ steps:
121
121
  args:
122
122
  - "-c"
123
123
  - |
124
- uv export --no-hashes --no-sources --no-header --no-dev --no-emit-project --no-annotate --frozen > .requirements.txt
124
+ uv export --no-hashes --no-sources --no-header --no-dev --no-emit-project --no-annotate --locked > .requirements.txt
125
125
  uv run app/agent_engine_app.py \
126
126
  --project ${_STAGING_PROJECT_ID} \
127
127
  --location ${_REGION} \
@@ -149,7 +149,7 @@ steps:
149
149
  {%- if cookiecutter.deployment_target == 'cloud_run' %}
150
150
  export _ID_TOKEN=$(cat id_token.txt)
151
151
  export _STAGING_URL=$(cat staging_url.txt)
152
- pip install uv==0.6.12 --user && uv sync --frozen
152
+ pip install uv==0.6.12 --user && uv sync --locked
153
153
  {%- elif cookiecutter.deployment_target == 'agent_engine' %}
154
154
  export _AUTH_TOKEN=$(cat auth_token.txt)
155
155
  {%- endif %}
@@ -20,7 +20,7 @@ steps:
20
20
  args:
21
21
  - "-c"
22
22
  - |
23
- pip install uv==0.6.12 --user && uv sync --frozen
23
+ pip install uv==0.6.12 --user && uv sync --locked
24
24
  env:
25
25
  - 'PATH=/usr/local/bin:/usr/bin:~/.local/bin'
26
26
 
@@ -16,11 +16,11 @@ dependencies = [
16
16
  {%- endif %}
17
17
  "google-cloud-logging~=3.11.4",
18
18
  {%- if cookiecutter.deployment_target == 'cloud_run' %}
19
- "google-cloud-aiplatform[evaluation]~=1.95.1",
19
+ "google-cloud-aiplatform[evaluation]~=1.99.0",
20
20
  "fastapi~=0.115.8",
21
21
  "uvicorn~=0.34.0"
22
22
  {%- elif cookiecutter.deployment_target == 'agent_engine' %}
23
- "google-cloud-aiplatform[evaluation,agent-engines]~=1.95.1"
23
+ "google-cloud-aiplatform[evaluation,agent-engines]~=1.99.0"
24
24
  {%- endif %}
25
25
  ]
26
26
  {% if cookiecutter.deployment_target == 'cloud_run' %}
src/cli/utils/template.py CHANGED
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import json
15
16
  import logging
16
17
  import os
17
18
  import pathlib
@@ -23,7 +24,7 @@ from typing import Any
23
24
  import yaml
24
25
  from cookiecutter.main import cookiecutter
25
26
  from rich.console import Console
26
- from rich.prompt import Prompt
27
+ from rich.prompt import IntPrompt, Prompt
27
28
 
28
29
  from src.cli.utils.version import get_current_version
29
30
 
@@ -197,8 +198,6 @@ def prompt_deployment_target(agent_name: str) -> str:
197
198
  description = info.get("description", "")
198
199
  console.print(f"{idx}. [bold]{display_name}[/] - [dim]{description}[/]")
199
200
 
200
- from rich.prompt import IntPrompt
201
-
202
201
  choice = IntPrompt.ask(
203
202
  "\nEnter the number of your deployment target choice",
204
203
  default=1,
@@ -510,6 +509,22 @@ def process_template(
510
509
  frontend_type = settings.get("frontend_type", DEFAULT_FRONTEND)
511
510
  tags = settings.get("tags", ["None"])
512
511
 
512
+ # Load adk-cheatsheet.md and llm.txt for injection
513
+ adk_cheatsheet_path = (
514
+ pathlib.Path(__file__).parent.parent.parent
515
+ / "resources"
516
+ / "docs"
517
+ / "adk-cheatsheet.md"
518
+ )
519
+ with open(adk_cheatsheet_path) as f:
520
+ adk_cheatsheet_content = f.read()
521
+
522
+ llm_txt_path = (
523
+ pathlib.Path(__file__).parent.parent.parent.parent / "llm.txt"
524
+ )
525
+ with open(llm_txt_path) as f:
526
+ llm_txt_content = f.read()
527
+
513
528
  cookiecutter_config = {
514
529
  "project_name": "my-project",
515
530
  "agent_name": agent_name,
@@ -525,11 +540,12 @@ def process_template(
525
540
  "extra_dependencies": [extra_deps],
526
541
  "data_ingestion": include_data_ingestion,
527
542
  "datastore_type": datastore if datastore else "",
543
+ "adk_cheatsheet": adk_cheatsheet_content,
544
+ "llm_txt": llm_txt_content,
528
545
  "_copy_without_render": [
529
546
  "*.ipynb", # Don't render notebooks
530
547
  "*.json", # Don't render JSON files
531
548
  "frontend/*", # Don't render frontend directory
532
- # "tests/*", # Don't render tests directory
533
549
  "notebooks/*", # Don't render notebooks directory
534
550
  ".git/*", # Don't render git directory
535
551
  "__pycache__/*", # Don't render cache
@@ -537,15 +553,12 @@ def process_template(
537
553
  ".pytest_cache/*",
538
554
  ".venv/*",
539
555
  "*templates.py", # Don't render templates files
540
- "!*.py", # render Python files
541
- "!Makefile", # DO render Makefile
542
- "!README.md", # DO render README.md
556
+ # Don't render agent.py unless it's agentic_rag
557
+ "app/agent.py" if agent_name != "agentic_rag" else "",
543
558
  ],
544
559
  }
545
560
 
546
561
  with open(cookiecutter_template / "cookiecutter.json", "w") as f:
547
- import json
548
-
549
562
  json.dump(cookiecutter_config, f, indent=4)
550
563
 
551
564
  logging.debug(f"Template structure created at {cookiecutter_template}")
@@ -1,4 +1,5 @@
1
1
  version = 1
2
+ revision = 1
2
3
  requires-python = ">=3.9, <=3.13"
3
4
  resolution-markers = [
4
5
  "python_full_version >= '3.13'",
@@ -135,12 +136,14 @@ version = "0.1.0"
135
136
  source = { editable = "." }
136
137
  dependencies = [
137
138
  { name = "google-cloud-aiplatform" },
139
+ { name = "google-cloud-pipeline-components" },
138
140
  { name = "kfp" },
139
141
  ]
140
142
 
141
143
  [package.metadata]
142
144
  requires-dist = [
143
145
  { name = "google-cloud-aiplatform", specifier = ">=1.80.0" },
146
+ { name = "google-cloud-pipeline-components", specifier = ">=2.19.0" },
144
147
  { name = "kfp", specifier = ">=1.4.0" },
145
148
  ]
146
149
 
@@ -243,6 +246,20 @@ wheels = [
243
246
  { url = "https://files.pythonhosted.org/packages/5e/0f/2e2061e3fbcb9d535d5da3f58cc8de4947df1786fe6a1355960feb05a681/google_cloud_core-2.4.1-py2.py3-none-any.whl", hash = "sha256:a9e6a4422b9ac5c29f79a0ede9485473338e2ce78d91f2370c01e730eab22e61", size = 29233 },
244
247
  ]
245
248
 
249
+ [[package]]
250
+ name = "google-cloud-pipeline-components"
251
+ version = "2.20.1"
252
+ source = { registry = "https://pypi.org/simple" }
253
+ dependencies = [
254
+ { name = "google-api-core" },
255
+ { name = "google-cloud-aiplatform" },
256
+ { name = "jinja2" },
257
+ { name = "kfp" },
258
+ ]
259
+ wheels = [
260
+ { url = "https://files.pythonhosted.org/packages/15/df/9840da02b887930783d23e7c966b3b1f8096f56c17ce52fa3d2682715da7/google_cloud_pipeline_components-2.20.1-py3-none-any.whl", hash = "sha256:77b3b735dc13f6868e3ed9281af3f195a1becbae0960755bb142286d784a06bd", size = 1471603 },
261
+ ]
262
+
246
263
  [[package]]
247
264
  name = "google-cloud-resource-manager"
248
265
  version = "1.14.0"
@@ -429,6 +446,18 @@ wheels = [
429
446
  { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
430
447
  ]
431
448
 
449
+ [[package]]
450
+ name = "jinja2"
451
+ version = "3.1.6"
452
+ source = { registry = "https://pypi.org/simple" }
453
+ dependencies = [
454
+ { name = "markupsafe" },
455
+ ]
456
+ sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 }
457
+ wheels = [
458
+ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 },
459
+ ]
460
+
432
461
  [[package]]
433
462
  name = "kfp"
434
463
  version = "2.11.0"
@@ -494,6 +523,74 @@ wheels = [
494
523
  { url = "https://files.pythonhosted.org/packages/62/a1/2027ddede72d33be2effc087580aeba07e733a7360780ae87226f1f91bd8/kubernetes-30.1.0-py2.py3-none-any.whl", hash = "sha256:e212e8b7579031dd2e512168b617373bc1e03888d41ac4e04039240a292d478d", size = 1706042 },
495
524
  ]
496
525
 
526
+ [[package]]
527
+ name = "markupsafe"
528
+ version = "3.0.2"
529
+ source = { registry = "https://pypi.org/simple" }
530
+ sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 }
531
+ wheels = [
532
+ { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 },
533
+ { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 },
534
+ { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 },
535
+ { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 },
536
+ { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 },
537
+ { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 },
538
+ { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 },
539
+ { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 },
540
+ { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 },
541
+ { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 },
542
+ { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 },
543
+ { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 },
544
+ { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 },
545
+ { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 },
546
+ { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 },
547
+ { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 },
548
+ { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 },
549
+ { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 },
550
+ { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 },
551
+ { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 },
552
+ { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 },
553
+ { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 },
554
+ { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 },
555
+ { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 },
556
+ { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 },
557
+ { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 },
558
+ { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 },
559
+ { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 },
560
+ { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 },
561
+ { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 },
562
+ { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 },
563
+ { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 },
564
+ { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 },
565
+ { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 },
566
+ { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 },
567
+ { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 },
568
+ { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 },
569
+ { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 },
570
+ { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 },
571
+ { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 },
572
+ { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 },
573
+ { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 },
574
+ { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 },
575
+ { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 },
576
+ { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 },
577
+ { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 },
578
+ { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 },
579
+ { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 },
580
+ { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 },
581
+ { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 },
582
+ { url = "https://files.pythonhosted.org/packages/a7/ea/9b1530c3fdeeca613faeb0fb5cbcf2389d816072fab72a71b45749ef6062/MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", size = 14344 },
583
+ { url = "https://files.pythonhosted.org/packages/4b/c2/fbdbfe48848e7112ab05e627e718e854d20192b674952d9042ebd8c9e5de/MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", size = 12389 },
584
+ { url = "https://files.pythonhosted.org/packages/f0/25/7a7c6e4dbd4f867d95d94ca15449e91e52856f6ed1905d58ef1de5e211d0/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", size = 21607 },
585
+ { url = "https://files.pythonhosted.org/packages/53/8f/f339c98a178f3c1e545622206b40986a4c3307fe39f70ccd3d9df9a9e425/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", size = 20728 },
586
+ { url = "https://files.pythonhosted.org/packages/1a/03/8496a1a78308456dbd50b23a385c69b41f2e9661c67ea1329849a598a8f9/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", size = 20826 },
587
+ { url = "https://files.pythonhosted.org/packages/e6/cf/0a490a4bd363048c3022f2f475c8c05582179bb179defcee4766fb3dcc18/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", size = 21843 },
588
+ { url = "https://files.pythonhosted.org/packages/19/a3/34187a78613920dfd3cdf68ef6ce5e99c4f3417f035694074beb8848cd77/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", size = 21219 },
589
+ { url = "https://files.pythonhosted.org/packages/17/d8/5811082f85bb88410ad7e452263af048d685669bbbfb7b595e8689152498/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", size = 20946 },
590
+ { url = "https://files.pythonhosted.org/packages/7c/31/bd635fb5989440d9365c5e3c47556cfea121c7803f5034ac843e8f37c2f2/MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", size = 15063 },
591
+ { url = "https://files.pythonhosted.org/packages/b3/73/085399401383ce949f727afec55ec3abd76648d04b9f22e1c0e99cb4bec3/MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", size = 15506 },
592
+ ]
593
+
497
594
  [[package]]
498
595
  name = "numpy"
499
596
  version = "2.0.2"