Skip to content

Commit 4e548fe

Browse files
committed
Merge branch 'main' into firecrawl-tool
# Conflicts: # agentstack/_tools/vision/__init__.py # agentstack/_tools/vision/config.json
2 parents a99694f + a996ba3 commit 4e548fe

File tree

174 files changed

+8913
-1791
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+8913
-1791
lines changed

.github/workflows/codecov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
pip install tox
3232
3333
- name: Run tests with tox
34-
run: tox
34+
run: tox -m quick # quick runs all 3.12 tests and then combines coverage
3535

3636
- name: Upload coverage to Codecov
3737
uses: codecov/codecov-action@v5

.github/workflows/python-testing.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,17 @@ jobs:
2525

2626
strategy:
2727
matrix:
28-
python-version: [3.10,3.11,3.12]
28+
python-version: ["3.10","3.11","3.12"] # versions need to be strings
2929

3030
steps:
3131
- uses: actions/checkout@v2
3232
- name: Set up Python
33-
uses: actions/setup-python@v2
33+
uses: actions/setup-python@v5
3434
with:
35-
python-version: '3.11' # Use a default Python version for running tox
35+
python-version: ${{ matrix.python-version }}
3636
- name: Install tox
3737
run: pip install tox
38+
- name: Install tox-gh-actions
39+
run: pip install tox-gh-actions # allows tox to get the current python version
3840
- name: Run tests with tox
39-
run: tox
41+
run: tox # we can't pass arguments to tox when using tox-gh-actions, so all frameworks happen in one run

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,13 @@ ex/
175175
**/ex/
176176
cookiecutter.json
177177

178+
tests/tmp
179+
178180
examples/tests/
179181
examples/tests/**/*
180182

181183
uv.lock
182184
.DS_Store
183185

186+
.python-version
187+

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
recursive-include agentstack/templates *
2+
recursive-include agentstack/frameworks/templates *
23
recursive-include agentstack/_tools *
34
include agentstack.json .env .env.example

README.md

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,16 @@ agentstack init <project_name>
2727
AgentStack scaffolds your _agent stack_ - the tech stack that collectively is your agent
2828

2929
<p align='center'>
30-
<img src='https://github.com/AgentOps-AI/AgentStack/blob/7b40e53bf7300f69e3291c62d5b45e46ff818245/docs/images/the_agent_stack.png?raw=true' width='600' alt='agentstack init'>
30+
<img src='https://github.com/AgentOps-AI/AgentStack/blob/main/docs/images/the_agent_stack.png?raw=true' width='600' alt='agentstack init'>
3131
</p>
3232

33+
### Currently Supported Providers
34+
- **LLMs**: Most all notable LLMs and providers are supported via LiteLLM or LangChain
35+
- **Framework**: Currently supported frameworks include CrewAI, LangGraph, OpenAI Swarms and LlamaStack
36+
- Roadmap: Pydantic AI, Eliza, AG2 and Autogen
37+
- **Tools**: Maintaining the largest repository of framework-agnostic tools! All tools listed [here](https://docs.agentstack.sh/tools/community)
38+
- **Observability**: AgentOps baked in by default with first-tier support
39+
3340
### Get Started Immediately
3441

3542
You **don't** need to install or configure tools like LangChain or LlamaIndex.<br>
@@ -44,7 +51,7 @@ Create a project, and you're good to go.
4451
To create a new agent project, run:
4552

4653
```sh
47-
pip install agentstack
54+
uv pip install agentstack
4855
agentstack init <project_name>
4956
```
5057

@@ -56,10 +63,17 @@ Once the initialization is done, you can open your project folder:
5663

5764
```sh
5865
cd <your_agent_project>
66+
uv pip install
67+
```
68+
69+
then run the default agent!
70+
71+
```sh
72+
agentstack run
5973
```
6074

6175
### Templates
62-
Additionally, pre-built templates are available as a shortcut to building your project. [View the available templates]().
76+
Additionally, pre-built templates are available as a shortcut to building your project. [View the available templates](https://docs.agentstack.sh/templates).
6377

6478
## Building Agent Functionality
6579

@@ -101,33 +115,36 @@ Runs the agent project in development mode.<br>
101115

102116
- **No Lock-In:** You can customize your setup at any time. AgentStack is designed to make it easy to get the components you need running right off the bat; it's up to you what to do next.
103117

118+
- **Provider Agnosticism:** AgentStack is designed to be provider agnostic in all ways. This means especially that the framework layer of your agent stack should be interoperable with every other layer. Frameworks must still be supported by AgentStack. See supported frameworks above.
119+
104120
AgentStack is not designed to be a low-code solution to building agents. Instead it is a great head-start for starting an agent project from scratch.
105121

106122
## Roadmap
107123

108-
### Framework Agnosticism
109-
110-
Development of AgentStack is being done primarily on [CrewAI](https://crewai.com). We will soon be working to make AgentStack fully framework-agnostic, meaning that any supported multi-agent framework can be used for your project.
111-
112124
### Tools
113-
- Core Tools built by AgentStack
125+
- More [core tools](https://docs.agentstack.sh/tools/core) built by AgentStack
114126
- Preferred partners in the package directly
115127
- Community partner tools added through external repositories
116128

129+
### New Stack Layers
130+
- Prompting layer (DSPy)
131+
- Eval Layer
132+
- UI layer
133+
117134
### Other Features
118135
- Generated testing
119136
- Integrated benchmarking
120137
- Easy integration of tools for browsing, RAG, and more.
121138
- A fast interactive test runner with built-in support for coverage reporting.
122-
- A live development server that warns about common mistakes.
123-
- A build script to bundle your project for production.
139+
- A live development server that warns about common mistakes (in progress).
140+
- A build script to bundle your project for production (in progress).
124141

125142
## License
126143

127144
AgentStack is open source software [licensed as MIT](LICENSE).
128145

129146
## How to Contribute
130147

131-
AgentStack is a new project built by passionate AI agent developers! We'd love help making this tool better. Easy first issues are available, create new issues with feature ideas, or chat with us on our [Discord](https://discord.gg/JdWkh9tgTQ).
148+
AgentStack is a new project built by passionate AI agent developers! We'd love help making this tool better. Easy first issues are available, create new issues with feature ideas, or chat with us on our [Discord](https://discord.gg/JdWkh9tgTQ). Make sure you read our contributor documentation to familiarize yourself with the project at [How to Contribute](https://docs.agentstack.sh/contributing/how-to-contribute).
132149

133150
If you are an Agent Tool developer, feel free to create an issue or even a PR to add your tool to AgentStack.

agentstack/__init__.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,46 @@
99
from pathlib import Path
1010
from agentstack import conf
1111
from agentstack.utils import get_framework
12+
from agentstack.agents import get_agent, get_all_agents, get_all_agent_names
13+
from agentstack.tasks import get_task, get_all_tasks, get_all_task_names
1214
from agentstack.inputs import get_inputs
1315
from agentstack import frameworks
1416

1517
___all___ = [
16-
"conf",
17-
"tools",
18-
"get_tags",
19-
"get_framework",
20-
"get_inputs",
18+
"conf",
19+
"agent",
20+
"task",
21+
"tools",
22+
"get_tags",
23+
"get_framework",
24+
"get_agent",
25+
"get_all_agents",
26+
"get_all_agent_names",
27+
"get_task",
28+
"get_all_tasks",
29+
"get_all_task_names",
30+
"get_inputs",
2131
]
2232

33+
def agent(func):
34+
"""
35+
The `agent` decorator is used to mark a method that implements an Agent.
36+
"""
37+
def wrap(*args, **kwargs):
38+
"""Does not alter the function's behavior; this is just a marker."""
39+
return func(*args, **kwargs)
40+
return wrap
41+
42+
43+
def task(func):
44+
"""
45+
The `task` decorator is used to mark a method that implements a Task.
46+
"""
47+
def wrap(*args, **kwargs):
48+
"""Does not alter the function's behavior; this is just a marker."""
49+
return func(*args, **kwargs)
50+
return wrap
51+
2352

2453
def get_tags() -> list[str]:
2554
"""

agentstack/_tools/__init__.py

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,23 @@
77
import pydantic
88
from agentstack.exceptions import ValidationError
99
from agentstack.utils import get_package_path, open_json_file, term_color, snake_to_camel
10+
from agentstack import conf, log
1011

1112

1213
TOOLS_DIR: Path = get_package_path() / '_tools' # NOTE: if you change this dir, also update MANIFEST.in
1314
TOOLS_CONFIG_FILENAME: str = 'config.json'
1415

1516

17+
def _get_custom_tool_path(name: str) -> Path:
18+
"""Get the path to a custom tool."""
19+
return conf.PATH / 'src/tools' / name / TOOLS_CONFIG_FILENAME
20+
21+
22+
def _get_builtin_tool_path(name: str) -> Path:
23+
"""Get the path to a builtin tool."""
24+
return TOOLS_DIR / name / TOOLS_CONFIG_FILENAME
25+
26+
1627
class ToolConfig(pydantic.BaseModel):
1728
"""
1829
This represents the configuration data for a tool.
@@ -32,10 +43,15 @@ class ToolConfig(pydantic.BaseModel):
3243

3344
@classmethod
3445
def from_tool_name(cls, name: str) -> 'ToolConfig':
35-
path = TOOLS_DIR / name / TOOLS_CONFIG_FILENAME
36-
if not os.path.exists(path): # TODO raise exceptions and handle message/exit in cli
37-
print(term_color(f'No known agentstack tool: {name}', 'red'))
38-
sys.exit(1)
46+
# First check in the user's project directory for custom tools
47+
custom_path = _get_custom_tool_path(name)
48+
if custom_path.exists():
49+
return cls.from_json(custom_path)
50+
51+
# Then check in the package's tools directory
52+
path = _get_builtin_tool_path(name)
53+
if not path.exists():
54+
raise ValidationError(f'No known agentstack tool: {name}')
3955
return cls.from_json(path)
4056

4157
@classmethod
@@ -44,11 +60,18 @@ def from_json(cls, path: Path) -> 'ToolConfig':
4460
try:
4561
return cls(**data)
4662
except pydantic.ValidationError as e:
47-
# TODO raise exceptions and handle message/exit in cli
48-
print(term_color(f"Error validating tool config JSON: \n{path}", 'red'))
63+
error_str = "Error validating tool config:\n"
4964
for error in e.errors():
50-
print(f"{' '.join([str(loc) for loc in error['loc']])}: {error['msg']}")
51-
sys.exit(1)
65+
error_str += f"{' '.join([str(loc) for loc in error['loc']])}: {error['msg']}\n"
66+
raise ValidationError(f"Error loading tool from {path}.\n{error_str}")
67+
68+
def write_to_file(self, filename: Path):
69+
"""Write the tool config to a json file."""
70+
if not filename.suffix == '.json':
71+
raise ValidationError(f"Filename must end with .json: {filename}")
72+
73+
with open(filename, 'w') as f:
74+
f.write(self.model_dump_json())
5275

5376
@property
5477
def type(self) -> type:
@@ -76,6 +99,12 @@ def not_implemented(*args, **kwargs):
7699
@property
77100
def module_name(self) -> str:
78101
"""Module name for the tool module."""
102+
# Check if this is a custom tool in the user's project
103+
custom_path = _get_custom_tool_path(self.name)
104+
if custom_path.exists():
105+
return f"src.tools.{self.name}"
106+
107+
# Otherwise, it's a package tool
79108
return f"agentstack._tools.{self.name}"
80109

81110
@property
@@ -107,19 +136,36 @@ def get_all_tool_paths() -> list[Path]:
107136
Get all the paths to the tool configuration files.
108137
ie. agentstack/_tools/<tool_name>/
109138
Tools are identified by having a `config.json` file inside the _tools/<tool_name> directory.
139+
Also checks the user's project directory for custom tools.
110140
"""
111141
paths = []
142+
143+
# Get package tools
112144
for tool_dir in TOOLS_DIR.iterdir():
113145
if tool_dir.is_dir():
114146
config_path = tool_dir / TOOLS_CONFIG_FILENAME
115147
if config_path.exists():
116148
paths.append(tool_dir)
149+
150+
# Get custom tools from user's project if in a project directory
151+
if conf.PATH:
152+
custom_tools_dir = conf.PATH / 'src/tools'
153+
if custom_tools_dir.exists():
154+
for tool_dir in custom_tools_dir.iterdir():
155+
if tool_dir.is_dir():
156+
config_path = tool_dir / TOOLS_CONFIG_FILENAME
157+
if config_path.exists():
158+
paths.append(tool_dir)
159+
117160
return paths
118161

119162

120163
def get_all_tool_names() -> list[str]:
121-
return [path.stem for path in get_all_tool_paths()]
164+
"""Get names of all available tools, including custom tools."""
165+
return [path.name for path in get_all_tool_paths()]
122166

123167

124168
def get_all_tools() -> list[ToolConfig]:
125-
return [ToolConfig.from_tool_name(path) for path in get_all_tool_names()]
169+
"""Get all tool configs, including custom tools."""
170+
tool_names = get_all_tool_names()
171+
return [ToolConfig.from_tool_name(name) for name in tool_names]

agentstack/_tools/composio/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"find_actions_by_tags"
1313
],
1414
"dependencies": [
15-
"composio>=1.0.0"
15+
"composio-core>=0.6.0"
1616
],
1717
"cta": "!!! Composio provides 150+ tools. Additional setup is required in agentstack/tools/composio/__init__.py"
1818
}

agentstack/_tools/file_read/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
"category": "computer-control",
44
"tools": ["read_file"],
55
"description": "Read contents of files",
6-
"url": "https://github.com/AgentOps-AI/AgentStack/tree/main/agentstack/tools/file_read",
6+
"url": "https://docs.agentstack.sh/tools/tool/file_read",
77
"dependencies": []
88
}

agentstack/_tools/neon/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
},
88
"dependencies": [
99
"neon-api>=0.1.5",
10-
"psycopg2-binary"
10+
"psycopg2-binary==2.9.10"
1111
],
1212
"tools": ["create_database", "execute_sql_ddl", "run_sql_query"],
1313
"cta": "Create an API key at https://www.neon.tech"

0 commit comments

Comments
 (0)