Cosmo Docs
API Reference

SSE Events

Server-Sent Events for streaming updates.

SSE (Server-Sent Events) are used for streaming AI responses and real-time updates from the server.

Chat Events

During a chat interaction, the system emits a stream of typed events.

Channel distinction: The server's POST /chat SSE stream emits ChatChunkDTO objects with types: text, tool_call, tool_result, error, done. The desktop app's IPC layer (chat:event) extends this with additional types (thinking, title-updated, tool_confirm) that are generated in the desktop main process — they are not part of the server SSE stream.

Server SSE Event Types (ChatChunkDTO)

TypeFieldsDescription
texttext: stringA chunk of streaming text from the LLM. Append to the current response.
tool_calltoolCall: { id, name, args, serverHandled? }The LLM invoked a tool.
tool_resulttoolResult: { callId, result }A tool call completed.
errorerror: stringFatal error — stream ends.
doneusage: { inputTokens, outputTokens }Stream complete.

Desktop IPC-only Event Types

These types exist only in the desktop chat:event IPC channel, not in the server SSE stream:

TypeFieldsDescription
thinkingProcessing heartbeat (desktop only).
title-updatedtitle: stringSession title generated (desktop only).
tool_confirmconfirmId, risk, explanationAwaiting user tool approval (desktop only).
contextUsage(on done event)Token usage appended by desktop to the done event.

Server SSE Event Shape

interface ChatChunkDTO {
  type: 'text' | 'tool_call' | 'tool_result' | 'error' | 'done'
  text?: string
  error?: string
  toolCall?: { id: string; name: string; args: Record<string, unknown>; serverHandled?: boolean }
  toolResult?: { callId: string; result: unknown }
  usage?: { inputTokens: number; outputTokens: number }
}

Typical Event Sequence

A simple text response:

thinking → text → text → text → done

A response that calls tools:

thinking → text → tool_call → tool_result → thinking → text → text → done

Multiple tool calls in one turn:

thinking → tool_call → tool_call → tool_result → tool_result → thinking → text → done

Rendering Guidance

When building a chat UI that consumes these events:

  1. On thinking — Show a subtle loading indicator (e.g., animated dots with "Thinking" label). Remove it when the next text or tool_call event arrives.
  2. On text — Append to the current text segment. If the previous segment was a thinking indicator, replace it with a text bubble.
  3. On tool_call — Show an activity badge with the tool name and a spinner. Display alongside text segments, not replacing them.
  4. On tool_result — Mark the corresponding tool call badge as complete (spinner to checkmark). Optionally show the result preview on expand.
  5. On done — Finalize: combine all text segments into the persisted message, clear streaming state. If contextUsage is present, update the context meter UI.
  6. On error — Save any partial text as a message, then display the error.

Context Usage

The done event may include a contextUsage field with the current context window consumption. Use this to display a context meter:

  • usedTokens — how many tokens the conversation is using
  • maxTokens — the model's context window limit (e.g., 200,000 for Claude models)
  • percentage — usage as a percentage

When percentage exceeds 80%, the engine may auto-compact older messages to free space. The next done event will reflect the reduced usage.

Server-Handled Tool Calls

Some tool calls are executed server-side by the AI provider (e.g., Anthropic's web search). These follow the same event flow as regular tool calls but with key differences:

  • The tool_call event has the same shape, but the engine does not execute the tool — the provider handles it
  • The tool_result event is emitted by the provider once the server-side execution completes
  • The engine's agentic loop does not re-run for server-handled calls — they resolve within a single provider turn

Web search event sequence:

thinking → tool_call (web_search) → tool_result (search complete) → text → text → done

From the UI's perspective, server-handled tools look identical to regular tools — you show a spinner, then a checkmark. The difference is only in the engine layer.

Tool Name Formatting

Tool names follow conventions that can be formatted for display:

  • cosmo_tasks_create — Cosmo built-in tool. Format as "Tasks: Create"
  • cosmo_artifacts_move — Format as "Artifacts: Move"
  • mcp__notion__search — MCP connector tool. Format as "Notion: Search"
  • web_search — Provider built-in tool. Format as "Web Search"