@bikdotai/bik-component-library 0.0.871 → 0.0.872
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 +5 -5
- 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/MentionPicker.js +27 -27
- package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/SelectableListSection.js +6 -6
- package/dist/cjs/components/agent-builder/components/SelectableListSection.js.map +1 -1
- package/dist/cjs/components/agent-builder/constants/tools.js +1 -1
- package/dist/cjs/components/agent-builder/constants/tools.js.map +1 -1
- 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/components/agent-builder/utils/sourceGrouping.js +2 -0
- package/dist/cjs/components/agent-builder/utils/sourceGrouping.js.map +1 -0
- package/dist/cjs/components/agent-builder/utils/sourceIcons.js +1 -1
- package/dist/cjs/components/agent-builder/utils/sourceIcons.js.map +1 -1
- package/dist/cjs/components/agent-builder/utils/toolActions.js +1 -1
- package/dist/cjs/components/agent-builder/utils/toolActions.js.map +1 -1
- package/dist/cjs/icons/Social/Channels/Aftership.js +2 -0
- package/dist/cjs/icons/Social/Channels/Aftership.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/Attentive.js +2 -0
- package/dist/cjs/icons/Social/Channels/Attentive.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/Freshdesk.js +2 -0
- package/dist/cjs/icons/Social/Channels/Freshdesk.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/GoogleSheets.js +2 -0
- package/dist/cjs/icons/Social/Channels/GoogleSheets.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/Klavyio.js +2 -0
- package/dist/cjs/icons/Social/Channels/Klavyio.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/Kustomer.js +2 -0
- package/dist/cjs/icons/Social/Channels/Kustomer.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/Mailchimp.js +2 -0
- package/dist/cjs/icons/Social/Channels/Mailchimp.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/OmniSend.js +2 -0
- package/dist/cjs/icons/Social/Channels/OmniSend.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/Segment.js +2 -0
- package/dist/cjs/icons/Social/Channels/Segment.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/ShipBob.js +2 -0
- package/dist/cjs/icons/Social/Channels/ShipBob.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/Skio.js +1 -1
- package/dist/cjs/icons/Social/Channels/Skio.js.map +1 -1
- package/dist/cjs/icons/index.js +1 -1
- package/dist/esm/components/agent-builder/__fixtures__/integrationCatalog.d.ts +17 -0
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +104 -96
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +256 -242
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionPicker.d.ts +0 -10
- package/dist/esm/components/agent-builder/components/MentionPicker.js +201 -199
- package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/esm/components/agent-builder/components/SelectableListSection.d.ts +9 -0
- package/dist/esm/components/agent-builder/components/SelectableListSection.js +213 -188
- package/dist/esm/components/agent-builder/components/SelectableListSection.js.map +1 -1
- package/dist/esm/components/agent-builder/constants/tools.d.ts +46 -22
- package/dist/esm/components/agent-builder/constants/tools.js +86 -35
- package/dist/esm/components/agent-builder/constants/tools.js.map +1 -1
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +289 -279
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/sourceGrouping.d.ts +39 -0
- package/dist/esm/components/agent-builder/utils/sourceGrouping.js +14 -0
- package/dist/esm/components/agent-builder/utils/sourceGrouping.js.map +1 -0
- package/dist/esm/components/agent-builder/utils/sourceIcons.d.ts +6 -4
- package/dist/esm/components/agent-builder/utils/sourceIcons.js +64 -33
- package/dist/esm/components/agent-builder/utils/sourceIcons.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/toolActions.d.ts +11 -6
- package/dist/esm/components/agent-builder/utils/toolActions.js +23 -16
- package/dist/esm/components/agent-builder/utils/toolActions.js.map +1 -1
- package/dist/esm/icons/Social/Channels/Aftership.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/Aftership.js +47 -0
- package/dist/esm/icons/Social/Channels/Aftership.js.map +1 -0
- package/dist/esm/icons/Social/Channels/Attentive.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/Attentive.js +54 -0
- package/dist/esm/icons/Social/Channels/Attentive.js.map +1 -0
- package/dist/esm/icons/Social/Channels/Freshdesk.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/Freshdesk.js +47 -0
- package/dist/esm/icons/Social/Channels/Freshdesk.js.map +1 -0
- package/dist/esm/icons/Social/Channels/GoogleSheets.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/GoogleSheets.js +53 -0
- package/dist/esm/icons/Social/Channels/GoogleSheets.js.map +1 -0
- package/dist/esm/icons/Social/Channels/Klavyio.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/Klavyio.js +47 -0
- package/dist/esm/icons/Social/Channels/Klavyio.js.map +1 -0
- package/dist/esm/icons/Social/Channels/Kustomer.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/Kustomer.js +68 -0
- package/dist/esm/icons/Social/Channels/Kustomer.js.map +1 -0
- package/dist/esm/icons/Social/Channels/Mailchimp.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/Mailchimp.js +31 -0
- package/dist/esm/icons/Social/Channels/Mailchimp.js.map +1 -0
- package/dist/esm/icons/Social/Channels/OmniSend.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/OmniSend.js +47 -0
- package/dist/esm/icons/Social/Channels/OmniSend.js.map +1 -0
- package/dist/esm/icons/Social/Channels/Segment.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/Segment.js +53 -0
- package/dist/esm/icons/Social/Channels/Segment.js.map +1 -0
- package/dist/esm/icons/Social/Channels/ShipBob.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/ShipBob.js +28 -0
- package/dist/esm/icons/Social/Channels/ShipBob.js.map +1 -0
- package/dist/esm/icons/Social/Channels/Skio.js +41 -19
- package/dist/esm/icons/Social/Channels/Skio.js.map +1 -1
- package/dist/esm/icons/Social/Channels/Zendesk.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/index.d.ts +10 -0
- package/dist/esm/icons/index.d.ts +26 -25
- package/dist/esm/icons/index.js +658 -638
- package/dist/esm/icons/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { jsx as
|
|
1
|
+
import { jsx as o, jsxs as I } from "react/jsx-runtime";
|
|
2
2
|
import L from "../../../assets/icons/cross.svg.js";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { TitleSmall as
|
|
3
|
+
import Y, { useState as E, useRef as w } from "react";
|
|
4
|
+
import T from "styled-components";
|
|
5
|
+
import { TitleSmall as A, BodyCaption as O } from "../../TypographyStyle.js";
|
|
6
6
|
import { COLORS as u } from "../../../constants/Theme.js";
|
|
7
|
-
import { FieldBlock as
|
|
8
|
-
import { AGENT_CHAR_LIMITS as
|
|
9
|
-
import { DRAWER_BODY_STYLE as
|
|
10
|
-
import { ToolInstructionsField as
|
|
11
|
-
import { VariableTriggerArea as
|
|
12
|
-
import { SideModal as
|
|
13
|
-
import { Switch as
|
|
14
|
-
import { Input as
|
|
7
|
+
import { FieldBlock as j } from "../AgentBuilder.styled.js";
|
|
8
|
+
import { AGENT_CHAR_LIMITS as P } from "../constants/charLimits.js";
|
|
9
|
+
import { DRAWER_BODY_STYLE as G, DRAWER_HEADER_STYLE as V, DrawerHeaderText as z } from "./DrawerHeaderText.js";
|
|
10
|
+
import { ToolInstructionsField as M } from "./ToolInstructionsField.js";
|
|
11
|
+
import { VariableTriggerArea as F } from "./VariableTriggerArea.js";
|
|
12
|
+
import { SideModal as q } from "../../side-modal/SideModal.js";
|
|
13
|
+
import { Switch as H } from "../../switch/Switch.js";
|
|
14
|
+
import { Input as W } from "../../input/Input.js";
|
|
15
15
|
import { Tag as N } from "../../tag/Tag.js";
|
|
16
16
|
const J = {
|
|
17
17
|
send_email: {
|
|
@@ -21,53 +21,61 @@ const J = {
|
|
|
21
21
|
send_slack_message: {
|
|
22
22
|
title: "Send Slack message",
|
|
23
23
|
subtitle: "Post a message to a Slack channel. You pick the channel, the AI composes the message from the conversation."
|
|
24
|
+
},
|
|
25
|
+
google_sheet_get_data: {
|
|
26
|
+
title: "Get data from sheet",
|
|
27
|
+
subtitle: "Look up rows in a Google Sheet. You pick the sheet and describe its columns, the AI writes the query it needs."
|
|
28
|
+
},
|
|
29
|
+
google_sheet_add_row: {
|
|
30
|
+
title: "Add row to sheet",
|
|
31
|
+
subtitle: "Append a row to a Google Sheet. You pick the sheet and its columns, the AI fills them in from the conversation."
|
|
24
32
|
}
|
|
25
33
|
}, K = ({
|
|
26
34
|
chips: n,
|
|
27
35
|
onChange: s,
|
|
28
36
|
placeholder: h,
|
|
29
|
-
nativeID:
|
|
30
|
-
hint:
|
|
31
|
-
variablesData:
|
|
37
|
+
nativeID: g,
|
|
38
|
+
hint: _,
|
|
39
|
+
variablesData: C
|
|
32
40
|
}) => {
|
|
33
|
-
const [i,
|
|
34
|
-
const t = i.split(",").map((
|
|
35
|
-
t.length && s([...n, ...t.filter((
|
|
36
|
-
}, f =
|
|
41
|
+
const [i, y] = E(""), [R, a] = E(!1), S = w(null), v = w(null), x = () => {
|
|
42
|
+
const t = i.split(",").map((l) => l.trim()).filter(Boolean);
|
|
43
|
+
t.length && s([...n, ...t.filter((l) => !n.includes(l))]), y("");
|
|
44
|
+
}, f = w(x);
|
|
37
45
|
f.current = x;
|
|
38
|
-
const b =
|
|
39
|
-
return /* @__PURE__ */ I(X, { ref:
|
|
40
|
-
/* @__PURE__ */
|
|
41
|
-
|
|
46
|
+
const b = w(!1), c = w(!1);
|
|
47
|
+
return /* @__PURE__ */ I(X, { ref: S, children: [
|
|
48
|
+
/* @__PURE__ */ o(
|
|
49
|
+
F,
|
|
42
50
|
{
|
|
43
51
|
addDataButton: !0,
|
|
44
|
-
variablesData:
|
|
52
|
+
variablesData: C,
|
|
45
53
|
onOpenChange: (t) => {
|
|
46
54
|
b.current = t, !t && setTimeout(() => {
|
|
47
|
-
!
|
|
55
|
+
!c.current && !S.current?.contains(document.activeElement) && f.current(), c.current = !1;
|
|
48
56
|
}, 0);
|
|
49
57
|
},
|
|
50
|
-
onInsert: (t,
|
|
51
|
-
|
|
52
|
-
const k =
|
|
53
|
-
|
|
54
|
-
const p =
|
|
58
|
+
onInsert: (t, l) => {
|
|
59
|
+
c.current = !0;
|
|
60
|
+
const k = l ?? i.length;
|
|
61
|
+
y(`${i.slice(0, k)}${t}${i.slice(k)}`), requestAnimationFrame(() => {
|
|
62
|
+
const p = v.current;
|
|
55
63
|
p?.focus(), p?.setSelectionRange(k + t.length, k + t.length);
|
|
56
64
|
});
|
|
57
65
|
},
|
|
58
|
-
children: /* @__PURE__ */
|
|
66
|
+
children: /* @__PURE__ */ o(
|
|
59
67
|
Z,
|
|
60
68
|
{
|
|
61
|
-
id:
|
|
62
|
-
ref:
|
|
69
|
+
id: g,
|
|
70
|
+
ref: v,
|
|
63
71
|
type: "text",
|
|
64
|
-
placeholder:
|
|
72
|
+
placeholder: R && i === "" && (C?.length ?? 0) > 0 ? "Enter text, type @ to add variable" : h,
|
|
65
73
|
value: i,
|
|
66
|
-
onChange: (t) =>
|
|
74
|
+
onChange: (t) => y(t.target.value),
|
|
67
75
|
onFocus: () => a(!0),
|
|
68
76
|
onBlur: () => {
|
|
69
77
|
a(!1), setTimeout(() => {
|
|
70
|
-
!b.current && !
|
|
78
|
+
!b.current && !S.current?.contains(document.activeElement) && f.current();
|
|
71
79
|
}, 0);
|
|
72
80
|
},
|
|
73
81
|
onKeyDown: (t) => {
|
|
@@ -77,8 +85,8 @@ const J = {
|
|
|
77
85
|
)
|
|
78
86
|
}
|
|
79
87
|
),
|
|
80
|
-
|
|
81
|
-
n.length > 0 && /* @__PURE__ */
|
|
88
|
+
_,
|
|
89
|
+
n.length > 0 && /* @__PURE__ */ o(ee, { children: n.map((t, l) => /* @__PURE__ */ o(
|
|
82
90
|
N,
|
|
83
91
|
{
|
|
84
92
|
tagText: t.replace(/\{\{variable:([^}]+)\}\}/g, "{{$1}}"),
|
|
@@ -86,41 +94,41 @@ const J = {
|
|
|
86
94
|
type: "neutral",
|
|
87
95
|
variant: "regular",
|
|
88
96
|
TrailingIcon: L,
|
|
89
|
-
onTrailingIconClicked: () => s(n.filter((k, p) => p !==
|
|
97
|
+
onTrailingIconClicked: () => s(n.filter((k, p) => p !== l))
|
|
90
98
|
},
|
|
91
|
-
`${t}-${
|
|
99
|
+
`${t}-${l}`
|
|
92
100
|
)) })
|
|
93
101
|
] });
|
|
94
102
|
}, Q = (n, s) => {
|
|
95
103
|
const h = {};
|
|
96
|
-
return Object.keys(n).forEach((
|
|
97
|
-
h[
|
|
104
|
+
return Object.keys(n).forEach((g) => {
|
|
105
|
+
h[g] = s?.params[g]?.value ?? n[g].value;
|
|
98
106
|
}), h;
|
|
99
107
|
}, U = (n) => String(n ?? "").split(",").map((s) => s.trim()).filter(Boolean), ke = ({
|
|
100
108
|
toolKey: n,
|
|
101
109
|
template: s,
|
|
102
110
|
onClose: h,
|
|
103
|
-
onSave:
|
|
104
|
-
initial:
|
|
105
|
-
onImprove:
|
|
106
|
-
charLimits: i =
|
|
107
|
-
variablesData:
|
|
108
|
-
zIndex:
|
|
111
|
+
onSave: g,
|
|
112
|
+
initial: _,
|
|
113
|
+
onImprove: C,
|
|
114
|
+
charLimits: i = P,
|
|
115
|
+
variablesData: y,
|
|
116
|
+
zIndex: R
|
|
109
117
|
}) => {
|
|
110
|
-
const [a,
|
|
111
|
-
() => Q(s,
|
|
112
|
-
), [
|
|
113
|
-
if (!t ||
|
|
118
|
+
const [a, S] = E(
|
|
119
|
+
() => Q(s, _)
|
|
120
|
+
), [v, x] = E(!1), f = Object.values(s), b = n === "send_email", c = (e, m) => S((d) => ({ ...d, [e]: m })), t = f.every((e) => !(e.required && String(a[e.key] ?? "").trim() === "" || e.component === "MultilineInput" && String(a[e.key] ?? "").length > i.instructions)), l = async () => {
|
|
121
|
+
if (!t || v)
|
|
114
122
|
return;
|
|
115
123
|
const e = {};
|
|
116
|
-
f.forEach((
|
|
117
|
-
e[
|
|
124
|
+
f.forEach((r) => {
|
|
125
|
+
e[r.key] = { ...r, value: a[r.key] };
|
|
118
126
|
});
|
|
119
127
|
const m = {
|
|
120
|
-
id:
|
|
128
|
+
id: _?.id ?? `${n}_${Date.now().toString(36)}`,
|
|
121
129
|
tool_key: n,
|
|
122
130
|
params: e
|
|
123
|
-
}, d =
|
|
131
|
+
}, d = g(m);
|
|
124
132
|
if (d && typeof d.then == "function") {
|
|
125
133
|
x(!0);
|
|
126
134
|
try {
|
|
@@ -137,53 +145,53 @@ const J = {
|
|
|
137
145
|
case "KeywordInput":
|
|
138
146
|
if (!b)
|
|
139
147
|
break;
|
|
140
|
-
return /* @__PURE__ */ I(
|
|
141
|
-
/* @__PURE__ */
|
|
142
|
-
/* @__PURE__ */
|
|
148
|
+
return /* @__PURE__ */ I(j, { children: [
|
|
149
|
+
/* @__PURE__ */ o(A, { color: u.content.primary, children: e.title }),
|
|
150
|
+
/* @__PURE__ */ o(
|
|
143
151
|
K,
|
|
144
152
|
{
|
|
145
153
|
nativeID: m,
|
|
146
154
|
placeholder: e.hint ?? "",
|
|
147
155
|
chips: U(a[e.key]),
|
|
148
|
-
onChange: (
|
|
149
|
-
variablesData:
|
|
150
|
-
hint: /* @__PURE__ */
|
|
156
|
+
onChange: (r) => c(e.key, r.join(",")),
|
|
157
|
+
variablesData: y,
|
|
158
|
+
hint: /* @__PURE__ */ o(O, { color: u.content.secondary, children: "Press Enter or comma to add multiple emails" })
|
|
151
159
|
}
|
|
152
160
|
)
|
|
153
161
|
] }, e.key);
|
|
154
162
|
case "MultilineInput":
|
|
155
|
-
return /* @__PURE__ */
|
|
156
|
-
|
|
163
|
+
return /* @__PURE__ */ o(
|
|
164
|
+
M,
|
|
157
165
|
{
|
|
158
166
|
"data-test": m,
|
|
159
167
|
label: e.title,
|
|
160
168
|
value: String(a[e.key] ?? ""),
|
|
161
|
-
onChange: (
|
|
169
|
+
onChange: (r) => c(e.key, r),
|
|
162
170
|
maxLength: i.instructions,
|
|
163
171
|
placeholder: e.hint ?? "",
|
|
164
|
-
onImprove:
|
|
165
|
-
variablesData:
|
|
172
|
+
onImprove: C,
|
|
173
|
+
variablesData: y
|
|
166
174
|
},
|
|
167
175
|
e.key
|
|
168
176
|
);
|
|
169
177
|
case "Switch":
|
|
170
178
|
return /* @__PURE__ */ I(te, { children: [
|
|
171
179
|
/* @__PURE__ */ I(ne, { children: [
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
-
e.hint && /* @__PURE__ */
|
|
180
|
+
/* @__PURE__ */ o(A, { color: u.content.primary, children: e.title }),
|
|
181
|
+
e.hint && /* @__PURE__ */ o(O, { color: u.content.secondary, children: e.hint })
|
|
174
182
|
] }),
|
|
175
|
-
/* @__PURE__ */
|
|
176
|
-
|
|
183
|
+
/* @__PURE__ */ o(
|
|
184
|
+
H,
|
|
177
185
|
{
|
|
178
186
|
"data-test": m,
|
|
179
187
|
value: !!a[e.key],
|
|
180
|
-
onValueChange: async (
|
|
188
|
+
onValueChange: async (r) => c(e.key, r)
|
|
181
189
|
}
|
|
182
190
|
)
|
|
183
191
|
] }, e.key);
|
|
184
192
|
}
|
|
185
|
-
const d = /* @__PURE__ */
|
|
186
|
-
|
|
193
|
+
const d = /* @__PURE__ */ o(
|
|
194
|
+
W,
|
|
187
195
|
{
|
|
188
196
|
"data-test": m,
|
|
189
197
|
variant: "small",
|
|
@@ -191,37 +199,37 @@ const J = {
|
|
|
191
199
|
labelTextBold: !0,
|
|
192
200
|
placeholder: e.hint ?? "",
|
|
193
201
|
value: String(a[e.key] ?? ""),
|
|
194
|
-
onChangeText: (
|
|
202
|
+
onChangeText: (r) => c(e.key, r)
|
|
195
203
|
}
|
|
196
204
|
);
|
|
197
|
-
return b ? /* @__PURE__ */
|
|
198
|
-
|
|
205
|
+
return b ? /* @__PURE__ */ o(
|
|
206
|
+
F,
|
|
199
207
|
{
|
|
200
208
|
addDataButton: !0,
|
|
201
|
-
variablesData:
|
|
202
|
-
onInsert: (
|
|
203
|
-
const
|
|
204
|
-
|
|
209
|
+
variablesData: y,
|
|
210
|
+
onInsert: (r, D) => {
|
|
211
|
+
const $ = String(a[e.key] ?? ""), B = D ?? $.length;
|
|
212
|
+
c(
|
|
205
213
|
e.key,
|
|
206
|
-
`${
|
|
214
|
+
`${$.slice(0, B)}${r}${$.slice(B)}`
|
|
207
215
|
);
|
|
208
216
|
},
|
|
209
217
|
children: d
|
|
210
218
|
},
|
|
211
219
|
e.key
|
|
212
|
-
) : /* @__PURE__ */
|
|
220
|
+
) : /* @__PURE__ */ o(Y.Fragment, { children: d }, e.key);
|
|
213
221
|
}, p = J[n];
|
|
214
|
-
return /* @__PURE__ */
|
|
215
|
-
|
|
222
|
+
return /* @__PURE__ */ o(
|
|
223
|
+
q,
|
|
216
224
|
{
|
|
217
225
|
header: p.title,
|
|
218
226
|
closeOnEscapeKey: !1,
|
|
219
|
-
zIndex:
|
|
220
|
-
headerCustomComponent: /* @__PURE__ */
|
|
227
|
+
zIndex: R,
|
|
228
|
+
headerCustomComponent: /* @__PURE__ */ o(z, { title: p.title, subtitle: p.subtitle }),
|
|
221
229
|
hideCrossButton: !1,
|
|
222
230
|
width: "431px",
|
|
223
|
-
headerStyle:
|
|
224
|
-
bodyStyle:
|
|
231
|
+
headerStyle: V,
|
|
232
|
+
bodyStyle: G,
|
|
225
233
|
onClose: h,
|
|
226
234
|
saveButtonProps: {
|
|
227
235
|
"data-test": "config-tool-save",
|
|
@@ -229,8 +237,8 @@ const J = {
|
|
|
229
237
|
buttonType: "primary",
|
|
230
238
|
size: "small",
|
|
231
239
|
disabled: !t,
|
|
232
|
-
isLoading:
|
|
233
|
-
onClick:
|
|
240
|
+
isLoading: v,
|
|
241
|
+
onClick: l
|
|
234
242
|
},
|
|
235
243
|
cancelButtonProps: {
|
|
236
244
|
"data-test": "config-tool-cancel",
|
|
@@ -242,11 +250,11 @@ const J = {
|
|
|
242
250
|
children: f.map(k)
|
|
243
251
|
}
|
|
244
252
|
);
|
|
245
|
-
}, X =
|
|
253
|
+
}, X = T.div`
|
|
246
254
|
display: flex;
|
|
247
255
|
flex-direction: column;
|
|
248
256
|
gap: 8px;
|
|
249
|
-
`, Z =
|
|
257
|
+
`, Z = T.input`
|
|
250
258
|
width: 100%;
|
|
251
259
|
min-width: 0;
|
|
252
260
|
box-sizing: border-box;
|
|
@@ -267,16 +275,16 @@ const J = {
|
|
|
267
275
|
&:focus {
|
|
268
276
|
border-color: ${u.stroke.brand};
|
|
269
277
|
}
|
|
270
|
-
`, ee =
|
|
278
|
+
`, ee = T.div`
|
|
271
279
|
display: flex;
|
|
272
280
|
flex-wrap: wrap;
|
|
273
281
|
gap: 6px;
|
|
274
|
-
`, te =
|
|
282
|
+
`, te = T.div`
|
|
275
283
|
display: flex;
|
|
276
284
|
align-items: center;
|
|
277
285
|
justify-content: space-between;
|
|
278
286
|
gap: 12px;
|
|
279
|
-
`, ne =
|
|
287
|
+
`, ne = T.div`
|
|
280
288
|
display: flex;
|
|
281
289
|
flex-direction: column;
|
|
282
290
|
gap: 4px;
|
|
@@ -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, { useRef, 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\t/**\n\t * Variable catalog for the `@` trigger. A picked variable is interpolated\n\t * into the entry TEXT at the caret (so values can mix text and variables,\n\t * e.g. `ops-{{variable:store_name}}@acme.com`) — it becomes a chip on\n\t * Enter / comma like any typed value.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\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\tvariablesData,\n}) => {\n\tconst [buffer, setBuffer] = useState('');\n\tconst [entryFocused, setEntryFocused] = useState(false);\n\tconst wrapRef = useRef<HTMLDivElement>(null);\n\tconst inputRef = useRef<HTMLInputElement>(null);\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\t// The blur handler defers via setTimeout — read the LATEST commit (with the\n\t// current buffer), not the one captured when the blur fired.\n\tconst commitRef = useRef(commit);\n\tcommitRef.current = commit;\n\t// While the variable panel is open, focus bounces through it (search box,\n\t// rows) — blur must not commit the half-composed entry.\n\tconst panelOpenRef = useRef(false);\n\t// A variable was just picked — the panel-close commit below must not fire\n\t// (onInsert refocuses the entry, so its eventual blur commits instead).\n\tconst insertedRef = useRef(false);\n\n\treturn (\n\t\t<ChipsFieldWrap ref={wrapRef}>\n\t\t\t<VariableTriggerArea\n\t\t\t\taddDataButton\n\t\t\t\tvariablesData={variablesData}\n\t\t\t\tonOpenChange={(open) => {\n\t\t\t\t\tpanelOpenRef.current = open;\n\t\t\t\t\tif (open) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// Panel closed (Escape / outside click / pick). If the entry's\n\t\t\t\t\t// blur-commit was skipped while the panel was open and focus is\n\t\t\t\t\t// not coming back, the half-typed entry would be silently lost\n\t\t\t\t\t// on save — commit it now.\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!insertedRef.current &&\n\t\t\t\t\t\t\t!wrapRef.current?.contains(document.activeElement)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tcommitRef.current();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tinsertedRef.current = false;\n\t\t\t\t\t}, 0);\n\t\t\t\t}}\n\t\t\t\tonInsert={(token, caret) => {\n\t\t\t\t\tinsertedRef.current = true;\n\t\t\t\t\tconst at = caret ?? buffer.length;\n\t\t\t\t\tsetBuffer(`${buffer.slice(0, at)}${token}${buffer.slice(at)}`);\n\t\t\t\t\t// Put the caret after the inserted token so typing continues\n\t\t\t\t\t// naturally (e.g. `{{variable:store_name}}|@acme.com`).\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tconst el = inputRef.current;\n\t\t\t\t\t\tel?.focus();\n\t\t\t\t\t\tel?.setSelectionRange(at + token.length, at + token.length);\n\t\t\t\t\t});\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<EmailInputBox\n\t\t\t\t\tid={nativeID}\n\t\t\t\t\tref={inputRef}\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t// Focused + empty → the @ hint (only when a catalog makes @ do\n\t\t\t\t\t// anything); otherwise the field's own text.\n\t\t\t\t\tplaceholder={\n\t\t\t\t\t\tentryFocused && buffer === '' && (variablesData?.length ?? 0) > 0\n\t\t\t\t\t\t\t? 'Enter text, type @ to add variable'\n\t\t\t\t\t\t\t: placeholder\n\t\t\t\t\t}\n\t\t\t\t\tvalue={buffer}\n\t\t\t\t\tonChange={(e) => setBuffer(e.target.value)}\n\t\t\t\t\tonFocus={() => setEntryFocused(true)}\n\t\t\t\t\tonBlur={() => {\n\t\t\t\t\t\tsetEntryFocused(false);\n\t\t\t\t\t\t// Focus moving into the variable panel / pill is not \"leaving\n\t\t\t\t\t\t// the field\" — committing then would chip a half-composed value.\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!panelOpenRef.current &&\n\t\t\t\t\t\t\t\t!wrapRef.current?.contains(document.activeElement)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcommitRef.current();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 0);\n\t\t\t\t\t}}\n\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\tif (e.key === 'Enter' || e.key === ',') {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tcommit();\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\te.key === 'Backspace' &&\n\t\t\t\t\t\t\tbuffer === '' &&\n\t\t\t\t\t\t\tchips.length > 0\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tonChange(chips.slice(0, -1));\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</VariableTriggerArea>\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\t// Variable tokens display as the short {{name}} (values can mix\n\t\t\t\t\t\t\t// text and tokens); the stored value keeps {{variable:<name>}}.\n\t\t\t\t\t\t\ttagText={email.replace(/\\{\\{variable:([^}]+)\\}\\}/g, '{{$1}}')}\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((f) => {\n\t\tif (f.required && String(values[f.key] ?? '').trim() === '') {\n\t\t\treturn false;\n\t\t}\n\t\t// MultilineInput renders the soft-limit editor (a paste may exceed the\n\t\t// cap, rendered grey) — gate the save so over-limit text can't persist.\n\t\tif (\n\t\t\tf.component === 'MultilineInput' &&\n\t\t\tString(values[f.key] ?? '').length > charLimits.instructions\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\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 a word boundary (or the \"+ Add data\" pill) interpolates\n\t\t\t\t\t\t a variable into the entry TEXT at the caret — mixed values like\n\t\t\t\t\t\t ops-{{variable:store_name}}@acme.com chip on Enter / comma. */}\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\tvariablesData={variablesData}\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\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\taddDataButton\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","variablesData","buffer","setBuffer","useState","entryFocused","setEntryFocused","wrapRef","useRef","inputRef","commit","parts","s","p","commitRef","panelOpenRef","insertedRef","jsxs","ChipsFieldWrap","jsx","VariableTriggerArea","open","token","caret","at","el","EmailInputBox","e","ChipRow","email","i","Tag","CrossIcon","_","idx","seedValues","template","initial","values","key","toChips","value","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","SwitchText","Switch","next","plainInput","Input","current","React","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, { useRef, 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\tgoogle_sheet_get_data: {\n\t\ttitle: 'Get data from sheet',\n\t\tsubtitle:\n\t\t\t'Look up rows in a Google Sheet. You pick the sheet and describe its columns, the AI writes the query it needs.',\n\t},\n\tgoogle_sheet_add_row: {\n\t\ttitle: 'Add row to sheet',\n\t\tsubtitle:\n\t\t\t'Append a row to a Google Sheet. You pick the sheet and its columns, the AI fills them in 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\t/**\n\t * Variable catalog for the `@` trigger. A picked variable is interpolated\n\t * into the entry TEXT at the caret (so values can mix text and variables,\n\t * e.g. `ops-{{variable:store_name}}@acme.com`) — it becomes a chip on\n\t * Enter / comma like any typed value.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\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\tvariablesData,\n}) => {\n\tconst [buffer, setBuffer] = useState('');\n\tconst [entryFocused, setEntryFocused] = useState(false);\n\tconst wrapRef = useRef<HTMLDivElement>(null);\n\tconst inputRef = useRef<HTMLInputElement>(null);\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\t// The blur handler defers via setTimeout — read the LATEST commit (with the\n\t// current buffer), not the one captured when the blur fired.\n\tconst commitRef = useRef(commit);\n\tcommitRef.current = commit;\n\t// While the variable panel is open, focus bounces through it (search box,\n\t// rows) — blur must not commit the half-composed entry.\n\tconst panelOpenRef = useRef(false);\n\t// A variable was just picked — the panel-close commit below must not fire\n\t// (onInsert refocuses the entry, so its eventual blur commits instead).\n\tconst insertedRef = useRef(false);\n\n\treturn (\n\t\t<ChipsFieldWrap ref={wrapRef}>\n\t\t\t<VariableTriggerArea\n\t\t\t\taddDataButton\n\t\t\t\tvariablesData={variablesData}\n\t\t\t\tonOpenChange={(open) => {\n\t\t\t\t\tpanelOpenRef.current = open;\n\t\t\t\t\tif (open) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// Panel closed (Escape / outside click / pick). If the entry's\n\t\t\t\t\t// blur-commit was skipped while the panel was open and focus is\n\t\t\t\t\t// not coming back, the half-typed entry would be silently lost\n\t\t\t\t\t// on save — commit it now.\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!insertedRef.current &&\n\t\t\t\t\t\t\t!wrapRef.current?.contains(document.activeElement)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tcommitRef.current();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tinsertedRef.current = false;\n\t\t\t\t\t}, 0);\n\t\t\t\t}}\n\t\t\t\tonInsert={(token, caret) => {\n\t\t\t\t\tinsertedRef.current = true;\n\t\t\t\t\tconst at = caret ?? buffer.length;\n\t\t\t\t\tsetBuffer(`${buffer.slice(0, at)}${token}${buffer.slice(at)}`);\n\t\t\t\t\t// Put the caret after the inserted token so typing continues\n\t\t\t\t\t// naturally (e.g. `{{variable:store_name}}|@acme.com`).\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tconst el = inputRef.current;\n\t\t\t\t\t\tel?.focus();\n\t\t\t\t\t\tel?.setSelectionRange(at + token.length, at + token.length);\n\t\t\t\t\t});\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<EmailInputBox\n\t\t\t\t\tid={nativeID}\n\t\t\t\t\tref={inputRef}\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t// Focused + empty → the @ hint (only when a catalog makes @ do\n\t\t\t\t\t// anything); otherwise the field's own text.\n\t\t\t\t\tplaceholder={\n\t\t\t\t\t\tentryFocused && buffer === '' && (variablesData?.length ?? 0) > 0\n\t\t\t\t\t\t\t? 'Enter text, type @ to add variable'\n\t\t\t\t\t\t\t: placeholder\n\t\t\t\t\t}\n\t\t\t\t\tvalue={buffer}\n\t\t\t\t\tonChange={(e) => setBuffer(e.target.value)}\n\t\t\t\t\tonFocus={() => setEntryFocused(true)}\n\t\t\t\t\tonBlur={() => {\n\t\t\t\t\t\tsetEntryFocused(false);\n\t\t\t\t\t\t// Focus moving into the variable panel / pill is not \"leaving\n\t\t\t\t\t\t// the field\" — committing then would chip a half-composed value.\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!panelOpenRef.current &&\n\t\t\t\t\t\t\t\t!wrapRef.current?.contains(document.activeElement)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcommitRef.current();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 0);\n\t\t\t\t\t}}\n\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\tif (e.key === 'Enter' || e.key === ',') {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tcommit();\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\te.key === 'Backspace' &&\n\t\t\t\t\t\t\tbuffer === '' &&\n\t\t\t\t\t\t\tchips.length > 0\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tonChange(chips.slice(0, -1));\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</VariableTriggerArea>\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\t// Variable tokens display as the short {{name}} (values can mix\n\t\t\t\t\t\t\t// text and tokens); the stored value keeps {{variable:<name>}}.\n\t\t\t\t\t\t\ttagText={email.replace(/\\{\\{variable:([^}]+)\\}\\}/g, '{{$1}}')}\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((f) => {\n\t\tif (f.required && String(values[f.key] ?? '').trim() === '') {\n\t\t\treturn false;\n\t\t}\n\t\t// MultilineInput renders the soft-limit editor (a paste may exceed the\n\t\t// cap, rendered grey) — gate the save so over-limit text can't persist.\n\t\tif (\n\t\t\tf.component === 'MultilineInput' &&\n\t\t\tString(values[f.key] ?? '').length > charLimits.instructions\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\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 a word boundary (or the \"+ Add data\" pill) interpolates\n\t\t\t\t\t\t a variable into the entry TEXT at the caret — mixed values like\n\t\t\t\t\t\t ops-{{variable:store_name}}@acme.com chip on Enter / comma. */}\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\tvariablesData={variablesData}\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\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\taddDataButton\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","variablesData","buffer","setBuffer","useState","entryFocused","setEntryFocused","wrapRef","useRef","inputRef","commit","parts","s","p","commitRef","panelOpenRef","insertedRef","jsxs","ChipsFieldWrap","jsx","VariableTriggerArea","open","token","caret","at","el","EmailInputBox","e","ChipRow","email","i","Tag","CrossIcon","_","idx","seedValues","template","initial","values","key","toChips","value","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","SwitchText","Switch","next","plainInput","Input","current","React","copy","SideModal","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","styled"],"mappings":"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"}
|