@bikdotai/bik-component-library 0.0.849-beta.4 → 0.0.849-beta.6
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/AddDataPill.js +10 -0
- package/dist/cjs/components/agent-builder/components/AddDataPill.js.map +1 -0
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js +10 -10
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +2 -2
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionEditor.js +1 -1
- package/dist/cjs/components/agent-builder/components/MentionEditor.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionField.js +1 -1
- package/dist/cjs/components/agent-builder/components/MentionField.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionPicker.js +49 -25
- package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js +9 -8
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +1 -1
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/VariableInlineField.js +56 -0
- package/dist/cjs/components/agent-builder/components/VariableInlineField.js.map +1 -0
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js +6 -5
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js.map +1 -1
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.js +4 -4
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.js.map +1 -1
- package/dist/cjs/editor/BikEditor.js +1 -1
- package/dist/cjs/editor/BikEditor.js.map +1 -1
- package/dist/cjs/editor/BikEditor.styles.js +5 -3
- package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
- package/dist/cjs/editor/BikEditor.types.js.map +1 -1
- package/dist/esm/components/agent-builder/components/AddDataPill.d.ts +18 -0
- package/dist/esm/components/agent-builder/components/AddDataPill.js +32 -0
- package/dist/esm/components/agent-builder/components/AddDataPill.js.map +1 -0
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +165 -148
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +15 -13
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionEditor.d.ts +7 -2
- package/dist/esm/components/agent-builder/components/MentionEditor.js +119 -102
- package/dist/esm/components/agent-builder/components/MentionEditor.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionField.js +30 -29
- package/dist/esm/components/agent-builder/components/MentionField.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionPicker.js +199 -165
- package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.d.ts +3 -2
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +160 -193
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +20 -19
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/esm/components/agent-builder/components/VariableInlineField.d.ts +26 -0
- package/dist/esm/components/agent-builder/components/VariableInlineField.js +142 -0
- package/dist/esm/components/agent-builder/components/VariableInlineField.js.map +1 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.d.ts +19 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js +113 -72
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js +26 -20
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js.map +1 -1
- package/dist/esm/editor/BikEditor.js +24 -18
- package/dist/esm/editor/BikEditor.js.map +1 -1
- package/dist/esm/editor/BikEditor.styles.js +5 -3
- package/dist/esm/editor/BikEditor.styles.js.map +1 -1
- package/dist/esm/editor/BikEditor.types.d.ts +9 -0
- package/dist/esm/editor/BikEditor.types.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { jsx as o, jsxs as
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { TitleSmall as
|
|
6
|
-
import { COLORS as
|
|
1
|
+
import { jsx as o, jsxs as w } from "react/jsx-runtime";
|
|
2
|
+
import F from "../../../assets/icons/cross.svg.js";
|
|
3
|
+
import j, { useState as $, useRef as T } from "react";
|
|
4
|
+
import v from "styled-components";
|
|
5
|
+
import { TitleSmall as R, BodyCaption as _ } from "../../TypographyStyle.js";
|
|
6
|
+
import { COLORS as c } from "../../../constants/Theme.js";
|
|
7
7
|
import { FieldBlock as P } from "../AgentBuilder.styled.js";
|
|
8
8
|
import { AGENT_CHAR_LIMITS as Y } from "../constants/charLimits.js";
|
|
9
9
|
import { DRAWER_BODY_STYLE as V, DRAWER_HEADER_STYLE as z, DrawerHeaderText as H } from "./DrawerHeaderText.js";
|
|
10
10
|
import { ToolInstructionsField as M } from "./ToolInstructionsField.js";
|
|
11
11
|
import { VariableTriggerArea as O } from "./VariableTriggerArea.js";
|
|
12
12
|
import { SideModal as W } from "../../side-modal/SideModal.js";
|
|
13
|
-
import { Switch as
|
|
14
|
-
import { Input as
|
|
15
|
-
import { Tag as
|
|
13
|
+
import { Switch as q } from "../../switch/Switch.js";
|
|
14
|
+
import { Input as G } from "../../input/Input.js";
|
|
15
|
+
import { Tag as N } from "../../tag/Tag.js";
|
|
16
16
|
const J = {
|
|
17
17
|
send_email: {
|
|
18
18
|
title: "Send Email",
|
|
@@ -23,247 +23,264 @@ const J = {
|
|
|
23
23
|
subtitle: "Post a message to a Slack channel. You pick the channel, the AI composes the message from the conversation."
|
|
24
24
|
}
|
|
25
25
|
}, K = ({
|
|
26
|
-
chips:
|
|
27
|
-
onChange:
|
|
28
|
-
placeholder:
|
|
29
|
-
nativeID:
|
|
30
|
-
hint:
|
|
26
|
+
chips: n,
|
|
27
|
+
onChange: s,
|
|
28
|
+
placeholder: d,
|
|
29
|
+
nativeID: h,
|
|
30
|
+
hint: S,
|
|
31
|
+
variablesData: C
|
|
31
32
|
}) => {
|
|
32
|
-
const [
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
};
|
|
36
|
-
|
|
33
|
+
const [u, y] = $(""), b = T(null), l = T(null), f = () => {
|
|
34
|
+
const t = u.split(",").map((a) => a.trim()).filter(Boolean);
|
|
35
|
+
t.length && s([...n, ...t.filter((a) => !n.includes(a))]), y("");
|
|
36
|
+
}, k = T(f);
|
|
37
|
+
k.current = f;
|
|
38
|
+
const x = T(!1);
|
|
39
|
+
return /* @__PURE__ */ w(X, { ref: b, children: [
|
|
37
40
|
/* @__PURE__ */ o(
|
|
38
|
-
|
|
41
|
+
O,
|
|
39
42
|
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
addDataButton: !0,
|
|
44
|
+
variablesData: C,
|
|
45
|
+
onOpenChange: (t) => {
|
|
46
|
+
x.current = t;
|
|
47
|
+
},
|
|
48
|
+
onInsert: (t, a) => {
|
|
49
|
+
const i = a ?? u.length;
|
|
50
|
+
y(`${u.slice(0, i)}${t}${u.slice(i)}`), requestAnimationFrame(() => {
|
|
51
|
+
const g = l.current;
|
|
52
|
+
g?.focus(), g?.setSelectionRange(i + t.length, i + t.length);
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
children: /* @__PURE__ */ o(
|
|
56
|
+
Z,
|
|
57
|
+
{
|
|
58
|
+
id: h,
|
|
59
|
+
ref: l,
|
|
60
|
+
type: "text",
|
|
61
|
+
placeholder: d,
|
|
62
|
+
value: u,
|
|
63
|
+
onChange: (t) => y(t.target.value),
|
|
64
|
+
onBlur: () => {
|
|
65
|
+
setTimeout(() => {
|
|
66
|
+
!x.current && !b.current?.contains(document.activeElement) && k.current();
|
|
67
|
+
}, 0);
|
|
68
|
+
},
|
|
69
|
+
onKeyDown: (t) => {
|
|
70
|
+
t.key === "Enter" || t.key === "," ? (t.preventDefault(), f()) : t.key === "Backspace" && u === "" && n.length > 0 && s(n.slice(0, -1));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
)
|
|
49
74
|
}
|
|
50
75
|
),
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
76
|
+
S,
|
|
77
|
+
n.length > 0 && /* @__PURE__ */ o(ee, { children: n.map((t, a) => /* @__PURE__ */ o(
|
|
78
|
+
N,
|
|
54
79
|
{
|
|
55
|
-
tagText:
|
|
80
|
+
tagText: t.replace(/\{\{variable:([^}]+)\}\}/g, "{{$1}}"),
|
|
56
81
|
theme: "light",
|
|
57
82
|
type: "neutral",
|
|
58
83
|
variant: "regular",
|
|
59
|
-
TrailingIcon:
|
|
60
|
-
onTrailingIconClicked: () =>
|
|
84
|
+
TrailingIcon: F,
|
|
85
|
+
onTrailingIconClicked: () => s(n.filter((i, g) => g !== a))
|
|
61
86
|
},
|
|
62
|
-
`${
|
|
87
|
+
`${t}-${a}`
|
|
63
88
|
)) })
|
|
64
89
|
] });
|
|
65
|
-
}, Q = (
|
|
66
|
-
const
|
|
67
|
-
return Object.keys(
|
|
68
|
-
|
|
69
|
-
}),
|
|
70
|
-
},
|
|
71
|
-
toolKey:
|
|
72
|
-
template:
|
|
73
|
-
onClose:
|
|
74
|
-
onSave:
|
|
75
|
-
initial:
|
|
76
|
-
onImprove:
|
|
77
|
-
charLimits:
|
|
78
|
-
variablesData:
|
|
79
|
-
zIndex:
|
|
90
|
+
}, Q = (n, s) => {
|
|
91
|
+
const d = {};
|
|
92
|
+
return Object.keys(n).forEach((h) => {
|
|
93
|
+
d[h] = s?.params[h]?.value ?? n[h].value;
|
|
94
|
+
}), d;
|
|
95
|
+
}, U = (n) => String(n ?? "").split(",").map((s) => s.trim()).filter(Boolean), ke = ({
|
|
96
|
+
toolKey: n,
|
|
97
|
+
template: s,
|
|
98
|
+
onClose: d,
|
|
99
|
+
onSave: h,
|
|
100
|
+
initial: S,
|
|
101
|
+
onImprove: C,
|
|
102
|
+
charLimits: u = Y,
|
|
103
|
+
variablesData: y,
|
|
104
|
+
zIndex: b
|
|
80
105
|
}) => {
|
|
81
|
-
const [
|
|
82
|
-
() => Q(
|
|
83
|
-
), [
|
|
84
|
-
(
|
|
85
|
-
),
|
|
86
|
-
if (!
|
|
106
|
+
const [l, f] = $(
|
|
107
|
+
() => Q(s, S)
|
|
108
|
+
), [k, x] = $(!1), t = Object.values(s), a = n === "send_email", i = (e, p) => f((m) => ({ ...m, [e]: p })), g = t.every(
|
|
109
|
+
(e) => !e.required || String(l[e.key] ?? "").trim() !== ""
|
|
110
|
+
), A = async () => {
|
|
111
|
+
if (!g || k)
|
|
87
112
|
return;
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
113
|
+
const e = {};
|
|
114
|
+
t.forEach((r) => {
|
|
115
|
+
e[r.key] = { ...r, value: l[r.key] };
|
|
91
116
|
});
|
|
92
|
-
const
|
|
93
|
-
id:
|
|
94
|
-
tool_key:
|
|
95
|
-
params:
|
|
96
|
-
},
|
|
97
|
-
if (
|
|
98
|
-
|
|
117
|
+
const p = {
|
|
118
|
+
id: S?.id ?? `${n}_${Date.now().toString(36)}`,
|
|
119
|
+
tool_key: n,
|
|
120
|
+
params: e
|
|
121
|
+
}, m = h(p);
|
|
122
|
+
if (m && typeof m.then == "function") {
|
|
123
|
+
x(!0);
|
|
99
124
|
try {
|
|
100
|
-
await
|
|
125
|
+
await m;
|
|
101
126
|
} finally {
|
|
102
|
-
|
|
127
|
+
x(!1);
|
|
103
128
|
}
|
|
104
129
|
}
|
|
105
|
-
},
|
|
106
|
-
const
|
|
107
|
-
switch (
|
|
130
|
+
}, D = (e) => {
|
|
131
|
+
const p = `config-tool-${e.key.toLowerCase()}`;
|
|
132
|
+
switch (e.component) {
|
|
108
133
|
// Multi-value email chips — only for the email tool. Slack's KeywordInput
|
|
109
134
|
// (channelId) falls through to the plain input below.
|
|
110
135
|
case "KeywordInput":
|
|
111
|
-
if (!
|
|
136
|
+
if (!a)
|
|
112
137
|
break;
|
|
113
|
-
return /* @__PURE__ */
|
|
114
|
-
/* @__PURE__ */ o(
|
|
138
|
+
return /* @__PURE__ */ w(P, { children: [
|
|
139
|
+
/* @__PURE__ */ o(R, { color: c.content.primary, children: e.title }),
|
|
115
140
|
/* @__PURE__ */ o(
|
|
116
|
-
|
|
141
|
+
K,
|
|
117
142
|
{
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
)
|
|
143
|
+
nativeID: p,
|
|
144
|
+
placeholder: e.hint ?? "",
|
|
145
|
+
chips: U(l[e.key]),
|
|
146
|
+
onChange: (r) => i(e.key, r.join(",")),
|
|
147
|
+
variablesData: y,
|
|
148
|
+
hint: /* @__PURE__ */ o(_, { color: c.content.secondary, children: "Press Enter or comma to add multiple emails" })
|
|
133
149
|
}
|
|
134
150
|
)
|
|
135
|
-
] },
|
|
151
|
+
] }, e.key);
|
|
136
152
|
case "MultilineInput":
|
|
137
153
|
return /* @__PURE__ */ o(
|
|
138
154
|
M,
|
|
139
155
|
{
|
|
140
|
-
"data-test":
|
|
141
|
-
label:
|
|
142
|
-
value: String(
|
|
143
|
-
onChange: (
|
|
144
|
-
maxLength:
|
|
145
|
-
placeholder:
|
|
146
|
-
onImprove:
|
|
147
|
-
variablesData:
|
|
156
|
+
"data-test": p,
|
|
157
|
+
label: e.title,
|
|
158
|
+
value: String(l[e.key] ?? ""),
|
|
159
|
+
onChange: (r) => i(e.key, r),
|
|
160
|
+
maxLength: u.instructions,
|
|
161
|
+
placeholder: e.hint ?? "",
|
|
162
|
+
onImprove: C,
|
|
163
|
+
variablesData: y
|
|
148
164
|
},
|
|
149
|
-
|
|
165
|
+
e.key
|
|
150
166
|
);
|
|
151
167
|
case "Switch":
|
|
152
|
-
return /* @__PURE__ */
|
|
153
|
-
/* @__PURE__ */
|
|
154
|
-
/* @__PURE__ */ o(
|
|
155
|
-
|
|
168
|
+
return /* @__PURE__ */ w(te, { children: [
|
|
169
|
+
/* @__PURE__ */ w(ne, { children: [
|
|
170
|
+
/* @__PURE__ */ o(R, { color: c.content.primary, children: e.title }),
|
|
171
|
+
e.hint && /* @__PURE__ */ o(_, { color: c.content.secondary, children: e.hint })
|
|
156
172
|
] }),
|
|
157
173
|
/* @__PURE__ */ o(
|
|
158
|
-
|
|
174
|
+
q,
|
|
159
175
|
{
|
|
160
|
-
"data-test":
|
|
161
|
-
value: !!
|
|
162
|
-
onValueChange: async (
|
|
176
|
+
"data-test": p,
|
|
177
|
+
value: !!l[e.key],
|
|
178
|
+
onValueChange: async (r) => i(e.key, r)
|
|
163
179
|
}
|
|
164
180
|
)
|
|
165
|
-
] },
|
|
181
|
+
] }, e.key);
|
|
166
182
|
}
|
|
167
|
-
const
|
|
168
|
-
|
|
183
|
+
const m = /* @__PURE__ */ o(
|
|
184
|
+
G,
|
|
169
185
|
{
|
|
170
|
-
"data-test":
|
|
186
|
+
"data-test": p,
|
|
171
187
|
variant: "small",
|
|
172
|
-
labelText:
|
|
188
|
+
labelText: e.title,
|
|
173
189
|
labelTextBold: !0,
|
|
174
|
-
placeholder:
|
|
175
|
-
value: String(
|
|
176
|
-
onChangeText: (
|
|
190
|
+
placeholder: e.hint ?? "",
|
|
191
|
+
value: String(l[e.key] ?? ""),
|
|
192
|
+
onChangeText: (r) => i(e.key, r)
|
|
177
193
|
}
|
|
178
194
|
);
|
|
179
|
-
return
|
|
195
|
+
return a ? /* @__PURE__ */ o(
|
|
180
196
|
O,
|
|
181
197
|
{
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
198
|
+
addDataButton: !0,
|
|
199
|
+
variablesData: y,
|
|
200
|
+
onInsert: (r, L) => {
|
|
201
|
+
const I = String(l[e.key] ?? ""), B = L ?? I.length;
|
|
202
|
+
i(
|
|
203
|
+
e.key,
|
|
204
|
+
`${I.slice(0, B)}${r}${I.slice(B)}`
|
|
188
205
|
);
|
|
189
206
|
},
|
|
190
|
-
children:
|
|
207
|
+
children: m
|
|
191
208
|
},
|
|
192
|
-
|
|
193
|
-
) : /* @__PURE__ */ o(
|
|
194
|
-
},
|
|
209
|
+
e.key
|
|
210
|
+
) : /* @__PURE__ */ o(j.Fragment, { children: m }, e.key);
|
|
211
|
+
}, E = J[n];
|
|
195
212
|
return /* @__PURE__ */ o(
|
|
196
213
|
W,
|
|
197
214
|
{
|
|
198
|
-
header:
|
|
215
|
+
header: E.title,
|
|
199
216
|
closeOnEscapeKey: !1,
|
|
200
|
-
zIndex:
|
|
201
|
-
headerCustomComponent: /* @__PURE__ */ o(H, { title:
|
|
217
|
+
zIndex: b,
|
|
218
|
+
headerCustomComponent: /* @__PURE__ */ o(H, { title: E.title, subtitle: E.subtitle }),
|
|
202
219
|
hideCrossButton: !1,
|
|
203
220
|
width: "431px",
|
|
204
221
|
headerStyle: z,
|
|
205
222
|
bodyStyle: V,
|
|
206
|
-
onClose:
|
|
223
|
+
onClose: d,
|
|
207
224
|
saveButtonProps: {
|
|
208
225
|
"data-test": "config-tool-save",
|
|
209
226
|
buttonText: "Save",
|
|
210
227
|
buttonType: "primary",
|
|
211
228
|
size: "small",
|
|
212
|
-
disabled: !
|
|
213
|
-
isLoading:
|
|
214
|
-
onClick:
|
|
229
|
+
disabled: !g,
|
|
230
|
+
isLoading: k,
|
|
231
|
+
onClick: A
|
|
215
232
|
},
|
|
216
233
|
cancelButtonProps: {
|
|
217
234
|
"data-test": "config-tool-cancel",
|
|
218
235
|
buttonText: "Cancel",
|
|
219
236
|
buttonType: "tertiaryGray",
|
|
220
237
|
size: "small",
|
|
221
|
-
onClick:
|
|
238
|
+
onClick: d
|
|
222
239
|
},
|
|
223
|
-
children:
|
|
240
|
+
children: t.map(D)
|
|
224
241
|
}
|
|
225
242
|
);
|
|
226
|
-
},
|
|
243
|
+
}, X = v.div`
|
|
227
244
|
display: flex;
|
|
228
245
|
flex-direction: column;
|
|
229
246
|
gap: 8px;
|
|
230
|
-
`,
|
|
247
|
+
`, Z = v.input`
|
|
231
248
|
width: 100%;
|
|
232
249
|
min-width: 0;
|
|
233
250
|
box-sizing: border-box;
|
|
234
251
|
height: 32px;
|
|
235
252
|
padding: 0 8px;
|
|
236
|
-
border: 1px solid ${
|
|
253
|
+
border: 1px solid ${c.stroke.primary};
|
|
237
254
|
border-radius: 4px;
|
|
238
255
|
font-family: 'Inter', sans-serif;
|
|
239
256
|
font-size: 14px;
|
|
240
|
-
color: ${
|
|
241
|
-
background: ${
|
|
257
|
+
color: ${c.content.primary};
|
|
258
|
+
background: ${c.surface.standard};
|
|
242
259
|
outline: none;
|
|
243
260
|
|
|
244
261
|
&::placeholder {
|
|
245
|
-
color: ${
|
|
262
|
+
color: ${c.content.secondary};
|
|
246
263
|
}
|
|
247
264
|
|
|
248
265
|
&:focus {
|
|
249
|
-
border-color: ${
|
|
266
|
+
border-color: ${c.stroke.brand};
|
|
250
267
|
}
|
|
251
|
-
`,
|
|
268
|
+
`, ee = v.div`
|
|
252
269
|
display: flex;
|
|
253
270
|
flex-wrap: wrap;
|
|
254
271
|
gap: 6px;
|
|
255
|
-
`,
|
|
272
|
+
`, te = v.div`
|
|
256
273
|
display: flex;
|
|
257
274
|
align-items: center;
|
|
258
275
|
justify-content: space-between;
|
|
259
276
|
gap: 12px;
|
|
260
|
-
`,
|
|
277
|
+
`, ne = v.div`
|
|
261
278
|
display: flex;
|
|
262
279
|
flex-direction: column;
|
|
263
280
|
gap: 4px;
|
|
264
281
|
min-width: 0;
|
|
265
282
|
`;
|
|
266
283
|
export {
|
|
267
|
-
|
|
284
|
+
ke as ConfigToolPanel
|
|
268
285
|
};
|
|
269
286
|
//# 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 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":"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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};\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 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\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}}\n\t\t\t\tonInsert={(token, caret) => {\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\tplaceholder={placeholder}\n\t\t\t\t\tvalue={buffer}\n\t\t\t\t\tonChange={(e) => setBuffer(e.target.value)}\n\t\t\t\t\tonBlur={() => {\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(\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 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","wrapRef","useRef","inputRef","commit","parts","s","p","commitRef","panelOpenRef","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,10 +1,10 @@
|
|
|
1
1
|
import { jsxs as lt, Fragment as Kt, jsx as c } from "react/jsx-runtime";
|
|
2
2
|
import { useState as r, useRef as h, useMemo as Nt, useCallback as a } from "react";
|
|
3
|
-
import
|
|
3
|
+
import Bt from "styled-components";
|
|
4
4
|
import { addUnique as at } from "../../../utils/arrayUtils.js";
|
|
5
5
|
import { COLORS as j } from "../../../constants/Theme.js";
|
|
6
|
-
import { AGENT_CHAR_LIMITS as
|
|
7
|
-
import { CONFIG_TOOL_SOURCES as
|
|
6
|
+
import { AGENT_CHAR_LIMITS as Dt } from "../constants/charLimits.js";
|
|
7
|
+
import { CONFIG_TOOL_SOURCES as Gt, ToolSource as p } from "../constants/tools.js";
|
|
8
8
|
import { buildAgentMentionItems as Pt, buildCustomToolMentionItems as zt, restApiMentionItem as Lt, configToolMentionItem as Ut, restApiToolName as Ht, configToolName as $t, toolSourceLabel as Ft } from "../utils/mentionSerialization.js";
|
|
9
9
|
import { sourceIcon as W, SOURCE_ICONS as ct, renderSourceIcon as ut } from "../utils/sourceIcons.js";
|
|
10
10
|
import { buildToolActions as jt } from "../utils/toolActions.js";
|
|
@@ -19,7 +19,7 @@ import { Toaster as te } from "../../toaster/Toaster.js";
|
|
|
19
19
|
const ee = 1e3, Y = 1002, mt = (A, f) => {
|
|
20
20
|
const s = A ?? [];
|
|
21
21
|
return s.some((u) => u.id === f.id) ? s.map((u) => u.id === f.id ? f : u) : [...s, f];
|
|
22
|
-
}, pt =
|
|
22
|
+
}, pt = Bt.button`
|
|
23
23
|
align-self: flex-start;
|
|
24
24
|
border: 1px solid ${j.stroke.primary};
|
|
25
25
|
color: ${j.content.primary};
|
|
@@ -45,14 +45,14 @@ const ee = 1e3, Y = 1002, mt = (A, f) => {
|
|
|
45
45
|
title: q = "Create sub-agent",
|
|
46
46
|
initial: g,
|
|
47
47
|
appLabel: J = "Manifest",
|
|
48
|
-
charLimits: T =
|
|
48
|
+
charLimits: T = Dt,
|
|
49
49
|
variablesData: v
|
|
50
50
|
}) => {
|
|
51
51
|
const [w, ft] = r(g?.name ?? ""), [b, R] = r(g?.instructions ?? ""), [I, _] = r(g?.guardrail ?? ""), [O, k] = r(g?.tools ?? []), [m, K] = r(
|
|
52
52
|
g?.configTools ?? []
|
|
53
53
|
), [d, N] = r(
|
|
54
54
|
g?.restApiTools ?? []
|
|
55
|
-
), [i, y] = r(null), E = h(0), [Q, V] = r(!1), [gt,
|
|
55
|
+
), [i, y] = r(null), E = h(0), [Q, V] = r(!1), [gt, B] = r(0), [yt, D] = r(0), [S, tt] = r(null), G = Nt(
|
|
56
56
|
() => [
|
|
57
57
|
...Pt(s, [], J),
|
|
58
58
|
...zt(m, d)
|
|
@@ -95,7 +95,7 @@ const ee = 1e3, Y = 1002, mt = (A, f) => {
|
|
|
95
95
|
[]
|
|
96
96
|
), St = a(
|
|
97
97
|
(t) => {
|
|
98
|
-
const e =
|
|
98
|
+
const e = Gt[t];
|
|
99
99
|
e ? L(e) : z();
|
|
100
100
|
},
|
|
101
101
|
[L, z]
|
|
@@ -121,10 +121,10 @@ const ee = 1e3, Y = 1002, mt = (A, f) => {
|
|
|
121
121
|
tools: O,
|
|
122
122
|
configTools: m,
|
|
123
123
|
restApiTools: d
|
|
124
|
-
}, R((n) => l(n)), _((n) => l(n)), k((n) => n.filter((x) => x !== t)), K((n) => n.filter((x) => x.id !== t)), N((n) => n.filter((x) => x.id !== t)),
|
|
124
|
+
}, R((n) => l(n)), _((n) => l(n)), k((n) => n.filter((x) => x !== t)), K((n) => n.filter((x) => x.id !== t)), N((n) => n.filter((x) => x.id !== t)), B((n) => n + 1), D((n) => n + 1), nt.current += 1, H({ id: nt.current, message: `Tool "${e}" removed` });
|
|
125
125
|
}, vt = () => {
|
|
126
126
|
const t = $.current;
|
|
127
|
-
t && (R(t.instructions), _(t.guardrail), k(t.tools), K(t.configTools), N(t.restApiTools),
|
|
127
|
+
t && (R(t.instructions), _(t.guardrail), k(t.tools), K(t.configTools), N(t.restApiTools), B((e) => e + 1), D((e) => e + 1), $.current = null), H(null);
|
|
128
128
|
}, st = w.trim().length > 0 && (b.trim().length > 0 || I.trim().length > 0), Rt = O.map((t) => {
|
|
129
129
|
const e = s.find((o) => o.tool_id === t);
|
|
130
130
|
return e ? {
|
|
@@ -191,7 +191,7 @@ const ee = 1e3, Y = 1002, mt = (A, f) => {
|
|
|
191
191
|
tt(t);
|
|
192
192
|
try {
|
|
193
193
|
const o = await u(t, t === "instructions" ? b : I);
|
|
194
|
-
t === "instructions" ? (R(o),
|
|
194
|
+
t === "instructions" ? (R(o), B((l) => l + 1)) : (_(o), D((l) => l + 1));
|
|
195
195
|
} finally {
|
|
196
196
|
tt(null);
|
|
197
197
|
}
|
|
@@ -257,10 +257,11 @@ const ee = 1e3, Y = 1002, mt = (A, f) => {
|
|
|
257
257
|
placeholder: "Write the steps in plain English. Type @ to reference a tool.",
|
|
258
258
|
minHeight: "160px",
|
|
259
259
|
resetKey: `instr-${gt}`,
|
|
260
|
-
mentionItems:
|
|
260
|
+
mentionItems: G,
|
|
261
261
|
tools: s,
|
|
262
262
|
toolActions: F,
|
|
263
263
|
variablesData: v,
|
|
264
|
+
addDataButton: !0,
|
|
264
265
|
onMentionSelect: ot,
|
|
265
266
|
onFocus: bt,
|
|
266
267
|
registerInsert: ht,
|
|
@@ -287,10 +288,11 @@ const ee = 1e3, Y = 1002, mt = (A, f) => {
|
|
|
287
288
|
placeholder: "e.g. Never discuss competitor pricing. Type @ to reference a tool.",
|
|
288
289
|
minHeight: "160px",
|
|
289
290
|
resetKey: `guard-${yt}`,
|
|
290
|
-
mentionItems:
|
|
291
|
+
mentionItems: G,
|
|
291
292
|
tools: s,
|
|
292
293
|
toolActions: F,
|
|
293
294
|
variablesData: v,
|
|
295
|
+
addDataButton: !0,
|
|
294
296
|
onMentionSelect: ot,
|
|
295
297
|
onFocus: It,
|
|
296
298
|
registerInsert: Tt,
|
|
@@ -314,7 +316,7 @@ const ee = 1e3, Y = 1002, mt = (A, f) => {
|
|
|
314
316
|
items: Et,
|
|
315
317
|
addableOptions: Mt,
|
|
316
318
|
sourceGroups: wt,
|
|
317
|
-
mentionItems:
|
|
319
|
+
mentionItems: G,
|
|
318
320
|
actionSources: F,
|
|
319
321
|
emptyText: "No tools added yet.",
|
|
320
322
|
pickerOpensUp: !0,
|