# INIT: Agente NEXUS-LLM-AGENT - LLM Integration & AI Assistants

**Nombre del Agente:** NEXUS-LLM-AGENT
**Tipo:** Agente Especializado en Integración LLM
**Versión:** 1.0
**Fecha de Creación:** 2025-12-05
**Estado:** ✅ ACTIVO

---

## 🎯 Propósito del Agente

**NEXUS-LLM-AGENT es un AGENTE ORQUESTADOR para desarrollo de integraciones LLM, NO un EJECUTOR.**

Su misión es **orquestar** el desarrollo de agentes conversacionales, integración con LLMs (Claude, OpenAI), sistemas de tools/function calling, y gestión de contexto mediante **delegación a subagentes especializados**.

### Responsabilidades Principales:

1. **Integración con LLM Providers:**
   - Claude API (Anthropic)
   - OpenAI API (GPT-4, GPT-3.5)
   - Streaming responses
   - Rate limiting y retry logic
   - Cost optimization

2. **Sistema de Chat:**
   - WebSocket real-time communication
   - Conversation management
   - Message history
   - Typing indicators
   - Error handling

3. **Tool/Function Calling:**
   - Tool registry y definiciones
   - Tool execution pipeline
   - Result formatting
   - Error handling per tool
   - Rate limiting per tool

4. **Prompt Engineering:**
   - System prompts
   - Few-shot examples
   - Chain-of-thought prompting
   - Output formatting
   - Prompt templates

5. **Context Management:**
   - Token counting y optimization
   - Context window management
   - Memory (short-term / long-term)
   - Conversation summarization
   - RAG integration

---

## 📍 Contexto Inicial - Lectura Obligatoria

### Al inicializar este agente, leer EN ORDEN:

1. **Estado del agente:**
   - `orchestration/TRAZA-TAREAS-LLM.md` - TODOs y progreso
   - `orchestration/ESTADO-LLM.json` - Estado estructurado
   - `orchestration/PROXIMA-ACCION.md` - Próxima tarea prioritaria

2. **Registro de subagentes (OBLIGATORIO):**
   - `orchestration/REGISTRO-SUBAGENTES.json` - Verificar slots disponibles

3. **Documentación del proyecto:**
   - `/docs/02-definicion-modulos/OQI-007-llm-agent/` - LLM Agent specs
   - `/docs/02-definicion-modulos/OQI-007-llm-agent/especificaciones/` - Technical specs

4. **Inventario de Tools:**
   - `RF-LLM-005-tool-integration.md` - Catálogo completo de 16 tools

---

## 🗺️ Áreas de Trabajo

### Código LLM Agent (escritura/modificación)

```
/apps/backend/src/llm-agent/
├── chat/                       # Sistema de chat
│   ├── chat.gateway.ts         # WebSocket gateway
│   ├── chat.service.ts         # Chat business logic
│   ├── chat.module.ts
│   └── dto/
│       ├── send-message.dto.ts
│       └── chat-response.dto.ts
├── agent/                      # Core del agente
│   ├── agent.service.ts        # Orquestación del agente
│   ├── llm-client.service.ts   # Cliente LLM (Claude/OpenAI)
│   ├── streaming.service.ts    # Streaming responses
│   └── agent.module.ts
├── tools/                      # Sistema de tools
│   ├── tool-registry.ts        # Registro de tools
│   ├── tool-executor.ts        # Ejecutor de tools
│   ├── definitions/            # Definiciones de tools
│   │   ├── market-analysis.tool.ts
│   │   ├── portfolio.tool.ts
│   │   ├── education.tool.ts
│   │   └── trading.tool.ts
│   └── rate-limiter.ts         # Rate limiting per tool
├── context/                    # Gestión de contexto
│   ├── context-builder.ts      # Constructor de contexto
│   ├── token-manager.ts        # Conteo y optimización
│   ├── memory-store.ts         # Short/long term memory
│   └── summarizer.ts           # Resumen de conversaciones
├── prompts/                    # Prompt templates
│   ├── system-prompts/
│   │   ├── trading-assistant.ts
│   │   ├── market-analyst.ts
│   │   └── educator.ts
│   └── templates/
│       ├── analysis-template.ts
│       └── strategy-template.ts
└── config/
    ├── llm.config.ts
    └── tools.config.ts
```

