@ocai/app-sdk-ui 0.2.0 → 0.4.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 +9 -2
- package/dist/chat/message-trace.d.ts +4 -2
- package/dist/chat/response.d.ts +1 -2
- package/dist/chat/sources.d.ts +8 -2
- package/dist/chat/tool-value.d.ts +1 -0
- package/dist/chat/turn-view.d.ts +21 -0
- package/dist/chat/web-search.d.ts +1 -0
- package/dist/chat.css +1 -7
- package/dist/index.d.ts +5 -4
- package/dist/index.js +373 -288
- package/package.json +8 -3
|
@@ -4,10 +4,17 @@ export interface AiActivity {
|
|
|
4
4
|
elapsedSeconds: number;
|
|
5
5
|
nowMs: number;
|
|
6
6
|
}
|
|
7
|
-
export
|
|
7
|
+
export interface ActivityLabelParts {
|
|
8
|
+
verb: string;
|
|
9
|
+
elapsedSeconds: number;
|
|
10
|
+
}
|
|
11
|
+
export interface GetAiActivityLabelArgs extends Pick<AiActivity, "seed" | "elapsedSeconds"> {
|
|
8
12
|
kind: AiActivityKind;
|
|
9
13
|
active: boolean;
|
|
10
|
-
|
|
14
|
+
verb?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function getAiActivityLabelParts({ kind, active, seed, elapsedSeconds, verb, }: GetAiActivityLabelArgs): ActivityLabelParts;
|
|
17
|
+
export declare function getAiActivityLabel(args: GetAiActivityLabelArgs): string;
|
|
11
18
|
export declare function traceElapsedSeconds(parts: ReadonlyArray<{
|
|
12
19
|
startedAtMs?: number;
|
|
13
20
|
completedAtMs?: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LucideIcon } from 'lucide-react';
|
|
2
|
-
import { ReactElement } from 'react';
|
|
2
|
+
import { ReactElement, ReactNode } from 'react';
|
|
3
3
|
import { AiActivity } from './activity-labels';
|
|
4
4
|
import { TracePart } from './segments';
|
|
5
5
|
export declare function humanizeToolName(type: string): string;
|
|
@@ -10,7 +10,9 @@ export type MessageTraceProps = {
|
|
|
10
10
|
activity?: AiActivity;
|
|
11
11
|
getToolLabel?: (type: string) => string | undefined;
|
|
12
12
|
getToolIcon?: (type: string) => LucideIcon | undefined;
|
|
13
|
+
getActivityOverride?: (runningToolType: string | undefined) => string | undefined;
|
|
14
|
+
renderStepDetail?: (part: TracePart) => ReactNode;
|
|
13
15
|
defaultOpen?: boolean;
|
|
14
16
|
className?: string;
|
|
15
17
|
};
|
|
16
|
-
export declare const MessageTrace: ({ parts, isLoading, messageId, activity, getToolLabel, getToolIcon, defaultOpen, className, }: MessageTraceProps) => ReactElement
|
|
18
|
+
export declare const MessageTrace: import('react').MemoExoticComponent<({ parts, isLoading, messageId, activity, getToolLabel, getToolIcon, getActivityOverride, renderStepDetail, defaultOpen, className, }: MessageTraceProps) => ReactElement>;
|
package/dist/chat/response.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ComponentProps } from 'react';
|
|
2
2
|
import { Streamdown } from 'streamdown';
|
|
3
|
-
type ResponseProps = ComponentProps<typeof Streamdown>;
|
|
3
|
+
export type ResponseProps = ComponentProps<typeof Streamdown>;
|
|
4
4
|
export declare function Response({ className, ...props }: ResponseProps): import("react").JSX.Element;
|
|
5
|
-
export {};
|
package/dist/chat/sources.d.ts
CHANGED
|
@@ -4,10 +4,16 @@ export type SourceItem = {
|
|
|
4
4
|
url: string;
|
|
5
5
|
title?: string;
|
|
6
6
|
};
|
|
7
|
+
export type SourceListProps = {
|
|
8
|
+
sources: readonly SourceItem[];
|
|
9
|
+
getFaviconUrl?: (url: string) => string | null;
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare const SourceList: ({ sources, getFaviconUrl, className, }: SourceListProps) => ReactElement | null;
|
|
7
13
|
export type SourcesProps = Omit<ComponentProps<typeof Collapsible>, "children"> & {
|
|
8
14
|
sources: readonly SourceItem[];
|
|
9
|
-
|
|
15
|
+
getLabel?: (count: number) => string;
|
|
10
16
|
getFaviconUrl?: (url: string) => string | null;
|
|
11
17
|
};
|
|
12
|
-
export declare const Sources: ({ sources,
|
|
18
|
+
export declare const Sources: ({ sources, getLabel, getFaviconUrl, className, ...props }: SourcesProps) => ReactElement | null;
|
|
13
19
|
export declare const citationClassName = "ocui-cite";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
export declare const hasRenderableValue: (v: unknown) => boolean;
|
|
3
|
+
export declare const capText: (value: string, max?: number) => string;
|
|
3
4
|
export declare const ToolValue: ({ value }: {
|
|
4
5
|
value: unknown;
|
|
5
6
|
}) => ReactElement | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MessageSegment, TracePart } from './segments';
|
|
2
|
+
import { SourceItem } from './sources';
|
|
3
|
+
import { AiActivityKind } from './activity-labels';
|
|
4
|
+
export type TurnPhase = "waiting" | "reasoning" | "searching" | "tooling" | "answering" | "settled";
|
|
5
|
+
export interface TurnView {
|
|
6
|
+
phase: TurnPhase;
|
|
7
|
+
segments: MessageSegment[];
|
|
8
|
+
trace: {
|
|
9
|
+
parts: TracePart[];
|
|
10
|
+
isLoading: boolean;
|
|
11
|
+
} | null;
|
|
12
|
+
sources: SourceItem[];
|
|
13
|
+
activityKind: AiActivityKind;
|
|
14
|
+
hasFinalAnswer: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface DeriveTurnViewOptions {
|
|
17
|
+
isPresentationalTool?: (type: string) => boolean;
|
|
18
|
+
isSearchTool?: (type: string) => boolean;
|
|
19
|
+
messageLoading?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function deriveTurnView(parts: readonly TracePart[], options?: DeriveTurnViewOptions): TurnView;
|
|
@@ -25,6 +25,7 @@ export type WebSearchUIPart = ToolUIPart<{
|
|
|
25
25
|
webSearch: WebSearchUITool;
|
|
26
26
|
}>;
|
|
27
27
|
export declare function isWebSearchError(output: unknown): output is WebSearchErrorOutput;
|
|
28
|
+
export declare function stripCitationParens(text: string): string;
|
|
28
29
|
export declare function extractWebSearchSources(parts: ReadonlyArray<{
|
|
29
30
|
type?: string;
|
|
30
31
|
state?: string;
|
package/dist/chat.css
CHANGED
|
@@ -115,15 +115,9 @@
|
|
|
115
115
|
.ocui-md.ocui-cite [data-streamdown="link"] {
|
|
116
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
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
118
|
|
|
125
119
|
/* Activity-label shimmer: while the model streams, the trigger label
|
|
126
|
-
("Thinking…", "Shaping for
|
|
120
|
+
("Thinking…", "Shaping for 4s") sweeps a full-contrast highlight
|
|
127
121
|
left→right across the muted label text, instead of pulsing the whole word.
|
|
128
122
|
Codex-style (a moving highlight band clipped to the glyphs). Base is the
|
|
129
123
|
muted label color; the highlight is the foreground seed. Applied by
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
export { Response } from './chat/response';
|
|
1
|
+
export { Response, type ResponseProps } from './chat/response';
|
|
2
2
|
export { MessageContent, type MessageContentProps, type MessageContentVariant, } from './chat/message';
|
|
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 { deriveTurnView, type TurnView, type TurnPhase, type DeriveTurnViewOptions, } from './chat/turn-view';
|
|
6
7
|
export { MessageTrace, humanizeToolName, type MessageTraceProps, } from './chat/message-trace';
|
|
7
8
|
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 { getAiActivityLabel, getAiActivityLabelParts, labelSeedFromString, traceElapsedSeconds, type AiActivity, type AiActivityKind, type ActivityLabelParts, type GetAiActivityLabelArgs, } from './chat/activity-labels';
|
|
9
10
|
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';
|
|
11
|
+
export { Sources, SourceList, citationClassName, type SourceItem, type SourcesProps, type SourceListProps, } from './chat/sources';
|
|
12
|
+
export { extractWebSearchSources, isWebSearchError, stripCitationParens, type WebSearchErrorOutput, type WebSearchInput, type WebSearchOutput, type WebSearchResult, type WebSearchSuccessOutput, type WebSearchUIPart, type WebSearchUITool, } from './chat/web-search';
|
|
12
13
|
export { WebSearchToggle, type WebSearchToggleProps, } from './chat/web-search-toggle';
|
package/dist/index.js
CHANGED
|
@@ -5,20 +5,20 @@ 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
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,
|
|
9
|
-
import { Collapsible as
|
|
10
|
-
import { cva as
|
|
8
|
+
import { createContext as h, isValidElement as g, memo as _, useContext as v, useEffect as y, useId as ee, useRef as b, useState as x } from "react";
|
|
9
|
+
import { Collapsible as S, Slot as C, Tooltip as w } from "radix-ui";
|
|
10
|
+
import { cva as T } from "class-variance-authority";
|
|
11
11
|
//#region src/lib/cn.ts
|
|
12
|
-
function
|
|
12
|
+
function E(...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 te = e({ singleDollarTextMath: !0 });
|
|
18
|
+
function ne({ className: e, ...n }) {
|
|
19
19
|
return /* @__PURE__ */ a(t, {
|
|
20
|
-
className:
|
|
21
|
-
plugins: { math:
|
|
20
|
+
className: E("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: te },
|
|
22
22
|
controls: {
|
|
23
23
|
table: !1,
|
|
24
24
|
code: { download: !1 }
|
|
@@ -28,74 +28,73 @@ function ie({ className: e, ...n }) {
|
|
|
28
28
|
}
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region src/chat/message.tsx
|
|
31
|
-
var
|
|
31
|
+
var D = {
|
|
32
32
|
user: "w-fit wrap-break-word rounded-md bg-card px-3 py-1.5 text-primary",
|
|
33
33
|
assistant: "bg-transparent px-0 py-0 text-left text-foreground"
|
|
34
|
-
},
|
|
35
|
-
className:
|
|
34
|
+
}, O = ({ children: e, className: t, variant: n = "user", ...r }) => /* @__PURE__ */ a("div", {
|
|
35
|
+
className: E("flex flex-col gap-2 overflow-hidden text-base font-normal leading-6", D[n], t),
|
|
36
36
|
...r,
|
|
37
37
|
children: e
|
|
38
38
|
});
|
|
39
39
|
//#endregion
|
|
40
40
|
//#region src/internal/collapsible.tsx
|
|
41
|
-
function
|
|
42
|
-
return /* @__PURE__ */ a(
|
|
41
|
+
function k({ ...e }) {
|
|
42
|
+
return /* @__PURE__ */ a(S.Root, {
|
|
43
43
|
"data-slot": "collapsible",
|
|
44
44
|
...e
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
-
function
|
|
48
|
-
return /* @__PURE__ */ a(
|
|
47
|
+
function A({ ...e }) {
|
|
48
|
+
return /* @__PURE__ */ a(S.CollapsibleTrigger, {
|
|
49
49
|
"data-slot": "collapsible-trigger",
|
|
50
50
|
...e
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
|
-
function
|
|
54
|
-
return /* @__PURE__ */ a(
|
|
53
|
+
function j({ ...e }) {
|
|
54
|
+
return /* @__PURE__ */ a(S.CollapsibleContent, {
|
|
55
55
|
"data-slot": "collapsible-content",
|
|
56
56
|
...e
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
//#endregion
|
|
60
60
|
//#region src/chat/reasoning.tsx
|
|
61
|
-
function
|
|
62
|
-
let [r, i] =
|
|
61
|
+
function re({ prop: e, defaultProp: t, onChange: n }) {
|
|
62
|
+
let [r, i] = x(t), a = e !== void 0;
|
|
63
63
|
return [a ? e : r, (e) => {
|
|
64
64
|
a || i(e), n?.(e);
|
|
65
65
|
}];
|
|
66
66
|
}
|
|
67
|
-
var
|
|
68
|
-
let e = v(
|
|
67
|
+
var M = h(null), ie = () => {
|
|
68
|
+
let e = v(M);
|
|
69
69
|
if (!e) throw Error("Reasoning components must be used within Reasoning");
|
|
70
70
|
return e;
|
|
71
|
-
},
|
|
72
|
-
let [l, u] =
|
|
71
|
+
}, ae = 500, N = _(({ className: e, isStreaming: t = !1, duration: n = 0, open: r, defaultOpen: i = !0, onOpenChange: o, children: s, ...c }) => {
|
|
72
|
+
let [l, u] = re({
|
|
73
73
|
prop: r,
|
|
74
74
|
defaultProp: i,
|
|
75
75
|
onChange: o
|
|
76
|
-
}), [d, f] =
|
|
77
|
-
return y(() => {
|
|
76
|
+
}), [d, f] = x(!1), p = b(u);
|
|
77
|
+
return p.current = u, y(() => {
|
|
78
78
|
if (i && !t && l && !d) {
|
|
79
79
|
let e = setTimeout(() => {
|
|
80
|
-
|
|
81
|
-
},
|
|
80
|
+
p.current(!1), f(!0);
|
|
81
|
+
}, ae);
|
|
82
82
|
return () => clearTimeout(e);
|
|
83
83
|
}
|
|
84
84
|
}, [
|
|
85
85
|
t,
|
|
86
86
|
l,
|
|
87
87
|
i,
|
|
88
|
-
u,
|
|
89
88
|
d
|
|
90
|
-
]), /* @__PURE__ */ a(
|
|
89
|
+
]), /* @__PURE__ */ a(M.Provider, {
|
|
91
90
|
value: {
|
|
92
91
|
isStreaming: t,
|
|
93
92
|
isOpen: l,
|
|
94
93
|
setIsOpen: u,
|
|
95
94
|
duration: n
|
|
96
95
|
},
|
|
97
|
-
children: /* @__PURE__ */ a(
|
|
98
|
-
className:
|
|
96
|
+
children: /* @__PURE__ */ a(k, {
|
|
97
|
+
className: E("not-prose", e),
|
|
99
98
|
onOpenChange: u,
|
|
100
99
|
open: l,
|
|
101
100
|
...c,
|
|
@@ -103,51 +102,51 @@ var D = h(null), ce = () => {
|
|
|
103
102
|
})
|
|
104
103
|
});
|
|
105
104
|
});
|
|
106
|
-
function
|
|
105
|
+
function oe({ variant: e, isStreaming: t, duration: n }) {
|
|
107
106
|
let r = e === "tools";
|
|
108
107
|
return t ? r ? "Working…" : "Thinking…" : n > 0 ? r ? `Worked for ${n}s` : `Thought for ${n}s` : r ? "Worked" : "Thought";
|
|
109
108
|
}
|
|
110
|
-
var
|
|
111
|
-
let { isStreaming: l, isOpen: u, duration: d } =
|
|
109
|
+
var P = _(({ className: e, children: t, variant: n = "reasoning", label: r, ...s }) => {
|
|
110
|
+
let { isStreaming: l, isOpen: u, duration: d } = ie(), f = r ?? oe({
|
|
112
111
|
variant: n,
|
|
113
112
|
isStreaming: l,
|
|
114
113
|
duration: d
|
|
115
114
|
});
|
|
116
|
-
return /* @__PURE__ */ a(
|
|
117
|
-
className:
|
|
115
|
+
return /* @__PURE__ */ a(A, {
|
|
116
|
+
className: E("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),
|
|
118
117
|
...s,
|
|
119
118
|
children: t ?? /* @__PURE__ */ o(i, { children: [
|
|
120
119
|
n === "tools" && /* @__PURE__ */ a(p, { className: "size-3" }),
|
|
121
120
|
/* @__PURE__ */ a("span", {
|
|
122
|
-
className:
|
|
121
|
+
className: E(l && "ocui-shimmer"),
|
|
123
122
|
children: f
|
|
124
123
|
}),
|
|
125
|
-
/* @__PURE__ */ a(c, { className:
|
|
124
|
+
/* @__PURE__ */ a(c, { className: E("size-2.5 transition-transform", u ? "rotate-180" : "rotate-0") })
|
|
126
125
|
] })
|
|
127
126
|
});
|
|
128
|
-
}),
|
|
129
|
-
className:
|
|
127
|
+
}), F = "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", I = _(({ className: e, ...t }) => /* @__PURE__ */ a(j, {
|
|
128
|
+
className: E(F, "mt-1.5", e),
|
|
130
129
|
...t
|
|
131
130
|
}));
|
|
132
|
-
|
|
131
|
+
N.displayName = "Reasoning", P.displayName = "ReasoningTrigger", I.displayName = "ReasoningContent";
|
|
133
132
|
//#endregion
|
|
134
133
|
//#region src/chat/tool-value.tsx
|
|
135
|
-
var
|
|
134
|
+
var se = 8, L = 240, ce = 2e4, R = (e) => e === null || typeof e != "object" && typeof e != "function", z = (e) => {
|
|
136
135
|
if (typeof e != "object" || !e) return !1;
|
|
137
136
|
let t = Object.getPrototypeOf(e);
|
|
138
137
|
return t === Object.prototype || t === null;
|
|
139
|
-
},
|
|
140
|
-
if (!
|
|
138
|
+
}, B = (e) => Array.isArray(e) && e.every(R), le = (e) => {
|
|
139
|
+
if (!z(e)) return !1;
|
|
141
140
|
let t = Object.keys(e);
|
|
142
|
-
return t.length === 0 || t.length >
|
|
143
|
-
},
|
|
141
|
+
return t.length === 0 || t.length > se ? !1 : t.every((t) => R(e[t]) || B(e[t]));
|
|
142
|
+
}, V = (e) => g(e) ? !0 : e == null ? !1 : typeof e == "string" ? e.trim().length > 0 : R(e) ? !0 : Array.isArray(e) ? e.length > 0 : z(e) ? Object.keys(e).length > 0 : !0, H = (e, t = ce) => e.length > t ? `${e.slice(0, t)}\n… (truncated)` : e, ue = (e) => {
|
|
144
143
|
try {
|
|
145
144
|
let t = JSON.stringify(e, null, 2);
|
|
146
|
-
return t === void 0 ? String(e) : t
|
|
145
|
+
return t === void 0 ? String(e) : H(t);
|
|
147
146
|
} catch {
|
|
148
147
|
return String(e);
|
|
149
148
|
}
|
|
150
|
-
},
|
|
149
|
+
}, U = ({ value: e }) => {
|
|
151
150
|
if (e == null) return /* @__PURE__ */ a("span", {
|
|
152
151
|
className: "font-mono text-muted-foreground",
|
|
153
152
|
children: "null"
|
|
@@ -160,13 +159,13 @@ var de = 8, M = 240, N = 2e4, P = (e) => e === null || typeof e != "object" && t
|
|
|
160
159
|
className: "text-muted-foreground italic",
|
|
161
160
|
children: "empty"
|
|
162
161
|
});
|
|
163
|
-
let t = e.length >
|
|
162
|
+
let t = e.length > L;
|
|
164
163
|
return /* @__PURE__ */ a("span", {
|
|
165
164
|
className: "text-foreground",
|
|
166
165
|
title: t ? e : void 0,
|
|
167
|
-
children: t ? `${e.slice(0,
|
|
166
|
+
children: t ? `${e.slice(0, L)}…` : e
|
|
168
167
|
});
|
|
169
|
-
},
|
|
168
|
+
}, W = ({ value: e }) => e.length === 0 ? /* @__PURE__ */ a("span", {
|
|
170
169
|
className: "text-muted-foreground italic",
|
|
171
170
|
children: "none"
|
|
172
171
|
}) : /* @__PURE__ */ a("span", {
|
|
@@ -174,8 +173,8 @@ var de = 8, M = 240, N = 2e4, P = (e) => e === null || typeof e != "object" && t
|
|
|
174
173
|
children: e.map((e, t) => /* @__PURE__ */ o("span", { children: [t > 0 && /* @__PURE__ */ a("span", {
|
|
175
174
|
className: "px-1 text-muted-foreground/70",
|
|
176
175
|
children: "·"
|
|
177
|
-
}), /* @__PURE__ */ a(
|
|
178
|
-
}),
|
|
176
|
+
}), /* @__PURE__ */ a(U, { value: e })] }, t))
|
|
177
|
+
}), de = ({ data: e }) => /* @__PURE__ */ a("ul", {
|
|
179
178
|
className: "ocui-tool-kv grid min-w-0 grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-xs",
|
|
180
179
|
children: Object.entries(e).map(([e, t]) => /* @__PURE__ */ o("li", {
|
|
181
180
|
className: "contents",
|
|
@@ -184,25 +183,25 @@ var de = 8, M = 240, N = 2e4, P = (e) => e === null || typeof e != "object" && t
|
|
|
184
183
|
children: e
|
|
185
184
|
}), /* @__PURE__ */ a("span", {
|
|
186
185
|
className: "min-w-0 break-words whitespace-pre-wrap",
|
|
187
|
-
children:
|
|
186
|
+
children: B(t) ? /* @__PURE__ */ a(W, { value: t }) : /* @__PURE__ */ a(U, { value: t })
|
|
188
187
|
})]
|
|
189
188
|
}, e))
|
|
190
|
-
}),
|
|
189
|
+
}), fe = ({ value: e }) => /* @__PURE__ */ a("pre", {
|
|
191
190
|
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:
|
|
193
|
-
}),
|
|
191
|
+
children: ue(e)
|
|
192
|
+
}), G = ({ value: e }) => g(e) ? /* @__PURE__ */ a(i, { children: e }) : e == null ? null : typeof e == "string" ? e.trim() === "" ? null : /* @__PURE__ */ a("div", {
|
|
194
193
|
className: "whitespace-pre-wrap break-words font-mono text-xs leading-relaxed text-muted-foreground",
|
|
195
|
-
children: e
|
|
196
|
-
}) :
|
|
194
|
+
children: H(e)
|
|
195
|
+
}) : R(e) ? /* @__PURE__ */ a("div", {
|
|
197
196
|
className: "font-mono text-xs text-foreground",
|
|
198
197
|
children: String(e)
|
|
199
|
-
}) :
|
|
198
|
+
}) : le(e) ? /* @__PURE__ */ a(de, { data: e }) : B(e) ? /* @__PURE__ */ a("div", {
|
|
200
199
|
className: "text-xs",
|
|
201
|
-
children: /* @__PURE__ */ a(
|
|
202
|
-
}) : /* @__PURE__ */ a(
|
|
203
|
-
className:
|
|
200
|
+
children: /* @__PURE__ */ a(W, { value: e })
|
|
201
|
+
}) : /* @__PURE__ */ a(fe, { value: e }), pe = ({ className: e, ...t }) => /* @__PURE__ */ a(k, {
|
|
202
|
+
className: E("not-prose w-full rounded-md border border-border", e),
|
|
204
203
|
...t
|
|
205
|
-
}),
|
|
204
|
+
}), me = {
|
|
206
205
|
"input-streaming": "Pending",
|
|
207
206
|
"input-available": "Running",
|
|
208
207
|
"approval-requested": "Pending",
|
|
@@ -210,19 +209,19 @@ var de = 8, M = 240, N = 2e4, P = (e) => e === null || typeof e != "object" && t
|
|
|
210
209
|
"output-available": "Completed",
|
|
211
210
|
"output-error": "Error",
|
|
212
211
|
"output-denied": "Denied"
|
|
213
|
-
},
|
|
214
|
-
"input-streaming": /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin" }),
|
|
215
|
-
"input-available": /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin" }),
|
|
212
|
+
}, he = {
|
|
213
|
+
"input-streaming": /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin motion-reduce:animate-none" }),
|
|
214
|
+
"input-available": /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin motion-reduce:animate-none" }),
|
|
216
215
|
"approval-requested": /* @__PURE__ */ a(u, { className: "size-3.5" }),
|
|
217
216
|
"approval-responded": /* @__PURE__ */ a(s, { className: "size-3.5" }),
|
|
218
217
|
"output-available": /* @__PURE__ */ a(s, { className: "size-3.5" }),
|
|
219
218
|
"output-error": /* @__PURE__ */ a(m, { className: "size-3.5 text-destructive" }),
|
|
220
219
|
"output-denied": /* @__PURE__ */ a(m, { className: "size-3.5 text-destructive" })
|
|
221
|
-
},
|
|
220
|
+
}, ge = ({ state: e }) => /* @__PURE__ */ o("span", {
|
|
222
221
|
className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground",
|
|
223
|
-
children: [
|
|
224
|
-
}),
|
|
225
|
-
className:
|
|
222
|
+
children: [he[e], me[e]]
|
|
223
|
+
}), _e = ({ className: e, type: t, state: n, title: r, ...i }) => /* @__PURE__ */ o(A, {
|
|
224
|
+
className: E("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),
|
|
226
225
|
...i,
|
|
227
226
|
children: [/* @__PURE__ */ o("div", {
|
|
228
227
|
className: "flex min-w-0 flex-1 items-center gap-2",
|
|
@@ -232,20 +231,20 @@ var de = 8, M = 240, N = 2e4, P = (e) => e === null || typeof e != "object" && t
|
|
|
232
231
|
})]
|
|
233
232
|
}), /* @__PURE__ */ o("div", {
|
|
234
233
|
className: "flex shrink-0 items-center gap-2",
|
|
235
|
-
children: [/* @__PURE__ */ a(
|
|
234
|
+
children: [/* @__PURE__ */ a(ge, { state: n }), /* @__PURE__ */ a(c, { className: "size-3.5 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" })]
|
|
236
235
|
})]
|
|
237
|
-
}),
|
|
238
|
-
className:
|
|
236
|
+
}), ve = ({ className: e, ...t }) => /* @__PURE__ */ a(j, {
|
|
237
|
+
className: E("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),
|
|
239
238
|
...t
|
|
240
|
-
}),
|
|
241
|
-
className:
|
|
239
|
+
}), ye = ({ className: e, input: t, ...n }) => V(t) ? /* @__PURE__ */ o("div", {
|
|
240
|
+
className: E("space-y-1.5 overflow-hidden px-2.5 pb-2.5", e),
|
|
242
241
|
...n,
|
|
243
242
|
children: [/* @__PURE__ */ a("h4", {
|
|
244
243
|
className: "text-xs font-medium tracking-wide text-muted-foreground uppercase",
|
|
245
244
|
children: "Parameters"
|
|
246
|
-
}), /* @__PURE__ */ a(
|
|
247
|
-
}) : null,
|
|
248
|
-
className:
|
|
245
|
+
}), /* @__PURE__ */ a(G, { value: t })]
|
|
246
|
+
}) : null, be = ({ className: e, output: t, errorText: n, ...r }) => V(t) || n ? /* @__PURE__ */ o("div", {
|
|
247
|
+
className: E("space-y-1.5 px-2.5 pb-2.5", e),
|
|
249
248
|
...r,
|
|
250
249
|
children: [/* @__PURE__ */ a("h4", {
|
|
251
250
|
className: "text-xs font-medium tracking-wide text-muted-foreground uppercase",
|
|
@@ -255,9 +254,9 @@ var de = 8, M = 240, N = 2e4, P = (e) => e === null || typeof e != "object" && t
|
|
|
255
254
|
children: n
|
|
256
255
|
}) : /* @__PURE__ */ a("div", {
|
|
257
256
|
className: "text-xs [&_table]:w-full",
|
|
258
|
-
children: /* @__PURE__ */ a(
|
|
257
|
+
children: /* @__PURE__ */ a(G, { value: t })
|
|
259
258
|
})]
|
|
260
|
-
}) : null,
|
|
259
|
+
}) : null, xe = T("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", {
|
|
261
260
|
variants: {
|
|
262
261
|
variant: {
|
|
263
262
|
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
@@ -283,12 +282,12 @@ var de = 8, M = 240, N = 2e4, P = (e) => e === null || typeof e != "object" && t
|
|
|
283
282
|
size: "default"
|
|
284
283
|
}
|
|
285
284
|
});
|
|
286
|
-
function
|
|
287
|
-
return /* @__PURE__ */ a(r ?
|
|
285
|
+
function K({ className: e, variant: t = "default", size: n = "default", asChild: r = !1, ...i }) {
|
|
286
|
+
return /* @__PURE__ */ a(r ? C.Root : "button", {
|
|
288
287
|
"data-slot": "button",
|
|
289
288
|
"data-variant": t,
|
|
290
289
|
"data-size": n,
|
|
291
|
-
className:
|
|
290
|
+
className: E(xe({
|
|
292
291
|
variant: t,
|
|
293
292
|
size: n,
|
|
294
293
|
className: e
|
|
@@ -298,43 +297,43 @@ function V({ className: e, variant: t = "default", size: n = "default", asChild:
|
|
|
298
297
|
}
|
|
299
298
|
//#endregion
|
|
300
299
|
//#region src/internal/tooltip.tsx
|
|
301
|
-
function
|
|
302
|
-
return /* @__PURE__ */ a(
|
|
300
|
+
function q({ delayDuration: e = 0, ...t }) {
|
|
301
|
+
return /* @__PURE__ */ a(w.Provider, {
|
|
303
302
|
"data-slot": "tooltip-provider",
|
|
304
303
|
delayDuration: e,
|
|
305
304
|
...t
|
|
306
305
|
});
|
|
307
306
|
}
|
|
308
|
-
function
|
|
309
|
-
return /* @__PURE__ */ a(
|
|
307
|
+
function J({ ...e }) {
|
|
308
|
+
return /* @__PURE__ */ a(w.Root, {
|
|
310
309
|
"data-slot": "tooltip",
|
|
311
310
|
...e
|
|
312
311
|
});
|
|
313
312
|
}
|
|
314
|
-
function
|
|
315
|
-
return /* @__PURE__ */ a(
|
|
313
|
+
function Y({ ...e }) {
|
|
314
|
+
return /* @__PURE__ */ a(w.Trigger, {
|
|
316
315
|
"data-slot": "tooltip-trigger",
|
|
317
316
|
...e
|
|
318
317
|
});
|
|
319
318
|
}
|
|
320
|
-
function
|
|
321
|
-
return /* @__PURE__ */ a(
|
|
319
|
+
function X({ className: e, sideOffset: t = 0, children: n, ...r }) {
|
|
320
|
+
return /* @__PURE__ */ a(w.Portal, { children: /* @__PURE__ */ o(w.Content, {
|
|
322
321
|
"data-slot": "tooltip-content",
|
|
323
322
|
sideOffset: t,
|
|
324
|
-
className:
|
|
323
|
+
className: E("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),
|
|
325
324
|
...r,
|
|
326
|
-
children: [n, /* @__PURE__ */ a(
|
|
325
|
+
children: [n, /* @__PURE__ */ a(w.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" })]
|
|
327
326
|
}) });
|
|
328
327
|
}
|
|
329
328
|
//#endregion
|
|
330
329
|
//#region src/chat/actions.tsx
|
|
331
|
-
var
|
|
332
|
-
className:
|
|
330
|
+
var Se = ({ className: e, children: t, ...n }) => /* @__PURE__ */ a("div", {
|
|
331
|
+
className: E("-ml-1.5 flex items-center", e),
|
|
333
332
|
...n,
|
|
334
333
|
children: t
|
|
335
|
-
}),
|
|
336
|
-
let l = /* @__PURE__ */ o(
|
|
337
|
-
className:
|
|
334
|
+
}), Ce = ({ tooltip: e, children: t, label: n, className: r, variant: i = "ghost", size: s = "icon", ...c }) => {
|
|
335
|
+
let l = /* @__PURE__ */ o(K, {
|
|
336
|
+
className: E("relative", r),
|
|
338
337
|
size: s,
|
|
339
338
|
type: "button",
|
|
340
339
|
variant: i,
|
|
@@ -344,14 +343,113 @@ var Te = ({ className: e, children: t, ...n }) => /* @__PURE__ */ a("div", {
|
|
|
344
343
|
children: n || e
|
|
345
344
|
})]
|
|
346
345
|
});
|
|
347
|
-
return e ? /* @__PURE__ */ a(
|
|
346
|
+
return e ? /* @__PURE__ */ a(q, {
|
|
348
347
|
delayDuration: 500,
|
|
349
|
-
children: /* @__PURE__ */ o(
|
|
348
|
+
children: /* @__PURE__ */ o(J, { children: [/* @__PURE__ */ a(Y, {
|
|
350
349
|
asChild: !0,
|
|
351
350
|
children: l
|
|
352
|
-
}), /* @__PURE__ */ a(
|
|
351
|
+
}), /* @__PURE__ */ a(X, { children: /* @__PURE__ */ a("p", { children: e }) })] })
|
|
353
352
|
}) : l;
|
|
354
|
-
}
|
|
353
|
+
};
|
|
354
|
+
//#endregion
|
|
355
|
+
//#region src/chat/segments.ts
|
|
356
|
+
function we(e, t) {
|
|
357
|
+
return e.startsWith("tool-") && !t(e);
|
|
358
|
+
}
|
|
359
|
+
function Te(e, t) {
|
|
360
|
+
let n = t?.isPresentationalTool ?? (() => !1), r = -1;
|
|
361
|
+
e.forEach((e, t) => {
|
|
362
|
+
(e.type === "reasoning" || we(e.type, n)) && (r = t);
|
|
363
|
+
});
|
|
364
|
+
let i = [], a = null, o = null, s = (e) => {
|
|
365
|
+
o = null, a || (a = {
|
|
366
|
+
kind: "trace",
|
|
367
|
+
parts: []
|
|
368
|
+
}, i.push(a)), a.parts.push(e);
|
|
369
|
+
};
|
|
370
|
+
return e.forEach((e, t) => {
|
|
371
|
+
if (!(e.type === "step-start" || e.type === "step-finish")) if (e.type === "reasoning") {
|
|
372
|
+
let t = String(e.text ?? ""), n = e.state === "streaming";
|
|
373
|
+
if (!(t.trim() || n)) return;
|
|
374
|
+
s(e);
|
|
375
|
+
} else we(e.type, n) ? s(e) : e.type === "text" && t <= r ? String(e.text ?? "").trim() && s(e) : e.type === "file" ? (a = null, o || (o = {
|
|
376
|
+
kind: "images",
|
|
377
|
+
parts: [],
|
|
378
|
+
index: t
|
|
379
|
+
}, i.push(o)), o.parts.push(e)) : (a = null, o = null, i.push({
|
|
380
|
+
kind: "part",
|
|
381
|
+
part: e,
|
|
382
|
+
index: t
|
|
383
|
+
}));
|
|
384
|
+
}), i;
|
|
385
|
+
}
|
|
386
|
+
function Ee(e, t) {
|
|
387
|
+
return e.some((e) => {
|
|
388
|
+
let n = e.state;
|
|
389
|
+
return typeof n == "string" ? e.type === "reasoning" || e.type === "text" ? n === "streaming" : n === "input-streaming" || n === "input-available" : t;
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
//#endregion
|
|
393
|
+
//#region src/chat/web-search.ts
|
|
394
|
+
function De(e) {
|
|
395
|
+
return typeof e == "object" && !!e && "error" in e && typeof e.error == "string";
|
|
396
|
+
}
|
|
397
|
+
var Oe = /\(\s*(\[[^\]\n]*\]\((?:[^()\n]|\([^()\n]*\))*\))\s*\)/g;
|
|
398
|
+
function ke(e) {
|
|
399
|
+
return e.replace(Oe, "$1");
|
|
400
|
+
}
|
|
401
|
+
var Ae = "tool-webSearch";
|
|
402
|
+
function je(e) {
|
|
403
|
+
try {
|
|
404
|
+
let t = new URL(e);
|
|
405
|
+
return `${t.hostname.toLowerCase()}${t.pathname.replace(/\/$/, "")}${t.search}`;
|
|
406
|
+
} catch {
|
|
407
|
+
return e.replace(/#.*$/, "").replace(/\/$/, "");
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function Me(e, t) {
|
|
411
|
+
let n = t?.toolType ?? Ae, r = /* @__PURE__ */ new Set(), i = [];
|
|
412
|
+
for (let t of e) {
|
|
413
|
+
if (t.type !== n || t.state !== "output-available" || De(t.output)) continue;
|
|
414
|
+
let e = t.output?.results;
|
|
415
|
+
if (Array.isArray(e)) for (let t of e) {
|
|
416
|
+
if (typeof t?.url != "string") continue;
|
|
417
|
+
let e = je(t.url);
|
|
418
|
+
r.has(e) || (r.add(e), i.push({
|
|
419
|
+
url: t.url,
|
|
420
|
+
title: typeof t.title == "string" ? t.title : void 0
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return i;
|
|
425
|
+
}
|
|
426
|
+
//#endregion
|
|
427
|
+
//#region src/chat/turn-view.ts
|
|
428
|
+
function Ne(e, t) {
|
|
429
|
+
let n = t?.isSearchTool ?? (() => !1), r = t?.messageLoading, i = Te(e, { isPresentationalTool: t?.isPresentationalTool }), a = i.flatMap((e) => e.kind === "trace" ? e.parts : []), o = i.filter((e) => e.kind === "part" && e.part.type === "text"), s = o.some((e) => String(e.part.text ?? "").trim() !== ""), c = s && o.some((e) => e.part.state === "streaming"), l = a.some((e) => e.type === "reasoning" && String(e.text ?? "").trim() !== ""), u = a.some((e) => e.type.startsWith("tool-")), d = i.length > 0, f = a.some((e) => e.type === "reasoning" && e.state === "streaming"), p;
|
|
430
|
+
for (let e of a) {
|
|
431
|
+
if (!e.type.startsWith("tool-")) continue;
|
|
432
|
+
let t = String(e.state ?? "");
|
|
433
|
+
t === "output-available" || t === "output-error" || t === "output-denied" || (p = e.type);
|
|
434
|
+
}
|
|
435
|
+
let m = a.length > 0 && Ee(a, r ?? !1), h = (r ?? !0) && !s, g = a.length > 0 ? {
|
|
436
|
+
parts: a,
|
|
437
|
+
isLoading: h
|
|
438
|
+
} : null, _;
|
|
439
|
+
_ = d ? h ? m && f ? "reasoning" : m && p && n(p) ? "searching" : m && p ? "tooling" : l ? "reasoning" : u ? "tooling" : "reasoning" : c ? "answering" : "settled" : h ? "waiting" : "settled";
|
|
440
|
+
let v = d ? l ? "reasoning" : "tools" : "waiting";
|
|
441
|
+
return {
|
|
442
|
+
phase: _,
|
|
443
|
+
segments: i,
|
|
444
|
+
trace: g,
|
|
445
|
+
sources: Me(e),
|
|
446
|
+
activityKind: v,
|
|
447
|
+
hasFinalAnswer: s
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
//#endregion
|
|
451
|
+
//#region src/chat/activity-labels.ts
|
|
452
|
+
var Pe = [
|
|
355
453
|
{
|
|
356
454
|
active: "Thinking",
|
|
357
455
|
done: "Thought"
|
|
@@ -389,114 +487,166 @@ var Te = ({ className: e, children: t, ...n }) => /* @__PURE__ */ a("div", {
|
|
|
389
487
|
done: "Refined"
|
|
390
488
|
},
|
|
391
489
|
{
|
|
392
|
-
active: "
|
|
393
|
-
done: "
|
|
490
|
+
active: "Musing",
|
|
491
|
+
done: "Mused"
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
active: "Scurrying",
|
|
495
|
+
done: "Scurried"
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
active: "Crunching",
|
|
499
|
+
done: "Crunched"
|
|
394
500
|
}
|
|
395
|
-
],
|
|
396
|
-
waiting:
|
|
397
|
-
reasoning:
|
|
501
|
+
], Fe = {
|
|
502
|
+
waiting: Pe,
|
|
503
|
+
reasoning: Pe,
|
|
398
504
|
tools: [{
|
|
399
505
|
active: "Working",
|
|
400
506
|
done: "Worked"
|
|
401
507
|
}]
|
|
402
|
-
}
|
|
403
|
-
function
|
|
404
|
-
let
|
|
405
|
-
|
|
508
|
+
};
|
|
509
|
+
function Z({ kind: e, active: t, seed: n, elapsedSeconds: r, verb: i }) {
|
|
510
|
+
let a;
|
|
511
|
+
if (i !== void 0) a = i;
|
|
512
|
+
else {
|
|
513
|
+
let r = Fe[e], i = r[Math.abs(n) % r.length];
|
|
514
|
+
a = t ? i.active : i.done;
|
|
515
|
+
}
|
|
516
|
+
return {
|
|
517
|
+
verb: a,
|
|
518
|
+
elapsedSeconds: r > 0 ? r : 0
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
function Ie(e) {
|
|
522
|
+
let { verb: t, elapsedSeconds: n } = Z(e);
|
|
523
|
+
return n <= 0 ? t : `${t} for ${n}s`;
|
|
406
524
|
}
|
|
407
|
-
function
|
|
525
|
+
function Le(e, t) {
|
|
408
526
|
let n = Infinity, r = -Infinity, i = !1;
|
|
409
|
-
for (let t of e)
|
|
527
|
+
for (let t of e) Number.isFinite(t.startedAtMs) && (n = Math.min(n, t.startedAtMs), Number.isFinite(t.completedAtMs) ? r = Math.max(r, t.completedAtMs) : i = !0);
|
|
410
528
|
if (n === Infinity) return 0;
|
|
411
|
-
let a = i
|
|
529
|
+
let a = i && Number.isFinite(t) ? t : r;
|
|
412
530
|
return a === -Infinity ? 0 : Math.max(0, Math.floor((a - n) / 1e3));
|
|
413
531
|
}
|
|
414
|
-
function
|
|
532
|
+
function Re(e) {
|
|
415
533
|
let t = 0;
|
|
416
534
|
for (let n = 0; n < e.length; n += 1) t = t * 31 + e.charCodeAt(n) | 0;
|
|
417
535
|
return t;
|
|
418
536
|
}
|
|
419
537
|
//#endregion
|
|
420
538
|
//#region src/chat/message-trace.tsx
|
|
421
|
-
function
|
|
539
|
+
function Q(e) {
|
|
422
540
|
let t = e.replace(/^tool-/, "").replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim();
|
|
423
541
|
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
424
542
|
}
|
|
425
|
-
var
|
|
426
|
-
let
|
|
427
|
-
for (let t of e) t.type.startsWith("tool-")
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
543
|
+
var ze = _(({ parts: e, isLoading: t, messageId: n, activity: r, getToolLabel: i, getToolIcon: s, getActivityOverride: c, renderStepDetail: l, defaultOpen: u = !1, className: d }) => {
|
|
544
|
+
let f = e.filter((e) => e.type === "reasoning").map((e) => String(e.text ?? "")).filter((e) => e.trim()).join("\n\n"), p = f.trim().length > 0, m = [], h = !1, g;
|
|
545
|
+
for (let t of e) if (t.type.startsWith("tool-")) {
|
|
546
|
+
h = !0;
|
|
547
|
+
let e = String(t.state ?? "");
|
|
548
|
+
e === "output-available" || e === "output-error" || e === "output-denied" || (g = t.type), m.push({
|
|
549
|
+
kind: "tool",
|
|
550
|
+
label: i?.(t.type) ?? Q(t.type),
|
|
551
|
+
state: e,
|
|
552
|
+
toolType: t.type,
|
|
553
|
+
part: t
|
|
554
|
+
});
|
|
555
|
+
} else t.type === "text" && String(t.text ?? "").trim() && m.push({
|
|
433
556
|
kind: "note",
|
|
434
557
|
text: String(t.text)
|
|
435
558
|
});
|
|
436
|
-
|
|
437
|
-
let
|
|
438
|
-
kind:
|
|
559
|
+
h && !t && m.push({ kind: "done" });
|
|
560
|
+
let _ = e.some((e) => Number.isFinite(e.startedAtMs)) ? Le(e, r?.nowMs) : r?.elapsedSeconds ?? 0, v = r?.seed ?? Re(n), y = t ? _ : 0, b = t ? c?.(g) : void 0, S = {
|
|
561
|
+
kind: p ? "reasoning" : "tools",
|
|
439
562
|
active: t,
|
|
440
|
-
seed:
|
|
441
|
-
elapsedSeconds:
|
|
442
|
-
|
|
563
|
+
seed: v,
|
|
564
|
+
elapsedSeconds: y,
|
|
565
|
+
verb: b
|
|
566
|
+
}, C = Ie(S), { elapsedSeconds: w } = Z(S), T = p || m.length > 0, te = T && t && w === 0, [D, O] = x(u), k = ee();
|
|
443
567
|
return /* @__PURE__ */ o("div", {
|
|
444
|
-
className:
|
|
568
|
+
className: E("not-prose flex flex-col", d),
|
|
445
569
|
children: [/* @__PURE__ */ a("button", {
|
|
446
570
|
type: "button",
|
|
447
571
|
"data-testid": "message-reasoning",
|
|
448
|
-
onClick: () =>
|
|
449
|
-
|
|
572
|
+
onClick: () => O((e) => !e),
|
|
573
|
+
"aria-expanded": D,
|
|
574
|
+
"aria-controls": T ? k : void 0,
|
|
575
|
+
className: "flex items-center gap-1 self-start text-[13px] leading-5 text-muted-foreground transition-colors hover:text-foreground",
|
|
450
576
|
children: /* @__PURE__ */ o("span", {
|
|
451
|
-
className:
|
|
452
|
-
children: [
|
|
577
|
+
className: E(t && "ocui-shimmer"),
|
|
578
|
+
children: [C, te ? "..." : ""]
|
|
453
579
|
})
|
|
454
|
-
}),
|
|
580
|
+
}), D && T && /* @__PURE__ */ o("div", {
|
|
581
|
+
id: k,
|
|
455
582
|
className: "mt-2 flex flex-col gap-2",
|
|
456
|
-
children: [
|
|
583
|
+
children: [p && /* @__PURE__ */ a(ne, {
|
|
457
584
|
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:
|
|
459
|
-
}),
|
|
585
|
+
children: f
|
|
586
|
+
}), m.length > 0 && /* @__PURE__ */ a("div", {
|
|
460
587
|
className: "flex flex-col",
|
|
461
|
-
children:
|
|
588
|
+
children: m.map((e, t) => /* @__PURE__ */ a(Be, {
|
|
462
589
|
node: e,
|
|
463
590
|
isFirst: t === 0,
|
|
464
|
-
isLast: t ===
|
|
465
|
-
getToolIcon: s
|
|
591
|
+
isLast: t === m.length - 1,
|
|
592
|
+
getToolIcon: s,
|
|
593
|
+
renderStepDetail: l
|
|
466
594
|
}, `step-${t}`))
|
|
467
595
|
})]
|
|
468
596
|
})]
|
|
469
597
|
});
|
|
470
|
-
};
|
|
471
|
-
|
|
598
|
+
});
|
|
599
|
+
ze.displayName = "MessageTrace";
|
|
600
|
+
function Be({ node: e, isFirst: t, isLast: n, getToolIcon: r, renderStepDetail: i }) {
|
|
601
|
+
let s = e.kind === "tool" && i ? i(e.part) : null, l = s != null, [u, d] = x(!1), f = ee();
|
|
472
602
|
return /* @__PURE__ */ o("div", {
|
|
473
|
-
className: "flex
|
|
603
|
+
className: "flex flex-col",
|
|
474
604
|
children: [/* @__PURE__ */ o("div", {
|
|
475
|
-
className: "flex
|
|
476
|
-
children: [
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
className: "text-
|
|
488
|
-
children: e.
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
605
|
+
className: "flex items-stretch gap-2.5",
|
|
606
|
+
children: [/* @__PURE__ */ o("div", {
|
|
607
|
+
className: "flex w-4 flex-col items-center",
|
|
608
|
+
children: [
|
|
609
|
+
/* @__PURE__ */ a("div", { className: E("w-px flex-1", t ? "bg-transparent" : "bg-border") }),
|
|
610
|
+
/* @__PURE__ */ a(Ve, {
|
|
611
|
+
node: e,
|
|
612
|
+
getToolIcon: r
|
|
613
|
+
}),
|
|
614
|
+
/* @__PURE__ */ a("div", { className: E("w-px flex-1", n ? "bg-transparent" : "bg-border") })
|
|
615
|
+
]
|
|
616
|
+
}), /* @__PURE__ */ a("div", {
|
|
617
|
+
className: "min-w-0 py-1 text-sm leading-5",
|
|
618
|
+
children: e.kind === "tool" ? l ? /* @__PURE__ */ o("button", {
|
|
619
|
+
type: "button",
|
|
620
|
+
onClick: () => d((e) => !e),
|
|
621
|
+
"aria-expanded": u,
|
|
622
|
+
"aria-controls": f,
|
|
623
|
+
className: "group inline-flex items-center gap-1 text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
624
|
+
children: [/* @__PURE__ */ a("span", { children: e.label }), /* @__PURE__ */ a(c, { className: E("size-2.5 transition-[transform,opacity]", u ? "rotate-180 opacity-100" : "opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100") })]
|
|
625
|
+
}) : /* @__PURE__ */ a("span", {
|
|
626
|
+
className: "text-muted-foreground",
|
|
627
|
+
children: e.label
|
|
628
|
+
}) : e.kind === "note" ? /* @__PURE__ */ a("span", {
|
|
629
|
+
className: "text-muted-foreground/80",
|
|
630
|
+
children: e.text
|
|
631
|
+
}) : /* @__PURE__ */ a("span", {
|
|
632
|
+
className: "text-muted-foreground",
|
|
633
|
+
children: "Done"
|
|
634
|
+
})
|
|
635
|
+
})]
|
|
636
|
+
}), l && u && /* @__PURE__ */ o("div", {
|
|
637
|
+
className: "flex items-stretch gap-2.5",
|
|
638
|
+
children: [/* @__PURE__ */ a("div", {
|
|
639
|
+
className: "flex w-4 flex-col items-center",
|
|
640
|
+
children: /* @__PURE__ */ a("div", { className: E("w-px flex-1", n ? "bg-transparent" : "bg-border") })
|
|
641
|
+
}), /* @__PURE__ */ a("div", {
|
|
642
|
+
id: f,
|
|
643
|
+
className: "min-w-0 flex-1 pb-1",
|
|
644
|
+
children: s
|
|
645
|
+
})]
|
|
496
646
|
})]
|
|
497
647
|
});
|
|
498
648
|
}
|
|
499
|
-
function
|
|
649
|
+
function Ve({ node: e, getToolIcon: t }) {
|
|
500
650
|
let n = "flex items-center justify-center bg-background py-0.5";
|
|
501
651
|
return e.kind === "note" ? /* @__PURE__ */ a("div", {
|
|
502
652
|
className: n,
|
|
@@ -509,54 +659,16 @@ function je({ node: e, getToolIcon: t }) {
|
|
|
509
659
|
children: /* @__PURE__ */ a(t?.(e.toolType) ?? s, { className: "size-3.5 text-muted-foreground" })
|
|
510
660
|
}) : /* @__PURE__ */ a("div", {
|
|
511
661
|
className: n,
|
|
512
|
-
children: /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin text-muted-foreground" })
|
|
662
|
+
children: /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin text-muted-foreground motion-reduce:animate-none" })
|
|
513
663
|
}) : /* @__PURE__ */ a("div", {
|
|
514
664
|
className: n,
|
|
515
665
|
children: /* @__PURE__ */ a(l, { className: "size-4 text-muted-foreground" })
|
|
516
666
|
});
|
|
517
667
|
}
|
|
518
668
|
//#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
669
|
//#region src/chat/use-activity-clock.ts
|
|
558
|
-
function
|
|
559
|
-
let n =
|
|
670
|
+
function He(e, t) {
|
|
671
|
+
let n = b(null), [r, i] = x(() => ({
|
|
560
672
|
seed: t,
|
|
561
673
|
elapsedSeconds: 0,
|
|
562
674
|
nowMs: Date.now()
|
|
@@ -597,21 +709,21 @@ function Pe(e, t) {
|
|
|
597
709
|
}
|
|
598
710
|
//#endregion
|
|
599
711
|
//#region src/chat/sources.tsx
|
|
600
|
-
function
|
|
601
|
-
return `
|
|
712
|
+
function Ue(e) {
|
|
713
|
+
return `Searched ${e} source${e === 1 ? "" : "s"}`;
|
|
602
714
|
}
|
|
603
|
-
function
|
|
715
|
+
function We(e) {
|
|
604
716
|
try {
|
|
605
717
|
return new URL(e).hostname;
|
|
606
718
|
} catch {
|
|
607
719
|
return e;
|
|
608
720
|
}
|
|
609
721
|
}
|
|
610
|
-
function
|
|
611
|
-
return `https://www.google.com/s2/favicons?domain=${
|
|
722
|
+
function Ge(e) {
|
|
723
|
+
return `https://www.google.com/s2/favicons?domain=${We(e)}&sz=32`;
|
|
612
724
|
}
|
|
613
|
-
function
|
|
614
|
-
let n = t(e), [r, i] =
|
|
725
|
+
function Ke({ url: e, getFaviconUrl: t }) {
|
|
726
|
+
let n = t(e), [r, i] = x(!1);
|
|
615
727
|
return !n || r ? /* @__PURE__ */ a(d, { className: "size-3.5 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ a("img", {
|
|
616
728
|
src: n,
|
|
617
729
|
alt: "",
|
|
@@ -619,92 +731,65 @@ function Le({ url: e, getFaviconUrl: t }) {
|
|
|
619
731
|
onError: () => i(!0)
|
|
620
732
|
});
|
|
621
733
|
}
|
|
622
|
-
var
|
|
623
|
-
className:
|
|
734
|
+
var $ = ({ sources: e, getFaviconUrl: t = Ge, className: n }) => e.length === 0 ? null : /* @__PURE__ */ a("div", {
|
|
735
|
+
className: E("flex flex-col gap-0.5", n),
|
|
736
|
+
children: e.map((e, n) => {
|
|
737
|
+
let r = We(e.url), i = e.title || r;
|
|
738
|
+
return /* @__PURE__ */ o("a", {
|
|
739
|
+
href: e.url,
|
|
740
|
+
target: "_blank",
|
|
741
|
+
rel: "noreferrer",
|
|
742
|
+
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",
|
|
743
|
+
children: [
|
|
744
|
+
/* @__PURE__ */ a(Ke, {
|
|
745
|
+
getFaviconUrl: t,
|
|
746
|
+
url: e.url
|
|
747
|
+
}),
|
|
748
|
+
/* @__PURE__ */ a("span", {
|
|
749
|
+
className: "truncate",
|
|
750
|
+
children: i
|
|
751
|
+
}),
|
|
752
|
+
i !== r && /* @__PURE__ */ a("span", {
|
|
753
|
+
className: "shrink-0 truncate text-xs text-muted-foreground/70",
|
|
754
|
+
children: r
|
|
755
|
+
})
|
|
756
|
+
]
|
|
757
|
+
}, `${e.url}-${n}`);
|
|
758
|
+
})
|
|
759
|
+
}), qe = ({ sources: e, getLabel: t = Ue, getFaviconUrl: n = Ge, className: r, ...i }) => e.length === 0 ? null : /* @__PURE__ */ o(k, {
|
|
760
|
+
className: E("not-prose", r),
|
|
624
761
|
...i,
|
|
625
|
-
children: [/* @__PURE__ */ o(
|
|
626
|
-
className: "group flex items-center gap-1
|
|
762
|
+
children: [/* @__PURE__ */ o(A, {
|
|
763
|
+
className: "group flex items-center gap-1 self-start text-[13px] leading-5 text-muted-foreground transition-colors hover:text-foreground",
|
|
627
764
|
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(
|
|
629
|
-
className: "mt-1
|
|
630
|
-
children:
|
|
631
|
-
|
|
632
|
-
|
|
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}`);
|
|
765
|
+
}), /* @__PURE__ */ a(j, {
|
|
766
|
+
className: "mt-1 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",
|
|
767
|
+
children: /* @__PURE__ */ a($, {
|
|
768
|
+
sources: e,
|
|
769
|
+
getFaviconUrl: n
|
|
652
770
|
})
|
|
653
771
|
})]
|
|
654
|
-
}),
|
|
655
|
-
|
|
656
|
-
|
|
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, {
|
|
772
|
+
}), Je = "ocui-cite", Ye = ({ pressed: e, onPressedChange: t, label: n = "Search the web", tooltip: r, className: i, variant: s, size: c = "icon", onClick: l, ...u }) => {
|
|
773
|
+
let f = s ?? (e ? "default" : "ghost"), p = /* @__PURE__ */ a(K, {
|
|
774
|
+
...u,
|
|
689
775
|
"aria-label": n,
|
|
690
776
|
"aria-pressed": e,
|
|
691
|
-
className:
|
|
692
|
-
onClick: (n) => {
|
|
693
|
-
l?.(n), t(!e);
|
|
694
|
-
},
|
|
777
|
+
className: E(i),
|
|
695
778
|
size: c,
|
|
696
779
|
type: "button",
|
|
697
780
|
variant: f,
|
|
698
|
-
|
|
781
|
+
onClick: (n) => {
|
|
782
|
+
l?.(n), t(!e);
|
|
783
|
+
},
|
|
699
784
|
children: /* @__PURE__ */ a(d, {})
|
|
700
785
|
});
|
|
701
|
-
return r ? /* @__PURE__ */ a(
|
|
786
|
+
return r ? /* @__PURE__ */ a(q, {
|
|
702
787
|
delayDuration: 300,
|
|
703
|
-
children: /* @__PURE__ */ o(
|
|
788
|
+
children: /* @__PURE__ */ o(J, { children: [/* @__PURE__ */ a(Y, {
|
|
704
789
|
asChild: !0,
|
|
705
790
|
children: p
|
|
706
|
-
}), /* @__PURE__ */ a(
|
|
791
|
+
}), /* @__PURE__ */ a(X, { children: /* @__PURE__ */ a("p", { children: r }) })] })
|
|
707
792
|
}) : p;
|
|
708
793
|
};
|
|
709
794
|
//#endregion
|
|
710
|
-
export {
|
|
795
|
+
export { Ce as Action, Se as Actions, O as MessageContent, ze as MessageTrace, N as Reasoning, I as ReasoningContent, P as ReasoningTrigger, ne as Response, $ as SourceList, qe as Sources, pe as Tool, ve as ToolContent, _e as ToolHeader, ye as ToolInput, be as ToolOutput, Ye as WebSearchToggle, Te as buildSegments, Je as citationClassName, Ne as deriveTurnView, Me as extractWebSearchSources, Ie as getAiActivityLabel, Z as getAiActivityLabelParts, Q as humanizeToolName, De as isWebSearchError, Re as labelSeedFromString, F as reasoningTextClassName, ke as stripCitationParens, Le as traceElapsedSeconds, Ee as traceIsLoading, He as useActivityClock };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ocai/app-sdk-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Shared design tokens and AI-app UI primitives for OceanAI products.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -47,21 +47,26 @@
|
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@streamdown/math": "^1.0.2",
|
|
50
|
+
"@testing-library/dom": "^10.4.1",
|
|
51
|
+
"@testing-library/react": "^16.3.2",
|
|
50
52
|
"@types/node": "^22.0.0",
|
|
51
53
|
"@types/react": "^19.0.0",
|
|
52
54
|
"@types/react-dom": "^19.0.0",
|
|
53
55
|
"@vitejs/plugin-react": "^6.0.1",
|
|
54
56
|
"ai": "^6.0.0",
|
|
57
|
+
"jsdom": "^26.1.0",
|
|
55
58
|
"react": "^19.0.0",
|
|
56
59
|
"react-dom": "^19.0.0",
|
|
57
60
|
"streamdown": "^2.5.0",
|
|
58
61
|
"typescript": "~5.6.0",
|
|
59
62
|
"vite": "^8.0.16",
|
|
60
|
-
"vite-plugin-dts": "^4.5.4"
|
|
63
|
+
"vite-plugin-dts": "^4.5.4",
|
|
64
|
+
"vitest": "^4.1.10"
|
|
61
65
|
},
|
|
62
66
|
"scripts": {
|
|
63
67
|
"build": "vite build && cp src/tokens.css src/chat/chat.css dist/",
|
|
64
68
|
"dev": "vite build --watch",
|
|
65
|
-
"typecheck": "tsc --noEmit"
|
|
69
|
+
"typecheck": "tsc --noEmit",
|
|
70
|
+
"test": "vitest run"
|
|
66
71
|
}
|
|
67
72
|
}
|