├── tests
├── __init__.py
├── agent
│ ├── __init__.py
│ ├── task
│ │ ├── __init__.py
│ │ └── weather.py
│ ├── test_serper_agent.py
│ ├── test_mcp_reddit_agent.py
│ └── test_mcp_sse_weather_agent.py
├── io
│ ├── __init__.py
│ └── test_console_io_stream.py
├── llm
│ ├── __init__.py
│ ├── test_tool.py
│ └── test_gemini_client.py
├── pipe
│ ├── __init__.py
│ ├── test_openai_iopipe_create_policy.py
│ ├── test_aws_iopipe_create_policy.py
│ └── create_pipe.py
├── task
│ ├── __init__.py
│ ├── test_safe_code_exec.py
│ ├── test_sequential_execution.py
│ ├── test_greetings.py
│ └── test_api_handler.py
├── browser
│ ├── __init__.py
│ ├── test_browser.py
│ ├── sensitive_data.py
│ ├── test_gdocs.py
│ ├── test_check_appointment.py
│ └── cricket_tweet.py
├── embeddings
│ └── __init__.py
├── handlers
│ ├── __init__.py
│ ├── test_email_handler.py
│ ├── test_serper_dev.py
│ ├── test_openapi_spec_handler.py
│ ├── test_exa_handler.py
│ ├── test_content_creator.py
│ ├── test_visualization.py
│ ├── test_financial_data.py
│ ├── test_bedrock_ai_handler.py
│ ├── test_elastic_search.py
│ └── test_mcp_handler.py
├── memory
│ └── __init__.py
├── prompts
│ ├── __init__.py
│ └── test_prompt.py
├── conversation
│ ├── __init__.py
│ └── test_conversation_pipe.py
├── output_parsers
│ ├── __init__.py
│ └── test_json_parser.py
├── vector_stores
│ └── __init__.py
└── cli_app.py
├── examples
├── __init__.py
├── agents
│ ├── __init__.py
│ └── ai_agent.py
├── browser
│ ├── __init__.py
│ └── simple.py
└── mcp
│ └── __init__.py
├── superagentx
├── __init__.py
├── llm
│ ├── types
│ │ ├── __init__.py
│ │ └── response.py
│ ├── client.py
│ └── constants.py
├── pipeimpl
│ └── __init__.py
├── utils
│ ├── __init__.py
│ ├── parsers
│ │ ├── json.py
│ │ ├── __init__.py
│ │ ├── base.py
│ │ └── list.py
│ ├── prompt
│ │ ├── __init__.py
│ │ └── templates
│ │ │ └── __init__.py
│ ├── console_color.py
│ ├── helper.py
│ └── llm_config.py
├── computer_use
│ ├── __init__.py
│ ├── browser
│ │ ├── __init__.py
│ │ ├── dom
│ │ │ ├── __init__.py
│ │ │ └── history_tree_processor
│ │ │ │ ├── __init__.py
│ │ │ │ └── view.py
│ │ ├── models.py
│ │ └── state.py
│ └── desktop
│ │ └── __init__.py
├── handler
│ ├── task
│ │ ├── __init__.py
│ │ ├── general
│ │ │ ├── __init__.py
│ │ │ ├── dummy_handler.py
│ │ │ └── api_handler.py
│ │ └── greetings
│ │ │ ├── __init__.py
│ │ │ └── welcome_handler.py
│ ├── exceptions.py
│ ├── decorators.py
│ ├── __init__.py
│ ├── base.py
│ ├── serper_dev.py
│ └── exa_search.py
├── vector_stores
│ ├── exceptions.py
│ ├── constants.py
│ └── base.py
├── visualization
│ └── exceptions.py
├── constants.py
├── io
│ ├── __init__.py
│ ├── base.py
│ └── console.py
├── result.py
├── config.py
├── base.py
├── exceptions.py
└── memory
│ ├── config.py
│ └── base.py
├── superagentx_cli
├── __init__.py
├── exceptions.py
├── templates
│ ├── config.py.jinja2
│ ├── README.md.jinja2
│ ├── pyproject.toml.jinja2
│ ├── iopipe.py.jinja2
│ ├── app_pipe.py.jinja2
│ ├── supervisor.conf.jinja2
│ ├── wspipe.py.jinja2
│ ├── deployment.sh.jinja2
│ ├── restpipe.py.jinja2
│ └── pipe.py.jinja2
├── cli_app.py
└── main.py
├── docs
├── images
│ ├── beta.png
│ ├── img.png
│ ├── todo.png
│ ├── wip.png
│ ├── checkmark.png
│ ├── llms
│ │ ├── ibm.png
│ │ ├── meta.png
│ │ ├── gemini.png
│ │ ├── ollama.png
│ │ ├── openai.png
│ │ ├── awsbedrock.png
│ │ ├── azure-icon.png
│ │ ├── deepseek.png
│ │ ├── claude-ai-logo.png
│ │ └── mistral-ai-logo.png
│ ├── agentx_logo.png
│ ├── architecture.png
│ ├── checks-passed.png
│ ├── global-network.png
│ ├── handler
│ │ └── pie_chart.png
│ ├── fulllogo_transparent.png
│ └── examples
│ │ └── ecom-output-console.png
├── examples-reference
│ ├── endpoint
│ │ ├── get.mdx
│ │ ├── create.mdx
│ │ └── delete.mdx
│ └── introduction.mdx
├── examples
│ ├── pipes
│ │ └── ecommerce.mdx
│ └── handlers
│ │ ├── aws
│ │ ├── helper.mdx
│ │ ├── security_groups.mdx
│ │ ├── serverless.mdx
│ │ ├── cloudwatch.mdx
│ │ ├── ecs.mdx
│ │ ├── elb.mdx
│ │ ├── cloudfront.mdx
│ │ ├── s3.mdx
│ │ ├── rds.mdx
│ │ └── ec2.mdx
│ │ ├── E-commerce
│ │ └── best_buy.mdx
│ │ ├── Gcp
│ │ ├── firewall.mdx
│ │ ├── gmail.mdx
│ │ ├── calendar.mdx
│ │ ├── api_gateway.mdx
│ │ ├── security_role.mdx
│ │ └── iam.mdx
│ │ ├── visualization.mdx
│ │ ├── azure
│ │ ├── load_balancer.mdx
│ │ ├── nsg.mdx
│ │ ├── storage.mdx
│ │ ├── vm.mdx
│ │ ├── cloud_functions.mdx
│ │ └── iam.mdx
│ │ ├── servicenow.mdx
│ │ ├── datadog
│ │ └── incidents.mdx
│ │ ├── slack.mdx
│ │ ├── Google
│ │ ├── gmail.mdx
│ │ └── calender.mdx
│ │ ├── zohohirs.mdx
│ │ ├── extract
│ │ └── ai.mdx
│ │ ├── atlassian
│ │ └── jira.mdx
│ │ ├── email.mdx
│ │ ├── elastic.mdx
│ │ ├── weather.mdx
│ │ ├── csv_cli.mdx
│ │ ├── exa.mdx
│ │ ├── scrape.mdx
│ │ ├── financial_data.mdx
│ │ └── openapi.mdx
├── logo
│ ├── fulllogo_transparent_nobuffer.png
│ ├── icononly_transparent_nobuffer.png
│ └── fullLogo_transparent_dark_nobuffer.png
├── README.md
├── installation.mdx
├── prompt.mdx
├── handler.mdx
├── memory.mdx
└── introduction.mdx
├── assets
└── superagentx_browser.gif
├── LICENSE
└── pyproject.toml
/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/agent/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/io/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/llm/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/pipe/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/task/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/agents/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/browser/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/mcp/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx_cli/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/agent/task/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/browser/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/embeddings/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/handlers/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/memory/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/prompts/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/llm/types/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/pipeimpl/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/utils/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/utils/parsers/json.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/conversation/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/output_parsers/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/vector_stores/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/computer_use/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/handler/task/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/utils/parsers/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/computer_use/browser/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/computer_use/browser/dom/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/computer_use/desktop/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/handler/task/general/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/handler/task/greetings/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx/computer_use/browser/dom/history_tree_processor/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/superagentx_cli/exceptions.py:
--------------------------------------------------------------------------------
1 | class AppConfigError(Exception):
2 | pass
3 |
--------------------------------------------------------------------------------
/superagentx/vector_stores/exceptions.py:
--------------------------------------------------------------------------------
1 | class InvalidUrl(Exception):
2 | pass
3 |
--------------------------------------------------------------------------------
/superagentx/visualization/exceptions.py:
--------------------------------------------------------------------------------
1 |
2 | class InvalidChartType(Exception):
3 | pass
4 |
--------------------------------------------------------------------------------
/docs/images/beta.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/beta.png
--------------------------------------------------------------------------------
/docs/images/img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/img.png
--------------------------------------------------------------------------------
/docs/images/todo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/todo.png
--------------------------------------------------------------------------------
/docs/images/wip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/wip.png
--------------------------------------------------------------------------------
/docs/examples-reference/endpoint/get.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Get Plants'
3 | openapi: 'GET /plants'
4 | ---
5 |
--------------------------------------------------------------------------------
/docs/examples-reference/endpoint/create.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Create Plant'
3 | openapi: 'POST /plants'
4 | ---
5 |
--------------------------------------------------------------------------------
/docs/images/checkmark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/checkmark.png
--------------------------------------------------------------------------------
/docs/images/llms/ibm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/ibm.png
--------------------------------------------------------------------------------
/docs/images/llms/meta.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/meta.png
--------------------------------------------------------------------------------
/docs/images/agentx_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/agentx_logo.png
--------------------------------------------------------------------------------
/docs/images/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/architecture.png
--------------------------------------------------------------------------------
/docs/images/llms/gemini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/gemini.png
--------------------------------------------------------------------------------
/docs/images/llms/ollama.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/ollama.png
--------------------------------------------------------------------------------
/docs/images/llms/openai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/openai.png
--------------------------------------------------------------------------------
/assets/superagentx_browser.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/assets/superagentx_browser.gif
--------------------------------------------------------------------------------
/docs/examples-reference/endpoint/delete.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Delete Plant'
3 | openapi: 'DELETE /plants/{id}'
4 | ---
5 |
--------------------------------------------------------------------------------
/docs/images/checks-passed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/checks-passed.png
--------------------------------------------------------------------------------
/docs/images/global-network.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/global-network.png
--------------------------------------------------------------------------------
/docs/images/llms/awsbedrock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/awsbedrock.png
--------------------------------------------------------------------------------
/docs/images/llms/azure-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/azure-icon.png
--------------------------------------------------------------------------------
/docs/images/llms/deepseek.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/deepseek.png
--------------------------------------------------------------------------------
/superagentx_cli/templates/config.py.jinja2:
--------------------------------------------------------------------------------
1 | {# templates/config.py.jinja2 #}
2 | AUTH_TOKEN = '{{ auth_token }}'{{ '\n' }}
--------------------------------------------------------------------------------
/docs/images/handler/pie_chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/handler/pie_chart.png
--------------------------------------------------------------------------------
/docs/images/fulllogo_transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/fulllogo_transparent.png
--------------------------------------------------------------------------------
/docs/images/llms/claude-ai-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/claude-ai-logo.png
--------------------------------------------------------------------------------
/docs/images/llms/mistral-ai-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/llms/mistral-ai-logo.png
--------------------------------------------------------------------------------
/docs/examples/pipes/ecommerce.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'E-Commerce AgentX'
3 | description: 'Display inline code and code blocks'
4 | icon: 'code'
5 | ---
--------------------------------------------------------------------------------
/docs/logo/fulllogo_transparent_nobuffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/logo/fulllogo_transparent_nobuffer.png
--------------------------------------------------------------------------------
/docs/logo/icononly_transparent_nobuffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/logo/icononly_transparent_nobuffer.png
--------------------------------------------------------------------------------
/superagentx/handler/exceptions.py:
--------------------------------------------------------------------------------
1 |
2 | class InvalidHandler(Exception):
3 | pass
4 |
5 |
6 | class InvalidAction(Exception):
7 | pass
8 |
--------------------------------------------------------------------------------
/docs/images/examples/ecom-output-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/images/examples/ecom-output-console.png
--------------------------------------------------------------------------------
/docs/logo/fullLogo_transparent_dark_nobuffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superagentxai/superagentx/HEAD/docs/logo/fullLogo_transparent_dark_nobuffer.png
--------------------------------------------------------------------------------
/superagentx_cli/templates/README.md.jinja2:
--------------------------------------------------------------------------------
1 | {# templates/README.md.jinja2 #}
2 |
3 | # {{ app_name }} - Use case using SuperAgentX
4 |
5 | SuperAgentX - A Lightweight Modular Autonomous True Multi Agent AI Framework.
--------------------------------------------------------------------------------
/superagentx/vector_stores/constants.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 |
3 | DEFAULT_EMBED_MODEL = "text-embedding-ada-002"
4 | DEFAULT_EMBED_TYPE = "openai"
5 |
6 |
7 | class EmbedTypeEnum(str, Enum):
8 | OPENAI = "openai"
9 |
--------------------------------------------------------------------------------
/superagentx/handler/decorators.py:
--------------------------------------------------------------------------------
1 | import functools
2 |
3 |
4 | def tool(func):
5 | @functools.wraps(func)
6 | async def wrapper(*args, **kwargs):
7 | return await func(*args, **kwargs)
8 | wrapper._is_handler_tool = True
9 | return wrapper
--------------------------------------------------------------------------------
/superagentx/constants.py:
--------------------------------------------------------------------------------
1 | DEFAULT = [
2 | {
3 | "role": "system",
4 | "content": "You are a helpful assistant."
5 | }
6 | ]
7 |
8 | SEQUENCE = 'SEQUENCE'
9 | PARALLEL = 'PARALLEL'
10 |
11 | DATE_TIME_FORMAT = "%Y-%m-%d %H:%M:%S.%f"
12 |
--------------------------------------------------------------------------------
/superagentx/io/__init__.py:
--------------------------------------------------------------------------------
1 | from superagentx.io.base import IOStream, InputStream, OutputStream
2 | from superagentx.io.console import IOConsole
3 |
4 | __all__ = (
5 | "OutputStream",
6 | "InputStream",
7 | "IOStream",
8 | "IOConsole"
9 | )
10 |
--------------------------------------------------------------------------------
/superagentx/handler/__init__.py:
--------------------------------------------------------------------------------
1 | # from .ai import AIHandler
2 | # from .elastic_search import ElasticsearchHandler
3 | # from .send_email import EmailHandler
4 | # from .exa_search import ExaHandler
5 | # from .financial_data import FinancialHandler
6 | # from .serper_dev import SerperDevToolHandler
7 |
--------------------------------------------------------------------------------
/superagentx/utils/parsers/base.py:
--------------------------------------------------------------------------------
1 | import abc
2 |
3 |
4 | class BaseParser(abc.ABC):
5 |
6 | @abc.abstractmethod
7 | async def parse(self, *args, **kwargs):
8 | raise NotImplementedError
9 |
10 | @abc.abstractmethod
11 | async def get_format_instructions(self) -> str:
12 | raise NotImplementedError
13 |
--------------------------------------------------------------------------------
/tests/cli_app.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os.path
3 |
4 | with open(os.path.join(os.path.dirname(__file__), 'cli_app.json'), 'rb') as fobj:
5 | d = json.load(fobj)
6 |
7 | from superagentx_cli.cli import CliApp
8 |
9 |
10 | def main():
11 | cli_app = CliApp(app_config=d)
12 | print(cli_app.render_pipe())
13 | cli_app.create_project()
14 |
15 |
16 | if __name__ == '__main__':
17 | main()
18 |
--------------------------------------------------------------------------------
/superagentx/result.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | from pydantic import BaseModel
4 |
5 |
6 | class GoalResult(BaseModel):
7 | name: str
8 | agent_id: str
9 | reason: str | None = None
10 | result: Any | None = None
11 | content: Any | None = None
12 | error: str | None = None
13 | verify_goal: bool = True
14 | is_goal_satisfied: bool | None = None
15 | engine_result: Any | None = None
16 |
--------------------------------------------------------------------------------
/superagentx/config.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import os
3 | import sys
4 |
5 |
6 | def is_verbose_enabled():
7 | verbose = os.environ.get('DEBUGGING') or os.environ.get('VERBOSE')
8 | if verbose and verbose.lower() in ('1', 'true'):
9 | logging.basicConfig(
10 | format='%(name)s - %(levelname)s - %(message)s',
11 | stream=sys.stdout,
12 | level=logging.DEBUG,
13 | force=True
14 | )
15 |
--------------------------------------------------------------------------------
/superagentx/base.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class BaseEngine(ABC):
5 | def __init__(self, *args, **kwargs):
6 | """
7 | BaseEngine is an abstract class that defines a common interface for different automation engines.
8 | """
9 | pass
10 |
11 | @abstractmethod
12 | async def start(self, *args, **kwargs):
13 | """
14 | Abstract method to execute an action within the engine.
15 | """
16 | pass
17 |
--------------------------------------------------------------------------------
/superagentx/exceptions.py:
--------------------------------------------------------------------------------
1 | from superagentx.result import GoalResult
2 |
3 |
4 | class InvalidType(Exception):
5 | pass
6 |
7 |
8 | class ToolError(Exception):
9 | pass
10 |
11 |
12 | class StopSuperAgentX(Exception):
13 |
14 | def __init__(
15 | self,
16 | message: str,
17 | goal_result: GoalResult
18 | ):
19 | self.message = message
20 | self.goal_result = goal_result
21 |
22 | def __str__(self):
23 | return f'StopSuperAgentX: {self.message}'
24 |
--------------------------------------------------------------------------------
/tests/browser/test_browser.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from superagentx.computer_use.browser.browser import Browser, BrowserConfig
4 |
5 |
6 | @pytest.mark.asyncio
7 | async def test_highlight_elements():
8 | browser = Browser(config=BrowserConfig(headless=False, disable_security=True, browser_type='firefox'))
9 |
10 | async with await browser.new_context() as context:
11 | page = await context.get_current_page()
12 | await page.goto('https://dictionary.cambridge.org')
13 |
14 | state = await context.get_state()
15 | print(f"Browser State : {state}")
16 |
--------------------------------------------------------------------------------
/superagentx/handler/base.py:
--------------------------------------------------------------------------------
1 | import abc
2 | import inspect
3 |
4 |
5 | # Base Class
6 | class BaseHandler(abc.ABC):
7 | tools = []
8 |
9 | def __init__(self):
10 | self._get_tools()
11 |
12 | def _get_tools(self) -> list[str]:
13 | self.tools = []
14 | for _name, _member in inspect.getmembers(self):
15 | if inspect.isfunction(_member) or inspect.ismethod(_member):
16 | if hasattr(_member, '_is_handler_tool') and getattr(_member, '_is_handler_tool'):
17 | self.tools.append(_member.__name__)
18 | return self.tools
19 |
--------------------------------------------------------------------------------
/tests/task/test_safe_code_exec.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from superagentx.task_engine import TaskEngine
3 | from superagentx.handler.task.general.dummy_handler import DummyHandler
4 |
5 | '''
6 | pytest tests/task/test_safe_code_exec.py -q
7 | '''
8 |
9 |
10 | @pytest.mark.asyncio
11 | async def test_safe_code_exec():
12 | engine = TaskEngine(
13 | handler=DummyHandler(),
14 | code="x = 5\ny = x * 2"
15 | )
16 | result = await engine.start("test")
17 |
18 | locals_dict = result[0]["code"]["locals"]
19 | assert locals_dict["x"] == 5
20 | assert locals_dict["y"] == 10
21 |
--------------------------------------------------------------------------------
/superagentx/handler/task/general/dummy_handler.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | from superagentx.handler.base import BaseHandler
3 |
4 |
5 | class DummyHandler(BaseHandler):
6 |
7 | async def get_name(self):
8 | await asyncio.sleep(0.01)
9 | return {"name": "SuperAgentX"}
10 |
11 | async def get_age(self):
12 | return {"age": 5}
13 |
14 | async def fail_method(self):
15 | raise ValueError("Simulated failure")
16 |
17 | def greet(self, name: str):
18 | return {"greeting": f"Hello {name}!"}
19 |
20 | async def echo(self, value):
21 | return {"value": value}
22 |
--------------------------------------------------------------------------------
/tests/prompts/test_prompt.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from superagentx.utils.helper import get_fstring_variables
4 |
5 | logger = logging.getLogger(__name__)
6 |
7 |
8 | class TestPrompt:
9 |
10 | async def test_f_string_parser(self):
11 | prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
12 |
13 |
14 | Question: {question}
15 | Helpful Answer:"""
16 |
17 | result = await get_fstring_variables(prompt_template)
18 | logger.info(f"Prompt variables test {type(result)}")
19 |
--------------------------------------------------------------------------------
/superagentx/utils/prompt/__init__.py:
--------------------------------------------------------------------------------
1 | from superagentx.utils.parsers.base import BaseParser
2 | from pydantic import BaseModel, Field
3 | from typing import List
4 |
5 |
6 | class PromptTemplate(BaseModel):
7 |
8 | # Required parameters
9 |
10 | template: str = Field(description='Prompt template')
11 |
12 | input_variables: List[str] | None = Field(
13 | description='the name of the model you want to use (e.g., gpt-3.5-turbo, gpt-4, gpt-3.5-turbo-16k-1106)',
14 | default=None
15 | )
16 |
17 | return_type: BaseParser | None = Field(description='Return type base parser type or a string', default=None)
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/tests/handlers/test_email_handler.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from superagentx.handler.send_email import EmailHandler
4 |
5 | '''
6 | Run Pytest:
7 |
8 | 1.pytest --log-cli-level=INFO tests/handlers/test_email_handler.py::TestEmail::test_email
9 |
10 | '''
11 |
12 |
13 | @pytest.fixture
14 | def email_client_init() -> EmailHandler:
15 | email_handler = EmailHandler(
16 | host="",
17 | port=345
18 | )
19 | return email_handler
20 |
21 |
22 | class TestEmail:
23 |
24 | async def test_email(self, email_client_init: EmailHandler):
25 | res = await email_client_init.send_email(**{})
26 | assert isinstance(res, object)
27 |
--------------------------------------------------------------------------------
/tests/task/test_sequential_execution.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from superagentx.task_engine import TaskEngine
3 | from superagentx.handler.task.general.dummy_handler import DummyHandler
4 |
5 | '''
6 | pytest tests/task/test_sequential_execution.py -q
7 | '''
8 |
9 |
10 | @pytest.mark.asyncio
11 | async def test_sequence_execution():
12 | engine = TaskEngine(
13 | handler=DummyHandler(),
14 | instructions=[
15 | {"get_name": {}},
16 | {"greet": {"name": "$prev.name"}},
17 | ]
18 | )
19 |
20 | result = await engine.start("seq test")
21 | assert result[0]["get_name"]["success"] is True
22 | assert result[1]["greet"]["result"]["greeting"] == "Hello SuperAgentX!"
23 |
--------------------------------------------------------------------------------
/tests/handlers/test_serper_dev.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import pytest
4 |
5 | from superagentx.handler.serper_dev import SerperDevToolHandler
6 |
7 | logger = logging.getLogger(__name__)
8 |
9 | '''
10 | Run Pytest:
11 |
12 | 1. pytest --log-cli-level=INFO tests/handlers/test_serper_dev.py::TestSerperDev::test_serper_dev_search
13 | '''
14 |
15 |
16 | @pytest.fixture
17 | def serper_dev_client_init() -> dict:
18 | return {}
19 |
20 |
21 | class TestSerperDev:
22 |
23 | async def test_serper_dev_search(self):
24 | serper_dev_handler = SerperDevToolHandler()
25 | response = await serper_dev_handler.search(query='Select the best city based on weather, season, and prices')
26 | logger.info(f'Results ==> {response}')
27 |
--------------------------------------------------------------------------------
/tests/output_parsers/test_json_parser.py:
--------------------------------------------------------------------------------
1 | from openai.types.chat.chat_completion import ChatCompletion, ChatCompletionMessage
2 |
3 | from superagentx.llm import LLMClient
4 | from superagentx.llm.openai import ChatCompletionParams
5 |
6 | llm_config = {'model': 'gpt-4-turbo-2024-04-09', 'llm_type': 'openai'}
7 |
8 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
9 |
10 | messages = [{"content": "Return ONLY JSON object"
11 | "Input: List top five billionaires"
12 |
13 | }]
14 |
15 | params = ChatCompletionParams(
16 | messages=messages,
17 | ).model_dump(exclude_none=True)
18 |
19 | response: ChatCompletion = llm_client.chat_completion(params=params)
20 | for choice in response.choices:
21 | message: ChatCompletionMessage = choice.message
22 | print(message.content)
23 |
--------------------------------------------------------------------------------
/tests/task/test_greetings.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from superagentx.task_engine import TaskEngine
4 | from superagentx.handler.task.greetings.welcome_handler import WelcomeHandler
5 |
6 | logger = logging.getLogger(__name__)
7 |
8 | '''
9 | Run Pytest:
10 |
11 | 1. pytest --log-cli-level=INFO tests/task/test_greetings.py::TestGreetings::test_greetings
12 | '''
13 |
14 |
15 | class TestGreetings:
16 |
17 | async def test_greetings(self):
18 | handler = WelcomeHandler(first_name="John", last_name="Doe")
19 |
20 | engine = TaskEngine(
21 | handler=handler,
22 | instructions=[
23 | {"get_first_name": {}},
24 | {"send_greeting": {"message": "Hello, $prev.first_name $prev.last_name !"}}
25 | ]
26 | )
27 |
28 | result = await engine.start()
29 | logger.info(f"Code : {result}")
30 |
--------------------------------------------------------------------------------
/superagentx_cli/templates/pyproject.toml.jinja2:
--------------------------------------------------------------------------------
1 | {# templates/pyproject.toml.jinja2 #}
2 | # https://python-poetry.org/docs/
3 | # https://packaging.python.org/en/latest/flow/#the-configuration-file
4 |
5 | [project]
6 | name = "{{ package_name }}"
7 | version = "0.0.1"
8 | description = "A Lightweight Modular Autonomous True Multi Agent AI Framework."
9 | readme = "README.md"
10 | keywords = ["{{ package_name }}", "AGI", "Agentic AI", "ASI", "superagentx", "agent", "LLM"]
11 |
12 | dependencies = [
13 | "rich>=13.9.2,<14.0.0",
14 | "websockets>=15.0.1,<16.0.0",
15 | "python-dotenv>=1.2.1",
16 | "uvicorn[standard]>=0.38.0",
17 |
18 | # superagentx: GitHub version, extras=all
19 | "superagentx[all]>=1.0.3b1",
20 | "superagentx-handlers>=0.1.5.4,<0.2.0",
21 |
22 | # FastAPI
23 | "fastapi[standard]>=0.115.4,<0.116.0",
24 | ]
25 |
26 | [build-system]
27 | requires = ["hatchling"]
28 | build-backend = "hatchling.build"
--------------------------------------------------------------------------------
/superagentx_cli/templates/iopipe.py.jinja2:
--------------------------------------------------------------------------------
1 | {# templates/iopipe.py.jinja2 #}
2 | import asyncio
3 |
4 | from rich import print as rprint
5 | from superagentx.pipeimpl.iopipe import IOPipe
6 |
7 | from {{ package_name }}.pipe import get_{{ pipe_name }}_pipe
8 |
9 |
10 | async def main():
11 | """
12 | Launches the {{ app_name }} pipeline console client for processing requests and handling data.
13 | """
14 |
15 | pipe = await get_{{ pipe_name }}_pipe()
16 |
17 | # Create IO Cli Console - Interface
18 | io_pipe = IOPipe(
19 | search_name='SuperAgentX {{ app_name }}',
20 | agentx_pipe=pipe,
21 | read_prompt=f"\n[bold green]Enter your search here"
22 | )
23 | await io_pipe.start()
24 |
25 |
26 | if __name__ == '__main__':
27 | try:
28 | asyncio.run(main())
29 | except (KeyboardInterrupt, asyncio.CancelledError):
30 | rprint("\nUser canceled the [bold yellow][i]pipe[/i]!"){{'\n'}}
--------------------------------------------------------------------------------
/tests/handlers/test_openapi_spec_handler.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import pytest
4 |
5 | from superagentx.handler.openapi import OpenAPIHandler
6 |
7 | logger = logging.getLogger(__name__)
8 |
9 | '''
10 | Run Pytest:
11 |
12 | 1. pytest --log-cli-level=INFO tests/handlers/test_openapi_spec_handler.py::TestOpenAPIHandler::test_openapi_handler
13 |
14 | '''
15 |
16 |
17 | @pytest.fixture
18 | def openapi_handler_init() -> OpenAPIHandler:
19 | openapi_handler = OpenAPIHandler(base_url='https://petstore.swagger.io/v2/', spec_url_path='swagger.json')
20 | return openapi_handler
21 |
22 |
23 | class TestOpenAPIHandler:
24 |
25 | async def test_openapi_handler(self, openapi_handler_init: OpenAPIHandler):
26 | response = await openapi_handler_init.call_endpoint(
27 | endpoint="/pet/findByStatus",
28 | method="GET",
29 | params={'status': 'sold'})
30 | logger.info(f"Response {response}")
31 |
32 |
--------------------------------------------------------------------------------
/superagentx_cli/templates/app_pipe.py.jinja2:
--------------------------------------------------------------------------------
1 | {# templates/app_pipe.py.jinja2 #}
2 | {%- for import in imports %}
3 | {{ import }}
4 | {%- endfor %}
5 |
6 | async def get_{{ pipe_name }}_pipe() -> AgentXPipe:
7 | # LLM Configuration
8 | {%- for llm in llms %}
9 | {{ llm }}
10 | {%- endfor %}
11 | # Enable Memory
12 | {%- for memory in memories %}
13 | {{ memory }}
14 | {%- endfor %}
15 | # Handlers
16 | {%- for handler in handlers %}
17 | {{ handler }}
18 | {%- endfor %}
19 | # Prompt Templates
20 | {%- for prompt_template in prompt_templates %}
21 | {{ prompt_template }}
22 | {%- endfor %}
23 | # Engines
24 | {%- for engine in engines %}
25 | {{ engine }}
26 | {%- endfor %}
27 | # Agents
28 | {%- for agent in agents %}
29 | {{ agent }}
30 | {%- endfor %}
31 | # Pipe
32 | {{ pipe }}
33 | return {{ pipe_name }}
34 |
35 |
36 | get_pipe = get_{{ pipe_name }}_pipe{{'\n'}}
--------------------------------------------------------------------------------
/tests/pipe/test_openai_iopipe_create_policy.py:
--------------------------------------------------------------------------------
1 |
2 | import asyncio
3 |
4 | from rich import print as rprint
5 | from superagentx.pipeimpl.openaivoicepipe import WhisperPipe
6 |
7 | from create_pipe import get_superagentx_voice_to_text_pipe
8 |
9 |
10 | async def main():
11 | """
12 | Launches the superagentx-voice-to-text pipeline console client for processing requests and handling data.
13 | """
14 |
15 | pipe = await get_superagentx_voice_to_text_pipe()
16 |
17 | # Create IO Cli Console - Interface
18 | io_pipe = WhisperPipe(
19 | search_name='SuperAgentX - Voice To Text',
20 | agentx_pipe=pipe,
21 | read_prompt=f"\n[bold green]Enter your search here"
22 | )
23 | await io_pipe.start()
24 |
25 |
26 | if __name__ == '__main__':
27 | try:
28 | asyncio.run(main())
29 | except (KeyboardInterrupt, asyncio.CancelledError):
30 | rprint("\nUser canceled the [bold yellow][i]pipe[/i]!")
31 |
32 |
--------------------------------------------------------------------------------
/superagentx/utils/prompt/templates/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | REACT_TOOLS_INSTRUCTIONS = '''Answer the following questions as best you can.
3 |
4 | {role}
5 |
6 | Use the following format:
7 | Intermediate Steps: Observe the question carefully and list out number of actions and its
8 | corresponding all tools [{tool_names}].
9 |
10 | {format_instructions}
11 |
12 | Question: the input question you must answer
13 | Thought: you should always think about what to do
14 | Action: the action to take, should be one of [{tool_names}]
15 | Action Input: the input to the action
16 | Observation: the result of the action
17 | ... (this Thought/Action/Action Input/Observation can repeat {max_repeat_times} times)
18 | Thought: I now know the final answer
19 | Final Answer: the final answer to the original input question
20 |
21 | Begin!
22 |
23 | Question: {input}
24 | Thought:{agent_scratchpad}
25 | '''
26 |
27 | # Initialize the engine's scratchpad (initial thoughts)
28 | agent_scratchpad = ""
29 |
--------------------------------------------------------------------------------
/tests/pipe/test_aws_iopipe_create_policy.py:
--------------------------------------------------------------------------------
1 |
2 | import asyncio
3 |
4 | from rich import print as rprint
5 | from superagentx.pipeimpl.awsvoicepipe import AWSVoicePipe
6 |
7 | from create_pipe import get_superagentx_voice_to_text_pipe
8 |
9 |
10 | async def main():
11 | """
12 | Launches the superagentx-voice-to-text pipeline console client for processing requests and handling data.
13 | """
14 |
15 | pipe = await get_superagentx_voice_to_text_pipe()
16 |
17 | # Create IO Cli Console - Interface
18 | io_pipe = AWSVoicePipe(
19 | search_name='SuperAgentX - Voice To Text',
20 | agentx_pipe=pipe,
21 | read_prompt=f"\n[bold green]Enter your search here",
22 | region="us-east-1"
23 | )
24 | await io_pipe.start()
25 |
26 |
27 | if __name__ == '__main__':
28 | try:
29 | asyncio.run(main())
30 | except (KeyboardInterrupt, asyncio.CancelledError):
31 | rprint("\nUser canceled the [bold yellow][i]pipe[/i]!")
32 |
33 |
--------------------------------------------------------------------------------
/superagentx/handler/task/general/api_handler.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | from superagentx.handler.base import BaseHandler
4 |
5 |
6 | class APIHandler(BaseHandler):
7 |
8 | async def fetch_weather(self, city: str):
9 | await asyncio.sleep(0.2)
10 | return {"temp": 26, "condition": "Sunny", "city": city}
11 |
12 | async def fetch_stock(self, symbol: str):
13 | await asyncio.sleep(0.1)
14 | raise ValueError("Simulated stock API failure") # FAIL intentionally
15 |
16 | async def fetch_news(self, topic: str):
17 | await asyncio.sleep(0.3)
18 | return {"topic": topic, "headline": "AI is transforming automation!"}
19 |
20 | def combine_successful(self, weather: dict | None, stock: dict | None, news: dict | None):
21 | return {
22 | "weather": weather,
23 | "stock": stock,
24 | "news": news,
25 | "summary": "Report generated with available data (failed calls skipped)."
26 | }
27 |
--------------------------------------------------------------------------------
/superagentx/memory/config.py:
--------------------------------------------------------------------------------
1 | import os
2 | from pathlib import Path
3 |
4 | from pydantic import BaseModel, Field
5 | from superagentx.vector_stores.base import BaseVectorStore
6 | from superagentx.llm import LLMClient
7 |
8 |
9 | def _db_path():
10 | _db_dir = os.environ.get('AGENTX_MEMORY_DIR')
11 | if not _db_dir:
12 | return ":memory:"
13 | else:
14 | _db_dir = Path(_db_dir)
15 | return _db_dir / 'history.db'
16 |
17 |
18 | class MemoryConfig(BaseModel):
19 | vector_store: BaseVectorStore | None = Field(
20 | description="Configuration for the vector store",
21 | default=None,
22 | )
23 |
24 | db_path: str | None = Field(
25 | description="Path to the history database",
26 | default=_db_path(),
27 | )
28 |
29 | llm_client: LLMClient | None = Field(
30 | description="Configuration for the LLM",
31 | default=None,
32 | )
33 |
34 | class Config:
35 | arbitrary_types_allowed = True
36 |
--------------------------------------------------------------------------------
/tests/handlers/test_exa_handler.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import pytest
4 | from exa_py.api import SearchResponse
5 |
6 | from superagentx.handler.exa_search import ExaHandler
7 |
8 | '''
9 | Run Pytest:
10 |
11 | pytest --log-cli-level=INFO tests/handlers/test_exa_handler.py::TestExaSearch::test_exa_handler
12 |
13 | '''
14 |
15 |
16 | @pytest.fixture
17 | def exa_search_client_init() -> ExaHandler:
18 | # Set the exa api key in environment variable as EXA_API_KEY
19 | exa_handler = ExaHandler(api_key=os.getenv("EXA_API_KEY"))
20 | return exa_handler
21 |
22 |
23 | class TestExaSearch:
24 |
25 | # Test async exa handler - search_contents method
26 | async def test_exa_handler(self, exa_search_client_init: ExaHandler):
27 | exa = await exa_search_client_init.search_contents(
28 | query="Topics in AI",
29 | search_type="auto",
30 | use_autoprompt=True,
31 | num_results=5,
32 | )
33 | assert isinstance(exa, SearchResponse)
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Permission is hereby granted, free of charge, to any person obtaining a copy
3 | of this software and associated documentation files (the "Software"), to deal
4 | in the Software without restriction, including without limitation the rights
5 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6 | copies of the Software, and to permit persons to whom the Software is
7 | furnished to do so, subject to the following conditions:
8 |
9 | The above copyright notice and this permission notice shall be included in all
10 | copies or substantial portions of the Software.
11 |
12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 | SOFTWARE.
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Mintlify Starter Kit
2 |
3 | Click on `Use this template` to copy the Mintlify starter kit. The starter kit contains examples including
4 |
5 | - Guide pages
6 | - Navigation
7 | - Customizations
8 | - API Reference pages
9 | - Use of popular components
10 |
11 | ### Development
12 |
13 | Install the [Mintlify CLI](https://www.npmjs.com/package/mintlify) to preview the documentation changes locally. To install, use the following command
14 |
15 | ```
16 | npm i -g mintlify
17 | ```
18 |
19 | Run the following command at the root of your documentation (where mint.json is)
20 |
21 | ```
22 | mintlify dev
23 | ```
24 |
25 | ### Publishing Changes
26 |
27 | Install our Github App to auto propagate changes from your repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
28 |
29 | #### Troubleshooting
30 |
31 | - Mintlify dev isn't running - Run `mintlify install` it'll re-install dependencies.
32 | - Page loads as a 404 - Make sure you are running in a folder with `mint.json`
33 |
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/helper.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'AWS Helper'
3 | icon: 'key'
4 | ---
5 |
6 | The **AWS Helper** provides utility functions to simplify authentication and temporary credential generation.
7 | One key feature is the ability to generate **AWS STS temporary credentials**, which are short-lived credentials used for secure authentication in AWS services without exposing long-term access keys.
8 |
9 | STS (Security Token Service) is particularly useful when granting temporary access to applications, scripts, or external systems.
10 |
11 | ## Example
12 |
13 | To use the AWS Helper, call the `generate_aws_sts_token` method with your AWS credentials and region details.
14 |
15 | ```python
16 | import os
17 | from helpers.aws_helper import generate_aws_sts_token
18 |
19 | # Generate temporary STS token
20 | sts_credentials = generate_aws_sts_token(
21 | region_name="us-east-1",
22 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
23 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
24 | duration_seconds=3600 # 1 hour
25 | )
26 |
27 | print(sts_credentials)
28 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/E-commerce/best_buy.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Best Buy Handler'
3 | icon: 'shopping-cart'
4 | ---
5 |
6 | Best Buy is a leading consumer electronics retailer that provides a wide variety of products including laptops, TVs, phones, appliances, and more.
7 | The **BestbuyHandler** allows programmatic access to Best Buy’s product catalog through its public API. Developers can search products, retrieve prices, discounts, reviews, and detailed product information.
8 |
9 | This integration is useful for building product recommendation systems, price tracking tools, or e-commerce integrations.
10 |
11 |
12 | ## Example
13 |
14 | To create the `BestbuyHandler` object with the API key:
15 |
16 | ```python
17 | import os
18 | from superagentx_handlers.retail.bestbuy import BestbuyHandler
19 |
20 | bestbuy_handler = BestbuyHandler(
21 | api_key=os.getenv("BESTBUY_API_KEY")
22 | )
23 | ```
24 |
25 | **Search Products (get_best_buy_info):**
26 | Fetch product details from Best Buy based on a search keyword.
27 | ```python
28 | products = await bestbuy_handler.get_best_buy_info(search_text="laptop")
29 | print(products)
30 | ```
31 |
--------------------------------------------------------------------------------
/superagentx_cli/cli_app.py:
--------------------------------------------------------------------------------
1 | import json
2 | import sys
3 | from typing import Annotated, Optional
4 |
5 | import typer
6 | from superagentx_cli.cli import CliApp
7 | from superagentx_cli.exceptions import AppConfigError
8 |
9 | app = typer.Typer(name='Superagentx-App')
10 |
11 |
12 | @app.command(name='app')
13 | def main(
14 | app_config_path: Annotated[str, typer.Option(
15 | help='Application configuration path.'
16 | )],
17 | app_dir_path: Annotated[Optional[str], typer.Option(
18 | help='Application will be created in the given dir path.'
19 | ' Default will be current execution path.'
20 | )] = None
21 | ):
22 | with open(app_config_path, 'r') as fobj:
23 | app_config = json.load(fobj)
24 | try:
25 | cli_app = CliApp(
26 | app_config=app_config,
27 | app_dir_path=app_dir_path
28 | )
29 | cli_app.create_project()
30 | except (AppConfigError, Exception) as ex:
31 | sys.stderr(f"Superagentx app creation failed!\n{ex}")
32 | sys.exit(1)
33 |
34 | if __name__ == '__main__':
35 | app()
36 |
--------------------------------------------------------------------------------
/tests/handlers/test_content_creator.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import pytest
4 |
5 | from superagentx.handler.ai import AIHandler
6 | from superagentx.llm import LLMClient
7 |
8 | logger = logging.getLogger(__name__)
9 |
10 | '''
11 | Run Pytest:
12 |
13 | 1.pytest --log-cli-level=INFO tests/handlers/test_content_creator.py::TestContentCreator::test_text_content_creator
14 |
15 | '''
16 |
17 |
18 | @pytest.fixture
19 | def content_creator_init() -> AIHandler:
20 | llm_config = {'model': 'gpt-4-turbo-2024-04-09', 'llm_type': 'openai'}
21 |
22 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
23 | content_creator_handler = AIHandler(
24 | llm=llm_client
25 | )
26 | logger.info(content_creator_handler)
27 | return content_creator_handler
28 |
29 |
30 | class TestContentCreator:
31 |
32 | async def test_text_content_creator(self, content_creator_init: AIHandler):
33 | result = await content_creator_init.text_creation(instruction='Create the digital marketing content')
34 | logger.info(f'Result => {result.choices[0].message.content}')
35 | assert "digital marketing" in result.choices[0].message.content
36 |
--------------------------------------------------------------------------------
/docs/installation.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Installation'
3 | icon: 'screwdriver-wrench'
4 | ---
5 |
6 | This guide will walk you through the installation process for SuperAgentX and its dependencies. SuperAgentX is a
7 | flexible and powerful AI framework designed to help you efficiently create AI agents and tools. Let’s dive in and
8 | get started!
9 |
10 |
11 |
12 | Ensure that Python version >=3.10 or more is to be installed on your system before continuing.
13 |
14 |
15 | #### 1. Install SuperAgentX
16 | >Install the main SuperAgentX package using the command given below:
17 |
18 | ```shell
19 | pip install superagentx
20 | ```
21 |
22 | ##### Verify the installation
23 | >To verify that the superagentx is installed correctly, run the following command:
24 |
25 | ```shell
26 | pip show superagentx
27 | ```
28 |
29 | #### 2. Install SuperAgentX-handlers
30 | >Install the superagentx-handlers using the command given below:
31 |
32 | ```shell
33 | pip install superagentx-handlers
34 | ```
35 |
36 | #### 3. Install superagentx-examples
37 | >Install the superagentx-examples using the command given below:
38 |
39 | ```shell
40 | pip install superagentx-examples
41 | ```
42 |
--------------------------------------------------------------------------------
/examples/browser/simple.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | from superagentx.agent import Agent
4 | from superagentx.browser_engine import BrowserEngine
5 | from superagentx.llm import LLMClient
6 | from superagentx.prompt import PromptTemplate
7 |
8 |
9 | async def main():
10 | llm_client: LLMClient = LLMClient(llm_config={'model': 'gpt-4.1', 'llm_type': 'openai'})
11 |
12 | prompt_template = PromptTemplate()
13 |
14 | browser_engine = BrowserEngine(
15 | llm=llm_client,
16 | prompt_template=prompt_template,
17 |
18 | )
19 | query_instruction = ("Which teams have won more than 3 FIFA World Cups, and which team is most likely to win the "
20 | "next one?")
21 |
22 | fifo_analyser_agent = Agent(
23 | goal="Complete user's task.",
24 | role="You are a Football / Soccer Expert Reviewer",
25 | llm=llm_client,
26 | prompt_template=prompt_template,
27 | max_retry=1,
28 | engines=[browser_engine]
29 | )
30 |
31 | result = await fifo_analyser_agent.execute(
32 | query_instruction=query_instruction
33 | )
34 |
35 | print(result)
36 |
37 |
38 | asyncio.run(main())
39 |
--------------------------------------------------------------------------------
/superagentx/computer_use/browser/models.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from pydantic import BaseModel
4 |
5 |
6 | class StepInfo(BaseModel):
7 | step_number: int
8 | max_steps: int
9 |
10 | def is_last_step(self) -> bool:
11 | """Check if this is the last step"""
12 | return self.step_number >= self.max_steps - 1
13 |
14 |
15 | class ToolResult(BaseModel):
16 | """Result of executing an action"""
17 |
18 | is_done: bool = False
19 | success: bool | None = None
20 | extracted_content: str | None = None
21 | error: str | None = None
22 | include_in_memory: bool = False # whether to include in past messages as context or not
23 |
24 |
25 | class InputTextParams(BaseModel):
26 | index: int
27 | text: str
28 | has_sensitive: bool
29 |
30 | class MFAParams(BaseModel):
31 | index: int
32 | mfa_secret_key: str
33 | has_sensitive: bool
34 | click_element_by_index: int
35 |
36 | class GoToUrl(BaseModel):
37 | url: str
38 |
39 |
40 | class ToastConfig(BaseModel):
41 | font_size: int = 22
42 | background: str = 'linear-gradient(45deg, #ff6ec4, #7873f5)'
43 | color: str = 'white'
44 |
--------------------------------------------------------------------------------
/docs/examples/handlers/Gcp/firewall.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Firewall Handler'
3 | icon: 'shield-check'
4 | ---
5 |
6 | Google Cloud Firewall is a **network security feature** that lets you define rules to allow or block traffic to and from your VM instances.
7 | This handler helps you **list firewall rules** in your GCP project using service account authentication.
8 | It makes it easier to fetch firewall configurations for auditing, monitoring, or compliance checks.
9 |
10 | ## Example
11 |
12 | To create the `GCPFirewallHandler` object with GCP credentials:
13 |
14 | ```python
15 | import os
16 | from superagentx.handler.gcp.firewall import GCPFirewallHandler
17 |
18 | # Initialize with a service account file
19 | firewall_handler = GCPFirewallHandler(
20 | creds="/path/to/service-account.json"
21 | )
22 | ```
23 | **List Firewall Rules:**
24 | The get_firewall_details method retrieves all firewall rules in your GCP project.
25 | It returns details like name, allowed protocols/ports, source/destination ranges, and priority.
26 | ```python
27 | firewalls = await firewall_handler.get_firewall_details()
28 | for fw in firewalls:
29 | print(fw.name, fw.direction, fw.priority)
30 | ```
31 |
32 |
--------------------------------------------------------------------------------
/tests/handlers/test_visualization.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from superagentx.visualization import Visualize
4 |
5 | '''
6 | Run Pytest:
7 |
8 | 1.pytest --log-cli-level=INFO tests/handlers/test_visualization.py::TestVisualization::test_visualization
9 |
10 | '''
11 |
12 | @pytest.fixture
13 | def visualize_client_init() -> dict:
14 | obj = Visualize()
15 | chart_data = [
16 | {
17 | "Apples": 5,
18 | "Pears": 3,
19 | "Nectarines": 4,
20 | "Plums": 2,
21 | "Grapes": 4,
22 | "Strawberries": 6
23 | },
24 | {
25 | "Apples": 12,
26 | "Pears": 42,
27 | "Nectarines": 1,
28 | "Plums": 51,
29 | "Grapes": 9,
30 | "Strawberries": 21
31 | }
32 | ]
33 | return {
34 | "visualization": obj,
35 | "data": chart_data
36 | }
37 |
38 | class TestVisualization:
39 |
40 | async def test_visualization(self, visualize_client_init: dict):
41 | obj: Visualize = visualize_client_init.get("visualization")
42 | await obj.pie_chart(data=visualize_client_init.get("data"), show_output=True)
43 | # obj.verticalBar(data=chart_data, output_type="html", show_output=True)
44 |
--------------------------------------------------------------------------------
/docs/prompt.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'PromptTemplate'
3 | icon: 'rectangle-terminal'
4 | ---
5 |
6 | A `PromptTemplate` class is used to create and organize the messages (prompts) that are sent to a language model.
7 | It allows you to define a basic structure for the prompt, making it easy to manage and reuse across different situations.
8 | This helps maintain consistency and simplifies prompt formatting when interacting with the model.
9 |
10 | ### Parameters
11 | | Attribute | Parameters |Type | Description |
12 | | :-------------------- | :---------------- | :------ | :------------------------------------- |
13 | | **Prompt Type** _(optional)_ |`prompt_type` | `str` | specifies the type of prompt. Default `None` |
14 | | **System Message** _(optional)_ |`system_message` | `str` | An optional string that defines a system-level message for the prompt. Default `None`|
15 |
16 |
17 | ```python
18 | from superagentx.prompt import PromptTemplate
19 |
20 | prompt_template = PromptTemplate()
21 | ```
--------------------------------------------------------------------------------
/superagentx/utils/console_color.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 |
3 |
4 | class ConsoleColorType(str, Enum):
5 |
6 | CBLACK = '\33[30m'
7 | CRED = '\33[31m'
8 | CGREEN = '\33[32m'
9 | CYELLOW = '\33[33m'
10 | CBLUE = '\33[34m'
11 | CVIOLET = '\33[35m'
12 | CBEIGE = '\33[36m'
13 | CWHITE = '\33[37m'
14 |
15 | CBLACKBG = '\33[40m'
16 | CREDBG = '\33[41m'
17 | CGREENBG = '\33[42m'
18 | CYELLOWBG = '\33[43m'
19 | CBLUEBG = '\33[44m'
20 | CVIOLETBG = '\33[45m'
21 | CBEIGEBG = '\33[46m'
22 | CWHITEBG = '\33[47m'
23 |
24 | CGREY = '\33[90m'
25 | CRED2 = '\33[91m'
26 | CGREEN2 = '\33[92m'
27 | CYELLOW2 = '\33[93m'
28 | CBLUE2 = '\33[94m'
29 | CVIOLET2 = '\33[95m'
30 | CBEIGE2 = '\33[96m'
31 | CWHITE2 = '\33[97m'
32 |
33 | CGREYBG = '\33[100m'
34 | CREDBG2 = '\33[101m'
35 | CGREENBG2 = '\33[102m'
36 | CYELLOWBG2 = '\33[103m'
37 | CBLUEBG2 = '\33[104m'
38 | CVIOLETBG2 = '\33[105m'
39 | CBEIGEBG2 = '\33[106m'
40 | CWHITEBG2 = '\33[107m'
41 |
42 | CEND = '\33[0m'
43 | CBOLD = '\33[1m'
44 | CITALIC = '\33[3m'
45 | CURL = '\33[4m'
46 | CBLINK = '\33[5m'
47 | CBLINK2 = '\33[6m'
48 | CSELECTED = '\33[7m'
--------------------------------------------------------------------------------
/docs/examples/handlers/visualization.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Visualization'
3 | icon: 'chart-bar'
4 | ---
5 |
6 | A visualization handler is a tool or library that helps developers and analysts create visual representations of data.
7 | Its main purpose is to transform raw data into charts, graphs, and dashboards, making it easier to understand trends,
8 | patterns, and insights. It serves as a bridge between complex datasets and easy-to-digest visuals, which are critical
9 | for decision-making.
10 |
11 | ## Example
12 | ```python visualization.py
13 | from superagentx.visualization import Visualize
14 |
15 | async def visualize_handler():
16 | obj = Visualize()
17 | chart_data = [
18 | {
19 | "Apples": 5,
20 | "Pears": 3,
21 | "Nectarines": 4,
22 | "Plums": 2
23 | "Grapes": 4,
24 | "Strawberries": 6
25 | },
26 | {
27 | "Apples": 12,
28 | "Pears": 42,
29 | "Nectarines": 1,
30 | "Plums": 51,
31 | "Grapes": 9,
32 | "Strawberries": 21
33 | }
34 | ]
35 | await obj.pie_chart(data=chart_data, show_output=True)
36 | ```
37 |
38 | ## Result
39 |
40 |
41 |
--------------------------------------------------------------------------------
/superagentx/vector_stores/base.py:
--------------------------------------------------------------------------------
1 | from abc import ABCMeta, abstractmethod
2 |
3 |
4 | class BaseVectorStore(metaclass=ABCMeta):
5 |
6 | @abstractmethod
7 | async def create(self, *args, **kwargs):
8 | """Creating a new collection or index"""
9 | raise NotImplementedError
10 |
11 | @abstractmethod
12 | async def insert(self, *args, **kwargs):
13 | """Insert Vectors into a collection"""
14 | raise NotImplementedError
15 |
16 | @abstractmethod
17 | async def search(self, *args, **kwargs):
18 | """Search for similar vectors"""
19 | raise NotImplementedError
20 |
21 | @abstractmethod
22 | async def update(self, *args, **kwargs):
23 | """Update a vector"""
24 | raise NotImplementedError
25 |
26 | @abstractmethod
27 | async def exists(self, *args, **kwargs):
28 | raise NotImplementedError
29 |
30 | @abstractmethod
31 | async def delete_collection(self, *args, **kwargs):
32 | """Delete a collection."""
33 | raise NotImplementedError
34 |
35 | @abstractmethod
36 | async def delete_by_conversation_id(self, **kwargs):
37 | """Delete by conversation id."""
38 | raise NotImplementedError
39 |
--------------------------------------------------------------------------------
/docs/examples/handlers/azure/load_balancer.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Load Balancer Handler'
3 | icon: 'network-wired'
4 | ---
5 |
6 | The **Azure Load Balancer Handler** is responsible for retrieving and managing **Azure Load Balancers** within a subscription.
7 | It uses the Azure SDK for Python (`azure-mgmt-network`) and authentication via `azure-identity` to collect server asset details for governance, compliance, and monitoring.
8 |
9 |
10 |
11 | ## Example
12 |
13 | To create the **AzureLoadBalancerHandler** object, initialize it with your **Azure Subscription ID, Tenant ID, Client ID, and Client Secret** (or load them from environment variables):
14 |
15 | ```python
16 | import os
17 | from superagentx_handlers.azure.loadbalancer import AzureLoadBalancerHandler
18 |
19 | lb_handler = AzureLoadBalancerHandler(
20 | subscription_id=os.getenv("AZURE_SUBSCRIPTION_ID"),
21 | tenant_id=os.getenv("AZURE_TENANT_ID"),
22 | client_id=os.getenv("AZURE_CLIENT_ID"),
23 | client_secret=os.getenv("AZURE_CLIENT_SECRET")
24 | )
25 | ```
26 |
27 | **Get All Load Balancers in Subscription:**
28 | Fetches all load balancers in the configured subscription, including their properties (frontend IPs, backend pools, probes, rules, etc.).
29 | ```python
30 | lbs = await lb_handler.get_all_load_balancers_in_subscription()
31 | print(lbs)
32 | ```
--------------------------------------------------------------------------------
/superagentx/handler/task/greetings/welcome_handler.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from superagentx.handler.base import BaseHandler
3 |
4 | logger = logging.getLogger(__name__)
5 |
6 |
7 | class WelcomeHandler(BaseHandler):
8 | """
9 | Simple handler used to demonstrate CodeEngine functionality.
10 | Returns raw dicts so CodeEngine can unwrap them properly.
11 | """
12 |
13 | def __init__(self, first_name: str | None = None, last_name: str | None = None):
14 | super().__init__()
15 | self.first_name = first_name
16 | self.last_name = last_name
17 |
18 | async def get_first_name(self) -> dict:
19 | """
20 | Return the user's first name or default to 'SuperAgentX'.
21 | Returns a raw dict so CodeEngine can parse it directly.
22 | """
23 | first_name = self.first_name or "SuperAgentX"
24 | last_name = self.last_name
25 |
26 | logger.debug("WelcomeHandler.get_first_name -> %s", first_name)
27 |
28 | return {"first_name": first_name, "last_name": last_name}
29 |
30 | async def send_greeting(self, message: str) -> dict:
31 | """
32 | Send a greeting message.
33 | """
34 | logger.info("Sending greeting: %s", message)
35 |
36 | return {
37 | "status": "sent",
38 | "message": message
39 | }
40 |
--------------------------------------------------------------------------------
/superagentx_cli/templates/supervisor.conf.jinja2:
--------------------------------------------------------------------------------
1 | [program:{{ app_name }}]
2 | ; -------------------------
3 | ; Metadata & Purpose
4 | ; -------------------------
5 | ; SuperAgentX CLI Worker
6 | ; Handles agentic job execution in production
7 | ; Starts after other system services (priority=1010)
8 | ; -------------------------
9 |
10 | directory={{ app_path }}
11 |
12 | command={{ app_path }}/.venv/bin/dotenv -f {{ app_path }}/.env run -- {{ app_path }}/.venv/bin/uvicorn {{ app_name }}.restpipe:{{ app_name }}_app --host 0.0.0.0 --port 9000
13 |
14 | ; Logging configuration
15 | stdout_logfile=/var/log/supervisor/{{ app_name }}.log
16 | stderr_logfile=/var/log/supervisor/{{ app_name }}.log
17 | stdout_logfile_maxbytes=20MB
18 | stderr_logfile_maxbytes=20MB
19 | stdout_logfile_backups=5
20 | stderr_logfile_backups=5
21 |
22 | ; Process control
23 | autostart=true
24 | autorestart=true
25 | startsecs=5
26 | startretries=3
27 |
28 | ; Graceful shutdown behavior
29 | stopsignal=INT
30 | stopasgroup=true
31 | killasgroup=true
32 |
33 | ; Run as root (can change to non-root for extra security)
34 | user=root
35 |
36 | ; Process priority (start order)
37 | priority=1010
38 |
39 | ; Environment variables (customize as needed)
40 | environment=APP_ENV="production",PYTHONUNBUFFERED="1",PATH="{{ app_path }}/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
41 |
--------------------------------------------------------------------------------
/docs/examples/handlers/azure/nsg.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'NSG Handler'
3 | icon: 'shield'
4 | ---
5 |
6 | Azure Network Security Group (NSG) is a core networking feature in Microsoft Azure that acts as a virtual firewall.
7 | It controls inbound and outbound traffic to Azure resources such as Virtual Machines, Subnets, and NICs.
8 | The `AzureNSGHandler` makes it easy to authenticate with Azure using service principal credentials and retrieve
9 | all NSGs within a subscription, helping with **network security auditing** and **firewall configuration visibility**.
10 |
11 | ## Example
12 |
13 | To create the `AzureNSGHandler` object, provide your Azure credentials (subscription ID, tenant ID, client ID, and client secret).
14 | These can also be loaded from environment variables:
15 |
16 | ```python
17 | import os
18 | from superagentx_handlers.azure.nsg import AzureNSGHandler
19 |
20 | nsg_handler = AzureNSGHandler(
21 | subscription_id=os.getenv("AZURE_SUBSCRIPTION_ID"),
22 | tenant_id=os.getenv("AZURE_TENANT_ID"),
23 | client_id=os.getenv("AZURE_CLIENT_ID"),
24 | client_secret=os.getenv("AZURE_CLIENT_SECRET"),
25 | )
26 | ```
27 |
28 | **List All Network Security Groups (NSGs):**
29 | Retrieves a list of all NSGs in the subscription. Each NSG includes its rules and properties.
30 | ```python
31 | nsgs = await nsg_handler.get_network_security_groups()
32 | print(nsgs)
33 | ```
34 |
35 |
--------------------------------------------------------------------------------
/tests/task/test_api_handler.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import json
3 |
4 | from superagentx.task_engine import TaskEngine
5 | from superagentx.handler.task.general.api_handler import APIHandler
6 |
7 | logger = logging.getLogger(__name__)
8 |
9 | '''
10 | Run Pytest:
11 |
12 | 1. pytest --log-cli-level=INFO tests/task/test_api_handler.py::TestAPIHandler::test_parallel_code
13 | '''
14 |
15 |
16 | class TestAPIHandler:
17 |
18 | async def test_parallel_code(self):
19 | engine = TaskEngine(
20 | handler=APIHandler(),
21 | instructions=[
22 |
23 | # PARALLEL (weather OK, stock FAILS, news OK)
24 | [
25 | {"fetch_weather": {"city": "San Francisco"}},
26 | {"fetch_stock": {"symbol": "AAPL"}}, # FAIL
27 | {"fetch_news": {"topic": "AI"}}
28 | ],
29 |
30 | # Combine using $prev.
31 | {
32 | "combine_successful": {
33 | "weather": "$prev.fetch_weather",
34 | "stock": "$prev.fetch_stock", # will be None
35 | "news": "$prev.fetch_news"
36 | }
37 | }
38 | ]
39 | )
40 |
41 | result = await engine.start()
42 | logger.info(f"Code : {json.dumps(result, indent=2)}")
43 |
--------------------------------------------------------------------------------
/docs/examples/handlers/azure/storage.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Storage Handler'
3 | icon: 'database'
4 | ---
5 |
6 | Azure Storage Accounts are scalable cloud storage solutions in Microsoft Azure,
7 | commonly used to store **blobs (files), queues, tables, and file shares**.
8 | The `AzureStorageHandler` provides an abstraction layer to authenticate with Azure using
9 | service principal credentials and retrieve all storage accounts within a subscription,
10 | including their **encryption settings, firewall/network rules, and public access status**.
11 |
12 | ## Example
13 |
14 | To create the `AzureStorageHandler` object, provide your Azure credentials
15 | (subscription ID, tenant ID, client ID, and client secret).
16 | These can also be loaded from environment variables:
17 |
18 | ```python
19 | import os
20 | from superagentx_handlers.azure.storage import AzureStorageHandler
21 |
22 | storage_handler = AzureStorageHandler(
23 | subscription_id=os.getenv("AZURE_SUBSCRIPTION_ID"),
24 | tenant_id=os.getenv("AZURE_TENANT_ID"),
25 | client_id=os.getenv("AZURE_CLIENT_ID"),
26 | client_secret=os.getenv("AZURE_CLIENT_SECRET"),
27 | )
28 | ```
29 | **List All Storage Accounts:**
30 | Retrieves a list of all storage accounts within the subscription,
31 | along with their associated properties.
32 | ```python
33 | accounts = await storage_handler.list_storage_accounts()
34 | print(accounts)
35 | ```
--------------------------------------------------------------------------------
/docs/handler.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Handler'
3 | icon: 'bars-progress'
4 | ---
5 |
6 | We use the term "handler" interchangeably with "tool calling." While "tool calling" is sometimes used to refer
7 | to the invocation of a single function. It contains the logic for managing particular operations, playing a
8 | key role in organizing and carrying out tasks.
9 |
10 | With the `BaseHandler` from `superagentx.handler.base`, you can create your own custom
11 | handlers.
12 |
13 | Additionally, we also provide pre-built handlers for various other
14 | services and libraries.
15 |
16 | ### Tool:
17 | A tool is a method or function that performs a specific action within a larger system. In this context,
18 | tools are asynchronous functions that handle specific tasks, like fetching data from external APIs or
19 | performing calculations. The @tool decorator marks these methods as tools that can be invoked by the system.
20 |
21 | ```python
22 | from superagentx.handler.decorators import tool
23 |
24 | class ExaHandler(BaseHandler):
25 |
26 | @tool
27 | async def search_contents(
28 | self,
29 | *,
30 | query: str,
31 | use_autoprompt: bool,
32 | num_results: int = 10,
33 | search_type: str | None = None
34 | ):
35 | ```
36 |
37 |
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/security_groups.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Security Groups Handler'
3 | icon: 'lock'
4 | ---
5 |
6 | Amazon EC2 **Security Groups** act as virtual firewalls to control inbound and outbound traffic for your AWS resources, such as EC2 instances and load balancers. They help secure your applications by defining rules that allow or deny specific traffic. Security Groups operate at the instance level and are an essential part of AWS networking and security best practices.
7 |
8 | This handler enables you to interact with **AWS Security Groups** using boto3, making it easier to retrieve details such as rules, attached instances, and associated VPCs. It provides an abstraction for developers to collect security group data seamlessly.
9 |
10 |
11 |
12 | ## Example
13 |
14 | To create the AWS Security Groups Handler object with AWS credentials:
15 |
16 | ```python
17 | import os
18 | from superagentx_handlers.aws.security_groups import AWSSecurityGroupsHandler
19 |
20 | sg_handler = AWSSecurityGroupsHandler(
21 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
22 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
23 | region_name="us-east-1"
24 | )
25 | ```
26 |
27 | **List Security Groups:**
28 | Retrieves details of all security groups in your AWS account for the given region, including rules, VPCs, and attached resources.
29 | ```python
30 | security_groups = await sg_handler.get_ec2_security_groups()
31 | print(security_groups)
32 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/azure/vm.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'VM Handler'
3 | icon: 'server'
4 | ---
5 |
6 | Azure Virtual Machines (VMs) are scalable computing resources in Microsoft Azure.
7 | They allow you to run Windows or Linux servers in the cloud without needing to maintain physical hardware.
8 | With Azure VMs, you can host applications, databases, and workloads with built-in high availability, security, and scalability.
9 |
10 | This handler provides seamless interaction with Azure VMs to collect information about virtual machines within a subscription.
11 | It uses service principal authentication (`tenant_id`, `client_id`, `client_secret`) and requires appropriate Azure RBAC permissions (e.g., **Reader** role).
12 |
13 |
14 |
15 | ## Example
16 |
17 | To create the `AzureVMHandler` object with your Azure credentials:
18 |
19 | ```python
20 | import os
21 | from superagentx_handlers.azure.vm import AzureVMHandler
22 |
23 | azure_vm_handler = AzureVMHandler(
24 | subscription_id=os.getenv("AZURE_SUBSCRIPTION_ID"),
25 | tenant_id=os.getenv("AZURE_TENANT_ID"),
26 | client_id=os.getenv("AZURE_CLIENT_ID"),
27 | client_secret=os.getenv("AZURE_CLIENT_SECRET")
28 | )
29 | ```
30 | **List Virtual Machines (get_vms):**
31 | Retrieves a list of all accessible Azure VM instances within the configured subscription.
32 | Each VM’s details (name, ID, region, size, OS, and network/storage profile) are returned in dictionary format.
33 | ```python
34 | vms = await azure_vm_handler.get_vms()
35 | print(vms)
36 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/servicenow.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'ServiceNow Handler'
3 | icon: 'server'
4 | ---
5 |
6 | ServiceNow is a cloud-based platform that provides IT service management (ITSM), helping organizations manage incidents, assets, changes, and workflows. The `ServiceNowHandler` allows seamless integration with ServiceNow to fetch users, assets, and related tickets programmatically.
7 |
8 | ## Example
9 |
10 | To create the `ServiceNowHandler` object, initialize it with your ServiceNow instance URL and credentials. If not provided, the values will be picked up from environment variables.
11 |
12 | ```python
13 | import os
14 | from superagentx_handlers.servicenow import ServiceNowHandler
15 |
16 | servicenow_handler = ServiceNowHandler(
17 | instance_url=os.getenv("SERVICENOW_INSTANCE_URL"),
18 | username=os.getenv("SERVICENOW_USERNAME"),
19 | password=os.getenv("SERVICENOW_PASSWORD"),
20 | )
21 | ```
22 |
23 | **Get User Name:**
24 | Fetches the user’s display name from ServiceNow using their sys_id.
25 | ```python
26 | user_name = await servicenow_handler.get_user_name("46d44a2d1b2123009b5f3d92cc4bcb65")
27 | print(user_name) # e.g., "John Doe"
28 | ```
29 |
30 | **Get Assets with Details and Tickets:**
31 | Retrieves a list of assets along with details like owner, model, warranty, and their associated incident tickets.
32 | ```python
33 | assets_report = await servicenow_handler.get_assets_with_details_and_tickets()
34 | for asset in assets_report:
35 | print(asset["Asset Name"], asset["Tickets"])
36 | ```
--------------------------------------------------------------------------------
/tests/handlers/test_financial_data.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import pytest
4 |
5 | from superagentx.handler.financial_data import FinancialHandler
6 |
7 | '''
8 | Run Pytest:
9 |
10 | 1.pytest --log-cli-level=INFO tests/handlers/test_financial_data.py::TestFinancial::test_get_stock_price
11 | 2.pytest --log-cli-level=INFO tests/handlers/test_financial_data.py::TestFinancial::test_get_company_financials
12 | 3.pytest --log-cli-level=INFO tests/handlers/test_financial_data.py::TestFinancial::test_get_income_statement
13 |
14 | '''
15 |
16 | @pytest.fixture
17 | def financial_client_init() -> FinancialHandler:
18 | financial_handler = FinancialHandler(
19 | api_key=os.getenv("FINANCIAL_MODELING_PREP_API_KEY"),
20 | symbol='AA'
21 | )
22 | return financial_handler
23 |
24 | class TestFinancial:
25 |
26 | async def test_get_stock_price(self, financial_client_init: FinancialHandler):
27 | res = await financial_client_init.get_stock_price()
28 | assert isinstance(res, list)
29 | assert len(res) > 0
30 |
31 | async def test_get_company_financials(self, financial_client_init: FinancialHandler):
32 | res = await financial_client_init.get_company_financials()
33 | assert isinstance(res, list)
34 | assert len(res) > 0
35 |
36 | async def test_get_income_statement(self, financial_client_init: FinancialHandler ):
37 | res = await financial_client_init.get_income_statement()
38 | assert isinstance(res, list)
39 | assert len(res) > 0
40 |
--------------------------------------------------------------------------------
/superagentx/computer_use/browser/state.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass, field
2 | from typing import Any
3 |
4 | from pydantic import BaseModel
5 |
6 | from superagentx.computer_use.browser.dom.history_tree_processor.tree_processor_service import DOMHistoryElement
7 | from superagentx.computer_use.browser.dom.views import DOMState
8 |
9 |
10 | class TabInfo(BaseModel):
11 | page_id: int
12 | url: str
13 | title: str
14 |
15 |
16 | @dataclass
17 | class BrowserState(DOMState):
18 | url: str
19 | title: str
20 | tabs: list[TabInfo]
21 | screenshot: str | None = None
22 | pixels_above: int = 0
23 | pixels_below: int = 0
24 | browser_errors: list[str] = field(default_factory=list)
25 |
26 |
27 | @dataclass
28 | class BrowserStateHistory:
29 | url: str
30 | title: str
31 | tabs: list[TabInfo]
32 | interacted_element: list[DOMHistoryElement | None]
33 | screenshot: str | None = None
34 |
35 | def to_dict(self) -> dict[str, Any]:
36 | return {
37 | "tabs": [tab.model_dump() for tab in self.tabs],
38 | "screenshot": self.screenshot,
39 | "interacted_element": [
40 | el.to_dict() if el else None for el in self.interacted_element
41 | ],
42 | "url": self.url,
43 | "title": self.title,
44 | }
45 |
46 |
47 | class BrowserError(Exception):
48 | """Base class for all browser errors"""
49 |
50 |
51 | class URLNotAllowedError(BrowserError):
52 | """Error raised when a URL is not allowed"""
--------------------------------------------------------------------------------
/docs/examples/handlers/datadog/incidents.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Datadog Incidents'
3 | icon: 'shield-dog'
4 | ---
5 |
6 | Datadog Incidents is a service that helps engineering and operations teams track, manage, and resolve incidents efficiently.
7 | It provides powerful integrations, collaborative workflows, and monitoring visibility to ensure quick resolution of critical issues.
8 |
9 | This handler allows seamless interaction with **Datadog Incidents API**, enabling you to **list** and **search** incidents programmatically.
10 | It uses API and Application keys for authentication (`DD_API_KEY`, `DD_APP_KEY`) and requires the `DD_SITE` configuration (e.g., `us5.datadoghq.com`).
11 |
12 |
13 |
14 | ## Example
15 |
16 | To create the `DDIncidentsHandler` object with Datadog credentials:
17 |
18 | ```python
19 | import os
20 | from superagentx_handlers.datadog.incidents import DDIncidentsHandler
21 |
22 | dd_handler = DDIncidentsHandler(
23 | host=os.getenv("DD_SITE"), # e.g., "us5.datadoghq.com"
24 | api_key=os.getenv("DD_API_KEY"),
25 | app_key=os.getenv("DD_APP_KEY")
26 | )
27 | ```
28 | **List Incidents (list_incidents):**
29 | Retrieves a list of all incidents in your Datadog account.
30 | ```python
31 | incidents = await dd_handler.list_incidents()
32 | print(incidents)
33 | ```
34 |
35 | **Search Incidents (search_incidents):**
36 | Search for incidents that match a specific query (by title, status, severity, etc.).
37 | ```python
38 | results = await dd_handler.search_incidents(query="status:active severity:SEV-1")
39 | print(results)
40 | ```
41 |
--------------------------------------------------------------------------------
/docs/examples/handlers/slack.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Slack Handler'
3 | icon: 'slack'
4 | ---
5 |
6 | Slack is a messaging platform widely used for team communication and collaboration. It provides channels for organizing conversations, direct messaging, file sharing, and integrates with external tools via its API. Using the Slack API, you can send messages, fetch messages, and manage channels programmatically.
7 |
8 | ## Example
9 |
10 | To create the `SlackHandler` object, initialize it with your Slack **bot token**.
11 | The handler uses the Slack Web API to interact with channels and messages.
12 |
13 | ```python
14 | import os
15 | from superagentx_handlers.slack import SlackHandler
16 |
17 | slack_handler = SlackHandler(
18 | bot_token=os.getenv("SLACK_BOT_TOKEN")
19 | )
20 | ```
21 |
22 | **Send Slack Message:**
23 | Sends a plain text message to a specific Slack channel.
24 | ```python
25 | response = await slack_handler.send_slack_message(
26 | text="Hello team! :wave:",
27 | channel_id="C1234567890"
28 | )
29 | print(response)
30 | ```
31 |
32 | **Get Messages from a Channel:**
33 | Retrieves the most recent messages from a given Slack channel.
34 | ```python
35 | messages = await slack_handler.get_messages_from_channel(
36 | channel_id="C1234567890",
37 | limit=5
38 | )
39 | for msg in messages:
40 | print(msg["text"])
41 | ```
42 |
43 | **Get Channel ID by Name:**
44 | Looks up the channel ID using its name.
45 | ```python
46 | channel_id = await slack_handler.get_channel_id("general")
47 | print("Channel ID:", channel_id)
48 | ```
--------------------------------------------------------------------------------
/tests/handlers/test_bedrock_ai_handler.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import pytest
4 |
5 | from superagentx.handler.ai import AIHandler
6 | from superagentx.llm import LLMClient
7 |
8 | logger = logging.getLogger(__name__)
9 |
10 | '''
11 | Run Pytest:
12 |
13 | 1. pytest --log-cli-level=INFO tests/handlers/test_bedrock_ai_handler.py::TestBedrockAIHandler::test_ai_bedrock_message
14 | '''
15 |
16 |
17 |
18 | @pytest.fixture
19 | def ai_bedrock_client_init() -> dict:
20 | llm_config = {'model': 'anthropic.claude-3-5-sonnet-20240620-v1:0', 'llm_type': 'bedrock', 'async_mode': True}
21 |
22 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
23 | response = {'llm': llm_client}
24 | return response
25 |
26 |
27 | class TestBedrockAIHandler:
28 |
29 | async def test_ai_bedrock_message(self, ai_bedrock_client_init: dict):
30 | llm_client: LLMClient = ai_bedrock_client_init.get('llm')
31 |
32 | content_handler = AIHandler(llm=llm_client)
33 | response = await content_handler.text_creation(system_message="You are an app that creates playlists for a "
34 | "radio station that plays rock and pop music. "
35 | "Only return song names and the artist.",
36 | instruction="Make sure the songs are by artists from the "
37 | "United Kingdom.")
38 | logger.info(f"Response ==> {response}")
39 |
--------------------------------------------------------------------------------
/superagentx/utils/helper.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 | import re
3 | import asyncio
4 |
5 | from typing import Callable, Awaitable, Any, Optional, Union
6 |
7 | StatusCallback = Callable[..., Awaitable[Any]]
8 |
9 |
10 | async def sync_to_async(func, *args, **kwargs) -> Any:
11 | return await asyncio.to_thread(func, *args, **kwargs)
12 |
13 |
14 | async def _maybe_await(coro):
15 | if asyncio.iscoroutine(coro):
16 | await coro
17 |
18 |
19 | async def iter_to_aiter(iterable):
20 | for item in iterable:
21 | yield item
22 |
23 |
24 | async def get_fstring_variables(s: str):
25 | # This regular expression looks for variables in curly braces
26 | return re.findall(r'\{(.*?)}', s)
27 |
28 |
29 | async def ptype_to_json_scheme(ptype: str) -> str:
30 | match ptype:
31 | case 'int':
32 | return "integer"
33 | case 'str':
34 | return "string"
35 | case 'bool':
36 | return "boolean"
37 | case 'list':
38 | return "array"
39 | case 'dict' | _:
40 | return "object"
41 |
42 |
43 | async def rm_trailing_spaces(data):
44 | """Recursively remove trailing whitespace from all string values in a JSON-like structure."""
45 | if isinstance(data, dict):
46 | return {k: await rm_trailing_spaces(v) for k, v in data.items()}
47 | elif isinstance(data, list):
48 | return [await rm_trailing_spaces(v) for v in data]
49 | elif isinstance(data, str):
50 | return data.rstrip() # Remove trailing whitespace
51 | else:
52 | return data
53 |
--------------------------------------------------------------------------------
/tests/io/test_console_io_stream.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import pytest
4 |
5 | from superagentx.io.console import IOConsole
6 | from superagentx.utils.console_color import ConsoleColorType
7 |
8 | logger = logging.getLogger(__name__)
9 |
10 | '''PyTest
11 | 1. pytest -s --log-cli-level=INFO tests/io/test_console_io_stream.py::TestIOConsole::test_console_io_input_print
12 | 2. pytest -s --log-cli-level=INFO tests/io/test_console_io_stream.py::TestIOConsole::test_console_io_input_password
13 | '''
14 |
15 |
16 | @pytest.fixture
17 | def console_io() -> IOConsole:
18 | return IOConsole()
19 |
20 |
21 | class TestIOConsole:
22 |
23 | async def test_console_io_input_print(self, console_io: IOConsole):
24 | logging.info(f"IO Console Print & Input Test.")
25 |
26 | await console_io.write(ConsoleColorType.CYELLOW2.value, end="")
27 | await console_io.write("Hello, Super AgentX World!", flush=True)
28 |
29 | # Getting input from the console
30 | data = await console_io.read("Enter something: ")
31 | await console_io.write(f"You entered: {data}", flush=True)
32 |
33 | async def test_console_io_input_password(self, console_io: IOConsole):
34 | logging.info(f"IO Console Print & Input Password Test.")
35 |
36 | await console_io.write(ConsoleColorType.CGREEN.value, end="")
37 | await console_io.write("Hello, Super AgentX World!", flush=True)
38 |
39 | # Getting password input from the console
40 | data = await console_io.read("Enter something: ", password=True)
41 | await console_io.write(f"You entered: {data}", flush=True)
42 |
--------------------------------------------------------------------------------
/docs/examples/handlers/Google/gmail.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Gmail Handler'
3 | icon: 'square-m'
4 | ---
5 |
6 | The Gmail Handler is a specialized tool designed to interact with the Gmail API, enabling users to manage their
7 | email accounts programmatically. This handler simplifies the process of accessing user profiles, sending emails,
8 | and creating draft emails. It uses OAuth 2.0 for authentication and provides a user-friendly interface to perform
9 | various email-related tasks asynchronously.
10 |
11 | ## Example
12 | Set up a GmailHandler using the provided credentials, allowing the application to send, receive, and manage emails
13 | through Gmail programmatically.
14 |
15 | To setup and get a credentials refer here.
16 |
17 | After creating and enabling the Google Cloud API, you need to provide the path to the credentials in the _credentials_ parameters.
18 |
19 | ```python Gmail_handler.py
20 | import asyncio
21 |
22 | from superagentx_handlers.google.gmail import GmailHandler
23 |
24 |
25 | async def get_user_profile():
26 | gmail_handler = GmailHandler(
27 | credentials=""
28 | )
29 | return await gmail_handler.get_user_profile()
30 |
31 |
32 | async def main():
33 | res = await get_user_profile()
34 | print(res)
35 |
36 | if __name__ == '__main__':
37 | asyncio.run(main())
38 | ```
39 |
40 | ## Result
41 | ```python Gmail user profile
42 | {
43 | 'emailAddress': 'bala234@gmail.com',
44 | 'messagesTotal': 3678,
45 | 'threadsTotal': 4352,
46 | 'historyId': '985428'
47 | }
48 | ```
49 |
--------------------------------------------------------------------------------
/superagentx_cli/templates/wspipe.py.jinja2:
--------------------------------------------------------------------------------
1 | {# templates/wspipe.py.jinja2 #}
2 | import asyncio
3 | import urllib.parse
4 |
5 | from rich import print as rprint
6 | from superagentx.pipeimpl.wspipe import WSPipe # https://websockets.readthedocs.io/en/stable/
7 | from websockets import CloseCode, ServerConnection
8 |
9 | from {{ package_name }}.config import AUTH_TOKEN
10 | from {{ package_name }}.pipe import get_{{ pipe_name }}_pipe
11 |
12 |
13 | async def auth_handler(ws: ServerConnection) -> bool:
14 | """Authenticate user from token in query parameter."""
15 | query = urllib.parse.urlparse(ws.request.path).query
16 | params = urllib.parse.parse_qs(query)
17 | values = params.get('token', [])
18 | if values:
19 | token = values[0]
20 | if token is None or token != AUTH_TOKEN:
21 | await ws.close(
22 | code=CloseCode.INTERNAL_ERROR,
23 | reason='Authentication failed!'
24 | )
25 | return False
26 | return True
27 |
28 |
29 | async def main():
30 | """
31 | Launches the {{ app_name }} pipeline websocket server for processing requests and handling data.
32 | """
33 | pipe = await get_{{ pipe_name }}_pipe()
34 | ws_pipe = WSPipe(
35 | search_name='SuperAgentX {{ app_name }} Websocket Server',
36 | agentx_pipe=pipe,
37 | auth_handler=auth_handler,
38 | )
39 | await ws_pipe.start()
40 |
41 |
42 | if __name__ == '__main__':
43 | try:
44 | asyncio.run(main())
45 | except (KeyboardInterrupt, asyncio.CancelledError):
46 | rprint("\nUser canceled the [bold yellow][i]pipe[/i]!"){{'\n'}}
47 |
--------------------------------------------------------------------------------
/tests/handlers/test_elastic_search.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from superagentx.handler.elastic_search import ElasticsearchHandler
4 |
5 | '''
6 | Run Pytest:
7 |
8 | 1.pytest --log-cli-level=INFO tests/handlers/test_elastic_search.py::TestElasticsearch::test_elasticsearch_search
9 | 2.pytest --log-cli-level=INFO tests/handlers/test_elastic_search.py::TestElasticsearch::test_elasticsearch_create
10 |
11 | '''
12 |
13 |
14 | @pytest.fixture
15 | def elasticsearch_client_init() -> ElasticsearchHandler:
16 | elasticsearch_handler = ElasticsearchHandler(
17 | hosts="http://localhost:9200",
18 | username="elastic",
19 | password="password"
20 | )
21 | return elasticsearch_handler
22 |
23 |
24 | class TestElasticsearch:
25 |
26 | # Test async elasticsearch handler - search method
27 | async def test_elasticsearch_search(self, elasticsearch_client_init: ElasticsearchHandler):
28 | elasticsearch = await elasticsearch_client_init.search(
29 | index_name="index_name",
30 | query={"match_all": {}}
31 | )
32 | assert isinstance(elasticsearch, object)
33 |
34 | # Test async elasticsearch handler - create method
35 | async def test_elasticsearch_create(self, elasticsearch_client_init: ElasticsearchHandler):
36 | elasticsearch = await elasticsearch_client_init.create(
37 | index_name="index_name",
38 | document_id="index_name",
39 | document={
40 | "@timestamp": "2099-11-15T13:12:00",
41 | "message": "GET /search HTTP/1.1 200 1070000",
42 | },
43 |
44 | )
45 | assert isinstance(elasticsearch, object)
46 |
--------------------------------------------------------------------------------
/tests/llm/test_tool.py:
--------------------------------------------------------------------------------
1 | import inspect
2 | from typing import get_type_hints
3 |
4 |
5 | def get_delivery_date(order_id: str, id: int) -> str:
6 | """Get the delivery date for a customer's order. Call this whenever you need to know
7 | the delivery date, for example when a customer asks 'Where is my package"""
8 | return "test"
9 |
10 |
11 | def generate_function_json(func) -> dict:
12 | # Get function name
13 | func_name = func.__name__
14 |
15 | # Get function docstring
16 | docstring = inspect.getdoc(func)
17 |
18 | # Get function annotations (parameter types and return llm_type)
19 | type_hints = get_type_hints(func)
20 |
21 | # Generate the 'properties' field based on function parameters
22 | properties = {}
23 | for param, param_type in type_hints.items():
24 | if param != 'return':
25 | properties[param] = {
26 | "llm_type": param_type.__name__,
27 | "description": f"The {param.replace('_', ' ')}."
28 | }
29 |
30 | # Create the final JSON structure
31 | function_json = {
32 | "function": {
33 | "name": func_name,
34 | "description": docstring,
35 | "parameters": {
36 | "llm_type": "object",
37 | "properties": properties,
38 | "required": list(properties.keys()),
39 | "additionalProperties": False
40 | }
41 | }
42 | }
43 | # return json.dumps(function_json, indent=4)
44 | return function_json
45 |
46 |
47 | # Generate JSON for the function
48 | function_json = generate_function_json(get_delivery_date)
49 | tool = [function_json]
50 |
--------------------------------------------------------------------------------
/examples/agents/ai_agent.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | from superagentx.agent import Agent
4 | from superagentx.engine import Engine
5 | from superagentx.handler.ai import AIHandler
6 | from superagentx.llm import LLMClient
7 | from superagentx.prompt import PromptTemplate
8 |
9 |
10 | async def main():
11 | print("Welcome to SuperAgentX AI Content Generator Tutorial")
12 |
13 | # Step 1: Initialize LLM
14 | # Note: You need to setup your OpenAI API key before running this step.
15 | # export OPENAI_API_KEY=
16 | llm_config = {"model": "gpt-4o", "llm_type": "openai"}
17 | llm_client = LLMClient(llm_config=llm_config)
18 |
19 | # Step 2: Setup MCP tool handler (Reddit trending analyzer)
20 | # Note: You need to install the mcp-server-reddit package before running this step.
21 |
22 | content_creator_handler = AIHandler(llm=llm_client)
23 |
24 | # Step 3: Create Prompt Template
25 | prompt_template = PromptTemplate()
26 |
27 | # Step 4: Create Engine for Reddit analysis using MCP
28 | content_engine = Engine(handler=content_creator_handler, llm=llm_client,
29 | prompt_template=prompt_template)
30 |
31 | # Step 5: Define Reddit Agent
32 | agent = Agent(goal="Generate content based on social media posts user input",
33 | role="You're Content Generator",
34 | llm=llm_client, prompt_template=prompt_template,
35 | engines=[content_engine])
36 |
37 | result = await agent.execute(query_instruction="Create the digital marketing content")
38 |
39 | print(f"Agent Result : {result}")
40 |
41 |
42 | if __name__ == "__main__":
43 | asyncio.run(main())
44 |
--------------------------------------------------------------------------------
/superagentx_cli/templates/deployment.sh.jinja2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 | set -u
4 |
5 | echo "🚀 Starting deployment of {{ app_name }}..."
6 |
7 | PROJECT_PATH="{{ app_path }}"
8 | VENV_PATH="{{ app_path }}/.venv"
9 | CONF_SRC="{{ app_path }}/{{ app_name }}/{{ app_name }}.conf"
10 |
11 | ###############################################
12 | # STEP 1 — Install uv (if missing)
13 | ###############################################
14 |
15 | if ! command -v uv &>/dev/null; then
16 | echo "📦 Installing uv..."
17 | curl -LsSf https://astral.sh/uv/install.sh | sh
18 | export PATH="$HOME/.local/bin:$PATH"
19 | fi
20 |
21 | echo "✔ uv available at: $(command -v uv)"
22 |
23 | ###############################################
24 | # STEP 2 — Create venv (uv venv)
25 | ###############################################
26 |
27 | if [[ ! -d "$VENV_PATH" ]]; then
28 | echo "🐍 Creating virtual environment using uv..."
29 | uv venv "$VENV_PATH"
30 | else
31 | echo "🐍 venv already exists."
32 | fi
33 |
34 | # Activate environment
35 | source "$VENV_PATH/bin/activate"
36 |
37 | ###############################################
38 | # STEP 3 — Install dependencies from pyproject
39 | ###############################################
40 |
41 | echo "📦 Installing dependencies via uv..."
42 | cd "$PROJECT_PATH"
43 | uv sync --reinstall
44 |
45 | echo "✔ Python environment ready."
46 | ##############################
47 | # STEP 4 — Supervisor config
48 | ##############################
49 |
50 | echo "📁 Copying Supervisor config..."
51 | SUPERVISOR_DIR="/etc/supervisor/conf.d"
52 | cp "$CONF_SRC" "$SUPERVISOR_DIR/{{ app_name }}.conf"
53 |
54 | echo "🎉 {{ app_name }} Setup Completed Successfully!"
55 |
--------------------------------------------------------------------------------
/docs/examples/handlers/zohohirs.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'ZohoHIRS Handler'
3 | icon: 'users'
4 | ---
5 |
6 | Zoho People (Zoho HIRS) is a cloud-based Human Resource Information System that helps organizations manage employees, onboarding, offboarding, and role changes. Using the Zoho People API, you can programmatically access employee records, workflows, and other HR-related data.
7 |
8 | ## Example
9 |
10 | To create the `ZohoHIRSHandler` object, initialize it with your Zoho **access token**.
11 | The handler provides methods for fetching employee records and HR workflows.
12 |
13 | ```python
14 | import os
15 | from superagentx_handlers.zoho.hirs import ZohoHIRSHandler
16 |
17 | zoho_handler = ZohoHIRSHandler(
18 | access_token=os.getenv("ZOHO_PEOPLE_ACCESS_TOKEN")
19 | )
20 | ```
21 |
22 | **List Employees:**
23 | Retrieves the list of all employees in the Zoho People organization.
24 | ```python
25 | employees = await zoho_handler.list_employees()
26 | for emp in employees:
27 | print(emp["Name"], emp["Email"])
28 | ```
29 |
30 | **List Onboarding Workflows:**
31 | Fetches onboarding workflows configured in Zoho People.
32 | ```python
33 | onboarding_flows = await zoho_handler.list_onboarding_workflows()
34 | print(onboarding_flows)
35 | ```
36 |
37 | **List Offboarding Workflows:**
38 | Fetches offboarding workflows configured in Zoho People.
39 | ```python
40 | offboarding_flows = await zoho_handler.list_offboarding_workflows()
41 | print(offboarding_flows)
42 | ```
43 |
44 | **List Role Change Workflows:**
45 | Retrieves role change (transfer) workflows configured in Zoho People.
46 | ```python
47 | role_change_flows = await zoho_handler.list_role_change_workflows()
48 | print(role_change_flows)
49 | ```
--------------------------------------------------------------------------------
/tests/browser/sensitive_data.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import logging
3 | import warnings
4 |
5 | from rich import print as rprint
6 |
7 | from superagentx.agent import Agent
8 | from superagentx.browser_engine import BrowserEngine
9 | from superagentx.llm import LLMClient
10 | from superagentx.prompt import PromptTemplate
11 |
12 | warnings.filterwarnings('ignore')
13 |
14 | sh = logging.StreamHandler()
15 | logging.basicConfig(
16 | level="INFO",
17 | format='%(asctime)s -%(levelname)s - %(name)s - %(funcName)s: %(message)s',
18 | datefmt='%Y-%m-%d %H:%M:%S',
19 | handlers=[sh]
20 | )
21 |
22 |
23 | async def main():
24 | llm_config = {'model': 'gpt-4o', 'llm_type': 'openai', 'async_mode': True}
25 |
26 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
27 |
28 | prompt_template = PromptTemplate()
29 | sensitive_data = {'x_name': '', 'x_password': ''}
30 |
31 | browser_engine = BrowserEngine(
32 | llm=llm_client,
33 | prompt_template=prompt_template,
34 | sensitive_data=sensitive_data
35 | )
36 | task = 'go to gmail and login with x_name and x_password'
37 |
38 | cricket_analyse_agent = Agent(
39 | goal="Complete user's task.",
40 | role="You are a Gmail Expert",
41 | llm=llm_client,
42 | prompt_template=prompt_template,
43 | max_retry=1,
44 | engines=[browser_engine]
45 | )
46 |
47 | result = await cricket_analyse_agent.execute(
48 | query_instruction=task
49 | )
50 | rprint(result)
51 |
52 |
53 | if __name__ == '__main__':
54 | try:
55 | asyncio.run(main())
56 | except (KeyboardInterrupt, asyncio.CancelledError):
57 | rprint("\nUser canceled the [bold yellow][i]pipe[/i]!")
--------------------------------------------------------------------------------
/docs/examples-reference/introduction.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Introduction'
3 | ---
4 | A set of examples that demonstrate how to use the SuperAgentX framework to automate your workflows.
5 |
6 |
7 |
13 | Ecommerce is the buying and selling of goods or services over the internet.
14 |
15 |
20 | Retrieving real-time or forecasted weather information from external sources.
21 |
22 |
23 |
28 | Find nearby cafes with detailed information about amenities, opening hours, and features.
29 |
30 |
31 |
36 | To automate trip planning when you're deciding between multiple options.
37 |
38 |
39 |
44 | This user-friendly smart app helps outpatients identify the best-specialized doctor and book an appointment with the doctor simultaneously.
45 |
46 |
47 |
--------------------------------------------------------------------------------
/docs/examples/handlers/extract/ai.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'AI Handler'
3 | icon: 'brain'
4 | ---
5 |
6 | The **ExtractAIHandler** is a utility for document AI extraction.
7 | It integrates with an AI-powered backend to process files (e.g., invoices, PDFs, receipts) and extract structured JSON data.
8 | It supports Base64 file encoding, asynchronous extraction requests, job polling, and retrieval of processed results.
9 |
10 | This handler is useful for **invoice extraction, document digitization, and structured data retrieval** from files.
11 |
12 |
13 |
14 | ## Example
15 |
16 | To create the `ExtractAIHandler` object with your Extract API credentials:
17 |
18 | ```python
19 | import os
20 | from superagentx.handler.ai.extract import ExtractAIHandler
21 |
22 | extract_handler = ExtractAIHandler(
23 | prompt_name="invoice_extraction",
24 | api_token=os.getenv("EXTRACT_API_TOKEN"),
25 | base_url=os.getenv("BASE_URL"),
26 | project_id="test_project_123"
27 | )
28 | ```
29 |
30 | **Get File Base64 Data:**
31 | Reads a file from the given path and returns its Base64-encoded content.
32 | ```python
33 | file_data = await extract_handler.get_file_base64_data("invoice.pdf")
34 | print(file_data[:100]) # preview first 100 chars
35 | ```
36 |
37 | **Extract API:**
38 | Initiates a file extraction request and polls until results are available.
39 | ```python
40 | result = await extract_handler.extract_api(
41 | file_path="invoice.pdf",
42 | file_data=file_data,
43 | poll_interval=5,
44 | retry=10
45 | )
46 | print(result)
47 | ```
48 |
49 | **Get Invoice JSON Data:**
50 | Fetches the extracted JSON data using the reference ID of a completed job.
51 | ```python
52 | invoice_data = await extract_handler.get_invoice_json_data("ref12345")
53 | print(invoice_data)
54 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/serverless.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Serverless Handler'
3 | icon: 'lambda'
4 | ---
5 |
6 | AWS Lambda is a **serverless compute service** that lets you run code without provisioning or managing servers. You just upload your code (as a ZIP package or container image), and Lambda automatically scales and runs it in response to events such as API Gateway requests, S3 object uploads, DynamoDB streams, or scheduled CloudWatch events.
7 |
8 | Lambda integrates seamlessly with **VPC, IAM, Security Groups, and other AWS services**, making it a core component of modern serverless applications.
9 |
10 |
11 |
12 | ## Example
13 |
14 | To create the AWSLambdaHandler with AWS credentials:
15 |
16 | ```python
17 | import os
18 | from superagentx_handlers.aws.serverless import AWSLambdaHandler
19 |
20 | lambda_handler = AWSLambdaHandler(
21 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
22 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
23 | region_name="eu-central-1"
24 | )
25 | ```
26 |
27 | **List Lambda Functions:**
28 | Retrieves all Lambda functions in the account, including runtime, handler, role, security groups, IAM policies, and environment configurations.
29 | ```python
30 | functions = await lambda_handler.get_lambda_functions()
31 | print(functions)
32 | ```
33 |
34 | **Get IAM Role Policies for a Lambda Role:**
35 | Fetches all attached and inline IAM policies for the IAM role associated with a Lambda.
36 | ```python
37 | policies = await lambda_handler.get_role_policies("MyLambdaRole")
38 | print(policies)
39 | ```
40 |
41 | **Get Security Group Details:**
42 | Fetches inbound/outbound rules for security groups attached to a Lambda function’s VPC.
43 | ```python
44 | sg_details = await lambda_handler.get_security_group_details(["sg-12345678"])
45 | print(sg_details)
46 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/cloudwatch.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'CloudWatch Handler'
3 | icon: 'chart-bar'
4 | ---
5 |
6 | Amazon CloudWatch is a monitoring and observability service that provides data and actionable insights for AWS, hybrid,
7 | and on-premises applications and infrastructure resources. It allows you to collect metrics, logs, and events, helping
8 | you monitor system health, detect anomalies, and keep applications running smoothly.
9 |
10 | ## Example
11 | To create the AWSCloudWatchHandler object with AWS credentials.
12 | The AWSCloudWatchHandler connects to Amazon CloudWatch using access credentials
13 | (access key, secret key) and specifies a region. It enables seamless interaction
14 | with CloudWatch for tasks like fetching metrics and monitoring resources.
15 |
16 | ```python cloudwatch_handler_test.py
17 | import os
18 | from superagentx_handlers.aws.cloudwatch import AWSCloudWatchHandler
19 |
20 | cloudwatch_handler = AWSCloudWatchHandler(
21 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
22 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
23 | region_name="us-east-1"
24 | )
25 | ```
26 | **Get Metric Data:**
27 | The get_metric_data method retrieves metrics for a specific namespace, metric, and dimensions within a given time range.
28 | from datetime import datetime, timedelta
29 | ```python
30 | end_time = datetime.utcnow()
31 | start_time = end_time - timedelta(hours=1)
32 |
33 | response = await cloudwatch_handler.get_metric_data(
34 | namespace="AWS/EC2",
35 | metric_name="CPUUtilization",
36 | start_time=start_time,
37 | end_time=end_time,
38 | period=300, # granularity in seconds
39 | statistics=["Average"], # can also use Sum, Minimum, Maximum, etc.
40 | dimensions=[{"Name": "InstanceId", "Value": "i-1234567890abcdef0"}]
41 | )
42 | print(response)
43 | ```
--------------------------------------------------------------------------------
/tests/agent/test_serper_agent.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import pytest
4 |
5 | from superagentx.agent import Agent
6 | from superagentx.engine import Engine
7 | from superagentx.handler.serper_dev import SerperDevToolHandler
8 | from superagentx.llm import LLMClient
9 | from superagentx.prompt import PromptTemplate
10 |
11 | logger = logging.getLogger(__name__)
12 |
13 | '''
14 | Run Pytest:
15 |
16 | 1. pytest --log-cli-level=DEBUG tests/agent/test_serper_agent.py::TestSerperDevAgent::test_search_agent
17 | '''
18 |
19 |
20 | @pytest.fixture
21 | def agent_client_init() -> dict:
22 | llm_config = {'model': 'gpt-4-turbo-2024-04-09', 'llm_type': 'openai'}
23 |
24 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
25 | response = {'llm': llm_client, 'llm_type': 'openai'}
26 | return response
27 |
28 |
29 | class TestSerperDevAgent:
30 |
31 | @pytest.mark.asyncio
32 | async def test_search_agent(self, agent_client_init: dict):
33 | llm_client: LLMClient = agent_client_init.get('llm')
34 | serper_dev_handler = SerperDevToolHandler()
35 |
36 | prompt_template = PromptTemplate()
37 | serper_search_engine = Engine(
38 | handler=serper_dev_handler,
39 | llm=llm_client,
40 | prompt_template=prompt_template
41 | )
42 |
43 | goal = """
44 | List five AI companies started 2024."""
45 | search_agent = Agent(
46 | goal=goal,
47 | role="You are the analyst",
48 | llm=llm_client,
49 | prompt_template=prompt_template
50 | )
51 |
52 | await search_agent.add(
53 | serper_search_engine
54 | )
55 |
56 | result = await search_agent.execute(query_instruction='')
57 | logger.info(f'Result ==> {result}')
58 | assert result
59 |
--------------------------------------------------------------------------------
/superagentx_cli/templates/restpipe.py.jinja2:
--------------------------------------------------------------------------------
1 | {# templates/restpipe.py.jinja2 #}
2 | from contextlib import asynccontextmanager
3 |
4 | from fastapi import Depends, FastAPI, HTTPException # https://fastapi.tiangolo.com/
5 | from fastapi.security import APIKeyHeader
6 | from superagentx.agentxpipe import AgentXPipe
7 | from superagentx.result import GoalResult
8 |
9 | from {{ package_name }}.config import AUTH_TOKEN
10 | from {{ package_name }}.pipe import get_{{ pipe_name }}_pipe
11 |
12 | pipes = {}
13 |
14 |
15 | @asynccontextmanager
16 | async def lifespan(app: FastAPI):
17 | pipes['{{ pipe_name }}_pipe'] = await get_{{ pipe_name }}_pipe()
18 | yield
19 | pipes.clear()
20 |
21 |
22 | {{ package_name }}_app = FastAPI(
23 | title='{{ app_name }} Search',
24 | lifespan=lifespan,
25 | docs_url='/app/rest/docs',
26 | openapi_url='/app/rest/openapi.json'
27 | )
28 |
29 |
30 | async def verify_api_token(
31 | api_token: str = Depends(APIKeyHeader(name='api-token', auto_error=False))
32 | ):
33 | if api_token != AUTH_TOKEN:
34 | raise HTTPException(status_code=401, detail='Invalid API Token!')
35 |
36 |
37 | @{{ package_name }}_app.get('/app/rest/health')
38 | async def index():
39 | return {"name": '{{ app_name }} Search SuperagentX App'}
40 |
41 |
42 | @{{ package_name }}_app.get('/app/rest/search', dependencies=[Depends(verify_api_token)])
43 | async def search(query: str) -> list[GoalResult]:
44 | {{ pipe_name }}_pipe: AgentXPipe = pipes.get('{{ pipe_name }}_pipe')
45 | return await {{ pipe_name }}_pipe.flow(query_instruction=query)
46 |
47 |
48 | """
49 | # To Run this, `pip install 'fastapi[standard]'`
50 |
51 | # Development Mode
52 | fastapi dev {{ app_name }}/{{ package_name }}/rest_pipe.py
53 |
54 | # Server Mode
55 | fastapi run {{ app_name }}/{{ package_name }}/rest_pipe.py
56 | """{{'\n'}}
--------------------------------------------------------------------------------
/docs/examples/handlers/Gcp/gmail.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Gmail Handler'
3 | icon: 'inbox'
4 | ---
5 |
6 | The Gmail Handler enables seamless interaction with the Gmail API for sending, reading, and managing emails. It handles authentication using OAuth 2.0, and provides methods to fetch user profiles, read emails with attachments, send new emails, and create drafts. It is designed to integrate Gmail into automation workflows securely and efficiently.
7 |
8 | ## Example
9 |
10 | To create the GmailHandler, initialize it with credentials JSON for OAuth:
11 |
12 | ```python
13 | from superagentx_handlers.gcp.gmail import GmailHandler
14 |
15 | gmail_handler = GmailHandler(
16 | credentials="credentials.json" # path to your OAuth 2.0 credentials file
17 | )
18 | ```
19 |
20 | **Get User Profile:**
21 | Retrieve Gmail profile information for the authenticated user.
22 | ```python
23 | profile = await gmail_handler.get_user_profile()
24 | print(profile)
25 | ```
26 |
27 | **Read Emails:**
28 | Fetches the latest emails, including sender, receiver, subject, body, and attachments.
29 | ```python
30 | emails = await gmail_handler.read_mail(max_results=10)
31 | for mail in emails:
32 | print(mail["subject"], mail["sender"])
33 | ```
34 |
35 | **Send Email:**
36 | Send an email via Gmail.
37 | ```python
38 | await gmail_handler.send_email(
39 | from_address="you@example.com",
40 | to="friend@example.com",
41 | subject="Hello from GmailHandler",
42 | content="This is a test email!"
43 | )
44 | ```
45 |
46 | **Create Draft Email:**
47 | Create a draft email that can be sent later.
48 | ```python
49 | draft = await gmail_handler.create_draft_email(
50 | from_address="you@example.com",
51 | to="friend@example.com",
52 | subject="Draft subject",
53 | content="This is a saved draft message."
54 | )
55 | print(draft)
56 | ```
57 |
--------------------------------------------------------------------------------
/tests/handlers/test_mcp_handler.py:
--------------------------------------------------------------------------------
1 | import inspect
2 | import logging
3 |
4 | import pytest
5 | from pydantic import typing
6 |
7 | from superagentx.handler.mcp import MCPHandler
8 |
9 | logger = logging.getLogger(__name__)
10 |
11 | '''
12 | Run Pytest:
13 |
14 | 1. pytest --log-cli-level=INFO tests/handlers/test_mcp_handler.py::TestMCPHandler::test_get_mcp_tools
15 |
16 | '''
17 |
18 |
19 | @pytest.fixture
20 | def mcp_handler_init() -> MCPHandler:
21 | mcp_handler = MCPHandler(command="npx",
22 | mcp_args=["-y", "@modelcontextprotocol/server-memory"])
23 |
24 | # mcp_handler = MCPHandler(sse_url="http://0.0.0.0:8080/sse")
25 |
26 | logger.info(mcp_handler)
27 | return mcp_handler
28 |
29 |
30 | class TestMCPHandler:
31 |
32 | @pytest.mark.asyncio
33 | async def test_get_mcp_tools(self, mcp_handler_init: MCPHandler):
34 | tools = await mcp_handler_init.get_mcp_tools()
35 | logger.info(f"MCP Tools {tools}")
36 |
37 | @pytest.mark.asyncio
38 | async def test_load_and_run_if_mcp(self, mcp_handler_init: MCPHandler):
39 | """
40 | Dynamically loads and runs `get_mcp_tools()` if handler has __type__ = "MCP".
41 | """
42 | if getattr(mcp_handler_init, "__type__", None) == "MCP":
43 | func = getattr(mcp_handler_init, "get_mcp_tools", None)
44 | if callable(func):
45 | tools = await func()
46 | logger.info(f"Dynamic MCP Tools Loader .. {tools}")
47 |
48 | if isinstance(func, typing.Callable):
49 | _func_name = func.__name__
50 | _doc_str = inspect.getdoc(func)
51 | _properties = {}
52 | _type_hints = typing.get_type_hints(func)
53 | logger.info(f"Function Name - {list(_type_hints)}")
54 |
--------------------------------------------------------------------------------
/tests/agent/task/weather.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import pytest
4 | import json
5 | from superagentx.agent import Agent
6 |
7 | from superagentx.handler.task.general.api_handler import APIHandler
8 | from superagentx.llm import LLMClient
9 | from superagentx.task_engine import TaskEngine
10 |
11 | logger = logging.getLogger(__name__)
12 |
13 | '''
14 | Run Pytest:
15 |
16 | 1. pytest --log-cli-level=DEBUG tests/agent/task/weather.py::TestWeatherTaskAgent::test_weather_agent
17 | '''
18 |
19 |
20 | @pytest.fixture
21 | def agent_client_init() -> dict:
22 | llm_config = {'model': 'gpt-4-turbo-2024-04-09', 'llm_type': 'openai'}
23 |
24 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
25 | response = {'llm': llm_client, 'llm_type': 'openai'}
26 | return response
27 |
28 |
29 | class TestWeatherTaskAgent:
30 |
31 | @pytest.mark.asyncio
32 | async def test_weather_agent(self, agent_client_init: dict):
33 |
34 | engine = TaskEngine(
35 | handler=APIHandler(),
36 | instructions=[
37 |
38 | # PARALLEL (weather OK, stock FAILS, news OK)
39 | [
40 | {"fetch_weather": {"city": "San Francisco"}},
41 | {"fetch_news": {"topic": "AI"}}
42 | ],
43 |
44 | # Combine using $prev.
45 | {
46 | "combine_successful": {
47 | "weather": "$prev.fetch_weather",
48 | "stock": "$prev.fetch_stock", # will be None
49 | "news": "$prev.fetch_news"
50 | }
51 | }
52 | ]
53 | )
54 |
55 | weather_agent = Agent(engines=[engine])
56 |
57 | result = await weather_agent.execute(query_instruction='')
58 | logger.info(f'Result ==> {result}')
59 | assert result
60 |
--------------------------------------------------------------------------------
/docs/memory.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Memory'
3 | icon: "memory"
4 | ---
5 |
6 | The `Memory` class from `superagentx.memory` is designed to provide a persistent storage mechanism for storing and retrieving context,
7 | data, and state during interactions with agents in a pipeline. `Memory` allows the system to “remember” information
8 | across agent actions and queries, which is particularly useful for complex workflows or tasks that span multiple steps.
9 |
10 | The `Memory` class is initialized with a configuration that defines how it interacts with the agent pipeline.
11 | It can be used to persist important data, store intermediate results, or maintain context across different
12 | stages of the agent’s execution.
13 |
14 | ### Memory config Parameters
15 | | Attribute | Parameters | Description |
16 | | :-------------------- | :---------------- | :------------------------------------- |
17 | | **LLM Client** | `llm_client` | Configuration for the LLM. |
18 | | **Vector Store** _(optional)_ | `vector_store` | Configuration for the vector store. Default is `Chroma db`. |
19 | | **DB Path** _(optional)_ | `db_path` | Path to the history database. Default `Sqlite memory`. |
20 |
21 |
22 | ### Parameters
23 | | Attribute | Parameters | Description |
24 | | :-------------------- | :---------------- | :------------------------------------- |
25 | | **Memory Config** | `memory_config` | Memory configuration |
26 |
27 |
28 | ```python
29 | from superagentx.memory import Memory
30 |
31 | memory = Memory(memory_config={"llm_client": llm_client})
32 | ```
--------------------------------------------------------------------------------
/superagentx/computer_use/browser/dom/history_tree_processor/view.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 |
3 |
4 | class HashedDomElement(BaseModel):
5 | """
6 | Hash of the dom element to be used as a unique identifier
7 | """
8 |
9 | branch_path_hash: str
10 | attributes_hash: str
11 | xpath_hash: str
12 | # text_hash: str
13 |
14 |
15 | class Coordinates(BaseModel):
16 | x: int
17 | y: int
18 |
19 |
20 | class CoordinateSet(BaseModel):
21 | top_left: Coordinates
22 | top_right: Coordinates
23 | bottom_left: Coordinates
24 | bottom_right: Coordinates
25 | center: Coordinates
26 | width: int
27 | height: int
28 |
29 |
30 | class ViewportInfo(BaseModel):
31 | scroll_x: int
32 | scroll_y: int
33 | width: int
34 | height: int
35 |
36 |
37 | class DOMHistoryElement:
38 | tag_name: str
39 | xpath: str
40 | highlight_index: int | None
41 | entire_parent_branch_path: list[str]
42 | attributes: dict[str, str]
43 | shadow_root: bool = False
44 | css_selector: str | None = None
45 | page_coordinates: CoordinateSet | None = None
46 | viewport_coordinates: CoordinateSet | None = None
47 | viewport_info: ViewportInfo | None = None
48 |
49 | def to_dict(self) -> dict:
50 | page_coordinates = self.page_coordinates.model_dump() if self.page_coordinates else None
51 | viewport_coordinates = self.viewport_coordinates.model_dump() if self.viewport_coordinates else None
52 | viewport_info = self.viewport_info.model_dump() if self.viewport_info else None
53 |
54 | return {
55 | 'tag_name': self.tag_name,
56 | 'xpath': self.xpath,
57 | 'highlight_index': self.highlight_index,
58 | 'entire_parent_branch_path': self.entire_parent_branch_path,
59 | 'attributes': self.attributes,
60 | 'shadow_root': self.shadow_root,
61 | 'css_selector': self.css_selector,
62 | 'page_coordinates': page_coordinates,
63 | 'viewport_coordinates': viewport_coordinates,
64 | 'viewport_info': viewport_info,
65 | }
--------------------------------------------------------------------------------
/docs/examples/handlers/atlassian/jira.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Jira Handler'
3 | icon: 'jira'
4 | ---
5 |
6 | The JiraHandler class is a tool that helps developers easily connect to Jira and perform common
7 | operations like creating, updating, and managing issues or projects. If you’ve ever used Jira
8 | for tracking bugs, managing tasks, or following project progress, this class makes it simpler
9 | to automate those activities using Python.
10 |
11 | ## Jira Handler Code
12 | The JiraHandler connects to Jira using an email, API token, and organization details. This setup allows the program to
13 | interact with Jira, making it easy to manage tasks, projects, and issues programmatically.
14 |
15 | To set up Confluence with email, token, and organization access, you can follow these steps in the given link.
16 | >Set up Email, Token and Organisation as an environmental variable and run the following code.
17 |
18 | ```python
19 | export ATLASSIAN_EMAIL = "**********"
20 | export ATLASSIAN_TOKEN = "*************"
21 | export ATLASSIAN_ORGANIZATION = "***************"
22 | ```
23 |
24 | ```python jira_handler.py
25 | import os
26 | import asyncio
27 |
28 | from superagentx_handlers.atlassian.jira import JiraHandler
29 |
30 |
31 | async def get_active_sprint():
32 | jira_handler = JiraHandler(
33 | email="",
34 | token="",
35 | organization=""
36 | )
37 | return await jira_handler.get_active_sprint(
38 | board_id=1,
39 | start=0,
40 | end=50
41 | )
42 |
43 |
44 | async def main():
45 | res = await get_active_sprint()
46 | print(res)
47 |
48 | if __name__ == '__main__':
49 | asyncio.run(main())
50 | ```
51 |
52 | ## Result
53 |
54 | ```python jira
55 | []
56 | ```
57 |
--------------------------------------------------------------------------------
/superagentx_cli/main.py:
--------------------------------------------------------------------------------
1 |
2 | import typer
3 | from rich import print as rprint
4 |
5 | from superagentx_cli.cli import EMAIL_COMP, PKG_NAME_COMP, CliAppTypeEnum, CliApp
6 |
7 | app = typer.Typer(name='Superagentx-Cli')
8 |
9 |
10 | def validate_email(email: str) -> str:
11 | if email and not bool(EMAIL_COMP.match(email)):
12 | raise typer.BadParameter('Invalid email!')
13 | return email
14 |
15 |
16 | def validate_project_name(name: str) -> str:
17 | if name and not bool(PKG_NAME_COMP.match(name)):
18 | raise typer.BadParameter('Starts with alphabets along with numbers, `-` and `_`')
19 | return name
20 |
21 |
22 | @app.command(name='help')
23 | def cli_help():
24 | rprint(f"Superagentx cli to create project structures based on the options.")
25 |
26 |
27 | @app.command(name='create')
28 | def create(
29 | name: str = typer.Option(
30 | prompt='Enter application name',
31 | help='Name of the application. '
32 | 'It helps to create application dir and pacakge in the given name. '
33 | 'Starts with alphabets along with numbers, `-` and `_`',
34 | rich_help_panel='Application Name',
35 | callback=validate_project_name
36 | ),
37 | pipe_name: str = typer.Option(
38 | default='',
39 | prompt='Enter pipe name. Default is application name',
40 | rich_help_panel='Pipe Name',
41 | callback=validate_project_name
42 | ),
43 | app_type: CliAppTypeEnum = typer.Option(
44 | default=CliAppTypeEnum.all.value,
45 | prompt='Enter one of the option',
46 | rich_help_panel='App Types'
47 | )
48 | ):
49 | cli_app = CliApp(
50 | name=name,
51 | pipe_name=pipe_name or name,
52 | app_type=app_type.value
53 | )
54 | cli_app.create_project()
55 |
56 |
57 | if __name__ == '__main__':
58 | app()
59 |
--------------------------------------------------------------------------------
/superagentx/llm/client.py:
--------------------------------------------------------------------------------
1 | from abc import ABCMeta, abstractmethod
2 |
3 |
4 | from typing import Callable
5 |
6 |
7 | class Client(metaclass=ABCMeta):
8 |
9 | def __init__(
10 | self,
11 | model: str | None = None,
12 | embed_model: str | None = None,
13 | **kwargs
14 | ):
15 | self._model = model
16 | self._embed_model = embed_model
17 |
18 | @abstractmethod
19 | def chat_completion(
20 | self,
21 | *args,
22 | **kwargs
23 | ):
24 | raise NotImplementedError
25 |
26 | @abstractmethod
27 | async def achat_completion(
28 | self,
29 | *args,
30 | **kwargs
31 | ):
32 | raise NotImplementedError
33 |
34 | @abstractmethod
35 | async def get_tool_json(
36 | self,
37 | func: Callable
38 | ) -> dict:
39 | raise NotImplementedError
40 |
41 | @abstractmethod
42 | def embed(
43 | self,
44 | text: str,
45 | **kwargs
46 | ):
47 | """
48 | Get the embedding for the given text using Client.
49 |
50 | Args:
51 | text (str): The text to embed.
52 |
53 | Returns:
54 | list: The embedding vector.
55 | """
56 | raise NotImplementedError
57 |
58 | @abstractmethod
59 | async def aembed(
60 | self,
61 | text: str,
62 | **kwargs
63 | ):
64 | """
65 | Get the embedding for the given text using Client.
66 |
67 | Args:
68 | text (str): The text to embed.
69 |
70 | Returns:
71 | list: The embedding vector.
72 | """
73 | raise NotImplementedError
74 |
75 | def count_tokens(self, **kwargs):
76 | raise NotImplementedError
77 |
78 | async def account_tokens(self, **kwargs):
79 | raise NotImplementedError
80 |
--------------------------------------------------------------------------------
/docs/examples/handlers/Google/calender.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Calender Handler'
3 | icon: 'calendar-days'
4 | ---
5 |
6 | The Google Calendar Handler is a utility designed to simplify interactions with the Google Calendar API.
7 | This handler enables users to authenticate, access, and manage their calendar events efficiently.
8 | It provides methods for retrieving events for specific time frames, such as today, the upcoming week,
9 | or the next month, as well as filtering events based on specific types.
10 |
11 | ## Example
12 | A CalendarHandler for Google Calendar using provided credentials. This setup enables the application to manage calendar
13 | events, schedule meetings, and interact with Google Calendar services programmatically.
14 |
15 | To setup and get a credentials refer here.
16 |
17 | After creating and enabling the Google Cloud API, you need to provide the path to the credentials in the _credentials_ parameters.
18 |
19 | ``` python calender_handler.py
20 | import asyncio
21 |
22 | from superagentx_handlers.google.calender import CalenderHandler
23 |
24 |
25 | async def get_today_events():
26 | calender_handler = CalenderHandler(
27 | credentials=""
28 | )
29 | return await calender_handler.get_today_events()
30 |
31 |
32 | async def main():
33 | res = await get_today_events()
34 | print(res)
35 |
36 | if __name__ == '__main__':
37 | asyncio.run(main())
38 | ```
39 |
40 | ## Result
41 | ```inline Calender Today Event
42 | {
43 | "kind": "calendar#events",
44 | "etag": "\"p32oftunmn22oe0o\"",
45 | "summary": "sam1234@gmail.com",
46 | "description": "",
47 | "updated": "2024-07-01T08:41:06.398Z",
48 | "timeZone": "America/Los_Angeles",
49 | "accessRole": "owner",
50 | "defaultReminders": [
51 | {
52 | "method": "popup",
53 | "minutes": 10
54 | }
55 | ],
56 | "items": []
57 | }
58 | ```
59 |
--------------------------------------------------------------------------------
/docs/examples/handlers/Gcp/calendar.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Calendar Handler'
3 | icon: 'calendar'
4 | ---
5 |
6 | Google Calendar is a scheduling and time-management service that allows users to create, manage, and share events. It provides features like reminders, recurring events, and integration with other Google Workspace services. With the `CalenderHandler`, you can connect to Google Calendar via OAuth 2.0 and programmatically fetch events for a day, week, month, or specific type.
7 |
8 | ## Example
9 |
10 | To create the `CalenderHandler` object, initialize it with your Google OAuth credentials file. The handler manages authentication and provides methods to retrieve events from Google Calendar.
11 |
12 | ```python
13 | import os
14 | from superagentx_handlers.gcp.calendar import CalenderHandler
15 |
16 | calendar_handler = CalenderHandler(
17 | credentials="credentials.json" # Path to Google OAuth client secrets file
18 | )
19 | ```
20 |
21 | **Get Today’s Events:**
22 | Retrieves all events scheduled for today.
23 | ```python
24 | events_today = await calendar_handler.get_today_events()
25 | print(events_today)
26 | ```
27 |
28 | **Get Week Events:**
29 | Retrieves all events scheduled for the next 7 days.
30 | ```python
31 | events_week = await calendar_handler.get_week_events()
32 | print(events_week)
33 | ```
34 |
35 | **Get Month Events:**
36 | Retrieves all events scheduled for the next 30 days.
37 | ```python
38 | events_month = await calendar_handler.get_month_events()
39 | print(events_month)
40 | ```
41 |
42 | **Get Events by Custom Days:**
43 | Fetches events for a custom range between 1 and 30 days.
44 | ```python
45 | events_5days = await calendar_handler.get_events_by_days(days=5)
46 | print(events_5days)
47 | ```
48 |
49 | **Get Events by Type:**
50 | Fetches events of a specific type such as "birthday", "focusTime", or "workingLocation".
51 | ```python
52 | birthday_events = await calendar_handler.get_events_by_type(event_type="birthday")
53 | print(birthday_events)
54 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/ecs.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'ECS Handler'
3 | icon: 'container-storage'
4 | ---
5 |
6 | Amazon ECS (Elastic Container Service) is a fully managed container orchestration service.
7 | It allows you to run Docker containers at scale, with integration to EC2 and Fargate.
8 | The ECS Handler helps fetch **clusters, services, tasks, and container instances**.
9 |
10 |
11 | ## Example
12 |
13 | To create the **ECS Handler**, pass AWS credentials (`access_key`, `secret_key`, and `region`).
14 |
15 | ```python
16 | import os
17 | from superagentx_handlers.aws.ecs import AWSECSHandler
18 |
19 | ecs_handler = AWSECSHandler(
20 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
21 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
22 | region_name="eu-central-1"
23 | )
24 | ```
25 | **List Clusters:**
26 | Fetches all ECS clusters.
27 | ```python
28 | clusters = await ecs_handler.list_clusters()
29 | print(clusters)
30 | ```
31 |
32 | **List Services:**
33 | Lists ECS services running inside a cluster.
34 | ```python
35 | services = await ecs_handler.list_services(cluster="my-cluster")
36 | print(services)
37 | ```
38 | **List Tasks:**
39 | Lists running tasks inside a service.
40 | ```python
41 | tasks = await ecs_handler.list_tasks(cluster="my-cluster")
42 | print(tasks)
43 | ```
44 |
45 | **Describe Cluster:**
46 | Fetches detailed information about a cluster.
47 | ```python
48 | cluster_info = await ecs_handler.describe_cluster(cluster="my-cluster")
49 | print(cluster_info)
50 | ```
51 | **Describe Service:**
52 | Fetches detailed info of a service inside a cluster.
53 | ```python
54 | service_info = await ecs_handler.describe_service(
55 | cluster="my-cluster",
56 | service="my-service"
57 | )
58 | print(service_info)
59 | ```
60 |
61 | **Describe Task:**
62 | Fetches details about a specific task.
63 | ```python
64 | task_info = await ecs_handler.describe_task(
65 | cluster="my-cluster",
66 | task="0123456789abcdef0"
67 | )
68 | print(task_info)
69 | ```
70 |
--------------------------------------------------------------------------------
/docs/examples/handlers/email.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'E-mail Handler'
3 | icon: 'envelope-open-text'
4 | ---
5 |
6 | The EmailHandler is a simple and effective tool for managing email communication in your applications.
7 | It allows you to send emails easily, handle multiple recipients, and include attachments, making it
8 | perfect for both personal and professional use.
9 |
10 | >**From:** The email address of the sender.
11 | **To:** The primary recipient(s) of the email.
12 | **Cc:** Additional recipients who will receive a copy of the email, visible to all.
13 | **Bcc:** Recipients who receive a copy of the email without other recipients knowing their addresses.
14 | **Subject:** A brief summary or title of the email's content.
15 | **Body:** The main content or message of the email, where the sender communicates their thoughts or information.
16 |
17 | ### Setup
18 | Install Postfix locally by running it on your machine. For more detail refer here.
19 | >**Note:** Postfix can run on UNIX-like systems including AIX, BSD, HP-UX, Linux, MacOS X, Solaris, and more.
20 |
21 | ## Example
22 | This code initializes an EmailHandler to connect to an email server using the specified host and port number.
23 | This setup enables sending, receiving, or managing emails programmatically.
24 | ```python email_handler.py
25 | import asyncio
26 |
27 | from superagentx.handler.send_email import EmailHandler
28 |
29 |
30 | async def send_email():
31 | email_handler = EmailHandler(
32 | host="mail.example.com",
33 | port=0
34 | )
35 | body = {
36 | "sender": "sample123@abcd.io",
37 | "to": ["test231@abcdf.io"],
38 | "subject": "test",
39 | "body": "Hi"
40 | }
41 | return await email_handler.send_email(**body)
42 |
43 |
44 | async def main():
45 | res = await send_email()
46 | print(res)
47 |
48 | if __name__ == '__main__':
49 | asyncio.run(main())
50 | ```
51 |
--------------------------------------------------------------------------------
/tests/browser/test_gdocs.py:
--------------------------------------------------------------------------------
1 | import warnings
2 | with warnings.catch_warnings():
3 | warnings.simplefilter("ignore", category=UserWarning)
4 |
5 | import logging
6 | import pytest
7 | from superagentx.agent import Agent
8 | from superagentx.browser_engine import BrowserEngine
9 | from superagentx.llm import LLMClient
10 | from superagentx.prompt import PromptTemplate
11 |
12 | logger = logging.getLogger(__name__)
13 |
14 | '''
15 | Run Pytest:
16 |
17 | 1. pytest -s --log-cli-level=INFO tests/agent/test_gdocs.py::TestDocWriterAgent::test_generation_agent
18 | '''
19 |
20 |
21 | @pytest.fixture
22 | def agent_client_init() -> dict:
23 | llm_config = {'model': 'gpt-4o', 'llm_type': 'openai'}
24 |
25 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
26 | response = {'llm': llm_client, 'llm_type': 'openai'}
27 | return response
28 |
29 |
30 | class TestDocWriterAgent:
31 |
32 | @pytest.mark.filterwarnings("ignore::UserWarning")
33 | async def test_generation_agent(self, agent_client_init: dict):
34 | llm_client: LLMClient = agent_client_init.get('llm')
35 |
36 | prompt_template = PromptTemplate()
37 |
38 | browser_engine = BrowserEngine(
39 | llm=llm_client,
40 | prompt_template=prompt_template,
41 | # browser_instance_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
42 | )
43 |
44 | goal = """Complete the user's input."""
45 |
46 | marketing_agent = Agent(
47 | goal=goal,
48 | role="You are the AI Assistant",
49 | llm=llm_client,
50 | prompt_template=prompt_template,
51 | max_retry=1,
52 | engines=[browser_engine]
53 | )
54 |
55 | task = 'In docs.google.com write about SuperAgentX'
56 |
57 | query_instruction = task
58 |
59 | result = await marketing_agent.execute(
60 | query_instruction=query_instruction
61 | )
62 | logger.info(f'Result ==> {result}')
63 | assert result
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/elb.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'ELB Handler'
3 | icon: 'server'
4 | ---
5 |
6 | Amazon Elastic Load Balancing (ELBv2) automatically distributes incoming application traffic across multiple targets, such as Amazon EC2 instances, containers, and IP addresses.
7 | It provides high availability, automatic scaling, and robust security features, and supports multiple load balancer types (Application, Network, and Gateway).
8 | This handler focuses on **Application Load Balancers (ALBs)** and retrieves details about load balancers, listeners, listener rules, target groups, and target health.
9 |
10 |
11 | ## Example
12 |
13 | To create the 'AWSElasticLoadBalancerHandler' object, you must provide AWS credentials:
14 |
15 | ```python elb_handler_test.py
16 | import os
17 | from superagentx_handlers.aws.elb import AWSElasticLoadBalancerHandler
18 |
19 | elb_handler = AWSElasticLoadBalancerHandler(
20 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
21 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
22 | region_name="us-east-1"
23 | )
24 | ```
25 | **Get ELB Details:**
26 | Fetches all Application Load Balancer (ALB) details, including listeners, rules, target groups, and target health.
27 | ```python
28 | elb_details = await elb_handler.get_elb_details()
29 | print(elb_details)
30 | ```
31 | **Collect Target Groups from Default Actions and Rules:**
32 | Collects all target groups referenced in listeners’ default actions and custom rules.
33 | ```python
34 | target_groups = await elb_handler.collect_target_groups_from_listeners("arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-alb/abc123")
35 | print(target_groups)
36 | ```
37 |
38 | **Fetch Detailed Target Group Info:**
39 | Fetches complete target group configuration and health status, including protocol, port, health check config, and registered targets.
40 | ```python
41 | tg_info = await elb_handler.get_target_group_info("arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-tg/ghi789")
42 | print(tg_info)
43 | ```
44 |
--------------------------------------------------------------------------------
/tests/conversation/test_conversation_pipe.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import uuid
3 |
4 | from rich import print as rprint
5 |
6 | from superagentx.agent import Agent
7 | from superagentx.agentxpipe import AgentXPipe
8 | from superagentx.engine import Engine
9 | from superagentx.handler.ai import AIHandler
10 | from superagentx.llm import LLMClient
11 | from superagentx.memory import Memory
12 | from superagentx.prompt import PromptTemplate
13 |
14 |
15 | async def get_test_ai_handler_pipe() -> AgentXPipe:
16 | # LLM Configuration
17 | llm_config = {
18 | 'llm_type': 'openai'
19 | }
20 | llm_client = LLMClient(llm_config=llm_config)
21 |
22 | # Enable Memory
23 | memory = Memory(memory_config={"llm_client": llm_client})
24 |
25 | ai_handler = AIHandler(
26 | llm=llm_client
27 | )
28 |
29 | # Prompt Template
30 | prompt_template = PromptTemplate()
31 |
32 | # Create Engine
33 | ai_engine = Engine(
34 | handler=ai_handler,
35 | llm=llm_client,
36 | prompt_template=prompt_template
37 | )
38 |
39 | # Create Agents
40 | ai_agent = Agent(
41 | name='AI agent',
42 | goal="Get me the best results",
43 | role="You are the best at answering",
44 | llm=llm_client,
45 | prompt_template=prompt_template,
46 | engines=[ai_engine]
47 | )
48 |
49 | # Expose via pipe for interaction
50 | pipe = AgentXPipe(
51 | agents=[ai_agent],
52 | memory=memory
53 | )
54 |
55 | return pipe
56 |
57 |
58 | conversation_id = uuid.uuid4().hex # Unique ID for tracking this conversation
59 |
60 | async def main():
61 |
62 | conversation_pipe = await get_test_ai_handler_pipe()
63 |
64 | while True:
65 | user_input = input(f"Enter Your Query Here: ")
66 | result = await conversation_pipe.flow(
67 | query_instruction=user_input,
68 | conversation_id=conversation_id # Context maintained here
69 | )
70 | print(result)
71 |
72 |
73 | if __name__ == "__main__":
74 | asyncio.run(main())
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/cloudfront.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'CloudFront Handler'
3 | icon: 'globe'
4 | ---
5 |
6 | Amazon CloudFront is a fast Content Delivery Network (CDN) service that securely delivers data, videos, applications,
7 | and APIs to customers globally with low latency and high transfer speeds. CloudFront works seamlessly with services
8 | like S3, API Gateway, and ACM for SSL/TLS certificates.
9 |
10 | ## Example
11 | To create the AWSCloudFrontHandler object with AWS credentials.
12 | The AWSCloudFrontHandler enables you to interact with CloudFront for tasks such as
13 | listing distributions, cache behaviors, access control settings, and certificates.
14 |
15 | ```python cloudfront_handler_test.py
16 | import os
17 |
18 | from superagentx_handlers.aws.cloudfront import AWSCloudFrontHandler
19 |
20 |
21 | cloudfront_handler = AWSCloudFrontHandler(
22 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
23 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
24 | region_name="us-east-1"
25 | )
26 | ```
27 |
28 | **List Distributions:**
29 | The list_distributions method retrieves all CloudFront distributions.
30 | ```python
31 | distributions = await cloudfront_handler.list_distributions()
32 | print(distributions)
33 | ```
34 |
35 | **List Certificates:**
36 | The list_certificates method retrieves all ACM-managed certificates in us-east-1,
37 | typically used with CloudFront.
38 | ```python
39 | certificates = await cloudfront_handler.list_certificates()
40 | print(certificates)
41 | ```
42 |
43 | **List Cache Behaviors:**
44 | The list_cache_behaviors method shows default and ordered cache behaviors for all distributions.
45 | ```python
46 | cache_behaviors = await cloudfront_handler.list_cache_behaviors()
47 | print(cache_behaviors)
48 | ```
49 |
50 | **List Access Control Configurations:**
51 | The list_access_control_configs method retrieves access control settings like geo-restrictions and WAF associations.
52 | ```python
53 | access_controls = await cloudfront_handler.list_access_control_configs()
54 | print(access_controls)
55 | ```
--------------------------------------------------------------------------------
/tests/agent/test_mcp_reddit_agent.py:
--------------------------------------------------------------------------------
1 | import json
2 | import logging
3 |
4 | import pytest
5 |
6 | from superagentx.agent import Agent
7 | from superagentx.engine import Engine
8 | from superagentx.handler.mcp import MCPHandler
9 | from superagentx.llm import LLMClient
10 | from superagentx.prompt import PromptTemplate
11 |
12 | logger = logging.getLogger(__name__)
13 |
14 |
15 | @pytest.fixture
16 | def agent_client_init() -> dict:
17 | llm_config = {'model': 'openai/gpt-5-mini'}
18 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
19 | return {'llm': llm_client, 'llm_type': 'openai'}
20 |
21 |
22 | async def status_callback(event: str, **kwargs):
23 | logger.info(f"[Callback] Event: {event}")
24 | logger.info(f"[Callback] Event: {event}, Data: {kwargs}")
25 |
26 |
27 | class TestMCPRedditAgent:
28 |
29 | @pytest.mark.asyncio
30 | async def test_reddit_search_agent(self, agent_client_init: dict):
31 | llm_client: LLMClient = agent_client_init.get('llm')
32 |
33 | # MCP Tool - pip install mcp-server-reddit
34 | mcp_handler = MCPHandler(command="uvx", mcp_args=["mcp-server-reddit"])
35 | prompt_template = PromptTemplate()
36 |
37 | # ✅ Enable engine to execute MCP Tools
38 | mcp_engine = Engine(handler=mcp_handler, llm=llm_client, prompt_template=prompt_template)
39 |
40 | goal = "Review and perform user's input"
41 |
42 | # ✅ SuperAgentX Agent
43 | reddit_search_agent = Agent(
44 | goal=goal,
45 | role="You're an Analyst",
46 | llm=llm_client,
47 | prompt_template=prompt_template,
48 | max_retry=1
49 | )
50 | await reddit_search_agent.add(mcp_engine)
51 |
52 | # ✅ Ask question with live callback
53 | result = await reddit_search_agent.execute(
54 | query_instruction="What are the current hot posts on Reddit's frontpage and summarize?",
55 | status_callback=status_callback # <-- callback passed here
56 | )
57 |
58 | # logger.info(f'Result ==> {result}')
59 | assert result
60 |
--------------------------------------------------------------------------------
/tests/browser/test_check_appointment.py:
--------------------------------------------------------------------------------
1 | import warnings
2 |
3 | from superagentx.agentxpipe import AgentXPipe
4 |
5 | with warnings.catch_warnings():
6 | warnings.simplefilter("ignore", category=UserWarning)
7 |
8 | import logging
9 | import pytest
10 | from superagentx.agent import Agent
11 | from superagentx.browser_engine import BrowserEngine
12 | from superagentx.llm import LLMClient
13 | from superagentx.prompt import PromptTemplate
14 |
15 | logger = logging.getLogger(__name__)
16 |
17 | '''
18 | Run Pytest:
19 |
20 | 1. pytest --log-cli-level=INFO tests/browser/test_check_appointment.py::test_check_appointment
21 | '''
22 |
23 |
24 | @pytest.fixture
25 | def agent_client_init() -> dict:
26 | llm_config = {'model': 'gpt-4o', 'llm_type': 'openai'}
27 |
28 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
29 | response = {'llm': llm_client, 'llm_type': 'openai'}
30 | return response
31 |
32 |
33 | @pytest.mark.filterwarnings("ignore::UserWarning")
34 | async def test_check_appointment(agent_client_init: dict):
35 | llm_client: LLMClient = agent_client_init.get('llm')
36 | prompt_template = PromptTemplate()
37 | browser_engine = BrowserEngine(
38 | llm=llm_client,
39 | prompt_template=prompt_template,
40 | # browser_instance_path="/usr/bin/google-chrome-stable"
41 | )
42 | goal = """Complete the user's input."""
43 | browser_agent = Agent(
44 | goal=goal,
45 | role="You are the AI Assistant",
46 | llm=llm_client,
47 | prompt_template=prompt_template,
48 | max_retry=1,
49 | engines=[browser_engine]
50 | )
51 |
52 | pipe = AgentXPipe(
53 | agents=[browser_agent],
54 | # memory=memory
55 | )
56 |
57 | task = (
58 | 'Go to the Greece MFA webpage via the link I provided you.https://appointment.mfa.gr/en/reservations/aero/ireland-grcon-dub/'
59 | 'Check the visa appointment dates. If there is no available date in this month, check the next month.'
60 | 'If there is no available date in both months, tell me there is no available date.'
61 | )
62 |
63 | await pipe.flow(
64 | query_instruction=task
65 | )
--------------------------------------------------------------------------------
/docs/examples/handlers/Gcp/api_gateway.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'API Gateway Handler'
3 | icon: 'server'
4 | ---
5 |
6 | Google Cloud API Gateway is a fully managed service that allows developers to create, secure, and monitor APIs for their applications. It enables seamless management of APIs at scale, integrates with IAM for authentication, and provides features like quota management, monitoring, and logging.
7 |
8 | The `GCPAPIGatewayHandler` helps interact with Google Cloud’s API Gateway service to fetch gateway details programmatically.
9 |
10 | ## Example
11 |
12 | To create the `GCPAPIGatewayHandler` object, initialize it with your Google service account credentials (JSON file path or dictionary).
13 |
14 | ```python
15 | from superagentx_handlers.gcp.api_gateway import GCPAPIGatewayHandler
16 |
17 | gateway_handler = GCPAPIGatewayHandler(
18 | creds="service-account.json" # or dict with service account info
19 | )
20 | ```
21 |
22 | **List API Gateways:**
23 | Lists all API Gateways available in your GCP project across supported regions.
24 | ```python
25 | gateways = await gateway_handler.list_gateways(page_size=50)
26 | for g in gateways:
27 | print(g["name"], g["state"], g["default_hostname"])
28 | ```
29 |
30 | **Convert Gateway to Dictionary (_gateway_to_dict):**
31 | Converts a Gateway object into a structured dictionary with useful metadata.
32 | ```python
33 | gateway_obj = (await gateway_handler.client.list_gateways(
34 | request={"parent": "projects/my-project/locations/us-central1"}
35 | )).pages[0][0]
36 |
37 | gateway_dict = await gateway_handler._gateway_to_dict(gateway_obj, location="us-central1")
38 | print(gateway_dict)
39 | ```
40 |
41 | **Get Gateway State (_get_gateway_state):**
42 | Converts a raw state value (string, int, or enum) into a Gateway.State enum.
43 | ```python
44 | from google.cloud import apigateway_v1
45 |
46 | # Using string
47 | print(_get_gateway_state("CREATING").name) # Output: CREATING
48 |
49 | # Using integer (matches enum value)
50 | print(_get_gateway_state(1).name) # Output: ACTIVE
51 |
52 | # Using enum directly
53 | print(_get_gateway_state(apigateway_v1.Gateway.State.FAILED).name) # Output: FAILED
54 | ```
55 |
--------------------------------------------------------------------------------
/superagentx/llm/types/response.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from typing import Any
3 |
4 | from pydantic import BaseModel, Field
5 |
6 |
7 | class Tool(BaseModel):
8 | name: str = Field(
9 | ...,
10 | description="The name of the function to call."
11 | )
12 |
13 | arguments: dict[str, Any] | None = Field(
14 | default=None,
15 | description="The arguments to call the function with, as generated by the model in JSON format"
16 | )
17 |
18 | tool_type: str | None = Field(
19 | default=None,
20 | description="The type of the tool"
21 | )
22 |
23 |
24 | class Message(BaseModel):
25 | role: str = Field(
26 | ...,
27 | description="Role of the message sender, e.g., 'assistant', 'user', or 'system'"
28 | )
29 |
30 | model: str = Field(
31 | ...,
32 | description="The model used for the chat completion."
33 | )
34 |
35 | content: str | None = Field(
36 | default=None,
37 | description="Content of the message"
38 | )
39 |
40 | tool_calls: list[Tool] | None = Field(
41 | default=None,
42 | description="The name and arguments of a function that should be called, as generated by the model."
43 | )
44 |
45 | system_fingerprint: str | None = Field(
46 | default=None,
47 | description="This fingerprint represents the backend configuration that the model runs with"
48 | )
49 |
50 | completion_tokens: int = Field(
51 | default=0,
52 | description="Number of tokens in the generated completion."
53 | )
54 |
55 | prompt_tokens: int = Field(
56 | default=0,
57 | description="Number of tokens in the prompt."
58 | )
59 |
60 | total_tokens: int = Field(
61 | default=0,
62 | description="Total number of tokens used in the request (prompt + completion)."
63 | )
64 |
65 | reasoning_tokens: int = Field(
66 | default=0,
67 | description="Tokens generated by the model for reasoning."
68 | )
69 |
70 | created: datetime = Field(
71 | description="The timestamp when the message was created, in datetime format."
72 | ) # Updated created field as datetime
73 |
--------------------------------------------------------------------------------
/docs/examples/handlers/elastic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Elastic Search Handler'
3 | icon: 'circle-e'
4 | ---
5 |
6 | Elasticsearch is a powerful, open-source search and analytics engine based on Apache Lucene. It quickly stores,
7 | searches, and analyzes large amounts of data by creating indexes, rather than searching the text directly. With
8 | a document-based structure and easy-to-use REST APIs, it processes and returns data in JSON format, offering
9 | fast and scalable performance.
10 |
11 | ### Setup
12 | Install Elasticsearch locally by running it on your machine. The simplest method is to use the official
13 | Elasticsearch Docker image. For more details, check the Elasticsearch Docker documentation.
14 |
15 | ## Example
16 | This code initializes an ElasticsearchHandler to connect to an Elasticsearch server running on localhost with specified
17 | username and password. This setup allows for searching and managing data stored in Elasticsearch efficiently.
18 |
19 | ```python elastic_handler.py
20 | import asyncio
21 |
22 | from superagentx.handler.elastic_search import ElasticsearchHandler
23 |
24 |
25 | async def create_index():
26 | elasticsearch_handler = ElasticsearchHandler(
27 | hosts="http://localhost:9200",
28 | username="",
29 | password=""
30 | )
31 |
32 | return await elasticsearch_handler.create(
33 | index_name="",
34 | document_id="",
35 | document={
36 | "@timestamp": "2099-11-15T13:12:00",
37 | "message": "GET /search HTTP/1.1 200 1070000",
38 | }
39 | )
40 |
41 |
42 | async def main():
43 | res = await create_index()
44 | print(res)
45 |
46 | if __name__ == '__main__':
47 | asyncio.run(main())
48 | ```
49 |
50 | ## Result
51 | ```inline Index Create Output:
52 | {
53 | "_index": "project8",
54 | "_id": "project test",
55 | "_version": 1,
56 | "result": "created",
57 | "_shards": {
58 | "total": 2,
59 | "successful": 1,
60 | "failed": 0
61 | },
62 | "_seq_no": 0,
63 | "_primary_term": 1
64 | }
65 | ```
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/docs/examples/handlers/weather.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Weather Handler'
3 | icon: 'cloud-bolt-sun'
4 | ---
5 |
6 | A weather handler is a tool or library that helps developers integrate weather data into applications.
7 | It works by retrieving real-time or forecasted weather information from external sources, such as weather
8 | APIs, and presenting it in a way that is easy to use in applications like websites, mobile apps, or IoT devices.
9 |
10 | ## Example
11 | This code initializes a WeatherHandler, which is designed to fetch weather-related data. This setup enables the
12 | application to access various weather services for retrieving current latitude and longitude.
13 |
14 | ```python weather_handler.py
15 | import asyncio
16 |
17 | from superagentx_handlers.weather import WeatherHandler
18 |
19 | weather_handler = WeatherHandler()
20 |
21 |
22 | async def get_lat_long(place):
23 | return await weather_handler.get_lat_long(place=place)
24 |
25 |
26 | async def get_weather(place):
27 | lat_long = await get_lat_long(place)
28 | latitude = lat_long.get("latitude")
29 | longitude = lat_long.get("longitude")
30 | return await weather_handler.get_weather(
31 | latitude=latitude,
32 | longitude=longitude
33 | )
34 |
35 |
36 | async def main(place):
37 | res = await get_weather(place)
38 | print(res)
39 |
40 | if __name__ == '__main__':
41 | place="coimbatore"
42 | asyncio.run(main(place))
43 | ```
44 |
45 | ## Result
46 | ```python weather
47 | {
48 | "latitude": 11.0,
49 | "longitude": 77.0,
50 | "generationtime_ms": 0.04398822784423828,
51 | "utc_offset_seconds": 0,
52 | "timezone": "GMT",
53 | "timezone_abbreviation": "GMT",
54 | "elevation": 421.0,
55 | "current_weather_units": {
56 | "time": "iso8601",
57 | "interval": "seconds",
58 | "temperature": "°C",
59 | "windspeed": "km/h",
60 | "winddirection": "°",
61 | "is_day": "",
62 | "weathercode": "wmo code"
63 | },
64 | "current_weather": {
65 | "time": "2024-11-04T17: 00",
66 | "interval": 900,
67 | "temperature": 23.5,
68 | "windspeed": 3.3,
69 | "winddirection": 13,
70 | "is_day": 0,
71 | "weathercode": 80
72 | }
73 | }
74 |
75 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/csv_cli.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Csv Handler'
3 | icon: 'file-csv'
4 | ---
5 |
6 | The method leverages a query string provided by the user to generate a filter condition based on the columns of the
7 | CSV file. This condition is used to extract relevant data from the CSV and return it in a structured format. The filtering
8 | logic is generated by an external LLM (Large Language Model) client, which receives a prompt based on the CSV's structure.
9 |
10 | ## Example
11 | This method is part of the CsvHandler class, which handles CSV file operations, and is specifically designed to search
12 | through the data in the CSV file based on a user-defined query.
13 |
14 | To use OpenAI models, you’ll need to create an OpenAI account and get an API key. For more details refer here.
15 |
16 | >Set up a OpenAI API key as an environmental variable and run the following code.
17 | ```python
18 | export OPENAI_API_KEY = "**************************"
19 | ```
20 |
21 | ```python csv_handler.py
22 | import asyncio
23 |
24 | from superagentx_handlers.csv_cli import CsvHandler
25 | from superagentx.llm import LLMClient
26 |
27 |
28 | async def search(query):
29 | input_path = ""
30 | llm_config = {'llm_type': 'openai'}
31 | llm_client = LLMClient(llm_config=llm_config)
32 | csv_handler = CsvHandler(
33 | file_path=input_path,
34 | llm_client=llm_client
35 | )
36 | return await csv_handler.search(query)
37 |
38 |
39 | async def main(query):
40 | res = await search(query)
41 | print(res)
42 |
43 | if __name__ == '__main__':
44 | query="who are all Petroleum engineer"
45 | asyncio.run(main(query))
46 | ```
47 |
48 | ### Result
49 | ```python csv cli
50 | {
51 | "Index": {
52 | "59": 60
53 | },
54 | "User Id": {
55 | "59": "0f8deedb629A5f6"
56 | },
57 | "First Name": {
58 | "59": "Grace"
59 | },
60 | "Last Name": {
61 | "59": "Phelps"
62 | },
63 | "Sex": {
64 | "59": "Male"
65 | },
66 | "Email": {
67 | "59": "clarkeangela@example.net"
68 | },
69 | "Phone": {
70 | "59": "(034)867-8827x6777"
71 | },
72 | "Date of birth": {
73 | "59": "1909-10-15"
74 | },
75 | "Job Title": {
76 | "59": "Petroleum engineer"
77 | }
78 | }
79 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/azure/cloud_functions.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Cloud Functions'
3 | icon: 'cloud'
4 | ---
5 |
6 | Azure Functions is a **serverless compute service** that enables you to run event-driven code without provisioning or managing infrastructure.
7 | It allows developers to write functions in multiple languages (like Python, Node.js, C#, etc.) and execute them in response to triggers (HTTP requests, timers, storage events, queues, etc.).
8 |
9 | Using the `AzureFunctionHandler`, you can easily **list, retrieve, and configure** function apps within your Azure subscription. It leverages the Azure SDK to interact with Azure Functions resources, supporting authentication via `ClientSecretCredential`.
10 |
11 |
12 | ## Example
13 |
14 | To create the `AzureFunctionHandler` object, provide your **Azure credentials**:
15 |
16 | ```python
17 | import os
18 | from superagentx_handlers.azure.functions import AzureFunctionHandler
19 |
20 | azure_handler = AzureFunctionHandler(
21 | subscription_id=os.getenv("AZURE_SUBSCRIPTION_ID"),
22 | tenant_id=os.getenv("AZURE_TENANT_ID"),
23 | client_id=os.getenv("AZURE_CLIENT_ID"),
24 | client_secret=os.getenv("AZURE_CLIENT_SECRET"),
25 | )
26 | ```
27 |
28 | **List All Function Apps in a Subscription:**
29 | Retrieves all function apps across the given subscription.
30 | ```python
31 | function_apps = await azure_handler.get_all_function_apps_in_subscription()
32 | print(function_apps)
33 | ```
34 |
35 | **List Function Apps by Resource Group:**
36 | Get all function apps inside a specific resource group.
37 | ```python
38 | apps_in_rg = await azure_handler.get_function_apps_by_resource_group("my-resource-group")
39 | print(apps_in_rg)
40 | ```
41 |
42 | **Get a Specific Function App by Name:**
43 | Retrieve metadata and configuration of a specific function app.
44 | ```python
45 | function_app = await azure_handler.get_function_app_by_name(
46 | resource_group_name="my-resource-group",
47 | function_app_name="my-function-app"
48 | )
49 | print(function_app)
50 | ```
51 |
52 | **Get Function App Configuration:**
53 | Fetches site configuration, app settings, and connection strings.
54 | ```python
55 | config = await azure_handler.get_function_app_configuration(
56 | resource_group_name="my-resource-group",
57 | function_app_name="my-function-app"
58 | )
59 | print(config)
60 | ```
--------------------------------------------------------------------------------
/superagentx/handler/serper_dev.py:
--------------------------------------------------------------------------------
1 | import os
2 | import json
3 | import aiohttp
4 |
5 | from superagentx.handler.base import BaseHandler
6 | from superagentx.handler.decorators import tool
7 |
8 |
9 | class SerperDevToolHandler(BaseHandler):
10 |
11 | def __init__(self):
12 | super().__init__()
13 | self.search_url: str = "https://google.serper.dev/search"
14 |
15 | @tool
16 | async def search(
17 | self,
18 | *,
19 | query: str,
20 | total_results: int = 5
21 | ):
22 | """
23 | A tool for performing real-time web searches and retrieving structured results based on the provided query.
24 |
25 | Parameters:
26 | query(str): The search text or query to find relevant information.
27 | total_results(int): Number of total results
28 |
29 | Return:
30 | List of Dict
31 | """
32 |
33 | payload = json.dumps({
34 | "q": query
35 | })
36 |
37 | headers = {
38 | "X-API-KEY": os.environ["SERPER_API_KEY"],
39 | "content-type": "application/json",
40 | }
41 | results = []
42 | async with aiohttp.ClientSession() as session:
43 | async with session.post(
44 | self.search_url,
45 | headers=headers,
46 | data=payload,
47 | ) as response:
48 | search_results = await response.json()
49 |
50 | if "organic" in search_results:
51 | results = search_results["organic"][: total_results]
52 | string = []
53 | for result in results:
54 | try:
55 | string.append(
56 | "\n".join(
57 | [
58 | f"Title: {result['title']}",
59 | f"Link: {result['link']}",
60 | f"Snippet: {result['snippet']}",
61 | "---",
62 | ]
63 | )
64 | )
65 | except KeyError:
66 | continue
67 | return results
68 |
--------------------------------------------------------------------------------
/superagentx/utils/parsers/list.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | from superagentx.utils.helper import iter_to_aiter
4 | from superagentx.utils.parsers.base import BaseParser
5 |
6 |
7 | class CommaSeparatedListOutputParser(BaseParser):
8 |
9 | async def parse(self, text: str) -> list[str]:
10 | """Parse the output of an LLM call.
11 |
12 | Args:
13 | text: The output of an LLM call.
14 |
15 | Returns:
16 | A list of strings.
17 | """
18 | return [part.strip() async for part in iter_to_aiter(text.split(","))]
19 |
20 | async def get_format_instructions(self) -> str:
21 | """Return the format instructions for the comma-separated list output."""
22 | return (
23 | "Your response should be a list of comma separated values, "
24 | "eg: `foo, bar, baz` or `foo,bar,baz`"
25 | )
26 |
27 |
28 | class NumberedListOutputParser(BaseParser):
29 | """Parse a numbered list."""
30 |
31 | pattern: str = r"\d+\.\s([^\n]+)"
32 | """The pattern to match a numbered list item."""
33 |
34 | async def get_format_instructions(self) -> str:
35 | return (
36 | "Your response should be a numbered list with each item on a new line. "
37 | "For example: \n\n1. foo\n\n2. bar\n\n3. baz"
38 | )
39 |
40 | async def parse(self, text: str) -> list[str]:
41 | """Parse the output of an LLM call.
42 |
43 | Args:
44 | text: The output of an LLM call.
45 |
46 | Returns:
47 | A list of strings.
48 | """
49 | return re.findall(self.pattern, text)
50 |
51 |
52 | class MarkdownListOutputParser(BaseParser):
53 | """Parse a Markdown list."""
54 |
55 | pattern: str = r"^\s*[-*]\s([^\n]+)$"
56 | """The pattern to match a Markdown list item."""
57 |
58 | async def get_format_instructions(self) -> str:
59 | """Return the format instructions for the Markdown list output."""
60 | return "Your response should be a markdown list, " "eg: `- foo\n- bar\n- baz`"
61 |
62 | async def parse(self, text: str) -> list[str]:
63 | """Parse the output of an LLM call.
64 |
65 | Args:
66 | text: The output of an LLM call.
67 |
68 | Returns:
69 | A list of strings.
70 | """
71 | return re.findall(self.pattern, text, re.MULTILINE)
72 |
--------------------------------------------------------------------------------
/superagentx/handler/exa_search.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from exa_py import Exa
4 |
5 | from superagentx.handler.base import BaseHandler
6 | from superagentx.handler.decorators import tool
7 | from superagentx.utils.helper import sync_to_async
8 |
9 |
10 | class ExaHandler(BaseHandler):
11 | """
12 | A handler class for managing interactions with an Exa database.
13 | This class extends BaseHandler and provides methods to perform various database operations,
14 | such as executing queries, managing tables, and handling data transactions in an Exa environment.
15 | """
16 |
17 | def __init__(
18 | self,
19 | api_key: str | None = None
20 | ):
21 | super().__init__()
22 | api_key = api_key or os.getenv("EXA_API_KEY")
23 | self.exa = Exa(api_key=api_key)
24 |
25 | @tool
26 | async def search_contents(
27 | self,
28 | *,
29 | query: str,
30 | use_autoprompt: bool,
31 | num_results: int = 10,
32 | search_type: str | None = None
33 | ):
34 | """
35 | Asynchronously searches content based on the query, with options to use autoprompt, limit the number of results,
36 | and filter by search type. Customizes the search experience according to the provided parameters.
37 |
38 | Parameters:
39 | query (str): The search query string used to find relevant content.
40 | use_autoprompt (bool): If True, the method will leverage autoprompt suggestions to enhance the search
41 | results.
42 | num_results (int | None, optional): The maximum number of search results to return. Defaults to 10.
43 | If set to None, all available results may be returned.
44 | search_type (str | None, optional): Specifies the type of search to perform. Defaults to None,
45 | in which case a general search is performed.
46 |
47 | Returns:
48 | Any: The search results, which may vary depending on the search type and query.
49 |
50 | """
51 | if not search_type:
52 | search_type = "auto"
53 |
54 | return await sync_to_async(
55 | self.exa.search_and_contents,
56 | query=query,
57 | type=search_type,
58 | use_autoprompt=use_autoprompt,
59 | num_results=num_results,
60 | )
61 |
--------------------------------------------------------------------------------
/superagentx/io/base.py:
--------------------------------------------------------------------------------
1 |
2 | import logging
3 | from contextlib import contextmanager
4 | from contextvars import ContextVar
5 | from typing import Any, Iterator, Optional, Protocol, runtime_checkable, Self
6 |
7 | logger = logging.getLogger(__name__)
8 |
9 |
10 | @runtime_checkable
11 | class OutputStream(Protocol):
12 | async def write(
13 | self,
14 | *objects: Any,
15 | sep: str | None = None,
16 | end: str | None = None,
17 | flush: bool = False
18 | ) -> None:
19 | """Print data to the output stream."""
20 |
21 |
22 | @runtime_checkable
23 | class InputStream(Protocol):
24 | async def read(
25 | self,
26 | prompt: str | None = None,
27 | *,
28 | password: bool = False
29 | ) -> str:
30 | """Read a line from the input stream."""
31 |
32 |
33 | @runtime_checkable
34 | class IOStream(InputStream, OutputStream, Protocol):
35 | """A protocol for input/output streams."""
36 |
37 | _default_io_stream: ContextVar[Self | None] = ContextVar("default_iostream", default=None)
38 | _global_default: Self | None = None
39 |
40 | @staticmethod
41 | def set_global_io_stream(stream: "IOStream") -> None:
42 | """Set the global default IO stream."""
43 | IOStream._global_default = stream
44 |
45 | @staticmethod
46 | def get_global_io_stream() -> "IOStream":
47 | """Get the global default IO stream."""
48 | if IOStream._global_default is None:
49 | raise RuntimeError("No global default IOStream has been set.")
50 | return IOStream._global_default
51 |
52 | @staticmethod
53 | def get_current_io_stream() -> "IOStream":
54 | """Get the current context's default IO stream."""
55 | iostream = IOStream._default_io_stream.get()
56 | if iostream is None:
57 | iostream = IOStream.get_global_io_stream()
58 | IOStream.override_default_io_stream(iostream)
59 | return iostream
60 |
61 | @staticmethod
62 | @contextmanager
63 | async def override_default_io_stream(stream: Optional["IOStream"]) -> Iterator[None]:
64 | """Temporarily override the default IO stream for the current context."""
65 | token = IOStream._default_io_stream.set(stream)
66 | try:
67 | yield
68 | finally:
69 | IOStream._default_io_stream.reset(token)
70 |
--------------------------------------------------------------------------------
/superagentx/llm/constants.py:
--------------------------------------------------------------------------------
1 | OPENAI_PRICE1K = {
2 | "gpt-4.1": (0.005, 0.015),
3 | "gpt-4o": (0.005, 0.015),
4 | "gpt-4o-2024-05-13": (0.005, 0.015),
5 | "gpt-4o-2024-08-06": (0.0025, 0.01),
6 | # gpt-4-turbo
7 | "gpt-4-turbo-2024-04-09": (0.01, 0.03),
8 | # gpt-4
9 | "gpt-4": (0.03, 0.06),
10 | "gpt-4-32k": (0.06, 0.12),
11 | # gpt-4o-mini
12 | "gpt-4o-mini": (0.000150, 0.000600),
13 | "gpt-4o-mini-2024-07-18": (0.000150, 0.000600),
14 | # gpt-3.5 turbo
15 | "gpt-3.5-turbo": (0.0005, 0.0015), # default is 0125
16 | "gpt-3.5-turbo-0125": (0.0005, 0.0015), # 16k
17 | "gpt-3.5-turbo-instruct": (0.0015, 0.002),
18 | # base model
19 | "davinci-002": 0.002,
20 | "babbage-002": 0.0004,
21 | # old model
22 | "gpt-4-0125-preview": (0.01, 0.03),
23 | "gpt-4-1106-preview": (0.01, 0.03),
24 | "gpt-4-1106-vision-preview": (0.01, 0.03),
25 | "gpt-3.5-turbo-1106": (0.001, 0.002),
26 | "gpt-3.5-turbo-0613": (0.0015, 0.002),
27 | # "gpt-3.5-turbo-16k": (0.003, 0.004),
28 | "gpt-3.5-turbo-16k-0613": (0.003, 0.004),
29 | "gpt-3.5-turbo-0301": (0.0015, 0.002),
30 | "text-ada-001": 0.0004,
31 | "text-babbage-001": 0.0005,
32 | "text-curie-001": 0.002,
33 | "code-cushman-001": 0.024,
34 | "code-davinci-002": 0.1,
35 | "text-davinci-002": 0.02,
36 | "text-davinci-003": 0.02,
37 | "gpt-4-0314": (0.03, 0.06), # deprecate in Sep
38 | "gpt-4-32k-0314": (0.06, 0.12), # deprecate in Sep
39 | "gpt-4-0613": (0.03, 0.06),
40 | "gpt-4-32k-0613": (0.06, 0.12),
41 | "gpt-4-turbo-preview": (0.01, 0.03),
42 | # https://azure.microsoft.com/en-us/pricing/details/cognitive-services/openai-service/#pricing
43 | "gpt-35-turbo": (0.0005, 0.0015), # what's the default? using 0125 here.
44 | "gpt-35-turbo-0125": (0.0005, 0.0015),
45 | "gpt-35-turbo-instruct": (0.0015, 0.002),
46 | "gpt-35-turbo-1106": (0.001, 0.002),
47 | "gpt-35-turbo-0613": (0.0015, 0.002),
48 | "gpt-35-turbo-0301": (0.0015, 0.002),
49 | "gpt-35-turbo-16k": (0.003, 0.004),
50 | "gpt-35-turbo-16k-0613": (0.003, 0.004),
51 | }
52 |
53 | DEFAULT_OPENAI_EMBED = "text-embedding-ada-002"
54 | DEFAULT_BEDROCK_EMBED = "amazon.titan-embed-g1-text-02"
55 | DEFAULT_ANTHROPIC_EMBED = 'sentence-transformers/all-MiniLM-L6-v2'
56 | DEFAULT_OLLAMA_EMBED = "mxbai-embed-large"
57 | DEFAULT_EMBED = 'sentence-transformers/all-MiniLM-L6-v2'
58 | DEFAULT_GEMINI_EMBED = "gemini-embedding-exp-03-07"
59 |
--------------------------------------------------------------------------------
/superagentx/utils/llm_config.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 |
3 |
4 | class LLMType(str, Enum):
5 | OPENAI_CLIENT = 'openai'
6 | AZURE_OPENAI_CLIENT = 'azure-openai'
7 | DEEPSEEK = 'deepseek'
8 | LLAMA_CLIENT = 'llama'
9 | GEMINI_CLIENT = 'gemini'
10 | MISTRAL_CLIENT = 'mistral'
11 | BEDROCK_CLIENT = 'bedrock'
12 | TOGETHER_CLIENT = 'together'
13 | GROQ_CLIENT = 'groq'
14 | ANTHROPIC_CLIENT = 'anthropic'
15 | OLLAMA = 'ollama'
16 | LITELLM = 'litellm'
17 |
18 | @classmethod
19 | def has_member_key(cls, key):
20 | return key in cls.__members__
21 |
22 | @classmethod
23 | def has_member_value(cls, value) -> bool:
24 | try:
25 | if cls(value):
26 | return True
27 | except ValueError:
28 | return False
29 |
30 |
31 | OPENAI_MODELS = [
32 | "gpt-4.1-mini",
33 | "gpt-4.1",
34 | "gpt-4o",
35 | "gpt-4o-2024-05-13",
36 | "gpt-4o-2024-08-06",
37 | "gpt-4-turbo-2024-04-09",
38 | "gpt-4",
39 | "gpt-4o-mini-2024-07-18",
40 | "gpt-4o-mini",
41 | "text-embedding-ada-002",
42 | "text-embedding-3-small",
43 | "text-embedding-3-large"
44 | ]
45 |
46 | BEDROCK_MODELS = [
47 | 'anthropic.claude-3-5-sonnet-20241022-v2:0',
48 | 'anthropic.claude-3-5-haiku-20241022-v1:0',
49 | 'anthropic.claude-instant-v1:2:100k',
50 | 'anthropic.claude-3-sonnet-20240229-v1:0',
51 | 'anthropic.claude-3-haiku-20240307-v1:0',
52 | 'anthropic.claude-3-opus-20240229-v1:0',
53 | 'anthropic.claude-3-5-sonnet-20240620-v1:0',
54 | 'cohere.command-r-v1:0',
55 | 'cohere.command-r-plus-v1:0',
56 | 'meta.llama3-1-8b-instruct-v1:0',
57 | 'meta.llama3-1-70b-instruct-v1:0',
58 | 'meta.llama3-1-405b-instruct-v1:0',
59 | 'meta.llama3-2-11b-instruct-v1:0',
60 | 'meta.llama3-2-90b-instruct-v1:0',
61 | 'meta.llama3-2-1b-instruct-v1:0',
62 | 'meta.llama3-2-3b-instruct-v1:0',
63 | 'mistral.mistral-large-2402-v1:0',
64 | 'mistral.mistral-large-2407-v1:0'
65 | ]
66 |
67 | ANTHROPIC_MODELS = [
68 | 'claude-3-5-sonnet-20241022',
69 | 'claude-3-5-haiku-20241022',
70 | 'claude-3-opus-20240229',
71 | 'claude-3-sonnet-20240229',
72 | 'claude-3-haiku-20240307'
73 | ]
74 |
75 | DEEPSEEK_MODELS = [
76 | "deepseek-chat",
77 | ]
78 |
79 | OLLAMA_MODELS = [
80 | "mistral:latest",
81 | "llama3.3:latest",
82 | ]
83 |
84 | # Azure Open AI Version - Default
85 | DEFAULT_AZURE_API_VERSION = "2024-02-01"
86 |
--------------------------------------------------------------------------------
/tests/browser/cricket_tweet.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import logging
3 | import warnings
4 |
5 | from rich import print as rprint
6 |
7 | from superagentx.agent import Agent
8 | from superagentx.browser_engine import BrowserEngine
9 | from superagentx.llm import LLMClient
10 | from superagentx.prompt import PromptTemplate
11 |
12 | warnings.filterwarnings('ignore')
13 |
14 | sh = logging.StreamHandler()
15 | logging.basicConfig(
16 | level="INFO",
17 | format='%(asctime)s -%(levelname)s - %(name)s - %(funcName)s: %(message)s',
18 | datefmt='%Y-%m-%d %H:%M:%S',
19 | handlers=[sh]
20 | )
21 |
22 |
23 | async def main():
24 | llm_config = {'model': 'gpt-4o', 'llm_type': 'openai', 'async_mode': True}
25 | llm_config = {'llm_type': 'gemini', 'model': 'gemini-2.0-flash'}
26 | # llm_config = {"model": 'anthropic.claude-3-5-haiku-20241022-v1:0', "llm_type": 'bedrock'}
27 |
28 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
29 |
30 | prompt_template = PromptTemplate()
31 |
32 | browser_engine = BrowserEngine(
33 | llm=llm_client,
34 | prompt_template=prompt_template,
35 | # browser_instance_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
36 | )
37 | query_instruction = "Which team have 5 trophies in IPL"
38 |
39 | task = f"""
40 | 1. Analyse and find the result for the given {query_instruction}.
41 | 2. Goto https://x.com/compose/post and click and set focus. Wait until user manual login.
42 | 3. Write the a detail result.
43 | 3. Review the tweet before post it for submit.
44 | 4. Submit the button to tweet the result!
45 |
46 | Important:
47 | 1. DO NOT write the post as reply
48 | 2. DO NOT post more than one.
49 | 3. Strictly Follow the instructions
50 |
51 | """
52 |
53 | cricket_analyse_agent = Agent(
54 | goal="Complete user's task.",
55 | role="You are a Cricket Expert Reviewer",
56 | llm=llm_client,
57 | prompt_template=prompt_template,
58 | max_retry=1,
59 | engines=[browser_engine]
60 | )
61 |
62 | result = await cricket_analyse_agent.execute(
63 | query_instruction=task
64 | )
65 | rprint(result)
66 |
67 |
68 | if __name__ == '__main__':
69 | try:
70 | asyncio.run(main())
71 | except (KeyboardInterrupt, asyncio.CancelledError):
72 | rprint("\nUser canceled the [bold yellow][i]pipe[/i]!")
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/s3.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'S3 Handler'
3 | icon: 'bucket'
4 | ---
5 |
6 | Amazon S3 is a cloud storage service on AWS that lets you store different types of files, like photos, audio, and
7 | videos, as objects. It offers high scalability and security, making it easy to store and access any amount of data
8 | from anywhere, anytime. S3 also provides features like high availability, strong security, and smooth integration with
9 | other AWS services.
10 |
11 | ## Example
12 | To create the AWSHandler object creation with the aws credentials.
13 | The AWSS3Handler connects to an Amazon S3 bucket using access credentials
14 | (access key, secret key) and specifies a region and bucket name. It enables
15 | seamless interaction with S3 for tasks like uploading, downloading, and
16 | managing files.
17 |
18 | ```python s3_handler_test.py
19 | from superagentx_handlers.aws.s3 import AWSS3Handler
20 |
21 | s3_handler = AWSS3Handler(
22 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
23 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
24 | bucket_name="test",
25 | region_name="eu-central-1"
26 | )
27 | ```
28 | **File Upload:**
29 | The upload_file method accepts a file name and an object name.
30 | ```python
31 | await s3_handler.upload_file(
32 | file_name="test.txt",
33 | object_name="test.txt"
34 | )
35 | ```
36 | **List Buckets:**
37 | Returns a list of all buckets owned by the authenticated sender of the request.
38 | ```python
39 | buckets = await s3_handler.list_bucket()
40 | print(buckets)
41 | ```
42 |
43 | **Download File:**
44 | The Download_file method accepts a file download in the buckets
45 | ```python
46 |
47 | await s3_handler.download_file(
48 | file_name="test.txt",
49 | object_name="test.txt"
50 | )
51 | ```
52 | **List Objects in a Bucket:**
53 | The List object method shows list all object in the bucket
54 | ```python
55 | await s3_handler.list_objects(prefix="folder/")
56 | print(objects)
57 | ```
58 |
59 | **Delete an Object:**
60 | The Delete object can delete the object in the bucket
61 | ```python
62 | await s3_handler.delete_object(
63 | object_name="test.txt"
64 | )
65 | ```
66 | **Generate a Pre-Signed URL:**
67 | The method will generate_presigned_url for the account
68 | ```python
69 | await s3_handler.generate_presigned_url(
70 | object_name="test.txt",
71 | expiration=3600 # URL valid for 1 hour
72 | )
73 | print("Presigned URL:", url)
74 | ```
75 |
--------------------------------------------------------------------------------
/superagentx/memory/base.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 | from typing import Optional, Dict, Any
3 |
4 | from pydantic import BaseModel, Field
5 |
6 |
7 | class MemoryItem(BaseModel):
8 | id: str = Field(..., description="The unique identifier for the text data")
9 | memory: str = Field(
10 | ..., description="The memory deduced from the text data"
11 | )
12 | reason: str = Field(
13 | ..., description="The memory deduced from the text data"
14 | )
15 | role: str = Field(
16 | ..., description="The memory of role"
17 | )
18 | # The metadata value can be anything and not just string. Fix it
19 | metadata: Dict[str, Any] | None = Field(None, description="Additional metadata for the text data")
20 | score: float | None = Field(None, description="The score associated with the text data")
21 | created_at: Any | None = Field(None, description="The timestamp when the memory was created")
22 | updated_at: Any | None = Field(None, description="The timestamp when the memory was updated")
23 |
24 |
25 | class MemoryBase(ABC):
26 |
27 | @abstractmethod
28 | async def add(self, *args, **kwargs):
29 | """
30 | Add the data.
31 | """
32 | raise NotImplementedError
33 |
34 | @abstractmethod
35 | async def get(self, memory_id):
36 | """
37 | Retrieve a memory by ID.
38 |
39 | Args:
40 | memory_id (str): ID of the memory to retrieve.
41 |
42 | Returns:
43 | dict: Retrieved memory.
44 | """
45 | raise NotImplementedError
46 |
47 | @abstractmethod
48 | async def update(self, memory_id, data):
49 | """
50 | Update a memory by ID.
51 |
52 | Args:
53 | memory_id (str): ID of the memory to update.
54 | data (dict): Data to update the memory with.
55 |
56 | Returns:
57 | dict: Updated memory.
58 | """
59 | raise NotImplementedError
60 |
61 | @abstractmethod
62 | async def delete(self, memory_id):
63 | """
64 | Delete a memory by ID.
65 |
66 | Args:
67 | memory_id (str): ID of the memory to delete.
68 | """
69 | raise NotImplementedError
70 |
71 | @abstractmethod
72 | async def delete_by_conversation_id(self, conversation_id: str):
73 | """
74 | Delete a conversation by ID.
75 |
76 | Args:
77 | conversation_id (str): ID of the memory to delete.
78 | """
79 | raise NotImplementedError
80 |
--------------------------------------------------------------------------------
/tests/agent/test_mcp_sse_weather_agent.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import pytest
4 |
5 | from superagentx.agent import Agent
6 | from superagentx.engine import Engine
7 | from superagentx.handler.mcp import MCPHandler
8 | from superagentx.llm import LLMClient
9 | from superagentx.prompt import PromptTemplate
10 |
11 | logger = logging.getLogger(__name__)
12 |
13 | '''
14 | Run Pytest:
15 |
16 | 1. pytest --log-cli-level=INFO tests/agent/test_mcp_sse_weather_agent.py::TestMCPWeatherAgent::test_weather_search_agent
17 | '''
18 |
19 |
20 | @pytest.fixture
21 | def agent_client_init() -> dict:
22 | llm_config = {'model': 'gpt-4o', 'llm_type': 'openai'}
23 | # llm_config = {'model': 'anthropic.claude-3-5-sonnet-20240620-v1:0', 'llm_type': 'anthropic'}
24 |
25 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
26 | response = {'llm': llm_client, 'llm_type': 'openai'}
27 | return response
28 |
29 |
30 | class TestMCPWeatherAgent:
31 |
32 | @pytest.mark.asyncio
33 | async def test_weather_search_agent(self, agent_client_init: dict):
34 | llm_client: LLMClient = agent_client_init.get('llm')
35 |
36 | # MCP Tool - SSE
37 | mcp_handler = MCPHandler(sse_url="http://0.0.0.0:8080/sse")
38 |
39 | weather_analyst_prompt = """You're a Weather Analyst.
40 | 1. Identify Latitude & Longitude for the given State / City from the user's input query
41 | 2. For Forecast, you get accurate latitude & longitude for the given State or City.
42 | 3. For Weather alerts, convert city / state into TWO letter US code. Example CA, NY. Weather alerts, ONLY two letter
43 | US code should be passed!.
44 | """
45 | prompt_template = PromptTemplate(system_message=weather_analyst_prompt)
46 |
47 | # Enable Engine to execute MCP Tools
48 | mcp_engine = Engine(handler=mcp_handler, llm=llm_client,
49 | prompt_template=prompt_template)
50 |
51 | goal = """ Answer the weather alert or forcast report"""
52 |
53 | # SuperAgentX's Agent to run based on the goal
54 | weather_search_agent = Agent(goal=goal, role="You're a Weather Analyst", max_retry=1,
55 | llm=llm_client, prompt_template=prompt_template)
56 | await weather_search_agent.add(mcp_engine)
57 |
58 | # Ask Question and get results
59 | result = await weather_search_agent.execute(query_instruction="Get weather forecast for California!")
60 | logger.info(f'Result ==> {result}')
61 | assert result
62 |
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/rds.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'RDS Handler'
3 | icon: 'database'
4 | ---
5 |
6 | Amazon RDS (Relational Database Service) is a managed service that makes it easy to set up, operate, and scale relational databases in the cloud.
7 | It supports multiple engines like MySQL, PostgreSQL, MariaDB, Oracle, and SQL Server, and provides features such as automated backups, scaling, monitoring, and high availability.
8 |
9 |
10 | ## Example
11 |
12 | To create the **RDS Handler**, you must pass AWS credentials (`access_key`, `secret_key`, and `region`).
13 | This enables you to interact with RDS resources, clusters, proxies, and their associations with EC2.
14 |
15 | ```python
16 | import os
17 | from superagentx_handlers.aws.rds import AWSRDSHandler
18 |
19 | rds_handler = AWSRDSHandler(
20 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
21 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
22 | region_name="eu-central-1"
23 | )
24 | ```
25 | **Get RDS Association Details:**
26 | Provides a comprehensive inventory of RDS resources and their associations.
27 | ```python
28 | details = await rds_handler.get_rds_association_details()
29 | print(details)
30 | ```
31 |
32 | **List RDS Instances:**
33 | Fetches all RDS database instances in the account.
34 | ```python
35 | instances = await rds_handler.get_rds_instances()
36 | print(instances)
37 | ```
38 |
39 | **List RDS Clusters:**
40 | Fetches all Aurora RDS clusters.
41 | ```python
42 | clusters = await rds_handler.get_rds_clusters()
43 | print(clusters)
44 | ```
45 |
46 | **List RDS Proxies:**
47 | Fetches all RDS database proxies.
48 | ```python
49 | proxies = await rds_handler.get_rds_proxies()
50 | print(proxies)
51 | ```
52 |
53 | **Get Proxy Targets:**
54 | Retrieves targets associated with a specific RDS proxy.
55 | ```python
56 | targets = await rds_handler.get_proxy_targets(
57 | proxy_name="my-rds-proxy"
58 | )
59 | print(targets)
60 | ```
61 |
62 | **Get EC2 Associations:**
63 | Finds EC2 instances that are associated with RDS security groups.
64 | ```python
65 | associations = await rds_handler.get_ec2_associations(
66 | rds_instances=instances
67 | )
68 | print(associations)
69 | ```
70 |
71 | **Get Backup Configuration:**
72 | Fetches backup details such as retention period, backup window, and maintenance window for an RDS instance or cluster.
73 | ```python
74 | backup = await rds_handler.get_backup_config(
75 | db_identifier="my-db-instance",
76 | is_cluster=False # set True for clusters
77 | )
78 | print(backup)
79 | ```
--------------------------------------------------------------------------------
/superagentx_cli/templates/pipe.py.jinja2:
--------------------------------------------------------------------------------
1 | {# templates/pipe.py.jinja2 #}
2 | from superagentx.agent import Agent
3 | from superagentx.agentxpipe import AgentXPipe
4 | from superagentx.engine import Engine
5 | from superagentx.llm import LLMClient
6 | from superagentx.memory import Memory
7 | from superagentx.prompt import PromptTemplate
8 |
9 | # Import handlers
10 |
11 | # Example
12 | # -------
13 | #################################################
14 | # Uncomment below lines to enable ecom handlers #
15 | #################################################
16 | # from superagentx_handlers import AmazonHandler
17 | # from superagentx_handlers.ecommerce.walmart import WalmartHandler
18 |
19 |
20 | async def get_{{ pipe_name }}_pipe() -> AgentXPipe:
21 | # LLM Configuration
22 | llm_config = {
23 | 'llm_type': 'openai'
24 | }
25 | llm_client = LLMClient(llm_config=llm_config)
26 |
27 | # Enable Memory
28 | memory = Memory(memory_config={"llm_client": llm_client})
29 |
30 | # Example
31 | # -------
32 | # amazon_ecom_handler = AmazonHandler()
33 | # walmart_ecom_handler = WalmartHandler()
34 |
35 | # Prompt Template
36 | prompt_template = PromptTemplate()
37 |
38 | # Example - Engine(s)
39 | # -------------------
40 | # amazon_engine = Engine(
41 | # handler=amazon_ecom_handler,
42 | # llm=llm_client,
43 | # prompt_template=prompt_template
44 | # )
45 | # walmart_engine = Engine(
46 | # handler=walmart_ecom_handler,
47 | # llm=llm_client,
48 | # prompt_template=prompt_template
49 | # )
50 |
51 | # Create Agents
52 |
53 | # Example - Agent(s)
54 | # ------------------
55 | # Create Agent with Amazon, Walmart Engines execute in Parallel - Search Products from user prompts
56 | # ecom_agent = Agent(
57 | # name='Ecom Agent',
58 | # goal="Get me the best search results",
59 | # role="You are the best product searcher",
60 | # llm=llm_client,
61 | # prompt_template=prompt_template,
62 | # engines=[[amazon_engine, walmart_engine]]
63 | # )
64 |
65 | # Create Pipe - Interface
66 |
67 | # Pipe Interface to send it to public accessible interface (Cli Console / WebSocket / Restful API)
68 | pipe = AgentXPipe(
69 | ###############################################
70 | # Uncomment below lines to enable ecom agents #
71 | ###############################################
72 | # agents=[ecom_agent],
73 | memory=memory
74 | )
75 | return pipe{{'\n'}}
--------------------------------------------------------------------------------
/docs/examples/handlers/aws/ec2.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'EC2 Handler'
3 | icon: 'server'
4 | ---
5 |
6 | Amazon EC2 (Elastic Compute Cloud) is a service that provides secure, resizable compute capacity in the cloud.
7 | It allows you to launch virtual servers (instances), manage storage volumes, security groups, and networking configurations.
8 | With the EC2 handler, you can programmatically retrieve and manage EC2 resources such as instances, volumes, AMIs, snapshots, and more.
9 |
10 | ## Example
11 | To create the AWSEC2Handler object with AWS credentials.
12 | The AWSEC2Handler connects to AWS EC2 using access credentials (access key, secret key) and a region name.
13 | It enables seamless interaction with EC2 for retrieving and managing compute resources.
14 |
15 | ```python ec2_handler_test.py
16 | import os
17 | from superagentx_handlers.aws.ec2 import AWSEC2Handler
18 |
19 | ec2_handler = AWSEC2Handler(
20 | aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
21 | aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
22 | region_name="eu-central-1"
23 | )
24 | ```
25 | **Get Instances:**
26 | The get_instances method fetches all EC2 instances.
27 | ```python
28 | await ec2_handler.get_instances()
29 | print(instances)
30 | ```
31 |
32 | **Get Security Groups:**
33 | The get_security_groups method fetches all security groups.
34 | ```python
35 | await ec2_handler.get_security_groups()
36 | print(security_groups)
37 | ```
38 |
39 | **Get Volumes:**
40 | The get_volumes method fetches all EBS volumes.
41 | ```python
42 | await ec2_handler.get_volumes()
43 | print(volumes)
44 | ```
45 |
46 | **Get AMIs:**
47 | The get_amis method fetches all AMIs owned by the account.
48 | ```python
49 | await ec2_handler.get_amis()
50 | print(amis)
51 | ```
52 |
53 | **Get Snapshots:**
54 | The get_snapshots method fetches all snapshots owned by the account.
55 | ```python
56 | await ec2_handler.get_snapshots()
57 | print(snapshots)
58 | ```
59 |
60 | **Get Key Pairs:**
61 | The get_key_pairs method fetches all key pairs.
62 | ```python
63 | key_pairs = await ec2_handler.get_key_pairs()
64 | print(key_pairs)
65 | ```
66 |
67 | **Get Network Interfaces:**
68 | The get_network_interfaces method fetches all network interfaces.
69 | ```python
70 | network_interfaces = await ec2_handler.get_network_interfaces()
71 | print(network_interfaces)
72 | ```
73 |
74 | **Collect All EC2 Resources:**
75 | The collect_all_ec2 method fetches all EC2 resources in parallel.
76 | ```python
77 | await ec2_handler.collect_all_ec2()
78 | print(all_ec2_data)
79 | ```
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "superagentx"
3 | version = "1.0.2b1"
4 | description = "The Ultimate Modular Autonomous Multi AI Agent Framework."
5 | license = { text = "MIT" }
6 | authors = [
7 | { name = "SuperAgentX AI", email = ""},
8 | ]
9 | maintainers = [
10 | { name = "SuperAgentX AI", email = ""},
11 | ]
12 | readme = "README.md"
13 |
14 | keywords = ["superagentX", "AGI", "Agentic AI", "ASI", "superagentx", "agent", "LLM", "cli"]
15 | requires-python = ">=3.12,<=3.13"
16 |
17 | dependencies = [
18 | "pydantic>=2.8.2",
19 | "openai>=1.47.1",
20 | "litellm>=1.79.0",
21 | "exa-py>=1.1.4",
22 | "aiohttp>=3.10.8",
23 | "rich>=13.9.2",
24 | "aiosqlite>=0.20.0",
25 | "websockets (>=15.0.1,<16.0.0)",
26 | "aiofiles>=24.1.0",
27 | "camel-converter>=4.0.1",
28 | "yapf (>=0.43.0,<0.44.0)",
29 | "httpx (>=0.28.1,<0.29.0)",
30 | "mcp (>=1.7.0,<2.0.0)",
31 | "aiopath (==0.7.7)",
32 | "markdownify (>=1.1.0)",
33 | "psutil (>=7.0.0 )",
34 | "playwright (>=1.52.0)",
35 | "pyyaml (>=6.0.2)",
36 | "importlib-resources (>=6.5.2)",
37 | "pyotp (>=2.9.0)",
38 | "ntplib (>=0.4.0)"
39 | ]
40 |
41 | [project.urls]
42 | homepage = "https://www.superagentx.ai/"
43 | repository = "https://github.com/superagentxai/superagentx"
44 | documentation = "https://docs.superagentx.ai/"
45 |
46 | [project.scripts]
47 | superagentx-cli = "superagentx_cli.main:app"
48 | superagentx-app = "superagentx_cli.cli_app:app"
49 |
50 | [project.optional-dependencies]
51 | cli = [
52 | "jinja2>=3.1.4",
53 | "typer>=0.13.0",
54 | "rich>=13.9.2",
55 | "yapf>=0.43.0"
56 | ]
57 | all =[
58 | # Cli
59 | "jinja2>=3.1.4",
60 | "typer>=0.13.0",
61 | "rich>=13.9.2",
62 | "yapf>=0.43.0",
63 | # All
64 | "bokeh>=3.7.3",
65 | "neo4j>=5.28.1",
66 | "opensearch-py>=2.8.0",
67 | "scipy>=1.15.3",
68 | "elasticsearch>=9.0.1",
69 | "numpy>=2.2.6",
70 | "ollama>=0.4.7",
71 | "fastembed>=0.6.0",
72 | "chromadb>=1.0.10",
73 | "opentelemetry-exporter-otlp-proto-grpc>=1.33.1",
74 | "boto3>=1.35.8",
75 | "google-genai>=1.20.0"
76 | ]
77 |
78 | [tool.poetry]
79 | packages = [
80 | { include = "superagentx" },
81 | { include = "superagentx_cli" }
82 | ]
83 |
84 | [tool.poetry.group.test.dependencies]
85 | pytest = "^8.3.3"
86 | pytest-asyncio = "^0.24.0"
87 |
88 | [tool.pytest.ini_options]
89 | asyncio_mode = "auto"
90 |
91 | [build-system]
92 | requires = ["poetry-core>=2.0.0,<3.0.0"]
93 | build-backend = "poetry.core.masonry.api"
94 |
--------------------------------------------------------------------------------
/docs/examples/handlers/Gcp/security_role.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Security Role Handler'
3 | icon: 'shield'
4 | ---
5 |
6 | The **GcpSecurityRoleHandler** is a specialized handler for Google Cloud Platform (GCP) that helps collect comprehensive **security and IAM-related information**.
7 | It focuses on discovering and retrieving IAM policies, service accounts, and custom roles across **organizations, folders, and projects**.
8 |
9 | This is particularly useful for compliance, governance, and security evidence collection across multiple levels of the GCP resource hierarchy.
10 |
11 |
12 |
13 | ## Example
14 |
15 | To create the handler, pass in your GCP **service account credentials** (either as a JSON dict/string or use the environment variable `GOOGLE_APPLICATION_CREDENTIALS` pointing to your JSON key file).
16 |
17 | ```python
18 | import os
19 | from superagentx_handlers.gcp.security_role import GcpSecurityRoleHandler
20 |
21 | gcp_handler = GcpSecurityRoleHandler(
22 | service_account_info=os.getenv("GCP_SERVICE_ACCOUNT_JSON")
23 | )
24 | ```
25 |
26 | **Collect Organization IAM Policies:**
27 | Retrieves IAM policies for all accessible organizations.
28 | ```python
29 | org_policies = await gcp_handler.collect_organization_iam()
30 | print(org_policies)
31 | ```
32 |
33 | **Collect Folder IAM Policies:**
34 | Fetches IAM policies for all folders under an organization or another folder.
35 | ```python
36 | folder_policies = await gcp_handler.collect_folder_iam(organization_id="1234567890")
37 | print(folder_policies)
38 | ```
39 |
40 | **Collect Project IAM Policies:**
41 | Retrieves IAM policies for specific projects or all accessible projects.
42 | ```python
43 | project_policies = await gcp_handler.collect_project_iam(project_id="my-gcp-project")
44 | print(project_policies)
45 | ```
46 |
47 | **Collect Service Accounts:**
48 | Lists service accounts in a given project.
49 | ```python
50 | service_accounts = await gcp_handler.collect_service_accounts(project_id="my-gcp-project")
51 | print(service_accounts)
52 | ```
53 |
54 | **Collect Custom Roles:**
55 | Fetches custom IAM roles at the project or organization level.
56 | ```python
57 | custom_roles = await gcp_handler.collect_custom_roles(project_id="my-gcp-project")
58 | print(custom_roles)
59 | ```
60 |
61 | **Collect All Security Information:**
62 | Performs a comprehensive security collection across IAM policies, service accounts, and custom roles for an organization or project.
63 | ```python
64 | security_info = await gcp_handler.collect_all_security_info(organization_id="1234567890")
65 | print(security_info.keys())
66 | ```
--------------------------------------------------------------------------------
/docs/introduction.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | icon: house
4 | ---
5 |
6 | **SuperAgentX**: A Lightweight Open Source AI Framework Built for Autonomous Multi-Agent Applications with Artificial General Intelligence (AGI) Capabilities.
7 |
8 | ## Why SuperAgentX?
9 |
10 | **Super** : Advanced AI systems with extraordinary capabilities, pioneering the path to AGI (Artificial General Intelligence) and ASI (Artificial Super Intelligence).
11 |
12 | **Agent** : Autonomous Multi AI agent framework designed to make decisions, act independently, and handle complex tasks.
13 |
14 | **X** : The unknown, the limitless, the extra factor that makes SuperAgentX revolutionary, futuristic, and transformative.
15 |
16 |
17 |
18 |
19 |
20 | ***SuperAgentX Features***
21 |
22 | 🚀 **Open-Source Framework**: A lightweight, open-source AI framework built for multi-agent applications with Artificial General Intelligence (AGI) capabilities.
23 |
24 | 🏖️ **Easy Deployment**: Offers WebSocket, RESTful API, IO console and Voice interfaces for rapid setup of agent-based AI solutions.
25 |
26 | ♨️ **Streamlined Architecture**: No major dependencies; built independently.
27 |
28 | 📚 **Contextual Memory**: Uses SQL + Vector databases to store and retrieve user-specific context effectively.
29 |
30 | 🧠 **Flexible LLM Configuration**: Supports simple configuration options of various Gen AI models.
31 |
32 | 🤝🏻 **Extendable Handlers**: Allows integration with diverse APIs, databases, data warehouses, data lakes, IoT streams, and more, making them accessible for function-calling features.
33 |
34 | 🎯 **Goal-Oriented Agents**: Enables the creation of agents with retry mechanisms to achieve set goals.
35 |
36 | It provides a powerful, modular, and flexible platform for building autonomous AI agents capable of executing complex tasks with minimal human intervention.
37 | By integrating cutting-edge AI technologies and promoting efficient, scalable agent behavior, SuperAgentX embodies a critical step forward in the path towards superintelligence and AGI.
38 | Whether for research, development, or deployment, SuperAgentX is built to push the boundaries of what is possible with autonomous AI systems.
39 |
40 |
41 |
42 |
47 | SuperAgentX installation procedures
48 |
49 |
54 | Create Your Awesome Multi-Agent Use cases with SuperAgentX
55 |
56 |
57 |
--------------------------------------------------------------------------------
/docs/examples/handlers/exa.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Exa Search Handler'
3 | icon: 'draw-polygon'
4 | ---
5 |
6 | Exa helps you locate precise content online using embeddings-based search. Its API offers three key features:
7 |
8 | >**Page Search:** Find web pages through natural language queries, with an option to use traditional keyword searches
9 | if needed.
**Content Extraction:** Access clean, parsed HTML from search results, with the option to focus on
10 | relevant sections using the highlights feature.
**Similar Page Discovery:** Input a link to identify and retrieve
11 | pages with related content or meaning.
12 |
13 | ## Example
14 | This code sets up an ExaHandler to perform a search using an API key. It retrieves content based on the provided query,
15 | automatically determining the search type and returning up to five results, making it easy to find relevant information
16 | quickly.
17 |
18 | To access ExaSearch services, you'll need to create an ExaSearch account, obtain an API key, and subscribe to the
19 | required API for your application. For more details, refer to the
20 | ExaSearch documentation.
21 |
22 | >Set up a Exa API key as an environmental variable and run the following code.
23 |
24 | ```python
25 | export EXA_API_KEY = "**************************"
26 | ```
27 |
28 | ```python exa_handler.py
29 | import os
30 | import asyncio
31 |
32 | from superagentx.handler.exa_search import ExaHandler
33 |
34 |
35 | async def search_contents(query):
36 | exa_handler = ExaHandler()
37 | return await exa_handler.search_contents(
38 | query=query,
39 | search_type="auto",
40 | use_autoprompt=True,
41 | num_results=5,
42 | )
43 |
44 |
45 | async def main(query):
46 | res = await search_contents(query)
47 | print(res)
48 |
49 | if __name__ == '__main__':
50 | query = "What is Agentic AI Framework?"
51 | asyncio.run(main(query))
52 | ```
53 |
54 | ## Result
55 |
56 | ```log exa search
57 | URL: https://aima.eecs.berkeley.edu/2nd-ed/ai.html
58 | ID: http://aima.eecs.berkeley.edu/2nd-ed/ai.html
59 | Score: 0.19881151616573334
60 | Published Date: 2006-09-12T00:00:00.000Z
61 | Author:
62 | Image: None
63 | Text: This page links to 849 pages around the web with
64 | information on Artificial Intelligence. Links in Bold* followed by a star are especially useful
65 | and interesting sites. Links with a + sign at the end have "tooltip"
66 | information that will pop up if you put your mouse over the link for a
67 | second or two. If you have new links to add, mail them to peter@norvig.com.
68 | ```
69 |
--------------------------------------------------------------------------------
/docs/examples/handlers/scrape.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Scrape Handler'
3 | icon: 'spider'
4 | ---
5 |
6 | A scrape handler is a tool or part of a program that helps you "scrape" data from websites. When you want to collect
7 | information from a webpage, like product prices, weather data, or news headlines, a scrape handler is the part of the
8 | system that goes to the website, gets the data, and then processes it for you.
9 |
10 | ```python scrape_handler.py
11 | import asyncio
12 |
13 | from superagentx_handlers.scrape import ScrapeHandler
14 |
15 |
16 | async def scrap_content() -> ScrapeHandler:
17 | scrap_handler = ScrapeHandler()
18 | return await scrap_handler.scrap_content(domain_urls=["https://www.booking.com/"])
19 |
20 |
21 | async def main():
22 | res = await scrap_content()
23 | print(res)
24 |
25 | if __name__ == '__main__':
26 | asyncio.run(main())
27 | ```
28 |
29 | ### Result
30 | ```shell
31 |
32 | Synchronous WebCrawler is not available. Install crawl4ai[sync] for synchronous support. However,
33 | please note that the synchronous version will be deprecated soon.
34 | [LOG] 🌤️ Warming up the AsyncWebCrawler
35 | [LOG] 🌞 AsyncWebCrawler is ready to crawl
36 | [LOG] 🕸️ Crawling https://www.booking.com/ using AsyncPlaywrightCrawlerStrategy...
37 | [LOG] ✅ Crawled https://www.booking.com/ successfully!
38 | [LOG] 🚀 Crawling done for https://www.booking.com/, success: True, time taken: 5.25 seconds
39 | [LOG] 🚀 Content extracted for https://www.booking.com/, success: True, time taken: 0.78 seconds
40 | [LOG] 🔥 Extracting semantic blocks for https://www.booking.com/, Strategy: AsyncWebCrawler
41 | [LOG] 🚀 Extraction done for https://www.booking.com/, time taken: 0.78 seconds.
42 | ['[ Skip to main content ](#indexsearch)\n\n[](https://www.booking.com/index.en-gb.html?label=gen173nr-
43 | 1BCAEoggI46AdIM1gEaGyIAQGYAQm4ARfIAQzYAQHoAQGIAgGoAgO4At7Q67kGwAIB0gIkMjhlOTViMzAtOWI3Yy00NTM4LWEwNmEtOD
44 | I5NWJjMWFjOWJi2AIF4AIB&sid=e80cd7587c79910cad64ebb4460be87c&aid=304142)\n\nINR\n\n\n\n[](https://secure.booking.com/help.en-gb.html
46 | ?label=gen173nr-1BCAEoggI46AdIM1gEaGyIAQGYAQm4ARfIAQzYAQHoAQGIAgGoAgO4At7Q67kGwAIB0gIkMjhlOTViMzAtOWI3Yy00NT
47 | M4LWEwNmEtODI5NWJjMWFjOWJi2AIF4AIB&sid=e80cd7587c79910cad64ebb4460be87c&aid=304142&source=header&src=profile_
48 | contact_cs)[List your property](https://join.booking.com/?label=gen173nr-1BCAEoggI46AdIM1gEaGyIAQGYAQm4ARfIAQz
49 | YAQHoAQGIAgGoAgO4At7Q67kGwAIB0gIkMjhlOTViMzAtOWI3Yy00NTM4LWEwNmEtODI5NWJjMWFjOWJi2AIF4AIB&sid=e80cd7587c79910ca
50 | d64ebb4460be87c&aid=304142&lang=en-gb&utm_medium=frontend&utm_source=topbar)
51 |
52 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/financial_data.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Financial Data Handler'
3 | icon: 'chart-mixed-up-circle-dollar'
4 | ---
5 |
6 | The Financial Data Handler is a tool that helps get important financial information from online sources.
7 | It allows businesses or individuals to easily access real-time data like stock prices, company financial
8 | details, and income statements. This information can be used for tracking market trends, analyzing a
9 | company’s performance, or making better investment decisions.
10 |
11 | Refer the link to know more details about symbol from the document
12 | here.
13 |
14 | ## Example
15 | This code sets up a FinancialHandler to access financial data using an API key and specifies the stock symbol for Amazon
16 | (AMZN). This allows for retrieving stock market information and other financial data programmatically.
17 |
18 | To use Financial Modeling, you'll need to create an Financial Modeling account and get an API key. For more details refer here.
19 |
20 | >Set up a FINANCIAL_DATA_API_KEY key as an environmental variable and run the following code.
21 | ```python
22 | export FINANCIAL_DATA_API_KEY = "**************************"
23 | ```
24 |
25 | ```python financial_handler.py
26 | import os
27 | import asyncio
28 |
29 | from superagentx.handler.financial_data import FinancialHandler
30 |
31 |
32 | async def get_stock_price():
33 | financial_handler = FinancialHandler(
34 | symbol='AMZN'
35 | )
36 | return await financial_handler.get_stock_price()
37 |
38 |
39 | async def main():
40 | res = await get_stock_price()
41 | print(res)
42 |
43 | if __name__ == '__main__':
44 | asyncio.run(main())
45 | ```
46 | ## Result
47 | ```inline Stock price Output:
48 | {
49 | "data": [
50 | {
51 | "symbol": "AA",
52 | "name": "Alcoa Corporation",
53 | "price": 41.71,
54 | "changesPercentage": 3.3705,
55 | "change": 1.36,
56 | "dayLow": 40.86,
57 | "dayHigh": 42.1659,
58 | "yearHigh": 45.48,
59 | "yearLow": 23.07,
60 | "marketCap": 10775361358,
61 | "priceAvg50": 34.709,
62 | "priceAvg200": 34.4335,
63 | "exchange": "NYSE",
64 | "volume": 4489893,
65 | "avgVolume": 6216657,
66 | "open": 41.77,
67 | "previousClose": 40.35,
68 | "eps": -1.56,
69 | "pe": -26.74,
70 | "earningsAnnouncement": "2025-01-15T05:00:00.000+0000",
71 | "sharesOutstanding": 258339999,
72 | "timestamp": 1729281602
73 | }
74 | ]
75 | }
76 |
77 | ```
78 |
--------------------------------------------------------------------------------
/docs/examples/handlers/Gcp/iam.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'IAM Handler'
3 | icon: 'shield'
4 | ---
5 |
6 | Google Cloud IAM (Identity and Access Management) allows you to securely manage access to your GCP resources.
7 | It provides fine-grained controls for organizations, folders, and projects, ensuring that only authorized users and services can access resources.
8 |
9 | With the **GCPIAMHandler**, you can fetch IAM policy details across organizations, folders, and projects, and also collect MFA-related evidence to strengthen compliance and security posture.
10 |
11 | It helps with:
12 | - Discovering IAM policies for GCP organizations, folders, and projects.
13 | - Checking roles, bindings, and enforced conditions like MFA.
14 | - Building a full compliance picture of your GCP environment.
15 |
16 |
17 | ## Example
18 | ### Initialization
19 |
20 | To create a handler with your service account credentials:
21 |
22 | ```python
23 | from superagentx_handlers.gcp.iam import GCPIAMHandler
24 |
25 | iam_handler = GCPIAMHandler(
26 | creds="service_account.json", # path to service account json
27 | scope=["https://www.googleapis.com/auth/cloud-platform"]
28 | )
29 | ```
30 |
31 | **Collect Organization IAM Evidence:**
32 | Fetch IAM policy evidence for all accessible GCP organizations.
33 | ```python
34 | org_evidence = await iam_handler.collect_organization_iam_evidence()
35 | print(org_evidence)
36 | ```
37 |
38 | **Collect Folder IAM Evidence:**
39 | Fetch IAM policy evidence for folders under a specific organization or folder.
40 | ```python
41 | folder_evidence = await iam_handler.collect_folder_iam_evidence(
42 | parent_resource="organizations/123456789"
43 | )
44 | print(folder_evidence)
45 | ```
46 |
47 | **Collect Project IAM Evidence:**
48 | Fetch IAM policies for projects under an organization or folder.
49 | ```python
50 | project_evidence = await iam_handler.collect_project_iam_evidence(
51 | parent_resource="folders/987654321"
52 | )
53 | print(project_evidence)
54 | ```
55 |
56 | **Collect All IAM Evidence:**
57 | Collects IAM evidence across organizations, folders, and projects in one run.
58 | ```python
59 | all_evidence = await iam_handler.collect_all_iam_evidence()
60 | print(all_evidence)
61 | ```
62 |
63 | **_get_resource_iam_policy(resource_name: str, resource_type: str):**
64 | Internal method that retrieves IAM policy details for a specific resource (organization, folder, or project).
65 | It returns information about roles, members, bindings, conditions, and MFA enforcement.
66 | ```python
67 | policy = await iam_handler._get_resource_iam_policy(
68 | resource_name="projects/my-project-123",
69 | resource_type="project"
70 | )
71 | print(policy)
72 | ```
73 |
--------------------------------------------------------------------------------
/tests/llm/test_gemini_client.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import pytest
4 |
5 | from superagentx.llm import LLMClient
6 | from superagentx.llm.gemini import GeminiClient
7 | from superagentx.llm.models import ChatCompletionParams
8 |
9 | logger = logging.getLogger(__name__)
10 |
11 | '''
12 | Run Pytest:
13 |
14 | 1. pytest --log-cli-level=INFO tests/llm/test_gemini_client.py::TestGeminiClient::test_gemini_chat_completion
15 | 2. pytest --log-cli-level=INFO tests/llm/test_gemini_client.py::TestGeminiClient::test_gemini_achat_completion
16 | '''
17 |
18 | # Define the function declaration for the model
19 | weather_function = [{
20 | "name": "get_current_temperature",
21 | "description": "Gets the current temperature for a given location.",
22 | "parameters": {
23 | "type": "object",
24 | "properties": {
25 | "location": {
26 | "type": "string",
27 | "description": "The city name, e.g. San Francisco",
28 | },
29 | },
30 | "required": ["location"],
31 | },
32 | }]
33 |
34 | # Start a conversation with the user message.
35 | user_message = "What's the temperature in London?"
36 |
37 | content = [
38 | {
39 | "role": "user",
40 | "content": user_message
41 | }
42 | ]
43 |
44 |
45 | @pytest.fixture
46 | def gemini_client_init() -> dict:
47 | llm_config = {'llm_type': 'gemini', 'model': 'gemini-2.0-flash'}
48 | llm_client: LLMClient = LLMClient(llm_config=llm_config)
49 | response = {'llm': llm_client}
50 | return response
51 |
52 |
53 | class TestGeminiClient:
54 |
55 | async def test_gemini_client(self, gemini_client_init: dict):
56 | llm_client: LLMClient = gemini_client_init.get('llm').client
57 | assert isinstance(llm_client, GeminiClient)
58 |
59 | @pytest.mark.asyncio
60 | async def test_gemini_chat_completion(self, gemini_client_init: dict):
61 | llm_client: LLMClient = gemini_client_init.get('llm')
62 |
63 | chat_completion_params = ChatCompletionParams(
64 | messages=content,
65 | tools=weather_function
66 | )
67 |
68 | response = llm_client.chat_completion(chat_completion_params=chat_completion_params)
69 | logger.info(response)
70 |
71 | @pytest.mark.asyncio
72 | async def test_gemini_achat_completion(self, gemini_client_init: dict):
73 | llm_client: LLMClient = gemini_client_init.get('llm')
74 |
75 | chat_completion_params = ChatCompletionParams(
76 | messages=content,
77 | tools=weather_function
78 | )
79 |
80 | response = await llm_client.achat_completion(chat_completion_params=chat_completion_params)
81 | logger.info(response)
82 |
83 |
--------------------------------------------------------------------------------
/superagentx/io/console.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | from rich import print as rprint
4 | from rich.console import Console
5 | from rich.prompt import Prompt
6 |
7 | from superagentx.io.base import IOStream
8 |
9 |
10 | class IOConsole(IOStream):
11 | """A console input/output stream."""
12 |
13 | def __init__(
14 | self,
15 | read_phrase: str | None = None,
16 | write_phrase: str | None = None
17 | ):
18 | self.read_phrase = read_phrase or ''
19 | self.write_phrase = write_phrase or ''
20 | self._console = Console()
21 |
22 | def __repr__(self):
23 | return self.__str__()
24 |
25 | def __str__(self):
26 | return ""
27 |
28 | async def write(
29 | self,
30 | *objects: Any,
31 | sep: str | None = None,
32 | end: str | None = None,
33 | flush: bool = False
34 | ) -> None:
35 | """Print data to the output stream.
36 |
37 | Args:
38 | objects (any): The data to print.
39 | sep (str, optional): The separator between objects. Defaults to " ".
40 | end (str, optional): The end of the output. Defaults to "\n".
41 | flush (bool, optional): Whether to flush the output. Defaults to False.
42 | """
43 | sep = sep or " "
44 | end = end or "\n"
45 | rprint(
46 | self.write_phrase,
47 | *objects,
48 | sep=sep,
49 | end=end,
50 | )
51 |
52 | async def read(
53 | self,
54 | prompt: str | None = None,
55 | *,
56 | password: bool = False
57 | ) -> str:
58 | """Read a line from the input stream.
59 |
60 | Args:
61 | prompt (str, optional): The prompt to display. Defaults to "".
62 | password (bool, optional): Whether to read a password. Defaults to False.
63 |
64 | Returns:
65 | str: The line read from the input stream.
66 |
67 | """
68 | prompt = prompt or self.read_phrase
69 | return Prompt.ask(
70 | prompt=prompt,
71 | console=self._console,
72 | password=password
73 | )
74 |
75 | async def rule(
76 | self,
77 | title: str
78 | ):
79 | self._console.rule(title)
80 |
81 | async def json(
82 | self,
83 | data: list | dict
84 | ):
85 | self._console.print_json(data=data)
86 |
87 | async def status(
88 | self,
89 | status_msg: str
90 | ):
91 | return self._console.status(
92 | status_msg,
93 | spinner='bouncingBall'
94 | )
95 |
--------------------------------------------------------------------------------
/docs/examples/handlers/azure/iam.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Entra IAM Handler'
3 | icon: 'shield'
4 | ---
5 |
6 | Microsoft Entra IAM (Identity and Access Management) is part of Microsoft Entra ID (formerly Azure Active Directory). It helps manage **users, groups, applications, roles, and MFA (multi-factor authentication)**. Using Microsoft Graph APIs, you can collect IAM evidence for governance, compliance, and auditing purposes.
7 |
8 | This handler provides methods to retrieve IAM data like users, groups, service principals (applications), role definitions, and MFA status.
9 |
10 |
11 | ## Example
12 |
13 | To create the **EntraIAMHandler** object, initialize it with your **Entra Tenant ID, Client ID, and Client Secret** (or load them from environment variables).
14 |
15 | ```python
16 | import os
17 | from superagentx_handlers.azure.iam import EntraIAMHandler
18 |
19 | entra_handler = EntraIAMHandler(
20 | tenant_id=os.getenv("ENTRA_TENANT_ID"),
21 | client_id=os.getenv("ENTRA_CLIENT_ID"),
22 | client_secret=os.getenv("ENTRA_CLIENT_SECRET")
23 | )
24 | ```
25 | **Collect Users IAM Evidence:**
26 | Fetches all users and their IAM-related details (display name, UPN, email, type, assigned roles).
27 | Requires User.Read.All and optionally RoleManagement.Read.All.
28 | ```python
29 | users = await entra_handler.collect_users_iam_evidence()
30 | print(users)
31 | ```
32 |
33 | **Collect Groups IAM Evidence:**
34 | Fetches all groups and their members (users, devices, service principals).
35 | Requires Group.Read.All.
36 | ```python
37 | groups = await entra_handler.collect_groups_iam_evidence()
38 | print(groups)
39 | ```
40 |
41 | **Collect Applications IAM Evidence (Service Principals):**
42 | Retrieves all applications (service principals) and their owners.
43 | Requires Application.Read.All.
44 | ```python
45 | apps = await entra_handler.collect_applications_iam_evidence()
46 | print(apps)
47 | ```
48 |
49 | **Collect Role Definitions:**
50 | Retrieves all built-in and custom role definitions available in Microsoft Entra ID.
51 | Requires RoleManagement.Read.Directory.
52 | ```python
53 | roles = await entra_handler.collect_roles_definitions()
54 | print(roles)
55 | ```
56 |
57 | **Collect MFA Status Evidence:**
58 | Collects MFA registration status and recent MFA usage from sign-in logs for users.
59 | Requires Reports.Read.All, UserAuthenticationMethod.Read.All, and AuditLog.Read.All.
60 | ```python
61 | mfa = await entra_handler.collect_mfa_status_evidence(days_ago=30)
62 | print(mfa)
63 | ```
64 |
65 | **Collect All entra IAM Evidence (Summary):**
66 | Fetches users, groups, applications, roles, and MFA evidence in a single call.
67 | ```python
68 | all_evidence = await entra_handler.collect_all_entra_iam_evidence()
69 | print(all_evidence)
70 | ```
--------------------------------------------------------------------------------
/docs/examples/handlers/openapi.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Openapi Handler'
3 | icon: 'webhook'
4 | ---
5 |
6 | The OpenAPIHandler class provides a simple way to interact with APIs that follow the OpenAPI specification.
7 | It allows you to load the OpenAPI specification from either a URL or a local file in JSON or YAML format.
8 | You can easily retrieve all available API endpoints, get the supported HTTP methods for each endpoint,
9 | and view detailed information about specific operations. The class also includes a call_endpoint method
10 | that makes it easy to send API requests with customizable parameters, request bodies, and headers. This
11 | makes the OpenAPIHandler class a powerful tool for automating interactions with APIs in a Python-based workflow.
12 |
13 | ```python openapi_handler.py
14 | import asyncio
15 |
16 | from superagentx.handler.openapi import OpenAPIHandler
17 |
18 | async def openapi_handler():
19 | openapi_handler = OpenAPIHandler(
20 | base_url='https://petstore.swagger.io/v2/',
21 | spec_url_path='swagger.json'
22 | )
23 |
24 | return await openapi_handler.call_endpoint(
25 | endpoint="/pet/findByStatus",
26 | method="GET",
27 | params={'status': 'sold'})
28 |
29 | async def main():
30 | res = await create_contact()
31 | print(res)
32 |
33 | if __name__ == '__main__':
34 | asyncio.run(main())
35 |
36 | ```
37 |
38 | ## Result
39 | ```shell
40 |
41 | platform linux -- Python 3.12.3, pytest-8.3.3, pluggy-1.5.0
42 | rootdir: /home/ram/Projects/superagentX
43 | configfile: pyproject.toml
44 | plugins: asyncio-0.24.0, anyio-4.6.2.post1
45 | asyncio: mode=Mode.AUTO, default_loop_scope=None
46 | collected 1 item
47 |
48 | tests/handlers/test_openapi_spec_handler.py::TestOpenAPIHandler::test_openapi_handler
49 | INFO tests.handlers.test_openapi_spec_handler:test_openapi_spec_handler.py:30 Response
50 | [{'id': 360274, 'category': {'id': 126898, 'name': 'tbhBBPKt'}, 'name': 'doggie', 'photoUrls': ['AcPwDp'],
51 | 'tags': [{'id': 530594, 'name': 'cgAhLGLz'}], 'status': 'sold'}, {'id': 7, 'category': {'id': 51, 'name': 'cat'},
52 | 'name': 'Milo', 'photoUrls': ['string'], 'tags': [{'id': 871, 'name': 'siamese'}], 'status': 'sold'}, {'id': 13,
53 | 'category': {'id': 0, 'name': 'cats'}, 'photoUrls': ['string'], 'tags': [{'id': 0, 'name': 'string'}], 'status': 'sold'},
54 | {'id': 102, 'category': {'id': 102, 'name': 'Qwerty'}, 'name': 'Mufasa', 'photoUrls': ['string'], 'tags': [{'id': 102,
55 | 'name': 'Mufasa'}], 'status': 'sold'}, {'id': 1346780, 'name': '見響见响仮仏!$%&()*+,-ƄƅƆḞḟṀʶʷʸ㥹', 'photoUrls':
56 | ['https://petstore3.swagger.io/resources/photos/623389095.jpg'], 'tags': [], 'status': 'sold'}]
57 | PASSED [100%]
58 |
59 | ```
--------------------------------------------------------------------------------
/tests/pipe/create_pipe.py:
--------------------------------------------------------------------------------
1 |
2 | from superagentx.agent import Agent
3 | from superagentx.agentxpipe import AgentXPipe
4 | from superagentx.engine import Engine
5 | from superagentx.llm import LLMClient
6 | from superagentx.memory import Memory
7 | from superagentx.prompt import PromptTemplate
8 |
9 | # Import handlers
10 | from superagentx_handlers.google.gmail import GmailHandler
11 | from superagentx_handlers.crm.hubspot_crm import HubSpotHandler
12 |
13 |
14 | async def get_superagentx_voice_to_text_pipe() -> AgentXPipe:
15 | # LLM Configuration
16 | llm_config = {
17 | 'llm_type': 'openai'
18 | }
19 | llm_client = LLMClient(llm_config=llm_config)
20 |
21 | # Enable Memory
22 | memory = Memory(memory_config={"llm_client": llm_client})
23 |
24 | # Enable Handler
25 | gmail_handler = GmailHandler(
26 | credentials="//path to json credentials."
27 | )
28 | hubspot_handler = HubSpotHandler()
29 |
30 | system_prompt = """
31 | 1. Get last email which is which is subject contains insurance or policy or claim
32 | """
33 |
34 | hubspot_system_prompt = """
35 | 1. Create only one ticket at a time in hubspot crm
36 | """
37 |
38 | # Prompt Template
39 |
40 | gmail_prompt_template = PromptTemplate(
41 | system_message=system_prompt
42 | )
43 |
44 | hubspot_prompt_template = PromptTemplate(
45 | system_message=hubspot_system_prompt
46 | )
47 |
48 | # Read last email to create a new ticket in HubSpot.
49 | # Example - Engine(s)
50 | # -------------------
51 | gmail_engine = Engine(
52 | handler=gmail_handler,
53 | llm=llm_client,
54 | prompt_template=gmail_prompt_template
55 | )
56 | hubspot_engine = Engine(
57 | handler=hubspot_handler,
58 | llm=llm_client,
59 | prompt_template=hubspot_prompt_template
60 | )
61 |
62 | # Create Agents
63 | # Create Agent with Gmail, Hubspot Engines execute in sequential
64 | gmail_agent = Agent(
65 | goal="Get me the best search results",
66 | role="You are the best gmail reader",
67 | llm=llm_client,
68 | prompt_template=gmail_prompt_template,
69 | engines=[[gmail_engine]]
70 | )
71 |
72 | hubspot_agent = Agent(
73 | name='CRM Agent',
74 | goal="Create new Ticket in Hubspot",
75 | role="You are the Hubspot admin",
76 | llm=llm_client,
77 | prompt_template=hubspot_prompt_template,
78 | engines=[[hubspot_engine]]
79 | )
80 |
81 | # Create Pipe - Interface
82 | # Pipe Interface to send it to public accessible interface (Cli Console / WebSocket / Restful API)
83 | pipe = AgentXPipe(
84 | agents=[gmail_agent, hubspot_agent],
85 | memory=memory
86 | )
87 | return pipe
88 |
89 |
--------------------------------------------------------------------------------