diff --git a/agentstack/cli/cli.py b/agentstack/cli/cli.py index bc5648c6..df65d01e 100644 --- a/agentstack/cli/cli.py +++ b/agentstack/cli/cli.py @@ -123,18 +123,9 @@ def init_project_builder( log.debug(f"project_details: {project_details}" f"framework: {framework}" f"design: {design}") insert_template(project_details, framework, design, template_data) + path = Path(project_details['name']) for tool_data in tools: - generation.add_tool(tool_data['name'], agents=tool_data['agents'], path=project_details['name']) - - try: - packaging.install(f'{AGENTSTACK_PACKAGE}[{framework}]', path=slug_name) - except Exception: - print( - term_color( - f"Failed to install dependencies for {slug_name}. Please try again by running `agentstack update`", - 'red', - ) - ) + generation.add_tool(tool_data['name'], agents=tool_data['agents'], path=path) def welcome_message(): @@ -392,7 +383,9 @@ def insert_template( design: dict, template_data: Optional[dict] = None, ): - framework = FrameworkData(framework_name.lower()) + framework = FrameworkData( + name=framework_name.lower(), + ) project_metadata = ProjectMetadata( project_name=project_details["name"], description=project_details["description"], @@ -432,7 +425,7 @@ def insert_template( "red", ) ) - return + sys.exit(1) cookiecutter(str(template_path), no_input=True, extra_context=None) @@ -455,10 +448,13 @@ def insert_template( "🚀 \033[92mAgentStack project generated successfully!\033[0m\n\n" " Next, run:\n" f" cd {project_metadata.project_slug}\n" - " poetry install\n" - " agentstack run\n\n" + " python -m venv .venv\n" + " source .venv/bin/activate\n" + " poetry install\n\n" " Add agents and tasks with:\n" " `agentstack generate agent/task `\n\n" + " Run your agent with:\n" + " agentstack run\n\n" " Run `agentstack quickstart` or `agentstack docs` for next steps.\n" ) diff --git a/agentstack/generation/files.py b/agentstack/generation/files.py index 4400dc34..cbd38204 100644 --- a/agentstack/generation/files.py +++ b/agentstack/generation/files.py @@ -3,6 +3,7 @@ import json from pathlib import Path from pydantic import BaseModel +from agentstack.utils import get_version DEFAULT_FRAMEWORK = "crewai" @@ -34,12 +35,21 @@ class ConfigFile(BaseModel): Whether the user has opted out of telemetry. default_model: Optional[str] The default model to use when generating agent configurations. + agentstack_version: Optional[str] + The version of agentstack used to generate the project. + template: Optional[str] + The template used to generate the project. + template_version: Optional[str] + The version of the template system used to generate the project. """ framework: str = DEFAULT_FRAMEWORK tools: list[str] = [] telemetry_opt_out: Optional[bool] = None default_model: Optional[str] = None + agentstack_version: Optional[str] = get_version() + template: Optional[str] = None + template_version: Optional[str] = None def __init__(self, path: Union[str, Path, None] = None): path = Path(path) if path else Path.cwd() diff --git a/agentstack/templates/crewai/{{cookiecutter.project_metadata.project_slug}}/pyproject.toml b/agentstack/templates/crewai/{{cookiecutter.project_metadata.project_slug}}/pyproject.toml index ce83ccac..a8d8807c 100644 --- a/agentstack/templates/crewai/{{cookiecutter.project_metadata.project_slug}}/pyproject.toml +++ b/agentstack/templates/crewai/{{cookiecutter.project_metadata.project_slug}}/pyproject.toml @@ -4,9 +4,11 @@ version = "{{cookiecutter.project_metadata.version}}" description = "{{cookiecutter.project_metadata.description}}" authors = ["{{cookiecutter.project_metadata.author_name}}"] license = "{{cookiecutter.project_metadata.license}}" +package-mode = false [tool.poetry.dependencies] python = ">=3.10,<=3.13" +agentstack = {extras = ["{{cookiecutter.framework}}"], version="{{cookiecutter.project_metadata.agentstack_version}}"} [project.scripts] {{cookiecutter.project_metadata.project_name}} = "{{cookiecutter.project_metadata.project_name}}.main:run" diff --git a/agentstack/utils.py b/agentstack/utils.py index 0bb32f93..c7c1ab61 100644 --- a/agentstack/utils.py +++ b/agentstack/utils.py @@ -58,6 +58,7 @@ def get_telemetry_opt_out(path: Optional[str] = None) -> bool: Gets the telemetry opt out setting. First checks the environment variable AGENTSTACK_TELEMETRY_OPT_OUT. If that is not set, it checks the agentstack.json file. + Otherwise we can assume the user has not opted out. """ from agentstack.generation import ConfigFile @@ -67,8 +68,7 @@ def get_telemetry_opt_out(path: Optional[str] = None) -> bool: agentstack_config = ConfigFile(path) return bool(agentstack_config.telemetry_opt_out) except FileNotFoundError: - print("\033[31mFile agentstack.json does not exist. Are you in the right directory?\033[0m") - sys.exit(1) + return False def camel_to_snake(name): diff --git a/tests/test_generation_files.py b/tests/test_generation_files.py index a2baf5ef..3a8f0a0e 100644 --- a/tests/test_generation_files.py +++ b/tests/test_generation_files.py @@ -7,6 +7,7 @@ verify_agentstack_project, get_framework, get_telemetry_opt_out, + get_version, ) BASE_PATH = Path(__file__).parent @@ -19,6 +20,9 @@ def test_read_config(self): assert config.tools == [] assert config.telemetry_opt_out is None assert config.default_model is None + assert config.agentstack_version == get_version() + assert config.template is None + assert config.template_version is None def test_write_config(self): try: @@ -30,6 +34,9 @@ def test_write_config(self): config.tools = ["tool1", "tool2"] config.telemetry_opt_out = True config.default_model = "openai/gpt-4o" + config.agentstack_version = "0.2.1" + config.template = "default" + config.template_version = "1" tmp_data = open(BASE_PATH / "tmp/agentstack.json").read() assert ( @@ -41,7 +48,10 @@ def test_write_config(self): "tool2" ], "telemetry_opt_out": true, - "default_model": "openai/gpt-4o" + "default_model": "openai/gpt-4o", + "agentstack_version": "0.2.1", + "template": "default", + "template_version": "1" }""" ) except Exception as e: