Skip to content

Commit 268d0ca

Browse files
committed
progress
1 parent 29ded9e commit 268d0ca

File tree

10 files changed

+1025
-27
lines changed

10 files changed

+1025
-27
lines changed

agentstack/templates/crewai/tools/neon_tool.py

-19
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,3 @@ def delete_database(project_id: str, database_name: str) -> str:
7575
return f"Database {database_name} deleted successfully"
7676
except Exception as e:
7777
return f"Failed to delete database: {str(e)}"
78-
79-
@tool("Create Branch")
80-
def create_branch(project_id: str, branch_name: str) -> str:
81-
"""
82-
Creates a new branch in specified Neon project.
83-
Args:
84-
project_id: ID of the project
85-
branch_name: Name of the branch to create
86-
Returns:
87-
Status message about branch creation
88-
"""
89-
try:
90-
result = neon_client.branches.create(
91-
project_id=project_id,
92-
name=branch_name
93-
)
94-
return f"Branch {branch_name} created successfully"
95-
except Exception as e:
96-
return f"Failed to create branch: {str(e)}"

examples/web_researcher/poetry.lock

+92-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/web_researcher/pyproject.toml

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ crewai = "^0.63.6"
1212
crewai-tools= "0.12.1"
1313
python-dotenv="1.0.1"
1414
firecrawl-py = "^1.4.0"
15+
neon-api = "^0.1.4"
16+
psycopg2-binary = "^2.9.9"
1517

1618
[project.scripts]
1719
web_researcher = "web_researcher.main:run"

examples/web_researcher/src/config/agents.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,12 @@ content_summarizer:
1313
analyze the contents of a web page and summarize
1414
backstory: >-
1515
you are an expert content writer who concisely summarizes technical writing
16+
llm: openai/gpt-4o
17+
content_storer:
18+
role: >-
19+
content storer
20+
goal: >-
21+
store the contents of a web page in a database
22+
backstory: >-
23+
you are an expert database engineer who knows how to use neon postgres to create tables, insert data, and query data
1624
llm: openai/gpt-4o

examples/web_researcher/src/config/tasks.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,10 @@ summarize:
1212
one paragraph text output
1313
agent: >-
1414
content_summarizer
15+
store:
16+
description: >-
17+
store the contents of the website in a postgres database
18+
expected_output: >-
19+
the sql query to retrieve the contents of the website from the database
20+
agent: >-
21+
content_storer

examples/web_researcher/src/crew.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ def web_scraper(self) -> Agent:
2424
verbose=True
2525
)
2626

27+
@agent
28+
def content_storer(self) -> Agent:
29+
return Agent(
30+
config=self.agents_config['content_storer'],
31+
tools=[tools.create_database, tools.execute_sql_ddl, tools.run_sql_query], # add tools here or use `agentstack tools add <tool_name>
32+
verbose=True
33+
)
34+
2735
# Task definitions
2836
@task
2937
def scrape_site(self) -> Task:
@@ -37,6 +45,12 @@ def summarize(self) -> Task:
3745
config=self.tasks_config['summarize'],
3846
)
3947

48+
@task
49+
def store(self) -> Task:
50+
return Task(
51+
config=self.tasks_config['store'],
52+
)
53+
4054
@crew
4155
def crew(self) -> Crew:
4256
"""Creates the Test crew"""
@@ -46,4 +60,4 @@ def crew(self) -> Crew:
4660
process=Process.sequential,
4761
verbose=True,
4862
# process=Process.hierarchical, # In case you wanna use that instead https://docs.crewai.com/how-to/Hierarchical/
49-
)
63+
)

examples/web_researcher/src/tools/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
# tool import
33

44
from .firecrawl_tool import web_scrape, web_crawl, retrieve_web_crawl
5+
6+
from .neon_tool import create_database, execute_sql_ddl, run_sql_query
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import os
2+
from crewai_tools import tool
3+
from dotenv import load_dotenv
4+
from neon_api import NeonAPI
5+
import psycopg2
6+
from psycopg2.extras import RealDictCursor
7+
8+
load_dotenv()
9+
10+
NEON_API_KEY = os.getenv('NEON_API_KEY')
11+
neon_client = NeonAPI(api_key=NEON_API_KEY)
12+
13+
@tool("Create Neon Project and Database")
14+
def create_database(project_name: str) -> str:
15+
"""
16+
Creates a new Neon project.
17+
Args:
18+
project_name: Name of the project to create
19+
Returns:
20+
the connection URI for the new project
21+
"""
22+
try:
23+
project = neon_client.project_create(project={"name": project_name}).project
24+
connection_uri = neon_client.connection_uri(project_id=project.id, database_name="neondb", role_name="neondb_owner").uri
25+
return f"Project/database created, connection URI: {connection_uri}"
26+
except Exception as e:
27+
return f"Failed to create project: {str(e)}"
28+
29+
30+
@tool("Execute SQL DDL")
31+
def execute_sql_ddl(connection_uri: str, command: str) -> str:
32+
"""
33+
Inserts data into a specified Neon database.
34+
Args:
35+
connection_uri: The connection URI for the Neon database
36+
command: The DDL command to execute
37+
Returns:
38+
the result of the DDL command
39+
"""
40+
conn = psycopg2.connect(connection_uri)
41+
cur = conn.cursor(cursor_factory=RealDictCursor)
42+
cur.execute(command)
43+
result = cur.fetchone()
44+
cur.close()
45+
conn.close()
46+
return f"Command result: {result}"
47+
48+
49+
@tool("Execute SQL DML")
50+
def run_sql_query(connection_uri: str, query: str) -> str:
51+
"""
52+
Inserts data into a specified Neon database.
53+
Args:
54+
connection_uri: The connection URI for the Neon database
55+
query: The SQL query to execute
56+
Returns:
57+
the result of the SQL query
58+
"""
59+
conn = psycopg2.connect(connection_uri)
60+
cur = conn.cursor(cursor_factory=RealDictCursor)
61+
cur.query(query)
62+
records = cur.fetchall()
63+
cur.close()
64+
conn.close()
65+
return f"Query result: {records}"

0 commit comments

Comments
 (0)