@bikdotai/bik-component-library 0.0.875-beta.0 → 0.0.875-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js +11 -11
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +2 -2
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js +4 -4
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/steps/Step4HandoverRules.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step4HandoverRules.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.d.ts +12 -0
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +149 -145
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.d.ts +12 -0
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +86 -82
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.d.ts +12 -0
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +52 -48
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/index.d.ts +0 -2
- package/dist/esm/components/agent-builder/steps/Step4HandoverRules.d.ts +2 -3
- package/dist/esm/components/agent-builder/steps/Step4HandoverRules.js +117 -31
- package/dist/esm/components/agent-builder/steps/Step4HandoverRules.js.map +1 -1
- package/dist/esm/index.js +316 -318
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/components/agent-builder/components/HandoverMethodSection.js +0 -2
- package/dist/cjs/components/agent-builder/components/HandoverMethodSection.js.map +0 -1
- package/dist/esm/components/agent-builder/components/HandoverMethodSection.d.ts +0 -22
- package/dist/esm/components/agent-builder/components/HandoverMethodSection.js +0 -109
- package/dist/esm/components/agent-builder/components/HandoverMethodSection.js.map +0 -1
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { jsxs as i, jsx as r } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import ee from "../../../assets/icons/delete.svg.js";
|
|
3
|
+
import te from "../../../assets/icons/plus.svg.js";
|
|
4
4
|
import { useState as l, useRef as B } from "react";
|
|
5
5
|
import C from "styled-components";
|
|
6
|
-
import { BodyCaption as
|
|
6
|
+
import { BodyCaption as re, TitleSmall as u } from "../../TypographyStyle.js";
|
|
7
7
|
import { COLORS as a } from "../../../constants/Theme.js";
|
|
8
8
|
import { FieldBlock as m } from "../AgentBuilder.styled.js";
|
|
9
|
-
import { AGENT_CHAR_LIMITS as
|
|
10
|
-
import { DRAWER_BODY_STYLE as
|
|
11
|
-
import { ToolInstructionsField as
|
|
9
|
+
import { AGENT_CHAR_LIMITS as ne } from "../constants/charLimits.js";
|
|
10
|
+
import { DRAWER_BODY_STYLE as oe, DRAWER_HEADER_STYLE as ae, DrawerHeaderText as se } from "./DrawerHeaderText.js";
|
|
11
|
+
import { ToolInstructionsField as le } from "./ToolInstructionsField.js";
|
|
12
12
|
import { VariableInlineField as D } from "./VariableInlineField.js";
|
|
13
|
-
import { SideModal as
|
|
13
|
+
import { SideModal as ie } from "../../side-modal/SideModal.js";
|
|
14
14
|
import { Input as _ } from "../../input/Input.js";
|
|
15
|
-
import { Dropdown as
|
|
16
|
-
import { unwrapDropdownValue as
|
|
17
|
-
import { Button as
|
|
15
|
+
import { Dropdown as de } from "../../dropdown/Dropdown.js";
|
|
16
|
+
import { unwrapDropdownValue as ce } from "../../dropdown/utils.js";
|
|
17
|
+
import { Button as pe } from "../../button/Button.js";
|
|
18
18
|
import { BikEditor as M } from "../../../editor/BikEditor.js";
|
|
19
|
-
const
|
|
19
|
+
const me = ["GET", "POST", "PUT", "PATCH", "DELETE"], he = me.map((s) => ({
|
|
20
20
|
label: s,
|
|
21
21
|
value: s
|
|
22
|
-
})),
|
|
22
|
+
})), ue = (s) => {
|
|
23
23
|
if (!/^https?:\/\//i.test(s))
|
|
24
24
|
return !1;
|
|
25
25
|
let d;
|
|
@@ -29,53 +29,57 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
29
29
|
return !1;
|
|
30
30
|
}
|
|
31
31
|
return d.includes(".") && !d.startsWith(".") && !d.endsWith(".");
|
|
32
|
-
},
|
|
32
|
+
}, Ue = ({
|
|
33
33
|
onClose: s,
|
|
34
34
|
onSave: d,
|
|
35
35
|
initial: o,
|
|
36
36
|
onImprove: N,
|
|
37
|
-
charLimits: f =
|
|
37
|
+
charLimits: f = ne,
|
|
38
38
|
zIndex: q,
|
|
39
39
|
existingNames: $ = [],
|
|
40
|
-
variablesData: y
|
|
40
|
+
variablesData: y,
|
|
41
|
+
element: j,
|
|
42
|
+
footerDirection: V
|
|
41
43
|
}) => {
|
|
42
|
-
const [g,
|
|
44
|
+
const [g, W] = l(o?.name ?? ""), [v, z] = l(o?.instructions ?? ""), [x, F] = l(o?.url ?? "https://"), [T, G] = l(
|
|
43
45
|
o?.method ?? "POST"
|
|
44
46
|
), [H, S] = l(
|
|
45
47
|
o?.headers ?? [{ key: "", value: "" }]
|
|
46
|
-
), [w,
|
|
48
|
+
), [w, J] = l(o?.requestBody ?? ""), [E, Y] = l(
|
|
47
49
|
o?.responseSample ?? ""
|
|
48
50
|
), [I, k] = l(!1), c = B(
|
|
49
51
|
(o?.headers ?? [{ key: "", value: "" }]).map(
|
|
50
52
|
(e, t) => t
|
|
51
53
|
)
|
|
52
54
|
), A = B(c.current.length), L = (e, t) => S(
|
|
53
|
-
(n) => n.map((h,
|
|
54
|
-
),
|
|
55
|
+
(n) => n.map((h, Z) => Z === e ? { ...h, ...t } : h)
|
|
56
|
+
), K = () => {
|
|
55
57
|
c.current = [...c.current, A.current], A.current += 1, S((e) => [...e, { key: "", value: "" }]);
|
|
56
|
-
},
|
|
58
|
+
}, Q = (e) => {
|
|
57
59
|
c.current = c.current.filter((t, n) => n !== e), S((t) => t.filter((n, h) => h !== e));
|
|
58
60
|
}, b = g.trim(), R = b.length > 0 && $.some(
|
|
59
61
|
(e) => e.trim().toLowerCase() === b.toLowerCase()
|
|
60
|
-
), p = x.trim(), O = p.includes("{{variable:") ? /^https?:\/\/./.test(p) :
|
|
62
|
+
), p = x.trim(), O = p.includes("{{variable:") ? /^https?:\/\/./.test(p) : ue(p), X = p.length > 0 && p !== "https://" && !O, P = b.length > 0 && O && !R && // The editor's characterLimit is soft (a paste may exceed it, rendered
|
|
61
63
|
// grey) — gate the save so over-limit instructions can't be persisted.
|
|
62
64
|
v.length <= f.instructions;
|
|
63
65
|
return /* @__PURE__ */ i(
|
|
64
|
-
|
|
66
|
+
ie,
|
|
65
67
|
{
|
|
66
68
|
header: "Rest API",
|
|
67
69
|
closeOnEscapeKey: !1,
|
|
68
70
|
zIndex: q,
|
|
71
|
+
element: j,
|
|
72
|
+
footerDirection: V,
|
|
69
73
|
headerCustomComponent: /* @__PURE__ */ r(
|
|
70
|
-
|
|
74
|
+
se,
|
|
71
75
|
{
|
|
72
76
|
title: "Rest API",
|
|
73
77
|
subtitle: "Connect to any API endpoint. Define the request and a sample response for the agent to reference."
|
|
74
78
|
}
|
|
75
79
|
),
|
|
76
80
|
width: "431px",
|
|
77
|
-
headerStyle:
|
|
78
|
-
bodyStyle:
|
|
81
|
+
headerStyle: ae,
|
|
82
|
+
bodyStyle: oe,
|
|
79
83
|
onClose: s,
|
|
80
84
|
saveButtonProps: {
|
|
81
85
|
"data-test": "restapi-save",
|
|
@@ -128,16 +132,16 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
128
132
|
maxCharLimit: f.name,
|
|
129
133
|
state: R ? "invalid" : void 0,
|
|
130
134
|
errorMessage: R ? "A tool with this name already exists" : void 0,
|
|
131
|
-
onChangeText:
|
|
135
|
+
onChangeText: W
|
|
132
136
|
}
|
|
133
137
|
),
|
|
134
138
|
/* @__PURE__ */ r(
|
|
135
|
-
|
|
139
|
+
le,
|
|
136
140
|
{
|
|
137
141
|
"data-test": "restapi-instructions",
|
|
138
142
|
label: "Instructions",
|
|
139
143
|
value: v,
|
|
140
|
-
onChange:
|
|
144
|
+
onChange: z,
|
|
141
145
|
maxLength: f.instructions,
|
|
142
146
|
placeholder: "Describe how should the LLM generate the rest API",
|
|
143
147
|
onImprove: N,
|
|
@@ -152,26 +156,26 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
152
156
|
label: "Request URL",
|
|
153
157
|
placeholder: "https://",
|
|
154
158
|
value: x,
|
|
155
|
-
onChange:
|
|
159
|
+
onChange: F,
|
|
156
160
|
variablesData: y
|
|
157
161
|
}
|
|
158
162
|
),
|
|
159
|
-
|
|
163
|
+
X && /* @__PURE__ */ r(re, { color: a.content.negative, children: "Enter a valid URL (including https://)" })
|
|
160
164
|
] }),
|
|
161
165
|
/* @__PURE__ */ i(m, { children: [
|
|
162
166
|
/* @__PURE__ */ r(u, { color: a.content.primary, children: "HTTP method" }),
|
|
163
167
|
/* @__PURE__ */ r(
|
|
164
|
-
|
|
168
|
+
de,
|
|
165
169
|
{
|
|
166
170
|
"data-test": "restapi-method",
|
|
167
171
|
size: "small",
|
|
168
172
|
width: "100%",
|
|
169
173
|
dropdownWidth: "399px",
|
|
170
|
-
options:
|
|
174
|
+
options: he,
|
|
171
175
|
defaultOptions: [{ label: T, value: T }],
|
|
172
176
|
onSelect: (e) => {
|
|
173
|
-
const t =
|
|
174
|
-
t &&
|
|
177
|
+
const t = ce(e);
|
|
178
|
+
t && G(t);
|
|
175
179
|
}
|
|
176
180
|
}
|
|
177
181
|
)
|
|
@@ -179,7 +183,7 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
179
183
|
/* @__PURE__ */ i(m, { children: [
|
|
180
184
|
/* @__PURE__ */ r(u, { color: a.content.primary, children: "Headers" }),
|
|
181
185
|
H.map((e, t) => /* @__PURE__ */ i(
|
|
182
|
-
|
|
186
|
+
fe,
|
|
183
187
|
{
|
|
184
188
|
"data-test": `restapi-header-${t}`,
|
|
185
189
|
children: [
|
|
@@ -203,14 +207,14 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
203
207
|
}
|
|
204
208
|
),
|
|
205
209
|
/* @__PURE__ */ r(
|
|
206
|
-
|
|
210
|
+
ge,
|
|
207
211
|
{
|
|
208
212
|
type: "button",
|
|
209
213
|
"aria-label": "Remove header",
|
|
210
214
|
"data-test": `restapi-header-remove-${t}`,
|
|
211
|
-
onClick: () =>
|
|
215
|
+
onClick: () => Q(t),
|
|
212
216
|
children: /* @__PURE__ */ r(
|
|
213
|
-
|
|
217
|
+
ee,
|
|
214
218
|
{
|
|
215
219
|
width: 16,
|
|
216
220
|
height: 16,
|
|
@@ -223,15 +227,15 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
223
227
|
},
|
|
224
228
|
c.current[t]
|
|
225
229
|
)),
|
|
226
|
-
/* @__PURE__ */ r(
|
|
227
|
-
|
|
230
|
+
/* @__PURE__ */ r(ye, { children: /* @__PURE__ */ r(
|
|
231
|
+
pe,
|
|
228
232
|
{
|
|
229
233
|
"data-test": "restapi-add-header",
|
|
230
234
|
buttonType: "dashRegular",
|
|
231
235
|
size: "small",
|
|
232
|
-
LeadingIcon:
|
|
236
|
+
LeadingIcon: te,
|
|
233
237
|
buttonText: "Add header",
|
|
234
|
-
onClick:
|
|
238
|
+
onClick: K
|
|
235
239
|
}
|
|
236
240
|
) })
|
|
237
241
|
] }),
|
|
@@ -244,7 +248,7 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
244
248
|
initialContent: w,
|
|
245
249
|
style: U,
|
|
246
250
|
placeholder: "Type or paste JSON here",
|
|
247
|
-
onChange: (e) =>
|
|
251
|
+
onChange: (e) => J(e.text),
|
|
248
252
|
minHeight: "120px",
|
|
249
253
|
maxHeight: "240px"
|
|
250
254
|
}
|
|
@@ -259,7 +263,7 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
259
263
|
style: U,
|
|
260
264
|
initialContent: E,
|
|
261
265
|
placeholder: "Type or paste JSON here",
|
|
262
|
-
onChange: (e) =>
|
|
266
|
+
onChange: (e) => Y(e.text),
|
|
263
267
|
minHeight: "120px",
|
|
264
268
|
maxHeight: "240px"
|
|
265
269
|
}
|
|
@@ -268,14 +272,14 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
268
272
|
]
|
|
269
273
|
}
|
|
270
274
|
);
|
|
271
|
-
},
|
|
275
|
+
}, fe = C.div`
|
|
272
276
|
display: grid;
|
|
273
277
|
grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) 32px;
|
|
274
278
|
align-items: center;
|
|
275
279
|
gap: 8px;
|
|
276
|
-
`,
|
|
280
|
+
`, ye = C.div`
|
|
277
281
|
display: flex;
|
|
278
|
-
`,
|
|
282
|
+
`, ge = C.button`
|
|
279
283
|
display: inline-flex;
|
|
280
284
|
align-items: center;
|
|
281
285
|
justify-content: center;
|
|
@@ -296,6 +300,6 @@ const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
|
296
300
|
};
|
|
297
301
|
export {
|
|
298
302
|
U as JsonFieldBox,
|
|
299
|
-
|
|
303
|
+
Ue as RestApiToolPanel
|
|
300
304
|
};
|
|
301
305
|
//# sourceMappingURL=RestApiToolPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RestApiToolPanel.js","sources":["../../../../../src/components/agent-builder/components/RestApiToolPanel.tsx"],"sourcesContent":["import DeleteIcon from '@src/assets/icons/delete.svg';\nimport PlusIcon from '@src/assets/icons/plus.svg';\nimport { BikEditor } from '@src/editor';\nimport React, { useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { Dropdown, unwrapDropdownValue } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport type { VariableListInterfaceV3 } from '../../variable-picker-v3/model';\nimport {\n\tRestApiHeader,\n\tRestApiMethod,\n\tRestApiToolConfig,\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 { VariableInlineField } from './VariableInlineField';\n\ninterface RestApiToolPanelProps {\n\tonClose: () => void;\n\t/** Persist the config. A pending promise shows the Save loader. */\n\tonSave: (config: RestApiToolConfig) => void | Promise<void>;\n\t/** Seed values when editing an existing tool. */\n\tinitial?: RestApiToolConfig;\n\t/** Optional \"Improve with AI\" for the instructions field. Omit to hide it. */\n\tonImprove?: (text: string) => Promise<string>;\n\tcharLimits?: AgentCharLimits;\n\t/** SideModal stacking order — raise it when opened over another drawer. */\n\tzIndex?: number;\n\t/** Names of the OTHER tools — a new tool can't reuse one of these. */\n\texistingNames?: string[];\n\t/**\n\t * Variable catalog for the `@` trigger. When non-empty, `@` opens the\n\t * variable picker directly in Instructions / Request URL / header values.\n\t * (Request / Response JSON editors are deliberately not wired for now.)\n\t * Absent → the drawer behaves exactly as before.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\n}\n\nconst METHODS: RestApiMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];\nconst METHOD_OPTIONS: SingleOption[] = METHODS.map((m) => ({\n\tlabel: m,\n\tvalue: m,\n}));\n\n// A callable endpoint needs an explicit http(s):// scheme AND a real, dotted\n// host. `new URL` alone is too lenient — it accepts single-label hosts\n// (\"https://abc\"), a one-slash scheme (\"https:/abc.com\"), and dangling-dot\n// hosts (\"https://.com\" / \"https://abc.\"). Require the `://` prefix on the raw\n// value plus a hostname that is either dotted (example.com) or an IPv4.\nconst isValidHttpUrl = (value: string): boolean => {\n\tif (!/^https?:\\/\\//i.test(value)) {\n\t\treturn false;\n\t}\n\tlet host: string;\n\ttry {\n\t\thost = new URL(value).hostname;\n\t} catch {\n\t\treturn false;\n\t}\n\treturn host.includes('.') && !host.startsWith('.') && !host.endsWith('.');\n};\n\n/**\n * Right-side drawer to configure a \"Rest API\" tool: the endpoint the agent can\n * call, plus a JSON request-body template and a sample response. Mount it fresh\n * per open (key it) so `initial` seeds the state. Built on the shared `SideModal`\n * shell and the BikEditor JSON body mode for the Request / Response editors.\n */\nexport const RestApiToolPanel: React.FC<RestApiToolPanelProps> = ({\n\tonClose,\n\tonSave,\n\tinitial,\n\tonImprove,\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tzIndex,\n\texistingNames = [],\n\tvariablesData,\n}) => {\n\tconst [name, setName] = useState(initial?.name ?? '');\n\tconst [instructions, setInstructions] = useState(initial?.instructions ?? '');\n\t// New tools start with the scheme pre-filled so the user only types the host.\n\tconst [url, setUrl] = useState(initial?.url ?? 'https://');\n\tconst [method, setMethod] = useState<RestApiMethod>(\n\t\tinitial?.method ?? 'POST',\n\t);\n\tconst [headers, setHeaders] = useState<RestApiHeader[]>(\n\t\tinitial?.headers ?? [{ key: '', value: '' }],\n\t);\n\tconst [requestBody, setRequestBody] = useState(initial?.requestBody ?? '');\n\tconst [responseSample, setResponseSample] = useState(\n\t\tinitial?.responseSample ?? '',\n\t);\n\tconst [saving, setSaving] = useState(false);\n\n\t// Stable per-row identity for React keys, parallel to `headers`. The value\n\t// field is an uncontrolled editor, so a row must keep its mount across\n\t// sibling add/remove — index-based keys would remount every row (dropping\n\t// focus mid-edit) or let a deleted row's text linger in a reused neighbour.\n\tconst headerIdsRef = useRef<number[]>(\n\t\t(initial?.headers ?? [{ key: '', value: '' }]).map(\n\t\t\t(_h: RestApiHeader, i: number) => i,\n\t\t),\n\t);\n\tconst nextHeaderIdRef = useRef(headerIdsRef.current.length);\n\n\tconst patchHeader = (i: number, patch: Partial<RestApiHeader>) =>\n\t\tsetHeaders((prev) =>\n\t\t\tprev.map((h, idx) => (idx === i ? { ...h, ...patch } : h)),\n\t\t);\n\tconst addHeader = () => {\n\t\theaderIdsRef.current = [...headerIdsRef.current, nextHeaderIdRef.current];\n\t\tnextHeaderIdRef.current += 1;\n\t\tsetHeaders((prev) => [...prev, { key: '', value: '' }]);\n\t};\n\tconst removeHeader = (i: number) => {\n\t\theaderIdsRef.current = headerIdsRef.current.filter((_, idx) => idx !== i);\n\t\tsetHeaders((prev) => prev.filter((_, idx) => idx !== i));\n\t};\n\n\tconst nameTrimmed = name.trim();\n\t// Case-insensitive: two tools can't share a name (the LLM references them by it).\n\tconst isDuplicateName =\n\t\tnameTrimmed.length > 0 &&\n\t\texistingNames.some(\n\t\t\t(n) => n.trim().toLowerCase() === nameTrimmed.toLowerCase(),\n\t\t);\n\tconst urlTrimmed = url.trim();\n\t// Save needs a real endpoint, but don't flash the error while the field still\n\t// holds its pristine \"https://\" seed — only once the user has typed past it.\n\t// A URL that interpolates variables can't be parsed literally (braces are\n\t// invalid URL characters) — accept it once a scheme + something follows;\n\t// it only becomes a concrete URL after runtime substitution.\n\tconst urlUsesVariables = urlTrimmed.includes('{{variable:');\n\tconst urlOk = urlUsesVariables\n\t\t? /^https?:\\/\\/./.test(urlTrimmed)\n\t\t: isValidHttpUrl(urlTrimmed);\n\tconst isUrlInvalid =\n\t\turlTrimmed.length > 0 && urlTrimmed !== 'https://' && !urlOk;\n\tconst canSave =\n\t\tnameTrimmed.length > 0 &&\n\t\turlOk &&\n\t\t!isDuplicateName &&\n\t\t// The editor's characterLimit is soft (a paste may exceed it, rendered\n\t\t// grey) — gate the save so over-limit instructions can't be persisted.\n\t\tinstructions.length <= charLimits.instructions;\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst config: RestApiToolConfig = {\n\t\t\tid: initial?.id ?? `restapi_${Date.now().toString(36)}`,\n\t\t\tname: name.trim(),\n\t\t\tinstructions,\n\t\t\turl: url.trim(),\n\t\t\tmethod,\n\t\t\t// Drop fully-empty header rows.\n\t\t\theaders: headers.filter((h) => h.key.trim() || h.value.trim()),\n\t\t\trequestBody,\n\t\t\tresponseSample,\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\treturn (\n\t\t<SideModal\n\t\t\theader=\"Rest API\"\n\t\t\tcloseOnEscapeKey={false}\n\t\t\tzIndex={zIndex}\n\t\t\theaderCustomComponent={\n\t\t\t\t<DrawerHeaderText\n\t\t\t\t\ttitle=\"Rest API\"\n\t\t\t\t\tsubtitle=\"Connect to any API endpoint. Define the request and a sample response for the agent to reference.\"\n\t\t\t\t/>\n\t\t\t}\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': 'restapi-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': 'restapi-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<Input\n\t\t\t\tdata-test=\"restapi-name\"\n\t\t\t\tvariant=\"small\"\n\t\t\t\tlabelText=\"Name\"\n\t\t\t\tlabelTextBold\n\t\t\t\tplaceholder=\"Enter action name\"\n\t\t\t\tvalue={name}\n\t\t\t\tmaxCharLimit={charLimits.name}\n\t\t\t\tstate={isDuplicateName ? 'invalid' : undefined}\n\t\t\t\terrorMessage={\n\t\t\t\t\tisDuplicateName ? 'A tool with this name already exists' : undefined\n\t\t\t\t}\n\t\t\t\tonChangeText={setName}\n\t\t\t/>\n\n\t\t\t<ToolInstructionsField\n\t\t\t\tdata-test=\"restapi-instructions\"\n\t\t\t\tlabel=\"Instructions\"\n\t\t\t\tvalue={instructions}\n\t\t\t\tonChange={setInstructions}\n\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\tplaceholder=\"Describe how should the LLM generate the rest API\"\n\t\t\t\tonImprove={onImprove}\n\t\t\t\tvariablesData={variablesData}\n\t\t\t/>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<VariableInlineField\n\t\t\t\t\tdata-test=\"restapi-url\"\n\t\t\t\t\tlabel=\"Request URL\"\n\t\t\t\t\tplaceholder=\"https://\"\n\t\t\t\t\tvalue={url}\n\t\t\t\t\tonChange={setUrl}\n\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t/>\n\t\t\t\t{/* VariableInlineField has no invalid state of its own — surface the\n\t\t\t\t URL validation (from main) as a caption below the field. */}\n\t\t\t\t{isUrlInvalid && (\n\t\t\t\t\t<BodyCaption color={COLORS.content.negative}>\n\t\t\t\t\t\tEnter a valid URL (including https://)\n\t\t\t\t\t</BodyCaption>\n\t\t\t\t)}\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>HTTP method</TitleSmall>\n\t\t\t\t<Dropdown\n\t\t\t\t\tdata-test=\"restapi-method\"\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\tdropdownWidth=\"399px\"\n\t\t\t\t\toptions={METHOD_OPTIONS}\n\t\t\t\t\tdefaultOptions={[{ label: method, value: method }]}\n\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\tsetMethod(v as RestApiMethod);\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Headers</TitleSmall>\n\t\t\t\t{headers.map((h, i) => (\n\t\t\t\t\t<HeaderRow\n\t\t\t\t\t\tkey={headerIdsRef.current[i]}\n\t\t\t\t\t\tdata-test={`restapi-header-${i}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tvariant=\"small\"\n\t\t\t\t\t\t\thideInputHeader\n\t\t\t\t\t\t\tplaceholder=\"Enter name\"\n\t\t\t\t\t\t\tvalue={h.key}\n\t\t\t\t\t\t\tonChangeText={(v) => patchHeader(i, { key: v })}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<VariableInlineField\n\t\t\t\t\t\t\tplaceholder=\"Enter value\"\n\t\t\t\t\t\t\tvalue={h.value}\n\t\t\t\t\t\t\tonChange={(v) => patchHeader(i, { value: v })}\n\t\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<IconBtn\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-label=\"Remove header\"\n\t\t\t\t\t\t\tdata-test={`restapi-header-remove-${i}`}\n\t\t\t\t\t\t\tonClick={() => removeHeader(i)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<DeleteIcon\n\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</IconBtn>\n\t\t\t\t\t</HeaderRow>\n\t\t\t\t))}\n\t\t\t\t<AddHeaderRow>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tdata-test=\"restapi-add-header\"\n\t\t\t\t\t\tbuttonType=\"dashRegular\"\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\tLeadingIcon={PlusIcon}\n\t\t\t\t\t\tbuttonText=\"Add header\"\n\t\t\t\t\t\tonClick={addHeader}\n\t\t\t\t\t/>\n\t\t\t\t</AddHeaderRow>\n\t\t\t</FieldBlock>\n\n\t\t\t{/* Variables intentionally NOT wired here (yet) — the JSON editors are\n\t\t\t plain code fields; @ types a literal @. */}\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Request </TitleSmall>\n\t\t\t\t<BikEditor\n\t\t\t\t\tfeatures={{ jsonMode: true }}\n\t\t\t\t\tinitialContent={requestBody}\n\t\t\t\t\tstyle={JsonFieldBox}\n\t\t\t\t\tplaceholder=\"Type or paste JSON here\"\n\t\t\t\t\tonChange={(c) => setRequestBody(c.text)}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"240px\"\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Response </TitleSmall>\n\t\t\t\t<BikEditor\n\t\t\t\t\tfeatures={{ jsonMode: true }}\n\t\t\t\t\tstyle={JsonFieldBox}\n\t\t\t\t\tinitialContent={responseSample}\n\t\t\t\t\tplaceholder=\"Type or paste JSON here\"\n\t\t\t\t\tonChange={(c) => setResponseSample(c.text)}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"240px\"\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\t\t</SideModal>\n\t);\n};\n\n// Fixed tracks (name / value / delete): minmax(0, …) lets the fields shrink\n// below their content width, so a long value scrolls inside its field and the\n// delete button can never be pushed off the row.\nconst HeaderRow = styled.div`\n\tdisplay: grid;\n\tgrid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) 32px;\n\talign-items: center;\n\tgap: 8px;\n`;\n\nconst AddHeaderRow = styled.div`\n\tdisplay: flex;\n`;\n\nconst IconBtn = styled.button`\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-shrink: 0;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbackground: ${COLORS.surface.standard};\n\tcursor: pointer;\n\n\t&:hover {\n\t\tborder-color: ${COLORS.content.secondary};\n\t}\n`;\n\nexport const JsonFieldBox = {\n\tborderRadius: '4px',\n\toverflow: 'hidden',\n};\n"],"names":["METHODS","METHOD_OPTIONS","m","isValidHttpUrl","value","host","RestApiToolPanel","onClose","onSave","initial","onImprove","charLimits","AGENT_CHAR_LIMITS","zIndex","existingNames","variablesData","name","setName","useState","instructions","setInstructions","url","setUrl","method","setMethod","headers","setHeaders","requestBody","setRequestBody","responseSample","setResponseSample","saving","setSaving","headerIdsRef","useRef","_h","i","nextHeaderIdRef","patchHeader","patch","prev","idx","addHeader","removeHeader","_","nameTrimmed","isDuplicateName","n","urlTrimmed","urlOk","isUrlInvalid","canSave","jsxs","SideModal","jsx","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","config","h","result","Input","ToolInstructionsField","FieldBlock","VariableInlineField","BodyCaption","COLORS","TitleSmall","Dropdown","opt","v","unwrapDropdownValue","HeaderRow","IconBtn","DeleteIcon","AddHeaderRow","Button","PlusIcon","BikEditor","JsonFieldBox","c","styled"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RestApiToolPanel.js","sources":["../../../../../src/components/agent-builder/components/RestApiToolPanel.tsx"],"sourcesContent":["import DeleteIcon from '@src/assets/icons/delete.svg';\nimport PlusIcon from '@src/assets/icons/plus.svg';\nimport { BikEditor } from '@src/editor';\nimport React, { useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { Dropdown, unwrapDropdownValue } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport type { VariableListInterfaceV3 } from '../../variable-picker-v3/model';\nimport {\n\tRestApiHeader,\n\tRestApiMethod,\n\tRestApiToolConfig,\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 { VariableInlineField } from './VariableInlineField';\n\ninterface RestApiToolPanelProps {\n\tonClose: () => void;\n\t/** Persist the config. A pending promise shows the Save loader. */\n\tonSave: (config: RestApiToolConfig) => void | Promise<void>;\n\t/** Seed values when editing an existing tool. */\n\tinitial?: RestApiToolConfig;\n\t/** Optional \"Improve with AI\" for the instructions field. Omit to hide it. */\n\tonImprove?: (text: string) => Promise<string>;\n\tcharLimits?: AgentCharLimits;\n\t/** SideModal stacking order — raise it when opened over another drawer. */\n\tzIndex?: number;\n\t/**\n\t * Portal target for the drawer, passed straight to {@link SideModal}\n\t * (default `document.body`). Lets a host render it into its own positioned\n\t * slot rather than as a viewport overlay.\n\t */\n\telement?: Element | DocumentFragment;\n\t/**\n\t * Footer button order, passed straight to {@link SideModal} (default\n\t * `'row'`). Hosts that show this drawer beside their own footer can set\n\t * `'row-reverse'` to line the Cancel / Save order up with it.\n\t */\n\tfooterDirection?: 'row' | 'row-reverse';\n\t/** Names of the OTHER tools — a new tool can't reuse one of these. */\n\texistingNames?: string[];\n\t/**\n\t * Variable catalog for the `@` trigger. When non-empty, `@` opens the\n\t * variable picker directly in Instructions / Request URL / header values.\n\t * (Request / Response JSON editors are deliberately not wired for now.)\n\t * Absent → the drawer behaves exactly as before.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\n}\n\nconst METHODS: RestApiMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];\nconst METHOD_OPTIONS: SingleOption[] = METHODS.map((m) => ({\n\tlabel: m,\n\tvalue: m,\n}));\n\n// A callable endpoint needs an explicit http(s):// scheme AND a real, dotted\n// host. `new URL` alone is too lenient — it accepts single-label hosts\n// (\"https://abc\"), a one-slash scheme (\"https:/abc.com\"), and dangling-dot\n// hosts (\"https://.com\" / \"https://abc.\"). Require the `://` prefix on the raw\n// value plus a hostname that is either dotted (example.com) or an IPv4.\nconst isValidHttpUrl = (value: string): boolean => {\n\tif (!/^https?:\\/\\//i.test(value)) {\n\t\treturn false;\n\t}\n\tlet host: string;\n\ttry {\n\t\thost = new URL(value).hostname;\n\t} catch {\n\t\treturn false;\n\t}\n\treturn host.includes('.') && !host.startsWith('.') && !host.endsWith('.');\n};\n\n/**\n * Right-side drawer to configure a \"Rest API\" tool: the endpoint the agent can\n * call, plus a JSON request-body template and a sample response. Mount it fresh\n * per open (key it) so `initial` seeds the state. Built on the shared `SideModal`\n * shell and the BikEditor JSON body mode for the Request / Response editors.\n */\nexport const RestApiToolPanel: React.FC<RestApiToolPanelProps> = ({\n\tonClose,\n\tonSave,\n\tinitial,\n\tonImprove,\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tzIndex,\n\texistingNames = [],\n\tvariablesData,\n\telement,\n\tfooterDirection,\n}) => {\n\tconst [name, setName] = useState(initial?.name ?? '');\n\tconst [instructions, setInstructions] = useState(initial?.instructions ?? '');\n\t// New tools start with the scheme pre-filled so the user only types the host.\n\tconst [url, setUrl] = useState(initial?.url ?? 'https://');\n\tconst [method, setMethod] = useState<RestApiMethod>(\n\t\tinitial?.method ?? 'POST',\n\t);\n\tconst [headers, setHeaders] = useState<RestApiHeader[]>(\n\t\tinitial?.headers ?? [{ key: '', value: '' }],\n\t);\n\tconst [requestBody, setRequestBody] = useState(initial?.requestBody ?? '');\n\tconst [responseSample, setResponseSample] = useState(\n\t\tinitial?.responseSample ?? '',\n\t);\n\tconst [saving, setSaving] = useState(false);\n\n\t// Stable per-row identity for React keys, parallel to `headers`. The value\n\t// field is an uncontrolled editor, so a row must keep its mount across\n\t// sibling add/remove — index-based keys would remount every row (dropping\n\t// focus mid-edit) or let a deleted row's text linger in a reused neighbour.\n\tconst headerIdsRef = useRef<number[]>(\n\t\t(initial?.headers ?? [{ key: '', value: '' }]).map(\n\t\t\t(_h: RestApiHeader, i: number) => i,\n\t\t),\n\t);\n\tconst nextHeaderIdRef = useRef(headerIdsRef.current.length);\n\n\tconst patchHeader = (i: number, patch: Partial<RestApiHeader>) =>\n\t\tsetHeaders((prev) =>\n\t\t\tprev.map((h, idx) => (idx === i ? { ...h, ...patch } : h)),\n\t\t);\n\tconst addHeader = () => {\n\t\theaderIdsRef.current = [...headerIdsRef.current, nextHeaderIdRef.current];\n\t\tnextHeaderIdRef.current += 1;\n\t\tsetHeaders((prev) => [...prev, { key: '', value: '' }]);\n\t};\n\tconst removeHeader = (i: number) => {\n\t\theaderIdsRef.current = headerIdsRef.current.filter((_, idx) => idx !== i);\n\t\tsetHeaders((prev) => prev.filter((_, idx) => idx !== i));\n\t};\n\n\tconst nameTrimmed = name.trim();\n\t// Case-insensitive: two tools can't share a name (the LLM references them by it).\n\tconst isDuplicateName =\n\t\tnameTrimmed.length > 0 &&\n\t\texistingNames.some(\n\t\t\t(n) => n.trim().toLowerCase() === nameTrimmed.toLowerCase(),\n\t\t);\n\tconst urlTrimmed = url.trim();\n\t// Save needs a real endpoint, but don't flash the error while the field still\n\t// holds its pristine \"https://\" seed — only once the user has typed past it.\n\t// A URL that interpolates variables can't be parsed literally (braces are\n\t// invalid URL characters) — accept it once a scheme + something follows;\n\t// it only becomes a concrete URL after runtime substitution.\n\tconst urlUsesVariables = urlTrimmed.includes('{{variable:');\n\tconst urlOk = urlUsesVariables\n\t\t? /^https?:\\/\\/./.test(urlTrimmed)\n\t\t: isValidHttpUrl(urlTrimmed);\n\tconst isUrlInvalid =\n\t\turlTrimmed.length > 0 && urlTrimmed !== 'https://' && !urlOk;\n\tconst canSave =\n\t\tnameTrimmed.length > 0 &&\n\t\turlOk &&\n\t\t!isDuplicateName &&\n\t\t// The editor's characterLimit is soft (a paste may exceed it, rendered\n\t\t// grey) — gate the save so over-limit instructions can't be persisted.\n\t\tinstructions.length <= charLimits.instructions;\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst config: RestApiToolConfig = {\n\t\t\tid: initial?.id ?? `restapi_${Date.now().toString(36)}`,\n\t\t\tname: name.trim(),\n\t\t\tinstructions,\n\t\t\turl: url.trim(),\n\t\t\tmethod,\n\t\t\t// Drop fully-empty header rows.\n\t\t\theaders: headers.filter((h) => h.key.trim() || h.value.trim()),\n\t\t\trequestBody,\n\t\t\tresponseSample,\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\treturn (\n\t\t<SideModal\n\t\t\theader=\"Rest API\"\n\t\t\tcloseOnEscapeKey={false}\n\t\t\tzIndex={zIndex}\n\t\t\telement={element}\n\t\t\tfooterDirection={footerDirection}\n\t\t\theaderCustomComponent={\n\t\t\t\t<DrawerHeaderText\n\t\t\t\t\ttitle=\"Rest API\"\n\t\t\t\t\tsubtitle=\"Connect to any API endpoint. Define the request and a sample response for the agent to reference.\"\n\t\t\t\t/>\n\t\t\t}\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': 'restapi-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': 'restapi-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<Input\n\t\t\t\tdata-test=\"restapi-name\"\n\t\t\t\tvariant=\"small\"\n\t\t\t\tlabelText=\"Name\"\n\t\t\t\tlabelTextBold\n\t\t\t\tplaceholder=\"Enter action name\"\n\t\t\t\tvalue={name}\n\t\t\t\tmaxCharLimit={charLimits.name}\n\t\t\t\tstate={isDuplicateName ? 'invalid' : undefined}\n\t\t\t\terrorMessage={\n\t\t\t\t\tisDuplicateName ? 'A tool with this name already exists' : undefined\n\t\t\t\t}\n\t\t\t\tonChangeText={setName}\n\t\t\t/>\n\n\t\t\t<ToolInstructionsField\n\t\t\t\tdata-test=\"restapi-instructions\"\n\t\t\t\tlabel=\"Instructions\"\n\t\t\t\tvalue={instructions}\n\t\t\t\tonChange={setInstructions}\n\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\tplaceholder=\"Describe how should the LLM generate the rest API\"\n\t\t\t\tonImprove={onImprove}\n\t\t\t\tvariablesData={variablesData}\n\t\t\t/>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<VariableInlineField\n\t\t\t\t\tdata-test=\"restapi-url\"\n\t\t\t\t\tlabel=\"Request URL\"\n\t\t\t\t\tplaceholder=\"https://\"\n\t\t\t\t\tvalue={url}\n\t\t\t\t\tonChange={setUrl}\n\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t/>\n\t\t\t\t{/* VariableInlineField has no invalid state of its own — surface the\n\t\t\t\t URL validation (from main) as a caption below the field. */}\n\t\t\t\t{isUrlInvalid && (\n\t\t\t\t\t<BodyCaption color={COLORS.content.negative}>\n\t\t\t\t\t\tEnter a valid URL (including https://)\n\t\t\t\t\t</BodyCaption>\n\t\t\t\t)}\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>HTTP method</TitleSmall>\n\t\t\t\t<Dropdown\n\t\t\t\t\tdata-test=\"restapi-method\"\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\tdropdownWidth=\"399px\"\n\t\t\t\t\toptions={METHOD_OPTIONS}\n\t\t\t\t\tdefaultOptions={[{ label: method, value: method }]}\n\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\tsetMethod(v as RestApiMethod);\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Headers</TitleSmall>\n\t\t\t\t{headers.map((h, i) => (\n\t\t\t\t\t<HeaderRow\n\t\t\t\t\t\tkey={headerIdsRef.current[i]}\n\t\t\t\t\t\tdata-test={`restapi-header-${i}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tvariant=\"small\"\n\t\t\t\t\t\t\thideInputHeader\n\t\t\t\t\t\t\tplaceholder=\"Enter name\"\n\t\t\t\t\t\t\tvalue={h.key}\n\t\t\t\t\t\t\tonChangeText={(v) => patchHeader(i, { key: v })}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<VariableInlineField\n\t\t\t\t\t\t\tplaceholder=\"Enter value\"\n\t\t\t\t\t\t\tvalue={h.value}\n\t\t\t\t\t\t\tonChange={(v) => patchHeader(i, { value: v })}\n\t\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<IconBtn\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-label=\"Remove header\"\n\t\t\t\t\t\t\tdata-test={`restapi-header-remove-${i}`}\n\t\t\t\t\t\t\tonClick={() => removeHeader(i)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<DeleteIcon\n\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</IconBtn>\n\t\t\t\t\t</HeaderRow>\n\t\t\t\t))}\n\t\t\t\t<AddHeaderRow>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tdata-test=\"restapi-add-header\"\n\t\t\t\t\t\tbuttonType=\"dashRegular\"\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\tLeadingIcon={PlusIcon}\n\t\t\t\t\t\tbuttonText=\"Add header\"\n\t\t\t\t\t\tonClick={addHeader}\n\t\t\t\t\t/>\n\t\t\t\t</AddHeaderRow>\n\t\t\t</FieldBlock>\n\n\t\t\t{/* Variables intentionally NOT wired here (yet) — the JSON editors are\n\t\t\t plain code fields; @ types a literal @. */}\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Request </TitleSmall>\n\t\t\t\t<BikEditor\n\t\t\t\t\tfeatures={{ jsonMode: true }}\n\t\t\t\t\tinitialContent={requestBody}\n\t\t\t\t\tstyle={JsonFieldBox}\n\t\t\t\t\tplaceholder=\"Type or paste JSON here\"\n\t\t\t\t\tonChange={(c) => setRequestBody(c.text)}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"240px\"\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Response </TitleSmall>\n\t\t\t\t<BikEditor\n\t\t\t\t\tfeatures={{ jsonMode: true }}\n\t\t\t\t\tstyle={JsonFieldBox}\n\t\t\t\t\tinitialContent={responseSample}\n\t\t\t\t\tplaceholder=\"Type or paste JSON here\"\n\t\t\t\t\tonChange={(c) => setResponseSample(c.text)}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"240px\"\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\t\t</SideModal>\n\t);\n};\n\n// Fixed tracks (name / value / delete): minmax(0, …) lets the fields shrink\n// below their content width, so a long value scrolls inside its field and the\n// delete button can never be pushed off the row.\nconst HeaderRow = styled.div`\n\tdisplay: grid;\n\tgrid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) 32px;\n\talign-items: center;\n\tgap: 8px;\n`;\n\nconst AddHeaderRow = styled.div`\n\tdisplay: flex;\n`;\n\nconst IconBtn = styled.button`\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-shrink: 0;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbackground: ${COLORS.surface.standard};\n\tcursor: pointer;\n\n\t&:hover {\n\t\tborder-color: ${COLORS.content.secondary};\n\t}\n`;\n\nexport const JsonFieldBox = {\n\tborderRadius: '4px',\n\toverflow: 'hidden',\n};\n"],"names":["METHODS","METHOD_OPTIONS","m","isValidHttpUrl","value","host","RestApiToolPanel","onClose","onSave","initial","onImprove","charLimits","AGENT_CHAR_LIMITS","zIndex","existingNames","variablesData","element","footerDirection","name","setName","useState","instructions","setInstructions","url","setUrl","method","setMethod","headers","setHeaders","requestBody","setRequestBody","responseSample","setResponseSample","saving","setSaving","headerIdsRef","useRef","_h","i","nextHeaderIdRef","patchHeader","patch","prev","idx","addHeader","removeHeader","_","nameTrimmed","isDuplicateName","n","urlTrimmed","urlOk","isUrlInvalid","canSave","jsxs","SideModal","jsx","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","config","h","result","Input","ToolInstructionsField","FieldBlock","VariableInlineField","BodyCaption","COLORS","TitleSmall","Dropdown","opt","v","unwrapDropdownValue","HeaderRow","IconBtn","DeleteIcon","AddHeaderRow","Button","PlusIcon","BikEditor","JsonFieldBox","c","styled"],"mappings":"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"}
|
|
@@ -12,8 +12,6 @@ export { MentionPicker } from './components/MentionPicker';
|
|
|
12
12
|
export { AiTextArea } from './components/AiTextArea';
|
|
13
13
|
export { ToolInstructionsField } from './components/ToolInstructionsField';
|
|
14
14
|
export { DrawerHeaderText } from './components/DrawerHeaderText';
|
|
15
|
-
export { HandoverMethodSection } from './components/HandoverMethodSection';
|
|
16
|
-
export type { HandoverMethodSectionProps } from './components/HandoverMethodSection';
|
|
17
15
|
export { useAgentDraft } from './hooks/useAgentDraft';
|
|
18
16
|
export type { AgentDraft } from './hooks/useAgentDraft';
|
|
19
17
|
export { AGENT_CHAR_LIMITS } from './constants/charLimits';
|
|
@@ -5,9 +5,8 @@ import { default as React } from 'react';
|
|
|
5
5
|
* **Manifest** (and any other host) keeps the original single free-text field:
|
|
6
6
|
* the method is implicit and the consumer always sends the seeded `'default'`.
|
|
7
7
|
*
|
|
8
|
-
* **BIK** picks a handover *method* first
|
|
9
|
-
*
|
|
10
|
-
* and links out to where those defaults live; "Custom instructions" is
|
|
8
|
+
* **BIK** picks a handover *method* first. "Use default settings" is selected by
|
|
9
|
+
* default and links out to where those defaults live; "Custom instructions" is
|
|
11
10
|
* deliberately disabled until that flow is built, so the free-text field only
|
|
12
11
|
* appears for an agent already saved with a non-default method.
|
|
13
12
|
*/
|
|
@@ -1,46 +1,132 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
import { jsxs as t, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import x from "../../../assets/icons/RedirectToNew.svg.js";
|
|
3
|
+
import { RadioButton as m } from "../../radioButton/RadioButton.js";
|
|
4
|
+
import { TitleSmall as c, BodyCaption as p } from "../../TypographyStyle.js";
|
|
5
|
+
import { COLORS as a, BASE_COLORS as v } from "../../../constants/Theme.js";
|
|
6
|
+
import { SectionBodyWrap as u, FieldBlock as T, CardRow as w, RadioCard as f, RadioCardText as g, ChannelsLink as H } from "../AgentBuilder.styled.js";
|
|
7
|
+
import { AiTextArea as A } from "../components/AiTextArea.js";
|
|
8
|
+
import { StepSectionHeader as C } from "../components/StepSectionHeader.js";
|
|
9
|
+
import { STEP_DEFINITIONS as B } from "../constants/steps.js";
|
|
10
|
+
import { useAgentBuilderContext as S } from "../context/AgentBuilderContext.js";
|
|
11
|
+
import { appTypeLabel as O } from "../utils/mentionSerialization.js";
|
|
12
|
+
import { Tooltip as R } from "../../tooltips/Tooltip.js";
|
|
13
|
+
const d = B[3], h = "default", K = () => {
|
|
14
|
+
const { value: l, patch: i, applicationType: s, onSmartAgentHandover: o } = S(), { handover: n } = l, b = O(s) === "BIK", r = n.method !== h;
|
|
15
|
+
return b ? /* @__PURE__ */ t("div", { className: "bik-agent-step bik-agent-step--handover", children: [
|
|
16
|
+
/* @__PURE__ */ e(C, { title: d.title, helper: d.helper }),
|
|
17
|
+
/* @__PURE__ */ t(u, { children: [
|
|
18
|
+
/* @__PURE__ */ t(T, { children: [
|
|
19
|
+
/* @__PURE__ */ e(c, { color: a.content.primary, children: "Handover method" }),
|
|
20
|
+
/* @__PURE__ */ t(w, { children: [
|
|
21
|
+
/* @__PURE__ */ t(
|
|
22
|
+
f,
|
|
23
|
+
{
|
|
24
|
+
"data-test": "handover-method-default",
|
|
25
|
+
type: "button",
|
|
26
|
+
selected: !r,
|
|
27
|
+
onClick: () => i({ handover: { ...n, method: h } }),
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ e(
|
|
30
|
+
m,
|
|
31
|
+
{
|
|
32
|
+
isActive: !r,
|
|
33
|
+
onValueChange: () => i({ handover: { ...n, method: h } }),
|
|
34
|
+
skipSelectingOff: !0,
|
|
35
|
+
activeColor: v.brand[800]
|
|
36
|
+
}
|
|
37
|
+
),
|
|
38
|
+
/* @__PURE__ */ t(g, { children: [
|
|
39
|
+
/* @__PURE__ */ e(c, { color: a.content.primary, children: "Use default settings" }),
|
|
40
|
+
/* @__PURE__ */ t(p, { color: a.content.secondary, children: [
|
|
41
|
+
"As defined in",
|
|
42
|
+
" ",
|
|
43
|
+
o ? /* @__PURE__ */ t(
|
|
44
|
+
H,
|
|
45
|
+
{
|
|
46
|
+
"data-test": "handover-smart-agent-link",
|
|
47
|
+
type: "button",
|
|
48
|
+
onClick: (k) => {
|
|
49
|
+
k.stopPropagation(), o();
|
|
50
|
+
},
|
|
51
|
+
style: { display: "inline-flex" },
|
|
52
|
+
children: [
|
|
53
|
+
"Smart agent handover",
|
|
54
|
+
/* @__PURE__ */ e(x, { width: 12, height: 12 })
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
) : "Smart agent handover"
|
|
58
|
+
] })
|
|
59
|
+
] })
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
/* @__PURE__ */ e(
|
|
64
|
+
R,
|
|
65
|
+
{
|
|
66
|
+
body: "Custom handover rules are coming soon. For now this agent follows your smart agent handover settings.",
|
|
67
|
+
placement: "top",
|
|
68
|
+
children: /* @__PURE__ */ e(
|
|
69
|
+
"span",
|
|
70
|
+
{
|
|
71
|
+
style: {
|
|
72
|
+
flex: 1,
|
|
73
|
+
display: "flex",
|
|
74
|
+
cursor: "not-allowed"
|
|
75
|
+
},
|
|
76
|
+
children: /* @__PURE__ */ t(
|
|
77
|
+
f,
|
|
78
|
+
{
|
|
79
|
+
"data-test": "handover-method-custom",
|
|
80
|
+
type: "button",
|
|
81
|
+
disabled: !0,
|
|
82
|
+
selected: r,
|
|
83
|
+
children: [
|
|
84
|
+
/* @__PURE__ */ e(
|
|
85
|
+
m,
|
|
86
|
+
{
|
|
87
|
+
isActive: r,
|
|
88
|
+
isDisabled: !0,
|
|
89
|
+
onValueChange: () => {
|
|
90
|
+
},
|
|
91
|
+
skipSelectingOff: !0,
|
|
92
|
+
activeColor: v.brand[800]
|
|
93
|
+
}
|
|
94
|
+
),
|
|
95
|
+
/* @__PURE__ */ t(g, { children: [
|
|
96
|
+
/* @__PURE__ */ e(c, { color: a.content.inactive, children: "Custom instructions" }),
|
|
97
|
+
/* @__PURE__ */ e(p, { color: a.content.inactive, children: "Write custom handover rules for this agent." })
|
|
98
|
+
] })
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
] })
|
|
107
|
+
] }),
|
|
108
|
+
r && /* @__PURE__ */ e(y, {})
|
|
23
109
|
] })
|
|
24
|
-
] }) : /* @__PURE__ */
|
|
25
|
-
/* @__PURE__ */ e(
|
|
26
|
-
/* @__PURE__ */ e(
|
|
110
|
+
] }) : /* @__PURE__ */ t("div", { className: "bik-agent-step bik-agent-step--handover", children: [
|
|
111
|
+
/* @__PURE__ */ e(C, { title: d.title, helper: d.helper }),
|
|
112
|
+
/* @__PURE__ */ e(u, { children: /* @__PURE__ */ e(y, {}) })
|
|
27
113
|
] });
|
|
28
|
-
},
|
|
29
|
-
const { value:
|
|
114
|
+
}, y = () => {
|
|
115
|
+
const { value: l, patch: i, charLimits: s } = S(), { handover: o } = l;
|
|
30
116
|
return /* @__PURE__ */ e(
|
|
31
|
-
|
|
117
|
+
A,
|
|
32
118
|
{
|
|
33
119
|
"data-test": "handover-when",
|
|
34
120
|
label: "Handover when",
|
|
35
121
|
value: o.when,
|
|
36
|
-
onChange: (
|
|
37
|
-
maxLength:
|
|
122
|
+
onChange: (n) => i({ handover: { ...o, when: n } }),
|
|
123
|
+
maxLength: s.handoverWhen,
|
|
38
124
|
placeholder: "e.g. Hand over if the customer is angry or asks for a human three times. Hand over if the order value exceeds ₹5,000.",
|
|
39
125
|
minHeight: "120px"
|
|
40
126
|
}
|
|
41
127
|
);
|
|
42
128
|
};
|
|
43
129
|
export {
|
|
44
|
-
|
|
130
|
+
K as Step4HandoverRules
|
|
45
131
|
};
|
|
46
132
|
//# sourceMappingURL=Step4HandoverRules.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Step4HandoverRules.js","sources":["../../../../../src/components/agent-builder/steps/Step4HandoverRules.tsx"],"sourcesContent":["import React from 'react';\nimport type { HandoverMethod } from '../AgentBuilder.model';\nimport { SectionBodyWrap } from '../AgentBuilder.styled';\nimport { AiTextArea } from '../components/AiTextArea';\nimport { HandoverMethodSection } from '../components/HandoverMethodSection';\nimport { StepSectionHeader } from '../components/StepSectionHeader';\nimport { STEP_DEFINITIONS } from '../constants/steps';\nimport { useAgentBuilderContext } from '../context/AgentBuilderContext';\nimport { appTypeLabel } from '../utils/mentionSerialization';\n\nconst STEP = STEP_DEFINITIONS[3];\n\n/**\n * The stored `handover.method` that means \"inherit the store's smart-agent\n * handover settings\" — the BIK default, and the only method selectable today.\n */\nconst DEFAULT_METHOD: HandoverMethod = 'default';\n\n/**\n * Step 4.\n *\n * **Manifest** (and any other host) keeps the original single free-text field:\n * the method is implicit and the consumer always sends the seeded `'default'`.\n *\n * **BIK** picks a handover *method* first, via the shared\n * {@link HandoverMethodSection}: \"Use default settings\" is selected by default\n * and links out to where those defaults live; \"Custom instructions\" is\n * deliberately disabled until that flow is built, so the free-text field only\n * appears for an agent already saved with a non-default method.\n */\nexport const Step4HandoverRules: React.FC = () => {\n\tconst { value, patch, applicationType, onSmartAgentHandover } =\n\t\tuseAgentBuilderContext();\n\tconst { handover } = value;\n\n\tconst isBik = appTypeLabel(applicationType) === 'BIK';\n\t// Anything other than the default method means the merchant is on custom\n\t// instructions, so the free-text field is what they need to see.\n\tconst usesCustom = handover.method !== DEFAULT_METHOD;\n\n\tif (!isBik) {\n\t\treturn (\n\t\t\t<div className=\"bik-agent-step bik-agent-step--handover\">\n\t\t\t\t<StepSectionHeader title={STEP.title} helper={STEP.helper} />\n\t\t\t\t<SectionBodyWrap>\n\t\t\t\t\t<HandoverWhenField />\n\t\t\t\t</SectionBodyWrap>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"bik-agent-step bik-agent-step--handover\">\n\t\t\t<StepSectionHeader title={STEP.title} helper={STEP.helper} />\n\n\t\t\t<SectionBodyWrap>\n\t\t\t\t<HandoverMethodSection\n\t\t\t\t\tmethod={handover.method}\n\t\t\t\t\tonMethodChange={(method) =>\n\t\t\t\t\t\tpatch({ handover: { ...handover, method } })\n\t\t\t\t\t}\n\t\t\t\t\tonSmartAgentHandover={onSmartAgentHandover}\n\t\t\t\t/>\n\n\t\t\t\t{usesCustom && <HandoverWhenField />}\n\t\t\t</SectionBodyWrap>\n\t\t</div>\n\t);\n};\n\n/** The free-text \"Handover when\" field, shared by both layouts. */\nconst HandoverWhenField: React.FC = () => {\n\tconst { value, patch, charLimits } = useAgentBuilderContext();\n\tconst { handover } = value;\n\n\treturn (\n\t\t<AiTextArea\n\t\t\tdata-test=\"handover-when\"\n\t\t\tlabel=\"Handover when\"\n\t\t\tvalue={handover.when}\n\t\t\tonChange={(text) => patch({ handover: { ...handover, when: text } })}\n\t\t\tmaxLength={charLimits.handoverWhen}\n\t\t\tplaceholder=\"e.g. Hand over if the customer is angry or asks for a human three times. Hand over if the order value exceeds ₹5,000.\"\n\t\t\tminHeight=\"120px\"\n\t\t/>\n\t);\n};\n"],"names":["STEP","STEP_DEFINITIONS","DEFAULT_METHOD","Step4HandoverRules","value","patch","applicationType","onSmartAgentHandover","useAgentBuilderContext","handover","isBik","appTypeLabel","usesCustom","jsxs","jsx","StepSectionHeader","SectionBodyWrap","HandoverMethodSection","method","HandoverWhenField","charLimits","AiTextArea","text"],"mappings":";;;;;;;;AAUA,MAAMA,IAAOC,EAAiB,CAAC,GAMzBC,IAAiC,WAc1BC,IAA+B,MAAM;AACjD,QAAM,EAAE,OAAAC,GAAO,OAAAC,GAAO,iBAAAC,GAAiB,sBAAAC,EAAA,IACtCC,EAAA,GACK,EAAE,UAAAC,MAAaL,GAEfM,IAAQC,EAAaL,CAAe,MAAM,OAG1CM,IAAaH,EAAS,WAAWP;AAEvC,SAAKQ,IAYJ,gBAAAG,EAAC,OAAA,EAAI,WAAU,2CACd,UAAA;AAAA,IAAA,gBAAAC,EAACC,KAAkB,OAAOf,EAAK,OAAO,QAAQA,EAAK,QAAQ;AAAA,sBAE1DgB,GAAA,EACA,UAAA;AAAA,MAAA,gBAAAF;AAAA,QAACG;AAAA,QAAA;AAAA,UACA,QAAQR,EAAS;AAAA,UACjB,gBAAgB,CAACS,MAChBb,EAAM,EAAE,UAAU,EAAE,GAAGI,GAAU,QAAAS,EAAA,GAAU;AAAA,UAE5C,sBAAAX;AAAA,QAAA;AAAA,MAAA;AAAA,MAGAK,uBAAeO,GAAA,CAAA,CAAkB;AAAA,IAAA,EAAA,CACnC;AAAA,EAAA,GACD,IAxBC,gBAAAN,EAAC,OAAA,EAAI,WAAU,2CACd,UAAA;AAAA,IAAA,gBAAAC,EAACC,KAAkB,OAAOf,EAAK,OAAO,QAAQA,EAAK,QAAQ;AAAA,IAC3D,gBAAAc,EAACE,GAAA,EACA,UAAA,gBAAAF,EAACK,GAAA,CAAA,CAAkB,EAAA,CACpB;AAAA,EAAA,GACD;AAqBH,GAGMA,IAA8B,MAAM;AACzC,QAAM,EAAE,OAAAf,GAAO,OAAAC,GAAO,YAAAe,EAAA,IAAeZ,EAAA,GAC/B,EAAE,UAAAC,MAAaL;AAErB,SACC,gBAAAU;AAAA,IAACO;AAAA,IAAA;AAAA,MACA,aAAU;AAAA,MACV,OAAM;AAAA,MACN,OAAOZ,EAAS;AAAA,MAChB,UAAU,CAACa,MAASjB,EAAM,EAAE,UAAU,EAAE,GAAGI,GAAU,MAAMa,EAAA,GAAQ;AAAA,MACnE,WAAWF,EAAW;AAAA,MACtB,aAAY;AAAA,MACZ,WAAU;AAAA,IAAA;AAAA,EAAA;AAGb;"}
|
|
1
|
+
{"version":3,"file":"Step4HandoverRules.js","sources":["../../../../../src/components/agent-builder/steps/Step4HandoverRules.tsx"],"sourcesContent":["import RedirectIcon from '@src/assets/icons/RedirectToNew.svg';\nimport React from 'react';\nimport { RadioButton } from '@src/components/radioButton/RadioButton';\nimport { Tooltip } from '@src/components/tooltips';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { BASE_COLORS, COLORS } from '@src/constants/Theme';\nimport type { HandoverMethod } from '../AgentBuilder.model';\nimport {\n\tCardRow,\n\tChannelsLink,\n\tFieldBlock,\n\tRadioCard,\n\tRadioCardText,\n\tSectionBodyWrap,\n} from '../AgentBuilder.styled';\nimport { AiTextArea } from '../components/AiTextArea';\nimport { StepSectionHeader } from '../components/StepSectionHeader';\nimport { STEP_DEFINITIONS } from '../constants/steps';\nimport { useAgentBuilderContext } from '../context/AgentBuilderContext';\nimport { appTypeLabel } from '../utils/mentionSerialization';\n\nconst STEP = STEP_DEFINITIONS[3];\n\n/**\n * The stored `handover.method` that means \"inherit the store's smart-agent\n * handover settings\" — the BIK default, and the only method selectable today.\n */\nconst DEFAULT_METHOD: HandoverMethod = 'default';\n\n/**\n * Step 4.\n *\n * **Manifest** (and any other host) keeps the original single free-text field:\n * the method is implicit and the consumer always sends the seeded `'default'`.\n *\n * **BIK** picks a handover *method* first. \"Use default settings\" is selected by\n * default and links out to where those defaults live; \"Custom instructions\" is\n * deliberately disabled until that flow is built, so the free-text field only\n * appears for an agent already saved with a non-default method.\n */\nexport const Step4HandoverRules: React.FC = () => {\n\tconst { value, patch, applicationType, onSmartAgentHandover } =\n\t\tuseAgentBuilderContext();\n\tconst { handover } = value;\n\n\tconst isBik = appTypeLabel(applicationType) === 'BIK';\n\t// Anything other than the default method means the merchant is on custom\n\t// instructions, so the free-text field is what they need to see.\n\tconst usesCustom = handover.method !== DEFAULT_METHOD;\n\n\tif (!isBik) {\n\t\treturn (\n\t\t\t<div className=\"bik-agent-step bik-agent-step--handover\">\n\t\t\t\t<StepSectionHeader title={STEP.title} helper={STEP.helper} />\n\t\t\t\t<SectionBodyWrap>\n\t\t\t\t\t<HandoverWhenField />\n\t\t\t\t</SectionBodyWrap>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"bik-agent-step bik-agent-step--handover\">\n\t\t\t<StepSectionHeader title={STEP.title} helper={STEP.helper} />\n\n\t\t\t<SectionBodyWrap>\n\t\t\t\t<FieldBlock>\n\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\tHandover method\n\t\t\t\t\t</TitleSmall>\n\n\t\t\t\t\t<CardRow>\n\t\t\t\t\t\t<RadioCard\n\t\t\t\t\t\t\tdata-test=\"handover-method-default\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tselected={!usesCustom}\n\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\tpatch({ handover: { ...handover, method: DEFAULT_METHOD } })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<RadioButton\n\t\t\t\t\t\t\t\tisActive={!usesCustom}\n\t\t\t\t\t\t\t\tonValueChange={() =>\n\t\t\t\t\t\t\t\t\tpatch({ handover: { ...handover, method: DEFAULT_METHOD } })\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tskipSelectingOff\n\t\t\t\t\t\t\t\tactiveColor={BASE_COLORS.brand['800']}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<RadioCardText>\n\t\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\tUse default settings\n\t\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\tAs defined in{' '}\n\t\t\t\t\t\t\t\t\t{onSmartAgentHandover ? (\n\t\t\t\t\t\t\t\t\t\t<ChannelsLink\n\t\t\t\t\t\t\t\t\t\t\tdata-test=\"handover-smart-agent-link\"\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t// The link sits inside the card's own click target, so\n\t\t\t\t\t\t\t\t\t\t\t// stop the click bubbling up and re-selecting the card.\n\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\tonSmartAgentHandover();\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ display: 'inline-flex' }}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tSmart agent handover\n\t\t\t\t\t\t\t\t\t\t\t<RedirectIcon width={12} height={12} />\n\t\t\t\t\t\t\t\t\t\t</ChannelsLink>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t'Smart agent handover'\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t</RadioCardText>\n\t\t\t\t\t\t</RadioCard>\n\n\t\t\t\t\t\t{/* Custom handover rules aren't built yet — the card is shown so the\n\t\t\t\t\t\t merchant knows it's coming, but it can't be selected. */}\n\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\tbody=\"Custom handover rules are coming soon. For now this agent follows your smart agent handover settings.\"\n\t\t\t\t\t\t\tplacement=\"top\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{/* A disabled <button> fires no mouse events, so the tooltip would\n\t\t\t\t\t\t\t never open on the card itself — the span is the hover target\n\t\t\t\t\t\t\t (same wrapper IconButton uses for its disabled tooltip). It also\n\t\t\t\t\t\t\t has to carry the card's `flex: 1`, since it is now the flex item. */}\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\t\t\t\tdisplay: 'flex',\n\t\t\t\t\t\t\t\t\tcursor: 'not-allowed',\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<RadioCard\n\t\t\t\t\t\t\t\t\tdata-test=\"handover-method-custom\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled\n\t\t\t\t\t\t\t\t\tselected={usesCustom}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<RadioButton\n\t\t\t\t\t\t\t\t\t\tisActive={usesCustom}\n\t\t\t\t\t\t\t\t\t\tisDisabled\n\t\t\t\t\t\t\t\t\t\tonValueChange={() => undefined}\n\t\t\t\t\t\t\t\t\t\tskipSelectingOff\n\t\t\t\t\t\t\t\t\t\tactiveColor={BASE_COLORS.brand['800']}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<RadioCardText>\n\t\t\t\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.inactive}>\n\t\t\t\t\t\t\t\t\t\t\tCustom instructions\n\t\t\t\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.inactive}>\n\t\t\t\t\t\t\t\t\t\t\tWrite custom handover rules for this agent.\n\t\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t\t</RadioCardText>\n\t\t\t\t\t\t\t\t</RadioCard>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t</CardRow>\n\t\t\t\t</FieldBlock>\n\n\t\t\t\t{usesCustom && <HandoverWhenField />}\n\t\t\t</SectionBodyWrap>\n\t\t</div>\n\t);\n};\n\n/** The free-text \"Handover when\" field, shared by both layouts. */\nconst HandoverWhenField: React.FC = () => {\n\tconst { value, patch, charLimits } = useAgentBuilderContext();\n\tconst { handover } = value;\n\n\treturn (\n\t\t<AiTextArea\n\t\t\tdata-test=\"handover-when\"\n\t\t\tlabel=\"Handover when\"\n\t\t\tvalue={handover.when}\n\t\t\tonChange={(text) => patch({ handover: { ...handover, when: text } })}\n\t\t\tmaxLength={charLimits.handoverWhen}\n\t\t\tplaceholder=\"e.g. Hand over if the customer is angry or asks for a human three times. Hand over if the order value exceeds ₹5,000.\"\n\t\t\tminHeight=\"120px\"\n\t\t/>\n\t);\n};\n"],"names":["STEP","STEP_DEFINITIONS","DEFAULT_METHOD","Step4HandoverRules","value","patch","applicationType","onSmartAgentHandover","useAgentBuilderContext","handover","isBik","appTypeLabel","usesCustom","jsxs","jsx","StepSectionHeader","SectionBodyWrap","FieldBlock","TitleSmall","COLORS","CardRow","RadioCard","RadioButton","BASE_COLORS","RadioCardText","BodyCaption","ChannelsLink","event","RedirectIcon","Tooltip","HandoverWhenField","charLimits","AiTextArea","text"],"mappings":"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"}
|