Skip to main content

Overview

Hyperbolic AgentKit uses a flexible tool/action system that allows agents to interact with GPU compute, blockchains, social media, web services, and more. Tools are the bridge between the agent’s reasoning and external systems.

Tool Architecture

The framework uses a three-layer tool architecture:
┌─────────────────────────────────────────┐
│      LangChain Tool Interface           │
│      (BaseTool, Tool)                   │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│         Toolkit Layer                   │
│   (HyperbolicToolkit, etc.)            │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│          Action Layer                   │
│   (HyperbolicAction subclasses)        │
└─────────────────────────────────────────┘

Core Concepts

Actions

Actions are the fundamental units of functionality. Each action defines:
hyperbolic_agentkit_core/actions/hyperbolic_action.py
from pydantic import BaseModel
from collections.abc import Callable

class HyperbolicAction(BaseModel):
    """Hyperbolic Action Base Class."""
    
    name: str                              # Tool name for the agent
    description: str                       # What the tool does (used by LLM)
    args_schema: type[BaseModel] | None   # Input validation schema
    func: Callable[..., str]              # The actual implementation

Tools

Tools wrap actions for LangChain compatibility:
hyperbolic_langchain/tools/hyperbolic_tool.py
from langchain_core.tools import BaseTool

class HyperbolicTool(BaseTool):
    """Tool for interacting with the Hyperbolic SDK."""
    
    hyperbolic_agentkit_wrapper: HyperbolicAgentkitWrapper
    name: str = ""
    description: str = ""
    args_schema: type[BaseModel] | None = None
    func: Callable[..., str]
    
    def _run(
        self,
        instructions: str | None = "",
        run_manager: CallbackManagerForToolRun | None = None,
        **kwargs: Any,
    ) -> str:
        """Use the Hyperbolic SDK to run an operation."""
        if self.args_schema is not None:
            validated_input_data = self.args_schema(**kwargs)
            parsed_input_args = validated_input_data.model_dump()
        else:
            parsed_input_args = {"instructions": instructions}
        
        return self.hyperbolic_agentkit_wrapper.run_action(
            self.func, **parsed_input_args
        )

Toolkits

Toolkits group related tools together:
hyperbolic_langchain/agent_toolkits/hyperbolic_toolkit.py
from langchain_core.tools.base import BaseToolkit

class HyperbolicToolkit(BaseToolkit):
    """Hyperbolic Platform Toolkit."""
    
    tools: list[BaseTool] = []
    
    @classmethod
    def from_hyperbolic_agentkit_wrapper(
        cls, hyperbolic_agentkit_wrapper: HyperbolicAgentkitWrapper
    ) -> "HyperbolicToolkit":
        """Create toolkit from wrapper."""
        actions = HYPERBOLIC_ACTIONS
        
        tools = [
            HyperbolicTool(
                name=action.name,
                description=action.description,
                hyperbolic_agentkit_wrapper=hyperbolic_agentkit_wrapper,
                args_schema=action.args_schema,
                func=action.func,
            ) for action in actions
        ]
        
        return cls(tools=tools)
    
    def get_tools(self) -> list[BaseTool]:
        """Get the tools in the toolkit."""
        return self.tools

Available Tool Categories

1. GPU Compute Tools (Hyperbolic)

Manage GPU instances on the Hyperbolic platform.

Get Available GPUs

hyperbolic_agentkit_core/actions/get_available_gpus.py
def get_available_gpus() -> str:
    """Returns available GPUs from the Hyperbolic API."""
    api_key = get_api_key()
    
    url = "https://api.hyperbolic.xyz/v1/marketplace"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}"
    }
    
    response = requests.post(url, headers=headers, json={"filters": {}})
    data = response.json()
    
    formatted_output = "Available GPU Options:\n\n"
    
    for instance in data.get("instances", []):
        if instance.get("reserved", True):
            continue
        
        cluster_name = instance.get("cluster_name", "Unknown")
        node_id = instance.get("id", "Unknown")
        gpu_model = instance.get("hardware", {}).get("gpus", [{}])[0].get("model", "Unknown")
        price = instance.get("pricing", {}).get("price", {}).get("amount", 0) / 100
        gpus_available = instance.get("gpus_total", 0) - instance.get("gpus_reserved", 0)
        
        if gpus_available > 0:
            formatted_output += f"Cluster: {cluster_name}\n"
            formatted_output += f"Node ID: {node_id}\n"
            formatted_output += f"GPU Model: {gpu_model}\n"
            formatted_output += f"Available GPUs: {gpus_available}\n"
            formatted_output += f"Price: ${price:.2f}/hour per GPU\n"
            formatted_output += "-" * 40 + "\n\n"
    
    return formatted_output

