From 0ef30aac99b233f2447ed5ae7f80ea468d53d023 Mon Sep 17 00:00:00 2001 From: Braelyn Boynton Date: Thu, 21 Nov 2024 20:46:12 -0800 Subject: [PATCH 1/3] add telemetry --- agentstack/main.py | 3 ++ agentstack/telemetry.py | 72 +++++++++++++++++++++++++++++++++++++++++ agentstack/utils.py | 13 ++++++++ pyproject.toml | 2 +- 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 agentstack/telemetry.py diff --git a/agentstack/main.py b/agentstack/main.py index fdc61804..e8ecd6b0 100644 --- a/agentstack/main.py +++ b/agentstack/main.py @@ -2,6 +2,7 @@ import sys from agentstack.cli import init_project_builder, list_tools +from agentstack.telemetry import track_cli_command from agentstack.utils import get_version import agentstack.generation as generation @@ -74,6 +75,8 @@ 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/') diff --git a/agentstack/telemetry.py b/agentstack/telemetry.py new file mode 100644 index 00000000..12d94b59 --- /dev/null +++ b/agentstack/telemetry.py @@ -0,0 +1,72 @@ +# 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 + +# 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 + } + + # 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 diff --git a/agentstack/utils.py b/agentstack/utils.py index 822208d5..29fe8d5d 100644 --- a/agentstack/utils.py +++ b/agentstack/utils.py @@ -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() diff --git a/pyproject.toml b/pyproject.toml index cf628a70..03fb6ffb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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="bboynton97@gmail.com" } From abd0f27b0d52102e7eb4b849b9c5f54d3aa61823 Mon Sep 17 00:00:00 2001 From: Braelyn Boynton Date: Thu, 21 Nov 2024 21:16:35 -0800 Subject: [PATCH 2/3] more data --- agentstack/main.py | 10 +++++++++- agentstack/telemetry.py | 7 ++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/agentstack/main.py b/agentstack/main.py index e8ecd6b0..e72871c6 100644 --- a/agentstack/main.py +++ b/agentstack/main.py @@ -1,9 +1,10 @@ import argparse +import os import sys from agentstack.cli import init_project_builder, list_tools from agentstack.telemetry import track_cli_command -from agentstack.utils import get_version +from agentstack.utils import get_version, get_framework import agentstack.generation as generation import webbrowser @@ -29,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') @@ -84,6 +88,10 @@ def main(): 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) diff --git a/agentstack/telemetry.py b/agentstack/telemetry.py index 12d94b59..0a43d610 100644 --- a/agentstack/telemetry.py +++ b/agentstack/telemetry.py @@ -28,8 +28,7 @@ import socket import psutil import requests - -from agentstack.utils import get_telemetry_opt_out +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' @@ -44,7 +43,9 @@ def collect_machine_telemetry(): 'platform': platform.platform(), 'os_version': platform.version(), 'cpu_count': psutil.cpu_count(logical=True), - 'memory': psutil.virtual_memory().total + 'memory': psutil.virtual_memory().total, + 'framework': get_framework(), + 'agentstack_version': get_version() } # Attempt to get general location based on public IP From 722e9a100fb3d2c2bdaf46d69e7f50ed819248d1 Mon Sep 17 00:00:00 2001 From: Braelyn Boynton Date: Thu, 21 Nov 2024 21:17:43 -0800 Subject: [PATCH 3/3] agentstack run --- README.md | 2 +- agentstack/cli/cli.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b2b58bb8..d12b02ee 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ agentstack tools add ## Running Your Agent -`python src/main.py` +`agentstack run` Runs the agent project in development mode.
diff --git a/agentstack/cli/cli.py b/agentstack/cli/cli.py index 7277db32..902d0de3 100644 --- a/agentstack/cli/cli.py +++ b/agentstack/cli/cli.py @@ -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 `\n\n" " Run `agentstack quickstart` or `agentstack docs` for next steps.\n"