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

# Conversaciones

> Como manejar threads de conversacion con el SDK

Las conversaciones permiten mantener contexto entre mensajes. El SDK gestiona `conversationId` automaticamente, o puedes controlarlo manualmente.

## Auto-tracking

Por defecto, el SDK trackea la conversacion activa automaticamente:

```typescript theme={null}
// Primer mensaje — se crea una conversacion nueva
const stream1 = thaliq.agent.stream('Hola, necesito ayuda');
for await (const event of stream1) { /* ... */ }

// El conversationId se guarda automaticamente
console.log(stream1.conversationId); // 'abc-123-...'
```

## Conversaciones manuales

Crea y gestiona conversaciones explicitamente:

```typescript theme={null}
// Crear una nueva conversacion
const conv = thaliq.conversations.create();

// Primer mensaje
const stream1 = thaliq.agent.stream('Hola', {
  conversationId: conv.id,
});
const response1 = await stream1.finalResponse();

// Segundo mensaje (misma conversacion, mantiene contexto)
const stream2 = thaliq.agent.stream('Dame mas detalles', {
  conversationId: conv.id,
});
const response2 = await stream2.finalResponse();
```

## ConversationManager

El SDK expone `thaliq.conversations` para gestionar conversaciones:

```typescript theme={null}
// Crear nueva conversacion
const conv = thaliq.conversations.create();
console.log(conv.id);        // UUID generado
console.log(conv.createdAt); // Date

// Ver conversacion activa
console.log(thaliq.conversations.active); // ConversationRef | null

// Cambiar conversacion activa
thaliq.conversations.setActive(conv.id);

// Historial de conversaciones (esta sesion)
console.log(thaliq.conversations.history); // ConversationRef[]

// Limpiar historial
thaliq.conversations.clear();
```

## Nueva conversacion vs continuacion

| Escenario                                   | Comportamiento                  |
| ------------------------------------------- | ------------------------------- |
| `stream('Hola')` sin `conversationId`       | Crea conversacion nueva         |
| `stream('Hola', { conversationId: 'xxx' })` | Continua conversacion existente |
| Despues de `thaliq.reset()`                 | Limpia conversacion activa      |

<Warning>
  **No envies valores reservados como `conversationId`** (literal `"pending"`, `"new"`, `"null"`, `"undefined"`, vacios, o ids de menos de 16 caracteres). El backend los rechaza y genera uno nuevo, pero loggea un warning de seguridad. Estos valores fueron causa de un bug previo de cross-tenant context leakage; ahora estan bloqueados explicitamente. Usa el id real de una conversacion existente o no envies el campo.
</Warning>

## Session timeout

Las conversaciones tienen un **session timeout** configurable por agente (default: 30 minutos). Si la ultima interaccion fue hace mas de 30 minutos, el backend crea una conversacion nueva automaticamente.

## Aislamiento por agente

Cada conversacion esta ligada al agente que la atendio. Si reusas un `conversationId` pero apuntas a un agente distinto, el backend detecta el mismatch y crea una conversacion nueva (no mezcla contextos). Esto evita que un cambio de `agentId` herede historial de otro agente.

## Persistencia

Las conversaciones se persisten en el backend con TTL segun tu plan:

| Plan       | Retencion |
| ---------- | --------- |
| Starter    | 7 dias    |
| Growth     | 30 dias   |
| Enterprise | 90+ dias  |

<Info>
  El `ConversationManager` del SDK solo trackea conversaciones **en memoria** (de la sesion actual). Los datos se persisten en el backend automaticamente.
</Info>

## Feedback en conversaciones

Puedes enviar feedback sobre mensajes individuales dentro de una conversacion:

```typescript theme={null}
const stream = thaliq.agent.stream('Analiza mis datos', {
  conversationId: 'conv-123',
});

const response = await stream.finalResponse();

// El messageId viene en la metadata
if (response.metadata.messageId) {
  await thaliq.agent.feedback({
    conversationId: 'conv-123',
    messageId: response.metadata.messageId,
    feedback: 'positive',
  });
}
```

Ver [Feedback e Insights](/sdk/feedback) para mas detalles.

## Acciones HITL inline

Cuando una instruccion dispara una accion (consent / confirm / select / form), la accion se entrega como un evento `action` y el stream se cierra. Para continuar la conversacion **dentro del mismo turno y mensaje**, mandas un nuevo request con `actionResponse`:

```typescript theme={null}
// Stream 1 — recibe la accion
const stream = thaliq.agent.stream('Quiero agendar una cita', {
  conversationId: 'conv-123',
});

let pendingAction;
for await (const event of stream) {
  if (event.type === 'action') {
    pendingAction = event;
    break; // El stream se cierra
  }
}

// El usuario decide en tu UI...
const userAccepted = true;

// Stream 2 — resume con la respuesta de la accion
const resumeStream = thaliq.agent.stream('Quiero agendar una cita', {
  conversationId: 'conv-123',
  actionResponse: {
    instructionId: pendingAction.instructionId,
    accepted: userAccepted,
  },
});

for await (const event of resumeStream) {
  // Siguen llegando content.delta, tool.start/end, etc.
  // El backend persiste todo (texto pre-accion + accion resuelta + tool calls + texto post-accion)
  // como UN SOLO mensaje del asistente con multiples parts en orden cronologico.
}
```

Ver [HITL](/sdk/hitl) para los formatos de `actionResponse` por tipo (consent, confirm, select, form).
