Examples - Agent Hustle

Explore complete, working examples that demonstrate different ways to integrate Agent Hustle into your applications. From simple CLI tools to full-featured web applications.

💻 Simple CLI Tool

Interactive Command Line Interface

A complete CLI application that demonstrates all Agent Hustle features with streaming responses.

JA
simple-cli.js
Loading...

Features Demonstrated:

  • • Real-time streaming responses
  • • Tool execution tracking
  • • Interactive conversation loop
  • • Error handling
  • • Token usage monitoring

🌐 Web Server with UI

Express Server + HTML Interface

A complete web application with REST API and beautiful test interface.

// server.js
import express from 'express';
import { HustleIncognitoClient } from 'hustle-incognito';
import path from 'path';

const app = express();
const port = 3000;

app.use(express.json());
app.use(express.static('public'));

const client = new HustleIncognitoClient({
  apiKey: process.env.HUSTLE_API_KEY
});

// Chat endpoint
app.post('/api/chat', async (req, res) => {
  try {
    const { message, vaultId } = req.body;

    const response = await client.chat([
      { role: 'user', content: message }
    ], {
      vaultId: vaultId || process.env.VAULT_ID,
      selectedToolCategories: ['standard-tools', 'solana-token-ecosystem']
    });

    res.json({
      success: true,
      content: response.content,
      usage: response.usage,
      toolCalls: response.toolCalls
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

// Streaming endpoint
app.post('/api/chat/stream', async (req, res) => {
  try {
    const { message, vaultId } = req.body;

    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'Access-Control-Allow-Origin': '*'
    });

    for await (const chunk of client.chatStream({
      messages: [{ role: 'user', content: message }],
      vaultId: vaultId || process.env.VAULT_ID,
      processChunks: true
    })) {
      res.write(`data: ${JSON.stringify(chunk)}\n\n`);
    }

    res.write('data: [DONE]\n\n');
    res.end();
  } catch (error) {
    res.write(`data: ${JSON.stringify({ type: 'error', error: error.message })}\n\n`);
    res.end();
  }
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

Frontend HTML (public/index.html)

<!DOCTYPE html>
<html>
<head>
  <title>Agent Hustle Web Interface</title>
  <style>
    body { font-family: system-ui; max-width: 800px; margin: 0 auto; padding: 20px; }
    .chat-container { border: 1px solid #ddd; height: 400px; overflow-y: auto; padding: 15px; }
    .message { margin: 10px 0; padding: 10px; border-radius: 8px; }
    .user { background: #e3f2fd; margin-left: 20px; }
    .agent { background: #f1f8e9; margin-right: 20px; }
    .tool-call { background: #fff3e0; font-style: italic; }
    input { width: 70%; padding: 10px; }
    button { padding: 10px 20px; }
  </style>
</head>
<body>
  <h1>🤖 Agent Hustle Web Interface</h1>

  <div class="chat-container" id="chatContainer">
    <div class="message agent">
      Hello! I'm your Agent Hustle AI assistant. Ask me anything about crypto!
    </div>
  </div>

  <div style="margin-top: 20px;">
    <input type="text" id="messageInput" placeholder="Ask about crypto prices, market analysis, etc..."
           onkeypress="if(event.key==='Enter') sendMessage()">
    <button onclick="sendMessage()">Send</button>
    <button onclick="streamMessage()">Stream</button>
  </div>

  <script>
    async function sendMessage() {
      const input = document.getElementById('messageInput');
      const message = input.value.trim();
      if (!message) return;

      addMessage(message, 'user');
      input.value = '';

      try {
        const response = await fetch('/api/chat', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ message })
        });

        const data = await response.json();

        if (data.success) {
          addMessage(data.content, 'agent');
          if (data.toolCalls?.length > 0) {
            addMessage(`Used tools: ${data.toolCalls.map(t => t.toolName).join(', ')}`, 'tool-call');
          }
        } else {
          addMessage(`Error: ${data.error}`, 'agent');
        }
      } catch (error) {
        addMessage(`Error: ${error.message}`, 'agent');
      }
    }

    async function streamMessage() {
      const input = document.getElementById('messageInput');
      const message = input.value.trim();
      if (!message) return;

      addMessage(message, 'user');
      input.value = '';

      const agentDiv = addMessage('', 'agent');

      try {
        const response = await fetch('/api/chat/stream', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ message })
        });

        const reader = response.body.getReader();
        const decoder = new TextDecoder();

        while (true) {
          const { value, done } = await reader.read();
          if (done) break;

          const chunk = decoder.decode(value);
          const lines = chunk.split('\n');

          for (const line of lines) {
            if (line.startsWith('data: ')) {
              const data = line.slice(6);
              if (data === '[DONE]') return;

              try {
                const parsed = JSON.parse(data);
                if (parsed.type === 'text') {
                  agentDiv.textContent += parsed.value;
                } else if (parsed.type === 'tool_call') {
                  addMessage(`🔧 Using ${parsed.value.toolName}`, 'tool-call');
                }
              } catch (e) {
                // Ignore parsing errors for incomplete chunks
              }
            }
          }
        }
      } catch (error) {
        addMessage(`Error: ${error.message}`, 'agent');
      }
    }

    function addMessage(content, type) {
      const container = document.getElementById('chatContainer');
      const div = document.createElement('div');
      div.className = `message ${type}`;
      div.textContent = content;
      container.appendChild(div);
      container.scrollTop = container.scrollHeight;
      return div;
    }
  </script>
</body>
</html>

Features Demonstrated:

  • • RESTful API endpoints
  • • Server-Sent Events for streaming
  • • Interactive web interface
  • • Real-time response display
  • • Tool execution visualization

📊 Portfolio Tracker

React Portfolio Dashboard

// PortfolioTracker.tsx
import React, { useState } from 'react';
import { HustleIncognitoClient } from 'hustle-incognito';

const client = new HustleIncognitoClient({
  apiKey: process.env.REACT_APP_HUSTLE_API_KEY
});

export function PortfolioTracker() {
  const [walletAddress, setWalletAddress] = useState('');
  const [analysis, setAnalysis] = useState('');
  const [loading, setLoading] = useState(false);

  const analyzePortfolio = async () => {
    if (!walletAddress) return;

    setLoading(true);
    setAnalysis('');

    try {
      for await (const chunk of client.chatStream({
        messages: [{
          role: 'user',
          content: `Analyze the portfolio for wallet address ${walletAddress}. Provide insights on allocation, performance, and recommendations.`
        }],
        vaultId: process.env.REACT_APP_VAULT_ID,
        selectedToolCategories: ['standard-tools', 'blockchain-analysis'],
        processChunks: true
      })) {
        if (chunk.type === 'text') {
          setAnalysis(prev => prev + chunk.value);
        }
      }
    } catch (error) {
      setAnalysis(`Error: ${error.message}`);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ padding: '20px', maxWidth: '800px', margin: '0 auto' }}>
      <h1>Portfolio Analysis</h1>

      <div style={{ marginBottom: '20px' }}>
        <input
          type="text"
          value={walletAddress}
          onChange={(e) => setWalletAddress(e.target.value)}
          placeholder="Enter wallet address"
          style={{ width: '70%', padding: '10px', marginRight: '10px' }}
        />
        <button
          onClick={analyzePortfolio}
          disabled={loading || !walletAddress}
          style={{ padding: '10px 20px' }}
        >
          {loading ? 'Analyzing...' : 'Analyze'}
        </button>
      </div>

      {analysis && (
        <div style={{
          background: '#f5f5f5',
          padding: '20px',
          borderRadius: '8px',
          whiteSpace: 'pre-wrap'
        }}>
          {analysis}
        </div>
      )}
    </div>
  );
}

🤖 Trading Bot

Automated Trading Assistant

// trading-bot.js
import { HustleIncognitoClient } from 'hustle-incognito';

class TradingBot {
  constructor() {
    this.client = new HustleIncognitoClient({
      apiKey: process.env.HUSTLE_API_KEY,
      debug: true
    });

    this.watchedTokens = ['BTC', 'ETH', 'SOL', 'BONK'];
    this.isRunning = false;
  }

  async start() {
    console.log('🤖 Trading Bot starting...');
    this.isRunning = true;

    while (this.isRunning) {
      try {
        await this.analyzeMarkets();
        await this.sleep(300000); // 5 minutes
      } catch (error) {
        console.error('Bot error:', error);
        await this.sleep(60000); // 1 minute retry
      }
    }
  }

  async analyzeMarkets() {
    console.log('📊 Analyzing markets...');

    for (const token of this.watchedTokens) {
      const analysis = await this.client.chat([{
        role: 'user',
        content: `Analyze ${token} for trading opportunities. Consider price action, volume, and market sentiment. Provide specific entry/exit recommendations.`
      }], {
        vaultId: process.env.VAULT_ID,
        selectedToolCategories: ['standard-tools', 'trading', 'market-analysis']
      });

      console.log(`\n📈 ${token} Analysis:`);
      console.log(analysis.content);

      // Check for trading signals
      if (analysis.content.toLowerCase().includes('buy signal') ||
          analysis.content.toLowerCase().includes('strong buy')) {
        await this.handleBuySignal(token, analysis.content);
      }
    }
  }

  async handleBuySignal(token, analysis) {
    console.log(`🚨 Buy signal detected for ${token}!`);

    // Risk assessment
    const riskAnalysis = await this.client.chat([{
      role: 'user',
      content: `Assess the risk for buying ${token} right now. What position size would you recommend?`
    }], {
      vaultId: process.env.VAULT_ID,
      selectedToolCategories: ['risk-management', 'portfolio-analysis']
    });

    console.log('⚖️  Risk Assessment:');
    console.log(riskAnalysis.content);

    // In a real bot, you would execute the trade here
    console.log(`📝 Would execute buy order for ${token}`);

    // Log to file or database
    this.logTrade({
      timestamp: new Date().toISOString(),
      action: 'BUY_SIGNAL',
      token,
      analysis: analysis.substring(0, 200) + '...',
      riskAssessment: riskAnalysis.content.substring(0, 200) + '...'
    });
  }

  logTrade(tradeLog) {
    console.log('📋 Trade Log:', JSON.stringify(tradeLog, null, 2));
    // In production, save to database or file
  }

  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  stop() {
    console.log('🛑 Stopping trading bot...');
    this.isRunning = false;
  }
}

// Start the bot
const bot = new TradingBot();

// Graceful shutdown
process.on('SIGINT', () => {
  bot.stop();
  process.exit(0);
});

bot.start().catch(console.error);

📱 Next.js Integration

API Route + React Component

// app/api/agent/route.ts
import { HustleIncognitoClient } from 'hustle-incognito';

const client = new HustleIncognitoClient({
  apiKey: process.env.HUSTLE_API_KEY!
});

export async function POST(request: Request) {
  try {
    const { message, vaultId } = await request.json();

    const response = await client.chat([
      { role: 'user', content: message }
    ], {
      vaultId: vaultId || process.env.VAULT_ID!,
      selectedToolCategories: ['standard-tools']
    });

    return Response.json({
      content: response.content,
      usage: response.usage,
      toolCalls: response.toolCalls
    });
  } catch (error) {
    return Response.json(
      { error: 'Failed to process request' },
      { status: 500 }
    );
  }
}

// app/components/AgentChat.tsx
'use client';

import { useState } from 'react';

export default function AgentChat() {
  const [message, setMessage] = useState('');
  const [response, setResponse] = useState('');
  const [loading, setLoading] = useState(false);

  const sendMessage = async () => {
    if (!message.trim()) return;

    setLoading(true);
    try {
      const res = await fetch('/api/agent', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message })
      });

      const data = await res.json();
      setResponse(data.content || data.error);
    } catch (error) {
      setResponse('Error: Failed to send message');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="max-w-2xl mx-auto p-6">
      <h1 className="text-2xl font-bold mb-6">Agent Hustle Chat</h1>

      <div className="mb-4">
        <textarea
          value={message}
          onChange={(e) => setMessage(e.target.value)}
          placeholder="Ask about crypto prices, market analysis..."
          className="w-full p-3 border rounded-lg"
          rows={3}
        />
        <button
          onClick={sendMessage}
          disabled={loading}
          className="mt-2 px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
        >
          {loading ? 'Sending...' : 'Send'}
        </button>
      </div>

      {response && (
        <div className="p-4 bg-gray-100 rounded-lg">
          <h3 className="font-semibold mb-2">Agent Response:</h3>
          <p className="whitespace-pre-wrap">{response}</p>
        </div>
      )}
    </div>
  );
}

🚀 Running the Examples

Setup Instructions

# 1. Clone and install
git clone <repository>
npm install

# 2. Set environment variables
export HUSTLE_API_KEY="your-api-key"
export VAULT_ID="your-vault-id"

# 3. Run examples
node examples/simple-cli.js
node examples/simple-server.js
node examples/trading-bot.js

Environment Setup

# .env file
HUSTLE_API_KEY=your-api-key-here
VAULT_ID=your-vault-id-here

# For React apps
REACT_APP_HUSTLE_API_KEY=your-key
REACT_APP_VAULT_ID=your-vault

# For Next.js
NEXT_PUBLIC_HUSTLE_API_KEY=your-key

⚠️ Important Notes

  • API Keys: Never commit API keys to version control
  • Rate Limits: Be mindful of API rate limits in production
  • Error Handling: All examples include basic error handling
  • Security: Use environment variables for sensitive data
  • Testing: Test with small amounts before using in production

🎯 Next Steps

  • Customize: Modify examples for your specific use case
  • Extend: Add additional tool categories and features
  • Deploy: Deploy your applications to production
  • Monitor: Add logging and monitoring to track usage
  • Scale: Implement caching and optimization strategies