@mcp-b/react-components 0.9.0 → 0.10.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.
|
@@ -3,7 +3,7 @@ import { A as SearchIcon, o as ChevronDownIcon } from "./icons-D2Q5n5C1.js";
|
|
|
3
3
|
import { Button } from "./components/Button.js";
|
|
4
4
|
import { Dialog, DialogBackdrop, DialogPopup, DialogPortal, DialogTitle, DialogTrigger } from "./components/Dialog.js";
|
|
5
5
|
import * as React from "react";
|
|
6
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
//#region src/components/_internal/provider-logos.tsx
|
|
8
8
|
function Svg({ children, size = 16, ...props }) {
|
|
9
9
|
return /* @__PURE__ */ jsx("svg", {
|
|
@@ -77,6 +77,128 @@ function ProviderLogo({ provider, ...props }) {
|
|
|
77
77
|
//#endregion
|
|
78
78
|
//#region src/components/ModelSelector.tsx
|
|
79
79
|
const ModelSelectorContext = React.createContext(null);
|
|
80
|
+
const cloudflareModelProviderLabels = {
|
|
81
|
+
ai4bharat: "AI4Bharat",
|
|
82
|
+
aisingapore: "AI Singapore",
|
|
83
|
+
alibaba: "Alibaba",
|
|
84
|
+
anthropic: "Anthropic",
|
|
85
|
+
baai: "BAAI",
|
|
86
|
+
cohere: "Cohere",
|
|
87
|
+
deepseek: "DeepSeek",
|
|
88
|
+
"deepseek-ai": "DeepSeek",
|
|
89
|
+
google: "Google",
|
|
90
|
+
"google-vertex": "Google Vertex",
|
|
91
|
+
groq: "Groq",
|
|
92
|
+
ibm: "IBM",
|
|
93
|
+
"ibm-granite": "IBM",
|
|
94
|
+
meta: "Meta",
|
|
95
|
+
"meta-llama": "Meta",
|
|
96
|
+
microsoft: "Microsoft",
|
|
97
|
+
mistral: "Mistral AI",
|
|
98
|
+
mistralai: "Mistral AI",
|
|
99
|
+
minimax: "MiniMax",
|
|
100
|
+
moonshotai: "Moonshot AI",
|
|
101
|
+
nvidia: "NVIDIA",
|
|
102
|
+
openai: "OpenAI",
|
|
103
|
+
openrouter: "OpenRouter",
|
|
104
|
+
perplexity: "Perplexity",
|
|
105
|
+
qwen: "Qwen",
|
|
106
|
+
replicate: "Replicate",
|
|
107
|
+
together: "Together AI",
|
|
108
|
+
xai: "xAI",
|
|
109
|
+
"zai-org": "Zhipu AI"
|
|
110
|
+
};
|
|
111
|
+
function isCloudflareRunnableModelId(value) {
|
|
112
|
+
const modelId = value.trim();
|
|
113
|
+
return /^@(?:cf|hf)\/[^/\s]+\/\S+$/.test(modelId) || /^[a-z0-9][a-z0-9._-]*\/\S+$/i.test(modelId);
|
|
114
|
+
}
|
|
115
|
+
function readCatalogString(value) {
|
|
116
|
+
if (typeof value !== "string") return null;
|
|
117
|
+
const trimmed = value.trim();
|
|
118
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
119
|
+
}
|
|
120
|
+
function readCatalogField(entry, field) {
|
|
121
|
+
if (typeof entry !== "object" || entry === null || !Object.hasOwn(entry, field)) return null;
|
|
122
|
+
return readCatalogString(entry[field]);
|
|
123
|
+
}
|
|
124
|
+
function readCatalogEntries(entry) {
|
|
125
|
+
if (Array.isArray(entry)) return entry;
|
|
126
|
+
if (typeof entry !== "object" || entry === null || !Object.hasOwn(entry, "data")) return null;
|
|
127
|
+
const data = entry.data;
|
|
128
|
+
return Array.isArray(data) ? data : null;
|
|
129
|
+
}
|
|
130
|
+
function readCloudflareModelId(entry) {
|
|
131
|
+
if (typeof entry === "string") {
|
|
132
|
+
const modelId = readCatalogString(entry);
|
|
133
|
+
return modelId && isCloudflareRunnableModelId(modelId) ? modelId : null;
|
|
134
|
+
}
|
|
135
|
+
for (const field of ["name", "id"]) {
|
|
136
|
+
const modelId = readCatalogField(entry, field);
|
|
137
|
+
if (modelId && isCloudflareRunnableModelId(modelId)) return modelId;
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
function getCloudflareModelProvider(modelId) {
|
|
142
|
+
const [, hostedProvider] = /^@(?:cf|hf)\/([^/]+)/.exec(modelId) ?? [];
|
|
143
|
+
if (hostedProvider) return hostedProvider;
|
|
144
|
+
return modelId.split("/", 1)[0] || "other";
|
|
145
|
+
}
|
|
146
|
+
function formatCloudflareModelProvider(provider) {
|
|
147
|
+
const normalized = provider.trim().toLowerCase();
|
|
148
|
+
if (cloudflareModelProviderLabels[normalized]) return cloudflareModelProviderLabels[normalized];
|
|
149
|
+
return normalized.split(/[-_]/).filter(Boolean).map((word) => word[0].toUpperCase() + word.slice(1)).join(" ");
|
|
150
|
+
}
|
|
151
|
+
function normalizeCloudflareModelSelectorModels(models) {
|
|
152
|
+
const seen = /* @__PURE__ */ new Set();
|
|
153
|
+
const options = [];
|
|
154
|
+
const appendOption = (entry) => {
|
|
155
|
+
const entries = readCatalogEntries(entry);
|
|
156
|
+
if (entries) {
|
|
157
|
+
for (const nestedEntry of entries) appendOption(nestedEntry);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const id = readCloudflareModelId(entry);
|
|
161
|
+
if (!id || seen.has(id)) return;
|
|
162
|
+
seen.add(id);
|
|
163
|
+
const provider = getCloudflareModelProvider(id);
|
|
164
|
+
options.push({
|
|
165
|
+
id,
|
|
166
|
+
provider,
|
|
167
|
+
providerLabel: formatCloudflareModelProvider(provider),
|
|
168
|
+
source: id.startsWith("@") ? "workers-ai" : "ai-gateway",
|
|
169
|
+
description: readCatalogField(entry, "description")
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
for (const entry of models) appendOption(entry);
|
|
173
|
+
return options;
|
|
174
|
+
}
|
|
175
|
+
async function listCloudflareModelSelectorOptions(client, params) {
|
|
176
|
+
const models = [];
|
|
177
|
+
for await (const model of client.ai.models.list(params)) models.push(model);
|
|
178
|
+
if (params.format !== "openrouter") for await (const model of client.ai.models.list({
|
|
179
|
+
...params,
|
|
180
|
+
format: "openrouter"
|
|
181
|
+
})) models.push(model);
|
|
182
|
+
return normalizeCloudflareModelSelectorModels(models);
|
|
183
|
+
}
|
|
184
|
+
function groupCloudflareModelOptions(options) {
|
|
185
|
+
const groups = [];
|
|
186
|
+
const groupsByLabel = /* @__PURE__ */ new Map();
|
|
187
|
+
for (const option of options) {
|
|
188
|
+
const group = groupsByLabel.get(option.providerLabel);
|
|
189
|
+
if (group) {
|
|
190
|
+
group.push(option);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const nextGroup = [option];
|
|
194
|
+
groupsByLabel.set(option.providerLabel, nextGroup);
|
|
195
|
+
groups.push({
|
|
196
|
+
providerLabel: option.providerLabel,
|
|
197
|
+
options: nextGroup
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
return groups;
|
|
201
|
+
}
|
|
80
202
|
function useModelSelectorContext() {
|
|
81
203
|
const ctx = React.useContext(ModelSelectorContext);
|
|
82
204
|
if (!ctx) throw new Error("ModelSelector subcomponents must be used inside <ModelSelector>.");
|
|
@@ -154,6 +276,67 @@ function ModelSelector({ open, defaultOpen = false, onOpenChange, children, clas
|
|
|
154
276
|
})
|
|
155
277
|
});
|
|
156
278
|
}
|
|
279
|
+
function CloudflareModelSelector({ models, selectedModelId = null, onSelectModel, disabled = false, placeholder = "Search or paste an AI Gateway model id...", triggerLabel = "Select a model", emptyLabel = "No models found", allowTypedModel = true, onOpenChange, ...props }) {
|
|
280
|
+
const [query, setQuery] = React.useState("");
|
|
281
|
+
const options = React.useMemo(() => normalizeCloudflareModelSelectorModels(models), [models]);
|
|
282
|
+
const groups = React.useMemo(() => groupCloudflareModelOptions(options), [options]);
|
|
283
|
+
const optionIds = React.useMemo(() => new Set(options.map((option) => option.id)), [options]);
|
|
284
|
+
const selectedOption = selectedModelId ? options.find((option) => option.id === selectedModelId) ?? {
|
|
285
|
+
id: selectedModelId,
|
|
286
|
+
provider: getCloudflareModelProvider(selectedModelId),
|
|
287
|
+
providerLabel: formatCloudflareModelProvider(getCloudflareModelProvider(selectedModelId)),
|
|
288
|
+
source: selectedModelId.startsWith("@") ? "workers-ai" : "ai-gateway",
|
|
289
|
+
description: null
|
|
290
|
+
} : null;
|
|
291
|
+
const typedModelId = query.trim();
|
|
292
|
+
const showTypedModel = allowTypedModel && isCloudflareRunnableModelId(typedModelId) && typedModelId !== selectedModelId && !optionIds.has(typedModelId);
|
|
293
|
+
return /* @__PURE__ */ jsxs(ModelSelector, {
|
|
294
|
+
onOpenChange: React.useCallback((nextOpen) => {
|
|
295
|
+
if (!nextOpen) setQuery("");
|
|
296
|
+
onOpenChange?.(nextOpen);
|
|
297
|
+
}, [onOpenChange]),
|
|
298
|
+
...props,
|
|
299
|
+
children: [/* @__PURE__ */ jsx(ModelSelectorTrigger, {
|
|
300
|
+
disabled,
|
|
301
|
+
children: selectedOption ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ModelSelectorLogo, { provider: selectedOption.provider }), /* @__PURE__ */ jsx(ModelSelectorName, { children: selectedOption.id })] }) : /* @__PURE__ */ jsx(ModelSelectorName, { children: triggerLabel })
|
|
302
|
+
}), /* @__PURE__ */ jsx(ModelSelectorContent, {
|
|
303
|
+
title: "Cloudflare model selector",
|
|
304
|
+
children: /* @__PURE__ */ jsxs(ModelSelectorDialog, { children: [/* @__PURE__ */ jsx(ModelSelectorInput, {
|
|
305
|
+
"aria-label": "Search Cloudflare AI models",
|
|
306
|
+
placeholder,
|
|
307
|
+
onInput: (event) => setQuery(event.currentTarget.value)
|
|
308
|
+
}), /* @__PURE__ */ jsxs(ModelSelectorList, { children: [
|
|
309
|
+
showTypedModel ? /* @__PURE__ */ jsx(ModelSelectorGroup, {
|
|
310
|
+
label: "AI Gateway",
|
|
311
|
+
children: /* @__PURE__ */ jsxs(ModelSelectorItem, {
|
|
312
|
+
value: typedModelId,
|
|
313
|
+
onSelect: onSelectModel,
|
|
314
|
+
children: [
|
|
315
|
+
/* @__PURE__ */ jsx(ModelSelectorLogo, { provider: getCloudflareModelProvider(typedModelId) }),
|
|
316
|
+
/* @__PURE__ */ jsx(ModelSelectorName, { children: typedModelId }),
|
|
317
|
+
/* @__PURE__ */ jsx(ModelSelectorShortcut, { children: "Use" })
|
|
318
|
+
]
|
|
319
|
+
})
|
|
320
|
+
}) : null,
|
|
321
|
+
groups.map((group) => /* @__PURE__ */ jsx(ModelSelectorGroup, {
|
|
322
|
+
label: group.providerLabel,
|
|
323
|
+
children: group.options.map((option) => /* @__PURE__ */ jsxs(ModelSelectorItem, {
|
|
324
|
+
value: option.id,
|
|
325
|
+
keywords: `${option.provider} ${option.providerLabel} ${option.source} ${option.description ?? ""}`,
|
|
326
|
+
selected: option.id === selectedModelId,
|
|
327
|
+
onSelect: onSelectModel,
|
|
328
|
+
children: [
|
|
329
|
+
/* @__PURE__ */ jsx(ModelSelectorLogo, { provider: option.provider }),
|
|
330
|
+
/* @__PURE__ */ jsx(ModelSelectorName, { children: option.id }),
|
|
331
|
+
/* @__PURE__ */ jsx(ModelSelectorShortcut, { children: option.source === "workers-ai" ? "Workers AI" : "Gateway" })
|
|
332
|
+
]
|
|
333
|
+
}, option.id))
|
|
334
|
+
}, group.providerLabel)),
|
|
335
|
+
/* @__PURE__ */ jsx(ModelSelectorEmpty, { children: emptyLabel })
|
|
336
|
+
] })] })
|
|
337
|
+
})]
|
|
338
|
+
});
|
|
339
|
+
}
|
|
157
340
|
function ModelSelectorTrigger({ className, children, ...props }) {
|
|
158
341
|
return /* @__PURE__ */ jsx(DialogTrigger, { render: /* @__PURE__ */ jsxs(Button, {
|
|
159
342
|
variant: "outline",
|
|
@@ -303,4 +486,4 @@ function ModelSelectorShortcut({ className, children, ref, ...props }) {
|
|
|
303
486
|
});
|
|
304
487
|
}
|
|
305
488
|
//#endregion
|
|
306
|
-
export {
|
|
489
|
+
export { getCloudflareModelProvider as _, ModelSelectorEmpty as a, normalizeCloudflareModelSelectorModels as b, ModelSelectorItem as c, ModelSelectorLogoGroup as d, ModelSelectorName as f, formatCloudflareModelProvider as g, ModelSelectorTrigger as h, ModelSelectorDialog as i, ModelSelectorList as l, ModelSelectorShortcut as m, ModelSelector as n, ModelSelectorGroup as o, ModelSelectorSeparator as p, ModelSelectorContent as r, ModelSelectorInput as s, CloudflareModelSelector as t, ModelSelectorLogo as u, isCloudflareRunnableModelId as v, readCloudflareModelId as x, listCloudflareModelSelectorOptions as y };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
2
2
|
import { M as SpinnerIcon } from "../icons-D2Q5n5C1.js";
|
|
3
3
|
import { Button } from "./Button.js";
|
|
4
|
-
import {
|
|
4
|
+
import { u as ModelSelectorLogo } from "../ModelSelector-DXtpcRmT.js";
|
|
5
5
|
import "react";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
//#region src/components/ChatGptSignInScreen.tsx
|
|
@@ -1,7 +1,41 @@
|
|
|
1
1
|
import { r as ButtonProps } from "../Button-Ct5I6aTu.js";
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
import Cloudflare from "cloudflare";
|
|
4
|
+
import { AiModelsSearchObject } from "@cloudflare/workers-types";
|
|
3
5
|
|
|
4
6
|
//#region src/components/ModelSelector.d.ts
|
|
7
|
+
type CloudflareModelSelectorModels = readonly Cloudflare.AI.ModelListResponse[] | readonly AiModelsSearchObject[] | readonly string[];
|
|
8
|
+
interface CloudflareModelSelectorOption {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly provider: string;
|
|
11
|
+
readonly providerLabel: string;
|
|
12
|
+
readonly source: "ai-gateway" | "workers-ai";
|
|
13
|
+
readonly description: string | null;
|
|
14
|
+
}
|
|
15
|
+
interface CloudflareModelSelectorProps extends Omit<ModelSelectorProps, "children"> {
|
|
16
|
+
/** Raw `client.ai.models.list()` entries, `env.AI.models()` entries, or model ids. */
|
|
17
|
+
models: CloudflareModelSelectorModels;
|
|
18
|
+
/** Current runnable model id, such as `@cf/meta/llama...` or `openai/gpt-5.5`. */
|
|
19
|
+
selectedModelId?: string | null;
|
|
20
|
+
/** Called with a runnable Workers AI or AI Gateway model id. */
|
|
21
|
+
onSelectModel: (modelId: string) => void;
|
|
22
|
+
/** Disables the trigger while the caller is loading or saving. */
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/** Search input placeholder. */
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
/** Trigger fallback when no model is selected. */
|
|
27
|
+
triggerLabel?: React.ReactNode;
|
|
28
|
+
/** Empty state copy. */
|
|
29
|
+
emptyLabel?: React.ReactNode;
|
|
30
|
+
/** Whether a pasted `provider/model` id can be selected when absent from the catalog. */
|
|
31
|
+
allowTypedModel?: boolean;
|
|
32
|
+
}
|
|
33
|
+
declare function isCloudflareRunnableModelId(value: string): boolean;
|
|
34
|
+
declare function readCloudflareModelId(entry: unknown): string | null;
|
|
35
|
+
declare function getCloudflareModelProvider(modelId: string): string;
|
|
36
|
+
declare function formatCloudflareModelProvider(provider: string): string;
|
|
37
|
+
declare function normalizeCloudflareModelSelectorModels(models: CloudflareModelSelectorModels): CloudflareModelSelectorOption[];
|
|
38
|
+
declare function listCloudflareModelSelectorOptions(client: Cloudflare, params: Cloudflare.AI.ModelListParams): Promise<CloudflareModelSelectorOption[]>;
|
|
5
39
|
interface ModelSelectorProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
6
40
|
/** Controlled dialog open state. */
|
|
7
41
|
open?: boolean;
|
|
@@ -65,6 +99,18 @@ declare function ModelSelector({
|
|
|
65
99
|
}: ModelSelectorProps & {
|
|
66
100
|
ref?: React.Ref<HTMLDivElement>;
|
|
67
101
|
}): React.JSX.Element;
|
|
102
|
+
declare function CloudflareModelSelector({
|
|
103
|
+
models,
|
|
104
|
+
selectedModelId,
|
|
105
|
+
onSelectModel,
|
|
106
|
+
disabled,
|
|
107
|
+
placeholder,
|
|
108
|
+
triggerLabel,
|
|
109
|
+
emptyLabel,
|
|
110
|
+
allowTypedModel,
|
|
111
|
+
onOpenChange,
|
|
112
|
+
...props
|
|
113
|
+
}: CloudflareModelSelectorProps): React.JSX.Element;
|
|
68
114
|
interface ModelSelectorTriggerProps extends Omit<ButtonProps, "variant" | "color" | "className"> {
|
|
69
115
|
className?: string;
|
|
70
116
|
}
|
|
@@ -195,4 +241,4 @@ declare function ModelSelectorShortcut({
|
|
|
195
241
|
ref?: React.Ref<HTMLSpanElement>;
|
|
196
242
|
}): React.JSX.Element;
|
|
197
243
|
//#endregion
|
|
198
|
-
export { ModelSelector, ModelSelectorContent, ModelSelectorContentProps, ModelSelectorDialog, ModelSelectorDialogProps, ModelSelectorEmpty, ModelSelectorEmptyProps, ModelSelectorGroup, ModelSelectorGroupProps, ModelSelectorInput, ModelSelectorInputProps, ModelSelectorItem, ModelSelectorItemProps, ModelSelectorList, ModelSelectorListProps, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorLogoGroupProps, ModelSelectorLogoProps, ModelSelectorName, ModelSelectorNameProps, ModelSelectorProps, ModelSelectorSeparator, ModelSelectorSeparatorProps, ModelSelectorShortcut, ModelSelectorShortcutProps, ModelSelectorTrigger, ModelSelectorTriggerProps };
|
|
244
|
+
export { CloudflareModelSelector, CloudflareModelSelectorModels, CloudflareModelSelectorOption, CloudflareModelSelectorProps, ModelSelector, ModelSelectorContent, ModelSelectorContentProps, ModelSelectorDialog, ModelSelectorDialogProps, ModelSelectorEmpty, ModelSelectorEmptyProps, ModelSelectorGroup, ModelSelectorGroupProps, ModelSelectorInput, ModelSelectorInputProps, ModelSelectorItem, ModelSelectorItemProps, ModelSelectorList, ModelSelectorListProps, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorLogoGroupProps, ModelSelectorLogoProps, ModelSelectorName, ModelSelectorNameProps, ModelSelectorProps, ModelSelectorSeparator, ModelSelectorSeparatorProps, ModelSelectorShortcut, ModelSelectorShortcutProps, ModelSelectorTrigger, ModelSelectorTriggerProps, formatCloudflareModelProvider, getCloudflareModelProvider, isCloudflareRunnableModelId, listCloudflareModelSelectorOptions, normalizeCloudflareModelSelectorModels, readCloudflareModelId };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { ModelSelector, ModelSelectorContent, ModelSelectorDialog, ModelSelectorEmpty, ModelSelectorGroup, ModelSelectorInput, ModelSelectorItem, ModelSelectorList, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorName, ModelSelectorSeparator, ModelSelectorShortcut, ModelSelectorTrigger };
|
|
1
|
+
import { _ as getCloudflareModelProvider, a as ModelSelectorEmpty, b as normalizeCloudflareModelSelectorModels, c as ModelSelectorItem, d as ModelSelectorLogoGroup, f as ModelSelectorName, g as formatCloudflareModelProvider, h as ModelSelectorTrigger, i as ModelSelectorDialog, l as ModelSelectorList, m as ModelSelectorShortcut, n as ModelSelector, o as ModelSelectorGroup, p as ModelSelectorSeparator, r as ModelSelectorContent, s as ModelSelectorInput, t as CloudflareModelSelector, u as ModelSelectorLogo, v as isCloudflareRunnableModelId, x as readCloudflareModelId, y as listCloudflareModelSelectorOptions } from "../ModelSelector-DXtpcRmT.js";
|
|
2
|
+
export { CloudflareModelSelector, ModelSelector, ModelSelectorContent, ModelSelectorDialog, ModelSelectorEmpty, ModelSelectorGroup, ModelSelectorInput, ModelSelectorItem, ModelSelectorList, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorName, ModelSelectorSeparator, ModelSelectorShortcut, ModelSelectorTrigger, formatCloudflareModelProvider, getCloudflareModelProvider, isCloudflareRunnableModelId, listCloudflareModelSelectorOptions, normalizeCloudflareModelSelectorModels, readCloudflareModelId };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-b/react-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "MCP-B React components built on Base UI and shared design tokens, including Cloudflare Think chat primitives.",
|
|
5
5
|
"homepage": "https://design-system.sigvelo.com",
|
|
6
6
|
"bugs": {
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@base-ui/react": "~1.6.0",
|
|
43
43
|
"@cloudflare/codemode": "^0.4.2",
|
|
44
|
+
"@cloudflare/workers-types": "^4.20260702.1",
|
|
44
45
|
"@rrweb/replay": "^2.1.0",
|
|
45
46
|
"@shadcn/react": "^0.2.0",
|
|
46
47
|
"@streamdown/cjk": "^1.0.3",
|
|
@@ -48,15 +49,15 @@
|
|
|
48
49
|
"@streamdown/math": "^1.0.2",
|
|
49
50
|
"@streamdown/mermaid": "^1.0.2",
|
|
50
51
|
"anser": "^2.3.5",
|
|
52
|
+
"cloudflare": "^6.5.0",
|
|
51
53
|
"shiki": "^3.23.0",
|
|
52
54
|
"streamdown": "^2.5.0",
|
|
53
|
-
"@mcp-b/design-tokens": "0.
|
|
55
|
+
"@mcp-b/design-tokens": "0.10.0"
|
|
54
56
|
},
|
|
55
57
|
"devDependencies": {
|
|
56
58
|
"@ai-sdk/react": "^3.0.222",
|
|
57
59
|
"@cloudflare/shell": "^0.4.1",
|
|
58
60
|
"@cloudflare/think": "^0.12.1",
|
|
59
|
-
"@cloudflare/workers-types": "^4.20260702.1",
|
|
60
61
|
"@storybook/addon-a11y": "^10.4.6",
|
|
61
62
|
"@storybook/addon-docs": "^10.4.6",
|
|
62
63
|
"@storybook/addon-vitest": "^10.4.6",
|