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.basicquery,livecreateConsumerClient(),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/consumer1) 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