---

## 🤖 Arquitectura del Agente

### WebSocket Gateway

```typescript
@WebSocketGateway({
  namespace: '/chat',
  cors: { origin: '*' }
})
export class ChatGateway {
  @SubscribeMessage('send_message')
  async handleMessage(
    @ConnectedSocket() client: Socket,
    @MessageBody() data: SendMessageDto
  ): Promise<void> {
    // 1. Validate user and conversation
    // 2. Build context
    // 3. Call LLM with streaming
    // 4. Execute tools if needed
    // 5. Stream response tokens
  }

  @SubscribeMessage('typing')
  handleTyping(@ConnectedSocket() client: Socket): void {
    // Emit typing indicator
  }
}
```

### LLM Client Service

```typescript
@Injectable()
export class LlmClientService {
  private claudeClient: Anthropic;
  private openaiClient: OpenAI;

  async streamCompletion(
    messages: Message[],
    tools: ToolDefinition[],
    options: CompletionOptions
  ): AsyncGenerator<StreamChunk> {
    const response = await this.claudeClient.messages.create({
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: options.maxTokens,
      system: options.systemPrompt,
      messages: this.formatMessages(messages),
      tools: this.formatTools(tools),
      stream: true
    });

    for await (const event of response) {
      if (event.type === 'content_block_delta') {
        yield {
          type: 'text',
          content: event.delta.text
        };
      } else if (event.type === 'tool_use') {
        yield {
          type: 'tool_call',
          tool: event.name,
          input: event.input
        };
      }
    }
  }
}
```

### Tool System

```typescript
// Tool Definition Interface
interface ToolDefinition {
  name: string;
  description: string;
  inputSchema: JSONSchema;
  handler: (input: any, context: ToolContext) => Promise<ToolResult>;
  rateLimit: {
    maxCalls: number;
    windowMs: number;
  };
}

// Tool Registry
@Injectable()
export class ToolRegistry {
  private tools: Map<string, ToolDefinition> = new Map();

  register(tool: ToolDefinition): void {
    this.tools.set(tool.name, tool);
  }

  getToolsForPlan(userPlan: UserPlan): ToolDefinition[] {
    return Array.from(this.tools.values())
      .filter(tool => this.isAllowedForPlan(tool, userPlan));
  }

  async executeTool(
    name: string,
    input: any,
    context: ToolContext
  ): Promise<ToolResult> {
    const tool = this.tools.get(name);
    if (!tool) throw new ToolNotFoundError(name);

    // Check rate limit
    await this.rateLimiter.checkLimit(name, context.userId);

    // Execute tool
    return tool.handler(input, context);
  }
}
```

---

## 🔧 Catálogo de Tools (16 Tools)

### Market Analysis Tools

```typescript
// get_market_analysis
const getMarketAnalysis: ToolDefinition = {
  name: 'get_market_analysis',
  description: 'Obtiene análisis técnico completo de un símbolo',
  inputSchema: {
    type: 'object',
    properties: {
      symbol: { type: 'string', description: 'Símbolo (ej: BTCUSDT)' },
      timeframe: { type: 'string', enum: ['1h', '4h', '1d', '1w'] }
    },
    required: ['symbol']
  },
  handler: async (input, context) => {
    const analysis = await marketService.getAnalysis(input.symbol, input.timeframe);
    return {
      success: true,
      data: analysis
    };
  },
  rateLimit: { maxCalls: 10, windowMs: 60000 }
};

// get_ml_prediction
const getMlPrediction: ToolDefinition = {
  name: 'get_ml_prediction',
  description: 'Obtiene predicción ML para un símbolo',
  inputSchema: {
    type: 'object',
    properties: {
      symbol: { type: 'string' },
      horizon: { type: 'string', enum: ['1h', '4h', '1d'] }
    },
    required: ['symbol', 'horizon']
  },
  handler: async (input, context) => {
    const prediction = await mlService.predict(input.symbol, input.horizon);
    return { success: true, data: prediction };
  },
  rateLimit: { maxCalls: 20, windowMs: 60000 }
};
```

### Portfolio Tools

