Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ agentstack tools add <tool_name>

## Running Your Agent

`python src/main.py`
`agentstack run`

Runs the agent project in development mode.<br>

Expand Down
2 changes: 1 addition & 1 deletion agentstack/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def insert_template(project_details: dict, framework_name: str, design: dict):
" Next, run:\n"
f" cd {project_metadata.project_slug}\n"
" poetry install\n"
" poetry run python src/main.py\n\n"
" agentstack run\n\n"
" Add agents and tasks with:\n"
" `agentstack generate agent/task <name>`\n\n"
" Run `agentstack quickstart` or `agentstack docs` for next steps.\n"
Expand Down
13 changes: 12 additions & 1 deletion agentstack/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import argparse
import os
import sys

from agentstack.cli import init_project_builder, list_tools
from agentstack.utils import get_version
from agentstack.telemetry import track_cli_command
from agentstack.utils import get_version, get_framework
import agentstack.generation as generation

import webbrowser
Expand All @@ -28,6 +30,9 @@ def main():
init_parser.add_argument('slug_name', nargs='?', help="The directory name to place the project in")
init_parser.add_argument('--no-wizard', action='store_true', help="Skip wizard steps")

# 'run' command
run_parser = subparsers.add_parser('run', aliases=['r'], help='Run your agent')

# 'generate' command
generate_parser = subparsers.add_parser('generate', aliases=['g'], help='Generate agents or tasks')

Expand Down Expand Up @@ -74,13 +79,19 @@ def main():
print(f"AgentStack CLI version: {get_version()}")
return

track_cli_command(args.command)

# Handle commands
if args.command in ['docs']:
webbrowser.open('https://docs.agentstack.sh/')
if args.command in ['quickstart']:
webbrowser.open('https://docs.agentstack.sh/quickstart')
if args.command in ['init', 'i']:
init_project_builder(args.slug_name, args.no_wizard)
if args.command in ['run', 'r']:
framework = get_framework()
if framework == "crewai":
os.system('python src/main.py')
elif args.command in ['generate', 'g']:
if args.generate_command in ['agent', 'a']:
generation.generate_agent(args.name, args.role, args.goal, args.backstory, args.llm)
Expand Down
73 changes: 73 additions & 0 deletions agentstack/telemetry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# hi :)
#
# if you're reading this, you probably saw "telemetry.py" and
# got mad and went to go see how we're spying on you
#
# i really hate to put this functionality in and was very
# resistant to it. as a human, i value privacy as a fundamental
# human right. but i also value my time.
#
# i have been putting a lot of my time into building out
# agentstack. i have strong conviction for what this project
# can be. it's showing some great progress, but for me to justify
# spending days and nights building this, i need to know that
# people are actually using it and not just starring the repo
#
# if you want to opt-out of telemetry, you can add the following
# configuration to your agentstack.json file:
#
# telemetry_opt_out: false
#
# i'm a single developer with a passion, working to lower the barrier
# of entry to building and deploying agents. it would be really
# cool of you to allow telemetry <3
#
# - braelyn

import platform
import socket
import psutil
import requests
from agentstack.utils import get_telemetry_opt_out, get_framework, get_version

# TELEMETRY_URL = 'https://api.agentstack.sh/telemetry'
TELEMETRY_URL = 'http://localhost:3000/telemetry'

def collect_machine_telemetry():
if get_telemetry_opt_out():
return

telemetry_data = {
'os': platform.system(),
'hostname': socket.gethostname(),
'platform': platform.platform(),
'os_version': platform.version(),
'cpu_count': psutil.cpu_count(logical=True),
'memory': psutil.virtual_memory().total,
'framework': get_framework(),
'agentstack_version': get_version()
}

# Attempt to get general location based on public IP
try:
response = requests.get('https://ipinfo.io/json')
if response.status_code == 200:
location_data = response.json()
telemetry_data.update({
'ip': location_data.get('ip'),
'city': location_data.get('city'),
'region': location_data.get('region'),
'country': location_data.get('country')
})
except requests.RequestException as e:
telemetry_data['location_error'] = str(e)

return telemetry_data


def track_cli_command(command):
try:
data = collect_machine_telemetry()
requests.post(TELEMETRY_URL, json={"command": command, **data})
except:
pass
13 changes: 13 additions & 0 deletions agentstack/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ def get_framework(path: Optional[str] = None) -> str:
sys.exit(1)


def get_telemetry_opt_out(path: Optional[str] = None) -> str:
try:
file_path = 'agentstack.json'
if path is not None:
file_path = path + '/' + file_path

agentstack_data = open_json_file(file_path)
opt_out = agentstack_data.get('telemetry_opt_out', False)
return opt_out
except FileNotFoundError:
print("\033[31mFile agentstack.json does not exist. Are you in the right directory?\033[0m")
sys.exit(1)

def camel_to_snake(name):
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "agentstack"
version = "0.1.9"
version = "0.1.10"
description = "The fastest way to build robust AI agents"
authors = [
{ name="Braelyn Boynton", email="[email protected]" }
Expand Down
Loading