@tangle-network/sandbox-ui 0.79.0 → 0.81.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.
@@ -1,15 +1,20 @@
1
+ import {
2
+ formatBytes
3
+ } from "./chunk-TK46XFLM.js";
1
4
  import {
2
5
  HARNESS_OPTIONS,
3
6
  HarnessLogo,
4
7
  chatCapableHarnesses
5
- } from "./chunk-IWIZ7RZE.js";
8
+ } from "./chunk-2T6KBMLN.js";
6
9
  import {
7
- ModelBrandStack,
8
10
  ModelPicker,
9
- canonicalModelId,
10
- resolveModelBrandIdentity,
11
11
  stripBrandPrefix
12
- } from "./chunk-L62ZT6RS.js";
12
+ } from "./chunk-R4AR3TKR.js";
13
+ import {
14
+ ModelBrandStack,
15
+ canonicalModelId,
16
+ resolveModelBrandIdentity
17
+ } from "./chunk-I3G23XHN.js";
13
18
  import {
14
19
  cn
15
20
  } from "./chunk-EI44GEQ5.js";
@@ -1064,12 +1069,84 @@ import {
1064
1069
  Folder,
1065
1070
  Loader2,
1066
1071
  Paperclip,
1072
+ RotateCcw,
1067
1073
  Square,
1068
1074
  Upload,
1069
1075
  X
1070
1076
  } from "lucide-react";
1071
1077
  import * as React4 from "react";
1078
+
1079
+ // src/chat/attachment-validation.ts
1080
+ function isAcceptedType(file, accept) {
1081
+ if (!accept || accept.trim().length === 0) return true;
1082
+ const patterns = accept.split(",").map((pattern) => pattern.trim()).filter((pattern) => pattern.length > 0);
1083
+ if (patterns.length === 0) return true;
1084
+ const name = file.name.toLowerCase();
1085
+ const type = (file.type || "").toLowerCase();
1086
+ return patterns.some((pattern) => {
1087
+ const lowerPattern = pattern.toLowerCase();
1088
+ if (lowerPattern.startsWith(".")) {
1089
+ return name.endsWith(lowerPattern);
1090
+ }
1091
+ if (lowerPattern.endsWith("/*")) {
1092
+ const prefix = lowerPattern.slice(0, -1);
1093
+ return type.startsWith(prefix);
1094
+ }
1095
+ return type === lowerPattern;
1096
+ });
1097
+ }
1098
+ function validateComposerFiles(files, config) {
1099
+ const { maxSizeBytes, maxCount, currentCount = 0, accept } = config;
1100
+ const list = Array.isArray(files) ? files : Array.from(files);
1101
+ const accepted = [];
1102
+ const rejected = [];
1103
+ for (const file of list) {
1104
+ if (!isAcceptedType(file, accept)) {
1105
+ rejected.push({
1106
+ file,
1107
+ reason: `"${file.name}" is not an accepted file type (${accept}).`
1108
+ });
1109
+ continue;
1110
+ }
1111
+ if (maxSizeBytes !== void 0 && file.size > maxSizeBytes) {
1112
+ rejected.push({
1113
+ file,
1114
+ reason: `"${file.name}" (${formatBytes(file.size)}) exceeds the ${formatBytes(maxSizeBytes)} limit.`
1115
+ });
1116
+ continue;
1117
+ }
1118
+ if (maxCount !== void 0 && currentCount + accepted.length >= maxCount) {
1119
+ rejected.push({
1120
+ file,
1121
+ reason: `"${file.name}" was not added \u2014 the ${maxCount}-file limit is already reached.`
1122
+ });
1123
+ continue;
1124
+ }
1125
+ accepted.push(file);
1126
+ }
1127
+ return { accepted, rejected };
1128
+ }
1129
+
1130
+ // src/chat/agent-composer.tsx
1072
1131
  import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1132