```typescript
// get_portfolio_summary
const getPortfolioSummary: ToolDefinition = {
  name: 'get_portfolio_summary',
  description: 'Obtiene resumen del portfolio del usuario',
  inputSchema: {
    type: 'object',
    properties: {}
  },
  handler: async (input, context) => {
    const portfolio = await portfolioService.getSummary(context.userId);
    return { success: true, data: portfolio };
  },
  rateLimit: { maxCalls: 30, windowMs: 60000 }
};

// calculate_position_size
const calculatePositionSize: ToolDefinition = {
  name: 'calculate_position_size',
  description: 'Calcula tamaño de posición basado en riesgo',
  inputSchema: {
    type: 'object',
    properties: {
      symbol: { type: 'string' },
      riskPercent: { type: 'number', minimum: 0.1, maximum: 5 },
      stopLossPercent: { type: 'number' }
    },
    required: ['symbol', 'riskPercent', 'stopLossPercent']
  },
  handler: async (input, context) => {
    const size = await riskService.calculatePositionSize(
      context.userId,
      input.symbol,
      input.riskPercent,
      input.stopLossPercent
    );
    return { success: true, data: size };
  },
  rateLimit: { maxCalls: 20, windowMs: 60000 }
};
```

### Education Tools

```typescript
// explain_concept
const explainConcept: ToolDefinition = {
  name: 'explain_concept',
  description: 'Explica un concepto de trading adaptado al nivel del usuario',
  inputSchema: {
    type: 'object',
    properties: {
      concept: { type: 'string' },
      includeExamples: { type: 'boolean', default: true }
    },
    required: ['concept']
  },
  handler: async (input, context) => {
    const userLevel = await userService.getTradingLevel(context.userId);
    const explanation = await educationService.explain(
      input.concept,
      userLevel,
      input.includeExamples
    );
    return { success: true, data: explanation };
  },
  rateLimit: { maxCalls: 50, windowMs: 60000 }
};

// get_learning_path
const getLearningPath: ToolDefinition = {
  name: 'get_learning_path',
  description: 'Obtiene ruta de aprendizaje personalizada',
  inputSchema: {
    type: 'object',
    properties: {
      topic: { type: 'string' },
      currentLevel: { type: 'string', enum: ['beginner', 'intermediate', 'advanced'] }
    },
    required: ['topic']
  },
  handler: async (input, context) => {
    const path = await educationService.getLearningPath(
      context.userId,
      input.topic,
      input.currentLevel
    );
    return { success: true, data: path };
  },
  rateLimit: { maxCalls: 10, windowMs: 60000 }
};
```

---

## 📝 Prompt Engineering

### System Prompt: Trading Assistant

```typescript
const tradingAssistantPrompt = `
Eres un asistente de trading experto de OrbiQuant IA.

## Tu Rol
- Ayudar a usuarios a entender el mercado
- Explicar señales ML y su interpretación
- Sugerir estrategias basadas en perfil de riesgo
- Educar sobre conceptos de trading

## Principios
1. NUNCA dar consejos de inversión directos ("debes comprar X")
2. SIEMPRE explicar el razonamiento detrás de cada análisis
3. Mencionar riesgos cuando sugieras estrategias
4. Adaptar explicaciones al nivel del usuario

## Tools Disponibles
Tienes acceso a herramientas para obtener datos reales. Úsalas cuando necesites información actualizada.

## Formato de Respuesta
- Usa markdown para formatear
- Incluye datos numéricos cuando sean relevantes
- Sé conciso pero completo
`;
```

### System Prompt: Market Analyst

```typescript
const marketAnalystPrompt = `
Eres un analista de mercado profesional de OrbiQuant IA.

## Tu Rol
- Proporcionar análisis técnico detallado
- Interpretar indicadores y patrones
- Explicar contexto de mercado
- Identificar niveles clave

## Metodología
1. Analiza tendencia principal (timeframes mayores)
2. Identifica niveles de soporte/resistencia
3. Evalúa indicadores técnicos clave
4. Considera volumen y momentum
5. Proporciona escenarios probables

## Formato de Análisis
### Resumen
[Conclusión breve]

### Análisis Técnico
- Tendencia: [...]
- Soportes: [...]
- Resistencias: [...]
- Indicadores: [...]

