@moldable-ai/ui 0.2.8 → 0.2.10

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 (38) hide show
  1. package/dist/components/app-error-boundary.d.ts +26 -0
  2. package/dist/components/app-error-boundary.d.ts.map +1 -0
  3. package/dist/components/app-error-boundary.js +87 -0
  4. package/dist/components/chat/chat-input.d.ts +8 -1
  5. package/dist/components/chat/chat-input.d.ts.map +1 -1
  6. package/dist/components/chat/chat-input.js +6 -3
  7. package/dist/components/chat/chat-message.d.ts +1 -0
  8. package/dist/components/chat/chat-message.d.ts.map +1 -1
  9. package/dist/components/chat/chat-message.js +100 -12
  10. package/dist/components/chat/chat-messages.d.ts +2 -1
  11. package/dist/components/chat/chat-messages.d.ts.map +1 -1
  12. package/dist/components/chat/chat-messages.js +3 -3
  13. package/dist/components/chat/chat-panel.d.ts +25 -3
  14. package/dist/components/chat/chat-panel.d.ts.map +1 -1
  15. package/dist/components/chat/chat-panel.js +158 -42
  16. package/dist/components/chat/index.d.ts +3 -3
  17. package/dist/components/chat/index.d.ts.map +1 -1
  18. package/dist/components/chat/index.js +1 -1
  19. package/dist/components/chat/model-selector.d.ts.map +1 -1
  20. package/dist/components/chat/model-selector.js +1 -1
  21. package/dist/components/chat/tool-handlers.d.ts.map +1 -1
  22. package/dist/components/chat/tool-handlers.js +89 -1
  23. package/dist/components/markdown.d.ts.map +1 -1
  24. package/dist/components/markdown.js +16 -2
  25. package/dist/components/rich-media-player.d.ts +8 -0
  26. package/dist/components/rich-media-player.d.ts.map +1 -0
  27. package/dist/components/rich-media-player.js +99 -0
  28. package/dist/components/ui/resizable.d.ts +4 -1
  29. package/dist/components/ui/resizable.d.ts.map +1 -1
  30. package/dist/components/ui/resizable.js +1 -1
  31. package/dist/index.d.ts +2 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -0
  34. package/package.json +4 -1
  35. package/src/styles/index.css +25 -0
  36. package/dist/lib/commands.test.d.ts +0 -2
  37. package/dist/lib/commands.test.d.ts.map +0 -1
  38. package/dist/lib/commands.test.js +0 -111