class GetAvailableGpusAction(HyperbolicAction):
    """Get available GPUs action."""
    
    name: str = "get_available_gpus"
    description: str = """Get all available GPU machines on Hyperbolic platform.
    Does not take any inputs. GPU prices are in CENTS per hour."""
    args_schema: type[BaseModel] | None = GetAvailableGpusInput
    func: Callable[..., str] = get_available_gpus

Rent Compute

hyperbolic_agentkit_core/actions/rent_compute.py
class RentComputeInput(BaseModel):
    """Input argument schema for compute rental action."""
    
    cluster_name: str = Field(
        ..., description="The cluster name to rent from"
    )
    node_name: str = Field(
        ..., description="The node ID to rent"
    )
    gpu_count: str = Field(
        ..., description="Number of GPUs to rent from the node"
    )

def rent_compute(cluster_name: str, node_name: str, gpu_count: str) -> str:
    """Creates a marketplace instance using the Hyperbolic API."""
    if not cluster_name or not node_name or not gpu_count:
        raise ValueError("cluster_name, node_name, and gpu_count are required")
    
    api_key = get_api_key()
    
    endpoint = "https://api.hyperbolic.xyz/v1/marketplace/instances/create"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}"
    }
    payload = {
        "cluster_name": cluster_name,
        "node_name": node_name,
        "gpu_count": gpu_count
    }
    
    response = requests.post(endpoint, headers=headers, json=payload)
    response.raise_for_status()
    
    return json.dumps(response.json(), indent=2)

class RentComputeAction(HyperbolicAction):
    """Rent compute action."""
    
    name: str = "rent_compute"
    description: str = """Rent a GPU machine on Hyperbolic platform.
    
    Inputs:
    - cluster_name: Which cluster the node is on
    - node_name: Which node to rent
    - gpu_count: How many GPUs to rent
    
    Important: Always use GetAvailableGpus first to get cluster_name and node_name.
    After renting, use GetGPUStatus, SSHAccess, and RemoteShell to manage the instance.
    """
    args_schema: type[BaseModel] | None = RentComputeInput
    func: Callable[..., str] = rent_compute

SSH Access & Remote Shell

hyperbolic_agentkit_core/actions/ssh_access.py
class SSHAccessInput(BaseModel):
    """Input argument schema for SSH access."""
    host: str = Field(..., description="Hostname or IP address")
    username: str = Field(..., description="SSH username")
    password: Optional[str] = Field(None, description="SSH password")
    private_key_path: Optional[str] = Field(None, description="Path to private key")
    port: int = Field(22, description="SSH port number")

def connect_ssh(host: str, username: str, password: Optional[str] = None,
                private_key_path: Optional[str] = None, port: int = 22) -> str:
    """Establish SSH connection to remote server."""
    return ssh_manager.connect(
        host=host,
        username=username,
        password=password,
        private_key_path=private_key_path,
        port=port
    )
hyperbolic_agentkit_core/actions/remote_shell.py
class RemoteShellInput(BaseModel):
    """Input argument schema for remote shell commands."""
    command: str = Field(..., description="Shell command to execute")

def execute_remote_command(command: str) -> str:
    """Execute a command on the remote server."""
    # Special command to check status
    if command.strip().lower() == 'ssh_status':
        return ssh_manager.get_connection_info()
    
    # Verify connection
    if not ssh_manager.is_connected:
        return "Error: No active SSH connection. Use ssh_connect first."
    
    # Execute remotely
    return ssh_manager.execute(command)

Terminate Compute

hyperbolic_agentkit_core/actions/terminate_compute.py
class TerminateComputeInput(BaseModel):
    """Input argument schema for compute termination."""
    instance_id: str = Field(..., description="Instance ID to terminate")

def terminate_compute(instance_id: str) -> str:
    """Terminates a marketplace instance."""
    if not instance_id:
        raise ValueError("instance_id is required")
    
    api_key = get_api_key()
    endpoint = "https://api.hyperbolic.xyz/v1/marketplace/instances/terminate"
    
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}"
    }
    payload = {"id": instance_id}
    
    response = requests.post(endpoint, headers=headers, json=payload)
    response.raise_for_status()
    
    return json.dumps(response.json(), indent=2)

