> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vultlocal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> Internal architecture and flow of the Agent-TS service

# Agent-TS Architecture

This document covers the internal architecture of Agent-TS, including the component structure, message flow, and extension patterns.

## Component Overview

```mermaid theme={null}
graph TB
    subgraph "Entry Points"
        WH1["/api/v1/external/whatsapp"]
        WH2["/api/v1/webhooks/whatsapp"]
        HEALTH["/health"]
    end

    subgraph "Core"
        IDX["index.ts<br/>Express Server"]
        OA["olive-agent.ts<br/>OpenAI Agent"]
        GC["gateway-client.ts<br/>API Client"]
    end

    subgraph "Tools"
        TW["wallet.ts"]
        TC["cards.ts"]
        TK["kyc.ts"]
        TR["registration.ts"]
        TA["agent.ts"]
    end

    subgraph "Services"
        OCR["ocr-service.ts"]
        IDV["id-card-validator.ts"]
        S3["s3-uploader.ts"]
        IMG["image-compressor.ts"]
    end

    subgraph "Security"
        SAV["service-auth-verifier.ts"]
        RL["rate-limiter.ts"]
        CS["chat-security.ts"]
        IS["input-sanitizer.ts"]
    end

    WH1 --> IDX
    WH2 --> IDX
    HEALTH --> IDX

    IDX --> OA
    OA --> TW & TC & TK & TR & TA
    TW & TC & TR & TA --> GC
    TK --> OCR & IDV & S3
    IDV --> IMG
```

## File Responsibilities

### Core Files

| File                | Responsibility                                          |
| ------------------- | ------------------------------------------------------- |
| `index.ts`          | Express server, webhook routes, agent lifecycle         |
| `olive-agent.ts`    | OpenAI client, assistant management, conversation state |
| `gateway-client.ts` | Gateway API client with typed interfaces                |
| `config.ts`         | Environment variable parsing and defaults               |
| `logger.ts`         | Pino logging adapter                                    |

### Tools Directory

| File              | Functions                                                                      |
| ----------------- | ------------------------------------------------------------------------------ |
| `wallet.ts`       | `check_balance`, `get_transactions`, `initiate_transfer`, `get_account_limits` |
| `cards.ts`        | `get_user_cards`, `link_card`, `block_card`, `unblock_card`                    |
| `kyc.ts`          | `upload_kyc_image`, `upgrade_kyc`                                              |
| `registration.ts` | `register_subscriber`                                                          |
| `agent.ts`        | Agent-specific operations                                                      |

### Service Files

| File                   | Responsibility                               |
| ---------------------- | -------------------------------------------- |
| `ocr-service.ts`       | Tesseract.js OCR extraction and scoring      |
| `id-card-validator.ts` | OpenAI Vision + heuristics for ID validation |
| `image-compressor.ts`  | Image optimization before upload             |
| `s3-uploader.ts`       | Private S3 uploads with pre-signed URLs      |

## Request Flow

### Text Message Processing

```mermaid theme={null}
sequenceDiagram
    participant W as Webhook
    participant I as index.ts
    participant A as olive-agent.ts
    participant O as OpenAI API
    participant T as Tool Handler
    participant G as Gateway

    W->>I: POST /external/whatsapp
    I->>I: Validate & sanitize input
    I->>A: processMessage(phone, text)
    A->>A: Get/create conversation thread
    A->>O: Create message in thread
    A->>O: Run assistant
    
    loop Tool Calls
        O-->>A: tool_calls[]
        A->>T: Execute tool handler
        T->>G: API call (if needed)
        G-->>T: Response
        T-->>A: Tool result
        A->>O: Submit tool outputs
    end
    
    O-->>A: Final response text
    A-->>I: Response message
    I-->>W: JSON response
```

### Image Upload Processing

