Ragwalla Agents Developer Guide

Ragwalla Agents provide a powerful framework for creating AI-powered assistants that can execute tools, maintain conversation state, and integrate with external services through the Model Context Protocol (MCP).

Table of Contents

Overview

Ragwalla Agents can:
- Maintain conversation history across sessions
- Execute various types of tools (system, user-defined, MCP)
- Stream responses in real-time via WebSocket
- Integrate with external services and APIs
- Access knowledge bases through vector search
- Delegate tasks to specialized assistants

Architecture

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│   Client    │────▶│    Agent     │────▶│     LLM     │
│  (HTTP/WS)  │◀────│   Service    │◀────│  (OpenAI)   │
└─────────────┘     └──────┬───────┘     └─────────────┘
                           │
                    ┌──────▼───────┐
                    │    Tools     │
                    ├──────────────┤
                    │ • System     │
                    │ • User       │
                    │ • MCP        │
                    │ • Assistant  │
                    │ • Knowledge  │
                    └──────────────┘

Quick Start

1. Create Your First Agent

const response = await fetch('https://example.ai.ragwalla.com/v1/agents', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'travel-assistant',
    description: 'A helpful travel planning assistant',
    instructions: 'You are a knowledgeable travel assistant. Help users plan their trips, find destinations, and provide travel advice.',
    model: 'gpt-4o-mini',
    temperature: 0.7,
    tools: [
      {
        type: 'function',
        function: {
          name: 'search_flights',
          description: 'Search for available flights',
          parameters: {
            type: 'object',
            properties: {
              origin: { type: 'string', description: 'Origin airport code' },
              destination: { type: 'string', description: 'Destination airport code' },
              date: { type: 'string', description: 'Travel date (YYYY-MM-DD)' }
            },
            required: ['origin', 'destination', 'date']
          }
        }
      }
    ]
  })
});

const agent = await response.json();
console.log('Created agent:', agent.id);

2. Start a Conversation

The simplest way to interact with agents is through WebSocket:

// Get WebSocket token
const tokenResponse = await fetch('https://example.ai.ragwalla.com/v1/agents/token', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: agent.id,
    sessionId: 'session_456'  // Optional: continue previous conversation
  })
});
const { token } = await tokenResponse.json();

// Connect to the agent
const ws = new WebSocket(
  `wss://example.ai.ragwalla.com/v1/agents/${agent.name}/main?token=${token}`
);

ws.onopen = () => {
  // Send a message
  ws.send(JSON.stringify({
    type: 'message',
    content: 'Find me flights from NYC to LON next Friday'
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.type === 'chunk') {
    // Real-time response streaming
    process.stdout.write(data.content);
  }
};

That's it! The agent handles all the complexity of managing conversations, executing tools, and generating responses.

Creating Agents

Agent Configuration

Agents support comprehensive configuration options:

{
  "name": "my-agent",
  "description": "Agent purpose and capabilities",
  "instructions": "Detailed instructions for the agent's behavior",
  "model": "gpt-4o-mini",  // or "gpt-4", "gpt-3.5-turbo"
  "temperature": 0.7,      // 0.0 to 2.0
  "top_p": 1.0,           // 0.0 to 1.0
  "max_prompt_tokens": 128000,
  "max_completion_tokens": 4096,
  "truncation_strategy": {
    "type": "auto"
  },
  "tool_choice": "auto",   // or "none", "required", specific tool
  "parallel_tool_calls": true,
  "response_format": {
    "type": "text"         // or "json_object"
  },
  "tools": [],            // Tool definitions
  "metadata": {           // Custom metadata
    "version": "1.0",
    "category": "customer-service"
  }
}

Tool Types

Agents can use five types of tools:

1. Function Tools (Custom Code)

{
  "type": "function",
  "function": {
    "name": "calculate_discount",
    "description": "Calculate discount for a product",
    "parameters": {
      "type": "object",
      "properties": {
        "price": { "type": "number" },
        "discount_percentage": { "type": "number" }
      },
      "required": ["price", "discount_percentage"]
    },
    "implementation": `
      export default function(args) {
        const { price, discount_percentage } = args;
        const discount = price * (discount_percentage / 100);
        return {
          original_price: price,
          discount_amount: discount,
          final_price: price - discount
        };
      }
    `
  }
}

2. MCP Tools (External Servers)

{
  "type": "mcp",
  "mcp": {
    "serverId": "mcp-server-123",
    "toolName": "get_weather"
  }
}

3. Assistant Tools (Delegate to Other Assistants)

{
  "type": "assistant",
  "assistant": {
    "assistantId": "asst_abc123",
    "name": "specialized-assistant",
    "description": "Handles specialized tasks"
  }
}
{
  "type": "knowledgeBase",
  "knowledgeBase": {
    "vectorStoreId": "vs_xyz789",
    "name": "product_catalog",
    "description": "Search product information"
  }
}

5. API Tools (HTTP Requests)

{
  "type": "api",
  "api": {
    "url": "https://api.example.com/data",
    "method": "GET",
    "headers": {
      "Authorization": "Bearer ${API_KEY}"
    }
  }
}

Working with Threads and Messages

Conversation Management

When using WebSocket, conversations are managed automatically. Each session maintains its own conversation history:

// Start a new conversation
const { token } = await getToken({ agentId: agent.id });

// Or continue a previous conversation
const { token } = await getToken({ 
  agentId: agent.id,
  sessionId: 'previous-session-id' 
});

The agent remembers the context within each session, so you can have natural, multi-turn conversations.

Message Handling

Messages support various content types:

// Text message
{
  "role": "user",
  "content": "Hello, I need help planning a trip"
}

// Message with attachments
{
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": "Can you analyze this image?"
    },
    {
      "type": "image_file",
      "image_file": {
        "file_id": "file_abc123"
      }
    }
  ]
}

