@bikdotai/bik-component-library 0.0.853 → 0.0.855
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/add-variableV2/AddDataPill.js +10 -0
- package/dist/cjs/components/add-variableV2/AddDataPill.js.map +1 -0
- package/dist/cjs/components/agent-builder/AgentBuilder.js +1 -1
- package/dist/cjs/components/agent-builder/AgentBuilder.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js +11 -11
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +5 -5
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionEditor.js +7 -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 +41 -14
- package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js +6 -5
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +2 -2
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/VariableInlineField.js +65 -0
- package/dist/cjs/components/agent-builder/components/VariableInlineField.js.map +1 -0
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js +10 -0
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
- package/dist/cjs/components/agent-builder/constants/tools.js +1 -1
- package/dist/cjs/components/agent-builder/constants/tools.js.map +1 -1
- package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js +1 -1
- package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.js +4 -4
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.js.map +1 -1
- package/dist/cjs/components/toaster/Toaster.js +1 -1
- package/dist/cjs/components/toaster/Toaster.js.map +1 -1
- package/dist/cjs/components/toaster/Toaster.styled.js +7 -7
- package/dist/cjs/components/toaster/Toaster.styled.js.map +1 -1
- package/dist/cjs/components/variable-picker-v3/Content.js +1 -1
- package/dist/cjs/components/variable-picker-v3/Content.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 +8 -0
- package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
- package/dist/cjs/editor/BikEditor.types.js.map +1 -1
- package/dist/cjs/editor/extensions/mention/MentionDropdown.js +1 -1
- package/dist/cjs/editor/extensions/mention/MentionDropdown.js.map +1 -1
- package/dist/cjs/editor/extensions/mention/MentionExtension.js +1 -1
- package/dist/cjs/editor/extensions/mention/MentionExtension.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/add-variableV2/AddDataPill.d.ts +24 -0
- package/dist/esm/components/add-variableV2/AddDataPill.js +33 -0
- package/dist/esm/components/add-variableV2/AddDataPill.js.map +1 -0
- package/dist/esm/components/add-variableV2/index.d.ts +1 -0
- package/dist/esm/components/agent-builder/AgentBuilder.js +76 -74
- package/dist/esm/components/agent-builder/AgentBuilder.js.map +1 -1
- package/dist/esm/components/agent-builder/AgentBuilder.model.d.ts +8 -0
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.d.ts +8 -0
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +182 -136
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.d.ts +3 -0
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +195 -188
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionEditor.d.ts +12 -0
- package/dist/esm/components/agent-builder/components/MentionEditor.js +144 -103
- package/dist/esm/components/agent-builder/components/MentionEditor.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionField.js +48 -45
- package/dist/esm/components/agent-builder/components/MentionField.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionPicker.d.ts +14 -1
- package/dist/esm/components/agent-builder/components/MentionPicker.js +286 -218
- package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.d.ts +8 -0
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +192 -176
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.d.ts +9 -0
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +67 -48
- 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 +149 -0
- package/dist/esm/components/agent-builder/components/VariableInlineField.js.map +1 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.d.ts +46 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js +118 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
- package/dist/esm/components/agent-builder/constants/tools.d.ts +1 -1
- package/dist/esm/components/agent-builder/constants/tools.js +14 -13
- package/dist/esm/components/agent-builder/constants/tools.js.map +1 -1
- package/dist/esm/components/agent-builder/context/AgentBuilderContext.d.ts +7 -0
- package/dist/esm/components/agent-builder/context/AgentBuilderContext.js +99 -96
- package/dist/esm/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +164 -160
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/mentionSerialization.d.ts +14 -4
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js +54 -36
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js.map +1 -1
- package/dist/esm/components/toaster/Toaster.js +30 -25
- package/dist/esm/components/toaster/Toaster.js.map +1 -1
- package/dist/esm/components/toaster/Toaster.styled.js +5 -5
- package/dist/esm/components/toaster/Toaster.styled.js.map +1 -1
- package/dist/esm/components/variable-picker-v3/Content.js +16 -15
- package/dist/esm/components/variable-picker-v3/Content.js.map +1 -1
- package/dist/esm/editor/BikEditor.js +40 -34
- package/dist/esm/editor/BikEditor.js.map +1 -1
- package/dist/esm/editor/BikEditor.styles.js +20 -12
- 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/dist/esm/editor/extensions/mention/MentionDropdown.js +28 -28
- package/dist/esm/editor/extensions/mention/MentionDropdown.js.map +1 -1
- package/dist/esm/editor/extensions/mention/MentionExtension.js +23 -19
- package/dist/esm/editor/extensions/mention/MentionExtension.js.map +1 -1
- package/dist/esm/icons/index.d.ts +25 -25
- package/dist/esm/index.js +543 -541
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,97 +1,109 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { useState as
|
|
5
|
-
import
|
|
6
|
-
import { TitleSmall as
|
|
7
|
-
import { COLORS as
|
|
8
|
-
import { FieldBlock as
|
|
9
|
-
import { AGENT_CHAR_LIMITS as
|
|
10
|
-
import { DRAWER_BODY_STYLE as
|
|
11
|
-
import { ToolInstructionsField as
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
import { jsxs as i, jsx as r } from "react/jsx-runtime";
|
|
2
|
+
import X from "../../../assets/icons/delete.svg.js";
|
|
3
|
+
import Z from "../../../assets/icons/plus.svg.js";
|
|
4
|
+
import { useState as l, useRef as B } from "react";
|
|
5
|
+
import C from "styled-components";
|
|
6
|
+
import { BodyCaption as ee, TitleSmall as u } from "../../TypographyStyle.js";
|
|
7
|
+
import { COLORS as a } from "../../../constants/Theme.js";
|
|
8
|
+
import { FieldBlock as m } from "../AgentBuilder.styled.js";
|
|
9
|
+
import { AGENT_CHAR_LIMITS as te } from "../constants/charLimits.js";
|
|
10
|
+
import { DRAWER_BODY_STYLE as re, DRAWER_HEADER_STYLE as ne, DrawerHeaderText as oe } from "./DrawerHeaderText.js";
|
|
11
|
+
import { ToolInstructionsField as ae } from "./ToolInstructionsField.js";
|
|
12
|
+
import { VariableInlineField as D } from "./VariableInlineField.js";
|
|
13
|
+
import { SideModal as se } from "../../side-modal/SideModal.js";
|
|
14
|
+
import { Input as _ } from "../../input/Input.js";
|
|
15
|
+
import { Dropdown as le } from "../../dropdown/Dropdown.js";
|
|
16
|
+
import { unwrapDropdownValue as ie } from "../../dropdown/utils.js";
|
|
17
|
+
import { Button as de } from "../../button/Button.js";
|
|
18
|
+
import { BikEditor as M } from "../../../editor/BikEditor.js";
|
|
19
|
+
const ce = ["GET", "POST", "PUT", "PATCH", "DELETE"], pe = ce.map((s) => ({
|
|
20
|
+
label: s,
|
|
21
|
+
value: s
|
|
22
|
+
})), me = (s) => {
|
|
23
|
+
if (!/^https?:\/\//i.test(s))
|
|
23
24
|
return !1;
|
|
24
|
-
let
|
|
25
|
+
let d;
|
|
25
26
|
try {
|
|
26
|
-
|
|
27
|
+
d = new URL(s).hostname;
|
|
27
28
|
} catch {
|
|
28
29
|
return !1;
|
|
29
30
|
}
|
|
30
|
-
return
|
|
31
|
-
},
|
|
32
|
-
onClose:
|
|
33
|
-
onSave:
|
|
34
|
-
initial:
|
|
35
|
-
onImprove:
|
|
36
|
-
charLimits:
|
|
37
|
-
zIndex:
|
|
38
|
-
existingNames:
|
|
31
|
+
return d.includes(".") && !d.startsWith(".") && !d.endsWith(".");
|
|
32
|
+
}, _e = ({
|
|
33
|
+
onClose: s,
|
|
34
|
+
onSave: d,
|
|
35
|
+
initial: o,
|
|
36
|
+
onImprove: N,
|
|
37
|
+
charLimits: f = te,
|
|
38
|
+
zIndex: q,
|
|
39
|
+
existingNames: $ = [],
|
|
40
|
+
variablesData: y
|
|
39
41
|
}) => {
|
|
40
|
-
const [
|
|
41
|
-
|
|
42
|
-
), [
|
|
43
|
-
|
|
44
|
-
), [
|
|
45
|
-
|
|
46
|
-
), [
|
|
47
|
-
(o
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
),
|
|
51
|
-
|
|
52
|
-
|
|
42
|
+
const [g, j] = l(o?.name ?? ""), [v, V] = l(o?.instructions ?? ""), [x, W] = l(o?.url ?? "https://"), [T, z] = l(
|
|
43
|
+
o?.method ?? "POST"
|
|
44
|
+
), [H, S] = l(
|
|
45
|
+
o?.headers ?? [{ key: "", value: "" }]
|
|
46
|
+
), [w, F] = l(o?.requestBody ?? ""), [E, G] = l(
|
|
47
|
+
o?.responseSample ?? ""
|
|
48
|
+
), [I, k] = l(!1), c = B(
|
|
49
|
+
(o?.headers ?? [{ key: "", value: "" }]).map(
|
|
50
|
+
(e, t) => t
|
|
51
|
+
)
|
|
52
|
+
), A = B(c.current.length), L = (e, t) => S(
|
|
53
|
+
(n) => n.map((h, Q) => Q === e ? { ...h, ...t } : h)
|
|
54
|
+
), J = () => {
|
|
55
|
+
c.current = [...c.current, A.current], A.current += 1, S((e) => [...e, { key: "", value: "" }]);
|
|
56
|
+
}, Y = (e) => {
|
|
57
|
+
c.current = c.current.filter((t, n) => n !== e), S((t) => t.filter((n, h) => h !== e));
|
|
58
|
+
}, b = g.trim(), R = b.length > 0 && $.some(
|
|
59
|
+
(e) => e.trim().toLowerCase() === b.toLowerCase()
|
|
60
|
+
), p = x.trim(), O = p.includes("{{variable:") ? /^https?:\/\/./.test(p) : me(p), K = 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
|
+
// grey) — gate the save so over-limit instructions can't be persisted.
|
|
62
|
+
v.length <= f.instructions;
|
|
63
|
+
return /* @__PURE__ */ i(
|
|
64
|
+
se,
|
|
53
65
|
{
|
|
54
66
|
header: "Rest API",
|
|
55
67
|
closeOnEscapeKey: !1,
|
|
56
|
-
zIndex:
|
|
57
|
-
headerCustomComponent: /* @__PURE__ */
|
|
58
|
-
|
|
68
|
+
zIndex: q,
|
|
69
|
+
headerCustomComponent: /* @__PURE__ */ r(
|
|
70
|
+
oe,
|
|
59
71
|
{
|
|
60
72
|
title: "Rest API",
|
|
61
73
|
subtitle: "Connect to any API endpoint. Define the request and a sample response for the agent to reference."
|
|
62
74
|
}
|
|
63
75
|
),
|
|
64
76
|
width: "431px",
|
|
65
|
-
headerStyle:
|
|
66
|
-
bodyStyle:
|
|
67
|
-
onClose:
|
|
77
|
+
headerStyle: ne,
|
|
78
|
+
bodyStyle: re,
|
|
79
|
+
onClose: s,
|
|
68
80
|
saveButtonProps: {
|
|
69
81
|
"data-test": "restapi-save",
|
|
70
82
|
buttonText: "Save",
|
|
71
83
|
buttonType: "primary",
|
|
72
84
|
size: "small",
|
|
73
|
-
disabled: !
|
|
74
|
-
isLoading:
|
|
85
|
+
disabled: !P,
|
|
86
|
+
isLoading: I,
|
|
75
87
|
onClick: async () => {
|
|
76
|
-
if (!
|
|
88
|
+
if (!P || I)
|
|
77
89
|
return;
|
|
78
90
|
const e = {
|
|
79
|
-
id:
|
|
80
|
-
name:
|
|
81
|
-
instructions:
|
|
82
|
-
url:
|
|
83
|
-
method:
|
|
91
|
+
id: o?.id ?? `restapi_${Date.now().toString(36)}`,
|
|
92
|
+
name: g.trim(),
|
|
93
|
+
instructions: v,
|
|
94
|
+
url: x.trim(),
|
|
95
|
+
method: T,
|
|
84
96
|
// Drop fully-empty header rows.
|
|
85
|
-
headers:
|
|
86
|
-
requestBody:
|
|
87
|
-
responseSample:
|
|
88
|
-
},
|
|
89
|
-
if (
|
|
90
|
-
|
|
97
|
+
headers: H.filter((n) => n.key.trim() || n.value.trim()),
|
|
98
|
+
requestBody: w,
|
|
99
|
+
responseSample: E
|
|
100
|
+
}, t = d(e);
|
|
101
|
+
if (t && typeof t.then == "function") {
|
|
102
|
+
k(!0);
|
|
91
103
|
try {
|
|
92
|
-
await
|
|
104
|
+
await t;
|
|
93
105
|
} finally {
|
|
94
|
-
|
|
106
|
+
k(!1);
|
|
95
107
|
}
|
|
96
108
|
}
|
|
97
109
|
}
|
|
@@ -101,150 +113,153 @@ const ae = ["GET", "POST", "PUT", "PATCH", "DELETE"], ne = ae.map((a) => ({
|
|
|
101
113
|
buttonText: "Cancel",
|
|
102
114
|
buttonType: "tertiaryGray",
|
|
103
115
|
size: "small",
|
|
104
|
-
onClick:
|
|
116
|
+
onClick: s
|
|
105
117
|
},
|
|
106
118
|
children: [
|
|
107
|
-
/* @__PURE__ */
|
|
108
|
-
|
|
119
|
+
/* @__PURE__ */ r(
|
|
120
|
+
_,
|
|
109
121
|
{
|
|
110
122
|
"data-test": "restapi-name",
|
|
111
123
|
variant: "small",
|
|
112
124
|
labelText: "Name",
|
|
113
125
|
labelTextBold: !0,
|
|
114
126
|
placeholder: "Enter action name",
|
|
115
|
-
value:
|
|
116
|
-
maxCharLimit:
|
|
117
|
-
state:
|
|
118
|
-
errorMessage:
|
|
119
|
-
onChangeText:
|
|
127
|
+
value: g,
|
|
128
|
+
maxCharLimit: f.name,
|
|
129
|
+
state: R ? "invalid" : void 0,
|
|
130
|
+
errorMessage: R ? "A tool with this name already exists" : void 0,
|
|
131
|
+
onChangeText: j
|
|
120
132
|
}
|
|
121
133
|
),
|
|
122
|
-
/* @__PURE__ */
|
|
123
|
-
|
|
134
|
+
/* @__PURE__ */ r(
|
|
135
|
+
ae,
|
|
124
136
|
{
|
|
125
137
|
"data-test": "restapi-instructions",
|
|
126
138
|
label: "Instructions",
|
|
127
|
-
value:
|
|
128
|
-
onChange:
|
|
129
|
-
maxLength:
|
|
139
|
+
value: v,
|
|
140
|
+
onChange: V,
|
|
141
|
+
maxLength: f.instructions,
|
|
130
142
|
placeholder: "Describe how should the LLM generate the rest API",
|
|
131
|
-
onImprove:
|
|
143
|
+
onImprove: N,
|
|
144
|
+
variablesData: y
|
|
132
145
|
}
|
|
133
146
|
),
|
|
134
|
-
/* @__PURE__ */
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
/* @__PURE__ */
|
|
151
|
-
|
|
152
|
-
te,
|
|
147
|
+
/* @__PURE__ */ i(m, { children: [
|
|
148
|
+
/* @__PURE__ */ r(
|
|
149
|
+
D,
|
|
150
|
+
{
|
|
151
|
+
"data-test": "restapi-url",
|
|
152
|
+
label: "Request URL",
|
|
153
|
+
placeholder: "https://",
|
|
154
|
+
value: x,
|
|
155
|
+
onChange: W,
|
|
156
|
+
variablesData: y
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
K && /* @__PURE__ */ r(ee, { color: a.content.negative, children: "Enter a valid URL (including https://)" })
|
|
160
|
+
] }),
|
|
161
|
+
/* @__PURE__ */ i(m, { children: [
|
|
162
|
+
/* @__PURE__ */ r(u, { color: a.content.primary, children: "HTTP method" }),
|
|
163
|
+
/* @__PURE__ */ r(
|
|
164
|
+
le,
|
|
153
165
|
{
|
|
154
166
|
"data-test": "restapi-method",
|
|
155
167
|
size: "small",
|
|
156
168
|
width: "100%",
|
|
157
169
|
dropdownWidth: "399px",
|
|
158
|
-
options:
|
|
159
|
-
defaultOptions: [{ label:
|
|
170
|
+
options: pe,
|
|
171
|
+
defaultOptions: [{ label: T, value: T }],
|
|
160
172
|
onSelect: (e) => {
|
|
161
|
-
const
|
|
162
|
-
|
|
173
|
+
const t = ie(e);
|
|
174
|
+
t && z(t);
|
|
163
175
|
}
|
|
164
176
|
}
|
|
165
177
|
)
|
|
166
178
|
] }),
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
-
/* @__PURE__ */
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
179
|
+
/* @__PURE__ */ i(m, { children: [
|
|
180
|
+
/* @__PURE__ */ r(u, { color: a.content.primary, children: "Headers" }),
|
|
181
|
+
H.map((e, t) => /* @__PURE__ */ i(
|
|
182
|
+
he,
|
|
183
|
+
{
|
|
184
|
+
"data-test": `restapi-header-${t}`,
|
|
185
|
+
children: [
|
|
186
|
+
/* @__PURE__ */ r(
|
|
187
|
+
_,
|
|
188
|
+
{
|
|
189
|
+
variant: "small",
|
|
190
|
+
hideInputHeader: !0,
|
|
191
|
+
placeholder: "Enter name",
|
|
192
|
+
value: e.key,
|
|
193
|
+
onChangeText: (n) => L(t, { key: n })
|
|
194
|
+
}
|
|
195
|
+
),
|
|
196
|
+
/* @__PURE__ */ r(
|
|
197
|
+
D,
|
|
198
|
+
{
|
|
199
|
+
placeholder: "Enter value",
|
|
200
|
+
value: e.value,
|
|
201
|
+
onChange: (n) => L(t, { value: n }),
|
|
202
|
+
variablesData: y
|
|
203
|
+
}
|
|
204
|
+
),
|
|
205
|
+
/* @__PURE__ */ r(
|
|
206
|
+
fe,
|
|
207
|
+
{
|
|
208
|
+
type: "button",
|
|
209
|
+
"aria-label": "Remove header",
|
|
210
|
+
"data-test": `restapi-header-remove-${t}`,
|
|
211
|
+
onClick: () => Y(t),
|
|
212
|
+
children: /* @__PURE__ */ r(
|
|
213
|
+
X,
|
|
214
|
+
{
|
|
215
|
+
width: 16,
|
|
216
|
+
height: 16,
|
|
217
|
+
color: a.content.secondary
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
)
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
c.current[t]
|
|
210
225
|
)),
|
|
211
|
-
/* @__PURE__ */
|
|
212
|
-
|
|
226
|
+
/* @__PURE__ */ r(ue, { children: /* @__PURE__ */ r(
|
|
227
|
+
de,
|
|
213
228
|
{
|
|
214
229
|
"data-test": "restapi-add-header",
|
|
215
230
|
buttonType: "dashRegular",
|
|
216
231
|
size: "small",
|
|
217
|
-
LeadingIcon:
|
|
232
|
+
LeadingIcon: Z,
|
|
218
233
|
buttonText: "Add header",
|
|
219
|
-
onClick:
|
|
234
|
+
onClick: J
|
|
220
235
|
}
|
|
221
236
|
) })
|
|
222
237
|
] }),
|
|
223
|
-
/* @__PURE__ */
|
|
224
|
-
/* @__PURE__ */
|
|
225
|
-
/* @__PURE__ */
|
|
226
|
-
|
|
238
|
+
/* @__PURE__ */ i(m, { children: [
|
|
239
|
+
/* @__PURE__ */ r(u, { color: a.content.primary, children: "Request " }),
|
|
240
|
+
/* @__PURE__ */ r(
|
|
241
|
+
M,
|
|
227
242
|
{
|
|
228
243
|
features: { jsonMode: !0 },
|
|
229
|
-
initialContent:
|
|
230
|
-
style:
|
|
244
|
+
initialContent: w,
|
|
245
|
+
style: U,
|
|
231
246
|
placeholder: "Type or paste JSON here",
|
|
232
|
-
onChange: (e) =>
|
|
247
|
+
onChange: (e) => F(e.text),
|
|
233
248
|
minHeight: "120px",
|
|
234
249
|
maxHeight: "240px"
|
|
235
250
|
}
|
|
236
251
|
)
|
|
237
252
|
] }),
|
|
238
|
-
/* @__PURE__ */
|
|
239
|
-
/* @__PURE__ */
|
|
240
|
-
/* @__PURE__ */
|
|
241
|
-
|
|
253
|
+
/* @__PURE__ */ i(m, { children: [
|
|
254
|
+
/* @__PURE__ */ r(u, { color: a.content.primary, children: "Response " }),
|
|
255
|
+
/* @__PURE__ */ r(
|
|
256
|
+
M,
|
|
242
257
|
{
|
|
243
258
|
features: { jsonMode: !0 },
|
|
244
|
-
style:
|
|
245
|
-
initialContent:
|
|
259
|
+
style: U,
|
|
260
|
+
initialContent: E,
|
|
246
261
|
placeholder: "Type or paste JSON here",
|
|
247
|
-
onChange: (e) =>
|
|
262
|
+
onChange: (e) => G(e.text),
|
|
248
263
|
minHeight: "120px",
|
|
249
264
|
maxHeight: "240px"
|
|
250
265
|
}
|
|
@@ -253,33 +268,34 @@ const ae = ["GET", "POST", "PUT", "PATCH", "DELETE"], ne = ae.map((a) => ({
|
|
|
253
268
|
]
|
|
254
269
|
}
|
|
255
270
|
);
|
|
256
|
-
},
|
|
257
|
-
display:
|
|
271
|
+
}, he = C.div`
|
|
272
|
+
display: grid;
|
|
273
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) 32px;
|
|
258
274
|
align-items: center;
|
|
259
275
|
gap: 8px;
|
|
260
|
-
`,
|
|
276
|
+
`, ue = C.div`
|
|
261
277
|
display: flex;
|
|
262
|
-
`,
|
|
278
|
+
`, fe = C.button`
|
|
263
279
|
display: inline-flex;
|
|
264
280
|
align-items: center;
|
|
265
281
|
justify-content: center;
|
|
266
282
|
flex-shrink: 0;
|
|
267
283
|
width: 32px;
|
|
268
284
|
height: 32px;
|
|
269
|
-
border: 1px solid ${
|
|
285
|
+
border: 1px solid ${a.stroke.primary};
|
|
270
286
|
border-radius: 4px;
|
|
271
|
-
background: ${
|
|
287
|
+
background: ${a.surface.standard};
|
|
272
288
|
cursor: pointer;
|
|
273
289
|
|
|
274
290
|
&:hover {
|
|
275
|
-
border-color: ${
|
|
291
|
+
border-color: ${a.content.secondary};
|
|
276
292
|
}
|
|
277
|
-
`,
|
|
293
|
+
`, U = {
|
|
278
294
|
borderRadius: "4px",
|
|
279
295
|
overflow: "hidden"
|
|
280
296
|
};
|
|
281
297
|
export {
|
|
282
|
-
|
|
283
|
-
|
|
298
|
+
U as JsonFieldBox,
|
|
299
|
+
_e as RestApiToolPanel
|
|
284
300
|
};
|
|
285
301
|
//# 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, { 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 { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\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';\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}\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}) => {\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\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\tsetHeaders((prev) => [...prev, { key: '', value: '' }]);\n\tconst removeHeader = (i: number) =>\n\t\tsetHeaders((prev) => prev.filter((_, idx) => idx !== i));\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\tconst isUrlInvalid =\n\t\turlTrimmed.length > 0 &&\n\t\turlTrimmed !== 'https://' &&\n\t\t!isValidHttpUrl(urlTrimmed);\n\tconst canSave =\n\t\tnameTrimmed.length > 0 && isValidHttpUrl(urlTrimmed) && !isDuplicateName;\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/>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<Input\n\t\t\t\t\tdata-test=\"restapi-url\"\n\t\t\t\t\tvariant=\"small\"\n\t\t\t\t\tlabelText=\"Request URL\"\n\t\t\t\t\tlabelTextBold\n\t\t\t\t\tplaceholder=\"https://\"\n\t\t\t\t\ttype=\"url\"\n\t\t\t\t\tvalue={url}\n\t\t\t\t\tstate={isUrlInvalid ? 'invalid' : undefined}\n\t\t\t\t\terrorMessage={\n\t\t\t\t\t\tisUrlInvalid ? 'Enter a valid URL (including https://)' : undefined\n\t\t\t\t\t}\n\t\t\t\t\tonChangeText={setUrl}\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// eslint-disable-next-line react/no-array-index-key\n\t\t\t\t\t<HeaderRow key={i} data-test={`restapi-header-${i}`}>\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<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 value\"\n\t\t\t\t\t\t\tvalue={h.value}\n\t\t\t\t\t\t\tonChangeText={(v) => patchHeader(i, { value: v })}\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<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\nconst HeaderRow = styled.div`\n\tdisplay: flex;\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","name","setName","useState","instructions","setInstructions","url","setUrl","method","setMethod","headers","setHeaders","requestBody","setRequestBody","responseSample","setResponseSample","saving","setSaving","patchHeader","i","patch","prev","h","idx","addHeader","removeHeader","_","nameTrimmed","isDuplicateName","n","urlTrimmed","isUrlInvalid","canSave","jsxs","SideModal","jsx","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","config","result","Input","ToolInstructionsField","FieldBlock","TitleSmall","COLORS","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/** 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,4 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
import { VariableListInterfaceV3 } from '../../variable-picker-v3/model';
|
|
2
3
|
interface ToolInstructionsFieldProps {
|
|
3
4
|
label: string;
|
|
4
5
|
value: string;
|
|
@@ -8,6 +9,14 @@ interface ToolInstructionsFieldProps {
|
|
|
8
9
|
minHeight?: string;
|
|
9
10
|
/** "Improve with AI" — resolves with rewritten text. Omit to hide the button. */
|
|
10
11
|
onImprove?: (text: string) => Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Variable catalog. When non-empty the field upgrades from a plain textarea
|
|
14
|
+
* to a variables-only `@` mention editor: typing `@` opens the variable
|
|
15
|
+
* categories directly (Variables is the sole category, so the picker skips
|
|
16
|
+
* the Tools / Sub-agent root), and picks render as chips persisted as
|
|
17
|
+
* `{{variable:<name>}}` tokens.
|
|
18
|
+
*/
|
|
19
|
+
variablesData?: VariableListInterfaceV3[];
|
|
11
20
|
'data-test'?: string;
|
|
12
21
|
}
|
|
13
22
|
/**
|