githubEdit

Quick Start: Chat Table

1

Introduction

This guide will help you quickly get started with JamAI Base chat tables using the TypeScript SDK. You'll learn how to create a simple chat application similar to the example provided.

2

Prerequisites

  • Node.js 16.x or higher

  • JamAI Base account

  • Personal Access Token (PAT)

  • Project ID

3

Installation

npm install jamaibase
4

Basic Setup

Get your Personal Access Token (PAT) here:

Get your Project ID here:

import JamAI from "jamaibase";

// Initialize JamAI client
const jamai = new JamAI({
  projectId: "your_project_id", // Replace with your project ID
  token: "your_pat_token", // Replace with your PAT
});
5

Creating a Chat Agent (UI First)

Go to JamAI Base web interface chat table tab

Navigate to "Agents" section, click + to create new agent.

Name the new agent "example_agent" and select LLM model.

You can further configure your agent in UI but it will not be covered in this tutorial.

Example of some configuration you can do:

  • Set system prompt

  • Set multiple parallel agents

  • Configure RAG settings

  • Set up knowledge base

6

Creating Chat Sessions

Each chat session is created by duplicating your base agent table. Here's how to do it:

async function createNewChat(): Promise<string | null> {
  const timestamp = Date.now();
  const newTableId = `Chat_${timestamp}`;

  try {
    await jamai.table.duplicateTable({
      table_type: "chat",
      table_id_src: "example_agent", // Your base agent ID
      table_id_dst: newTableId,
      include_data: true,
      create_as_child: true,
    });
    return newTableId;
  } catch (error) {
    console.error(`Error creating new chat: ${error}`);
    return null;
  }
}
7

Basic Chat Interaction

// Send a message and get response
async function chatInteraction(
  tableId: string,
  userMessage: string
): Promise<string> {
  const response = await jamai.table.addRowStream({
    table_type: "chat",
    table_id: tableId,
    data: [{ User: userMessage }],
  });

  // For streaming response
  let fullResponse = "";

  for await (const value of response) {
    if (
      value.object === "gen_table.completion.chunk" &&
      value.choices?.[0]?.message?.content
    ) {
      fullResponse += value.choices[0].message.content;
      console.log(value.choices[0].message.content);
    }
  }

  return fullResponse;
}

// For non-streaming response
async function chatInteractionNonStream(tableId: string, userMessage: string) {
  const response = await jamai.table.addRow({
    table_type: "chat",
    table_id: tableId,
    data: [{ User: userMessage }],
    concurrent: false,
  });

  return response.rows[0]?.columns["AI"]?.choices[0]?.message?.content;
}
8

Simple Implementation Example

async function main() {
  // Create a new chat session
  const chatId = await createNewChat();

  if (chatId) {
    // Send a message
    const response = await chatInteraction(chatId, "Hello, how are you?");
    console.log("\nAI:", response);
  }
}

main().catch(console.error);
9

Key Features

  • Streaming Responses: Use addRowStream() for real-time responses

  • Session Management: Each chat creates a new table instance

  • Inheritance: New chats inherit settings from the base agent

  • History Preservation: Chat history is maintained in the table

10

Best Practices

  • Create a new chat session for each conversation

  • Handle exceptions during table creation

  • Store chat IDs for session management

  • Clean up unused chat tables periodically

11

Complete Runnable Example with CLI

Here's a complete, standalone example that you can copy, paste, and run in the terminal:

import JamAI from "jamaibase";
import * as readline from "readline";
import * as dotenv from "dotenv";

// Load environment variables (optional)
dotenv.config();

// Constants
const PROJECT_ID = process.env.JAMAI_PROJECT_ID || "your_project_id";
const PAT = process.env.JAMAI_API_KEY || "your_pat_token";
const AGENT_ID = "example_agent"; // Replace with your agent ID
const OPENER = "Hello! How can I help you today?";

// Initialize JamAI
const jamai = new JamAI({
  projectId: PROJECT_ID,
  token: PAT,
});

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

class ChatSession {
  private tableId: string | null = null;
  private messages: Message[] = [];
  private rl: readline.Interface;

  constructor() {
    this.rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
    });
  }

  async initialize(): Promise<boolean> {
    this.tableId = await this.createNewChat();
    if (this.tableId) {
      this.messages.push({ role: "assistant", content: OPENER });
      console.log(`\nAssistant: ${OPENER}\n`);
      return true;
    }
    return false;
  }

  async createNewChat(): Promise<string | null> {
    const timestamp = Date.now();
    const newTableId = `Chat_${timestamp}`;

    try {
      await jamai.table.duplicateTable({
        table_type: "chat",
        table_id_src: AGENT_ID,
        table_id_dst: newTableId,
        include_data: true,
        create_as_child: true,
      });
      console.log(`Created new chat session: ${newTableId}`);
      return newTableId;
    } catch (error) {
      console.error(`Error creating new chat: ${error}`);
      return null;
    }
  }

  async sendMessage(userMessage: string): Promise<void> {
    if (!this.tableId) {
      console.error("No active chat session");
      return;
    }

    // Add user message
    this.messages.push({ role: "user", content: userMessage });

    // Get AI response with streaming
    console.log("\nAssistant: ");

    const response = await jamai.table.addRowStream({
      table_type: "chat",
      table_id: this.tableId,
      data: [{ User: userMessage }],
    });

    let fullResponse = "";

    for await (const value of response) {
      if (
        value.object === "gen_table.completion.chunk" &&
        value.choices?.[0]?.message?.content
      ) {
        const content = value.choices[0].message.content;
        fullResponse += content;
        console.log(content);
      }
    }

    console.log("\n");
    this.messages.push({ role: "assistant", content: fullResponse });
  }

  async startChat(): Promise<void> {
    console.log(
      "\nChat started! Type 'exit' to quit, 'new' to start a new chat.\n"
    );

    const askQuestion = () => {
      this.rl.question("You: ", async (input) => {
        const userInput = input.trim();

        if (userInput.toLowerCase() === "exit") {
          console.log("Goodbye!");
          this.rl.close();
          process.exit(0);
        } else if (userInput.toLowerCase() === "new") {
          const success = await this.initialize();
          if (success) {
            askQuestion();
          } else {
            console.log("Failed to create new chat. Exiting...");
            this.rl.close();
            process.exit(1);
          }
        } else if (userInput) {
          await this.sendMessage(userInput);
          askQuestion();
        } else {
          askQuestion();
        }
      });
    };

    askQuestion();
  }
}

