From 65e5fcc864905ee160d583c342d45ad1705e464f Mon Sep 17 00:00:00 2001 From: Braelyn Boynton Date: Wed, 27 Nov 2024 01:07:33 -0800 Subject: [PATCH] generate project from template --- 0.2-changes.md | 1 + agentstack/cli/agentstack_data.py | 6 ++++- agentstack/cli/cli.py | 24 ++++++++++++------- agentstack/generation/tool_generation.py | 2 +- agentstack/telemetry.py | 2 +- .../agentstack.json | 5 ++-- .../templates/proj_templates/research.json | 23 ++++++++---------- 7 files changed, 36 insertions(+), 27 deletions(-) diff --git a/0.2-changes.md b/0.2-changes.md index cd76fc59..beff03fa 100644 --- a/0.2-changes.md +++ b/0.2-changes.md @@ -74,6 +74,7 @@ We'll move forward with the codegen method unless other information comes to lig - dont place into a subdirectory - `--template ` - generate the project according to a template + - can also consume a url ### `agentstack tools` - Stays the same diff --git a/agentstack/cli/agentstack_data.py b/agentstack/cli/agentstack_data.py index 033a1f0e..952dddf6 100644 --- a/agentstack/cli/agentstack_data.py +++ b/agentstack/cli/agentstack_data.py @@ -15,7 +15,8 @@ def __init__(self, version: str = "", license: str = "", year: int = datetime.now().year, - template: str = "default" + template: str = "none", + template_version: str = "0", ): self.project_name = clean_input(project_name) if project_name else "myagent" self.project_slug = clean_input(project_slug) if project_slug else self.project_name @@ -26,6 +27,7 @@ def __init__(self, self.year = year self.agentstack_version = get_version() self.template = template + self.template_version = template log.debug(f"ProjectMetadata: {self.to_dict()}") @@ -39,6 +41,8 @@ def to_dict(self): 'license': self.license, 'year': self.year, 'agentstack_version': self.agentstack_version, + 'template': self.template, + 'template_version': self.template_version, } def to_json(self): diff --git a/agentstack/cli/cli.py b/agentstack/cli/cli.py index f7c37676..d7642480 100644 --- a/agentstack/cli/cli.py +++ b/agentstack/cli/cli.py @@ -23,7 +23,7 @@ def init_project_builder(slug_name: Optional[str] = None, template: Optional[str print(term_color("Project name must be snake case", 'red')) return - if template is not None and not use_wizard: + if template is not None and use_wizard: print(term_color("Template and wizard flags cannot be used together", 'red')) return @@ -39,7 +39,7 @@ def init_project_builder(slug_name: Optional[str] = None, template: Optional[str print(term_color(f"Failed to fetch template data from {template}. Status code: {response.status_code}", 'red')) sys.exit(1) else: - with importlib.resources.path('agentstack.templates.proj_templates', template) as template_path: + with importlib.resources.path('agentstack.templates.proj_templates', f'{template}.json') as template_path: if template_path is None: print(term_color(f"No such template {template} found", 'red')) sys.exit(1) @@ -58,8 +58,10 @@ def init_project_builder(slug_name: Optional[str] = None, template: Optional[str 'agents': template_data['agents'], 'tasks': template_data['tasks'] } - for tool_data in template_data['tools']: - generation.add_tool(tool_data['name'], agents=tool_data['agents'], path=project_details['name']) + + tools = template_data['tools'] + # for tool_data in template_data['tools']: + # generation.add_tool(tool_data['name'], agents=tool_data['agents'], path=project_details['name']) elif use_wizard: @@ -68,7 +70,7 @@ def init_project_builder(slug_name: Optional[str] = None, template: Optional[str welcome_message() framework = ask_framework() design = ask_design() - # tools = ask_tools() + tools = ask_tools() else: welcome_message() @@ -87,15 +89,17 @@ def init_project_builder(slug_name: Optional[str] = None, template: Optional[str 'tasks': [] } - # tools = [] + tools = [] log.debug( f"project_details: {project_details}" f"framework: {framework}" f"design: {design}" ) - insert_template(project_details, framework, design) + insert_template(project_details, framework, design, template_data) # add_tools(tools, project_details['name']) + for tool_data in tools: + generation.add_tool(tool_data['name'], agents=tool_data['agents'], path=project_details['name']) def welcome_message(): @@ -298,14 +302,16 @@ def ask_project_details(slug_name: Optional[str] = None) -> dict: return questions -def insert_template(project_details: dict, framework_name: str, design: dict): +def insert_template(project_details: dict, framework_name: str, design: dict, template_data: Optional[dict] = None): framework = FrameworkData(framework_name.lower()) project_metadata = ProjectMetadata(project_name=project_details["name"], description=project_details["description"], author_name=project_details["author"], version="0.0.1", license="MIT", - year=datetime.now().year) + year=datetime.now().year, + template=template_data['name'], + template_version=template_data['template_version'] if template_data else None) project_structure = ProjectStructure() project_structure.agents = design["agents"] diff --git a/agentstack/generation/tool_generation.py b/agentstack/generation/tool_generation.py index 6097ae02..9dc152d9 100644 --- a/agentstack/generation/tool_generation.py +++ b/agentstack/generation/tool_generation.py @@ -321,7 +321,7 @@ def modify_agent_tools( base_name: Base module name for tools (default: 'tools') """ if agents is not None: - valid_agents = get_agent_names() + valid_agents = get_agent_names(path=path) for agent in agents: if agent not in valid_agents: print(term_color(f"Agent '{agent}' not found in the project.", 'red')) diff --git a/agentstack/telemetry.py b/agentstack/telemetry.py index 01fb7e09..db613c8c 100644 --- a/agentstack/telemetry.py +++ b/agentstack/telemetry.py @@ -33,7 +33,7 @@ TELEMETRY_URL = 'https://api.agentstack.sh/telemetry' def collect_machine_telemetry(command: str): - if get_telemetry_opt_out(): + if command != "init" and get_telemetry_opt_out(): return telemetry_data = { diff --git a/agentstack/templates/crewai/{{cookiecutter.project_metadata.project_slug}}/agentstack.json b/agentstack/templates/crewai/{{cookiecutter.project_metadata.project_slug}}/agentstack.json index 6296e2ad..5511a17a 100644 --- a/agentstack/templates/crewai/{{cookiecutter.project_metadata.project_slug}}/agentstack.json +++ b/agentstack/templates/crewai/{{cookiecutter.project_metadata.project_slug}}/agentstack.json @@ -1,5 +1,6 @@ { "framework": "{{ cookiecutter.framework }}", - "agentstack_version": "{{ cookiecutter.agentstack_version }}", - "template": "{{ cookiecutter.template }}" + "agentstack_version": "{{ cookiecutter.project_metadata.agentstack_version }}", + "template": "{{ cookiecutter.project_metadata.template }}", + "template_version": "{{ cookiecutter.project_metadata.template_version }}" } \ No newline at end of file diff --git a/agentstack/templates/proj_templates/research.json b/agentstack/templates/proj_templates/research.json index d3e6cf76..b27b19c7 100644 --- a/agentstack/templates/proj_templates/research.json +++ b/agentstack/templates/proj_templates/research.json @@ -1,23 +1,20 @@ { "name": "research", "description": "Starter project research agent", - "framework": "Framework", + "template_version": 1, + "framework": "crewai", "agents": [{ "name": "researcher", - "prompt": { - "role": "Gather data using research tools.", - "goal": "Collect all relevant information asked for using the tools available to you. The data will be analyzed later, compile a result of all data that you believe to be relevant to the query.", - "backstory": "You are an expert researcher. You are given a query and are tasked with providing as much relevant data in a concise manner." - }, - "llm": "openai/gpt-4o" + "role": "Gather data using research tools.", + "goal": "Collect all relevant information asked for using the tools available to you. The data will be analyzed later, compile a result of all data that you believe to be relevant to the query.", + "backstory": "You are an expert researcher. You are given a query and are tasked with providing as much relevant data in a concise manner.", + "model": "openai/gpt-4o" },{ "name": "analyst", - "prompt": { - "role": "Analyze gathered data.", - "goal": "Analyze and consolidate the data gathered from research to adequately answer the query provided in the task.", - "backstory": "You are an expert analyst. You are given a collection of research results and should use your knowledge to make conclusions on the data without making any assumptions that are not specifically supported by the data." - }, - "llm": "openai/gpt-4o" + "role": "Analyze gathered data.", + "goal": "Analyze and consolidate the data gathered from research to adequately answer the query provided in the task.", + "backstory": "You are an expert analyst. You are given a collection of research results and should use your knowledge to make conclusions on the data without making any assumptions that are not specifically supported by the data.", + "model": "openai/gpt-4o" }], "tasks": [{ "name": "research",