Cogitator
Channels

WebChat

Built-in WebSocket channel for custom web interfaces and CLI tools.

Setup

pnpm add ws

Usage

import { webchatChannel } from '@cogitator-ai/channels';

const webchat = webchatChannel({
  port: 3100,
  path: '/ws',
  auth: (token) => token === process.env.WEBCHAT_TOKEN,
});

Use with cogitator up

Add a webchat entry to cogitator.yml and set WEBCHAT_TOKEN in the .env next to it:

cogitator.yml
channels:
  webchat:
    port: 8080 # default
    path: /ws # default
.env
WEBCHAT_TOKEN=a-long-random-secret

Clients connect to ws://localhost:8080/ws?token=<WEBCHAT_TOKEN>. Without WEBCHAT_TOKEN the channel is not started (a warning is logged), because an open socket would give anyone the assistant's tools. WebChat has no ownerIds: every connection is a separate anonymous user. cogitator wizard --edit keeps the entry. See the config reference.

Configuration

interface WebChatConfig {
  port: number;
  path?: string; // default: '/ws'
  auth?: (token: string) => boolean;
  maxPayload?: number; // max incoming frame size in bytes, default 1 MiB
}

Connecting

WebSocket URL: ws://localhost:3100/ws?token=YOUR_SECRET

With wscat

npx wscat -c "ws://localhost:3100/ws?token=secret"
> {"text": "Hello!"}

From JavaScript

const ws = new WebSocket('ws://localhost:3100/ws?token=secret');
ws.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  if (msg.type === 'message') console.log('Bot:', msg.text);
  if (msg.type === 'edit') console.log('Bot (updated):', msg.text);
};
ws.onopen = () => ws.send(JSON.stringify({ text: 'Hi!' }));

Protocol

Client → Server

{ "text": "Hello!", "id": "optional-id" }

Server → Client

TypeFieldsDescription
connectedclientIdConnection established
messageid, text, replyTo?New message
editid, textUpdated message (streaming)
deleteidMessage removed (e.g. aborted stream)
typing—Agent is thinking
filefilename, mimeType, url?, data? (base64)File attachment
errormessageSent before closing an unauthorized socket (close code 1008)

Frames that are not JSON or have no non-empty text string are ignored.

Features

FeatureSupport
Streaming (edit)✅
Typing indicator✅
Token auth✅
File metadata✅
Message length limitNone
Multiple clients✅ (each gets own session)

Tips

  • Perfect for building custom chat UIs
  • Auth is optional but recommended for production
  • Each WebSocket connection is treated as a separate user: channelId and userId are the random clientId, so a reconnect starts a new thread
  • Incoming messages carry text only — attachments are not supported from the client
  • start() rejects if the port is already in use; stop() closes all client connections (code 1001)
  • Use with reverse proxy (nginx) for TLS in production

On this page