Skip to content

Framework switch #294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions agentstack/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
from .cli import configure_default_model, welcome_message, get_validated_input, parse_insertion_point
from .cli import (
configure_default_model,
welcome_message,
get_validated_input,
parse_insertion_point,
undo,
)
from .init import init_project
from .wizard import run_wizard
from .run import run_project
from .tools import list_tools, add_tool, remove_tool
from .tasks import add_task
from .agents import add_agent
from .templates import insert_template, export_template
from .templates import insert_template, export_template, switch_framework

20 changes: 20 additions & 0 deletions agentstack/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from agentstack.exceptions import ValidationError
from agentstack.utils import validator_not_empty, is_snake_case
from agentstack.generation import InsertionPoint
from agentstack import repo


PREFERRED_MODELS = [
Expand Down Expand Up @@ -34,6 +35,25 @@
log.info(border)


def undo() -> None:
"""Undo the last committed changes."""
conf.assert_project()

Check warning on line 40 in agentstack/cli/cli.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/cli.py#L40

Added line #L40 was not covered by tests

changed_files = repo.get_uncommitted_files()

Check warning on line 42 in agentstack/cli/cli.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/cli.py#L42

Added line #L42 was not covered by tests
if changed_files:
log.warning("There are uncommitted changes that may be overwritten.")

Check warning on line 44 in agentstack/cli/cli.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/cli.py#L44

Added line #L44 was not covered by tests
for changed in changed_files:
log.info(f" - {changed}")
should_continue = inquirer.confirm(

Check warning on line 47 in agentstack/cli/cli.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/cli.py#L46-L47

Added lines #L46 - L47 were not covered by tests
message="Do you want to continue?",
default=False,
)
if not should_continue:
return

Check warning on line 52 in agentstack/cli/cli.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/cli.py#L52

Added line #L52 was not covered by tests

repo.revert_last_commit(hard=True)

Check warning on line 54 in agentstack/cli/cli.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/cli.py#L54

Added line #L54 was not covered by tests


def configure_default_model():
"""Set the default model"""
agentstack_config = ConfigFile()
Expand Down
29 changes: 27 additions & 2 deletions agentstack/cli/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
cookiecutter(str(template_path), no_input=True, extra_context=None)


def export_template(output_filename: str):
def _export_template_data() -> TemplateConfig:
"""
Export the current project as a template.
"""
Expand Down Expand Up @@ -137,7 +137,7 @@
]
)

template = TemplateConfig(
return TemplateConfig(

Check warning on line 140 in agentstack/cli/templates.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/templates.py#L140

Added line #L140 was not covered by tests
template_version=CURRENT_VERSION,
name=metadata.project_name,
description=metadata.project_description,
Expand All @@ -151,8 +151,33 @@
graph=graph,
)


def export_template(output_filename: str):
"""
Export the current project as a template file.
"""
template = _export_template_data()

Check warning on line 159 in agentstack/cli/templates.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/templates.py#L159

Added line #L159 was not covered by tests
try:
template.write_to_file(conf.PATH / output_filename)
log.success(f"Template saved to: {conf.PATH / output_filename}")
except Exception as e:
raise Exception(f"Failed to write template to file: {e}")


def switch_framework(framework: str) -> None:
"""
Switch the current project to a different framework.

- export the current project as a template.
- create a new branch & switch to it.
- empty the directory (hopefully partially, but cookiecutter wants an empty dir)
- generate a new project with `insert_template`
"""
if not framework in frameworks.SUPPORTED_FRAMEWORKS:
raise ValueError(f"Framework {framework} is not supported.")

Check warning on line 177 in agentstack/cli/templates.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/templates.py#L177

Added line #L177 was not covered by tests

raise NotImplementedError("switch_framework is not implemented")

Check warning on line 179 in agentstack/cli/templates.py

View check run for this annotation

Codecov / codecov/patch

agentstack/cli/templates.py#L179

Added line #L179 was not covered by tests
template = _export_template_data()
# TODO we can't do this with cookiecutter
insert_template(template.name, template, framework=framework)

18 changes: 17 additions & 1 deletion agentstack/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
add_task,
run_project,
export_template,
undo,
switch_framework,
)
from agentstack.telemetry import track_cli_command, update_telemetry
from agentstack.utils import get_version, term_color
Expand Down Expand Up @@ -154,7 +156,14 @@
)
export_parser.add_argument('filename', help='The name of the file to export to')

