← All @molecule/* packages · App templates
@molecule/app-ai-copilotCore interface · ai-copilot · App (browser) · v1.0.1 · Apache-2.0
Inline AI suggestion (copilot) core interface — editor-style completions streamed from your backend for a prefix/suffix cursor context, with accept/reject/abort.
npm install @molecule/app-ai-copilot@molecule/app-ai-copilot is the ai-copilot core interface on the app (browser) side: the API your app calls, with no vendor inside.
Choose the implementation by bonding one of its 1 provider: @molecule/app-ai-copilot-default.
import { requireProvider, setProvider } from '@molecule/app-ai-copilot'
import { createProvider } from '@molecule/app-ai-copilot-default'
setProvider(createProvider()) // at startup
const copilot = requireProvider()
copilot.abort() // cancel any stale request before asking again
await copilot.getSuggestions(
{ prefix: textBeforeCursor, suffix: textAfterCursor, language: 'typescript' },
{ endpoint: '/api/copilot' },
(event) => {
if (event.type === 'suggestion') showGhostText(event.suggestion.text)
},
)Providers (1): @molecule/app-ai-copilot-default
Works with: @molecule/app-bond
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.tsJSDoc, not this file.
Inline AI suggestion (copilot) core interface for molecule.dev.
Defines the AICopilotProvider contract for editor-style inline completions:
getSuggestions(context, config, onEvent) streams suggestions for a
prefix/suffix cursor context; acceptSuggestion / rejectSuggestion report
the user's choice back to your API; abort() cancels the in-flight request.
HEADLESS: your editor integration renders and inserts the suggestion text.
import { requireProvider, setProvider } from '@molecule/app-ai-copilot'
import { createProvider } from '@molecule/app-ai-copilot-default'
setProvider(createProvider()) // at startup
const copilot = requireProvider()
copilot.abort() // cancel any stale request before asking again
await copilot.getSuggestions(
{ prefix: textBeforeCursor, suffix: textAfterCursor, language: 'typescript' },
{ endpoint: '/api/copilot' },
(event) => {
if (event.type === 'suggestion') showGhostText(event.suggestion.text)
},
)
core
npm install @molecule/app-ai-copilot @molecule/app-bond
AICopilotConfigConfiguration passed to copilot provider methods.
interface AICopilotConfig {
/** Backend endpoint URL for suggestion requests. */
endpoint: string
/** Maximum number of suggestions to return per request. */
maxSuggestions?: number
/** AI model identifier to use for generation. */
model?: string
/** Project identifier for scoped context. */
projectId?: string
}
AICopilotProviderProvider interface for inline AI suggestions.
Bond packages implement this interface to supply completions from different backends (HTTP, WebSocket, local model, etc.).
interface AICopilotProvider {
/** Provider name identifier. */
readonly name: string
/**
* Requests inline suggestions for the given editor context.
* Results are delivered via the `onEvent` callback as they arrive.
*
* @param context - Current editor state (prefix, suffix, language, etc.).
* @param config - Endpoint, model, and other request-level configuration.
* @param onEvent - Callback invoked for each suggestion or terminal event.
* @returns Resolves when the suggestion stream completes.
*/
getSuggestions(
context: CopilotContext,
config: AICopilotConfig,
onEvent: CopilotEventHandler,
): Promise<void>
/**
* Notifies the backend that a suggestion was accepted by the user.
* Used for analytics and model improvement.
*
* @param suggestion - The accepted suggestion.
* @param config - Request-level configuration.
*/
acceptSuggestion(suggestion: CopilotSuggestion, config: AICopilotConfig): Promise<void>
/**
* Notifies the backend that a suggestion was dismissed by the user.
*
* @param suggestion - The rejected suggestion.
* @param config - Request-level configuration.
*/
rejectSuggestion(suggestion: CopilotSuggestion, config: AICopilotConfig): Promise<void>
/**
* Cancels any in-flight suggestion request.
*/
abort(): void
}
CopilotContextContext sent to the copilot provider to generate suggestions. Mirrors the information available in a typical code editor.
interface CopilotContext {
/** Document content before the cursor position. */
prefix: string
/** Document content after the cursor position. */
suffix: string
/** Language identifier (e.g., "typescript", "python"). */
language?: string
/** File path or name for additional context. */
filePath?: string
/** Cursor line (0-based). */
cursorLine?: number
/** Cursor column (0-based). */
cursorColumn?: number
}
CopilotRangeA range within a document, using 0-based line and column numbers.
interface CopilotRange {
/** Start line (0-based). */
startLine: number
/** Start column (0-based). */
startColumn: number
/** End line (0-based). */
endLine: number
/** End column (0-based). */
endColumn: number
}
CopilotSuggestionA single inline suggestion returned by the copilot provider.
interface CopilotSuggestion {
/** Unique identifier for this suggestion. */
id: string
/** The suggested text to insert or replace. */
text: string
/** Document range to replace. When omitted, text is inserted at the cursor. */
range?: CopilotRange
/** Short display label (e.g., for a suggestion list UI). */
label?: string
/** Arbitrary provider-specific metadata. */
metadata?: Record<string, unknown>
}
CopilotEventDiscriminated union of events emitted during suggestion generation.
type CopilotEvent =
| { type: 'suggestion'; suggestion: CopilotSuggestion }
| { type: 'suggestions'; suggestions: CopilotSuggestion[] }
| { type: 'done' }
| { type: 'error'; message: string }
CopilotEventHandlerCallback for receiving copilot events during streaming.
type CopilotEventHandler = (event: CopilotEvent) => void
getProvider()Returns the current copilot provider, or null if none is registered.
function getProvider(): AICopilotProvider | null
Returns: The registered provider or null.
hasProvider()Checks whether a copilot provider has been registered.
function hasProvider(): boolean
Returns: true if a provider is available.
requireProvider()Returns the current copilot provider or throws if none is registered.
function requireProvider(): AICopilotProvider
Returns: The registered provider.
setProvider(provider)Registers the active copilot provider.
function setProvider(provider: AICopilotProvider): void
provider — The provider instance to register.| Provider | Package |
|---|---|
| Ai Copilot | @molecule/app-ai-copilot-default |
Peer dependencies:
@molecule/app-bond ^1.0.1@molecule/app-bond
Wire it with THIS package's setProvider() or bond('ai-copilot', …).
setProvider() delegates into the shared @molecule/app-bond registry, so
both write the same slot; requireProvider() throws until one has run.
Suggestions come from YOUR backend (config.endpoint), which calls the
AI provider server-side (see @molecule/api-ai) — no vendor key in the
browser.
Debounce keystrokes and abort() before every new request. An
un-aborted stale request races the fresh one and inserts outdated text at
the wrong cursor position.
Suggested text is MODEL OUTPUT — insert it as plain text; never execute or eval it, and validate anything it triggers server-side.
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:
getSuggestions(context, config, onEvent)
and the returned CopilotSuggestion.text renders as ghost/inline text
anchored to the suggestion's range (CopilotRange) — or the caret when
range is omitted — never at a stale or wrong offset.suggestion.text
at that range/caret and nothing stale, and fires
acceptSuggestion(suggestion, config); the buffer holds only the accepted
text with no leftover ghost preview.abort() so the in-flight request is cancelled before the next
getSuggestions — a late-arriving stale suggestion never lands at the
moved cursor, and rejectSuggestion(suggestion, config) reports the miss.CopilotContext (prefix/suffix/language around the cursor), so
editing the surrounding code visibly changes what gets proposed.onEvent { type: 'error' }) fails quietly — no
ghost text, no thrown exception in the editor, the buffer is untouched, and
the user can keep typing.CopilotRange (it never overwrites unrelated lines), and suggestion.text
is treated as plain model output — inserted as text, never eval'd or run as
trusted code by the copilot itself.