@invergent/agent-chat-react 1.5.4 → 1.5.6
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/index.cjs +667 -567
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +672 -572
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -19,9 +19,9 @@ var reactUseControllableState = require('@radix-ui/react-use-controllable-state'
|
|
|
19
19
|
var shiki = require('shiki');
|
|
20
20
|
var diff = require('diff');
|
|
21
21
|
var Ansi = require('ansi-to-react');
|
|
22
|
-
var tokenlens = require('tokenlens');
|
|
23
22
|
var cmdk = require('cmdk');
|
|
24
23
|
var nanoid = require('nanoid');
|
|
24
|
+
var tokenlens = require('tokenlens');
|
|
25
25
|
require('pdfjs-dist/web/pdf_viewer.css');
|
|
26
26
|
var dateFns = require('date-fns');
|
|
27
27
|
|
|
@@ -3555,7 +3555,7 @@ function ClarifyLocked({
|
|
|
3555
3555
|
function ArtifactToolBlock({ tc }) {
|
|
3556
3556
|
const args = parseArgs(tc.args) ?? {};
|
|
3557
3557
|
const status = effectiveStatus(tc);
|
|
3558
|
-
const label = status === "running" ? "Creating artifact\u2026" : status === "error" ? "
|
|
3558
|
+
const label = status === "running" ? "Creating artifact\u2026" : status === "error" ? "Creating artifact\u2026" : "Created";
|
|
3559
3559
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-sm ", children: [
|
|
3560
3560
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground", children: label }),
|
|
3561
3561
|
args.name && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground truncate", children: args.name })
|
|
@@ -3947,7 +3947,18 @@ var ChatMessage = react.memo(function ChatMessage2({
|
|
|
3947
3947
|
onFileSelect
|
|
3948
3948
|
}) {
|
|
3949
3949
|
if (message.role === "user") {
|
|
3950
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Message, { from: "user", children: /* @__PURE__ */ jsxRuntime.
|
|
3950
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Message, { from: "user", children: /* @__PURE__ */ jsxRuntime.jsxs(MessageContent, { children: [
|
|
3951
|
+
message.content,
|
|
3952
|
+
message.images && message.images.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 mt-2", children: message.images.map((img, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3953
|
+
"img",
|
|
3954
|
+
{
|
|
3955
|
+
src: img.data,
|
|
3956
|
+
alt: "Attached",
|
|
3957
|
+
className: "max-w-64 max-h-48 rounded-lg border border-border object-contain"
|
|
3958
|
+
},
|
|
3959
|
+
i
|
|
3960
|
+
)) })
|
|
3961
|
+
] }) });
|
|
3951
3962
|
}
|
|
3952
3963
|
return /* @__PURE__ */ jsxRuntime.jsx(AssistantMessage, { message, isLast, onFileSelect });
|
|
3953
3964
|
});
|
|
@@ -3974,487 +3985,159 @@ function AssistantMessage({
|
|
|
3974
3985
|
] }) });
|
|
3975
3986
|
}
|
|
3976
3987
|
|
|
3977
|
-
// src/components/ui/
|
|
3988
|
+
// src/components/ui/command.tsx
|
|
3978
3989
|
init_utils();
|
|
3979
|
-
|
|
3990
|
+
|
|
3991
|
+
// src/components/ui/input-group.tsx
|
|
3992
|
+
init_utils();
|
|
3993
|
+
function InputGroup({ className, ...props }) {
|
|
3994
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3995
|
+
"div",
|
|
3996
|
+
{
|
|
3997
|
+
"data-slot": "input-group",
|
|
3998
|
+
role: "group",
|
|
3999
|
+
className: cn(
|
|
4000
|
+
"group/input-group relative flex h-10 w-full min-w-0 items-center rounded-none border border-transparent border-b-input bg-transparent transition-[color,border-color] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-data-[align=block-end]:rounded-none has-data-[align=block-start]:rounded-none has-[[data-slot=input-group-control]:focus-visible]:border-b-ring has-[[data-slot][aria-invalid=true]]:border-b-destructive has-[textarea]:rounded-none has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:has-[[data-slot][aria-invalid=true]]:border-b-destructive/50 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3",
|
|
4001
|
+
className
|
|
4002
|
+
),
|
|
4003
|
+
...props
|
|
4004
|
+
}
|
|
4005
|
+
);
|
|
4006
|
+
}
|
|
4007
|
+
var inputGroupAddonVariants = classVarianceAuthority.cva(
|
|
4008
|
+
"flex h-auto cursor-text items-center justify-center gap-2 py-2 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 **:data-[slot=kbd]:rounded-none **:data-[slot=kbd]:bg-muted-foreground/10 **:data-[slot=kbd]:px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
|
|
4009
|
+
{
|
|
4010
|
+
variants: {
|
|
4011
|
+
align: {
|
|
4012
|
+
"inline-start": "order-first",
|
|
4013
|
+
"inline-end": "order-last",
|
|
4014
|
+
"block-start": "order-first w-full justify-start pt-3 group-has-[>input]/input-group:pt-3.5 [.border-b]:pb-3.5",
|
|
4015
|
+
"block-end": "order-last w-full justify-start pb-3 group-has-[>input]/input-group:pb-3.5 [.border-t]:pt-3.5"
|
|
4016
|
+
}
|
|
4017
|
+
},
|
|
4018
|
+
defaultVariants: {
|
|
4019
|
+
align: "inline-start"
|
|
4020
|
+
}
|
|
4021
|
+
}
|
|
4022
|
+
);
|
|
4023
|
+
function InputGroupAddon({
|
|
4024
|
+
className,
|
|
4025
|
+
align = "inline-start",
|
|
3980
4026
|
...props
|
|
3981
4027
|
}) {
|
|
3982
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4028
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4029
|
+
"div",
|
|
4030
|
+
{
|
|
4031
|
+
role: "group",
|
|
4032
|
+
"data-slot": "input-group-addon",
|
|
4033
|
+
"data-align": align,
|
|
4034
|
+
className: cn(inputGroupAddonVariants({ align }), className),
|
|
4035
|
+
onClick: (e) => {
|
|
4036
|
+
if (e.target.closest("button")) {
|
|
4037
|
+
return;
|
|
4038
|
+
}
|
|
4039
|
+
e.currentTarget.parentElement?.querySelector("input")?.focus();
|
|
4040
|
+
},
|
|
4041
|
+
...props
|
|
4042
|
+
}
|
|
4043
|
+
);
|
|
3983
4044
|
}
|
|
3984
|
-
|
|
4045
|
+
var inputGroupButtonVariants = classVarianceAuthority.cva(
|
|
4046
|
+
"flex items-center gap-2 rounded-none text-sm shadow-none",
|
|
4047
|
+
{
|
|
4048
|
+
variants: {
|
|
4049
|
+
size: {
|
|
4050
|
+
xs: "h-6 gap-1 rounded-none px-1.5 text-xs [&>svg:not([class*='size-'])]:size-3.5",
|
|
4051
|
+
sm: "",
|
|
4052
|
+
"icon-xs": "size-6 p-0 text-xs has-[>svg]:p-0",
|
|
4053
|
+
"icon-sm": "size-8 p-0 has-[>svg]:p-0"
|
|
4054
|
+
}
|
|
4055
|
+
},
|
|
4056
|
+
defaultVariants: {
|
|
4057
|
+
size: "xs"
|
|
4058
|
+
}
|
|
4059
|
+
}
|
|
4060
|
+
);
|
|
4061
|
+
function InputGroupButton({
|
|
4062
|
+
className,
|
|
4063
|
+
type = "button",
|
|
4064
|
+
variant = "ghost",
|
|
4065
|
+
size = "xs",
|
|
3985
4066
|
...props
|
|
3986
4067
|
}) {
|
|
3987
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4068
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4069
|
+
Button,
|
|
4070
|
+
{
|
|
4071
|
+
type,
|
|
4072
|
+
"data-size": size,
|
|
4073
|
+
variant,
|
|
4074
|
+
className: cn(inputGroupButtonVariants({ size }), className),
|
|
4075
|
+
...props
|
|
4076
|
+
}
|
|
4077
|
+
);
|
|
3988
4078
|
}
|
|
3989
|
-
function
|
|
4079
|
+
function InputGroupTextarea({
|
|
3990
4080
|
className,
|
|
3991
|
-
align = "center",
|
|
3992
|
-
sideOffset = 4,
|
|
3993
4081
|
...props
|
|
3994
4082
|
}) {
|
|
3995
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3996
|
-
|
|
4083
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4084
|
+
Textarea,
|
|
3997
4085
|
{
|
|
3998
|
-
"data-slot": "
|
|
3999
|
-
align,
|
|
4000
|
-
sideOffset,
|
|
4086
|
+
"data-slot": "input-group-control",
|
|
4001
4087
|
className: cn(
|
|
4002
|
-
"
|
|
4088
|
+
"flex-1 resize-none border-0 bg-transparent py-2.5 ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
|
|
4003
4089
|
className
|
|
4004
4090
|
),
|
|
4005
4091
|
...props
|
|
4006
4092
|
}
|
|
4007
|
-
)
|
|
4093
|
+
);
|
|
4008
4094
|
}
|
|
4009
|
-
|
|
4010
|
-
// src/components/ui/progress.tsx
|
|
4011
|
-
init_utils();
|
|
4012
|
-
function Progress({
|
|
4095
|
+
function Command({
|
|
4013
4096
|
className,
|
|
4014
|
-
value,
|
|
4015
4097
|
...props
|
|
4016
4098
|
}) {
|
|
4017
4099
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4018
|
-
|
|
4100
|
+
cmdk.Command,
|
|
4019
4101
|
{
|
|
4020
|
-
"data-slot": "
|
|
4102
|
+
"data-slot": "command",
|
|
4021
4103
|
className: cn(
|
|
4022
|
-
"
|
|
4104
|
+
"flex size-full flex-col overflow-hidden bg-popover text-popover-foreground",
|
|
4023
4105
|
className
|
|
4024
4106
|
),
|
|
4025
|
-
...props
|
|
4026
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4027
|
-
radixUi.Progress.Indicator,
|
|
4028
|
-
{
|
|
4029
|
-
"data-slot": "progress-indicator",
|
|
4030
|
-
className: "size-full flex-1 bg-primary transition-all",
|
|
4031
|
-
style: { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
4032
|
-
}
|
|
4033
|
-
)
|
|
4107
|
+
...props
|
|
4034
4108
|
}
|
|
4035
4109
|
);
|
|
4036
4110
|
}
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
init_utils();
|
|
4040
|
-
var PERCENT_MAX = 100;
|
|
4041
|
-
var ICON_RADIUS = 10;
|
|
4042
|
-
var ICON_VIEWBOX = 24;
|
|
4043
|
-
var ICON_CENTER = 12;
|
|
4044
|
-
var ICON_STROKE_WIDTH = 2;
|
|
4045
|
-
var ContextContext = react.createContext(null);
|
|
4046
|
-
var useContextValue = () => {
|
|
4047
|
-
const context = react.useContext(ContextContext);
|
|
4048
|
-
if (!context) {
|
|
4049
|
-
throw new Error("Context components must be used within Context");
|
|
4050
|
-
}
|
|
4051
|
-
return context;
|
|
4052
|
-
};
|
|
4053
|
-
var Context = ({
|
|
4054
|
-
usedTokens,
|
|
4055
|
-
maxTokens,
|
|
4056
|
-
usage,
|
|
4057
|
-
modelId,
|
|
4111
|
+
function CommandList({
|
|
4112
|
+
className,
|
|
4058
4113
|
...props
|
|
4059
|
-
})
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
[maxTokens, modelId, usage, usedTokens]
|
|
4063
|
-
);
|
|
4064
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ContextContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(HoverCard, { closeDelay: 0, openDelay: 0, ...props }) });
|
|
4065
|
-
};
|
|
4066
|
-
var ContextIcon = () => {
|
|
4067
|
-
const { usedTokens, maxTokens } = useContextValue();
|
|
4068
|
-
const circumference = 2 * Math.PI * ICON_RADIUS;
|
|
4069
|
-
const usedPercent = usedTokens / maxTokens;
|
|
4070
|
-
const dashOffset = circumference * (1 - usedPercent);
|
|
4071
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4072
|
-
"svg",
|
|
4114
|
+
}) {
|
|
4115
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4116
|
+
cmdk.Command.List,
|
|
4073
4117
|
{
|
|
4074
|
-
"
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
children: [
|
|
4081
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4082
|
-
"circle",
|
|
4083
|
-
{
|
|
4084
|
-
cx: ICON_CENTER,
|
|
4085
|
-
cy: ICON_CENTER,
|
|
4086
|
-
fill: "none",
|
|
4087
|
-
opacity: "0.25",
|
|
4088
|
-
r: ICON_RADIUS,
|
|
4089
|
-
stroke: "currentColor",
|
|
4090
|
-
strokeWidth: ICON_STROKE_WIDTH
|
|
4091
|
-
}
|
|
4092
|
-
),
|
|
4093
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4094
|
-
"circle",
|
|
4095
|
-
{
|
|
4096
|
-
cx: ICON_CENTER,
|
|
4097
|
-
cy: ICON_CENTER,
|
|
4098
|
-
fill: "none",
|
|
4099
|
-
opacity: "0.7",
|
|
4100
|
-
r: ICON_RADIUS,
|
|
4101
|
-
stroke: "currentColor",
|
|
4102
|
-
strokeDasharray: `${circumference} ${circumference}`,
|
|
4103
|
-
strokeDashoffset: dashOffset,
|
|
4104
|
-
strokeLinecap: "round",
|
|
4105
|
-
strokeWidth: ICON_STROKE_WIDTH,
|
|
4106
|
-
style: { transform: "rotate(-90deg)", transformOrigin: "center" }
|
|
4107
|
-
}
|
|
4108
|
-
)
|
|
4109
|
-
]
|
|
4118
|
+
"data-slot": "command-list",
|
|
4119
|
+
className: cn(
|
|
4120
|
+
"no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none",
|
|
4121
|
+
className
|
|
4122
|
+
),
|
|
4123
|
+
...props
|
|
4110
4124
|
}
|
|
4111
4125
|
);
|
|
4112
|
-
}
|
|
4113
|
-
|
|
4114
|
-
return /* @__PURE__ */ jsxRuntime.jsx(HoverCardTrigger, { asChild: true, children: children ?? /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", ...props, children: /* @__PURE__ */ jsxRuntime.jsx(ContextIcon, {}) }) });
|
|
4115
|
-
};
|
|
4116
|
-
var ContextContent = ({
|
|
4126
|
+
}
|
|
4127
|
+
function CommandEmpty({
|
|
4117
4128
|
className,
|
|
4118
4129
|
...props
|
|
4119
|
-
})
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
}) => {
|
|
4131
|
-
const { usedTokens, maxTokens } = useContextValue();
|
|
4132
|
-
const usedPercent = usedTokens / maxTokens;
|
|
4133
|
-
const displayPct = new Intl.NumberFormat("en-US", {
|
|
4134
|
-
maximumFractionDigits: 1,
|
|
4135
|
-
style: "percent"
|
|
4136
|
-
}).format(usedPercent);
|
|
4137
|
-
const used = new Intl.NumberFormat("en-US", {
|
|
4138
|
-
notation: "compact"
|
|
4139
|
-
}).format(usedTokens);
|
|
4140
|
-
const total = new Intl.NumberFormat("en-US", {
|
|
4141
|
-
notation: "compact"
|
|
4142
|
-
}).format(maxTokens);
|
|
4143
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full space-y-2 p-3", className), ...props, children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4144
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 text-xs", children: [
|
|
4145
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { children: displayPct }),
|
|
4146
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: " text-muted-foreground", children: [
|
|
4147
|
-
used,
|
|
4148
|
-
" / ",
|
|
4149
|
-
total
|
|
4150
|
-
] })
|
|
4151
|
-
] }),
|
|
4152
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: /* @__PURE__ */ jsxRuntime.jsx(Progress, { className: "bg-muted", value: usedPercent * PERCENT_MAX }) })
|
|
4153
|
-
] }) });
|
|
4154
|
-
};
|
|
4155
|
-
var ContextContentBody = ({
|
|
4156
|
-
children,
|
|
4157
|
-
className,
|
|
4158
|
-
...props
|
|
4159
|
-
}) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full p-3", className), ...props, children });
|
|
4160
|
-
var TokensWithCost = ({
|
|
4161
|
-
tokens,
|
|
4162
|
-
costText
|
|
4163
|
-
}) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4164
|
-
tokens === void 0 ? "\u2014" : new Intl.NumberFormat("en-US", {
|
|
4165
|
-
notation: "compact"
|
|
4166
|
-
}).format(tokens),
|
|
4167
|
-
costText ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 text-muted-foreground", children: [
|
|
4168
|
-
"\u2022 ",
|
|
4169
|
-
costText
|
|
4170
|
-
] }) : null
|
|
4171
|
-
] });
|
|
4172
|
-
var ContextInputUsage = ({
|
|
4173
|
-
className,
|
|
4174
|
-
children,
|
|
4175
|
-
...props
|
|
4176
|
-
}) => {
|
|
4177
|
-
const { usage, modelId } = useContextValue();
|
|
4178
|
-
const inputTokens = usage?.inputTokens ?? 0;
|
|
4179
|
-
if (children) {
|
|
4180
|
-
return children;
|
|
4181
|
-
}
|
|
4182
|
-
if (!inputTokens) {
|
|
4183
|
-
return null;
|
|
4184
|
-
}
|
|
4185
|
-
const inputCost = modelId ? tokenlens.getUsage({
|
|
4186
|
-
modelId,
|
|
4187
|
-
usage: { input: inputTokens, output: 0 }
|
|
4188
|
-
}).costUSD?.totalUSD : void 0;
|
|
4189
|
-
const inputCostText = new Intl.NumberFormat("en-US", {
|
|
4190
|
-
currency: "USD",
|
|
4191
|
-
style: "currency"
|
|
4192
|
-
}).format(inputCost ?? 0);
|
|
4193
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4194
|
-
"div",
|
|
4195
|
-
{
|
|
4196
|
-
className: cn("flex items-center justify-between text-xs", className),
|
|
4197
|
-
...props,
|
|
4198
|
-
children: [
|
|
4199
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Input" }),
|
|
4200
|
-
/* @__PURE__ */ jsxRuntime.jsx(TokensWithCost, { costText: inputCostText, tokens: inputTokens })
|
|
4201
|
-
]
|
|
4202
|
-
}
|
|
4203
|
-
);
|
|
4204
|
-
};
|
|
4205
|
-
var ContextOutputUsage = ({
|
|
4206
|
-
className,
|
|
4207
|
-
children,
|
|
4208
|
-
...props
|
|
4209
|
-
}) => {
|
|
4210
|
-
const { usage, modelId } = useContextValue();
|
|
4211
|
-
const outputTokens = usage?.outputTokens ?? 0;
|
|
4212
|
-
if (children) {
|
|
4213
|
-
return children;
|
|
4214
|
-
}
|
|
4215
|
-
if (!outputTokens) {
|
|
4216
|
-
return null;
|
|
4217
|
-
}
|
|
4218
|
-
const outputCost = modelId ? tokenlens.getUsage({
|
|
4219
|
-
modelId,
|
|
4220
|
-
usage: { input: 0, output: outputTokens }
|
|
4221
|
-
}).costUSD?.totalUSD : void 0;
|
|
4222
|
-
const outputCostText = new Intl.NumberFormat("en-US", {
|
|
4223
|
-
currency: "USD",
|
|
4224
|
-
style: "currency"
|
|
4225
|
-
}).format(outputCost ?? 0);
|
|
4226
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4227
|
-
"div",
|
|
4228
|
-
{
|
|
4229
|
-
className: cn("flex items-center justify-between text-xs", className),
|
|
4230
|
-
...props,
|
|
4231
|
-
children: [
|
|
4232
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Output" }),
|
|
4233
|
-
/* @__PURE__ */ jsxRuntime.jsx(TokensWithCost, { costText: outputCostText, tokens: outputTokens })
|
|
4234
|
-
]
|
|
4235
|
-
}
|
|
4236
|
-
);
|
|
4237
|
-
};
|
|
4238
|
-
var ContextReasoningUsage = ({
|
|
4239
|
-
className,
|
|
4240
|
-
children,
|
|
4241
|
-
...props
|
|
4242
|
-
}) => {
|
|
4243
|
-
const { usage, modelId } = useContextValue();
|
|
4244
|
-
const reasoningTokens = usage?.reasoningTokens ?? 0;
|
|
4245
|
-
if (children) {
|
|
4246
|
-
return children;
|
|
4247
|
-
}
|
|
4248
|
-
if (!reasoningTokens) {
|
|
4249
|
-
return null;
|
|
4250
|
-
}
|
|
4251
|
-
const reasoningCost = modelId ? tokenlens.getUsage({
|
|
4252
|
-
modelId,
|
|
4253
|
-
usage: { reasoningTokens }
|
|
4254
|
-
}).costUSD?.totalUSD : void 0;
|
|
4255
|
-
const reasoningCostText = new Intl.NumberFormat("en-US", {
|
|
4256
|
-
currency: "USD",
|
|
4257
|
-
style: "currency"
|
|
4258
|
-
}).format(reasoningCost ?? 0);
|
|
4259
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4260
|
-
"div",
|
|
4261
|
-
{
|
|
4262
|
-
className: cn("flex items-center justify-between text-xs", className),
|
|
4263
|
-
...props,
|
|
4264
|
-
children: [
|
|
4265
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Reasoning" }),
|
|
4266
|
-
/* @__PURE__ */ jsxRuntime.jsx(TokensWithCost, { costText: reasoningCostText, tokens: reasoningTokens })
|
|
4267
|
-
]
|
|
4268
|
-
}
|
|
4269
|
-
);
|
|
4270
|
-
};
|
|
4271
|
-
var ContextCacheUsage = ({
|
|
4272
|
-
className,
|
|
4273
|
-
children,
|
|
4274
|
-
...props
|
|
4275
|
-
}) => {
|
|
4276
|
-
const { usage, modelId } = useContextValue();
|
|
4277
|
-
const cacheTokens = usage?.cachedInputTokens ?? 0;
|
|
4278
|
-
if (children) {
|
|
4279
|
-
return children;
|
|
4280
|
-
}
|
|
4281
|
-
if (!cacheTokens) {
|
|
4282
|
-
return null;
|
|
4283
|
-
}
|
|
4284
|
-
const cacheCost = modelId ? tokenlens.getUsage({
|
|
4285
|
-
modelId,
|
|
4286
|
-
usage: { cacheReads: cacheTokens, input: 0, output: 0 }
|
|
4287
|
-
}).costUSD?.totalUSD : void 0;
|
|
4288
|
-
const cacheCostText = new Intl.NumberFormat("en-US", {
|
|
4289
|
-
currency: "USD",
|
|
4290
|
-
style: "currency"
|
|
4291
|
-
}).format(cacheCost ?? 0);
|
|
4292
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4293
|
-
"div",
|
|
4294
|
-
{
|
|
4295
|
-
className: cn("flex items-center justify-between text-xs", className),
|
|
4296
|
-
...props,
|
|
4297
|
-
children: [
|
|
4298
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Cache" }),
|
|
4299
|
-
/* @__PURE__ */ jsxRuntime.jsx(TokensWithCost, { costText: cacheCostText, tokens: cacheTokens })
|
|
4300
|
-
]
|
|
4301
|
-
}
|
|
4302
|
-
);
|
|
4303
|
-
};
|
|
4304
|
-
|
|
4305
|
-
// src/components/ui/command.tsx
|
|
4306
|
-
init_utils();
|
|
4307
|
-
|
|
4308
|
-
// src/components/ui/input-group.tsx
|
|
4309
|
-
init_utils();
|
|
4310
|
-
function InputGroup({ className, ...props }) {
|
|
4311
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4312
|
-
"div",
|
|
4313
|
-
{
|
|
4314
|
-
"data-slot": "input-group",
|
|
4315
|
-
role: "group",
|
|
4316
|
-
className: cn(
|
|
4317
|
-
"group/input-group relative flex h-10 w-full min-w-0 items-center rounded-none border border-transparent border-b-input bg-transparent transition-[color,border-color] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-data-[align=block-end]:rounded-none has-data-[align=block-start]:rounded-none has-[[data-slot=input-group-control]:focus-visible]:border-b-ring has-[[data-slot][aria-invalid=true]]:border-b-destructive has-[textarea]:rounded-none has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:has-[[data-slot][aria-invalid=true]]:border-b-destructive/50 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3",
|
|
4318
|
-
className
|
|
4319
|
-
),
|
|
4320
|
-
...props
|
|
4321
|
-
}
|
|
4322
|
-
);
|
|
4323
|
-
}
|
|
4324
|
-
var inputGroupAddonVariants = classVarianceAuthority.cva(
|
|
4325
|
-
"flex h-auto cursor-text items-center justify-center gap-2 py-2 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 **:data-[slot=kbd]:rounded-none **:data-[slot=kbd]:bg-muted-foreground/10 **:data-[slot=kbd]:px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
|
|
4326
|
-
{
|
|
4327
|
-
variants: {
|
|
4328
|
-
align: {
|
|
4329
|
-
"inline-start": "order-first",
|
|
4330
|
-
"inline-end": "order-last",
|
|
4331
|
-
"block-start": "order-first w-full justify-start pt-3 group-has-[>input]/input-group:pt-3.5 [.border-b]:pb-3.5",
|
|
4332
|
-
"block-end": "order-last w-full justify-start pb-3 group-has-[>input]/input-group:pb-3.5 [.border-t]:pt-3.5"
|
|
4333
|
-
}
|
|
4334
|
-
},
|
|
4335
|
-
defaultVariants: {
|
|
4336
|
-
align: "inline-start"
|
|
4337
|
-
}
|
|
4338
|
-
}
|
|
4339
|
-
);
|
|
4340
|
-
function InputGroupAddon({
|
|
4341
|
-
className,
|
|
4342
|
-
align = "inline-start",
|
|
4343
|
-
...props
|
|
4344
|
-
}) {
|
|
4345
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4346
|
-
"div",
|
|
4347
|
-
{
|
|
4348
|
-
role: "group",
|
|
4349
|
-
"data-slot": "input-group-addon",
|
|
4350
|
-
"data-align": align,
|
|
4351
|
-
className: cn(inputGroupAddonVariants({ align }), className),
|
|
4352
|
-
onClick: (e) => {
|
|
4353
|
-
if (e.target.closest("button")) {
|
|
4354
|
-
return;
|
|
4355
|
-
}
|
|
4356
|
-
e.currentTarget.parentElement?.querySelector("input")?.focus();
|
|
4357
|
-
},
|
|
4358
|
-
...props
|
|
4359
|
-
}
|
|
4360
|
-
);
|
|
4361
|
-
}
|
|
4362
|
-
var inputGroupButtonVariants = classVarianceAuthority.cva(
|
|
4363
|
-
"flex items-center gap-2 rounded-none text-sm shadow-none",
|
|
4364
|
-
{
|
|
4365
|
-
variants: {
|
|
4366
|
-
size: {
|
|
4367
|
-
xs: "h-6 gap-1 rounded-none px-1.5 text-xs [&>svg:not([class*='size-'])]:size-3.5",
|
|
4368
|
-
sm: "",
|
|
4369
|
-
"icon-xs": "size-6 p-0 text-xs has-[>svg]:p-0",
|
|
4370
|
-
"icon-sm": "size-8 p-0 has-[>svg]:p-0"
|
|
4371
|
-
}
|
|
4372
|
-
},
|
|
4373
|
-
defaultVariants: {
|
|
4374
|
-
size: "xs"
|
|
4375
|
-
}
|
|
4376
|
-
}
|
|
4377
|
-
);
|
|
4378
|
-
function InputGroupButton({
|
|
4379
|
-
className,
|
|
4380
|
-
type = "button",
|
|
4381
|
-
variant = "ghost",
|
|
4382
|
-
size = "xs",
|
|
4383
|
-
...props
|
|
4384
|
-
}) {
|
|
4385
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4386
|
-
Button,
|
|
4387
|
-
{
|
|
4388
|
-
type,
|
|
4389
|
-
"data-size": size,
|
|
4390
|
-
variant,
|
|
4391
|
-
className: cn(inputGroupButtonVariants({ size }), className),
|
|
4392
|
-
...props
|
|
4393
|
-
}
|
|
4394
|
-
);
|
|
4395
|
-
}
|
|
4396
|
-
function InputGroupTextarea({
|
|
4397
|
-
className,
|
|
4398
|
-
...props
|
|
4399
|
-
}) {
|
|
4400
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4401
|
-
Textarea,
|
|
4402
|
-
{
|
|
4403
|
-
"data-slot": "input-group-control",
|
|
4404
|
-
className: cn(
|
|
4405
|
-
"flex-1 resize-none border-0 bg-transparent py-2.5 ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
|
|
4406
|
-
className
|
|
4407
|
-
),
|
|
4408
|
-
...props
|
|
4409
|
-
}
|
|
4410
|
-
);
|
|
4411
|
-
}
|
|
4412
|
-
function Command({
|
|
4413
|
-
className,
|
|
4414
|
-
...props
|
|
4415
|
-
}) {
|
|
4416
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4417
|
-
cmdk.Command,
|
|
4418
|
-
{
|
|
4419
|
-
"data-slot": "command",
|
|
4420
|
-
className: cn(
|
|
4421
|
-
"flex size-full flex-col overflow-hidden bg-popover text-popover-foreground",
|
|
4422
|
-
className
|
|
4423
|
-
),
|
|
4424
|
-
...props
|
|
4425
|
-
}
|
|
4426
|
-
);
|
|
4427
|
-
}
|
|
4428
|
-
function CommandList({
|
|
4429
|
-
className,
|
|
4430
|
-
...props
|
|
4431
|
-
}) {
|
|
4432
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4433
|
-
cmdk.Command.List,
|
|
4434
|
-
{
|
|
4435
|
-
"data-slot": "command-list",
|
|
4436
|
-
className: cn(
|
|
4437
|
-
"no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none",
|
|
4438
|
-
className
|
|
4439
|
-
),
|
|
4440
|
-
...props
|
|
4441
|
-
}
|
|
4442
|
-
);
|
|
4443
|
-
}
|
|
4444
|
-
function CommandEmpty({
|
|
4445
|
-
className,
|
|
4446
|
-
...props
|
|
4447
|
-
}) {
|
|
4448
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4449
|
-
cmdk.Command.Empty,
|
|
4450
|
-
{
|
|
4451
|
-
"data-slot": "command-empty",
|
|
4452
|
-
className: cn("py-6 text-center text-sm", className),
|
|
4453
|
-
...props
|
|
4454
|
-
}
|
|
4455
|
-
);
|
|
4456
|
-
}
|
|
4457
|
-
function CommandGroup({
|
|
4130
|
+
}) {
|
|
4131
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4132
|
+
cmdk.Command.Empty,
|
|
4133
|
+
{
|
|
4134
|
+
"data-slot": "command-empty",
|
|
4135
|
+
className: cn("py-6 text-center text-sm", className),
|
|
4136
|
+
...props
|
|
4137
|
+
}
|
|
4138
|
+
);
|
|
4139
|
+
}
|
|
4140
|
+
function CommandGroup({
|
|
4458
4141
|
className,
|
|
4459
4142
|
...props
|
|
4460
4143
|
}) {
|
|
@@ -4548,6 +4231,39 @@ function DropdownMenuItem({
|
|
|
4548
4231
|
);
|
|
4549
4232
|
}
|
|
4550
4233
|
|
|
4234
|
+
// src/components/ui/hover-card.tsx
|
|
4235
|
+
init_utils();
|
|
4236
|
+
function HoverCard({
|
|
4237
|
+
...props
|
|
4238
|
+
}) {
|
|
4239
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.HoverCard.Root, { "data-slot": "hover-card", ...props });
|
|
4240
|
+
}
|
|
4241
|
+
function HoverCardTrigger({
|
|
4242
|
+
...props
|
|
4243
|
+
}) {
|
|
4244
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.HoverCard.Trigger, { "data-slot": "hover-card-trigger", ...props });
|
|
4245
|
+
}
|
|
4246
|
+
function HoverCardContent({
|
|
4247
|
+
className,
|
|
4248
|
+
align = "center",
|
|
4249
|
+
sideOffset = 4,
|
|
4250
|
+
...props
|
|
4251
|
+
}) {
|
|
4252
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.HoverCard.Portal, { "data-slot": "hover-card-portal", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4253
|
+
radixUi.HoverCard.Content,
|
|
4254
|
+
{
|
|
4255
|
+
"data-slot": "hover-card-content",
|
|
4256
|
+
align,
|
|
4257
|
+
sideOffset,
|
|
4258
|
+
className: cn(
|
|
4259
|
+
"z-50 w-72 origin-(--radix-hover-card-content-transform-origin) bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 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-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
4260
|
+
className
|
|
4261
|
+
),
|
|
4262
|
+
...props
|
|
4263
|
+
}
|
|
4264
|
+
) });
|
|
4265
|
+
}
|
|
4266
|
+
|
|
4551
4267
|
// src/components/ui/spinner.tsx
|
|
4552
4268
|
init_utils();
|
|
4553
4269
|
function Spinner({ className, ...props }) {
|
|
@@ -4586,6 +4302,15 @@ var usePromptInputController = () => {
|
|
|
4586
4302
|
return ctx;
|
|
4587
4303
|
};
|
|
4588
4304
|
var useOptionalPromptInputController = () => react.useContext(PromptInputController);
|
|
4305
|
+
var useProviderAttachments = () => {
|
|
4306
|
+
const ctx = react.useContext(ProviderAttachmentsContext);
|
|
4307
|
+
if (!ctx) {
|
|
4308
|
+
throw new Error(
|
|
4309
|
+
"Wrap your component inside <PromptInputProvider> to use useProviderAttachments()."
|
|
4310
|
+
);
|
|
4311
|
+
}
|
|
4312
|
+
return ctx;
|
|
4313
|
+
};
|
|
4589
4314
|
var useOptionalProviderAttachments = () => react.useContext(ProviderAttachmentsContext);
|
|
4590
4315
|
var PromptInputProvider = ({
|
|
4591
4316
|
initialInput: initialTextInput = "",
|
|
@@ -5146,110 +4871,405 @@ var PromptInputTextarea = ({
|
|
|
5146
4871
|
}
|
|
5147
4872
|
);
|
|
5148
4873
|
};
|
|
5149
|
-
var PromptInputFooter = ({
|
|
4874
|
+
var PromptInputFooter = ({
|
|
4875
|
+
className,
|
|
4876
|
+
...props
|
|
4877
|
+
}) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4878
|
+
InputGroupAddon,
|
|
4879
|
+
{
|
|
4880
|
+
align: "block-end",
|
|
4881
|
+
className: cn("justify-between gap-1", className),
|
|
4882
|
+
...props
|
|
4883
|
+
}
|
|
4884
|
+
);
|
|
4885
|
+
var PromptInputTools = ({
|
|
4886
|
+
className,
|
|
4887
|
+
...props
|
|
4888
|
+
}) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4889
|
+
"div",
|
|
4890
|
+
{
|
|
4891
|
+
className: cn("flex min-w-0 items-center gap-1", className),
|
|
4892
|
+
...props
|
|
4893
|
+
}
|
|
4894
|
+
);
|
|
4895
|
+
var PromptInputButton = ({
|
|
4896
|
+
variant = "ghost",
|
|
4897
|
+
className,
|
|
4898
|
+
size,
|
|
4899
|
+
tooltip,
|
|
4900
|
+
...props
|
|
4901
|
+
}) => {
|
|
4902
|
+
const newSize = size ?? (react.Children.count(props.children) > 1 ? "sm" : "icon-sm");
|
|
4903
|
+
const button = /* @__PURE__ */ jsxRuntime.jsx(
|
|
4904
|
+
InputGroupButton,
|
|
4905
|
+
{
|
|
4906
|
+
className: cn(className),
|
|
4907
|
+
size: newSize,
|
|
4908
|
+
type: "button",
|
|
4909
|
+
variant,
|
|
4910
|
+
...props
|
|
4911
|
+
}
|
|
4912
|
+
);
|
|
4913
|
+
if (!tooltip) {
|
|
4914
|
+
return button;
|
|
4915
|
+
}
|
|
4916
|
+
const tooltipContent = typeof tooltip === "string" ? tooltip : tooltip.content;
|
|
4917
|
+
const shortcut = typeof tooltip === "string" ? void 0 : tooltip.shortcut;
|
|
4918
|
+
const side = typeof tooltip === "string" ? "top" : tooltip.side ?? "top";
|
|
4919
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
4920
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: button }),
|
|
4921
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TooltipContent, { side, children: [
|
|
4922
|
+
tooltipContent,
|
|
4923
|
+
shortcut && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 text-muted-foreground", children: shortcut })
|
|
4924
|
+
] })
|
|
4925
|
+
] });
|
|
4926
|
+
};
|
|
4927
|
+
var PromptInputActionMenu = (props) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu, { ...props });
|
|
4928
|
+
var PromptInputActionMenuTrigger = ({
|
|
4929
|
+
className,
|
|
4930
|
+
children,
|
|
4931
|
+
...props
|
|
4932
|
+
}) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(PromptInputButton, { className, ...props, children: children ?? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PlusIcon, { className: "size-4" }) }) });
|
|
4933
|
+
var PromptInputActionMenuContent = ({
|
|
4934
|
+
className,
|
|
4935
|
+
...props
|
|
4936
|
+
}) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "start", className: cn(className), ...props });
|
|
4937
|
+
var PromptInputSubmit = ({
|
|
4938
|
+
className,
|
|
4939
|
+
variant = "default",
|
|
4940
|
+
size = "icon-sm",
|
|
4941
|
+
status,
|
|
4942
|
+
onStop,
|
|
4943
|
+
onClick,
|
|
4944
|
+
children,
|
|
4945
|
+
...props
|
|
4946
|
+
}) => {
|
|
4947
|
+
const isGenerating = status === "submitted" || status === "streaming";
|
|
4948
|
+
let Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownLeftIcon, { className: "size-4" });
|
|
4949
|
+
if (status === "submitted") {
|
|
4950
|
+
Icon = /* @__PURE__ */ jsxRuntime.jsx(Spinner, {});
|
|
4951
|
+
} else if (status === "streaming") {
|
|
4952
|
+
Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SquareIcon, { className: "size-4" });
|
|
4953
|
+
} else if (status === "error") {
|
|
4954
|
+
Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-4" });
|
|
4955
|
+
}
|
|
4956
|
+
const handleClick = react.useCallback(
|
|
4957
|
+
(e) => {
|
|
4958
|
+
if (isGenerating && onStop) {
|
|
4959
|
+
e.preventDefault();
|
|
4960
|
+
onStop();
|
|
4961
|
+
return;
|
|
4962
|
+
}
|
|
4963
|
+
onClick?.(e);
|
|
4964
|
+
},
|
|
4965
|
+
[isGenerating, onStop, onClick]
|
|
4966
|
+
);
|
|
4967
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4968
|
+
InputGroupButton,
|
|
4969
|
+
{
|
|
4970
|
+
"aria-label": isGenerating ? "Stop" : "Submit",
|
|
4971
|
+
className: cn(className),
|
|
4972
|
+
onClick: handleClick,
|
|
4973
|
+
size,
|
|
4974
|
+
type: isGenerating && onStop ? "button" : "submit",
|
|
4975
|
+
variant,
|
|
4976
|
+
...props,
|
|
4977
|
+
children: children ?? Icon
|
|
4978
|
+
}
|
|
4979
|
+
);
|
|
4980
|
+
};
|
|
4981
|
+
|
|
4982
|
+
// src/components/ui/progress.tsx
|
|
4983
|
+
init_utils();
|
|
4984
|
+
function Progress({
|
|
4985
|
+
className,
|
|
4986
|
+
value,
|
|
4987
|
+
...props
|
|
4988
|
+
}) {
|
|
4989
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4990
|
+
radixUi.Progress.Root,
|
|
4991
|
+
{
|
|
4992
|
+
"data-slot": "progress",
|
|
4993
|
+
className: cn(
|
|
4994
|
+
"relative flex h-0.5 w-full items-center overflow-x-hidden rounded-none bg-muted",
|
|
4995
|
+
className
|
|
4996
|
+
),
|
|
4997
|
+
...props,
|
|
4998
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4999
|
+
radixUi.Progress.Indicator,
|
|
5000
|
+
{
|
|
5001
|
+
"data-slot": "progress-indicator",
|
|
5002
|
+
className: "size-full flex-1 bg-primary transition-all",
|
|
5003
|
+
style: { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
5004
|
+
}
|
|
5005
|
+
)
|
|
5006
|
+
}
|
|
5007
|
+
);
|
|
5008
|
+
}
|
|
5009
|
+
|
|
5010
|
+
// src/components/ai-elements/context.tsx
|
|
5011
|
+
init_utils();
|
|
5012
|
+
var PERCENT_MAX = 100;
|
|
5013
|
+
var ICON_RADIUS = 10;
|
|
5014
|
+
var ICON_VIEWBOX = 24;
|
|
5015
|
+
var ICON_CENTER = 12;
|
|
5016
|
+
var ICON_STROKE_WIDTH = 2;
|
|
5017
|
+
var ContextContext = react.createContext(null);
|
|
5018
|
+
var useContextValue = () => {
|
|
5019
|
+
const context = react.useContext(ContextContext);
|
|
5020
|
+
if (!context) {
|
|
5021
|
+
throw new Error("Context components must be used within Context");
|
|
5022
|
+
}
|
|
5023
|
+
return context;
|
|
5024
|
+
};
|
|
5025
|
+
var Context = ({
|
|
5026
|
+
usedTokens,
|
|
5027
|
+
maxTokens,
|
|
5028
|
+
usage,
|
|
5029
|
+
modelId,
|
|
5030
|
+
...props
|
|
5031
|
+
}) => {
|
|
5032
|
+
const contextValue = react.useMemo(
|
|
5033
|
+
() => ({ maxTokens, modelId, usage, usedTokens }),
|
|
5034
|
+
[maxTokens, modelId, usage, usedTokens]
|
|
5035
|
+
);
|
|
5036
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ContextContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(HoverCard, { closeDelay: 0, openDelay: 0, ...props }) });
|
|
5037
|
+
};
|
|
5038
|
+
var ContextIcon = () => {
|
|
5039
|
+
const { usedTokens, maxTokens } = useContextValue();
|
|
5040
|
+
const circumference = 2 * Math.PI * ICON_RADIUS;
|
|
5041
|
+
const usedPercent = usedTokens / maxTokens;
|
|
5042
|
+
const dashOffset = circumference * (1 - usedPercent);
|
|
5043
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5044
|
+
"svg",
|
|
5045
|
+
{
|
|
5046
|
+
"aria-label": "Model context usage",
|
|
5047
|
+
height: "20",
|
|
5048
|
+
role: "img",
|
|
5049
|
+
style: { color: "currentcolor" },
|
|
5050
|
+
viewBox: `0 0 ${ICON_VIEWBOX} ${ICON_VIEWBOX}`,
|
|
5051
|
+
width: "20",
|
|
5052
|
+
children: [
|
|
5053
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5054
|
+
"circle",
|
|
5055
|
+
{
|
|
5056
|
+
cx: ICON_CENTER,
|
|
5057
|
+
cy: ICON_CENTER,
|
|
5058
|
+
fill: "none",
|
|
5059
|
+
opacity: "0.25",
|
|
5060
|
+
r: ICON_RADIUS,
|
|
5061
|
+
stroke: "currentColor",
|
|
5062
|
+
strokeWidth: ICON_STROKE_WIDTH
|
|
5063
|
+
}
|
|
5064
|
+
),
|
|
5065
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5066
|
+
"circle",
|
|
5067
|
+
{
|
|
5068
|
+
cx: ICON_CENTER,
|
|
5069
|
+
cy: ICON_CENTER,
|
|
5070
|
+
fill: "none",
|
|
5071
|
+
opacity: "0.7",
|
|
5072
|
+
r: ICON_RADIUS,
|
|
5073
|
+
stroke: "currentColor",
|
|
5074
|
+
strokeDasharray: `${circumference} ${circumference}`,
|
|
5075
|
+
strokeDashoffset: dashOffset,
|
|
5076
|
+
strokeLinecap: "round",
|
|
5077
|
+
strokeWidth: ICON_STROKE_WIDTH,
|
|
5078
|
+
style: { transform: "rotate(-90deg)", transformOrigin: "center" }
|
|
5079
|
+
}
|
|
5080
|
+
)
|
|
5081
|
+
]
|
|
5082
|
+
}
|
|
5083
|
+
);
|
|
5084
|
+
};
|
|
5085
|
+
var ContextTrigger = ({ children, ...props }) => {
|
|
5086
|
+
return /* @__PURE__ */ jsxRuntime.jsx(HoverCardTrigger, { asChild: true, children: children ?? /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", ...props, children: /* @__PURE__ */ jsxRuntime.jsx(ContextIcon, {}) }) });
|
|
5087
|
+
};
|
|
5088
|
+
var ContextContent = ({
|
|
5089
|
+
className,
|
|
5090
|
+
...props
|
|
5091
|
+
}) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5092
|
+
HoverCardContent,
|
|
5093
|
+
{
|
|
5094
|
+
className: cn("min-w-60 divide-y overflow-hidden p-0", className),
|
|
5095
|
+
...props
|
|
5096
|
+
}
|
|
5097
|
+
);
|
|
5098
|
+
var ContextContentHeader = ({
|
|
5099
|
+
children,
|
|
5100
|
+
className,
|
|
5101
|
+
...props
|
|
5102
|
+
}) => {
|
|
5103
|
+
const { usedTokens, maxTokens } = useContextValue();
|
|
5104
|
+
const usedPercent = usedTokens / maxTokens;
|
|
5105
|
+
const displayPct = new Intl.NumberFormat("en-US", {
|
|
5106
|
+
maximumFractionDigits: 1,
|
|
5107
|
+
style: "percent"
|
|
5108
|
+
}).format(usedPercent);
|
|
5109
|
+
const used = new Intl.NumberFormat("en-US", {
|
|
5110
|
+
notation: "compact"
|
|
5111
|
+
}).format(usedTokens);
|
|
5112
|
+
const total = new Intl.NumberFormat("en-US", {
|
|
5113
|
+
notation: "compact"
|
|
5114
|
+
}).format(maxTokens);
|
|
5115
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full space-y-2 p-3", className), ...props, children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5116
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 text-xs", children: [
|
|
5117
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: displayPct }),
|
|
5118
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: " text-muted-foreground", children: [
|
|
5119
|
+
used,
|
|
5120
|
+
" / ",
|
|
5121
|
+
total
|
|
5122
|
+
] })
|
|
5123
|
+
] }),
|
|
5124
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: /* @__PURE__ */ jsxRuntime.jsx(Progress, { className: "bg-muted", value: usedPercent * PERCENT_MAX }) })
|
|
5125
|
+
] }) });
|
|
5126
|
+
};
|
|
5127
|
+
var ContextContentBody = ({
|
|
5128
|
+
children,
|
|
5150
5129
|
className,
|
|
5151
5130
|
...props
|
|
5152
|
-
}) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
)
|
|
5160
|
-
|
|
5131
|
+
}) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full p-3", className), ...props, children });
|
|
5132
|
+
var TokensWithCost = ({
|
|
5133
|
+
tokens,
|
|
5134
|
+
costText
|
|
5135
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5136
|
+
tokens === void 0 ? "\u2014" : new Intl.NumberFormat("en-US", {
|
|
5137
|
+
notation: "compact"
|
|
5138
|
+
}).format(tokens),
|
|
5139
|
+
costText ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 text-muted-foreground", children: [
|
|
5140
|
+
"\u2022 ",
|
|
5141
|
+
costText
|
|
5142
|
+
] }) : null
|
|
5143
|
+
] });
|
|
5144
|
+
var ContextInputUsage = ({
|
|
5161
5145
|
className,
|
|
5146
|
+
children,
|
|
5162
5147
|
...props
|
|
5163
|
-
}) =>
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5148
|
+
}) => {
|
|
5149
|
+
const { usage, modelId } = useContextValue();
|
|
5150
|
+
const inputTokens = usage?.inputTokens ?? 0;
|
|
5151
|
+
if (children) {
|
|
5152
|
+
return children;
|
|
5168
5153
|
}
|
|
5169
|
-
)
|
|
5170
|
-
|
|
5171
|
-
|
|
5154
|
+
if (!inputTokens) {
|
|
5155
|
+
return null;
|
|
5156
|
+
}
|
|
5157
|
+
const inputCost = modelId ? tokenlens.getUsage({
|
|
5158
|
+
modelId,
|
|
5159
|
+
usage: { input: inputTokens, output: 0 }
|
|
5160
|
+
}).costUSD?.totalUSD : void 0;
|
|
5161
|
+
const inputCostText = new Intl.NumberFormat("en-US", {
|
|
5162
|
+
currency: "USD",
|
|
5163
|
+
style: "currency"
|
|
5164
|
+
}).format(inputCost ?? 0);
|
|
5165
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5166
|
+
"div",
|
|
5167
|
+
{
|
|
5168
|
+
className: cn("flex items-center justify-between text-xs", className),
|
|
5169
|
+
...props,
|
|
5170
|
+
children: [
|
|
5171
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Input" }),
|
|
5172
|
+
/* @__PURE__ */ jsxRuntime.jsx(TokensWithCost, { costText: inputCostText, tokens: inputTokens })
|
|
5173
|
+
]
|
|
5174
|
+
}
|
|
5175
|
+
);
|
|
5176
|
+
};
|
|
5177
|
+
var ContextOutputUsage = ({
|
|
5172
5178
|
className,
|
|
5173
|
-
|
|
5174
|
-
tooltip,
|
|
5179
|
+
children,
|
|
5175
5180
|
...props
|
|
5176
5181
|
}) => {
|
|
5177
|
-
const
|
|
5178
|
-
const
|
|
5179
|
-
|
|
5182
|
+
const { usage, modelId } = useContextValue();
|
|
5183
|
+
const outputTokens = usage?.outputTokens ?? 0;
|
|
5184
|
+
if (children) {
|
|
5185
|
+
return children;
|
|
5186
|
+
}
|
|
5187
|
+
if (!outputTokens) {
|
|
5188
|
+
return null;
|
|
5189
|
+
}
|
|
5190
|
+
const outputCost = modelId ? tokenlens.getUsage({
|
|
5191
|
+
modelId,
|
|
5192
|
+
usage: { input: 0, output: outputTokens }
|
|
5193
|
+
}).costUSD?.totalUSD : void 0;
|
|
5194
|
+
const outputCostText = new Intl.NumberFormat("en-US", {
|
|
5195
|
+
currency: "USD",
|
|
5196
|
+
style: "currency"
|
|
5197
|
+
}).format(outputCost ?? 0);
|
|
5198
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5199
|
+
"div",
|
|
5180
5200
|
{
|
|
5181
|
-
className: cn(className),
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5201
|
+
className: cn("flex items-center justify-between text-xs", className),
|
|
5202
|
+
...props,
|
|
5203
|
+
children: [
|
|
5204
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Output" }),
|
|
5205
|
+
/* @__PURE__ */ jsxRuntime.jsx(TokensWithCost, { costText: outputCostText, tokens: outputTokens })
|
|
5206
|
+
]
|
|
5186
5207
|
}
|
|
5187
5208
|
);
|
|
5188
|
-
if (!tooltip) {
|
|
5189
|
-
return button;
|
|
5190
|
-
}
|
|
5191
|
-
const tooltipContent = typeof tooltip === "string" ? tooltip : tooltip.content;
|
|
5192
|
-
const shortcut = typeof tooltip === "string" ? void 0 : tooltip.shortcut;
|
|
5193
|
-
const side = typeof tooltip === "string" ? "top" : tooltip.side ?? "top";
|
|
5194
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
5195
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: button }),
|
|
5196
|
-
/* @__PURE__ */ jsxRuntime.jsxs(TooltipContent, { side, children: [
|
|
5197
|
-
tooltipContent,
|
|
5198
|
-
shortcut && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 text-muted-foreground", children: shortcut })
|
|
5199
|
-
] })
|
|
5200
|
-
] });
|
|
5201
5209
|
};
|
|
5202
|
-
var
|
|
5203
|
-
var PromptInputActionMenuTrigger = ({
|
|
5210
|
+
var ContextReasoningUsage = ({
|
|
5204
5211
|
className,
|
|
5205
5212
|
children,
|
|
5206
5213
|
...props
|
|
5207
|
-
}) =>
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5214
|
+
}) => {
|
|
5215
|
+
const { usage, modelId } = useContextValue();
|
|
5216
|
+
const reasoningTokens = usage?.reasoningTokens ?? 0;
|
|
5217
|
+
if (children) {
|
|
5218
|
+
return children;
|
|
5219
|
+
}
|
|
5220
|
+
if (!reasoningTokens) {
|
|
5221
|
+
return null;
|
|
5222
|
+
}
|
|
5223
|
+
const reasoningCost = modelId ? tokenlens.getUsage({
|
|
5224
|
+
modelId,
|
|
5225
|
+
usage: { reasoningTokens }
|
|
5226
|
+
}).costUSD?.totalUSD : void 0;
|
|
5227
|
+
const reasoningCostText = new Intl.NumberFormat("en-US", {
|
|
5228
|
+
currency: "USD",
|
|
5229
|
+
style: "currency"
|
|
5230
|
+
}).format(reasoningCost ?? 0);
|
|
5231
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5232
|
+
"div",
|
|
5233
|
+
{
|
|
5234
|
+
className: cn("flex items-center justify-between text-xs", className),
|
|
5235
|
+
...props,
|
|
5236
|
+
children: [
|
|
5237
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Reasoning" }),
|
|
5238
|
+
/* @__PURE__ */ jsxRuntime.jsx(TokensWithCost, { costText: reasoningCostText, tokens: reasoningTokens })
|
|
5239
|
+
]
|
|
5240
|
+
}
|
|
5241
|
+
);
|
|
5242
|
+
};
|
|
5243
|
+
var ContextCacheUsage = ({
|
|
5213
5244
|
className,
|
|
5214
|
-
variant = "default",
|
|
5215
|
-
size = "icon-sm",
|
|
5216
|
-
status,
|
|
5217
|
-
onStop,
|
|
5218
|
-
onClick,
|
|
5219
5245
|
children,
|
|
5220
5246
|
...props
|
|
5221
5247
|
}) => {
|
|
5222
|
-
const
|
|
5223
|
-
|
|
5224
|
-
if (
|
|
5225
|
-
|
|
5226
|
-
} else if (status === "streaming") {
|
|
5227
|
-
Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SquareIcon, { className: "size-4" });
|
|
5228
|
-
} else if (status === "error") {
|
|
5229
|
-
Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-4" });
|
|
5248
|
+
const { usage, modelId } = useContextValue();
|
|
5249
|
+
const cacheTokens = usage?.cachedInputTokens ?? 0;
|
|
5250
|
+
if (children) {
|
|
5251
|
+
return children;
|
|
5230
5252
|
}
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
);
|
|
5242
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
5243
|
-
|
|
5253
|
+
if (!cacheTokens) {
|
|
5254
|
+
return null;
|
|
5255
|
+
}
|
|
5256
|
+
const cacheCost = modelId ? tokenlens.getUsage({
|
|
5257
|
+
modelId,
|
|
5258
|
+
usage: { cacheReads: cacheTokens, input: 0, output: 0 }
|
|
5259
|
+
}).costUSD?.totalUSD : void 0;
|
|
5260
|
+
const cacheCostText = new Intl.NumberFormat("en-US", {
|
|
5261
|
+
currency: "USD",
|
|
5262
|
+
style: "currency"
|
|
5263
|
+
}).format(cacheCost ?? 0);
|
|
5264
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5265
|
+
"div",
|
|
5244
5266
|
{
|
|
5245
|
-
|
|
5246
|
-
className: cn(className),
|
|
5247
|
-
onClick: handleClick,
|
|
5248
|
-
size,
|
|
5249
|
-
type: isGenerating && onStop ? "button" : "submit",
|
|
5250
|
-
variant,
|
|
5267
|
+
className: cn("flex items-center justify-between text-xs", className),
|
|
5251
5268
|
...props,
|
|
5252
|
-
children:
|
|
5269
|
+
children: [
|
|
5270
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Cache" }),
|
|
5271
|
+
/* @__PURE__ */ jsxRuntime.jsx(TokensWithCost, { costText: cacheCostText, tokens: cacheTokens })
|
|
5272
|
+
]
|
|
5253
5273
|
}
|
|
5254
5274
|
);
|
|
5255
5275
|
};
|
|
@@ -5289,6 +5309,29 @@ function PopoverAnchor({
|
|
|
5289
5309
|
function ChatComposer(props) {
|
|
5290
5310
|
return /* @__PURE__ */ jsxRuntime.jsx(PromptInputProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ChatComposerInner, { ...props }) });
|
|
5291
5311
|
}
|
|
5312
|
+
function AttachmentPreviewStrip() {
|
|
5313
|
+
const attachments = useProviderAttachments();
|
|
5314
|
+
if (attachments.files.length === 0) return null;
|
|
5315
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2 px-3 pt-2 pb-1 flex-wrap", children: attachments.files.map((file) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group", children: [
|
|
5316
|
+
file.mediaType?.startsWith("image/") && file.url ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5317
|
+
"img",
|
|
5318
|
+
{
|
|
5319
|
+
src: file.url,
|
|
5320
|
+
alt: file.filename,
|
|
5321
|
+
className: "h-16 w-16 rounded-lg border border-border object-cover"
|
|
5322
|
+
}
|
|
5323
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-16 w-16 rounded-lg border border-border bg-muted flex items-center justify-center text-[10px] text-muted-foreground truncate px-1", children: file.filename }),
|
|
5324
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5325
|
+
"button",
|
|
5326
|
+
{
|
|
5327
|
+
type: "button",
|
|
5328
|
+
onClick: () => attachments.remove(file.id),
|
|
5329
|
+
className: "absolute -top-1.5 -right-1.5 hidden group-hover:flex items-center justify-center w-4 h-4 rounded-full bg-destructive text-destructive-foreground text-[10px]",
|
|
5330
|
+
children: "\xD7"
|
|
5331
|
+
}
|
|
5332
|
+
)
|
|
5333
|
+
] }, file.id)) });
|
|
5334
|
+
}
|
|
5292
5335
|
function ChatComposerInner({
|
|
5293
5336
|
onSend,
|
|
5294
5337
|
onStop,
|
|
@@ -5381,7 +5424,13 @@ function ChatComposerInner({
|
|
|
5381
5424
|
(message) => {
|
|
5382
5425
|
const text = message.text.trim();
|
|
5383
5426
|
if (!text || isRunning || disabled) return;
|
|
5384
|
-
|
|
5427
|
+
const images = [];
|
|
5428
|
+
for (const file of message.files) {
|
|
5429
|
+
if (file.mediaType?.startsWith("image/") && file.url) {
|
|
5430
|
+
images.push({ data: file.url, mimeType: file.mediaType });
|
|
5431
|
+
}
|
|
5432
|
+
}
|
|
5433
|
+
onSend(text, images.length > 0 ? images : void 0);
|
|
5385
5434
|
},
|
|
5386
5435
|
[onSend, isRunning, disabled]
|
|
5387
5436
|
);
|
|
@@ -5390,7 +5439,8 @@ function ChatComposerInner({
|
|
|
5390
5439
|
setButtonMenuOpen(false);
|
|
5391
5440
|
}
|
|
5392
5441
|
}, children: [
|
|
5393
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5442
|
+
/* @__PURE__ */ jsxRuntime.jsx(AttachmentPreviewStrip, {}),
|
|
5443
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(PromptInput, { onSubmit: handleSubmit, accept: "image/*", multiple: true, children: [
|
|
5394
5444
|
/* @__PURE__ */ jsxRuntime.jsx(PromptInputBody, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5395
5445
|
PromptInputTextarea,
|
|
5396
5446
|
{
|
|
@@ -6234,14 +6284,17 @@ function TimelineEntryItem({
|
|
|
6234
6284
|
] });
|
|
6235
6285
|
}
|
|
6236
6286
|
if (entry.kind === "tool") {
|
|
6237
|
-
const
|
|
6287
|
+
const rawStatus = effectiveStatus(entry.tc);
|
|
6288
|
+
const hideArtifactFailure = rawStatus === "error" && entry.tc.toolName === "create_artifact";
|
|
6289
|
+
const indicatorStatus = hideArtifactFailure ? "running" : rawStatus;
|
|
6290
|
+
const failureSummary = rawStatus === "error" && !hideArtifactFailure ? toolErrorSummary(entry.tc.result) : "";
|
|
6238
6291
|
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
6239
6292
|
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
6240
6293
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
6241
6294
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6242
6295
|
TimelineIndicator,
|
|
6243
6296
|
{
|
|
6244
|
-
className: cn("size-2 border-none", statusColorClass(
|
|
6297
|
+
className: cn("size-2 border-none", statusColorClass(indicatorStatus))
|
|
6245
6298
|
}
|
|
6246
6299
|
)
|
|
6247
6300
|
] }),
|
|
@@ -6299,13 +6352,14 @@ function TimelineEntryItem({
|
|
|
6299
6352
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
6300
6353
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineIndicator, { className: "size-2 border-none bg-primary animate-pulse" })
|
|
6301
6354
|
] }),
|
|
6302
|
-
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration:
|
|
6355
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration: 3, spread: 3, className: "text-sm", children: "Working on it..." }) })
|
|
6303
6356
|
] });
|
|
6304
6357
|
}
|
|
6305
6358
|
function AssistantGroup({
|
|
6306
6359
|
messages,
|
|
6307
6360
|
lastGlobalIndex,
|
|
6308
6361
|
totalMessages,
|
|
6362
|
+
isRunning,
|
|
6309
6363
|
sessionId,
|
|
6310
6364
|
onFileSelect,
|
|
6311
6365
|
onRetry
|
|
@@ -6315,6 +6369,15 @@ function AssistantGroup({
|
|
|
6315
6369
|
const isLast = i === messages.length - 1 && lastGlobalIndex === totalMessages - 1;
|
|
6316
6370
|
entries.push(...messageToEntries(messages[i], isLast));
|
|
6317
6371
|
}
|
|
6372
|
+
const isTailGroup = lastGlobalIndex === totalMessages - 1;
|
|
6373
|
+
const lastEntry = entries[entries.length - 1];
|
|
6374
|
+
const hasRunningTool = entries.some(
|
|
6375
|
+
(e) => e.kind === "tool" && e.tc.status === "running"
|
|
6376
|
+
);
|
|
6377
|
+
const tailMsg = messages[messages.length - 1];
|
|
6378
|
+
if (isTailGroup && isRunning && !hasRunningTool && lastEntry?.kind !== "thinking") {
|
|
6379
|
+
entries.push({ kind: "thinking", key: `${tailMsg.id}-tail-thinking` });
|
|
6380
|
+
}
|
|
6318
6381
|
const tail = messages[messages.length - 1];
|
|
6319
6382
|
const showErrorInfo = tail && tail.role === "assistant" && tail.status === "error" && !!tail.errorInfo;
|
|
6320
6383
|
return /* @__PURE__ */ jsxRuntime.jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsxRuntime.jsxs(MessageContent, { children: [
|
|
@@ -6438,6 +6501,7 @@ function ChatThread({
|
|
|
6438
6501
|
messages: group.messages,
|
|
6439
6502
|
lastGlobalIndex: group.lastGlobalIndex,
|
|
6440
6503
|
totalMessages: messages.length,
|
|
6504
|
+
isRunning,
|
|
6441
6505
|
sessionId,
|
|
6442
6506
|
onFileSelect,
|
|
6443
6507
|
onRetry: groupRetry
|
|
@@ -6445,7 +6509,7 @@ function ChatThread({
|
|
|
6445
6509
|
group.messages[0].id
|
|
6446
6510
|
);
|
|
6447
6511
|
}),
|
|
6448
|
-
isRunning && messages.length > 0 && messages[messages.length - 1].role === "user" && /* @__PURE__ */ jsxRuntime.jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsxRuntime.jsx(MessageContent, { children: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration:
|
|
6512
|
+
isRunning && messages.length > 0 && messages[messages.length - 1].role === "user" && /* @__PURE__ */ jsxRuntime.jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsxRuntime.jsx(MessageContent, { children: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration: 3, spread: 3, className: "text-sm", children: "Working on it..." }) }) })
|
|
6449
6513
|
] }) }),
|
|
6450
6514
|
/* @__PURE__ */ jsxRuntime.jsx(ConversationScrollButton, {})
|
|
6451
6515
|
] }),
|
|
@@ -7143,6 +7207,7 @@ function WorkspacePanel({
|
|
|
7143
7207
|
onSelectedPathChange,
|
|
7144
7208
|
collapsed = false,
|
|
7145
7209
|
onCollapsedChange,
|
|
7210
|
+
refreshSignal = 0,
|
|
7146
7211
|
disabled = false
|
|
7147
7212
|
}) {
|
|
7148
7213
|
const fileInputRef = react.useRef(null);
|
|
@@ -7222,6 +7287,13 @@ function WorkspacePanel({
|
|
|
7222
7287
|
react.useEffect(() => {
|
|
7223
7288
|
void fetchTree();
|
|
7224
7289
|
}, [fetchTree]);
|
|
7290
|
+
react.useEffect(() => {
|
|
7291
|
+
if (!sessionId || refreshSignal === 0) return;
|
|
7292
|
+
const timer = setTimeout(() => {
|
|
7293
|
+
void fetchTree();
|
|
7294
|
+
}, 300);
|
|
7295
|
+
return () => clearTimeout(timer);
|
|
7296
|
+
}, [refreshSignal, sessionId, fetchTree]);
|
|
7225
7297
|
react.useEffect(() => {
|
|
7226
7298
|
if (!sessionId) {
|
|
7227
7299
|
setFile(null);
|
|
@@ -7562,6 +7634,12 @@ function ConfirmDialog({
|
|
|
7562
7634
|
}
|
|
7563
7635
|
|
|
7564
7636
|
// src/runtime/events.ts
|
|
7637
|
+
var WORKSPACE_MUTATING_TOOLS = /* @__PURE__ */ new Set([
|
|
7638
|
+
"terminal",
|
|
7639
|
+
"write_file",
|
|
7640
|
+
"patch",
|
|
7641
|
+
"execute_code"
|
|
7642
|
+
]);
|
|
7565
7643
|
var AGENT_CHAT_LISTENED_EVENTS = [
|
|
7566
7644
|
"user.message",
|
|
7567
7645
|
"llm.request",
|
|
@@ -7610,7 +7688,8 @@ function createInitialAgentChatState(options = {}) {
|
|
|
7610
7688
|
lastEventId: 0,
|
|
7611
7689
|
sessionDone: false,
|
|
7612
7690
|
hadDeltas: false,
|
|
7613
|
-
terminal: false
|
|
7691
|
+
terminal: false,
|
|
7692
|
+
workspaceRefreshKey: 0
|
|
7614
7693
|
};
|
|
7615
7694
|
}
|
|
7616
7695
|
function applyAgentChatEvent(state, event) {
|
|
@@ -7672,11 +7751,17 @@ function applyAgentChatEvent(state, event) {
|
|
|
7672
7751
|
return applyLlmThinking(nextState, event);
|
|
7673
7752
|
case "tool.call":
|
|
7674
7753
|
return applyToolCall(nextState, event);
|
|
7675
|
-
case "tool.result":
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
);
|
|
7754
|
+
case "tool.result": {
|
|
7755
|
+
const toolCallId = stringValue(event.data.tool_call_id);
|
|
7756
|
+
const toolName = findToolNameById(nextState.messages, toolCallId);
|
|
7757
|
+
const messages = applyToolResult(nextState.messages, event.data);
|
|
7758
|
+
const mutatesWorkspace = toolName !== null && WORKSPACE_MUTATING_TOOLS.has(toolName);
|
|
7759
|
+
return {
|
|
7760
|
+
...nextState,
|
|
7761
|
+
messages,
|
|
7762
|
+
workspaceRefreshKey: mutatesWorkspace ? nextState.workspaceRefreshKey + 1 : nextState.workspaceRefreshKey
|
|
7763
|
+
};
|
|
7764
|
+
}
|
|
7680
7765
|
case "harness.wake":
|
|
7681
7766
|
case "llm.request":
|
|
7682
7767
|
return nextState.terminal ? nextState : { ...nextState, isRunning: true };
|
|
@@ -8116,6 +8201,14 @@ function hasUserAfterIndex(messages, idx) {
|
|
|
8116
8201
|
}
|
|
8117
8202
|
return false;
|
|
8118
8203
|
}
|
|
8204
|
+
function findToolNameById(messages, toolCallId) {
|
|
8205
|
+
if (!toolCallId) return null;
|
|
8206
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8207
|
+
const tc = messages[i]?.toolCalls?.find((c) => c.id === toolCallId);
|
|
8208
|
+
if (tc) return tc.toolName;
|
|
8209
|
+
}
|
|
8210
|
+
return null;
|
|
8211
|
+
}
|
|
8119
8212
|
function findLatestConsultExpertCall(messages) {
|
|
8120
8213
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8121
8214
|
const msg = messages[i];
|
|
@@ -8247,23 +8340,27 @@ function useAgentChatRuntime({
|
|
|
8247
8340
|
closeStream();
|
|
8248
8341
|
};
|
|
8249
8342
|
}, [adapter, clearReconnectTimer, closeStream, sessionId]);
|
|
8250
|
-
const markSending = react.useCallback(
|
|
8251
|
-
|
|
8252
|
-
|
|
8253
|
-
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8343
|
+
const markSending = react.useCallback(
|
|
8344
|
+
(content, images) => {
|
|
8345
|
+
setState((prev) => ({
|
|
8346
|
+
...prev,
|
|
8347
|
+
terminal: false,
|
|
8348
|
+
isRunning: true,
|
|
8349
|
+
messages: [
|
|
8350
|
+
...prev.messages,
|
|
8351
|
+
{
|
|
8352
|
+
id: `local-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
8353
|
+
role: "user",
|
|
8354
|
+
content,
|
|
8355
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
8356
|
+
status: "complete",
|
|
8357
|
+
images: images?.length ? images : void 0
|
|
8358
|
+
}
|
|
8359
|
+
]
|
|
8360
|
+
}));
|
|
8361
|
+
},
|
|
8362
|
+
[]
|
|
8363
|
+
);
|
|
8267
8364
|
const markSendError = react.useCallback((errorText) => {
|
|
8268
8365
|
setState((prev) => {
|
|
8269
8366
|
for (let i = prev.messages.length - 1; i >= 0; i--) {
|
|
@@ -8314,13 +8411,13 @@ function useAgentChatRuntime({
|
|
|
8314
8411
|
});
|
|
8315
8412
|
}, []);
|
|
8316
8413
|
const send = react.useCallback(
|
|
8317
|
-
async (content) => {
|
|
8318
|
-
markSending(content);
|
|
8414
|
+
async (content, images) => {
|
|
8415
|
+
markSending(content, images);
|
|
8319
8416
|
if (!sessionId) {
|
|
8320
8417
|
try {
|
|
8321
8418
|
const session = await adapter.createSession({ agentId });
|
|
8322
8419
|
onSessionChange?.(session.id);
|
|
8323
|
-
await adapter.sendMessage({ sessionId: session.id, content });
|
|
8420
|
+
await adapter.sendMessage({ sessionId: session.id, content, images });
|
|
8324
8421
|
} catch (error) {
|
|
8325
8422
|
markSendError(error instanceof Error ? error.message : "send failed");
|
|
8326
8423
|
throw error;
|
|
@@ -8328,7 +8425,7 @@ function useAgentChatRuntime({
|
|
|
8328
8425
|
return;
|
|
8329
8426
|
}
|
|
8330
8427
|
try {
|
|
8331
|
-
await adapter.sendMessage({ sessionId, content });
|
|
8428
|
+
await adapter.sendMessage({ sessionId, content, images });
|
|
8332
8429
|
} catch (error) {
|
|
8333
8430
|
markSendError(error instanceof Error ? error.message : "send failed");
|
|
8334
8431
|
throw error;
|
|
@@ -8366,6 +8463,7 @@ function useAgentChatRuntime({
|
|
|
8366
8463
|
isLoadingHistory: state.isLoadingHistory,
|
|
8367
8464
|
tokenUsage: state.tokenUsage,
|
|
8368
8465
|
retryIndicator: state.retryIndicator,
|
|
8466
|
+
workspaceRefreshKey: state.workspaceRefreshKey,
|
|
8369
8467
|
send,
|
|
8370
8468
|
stop,
|
|
8371
8469
|
retry,
|
|
@@ -8433,7 +8531,7 @@ function AgentChat({
|
|
|
8433
8531
|
messages: runtime.messages,
|
|
8434
8532
|
isRunning: runtime.isRunning,
|
|
8435
8533
|
isLoadingHistory: runtime.isLoadingHistory,
|
|
8436
|
-
onSend: (content) => void runtime.send(content),
|
|
8534
|
+
onSend: (content, images) => void runtime.send(content, images),
|
|
8437
8535
|
onStop: () => void runtime.stop(),
|
|
8438
8536
|
onRetry: runtime.retry,
|
|
8439
8537
|
onFileSelect: handleFileSelect,
|
|
@@ -8451,6 +8549,7 @@ function AgentChat({
|
|
|
8451
8549
|
onSelectedPathChange: setWorkspacePath,
|
|
8452
8550
|
collapsed: workspaceCollapsed,
|
|
8453
8551
|
onCollapsedChange: setWorkspaceCollapsed,
|
|
8552
|
+
refreshSignal: runtime.workspaceRefreshKey,
|
|
8454
8553
|
disabled
|
|
8455
8554
|
}
|
|
8456
8555
|
)
|
|
@@ -8556,6 +8655,7 @@ function TreeNodeRow({
|
|
|
8556
8655
|
const hasChildren = entry.children.length > 0;
|
|
8557
8656
|
const isActive = entry.id === activeSessionId;
|
|
8558
8657
|
const isRunning = entry.status === "active";
|
|
8658
|
+
const isSubAgent = entry.parentId != null;
|
|
8559
8659
|
const title = entry.title ?? "New session";
|
|
8560
8660
|
const subtitle = [
|
|
8561
8661
|
entry.model ?? "default",
|
|
@@ -8595,7 +8695,7 @@ function TreeNodeRow({
|
|
|
8595
8695
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm truncate", children: title }),
|
|
8596
8696
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-faint truncate", children: subtitle })
|
|
8597
8697
|
] }),
|
|
8598
|
-
isRunning && canStop && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8698
|
+
isRunning && canStop && isSubAgent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8599
8699
|
"button",
|
|
8600
8700
|
{
|
|
8601
8701
|
type: "button",
|