// Assistant message with annotations
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "I found this information in the documentation:",
      "annotations": [
        {
          "type": "file_citation",
          "file_citation": {
            "file_id": "file_def456",
            "quote": "Relevant quote from document"
          }
        }
      ]
    }
  ]
}

Tool Integration

Implementing Custom Functions

Create sandboxed functions that agents can execute:

// Weather lookup function
const weatherTool = {
  type: 'function',
  function: {
    name: 'get_weather',
    description: 'Get current weather for a location',
    parameters: {
      type: 'object',
      properties: {
        location: { type: 'string', description: 'City name' },
        units: { 
          type: 'string', 
          enum: ['celsius', 'fahrenheit'],
          default: 'celsius'
        }
      },
      required: ['location']
    },
    implementation: `
      export default async function(args) {
        const { location, units = 'celsius' } = args;

        // Fetch weather data (example)
        const response = await fetch(
          \`https://api.weather.com/v1/current?q=\${location}&units=\${units}\`
        );
        const data = await response.json();

        return {
          location: location,
          temperature: data.temp,
          conditions: data.conditions,
          humidity: data.humidity,
          wind_speed: data.wind_speed
        };
      }
    `
  }
};

// Add tool to agent
await fetch(`https://example.ai.ragwalla.com/v1/agents/${agentId}/tools`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(weatherTool)
});

System Tools

Ragwalla provides built-in system tools:

// Vector search tool
{
  type: 'system',
  name: 'vector_search',
  parameters: {
    query: 'How do I reset my password?',
    limit: 5,
    filter: { category: 'support' }
  }
}

// Assistant delegation tool
{
  type: 'system',
  name: 'use_assistant',
  parameters: {
    assistant_id: 'asst_specialized',
    message: 'Analyze this technical issue'
  }
}

MCP Integration

Setting Up MCP Servers

Register MCP servers for your agents to use:

// Register an MCP server
const mcpServer = await fetch('https://example.ai.ragwalla.com/v1/mcp-servers', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'weather-mcp-server',
    url: 'https://mcp.weather-service.com/mcp',
    description: 'MCP server for weather data',
    authRequired: true,
    authConfig: {
      type: 'bearer',
      token: 'MCP_SERVER_TOKEN'
    }
  })
});

// Discover available tools
const tools = await fetch(
  `https://example.ai.ragwalla.com/v1/mcp-servers/${mcpServer.id}/tools`,
  { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
).then(r => r.json());

// Add MCP tool to agent
await fetch(`https://example.ai.ragwalla.com/v1/agents/${agentId}/tools`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    type: 'mcp',
    mcp: {
      serverId: mcpServer.id,
      toolName: 'get_current_weather'
    }
  })
});