update = subparsers.add_parser('update', aliases=['u'], help='Check for updates', parents=[global_parser])
switch_parser = subparsers.add_parser('switch', help='Switch frameworks', parents=[global_parser])
switch_subparsers = switch_parser.add_subparsers(dest='switch_command', help='Switch commands')

Check warning on line 160 in agentstack/main.py

View check run for this annotation

Codecov / codecov/patch

agentstack/main.py#L159-L160

Added lines #L159 - L160 were not covered by tests

switch_framework_parser = switch_subparsers.add_parser('framework', help='Switch frameworks')
switch_framework_parser.add_argument('framework', help='The framework to switch to')

Check warning on line 163 in agentstack/main.py

View check run for this annotation

Codecov / codecov/patch

agentstack/main.py#L162-L163

Added lines #L162 - L163 were not covered by tests

undo_parser = subparsers.add_parser('undo', help='Undo the last change to your project', parents=[global_parser])
update_parser = subparsers.add_parser('update', aliases=['u'], help='Check for updates', parents=[global_parser])

Check warning on line 166 in agentstack/main.py

View check run for this annotation

Codecov / codecov/patch

agentstack/main.py#L165-L166

Added lines #L165 - L166 were not covered by tests

# Parse known args and store unknown args in extras; some commands use them later on
args, extra_args = parser.parse_known_args()
Expand Down Expand Up @@ -228,6 +237,13 @@
generate_parser.print_help()
elif args.command in ['export', 'e']:
export_template(args.filename)
elif args.command in ['switch']:
if args.switch_command in ['framework']:
switch_framework(args.framework)

Check warning on line 242 in agentstack/main.py

View check run for this annotation

Codecov / codecov/patch

agentstack/main.py#L242

Added line #L242 was not covered by tests
else:
switch_parser.print_help()

Check warning on line 244 in agentstack/main.py

View check run for this annotation

Codecov / codecov/patch

agentstack/main.py#L244

Added line #L244 was not covered by tests
elif args.command in ['undo']:
undo()

Check warning on line 246 in agentstack/main.py

View check run for this annotation

Codecov / codecov/patch

agentstack/main.py#L246

Added line #L246 was not covered by tests
else:
parser.print_help()

Expand Down
21 changes: 21 additions & 0 deletions agentstack/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,24 @@
untracked = repo.untracked_files
modified = [item.a_path for item in repo.index.diff(None) if item.a_path]
return untracked + modified


def revert_last_commit(hard: bool = False) -> None:
"""
Revert the last commit in the current project.
"""
try:
repo = _get_repo()
except EnvironmentError as e:
return # git is not installed or tracking is disabled

Check warning on line 202 in agentstack/repo.py

View check run for this annotation

Codecov / codecov/patch

agentstack/repo.py#L199-L202

Added lines #L199 - L202 were not covered by tests

if len(repo.head.commit.parents) == 0:
log.error("No commits to revert.")
return

Check warning on line 206 in agentstack/repo.py

View check run for this annotation

Codecov / codecov/patch

agentstack/repo.py#L205-L206

Added lines #L205 - L206 were not covered by tests

def _format_commit_message(commit):
return commit.message.split('\n')[0]

Check warning on line 209 in agentstack/repo.py

View check run for this annotation

Codecov / codecov/patch

agentstack/repo.py#L208-L209

