@chat-js/cli 0.6.1 → 0.6.3
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.js +17065 -16667
- package/package.json +1 -1
- package/templates/chat-app/app/(auth)/login/page.tsx +3 -3
- package/templates/chat-app/app/(chat)/api/chat/route.ts +4 -60
- package/templates/chat-app/app/not-found.tsx +2 -2
- package/templates/chat-app/chat.config.ts +3 -0
- package/templates/chat-app/components/ai-elements/actions.tsx +44 -44
- package/templates/chat-app/components/ai-elements/artifact.tsx +92 -92
- package/templates/chat-app/components/ai-elements/code-block.tsx +143 -143
- package/templates/chat-app/components/ai-elements/context.tsx +313 -313
- package/templates/chat-app/components/ai-elements/conversation.tsx +65 -65
- package/templates/chat-app/components/ai-elements/extra/conversation-content-scroll-area.tsx +29 -29
- package/templates/chat-app/components/ai-elements/extra/mcp-tool-header.tsx +27 -27
- package/templates/chat-app/components/ai-elements/message.tsx +341 -344
- package/templates/chat-app/components/ai-elements/parseIncompleteMarkdown.tsx +122 -122
- package/templates/chat-app/components/ai-elements/prompt-input.tsx +1059 -1059
- package/templates/chat-app/components/ai-elements/reasoning.tsx +131 -131
- package/templates/chat-app/components/ai-elements/response.tsx +15 -12
- package/templates/chat-app/components/ai-elements/sandbox.tsx +84 -84
- package/templates/chat-app/components/ai-elements/shimmer.tsx +47 -47
- package/templates/chat-app/components/ai-elements/suggestion.tsx +33 -33
- package/templates/chat-app/components/ai-elements/tool.tsx +118 -118
- package/templates/chat-app/components/app-sidebar-history-conditional.tsx +3 -3
- package/templates/chat-app/components/app-sidebar.tsx +3 -3
- package/templates/chat-app/components/connectors-dropdown.tsx +6 -3
- package/templates/chat-app/components/deep-research-progress.tsx +1 -1
- package/templates/chat-app/components/header-breadcrumb.tsx +14 -11
- package/templates/chat-app/components/internal-link.tsx +73 -0
- package/templates/chat-app/components/login-form.tsx +5 -5
- package/templates/chat-app/components/message-parts.tsx +1 -71
- package/templates/chat-app/components/model-selector.tsx +3 -3
- package/templates/chat-app/components/new-chat-button.tsx +4 -4
- package/templates/chat-app/components/part/document-common.tsx +3 -3
- package/templates/chat-app/components/part/document-tool.tsx +3 -3
- package/templates/chat-app/components/part/message-annotations.tsx +2 -2
- package/templates/chat-app/components/part/tool-part.tsx +92 -0
- package/templates/chat-app/components/project-chat-item.tsx +2 -2
- package/templates/chat-app/components/research-progress.tsx +2 -2
- package/templates/chat-app/components/research-task.tsx +1 -1
- package/templates/chat-app/components/research-tasks.tsx +1 -1
- package/templates/chat-app/components/settings/connectors-settings.tsx +4 -4
- package/templates/chat-app/components/settings/mcp-details-page.tsx +5 -5
- package/templates/chat-app/components/settings/settings-nav.tsx +3 -3
- package/templates/chat-app/components/sidebar-chat-item.tsx +4 -12
- package/templates/chat-app/components/sidebar-project-item.tsx +4 -11
- package/templates/chat-app/components/sidebar-top-row.tsx +7 -7
- package/templates/chat-app/components/sidebar-user-nav.tsx +3 -3
- package/templates/chat-app/components/signup-form.tsx +8 -5
- package/templates/chat-app/components/source-badge.tsx +3 -9
- package/templates/chat-app/components/sources.tsx +1 -1
- package/templates/chat-app/components/ui/accordion.tsx +32 -32
- package/templates/chat-app/components/ui/alert-dialog.tsx +103 -103
- package/templates/chat-app/components/ui/alert.tsx +36 -36
- package/templates/chat-app/components/ui/avatar.tsx +28 -28
- package/templates/chat-app/components/ui/badge.tsx +22 -22
- package/templates/chat-app/components/ui/breadcrumb.tsx +72 -72
- package/templates/chat-app/components/ui/button-group.tsx +58 -58
- package/templates/chat-app/components/ui/button.tsx +45 -45
- package/templates/chat-app/components/ui/card.tsx +65 -65
- package/templates/chat-app/components/ui/checkbox.tsx +16 -16
- package/templates/chat-app/components/ui/collapsible.tsx +1 -1
- package/templates/chat-app/components/ui/command.tsx +137 -137
- package/templates/chat-app/components/ui/dialog.tsx +94 -94
- package/templates/chat-app/components/ui/drawer.tsx +68 -68
- package/templates/chat-app/components/ui/dropdown-menu.tsx +184 -184
- package/templates/chat-app/components/ui/empty.tsx +76 -76
- package/templates/chat-app/components/ui/extra/action-container.tsx +3 -3
- package/templates/chat-app/components/ui/extra/scroll-area-viewport-ref.tsx +24 -24
- package/templates/chat-app/components/ui/form.tsx +112 -112
- package/templates/chat-app/components/ui/hover-card.tsx +25 -25
- package/templates/chat-app/components/ui/input-group.tsx +126 -126
- package/templates/chat-app/components/ui/input.tsx +13 -13
- package/templates/chat-app/components/ui/label.tsx +12 -12
- package/templates/chat-app/components/ui/popover.tsx +25 -25
- package/templates/chat-app/components/ui/progress.tsx +19 -19
- package/templates/chat-app/components/ui/resizable.tsx +27 -27
- package/templates/chat-app/components/ui/scroll-area.tsx +30 -30
- package/templates/chat-app/components/ui/select.tsx +108 -108
- package/templates/chat-app/components/ui/separator.tsx +16 -16
- package/templates/chat-app/components/ui/sheet.tsx +91 -91
- package/templates/chat-app/components/ui/sidebar.tsx +615 -615
- package/templates/chat-app/components/ui/skeleton.tsx +7 -7
- package/templates/chat-app/components/ui/slider.tsx +50 -50
- package/templates/chat-app/components/ui/spinner.tsx +8 -8
- package/templates/chat-app/components/ui/switch.tsx +16 -16
- package/templates/chat-app/components/ui/table.tsx +71 -71
- package/templates/chat-app/components/ui/tabs.tsx +31 -31
- package/templates/chat-app/components/ui/textarea.tsx +10 -10
- package/templates/chat-app/components/ui/toggle.tsx +31 -31
- package/templates/chat-app/components/ui/tooltip.tsx +48 -48
- package/templates/chat-app/components/upgrade-cta/limit-display.tsx +7 -7
- package/templates/chat-app/components/upgrade-cta/login-cta-banner.tsx +3 -3
- package/templates/chat-app/components/upgrade-cta/login-prompt.tsx +3 -3
- package/templates/chat-app/hooks/use-mobile.ts +13 -13
- package/templates/chat-app/lib/ai/core-chat-agent.ts +25 -14
- package/templates/chat-app/lib/ai/eval-agent.ts +4 -5
- package/templates/chat-app/lib/ai/gateway-model-defaults.ts +24 -0
- package/templates/chat-app/lib/ai/installed-tools.ts +12 -0
- package/templates/chat-app/lib/ai/mcp/mcp-client.ts +2 -2
- package/templates/chat-app/lib/ai/models.generated.ts +4236 -4585
- package/templates/chat-app/lib/ai/tool-renderer-registry.ts +31 -0
- package/templates/chat-app/lib/ai/types.ts +15 -20
- package/templates/chat-app/lib/config-requirements.ts +11 -6
- package/templates/chat-app/lib/config-schema.ts +24 -0
- package/templates/chat-app/lib/stores/hooks-message-parts.ts +1 -1
- package/templates/chat-app/lib/utils.ts +157 -157
- package/templates/chat-app/package.json +1 -1
- package/templates/chat-app/scripts/check-env.ts +229 -2
- package/templates/chat-app/tools/chatjs/_shared/lib/tool-part.ts +5 -0
- package/templates/chat-app/{components/part/weather.tsx → tools/chatjs/get-weather/renderer.tsx} +24 -38
- package/templates/chat-app/{components/part/retrieve-url.tsx → tools/chatjs/retrieve-url/renderer.tsx} +20 -15
- package/templates/chat-app/{lib/ai/tools/retrieve-url.ts → tools/chatjs/retrieve-url/tool.ts} +46 -7
- package/templates/chat-app/tools/chatjs/tools.ts +16 -0
- package/templates/chat-app/tools/chatjs/ui.ts +17 -0
- package/templates/chat-app/tools/chatjs/word-count/renderer.tsx +50 -0
- package/templates/chat-app/tools/chatjs/word-count/tool.ts +30 -0
- package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.ts +3 -5
- package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/deep-research.ts +2 -3
- package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/pipeline.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/types.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/utils.ts +7 -7
- package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/types.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/generate-video.ts +4 -6
- package/templates/chat-app/{lib/ai/tools → tools/platform}/read-document.ts +2 -2
- package/templates/chat-app/{lib/ai/tools → tools/platform}/steps/multi-query-web-search.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/steps/web-search.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/tools.ts +54 -30
- package/templates/chat-app/{lib/ai/tools → tools/platform}/web-search.ts +7 -5
- package/templates/electron/CHANGELOG.md +16 -2
- package/templates/electron/package.json +1 -1
- package/templates/chat-app/lib/ai/tools/tools-definitions.ts +0 -83
- /package/templates/chat-app/{lib/ai/tools/get-weather.ts → tools/chatjs/get-weather/tool.ts} +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.javascript.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.python.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.shared.test.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.shared.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.types.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/configuration.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/prompts.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/researcher-agent.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/supervisor-agent.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/code-guidelines.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/create-code-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/create-sheet-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/create-text-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/edit-code-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/edit-sheet-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/edit-text-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/sheet-guidelines.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/text-guidelines.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/generate-image.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/research-updates-schema.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/steps/search-utils.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/types.ts +0 -0
|
@@ -5,9 +5,9 @@ import { type ComponentProps, createContext, useContext } from "react";
|
|
|
5
5
|
import { getUsage } from "tokenlens";
|
|
6
6
|
import { Button } from "@/components/ui/button";
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
HoverCard,
|
|
9
|
+
HoverCardContent,
|
|
10
|
+
HoverCardTrigger,
|
|
11
11
|
} from "@/components/ui/hover-card";
|
|
12
12
|
import { Progress } from "@/components/ui/progress";
|
|
13
13
|
import { cn } from "@/lib/utils";
|
|
@@ -21,388 +21,388 @@ const ICON_STROKE_WIDTH = 2;
|
|
|
21
21
|
type ModelId = string;
|
|
22
22
|
|
|
23
23
|
type ContextSchema = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
usedTokens: number;
|
|
25
|
+
maxTokens: number;
|
|
26
|
+
usage?: LanguageModelUsage;
|
|
27
|
+
modelId?: ModelId;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
const ContextContext = createContext<ContextSchema | null>(null);
|
|
31
31
|
|
|
32
32
|
const useContextValue = () => {
|
|
33
|
-
|
|
33
|
+
const context = useContext(ContextContext);
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
if (!context) {
|
|
36
|
+
throw new Error("Context components must be used within Context");
|
|
37
|
+
}
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
return context;
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
export type ContextProps = ComponentProps<typeof HoverCard> & ContextSchema;
|
|
43
43
|
|
|
44
44
|
export const Context = ({
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
usedTokens,
|
|
46
|
+
maxTokens,
|
|
47
|
+
usage,
|
|
48
|
+
modelId,
|
|
49
|
+
...props
|
|
50
50
|
}: ContextProps) => (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
<ContextContext.Provider
|
|
52
|
+
value={{
|
|
53
|
+
usedTokens,
|
|
54
|
+
maxTokens,
|
|
55
|
+
usage,
|
|
56
|
+
modelId,
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
<HoverCard closeDelay={0} openDelay={0} {...props} />
|
|
60
|
+
</ContextContext.Provider>
|
|
61
61
|
);
|
|
62
62
|
|
|
63
63
|
const ContextIcon = () => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
64
|
+
const { usedTokens, maxTokens } = useContextValue();
|
|
65
|
+
const circumference = 2 * Math.PI * ICON_RADIUS;
|
|
66
|
+
const usedPercent = usedTokens / maxTokens;
|
|
67
|
+
const dashOffset = circumference * (1 - usedPercent);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<svg
|
|
71
|
+
aria-label="Model context usage"
|
|
72
|
+
height="20"
|
|
73
|
+
role="img"
|
|
74
|
+
style={{ color: "currentcolor" }}
|
|
75
|
+
viewBox={`0 0 ${ICON_VIEWBOX} ${ICON_VIEWBOX}`}
|
|
76
|
+
width="20"
|
|
77
|
+
>
|
|
78
|
+
<circle
|
|
79
|
+
cx={ICON_CENTER}
|
|
80
|
+
cy={ICON_CENTER}
|
|
81
|
+
fill="none"
|
|
82
|
+
opacity="0.25"
|
|
83
|
+
r={ICON_RADIUS}
|
|
84
|
+
stroke="currentColor"
|
|
85
|
+
strokeWidth={ICON_STROKE_WIDTH}
|
|
86
|
+
/>
|
|
87
|
+
<circle
|
|
88
|
+
cx={ICON_CENTER}
|
|
89
|
+
cy={ICON_CENTER}
|
|
90
|
+
fill="none"
|
|
91
|
+
opacity="0.7"
|
|
92
|
+
r={ICON_RADIUS}
|
|
93
|
+
stroke="currentColor"
|
|
94
|
+
strokeDasharray={`${circumference} ${circumference}`}
|
|
95
|
+
strokeDashoffset={dashOffset}
|
|
96
|
+
strokeLinecap="round"
|
|
97
|
+
strokeWidth={ICON_STROKE_WIDTH}
|
|
98
|
+
style={{ transformOrigin: "center", transform: "rotate(-90deg)" }}
|
|
99
|
+
/>
|
|
100
|
+
</svg>
|
|
101
|
+
);
|
|
102
102
|
};
|
|
103
103
|
|
|
104
104
|
export type ContextTriggerProps = ComponentProps<typeof Button>;
|
|
105
105
|
|
|
106
106
|
export const ContextTrigger = ({ children, ...props }: ContextTriggerProps) => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
107
|
+
const { usedTokens, maxTokens } = useContextValue();
|
|
108
|
+
const usedPercent = usedTokens / maxTokens;
|
|
109
|
+
const renderedPercent = new Intl.NumberFormat("en-US", {
|
|
110
|
+
style: "percent",
|
|
111
|
+
maximumFractionDigits: 1,
|
|
112
|
+
}).format(usedPercent);
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<HoverCardTrigger asChild>
|
|
116
|
+
{children ?? (
|
|
117
|
+
<Button type="button" variant="ghost" {...props}>
|
|
118
|
+
<span className="font-medium text-muted-foreground">
|
|
119
|
+
{renderedPercent}
|
|
120
|
+
</span>
|
|
121
|
+
<ContextIcon />
|
|
122
|
+
</Button>
|
|
123
|
+
)}
|
|
124
|
+
</HoverCardTrigger>
|
|
125
|
+
);
|
|
126
126
|
};
|
|
127
127
|
|
|
128
128
|
export type ContextContentProps = ComponentProps<typeof HoverCardContent>;
|
|
129
129
|
|
|
130
130
|
export const ContextContent = ({
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
className,
|
|
132
|
+
...props
|
|
133
133
|
}: ContextContentProps) => (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
<HoverCardContent
|
|
135
|
+
className={cn("min-w-60 divide-y overflow-hidden p-0", className)}
|
|
136
|
+
{...props}
|
|
137
|
+
/>
|
|
138
138
|
);
|
|
139
139
|
|
|
140
140
|
export type ContextContentHeaderProps = ComponentProps<"div">;
|
|
141
141
|
|
|
142
142
|
export const ContextContentHeader = ({
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
children,
|
|
144
|
+
className,
|
|
145
|
+
...props
|
|
146
146
|
}: ContextContentHeaderProps) => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
147
|
+
const { usedTokens, maxTokens } = useContextValue();
|
|
148
|
+
const usedPercent = usedTokens / maxTokens;
|
|
149
|
+
const displayPct = new Intl.NumberFormat("en-US", {
|
|
150
|
+
style: "percent",
|
|
151
|
+
maximumFractionDigits: 1,
|
|
152
|
+
}).format(usedPercent);
|
|
153
|
+
const used = new Intl.NumberFormat("en-US", {
|
|
154
|
+
notation: "compact",
|
|
155
|
+
}).format(usedTokens);
|
|
156
|
+
const total = new Intl.NumberFormat("en-US", {
|
|
157
|
+
notation: "compact",
|
|
158
|
+
}).format(maxTokens);
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<div className={cn("w-full space-y-2 p-3", className)} {...props}>
|
|
162
|
+
{children ?? (
|
|
163
|
+
<>
|
|
164
|
+
<div className="flex items-center justify-between gap-3 text-xs">
|
|
165
|
+
<p>{displayPct}</p>
|
|
166
|
+
<p className="font-mono text-muted-foreground">
|
|
167
|
+
{used} / {total}
|
|
168
|
+
</p>
|
|
169
|
+
</div>
|
|
170
|
+
<div className="space-y-2">
|
|
171
|
+
<Progress className="bg-muted" value={usedPercent * PERCENT_MAX} />
|
|
172
|
+
</div>
|
|
173
|
+
</>
|
|
174
|
+
)}
|
|
175
|
+
</div>
|
|
176
|
+
);
|
|
177
177
|
};
|
|
178
178
|
|
|
179
179
|
export type ContextContentBodyProps = ComponentProps<"div">;
|
|
180
180
|
|
|
181
181
|
export const ContextContentBody = ({
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
children,
|
|
183
|
+
className,
|
|
184
|
+
...props
|
|
185
185
|
}: ContextContentBodyProps) => (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
<div className={cn("w-full p-3", className)} {...props}>
|
|
187
|
+
{children}
|
|
188
|
+
</div>
|
|
189
189
|
);
|
|
190
190
|
|
|
191
191
|
export type ContextContentFooterProps = ComponentProps<"div">;
|
|
192
192
|
|
|
193
193
|
export const ContextContentFooter = ({
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
194
|
+
children,
|
|
195
|
+
className,
|
|
196
|
+
...props
|
|
197
197
|
}: ContextContentFooterProps) => {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
198
|
+
const { modelId, usage } = useContextValue();
|
|
199
|
+
const costUSD = modelId
|
|
200
|
+
? getUsage({
|
|
201
|
+
modelId,
|
|
202
|
+
usage: {
|
|
203
|
+
input: usage?.inputTokens ?? 0,
|
|
204
|
+
output: usage?.outputTokens ?? 0,
|
|
205
|
+
},
|
|
206
|
+
}).costUSD?.totalUSD
|
|
207
|
+
: undefined;
|
|
208
|
+
const totalCost = new Intl.NumberFormat("en-US", {
|
|
209
|
+
style: "currency",
|
|
210
|
+
currency: "USD",
|
|
211
|
+
}).format(costUSD ?? 0);
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<div
|
|
215
|
+
className={cn(
|
|
216
|
+
"flex w-full items-center justify-between gap-3 bg-secondary p-3 text-xs",
|
|
217
|
+
className,
|
|
218
|
+
)}
|
|
219
|
+
{...props}
|
|
220
|
+
>
|
|
221
|
+
{children ?? (
|
|
222
|
+
<>
|
|
223
|
+
<span className="text-muted-foreground">Total cost</span>
|
|
224
|
+
<span>{totalCost}</span>
|
|
225
|
+
</>
|
|
226
|
+
)}
|
|
227
|
+
</div>
|
|
228
|
+
);
|
|
229
229
|
};
|
|
230
230
|
|
|
231
231
|
export type ContextInputUsageProps = ComponentProps<"div">;
|
|
232
232
|
|
|
233
233
|
export const ContextInputUsage = ({
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
className,
|
|
235
|
+
children,
|
|
236
|
+
...props
|
|
237
237
|
}: ContextInputUsageProps) => {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
238
|
+
const { usage, modelId } = useContextValue();
|
|
239
|
+
const inputTokens = usage?.inputTokens ?? 0;
|
|
240
|
+
|
|
241
|
+
if (children) {
|
|
242
|
+
return children;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!inputTokens) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const inputCost = modelId
|
|
250
|
+
? getUsage({
|
|
251
|
+
modelId,
|
|
252
|
+
usage: { input: inputTokens, output: 0 },
|
|
253
|
+
}).costUSD?.totalUSD
|
|
254
|
+
: undefined;
|
|
255
|
+
const inputCostText = new Intl.NumberFormat("en-US", {
|
|
256
|
+
style: "currency",
|
|
257
|
+
currency: "USD",
|
|
258
|
+
}).format(inputCost ?? 0);
|
|
259
|
+
|
|
260
|
+
return (
|
|
261
|
+
<div
|
|
262
|
+
className={cn("flex items-center justify-between text-xs", className)}
|
|
263
|
+
{...props}
|
|
264
|
+
>
|
|
265
|
+
<span className="text-muted-foreground">Input</span>
|
|
266
|
+
<TokensWithCost costText={inputCostText} tokens={inputTokens} />
|
|
267
|
+
</div>
|
|
268
|
+
);
|
|
269
269
|
};
|
|
270
270
|
|
|
271
271
|
export type ContextOutputUsageProps = ComponentProps<"div">;
|
|
272
272
|
|
|
273
273
|
export const ContextOutputUsage = ({
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
274
|
+
className,
|
|
275
|
+
children,
|
|
276
|
+
...props
|
|
277
277
|
}: ContextOutputUsageProps) => {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
278
|
+
const { usage, modelId } = useContextValue();
|
|
279
|
+
const outputTokens = usage?.outputTokens ?? 0;
|
|
280
|
+
|
|
281
|
+
if (children) {
|
|
282
|
+
return children;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!outputTokens) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const outputCost = modelId
|
|
290
|
+
? getUsage({
|
|
291
|
+
modelId,
|
|
292
|
+
usage: { input: 0, output: outputTokens },
|
|
293
|
+
}).costUSD?.totalUSD
|
|
294
|
+
: undefined;
|
|
295
|
+
const outputCostText = new Intl.NumberFormat("en-US", {
|
|
296
|
+
style: "currency",
|
|
297
|
+
currency: "USD",
|
|
298
|
+
}).format(outputCost ?? 0);
|
|
299
|
+
|
|
300
|
+
return (
|
|
301
|
+
<div
|
|
302
|
+
className={cn("flex items-center justify-between text-xs", className)}
|
|
303
|
+
{...props}
|
|
304
|
+
>
|
|
305
|
+
<span className="text-muted-foreground">Output</span>
|
|
306
|
+
<TokensWithCost costText={outputCostText} tokens={outputTokens} />
|
|
307
|
+
</div>
|
|
308
|
+
);
|
|
309
309
|
};
|
|
310
310
|
|
|
311
311
|
export type ContextReasoningUsageProps = ComponentProps<"div">;
|
|
312
312
|
|
|
313
313
|
export const ContextReasoningUsage = ({
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
314
|
+
className,
|
|
315
|
+
children,
|
|
316
|
+
...props
|
|
317
317
|
}: ContextReasoningUsageProps) => {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
318
|
+
const { usage, modelId } = useContextValue();
|
|
319
|
+
const reasoningTokens = usage?.reasoningTokens ?? 0;
|
|
320
|
+
|
|
321
|
+
if (children) {
|
|
322
|
+
return children;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (!reasoningTokens) {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const reasoningCost = modelId
|
|
330
|
+
? getUsage({
|
|
331
|
+
modelId,
|
|
332
|
+
usage: { reasoningTokens },
|
|
333
|
+
}).costUSD?.totalUSD
|
|
334
|
+
: undefined;
|
|
335
|
+
const reasoningCostText = new Intl.NumberFormat("en-US", {
|
|
336
|
+
style: "currency",
|
|
337
|
+
currency: "USD",
|
|
338
|
+
}).format(reasoningCost ?? 0);
|
|
339
|
+
|
|
340
|
+
return (
|
|
341
|
+
<div
|
|
342
|
+
className={cn("flex items-center justify-between text-xs", className)}
|
|
343
|
+
{...props}
|
|
344
|
+
>
|
|
345
|
+
<span className="text-muted-foreground">Reasoning</span>
|
|
346
|
+
<TokensWithCost costText={reasoningCostText} tokens={reasoningTokens} />
|
|
347
|
+
</div>
|
|
348
|
+
);
|
|
349
349
|
};
|
|
350
350
|
|
|
351
351
|
export type ContextCacheUsageProps = ComponentProps<"div">;
|
|
352
352
|
|
|
353
353
|
export const ContextCacheUsage = ({
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
354
|
+
className,
|
|
355
|
+
children,
|
|
356
|
+
...props
|
|
357
357
|
}: ContextCacheUsageProps) => {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
358
|
+
const { usage, modelId } = useContextValue();
|
|
359
|
+
const cacheTokens = usage?.cachedInputTokens ?? 0;
|
|
360
|
+
|
|
361
|
+
if (children) {
|
|
362
|
+
return children;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (!cacheTokens) {
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const cacheCost = modelId
|
|
370
|
+
? getUsage({
|
|
371
|
+
modelId,
|
|
372
|
+
usage: { cacheReads: cacheTokens, input: 0, output: 0 },
|
|
373
|
+
}).costUSD?.totalUSD
|
|
374
|
+
: undefined;
|
|
375
|
+
const cacheCostText = new Intl.NumberFormat("en-US", {
|
|
376
|
+
style: "currency",
|
|
377
|
+
currency: "USD",
|
|
378
|
+
}).format(cacheCost ?? 0);
|
|
379
|
+
|
|
380
|
+
return (
|
|
381
|
+
<div
|
|
382
|
+
className={cn("flex items-center justify-between text-xs", className)}
|
|
383
|
+
{...props}
|
|
384
|
+
>
|
|
385
|
+
<span className="text-muted-foreground">Cache</span>
|
|
386
|
+
<TokensWithCost costText={cacheCostText} tokens={cacheTokens} />
|
|
387
|
+
</div>
|
|
388
|
+
);
|
|
389
389
|
};
|
|
390
390
|
|
|
391
391
|
const TokensWithCost = ({
|
|
392
|
-
|
|
393
|
-
|
|
392
|
+
tokens,
|
|
393
|
+
costText,
|
|
394
394
|
}: {
|
|
395
|
-
|
|
396
|
-
|
|
395
|
+
tokens?: number;
|
|
396
|
+
costText?: string;
|
|
397
397
|
}) => (
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
398
|
+
<span>
|
|
399
|
+
{tokens === undefined
|
|
400
|
+
? "—"
|
|
401
|
+
: new Intl.NumberFormat("en-US", {
|
|
402
|
+
notation: "compact",
|
|
403
|
+
}).format(tokens)}
|
|
404
|
+
{costText ? (
|
|
405
|
+
<span className="ml-2 text-muted-foreground">• {costText}</span>
|
|
406
|
+
) : null}
|
|
407
|
+
</span>
|
|
408
408
|
);
|