@threadplane/chat 0.0.51 → 0.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/fesm2022/threadplane-chat.mjs +561 -158
- package/fesm2022/threadplane-chat.mjs.map +1 -1
- package/package.json +9 -3
- package/types/threadplane-chat.d.ts +208 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threadplane/chat",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.53",
|
|
4
4
|
"exports": {
|
|
5
5
|
"./chat.css": "./chat.css",
|
|
6
6
|
"./themes/default-dark.css": "./themes/default-dark.css",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@cacheplane/partial-json": ">=0.1.1 <0.3.0",
|
|
28
|
-
"@cacheplane/partial-markdown": "^0.
|
|
28
|
+
"@cacheplane/partial-markdown": "^0.4.1",
|
|
29
29
|
"tslib": "^2.3.0",
|
|
30
30
|
"@threadplane/telemetry": "*"
|
|
31
31
|
},
|
|
@@ -41,7 +41,13 @@
|
|
|
41
41
|
"@json-render/core": "^0.16.0",
|
|
42
42
|
"@langchain/core": "^1.1.33",
|
|
43
43
|
"rxjs": "~7.8.0",
|
|
44
|
-
"marked": "^15.0.0 || ^16.0.0"
|
|
44
|
+
"marked": "^15.0.0 || ^16.0.0",
|
|
45
|
+
"katex": "^0.16.0 || ^0.17.0"
|
|
46
|
+
},
|
|
47
|
+
"peerDependenciesMeta": {
|
|
48
|
+
"katex": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
45
51
|
},
|
|
46
52
|
"license": "PolyForm-Noncommercial-1.0.0 OR LicenseRef-Threadplane-Commercial",
|
|
47
53
|
"repository": {
|
|
@@ -12,9 +12,9 @@ import * as _threadplane_chat from '@threadplane/chat';
|
|
|
12
12
|
import { PartialJsonParser } from '@cacheplane/partial-json';
|
|
13
13
|
import { BaseMessage } from '@langchain/core/messages';
|
|
14
14
|
import * as _cacheplane_partial_markdown from '@cacheplane/partial-markdown';
|
|
15
|
-
import { CitationDefinition, MarkdownDocumentNode, MarkdownNode, MarkdownParagraphNode, MarkdownHeadingNode, MarkdownBlockquoteNode, MarkdownListNode, MarkdownListItemNode, MarkdownCodeBlockNode, MarkdownThematicBreakNode, MarkdownTextNode, MarkdownEmphasisNode, MarkdownStrongNode, MarkdownStrikethroughNode, MarkdownInlineCodeNode, MarkdownLinkNode, MarkdownAutolinkNode, MarkdownImageNode, MarkdownSoftBreakNode, MarkdownHardBreakNode, MarkdownCitationReferenceNode, MarkdownTableNode, MarkdownTableRowNode, MarkdownTableCellNode } from '@cacheplane/partial-markdown';
|
|
15
|
+
import { CitationDefinition, MarkdownDocumentNode, MarkdownNode, MarkdownParagraphNode, MarkdownHeadingNode, MarkdownBlockquoteNode, MarkdownListNode, MarkdownListItemNode, MarkdownCodeBlockNode, MarkdownThematicBreakNode, MarkdownTextNode, MarkdownEmphasisNode, MarkdownStrongNode, MarkdownStrikethroughNode, MarkdownInlineCodeNode, MarkdownMathInlineNode, MarkdownMathDisplayNode, MarkdownHtmlInlineNode, MarkdownHtmlBlockNode, MarkdownLinkNode, MarkdownAutolinkNode, MarkdownImageNode, MarkdownSoftBreakNode, MarkdownHardBreakNode, MarkdownCitationReferenceNode, MarkdownTableNode, MarkdownTableRowNode, MarkdownTableCellNode } from '@cacheplane/partial-markdown';
|
|
16
|
+
import { SafeHtml, DomSanitizer } from '@angular/platform-browser';
|
|
16
17
|
import { NavigationExtras } from '@angular/router';
|
|
17
|
-
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
|
18
18
|
|
|
19
19
|
/** Precise authored function tool — what `action()` returns. Carries the schema
|
|
20
20
|
* `S` and the handler's resolved return type `R`. */
|
|
@@ -52,6 +52,12 @@ type ClientToolDef = AnyFunctionToolDef | ViewToolDef | AskToolDef;
|
|
|
52
52
|
/** A frozen, name-keyed registry of client tools. */
|
|
53
53
|
type ClientToolRegistry = Readonly<Record<string, ClientToolDef>>;
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Application-wide options for {@link provideChat}. Every field is optional;
|
|
57
|
+
* the values are exposed to all chat components in the tree via the
|
|
58
|
+
* `CHAT_CONFIG` injection token, so you set them once at bootstrap instead of
|
|
59
|
+
* threading props through every component.
|
|
60
|
+
*/
|
|
55
61
|
interface ChatConfig {
|
|
56
62
|
/** Shared render registry for consumers that read CHAT_CONFIG. */
|
|
57
63
|
renderRegistry?: AngularRegistry;
|
|
@@ -198,15 +204,55 @@ interface Message {
|
|
|
198
204
|
*/
|
|
199
205
|
toolCallIds?: string[];
|
|
200
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Type guard narrowing a {@link Message} to `role: 'user'`.
|
|
209
|
+
*
|
|
210
|
+
* @param m The message to test.
|
|
211
|
+
* @returns `true` (and narrows `m`) when the message was sent by the user.
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* const userTurns = agent.messages().filter(isUserMessage);
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
201
217
|
declare function isUserMessage(m: Message): m is Message & {
|
|
202
218
|
role: 'user';
|
|
203
219
|
};
|
|
220
|
+
/**
|
|
221
|
+
* Type guard narrowing a {@link Message} to `role: 'assistant'`.
|
|
222
|
+
*
|
|
223
|
+
* @param m The message to test.
|
|
224
|
+
* @returns `true` (and narrows `m`) when the message came from the assistant.
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* const reply = agent.messages().findLast(isAssistantMessage);
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
204
230
|
declare function isAssistantMessage(m: Message): m is Message & {
|
|
205
231
|
role: 'assistant';
|
|
206
232
|
};
|
|
233
|
+
/**
|
|
234
|
+
* Type guard narrowing a {@link Message} to `role: 'tool'` (a tool result turn).
|
|
235
|
+
*
|
|
236
|
+
* @param m The message to test.
|
|
237
|
+
* @returns `true` (and narrows `m`) when the message is a tool result.
|
|
238
|
+
* @example
|
|
239
|
+
* ```ts
|
|
240
|
+
* if (isToolMessage(m)) console.log(m.toolCallId);
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
207
243
|
declare function isToolMessage(m: Message): m is Message & {
|
|
208
244
|
role: 'tool';
|
|
209
245
|
};
|
|
246
|
+
/**
|
|
247
|
+
* Type guard narrowing a {@link Message} to `role: 'system'`.
|
|
248
|
+
*
|
|
249
|
+
* @param m The message to test.
|
|
250
|
+
* @returns `true` (and narrows `m`) when the message is a system message.
|
|
251
|
+
* @example
|
|
252
|
+
* ```ts
|
|
253
|
+
* const visible = agent.messages().filter((m) => !isSystemMessage(m));
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
210
256
|
declare function isSystemMessage(m: Message): m is Message & {
|
|
211
257
|
role: 'system';
|
|
212
258
|
};
|
|
@@ -714,6 +760,18 @@ declare class ChatInputComponent {
|
|
|
714
760
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChatInputComponent, "chat-input", never, { "agent": { "alias": "agent"; "required": true; "isSignal": true; }; "submitOnEnter": { "alias": "submitOnEnter"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "showStopButton": { "alias": "showStopButton"; "required": false; "isSignal": true; }; }, { "submitted": "submitted"; "stopped": "stopped"; }, never, ["[chatInputBanner]", "[chatInputAttachments]", "[chatInputLeading]", "[chatInputModelSelect]", "[chatInputTrailing]", "[chatInputFooter]"], true, never>;
|
|
715
761
|
}
|
|
716
762
|
|
|
763
|
+
/**
|
|
764
|
+
* Whether the agent should show a "typing" indicator — it is loading and has
|
|
765
|
+
* not yet started streaming the assistant's reply.
|
|
766
|
+
*
|
|
767
|
+
* @param agent The agent to inspect.
|
|
768
|
+
* @returns `true` while the agent is awaiting a response but no assistant text
|
|
769
|
+
* has streamed yet; `false` once tokens arrive or the agent is idle.
|
|
770
|
+
* @example
|
|
771
|
+
* ```ts
|
|
772
|
+
* \@if (isTyping(agent)) { <chat-typing-indicator [agent]="agent" /> }
|
|
773
|
+
* ```
|
|
774
|
+
*/
|
|
717
775
|
declare function isTyping(agent: Agent): boolean;
|
|
718
776
|
declare class ChatTypingIndicatorComponent {
|
|
719
777
|
readonly agent: _angular_core.InputSignal<Agent<Record<string, unknown>>>;
|
|
@@ -810,6 +868,19 @@ declare class ChatScrollBubbleComponent {
|
|
|
810
868
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChatScrollBubbleComponent, "chat-scroll-bubble", never, { "mode": { "alias": "mode"; "required": true; "isSignal": true; }; }, { "clicked": "clicked"; }, never, never, true, never>;
|
|
811
869
|
}
|
|
812
870
|
|
|
871
|
+
/**
|
|
872
|
+
* Coerce an unknown error value into a human-readable message string — reads
|
|
873
|
+
* `.message` from `Error`s, returns strings as-is, and `String()`-casts the
|
|
874
|
+
* rest. Useful when rendering an agent's `error` outside the built-in
|
|
875
|
+
* `chat-error` component.
|
|
876
|
+
*
|
|
877
|
+
* @param error Any caught/agent error value.
|
|
878
|
+
* @returns The message text, or `null` when `error` is nullish.
|
|
879
|
+
* @example
|
|
880
|
+
* ```ts
|
|
881
|
+
* const msg = extractErrorMessage(agent.error());
|
|
882
|
+
* ```
|
|
883
|
+
*/
|
|
813
884
|
declare function extractErrorMessage(error: unknown): string | null;
|
|
814
885
|
declare class ChatErrorComponent {
|
|
815
886
|
readonly agent: _angular_core.InputSignal<Agent<Record<string, unknown>>>;
|
|
@@ -817,6 +888,18 @@ declare class ChatErrorComponent {
|
|
|
817
888
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChatErrorComponent, "chat-error", never, { "agent": { "alias": "agent"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
818
889
|
}
|
|
819
890
|
|
|
891
|
+
/**
|
|
892
|
+
* Read the agent's current human-in-the-loop interrupt, if any.
|
|
893
|
+
*
|
|
894
|
+
* @param agent The agent to inspect.
|
|
895
|
+
* @returns The pending {@link AgentInterrupt}, or `undefined` when the agent is
|
|
896
|
+
* not currently waiting on an interrupt.
|
|
897
|
+
* @example
|
|
898
|
+
* ```ts
|
|
899
|
+
* const interrupt = getInterrupt(agent);
|
|
900
|
+
* if (interrupt) agent.resume('approved');
|
|
901
|
+
* ```
|
|
902
|
+
*/
|
|
820
903
|
declare function getInterrupt(agent: Agent): AgentInterrupt | undefined;
|
|
821
904
|
declare class ChatInterruptComponent {
|
|
822
905
|
readonly agent: _angular_core.InputSignal<Agent<Record<string, unknown>>>;
|
|
@@ -886,6 +969,8 @@ interface Group {
|
|
|
886
969
|
name: string;
|
|
887
970
|
calls: ToolCall[];
|
|
888
971
|
templateRef?: ChatToolCallTemplateDirective;
|
|
972
|
+
/** Present when this group anchors a subagent spawned by its (single) task call. */
|
|
973
|
+
subagent?: Subagent;
|
|
889
974
|
}
|
|
890
975
|
declare class ChatToolCallsComponent {
|
|
891
976
|
readonly agent: _angular_core.InputSignal<Agent<Record<string, unknown>>>;
|
|
@@ -1347,6 +1432,21 @@ interface ParseTreeStore {
|
|
|
1347
1432
|
readonly spec: Signal<Spec | null>;
|
|
1348
1433
|
readonly elementStates: Signal<Map<string, ElementAccumulationState>>;
|
|
1349
1434
|
}
|
|
1435
|
+
/**
|
|
1436
|
+
* Create a {@link ParseTreeStore} — feeds streamed JSON chunks through a
|
|
1437
|
+
* partial-JSON parser and exposes the progressively-materialized spec and
|
|
1438
|
+
* per-element accumulation state as signals, so a generative-UI surface can
|
|
1439
|
+
* render while the spec is still arriving.
|
|
1440
|
+
*
|
|
1441
|
+
* @param parser The partial-JSON parser used to incrementally materialize chunks.
|
|
1442
|
+
* @returns A {@link ParseTreeStore}; call `push(chunk)` as bytes stream in.
|
|
1443
|
+
* @example
|
|
1444
|
+
* ```ts
|
|
1445
|
+
* const store = createParseTreeStore(parser);
|
|
1446
|
+
* store.push('{"type":"Car');
|
|
1447
|
+
* store.spec(); // best-effort Spec | null
|
|
1448
|
+
* ```
|
|
1449
|
+
*/
|
|
1350
1450
|
declare function createParseTreeStore(parser: PartialJsonParser): ParseTreeStore;
|
|
1351
1451
|
|
|
1352
1452
|
/** Chat-internal projection of an A2UI component, materialized by the
|
|
@@ -1401,6 +1501,19 @@ interface A2uiSurfaceStore {
|
|
|
1401
1501
|
readonly surfaceStates: Signal<Map<string, A2uiSurfaceState>>;
|
|
1402
1502
|
surfaceState(surfaceId: string): Signal<A2uiSurfaceState | undefined>;
|
|
1403
1503
|
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Create an {@link A2uiSurfaceStore} — the per-conversation store that buffers
|
|
1506
|
+
* streamed A2UI surface updates, tracks each surface's data model + lifecycle
|
|
1507
|
+
* state, and exposes them as signals for rendering. One store backs a chat
|
|
1508
|
+
* thread's A2UI surfaces.
|
|
1509
|
+
*
|
|
1510
|
+
* @returns A fresh, empty {@link A2uiSurfaceStore}.
|
|
1511
|
+
* @example
|
|
1512
|
+
* ```ts
|
|
1513
|
+
* const store = createA2uiSurfaceStore();
|
|
1514
|
+
* const surfaces = store.surfaces; // Signal<Map<string, A2uiSurface>>
|
|
1515
|
+
* ```
|
|
1516
|
+
*/
|
|
1404
1517
|
declare function createA2uiSurfaceStore(): A2uiSurfaceStore;
|
|
1405
1518
|
|
|
1406
1519
|
type ContentType = 'pending' | 'markdown' | 'json-render' | 'a2ui' | 'mixed';
|
|
@@ -1416,6 +1529,19 @@ interface ContentClassifier {
|
|
|
1416
1529
|
readonly errors: Signal<string[]>;
|
|
1417
1530
|
dispose(): void;
|
|
1418
1531
|
}
|
|
1532
|
+
/**
|
|
1533
|
+
* Create a {@link ContentClassifier} — the streaming accumulator that inspects
|
|
1534
|
+
* an assistant message's content as it arrives and classifies it (markdown vs a
|
|
1535
|
+
* generative-UI/A2UI spec), exposing the parsed result and per-element state as
|
|
1536
|
+
* signals so the renderer can switch modes mid-stream.
|
|
1537
|
+
*
|
|
1538
|
+
* @returns A fresh {@link ContentClassifier}; call `dispose()` when done.
|
|
1539
|
+
* @example
|
|
1540
|
+
* ```ts
|
|
1541
|
+
* const cc = createContentClassifier();
|
|
1542
|
+
* effect(() => console.log(cc.type())); // 'pending' | 'markdown' | 'spec'
|
|
1543
|
+
* ```
|
|
1544
|
+
*/
|
|
1419
1545
|
declare function createContentClassifier(): ContentClassifier;
|
|
1420
1546
|
|
|
1421
1547
|
/**
|
|
@@ -1542,6 +1668,26 @@ declare class ChatComponent {
|
|
|
1542
1668
|
* reasoning pill collapses (per its internal logic).
|
|
1543
1669
|
*/
|
|
1544
1670
|
protected isReasoningStreaming(message: Message, index: number): boolean;
|
|
1671
|
+
/** The nearest preceding assistant message (skipping hidden tool messages), or undefined. */
|
|
1672
|
+
private prevAssistant;
|
|
1673
|
+
/**
|
|
1674
|
+
* True when message[index] starts a reasoning RUN — a maximal sequence of
|
|
1675
|
+
* consecutive assistant reasoning steps separated only by (hidden) tool
|
|
1676
|
+
* messages. The merged reasoning pill renders once, here.
|
|
1677
|
+
*/
|
|
1678
|
+
protected reasoningRunStart(index: number): boolean;
|
|
1679
|
+
/**
|
|
1680
|
+
* Aggregate the reasoning RUN starting at `index`: joins each step's
|
|
1681
|
+
* reasoning, sums durations, counts steps, and computes the streaming flag
|
|
1682
|
+
* and the merged label when N > 1 ("Thought for {total} · {N} steps", or
|
|
1683
|
+
* just "{N} steps" when no step reported timing).
|
|
1684
|
+
*/
|
|
1685
|
+
protected reasoningRun(index: number): {
|
|
1686
|
+
content: string;
|
|
1687
|
+
durationMs: number | undefined;
|
|
1688
|
+
streaming: boolean;
|
|
1689
|
+
label: string | undefined;
|
|
1690
|
+
};
|
|
1545
1691
|
private readonly classifiers;
|
|
1546
1692
|
private readonly destroyRef;
|
|
1547
1693
|
private readonly injector;
|
|
@@ -2000,6 +2146,36 @@ declare class MarkdownInlineCodeComponent {
|
|
|
2000
2146
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MarkdownInlineCodeComponent, "chat-md-inline-code", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2001
2147
|
}
|
|
2002
2148
|
|
|
2149
|
+
type MathNode = MarkdownMathInlineNode | MarkdownMathDisplayNode;
|
|
2150
|
+
/**
|
|
2151
|
+
* Renders a `math-inline` / `math-display` markdown node as KaTeX. KaTeX is
|
|
2152
|
+
* lazy-loaded (see katex-loader); until it resolves, or if the LaTeX is
|
|
2153
|
+
* invalid, the raw `$…$` source is shown — never blank, never a crash.
|
|
2154
|
+
*/
|
|
2155
|
+
declare class MarkdownMathComponent {
|
|
2156
|
+
readonly node: _angular_core.InputSignal<MathNode>;
|
|
2157
|
+
private readonly sanitizer;
|
|
2158
|
+
protected readonly display: _angular_core.Signal<boolean>;
|
|
2159
|
+
protected readonly raw: _angular_core.Signal<string>;
|
|
2160
|
+
protected readonly html: _angular_core.Signal<SafeHtml | null>;
|
|
2161
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MarkdownMathComponent, never>;
|
|
2162
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MarkdownMathComponent, "chat-md-math", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
/**
|
|
2166
|
+
* Renders a `html-block` / `html-inline` markdown node as **escaped text** —
|
|
2167
|
+
* the raw HTML is shown literally (Angular interpolation auto-escapes it),
|
|
2168
|
+
* never injected as live markup. This preserves the pre-0.4 behavior where
|
|
2169
|
+
* raw HTML was plain text, and keeps the chat XSS-safe: model-emitted
|
|
2170
|
+
* `<script>`, `<iframe>`, etc. are displayed as text and never executed.
|
|
2171
|
+
*/
|
|
2172
|
+
declare class MarkdownHtmlComponent {
|
|
2173
|
+
readonly node: _angular_core.InputSignal<MarkdownHtmlInlineNode | MarkdownHtmlBlockNode>;
|
|
2174
|
+
protected readonly raw: _angular_core.Signal<string>;
|
|
2175
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MarkdownHtmlComponent, never>;
|
|
2176
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MarkdownHtmlComponent, "chat-md-html", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2003
2179
|
declare class MarkdownLinkComponent {
|
|
2004
2180
|
readonly node: _angular_core.InputSignal<MarkdownLinkNode>;
|
|
2005
2181
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MarkdownLinkComponent, never>;
|
|
@@ -2069,8 +2245,6 @@ declare class MarkdownTableCellComponent {
|
|
|
2069
2245
|
*/
|
|
2070
2246
|
declare const IS_HEADER_ROW: InjectionToken<Signal<boolean>>;
|
|
2071
2247
|
|
|
2072
|
-
declare const CHAT_MARKDOWN_STYLES = "\n chat-streaming-md { display: block; color: var(--ngaf-chat-text); line-height: var(--ngaf-chat-line-height); }\n\n /* Headings */\n chat-streaming-md h1, chat-streaming-md h2, chat-streaming-md h3, chat-streaming-md h4, chat-streaming-md h5, chat-streaming-md h6 {\n font-weight: 600;\n line-height: 1.25;\n margin: 1.25rem 0 0.75rem;\n }\n chat-streaming-md h1:first-child, chat-streaming-md h2:first-child, chat-streaming-md h3:first-child,\n chat-streaming-md h4:first-child, chat-streaming-md h5:first-child, chat-streaming-md h6:first-child { margin-top: 0; }\n chat-streaming-md h1 { font-size: 1.5em; font-weight: 700; }\n chat-streaming-md h2 { font-size: 1.25em; }\n chat-streaming-md h3 { font-size: 1.1em; }\n chat-streaming-md h4 { font-size: 1em; }\n chat-streaming-md h5, chat-streaming-md h6 { font-size: 0.95em; color: var(--ngaf-chat-text-muted); }\n\n /* Paragraphs and inline emphasis */\n chat-streaming-md p { margin: 0 0 0.75rem; line-height: 1.6; font-size: var(--ngaf-chat-font-size); }\n chat-streaming-md p:last-child { margin-bottom: 0; }\n chat-streaming-md strong, chat-streaming-md b { font-weight: 700; }\n chat-streaming-md em, chat-streaming-md i { font-style: italic; }\n chat-streaming-md del, chat-streaming-md s { text-decoration: line-through; color: var(--ngaf-chat-text-muted); }\n chat-streaming-md mark { background: var(--ngaf-chat-surface-alt); padding: 0 2px; border-radius: 2px; }\n chat-streaming-md sub { font-size: 0.75em; vertical-align: sub; }\n chat-streaming-md sup { font-size: 0.75em; vertical-align: super; }\n\n /* Links */\n chat-streaming-md a { color: var(--ngaf-chat-primary); text-decoration: underline; text-underline-offset: 2px; }\n chat-streaming-md a:hover { text-decoration-thickness: 2px; }\n\n /* Lists (CommonMark + GFM task lists) */\n chat-streaming-md ul, chat-streaming-md ol { margin: 0 0 0.75rem; padding-left: 1.5rem; }\n chat-streaming-md ul { list-style: disc outside; }\n chat-streaming-md ol { list-style: decimal outside; }\n chat-streaming-md ul ul { list-style: circle outside; }\n chat-streaming-md ul ul ul { list-style: square outside; }\n chat-streaming-md li { margin: 0.2rem 0; }\n chat-streaming-md li::marker { color: var(--ngaf-chat-text-muted); }\n chat-streaming-md li > p { margin: 0 0 0.25rem; }\n chat-streaming-md li > ul, chat-streaming-md li > ol { margin: 0.25rem 0 0; }\n /* GFM task lists: marked emits <li><input type=\"checkbox\" disabled> ... */\n chat-streaming-md li:has(> input[type=\"checkbox\"]) { list-style: none; margin-left: -1.25rem; }\n chat-streaming-md li > input[type=\"checkbox\"] { margin-right: 0.5rem; vertical-align: middle; }\n\n /* Code (inline + fenced) */\n chat-streaming-md code {\n background: var(--ngaf-chat-surface-alt);\n color: var(--ngaf-chat-text);\n padding: 1px 5px;\n border-radius: 4px;\n font-family: var(--ngaf-chat-font-mono);\n font-size: 0.9em;\n }\n chat-streaming-md pre {\n background: var(--ngaf-chat-surface-alt);\n color: var(--ngaf-chat-text);\n padding: 12px 14px;\n border-radius: var(--ngaf-chat-radius-card);\n overflow-x: auto;\n font-family: var(--ngaf-chat-font-mono);\n font-size: var(--ngaf-chat-font-size-sm);\n line-height: 1.5;\n margin: 0 0 0.75rem;\n }\n chat-streaming-md pre code { background: transparent; padding: 0; border-radius: 0; font-size: inherit; }\n\n /* Blockquote */\n chat-streaming-md blockquote {\n border-left: 3px solid var(--ngaf-chat-separator);\n padding: 0.25rem 0 0.25rem 12px;\n margin: 0 0 0.75rem;\n color: var(--ngaf-chat-text-muted);\n }\n chat-streaming-md blockquote > :last-child { margin-bottom: 0; }\n\n /* Horizontal rule */\n chat-streaming-md hr {\n border: none;\n border-top: 1px solid var(--ngaf-chat-separator);\n margin: 1rem 0;\n }\n\n /* Tables (GFM) */\n chat-streaming-md table {\n border-collapse: collapse;\n margin: 0 0 0.75rem;\n width: 100%;\n font-size: 0.95em;\n }\n chat-streaming-md thead { background: var(--ngaf-chat-surface-alt); }\n chat-streaming-md th, chat-streaming-md td {\n border: 1px solid var(--ngaf-chat-separator);\n padding: 6px 10px;\n text-align: left;\n vertical-align: top;\n }\n chat-streaming-md th { font-weight: 600; }\n /* Component-rendered table: chat-md-table becomes a horizontally-scrollable\n wrapper for the inner <table>; row/cell elements stay layout-transparent\n so the browser's table layout takes over. Without this overflow wrapper,\n wide tables push their parent container past the viewport horizontally. */\n chat-streaming-md chat-md-table {\n display: block;\n overflow-x: auto;\n max-width: 100%;\n margin: 0 0 0.75rem;\n }\n chat-streaming-md chat-md-table-row { display: contents; }\n chat-streaming-md chat-md-table-cell { display: contents; }\n chat-streaming-md chat-md-table > table { margin: 0; }\n /* Task-list items: checkbox + first paragraph render inline; subsequent\n blocks (sub-lists, multi-paragraph items) flow normally below. */\n chat-streaming-md li.chat-md-list-item--task {\n list-style: none;\n margin-left: -1.25rem;\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 0.5rem;\n }\n chat-streaming-md li.chat-md-list-item--task > input[type=\"checkbox\"] {\n margin: 0;\n flex: 0 0 auto;\n transform: translateY(2px);\n }\n /* The chat-md-children wrapper around list-item content takes remaining width */\n chat-streaming-md li.chat-md-list-item--task > chat-md-children {\n flex: 1 1 auto;\n min-width: 0;\n }\n /* Tight task items: only the FIRST paragraph aligns inline with the\n checkbox (margin collapsed). Subsequent paragraphs/blocks keep their\n normal vertical spacing so multi-block items render readably. */\n chat-streaming-md li.chat-md-list-item--task > chat-md-children > chat-md-paragraph:first-child > p {\n margin: 0;\n }\n\n /* Media */\n chat-streaming-md img { max-width: 100%; height: auto; border-radius: 6px; }\n /* Broken-image fallback: muted pill showing alt text + icon. Triggered\n when <img> fires (error). Caught by live browser smoke \u2014 prior impl\n showed only the browser's broken-image icon with no readable alt. */\n chat-streaming-md .chat-md-image--broken {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.25rem 0.5rem;\n background: var(--ngaf-chat-surface-alt);\n border: 1px dashed var(--ngaf-chat-separator);\n border-radius: 6px;\n font-size: 0.9em;\n color: var(--ngaf-chat-text-muted, currentColor);\n opacity: 0.85;\n }\n chat-streaming-md .chat-md-image__icon { font-size: 1em; line-height: 1; }\n chat-streaming-md .chat-md-image__alt { font-style: italic; }\n";
|
|
2073
|
-
|
|
2074
2248
|
/**
|
|
2075
2249
|
* Renders markdown content to sanitized HTML.
|
|
2076
2250
|
* Falls back to plain text with newline->br conversion if `marked` is not installed.
|
|
@@ -2090,21 +2264,6 @@ declare function renderMarkdown(content: string, sanitizer: DomSanitizer): SafeH
|
|
|
2090
2264
|
*/
|
|
2091
2265
|
declare function formatDuration(ms: number): string;
|
|
2092
2266
|
|
|
2093
|
-
/** Chevron down (▼ replacement). 12x12, stroke-based. */
|
|
2094
|
-
declare const ICON_CHEVRON_DOWN = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 4.5L6 7.5L9 4.5\"/></svg>";
|
|
2095
|
-
/** Chevron up (▲ replacement). 12x12, stroke-based. */
|
|
2096
|
-
declare const ICON_CHEVRON_UP = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 7.5L6 4.5L9 7.5\"/></svg>";
|
|
2097
|
-
/** Gear icon (⚙ replacement). 14x14. */
|
|
2098
|
-
declare const ICON_TOOL = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42\"/></svg>";
|
|
2099
|
-
/** Warning triangle (⚠ replacement). 18x18. */
|
|
2100
|
-
declare const ICON_WARNING = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></svg>";
|
|
2101
|
-
/** Robot/agent icon (replacement). 14x14. */
|
|
2102
|
-
declare const ICON_AGENT = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"10\" rx=\"2\"/><circle cx=\"12\" cy=\"5\" r=\"2\"/><path d=\"M12 7v4\"/><line x1=\"8\" y1=\"16\" x2=\"8\" y2=\"16\"/><line x1=\"16\" y1=\"16\" x2=\"16\" y2=\"16\"/></svg>";
|
|
2103
|
-
/** Check mark replacement. 12x12. */
|
|
2104
|
-
declare const ICON_CHECK = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M2.5 6L5 8.5L9.5 3.5\"/></svg>";
|
|
2105
|
-
/** Send arrow (for chat input). 16x16. */
|
|
2106
|
-
declare const ICON_SEND = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 12V4M8 4L4 8M8 4L12 8\"/></svg>";
|
|
2107
|
-
|
|
2108
2267
|
/** Catalog entry for the A2UI surface renderer.
|
|
2109
2268
|
*
|
|
2110
2269
|
* `component` is mounted once all of the component's bindings (data
|
|
@@ -2222,14 +2381,24 @@ declare class A2uiSurfaceComponent {
|
|
|
2222
2381
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<A2uiSurfaceComponent, "a2ui-surface", never, { "surface": { "alias": "surface"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "catalog": { "alias": "catalog"; "required": true; "isSignal": true; }; "handlers": { "alias": "handlers"; "required": false; "isSignal": true; }; "surfaceFallback": { "alias": "surfaceFallback"; "required": false; "isSignal": true; }; }, { "events": "events"; "action": "action"; }, never, never, true, never>;
|
|
2223
2382
|
}
|
|
2224
2383
|
|
|
2225
|
-
declare function surfaceToSpec(surface: A2uiSurface): Spec | null;
|
|
2226
|
-
|
|
2227
2384
|
/** Builds an A2uiActionMessage from handler params and the current surface.
|
|
2228
2385
|
* The action.context is serialized as v1 DynamicValue-wrapped entries.
|
|
2229
2386
|
* Sets action.label when the source component is a Button with a Text
|
|
2230
2387
|
* child whose literalString is non-empty. */
|
|
2231
2388
|
declare function buildA2uiActionMessage(params: Record<string, unknown>, surface: A2uiSurface): A2uiActionMessage;
|
|
2232
2389
|
|
|
2390
|
+
/**
|
|
2391
|
+
* Build the built-in A2UI component catalog — a {@link ViewRegistry} mapping
|
|
2392
|
+
* the standard A2UI element types (Card, Button, TextField, Image, AudioPlayer,
|
|
2393
|
+
* Video, …) to their Angular renderers. Spread it into `provideViews` (with any
|
|
2394
|
+
* of your own views) so an agent's A2UI surface specs render.
|
|
2395
|
+
*
|
|
2396
|
+
* @returns A {@link ViewRegistry} of the standard A2UI components.
|
|
2397
|
+
* @example
|
|
2398
|
+
* ```ts
|
|
2399
|
+
* providers: [provideViews({ ...a2uiBasicCatalog(), MyWidget: MyWidgetComponent })]
|
|
2400
|
+
* ```
|
|
2401
|
+
*/
|
|
2233
2402
|
declare function a2uiBasicCatalog(): ViewRegistry;
|
|
2234
2403
|
|
|
2235
2404
|
/** Writes a typed value to the render state store if the prop has a binding path. */
|
|
@@ -2394,6 +2563,8 @@ declare class A2uiIconComponent {
|
|
|
2394
2563
|
readonly childKeys: _angular_core.InputSignal<string[]>;
|
|
2395
2564
|
readonly spec: _angular_core.InputSignal<Spec | undefined>;
|
|
2396
2565
|
protected readonly effectiveName: _angular_core.Signal<string>;
|
|
2566
|
+
/** The effective name as a Material Symbols ligature (camelCase → snake_case). */
|
|
2567
|
+
protected readonly glyphName: _angular_core.Signal<string>;
|
|
2397
2568
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<A2uiIconComponent, never>;
|
|
2398
2569
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<A2uiIconComponent, "a2ui-icon", never, { "name": { "alias": "name"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "bindings": { "alias": "bindings"; "required": false; "isSignal": true; }; "emit": { "alias": "emit"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "childKeys": { "alias": "childKeys"; "required": false; "isSignal": true; }; "spec": { "alias": "spec"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2399
2570
|
}
|
|
@@ -2763,7 +2934,6 @@ interface ClientToolsCoordinator {
|
|
|
2763
2934
|
}
|
|
2764
2935
|
/** Build the catalog spec list shipped to the model. */
|
|
2765
2936
|
declare function toClientToolSpecs(registry: ClientToolRegistry): ClientToolSpec[];
|
|
2766
|
-
declare function createClientToolsCoordinator(registry: ClientToolRegistry): ClientToolsCoordinator;
|
|
2767
2937
|
|
|
2768
2938
|
interface MockAgent extends Agent {
|
|
2769
2939
|
messages: WritableSignal<Message[]>;
|
|
@@ -2814,10 +2984,25 @@ interface MockAgentOptions {
|
|
|
2814
2984
|
history?: AgentCheckpoint[];
|
|
2815
2985
|
events$?: Observable<AgentEvent>;
|
|
2816
2986
|
}
|
|
2987
|
+
/**
|
|
2988
|
+
* Build an in-memory {@link Agent} for tests and stories — no transport, no
|
|
2989
|
+
* network. Every field is a writable signal so a test can drive UI states
|
|
2990
|
+
* (loading, error, interrupts, tool calls, subagents) deterministically.
|
|
2991
|
+
*
|
|
2992
|
+
* @param opts Initial values for the mock's signals; all optional.
|
|
2993
|
+
* @returns A {@link MockAgent} satisfying the full `Agent` contract.
|
|
2994
|
+
* @example
|
|
2995
|
+
* ```ts
|
|
2996
|
+
* const agent = mockAgent({
|
|
2997
|
+
* messages: [{ id: '1', role: 'assistant', content: 'Hi' }],
|
|
2998
|
+
* isLoading: true,
|
|
2999
|
+
* });
|
|
3000
|
+
* ```
|
|
3001
|
+
*/
|
|
2817
3002
|
declare function mockAgent(opts?: MockAgentOptions): MockAgent;
|
|
2818
3003
|
|
|
2819
3004
|
/** Inferred argument type for a schema (alias of StandardSchemaInferOutput). */
|
|
2820
3005
|
type ToolArgs<S extends StandardSchemaV1> = StandardSchemaInferOutput<S>;
|
|
2821
3006
|
|
|
2822
|
-
export { A2uiAudioPlayerComponent, A2uiButtonComponent, A2uiCardComponent, A2uiCheckBoxComponent, A2uiColumnComponent, A2uiDateTimeInputComponent, A2uiDividerComponent, A2uiIconComponent, A2uiImageComponent, A2uiListComponent, A2uiModalComponent, A2uiMultipleChoiceComponent, A2uiRowComponent, A2uiSliderComponent, A2uiSurfaceComponent, A2uiTabsComponent, A2uiTextComponent, A2uiTextFieldComponent, A2uiVideoComponent, AGENT_ERROR_MESSAGES, AgentError, CHAT_CONFIG, CHAT_LIFECYCLE,
|
|
3007
|
+
export { A2uiAudioPlayerComponent, A2uiButtonComponent, A2uiCardComponent, A2uiCheckBoxComponent, A2uiColumnComponent, A2uiDateTimeInputComponent, A2uiDividerComponent, A2uiIconComponent, A2uiImageComponent, A2uiListComponent, A2uiModalComponent, A2uiMultipleChoiceComponent, A2uiRowComponent, A2uiSliderComponent, A2uiSurfaceComponent, A2uiTabsComponent, A2uiTextComponent, A2uiTextFieldComponent, A2uiVideoComponent, AGENT_ERROR_MESSAGES, AgentError, CHAT_CONFIG, CHAT_LIFECYCLE, ChatApprovalCardComponent, ChatCitationCardTemplateDirective, ChatCitationsCardComponent, ChatCitationsComponent, ChatComponent, ChatConfirmDialogComponent, ChatErrorComponent, ChatGenerativeUiComponent, ChatGenuiSkeletonComponent, ChatHistorySearchPaletteComponent, ChatInputComponent, ChatInterruptComponent, ChatInterruptPanelComponent, ChatLauncherButtonComponent, ChatMessageActionsComponent, ChatMessageComponent, ChatMessageListComponent, ChatOverflowMenuComponent, ChatPopupComponent, ChatProjectListComponent, ChatReasoningComponent, ChatScrollBubbleComponent, ChatSelectComponent, ChatSidebarComponent, ChatSidenavComponent, ChatSidenavScrimComponent, ChatStreamingMdComponent, ChatSubagentCardComponent, ChatSubagentsComponent, ChatSuggestionsComponent, ChatThreadListComponent, ChatTimelineComponent, ChatTimelineSliderComponent, ChatToolCallCardComponent, ChatToolCallTemplateDirective, ChatToolCallsComponent, ChatToolViewsComponent, ChatTraceComponent, ChatTypingIndicatorComponent, ChatWelcomeComponent, ChatWelcomeSuggestionComponent, ChatWindowComponent, CitationsResolverService, IS_HEADER_ROW, MARKDOWN_VIEW_REGISTRY, MarkdownAutolinkComponent, MarkdownBlockquoteComponent, MarkdownChildrenComponent, MarkdownCitationReferenceComponent, MarkdownCodeBlockComponent, MarkdownDocumentComponent, MarkdownEmphasisComponent, MarkdownHardBreakComponent, MarkdownHeadingComponent, MarkdownHtmlComponent, MarkdownImageComponent, MarkdownInlineCodeComponent, MarkdownLinkComponent, MarkdownListComponent, MarkdownListItemComponent, MarkdownMathComponent, MarkdownParagraphComponent, MarkdownSoftBreakComponent, MarkdownStrikethroughComponent, MarkdownStrongComponent, MarkdownTableCellComponent, MarkdownTableComponent, MarkdownTableRowComponent, MarkdownTextComponent, MarkdownThematicBreakComponent, MessageTemplateDirective, a2uiBasicCatalog, action, ask, buildA2uiActionMessage, cacheplaneMarkdownViews, createA2uiSurfaceStore, createAgentRef, createContentClassifier, createParseTreeStore, createPartialArgsBridge, deriveJsonSchema, emitBinding, executeFunctionTool, extractErrorMessage, formatDuration, getInterrupt, getMessageType, injectThreadRouting, isAbortError, isAssistantMessage, isSystemMessage, isToolMessage, isTyping, isUserMessage, messageContent, mockAgent, normalizeEnvelopeArgs, normalizeViewEntry, provideChat, renderMarkdown, startClientToolExecutor, statusColor, submitMessage, toAgentError, toClientToolSpecs, tools, validateArgs, view };
|
|
2823
3008
|
export type { A2uiComponentView, A2uiSurfaceState, A2uiSurfaceStore, A2uiViewEntry, A2uiViews, Agent, AgentCheckpoint, AgentCustomEvent, AgentErrorKind, AgentEvent, AgentInterrupt, AgentRef, AgentRuntimeTelemetryEvent, AgentRuntimeTelemetryPayload, AgentRuntimeTelemetryProperties, AgentRuntimeTelemetrySink, AgentStateUpdateEvent, AgentStatus, AgentSubmitInput, AgentSubmitOptions, AgentWithHistory, AnyFunctionToolDef, AskToolDef, ChatApprovalAction, ChatConfig, ChatLifecycle, ChatMessageRole, ChatRenderEvent, ChatScrollBubbleMode, ChatSelectOption, ChatSidenavMode, ChatToolCallTemplateContext, Citation, ClientToolDef, ClientToolRegistry, ClientToolResult, ClientToolSpec, ClientToolsCapability, ClientToolsCoordinator, ContentBlock, ContentClassifier, ContentType, ElementAccumulationState, FunctionToolDef, InterruptAction, Message, MessageTemplateType, MockAgent, MockAgentOptions, OverflowMenuItem, ParseTreeStore, PartialArgsBridge, Project, ProjectActionAdapter, ResolvedCitation, Role, Subagent, SubagentStatus, Thread, ThreadActionAdapter, ThreadMatch, ThreadRoutingConfig, ToolArgs, ToolCall, ToolCallInfo, ToolCallStatus, TraceState, ViewProps, ViewToolDef };
|