2. Blockchain Tools (Coinbase CDP)

Provided by Coinbase AgentKit:
chatbot.py
from coinbase_agentkit import (
    AgentKit,
    AgentKitConfig,
    CdpWalletProvider,
    cdp_wallet_action_provider,
    erc20_action_provider,
    wallet_action_provider,
)
from coinbase_agentkit_langchain import get_langchain_tools

# Initialize wallet provider
wallet_provider = CdpWalletProvider(CdpWalletProviderConfig(
    api_key_name=os.getenv("CDP_API_KEY_NAME"),
    api_key_private=os.getenv("CDP_API_KEY_PRIVATE"),
    network_id=os.getenv("CDP_NETWORK_ID", "base-mainnet"),
))

# Initialize AgentKit
agent_kit = AgentKit(AgentKitConfig(
    wallet_provider=wallet_provider,
    action_providers=[
        cdp_wallet_action_provider(),
        erc20_action_provider(),
        wallet_action_provider(),
    ]
))

# Get LangChain tools
coinbase_tools = get_langchain_tools(agent_kit)

3. Social Media Tools (Twitter)

Custom Twitter operations:
chatbot.py
from twitter_agent.custom_twitter_actions import (
    TwitterClient,
    create_delete_tweet_tool,
    create_get_user_id_tool,
    create_get_user_tweets_tool,
    create_retweet_tool
)

twitter_client = TwitterClient()

# Add custom Twitter tools
if os.getenv("USE_TWEET_DELETE", "true").lower() == "true":
    tools.append(create_delete_tweet_tool())

if os.getenv("USE_USER_ID_LOOKUP", "true").lower() == "true":
    tools.append(create_get_user_id_tool())

if os.getenv("USE_USER_TWEETS_LOOKUP", "true").lower() == "true":
    tools.append(create_get_user_tweets_tool())

if os.getenv("USE_RETWEET", "true").lower() == "true":
    tools.append(create_retweet_tool())

4. Browser Automation Tools

chatbot.py
from browser_agent import BrowserToolkit

# Add browser toolkit
if os.getenv("USE_BROWSER_TOOLS", "true").lower() == "true":
    browser_toolkit = BrowserToolkit.from_llm(llm)
    tools.extend(browser_toolkit.get_tools())

5. Knowledge Base Tools

chatbot.py
from twitter_agent.twitter_knowledge_base import TweetKnowledgeBase
from podcast_agent.podcast_knowledge_base import PodcastKnowledgeBase

# Twitter Knowledge Base
knowledge_base = TweetKnowledgeBase()
tools.append(Tool(
    name="query_twitter_knowledge_base",
    description="Query the knowledge base for relevant tweets from KOLs",
    func=lambda query: knowledge_base.query_knowledge_base(query)
))

# Podcast Knowledge Base
podcast_knowledge_base = PodcastKnowledgeBase()
tools.append(Tool(
    name="query_podcast_knowledge_base",
    func=lambda query: podcast_knowledge_base.format_query_results(
        podcast_knowledge_base.query_knowledge_base(query)
    ),
    description="Query podcast transcripts for relevant information"
))

6. Web Search Tools

chatbot.py
from langchain_community.tools import DuckDuckGoSearchRun

if os.getenv("USE_WEB_SEARCH", "false").lower() == "true":
    tools.append(DuckDuckGoSearchRun(
        name="web_search",
        description="Search the web for current information"
    ))

7. Writing Agent Tools

chatbot.py
from writing_agent.writing_tool import WritingTool

if os.getenv("USE_WRITING_AGENT", "true").lower() == "true":
    output_dir = os.path.join(os.getcwd(), "generated_articles")
    os.makedirs(output_dir, exist_ok=True)
    writing_tool = WritingTool(llm=llm)
    tools.append(writing_tool)

Creating Custom Tools

Method 1: Simple LangChain Tool

For simple functions without complex schemas:
from langchain.tools import Tool

def my_custom_function(input_text: str) -> str:
    """Do something useful."""
    return f"Processed: {input_text}"

my_tool = Tool(
    name="my_custom_tool",
    description="Describe what this tool does for the LLM",
    func=my_custom_function
)

tools.append(my_tool)

Method 2: HyperbolicAction Pattern

For more complex tools with validation:
from pydantic import BaseModel, Field
from hyperbolic_agentkit_core.actions.hyperbolic_action import HyperbolicAction

