Messages and segments — core API
Generated reference for @aparte/core. A message and the segments it is made of, the parser that builds them from a stream, the renderers that draw them, and the errors.
On this page
- Overview
- Classes
- Functions
-
Interfaces
- AparteThinkingDelimiterPair
- AparteStreamParserOptions
- AparteParserState
- AparteParserResult
- AparteTextPart
- AparteImagePart
- AparteChatMessage
- AparteChatRequest
- AparteRequestMeta
- AparteUsage
- AparteStreamEventMap
- AparteSendEventDetail
- AparteSiblingInfo
- AparteChatImperativeApi
- AparteUiHandle
- AparteAIModel
- ModelLoadProgress
- AparteAIProviderMetadata
- AparteAIProviderConfigField
- AparteAIProviderConfigSchema
- AparteModelConfig
- AparteAttachment
- AparteMessageBranch
- AparteBubbleActionsConfig
- AparteHostHandlersConfig
- AparteMessage
- AparteViewportConfig
- AparteInputConfig
- AparteContentParser
- AparteSegmentBase
- AparteSegmentTiming
- AparteTextSegment
- AparteThinkingSegment
- AparteCodeSegment
- AparteErrorSegment
- AparteToolCallSegment
- AparteCustomSegment
- AparteSegmentRenderer
- AparteSegmentUpdateEventDetail
- AparteStreamBlockMatch
- AparteStreamBlock
- AparteTool
- AparteToolCall
- AparteApprovalRuling
- AparteToolResult
- AparteToolContext
- AparteToolRenderer
-
Type Aliases
- AparteContentPart
- AparteStreamEvent
- AparteChatResponse
- AparteAttrValue
- AparteTemplateAttrs
- ModelStatus
- AparteAIProvider
- AparteStatus
- AparteBubbleRole
- AparteBubbleActionName
- AparteSegmentDefaults
- AparteSegment
- AparteSegmentType
- AparteThemeVariables
- AparteApprovalPolicy
- AparteToolHandler
- AparteToolSummary
- Enumerations
-
Event details
- AparteMessageDoneEventDetail
- AparteModelChangeEventDetail
- AparteLinkClickEventDetail
- AparteBranchNavigateEventDetail
- ApartePathChangedEventDetail
- AparteRetryEventDetail
- AparteEditEventDetail
- AparteFeedbackEventDetail
- AparteActionEventDetail
- AparteMessageInfoEventDetail
- AparteMessageStartEventDetail
- AparteMessageErrorEventDetail
- AparteMessagePausedEventDetail
- AparteMessageAbortedEventDetail
- AparteAbortEventDetail
- AparteCompactEventDetail
- AparteCompactStartEventDetail
- AparteCompactDoneEventDetail
- AparteCompactErrorEventDetail
- AparteAttachmentPreviewEventDetail
- AparteApprovalModeChangeEventDetail
- AparteToolApprovalRequestDetail
Classes
Section titled “Classes”AparteStreamParser
Section titled “AparteStreamParser”Defined in: packages/core/src/parsers/aparte-stream-parser.ts:93
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new AparteStreamParser(options?): AparteStreamParser;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:109
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
options | AparteStreamParserOptions |
Returns
Section titled “Returns”Methods
Section titled “Methods”parse()
Section titled “parse()”parse(chunk): AparteParserResult;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:131
Parse a chunk of streamed content Call this for each chunk received from the LLM
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
chunk | string |
Returns
Section titled “Returns”finalize()
Section titled “finalize()”finalize(): AparteSegment[];Defined in: packages/core/src/parsers/aparte-stream-parser.ts:164
Finalize parsing - flush any remaining content as text
Returns
Section titled “Returns”reset()
Section titled “reset()”reset(): void;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:210
Reset parser state
Returns
Section titled “Returns”void
getState()
Section titled “getState()”getState(): Readonly<AparteParserState>;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:218
Get current parser state (for debugging/inspection)
Returns
Section titled “Returns”Readonly<AparteParserState>
AparteError
Section titled “AparteError”Defined in: packages/core/src/types/errors.ts:28
Extends
Section titled “Extends”Error
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new AparteError(
message,
code,
data?,
originalError?,
httpStatus?): AparteError;Defined in: packages/core/src/types/errors.ts:29
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
message | string |
code | AparteErrorCode |
data? | Record<string, unknown> |
originalError? | unknown |
httpStatus? | number |
Returns
Section titled “Returns”Overrides
Section titled “Overrides”Error.constructorProperties
Section titled “Properties”message
Section titled “message”message: string;Defined in: packages/core/src/types/errors.ts:30
Inherited from
Section titled “Inherited from”Error.messagecode: AparteErrorCode;Defined in: packages/core/src/types/errors.ts:31
optional data?: Record<string, unknown>;Defined in: packages/core/src/types/errors.ts:32
originalError?
Section titled “originalError?”optional originalError?: unknown;Defined in: packages/core/src/types/errors.ts:33
httpStatus?
Section titled “httpStatus?”optional httpStatus?: number;Defined in: packages/core/src/types/errors.ts:34
Methods
Section titled “Methods”codeForStatus()
Section titled “codeForStatus()”static codeForStatus(status): AparteErrorCode | undefined;Defined in: packages/core/src/types/errors.ts:45
The code an HTTP status stands for — the table the enum’s own comments promise.
undefined for a status the enum does not name (a 404 can be a wrong model or a
wrong URL; the message says which, a code would guess).
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
status | number | undefined |
Returns
Section titled “Returns”AparteErrorCode | undefined
from()
Section titled “from()”static from(
error,
defaultCode?,
defaultStatus?): AparteError;Defined in: packages/core/src/types/errors.ts:57
Parameters
Section titled “Parameters”| Parameter | Type | Default value |
|---|---|---|
error | unknown | undefined |
defaultCode | AparteErrorCode | AparteErrorCode.UNKNOWN_ERROR |
defaultStatus? | number | undefined |
Returns
Section titled “Returns”Functions
Section titled “Functions”parseAparteEventStream()
Section titled “parseAparteEventStream()”function parseAparteEventStream(stream): ReadableStream<AparteStreamEvent>;Defined in: packages/core/src/parsers/aparte-event-stream.ts:15
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
stream | ReadableStream<Uint8Array<ArrayBufferLike>> |
Returns
Section titled “Returns”ReadableStream<AparteStreamEvent>
parseMarkdownToSegments()
Section titled “parseMarkdownToSegments()”function parseMarkdownToSegments(content, options?): AparteSegment[];Defined in: packages/core/src/parsers/aparte-stream-parser.ts:713
Parse a complete markdown string into segments Use this for non-streaming scenarios
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
content | string |
options? | AparteStreamParserOptions |
Returns
Section titled “Returns”registerSegmentRenderer()
Section titled “registerSegmentRenderer()”function registerSegmentRenderer<T>(renderer, config?): void;Defined in: packages/core/src/renderers/segment-renderers.ts:114
Register a segment renderer.
config defaults to the ambient render config, which at app startup — no
element, no active render — is the global singleton. That is the right default:
a chat with its own config inherits global registrations. Pass a config
explicitly only to give ONE chat a renderer the others must not have.
Type Parameters
Section titled “Type Parameters”| Type Parameter |
|---|
T extends AparteSegmentBase |
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
renderer | AparteSegmentRenderer<T> |
config | AparteConfig |
Returns
Section titled “Returns”void
declineDefaultRenderers()
Section titled “declineDefaultRenderers()”function declineDefaultRenderers(config?): void;Defined in: packages/core/src/renderers/segment-renderers.ts:129
Remember that the app declined the built-in renderers, so installDefaultRenderersOnce stays out of the way for good.
AparteClient({ autoRegister: false }) is the one caller. Without this latch the
lazy install below would quietly turn that option into a no-op.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
config | AparteConfig |
Returns
Section titled “Returns”void
installDefaultRenderersOnce()
Section titled “installDefaultRenderersOnce()”function installDefaultRenderersOnce(config?): void;Defined in: packages/core/src/renderers/segment-renderers.ts:147
Fill in the built-in renderers for the types nobody has claimed — called by the bubble the first time a segment has no renderer.
Why lazily and not at import time: registerDefaultRenderers() used to have
exactly one caller, new AparteClient(). An app on the bring-your-own-loop
path — the one the guide tells you not to construct a client on — rendered
[Unknown segment type: text] for every reply. Bubbles, streaming and scrolling
all worked; only the content was missing, which reads as a bug in the consumer’s
own loop, not as a missing call.
Strictly additive: a type someone registered themselves is never replaced, so a
custom text renderer survives the sweep triggered by a code segment.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
config | AparteConfig |
Returns
Section titled “Returns”void
unregisterSegmentRenderer()
Section titled “unregisterSegmentRenderer()”function unregisterSegmentRenderer(type, config?): void;Defined in: packages/core/src/renderers/segment-renderers.ts:160
Unregister a segment renderer
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
type | string |
config | AparteConfig |
Returns
Section titled “Returns”void
getSegmentRenderer()
Section titled “getSegmentRenderer()”function getSegmentRenderer(type, config?):
| AparteSegmentRenderer<AparteSegmentBase>
| undefined;Defined in: packages/core/src/renderers/segment-renderers.ts:167
Get renderer for a segment type
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
type | string |
config | AparteConfig |
Returns
Section titled “Returns”| AparteSegmentRenderer<AparteSegmentBase>
| undefined
getAllRenderers()
Section titled “getAllRenderers()”function getAllRenderers(config?): readonly AparteSegmentRenderer<AparteSegmentBase>[];Defined in: packages/core/src/renderers/segment-renderers.ts:177
Get all registered renderers
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
config | AparteConfig |
Returns
Section titled “Returns”readonly AparteSegmentRenderer<AparteSegmentBase>[]
collectRendererStyles()
Section titled “collectRendererStyles()”function collectRendererStyles(config?): string;Defined in: packages/core/src/renderers/segment-renderers.ts:187
Collect all renderer styles for one config.
Its OWN renderers, not the inherited view: a config that inherits the global’s renderers also inherits their stylesheet, which the global already injected.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
config | AparteConfig |
Returns
Section titled “Returns”string
registerDefaultRenderers()
Section titled “registerDefaultRenderers()”function registerDefaultRenderers(config?): void;Defined in: packages/core/src/renderers/segment-renderers.ts:266
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
config | AparteConfig |
Returns
Section titled “Returns”void
contentToText()
Section titled “contentToText()”function contentToText(content): string;Defined in: packages/core/src/types/chat.ts:44
Extract plain text from a string | AparteContentPart[] content value.
Use this in providers and app-layer code whenever you need the text-only representation.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
content | string | AparteContentPart[] |
Returns
Section titled “Returns”string
Interfaces
Section titled “Interfaces”AparteThinkingDelimiterPair
Section titled “AparteThinkingDelimiterPair”Defined in: packages/core/src/parsers/aparte-stream-parser.ts:27
One inline thinking-block delimiter pair (open/close tag).
Properties
Section titled “Properties”start: string;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:28
end: string;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:29
AparteStreamParserOptions
Section titled “AparteStreamParserOptions”Defined in: packages/core/src/parsers/aparte-stream-parser.ts:32
Properties
Section titled “Properties”thinkingDelimiters?
Section titled “thinkingDelimiters?”optional thinkingDelimiters?:
| AparteThinkingDelimiterPair
| AparteThinkingDelimiterPair[];Defined in: packages/core/src/parsers/aparte-stream-parser.ts:41
Inline thinking-block delimiters — for a model that streams its reasoning
inline in the content (rather than on a separate reasoning channel).
Accepts one pair or several; the parser opens a thinking segment at
whichever pair appears first. Default recognizes BOTH common conventions:
<think>…</think> (DeepSeek-R1, QwQ, most local GGUF reasoning models) and
<thinking>…</thinking> (Claude-style). Pass your own to override.
blocks?
Section titled “blocks?”optional blocks?: AparteStreamBlock[];Defined in: packages/core/src/parsers/aparte-stream-parser.ts:48
Tagged blocks to recognise in the prose — <tag attr="…">…</tag> — each turned
into the segment its grammar builds. The stream adapter passes the blocks
registered on the config (registerStreamBlock); pass your own when you drive
the parser yourself. See AparteStreamBlock.
autoGenerateIds?
Section titled “autoGenerateIds?”optional autoGenerateIds?: boolean;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:50
Auto-generate segment IDs (default: true)
idPrefix?
Section titled “idPrefix?”optional idPrefix?: string;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:52
ID prefix for generated segments
AparteParserState
Section titled “AparteParserState”Defined in: packages/core/src/parsers/aparte-stream-parser.ts:61
Properties
Section titled “Properties”mode: "text" | "thinking" | "code" | "block";Defined in: packages/core/src/parsers/aparte-stream-parser.ts:63
Current parser mode
buffer
Section titled “buffer”buffer: string;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:65
Buffer for incomplete patterns
codeLanguage?
Section titled “codeLanguage?”optional codeLanguage?: string;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:67
Current code block language
thinkingEnd?
Section titled “thinkingEnd?”optional thinkingEnd?: string;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:69
Close delimiter of the thinking pair currently open (multi-delimiter support)
blockEnd?
Section titled “blockEnd?”optional blockEnd?: string;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:71
Closing tag of the registered block currently open (</tag>).
segments
Section titled “segments”segments: AparteSegment[];Defined in: packages/core/src/parsers/aparte-stream-parser.ts:73
Accumulated segments
activeSegment
Section titled “activeSegment”activeSegment: AparteSegment | null;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:75
Current active segment being built
segmentCounter
Section titled “segmentCounter”segmentCounter: number;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:77
Counter for generating IDs
AparteParserResult
Section titled “AparteParserResult”Defined in: packages/core/src/parsers/aparte-stream-parser.ts:80
Properties
Section titled “Properties”segments
Section titled “segments”segments: AparteSegment[];Defined in: packages/core/src/parsers/aparte-stream-parser.ts:82
Parsed segments
remaining
Section titled “remaining”remaining: string;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:84
Remaining buffer (incomplete patterns)
state: AparteParserState;Defined in: packages/core/src/parsers/aparte-stream-parser.ts:86
Current parser state
AparteTextPart
Section titled “AparteTextPart”Defined in: packages/core/src/types/chat.ts:13
Plain text content part
Properties
Section titled “Properties”type: "text";Defined in: packages/core/src/types/chat.ts:14
text: string;Defined in: packages/core/src/types/chat.ts:15
AparteImagePart
Section titled “AparteImagePart”Defined in: packages/core/src/types/chat.ts:23
Image content part.
image must be a base64 data URL: data:image/png;base64,...
The data URL encodes the MIME type, making it consumable by all providers.
Properties
Section titled “Properties”type: "image";Defined in: packages/core/src/types/chat.ts:24
image: string;Defined in: packages/core/src/types/chat.ts:25
mimeType?
Section titled “mimeType?”optional mimeType?: string;Defined in: packages/core/src/types/chat.ts:26
AparteChatMessage
Section titled “AparteChatMessage”Defined in: packages/core/src/types/chat.ts:52
Properties
Section titled “Properties”role: "user" | "assistant" | "system" | "tool";Defined in: packages/core/src/types/chat.ts:53
content
Section titled “content”content: string | AparteContentPart[];Defined in: packages/core/src/types/chat.ts:61
Message content — either a plain string (backward compatible) or an array of typed content parts: text and images. A binary the model cannot read is not a content part; see the note on AparteContentPart.
Use contentToText(content) to extract the text-only representation.
toolCalls?
Section titled “toolCalls?”optional toolCalls?: AparteToolCall[];Defined in: packages/core/src/types/chat.ts:66
On an assistant message: the tool calls the model made this turn, grouped.
content is what it said before them — '' when it said nothing.
toolCallId?
Section titled “toolCallId?”optional toolCallId?: string;Defined in: packages/core/src/types/chat.ts:68
On a tool message: the id of the call, in the preceding assistant message, that it answers.
toolName?
Section titled “toolName?”optional toolName?: string;Defined in: packages/core/src/types/chat.ts:76
On a tool message: the name of the tool that ran.
Optional, and worth setting: a wire format that names the tool on the result (the AI SDK does) otherwise has to scan back for the call that declared the id, which a hand-built history need not contain.
AparteChatRequest
Section titled “AparteChatRequest”Defined in: packages/core/src/types/chat.ts:88
The request one turn sends to a provider.
prefill, systemOverride and fastStream used to sit here, each documented “providers
MAY ignore it” and read by none — one model family’s raw-completion vocabulary flattened
onto every provider’s request. A provider reads its option off _meta, the namespaced bag,
which reaches it untouched; the trigger to reconsider is a raw-completion provider in this
repo (provider-llamacpp) that would actually read one.
Properties
Section titled “Properties”messages
Section titled “messages”messages: AparteChatMessage[];Defined in: packages/core/src/types/chat.ts:89
modelId
Section titled “modelId”modelId: string;Defined in: packages/core/src/types/chat.ts:90
temperature?
Section titled “temperature?”optional temperature?: number;Defined in: packages/core/src/types/chat.ts:91
maxTokens?
Section titled “maxTokens?”optional maxTokens?: number;Defined in: packages/core/src/types/chat.ts:92
stream?
Section titled “stream?”optional stream?: boolean;Defined in: packages/core/src/types/chat.ts:93
tools?
Section titled “tools?”optional tools?: AparteTool[];Defined in: packages/core/src/types/chat.ts:95
Tools the AI is allowed to call
optional seed?: number;Defined in: packages/core/src/types/chat.ts:106
Random seed for reproducibility. Passed through verbatim by the providers that support it (OpenAI-compatible endpoints, the AI SDK bridge, the transformers worker); Anthropic exposes none, so it is ignored there.
Nothing sets it for you: a retry varies its answer by sampling
(temperature), not by seeding — this line used to promise an automatic
per-retry seed that no code had ever written. Set it from a
requestInterceptor when you need reproducible runs.
toolChoice?
Section titled “toolChoice?”optional toolChoice?:
| "auto"
| "none"
| {
name: string;
input?: Record<string, unknown>;
};Defined in: packages/core/src/types/chat.ts:118
Controls which tool the model must call — mirrors OpenAI tool_choice / Anthropic tool_choice.
- ‘auto’ : model decides (default when tools are present)
- ‘none’ : no tools injected this turn — model answers directly
- { name } : model MUST call this tool (provider injects a strong directive)
- { name, input }: synthetic call — the agent loop (
runStreamAgent, or the runner you injected) bypasses the LLM entirely and runs the handler directly with the provided input, then re-calls the LLM with the tool message in history.
AparteRequestMeta
Section titled “AparteRequestMeta”Defined in: packages/core/src/types/chat.ts:139
The well-known keys of AparteChatRequest._meta. One, read by core’s client and
not by the loop; the rest of the bag is the consumer’s (index signature).
pipeline, artifactRaw and artifactXml used to sit here too and were removed
(audit 2026-08-28, D2), then artifactHint (D7): an artifact is a plugin’s
convention now, and a promoted code fence had no consumer.
Indexable
Section titled “Indexable”[key: string]: unknownConsumer-specific context (open channel).
Properties
Section titled “Properties”prefixSegments?
Section titled “prefixSegments?”optional prefixSegments?: AparteSegment[];Defined in: packages/core/src/types/chat.ts:146
Segments to show at the top of the assistant’s turn before the model has said
anything — a “planning” thinking block a host wants visible from the first
frame, a status row. Added right after the turn flips to streaming, in this
order, and never sent to the model.
compaction?
Section titled “compaction?”optional compaction?: true;Defined in: packages/core/src/types/chat.ts:152
Set by @aparte/plugin-compaction on the summarisation request, and on nothing
else. A backend transport can route it — a cheaper model, a shorter timeout —
without inspecting the messages to guess what the request is for.
AparteUsage
Section titled “AparteUsage”Defined in: packages/core/src/types/chat.ts:160
Token usage reported by the AI provider after a completed response.
Properties
Section titled “Properties”inputTokens
Section titled “inputTokens”inputTokens: number;Defined in: packages/core/src/types/chat.ts:162
Tokens in the prompt / conversation history sent to the model
outputTokens
Section titled “outputTokens”outputTokens: number;Defined in: packages/core/src/types/chat.ts:164
Tokens generated by the model
totalTokens?
Section titled “totalTokens?”optional totalTokens?: number;Defined in: packages/core/src/types/chat.ts:166
Total tokens (inputTokens + outputTokens). Populated when the provider reports it.
cacheReadTokens?
Section titled “cacheReadTokens?”optional cacheReadTokens?: number;Defined in: packages/core/src/types/chat.ts:168
Tokens read from the provider’s prompt cache (Anthropic, OpenAI).
durationMs?
Section titled “durationMs?”optional durationMs?: number;Defined in: packages/core/src/types/chat.ts:170
Wall-clock generation time in milliseconds (provider-measured). Used to compute tokens/sec.
ttftMs?
Section titled “ttftMs?”optional ttftMs?: number;Defined in: packages/core/src/types/chat.ts:174
Time to first token in ms — the prefill / TTFT phase.
decodeMs?
Section titled “decodeMs?”optional decodeMs?: number;Defined in: packages/core/src/types/chat.ts:176
Decode-phase wall time in ms (≈ durationMs − ttftMs).
decodeTokens?
Section titled “decodeTokens?”optional decodeTokens?: number;Defined in: packages/core/src/types/chat.ts:178
Tokens emitted during the decode phase (outputTokens minus the first).
wallMs?
Section titled “wallMs?”optional wallMs?: number;Defined in: packages/core/src/types/chat.ts:180
Total turn wall-clock time in ms, measured client-side across all phases.
modelId?
Section titled “modelId?”optional modelId?: string;Defined in: packages/core/src/types/chat.ts:182
Id of the model that produced this response.
device?
Section titled “device?”optional device?: string;Defined in: packages/core/src/types/chat.ts:184
Compute device used for this response (‘webgpu’ | ‘wasm’ | …).
phases?
Section titled “phases?”optional phases?: AparteUsage[];Defined in: packages/core/src/types/chat.ts:190
Per-call breakdown when a single turn used several provider calls (e.g. a tool-use round-trip or a mid-turn model swap). Absent for a plain single-call turn. Each entry is the AparteUsage of one provider call.
AparteStreamEventMap
Section titled “AparteStreamEventMap”Defined in: packages/core/src/types/chat.ts:204
Normalized stream event map — extensible via declaration merging.
Example
Section titled “Example”// In a plugin or app:
declare module '@aparte/core' {
interface AparteStreamEventMap {
tool_call: { name: string; arguments: string }
}
}Properties
Section titled “Properties”text: {
delta: string;
};Defined in: packages/core/src/types/chat.ts:205
delta: string;thinking
Section titled “thinking”thinking: {
delta: string;
};Defined in: packages/core/src/types/chat.ts:206
delta: string;done: {
usage?: AparteUsage;
};Defined in: packages/core/src/types/chat.ts:208
Emitted when the stream ends. May carry token usage reported by the provider.
usage?
Section titled “usage?”optional usage?: AparteUsage;error: {
message: string;
};Defined in: packages/core/src/types/chat.ts:209
message
Section titled “message”message: string;tool_use
Section titled “tool_use”tool_use: AparteToolCall;Defined in: packages/core/src/types/chat.ts:210
AparteSendEventDetail
Section titled “AparteSendEventDetail”Defined in: packages/core/src/types/events.ts:19
Detail payload for aparte-send custom event Emitted when user sends a message via the input component
Properties
Section titled “Properties”content
Section titled “content”content: string;Defined in: packages/core/src/types/events.ts:21
The message content being sent
timestamp
Section titled “timestamp”timestamp: number;Defined in: packages/core/src/types/events.ts:24
Timestamp of the send action
targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:33
ID of the chat this send belongs to: the composer’s target attribute, or the id
of the <aparte-chat> / [data-aparte-chat] host above it — the same resolution
the composer’s receive side (_isForThisComposer) uses, so the two halves of the
channel cannot disagree about which chat is which.
Used by AparteClient to find the host without DOM traversal.
files?
Section titled “files?”optional files?: File[];Defined in: packages/core/src/types/events.ts:36
Files attached to this message (populated by composer attachments)
modelId?
Section titled “modelId?”optional modelId?: string;Defined in: packages/core/src/types/events.ts:50
Send THIS message to a specific model, overriding the config’s default for one turn — a per-message model picker, the pattern several products now ship.
AparteClient has honoured both fields for as long as it has read
event.detail, while nothing declared them: the composer never sends them and
this type did not name them, so the capability existed only for someone who
read the client’s source. A capability cited nowhere is invisible (ratified
decision #4); declaring it is what makes it real. Dispatch your own
aparte-send with them, or set them on the detail from a listener that runs
before the client’s (capture phase).
providerId?
Section titled “providerId?”optional providerId?: string;Defined in: packages/core/src/types/events.ts:52
The provider that modelId belongs to; defaults to the config’s defaultProvider.
AparteSiblingInfo
Section titled “AparteSiblingInfo”Defined in: packages/core/src/types/events.ts:119
Per-message sibling metadata carried by aparte-path-changed.
index is 0-based; UI renders it as index + 1 / count.
Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/events.ts:121
Message id
count: number;Defined in: packages/core/src/types/events.ts:123
Total number of siblings (including this one). 1 = no branch picker.
index: number;Defined in: packages/core/src/types/events.ts:125
0-based position of this message among its siblings.
AparteChatImperativeApi
Section titled “AparteChatImperativeApi”Defined in: packages/core/src/types/imperative-api.ts:14
The canonical imperative surface a framework <AparteChat> exposes (React’s
ref handle, Vue/Svelte’s instance, Angular’s component). All four delegate to
the framework-agnostic AparteChatHost, so this ONE contract is the single
source of truth, and each wrapper enforces it against the compiler — React via
the ref-handle type on a return-annotated useImperativeHandle, Angular via
implements, Vue via satisfies on defineExpose, Svelte via a type-checked
parity factory — so a missing or mistyped method is a build error in that
wrapper, not a silent divergence.
Properties
Section titled “Properties”appendMessage
Section titled “appendMessage”appendMessage: (message, options?) => void;Defined in: packages/core/src/types/imperative-api.ts:23
Append a message. { historical: true } says it is RESTORED, not live: its
segments are adopted as they are — no fresh timing stamps, isStreaming forced
off — the way a stored conversation is loaded, so a tool call read back from
your own backend renders settled rather than spinning. Use it when you replay
history one message at a time; a live turn passes nothing.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
message | AparteMessage |
options? | { historical?: boolean; } |
options.historical? | boolean |
Returns
Section titled “Returns”void
updateMessage
Section titled “updateMessage”updateMessage: (messageId, updates) => void;Defined in: packages/core/src/types/imperative-api.ts:24
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
messageId | string |
updates | Partial<AparteMessage> |
Returns
Section titled “Returns”void
updateLastMessage
Section titled “updateLastMessage”updateLastMessage: (content, options?) => void;Defined in: packages/core/src/types/imperative-api.ts:25
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
content | string |
options? | { append?: boolean; } |
options.append? | boolean |
Returns
Section titled “Returns”void
addSegment
Section titled “addSegment”addSegment: (segment) => void;Defined in: packages/core/src/types/imperative-api.ts:26
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
segment | AparteSegment |
Returns
Section titled “Returns”void
updateSegment
Section titled “updateSegment”updateSegment: (segmentId, updates) => void;Defined in: packages/core/src/types/imperative-api.ts:27
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
segmentId | string |
updates | Partial<AparteSegment> |
Returns
Section titled “Returns”void
removeSegment
Section titled “removeSegment”removeSegment: (segmentId) => void;Defined in: packages/core/src/types/imperative-api.ts:28
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
segmentId | string |
Returns
Section titled “Returns”void
appendToSegment
Section titled “appendToSegment”appendToSegment: (segmentId, content) => void;Defined in: packages/core/src/types/imperative-api.ts:42
Append text to a segment of the last message — the streaming path for a thinking block, a tool pill, or any segment that grows token by token.
Each chunk is written straight into the bubble, and the framework’s message list is synced once per frame rather than per chunk, so streaming a segment costs about one render per frame instead of one per token.
Note that segments and content are mutually exclusive at render time: as
soon as a message has segments the bubble hides its plain content, so a
message driven by injectTokenStream (which writes content) can’t also show
a thinking segment — put the text in a segment of its own instead.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
segmentId | string |
content | string |
Returns
Section titled “Returns”void
getMessages
Section titled “getMessages”getMessages: () => AparteMessage[];Defined in: packages/core/src/types/imperative-api.ts:43
Returns
Section titled “Returns”clearMessages
Section titled “clearMessages”clearMessages: (options?) => void;Defined in: packages/core/src/types/imperative-api.ts:44
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
options? | { revokeAttachments?: boolean; } |
options.revokeAttachments? | boolean |
Returns
Section titled “Returns”void
addBranch
Section titled “addBranch”addBranch: (messageId) => number;Defined in: packages/core/src/types/imperative-api.ts:46
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
messageId | string |
Returns
Section titled “Returns”number
addSiblingOf
Section titled “addSiblingOf”addSiblingOf: (existingId, message) => string | null;Defined in: packages/core/src/types/imperative-api.ts:47
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
existingId | string |
message | AparteMessage |
Returns
Section titled “Returns”string | null
truncateFrom
Section titled “truncateFrom”truncateFrom: (messageId) => void;Defined in: packages/core/src/types/imperative-api.ts:48
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
messageId | string |
Returns
Section titled “Returns”void
truncateResponsesAfter
Section titled “truncateResponsesAfter”truncateResponsesAfter: (userMessageId) => void;Defined in: packages/core/src/types/imperative-api.ts:49
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
userMessageId | string |
Returns
Section titled “Returns”void
injectTokenStream
Section titled “injectTokenStream”injectTokenStream: (messageId, tokens) => Promise<void>;Defined in: packages/core/src/types/imperative-api.ts:66
Stream tokens into a message from your own loop (no AparteClient
involved). It sends the turn’s lifecycle events itself — aparte-message-start,
then -done, -aborted or -error — so the composer shows Stop, its Stop
cancels the stream, and the conversation manager saves the reply. Resolves when
the iterable completes; the message is then marked complete.
If messageId doesn’t exist the viewport auto-creates an empty
assistant message — but only in its internal repo, NOT in the
framework’s message state. In a wrapper, call
appendMessage({ id, role: 'assistant', content: '' , timestamp: Date.now() })
first so both stay in sync. Starting a new stream cancels the previous
one; stopTokenStream cancels explicitly. See the
“Bring your own loop” guide.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
messageId | string |
tokens | AsyncIterable<string> |
Returns
Section titled “Returns”Promise<void>
stopTokenStream
Section titled “stopTokenStream”stopTokenStream: () => void;Defined in: packages/core/src/types/imperative-api.ts:68
Abort an in-flight injectTokenStream loop (the source iterable is return()ed).
Returns
Section titled “Returns”void
setConversationId
Section titled “setConversationId”setConversationId: (id) => Promise<void>;Defined in: packages/core/src/types/imperative-api.ts:70
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
id | string | null |
Returns
Section titled “Returns”Promise<void>
scrollToBottom
Section titled “scrollToBottom”scrollToBottom: () => void;Defined in: packages/core/src/types/imperative-api.ts:72
Returns
Section titled “Returns”void
focusInput
Section titled “focusInput”focusInput: () => void;Defined in: packages/core/src/types/imperative-api.ts:73
Returns
Section titled “Returns”void
isStreaming
Section titled “isStreaming”isStreaming: () => boolean;Defined in: packages/core/src/types/imperative-api.ts:74
Returns
Section titled “Returns”boolean
getViewport
Section titled “getViewport”getViewport: () => HTMLElement | null;Defined in: packages/core/src/types/imperative-api.ts:76
The <aparte-chat-viewport> element — same getViewport() on all four wrappers.
Returns
Section titled “Returns”HTMLElement | null
AparteUiHandle
Section titled “AparteUiHandle”Defined in: packages/core/src/types/imperative-api.ts:89
The imperative surface every framework <AparteUi> proxy exposes — React’s ref
handle, Vue’s template ref, Svelte’s bind:this, Angular’s @ViewChild.
It lives here for the same reason AparteChatImperativeApi does: it was
hand-copied into all four wrappers, each docblock promising “the same contract on
all four”, and it had already drifted once (two of them returned
HTMLElement | null / unknown instead of the generic form). One declaration, four
re-exports, and a divergence is a compile error rather than a promise in prose.
Methods
Section titled “Methods”getElement()
Section titled “getElement()”getElement<T>(): T | null;Defined in: packages/core/src/types/imperative-api.ts:91
The proxied custom element, once mounted.
Type Parameters
Section titled “Type Parameters”| Type Parameter | Default type |
|---|---|
T extends HTMLElement | HTMLElement |
Returns
Section titled “Returns”T | null
callMethod()
Section titled “callMethod()”callMethod<T>(methodName, ...args): T | undefined;Defined in: packages/core/src/types/imperative-api.ts:93
Call a method on it — the escape hatch for an element-specific API.
Type Parameters
Section titled “Type Parameters”| Type Parameter | Default type |
|---|---|
T | unknown |
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
methodName | string |
…args | unknown[] |
Returns
Section titled “Returns”T | undefined
AparteAIModel
Section titled “AparteAIModel”Defined in: packages/core/src/types/model-provider.ts:30
Represents an AI model that can be selected by the user.
Example
Section titled “Example”const model: AparteAIModel = {
id: 'gpt-4-turbo',
name: 'GPT-4 Turbo',
contextWindow: 128000,
capabilities: ['vision', 'function_calling', 'streaming']
};Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/model-provider.ts:32
Unique identifier for the model (e.g., ‘gpt-4-turbo’, ‘claude-3-opus’)
name: string;Defined in: packages/core/src/types/model-provider.ts:35
Human-readable display name
contextWindow?
Section titled “contextWindow?”optional contextWindow?: number;Defined in: packages/core/src/types/model-provider.ts:38
Optional context window size in tokens
pricing?
Section titled “pricing?”optional pricing?: {
input: number;
output: number;
};Defined in: packages/core/src/types/model-provider.ts:41
Optional pricing information (per 1M tokens)
input: number;output
Section titled “output”output: number;capabilities?
Section titled “capabilities?”optional capabilities?: ("streaming" | "code" | "vision" | "function_calling" | "reasoning")[];Defined in: packages/core/src/types/model-provider.ts:47
Optional capability flags
description?
Section titled “description?”optional description?: string;Defined in: packages/core/src/types/model-provider.ts:50
Optional short description shown in model pickers
metadata?
Section titled “metadata?”optional metadata?: Record<string, unknown>;Defined in: packages/core/src/types/model-provider.ts:53
Optional metadata for custom properties
ModelLoadProgress
Section titled “ModelLoadProgress”Defined in: packages/core/src/types/model-provider.ts:75
Progress update emitted during model preparation (download + load).
Passed to the onProgress callback of AparteAIProvider.prepareModel().
Properties
Section titled “Properties”status
Section titled “status”status: "error" | "downloading" | "loading" | "cached" | "ready";Defined in: packages/core/src/types/model-provider.ts:77
Current phase of the preparation
optional file?: string;Defined in: packages/core/src/types/model-provider.ts:79
File currently being processed (e.g. “model.safetensors”)
progress?
Section titled “progress?”optional progress?: number;Defined in: packages/core/src/types/model-provider.ts:81
Progress percentage 0–100
message?
Section titled “message?”optional message?: string;Defined in: packages/core/src/types/model-provider.ts:83
Optional human-readable message
AparteAIProviderMetadata
Section titled “AparteAIProviderMetadata”Defined in: packages/core/src/types/model-provider.ts:93
Brand metadata for an AI provider, used for visual selection and onboarding.
Properties
Section titled “Properties”name: string;Defined in: packages/core/src/types/model-provider.ts:95
Human-readable display name
id: string;Defined in: packages/core/src/types/model-provider.ts:98
Provider ID
optional icon?: string;Defined in: packages/core/src/types/model-provider.ts:104
Brand icon. Can be an SVG string, a data URI, or a key for AparteIconProvider.
color?
Section titled “color?”optional color?: string;Defined in: packages/core/src/types/model-provider.ts:107
Brand primary color (hex or CSS variable)
description?
Section titled “description?”optional description?: string;Defined in: packages/core/src/types/model-provider.ts:110
Short tag line or description
hasFreeModels?
Section titled “hasFreeModels?”optional hasFreeModels?: boolean;Defined in: packages/core/src/types/model-provider.ts:113
Whether the provider offers free models or Tiers
isLocal?
Section titled “isLocal?”optional isLocal?: boolean;Defined in: packages/core/src/types/model-provider.ts:116
Whether the provider runs locally on the user machine
helpUrl?
Section titled “helpUrl?”optional helpUrl?: string;Defined in: packages/core/src/types/model-provider.ts:119
URL to the provider’s API key management page or documentation
configSchema?
Section titled “configSchema?”optional configSchema?: AparteAIProviderConfigSchema;Defined in: packages/core/src/types/model-provider.ts:122
Configuration schema for the onboarding UI
AparteAIProviderConfigField
Section titled “AparteAIProviderConfigField”Defined in: packages/core/src/types/model-provider.ts:128
Definition of a configuration field for the provider
Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/model-provider.ts:130
Unique identifier for the field (e.g., ‘apiKey’, ‘endpoint’)
type: "text" | "password" | "url";Defined in: packages/core/src/types/model-provider.ts:132
Basic type for the input field
label: string;Defined in: packages/core/src/types/model-provider.ts:134
Human readable label (e.g., ‘API Key’, ‘Sever URL’)
placeholder?
Section titled “placeholder?”optional placeholder?: string;Defined in: packages/core/src/types/model-provider.ts:136
Placeholder hint
defaultValue?
Section titled “defaultValue?”optional defaultValue?: string;Defined in: packages/core/src/types/model-provider.ts:138
Initial value
required?
Section titled “required?”optional required?: boolean;Defined in: packages/core/src/types/model-provider.ts:140
Whether the field is mandatory to start
isAdvanced?
Section titled “isAdvanced?”optional isAdvanced?: boolean;Defined in: packages/core/src/types/model-provider.ts:142
If true, the field is hidden behind an ‘Advanced’ toggle in UI
AparteAIProviderConfigSchema
Section titled “AparteAIProviderConfigSchema”Defined in: packages/core/src/types/model-provider.ts:148
Encapsulates all configuration fields for a provider
Properties
Section titled “Properties”fields
Section titled “fields”fields: AparteAIProviderConfigField[];Defined in: packages/core/src/types/model-provider.ts:149
AparteModelConfig
Section titled “AparteModelConfig”Defined in: packages/core/src/types/model-provider.ts:321
Configuration options for model selection behavior.
Properties
Section titled “Properties”enabledProviders?
Section titled “enabledProviders?”optional enabledProviders?: string[];Defined in: packages/core/src/types/model-provider.ts:323
Which providers to enable (all if omitted)
modelFilters?
Section titled “modelFilters?”optional modelFilters?: Record<string, string[]>;Defined in: packages/core/src/types/model-provider.ts:326
Filter models by provider
defaultProvider?
Section titled “defaultProvider?”optional defaultProvider?: string;Defined in: packages/core/src/types/model-provider.ts:329
Default provider ID
defaultModel?
Section titled “defaultModel?”optional defaultModel?: string;Defined in: packages/core/src/types/model-provider.ts:332
Default model ID
AparteAttachment
Section titled “AparteAttachment”Defined in: packages/core/src/types/models.ts:34
Attachment interface for media and file support Future-proof structure for images, audio, documents, etc.
Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/models.ts:36
Unique identifier for the attachment
name: string;Defined in: packages/core/src/types/models.ts:39
Display name of the attachment
type: string;Defined in: packages/core/src/types/models.ts:42
MIME type (e.g., ‘image/png’, ‘application/pdf’)
url: string;Defined in: packages/core/src/types/models.ts:45
URL or data URI to access the attachment
optional size?: number;Defined in: packages/core/src/types/models.ts:48
Optional file size in bytes
thumbnailUrl?
Section titled “thumbnailUrl?”optional thumbnailUrl?: string;Defined in: packages/core/src/types/models.ts:51
Optional thumbnail URL for previews
metadata?
Section titled “metadata?”optional metadata?: Record<string, unknown>;Defined in: packages/core/src/types/models.ts:54
Optional metadata for custom properties
optional blob?: Blob;Defined in: packages/core/src/types/models.ts:62
Binary payload. Set at message-creation time (File from upload) so the
persistence adapter can save it to its attachments table. Stripped from
the serialised message row — the adapter reconstructs url via
URL.createObjectURL(blob) on hydration. Not serialised to JSON.
AparteMessageBranch
Section titled “AparteMessageBranch”Defined in: packages/core/src/types/models.ts:82
A single branch (alternative response) within an assistant message.
Deprecated
Section titled “Deprecated”The active branching system is tree-based via AparteMessageRepository
(siblings under the same parent node). This in-message versioning struct is
kept only for backwards compatibility with existing serialised payloads.
New code should rely on viewport methods addSiblingOf / navigateBranch
and on the aparte-path-changed event payload to drive the branch picker UI.
Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/models.ts:84
Unique identifier for this branch
content?
Section titled “content?”optional content?: string;Defined in: packages/core/src/types/models.ts:86
Text content of this branch
segments?
Section titled “segments?”optional segments?: AparteSegment[];Defined in: packages/core/src/types/models.ts:88
Rich segments of this branch
status?
Section titled “status?”optional status?: AparteStatus;Defined in: packages/core/src/types/models.ts:90
Branch status
timestamp
Section titled “timestamp”timestamp: number;Defined in: packages/core/src/types/models.ts:92
Creation timestamp
AparteBubbleActionsConfig
Section titled “AparteBubbleActionsConfig”Defined in: packages/core/src/types/models.ts:125
Controls which action buttons are rendered in message bubbles.
Pass to aparteGlobalConfig.setBubbleActions() to customise or disable actions.
Only copy is on by default. Core can copy text on its own; every other
button needs someone outside core to honor it — AparteClient (retry, edit) or
your own listener (feedback, info). A button nobody answers is a lie told to the
user, so aparté ships them off and you turn on what you handle:
aparteGlobalConfig.setBubbleActions({ retry: true, edit: true }); // you run AparteClientTwo ways to configure:
- Global flags (
copy/retry/edit/feedback/info) — role-aware defaults. - Explicit per-role ordered sets (
user/assistant) — when provided for a role, they fully replace the flag-derived set for that role: buttons render in exactly the given order, and naming a button there IS the opt-in (the flag is not consulted). Lets a theme match a specific product 1:1.
Properties
Section titled “Properties”optional copy?: boolean;Defined in: packages/core/src/types/models.ts:127
Copy message text to clipboard — the one action core honors alone. Default: true
retry?
Section titled “retry?”optional retry?: boolean;Defined in: packages/core/src/types/models.ts:129
Retry / regenerate the response (assistant bubbles). Needs a host to re-send. Default: false
optional edit?: boolean;Defined in: packages/core/src/types/models.ts:131
Edit the sent message inline (user bubbles). Needs a host to keep the new text. Default: false
feedback?
Section titled “feedback?”optional feedback?: boolean;Defined in: packages/core/src/types/models.ts:133
Thumbs-up / thumbs-down feedback (assistant bubbles). Needs a listener. Default: false
optional info?: boolean;Defined in: packages/core/src/types/models.ts:139
The details (“i”) button, which opens the app-owned stats popover by
emitting aparte-message-info (assistant bubbles). Rendered only when the
message also carries a usage — no numbers, nothing to show. Default: false
optional user?: AparteBubbleActionName[];Defined in: packages/core/src/types/models.ts:141
Explicit, ordered action set for USER bubbles. Example: ['edit', 'copy'].
assistant?
Section titled “assistant?”optional assistant?: AparteBubbleActionName[];Defined in: packages/core/src/types/models.ts:143
Explicit, ordered action set for ASSISTANT bubbles. Example: ['copy', 'thumbUp', 'thumbDown', 'retry'].
AparteHostHandlersConfig
Section titled “AparteHostHandlersConfig”Defined in: packages/core/src/types/models.ts:159
The affordances core RENDERS but cannot COMPLETE — each one only asks, through a
DOM event, and the app does the work. Declare what your app actually handles
with aparteGlobalConfig.setHostHandlers(); everything else stays out of the UI
rather than showing a control that answers to nobody.
aparteGlobalConfig.setHostHandlers({ attachmentPreview: true }); // you open a lightboxThese are declarations, not callbacks: the event (aparte-attachment-preview)
is unchanged, and you keep listening for it wherever you already do.
Properties
Section titled “Properties”attachmentPreview?
Section titled “attachmentPreview?”optional attachmentPreview?: boolean;Defined in: packages/core/src/types/models.ts:165
Clicking an image attachment asks for a full-size preview
(aparte-attachment-preview) — core owns no lightbox. Until declared, the
tile is inert and is not signalled as a button. Default: false
AparteMessage
Section titled “AparteMessage”Defined in: packages/core/src/types/models.ts:172
Core message structure for the chat Supports both simple content and rich multi-segment content
Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/models.ts:174
Unique identifier for the message
role: AparteBubbleRole;Defined in: packages/core/src/types/models.ts:177
Role of the message sender
content?
Section titled “content?”optional content?: string;Defined in: packages/core/src/types/models.ts:183
Simple text content (for basic messages)
Use segments for rich content with multiple parts
segments?
Section titled “segments?”optional segments?: AparteSegment[];Defined in: packages/core/src/types/models.ts:189
Rich content segments (thinking, code, tool calls, artifacts, …)
Takes precedence over content if provided
timestamp
Section titled “timestamp”timestamp: number;Defined in: packages/core/src/types/models.ts:192
Unix timestamp of message creation
isStreaming?
Section titled “isStreaming?”optional isStreaming?: boolean;Defined in: packages/core/src/types/models.ts:195
Whether the message is still being streamed
status?
Section titled “status?”optional status?: AparteStatus;Defined in: packages/core/src/types/models.ts:198
Current status of the message
attachments?
Section titled “attachments?”optional attachments?: AparteAttachment[];Defined in: packages/core/src/types/models.ts:201
Optional attachments (images, files, etc.)
usage?
Section titled “usage?”optional usage?: AparteUsage;Defined in: packages/core/src/types/models.ts:204
Token usage + timing reported by the provider for assistant messages.
model?
Section titled “model?”optional model?: {
providerId: string;
modelId: string;
temperature?: number;
};Defined in: packages/core/src/types/models.ts:211
The provider, model and temperature an assistant turn ran on, written by
AparteClient when the turn starts. A turn a server paused is resumed on them after
a reload (resumeDeferred), not on whatever model is selected by then.
providerId
Section titled “providerId”providerId: string;modelId
Section titled “modelId”modelId: string;temperature?
Section titled “temperature?”optional temperature?: number;compaction?
Section titled “compaction?”optional compaction?: true;Defined in: packages/core/src/types/models.ts:221
This message is the summary @aparte/plugin-compaction injected in place of the
turns it summarised (a host that summarises by other means sets the flag too). Its role is user — the summary is context handed to the
model, and a system message mid-conversation is refused by some providers —
but it is not something the user said: the viewport renders it as a notice
(data-kind="compaction" on the bubble: centred, no avatar, no actions) and
the history sends it under a fixed preamble saying what it is.
branches?
Section titled “branches?”optional branches?: AparteMessageBranch[];Defined in: packages/core/src/types/models.ts:230
Alternative responses generated by retrying.
Deprecated
Section titled “Deprecated”Use the tree-based branching exposed by AparteMessageRepository
(siblings under the same parent). The bubble no longer reads this field
— sibling counts come from aparte-path-changed event metadata.
activeBranchIndex?
Section titled “activeBranchIndex?”optional activeBranchIndex?: number;Defined in: packages/core/src/types/models.ts:236
Index of the currently displayed branch (default 0).
Deprecated
Section titled “Deprecated”metadata?
Section titled “metadata?”optional metadata?: Record<string, unknown>;Defined in: packages/core/src/types/models.ts:239
Optional metadata for custom properties
AparteViewportConfig
Section titled “AparteViewportConfig”Defined in: packages/core/src/types/models.ts:247
Configuration options for AparteChatViewport
Properties
Section titled “Properties”scrollThreshold?
Section titled “scrollThreshold?”optional scrollThreshold?: number;Defined in: packages/core/src/types/models.ts:249
Threshold in pixels for smart scroll detection
maxRenderedBubbles?
Section titled “maxRenderedBubbles?”optional maxRenderedBubbles?: number;Defined in: packages/core/src/types/models.ts:257
DOM render cap: the max number of bubbles kept in the DOM at once (a perf ceiling for very long conversations). This does NOT evict messages from the conversation model — the full tree and its persistence snapshot stay intact. Defaults to 1000.
layoutTransitionMs?
Section titled “layoutTransitionMs?”optional layoutTransitionMs?: number;Defined in: packages/core/src/types/models.ts:265
Duration in milliseconds to freeze spacer recalculation after resetSpacer().
Set this to the duration of any CSS layout transition in the host app
(e.g. the flex animation that moves the composer from center to bottom).
Defaults to 0 (no freeze). Example: 350 when transition: flex 0.3s ease is used.
AparteInputConfig
Section titled “AparteInputConfig”Defined in: packages/core/src/types/models.ts:269
Configuration options for the composer input.
Properties
Section titled “Properties”placeholder?
Section titled “placeholder?”optional placeholder?: string;Defined in: packages/core/src/types/models.ts:271
Placeholder text for the input
maxHeight?
Section titled “maxHeight?”optional maxHeight?: number;Defined in: packages/core/src/types/models.ts:274
Maximum height in pixels for auto-expand
minHeight?
Section titled “minHeight?”optional minHeight?: number;Defined in: packages/core/src/types/models.ts:277
Minimum height in pixels
AparteContentParser
Section titled “AparteContentParser”Defined in: packages/core/src/types/parsers.ts:15
Content parser plugin interface for external parsers Allows integration of Markdown, code highlighting, LaTeX, etc. without adding dependencies to the core
Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/parsers.ts:17
Unique identifier for the parser
priority
Section titled “priority”priority: number;Defined in: packages/core/src/types/parsers.ts:20
Priority for parser execution (higher = first)
Methods
Section titled “Methods”canParse()
Section titled “canParse()”canParse(content): boolean;Defined in: packages/core/src/types/parsers.ts:27
Check if this parser can handle the content
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
content | string | Raw content to check |
Returns
Section titled “Returns”boolean
true if parser should process this content
parse()
Section titled “parse()”parse(content): string;Defined in: packages/core/src/types/parsers.ts:34
Parse content and return transformed output
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
content | string | Raw content to parse |
Returns
Section titled “Returns”string
Parsed HTML string or transformed content
AparteSegmentBase
Section titled “AparteSegmentBase”Defined in: packages/core/src/types/segments.ts:11
Base segment interface - all segments extend this
Extended by
Section titled “Extended by”AparteTextSegmentAparteThinkingSegmentAparteCodeSegmentAparteCustomSegmentAparteToolCallSegmentAparteErrorSegment
Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/segments.ts:13
Unique segment identifier
type: string;Defined in: packages/core/src/types/segments.ts:16
Segment type discriminator
isStreaming?
Section titled “isStreaming?”optional isStreaming?: boolean;Defined in: packages/core/src/types/segments.ts:19
Whether segment is currently being streamed
fallback?
Section titled “fallback?”optional fallback?: string;Defined in: packages/core/src/types/segments.ts:36
One sentence standing in for the segment when no renderer claims its type —
DRAWN for every type, not only for custom.
It is the answer to a real moment: a conversation replayed in another app, a
client that loads its views lazily, an export. Core draws it as text (no markup)
under .aparte-segment-fallback. Supplying one also silences the “no renderer”
developer warning: an author who wrote a fallback has already said this can happen.
In the HISTORY sent back to the model it stands in for the segment only where core
does not serialise the type itself — custom, and any type core does not know (a
registered block grammar’s, a plugin’s). A text or a code segment contributes
its content and nothing else; thinking and tool_call are left out of the history
on purpose (_segmentsToText in AparteClient states why), and so is error.
messageId?
Section titled “messageId?”optional messageId?: string;Defined in: packages/core/src/types/segments.ts:55
Id of the message this segment belongs to. Stamped on insertion.
index?
Section titled “index?”optional index?: number;Defined in: packages/core/src/types/segments.ts:61
Position in the owning message’s segments[], maintained across
insertions and removals.
optional meta?: Record<string, unknown> & {
aparte?: AparteSegmentTiming;
};Defined in: packages/core/src/types/segments.ts:71
Extras the producer of the segment knows — token counts, cost, compute
device — plus aparte, the one sub-object core writes.
Everything except meta.aparte is yours: fill it with
updateSegment(segmentId, { meta }), which MERGES rather than replaces.
Mirrors AparteMessage.metadata.
Type Declaration
Section titled “Type Declaration”aparte?
Section titled “aparte?”optional aparte?: AparteSegmentTiming;AparteSegmentTiming
Section titled “AparteSegmentTiming”Defined in: packages/core/src/types/segments.ts:93
What core measured about a segment. Lives in meta.aparte, not on the segment.
These two were first-class fields, and moving them is not tidying. No protocol
carries a timestamp on a content block — verified rather than assumed: Anthropic’s
blocks have none (and neither does the message), OpenAI’s output_text part is
{annotations, logprobs, text, type} with created_at on the item above it, and the
AI SDK’s UIMessage.parts have none either. What the AI SDK does have is a metadata
bag whose canonical example is literally { createdAt, model, totalTokens } — at the
message level. A per-block id has industry precedent; per-block time has none.
So this is a local measurement, and the shape says so. It stays typed — the bag is
where it belongs, opacity is not part of the deal — and it is namespaced under
aparte because meta is the consumer’s: a flat startedAt there would collide
with a key of their own.
Core reads it through segmentDuration and isSegmentSettled; it never renders either number.
Properties
Section titled “Properties”startedAt?
Section titled “startedAt?”optional startedAt?: number;Defined in: packages/core/src/types/segments.ts:95
Epoch ms when the segment entered a LIVE transcript. Absent for history.
endedAt?
Section titled “endedAt?”optional endedAt?: number;Defined in: packages/core/src/types/segments.ts:111
Epoch ms when content last arrived on this segment.
It ADVANCES while the segment streams and freezes when the segment settles, so
endedAt - startedAt is a live duration during a turn and a final one after it
— ask isSegmentSettled(segment) which you are looking at.
Why not simply “when it finished”: the two obvious rules are both wrong, and measurably. Closing at the end of the turn makes a reasoning block span the whole answer that followed it (2s of thinking before a 20s reply reads ”22s”). Closing when the next segment opens is the same error, smaller — a gap of ten seconds before the next segment is counted as thinking, while the person watching knows nothing happened. The last delta is the only moment the segment itself can vouch for.
AparteTextSegment
Section titled “AparteTextSegment”Defined in: packages/core/src/types/segments.ts:120
Text segment - plain text content
Example
Section titled “Example”{ id: 's1', type: 'text', content: 'A transport is the object that talks to the model.' }Extends
Section titled “Extends”Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/segments.ts:13
Unique segment identifier
Inherited from
Section titled “Inherited from”isStreaming?
Section titled “isStreaming?”optional isStreaming?: boolean;Defined in: packages/core/src/types/segments.ts:19
Whether segment is currently being streamed
Inherited from
Section titled “Inherited from”fallback?
Section titled “fallback?”optional fallback?: string;Defined in: packages/core/src/types/segments.ts:36
One sentence standing in for the segment when no renderer claims its type —
DRAWN for every type, not only for custom.
It is the answer to a real moment: a conversation replayed in another app, a
client that loads its views lazily, an export. Core draws it as text (no markup)
under .aparte-segment-fallback. Supplying one also silences the “no renderer”
developer warning: an author who wrote a fallback has already said this can happen.
In the HISTORY sent back to the model it stands in for the segment only where core
does not serialise the type itself — custom, and any type core does not know (a
registered block grammar’s, a plugin’s). A text or a code segment contributes
its content and nothing else; thinking and tool_call are left out of the history
on purpose (_segmentsToText in AparteClient states why), and so is error.
Inherited from
Section titled “Inherited from”messageId?
Section titled “messageId?”optional messageId?: string;Defined in: packages/core/src/types/segments.ts:55
Id of the message this segment belongs to. Stamped on insertion.
Inherited from
Section titled “Inherited from”index?
Section titled “index?”optional index?: number;Defined in: packages/core/src/types/segments.ts:61
Position in the owning message’s segments[], maintained across
insertions and removals.
Inherited from
Section titled “Inherited from”optional meta?: Record<string, unknown> & {
aparte?: AparteSegmentTiming;
};Defined in: packages/core/src/types/segments.ts:71
Extras the producer of the segment knows — token counts, cost, compute
device — plus aparte, the one sub-object core writes.
Everything except meta.aparte is yours: fill it with
updateSegment(segmentId, { meta }), which MERGES rather than replaces.
Mirrors AparteMessage.metadata.
Type Declaration
Section titled “Type Declaration”aparte?
Section titled “aparte?”optional aparte?: AparteSegmentTiming;Inherited from
Section titled “Inherited from”type: "text";Defined in: packages/core/src/types/segments.ts:121
Segment type discriminator
Overrides
Section titled “Overrides”content
Section titled “content”content: string;Defined in: packages/core/src/types/segments.ts:122
AparteThinkingSegment
Section titled “AparteThinkingSegment”Defined in: packages/core/src/types/segments.ts:155
Thinking/reasoning segment - collapsible.
A literal <think>…</think> in a reply is read as reasoning on every path — while
it streams and when the reply is restored from storage — so a message that merely
quotes the tag in its prose becomes this segment rather than text; and reasoning is
deliberately not sent back to the model, so those words leave the wire history with
it. Models whose reasoning is marked differently are handled by the parser’s
thinkingDelimiters.
Example
Section titled “Example”// No `collapsed` key, so it renders CLOSED — see the field's own note below.
{
id: 's1',
type: 'thinking',
label: 'Reasoning',
content: 'The question is about transports, so name the two and say where the key lives.',
}Extends
Section titled “Extends”Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/segments.ts:13
Unique segment identifier
Inherited from
Section titled “Inherited from”isStreaming?
Section titled “isStreaming?”optional isStreaming?: boolean;Defined in: packages/core/src/types/segments.ts:19
Whether segment is currently being streamed
Inherited from
Section titled “Inherited from”fallback?
Section titled “fallback?”optional fallback?: string;Defined in: packages/core/src/types/segments.ts:36
One sentence standing in for the segment when no renderer claims its type —
DRAWN for every type, not only for custom.
It is the answer to a real moment: a conversation replayed in another app, a
client that loads its views lazily, an export. Core draws it as text (no markup)
under .aparte-segment-fallback. Supplying one also silences the “no renderer”
developer warning: an author who wrote a fallback has already said this can happen.
In the HISTORY sent back to the model it stands in for the segment only where core
does not serialise the type itself — custom, and any type core does not know (a
registered block grammar’s, a plugin’s). A text or a code segment contributes
its content and nothing else; thinking and tool_call are left out of the history
on purpose (_segmentsToText in AparteClient states why), and so is error.
Inherited from
Section titled “Inherited from”messageId?
Section titled “messageId?”optional messageId?: string;Defined in: packages/core/src/types/segments.ts:55
Id of the message this segment belongs to. Stamped on insertion.
Inherited from
Section titled “Inherited from”index?
Section titled “index?”optional index?: number;Defined in: packages/core/src/types/segments.ts:61
Position in the owning message’s segments[], maintained across
insertions and removals.
Inherited from
Section titled “Inherited from”optional meta?: Record<string, unknown> & {
aparte?: AparteSegmentTiming;
};Defined in: packages/core/src/types/segments.ts:71
Extras the producer of the segment knows — token counts, cost, compute
device — plus aparte, the one sub-object core writes.
Everything except meta.aparte is yours: fill it with
updateSegment(segmentId, { meta }), which MERGES rather than replaces.
Mirrors AparteMessage.metadata.
Type Declaration
Section titled “Type Declaration”aparte?
Section titled “aparte?”optional aparte?: AparteSegmentTiming;Inherited from
Section titled “Inherited from”type: "thinking";Defined in: packages/core/src/types/segments.ts:156
Segment type discriminator
Overrides
Section titled “Overrides”content
Section titled “content”content: string;Defined in: packages/core/src/types/segments.ts:157
collapsed?
Section titled “collapsed?”optional collapsed?: boolean;Defined in: packages/core/src/types/segments.ts:170
Open the block. Absent means CLOSED — a reasoning block is a disclosure, and the reader opens it.
It used to be the other way round: absent meant open, and core’s own parser
emitted collapsed: false on every block it produced, so a reasoning block
stayed unfolded for the whole conversation and buried the answer under it. No
assistant on the market does that — the content is behind a click, streaming
or settled.
false is still how you open one on purpose. Only ABSENT changed meaning.
label?
Section titled “label?”optional label?: string;Defined in: packages/core/src/types/segments.ts:171
AparteCodeSegment
Section titled “AparteCodeSegment”Defined in: packages/core/src/types/segments.ts:189
Code segment - syntax highlighted code block
Highlighting is a plugin you opt into; with none installed the block renders plain, which is what core’s zero-dependency promise costs here.
Example
Section titled “Example”{
* id: 's1',
* type: 'code',
* language: 'ts',
* filename: 'transport.ts',
* content: "const transport = new AparteBackendTransport({ endpoint: '/api/chat' });",
* }Extends
Section titled “Extends”Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/segments.ts:13
Unique segment identifier
Inherited from
Section titled “Inherited from”isStreaming?
Section titled “isStreaming?”optional isStreaming?: boolean;Defined in: packages/core/src/types/segments.ts:19
Whether segment is currently being streamed
Inherited from
Section titled “Inherited from”fallback?
Section titled “fallback?”optional fallback?: string;Defined in: packages/core/src/types/segments.ts:36
One sentence standing in for the segment when no renderer claims its type —
DRAWN for every type, not only for custom.
It is the answer to a real moment: a conversation replayed in another app, a
client that loads its views lazily, an export. Core draws it as text (no markup)
under .aparte-segment-fallback. Supplying one also silences the “no renderer”
developer warning: an author who wrote a fallback has already said this can happen.
In the HISTORY sent back to the model it stands in for the segment only where core
does not serialise the type itself — custom, and any type core does not know (a
registered block grammar’s, a plugin’s). A text or a code segment contributes
its content and nothing else; thinking and tool_call are left out of the history
on purpose (_segmentsToText in AparteClient states why), and so is error.
Inherited from
Section titled “Inherited from”messageId?
Section titled “messageId?”optional messageId?: string;Defined in: packages/core/src/types/segments.ts:55
Id of the message this segment belongs to. Stamped on insertion.
Inherited from
Section titled “Inherited from”index?
Section titled “index?”optional index?: number;Defined in: packages/core/src/types/segments.ts:61
Position in the owning message’s segments[], maintained across
insertions and removals.
Inherited from
Section titled “Inherited from”optional meta?: Record<string, unknown> & {
aparte?: AparteSegmentTiming;
};Defined in: packages/core/src/types/segments.ts:71
Extras the producer of the segment knows — token counts, cost, compute
device — plus aparte, the one sub-object core writes.
Everything except meta.aparte is yours: fill it with
updateSegment(segmentId, { meta }), which MERGES rather than replaces.
Mirrors AparteMessage.metadata.
Type Declaration
Section titled “Type Declaration”aparte?
Section titled “aparte?”optional aparte?: AparteSegmentTiming;Inherited from
Section titled “Inherited from”type: "code";Defined in: packages/core/src/types/segments.ts:190
Segment type discriminator
Overrides
Section titled “Overrides”content
Section titled “content”content: string;Defined in: packages/core/src/types/segments.ts:191
language?
Section titled “language?”optional language?: string;Defined in: packages/core/src/types/segments.ts:192
filename?
Section titled “filename?”optional filename?: string;Defined in: packages/core/src/types/segments.ts:193
showLineNumbers?
Section titled “showLineNumbers?”optional showLineNumbers?: boolean;Defined in: packages/core/src/types/segments.ts:198
Deprecated
Section titled “Deprecated”Read by nothing: no renderer and no stylesheet draws line numbers, so setting it changes nothing. It will be removed in a later minor.
AparteErrorSegment
Section titled “AparteErrorSegment”Defined in: packages/core/src/types/segments.ts:215
Error segment
A failure card inside the turn that produced it, rather than a toast somewhere else on the page — so the reader can see which question failed.
Example
Section titled “Example”{
* id: 's1',
* type: 'error',
* content: 'The model did not answer.',
* details: 'HTTP 429 — rate limited. Retrying in 20s.',
* }Extends
Section titled “Extends”Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/segments.ts:13
Unique segment identifier
Inherited from
Section titled “Inherited from”isStreaming?
Section titled “isStreaming?”optional isStreaming?: boolean;Defined in: packages/core/src/types/segments.ts:19
Whether segment is currently being streamed
Inherited from
Section titled “Inherited from”fallback?
Section titled “fallback?”optional fallback?: string;Defined in: packages/core/src/types/segments.ts:36
One sentence standing in for the segment when no renderer claims its type —
DRAWN for every type, not only for custom.
It is the answer to a real moment: a conversation replayed in another app, a
client that loads its views lazily, an export. Core draws it as text (no markup)
under .aparte-segment-fallback. Supplying one also silences the “no renderer”
developer warning: an author who wrote a fallback has already said this can happen.
In the HISTORY sent back to the model it stands in for the segment only where core
does not serialise the type itself — custom, and any type core does not know (a
registered block grammar’s, a plugin’s). A text or a code segment contributes
its content and nothing else; thinking and tool_call are left out of the history
on purpose (_segmentsToText in AparteClient states why), and so is error.
Inherited from
Section titled “Inherited from”messageId?
Section titled “messageId?”optional messageId?: string;Defined in: packages/core/src/types/segments.ts:55
Id of the message this segment belongs to. Stamped on insertion.
Inherited from
Section titled “Inherited from”index?
Section titled “index?”optional index?: number;Defined in: packages/core/src/types/segments.ts:61
Position in the owning message’s segments[], maintained across
insertions and removals.
Inherited from
Section titled “Inherited from”optional meta?: Record<string, unknown> & {
aparte?: AparteSegmentTiming;
};Defined in: packages/core/src/types/segments.ts:71
Extras the producer of the segment knows — token counts, cost, compute
device — plus aparte, the one sub-object core writes.
Everything except meta.aparte is yours: fill it with
updateSegment(segmentId, { meta }), which MERGES rather than replaces.
Mirrors AparteMessage.metadata.
Type Declaration
Section titled “Type Declaration”aparte?
Section titled “aparte?”optional aparte?: AparteSegmentTiming;Inherited from
Section titled “Inherited from”type: "error";Defined in: packages/core/src/types/segments.ts:216
Segment type discriminator
Overrides
Section titled “Overrides”content
Section titled “content”content: string;Defined in: packages/core/src/types/segments.ts:217
details?
Section titled “details?”optional details?: string;Defined in: packages/core/src/types/segments.ts:218
stack?
Section titled “stack?”optional stack?: string;Defined in: packages/core/src/types/segments.ts:223
Deprecated
Section titled “Deprecated”Set by nothing and read by nothing: the error renderer draws content and
details only. Put a stack in details to show it. It will be removed in a later minor.
AparteToolCallSegment
Section titled “AparteToolCallSegment”Defined in: packages/core/src/types/segments.ts:238
Tool call segment - rendered while waiting for a tool handler to resolve
Example
Section titled “Example”{
* id: 's1',
* type: 'tool_call',
* status: 'resolved',
* toolCall: { id: 'call_1', name: 'get_weather', input: { city: 'Lille' } },
* result: '11°C, overcast.',
* }Extends
Section titled “Extends”Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/segments.ts:13
Unique segment identifier
Inherited from
Section titled “Inherited from”isStreaming?
Section titled “isStreaming?”optional isStreaming?: boolean;Defined in: packages/core/src/types/segments.ts:19
Whether segment is currently being streamed
Inherited from
Section titled “Inherited from”fallback?
Section titled “fallback?”optional fallback?: string;Defined in: packages/core/src/types/segments.ts:36
One sentence standing in for the segment when no renderer claims its type —
DRAWN for every type, not only for custom.
It is the answer to a real moment: a conversation replayed in another app, a
client that loads its views lazily, an export. Core draws it as text (no markup)
under .aparte-segment-fallback. Supplying one also silences the “no renderer”
developer warning: an author who wrote a fallback has already said this can happen.
In the HISTORY sent back to the model it stands in for the segment only where core
does not serialise the type itself — custom, and any type core does not know (a
registered block grammar’s, a plugin’s). A text or a code segment contributes
its content and nothing else; thinking and tool_call are left out of the history
on purpose (_segmentsToText in AparteClient states why), and so is error.
Inherited from
Section titled “Inherited from”messageId?
Section titled “messageId?”optional messageId?: string;Defined in: packages/core/src/types/segments.ts:55
Id of the message this segment belongs to. Stamped on insertion.
Inherited from
Section titled “Inherited from”index?
Section titled “index?”optional index?: number;Defined in: packages/core/src/types/segments.ts:61
Position in the owning message’s segments[], maintained across
insertions and removals.
Inherited from
Section titled “Inherited from”optional meta?: Record<string, unknown> & {
aparte?: AparteSegmentTiming;
};Defined in: packages/core/src/types/segments.ts:71
Extras the producer of the segment knows — token counts, cost, compute
device — plus aparte, the one sub-object core writes.
Everything except meta.aparte is yours: fill it with
updateSegment(segmentId, { meta }), which MERGES rather than replaces.
Mirrors AparteMessage.metadata.
Type Declaration
Section titled “Type Declaration”aparte?
Section titled “aparte?”optional aparte?: AparteSegmentTiming;Inherited from
Section titled “Inherited from”type: "tool_call";Defined in: packages/core/src/types/segments.ts:239
Segment type discriminator
Overrides
Section titled “Overrides”toolCall
Section titled “toolCall”toolCall: AparteToolCall;Defined in: packages/core/src/types/segments.ts:240
status
Section titled “status”status:
| "pending"
| "resolved"
| "aborted"
| "awaiting-approval"
| "rejected"
| "failed";Defined in: packages/core/src/types/segments.ts:246
awaiting-approval — paused for a human decision; rejected — the human (or a
policy) declined to run it; aborted — stopped, timed out, or nothing could run
it; failed — the handler threw, and result carries the crash’s one line.
result?
Section titled “result?”optional result?: string;Defined in: packages/core/src/types/segments.ts:247
structuredResult?
Section titled “structuredResult?”optional structuredResult?: unknown;Defined in: packages/core/src/types/segments.ts:249
The handler’s structuredContent, when it returned one — the value behind result’s prose.
deferred?
Section titled “deferred?”optional deferred?: {
reason: "approval" | "external" | "queued";
ticket?: string;
};Defined in: packages/core/src/types/segments.ts:257
Set when a server loop (createAparteAgentHandler) suspended its run on this call:
why it waits — a person’s decision (approval), a tool the page runs
(external), or nothing but its turn (queued) — and the server’s signed
continuation. Saved with the conversation, so a reload can still answer it
(AparteClient.resumeDeferred).
reason
Section titled “reason”reason: "approval" | "external" | "queued";ticket?
Section titled “ticket?”optional ticket?: string;AparteCustomSegment
Section titled “AparteCustomSegment”Defined in: packages/core/src/types/segments.ts:296
Custom segment - one escape hatch for the views an app draws itself.
Renderers are keyed on type, so subType never reaches the registry: you
register ONE renderer for custom and switch on subType inside it, with fallback
as the default branch. Independent views take their own type instead — register a
chart renderer for a chart — and custom is for a family of small views an app
would rather keep behind one key.
Example
Section titled “Example”registerSegmentRenderer<AparteCustomSegment>({
type: 'custom',
render(segment) {
const data = (segment.data ?? {}) as Record<string, unknown>;
const el = document.createElement('div');
switch (segment.subType) {
case 'weather':
el.className = 'weather';
el.textContent = `${data['city']} — ${data['celsius']}°C`;
break;
case 'poll':
el.className = 'poll';
el.textContent = String(data['question']);
break;
default:
// A subType this build does not know: the sentence, not nothing.
el.textContent = segment.fallback ?? '';
}
return el;
},
});
// The segments that renderer draws:
{ id: 's1', type: 'custom', subType: 'weather', data: { city: 'Lille', celsius: 11 } }
{ id: 's2', type: 'custom', subType: 'gantt', fallback: 'Three tasks, ending Friday.' }Extends
Section titled “Extends”Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/segments.ts:13
Unique segment identifier
Inherited from
Section titled “Inherited from”isStreaming?
Section titled “isStreaming?”optional isStreaming?: boolean;Defined in: packages/core/src/types/segments.ts:19
Whether segment is currently being streamed
Inherited from
Section titled “Inherited from”fallback?
Section titled “fallback?”optional fallback?: string;Defined in: packages/core/src/types/segments.ts:36
One sentence standing in for the segment when no renderer claims its type —
DRAWN for every type, not only for custom.
It is the answer to a real moment: a conversation replayed in another app, a
client that loads its views lazily, an export. Core draws it as text (no markup)
under .aparte-segment-fallback. Supplying one also silences the “no renderer”
developer warning: an author who wrote a fallback has already said this can happen.
In the HISTORY sent back to the model it stands in for the segment only where core
does not serialise the type itself — custom, and any type core does not know (a
registered block grammar’s, a plugin’s). A text or a code segment contributes
its content and nothing else; thinking and tool_call are left out of the history
on purpose (_segmentsToText in AparteClient states why), and so is error.
Inherited from
Section titled “Inherited from”messageId?
Section titled “messageId?”optional messageId?: string;Defined in: packages/core/src/types/segments.ts:55
Id of the message this segment belongs to. Stamped on insertion.
Inherited from
Section titled “Inherited from”index?
Section titled “index?”optional index?: number;Defined in: packages/core/src/types/segments.ts:61
Position in the owning message’s segments[], maintained across
insertions and removals.
Inherited from
Section titled “Inherited from”optional meta?: Record<string, unknown> & {
aparte?: AparteSegmentTiming;
};Defined in: packages/core/src/types/segments.ts:71
Extras the producer of the segment knows — token counts, cost, compute
device — plus aparte, the one sub-object core writes.
Everything except meta.aparte is yours: fill it with
updateSegment(segmentId, { meta }), which MERGES rather than replaces.
Mirrors AparteMessage.metadata.
Type Declaration
Section titled “Type Declaration”aparte?
Section titled “aparte?”optional aparte?: AparteSegmentTiming;Inherited from
Section titled “Inherited from”type: "custom";Defined in: packages/core/src/types/segments.ts:297
Segment type discriminator
Overrides
Section titled “Overrides”subType
Section titled “subType”subType: string;Defined in: packages/core/src/types/segments.ts:299
Which view inside the custom renderer draws this segment (e.g. ‘weather’, ‘poll’, ‘onboarding’).
optional data?: unknown;Defined in: packages/core/src/types/segments.ts:301
Arbitrary data payload for the component
AparteSegmentRenderer
Section titled “AparteSegmentRenderer”Defined in: packages/core/src/types/segments.ts:333
Segment renderer interface for custom segment types Implement this to add new segment renderers
Type Parameters
Section titled “Type Parameters”| Type Parameter | Default type |
|---|---|
T extends AparteSegmentBase | AparteSegmentBase |
Properties
Section titled “Properties”type: string;Defined in: packages/core/src/types/segments.ts:335
Segment type this renderer handles
Methods
Section titled “Methods”render()
Section titled “render()”render(segment): string | HTMLElement;Defined in: packages/core/src/types/segments.ts:351
Render a segment to either an HTML string or a ready DOM element.
Return a string for simple markup (inserted via innerHTML) — the built-in
renderers do this. Return an HTMLElement to skip innerHTML entirely: you
can attach event listeners and framework nodes directly, and there is no
innerHTML XSS surface for values you interpolate. Either way, setup() (if
provided) runs afterwards with the resulting element. For in-place streaming
updates to find your element, keep a data-segment-id="<segment.id>" on its
root (or implement update()).
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
segment | T | Segment data to render |
Returns
Section titled “Returns”string | HTMLElement
HTML string or a DOM element
getStyles()?
Section titled “getStyles()?”optional getStyles(): string;Defined in: packages/core/src/types/segments.ts:357
Optional: Get CSS styles for this segment type
Returns
Section titled “Returns”string
CSS string to inject
setup()?
Section titled “setup()?”optional setup(element, segment): void;Defined in: packages/core/src/types/segments.ts:364
Optional: Setup interactivity after render
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
element | HTMLElement | The rendered DOM element |
segment | T | Segment data |
Returns
Section titled “Returns”void
update()?
Section titled “update()?”optional update(element, segment): void;Defined in: packages/core/src/types/segments.ts:372
Optional: In-place DOM update during streaming. When provided, called instead of re-rendering the full element. Must not add/remove child nodes — only mutate attributes or textContent so the MutationObserver (childList) doesn’t fire and scroll stays stable.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
element | HTMLElement |
segment | T |
Returns
Section titled “Returns”void
relabel()?
Section titled “relabel()?”optional relabel(element, segment): void;Defined in: packages/core/src/types/segments.ts:396
Optional: re-read the CONFIG-DERIVED text of an already-rendered segment — an icon from the icon provider, a label from the locale.
Called when the config changes (a language switch, a new icon set), on every
segment already on screen. Bound by the same rule as update(): must not
add or remove child nodes — only attributes and textContent — so the
viewport’s childList observer stays quiet and scroll does not move.
This exists because the obvious alternative does not work. Re-rendering the
segments container to pick up a new locale destroys state the DOM owns and the
segment data does not: a mounted sandboxed artifact preview, a reasoning block
the reader expanded by clicking <summary> (which never writes back to
collapsed), scroll position inside a long terminal, the focus on an
Approve/Reject gate, and the buffered lookahead of the incremental Markdown
parser mid-stream. It also fires container-wide childList mutations, which is
exactly what the rule above forbids.
Implement it only if the rendered output contains text or icons that came from
the config. A renderer whose chrome is entirely its own data — progress,
text — correctly does not, exactly as it does not implement update().
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
element | HTMLElement |
segment | T |
Returns
Section titled “Returns”void
cleanup()?
Section titled “cleanup()?”optional cleanup(element): void;Defined in: packages/core/src/types/segments.ts:402
Optional: Cleanup when segment is removed
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
element | HTMLElement | The DOM element being removed |
Returns
Section titled “Returns”void
AparteSegmentUpdateEventDetail
Section titled “AparteSegmentUpdateEventDetail”Defined in: packages/core/src/types/segments.ts:410
Event when segment content is updated during streaming
Properties
Section titled “Properties”messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/segments.ts:411
segmentId
Section titled “segmentId”segmentId: string;Defined in: packages/core/src/types/segments.ts:412
content
Section titled “content”content: string;Defined in: packages/core/src/types/segments.ts:413
append?
Section titled “append?”optional append?: boolean;Defined in: packages/core/src/types/segments.ts:414
AparteStreamBlockMatch
Section titled “AparteStreamBlockMatch”Defined in: packages/core/src/types/stream-blocks.ts:24
What the parser hands to AparteStreamBlock.toSegment when a block opens.
Properties
Section titled “Properties”attrs: Record<string, string>;Defined in: packages/core/src/types/stream-blocks.ts:30
The opening tag’s attributes, as written: type="text/html", title='Notes'
and lang=fr all parse; the values are verbatim, never trimmed or decoded.
The model wrote them — treat them as untrusted, like every segment field.
id: string;Defined in: packages/core/src/types/stream-blocks.ts:32
The id the parser generated for the segment (its usual prefix + uuid).
AparteStreamBlock
Section titled “AparteStreamBlock”Defined in: packages/core/src/types/stream-blocks.ts:45
A block grammar: the tag, and the segment its body becomes.
The parser owns everything after toSegment returns: it appends each delta
to segment.content, sets isStreaming while the block is open and clears it at
</tag> (or at the end of the stream). So the segment MUST carry a content
string — the one field core touches — and the rest of its shape is yours:
a type of your own, registered with registerSegmentRenderer, or a built-in
one if the block is merely another way of spelling it.
Properties
Section titled “Properties”tag: string;Defined in: packages/core/src/types/stream-blocks.ts:51
The tag name without brackets: artifact recognises <artifact …> … </artifact>.
Matched exactly and case-sensitively, and only as a whole name — <artifacts>
does not open an artifact block. Letters, digits, - and _.
toSegment
Section titled “toSegment”toSegment: (match) => AparteSegmentBase & {
content: string;
};Defined in: packages/core/src/types/stream-blocks.ts:56
Build the segment at the opening tag, with an empty content. Called once per
block; the parser fills the body in afterwards.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
match | AparteStreamBlockMatch |
Returns
Section titled “Returns”AparteSegmentBase & {
content: string;
}
AparteTool
Section titled “AparteTool”Defined in: packages/core/src/types/tools.ts:9
Definition of a tool the AI can call
Properties
Section titled “Properties”name: string;Defined in: packages/core/src/types/tools.ts:10
description
Section titled “description”description: string;Defined in: packages/core/src/types/tools.ts:11
inputSchema
Section titled “inputSchema”inputSchema: Record<string, unknown>;Defined in: packages/core/src/types/tools.ts:13
JSON Schema object describing the tool’s input parameters
systemPrompt?
Section titled “systemPrompt?”optional systemPrompt?: string;Defined in: packages/core/src/types/tools.ts:15
System prompt injected automatically when this tool is registered — tells the AI when and why to use it
maxTurns?
Section titled “maxTurns?”optional maxTurns?: number;Defined in: packages/core/src/types/tools.ts:20
Maximum number of agentic loop turns before aborting.
Overrides the global maxTurns in AparteClientOptions for this specific tool.
needsApproval?
Section titled “needsApproval?”optional needsApproval?: boolean;Defined in: packages/core/src/types/tools.ts:39
When true, the agent loop pauses before running this tool’s handler and waits for a human decision — “human in the loop”.
The decision is asked AT THE COMPOSER, through the same requestUserInput
a tool handler calls: every request for the user is answered in one place.
The row in the transcript is the anchor, naming which tool is waiting, and
holds nothing clickable. An approvalResolver on AparteClientOptions
answers it programmatically instead.
On a refusal the rest of the turn is skipped — no later tool call of the same turn runs — and then the model gets a turn to answer it, so it can say what it will do instead. The refusal may carry the user’s own words.
All three clauses of this comment used to say something else: the default
renderer surfaced the buttons, an aparte-tool-decision event resolved
them, and a refusal ended the turn. None of that is true any more.
AparteToolCall
Section titled “AparteToolCall”Defined in: packages/core/src/types/tools.ts:65
A tool call emitted by the AI during streaming
Properties
Section titled “Properties”id: string;Defined in: packages/core/src/types/tools.ts:66
name: string;Defined in: packages/core/src/types/tools.ts:67
input: Record<string, unknown>;Defined in: packages/core/src/types/tools.ts:68
AparteApprovalRuling
Section titled “AparteApprovalRuling”Defined in: packages/core/src/types/tools.ts:79
What an approval policy says about one call.
allow runs it without asking; ask puts it to the person the way a
needsApproval tool is put to them; deny refuses it on the spot, and reason is
the sentence the model reads about that refusal — verbatim, because nobody said
anything (“Plan mode: write_file changes files; only read-only tools run.”).
Properties
Section titled “Properties”verdict
Section titled “verdict”verdict: "allow" | "ask" | "deny";Defined in: packages/core/src/types/tools.ts:80
reason?
Section titled “reason?”optional reason?: string;Defined in: packages/core/src/types/tools.ts:81
AparteToolResult
Section titled “AparteToolResult”Defined in: packages/core/src/types/tools.ts:103
Result returned after a tool handler resolves
Properties
Section titled “Properties”toolCallId
Section titled “toolCallId”toolCallId: string;Defined in: packages/core/src/types/tools.ts:104
content
Section titled “content”content: string;Defined in: packages/core/src/types/tools.ts:106
What the model reads.
structuredContent?
Section titled “structuredContent?”optional structuredContent?: unknown;Defined in: packages/core/src/types/tools.ts:113
The same result as a value, for a renderer or the host — MCP’s name for exactly
this field, beside content. Optional and additive: a handler that returns prose
alone behaves as before, and the model never sees this. It lands on the
transcript’s segment as AparteToolCallSegment.structuredResult.
AparteToolContext
Section titled “AparteToolContext”Defined in: packages/core/src/types/tools.ts:147
Which chat a tool handler is running for.
Optional and third, so every existing handler keeps compiling and working — nothing has to be rewritten to ignore it.
It exists because a handler had NO way to know. @aparte/plugin-ask-user
calls requestUserInput({ message, schema, signal }) with no target, and
requestUserInput resolves its presenter with resolveConfig(request.target ?? null) — so with an instance config carrying the presenter, the call resolved
against the GLOBAL config, found nothing, and returned { action: 'cancel' }.
The model was told the user refused a question the user was never shown.
That failure is described in AparteConfig.requestUserInput as “a lie told
quietly”, and the plugin walked straight into it because the handler signature
gave it nothing to walk around with.
The loop supplies it — runStreamAgent, or the runner you injected — so
a handler behaves the same whichever one is running.
Properties
Section titled “Properties”request?
Section titled “request?”optional request?: Request;Defined in: packages/core/src/types/tools.ts:153
On the server (createAparteAgentHandler): the request being served — the one that
started the run, or, for a call answered after a pause, the one that resumed it — for
a tool that checks who is calling. The model chose the arguments, not the caller.
target?
Section titled “target?”optional target?: HTMLElement;Defined in: packages/core/src/types/tools.ts:159
The chat element this turn belongs to. Pass it as target to
requestUserInput (or to anything else that resolves a config from the DOM)
and the right instance answers.
config?
Section titled “config?”optional config?: unknown;Defined in: packages/core/src/types/tools.ts:164
The resolved config for this chat, for a handler that needs it without going through the DOM — a handler running in a worker, or one reading a provider.
AparteToolRenderer
Section titled “AparteToolRenderer”Defined in: packages/core/src/types/tools.ts:190
Per-tool segment renderer. Registered via aparteGlobalConfig.registerToolRenderer(toolName, renderer). When the AI calls a tool, this renderer controls what appears in the bubble for that specific tool instead of the generic tool_call renderer.
Return an empty string from render() to render nothing (e.g. for UI-only tools like ask_user).
Properties
Section titled “Properties”render
Section titled “render”render: (segment) => string | HTMLElement;Defined in: packages/core/src/types/tools.ts:221
Render the tool-call segment, as an HTML string or a ready DOM element.
The segment carries model-chosen data. segment.toolCall.input is
whatever the model decided to pass, and segment.result is whatever the tool
returned — on the SEGMENT, because AparteToolCall is { id, name, input }
and nothing else. This line used to say segment.toolCall.result, which does
not compile; the first renderer written against it found out.
Both values are untrusted.
Return an HTMLElement and there is no innerHTML surface at all — set
textContent, attach listeners, insert framework nodes. That is the safe
default and the reason this arm exists.
Return a string and core inserts it with innerHTML, so every
interpolated value must go through escapeHtml (text position) or
escapeAttr (inside an attribute). The natural first thing to write here is
`<div>Searching for ${s.toolCall.input.query}</div>`, and that is a direct
model-to-DOM XSS in the host page’s origin.
Return an empty string to render nothing (e.g. a UI-only tool like
ask_user).
The root you return is the segment’s element in the bubble: core stamps
data-segment-id="<segment.id>" on it if you did not, so an update to the
call (its result landing, an approval decision) is patched into that element
rather than rebuilding every segment of the bubble — a rebuild destroys a
mounted artifact preview, collapses an opened reasoning block and drops the
focus. Keep your markup’s root a single element for that reason.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
segment | AparteToolCallSegment |
Returns
Section titled “Returns”string | HTMLElement
setup?
Section titled “setup?”optional setup?: (element, segment) => void;Defined in: packages/core/src/types/tools.ts:223
Optional DOM setup (event listeners etc.) called after HTML is injected
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
element | HTMLElement |
segment | AparteToolCallSegment |
Returns
Section titled “Returns”void
update?
Section titled “update?”optional update?: (element, segment) => void;Defined in: packages/core/src/types/tools.ts:232
Patch the element in place when the call changes — its result landing, an
approval decided, a failed status. Without it core rebuilds your markup from
render() on every change, which is right for a receipt and wrong for anything
with state: a mounted preview, an opened disclosure, a focused control are all
lost in a rebuild. Same contract as AparteSegmentRenderer.update: never
re-render, never touch what the reader opened.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
element | HTMLElement |
segment | AparteToolCallSegment |
Returns
Section titled “Returns”void
relabel?
Section titled “relabel?”optional relabel?: (element, segment) => void;Defined in: packages/core/src/types/tools.ts:239
Re-read the locale and the icon provider without touching the DOM shape —
called on every config change (setLocale, setIconProvider, reset()), for
as long as the element is on the page. Add or remove no child node; replace
text and glyphs only.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
element | HTMLElement |
segment | AparteToolCallSegment |
Returns
Section titled “Returns”void
getStyles?
Section titled “getStyles?”optional getStyles?: () => string;Defined in: packages/core/src/types/tools.ts:241
Optional CSS to inject once into document.head
Returns
Section titled “Returns”string
Type Aliases
Section titled “Type Aliases”AparteContentPart
Section titled “AparteContentPart”type AparteContentPart =
| AparteTextPart
| AparteImagePart;Defined in: packages/core/src/types/chat.ts:38
Discriminated union of all content part types.
There was a third, AparteFilePart, “reserved for future PDF/audio support” — nothing
ever produced one: the client inlines images and text files and drops the rest, and both
wire mappers answered it with an empty text part no message could reach. What it did do
was promise a consumer that attaching a PDF sent it. That promise is now a warning at the
one place the file is really dropped.
AparteStreamEvent
Section titled “AparteStreamEvent”type AparteStreamEvent = { [K in keyof AparteStreamEventMap]: { type: K } & AparteStreamEventMap[K] }[keyof AparteStreamEventMap];Defined in: packages/core/src/types/chat.ts:214
Discriminated union derived from AparteStreamEventMap — stays in sync automatically.
AparteChatResponse
Section titled “AparteChatResponse”type AparteChatResponse = ReadableStream<AparteStreamEvent> | string;Defined in: packages/core/src/types/chat.ts:218
AparteAttrValue
Section titled “AparteAttrValue”type AparteAttrValue<T> = T extends boolean ? "" | null | undefined : T extends number ? number | string : T;Defined in: packages/core/src/types/element-attributes.ts:44
One attribute as a TEMPLATE must write it.
A presence attribute becomes '' | undefined, never boolean, and that is not
pedantry — it is the same trap in all three template languages. React and Vue
stringify what they set on a custom element, so disabled={false} renders
disabled="false", and an element that tests hasAttribute reads that as ON. The
wrapper’s own bubble rendering already used the right spelling
(streaming={… ? '' : undefined}); this makes it the only one that type-checks.
Svelte 5 is the caveat that shaped the SETTERS (#62): it assigns the PROPERTY
whenever the element has a setter for it (set_custom_element_data checks
get_setters(node)), so an accessor-backed presence attribute receives the ''
this union promises as a property value. Every presence setter therefore treats
'' as ON (presenceOn in utils/presence.ts) — one spelling, both paths.
null is in the union alongside undefined because all three treat it as REMOVE,
and Vue’s own wrapper template writes exactly that (:streaming="… ? '' : null").
Leaving it out made the wrapper’s own code fail to type-check — the second time the
existing wrappers corrected a declaration here, after timestamp, which the React
bubble rendering proved accepts a number.
A numeric attribute takes a number or the string it becomes, because both read naturally in a template.
Angular does NOT use this: its directives take boolean through booleanAttribute
and write the attribute themselves, so a consumer there writes [disabled]="busy".
That difference is the whole reason this is a mapping and not the declared type.
Type Parameters
Section titled “Type Parameters”| Type Parameter |
|---|
T |
AparteTemplateAttrs
Section titled “AparteTemplateAttrs”type AparteTemplateAttrs<T> = { [K in keyof T]?: AparteAttrValue<NonNullable<T[K]>> };Defined in: packages/core/src/types/element-attributes.ts:49
An element’s attribute surface, in template spelling. Used by three of four wrappers.
Type Parameters
Section titled “Type Parameters”| Type Parameter |
|---|
T |
ModelStatus
Section titled “ModelStatus”type ModelStatus = "ready" | "cached" | "not-downloaded";Defined in: packages/core/src/types/model-provider.ts:66
Availability status of a model, as reported by the provider.
Provider-agnostic: Transformers.js checks the Cache API, Ollama checks pulled models, LM Studio checks VRAM, etc.
AparteAIProvider
Section titled “AparteAIProvider”type AparteAIProvider =
| AparteAIProviderCore & AparteAIProviderFormat & AparteAIProviderAuth & Partial<AparteAIProviderChat>
| AparteAIProviderCore & AparteAIProviderChat & Partial<AparteAIProviderFormat> & AparteAIProviderAuthMembers;Defined in: packages/core/src/types/model-provider.ts:310
An AI provider (e.g. OpenRouter, OpenAI, Transformers.js).
A union, not one interface, because there are two mutually sufficient ways
to be a provider and the compiler should say which one you implemented. It used
to be a single interface with three required members and fifteen optional ones,
discriminated at RUNTIME by isFormatAdapter() — so { id, getMetadata, getModels } typechecked, registered, and then failed on the first message with
nothing at build time to warn you.
Every member of both surfaces stays reachable on the union (optional on the arm
that does not require it), so runtime probes like typeof p.buildRequest === 'function' and isFormatAdapter() narrowing keep working unchanged. A provider
implementing both surfaces is valid and satisfies the format arm.
Examples
Section titled “Examples”A format adapter — a transport does the call
const provider: AparteAIProvider = {
id: 'openrouter',
getMetadata: () => ({ name: 'OpenRouter', id: 'openrouter', icon: '<svg/>', color: '#000' }),
getModels: () => [],
defaultEndpoint: 'https://openrouter.ai/api/v1',
buildRequest: (req) => ({ path: '/chat/completions', body: req }),
authHeaders: (key) => ({ Authorization: `Bearer ${key}` }),
parseStream: (body) => body as unknown as ReadableStream<AparteStreamEvent>,
};A provider owning its own I/O
const local: AparteAIProvider = {
id: 'transformers',
getMetadata: () => ({ name: 'Transformers.js', id: 'transformers', icon: '<svg/>', color: '#000' }),
getModels: () => [],
chat: async (request) => runLocally(request),
};AparteStatus
Section titled “AparteStatus”type AparteStatus = "idle" | "pending" | "streaming" | "completed" | "error" | "success";Defined in: packages/core/src/types/models.ts:17
Generic status type for flow management Used to drive loading indicators, error states, and transitions without coupling to any specific data source
AparteBubbleRole
Section titled “AparteBubbleRole”type AparteBubbleRole = "user" | "assistant";Defined in: packages/core/src/types/models.ts:24
Role of a message sender in the conversation
AparteBubbleActionName
Section titled “AparteBubbleActionName”type AparteBubbleActionName = "copy" | "edit" | "retry" | "thumbUp" | "thumbDown" | "info";Defined in: packages/core/src/types/models.ts:103
Names of the individual action-bar buttons, used for explicit per-role
ordered configuration (see AparteBubbleActionsConfig.user / .assistant).
AparteSegmentDefaults
Section titled “AparteSegmentDefaults”type AparteSegmentDefaults = Readonly<Record<string, unknown>>;Defined in: packages/core/src/types/segments.ts:134
Field defaults for one segment TYPE, merged when a segment enters a message.
A record and not a Partial<AparteSegment> on purpose: the type key is a string,
a consumer’s own segment type is as valid as a built-in one, and its fields cannot
be known here. What CANNOT be defaulted is identity — id, type, messageId,
index, startedAt, endedAt are refused, because a default id would give
every segment in a conversation the same one.
AparteSegment
Section titled “AparteSegment”type AparteSegment =
| AparteTextSegment
| AparteThinkingSegment
| AparteCodeSegment
| AparteErrorSegment
| AparteCustomSegment
| AparteToolCallSegment;Defined in: packages/core/src/types/segments.ts:314
All built-in segment types. An artifact is not one of them any more: it is a
convention an app teaches its model, and @aparte/plugin-artifacts registers its
segment — a type of its own, through registerSegmentRenderer and
registerStreamBlock — the way any consumer registers a chart or a citation.
AparteSegmentType
Section titled “AparteSegmentType”type AparteSegmentType = AparteSegment["type"];Defined in: packages/core/src/types/segments.ts:323
Segment type discriminator values
AparteThemeVariables
Section titled “AparteThemeVariables”type AparteThemeVariables = { [K in `--aparte-${string}`]?: string };Defined in: packages/core/src/types/theming.ts:34
Any aparté CSS custom property, for typing a theme object or a style record:
const brand: AparteThemeVariables = {
'--aparte-primary': '#b45309',
'--aparte-surface-1': '#ffffff',
};This was a hand-written list of 33 named properties, and it could not work. Ten of the 33 named variables were neither declared nor read anywhere in aparté — so the type autocompleted ten knobs that did nothing — while the real surface is 254 tokens, meaning even the 23 live members were an arbitrary slice presented as the whole. A hand-maintained mirror of a stylesheet that size is wrong the day after it is written, and nothing could tell you.
What this trades away, stated rather than glossed: autocomplete, and catching a
typo in the part after --aparte-. What it buys is that the type cannot lie. The
discoverable list is the generated
CSS variables reference, which
is swept from the source on every build and marks which tokens aparté actually
reads.
AparteApprovalPolicy
Section titled “AparteApprovalPolicy”type AparteApprovalPolicy = (call, tool) => AparteApprovalRuling | undefined;Defined in: packages/core/src/types/tools.ts:97
Decides, per CALL, whether a tool runs, asks, or is refused.
A tool’s own needsApproval is a declaration about the tool; a policy is a decision
about the call — the same run_command can be a read (ls) or an execution, and a
mode (“plan”: read-only, “auto”: never ask) is a policy the host switches, not a
flag on twenty definitions. Registered with setApprovalPolicy(); the client’s
default approval channel consults it before asking. Return undefined to have no
opinion, in which case the tool’s needsApproval decides as before.
Pure and synchronous: it is evaluated once to decide whether the call pauses at all (so an allowed call never flashes “awaiting approval”) and once to answer.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
call | AparteToolCall |
tool | AparteTool | undefined |
Returns
Section titled “Returns”AparteApprovalRuling | undefined
AparteToolHandler
Section titled “AparteToolHandler”type AparteToolHandler = (call, signal, context?) => Promise<AparteToolResult>;Defined in: packages/core/src/types/tools.ts:121
Handler function for a registered tool. Receives the tool call and an AbortSignal (fires after timeout or on cancellation). Must resolve with a AparteToolResult.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
call | AparteToolCall |
signal | AbortSignal |
context? | AparteToolContext |
Returns
Section titled “Returns”Promise<AparteToolResult>
AparteToolSummary
Section titled “AparteToolSummary”type AparteToolSummary = (segment) => string;Defined in: packages/core/src/types/tools.ts:180
What a call targets, in one line: the text the DEFAULT tool row shows after the
tool’s name — read_file skills.json rather than read_file alone.
Registered via aparteGlobalConfig.registerToolSummary(toolName, summary).
The name says which tool ran; this says to what, without opening the disclosure.
The row, its states and its disclosure stay core’s, so a host that only wants that
one line does not re-implement them in an AparteToolRenderer.
Return plain text: it is written as text, never parsed as HTML. Return '' to show
nothing. segment.toolCall.input is whatever the model chose, so read it
defensively — a summary that throws shows nothing rather than breaking the row.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
segment | AparteToolCallSegment |
Returns
Section titled “Returns”string
Enumerations
Section titled “Enumerations”AparteErrorCode
Section titled “AparteErrorCode”Defined in: packages/core/src/types/errors.ts:2
Enumeration Members
Section titled “Enumeration Members”CONFIG_NO_PROVIDER
Section titled “CONFIG_NO_PROVIDER”CONFIG_NO_PROVIDER: "CONFIG_NO_PROVIDER";Defined in: packages/core/src/types/errors.ts:4
CONFIG_MISSING_KEY
Section titled “CONFIG_MISSING_KEY”CONFIG_MISSING_KEY: "CONFIG_MISSING_KEY";Defined in: packages/core/src/types/errors.ts:5
CONFIG_INVALID_KEY
Section titled “CONFIG_INVALID_KEY”CONFIG_INVALID_KEY: "CONFIG_INVALID_KEY";Defined in: packages/core/src/types/errors.ts:6
CONFIG_INVALID_MODEL
Section titled “CONFIG_INVALID_MODEL”CONFIG_INVALID_MODEL: "CONFIG_INVALID_MODEL";Defined in: packages/core/src/types/errors.ts:7
USAGE_RATE_LIMIT
Section titled “USAGE_RATE_LIMIT”USAGE_RATE_LIMIT: "USAGE_RATE_LIMIT";Defined in: packages/core/src/types/errors.ts:10
USAGE_CONTEXT_EXCEEDED
Section titled “USAGE_CONTEXT_EXCEEDED”USAGE_CONTEXT_EXCEEDED: "USAGE_CONTEXT_EXCEEDED";Defined in: packages/core/src/types/errors.ts:11
USAGE_BAD_REQUEST
Section titled “USAGE_BAD_REQUEST”USAGE_BAD_REQUEST: "USAGE_BAD_REQUEST";Defined in: packages/core/src/types/errors.ts:12
NET_OFFLINE
Section titled “NET_OFFLINE”NET_OFFLINE: "NET_OFFLINE";Defined in: packages/core/src/types/errors.ts:15
NET_TIMEOUT
Section titled “NET_TIMEOUT”NET_TIMEOUT: "NET_TIMEOUT";Defined in: packages/core/src/types/errors.ts:16
NET_ERROR
Section titled “NET_ERROR”NET_ERROR: "NET_ERROR";Defined in: packages/core/src/types/errors.ts:17
PROVIDER_ERROR
Section titled “PROVIDER_ERROR”PROVIDER_ERROR: "PROVIDER_ERROR";Defined in: packages/core/src/types/errors.ts:20
PROVIDER_UNAVAILABLE
Section titled “PROVIDER_UNAVAILABLE”PROVIDER_UNAVAILABLE: "PROVIDER_UNAVAILABLE";Defined in: packages/core/src/types/errors.ts:21
PROVIDER_POLICY
Section titled “PROVIDER_POLICY”PROVIDER_POLICY: "PROVIDER_POLICY";Defined in: packages/core/src/types/errors.ts:22
UNKNOWN_ERROR
Section titled “UNKNOWN_ERROR”UNKNOWN_ERROR: "UNKNOWN_ERROR";Defined in: packages/core/src/types/errors.ts:25
Event details
Section titled “Event details”AparteMessageDoneEventDetail
Section titled “AparteMessageDoneEventDetail”Defined in: packages/core/src/types/events.ts:66
Detail payload for aparte-message-done.
Dispatched when a turn finishes normally. Carries token usage when the provider
reports it.
aparte-message-done
Properties
Section titled “Properties”targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:75
Id of the <aparte-chat> host that produced this turn, when it has one.
Stamped by the client’s lifecycle dispatcher on EVERY lifecycle event so
several chats on one page stay isolated — a composer reacts only to its own
host’s turn. It was undeclared here while being sent at runtime, and the
dispatcher takes Record<string, unknown>, so the compiler could not notice.
messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/events.ts:76
role: string;Defined in: packages/core/src/types/events.ts:77
usage?
Section titled “usage?”optional usage?: AparteUsage;Defined in: packages/core/src/types/events.ts:79
Token usage for the completed response, if reported by the provider.
AparteModelChangeEventDetail
Section titled “AparteModelChangeEventDetail”Defined in: packages/core/src/types/events.ts:97
Detail payload for aparte-model-change.
Dispatched by @aparte/plugin-model-selector when the user picks a different
provider or model — the clearest cross-package contract in the set.
Its @event tag used to sit above AparteMessageDoneEventDetail’s doc block
instead, so this interface had no documentation of its own and the other one
claimed to describe a different event.
aparte-model-change
Properties
Section titled “Properties”providerId?
Section titled “providerId?”optional providerId?: string;Defined in: packages/core/src/types/events.ts:99
Selected provider ID (e.g., ‘openrouter’, ‘gemini’)
modelId
Section titled “modelId”modelId: string;Defined in: packages/core/src/types/events.ts:102
Selected model ID (e.g., ‘gpt-4-turbo’, ‘claude-3-opus’)
previousModelId?
Section titled “previousModelId?”optional previousModelId?: string;Defined in: packages/core/src/types/events.ts:105
Previous model ID if changed
previousProviderId?
Section titled “previousProviderId?”optional previousProviderId?: string;Defined in: packages/core/src/types/events.ts:108
Previous provider ID if changed
AparteLinkClickEventDetail
Section titled “AparteLinkClickEventDetail”Defined in: packages/core/src/types/events.ts:138
Detail payload for aparte-link-click.
Dispatched by the bubble, cancelable, when a link in a message body is about to be
followed — a link the MODEL wrote. preventDefault() on the event keeps the browser
from navigating, so a host routes the link itself (an external browser, a
confirmation, an embedded view) without intercepting the DOM. With no listener the
browser follows it; the sanitizer has made an external URL open in a new tab.
aparte-link-click
Properties
Section titled “Properties”href: string;Defined in: packages/core/src/types/events.ts:140
The href as written on the anchor, after sanitization.
anchor
Section titled “anchor”anchor: HTMLAnchorElement;Defined in: packages/core/src/types/events.ts:142
The anchor itself, for a host that wants its text or its rel.
messageId
Section titled “messageId”messageId: string | null;Defined in: packages/core/src/types/events.ts:144
The message the link sits in, or null for a bubble mounted without one.
AparteBranchNavigateEventDetail
Section titled “AparteBranchNavigateEventDetail”Defined in: packages/core/src/types/events.ts:154
Detail payload for aparte-branch-navigate.
Dispatched by the bubble’s branch-picker buttons; the viewport listens
(bubbling) and calls navigateBranch(messageId, direction) on its repo.
aparte-branch-navigate
Properties
Section titled “Properties”messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/events.ts:156
Message id whose siblings should be navigated
direction
Section titled “direction”direction: "prev" | "next";Defined in: packages/core/src/types/events.ts:158
‘prev’ = move to previous sibling, ‘next’ = move to next sibling
ApartePathChangedEventDetail
Section titled “ApartePathChangedEventDetail”Defined in: packages/core/src/types/events.ts:169
Detail payload for aparte-path-changed.
Dispatched by the viewport in framework-managed mode after the active
path of the conversation tree changes (sibling switch, retry, edit, etc.).
Consumers (Angular wrapper) reconcile their signal/state from this payload.
aparte-path-changed
Properties
Section titled “Properties”messages
Section titled “messages”messages: AparteMessage[];Defined in: packages/core/src/types/events.ts:171
Messages on the new active path, root → head.
siblings
Section titled “siblings”siblings: AparteSiblingInfo[];Defined in: packages/core/src/types/events.ts:173
Sibling metadata, one entry per message on the path.
AparteRetryEventDetail
Section titled “AparteRetryEventDetail”Defined in: packages/core/src/types/events.ts:184
Detail payload for aparte-retry.
Dispatched by the assistant bubble’s “Retry” action. Picked up by the
AparteClient, which calls addSiblingOf on the target viewport and streams
a fresh response into the new sibling.
aparte-retry
Properties
Section titled “Properties”messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/events.ts:186
Message id of the assistant response being retried (its sibling will be created).
targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:188
Optional id of the host element (aparte-chat) — used by scopeToTargetId.
AparteEditEventDetail
Section titled “AparteEditEventDetail”Defined in: packages/core/src/types/events.ts:199
Detail payload for aparte-edit.
Dispatched by the user bubble after the user confirms an inline edit.
Picked up by the AparteClient, which truncates the existing responses to
this message and re-streams a new one.
aparte-edit
Properties
Section titled “Properties”messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/events.ts:201
Message id of the user message being edited.
content
Section titled “content”content: string;Defined in: packages/core/src/types/events.ts:203
New content submitted by the user.
targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:205
Optional id of the host element (aparte-chat) — used by scopeToTargetId.
AparteFeedbackEventDetail
Section titled “AparteFeedbackEventDetail”Defined in: packages/core/src/types/events.ts:214
Detail payload for aparte-feedback.
Dispatched by the assistant bubble’s thumbs-up / thumbs-down buttons.
aparte-feedback
Properties
Section titled “Properties”messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/events.ts:216
Message id receiving the feedback.
value: "positive" | "negative";Defined in: packages/core/src/types/events.ts:218
‘positive’ for thumbs-up, ‘negative’ for thumbs-down.
AparteActionEventDetail
Section titled “AparteActionEventDetail”Defined in: packages/core/src/types/events.ts:230
Detail payload for aparte-action.
Dispatched by a custom action button (registered via aparteGlobalConfig.registerAction)
in a message-bubble toolbar. Apps listen (bubbling) and dispatch on actionId.
Mirrors the built-in bubble events (retry/feedback) so custom actions are wired
the same way in every framework and in vanilla.
aparte-action
Properties
Section titled “Properties”actionId
Section titled “actionId”actionId: string;Defined in: packages/core/src/types/events.ts:232
The registered action’s id (from AparteAction.id).
zone: "bubble";Defined in: packages/core/src/types/events.ts:234
Which zone the action was clicked in.
messageId?
Section titled “messageId?”optional messageId?: string;Defined in: packages/core/src/types/events.ts:236
Message id of the bubble the action was clicked on.
optional role?: "user" | "assistant";Defined in: packages/core/src/types/events.ts:238
Role of that bubble.
targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:240
Optional host element id (aparte-chat) — same use as retry/edit’s targetId.
AparteMessageInfoEventDetail
Section titled “AparteMessageInfoEventDetail”Defined in: packages/core/src/types/events.ts:250
Detail payload for aparte-message-info.
Dispatched by the assistant bubble’s info (“i”) action button. Apps
listen (bubbling) and present a stats popover for the completed response.
aparte-message-info
Properties
Section titled “Properties”messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/events.ts:252
Message id whose stats should be shown.
usage?
Section titled “usage?”optional usage?: AparteUsage;Defined in: packages/core/src/types/events.ts:254
Token usage + timing for the message, when available.
AparteMessageStartEventDetail
Section titled “AparteMessageStartEventDetail”Defined in: packages/core/src/types/events.ts:277
Detail payload for aparte-message-start.
Dispatched when a turn begins, before the first token. The composer and the
conversation controller both use it to enter their streaming state.
aparte-message-start
Properties
Section titled “Properties”targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:279
Host element id, when the <aparte-chat> has one.
messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/events.ts:281
Id of the assistant message about to stream.
role: string;Defined in: packages/core/src/types/events.ts:283
Role of the message being created — 'assistant' in every current path.
AparteMessageErrorEventDetail
Section titled “AparteMessageErrorEventDetail”Defined in: packages/core/src/types/events.ts:293
Detail payload for aparte-message-error.
Dispatched when a turn fails. Four core components listen for it, and it is the
event guides/troubleshooting.md tells you to bind to surface a failure.
aparte-message-error
Properties
Section titled “Properties”targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:295
Host element id, when the <aparte-chat> has one.
messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/events.ts:297
Id of the message that failed.
error: AparteError;Defined in: packages/core/src/types/events.ts:299
The failure, with its code — not a string, unlike aparte-compact-error.
AparteMessagePausedEventDetail
Section titled “AparteMessagePausedEventDetail”Defined in: packages/core/src/types/events.ts:312
Detail payload for aparte-message-paused.
Dispatched when a server loop pauses the turn on calls only the page can answer — an
approval, a browser tool. The turn is not over (aparte-message-done follows the
resume), but the reply is worth saving now: its paused calls carry the server’s
ticket, and a conversation saved here can still be answered after a reload. The
conversation manager persists on it.
aparte-message-paused
Properties
Section titled “Properties”targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:314
Host element id, when the <aparte-chat> has one.
messageId
Section titled “messageId”messageId: string;Defined in: packages/core/src/types/events.ts:316
Id of the paused reply.
AparteMessageAbortedEventDetail
Section titled “AparteMessageAbortedEventDetail”Defined in: packages/core/src/types/events.ts:325
Detail payload for aparte-message-aborted.
Dispatched when the user stops a turn.
aparte-message-aborted
Properties
Section titled “Properties”targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:327
Host element id, when the <aparte-chat> has one.
messageId?
Section titled “messageId?”optional messageId?: string;Defined in: packages/core/src/types/events.ts:333
Id of the aborted message — OPTIONAL, and that is not laziness: the composer
dispatches this event on its own with only a targetId, because a user can
press Stop during the pre-flight window before any message id exists.
AparteAbortEventDetail
Section titled “AparteAbortEventDetail”Defined in: packages/core/src/types/events.ts:345
Detail payload for aparte-abort — a COMMAND, not a notification.
AparteClient listens for it on window; a bring-your-own-composer consumer
dispatches it to stop a stream. Nothing in core dispatches it on the consumer’s
behalf, which is exactly why its shape had to be documented somewhere.
aparte-abort
Properties
Section titled “Properties”targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:347
Which chat to stop. Omit on a single-chat page.
AparteCompactEventDetail
Section titled “AparteCompactEventDetail”Defined in: packages/core/src/types/events.ts:360
Detail payload for aparte-compact — a COMMAND dispatched on window to ask for
the conversation so far to be summarised.
<aparte-context auto-compact> dispatches it on reaching danger, and a host
dispatches it from a button; @aparte/plugin-compaction is what answers it. Core
itself neither listens for it nor compacts — the events below are the plugin’s.
aparte-compact
Properties
Section titled “Properties”targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:362
Which chat to compact. Omit on a single-chat page.
AparteCompactStartEventDetail
Section titled “AparteCompactStartEventDetail”Defined in: packages/core/src/types/events.ts:372
Detail payload for aparte-compact-start — the summarisation began. The point for a
host to show a spinner: summarising a long conversation is a model call and takes as
long as one.
aparte-compact-start
Properties
Section titled “Properties”targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:374
The chat being compacted, when it has an id.
AparteCompactDoneEventDetail
Section titled “AparteCompactDoneEventDetail”Defined in: packages/core/src/types/events.ts:386
Detail payload for aparte-compact-done.
A union flattened to optional fields, because the two outcomes carry different
payloads and a consumer cannot guess which: nothing to compact sends
{ skipped: true, reason }, a real compaction sends { summary, kept, dropped }.
aparte-compact-done
Properties
Section titled “Properties”skipped?
Section titled “skipped?”optional skipped?: boolean;Defined in: packages/core/src/types/events.ts:388
true when there was nothing worth summarising; the other two are absent.
reason?
Section titled “reason?”optional reason?: "streaming" | "empty" | "nothing-to-drop" | "running";Defined in: packages/core/src/types/events.ts:394
Why it was skipped: empty (no messages), nothing-to-drop (the selector kept
everything), running (a compaction was already in flight), streaming (a turn
is in flight in the transcript).
summary?
Section titled “summary?”optional summary?: string;Defined in: packages/core/src/types/events.ts:396
The summary that replaced the compacted turns.
optional kept?: number;Defined in: packages/core/src/types/events.ts:398
How many messages were kept verbatim after the summary.
dropped?
Section titled “dropped?”optional dropped?: number;Defined in: packages/core/src/types/events.ts:400
How many messages the summary replaced.
targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:402
The chat that was compacted, when it has an id — so a gauge on a multi-chat page resets only its own.
AparteCompactErrorEventDetail
Section titled “AparteCompactErrorEventDetail”Defined in: packages/core/src/types/events.ts:413
Detail payload for aparte-compact-error.
Note the asymmetry with aparte-message-error, which is deliberate rather than
hidden: error here is a plain string, not an AparteError.
aparte-compact-error
Properties
Section titled “Properties”error: string;Defined in: packages/core/src/types/events.ts:415
Human-readable failure reason.
targetId?
Section titled “targetId?”optional targetId?: string;Defined in: packages/core/src/types/events.ts:417
The chat the compaction was for, when it has an id.
AparteAttachmentPreviewEventDetail
Section titled “AparteAttachmentPreviewEventDetail”Defined in: packages/core/src/types/events.ts:432
Detail payload for aparte-attachment-preview.
Dispatched when a user clicks an image tile, once
setHostHandlers({ attachmentPreview: true }) has declared that you will open
a lightbox. Without the handler the tile is not interactive at all.
aparte-attachment-preview
Properties
Section titled “Properties”url: string;Defined in: packages/core/src/types/events.ts:434
Object URL or remote URL of the image.
name: string;Defined in: packages/core/src/types/events.ts:436
File name, or '' when the attachment carries none.
AparteApprovalModeChangeEventDetail
Section titled “AparteApprovalModeChangeEventDetail”Defined in: packages/core/src/types/events.ts:451
Detail for aparte-approval-mode-change — dispatched by @aparte/plugin-approval’s
<aparte-approval-mode> after the person switched the approval mode. Bubbles and
crosses shadow roots, so a host can persist the choice from any ancestor.
Declared here, like aparte-model-change, because a listener in any framework reads
e.detail through the typed event map. The values are the plugin’s four modes
(plan, ask, auto-edit, auto); typed as strings so core names none of them.
aparte-approval-mode-change
Properties
Section titled “Properties”mode: string;Defined in: packages/core/src/types/events.ts:453
The mode just switched to.
previousMode
Section titled “previousMode”previousMode: string;Defined in: packages/core/src/types/events.ts:455
The mode it replaced.
AparteToolApprovalRequestDetail
Section titled “AparteToolApprovalRequestDetail”Defined in: packages/core/src/types/tools.ts:58
Detail for aparte-tool-approval-request — emitted by the loop when a tool
marked needsApproval is about to run.
Listen for it to present the decision yourself. Core’s own gate asks at the COMPOSER
(<aparte-elicitation> renders the panel there), and the transcript row shows only a
state — there is no Approve/Reject control in a bubble.
This block used to say “the built-in renderer already shows Approve/Reject inline”,
which stopped being true when the decision moved to the composer. A consumer trusting
it shipped with no presenter and no approvalResolver, and every needsApproval call
aborted with nothing clickable on screen. The sibling docblock on needsApproval
records the same correction; this one was missed in the same file.
aparte-tool-approval-request
Properties
Section titled “Properties”toolCallId
Section titled “toolCallId”toolCallId: string;Defined in: packages/core/src/types/tools.ts:59
toolName
Section titled “toolName”toolName: string;Defined in: packages/core/src/types/tools.ts:60
input: Record<string, unknown>;Defined in: packages/core/src/types/tools.ts:61