Cell - Ta Client
The client for ta serve: depends only on platform-native WebSocket, and works in browsers, Electron, mobile apps, and Node.js >= 22.4.
ts
import { SessionStore, TaConnection } from '@celljs/ta-client';
const connection = new TaConnection({ url, token }); // from ~/.ta/agent/serve.json
await connection.connect();
const { sessionId } = await connection.server.openSession({ cwd: '/repo' });
const store = new SessionStore(connection, sessionId);
store.subscribe(state => render(state)); // notified once per batch of events
await store.attach();
await store.prompt('Fix the failing tests');TaConnection: auto-reconnects after disconnect using exponential backoff.onReconnecting(delayMs, attempt)notifies you before each wait, andreconnect()skips the wait and retries immediately.connection.server(sessions),workspace,terminals,settings,packages,auth(login to model services, subscribe to events withonAuthEvent), andrelay(paired devices) are typed proxies for ta serve's services, all sharing one connection. ThecreateSocketoption lets you use a different transport, likeRelaySocketthrough Relay (@celljs/ta-relay). Calls during disconnection fail immediately (TaRemoteError,codeisCELL_TA_CONNECTION_LOST) without queuing; whether to retry is up to the caller (reuseclientMessageIdwhen retrying). Connections that drop re-establish themselves; operations from before the drop complete with the previous code if the server still has them.SessionStore: the client-side state for one session (messages, tool runs, pending dialogs, extension status bars). After reconnect, it resends missed events byseq. If it can't catch up (agap), it auto-syncs withgetMessages.- Client tools: the model can call tools run by the client (e.g., read clipboard, let the user pick something in the UI). Declare them when opening a session;
SessionStoreruns them and returns the results:
ts
const pickColor: ClientTool = {
definition: { name: 'pick_color', description: 'Ask the user to pick a color', parameters: { type: 'object', properties: {} } },
run: async () => await showColorPicker(), // text returned to model; errors mean tool failure
};
const { sessionId } = await connection.server.openSession({ cwd, clientTools: [pickColor.definition] });
const store = new SessionStore(connection, sessionId, { clientTools: [pickColor] });Call requests broadcast to all connected clients; the first result wins (same as dialogs). Each call runs once per client, and after disconnect, resends the already-calculated result instead of running again. If run is aborted or the session closes, the call ends as failed. The same client tools work in codemode scripts using tools.pick_color().
openSession'sappendSystemPromptappends a system prompt line to the session (like pi's--append-system-prompt), allowing clients to give the Agent a role.SessionReducer: a pure function(state, event) => state, never mutating old state, so UIs can compare by reference.