@@ -0,0 +1,26 @@
1
+ import { Component, type ErrorInfo, type ReactNode } from 'react';
2
+ type ErrorSource = 'react' | 'window' | 'promise';
3
+ interface AppErrorBoundaryProps {
4
+ appName: string;
5
+ children: ReactNode;
6
+ surface?: 'app' | 'widget';
7
+ }
8
+ interface AppErrorBoundaryState {
9
+ error: Error | null;
10
+ source: ErrorSource;
11
+ componentStack: string | null;
12
+ }
13
+ export declare class AppErrorBoundary extends Component<AppErrorBoundaryProps, AppErrorBoundaryState> {
14
+ state: AppErrorBoundaryState;
15
+ static getDerivedStateFromError(error: Error): Partial<AppErrorBoundaryState>;
16
+ componentDidMount(): void;
17
+ componentWillUnmount(): void;
18
+ componentDidCatch(error: Error, info: ErrorInfo): void;
19
+ private handleWindowError;
20
+ private handleUnhandledRejection;
21
+ private reload;
22
+ private askMoldable;
23
+ render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
24
+ }
25
+ export {};
26
+ //# sourceMappingURL=app-error-boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-error-boundary.d.ts","sourceRoot":"","sources":["../../src/components/app-error-boundary.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAGjE,KAAK,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAA;AAEjD,UAAU,qBAAqB;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,SAAS,CAAA;IACnB,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;CAC3B;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACnB,MAAM,EAAE,WAAW,CAAA;IACnB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;AAiCD,qBAAa,gBAAiB,SAAQ,SAAS,CAC7C,qBAAqB,EACrB,qBAAqB,CACtB;IACC,KAAK,EAAE,qBAAqB,CAI3B;IAED,MAAM,CAAC,wBAAwB,CAC7B,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,qBAAqB,CAAC;IAIjC,iBAAiB,IAAI,IAAI;IAOzB,oBAAoB,IAAI,IAAI;IAU5B,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAKtD,OAAO,CAAC,iBAAiB,CAKxB;IAED,OAAO,CAAC,wBAAwB,CAI/B;IAED,OAAO,CAAC,MAAM,CAEb;IAED,OAAO,CAAC,WAAW,CAclB;IAED,MAAM;CA8CP"}
@@ -0,0 +1,87 @@
1
+ 'use client';
2
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
+ import { MessageSquareWarning, RefreshCw } from 'lucide-react';
4
+ import { Component } from 'react';
5
+ import { Button } from './ui/button';
6
+ function toError(value) {
7
+ if (value instanceof Error)
8
+ return value;
9
+ if (typeof value === 'string')
10
+ return new Error(value);
11
+ try {
12
+ return new Error(JSON.stringify(value));
13
+ }
14
+ catch {
15
+ return new Error(String(value));
16
+ }
17
+ }
18
+ function formatError(error, source, componentStack) {
19
+ const parts = [`${error.name}: ${error.message}`];
20
+ if (error.stack) {
21
+ parts.push(error.stack);
22
+ }
23
+ if (componentStack) {
24
+ parts.push(`React component stack:${componentStack}`);
25
+ }
26
+ parts.push(`Source: ${source}`);
27
+ return parts.join('\n\n');
28
+ }
29
+ export class AppErrorBoundary extends Component {
30
+ state = {
31
+ error: null,
32
+ source: 'react',
33
+ componentStack: null,
34
+ };
35
+ static getDerivedStateFromError(error) {
36
+ return { error, source: 'react' };
37
+ }
38
+ componentDidMount() {
39
+ if (typeof window === 'undefined')
40
+ return;
41
+ window.addEventListener('error', this.handleWindowError);
42
+ window.addEventListener('unhandledrejection', this.handleUnhandledRejection);
43
+ }
44
+ componentWillUnmount() {
45
+ if (typeof window === 'undefined')
46
+ return;
47
+ window.removeEventListener('error', this.handleWindowError);
48
+ window.removeEventListener('unhandledrejection', this.handleUnhandledRejection);
49
+ }
50
+ componentDidCatch(error, info) {
51
+ console.error(`${this.props.appName} UI crashed:`, error, info);
52
+ this.setState({ componentStack: info.componentStack ?? null });
53
+ }
54
+ handleWindowError = (event) => {
55
+ const error = event.error instanceof Error ? event.error : new Error(event.message);
56
+ console.error(`${this.props.appName} uncaught frontend error:`, error);
57
+ this.setState({ error, source: 'window', componentStack: null });
58
+ };
59
+ handleUnhandledRejection = (event) => {
60
+ const error = toError(event.reason);
61
+ console.error(`${this.props.appName} unhandled promise rejection:`, error);
62
+ this.setState({ error, source: 'promise', componentStack: null });
63
+ };
64
+ reload = () => {
65
+ window.location.reload();
66
+ };
67
+ askMoldable = () => {
68
+ const { error, source, componentStack } = this.state;
69
+ if (!error)
70
+ return;
71
+ const surfaceLabel = this.props.surface === 'widget' ? ' widget' : ' full app';
72
+ const errorReport = formatError(error, source, componentStack);
73
+ const text = [
74
+ `${this.props.appName}${surfaceLabel} hit an uncaught frontend error.`,
75
+ 'Please inspect and fix the client crash.',
76
+ errorReport,
77
+ ].join('\n\n');
78
+ window.parent.postMessage({ type: 'moldable:set-chat-input', text }, '*');
79
+ };
80
+ render() {
81
+ const { error, source, componentStack } = this.state;
82
+ if (!error)
83
+ return this.props.children;
84
+ const errorSummary = formatError(error, source, componentStack);
85
+ return (_jsx("main", { className: "bg-background text-foreground flex min-h-screen items-center justify-center p-4 sm:p-6", children: _jsxs("section", { className: "border-border bg-card w-full max-w-xl rounded-lg border p-5 shadow-lg sm:p-6", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs("h1", { className: "text-xl font-semibold tracking-tight", children: [this.props.appName, " hit a UI error"] }), _jsx("p", { className: "text-muted-foreground text-sm leading-6", children: "Reload to recover, or send the captured client error to Moldable so it can inspect the crash." })] }), _jsx("pre", { className: "bg-muted text-muted-foreground mt-5 max-h-44 overflow-auto whitespace-pre-wrap rounded-md border p-3 font-mono text-xs", children: errorSummary }), _jsxs("div", { className: "mt-5 flex flex-col gap-2 sm:flex-row", children: [_jsxs(Button, { type: "button", className: "cursor-pointer", onClick: this.reload, children: [_jsx(RefreshCw, {}), "Reload"] }), _jsxs(Button, { type: "button", variant: "secondary", className: "cursor-pointer", onClick: this.askMoldable, children: [_jsx(MessageSquareWarning, {}), "Ask Moldable to fix this"] })] })] }) }));
86
+ }
87
+ }
@@ -1,5 +1,10 @@
1
1
  import type { ChangeEvent, FormEvent, ReactNode, RefObject } from 'react';
2
2
  export type ChatSubmitMode = 'send' | 'steer' | 'queue';
