Skip to Content
SDK & ClientTypeScript SDKChat Quickstart (Docs-Only)

Chat Quickstart (Docs-Only)

This page mirrors the smaller examples/chat-with-ai flow using only documented @kalamdb/client and @kalamdb/consumer APIs:

  • createClient, Auth.basic
  • query, live
  • createConsumerClient(), runAgent()

This path is for local development without external auth setup.

Prerequisites

  • Node.js >= 18
  • running KalamDB server
  • a user that can run SQL and consume topic messages

Install:

npm i @kalamdb/client @kalamdb/consumer

1) Create a client

import { createClient, Auth } from '@kalamdb/client'; import { createConsumerClient, runAgent } from '@kalamdb/consumer'; const client = createClient({ url: 'http://localhost:8080', authProvider: async () => Auth.basic('admin', 'AdminPass123!'), }); const worker = createConsumerClient({ url: 'http://localhost:8080', authProvider: async () => Auth.basic('admin', 'AdminPass123!'), });

2) Apply chat schema + topic

await client.query('CREATE NAMESPACE IF NOT EXISTS chat_demo'); await client.query(` CREATE SHARED TABLE chat_demo.messages ( id BIGINT PRIMARY KEY DEFAULT SNOWFLAKE_ID(), room TEXT NOT NULL DEFAULT 'main', role TEXT NOT NULL, author TEXT NOT NULL, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW() ) `); await client.query('CREATE TOPIC chat_demo.ai_inbox'); await client.query(` ALTER TOPIC chat_demo.ai_inbox ADD SOURCE chat_demo.messages ON INSERT WITH (payload = 'full') `);

3) Start the worker with runAgent()

await runAgent<Record<string, unknown>>({ client: worker, name: 'chat-demo-agent', topic: 'chat_demo.ai_inbox', groupId: 'chat-demo-agent', onRow: async (ctx, row) => { if (String(row.role ?? '') !== 'user') { return; } const room = String(row.room ?? 'main'); const content = String(row.content ?? '').trim(); if (!content) { return; } const reply = `AI reply: KalamDB stored "${content}" and this worker wrote the response.`; await ctx.sql( 'INSERT INTO chat_demo.messages (room, role, author, content) VALUES ($1, $2, $3, $4)', [room, 'assistant', 'KalamDB Copilot', reply], ); }, });

4) Subscribe in the chat client

Use live() so the UI always receives the latest materialized row set.

const room = 'main'; const unsubscribe = await client.live( `SELECT * FROM chat_demo.messages WHERE room = '${room}'`, (rows) => { // This callback receives the current chat timeline after KalamDB has // already reconciled inserts and updates for you. renderRows(rows); }, { subscriptionOptions: { last_rows: 200 }, }, );

If you switch this table to WITH (TYPE = 'USER'), the same query text still works for every user and KalamDB will only return that authenticated user’s rows.

Insert a user message:

await client.query( 'INSERT INTO chat_demo.messages (room, role, author, content) VALUES ($1, $2, $3, $4)', [room, 'user', 'demo-user', 'hello'], );

5) Cleanup

await unsubscribe(); await client.disconnect();

Next

Last updated on