# 1. Define input schema
class MyToolInput(BaseModel):
    """Input schema for my tool."""
    param1: str = Field(..., description="First parameter")
    param2: int = Field(default=10, description="Second parameter")

# 2. Implement the function
def my_tool_function(param1: str, param2: int = 10) -> str:
    """Implement the actual functionality."""
    result = f"Processing {param1} with {param2}"
    return result

# 3. Create the action class
class MyToolAction(HyperbolicAction):
    """My custom tool action."""
    
    name: str = "my_tool"
    description: str = """Describe what this tool does.
    Include usage notes and important information for the LLM."""
    args_schema: type[BaseModel] = MyToolInput
    func: Callable[..., str] = my_tool_function

# 4. Register in __init__.py
# Add to hyperbolic_agentkit_core/actions/__init__.py:
from hyperbolic_agentkit_core.actions.my_tool import MyToolAction

Method 3: Custom Toolkit

For grouping related tools:
from langchain_core.tools.base import BaseToolkit
from langchain_core.tools import BaseTool

class MyCustomToolkit(BaseToolkit):
    """Toolkit for my custom tools."""
    
    tools: list[BaseTool] = []
    
    @classmethod
    def create(cls) -> "MyCustomToolkit":
        """Create the toolkit with all tools."""
        tools = [
            Tool(name="tool1", func=func1, description="..."),
            Tool(name="tool2", func=func2, description="..."),
        ]
        return cls(tools=tools)
    
    def get_tools(self) -> list[BaseTool]:
        """Get the tools in the toolkit."""
        return self.tools

# Usage
my_toolkit = MyCustomToolkit.create()
tools.extend(my_toolkit.get_tools())

Tool Registration

Tools are registered in chatbot.py via the create_agent_tools() function:
chatbot.py
def create_agent_tools(llm, knowledge_base, podcast_knowledge_base,
                       agent_kit, config):
    """Create and return a list of tools for the agent to use."""
    tools = []
    
    # Hyperbolic tools
    if os.getenv("USE_HYPERBOLIC_TOOLS", "false").lower() == "true":
        hyperbolic_agentkit = HyperbolicAgentkitWrapper()
        hyperbolic_toolkit = HyperbolicToolkit.from_hyperbolic_agentkit_wrapper(
            hyperbolic_agentkit
        )
        tools.extend(hyperbolic_toolkit.get_tools())
    
    # Add your custom tools here
    if os.getenv("USE_MY_CUSTOM_TOOLS", "false").lower() == "true":
        my_toolkit = MyCustomToolkit.create()
        tools.extend(my_toolkit.get_tools())
    
    return tools

Environment Configuration

Control which tools are available via .env:
.env
# Hyperbolic GPU Tools
USE_HYPERBOLIC_TOOLS=true
HYPERBOLIC_API_KEY=your_api_key

# Browser Tools
USE_BROWSER_TOOLS=true

# Twitter Tools
USE_TWITTER_CORE=true
USE_TWEET_DELETE=true
USE_USER_ID_LOOKUP=true
USE_USER_TWEETS_LOOKUP=true
USE_RETWEET=true

# Knowledge Base Tools
USE_TWITTER_KNOWLEDGE_BASE=true
USE_PODCAST_KNOWLEDGE_BASE=true

# State Management
USE_TWEET_REPLY_TRACKING=true
USE_TWEET_REPOST_TRACKING=true

# Coinbase Tools
USE_COINBASE_TOOLS=true

# Web Search
USE_WEB_SEARCH=false

# Writing Agent
USE_WRITING_AGENT=true

# Request Tools
USE_REQUEST_TOOLS=false

Best Practices

Write clear, detailed descriptions that help the LLM understand:
  • What the tool does
  • When to use it
  • What inputs it requires
  • What output to expect
  • Any important notes or warnings
Use Pydantic schemas for:
  • Type validation
  • Required vs optional parameters
  • Default values
  • Field descriptions
  • Return descriptive error messages
  • Don’t raise exceptions unless critical
  • Include troubleshooting hints
  • Log errors for debugging
Document and check dependencies:
  • API keys required
  • Other tools that must run first
  • External services needed
  • Environment variables
  • Add timeouts for long-running operations
  • Stream large outputs
  • Cache results when appropriate
  • Paginate API responses

Next Steps

Architecture

Understand the framework architecture

Agents

Learn about agent types and modes

Character Configuration

Configure agent personality

Hyperbolic Integration

Set up GPU compute tools

Build docs developers (and LLMs) love