3
+ export type ChatSlashCommandOption = {
4
+ id: string;
5
+ name: string;
6
+ description: string;
7
+ };
3
8
  export type ChatImageAttachment = {
4
9
  id: string;
5
10
  name: string;
@@ -21,7 +26,9 @@ type ChatInputProps = {
21
26
  footerStartControls?: ReactNode;
22
27
  footerControls?: ReactNode;
23
28
  submitDisabled?: boolean;
29
+ slashCommands?: ChatSlashCommandOption[];
30
+ onSlashCommandSelect?: (command: ChatSlashCommandOption) => void;
24
31
  };
25
- export declare function ChatInput({ input, onInputChange, onSubmit, isResponding, placeholder, inputRef, onStop, compact, imageAttachments, onRemoveImageAttachment, footerStartControls, footerControls, submitDisabled, }: ChatInputProps): import("react/jsx-runtime").JSX.Element;
32
+ export declare function ChatInput({ input, onInputChange, onSubmit, isResponding, placeholder, inputRef, onStop, compact, imageAttachments, onRemoveImageAttachment, footerStartControls, footerControls, submitDisabled, slashCommands, onSlashCommandSelect, }: ChatInputProps): import("react/jsx-runtime").JSX.Element;
26
33
  export {};
27
34
  //# sourceMappingURL=chat-input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-input.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-input.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EAGT,SAAS,EACT,SAAS,EACV,MAAM,OAAO,CAAA;AAKd,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AAEvD,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAA;IAC5D,QAAQ,EAAE,CACR,CAAC,EAAE,SAAS,CAAC,eAAe,CAAC,GAAG,SAAS,EACzC,IAAI,CAAC,EAAE,cAAc,KAClB,IAAI,CAAA;IACT,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAChD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACxC,uBAAuB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9C,mBAAmB,CAAC,EAAE,SAAS,CAAA;IAC/B,cAAc,CAAC,EAAE,SAAS,CAAA;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAA+B,EAC/B,QAAQ,EACR,MAAM,EACN,OAAe,EACf,gBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,cAAc,EACd,cAAsB,GACvB,EAAE,cAAc,2CAqJhB"}
1
+ {"version":3,"file":"chat-input.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-input.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EAGT,SAAS,EACT,SAAS,EACV,MAAM,OAAO,CAAA;AAKd,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AAEvD,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAA;IAC5D,QAAQ,EAAE,CACR,CAAC,EAAE,SAAS,CAAC,eAAe,CAAC,GAAG,SAAS,EACzC,IAAI,CAAC,EAAE,cAAc,KAClB,IAAI,CAAA;IACT,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAChD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACxC,uBAAuB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9C,mBAAmB,CAAC,EAAE,SAAS,CAAA;IAC/B,cAAc,CAAC,EAAE,SAAS,CAAA;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,aAAa,CAAC,EAAE,sBAAsB,EAAE,CAAA;IACxC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAA;CACjE,CAAA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAA+B,EAC/B,QAAQ,EACR,MAAM,EACN,OAAe,EACf,gBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,cAAc,EACd,cAAsB,EACtB,aAAkB,EAClB,oBAAoB,GACrB,EAAE,cAAc,2CA2KhB"}
@@ -1,9 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { ArrowUp, Image as ImageIcon, Square, X } from 'lucide-react';
3
3
  import { cn } from '../../lib/utils';
4
4
  import { Button } from '../ui/button';
5
5
  import { Textarea } from '../ui/textarea';
6
- export function ChatInput({ input, onInputChange, onSubmit, isResponding, placeholder = 'Ask anything...', inputRef, onStop, compact = false, imageAttachments = [], onRemoveImageAttachment, footerStartControls, footerControls, submitDisabled = false, }) {
6
+ export function ChatInput({ input, onInputChange, onSubmit, isResponding, placeholder = 'Ask anything...', inputRef, onStop, compact = false, imageAttachments = [], onRemoveImageAttachment, footerStartControls, footerControls, submitDisabled = false, slashCommands = [], onSlashCommandSelect, }) {
7
7
  const hasInput = input.trim().length > 0;
8
8
  const hasAttachments = imageAttachments.length > 0;
9
9
  const canSubmit = !submitDisabled && (hasInput || hasAttachments);
@@ -47,7 +47,10 @@ export function ChatInput({ input, onInputChange, onSubmit, isResponding, placeh
47
47
  return;
48
48
  }
49
49
  onSubmit(e, isResponding ? 'queue' : 'send');
50
- }, children: _jsxs("div", { className: cn('bg-background relative flex w-full flex-col rounded-3xl border', compact && !hasAttachments && 'h-14'), children: [!compact && hasAttachments && (_jsx("div", { className: "flex max-h-32 gap-2 overflow-x-auto px-3 pt-3", children: imageAttachments.map((attachment) => (_jsxs("div", { className: "bg-muted/70 border-border flex max-w-48 shrink-0 items-center gap-2 rounded-xl border p-1.5 pr-2", children: [_jsx("div", { className: "bg-background flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg border", children: attachment.previewUrl ? (_jsx("img", { src: attachment.previewUrl, alt: "", className: "size-full object-cover", draggable: false })) : (_jsx(ImageIcon, { className: "text-muted-foreground size-4" })) }), _jsx("span", { className: "min-w-0 truncate text-xs font-medium", title: attachment.path, children: attachment.name }), onRemoveImageAttachment && (_jsx("button", { type: "button", onClick: () => onRemoveImageAttachment(attachment.id), className: "text-muted-foreground hover:bg-accent hover:text-foreground flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-md transition-colors", "aria-label": `Remove ${attachment.name}`, children: _jsx(X, { className: "size-3.5" }) }))] }, attachment.id))) })), _jsx("div", { className: cn('w-full px-5', compact ? 'py-4' : 'pb-2 pt-4'), children: _jsx(Textarea, { ref: inputRef, value: input, placeholder: placeholder, onChange: onInputChange, onKeyDown: handleKeyDown, className: cn('max-h-32 min-h-[24px] resize-none rounded-none border-0 !bg-transparent p-0 text-sm shadow-none focus:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 dark:!bg-transparent', compact && 'max-h-6 min-h-6') }) }), !compact && (_jsxs("div", { className: "flex min-h-11 items-center justify-between gap-3 px-3 pb-3", children: [_jsx("div", { className: "flex min-w-0 shrink-0 items-center justify-start gap-1", children: footerStartControls }), _jsx("div", { className: "min-w-0 flex-1" }), _jsx("div", { className: "flex min-w-0 shrink-0 items-center justify-end gap-1.5", children: footerControls }), _jsxs(Button, { type: showStopButton ? 'button' : 'submit', size: "icon", className: "bg-primary text-primary-foreground size-8 cursor-pointer rounded-full hover:opacity-70 disabled:opacity-30", disabled: !canSubmit && !isResponding, onClick: handleButtonClick, children: [showStopButton ? (_jsx(Square, { className: "fill-primary-foreground size-4 animate-pulse" })) : (_jsx(ArrowUp, { className: "size-4" })), _jsx("span", { className: "sr-only", children: showStopButton
50
+ }, children: _jsxs("div", { className: cn('bg-background relative flex w-full flex-col rounded-3xl border', compact && !hasAttachments && 'h-14'), children: [!compact && slashCommands.length > 0 && (_jsx("div", { className: "border-border bg-popover text-popover-foreground absolute bottom-full left-4 right-4 z-20 mb-2 overflow-hidden rounded-lg border shadow-lg", children: slashCommands.map((command) => (_jsxs("button", { type: "button", className: "hover:bg-accent hover:text-accent-foreground flex min-h-12 w-full cursor-pointer items-center gap-3 px-3 py-2.5 text-left transition-colors", onMouseDown: (event) => {
51
+ event.preventDefault();
52
+ onSlashCommandSelect?.(command);
53
+ }, children: [_jsxs("span", { className: "bg-muted text-muted-foreground rounded px-1.5 py-0.5 font-mono text-xs", children: ["/", command.name] }), _jsx("span", { className: "min-w-0 text-xs", children: command.description })] }, command.id))) })), !compact && hasAttachments && (_jsx("div", { className: "flex max-h-32 gap-2 overflow-x-auto px-3 pt-3", children: imageAttachments.map((attachment) => (_jsxs("div", { className: "bg-muted/70 border-border flex max-w-48 shrink-0 items-center gap-2 rounded-xl border p-1.5 pr-2", children: [_jsx("div", { className: "bg-background flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg border", children: attachment.previewUrl ? (_jsx("img", { src: attachment.previewUrl, alt: "", className: "size-full object-cover", draggable: false })) : (_jsx(ImageIcon, { className: "text-muted-foreground size-4" })) }), _jsx("span", { className: "min-w-0 truncate text-xs font-medium", title: attachment.path, children: attachment.name }), onRemoveImageAttachment && (_jsx("button", { type: "button", onClick: () => onRemoveImageAttachment(attachment.id), className: "text-muted-foreground hover:bg-accent hover:text-foreground flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-md transition-colors", "aria-label": `Remove ${attachment.name}`, children: _jsx(X, { className: "size-3.5" }) }))] }, attachment.id))) })), _jsx("div", { className: cn('w-full px-5', compact ? 'py-4' : 'pb-2 pt-4'), children: _jsx(Textarea, { ref: inputRef, value: input, placeholder: placeholder, onChange: onInputChange, onKeyDown: handleKeyDown, className: cn('max-h-32 min-h-[24px] resize-none rounded-none border-0 !bg-transparent p-0 text-sm shadow-none focus:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 dark:!bg-transparent', compact && 'max-h-6 min-h-6') }) }), !compact && (_jsxs("div", { className: "flex min-h-11 items-center justify-between gap-3 px-3 pb-3", children: [_jsx("div", { className: "flex min-w-0 shrink-0 items-center justify-start gap-1", children: footerStartControls }), _jsx("div", { className: "min-w-0 flex-1" }), _jsx("div", { className: "flex min-w-0 shrink-0 items-center justify-end gap-0.5", children: footerControls }), _jsxs(Button, { type: showStopButton ? 'button' : 'submit', size: "icon", className: "bg-primary text-primary-foreground size-8 cursor-pointer rounded-full hover:opacity-70 disabled:opacity-30", disabled: !canSubmit && !isResponding, onClick: handleButtonClick, children: [showStopButton ? (_jsx(Square, { className: "fill-primary-foreground size-4 animate-pulse" })) : (_jsx(ArrowUp, { className: "size-4" })), _jsx("span", { className: "sr-only", children: showStopButton
51
54
  ? 'Stop generating'
52
55
  : isResponding
53
56
  ? 'Steer response'
@@ -41,5 +41,6 @@ type MessageProps = {
41
41
  declare function PureMessage({ message, isLast, isStreaming, }: MessageProps): import("react/jsx-runtime").JSX.Element;
42
42
  export declare const Message: import("react").MemoExoticComponent<typeof PureMessage>;
43
43
  export declare function ThinkingMessage(): import("react/jsx-runtime").JSX.Element;
44
+ export declare function CompactingMessage(): import("react/jsx-runtime").JSX.Element;
44
45
  export {};
45
46
  //# sourceMappingURL=chat-message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-message.tsx"],"names":[],"mappings":"AA+BA,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,GACD;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,MAAM,CAAA;QACV,QAAQ,CAAC,EAAE,OAAO,CAAA;KACnB,CAAA;CACF,CAAA;AAEL,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;IACrC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;IACzB,IAAI,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;CACF,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAopBD,iBAAS,WAAW,CAAC,EACnB,OAAO,EACP,MAAc,EACd,WAAmB,GACpB,EAAE,YAAY,2CAied;AAED,eAAO,MAAM,OAAO,yDAAoB,CAAA;AAExC,wBAAgB,eAAe,4CAc9B"}
1
+ {"version":3,"file":"chat-message.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-message.tsx"],"names":[],"mappings":"AA+BA,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,GACD;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,MAAM,CAAA;QACV,QAAQ,CAAC,EAAE,OAAO,CAAA;KACnB,CAAA;CACF,CAAA;AAEL,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;IACrC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;IACzB,IAAI,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;CACF,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAsvBD,iBAAS,WAAW,CAAC,EACnB,OAAO,EACP,MAAc,EACd,WAAmB,GACpB,EAAE,YAAY,2CAqgBd;AAED,eAAO,MAAM,OAAO,yDAAoB,CAAA;AAExC,wBAAgB,eAAe,4CAc9B;AAED,wBAAgB,iBAAiB,4CAkBhC"}
@@ -102,14 +102,32 @@ function getToolTarget(part) {
102
102
  return (getString(output, ['appName', 'appId', 'name', 'id']) ??
103
103
  getString(args, ['appName', 'appId', 'name', 'id', 'repoName', 'skillName']));
104
104
  }
105
+ function getAppApiTarget(part) {
106
+ const args = asRecord(part.args);
107
+ const output = asRecord(part.output);
108
+ return (getString(args, ['targetAppId', 'appId']) ??
109
+ getString(output, ['targetAppId', 'appId', 'appName']));
110
+ }
111
+ function getAppApiMethod(part) {
112
+ const args = asRecord(part.args);
113
+ const output = asRecord(part.output);
114
+ return getString(args, ['method']) ?? getString(output, ['method']);
115
+ }
105
116
  function isToolLoading(part, progress) {
106
117
  const isApprovalResponded = part.state === 'approval-responded' || part.state === 'output-denied';
107
118
  const wasApproved = part.approval?.approved === true;
119
+ const hasOutput = part.output !== undefined;
108
120
  return (part.state === 'partial-call' ||
109
121
  part.state === 'call' ||
122
+ part.state === 'input-streaming' ||
123
+ part.state === 'input-available' ||
110
124
  part.state === 'pending' ||
111
125
  progress?.status === 'running' ||
112
- (isApprovalResponded && wasApproved && part.output === undefined));
126
+ (isApprovalResponded && wasApproved && !hasOutput) ||
127
+ (!hasOutput &&
128
+ part.state !== 'output-available' &&
129
+ part.state !== 'output-error' &&
130
+ part.state !== 'output-denied'));
113
131
  }
114
132
  function toolHasError(part) {
115
133
  const output = asRecord(part.output);
@@ -127,7 +145,19 @@ function plural(count, singular, pluralForm = `${singular}s`) {
127
145
  function sentenceCase(text) {
128
146
  return text.length > 0 ? text.charAt(0).toUpperCase() + text.slice(1) : text;
129
147
  }
130
- function formatActivitySummary(counts, fallback, isStreaming) {
148
+ function formatAppApiSummary(count, labels) {
149
+ if (labels.length === 0) {
150
+ return `called ${plural(count, 'app API', 'app APIs')}`;
151
+ }
152
+ if (count === 1) {
153
+ return `called app API ${labels[0]}`;
154
+ }
155
+ const shown = labels.slice(0, 2);
156
+ const remaining = labels.length - shown.length;
157
+ const labelText = remaining > 0 ? `${shown.join(', ')} +${remaining}` : shown.join(', ');
158
+ return `called ${plural(count, 'app API', 'app APIs')} (${labelText})`;
159
+ }
160
+ function formatActivitySummary(counts, fallback, isStreaming, apiCallLabels = []) {
131
161
  const segments = [];
132
162
  const completedCommands = Math.max(0, counts.commandCount - counts.runningCommandCount);
133
163
  const explorationDetails = [
@@ -163,7 +193,7 @@ function formatActivitySummary(counts, fallback, isStreaming) {
163
193
  segments.push(`ran ${plural(counts.webSearchCount, 'web search', 'web searches')}`);
164
194
  }
165
195
  if (counts.apiCallCount > 0) {
166
- segments.push(`called ${plural(counts.apiCallCount, 'app API', 'app APIs')}`);
196
+ segments.push(formatAppApiSummary(counts.apiCallCount, apiCallLabels));
167
197
  }
168
198
  if (counts.skillActionCount > 0) {
169
199
  segments.push(`updated ${plural(counts.skillActionCount, 'skill setting')}`);
@@ -272,14 +302,44 @@ function summarizeToolActivity(part, toolHandler, progress, fallbackId) {
272
302
  case 'listMoldableAppApi':
273
303
  case 'callMoldableAppApi':
274
304
  incrementActivityCount(counts, 'apiCallCount');
275
- content = (_jsxs(_Fragment, { children: [_jsx("span", { children: running
276
- ? part.toolName === 'listMoldableAppApi'
277
- ? 'Listing app APIs'
278
- : 'Calling app API'
279
- : part.toolName === 'listMoldableAppApi'
280
- ? 'Listed app APIs'
281
- : 'Called app API' }), target && (_jsxs(_Fragment, { children: [' ', _jsx(ActivityCode, { title: target, children: target })] }))] }));
305
+ {
306
+ const apiTarget = getAppApiTarget(part);
307
+ const apiMethod = getAppApiMethod(part);
308
+ const apiSummaryLabel = apiMethod ?? apiTarget;
309
+ const apiTitle = apiMethod && apiTarget
310
+ ? `${apiTarget}: ${apiMethod}`
311
+ : apiSummaryLabel;
312
+ content = (_jsxs(_Fragment, { children: [_jsx("span", { children: running
313
+ ? part.toolName === 'listMoldableAppApi'
314
+ ? 'Listing app APIs'
315
+ : 'Calling app API'
316
+ : part.toolName === 'listMoldableAppApi'
317
+ ? 'Listed app APIs'
318
+ : 'Called app API' }), apiSummaryLabel && (_jsxs(_Fragment, { children: [' ', _jsx(ActivityCode, { title: apiTitle, children: apiSummaryLabel })] }))] }));
319
+ return {
320
+ entry: {
321
+ id: entryId,
322
+ content: hasError ? (_jsxs(_Fragment, { children: [content, _jsx("span", { children: " failed" })] })) : (content),
323
+ isRunning: running,
324
+ isError: hasError,
325
+ summaryLabel: part.toolName === 'callMoldableAppApi'
326
+ ? apiSummaryLabel
327
+ : undefined,
328
+ },
329
+ counts,
330
+ };
331
+ }
332
+ case 'take_screenshot':
333
+ incrementActivityCount(counts, 'toolCallCount');
334
+ content = running ? 'Taking app screenshot' : 'Captured app screenshot';
282
335
  break;
336
+ case 'viewImage': {
337
+ incrementActivityCount(counts, 'toolCallCount');
338
+ const imagePath = stringValue(args?.imagePath) ?? stringValue(output?.imagePath);
339
+ const imageLabel = getPathLabel(imagePath);
340
+ content = (_jsxs(_Fragment, { children: [_jsx("span", { children: running ? 'Viewing image' : 'Viewed image' }), imageLabel && (_jsxs(_Fragment, { children: [' ', _jsx(ActivityCode, { title: imagePath, children: imageLabel })] }))] }));
341
+ break;
342
+ }
283
343
  case 'listSkillRepos':
284
344
  case 'listAvailableSkills':
285
345
  case 'syncSkills':
@@ -378,10 +438,14 @@ function PureMessage({ message, isLast = false, isStreaming = false, }) {
378
438
  hasText: false,
379
439
  };
380
440
  const updateActivityTitle = (group) => {
381
- group.title = formatActivitySummary(group.counts, group.title, group.isStreaming);
441
+ group.title = formatActivitySummary(group.counts, group.title, group.isStreaming, group.apiCallLabels);
382
442
  };
383
443
  const addActivity = (group, entry, counts) => {
384
444
  group.entries.push(entry);
445
+ if (entry.summaryLabel &&
446
+ !group.apiCallLabels.includes(entry.summaryLabel)) {
447
+ group.apiCallLabels.push(entry.summaryLabel);
448
+ }
385
449
  group.isStreaming = group.isStreaming || Boolean(entry.isRunning);
386
450
  if (counts) {
387
451
  for (const key of Object.keys(counts)) {
@@ -409,6 +473,7 @@ function PureMessage({ message, isLast = false, isStreaming = false, }) {
409
473
  id: `activity-${message.id}-${state.activityGroupIndex}`,
410
474
  entries: [],
411
475
  counts: emptyActivityCounts(),
476
+ apiCallLabels: [],
412
477
  title: DEFAULT_ACTIONS_LABEL,
413
478
  isStreaming: false,
414
479
  };
@@ -463,10 +528,30 @@ function PureMessage({ message, isLast = false, isStreaming = false, }) {
463
528
  });
464
529
  continue;
465
530
  }
466
- const group = ensureActivityGroup();
467
531
  const progress = part.toolCallId
468
532
  ? toolProgress[part.toolCallId]
469
533
  : undefined;
534
+ const shouldRenderImageToolInline = part.toolName === 'take_screenshot' ||
535
+ part.toolName === 'generateImage';
536
+ if (shouldRenderImageToolInline && isToolLoading(part, progress)) {
537
+ closeActivityGroup();
538
+ items.push({
539
+ type: 'inline-tool',
540
+ id: key,
541
+ content: toolHandler.renderLoading?.(part.args) ?? null,
542
+ });
543
+ continue;
544
+ }
545
+ if (shouldRenderImageToolInline && part.output !== undefined) {
546
+ closeActivityGroup();
547
+ items.push({
548
+ type: 'inline-tool',
549
+ id: key,
550
+ content: toolHandler.renderOutput(part.output, part.toolCallId || key),
551
+ });
552
+ continue;
553
+ }
554
+ const group = ensureActivityGroup();
470
555
  const activity = summarizeToolActivity(part, toolHandler, progress, key);
471
556
  addActivity(group, activity.entry, activity.counts);
472
557
  continue;
@@ -648,3 +733,6 @@ export const Message = memo(PureMessage);
648
733
  export function ThinkingMessage() {
649
734
  return (_jsx(motion.div, { "data-testid": "message-assistant-loading", className: "group/message w-full px-2", initial: { y: 5, opacity: 0 }, animate: { y: 0, opacity: 1, transition: { delay: 0.5 } }, "data-role": "assistant", children: _jsx("div", { className: "text-muted-foreground/75 px-2 text-[13px] leading-5", children: _jsx("span", { className: "animate-pulse select-none", children: "Thinking" }) }) }));
650
735
  }
736
+ export function CompactingMessage() {
737
+ return (_jsx(motion.div, { "data-testid": "message-compacting", className: "w-full px-4 py-1", initial: { y: 3, opacity: 0 }, animate: { y: 0, opacity: 1 }, "data-role": "assistant", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "bg-border h-px min-w-8 flex-1" }), _jsx("span", { className: "moldable-chat-shimmer select-none whitespace-nowrap text-[13px] font-medium leading-5", children: "Compacting conversation..." }), _jsx("div", { className: "bg-border h-px min-w-8 flex-1" })] }) }));
738
+ }
@@ -17,6 +17,7 @@ interface MessagesProps {
17
17
  restoringMessageId?: string | null;
18
18
  /** Callback when restore is requested for a message */
19
19
  onRestoreCheckpoint?: (messageId: string) => void;
20
+ isCompacting?: boolean;
20
21
  }
21
22
  export declare function computeIsThinking(messages: ChatMessage[], status: ChatStatus): boolean;
22
23
  interface MessageRowProps {
@@ -29,7 +30,7 @@ interface MessageRowProps {
29
30
  }
30
31
  declare function PureMessageRow({ message, isLast, isStreaming, checkpoint, restoringMessageId, onRestoreCheckpoint, }: MessageRowProps): import("react/jsx-runtime").JSX.Element;
31
32
  export declare const MessageRow: import("react").MemoExoticComponent<typeof PureMessageRow>;
32
- declare function PureMessages({ messages, status, checkpoints, restoringMessageId, onRestoreCheckpoint, }: MessagesProps): import("react/jsx-runtime").JSX.Element;
33
+ declare function PureMessages({ messages, status, checkpoints, restoringMessageId, onRestoreCheckpoint, isCompacting, }: MessagesProps): import("react/jsx-runtime").JSX.Element;
33
34
  export declare const Messages: import("react").MemoExoticComponent<typeof PureMessages>;
34
35
  export {};
35
36
  //# sourceMappingURL=chat-messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-messages.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-messages.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAA4B,MAAM,gBAAgB,CAAA;AAG3E,KAAK,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAA;AAE/D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,aAAa;IACrB,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,MAAM,EAAE,UAAU,CAAA;IAClB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IAC5C,0CAA0C;IAC1C,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CAClD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,WAwB5E;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CAClD;AAED,iBAAS,cAAc,CAAC,EACtB,OAAO,EACP,MAAM,EACN,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,mBAAmB,GACpB,EAAE,eAAe,2CAsBjB;AAED,eAAO,MAAM,UAAU,4DAAuB,CAAA;AAE9C,iBAAS,YAAY,CAAC,EACpB,QAAQ,EACR,MAAM,EACN,WAAW,EACX,kBAAkB,EAClB,mBAAmB,GACpB,EAAE,aAAa,2CAyBf;AAED,eAAO,MAAM,QAAQ,0DAAqB,CAAA"}
1
+ {"version":3,"file":"chat-messages.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-messages.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,gBAAgB,CAAA;AAGvB,KAAK,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAA;AAE/D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,aAAa;IACrB,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,MAAM,EAAE,UAAU,CAAA;IAClB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IAC5C,0CAA0C;IAC1C,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IACjD,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,WAwB5E;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CAClD;AAED,iBAAS,cAAc,CAAC,EACtB,OAAO,EACP,MAAM,EACN,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,mBAAmB,GACpB,EAAE,eAAe,2CAsBjB;AAED,eAAO,MAAM,UAAU,4DAAuB,CAAA;AAE9C,iBAAS,YAAY,CAAC,EACpB,QAAQ,EACR,MAAM,EACN,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,YAAoB,GACrB,EAAE,aAAa,2CA0Bf;AAED,eAAO,MAAM,QAAQ,0DAAqB,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { memo } from 'react';
3
- import { Message, ThinkingMessage } from './chat-message';
3
+ import { CompactingMessage, Message, ThinkingMessage, } from './chat-message';
4
4
  import { CheckpointBadge } from './checkpoint-badge';
5
5
  export function computeIsThinking(messages, status) {
6
6
  const lastMessage = messages[messages.length - 1];
@@ -30,12 +30,12 @@ function PureMessageRow({ message, isLast, isStreaming, checkpoint, restoringMes
30
30
  return (_jsxs("div", { className: "group/message-row relative", children: [_jsx(Message, { message: message, isLast: isLast, isStreaming: isStreaming }), showCheckpointBadge && (_jsx("div", { className: "absolute bottom-1 right-4 opacity-0 transition-opacity group-hover/message-row:opacity-100", children: _jsx(CheckpointBadge, { messageId: message.id, fileCount: checkpoint.fileCount, totalBytes: checkpoint.totalBytes, isRestoring: restoringMessageId === message.id, onRestore: () => onRestoreCheckpoint(message.id) }) }))] }));
31
31
  }
32
32
  export const MessageRow = memo(PureMessageRow);
33
- function PureMessages({ messages, status, checkpoints, restoringMessageId, onRestoreCheckpoint, }) {
33
+ function PureMessages({ messages, status, checkpoints, restoringMessageId, onRestoreCheckpoint, isCompacting = false, }) {
34
34
  const isThinking = computeIsThinking(messages, status);
35
35
  const isStreaming = status === 'streaming' || status === 'submitted';
36
36
  return (_jsxs(_Fragment, { children: [messages.map((message, index) => {
37
37
  const checkpoint = checkpoints?.get(message.id);
38
38
  return (_jsx(MessageRow, { message: message, isLast: index === messages.length - 1, isStreaming: isStreaming, checkpoint: checkpoint, restoringMessageId: restoringMessageId, onRestoreCheckpoint: onRestoreCheckpoint }, message.id));
39
- }), isThinking && _jsx(ThinkingMessage, {})] }));
39
+ }), isThinking && _jsx(ThinkingMessage, {}), isCompacting && _jsx(CompactingMessage, {})] }));
40
40
  }
41
41
  export const Messages = memo(PureMessages);
@@ -1,5 +1,5 @@
1
1
  import { type ChangeEvent, type FormEvent, type ReactNode } from 'react';
2
- import { type ChatImageAttachment, type ChatSubmitMode } from './chat-input';
2
+ import { type ChatImageAttachment, type ChatSlashCommandOption, type ChatSubmitMode } from './chat-input';
3
3
  import { type ChatMessage } from './chat-message';
4
4
  import { type MessageCheckpoint } from './chat-messages';
5
5
  import { type ConversationMeta } from './conversation-history';
@@ -21,9 +21,15 @@ export interface QueuedChatMessage {
21
21
  id: string;
22
22
  preview: string;
23
23
  attachmentCount: number;
24
- status?: 'queued' | 'failed';
24
+ status?: 'queued' | 'failed' | 'steering';
25
25
  error?: string;
26
26
  }
27
+ export interface ChatContextUsage {
28
+ usedTokens: number;
29
+ maxTokens: number;
30
+ isEstimate?: boolean;
31
+ compactsAutomatically?: boolean;
32
+ }
27
33
  export interface ChatPanelProps {
28
34
  /** Chat messages */
29
35
  messages: ChatMessage[];
@@ -57,6 +63,8 @@ export interface ChatPanelProps {
57
63
  conversations?: ConversationMeta[];
58
64
  /** Current conversation ID */
59
65
  currentConversationId?: string | null;
66
+ /** Incremented when a conversation is explicitly loaded from history */
67
+ scrollToBottomSignal?: number;
60
68
  /** Handle conversation selection */
61
69
  onSelectConversation?: (id: string) => void;
62
70
  /** Handle conversation deletion */
@@ -111,10 +119,24 @@ export interface ChatPanelProps {
111
119
  onRetryQueuedMessage?: (id: string) => void;
112
120
  /** Send a queued follow-up into the active response immediately */
113
121
  onSteerQueuedMessage?: (id: string) => void;
122
+ /** Reorder queued follow-ups */
123
+ onReorderQueuedMessages?: (activeId: string, overId: string) => void;
124
+ /** Edit a queued follow-up in the composer */
125
+ onEditQueuedMessage?: (id: string) => void;
126
+ /** Slash commands matching the current input */
127
+ slashCommands?: ChatSlashCommandOption[];
128
+ /** Fill the composer with a slash command */
129
+ onSlashCommandSelect?: (command: ChatSlashCommandOption) => void;
130
+ /** Whether a manual compaction command is running */
131
+ isCompacting?: boolean;
132
+ /** Display-message index where the currently compacted context resumes */
133
+ compactedHistoryStartIndex?: number | null;
134
+ /** Estimated chat context usage for the selected model */
135
+ contextUsage?: ChatContextUsage;
114
136
  }
115
137
  /**
116
138
  * Floating chat panel with model selector
117
139
  */
118
- export declare function ChatPanel({ messages, status, isTurnInFlight, input, onInputChange, onSubmit, onStop, onNewChat, models, selectedModel, onModelChange, reasoningEffortOptions, selectedReasoningEffort, onReasoningEffortChange, conversations, currentConversationId, onSelectConversation, onDeleteConversation, placeholder, welcomeMessage, isExpanded, onExpandedChange, isMinimized, onMinimizedChange, className, error, missingApiKey, onAddApiKey, toolProgress, onApprovalResponse, isEditingApp, onEditingAppChange, showEditingAppToggle, checkpoints, restoringMessageId, onRestoreCheckpoint, imageAttachments, onRemoveImageAttachment, isImageDropActive, queuedMessages, onRemoveQueuedMessage, onRetryQueuedMessage, onSteerQueuedMessage, }: ChatPanelProps): import("react/jsx-runtime").JSX.Element;
140
+ export declare function ChatPanel({ messages, status, isTurnInFlight, input, onInputChange, onSubmit, onStop, onNewChat, models, selectedModel, onModelChange, reasoningEffortOptions, selectedReasoningEffort, onReasoningEffortChange, conversations, currentConversationId, scrollToBottomSignal, onSelectConversation, onDeleteConversation, placeholder, welcomeMessage, isExpanded, onExpandedChange, isMinimized, onMinimizedChange, className, error, missingApiKey, onAddApiKey, toolProgress, onApprovalResponse, isEditingApp, onEditingAppChange, showEditingAppToggle, checkpoints, restoringMessageId, onRestoreCheckpoint, imageAttachments, onRemoveImageAttachment, isImageDropActive, queuedMessages, onRemoveQueuedMessage, onRetryQueuedMessage, onSteerQueuedMessage, onReorderQueuedMessages, onEditQueuedMessage, slashCommands, onSlashCommandSelect, isCompacting, compactedHistoryStartIndex, contextUsage, }: ChatPanelProps): import("react/jsx-runtime").JSX.Element;
119
141
  export {};
120
142
  //# sourceMappingURL=chat-panel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-panel.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-panel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-panel.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-panel.tsx"],"names":[],"mappings":"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"}