@burtson-labs/bandit-engine 2.1.5 → 2.1.7
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/CHANGELOG.md +15 -0
- package/dist/{ProjectsPane-BSVOVNK7.mjs → ProjectsPane-E5D72PUG.mjs} +4 -4
- package/dist/{SchedulesTab-TCUOAKLH.mjs → SchedulesTab-AKJ6WFZV.mjs} +3 -3
- package/dist/{chat-Y7KPN54G.mjs → chat-MI4IL3WK.mjs} +7 -6
- package/dist/{chunk-4257FVLK.mjs → chunk-2HFSBPOE.mjs} +6 -1
- package/dist/chunk-2HFSBPOE.mjs.map +1 -0
- package/dist/{chunk-XGIQNHUO.mjs → chunk-4NHPLHXU.mjs} +816 -394
- package/dist/chunk-4NHPLHXU.mjs.map +1 -0
- package/dist/{chunk-SK7FSLCY.mjs → chunk-4NUQYUZH.mjs} +7 -2
- package/dist/chunk-4NUQYUZH.mjs.map +1 -0
- package/dist/{chunk-ZG66NJC3.mjs → chunk-5URP2E5V.mjs} +3 -6
- package/dist/chunk-5URP2E5V.mjs.map +1 -0
- package/dist/{chunk-IXD2TDA5.mjs → chunk-SQJ4OKWM.mjs} +2 -2
- package/dist/chunk-WBKTQJNX.mjs +21 -0
- package/dist/chunk-WBKTQJNX.mjs.map +1 -0
- package/dist/image-compare-NW5VCP4Q.mjs +74 -0
- package/dist/image-compare-NW5VCP4Q.mjs.map +1 -0
- package/dist/image-edit-acknowledgement-RZPQYKYJ.mjs +54 -0
- package/dist/image-edit-acknowledgement-RZPQYKYJ.mjs.map +1 -0
- package/dist/index.d.mts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +5758 -5120
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +365 -340
- package/dist/index.mjs.map +1 -1
- package/dist/{schedule-confirm-card-7CMATYSP.mjs → schedule-confirm-card-D4K76HEA.mjs} +5 -5
- package/package.json +1 -1
- package/dist/chunk-4257FVLK.mjs.map +0 -1
- package/dist/chunk-SK7FSLCY.mjs.map +0 -1
- package/dist/chunk-XGIQNHUO.mjs.map +0 -1
- package/dist/chunk-ZG66NJC3.mjs.map +0 -1
- /package/dist/{ProjectsPane-BSVOVNK7.mjs.map → ProjectsPane-E5D72PUG.mjs.map} +0 -0
- /package/dist/{SchedulesTab-TCUOAKLH.mjs.map → SchedulesTab-AKJ6WFZV.mjs.map} +0 -0
- /package/dist/{chat-Y7KPN54G.mjs.map → chat-MI4IL3WK.mjs.map} +0 -0
- /package/dist/{chunk-IXD2TDA5.mjs.map → chunk-SQJ4OKWM.mjs.map} +0 -0
- /package/dist/{schedule-confirm-card-7CMATYSP.mjs.map → schedule-confirm-card-D4K76HEA.mjs.map} +0 -0
|
@@ -1,3 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AlertCircle as AlertCircle2,
|
|
3
|
+
AlertTriangle,
|
|
4
|
+
ArrowDown,
|
|
5
|
+
ArrowUp,
|
|
6
|
+
Braces,
|
|
7
|
+
Check as Check2,
|
|
8
|
+
CloudOff,
|
|
9
|
+
CloudSync,
|
|
10
|
+
Code,
|
|
11
|
+
Copy as Copy2,
|
|
12
|
+
Download as Download2,
|
|
13
|
+
EarOff,
|
|
14
|
+
EditSquare,
|
|
15
|
+
FilePdf,
|
|
16
|
+
FileText as FileText2,
|
|
17
|
+
Ghost as Ghost2,
|
|
18
|
+
Info,
|
|
19
|
+
Lock,
|
|
20
|
+
MarkdownImage,
|
|
21
|
+
Maximize,
|
|
22
|
+
MemoryLayers,
|
|
23
|
+
Mic as Mic2,
|
|
24
|
+
Minimize,
|
|
25
|
+
PanelLeft,
|
|
26
|
+
Pin,
|
|
27
|
+
PinOff,
|
|
28
|
+
Plus as Plus2,
|
|
29
|
+
Search as Search2,
|
|
30
|
+
Sparkles,
|
|
31
|
+
Square as Square2,
|
|
32
|
+
StreamingMarkdown_default,
|
|
33
|
+
Trash as Trash2,
|
|
34
|
+
Type,
|
|
35
|
+
Waveform as Waveform2,
|
|
36
|
+
Wifi,
|
|
37
|
+
WifiOff,
|
|
38
|
+
X as X2,
|
|
39
|
+
ZoomIn,
|
|
40
|
+
ZoomOut,
|
|
41
|
+
getHighlightTree,
|
|
42
|
+
markdownSanitizeSchema,
|
|
43
|
+
maybeHandleFileLinkClick,
|
|
44
|
+
renderLowlightChildren
|
|
45
|
+
} from "./chunk-4NUQYUZH.mjs";
|
|
1
46
|
import {
|
|
2
47
|
GatewayService,
|
|
3
48
|
readContextSourcesField,
|
|
@@ -56,15 +101,23 @@ import {
|
|
|
56
101
|
useSectionsLayout,
|
|
57
102
|
useSidebarStore,
|
|
58
103
|
writePersistedCollapsed
|
|
59
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-SQJ4OKWM.mjs";
|
|
60
105
|
import {
|
|
61
106
|
indexedDBService_default,
|
|
62
107
|
useModelStore,
|
|
63
108
|
usePreferencesStore
|
|
64
109
|
} from "./chunk-KWOUXBSF.mjs";
|
|
110
|
+
import {
|
|
111
|
+
useImageEditAckStore
|
|
112
|
+
} from "./chunk-WBKTQJNX.mjs";
|
|
65
113
|
import {
|
|
66
114
|
useScheduleConfirmStore
|
|
67
115
|
} from "./chunk-HS62C62A.mjs";
|
|
116
|
+
import {
|
|
117
|
+
browserTimeZone,
|
|
118
|
+
formatInZone,
|
|
119
|
+
normalizeScheduleArgs
|
|
120
|
+
} from "./chunk-MAKXJD7A.mjs";
|
|
68
121
|
import {
|
|
69
122
|
Activity,
|
|
70
123
|
Agent,
|
|
@@ -123,57 +176,7 @@ import {
|
|
|
123
176
|
Waveform,
|
|
124
177
|
Wrench,
|
|
125
178
|
X
|
|
126
|
-
} from "./chunk-
|
|
127
|
-
import {
|
|
128
|
-
AlertCircle as AlertCircle2,
|
|
129
|
-
AlertTriangle,
|
|
130
|
-
ArrowDown,
|
|
131
|
-
ArrowUp,
|
|
132
|
-
Braces,
|
|
133
|
-
Check as Check2,
|
|
134
|
-
CloudOff,
|
|
135
|
-
CloudSync,
|
|
136
|
-
Code,
|
|
137
|
-
Copy as Copy2,
|
|
138
|
-
Download as Download2,
|
|
139
|
-
EarOff,
|
|
140
|
-
EditSquare,
|
|
141
|
-
FilePdf,
|
|
142
|
-
FileText as FileText2,
|
|
143
|
-
Ghost as Ghost2,
|
|
144
|
-
Info,
|
|
145
|
-
Lock,
|
|
146
|
-
MarkdownImage,
|
|
147
|
-
Maximize,
|
|
148
|
-
MemoryLayers,
|
|
149
|
-
Mic as Mic2,
|
|
150
|
-
Minimize,
|
|
151
|
-
PanelLeft,
|
|
152
|
-
Pin,
|
|
153
|
-
PinOff,
|
|
154
|
-
Plus as Plus2,
|
|
155
|
-
Search as Search2,
|
|
156
|
-
Sparkles,
|
|
157
|
-
Square as Square2,
|
|
158
|
-
StreamingMarkdown_default,
|
|
159
|
-
Trash as Trash2,
|
|
160
|
-
Type,
|
|
161
|
-
Waveform as Waveform2,
|
|
162
|
-
Wifi,
|
|
163
|
-
WifiOff,
|
|
164
|
-
X as X2,
|
|
165
|
-
ZoomIn,
|
|
166
|
-
ZoomOut,
|
|
167
|
-
getHighlightTree,
|
|
168
|
-
markdownSanitizeSchema,
|
|
169
|
-
maybeHandleFileLinkClick,
|
|
170
|
-
renderLowlightChildren
|
|
171
|
-
} from "./chunk-SK7FSLCY.mjs";
|
|
172
|
-
import {
|
|
173
|
-
browserTimeZone,
|
|
174
|
-
formatInZone,
|
|
175
|
-
normalizeScheduleArgs
|
|
176
|
-
} from "./chunk-MAKXJD7A.mjs";
|
|
179
|
+
} from "./chunk-5URP2E5V.mjs";
|
|
177
180
|
import {
|
|
178
181
|
usePackageSettingsStore
|
|
179
182
|
} from "./chunk-K7SQWDNF.mjs";
|
|
@@ -187,7 +190,8 @@ import {
|
|
|
187
190
|
} from "./chunk-NI7BKLC7.mjs";
|
|
188
191
|
|
|
189
192
|
// src/chat/chat.tsx
|
|
190
|
-
import
|
|
193
|
+
import React25 from "react";
|
|
194
|
+
import { lazy as lazy2, Suspense as Suspense3, useCallback as useCallback13, useEffect as useEffect26, useLayoutEffect as useLayoutEffect2, useRef as useRef20, useState as useState29 } from "react";
|
|
191
195
|
|
|
192
196
|
// src/chat/custom-logo.tsx
|
|
193
197
|
import React, { useEffect } from "react";
|
|
@@ -358,8 +362,8 @@ import {
|
|
|
358
362
|
Box as Box32,
|
|
359
363
|
ThemeProvider as ThemeProvider2,
|
|
360
364
|
CssBaseline,
|
|
361
|
-
Typography as
|
|
362
|
-
Button as
|
|
365
|
+
Typography as Typography25,
|
|
366
|
+
Button as Button14,
|
|
363
367
|
IconButton as IconButton21
|
|
364
368
|
} from "@mui/material";
|
|
365
369
|
import { alpha as alpha18 } from "@mui/material/styles";
|
|
@@ -3481,6 +3485,23 @@ var hostOf = (url) => {
|
|
|
3481
3485
|
}
|
|
3482
3486
|
};
|
|
3483
3487
|
var str2 = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
3488
|
+
var quotaNote = (data) => {
|
|
3489
|
+
const quota = data.quota;
|
|
3490
|
+
if (!quota || typeof quota.limit !== "number" || typeof quota.remaining !== "number") return "";
|
|
3491
|
+
return ` \u2014 ${quota.remaining} of ${quota.limit} left today`;
|
|
3492
|
+
};
|
|
3493
|
+
var planRequired = (data) => str2(data.code) === "image_plan_required";
|
|
3494
|
+
var cloudNote = (data) => str2(data.backend) === "cloud" ? " in the cloud to skip the queue" : "";
|
|
3495
|
+
var failedLabel = (base, result) => {
|
|
3496
|
+
const data = result?.data ?? {};
|
|
3497
|
+
const code = str2(data.code);
|
|
3498
|
+
if (code === "image_quota_exceeded") return "Daily image allowance used";
|
|
3499
|
+
if (code === "image_plan_required") return "Image generation is on paid plans";
|
|
3500
|
+
if (code === "content_refused") return "Image request refused by safety check";
|
|
3501
|
+
if (code === "acknowledgement_required") return "Photo edit needs your acknowledgement";
|
|
3502
|
+
if (code === "chat_images_disabled") return "Image tools are not enabled";
|
|
3503
|
+
return base;
|
|
3504
|
+
};
|
|
3484
3505
|
var kindFor = (name) => {
|
|
3485
3506
|
switch (canonicalToolName(name)) {
|
|
3486
3507
|
case "web_search":
|
|
@@ -3489,6 +3510,8 @@ var kindFor = (name) => {
|
|
|
3489
3510
|
return "web_fetch";
|
|
3490
3511
|
case "image_generation":
|
|
3491
3512
|
return "image_generation";
|
|
3513
|
+
case "image_edit":
|
|
3514
|
+
return "image_edit";
|
|
3492
3515
|
case "create_file":
|
|
3493
3516
|
return "create_file";
|
|
3494
3517
|
case "ask_user":
|
|
@@ -3529,14 +3552,29 @@ var trailItemForTool = (name, params, result) => {
|
|
|
3529
3552
|
label: `${failed ? "Couldn't read" : "Read"}${url ? `: ${hostOf(url)}` : ""}`
|
|
3530
3553
|
};
|
|
3531
3554
|
}
|
|
3532
|
-
case "image_generation":
|
|
3555
|
+
case "image_generation": {
|
|
3556
|
+
const quota = quotaNote(data);
|
|
3533
3557
|
return {
|
|
3534
3558
|
kind,
|
|
3535
3559
|
tool: name,
|
|
3536
3560
|
ok,
|
|
3537
3561
|
detail: str2(params.prompt),
|
|
3538
|
-
label: ok ?
|
|
3562
|
+
label: planRequired(data) ? "Image generation is on paid plans" : ok ? `Generated an image${cloudNote(data)}${quota}` : failedLabel("Image generation failed", result)
|
|
3563
|
+
};
|
|
3564
|
+
}
|
|
3565
|
+
case "image_edit": {
|
|
3566
|
+
const quota = quotaNote(data);
|
|
3567
|
+
const index = typeof params.image === "number" && params.image >= 1 ? Math.floor(params.image) : void 0;
|
|
3568
|
+
return {
|
|
3569
|
+
kind,
|
|
3570
|
+
tool: name,
|
|
3571
|
+
ok,
|
|
3572
|
+
detail: str2(params.instruction) ?? str2(params.prompt),
|
|
3573
|
+
afterUrl: ok && !planRequired(data) ? str2(data.imageUrl) : void 0,
|
|
3574
|
+
attachmentIndex: index,
|
|
3575
|
+
label: planRequired(data) ? "Photo editing is on paid plans" : ok ? `Edited the photo${cloudNote(data)}${quota}` : failedLabel("Photo edit failed", result)
|
|
3539
3576
|
};
|
|
3577
|
+
}
|
|
3540
3578
|
case "create_file": {
|
|
3541
3579
|
const filename = str2(data.filename) ?? str2(params.filename);
|
|
3542
3580
|
const stash = data.stash && typeof data.stash === "object" ? data.stash : {};
|
|
@@ -3590,25 +3628,24 @@ var pendingTrailItem = (name, params) => {
|
|
|
3590
3628
|
const query = str2(params.query);
|
|
3591
3629
|
const url = str2(params.url);
|
|
3592
3630
|
const filename = str2(params.filename);
|
|
3593
|
-
const label = kind === "web_search" ? `Searching${query ? `: ${clip(query)}` : " the web"}` : kind === "web_fetch" ? `Reading${url ? `: ${hostOf(url)}` : " the page"}` : kind === "image_generation" ? "Generating an image" : kind === "create_file" ? `Creating file${filename ? `: ${clip(filename)}` : ""}` : kind === "ask_user" ? "Waiting for your answer" : kind === "create_schedule" ? "Setting up a schedule" : kind === "health_check" ? "Checking service health" : `Running tool: ${name}`;
|
|
3631
|
+
const label = kind === "web_search" ? `Searching${query ? `: ${clip(query)}` : " the web"}` : kind === "web_fetch" ? `Reading${url ? `: ${hostOf(url)}` : " the page"}` : kind === "image_generation" ? "Generating an image" : kind === "image_edit" ? "Editing the photo" : kind === "create_file" ? `Creating file${filename ? `: ${clip(filename)}` : ""}` : kind === "ask_user" ? "Waiting for your answer" : kind === "create_schedule" ? "Setting up a schedule" : kind === "health_check" ? "Checking service health" : `Running tool: ${name}`;
|
|
3594
3632
|
return {
|
|
3595
3633
|
kind,
|
|
3596
3634
|
tool: name,
|
|
3597
3635
|
ok: true,
|
|
3598
3636
|
pending: true,
|
|
3599
3637
|
label,
|
|
3600
|
-
detail: query ?? url ?? filename,
|
|
3638
|
+
detail: query ?? url ?? filename ?? str2(params.prompt) ?? str2(params.instruction),
|
|
3601
3639
|
url: kind === "web_fetch" ? url : void 0
|
|
3602
3640
|
};
|
|
3603
3641
|
};
|
|
3642
|
+
var pendingTrailItemWithStatus = (name, params, status) => ({ ...pendingTrailItem(name, params), label: status });
|
|
3604
3643
|
var upsertTrailItem = (trail, item) => {
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
return next;
|
|
3611
|
-
}
|
|
3644
|
+
const idx = trail.findIndex((t) => t.pending && t.tool === item.tool);
|
|
3645
|
+
if (idx !== -1) {
|
|
3646
|
+
const next = [...trail];
|
|
3647
|
+
next[idx] = item;
|
|
3648
|
+
return next;
|
|
3612
3649
|
}
|
|
3613
3650
|
return appendTrailItem(trail, item);
|
|
3614
3651
|
};
|
|
@@ -3763,6 +3800,7 @@ var KNOWN_KINDS = /* @__PURE__ */ new Set([
|
|
|
3763
3800
|
"web_search",
|
|
3764
3801
|
"web_fetch",
|
|
3765
3802
|
"image_generation",
|
|
3803
|
+
"image_edit",
|
|
3766
3804
|
"create_file",
|
|
3767
3805
|
"ask_user",
|
|
3768
3806
|
"health_check",
|
|
@@ -3783,13 +3821,16 @@ var normalizeToolTrail = (raw) => {
|
|
|
3783
3821
|
const kind = typeof r.kind === "string" && KNOWN_KINDS.has(r.kind) ? r.kind : "tool";
|
|
3784
3822
|
const url = str2(r.url);
|
|
3785
3823
|
const stillPending = r.pending === true;
|
|
3824
|
+
const afterUrl = str2(r.afterUrl);
|
|
3786
3825
|
out.push({
|
|
3787
3826
|
kind,
|
|
3788
3827
|
tool,
|
|
3789
3828
|
label,
|
|
3790
3829
|
detail: str2(r.detail),
|
|
3791
3830
|
url: url && /^https?:\/\//i.test(url) ? url : void 0,
|
|
3792
|
-
ok: stillPending ? false : r.ok !== false
|
|
3831
|
+
ok: stillPending ? false : r.ok !== false,
|
|
3832
|
+
afterUrl: afterUrl && /^https?:\/\//i.test(afterUrl) ? afterUrl : void 0,
|
|
3833
|
+
attachmentIndex: typeof r.attachmentIndex === "number" && r.attachmentIndex >= 1 ? Math.floor(r.attachmentIndex) : void 0
|
|
3793
3834
|
});
|
|
3794
3835
|
}
|
|
3795
3836
|
return out.length ? out : void 0;
|
|
@@ -9577,6 +9618,7 @@ var SourceChips = ({ content }) => {
|
|
|
9577
9618
|
var source_chips_default = SourceChips;
|
|
9578
9619
|
|
|
9579
9620
|
// src/chat/tool-trail-view.tsx
|
|
9621
|
+
import React6, { Suspense } from "react";
|
|
9580
9622
|
import { Box as Box9 } from "@mui/material";
|
|
9581
9623
|
import { alpha as alpha4 } from "@mui/material/styles";
|
|
9582
9624
|
import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
@@ -9584,6 +9626,7 @@ var ICONS = {
|
|
|
9584
9626
|
web_search: Search,
|
|
9585
9627
|
web_fetch: Globe,
|
|
9586
9628
|
image_generation: Image,
|
|
9629
|
+
image_edit: Edit,
|
|
9587
9630
|
create_file: FileText,
|
|
9588
9631
|
ask_user: HelpCircle,
|
|
9589
9632
|
create_schedule: Clock,
|
|
@@ -9593,96 +9636,126 @@ var ICONS = {
|
|
|
9593
9636
|
stash: Archive,
|
|
9594
9637
|
tool: Wrench
|
|
9595
9638
|
};
|
|
9596
|
-
var
|
|
9639
|
+
var ImageCompare = React6.lazy(() => import("./image-compare-NW5VCP4Q.mjs"));
|
|
9640
|
+
var imageComparePairs = (items, attachments) => {
|
|
9641
|
+
if (!items || !attachments || attachments.length === 0) return [];
|
|
9642
|
+
const pairs = [];
|
|
9643
|
+
for (const item of items) {
|
|
9644
|
+
if (item.kind !== "image_edit" || !item.ok || !item.afterUrl) continue;
|
|
9645
|
+
const index = item.attachmentIndex && item.attachmentIndex <= attachments.length ? item.attachmentIndex - 1 : attachments.length - 1;
|
|
9646
|
+
const beforeUrl = attachments[index];
|
|
9647
|
+
if (beforeUrl) pairs.push({ beforeUrl, afterUrl: item.afterUrl });
|
|
9648
|
+
}
|
|
9649
|
+
return pairs;
|
|
9650
|
+
};
|
|
9651
|
+
var ToolTrail = ({
|
|
9652
|
+
items,
|
|
9653
|
+
attachments
|
|
9654
|
+
}) => {
|
|
9597
9655
|
if (!items || items.length === 0) return null;
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
{
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
listStyle: "none",
|
|
9606
|
-
m: 0,
|
|
9607
|
-
mb: 1,
|
|
9608
|
-
p: 0,
|
|
9609
|
-
display: "flex",
|
|
9610
|
-
flexWrap: "wrap",
|
|
9611
|
-
gap: 0.75
|
|
9656
|
+
const compares = imageComparePairs(items, attachments);
|
|
9657
|
+
return /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
9658
|
+
compares.length > 0 && /* @__PURE__ */ jsx11(Suspense, { fallback: null, children: /* @__PURE__ */ jsx11(Box9, { sx: { display: "flex", flexDirection: "column", gap: 1.5, mb: 1.5 }, children: compares.map((pair, i) => /* @__PURE__ */ jsx11(
|
|
9659
|
+
ImageCompare,
|
|
9660
|
+
{
|
|
9661
|
+
beforeUrl: pair.beforeUrl,
|
|
9662
|
+
afterUrl: pair.afterUrl
|
|
9612
9663
|
},
|
|
9613
|
-
|
|
9614
|
-
|
|
9615
|
-
|
|
9616
|
-
|
|
9617
|
-
|
|
9618
|
-
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9664
|
+
`${pair.afterUrl}-${i}`
|
|
9665
|
+
)) }) }),
|
|
9666
|
+
/* @__PURE__ */ jsx11(
|
|
9667
|
+
Box9,
|
|
9668
|
+
{
|
|
9669
|
+
component: "ul",
|
|
9670
|
+
"aria-label": "Tools used for this answer",
|
|
9671
|
+
"data-testid": "tool-trail",
|
|
9672
|
+
sx: {
|
|
9673
|
+
listStyle: "none",
|
|
9674
|
+
m: 0,
|
|
9675
|
+
mb: 1,
|
|
9676
|
+
p: 0,
|
|
9677
|
+
display: "flex",
|
|
9678
|
+
flexWrap: "wrap",
|
|
9679
|
+
gap: 0.75
|
|
9680
|
+
},
|
|
9681
|
+
children: items.map((item, i) => {
|
|
9682
|
+
const Icon = item.ok ? ICONS[item.kind] ?? Wrench : AlertCircle;
|
|
9683
|
+
const pending = item.pending === true;
|
|
9684
|
+
const title = item.detail && item.detail !== item.label ? item.detail : void 0;
|
|
9685
|
+
const body = /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
9686
|
+
/* @__PURE__ */ jsx11(
|
|
9687
|
+
Box9,
|
|
9688
|
+
{
|
|
9689
|
+
component: "span",
|
|
9690
|
+
sx: { display: "inline-flex", flexShrink: 0, opacity: 0.85 },
|
|
9691
|
+
"aria-hidden": true,
|
|
9692
|
+
children: /* @__PURE__ */ jsx11(Icon, { size: 13 })
|
|
9693
|
+
}
|
|
9694
|
+
),
|
|
9695
|
+
/* @__PURE__ */ jsxs8(
|
|
9696
|
+
Box9,
|
|
9697
|
+
{
|
|
9698
|
+
component: "span",
|
|
9699
|
+
sx: {
|
|
9700
|
+
overflow: "hidden",
|
|
9701
|
+
textOverflow: "ellipsis",
|
|
9702
|
+
whiteSpace: "nowrap"
|
|
9703
|
+
},
|
|
9704
|
+
children: [
|
|
9705
|
+
item.label,
|
|
9706
|
+
pending ? "\u2026" : ""
|
|
9707
|
+
]
|
|
9708
|
+
}
|
|
9709
|
+
)
|
|
9710
|
+
] });
|
|
9711
|
+
return /* @__PURE__ */ jsx11(
|
|
9628
9712
|
Box9,
|
|
9629
9713
|
{
|
|
9630
|
-
component: "
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
)
|
|
9638
|
-
] });
|
|
9639
|
-
return /* @__PURE__ */ jsx11(
|
|
9640
|
-
Box9,
|
|
9641
|
-
{
|
|
9642
|
-
component: "li",
|
|
9643
|
-
"data-kind": item.kind,
|
|
9644
|
-
"data-ok": item.ok ? "true" : "false",
|
|
9645
|
-
"data-pending": pending ? "true" : void 0,
|
|
9646
|
-
"aria-busy": pending || void 0,
|
|
9647
|
-
title,
|
|
9648
|
-
sx: (theme) => ({
|
|
9649
|
-
display: "inline-flex",
|
|
9650
|
-
alignItems: "center",
|
|
9651
|
-
gap: 0.6,
|
|
9652
|
-
maxWidth: "100%",
|
|
9653
|
-
px: 1,
|
|
9654
|
-
py: 0.35,
|
|
9655
|
-
borderRadius: 1.5,
|
|
9656
|
-
fontSize: "0.78rem",
|
|
9657
|
-
lineHeight: 1.4,
|
|
9658
|
-
color: item.ok ? theme.palette.text.secondary : theme.palette.error.main,
|
|
9659
|
-
bgcolor: alpha4(theme.palette.text.primary, 0.04),
|
|
9660
|
-
border: `1px solid ${alpha4(theme.palette.text.primary, 0.1)}`,
|
|
9661
|
-
"& a": {
|
|
9662
|
-
color: "inherit",
|
|
9663
|
-
textDecoration: "none",
|
|
9714
|
+
component: "li",
|
|
9715
|
+
"data-kind": item.kind,
|
|
9716
|
+
"data-ok": item.ok ? "true" : "false",
|
|
9717
|
+
"data-pending": pending ? "true" : void 0,
|
|
9718
|
+
"aria-busy": pending || void 0,
|
|
9719
|
+
title,
|
|
9720
|
+
sx: (theme) => ({
|
|
9664
9721
|
display: "inline-flex",
|
|
9665
9722
|
alignItems: "center",
|
|
9666
9723
|
gap: 0.6,
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
9724
|
+
maxWidth: "100%",
|
|
9725
|
+
px: 1,
|
|
9726
|
+
py: 0.35,
|
|
9727
|
+
borderRadius: 1.5,
|
|
9728
|
+
fontSize: "0.78rem",
|
|
9729
|
+
lineHeight: 1.4,
|
|
9730
|
+
color: item.ok ? theme.palette.text.secondary : theme.palette.error.main,
|
|
9731
|
+
bgcolor: alpha4(theme.palette.text.primary, 0.04),
|
|
9732
|
+
border: `1px solid ${alpha4(theme.palette.text.primary, 0.1)}`,
|
|
9733
|
+
"& a": {
|
|
9734
|
+
color: "inherit",
|
|
9735
|
+
textDecoration: "none",
|
|
9736
|
+
display: "inline-flex",
|
|
9737
|
+
alignItems: "center",
|
|
9738
|
+
gap: 0.6,
|
|
9739
|
+
minWidth: 0
|
|
9675
9740
|
},
|
|
9676
|
-
"
|
|
9677
|
-
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
9741
|
+
"& a:hover span:last-of-type": { textDecoration: "underline" },
|
|
9742
|
+
...pending ? {
|
|
9743
|
+
animation: "toolTrailPulse 1.4s ease-in-out infinite",
|
|
9744
|
+
"@keyframes toolTrailPulse": {
|
|
9745
|
+
"0%, 100%": { opacity: 1 },
|
|
9746
|
+
"50%": { opacity: 0.55 }
|
|
9747
|
+
},
|
|
9748
|
+
"@media (prefers-reduced-motion: reduce)": { animation: "none" }
|
|
9749
|
+
} : {}
|
|
9750
|
+
}),
|
|
9751
|
+
children: item.url && item.ok && !pending ? /* @__PURE__ */ jsx11("a", { href: item.url, target: "_blank", rel: "noopener noreferrer", children: body }) : body
|
|
9752
|
+
},
|
|
9753
|
+
`${item.tool}-${i}`
|
|
9754
|
+
);
|
|
9755
|
+
})
|
|
9756
|
+
}
|
|
9757
|
+
)
|
|
9758
|
+
] });
|
|
9686
9759
|
};
|
|
9687
9760
|
var tool_trail_view_default = ToolTrail;
|
|
9688
9761
|
|
|
@@ -9792,7 +9865,7 @@ var ChatMessages = ({
|
|
|
9792
9865
|
transition: "min-height 0.25s cubic-bezier(0.4, 0, 0.2, 1)"
|
|
9793
9866
|
},
|
|
9794
9867
|
children: [
|
|
9795
|
-
/* @__PURE__ */ jsx12(tool_trail_view_default, { items: entry.toolsUsed }),
|
|
9868
|
+
/* @__PURE__ */ jsx12(tool_trail_view_default, { items: entry.toolsUsed, attachments: entry.images }),
|
|
9796
9869
|
/* @__PURE__ */ jsx12(
|
|
9797
9870
|
Box10,
|
|
9798
9871
|
{
|
|
@@ -9900,7 +9973,7 @@ var ChatMessages = ({
|
|
|
9900
9973
|
var chat_messages_default = ChatMessages;
|
|
9901
9974
|
|
|
9902
9975
|
// src/chat/chat-input.tsx
|
|
9903
|
-
import { useEffect as useEffect11, useRef as useRef6, useState as useState14 } from "react";
|
|
9976
|
+
import React9, { useEffect as useEffect11, useRef as useRef6, useState as useState14 } from "react";
|
|
9904
9977
|
import {
|
|
9905
9978
|
Box as Box14,
|
|
9906
9979
|
Button as Button4,
|
|
@@ -10462,7 +10535,7 @@ var Transcriber = ({ onTranscriptionCompleted }) => {
|
|
|
10462
10535
|
var transcriber_default = Transcriber;
|
|
10463
10536
|
|
|
10464
10537
|
// src/chat/memory-modal.tsx
|
|
10465
|
-
import
|
|
10538
|
+
import React8, { useState as useState13, useEffect as useEffect10 } from "react";
|
|
10466
10539
|
import { useTheme as useTheme9, alpha as alpha7, keyframes } from "@mui/material/styles";
|
|
10467
10540
|
import {
|
|
10468
10541
|
Box as Box13,
|
|
@@ -11396,7 +11469,7 @@ var MemoryModal = ({ open, onClose }) => {
|
|
|
11396
11469
|
}
|
|
11397
11470
|
) : filteredMemories.map((memory, memoryIndex) => {
|
|
11398
11471
|
const isSelected = selectedIds.includes(memory.id);
|
|
11399
|
-
return /* @__PURE__ */ jsxs12(
|
|
11472
|
+
return /* @__PURE__ */ jsxs12(React8.Fragment, { children: [
|
|
11400
11473
|
/* @__PURE__ */ jsx15(List, { sx: { listStyle: "none", pl: 0, m: 0 }, children: /* @__PURE__ */ jsxs12(
|
|
11401
11474
|
ListItem,
|
|
11402
11475
|
{
|
|
@@ -12678,6 +12751,273 @@ function markAiReminderSeen(now = Date.now(), storage = defaultStorage()) {
|
|
|
12678
12751
|
// src/chat/chat-input.tsx
|
|
12679
12752
|
import { useTheme as useTheme10, alpha as alpha8 } from "@mui/material/styles";
|
|
12680
12753
|
|
|
12754
|
+
// src/services/images/imageTools.ts
|
|
12755
|
+
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set(["image_generation", "image_edit"]);
|
|
12756
|
+
var IMAGE_TOOL_TIMEOUT_MS = 12e4;
|
|
12757
|
+
var IMAGE_JOB_MAX_WAIT_MS = 40 * 6e4;
|
|
12758
|
+
var IMAGE_JOB_POLL_MS = 2500;
|
|
12759
|
+
var MAX_IMAGE_UPLOAD_BYTES = 20 * 1024 * 1024;
|
|
12760
|
+
var MAX_IMAGES_PER_MESSAGE = 4;
|
|
12761
|
+
var MAX_UPLOAD_SIDE = 2048;
|
|
12762
|
+
var canonicalImageTool = (name) => name.replace(/-/g, "_");
|
|
12763
|
+
var isImageTool = (name) => IMAGE_TOOL_NAMES.has(canonicalImageTool(name));
|
|
12764
|
+
var isImageEditTool = (name) => canonicalImageTool(name) === "image_edit";
|
|
12765
|
+
var IMAGE_PLAN_REQUIRED = "image_plan_required";
|
|
12766
|
+
var PLAN_REQUIRED_SENTENCE = "Image generation and photo editing are on paid plans.";
|
|
12767
|
+
var PLAN_REQUIRED_NO_LINK = "Image generation and photo editing aren't included with this account.";
|
|
12768
|
+
var PLANS_PATH = IS_STORE_BUILD ? "" : "/plans";
|
|
12769
|
+
var PLANS_LINK_TEXT = IS_STORE_BUILD ? "" : "See plans";
|
|
12770
|
+
var CLOUD_RUNNING_LABEL = "Running in the cloud to skip the queue";
|
|
12771
|
+
var isPlanRequired = (data) => !!data && data.code === IMAGE_PLAN_REQUIRED;
|
|
12772
|
+
var isTerminalImageStatus = (status) => status === "completed" || status === "failed" || status === "refused" || status === "cancelled";
|
|
12773
|
+
var minutesOf = (seconds) => typeof seconds === "number" && seconds > 0 ? Math.max(1, Math.ceil(seconds / 60)) : void 0;
|
|
12774
|
+
var imageQueueLabel = (base, progress) => {
|
|
12775
|
+
if (!progress) return base;
|
|
12776
|
+
if (progress.status === "running") {
|
|
12777
|
+
return progress.backend === "cloud" ? CLOUD_RUNNING_LABEL : `${base} \u2014 working on it now`;
|
|
12778
|
+
}
|
|
12779
|
+
if (progress.status !== "queued") return base;
|
|
12780
|
+
const minutes = minutesOf(progress.etaSeconds);
|
|
12781
|
+
const wait = minutes === void 0 ? "" : minutes === 1 ? ", about a minute" : `, about ${minutes} min`;
|
|
12782
|
+
const position = typeof progress.position === "number" && progress.position > 0 ? ` at position ${progress.position}` : "";
|
|
12783
|
+
return `${base} \u2014 queued${position}${wait}`;
|
|
12784
|
+
};
|
|
12785
|
+
var quotaLine = (quota) => {
|
|
12786
|
+
if (!quota) return void 0;
|
|
12787
|
+
if (quota.unlimited || quota.limit === null || quota.limit === void 0)
|
|
12788
|
+
return void 0;
|
|
12789
|
+
const remaining = typeof quota.remaining === "number" ? quota.remaining : Math.max(0, quota.limit - (quota.used ?? 0));
|
|
12790
|
+
return `${remaining} of ${quota.limit} image generations left today.`;
|
|
12791
|
+
};
|
|
12792
|
+
var formatImageResult = (data, kind, options = {}) => {
|
|
12793
|
+
if (isPlanRequired(data)) {
|
|
12794
|
+
const forModel = "Image tools aren't on the user's plan and they were told so. Acknowledge it in one short sentence. Don't retry, don't describe an image and don't suggest workarounds.";
|
|
12795
|
+
if (IS_STORE_BUILD || options.noUpgrade) {
|
|
12796
|
+
return { inline: PLAN_REQUIRED_NO_LINK, forModel };
|
|
12797
|
+
}
|
|
12798
|
+
const sentence = (data.error ?? data.message ?? PLAN_REQUIRED_SENTENCE).trim();
|
|
12799
|
+
return {
|
|
12800
|
+
inline: `${sentence} [${PLANS_LINK_TEXT}](${data.upgradeUrl || PLANS_PATH})`,
|
|
12801
|
+
forModel
|
|
12802
|
+
};
|
|
12803
|
+
}
|
|
12804
|
+
const url = data.imageUrl ?? void 0;
|
|
12805
|
+
if (!url) {
|
|
12806
|
+
return {
|
|
12807
|
+
inline: "",
|
|
12808
|
+
forModel: kind === "edit" ? "The photo edit finished but returned no image." : "Image generated successfully."
|
|
12809
|
+
};
|
|
12810
|
+
}
|
|
12811
|
+
const alt = kind === "edit" ? "Edited photo" : "Generated image";
|
|
12812
|
+
const notes = [];
|
|
12813
|
+
if (data.backend === "cloud") notes.push("Ran in the cloud to skip the queue.");
|
|
12814
|
+
if (data.stashUrl) notes.push("Saved to your Stash.");
|
|
12815
|
+
notes.push("This link expires in about 2 hours.");
|
|
12816
|
+
const quota = quotaLine(data.quota);
|
|
12817
|
+
if (quota) notes.push(quota);
|
|
12818
|
+
const inline = `
|
|
12819
|
+
|
|
12820
|
+
_${notes.join(" ")}_`;
|
|
12821
|
+
return {
|
|
12822
|
+
inline,
|
|
12823
|
+
forModel: kind === "edit" ? "The edited photo is shown to the user with a before/after view. Briefly say what was changed; do not describe the image link." : "The image is shown to the user. Briefly describe what you made; do not repeat the link."
|
|
12824
|
+
};
|
|
12825
|
+
};
|
|
12826
|
+
var authHeaders = (token) => token ? { Authorization: `Bearer ${token}` } : {};
|
|
12827
|
+
var baseUrl = (gatewayUrl) => gatewayUrl.replace(/\/+$/, "");
|
|
12828
|
+
var readJsonSafe = async (response) => {
|
|
12829
|
+
try {
|
|
12830
|
+
return await response.json();
|
|
12831
|
+
} catch {
|
|
12832
|
+
return {};
|
|
12833
|
+
}
|
|
12834
|
+
};
|
|
12835
|
+
var pollImageJob = async (jobId, http, options = {}) => {
|
|
12836
|
+
const fetchImpl = http.fetchImpl ?? fetch;
|
|
12837
|
+
const sleep = options.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
12838
|
+
const deadline = Date.now() + (options.maxWaitMs ?? IMAGE_JOB_MAX_WAIT_MS);
|
|
12839
|
+
const pollMs = options.pollMs ?? IMAGE_JOB_POLL_MS;
|
|
12840
|
+
let last = { status: "queued", jobId };
|
|
12841
|
+
let failures = 0;
|
|
12842
|
+
while (Date.now() < deadline) {
|
|
12843
|
+
if (options.signal?.aborted) break;
|
|
12844
|
+
await sleep(pollMs);
|
|
12845
|
+
try {
|
|
12846
|
+
const response = await fetchImpl(
|
|
12847
|
+
`${baseUrl(http.gatewayUrl)}/api/mcp/image-jobs/${encodeURIComponent(jobId)}`,
|
|
12848
|
+
{
|
|
12849
|
+
headers: authHeaders(http.token),
|
|
12850
|
+
signal: options.signal
|
|
12851
|
+
}
|
|
12852
|
+
);
|
|
12853
|
+
const data = await readJsonSafe(response);
|
|
12854
|
+
if (response.status === 404) {
|
|
12855
|
+
return {
|
|
12856
|
+
...last,
|
|
12857
|
+
status: "failed",
|
|
12858
|
+
error: "The image job was lost. Please try again."
|
|
12859
|
+
};
|
|
12860
|
+
}
|
|
12861
|
+
failures = 0;
|
|
12862
|
+
last = { ...last, ...data };
|
|
12863
|
+
options.onProgress?.({
|
|
12864
|
+
status: data.status ?? "queued",
|
|
12865
|
+
position: data.position,
|
|
12866
|
+
etaSeconds: data.etaSeconds,
|
|
12867
|
+
message: data.message,
|
|
12868
|
+
backend: data.backend
|
|
12869
|
+
});
|
|
12870
|
+
if (isTerminalImageStatus(data.status)) return last;
|
|
12871
|
+
} catch (error) {
|
|
12872
|
+
if (options.signal?.aborted) break;
|
|
12873
|
+
failures += 1;
|
|
12874
|
+
if (failures >= 5) {
|
|
12875
|
+
return {
|
|
12876
|
+
...last,
|
|
12877
|
+
status: "failed",
|
|
12878
|
+
error: error instanceof Error ? error.message : "The image service stopped answering."
|
|
12879
|
+
};
|
|
12880
|
+
}
|
|
12881
|
+
}
|
|
12882
|
+
}
|
|
12883
|
+
return {
|
|
12884
|
+
...last,
|
|
12885
|
+
status: last.status && isTerminalImageStatus(last.status) ? last.status : "failed",
|
|
12886
|
+
error: last.error ?? "Timed out waiting for the image. It may still finish; check your Stash later."
|
|
12887
|
+
};
|
|
12888
|
+
};
|
|
12889
|
+
var ImageEditAcknowledgementRequired = class extends Error {
|
|
12890
|
+
constructor(text) {
|
|
12891
|
+
super(text);
|
|
12892
|
+
this.text = text;
|
|
12893
|
+
this.name = "ImageEditAcknowledgementRequired";
|
|
12894
|
+
}
|
|
12895
|
+
};
|
|
12896
|
+
var ACKNOWLEDGEMENT_TEXT = "Only upload photos of yourself or people who agreed. Don't use this to create images that deceive or harass.";
|
|
12897
|
+
var dataUrlToBlob = (dataUrl) => {
|
|
12898
|
+
const match = /^data:([^;,]+)?(;base64)?,(.*)$/s.exec(dataUrl);
|
|
12899
|
+
if (!match) throw new Error("Not a data URL.");
|
|
12900
|
+
const type = match[1] || "application/octet-stream";
|
|
12901
|
+
const payload = match[3];
|
|
12902
|
+
if (match[2]) {
|
|
12903
|
+
const binary = atob(payload);
|
|
12904
|
+
const bytes = new Uint8Array(binary.length);
|
|
12905
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
12906
|
+
return new Blob([bytes], { type });
|
|
12907
|
+
}
|
|
12908
|
+
return new Blob([decodeURIComponent(payload)], { type });
|
|
12909
|
+
};
|
|
12910
|
+
var extensionFor = (type) => type === "image/png" ? "png" : type === "image/webp" ? "webp" : "jpg";
|
|
12911
|
+
var submitImageEdit = async (request) => {
|
|
12912
|
+
const fetchImpl = request.fetchImpl ?? fetch;
|
|
12913
|
+
const blob = dataUrlToBlob(request.imageDataUrl);
|
|
12914
|
+
const form = new FormData();
|
|
12915
|
+
form.append("image", blob, `photo.${extensionFor(blob.type)}`);
|
|
12916
|
+
form.append("prompt", request.instruction);
|
|
12917
|
+
if (typeof request.strength === "number")
|
|
12918
|
+
form.append("strength", String(request.strength));
|
|
12919
|
+
const response = await fetchImpl(`${baseUrl(request.gatewayUrl)}/api/mcp/edit-image`, {
|
|
12920
|
+
method: "POST",
|
|
12921
|
+
headers: authHeaders(request.token),
|
|
12922
|
+
body: form,
|
|
12923
|
+
signal: request.signal
|
|
12924
|
+
});
|
|
12925
|
+
const data = await readJsonSafe(response);
|
|
12926
|
+
if (response.status === 428) {
|
|
12927
|
+
throw new ImageEditAcknowledgementRequired(data.error ?? ACKNOWLEDGEMENT_TEXT);
|
|
12928
|
+
}
|
|
12929
|
+
return { status: response.status, data };
|
|
12930
|
+
};
|
|
12931
|
+
var acknowledgeImageEdit = async (http) => {
|
|
12932
|
+
const fetchImpl = http.fetchImpl ?? fetch;
|
|
12933
|
+
const response = await fetchImpl(
|
|
12934
|
+
`${baseUrl(http.gatewayUrl)}/api/mcp/image-edit/acknowledgement`,
|
|
12935
|
+
{
|
|
12936
|
+
method: "POST",
|
|
12937
|
+
headers: authHeaders(http.token)
|
|
12938
|
+
}
|
|
12939
|
+
);
|
|
12940
|
+
return response.ok;
|
|
12941
|
+
};
|
|
12942
|
+
var isHeicFile = (file) => {
|
|
12943
|
+
const type = (file.type ?? "").toLowerCase();
|
|
12944
|
+
if (type === "image/heic" || type === "image/heif") return true;
|
|
12945
|
+
return /\.(heic|heif)$/i.test(file.name ?? "");
|
|
12946
|
+
};
|
|
12947
|
+
var isImageFile = (file) => (file.type ?? "").toLowerCase().startsWith("image/") || isHeicFile(file);
|
|
12948
|
+
var defaultReadAsDataUrl = (file) => new Promise((resolve, reject) => {
|
|
12949
|
+
const reader = new FileReader();
|
|
12950
|
+
reader.onload = () => resolve(String(reader.result ?? ""));
|
|
12951
|
+
reader.onerror = () => reject(reader.error ?? new Error("Could not read the file."));
|
|
12952
|
+
reader.readAsDataURL(file);
|
|
12953
|
+
});
|
|
12954
|
+
var fitWithin = (width, height, maxSide) => {
|
|
12955
|
+
const longest = Math.max(width, height);
|
|
12956
|
+
if (longest <= maxSide) return { width, height };
|
|
12957
|
+
const scale = maxSide / longest;
|
|
12958
|
+
return {
|
|
12959
|
+
width: Math.max(1, Math.round(width * scale)),
|
|
12960
|
+
height: Math.max(1, Math.round(height * scale))
|
|
12961
|
+
};
|
|
12962
|
+
};
|
|
12963
|
+
var prepareImageFile = async (file, deps = {}) => {
|
|
12964
|
+
if (file.size > MAX_IMAGE_UPLOAD_BYTES) {
|
|
12965
|
+
return {
|
|
12966
|
+
ok: false,
|
|
12967
|
+
reason: `${file.name || "That photo"} is larger than 20 MB. Please use a smaller copy.`
|
|
12968
|
+
};
|
|
12969
|
+
}
|
|
12970
|
+
const heic = isHeicFile(file);
|
|
12971
|
+
const readAsDataUrl = deps.readAsDataUrl ?? defaultReadAsDataUrl;
|
|
12972
|
+
const createBitmap = deps.createBitmap ?? (typeof createImageBitmap === "function" ? (blob) => createImageBitmap(blob) : void 0);
|
|
12973
|
+
const createCanvas = deps.createCanvas ?? ((width, height) => {
|
|
12974
|
+
const canvas2 = document.createElement("canvas");
|
|
12975
|
+
canvas2.width = width;
|
|
12976
|
+
canvas2.height = height;
|
|
12977
|
+
return canvas2;
|
|
12978
|
+
});
|
|
12979
|
+
let bitmap;
|
|
12980
|
+
if (createBitmap) {
|
|
12981
|
+
try {
|
|
12982
|
+
bitmap = await createBitmap(file);
|
|
12983
|
+
} catch {
|
|
12984
|
+
bitmap = void 0;
|
|
12985
|
+
}
|
|
12986
|
+
}
|
|
12987
|
+
if (heic) {
|
|
12988
|
+
if (!bitmap) {
|
|
12989
|
+
return {
|
|
12990
|
+
ok: false,
|
|
12991
|
+
reason: `${file.name || "That photo"} is HEIC and this browser can't decode it. Export it as JPEG (or use Bandit on your phone) and try again.`
|
|
12992
|
+
};
|
|
12993
|
+
}
|
|
12994
|
+
} else if (!bitmap || Math.max(bitmap.width, bitmap.height) <= MAX_UPLOAD_SIDE) {
|
|
12995
|
+
bitmap?.close?.();
|
|
12996
|
+
try {
|
|
12997
|
+
return { ok: true, dataUrl: await readAsDataUrl(file), converted: false };
|
|
12998
|
+
} catch (error) {
|
|
12999
|
+
return {
|
|
13000
|
+
ok: false,
|
|
13001
|
+
reason: error instanceof Error ? error.message : "Could not read the photo."
|
|
13002
|
+
};
|
|
13003
|
+
}
|
|
13004
|
+
}
|
|
13005
|
+
const size = fitWithin(bitmap.width, bitmap.height, MAX_UPLOAD_SIDE);
|
|
13006
|
+
const canvas = createCanvas(size.width, size.height);
|
|
13007
|
+
const context = canvas.getContext("2d");
|
|
13008
|
+
if (!context) {
|
|
13009
|
+
bitmap.close?.();
|
|
13010
|
+
return { ok: false, reason: "This browser can't prepare the photo for upload." };
|
|
13011
|
+
}
|
|
13012
|
+
context.drawImage(bitmap, 0, 0, size.width, size.height);
|
|
13013
|
+
bitmap.close?.();
|
|
13014
|
+
const dataUrl = canvas.toDataURL("image/jpeg", 0.92);
|
|
13015
|
+
if (!dataUrl.startsWith("data:image/")) {
|
|
13016
|
+
return { ok: false, reason: "This browser can't prepare the photo for upload." };
|
|
13017
|
+
}
|
|
13018
|
+
return { ok: true, dataUrl, converted: true };
|
|
13019
|
+
};
|
|
13020
|
+
|
|
12681
13021
|
// src/store/voiceModeStore.ts
|
|
12682
13022
|
import { create as create7 } from "zustand";
|
|
12683
13023
|
var useVoiceModeStore = create7((set) => ({
|
|
@@ -12716,7 +13056,7 @@ var useVoiceModeStore = create7((set) => ({
|
|
|
12716
13056
|
// src/chat/chat-input.tsx
|
|
12717
13057
|
import { useShallow } from "zustand/react/shallow";
|
|
12718
13058
|
import { Fragment as Fragment10, jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
12719
|
-
var DOCUMENT_ACCEPT = ".txt,.docx,.pdf,.md,.json,.js,.ts,.tsx,.py,.java,.c,.cpp,.cs,image
|
|
13059
|
+
var DOCUMENT_ACCEPT = ".txt,.docx,.pdf,.md,.json,.js,.ts,.tsx,.py,.java,.c,.cpp,.cs,image/*,.heic,.heif";
|
|
12720
13060
|
var MEETING_ACCEPT = `${DOCUMENT_ACCEPT},.vtt,.srt,audio/*,video/*`;
|
|
12721
13061
|
var isTextDocument = (file) => /\.(txt|md|docx)$/i.test(file.name) || file.type.startsWith("text/");
|
|
12722
13062
|
var ChatInput = (props) => {
|
|
@@ -12827,30 +13167,43 @@ var ChatInput = (props) => {
|
|
|
12827
13167
|
};
|
|
12828
13168
|
loadBrandingText();
|
|
12829
13169
|
}, []);
|
|
13170
|
+
const [attachmentNotice, setAttachmentNotice] = useState14(null);
|
|
13171
|
+
const attachImages = React9.useCallback(
|
|
13172
|
+
async (images) => {
|
|
13173
|
+
if (images.length === 0) return;
|
|
13174
|
+
let notice = null;
|
|
13175
|
+
const accepted = [];
|
|
13176
|
+
for (const image of images) {
|
|
13177
|
+
if (pastedImages.length + accepted.length >= MAX_IMAGES_PER_MESSAGE) {
|
|
13178
|
+
notice = `Up to ${MAX_IMAGES_PER_MESSAGE} photos per message.`;
|
|
13179
|
+
break;
|
|
13180
|
+
}
|
|
13181
|
+
const prepared = await prepareImageFile(image);
|
|
13182
|
+
if (prepared.ok) accepted.push(prepared.dataUrl);
|
|
13183
|
+
else notice = prepared.reason;
|
|
13184
|
+
}
|
|
13185
|
+
if (accepted.length) setPastedImages((prev) => [...prev, ...accepted]);
|
|
13186
|
+
setAttachmentNotice(notice);
|
|
13187
|
+
if (notice) debugLogger.info("Photo not attached", { reason: notice });
|
|
13188
|
+
},
|
|
13189
|
+
[pastedImages.length, setPastedImages]
|
|
13190
|
+
);
|
|
12830
13191
|
useEffect11(() => {
|
|
12831
13192
|
const handlePaste = (e) => {
|
|
12832
13193
|
const items = e.clipboardData?.items;
|
|
12833
|
-
if (items)
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
reader.onload = (event) => {
|
|
12840
|
-
const result = event.target?.result;
|
|
12841
|
-
if (result) {
|
|
12842
|
-
setPastedImages((prev) => [...prev, result]);
|
|
12843
|
-
}
|
|
12844
|
-
};
|
|
12845
|
-
reader.readAsDataURL(file);
|
|
12846
|
-
}
|
|
12847
|
-
}
|
|
13194
|
+
if (!items) return;
|
|
13195
|
+
const files = [];
|
|
13196
|
+
for (const item of items) {
|
|
13197
|
+
if (item.type.startsWith("image/")) {
|
|
13198
|
+
const file = item.getAsFile();
|
|
13199
|
+
if (file) files.push(file);
|
|
12848
13200
|
}
|
|
12849
13201
|
}
|
|
13202
|
+
if (files.length) void attachImages(files);
|
|
12850
13203
|
};
|
|
12851
13204
|
document.addEventListener("paste", handlePaste);
|
|
12852
13205
|
return () => document.removeEventListener("paste", handlePaste);
|
|
12853
|
-
}, [
|
|
13206
|
+
}, [attachImages]);
|
|
12854
13207
|
const meetingFileProblem = (file) => {
|
|
12855
13208
|
if (!isRecordingFile(file)) return null;
|
|
12856
13209
|
if (!canTranscribeRecordings) {
|
|
@@ -12871,8 +13224,8 @@ var ChatInput = (props) => {
|
|
|
12871
13224
|
});
|
|
12872
13225
|
};
|
|
12873
13226
|
const acceptFiles = (selected) => {
|
|
12874
|
-
const images = selected.filter((file) => file
|
|
12875
|
-
const others = selected.filter((file) => !file
|
|
13227
|
+
const images = selected.filter((file) => isImageFile(file));
|
|
13228
|
+
const others = selected.filter((file) => !isImageFile(file));
|
|
12876
13229
|
const meetingFiles = meetingNotesEnabled ? others.filter(isMeetingFile) : [];
|
|
12877
13230
|
const nonImages = others.filter((file) => !meetingFiles.includes(file));
|
|
12878
13231
|
if (meetingFiles.length > 0) {
|
|
@@ -12902,16 +13255,7 @@ var ChatInput = (props) => {
|
|
|
12902
13255
|
const safeNonImages = nonImages.filter((file) => file.size <= 1e6);
|
|
12903
13256
|
setFileInputs((prev) => [...prev, ...safeNonImages]);
|
|
12904
13257
|
safeNonImages.forEach(checkForTranscript);
|
|
12905
|
-
images
|
|
12906
|
-
const reader = new FileReader();
|
|
12907
|
-
reader.onload = (event) => {
|
|
12908
|
-
const result = event.target?.result;
|
|
12909
|
-
if (result) {
|
|
12910
|
-
setPastedImages((prev) => [...prev, result]);
|
|
12911
|
-
}
|
|
12912
|
-
};
|
|
12913
|
-
reader.readAsDataURL(image);
|
|
12914
|
-
});
|
|
13258
|
+
void attachImages(images);
|
|
12915
13259
|
};
|
|
12916
13260
|
const [dragging, setDragging] = useState14(false);
|
|
12917
13261
|
const dropHandlers = !isPlaygroundMode2 && isDocumentUploadEnabled ? {
|
|
@@ -13091,19 +13435,26 @@ var ChatInput = (props) => {
|
|
|
13091
13435
|
const showSendButton = streamingActive || hasComposeContent || !isVoiceModeEligible;
|
|
13092
13436
|
const renderAttachmentButton = (key) => {
|
|
13093
13437
|
if (!hasAttachmentAction) return null;
|
|
13094
|
-
return /* @__PURE__ */ jsx16(
|
|
13095
|
-
|
|
13438
|
+
return /* @__PURE__ */ jsx16(
|
|
13439
|
+
Tooltip8,
|
|
13096
13440
|
{
|
|
13097
|
-
|
|
13098
|
-
|
|
13099
|
-
|
|
13100
|
-
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13441
|
+
title: "Attach files or photos (JPEG, PNG, WebP, HEIC up to 20 MB)",
|
|
13442
|
+
children: /* @__PURE__ */ jsx16(
|
|
13443
|
+
ComposerControl,
|
|
13444
|
+
{
|
|
13445
|
+
"aria-label": "Attach files or images",
|
|
13446
|
+
onClick: () => fileInputRef.current?.click(),
|
|
13447
|
+
visualSize: primaryIconSize,
|
|
13448
|
+
hitSize: controlHitSize,
|
|
13449
|
+
surface: tokens.control.surface,
|
|
13450
|
+
surfaceHover: tokens.control.surfaceHover,
|
|
13451
|
+
foreground: tokens.control.foreground,
|
|
13452
|
+
children: /* @__PURE__ */ jsx16(Plus2, { fontSize: "small" })
|
|
13453
|
+
}
|
|
13454
|
+
)
|
|
13455
|
+
},
|
|
13456
|
+
key ?? "attach"
|
|
13457
|
+
);
|
|
13107
13458
|
};
|
|
13108
13459
|
const renderMemoryButton = (key) => {
|
|
13109
13460
|
if (!hasMemoryAction) return null;
|
|
@@ -13203,6 +13554,15 @@ var ChatInput = (props) => {
|
|
|
13203
13554
|
gap: isMobile ? compactMobile ? 0.75 : 1 : 0.5
|
|
13204
13555
|
},
|
|
13205
13556
|
children: [
|
|
13557
|
+
attachmentNotice && !sendError && /* @__PURE__ */ jsx16(
|
|
13558
|
+
Box14,
|
|
13559
|
+
{
|
|
13560
|
+
role: "status",
|
|
13561
|
+
sx: { px: 0.5, pt: isMobile ? 0 : 0.5 },
|
|
13562
|
+
"data-testid": "attachment-notice",
|
|
13563
|
+
children: /* @__PURE__ */ jsx16(Typography8, { variant: "caption", sx: { color: tokens.status.error }, children: attachmentNotice })
|
|
13564
|
+
}
|
|
13565
|
+
),
|
|
13206
13566
|
sendError && /* @__PURE__ */ jsxs13(
|
|
13207
13567
|
Box14,
|
|
13208
13568
|
{
|
|
@@ -15184,7 +15544,7 @@ var gatewayBase = () => {
|
|
|
15184
15544
|
if (!url) throw new Error("Gateway API is not configured.");
|
|
15185
15545
|
return url;
|
|
15186
15546
|
};
|
|
15187
|
-
var
|
|
15547
|
+
var authHeaders2 = () => {
|
|
15188
15548
|
const headers = { "Content-Type": "application/json" };
|
|
15189
15549
|
const token = authenticationService.getToken();
|
|
15190
15550
|
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
@@ -15199,25 +15559,25 @@ var parse = async (res) => {
|
|
|
15199
15559
|
}
|
|
15200
15560
|
return body;
|
|
15201
15561
|
};
|
|
15202
|
-
var listMcpServers = async () => parse(await fetch(`${gatewayBase()}/mcp/servers`, { headers:
|
|
15562
|
+
var listMcpServers = async () => parse(await fetch(`${gatewayBase()}/mcp/servers`, { headers: authHeaders2() }));
|
|
15203
15563
|
var addMcpServer = async (input) => parse(
|
|
15204
15564
|
await fetch(`${gatewayBase()}/mcp/servers`, {
|
|
15205
15565
|
method: "POST",
|
|
15206
|
-
headers:
|
|
15566
|
+
headers: authHeaders2(),
|
|
15207
15567
|
body: JSON.stringify(input)
|
|
15208
15568
|
})
|
|
15209
15569
|
);
|
|
15210
15570
|
var updateMcpServer = async (id, input) => parse(
|
|
15211
15571
|
await fetch(`${gatewayBase()}/mcp/servers/${encodeURIComponent(id)}`, {
|
|
15212
15572
|
method: "PUT",
|
|
15213
|
-
headers:
|
|
15573
|
+
headers: authHeaders2(),
|
|
15214
15574
|
body: JSON.stringify(input)
|
|
15215
15575
|
})
|
|
15216
15576
|
);
|
|
15217
15577
|
var deleteMcpServer = async (id) => {
|
|
15218
15578
|
const res = await fetch(`${gatewayBase()}/mcp/servers/${encodeURIComponent(id)}`, {
|
|
15219
15579
|
method: "DELETE",
|
|
15220
|
-
headers:
|
|
15580
|
+
headers: authHeaders2()
|
|
15221
15581
|
});
|
|
15222
15582
|
if (!res.ok && res.status !== 204) {
|
|
15223
15583
|
throw new Error(`Could not remove the server (${res.status}).`);
|
|
@@ -15225,7 +15585,7 @@ var deleteMcpServer = async (id) => {
|
|
|
15225
15585
|
};
|
|
15226
15586
|
var discoverMcpTools = async (id) => parse(
|
|
15227
15587
|
await fetch(`${gatewayBase()}/mcp/servers/${encodeURIComponent(id)}/tools`, {
|
|
15228
|
-
headers:
|
|
15588
|
+
headers: authHeaders2()
|
|
15229
15589
|
})
|
|
15230
15590
|
);
|
|
15231
15591
|
|
|
@@ -15342,6 +15702,38 @@ var imageGenerationTool = {
|
|
|
15342
15702
|
method: "POST",
|
|
15343
15703
|
isBuiltIn: true
|
|
15344
15704
|
};
|
|
15705
|
+
var imageEditTool = {
|
|
15706
|
+
id: "image-edit",
|
|
15707
|
+
name: "image_edit",
|
|
15708
|
+
description: "Edit a photo the user attached to this message (lighting, style, background, remove or add something)",
|
|
15709
|
+
enabled: true,
|
|
15710
|
+
type: "function",
|
|
15711
|
+
function: {
|
|
15712
|
+
name: "image_edit",
|
|
15713
|
+
description: "Edit a photo the user attached to this message. Use when they ask to change, touch up, restyle or clean up their own photo.",
|
|
15714
|
+
parameters: {
|
|
15715
|
+
type: "object",
|
|
15716
|
+
properties: {
|
|
15717
|
+
instruction: {
|
|
15718
|
+
type: "string",
|
|
15719
|
+
description: "What to change, in plain words (e.g. 'brighten the lighting', 'make it a watercolor', 'remove the background')"
|
|
15720
|
+
},
|
|
15721
|
+
image: {
|
|
15722
|
+
type: "integer",
|
|
15723
|
+
description: "Which attached photo to edit, 1-based. Omit for the most recent one."
|
|
15724
|
+
},
|
|
15725
|
+
strength: {
|
|
15726
|
+
type: "number",
|
|
15727
|
+
description: "How far to depart from the original, 0.05 (subtle) to 1 (free). Omit for the model default."
|
|
15728
|
+
}
|
|
15729
|
+
},
|
|
15730
|
+
required: ["instruction"]
|
|
15731
|
+
}
|
|
15732
|
+
},
|
|
15733
|
+
endpoint: "/mcp/edit-image",
|
|
15734
|
+
method: "POST",
|
|
15735
|
+
isBuiltIn: true
|
|
15736
|
+
};
|
|
15345
15737
|
var CREATE_FILE_FORMATS = [
|
|
15346
15738
|
"md",
|
|
15347
15739
|
"txt",
|
|
@@ -15442,6 +15834,7 @@ var defaultTools = [
|
|
|
15442
15834
|
webSearchTool,
|
|
15443
15835
|
webFetchTool,
|
|
15444
15836
|
imageGenerationTool,
|
|
15837
|
+
imageEditTool,
|
|
15445
15838
|
createFileTool,
|
|
15446
15839
|
createScheduleTool
|
|
15447
15840
|
];
|
|
@@ -15744,6 +16137,9 @@ var executeMCPTool = async (toolCall) => {
|
|
|
15744
16137
|
endpoint: tool.endpoint,
|
|
15745
16138
|
parameters: toolCall.parameters
|
|
15746
16139
|
});
|
|
16140
|
+
if (isImageEditTool(tool.function.name)) {
|
|
16141
|
+
return executeImageEdit(toolCall, settings.gatewayApiUrl);
|
|
16142
|
+
}
|
|
15747
16143
|
const requestOptions = {
|
|
15748
16144
|
method,
|
|
15749
16145
|
headers: {
|
|
@@ -15776,7 +16172,8 @@ var executeMCPTool = async (toolCall) => {
|
|
|
15776
16172
|
}
|
|
15777
16173
|
}
|
|
15778
16174
|
const controller = new AbortController();
|
|
15779
|
-
const
|
|
16175
|
+
const timeoutMs = isImageTool(tool.function.name) ? IMAGE_TOOL_TIMEOUT_MS : 3e4;
|
|
16176
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
15780
16177
|
let response;
|
|
15781
16178
|
try {
|
|
15782
16179
|
response = await fetch(url, { ...requestOptions, signal: controller.signal });
|
|
@@ -15793,10 +16190,13 @@ var executeMCPTool = async (toolCall) => {
|
|
|
15793
16190
|
});
|
|
15794
16191
|
return {
|
|
15795
16192
|
success: false,
|
|
15796
|
-
error:
|
|
16193
|
+
error: toolErrorMessage(response, data),
|
|
15797
16194
|
data
|
|
15798
16195
|
};
|
|
15799
16196
|
}
|
|
16197
|
+
if (response.status === 202 && isImageTool(tool.function.name)) {
|
|
16198
|
+
return followImageJob(data, toolCall, settings.gatewayApiUrl);
|
|
16199
|
+
}
|
|
15800
16200
|
debugLogger.info("MCP tool executed successfully", {
|
|
15801
16201
|
toolName: toolCall.toolName,
|
|
15802
16202
|
resultPreview: JSON.stringify(data).substring(0, 200) + "..."
|
|
@@ -15832,6 +16232,98 @@ var isMCPAvailable = () => {
|
|
|
15832
16232
|
const { tools } = useMCPToolsStore.getState();
|
|
15833
16233
|
return !!(settings?.gatewayApiUrl && tools.some((t) => t.enabled));
|
|
15834
16234
|
};
|
|
16235
|
+
var toolErrorMessage = (response, data) => {
|
|
16236
|
+
const body = data ?? {};
|
|
16237
|
+
if (typeof body.code === "string") {
|
|
16238
|
+
const text = [body.error, body.message].find(
|
|
16239
|
+
(v) => typeof v === "string" && v.trim()
|
|
16240
|
+
);
|
|
16241
|
+
if (typeof text === "string") return text;
|
|
16242
|
+
}
|
|
16243
|
+
return `API call failed: ${response.status} ${response.statusText}`;
|
|
16244
|
+
};
|
|
16245
|
+
var gatewayBase2 = (gatewayUrl) => gatewayUrl.replace(/\/+$/, "").replace(/\/api$/, "");
|
|
16246
|
+
var followImageJob = async (first2, toolCall, gatewayUrl) => {
|
|
16247
|
+
if (!first2.jobId) {
|
|
16248
|
+
return {
|
|
16249
|
+
success: false,
|
|
16250
|
+
error: "The image service accepted the job but gave no job id.",
|
|
16251
|
+
data: first2
|
|
16252
|
+
};
|
|
16253
|
+
}
|
|
16254
|
+
toolCall.onProgress?.({
|
|
16255
|
+
status: first2.status ?? "queued",
|
|
16256
|
+
position: first2.position,
|
|
16257
|
+
etaSeconds: first2.etaSeconds,
|
|
16258
|
+
message: first2.message,
|
|
16259
|
+
backend: first2.backend
|
|
16260
|
+
});
|
|
16261
|
+
const final = await pollImageJob(
|
|
16262
|
+
first2.jobId,
|
|
16263
|
+
{
|
|
16264
|
+
gatewayUrl: gatewayBase2(gatewayUrl),
|
|
16265
|
+
token: authenticationService.getToken()
|
|
16266
|
+
},
|
|
16267
|
+
{ onProgress: toolCall.onProgress }
|
|
16268
|
+
);
|
|
16269
|
+
const merged = {
|
|
16270
|
+
...first2,
|
|
16271
|
+
...final,
|
|
16272
|
+
quota: final.quota ?? first2.quota
|
|
16273
|
+
};
|
|
16274
|
+
if (merged.status === "completed") return { success: true, data: merged };
|
|
16275
|
+
return {
|
|
16276
|
+
success: false,
|
|
16277
|
+
error: merged.error ?? merged.message ?? `The image job ended as ${merged.status ?? "unknown"}.`,
|
|
16278
|
+
data: merged
|
|
16279
|
+
};
|
|
16280
|
+
};
|
|
16281
|
+
var executeImageEdit = async (toolCall, gatewayUrl) => {
|
|
16282
|
+
const params = toolCall.parameters ?? {};
|
|
16283
|
+
const attachments = toolCall.attachments ?? [];
|
|
16284
|
+
if (attachments.length === 0) {
|
|
16285
|
+
return {
|
|
16286
|
+
success: false,
|
|
16287
|
+
error: "No photo is attached to this message. Attach the photo you want edited and ask again.",
|
|
16288
|
+
data: { code: "image_required" }
|
|
16289
|
+
};
|
|
16290
|
+
}
|
|
16291
|
+
const raw = params.image;
|
|
16292
|
+
const index = typeof raw === "number" && Number.isFinite(raw) && raw >= 1 && raw <= attachments.length ? Math.floor(raw) - 1 : attachments.length - 1;
|
|
16293
|
+
const instruction = typeof params.instruction === "string" ? params.instruction : typeof params.prompt === "string" ? params.prompt : "";
|
|
16294
|
+
const strength = typeof params.strength === "number" ? params.strength : void 0;
|
|
16295
|
+
const http = {
|
|
16296
|
+
gatewayUrl: gatewayBase2(gatewayUrl),
|
|
16297
|
+
token: authenticationService.getToken()
|
|
16298
|
+
};
|
|
16299
|
+
let status;
|
|
16300
|
+
let data;
|
|
16301
|
+
try {
|
|
16302
|
+
({ status, data } = await submitImageEdit({
|
|
16303
|
+
...http,
|
|
16304
|
+
imageDataUrl: attachments[index],
|
|
16305
|
+
instruction,
|
|
16306
|
+
strength
|
|
16307
|
+
}));
|
|
16308
|
+
} catch (error) {
|
|
16309
|
+
if (error instanceof ImageEditAcknowledgementRequired) {
|
|
16310
|
+
return {
|
|
16311
|
+
success: false,
|
|
16312
|
+
error: error.text,
|
|
16313
|
+
data: { code: "acknowledgement_required", error: error.text }
|
|
16314
|
+
};
|
|
16315
|
+
}
|
|
16316
|
+
throw error;
|
|
16317
|
+
}
|
|
16318
|
+
if (status === 202) return followImageJob(data, toolCall, gatewayUrl);
|
|
16319
|
+
if (status >= 200 && status < 300 && data.status === "completed")
|
|
16320
|
+
return { success: true, data };
|
|
16321
|
+
return {
|
|
16322
|
+
success: false,
|
|
16323
|
+
error: data.error ?? data.message ?? `Photo edit failed (${status}).`,
|
|
16324
|
+
data
|
|
16325
|
+
};
|
|
16326
|
+
};
|
|
15835
16327
|
|
|
15836
16328
|
// src/services/schedules/scheduleTool.ts
|
|
15837
16329
|
var requestScheduleConfirmation = async (args) => {
|
|
@@ -16800,7 +17292,8 @@ ${TOOL_JUDGMENT_RULES}
|
|
|
16800
17292
|
- Available tools and when to use them:
|
|
16801
17293
|
* web_search() - when asked about recent/current events, breaking news, live information (weather, prices, sports scores), or when you need to look up documentation, libraries, APIs, error messages, or verify a specific fact
|
|
16802
17294
|
* web_fetch() - to read the FULL contents of a specific URL you already have. Reach for this when the user wants to "tell me more", "go deeper", "read/open that article", or asks for details about a specific source, link, or article from an EARLIER answer: take that item's URL from the previous Sources list in this conversation and fetch it, then answer from the page's actual content (not just the prior summary)
|
|
16803
|
-
* image_generation() - ONLY when explicitly asked to create or generate an image. Runs on Burtson's
|
|
17295
|
+
* image_generation({"prompt": "...", "size": "1024x1024"}) - ONLY when explicitly asked to create or generate an image. Paid plans only, within a daily allowance per plan (a free account is told image generation is on paid plans \u2014 relay that with the plans link, don't retry). Runs on Burtson's own GPU; when the queue is long a paid job may run in the cloud instead to skip it
|
|
17296
|
+
* image_edit({"instruction": "..."}) - ONLY when the user attached a photo to THIS message and asks to change it (touch up lighting, restyle, remove the background, remove or add something). The attached photo is sent automatically; never ask for a link or describe the photo back. Same daily allowance as image_generation. Nothing sexual involving real people, nothing involving minors in revealing contexts, nothing meant to deceive (fake documents, compromising scenes, impersonation) \u2014 refuse those yourself
|
|
16804
17297
|
* create_file({"content": "...", "filename": "report.docx", "format": "docx"}) - when the user asks for a downloadable FILE (a document, spreadsheet, slides, markdown, code, etc.) or to "export"/"download"/"save" something. Formats: md, txt, csv, json, html, xml, yaml, docx, pptx, xlsx, pdf. For docx/pptx write well-structured Markdown (use "## " headings to start each slide for pptx). For pdf, prefer complete HTML with inline CSS. For a SPREADSHEET use format "xlsx" and put the data in a "spreadsheet" object, e.g. create_file({"content": "FY26 budget by region", "filename": "budget.xlsx", "format": "xlsx", "spreadsheet": {"title": "FY26 Budget", "sheets": [{"name": "Summary", "columns": [{"header": "Region", "type": "text"}, {"header": "Revenue", "type": "currency", "currency": "USD"}, {"header": "Growth", "type": "percent"}, {"header": "Closed", "type": "date"}], "rows": [["North", 1200.5, 0.12, "2026-01-31"], ["South", 800, 0.08, "2026-02-28"]], "totals": true}]}}) \u2014 numbers as JSON numbers (never "1,200" strings), dates as ISO strings, percents as fractions, {"formula": "B2*C2"} for a formula, one entry in "sheets" per tab; never CSV text for xlsx. The tool result says whether the file was saved to the user's Stash (lasting link \u2014 say so) or is a temporary link (~1 hour \u2014 tell the user it expires). If it is unclear whether they want it shown inline vs. as a downloadable file, use ask_user first.
|
|
16805
17298
|
* ask_user({"questions": [{"question": "...", "header": "Format", "options": [{"label": "Inline (Recommended)"}, {"label": "Download a file"}]}]}) - when the request is AMBIGUOUS or missing a detail you need to do a good job (unclear scope, audience, format, tone, which of several interpretations they meant), or you are blocked on a decision that is the user's to make and cannot resolve from the request, context, or sensible defaults. Renders clickable options the user answers in one step \u2014 ALWAYS prefer this over asking a clarifying question in prose and ending your turn. Give 1-4 questions, each with 2-4 short options; if one is clearly best, list it first and append " (Recommended)". The user may also type their own answer; act on it directly. Don't overuse it \u2014 when a sensible default exists, take it and note the assumption instead.
|
|
16806
17299
|
* create_schedule({"name": "Morning AI brief", "prompt": "Summarise the most important AI news of the past day with sources", "preset": "weekdays", "time": "08:00"}) - when the user wants something done on a RECURRING schedule or at a set time each day or week ("every weekday at 8", "each morning", "daily", "every Monday", "send me \u2026 every \u2026"). Put the complete task in "prompt" (self-contained: the run has no chat context). preset: daily | weekdays | weekly (add "weekday") | custom (add "cron"). Omit time_zone to use the user's own. This opens a confirmation card the user must approve and may edit; wait for the tool result and never say a schedule exists until it reports it was created.
|
|
@@ -16859,6 +17352,45 @@ ${protocol}`;
|
|
|
16859
17352
|
let sawToolBlock = false;
|
|
16860
17353
|
const nativeToolCalls = [];
|
|
16861
17354
|
let toolTrail = [];
|
|
17355
|
+
const runImageAwareTool = async (fn, params, attachments, pendingLabel) => {
|
|
17356
|
+
if (!isImageTool(fn)) {
|
|
17357
|
+
return executeMCPTool({ toolName: fn, parameters: params });
|
|
17358
|
+
}
|
|
17359
|
+
const onProgress = (progress) => {
|
|
17360
|
+
const label = imageQueueLabel(
|
|
17361
|
+
isImageEditTool(fn) ? "Editing the photo" : "Generating an image",
|
|
17362
|
+
progress
|
|
17363
|
+
);
|
|
17364
|
+
pushTrail(pendingTrailItemWithStatus(fn, params, label));
|
|
17365
|
+
startWorking(
|
|
17366
|
+
progress.status === "queued" ? label.replace(/^[^—]+— /, "Queued ") : progress.backend === "cloud" ? label : pendingLabel
|
|
17367
|
+
);
|
|
17368
|
+
};
|
|
17369
|
+
const call = () => executeMCPTool({ toolName: fn, parameters: params, attachments, onProgress });
|
|
17370
|
+
let result = await call();
|
|
17371
|
+
const code = (result.data ?? {}).code;
|
|
17372
|
+
if (!result.success && isPlanRequired(result.data)) {
|
|
17373
|
+
return { success: true, data: result.data };
|
|
17374
|
+
}
|
|
17375
|
+
if (!result.success && code === "acknowledgement_required") {
|
|
17376
|
+
const text = (result.data ?? {}).error ?? result.error ?? "";
|
|
17377
|
+
const accepted = await useImageEditAckStore.getState().ask(text);
|
|
17378
|
+
if (!accepted) {
|
|
17379
|
+
return {
|
|
17380
|
+
success: false,
|
|
17381
|
+
error: "The photo edit was not started: the acknowledgement was declined.",
|
|
17382
|
+
data: { code: "acknowledgement_declined" }
|
|
17383
|
+
};
|
|
17384
|
+
}
|
|
17385
|
+
const settings = usePackageSettingsStore.getState().settings;
|
|
17386
|
+
const ok = await acknowledgeImageEdit({
|
|
17387
|
+
gatewayUrl: (settings?.gatewayApiUrl ?? "").replace(/\/+$/, "").replace(/\/api$/, ""),
|
|
17388
|
+
token: authenticationService.getToken()
|
|
17389
|
+
});
|
|
17390
|
+
if (ok) result = await call();
|
|
17391
|
+
}
|
|
17392
|
+
return result;
|
|
17393
|
+
};
|
|
16862
17394
|
const pushTrail = (item) => {
|
|
16863
17395
|
const next = upsertTrailItem(toolTrail, item);
|
|
16864
17396
|
if (next === toolTrail) return;
|
|
@@ -16876,6 +17408,7 @@ ${protocol}`;
|
|
|
16876
17408
|
"web_search",
|
|
16877
17409
|
"web_fetch",
|
|
16878
17410
|
"image_generation",
|
|
17411
|
+
"image_edit",
|
|
16879
17412
|
"create_file",
|
|
16880
17413
|
"ask_user",
|
|
16881
17414
|
"ask-user",
|
|
@@ -16898,11 +17431,11 @@ ${protocol}`;
|
|
|
16898
17431
|
const fenceIdx = t.search(/```(?:tool_code|TOOL_CODE)/);
|
|
16899
17432
|
if (fenceIdx !== -1) t = t.slice(0, fenceIdx);
|
|
16900
17433
|
const callIdx = t.search(
|
|
16901
|
-
/\b(?:web_search|web_fetch|image_generation|create_file|ask_user|create_schedule)\s*\(/
|
|
17434
|
+
/\b(?:web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule)\s*\(/
|
|
16902
17435
|
);
|
|
16903
17436
|
if (callIdx !== -1) t = t.slice(0, callIdx);
|
|
16904
17437
|
const jsonIdx = t.search(
|
|
16905
|
-
/\{\s*"name"\s*:\s*"(?:web_search|web_fetch|image_generation|create_file|ask_user|create_schedule)"/
|
|
17438
|
+
/\{\s*"name"\s*:\s*"(?:web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule)"/
|
|
16906
17439
|
);
|
|
16907
17440
|
if (jsonIdx !== -1) t = t.slice(0, jsonIdx);
|
|
16908
17441
|
t = t.replace(/```[\w-]*\s*$/, "");
|
|
@@ -16976,17 +17509,17 @@ ${protocol}`;
|
|
|
16976
17509
|
setIsThinking?.(inThinkBlock);
|
|
16977
17510
|
const visibleMessage = stripThinking2(fullMessage);
|
|
16978
17511
|
const bareToolMatch = visibleMessage.match(
|
|
16979
|
-
/\b(web_search|web_fetch|image_generation|create_file|ask_user|create_schedule)\s*\(/
|
|
17512
|
+
/\b(web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule)\s*\(/
|
|
16980
17513
|
) || // JSON-form calls from cloud/native-tool engines.
|
|
16981
17514
|
visibleMessage.match(
|
|
16982
|
-
/\{\s*"name"\s*:\s*"(web_search|web_fetch|image_generation|create_file|ask_user|create_schedule)"/
|
|
17515
|
+
/\{\s*"name"\s*:\s*"(web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule)"/
|
|
16983
17516
|
);
|
|
16984
17517
|
if (/```(?:tool_code|TOOL_CODE)/.test(visibleMessage) || bareToolMatch) {
|
|
16985
17518
|
sawToolBlock = true;
|
|
16986
17519
|
clearFlushTimer();
|
|
16987
17520
|
const fn = bareToolMatch?.[1];
|
|
16988
17521
|
startWorking(
|
|
16989
|
-
fn === "create_schedule" ? "Setting up your schedule" : fn === "create_file" ? "Creating your file" : fn === "web_search" ? "Searching the web" : fn === "web_fetch" ? "Reading the page" : fn === "image_generation" ? "Generating the image" : "Working on it"
|
|
17522
|
+
fn === "create_schedule" ? "Setting up your schedule" : fn === "create_file" ? "Creating your file" : fn === "web_search" ? "Searching the web" : fn === "web_fetch" ? "Reading the page" : fn === "image_generation" ? "Generating the image" : fn === "image_edit" ? "Editing the photo" : "Working on it"
|
|
16990
17523
|
);
|
|
16991
17524
|
}
|
|
16992
17525
|
latestDisplayMessage = visibleMessage;
|
|
@@ -17317,17 +17850,14 @@ A: ${(answers[q.id] || "").trim() || "(no answer)"}`
|
|
|
17317
17850
|
const placeholderToken = `<<TOOL_LOADING_${functionName}_${Math.random().toString(36).slice(2)}>>`;
|
|
17318
17851
|
enhancedMessage = enhancedMessage.replace(match, placeholderToken);
|
|
17319
17852
|
clearFlushTimer();
|
|
17320
|
-
const toolStatus = functionName === "web_search" || functionName === "web-search" ? "Searching the web" : functionName === "web_fetch" || functionName === "web-fetch" ? "Reading the page" : functionName === "image_generation" || functionName === "image-generation" ? "Generating the image" : functionName === "create_file" || functionName === "create-file" ? "Creating your file" : "Working on it";
|
|
17853
|
+
const toolStatus = functionName === "web_search" || functionName === "web-search" ? "Searching the web" : functionName === "web_fetch" || functionName === "web-fetch" ? "Reading the page" : functionName === "image_generation" || functionName === "image-generation" ? "Generating the image" : isImageEditTool(functionName) ? "Editing the photo" : functionName === "create_file" || functionName === "create-file" ? "Creating your file" : "Working on it";
|
|
17321
17854
|
startWorking(toolStatus);
|
|
17322
17855
|
pushTrail(pendingTrailItem(functionName, parsedParams));
|
|
17323
17856
|
telemetryEvent("tool_loop:tool_execute", {
|
|
17324
17857
|
name: functionName,
|
|
17325
17858
|
params: parsedParams
|
|
17326
17859
|
});
|
|
17327
|
-
const result = await
|
|
17328
|
-
toolName: functionName,
|
|
17329
|
-
parameters: parsedParams
|
|
17330
|
-
});
|
|
17860
|
+
const result = await runImageAwareTool(functionName, parsedParams, imageList, toolStatus);
|
|
17331
17861
|
telemetryEvent(
|
|
17332
17862
|
result.success ? "tool_loop:tool_result" : "tool_loop:tool_error",
|
|
17333
17863
|
{
|
|
@@ -17346,15 +17876,13 @@ A: ${(answers[q.id] || "").trim() || "(no answer)"}`
|
|
|
17346
17876
|
result,
|
|
17347
17877
|
collectedSources
|
|
17348
17878
|
);
|
|
17349
|
-
} else if (functionName
|
|
17350
|
-
const
|
|
17351
|
-
|
|
17352
|
-
|
|
17353
|
-
|
|
17354
|
-
|
|
17355
|
-
|
|
17356
|
-
${revisedPrompt ? `Prompt refinement: \u201C${revisedPrompt}\u201D
|
|
17357
|
-
` : ""}Note: the image link may expire in ~2 hours.` : "Image generated successfully.";
|
|
17879
|
+
} else if (isImageTool(functionName)) {
|
|
17880
|
+
const image = formatImageResult(
|
|
17881
|
+
result.data ?? {},
|
|
17882
|
+
isImageEditTool(functionName) ? "edit" : "generate",
|
|
17883
|
+
{ noUpgrade: usePackageSettingsStore.getState().settings?.hideUpgradePrompts === true }
|
|
17884
|
+
);
|
|
17885
|
+
resultText = image.inline || image.forModel;
|
|
17358
17886
|
} else if (functionName === "create_file" || functionName === "create-file") {
|
|
17359
17887
|
resultText = describeCreatedFile(result.data).markdown;
|
|
17360
17888
|
} else if (typeof result.data === "string") {
|
|
@@ -17378,7 +17906,7 @@ ${revisedPrompt ? `Prompt refinement: \u201C${revisedPrompt}\u201D
|
|
|
17378
17906
|
}
|
|
17379
17907
|
enhancedMessage = enhancedMessage.replace(placeholderToken, resultText);
|
|
17380
17908
|
if (result.success) {
|
|
17381
|
-
if (functionName
|
|
17909
|
+
if (isImageTool(functionName) || functionName === "create_file" || functionName === "create-file") {
|
|
17382
17910
|
inlineImageBlocks.push(resultText);
|
|
17383
17911
|
} else if (functionName !== "check_gateway_health") {
|
|
17384
17912
|
summarizableResults.push({
|
|
@@ -17533,14 +18061,11 @@ A: ${(ans[q.id] || "").trim() || "(no answer)"}`
|
|
|
17533
18061
|
);
|
|
17534
18062
|
return scheduleOutcomeForModel(outcome);
|
|
17535
18063
|
}
|
|
17536
|
-
const status = fn === "create_file" || fn === "create-file" ? "Creating your file" : fn === "web_search" || fn === "web-search" ? "Searching the web" : fn === "web_fetch" || fn === "web-fetch" ? "Reading the page" : fn === "image_generation" || fn === "image-generation" ? "Generating the image" : "Working on it";
|
|
18064
|
+
const status = fn === "create_file" || fn === "create-file" ? "Creating your file" : fn === "web_search" || fn === "web-search" ? "Searching the web" : fn === "web_fetch" || fn === "web-fetch" ? "Reading the page" : fn === "image_generation" || fn === "image-generation" ? "Generating the image" : isImageEditTool(fn) ? "Editing the photo" : "Working on it";
|
|
17537
18065
|
startWorking(status);
|
|
17538
18066
|
pushTrail(pendingTrailItem(fn, params));
|
|
17539
18067
|
telemetryEvent("tool_loop:tool_execute", { name: fn, params });
|
|
17540
|
-
const result = await
|
|
17541
|
-
toolName: fn,
|
|
17542
|
-
parameters: params
|
|
17543
|
-
});
|
|
18068
|
+
const result = await runImageAwareTool(fn, params, imageList, status);
|
|
17544
18069
|
record(trailItemForTool(fn, params, result));
|
|
17545
18070
|
if (!result.success)
|
|
17546
18071
|
return `That step failed: ${result.error || "unknown error"}.`;
|
|
@@ -17553,11 +18078,15 @@ A: ${(ans[q.id] || "").trim() || "(no answer)"}`
|
|
|
17553
18078
|
if (created.url) inlineImageBlocks.push(created.markdown);
|
|
17554
18079
|
return created.modelNote;
|
|
17555
18080
|
}
|
|
17556
|
-
if (fn
|
|
17557
|
-
const
|
|
17558
|
-
|
|
17559
|
-
|
|
17560
|
-
|
|
18081
|
+
if (isImageTool(fn)) {
|
|
18082
|
+
const image = formatImageResult(
|
|
18083
|
+
result.data ?? {},
|
|
18084
|
+
isImageEditTool(fn) ? "edit" : "generate",
|
|
18085
|
+
{ noUpgrade: usePackageSettingsStore.getState().settings?.hideUpgradePrompts === true }
|
|
18086
|
+
);
|
|
18087
|
+
if (image.inline) {
|
|
18088
|
+
inlineImageBlocks.push(image.inline);
|
|
18089
|
+
return image.forModel;
|
|
17561
18090
|
}
|
|
17562
18091
|
}
|
|
17563
18092
|
return formatToolResultForModel(fn, result, collectedSources);
|
|
@@ -18033,21 +18562,8 @@ var useNetworkStatus = () => {
|
|
|
18033
18562
|
};
|
|
18034
18563
|
|
|
18035
18564
|
// src/chat/chat-app-bar.tsx
|
|
18036
|
-
import { Avatar as Avatar10 } from "@mui/material";
|
|
18037
18565
|
import { useEffect as useEffect21, useRef as useRef16, useState as useState25 } from "react";
|
|
18038
|
-
import {
|
|
18039
|
-
Box as Box26,
|
|
18040
|
-
IconButton as IconButton19,
|
|
18041
|
-
Tooltip as Tooltip13,
|
|
18042
|
-
useMediaQuery as useMediaQuery10,
|
|
18043
|
-
useTheme as useTheme23,
|
|
18044
|
-
Dialog as Dialog9,
|
|
18045
|
-
DialogTitle as DialogTitle6,
|
|
18046
|
-
DialogContent as DialogContent6,
|
|
18047
|
-
DialogActions as DialogActions6,
|
|
18048
|
-
Typography as Typography21,
|
|
18049
|
-
Button as Button12
|
|
18050
|
-
} from "@mui/material";
|
|
18566
|
+
import { Box as Box26, IconButton as IconButton19, Tooltip as Tooltip13, useMediaQuery as useMediaQuery10, useTheme as useTheme23 } from "@mui/material";
|
|
18051
18567
|
import { useNavigate as useNavigate2 } from "react-router-dom";
|
|
18052
18568
|
|
|
18053
18569
|
// src/chat/conversation-drawer.tsx
|
|
@@ -22733,16 +23249,17 @@ var SidebarBody = ({ variant, onRequestClose }) => {
|
|
|
22733
23249
|
anchorOrigin: { vertical: "bottom", horizontal: "right" },
|
|
22734
23250
|
transformOrigin: { vertical: "top", horizontal: "right" },
|
|
22735
23251
|
children: [
|
|
22736
|
-
syncEnabled && /* @__PURE__ */ jsxs22(
|
|
23252
|
+
syncEnabled && (syncStatus === "syncing" || syncStatus === "error") && /* @__PURE__ */ jsxs22(
|
|
22737
23253
|
MenuItem6,
|
|
22738
23254
|
{
|
|
23255
|
+
disabled: syncStatus === "syncing",
|
|
22739
23256
|
onClick: () => {
|
|
22740
23257
|
setMenuAnchor(null);
|
|
22741
|
-
|
|
23258
|
+
void runSync({ force: true });
|
|
22742
23259
|
},
|
|
22743
23260
|
children: [
|
|
22744
23261
|
/* @__PURE__ */ jsx25(ListItemIcon3, { children: syncStatus === "error" ? /* @__PURE__ */ jsx25(AlertCircle, { size: 16, color: theme.palette.error.main }) : /* @__PURE__ */ jsx25(Refresh, { size: 16 }) }),
|
|
22745
|
-
/* @__PURE__ */ jsx25(ListItemText3, { children: syncStatus === "error" ? "Sync needs attention. Retry" :
|
|
23262
|
+
/* @__PURE__ */ jsx25(ListItemText3, { children: syncStatus === "error" ? "Sync needs attention. Retry" : "Syncing\u2026" })
|
|
22746
23263
|
]
|
|
22747
23264
|
}
|
|
22748
23265
|
),
|
|
@@ -23021,12 +23538,12 @@ var MobileSidebar = ({ open, onClose, drag }) => {
|
|
|
23021
23538
|
};
|
|
23022
23539
|
|
|
23023
23540
|
// src/chat/sidebar/ProjectsPaneLazy.tsx
|
|
23024
|
-
import { Suspense, lazy } from "react";
|
|
23541
|
+
import { Suspense as Suspense2, lazy } from "react";
|
|
23025
23542
|
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
23026
23543
|
var Pane = lazy(
|
|
23027
|
-
() => import("./ProjectsPane-
|
|
23544
|
+
() => import("./ProjectsPane-E5D72PUG.mjs").then((module) => ({ default: module.ProjectsPane }))
|
|
23028
23545
|
);
|
|
23029
|
-
var ProjectsPane = (props) => /* @__PURE__ */ jsx28(
|
|
23546
|
+
var ProjectsPane = (props) => /* @__PURE__ */ jsx28(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx28(Pane, { ...props }) });
|
|
23030
23547
|
|
|
23031
23548
|
// src/chat/sidebar/useSidebarShortcuts.ts
|
|
23032
23549
|
import { useEffect as useEffect20 } from "react";
|
|
@@ -23107,18 +23624,8 @@ var MobileViewTitle = () => {
|
|
|
23107
23624
|
import { useShallow as useShallow2 } from "zustand/react/shallow";
|
|
23108
23625
|
import { alpha as alpha16 } from "@mui/material/styles";
|
|
23109
23626
|
import { Fragment as Fragment16, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
23110
|
-
var CDN_BASE = "https://cdn.burtson.ai/";
|
|
23111
|
-
var banditHead2 = `${CDN_BASE}/images/bandit-head.png`;
|
|
23112
|
-
var modelAvatars2 = {
|
|
23113
|
-
"Bandit-Core": `${CDN_BASE}/avatars/core-avatar.png`,
|
|
23114
|
-
"Bandit-Muse": `${CDN_BASE}/avatars/muse-avatar.png`,
|
|
23115
|
-
"Bandit-Logic": `${CDN_BASE}/avatars/logic-avatar.png`,
|
|
23116
|
-
"Bandit-D1VA": `${CDN_BASE}/avatars/d1va-avatar.png`,
|
|
23117
|
-
"Bandit-Exec": `${CDN_BASE}/avatars/exec-avatar.png`
|
|
23118
|
-
};
|
|
23119
23627
|
var ChatAppBar = ({
|
|
23120
23628
|
availableModels,
|
|
23121
|
-
handleModelChange,
|
|
23122
23629
|
selectedVoice,
|
|
23123
23630
|
availableVoices,
|
|
23124
23631
|
handleVoiceChange,
|
|
@@ -23165,8 +23672,6 @@ var ChatAppBar = ({
|
|
|
23165
23672
|
setInternalModalOpen(open);
|
|
23166
23673
|
onMobileConversationsOpenChange?.(open);
|
|
23167
23674
|
};
|
|
23168
|
-
const [confirmModelChangeOpen, setConfirmModelChangeOpen] = useState25(false);
|
|
23169
|
-
const [pendingModel, setPendingModel] = useState25(null);
|
|
23170
23675
|
const {
|
|
23171
23676
|
conversations,
|
|
23172
23677
|
currentId,
|
|
@@ -23254,10 +23759,6 @@ var ChatAppBar = ({
|
|
|
23254
23759
|
);
|
|
23255
23760
|
};
|
|
23256
23761
|
const selectedModel = useModelStore((s) => s.selectedModel);
|
|
23257
|
-
const currentModel = useModelStore(
|
|
23258
|
-
(s) => s.availableModels.find((m) => m.name === selectedModel)
|
|
23259
|
-
);
|
|
23260
|
-
const currentAvatar = currentModel?.avatarBase64 || modelAvatars2[selectedModel] || banditHead2;
|
|
23261
23762
|
const engines = useEngineStore((s) => s.engines);
|
|
23262
23763
|
const selectedEngine = useEngineStore((s) => s.selectedEngine);
|
|
23263
23764
|
const effectiveEngineId = selectedEngine || usePackageSettingsStore.getState().settings?.defaultModel || "bandit-core";
|
|
@@ -23268,7 +23769,6 @@ var ChatAppBar = ({
|
|
|
23268
23769
|
useEffect21(() => {
|
|
23269
23770
|
useEngineStore.getState().fetchEngines();
|
|
23270
23771
|
}, []);
|
|
23271
|
-
const pendingModelAvatar = useModelStore.getState().availableModels.find((m) => m.name === pendingModel)?.avatarBase64 || modelAvatars2[pendingModel || ""] || banditHead2;
|
|
23272
23772
|
return /* @__PURE__ */ jsxs25(Fragment16, { children: [
|
|
23273
23773
|
/* @__PURE__ */ jsxs25(
|
|
23274
23774
|
Box26,
|
|
@@ -23415,7 +23915,7 @@ var ChatAppBar = ({
|
|
|
23415
23915
|
"aria-pressed": drawerOpen,
|
|
23416
23916
|
children: [
|
|
23417
23917
|
/* @__PURE__ */ jsx30(PanelLeft, {}),
|
|
23418
|
-
conversations.length > 0 && /* @__PURE__ */ jsx30(
|
|
23918
|
+
conversations.length > 0 && !sectionsLayout && /* @__PURE__ */ jsx30(
|
|
23419
23919
|
Box26,
|
|
23420
23920
|
{
|
|
23421
23921
|
sx: {
|
|
@@ -23533,86 +24033,7 @@ var ChatAppBar = ({
|
|
|
23533
24033
|
drag: mobileConversationsDrag
|
|
23534
24034
|
}
|
|
23535
24035
|
)
|
|
23536
|
-
] })
|
|
23537
|
-
/* @__PURE__ */ jsxs25(
|
|
23538
|
-
Dialog9,
|
|
23539
|
-
{
|
|
23540
|
-
open: confirmModelChangeOpen,
|
|
23541
|
-
onClose: () => setConfirmModelChangeOpen(false),
|
|
23542
|
-
children: [
|
|
23543
|
-
/* @__PURE__ */ jsx30(DialogTitle6, { children: "Change personality and start new conversation?" }),
|
|
23544
|
-
/* @__PURE__ */ jsx30(DialogContent6, { children: /* @__PURE__ */ jsxs25(Box26, { display: "flex", alignItems: "center", gap: 2, mt: 1, justifyContent: "center", children: [
|
|
23545
|
-
/* @__PURE__ */ jsx30(
|
|
23546
|
-
Avatar10,
|
|
23547
|
-
{
|
|
23548
|
-
src: pendingModelAvatar,
|
|
23549
|
-
alt: pendingModel || "Personality Avatar",
|
|
23550
|
-
sx: { width: 40, height: 40, filter: "brightness(1.7)" }
|
|
23551
|
-
}
|
|
23552
|
-
),
|
|
23553
|
-
/* @__PURE__ */ jsxs25(Typography21, { variant: "body2", children: [
|
|
23554
|
-
"Your current conversation will be saved, and a new one will begin with",
|
|
23555
|
-
" ",
|
|
23556
|
-
/* @__PURE__ */ jsx30("strong", { children: pendingModel }),
|
|
23557
|
-
"."
|
|
23558
|
-
] })
|
|
23559
|
-
] }) }),
|
|
23560
|
-
/* @__PURE__ */ jsxs25(DialogActions6, { children: [
|
|
23561
|
-
/* @__PURE__ */ jsx30(Button12, { onClick: () => setConfirmModelChangeOpen(false), children: "Cancel" }),
|
|
23562
|
-
/* @__PURE__ */ jsx30(
|
|
23563
|
-
Button12,
|
|
23564
|
-
{
|
|
23565
|
-
onClick: () => {
|
|
23566
|
-
if (pendingModel) {
|
|
23567
|
-
createNewConversation();
|
|
23568
|
-
handleModelChange(pendingModel);
|
|
23569
|
-
useModelStore.getState().setSelectedModel(pendingModel);
|
|
23570
|
-
(async () => {
|
|
23571
|
-
try {
|
|
23572
|
-
const storeConfigs2 = [{ name: "config", keyPath: "id" }];
|
|
23573
|
-
const current = await indexedDBService_default.get(
|
|
23574
|
-
"banditConfig",
|
|
23575
|
-
1,
|
|
23576
|
-
"config",
|
|
23577
|
-
"main",
|
|
23578
|
-
storeConfigs2
|
|
23579
|
-
);
|
|
23580
|
-
const updated = {
|
|
23581
|
-
...current ?? {},
|
|
23582
|
-
id: "main",
|
|
23583
|
-
model: {
|
|
23584
|
-
...current?.model || {},
|
|
23585
|
-
name: pendingModel,
|
|
23586
|
-
selectedModel: pendingModel
|
|
23587
|
-
}
|
|
23588
|
-
};
|
|
23589
|
-
await indexedDBService_default.put(
|
|
23590
|
-
"banditConfig",
|
|
23591
|
-
1,
|
|
23592
|
-
"config",
|
|
23593
|
-
updated,
|
|
23594
|
-
storeConfigs2
|
|
23595
|
-
);
|
|
23596
|
-
} catch (err) {
|
|
23597
|
-
debugLogger.error("Failed to persist selectedModel to IndexedDB", {
|
|
23598
|
-
error: err
|
|
23599
|
-
});
|
|
23600
|
-
}
|
|
23601
|
-
})();
|
|
23602
|
-
const { conversations: conversations2, currentId: currentId2 } = useConversationStore.getState();
|
|
23603
|
-
const conv = conversations2.find((c) => c.id === currentId2);
|
|
23604
|
-
if (conv) conv.model = pendingModel;
|
|
23605
|
-
}
|
|
23606
|
-
setConfirmModelChangeOpen(false);
|
|
23607
|
-
},
|
|
23608
|
-
color: "error",
|
|
23609
|
-
children: "Change Personality"
|
|
23610
|
-
}
|
|
23611
|
-
)
|
|
23612
|
-
] })
|
|
23613
|
-
]
|
|
23614
|
-
}
|
|
23615
|
-
)
|
|
24036
|
+
] })
|
|
23616
24037
|
] });
|
|
23617
24038
|
};
|
|
23618
24039
|
var chat_app_bar_default = ChatAppBar;
|
|
@@ -23632,7 +24053,7 @@ var stashBaseUrl = () => {
|
|
|
23632
24053
|
return /\/api$/i.test(trimmed) ? trimmed : `${trimmed}/api`;
|
|
23633
24054
|
};
|
|
23634
24055
|
var stashAvailable = () => stashBaseUrl() !== null && Boolean(authenticationService.getToken());
|
|
23635
|
-
var
|
|
24056
|
+
var authHeaders3 = () => {
|
|
23636
24057
|
const token = authenticationService.getToken();
|
|
23637
24058
|
if (!token) throw new StashError("Sign in to save to Stash.", 401);
|
|
23638
24059
|
return { Authorization: `Bearer ${token}` };
|
|
@@ -23657,7 +24078,7 @@ var saveToStash = async (args) => {
|
|
|
23657
24078
|
const query = args.scope === "team" ? "?scope=team" : "";
|
|
23658
24079
|
const response = await fetch(`${base}/artifact${query}`, {
|
|
23659
24080
|
method: "POST",
|
|
23660
|
-
headers:
|
|
24081
|
+
headers: authHeaders3(),
|
|
23661
24082
|
body,
|
|
23662
24083
|
signal: args.signal
|
|
23663
24084
|
});
|
|
@@ -23684,7 +24105,7 @@ var createStashShareLink = async (args) => {
|
|
|
23684
24105
|
if (!base) throw new StashError("Stash isn't configured here.");
|
|
23685
24106
|
const response = await fetch(`${base}/artifact/share`, {
|
|
23686
24107
|
method: "POST",
|
|
23687
|
-
headers: { ...
|
|
24108
|
+
headers: { ...authHeaders3(), "Content-Type": "application/json" },
|
|
23688
24109
|
body: JSON.stringify({ key: args.key, expiryMinutes: args.expiryMinutes ?? null }),
|
|
23689
24110
|
signal: args.signal
|
|
23690
24111
|
});
|
|
@@ -24560,7 +24981,7 @@ function startConversationWithBackgroundTitle(question, generateName) {
|
|
|
24560
24981
|
|
|
24561
24982
|
// src/chat/query-suggestion-picker.tsx
|
|
24562
24983
|
import { useEffect as useEffect22, useRef as useRef17, useState as useState26 } from "react";
|
|
24563
|
-
import { Box as Box27, Button as
|
|
24984
|
+
import { Box as Box27, Button as Button12, Typography as Typography21 } from "@mui/material";
|
|
24564
24985
|
import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
24565
24986
|
var STARTERS = [
|
|
24566
24987
|
{
|
|
@@ -24649,9 +25070,9 @@ function QuerySuggestionPicker({ onSend, onSelect }) {
|
|
|
24649
25070
|
mb: 1.5
|
|
24650
25071
|
},
|
|
24651
25072
|
children: [
|
|
24652
|
-
/* @__PURE__ */ jsx31(
|
|
25073
|
+
/* @__PURE__ */ jsx31(Typography21, { variant: "body2", sx: { fontWeight: 600 }, children: "What would move your work forward?" }),
|
|
24653
25074
|
/* @__PURE__ */ jsx31(
|
|
24654
|
-
|
|
25075
|
+
Button12,
|
|
24655
25076
|
{
|
|
24656
25077
|
size: "small",
|
|
24657
25078
|
startIcon: /* @__PURE__ */ jsx31(Refresh, { size: 14 }),
|
|
@@ -24678,7 +25099,7 @@ function QuerySuggestionPicker({ onSend, onSelect }) {
|
|
|
24678
25099
|
icon: ArrowRight,
|
|
24679
25100
|
prompt
|
|
24680
25101
|
})) : STARTERS).map(({ title, detail, icon: Icon, prompt }) => /* @__PURE__ */ jsxs26(
|
|
24681
|
-
|
|
25102
|
+
Button12,
|
|
24682
25103
|
{
|
|
24683
25104
|
variant: "outlined",
|
|
24684
25105
|
onClick: () => select(prompt),
|
|
@@ -24705,7 +25126,7 @@ function QuerySuggestionPicker({ onSend, onSelect }) {
|
|
|
24705
25126
|
),
|
|
24706
25127
|
/* @__PURE__ */ jsxs26(Box27, { component: "span", children: [
|
|
24707
25128
|
/* @__PURE__ */ jsx31(
|
|
24708
|
-
|
|
25129
|
+
Typography21,
|
|
24709
25130
|
{
|
|
24710
25131
|
component: "span",
|
|
24711
25132
|
variant: "body2",
|
|
@@ -24714,7 +25135,7 @@ function QuerySuggestionPicker({ onSend, onSelect }) {
|
|
|
24714
25135
|
}
|
|
24715
25136
|
),
|
|
24716
25137
|
detail && /* @__PURE__ */ jsx31(
|
|
24717
|
-
|
|
25138
|
+
Typography21,
|
|
24718
25139
|
{
|
|
24719
25140
|
component: "span",
|
|
24720
25141
|
variant: "caption",
|
|
@@ -24735,7 +25156,7 @@ function QuerySuggestionPicker({ onSend, onSelect }) {
|
|
|
24735
25156
|
}
|
|
24736
25157
|
),
|
|
24737
25158
|
/* @__PURE__ */ jsx31(
|
|
24738
|
-
|
|
25159
|
+
Typography21,
|
|
24739
25160
|
{
|
|
24740
25161
|
variant: "caption",
|
|
24741
25162
|
sx: { display: "block", color: "text.secondary", mt: 1.25 },
|
|
@@ -24743,7 +25164,7 @@ function QuerySuggestionPicker({ onSend, onSelect }) {
|
|
|
24743
25164
|
}
|
|
24744
25165
|
),
|
|
24745
25166
|
message && /* @__PURE__ */ jsx31(
|
|
24746
|
-
|
|
25167
|
+
Typography21,
|
|
24747
25168
|
{
|
|
24748
25169
|
role: "status",
|
|
24749
25170
|
variant: "caption",
|
|
@@ -25322,7 +25743,7 @@ function createBanditTheme(config = {}, ...overrides) {
|
|
|
25322
25743
|
|
|
25323
25744
|
// ../bandit-themes/src/provider.tsx
|
|
25324
25745
|
import { ThemeProvider } from "@mui/material/styles";
|
|
25325
|
-
import * as
|
|
25746
|
+
import * as React21 from "react";
|
|
25326
25747
|
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
25327
25748
|
function BanditThemeProvider({
|
|
25328
25749
|
theme,
|
|
@@ -25332,9 +25753,9 @@ function BanditThemeProvider({
|
|
|
25332
25753
|
style,
|
|
25333
25754
|
children
|
|
25334
25755
|
}) {
|
|
25335
|
-
const resolved =
|
|
25756
|
+
const resolved = React21.useMemo(() => theme ?? createBanditTheme(config), [theme, config]);
|
|
25336
25757
|
const { cssVars, mode } = resolved.bandit;
|
|
25337
|
-
|
|
25758
|
+
React21.useLayoutEffect(() => {
|
|
25338
25759
|
if (scope !== "document" || typeof document === "undefined") return;
|
|
25339
25760
|
const root = document.documentElement;
|
|
25340
25761
|
const previous = /* @__PURE__ */ new Map();
|
|
@@ -25475,14 +25896,14 @@ var volcanicDarkTheme = skinThemes["volcanic-dark"];
|
|
|
25475
25896
|
var volcanicLightTheme = skinThemes["volcanic-light"];
|
|
25476
25897
|
|
|
25477
25898
|
// ../bandit-themes/src/TenantPreview.tsx
|
|
25478
|
-
import
|
|
25899
|
+
import Avatar10 from "@mui/material/Avatar";
|
|
25479
25900
|
import Box28 from "@mui/material/Box";
|
|
25480
|
-
import
|
|
25901
|
+
import Button13 from "@mui/material/Button";
|
|
25481
25902
|
import Paper5 from "@mui/material/Paper";
|
|
25482
25903
|
import Stack2 from "@mui/material/Stack";
|
|
25483
|
-
import
|
|
25904
|
+
import Typography22 from "@mui/material/Typography";
|
|
25484
25905
|
import { useTheme as useTheme24 } from "@mui/material/styles";
|
|
25485
|
-
import * as
|
|
25906
|
+
import * as React22 from "react";
|
|
25486
25907
|
import { jsx as jsx33, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
25487
25908
|
function TenantPreview({
|
|
25488
25909
|
accent,
|
|
@@ -25498,7 +25919,7 @@ function TenantPreview({
|
|
|
25498
25919
|
const pageMode = useTheme24().palette.mode;
|
|
25499
25920
|
const shown = modes ?? (pageMode === "light" ? ["light", "dark"] : ["dark", "light"]);
|
|
25500
25921
|
return /* @__PURE__ */ jsxs27(Stack2, { spacing: 1.5, role: "group", "aria-label": "Branding preview", children: [
|
|
25501
|
-
title !== null && /* @__PURE__ */ jsx33(
|
|
25922
|
+
title !== null && /* @__PURE__ */ jsx33(Typography22, { component: "h3", variant: "subtitle2", sx: { fontWeight: 600 }, children: title }),
|
|
25502
25923
|
/* @__PURE__ */ jsx33(
|
|
25503
25924
|
Box28,
|
|
25504
25925
|
{
|
|
@@ -25535,7 +25956,7 @@ function PreviewPane({
|
|
|
25535
25956
|
density,
|
|
25536
25957
|
renderBody
|
|
25537
25958
|
}) {
|
|
25538
|
-
const theme =
|
|
25959
|
+
const theme = React22.useMemo(
|
|
25539
25960
|
() => createBanditTheme({
|
|
25540
25961
|
mode,
|
|
25541
25962
|
skin,
|
|
@@ -25555,21 +25976,21 @@ function PreviewPane({
|
|
|
25555
25976
|
children: [
|
|
25556
25977
|
/* @__PURE__ */ jsxs27(Stack2, { direction: "row", spacing: 1.25, alignItems: "center", sx: { minWidth: 0 }, children: [
|
|
25557
25978
|
logoUrl ? /* @__PURE__ */ jsx33(Box28, { component: "img", src: logoUrl, alt: "", sx: { width: 28, height: 28, objectFit: "contain", flexShrink: 0 } }) : /* @__PURE__ */ jsx33(
|
|
25558
|
-
|
|
25979
|
+
Avatar10,
|
|
25559
25980
|
{
|
|
25560
25981
|
"aria-hidden": true,
|
|
25561
25982
|
sx: { width: 28, height: 28, fontSize: 13, fontWeight: 600, bgcolor: "primary.main", color: "primary.contrastText" },
|
|
25562
25983
|
children: label.charAt(0).toUpperCase()
|
|
25563
25984
|
}
|
|
25564
25985
|
),
|
|
25565
|
-
/* @__PURE__ */ jsx33(
|
|
25566
|
-
/* @__PURE__ */ jsx33(
|
|
25986
|
+
/* @__PURE__ */ jsx33(Typography22, { sx: { fontWeight: 600, minWidth: 0, flex: 1, overflowWrap: "anywhere" }, children: label }),
|
|
25987
|
+
/* @__PURE__ */ jsx33(Typography22, { variant: "caption", color: "text.secondary", sx: { textTransform: "capitalize", flexShrink: 0 }, children: mode })
|
|
25567
25988
|
] }),
|
|
25568
|
-
tagline ? /* @__PURE__ */ jsx33(
|
|
25989
|
+
tagline ? /* @__PURE__ */ jsx33(Typography22, { variant: "body2", color: "text.secondary", sx: { mt: 0.5 }, children: tagline }) : null,
|
|
25569
25990
|
renderBody ? /* @__PURE__ */ jsx33(Box28, { sx: { mt: 2 }, children: renderBody(mode) }) : /* @__PURE__ */ jsxs27(Stack2, { direction: "row", spacing: 1.5, alignItems: "center", sx: { mt: 2 }, children: [
|
|
25570
|
-
/* @__PURE__ */ jsx33(
|
|
25991
|
+
/* @__PURE__ */ jsx33(Button13, { variant: "contained", size: "small", tabIndex: -1, children: "New chat" }),
|
|
25571
25992
|
/* @__PURE__ */ jsx33(
|
|
25572
|
-
|
|
25993
|
+
Typography22,
|
|
25573
25994
|
{
|
|
25574
25995
|
variant: "body2",
|
|
25575
25996
|
sx: (t) => ({ color: t.bandit.tokens.brand, textDecoration: "underline", textUnderlineOffset: 3 }),
|
|
@@ -25577,7 +25998,7 @@ function PreviewPane({
|
|
|
25577
25998
|
}
|
|
25578
25999
|
)
|
|
25579
26000
|
] }),
|
|
25580
|
-
adjusted && /* @__PURE__ */ jsxs27(
|
|
26001
|
+
adjusted && /* @__PURE__ */ jsxs27(Typography22, { variant: "caption", color: "text.secondary", sx: { display: "block", mt: 1.5 }, children: [
|
|
25581
26002
|
"Adjusted in ",
|
|
25582
26003
|
mode,
|
|
25583
26004
|
" mode to keep text readable."
|
|
@@ -25588,7 +26009,7 @@ function PreviewPane({
|
|
|
25588
26009
|
}
|
|
25589
26010
|
|
|
25590
26011
|
// src/components/UnderReview.tsx
|
|
25591
|
-
import { Box as Box29, Typography as
|
|
26012
|
+
import { Box as Box29, Typography as Typography23, useTheme as useTheme25 } from "@mui/material";
|
|
25592
26013
|
import { useNavigate as useNavigate3 } from "react-router-dom";
|
|
25593
26014
|
import { jsx as jsx34, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
25594
26015
|
var UnderReview = () => {
|
|
@@ -25641,14 +26062,14 @@ var UnderReview = () => {
|
|
|
25641
26062
|
}
|
|
25642
26063
|
),
|
|
25643
26064
|
/* @__PURE__ */ jsx34(
|
|
25644
|
-
|
|
26065
|
+
Typography23,
|
|
25645
26066
|
{
|
|
25646
26067
|
variant: "h4",
|
|
25647
26068
|
sx: { mb: 2, fontWeight: 700, color: theme.palette.error.main },
|
|
25648
26069
|
children: "Under Review"
|
|
25649
26070
|
}
|
|
25650
26071
|
),
|
|
25651
|
-
/* @__PURE__ */ jsxs28(
|
|
26072
|
+
/* @__PURE__ */ jsxs28(Typography23, { variant: "body1", sx: { mb: 2, color: theme.palette.text.secondary }, children: [
|
|
25652
26073
|
"Your request to use this deployment is currently being reviewed.",
|
|
25653
26074
|
/* @__PURE__ */ jsx34("br", {}),
|
|
25654
26075
|
"For more info, contact your deployment admin or",
|
|
@@ -25670,7 +26091,7 @@ var UnderReview_default = UnderReview;
|
|
|
25670
26091
|
|
|
25671
26092
|
// src/components/feedback/FeedbackPulse.tsx
|
|
25672
26093
|
import { useEffect as useEffect23, useRef as useRef18, useState as useState27 } from "react";
|
|
25673
|
-
import { Box as Box30, IconButton as IconButton20, Paper as Paper6, Slide as Slide3, Typography as
|
|
26094
|
+
import { Box as Box30, IconButton as IconButton20, Paper as Paper6, Slide as Slide3, Typography as Typography24 } from "@mui/material";
|
|
25674
26095
|
import { useTheme as useTheme26, alpha as alpha17 } from "@mui/material/styles";
|
|
25675
26096
|
import { Fragment as Fragment17, jsx as jsx35, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
25676
26097
|
var STORAGE_KEY2 = "bandit-feedback-pulse-last";
|
|
@@ -25777,7 +26198,7 @@ var FeedbackPulse = ({
|
|
|
25777
26198
|
},
|
|
25778
26199
|
children: [
|
|
25779
26200
|
/* @__PURE__ */ jsx35(Box30, { component: "span", sx: { display: "inline-flex", lineHeight: 1 }, children: icon }),
|
|
25780
|
-
/* @__PURE__ */ jsx35(
|
|
26201
|
+
/* @__PURE__ */ jsx35(Typography24, { variant: "caption", sx: { fontWeight: 600 }, children: label })
|
|
25781
26202
|
]
|
|
25782
26203
|
}
|
|
25783
26204
|
);
|
|
@@ -25801,9 +26222,9 @@ var FeedbackPulse = ({
|
|
|
25801
26222
|
bgcolor: theme.palette.background.paper,
|
|
25802
26223
|
boxShadow: `0 12px 40px ${alpha17(theme.palette.common.black, theme.palette.mode === "dark" ? 0.5 : 0.18)}`
|
|
25803
26224
|
},
|
|
25804
|
-
children: thanked ? /* @__PURE__ */ jsx35(
|
|
26225
|
+
children: thanked ? /* @__PURE__ */ jsx35(Typography24, { sx: { textAlign: "center", py: 1.5, fontWeight: 600 }, children: "Thanks for the feedback!" }) : /* @__PURE__ */ jsxs29(Fragment17, { children: [
|
|
25805
26226
|
/* @__PURE__ */ jsxs29(Box30, { sx: { display: "flex", alignItems: "center", mb: 0.5 }, children: [
|
|
25806
|
-
/* @__PURE__ */ jsx35(
|
|
26227
|
+
/* @__PURE__ */ jsx35(Typography24, { variant: "body2", sx: { fontWeight: 600, flex: 1 }, children: "How's Bandit doing?" }),
|
|
25807
26228
|
/* @__PURE__ */ jsx35(
|
|
25808
26229
|
IconButton20,
|
|
25809
26230
|
{
|
|
@@ -26329,7 +26750,8 @@ var useVoiceMode = (config) => {
|
|
|
26329
26750
|
|
|
26330
26751
|
// src/chat/chat.tsx
|
|
26331
26752
|
import { Fragment as Fragment18, jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
26332
|
-
var
|
|
26753
|
+
var ImageEditAcknowledgement = React25.lazy(() => import("./image-edit-acknowledgement-RZPQYKYJ.mjs"));
|
|
26754
|
+
var ScheduleConfirmCard = lazy2(() => import("./schedule-confirm-card-D4K76HEA.mjs"));
|
|
26333
26755
|
var CLASSIC_DRAWER_WIDTH = 340;
|
|
26334
26756
|
var ChatContent = () => {
|
|
26335
26757
|
const packageSettings = usePackageSettingsStore((state) => state.settings);
|
|
@@ -27868,7 +28290,7 @@ var ChatContent = () => {
|
|
|
27868
28290
|
color: theme.palette.text.primary
|
|
27869
28291
|
}),
|
|
27870
28292
|
children: /* @__PURE__ */ jsx38(
|
|
27871
|
-
|
|
28293
|
+
Typography25,
|
|
27872
28294
|
{
|
|
27873
28295
|
sx: {
|
|
27874
28296
|
fontWeight: 500,
|
|
@@ -27895,7 +28317,7 @@ var ChatContent = () => {
|
|
|
27895
28317
|
color: theme.palette.text.primary
|
|
27896
28318
|
}),
|
|
27897
28319
|
children: /* @__PURE__ */ jsx38(
|
|
27898
|
-
|
|
28320
|
+
Typography25,
|
|
27899
28321
|
{
|
|
27900
28322
|
sx: {
|
|
27901
28323
|
fontWeight: 600,
|
|
@@ -27931,11 +28353,11 @@ var ChatContent = () => {
|
|
|
27931
28353
|
}),
|
|
27932
28354
|
children: [
|
|
27933
28355
|
/* @__PURE__ */ jsxs31(Box32, { sx: { flex: 1, minWidth: 0 }, children: [
|
|
27934
|
-
/* @__PURE__ */ jsx38(
|
|
27935
|
-
/* @__PURE__ */ jsx38(
|
|
28356
|
+
/* @__PURE__ */ jsx38(Typography25, { variant: "body2", sx: { fontWeight: 600 }, children: "Add your documents" }),
|
|
28357
|
+
/* @__PURE__ */ jsx38(Typography25, { variant: "caption", color: "text.secondary", children: "Upload your policies, handbooks or notes and Bandit answers from them, with sources." })
|
|
27936
28358
|
] }),
|
|
27937
28359
|
/* @__PURE__ */ jsx38(
|
|
27938
|
-
|
|
28360
|
+
Button14,
|
|
27939
28361
|
{
|
|
27940
28362
|
size: "small",
|
|
27941
28363
|
variant: "outlined",
|
|
@@ -28029,7 +28451,8 @@ var ChatContent = () => {
|
|
|
28029
28451
|
) }),
|
|
28030
28452
|
/* @__PURE__ */ jsx38(rate_limit_prompt_default, {}),
|
|
28031
28453
|
/* @__PURE__ */ jsx38(ask_user_card_default, {}),
|
|
28032
|
-
|
|
28454
|
+
/* @__PURE__ */ jsx38(React25.Suspense, { fallback: null, children: /* @__PURE__ */ jsx38(ImageEditAcknowledgement, {}) }),
|
|
28455
|
+
schedulePending && /* @__PURE__ */ jsx38(Suspense3, { fallback: null, children: /* @__PURE__ */ jsx38(ScheduleConfirmCard, {}) }),
|
|
28033
28456
|
/* @__PURE__ */ jsx38(
|
|
28034
28457
|
chat_input_default,
|
|
28035
28458
|
{
|
|
@@ -28178,11 +28601,10 @@ export {
|
|
|
28178
28601
|
createBrandingTheme,
|
|
28179
28602
|
describeBrandingTheme,
|
|
28180
28603
|
registry_default,
|
|
28181
|
-
predefinedThemes,
|
|
28182
28604
|
themeSkinIds,
|
|
28183
28605
|
banditDarkTheme,
|
|
28184
28606
|
TenantPreview,
|
|
28185
28607
|
useNotificationService,
|
|
28186
28608
|
chat_default
|
|
28187
28609
|
};
|
|
28188
|
-
//# sourceMappingURL=chunk-
|
|
28610
|
+
//# sourceMappingURL=chunk-4NHPLHXU.mjs.map
|