@burtson-labs/bandit-engine 2.1.8 → 2.1.9
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 +6 -0
- package/dist/{AdvancedTab-HZTDXFST.mjs → AdvancedTab-D7SDAQEL.mjs} +4 -4
- package/dist/CrewSection-N2J3TJGU.mjs +15 -0
- package/dist/{PersonalizationTab-2XHFTYYW.mjs → PersonalizationTab-KPTVJKB3.mjs} +6 -6
- package/dist/{ProjectsPane-KE5DGFN4.mjs → ProjectsPane-C63C6GW5.mjs} +11 -10
- package/dist/ProjectsPane-C63C6GW5.mjs.map +1 -0
- package/dist/{SchedulesTab-AM5QP36K.mjs → SchedulesTab-TEOM3NWQ.mjs} +12 -12
- package/dist/{chat-D66YM4MB.mjs → chat-QAEEYO73.mjs} +16 -13
- package/dist/chunk-3CDCJJ4S.mjs +64 -0
- package/dist/chunk-3CDCJJ4S.mjs.map +1 -0
- package/dist/{chunk-FBLITVVY.mjs → chunk-5JNKGMMN.mjs} +31 -5
- package/dist/chunk-5JNKGMMN.mjs.map +1 -0
- package/dist/chunk-F56OTXXR.mjs +17 -0
- package/dist/chunk-F56OTXXR.mjs.map +1 -0
- package/dist/{chunk-LAH6UL3Q.mjs → chunk-GN3X7IIZ.mjs} +10 -10
- package/dist/{chunk-2FI2IICG.mjs → chunk-JGJRY4MR.mjs} +2 -2
- package/dist/chunk-MR643IO6.mjs +294 -0
- package/dist/chunk-MR643IO6.mjs.map +1 -0
- package/dist/{chunk-WZGDQ4EA.mjs → chunk-MX37LD3Z.mjs} +382 -81
- package/dist/chunk-MX37LD3Z.mjs.map +1 -0
- package/dist/{chunk-2THUYNVU.mjs → chunk-MX7Z4RSP.mjs} +2 -2
- package/dist/{chunk-5WCKKD3S.mjs → chunk-P42M52OW.mjs} +18 -28
- package/dist/chunk-P42M52OW.mjs.map +1 -0
- package/dist/{chunk-5URP2E5V.mjs → chunk-UT46TXNG.mjs} +42 -6
- package/dist/chunk-UT46TXNG.mjs.map +1 -0
- package/dist/{chunk-2HFSBPOE.mjs → chunk-WDFQG3RM.mjs} +21 -1
- package/dist/chunk-WDFQG3RM.mjs.map +1 -0
- package/dist/chunk-XWUHUDAV.mjs +814 -0
- package/dist/chunk-XWUHUDAV.mjs.map +1 -0
- package/dist/{chunk-K4AO466X.mjs → chunk-YY7BX2HM.mjs} +10 -14
- package/dist/chunk-YY7BX2HM.mjs.map +1 -0
- package/dist/crew-delegate-card-I4SSZU5H.mjs +229 -0
- package/dist/crew-delegate-card-I4SSZU5H.mjs.map +1 -0
- package/dist/crew-mention-picker-OSJ2NHUB.mjs +118 -0
- package/dist/crew-mention-picker-OSJ2NHUB.mjs.map +1 -0
- package/dist/crew-task-card-ZCXFTR34.mjs +416 -0
- package/dist/crew-task-card-ZCXFTR34.mjs.map +1 -0
- package/dist/index.js +7142 -5177
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -59
- package/dist/index.mjs.map +1 -1
- package/dist/{schedule-confirm-card-D4K76HEA.mjs → schedule-confirm-card-Y2JF2RBV.mjs} +5 -5
- package/package.json +1 -1
- package/dist/CrewSection-YM26YD2N.mjs +0 -12
- package/dist/ProjectsPane-KE5DGFN4.mjs.map +0 -1
- package/dist/chunk-2HFSBPOE.mjs.map +0 -1
- package/dist/chunk-5URP2E5V.mjs.map +0 -1
- package/dist/chunk-5WCKKD3S.mjs.map +0 -1
- package/dist/chunk-EKPPIS3X.mjs +0 -336
- package/dist/chunk-EKPPIS3X.mjs.map +0 -1
- package/dist/chunk-FBLITVVY.mjs.map +0 -1
- package/dist/chunk-K4AO466X.mjs.map +0 -1
- package/dist/chunk-WZGDQ4EA.mjs.map +0 -1
- /package/dist/{AdvancedTab-HZTDXFST.mjs.map → AdvancedTab-D7SDAQEL.mjs.map} +0 -0
- /package/dist/{CrewSection-YM26YD2N.mjs.map → CrewSection-N2J3TJGU.mjs.map} +0 -0
- /package/dist/{PersonalizationTab-2XHFTYYW.mjs.map → PersonalizationTab-KPTVJKB3.mjs.map} +0 -0
- /package/dist/{SchedulesTab-AM5QP36K.mjs.map → SchedulesTab-TEOM3NWQ.mjs.map} +0 -0
- /package/dist/{chat-D66YM4MB.mjs.map → chat-QAEEYO73.mjs.map} +0 -0
- /package/dist/{chunk-LAH6UL3Q.mjs.map → chunk-GN3X7IIZ.mjs.map} +0 -0
- /package/dist/{chunk-2FI2IICG.mjs.map → chunk-JGJRY4MR.mjs.map} +0 -0
- /package/dist/{chunk-2THUYNVU.mjs.map → chunk-MX7Z4RSP.mjs.map} +0 -0
- /package/dist/{schedule-confirm-card-D4K76HEA.mjs.map → schedule-confirm-card-Y2JF2RBV.mjs.map} +0 -0
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getStreamingTTSClient,
|
|
3
|
+
sanitizeForTTS,
|
|
4
|
+
stopTTS,
|
|
5
|
+
useVoiceStore
|
|
6
|
+
} from "./chunk-LC64VSDS.mjs";
|
|
7
|
+
import {
|
|
8
|
+
useImageEditAckStore
|
|
9
|
+
} from "./chunk-WBKTQJNX.mjs";
|
|
10
|
+
import {
|
|
11
|
+
useScheduleConfirmStore
|
|
12
|
+
} from "./chunk-HS62C62A.mjs";
|
|
13
|
+
import {
|
|
14
|
+
IS_STORE_BUILD,
|
|
15
|
+
crewSurfacesEnabled,
|
|
16
|
+
managementConsoleVariant,
|
|
17
|
+
useCrewStore
|
|
18
|
+
} from "./chunk-3CDCJJ4S.mjs";
|
|
1
19
|
import {
|
|
2
20
|
MarkdownImage,
|
|
3
21
|
StreamingMarkdown_default,
|
|
@@ -5,7 +23,12 @@ import {
|
|
|
5
23
|
markdownSanitizeSchema,
|
|
6
24
|
maybeHandleFileLinkClick,
|
|
7
25
|
renderLowlightChildren
|
|
8
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-JGJRY4MR.mjs";
|
|
27
|
+
import {
|
|
28
|
+
browserTimeZone,
|
|
29
|
+
formatInZone,
|
|
30
|
+
normalizeScheduleArgs
|
|
31
|
+
} from "./chunk-MAKXJD7A.mjs";
|
|
9
32
|
import {
|
|
10
33
|
ATTRIBUTION_RULE,
|
|
11
34
|
CONTEXT_USAGE_RULES,
|
|
@@ -16,6 +39,7 @@ import {
|
|
|
16
39
|
buildCitationGuide,
|
|
17
40
|
canonicalToolName,
|
|
18
41
|
contextNoteForTrail,
|
|
42
|
+
crewTaskIdOf,
|
|
19
43
|
fetchConversationById,
|
|
20
44
|
formatToolResultForModel,
|
|
21
45
|
mapConversationFromDTO,
|
|
@@ -31,16 +55,7 @@ import {
|
|
|
31
55
|
useMemoryStore,
|
|
32
56
|
useVectorStore,
|
|
33
57
|
vectorDatabaseService
|
|
34
|
-
} from "./chunk-
|
|
35
|
-
import {
|
|
36
|
-
useInstructionsStore
|
|
37
|
-
} from "./chunk-H2XUGGKV.mjs";
|
|
38
|
-
import {
|
|
39
|
-
getStreamingTTSClient,
|
|
40
|
-
sanitizeForTTS,
|
|
41
|
-
stopTTS,
|
|
42
|
-
useVoiceStore
|
|
43
|
-
} from "./chunk-LC64VSDS.mjs";
|
|
58
|
+
} from "./chunk-5JNKGMMN.mjs";
|
|
44
59
|
import {
|
|
45
60
|
AlertCircle as AlertCircle2,
|
|
46
61
|
ArrowDown,
|
|
@@ -75,7 +90,10 @@ import {
|
|
|
75
90
|
X as X2,
|
|
76
91
|
ZoomIn,
|
|
77
92
|
ZoomOut
|
|
78
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-YY7BX2HM.mjs";
|
|
94
|
+
import {
|
|
95
|
+
useInstructionsStore
|
|
96
|
+
} from "./chunk-H2XUGGKV.mjs";
|
|
79
97
|
import {
|
|
80
98
|
GatewayService,
|
|
81
99
|
useAIProviderStore
|
|
@@ -91,8 +109,6 @@ import {
|
|
|
91
109
|
brandingService_default,
|
|
92
110
|
groupByRecency,
|
|
93
111
|
initialSidebarOpen,
|
|
94
|
-
isNativeShell,
|
|
95
|
-
isStandalonePwa,
|
|
96
112
|
listable,
|
|
97
113
|
managementPathFor,
|
|
98
114
|
move_conversation_modal_default,
|
|
@@ -104,7 +120,11 @@ import {
|
|
|
104
120
|
useSectionsLayout,
|
|
105
121
|
useSidebarStore,
|
|
106
122
|
writePersistedCollapsed
|
|
107
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-P42M52OW.mjs";
|
|
124
|
+
import {
|
|
125
|
+
isNativeShell,
|
|
126
|
+
isStandalonePwa
|
|
127
|
+
} from "./chunk-F56OTXXR.mjs";
|
|
108
128
|
import {
|
|
109
129
|
ComposerControl,
|
|
110
130
|
accentTokens,
|
|
@@ -132,7 +152,7 @@ import {
|
|
|
132
152
|
useFeatureVisibility,
|
|
133
153
|
useFeatures,
|
|
134
154
|
useProjectStore
|
|
135
|
-
} from "./chunk-
|
|
155
|
+
} from "./chunk-GN3X7IIZ.mjs";
|
|
136
156
|
import {
|
|
137
157
|
useModelStore,
|
|
138
158
|
usePreferencesStore
|
|
@@ -141,16 +161,16 @@ import {
|
|
|
141
161
|
indexedDBService_default
|
|
142
162
|
} from "./chunk-KPT7NNNK.mjs";
|
|
143
163
|
import {
|
|
144
|
-
|
|
145
|
-
} from "./chunk-
|
|
164
|
+
usePackageSettingsStore
|
|
165
|
+
} from "./chunk-K7SQWDNF.mjs";
|
|
146
166
|
import {
|
|
147
|
-
|
|
148
|
-
|
|
167
|
+
authenticationService,
|
|
168
|
+
readPersistedToken,
|
|
169
|
+
useAuthenticationStore
|
|
170
|
+
} from "./chunk-S3DWWUBD.mjs";
|
|
149
171
|
import {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
normalizeScheduleArgs
|
|
153
|
-
} from "./chunk-MAKXJD7A.mjs";
|
|
172
|
+
debugLogger
|
|
173
|
+
} from "./chunk-NI7BKLC7.mjs";
|
|
154
174
|
import {
|
|
155
175
|
Activity,
|
|
156
176
|
Agent,
|
|
@@ -206,27 +226,17 @@ import {
|
|
|
206
226
|
ThumbsUp,
|
|
207
227
|
Trash,
|
|
208
228
|
TrendingUp,
|
|
229
|
+
Users,
|
|
209
230
|
Waveform,
|
|
210
231
|
Wrench,
|
|
211
232
|
X
|
|
212
|
-
} from "./chunk-
|
|
213
|
-
import {
|
|
214
|
-
usePackageSettingsStore
|
|
215
|
-
} from "./chunk-K7SQWDNF.mjs";
|
|
216
|
-
import {
|
|
217
|
-
authenticationService,
|
|
218
|
-
readPersistedToken,
|
|
219
|
-
useAuthenticationStore
|
|
220
|
-
} from "./chunk-S3DWWUBD.mjs";
|
|
221
|
-
import {
|
|
222
|
-
debugLogger
|
|
223
|
-
} from "./chunk-NI7BKLC7.mjs";
|
|
233
|
+
} from "./chunk-UT46TXNG.mjs";
|
|
224
234
|
|
|
225
235
|
// src/chat/chat.tsx
|
|
226
|
-
import
|
|
236
|
+
import React25 from "react";
|
|
227
237
|
import {
|
|
228
|
-
lazy as
|
|
229
|
-
Suspense as
|
|
238
|
+
lazy as lazy3,
|
|
239
|
+
Suspense as Suspense4,
|
|
230
240
|
useCallback as useCallback12,
|
|
231
241
|
useEffect as useEffect24,
|
|
232
242
|
useLayoutEffect as useLayoutEffect2,
|
|
@@ -487,12 +497,6 @@ function ChatStartupSkeleton() {
|
|
|
487
497
|
);
|
|
488
498
|
}
|
|
489
499
|
|
|
490
|
-
// src/utils/storeBuild.ts
|
|
491
|
-
var IS_STORE_BUILD = typeof __BANDIT_STORE_BUILD__ !== "undefined" && __BANDIT_STORE_BUILD__ === true;
|
|
492
|
-
|
|
493
|
-
// src/management/shell/console.ts
|
|
494
|
-
var managementConsoleVariant = () => IS_STORE_BUILD || isNativeShell() ? "native" : "web";
|
|
495
|
-
|
|
496
500
|
// src/store/canvasStore.ts
|
|
497
501
|
import { create } from "zustand";
|
|
498
502
|
var useCanvasStore = create((set) => ({
|
|
@@ -762,6 +766,7 @@ var BanditChatLogo = ({
|
|
|
762
766
|
var bandit_chat_logo_default = BanditChatLogo;
|
|
763
767
|
|
|
764
768
|
// src/chat/chat-messages.tsx
|
|
769
|
+
import React7 from "react";
|
|
765
770
|
import { Box as Box10 } from "@mui/material";
|
|
766
771
|
|
|
767
772
|
// src/modals/chat-modal/ai-response-text-field.tsx
|
|
@@ -4910,6 +4915,7 @@ var ICONS = {
|
|
|
4910
4915
|
create_file: FileText,
|
|
4911
4916
|
ask_user: HelpCircle,
|
|
4912
4917
|
create_schedule: Clock,
|
|
4918
|
+
crew: Users,
|
|
4913
4919
|
health_check: Activity,
|
|
4914
4920
|
context: Library,
|
|
4915
4921
|
transcribe: Mic,
|
|
@@ -5041,6 +5047,7 @@ var tool_trail_view_default = ToolTrail;
|
|
|
5041
5047
|
|
|
5042
5048
|
// src/chat/chat-messages.tsx
|
|
5043
5049
|
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
5050
|
+
var CrewTaskCard = React7.lazy(() => import("./crew-task-card-ZCXFTR34.mjs"));
|
|
5044
5051
|
var WORKING_TOKEN_RE = /\s*<<working:([^>]*)>>\s*$/;
|
|
5045
5052
|
var BYTE_TOKEN_RUN_RE = /(?:<0x[0-9A-Fa-f]{2}>)+/g;
|
|
5046
5053
|
var decodeByteTokens = (text) => {
|
|
@@ -5146,6 +5153,7 @@ var ChatMessages = ({
|
|
|
5146
5153
|
},
|
|
5147
5154
|
children: [
|
|
5148
5155
|
/* @__PURE__ */ jsx12(tool_trail_view_default, { items: entry.toolsUsed, attachments: entry.images }),
|
|
5156
|
+
crewTaskIdOf(entry.toolsUsed) && /* @__PURE__ */ jsx12(React7.Suspense, { fallback: null, children: /* @__PURE__ */ jsx12(CrewTaskCard, { taskId: crewTaskIdOf(entry.toolsUsed) }) }),
|
|
5149
5157
|
/* @__PURE__ */ jsx12(
|
|
5150
5158
|
Box10,
|
|
5151
5159
|
{
|
|
@@ -5253,7 +5261,7 @@ var ChatMessages = ({
|
|
|
5253
5261
|
var chat_messages_default = ChatMessages;
|
|
5254
5262
|
|
|
5255
5263
|
// src/chat/chat-input.tsx
|
|
5256
|
-
import
|
|
5264
|
+
import React9, { Suspense as Suspense2, lazy, useEffect as useEffect9, useRef as useRef5, useState as useState12 } from "react";
|
|
5257
5265
|
import {
|
|
5258
5266
|
Box as Box13,
|
|
5259
5267
|
Button as Button3,
|
|
@@ -6391,6 +6399,102 @@ function markAiReminderSeen(now = Date.now(), storage = defaultStorage()) {
|
|
|
6391
6399
|
// src/chat/chat-input.tsx
|
|
6392
6400
|
import { useTheme as useTheme10, alpha as alpha7 } from "@mui/material/styles";
|
|
6393
6401
|
|
|
6402
|
+
// src/services/crew/crewTool.ts
|
|
6403
|
+
var DELEGATE_TOOL_NAME = "delegate_to_bandit";
|
|
6404
|
+
var isDelegateTool = (name) => name === DELEGATE_TOOL_NAME || name === "delegate-to-bandit";
|
|
6405
|
+
var pick = (raw, ...keys) => {
|
|
6406
|
+
for (const key of keys) {
|
|
6407
|
+
const value = raw[key];
|
|
6408
|
+
if (value !== void 0 && value !== null && value !== "") return value;
|
|
6409
|
+
}
|
|
6410
|
+
return void 0;
|
|
6411
|
+
};
|
|
6412
|
+
var asString = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
6413
|
+
var banditHandle = (name) => name.trim().replace(/^@/, "").toLowerCase();
|
|
6414
|
+
var normalizeDelegateArgs = (raw, bandits = []) => {
|
|
6415
|
+
const args = raw ?? {};
|
|
6416
|
+
const problems = [];
|
|
6417
|
+
const named = asString(
|
|
6418
|
+
pick(
|
|
6419
|
+
args,
|
|
6420
|
+
"bandit",
|
|
6421
|
+
"bandit_name",
|
|
6422
|
+
"banditName",
|
|
6423
|
+
"name",
|
|
6424
|
+
"to",
|
|
6425
|
+
"teammate",
|
|
6426
|
+
"assignee"
|
|
6427
|
+
)
|
|
6428
|
+
);
|
|
6429
|
+
const prompt = asString(
|
|
6430
|
+
pick(args, "task", "prompt", "instruction", "instructions", "request", "goal")
|
|
6431
|
+
) ?? "";
|
|
6432
|
+
const context = asString(pick(args, "context", "background", "notes", "details"));
|
|
6433
|
+
let banditId;
|
|
6434
|
+
let banditName = named ? named.replace(/^@/, "") : void 0;
|
|
6435
|
+
if (banditName) {
|
|
6436
|
+
const match = bandits.find(
|
|
6437
|
+
(b) => banditHandle(b.name) === banditHandle(banditName)
|
|
6438
|
+
);
|
|
6439
|
+
if (match) {
|
|
6440
|
+
banditId = match.id;
|
|
6441
|
+
banditName = match.name;
|
|
6442
|
+
} else if (bandits.length > 0) {
|
|
6443
|
+
problems.push(
|
|
6444
|
+
`There is no Bandit called ${banditName} on your crew; pick one below.`
|
|
6445
|
+
);
|
|
6446
|
+
banditName = void 0;
|
|
6447
|
+
}
|
|
6448
|
+
} else {
|
|
6449
|
+
problems.push("Choose which Bandit should take this.");
|
|
6450
|
+
}
|
|
6451
|
+
if (!prompt) problems.push("Describe what the Bandit should do.");
|
|
6452
|
+
return { input: { banditId, banditName, prompt, context }, problems };
|
|
6453
|
+
};
|
|
6454
|
+
var parseCrewMention = (text, bandits) => {
|
|
6455
|
+
if (!bandits.length) return null;
|
|
6456
|
+
const match = /^\s*@([A-Za-z][\w-]{0,30})(?![\w.-]*@)(?:[\s,:—–-]+|$)([\s\S]*)$/.exec(
|
|
6457
|
+
text
|
|
6458
|
+
);
|
|
6459
|
+
if (!match) return null;
|
|
6460
|
+
const handle = match[1].toLowerCase();
|
|
6461
|
+
const bandit = bandits.find((b) => banditHandle(b.name) === handle);
|
|
6462
|
+
if (!bandit) return null;
|
|
6463
|
+
return { bandit, prompt: match[2].trim() };
|
|
6464
|
+
};
|
|
6465
|
+
var matchingBandits = (partial, bandits) => {
|
|
6466
|
+
const prefix = partial.trim().replace(/^@/, "").toLowerCase();
|
|
6467
|
+
return bandits.filter((b) => banditHandle(b.name).startsWith(prefix));
|
|
6468
|
+
};
|
|
6469
|
+
var mentionInProgress = (draft) => {
|
|
6470
|
+
const match = /^\s*@([\w-]*)$/.exec(draft);
|
|
6471
|
+
return match ? match[1] : null;
|
|
6472
|
+
};
|
|
6473
|
+
var requestCrewDelegation = async (args) => {
|
|
6474
|
+
const store = useCrewStore.getState();
|
|
6475
|
+
const bandits = store.loaded ? store.bandits : await store.refresh();
|
|
6476
|
+
const { input, problems } = normalizeDelegateArgs(args, bandits);
|
|
6477
|
+
return useCrewStore.getState().request(input, problems);
|
|
6478
|
+
};
|
|
6479
|
+
var crewOutcomeForModel = (outcome) => {
|
|
6480
|
+
switch (outcome.status) {
|
|
6481
|
+
case "started": {
|
|
6482
|
+
const t = outcome.task;
|
|
6483
|
+
return `The user confirmed and ${t.banditName} has started the task (task id ${t.id}): "${t.prompt}". The task runs in the background; its steps, any approval it needs and the finished result (with a Stash link when there is a file) show in a card in this conversation as they happen. Tell the user in one or two sentences that ${t.banditName} is on it and that you will not have the result in this reply. Do not call delegate_to_bandit again for the same task and do not invent a result.`;
|
|
6484
|
+
}
|
|
6485
|
+
case "cancelled":
|
|
6486
|
+
return "The user did not hand the task to a Bandit, so nothing was started. Ask briefly whether they want it changed or want you to do it yourself, or move on.";
|
|
6487
|
+
default:
|
|
6488
|
+
return `Starting the Bandit task failed: ${outcome.error}. Tell the user plainly. If no Bandit exists yet, mention they can create one under Settings \u2192 Crew.`;
|
|
6489
|
+
}
|
|
6490
|
+
};
|
|
6491
|
+
var crewToolProtocolLine = (bandits) => {
|
|
6492
|
+
if (!bandits.length) return "";
|
|
6493
|
+
const names = bandits.map((b) => b.name).join(", ");
|
|
6494
|
+
return `
|
|
6495
|
+
* ${DELEGATE_TOOL_NAME}({"bandit": "Riley", "task": "Research Acme's 2026 pricing changes and draft a one-page brief"}) - ONLY when the user asks to hand work to one of their Bandits BY NAME ("ask Riley to\u2026", "have Scout\u2026", "@Riley \u2026"), or asks for a longer research/drafting job to be done in the background by the crew. The user's Bandits: ${names}. Put the complete task in "task" (self-contained: the Bandit has no chat context unless you pass the relevant facts in "context"). This opens a confirmation card the user must approve; wait for the tool result and never say a Bandit is working until it reports the task started. Do not use it for questions you can answer yourself.`;
|
|
6496
|
+
};
|
|
6497
|
+
|
|
6394
6498
|
// src/services/images/imageTools.ts
|
|
6395
6499
|
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set(["image_generation", "image_edit"]);
|
|
6396
6500
|
var IMAGE_TOOL_TIMEOUT_MS = 12e4;
|
|
@@ -6696,6 +6800,7 @@ var useVoiceModeStore = create3((set) => ({
|
|
|
6696
6800
|
// src/chat/chat-input.tsx
|
|
6697
6801
|
import { useShallow } from "zustand/react/shallow";
|
|
6698
6802
|
import { Fragment as Fragment9, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
6803
|
+
var CrewMentionPicker = lazy(() => import("./crew-mention-picker-OSJ2NHUB.mjs"));
|
|
6699
6804
|
var DOCUMENT_ACCEPT = ".txt,.docx,.pdf,.md,.json,.js,.ts,.tsx,.py,.java,.c,.cpp,.cs,image/*,.heic,.heif";
|
|
6700
6805
|
var MEETING_ACCEPT = `${DOCUMENT_ACCEPT},.vtt,.srt,audio/*,video/*`;
|
|
6701
6806
|
var isTextDocument = (file) => /\.(txt|md|docx)$/i.test(file.name) || file.type.startsWith("text/");
|
|
@@ -6778,6 +6883,17 @@ var ChatInput = (props) => {
|
|
|
6778
6883
|
const canTranscribeRecordings = meetingNotesEnabled && hasSTT();
|
|
6779
6884
|
const gatewayUrlLower = packageSettings?.gatewayApiUrl?.toLowerCase?.() ?? "";
|
|
6780
6885
|
const isPlaygroundMode2 = packageSettings?.playgroundMode === true || gatewayUrlLower.startsWith("playground://") || typeof window !== "undefined" && window.location.pathname.includes("/playground");
|
|
6886
|
+
const crewBandits = useCrewStore((state) => state.bandits);
|
|
6887
|
+
const [mentionIndex, setMentionIndex] = useState12(0);
|
|
6888
|
+
const mentionQuery = !isPlaygroundMode2 && crewBandits.length > 0 && crewSurfacesEnabled() ? mentionInProgress(inputValue) : null;
|
|
6889
|
+
const mentionMatches = mentionQuery !== null ? matchingBandits(mentionQuery, crewBandits) : [];
|
|
6890
|
+
const mentionOpen = mentionMatches.length > 0;
|
|
6891
|
+
const highlightedMention = Math.min(mentionIndex, Math.max(0, mentionMatches.length - 1));
|
|
6892
|
+
const pickMention = (bandit) => {
|
|
6893
|
+
setInputValue(`@${bandit.name} `);
|
|
6894
|
+
setMentionIndex(0);
|
|
6895
|
+
inputRef.current?.focus();
|
|
6896
|
+
};
|
|
6781
6897
|
useEffect9(() => {
|
|
6782
6898
|
const lockViewportHeight = () => {
|
|
6783
6899
|
if (isMobile) {
|
|
@@ -6808,7 +6924,7 @@ var ChatInput = (props) => {
|
|
|
6808
6924
|
loadBrandingText();
|
|
6809
6925
|
}, []);
|
|
6810
6926
|
const [attachmentNotice, setAttachmentNotice] = useState12(null);
|
|
6811
|
-
const attachImages =
|
|
6927
|
+
const attachImages = React9.useCallback(
|
|
6812
6928
|
async (images) => {
|
|
6813
6929
|
if (images.length === 0) return;
|
|
6814
6930
|
let notice = null;
|
|
@@ -7055,6 +7171,23 @@ var ChatInput = (props) => {
|
|
|
7055
7171
|
};
|
|
7056
7172
|
const handleKeyPress = (e) => {
|
|
7057
7173
|
if (isImeComposing(e)) return;
|
|
7174
|
+
if (mentionOpen) {
|
|
7175
|
+
if (e.key === "ArrowDown") {
|
|
7176
|
+
e.preventDefault();
|
|
7177
|
+
setMentionIndex((i) => (i + 1) % mentionMatches.length);
|
|
7178
|
+
return;
|
|
7179
|
+
}
|
|
7180
|
+
if (e.key === "ArrowUp") {
|
|
7181
|
+
e.preventDefault();
|
|
7182
|
+
setMentionIndex((i) => (i - 1 + mentionMatches.length) % mentionMatches.length);
|
|
7183
|
+
return;
|
|
7184
|
+
}
|
|
7185
|
+
if (e.key === "Enter" || e.key === "Tab") {
|
|
7186
|
+
e.preventDefault();
|
|
7187
|
+
pickMention(mentionMatches[highlightedMention]);
|
|
7188
|
+
return;
|
|
7189
|
+
}
|
|
7190
|
+
}
|
|
7058
7191
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
7059
7192
|
e.preventDefault();
|
|
7060
7193
|
void handleSubmit();
|
|
@@ -7165,6 +7298,7 @@ var ChatInput = (props) => {
|
|
|
7165
7298
|
...dropHandlers,
|
|
7166
7299
|
"data-dragging": dragging ? "true" : void 0,
|
|
7167
7300
|
sx: {
|
|
7301
|
+
position: "relative",
|
|
7168
7302
|
width: "100%",
|
|
7169
7303
|
bgcolor: tokens.composer.surface,
|
|
7170
7304
|
color: tokens.composer.foreground,
|
|
@@ -7194,6 +7328,15 @@ var ChatInput = (props) => {
|
|
|
7194
7328
|
gap: isMobile ? compactMobile ? 0.75 : 1 : 0.5
|
|
7195
7329
|
},
|
|
7196
7330
|
children: [
|
|
7331
|
+
mentionOpen && /* @__PURE__ */ jsx16(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx16(
|
|
7332
|
+
CrewMentionPicker,
|
|
7333
|
+
{
|
|
7334
|
+
bandits: mentionMatches,
|
|
7335
|
+
highlighted: highlightedMention,
|
|
7336
|
+
onPick: pickMention,
|
|
7337
|
+
onHover: setMentionIndex
|
|
7338
|
+
}
|
|
7339
|
+
) }),
|
|
7197
7340
|
attachmentNotice && !sendError && /* @__PURE__ */ jsx16(
|
|
7198
7341
|
Box13,
|
|
7199
7342
|
{
|
|
@@ -9469,6 +9612,33 @@ var createScheduleTool = {
|
|
|
9469
9612
|
},
|
|
9470
9613
|
isBuiltIn: true
|
|
9471
9614
|
};
|
|
9615
|
+
var delegateToBanditTool = {
|
|
9616
|
+
id: "delegate-to-bandit",
|
|
9617
|
+
name: "delegate_to_bandit",
|
|
9618
|
+
description: "Hand a task to one of the user's named Bandits (Bandit Crew). The Bandit works in the background with web search and file creation, asks before any action that affects other people, and files the result in Stash. Opens a confirmation card the user must approve.",
|
|
9619
|
+
enabled: true,
|
|
9620
|
+
type: "function",
|
|
9621
|
+
function: {
|
|
9622
|
+
name: "delegate_to_bandit",
|
|
9623
|
+
description: `Delegate a task to one of the user's Bandits by name ("ask Riley to\u2026", "@Riley \u2026"). The Bandit runs the task in the background on the user's account; its steps, approvals and result appear in a card in the conversation. The user confirms (and can edit) the hand-off in a card before it starts; never claim a Bandit is working until the tool result says the task started.`,
|
|
9624
|
+
parameters: {
|
|
9625
|
+
type: "object",
|
|
9626
|
+
properties: {
|
|
9627
|
+
bandit: { type: "string", description: "The Bandit's name, e.g. 'Riley'" },
|
|
9628
|
+
task: {
|
|
9629
|
+
type: "string",
|
|
9630
|
+
description: "The complete task, self-contained (the Bandit has no chat context)."
|
|
9631
|
+
},
|
|
9632
|
+
context: {
|
|
9633
|
+
type: "string",
|
|
9634
|
+
description: "Optional facts from the conversation the Bandit needs (passed as data, not instructions)."
|
|
9635
|
+
}
|
|
9636
|
+
},
|
|
9637
|
+
required: ["bandit", "task"]
|
|
9638
|
+
}
|
|
9639
|
+
},
|
|
9640
|
+
isBuiltIn: true
|
|
9641
|
+
};
|
|
9472
9642
|
var defaultTools = [
|
|
9473
9643
|
healthCheckTool,
|
|
9474
9644
|
webSearchTool,
|
|
@@ -9476,7 +9646,8 @@ var defaultTools = [
|
|
|
9476
9646
|
imageGenerationTool,
|
|
9477
9647
|
imageEditTool,
|
|
9478
9648
|
createFileTool,
|
|
9479
|
-
createScheduleTool
|
|
9649
|
+
createScheduleTool,
|
|
9650
|
+
delegateToBanditTool
|
|
9480
9651
|
];
|
|
9481
9652
|
var useMCPToolsStore = create6((set, get) => {
|
|
9482
9653
|
const persist = async () => {
|
|
@@ -9859,7 +10030,8 @@ var executeMCPTool = async (toolCall) => {
|
|
|
9859
10030
|
var getEnabledMCPToolsForAI = () => {
|
|
9860
10031
|
const { getEnabledTools } = useMCPToolsStore.getState();
|
|
9861
10032
|
const enabledTools = getEnabledTools();
|
|
9862
|
-
|
|
10033
|
+
const crewOffered = crewSurfacesEnabled() && useCrewStore.getState().bandits.length > 0;
|
|
10034
|
+
return enabledTools.filter((tool) => tool.function.name !== "delegate_to_bandit" || crewOffered).map((tool) => ({
|
|
9863
10035
|
type: tool.type,
|
|
9864
10036
|
function: tool.function
|
|
9865
10037
|
}));
|
|
@@ -10925,6 +11097,7 @@ ${CONTEXT_USAGE_RULES}`;
|
|
|
10925
11097
|
const paramSuffix = params.length ? ` (parameters: ${params.join(", ")})` : "";
|
|
10926
11098
|
return `- ${tool.function.name}: ${tool.function.description}${paramSuffix}`;
|
|
10927
11099
|
}).join("\n");
|
|
11100
|
+
const crewProtocolLine = crewSurfacesEnabled() ? crewToolProtocolLine(useCrewStore.getState().bandits) : "";
|
|
10928
11101
|
const protocol = `
|
|
10929
11102
|
|
|
10930
11103
|
TOOL USAGE PROTOCOL
|
|
@@ -10936,7 +11109,7 @@ ${TOOL_JUDGMENT_RULES}
|
|
|
10936
11109
|
* 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
|
|
10937
11110
|
* 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.
|
|
10938
11111
|
* 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.
|
|
10939
|
-
* 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
|
|
11112
|
+
* 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.${crewProtocolLine}
|
|
10940
11113
|
- Examples of what NOT to use tools for: "who are you?", "what is React?", "explain machine learning", "how does X work?", general programming questions.
|
|
10941
11114
|
- When a tool is truly needed, call exactly ONE tool that best matches the request.
|
|
10942
11115
|
- Begin tool usage with a fenced code block: \`\`\`tool_code
|
|
@@ -11054,6 +11227,8 @@ ${protocol}`;
|
|
|
11054
11227
|
"ask-user",
|
|
11055
11228
|
"create_schedule",
|
|
11056
11229
|
"create-schedule",
|
|
11230
|
+
"delegate_to_bandit",
|
|
11231
|
+
"delegate-to-bandit",
|
|
11057
11232
|
...getEnabledMCPToolsForAI().map((t) => t.function?.name).filter((n) => !!n && /^[\w-]+$/.test(n))
|
|
11058
11233
|
])
|
|
11059
11234
|
);
|
|
@@ -11071,11 +11246,11 @@ ${protocol}`;
|
|
|
11071
11246
|
const fenceIdx = t.search(/```(?:tool_code|TOOL_CODE)/);
|
|
11072
11247
|
if (fenceIdx !== -1) t = t.slice(0, fenceIdx);
|
|
11073
11248
|
const callIdx = t.search(
|
|
11074
|
-
/\b(?:web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule)\s*\(/
|
|
11249
|
+
/\b(?:web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule|delegate_to_bandit)\s*\(/
|
|
11075
11250
|
);
|
|
11076
11251
|
if (callIdx !== -1) t = t.slice(0, callIdx);
|
|
11077
11252
|
const jsonIdx = t.search(
|
|
11078
|
-
/\{\s*"name"\s*:\s*"(?:web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule)"/
|
|
11253
|
+
/\{\s*"name"\s*:\s*"(?:web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule|delegate_to_bandit)"/
|
|
11079
11254
|
);
|
|
11080
11255
|
if (jsonIdx !== -1) t = t.slice(0, jsonIdx);
|
|
11081
11256
|
t = t.replace(/```[\w-]*\s*$/, "");
|
|
@@ -11149,17 +11324,17 @@ ${protocol}`;
|
|
|
11149
11324
|
setIsThinking?.(inThinkBlock);
|
|
11150
11325
|
const visibleMessage = stripThinking2(fullMessage);
|
|
11151
11326
|
const bareToolMatch = visibleMessage.match(
|
|
11152
|
-
/\b(web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule)\s*\(/
|
|
11327
|
+
/\b(web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule|delegate_to_bandit)\s*\(/
|
|
11153
11328
|
) || // JSON-form calls from cloud/native-tool engines.
|
|
11154
11329
|
visibleMessage.match(
|
|
11155
|
-
/\{\s*"name"\s*:\s*"(web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule)"/
|
|
11330
|
+
/\{\s*"name"\s*:\s*"(web_search|web_fetch|image_generation|image_edit|create_file|ask_user|create_schedule|delegate_to_bandit)"/
|
|
11156
11331
|
);
|
|
11157
11332
|
if (/```(?:tool_code|TOOL_CODE)/.test(visibleMessage) || bareToolMatch) {
|
|
11158
11333
|
sawToolBlock = true;
|
|
11159
11334
|
clearFlushTimer();
|
|
11160
11335
|
const fn = bareToolMatch?.[1];
|
|
11161
11336
|
startWorking(
|
|
11162
|
-
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"
|
|
11337
|
+
fn === "delegate_to_bandit" ? "Handing this to the crew" : 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"
|
|
11163
11338
|
);
|
|
11164
11339
|
}
|
|
11165
11340
|
latestDisplayMessage = visibleMessage;
|
|
@@ -11487,6 +11662,30 @@ A: ${(answers[q.id] || "").trim() || "(no answer)"}`
|
|
|
11487
11662
|
});
|
|
11488
11663
|
continue;
|
|
11489
11664
|
}
|
|
11665
|
+
if (isDelegateTool(functionName)) {
|
|
11666
|
+
enhancedMessage = enhancedMessage.replace(match, "");
|
|
11667
|
+
clearFlushTimer();
|
|
11668
|
+
stopWorking();
|
|
11669
|
+
const preamble = stripToolBlocks(fullMessage).trim();
|
|
11670
|
+
setStreamBuffer(preamble || "_Confirm the hand-off below\u2026_");
|
|
11671
|
+
pushTrail(pendingTrailItem(functionName, parsedParams));
|
|
11672
|
+
const outcome = await requestCrewDelegation(
|
|
11673
|
+
parsedParams
|
|
11674
|
+
);
|
|
11675
|
+
telemetryEvent("tool_loop:delegate_to_bandit", { status: outcome.status });
|
|
11676
|
+
const crewItem = trailItemForTool(functionName, parsedParams, {
|
|
11677
|
+
success: outcome.status === "started",
|
|
11678
|
+
data: outcome.status === "started" ? { taskId: outcome.task.id, banditName: outcome.task.banditName } : {},
|
|
11679
|
+
error: outcome.status === "failed" ? outcome.error : void 0
|
|
11680
|
+
});
|
|
11681
|
+
pushTrail(crewItem);
|
|
11682
|
+
if (outcome.status === "started") passCalls.push(crewItem);
|
|
11683
|
+
summarizableResults.push({
|
|
11684
|
+
name: functionName,
|
|
11685
|
+
output: crewOutcomeForModel(outcome)
|
|
11686
|
+
});
|
|
11687
|
+
continue;
|
|
11688
|
+
}
|
|
11490
11689
|
const placeholderToken = `<<TOOL_LOADING_${functionName}_${Math.random().toString(36).slice(2)}>>`;
|
|
11491
11690
|
enhancedMessage = enhancedMessage.replace(match, placeholderToken);
|
|
11492
11691
|
clearFlushTimer();
|
|
@@ -11701,6 +11900,22 @@ A: ${(ans[q.id] || "").trim() || "(no answer)"}`
|
|
|
11701
11900
|
);
|
|
11702
11901
|
return scheduleOutcomeForModel(outcome);
|
|
11703
11902
|
}
|
|
11903
|
+
if (isDelegateTool(fn)) {
|
|
11904
|
+
stopWorking();
|
|
11905
|
+
pushTrail(pendingTrailItem(fn, params));
|
|
11906
|
+
const outcome = await requestCrewDelegation(
|
|
11907
|
+
params
|
|
11908
|
+
);
|
|
11909
|
+
telemetryEvent("tool_loop:delegate_to_bandit", { status: outcome.status });
|
|
11910
|
+
record(
|
|
11911
|
+
trailItemForTool(fn, params, {
|
|
11912
|
+
success: outcome.status === "started",
|
|
11913
|
+
data: outcome.status === "started" ? { taskId: outcome.task.id, banditName: outcome.task.banditName } : {},
|
|
11914
|
+
error: outcome.status === "failed" ? outcome.error : void 0
|
|
11915
|
+
})
|
|
11916
|
+
);
|
|
11917
|
+
return crewOutcomeForModel(outcome);
|
|
11918
|
+
}
|
|
11704
11919
|
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";
|
|
11705
11920
|
startWorking(status);
|
|
11706
11921
|
pushTrail(pendingTrailItem(fn, params));
|
|
@@ -17184,12 +17399,12 @@ var MobileSidebar = ({ open, onClose, drag }) => {
|
|
|
17184
17399
|
};
|
|
17185
17400
|
|
|
17186
17401
|
// src/chat/sidebar/ProjectsPaneLazy.tsx
|
|
17187
|
-
import { Suspense as
|
|
17402
|
+
import { Suspense as Suspense3, lazy as lazy2 } from "react";
|
|
17188
17403
|
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
17189
|
-
var Pane =
|
|
17190
|
-
() => import("./ProjectsPane-
|
|
17404
|
+
var Pane = lazy2(
|
|
17405
|
+
() => import("./ProjectsPane-C63C6GW5.mjs").then((module) => ({ default: module.ProjectsPane }))
|
|
17191
17406
|
);
|
|
17192
|
-
var ProjectsPane = (props) => /* @__PURE__ */ jsx28(
|
|
17407
|
+
var ProjectsPane = (props) => /* @__PURE__ */ jsx28(Suspense3, { fallback: null, children: /* @__PURE__ */ jsx28(Pane, { ...props }) });
|
|
17193
17408
|
|
|
17194
17409
|
// src/chat/sidebar/useSidebarShortcuts.ts
|
|
17195
17410
|
import { useEffect as useEffect18 } from "react";
|
|
@@ -17864,18 +18079,18 @@ ${rest}` : rest;
|
|
|
17864
18079
|
if (current) chunks.push(current);
|
|
17865
18080
|
return chunks;
|
|
17866
18081
|
};
|
|
17867
|
-
var
|
|
18082
|
+
var asString2 = (value) => {
|
|
17868
18083
|
if (typeof value === "number") return String(value);
|
|
17869
18084
|
if (typeof value !== "string") return void 0;
|
|
17870
18085
|
const trimmed = value.trim();
|
|
17871
18086
|
return trimmed === "" || /^(null|none|n\/a|unknown|not stated|tbd)$/i.test(trimmed) ? void 0 : trimmed;
|
|
17872
18087
|
};
|
|
17873
18088
|
var asStringList = (value) => {
|
|
17874
|
-
if (typeof value === "string") return
|
|
18089
|
+
if (typeof value === "string") return asString2(value) ? [value.trim()] : [];
|
|
17875
18090
|
if (!Array.isArray(value)) return [];
|
|
17876
18091
|
const out = [];
|
|
17877
18092
|
for (const item of value) {
|
|
17878
|
-
const text =
|
|
18093
|
+
const text = asString2(item) ?? (item && typeof item === "object" ? asString2(
|
|
17879
18094
|
item.text ?? item.name ?? item.question ?? item.decision
|
|
17880
18095
|
) : void 0);
|
|
17881
18096
|
if (text && !out.some((existing) => existing.toLowerCase() === text.toLowerCase())) {
|
|
@@ -17889,18 +18104,18 @@ var asActionItems = (value) => {
|
|
|
17889
18104
|
const items = [];
|
|
17890
18105
|
for (const raw of value) {
|
|
17891
18106
|
if (typeof raw === "string") {
|
|
17892
|
-
const task2 =
|
|
18107
|
+
const task2 = asString2(raw);
|
|
17893
18108
|
if (task2) items.push({ task: task2 });
|
|
17894
18109
|
continue;
|
|
17895
18110
|
}
|
|
17896
18111
|
if (!raw || typeof raw !== "object") continue;
|
|
17897
18112
|
const record = raw;
|
|
17898
|
-
const task =
|
|
18113
|
+
const task = asString2(record.task ?? record.action ?? record.item ?? record.text);
|
|
17899
18114
|
if (!task) continue;
|
|
17900
18115
|
items.push({
|
|
17901
18116
|
task,
|
|
17902
|
-
owner:
|
|
17903
|
-
due:
|
|
18117
|
+
owner: asString2(record.owner ?? record.assignee ?? record.who),
|
|
18118
|
+
due: asString2(record.due ?? record.dueDate ?? record.deadline ?? record.when)
|
|
17904
18119
|
});
|
|
17905
18120
|
}
|
|
17906
18121
|
return items;
|
|
@@ -17945,10 +18160,10 @@ var parseNotesJson = (raw) => {
|
|
|
17945
18160
|
if (!parsed || typeof parsed !== "object") return null;
|
|
17946
18161
|
const record = parsed;
|
|
17947
18162
|
const notes = {
|
|
17948
|
-
title:
|
|
17949
|
-
date:
|
|
18163
|
+
title: asString2(record.title) ?? "Meeting notes",
|
|
18164
|
+
date: asString2(record.date),
|
|
17950
18165
|
attendees: asStringList(record.attendees ?? record.participants),
|
|
17951
|
-
summary:
|
|
18166
|
+
summary: asString2(record.summary) ?? "",
|
|
17952
18167
|
decisions: asStringList(record.decisions),
|
|
17953
18168
|
actionItems: asActionItems(
|
|
17954
18169
|
record.actionItems ?? record.action_items ?? record.actions
|
|
@@ -19389,7 +19604,7 @@ function createBanditTheme(config = {}, ...overrides) {
|
|
|
19389
19604
|
|
|
19390
19605
|
// ../bandit-themes/src/provider.tsx
|
|
19391
19606
|
import { ThemeProvider } from "@mui/material/styles";
|
|
19392
|
-
import * as
|
|
19607
|
+
import * as React21 from "react";
|
|
19393
19608
|
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
19394
19609
|
function BanditThemeProvider({
|
|
19395
19610
|
theme,
|
|
@@ -19399,9 +19614,9 @@ function BanditThemeProvider({
|
|
|
19399
19614
|
style,
|
|
19400
19615
|
children
|
|
19401
19616
|
}) {
|
|
19402
|
-
const resolved =
|
|
19617
|
+
const resolved = React21.useMemo(() => theme ?? createBanditTheme(config), [theme, config]);
|
|
19403
19618
|
const { cssVars, mode } = resolved.bandit;
|
|
19404
|
-
|
|
19619
|
+
React21.useLayoutEffect(() => {
|
|
19405
19620
|
if (scope !== "document" || typeof document === "undefined") return;
|
|
19406
19621
|
const root = document.documentElement;
|
|
19407
19622
|
const previous = /* @__PURE__ */ new Map();
|
|
@@ -19549,7 +19764,7 @@ import Paper5 from "@mui/material/Paper";
|
|
|
19549
19764
|
import Stack2 from "@mui/material/Stack";
|
|
19550
19765
|
import Typography21 from "@mui/material/Typography";
|
|
19551
19766
|
import { useTheme as useTheme24 } from "@mui/material/styles";
|
|
19552
|
-
import * as
|
|
19767
|
+
import * as React22 from "react";
|
|
19553
19768
|
import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
19554
19769
|
function TenantPreview({
|
|
19555
19770
|
accent,
|
|
@@ -19602,7 +19817,7 @@ function PreviewPane({
|
|
|
19602
19817
|
density,
|
|
19603
19818
|
renderBody
|
|
19604
19819
|
}) {
|
|
19605
|
-
const theme =
|
|
19820
|
+
const theme = React22.useMemo(
|
|
19606
19821
|
() => createBanditTheme({
|
|
19607
19822
|
mode,
|
|
19608
19823
|
skin,
|
|
@@ -20396,8 +20611,9 @@ var useVoiceMode = (config) => {
|
|
|
20396
20611
|
|
|
20397
20612
|
// src/chat/chat.tsx
|
|
20398
20613
|
import { Fragment as Fragment17, jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
20399
|
-
var ImageEditAcknowledgement =
|
|
20400
|
-
var ScheduleConfirmCard =
|
|
20614
|
+
var ImageEditAcknowledgement = React25.lazy(() => import("./image-edit-acknowledgement-RZPQYKYJ.mjs"));
|
|
20615
|
+
var ScheduleConfirmCard = lazy3(() => import("./schedule-confirm-card-Y2JF2RBV.mjs"));
|
|
20616
|
+
var CrewDelegateCard = lazy3(() => import("./crew-delegate-card-I4SSZU5H.mjs"));
|
|
20401
20617
|
var CLASSIC_DRAWER_WIDTH = 340;
|
|
20402
20618
|
var ChatContent = () => {
|
|
20403
20619
|
const packageSettings = usePackageSettingsStore((state) => state.settings);
|
|
@@ -20436,6 +20652,7 @@ var ChatContent = () => {
|
|
|
20436
20652
|
const isVoiceModeEnabled = useVoiceModeStore((state) => state.enabled);
|
|
20437
20653
|
const canvasOpen = useCanvasStore((state) => state.open);
|
|
20438
20654
|
const schedulePending = useScheduleConfirmStore((state) => state.pending !== null);
|
|
20655
|
+
const crewPending = useCrewStore((state) => state.pending !== null);
|
|
20439
20656
|
const previousVoiceModeEnabledRef = useRef19(isVoiceModeEnabled);
|
|
20440
20657
|
const historyRef = useRef19(history);
|
|
20441
20658
|
useEffect24(() => {
|
|
@@ -20625,6 +20842,9 @@ var ChatContent = () => {
|
|
|
20625
20842
|
const GRACE_OFFSET_DESKTOP = 28;
|
|
20626
20843
|
const GRACE_OFFSET_MOBILE = 20;
|
|
20627
20844
|
const followStreamRef = useRef19(true);
|
|
20845
|
+
useEffect24(() => {
|
|
20846
|
+
if (crewSurfacesEnabled()) void useCrewStore.getState().refresh();
|
|
20847
|
+
}, []);
|
|
20628
20848
|
const lastSpokenResponseRef = useRef19(null);
|
|
20629
20849
|
const previousConversationIdRef = useRef19(null);
|
|
20630
20850
|
const logoFadeTimeoutRef = useRef19(null);
|
|
@@ -21254,8 +21474,89 @@ var ChatContent = () => {
|
|
|
21254
21474
|
handleStop();
|
|
21255
21475
|
}
|
|
21256
21476
|
}, [ttsStop, isStreaming, handleStop]);
|
|
21477
|
+
const delegateFromComposer = useCallback12(
|
|
21478
|
+
async (mention, question) => {
|
|
21479
|
+
setPendingMessage({ question });
|
|
21480
|
+
setIsStreaming(true);
|
|
21481
|
+
setResponseStarted(true);
|
|
21482
|
+
setIsSubmitting(true);
|
|
21483
|
+
setStreamBuffer("<<working:Waiting for your confirmation>>");
|
|
21484
|
+
const store = useConversationStore.getState();
|
|
21485
|
+
if (!store.conversations.find((c) => c.id === store.currentId)) {
|
|
21486
|
+
store.createConversation(question);
|
|
21487
|
+
setLogoVisible(true);
|
|
21488
|
+
}
|
|
21489
|
+
useConversationStore.getState().addToCurrent({
|
|
21490
|
+
question,
|
|
21491
|
+
answer: "...",
|
|
21492
|
+
placeholder: true,
|
|
21493
|
+
rawQuestion: question
|
|
21494
|
+
});
|
|
21495
|
+
const conversationId = useConversationStore.getState().currentId;
|
|
21496
|
+
followStreamRef.current = getScrollState().isNearBottom;
|
|
21497
|
+
setTimeout(() => {
|
|
21498
|
+
if (followStreamRef.current) scrollToBottom();
|
|
21499
|
+
}, 50);
|
|
21500
|
+
try {
|
|
21501
|
+
const outcome = await useCrewStore.getState().request(
|
|
21502
|
+
{ banditId: mention.bandit.id, banditName: mention.bandit.name, prompt: mention.prompt },
|
|
21503
|
+
mention.prompt ? [] : ["Describe what the Bandit should do."]
|
|
21504
|
+
);
|
|
21505
|
+
const current = useConversationStore.getState();
|
|
21506
|
+
if (current.currentId !== conversationId) {
|
|
21507
|
+
debugLogger.warn("The Bandit hand-off finished for a conversation that is no longer open");
|
|
21508
|
+
return;
|
|
21509
|
+
}
|
|
21510
|
+
if (outcome.status === "started") {
|
|
21511
|
+
current.setLastToolTrail([
|
|
21512
|
+
{
|
|
21513
|
+
kind: "crew",
|
|
21514
|
+
tool: "delegate_to_bandit",
|
|
21515
|
+
label: `Delegated to ${outcome.task.banditName}`,
|
|
21516
|
+
detail: outcome.task.prompt,
|
|
21517
|
+
ok: true,
|
|
21518
|
+
crewTaskId: outcome.task.id
|
|
21519
|
+
}
|
|
21520
|
+
]);
|
|
21521
|
+
current.replaceLastAnswer(
|
|
21522
|
+
`**${outcome.task.banditName}** is on it. The steps, any approval it needs and the result show below as they happen.`
|
|
21523
|
+
);
|
|
21524
|
+
} else if (outcome.status === "cancelled") {
|
|
21525
|
+
current.replaceLastAnswer("_No task was started._", void 0, false, void 0, true);
|
|
21526
|
+
} else {
|
|
21527
|
+
current.replaceLastAnswer(
|
|
21528
|
+
`_The task could not be started: ${outcome.error}_`,
|
|
21529
|
+
void 0,
|
|
21530
|
+
false,
|
|
21531
|
+
void 0,
|
|
21532
|
+
true
|
|
21533
|
+
);
|
|
21534
|
+
}
|
|
21535
|
+
} finally {
|
|
21536
|
+
setStreamBuffer("");
|
|
21537
|
+
setIsStreaming(false);
|
|
21538
|
+
setResponseStarted(false);
|
|
21539
|
+
setIsSubmitting(false);
|
|
21540
|
+
setPendingMessage(null);
|
|
21541
|
+
setLogoVisible(false);
|
|
21542
|
+
}
|
|
21543
|
+
},
|
|
21544
|
+
[
|
|
21545
|
+
getScrollState,
|
|
21546
|
+
scrollToBottom,
|
|
21547
|
+
setIsStreaming,
|
|
21548
|
+
setLogoVisible,
|
|
21549
|
+
setPendingMessage,
|
|
21550
|
+
setResponseStarted,
|
|
21551
|
+
setStreamBuffer
|
|
21552
|
+
]
|
|
21553
|
+
);
|
|
21257
21554
|
const handleSend = useCallback12(
|
|
21258
21555
|
(question, images, displayQuestion) => {
|
|
21556
|
+
const mention = images.length === 0 && crewSurfacesEnabled() ? parseCrewMention(question, useCrewStore.getState().bandits) : null;
|
|
21557
|
+
if (mention) {
|
|
21558
|
+
return delegateFromComposer(mention, displayQuestion || question);
|
|
21559
|
+
}
|
|
21259
21560
|
sendAckRef.current?.resolve();
|
|
21260
21561
|
const acknowledged = new Promise((resolve, reject) => {
|
|
21261
21562
|
sendAckRef.current = { resolve, reject };
|
|
@@ -21394,6 +21695,7 @@ var ChatContent = () => {
|
|
|
21394
21695
|
},
|
|
21395
21696
|
[
|
|
21396
21697
|
aiProvider,
|
|
21698
|
+
delegateFromComposer,
|
|
21397
21699
|
settleSendAck,
|
|
21398
21700
|
chatContainerRef,
|
|
21399
21701
|
generateName,
|
|
@@ -22110,8 +22412,9 @@ var ChatContent = () => {
|
|
|
22110
22412
|
) }),
|
|
22111
22413
|
/* @__PURE__ */ jsx38(rate_limit_prompt_default, {}),
|
|
22112
22414
|
/* @__PURE__ */ jsx38(ask_user_card_default, {}),
|
|
22113
|
-
/* @__PURE__ */ jsx38(
|
|
22114
|
-
schedulePending && /* @__PURE__ */ jsx38(
|
|
22415
|
+
/* @__PURE__ */ jsx38(React25.Suspense, { fallback: null, children: /* @__PURE__ */ jsx38(ImageEditAcknowledgement, {}) }),
|
|
22416
|
+
schedulePending && /* @__PURE__ */ jsx38(Suspense4, { fallback: null, children: /* @__PURE__ */ jsx38(ScheduleConfirmCard, {}) }),
|
|
22417
|
+
crewPending && /* @__PURE__ */ jsx38(Suspense4, { fallback: null, children: /* @__PURE__ */ jsx38(CrewDelegateCard, {}) }),
|
|
22115
22418
|
/* @__PURE__ */ jsx38(
|
|
22116
22419
|
chat_input_default,
|
|
22117
22420
|
{
|
|
@@ -22202,8 +22505,6 @@ export {
|
|
|
22202
22505
|
useNotification,
|
|
22203
22506
|
NotificationProvider,
|
|
22204
22507
|
styleInject,
|
|
22205
|
-
IS_STORE_BUILD,
|
|
22206
|
-
managementConsoleVariant,
|
|
22207
22508
|
DocumentCard_default,
|
|
22208
22509
|
knowledge_file_modal_default,
|
|
22209
22510
|
useTTS,
|
|
@@ -22248,4 +22549,4 @@ export {
|
|
|
22248
22549
|
useNotificationService,
|
|
22249
22550
|
chat_default
|
|
22250
22551
|
};
|
|
22251
|
-
//# sourceMappingURL=chunk-
|
|
22552
|
+
//# sourceMappingURL=chunk-MX37LD3Z.mjs.map
|