```mermaid theme={null}
sequenceDiagram
    participant W as Webhook
    participant I as index.ts
    participant A as olive-agent.ts
    participant ID as id-card-validator
    participant OCR as ocr-service
    participant S3 as s3-uploader
    participant G as Gateway

    W->>I: POST with media data
    I->>I: Extract base64 image
    I->>A: processMessage with media context
    A->>OCR: Extract text from image
    OCR-->>A: OCR result + confidence
    A->>ID: Validate ID card
    ID->>ID: Vision API check
    ID->>ID: Heuristic validation
    ID-->>A: Validation result
    
    alt Valid Document
        A->>S3: Upload to S3
        S3-->>A: s3:// URI
        A->>G: Update KYC status
        G-->>A: Success
    else Invalid Document
        A-->>W: Request retry with issues
    end
```

## OpenAI Integration

### Assistant Configuration

```typescript theme={null}
const assistant = await openai.beta.assistants.create({
  name: "OLIVE Wallet Assistant",
  model: "gpt-4o-mini",
  instructions: `You are a helpful assistant for OLIVE mobile wallet users.
    Help users check balances, send money, and manage their cards.
    Always verify transaction details before executing.`,
  tools: toolDefinitions
});
```

### Tool Registration Pattern

```typescript theme={null}
// Define the tool schema
export const checkBalanceDefinition = {
  type: "function" as const,
  function: {
    name: "check_balance",
    description: "Get the user's current wallet balance",
    parameters: {
      type: "object",
      properties: {
        currency: {
          type: "string",
          enum: ["SLE", "USD"],
          description: "Currency to check balance for"
        }
      },
      required: []
    }
  }
};

// Implement the handler
export async function checkBalanceHandler(
  args: { currency?: string },
  context: ToolContext
): Promise<ToolResult> {
  const balance = await gatewayClient.getBalance(
    context.userId,
    args.currency || "SLE"
  );
  
  return {
    success: true,
    data: balance,
    message: `Balance: ${balance.balance} ${balance.currency}`
  };
}
```

## Security Layers

### Input Sanitization

```typescript theme={null}
// chat-security.ts
export function sanitizeInput(input: string): string {
  // Remove potential injection attacks
  // Validate phone number format
  // Strip control characters
  return sanitized;
}
```

### Rate Limiting

```typescript theme={null}
// rate-limiter.ts
const limiter = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 30, // 30 requests per minute per phone
  keyGenerator: (req) => req.body.phoneE164
});
```

### Service Authentication

For internal service calls, the agent uses HMAC-based authentication:

```typescript theme={null}
// service-auth.ts
export function generateServiceAuthHeader(
  secret: string,
  timestamp: string,
  body: string
): string {
  const signature = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}${body}`)
    .digest('hex');
  return `HMAC ${timestamp}:${signature}`;
}
```

## Error Handling

### Graceful Degradation

```typescript theme={null}
try {
  const result = await gatewayClient.transfer(params);
  return { success: true, data: result };
} catch (error) {
  if (error.code === 'INSUFFICIENT_BALANCE') {
    return {
      success: false,
      error: 'Insufficient balance for this transfer',
      userMessage: 'You do not have enough balance. Please top up.'
    };
  }
  // Log and return generic error
  logger.error('Transfer failed', { error, params });
  return {
    success: false,
    error: 'Transfer failed',
    userMessage: 'Unable to complete transfer. Please try again.'
  };
}
```

## Extension Guide

### Adding a New Tool

1. Create the tool definition and handler:

```typescript theme={null}
// src/tools/my-tool.ts
export const myToolDefinition = {
  type: "function" as const,
  function: {
    name: "my_tool",
    description: "Description of what this tool does",
    parameters: {
      type: "object",
      properties: {
        param1: { type: "string" }
      },
      required: ["param1"]
    }
  }
};

export async function myToolHandler(
  args: { param1: string },
  context: ToolContext
): Promise<ToolResult> {
  // Implementation
  return { success: true, data: result };
}
```

2. Register in `olive-agent.ts`:

```typescript theme={null}
import { myToolDefinition, myToolHandler } from './tools/my-tool';

toolDefinitions.push(myToolDefinition);
toolHandlers['my_tool'] = myToolHandler;
```

3. Restart the agent to apply changes.

## Next Steps

<CardGroup cols={2}>
  <Card title="Configuration" icon="gear" href="/agent-ts/configuration">
    Environment variables reference
  </Card>

  <Card title="Tools Reference" icon="wrench" href="/agent-ts/tools">
    Complete tool documentation
  </Card>
</CardGroup>
