@factorialco/f0-react 2.22.0 → 2.24.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.
@@ -1 +1 @@
1
- .rich-text-editor-container a.mention:not([data-type=mention]),.rich-text-display-container a.mention:not([data-type=mention]){border-radius:.375rem;background-color:hsl(var(--neutral-10));padding-left:6px!important;padding-right:6px!important;font-weight:500;color:hsl(var(--neutral-100));text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.rich-text-editor-container a.mention:not([data-type=mention]):hover,.rich-text-display-container a.mention:not([data-type=mention]):hover{background-color:hsl(var(--neutral-20))}.rich-text-editor-container a.mention:not([data-type=mention]):focus,.rich-text-display-container a.mention:not([data-type=mention]):focus{outline-style:solid;outline-width:1px;outline-offset:1px;outline-color:hsl(var(--selected-50))}.preserved-selection{background-color:hsl(var(--selected-60) / .2)}.enhance-highlight{background:linear-gradient(90deg,#e5561980,#a1ade580,#e5194380,#e5561980);background-size:300% 100%;animation:enhance-gradient-move 3s linear infinite;border-radius:4px}@keyframes enhance-gradient-move{0%{background-position:0% 50%}to{background-position:100% 50%}}.rich-text-editor-container *::-moz-selection{background-color:transparent!important}.rich-text-editor-container *::selection{background-color:transparent!important}.rich-text-editor-container::-moz-selection{background-color:transparent!important}.rich-text-editor-container::selection{background-color:transparent!important}.rich-text-editor-container p,.rich-text-display-container p{position:relative;margin:0 0 8px}.rich-text-editor-container p:last-child,.rich-text-display-container p:last-child{margin-bottom:0}.rich-text-editor-container h1,.rich-text-display-container h1{margin:0 0 12px;padding:0;font-size:1.625rem;line-height:2rem;letter-spacing:-.01em;font-weight:600}.rich-text-editor-container h2,.rich-text-display-container h2{margin:0 0 10px;padding:0;font-size:1.375rem;line-height:1.75rem;letter-spacing:-.01em;font-weight:500}.rich-text-editor-container h3,.rich-text-display-container h3,.rich-text-editor-container h4,.rich-text-display-container h4{margin:0 0 10px;padding:0;font-size:1rem;line-height:1.5rem;letter-spacing:-.01em;font-weight:500}.rich-text-editor-container ul,.rich-text-display-container ul{margin:0 0 10px;list-style:disc}.rich-text-editor-container ol,.rich-text-display-container ol{margin:0 0 10px;list-style-type:decimal}.rich-text-editor-container a:not([data-type=mention]):not(.mention),.rich-text-display-container a:not([data-type=mention]):not(.mention){cursor:pointer;font-weight:500;color:hsl(var(--neutral-100));text-decoration-line:underline;text-decoration-color:hsl(var(--neutral-40));text-decoration-thickness:1px;text-underline-offset:5px}.rich-text-editor-container a:not([data-type=mention]):not(.mention):hover,.rich-text-display-container a:not([data-type=mention]):not(.mention):hover{text-decoration-color:hsl(var(--neutral-100))}.rich-text-editor-container strong,.rich-text-display-container strong{font-weight:600}.rich-text-editor-container em,.rich-text-display-container em{font-style:italic}.rich-text-editor-container u,.rich-text-display-container u{text-decoration-line:underline}.rich-text-editor-container s,.rich-text-display-container s{text-decoration-line:line-through}.rich-text-editor-container .f1-bullet-list,.rich-text-display-container .f1-bullet-list{list-style-type:disc}.rich-text-editor-container .f1-ordered-list,.rich-text-display-container .f1-ordered-list{list-style-type:decimal}.rich-text-editor-container ul,.rich-text-editor-container ol,.rich-text-display-container ul,.rich-text-display-container ol{padding-left:20px}.rich-text-editor-container .f1-ordered-list p,.rich-text-display-container .f1-ordered-list p,.rich-text-editor-container .f1-bullet-list p,.rich-text-display-container .f1-bullet-list p{margin-left:8px}.rich-text-editor-container li,.rich-text-display-container li{margin-bottom:8px}.rich-text-editor-container pre,.rich-text-display-container pre{position:relative;margin:16px 0;overflow-x:auto;white-space:pre-wrap;border-radius:.75rem;background-color:hsl(var(--neutral-10));padding:8px}.rich-text-editor-container code,.rich-text-display-container code{font-size:.75rem;line-height:1rem;font-family:Menlo,Consolas,Monaco,monospace}.rich-text-editor-container blockquote,.rich-text-display-container blockquote{margin:0 0 10px;border-width:0px;border-left-width:4px;border-style:solid;border-color:hsl(var(--neutral-30));padding-left:16px}.ProseMirror:focus,.rich-text-display-container:focus{outline:2px solid transparent;outline-offset:2px}.ProseMirror-selectednode{outline:none!important}.rich-text-editor-container hr,.rich-text-display-container hr{margin-top:12px;margin-bottom:12px;border-width:0px;border-top-width:1px;border-color:hsl(var(--neutral-30))}.rich-text-editor-container mark,.rich-text-display-container mark{border-radius:.375rem;background-color:hsl(var(--promote-50) / .3);padding:2px;color:hsl(var(--neutral-100))}.rich-text-editor-container p:empty:before,.rich-text-display-container p:empty:before{content:" "}.rich-text-editor-container ul[data-type=taskList],.rich-text-display-container ul[data-type=taskList]{padding-left:0}.shadow-editor-tools{box-shadow:0 -4px 20px #0d162514}.scrollbar-macos{scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track)}.scrollbar-macos::-webkit-scrollbar{width:8px}.scrollbar-macos::-webkit-scrollbar-track{background:var(--scrollbar-track)}.scrollbar-macos::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb);border-radius:9999px;border:2px solid transparent;background-clip:padding-box}.scrollbar-macos::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover)}.f1-task-item{margin-bottom:8px;display:flex;list-style-type:none;gap:8px}.f1-task-item div{flex:1 1 0%}.f1-task-item input{-moz-appearance:none;appearance:none;-webkit-appearance:none;position:relative;height:1.25rem;width:1.25rem;flex-shrink:0;cursor:pointer;border-radius:.375rem;border-width:1px;border-style:solid;border-color:hsl(var(--neutral-30));background-color:hsl(var(--neutral-0));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.f1-task-item input:hover{border-color:hsl(var(--neutral-40))}.f1-task-item input:checked{border-color:hsl(var(--selected-50) / .4);background-color:hsl(var(--selected-60))}.f1-task-item[data-checked=true]>div>p{color:hsl(var(--neutral-50));text-decoration-line:line-through}.f1-task-item input:checked:after{position:absolute;top:50%;left:50%;height:1rem;width:1rem;--tw-translate-x: -50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));content:"";background-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.75 16.75L17.75 7.25004' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M6.25 11.75L10.75 16.75' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-position:center;background-repeat:no-repeat;background-size:contain}.f1-task-item-content{min-width:0px;flex:1 1 0%;outline:none}.f1-task-item[data-checked=true] .f1-task-item-content{color:hsl(var(--neutral-50));text-decoration-line:line-through}.f1-task-item-content p{margin:0}.tiptap p.is-empty:before{pointer-events:none;float:left;display:block;height:0px;max-width:100%;text-overflow:ellipsis;white-space:nowrap;color:hsl(var(--neutral-40));content:attr(data-placeholder)}.editor-mood-tracker p{margin:0}.rich-text-details{margin-top:0;margin-bottom:0;display:flex;gap:8px;padding-top:4px;padding-bottom:4px;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.rich-text-details summary{font-size:1rem;line-height:1.5rem;letter-spacing:-.01em;font-weight:600}.rich-text-details summary::marker{content:""}.rich-text-details>button{display:flex;height:1.5rem;width:1.5rem;align-items:center;justify-content:center;border-radius:.375rem;background-color:hsl(var(--neutral-0))}.rich-text-details>button:hover{background-color:hsl(var(--neutral-10))}.rich-text-details>button:before{font-size:.625rem;line-height:.75rem;color:hsl(var(--neutral-100));content:"▶"}.rich-text-details.is-open>button:before{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rich-text-details>div{display:flex;width:100%;flex-direction:column;gap:8px}.rich-text-details>div>[data-type=detailsContent]>:last-child{margin-bottom:8px}.rich-text-details.rich-text-details{margin-bottom:8px}.image-resizable-wrapper{max-width:100%}.image-resize-handle{z-index:10}.shine-text{background:linear-gradient(90deg,#888 0% 35%,#f5f5f5 50%,#888 65% 100%);background-size:200% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:shine 3s ease-in-out infinite}@keyframes shine{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes globe-spin-enter{0%{opacity:0;transform:scale(.8);filter:blur(4px)}to{opacity:1;transform:scale(1);filter:blur(0)}}@keyframes globe-spin-breathe{0%,to{transform:scale(1)}50%{transform:scale(1.035)}}.globe-spin-anim{animation:globe-spin-enter .5s cubic-bezier(.33,1,.68,1) both,globe-spin-breathe 3.6s ease-in-out .5s infinite}@media(prefers-reduced-motion:reduce){.globe-spin-anim{animation:none}}
1
+ .rich-text-editor-container a.mention:not([data-type=mention]),.rich-text-display-container a.mention:not([data-type=mention]){border-radius:.375rem;background-color:hsl(var(--neutral-10));padding-left:6px!important;padding-right:6px!important;font-weight:500;color:hsl(var(--neutral-100));text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.rich-text-editor-container a.mention:not([data-type=mention]):hover,.rich-text-display-container a.mention:not([data-type=mention]):hover{background-color:hsl(var(--neutral-20))}.rich-text-editor-container a.mention:not([data-type=mention]):focus,.rich-text-display-container a.mention:not([data-type=mention]):focus{outline-style:solid;outline-width:1px;outline-offset:1px;outline-color:hsl(var(--selected-50))}.preserved-selection{background-color:hsl(var(--selected-60) / .2)}.enhance-highlight{background:linear-gradient(90deg,#e5561980,#a1ade580,#e5194380,#e5561980);background-size:300% 100%;animation:enhance-gradient-move 3s linear infinite;border-radius:4px}@keyframes enhance-gradient-move{0%{background-position:0% 50%}to{background-position:100% 50%}}.rich-text-editor-container *::-moz-selection{background-color:transparent!important}.rich-text-editor-container *::selection{background-color:transparent!important}.rich-text-editor-container::-moz-selection{background-color:transparent!important}.rich-text-editor-container::selection{background-color:transparent!important}.rich-text-editor-container p,.rich-text-display-container p{position:relative;margin:0 0 8px}.rich-text-editor-container p:last-child,.rich-text-display-container p:last-child{margin-bottom:0}.rich-text-editor-container h1,.rich-text-display-container h1{margin:0 0 12px;padding:0;font-size:1.625rem;line-height:2rem;letter-spacing:-.01em;font-weight:600}.rich-text-editor-container h2,.rich-text-display-container h2{margin:0 0 10px;padding:0;font-size:1.375rem;line-height:1.75rem;letter-spacing:-.01em;font-weight:500}.rich-text-editor-container h3,.rich-text-display-container h3,.rich-text-editor-container h4,.rich-text-display-container h4{margin:0 0 10px;padding:0;font-size:1rem;line-height:1.5rem;letter-spacing:-.01em;font-weight:500}.rich-text-editor-container ul,.rich-text-display-container ul{margin:0 0 10px;list-style:disc}.rich-text-editor-container ol,.rich-text-display-container ol{margin:0 0 10px;list-style-type:decimal}.rich-text-editor-container a:not([data-type=mention]):not(.mention),.rich-text-display-container a:not([data-type=mention]):not(.mention){cursor:pointer;font-weight:500;color:hsl(var(--neutral-100));text-decoration-line:underline;text-decoration-color:hsl(var(--neutral-40));text-decoration-thickness:1px;text-underline-offset:5px}.rich-text-editor-container a:not([data-type=mention]):not(.mention):hover,.rich-text-display-container a:not([data-type=mention]):not(.mention):hover{text-decoration-color:hsl(var(--neutral-100))}.rich-text-editor-container strong,.rich-text-display-container strong{font-weight:600}.rich-text-editor-container em,.rich-text-display-container em{font-style:italic}.rich-text-editor-container u,.rich-text-display-container u{text-decoration-line:underline}.rich-text-editor-container s,.rich-text-display-container s{text-decoration-line:line-through}.rich-text-editor-container .f1-bullet-list,.rich-text-display-container .f1-bullet-list{list-style-type:disc}.rich-text-editor-container .f1-ordered-list,.rich-text-display-container .f1-ordered-list{list-style-type:decimal}.rich-text-editor-container ul,.rich-text-editor-container ol,.rich-text-display-container ul,.rich-text-display-container ol{padding-left:20px}.rich-text-editor-container .f1-ordered-list p,.rich-text-display-container .f1-ordered-list p,.rich-text-editor-container .f1-bullet-list p,.rich-text-display-container .f1-bullet-list p{margin-left:8px}.rich-text-editor-container li,.rich-text-display-container li{margin-bottom:8px}.rich-text-editor-container pre,.rich-text-display-container pre{position:relative;margin:16px 0;overflow-x:auto;white-space:pre-wrap;border-radius:.75rem;background-color:hsl(var(--neutral-10));padding:8px}.rich-text-editor-container code,.rich-text-display-container code{font-size:.75rem;line-height:1rem;font-family:Menlo,Consolas,Monaco,monospace}.rich-text-editor-container blockquote,.rich-text-display-container blockquote{margin:0 0 10px;border-width:0px;border-left-width:4px;border-style:solid;border-color:hsl(var(--neutral-30));padding-left:16px}.ProseMirror:focus,.rich-text-display-container:focus{outline:2px solid transparent;outline-offset:2px}.ProseMirror-selectednode{outline:none!important}.rich-text-editor-container hr,.rich-text-display-container hr{margin-top:12px;margin-bottom:12px;border-width:0px;border-top-width:1px;border-color:hsl(var(--neutral-30))}.rich-text-editor-container mark,.rich-text-display-container mark{border-radius:.375rem;background-color:hsl(var(--promote-50) / .3);padding:2px;color:hsl(var(--neutral-100))}.rich-text-editor-container p:empty:before,.rich-text-display-container p:empty:before{content:" "}.rich-text-editor-container ul[data-type=taskList],.rich-text-display-container ul[data-type=taskList]{padding-left:0}.shadow-editor-tools{box-shadow:0 -4px 20px #0d162514}.scrollbar-macos{scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track)}.scrollbar-macos::-webkit-scrollbar{width:8px}.scrollbar-macos::-webkit-scrollbar-track{background:var(--scrollbar-track)}.scrollbar-macos::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb);border-radius:9999px;border:2px solid transparent;background-clip:padding-box}.scrollbar-macos::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover)}.f1-task-item{margin-bottom:8px;display:flex;list-style-type:none;gap:8px}.f1-task-item div{flex:1 1 0%}.f1-task-item input{-moz-appearance:none;appearance:none;-webkit-appearance:none;position:relative;height:1.25rem;width:1.25rem;flex-shrink:0;cursor:pointer;border-radius:.375rem;border-width:1px;border-style:solid;border-color:hsl(var(--neutral-30));background-color:hsl(var(--neutral-0));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.f1-task-item input:hover{border-color:hsl(var(--neutral-40))}.f1-task-item input:checked{border-color:hsl(var(--selected-50) / .4);background-color:hsl(var(--selected-60))}.f1-task-item[data-checked=true]>div>p{color:hsl(var(--neutral-50));text-decoration-line:line-through}.f1-task-item input:checked:after{position:absolute;top:50%;left:50%;height:1rem;width:1rem;--tw-translate-x: -50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));content:"";background-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.75 16.75L17.75 7.25004' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M6.25 11.75L10.75 16.75' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-position:center;background-repeat:no-repeat;background-size:contain}.f1-task-item-content{min-width:0px;flex:1 1 0%;outline:none}.f1-task-item[data-checked=true] .f1-task-item-content{color:hsl(var(--neutral-50));text-decoration-line:line-through}.f1-task-item-content p{margin:0}.tiptap p.is-empty:before{pointer-events:none;float:left;display:block;height:0px;max-width:100%;text-overflow:ellipsis;white-space:nowrap;color:hsl(var(--neutral-40));content:attr(data-placeholder)}.editor-mood-tracker p{margin:0}.rich-text-details{margin-top:0;margin-bottom:0;display:flex;gap:8px;padding-top:4px;padding-bottom:4px;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.rich-text-details summary{font-size:1rem;line-height:1.5rem;letter-spacing:-.01em;font-weight:600}.rich-text-details summary::marker{content:""}.rich-text-details>button{display:flex;height:1.5rem;width:1.5rem;align-items:center;justify-content:center;border-radius:.375rem;background-color:hsl(var(--neutral-0))}.rich-text-details>button:hover{background-color:hsl(var(--neutral-10))}.rich-text-details>button:before{font-size:.625rem;line-height:.75rem;color:hsl(var(--neutral-100));content:"▶"}.rich-text-details.is-open>button:before{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rich-text-details>div{display:flex;width:100%;flex-direction:column;gap:8px}.rich-text-details>div>[data-type=detailsContent]>:last-child{margin-bottom:8px}.rich-text-details.rich-text-details{margin-bottom:8px}.image-resizable-wrapper{max-width:100%}.image-resize-handle{z-index:10}
package/dist/ai.d.ts CHANGED
@@ -1,12 +1,10 @@
1
1
  import { AgentState } from '@livekit/components-react';
2
- import { AIMessage } from '@copilotkit/shared';
3
2
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
4
3
  import { baseColors } from '@factorialco/f0-core';
5
4
  import { ClassValue } from 'cva';
6
5
  import { CompanyItemProps } from './types';
7
6
  import { ComponentProps } from 'react';
8
7
  import { ComponentType } from 'react';
9
- import { CopilotKitProps } from '@copilotkit/react-core';
10
8
  import { CSSProperties } from 'react';
11
9
  import { EmployeeItemProps } from './types';
12
10
  import { F0TagBalanceProps as F0TagBalanceProps_2 } from './types';
@@ -19,7 +17,6 @@ import { ForwardRefExoticComponent } from 'react';
19
17
  import { ItemProps } from './types';
20
18
  import { JSX as JSX_2 } from 'react';
21
19
  import { LocalAudioTrack } from 'livekit-client';
22
- import { Message } from '@copilotkit/shared';
23
20
  import { Props as Props_3 } from './types';
24
21
  import * as React_2 from 'react';
25
22
  import { ReactElement } from 'react';
@@ -137,6 +134,11 @@ export declare type AiChatMode = "chat" | "voice";
137
134
  */
138
135
  export declare type AiChatProviderProps = {
139
136
  enabled?: boolean;
137
+ /**
138
+ * Greeting phrase(s) shown by the welcome screen when the chat is empty.
139
+ * A single string renders once; an array rotates through phrases. Purely
140
+ * UI config — does not affect runtime behavior.
141
+ */
140
142
  initialMessage?: string | string[];
141
143
  welcomeScreenSuggestions?: WelcomeScreenSuggestion[];
142
144
  disclaimer?: AiChatDisclaimer;
@@ -214,27 +216,38 @@ export declare type AiChatProviderProps = {
214
216
  * File attachment configuration. When provided, enables file uploads in the chat.
215
217
  */
216
218
  fileAttachments?: AiChatFileAttachmentConfig;
217
- onThumbsUp?: (message: AIMessage, { threadId, feedback }: {
219
+ onThumbsUp?: (message: F0AIMessage, { threadId, feedback }: {
218
220
  threadId: string;
219
221
  feedback: string;
220
222
  }) => void;
221
- onThumbsDown?: (message: AIMessage, { threadId, feedback }: {
223
+ onThumbsDown?: (message: F0AIMessage, { threadId, feedback }: {
222
224
  threadId: string;
223
225
  feedback: string;
224
226
  }) => void;
225
227
  tracking?: AiChatTrackingOptions;
226
228
  /**
227
- * Optional hook called before a user message is sent. Return false to block submission.
229
+ * Optional name of the AI agent. Forwarded to the host runtime adapter
230
+ * (mock in stories, CopilotKit in factorial) — f0 itself only stores it.
228
231
  */
229
- onBeforeSendMessage?: () => boolean | Promise<boolean>;
232
+ agent?: string;
230
233
  /**
231
- * Optional fetch implementation for AI runtime requests owned by F0.
234
+ * Slot elements rendered inside `<F0AiChat />`. Host apps (factorial in
235
+ * production, the mock runtime in stories) provide their own connected
236
+ * wrappers — f0 ships only the shell. Passing slots here makes them
237
+ * available to any `<F0AiChat />` mounted under this provider (used by
238
+ * `ApplicationFrame`, which renders the chat itself).
232
239
  */
233
- runtimeFetch?: typeof fetch;
234
- } & Pick<CopilotKitProps, "agent" | "credentials" | "children" | "runtimeUrl" | "showDevConsole" | "threadId" | "headers">;
240
+ chatHeader?: React.ReactNode;
241
+ chatMessages?: React.ReactNode;
242
+ chatInput?: React.ReactNode;
243
+ /** Children rendered inside the provider. */
244
+ children?: React.ReactNode;
245
+ };
235
246
 
236
247
  /**
237
- * Return value type for the useAiChat hook
248
+ * Return value type for the useAiChat hook. UI-only by design — message
249
+ * state and actions (send, clear, loadThread, etc.) live in the runtime
250
+ * adapter and are read via `useAiChatRuntime()`.
238
251
  */
239
252
  declare type AiChatProviderReturnValue = {
240
253
  enabled: boolean;
@@ -243,76 +256,22 @@ declare type AiChatProviderReturnValue = {
243
256
  setOpen: React.Dispatch<React.SetStateAction<boolean>>;
244
257
  shouldPlayEntranceAnimation: boolean;
245
258
  setShouldPlayEntranceAnimation: React.Dispatch<React.SetStateAction<boolean>>;
246
- tmp_setAgent: (agent?: string) => void;
259
+ setAgent: React.Dispatch<React.SetStateAction<string | undefined>>;
247
260
  placeholders: string[];
248
261
  setPlaceholders: React.Dispatch<React.SetStateAction<string[]>>;
249
- /**
250
- * The initial message to display in the chat
251
- */
252
262
  initialMessage?: string | string[];
253
263
  setInitialMessage: React.Dispatch<React.SetStateAction<string | string[] | undefined>>;
254
264
  welcomeScreenSuggestions: WelcomeScreenSuggestion[];
255
265
  setWelcomeScreenSuggestions: React.Dispatch<React.SetStateAction<WelcomeScreenSuggestion[]>>;
256
- onThumbsUp?: (message: AIMessage, { threadId, feedback }: {
266
+ onThumbsUp?: (message: F0AIMessage, { threadId, feedback }: {
257
267
  threadId: string;
258
268
  feedback: string;
259
269
  }) => void;
260
- onThumbsDown?: (message: AIMessage, { threadId, feedback }: {
270
+ onThumbsDown?: (message: F0AIMessage, { threadId, feedback }: {
261
271
  threadId: string;
262
272
  feedback: string;
263
273
  }) => void;
264
274
  tracking?: AiChatTrackingOptions;
265
- /**
266
- * Optional hook called before a user message is sent. Return false to block submission.
267
- */
268
- onBeforeSendMessage?: () => boolean | Promise<boolean>;
269
- /**
270
- * Fetch implementation for AI runtime requests owned by F0.
271
- */
272
- runtimeFetch: typeof fetch;
273
- /**
274
- * Clear/reset the chat conversation
275
- */
276
- clear: () => void;
277
- /* Excluded from this release type: setClearFunction */
278
- /**
279
- * Title of the currently loaded thread, or null for new conversations
280
- */
281
- currentThreadTitle: string | null;
282
- /**
283
- * Load a thread by ID and set its title in the header
284
- */
285
- loadThread: (threadId: string, title: string) => void;
286
- /* Excluded from this release type: setLoadThreadFunction */
287
- /** Whether a thread's messages are currently being fetched */
288
- isLoadingThread: boolean;
289
- /* Excluded from this release type: setIsLoadingThread */
290
- /**
291
- * Send a message to the chat
292
- * @param message - The message content as a string, or a full Message object
293
- */
294
- sendMessage: (message: string | Message) => void;
295
- /* Excluded from this release type: setSendMessageFunction */
296
- /**
297
- * Append messages to the current conversation.
298
- * Useful for injecting pre-built assistant responses (e.g. dashboards)
299
- * from outside the chat. IDs are generated internally.
300
- *
301
- * @param options.persist - Whether to persist messages to the backend thread.
302
- * Defaults to `true`. Pass `false` for client-only display messages that
303
- * should not create or modify a backend thread (e.g. seed messages).
304
- */
305
- appendMessages: (messages: AppendMessage[], options?: {
306
- persist?: boolean;
307
- }) => void;
308
- /* Excluded from this release type: setAppendMessagesFunction */
309
- /**
310
- * Atomically clear the conversation and inject new messages.
311
- * Starts a fresh thread without the race condition of calling
312
- * clear() + appendMessages() separately.
313
- */
314
- clearAndAppend: (messages: AppendMessage[]) => void;
315
- /* Excluded from this release type: setReplaceMessagesFunction */
316
275
  /**
317
276
  * Current width of the chat window (for resizable mode)
318
277
  */
@@ -355,14 +314,14 @@ declare type AiChatProviderReturnValue = {
355
314
  * Set the footer content. Use this to update the footer from outside the provider (e.g. per page/route).
356
315
  */
357
316
  setFooter: React.Dispatch<React.SetStateAction<React.ReactNode | undefined>>;
358
- /** Whether the assistant is currently generating a response */
359
- inProgress: boolean;
360
- /** Set the in-progress state (synced from CopilotKit's isLoading) */
361
- setInProgress: (value: boolean) => void;
362
- /** The current clarifying question shown in the textarea, or null if none */
363
- clarifyingQuestion: ClarifyingQuestionState | null;
364
- /** Set the current clarifying question (or null to dismiss) */
365
- setClarifyingQuestion: React.Dispatch<React.SetStateAction<ClarifyingQuestionState | null>>;
317
+ /**
318
+ * True while a clarifying flow is active. F0 uses this flag to freeze
319
+ * layout / disable file drop / hide disclaimer. The actual panel state
320
+ * is owned by the host (factorial); F0 only sees the boolean.
321
+ */
322
+ isClarifying: boolean;
323
+ /** Set the clarifying flag. */
324
+ setIsClarifying: React.Dispatch<React.SetStateAction<boolean>>;
366
325
  /**
367
326
  * Whether files are currently being dragged over the chat window.
368
327
  * Set by the ChatWindow drag listeners and read by the DropOverlay
@@ -392,7 +351,7 @@ declare type AiChatProviderReturnValue = {
392
351
  pendingQuote: PendingQuote | null;
393
352
  /** Set the pending quote (pass null to clear). */
394
353
  setPendingQuote: React.Dispatch<React.SetStateAction<PendingQuote | null>>;
395
- } & Pick<AiChatState, "agent" | "disclaimer" | "resizable" | "entityRefs" | "canvasActions" | "canvasEntities" | "credits" | "employeeCredits" | "creditWarning" | "fileAttachments"> & {
354
+ } & Pick<AiChatState, "agent" | "chatHeader" | "chatMessages" | "chatInput" | "disclaimer" | "resizable" | "entityRefs" | "canvasActions" | "canvasEntities" | "credits" | "employeeCredits" | "creditWarning" | "fileAttachments"> & {
396
355
  /** The current canvas content, or null when canvas is closed */
397
356
  canvasContent: CanvasContent | null;
398
357
  /** Open the canvas panel with the given content */
@@ -408,12 +367,17 @@ declare type AiChatProviderReturnValue = {
408
367
  };
409
368
 
410
369
  /**
411
- * Internal state for the AiChat provider
370
+ * Internal state for the AiChat provider. Pure UI / config concerns —
371
+ * message-runtime concerns (sendMessage, threadId, streaming) live in a
372
+ * separate adapter (mock in stories, factorial-side in production).
412
373
  */
413
374
  declare interface AiChatState {
414
375
  enabled: boolean;
415
376
  agent?: string;
416
377
  initialMessage?: string | string[];
378
+ chatHeader?: React.ReactNode;
379
+ chatMessages?: React.ReactNode;
380
+ chatInput?: React.ReactNode;
417
381
  welcomeScreenSuggestions?: WelcomeScreenSuggestion[];
418
382
  disclaimer?: AiChatDisclaimer;
419
383
  resizable?: boolean;
@@ -431,31 +395,23 @@ declare interface AiChatState {
431
395
  fileAttachments?: AiChatFileAttachmentConfig;
432
396
  placeholders?: string[];
433
397
  setPlaceholders?: React.Dispatch<React.SetStateAction<string[]>>;
434
- onThumbsUp?: (message: AIMessage, { threadId, feedback }: {
398
+ onThumbsUp?: (message: F0AIMessage, { threadId, feedback }: {
435
399
  threadId: string;
436
400
  feedback: string;
437
401
  }) => void;
438
- onThumbsDown?: (message: AIMessage, { threadId, feedback }: {
402
+ onThumbsDown?: (message: F0AIMessage, { threadId, feedback }: {
439
403
  threadId: string;
440
404
  feedback: string;
441
405
  }) => void;
442
406
  tracking?: AiChatTrackingOptions;
443
- /**
444
- * Optional hook called before a user message is sent. Return false to block submission.
445
- */
446
- onBeforeSendMessage?: () => boolean | Promise<boolean>;
447
- /**
448
- * Optional fetch implementation for AI runtime requests owned by F0.
449
- */
450
- runtimeFetch?: typeof fetch;
451
407
  }
452
408
 
453
- declare type AiChatTrackingOptions = {
409
+ export declare type AiChatTrackingOptions = {
454
410
  onVisibility?: () => void;
455
411
  onClose?: () => void;
456
412
  onWelcomeSuggestionClick?: (event: WelcomeSuggestionClickEvent) => void;
457
413
  onNewChat?: () => void;
458
- onMessage?: (message: Message) => void;
414
+ onMessage?: (message: F0Message) => void;
459
415
  };
460
416
 
461
417
  /**
@@ -502,7 +458,7 @@ export declare type AiInsightCardContent = {
502
458
  };
503
459
 
504
460
  /** Assistant-flavoured `Message`. Same shape — alias for self-documentation. */
505
- declare type AIMessage_2 = Message_2;
461
+ declare type AIMessage = Message;
506
462
 
507
463
  /**
508
464
  * Default AI chat translations — derived from the global defaultTranslations
@@ -2224,7 +2180,9 @@ declare type DetailsItemContent = (ComponentProps<typeof DataList.Item> & {
2224
2180
  }[TagType_2] | {
2225
2181
  type: "avatar-list";
2226
2182
  avatarList: F0AvatarListProps;
2227
- };
2183
+ } | (ComponentProps<typeof FileItem> & {
2184
+ type: "file";
2185
+ });
2228
2186
 
2229
2187
  /**
2230
2188
  * Remove a property from a union of objects.
@@ -2340,7 +2298,7 @@ export declare interface F0ActionItemProps {
2340
2298
  /**
2341
2299
  * @experimental This is an experimental component use it at your own risk
2342
2300
  */
2343
- export declare const F0AiChat: () => JSX_2.Element | null;
2301
+ export declare const F0AiChat: ({ header: headerProp, messages: messagesProp, input: inputProp, }: F0AiChatProps) => JSX_2.Element | null;
2344
2302
 
2345
2303
  /**
2346
2304
  * Headless chat header. Renders a top bar with title (or thread selector),
@@ -2426,10 +2384,28 @@ export declare type F0AiChatHistoryProps = {
2426
2384
  onDeleteThread: (id: string) => Promise<void> | void;
2427
2385
  };
2428
2386
 
2387
+ /**
2388
+ * Slot composition for the F0 AI chat shell. F0 ships the shell + UI
2389
+ * primitives; the consumer (factorial in production, the mock runtime
2390
+ * in stories) supplies the connected slot components that wire data
2391
+ * through whatever runtime they choose (CopilotKit, Mastra, mock, …).
2392
+ *
2393
+ * Slots are optional so the shell renders cleanly even when no runtime
2394
+ * is mounted (the chat just stays empty).
2395
+ */
2396
+ export declare interface F0AiChatProps {
2397
+ /** Header slot rendered at the top of the chat window. */
2398
+ header?: ReactNode;
2399
+ /** Messages slot rendered inside the scrollable area. */
2400
+ messages?: ReactNode;
2401
+ /** Input slot rendered at the bottom (textarea + suggestions + disclaimer). */
2402
+ input?: ReactNode;
2403
+ }
2404
+
2429
2405
  /**
2430
2406
  * @experimental This is an experimental component use it at your own risk
2431
2407
  */
2432
- export declare const F0AiChatProvider: ({ enabled, initialMessage, welcomeScreenSuggestions, disclaimer, resizable, defaultVisualizationMode, lockVisualizationMode, historyEnabled, footer, VoiceMode, entityRefs, canvasActions, canvasEntities, credits, employeeCredits, creditWarning, fileAttachments, onThumbsUp, onThumbsDown, onBeforeSendMessage, runtimeFetch, children, agent, tracking, ...copilotKitProps }: AiChatProviderProps) => JSX_2.Element;
2408
+ export declare const F0AiChatProvider: ({ enabled, initialMessage, chatHeader, chatMessages, chatInput, welcomeScreenSuggestions, disclaimer, resizable, defaultVisualizationMode, lockVisualizationMode, historyEnabled, footer, VoiceMode, entityRefs, canvasActions, canvasEntities, credits, employeeCredits, creditWarning, fileAttachments, onThumbsUp, onThumbsDown, children, agent, tracking, }: AiChatProviderProps) => JSX_2.Element;
2433
2409
 
2434
2410
  /**
2435
2411
  * Headless chat composer.
@@ -2440,7 +2416,7 @@ export declare const F0AiChatProvider: ({ enabled, initialMessage, welcomeScreen
2440
2416
  * coupling to `useAiChat()` or CopilotKit — wrappers like F0AiChat
2441
2417
  * provide the wiring.
2442
2418
  */
2443
- export declare const F0AiChatTextArea: ({ onSubmit, onStop, inProgress, onBeforeSubmit, placeholders, creditWarning, clarifyingQuestion, pendingContext, onPendingContextChange, pendingQuote, onPendingQuoteChange, fileAttachments, searchPersons, onProcessFilesRef, disclaimer, footer, isWelcomeScreen, fullscreen, welcomeScreenSuggestions, onSuggestionClick, ref, }: F0AiChatTextAreaProps) => JSX_2.Element;
2419
+ export declare const F0AiChatTextArea: ({ onSubmit, onStop, inProgress, onBeforeSubmit, placeholders, creditWarning, clarifyingUI, pendingContext, onPendingContextChange, pendingQuote, onPendingQuoteChange, fileAttachments, searchPersons, onProcessFilesRef, disclaimer, footer, isWelcomeScreen, fullscreen, welcomeScreenSuggestions, onSuggestionClick, ref, }: F0AiChatTextAreaProps) => JSX_2.Element;
2444
2420
 
2445
2421
  export declare type F0AiChatTextAreaProps = {
2446
2422
  ref: RefObject<HTMLDivElement>;
@@ -2461,10 +2437,13 @@ export declare type F0AiChatTextAreaProps = {
2461
2437
  /** Credit warning banner shown above the composer. */
2462
2438
  creditWarning?: AiChatCreditWarning;
2463
2439
  /**
2464
- * Clarifying question to render in place of the input. When non-null the
2465
- * panel takes over the composer surface and submission is blocked.
2440
+ * Optional ReactNode rendered in place of the input. When present the
2441
+ * composer enters "clarifying" mode: form submission is blocked, the
2442
+ * gradient border activates, and a nav-hint replaces the disclaimer.
2443
+ * The host owns the panel (typically `F0ClarifyingPanel`) and its
2444
+ * state — F0 just renders the slot.
2466
2445
  */
2467
- clarifyingQuestion?: ClarifyingQuestionState | null;
2446
+ clarifyingUI?: ReactNode;
2468
2447
  /** Pending context shown as a chip; prepended invisibly on submit. */
2469
2448
  pendingContext?: PendingContext | null;
2470
2449
  /** Called when the user dismisses pending context (or it gets consumed on submit). */
@@ -2519,16 +2498,16 @@ export declare type F0AiChatTextAreaProps = {
2519
2498
  /**
2520
2499
  * Payload emitted by `F0AiChatTextArea` when the user submits.
2521
2500
  *
2522
- * `text` already contains the inline markup the renderer expects:
2523
- * `<entity-ref>` tags for @mentions, `<reply-quote>` for the quoted
2524
- * fragment, and HTML-escaped user-typed text. The consumer decides how
2525
- * to wrap it (plain string vs multipart message) when forwarding to
2526
- * the agent.
2501
+ * `text` contains HTML-escaped user-typed text with `<entity-ref>` tags
2502
+ * for @mentions only. The reply quote (if any) and pending context
2503
+ * travel as separate structured fields the adapter (factorial) owns
2504
+ * the wire encoding when forwarding to the agent.
2527
2505
  */
2528
2506
  export declare type F0AiChatTextAreaSubmitPayload = {
2529
2507
  text: string;
2530
2508
  files: UploadedFile[];
2531
2509
  context: PendingContext | null;
2510
+ quote: PendingQuote | null;
2532
2511
  };
2533
2512
 
2534
2513
  export declare const F0AiInsightCard: WithDataTestIdReturnType<ForwardRefExoticComponent<F0AiInsightCardPublicProps & RefAttributes<HTMLDivElement>> & {
@@ -2575,6 +2554,9 @@ export declare class F0AiMask {
2575
2554
  private render;
2576
2555
  }
2577
2556
 
2557
+ /** Assistant-flavoured `F0Message`. Same shape — alias kept for clarity. */
2558
+ export declare type F0AIMessage = F0Message;
2559
+
2578
2560
  export declare const F0AiMessagesContainer: (props: F0AiMessagesContainerProps) => JSX_2.Element;
2579
2561
 
2580
2562
  export declare type F0AiMessagesContainerProps = {
@@ -2603,7 +2585,7 @@ export declare type F0AiMessagesContainerProps = {
2603
2585
  /** Called when the user selects text and clicks Reply (user or assistant bubble). */
2604
2586
  onReplyQuote?: (text: string) => void;
2605
2587
  /** Called when an assistant message finishes generating — for analytics. */
2606
- onAssistantMessageRendered?: (message: Message_2) => void;
2588
+ onAssistantMessageRendered?: (message: Message) => void;
2607
2589
  /** Disables auto-scrollIntoView on new user messages (fullscreen sets false). */
2608
2590
  autoScrollUserIntoView?: boolean;
2609
2591
  /**
@@ -2740,11 +2722,11 @@ declare type F0AssistantMessageExtraProps = {
2740
2722
  * full message list to call CopilotKit's lazy tool renderer; standalone
2741
2723
  * consumers can omit it.
2742
2724
  */
2743
- renderToolCall?: (message: Message_2) => ReactNode | null;
2725
+ renderToolCall?: (message: Message) => ReactNode | null;
2744
2726
  /** Called when the user selects text in this message and clicks Reply. */
2745
2727
  onReplyQuote?: (text: string) => void;
2746
2728
  /** Called once the assistant message has finished generating — for analytics. */
2747
- onRendered?: (message: Message_2) => void;
2729
+ onRendered?: (message: Message) => void;
2748
2730
  /**
2749
2731
  * Renders the assistant text content. The connected wrapper provides a
2750
2732
  * markdown-aware implementation; standalone consumers can omit it and a
@@ -2805,6 +2787,15 @@ declare type F0AvatarIconProps = {
2805
2787
  state?: F0IconProps["state"];
2806
2788
  } & Partial<Pick<BaseAvatarProps, "aria-label" | "aria-labelledby">>;
2807
2789
 
2790
+ /**
2791
+ * Optional extras every avatar entry may carry regardless of `type`.
2792
+ * `tooltipDescription` is rendered as the tooltip's secondary line via the
2793
+ * underlying `Tooltip` `description` slot (use it for emails, roles, etc.).
2794
+ */
2795
+ declare type F0AvatarListExtras = {
2796
+ tooltipDescription?: string;
2797
+ };
2798
+
2808
2799
  declare type F0AvatarListProps = {
2809
2800
  /**
2810
2801
  * The size of the avatars in the list.
@@ -2832,23 +2823,32 @@ declare type F0AvatarListProps = {
2832
2823
  * @default "compact"
2833
2824
  */
2834
2825
  layout?: "fill" | "compact";
2826
+ /**
2827
+ * Controls the scroll behavior of the `+N` overflow popover that lists
2828
+ * collapsed avatars (including their `tooltipDescription` entries).
2829
+ * - `"vertical"` (default): caps the popover height and scrolls vertically.
2830
+ * - `"none"`: lets the popover grow to fit all entries.
2831
+ * @default "vertical"
2832
+ */
2833
+ tooltipScroll?: "vertical" | "none";
2835
2834
  } & F0AvatarListPropsAvatars;
2836
2835
 
2837
2836
  declare type F0AvatarListPropsAvatars = {
2838
2837
  type: "person";
2839
- avatars: (Omit<PersonAvatarVariant, "type"> & Record<string, unknown>)[];
2838
+ avatars: (Omit<PersonAvatarVariant, "type"> & // Allow to have more properties in the avatar variant
2839
+ F0AvatarListExtras & Record<string, unknown>)[];
2840
2840
  } | {
2841
2841
  type: "team";
2842
- avatars: (Omit<TeamAvatarVariant, "type"> & Record<string, unknown>)[];
2842
+ avatars: (Omit<TeamAvatarVariant, "type"> & F0AvatarListExtras & Record<string, unknown>)[];
2843
2843
  } | {
2844
2844
  type: "company";
2845
- avatars: (Omit<CompanyAvatarVariant, "type"> & Record<string, unknown>)[];
2845
+ avatars: (Omit<CompanyAvatarVariant, "type"> & F0AvatarListExtras & Record<string, unknown>)[];
2846
2846
  } | {
2847
2847
  type: "flag";
2848
- avatars: (Omit<FlagAvatarVariant, "type"> & Record<string, unknown>)[];
2848
+ avatars: (Omit<FlagAvatarVariant, "type"> & F0AvatarListExtras & Record<string, unknown>)[];
2849
2849
  } | {
2850
2850
  type: "file";
2851
- avatars: (Omit<FileAvatarVariant, "type"> & Record<string, unknown>)[];
2851
+ avatars: (Omit<FileAvatarVariant, "type"> & F0AvatarListExtras & Record<string, unknown>)[];
2852
2852
  };
2853
2853
 
2854
2854
  declare type F0AvatarPersonProps = {
@@ -3006,6 +3006,24 @@ declare interface F0IconProps extends SVGProps<SVGSVGElement>, VariantProps<type
3006
3006
  color?: "default" | "currentColor" | `#${string}` | Lowercase<NestedKeyOf<typeof f1Colors.icon>>;
3007
3007
  }
3008
3008
 
3009
+ export declare type F0Message = {
3010
+ id: string;
3011
+ role: "user" | "assistant" | "system" | "tool";
3012
+ content?: unknown;
3013
+ toolCalls?: F0ToolCall[];
3014
+ toolCallId?: string;
3015
+ createdAt?: string;
3016
+ generativeUI?: () => unknown;
3017
+ rawData?: unknown;
3018
+ /**
3019
+ * Reply quote text attached to the message by the composer. Rendered
3020
+ * as a block above the user bubble. Adapters (factorial / mock) own
3021
+ * the wire encoding; F0 only reads this structured field.
3022
+ */
3023
+ replyQuote?: string;
3024
+ [key: string]: any;
3025
+ };
3026
+
3009
3027
  export declare const F0OneIcon: ForwardRefExoticComponent<Omit<F0OneIconProps, "ref"> & RefAttributes<SVGSVGElement>>;
3010
3028
 
3011
3029
  /**
@@ -3140,18 +3158,40 @@ declare interface F0TagStatusProps {
3140
3158
 
3141
3159
  declare const F0TagTeam: WithDataTestIdReturnType<ForwardRefExoticComponent<F0TagTeamProps & RefAttributes<HTMLDivElement>>>;
3142
3160
 
3161
+ /**
3162
+ * Loose message shape used inside f0. Mirrors the CopilotKit `Message`
3163
+ * shape so adapters (factorial, mock runtime) can map back and forth
3164
+ * with no field rename, but is owned by f0 — nothing in `src/` imports
3165
+ * from `@copilotkit/*` anymore.
3166
+ */
3167
+ export declare type F0ToolCall = {
3168
+ id: string;
3169
+ type?: "function";
3170
+ function: {
3171
+ name: string;
3172
+ arguments: string;
3173
+ };
3174
+ };
3175
+
3143
3176
  export declare type FeedbackConfig = {
3144
3177
  threadId: string;
3145
- onThumbsUp: (msg: AIMessage_2, ctx: {
3178
+ onThumbsUp: (msg: AIMessage, ctx: {
3146
3179
  threadId: string;
3147
3180
  feedback: string;
3148
3181
  }) => void;
3149
- onThumbsDown: (msg: AIMessage_2, ctx: {
3182
+ onThumbsDown: (msg: AIMessage, ctx: {
3150
3183
  threadId: string;
3151
3184
  feedback: string;
3152
3185
  }) => void;
3153
3186
  };
3154
3187
 
3188
+ declare type FileAction = {
3189
+ icon?: IconType;
3190
+ label: string;
3191
+ onClick: () => void;
3192
+ critical?: boolean;
3193
+ };
3194
+
3155
3195
  declare type FileAvatarVariant = Extract<AvatarVariant, {
3156
3196
  type: "file";
3157
3197
  }>;
@@ -3161,6 +3201,27 @@ declare type FileDef = {
3161
3201
  type: string;
3162
3202
  };
3163
3203
 
3204
+ declare const FileItem: WithDataTestIdReturnType<ForwardRefExoticComponent<FileItemProps & RefAttributes<HTMLDivElement>>>;
3205
+
3206
+ declare interface FileItemProps extends React.HTMLAttributes<HTMLDivElement> {
3207
+ file: File | FileDef;
3208
+ actions?: FileAction[];
3209
+ disabled?: boolean;
3210
+ size?: FileItemSize;
3211
+ }
3212
+
3213
+ declare type FileItemSize = NonNullable<VariantProps<typeof fileItemVariants>["size"]>;
3214
+
3215
+ declare const fileItemVariants: (props?: ({
3216
+ size?: "lg" | "md" | undefined;
3217
+ } & ({
3218
+ class?: ClassValue;
3219
+ className?: never;
3220
+ } | {
3221
+ class?: never;
3222
+ className?: ClassValue;
3223
+ })) | undefined) => string;
3224
+
3164
3225
  declare type FlagAvatarVariant = Extract<AvatarVariant, {
3165
3226
  type: "flag";
3166
3227
  }>;
@@ -3347,7 +3408,7 @@ export declare type MaskOptions = {
3347
3408
  * Most fields are optional / wide on purpose — the headless renders
3348
3409
  * what it finds and ignores the rest.
3349
3410
  */
3350
- declare type Message_2 = {
3411
+ declare type Message = {
3351
3412
  id?: string;
3352
3413
  role?: string;
3353
3414
  content?: unknown;
@@ -3361,6 +3422,13 @@ declare type Message_2 = {
3361
3422
  }>;
3362
3423
  generativeUI?: () => unknown;
3363
3424
  rawData?: unknown;
3425
+ /**
3426
+ * Reply quote text the composer attached to this (user) message.
3427
+ * Rendered as a block above the bubble. The wire protocol that carries
3428
+ * this is owned by the adapter (factorial) — F0 only consumes the
3429
+ * structured field.
3430
+ */
3431
+ replyQuote?: string;
3364
3432
  [key: string]: any;
3365
3433
  };
3366
3434
 
@@ -3701,7 +3769,7 @@ declare type RelaxedNumericWithFormatter = Omit<NumericWithFormatter, "numericVa
3701
3769
  */
3702
3770
  export declare type RenderableTurn = {
3703
3771
  /** Messages rendered before the thinking section (typically the user message). */
3704
- userMessages: Message_2[];
3772
+ userMessages: Message[];
3705
3773
  /**
3706
3774
  * Optional collapsible "thinking" header rendered between user and
3707
3775
  * assistant blocks. Titles are pre-parsed upstream.
@@ -3722,7 +3790,7 @@ export declare type RenderableTurn = {
3722
3790
  isWriting?: boolean;
3723
3791
  };
3724
3792
  /** Messages rendered after the thinking section (assistant replies). */
3725
- assistantMessages: Message_2[];
3793
+ assistantMessages: Message[];
3726
3794
  /** True while the agent is still producing content for this turn. */
3727
3795
  isInProgress: boolean;
3728
3796
  /**
@@ -3741,7 +3809,7 @@ export declare type RenderableTurn = {
3741
3809
  /** Concatenated assistant content for the copy button. */
3742
3810
  content: string;
3743
3811
  /** Reference message attached to feedback submissions. */
3744
- targetMessage: Message_2;
3812
+ targetMessage: Message;
3745
3813
  };
3746
3814
  };
3747
3815
 
@@ -3895,9 +3963,6 @@ export declare type UploadedFile = {
3895
3963
  * is mounted — that case is intentional in `ApplicationFrame`, which
3896
3964
  * renders chat-aware components in both the AI-enabled tree and the
3897
3965
  * promotion-chat tree.
3898
- *
3899
- * Most consumers don't need to think about this — they're rendered
3900
- * under `<F0AiChatProvider>` and receive the real context.
3901
3966
  */
3902
3967
  export declare function useAiChat(): AiChatProviderReturnValue;
3903
3968
 
@@ -4048,7 +4113,7 @@ export declare type WelcomeScreenSuggestionItem = {
4048
4113
  * analytics layer (e.g. Amplitude) needs to attribute the click: the picked
4049
4114
  * sub-item, its parent group, and the resolved prompt that was actually sent.
4050
4115
  */
4051
- declare type WelcomeSuggestionClickEvent = {
4116
+ export declare type WelcomeSuggestionClickEvent = {
4052
4117
  item: WelcomeScreenSuggestionItem;
4053
4118
  group: WelcomeScreenSuggestion;
4054
4119
  /** Prompt actually sent to the AI — `item.prompt` falling back to `item.title`. */
@@ -4137,10 +4202,8 @@ declare module "@tiptap/core" {
4137
4202
 
4138
4203
  declare module "@tiptap/core" {
4139
4204
  interface Commands<ReturnType> {
4140
- videoEmbed: {
4141
- setVideoEmbed: (options: {
4142
- src: string;
4143
- }) => ReturnType;
4205
+ transcript: {
4206
+ insertTranscript: (data: TranscriptData) => ReturnType;
4144
4207
  };
4145
4208
  }
4146
4209
  }
@@ -4148,8 +4211,10 @@ declare module "@tiptap/core" {
4148
4211
 
4149
4212
  declare module "@tiptap/core" {
4150
4213
  interface Commands<ReturnType> {
4151
- transcript: {
4152
- insertTranscript: (data: TranscriptData) => ReturnType;
4214
+ videoEmbed: {
4215
+ setVideoEmbed: (options: {
4216
+ src: string;
4217
+ }) => ReturnType;
4153
4218
  };
4154
4219
  }
4155
4220
  }