MCP Tool Execution Flow

Agent receives user message
    ↓
LLM decides to use MCP tool
    ↓
Agent calls MCP server via HTTP/WebSocket
    ↓
MCP server executes tool
    ↓
Results returned to agent
    ↓
Agent incorporates results into response

WebSocket Real-time Communication

Connecting to an Agent

The WebSocket connection provides the simplest way to interact with agents. It automatically manages threads and runs for you:

// Get WebSocket token
const tokenResponse = await fetch('https://example.ai.ragwalla.com/v1/agents/token', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: 'agent_123',
    sessionId: 'session_456'  // Optional: reuse existing session
  })
});
const { token } = await tokenResponse.json();

// Connect via WebSocket
const ws = new WebSocket(
  `wss://example.ai.ragwalla.com/v1/agents/travel-assistant/main?token=${token}`
);

ws.onopen = () => {
  console.log('Connected to agent');

  // Just send messages - no need to manage threads or runs
  ws.send(JSON.stringify({
    type: 'message',
    content: 'Help me plan a trip to Paris'
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);

  switch (data.type) {
    case 'chunk':
      // Streaming response chunk
      process.stdout.write(data.content);
      break;

    case 'tool_call':
      console.log('Agent is calling tool:', data.tool);
      break;

    case 'tool_result':
      console.log('Tool result:', data.result);
      break;

    case 'error':
      console.error('Error:', data.error);
      break;

    case 'done':
      console.log('\nResponse complete');
      break;
  }
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

ws.onclose = () => {
  console.log('Disconnected from agent');
};

WebSocket Benefits

The WebSocket connection provides:
- Real-time streaming: See responses as they're generated
- Automatic conversation management: No need to manage threads manually
- Interactive experience: Natural back-and-forth conversations
- Lower latency: Direct connection to the agent
- Simpler code: Just send messages and receive responses

WebSocket Message Types

// Client to Agent
interface ClientMessage {
  type: 'message' | 'stop' | 'feedback';
  content?: string;
  feedback?: {
    rating: number;
    comment: string;
  };
}

// Agent to Client
interface AgentMessage {
  type: 'chunk' | 'tool_call' | 'tool_result' | 'error' | 'done';
  content?: string;
  tool?: {
    id: string;
    name: string;
    arguments: any;
  };
  result?: any;
  error?: {
    code: string;
    message: string;
  };
}

Thread Management

With WebSocket connections, thread management is automatic:

  1. New Session: If no sessionId is provided, a new thread is created
  2. Resume Session: Provide a sessionId to continue an existing conversation
  3. Thread Persistence: Threads are automatically saved and can be resumed later
  4. Context Retention: The agent maintains conversation history within the thread

Advanced Features

1. Agent Composition

Chain multiple agents for complex workflows:

// Create a research agent
const researchAgent = await createAgent({
  name: 'research-agent',
  instructions: 'You are a research specialist. Gather comprehensive information on topics.',
  tools: [/* research tools */]
});

// Create a writer agent that uses the research agent
const writerAgent = await createAgent({
  name: 'writer-agent',
  instructions: 'You are a content writer. Use the research agent to gather information, then create engaging content.',
  tools: [
    {
      type: 'assistant',
      assistant: {
        assistantId: researchAgent.id,
        name: 'research-assistant',
        description: 'Gather research on topics'
      }
    }
  ]
});

2. Knowledge Base Integration

// Create a vector store
const vectorStore = await createVectorStore({
  name: 'product-knowledge',
  description: 'Product documentation and FAQs'
});

// Add files to vector store
await addFileToVectorStore(vectorStore.id, {
  file_id: 'file_123',
  chunking_strategy: {
    type: 'auto',
    static: {
      max_chunk_size_tokens: 800,
      chunk_overlap_tokens: 400
    }
  }
});

// Add knowledge base tool to agent
await addToolToAgent(agentId, {
  type: 'knowledgeBase',
  knowledgeBase: {
    vectorStoreId: vectorStore.id,
    name: 'search_products',
    description: 'Search product information and documentation'
  }
});

3. Custom Tool Validation

// Tool with complex validation
{
  type: 'function',
  function: {
    name: 'book_appointment',
    description: 'Book an appointment',
    parameters: {
      type: 'object',
      properties: {
        date: { 
          type: 'string', 
          pattern: '^\\d{4}-\\d{2}-\\d{2}$',
          description: 'Date in YYYY-MM-DD format'
        },
        time: {
          type: 'string',
          pattern: '^\\d{2}:\\d{2}$',
          description: 'Time in HH:MM format'
        },
        duration: {
          type: 'integer',
          minimum: 15,
          maximum: 120,
          description: 'Duration in minutes'
        },
        attendees: {
          type: 'array',
          items: {
            type: 'object',
            properties: {
              email: { type: 'string', format: 'email' },
              name: { type: 'string' }
            },
            required: ['email', 'name']
          },
          minItems: 1,
          maxItems: 10
        }
      },
      required: ['date', 'time', 'duration', 'attendees']
    },
    implementation: `...`
  }
}

4. State Management

Agents can maintain state across conversations:

// Agent with persistent state
const statefulAgent = await createAgent({
  name: 'shopping-assistant',
  instructions: 'You help users shop. Remember their preferences and cart items.',
  metadata: {
    enable_state: true,
    state_schema: {
      cart: { type: 'array', items: { type: 'object' } },
      preferences: { type: 'object' },
      last_viewed: { type: 'array', maxItems: 10 }
    }
  }
});

// Access state in tool implementation
{
  implementation: `
    export default async function(args, context) {
      const { state } = context;

      // Read current cart
      const cart = state.cart || [];

      // Add item
      cart.push(args.item);

      // Update state
      await context.updateState({ cart });

      return { cart_size: cart.length };
    }
  `
}

API Reference

Authentication

All API requests require authentication:

// API Key Authentication
headers: {
  'Authorization': 'Bearer YOUR_API_KEY'
}

// JWT Authentication (for user-specific access)
headers: {
  'Authorization': 'Bearer YOUR_JWT_TOKEN'
}

Error Handling

try {
  const response = await fetch('https://example.ai.ragwalla.com/v1/agents', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(agentConfig)
  });

  if (!response.ok) {
    const error = await response.json();
    console.error('API Error:', {
      status: response.status,
      code: error.code,
      message: error.message,
      details: error.details
    });
  }
} catch (error) {
  console.error('Network error:', error);
}

Rate Limiting

The API implements rate limiting:

// Check rate limit headers
const remaining = response.headers.get('X-RateLimit-Remaining');
const reset = response.headers.get('X-RateLimit-Reset');

if (remaining === '0') {
  const resetDate = new Date(parseInt(reset) * 1000);
  console.log(`Rate limited. Resets at ${resetDate}`);
}

Best Practices

1. Agent Design

  • Single Responsibility: Design agents with focused purposes
  • Clear Instructions: Provide detailed, unambiguous instructions
  • Tool Selection: Only include tools the agent actually needs
  • Error Handling: Include error handling in tool implementations

2. Performance Optimization

// Configure agent for optimal performance
const agent = await createAgent({
  name: 'efficient-agent',
  model: 'gpt-4o-mini',  // Faster model for lower latency
  temperature: 0.7,
  max_prompt_tokens: 4000,
  max_completion_tokens: 1000,
  tools: [...]
});

// Implement caching in tools
{
  implementation: `
    const cache = new Map();

    export default async function(args) {
      const cacheKey = JSON.stringify(args);

      if (cache.has(cacheKey)) {
        return cache.get(cacheKey);
      }

      const result = await expensiveOperation(args);
      cache.set(cacheKey, result);

      return result;
    }
  `
}

3. Security

  • Validate Inputs: Always validate tool inputs
  • Sanitize Outputs: Clean tool outputs before returning
  • Limit Permissions: Use minimal required permissions
  • Audit Logs: Track tool usage for compliance

4. Monitoring

// Track agent usage
const { token } = await getToken({
  agentId: agent.id,
  sessionId: generateSessionId(),
  metadata: {
    user_id: 'user123',
    source: 'mobile-app',
    version: '1.2.0'
  }
});

// Monitor WebSocket connections
ws.onopen = () => {
  telemetry.trackEvent('agent.connected', {
    agent: 'travel-assistant',
    session: sessionId
  });
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.type === 'tool_call') {
    telemetry.trackEvent('tool.invoked', {
      tool: data.tool.name,
      agent: 'travel-assistant'
    });
  }
};

Examples

Complete Travel Assistant

// Create a comprehensive travel assistant
const travelAssistant = await createAgent({
  name: 'travel-buddy',
  description: 'Your personal travel planning assistant',
  instructions: `You are Travel Buddy, an expert travel planning assistant. 
    You help users plan trips, find flights, book hotels, and discover activities.
    Always consider budget, preferences, and travel dates.
    Be enthusiastic and provide personalized recommendations.`,
  model: 'gpt-4o-mini',
  temperature: 0.8,
  tools: [
    // Flight search
    {
      type: 'function',
      function: {
        name: 'search_flights',
        description: 'Search for flights between cities',
        parameters: { /* ... */ },
        implementation: flightSearchCode
      }
    },
    // Hotel search via MCP
    {
      type: 'mcp',
      mcp: {
        serverId: 'hotel-mcp-server',
        toolName: 'search_hotels'
      }
    },
    // Weather information
    {
      type: 'api',
      api: {
        url: 'https://api.weather.com/v1/forecast',
        method: 'GET',
        description: 'Get weather forecast for destination'
      }
    },
    // Travel guides knowledge base
    {
      type: 'knowledgeBase',
      knowledgeBase: {
        vectorStoreId: 'travel-guides-vs',
        name: 'search_destinations',
        description: 'Search travel guides and destination info'
      }
    }
  ]
});

// Use the assistant via WebSocket
const tokenResponse = await fetch('https://example.ai.ragwalla.com/v1/agents/token', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
  body: JSON.stringify({ agentId: travelAssistant.id })
});
const { token } = await tokenResponse.json();