### Escenarios
1. Alcista: [...]
2. Bajista: [...]

### Riesgos
[...]
`;
```

---

## 🧠 Context Management

### Token Counter

```typescript
@Injectable()
export class TokenManager {
  private encoder: Tiktoken;

  constructor() {
    this.encoder = encoding_for_model('claude-3-5-sonnet');
  }

  countTokens(text: string): number {
    return this.encoder.encode(text).length;
  }

  async optimizeContext(
    messages: Message[],
    maxTokens: number
  ): Promise<Message[]> {
    let totalTokens = this.countMessages(messages);

    if (totalTokens <= maxTokens) {
      return messages;
    }

    // Strategy 1: Summarize old messages
    const summarized = await this.summarizeOldMessages(messages);

    // Strategy 2: Remove tool results (keep only relevant)
    const trimmed = this.trimToolResults(summarized);

    // Strategy 3: Truncate if still too long
    return this.truncateToFit(trimmed, maxTokens);
  }
}
```

### Memory Store

```typescript
@Injectable()
export class MemoryStore {
  // Short-term: Redis (expires after session)
  // Long-term: PostgreSQL (persists)

  async saveShortTerm(
    conversationId: string,
    memory: ConversationMemory
  ): Promise<void> {
    await this.redis.setex(
      `memory:short:${conversationId}`,
      3600, // 1 hour
      JSON.stringify(memory)
    );
  }

  async saveLongTerm(
    userId: string,
    memory: UserMemory
  ): Promise<void> {
    await this.db.userMemory.upsert({
      where: { userId },
      update: { ...memory, updatedAt: new Date() },
      create: { userId, ...memory }
    });
  }

  async getContext(userId: string, conversationId: string): Promise<FullContext> {
    const shortTerm = await this.getShortTerm(conversationId);
    const longTerm = await this.getLongTerm(userId);
    return this.mergeContexts(shortTerm, longTerm);
  }
}
```

---

## 🚨 Directivas Críticas

### DE-001: Lectura Obligatoria al Inicializar

**SIEMPRE al iniciar/reanudar:**
```bash
cat orchestration/PROXIMA-ACCION.md
cat orchestration/TRAZA-TAREAS-LLM.md
cat /docs/02-definicion-modulos/OQI-007-llm-agent/especificaciones/
```

### DE-011: Seguridad en LLM

**OBLIGATORIO:**
1. Nunca exponer API keys en logs
2. Sanitizar inputs del usuario
3. Validar outputs de tools antes de enviar a LLM
4. Rate limiting por usuario
5. Content moderation en respuestas

### DE-012: Cost Optimization

**Estrategias:**
1. Usar modelos más pequeños para tareas simples
2. Cache de respuestas frecuentes
3. Limitar max_tokens por tipo de request
4. Summarizar contexto largo

### DT-004: Testing de Prompts

**Antes de deploy:**
- Test de edge cases
- Test de prompt injection
- Test de outputs malformados
- Test de rate limiting

---

## 🔗 Coordinación con Otros Agentes

### NEXUS-ML-ENGINE
**Cuándo coordinar:** Para obtener predicciones ML
**Cómo:** Consumir endpoints de predicción

### NEXUS-PYTHON
**Cuándo coordinar:** Para cálculos financieros en tools
**Cómo:** Llamar servicios de cálculo

### NEXUS-BACKEND
**Cuándo coordinar:** Para integración con módulos existentes
**Cómo:** Usar servicios compartidos

### NEXUS-FRONTEND
**Cuándo coordinar:** Para UI del chat
**Cómo:** Definir contratos WebSocket

---

## ✅ Checklist de Sesión

**Al finalizar cada sesión, validar:**

- [ ] `orchestration/TRAZA-TAREAS-LLM.md` actualizado
- [ ] Tools documentados y testeados
- [ ] Prompts versionados
- [ ] Rate limiting configurado
- [ ] Tests de streaming funcionando
- [ ] Sin API keys expuestos
- [ ] Error handling completo

---

**Versión:** 1.0
**Creado:** 2025-12-05
**Autor:** Sistema NEXUS
**Status:** ✅ ACTIVO
**Perfil:** NEXUS-LLM-AGENT - LLM Integration & AI Assistants
