@urbicon-ui/blocks 6.35.0 → 6.36.0

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.
Files changed (99) hide show
  1. package/dist/components/Chat/Chat/Chat.svelte +53 -0
  2. package/dist/components/Chat/Chat/Chat.svelte.d.ts +4 -0
  3. package/dist/components/Chat/Chat/chat.variants.d.ts +20 -0
  4. package/dist/components/Chat/Chat/chat.variants.js +15 -0
  5. package/dist/components/Chat/Chat/index.d.ts +47 -0
  6. package/dist/components/Chat/Chat/index.js +2 -0
  7. package/dist/components/Chat/ChatMessage/ChatMessage.svelte +342 -0
  8. package/dist/components/Chat/ChatMessage/ChatMessage.svelte.d.ts +4 -0
  9. package/dist/components/Chat/ChatMessage/chat-message.variants.d.ts +138 -0
  10. package/dist/components/Chat/ChatMessage/chat-message.variants.js +118 -0
  11. package/dist/components/Chat/ChatMessage/index.d.ts +102 -0
  12. package/dist/components/Chat/ChatMessage/index.js +2 -0
  13. package/dist/components/Chat/ChatMessageList/ChatMessageList.svelte +301 -0
  14. package/dist/components/Chat/ChatMessageList/ChatMessageList.svelte.d.ts +6 -0
  15. package/dist/components/Chat/ChatMessageList/chat-message-list.variants.d.ts +23 -0
  16. package/dist/components/Chat/ChatMessageList/chat-message-list.variants.js +32 -0
  17. package/dist/components/Chat/ChatMessageList/chat-scroll.d.ts +45 -0
  18. package/dist/components/Chat/ChatMessageList/chat-scroll.js +52 -0
  19. package/dist/components/Chat/ChatMessageList/index.d.ts +93 -0
  20. package/dist/components/Chat/ChatMessageList/index.js +3 -0
  21. package/dist/components/Chat/CitationChip/CitationChip.svelte +107 -0
  22. package/dist/components/Chat/CitationChip/CitationChip.svelte.d.ts +4 -0
  23. package/dist/components/Chat/CitationChip/citation-chip.variants.d.ts +40 -0
  24. package/dist/components/Chat/CitationChip/citation-chip.variants.js +42 -0
  25. package/dist/components/Chat/CitationChip/index.d.ts +69 -0
  26. package/dist/components/Chat/CitationChip/index.js +2 -0
  27. package/dist/components/Chat/CodeBlock/CodeBlock.svelte +120 -0
  28. package/dist/components/Chat/CodeBlock/CodeBlock.svelte.d.ts +4 -0
  29. package/dist/components/Chat/CodeBlock/code-block.variants.d.ts +40 -0
  30. package/dist/components/Chat/CodeBlock/code-block.variants.js +51 -0
  31. package/dist/components/Chat/CodeBlock/index.d.ts +55 -0
  32. package/dist/components/Chat/CodeBlock/index.js +2 -0
  33. package/dist/components/Chat/PromptInput/PromptInput.svelte +432 -0
  34. package/dist/components/Chat/PromptInput/PromptInput.svelte.d.ts +4 -0
  35. package/dist/components/Chat/PromptInput/index.d.ts +165 -0
  36. package/dist/components/Chat/PromptInput/index.js +2 -0
  37. package/dist/components/Chat/PromptInput/prompt-input.variants.d.ts +90 -0
  38. package/dist/components/Chat/PromptInput/prompt-input.variants.js +102 -0
  39. package/dist/components/Chat/ReasoningDisclosure/ReasoningDisclosure.svelte +107 -0
  40. package/dist/components/Chat/ReasoningDisclosure/ReasoningDisclosure.svelte.d.ts +4 -0
  41. package/dist/components/Chat/ReasoningDisclosure/index.d.ts +85 -0
  42. package/dist/components/Chat/ReasoningDisclosure/index.js +2 -0
  43. package/dist/components/Chat/ReasoningDisclosure/reasoning-disclosure.variants.d.ts +20 -0
  44. package/dist/components/Chat/ReasoningDisclosure/reasoning-disclosure.variants.js +31 -0
  45. package/dist/components/Chat/StreamingMarkdown/MdBlock.svelte +99 -0
  46. package/dist/components/Chat/StreamingMarkdown/MdBlock.svelte.d.ts +9 -0
  47. package/dist/components/Chat/StreamingMarkdown/MdInline.svelte +82 -0
  48. package/dist/components/Chat/StreamingMarkdown/MdInline.svelte.d.ts +9 -0
  49. package/dist/components/Chat/StreamingMarkdown/StreamingMarkdown.svelte +118 -0
  50. package/dist/components/Chat/StreamingMarkdown/StreamingMarkdown.svelte.d.ts +4 -0
  51. package/dist/components/Chat/StreamingMarkdown/index.d.ts +86 -0
  52. package/dist/components/Chat/StreamingMarkdown/index.js +2 -0
  53. package/dist/components/Chat/StreamingMarkdown/md-context.d.ts +58 -0
  54. package/dist/components/Chat/StreamingMarkdown/md-context.js +1 -0
  55. package/dist/components/Chat/StreamingMarkdown/streaming-markdown.variants.d.ts +145 -0
  56. package/dist/components/Chat/StreamingMarkdown/streaming-markdown.variants.js +73 -0
  57. package/dist/components/Chat/ToolCallCard/ToolCallCard.svelte +174 -0
  58. package/dist/components/Chat/ToolCallCard/ToolCallCard.svelte.d.ts +4 -0
  59. package/dist/components/Chat/ToolCallCard/index.d.ts +84 -0
  60. package/dist/components/Chat/ToolCallCard/index.js +2 -0
  61. package/dist/components/Chat/ToolCallCard/tool-call-card.variants.d.ts +38 -0
  62. package/dist/components/Chat/ToolCallCard/tool-call-card.variants.js +38 -0
  63. package/dist/components/Chat/chat.types.d.ts +82 -0
  64. package/dist/components/Chat/chat.types.js +7 -0
  65. package/dist/components/Chat/index.d.ts +22 -0
  66. package/dist/components/Chat/index.js +14 -0
  67. package/dist/components/Chat/markdown/blocks.d.ts +54 -0
  68. package/dist/components/Chat/markdown/blocks.js +462 -0
  69. package/dist/components/Chat/markdown/inline.d.ts +31 -0
  70. package/dist/components/Chat/markdown/inline.js +446 -0
  71. package/dist/components/Chat/markdown/repair.d.ts +23 -0
  72. package/dist/components/Chat/markdown/repair.js +337 -0
  73. package/dist/components/Chat/markdown/streaming-harness.d.ts +23 -0
  74. package/dist/components/Chat/markdown/streaming-harness.js +62 -0
  75. package/dist/components/Chat/markdown/types.d.ts +139 -0
  76. package/dist/components/Chat/markdown/types.js +13 -0
  77. package/dist/components/Chat/markdown/url-policy.d.ts +33 -0
  78. package/dist/components/Chat/markdown/url-policy.js +109 -0
  79. package/dist/components/FileUpload/FileUpload.svelte +35 -123
  80. package/dist/components/FileUpload/FileUpload.svelte.d.ts +1 -1
  81. package/dist/components/FileUpload/index.d.ts +2 -28
  82. package/dist/components/index.d.ts +1 -0
  83. package/dist/components/index.js +1 -0
  84. package/dist/primitives/Collapsible/Collapsible.svelte +5 -0
  85. package/dist/primitives/SplitPane/SplitPane.svelte +293 -0
  86. package/dist/primitives/SplitPane/SplitPane.svelte.d.ts +4 -0
  87. package/dist/primitives/SplitPane/index.d.ts +88 -0
  88. package/dist/primitives/SplitPane/index.js +2 -0
  89. package/dist/primitives/SplitPane/split-pane.utils.d.ts +73 -0
  90. package/dist/primitives/SplitPane/split-pane.utils.js +94 -0
  91. package/dist/primitives/SplitPane/split-pane.variants.d.ts +40 -0
  92. package/dist/primitives/SplitPane/split-pane.variants.js +56 -0
  93. package/dist/primitives/index.d.ts +2 -0
  94. package/dist/primitives/index.js +1 -0
  95. package/dist/utils/file-intake.d.ts +78 -0
  96. package/dist/utils/file-intake.js +144 -0
  97. package/dist/utils/index.d.ts +1 -0
  98. package/dist/utils/index.js +1 -0
  99. package/package.json +3 -3
