@ocai/app-sdk-ui 0.1.0 → 0.2.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.
- package/dist/chat/activity-labels.d.ts +15 -0
- package/dist/chat/message-trace.d.ts +16 -0
- package/dist/chat/segments.d.ts +23 -0
- package/dist/chat/sources.d.ts +13 -0
- package/dist/chat/tool-value.d.ts +5 -0
- package/dist/chat/tool.d.ts +3 -3
- package/dist/chat/use-activity-clock.d.ts +2 -0
- package/dist/chat/web-search-toggle.d.ts +9 -0
- package/dist/chat/web-search.d.ts +34 -0
- package/dist/chat.css +115 -6
- package/dist/index.d.ts +7 -0
- package/dist/index.js +521 -97
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type AiActivityKind = "waiting" | "reasoning" | "tools";
|
|
2
|
+
export interface AiActivity {
|
|
3
|
+
seed: number;
|
|
4
|
+
elapsedSeconds: number;
|
|
5
|
+
nowMs: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function getAiActivityLabel({ kind, active, seed, elapsedSeconds, }: Pick<AiActivity, "seed" | "elapsedSeconds"> & {
|
|
8
|
+
kind: AiActivityKind;
|
|
9
|
+
active: boolean;
|
|
10
|
+
}): string;
|
|
11
|
+
export declare function traceElapsedSeconds(parts: ReadonlyArray<{
|
|
12
|
+
startedAtMs?: number;
|
|
13
|
+
completedAtMs?: number;
|
|
14
|
+
}>, nowMs?: number): number;
|
|
15
|
+
export declare function labelSeedFromString(value: string): number;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LucideIcon } from 'lucide-react';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
|
+
import { AiActivity } from './activity-labels';
|
|
4
|
+
import { TracePart } from './segments';
|
|
5
|
+
export declare function humanizeToolName(type: string): string;
|
|
6
|
+
export type MessageTraceProps = {
|
|
7
|
+
parts: readonly TracePart[];
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
messageId: string;
|
|
10
|
+
activity?: AiActivity;
|
|
11
|
+
getToolLabel?: (type: string) => string | undefined;
|
|
12
|
+
getToolIcon?: (type: string) => LucideIcon | undefined;
|
|
13
|
+
defaultOpen?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const MessageTrace: ({ parts, isLoading, messageId, activity, getToolLabel, getToolIcon, defaultOpen, className, }: MessageTraceProps) => ReactElement;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type TracePart = {
|
|
2
|
+
type: string;
|
|
3
|
+
startedAtMs?: number;
|
|
4
|
+
completedAtMs?: number;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
};
|
|
7
|
+
export type MessageSegment = {
|
|
8
|
+
kind: "trace";
|
|
9
|
+
parts: TracePart[];
|
|
10
|
+
} | {
|
|
11
|
+
kind: "images";
|
|
12
|
+
parts: TracePart[];
|
|
13
|
+
index: number;
|
|
14
|
+
} | {
|
|
15
|
+
kind: "part";
|
|
16
|
+
part: TracePart;
|
|
17
|
+
index: number;
|
|
18
|
+
};
|
|
19
|
+
export type BuildSegmentsOptions = {
|
|
20
|
+
isPresentationalTool?: (type: string) => boolean;
|
|
21
|
+
};
|
|
22
|
+
export declare function buildSegments(parts: readonly TracePart[], options?: BuildSegmentsOptions): MessageSegment[];
|
|
23
|
+
export declare function traceIsLoading(parts: readonly TracePart[], messageLoading: boolean): boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ComponentProps, ReactElement } from 'react';
|
|
2
|
+
import { Collapsible } from '../internal/collapsible';
|
|
3
|
+
export type SourceItem = {
|
|
4
|
+
url: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
};
|
|
7
|
+
export type SourcesProps = Omit<ComponentProps<typeof Collapsible>, "children"> & {
|
|
8
|
+
sources: readonly SourceItem[];
|
|
9
|
+
label?: (count: number) => string;
|
|
10
|
+
getFaviconUrl?: (url: string) => string | null;
|
|
11
|
+
};
|
|
12
|
+
export declare const Sources: ({ sources, label, getFaviconUrl, className, ...props }: SourcesProps) => ReactElement | null;
|
|
13
|
+
export declare const citationClassName = "ocui-cite";
|
package/dist/chat/tool.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ToolUIPart } from 'ai';
|
|
2
|
-
import { ComponentProps
|
|
2
|
+
import { ComponentProps } from 'react';
|
|
3
3
|
import { Collapsible, CollapsibleContent } from '../internal/collapsible';
|
|
4
4
|
export type ToolProps = ComponentProps<typeof Collapsible>;
|
|
5
5
|
export declare const Tool: ({ className, ...props }: ToolProps) => import("react").JSX.Element;
|
|
@@ -15,9 +15,9 @@ export declare const ToolContent: ({ className, ...props }: ToolContentProps) =>
|
|
|
15
15
|
export type ToolInputProps = ComponentProps<"div"> & {
|
|
16
16
|
input: ToolUIPart["input"];
|
|
17
17
|
};
|
|
18
|
-
export declare const ToolInput: ({ className, input, ...props }: ToolInputProps) => import("react").JSX.Element;
|
|
18
|
+
export declare const ToolInput: ({ className, input, ...props }: ToolInputProps) => import("react").JSX.Element | null;
|
|
19
19
|
export type ToolOutputProps = ComponentProps<"div"> & {
|
|
20
|
-
output:
|
|
20
|
+
output: unknown;
|
|
21
21
|
errorText: ToolUIPart["errorText"];
|
|
22
22
|
};
|
|
23
23
|
export declare const ToolOutput: ({ className, output, errorText, ...props }: ToolOutputProps) => import("react").JSX.Element | null;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ComponentProps } from 'react';
|
|
2
|
+
import { Button } from '../internal/button';
|
|
3
|
+
export type WebSearchToggleProps = Omit<ComponentProps<typeof Button>, "children"> & {
|
|
4
|
+
pressed: boolean;
|
|
5
|
+
onPressedChange: (pressed: boolean) => void;
|
|
6
|
+
label?: string;
|
|
7
|
+
tooltip?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const WebSearchToggle: ({ pressed, onPressedChange, label, tooltip, className, variant, size, onClick, ...props }: WebSearchToggleProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ToolUIPart } from 'ai';
|
|
2
|
+
import { SourceItem } from './sources';
|
|
3
|
+
export interface WebSearchInput {
|
|
4
|
+
query: string;
|
|
5
|
+
}
|
|
6
|
+
export interface WebSearchResult {
|
|
7
|
+
title: string;
|
|
8
|
+
url: string;
|
|
9
|
+
content: string;
|
|
10
|
+
score: number;
|
|
11
|
+
}
|
|
12
|
+
export interface WebSearchSuccessOutput {
|
|
13
|
+
query: string;
|
|
14
|
+
results: WebSearchResult[];
|
|
15
|
+
}
|
|
16
|
+
export interface WebSearchErrorOutput {
|
|
17
|
+
error: string;
|
|
18
|
+
}
|
|
19
|
+
export type WebSearchOutput = WebSearchSuccessOutput | WebSearchErrorOutput;
|
|
20
|
+
export type WebSearchUITool = {
|
|
21
|
+
input: WebSearchInput;
|
|
22
|
+
output: WebSearchOutput;
|
|
23
|
+
};
|
|
24
|
+
export type WebSearchUIPart = ToolUIPart<{
|
|
25
|
+
webSearch: WebSearchUITool;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function isWebSearchError(output: unknown): output is WebSearchErrorOutput;
|
|
28
|
+
export declare function extractWebSearchSources(parts: ReadonlyArray<{
|
|
29
|
+
type?: string;
|
|
30
|
+
state?: string;
|
|
31
|
+
output?: unknown;
|
|
32
|
+
}>, options?: {
|
|
33
|
+
toolType?: string;
|
|
34
|
+
}): SourceItem[];
|
package/dist/chat.css
CHANGED
|
@@ -60,16 +60,125 @@
|
|
|
60
60
|
@apply font-medium text-foreground;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
/* --- Code block:
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
/* --- Code block: Claude.ai-style shell. ONE subtle card; the language is a
|
|
64
|
+
plain muted label (no header bar, no divider); and a single copy button
|
|
65
|
+
fades in on hover at the top-right (download is turned off via the
|
|
66
|
+
`controls` prop in chat/response.tsx). Streamdown frames the block with its
|
|
67
|
+
own utility classes as a padded `bg-sidebar` card wrapping a SECOND bordered
|
|
68
|
+
`bg-background` card, plus an always-visible copy/download pill floated up
|
|
69
|
+
by -mt-10 — we flatten both cards into one and re-home the copy overlay. */
|
|
66
70
|
.ocui-md [data-streamdown="code-block"] {
|
|
67
|
-
@apply my-4 overflow-hidden rounded-lg border border-border;
|
|
71
|
+
@apply relative my-4 gap-0 overflow-hidden rounded-lg border border-border bg-muted/40 p-0;
|
|
68
72
|
}
|
|
73
|
+
/* Language label: not a bar — small muted text with padding, no divider. The
|
|
74
|
+
inner <span> is Streamdown's `font-mono lowercase ml-1`; drop the mono and
|
|
75
|
+
the indent so the label lines up with the code's left edge. */
|
|
69
76
|
.ocui-md [data-streamdown="code-block-header"] {
|
|
70
|
-
@apply
|
|
77
|
+
@apply h-auto px-4 pt-3 pb-0 text-xs font-normal text-muted-foreground;
|
|
71
78
|
}
|
|
79
|
+
.ocui-md [data-streamdown="code-block-header"] span {
|
|
80
|
+
@apply ml-0 font-sans;
|
|
81
|
+
}
|
|
82
|
+
/* Copy overlay: Streamdown wraps the buttons in an un-hooked div (no
|
|
83
|
+
data-streamdown), floated by `-mt-10` and always visible. Target it as the
|
|
84
|
+
div directly wrapping `code-block-actions` (mirrors the table's :has hook),
|
|
85
|
+
pin it top-right, and fade it in only on hover / keyboard focus. */
|
|
86
|
+
.ocui-md [data-streamdown="code-block"] > div:has(> [data-streamdown="code-block-actions"]) {
|
|
87
|
+
@apply absolute right-2 top-2 z-10 mt-0 h-auto opacity-0 transition-opacity;
|
|
88
|
+
}
|
|
89
|
+
.ocui-md [data-streamdown="code-block"]:hover > div:has(> [data-streamdown="code-block-actions"]),
|
|
90
|
+
.ocui-md [data-streamdown="code-block"]:focus-within > div:has(> [data-streamdown="code-block-actions"]) {
|
|
91
|
+
@apply opacity-100;
|
|
92
|
+
}
|
|
93
|
+
/* Drop the pill chrome (border + tinted bg) around the button. */
|
|
94
|
+
.ocui-md [data-streamdown="code-block-actions"] {
|
|
95
|
+
@apply gap-1 rounded-md border-0 bg-transparent p-0;
|
|
96
|
+
}
|
|
97
|
+
/* Copy button: 32px square, subtle hover fill, blur so it reads over code. */
|
|
98
|
+
.ocui-md [data-streamdown="code-block-copy-button"] {
|
|
99
|
+
@apply inline-flex h-8 w-8 items-center justify-center rounded-md p-0 backdrop-blur-md hover:bg-muted;
|
|
100
|
+
}
|
|
101
|
+
/* Body: strip Streamdown's inner card (border + rounding + bg) so the code
|
|
102
|
+
sits flush in the single shell; keep horizontal scroll + a code padding. */
|
|
72
103
|
.ocui-md [data-streamdown="code-block-body"] {
|
|
73
|
-
@apply text-sm;
|
|
104
|
+
@apply rounded-none border-0 bg-transparent px-4 pb-4 pt-2 text-sm;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Opt-in inline-citation chips: <Response className={citationClassName}>
|
|
108
|
+
renders model-emitted "[title](url)" citations as compact pills. Opt-in so
|
|
109
|
+
ordinary markdown links elsewhere keep their default look. Streamdown 2.x
|
|
110
|
+
renders markdown links as <button data-streamdown="link"> (click-to-
|
|
111
|
+
confirm hardening), NOT <a href> — so target its data hook like every
|
|
112
|
+
other rule in this file; an href-based selector matches nothing. Stays
|
|
113
|
+
`inline` (never inline-flex) so the pill breaks with the surrounding text
|
|
114
|
+
like any other word instead of forcing a rigid box. */
|
|
115
|
+
.ocui-md.ocui-cite [data-streamdown="link"] {
|
|
116
|
+
@apply inline cursor-pointer rounded-sm bg-muted px-1.5 py-0.5 align-baseline text-xs font-normal text-muted-foreground no-underline transition-colors hover:bg-accent hover:text-accent-foreground;
|
|
117
|
+
}
|
|
118
|
+
/* External-link hint: a small superscript arrow, added via content so it
|
|
119
|
+
never disturbs inline flow the way an <svg> child would. */
|
|
120
|
+
.ocui-md.ocui-cite [data-streamdown="link"]::after {
|
|
121
|
+
content: "↗";
|
|
122
|
+
@apply ml-0.5 align-super text-[0.65em] text-muted-foreground/70;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* Activity-label shimmer: while the model streams, the trigger label
|
|
126
|
+
("Thinking…", "Shaping for 4 seconds") sweeps a full-contrast highlight
|
|
127
|
+
left→right across the muted label text, instead of pulsing the whole word.
|
|
128
|
+
Codex-style (a moving highlight band clipped to the glyphs). Base is the
|
|
129
|
+
muted label color; the highlight is the foreground seed. Applied by
|
|
130
|
+
Reasoning/MessageTrace's trigger only while streaming; reduced-motion
|
|
131
|
+
falls back to solid muted text. */
|
|
132
|
+
.ocui-shimmer {
|
|
133
|
+
/* Two glyph-clipped layers. LAYER 1 (background-color) is a SOLID base that
|
|
134
|
+
always fills every glyph, so text is never transparent. LAYER 2 (gradient,
|
|
135
|
+
painted on top) is transparent at both ends with an opaque --foreground band
|
|
136
|
+
in the middle — only that band tints the glyphs; elsewhere the base shows. */
|
|
137
|
+
background-color: var(--muted-foreground);
|
|
138
|
+
background-image: linear-gradient(
|
|
139
|
+
to right,
|
|
140
|
+
transparent 0%,
|
|
141
|
+
var(--foreground) 40%,
|
|
142
|
+
var(--foreground) 60%,
|
|
143
|
+
transparent 100%
|
|
144
|
+
);
|
|
145
|
+
background-size: 50% 100%;
|
|
146
|
+
background-repeat: no-repeat;
|
|
147
|
+
background-position: -100% 0;
|
|
148
|
+
-webkit-background-clip: text;
|
|
149
|
+
background-clip: text;
|
|
150
|
+
-webkit-text-fill-color: transparent;
|
|
151
|
+
color: transparent;
|
|
152
|
+
display: inline-block;
|
|
153
|
+
animation: ocui-shimmer-sweep 1.6s linear infinite;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* --- Tool call params/results (chat/tool-value.tsx). Structured shallow
|
|
157
|
+
objects render as aligned key–value rows; deep/large values fall back to
|
|
158
|
+
this single muted mono block — a refined replacement for the old heavy
|
|
159
|
+
bg-muted/50 JSON.stringify dump. --- */
|
|
160
|
+
.ocui-tool-json {
|
|
161
|
+
tab-size: 2;
|
|
162
|
+
line-height: 1.5;
|
|
163
|
+
max-height: 22rem;
|
|
164
|
+
overflow: auto;
|
|
165
|
+
}
|
|
166
|
+
/* Key column top-aligns with the first line of a wrapping value. */
|
|
167
|
+
.ocui-tool-kv > li > span:first-child {
|
|
168
|
+
align-self: start;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@keyframes ocui-shimmer-sweep {
|
|
173
|
+
from { background-position: -100% 0; }
|
|
174
|
+
to { background-position: 250% 0; }
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@media (prefers-reduced-motion: reduce) {
|
|
178
|
+
.ocui-shimmer {
|
|
179
|
+
animation: none;
|
|
180
|
+
background-image: none;
|
|
181
|
+
-webkit-text-fill-color: var(--muted-foreground);
|
|
182
|
+
color: var(--muted-foreground);
|
|
74
183
|
}
|
|
75
184
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,3 +3,10 @@ export { MessageContent, type MessageContentProps, type MessageContentVariant, }
|
|
|
3
3
|
export { Reasoning, ReasoningContent, ReasoningTrigger, reasoningTextClassName, type ReasoningProps, type ReasoningTriggerProps, } from './chat/reasoning';
|
|
4
4
|
export { Tool, ToolContent, ToolHeader, ToolInput, ToolOutput, type ToolContentProps, type ToolHeaderProps, type ToolInputProps, type ToolOutputProps, type ToolProps, } from './chat/tool';
|
|
5
5
|
export { Action, Actions, type ActionProps, type ActionsProps, } from './chat/actions';
|
|
6
|
+
export { MessageTrace, humanizeToolName, type MessageTraceProps, } from './chat/message-trace';
|
|
7
|
+
export { buildSegments, traceIsLoading, type BuildSegmentsOptions, type MessageSegment, type TracePart, } from './chat/segments';
|
|
8
|
+
export { getAiActivityLabel, labelSeedFromString, traceElapsedSeconds, type AiActivity, type AiActivityKind, } from './chat/activity-labels';
|
|
9
|
+
export { useActivityClock } from './chat/use-activity-clock';
|
|
10
|
+
export { Sources, citationClassName, type SourceItem, type SourcesProps, } from './chat/sources';
|
|
11
|
+
export { extractWebSearchSources, isWebSearchError, type WebSearchErrorOutput, type WebSearchInput, type WebSearchOutput, type WebSearchResult, type WebSearchSuccessOutput, type WebSearchUIPart, type WebSearchUITool, } from './chat/web-search';
|
|
12
|
+
export { WebSearchToggle, type WebSearchToggleProps, } from './chat/web-search-toggle';
|
package/dist/index.js
CHANGED
|
@@ -4,78 +4,81 @@ import { Streamdown as t } from "streamdown";
|
|
|
4
4
|
import { clsx as n } from "clsx";
|
|
5
5
|
import { twMerge as r } from "tailwind-merge";
|
|
6
6
|
import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
7
|
-
import { CheckIcon as s, ChevronDownIcon as c,
|
|
8
|
-
import { createContext as
|
|
9
|
-
import { Collapsible as
|
|
10
|
-
import { cva as
|
|
7
|
+
import { CheckIcon as s, ChevronDownIcon as c, CircleCheckIcon as l, ClockIcon as u, GlobeIcon as d, Loader2Icon as f, WrenchIcon as p, XIcon as m } from "lucide-react";
|
|
8
|
+
import { createContext as h, isValidElement as g, memo as _, useContext as v, useEffect as y, useRef as ee, useState as b } from "react";
|
|
9
|
+
import { Collapsible as x, Slot as te, Tooltip as S } from "radix-ui";
|
|
10
|
+
import { cva as ne } from "class-variance-authority";
|
|
11
11
|
//#region src/lib/cn.ts
|
|
12
|
-
function
|
|
12
|
+
function C(...e) {
|
|
13
13
|
return r(n(e));
|
|
14
14
|
}
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/chat/response.tsx
|
|
17
|
-
var
|
|
18
|
-
function
|
|
17
|
+
var re = e({ singleDollarTextMath: !0 });
|
|
18
|
+
function ie({ className: e, ...n }) {
|
|
19
19
|
return /* @__PURE__ */ a(t, {
|
|
20
|
-
className:
|
|
21
|
-
plugins: { math:
|
|
22
|
-
controls: {
|
|
20
|
+
className: C("ocui-md size-full text-base font-normal leading-6 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&_code]:whitespace-pre-wrap [&_code]:wrap-break-word [&_pre]:max-w-full [&_pre]:overflow-x-auto", e),
|
|
21
|
+
plugins: { math: re },
|
|
22
|
+
controls: {
|
|
23
|
+
table: !1,
|
|
24
|
+
code: { download: !1 }
|
|
25
|
+
},
|
|
23
26
|
...n
|
|
24
27
|
});
|
|
25
28
|
}
|
|
26
29
|
//#endregion
|
|
27
30
|
//#region src/chat/message.tsx
|
|
28
|
-
var
|
|
31
|
+
var ae = {
|
|
29
32
|
user: "w-fit wrap-break-word rounded-md bg-card px-3 py-1.5 text-primary",
|
|
30
33
|
assistant: "bg-transparent px-0 py-0 text-left text-foreground"
|
|
31
|
-
},
|
|
32
|
-
className:
|
|
34
|
+
}, oe = ({ children: e, className: t, variant: n = "user", ...r }) => /* @__PURE__ */ a("div", {
|
|
35
|
+
className: C("flex flex-col gap-2 overflow-hidden text-base font-normal leading-6", ae[n], t),
|
|
33
36
|
...r,
|
|
34
37
|
children: e
|
|
35
38
|
});
|
|
36
39
|
//#endregion
|
|
37
40
|
//#region src/internal/collapsible.tsx
|
|
38
|
-
function
|
|
39
|
-
return /* @__PURE__ */ a(
|
|
41
|
+
function w({ ...e }) {
|
|
42
|
+
return /* @__PURE__ */ a(x.Root, {
|
|
40
43
|
"data-slot": "collapsible",
|
|
41
44
|
...e
|
|
42
45
|
});
|
|
43
46
|
}
|
|
44
|
-
function
|
|
45
|
-
return /* @__PURE__ */ a(
|
|
47
|
+
function T({ ...e }) {
|
|
48
|
+
return /* @__PURE__ */ a(x.CollapsibleTrigger, {
|
|
46
49
|
"data-slot": "collapsible-trigger",
|
|
47
50
|
...e
|
|
48
51
|
});
|
|
49
52
|
}
|
|
50
|
-
function
|
|
51
|
-
return /* @__PURE__ */ a(
|
|
53
|
+
function E({ ...e }) {
|
|
54
|
+
return /* @__PURE__ */ a(x.CollapsibleContent, {
|
|
52
55
|
"data-slot": "collapsible-content",
|
|
53
56
|
...e
|
|
54
57
|
});
|
|
55
58
|
}
|
|
56
59
|
//#endregion
|
|
57
60
|
//#region src/chat/reasoning.tsx
|
|
58
|
-
function
|
|
59
|
-
let [r, i] =
|
|
61
|
+
function se({ prop: e, defaultProp: t, onChange: n }) {
|
|
62
|
+
let [r, i] = b(t), a = e !== void 0;
|
|
60
63
|
return [a ? e : r, (e) => {
|
|
61
64
|
a || i(e), n?.(e);
|
|
62
65
|
}];
|
|
63
66
|
}
|
|
64
|
-
var
|
|
65
|
-
let e =
|
|
67
|
+
var D = h(null), ce = () => {
|
|
68
|
+
let e = v(D);
|
|
66
69
|
if (!e) throw Error("Reasoning components must be used within Reasoning");
|
|
67
70
|
return e;
|
|
68
|
-
},
|
|
69
|
-
let [l, u] =
|
|
71
|
+
}, le = 500, O = _(({ className: e, isStreaming: t = !1, duration: n = 0, open: r, defaultOpen: i = !0, onOpenChange: o, children: s, ...c }) => {
|
|
72
|
+
let [l, u] = se({
|
|
70
73
|
prop: r,
|
|
71
74
|
defaultProp: i,
|
|
72
75
|
onChange: o
|
|
73
|
-
}), [d, f] =
|
|
74
|
-
return
|
|
76
|
+
}), [d, f] = b(!1);
|
|
77
|
+
return y(() => {
|
|
75
78
|
if (i && !t && l && !d) {
|
|
76
79
|
let e = setTimeout(() => {
|
|
77
80
|
u(!1), f(!0);
|
|
78
|
-
},
|
|
81
|
+
}, le);
|
|
79
82
|
return () => clearTimeout(e);
|
|
80
83
|
}
|
|
81
84
|
}, [
|
|
@@ -84,15 +87,15 @@ var j = p(null), M = () => {
|
|
|
84
87
|
i,
|
|
85
88
|
u,
|
|
86
89
|
d
|
|
87
|
-
]), /* @__PURE__ */ a(
|
|
90
|
+
]), /* @__PURE__ */ a(D.Provider, {
|
|
88
91
|
value: {
|
|
89
92
|
isStreaming: t,
|
|
90
93
|
isOpen: l,
|
|
91
94
|
setIsOpen: u,
|
|
92
95
|
duration: n
|
|
93
96
|
},
|
|
94
|
-
children: /* @__PURE__ */ a(
|
|
95
|
-
className:
|
|
97
|
+
children: /* @__PURE__ */ a(w, {
|
|
98
|
+
className: C("not-prose", e),
|
|
96
99
|
onOpenChange: u,
|
|
97
100
|
open: l,
|
|
98
101
|
...c,
|
|
@@ -100,39 +103,106 @@ var j = p(null), M = () => {
|
|
|
100
103
|
})
|
|
101
104
|
});
|
|
102
105
|
});
|
|
103
|
-
function
|
|
106
|
+
function ue({ variant: e, isStreaming: t, duration: n }) {
|
|
104
107
|
let r = e === "tools";
|
|
105
108
|
return t ? r ? "Working…" : "Thinking…" : n > 0 ? r ? `Worked for ${n}s` : `Thought for ${n}s` : r ? "Worked" : "Thought";
|
|
106
109
|
}
|
|
107
|
-
var
|
|
108
|
-
let { isStreaming: l, isOpen: u, duration:
|
|
110
|
+
var k = _(({ className: e, children: t, variant: n = "reasoning", label: r, ...s }) => {
|
|
111
|
+
let { isStreaming: l, isOpen: u, duration: d } = ce(), f = r ?? ue({
|
|
109
112
|
variant: n,
|
|
110
113
|
isStreaming: l,
|
|
111
|
-
duration:
|
|
114
|
+
duration: d
|
|
112
115
|
});
|
|
113
|
-
return /* @__PURE__ */ a(
|
|
114
|
-
className:
|
|
116
|
+
return /* @__PURE__ */ a(T, {
|
|
117
|
+
className: C("flex items-center gap-1 rounded-md px-1.5 py-0.5 text-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", e),
|
|
115
118
|
...s,
|
|
116
119
|
children: t ?? /* @__PURE__ */ o(i, { children: [
|
|
117
|
-
n === "tools" && /* @__PURE__ */ a(
|
|
120
|
+
n === "tools" && /* @__PURE__ */ a(p, { className: "size-3" }),
|
|
118
121
|
/* @__PURE__ */ a("span", {
|
|
119
|
-
className:
|
|
120
|
-
children:
|
|
122
|
+
className: C(l && "ocui-shimmer"),
|
|
123
|
+
children: f
|
|
121
124
|
}),
|
|
122
|
-
/* @__PURE__ */ a(c, { className:
|
|
125
|
+
/* @__PURE__ */ a(c, { className: C("size-2.5 transition-transform", u ? "rotate-180" : "rotate-0") })
|
|
123
126
|
] })
|
|
124
127
|
});
|
|
125
|
-
}),
|
|
126
|
-
className:
|
|
128
|
+
}), A = "grid gap-1 text-sm text-muted-foreground/80 **:text-sm [&_code]:bg-transparent [&_code]:p-0 [&_code]:font-semibold [&_code]:text-foreground [&_li]:my-0 [&_ol]:my-1 [&_p]:my-0 [&_ul]:my-1", j = _(({ className: e, ...t }) => /* @__PURE__ */ a(E, {
|
|
129
|
+
className: C(A, "mt-1.5", e),
|
|
127
130
|
...t
|
|
128
131
|
}));
|
|
129
|
-
|
|
132
|
+
O.displayName = "Reasoning", k.displayName = "ReasoningTrigger", j.displayName = "ReasoningContent";
|
|
130
133
|
//#endregion
|
|
131
|
-
//#region src/chat/tool.tsx
|
|
132
|
-
var
|
|
133
|
-
|
|
134
|
+
//#region src/chat/tool-value.tsx
|
|
135
|
+
var de = 8, M = 240, N = 2e4, P = (e) => e === null || typeof e != "object" && typeof e != "function", F = (e) => {
|
|
136
|
+
if (typeof e != "object" || !e) return !1;
|
|
137
|
+
let t = Object.getPrototypeOf(e);
|
|
138
|
+
return t === Object.prototype || t === null;
|
|
139
|
+
}, I = (e) => Array.isArray(e) && e.every(P), fe = (e) => {
|
|
140
|
+
if (!F(e)) return !1;
|
|
141
|
+
let t = Object.keys(e);
|
|
142
|
+
return t.length === 0 || t.length > de ? !1 : t.every((t) => P(e[t]) || I(e[t]));
|
|
143
|
+
}, L = (e) => g(e) ? !0 : e == null ? !1 : typeof e == "string" ? e.trim().length > 0 : P(e) ? !0 : Array.isArray(e) ? e.length > 0 : F(e) ? Object.keys(e).length > 0 : !0, pe = (e) => {
|
|
144
|
+
try {
|
|
145
|
+
let t = JSON.stringify(e, null, 2);
|
|
146
|
+
return t === void 0 ? String(e) : t.length > N ? `${t.slice(0, N)}\n… (truncated)` : t;
|
|
147
|
+
} catch {
|
|
148
|
+
return String(e);
|
|
149
|
+
}
|
|
150
|
+
}, R = ({ value: e }) => {
|
|
151
|
+
if (e == null) return /* @__PURE__ */ a("span", {
|
|
152
|
+
className: "font-mono text-muted-foreground",
|
|
153
|
+
children: "null"
|
|
154
|
+
});
|
|
155
|
+
if (typeof e != "string") return /* @__PURE__ */ a("span", {
|
|
156
|
+
className: "font-mono text-foreground",
|
|
157
|
+
children: String(e)
|
|
158
|
+
});
|
|
159
|
+
if (e === "") return /* @__PURE__ */ a("span", {
|
|
160
|
+
className: "text-muted-foreground italic",
|
|
161
|
+
children: "empty"
|
|
162
|
+
});
|
|
163
|
+
let t = e.length > M;
|
|
164
|
+
return /* @__PURE__ */ a("span", {
|
|
165
|
+
className: "text-foreground",
|
|
166
|
+
title: t ? e : void 0,
|
|
167
|
+
children: t ? `${e.slice(0, M)}…` : e
|
|
168
|
+
});
|
|
169
|
+
}, z = ({ value: e }) => e.length === 0 ? /* @__PURE__ */ a("span", {
|
|
170
|
+
className: "text-muted-foreground italic",
|
|
171
|
+
children: "none"
|
|
172
|
+
}) : /* @__PURE__ */ a("span", {
|
|
173
|
+
className: "text-foreground",
|
|
174
|
+
children: e.map((e, t) => /* @__PURE__ */ o("span", { children: [t > 0 && /* @__PURE__ */ a("span", {
|
|
175
|
+
className: "px-1 text-muted-foreground/70",
|
|
176
|
+
children: "·"
|
|
177
|
+
}), /* @__PURE__ */ a(R, { value: e })] }, t))
|
|
178
|
+
}), me = ({ data: e }) => /* @__PURE__ */ a("ul", {
|
|
179
|
+
className: "ocui-tool-kv grid min-w-0 grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-xs",
|
|
180
|
+
children: Object.entries(e).map(([e, t]) => /* @__PURE__ */ o("li", {
|
|
181
|
+
className: "contents",
|
|
182
|
+
children: [/* @__PURE__ */ a("span", {
|
|
183
|
+
className: "break-words text-muted-foreground",
|
|
184
|
+
children: e
|
|
185
|
+
}), /* @__PURE__ */ a("span", {
|
|
186
|
+
className: "min-w-0 break-words whitespace-pre-wrap",
|
|
187
|
+
children: I(t) ? /* @__PURE__ */ a(z, { value: t }) : /* @__PURE__ */ a(R, { value: t })
|
|
188
|
+
})]
|
|
189
|
+
}, e))
|
|
190
|
+
}), he = ({ value: e }) => /* @__PURE__ */ a("pre", {
|
|
191
|
+
className: "ocui-tool-json overflow-x-auto rounded-md bg-muted/40 px-2.5 py-2 font-mono text-xs text-muted-foreground",
|
|
192
|
+
children: pe(e)
|
|
193
|
+
}), B = ({ value: e }) => g(e) ? /* @__PURE__ */ a(i, { children: e }) : e == null ? null : typeof e == "string" ? e.trim() === "" ? null : /* @__PURE__ */ a("div", {
|
|
194
|
+
className: "whitespace-pre-wrap break-words font-mono text-xs leading-relaxed text-muted-foreground",
|
|
195
|
+
children: e
|
|
196
|
+
}) : P(e) ? /* @__PURE__ */ a("div", {
|
|
197
|
+
className: "font-mono text-xs text-foreground",
|
|
198
|
+
children: String(e)
|
|
199
|
+
}) : fe(e) ? /* @__PURE__ */ a(me, { data: e }) : I(e) ? /* @__PURE__ */ a("div", {
|
|
200
|
+
className: "text-xs",
|
|
201
|
+
children: /* @__PURE__ */ a(z, { value: e })
|
|
202
|
+
}) : /* @__PURE__ */ a(he, { value: e }), ge = ({ className: e, ...t }) => /* @__PURE__ */ a(w, {
|
|
203
|
+
className: C("not-prose w-full rounded-md border border-border", e),
|
|
134
204
|
...t
|
|
135
|
-
}),
|
|
205
|
+
}), _e = {
|
|
136
206
|
"input-streaming": "Pending",
|
|
137
207
|
"input-available": "Running",
|
|
138
208
|
"approval-requested": "Pending",
|
|
@@ -140,54 +210,54 @@ var z = ({ className: e, ...t }) => /* @__PURE__ */ a(D, {
|
|
|
140
210
|
"output-available": "Completed",
|
|
141
211
|
"output-error": "Error",
|
|
142
212
|
"output-denied": "Denied"
|
|
143
|
-
},
|
|
144
|
-
"input-streaming": /* @__PURE__ */ a(
|
|
145
|
-
"input-available": /* @__PURE__ */ a(
|
|
146
|
-
"approval-requested": /* @__PURE__ */ a(
|
|
213
|
+
}, ve = {
|
|
214
|
+
"input-streaming": /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin" }),
|
|
215
|
+
"input-available": /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin" }),
|
|
216
|
+
"approval-requested": /* @__PURE__ */ a(u, { className: "size-3.5" }),
|
|
147
217
|
"approval-responded": /* @__PURE__ */ a(s, { className: "size-3.5" }),
|
|
148
218
|
"output-available": /* @__PURE__ */ a(s, { className: "size-3.5" }),
|
|
149
|
-
"output-error": /* @__PURE__ */ a(
|
|
150
|
-
"output-denied": /* @__PURE__ */ a(
|
|
151
|
-
},
|
|
219
|
+
"output-error": /* @__PURE__ */ a(m, { className: "size-3.5 text-destructive" }),
|
|
220
|
+
"output-denied": /* @__PURE__ */ a(m, { className: "size-3.5 text-destructive" })
|
|
221
|
+
}, ye = ({ state: e }) => /* @__PURE__ */ o("span", {
|
|
152
222
|
className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground",
|
|
153
|
-
children: [
|
|
154
|
-
}),
|
|
155
|
-
className:
|
|
223
|
+
children: [ve[e], _e[e]]
|
|
224
|
+
}), be = ({ className: e, type: t, state: n, title: r, ...i }) => /* @__PURE__ */ o(T, {
|
|
225
|
+
className: C("group flex w-full min-w-0 items-center justify-between gap-2 rounded-md p-2.5 transition-colors hover:bg-muted/50", e),
|
|
156
226
|
...i,
|
|
157
227
|
children: [/* @__PURE__ */ o("div", {
|
|
158
228
|
className: "flex min-w-0 flex-1 items-center gap-2",
|
|
159
|
-
children: [/* @__PURE__ */ a(
|
|
229
|
+
children: [/* @__PURE__ */ a(p, { className: "size-3.5 shrink-0 text-muted-foreground" }), /* @__PURE__ */ a("span", {
|
|
160
230
|
className: "truncate text-sm font-medium",
|
|
161
231
|
children: r ?? t
|
|
162
232
|
})]
|
|
163
233
|
}), /* @__PURE__ */ o("div", {
|
|
164
234
|
className: "flex shrink-0 items-center gap-2",
|
|
165
|
-
children: [/* @__PURE__ */ a(
|
|
235
|
+
children: [/* @__PURE__ */ a(ye, { state: n }), /* @__PURE__ */ a(c, { className: "size-3.5 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" })]
|
|
166
236
|
})]
|
|
167
|
-
}),
|
|
168
|
-
className:
|
|
237
|
+
}), xe = ({ className: e, ...t }) => /* @__PURE__ */ a(E, {
|
|
238
|
+
className: C("data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-hidden data-[state=closed]:animate-out data-[state=open]:animate-in", e),
|
|
169
239
|
...t
|
|
170
|
-
}),
|
|
171
|
-
className:
|
|
240
|
+
}), Se = ({ className: e, input: t, ...n }) => L(t) ? /* @__PURE__ */ o("div", {
|
|
241
|
+
className: C("space-y-1.5 overflow-hidden px-2.5 pb-2.5", e),
|
|
172
242
|
...n,
|
|
173
243
|
children: [/* @__PURE__ */ a("h4", {
|
|
174
244
|
className: "text-xs font-medium tracking-wide text-muted-foreground uppercase",
|
|
175
245
|
children: "Parameters"
|
|
176
|
-
}), /* @__PURE__ */ a(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
})]
|
|
180
|
-
}), K = ({ className: e, output: t, errorText: n, ...r }) => t || n ? /* @__PURE__ */ o("div", {
|
|
181
|
-
className: S("space-y-1.5 px-2.5 pb-2.5", e),
|
|
246
|
+
}), /* @__PURE__ */ a(B, { value: t })]
|
|
247
|
+
}) : null, Ce = ({ className: e, output: t, errorText: n, ...r }) => L(t) || n ? /* @__PURE__ */ o("div", {
|
|
248
|
+
className: C("space-y-1.5 px-2.5 pb-2.5", e),
|
|
182
249
|
...r,
|
|
183
250
|
children: [/* @__PURE__ */ a("h4", {
|
|
184
251
|
className: "text-xs font-medium tracking-wide text-muted-foreground uppercase",
|
|
185
252
|
children: n ? "Error" : "Result"
|
|
186
|
-
}), /* @__PURE__ */
|
|
187
|
-
className:
|
|
188
|
-
children:
|
|
253
|
+
}), n ? /* @__PURE__ */ a("div", {
|
|
254
|
+
className: "whitespace-pre-wrap break-words rounded-md bg-destructive/10 px-2.5 py-2 text-xs text-destructive",
|
|
255
|
+
children: n
|
|
256
|
+
}) : /* @__PURE__ */ a("div", {
|
|
257
|
+
className: "text-xs [&_table]:w-full",
|
|
258
|
+
children: /* @__PURE__ */ a(B, { value: t })
|
|
189
259
|
})]
|
|
190
|
-
}) : null,
|
|
260
|
+
}) : null, we = ne("group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
191
261
|
variants: {
|
|
192
262
|
variant: {
|
|
193
263
|
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
@@ -213,12 +283,12 @@ var z = ({ className: e, ...t }) => /* @__PURE__ */ a(D, {
|
|
|
213
283
|
size: "default"
|
|
214
284
|
}
|
|
215
285
|
});
|
|
216
|
-
function
|
|
217
|
-
return /* @__PURE__ */ a(r ?
|
|
286
|
+
function V({ className: e, variant: t = "default", size: n = "default", asChild: r = !1, ...i }) {
|
|
287
|
+
return /* @__PURE__ */ a(r ? te.Root : "button", {
|
|
218
288
|
"data-slot": "button",
|
|
219
289
|
"data-variant": t,
|
|
220
290
|
"data-size": n,
|
|
221
|
-
className:
|
|
291
|
+
className: C(we({
|
|
222
292
|
variant: t,
|
|
223
293
|
size: n,
|
|
224
294
|
className: e
|
|
@@ -228,43 +298,43 @@ function J({ className: e, variant: t = "default", size: n = "default", asChild:
|
|
|
228
298
|
}
|
|
229
299
|
//#endregion
|
|
230
300
|
//#region src/internal/tooltip.tsx
|
|
231
|
-
function
|
|
232
|
-
return /* @__PURE__ */ a(
|
|
301
|
+
function H({ delayDuration: e = 0, ...t }) {
|
|
302
|
+
return /* @__PURE__ */ a(S.Provider, {
|
|
233
303
|
"data-slot": "tooltip-provider",
|
|
234
304
|
delayDuration: e,
|
|
235
305
|
...t
|
|
236
306
|
});
|
|
237
307
|
}
|
|
238
|
-
function
|
|
239
|
-
return /* @__PURE__ */ a(
|
|
308
|
+
function U({ ...e }) {
|
|
309
|
+
return /* @__PURE__ */ a(S.Root, {
|
|
240
310
|
"data-slot": "tooltip",
|
|
241
311
|
...e
|
|
242
312
|
});
|
|
243
313
|
}
|
|
244
|
-
function
|
|
245
|
-
return /* @__PURE__ */ a(
|
|
314
|
+
function W({ ...e }) {
|
|
315
|
+
return /* @__PURE__ */ a(S.Trigger, {
|
|
246
316
|
"data-slot": "tooltip-trigger",
|
|
247
317
|
...e
|
|
248
318
|
});
|
|
249
319
|
}
|
|
250
|
-
function
|
|
251
|
-
return /* @__PURE__ */ a(
|
|
320
|
+
function G({ className: e, sideOffset: t = 0, children: n, ...r }) {
|
|
321
|
+
return /* @__PURE__ */ a(S.Portal, { children: /* @__PURE__ */ o(S.Content, {
|
|
252
322
|
"data-slot": "tooltip-content",
|
|
253
323
|
sideOffset: t,
|
|
254
|
-
className:
|
|
324
|
+
className: C("z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-[state=instant-open]:animate-in data-[state=instant-open]:fade-in-0 data-[state=instant-open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", e),
|
|
255
325
|
...r,
|
|
256
|
-
children: [n, /* @__PURE__ */ a(
|
|
326
|
+
children: [n, /* @__PURE__ */ a(S.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] border-r border-b border-border bg-popover fill-popover" })]
|
|
257
327
|
}) });
|
|
258
328
|
}
|
|
259
329
|
//#endregion
|
|
260
330
|
//#region src/chat/actions.tsx
|
|
261
|
-
var
|
|
262
|
-
className:
|
|
331
|
+
var Te = ({ className: e, children: t, ...n }) => /* @__PURE__ */ a("div", {
|
|
332
|
+
className: C("flex items-center", e),
|
|
263
333
|
...n,
|
|
264
334
|
children: t
|
|
265
|
-
}),
|
|
266
|
-
let l = /* @__PURE__ */ o(
|
|
267
|
-
className:
|
|
335
|
+
}), Ee = ({ tooltip: e, children: t, label: n, className: r, variant: i = "ghost", size: s = "icon", ...c }) => {
|
|
336
|
+
let l = /* @__PURE__ */ o(V, {
|
|
337
|
+
className: C("relative", r),
|
|
268
338
|
size: s,
|
|
269
339
|
type: "button",
|
|
270
340
|
variant: i,
|
|
@@ -274,13 +344,367 @@ var $ = ({ className: e, children: t, ...n }) => /* @__PURE__ */ a("div", {
|
|
|
274
344
|
children: n || e
|
|
275
345
|
})]
|
|
276
346
|
});
|
|
277
|
-
return e ? /* @__PURE__ */ a(
|
|
278
|
-
delayDuration:
|
|
279
|
-
children: /* @__PURE__ */ o(
|
|
347
|
+
return e ? /* @__PURE__ */ a(H, {
|
|
348
|
+
delayDuration: 500,
|
|
349
|
+
children: /* @__PURE__ */ o(U, { children: [/* @__PURE__ */ a(W, {
|
|
280
350
|
asChild: !0,
|
|
281
351
|
children: l
|
|
282
|
-
}), /* @__PURE__ */ a(
|
|
352
|
+
}), /* @__PURE__ */ a(G, { children: /* @__PURE__ */ a("p", { children: e }) })] })
|
|
283
353
|
}) : l;
|
|
354
|
+
}, K = [
|
|
355
|
+
{
|
|
356
|
+
active: "Thinking",
|
|
357
|
+
done: "Thought"
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
active: "Reading",
|
|
361
|
+
done: "Read"
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
active: "Drafting",
|
|
365
|
+
done: "Drafted"
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
active: "Shaping",
|
|
369
|
+
done: "Shaped"
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
active: "Composing",
|
|
373
|
+
done: "Composed"
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
active: "Polishing",
|
|
377
|
+
done: "Polished"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
active: "Mapping",
|
|
381
|
+
done: "Mapped"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
active: "Sorting",
|
|
385
|
+
done: "Sorted"
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
active: "Refining",
|
|
389
|
+
done: "Refined"
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
active: "Working",
|
|
393
|
+
done: "Done"
|
|
394
|
+
}
|
|
395
|
+
], De = {
|
|
396
|
+
waiting: K,
|
|
397
|
+
reasoning: K,
|
|
398
|
+
tools: [{
|
|
399
|
+
active: "Working",
|
|
400
|
+
done: "Worked"
|
|
401
|
+
}]
|
|
402
|
+
}, Oe = 5;
|
|
403
|
+
function q({ kind: e, active: t, seed: n, elapsedSeconds: r }) {
|
|
404
|
+
let i = De[e], a = Math.floor(Math.max(0, r) / Oe), o = i[Math.abs(n + a) % i.length], s = t ? o.active : o.done;
|
|
405
|
+
return r <= 0 ? s : `${s} for ${r}s`;
|
|
406
|
+
}
|
|
407
|
+
function J(e, t) {
|
|
408
|
+
let n = Infinity, r = -Infinity, i = !1;
|
|
409
|
+
for (let t of e) typeof t.startedAtMs == "number" && (n = Math.min(n, t.startedAtMs), typeof t.completedAtMs == "number" ? r = Math.max(r, t.completedAtMs) : i = !0);
|
|
410
|
+
if (n === Infinity) return 0;
|
|
411
|
+
let a = i ? t ?? r : r;
|
|
412
|
+
return a === -Infinity ? 0 : Math.max(0, Math.floor((a - n) / 1e3));
|
|
413
|
+
}
|
|
414
|
+
function Y(e) {
|
|
415
|
+
let t = 0;
|
|
416
|
+
for (let n = 0; n < e.length; n += 1) t = t * 31 + e.charCodeAt(n) | 0;
|
|
417
|
+
return t;
|
|
418
|
+
}
|
|
419
|
+
//#endregion
|
|
420
|
+
//#region src/chat/message-trace.tsx
|
|
421
|
+
function X(e) {
|
|
422
|
+
let t = e.replace(/^tool-/, "").replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim();
|
|
423
|
+
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
424
|
+
}
|
|
425
|
+
var ke = ({ parts: e, isLoading: t, messageId: n, activity: r, getToolLabel: i, getToolIcon: s, defaultOpen: c = !1, className: l }) => {
|
|
426
|
+
let u = e.filter((e) => e.type === "reasoning").map((e) => String(e.text ?? "")).filter((e) => e.trim()).join("\n\n"), d = u.trim().length > 0, f = [], p = !1;
|
|
427
|
+
for (let t of e) t.type.startsWith("tool-") ? (p = !0, f.push({
|
|
428
|
+
kind: "tool",
|
|
429
|
+
label: i?.(t.type) ?? X(t.type),
|
|
430
|
+
state: String(t.state ?? ""),
|
|
431
|
+
toolType: t.type
|
|
432
|
+
})) : t.type === "text" && String(t.text ?? "").trim() && f.push({
|
|
433
|
+
kind: "note",
|
|
434
|
+
text: String(t.text)
|
|
435
|
+
});
|
|
436
|
+
p && !t && f.push({ kind: "done" });
|
|
437
|
+
let m = e.some((e) => typeof e.startedAtMs == "number") ? J(e, r?.nowMs) : r?.elapsedSeconds ?? 0, h = r?.seed ?? Y(n), g = q({
|
|
438
|
+
kind: d ? "reasoning" : "tools",
|
|
439
|
+
active: t,
|
|
440
|
+
seed: h,
|
|
441
|
+
elapsedSeconds: t ? m : 0
|
|
442
|
+
}), _ = d || f.length > 0, [v, y] = b(c);
|
|
443
|
+
return /* @__PURE__ */ o("div", {
|
|
444
|
+
className: C("not-prose flex flex-col", l),
|
|
445
|
+
children: [/* @__PURE__ */ a("button", {
|
|
446
|
+
type: "button",
|
|
447
|
+
"data-testid": "message-reasoning",
|
|
448
|
+
onClick: () => y((e) => !e),
|
|
449
|
+
className: "flex items-center gap-1 self-start text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
450
|
+
children: /* @__PURE__ */ o("span", {
|
|
451
|
+
className: C(t && "ocui-shimmer"),
|
|
452
|
+
children: [g, _ ? "..." : ""]
|
|
453
|
+
})
|
|
454
|
+
}), v && _ && /* @__PURE__ */ o("div", {
|
|
455
|
+
className: "mt-2 flex flex-col gap-2",
|
|
456
|
+
children: [d && /* @__PURE__ */ a(ie, {
|
|
457
|
+
className: "grid gap-1 text-sm text-muted-foreground/80 **:text-sm [&_code]:bg-transparent [&_code]:p-0 [&_code]:font-semibold [&_code]:text-foreground [&_li]:my-0 [&_ol]:my-1 [&_p]:my-0 [&_ul]:my-1",
|
|
458
|
+
children: u
|
|
459
|
+
}), f.length > 0 && /* @__PURE__ */ a("div", {
|
|
460
|
+
className: "flex flex-col",
|
|
461
|
+
children: f.map((e, t) => /* @__PURE__ */ a(Ae, {
|
|
462
|
+
node: e,
|
|
463
|
+
isFirst: t === 0,
|
|
464
|
+
isLast: t === f.length - 1,
|
|
465
|
+
getToolIcon: s
|
|
466
|
+
}, `step-${t}`))
|
|
467
|
+
})]
|
|
468
|
+
})]
|
|
469
|
+
});
|
|
470
|
+
};
|
|
471
|
+
function Ae({ node: e, isFirst: t, isLast: n, getToolIcon: r }) {
|
|
472
|
+
return /* @__PURE__ */ o("div", {
|
|
473
|
+
className: "flex items-stretch gap-2.5",
|
|
474
|
+
children: [/* @__PURE__ */ o("div", {
|
|
475
|
+
className: "flex w-4 flex-col items-center",
|
|
476
|
+
children: [
|
|
477
|
+
/* @__PURE__ */ a("div", { className: C("w-px flex-1", t ? "bg-transparent" : "bg-border") }),
|
|
478
|
+
/* @__PURE__ */ a(je, {
|
|
479
|
+
node: e,
|
|
480
|
+
getToolIcon: r
|
|
481
|
+
}),
|
|
482
|
+
/* @__PURE__ */ a("div", { className: C("w-px flex-1", n ? "bg-transparent" : "bg-border") })
|
|
483
|
+
]
|
|
484
|
+
}), /* @__PURE__ */ a("div", {
|
|
485
|
+
className: "min-w-0 py-1 text-sm leading-5",
|
|
486
|
+
children: e.kind === "tool" ? /* @__PURE__ */ a("span", {
|
|
487
|
+
className: "text-muted-foreground",
|
|
488
|
+
children: e.label
|
|
489
|
+
}) : e.kind === "note" ? /* @__PURE__ */ a("span", {
|
|
490
|
+
className: "text-muted-foreground/80",
|
|
491
|
+
children: e.text
|
|
492
|
+
}) : /* @__PURE__ */ a("span", {
|
|
493
|
+
className: "text-muted-foreground",
|
|
494
|
+
children: "Done"
|
|
495
|
+
})
|
|
496
|
+
})]
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
function je({ node: e, getToolIcon: t }) {
|
|
500
|
+
let n = "flex items-center justify-center bg-background py-0.5";
|
|
501
|
+
return e.kind === "note" ? /* @__PURE__ */ a("div", {
|
|
502
|
+
className: n,
|
|
503
|
+
children: /* @__PURE__ */ a("div", { className: "size-1 rounded-full bg-muted-foreground/60" })
|
|
504
|
+
}) : e.kind === "tool" ? e.state === "output-error" || e.state === "output-denied" ? /* @__PURE__ */ a("div", {
|
|
505
|
+
className: n,
|
|
506
|
+
children: /* @__PURE__ */ a(m, { className: "size-3.5 text-destructive" })
|
|
507
|
+
}) : e.state === "output-available" ? /* @__PURE__ */ a("div", {
|
|
508
|
+
className: n,
|
|
509
|
+
children: /* @__PURE__ */ a(t?.(e.toolType) ?? s, { className: "size-3.5 text-muted-foreground" })
|
|
510
|
+
}) : /* @__PURE__ */ a("div", {
|
|
511
|
+
className: n,
|
|
512
|
+
children: /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin text-muted-foreground" })
|
|
513
|
+
}) : /* @__PURE__ */ a("div", {
|
|
514
|
+
className: n,
|
|
515
|
+
children: /* @__PURE__ */ a(l, { className: "size-4 text-muted-foreground" })
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
//#endregion
|
|
519
|
+
//#region src/chat/segments.ts
|
|
520
|
+
function Z(e, t) {
|
|
521
|
+
return e.startsWith("tool-") && !t(e);
|
|
522
|
+
}
|
|
523
|
+
function Me(e, t) {
|
|
524
|
+
let n = t?.isPresentationalTool ?? (() => !1), r = -1;
|
|
525
|
+
e.forEach((e, t) => {
|
|
526
|
+
(e.type === "reasoning" || Z(e.type, n)) && (r = t);
|
|
527
|
+
});
|
|
528
|
+
let i = [], a = null, o = null, s = (e) => {
|
|
529
|
+
o = null, a || (a = {
|
|
530
|
+
kind: "trace",
|
|
531
|
+
parts: []
|
|
532
|
+
}, i.push(a)), a.parts.push(e);
|
|
533
|
+
};
|
|
534
|
+
return e.forEach((e, t) => {
|
|
535
|
+
if (!(e.type === "step-start" || e.type === "step-finish")) if (e.type === "reasoning") {
|
|
536
|
+
let t = String(e.text ?? ""), n = e.state === "streaming";
|
|
537
|
+
if (!(t.trim() || n)) return;
|
|
538
|
+
s(e);
|
|
539
|
+
} else Z(e.type, n) ? s(e) : e.type === "text" && t <= r ? String(e.text ?? "").trim() && s(e) : e.type === "file" ? (a = null, o || (o = {
|
|
540
|
+
kind: "images",
|
|
541
|
+
parts: [],
|
|
542
|
+
index: t
|
|
543
|
+
}, i.push(o)), o.parts.push(e)) : (a = null, o = null, i.push({
|
|
544
|
+
kind: "part",
|
|
545
|
+
part: e,
|
|
546
|
+
index: t
|
|
547
|
+
}));
|
|
548
|
+
}), i;
|
|
549
|
+
}
|
|
550
|
+
function Ne(e, t) {
|
|
551
|
+
return e.some((e) => {
|
|
552
|
+
let n = e.state;
|
|
553
|
+
return typeof n == "string" ? e.type === "reasoning" || e.type === "text" ? n === "streaming" : n === "input-streaming" || n === "input-available" : t;
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
//#endregion
|
|
557
|
+
//#region src/chat/use-activity-clock.ts
|
|
558
|
+
function Pe(e, t) {
|
|
559
|
+
let n = ee(null), [r, i] = b(() => ({
|
|
560
|
+
seed: t,
|
|
561
|
+
elapsedSeconds: 0,
|
|
562
|
+
nowMs: Date.now()
|
|
563
|
+
}));
|
|
564
|
+
return y(() => {
|
|
565
|
+
if (!e) {
|
|
566
|
+
if (n.current === null) return;
|
|
567
|
+
let e = n.current;
|
|
568
|
+
n.current = null;
|
|
569
|
+
let t = setTimeout(() => {
|
|
570
|
+
i((t) => ({
|
|
571
|
+
...t,
|
|
572
|
+
elapsedSeconds: Math.max(1, Math.round((Date.now() - e) / 1e3)),
|
|
573
|
+
nowMs: Date.now()
|
|
574
|
+
}));
|
|
575
|
+
}, 0);
|
|
576
|
+
return () => clearTimeout(t);
|
|
577
|
+
}
|
|
578
|
+
let r;
|
|
579
|
+
n.current === null && (n.current = Date.now(), r = setTimeout(() => {
|
|
580
|
+
i({
|
|
581
|
+
seed: t,
|
|
582
|
+
elapsedSeconds: 0,
|
|
583
|
+
nowMs: Date.now()
|
|
584
|
+
});
|
|
585
|
+
}, 0));
|
|
586
|
+
let a = setInterval(() => {
|
|
587
|
+
n.current !== null && i((e) => ({
|
|
588
|
+
...e,
|
|
589
|
+
elapsedSeconds: Math.floor((Date.now() - n.current) / 1e3),
|
|
590
|
+
nowMs: Date.now()
|
|
591
|
+
}));
|
|
592
|
+
}, 1e3);
|
|
593
|
+
return () => {
|
|
594
|
+
r && clearTimeout(r), clearInterval(a);
|
|
595
|
+
};
|
|
596
|
+
}, [e, t]), r;
|
|
597
|
+
}
|
|
598
|
+
//#endregion
|
|
599
|
+
//#region src/chat/sources.tsx
|
|
600
|
+
function Fe(e) {
|
|
601
|
+
return `Used ${e} source${e === 1 ? "" : "s"}`;
|
|
602
|
+
}
|
|
603
|
+
function Q(e) {
|
|
604
|
+
try {
|
|
605
|
+
return new URL(e).hostname;
|
|
606
|
+
} catch {
|
|
607
|
+
return e;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
function Ie(e) {
|
|
611
|
+
return `https://www.google.com/s2/favicons?domain=${Q(e)}&sz=32`;
|
|
612
|
+
}
|
|
613
|
+
function Le({ url: e, getFaviconUrl: t }) {
|
|
614
|
+
let n = t(e), [r, i] = b(!1);
|
|
615
|
+
return !n || r ? /* @__PURE__ */ a(d, { className: "size-3.5 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ a("img", {
|
|
616
|
+
src: n,
|
|
617
|
+
alt: "",
|
|
618
|
+
className: "size-3.5 shrink-0 rounded-xs",
|
|
619
|
+
onError: () => i(!0)
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
var Re = ({ sources: e, label: t = Fe, getFaviconUrl: n = Ie, className: r, ...i }) => e.length === 0 ? null : /* @__PURE__ */ o(w, {
|
|
623
|
+
className: C("not-prose", r),
|
|
624
|
+
...i,
|
|
625
|
+
children: [/* @__PURE__ */ o(T, {
|
|
626
|
+
className: "group flex items-center gap-1 rounded-md px-1.5 py-0.5 text-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
627
|
+
children: [/* @__PURE__ */ a("span", { children: t(e.length) }), /* @__PURE__ */ a(c, { className: "size-2.5 transition-transform group-data-[state=open]:rotate-180" })]
|
|
628
|
+
}), /* @__PURE__ */ a(E, {
|
|
629
|
+
className: "mt-1 flex flex-col gap-0.5 data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
630
|
+
children: e.map((e, t) => {
|
|
631
|
+
let r = Q(e.url), i = e.title || r;
|
|
632
|
+
return /* @__PURE__ */ o("a", {
|
|
633
|
+
href: e.url,
|
|
634
|
+
target: "_blank",
|
|
635
|
+
rel: "noreferrer",
|
|
636
|
+
className: "flex min-w-0 items-center gap-1.5 rounded-md px-1.5 py-1 text-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
637
|
+
children: [
|
|
638
|
+
/* @__PURE__ */ a(Le, {
|
|
639
|
+
getFaviconUrl: n,
|
|
640
|
+
url: e.url
|
|
641
|
+
}),
|
|
642
|
+
/* @__PURE__ */ a("span", {
|
|
643
|
+
className: "truncate",
|
|
644
|
+
children: i
|
|
645
|
+
}),
|
|
646
|
+
i !== r && /* @__PURE__ */ a("span", {
|
|
647
|
+
className: "shrink-0 truncate text-xs text-muted-foreground/70",
|
|
648
|
+
children: r
|
|
649
|
+
})
|
|
650
|
+
]
|
|
651
|
+
}, `${e.url}-${t}`);
|
|
652
|
+
})
|
|
653
|
+
})]
|
|
654
|
+
}), ze = "ocui-cite";
|
|
655
|
+
//#endregion
|
|
656
|
+
//#region src/chat/web-search.ts
|
|
657
|
+
function $(e) {
|
|
658
|
+
return typeof e == "object" && !!e && "error" in e && typeof e.error == "string";
|
|
659
|
+
}
|
|
660
|
+
var Be = "tool-webSearch";
|
|
661
|
+
function Ve(e) {
|
|
662
|
+
try {
|
|
663
|
+
let t = new URL(e);
|
|
664
|
+
return `${t.hostname.toLowerCase()}${t.pathname.replace(/\/$/, "")}${t.search}`;
|
|
665
|
+
} catch {
|
|
666
|
+
return e.replace(/#.*$/, "").replace(/\/$/, "");
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
function He(e, t) {
|
|
670
|
+
let n = t?.toolType ?? Be, r = /* @__PURE__ */ new Set(), i = [];
|
|
671
|
+
for (let t of e) {
|
|
672
|
+
if (t.type !== n || t.state !== "output-available" || $(t.output)) continue;
|
|
673
|
+
let e = t.output?.results;
|
|
674
|
+
if (Array.isArray(e)) for (let t of e) {
|
|
675
|
+
if (typeof t?.url != "string") continue;
|
|
676
|
+
let e = Ve(t.url);
|
|
677
|
+
r.has(e) || (r.add(e), i.push({
|
|
678
|
+
url: t.url,
|
|
679
|
+
title: t.title
|
|
680
|
+
}));
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return i;
|
|
684
|
+
}
|
|
685
|
+
//#endregion
|
|
686
|
+
//#region src/chat/web-search-toggle.tsx
|
|
687
|
+
var Ue = ({ pressed: e, onPressedChange: t, label: n = "Search the web", tooltip: r, className: i, variant: s, size: c = "icon", onClick: l, ...u }) => {
|
|
688
|
+
let f = s ?? (e ? "default" : "ghost"), p = /* @__PURE__ */ a(V, {
|
|
689
|
+
"aria-label": n,
|
|
690
|
+
"aria-pressed": e,
|
|
691
|
+
className: C(i),
|
|
692
|
+
onClick: (n) => {
|
|
693
|
+
l?.(n), t(!e);
|
|
694
|
+
},
|
|
695
|
+
size: c,
|
|
696
|
+
type: "button",
|
|
697
|
+
variant: f,
|
|
698
|
+
...u,
|
|
699
|
+
children: /* @__PURE__ */ a(d, {})
|
|
700
|
+
});
|
|
701
|
+
return r ? /* @__PURE__ */ a(H, {
|
|
702
|
+
delayDuration: 300,
|
|
703
|
+
children: /* @__PURE__ */ o(U, { children: [/* @__PURE__ */ a(W, {
|
|
704
|
+
asChild: !0,
|
|
705
|
+
children: p
|
|
706
|
+
}), /* @__PURE__ */ a(G, { children: /* @__PURE__ */ a("p", { children: r }) })] })
|
|
707
|
+
}) : p;
|
|
284
708
|
};
|
|
285
709
|
//#endregion
|
|
286
|
-
export {
|
|
710
|
+
export { Ee as Action, Te as Actions, oe as MessageContent, ke as MessageTrace, O as Reasoning, j as ReasoningContent, k as ReasoningTrigger, ie as Response, Re as Sources, ge as Tool, xe as ToolContent, be as ToolHeader, Se as ToolInput, Ce as ToolOutput, Ue as WebSearchToggle, Me as buildSegments, ze as citationClassName, He as extractWebSearchSources, q as getAiActivityLabel, X as humanizeToolName, $ as isWebSearchError, Y as labelSeedFromString, A as reasoningTextClassName, J as traceElapsedSeconds, Ne as traceIsLoading, Pe as useActivityClock };
|
package/dist/tokens.css
CHANGED