+ var IMAGE_EXTENSION_BY_MIME = {
1133
+ "image/png": "png",
1134
+ "image/jpeg": "jpg",
1135
+ "image/jpg": "jpg",
1136
+ "image/gif": "gif",
1137
+ "image/webp": "webp",
1138
+ "image/bmp": "bmp",
1139
+ "image/svg+xml": "svg"
1140
+ };
1141
+ function isGenericImageName(name) {
1142
+ return /^(image)?(\.[a-z0-9]+)?$/i.test(name.trim());
1143
+ }
1144
+ function imageExtension(file) {
1145
+ const fromMime = IMAGE_EXTENSION_BY_MIME[file.type.toLowerCase()];
1146
+ if (fromMime) return fromMime;
1147
+ const fromName = /\.([a-z0-9]+)$/i.exec(file.name)?.[1];
1148
+ return fromName?.toLowerCase() ?? "png";
1149
+ }
1073
1150
  function AgentComposer({
1074
1151
  value,
1075
1152
  onChange,
@@ -1089,9 +1166,13 @@ function AgentComposer({
1089
1166
  onAttachFolder,
1090
1167
  attachments = [],
1091
1168
  onRemoveFile,
1169
+ onRetryFile,
1092
1170
  accept,
1171
+ onRejectFiles,
1093
1172
  dropTitle = "Drop files to add context",
1094
1173
  dropDescription = "They attach to your next message.",
1174
+ canSubmitWhileBusy = false,
1175
+ canSubmitAttachmentsOnly = false,
1095
1176
  focusShortcut = false,
1096
1177
  minRows = 2,
1097
1178
  maxHeight = 200,
@@ -1104,6 +1185,7 @@ function AgentComposer({
1104
1185
  const folderInputRef = React4.useRef(null);
1105
1186
  const [dragOver, setDragOver] = React4.useState(false);
1106
1187
  const dragDepth = React4.useRef(0);
1188
+ const pastedImageCount = React4.useRef(0);
1107
1189
  const resize = React4.useCallback(
1108
1190
  (el) => {
1109
1191
  el.style.height = "auto";
@@ -1125,7 +1207,7 @@ function AgentComposer({
1125
1207
  document.addEventListener("keydown", onKeyDown);
1126
1208
  return () => document.removeEventListener("keydown", onKeyDown);
1127
1209
  }, [focusShortcut, disabled]);
1128
- const canSend = !disabled && !busy && value.trim().length > 0;
1210
+ const canSend = !disabled && (!busy || canSubmitWhileBusy) && (value.trim().length > 0 || canSubmitAttachmentsOnly && attachments.length > 0);
1129
1211
  const submit = () => {
1130
1212
  if (!canSend) return;
1131
1213
  onSubmit();
@@ -1154,6 +1236,15 @@ function AgentComposer({
1154
1236
  event.stopPropagation();
1155
1237
  if (event.dataTransfer) event.dataTransfer.dropEffect = "copy";
1156
1238
  };
1239
+ const deliverFiles = (files) => {
1240
+ if (!onAttach || files.length === 0) return;
1241
+ const { accepted, rejected } = validateComposerFiles(files, { accept });
1242
+ if (rejected.length > 0) onRejectFiles?.(rejected);
1243
+ if (accepted.length === 0) return;
1244
+ const dt = new DataTransfer();
1245
+ for (const file of accepted) dt.items.add(file);
1246
+ onAttach(dt.files);
1247
+ };
1157
1248
  const handleDrop = (event) => {
1158
1249
  if (!dropEnabled) return;
1159
1250
  event.preventDefault();
@@ -1161,7 +1252,25 @@ function AgentComposer({
1161
1252
  dragDepth.current = 0;
1162
1253
  setDragOver(false);
1163
1254
  const files = event.dataTransfer?.files;
1164
- if (files?.length) onAttach?.(files);
1255
+ if (files?.length) deliverFiles(Array.from(files));
1256
+ };
1257
+ const handlePaste = (event) => {
1258
+ if (!onAttach) return;
1259
+ const clipboardFiles = event.clipboardData?.files;
1260
+ if (!clipboardFiles || clipboardFiles.length === 0) return;
1261
+ event.preventDefault();
1262
+ const files = Array.from(clipboardFiles).map((file) => {
1263
+ if (file.type.startsWith("image/") && isGenericImageName(file.name)) {
1264
+ pastedImageCount.current += 1;
1265
+ return new File(
1266
+ [file],
1267
+ `pasted-image-${pastedImageCount.current}.${imageExtension(file)}`,
1268
+ { type: file.type }
1269
+ );
1270
+ }
1271
+ return file;
1272
+ });
1273
+ deliverFiles(files);
1165
1274
  };
1166
1275
  const folderChips = attachments.filter((file) => file.kind === "folder");
1167
1276
  const fileChips = attachments.filter((file) => file.kind !== "folder");
@@ -1190,36 +1299,60 @@ function AgentComposer({
1190
1299
  disabled && "opacity-60"
1191
1300
  ),
1192
1301
  children: [
1193
- attachments.length > 0 && /* @__PURE__ */ jsx4("div", { className: "flex flex-wrap gap-1.5", children: [...folderChips, ...fileChips].map((file) => /* @__PURE__ */ jsxs4(
1194
- "span",
1195
- {
1196
- className: cn(
1197
- "inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs",
1198
- file.status === "error" ? "border-[var(--status-error,#ff4d6d)]/40 text-[var(--status-error,#ff4d6d)]" : "border-[var(--md3-outline-variant)] bg-surface-container text-foreground"
1199
- ),
1200
- children: [
1201
- file.kind === "folder" ? /* @__PURE__ */ jsx4(Folder, { className: "size-3 shrink-0" }) : /* @__PURE__ */ jsx4(Paperclip, { className: "size-3 shrink-0" }),
1202
- /* @__PURE__ */ jsx4("span", { className: "max-w-[150px] truncate", children: file.name }),
1203
- file.fileCount !== void 0 && /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground", children: [
1204
- "(",
1205
- file.fileCount,
1206
- ")"
1207
- ] }),
1208
- file.status === "uploading" && /* @__PURE__ */ jsx4(Loader2, { className: "size-3 animate-spin" }),
1209
- onRemoveFile && /* @__PURE__ */ jsx4(
1210
- "button",
1211
- {
1212
- type: "button",
1213
- "aria-label": `Remove ${file.name}`,
1214
- onClick: () => onRemoveFile(file.id),
1215
- className: "rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
1216
- children: /* @__PURE__ */ jsx4(X, { className: "size-3" })
1217
- }
1218
- )
1219
- ]
1220
- },
1221
- file.id
1222
- )) }),
1302
+ attachments.length > 0 && /* @__PURE__ */ jsx4("div", { className: "flex flex-wrap gap-1.5", children: [...folderChips, ...fileChips].map((file) => {
1303
+ const isError = file.status === "error";
1304
+ const isPending = file.status === "pending";
1305
+ return /* @__PURE__ */ jsxs4(
1306
+ "span",
1307
+ {
1308
+ title: isError ? file.errorMessage : void 0,
1309
+ className: cn(
1310
+ "inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs",
1311
+ isError ? "border-[var(--status-error,#ff4d6d)]/40 text-[var(--status-error,#ff4d6d)]" : "border-[var(--md3-outline-variant)] bg-surface-container text-foreground",
1312
+ isPending && "opacity-60"
1313
+ ),
1314
+ children: [
1315
+ file.kind !== "folder" && file.previewUrl ? /* @__PURE__ */ jsx4(
1316
+ "img",
1317
+ {
1318
+ src: file.previewUrl,
1319
+ alt: "",
1320
+ className: "size-8 rounded object-cover"
1321
+ }
1322
+ ) : file.kind === "folder" ? /* @__PURE__ */ jsx4(Folder, { className: "size-3 shrink-0" }) : /* @__PURE__ */ jsx4(Paperclip, { className: "size-3 shrink-0" }),
1323
+ /* @__PURE__ */ jsx4("span", { className: "max-w-[150px] truncate", children: file.name }),
1324
+ file.fileCount !== void 0 && /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground", children: [
1325
+ "(",
1326
+ file.fileCount,
1327
+ ")"
1328
+ ] }),
1329
+ file.status === "uploading" && /* @__PURE__ */ jsx4(Loader2, { className: "size-3 animate-spin" }),
1330
+ isError && file.errorMessage && /* @__PURE__ */ jsx4("span", { className: "max-w-[150px] truncate text-[var(--status-error,#ff4d6d)]/80", children: file.errorMessage }),
1331
+ isError && onRetryFile && /* @__PURE__ */ jsx4(
1332
+ "button",
1333
+ {
1334
+ type: "button",
1335
+ "aria-label": `Retry upload ${file.name}`,
1336
+ onClick: () => onRetryFile(file.id),
1337
+ className: "rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
1338
+ children: /* @__PURE__ */ jsx4(RotateCcw, { className: "size-3" })
1339
+ }
1340
+ ),
1341
+ onRemoveFile && /* @__PURE__ */ jsx4(
1342
+ "button",
1343
+ {
1344
+ type: "button",
1345
+ "aria-label": `Remove ${file.name}`,
1346
+ onClick: () => onRemoveFile(file.id),
1347
+ className: "rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
1348
+ children: /* @__PURE__ */ jsx4(X, { className: "size-3" })
1349
+ }
1350
+ )
1351
+ ]
1352
+ },
1353
+ file.id
1354
+ );
1355
+ }) }),
1223
1356
  /* @__PURE__ */ jsx4(
1224
1357
  "textarea",
1225
1358
  {
@@ -1230,6 +1363,7 @@ function AgentComposer({
1230
1363
  autoFocus,
1231
1364
  onChange: (event) => onChange(event.target.value),
1232
1365
  onInput: (event) => resize(event.currentTarget),
1366
+ onPaste: handlePaste,
1233
1367
  onKeyDown: (event) => {
1234
1368
  if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing && event.keyCode !== 229) {
1235
1369
  event.preventDefault();
@@ -1277,7 +1411,8 @@ function AgentComposer({
1277
1411
  className: "hidden",
1278
1412
  accept,
1279
1413
  onChange: (event) => {
1280
- if (event.target.files?.length) onAttach(event.target.files);
1414
+ if (event.target.files?.length)
1415
+ deliverFiles(Array.from(event.target.files));
1281
1416
  event.target.value = "";
1282
1417
  }
1283
1418
  }
@@ -1700,6 +1835,8 @@ export {
1700
1835
  snapHarnessToModel,
1701
1836
  AgentProfilePicker,
1702
1837
  AgentSessionControls,
1838
+ isAcceptedType,
1839
+ validateComposerFiles,
1703
1840
  AgentComposer,
1704
1841
  ArtifactAgentDock,
1705
1842
  createFetchTransport,
@@ -3,10 +3,11 @@ import * as React from 'react';
3
3
  import { ReactNode } from 'react';
4
4
  import { HarnessType } from '@tangle-network/agent-interface';
5
5
  export { HarnessType } from '@tangle-network/agent-interface';
6
- export { D as DEFAULT_FEATURED_MODEL_IDS, M as ModelInfo, a as ModelPicker, b as ModelPickerProps, c as ModelPickerVariant, d as canonicalModelId, e as dedupeModels, f as formatContext, g as formatPricing, m as modelDedupKey } from './model-picker-COjPVMzg.js';
6
+ import * as Popover from '@radix-ui/react-dropdown-menu';
7
+ import { b as ModelInfo } from './model-brand-CsFykzMA.js';
8
+ export { M as ModelBrandIdentity, a as ModelBrandStack, c as canonicalModelId, m as modelBrandFor } from './model-brand-CsFykzMA.js';
7
9
  export { B as BillingBalance, a as BillingDashboard, b as BillingDashboardProps, c as BillingSubscription, d as BillingUsage, P as PricingPage, e as PricingPageProps, f as PricingTier, T as TemplateCard, g as TemplateCardData, h as TemplateCardProps, U as UsageChart, i as UsageChartProps, j as UsageDataPoint, k as formatPrice } from './template-card-UhV3pmRC.js';
8
10
  export { E as ExposedPort, P as PortsList, a as PortsListProps } from './ports-list-DfG0VfPt.js';
9
- import '@radix-ui/react-dropdown-menu';
10
11
 
11
12
  interface SidebarUser {
12
13
  email: string;
@@ -781,6 +782,82 @@ interface HarnessLogoProps {
781
782
  */
782
783
  declare function HarnessLogo({ type, size, className }: HarnessLogoProps): react_jsx_runtime.JSX.Element;
783
784
 
785
+ type ModelPickerVariant = "field" | "pill";
786
+ interface ModelPickerProps {
787
+ /** Canonical model id (provider-prefixed, e.g. "openai/gpt-5.4"). */
788
+ value: string;
789
+ onChange: (modelId: string) => void;
790
+ /** Models to choose from. Pass `[]` while loading. */
791
+ models: ModelInfo[];
792
+ /** Show the loading state (overrides empty-list copy). */
793
+ loading?: boolean;
794
+ /** Recently-used canonical ids to surface at the top. */
795
+ recents?: ReadonlyArray<string>;
796
+ /**
797
+ * Canonical model ids to surface in a "Popular" section above the full
798
+ * list. Each id is resolved against `models`; ids not present in the
799
+ * loaded catalog are silently skipped, so callers can pass a stable
800
+ * curation list without worrying about provider availability.
801
+ */
802
+ popular?: ReadonlyArray<string>;
803
+ /** Drop providers from the picker entirely (e.g. "audio", "embedding"). */
804
+ excludeProviders?: ReadonlyArray<string>;
805
+ /** Restrict to these architectures (e.g. ["text"]). Default: all. */
806
+ modalities?: ReadonlyArray<string>;
807
+ /** Trigger appearance. "field" = full-width form field; "pill" = inline chat input pill. */
808
+ variant?: ModelPickerVariant;
809
+ label?: string;
810
+ placeholder?: string;
811
+ className?: string;
812
+ /**
813
+ * Extra classes merged onto the trigger button itself (after the
814
+ * built-in defaults, so callers can override sizing/radius/font to
815
+ * match a surrounding form). Distinct from `className`, which on the
816
+ * "field" variant styles the outer wrapper.
817
+ */
818
+ triggerClassName?: string;
819
+ disabled?: boolean;
820
+ /** Side the menu opens toward. Defaults to Radix's "bottom". */
821
+ side?: Popover.DropdownMenuContentProps["side"];
822
+ /**
823
+ * Let Radix flip the menu to the opposite side when it would overflow the
824
+ * viewport. Defaults to `true` (Radix default). Pass `false` to pin the menu
825
+ * to `side` — e.g. a composer floating in open space that should always open
826
+ * downward rather than flipping up over the heading.
827
+ */
828
+ avoidCollisions?: boolean;
829
+ }
830
+ /**
831
+ * Stable key used to collapse catalog duplicates. The Tangle Router lists the
832
+ * same underlying model under several host prefixes (e.g. `openai/gpt-5.4`,
833
+ * `tcloud/gpt-5.4`, `openrouter/openai/gpt-5.4`); they all name one model and
834
+ * should occupy a single row. The key is `<lab>/<model-id>`: the authoring lab
835
+ * (inferred via {@link resolveModelBrandIdentity}, which already maps
836
+ * `gpt-5.4` → openai, `kimi-k2` → moonshot, etc.) plus the final id segment,
837
+ * so a model collapses to one identity regardless of which host serves it.
838
+ */
839
+ declare function modelDedupKey(model: ModelInfo): string;
840
+ /**
841
+ * Collapse catalog duplicates to one row per {@link modelDedupKey}. When a
842
+ * model is served under multiple hosts the preferred row wins: a `featured`
843
+ * row beats a non-featured one, otherwise the first occurrence is kept (so
844
+ * caller-controlled catalog order still decides ties). Input order is
845
+ * preserved for the surviving rows.
846
+ */
847
+ declare function dedupeModels(models: ReadonlyArray<ModelInfo>): ModelInfo[];
848
+ /**
849
+ * Fallback "Recommended" seed — latest frontier models per major lab, matched
850
+ * by {@link modelDedupKey} against the loaded catalog. Used only when no
851
+ * catalog row carries an explicit `featured` flag, so a standard router
852
+ * catalog still gets a curated top section without per-deployment config.
853
+ */
854
+ declare const DEFAULT_FEATURED_MODEL_IDS: ReadonlyArray<string>;
855
+ /** Format $/M tokens. Returns null if pricing is missing or zero. */
856
+ declare function formatPricing(pricing: ModelInfo["pricing"]): string | null;
857
+ /** Format context length compactly (e.g. 200_000 → "200k"). */
858
+ declare function formatContext(ctx: number | undefined): string | null;
859
+ declare function ModelPicker({ value, onChange, models, loading, recents, popular, excludeProviders, modalities, variant, label, placeholder, className, triggerClassName, disabled, side, avoidCollisions, }: ModelPickerProps): react_jsx_runtime.JSX.Element;
860
+
784
861
  type ProductVariant = "sandbox";
785
862
  interface NavItem {
786
863
  id: string;
@@ -1269,4 +1346,4 @@ interface InfoPanelProps {
1269
1346
  }
1270
1347
  declare function InfoPanel({ label, title, description, className }: InfoPanelProps): react_jsx_runtime.JSX.Element;
1271
1348
 
1272
- export { ActivityFeed, type ActivityFeedProps, type ActivityItem, type AppearanceController, type Backend, BackendConfig, type BackendConfigProps, BackendSelector, type BackendSelectorProps, type BackendStatusData, ClusterStatusBar, type ClusterStatusBarProps, type ClusterStatusItem, CreditBalance, type CreditBalanceProps, DashboardLayout, type DashboardLayoutProps, type Profile as DashboardProfile, type SnapshotInfo as DashboardSnapshotInfo, type DashboardUser, type GitCommitData, GitPanel, type GitPanelProps, type GitStatusData, HARNESS_BRAND, HARNESS_OPTIONS, type HarnessBrand, HarnessLogo, type HarnessLogoProps, HarnessPicker, type HarnessPickerProps, INSUFFICIENT_BALANCE_CODE, InfoPanel, type InfoPanelProps, type InsufficientBalance, type Invoice, InvoiceTable, type InvoiceTableProps, type McpServer, MetricAreaChart, type MetricAreaChartProps, type MetricChartPoint, type MetricChartTone, type NavItem, NetworkConfig, type NetworkConfigData, type NetworkConfigProps, NewSandboxCard, type NewSandboxCardProps, OutOfCreditsModal, type OutOfCreditsModalProps, type PlanCardData, PlanCards, type PlanCardsProps, type PlanFeature, type ProcessInfo, ProcessList, type ProcessListProps, type ProductVariant, ProfileAvatar, type ProfileAvatarProps, ProfileComparison, type ProfileComparisonProps, ProfileSelector, type ProfileSelectorProps, PromoBanner, type PromoBannerProps, RailButton, type RailButtonProps, RailCollapseToggle, type RailCollapseToggleProps, RailExpandable, type RailExpandableProps, type RailExpandableSubItem, RailFlyout, type RailFlyoutProps, RailHeader, type RailHeaderProps, RailModeButton, type RailModeButtonProps, RailSeparator, type RailSeparatorProps, RailThemeToggle, RailTooltip, type RailTooltipProps, ResourceMeter, type ResourceMeterProps, ResourceSnapshot, type ResourceSnapshotItem, type ResourceSnapshotProps, SIDEBAR_MOBILE_WIDTH, SIDEBAR_PANEL_WIDTH, SIDEBAR_RAIL_LABELED_WIDTH, SIDEBAR_RAIL_WIDTH, SIDEBAR_TOTAL_WIDTH, SandboxCard, type SandboxCardData, type SandboxCardProps, type SandboxStatus, SandboxTable, type SandboxTableProps, Sidebar, SidebarContent, type SidebarContentProps, SidebarLayout, type SidebarLayoutFlyoutItem, type SidebarLayoutNavItem, type SidebarLayoutProps, SidebarPanel, SidebarPanelContent, type SidebarPanelContentProps, SidebarPanelHeader, type SidebarPanelHeaderProps, type SidebarPanelProps, type SidebarProps, SidebarProvider, type SidebarProviderProps, SidebarRail, SidebarRailFooter, type SidebarRailFooterProps, SidebarRailHeader, type SidebarRailHeaderProps, SidebarRailNav, type SidebarRailNavProps, type SidebarRailProps, type SidebarUser, SnapshotList, type SnapshotListProps, SystemLogsViewer, type SystemLogsViewerProps, type TeamRole, type ThemeMode, UsageSummary, type UsageSummaryData, type UsageSummaryProps, type Variant, VariantList, type VariantListProps, type VariantOutcome, type VariantStatus, canAdminSandbox, chatCapableHarnesses, parseInsufficientBalance, useSidebar };
1349
+ export { ActivityFeed, type ActivityFeedProps, type ActivityItem, type AppearanceController, type Backend, BackendConfig, type BackendConfigProps, BackendSelector, type BackendSelectorProps, type BackendStatusData, ClusterStatusBar, type ClusterStatusBarProps, type ClusterStatusItem, CreditBalance, type CreditBalanceProps, DEFAULT_FEATURED_MODEL_IDS, DashboardLayout, type DashboardLayoutProps, type Profile as DashboardProfile, type SnapshotInfo as DashboardSnapshotInfo, type DashboardUser, type GitCommitData, GitPanel, type GitPanelProps, type GitStatusData, HARNESS_BRAND, HARNESS_OPTIONS, type HarnessBrand, HarnessLogo, type HarnessLogoProps, HarnessPicker, type HarnessPickerProps, INSUFFICIENT_BALANCE_CODE, InfoPanel, type InfoPanelProps, type InsufficientBalance, type Invoice, InvoiceTable, type InvoiceTableProps, type McpServer, MetricAreaChart, type MetricAreaChartProps, type MetricChartPoint, type MetricChartTone, ModelInfo, ModelPicker, type ModelPickerProps, type ModelPickerVariant, type NavItem, NetworkConfig, type NetworkConfigData, type NetworkConfigProps, NewSandboxCard, type NewSandboxCardProps, OutOfCreditsModal, type OutOfCreditsModalProps, type PlanCardData, PlanCards, type PlanCardsProps, type PlanFeature, type ProcessInfo, ProcessList, type ProcessListProps, type ProductVariant, ProfileAvatar, type ProfileAvatarProps, ProfileComparison, type ProfileComparisonProps, ProfileSelector, type ProfileSelectorProps, PromoBanner, type PromoBannerProps, RailButton, type RailButtonProps, RailCollapseToggle, type RailCollapseToggleProps, RailExpandable, type RailExpandableProps, type RailExpandableSubItem, RailFlyout, type RailFlyoutProps, RailHeader, type RailHeaderProps, RailModeButton, type RailModeButtonProps, RailSeparator, type RailSeparatorProps, RailThemeToggle, RailTooltip, type RailTooltipProps, ResourceMeter, type ResourceMeterProps, ResourceSnapshot, type ResourceSnapshotItem, type ResourceSnapshotProps, SIDEBAR_MOBILE_WIDTH, SIDEBAR_PANEL_WIDTH, SIDEBAR_RAIL_LABELED_WIDTH, SIDEBAR_RAIL_WIDTH, SIDEBAR_TOTAL_WIDTH, SandboxCard, type SandboxCardData, type SandboxCardProps, type SandboxStatus, SandboxTable, type SandboxTableProps, Sidebar, SidebarContent, type SidebarContentProps, SidebarLayout, type SidebarLayoutFlyoutItem, type SidebarLayoutNavItem, type SidebarLayoutProps, SidebarPanel, SidebarPanelContent, type SidebarPanelContentProps, SidebarPanelHeader, type SidebarPanelHeaderProps, type SidebarPanelProps, type SidebarProps, SidebarProvider, type SidebarProviderProps, SidebarRail, SidebarRailFooter, type SidebarRailFooterProps, SidebarRailHeader, type SidebarRailHeaderProps, SidebarRailNav, type SidebarRailNavProps, type SidebarRailProps, type SidebarUser, SnapshotList, type SnapshotListProps, SystemLogsViewer, type SystemLogsViewerProps, type TeamRole, type ThemeMode, UsageSummary, type UsageSummaryData, type UsageSummaryProps, type Variant, VariantList, type VariantListProps, type VariantOutcome, type VariantStatus, canAdminSandbox, chatCapableHarnesses, dedupeModels, formatContext, formatPricing, modelDedupKey, parseInsufficientBalance, useSidebar };
package/dist/dashboard.js CHANGED
@@ -71,16 +71,20 @@ import {
71
71
  HarnessLogo,
72
72
  HarnessPicker,
73
73
  chatCapableHarnesses
74
- } from "./chunk-IWIZ7RZE.js";
74
+ } from "./chunk-2T6KBMLN.js";
75
75
  import {
76
76
  DEFAULT_FEATURED_MODEL_IDS,
77
77
  ModelPicker,
78
- canonicalModelId,
79
78
  dedupeModels,
80
79
  formatContext,
81
80
  formatPricing,
82
81
  modelDedupKey
83
- } from "./chunk-L62ZT6RS.js";
82
+ } from "./chunk-R4AR3TKR.js";
83
+ import {
84
+ ModelBrandStack,
85
+ canonicalModelId,
86
+ modelBrandFor
87
+ } from "./chunk-I3G23XHN.js";
84
88
  import "./chunk-EI44GEQ5.js";
85
89
  import "./chunk-U67V476Y.js";
86
90
  export {
@@ -101,6 +105,7 @@ export {
101
105
  InfoPanel,
102
106
  InvoiceTable,
103
107
  MetricAreaChart,
108
+ ModelBrandStack,
104
109
  ModelPicker,
105
110
  NetworkConfig,
106
111
  NewSandboxCard,
@@ -155,6 +160,7 @@ export {
155
160
  formatContext,
156
161
  formatPrice,
157
162
  formatPricing,
163
+ modelBrandFor,
158
164
  modelDedupKey,
159
165
  parseInsufficientBalance,
160
166
  useSidebar
package/dist/globals.css CHANGED
@@ -444,6 +444,9 @@
444
444
  .left-full {
445
445
  left: 100%;
446
446
  }
447
+ .isolate {
448
+ isolation: isolate;
449
+ }
447
450
  .z-0 {
448
451
  z-index: 0;
449
452
  }
@@ -3185,6 +3188,12 @@
3185
3188
  .text-\[var\(--status-error\,\#ff4d6d\)\] {
3186
3189
  color: var(--status-error,#ff4d6d);
3187
3190
  }
3191
+ .text-\[var\(--status-error\,\#ff4d6d\)\]\/80 {
3192
+ color: var(--status-error,#ff4d6d);
3193
+ @supports (color: color-mix(in lab, red, red)) {
3194
+ color: color-mix(in oklab, var(--status-error,#ff4d6d) 80%, transparent);
3195
+ }
3196
+ }
3188
3197
  .text-\[var\(--surface-danger-text\)\] {
3189
3198
  color: var(--surface-danger-text);
3190
3199
  }
package/dist/index.d.ts CHANGED
@@ -5,12 +5,11 @@ export { AgentWorkbench, ApprovalConfidenceStat, ApprovalItem, ApprovalQueue, Ap
5
5
  export { ArtifactView, BRAND_PRISM_THEME, CodeSurface, CodeSurfaceProps, CodeView, CodeViewProps, DiffStats, DiffView, DiffViewProps, FileBreadcrumb, FileBreadcrumbProps, GitStatusBadge, PanelHeader, PanelHeaderProps, PillTabItem, PillTabs, PillTabsProps, PreviewView, PreviewViewProps, SandboxArtifact, SandboxArtifactPane, SandboxArtifactPaneProps, SandboxArtifactTerminal, buildUnifiedPatch, computeDiffStats, resolveLanguage } from './workbench.js';
6
6
  export { OpenUIAction, OpenUIActionsNode, OpenUIArtifactRenderer, OpenUIArtifactRendererProps, OpenUIBadgeNode, OpenUICardNode, OpenUICodeNode, OpenUIComponentNode, OpenUIGridNode, OpenUIHeadingNode, OpenUIKeyValueNode, OpenUIMarkdownNode, OpenUIPrimitive, OpenUISeparatorNode, OpenUIStackNode, OpenUIStatNode, OpenUITableNode, OpenUITextNode } from '@tangle-network/ui/openui';
7
7
  export { AgentTimeline, AgentTimelineArtifactItem, AgentTimelineCustomItem, AgentTimelineItem, AgentTimelineMessageItem, AgentTimelineProps, AgentTimelineStatusItem, AgentTimelineTone, AgentTimelineToolGroupItem, AgentTimelineToolItem, ChatContainer, ChatContainerProps, ChatMessage, ChatMessageProps, MessageList, MessageListProps, MessageRole, ThinkingIndicator, ThinkingIndicatorProps, UserMessage, UserMessageProps } from '@tangle-network/ui/chat';
8
- export { AgentComposer, AgentComposerProps, AgentProfileCapability, AgentProfileDraft, AgentProfileOption, AgentProfilePicker, AgentProfilePickerProps, AgentSessionControls, AgentSessionControlsProps, AgentSessionHarnessControl, AgentSessionModelControl, AgentSessionProfileControl, AgentSessionReasoningControl, ArtifactAgentDock, ArtifactAgentDockProps, ArtifactAgentDockTransport, ArtifactDockMessage, ArtifactDockStreamEvent, ArtifactKind, ArtifactScope, ComposerFile, DEFAULT_REASONING_LEVEL_OPTIONS, HARNESS_REASONING_OPTIONS, ReasoningLevel, ReasoningLevelOption, ReasoningLevelPicker, ReasoningLevelPickerProps, createFetchTransport, isModelCompatibleWithHarness, snapModelToHarness } from './chat.js';
8
+ export { AgentComposer, AgentComposerProps, AgentProfileCapability, AgentProfileDraft, AgentProfileOption, AgentProfilePicker, AgentProfilePickerProps, AgentSessionControls, AgentSessionControlsProps, AgentSessionHarnessControl, AgentSessionModelControl, AgentSessionProfileControl, AgentSessionReasoningControl, ArtifactAgentDock, ArtifactAgentDockProps, ArtifactAgentDockTransport, ArtifactDockMessage, ArtifactDockStreamEvent, ArtifactKind, ArtifactScope, ComposerFile, ComposerFileRejection, ComposerFileValidationConfig, DEFAULT_REASONING_LEVEL_OPTIONS, HARNESS_REASONING_OPTIONS, ReasoningLevel, ReasoningLevelOption, ReasoningLevelPicker, ReasoningLevelPickerProps, createFetchTransport, isAcceptedType, isModelCompatibleWithHarness, snapModelToHarness, validateComposerFiles } from './chat.js';
9
9
  export { ExpandedToolDetail, ExpandedToolDetailProps, InlineThinkingItem, InlineThinkingItemProps, InlineToolItem, InlineToolItemProps, LiveDuration, RunGroup, RunGroupProps } from '@tangle-network/ui/run';
10
10
  export { CommandPreview, DiffPreview, GlobResultsPreview, GrepResultsPreview, QuestionPreview, WebSearchPreview, WriteFilePreview } from '@tangle-network/ui/tool-previews';
11
11
  export { FileArtifactPane, FileArtifactPaneProps, FileNode, FilePreview, FilePreviewProps, FileTabData, FileTabs, FileTabsProps, FileTree, FileTreeProps, FileTreeVisibilityOptions, RichFileTree, RichFileTreeGitEntry, RichFileTreeGitStatus, RichFileTreeProps, RichFileTreeThemeVars, filterFileTree } from '@tangle-network/ui/files';
12
- export { ActivityFeed, ActivityFeedProps, ActivityItem, AppearanceController, Backend, BackendConfig, BackendConfigProps, BackendSelector, BackendSelectorProps, BackendStatusData, ClusterStatusBar, ClusterStatusBarProps, ClusterStatusItem, CreditBalance, CreditBalanceProps, DashboardLayout, DashboardLayoutProps, DashboardProfile, DashboardSnapshotInfo, DashboardUser, GitCommitData, GitPanel, GitPanelProps, GitStatusData, HARNESS_BRAND, HARNESS_OPTIONS, HarnessBrand, HarnessLogo, HarnessLogoProps, HarnessPicker, HarnessPickerProps, INSUFFICIENT_BALANCE_CODE, InfoPanel, InfoPanelProps, InsufficientBalance, Invoice, InvoiceTable, InvoiceTableProps, McpServer, MetricAreaChart, MetricAreaChartProps, MetricChartPoint, MetricChartTone, NavItem, NetworkConfig, NetworkConfigData, NetworkConfigProps, NewSandboxCard, NewSandboxCardProps, OutOfCreditsModal, OutOfCreditsModalProps, PlanCardData, PlanCards, PlanCardsProps, PlanFeature, ProcessInfo, ProcessList, ProcessListProps, ProductVariant, ProfileAvatar, ProfileAvatarProps, ProfileComparison, ProfileComparisonProps, ProfileSelector, ProfileSelectorProps, PromoBanner, PromoBannerProps, RailButton, RailButtonProps, RailCollapseToggle, RailCollapseToggleProps, RailExpandable, RailExpandableProps, RailExpandableSubItem, RailFlyout, RailFlyoutProps, RailHeader, RailHeaderProps, RailModeButton, RailModeButtonProps, RailSeparator, RailSeparatorProps, RailThemeToggle, RailTooltip, RailTooltipProps, ResourceMeter, ResourceMeterProps, ResourceSnapshot, ResourceSnapshotItem, ResourceSnapshotProps, SIDEBAR_MOBILE_WIDTH, SIDEBAR_PANEL_WIDTH, SIDEBAR_RAIL_LABELED_WIDTH, SIDEBAR_RAIL_WIDTH, SIDEBAR_TOTAL_WIDTH, SandboxCard, SandboxCardData, SandboxCardProps, SandboxStatus, SandboxTable, SandboxTableProps, Sidebar, SidebarContent, SidebarContentProps, SidebarLayout, SidebarLayoutFlyoutItem, SidebarLayoutNavItem, SidebarLayoutProps, SidebarPanel, SidebarPanelContent, SidebarPanelContentProps, SidebarPanelHeader, SidebarPanelHeaderProps, SidebarPanelProps, SidebarProps, SidebarProvider, SidebarProviderProps, SidebarRail, SidebarRailFooter, SidebarRailFooterProps, SidebarRailHeader, SidebarRailHeaderProps, SidebarRailNav, SidebarRailNavProps, SidebarRailProps, SidebarUser, SnapshotList, SnapshotListProps, SystemLogsViewer, SystemLogsViewerProps, TeamRole, ThemeMode, UsageSummary, UsageSummaryData, UsageSummaryProps, Variant, VariantList, VariantListProps, VariantOutcome, VariantStatus, canAdminSandbox, chatCapableHarnesses, parseInsufficientBalance, useSidebar } from './dashboard.js';
13
- export { D as DEFAULT_FEATURED_MODEL_IDS, M as ModelInfo, a as ModelPicker, b as ModelPickerProps, c as ModelPickerVariant, d as canonicalModelId, e as dedupeModels, f as formatContext, g as formatPricing, m as modelDedupKey } from './model-picker-COjPVMzg.js';
12
+ export { ActivityFeed, ActivityFeedProps, ActivityItem, AppearanceController, Backend, BackendConfig, BackendConfigProps, BackendSelector, BackendSelectorProps, BackendStatusData, ClusterStatusBar, ClusterStatusBarProps, ClusterStatusItem, CreditBalance, CreditBalanceProps, DEFAULT_FEATURED_MODEL_IDS, DashboardLayout, DashboardLayoutProps, DashboardProfile, DashboardSnapshotInfo, DashboardUser, GitCommitData, GitPanel, GitPanelProps, GitStatusData, HARNESS_BRAND, HARNESS_OPTIONS, HarnessBrand, HarnessLogo, HarnessLogoProps, HarnessPicker, HarnessPickerProps, INSUFFICIENT_BALANCE_CODE, InfoPanel, InfoPanelProps, InsufficientBalance, Invoice, InvoiceTable, InvoiceTableProps, McpServer, MetricAreaChart, MetricAreaChartProps, MetricChartPoint, MetricChartTone, ModelPicker, ModelPickerProps, ModelPickerVariant, NavItem, NetworkConfig, NetworkConfigData, NetworkConfigProps, NewSandboxCard, NewSandboxCardProps, OutOfCreditsModal, OutOfCreditsModalProps, PlanCardData, PlanCards, PlanCardsProps, PlanFeature, ProcessInfo, ProcessList, ProcessListProps, ProductVariant, ProfileAvatar, ProfileAvatarProps, ProfileComparison, ProfileComparisonProps, ProfileSelector, ProfileSelectorProps, PromoBanner, PromoBannerProps, RailButton, RailButtonProps, RailCollapseToggle, RailCollapseToggleProps, RailExpandable, RailExpandableProps, RailExpandableSubItem, RailFlyout, RailFlyoutProps, RailHeader, RailHeaderProps, RailModeButton, RailModeButtonProps, RailSeparator, RailSeparatorProps, RailThemeToggle, RailTooltip, RailTooltipProps, ResourceMeter, ResourceMeterProps, ResourceSnapshot, ResourceSnapshotItem, ResourceSnapshotProps, SIDEBAR_MOBILE_WIDTH, SIDEBAR_PANEL_WIDTH, SIDEBAR_RAIL_LABELED_WIDTH, SIDEBAR_RAIL_WIDTH, SIDEBAR_TOTAL_WIDTH, SandboxCard, SandboxCardData, SandboxCardProps, SandboxStatus, SandboxTable, SandboxTableProps, Sidebar, SidebarContent, SidebarContentProps, SidebarLayout, SidebarLayoutFlyoutItem, SidebarLayoutNavItem, SidebarLayoutProps, SidebarPanel, SidebarPanelContent, SidebarPanelContentProps, SidebarPanelHeader, SidebarPanelHeaderProps, SidebarPanelProps, SidebarProps, SidebarProvider, SidebarProviderProps, SidebarRail, SidebarRailFooter, SidebarRailFooterProps, SidebarRailHeader, SidebarRailHeaderProps, SidebarRailNav, SidebarRailNavProps, SidebarRailProps, SidebarUser, SnapshotList, SnapshotListProps, SystemLogsViewer, SystemLogsViewerProps, TeamRole, ThemeMode, UsageSummary, UsageSummaryData, UsageSummaryProps, Variant, VariantList, VariantListProps, VariantOutcome, VariantStatus, canAdminSandbox, chatCapableHarnesses, dedupeModels, formatContext, formatPricing, modelDedupKey, parseInsufficientBalance, useSidebar } from './dashboard.js';
14
13
  export { B as BillingBalance, a as BillingDashboard, b as BillingDashboardProps, c as BillingSubscription, d as BillingUsage, P as PricingPage, e as PricingPageProps, f as PricingTier, T as TemplateCard, g as TemplateCardData, h as TemplateCardProps, U as UsageChart, i as UsageChartProps, j as UsageDataPoint, k as formatPrice } from './template-card-UhV3pmRC.js';
15
14
  export { E as ExposedPort, P as PortsList, a as PortsListProps } from './ports-list-DfG0VfPt.js';
16
15
  export { AuthHeader, AuthHeaderProps, GitHubLoginButton, GitHubLoginButtonProps, LoginLayout, LoginLayoutProps, SessionUser, UserMenu, UserMenuProps } from '@tangle-network/ui/auth';
@@ -24,6 +23,7 @@ export { AgentBranding, CustomToolRenderer, DisplayVariant, FinalTextPart, Group
24
23
  export { Session } from './types.js';
25
24
  export { TOOL_CATEGORY_ICONS, cn, copyText, formatBytes, formatDuration, formatUptime, getToolCategory, getToolDisplayMetadata, getToolErrorText, timeAgo, truncateText } from '@tangle-network/ui/utils';
26
25
  export { HarnessType, modelProvider, snapHarnessToModel } from '@tangle-network/agent-interface';
26
+ export { M as ModelBrandIdentity, a as ModelBrandStack, b as ModelInfo, c as canonicalModelId, m as modelBrandFor } from './model-brand-CsFykzMA.js';
27
27
  import 'react/jsx-runtime';
28
28
  import 'react';
29
29
  import '@radix-ui/react-dropdown-menu';
package/dist/index.js CHANGED
@@ -63,19 +63,6 @@ import {
63
63
  useTotalRunningSessions
64
64
  } from "./chunk-WID73FPH.js";
65
65
  import "./chunk-2BUPSB7O.js";
66
- import {
67
- TOOL_CATEGORY_ICONS,
68
- cn,
69
- copyText,
70
- formatBytes,
71
- formatDuration,
72
- formatUptime,
73
- getToolCategory,
74
- getToolDisplayMetadata,
75
- getToolErrorText,
76
- timeAgo,
77
- truncateText
78
- } from "./chunk-TK46XFLM.js";
79
66
  import {
80
67
  AuthHeader,
81
68
  GitHubLoginButton,
@@ -98,11 +85,26 @@ import {
98
85
  ThinkingIndicator,
99
86
  UserMessage,
100
87
  createFetchTransport,
88
+ isAcceptedType,
101
89
  isModelCompatibleWithHarness,
102
90
  modelProvider,
103
91
  snapHarnessToModel,
104
- snapModelToHarness
105
- } from "./chunk-UQXDIQWD.js";
92
+ snapModelToHarness,
93
+ validateComposerFiles
94
+ } from "./chunk-YBFGWPUF.js";
95
+ import {
96
+ TOOL_CATEGORY_ICONS,
97
+ cn,
98
+ copyText,
99
+ formatBytes,
100
+ formatDuration,
101
+ formatUptime,
102
+ getToolCategory,
103
+ getToolDisplayMetadata,
104
+ getToolErrorText,
105
+ timeAgo,
106
+ truncateText
107
+ } from "./chunk-TK46XFLM.js";
106
108
  import {
107
109
  ExpandedToolDetail,
108
110
  InlineThinkingItem,
@@ -318,16 +320,20 @@ import {
318
320
  HarnessLogo,
319
321
  HarnessPicker,
320
322
  chatCapableHarnesses
321
- } from "./chunk-IWIZ7RZE.js";
323
+ } from "./chunk-2T6KBMLN.js";
322
324
  import {
323
325
  DEFAULT_FEATURED_MODEL_IDS,
324
326
  ModelPicker,
325
- canonicalModelId,
326
327
  dedupeModels,
327
328
  formatContext,
328
329
  formatPricing,
329
330
  modelDedupKey
330
- } from "./chunk-L62ZT6RS.js";
331
+ } from "./chunk-R4AR3TKR.js";
332
+ import {
333
+ ModelBrandStack,
334
+ canonicalModelId,
335
+ modelBrandFor
336
+ } from "./chunk-I3G23XHN.js";
331
337
  import "./chunk-EI44GEQ5.js";
332
338
  import {
333
339
  OpenUIArtifactRenderer
@@ -452,6 +458,7 @@ export {
452
458
  Markdown,
453
459
  MessageList,
454
460
  MetricAreaChart,
461
+ ModelBrandStack,
455
462
  ModelPicker,
456
463
  NetworkConfig,
457
464
  NewSandboxCard,
@@ -605,9 +612,11 @@ export {
605
612
  getToolErrorText,
606
613
  getTotalRunningSessionCount,
607
614
  hasBackgroundRunningSessions,
615
+ isAcceptedType,
608
616
  isModelCompatibleWithHarness,
609
617
  isStreamingAtom,
610
618
  messagesAtom,
619
+ modelBrandFor,
611
620
  modelDedupKey,
612
621
  modelProvider,
613
622
  parseInsufficientBalance,
@@ -660,5 +669,6 @@ export {
660
669
  useTheme,
661
670
  useToast,
662
671
  useToolCallStream,
663
- useTotalRunningSessions
672
+ useTotalRunningSessions,
673
+ validateComposerFiles
664
674
  };