@bikdotai/bik-component-library 0.0.849-beta.2 → 0.0.849-beta.3
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/dist/cjs/components/agent-builder/components/ConfigToolPanel.js +11 -11
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +5 -5
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js +7 -7
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +2 -2
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js +9 -0
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/cjs/editor/extensions/mention/MentionDropdown.js +1 -1
- package/dist/cjs/editor/extensions/mention/MentionDropdown.js.map +1 -1
- package/dist/cjs/editor/extensions/mention/MentionExtension.js +1 -1
- package/dist/cjs/editor/extensions/mention/MentionExtension.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.d.ts +8 -0
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +151 -124
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +90 -88
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.d.ts +7 -0
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +174 -133
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.d.ts +9 -0
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +65 -47
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.d.ts +27 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js +70 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +93 -91
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/esm/editor/extensions/mention/MentionDropdown.js +19 -19
- package/dist/esm/editor/extensions/mention/MentionDropdown.js.map +1 -1
- package/dist/esm/editor/extensions/mention/MentionExtension.js +15 -15
- package/dist/esm/editor/extensions/mention/MentionExtension.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import
|
|
3
|
-
import { useState as w } from "react";
|
|
4
|
-
import
|
|
5
|
-
import { TitleSmall as
|
|
6
|
-
import { COLORS as
|
|
7
|
-
import { FieldBlock as
|
|
8
|
-
import { AGENT_CHAR_LIMITS as
|
|
9
|
-
import { DRAWER_BODY_STYLE as
|
|
10
|
-
import { ToolInstructionsField as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
|
|
1
|
+
import { jsx as o, jsxs as S } from "react/jsx-runtime";
|
|
2
|
+
import D from "../../../assets/icons/cross.svg.js";
|
|
3
|
+
import F, { useState as w } from "react";
|
|
4
|
+
import y from "styled-components";
|
|
5
|
+
import { TitleSmall as $, BodyCaption as R } from "../../TypographyStyle.js";
|
|
6
|
+
import { COLORS as s } from "../../../constants/Theme.js";
|
|
7
|
+
import { FieldBlock as P } from "../AgentBuilder.styled.js";
|
|
8
|
+
import { AGENT_CHAR_LIMITS as Y } from "../constants/charLimits.js";
|
|
9
|
+
import { DRAWER_BODY_STYLE as V, DRAWER_HEADER_STYLE as z, DrawerHeaderText as H } from "./DrawerHeaderText.js";
|
|
10
|
+
import { ToolInstructionsField as M } from "./ToolInstructionsField.js";
|
|
11
|
+
import { VariableTriggerArea as O } from "./VariableTriggerArea.js";
|
|
12
|
+
import { SideModal as W } from "../../side-modal/SideModal.js";
|
|
13
|
+
import { Switch as G } from "../../switch/Switch.js";
|
|
14
|
+
import { Input as N } from "../../input/Input.js";
|
|
15
|
+
import { Tag as q } from "../../tag/Tag.js";
|
|
16
|
+
const J = {
|
|
16
17
|
send_email: {
|
|
17
18
|
title: "Send Email",
|
|
18
19
|
subtitle: "Notify someone by email when this agent can't continue. You pick the recipient, the AI drafts the message."
|
|
@@ -21,222 +22,248 @@ const V = {
|
|
|
21
22
|
title: "Send Slack message",
|
|
22
23
|
subtitle: "Post a message to a Slack channel. You pick the channel, the AI composes the message from the conversation."
|
|
23
24
|
}
|
|
24
|
-
},
|
|
25
|
-
chips:
|
|
26
|
-
onChange:
|
|
27
|
-
placeholder:
|
|
28
|
-
nativeID:
|
|
29
|
-
hint:
|
|
25
|
+
}, K = ({
|
|
26
|
+
chips: e,
|
|
27
|
+
onChange: i,
|
|
28
|
+
placeholder: p,
|
|
29
|
+
nativeID: m,
|
|
30
|
+
hint: g
|
|
30
31
|
}) => {
|
|
31
|
-
const [
|
|
32
|
-
const
|
|
33
|
-
|
|
32
|
+
const [h, k] = w(""), u = () => {
|
|
33
|
+
const a = h.split(",").map((r) => r.trim()).filter(Boolean);
|
|
34
|
+
a.length && i([...e, ...a.filter((r) => !e.includes(r))]), k("");
|
|
34
35
|
};
|
|
35
|
-
return /* @__PURE__ */
|
|
36
|
-
/* @__PURE__ */
|
|
37
|
-
|
|
36
|
+
return /* @__PURE__ */ S(U, { children: [
|
|
37
|
+
/* @__PURE__ */ o(
|
|
38
|
+
X,
|
|
38
39
|
{
|
|
39
|
-
id:
|
|
40
|
+
id: m,
|
|
40
41
|
type: "text",
|
|
41
|
-
placeholder:
|
|
42
|
-
value:
|
|
43
|
-
onChange: (
|
|
44
|
-
onBlur:
|
|
45
|
-
onKeyDown: (
|
|
46
|
-
|
|
42
|
+
placeholder: p,
|
|
43
|
+
value: h,
|
|
44
|
+
onChange: (a) => k(a.target.value),
|
|
45
|
+
onBlur: u,
|
|
46
|
+
onKeyDown: (a) => {
|
|
47
|
+
a.key === "Enter" || a.key === "," ? (a.preventDefault(), u()) : a.key === "Backspace" && h === "" && e.length > 0 && i(e.slice(0, -1));
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
),
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
g,
|
|
52
|
+
e.length > 0 && /* @__PURE__ */ o(Z, { children: e.map((a, r) => /* @__PURE__ */ o(
|
|
53
|
+
q,
|
|
53
54
|
{
|
|
54
|
-
tagText:
|
|
55
|
+
tagText: a,
|
|
55
56
|
theme: "light",
|
|
56
57
|
type: "neutral",
|
|
57
58
|
variant: "regular",
|
|
58
|
-
TrailingIcon:
|
|
59
|
-
onTrailingIconClicked: () =>
|
|
59
|
+
TrailingIcon: D,
|
|
60
|
+
onTrailingIconClicked: () => i(e.filter((C, f) => f !== r))
|
|
60
61
|
},
|
|
61
|
-
`${
|
|
62
|
+
`${a}-${r}`
|
|
62
63
|
)) })
|
|
63
64
|
] });
|
|
64
|
-
},
|
|
65
|
-
const
|
|
66
|
-
return Object.keys(
|
|
67
|
-
|
|
68
|
-
}),
|
|
69
|
-
},
|
|
70
|
-
toolKey:
|
|
71
|
-
template:
|
|
72
|
-
onClose:
|
|
73
|
-
onSave:
|
|
74
|
-
initial:
|
|
75
|
-
onImprove:
|
|
76
|
-
charLimits:
|
|
77
|
-
|
|
65
|
+
}, Q = (e, i) => {
|
|
66
|
+
const p = {};
|
|
67
|
+
return Object.keys(e).forEach((m) => {
|
|
68
|
+
p[m] = i?.params[m]?.value ?? e[m].value;
|
|
69
|
+
}), p;
|
|
70
|
+
}, A = (e) => String(e ?? "").split(",").map((i) => i.trim()).filter(Boolean), kt = ({
|
|
71
|
+
toolKey: e,
|
|
72
|
+
template: i,
|
|
73
|
+
onClose: p,
|
|
74
|
+
onSave: m,
|
|
75
|
+
initial: g,
|
|
76
|
+
onImprove: h,
|
|
77
|
+
charLimits: k = Y,
|
|
78
|
+
variablesData: u,
|
|
79
|
+
zIndex: a
|
|
78
80
|
}) => {
|
|
79
|
-
const [
|
|
80
|
-
() =>
|
|
81
|
-
), [
|
|
82
|
-
(t) => !t.required || String(
|
|
83
|
-
),
|
|
84
|
-
if (!
|
|
81
|
+
const [r, C] = w(
|
|
82
|
+
() => Q(i, g)
|
|
83
|
+
), [f, I] = w(!1), v = Object.values(i), E = e === "send_email", d = (t, l) => C((c) => ({ ...c, [t]: l })), _ = v.every(
|
|
84
|
+
(t) => !t.required || String(r[t.key] ?? "").trim() !== ""
|
|
85
|
+
), L = async () => {
|
|
86
|
+
if (!_ || f)
|
|
85
87
|
return;
|
|
86
88
|
const t = {};
|
|
87
|
-
v.forEach((
|
|
88
|
-
t[
|
|
89
|
+
v.forEach((n) => {
|
|
90
|
+
t[n.key] = { ...n, value: r[n.key] };
|
|
89
91
|
});
|
|
90
92
|
const l = {
|
|
91
|
-
id:
|
|
92
|
-
tool_key:
|
|
93
|
+
id: g?.id ?? `${e}_${Date.now().toString(36)}`,
|
|
94
|
+
tool_key: e,
|
|
93
95
|
params: t
|
|
94
|
-
},
|
|
95
|
-
if (
|
|
96
|
-
|
|
96
|
+
}, c = m(l);
|
|
97
|
+
if (c && typeof c.then == "function") {
|
|
98
|
+
I(!0);
|
|
97
99
|
try {
|
|
98
|
-
await
|
|
100
|
+
await c;
|
|
99
101
|
} finally {
|
|
100
|
-
|
|
102
|
+
I(!1);
|
|
101
103
|
}
|
|
102
104
|
}
|
|
103
|
-
},
|
|
105
|
+
}, j = (t) => {
|
|
104
106
|
const l = `config-tool-${t.key.toLowerCase()}`;
|
|
105
107
|
switch (t.component) {
|
|
106
108
|
// Multi-value email chips — only for the email tool. Slack's KeywordInput
|
|
107
109
|
// (channelId) falls through to the plain input below.
|
|
108
110
|
case "KeywordInput":
|
|
109
|
-
if (!
|
|
111
|
+
if (!E)
|
|
110
112
|
break;
|
|
111
|
-
return /* @__PURE__ */
|
|
112
|
-
/* @__PURE__ */
|
|
113
|
-
/* @__PURE__ */
|
|
114
|
-
|
|
113
|
+
return /* @__PURE__ */ S(P, { children: [
|
|
114
|
+
/* @__PURE__ */ o($, { color: s.content.primary, children: t.title }),
|
|
115
|
+
/* @__PURE__ */ o(
|
|
116
|
+
O,
|
|
115
117
|
{
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
variablesData: u,
|
|
119
|
+
onInsert: (n) => {
|
|
120
|
+
const x = A(r[t.key]);
|
|
121
|
+
x.includes(n) || d(t.key, [...x, n].join(","));
|
|
122
|
+
},
|
|
123
|
+
children: /* @__PURE__ */ o(
|
|
124
|
+
K,
|
|
125
|
+
{
|
|
126
|
+
nativeID: l,
|
|
127
|
+
placeholder: t.hint ?? "",
|
|
128
|
+
chips: A(r[t.key]),
|
|
129
|
+
onChange: (n) => d(t.key, n.join(",")),
|
|
130
|
+
hint: /* @__PURE__ */ o(R, { color: s.content.secondary, children: "Press Enter or comma to add multiple emails" })
|
|
131
|
+
}
|
|
132
|
+
)
|
|
121
133
|
}
|
|
122
134
|
)
|
|
123
135
|
] }, t.key);
|
|
124
136
|
case "MultilineInput":
|
|
125
|
-
return /* @__PURE__ */
|
|
126
|
-
|
|
137
|
+
return /* @__PURE__ */ o(
|
|
138
|
+
M,
|
|
127
139
|
{
|
|
128
140
|
"data-test": l,
|
|
129
141
|
label: t.title,
|
|
130
|
-
value: String(
|
|
131
|
-
onChange: (
|
|
132
|
-
maxLength:
|
|
142
|
+
value: String(r[t.key] ?? ""),
|
|
143
|
+
onChange: (n) => d(t.key, n),
|
|
144
|
+
maxLength: k.instructions,
|
|
133
145
|
placeholder: t.hint ?? "",
|
|
134
|
-
onImprove:
|
|
146
|
+
onImprove: h,
|
|
147
|
+
variablesData: u
|
|
135
148
|
},
|
|
136
149
|
t.key
|
|
137
150
|
);
|
|
138
151
|
case "Switch":
|
|
139
|
-
return /* @__PURE__ */
|
|
140
|
-
/* @__PURE__ */
|
|
141
|
-
/* @__PURE__ */
|
|
142
|
-
t.hint && /* @__PURE__ */
|
|
152
|
+
return /* @__PURE__ */ S(tt, { children: [
|
|
153
|
+
/* @__PURE__ */ S(et, { children: [
|
|
154
|
+
/* @__PURE__ */ o($, { color: s.content.primary, children: t.title }),
|
|
155
|
+
t.hint && /* @__PURE__ */ o(R, { color: s.content.secondary, children: t.hint })
|
|
143
156
|
] }),
|
|
144
|
-
/* @__PURE__ */
|
|
145
|
-
|
|
157
|
+
/* @__PURE__ */ o(
|
|
158
|
+
G,
|
|
146
159
|
{
|
|
147
160
|
"data-test": l,
|
|
148
|
-
value: !!
|
|
149
|
-
onValueChange: async (
|
|
161
|
+
value: !!r[t.key],
|
|
162
|
+
onValueChange: async (n) => d(t.key, n)
|
|
150
163
|
}
|
|
151
164
|
)
|
|
152
165
|
] }, t.key);
|
|
153
166
|
}
|
|
154
|
-
|
|
155
|
-
|
|
167
|
+
const c = /* @__PURE__ */ o(
|
|
168
|
+
N,
|
|
156
169
|
{
|
|
157
170
|
"data-test": l,
|
|
158
171
|
variant: "small",
|
|
159
172
|
labelText: t.title,
|
|
160
173
|
labelTextBold: !0,
|
|
161
174
|
placeholder: t.hint ?? "",
|
|
162
|
-
value: String(
|
|
163
|
-
onChangeText: (
|
|
175
|
+
value: String(r[t.key] ?? ""),
|
|
176
|
+
onChangeText: (n) => d(t.key, n)
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
return E ? /* @__PURE__ */ o(
|
|
180
|
+
O,
|
|
181
|
+
{
|
|
182
|
+
variablesData: u,
|
|
183
|
+
onInsert: (n, x) => {
|
|
184
|
+
const T = String(r[t.key] ?? ""), B = x ?? T.length;
|
|
185
|
+
d(
|
|
186
|
+
t.key,
|
|
187
|
+
`${T.slice(0, B)}${n}${T.slice(B)}`
|
|
188
|
+
);
|
|
189
|
+
},
|
|
190
|
+
children: c
|
|
164
191
|
},
|
|
165
192
|
t.key
|
|
166
|
-
);
|
|
167
|
-
}, b =
|
|
168
|
-
return /* @__PURE__ */
|
|
169
|
-
|
|
193
|
+
) : /* @__PURE__ */ o(F.Fragment, { children: c }, t.key);
|
|
194
|
+
}, b = J[e];
|
|
195
|
+
return /* @__PURE__ */ o(
|
|
196
|
+
W,
|
|
170
197
|
{
|
|
171
198
|
header: b.title,
|
|
172
199
|
closeOnEscapeKey: !1,
|
|
173
|
-
zIndex:
|
|
174
|
-
headerCustomComponent: /* @__PURE__ */
|
|
200
|
+
zIndex: a,
|
|
201
|
+
headerCustomComponent: /* @__PURE__ */ o(H, { title: b.title, subtitle: b.subtitle }),
|
|
175
202
|
hideCrossButton: !1,
|
|
176
203
|
width: "431px",
|
|
177
|
-
headerStyle:
|
|
178
|
-
bodyStyle:
|
|
179
|
-
onClose:
|
|
204
|
+
headerStyle: z,
|
|
205
|
+
bodyStyle: V,
|
|
206
|
+
onClose: p,
|
|
180
207
|
saveButtonProps: {
|
|
181
208
|
"data-test": "config-tool-save",
|
|
182
209
|
buttonText: "Save",
|
|
183
210
|
buttonType: "primary",
|
|
184
211
|
size: "small",
|
|
185
|
-
disabled: !
|
|
186
|
-
isLoading:
|
|
187
|
-
onClick:
|
|
212
|
+
disabled: !_,
|
|
213
|
+
isLoading: f,
|
|
214
|
+
onClick: L
|
|
188
215
|
},
|
|
189
216
|
cancelButtonProps: {
|
|
190
217
|
"data-test": "config-tool-cancel",
|
|
191
218
|
buttonText: "Cancel",
|
|
192
219
|
buttonType: "tertiaryGray",
|
|
193
220
|
size: "small",
|
|
194
|
-
onClick:
|
|
221
|
+
onClick: p
|
|
195
222
|
},
|
|
196
|
-
children: v.map(
|
|
223
|
+
children: v.map(j)
|
|
197
224
|
}
|
|
198
225
|
);
|
|
199
|
-
},
|
|
226
|
+
}, U = y.div`
|
|
200
227
|
display: flex;
|
|
201
228
|
flex-direction: column;
|
|
202
229
|
gap: 8px;
|
|
203
|
-
`,
|
|
230
|
+
`, X = y.input`
|
|
204
231
|
width: 100%;
|
|
205
232
|
min-width: 0;
|
|
206
233
|
box-sizing: border-box;
|
|
207
234
|
height: 32px;
|
|
208
235
|
padding: 0 8px;
|
|
209
|
-
border: 1px solid ${
|
|
236
|
+
border: 1px solid ${s.stroke.primary};
|
|
210
237
|
border-radius: 4px;
|
|
211
238
|
font-family: 'Inter', sans-serif;
|
|
212
239
|
font-size: 14px;
|
|
213
|
-
color: ${
|
|
214
|
-
background: ${
|
|
240
|
+
color: ${s.content.primary};
|
|
241
|
+
background: ${s.surface.standard};
|
|
215
242
|
outline: none;
|
|
216
243
|
|
|
217
244
|
&::placeholder {
|
|
218
|
-
color: ${
|
|
245
|
+
color: ${s.content.secondary};
|
|
219
246
|
}
|
|
220
247
|
|
|
221
248
|
&:focus {
|
|
222
|
-
border-color: ${
|
|
249
|
+
border-color: ${s.stroke.brand};
|
|
223
250
|
}
|
|
224
|
-
`,
|
|
251
|
+
`, Z = y.div`
|
|
225
252
|
display: flex;
|
|
226
253
|
flex-wrap: wrap;
|
|
227
254
|
gap: 6px;
|
|
228
|
-
`,
|
|
255
|
+
`, tt = y.div`
|
|
229
256
|
display: flex;
|
|
230
257
|
align-items: center;
|
|
231
258
|
justify-content: space-between;
|
|
232
259
|
gap: 12px;
|
|
233
|
-
`,
|
|
260
|
+
`, et = y.div`
|
|
234
261
|
display: flex;
|
|
235
262
|
flex-direction: column;
|
|
236
263
|
gap: 4px;
|
|
237
264
|
min-width: 0;
|
|
238
265
|
`;
|
|
239
266
|
export {
|
|
240
|
-
|
|
267
|
+
kt as ConfigToolPanel
|
|
241
268
|
};
|
|
242
269
|
//# sourceMappingURL=ConfigToolPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigToolPanel.js","sources":["../../../../../src/components/agent-builder/components/ConfigToolPanel.tsx"],"sourcesContent":["import CrossIcon from '@src/assets/icons/cross.svg';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { Switch } from '@src/components/switch';\nimport { Tag } from '@src/components/tag';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tConfigToolConfig,\n\tConfigToolKey,\n\tParamField,\n\tParamsBlob,\n} from '../AgentBuilder.model';\nimport { FieldBlock } from '../AgentBuilder.styled';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport {\n\tDRAWER_BODY_STYLE,\n\tDRAWER_HEADER_STYLE,\n\tDrawerHeaderText,\n} from './DrawerHeaderText';\nimport { ToolInstructionsField } from './ToolInstructionsField';\n\n/** Header copy per shared-drawer tool. */\nconst TOOL_COPY: Record<ConfigToolKey, { title: string; subtitle: string }> = {\n\tsend_email: {\n\t\ttitle: 'Send Email',\n\t\tsubtitle:\n\t\t\t\"Notify someone by email when this agent can't continue. You pick the recipient, the AI drafts the message.\",\n\t},\n\tsend_slack_message: {\n\t\ttitle: 'Send Slack message',\n\t\tsubtitle:\n\t\t\t'Post a message to a Slack channel. You pick the channel, the AI composes the message from the conversation.',\n\t},\n};\n\ninterface ConfigToolPanelProps {\n\t/** Which tool this drawer configures (drives copy + persistence). */\n\ttoolKey: ConfigToolKey;\n\t/**\n\t * The backend template (`list-catalog` → params) for `toolKey`. The form is\n\t * DYNAMIC: exactly these fields render, in this order, each by its\n\t * `component` kind (KeywordInput | MultilineInput | Switch | fallback input).\n\t */\n\ttemplate: ParamsBlob;\n\tonClose: () => void;\n\t/** Persist the filled template. A pending promise shows the Save loader. */\n\tonSave: (config: ConfigToolConfig) => void | Promise<void>;\n\t/** Seed values when editing an existing tool. */\n\tinitial?: ConfigToolConfig;\n\t/** Optional \"Improve with AI\" for multiline fields. Omit to hide it. */\n\tonImprove?: (text: string) => Promise<string>;\n\tcharLimits?: AgentCharLimits;\n\t/** SideModal stacking order — raise it when opened over another drawer. */\n\tzIndex?: number;\n}\n\ninterface EmailChipsFieldProps {\n\tchips: string[];\n\tonChange: (next: string[]) => void;\n\tplaceholder: string;\n\tnativeID?: string;\n\t/** Optional helper caption shown between the input and the chips. */\n\thint?: React.ReactNode;\n}\n\n/**\n * Email entry field: type an address and press Enter / comma (or blur) to add\n * it. Added emails render as removable chips BELOW the input — not inside it.\n * Backspace on an empty input removes the last chip.\n */\nconst EmailChipsField: React.FC<EmailChipsFieldProps> = ({\n\tchips,\n\tonChange,\n\tplaceholder,\n\tnativeID,\n\thint,\n}) => {\n\tconst [buffer, setBuffer] = useState('');\n\n\tconst commit = () => {\n\t\tconst parts = buffer\n\t\t\t.split(',')\n\t\t\t.map((s) => s.trim())\n\t\t\t.filter(Boolean);\n\t\tif (parts.length) {\n\t\t\tonChange([...chips, ...parts.filter((p) => !chips.includes(p))]);\n\t\t}\n\t\tsetBuffer('');\n\t};\n\n\treturn (\n\t\t<ChipsFieldWrap>\n\t\t\t<EmailInputBox\n\t\t\t\tid={nativeID}\n\t\t\t\ttype=\"text\"\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tvalue={buffer}\n\t\t\t\tonChange={(e) => setBuffer(e.target.value)}\n\t\t\t\tonBlur={commit}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (e.key === 'Enter' || e.key === ',') {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tcommit();\n\t\t\t\t\t} else if (\n\t\t\t\t\t\te.key === 'Backspace' &&\n\t\t\t\t\t\tbuffer === '' &&\n\t\t\t\t\t\tchips.length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tonChange(chips.slice(0, -1));\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t{hint}\n\t\t\t{chips.length > 0 && (\n\t\t\t\t<ChipRow>\n\t\t\t\t\t{chips.map((email, i) => (\n\t\t\t\t\t\t<Tag\n\t\t\t\t\t\t\tkey={`${email}-${i}`}\n\t\t\t\t\t\t\ttagText={email}\n\t\t\t\t\t\t\ttheme=\"light\"\n\t\t\t\t\t\t\ttype=\"neutral\"\n\t\t\t\t\t\t\tvariant=\"regular\"\n\t\t\t\t\t\t\tTrailingIcon={CrossIcon}\n\t\t\t\t\t\t\tonTrailingIconClicked={() =>\n\t\t\t\t\t\t\t\tonChange(chips.filter((_, idx) => idx !== i))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</ChipRow>\n\t\t\t)}\n\t\t</ChipsFieldWrap>\n\t);\n};\n\n/** Field values keyed by param key (the editable part of a {@link ParamsBlob}). */\ntype ParamValues = Record<string, string | boolean | number | object>;\n\nconst seedValues = (\n\ttemplate: ParamsBlob,\n\tinitial?: ConfigToolConfig,\n): ParamValues => {\n\tconst values: ParamValues = {};\n\tObject.keys(template).forEach((key) => {\n\t\tvalues[key] = initial?.params[key]?.value ?? template[key].value;\n\t});\n\treturn values;\n};\n\n/** Chips ↔ the string value KeywordInput fields carry (comma-separated). */\nconst toChips = (value: unknown): string[] =>\n\tString(value ?? '')\n\t\t.split(',')\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean);\n\n/**\n * Shared right-side drawer for the params-driven configurable tools (email /\n * Slack). Fully backend-driven: it renders the template fields by their\n * `component` kind and returns the same blob with values filled in. KeywordInput\n * renders as multi-value email chips only for `send_email`; every other tool\n * gets a plain single-line input. Mount it fresh per open (key it) so `initial`\n * seeds the state. Built on the shared `SideModal` shell.\n */\nexport const ConfigToolPanel: React.FC<ConfigToolPanelProps> = ({\n\ttoolKey,\n\ttemplate,\n\tonClose,\n\tonSave,\n\tinitial,\n\tonImprove,\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tzIndex,\n}) => {\n\tconst [values, setValues] = useState<ParamValues>(() =>\n\t\tseedValues(template, initial),\n\t);\n\tconst [saving, setSaving] = useState(false);\n\n\tconst fields = Object.values(template);\n\tconst isEmail = toolKey === 'send_email';\n\tconst setValue = (key: string, value: string | boolean | number | object) =>\n\t\tsetValues((prev) => ({ ...prev, [key]: value }));\n\n\tconst canSave = fields.every(\n\t\t(f) => !f.required || String(values[f.key] ?? '').trim() !== '',\n\t);\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst params: ParamsBlob = {};\n\t\tfields.forEach((f) => {\n\t\t\t// Save the FULL descriptor with only `value` changed — the backend\n\t\t\t// infers each field's type from `component` and reads `required`.\n\t\t\tparams[f.key] = { ...f, value: values[f.key] };\n\t\t});\n\t\tconst config: ConfigToolConfig = {\n\t\t\tid: initial?.id ?? `${toolKey}_${Date.now().toString(36)}`,\n\t\t\ttool_key: toolKey,\n\t\t\tparams,\n\t\t};\n\t\tconst result = onSave(config);\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetSaving(true);\n\t\t\ttry {\n\t\t\t\tawait result;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst renderField = (field: ParamField) => {\n\t\tconst testId = `config-tool-${field.key.toLowerCase()}`;\n\t\tswitch (field.component) {\n\t\t\t// Multi-value email chips — only for the email tool. Slack's KeywordInput\n\t\t\t// (channelId) falls through to the plain input below.\n\t\t\tcase 'KeywordInput':\n\t\t\t\tif (!isEmail) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t<FieldBlock key={field.key}>\n\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t{field.title}\n\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t<EmailChipsField\n\t\t\t\t\t\t\tnativeID={testId}\n\t\t\t\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\t\t\t\tchips={toChips(values[field.key])}\n\t\t\t\t\t\t\tonChange={(chips) => setValue(field.key, chips.join(','))}\n\t\t\t\t\t\t\thint={\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\tPress Enter or comma to add multiple emails\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FieldBlock>\n\t\t\t\t);\n\t\t\tcase 'MultilineInput':\n\t\t\t\treturn (\n\t\t\t\t\t<ToolInstructionsField\n\t\t\t\t\t\tkey={field.key}\n\t\t\t\t\t\tdata-test={testId}\n\t\t\t\t\t\tlabel={field.title}\n\t\t\t\t\t\tvalue={String(values[field.key] ?? '')}\n\t\t\t\t\t\tonChange={(text) => setValue(field.key, text)}\n\t\t\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\t\t\tonImprove={onImprove}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase 'Switch':\n\t\t\t\treturn (\n\t\t\t\t\t<SwitchRow key={field.key}>\n\t\t\t\t\t\t<SwitchText>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t{field.title}\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t{field.hint && (\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\t{field.hint}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</SwitchText>\n\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\tdata-test={testId}\n\t\t\t\t\t\t\tvalue={Boolean(values[field.key])}\n\t\t\t\t\t\t\tonValueChange={async (next) => setValue(field.key, next)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</SwitchRow>\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t\treturn (\n\t\t\t<Input\n\t\t\t\tkey={field.key}\n\t\t\t\tdata-test={testId}\n\t\t\t\tvariant=\"small\"\n\t\t\t\tlabelText={field.title}\n\t\t\t\tlabelTextBold\n\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\tvalue={String(values[field.key] ?? '')}\n\t\t\t\tonChangeText={(text) => setValue(field.key, text)}\n\t\t\t/>\n\t\t);\n\t};\n\n\tconst copy = TOOL_COPY[toolKey];\n\n\treturn (\n\t\t<SideModal\n\t\t\theader={copy.title}\n\t\t\tcloseOnEscapeKey={false}\n\t\t\tzIndex={zIndex}\n\t\t\theaderCustomComponent={\n\t\t\t\t<DrawerHeaderText title={copy.title} subtitle={copy.subtitle} />\n\t\t\t}\n\t\t\thideCrossButton={false}\n\t\t\twidth=\"431px\"\n\t\t\theaderStyle={DRAWER_HEADER_STYLE}\n\t\t\tbodyStyle={DRAWER_BODY_STYLE}\n\t\t\tonClose={onClose}\n\t\t\tsaveButtonProps={{\n\t\t\t\t'data-test': 'config-tool-save',\n\t\t\t\tbuttonText: 'Save',\n\t\t\t\tbuttonType: 'primary',\n\t\t\t\tsize: 'small',\n\t\t\t\tdisabled: !canSave,\n\t\t\t\tisLoading: saving,\n\t\t\t\tonClick: handleSave,\n\t\t\t}}\n\t\t\tcancelButtonProps={{\n\t\t\t\t'data-test': 'config-tool-cancel',\n\t\t\t\tbuttonText: 'Cancel',\n\t\t\t\tbuttonType: 'tertiaryGray',\n\t\t\t\tsize: 'small',\n\t\t\t\tonClick: onClose,\n\t\t\t}}\n\t\t>\n\t\t\t{fields.map(renderField)}\n\t\t</SideModal>\n\t);\n};\n\nconst ChipsFieldWrap = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n`;\n\nconst EmailInputBox = styled.input`\n\twidth: 100%;\n\tmin-width: 0;\n\tbox-sizing: border-box;\n\theight: 32px;\n\tpadding: 0 8px;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tfont-family: 'Inter', sans-serif;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\tbackground: ${COLORS.surface.standard};\n\toutline: none;\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.secondary};\n\t}\n\n\t&:focus {\n\t\tborder-color: ${COLORS.stroke.brand};\n\t}\n`;\n\nconst ChipRow = styled.div`\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 6px;\n`;\n\nconst SwitchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 12px;\n`;\n\nconst SwitchText = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n`;\n"],"names":["TOOL_COPY","EmailChipsField","chips","onChange","placeholder","nativeID","hint","buffer","setBuffer","useState","commit","parts","p","ChipsFieldWrap","jsx","EmailInputBox","ChipRow","email","i","Tag","CrossIcon","_","idx","seedValues","template","initial","values","key","toChips","value","s","ConfigToolPanel","toolKey","onClose","onSave","onImprove","charLimits","AGENT_CHAR_LIMITS","zIndex","setValues","saving","setSaving","fields","isEmail","setValue","prev","canSave","f","handleSave","params","config","result","renderField","field","testId","FieldBlock","TitleSmall","COLORS","BodyCaption","ToolInstructionsField","text","SwitchRow","jsxs","SwitchText","Switch","next","Input","copy","SideModal","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","styled"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ConfigToolPanel.js","sources":["../../../../../src/components/agent-builder/components/ConfigToolPanel.tsx"],"sourcesContent":["import CrossIcon from '@src/assets/icons/cross.svg';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { Switch } from '@src/components/switch';\nimport { Tag } from '@src/components/tag';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport type { VariableListInterfaceV3 } from '../../variable-picker-v3/model';\nimport {\n\tConfigToolConfig,\n\tConfigToolKey,\n\tParamField,\n\tParamsBlob,\n} from '../AgentBuilder.model';\nimport { FieldBlock } from '../AgentBuilder.styled';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport {\n\tDRAWER_BODY_STYLE,\n\tDRAWER_HEADER_STYLE,\n\tDrawerHeaderText,\n} from './DrawerHeaderText';\nimport { ToolInstructionsField } from './ToolInstructionsField';\nimport { VariableTriggerArea } from './VariableTriggerArea';\n\n/** Header copy per shared-drawer tool. */\nconst TOOL_COPY: Record<ConfigToolKey, { title: string; subtitle: string }> = {\n\tsend_email: {\n\t\ttitle: 'Send Email',\n\t\tsubtitle:\n\t\t\t\"Notify someone by email when this agent can't continue. You pick the recipient, the AI drafts the message.\",\n\t},\n\tsend_slack_message: {\n\t\ttitle: 'Send Slack message',\n\t\tsubtitle:\n\t\t\t'Post a message to a Slack channel. You pick the channel, the AI composes the message from the conversation.',\n\t},\n};\n\ninterface ConfigToolPanelProps {\n\t/** Which tool this drawer configures (drives copy + persistence). */\n\ttoolKey: ConfigToolKey;\n\t/**\n\t * The backend template (`list-catalog` → params) for `toolKey`. The form is\n\t * DYNAMIC: exactly these fields render, in this order, each by its\n\t * `component` kind (KeywordInput | MultilineInput | Switch | fallback input).\n\t */\n\ttemplate: ParamsBlob;\n\tonClose: () => void;\n\t/** Persist the filled template. A pending promise shows the Save loader. */\n\tonSave: (config: ConfigToolConfig) => void | Promise<void>;\n\t/** Seed values when editing an existing tool. */\n\tinitial?: ConfigToolConfig;\n\t/** Optional \"Improve with AI\" for multiline fields. Omit to hide it. */\n\tonImprove?: (text: string) => Promise<string>;\n\tcharLimits?: AgentCharLimits;\n\t/**\n\t * Variable catalog for the `@` trigger. When non-empty, `@` in the email\n\t * tool's Subject / Send To / Reply To / CC opens the variable picker\n\t * directly, and Message Instructions upgrades to the variables-only mention\n\t * editor. Absent → the drawer behaves exactly as before.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\n\t/** SideModal stacking order — raise it when opened over another drawer. */\n\tzIndex?: number;\n}\n\ninterface EmailChipsFieldProps {\n\tchips: string[];\n\tonChange: (next: string[]) => void;\n\tplaceholder: string;\n\tnativeID?: string;\n\t/** Optional helper caption shown between the input and the chips. */\n\thint?: React.ReactNode;\n}\n\n/**\n * Email entry field: type an address and press Enter / comma (or blur) to add\n * it. Added emails render as removable chips BELOW the input — not inside it.\n * Backspace on an empty input removes the last chip.\n */\nconst EmailChipsField: React.FC<EmailChipsFieldProps> = ({\n\tchips,\n\tonChange,\n\tplaceholder,\n\tnativeID,\n\thint,\n}) => {\n\tconst [buffer, setBuffer] = useState('');\n\n\tconst commit = () => {\n\t\tconst parts = buffer\n\t\t\t.split(',')\n\t\t\t.map((s) => s.trim())\n\t\t\t.filter(Boolean);\n\t\tif (parts.length) {\n\t\t\tonChange([...chips, ...parts.filter((p) => !chips.includes(p))]);\n\t\t}\n\t\tsetBuffer('');\n\t};\n\n\treturn (\n\t\t<ChipsFieldWrap>\n\t\t\t<EmailInputBox\n\t\t\t\tid={nativeID}\n\t\t\t\ttype=\"text\"\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tvalue={buffer}\n\t\t\t\tonChange={(e) => setBuffer(e.target.value)}\n\t\t\t\tonBlur={commit}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (e.key === 'Enter' || e.key === ',') {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tcommit();\n\t\t\t\t\t} else if (\n\t\t\t\t\t\te.key === 'Backspace' &&\n\t\t\t\t\t\tbuffer === '' &&\n\t\t\t\t\t\tchips.length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tonChange(chips.slice(0, -1));\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t{hint}\n\t\t\t{chips.length > 0 && (\n\t\t\t\t<ChipRow>\n\t\t\t\t\t{chips.map((email, i) => (\n\t\t\t\t\t\t<Tag\n\t\t\t\t\t\t\tkey={`${email}-${i}`}\n\t\t\t\t\t\t\ttagText={email}\n\t\t\t\t\t\t\ttheme=\"light\"\n\t\t\t\t\t\t\ttype=\"neutral\"\n\t\t\t\t\t\t\tvariant=\"regular\"\n\t\t\t\t\t\t\tTrailingIcon={CrossIcon}\n\t\t\t\t\t\t\tonTrailingIconClicked={() =>\n\t\t\t\t\t\t\t\tonChange(chips.filter((_, idx) => idx !== i))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</ChipRow>\n\t\t\t)}\n\t\t</ChipsFieldWrap>\n\t);\n};\n\n/** Field values keyed by param key (the editable part of a {@link ParamsBlob}). */\ntype ParamValues = Record<string, string | boolean | number | object>;\n\nconst seedValues = (\n\ttemplate: ParamsBlob,\n\tinitial?: ConfigToolConfig,\n): ParamValues => {\n\tconst values: ParamValues = {};\n\tObject.keys(template).forEach((key) => {\n\t\tvalues[key] = initial?.params[key]?.value ?? template[key].value;\n\t});\n\treturn values;\n};\n\n/** Chips ↔ the string value KeywordInput fields carry (comma-separated). */\nconst toChips = (value: unknown): string[] =>\n\tString(value ?? '')\n\t\t.split(',')\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean);\n\n/**\n * Shared right-side drawer for the params-driven configurable tools (email /\n * Slack). Fully backend-driven: it renders the template fields by their\n * `component` kind and returns the same blob with values filled in. KeywordInput\n * renders as multi-value email chips only for `send_email`; every other tool\n * gets a plain single-line input. Mount it fresh per open (key it) so `initial`\n * seeds the state. Built on the shared `SideModal` shell.\n */\nexport const ConfigToolPanel: React.FC<ConfigToolPanelProps> = ({\n\ttoolKey,\n\ttemplate,\n\tonClose,\n\tonSave,\n\tinitial,\n\tonImprove,\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tvariablesData,\n\tzIndex,\n}) => {\n\tconst [values, setValues] = useState<ParamValues>(() =>\n\t\tseedValues(template, initial),\n\t);\n\tconst [saving, setSaving] = useState(false);\n\n\tconst fields = Object.values(template);\n\tconst isEmail = toolKey === 'send_email';\n\tconst setValue = (key: string, value: string | boolean | number | object) =>\n\t\tsetValues((prev) => ({ ...prev, [key]: value }));\n\n\tconst canSave = fields.every(\n\t\t(f) => !f.required || String(values[f.key] ?? '').trim() !== '',\n\t);\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst params: ParamsBlob = {};\n\t\tfields.forEach((f) => {\n\t\t\t// Save the FULL descriptor with only `value` changed — the backend\n\t\t\t// infers each field's type from `component` and reads `required`.\n\t\t\tparams[f.key] = { ...f, value: values[f.key] };\n\t\t});\n\t\tconst config: ConfigToolConfig = {\n\t\t\tid: initial?.id ?? `${toolKey}_${Date.now().toString(36)}`,\n\t\t\ttool_key: toolKey,\n\t\t\tparams,\n\t\t};\n\t\tconst result = onSave(config);\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetSaving(true);\n\t\t\ttry {\n\t\t\t\tawait result;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst renderField = (field: ParamField) => {\n\t\tconst testId = `config-tool-${field.key.toLowerCase()}`;\n\t\tswitch (field.component) {\n\t\t\t// Multi-value email chips — only for the email tool. Slack's KeywordInput\n\t\t\t// (channelId) falls through to the plain input below.\n\t\t\tcase 'KeywordInput':\n\t\t\t\tif (!isEmail) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t<FieldBlock key={field.key}>\n\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t{field.title}\n\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t{/* `@` at the start of an entry picks a variable (added as a\n\t\t\t\t\t\t chip); `@` inside an address types normally. */}\n\t\t\t\t\t\t<VariableTriggerArea\n\t\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t\t\tonInsert={(token) => {\n\t\t\t\t\t\t\t\tconst chips = toChips(values[field.key]);\n\t\t\t\t\t\t\t\tif (!chips.includes(token)) {\n\t\t\t\t\t\t\t\t\tsetValue(field.key, [...chips, token].join(','));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<EmailChipsField\n\t\t\t\t\t\t\t\tnativeID={testId}\n\t\t\t\t\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\t\t\t\t\tchips={toChips(values[field.key])}\n\t\t\t\t\t\t\t\tonChange={(chips) => setValue(field.key, chips.join(','))}\n\t\t\t\t\t\t\t\thint={\n\t\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\t\tPress Enter or comma to add multiple emails\n\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</VariableTriggerArea>\n\t\t\t\t\t</FieldBlock>\n\t\t\t\t);\n\t\t\tcase 'MultilineInput':\n\t\t\t\treturn (\n\t\t\t\t\t<ToolInstructionsField\n\t\t\t\t\t\tkey={field.key}\n\t\t\t\t\t\tdata-test={testId}\n\t\t\t\t\t\tlabel={field.title}\n\t\t\t\t\t\tvalue={String(values[field.key] ?? '')}\n\t\t\t\t\t\tonChange={(text) => setValue(field.key, text)}\n\t\t\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\t\t\tonImprove={onImprove}\n\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase 'Switch':\n\t\t\t\treturn (\n\t\t\t\t\t<SwitchRow key={field.key}>\n\t\t\t\t\t\t<SwitchText>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t{field.title}\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t{field.hint && (\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\t{field.hint}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</SwitchText>\n\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\tdata-test={testId}\n\t\t\t\t\t\t\tvalue={Boolean(values[field.key])}\n\t\t\t\t\t\t\tonValueChange={async (next) => setValue(field.key, next)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</SwitchRow>\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t\tconst plainInput = (\n\t\t\t<Input\n\t\t\t\tdata-test={testId}\n\t\t\t\tvariant=\"small\"\n\t\t\t\tlabelText={field.title}\n\t\t\t\tlabelTextBold\n\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\tvalue={String(values[field.key] ?? '')}\n\t\t\t\tonChangeText={(text) => setValue(field.key, text)}\n\t\t\t/>\n\t\t);\n\t\t// `@` variables only in the email tool's free-text fields (Subject) —\n\t\t// a Slack channel id can't hold a variable.\n\t\tif (!isEmail) {\n\t\t\treturn <React.Fragment key={field.key}>{plainInput}</React.Fragment>;\n\t\t}\n\t\treturn (\n\t\t\t<VariableTriggerArea\n\t\t\t\tkey={field.key}\n\t\t\t\tvariablesData={variablesData}\n\t\t\t\tonInsert={(token, caret) => {\n\t\t\t\t\tconst current = String(values[field.key] ?? '');\n\t\t\t\t\tconst at = caret ?? current.length;\n\t\t\t\t\tsetValue(\n\t\t\t\t\t\tfield.key,\n\t\t\t\t\t\t`${current.slice(0, at)}${token}${current.slice(at)}`,\n\t\t\t\t\t);\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{plainInput}\n\t\t\t</VariableTriggerArea>\n\t\t);\n\t};\n\n\tconst copy = TOOL_COPY[toolKey];\n\n\treturn (\n\t\t<SideModal\n\t\t\theader={copy.title}\n\t\t\tcloseOnEscapeKey={false}\n\t\t\tzIndex={zIndex}\n\t\t\theaderCustomComponent={\n\t\t\t\t<DrawerHeaderText title={copy.title} subtitle={copy.subtitle} />\n\t\t\t}\n\t\t\thideCrossButton={false}\n\t\t\twidth=\"431px\"\n\t\t\theaderStyle={DRAWER_HEADER_STYLE}\n\t\t\tbodyStyle={DRAWER_BODY_STYLE}\n\t\t\tonClose={onClose}\n\t\t\tsaveButtonProps={{\n\t\t\t\t'data-test': 'config-tool-save',\n\t\t\t\tbuttonText: 'Save',\n\t\t\t\tbuttonType: 'primary',\n\t\t\t\tsize: 'small',\n\t\t\t\tdisabled: !canSave,\n\t\t\t\tisLoading: saving,\n\t\t\t\tonClick: handleSave,\n\t\t\t}}\n\t\t\tcancelButtonProps={{\n\t\t\t\t'data-test': 'config-tool-cancel',\n\t\t\t\tbuttonText: 'Cancel',\n\t\t\t\tbuttonType: 'tertiaryGray',\n\t\t\t\tsize: 'small',\n\t\t\t\tonClick: onClose,\n\t\t\t}}\n\t\t>\n\t\t\t{fields.map(renderField)}\n\t\t</SideModal>\n\t);\n};\n\nconst ChipsFieldWrap = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n`;\n\nconst EmailInputBox = styled.input`\n\twidth: 100%;\n\tmin-width: 0;\n\tbox-sizing: border-box;\n\theight: 32px;\n\tpadding: 0 8px;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tfont-family: 'Inter', sans-serif;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\tbackground: ${COLORS.surface.standard};\n\toutline: none;\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.secondary};\n\t}\n\n\t&:focus {\n\t\tborder-color: ${COLORS.stroke.brand};\n\t}\n`;\n\nconst ChipRow = styled.div`\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 6px;\n`;\n\nconst SwitchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 12px;\n`;\n\nconst SwitchText = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n`;\n"],"names":["TOOL_COPY","EmailChipsField","chips","onChange","placeholder","nativeID","hint","buffer","setBuffer","useState","commit","parts","s","p","ChipsFieldWrap","jsx","EmailInputBox","e","ChipRow","email","i","Tag","CrossIcon","_","idx","seedValues","template","initial","values","key","toChips","value","ConfigToolPanel","toolKey","onClose","onSave","onImprove","charLimits","AGENT_CHAR_LIMITS","variablesData","zIndex","setValues","saving","setSaving","fields","isEmail","setValue","prev","canSave","f","handleSave","params","config","result","renderField","field","testId","FieldBlock","TitleSmall","COLORS","VariableTriggerArea","token","BodyCaption","ToolInstructionsField","text","SwitchRow","jsxs","SwitchText","Switch","next","plainInput","Input","caret","current","at","React","copy","SideModal","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","styled"],"mappings":";;;;;;;;;;;;;;;AA4BA,MAAMA,IAAwE;AAAA,EAC7E,YAAY;AAAA,IACX,OAAO;AAAA,IACP,UACC;AAAA,EAAA;AAAA,EAEF,oBAAoB;AAAA,IACnB,OAAO;AAAA,IACP,UACC;AAAA,EAAA;AAEH,GA4CMC,IAAkD,CAAC;AAAA,EACxD,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC;AACD,MAAM;AACL,QAAM,CAACC,GAAQC,CAAS,IAAIC,EAAS,EAAE,GAEjCC,IAAS,MAAM;AACpB,UAAMC,IAAQJ,EACZ,MAAM,GAAG,EACT,IAAI,CAACK,MAAMA,EAAE,KAAA,CAAM,EACnB,OAAO,OAAO;AAChB,IAAID,EAAM,UACTR,EAAS,CAAC,GAAGD,GAAO,GAAGS,EAAM,OAAO,CAACE,MAAM,CAACX,EAAM,SAASW,CAAC,CAAC,CAAC,CAAC,GAEhEL,EAAU,EAAE;AAAA,EACb;AAEA,2BACEM,GAAA,EACA,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAACC;AAAA,MAAA;AAAA,QACA,IAAIX;AAAA,QACJ,MAAK;AAAA,QACL,aAAAD;AAAA,QACA,OAAOG;AAAA,QACP,UAAU,CAACU,MAAMT,EAAUS,EAAE,OAAO,KAAK;AAAA,QACzC,QAAQP;AAAA,QACR,WAAW,CAACO,MAAM;AACjB,UAAIA,EAAE,QAAQ,WAAWA,EAAE,QAAQ,OAClCA,EAAE,eAAA,GACFP,EAAA,KAEAO,EAAE,QAAQ,eACVV,MAAW,MACXL,EAAM,SAAS,KAEfC,EAASD,EAAM,MAAM,GAAG,EAAE,CAAC;AAAA,QAE7B;AAAA,MAAA;AAAA,IAAA;AAAA,IAEAI;AAAA,IACAJ,EAAM,SAAS,KACf,gBAAAa,EAACG,KACC,UAAAhB,EAAM,IAAI,CAACiB,GAAOC,MAClB,gBAAAL;AAAA,MAACM;AAAA,MAAA;AAAA,QAEA,SAASF;AAAA,QACT,OAAM;AAAA,QACN,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,cAAcG;AAAAA,QACd,uBAAuB,MACtBnB,EAASD,EAAM,OAAO,CAACqB,GAAGC,MAAQA,MAAQJ,CAAC,CAAC;AAAA,MAAA;AAAA,MAPxC,GAAGD,CAAK,IAAIC,CAAC;AAAA,IAAA,CAUnB,EAAA,CACF;AAAA,EAAA,GAEF;AAEF,GAKMK,IAAa,CAClBC,GACAC,MACiB;AACjB,QAAMC,IAAsB,CAAA;AAC5B,gBAAO,KAAKF,CAAQ,EAAE,QAAQ,CAACG,MAAQ;AACtC,IAAAD,EAAOC,CAAG,IAAIF,GAAS,OAAOE,CAAG,GAAG,SAASH,EAASG,CAAG,EAAE;AAAA,EAC5D,CAAC,GACMD;AACR,GAGME,IAAU,CAACC,MAChB,OAAOA,KAAS,EAAE,EAChB,MAAM,GAAG,EACT,IAAI,CAACnB,MAAMA,EAAE,MAAM,EACnB,OAAO,OAAO,GAUJoB,KAAkD,CAAC;AAAA,EAC/D,SAAAC;AAAA,EACA,UAAAP;AAAA,EACA,SAAAQ;AAAA,EACA,QAAAC;AAAA,EACA,SAAAR;AAAA,EACA,WAAAS;AAAA,EACA,YAAAC,IAAaC;AAAA,EACb,eAAAC;AAAA,EACA,QAAAC;AACD,MAAM;AACL,QAAM,CAACZ,GAAQa,CAAS,IAAIhC;AAAA,IAAsB,MACjDgB,EAAWC,GAAUC,CAAO;AAAA,EAAA,GAEvB,CAACe,GAAQC,CAAS,IAAIlC,EAAS,EAAK,GAEpCmC,IAAS,OAAO,OAAOlB,CAAQ,GAC/BmB,IAAUZ,MAAY,cACtBa,IAAW,CAACjB,GAAaE,MAC9BU,EAAU,CAACM,OAAU,EAAE,GAAGA,GAAM,CAAClB,CAAG,GAAGE,IAAQ,GAE1CiB,IAAUJ,EAAO;AAAA,IACtB,CAACK,MAAM,CAACA,EAAE,YAAY,OAAOrB,EAAOqB,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW;AAAA,EAAA,GAGxDC,IAAa,YAAY;AAC9B,QAAI,CAACF,KAAWN;AACf;AAED,UAAMS,IAAqB,CAAA;AAC3B,IAAAP,EAAO,QAAQ,CAACK,MAAM;AAGrB,MAAAE,EAAOF,EAAE,GAAG,IAAI,EAAE,GAAGA,GAAG,OAAOrB,EAAOqB,EAAE,GAAG,EAAA;AAAA,IAC5C,CAAC;AACD,UAAMG,IAA2B;AAAA,MAChC,IAAIzB,GAAS,MAAM,GAAGM,CAAO,IAAI,KAAK,IAAA,EAAM,SAAS,EAAE,CAAC;AAAA,MACxD,UAAUA;AAAA,MACV,QAAAkB;AAAA,IAAA,GAEKE,IAASlB,EAAOiB,CAAM;AAC5B,QAAIC,KAAU,OAAQA,EAAyB,QAAS,YAAY;AACnE,MAAAV,EAAU,EAAI;AACd,UAAI;AACH,cAAMU;AAAA,MACP,UAAA;AACC,QAAAV,EAAU,EAAK;AAAA,MAChB;AAAA,IACD;AAAA,EACD,GAEMW,IAAc,CAACC,MAAsB;AAC1C,UAAMC,IAAS,eAAeD,EAAM,IAAI,aAAa;AACrD,YAAQA,EAAM,WAAA;AAAA;AAAA;AAAA,MAGb,KAAK;AACJ,YAAI,CAACV;AACJ;AAED,iCACEY,GAAA,EACA,UAAA;AAAA,UAAA,gBAAA1C,EAAC2C,KAAW,OAAOC,EAAO,QAAQ,SAChC,YAAM,OACR;AAAA,UAGA,gBAAA5C;AAAA,YAAC6C;AAAA,YAAA;AAAA,cACA,eAAArB;AAAA,cACA,UAAU,CAACsB,MAAU;AACpB,sBAAM3D,IAAQ4B,EAAQF,EAAO2B,EAAM,GAAG,CAAC;AACvC,gBAAKrD,EAAM,SAAS2D,CAAK,KACxBf,EAASS,EAAM,KAAK,CAAC,GAAGrD,GAAO2D,CAAK,EAAE,KAAK,GAAG,CAAC;AAAA,cAEjD;AAAA,cAEA,UAAA,gBAAA9C;AAAA,gBAACd;AAAA,gBAAA;AAAA,kBACA,UAAUuD;AAAA,kBACV,aAAaD,EAAM,QAAQ;AAAA,kBAC3B,OAAOzB,EAAQF,EAAO2B,EAAM,GAAG,CAAC;AAAA,kBAChC,UAAU,CAACrD,MAAU4C,EAASS,EAAM,KAAKrD,EAAM,KAAK,GAAG,CAAC;AAAA,kBACxD,MACC,gBAAAa,EAAC+C,GAAA,EAAY,OAAOH,EAAO,QAAQ,WAAW,UAAA,8CAAA,CAE9C;AAAA,gBAAA;AAAA,cAAA;AAAA,YAEF;AAAA,UAAA;AAAA,QACD,EAAA,GA1BgBJ,EAAM,GA2BvB;AAAA,MAEF,KAAK;AACJ,eACC,gBAAAxC;AAAA,UAACgD;AAAA,UAAA;AAAA,YAEA,aAAWP;AAAA,YACX,OAAOD,EAAM;AAAA,YACb,OAAO,OAAO3B,EAAO2B,EAAM,GAAG,KAAK,EAAE;AAAA,YACrC,UAAU,CAACS,MAASlB,EAASS,EAAM,KAAKS,CAAI;AAAA,YAC5C,WAAW3B,EAAW;AAAA,YACtB,aAAakB,EAAM,QAAQ;AAAA,YAC3B,WAAAnB;AAAA,YACA,eAAAG;AAAA,UAAA;AAAA,UARKgB,EAAM;AAAA,QAAA;AAAA,MAWd,KAAK;AACJ,iCACEU,IAAA,EACA,UAAA;AAAA,UAAA,gBAAAC,EAACC,IAAA,EACA,UAAA;AAAA,YAAA,gBAAApD,EAAC2C,KAAW,OAAOC,EAAO,QAAQ,SAChC,YAAM,OACR;AAAA,YACCJ,EAAM,QACN,gBAAAxC,EAAC+C,GAAA,EAAY,OAAOH,EAAO,QAAQ,WACjC,UAAAJ,EAAM,KAAA,CACR;AAAA,UAAA,GAEF;AAAA,UACA,gBAAAxC;AAAA,YAACqD;AAAA,YAAA;AAAA,cACA,aAAWZ;AAAA,cACX,OAAO,EAAQ5B,EAAO2B,EAAM,GAAG;AAAA,cAC/B,eAAe,OAAOc,MAASvB,EAASS,EAAM,KAAKc,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QACxD,EAAA,GAfed,EAAM,GAgBtB;AAAA,IAGD;AAEF,UAAMe,IACL,gBAAAvD;AAAA,MAACwD;AAAA,MAAA;AAAA,QACA,aAAWf;AAAA,QACX,SAAQ;AAAA,QACR,WAAWD,EAAM;AAAA,QACjB,eAAa;AAAA,QACb,aAAaA,EAAM,QAAQ;AAAA,QAC3B,OAAO,OAAO3B,EAAO2B,EAAM,GAAG,KAAK,EAAE;AAAA,QACrC,cAAc,CAACS,MAASlB,EAASS,EAAM,KAAKS,CAAI;AAAA,MAAA;AAAA,IAAA;AAKlD,WAAKnB,IAIJ,gBAAA9B;AAAA,MAAC6C;AAAA,MAAA;AAAA,QAEA,eAAArB;AAAA,QACA,UAAU,CAACsB,GAAOW,MAAU;AAC3B,gBAAMC,IAAU,OAAO7C,EAAO2B,EAAM,GAAG,KAAK,EAAE,GACxCmB,IAAKF,KAASC,EAAQ;AAC5B,UAAA3B;AAAA,YACCS,EAAM;AAAA,YACN,GAAGkB,EAAQ,MAAM,GAAGC,CAAE,CAAC,GAAGb,CAAK,GAAGY,EAAQ,MAAMC,CAAE,CAAC;AAAA,UAAA;AAAA,QAErD;AAAA,QAEC,UAAAJ;AAAA,MAAA;AAAA,MAXIf,EAAM;AAAA,IAAA,sBAJJoB,EAAM,UAAN,EAAgC,UAAAL,EAAA,GAAZf,EAAM,GAAiB;AAAA,EAkBrD,GAEMqB,IAAO5E,EAAUiC,CAAO;AAE9B,SACC,gBAAAlB;AAAA,IAAC8D;AAAA,IAAA;AAAA,MACA,QAAQD,EAAK;AAAA,MACb,kBAAkB;AAAA,MAClB,QAAApC;AAAA,MACA,yCACEsC,GAAA,EAAiB,OAAOF,EAAK,OAAO,UAAUA,EAAK,UAAU;AAAA,MAE/D,iBAAiB;AAAA,MACjB,OAAM;AAAA,MACN,aAAaG;AAAA,MACb,WAAWC;AAAA,MACX,SAAA9C;AAAA,MACA,iBAAiB;AAAA,QAChB,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,UAAU,CAACc;AAAA,QACX,WAAWN;AAAA,QACX,SAASQ;AAAA,MAAA;AAAA,MAEV,mBAAmB;AAAA,QAClB,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,SAAShB;AAAA,MAAA;AAAA,MAGT,UAAAU,EAAO,IAAIU,CAAW;AAAA,IAAA;AAAA,EAAA;AAG1B,GAEMxC,IAAiBmE,EAAO;AAAA;AAAA;AAAA;AAAA,GAMxBjE,IAAgBiE,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAMRtB,EAAO,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA,UAIhCA,EAAO,QAAQ,OAAO;AAAA,eACjBA,EAAO,QAAQ,QAAQ;AAAA;AAAA;AAAA;AAAA,WAI3BA,EAAO,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,kBAIjBA,EAAO,OAAO,KAAK;AAAA;AAAA,GAI/BzC,IAAU+D,EAAO;AAAA;AAAA;AAAA;AAAA,GAMjBhB,KAAYgB,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA,GAOnBd,KAAac,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;"}
|