Agent doc: Chat JS SDK
Package
- Name:
@spectra-platform/chat-sdk - Public docs snapshot:
0.1.0on 2026-09-06; not a current registry version check. - Registry: GitHub Packages
- Role 70 verified registry/tarball
0.1.3has no leave or membership APIs. Local source0.2.0is unpublished.
Room leave contract
The new room leave feature is unpublished / undeployed. Follow the
room leave contract for release gates, self-only membership revocation,
repeat requests, timeout reconciliation, errors, retained versus accessible history, last-member behavior,
and the in-memory / independent multi-instance limitation. Existing-room DM resume and group reinvite
are unsupported. Never auto-rejoin through ensureDM/list/connect or substitute new-room creation for leave recovery.
Disconnect is transport cleanup, not membership revocation. Leaving Chat cannot revoke public Storage URLs,
already issued valid download URLs, delivered events, cached text, or downloaded files.
POST leave requires app-user-only chat.rooms.leave; GET membership requires chat.rooms.read.
No Secret Key grant is added. Never fall back to read-only token authorization for mutation.
SDK consumers do not configure scopes: the existing one-time 401/403 force-refresh asks Auth for a fresh service token.
Activation requires the new Auth and Chat servers plus published SDK 0.2.0; none is deployed/published in this change.
Chat leave does not terminate a Call session or its media connection.
Local PostgreSQL Contract
The new PG contract is local-only, unpublished and undeployed. Production migration is BLOCKED.
Final local P4 evidence: frozen Chat 8540121 + Auth 97e2419, packed Chat SDK bd9b877 (0.2.0)
and Auth SDK 94fb11d (0.1.10), 9 subtests + parent + guard2 = 12 pass, zero skip.
Actual Auth HTTP issuance/session refresh/PG introspection/RSA/JWKS and Chat HTTP/WS/PG are exercised.
Initial synthetic identity/session and old/read-only tokens use separate test-only control;
the packed Auth SDK sessionStore is seeded before real HTTP grant/refresh. Delivery is fake and external
fetch is blocked. Google/Apple/Keycloak login, SMTP/KMS, public-domain and device E2E remain unverified.
Actual API child PID replacement preserves history/read/first leftAt/dedup and invalidates old tickets.
SDK did not restart DB containers, run backups or switch rollback binaries. Do not merge earlier
fixture evidence or baseline P4 counts into this final run.
Follow the Chat SDK local PG contract; do not infer current public support.
Retry a send with the same room, sender, environment, clientMessageId and canonical payload.
Different payload for that key is 409 CHAT_MESSAGE_IDEMPOTENCY_CONFLICT.
The wire read endpoint accepts safe integers: zero or an existing positive committed message sequence,
never a future value. Invalid input is 400 CHAT_BAD_REQUEST; response/read event returns stored max(old,input).
SDK markRead still requires a positive integer and returns Promise<void>; inspect listRooms lastReadSequence.
DB failure is 503 CHAT_STORAGE_UNAVAILABLE; schema/ledger/ownership gate failure is
503 CHAT_STORAGE_NOT_READY, not a normal empty result, leave confirmation or memory fallback.
Environment comes only from verified Auth, not caller body/header or historical user-ID inference.
Auth enables one environment per project/service. Separate Test/Live projects and same-project service
environment drift rejection/restoration were tested, not simultaneous Test/Live enablement for one project.
Chat DB tenant/environment isolation is distinct from that Auth policy.
Event envelope sequence remains hub-local, not durable replay. Local synthetic PG restore and local actual
Auth P4 do not prove external provider login or production data preservation.
Chat 8540121 bounds Auth introspection headers and body to five seconds and preserves
503 CHAT_AUTH_UNAVAILABLE, without automatic server retry. SDK deadlines are separate.
Observed PostgreSQL 53100 or uncertain ROLLBACK latches authority/readiness fail closed;
capacity recovery alone does not resume that process. The server owner resolves the cause and explicitly
restarts the API before same-key/payload reconciliation. A confirmed rollback after timeout/deadlock can
permit a later readiness 200; that does not acknowledge the failed write.
Actual disk-full coverage is a tmpfs scratch/test-trigger 53100 propagated into a Chat transaction,
not whole PGDATA/WAL/host exhaustion. Separate server tests switched durable binaries
192f583 → 8540121 → 192f583 → 8540121 while preserving latest writes/read/first leftAt/dedup.
This is not container image rollback, SDK-owned DB manipulation, or production migration evidence.
Compatibility does not authorize returning to baseline during the Auth/capacity faults fixed by candidate.
A separate committed-script run verified outbox immutable event fields, message/member references,
zero duplicate recipient/destination rows and uninjected Delivery pending. Mutable retry/lease state,
real delivery and exactly-once are not guaranteed by that oracle.
Purpose
Chat JS SDK consumes Chat Platform room, message, typing/read, and WebSocket contracts through app-user authorization.
API tree
Chat JS SDK
├─ setup
│ ├─ new SpectraChatClient(config)
│ ├─ createSpectraChatClient(config)
│ └─ on(event, handler)
├─ rooms
│ ├─ listRooms(options?)
│ ├─ createDirectRoom({ userId })
│ ├─ createGroupRoom({ title?, userIds })
│ ├─ leaveRoom(roomId, options?) # 0.2.0 unpublished
│ └─ getRoomMembership(roomId, options?) # 0.2.0 unpublished
├─ messages
│ ├─ listMessages(roomId, options?)
│ ├─ sendMessage(roomId, options)
│ └─ markRead(roomId, { lastReadSequence })
└─ realtime
├─ connect(roomId)
├─ setTyping(roomId, isTyping)
└─ disconnect()
Public setup inputs
projectIdauth, usually an Auth SDK instance- optional HTTP/WebSocket
baseUrl - optional
webSocketfactory - optional
reconnectDelayMs
Required auth object and token boundary
- Pass the Auth JS SDK object as
auth. - Chat SDK obtains Chat-scoped authorization through
auth.getAccessToken({ service: "chat" })or an equivalent Auth SDK boundary. - Chat payloads may include Storage object references for attachments.
- Chat payloads must not include binary file bytes, raw Secret Keys, provider secrets, or long-lived app-user tokens. Websocket ticket expiry is separate from Project Secret Key handling.
Agent integration order
1. Verify Auth SDK login/session/token first.
2. For Chat SDK QA, use chat-sdk-js/examples/web; do not move Chat SDK E2E into Console.
3. Register the demo/app callback URL as an App/Web Callback in Spectra Console, for example http://127.0.0.1:5176/auth/callback.
4. Create SpectraChatClient with projectId and auth.
5. Register event handlers with on(event, handler) before connecting realtime when the UI needs live updates.
6. Implement createDirectRoom() and createGroupRoom().
7. Implement listRooms() and listMessages().
8. Implement sendMessage() with text and Storage object reference attachments.
9. Implement markRead() and setTyping().
10. Implement connect(roomId)/disconnect() and observe reconnect behavior separately from HTTP API calls.
Public operations
listRooms({ limit? }): list current user's rooms.createDirectRoom({ userId }): create a new 1:1 room, not get/resume the previous room.createGroupRoom({ title?, userIds }): create a group room.leaveRoom(roomId, { timeoutMs?, signal? }): self-leave; resolves only with a validatedleftresult. Repeated leave preserves the originalleftAt.getRoomMembership(roomId, { timeoutMs?, signal? }): query self membership, including after leaving. Only explicitleftconfirms completion; 404 is not confirmation.listMessages(roomId, { beforeSequence?, limit? }): list room messages.sendMessage(roomId, { text?, attachments?, clientMessageId?, replyToMessageId?, mentionedUserIds? }): send text or Storage object references.markRead(roomId, { lastReadSequence }): update read cursor.setTyping(roomId, isTyping): send typing event over socket.connect(roomId): connect realtime channel and auto-reconnect on unexpected close.disconnect(): close socket and stop reconnect.on(event, handler): subscribe tomessage,typing,read,connected,disconnected,error.on("membership", handler): source0.2.0self-only leave control event withroomId,appUserId,status: "left",leftAt,occurredAt. Duplicate events are possible. Preserve other-room connections; use GET after missed events. Do not promise offline replay or independent multi-instance propagation.
Consumer example
import { SpectraChatClient } from "@spectra-platform/chat-sdk";
const chat = new SpectraChatClient({
projectId,
auth,
});
const room = await chat.createDirectRoom({ userId });
await chat.sendMessage(room.id, { text: "hello" });
chat.on("message", (event) => console.log(event.message.text));
await chat.connect(room.id);
Current caveats
- Role 80 verified the current deployment runs a single non-durable Map-backed process, without DB/data mounts, on image
578647a. It does not support leave/membership. Do not redeploy/recreate it without an agreed data-preservation plan: existing rooms/messages/memberships would be lost. Persistence is a separate decision, not part of this unpublished change. - Membership calls default to a 10,000ms deadline including token acquisition and response parsing.
REQUEST_TIMEOUT/REQUEST_ABORTEDdo not roll back server changes; keep the result uncertain until confirmed.REQUEST_TIMEOUT_INVALIDis a local options error. Preservecode,status,requestId, andretryablewhen present. activefrom a reconciliation GET can precede a delayed POST. Do not auto-reconnect, auto-create a room, or auto-rejoin based on it. A repeated leave remains safe for the same authenticated former member, even for an empty room.- Room-scoped WebSocket errors identify the target using envelope
room_id. A delayed error for room A must not close room B. A legacy error withoutroom_idmust not infer the current room for cleanup;CHAT_NOT_FOUNDalone is not leave confirmation. - Chat server implementation and service E2E must be checked separately from SDK package publication.
- Browser demo build exists at
chat-sdk-js/examples/web, but public Auth/Chat multi-browser E2E still needs live verification. - Attachments should use Storage object references, not binary payloads inside Chat.
Unsupported or separate gates
- Media calls are Call SDK/Call Platform scope, not Chat JS SDK.
- Push delivery for offline message notifications is Delivery Platform scope.
- Live WebSocket service E2E must be verified separately from package API existence.
Escalate to Platform CS when
- The SDK requires a raw Chat service secret instead of the injected Auth object.
- Room/message methods differ from the public API tree in this document.
- WebSocket ticket or reconnect behavior is undocumented or forces internal API calls.
- Storage attachment references are rejected even though the object reference follows Storage SDK output.
- A consuming app tries to use Console E2E callbacks instead of its own App/Web Callback URL.