const ws = new WebSocket(
  `wss://example.ai.ragwalla.com/v1/agents/travel-buddy/main?token=${token}`
);

ws.onopen = () => {
  ws.send(JSON.stringify({
    type: 'message',
    content: 'I want to visit Tokyo next month. What do you recommend?'
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  switch (data.type) {
    case 'chunk':
      process.stdout.write(data.content);
      break;
    case 'tool_call':
      console.log(`Calling ${data.tool.name}...`);
      break;
    case 'done':
      console.log('\n✅ Response complete');
      break;
  }
};

Customer Support Agent

// Multi-tier support system
const supportAgent = await createAgent({
  name: 'support-agent',
  instructions: 'You are a customer support agent. Help resolve issues and escalate when needed.',
  tools: [
    // Search knowledge base first
    {
      type: 'knowledgeBase',
      knowledgeBase: {
        vectorStoreId: 'support-kb',
        name: 'search_solutions',
        description: 'Search support articles and solutions'
      }
    },
    // Check order status
    {
      type: 'function',
      function: {
        name: 'check_order',
        parameters: {
          type: 'object',
          properties: {
            order_id: { type: 'string' }
          }
        },
        implementation: orderCheckCode
      }
    },
    // Escalate to human
    {
      type: 'function',
      function: {
        name: 'escalate_to_human',
        description: 'Escalate complex issues to human support',
        parameters: {
          type: 'object',
          properties: {
            issue_summary: { type: 'string' },
            priority: { type: 'string', enum: ['low', 'medium', 'high'] }
          }
        },
        implementation: escalationCode
      }
    }
  ]
});

Troubleshooting

Common Issues

  1. Tool Execution Timeouts
    javascript // Increase timeout for long-running tools { type: 'function', function: { name: 'process_data', timeout: 30000, // 30 seconds implementation: '...' } }

  2. WebSocket Connection Drops
    ```javascript
    // Implement reconnection logic
    let reconnectAttempts = 0;

function connectWithRetry() {
const ws = new WebSocket(wsUrl);

 ws.onclose = () => {
   if (reconnectAttempts < 5) {
     reconnectAttempts++;
     setTimeout(connectWithRetry, 1000 * reconnectAttempts);
   }
 };

 ws.onopen = () => {
   reconnectAttempts = 0;
 };

}
```

  1. Rate Limiting
    javascript // Implement exponential backoff async function callWithRetry(fn, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { return await fn(); } catch (error) { if (error.status === 429 && i < maxRetries - 1) { await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000)); } else { throw error; } } } }

Next Steps

For more information, visit docs.ragwalla.com.