@burtson-labs/bandit-engine 2.1.7 → 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 +20 -0
- package/dist/AdvancedTab-D7SDAQEL.mjs +229 -0
- package/dist/AdvancedTab-D7SDAQEL.mjs.map +1 -0
- package/dist/CrewSection-N2J3TJGU.mjs +15 -0
- package/dist/InstructionsTab-MKOGBQ5L.mjs +195 -0
- package/dist/InstructionsTab-MKOGBQ5L.mjs.map +1 -0
- package/dist/PersonalizationTab-KPTVJKB3.mjs +179 -0
- package/dist/PersonalizationTab-KPTVJKB3.mjs.map +1 -0
- package/dist/{ProjectsPane-E5D72PUG.mjs → ProjectsPane-C63C6GW5.mjs} +17 -13
- package/dist/ProjectsPane-C63C6GW5.mjs.map +1 -0
- package/dist/{SchedulesTab-AKJ6WFZV.mjs → SchedulesTab-TEOM3NWQ.mjs} +13 -11
- package/dist/SchedulesTab-TEOM3NWQ.mjs.map +1 -0
- package/dist/{aiProviderStore-ANPQVHGD.mjs → aiProviderStore-GH4JZTMW.mjs} +3 -2
- package/dist/chat-QAEEYO73.mjs +29 -0
- package/dist/chunk-3CDCJJ4S.mjs +64 -0
- package/dist/chunk-3CDCJJ4S.mjs.map +1 -0
- package/dist/chunk-5JNKGMMN.mjs +5871 -0
- package/dist/chunk-5JNKGMMN.mjs.map +1 -0
- package/dist/{chunk-KWOUXBSF.mjs → chunk-5LXCZJLJ.mjs} +5 -213
- package/dist/chunk-5LXCZJLJ.mjs.map +1 -0
- package/dist/{chunk-GX4FVZNA.mjs → chunk-DHXSFFLX.mjs} +4 -26
- package/dist/chunk-DHXSFFLX.mjs.map +1 -0
- package/dist/chunk-F56OTXXR.mjs +17 -0
- package/dist/chunk-F56OTXXR.mjs.map +1 -0
- package/dist/{chunk-SQJ4OKWM.mjs → chunk-GN3X7IIZ.mjs} +18 -1734
- package/dist/chunk-GN3X7IIZ.mjs.map +1 -0
- package/dist/chunk-H2XUGGKV.mjs +168 -0
- package/dist/chunk-H2XUGGKV.mjs.map +1 -0
- package/dist/{chunk-4NUQYUZH.mjs → chunk-JGJRY4MR.mjs} +7 -569
- package/dist/chunk-JGJRY4MR.mjs.map +1 -0
- package/dist/chunk-KPT7NNNK.mjs +214 -0
- package/dist/chunk-KPT7NNNK.mjs.map +1 -0
- package/dist/chunk-LC64VSDS.mjs +541 -0
- package/dist/chunk-LC64VSDS.mjs.map +1 -0
- package/dist/{chunk-DH5A2HT2.mjs → chunk-LY3O7UWA.mjs} +45 -1
- package/dist/chunk-LY3O7UWA.mjs.map +1 -0
- package/dist/chunk-MR643IO6.mjs +294 -0
- package/dist/chunk-MR643IO6.mjs.map +1 -0
- package/dist/{chunk-4NHPLHXU.mjs → chunk-MX37LD3Z.mjs} +5469 -11527
- package/dist/chunk-MX37LD3Z.mjs.map +1 -0
- package/dist/chunk-MX7Z4RSP.mjs +1203 -0
- package/dist/chunk-MX7Z4RSP.mjs.map +1 -0
- package/dist/chunk-P42M52OW.mjs +1732 -0
- 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-Y272M3D5.mjs +28 -0
- package/dist/chunk-Y272M3D5.mjs.map +1 -0
- package/dist/chunk-YY7BX2HM.mjs +566 -0
- 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.d.mts +121 -8
- package/dist/index.d.ts +121 -8
- package/dist/index.js +11313 -8127
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1222 -2217
- package/dist/index.mjs.map +1 -1
- package/dist/{modelStore-YNANSWCN.mjs → modelStore-KO45QAO2.mjs} +3 -2
- package/dist/modelStore-KO45QAO2.mjs.map +1 -0
- package/dist/{public-Tq2Pmw9m.d.mts → public-_W_Zew3C.d.mts} +14 -0
- package/dist/{public-Tq2Pmw9m.d.ts → public-_W_Zew3C.d.ts} +14 -0
- package/dist/public-types.d.mts +1 -1
- package/dist/public-types.d.ts +1 -1
- package/dist/{schedule-confirm-card-D4K76HEA.mjs → schedule-confirm-card-Y2JF2RBV.mjs} +5 -5
- package/package.json +1 -1
- package/dist/ProjectsPane-E5D72PUG.mjs.map +0 -1
- package/dist/SchedulesTab-AKJ6WFZV.mjs.map +0 -1
- package/dist/chat-MI4IL3WK.mjs +0 -19
- package/dist/chunk-2HFSBPOE.mjs.map +0 -1
- package/dist/chunk-4NHPLHXU.mjs.map +0 -1
- package/dist/chunk-4NUQYUZH.mjs.map +0 -1
- package/dist/chunk-5URP2E5V.mjs.map +0 -1
- package/dist/chunk-DH5A2HT2.mjs.map +0 -1
- package/dist/chunk-GX4FVZNA.mjs.map +0 -1
- package/dist/chunk-KWOUXBSF.mjs.map +0 -1
- package/dist/chunk-SQJ4OKWM.mjs.map +0 -1
- /package/dist/{aiProviderStore-ANPQVHGD.mjs.map → CrewSection-N2J3TJGU.mjs.map} +0 -0
- /package/dist/{chat-MI4IL3WK.mjs.map → aiProviderStore-GH4JZTMW.mjs.map} +0 -0
- /package/dist/{modelStore-YNANSWCN.mjs.map → chat-QAEEYO73.mjs.map} +0 -0
- /package/dist/{schedule-confirm-card-D4K76HEA.mjs.map → schedule-confirm-card-Y2JF2RBV.mjs.map} +0 -0
|
@@ -0,0 +1,814 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useCrewStore
|
|
3
|
+
} from "./chunk-3CDCJJ4S.mjs";
|
|
4
|
+
import {
|
|
5
|
+
Play,
|
|
6
|
+
Plus,
|
|
7
|
+
Refresh,
|
|
8
|
+
Trash
|
|
9
|
+
} from "./chunk-YY7BX2HM.mjs";
|
|
10
|
+
import {
|
|
11
|
+
claimSlackWorkspace,
|
|
12
|
+
claimTeamsTenant,
|
|
13
|
+
createBandit,
|
|
14
|
+
deleteBandit,
|
|
15
|
+
disconnectSlackWorkspace,
|
|
16
|
+
disconnectTeamsTenant,
|
|
17
|
+
isCrewTaskActive,
|
|
18
|
+
listBandits,
|
|
19
|
+
listChatWorkspaces,
|
|
20
|
+
listCrewTasks,
|
|
21
|
+
runCrewTask,
|
|
22
|
+
startSlackInstall
|
|
23
|
+
} from "./chunk-MR643IO6.mjs";
|
|
24
|
+
|
|
25
|
+
// src/management/components/CrewSection.tsx
|
|
26
|
+
import { Suspense, lazy, useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
|
|
27
|
+
import {
|
|
28
|
+
Alert as Alert2,
|
|
29
|
+
Box as Box2,
|
|
30
|
+
Button as Button2,
|
|
31
|
+
Chip as Chip2,
|
|
32
|
+
Collapse,
|
|
33
|
+
IconButton,
|
|
34
|
+
LinearProgress as LinearProgress2,
|
|
35
|
+
Link,
|
|
36
|
+
MenuItem,
|
|
37
|
+
Paper as Paper2,
|
|
38
|
+
Stack as Stack2,
|
|
39
|
+
Tab,
|
|
40
|
+
Tabs,
|
|
41
|
+
TextField,
|
|
42
|
+
Tooltip,
|
|
43
|
+
Typography as Typography2
|
|
44
|
+
} from "@mui/material";
|
|
45
|
+
|
|
46
|
+
// src/management/components/WorkspacesPanel.tsx
|
|
47
|
+
import { useCallback, useEffect, useState } from "react";
|
|
48
|
+
import {
|
|
49
|
+
Alert,
|
|
50
|
+
Box,
|
|
51
|
+
Button,
|
|
52
|
+
Chip,
|
|
53
|
+
LinearProgress,
|
|
54
|
+
Paper,
|
|
55
|
+
Stack,
|
|
56
|
+
Typography
|
|
57
|
+
} from "@mui/material";
|
|
58
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
59
|
+
var RETURN_TO = "/management?section=crew";
|
|
60
|
+
var orgLabel = (org) => org ? `${org.name ?? org.id} (${org.type === "tenant" ? "organization" : "Team"})` : "not connected to an organization";
|
|
61
|
+
var when = (iso) => {
|
|
62
|
+
const d = new Date(iso);
|
|
63
|
+
return Number.isNaN(d.getTime()) ? "" : d.toLocaleDateString();
|
|
64
|
+
};
|
|
65
|
+
var WorkspacesPanel = () => {
|
|
66
|
+
const [data, setData] = useState(null);
|
|
67
|
+
const [loading, setLoading] = useState(true);
|
|
68
|
+
const [notAdmin, setNotAdmin] = useState(false);
|
|
69
|
+
const [error, setError] = useState(null);
|
|
70
|
+
const [busy, setBusy] = useState(null);
|
|
71
|
+
const refresh = useCallback(async () => {
|
|
72
|
+
setLoading(true);
|
|
73
|
+
setError(null);
|
|
74
|
+
try {
|
|
75
|
+
setData(await listChatWorkspaces());
|
|
76
|
+
} catch (err) {
|
|
77
|
+
const message = err instanceof Error ? err.message : "Could not load the connected workspaces.";
|
|
78
|
+
if (/administer|no_org|Forbidden|403/i.test(message)) setNotAdmin(true);
|
|
79
|
+
else setError(message);
|
|
80
|
+
} finally {
|
|
81
|
+
setLoading(false);
|
|
82
|
+
}
|
|
83
|
+
}, []);
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
void refresh();
|
|
86
|
+
}, [refresh]);
|
|
87
|
+
const run = async (key, action) => {
|
|
88
|
+
setBusy(key);
|
|
89
|
+
setError(null);
|
|
90
|
+
try {
|
|
91
|
+
await action();
|
|
92
|
+
await refresh();
|
|
93
|
+
} catch (err) {
|
|
94
|
+
setError(err instanceof Error ? err.message : "That did not work.");
|
|
95
|
+
} finally {
|
|
96
|
+
setBusy(null);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const addToSlack = async () => {
|
|
100
|
+
setBusy("add-slack");
|
|
101
|
+
setError(null);
|
|
102
|
+
try {
|
|
103
|
+
const { url } = await startSlackInstall(RETURN_TO);
|
|
104
|
+
window.location.assign(url);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
setError(err instanceof Error ? err.message : "Could not start the Slack install.");
|
|
107
|
+
setBusy(null);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
if (notAdmin) {
|
|
111
|
+
return /* @__PURE__ */ jsxs(Box, { component: "section", "aria-label": "Connected workspaces", sx: { mt: 3 }, children: [
|
|
112
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", sx: { fontWeight: 700 }, children: "Connected workspaces" }),
|
|
113
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: "Team owners connect Slack workspaces and Microsoft Teams tenants here. Ask your Team owner to connect one." })
|
|
114
|
+
] });
|
|
115
|
+
}
|
|
116
|
+
const slack = data?.slack.workspaces ?? [];
|
|
117
|
+
const teams = data?.teams.tenants ?? [];
|
|
118
|
+
return /* @__PURE__ */ jsxs(Box, { component: "section", "aria-label": "Connected workspaces", sx: { mt: 3 }, children: [
|
|
119
|
+
/* @__PURE__ */ jsxs(
|
|
120
|
+
Box,
|
|
121
|
+
{
|
|
122
|
+
sx: {
|
|
123
|
+
display: "flex",
|
|
124
|
+
alignItems: "center",
|
|
125
|
+
justifyContent: "space-between",
|
|
126
|
+
mb: 0.5
|
|
127
|
+
},
|
|
128
|
+
children: [
|
|
129
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", sx: { fontWeight: 700 }, children: "Connected workspaces" }),
|
|
130
|
+
data?.slack.distributionEnabled && /* @__PURE__ */ jsx(
|
|
131
|
+
Button,
|
|
132
|
+
{
|
|
133
|
+
size: "small",
|
|
134
|
+
variant: "outlined",
|
|
135
|
+
onClick: () => void addToSlack(),
|
|
136
|
+
disabled: busy !== null,
|
|
137
|
+
children: busy === "add-slack" ? "Opening Slack\u2026" : "Add to Slack"
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
),
|
|
143
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mb: 1 }, children: "Slack workspaces and Microsoft Teams tenants where Bandit runs under this organization. People who link their own Bandit account use their own plan; everyone else uses the organization's allowance, and only inside connected workspaces." }),
|
|
144
|
+
loading && /* @__PURE__ */ jsx(LinearProgress, { sx: { mb: 1 } }),
|
|
145
|
+
error && /* @__PURE__ */ jsx(Alert, { severity: "error", sx: { mb: 1 }, onClose: () => setError(null), children: error }),
|
|
146
|
+
!loading && slack.length === 0 && teams.length === 0 && /* @__PURE__ */ jsx(Paper, { variant: "outlined", sx: { p: 1.5 }, children: /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "text.secondary", children: [
|
|
147
|
+
"Nothing connected yet.",
|
|
148
|
+
" ",
|
|
149
|
+
data?.slack.distributionEnabled ? "Use Add to Slack to install Bandit in a workspace you administer." : "Slack installs for other workspaces open soon; ask us to add Bandit to yours.",
|
|
150
|
+
" ",
|
|
151
|
+
data?.teams.enabled ? "For Microsoft Teams, your Teams admin uploads the Bandit app; the tenant appears here after the first install." : ""
|
|
152
|
+
] }) }),
|
|
153
|
+
/* @__PURE__ */ jsxs(Stack, { spacing: 1, children: [
|
|
154
|
+
slack.map((w) => /* @__PURE__ */ jsxs(
|
|
155
|
+
Paper,
|
|
156
|
+
{
|
|
157
|
+
variant: "outlined",
|
|
158
|
+
sx: { p: 1.5, display: "flex", alignItems: "flex-start", gap: 1.5 },
|
|
159
|
+
children: [
|
|
160
|
+
/* @__PURE__ */ jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [
|
|
161
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 1, alignItems: "center", flexWrap: "wrap", children: [
|
|
162
|
+
/* @__PURE__ */ jsx(Typography, { sx: { fontWeight: 700 }, children: w.name }),
|
|
163
|
+
/* @__PURE__ */ jsx(Chip, { size: "small", label: "Slack", variant: "outlined" }),
|
|
164
|
+
w.isEnterpriseInstall && /* @__PURE__ */ jsx(Chip, { size: "small", label: "Enterprise Grid", variant: "outlined" }),
|
|
165
|
+
!w.active && /* @__PURE__ */ jsx(
|
|
166
|
+
Chip,
|
|
167
|
+
{
|
|
168
|
+
size: "small",
|
|
169
|
+
color: "warning",
|
|
170
|
+
label: w.revokedReason === "app_uninstalled" ? "uninstalled" : "revoked"
|
|
171
|
+
}
|
|
172
|
+
),
|
|
173
|
+
w.claimable && /* @__PURE__ */ jsx(Chip, { size: "small", color: "info", label: "unclaimed" })
|
|
174
|
+
] }),
|
|
175
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "text.secondary", children: [
|
|
176
|
+
orgLabel(w.org),
|
|
177
|
+
" \xB7 installed ",
|
|
178
|
+
when(w.installedAt),
|
|
179
|
+
w.workspaceKey ? ` \xB7 organization key ${w.workspaceKey.label ?? "set"}` : ""
|
|
180
|
+
] }),
|
|
181
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "text.secondary", children: [
|
|
182
|
+
"unlinked users:",
|
|
183
|
+
" ",
|
|
184
|
+
w.settings.unlinkedMode === "prompt" ? "must link" : "organization allowance",
|
|
185
|
+
w.settings.crewEnabled === false ? " \xB7 crew off" : "",
|
|
186
|
+
w.settings.defaultModel ? ` \xB7 model ${w.settings.defaultModel}` : ""
|
|
187
|
+
] })
|
|
188
|
+
] }),
|
|
189
|
+
w.claimable ? /* @__PURE__ */ jsx(
|
|
190
|
+
Button,
|
|
191
|
+
{
|
|
192
|
+
size: "small",
|
|
193
|
+
variant: "contained",
|
|
194
|
+
disabled: busy !== null,
|
|
195
|
+
onClick: () => void run(w.id, () => claimSlackWorkspace(w.id)),
|
|
196
|
+
children: busy === w.id ? "Connecting\u2026" : "Connect to my organization"
|
|
197
|
+
}
|
|
198
|
+
) : w.org ? /* @__PURE__ */ jsx(
|
|
199
|
+
Button,
|
|
200
|
+
{
|
|
201
|
+
size: "small",
|
|
202
|
+
disabled: busy !== null,
|
|
203
|
+
onClick: () => void run(w.id, () => disconnectSlackWorkspace(w.id)),
|
|
204
|
+
children: busy === w.id ? "Disconnecting\u2026" : "Disconnect"
|
|
205
|
+
}
|
|
206
|
+
) : null
|
|
207
|
+
]
|
|
208
|
+
},
|
|
209
|
+
w.id
|
|
210
|
+
)),
|
|
211
|
+
teams.map((t) => /* @__PURE__ */ jsxs(
|
|
212
|
+
Paper,
|
|
213
|
+
{
|
|
214
|
+
variant: "outlined",
|
|
215
|
+
sx: { p: 1.5, display: "flex", alignItems: "flex-start", gap: 1.5 },
|
|
216
|
+
children: [
|
|
217
|
+
/* @__PURE__ */ jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [
|
|
218
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 1, alignItems: "center", flexWrap: "wrap", children: [
|
|
219
|
+
/* @__PURE__ */ jsx(Typography, { sx: { fontWeight: 700 }, children: t.name ?? t.tenantId }),
|
|
220
|
+
/* @__PURE__ */ jsx(Chip, { size: "small", label: "Microsoft Teams", variant: "outlined" }),
|
|
221
|
+
!t.active && /* @__PURE__ */ jsx(Chip, { size: "small", color: "warning", label: "removed" })
|
|
222
|
+
] }),
|
|
223
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "text.secondary", children: [
|
|
224
|
+
orgLabel(t.org),
|
|
225
|
+
" \xB7 installed ",
|
|
226
|
+
when(t.installedAt),
|
|
227
|
+
t.installedByName ? ` by ${t.installedByName}` : "",
|
|
228
|
+
" \xB7 ",
|
|
229
|
+
t.conversations,
|
|
230
|
+
" ",
|
|
231
|
+
"conversation",
|
|
232
|
+
t.conversations === 1 ? "" : "s"
|
|
233
|
+
] })
|
|
234
|
+
] }),
|
|
235
|
+
t.org ? /* @__PURE__ */ jsx(
|
|
236
|
+
Button,
|
|
237
|
+
{
|
|
238
|
+
size: "small",
|
|
239
|
+
disabled: busy !== null,
|
|
240
|
+
onClick: () => void run(t.id, () => disconnectTeamsTenant(t.tenantId)),
|
|
241
|
+
children: busy === t.id ? "Disconnecting\u2026" : "Disconnect"
|
|
242
|
+
}
|
|
243
|
+
) : /* @__PURE__ */ jsx(
|
|
244
|
+
Button,
|
|
245
|
+
{
|
|
246
|
+
size: "small",
|
|
247
|
+
variant: "contained",
|
|
248
|
+
disabled: busy !== null,
|
|
249
|
+
onClick: () => void run(t.id, () => claimTeamsTenant(t.tenantId)),
|
|
250
|
+
children: busy === t.id ? "Connecting\u2026" : "Connect to my organization"
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
]
|
|
254
|
+
},
|
|
255
|
+
t.id
|
|
256
|
+
))
|
|
257
|
+
] })
|
|
258
|
+
] });
|
|
259
|
+
};
|
|
260
|
+
var WorkspacesPanel_default = WorkspacesPanel;
|
|
261
|
+
|
|
262
|
+
// src/management/components/CrewSection.tsx
|
|
263
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
264
|
+
var CrewTaskCard = lazy(() => import("./crew-task-card-ZCXFTR34.mjs"));
|
|
265
|
+
var NAME_PATTERN = /^[A-Za-z][\w-]{0,30}$/;
|
|
266
|
+
var STATUS_FILTERS = [
|
|
267
|
+
{ value: "all", label: "All" },
|
|
268
|
+
{ value: "active", label: "Active", query: "active" },
|
|
269
|
+
{ value: "awaiting_approval", label: "Needs approval", query: "awaiting_approval" },
|
|
270
|
+
{ value: "completed", label: "Done", query: "completed" },
|
|
271
|
+
{ value: "stopped", label: "Failed or stopped", query: "failed,cancelled,expired" }
|
|
272
|
+
];
|
|
273
|
+
var statusChip = (status) => {
|
|
274
|
+
switch (status) {
|
|
275
|
+
case "completed":
|
|
276
|
+
return { label: "done", color: "success" };
|
|
277
|
+
case "awaiting_approval":
|
|
278
|
+
return { label: "needs approval", color: "warning" };
|
|
279
|
+
case "failed":
|
|
280
|
+
case "expired":
|
|
281
|
+
return { label: status, color: "error" };
|
|
282
|
+
case "cancelled":
|
|
283
|
+
return { label: "stopped", color: "default" };
|
|
284
|
+
default:
|
|
285
|
+
return { label: status, color: "info" };
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
var readLocation = () => {
|
|
289
|
+
if (typeof window === "undefined") return { view: "bandits", taskId: null };
|
|
290
|
+
const params = new URLSearchParams(window.location.search);
|
|
291
|
+
const taskId = params.get("task");
|
|
292
|
+
return { view: params.get("view") === "tasks" || taskId ? "tasks" : "bandits", taskId };
|
|
293
|
+
};
|
|
294
|
+
var writeLocation = (view, taskId) => {
|
|
295
|
+
if (typeof window === "undefined") return;
|
|
296
|
+
const url = new URL(window.location.href);
|
|
297
|
+
if (view === "tasks") url.searchParams.set("view", "tasks");
|
|
298
|
+
else url.searchParams.delete("view");
|
|
299
|
+
if (taskId) url.searchParams.set("task", taskId);
|
|
300
|
+
else url.searchParams.delete("task");
|
|
301
|
+
const next = `${url.pathname}${url.search}${url.hash}`;
|
|
302
|
+
if (next !== `${window.location.pathname}${window.location.search}${window.location.hash}`) {
|
|
303
|
+
window.history.replaceState(window.history.state, "", next);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
var when2 = (iso) => {
|
|
307
|
+
const date = new Date(iso);
|
|
308
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
309
|
+
const today = /* @__PURE__ */ new Date();
|
|
310
|
+
const sameDay = date.toDateString() === today.toDateString();
|
|
311
|
+
return sameDay ? date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : date.toLocaleDateString([], { month: "short", day: "numeric" });
|
|
312
|
+
};
|
|
313
|
+
var CrewSection = ({ standalone = false }) => {
|
|
314
|
+
const [bandits, setBandits] = useState2([]);
|
|
315
|
+
const [tasks, setTasks] = useState2([]);
|
|
316
|
+
const [loading, setLoading] = useState2(true);
|
|
317
|
+
const [error, setError] = useState2(null);
|
|
318
|
+
const [showForm, setShowForm] = useState2(false);
|
|
319
|
+
const [name, setName] = useState2("");
|
|
320
|
+
const [job, setJob] = useState2("");
|
|
321
|
+
const [saving, setSaving] = useState2(false);
|
|
322
|
+
const initialLocation = useMemo(readLocation, []);
|
|
323
|
+
const [view, setView] = useState2(
|
|
324
|
+
standalone ? initialLocation.view : "bandits"
|
|
325
|
+
);
|
|
326
|
+
const [selectedTaskId, setSelectedTaskId] = useState2(
|
|
327
|
+
standalone ? initialLocation.taskId : null
|
|
328
|
+
);
|
|
329
|
+
const [statusFilter, setStatusFilter] = useState2("all");
|
|
330
|
+
const [banditFilter, setBanditFilter] = useState2("all");
|
|
331
|
+
const [runFor, setRunFor] = useState2(null);
|
|
332
|
+
const [runPrompt, setRunPrompt] = useState2("");
|
|
333
|
+
const [starting, setStarting] = useState2(false);
|
|
334
|
+
const taskLimit = standalone ? 50 : 5;
|
|
335
|
+
const taskFilters = useMemo(() => {
|
|
336
|
+
const status = STATUS_FILTERS.find((f) => f.value === statusFilter)?.query;
|
|
337
|
+
return {
|
|
338
|
+
status: standalone ? status : void 0,
|
|
339
|
+
banditId: standalone && banditFilter !== "all" ? banditFilter : void 0
|
|
340
|
+
};
|
|
341
|
+
}, [standalone, statusFilter, banditFilter]);
|
|
342
|
+
const refresh = useCallback2(async () => {
|
|
343
|
+
setLoading(true);
|
|
344
|
+
setError(null);
|
|
345
|
+
try {
|
|
346
|
+
const [list, recent] = await Promise.all([
|
|
347
|
+
listBandits(),
|
|
348
|
+
listCrewTasks(void 0, taskLimit, taskFilters).catch(() => [])
|
|
349
|
+
]);
|
|
350
|
+
setBandits(list);
|
|
351
|
+
setTasks(recent);
|
|
352
|
+
useCrewStore.setState({ bandits: list, loaded: true });
|
|
353
|
+
} catch (err) {
|
|
354
|
+
setError(err instanceof Error ? err.message : "Could not load the crew.");
|
|
355
|
+
} finally {
|
|
356
|
+
setLoading(false);
|
|
357
|
+
}
|
|
358
|
+
}, [taskLimit, taskFilters]);
|
|
359
|
+
useEffect2(() => {
|
|
360
|
+
void refresh();
|
|
361
|
+
}, [refresh]);
|
|
362
|
+
useEffect2(() => {
|
|
363
|
+
if (standalone) writeLocation(view, selectedTaskId);
|
|
364
|
+
}, [standalone, view, selectedTaskId]);
|
|
365
|
+
const openTask = (taskId) => {
|
|
366
|
+
setSelectedTaskId(taskId);
|
|
367
|
+
if (taskId) setView("tasks");
|
|
368
|
+
};
|
|
369
|
+
const submit = async () => {
|
|
370
|
+
const trimmedName = name.trim();
|
|
371
|
+
const trimmedJob = job.trim();
|
|
372
|
+
if (!NAME_PATTERN.test(trimmedName)) {
|
|
373
|
+
setError("Names are one word: letters, digits, - or _ (for example Riley).");
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (trimmedJob.length < 10) {
|
|
377
|
+
setError("Give the Bandit a job description of at least a sentence.");
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
setSaving(true);
|
|
381
|
+
setError(null);
|
|
382
|
+
try {
|
|
383
|
+
await createBandit({ name: trimmedName, jobDescription: trimmedJob });
|
|
384
|
+
setName("");
|
|
385
|
+
setJob("");
|
|
386
|
+
setShowForm(false);
|
|
387
|
+
await refresh();
|
|
388
|
+
} catch (err) {
|
|
389
|
+
setError(err instanceof Error ? err.message : "Could not create the Bandit.");
|
|
390
|
+
} finally {
|
|
391
|
+
setSaving(false);
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
const remove = async (bandit) => {
|
|
395
|
+
try {
|
|
396
|
+
await deleteBandit(bandit.id);
|
|
397
|
+
setBandits((current) => {
|
|
398
|
+
const next = current.filter((b) => b.id !== bandit.id);
|
|
399
|
+
useCrewStore.setState({ bandits: next });
|
|
400
|
+
return next;
|
|
401
|
+
});
|
|
402
|
+
} catch (err) {
|
|
403
|
+
setError(err instanceof Error ? err.message : "Could not remove the Bandit.");
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
const start = async (bandit) => {
|
|
407
|
+
const prompt = runPrompt.trim();
|
|
408
|
+
if (!prompt) {
|
|
409
|
+
setError(`Tell ${bandit.name} what to do.`);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
setStarting(true);
|
|
413
|
+
setError(null);
|
|
414
|
+
try {
|
|
415
|
+
const task = await runCrewTask({ banditId: bandit.id, prompt, origin: "web" });
|
|
416
|
+
setTasks((current) => [task, ...current.filter((t) => t.id !== task.id)]);
|
|
417
|
+
setRunPrompt("");
|
|
418
|
+
setRunFor(null);
|
|
419
|
+
openTask(task.id);
|
|
420
|
+
} catch (err) {
|
|
421
|
+
setError(err instanceof Error ? err.message : "The task could not be started.");
|
|
422
|
+
} finally {
|
|
423
|
+
setStarting(false);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
const onTaskChange = useCallback2((task) => {
|
|
427
|
+
setTasks(
|
|
428
|
+
(current) => current.some((t) => t.id === task.id) ? current.map((t) => t.id === task.id ? task : t) : [task, ...current]
|
|
429
|
+
);
|
|
430
|
+
}, []);
|
|
431
|
+
const selectedTask = selectedTaskId ? tasks.find((t) => t.id === selectedTaskId) ?? null : null;
|
|
432
|
+
const activeCount = tasks.filter((t) => isCrewTaskActive(t.status)).length;
|
|
433
|
+
const banditList = /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
434
|
+
/* @__PURE__ */ jsx2(Collapse, { in: showForm, children: /* @__PURE__ */ jsx2(Paper2, { variant: "outlined", sx: { p: 2, mb: 1.5 }, children: /* @__PURE__ */ jsxs2(Stack2, { spacing: 1.5, children: [
|
|
435
|
+
/* @__PURE__ */ jsx2(
|
|
436
|
+
TextField,
|
|
437
|
+
{
|
|
438
|
+
label: "Name",
|
|
439
|
+
size: "small",
|
|
440
|
+
value: name,
|
|
441
|
+
onChange: (e) => setName(e.target.value),
|
|
442
|
+
placeholder: "Riley",
|
|
443
|
+
inputProps: { maxLength: 31, "aria-label": "Bandit name" }
|
|
444
|
+
}
|
|
445
|
+
),
|
|
446
|
+
/* @__PURE__ */ jsx2(
|
|
447
|
+
TextField,
|
|
448
|
+
{
|
|
449
|
+
label: "Job description",
|
|
450
|
+
size: "small",
|
|
451
|
+
multiline: true,
|
|
452
|
+
minRows: 2,
|
|
453
|
+
value: job,
|
|
454
|
+
onChange: (e) => setJob(e.target.value),
|
|
455
|
+
placeholder: "Research analyst who writes short, cited briefs for the sales team.",
|
|
456
|
+
inputProps: { "aria-label": "Job description" }
|
|
457
|
+
}
|
|
458
|
+
),
|
|
459
|
+
/* @__PURE__ */ jsxs2(Stack2, { direction: "row", spacing: 1, children: [
|
|
460
|
+
/* @__PURE__ */ jsx2(
|
|
461
|
+
Button2,
|
|
462
|
+
{
|
|
463
|
+
variant: "contained",
|
|
464
|
+
size: "small",
|
|
465
|
+
onClick: () => void submit(),
|
|
466
|
+
disabled: saving,
|
|
467
|
+
children: saving ? "Creating\u2026" : "Create"
|
|
468
|
+
}
|
|
469
|
+
),
|
|
470
|
+
/* @__PURE__ */ jsx2(Button2, { size: "small", onClick: () => setShowForm(false), disabled: saving, children: "Cancel" })
|
|
471
|
+
] })
|
|
472
|
+
] }) }) }),
|
|
473
|
+
!loading && bandits.length === 0 && !showForm && /* @__PURE__ */ jsx2(Paper2, { variant: "outlined", sx: { p: 2, mb: 1.5 }, children: /* @__PURE__ */ jsxs2(Typography2, { variant: "body2", color: "text.secondary", children: [
|
|
474
|
+
"No Bandits yet. Create one here, in Slack (",
|
|
475
|
+
/* @__PURE__ */ jsx2("code", { children: "/bandit crew create Riley | Research analyst who writes short, cited briefs" }),
|
|
476
|
+
") or from the terminal (",
|
|
477
|
+
/* @__PURE__ */ jsx2("code", { children: 'bandit crew create Riley --job "\u2026"' }),
|
|
478
|
+
")."
|
|
479
|
+
] }) }),
|
|
480
|
+
/* @__PURE__ */ jsx2(Stack2, { spacing: 1, children: bandits.map((bandit) => /* @__PURE__ */ jsxs2(
|
|
481
|
+
Paper2,
|
|
482
|
+
{
|
|
483
|
+
variant: "outlined",
|
|
484
|
+
sx: { p: 1.5, display: "flex", flexDirection: "column", gap: 1 },
|
|
485
|
+
children: [
|
|
486
|
+
/* @__PURE__ */ jsxs2(Box2, { sx: { display: "flex", alignItems: "flex-start", gap: 1.5 }, children: [
|
|
487
|
+
/* @__PURE__ */ jsxs2(Box2, { sx: { flex: 1, minWidth: 0 }, children: [
|
|
488
|
+
/* @__PURE__ */ jsxs2(Stack2, { direction: "row", spacing: 1, alignItems: "center", children: [
|
|
489
|
+
/* @__PURE__ */ jsx2(Typography2, { sx: { fontWeight: 700 }, children: bandit.name }),
|
|
490
|
+
bandit.model && /* @__PURE__ */ jsx2(Chip2, { size: "small", label: bandit.model })
|
|
491
|
+
] }),
|
|
492
|
+
/* @__PURE__ */ jsx2(
|
|
493
|
+
Typography2,
|
|
494
|
+
{
|
|
495
|
+
variant: "body2",
|
|
496
|
+
color: "text.secondary",
|
|
497
|
+
sx: { whiteSpace: "pre-wrap" },
|
|
498
|
+
children: bandit.jobDescription
|
|
499
|
+
}
|
|
500
|
+
),
|
|
501
|
+
/* @__PURE__ */ jsxs2(Typography2, { variant: "caption", color: "text.secondary", children: [
|
|
502
|
+
"tools: ",
|
|
503
|
+
bandit.allowedTools.join(", "),
|
|
504
|
+
bandit.ownerDisplayName ? ` \xB7 owner ${bandit.ownerDisplayName}` : ""
|
|
505
|
+
] })
|
|
506
|
+
] }),
|
|
507
|
+
standalone && /* @__PURE__ */ jsx2(Tooltip, { title: `Hand ${bandit.name} a task`, children: /* @__PURE__ */ jsx2(
|
|
508
|
+
IconButton,
|
|
509
|
+
{
|
|
510
|
+
size: "small",
|
|
511
|
+
onClick: () => {
|
|
512
|
+
setRunFor((current) => current === bandit.id ? null : bandit.id);
|
|
513
|
+
setRunPrompt("");
|
|
514
|
+
},
|
|
515
|
+
"aria-label": `Hand ${bandit.name} a task`,
|
|
516
|
+
color: runFor === bandit.id ? "primary" : "default",
|
|
517
|
+
children: /* @__PURE__ */ jsx2(Play, { fontSize: "small" })
|
|
518
|
+
}
|
|
519
|
+
) }),
|
|
520
|
+
/* @__PURE__ */ jsx2(Tooltip, { title: `Remove ${bandit.name}`, children: /* @__PURE__ */ jsx2(
|
|
521
|
+
IconButton,
|
|
522
|
+
{
|
|
523
|
+
size: "small",
|
|
524
|
+
onClick: () => void remove(bandit),
|
|
525
|
+
"aria-label": `Remove ${bandit.name}`,
|
|
526
|
+
children: /* @__PURE__ */ jsx2(Trash, { fontSize: "small" })
|
|
527
|
+
}
|
|
528
|
+
) })
|
|
529
|
+
] }),
|
|
530
|
+
standalone && /* @__PURE__ */ jsx2(Collapse, { in: runFor === bandit.id, unmountOnExit: true, children: /* @__PURE__ */ jsxs2(Stack2, { spacing: 1, children: [
|
|
531
|
+
/* @__PURE__ */ jsx2(
|
|
532
|
+
TextField,
|
|
533
|
+
{
|
|
534
|
+
size: "small",
|
|
535
|
+
multiline: true,
|
|
536
|
+
minRows: 2,
|
|
537
|
+
value: runPrompt,
|
|
538
|
+
onChange: (e) => setRunPrompt(e.target.value),
|
|
539
|
+
placeholder: `What should ${bandit.name} do? For example: research Acme's 2026 pricing changes and draft a one-page brief.`,
|
|
540
|
+
inputProps: {
|
|
541
|
+
maxLength: 8e3,
|
|
542
|
+
"aria-label": `Task for ${bandit.name}`
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
),
|
|
546
|
+
/* @__PURE__ */ jsxs2(Stack2, { direction: "row", spacing: 1, alignItems: "center", children: [
|
|
547
|
+
/* @__PURE__ */ jsx2(
|
|
548
|
+
Button2,
|
|
549
|
+
{
|
|
550
|
+
variant: "contained",
|
|
551
|
+
size: "small",
|
|
552
|
+
onClick: () => void start(bandit),
|
|
553
|
+
disabled: starting || !runPrompt.trim(),
|
|
554
|
+
children: starting ? "Starting\u2026" : "Start task"
|
|
555
|
+
}
|
|
556
|
+
),
|
|
557
|
+
/* @__PURE__ */ jsx2(
|
|
558
|
+
Button2,
|
|
559
|
+
{
|
|
560
|
+
size: "small",
|
|
561
|
+
onClick: () => setRunFor(null),
|
|
562
|
+
disabled: starting,
|
|
563
|
+
children: "Cancel"
|
|
564
|
+
}
|
|
565
|
+
),
|
|
566
|
+
/* @__PURE__ */ jsx2(Typography2, { variant: "caption", color: "text.secondary", children: "Runs on your account; anything that affects others waits for your approval." })
|
|
567
|
+
] })
|
|
568
|
+
] }) })
|
|
569
|
+
]
|
|
570
|
+
},
|
|
571
|
+
bandit.id
|
|
572
|
+
)) })
|
|
573
|
+
] });
|
|
574
|
+
const recentTasks = tasks.length > 0 && /* @__PURE__ */ jsxs2(Box2, { sx: { mt: 2 }, children: [
|
|
575
|
+
/* @__PURE__ */ jsx2(Typography2, { variant: "caption", color: "text.secondary", sx: { fontWeight: 700 }, children: "Recent tasks" }),
|
|
576
|
+
/* @__PURE__ */ jsx2(Stack2, { spacing: 0.5, sx: { mt: 0.5 }, children: tasks.map((task) => {
|
|
577
|
+
const status = statusChip(task.status);
|
|
578
|
+
const link = task.deliverables?.find((d) => d.shareUrl || d.url);
|
|
579
|
+
return /* @__PURE__ */ jsxs2(
|
|
580
|
+
Stack2,
|
|
581
|
+
{
|
|
582
|
+
direction: "row",
|
|
583
|
+
spacing: 1,
|
|
584
|
+
alignItems: "center",
|
|
585
|
+
sx: { minWidth: 0 },
|
|
586
|
+
children: [
|
|
587
|
+
/* @__PURE__ */ jsx2(
|
|
588
|
+
Chip2,
|
|
589
|
+
{
|
|
590
|
+
size: "small",
|
|
591
|
+
label: status.label,
|
|
592
|
+
color: status.color,
|
|
593
|
+
variant: "outlined"
|
|
594
|
+
}
|
|
595
|
+
),
|
|
596
|
+
/* @__PURE__ */ jsxs2(Typography2, { variant: "body2", noWrap: true, sx: { flex: 1, minWidth: 0 }, children: [
|
|
597
|
+
/* @__PURE__ */ jsx2("strong", { children: task.banditName }),
|
|
598
|
+
": ",
|
|
599
|
+
task.prompt
|
|
600
|
+
] }),
|
|
601
|
+
link && /* @__PURE__ */ jsx2(
|
|
602
|
+
Link,
|
|
603
|
+
{
|
|
604
|
+
href: link.shareUrl ?? link.url ?? void 0,
|
|
605
|
+
target: "_blank",
|
|
606
|
+
rel: "noreferrer",
|
|
607
|
+
variant: "body2",
|
|
608
|
+
children: "open"
|
|
609
|
+
}
|
|
610
|
+
)
|
|
611
|
+
]
|
|
612
|
+
},
|
|
613
|
+
task.id
|
|
614
|
+
);
|
|
615
|
+
}) })
|
|
616
|
+
] });
|
|
617
|
+
const tasksView = selectedTask || selectedTaskId ? /* @__PURE__ */ jsxs2(Box2, { "data-testid": "crew-task-detail", children: [
|
|
618
|
+
/* @__PURE__ */ jsx2(Button2, { size: "small", onClick: () => openTask(null), sx: { mb: 1 }, children: "\u2190 All tasks" }),
|
|
619
|
+
/* @__PURE__ */ jsx2(Suspense, { fallback: /* @__PURE__ */ jsx2(LinearProgress2, {}), children: /* @__PURE__ */ jsx2(
|
|
620
|
+
CrewTaskCard,
|
|
621
|
+
{
|
|
622
|
+
taskId: selectedTaskId,
|
|
623
|
+
initial: selectedTask,
|
|
624
|
+
embedded: true,
|
|
625
|
+
onChange: onTaskChange
|
|
626
|
+
},
|
|
627
|
+
selectedTaskId ?? ""
|
|
628
|
+
) })
|
|
629
|
+
] }) : /* @__PURE__ */ jsxs2(Box2, { "data-testid": "crew-task-list", children: [
|
|
630
|
+
/* @__PURE__ */ jsxs2(Stack2, { direction: { xs: "column", sm: "row" }, spacing: 1, sx: { mb: 1.5 }, children: [
|
|
631
|
+
/* @__PURE__ */ jsx2(
|
|
632
|
+
TextField,
|
|
633
|
+
{
|
|
634
|
+
select: true,
|
|
635
|
+
size: "small",
|
|
636
|
+
label: "Status",
|
|
637
|
+
value: statusFilter,
|
|
638
|
+
onChange: (e) => setStatusFilter(e.target.value),
|
|
639
|
+
sx: { minWidth: 180 },
|
|
640
|
+
inputProps: { "aria-label": "Status filter" },
|
|
641
|
+
children: STATUS_FILTERS.map((f) => /* @__PURE__ */ jsx2(MenuItem, { value: f.value, children: f.label }, f.value))
|
|
642
|
+
}
|
|
643
|
+
),
|
|
644
|
+
/* @__PURE__ */ jsxs2(
|
|
645
|
+
TextField,
|
|
646
|
+
{
|
|
647
|
+
select: true,
|
|
648
|
+
size: "small",
|
|
649
|
+
label: "Bandit",
|
|
650
|
+
value: banditFilter,
|
|
651
|
+
onChange: (e) => setBanditFilter(e.target.value),
|
|
652
|
+
sx: { minWidth: 160 },
|
|
653
|
+
inputProps: { "aria-label": "Bandit filter" },
|
|
654
|
+
children: [
|
|
655
|
+
/* @__PURE__ */ jsx2(MenuItem, { value: "all", children: "All Bandits" }),
|
|
656
|
+
bandits.map((b) => /* @__PURE__ */ jsx2(MenuItem, { value: b.id, children: b.name }, b.id))
|
|
657
|
+
]
|
|
658
|
+
}
|
|
659
|
+
)
|
|
660
|
+
] }),
|
|
661
|
+
!loading && tasks.length === 0 && /* @__PURE__ */ jsx2(Paper2, { variant: "outlined", sx: { p: 2 }, children: /* @__PURE__ */ jsxs2(Typography2, { variant: "body2", color: "text.secondary", children: [
|
|
662
|
+
"No tasks",
|
|
663
|
+
" ",
|
|
664
|
+
statusFilter === "all" && banditFilter === "all" ? "yet" : "match these filters",
|
|
665
|
+
". Hand a Bandit a task from the Bandits view, type ",
|
|
666
|
+
/* @__PURE__ */ jsx2("code", { children: "@Riley \u2026" }),
|
|
667
|
+
" in the chat, or run ",
|
|
668
|
+
/* @__PURE__ */ jsx2("code", { children: 'bandit crew run Riley "\u2026"' }),
|
|
669
|
+
" in the terminal."
|
|
670
|
+
] }) }),
|
|
671
|
+
/* @__PURE__ */ jsx2(Stack2, { spacing: 0.75, children: tasks.map((task) => {
|
|
672
|
+
const status = statusChip(task.status);
|
|
673
|
+
return /* @__PURE__ */ jsxs2(
|
|
674
|
+
Paper2,
|
|
675
|
+
{
|
|
676
|
+
variant: "outlined",
|
|
677
|
+
component: "button",
|
|
678
|
+
type: "button",
|
|
679
|
+
onClick: () => openTask(task.id),
|
|
680
|
+
"aria-label": `Open task: ${task.prompt}`,
|
|
681
|
+
sx: {
|
|
682
|
+
p: 1.25,
|
|
683
|
+
display: "flex",
|
|
684
|
+
alignItems: "center",
|
|
685
|
+
gap: 1,
|
|
686
|
+
width: "100%",
|
|
687
|
+
textAlign: "left",
|
|
688
|
+
cursor: "pointer",
|
|
689
|
+
bgcolor: "background.paper",
|
|
690
|
+
font: "inherit",
|
|
691
|
+
color: "inherit"
|
|
692
|
+
},
|
|
693
|
+
children: [
|
|
694
|
+
/* @__PURE__ */ jsx2(
|
|
695
|
+
Chip2,
|
|
696
|
+
{
|
|
697
|
+
size: "small",
|
|
698
|
+
label: status.label,
|
|
699
|
+
color: status.color,
|
|
700
|
+
variant: "outlined"
|
|
701
|
+
}
|
|
702
|
+
),
|
|
703
|
+
/* @__PURE__ */ jsxs2(Box2, { sx: { flex: 1, minWidth: 0 }, children: [
|
|
704
|
+
/* @__PURE__ */ jsxs2(Typography2, { variant: "body2", noWrap: true, children: [
|
|
705
|
+
/* @__PURE__ */ jsx2("strong", { children: task.banditName }),
|
|
706
|
+
": ",
|
|
707
|
+
task.prompt
|
|
708
|
+
] }),
|
|
709
|
+
/* @__PURE__ */ jsxs2(Typography2, { variant: "caption", color: "text.secondary", children: [
|
|
710
|
+
when2(task.createdAt),
|
|
711
|
+
task.origin ? ` \xB7 from ${task.origin}` : "",
|
|
712
|
+
task.steps?.length ? ` \xB7 ${task.steps.length} steps` : ""
|
|
713
|
+
] })
|
|
714
|
+
] })
|
|
715
|
+
]
|
|
716
|
+
},
|
|
717
|
+
task.id
|
|
718
|
+
);
|
|
719
|
+
}) })
|
|
720
|
+
] });
|
|
721
|
+
return /* @__PURE__ */ jsxs2(Box2, { component: "section", "aria-label": "Bandit Crew", sx: { mt: standalone ? 0 : 4 }, children: [
|
|
722
|
+
/* @__PURE__ */ jsxs2(
|
|
723
|
+
Box2,
|
|
724
|
+
{
|
|
725
|
+
sx: {
|
|
726
|
+
display: "flex",
|
|
727
|
+
alignItems: "center",
|
|
728
|
+
justifyContent: standalone ? "space-between" : "space-between",
|
|
729
|
+
gap: 1,
|
|
730
|
+
mb: 0.5,
|
|
731
|
+
flexWrap: "wrap"
|
|
732
|
+
},
|
|
733
|
+
children: [
|
|
734
|
+
!standalone && /* @__PURE__ */ jsx2(
|
|
735
|
+
Typography2,
|
|
736
|
+
{
|
|
737
|
+
variant: "overline",
|
|
738
|
+
color: "text.secondary",
|
|
739
|
+
sx: { fontWeight: 700, letterSpacing: 0.6 },
|
|
740
|
+
children: "Bandit Crew"
|
|
741
|
+
}
|
|
742
|
+
),
|
|
743
|
+
standalone && /* @__PURE__ */ jsxs2(
|
|
744
|
+
Tabs,
|
|
745
|
+
{
|
|
746
|
+
value: view,
|
|
747
|
+
onChange: (_, next) => {
|
|
748
|
+
setView(next);
|
|
749
|
+
if (next === "bandits") setSelectedTaskId(null);
|
|
750
|
+
},
|
|
751
|
+
"aria-label": "Crew views",
|
|
752
|
+
sx: { minHeight: 36, "& .MuiTab-root": { minHeight: 36, py: 0.5 } },
|
|
753
|
+
children: [
|
|
754
|
+
/* @__PURE__ */ jsx2(Tab, { value: "bandits", label: "Bandits" }),
|
|
755
|
+
/* @__PURE__ */ jsx2(
|
|
756
|
+
Tab,
|
|
757
|
+
{
|
|
758
|
+
value: "tasks",
|
|
759
|
+
label: activeCount > 0 ? `Tasks (${activeCount} active)` : "Tasks"
|
|
760
|
+
}
|
|
761
|
+
)
|
|
762
|
+
]
|
|
763
|
+
}
|
|
764
|
+
),
|
|
765
|
+
/* @__PURE__ */ jsxs2(Stack2, { direction: "row", spacing: 0.5, children: [
|
|
766
|
+
/* @__PURE__ */ jsx2(Tooltip, { title: "Refresh", children: /* @__PURE__ */ jsx2(
|
|
767
|
+
IconButton,
|
|
768
|
+
{
|
|
769
|
+
size: "small",
|
|
770
|
+
onClick: () => void refresh(),
|
|
771
|
+
"aria-label": "Refresh crew",
|
|
772
|
+
children: /* @__PURE__ */ jsx2(Refresh, { fontSize: "small" })
|
|
773
|
+
}
|
|
774
|
+
) }),
|
|
775
|
+
view === "bandits" && /* @__PURE__ */ jsx2(
|
|
776
|
+
Button2,
|
|
777
|
+
{
|
|
778
|
+
size: "small",
|
|
779
|
+
startIcon: /* @__PURE__ */ jsx2(Plus, {}),
|
|
780
|
+
onClick: () => setShowForm((v) => !v),
|
|
781
|
+
children: "New Bandit"
|
|
782
|
+
}
|
|
783
|
+
)
|
|
784
|
+
] })
|
|
785
|
+
]
|
|
786
|
+
}
|
|
787
|
+
),
|
|
788
|
+
view === "bandits" && /* @__PURE__ */ jsxs2(Typography2, { variant: "body2", color: "text.secondary", sx: { mb: 1.5 }, children: [
|
|
789
|
+
"Named teammates you can hand work to: in the chat with",
|
|
790
|
+
" ",
|
|
791
|
+
/* @__PURE__ */ jsx2("code", { children: "@Riley research X and draft a summary" }),
|
|
792
|
+
", in Slack or Microsoft Teams with",
|
|
793
|
+
" ",
|
|
794
|
+
/* @__PURE__ */ jsx2("code", { children: "@Bandit ask Riley to \u2026" }),
|
|
795
|
+
", or from the terminal with",
|
|
796
|
+
" ",
|
|
797
|
+
/* @__PURE__ */ jsx2("code", { children: 'bandit crew run Riley "\u2026"' }),
|
|
798
|
+
". Each one shows its steps, asks before it acts outside the conversation, and files the result in your Stash."
|
|
799
|
+
] }),
|
|
800
|
+
loading && /* @__PURE__ */ jsx2(LinearProgress2, { sx: { mb: 1 } }),
|
|
801
|
+
error && /* @__PURE__ */ jsx2(Alert2, { severity: "error", sx: { mb: 1.5 }, onClose: () => setError(null), children: error }),
|
|
802
|
+
view === "bandits" ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
803
|
+
banditList,
|
|
804
|
+
!standalone && recentTasks,
|
|
805
|
+
standalone && /* @__PURE__ */ jsx2(WorkspacesPanel_default, {})
|
|
806
|
+
] }) : tasksView
|
|
807
|
+
] });
|
|
808
|
+
};
|
|
809
|
+
var CrewSection_default = CrewSection;
|
|
810
|
+
|
|
811
|
+
export {
|
|
812
|
+
CrewSection_default
|
|
813
|
+
};
|
|
814
|
+
//# sourceMappingURL=chunk-XWUHUDAV.mjs.map
|