agent-starter-pack 0.10.0__py3-none-any.whl → 0.11.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-0.10.0.dist-info → agent_starter_pack-0.11.0.dist-info}/METADATA +2 -2
- {agent_starter_pack-0.10.0.dist-info → agent_starter_pack-0.11.0.dist-info}/RECORD +46 -45
- agents/adk_gemini_fullstack/.template/templateconfig.yaml +1 -0
- agents/crewai_coding_crew/.template/templateconfig.yaml +2 -2
- agents/crewai_coding_crew/tests/integration/test_agent.py +1 -1
- agents/langgraph_base_react/.template/templateconfig.yaml +1 -1
- agents/langgraph_base_react/tests/integration/test_agent.py +1 -1
- agents/live_api/tests/unit/test_server.py +2 -1
- src/base_template/deployment/terraform/dev/iam.tf +12 -11
- src/base_template/deployment/terraform/dev/variables.tf +2 -7
- src/base_template/deployment/terraform/github.tf +14 -0
- src/base_template/deployment/terraform/iam.tf +10 -7
- src/base_template/deployment/terraform/service_accounts.tf +4 -5
- src/base_template/deployment/terraform/variables.tf +2 -7
- src/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}build_triggers.tf{% else %}unused_build_triggers.tf{% endif %} +4 -2
- src/base_template/pyproject.toml +2 -2
- src/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/deploy-to-prod.yaml +1 -0
- src/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/staging.yaml +1 -0
- src/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/deploy-to-prod.yaml +1 -0
- src/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/staging.yaml +1 -0
- src/cli/commands/create.py +232 -101
- src/cli/commands/enhance.py +248 -0
- src/cli/commands/list.py +23 -11
- src/cli/commands/setup_cicd.py +1 -1
- src/cli/main.py +2 -0
- src/cli/utils/logging.py +40 -0
- src/cli/utils/remote_template.py +55 -16
- src/cli/utils/template.py +212 -94
- src/deployment_targets/agent_engine/app/agent_engine_app.py +8 -0
- src/deployment_targets/cloud_run/app/server.py +1 -1
- src/deployment_targets/cloud_run/deployment/terraform/dev/service.tf +1 -1
- src/deployment_targets/cloud_run/deployment/terraform/service.tf +2 -2
- src/resources/locks/uv-adk_base-agent_engine.lock +312 -312
- src/resources/locks/uv-adk_base-cloud_run.lock +403 -404
- src/resources/locks/uv-adk_gemini_fullstack-agent_engine.lock +312 -312
- src/resources/locks/uv-adk_gemini_fullstack-cloud_run.lock +403 -404
- src/resources/locks/uv-agentic_rag-agent_engine.lock +371 -371
- src/resources/locks/uv-agentic_rag-cloud_run.lock +477 -478
- src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +661 -591
- src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +868 -760
- src/resources/locks/uv-langgraph_base_react-agent_engine.lock +496 -446
- src/resources/locks/uv-langgraph_base_react-cloud_run.lock +639 -565
- src/resources/locks/uv-live_api-cloud_run.lock +584 -510
- {agent_starter_pack-0.10.0.dist-info → agent_starter_pack-0.11.0.dist-info}/WHEEL +0 -0
- {agent_starter_pack-0.10.0.dist-info → agent_starter_pack-0.11.0.dist-info}/entry_points.txt +0 -0
- {agent_starter_pack-0.10.0.dist-info → agent_starter_pack-0.11.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,248 @@
|
|
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 pathlib
|
16
|
+
|
17
|
+
import click
|
18
|
+
from rich.console import Console
|
19
|
+
|
20
|
+
from ..utils.logging import display_welcome_banner, handle_cli_error
|
21
|
+
from .create import (
|
22
|
+
create,
|
23
|
+
get_available_base_templates,
|
24
|
+
shared_template_options,
|
25
|
+
validate_base_template,
|
26
|
+
)
|
27
|
+
|
28
|
+
console = Console()
|
29
|
+
|
30
|
+
|
31
|
+
@click.command()
|
32
|
+
@click.pass_context
|
33
|
+
@click.argument(
|
34
|
+
"template_path",
|
35
|
+
type=click.Path(path_type=pathlib.Path),
|
36
|
+
default=".",
|
37
|
+
required=False,
|
38
|
+
)
|
39
|
+
@click.option(
|
40
|
+
"--name",
|
41
|
+
"-n",
|
42
|
+
help="Project name for templating (defaults to current directory name)",
|
43
|
+
)
|
44
|
+
@click.option(
|
45
|
+
"--base-template",
|
46
|
+
help="Base template to inherit from (e.g., adk_base, langgraph_base_react, agentic_rag)",
|
47
|
+
)
|
48
|
+
@shared_template_options
|
49
|
+
@handle_cli_error
|
50
|
+
def enhance(
|
51
|
+
ctx: click.Context,
|
52
|
+
template_path: pathlib.Path,
|
53
|
+
name: str | None,
|
54
|
+
deployment_target: str | None,
|
55
|
+
cicd_runner: str | None,
|
56
|
+
include_data_ingestion: bool,
|
57
|
+
datastore: str | None,
|
58
|
+
session_type: str | None,
|
59
|
+
debug: bool,
|
60
|
+
auto_approve: bool,
|
61
|
+
region: str,
|
62
|
+
skip_checks: bool,
|
63
|
+
base_template: str | None,
|
64
|
+
) -> None:
|
65
|
+
"""Enhance your existing project with AI agent capabilities.
|
66
|
+
|
67
|
+
This command is an alias for 'create' with --in-folder mode enabled, designed to
|
68
|
+
add agent-starter-pack features to your existing project in-place rather than
|
69
|
+
creating a new project directory.
|
70
|
+
|
71
|
+
For best compatibility, your project should follow the agent-starter-pack structure
|
72
|
+
with agent code organized in an /app folder (containing agent.py, etc.).
|
73
|
+
|
74
|
+
TEMPLATE_PATH can be:
|
75
|
+
- A local directory path (e.g., . for current directory)
|
76
|
+
- An agent name (e.g., adk_base)
|
77
|
+
- A remote template (e.g., adk@data-science)
|
78
|
+
|
79
|
+
The command will validate your project structure and provide guidance if needed.
|
80
|
+
"""
|
81
|
+
|
82
|
+
# Display welcome banner for enhance command
|
83
|
+
display_welcome_banner(enhance_mode=True)
|
84
|
+
|
85
|
+
# Validate base template if provided
|
86
|
+
if base_template and not validate_base_template(base_template):
|
87
|
+
available_templates = get_available_base_templates()
|
88
|
+
console.print(
|
89
|
+
f"Error: Base template '{base_template}' not found.", style="bold red"
|
90
|
+
)
|
91
|
+
console.print(
|
92
|
+
f"Available base templates: {', '.join(available_templates)}",
|
93
|
+
style="yellow",
|
94
|
+
)
|
95
|
+
return
|
96
|
+
|
97
|
+
# Determine project name
|
98
|
+
if name:
|
99
|
+
project_name = name
|
100
|
+
else:
|
101
|
+
# Use current directory name as default
|
102
|
+
current_dir = pathlib.Path.cwd()
|
103
|
+
project_name = current_dir.name
|
104
|
+
console.print(
|
105
|
+
f"Using current directory name as project name: {project_name}", style="dim"
|
106
|
+
)
|
107
|
+
|
108
|
+
# Show confirmation prompt for enhancement unless auto-approved
|
109
|
+
if not auto_approve:
|
110
|
+
current_dir = pathlib.Path.cwd()
|
111
|
+
console.print()
|
112
|
+
console.print(
|
113
|
+
"🚀 [blue]Ready to enhance your project with deployment capabilities[/blue]"
|
114
|
+
)
|
115
|
+
console.print(f"📂 {current_dir}")
|
116
|
+
console.print()
|
117
|
+
console.print("[bold]What will happen:[/bold]")
|
118
|
+
console.print("• New template files will be added to this directory")
|
119
|
+
console.print("• Your existing files will be preserved")
|
120
|
+
console.print("• A backup will be created before any changes")
|
121
|
+
console.print()
|
122
|
+
|
123
|
+
if not click.confirm(
|
124
|
+
f"Continue with enhancement? {click.style('[Y/n]: ', fg='blue', bold=True)}",
|
125
|
+
default=True,
|
126
|
+
show_default=False,
|
127
|
+
):
|
128
|
+
console.print("✋ [yellow]Enhancement cancelled.[/yellow]")
|
129
|
+
return
|
130
|
+
console.print()
|
131
|
+
|
132
|
+
# Determine agent specification based on template_path
|
133
|
+
if template_path == pathlib.Path("."):
|
134
|
+
# Current directory - use local@ syntax
|
135
|
+
agent_spec = "local@."
|
136
|
+
elif template_path.is_dir():
|
137
|
+
# Other local directory
|
138
|
+
agent_spec = f"local@{template_path.resolve()}"
|
139
|
+
else:
|
140
|
+
# Assume it's an agent name or remote spec
|
141
|
+
agent_spec = str(template_path)
|
142
|
+
|
143
|
+
# Show base template inheritance info early for local projects
|
144
|
+
if agent_spec.startswith("local@"):
|
145
|
+
from ..utils.remote_template import (
|
146
|
+
get_base_template_name,
|
147
|
+
load_remote_template_config,
|
148
|
+
)
|
149
|
+
|
150
|
+
# Prepare CLI overrides for base template
|
151
|
+
cli_overrides = {}
|
152
|
+
if base_template:
|
153
|
+
cli_overrides["base_template"] = base_template
|
154
|
+
|
155
|
+
# Load config from current directory for inheritance info
|
156
|
+
current_dir = pathlib.Path.cwd()
|
157
|
+
source_config = load_remote_template_config(current_dir, cli_overrides)
|
158
|
+
base_template_name = get_base_template_name(source_config)
|
159
|
+
|
160
|
+
console.print()
|
161
|
+
console.print(
|
162
|
+
f"Template inherits from base: [cyan][link=https://github.com/GoogleCloudPlatform/agent-starter-pack/tree/main/agents/{base_template_name}]{base_template_name}[/link][/cyan]"
|
163
|
+
)
|
164
|
+
|
165
|
+
# Show available alternatives and guidance
|
166
|
+
available_bases = get_available_base_templates()
|
167
|
+
if len(available_bases) > 1:
|
168
|
+
other_bases = [b for b in available_bases if b != base_template_name]
|
169
|
+
if other_bases:
|
170
|
+
console.print(
|
171
|
+
f"[dim]💡 To use a different base template (e.g., {', '.join(other_bases[:2])}), use:[/dim]"
|
172
|
+
)
|
173
|
+
console.print(
|
174
|
+
"[dim] asp enhance . --base-template langgraph_base_react[/dim]"
|
175
|
+
)
|
176
|
+
console.print()
|
177
|
+
|
178
|
+
# Validate project structure when using current directory template
|
179
|
+
if template_path == pathlib.Path("."):
|
180
|
+
current_dir = pathlib.Path.cwd()
|
181
|
+
app_folder = current_dir / "app"
|
182
|
+
|
183
|
+
if not app_folder.exists() or not app_folder.is_dir():
|
184
|
+
console.print()
|
185
|
+
console.print(
|
186
|
+
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
187
|
+
)
|
188
|
+
console.print("⚠️ [bold yellow]PROJECT STRUCTURE WARNING[/bold yellow] ⚠️")
|
189
|
+
console.print(
|
190
|
+
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
191
|
+
)
|
192
|
+
console.print()
|
193
|
+
console.print(
|
194
|
+
"📁 [bold]Expected Structure:[/bold] [cyan]/app[/cyan] folder containing your agent code"
|
195
|
+
)
|
196
|
+
console.print(f"📍 [bold]Current Directory:[/bold] {current_dir}")
|
197
|
+
console.print("❌ [bold red]Missing:[/bold red] /app folder")
|
198
|
+
console.print()
|
199
|
+
console.print(
|
200
|
+
"[dim]The enhance command can still proceed, but for best compatibility"
|
201
|
+
" your agent code should be organized in an /app folder structure.[/dim]"
|
202
|
+
)
|
203
|
+
console.print()
|
204
|
+
|
205
|
+
# Ask for confirmation after showing the structure warning
|
206
|
+
console.print(
|
207
|
+
"💡 [dim]Consider creating an /app folder for better compatibility.[/dim]"
|
208
|
+
)
|
209
|
+
console.print()
|
210
|
+
|
211
|
+
if not auto_approve:
|
212
|
+
if not click.confirm(
|
213
|
+
"Continue with enhancement despite missing /app folder?",
|
214
|
+
default=True,
|
215
|
+
):
|
216
|
+
console.print("✋ [yellow]Enhancement cancelled.[/yellow]")
|
217
|
+
return
|
218
|
+
else:
|
219
|
+
# Check for common agent files
|
220
|
+
agent_py = app_folder / "agent.py"
|
221
|
+
if agent_py.exists():
|
222
|
+
console.print(
|
223
|
+
"Detected existing agent structure with [cyan]/app/agent.py[/cyan]"
|
224
|
+
)
|
225
|
+
else:
|
226
|
+
console.print(
|
227
|
+
"ℹ️ [blue]Found /app folder[/blue] - ensure your agent code is properly organized within it"
|
228
|
+
)
|
229
|
+
|
230
|
+
# Call the create command with in-folder mode enabled
|
231
|
+
ctx.invoke(
|
232
|
+
create,
|
233
|
+
project_name=project_name,
|
234
|
+
agent=agent_spec,
|
235
|
+
deployment_target=deployment_target,
|
236
|
+
cicd_runner=cicd_runner,
|
237
|
+
include_data_ingestion=include_data_ingestion,
|
238
|
+
datastore=datastore,
|
239
|
+
session_type=session_type,
|
240
|
+
debug=debug,
|
241
|
+
output_dir=None, # Use current directory
|
242
|
+
auto_approve=auto_approve,
|
243
|
+
region=region,
|
244
|
+
skip_checks=skip_checks,
|
245
|
+
in_folder=True, # Always use in-folder mode for enhance
|
246
|
+
base_template=base_template,
|
247
|
+
skip_welcome=True, # Skip welcome message since enhance shows its own
|
248
|
+
)
|
src/cli/commands/list.py
CHANGED
@@ -16,7 +16,7 @@ import logging
|
|
16
16
|
import pathlib
|
17
17
|
|
18
18
|
import click
|
19
|
-
import
|
19
|
+
import tomllib
|
20
20
|
from rich.console import Console
|
21
21
|
from rich.table import Table
|
22
22
|
|
@@ -42,25 +42,37 @@ def display_agents_from_path(base_path: pathlib.Path, source_name: str) -> None:
|
|
42
42
|
return
|
43
43
|
|
44
44
|
found_agents = False
|
45
|
-
# Search for
|
46
|
-
for config_path in sorted(base_path.glob("**/
|
45
|
+
# Search for pyproject.toml files to identify agents (explicit opt-in)
|
46
|
+
for config_path in sorted(base_path.glob("**/pyproject.toml")):
|
47
47
|
try:
|
48
|
-
with open(config_path,
|
49
|
-
|
48
|
+
with open(config_path, "rb") as f:
|
49
|
+
pyproject_data = tomllib.load(f)
|
50
50
|
|
51
|
-
|
52
|
-
|
51
|
+
config = pyproject_data.get("tool", {}).get("agent-starter-pack", {})
|
52
|
+
|
53
|
+
# Skip pyproject.toml files that don't have agent-starter-pack config
|
54
|
+
if not config:
|
55
|
+
continue
|
56
|
+
|
57
|
+
template_root = config_path.parent
|
58
|
+
|
59
|
+
# Use fallbacks to [project] section if needed
|
60
|
+
project_info = pyproject_data.get("project", {})
|
61
|
+
agent_name = (
|
62
|
+
config.get("name") or project_info.get("name") or template_root.name
|
63
|
+
)
|
64
|
+
description = (
|
65
|
+
config.get("description") or project_info.get("description") or ""
|
66
|
+
)
|
53
67
|
|
54
68
|
# Display the agent's path relative to the scanned directory
|
55
|
-
relative_path =
|
69
|
+
relative_path = template_root.relative_to(base_path)
|
56
70
|
|
57
71
|
table.add_row(agent_name, f"/{relative_path}", description)
|
58
72
|
found_agents = True
|
59
73
|
|
60
74
|
except Exception as e:
|
61
|
-
logging.warning(
|
62
|
-
f"Could not load agent from {config_path.parent.parent}: {e}"
|
63
|
-
)
|
75
|
+
logging.warning(f"Could not load agent from {config_path.parent}: {e}")
|
64
76
|
|
65
77
|
if not found_agents:
|
66
78
|
console.print(f"No agents found in {source_name}", style="yellow")
|
src/cli/commands/setup_cicd.py
CHANGED
@@ -373,7 +373,7 @@ def create_or_update_secret(secret_id: str, secret_value: str, project_id: str)
|
|
373
373
|
Raises:
|
374
374
|
subprocess.CalledProcessError: If secret creation/update fails
|
375
375
|
"""
|
376
|
-
with tempfile.NamedTemporaryFile(mode="w") as temp_file:
|
376
|
+
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8") as temp_file:
|
377
377
|
temp_file.write(secret_value)
|
378
378
|
temp_file.flush()
|
379
379
|
|
src/cli/main.py
CHANGED
@@ -18,6 +18,7 @@ import click
|
|
18
18
|
from rich.console import Console
|
19
19
|
|
20
20
|
from .commands.create import create
|
21
|
+
from .commands.enhance import enhance
|
21
22
|
from .commands.list import list_agents
|
22
23
|
from .commands.setup_cicd import setup_cicd
|
23
24
|
from .utils import display_update_message
|
@@ -53,6 +54,7 @@ def cli() -> None:
|
|
53
54
|
|
54
55
|
# Register commands
|
55
56
|
cli.add_command(create)
|
57
|
+
cli.add_command(enhance)
|
56
58
|
cli.add_command(setup_cicd)
|
57
59
|
cli.add_command(list_agents, name="list")
|
58
60
|
|
src/cli/utils/logging.py
CHANGED
@@ -24,6 +24,46 @@ console = Console()
|
|
24
24
|
F = TypeVar("F", bound=Callable[..., Any])
|
25
25
|
|
26
26
|
|
27
|
+
def display_welcome_banner(
|
28
|
+
agent: str | None = None, enhance_mode: bool = False
|
29
|
+
) -> None:
|
30
|
+
"""Display the Agent Starter Pack welcome banner.
|
31
|
+
|
32
|
+
Args:
|
33
|
+
agent: Optional agent specification to customize the welcome message
|
34
|
+
enhance_mode: Whether this is for enhancement mode
|
35
|
+
"""
|
36
|
+
if enhance_mode:
|
37
|
+
console.print(
|
38
|
+
"\n=== Google Cloud Agent Starter Pack 🚀===",
|
39
|
+
style="bold blue",
|
40
|
+
)
|
41
|
+
console.print(
|
42
|
+
"Enhancing your existing project with production-ready agent capabilities!\n",
|
43
|
+
style="green",
|
44
|
+
)
|
45
|
+
elif agent and agent.startswith("adk@"):
|
46
|
+
console.print(
|
47
|
+
"\n=== Welcome to [link=https://github.com/google/adk-samples]google/adk-samples[/link]! ✨ ===",
|
48
|
+
style="bold blue",
|
49
|
+
)
|
50
|
+
console.print(
|
51
|
+
"Powered by [link=https://goo.gle/agent-starter-pack]Google Cloud - Agent Starter Pack [/link]\n",
|
52
|
+
)
|
53
|
+
console.print(
|
54
|
+
"This tool will help you create an end-to-end production-ready AI agent in Google Cloud!\n"
|
55
|
+
)
|
56
|
+
else:
|
57
|
+
console.print(
|
58
|
+
"\n=== Google Cloud Agent Starter Pack 🚀===",
|
59
|
+
style="bold blue",
|
60
|
+
)
|
61
|
+
console.print("Welcome to the Agent Starter Pack!")
|
62
|
+
console.print(
|
63
|
+
"This tool will help you create an end-to-end production-ready AI agent in Google Cloud!\n"
|
64
|
+
)
|
65
|
+
|
66
|
+
|
27
67
|
def handle_cli_error(f: F) -> F:
|
28
68
|
"""Decorator to handle CLI errors gracefully.
|
29
69
|
|
src/cli/utils/remote_template.py
CHANGED
@@ -22,7 +22,7 @@ import tempfile
|
|
22
22
|
from dataclasses import dataclass
|
23
23
|
from typing import Any
|
24
24
|
|
25
|
-
import
|
25
|
+
import tomllib
|
26
26
|
from jinja2 import Environment
|
27
27
|
|
28
28
|
|
@@ -183,27 +183,66 @@ def fetch_remote_template(
|
|
183
183
|
) from e
|
184
184
|
|
185
185
|
|
186
|
-
def load_remote_template_config(
|
187
|
-
|
186
|
+
def load_remote_template_config(
|
187
|
+
template_dir: pathlib.Path, cli_overrides: dict[str, Any] | None = None
|
188
|
+
) -> dict[str, Any]:
|
189
|
+
"""Load template configuration from remote template's pyproject.toml with CLI overrides.
|
190
|
+
|
191
|
+
Loads configuration from [tool.agent-starter-pack] section with fallbacks
|
192
|
+
to [project] section for name and description if not specified. CLI overrides
|
193
|
+
take precedence over all other sources.
|
188
194
|
|
189
195
|
Args:
|
190
196
|
template_dir: Path to template directory
|
197
|
+
cli_overrides: Configuration overrides from CLI (takes highest precedence)
|
191
198
|
|
192
199
|
Returns:
|
193
|
-
Template configuration dictionary
|
200
|
+
Template configuration dictionary with merged sources
|
194
201
|
"""
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
202
|
+
config = {}
|
203
|
+
|
204
|
+
# Start with defaults
|
205
|
+
defaults = {
|
206
|
+
"base_template": "adk_base",
|
207
|
+
"name": template_dir.name,
|
208
|
+
"description": "",
|
209
|
+
}
|
210
|
+
config.update(defaults)
|
211
|
+
|
212
|
+
# Load from pyproject.toml if it exists
|
213
|
+
pyproject_path = template_dir / "pyproject.toml"
|
214
|
+
if pyproject_path.exists():
|
215
|
+
try:
|
216
|
+
with open(pyproject_path, "rb") as f:
|
217
|
+
pyproject_data = tomllib.load(f)
|
218
|
+
|
219
|
+
# Extract the agent-starter-pack configuration
|
220
|
+
toml_config = pyproject_data.get("tool", {}).get("agent-starter-pack", {})
|
221
|
+
|
222
|
+
# Fallback to [project] fields if not specified in agent-starter-pack section
|
223
|
+
project_info = pyproject_data.get("project", {})
|
224
|
+
|
225
|
+
# Apply pyproject.toml configuration (overrides defaults)
|
226
|
+
if toml_config:
|
227
|
+
config.update(toml_config)
|
228
|
+
|
229
|
+
# Apply [project] fallbacks if not already set
|
230
|
+
if "name" not in toml_config and "name" in project_info:
|
231
|
+
config["name"] = project_info["name"]
|
232
|
+
|
233
|
+
if "description" not in toml_config and "description" in project_info:
|
234
|
+
config["description"] = project_info["description"]
|
235
|
+
|
236
|
+
logging.debug(f"Loaded template config from {pyproject_path}")
|
237
|
+
except Exception as e:
|
238
|
+
logging.error(f"Error loading pyproject.toml config: {e}")
|
239
|
+
|
240
|
+
# Apply CLI overrides (highest precedence) using deep merge
|
241
|
+
if cli_overrides:
|
242
|
+
config = merge_template_configs(config, cli_overrides)
|
243
|
+
logging.debug(f"Applied CLI overrides: {cli_overrides}")
|
244
|
+
|
245
|
+
return config
|
207
246
|
|
208
247
|
|
209
248
|
def get_base_template_name(config: dict[str, Any]) -> str:
|