Skip to main content

Basic Chat

Send messages to a chat agent and get a response:
import Reminix from '@reminix/sdk';

const client = new Reminix();

const response = await client.agents.chat('chat-assistant', {
  messages: [
    { role: 'user', content: 'Hello! What can you do?' }
  ]
});

// Returns messages array with assistant responses
for (const msg of response.messages) {
  console.log(msg.content);
}

// If conversation persistence is enabled, a conversation_id is returned
if (response.conversation_id) {
  console.log(`Conversation ID: ${response.conversation_id}`);
}

Message Format

OpenAI-compatible: roles system, developer, user, assistant, tool; content is string, array of parts (e.g. text, image_url), or null. Use Message and ToolCall from @reminix/runtime for handlers; use messageContentToText when displaying content that may be an array.
const response = await client.agents.chat('chat-assistant', {
  messages: [
    // System message (optional) - sets behavior
    { role: 'system', content: 'You are a helpful assistant.' },
    
    // User message
    { role: 'user', content: 'Hello!' },
    
    // Assistant message (from previous response)
    { role: 'assistant', content: 'Hi! How can I help?' },
    
    // Another user message
    { role: 'user', content: "What's the weather?" }
  ]
});

Conversations

Maintain conversation history:
interface Message {
  role: 'user' | 'assistant' | 'system';
  content: string;
}

const messages: Message[] = [];

async function chat(userMessage: string): Promise<string> {
  // Add user message
  messages.push({ role: 'user', content: userMessage });
  
  // Get response
  const response = await client.agents.chat('chat-assistant', { messages });
  
  // Extract assistant message (first message in response)
  const assistantMessage = response.messages[0];
  
  // Add assistant response to history
  messages.push({ role: assistantMessage.role, content: assistantMessage.content });
  
  return assistantMessage.content;
}

// Conversation
console.log(await chat('Hello!'));
// "Hi! How can I help you today?"

console.log(await chat("What's the capital of France?"));
// "The capital of France is Paris."

console.log(await chat('What about Germany?'));
// "The capital of Germany is Berlin."

Multimodal Content

Send images alongside text:
const response = await client.agents.chat('vision-agent', {
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: "What's in this image?" },
        {
          type: 'image_url',
          image_url: { url: 'https://example.com/image.jpg' }
        }
      ]
    }
  ]
});

Base64 Images

import fs from 'fs';

const imageData = fs.readFileSync('image.png').toString('base64');

const response = await client.agents.chat('vision-agent', {
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: 'Describe this image' },
        {
          type: 'image_url',
          image_url: { url: `data:image/png;base64,${imageData}` }
        }
      ]
    }
  ]
});

Streaming Chat

Stream responses for real-time chat UI:
const stream = await client.agents.chat('chat-assistant', {
  messages: [{ role: 'user', content: 'Tell me a story' }],
  stream: true
});

process.stdout.write('Assistant: ');
for await (const chunk of stream) {
  process.stdout.write(chunk);
}
console.log();

Collecting Streamed Response

const chunks: string[] = [];

const stream = await client.agents.chat('chat-assistant', {
  messages,
  stream: true
});

for await (const chunk of stream) {
  chunks.push(chunk);
  process.stdout.write(chunk);
}

const fullResponse = chunks.join('');

// Add to conversation history
messages.push({ role: 'assistant', content: fullResponse });

With Context

Pass additional context:
const response = await client.agents.chat('support-agent', {
  messages: [{ role: 'user', content: "What's my order status?" }],
  context: {
    identity: {
      user_id: 'user_456'
    },
    order_id: 'order_789',
    customer_tier: 'premium'
  }
});

Tool Calls

If your agent uses tools/functions:
const response = await client.agents.chat('assistant', {
  messages: [{ role: 'user', content: "What's the weather in Paris?" }]
});

// Agent might return tool calls in the message
const message = response.messages[0];
if (message.tool_calls) {
  for (const toolCall of message.tool_calls) {
    console.log(`Tool: ${toolCall.function.name}`);
    console.log(`Args: ${toolCall.function.arguments}`);
    
    // Execute the tool and send result back
    const toolResult = await executeToolCall(toolCall);
    
    messages.push({
      role: 'assistant',
      content: null,
      tool_calls: [{ id: toolCall.id, type: 'function', function: { name: toolCall.function.name, arguments: toolCall.function.arguments } }]
    });
    messages.push({
      role: 'tool',
      name: toolCall.function.name,
      tool_call_id: toolCall.id,
      content: toolResult
    });
    
    // Get final response
    const finalResponse = await client.agents.chat('assistant', { messages });
    console.log(finalResponse.messages[0].content);
  }
}

React Example

Basic chat component:
import { useState } from 'react';
import Reminix from '@reminix/sdk';

const client = new Reminix();

interface Message {
  role: 'user' | 'assistant';
  content: string;
}

function Chat() {
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);

  async function sendMessage() {
    if (!input.trim()) return;
    
    const userMessage: Message = { role: 'user', content: input };
    setMessages(prev => [...prev, userMessage]);
    setInput('');
    setLoading(true);
    
    try {
      const response = await client.agents.chat('chat-assistant', {
        messages: [...messages, userMessage]
      });
      
      // Add the first assistant message from the response
      const assistantMsg = response.messages[0];
      setMessages(prev => [...prev, { role: 'assistant', content: assistantMsg.content }]);
    } catch (error) {
      console.error('Chat error:', error);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div>
      {messages.map((msg, i) => (
        <div key={i} className={msg.role}>
          {msg.content}
        </div>
      ))}
      <input 
        value={input} 
        onChange={e => setInput(e.target.value)}
        onKeyDown={e => e.key === 'Enter' && sendMessage()}
      />
      <button onClick={sendMessage} disabled={loading}>
        Send
      </button>
    </div>
  );
}