async function main() {
  console.log("=== JamAI Base Chat Demo ===\n");

  const chat = new ChatSession();
  const initialized = await chat.initialize();

  if (initialized) {
    await chat.startChat();
  } else {
    console.error("Failed to initialize chat session");
    process.exit(1);
  }
}

main().catch(console.error);

How to Run:

  1. Save the code in a file (e.g., chat_demo.ts)

  2. Create a .env file:

    JAMAI_PROJECT_ID=your_project_id
    JAMAI_API_KEY=your_pat_token
  3. Install required packages:

    npm install jamaibase dotenv
    npm install --save-dev @types/node typescript ts-node
  4. Replace the following values in the code:

    • AGENT_ID with your agent ID created in the UI (or use environment variable)

  5. Run the application:

    ts-node chat_demo.ts

Or compile and run:

tsc chat_demo.ts
node chat_demo.js

Using the Chat Demo:

  • Type your message and press Enter to chat

  • Type new to start a new chat session

  • Type exit to quit the application

12

Web-Based Chat Example (Express + HTML)

Server (TypeScript):

import JamAI from "jamaibase";
import express from "express";
import * as dotenv from "dotenv";

dotenv.config();

const app = express();
const PORT = 3000;

const PROJECT_ID = process.env.JAMAI_PROJECT_ID || "your_project_id";
const PAT = process.env.JAMAI_API_KEY || "your_pat_token";
const AGENT_ID = "example_agent";

const jamai = new JamAI({
  projectId: PROJECT_ID,
  token: PAT,
});

app.use(express.json());
app.use(express.static("public"));

// Create new chat session
app.post("/api/chat/new", async (req, res) => {
  try {
    const timestamp = Date.now();
    const newTableId = `Chat_${timestamp}`;

    await jamai.table.duplicateTable({
      table_type: "chat",
      table_id_src: AGENT_ID,
      table_id_dst: newTableId,
      include_data: true,
      create_as_child: true,
    });

    res.json({ chatId: newTableId });
  } catch (error) {
    res.status(500).json({ error: String(error) });
  }
});

// Send message
app.post("/api/chat/message", async (req, res) => {
  try {
    const { chatId, message } = req.body;

    const response = await jamai.table.addRow({
      table_type: "chat",
      table_id: chatId,
      data: [{ User: message }],
      concurrent: false,
    });

    const aiResponse =
      response.rows[0]?.columns["AI"]?.choices[0]?.message?.content;
    res.json({ response: aiResponse });
  } catch (error) {
    res.status(500).json({ error: String(error) });
  }
});

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

Save the following HTML in public/index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>JamAI Chat Demo</title>
    <style>
      body {
        font-family: Arial, sans-serif;
        max-width: 800px;
        margin: 50px auto;
      }
      #chat {
        border: 1px solid #ccc;
        height: 400px;
        overflow-y: scroll;
        padding: 10px;
        margin-bottom: 10px;
      }
      .message {
        margin: 10px 0;
        padding: 10px;
        border-radius: 5px;
      }
      .user {
        background: #e3f2fd;
        text-align: right;
      }
      .assistant {
        background: #f5f5f5;
      }
      #input {
        width: 80%;
        padding: 10px;
      }
      button {
        padding: 10px 20px;
      }
    </style>
  </head>
  <body>
    <h1>JamAI Chat Demo</h1>
    <div id="chat"></div>
    <input type="text" id="input" placeholder="Type your message..." />
    <button onclick="sendMessage()">Send</button>
    <button onclick="newChat()">New Chat</button>

    <script>
      let chatId = null;

      async function newChat() {
        const response = await fetch("/api/chat/new", { method: "POST" });
        const data = await response.json();
        chatId = data.chatId;
        document.getElementById("chat").innerHTML = "";
        addMessage("assistant", "Hello! How can I help you today?");
      }

      async function sendMessage() {
        const input = document.getElementById("input");
        const message = input.value.trim();
        if (!message || !chatId) return;

        addMessage("user", message);
        input.value = "";

        const response = await fetch("/api/chat/message", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ chatId, message }),
        });

        const data = await response.json();
        addMessage("assistant", data.response);
      }

      function addMessage(role, content) {
        const chat = document.getElementById("chat");
        const div = document.createElement("div");
        div.className = `message ${role}`;
        div.textContent = content;
        chat.appendChild(div);
        chat.scrollTop = chat.scrollHeight;
      }

      // Initialize with new chat
      newChat();
    </script>
  </body>
</html>

Run the server:

npm install express dotenv
ts-node server.ts

Then open http://localhost:3000 in your browser.

13

Summary

This example provides:

  • A simple chat interface (CLI and Web-based)

  • Streaming and non-streaming responses

  • New chat session creation

  • Basic error handling

Note: Make sure you have created your agent in the JamAI Base UI before running this code, as it relies on duplicating an existing agent table.

This example serves as a great starting point for building more complex chat applications with JamAI Base using TypeScript/JavaScript.

Last updated

Was this helpful?