├── 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![](https://t-cf.bstatic 45 | .com/design-assets/assets/v3.134.0/images-flags/In@3x.png)\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 | --------------------------------------------------------------------------------