import type { Source, ProjectAction } from '../../types/widget';
import { EventEmitter } from '../../stencil-public-runtime';
import { AiIconType } from '../../utils/icon-types';
export declare class BielMessage {
messageId?: string;
sender: 'user' | 'ai';
text: string;
sources?: Source[];
availableActions?: ProjectAction[];
feedback?: 0 | 1;
hideFeedback: boolean;
bielId: string;
isPartial: boolean;
partialId: number;
sourcesText: string;
aiIcon: AiIconType;
hideAvatars: boolean;
hideSources: boolean;
hideInlineCitations: boolean;
assistantLabel: string;
smoothStreaming: boolean;
renderMath: boolean;
mathjaxUrl: string;
renderDiagrams: boolean;
mermaidTheme: string;
content: string;
rawContent: string;
feedbackValue: 0 | 1;
displaySources: Source[];
citationNumbers: {
[urlKey: string]: number;
};
showSources: boolean;
copied: boolean;
completed: boolean;
el: HTMLElement;
scrollToBottom: EventEmitter<{
bielId: string;
}>;
feedbackSent: EventEmitter<{
bielId: string;
messageId: string;
reaction: 0 | 1;
}>;
private copyTimers;
private revealBacklog;
private revealCarry;
private revealRafId;
private lastRevealTs;
private pendingReveal;
private lastMarkdownTs;
private waitingForFade;
private completionWaitVersion;
private pendingCompletion;
private get useSmoothStreaming();
handleTextUpdate(event: CustomEvent<{
text: string;
id: number;
bielId: string;
}>): void;
private startRevealLoop;
private revealTick;
private invalidateCompletionWait;
private completeAfterReveal;
private finishRevealNow;
private applyCompletion;
handlePartialMessageComplete(event: CustomEvent<{
partialId: number;
bielId: string;
msg: {
text: string;
sender: 'user' | 'ai';
messageId?: string;
feedback?: 0 | 1;
sources?: Source[];
isPartial: boolean;
partialId?: number;
};
}>): void;
/**
* Replace the streamed draft with the server's completed text, which is
* authoritative: the payload may differ from the deltas (the server validates
* citations only once the answer is whole, so the final text can drop markers
* the draft still shows — leaving a chip pointing at a source that isn't in
* the sources list), and it is the safest point to remount custom elements
* that were updated repeatedly while Markdown was partial. An empty text is
* treated as "nothing to replace with" and keeps the draft.
*/
replaceContent(text?: string): void;
handleSettledTextChanged(text: string): void;
handleSettledSourcesChanged(sources: Source[]): void;
componentWillLoad(): void;
disconnectedCallback(): void;
private get isComplete();
private toggleSources;
private hostnameFrom;
private handleReaction;
private copyAnswer;
private execCommandCopy;
componentDidLoad(): void;
/**
* Replace each inline ```` tag with an anchor styled as a
* chip, resolving the name against the project's actions. Unknown/unresolved
* tags are removed so no raw markup leaks. Runs before Markdown parsing so
* the anchor survives marked + DOMPurify (which both keep plain elements).
*/
renderInlineActions(text: string): string;
/**
* Upgrade citation links into compact superscript chips as a DOM pass over the
* already-parsed, already-sanitized message tree: any anchor whose visible
* text is purely 1-2 digits and whose href is http(s) becomes a scholarly
* ``[n]`` chip. The backend streams these as plain markdown links, e.g.
* ``[1](https://docs.example.com/page)``.
*
* Running AFTER marked + DOMPurify (rather than a raw-text regex before them)
* means: URLs with balanced parentheses are parsed correctly by marked;
* citation-shaped text inside code spans/fences stays literal because it never
* becomes an anchor; and DOMPurify has already stripped any dangerous href, so
* only safe http(s) links remain to match. The pass is idempotent (an anchor
* already carrying the chip class is skipped) and mutates in place, so the
* upgraded anchor rides the same streaming diff as the action chips. Partial
* links at a chunk boundary (``[1](https://doc``) aren't anchors yet, so no
* chip appears until the link completes.
*
* With `hideInlineCitations` the same detection applies but matching anchors
* are removed (with the space before them) instead of upgraded — the message
* reads as if the backend had never cited.
*
* A chip shows its source's rank by first appearance in the message, not the
* number the backend wrote: those are positions in the model's context list,
* so a message can arrive citing 1, 5, 3. Numbering by appearance keeps the
* sequence counting up from the very first streamed chunk — the backend
* settles on the same numbering for the final message, so nothing shifts
* when streaming ends. The href is the citation's real identity; the digit
* is only a pointer to it. The same map (normalized href → number) badges
* the footer's source cards, so a card always matches its chips.
*/
upgradeCitationAnchors(root: HTMLElement): void;
/**
* Remove a citation anchor along with the single space that precedes it, so
* "blue [1](url)." collapses to "blue." — the same one-space cleanup the
* backend applies when it strips an invalid marker.
*/
removeCitationAnchor(anchor: HTMLAnchorElement): void;
/** Replace `citationNumbers` only when the collected map actually differs,
* so the per-chunk streaming passes don't trigger a re-render each time. */
recordCitationNumbers(found: {
[urlKey: string]: number;
}): void;
/** Citation number for a source card, or `undefined` when that source was
* never cited inline (or citations are hidden). */
citationNumberFor(url: string): number | undefined;
/**
* Pull math out of the Markdown before anything else touches it. Runs ahead
* of the action tags so the anchors injected for those can never be mistaken
* for a formula, and returns the spans to be put back after sanitizing.
*/
private takeMathSpans;
processMarkdown(fragment: string, replaceAll?: boolean): void;
convertToElement(content: string): HTMLElement;
private wrapStreamingText;
private settleStreamingFragment;
deepCompareAndReplace(element1: HTMLElement, element2: HTMLElement): void;
private cloneMessageNode;
areNodesEqual(node1: Node, node2: Node): boolean;
/**
* Copy the freshly parsed element's attributes onto the mounted one.
*
* `class` is excluded for custom elements only: Stencil writes their host
* class itself (`hydrated`, scoping classes) and the detached tree never
* carries it, so copying would strip it and leave the element invisible. On
* a plain element the class comes solely from this component's own parse
* pipeline and must be synced — a citation anchor is already mounted as the
* autolink of a half-streamed URL by the time the chip pass claims it, and
* the chip class is then the only thing that changes.
*/
synchronizeAttributes(element1: HTMLElement, element2: HTMLElement): void;
private renderFooter;
render(): any;
}