@bikdotai/bik-component-library 0.0.831-beta.1 → 0.0.831-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js +6 -6
- 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/DrawerHeaderText.js +3 -3
- package/dist/cjs/components/agent-builder/components/DrawerHeaderText.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 +19 -19
- package/dist/cjs/components/agent-builder/components/MentionPicker.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/components/SelectableListSection.js +4 -4
- package/dist/cjs/components/agent-builder/components/SelectableListSection.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/sourceIcons.js +1 -1
- package/dist/cjs/components/agent-builder/utils/sourceIcons.js.map +1 -1
- package/dist/cjs/components/agent-builder/utils/toolActions.js +2 -0
- package/dist/cjs/components/agent-builder/utils/toolActions.js.map +1 -0
- package/dist/cjs/components/states-modal/DeleteConfirmationModal.js +1 -1
- package/dist/cjs/components/states-modal/DeleteConfirmationModal.js.map +1 -1
- package/dist/cjs/icons/Media/Visual/{FormkitNeutral.js → Frame26086263.js} +1 -1
- package/dist/cjs/icons/Media/Visual/Frame26086263.js.map +1 -0
- package/dist/cjs/icons/Media/Visual/{FormkitSad.js → IconTrailing.js} +1 -1
- package/dist/cjs/icons/Media/Visual/IconTrailing.js.map +1 -0
- package/dist/cjs/icons/Social/Social/SlackIcon.js +2 -0
- package/dist/cjs/icons/Social/Social/SlackIcon.js.map +1 -0
- package/dist/cjs/icons/index.js +1 -1
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +92 -101
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +149 -154
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/DrawerHeaderText.d.ts +2 -9
- package/dist/esm/components/agent-builder/components/DrawerHeaderText.js +15 -19
- package/dist/esm/components/agent-builder/components/DrawerHeaderText.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionField.js +57 -66
- package/dist/esm/components/agent-builder/components/MentionField.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionPicker.js +66 -55
- package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +77 -80
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/SelectableListSection.d.ts +10 -0
- package/dist/esm/components/agent-builder/components/SelectableListSection.js +134 -118
- package/dist/esm/components/agent-builder/components/SelectableListSection.js.map +1 -1
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +144 -148
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/sourceIcons.js +14 -14
- package/dist/esm/components/agent-builder/utils/sourceIcons.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/toolActions.d.ts +11 -0
- package/dist/esm/components/agent-builder/utils/toolActions.js +15 -0
- package/dist/esm/components/agent-builder/utils/toolActions.js.map +1 -0
- package/dist/esm/components/states-modal/DeleteConfirmationModal.d.ts +2 -0
- package/dist/esm/components/states-modal/DeleteConfirmationModal.js +11 -10
- package/dist/esm/components/states-modal/DeleteConfirmationModal.js.map +1 -1
- package/dist/esm/icons/Media/Visual/Frame26086263.d.ts +7 -0
- package/dist/esm/icons/Media/Visual/{FormkitNeutral.js → Frame26086263.js} +1 -1
- package/dist/esm/icons/Media/Visual/Frame26086263.js.map +1 -0
- package/dist/esm/icons/Media/Visual/IconTrailing.d.ts +7 -0
- package/dist/esm/icons/Media/Visual/{FormkitSad.js → IconTrailing.js} +1 -1
- package/dist/esm/icons/Media/Visual/IconTrailing.js.map +1 -0
- package/dist/esm/icons/Media/Visual/index.d.ts +2 -2
- package/dist/esm/icons/Social/Social/SlackIcon.d.ts +7 -0
- package/dist/esm/icons/Social/Social/SlackIcon.js +47 -0
- package/dist/esm/icons/Social/Social/SlackIcon.js.map +1 -0
- package/dist/esm/icons/Social/Social/index.d.ts +1 -0
- package/dist/esm/icons/index.d.ts +25 -25
- package/dist/esm/icons/index.js +246 -244
- package/dist/esm/icons/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/icons/Media/Visual/FormkitNeutral.js.map +0 -1
- package/dist/cjs/icons/Media/Visual/FormkitSad.js.map +0 -1
- package/dist/esm/icons/Media/Visual/FormkitNeutral.js.map +0 -1
- package/dist/esm/icons/Media/Visual/FormkitSad.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),L=require("../../../assets/icons/cross.svg.js"),T=require("react"),_=require("styled-components"),S=require("../../TypographyStyle.js"),r=require("../../../constants/Theme.js"),B=require("../AgentBuilder.styled.js"),I=require("../constants/charLimits.js"),C=require("./DrawerHeaderText.js"),q=require("./ToolInstructionsField.js"),E=require("../../side-modal/SideModal.js"),D=require("../../switch/Switch.js"),$=require("../../input/Input.js"),A=require("../../tag/Tag.js"),P=t=>t&&typeof t=="object"&&"default"in t?t:{default:t},p=P(_),F={send_email:{title:"Handover to email",subtitle:"Notify someone by email when this agent can't continue. You pick the recipient, the AI drafts the message."},send_slack_message:{title:"Send Slack message",subtitle:"Post a message to a Slack channel. You pick the channel, the AI composes the message from the conversation."}},Y=({chips:t,onChange:s,placeholder:c,nativeID:u,hint:h})=>{const[d,y]=T.useState(""),m=()=>{const n=d.split(",").map(i=>i.trim()).filter(Boolean);n.length&&s([...t,...n.filter(i=>!t.includes(i))]),y("")};return o.jsxs(V,{children:[o.jsx(W,{id:u,type:"text",placeholder:c,value:d,onChange:n=>y(n.target.value),onBlur:m,onKeyDown:n=>{n.key==="Enter"||n.key===","?(n.preventDefault(),m()):n.key==="Backspace"&&d===""&&t.length>0&&s(t.slice(0,-1))}}),h,t.length>0&&o.jsx(G,{children:t.map((n,i)=>o.jsx(A.Tag,{tagText:n,theme:"light",type:"neutral",variant:"regular",TrailingIcon:L.default,onTrailingIconClicked:()=>s(t.filter((f,x)=>x!==i))},`${n}-${i}`))})]})},H=(t,s)=>{const c={};return Object.keys(t).forEach(u=>{c[u]=s?.params[u]?.value??t[u].value}),c},M=t=>String(t??"").split(",").map(s=>s.trim()).filter(Boolean),z=({toolKey:t,template:s,onClose:c,onSave:u,initial:h,onImprove:d,charLimits:y=I.AGENT_CHAR_LIMITS,zIndex:m})=>{const[n,i]=T.useState(()=>H(s,h)),[f,x]=T.useState(!1),k=Object.values(s),j=t==="send_email",g=(e,l)=>i(a=>({...a,[e]:l})),O=k.every(e=>!e.required||String(n[e.key]??"").trim()!==""),w=async()=>{if(!O||f)return;const e={};k.forEach(v=>{e[v.key]={...v,value:n[v.key]}});const l={id:h?.id??`${t}_${Date.now().toString(36)}`,tool_key:t,params:e},a=u(l);if(a&&typeof a.then=="function"){x(!0);try{await a}finally{x(!1)}}},R=e=>{const l=`config-tool-${e.key.toLowerCase()}`;switch(e.component){case"KeywordInput":if(!j)break;return o.jsxs(B.FieldBlock,{children:[o.jsx(S.TitleSmall,{color:r.COLORS.content.primary,children:e.title}),o.jsx(Y,{nativeID:l,placeholder:e.hint??"",chips:M(n[e.key]),onChange:a=>g(e.key,a.join(",")),hint:o.jsx(S.BodyCaption,{color:r.COLORS.content.secondary,children:"Press Enter or comma to add multiple emails"})})]},e.key);case"MultilineInput":return o.jsx(q.ToolInstructionsField,{"data-test":l,label:e.title,value:String(n[e.key]??""),onChange:a=>g(e.key,a),maxLength:y.instructions,placeholder:e.hint??"",onImprove:d},e.key);case"Switch":return o.jsxs(N,{children:[o.jsxs(J,{children:[o.jsx(S.TitleSmall,{color:r.COLORS.content.primary,children:e.title}),e.hint&&o.jsx(S.BodyCaption,{color:r.COLORS.content.secondary,children:e.hint})]}),o.jsx(D.Switch,{"data-test":l,value:!!n[e.key],onValueChange:async a=>g(e.key,a)})]},e.key)}return o.jsx($.Input,{"data-test":l,variant:"small",labelText:e.title,labelTextBold:!0,placeholder:e.hint??"",value:String(n[e.key]??""),onChangeText:a=>g(e.key,a)},e.key)},b=F[t];return o.jsx(E.SideModal,{header:b.title,closeOnEscapeKey:!1,zIndex:m,headerCustomComponent:o.jsx(C.DrawerHeaderText,{title:b.title,subtitle:b.subtitle}),hideCrossButton:!1,width:"431px",headerStyle:C.DRAWER_HEADER_STYLE,bodyStyle:C.DRAWER_BODY_STYLE,onClose:c,saveButtonProps:{"data-test":"config-tool-save",buttonText:"Save",buttonType:"primary",size:"small",disabled:!O,isLoading:f,onClick:w},cancelButtonProps:{"data-test":"config-tool-cancel",buttonText:"Cancel",buttonType:"tertiaryGray",size:"small",onClick:c},children:k.map(R)})},V=p.default.div`
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-direction: column;
|
|
4
4
|
gap: 8px;
|
|
5
|
-
`,
|
|
5
|
+
`,W=p.default.input`
|
|
6
6
|
width: 100%;
|
|
7
7
|
min-width: 0;
|
|
8
8
|
box-sizing: border-box;
|
|
@@ -23,19 +23,19 @@
|
|
|
23
23
|
&:focus {
|
|
24
24
|
border-color: ${r.COLORS.stroke.brand};
|
|
25
25
|
}
|
|
26
|
-
`,
|
|
26
|
+
`,G=p.default.div`
|
|
27
27
|
display: flex;
|
|
28
28
|
flex-wrap: wrap;
|
|
29
29
|
gap: 6px;
|
|
30
|
-
`,
|
|
30
|
+
`,N=p.default.div`
|
|
31
31
|
display: flex;
|
|
32
32
|
align-items: center;
|
|
33
33
|
justify-content: space-between;
|
|
34
34
|
gap: 12px;
|
|
35
|
-
`,
|
|
35
|
+
`,J=p.default.div`
|
|
36
36
|
display: flex;
|
|
37
37
|
flex-direction: column;
|
|
38
38
|
gap: 4px;
|
|
39
39
|
min-width: 0;
|
|
40
|
-
`;exports.ConfigToolPanel=
|
|
40
|
+
`;exports.ConfigToolPanel=z;
|
|
41
41
|
//# sourceMappingURL=ConfigToolPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigToolPanel.js","sources":["../../../../../src/components/agent-builder/components/ConfigToolPanel.tsx"],"sourcesContent":["import CrossIcon from '@src/assets/icons/cross.svg';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { Switch } from '@src/components/switch';\nimport { Tag } from '@src/components/tag';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tConfigToolConfig,\n\tConfigToolKey,\n\tParamField,\n\tParamsBlob,\n} from '../AgentBuilder.model';\nimport { FieldBlock } from '../AgentBuilder.styled';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport { ToolSource } from '../constants/tools';\nimport { SOURCE_ICONS } from '../utils/sourceIcons';\nimport {\n\tDRAWER_BODY_STYLE,\n\tDRAWER_HEADER_STYLE,\n\tDrawerHeaderText,\n} from './DrawerHeaderText';\nimport { ToolInstructionsField } from './ToolInstructionsField';\n\n/** Header copy per shared-drawer tool. */\nconst TOOL_COPY: Record<ConfigToolKey, { title: string; subtitle: string }> = {\n\tsend_email: {\n\t\ttitle: 'Handover to email',\n\t\tsubtitle:\n\t\t\t\"Notify someone by email when this agent can't continue. You pick the recipient, the AI drafts the message.\",\n\t},\n\tsend_slack_message: {\n\t\ttitle: 'Send Slack message',\n\t\tsubtitle:\n\t\t\t'Post a message to a Slack channel. You pick the channel, the AI composes the message from the conversation.',\n\t},\n};\n\ninterface ConfigToolPanelProps {\n\t/** Which tool this drawer configures (drives copy + persistence). */\n\ttoolKey: ConfigToolKey;\n\t/**\n\t * The backend template (`list-catalog` → params) for `toolKey`. The form is\n\t * DYNAMIC: exactly these fields render, in this order, each by its\n\t * `component` kind (KeywordInput | MultilineInput | Switch | fallback input).\n\t */\n\ttemplate: ParamsBlob;\n\tonClose: () => void;\n\t/** Persist the filled template. A pending promise shows the Save loader. */\n\tonSave: (config: ConfigToolConfig) => void | Promise<void>;\n\t/** Seed values when editing an existing tool. */\n\tinitial?: ConfigToolConfig;\n\t/** Optional \"Improve with AI\" for multiline fields. Omit to hide it. */\n\tonImprove?: (text: string) => Promise<string>;\n\tcharLimits?: AgentCharLimits;\n\t/** SideModal stacking order — raise it when opened over another drawer. */\n\tzIndex?: number;\n}\n\ninterface EmailChipsFieldProps {\n\tchips: string[];\n\tonChange: (next: string[]) => void;\n\tplaceholder: string;\n\tnativeID?: string;\n\t/** Optional helper caption shown between the input and the chips. */\n\thint?: React.ReactNode;\n}\n\n/**\n * Email entry field: type an address and press Enter / comma (or blur) to add\n * it. Added emails render as removable chips BELOW the input — not inside it.\n * Backspace on an empty input removes the last chip.\n */\nconst EmailChipsField: React.FC<EmailChipsFieldProps> = ({\n\tchips,\n\tonChange,\n\tplaceholder,\n\tnativeID,\n\thint,\n}) => {\n\tconst [buffer, setBuffer] = useState('');\n\n\tconst commit = () => {\n\t\tconst parts = buffer\n\t\t\t.split(',')\n\t\t\t.map((s) => s.trim())\n\t\t\t.filter(Boolean);\n\t\tif (parts.length) {\n\t\t\tonChange([...chips, ...parts.filter((p) => !chips.includes(p))]);\n\t\t}\n\t\tsetBuffer('');\n\t};\n\n\treturn (\n\t\t<ChipsFieldWrap>\n\t\t\t<EmailInputBox\n\t\t\t\tid={nativeID}\n\t\t\t\ttype=\"text\"\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tvalue={buffer}\n\t\t\t\tonChange={(e) => setBuffer(e.target.value)}\n\t\t\t\tonBlur={commit}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (e.key === 'Enter' || e.key === ',') {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tcommit();\n\t\t\t\t\t} else if (\n\t\t\t\t\t\te.key === 'Backspace' &&\n\t\t\t\t\t\tbuffer === '' &&\n\t\t\t\t\t\tchips.length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tonChange(chips.slice(0, -1));\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t{hint}\n\t\t\t{chips.length > 0 && (\n\t\t\t\t<ChipRow>\n\t\t\t\t\t{chips.map((email, i) => (\n\t\t\t\t\t\t<Tag\n\t\t\t\t\t\t\tkey={`${email}-${i}`}\n\t\t\t\t\t\t\ttagText={email}\n\t\t\t\t\t\t\ttheme=\"light\"\n\t\t\t\t\t\t\ttype=\"neutral\"\n\t\t\t\t\t\t\tvariant=\"regular\"\n\t\t\t\t\t\t\tTrailingIcon={CrossIcon}\n\t\t\t\t\t\t\tonTrailingIconClicked={() =>\n\t\t\t\t\t\t\t\tonChange(chips.filter((_, idx) => idx !== i))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</ChipRow>\n\t\t\t)}\n\t\t</ChipsFieldWrap>\n\t);\n};\n\n/** Field values keyed by param key (the editable part of a {@link ParamsBlob}). */\ntype ParamValues = Record<string, string | boolean | number | object>;\n\nconst seedValues = (\n\ttemplate: ParamsBlob,\n\tinitial?: ConfigToolConfig,\n): ParamValues => {\n\tconst values: ParamValues = {};\n\tObject.keys(template).forEach((key) => {\n\t\tvalues[key] = initial?.params[key]?.value ?? template[key].value;\n\t});\n\treturn values;\n};\n\n/** Chips ↔ the string value KeywordInput fields carry (comma-separated). */\nconst toChips = (value: unknown): string[] =>\n\tString(value ?? '')\n\t\t.split(',')\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean);\n\n/**\n * Shared right-side drawer for the params-driven configurable tools (email /\n * Slack). Fully backend-driven: it renders the template fields by their\n * `component` kind and returns the same blob with values filled in. KeywordInput\n * renders as multi-value email chips only for `send_email`; every other tool\n * gets a plain single-line input. Mount it fresh per open (key it) so `initial`\n * seeds the state. Built on the shared `SideModal` shell.\n */\nexport const ConfigToolPanel: React.FC<ConfigToolPanelProps> = ({\n\ttoolKey,\n\ttemplate,\n\tonClose,\n\tonSave,\n\tinitial,\n\tonImprove,\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tzIndex,\n}) => {\n\tconst [values, setValues] = useState<ParamValues>(() =>\n\t\tseedValues(template, initial),\n\t);\n\tconst [saving, setSaving] = useState(false);\n\n\tconst fields = Object.values(template);\n\tconst isEmail = toolKey === 'send_email';\n\tconst setValue = (key: string, value: string | boolean | number | object) =>\n\t\tsetValues((prev) => ({ ...prev, [key]: value }));\n\n\tconst canSave = fields.every(\n\t\t(f) => !f.required || String(values[f.key] ?? '').trim() !== '',\n\t);\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst params: ParamsBlob = {};\n\t\tfields.forEach((f) => {\n\t\t\t// Save the FULL descriptor with only `value` changed — the backend\n\t\t\t// infers each field's type from `component` and reads `required`.\n\t\t\tparams[f.key] = { ...f, value: values[f.key] };\n\t\t});\n\t\tconst config: ConfigToolConfig = {\n\t\t\tid: initial?.id ?? `${toolKey}_${Date.now().toString(36)}`,\n\t\t\ttool_key: toolKey,\n\t\t\tparams,\n\t\t};\n\t\tconst result = onSave(config);\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetSaving(true);\n\t\t\ttry {\n\t\t\t\tawait result;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst renderField = (field: ParamField) => {\n\t\tconst testId = `config-tool-${field.key.toLowerCase()}`;\n\t\tswitch (field.component) {\n\t\t\t// Multi-value email chips — only for the email tool. Slack's KeywordInput\n\t\t\t// (channelId) falls through to the plain input below.\n\t\t\tcase 'KeywordInput':\n\t\t\t\tif (!isEmail) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t<FieldBlock key={field.key}>\n\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t{field.title}\n\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t<EmailChipsField\n\t\t\t\t\t\t\tnativeID={testId}\n\t\t\t\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\t\t\t\tchips={toChips(values[field.key])}\n\t\t\t\t\t\t\tonChange={(chips) => setValue(field.key, chips.join(','))}\n\t\t\t\t\t\t\thint={\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\tPress Enter or comma to add multiple emails\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FieldBlock>\n\t\t\t\t);\n\t\t\tcase 'MultilineInput':\n\t\t\t\treturn (\n\t\t\t\t\t<ToolInstructionsField\n\t\t\t\t\t\tkey={field.key}\n\t\t\t\t\t\tdata-test={testId}\n\t\t\t\t\t\tlabel={field.title}\n\t\t\t\t\t\tvalue={String(values[field.key] ?? '')}\n\t\t\t\t\t\tonChange={(text) => setValue(field.key, text)}\n\t\t\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\t\t\tonImprove={onImprove}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase 'Switch':\n\t\t\t\treturn (\n\t\t\t\t\t<SwitchRow key={field.key}>\n\t\t\t\t\t\t<SwitchText>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t{field.title}\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t{field.hint && (\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\t{field.hint}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</SwitchText>\n\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\tdata-test={testId}\n\t\t\t\t\t\t\tvalue={Boolean(values[field.key])}\n\t\t\t\t\t\t\tonValueChange={async (next) => setValue(field.key, next)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</SwitchRow>\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t\treturn (\n\t\t\t<Input\n\t\t\t\tkey={field.key}\n\t\t\t\tdata-test={testId}\n\t\t\t\tvariant=\"small\"\n\t\t\t\tlabelText={field.title}\n\t\t\t\tlabelTextBold\n\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\tvalue={String(values[field.key] ?? '')}\n\t\t\t\tonChangeText={(text) => setValue(field.key, text)}\n\t\t\t/>\n\t\t);\n\t};\n\n\tconst copy = TOOL_COPY[toolKey];\n\n\treturn (\n\t\t<SideModal\n\t\t\theader={copy.title}\n\t\t\tcloseOnEscapeKey={false}\n\t\t\tzIndex={zIndex}\n\t\t\theaderCustomComponent={\n\t\t\t\t<DrawerHeaderText\n\t\t\t\t\ttitle={copy.title}\n\t\t\t\t\tsubtitle={copy.subtitle}\n\t\t\t\t\ticon={\n\t\t\t\t\t\tSOURCE_ICONS[\n\t\t\t\t\t\t\ttoolKey === 'send_slack_message'\n\t\t\t\t\t\t\t\t? ToolSource.Slack\n\t\t\t\t\t\t\t\t: ToolSource.EmailHandover\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t}\n\t\t\thideCrossButton={false}\n\t\t\twidth=\"431px\"\n\t\t\theaderStyle={DRAWER_HEADER_STYLE}\n\t\t\tbodyStyle={DRAWER_BODY_STYLE}\n\t\t\tonClose={onClose}\n\t\t\tsaveButtonProps={{\n\t\t\t\t'data-test': 'config-tool-save',\n\t\t\t\tbuttonText: 'Save',\n\t\t\t\tbuttonType: 'primary',\n\t\t\t\tsize: 'small',\n\t\t\t\tdisabled: !canSave,\n\t\t\t\tisLoading: saving,\n\t\t\t\tonClick: handleSave,\n\t\t\t}}\n\t\t\tcancelButtonProps={{\n\t\t\t\t'data-test': 'config-tool-cancel',\n\t\t\t\tbuttonText: 'Cancel',\n\t\t\t\tbuttonType: 'tertiaryGray',\n\t\t\t\tsize: 'small',\n\t\t\t\tonClick: onClose,\n\t\t\t}}\n\t\t>\n\t\t\t{fields.map(renderField)}\n\t\t</SideModal>\n\t);\n};\n\nconst ChipsFieldWrap = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n`;\n\nconst EmailInputBox = styled.input`\n\twidth: 100%;\n\tmin-width: 0;\n\tbox-sizing: border-box;\n\theight: 32px;\n\tpadding: 0 8px;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tfont-family: 'Inter', sans-serif;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\tbackground: ${COLORS.surface.standard};\n\toutline: none;\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.secondary};\n\t}\n\n\t&:focus {\n\t\tborder-color: ${COLORS.stroke.brand};\n\t}\n`;\n\nconst ChipRow = styled.div`\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 6px;\n`;\n\nconst SwitchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 12px;\n`;\n\nconst SwitchText = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n`;\n"],"names":["TOOL_COPY","EmailChipsField","chips","onChange","placeholder","nativeID","hint","buffer","setBuffer","useState","commit","parts","s","p","ChipsFieldWrap","jsx","EmailInputBox","e","ChipRow","email","Tag","CrossIcon","_","idx","seedValues","template","initial","values","key","toChips","value","ConfigToolPanel","toolKey","onClose","onSave","onImprove","charLimits","AGENT_CHAR_LIMITS","zIndex","setValues","saving","setSaving","fields","isEmail","setValue","prev","canSave","f","handleSave","params","config","result","renderField","field","testId","FieldBlock","TitleSmall","COLORS","BodyCaption","ToolInstructionsField","text","SwitchRow","jsxs","SwitchText","Switch","next","Input","copy","SideModal","DrawerHeaderText","SOURCE_ICONS","ToolSource","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","styled"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ConfigToolPanel.js","sources":["../../../../../src/components/agent-builder/components/ConfigToolPanel.tsx"],"sourcesContent":["import CrossIcon from '@src/assets/icons/cross.svg';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { Switch } from '@src/components/switch';\nimport { Tag } from '@src/components/tag';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tConfigToolConfig,\n\tConfigToolKey,\n\tParamField,\n\tParamsBlob,\n} from '../AgentBuilder.model';\nimport { FieldBlock } from '../AgentBuilder.styled';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport {\n\tDRAWER_BODY_STYLE,\n\tDRAWER_HEADER_STYLE,\n\tDrawerHeaderText,\n} from './DrawerHeaderText';\nimport { ToolInstructionsField } from './ToolInstructionsField';\n\n/** Header copy per shared-drawer tool. */\nconst TOOL_COPY: Record<ConfigToolKey, { title: string; subtitle: string }> = {\n\tsend_email: {\n\t\ttitle: 'Handover to email',\n\t\tsubtitle:\n\t\t\t\"Notify someone by email when this agent can't continue. You pick the recipient, the AI drafts the message.\",\n\t},\n\tsend_slack_message: {\n\t\ttitle: 'Send Slack message',\n\t\tsubtitle:\n\t\t\t'Post a message to a Slack channel. You pick the channel, the AI composes the message from the conversation.',\n\t},\n};\n\ninterface ConfigToolPanelProps {\n\t/** Which tool this drawer configures (drives copy + persistence). */\n\ttoolKey: ConfigToolKey;\n\t/**\n\t * The backend template (`list-catalog` → params) for `toolKey`. The form is\n\t * DYNAMIC: exactly these fields render, in this order, each by its\n\t * `component` kind (KeywordInput | MultilineInput | Switch | fallback input).\n\t */\n\ttemplate: ParamsBlob;\n\tonClose: () => void;\n\t/** Persist the filled template. A pending promise shows the Save loader. */\n\tonSave: (config: ConfigToolConfig) => void | Promise<void>;\n\t/** Seed values when editing an existing tool. */\n\tinitial?: ConfigToolConfig;\n\t/** Optional \"Improve with AI\" for multiline fields. Omit to hide it. */\n\tonImprove?: (text: string) => Promise<string>;\n\tcharLimits?: AgentCharLimits;\n\t/** SideModal stacking order — raise it when opened over another drawer. */\n\tzIndex?: number;\n}\n\ninterface EmailChipsFieldProps {\n\tchips: string[];\n\tonChange: (next: string[]) => void;\n\tplaceholder: string;\n\tnativeID?: string;\n\t/** Optional helper caption shown between the input and the chips. */\n\thint?: React.ReactNode;\n}\n\n/**\n * Email entry field: type an address and press Enter / comma (or blur) to add\n * it. Added emails render as removable chips BELOW the input — not inside it.\n * Backspace on an empty input removes the last chip.\n */\nconst EmailChipsField: React.FC<EmailChipsFieldProps> = ({\n\tchips,\n\tonChange,\n\tplaceholder,\n\tnativeID,\n\thint,\n}) => {\n\tconst [buffer, setBuffer] = useState('');\n\n\tconst commit = () => {\n\t\tconst parts = buffer\n\t\t\t.split(',')\n\t\t\t.map((s) => s.trim())\n\t\t\t.filter(Boolean);\n\t\tif (parts.length) {\n\t\t\tonChange([...chips, ...parts.filter((p) => !chips.includes(p))]);\n\t\t}\n\t\tsetBuffer('');\n\t};\n\n\treturn (\n\t\t<ChipsFieldWrap>\n\t\t\t<EmailInputBox\n\t\t\t\tid={nativeID}\n\t\t\t\ttype=\"text\"\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tvalue={buffer}\n\t\t\t\tonChange={(e) => setBuffer(e.target.value)}\n\t\t\t\tonBlur={commit}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (e.key === 'Enter' || e.key === ',') {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tcommit();\n\t\t\t\t\t} else if (\n\t\t\t\t\t\te.key === 'Backspace' &&\n\t\t\t\t\t\tbuffer === '' &&\n\t\t\t\t\t\tchips.length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tonChange(chips.slice(0, -1));\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t{hint}\n\t\t\t{chips.length > 0 && (\n\t\t\t\t<ChipRow>\n\t\t\t\t\t{chips.map((email, i) => (\n\t\t\t\t\t\t<Tag\n\t\t\t\t\t\t\tkey={`${email}-${i}`}\n\t\t\t\t\t\t\ttagText={email}\n\t\t\t\t\t\t\ttheme=\"light\"\n\t\t\t\t\t\t\ttype=\"neutral\"\n\t\t\t\t\t\t\tvariant=\"regular\"\n\t\t\t\t\t\t\tTrailingIcon={CrossIcon}\n\t\t\t\t\t\t\tonTrailingIconClicked={() =>\n\t\t\t\t\t\t\t\tonChange(chips.filter((_, idx) => idx !== i))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</ChipRow>\n\t\t\t)}\n\t\t</ChipsFieldWrap>\n\t);\n};\n\n/** Field values keyed by param key (the editable part of a {@link ParamsBlob}). */\ntype ParamValues = Record<string, string | boolean | number | object>;\n\nconst seedValues = (\n\ttemplate: ParamsBlob,\n\tinitial?: ConfigToolConfig,\n): ParamValues => {\n\tconst values: ParamValues = {};\n\tObject.keys(template).forEach((key) => {\n\t\tvalues[key] = initial?.params[key]?.value ?? template[key].value;\n\t});\n\treturn values;\n};\n\n/** Chips ↔ the string value KeywordInput fields carry (comma-separated). */\nconst toChips = (value: unknown): string[] =>\n\tString(value ?? '')\n\t\t.split(',')\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean);\n\n/**\n * Shared right-side drawer for the params-driven configurable tools (email /\n * Slack). Fully backend-driven: it renders the template fields by their\n * `component` kind and returns the same blob with values filled in. KeywordInput\n * renders as multi-value email chips only for `send_email`; every other tool\n * gets a plain single-line input. Mount it fresh per open (key it) so `initial`\n * seeds the state. Built on the shared `SideModal` shell.\n */\nexport const ConfigToolPanel: React.FC<ConfigToolPanelProps> = ({\n\ttoolKey,\n\ttemplate,\n\tonClose,\n\tonSave,\n\tinitial,\n\tonImprove,\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tzIndex,\n}) => {\n\tconst [values, setValues] = useState<ParamValues>(() =>\n\t\tseedValues(template, initial),\n\t);\n\tconst [saving, setSaving] = useState(false);\n\n\tconst fields = Object.values(template);\n\tconst isEmail = toolKey === 'send_email';\n\tconst setValue = (key: string, value: string | boolean | number | object) =>\n\t\tsetValues((prev) => ({ ...prev, [key]: value }));\n\n\tconst canSave = fields.every(\n\t\t(f) => !f.required || String(values[f.key] ?? '').trim() !== '',\n\t);\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst params: ParamsBlob = {};\n\t\tfields.forEach((f) => {\n\t\t\t// Save the FULL descriptor with only `value` changed — the backend\n\t\t\t// infers each field's type from `component` and reads `required`.\n\t\t\tparams[f.key] = { ...f, value: values[f.key] };\n\t\t});\n\t\tconst config: ConfigToolConfig = {\n\t\t\tid: initial?.id ?? `${toolKey}_${Date.now().toString(36)}`,\n\t\t\ttool_key: toolKey,\n\t\t\tparams,\n\t\t};\n\t\tconst result = onSave(config);\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetSaving(true);\n\t\t\ttry {\n\t\t\t\tawait result;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst renderField = (field: ParamField) => {\n\t\tconst testId = `config-tool-${field.key.toLowerCase()}`;\n\t\tswitch (field.component) {\n\t\t\t// Multi-value email chips — only for the email tool. Slack's KeywordInput\n\t\t\t// (channelId) falls through to the plain input below.\n\t\t\tcase 'KeywordInput':\n\t\t\t\tif (!isEmail) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t<FieldBlock key={field.key}>\n\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t{field.title}\n\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t<EmailChipsField\n\t\t\t\t\t\t\tnativeID={testId}\n\t\t\t\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\t\t\t\tchips={toChips(values[field.key])}\n\t\t\t\t\t\t\tonChange={(chips) => setValue(field.key, chips.join(','))}\n\t\t\t\t\t\t\thint={\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\tPress Enter or comma to add multiple emails\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FieldBlock>\n\t\t\t\t);\n\t\t\tcase 'MultilineInput':\n\t\t\t\treturn (\n\t\t\t\t\t<ToolInstructionsField\n\t\t\t\t\t\tkey={field.key}\n\t\t\t\t\t\tdata-test={testId}\n\t\t\t\t\t\tlabel={field.title}\n\t\t\t\t\t\tvalue={String(values[field.key] ?? '')}\n\t\t\t\t\t\tonChange={(text) => setValue(field.key, text)}\n\t\t\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\t\t\tonImprove={onImprove}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase 'Switch':\n\t\t\t\treturn (\n\t\t\t\t\t<SwitchRow key={field.key}>\n\t\t\t\t\t\t<SwitchText>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t{field.title}\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t{field.hint && (\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\t{field.hint}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</SwitchText>\n\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\tdata-test={testId}\n\t\t\t\t\t\t\tvalue={Boolean(values[field.key])}\n\t\t\t\t\t\t\tonValueChange={async (next) => setValue(field.key, next)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</SwitchRow>\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t\treturn (\n\t\t\t<Input\n\t\t\t\tkey={field.key}\n\t\t\t\tdata-test={testId}\n\t\t\t\tvariant=\"small\"\n\t\t\t\tlabelText={field.title}\n\t\t\t\tlabelTextBold\n\t\t\t\tplaceholder={field.hint ?? ''}\n\t\t\t\tvalue={String(values[field.key] ?? '')}\n\t\t\t\tonChangeText={(text) => setValue(field.key, text)}\n\t\t\t/>\n\t\t);\n\t};\n\n\tconst copy = TOOL_COPY[toolKey];\n\n\treturn (\n\t\t<SideModal\n\t\t\theader={copy.title}\n\t\t\tcloseOnEscapeKey={false}\n\t\t\tzIndex={zIndex}\n\t\t\theaderCustomComponent={\n\t\t\t\t<DrawerHeaderText title={copy.title} subtitle={copy.subtitle} />\n\t\t\t}\n\t\t\thideCrossButton={false}\n\t\t\twidth=\"431px\"\n\t\t\theaderStyle={DRAWER_HEADER_STYLE}\n\t\t\tbodyStyle={DRAWER_BODY_STYLE}\n\t\t\tonClose={onClose}\n\t\t\tsaveButtonProps={{\n\t\t\t\t'data-test': 'config-tool-save',\n\t\t\t\tbuttonText: 'Save',\n\t\t\t\tbuttonType: 'primary',\n\t\t\t\tsize: 'small',\n\t\t\t\tdisabled: !canSave,\n\t\t\t\tisLoading: saving,\n\t\t\t\tonClick: handleSave,\n\t\t\t}}\n\t\t\tcancelButtonProps={{\n\t\t\t\t'data-test': 'config-tool-cancel',\n\t\t\t\tbuttonText: 'Cancel',\n\t\t\t\tbuttonType: 'tertiaryGray',\n\t\t\t\tsize: 'small',\n\t\t\t\tonClick: onClose,\n\t\t\t}}\n\t\t>\n\t\t\t{fields.map(renderField)}\n\t\t</SideModal>\n\t);\n};\n\nconst ChipsFieldWrap = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n`;\n\nconst EmailInputBox = styled.input`\n\twidth: 100%;\n\tmin-width: 0;\n\tbox-sizing: border-box;\n\theight: 32px;\n\tpadding: 0 8px;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tfont-family: 'Inter', sans-serif;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\tbackground: ${COLORS.surface.standard};\n\toutline: none;\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.secondary};\n\t}\n\n\t&:focus {\n\t\tborder-color: ${COLORS.stroke.brand};\n\t}\n`;\n\nconst ChipRow = styled.div`\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 6px;\n`;\n\nconst SwitchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 12px;\n`;\n\nconst SwitchText = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n`;\n"],"names":["TOOL_COPY","EmailChipsField","chips","onChange","placeholder","nativeID","hint","buffer","setBuffer","useState","commit","parts","s","p","ChipsFieldWrap","jsx","EmailInputBox","e","ChipRow","email","Tag","CrossIcon","_","idx","seedValues","template","initial","values","key","toChips","value","ConfigToolPanel","toolKey","onClose","onSave","onImprove","charLimits","AGENT_CHAR_LIMITS","zIndex","setValues","saving","setSaving","fields","isEmail","setValue","prev","canSave","f","handleSave","params","config","result","renderField","field","testId","FieldBlock","TitleSmall","COLORS","BodyCaption","ToolInstructionsField","text","SwitchRow","jsxs","SwitchText","Switch","next","Input","copy","SideModal","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","styled"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),o=require("react"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),o=require("react"),_e=require("styled-components"),re=require("../../../utils/arrayUtils.js"),H=require("../../../constants/Theme.js"),Ee=require("../constants/charLimits.js"),p=require("../constants/tools.js"),m=require("../utils/mentionSerialization.js"),f=require("../utils/sourceIcons.js"),Oe=require("../utils/toolActions.js"),Me=require("./ConfigToolPanel.js"),F=require("./DrawerHeaderText.js"),ie=require("./MentionEditor.js"),qe=require("./RestApiToolPanel.js"),je=require("./SelectableListSection.js"),we=require("../../side-modal/SideModal.js"),Le=require("../../input/Input.js"),De=require("../../toaster/Toaster.js"),Ke=c=>c&&typeof c=="object"&&"default"in c?c:{default:c},Ne=Ke(_e),Pe=1e3,W=1002,ae=(c,S)=>{const i=c??[];return i.some(u=>u.id===S.id)?i.map(u=>u.id===S.id?S:u):[...i,S]},le=Ne.default.button`
|
|
2
2
|
align-self: flex-start;
|
|
3
3
|
border: 1px solid ${H.COLORS.stroke.primary};
|
|
4
4
|
color: ${H.COLORS.content.primary};
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
cursor: default;
|
|
15
15
|
opacity: 0.6;
|
|
16
16
|
}
|
|
17
|
-
`,
|
|
17
|
+
`,Ge=({onClose:c,onSave:S,availableTools:i,onImprove:u,onImproveToolInstructions:$,configToolTemplates:Y,title:X="Create sub-agent",initial:b,appLabel:Z="Manifest",charLimits:C=Ee.AGENT_CHAR_LIMITS})=>{const[O,ce]=o.useState(b?.name??""),[T,A]=o.useState(b?.instructions??""),[h,v]=o.useState(b?.guardrail??""),[M,k]=o.useState(b?.tools??[]),[g,q]=o.useState(b?.configTools??[]),[d,j]=o.useState(b?.restApiTools??[]),[a,y]=o.useState(null),_=o.useRef(0),[J,Q]=o.useState(!1),[ue,w]=o.useState(0),[de,L]=o.useState(0),[I,V]=o.useState(null),D=o.useMemo(()=>[...m.buildAgentMentionItems(i,[],Z),...m.buildCustomToolMentionItems(g,d)],[i,Z,g,d]),E=o.useRef({}),K=o.useRef("instructions"),pe=o.useCallback(e=>{E.current.instructions=e??void 0},[]),ge=o.useCallback(e=>{E.current.guardrail=e??void 0},[]),me=o.useCallback(()=>{K.current="instructions"},[]),fe=o.useCallback(()=>{K.current="guardrail"},[]),ee=o.useCallback((e,t)=>{e==="tool"&&k(n=>re.addUnique(n,t))},[]),x=o.useCallback((e,t)=>{(E.current[K.current]??E.current.instructions)?.("tool",e,t)},[]),N=o.useCallback(e=>{_.current+=1,y({key:_.current,kind:"restapi",initialRest:e})},[]),P=o.useCallback((e,t)=>{_.current+=1,y({key:_.current,kind:"config",toolKey:e,initialConfig:t})},[]),Se=o.useCallback(e=>{const t=p.CONFIG_TOOL_SOURCES[e];t?P(t):N()},[P,N]),be=o.useCallback(e=>{const t=!d.some(n=>n.id===e.id);j(n=>ae(n,e)),t&&x(e.id,m.restApiMentionItem(e).label),y(null)},[d,x]),ye=o.useCallback(e=>{const t=!g.some(n=>n.id===e.id);q(n=>ae(n,e)),t&&x(e.id,m.configToolMentionItem(e).label),y(null)},[g,x]),[G,B]=o.useState(null),U=o.useRef(null),te=o.useRef(0),Ce=e=>{const t=i.find(s=>s.tool_id===e)?.display_name??d.find(s=>s.id===e)?.name??"Tool",n=`{{tool:${e}}}`,l=s=>s.split(n).join("");U.current={instructions:T,guardrail:h,tools:M,configTools:g,restApiTools:d},A(s=>l(s)),v(s=>l(s)),k(s=>s.filter(R=>R!==e)),q(s=>s.filter(R=>R.id!==e)),j(s=>s.filter(R=>R.id!==e)),w(s=>s+1),L(s=>s+1),te.current+=1,B({id:te.current,message:`Tool "${t}" removed`})},Te=()=>{const e=U.current;e&&(A(e.instructions),v(e.guardrail),k(e.tools),q(e.configTools),j(e.restApiTools),w(t=>t+1),L(t=>t+1),U.current=null),B(null)},oe=O.trim().length>0&&(T.trim().length>0||h.trim().length>0),he=M.map(e=>{const t=i.find(n=>n.tool_id===e);return t?{id:e,label:t.display_name,icon:f.sourceIcon(t.source??p.ToolSource.Manifest)}:null}).filter(e=>e!==null),Ie=d.map(e=>({id:e.id,label:m.restApiToolName(e),icon:f.SOURCE_ICONS[p.ToolSource.RestApi],onConfigure:()=>N(e)})),xe=g.map(e=>({id:e.id,label:m.configToolName(e),icon:f.SOURCE_ICONS[e.tool_key==="send_slack_message"?p.ToolSource.Slack:p.ToolSource.EmailHandover],onConfigure:()=>P(e.tool_key,e)})),Re=[...he,...Ie,...xe],z=Oe.buildToolActions(Y,Se),ne=a?.kind==="config"&&a.toolKey?Y?.[a.toolKey]:void 0,Ae=i.map(e=>({label:e.display_name,value:e.tool_id,leadingIcon:f.renderSourceIcon(f.sourceIcon(e.source??p.ToolSource.Manifest))??void 0})),ve=(()=>{const e=[],t=new Map;return i.forEach(n=>{const l=n.source??p.ToolSource.Manifest;t.has(l)||(t.set(l,[]),e.push(l)),t.get(l)?.push({label:n.display_name,value:n.tool_id,leadingIcon:f.renderSourceIcon(f.sourceIcon(n.source??p.ToolSource.Manifest))??void 0})}),e.map(n=>({source:n,label:m.toolSourceLabel(n),options:t.get(n)??[]}))})(),ke=async()=>{if(!oe||J)return;const e=S({name:O.trim(),instructions:T,guardrail:h,tools:M,configTools:g,restApiTools:d});if(e&&typeof e.then=="function"){Q(!0);try{await e}finally{Q(!1)}}},se=async e=>{if(!(!u||I)){V(e);try{const n=await u(e,e==="instructions"?T:h);e==="instructions"?(A(n),w(l=>l+1)):(v(n),L(l=>l+1))}finally{V(null)}}};return r.jsxs(r.Fragment,{children:[r.jsxs(we.SideModal,{header:X,closeOnEscapeKey:!1,zIndex:Pe,headerCustomComponent:r.jsx(F.DrawerHeaderText,{title:X,subtitle:"Each sub-agent handles one piece of the job. Use @ in the main instructions to call them."}),width:"421px",headerStyle:F.DRAWER_HEADER_STYLE,bodyStyle:F.DRAWER_BODY_STYLE,onClose:c,saveButtonProps:{"data-test":"subagent-save",buttonText:"Save",buttonType:"primary",size:"small",disabled:!oe,isLoading:J,onClick:ke},cancelButtonProps:{"data-test":"subagent-cancel",buttonText:"Cancel",buttonType:"tertiaryGray",size:"small",onClick:c},children:[r.jsx(Le.Input,{"data-test":"subagent-name",labelText:"Agent name",labelTextBold:!0,placeholder:"Enter agent name",value:O,maxCharLimit:C.name,maxCharLimitPosition:"TOP",maxCharStyle:{fontSize:12,lineHeight:"16px"},onChangeText:ce}),r.jsx(ie.MentionEditor,{"data-test":"subagent-instructions",label:"Instructions",value:T,onChange:A,maxLength:C.instructions,placeholder:"Write the steps in plain English. Type @ to reference a tool.",minHeight:"160px",resetKey:`instr-${ue}`,mentionItems:D,tools:i,toolActions:z,onMentionSelect:ee,onFocus:me,registerInsert:pe,action:u?r.jsx(le,{type:"button","data-test":"subagent-improve-instructions",disabled:I!==null,onClick:()=>se("instructions"),children:I==="instructions"?"Improving…":"Improve with AI"}):void 0}),r.jsx(ie.MentionEditor,{"data-test":"subagent-guardrail",label:"Guardrails",value:h,onChange:v,maxLength:C.guardrail,placeholder:"e.g. Never discuss competitor pricing. Type @ to reference a tool.",minHeight:"160px",resetKey:`guard-${de}`,mentionItems:D,tools:i,toolActions:z,onMentionSelect:ee,onFocus:fe,registerInsert:ge,action:u?r.jsx(le,{type:"button","data-test":"subagent-improve-guardrail",disabled:I!==null,onClick:()=>se("guardrail"),children:I==="guardrail"?"Improving…":"Improve with AI"}):void 0}),r.jsx(je.SelectableListSection,{title:"Tools this agent can use",dataTestPrefix:"subagent-tools",items:Re,addableOptions:Ae,sourceGroups:ve,mentionItems:D,actionSources:z,emptyText:"No tools added yet.",onAdd:e=>{x(e),k(t=>re.addUnique(t,e))},onRemove:Ce,confirmDelete:{noun:"tool",zIndex:W+1}})]}),a?.kind==="restapi"&&r.jsx(qe.RestApiToolPanel,{initial:a.initialRest,charLimits:C,onImprove:$,onClose:()=>y(null),onSave:be,zIndex:W},a.key),a?.kind==="config"&&a.toolKey&&ne&&r.jsx(Me.ConfigToolPanel,{toolKey:a.toolKey,template:ne,initial:a.initialConfig,charLimits:C,onImprove:$,onClose:()=>y(null),onSave:ye,zIndex:W},a.key),G&&r.jsx(De.Toaster,{text:G.message,type:"info",position:"top-right",autoClose:5e3,hideCloseButton:!0,buttonProps:{buttonText:"Undo",showButton:!0,onButtonClick:()=>(Te(),{})},onCloseToast:()=>B(null)},G.id)]})};exports.CreateSubAgentPanel=Ge;
|
|
18
18
|
//# sourceMappingURL=CreateSubAgentPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateSubAgentPanel.js","sources":["../../../../../src/components/agent-builder/components/CreateSubAgentPanel.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { Toaster } from '@src/components/toaster';\nimport { addUnique } from '@src/utils/arrayUtils';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tAgentTool,\n\tConfigToolConfig,\n\tConfigToolKey,\n\tParamsBlob,\n\tRestApiToolConfig,\n\tSubAgentDraft,\n} from '../AgentBuilder.model';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport {\n\tCONFIG_TOOL_SOURCES,\n\tTOOL_ACTION_LABELS,\n\tTOOL_ACTION_SOURCES,\n\tTOOL_SOURCE_LABELS,\n\tToolAction,\n\tToolSource,\n} from '../constants/tools';\nimport {\n\tbuildAgentMentionItems,\n\tbuildCustomToolMentionItems,\n\tconfigToolMentionItem,\n\tconfigToolName,\n\trestApiMentionItem,\n\trestApiToolName,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport {\n\trenderSourceIcon,\n\tSOURCE_ICONS,\n\tsourceIcon,\n} from '../utils/sourceIcons';\nimport { ConfigToolPanel } from './ConfigToolPanel';\nimport {\n\tDRAWER_BODY_STYLE,\n\tDRAWER_HEADER_STYLE,\n\tDrawerHeaderText,\n} from './DrawerHeaderText';\nimport { MentionEditor } from './MentionEditor';\nimport { RestApiToolPanel } from './RestApiToolPanel';\nimport {\n\tSelectableItem,\n\tSelectableListSection,\n\tSourceGroup,\n} from './SelectableListSection';\n\n/**\n * The sub-agent drawer sits above the main builder; its own tool drawers\n * (Rest API / email / Slack) stack one level higher so they open ON TOP of it\n * rather than behind (SideModal defaults to z-index 10).\n */\nconst SUBAGENT_ZINDEX = 1000;\nconst TOOL_DRAWER_ZINDEX = 1002;\n\n/** Upsert an item by id (replace when present, append otherwise). */\nconst upsertById = <T extends { id: string }>(\n\tlist: T[] | undefined,\n\titem: T,\n): T[] => {\n\tconst arr = list ?? [];\n\treturn arr.some((x) => x.id === item.id)\n\t\t? arr.map((x) => (x.id === item.id ? item : x))\n\t\t: [...arr, item];\n};\n\n/** Config-tool / Rest API drawer state; `key` remounts fresh per open. */\ninterface ToolDrawerState {\n\tkey: number;\n\tkind: 'restapi' | 'config';\n\ttoolKey?: ConfigToolKey;\n\tinitialRest?: RestApiToolConfig;\n\tinitialConfig?: ConfigToolConfig;\n}\n\n/** Inline \"Improve with AI\" action rendered below a mention editor. */\nconst ImproveButton = styled.button`\n\talign-self: flex-start;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tcolor: ${COLORS.content.primary};\n\tbackground: ${COLORS.surface.standard};\n\tborder-radius: 8px;\n\tpadding: 6px 12px;\n\tfont-size: 13px;\n\tline-height: 1.1;\n\tfont-weight: 600;\n\tcursor: pointer;\n\n\t&:disabled {\n\t\tcursor: default;\n\t\topacity: 0.6;\n\t}\n`;\n\ntype InsertFn = (kind: 'tool' | 'subagent', id: string, label?: string) => void;\n\ninterface CreateSubAgentPanelProps {\n\tonClose: () => void;\n\t/** Persist the draft. The drawer shows a loader while the returned promise is pending. */\n\tonSave: (draft: SubAgentDraft) => void | Promise<void>;\n\tavailableTools: AgentTool[];\n\t/** Optional \"Improve with AI\" for instructions / guardrails. Omit to hide the buttons. */\n\tonImprove?: (\n\t\tkind: 'instructions' | 'guardrail',\n\t\ttext: string,\n\t) => Promise<string>;\n\t/** Optional \"Improve with AI\" for the Rest API / config-tool drawers. */\n\tonImproveToolInstructions?: (text: string) => Promise<string>;\n\t/**\n\t * Backend templates (email / Slack) that drive the shared config-tool drawer.\n\t * Each present key enables its tool action in this drawer; absent → hidden.\n\t * Same prop the main builder gets — sub-agents can add the same tools.\n\t */\n\tconfigToolTemplates?: Partial<Record<ConfigToolKey, ParamsBlob>>;\n\t/** Header title — \"Create sub-agent\" (default) or \"Edit sub-agent\". */\n\ttitle?: string;\n\t/** Initial values, e.g. when configuring an existing sub-agent. */\n\tinitial?: SubAgentDraft;\n\t/** Tool-source fallback label for chips (host app). */\n\tappLabel?: string;\n\t/** Resolved character limits (defaults to {@link AGENT_CHAR_LIMITS}). */\n\tcharLimits?: AgentCharLimits;\n}\n\n/**\n * Right-side drawer for creating / editing a sub-agent (name, instructions,\n * guardrails, tools). Instructions & Guardrails are `@`-mention editors (tools\n * only — sub-agents can't nest); adding a tool from the list inserts it at the\n * last-focused field's cursor. Mount it fresh per open (key it) so `initial`\n * seeds the draft.\n */\nexport const CreateSubAgentPanel: React.FC<CreateSubAgentPanelProps> = ({\n\tonClose,\n\tonSave,\n\tavailableTools,\n\tonImprove,\n\tonImproveToolInstructions,\n\tconfigToolTemplates,\n\ttitle = 'Create sub-agent',\n\tinitial,\n\tappLabel = 'Manifest',\n\tcharLimits = AGENT_CHAR_LIMITS,\n}) => {\n\tconst [name, setName] = useState(initial?.name ?? '');\n\tconst [instructions, setInstructions] = useState(initial?.instructions ?? '');\n\tconst [guardrail, setGuardrail] = useState(initial?.guardrail ?? '');\n\tconst [tools, setTools] = useState<string[]>(initial?.tools ?? []);\n\t// Inline-configured tools owned by this sub-agent (same drawers as the main\n\t// agent). Local to the drawer; flow to the consumer via the saved draft.\n\tconst [configTools, setConfigTools] = useState<ConfigToolConfig[]>(\n\t\tinitial?.configTools ?? [],\n\t);\n\tconst [restApiTools, setRestApiTools] = useState<RestApiToolConfig[]>(\n\t\tinitial?.restApiTools ?? [],\n\t);\n\tconst [toolDrawer, setToolDrawer] = useState<ToolDrawerState | null>(null);\n\tconst toolDrawerKeyRef = useRef(0);\n\tconst [saving, setSaving] = useState(false);\n\t// Bumped to remount a field after its text is replaced (e.g. by Improve).\n\tconst [instrKey, setInstrKey] = useState(0);\n\tconst [guardKey, setGuardKey] = useState(0);\n\tconst [improving, setImproving] = useState<\n\t\t'instructions' | 'guardrail' | null\n\t>(null);\n\n\t// Tools-only mention list (sub-agents can't reference other sub-agents), PLUS\n\t// this drawer's inline custom tools so their `{{tool:<id>}}` tokens rehydrate\n\t// as chips on remount (they aren't in `availableTools`).\n\tconst mentionItems = useMemo(\n\t\t() => [\n\t\t\t...buildAgentMentionItems(availableTools, [], appLabel),\n\t\t\t...buildCustomToolMentionItems(configTools, restApiTools),\n\t\t],\n\t\t[availableTools, appLabel, configTools, restApiTools],\n\t);\n\n\t// Per-field insert + focus registry, so the Tools list inserts a chip into the\n\t// last-focused editor at its cursor.\n\tconst insertersRef = useRef<\n\t\tPartial<Record<'instructions' | 'guardrail', InsertFn>>\n\t>({});\n\tconst lastFocusedRef = useRef<'instructions' | 'guardrail'>('instructions');\n\tconst registerInstr = useCallback((fn: InsertFn | null) => {\n\t\tinsertersRef.current.instructions = fn ?? undefined;\n\t}, []);\n\tconst registerGuard = useCallback((fn: InsertFn | null) => {\n\t\tinsertersRef.current.guardrail = fn ?? undefined;\n\t}, []);\n\tconst focusInstr = useCallback(() => {\n\t\tlastFocusedRef.current = 'instructions';\n\t}, []);\n\tconst focusGuard = useCallback(() => {\n\t\tlastFocusedRef.current = 'guardrail';\n\t}, []);\n\tconst addToolMention = useCallback(\n\t\t(kind: 'tool' | 'subagent', id: string) => {\n\t\t\tif (kind === 'tool') {\n\t\t\t\tsetTools((prev) => addUnique(prev, id));\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\tconst insertToolAtCursor = useCallback((id: string, label?: string) => {\n\t\tconst target =\n\t\t\tinsertersRef.current[lastFocusedRef.current] ??\n\t\t\tinsertersRef.current.instructions;\n\t\ttarget?.('tool', id, label);\n\t}, []);\n\n\t// Rest API (bespoke) + shared config-tool (email / Slack) drawers, same as the\n\t// main builder's Step 3 — here backed by the drawer's local state.\n\t// ponytail: mirrors Step3HowItResponds; kept local rather than sharing a hook\n\t// because Step3 is context-backed and this drawer is local-state.\n\tconst openRestApi = useCallback((tool?: RestApiToolConfig) => {\n\t\ttoolDrawerKeyRef.current += 1;\n\t\tsetToolDrawer({\n\t\t\tkey: toolDrawerKeyRef.current,\n\t\t\tkind: 'restapi',\n\t\t\tinitialRest: tool,\n\t\t});\n\t}, []);\n\tconst openConfigTool = useCallback(\n\t\t(toolKey: ConfigToolKey, tool?: ConfigToolConfig) => {\n\t\t\ttoolDrawerKeyRef.current += 1;\n\t\t\tsetToolDrawer({\n\t\t\t\tkey: toolDrawerKeyRef.current,\n\t\t\t\tkind: 'config',\n\t\t\t\ttoolKey,\n\t\t\t\tinitialConfig: tool,\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\tconst openToolAction = useCallback(\n\t\t(source: ToolSource) => {\n\t\t\tconst toolKey = CONFIG_TOOL_SOURCES[source];\n\t\t\tif (toolKey) {\n\t\t\t\topenConfigTool(toolKey);\n\t\t\t} else {\n\t\t\t\topenRestApi();\n\t\t\t}\n\t\t},\n\t\t[openConfigTool, openRestApi],\n\t);\n\tconst handleSaveRestApi = useCallback(\n\t\t(tool: RestApiToolConfig) => {\n\t\t\tconst isNew = !restApiTools.some((t) => t.id === tool.id);\n\t\t\tsetRestApiTools((prev) => upsertById(prev, tool));\n\t\t\t// Drop a reference chip at the cursor on creation (edits keep the chip).\n\t\t\tif (isNew) {\n\t\t\t\tinsertToolAtCursor(tool.id, restApiMentionItem(tool).label);\n\t\t\t}\n\t\t\tsetToolDrawer(null);\n\t\t},\n\t\t[restApiTools, insertToolAtCursor],\n\t);\n\tconst handleSaveConfigTool = useCallback(\n\t\t(tool: ConfigToolConfig) => {\n\t\t\tconst isNew = !configTools.some((t) => t.id === tool.id);\n\t\t\tsetConfigTools((prev) => upsertById(prev, tool));\n\t\t\tif (isNew) {\n\t\t\t\tinsertToolAtCursor(tool.id, configToolMentionItem(tool).label);\n\t\t\t}\n\t\t\tsetToolDrawer(null);\n\t\t},\n\t\t[configTools, insertToolAtCursor],\n\t);\n\n\t// Local undo toast for tool removal (drawer state isn't in AgentValue).\n\tconst [undo, setUndo] = useState<{ id: number; message: string } | null>(\n\t\tnull,\n\t);\n\tconst undoSnapshotRef = useRef<{\n\t\tinstructions: string;\n\t\tguardrail: string;\n\t\ttools: string[];\n\t\tconfigTools: ConfigToolConfig[];\n\t\trestApiTools: RestApiToolConfig[];\n\t} | null>(null);\n\tconst undoIdRef = useRef(0);\n\n\t// Remove ANY tool by id: strip its `{{tool:<id>}}` tokens, remount the fields,\n\t// and drop it from whichever list holds it (catalog `tools` or an inline\n\t// custom-tool list). One undo restores all of it.\n\tconst removeTool = (id: string) => {\n\t\tconst label =\n\t\t\tavailableTools.find((t) => t.tool_id === id)?.display_name ??\n\t\t\trestApiTools.find((t) => t.id === id)?.name ??\n\t\t\t'Tool';\n\t\t// The token stores the tool id (a tool's id is its tool_id).\n\t\tconst token = `{{tool:${id}}}`;\n\t\tconst strip = (text: string) => text.split(token).join('');\n\t\tundoSnapshotRef.current = {\n\t\t\tinstructions,\n\t\t\tguardrail,\n\t\t\ttools,\n\t\t\tconfigTools,\n\t\t\trestApiTools,\n\t\t};\n\t\tsetInstructions((prev) => strip(prev));\n\t\tsetGuardrail((prev) => strip(prev));\n\t\tsetTools((prev) => prev.filter((t) => t !== id));\n\t\tsetConfigTools((prev) => prev.filter((t) => t.id !== id));\n\t\tsetRestApiTools((prev) => prev.filter((t) => t.id !== id));\n\t\tsetInstrKey((k) => k + 1);\n\t\tsetGuardKey((k) => k + 1);\n\t\tundoIdRef.current += 1;\n\t\tsetUndo({ id: undoIdRef.current, message: `Tool \"${label}\" removed` });\n\t};\n\n\tconst undoRemove = () => {\n\t\tconst snap = undoSnapshotRef.current;\n\t\tif (snap) {\n\t\t\tsetInstructions(snap.instructions);\n\t\t\tsetGuardrail(snap.guardrail);\n\t\t\tsetTools(snap.tools);\n\t\t\tsetConfigTools(snap.configTools);\n\t\t\tsetRestApiTools(snap.restApiTools);\n\t\t\tsetInstrKey((k) => k + 1);\n\t\t\tsetGuardKey((k) => k + 1);\n\t\t\tundoSnapshotRef.current = null;\n\t\t}\n\t\tsetUndo(null);\n\t};\n\n\tconst canSave =\n\t\tname.trim().length > 0 &&\n\t\t(instructions.trim().length > 0 || guardrail.trim().length > 0);\n\n\tconst toolItems: SelectableItem[] = tools\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst tool = availableTools.find((t) => t.tool_id === id);\n\t\t\treturn tool\n\t\t\t\t? {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tlabel: tool.display_name,\n\t\t\t\t\t\ticon: sourceIcon(tool.source ?? ToolSource.Manifest),\n\t\t\t\t }\n\t\t\t\t: null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\t// Inline-configured tools (Rest API + email / Slack) render as rows in the same\n\t// list, each with its own Configure (edit) action that reopens its drawer.\n\tconst restApiItems: SelectableItem[] = restApiTools.map((t) => ({\n\t\tid: t.id,\n\t\tlabel: restApiToolName(t),\n\t\ticon: SOURCE_ICONS[ToolSource.RestApi],\n\t\tonConfigure: () => openRestApi(t),\n\t}));\n\tconst configToolItems: SelectableItem[] = configTools.map((t) => ({\n\t\tid: t.id,\n\t\tlabel: configToolName(t),\n\t\ticon: SOURCE_ICONS[\n\t\t\tt.tool_key === 'send_slack_message'\n\t\t\t\t? ToolSource.Slack\n\t\t\t\t: ToolSource.EmailHandover\n\t\t],\n\t\tonConfigure: () => openConfigTool(t.tool_key, t),\n\t}));\n\tconst allToolItems: SelectableItem[] = [\n\t\t...toolItems,\n\t\t...restApiItems,\n\t\t...configToolItems,\n\t];\n\n\t// Built-in tool actions (Rest API / email / Slack); the shared email / Slack\n\t// forms appear only when their backend template was provided.\n\tconst toolActionSources: ToolAction[] = TOOL_ACTION_SOURCES.filter(\n\t\t(source) => {\n\t\t\tconst toolKey = CONFIG_TOOL_SOURCES[source];\n\t\t\treturn !toolKey || Boolean(configToolTemplates?.[toolKey]);\n\t\t},\n\t).map((source) => ({\n\t\tsource,\n\t\tlabel: TOOL_ACTION_LABELS[source] ?? TOOL_SOURCE_LABELS[source],\n\t\ticon: SOURCE_ICONS[source],\n\t\tonSelect: () => openToolAction(source),\n\t}));\n\n\tconst openConfigTemplate =\n\t\ttoolDrawer?.kind === 'config' && toolDrawer.toolKey\n\t\t\t? configToolTemplates?.[toolDrawer.toolKey]\n\t\t\t: undefined;\n\n\t// Offer all tools (re-add allowed); the chip list stays deduped. Icon left of\n\t// the name, no description.\n\tconst toolOptions: SingleOption[] = availableTools.map((t) => ({\n\t\tlabel: t.display_name,\n\t\tvalue: t.tool_id,\n\t\tleadingIcon:\n\t\t\trenderSourceIcon(sourceIcon(t.source ?? ToolSource.Manifest)) ??\n\t\t\tundefined,\n\t}));\n\n\t// Group tools by source (Manifest / Shopify / …) so the empty state shows the\n\t// same per-source buttons as the main builder's side panel.\n\tconst toolSourceGroups: SourceGroup[] = (() => {\n\t\tconst order: string[] = [];\n\t\tconst bySource = new Map<string, SingleOption[]>();\n\t\tavailableTools.forEach((t) => {\n\t\t\tconst src = t.source ?? ToolSource.Manifest;\n\t\t\tif (!bySource.has(src)) {\n\t\t\t\tbySource.set(src, []);\n\t\t\t\torder.push(src);\n\t\t\t}\n\t\t\tbySource.get(src)?.push({\n\t\t\t\tlabel: t.display_name,\n\t\t\t\tvalue: t.tool_id,\n\t\t\t\tleadingIcon:\n\t\t\t\t\trenderSourceIcon(sourceIcon(t.source ?? ToolSource.Manifest)) ??\n\t\t\t\t\tundefined,\n\t\t\t});\n\t\t});\n\t\treturn order.map((src) => ({\n\t\t\tsource: src,\n\t\t\tlabel: toolSourceLabel(src),\n\t\t\toptions: bySource.get(src) ?? [],\n\t\t}));\n\t})();\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst result = onSave({\n\t\t\tname: name.trim(),\n\t\t\tinstructions,\n\t\t\tguardrail,\n\t\t\ttools,\n\t\t\tconfigTools,\n\t\t\trestApiTools,\n\t\t});\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetSaving(true);\n\t\t\ttry {\n\t\t\t\tawait result;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleImprove = async (kind: 'instructions' | 'guardrail') => {\n\t\tif (!onImprove || improving) {\n\t\t\treturn;\n\t\t}\n\t\tsetImproving(kind);\n\t\ttry {\n\t\t\tconst current = kind === 'instructions' ? instructions : guardrail;\n\t\t\tconst improved = await onImprove(kind, current);\n\t\t\tif (kind === 'instructions') {\n\t\t\t\tsetInstructions(improved);\n\t\t\t\tsetInstrKey((k) => k + 1);\n\t\t\t} else {\n\t\t\t\tsetGuardrail(improved);\n\t\t\t\tsetGuardKey((k) => k + 1);\n\t\t\t}\n\t\t} finally {\n\t\t\tsetImproving(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SideModal\n\t\t\t\theader={title}\n\t\t\t\tcloseOnEscapeKey={false}\n\t\t\t\tzIndex={SUBAGENT_ZINDEX}\n\t\t\t\theaderCustomComponent={\n\t\t\t\t\t<DrawerHeaderText\n\t\t\t\t\t\ttitle={title}\n\t\t\t\t\t\tsubtitle=\"Each sub-agent handles one piece of the job. Use @ in the main instructions to call them.\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\twidth=\"421px\"\n\t\t\t\theaderStyle={DRAWER_HEADER_STYLE}\n\t\t\t\tbodyStyle={DRAWER_BODY_STYLE}\n\t\t\t\tonClose={onClose}\n\t\t\t\tsaveButtonProps={{\n\t\t\t\t\t'data-test': 'subagent-save',\n\t\t\t\t\tbuttonText: 'Save',\n\t\t\t\t\tbuttonType: 'primary',\n\t\t\t\t\tsize: 'small',\n\t\t\t\t\tdisabled: !canSave,\n\t\t\t\t\tisLoading: saving,\n\t\t\t\t\tonClick: handleSave,\n\t\t\t\t}}\n\t\t\t\tcancelButtonProps={{\n\t\t\t\t\t'data-test': 'subagent-cancel',\n\t\t\t\t\tbuttonText: 'Cancel',\n\t\t\t\t\tbuttonType: 'tertiaryGray',\n\t\t\t\t\tsize: 'small',\n\t\t\t\t\tonClick: onClose,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<Input\n\t\t\t\t\tdata-test=\"subagent-name\"\n\t\t\t\t\tlabelText=\"Agent name\"\n\t\t\t\t\tlabelTextBold\n\t\t\t\t\tplaceholder=\"Enter agent name\"\n\t\t\t\t\tvalue={name}\n\t\t\t\t\tmaxCharLimit={charLimits.name}\n\t\t\t\t\tmaxCharLimitPosition=\"TOP\"\n\t\t\t\t\tmaxCharStyle={{ fontSize: 12, lineHeight: '16px' }}\n\t\t\t\t\tonChangeText={setName}\n\t\t\t\t/>\n\n\t\t\t\t<MentionEditor\n\t\t\t\t\tdata-test=\"subagent-instructions\"\n\t\t\t\t\tlabel=\"Instructions\"\n\t\t\t\t\tvalue={instructions}\n\t\t\t\t\tonChange={setInstructions}\n\t\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\t\tplaceholder=\"Write the steps in plain English. Type @ to reference a tool.\"\n\t\t\t\t\tminHeight=\"160px\"\n\t\t\t\t\tresetKey={`instr-${instrKey}`}\n\t\t\t\t\tmentionItems={mentionItems}\n\t\t\t\t\ttools={availableTools}\n\t\t\t\t\ttoolActions={toolActionSources}\n\t\t\t\t\tonMentionSelect={addToolMention}\n\t\t\t\t\tonFocus={focusInstr}\n\t\t\t\t\tregisterInsert={registerInstr}\n\t\t\t\t\taction={\n\t\t\t\t\t\tonImprove ? (\n\t\t\t\t\t\t\t<ImproveButton\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tdata-test=\"subagent-improve-instructions\"\n\t\t\t\t\t\t\t\tdisabled={improving !== null}\n\t\t\t\t\t\t\t\tonClick={() => handleImprove('instructions')}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{improving === 'instructions'\n\t\t\t\t\t\t\t\t\t? 'Improving…'\n\t\t\t\t\t\t\t\t\t: 'Improve with AI'}\n\t\t\t\t\t\t\t</ImproveButton>\n\t\t\t\t\t\t) : undefined\n\t\t\t\t\t}\n\t\t\t\t/>\n\n\t\t\t\t<MentionEditor\n\t\t\t\t\tdata-test=\"subagent-guardrail\"\n\t\t\t\t\tlabel=\"Guardrails\"\n\t\t\t\t\tvalue={guardrail}\n\t\t\t\t\tonChange={setGuardrail}\n\t\t\t\t\tmaxLength={charLimits.guardrail}\n\t\t\t\t\tplaceholder=\"e.g. Never discuss competitor pricing. Type @ to reference a tool.\"\n\t\t\t\t\tminHeight=\"160px\"\n\t\t\t\t\tresetKey={`guard-${guardKey}`}\n\t\t\t\t\tmentionItems={mentionItems}\n\t\t\t\t\ttools={availableTools}\n\t\t\t\t\ttoolActions={toolActionSources}\n\t\t\t\t\tonMentionSelect={addToolMention}\n\t\t\t\t\tonFocus={focusGuard}\n\t\t\t\t\tregisterInsert={registerGuard}\n\t\t\t\t\taction={\n\t\t\t\t\t\tonImprove ? (\n\t\t\t\t\t\t\t<ImproveButton\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tdata-test=\"subagent-improve-guardrail\"\n\t\t\t\t\t\t\t\tdisabled={improving !== null}\n\t\t\t\t\t\t\t\tonClick={() => handleImprove('guardrail')}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{improving === 'guardrail' ? 'Improving…' : 'Improve with AI'}\n\t\t\t\t\t\t\t</ImproveButton>\n\t\t\t\t\t\t) : undefined\n\t\t\t\t\t}\n\t\t\t\t/>\n\n\t\t\t\t<SelectableListSection\n\t\t\t\t\ttitle=\"Tools this agent can use\"\n\t\t\t\t\tdataTestPrefix=\"subagent-tools\"\n\t\t\t\t\titems={allToolItems}\n\t\t\t\t\taddableOptions={toolOptions}\n\t\t\t\t\tsourceGroups={toolSourceGroups}\n\t\t\t\t\tmentionItems={mentionItems}\n\t\t\t\t\tactionSources={toolActionSources}\n\t\t\t\t\temptyText=\"No tools added yet.\"\n\t\t\t\t\tonAdd={(id) => {\n\t\t\t\t\t\tinsertToolAtCursor(id);\n\t\t\t\t\t\tsetTools((prev) => addUnique(prev, id));\n\t\t\t\t\t}}\n\t\t\t\t\tonRemove={removeTool}\n\t\t\t\t/>\n\t\t\t</SideModal>\n\n\t\t\t{toolDrawer?.kind === 'restapi' && (\n\t\t\t\t<RestApiToolPanel\n\t\t\t\t\tkey={toolDrawer.key}\n\t\t\t\t\tinitial={toolDrawer.initialRest}\n\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\tonImprove={onImproveToolInstructions}\n\t\t\t\t\tonClose={() => setToolDrawer(null)}\n\t\t\t\t\tonSave={handleSaveRestApi}\n\t\t\t\t\tzIndex={TOOL_DRAWER_ZINDEX}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{toolDrawer?.kind === 'config' &&\n\t\t\t\ttoolDrawer.toolKey &&\n\t\t\t\topenConfigTemplate && (\n\t\t\t\t\t<ConfigToolPanel\n\t\t\t\t\t\tkey={toolDrawer.key}\n\t\t\t\t\t\ttoolKey={toolDrawer.toolKey}\n\t\t\t\t\t\ttemplate={openConfigTemplate}\n\t\t\t\t\t\tinitial={toolDrawer.initialConfig}\n\t\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\t\tonImprove={onImproveToolInstructions}\n\t\t\t\t\t\tonClose={() => setToolDrawer(null)}\n\t\t\t\t\t\tonSave={handleSaveConfigTool}\n\t\t\t\t\t\tzIndex={TOOL_DRAWER_ZINDEX}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\n\t\t\t{undo && (\n\t\t\t\t<Toaster\n\t\t\t\t\tkey={undo.id}\n\t\t\t\t\ttext={undo.message}\n\t\t\t\t\ttype=\"info\"\n\t\t\t\t\tposition=\"top-right\"\n\t\t\t\t\tautoClose={5000}\n\t\t\t\t\thideCloseButton\n\t\t\t\t\tbuttonProps={{\n\t\t\t\t\t\tbuttonText: 'Undo',\n\t\t\t\t\t\tshowButton: true,\n\t\t\t\t\t\tonButtonClick: () => {\n\t\t\t\t\t\t\tundoRemove();\n\t\t\t\t\t\t\treturn {} as Record<string, never>;\n\t\t\t\t\t\t},\n\t\t\t\t\t}}\n\t\t\t\t\tonCloseToast={() => setUndo(null)}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n};\n"],"names":["SUBAGENT_ZINDEX","TOOL_DRAWER_ZINDEX","upsertById","list","item","arr","x","ImproveButton","styled","COLORS","CreateSubAgentPanel","onClose","onSave","availableTools","onImprove","onImproveToolInstructions","configToolTemplates","title","initial","appLabel","charLimits","AGENT_CHAR_LIMITS","name","setName","useState","instructions","setInstructions","guardrail","setGuardrail","tools","setTools","configTools","setConfigTools","restApiTools","setRestApiTools","toolDrawer","setToolDrawer","toolDrawerKeyRef","useRef","saving","setSaving","instrKey","setInstrKey","guardKey","setGuardKey","improving","setImproving","mentionItems","useMemo","buildAgentMentionItems","buildCustomToolMentionItems","insertersRef","lastFocusedRef","registerInstr","useCallback","fn","registerGuard","focusInstr","focusGuard","addToolMention","kind","id","prev","addUnique","insertToolAtCursor","label","openRestApi","tool","openConfigTool","toolKey","openToolAction","source","CONFIG_TOOL_SOURCES","handleSaveRestApi","isNew","t","restApiMentionItem","handleSaveConfigTool","configToolMentionItem","undo","setUndo","undoSnapshotRef","undoIdRef","removeTool","token","strip","text","k","undoRemove","snap","canSave","toolItems","sourceIcon","ToolSource","restApiItems","restApiToolName","SOURCE_ICONS","configToolItems","configToolName","allToolItems","toolActionSources","TOOL_ACTION_SOURCES","TOOL_ACTION_LABELS","TOOL_SOURCE_LABELS","openConfigTemplate","toolOptions","renderSourceIcon","toolSourceGroups","order","bySource","src","toolSourceLabel","handleSave","result","handleImprove","improved","jsxs","Fragment","SideModal","jsx","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","Input","MentionEditor","SelectableListSection","RestApiToolPanel","ConfigToolPanel","Toaster"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CreateSubAgentPanel.js","sources":["../../../../../src/components/agent-builder/components/CreateSubAgentPanel.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { Toaster } from '@src/components/toaster';\nimport { addUnique } from '@src/utils/arrayUtils';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tAgentTool,\n\tConfigToolConfig,\n\tConfigToolKey,\n\tParamsBlob,\n\tRestApiToolConfig,\n\tSubAgentDraft,\n} from '../AgentBuilder.model';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport { CONFIG_TOOL_SOURCES, ToolSource } from '../constants/tools';\nimport {\n\tbuildAgentMentionItems,\n\tbuildCustomToolMentionItems,\n\tconfigToolMentionItem,\n\tconfigToolName,\n\trestApiMentionItem,\n\trestApiToolName,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport {\n\trenderSourceIcon,\n\tSOURCE_ICONS,\n\tsourceIcon,\n} from '../utils/sourceIcons';\nimport { buildToolActions } from '../utils/toolActions';\nimport { ConfigToolPanel } from './ConfigToolPanel';\nimport {\n\tDRAWER_BODY_STYLE,\n\tDRAWER_HEADER_STYLE,\n\tDrawerHeaderText,\n} from './DrawerHeaderText';\nimport { MentionEditor } from './MentionEditor';\nimport { RestApiToolPanel } from './RestApiToolPanel';\nimport {\n\tSelectableItem,\n\tSelectableListSection,\n\tSourceGroup,\n} from './SelectableListSection';\n\n/**\n * The sub-agent drawer sits above the main builder; its own tool drawers\n * (Rest API / email / Slack) stack one level higher so they open ON TOP of it\n * rather than behind (SideModal defaults to z-index 10).\n */\nconst SUBAGENT_ZINDEX = 1000;\nconst TOOL_DRAWER_ZINDEX = 1002;\n\n/** Upsert an item by id (replace when present, append otherwise). */\nconst upsertById = <T extends { id: string }>(\n\tlist: T[] | undefined,\n\titem: T,\n): T[] => {\n\tconst arr = list ?? [];\n\treturn arr.some((x) => x.id === item.id)\n\t\t? arr.map((x) => (x.id === item.id ? item : x))\n\t\t: [...arr, item];\n};\n\n/** Config-tool / Rest API drawer state; `key` remounts fresh per open. */\ninterface ToolDrawerState {\n\tkey: number;\n\tkind: 'restapi' | 'config';\n\ttoolKey?: ConfigToolKey;\n\tinitialRest?: RestApiToolConfig;\n\tinitialConfig?: ConfigToolConfig;\n}\n\n/** Inline \"Improve with AI\" action rendered below a mention editor. */\nconst ImproveButton = styled.button`\n\talign-self: flex-start;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tcolor: ${COLORS.content.primary};\n\tbackground: ${COLORS.surface.standard};\n\tborder-radius: 8px;\n\tpadding: 6px 12px;\n\tfont-size: 13px;\n\tline-height: 1.1;\n\tfont-weight: 600;\n\tcursor: pointer;\n\n\t&:disabled {\n\t\tcursor: default;\n\t\topacity: 0.6;\n\t}\n`;\n\ntype InsertFn = (kind: 'tool' | 'subagent', id: string, label?: string) => void;\n\ninterface CreateSubAgentPanelProps {\n\tonClose: () => void;\n\t/** Persist the draft. The drawer shows a loader while the returned promise is pending. */\n\tonSave: (draft: SubAgentDraft) => void | Promise<void>;\n\tavailableTools: AgentTool[];\n\t/** Optional \"Improve with AI\" for instructions / guardrails. Omit to hide the buttons. */\n\tonImprove?: (\n\t\tkind: 'instructions' | 'guardrail',\n\t\ttext: string,\n\t) => Promise<string>;\n\t/** Optional \"Improve with AI\" for the Rest API / config-tool drawers. */\n\tonImproveToolInstructions?: (text: string) => Promise<string>;\n\t/**\n\t * Backend templates (email / Slack) that drive the shared config-tool drawer.\n\t * Each present key enables its tool action in this drawer; absent → hidden.\n\t * Same prop the main builder gets — sub-agents can add the same tools.\n\t */\n\tconfigToolTemplates?: Partial<Record<ConfigToolKey, ParamsBlob>>;\n\t/** Header title — \"Create sub-agent\" (default) or \"Edit sub-agent\". */\n\ttitle?: string;\n\t/** Initial values, e.g. when configuring an existing sub-agent. */\n\tinitial?: SubAgentDraft;\n\t/** Tool-source fallback label for chips (host app). */\n\tappLabel?: string;\n\t/** Resolved character limits (defaults to {@link AGENT_CHAR_LIMITS}). */\n\tcharLimits?: AgentCharLimits;\n}\n\n/**\n * Right-side drawer for creating / editing a sub-agent (name, instructions,\n * guardrails, tools). Instructions & Guardrails are `@`-mention editors (tools\n * only — sub-agents can't nest); adding a tool from the list inserts it at the\n * last-focused field's cursor. Mount it fresh per open (key it) so `initial`\n * seeds the draft.\n */\nexport const CreateSubAgentPanel: React.FC<CreateSubAgentPanelProps> = ({\n\tonClose,\n\tonSave,\n\tavailableTools,\n\tonImprove,\n\tonImproveToolInstructions,\n\tconfigToolTemplates,\n\ttitle = 'Create sub-agent',\n\tinitial,\n\tappLabel = 'Manifest',\n\tcharLimits = AGENT_CHAR_LIMITS,\n}) => {\n\tconst [name, setName] = useState(initial?.name ?? '');\n\tconst [instructions, setInstructions] = useState(initial?.instructions ?? '');\n\tconst [guardrail, setGuardrail] = useState(initial?.guardrail ?? '');\n\tconst [tools, setTools] = useState<string[]>(initial?.tools ?? []);\n\t// Inline-configured tools owned by this sub-agent (same drawers as the main\n\t// agent). Local to the drawer; flow to the consumer via the saved draft.\n\tconst [configTools, setConfigTools] = useState<ConfigToolConfig[]>(\n\t\tinitial?.configTools ?? [],\n\t);\n\tconst [restApiTools, setRestApiTools] = useState<RestApiToolConfig[]>(\n\t\tinitial?.restApiTools ?? [],\n\t);\n\tconst [toolDrawer, setToolDrawer] = useState<ToolDrawerState | null>(null);\n\tconst toolDrawerKeyRef = useRef(0);\n\tconst [saving, setSaving] = useState(false);\n\t// Bumped to remount a field after its text is replaced (e.g. by Improve).\n\tconst [instrKey, setInstrKey] = useState(0);\n\tconst [guardKey, setGuardKey] = useState(0);\n\tconst [improving, setImproving] = useState<\n\t\t'instructions' | 'guardrail' | null\n\t>(null);\n\n\t// Tools-only mention list (sub-agents can't reference other sub-agents), PLUS\n\t// this drawer's inline custom tools so their `{{tool:<id>}}` tokens rehydrate\n\t// as chips on remount (they aren't in `availableTools`).\n\tconst mentionItems = useMemo(\n\t\t() => [\n\t\t\t...buildAgentMentionItems(availableTools, [], appLabel),\n\t\t\t...buildCustomToolMentionItems(configTools, restApiTools),\n\t\t],\n\t\t[availableTools, appLabel, configTools, restApiTools],\n\t);\n\n\t// Per-field insert + focus registry, so the Tools list inserts a chip into the\n\t// last-focused editor at its cursor.\n\tconst insertersRef = useRef<\n\t\tPartial<Record<'instructions' | 'guardrail', InsertFn>>\n\t>({});\n\tconst lastFocusedRef = useRef<'instructions' | 'guardrail'>('instructions');\n\tconst registerInstr = useCallback((fn: InsertFn | null) => {\n\t\tinsertersRef.current.instructions = fn ?? undefined;\n\t}, []);\n\tconst registerGuard = useCallback((fn: InsertFn | null) => {\n\t\tinsertersRef.current.guardrail = fn ?? undefined;\n\t}, []);\n\tconst focusInstr = useCallback(() => {\n\t\tlastFocusedRef.current = 'instructions';\n\t}, []);\n\tconst focusGuard = useCallback(() => {\n\t\tlastFocusedRef.current = 'guardrail';\n\t}, []);\n\tconst addToolMention = useCallback(\n\t\t(kind: 'tool' | 'subagent', id: string) => {\n\t\t\tif (kind === 'tool') {\n\t\t\t\tsetTools((prev) => addUnique(prev, id));\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\tconst insertToolAtCursor = useCallback((id: string, label?: string) => {\n\t\tconst target =\n\t\t\tinsertersRef.current[lastFocusedRef.current] ??\n\t\t\tinsertersRef.current.instructions;\n\t\ttarget?.('tool', id, label);\n\t}, []);\n\n\t// Rest API (bespoke) + shared config-tool (email / Slack) drawers, same as the\n\t// main builder's Step 3 — here backed by the drawer's local state.\n\t// ponytail: mirrors Step3HowItResponds; kept local rather than sharing a hook\n\t// because Step3 is context-backed and this drawer is local-state.\n\tconst openRestApi = useCallback((tool?: RestApiToolConfig) => {\n\t\ttoolDrawerKeyRef.current += 1;\n\t\tsetToolDrawer({\n\t\t\tkey: toolDrawerKeyRef.current,\n\t\t\tkind: 'restapi',\n\t\t\tinitialRest: tool,\n\t\t});\n\t}, []);\n\tconst openConfigTool = useCallback(\n\t\t(toolKey: ConfigToolKey, tool?: ConfigToolConfig) => {\n\t\t\ttoolDrawerKeyRef.current += 1;\n\t\t\tsetToolDrawer({\n\t\t\t\tkey: toolDrawerKeyRef.current,\n\t\t\t\tkind: 'config',\n\t\t\t\ttoolKey,\n\t\t\t\tinitialConfig: tool,\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\tconst openToolAction = useCallback(\n\t\t(source: ToolSource) => {\n\t\t\tconst toolKey = CONFIG_TOOL_SOURCES[source];\n\t\t\tif (toolKey) {\n\t\t\t\topenConfigTool(toolKey);\n\t\t\t} else {\n\t\t\t\topenRestApi();\n\t\t\t}\n\t\t},\n\t\t[openConfigTool, openRestApi],\n\t);\n\tconst handleSaveRestApi = useCallback(\n\t\t(tool: RestApiToolConfig) => {\n\t\t\tconst isNew = !restApiTools.some((t) => t.id === tool.id);\n\t\t\tsetRestApiTools((prev) => upsertById(prev, tool));\n\t\t\t// Drop a reference chip at the cursor on creation (edits keep the chip).\n\t\t\tif (isNew) {\n\t\t\t\tinsertToolAtCursor(tool.id, restApiMentionItem(tool).label);\n\t\t\t}\n\t\t\tsetToolDrawer(null);\n\t\t},\n\t\t[restApiTools, insertToolAtCursor],\n\t);\n\tconst handleSaveConfigTool = useCallback(\n\t\t(tool: ConfigToolConfig) => {\n\t\t\tconst isNew = !configTools.some((t) => t.id === tool.id);\n\t\t\tsetConfigTools((prev) => upsertById(prev, tool));\n\t\t\tif (isNew) {\n\t\t\t\tinsertToolAtCursor(tool.id, configToolMentionItem(tool).label);\n\t\t\t}\n\t\t\tsetToolDrawer(null);\n\t\t},\n\t\t[configTools, insertToolAtCursor],\n\t);\n\n\t// Local undo toast for tool removal (drawer state isn't in AgentValue).\n\tconst [undo, setUndo] = useState<{ id: number; message: string } | null>(\n\t\tnull,\n\t);\n\tconst undoSnapshotRef = useRef<{\n\t\tinstructions: string;\n\t\tguardrail: string;\n\t\ttools: string[];\n\t\tconfigTools: ConfigToolConfig[];\n\t\trestApiTools: RestApiToolConfig[];\n\t} | null>(null);\n\tconst undoIdRef = useRef(0);\n\n\t// Remove ANY tool by id: strip its `{{tool:<id>}}` tokens, remount the fields,\n\t// and drop it from whichever list holds it (catalog `tools` or an inline\n\t// custom-tool list). One undo restores all of it.\n\tconst removeTool = (id: string) => {\n\t\tconst label =\n\t\t\tavailableTools.find((t) => t.tool_id === id)?.display_name ??\n\t\t\trestApiTools.find((t) => t.id === id)?.name ??\n\t\t\t'Tool';\n\t\t// The token stores the tool id (a tool's id is its tool_id).\n\t\tconst token = `{{tool:${id}}}`;\n\t\tconst strip = (text: string) => text.split(token).join('');\n\t\tundoSnapshotRef.current = {\n\t\t\tinstructions,\n\t\t\tguardrail,\n\t\t\ttools,\n\t\t\tconfigTools,\n\t\t\trestApiTools,\n\t\t};\n\t\tsetInstructions((prev) => strip(prev));\n\t\tsetGuardrail((prev) => strip(prev));\n\t\tsetTools((prev) => prev.filter((t) => t !== id));\n\t\tsetConfigTools((prev) => prev.filter((t) => t.id !== id));\n\t\tsetRestApiTools((prev) => prev.filter((t) => t.id !== id));\n\t\tsetInstrKey((k) => k + 1);\n\t\tsetGuardKey((k) => k + 1);\n\t\tundoIdRef.current += 1;\n\t\tsetUndo({ id: undoIdRef.current, message: `Tool \"${label}\" removed` });\n\t};\n\n\tconst undoRemove = () => {\n\t\tconst snap = undoSnapshotRef.current;\n\t\tif (snap) {\n\t\t\tsetInstructions(snap.instructions);\n\t\t\tsetGuardrail(snap.guardrail);\n\t\t\tsetTools(snap.tools);\n\t\t\tsetConfigTools(snap.configTools);\n\t\t\tsetRestApiTools(snap.restApiTools);\n\t\t\tsetInstrKey((k) => k + 1);\n\t\t\tsetGuardKey((k) => k + 1);\n\t\t\tundoSnapshotRef.current = null;\n\t\t}\n\t\tsetUndo(null);\n\t};\n\n\tconst canSave =\n\t\tname.trim().length > 0 &&\n\t\t(instructions.trim().length > 0 || guardrail.trim().length > 0);\n\n\tconst toolItems: SelectableItem[] = tools\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst tool = availableTools.find((t) => t.tool_id === id);\n\t\t\treturn tool\n\t\t\t\t? {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tlabel: tool.display_name,\n\t\t\t\t\t\ticon: sourceIcon(tool.source ?? ToolSource.Manifest),\n\t\t\t\t }\n\t\t\t\t: null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\t// Inline-configured tools (Rest API + email / Slack) render as rows in the same\n\t// list, each with its own Configure (edit) action that reopens its drawer.\n\tconst restApiItems: SelectableItem[] = restApiTools.map((t) => ({\n\t\tid: t.id,\n\t\tlabel: restApiToolName(t),\n\t\ticon: SOURCE_ICONS[ToolSource.RestApi],\n\t\tonConfigure: () => openRestApi(t),\n\t}));\n\tconst configToolItems: SelectableItem[] = configTools.map((t) => ({\n\t\tid: t.id,\n\t\tlabel: configToolName(t),\n\t\ticon: SOURCE_ICONS[\n\t\t\tt.tool_key === 'send_slack_message'\n\t\t\t\t? ToolSource.Slack\n\t\t\t\t: ToolSource.EmailHandover\n\t\t],\n\t\tonConfigure: () => openConfigTool(t.tool_key, t),\n\t}));\n\tconst allToolItems: SelectableItem[] = [\n\t\t...toolItems,\n\t\t...restApiItems,\n\t\t...configToolItems,\n\t];\n\n\t// Built-in tool actions (Rest API / email / Slack); the shared email / Slack\n\t// forms appear only when their backend template was provided.\n\tconst toolActionSources = buildToolActions(\n\t\tconfigToolTemplates,\n\t\topenToolAction,\n\t);\n\n\tconst openConfigTemplate =\n\t\ttoolDrawer?.kind === 'config' && toolDrawer.toolKey\n\t\t\t? configToolTemplates?.[toolDrawer.toolKey]\n\t\t\t: undefined;\n\n\t// Offer all tools (re-add allowed); the chip list stays deduped. Icon left of\n\t// the name, no description.\n\tconst toolOptions: SingleOption[] = availableTools.map((t) => ({\n\t\tlabel: t.display_name,\n\t\tvalue: t.tool_id,\n\t\tleadingIcon:\n\t\t\trenderSourceIcon(sourceIcon(t.source ?? ToolSource.Manifest)) ??\n\t\t\tundefined,\n\t}));\n\n\t// Group tools by source (Manifest / Shopify / …) so the empty state shows the\n\t// same per-source buttons as the main builder's side panel.\n\tconst toolSourceGroups: SourceGroup[] = (() => {\n\t\tconst order: string[] = [];\n\t\tconst bySource = new Map<string, SingleOption[]>();\n\t\tavailableTools.forEach((t) => {\n\t\t\tconst src = t.source ?? ToolSource.Manifest;\n\t\t\tif (!bySource.has(src)) {\n\t\t\t\tbySource.set(src, []);\n\t\t\t\torder.push(src);\n\t\t\t}\n\t\t\tbySource.get(src)?.push({\n\t\t\t\tlabel: t.display_name,\n\t\t\t\tvalue: t.tool_id,\n\t\t\t\tleadingIcon:\n\t\t\t\t\trenderSourceIcon(sourceIcon(t.source ?? ToolSource.Manifest)) ??\n\t\t\t\t\tundefined,\n\t\t\t});\n\t\t});\n\t\treturn order.map((src) => ({\n\t\t\tsource: src,\n\t\t\tlabel: toolSourceLabel(src),\n\t\t\toptions: bySource.get(src) ?? [],\n\t\t}));\n\t})();\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst result = onSave({\n\t\t\tname: name.trim(),\n\t\t\tinstructions,\n\t\t\tguardrail,\n\t\t\ttools,\n\t\t\tconfigTools,\n\t\t\trestApiTools,\n\t\t});\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetSaving(true);\n\t\t\ttry {\n\t\t\t\tawait result;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleImprove = async (kind: 'instructions' | 'guardrail') => {\n\t\tif (!onImprove || improving) {\n\t\t\treturn;\n\t\t}\n\t\tsetImproving(kind);\n\t\ttry {\n\t\t\tconst current = kind === 'instructions' ? instructions : guardrail;\n\t\t\tconst improved = await onImprove(kind, current);\n\t\t\tif (kind === 'instructions') {\n\t\t\t\tsetInstructions(improved);\n\t\t\t\tsetInstrKey((k) => k + 1);\n\t\t\t} else {\n\t\t\t\tsetGuardrail(improved);\n\t\t\t\tsetGuardKey((k) => k + 1);\n\t\t\t}\n\t\t} finally {\n\t\t\tsetImproving(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SideModal\n\t\t\t\theader={title}\n\t\t\t\tcloseOnEscapeKey={false}\n\t\t\t\tzIndex={SUBAGENT_ZINDEX}\n\t\t\t\theaderCustomComponent={\n\t\t\t\t\t<DrawerHeaderText\n\t\t\t\t\t\ttitle={title}\n\t\t\t\t\t\tsubtitle=\"Each sub-agent handles one piece of the job. Use @ in the main instructions to call them.\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\twidth=\"421px\"\n\t\t\t\theaderStyle={DRAWER_HEADER_STYLE}\n\t\t\t\tbodyStyle={DRAWER_BODY_STYLE}\n\t\t\t\tonClose={onClose}\n\t\t\t\tsaveButtonProps={{\n\t\t\t\t\t'data-test': 'subagent-save',\n\t\t\t\t\tbuttonText: 'Save',\n\t\t\t\t\tbuttonType: 'primary',\n\t\t\t\t\tsize: 'small',\n\t\t\t\t\tdisabled: !canSave,\n\t\t\t\t\tisLoading: saving,\n\t\t\t\t\tonClick: handleSave,\n\t\t\t\t}}\n\t\t\t\tcancelButtonProps={{\n\t\t\t\t\t'data-test': 'subagent-cancel',\n\t\t\t\t\tbuttonText: 'Cancel',\n\t\t\t\t\tbuttonType: 'tertiaryGray',\n\t\t\t\t\tsize: 'small',\n\t\t\t\t\tonClick: onClose,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<Input\n\t\t\t\t\tdata-test=\"subagent-name\"\n\t\t\t\t\tlabelText=\"Agent name\"\n\t\t\t\t\tlabelTextBold\n\t\t\t\t\tplaceholder=\"Enter agent name\"\n\t\t\t\t\tvalue={name}\n\t\t\t\t\tmaxCharLimit={charLimits.name}\n\t\t\t\t\tmaxCharLimitPosition=\"TOP\"\n\t\t\t\t\tmaxCharStyle={{ fontSize: 12, lineHeight: '16px' }}\n\t\t\t\t\tonChangeText={setName}\n\t\t\t\t/>\n\n\t\t\t\t<MentionEditor\n\t\t\t\t\tdata-test=\"subagent-instructions\"\n\t\t\t\t\tlabel=\"Instructions\"\n\t\t\t\t\tvalue={instructions}\n\t\t\t\t\tonChange={setInstructions}\n\t\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\t\tplaceholder=\"Write the steps in plain English. Type @ to reference a tool.\"\n\t\t\t\t\tminHeight=\"160px\"\n\t\t\t\t\tresetKey={`instr-${instrKey}`}\n\t\t\t\t\tmentionItems={mentionItems}\n\t\t\t\t\ttools={availableTools}\n\t\t\t\t\ttoolActions={toolActionSources}\n\t\t\t\t\tonMentionSelect={addToolMention}\n\t\t\t\t\tonFocus={focusInstr}\n\t\t\t\t\tregisterInsert={registerInstr}\n\t\t\t\t\taction={\n\t\t\t\t\t\tonImprove ? (\n\t\t\t\t\t\t\t<ImproveButton\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tdata-test=\"subagent-improve-instructions\"\n\t\t\t\t\t\t\t\tdisabled={improving !== null}\n\t\t\t\t\t\t\t\tonClick={() => handleImprove('instructions')}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{improving === 'instructions'\n\t\t\t\t\t\t\t\t\t? 'Improving…'\n\t\t\t\t\t\t\t\t\t: 'Improve with AI'}\n\t\t\t\t\t\t\t</ImproveButton>\n\t\t\t\t\t\t) : undefined\n\t\t\t\t\t}\n\t\t\t\t/>\n\n\t\t\t\t<MentionEditor\n\t\t\t\t\tdata-test=\"subagent-guardrail\"\n\t\t\t\t\tlabel=\"Guardrails\"\n\t\t\t\t\tvalue={guardrail}\n\t\t\t\t\tonChange={setGuardrail}\n\t\t\t\t\tmaxLength={charLimits.guardrail}\n\t\t\t\t\tplaceholder=\"e.g. Never discuss competitor pricing. Type @ to reference a tool.\"\n\t\t\t\t\tminHeight=\"160px\"\n\t\t\t\t\tresetKey={`guard-${guardKey}`}\n\t\t\t\t\tmentionItems={mentionItems}\n\t\t\t\t\ttools={availableTools}\n\t\t\t\t\ttoolActions={toolActionSources}\n\t\t\t\t\tonMentionSelect={addToolMention}\n\t\t\t\t\tonFocus={focusGuard}\n\t\t\t\t\tregisterInsert={registerGuard}\n\t\t\t\t\taction={\n\t\t\t\t\t\tonImprove ? (\n\t\t\t\t\t\t\t<ImproveButton\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tdata-test=\"subagent-improve-guardrail\"\n\t\t\t\t\t\t\t\tdisabled={improving !== null}\n\t\t\t\t\t\t\t\tonClick={() => handleImprove('guardrail')}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{improving === 'guardrail' ? 'Improving…' : 'Improve with AI'}\n\t\t\t\t\t\t\t</ImproveButton>\n\t\t\t\t\t\t) : undefined\n\t\t\t\t\t}\n\t\t\t\t/>\n\n\t\t\t\t<SelectableListSection\n\t\t\t\t\ttitle=\"Tools this agent can use\"\n\t\t\t\t\tdataTestPrefix=\"subagent-tools\"\n\t\t\t\t\titems={allToolItems}\n\t\t\t\t\taddableOptions={toolOptions}\n\t\t\t\t\tsourceGroups={toolSourceGroups}\n\t\t\t\t\tmentionItems={mentionItems}\n\t\t\t\t\tactionSources={toolActionSources}\n\t\t\t\t\temptyText=\"No tools added yet.\"\n\t\t\t\t\tonAdd={(id) => {\n\t\t\t\t\t\tinsertToolAtCursor(id);\n\t\t\t\t\t\tsetTools((prev) => addUnique(prev, id));\n\t\t\t\t\t}}\n\t\t\t\t\tonRemove={removeTool}\n\t\t\t\t\tconfirmDelete={{ noun: 'tool', zIndex: TOOL_DRAWER_ZINDEX + 1 }}\n\t\t\t\t/>\n\t\t\t</SideModal>\n\n\t\t\t{toolDrawer?.kind === 'restapi' && (\n\t\t\t\t<RestApiToolPanel\n\t\t\t\t\tkey={toolDrawer.key}\n\t\t\t\t\tinitial={toolDrawer.initialRest}\n\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\tonImprove={onImproveToolInstructions}\n\t\t\t\t\tonClose={() => setToolDrawer(null)}\n\t\t\t\t\tonSave={handleSaveRestApi}\n\t\t\t\t\tzIndex={TOOL_DRAWER_ZINDEX}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{toolDrawer?.kind === 'config' &&\n\t\t\t\ttoolDrawer.toolKey &&\n\t\t\t\topenConfigTemplate && (\n\t\t\t\t\t<ConfigToolPanel\n\t\t\t\t\t\tkey={toolDrawer.key}\n\t\t\t\t\t\ttoolKey={toolDrawer.toolKey}\n\t\t\t\t\t\ttemplate={openConfigTemplate}\n\t\t\t\t\t\tinitial={toolDrawer.initialConfig}\n\t\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\t\tonImprove={onImproveToolInstructions}\n\t\t\t\t\t\tonClose={() => setToolDrawer(null)}\n\t\t\t\t\t\tonSave={handleSaveConfigTool}\n\t\t\t\t\t\tzIndex={TOOL_DRAWER_ZINDEX}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\n\t\t\t{undo && (\n\t\t\t\t<Toaster\n\t\t\t\t\tkey={undo.id}\n\t\t\t\t\ttext={undo.message}\n\t\t\t\t\ttype=\"info\"\n\t\t\t\t\tposition=\"top-right\"\n\t\t\t\t\tautoClose={5000}\n\t\t\t\t\thideCloseButton\n\t\t\t\t\tbuttonProps={{\n\t\t\t\t\t\tbuttonText: 'Undo',\n\t\t\t\t\t\tshowButton: true,\n\t\t\t\t\t\tonButtonClick: () => {\n\t\t\t\t\t\t\tundoRemove();\n\t\t\t\t\t\t\treturn {} as Record<string, never>;\n\t\t\t\t\t\t},\n\t\t\t\t\t}}\n\t\t\t\t\tonCloseToast={() => setUndo(null)}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n};\n"],"names":["SUBAGENT_ZINDEX","TOOL_DRAWER_ZINDEX","upsertById","list","item","arr","x","ImproveButton","styled","COLORS","CreateSubAgentPanel","onClose","onSave","availableTools","onImprove","onImproveToolInstructions","configToolTemplates","title","initial","appLabel","charLimits","AGENT_CHAR_LIMITS","name","setName","useState","instructions","setInstructions","guardrail","setGuardrail","tools","setTools","configTools","setConfigTools","restApiTools","setRestApiTools","toolDrawer","setToolDrawer","toolDrawerKeyRef","useRef","saving","setSaving","instrKey","setInstrKey","guardKey","setGuardKey","improving","setImproving","mentionItems","useMemo","buildAgentMentionItems","buildCustomToolMentionItems","insertersRef","lastFocusedRef","registerInstr","useCallback","fn","registerGuard","focusInstr","focusGuard","addToolMention","kind","id","prev","addUnique","insertToolAtCursor","label","openRestApi","tool","openConfigTool","toolKey","openToolAction","source","CONFIG_TOOL_SOURCES","handleSaveRestApi","isNew","t","restApiMentionItem","handleSaveConfigTool","configToolMentionItem","undo","setUndo","undoSnapshotRef","undoIdRef","removeTool","token","strip","text","k","undoRemove","snap","canSave","toolItems","sourceIcon","ToolSource","restApiItems","restApiToolName","SOURCE_ICONS","configToolItems","configToolName","allToolItems","toolActionSources","buildToolActions","openConfigTemplate","toolOptions","renderSourceIcon","toolSourceGroups","order","bySource","src","toolSourceLabel","handleSave","result","handleImprove","improved","jsxs","Fragment","SideModal","jsx","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","Input","MentionEditor","SelectableListSection","RestApiToolPanel","ConfigToolPanel","Toaster"],"mappings":"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"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),i=require("styled-components"),n=require("../../TypographyStyle.js"),o=require("../../../constants/Theme.js"),a=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},r=a(i),d=({title:e,subtitle:l})=>t.jsx(p,{children:t.jsxs(x,{children:[t.jsx(n.TitleRegular,{color:o.COLORS.content.primary,children:e}),t.jsx(n.BodySecondary,{color:o.COLORS.content.secondary,children:l})]})}),s={padding:"16px",display:"flex","flex-direction":"column",gap:"16px"},c={height:"auto","min-height":"60px","align-items":"flex-start",padding:"10px 12px",color:o.COLORS.content.secondary},p=r.default.div`
|
|
2
2
|
display: flex;
|
|
3
3
|
flex: 1;
|
|
4
4
|
align-items: flex-start;
|
|
5
5
|
gap: 8px;
|
|
6
6
|
min-width: 0;
|
|
7
|
-
`,
|
|
7
|
+
`,x=r.default.div`
|
|
8
8
|
display: flex;
|
|
9
9
|
flex: 1;
|
|
10
10
|
flex-direction: column;
|
|
11
11
|
min-width: 0;
|
|
12
12
|
/* Wrap long subtitles instead of overflowing past the close icon. */
|
|
13
13
|
overflow-wrap: anywhere;
|
|
14
|
-
`;exports.DRAWER_BODY_STYLE=
|
|
14
|
+
`;exports.DRAWER_BODY_STYLE=s;exports.DRAWER_HEADER_STYLE=c;exports.DrawerHeaderText=d;
|
|
15
15
|
//# sourceMappingURL=DrawerHeaderText.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DrawerHeaderText.js","sources":["../../../../../src/components/agent-builder/components/DrawerHeaderText.tsx"],"sourcesContent":["import React from 'react';\nimport styled from 'styled-components';\nimport { BodySecondary, TitleRegular } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\
|
|
1
|
+
{"version":3,"file":"DrawerHeaderText.js","sources":["../../../../../src/components/agent-builder/components/DrawerHeaderText.tsx"],"sourcesContent":["import React from 'react';\nimport styled from 'styled-components';\nimport { BodySecondary, TitleRegular } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\n\n/**\n * Title + subtitle for a tool drawer, passed to `SideModal`'s\n * `headerCustomComponent` (its default header is a single title line). No icon or\n * back button — the drawer already has `SideModal`'s close button.\n */\nexport const DrawerHeaderText: React.FC<{\n\ttitle: string;\n\tsubtitle: string;\n}> = ({ title, subtitle }) => (\n\t<HeaderRow>\n\t\t<HeaderCol>\n\t\t\t<TitleRegular color={COLORS.content.primary}>{title}</TitleRegular>\n\t\t\t<BodySecondary color={COLORS.content.secondary}>{subtitle}</BodySecondary>\n\t\t</HeaderCol>\n\t</HeaderRow>\n);\n\n/**\n * Body layout for the tool drawers: a 16px-padded column with a consistent gap.\n *\n * NOTE: `SideModal` interpolates these keys verbatim into CSS, so multi-word\n * properties must be written kebab-case (`flex-direction`, not `flexDirection`)\n * — hence the `as unknown as` cast past the camelCase `CSSProperties` type.\n */\nexport const DRAWER_BODY_STYLE = {\n\tpadding: '16px',\n\tdisplay: 'flex',\n\t'flex-direction': 'column',\n\tgap: '16px',\n} as unknown as React.CSSProperties;\n\n/**\n * Let the header grow past its fixed 60px to fit the subtitle. `color` sets the\n * inherited colour for `SideModal`'s close icon (its `cross.svg` uses\n * `fill: currentColor`, and the header itself sets no colour → otherwise it\n * renders invisible). The title/subtitle set their own colours, so they're\n * unaffected.\n */\nexport const DRAWER_HEADER_STYLE = {\n\theight: 'auto',\n\t'min-height': '60px',\n\t'align-items': 'flex-start',\n\tpadding: '10px 12px',\n\tcolor: COLORS.content.secondary,\n} as unknown as React.CSSProperties;\n\nconst HeaderRow = styled.div`\n\tdisplay: flex;\n\tflex: 1;\n\talign-items: flex-start;\n\tgap: 8px;\n\tmin-width: 0;\n`;\n\nconst HeaderCol = styled.div`\n\tdisplay: flex;\n\tflex: 1;\n\tflex-direction: column;\n\tmin-width: 0;\n\t/* Wrap long subtitles instead of overflowing past the close icon. */\n\toverflow-wrap: anywhere;\n`;\n"],"names":["DrawerHeaderText","title","subtitle","jsx","HeaderRow","jsxs","HeaderCol","TitleRegular","COLORS","BodySecondary","DRAWER_BODY_STYLE","DRAWER_HEADER_STYLE","styled"],"mappings":"kSAUaA,EAGR,CAAC,CAAE,MAAAC,EAAO,SAAAC,KACdC,EAAAA,IAACC,EAAA,CACA,SAAAC,EAAAA,KAACC,EAAA,CACA,SAAA,CAAAH,MAACI,EAAAA,aAAA,CAAa,MAAOC,EAAAA,OAAO,QAAQ,QAAU,SAAAP,EAAM,QACnDQ,EAAAA,cAAA,CAAc,MAAOD,EAAAA,OAAO,QAAQ,UAAY,SAAAN,CAAA,CAAS,CAAA,CAAA,CAC3D,CAAA,CACD,EAUYQ,EAAoB,CAChC,QAAS,OACT,QAAS,OACT,iBAAkB,SAClB,IAAK,MACN,EASaC,EAAsB,CAClC,OAAQ,OACR,aAAc,OACd,cAAe,aACf,QAAS,YACT,MAAOH,EAAAA,OAAO,QAAQ,SACvB,EAEMJ,EAAYQ,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQnBN,EAAYM,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const $=require("react/jsx-runtime"),n=require("react"),j=require("../context/AgentBuilderContext.js"),i=require("../utils/mentionSerialization.js"),h=require("../utils/toolActions.js"),k=require("./MentionEditor.js"),y=({fieldKey:e,label:b,placeholder:A,maxLength:d,minHeight:T,...m})=>{const{value:t,patch:M,addReference:r,availableTools:s,availableSubAgents:l,applicationType:a,mentionResetKey:p,registerMentionField:u,notifyMentionFocus:C,onCreateSubAgent:q,requestCreateSubAgent:S,requestToolAction:c,configToolTemplates:g}=j.useAgentBuilderContext(),v=n.useMemo(()=>[...i.buildAgentMentionItems(s,l,i.appTypeLabel(a)),...i.buildCustomToolMentionItems(t.configTools,t.restApiTools)],[s,l,a,t.configTools,t.restApiTools]),F=n.useMemo(()=>h.buildToolActions(g,c),[c,g]),x=n.useCallback(o=>u(e,o),[u,e]),I=n.useCallback((o,R)=>r(o,R),[r]);return $.jsx(k.MentionEditor,{label:b,value:t[e]??"",onChange:o=>M({[e]:o}),maxLength:d,placeholder:A,minHeight:T,resetKey:`${t.id}:${e}:${p}`,mentionItems:v,tools:s,onMentionSelect:I,onFocus:()=>C(e),registerInsert:x,onCreateSubAgent:q?S:void 0,toolActions:F,"data-test":m["data-test"]})};exports.MentionField=y;
|
|
2
2
|
//# sourceMappingURL=MentionField.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MentionField.js","sources":["../../../../../src/components/agent-builder/components/MentionField.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from 'react';\nimport { AgentValue } from '../AgentBuilder.model';\nimport {
|
|
1
|
+
{"version":3,"file":"MentionField.js","sources":["../../../../../src/components/agent-builder/components/MentionField.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from 'react';\nimport { AgentValue } from '../AgentBuilder.model';\nimport { ToolAction } from '../constants/tools';\nimport {\n\tMentionFieldKey,\n\tuseAgentBuilderContext,\n} from '../context/AgentBuilderContext';\nimport {\n\tappTypeLabel,\n\tbuildAgentMentionItems,\n\tbuildCustomToolMentionItems,\n} from '../utils/mentionSerialization';\nimport { buildToolActions } from '../utils/toolActions';\nimport { MentionEditor } from './MentionEditor';\n\ninterface MentionFieldProps {\n\t/** Which AgentValue field this editor reads / writes. */\n\tfieldKey: MentionFieldKey;\n\tlabel: string;\n\tplaceholder?: string;\n\tmaxLength: number;\n\tminHeight?: string;\n\t'data-test'?: string;\n}\n\n/**\n * Context-bound {@link MentionEditor} for the builder's Step-3 Instructions /\n * Guardrails. Both `@` tools and sub-agents are offered; the field registers its\n * insert + focus with the context so side-panel adds drop a chip into whichever\n * field was last focused, and remounts on `mentionResetKey`.\n */\nexport const MentionField: React.FC<MentionFieldProps> = ({\n\tfieldKey,\n\tlabel,\n\tplaceholder,\n\tmaxLength,\n\tminHeight,\n\t...rest\n}) => {\n\tconst {\n\t\tvalue,\n\t\tpatch,\n\t\taddReference,\n\t\tavailableTools,\n\t\tavailableSubAgents,\n\t\tapplicationType,\n\t\tmentionResetKey,\n\t\tregisterMentionField,\n\t\tnotifyMentionFocus,\n\t\tonCreateSubAgent,\n\t\trequestCreateSubAgent,\n\t\trequestToolAction,\n\t\tconfigToolTemplates,\n\t} = useAgentBuilderContext();\n\n\t// Catalog tools + sub-agents, PLUS the inline custom tools (Rest API / email /\n\t// Slack) so their `{{tool:<id>}}` tokens rehydrate as chips on remount — they\n\t// live on the value, not in `availableTools`.\n\tconst mentionItems = useMemo(\n\t\t() => [\n\t\t\t...buildAgentMentionItems(\n\t\t\t\tavailableTools,\n\t\t\t\tavailableSubAgents,\n\t\t\t\tappTypeLabel(applicationType),\n\t\t\t),\n\t\t\t...buildCustomToolMentionItems(value.configTools, value.restApiTools),\n\t\t],\n\t\t[\n\t\t\tavailableTools,\n\t\t\tavailableSubAgents,\n\t\t\tapplicationType,\n\t\t\tvalue.configTools,\n\t\t\tvalue.restApiTools,\n\t\t],\n\t);\n\n\t// Built-in tool actions (Rest API / email / Slack) shown in the `@` picker's\n\t// Tools view — picking one opens its drawer (Step 3) instead of inserting text.\n\t// The shared email / Slack forms are backend-driven: each is offered only when\n\t// its template was provided.\n\tconst toolActions = useMemo<ToolAction[]>(\n\t\t() => buildToolActions(configToolTemplates, requestToolAction),\n\t\t[requestToolAction, configToolTemplates],\n\t);\n\n\tconst registerInsert = useCallback(\n\t\t(fn: Parameters<typeof registerMentionField>[1]) =>\n\t\t\tregisterMentionField(fieldKey, fn),\n\t\t[registerMentionField, fieldKey],\n\t);\n\n\t// Route through the context's ref-backed `addReference`: BikEditor captures\n\t// this handler at mount, so reading `value.tools` here would keep only the last\n\t// pick. `addReference` always appends against the latest lists.\n\tconst onMentionSelect = useCallback(\n\t\t(kind: 'tool' | 'subagent', id: string) => addReference(kind, id),\n\t\t[addReference],\n\t);\n\n\treturn (\n\t\t<MentionEditor\n\t\t\tlabel={label}\n\t\t\tvalue={(value[fieldKey] as string | undefined) ?? ''}\n\t\t\tonChange={(text) => patch({ [fieldKey]: text } as Partial<AgentValue>)}\n\t\t\tmaxLength={maxLength}\n\t\t\tplaceholder={placeholder}\n\t\t\tminHeight={minHeight}\n\t\t\tresetKey={`${value.id}:${fieldKey}:${mentionResetKey}`}\n\t\t\tmentionItems={mentionItems}\n\t\t\ttools={availableTools}\n\t\t\tonMentionSelect={onMentionSelect}\n\t\t\tonFocus={() => notifyMentionFocus(fieldKey)}\n\t\t\tregisterInsert={registerInsert}\n\t\t\tonCreateSubAgent={onCreateSubAgent ? requestCreateSubAgent : undefined}\n\t\t\ttoolActions={toolActions}\n\t\t\tdata-test={rest['data-test']}\n\t\t/>\n\t);\n};\n"],"names":["MentionField","fieldKey","label","placeholder","maxLength","minHeight","rest","value","patch","addReference","availableTools","availableSubAgents","applicationType","mentionResetKey","registerMentionField","notifyMentionFocus","onCreateSubAgent","requestCreateSubAgent","requestToolAction","configToolTemplates","useAgentBuilderContext","mentionItems","useMemo","buildAgentMentionItems","appTypeLabel","buildCustomToolMentionItems","toolActions","buildToolActions","registerInsert","useCallback","fn","onMentionSelect","kind","id","jsx","MentionEditor","text"],"mappings":"0SA+BaA,EAA4C,CAAC,CACzD,SAAAC,EACA,MAAAC,EACA,YAAAC,EACA,UAAAC,EACA,UAAAC,EACA,GAAGC,CACJ,IAAM,CACL,KAAM,CACL,MAAAC,EACA,MAAAC,EACA,aAAAC,EACA,eAAAC,EACA,mBAAAC,EACA,gBAAAC,EACA,gBAAAC,EACA,qBAAAC,EACA,mBAAAC,EACA,iBAAAC,EACA,sBAAAC,EACA,kBAAAC,EACA,oBAAAC,CAAA,EACGC,yBAAA,EAKEC,EAAeC,EAAAA,QACpB,IAAM,CACL,GAAGC,EAAAA,uBACFb,EACAC,EACAa,EAAAA,aAAaZ,CAAe,CAAA,EAE7B,GAAGa,8BAA4BlB,EAAM,YAAaA,EAAM,YAAY,CAAA,EAErE,CACCG,EACAC,EACAC,EACAL,EAAM,YACNA,EAAM,YAAA,CACP,EAOKmB,EAAcJ,EAAAA,QACnB,IAAMK,EAAAA,iBAAiBR,EAAqBD,CAAiB,EAC7D,CAACA,EAAmBC,CAAmB,CAAA,EAGlCS,EAAiBC,EAAAA,YACrBC,GACAhB,EAAqBb,EAAU6B,CAAE,EAClC,CAAChB,EAAsBb,CAAQ,CAAA,EAM1B8B,EAAkBF,EAAAA,YACvB,CAACG,EAA2BC,IAAexB,EAAauB,EAAMC,CAAE,EAChE,CAACxB,CAAY,CAAA,EAGd,OACCyB,EAAAA,IAACC,EAAAA,cAAA,CACA,MAAAjC,EACA,MAAQK,EAAMN,CAAQ,GAA4B,GAClD,SAAWmC,GAAS5B,EAAM,CAAE,CAACP,CAAQ,EAAGmC,EAA6B,EACrE,UAAAhC,EACA,YAAAD,EACA,UAAAE,EACA,SAAU,GAAGE,EAAM,EAAE,IAAIN,CAAQ,IAAIY,CAAe,GACpD,aAAAQ,EACA,MAAOX,EACP,gBAAAqB,EACA,QAAS,IAAMhB,EAAmBd,CAAQ,EAC1C,eAAA2B,EACA,iBAAkBZ,EAAmBC,EAAwB,OAAA,YAC7DS,EACA,YAAWpB,EAAK,WAAW,CAAA,CAAA,CAG9B"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),F=require("../../../assets/icons/chevronRight.svg.js"),G=require("../../../assets/icons/searchIcon.svg.js"),J=require("../../../icons/Arrows/Normal arrows/ArrowLeft.js"),l=require("react"),Q=require("styled-components"),M=require("../../TypographyStyle.js"),i=require("../../../constants/Theme.js"),T=require("../constants/tools.js"),P=require("../utils/mentionSerialization.js"),C=require("../utils/sourceIcons.js"),V=n=>n&&typeof n=="object"&&"default"in n?n:{default:n},p=V(Q),m=n=>n.meta,R=n=>m(n)?.plainLabel??n.label,W="__bik_create_subagent__",X=({items:n,onSelect:L,registerKeyHandler:v,onClose:I,onCreateSubAgent:b,initialSource:D,toolActions:h})=>{const[z,j]=l.useState(null),[c,$]=l.useState(D??null),[O,g]=l.useState(0),[k,_]=l.useState(""),x=l.useMemo(()=>n.filter(e=>m(e)?.kind==="tool"),[n]),S=l.useMemo(()=>n.filter(e=>m(e)?.kind==="subagent"),[n]),E=l.useMemo(()=>{const e=[];return x.forEach(r=>{const f=m(r)?.source??"other";e.includes(f)||e.push(f)}),e},[x]),q=l.useMemo(()=>new Map((h??[]).map(e=>[e.source,e])),[h]),w=l.useMemo(()=>T.CATEGORIES.filter(e=>e.key==="tool"?x.length>0||(h?.length??0)>0:S.length>0||!!b),[x.length,S.length,b,h?.length]),B=w.length===1?w[0].key:null,s=z??B,d=s?s==="subagent"?{title:"Sub-agent",onBack:B?void 0:()=>j(null)}:c?{title:P.toolSourceLabel(c),onBack:()=>$(null),icon:C.sourceIcon(c)}:{title:"Tools",onBack:B?void 0:()=>j(null)}:null,u=l.useMemo(()=>{if(!s)return w.map(t=>({id:t.key,label:t.label,drillsIn:!0,onActivate:()=>{j(t.key),$(null)}}));if(s==="subagent"){const t=k.trim().toLowerCase(),o=S.filter(y=>!t||R(y).toLowerCase().includes(t)).map(y=>({id:String(y.id),label:R(y),drillsIn:!1,onActivate:()=>L(y)}));return b&&o.push({id:W,label:"Create new",drillsIn:!1,isCreate:!0,onActivate:()=>{I?.(),b()}}),o}if(!c){const t=(h??[]).map(o=>o.source).filter(o=>!E.includes(o));return[...E,...t].map(o=>({id:o,label:P.toolSourceLabel(o),drillsIn:!0,icon:C.sourceIcon(o)??q.get(o)?.icon,onActivate:()=>$(o)}))}const e=k.trim().toLowerCase(),r=x.filter(t=>(m(t)?.source??"other")===c).filter(t=>!e||R(t).toLowerCase().includes(e)).map(t=>({id:String(t.id),label:R(t),drillsIn:!1,onActivate:()=>L(t)})),f=q.get(c);if(f){const t=c in T.CONFIG_TOOL_SOURCES;r.push({id:`create:${c}`,label:f.label,drillsIn:!1,isCreate:!t,onActivate:()=>{I?.(),f.onSelect()}})}return r},[s,w,c,k,x,S,E,L,I,b,h,q]);l.useEffect(()=>g(0),[s,c,k,n]),l.useEffect(()=>_(""),[s,c]);const A=l.useRef({rows:u,activeIndex:O,header:d});A.current={rows:u,activeIndex:O,header:d},l.useEffect(()=>{if(v)return v(e=>{const{rows:r,activeIndex:f,header:t}=A.current;switch(e.key){case"ArrowDown":return r.length&&g(o=>(o+1)%r.length),!0;case"ArrowUp":return r.length&&g(o=>(o+r.length-1)%r.length),!0;case"ArrowRight":case"Enter":return r[f]?.onActivate(),!0;case"ArrowLeft":return t?.onBack?(t.onBack(),!0):!1;default:return!1}}),()=>v(null)},[v]);const N=s?u.length&&!u[0].drillsIn?"items":"sources":"categories",U=s==="tool"&&!!c||s==="subagent";return a.jsxs(Y,{className:`bik-mention-picker bik-mention-picker--${N}`,children:[d&&a.jsxs(ne,{type:"button",onClick:d.onBack,disabled:!d.onBack,style:{background:i.COLORS.surface.subdued,cursor:d.onBack?"pointer":"default"},children:[d.onBack&&a.jsx(J.default,{width:20,height:20,color:i.COLORS.content.primary}),d.icon&&C.renderSourceIcon(d.icon),a.jsxs(M.TitleSmall,{children:[" ",d.title]})]}),U&&a.jsxs(Z,{children:[a.jsx(G.default,{width:20,height:20,color:i.COLORS.content.placeholder}),a.jsx(K,{autoFocus:!0,value:k,placeholder:"Search","data-test":"mention-picker-search",onChange:e=>_(e.target.value),onKeyDown:e=>{u.length&&(e.key==="ArrowDown"?(e.preventDefault(),g(r=>(r+1)%u.length)):e.key==="ArrowUp"?(e.preventDefault(),g(r=>(r+u.length-1)%u.length)):e.key==="Enter"&&(e.preventDefault(),u[O]?.onActivate()))}})]}),u.length===0?a.jsx(re,{children:s==="subagent"?"No sub-agents available":"No tools available"}):u.map((e,r)=>a.jsx(H,{type:"button",$active:r===O,onMouseEnter:()=>g(r),onClick:e.onActivate,children:e.isCreate?a.jsx(te,{children:e.label}):a.jsxs(a.Fragment,{children:[a.jsxs(ee,{children:[C.renderSourceIcon(e.icon),a.jsx(M.BodySecondary,{color:i.COLORS.content.primary,children:e.label})]}),e.drillsIn&&a.jsx(F.default,{width:12,height:12})]})},e.id))]})},Y=p.default.div`
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-direction: column;
|
|
4
4
|
min-width: 240px;
|
|
5
5
|
max-height: 301px;
|
|
6
6
|
overflow-y: auto;
|
|
7
|
-
background: ${
|
|
8
|
-
border: 1px solid ${
|
|
7
|
+
background: ${i.COLORS.surface.standard};
|
|
8
|
+
border: 1px solid ${i.COLORS.stroke.primary};
|
|
9
9
|
border-radius: 4px;
|
|
10
10
|
box-shadow: 0px -2px 8px 0px #0000001f;
|
|
11
|
-
`,Z=
|
|
11
|
+
`,Z=p.default.div`
|
|
12
12
|
display: flex;
|
|
13
13
|
align-items: center;
|
|
14
14
|
gap: 8px;
|
|
15
15
|
padding: 10px 12px;
|
|
16
|
-
border-bottom: 1px solid ${
|
|
17
|
-
`,K=
|
|
16
|
+
border-bottom: 1px solid ${i.COLORS.stroke.primary};
|
|
17
|
+
`,K=p.default.input`
|
|
18
18
|
flex: 1;
|
|
19
19
|
min-width: 0;
|
|
20
20
|
border: none;
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
background: transparent;
|
|
23
23
|
font-family: Inter;
|
|
24
24
|
font-size: 14px;
|
|
25
|
-
color: ${
|
|
25
|
+
color: ${i.COLORS.content.primary};
|
|
26
26
|
|
|
27
27
|
&::placeholder {
|
|
28
|
-
color: ${
|
|
28
|
+
color: ${i.COLORS.content.placeholder};
|
|
29
29
|
}
|
|
30
|
-
`,H=
|
|
30
|
+
`,H=p.default.button`
|
|
31
31
|
display: flex;
|
|
32
32
|
justify-content: space-between;
|
|
33
33
|
align-items: center;
|
|
@@ -36,32 +36,32 @@
|
|
|
36
36
|
padding: 8px 10px;
|
|
37
37
|
height: 48px;
|
|
38
38
|
border: none;
|
|
39
|
-
border-bottom: 1px solid ${
|
|
40
|
-
background: ${n=>n.$active?
|
|
39
|
+
border-bottom: 1px solid ${i.COLORS.stroke.primary};
|
|
40
|
+
background: ${n=>n.$active?i.COLORS.surface.subdued:"transparent"};
|
|
41
41
|
cursor: pointer;
|
|
42
42
|
text-align: left;
|
|
43
43
|
|
|
44
44
|
&:hover {
|
|
45
|
-
background: ${
|
|
45
|
+
background: ${i.COLORS.surface.subdued};
|
|
46
46
|
}
|
|
47
|
-
`,ee=
|
|
47
|
+
`,ee=p.default.div`
|
|
48
48
|
display: flex;
|
|
49
49
|
align-items: center;
|
|
50
50
|
gap: 12px;
|
|
51
51
|
min-width: 0;
|
|
52
|
-
`,te=
|
|
52
|
+
`,te=p.default.div`
|
|
53
53
|
width: 100%;
|
|
54
54
|
text-align: center;
|
|
55
|
-
color: ${
|
|
55
|
+
color: ${i.COLORS.content.brand};
|
|
56
56
|
font-family: Inter;
|
|
57
57
|
font-size: 14px;
|
|
58
58
|
font-weight: 600;
|
|
59
|
-
`,ne=
|
|
59
|
+
`,ne=p.default.button`
|
|
60
60
|
display: flex;
|
|
61
61
|
align-items: center;
|
|
62
62
|
padding: 12px 16px;
|
|
63
63
|
border: none;
|
|
64
|
-
border-bottom: 1px solid ${
|
|
64
|
+
border-bottom: 1px solid ${i.COLORS.stroke.primary};
|
|
65
65
|
background: transparent;
|
|
66
66
|
cursor: pointer;
|
|
67
67
|
font-family: Inter;
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
font-weight: 600;
|
|
70
70
|
height: 48px;
|
|
71
71
|
gap: 4px;
|
|
72
|
-
`,re=
|
|
72
|
+
`,re=p.default.div`
|
|
73
73
|
padding: 12px 10px;
|
|
74
74
|
font-family: Inter;
|
|
75
75
|
font-size: 13px;
|
|
76
|
-
color: ${
|
|
76
|
+
color: ${i.COLORS.content.secondary};
|
|
77
77
|
`;exports.MentionPicker=X;
|
|
78
78
|
//# sourceMappingURL=MentionPicker.js.map
|