Skip to main content

Node.js — Chat basico

import { Thaliq } from '@thaliq/sdk';

const thaliq = new Thaliq({
  apiKey: 'tq_live_TU_API_KEY',
});

async function main() {
  const response = await thaliq.agent.chat('¿Que servicios ofrecen?');
  console.log(response.message);
}

main();

Node.js — Streaming en terminal

import { Thaliq } from '@thaliq/sdk';

const thaliq = new Thaliq({
  apiKey: 'tq_live_TU_API_KEY',
});

async function main() {
  const stream = thaliq.agent.stream('Analiza las tendencias de ventas');

  for await (const event of stream) {
    switch (event.type) {
      case 'content.delta':
        process.stdout.write(event.delta);
        break;
      case 'tool.start':
        console.log(`\n> Ejecutando: ${event.tool}`);
        break;
      case 'tool.end':
        console.log(`> ${event.tool}: ${event.success ? 'OK' : 'Error'}`);
        break;
    }
  }

  console.log('\n---');
  console.log('Conversacion:', stream.conversationId);
}

main();

Express — API endpoint con streaming

Expone el agente de Thaliq como un endpoint SSE en tu backend:
import express from 'express';
import { Thaliq } from '@thaliq/sdk';

const app = express();
app.use(express.json());

const thaliq = new Thaliq({
  apiKey: 'tq_live_TU_API_KEY',
});

app.post('/api/ask', async (req, res) => {
  const { message, userId, conversationId } = req.body;

  // Identificar al usuario
  thaliq.identify({ userId });

  // Configurar SSE
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  const stream = thaliq.agent.stream(message, { conversationId });

  for await (const event of stream) {
    res.write(`data: ${JSON.stringify(event)}\n\n`);
  }

  res.write(`data: ${JSON.stringify({ type: 'done', conversationId: stream.conversationId })}\n\n`);
  res.end();
});

app.listen(3001, () => console.log('Listening on :3001'));

Express — HITL completo

Flujo con accion interactiva (consent/confirm):
import express from 'express';
import { Thaliq, ActionResponseBuilder } from '@thaliq/sdk';

const app = express();
app.use(express.json());

const thaliq = new Thaliq({ apiKey: 'tq_live_TU_API_KEY' });

// Paso 1: Enviar mensaje, puede retornar una accion
app.post('/api/agent/message', async (req, res) => {
  const { message, userId, conversationId } = req.body;
  thaliq.identify({ userId });

  const stream = thaliq.agent.stream(message, { conversationId });
  let text = '';

  for await (const event of stream) {
    if (event.type === 'content.delta') text += event.delta;
  }

  res.json({
    text,
    conversationId: stream.conversationId,
    pendingAction: stream.pendingAction,  // null si no hay accion
    status: stream.status,
  });
});

// Paso 2: Responder a una accion HITL
app.post('/api/agent/action', async (req, res) => {
  const { conversationId, originalMessage, instructionId, accepted } = req.body;

  const actionResponse = accepted
    ? ActionResponseBuilder.accept(instructionId)
    : ActionResponseBuilder.reject(instructionId);

  const resumed = thaliq.agent.respondToAction({
    conversationId,
    originalMessage,
    actionResponse,
  });

  let text = '';
  for await (const event of resumed) {
    if (event.type === 'content.delta') text += event.delta;
  }

  res.json({
    text,
    conversationId: resumed.conversationId,
    status: resumed.status,
  });
});

app.listen(3001);

Multiples conversaciones

Gestiona varias conversaciones en paralelo:
import { Thaliq } from '@thaliq/sdk';

const thaliq = new Thaliq({ apiKey: 'tq_live_TU_API_KEY' });

// Crear dos conversaciones
const conv1 = thaliq.conversations.create();
const conv2 = thaliq.conversations.create();

// Conversacion 1: tema de ventas
const stream1 = thaliq.agent.stream('Dame el resumen de ventas', {
  conversationId: conv1.id,
});

// Conversacion 2: tema de soporte
const stream2 = thaliq.agent.stream('¿Cuantos tickets abiertos hay?', {
  conversationId: conv2.id,
});

// Consumir ambas en paralelo
const [text1, text2] = await Promise.all([
  stream1.text(),
  stream2.text(),
]);

console.log('Ventas:', text1);
console.log('Soporte:', text2);

Manejo de errores

import { Thaliq, RateLimitError, AuthError, ThaliqError } from '@thaliq/sdk';

const thaliq = new Thaliq({ apiKey: 'tq_live_TU_API_KEY' });

// Listener global para errores
thaliq.on('error', (err) => {
  console.error('[Thaliq Error]', err.code, err.message);
});

// Listener para rate limits
thaliq.on('rateLimit', (info) => {
  console.warn(`Rate limited. Retry en ${info.retryAfter}s`);
});

// Manejo por tipo de error
async function askAgent(message: string) {
  try {
    return await thaliq.agent.chat(message);
  } catch (error) {
    if (error instanceof RateLimitError) {
      // Esperar y reintentar
      await new Promise(r => setTimeout(r, (error.retryAfter ?? 5) * 1000));
      return thaliq.agent.chat(message);
    }
    if (error instanceof AuthError) {
      throw new Error('API Key invalida — verifica tu configuracion');
    }
    if (error instanceof ThaliqError) {
      throw new Error(`Error del agente: ${error.message}`);
    }
    throw error;
  }
}