@ocai/app-sdk-ui 0.2.0 → 0.3.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 +2 -1
- package/dist/chat/response.d.ts +1 -2
- package/dist/chat/sources.d.ts +2 -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 +4 -3
- package/dist/index.js +291 -243
- 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;
|
|
@@ -10,7 +10,8 @@ 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;
|
|
13
14
|
defaultOpen?: boolean;
|
|
14
15
|
className?: string;
|
|
15
16
|
};
|
|
16
|
-
export declare const MessageTrace: ({ parts, isLoading, messageId, activity, getToolLabel, getToolIcon, defaultOpen, className, }: MessageTraceProps) => ReactElement
|
|
17
|
+
export declare const MessageTrace: import('react').MemoExoticComponent<({ parts, isLoading, messageId, activity, getToolLabel, getToolIcon, getActivityOverride, 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
|
@@ -6,8 +6,8 @@ export type SourceItem = {
|
|
|
6
6
|
};
|
|
7
7
|
export type SourcesProps = Omit<ComponentProps<typeof Collapsible>, "children"> & {
|
|
8
8
|
sources: readonly SourceItem[];
|
|
9
|
-
|
|
9
|
+
getLabel?: (count: number) => string;
|
|
10
10
|
getFaviconUrl?: (url: string) => string | null;
|
|
11
11
|
};
|
|
12
|
-
export declare const Sources: ({ sources,
|
|
12
|
+
export declare const Sources: ({ sources, getLabel, getFaviconUrl, className, ...props }: SourcesProps) => ReactElement | null;
|
|
13
13
|
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
11
|
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 { 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 te, Tooltip as C } from "radix-ui";
|
|
10
|
+
import { cva as w } from "class-variance-authority";
|
|
11
11
|
//#region src/lib/cn.ts
|
|
12
|
-
function
|
|
12
|
+
function T(...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 E = e({ singleDollarTextMath: !0 });
|
|
18
|
+
function ne({ className: e, ...n }) {
|
|
19
19
|
return /* @__PURE__ */ a(t, {
|
|
20
|
-
className:
|
|
21
|
-
plugins: { math:
|
|
20
|
+
className: T("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: E },
|
|
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: T("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: T("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: T("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: T(l && "ocui-shimmer"),
|
|
123
122
|
children: f
|
|
124
123
|
}),
|
|
125
|
-
/* @__PURE__ */ a(c, { className:
|
|
124
|
+
/* @__PURE__ */ a(c, { className: T("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: T(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: T("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: T("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: T("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: T("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: T("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 = w("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
|
|
285
|
+
function K({ className: e, variant: t = "default", size: n = "default", asChild: r = !1, ...i }) {
|
|
287
286
|
return /* @__PURE__ */ a(r ? te.Root : "button", {
|
|
288
287
|
"data-slot": "button",
|
|
289
288
|
"data-variant": t,
|
|
290
289
|
"data-size": n,
|
|
291
|
-
className:
|
|
290
|
+
className: T(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(C.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(C.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(C.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(C.Portal, { children: /* @__PURE__ */ o(C.Content, {
|
|
322
321
|
"data-slot": "tooltip-content",
|
|
323
322
|
sideOffset: t,
|
|
324
|
-
className:
|
|
323
|
+
className: T("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(C.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: T("-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: T("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"
|
|
@@ -392,94 +490,115 @@ var Te = ({ className: e, children: t, ...n }) => /* @__PURE__ */ a("div", {
|
|
|
392
490
|
active: "Working",
|
|
393
491
|
done: "Done"
|
|
394
492
|
}
|
|
395
|
-
],
|
|
396
|
-
waiting:
|
|
397
|
-
reasoning:
|
|
493
|
+
], Fe = {
|
|
494
|
+
waiting: Pe,
|
|
495
|
+
reasoning: Pe,
|
|
398
496
|
tools: [{
|
|
399
497
|
active: "Working",
|
|
400
498
|
done: "Worked"
|
|
401
499
|
}]
|
|
402
|
-
}
|
|
403
|
-
function
|
|
404
|
-
let
|
|
405
|
-
|
|
500
|
+
};
|
|
501
|
+
function Z({ kind: e, active: t, seed: n, elapsedSeconds: r, verb: i }) {
|
|
502
|
+
let a;
|
|
503
|
+
if (i !== void 0) a = i;
|
|
504
|
+
else {
|
|
505
|
+
let r = Fe[e], i = r[Math.abs(n) % r.length];
|
|
506
|
+
a = t ? i.active : i.done;
|
|
507
|
+
}
|
|
508
|
+
return {
|
|
509
|
+
verb: a,
|
|
510
|
+
elapsedSeconds: r > 0 ? r : 0
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
function Q(e) {
|
|
514
|
+
let { verb: t, elapsedSeconds: n } = Z(e);
|
|
515
|
+
return n <= 0 ? t : `${t} for ${n}s`;
|
|
406
516
|
}
|
|
407
|
-
function
|
|
517
|
+
function Ie(e, t) {
|
|
408
518
|
let n = Infinity, r = -Infinity, i = !1;
|
|
409
|
-
for (let t of e)
|
|
519
|
+
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
520
|
if (n === Infinity) return 0;
|
|
411
|
-
let a = i
|
|
521
|
+
let a = i && Number.isFinite(t) ? t : r;
|
|
412
522
|
return a === -Infinity ? 0 : Math.max(0, Math.floor((a - n) / 1e3));
|
|
413
523
|
}
|
|
414
|
-
function
|
|
524
|
+
function Le(e) {
|
|
415
525
|
let t = 0;
|
|
416
526
|
for (let n = 0; n < e.length; n += 1) t = t * 31 + e.charCodeAt(n) | 0;
|
|
417
527
|
return t;
|
|
418
528
|
}
|
|
419
529
|
//#endregion
|
|
420
530
|
//#region src/chat/message-trace.tsx
|
|
421
|
-
function
|
|
531
|
+
function Re(e) {
|
|
422
532
|
let t = e.replace(/^tool-/, "").replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim();
|
|
423
533
|
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
424
534
|
}
|
|
425
|
-
var
|
|
426
|
-
let
|
|
427
|
-
for (let t of e) t.type.startsWith("tool-")
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
535
|
+
var ze = _(({ parts: e, isLoading: t, messageId: n, activity: r, getToolLabel: i, getToolIcon: s, getActivityOverride: c, defaultOpen: l = !1, className: u }) => {
|
|
536
|
+
let d = e.filter((e) => e.type === "reasoning").map((e) => String(e.text ?? "")).filter((e) => e.trim()).join("\n\n"), f = d.trim().length > 0, p = [], m = !1, h;
|
|
537
|
+
for (let t of e) if (t.type.startsWith("tool-")) {
|
|
538
|
+
m = !0;
|
|
539
|
+
let e = String(t.state ?? "");
|
|
540
|
+
e === "output-available" || e === "output-error" || e === "output-denied" || (h = t.type), p.push({
|
|
541
|
+
kind: "tool",
|
|
542
|
+
label: i?.(t.type) ?? Re(t.type),
|
|
543
|
+
state: e,
|
|
544
|
+
toolType: t.type
|
|
545
|
+
});
|
|
546
|
+
} else t.type === "text" && String(t.text ?? "").trim() && p.push({
|
|
433
547
|
kind: "note",
|
|
434
548
|
text: String(t.text)
|
|
435
549
|
});
|
|
436
|
-
|
|
437
|
-
let
|
|
438
|
-
kind:
|
|
550
|
+
m && !t && p.push({ kind: "done" });
|
|
551
|
+
let g = e.some((e) => Number.isFinite(e.startedAtMs)) ? Ie(e, r?.nowMs) : r?.elapsedSeconds ?? 0, _ = r?.seed ?? Le(n), v = t ? g : 0, y = t ? c?.(h) : void 0, b = {
|
|
552
|
+
kind: f ? "reasoning" : "tools",
|
|
439
553
|
active: t,
|
|
440
|
-
seed:
|
|
441
|
-
elapsedSeconds:
|
|
442
|
-
|
|
554
|
+
seed: _,
|
|
555
|
+
elapsedSeconds: v,
|
|
556
|
+
verb: y
|
|
557
|
+
}, S = Q(b), { elapsedSeconds: te } = Z(b), C = f || p.length > 0, w = C && t && te === 0, [E, D] = x(l), O = ee();
|
|
443
558
|
return /* @__PURE__ */ o("div", {
|
|
444
|
-
className:
|
|
559
|
+
className: T("not-prose flex flex-col", u),
|
|
445
560
|
children: [/* @__PURE__ */ a("button", {
|
|
446
561
|
type: "button",
|
|
447
562
|
"data-testid": "message-reasoning",
|
|
448
|
-
onClick: () =>
|
|
563
|
+
onClick: () => D((e) => !e),
|
|
564
|
+
"aria-expanded": E,
|
|
565
|
+
"aria-controls": C ? O : void 0,
|
|
449
566
|
className: "flex items-center gap-1 self-start text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
450
567
|
children: /* @__PURE__ */ o("span", {
|
|
451
|
-
className:
|
|
452
|
-
children: [
|
|
568
|
+
className: T(t && "ocui-shimmer"),
|
|
569
|
+
children: [S, w ? "..." : ""]
|
|
453
570
|
})
|
|
454
|
-
}),
|
|
571
|
+
}), E && C && /* @__PURE__ */ o("div", {
|
|
572
|
+
id: O,
|
|
455
573
|
className: "mt-2 flex flex-col gap-2",
|
|
456
|
-
children: [
|
|
574
|
+
children: [f && /* @__PURE__ */ a(ne, {
|
|
457
575
|
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
|
-
}),
|
|
576
|
+
children: d
|
|
577
|
+
}), p.length > 0 && /* @__PURE__ */ a("div", {
|
|
460
578
|
className: "flex flex-col",
|
|
461
|
-
children:
|
|
579
|
+
children: p.map((e, t) => /* @__PURE__ */ a(Be, {
|
|
462
580
|
node: e,
|
|
463
581
|
isFirst: t === 0,
|
|
464
|
-
isLast: t ===
|
|
582
|
+
isLast: t === p.length - 1,
|
|
465
583
|
getToolIcon: s
|
|
466
584
|
}, `step-${t}`))
|
|
467
585
|
})]
|
|
468
586
|
})]
|
|
469
587
|
});
|
|
470
|
-
};
|
|
471
|
-
|
|
588
|
+
});
|
|
589
|
+
ze.displayName = "MessageTrace";
|
|
590
|
+
function Be({ node: e, isFirst: t, isLast: n, getToolIcon: r }) {
|
|
472
591
|
return /* @__PURE__ */ o("div", {
|
|
473
592
|
className: "flex items-stretch gap-2.5",
|
|
474
593
|
children: [/* @__PURE__ */ o("div", {
|
|
475
594
|
className: "flex w-4 flex-col items-center",
|
|
476
595
|
children: [
|
|
477
|
-
/* @__PURE__ */ a("div", { className:
|
|
478
|
-
/* @__PURE__ */ a(
|
|
596
|
+
/* @__PURE__ */ a("div", { className: T("w-px flex-1", t ? "bg-transparent" : "bg-border") }),
|
|
597
|
+
/* @__PURE__ */ a(Ve, {
|
|
479
598
|
node: e,
|
|
480
599
|
getToolIcon: r
|
|
481
600
|
}),
|
|
482
|
-
/* @__PURE__ */ a("div", { className:
|
|
601
|
+
/* @__PURE__ */ a("div", { className: T("w-px flex-1", n ? "bg-transparent" : "bg-border") })
|
|
483
602
|
]
|
|
484
603
|
}), /* @__PURE__ */ a("div", {
|
|
485
604
|
className: "min-w-0 py-1 text-sm leading-5",
|
|
@@ -496,7 +615,7 @@ function Ae({ node: e, isFirst: t, isLast: n, getToolIcon: r }) {
|
|
|
496
615
|
})]
|
|
497
616
|
});
|
|
498
617
|
}
|
|
499
|
-
function
|
|
618
|
+
function Ve({ node: e, getToolIcon: t }) {
|
|
500
619
|
let n = "flex items-center justify-center bg-background py-0.5";
|
|
501
620
|
return e.kind === "note" ? /* @__PURE__ */ a("div", {
|
|
502
621
|
className: n,
|
|
@@ -509,54 +628,16 @@ function je({ node: e, getToolIcon: t }) {
|
|
|
509
628
|
children: /* @__PURE__ */ a(t?.(e.toolType) ?? s, { className: "size-3.5 text-muted-foreground" })
|
|
510
629
|
}) : /* @__PURE__ */ a("div", {
|
|
511
630
|
className: n,
|
|
512
|
-
children: /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin text-muted-foreground" })
|
|
631
|
+
children: /* @__PURE__ */ a(f, { className: "size-3.5 animate-spin text-muted-foreground motion-reduce:animate-none" })
|
|
513
632
|
}) : /* @__PURE__ */ a("div", {
|
|
514
633
|
className: n,
|
|
515
634
|
children: /* @__PURE__ */ a(l, { className: "size-4 text-muted-foreground" })
|
|
516
635
|
});
|
|
517
636
|
}
|
|
518
637
|
//#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
638
|
//#region src/chat/use-activity-clock.ts
|
|
558
|
-
function
|
|
559
|
-
let n =
|
|
639
|
+
function He(e, t) {
|
|
640
|
+
let n = b(null), [r, i] = x(() => ({
|
|
560
641
|
seed: t,
|
|
561
642
|
elapsedSeconds: 0,
|
|
562
643
|
nowMs: Date.now()
|
|
@@ -597,21 +678,21 @@ function Pe(e, t) {
|
|
|
597
678
|
}
|
|
598
679
|
//#endregion
|
|
599
680
|
//#region src/chat/sources.tsx
|
|
600
|
-
function
|
|
601
|
-
return `
|
|
681
|
+
function Ue(e) {
|
|
682
|
+
return `Searched ${e} source${e === 1 ? "" : "s"}`;
|
|
602
683
|
}
|
|
603
|
-
function
|
|
684
|
+
function $(e) {
|
|
604
685
|
try {
|
|
605
686
|
return new URL(e).hostname;
|
|
606
687
|
} catch {
|
|
607
688
|
return e;
|
|
608
689
|
}
|
|
609
690
|
}
|
|
610
|
-
function
|
|
611
|
-
return `https://www.google.com/s2/favicons?domain=${
|
|
691
|
+
function We(e) {
|
|
692
|
+
return `https://www.google.com/s2/favicons?domain=${$(e)}&sz=32`;
|
|
612
693
|
}
|
|
613
|
-
function
|
|
614
|
-
let n = t(e), [r, i] =
|
|
694
|
+
function Ge({ url: e, getFaviconUrl: t }) {
|
|
695
|
+
let n = t(e), [r, i] = x(!1);
|
|
615
696
|
return !n || r ? /* @__PURE__ */ a(d, { className: "size-3.5 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ a("img", {
|
|
616
697
|
src: n,
|
|
617
698
|
alt: "",
|
|
@@ -619,23 +700,23 @@ function Le({ url: e, getFaviconUrl: t }) {
|
|
|
619
700
|
onError: () => i(!0)
|
|
620
701
|
});
|
|
621
702
|
}
|
|
622
|
-
var
|
|
623
|
-
className:
|
|
703
|
+
var Ke = ({ sources: e, getLabel: t = Ue, getFaviconUrl: n = We, className: r, ...i }) => e.length === 0 ? null : /* @__PURE__ */ o(k, {
|
|
704
|
+
className: T("not-prose", r),
|
|
624
705
|
...i,
|
|
625
|
-
children: [/* @__PURE__ */ o(
|
|
626
|
-
className: "group flex items-center gap-1
|
|
706
|
+
children: [/* @__PURE__ */ o(A, {
|
|
707
|
+
className: "group flex items-center gap-1 self-start text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
627
708
|
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(
|
|
709
|
+
}), /* @__PURE__ */ a(j, {
|
|
629
710
|
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
711
|
children: e.map((e, t) => {
|
|
631
|
-
let r =
|
|
712
|
+
let r = $(e.url), i = e.title || r;
|
|
632
713
|
return /* @__PURE__ */ o("a", {
|
|
633
714
|
href: e.url,
|
|
634
715
|
target: "_blank",
|
|
635
716
|
rel: "noreferrer",
|
|
636
717
|
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
718
|
children: [
|
|
638
|
-
/* @__PURE__ */ a(
|
|
719
|
+
/* @__PURE__ */ a(Ge, {
|
|
639
720
|
getFaviconUrl: n,
|
|
640
721
|
url: e.url
|
|
641
722
|
}),
|
|
@@ -651,60 +732,27 @@ var Re = ({ sources: e, label: t = Fe, getFaviconUrl: n = Ie, className: r, ...i
|
|
|
651
732
|
}, `${e.url}-${t}`);
|
|
652
733
|
})
|
|
653
734
|
})]
|
|
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, {
|
|
735
|
+
}), qe = "ocui-cite", Je = ({ pressed: e, onPressedChange: t, label: n = "Search the web", tooltip: r, className: i, variant: s, size: c = "icon", onClick: l, ...u }) => {
|
|
736
|
+
let f = s ?? (e ? "default" : "ghost"), p = /* @__PURE__ */ a(K, {
|
|
737
|
+
...u,
|
|
689
738
|
"aria-label": n,
|
|
690
739
|
"aria-pressed": e,
|
|
691
|
-
className:
|
|
692
|
-
onClick: (n) => {
|
|
693
|
-
l?.(n), t(!e);
|
|
694
|
-
},
|
|
740
|
+
className: T(i),
|
|
695
741
|
size: c,
|
|
696
742
|
type: "button",
|
|
697
743
|
variant: f,
|
|
698
|
-
|
|
744
|
+
onClick: (n) => {
|
|
745
|
+
l?.(n), t(!e);
|
|
746
|
+
},
|
|
699
747
|
children: /* @__PURE__ */ a(d, {})
|
|
700
748
|
});
|
|
701
|
-
return r ? /* @__PURE__ */ a(
|
|
749
|
+
return r ? /* @__PURE__ */ a(q, {
|
|
702
750
|
delayDuration: 300,
|
|
703
|
-
children: /* @__PURE__ */ o(
|
|
751
|
+
children: /* @__PURE__ */ o(J, { children: [/* @__PURE__ */ a(Y, {
|
|
704
752
|
asChild: !0,
|
|
705
753
|
children: p
|
|
706
|
-
}), /* @__PURE__ */ a(
|
|
754
|
+
}), /* @__PURE__ */ a(X, { children: /* @__PURE__ */ a("p", { children: r }) })] })
|
|
707
755
|
}) : p;
|
|
708
756
|
};
|
|
709
757
|
//#endregion
|
|
710
|
-
export {
|
|
758
|
+
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, Ke as Sources, pe as Tool, ve as ToolContent, _e as ToolHeader, ye as ToolInput, be as ToolOutput, Je as WebSearchToggle, Te as buildSegments, qe as citationClassName, Ne as deriveTurnView, Me as extractWebSearchSources, Q as getAiActivityLabel, Z as getAiActivityLabelParts, Re as humanizeToolName, De as isWebSearchError, Le as labelSeedFromString, F as reasoningTextClassName, ke as stripCitationParens, Ie 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.3.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
|
}
|