← All @molecule/* packages · App templates

@molecule/app-ai-assistant-default

Provider bond · ai-assistant · App (browser) · v1.0.1 · Apache-2.0

Default HTTP/SSE AI assistant panel provider

npm install @molecule/app-ai-assistant-default

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

How it works

@molecule/app-ai-assistant-default is a provider bond on the app (browser) side: it implements the ai-assistant core interface (@molecule/app-ai-assistant) 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.

import { setProvider } from '@molecule/app-ai-assistant'
import { provider } from '@molecule/app-ai-assistant-default'

setProvider(provider) // at startup; same-origin base URL

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.

Default AI assistant provider for molecule.dev.

Uses HTTP/SSE to stream assistant replies from YOUR backend, with built-in panel state management and context awareness.

Quick Start

import { setProvider } from '@molecule/app-ai-assistant'
import { provider } from '@molecule/app-ai-assistant-default'

setProvider(provider) // at startup; same-origin base URL

Type

provider

Installation

npm install @molecule/app-ai-assistant-default @molecule/app-ai-assistant

API

Interfaces

DefaultAssistantConfig

Configuration specific to the default HTTP/SSE assistant provider.

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

Classes

DefaultAssistantProvider

Default AI assistant provider using HTTP/SSE for streaming.

Manages an internal panel state store with subscriber notifications, streams assistant responses via SSE, and supports context-enriched messaging.

Functions

createProvider(config)

Create a new default assistant provider instance.

function createProvider(config?: DefaultAssistantConfig): DefaultAssistantProvider
  • config — Optional provider-specific configuration

Returns: A new DefaultAssistantProvider instance

Constants

provider

Pre-instantiated provider singleton.

const provider: DefaultAssistantProvider

Core Interface

Implements @molecule/app-ai-assistant interface.

Bond Wiring

Setup function to register this provider with the core interface:

import { setProvider } from '@molecule/app-ai-assistant'
import { provider } from '@molecule/app-ai-assistant-default'

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

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-ai-assistant ^1.0.1

Runtime Dependencies

  • @molecule/app-ai-assistant

HEADLESS — manages panel state + streaming only; your app renders the panel from getState() / subscribe(). Talks to YOUR backend at config.endpoint (relative path on baseUrl, default same-origin) — it holds no AI key. Your API must implement, on that one endpoint:

  • POST { message, systemContext?, context? } → an SSE stream of data: <AssistantStreamEvent JSON> lines (text / thinking / suggestion / done / error),
  • GET → { messages: [...] } (loadHistory; fails open to [] on any error), and DELETE → clear history (best-effort; local state clears even if it fails). The bare provider export is createProvider() with no options — to set baseUrl/headers, wire setProvider(createProvider({ ... })) instead. sendMessage aborts any previous in-flight stream automatically.

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:

  • Opening the panel (open/togglegetState().isOpen is true) and sending a message through sendMessage renders the user turn immediately, then the assistant reply below it — both present in getState().messages.
  • The reply STREAMS: text events append the assistant message progressively (token by token) while its isStreaming stays true, and isStreaming clears when the done event lands — not one atomic blob at the end.
  • A stop/cancel control mid-stream calls abort() and actually halts the reply: the message stops growing and is marked aborted, not left spinning.
  • A thinking/loading indicator driven by getState().isLoading shows while a response is in flight and clears once it settles — on done AND on abort.
  • A provider failure surfaces getState().error (from the error stream event) as a visible message in the panel — never a blank or perpetually spinning panel.
  • Suggestions from getState().suggestions render as chips, and clicking one sends THAT chip's own action string — the suggestion's wired message, not a generic prompt.
  • Context set via setContext (the selected code / current page) is actually attached to the request so the answer is context-aware; clearContext drops it, and one user's context never bleeds into another user's session.
  • Conversation history persists across turns and reloads — loadHistory rehydrates getState().messages and clearHistory empties the panel — and model output renders through the app's sanitizing markdown renderer, never as raw or executable HTML.