← All @molecule/* packages · App templates

@molecule/app-ai-chat-http

Provider bond · ai-chat · App (browser) · v1.1.0 · Apache-2.0

HTTP/SSE AI chat provider implementation

npm install @molecule/app-ai-chat-http

npm · Source on GitHub · Implements @molecule/app-ai-chat

How it works

@molecule/app-ai-chat-http is a provider bond on the app (browser) side: it implements the ai-chat core interface (@molecule/app-ai-chat) with a concrete vendor or library behind it.

Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.

Works with: @molecule/app-i18n

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

HTTP/SSE AI chat provider for molecule.dev.

Type

provider

Installation

npm install @molecule/app-ai-chat-http @molecule/app-ai-chat @molecule/app-i18n

API

Interfaces

HttpChatConfig

Configuration for http chat.

interface HttpChatConfig {
  /** Base URL for API requests. Defaults to '' (same origin). */
  baseUrl?: string
  /** Custom headers to include in requests. */
  headers?: Record<string, string>
}

Classes

HttpChatProvider

HTTP/SSE-based implementation of ChatProvider. Sends messages via POST to a backend endpoint and reads SSE (Server-Sent Events) streams for real-time AI responses.

Functions

createProvider(config)

Creates an HttpChatProvider instance with optional base URL and custom headers.

function createProvider(config?: HttpChatConfig): HttpChatProvider
  • config — HTTP-specific chat configuration (base URL, headers).

Returns: An HttpChatProvider that communicates with the backend via HTTP/SSE.

Constants

provider

Pre-instantiated provider singleton.

const provider: HttpChatProvider

Core Interface

Implements @molecule/app-ai-chat interface.

Bond Wiring

Setup function to register this provider with the core interface:

import { setProvider } from '@molecule/app-ai-chat'
import { provider } from '@molecule/app-ai-chat-http'

export function setupAiChatHttp(): void {
  setProvider(provider)
}

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-ai-chat ^1.0.1
  • @molecule/app-i18n ^1.0.1

Runtime Dependencies

  • @molecule/app-ai-chat
  • @molecule/app-i18n

POSTs each message to YOUR backend chat endpoint (config.endpoint, a RELATIVE path like /api/ai/chat on the app's baseUrl) and reads the reply as an SSE stream — it does NOT talk to an AI provider directly and holds NO AI key. Point endpoint at your own API, where the provider key + @molecule/api-ai live; auth rides the session via the HTTP client (cookie/bearer), so never attach a provider key or an absolute AI-provider URL here. See @molecule/app-ai-chat for the safe-render rules.

Server contract (all on the ONE config.endpoint route): POST { message, model?, attachments?, resume?, suppressUserMessage?, automatic?, userInitiated? } → SSE data: <ChatStreamEvent JSON> lines; GET → { messages, streaming? } plus any app-specific top-level fields (this bond only reads messages + streaming; every other field rides through in provider.lastMeta — e.g. an app that persists an agent mode reads it back as provider.lastMeta?.mode); DELETE → clear history. Two conventions beyond that route: a POST answered 409 means "conversation locked, still streaming" — this bond retries automatically (up to 10 tries, 500 ms doubling backoff) so return 409 rather than erroring; and Stop/unload aborts POST to <endpoint>-abort (suffix on the pathname, query kept) with { conversationId?, userInitiated? } via sendBeacon. abortOnServer(), isServerStreaming, and lastMeta are extensions on HttpChatProvider beyond the core ChatProvider type. loadHistory() returns [] on HTTP errors but REJECTS on network failure; wrap it.

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:

  • Sending a message renders it in the thread and a streamed assistant reply appears incrementally (visible tokens while generating — not a frozen UI that dumps one blob).
  • The reply flows through the app's OWN backend: the browser's network log shows no direct calls to an AI provider and no provider key anywhere client-side.
  • Model output renders as sanitized markdown — a reply containing HTML or <script> displays as text and never executes.
  • If the app claims conversation persistence, reloading restores the thread history.
  • A backend failure (endpoint down, missing API key) surfaces a readable, actionable error — not an infinite spinner.
  • Sending again while a reply streams is handled sanely (queued, blocked, or parallel — never corrupted/interleaved text).