Added lines #L208 - L209 were not covered by tests

log.info(f"Reverting: {_format_commit_message(repo.head.commit)}")
repo.git.reset('HEAD~1', hard=hard)
log.info(f"Head is now at: {_format_commit_message(repo.head.commit)}")

Check warning on line 213 in agentstack/repo.py

View check run for this annotation

Codecov / codecov/patch

agentstack/repo.py#L211-L213

Added lines #L211 - L213 were not covered by tests
59 changes: 51 additions & 8 deletions docs/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -514,10 +514,6 @@ which adheres to a common pattern or exporting your project to share.
Templates are versioned, and each previous version provides a method to convert
it's content to the current version.

> TODO: Templates are currently identified as `proj_templates` since they conflict
with the templates used by `generation`. Move existing templates to be part of
the generation package.

### `TemplateConfig.from_user_input(identifier: str)`
`<TemplateConfig>` Returns a `TemplateConfig` object for either a URL, file path,
or builtin template name.
Expand Down Expand Up @@ -716,7 +712,7 @@ title: 'System Analyzer'
description: 'Inspect a project directory and improve it'
---

[View Template](https://github.com/AgentOps-AI/AgentStack/blob/main/agentstack/templates/proj_templates/system_analyzer.json)
[View Template](https://github.com/AgentOps-AI/AgentStack/blob/main/agentstack/templates/system_analyzer.json)

```bash
agentstack init --template=system_analyzer
Expand All @@ -737,7 +733,7 @@ title: 'Researcher'
description: 'Research and report result from a query'
---

[View Template](https://github.com/AgentOps-AI/AgentStack/blob/main/agentstack/templates/proj_templates/research.json)
[View Template](https://github.com/AgentOps-AI/AgentStack/blob/main/agentstack/templates/research.json)

```bash
agentstack init --template=research
Expand Down Expand Up @@ -828,7 +824,54 @@ title: 'Content Creator'
description: 'Research a topic and create content on it'
---

[View Template](https://github.com/AgentOps-AI/AgentStack/blob/main/agentstack/templates/proj_templates/content_creator.json)
[View Template](https://github.com/AgentOps-AI/AgentStack/blob/main/agentstack/templates/content_creator.json)

## frameworks/list.mdx

---
title: Frameworks
description: 'Supported frameworks in AgentStack'
icon: 'ship'
---

These are documentation links to the frameworks supported directly by AgentStack.

To start a project with one of these frameworks, use
```bash
agentstack init <project_name> --framework <framework_name>
```

## Framework Docs
<CardGroup cols={3}>
<Card
title="CrewAI"
icon="ship"
href="https://docs.crewai.com/introduction"
>
An intuitive agentic framework (recommended)
</Card>
<Card
title="LangGraph"
icon="circle-nodes"
href="https://langchain-ai.github.io/langgraph/"
>
A complex but capable framework with a _steep_ learning curve
</Card>
<Card
title="OpenAI Swarms"
icon="bee"
href="https://github.com/openai/swarm"
>
A simple framework with a cult following
</Card>
<Card
title="LlamaIndex"
icon="layer-group"
href="https://docs.llamaindex.ai/en/stable/"
>
An expansive framework with many ancillary features
</Card>
</CardGroup>

## tools/package-structure.mdx

Expand Down Expand Up @@ -1043,7 +1086,7 @@ You can pass the `--wizard` flag to `agentstack init` to use an interactive proj
You can also pass a `--template=<template_name>` argument to `agentstack init` which will pre-populate your project with functionality
from a built-in template, or one found on the internet. A `template_name` can be one of three identifiers:

- A built-in AgentStack template (see the `templates/proj_templates` directory in the AgentStack repo for bundled templates).
- A built-in AgentStack template (see the `templates` directory in the AgentStack repo for bundled templates).
- A template file from the internet; pass the full https URL of the template.
- A local template file; pass an absolute or relative path.

Expand Down