@@ -0,0 +1,174 @@
1
+ <script lang="ts">
2
+ import { untrack } from 'svelte';
3
+ import { Badge, Collapsible } from '../../../primitives';
4
+ import { getBlocksConfig, resolveSlotClasses } from '../../../provider';
5
+ import { resolveIcon } from '../../../icons';
6
+ import ChevronDownIconDefault from '../../../icons/ChevronDownIcon.svelte';
7
+ import CoreSpinner from '../../../internal/core/CoreSpinner.svelte';
8
+ import CodeBlock from '../CodeBlock/CodeBlock.svelte';
9
+ import { toolCallCardVariants } from './tool-call-card.variants';
10
+ import type { ToolCallCardProps } from './index';
11
+
12
+ const ChevronDownIcon = resolveIcon('chevronDown', ChevronDownIconDefault);
13
+
14
+ let {
15
+ toolCall,
16
+ open = $bindable(),
17
+ defaultOpen,
18
+ onOpenChange,
19
+ children,
20
+ pendingLabel = 'Pending',
21
+ runningLabel = 'Running',
22
+ completeLabel = 'Done',
23
+ errorLabel = 'Failed',
24
+ inputLabel = 'Input',
25
+ outputLabel = 'Output',
26
+ class: className,
27
+ unstyled: unstyledProp = false,
28
+ slotClasses: slotClassesProp = {},
29
+ preset,
30
+ ...restProps
31
+ }: ToolCallCardProps = $props();
32
+
33
+ const blocksConfig = getBlocksConfig();
34
+ const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
35
+
36
+ // Forward arbitrary root attributes onto the underlying Collapsible without
37
+ // re-deriving its (very wide) props union: spreading the typed `HTMLDivElement`
38
+ // rest here makes svelte-check try to reconcile HTMLAttributes' nullable
39
+ // `title` against Collapsible's narrowed one and blows the union-complexity
40
+ // budget. A plain record spread carries the attributes through cleanly.
41
+ const rootProps = $derived(restProps as Record<string, unknown>);
42
+
43
+ const styles = toolCallCardVariants();
44
+ const slotClasses = $derived(
45
+ resolveSlotClasses(blocksConfig, 'ToolCallCard', preset, {}, slotClassesProp)
46
+ );
47
+
48
+ function cls(name: keyof typeof slotClasses, extra?: string | (string | undefined)[]) {
49
+ const extras = Array.isArray(extra) ? extra : [extra];
50
+ if (unstyled) {
51
+ return [slotClasses?.[name], ...extras].filter(Boolean).join(' ');
52
+ }
53
+ const slotFns = styles as Record<string, (args: { class?: unknown }) => string>;
54
+ return slotFns[name]({ class: [slotClasses?.[name], ...extras] });
55
+ }
56
+
57
+ // Uncontrolled seed: expanded by default only for an already-failed call.
58
+ // svelte-ignore state_referenced_locally
59
+ let internalOpen = $state(defaultOpen ?? toolCall.state === 'error');
60
+ const isOpen = $derived(open !== undefined ? open : internalOpen);
61
+
62
+ // Tracks whether the user has toggled the card. Once they have, auto-open is
63
+ // disabled — a manual choice always wins.
64
+ let userToggled = $state(false);
65
+
66
+ function toggle() {
67
+ userToggled = true;
68
+ const next = !isOpen;
69
+ if (open !== undefined) {
70
+ open = next;
71
+ } else {
72
+ internalOpen = next;
73
+ }
74
+ onOpenChange?.(next);
75
+ }
76
+
77
+ // Auto-open on a GENUINE transition to `error` while mounted — unless the
78
+ // user has toggled. A call that is already failed at mount is covered by the
79
+ // seed above (so an explicit defaultOpen={false} wins there), and the open
80
+ // runs through the same notification path as a manual toggle so a
81
+ // controlled-without-bind consumer can mirror it (review findings, P3 wave).
82
+ // svelte-ignore state_referenced_locally
83
+ let prevState = toolCall.state;
84
+ $effect(() => {
85
+ const state = toolCall.state;
86
+ const wasError = prevState === 'error';
87
+ prevState = state;
88
+ if (state !== 'error' || wasError) return;
89
+ untrack(() => {
90
+ if (userToggled || isOpen) return;
91
+ if (open !== undefined) open = true;
92
+ else internalOpen = true;
93
+ onOpenChange?.(true);
94
+ });
95
+ });
96
+
97
+ const statusLabel = $derived(
98
+ {
99
+ pending: pendingLabel,
100
+ running: runningLabel,
101
+ complete: completeLabel,
102
+ error: errorLabel
103
+ }[toolCall.state]
104
+ );
105
+
106
+ const badgeIntent = $derived(
107
+ toolCall.state === 'complete' ? 'success' : toolCall.state === 'error' ? 'danger' : 'neutral'
108
+ );
109
+
110
+ const isBusy = $derived(toolCall.state === 'pending' || toolCall.state === 'running');
111
+
112
+ // JSON.stringify can throw on circular structures, or return `undefined` for
113
+ // a non-serializable value (function, symbol) — fall back to String() so the
114
+ // CodeBlock always receives a string.
115
+ function stringify(value: unknown): string {
116
+ try {
117
+ const json = JSON.stringify(value, null, 2);
118
+ return json ?? String(value);
119
+ } catch {
120
+ return String(value);
121
+ }
122
+ }
123
+ </script>
124
+
125
+ <Collapsible variant="card" size="sm" open={isOpen} class={className} {...rootProps}>
126
+ {#snippet trigger({ triggerId, contentId })}
127
+ <button
128
+ id={triggerId}
129
+ type="button"
130
+ class={cls('trigger')}
131
+ aria-expanded={isOpen}
132
+ aria-controls={contentId}
133
+ onclick={toggle}
134
+ >
135
+ <span class={cls('triggerLeft')}>
136
+ {#if isBusy}
137
+ <span aria-hidden="true" class="inline-flex">
138
+ <CoreSpinner size="xs" class={cls('spinner')} />
139
+ </span>
140
+ {/if}
141
+ <!-- CoreSpinner and Badge carry no ARIA (the badge is aria-hidden chrome),
142
+ so this sr-only line is the single textual status for assistive tech. -->
143
+ <span class="sr-only">{statusLabel}</span>
144
+ <span class={cls('toolName')}>{toolCall.name}</span>
145
+ </span>
146
+ <span class={cls('triggerRight')}>
147
+ <Badge intent={badgeIntent} variant="soft" aria-hidden="true">{statusLabel}</Badge>
148
+ <ChevronDownIcon class={cls('chevron', isOpen ? 'rotate-180' : undefined)} />
149
+ </span>
150
+ </button>
151
+ {/snippet}
152
+
153
+ {#if children}
154
+ {@render children(toolCall)}
155
+ {:else}
156
+ <div class={cls('body')}>
157
+ {#if toolCall.errorMessage}
158
+ <p class={cls('errorMessage')}>{toolCall.errorMessage}</p>
159
+ {/if}
160
+ {#if toolCall.input !== undefined}
161
+ <div class={cls('section')}>
162
+ <span class={cls('sectionLabel')}>{inputLabel}</span>
163
+ <CodeBlock lang="json" code={stringify(toolCall.input)} />
164
+ </div>
165
+ {/if}
166
+ {#if toolCall.output !== undefined}
167
+ <div class={cls('section')}>
168
+ <span class={cls('sectionLabel')}>{outputLabel}</span>
169
+ <CodeBlock lang="json" code={stringify(toolCall.output)} />
170
+ </div>
171
+ {/if}
172
+ </div>
173
+ {/if}
174
+ </Collapsible>
@@ -0,0 +1,4 @@
1
+ import type { ToolCallCardProps } from './index.js';
2
+ declare const ToolCallCard: import("svelte").Component<ToolCallCardProps, {}, "open">;
3
+ type ToolCallCard = ReturnType<typeof ToolCallCard>;
4
+ export default ToolCallCard;
@@ -0,0 +1,84 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { ChatToolCallPart } from '../chat.types.js';
4
+ import type { ToolCallCardSlots } from './tool-call-card.variants.js';
5
+ /**
6
+ * @description Collapsible card that renders one agent tool-call part (`type: 'tool-call'`)
7
+ * — a status indicator + monospaced tool name in the header, and the JSON input/output (or an
8
+ * error message) in the expandable body. It is the default renderer ChatMessage reaches for on
9
+ * `tool-call` parts (wire it in via `partRenderers`). Opens itself when a call fails so the error
10
+ * is visible without a click; a manual toggle always wins afterwards. Pass a `children` snippet to
11
+ * replace the default JSON body with a domain-specific view of the same part.
12
+ * @tag ai
13
+ * @related ChatMessage
14
+ * @related ReasoningDisclosure
15
+ * @related CodeBlock
16
+ * @stability experimental
17
+ *
18
+ * @example
19
+ * ```svelte
20
+ * <ToolCallCard toolCall={part} />
21
+ * ```
22
+ *
23
+ * @example Domain-specific body via the children snippet
24
+ * ```svelte
25
+ * <ToolCallCard {toolCall}>
26
+ * {#snippet children(call)}
27
+ * <WeatherResult data={call.output} />
28
+ * {/snippet}
29
+ * </ToolCallCard>
30
+ * ```
31
+ */
32
+ export interface ToolCallCardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'class' | 'children'> {
33
+ /** The tool-call part to render. Required. */
34
+ toolCall: ChatToolCallPart;
35
+ /**
36
+ * Whether the card is expanded. Supports `bind:open`. Left uncontrolled, the
37
+ * card starts collapsed for `pending` / `running` / `complete` and expanded
38
+ * for `error`.
39
+ */
40
+ open?: boolean;
41
+ /**
42
+ * Initial expanded state for uncontrolled usage. Defaults to `true` when the
43
+ * call is already in the `error` state, `false` otherwise.
44
+ */
45
+ defaultOpen?: boolean;
46
+ /** Fired once per toggle, after the new open state is applied. */
47
+ onOpenChange?: (open: boolean) => void;
48
+ /**
49
+ * Replace the default JSON input/output body with a custom rendering of the
50
+ * tool-call part. Receives the same `toolCall`. When provided, the built-in
51
+ * error line + input/output sections are not rendered.
52
+ */
53
+ children?: Snippet<[ChatToolCallPart]>;
54
+ /** Header badge label for the `pending` state. @default 'Pending' */
55
+ pendingLabel?: string;
56
+ /** Header badge label for the `running` state. @default 'Running' */
57
+ runningLabel?: string;
58
+ /** Header badge label for the `complete` state. @default 'Done' */
59
+ completeLabel?: string;
60
+ /** Header badge label for the `error` state. @default 'Failed' */
61
+ errorLabel?: string;
62
+ /** Heading above the input code block. @default 'Input' */
63
+ inputLabel?: string;
64
+ /** Heading above the output code block. @default 'Output' */
65
+ outputLabel?: string;
66
+ /** Extra classes merged onto the root card element. */
67
+ class?: string;
68
+ /** Strip the component's default tv() classes (the underlying Collapsible card chrome is kept). */
69
+ unstyled?: boolean;
70
+ /**
71
+ * Per-slot class overrides. Slots: `trigger` (header button), `triggerLeft`,
72
+ * `triggerRight`, `spinner`, `toolName`, `chevron`, `body`, `section`,
73
+ * `sectionLabel`, `errorMessage`.
74
+ */
75
+ slotClasses?: Partial<Record<ToolCallCardSlots, string>>;
76
+ /**
77
+ * Apply a named preset registered via `<BlocksProvider presets={{ ToolCallCard: {...} }}>`.
78
+ * Prefer this over `class` overrides when the requested look falls outside the
79
+ * semantic intent palette.
80
+ */
81
+ preset?: string;
82
+ }
83
+ export { default as ToolCallCard } from './ToolCallCard.svelte';
84
+ export { type ToolCallCardSlots, type ToolCallCardVariants, toolCallCardVariants } from './tool-call-card.variants.js';
@@ -0,0 +1,2 @@
1
+ export { default as ToolCallCard } from './ToolCallCard.svelte';
2
+ export { toolCallCardVariants } from './tool-call-card.variants.js';
@@ -0,0 +1,38 @@
1
+ import { type SlotNames, type VariantProps } from '../../../utils/variants.js';
2
+ export declare const toolCallCardVariants: ((props?: {} | undefined) => {
3
+ trigger: (props?: ({} & {
4
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
5
+ }) | undefined) => string;
6
+ triggerLeft: (props?: ({} & {
7
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
8
+ }) | undefined) => string;
9
+ triggerRight: (props?: ({} & {
10
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
11
+ }) | undefined) => string;
12
+ spinner: (props?: ({} & {
13
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
14
+ }) | undefined) => string;
15
+ toolName: (props?: ({} & {
16
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
17
+ }) | undefined) => string;
18
+ chevron: (props?: ({} & {
19
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
20
+ }) | undefined) => string;
21
+ body: (props?: ({} & {
22
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
23
+ }) | undefined) => string;
24
+ section: (props?: ({} & {
25
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
26
+ }) | undefined) => string;
27
+ sectionLabel: (props?: ({} & {
28
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
29
+ }) | undefined) => string;
30
+ errorMessage: (props?: ({} & {
31
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
32
+ }) | undefined) => string;
33
+ }) & {
34
+ readonly config: import("../../../utils/variants.js").TVConfig;
35
+ };
36
+ export type ToolCallCardVariants = VariantProps<typeof toolCallCardVariants>;
37
+ /** Slot names derived from the tv() config — single source of truth for slotClasses. */
38
+ export type ToolCallCardSlots = SlotNames<typeof toolCallCardVariants>;
@@ -0,0 +1,38 @@
1
+ import { tv } from '../../../utils/variants.js';
2
+ export const toolCallCardVariants = tv({
3
+ slots: {
4
+ // The whole card header IS the collapsible trigger button. Collapsible's
5
+ // card variant only styles the DEFAULT trigger; a custom trigger snippet
6
+ // replaces it, so the horizontal padding / focus ring live here.
7
+ trigger: [
8
+ 'flex w-full items-center justify-between gap-2 px-4 py-2 text-left cursor-pointer',
9
+ 'text-text-primary',
10
+ 'transition-colors duration-[var(--blocks-duration-fast)] ease-out',
11
+ 'hover:bg-surface-hover',
12
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:rounded-sm',
13
+ 'disabled:opacity-50 disabled:cursor-not-allowed'
14
+ ],
15
+ // Status indicator + tool name; min-w-0 lets the mono name truncate.
16
+ triggerLeft: 'flex items-center gap-2 min-w-0',
17
+ // Status badge + chevron; never shrinks so the name gives way first.
18
+ triggerRight: 'flex items-center gap-2 shrink-0',
19
+ // Inline busy indicator (CoreSpinner wrapper) — tertiary tint via text-current.
20
+ spinner: 'text-text-tertiary shrink-0',
21
+ // The invoked tool's identifier, monospaced.
22
+ toolName: 'font-mono text-sm text-text-secondary truncate',
23
+ // Chevron mirrors Collapsible's own spin timing so both animate in sync.
24
+ chevron: [
25
+ 'shrink-0 w-4 h-4 text-text-tertiary',
26
+ 'transition-transform duration-[var(--blocks-collapse-duration)] ease-[var(--blocks-collapse-easing)]',
27
+ 'motion-reduce:duration-[1ms]'
28
+ ],
29
+ // Default body wrapper (input/output sections + error line).
30
+ body: 'flex flex-col gap-3',
31
+ // One labelled block (heading + CodeBlock).
32
+ section: 'flex flex-col gap-1',
33
+ // Small tertiary heading above each code block.
34
+ sectionLabel: 'text-xs font-medium text-text-tertiary',
35
+ // Error message line shown above the sections.
36
+ errorMessage: 'text-sm text-danger'
37
+ }
38
+ });
@@ -0,0 +1,82 @@
1
+ import type { CitationSource } from './CitationChip/index.js';
2
+ /** Author of a chat message. */
3
+ export type ChatRole = 'user' | 'assistant' | 'system';
4
+ /**
5
+ * Lifecycle of a message. `streaming` drives the live-rendering affordances
6
+ * (markdown tail repair, cursor, deferred screen-reader announcement);
7
+ * `error` / `aborted` switch the message to its failure presentation.
8
+ * A message without a status counts as `complete`.
9
+ */
10
+ export type ChatMessageStatus = 'streaming' | 'complete' | 'error' | 'aborted';
11
+ /**
12
+ * One renderable segment of a message. Mirrors the shape of modern
13
+ * model/tool transcripts: interleaved text, reasoning, tool calls, sources
14
+ * and attachments — rendered in order by the ChatMessage component.
15
+ */
16
+ export type ChatMessagePart =
17
+ /** Markdown text, rendered through StreamingMarkdown. */
18
+ {
19
+ type: 'text';
20
+ text: string;
21
+ }
22
+ /** Model reasoning. Collapsed, tertiary presentation; `durationMs` feeds the "Thought for Xs" label. */
23
+ | {
24
+ type: 'reasoning';
25
+ text: string;
26
+ durationMs?: number;
27
+ }
28
+ /** A tool invocation with its lifecycle state. Rendered as a ToolCallCard by default; override via `partRenderers`. */
29
+ | {
30
+ type: 'tool-call';
31
+ id: string;
32
+ name: string;
33
+ state: 'pending' | 'running' | 'complete' | 'error';
34
+ input?: unknown;
35
+ output?: unknown;
36
+ errorMessage?: string;
37
+ }
38
+ /** A cited source. Same shape as CitationSource — also feeds StreamingMarkdown's `sources` for `[id]` markers. */
39
+ | ({
40
+ type: 'source';
41
+ } & CitationSource)
42
+ /**
43
+ * A file attached to the message. `url` is only ever rendered as a
44
+ * policy-checked download link (never as an inline image/iframe) — LLM- or
45
+ * server-supplied URLs are untrusted input.
46
+ */
47
+ | {
48
+ type: 'attachment';
49
+ name: string;
50
+ mimeType: string;
51
+ size?: number;
52
+ url?: string;
53
+ }
54
+ /** Declarative A2UI payload (P4). Validated fail-loud by A2UIView; ignored by default renderers until then. */
55
+ | {
56
+ type: 'a2ui';
57
+ payload: unknown;
58
+ };
59
+ /** The `tool-call` member of {@link ChatMessagePart} — the prop shape of ToolCallCard. */
60
+ export type ChatToolCallPart = Extract<ChatMessagePart, {
61
+ type: 'tool-call';
62
+ }>;
63
+ /** The `reasoning` member of {@link ChatMessagePart} — the prop shape of ReasoningDisclosure. */
64
+ export type ChatReasoningPart = Extract<ChatMessagePart, {
65
+ type: 'reasoning';
66
+ }>;
67
+ /**
68
+ * One message in a conversation. Named `ChatMessageData` because the value
69
+ * export `ChatMessage` is the component that renders it.
70
+ */
71
+ export interface ChatMessageData {
72
+ /** Stable unique id — keyed `{#each}` identity, never an array index. */
73
+ id: string;
74
+ role: ChatRole;
75
+ /** Ordered renderable segments. A plain text answer is `[{ type: 'text', text }]`. */
76
+ parts: ChatMessagePart[];
77
+ createdAt?: Date;
78
+ /** Omitted counts as `complete`. */
79
+ status?: ChatMessageStatus;
80
+ /** Consumer-defined extras (model name, token counts, …). Not rendered by defaults. */
81
+ metadata?: Record<string, unknown>;
82
+ }
@@ -0,0 +1,7 @@
1
+ // Chat conversation data model — the contract between a consumer's transport
2
+ // layer (SSE/fetch/websocket) and the Chat family's rendering components.
3
+ //
4
+ // Deliberately NOT a store: the consumer owns `ChatMessageData[]` (typically
5
+ // `$state` + appends from a stream) and passes it down. Components never
6
+ // mutate messages.
7
+ export {};
@@ -0,0 +1,22 @@
1
+ export type { ChatProps } from './Chat/index.js';
2
+ export * from './Chat/index.js';
3
+ export type { ChatMessageProps, ChatPartRenderers } from './ChatMessage/index.js';
4
+ export * from './ChatMessage/index.js';
5
+ export type { ChatMessageListItemContext, ChatMessageListProps } from './ChatMessageList/index.js';
6
+ export * from './ChatMessageList/index.js';
7
+ export type { CitationChipProps, CitationSource } from './CitationChip/index.js';
8
+ export * from './CitationChip/index.js';
9
+ export type { CodeBlockProps } from './CodeBlock/index.js';
10
+ export * from './CodeBlock/index.js';
11
+ export type { ChatMessageData, ChatMessagePart, ChatMessageStatus, ChatReasoningPart, ChatRole, ChatToolCallPart } from './chat.types.js';
12
+ export { createIncrementalParser, parseMarkdown } from './markdown/blocks.js';
13
+ export { repairMarkdownTail } from './markdown/repair.js';
14
+ export type { BlockNode, IncrementalMarkdownParser, InlineNode, MarkdownBlock, MarkdownDocument, MarkdownParseOptions, MarkdownUrlPolicy } from './markdown/types.js';
15
+ export type { PromptInputProps } from './PromptInput/index.js';
16
+ export * from './PromptInput/index.js';
17
+ export type { ReasoningDisclosureProps } from './ReasoningDisclosure/index.js';
18
+ export * from './ReasoningDisclosure/index.js';
19
+ export type { MarkdownRenderers, StreamingMarkdownProps } from './StreamingMarkdown/index.js';
20
+ export * from './StreamingMarkdown/index.js';
21
+ export type { ToolCallCardProps } from './ToolCallCard/index.js';
22
+ export * from './ToolCallCard/index.js';
@@ -0,0 +1,14 @@
1
+ // Chat family barrel — AI-kit surfaces (conversation, composer, streaming
2
+ // markdown, code display, citations) plus the public pieces of the markdown
3
+ // engine underneath them.
4
+ export * from './Chat/index.js';
5
+ export * from './ChatMessage/index.js';
6
+ export * from './ChatMessageList/index.js';
7
+ export * from './CitationChip/index.js';
8
+ export * from './CodeBlock/index.js';
9
+ export { createIncrementalParser, parseMarkdown } from './markdown/blocks.js';
10
+ export { repairMarkdownTail } from './markdown/repair.js';
11
+ export * from './PromptInput/index.js';
12
+ export * from './ReasoningDisclosure/index.js';
13
+ export * from './StreamingMarkdown/index.js';
14
+ export * from './ToolCallCard/index.js';
@@ -0,0 +1,54 @@
1
+ import type { IncrementalMarkdownParser, MarkdownDocument, MarkdownParseOptions } from './types.js';
2
+ type RawBlock = {
3
+ type: 'paragraph';
4
+ start: number;
5
+ lines: string[];
6
+ } | {
7
+ type: 'heading';
8
+ start: number;
9
+ level: 1 | 2 | 3 | 4 | 5 | 6;
10
+ text: string;
11
+ } | {
12
+ type: 'fence';
13
+ start: number;
14
+ lang?: string;
15
+ code: string[];
16
+ open: boolean;
17
+ } | {
18
+ type: 'list';
19
+ start: number;
20
+ ordered: boolean;
21
+ startNumber?: number;
22
+ lines: string[];
23
+ } | {
24
+ type: 'quote';
25
+ start: number;
26
+ lines: string[];
27
+ } | {
28
+ type: 'table';
29
+ start: number;
30
+ header: string;
31
+ delimiter: string;
32
+ rows: string[];
33
+ } | {
34
+ type: 'hr';
35
+ start: number;
36
+ };
37
+ interface ScanResult {
38
+ blocks: RawBlock[];
39
+ refs: Map<string, {
40
+ href: string;
41
+ title?: string;
42
+ }>;
43
+ /**
44
+ * Label of a reference definition sitting on the final, not-yet-terminated
45
+ * line — its URL may still be streaming in. Such a definition is used for
46
+ * display (one-shot parity if the stream really ends here) but never for
47
+ * settling, and it does not count as "arrived" for invalidation purposes.
48
+ */
49
+ unstableRefLabel?: string;
50
+ }
51
+ export declare function scanBlocks(text: string): ScanResult;
52
+ export declare function parseMarkdown(text: string, options?: MarkdownParseOptions): MarkdownDocument;
53
+ export declare function createIncrementalParser(options?: MarkdownParseOptions): IncrementalMarkdownParser;
54
+ export {};