@bikdotai/bik-component-library 0.0.866 → 0.0.867
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/AgentBuilder.js +1 -1
- package/dist/cjs/components/agent-builder/AgentBuilder.js.map +1 -1
- package/dist/cjs/components/agent-builder/AgentBuilder.styled.js +151 -29
- package/dist/cjs/components/agent-builder/AgentBuilder.styled.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/ChannelSelectModal.js +2 -0
- package/dist/cjs/components/agent-builder/components/ChannelSelectModal.js.map +1 -0
- package/dist/cjs/components/agent-builder/components/ChannelsSection.js +2 -0
- package/dist/cjs/components/agent-builder/components/ChannelsSection.js.map +1 -0
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +5 -5
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/GoLiveModal.js +1 -1
- package/dist/cjs/components/agent-builder/components/GoLiveModal.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionEditor.js +2 -2
- package/dist/cjs/components/agent-builder/components/MentionEditor.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionField.js +1 -1
- package/dist/cjs/components/agent-builder/components/MentionField.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionPicker.js +13 -13
- package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/SelectableListSection.js +3 -3
- package/dist/cjs/components/agent-builder/components/SelectableListSection.js.map +1 -1
- package/dist/cjs/components/agent-builder/constants/channels.js +2 -0
- package/dist/cjs/components/agent-builder/constants/channels.js.map +1 -0
- package/dist/cjs/components/agent-builder/constants/steps.js +1 -1
- package/dist/cjs/components/agent-builder/constants/steps.js.map +1 -1
- package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js +1 -1
- package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
- package/dist/cjs/components/agent-builder/steps/Step1About.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step1About.js.map +1 -1
- package/dist/cjs/components/agent-builder/steps/Step2WhenItStepsIn.js +2 -2
- package/dist/cjs/components/agent-builder/steps/Step2WhenItStepsIn.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/steps/Step4HandoverRules.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step4HandoverRules.js.map +1 -1
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.js +2 -2
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.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/icons/Social/Channels/ManifestGlass.js +2 -0
- package/dist/cjs/icons/Social/Channels/ManifestGlass.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/ShipStation.js +2 -0
- package/dist/cjs/icons/Social/Channels/ShipStation.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/Skio.js +2 -0
- package/dist/cjs/icons/Social/Channels/Skio.js.map +1 -0
- package/dist/cjs/icons/index.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/agent-builder/AgentBuilder.js +103 -97
- package/dist/esm/components/agent-builder/AgentBuilder.js.map +1 -1
- package/dist/esm/components/agent-builder/AgentBuilder.model.d.ts +76 -0
- package/dist/esm/components/agent-builder/AgentBuilder.styled.d.ts +68 -0
- package/dist/esm/components/agent-builder/AgentBuilder.styled.js +224 -59
- package/dist/esm/components/agent-builder/AgentBuilder.styled.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ChannelSelectModal.d.ts +26 -0
- package/dist/esm/components/agent-builder/components/ChannelSelectModal.js +121 -0
- package/dist/esm/components/agent-builder/components/ChannelSelectModal.js.map +1 -0
- package/dist/esm/components/agent-builder/components/ChannelsSection.d.ts +10 -0
- package/dist/esm/components/agent-builder/components/ChannelsSection.js +183 -0
- package/dist/esm/components/agent-builder/components/ChannelsSection.js.map +1 -0
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +135 -132
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/GoLiveModal.js +12 -12
- package/dist/esm/components/agent-builder/components/GoLiveModal.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionEditor.d.ts +2 -0
- package/dist/esm/components/agent-builder/components/MentionEditor.js +47 -45
- package/dist/esm/components/agent-builder/components/MentionEditor.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionField.js +52 -51
- package/dist/esm/components/agent-builder/components/MentionField.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionPicker.d.ts +5 -0
- package/dist/esm/components/agent-builder/components/MentionPicker.js +134 -132
- package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/esm/components/agent-builder/components/SelectableListSection.d.ts +2 -0
- package/dist/esm/components/agent-builder/components/SelectableListSection.js +48 -46
- package/dist/esm/components/agent-builder/components/SelectableListSection.js.map +1 -1
- package/dist/esm/components/agent-builder/constants/channels.d.ts +56 -0
- package/dist/esm/components/agent-builder/constants/channels.js +41 -0
- package/dist/esm/components/agent-builder/constants/channels.js.map +1 -0
- package/dist/esm/components/agent-builder/constants/steps.d.ts +31 -1
- package/dist/esm/components/agent-builder/constants/steps.js +15 -6
- package/dist/esm/components/agent-builder/constants/steps.js.map +1 -1
- package/dist/esm/components/agent-builder/context/AgentBuilderContext.d.ts +13 -1
- package/dist/esm/components/agent-builder/context/AgentBuilderContext.js +157 -148
- package/dist/esm/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
- package/dist/esm/components/agent-builder/index.d.ts +5 -2
- package/dist/esm/components/agent-builder/steps/Step1About.js +15 -13
- package/dist/esm/components/agent-builder/steps/Step1About.js.map +1 -1
- package/dist/esm/components/agent-builder/steps/Step2WhenItStepsIn.js +55 -48
- package/dist/esm/components/agent-builder/steps/Step2WhenItStepsIn.js.map +1 -1
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +158 -157
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/esm/components/agent-builder/steps/Step4HandoverRules.d.ts +11 -0
- package/dist/esm/components/agent-builder/steps/Step4HandoverRules.js +127 -23
- package/dist/esm/components/agent-builder/steps/Step4HandoverRules.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/mentionSerialization.d.ts +10 -3
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js +31 -23
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/sourceIcons.d.ts +7 -5
- package/dist/esm/components/agent-builder/utils/sourceIcons.js +26 -26
- package/dist/esm/components/agent-builder/utils/sourceIcons.js.map +1 -1
- package/dist/esm/icons/Social/Channels/ManifestGlass.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/ManifestGlass.js +252 -0
- package/dist/esm/icons/Social/Channels/ManifestGlass.js.map +1 -0
- package/dist/esm/icons/Social/Channels/ShipStation.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/ShipStation.js +31 -0
- package/dist/esm/icons/Social/Channels/ShipStation.js.map +1 -0
- package/dist/esm/icons/Social/Channels/Skio.d.ts +6 -0
- package/dist/{cjs/assets/icons/Skio.svg.js → esm/icons/Social/Channels/Skio.js} +31 -2
- package/dist/esm/icons/Social/Channels/Skio.js.map +1 -0
- package/dist/esm/icons/Social/Channels/index.d.ts +3 -0
- package/dist/esm/icons/index.d.ts +25 -25
- package/dist/esm/icons/index.js +330 -324
- package/dist/esm/icons/index.js.map +1 -1
- package/dist/esm/index.js +671 -663
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/assets/icons/BigCommerce.svg.js +0 -2
- package/dist/cjs/assets/icons/BigCommerce.svg.js.map +0 -1
- package/dist/cjs/assets/icons/Gorgias.svg.js +0 -2
- package/dist/cjs/assets/icons/Gorgias.svg.js.map +0 -1
- package/dist/cjs/assets/icons/ManifestGlass.svg.js +0 -2
- package/dist/cjs/assets/icons/ManifestGlass.svg.js.map +0 -1
- package/dist/cjs/assets/icons/ShipStation.svg.js +0 -2
- package/dist/cjs/assets/icons/ShipStation.svg.js.map +0 -1
- package/dist/cjs/assets/icons/Shopify.svg.js +0 -2
- package/dist/cjs/assets/icons/Shopify.svg.js.map +0 -1
- package/dist/cjs/assets/icons/Skio.svg.js.map +0 -1
- package/dist/esm/assets/icons/BigCommerce.svg.js +0 -6
- package/dist/esm/assets/icons/BigCommerce.svg.js.map +0 -1
- package/dist/esm/assets/icons/Gorgias.svg.js +0 -6
- package/dist/esm/assets/icons/Gorgias.svg.js.map +0 -1
- package/dist/esm/assets/icons/ManifestGlass.svg.js +0 -6
- package/dist/esm/assets/icons/ManifestGlass.svg.js.map +0 -1
- package/dist/esm/assets/icons/ShipStation.svg.js +0 -6
- package/dist/esm/assets/icons/ShipStation.svg.js.map +0 -1
- package/dist/esm/assets/icons/Shopify.svg.js +0 -6
- package/dist/esm/assets/icons/Shopify.svg.js.map +0 -1
- package/dist/esm/assets/icons/Skio.svg.js +0 -6
- package/dist/esm/assets/icons/Skio.svg.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelsSection.js","sources":["../../../../../src/components/agent-builder/components/ChannelsSection.tsx"],"sourcesContent":["import EditIcon from '@src/assets/icons/edit.svg';\nimport ErrorInfoIcon from '@src/assets/icons/errorInfo.svg';\nimport React, { useMemo, useState } from 'react';\nimport { CheckBox } from '@src/components/checkBox';\nimport { IconButton } from '@src/components/icon-button';\nimport { Tag } from '@src/components/tag';\nimport { Tooltip } from '@src/components/tooltips';\nimport { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport type {\n\tAgentChannel,\n\tAgentChannelAccount,\n\tAgentChannelType,\n} from '../AgentBuilder.model';\nimport {\n\tChannelCard,\n\tChannelChips,\n\tChannelGlyph,\n\tChannelIdentity,\n\tChannelRow,\n\tChannelRowMain,\n\tChannelsSectionRoot,\n\tCHECKBOX_SLOT,\n\tChipTooltipTarget,\n} from '../AgentBuilder.styled';\nimport {\n\tchannelPresentation,\n\tisAccountDisconnected,\n\tselectedAccounts,\n} from '../constants/channels';\nimport { useAgentBuilderContext } from '../context/AgentBuilderContext';\nimport { ChannelSelectModal } from './ChannelSelectModal';\n\n/**\n * How many account chips a row shows before collapsing the rest into \"+N\". The\n * design draws three; without a cap a store with a dozen numbers pushes the row\n * well past its 48px height.\n */\nconst MAX_VISIBLE_CHIPS = 3;\n\n/**\n * Chips for a row: disconnected accounts first so a cap can never hide the very\n * thing the merchant needs to act on, then the rest in their original order.\n */\nconst chipOrder = (accounts: AgentChannelAccount[]): AgentChannelAccount[] => [\n\t...accounts.filter(isAccountDisconnected),\n\t...accounts.filter((a) => !isAccountDisconnected(a)),\n];\n\n/**\n * Step 1's \"Channels to activate it on\" — one card per connected channel, each\n * with a select-all checkbox, the accounts it covers as chips, and an edit\n * button that opens the per-account picker.\n *\n * Renders nothing when the consumer passes no `availableChannels`, so a host\n * that hasn't wired channels up yet sees the step exactly as it was.\n */\nexport const ChannelsSection: React.FC = () => {\n\tconst { value, updateField, availableChannels, onManageChannels } =\n\t\tuseAgentBuilderContext();\n\n\t// Which channel's picker is open (by type); null = closed.\n\tconst [editingType, setEditingType] = useState<AgentChannelType | null>(null);\n\n\t// Selection is stored as a list; index it once so each row is a lookup.\n\tconst selectionByType = useMemo(() => {\n\t\tconst map = new Map<AgentChannelType, string[]>();\n\t\t(value.channels ?? []).forEach((c) => map.set(c.type, c.channelIds));\n\t\treturn map;\n\t}, [value.channels]);\n\n\tif (!availableChannels || availableChannels.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst setSelection = (type: AgentChannelType, channelIds: string[]) => {\n\t\tconst rest = (value.channels ?? []).filter((c) => c.type !== type);\n\t\t// An empty selection drops the channel entirely rather than persisting a\n\t\t// `{ type, channelIds: [] }` no-op the backend would have to filter out.\n\t\tupdateField(\n\t\t\t'channels',\n\t\t\tchannelIds.length > 0 ? [...rest, { type, channelIds }] : rest,\n\t\t);\n\t};\n\n\tconst editingChannel =\n\t\tavailableChannels.find((c) => c.type === editingType) ?? null;\n\n\treturn (\n\t\t<ChannelsSectionRoot>\n\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\tChannels to activate it on\n\t\t\t</TitleSmall>\n\n\t\t\t{availableChannels.map((channel) => (\n\t\t\t\t<ChannelCardRow\n\t\t\t\t\tkey={String(channel.type)}\n\t\t\t\t\tchannel={channel}\n\t\t\t\t\tselectedIds={selectionByType.get(channel.type) ?? []}\n\t\t\t\t\tonSelectionChange={(ids) => setSelection(channel.type, ids)}\n\t\t\t\t\tonEdit={() => setEditingType(channel.type)}\n\t\t\t\t/>\n\t\t\t))}\n\n\t\t\t<ChannelSelectModal\n\t\t\t\tchannel={editingChannel}\n\t\t\t\tselectedIds={\n\t\t\t\t\teditingChannel ? selectionByType.get(editingChannel.type) ?? [] : []\n\t\t\t\t}\n\t\t\t\tonClose={() => setEditingType(null)}\n\t\t\t\tonApply={(ids) => {\n\t\t\t\t\tif (editingChannel) {\n\t\t\t\t\t\tsetSelection(editingChannel.type, ids);\n\t\t\t\t\t}\n\t\t\t\t\tsetEditingType(null);\n\t\t\t\t}}\n\t\t\t\tonManageChannels={\n\t\t\t\t\tonManageChannels && editingChannel\n\t\t\t\t\t\t? () => onManageChannels(editingChannel.type)\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t/>\n\t\t</ChannelsSectionRoot>\n\t);\n};\n\nChannelsSection.displayName = 'ChannelsSection';\n\ninterface ChannelCardRowProps {\n\tchannel: AgentChannel;\n\tselectedIds: string[];\n\tonSelectionChange: (channelIds: string[]) => void;\n\tonEdit: () => void;\n}\n\nconst ChannelCardRow: React.FC<ChannelCardRowProps> = ({\n\tchannel,\n\tselectedIds,\n\tonSelectionChange,\n\tonEdit,\n}) => {\n\tconst { label, Icon, tint, accountsNoun } = channelPresentation(\n\t\tchannel.type,\n\t\tchannel.label,\n\t);\n\n\t/**\n\t * Zero state — the store supports this channel but has nothing connected\n\t * under it. Nothing on the row is actionable, so the checkbox and the edit\n\t * button are both inert and a \"Disabled\" chip stands in for the accounts.\n\t */\n\tconst isUnavailable = channel.accounts.length === 0;\n\n\tconst selected = selectedAccounts(channel, selectedIds);\n\tconst allSelected =\n\t\t!isUnavailable && selected.length === channel.accounts.length;\n\tconst someSelected = selected.length > 0 && !allSelected;\n\n\t// With nothing picked yet the row shows the store's inventory — that's the\n\t// state the design draws, and it tells the merchant what's on offer. Once\n\t// they've picked, the chips narrow to what the agent actually runs on.\n\tconst shown = chipOrder(selected.length > 0 ? selected : channel.accounts);\n\tconst visible = shown.slice(0, MAX_VISIBLE_CHIPS);\n\tconst overflow = shown.slice(MAX_VISIBLE_CHIPS);\n\n\tconst toggleAll = () =>\n\t\tonSelectionChange(\n\t\t\tallSelected ? [] : channel.accounts.map((a) => a.channelId),\n\t\t);\n\n\treturn (\n\t\t<ChannelCard\n\t\t\tdata-test={`agent-channel-${channel.type}`}\n\t\t\t// A card groups a channel's checkbox, chips and edit button; naming the\n\t\t\t// group lets assistive tech (and tests) address one channel at a time.\n\t\t\trole=\"group\"\n\t\t\taria-label={label}\n\t\t>\n\t\t\t<ChannelRow>\n\t\t\t\t<ChannelRowMain>\n\t\t\t\t\t<CheckBox\n\t\t\t\t\t\tisChecked={allSelected || someSelected}\n\t\t\t\t\t\tisPartiallyChecked={someSelected}\n\t\t\t\t\t\tisDisabled={isUnavailable}\n\t\t\t\t\t\tariaLabel={label}\n\t\t\t\t\t\tonValueChange={toggleAll}\n\t\t\t\t\t\tstyle={CHECKBOX_SLOT}\n\t\t\t\t\t/>\n\t\t\t\t\t<ChannelIdentity>\n\t\t\t\t\t\t<ChannelGlyph tint={tint}>\n\t\t\t\t\t\t\t{Icon && <Icon size={16} />}\n\t\t\t\t\t\t</ChannelGlyph>\n\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>{label}</TitleSmall>\n\t\t\t\t\t</ChannelIdentity>\n\n\t\t\t\t\t<ChannelChips>\n\t\t\t\t\t\t{isUnavailable ? (\n\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\tbody={`No ${accountsNoun} are connected to this store yet. Connect one from channel management to activate this agent on ${label}.`}\n\t\t\t\t\t\t\t\tplacement=\"top\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ChipTooltipTarget>\n\t\t\t\t\t\t\t\t\t<Tag\n\t\t\t\t\t\t\t\t\t\ttagText=\"Disabled\"\n\t\t\t\t\t\t\t\t\t\ttype=\"neutral\"\n\t\t\t\t\t\t\t\t\t\tvariant=\"regular\"\n\t\t\t\t\t\t\t\t\t\theight={24}\n\t\t\t\t\t\t\t\t\t\tcursor=\"default\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</ChipTooltipTarget>\n\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t{visible.map((account) => (\n\t\t\t\t\t\t\t\t\t<AccountChip\n\t\t\t\t\t\t\t\t\t\tkey={account.channelId}\n\t\t\t\t\t\t\t\t\t\taccount={account}\n\t\t\t\t\t\t\t\t\t\tchannelLabel={label}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t{overflow.length > 0 && (\n\t\t\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\t\t\tbody={overflow.map((a) => a.channelName).join(', ')}\n\t\t\t\t\t\t\t\t\t\tplacement=\"top\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<ChipTooltipTarget>\n\t\t\t\t\t\t\t\t\t\t\t<Tag\n\t\t\t\t\t\t\t\t\t\t\t\ttagText={`+${overflow.length}`}\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"purple\"\n\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"regular\"\n\t\t\t\t\t\t\t\t\t\t\t\theight={24}\n\t\t\t\t\t\t\t\t\t\t\t\tcursor=\"default\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</ChipTooltipTarget>\n\t\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</ChannelChips>\n\t\t\t\t</ChannelRowMain>\n\n\t\t\t\t<IconButton\n\t\t\t\t\tdata-test={`agent-channel-${channel.type}-edit`}\n\t\t\t\t\taria-label={`Edit ${label} channels`}\n\t\t\t\t\tIcon={EditIcon}\n\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\ticonPadding={4}\n\t\t\t\t\tdisabled={isUnavailable}\n\t\t\t\t\tonClick={onEdit}\n\t\t\t\t/>\n\t\t\t</ChannelRow>\n\t\t</ChannelCard>\n\t);\n};\n\n/**\n * One account chip. A healthy account reads as a brand chip; a disconnected one\n * turns negative and gains the error glyph.\n *\n * The tooltip is NOT in the design — but a bare red chip tells the merchant\n * something is broken and nothing about what to do, so it names the account and\n * the fix.\n */\nconst AccountChip: React.FC<{\n\taccount: AgentChannelAccount;\n\tchannelLabel: string;\n}> = ({ account, channelLabel }) => {\n\tif (!isAccountDisconnected(account)) {\n\t\treturn (\n\t\t\t<Tag\n\t\t\t\ttagText={account.channelName}\n\t\t\t\ttype=\"purple\"\n\t\t\t\tvariant=\"regular\"\n\t\t\t\theight={24}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Tooltip\n\t\t\tbody={`${account.channelName} is disconnected. This agent won't run on it until you reconnect it from ${channelLabel} channel management.`}\n\t\t\tplacement=\"top\"\n\t\t>\n\t\t\t<ChipTooltipTarget>\n\t\t\t\t<Tag\n\t\t\t\t\ttagText={account.channelName}\n\t\t\t\t\ttype=\"negative\"\n\t\t\t\t\tvariant=\"regular\"\n\t\t\t\t\theight={24}\n\t\t\t\t\tLeadingIcon={ErrorInfoIcon}\n\t\t\t\t\t// Tag doesn't spread rest props, so `data-test` would be dropped —\n\t\t\t\t\t// `leadingIconId` is the one hook it does put on the DOM, which gives\n\t\t\t\t\t// the error glyph a stable handle for tests and e2e.\n\t\t\t\t\tleadingIconId={`channel-error-${account.channelId}`}\n\t\t\t\t\tcursor=\"default\"\n\t\t\t\t/>\n\t\t\t</ChipTooltipTarget>\n\t\t</Tooltip>\n\t);\n};\n"],"names":["MAX_VISIBLE_CHIPS","chipOrder","accounts","isAccountDisconnected","a","ChannelsSection","value","updateField","availableChannels","onManageChannels","useAgentBuilderContext","editingType","setEditingType","useState","selectionByType","useMemo","map","c","setSelection","type","channelIds","rest","editingChannel","ChannelsSectionRoot","jsx","TitleSmall","COLORS","channel","ChannelCardRow","ids","ChannelSelectModal","selectedIds","onSelectionChange","onEdit","label","Icon","tint","accountsNoun","channelPresentation","isUnavailable","selected","selectedAccounts","allSelected","someSelected","shown","visible","overflow","toggleAll","ChannelCard","ChannelRow","jsxs","ChannelRowMain","CheckBox","CHECKBOX_SLOT","ChannelIdentity","ChannelGlyph","ChannelChips","Tooltip","ChipTooltipTarget","Tag","Fragment","account","AccountChip","IconButton","EditIcon","channelLabel","ErrorInfoIcon"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),n=require("react"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),n=require("react"),De=require("styled-components"),de=require("../../../utils/arrayUtils.js"),Z=require("../../../constants/Theme.js"),Ne=require("../constants/charLimits.js"),c=require("../constants/tools.js"),g=require("../utils/mentionSerialization.js"),f=require("../utils/sourceIcons.js"),Ke=require("../utils/toolActions.js"),Le=require("./ConfigToolPanel.js"),J=require("./DrawerHeaderText.js"),me=require("./MentionEditor.js"),Pe=require("./RestApiToolPanel.js"),Be=require("./SelectableListSection.js"),Ge=require("../../side-modal/SideModal.js"),Ue=require("../../input/Input.js"),ze=require("../../toaster/Toaster.js"),He=u=>u&&typeof u=="object"&&"default"in u?u:{default:u},Fe=He(De),We=1e3,Q=1002,pe=(u,S)=>{const i=u??[];return i.some(d=>d.id===S.id)?i.map(d=>d.id===S.id?S:d):[...i,S]},ge=Fe.default.button`
|
|
2
2
|
align-self: flex-start;
|
|
3
|
-
border: 1px solid ${
|
|
4
|
-
color: ${
|
|
5
|
-
background: ${
|
|
3
|
+
border: 1px solid ${Z.COLORS.stroke.primary};
|
|
4
|
+
color: ${Z.COLORS.content.primary};
|
|
5
|
+
background: ${Z.COLORS.surface.standard};
|
|
6
6
|
border-radius: 8px;
|
|
7
7
|
padding: 6px 12px;
|
|
8
8
|
font-size: 13px;
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
cursor: default;
|
|
15
15
|
opacity: 0.6;
|
|
16
16
|
}
|
|
17
|
-
`,$e=({onClose:u,onSave:S,availableTools:i,onImprove:d,onImproveToolInstructions:
|
|
17
|
+
`,$e=({onClose:u,onSave:S,availableTools:i,onImprove:d,onImproveToolInstructions:V,configToolTemplates:ee,integrationStatus:v,onConnectIntegration:k,title:te="Create sub-agent",initial:h,existingNames:fe=[],appLabel:y="Manifest",charLimits:C=Ne.AGENT_CHAR_LIMITS,variablesData:_})=>{const[j,Se]=n.useState(h?.name??""),[b,w]=n.useState(h?.instructions??""),[x,E]=n.useState(h?.guardrail??""),[D,O]=n.useState(h?.tools??[]),[p,N]=n.useState(h?.configTools??[]),[m,K]=n.useState(h?.restApiTools??[]),[l,T]=n.useState(null),q=n.useRef(0),[oe,ne]=n.useState(!1),[he,L]=n.useState(0),[ye,P]=n.useState(0),[I,se]=n.useState(null),B=n.useMemo(()=>[...g.buildAgentMentionItems(i,[],y),...g.buildCustomToolMentionItems(p,m)],[i,y,p,m]),M=n.useRef({}),G=n.useRef("instructions"),Te=n.useCallback(e=>{M.current.instructions=e??void 0},[]),Ce=n.useCallback(e=>{M.current.guardrail=e??void 0},[]),be=n.useCallback(()=>{G.current="instructions"},[]),xe=n.useCallback(()=>{G.current="guardrail"},[]),re=n.useRef(new Set);re.current=new Set([...p,...m].map(e=>e.id));const ie=n.useCallback((e,t)=>{e==="tool"&&!re.current.has(t)&&O(o=>de.addUnique(o,t))},[]),R=n.useCallback((e,t,o)=>{(M.current[G.current]??M.current.instructions)?.("tool",e,t,o)},[]),U=n.useCallback(e=>{q.current+=1,T({key:q.current,kind:"restapi",initialRest:e})},[]),z=n.useCallback((e,t)=>{q.current+=1,T({key:q.current,kind:"config",toolKey:e,initialConfig:t})},[]),Ie=n.useCallback(e=>{const t=c.CONFIG_TOOL_SOURCES[e];t?z(t):U()},[z,U]),Re=n.useCallback(e=>{const t=!m.some(o=>o.id===e.id);K(o=>pe(o,e)),t&&R(e.id,g.restApiMentionItem(e).label,c.ToolSource.RestApi),T(null)},[m,R]),Ae=n.useCallback(e=>{const t=!p.some(o=>o.id===e.id);if(N(o=>pe(o,e)),t){const o=e.tool_key==="send_slack_message"?c.ToolSource.Slack:c.ToolSource.EmailHandover;R(e.id,g.configToolMentionItem(e).label,o)}T(null)},[p,R]),[H,F]=n.useState(null),W=n.useRef(null),ae=n.useRef(0),ve=e=>{const t=i.find(s=>s.tool_id===e)?.display_name??m.find(s=>s.id===e)?.name??"Tool",o=`{{tool:${e}}}`,a=s=>s.split(o).join("");W.current={instructions:b,guardrail:x,tools:D,configTools:p,restApiTools:m},w(s=>a(s)),E(s=>a(s)),O(s=>s.filter(A=>A!==e)),N(s=>s.filter(A=>A.id!==e)),K(s=>s.filter(A=>A.id!==e)),L(s=>s+1),P(s=>s+1),ae.current+=1,F({id:ae.current,message:`Tool "${t}" removed`})},ke=()=>{const e=W.current;e&&(w(e.instructions),E(e.guardrail),O(e.tools),N(e.configTools),K(e.restApiTools),L(t=>t+1),P(t=>t+1),W.current=null),F(null)},$=j.trim(),Y=$.length>0&&fe.some(e=>e.trim().toLowerCase()===$.toLowerCase()),le=$.length>0&&!Y&&(b.trim().length>0||x.trim().length>0),_e=D.map(e=>{const t=i.find(o=>o.tool_id===e);return t?{id:e,label:t.display_name,icon:f.sourceIcon(t.source??c.ToolSource.Manifest),authRequired:t.auth_required}:null}).filter(e=>e!==null),we=m.map(e=>({id:e.id,label:g.restApiToolName(e),icon:f.SOURCE_ICONS[c.ToolSource.RestApi],onConfigure:()=>U(e)})),Ee=p.map(e=>({id:e.id,label:g.configToolName(e),icon:f.SOURCE_ICONS[e.tool_key==="send_slack_message"?c.ToolSource.Slack:c.ToolSource.EmailHandover],onConfigure:()=>z(e.tool_key,e)})),Oe=[..._e,...we,...Ee],X=Ke.buildToolActions(ee,Ie,v,k),ce=l?.kind==="config"&&l.toolKey?ee?.[l.toolKey]:void 0,qe=i.map(e=>({label:e.display_name,value:e.tool_id,leadingIcon:f.renderSourceIcon(f.sourceIcon(e.source??c.ToolSource.Manifest))??void 0})),Me=(()=>{const e=[],t=new Map;return i.forEach(o=>{const a=o.source??c.ToolSource.Manifest;t.has(a)||(t.set(a,[]),e.push(a)),t.get(a)?.push({label:o.display_name,value:o.tool_id,leadingIcon:f.renderSourceIcon(f.sourceIcon(o.source??c.ToolSource.Manifest))??void 0})}),e.map(o=>({source:o,label:g.toolSourceLabel(o,y),options:t.get(o)??[],connected:v?.[o],onConnect:()=>k?.(o)}))})(),je=async()=>{if(!le||oe)return;const e=S({name:j.trim(),instructions:b,guardrail:x,tools:D,configTools:p,restApiTools:m});if(e&&typeof e.then=="function"){ne(!0);try{await e}finally{ne(!1)}}},ue=async e=>{if(!(!d||I)){se(e);try{const o=await d(e,e==="instructions"?b:x);e==="instructions"?(w(o),L(a=>a+1)):(E(o),P(a=>a+1))}finally{se(null)}}};return r.jsxs(r.Fragment,{children:[r.jsxs(Ge.SideModal,{header:te,closeOnEscapeKey:!1,zIndex:We,headerCustomComponent:r.jsx(J.DrawerHeaderText,{title:te,subtitle:"Each sub-agent handles one piece of the job. Use @ in the main instructions to call them."}),width:"421px",headerStyle:J.DRAWER_HEADER_STYLE,bodyStyle:J.DRAWER_BODY_STYLE,onClose:u,saveButtonProps:{"data-test":"subagent-save",buttonText:"Save",buttonType:"primary",size:"small",disabled:!le,isLoading:oe,onClick:je},cancelButtonProps:{"data-test":"subagent-cancel",buttonText:"Cancel",buttonType:"tertiaryGray",size:"small",onClick:u},children:[r.jsx(Ue.Input,{"data-test":"subagent-name",labelText:"Agent name",labelTextBold:!0,placeholder:"Enter agent name",value:j,maxCharLimit:C.name,maxCharLimitPosition:"TOP",maxCharStyle:{fontSize:12,lineHeight:"16px"},state:Y?"invalid":void 0,errorMessage:Y?"A sub-agent with this name already exists":void 0,onChangeText:Se}),r.jsx(me.MentionEditor,{"data-test":"subagent-instructions",label:"Instructions",value:b,onChange:w,maxLength:C.instructions,placeholder:"Write the steps in plain English. The agent will follow them exactly. The more specific you are, the better it performs.",minHeight:"160px",resetKey:`instr-${he}`,mentionItems:B,tools:i,toolActions:X,variablesData:_,addDataButton:!0,integrationStatus:v,appLabel:y,onConnectIntegration:k,onMentionSelect:ie,onFocus:be,registerInsert:Te,action:d?r.jsx(ge,{type:"button","data-test":"subagent-improve-instructions",disabled:I!==null,onClick:()=>ue("instructions"),children:I==="instructions"?"Improving…":"Improve with AI"}):void 0}),r.jsx(me.MentionEditor,{"data-test":"subagent-guardrail",label:"Guardrails",value:x,onChange:E,maxLength:C.guardrail,placeholder:"e.g. Never discuss competitor pricing. Always stay within the cancellation policy. Do not process refunds above ₹10,000 without human approval.",minHeight:"160px",resetKey:`guard-${ye}`,mentionItems:B,tools:i,toolActions:X,variablesData:_,addDataButton:!0,integrationStatus:v,appLabel:y,onConnectIntegration:k,onMentionSelect:ie,onFocus:xe,registerInsert:Ce,action:d?r.jsx(ge,{type:"button","data-test":"subagent-improve-guardrail",disabled:I!==null,onClick:()=>ue("guardrail"),children:I==="guardrail"?"Improving…":"Improve with AI"}):void 0}),r.jsx(Be.SelectableListSection,{title:"Tools this agent can use",dataTestPrefix:"subagent-tools",items:Oe,addableOptions:qe,sourceGroups:Me,mentionItems:B,actionSources:X,emptyText:"No tools added yet.",appLabel:y,pickerOpensUp:!0,onAdd:e=>{R(e),O(t=>de.addUnique(t,e))},onRemove:ve,confirmDelete:{noun:"tool",zIndex:Q+1}})]}),l?.kind==="restapi"&&r.jsx(Pe.RestApiToolPanel,{initial:l.initialRest,charLimits:C,variablesData:_,onImprove:V,onClose:()=>T(null),onSave:Re,zIndex:Q},l.key),l?.kind==="config"&&l.toolKey&&ce&&r.jsx(Le.ConfigToolPanel,{toolKey:l.toolKey,template:ce,initial:l.initialConfig,charLimits:C,variablesData:_,onImprove:V,onClose:()=>T(null),onSave:Ae,zIndex:Q},l.key),H&&r.jsx(ze.Toaster,{text:H.message,type:"info",position:"top-right",autoClose:5e3,hideCloseButton:!0,buttonProps:{buttonText:"Undo",showButton:!0,onButtonClick:()=>(ke(),{})},onCloseToast:()=>F(null)},H.id)]})};exports.CreateSubAgentPanel=$e;
|
|
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 type { VariableListInterfaceV3 } from '../../variable-picker-v3/model';\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 = (\n\tkind: 'tool' | 'subagent',\n\tid: string,\n\tlabel?: string,\n\tsource?: string,\n) => 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/**\n\t * Per-source integration connection state (today: Slack). A source mapped to\n\t * `false` shows a \"Connect\" affordance instead of drilling into its tools —\n\t * same gating the main builder's Step 3 tool section gets.\n\t */\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\t/** Open the consumer's connect flow for an unconnected integration source. */\n\tonConnectIntegration?: (source: ToolSource) => void;\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/**\n\t * Names of the other sub-agents already on this agent (exclude the one being\n\t * edited). Blocks saving a duplicate name — the LLM references sub-agents by it.\n\t */\n\texistingNames?: string[];\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\t/** Variable catalog for the editors' `@` picker \"Variables\" view. */\n\tvariablesData?: VariableListInterfaceV3[];\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\tintegrationStatus,\n\tonConnectIntegration,\n\ttitle = 'Create sub-agent',\n\tinitial,\n\texistingNames = [],\n\tappLabel = 'Manifest',\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tvariablesData,\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\t// Latest custom-tool ids, readable from the mount-captured `@` onSelect handler\n\t// (BikEditor captures it once) — mirrors the context's valueRef trick.\n\tconst customToolIdsRef = useRef<Set<string>>(new Set());\n\tcustomToolIdsRef.current = new Set(\n\t\t[...configTools, ...restApiTools].map((t) => t.id),\n\t);\n\tconst addToolMention = useCallback(\n\t\t(kind: 'tool' | 'subagent', id: string) => {\n\t\t\t// Only catalog tool ids belong in `tools`; custom tools (Rest API / email /\n\t\t\t// Slack) track themselves on their own lists. Picking an existing custom\n\t\t\t// tool from `@` must not leak its id in as a bogus native ref.\n\t\t\tif (kind === 'tool' && !customToolIdsRef.current.has(id)) {\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(\n\t\t(id: string, label?: string, source?: string) => {\n\t\t\tconst target =\n\t\t\t\tinsertersRef.current[lastFocusedRef.current] ??\n\t\t\t\tinsertersRef.current.instructions;\n\t\t\ttarget?.('tool', id, label, source);\n\t\t},\n\t\t[],\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\t// Pass the source so the fresh chip shows its icon (not yet in the list).\n\t\t\tif (isNew) {\n\t\t\t\tinsertToolAtCursor(\n\t\t\t\t\ttool.id,\n\t\t\t\t\trestApiMentionItem(tool).label,\n\t\t\t\t\tToolSource.RestApi,\n\t\t\t\t);\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\tconst source =\n\t\t\t\t\ttool.tool_key === 'send_slack_message'\n\t\t\t\t\t\t? ToolSource.Slack\n\t\t\t\t\t\t: ToolSource.EmailHandover;\n\t\t\t\tinsertToolAtCursor(tool.id, configToolMentionItem(tool).label, source);\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 nameTrimmed = name.trim();\n\t// Case-insensitive: two sub-agents on the same agent can't share a name (the\n\t// LLM references them by it) — mirrors the Rest API tool-name check.\n\tconst isDuplicateName =\n\t\tnameTrimmed.length > 0 &&\n\t\texistingNames.some(\n\t\t\t(n) => n.trim().toLowerCase() === nameTrimmed.toLowerCase(),\n\t\t);\n\tconst canSave =\n\t\tnameTrimmed.length > 0 &&\n\t\t!isDuplicateName &&\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\t\t// Shield flags a tool that needs customer verification, same as\n\t\t\t\t\t\t// the main builder's Step 3 tool rows.\n\t\t\t\t\t\tauthRequired: tool.auth_required,\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. Integration\n\t// state drives the \"Connect\" affordance, same as the main builder's Step 3.\n\tconst toolActionSources = buildToolActions(\n\t\tconfigToolTemplates,\n\t\topenToolAction,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\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\t// Not connected → the source button opens the connect flow instead of\n\t\t\t// its tool list (mirrors Step 3's tool section).\n\t\t\tconnected: integrationStatus?.[src as ToolSource],\n\t\t\tonConnect: () => onConnectIntegration?.(src as ToolSource),\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\tstate={isDuplicateName ? 'invalid' : undefined}\n\t\t\t\t\terrorMessage={\n\t\t\t\t\t\tisDuplicateName\n\t\t\t\t\t\t\t? 'A sub-agent with this name already exists'\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\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. The agent will follow them exactly. The more specific you are, the better it performs.\"\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\tvariablesData={variablesData}\n\t\t\t\t\taddDataButton\n\t\t\t\t\tintegrationStatus={integrationStatus}\n\t\t\t\t\tonConnectIntegration={onConnectIntegration}\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. Always stay within the cancellation policy. Do not process refunds above ₹10,000 without human approval.\"\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\tvariablesData={variablesData}\n\t\t\t\t\taddDataButton\n\t\t\t\t\tintegrationStatus={integrationStatus}\n\t\t\t\t\tonConnectIntegration={onConnectIntegration}\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\tpickerOpensUp\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\tvariablesData={variablesData}\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\tvariablesData={variablesData}\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","integrationStatus","onConnectIntegration","title","initial","existingNames","appLabel","charLimits","AGENT_CHAR_LIMITS","variablesData","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","customToolIdsRef","t","addToolMention","kind","id","prev","addUnique","insertToolAtCursor","label","source","openRestApi","tool","openConfigTool","toolKey","openToolAction","CONFIG_TOOL_SOURCES","handleSaveRestApi","isNew","restApiMentionItem","ToolSource","handleSaveConfigTool","configToolMentionItem","undo","setUndo","undoSnapshotRef","undoIdRef","removeTool","token","strip","text","k","undoRemove","snap","nameTrimmed","isDuplicateName","n","canSave","toolItems","sourceIcon","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":"8yBAsDMA,GAAkB,IAClBC,EAAqB,KAGrBC,GAAa,CAClBC,EACAC,IACS,CACT,MAAMC,EAAMF,GAAQ,CAAA,EACpB,OAAOE,EAAI,KAAMC,GAAMA,EAAE,KAAOF,EAAK,EAAE,EACpCC,EAAI,IAAKC,GAAOA,EAAE,KAAOF,EAAK,GAAKA,EAAOE,CAAE,EAC5C,CAAC,GAAGD,EAAKD,CAAI,CACjB,EAYMG,GAAgBC,GAAAA,QAAO;AAAA;AAAA,qBAERC,EAAAA,OAAO,OAAO,OAAO;AAAA,UAChCA,EAAAA,OAAO,QAAQ,OAAO;AAAA,eACjBA,EAAAA,OAAO,QAAQ,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuEzBC,GAA0D,CAAC,CACvE,QAAAC,EACA,OAAAC,EACA,eAAAC,EACA,UAAAC,EACA,0BAAAC,EACA,oBAAAC,EACA,kBAAAC,EACA,qBAAAC,EACA,MAAAC,GAAQ,mBACR,QAAAC,EACA,cAAAC,GAAgB,CAAA,EAChB,SAAAC,GAAW,WAAA,WACXC,EAAaC,GAAAA,kBACb,cAAAC,CACD,IAAM,CACL,KAAM,CAACC,EAAMC,EAAO,EAAIC,EAAAA,SAASR,GAAS,MAAQ,EAAE,EAC9C,CAACS,EAAcC,CAAe,EAAIF,EAAAA,SAASR,GAAS,cAAgB,EAAE,EACtE,CAACW,EAAWC,CAAY,EAAIJ,EAAAA,SAASR,GAAS,WAAa,EAAE,EAC7D,CAACa,EAAOC,CAAQ,EAAIN,EAAAA,SAAmBR,GAAS,OAAS,EAAE,EAG3D,CAACe,EAAaC,CAAc,EAAIR,EAAAA,SACrCR,GAAS,aAAe,CAAA,CAAC,EAEpB,CAACiB,EAAcC,CAAe,EAAIV,EAAAA,SACvCR,GAAS,cAAgB,CAAA,CAAC,EAErB,CAACmB,EAAYC,CAAa,EAAIZ,EAAAA,SAAiC,IAAI,EACnEa,EAAmBC,EAAAA,OAAO,CAAC,EAC3B,CAACC,GAAQC,EAAS,EAAIhB,EAAAA,SAAS,EAAK,EAEpC,CAACiB,GAAUC,CAAW,EAAIlB,EAAAA,SAAS,CAAC,EACpC,CAACmB,GAAUC,CAAW,EAAIpB,EAAAA,SAAS,CAAC,EACpC,CAACqB,EAAWC,EAAY,EAAItB,EAAAA,SAEhC,IAAI,EAKAuB,EAAeC,EAAAA,QACpB,IAAM,CACL,GAAGC,yBAAuBxC,EAAgB,CAAA,EAAIS,EAAQ,EACtD,GAAGgC,EAAAA,4BAA4BnB,EAAaE,CAAY,CAAA,EAEzD,CAACxB,EAAgBS,GAAUa,EAAaE,CAAY,CAAA,EAK/CkB,EAAeb,EAAAA,OAEnB,EAAE,EACEc,EAAiBd,EAAAA,OAAqC,cAAc,EACpEe,GAAgBC,cAAaC,GAAwB,CAC1DJ,EAAa,QAAQ,aAAeI,GAAM,MAC3C,EAAG,CAAA,CAAE,EACCC,GAAgBF,cAAaC,GAAwB,CAC1DJ,EAAa,QAAQ,UAAYI,GAAM,MACxC,EAAG,CAAA,CAAE,EACCE,GAAaH,EAAAA,YAAY,IAAM,CACpCF,EAAe,QAAU,cAC1B,EAAG,CAAA,CAAE,EACCM,GAAaJ,EAAAA,YAAY,IAAM,CACpCF,EAAe,QAAU,WAC1B,EAAG,CAAA,CAAE,EAGCO,GAAmBrB,EAAAA,OAAoB,IAAI,GAAK,EACtDqB,GAAiB,QAAU,IAAI,IAC9B,CAAC,GAAG5B,EAAa,GAAGE,CAAY,EAAE,IAAK2B,GAAMA,EAAE,EAAE,CAAA,EAElD,MAAMC,GAAiBP,EAAAA,YACtB,CAACQ,EAA2BC,IAAe,CAItCD,IAAS,QAAU,CAACH,GAAiB,QAAQ,IAAII,CAAE,GACtDjC,EAAUkC,GAASC,GAAAA,UAAUD,EAAMD,CAAE,CAAC,CAExC,EACA,CAAA,CAAC,EAEIG,EAAqBZ,EAAAA,YAC1B,CAACS,EAAYI,EAAgBC,IAAoB,EAE/CjB,EAAa,QAAQC,EAAe,OAAO,GAC3CD,EAAa,QAAQ,gBACb,OAAQY,EAAII,EAAOC,CAAM,CACnC,EACA,CAAA,CAAC,EAOIC,EAAcf,cAAagB,GAA6B,CAC7DjC,EAAiB,SAAW,EAC5BD,EAAc,CACb,IAAKC,EAAiB,QACtB,KAAM,UACN,YAAaiC,CAAA,CACb,CACF,EAAG,CAAA,CAAE,EACCC,EAAiBjB,EAAAA,YACtB,CAACkB,EAAwBF,IAA4B,CACpDjC,EAAiB,SAAW,EAC5BD,EAAc,CACb,IAAKC,EAAiB,QACtB,KAAM,SACN,QAAAmC,EACA,cAAeF,CAAA,CACf,CACF,EACA,CAAA,CAAC,EAEIG,GAAiBnB,EAAAA,YACrBc,GAAuB,CACvB,MAAMI,EAAUE,EAAAA,oBAAoBN,CAAM,EACtCI,EACHD,EAAeC,CAAO,EAEtBH,EAAA,CAEF,EACA,CAACE,EAAgBF,CAAW,CAAA,EAEvBM,GAAoBrB,EAAAA,YACxBgB,GAA4B,CAC5B,MAAMM,EAAQ,CAAC3C,EAAa,KAAM2B,GAAMA,EAAE,KAAOU,EAAK,EAAE,EACxDpC,EAAiB8B,GAASlE,GAAWkE,EAAMM,CAAI,CAAC,EAG5CM,GACHV,EACCI,EAAK,GACLO,EAAAA,mBAAmBP,CAAI,EAAE,MACzBQ,aAAW,OAAA,EAGb1C,EAAc,IAAI,CACnB,EACA,CAACH,EAAciC,CAAkB,CAAA,EAE5Ba,GAAuBzB,EAAAA,YAC3BgB,GAA2B,CAC3B,MAAMM,EAAQ,CAAC7C,EAAY,KAAM6B,GAAMA,EAAE,KAAOU,EAAK,EAAE,EAEvD,GADAtC,EAAgBgC,GAASlE,GAAWkE,EAAMM,CAAI,CAAC,EAC3CM,EAAO,CACV,MAAMR,EACLE,EAAK,WAAa,qBACfQ,aAAW,MACXA,EAAAA,WAAW,cACfZ,EAAmBI,EAAK,GAAIU,EAAAA,sBAAsBV,CAAI,EAAE,MAAOF,CAAM,CACtE,CACAhC,EAAc,IAAI,CACnB,EACA,CAACL,EAAamC,CAAkB,CAAA,EAI3B,CAACe,EAAMC,CAAO,EAAI1D,EAAAA,SACvB,IAAA,EAEK2D,EAAkB7C,EAAAA,OAMd,IAAI,EACR8C,GAAY9C,EAAAA,OAAO,CAAC,EAKpB+C,GAActB,GAAe,CAClC,MAAMI,EACL1D,EAAe,KAAMmD,GAAMA,EAAE,UAAYG,CAAE,GAAG,cAC9C9B,EAAa,KAAM2B,GAAMA,EAAE,KAAOG,CAAE,GAAG,MACvC,OAEKuB,EAAQ,UAAUvB,CAAE,KACpBwB,EAASC,GAAiBA,EAAK,MAAMF,CAAK,EAAE,KAAK,EAAE,EACzDH,EAAgB,QAAU,CACzB,aAAA1D,EACA,UAAAE,EAAA,MACAE,EACA,YAAAE,EACA,aAAAE,CAAA,EAEDP,EAAiBsC,GAASuB,EAAMvB,CAAI,CAAC,EACrCpC,EAAcoC,GAASuB,EAAMvB,CAAI,CAAC,EAClClC,EAAUkC,GAASA,EAAK,OAAQJ,GAAMA,IAAMG,CAAE,CAAC,EAC/C/B,EAAgBgC,GAASA,EAAK,OAAQJ,GAAMA,EAAE,KAAOG,CAAE,CAAC,EACxD7B,EAAiB8B,GAASA,EAAK,OAAQJ,GAAMA,EAAE,KAAOG,CAAE,CAAC,EACzDrB,EAAa+C,GAAMA,EAAI,CAAC,EACxB7C,EAAa6C,GAAMA,EAAI,CAAC,EACxBL,GAAU,SAAW,EACrBF,EAAQ,CAAE,GAAIE,GAAU,QAAS,QAAS,SAASjB,CAAK,YAAa,CACtE,EAEMuB,GAAa,IAAM,CACxB,MAAMC,EAAOR,EAAgB,QACzBQ,IACHjE,EAAgBiE,EAAK,YAAY,EACjC/D,EAAa+D,EAAK,SAAS,EAC3B7D,EAAS6D,EAAK,KAAK,EACnB3D,EAAe2D,EAAK,WAAW,EAC/BzD,EAAgByD,EAAK,YAAY,EACjCjD,EAAa+C,GAAMA,EAAI,CAAC,EACxB7C,EAAa6C,GAAMA,EAAI,CAAC,EACxBN,EAAgB,QAAU,MAE3BD,EAAQ,IAAI,CACb,EAEMU,EAActE,EAAK,KAAA,EAGnBuE,EACLD,EAAY,OAAS,GACrB3E,GAAc,KACZ6E,GAAMA,EAAE,KAAA,EAAO,YAAA,IAAkBF,EAAY,YAAA,CAAY,EAEtDG,GACLH,EAAY,OAAS,GACrB,CAACC,IACApE,EAAa,KAAA,EAAO,OAAS,GAAKE,EAAU,KAAA,EAAO,OAAS,GAExDqE,GAA8BnE,EAClC,IAAKkC,GAA8B,CACnC,MAAMO,EAAO7D,EAAe,KAAMmD,GAAMA,EAAE,UAAYG,CAAE,EACxD,OAAOO,EACJ,CACA,GAAAP,EACA,MAAOO,EAAK,aACZ,KAAM2B,EAAAA,WAAW3B,EAAK,QAAUQ,EAAAA,WAAW,QAAQ,EAGnD,aAAcR,EAAK,aAAA,EAEnB,IACJ,CAAC,EACA,OAAQpE,GAA2BA,IAAM,IAAI,EAIzCgG,GAAiCjE,EAAa,IAAK2B,IAAO,CAC/D,GAAIA,EAAE,GACN,MAAOuC,EAAAA,gBAAgBvC,CAAC,EACxB,KAAMwC,EAAAA,aAAatB,EAAAA,WAAW,OAAO,EACrC,YAAa,IAAMT,EAAYT,CAAC,CAAA,EAC/B,EACIyC,GAAoCtE,EAAY,IAAK6B,IAAO,CACjE,GAAIA,EAAE,GACN,MAAO0C,EAAAA,eAAe1C,CAAC,EACvB,KAAMwC,EAAAA,aACLxC,EAAE,WAAa,qBACZkB,aAAW,MACXA,EAAAA,WAAW,aACf,EACA,YAAa,IAAMP,EAAeX,EAAE,SAAUA,CAAC,CAAA,EAC9C,EACI2C,GAAiC,CACtC,GAAGP,GACH,GAAGE,GACH,GAAGG,EAAA,EAMEG,EAAoBC,GAAAA,iBACzB7F,EACA6D,GACA5D,EACAC,CAAA,EAGK4F,GACLvE,GAAY,OAAS,UAAYA,EAAW,QACzCvB,IAAsBuB,EAAW,OAAO,EACxC,OAIEwE,GAA8BlG,EAAe,IAAKmD,IAAO,CAC9D,MAAOA,EAAE,aACT,MAAOA,EAAE,QACT,YACCgD,EAAAA,iBAAiBX,aAAWrC,EAAE,QAAUkB,EAAAA,WAAW,QAAQ,CAAC,GAC5D,MAAA,EACA,EAII+B,IAAmC,IAAM,CAC9C,MAAMC,EAAkB,CAAA,EAClBC,MAAe,IACrB,OAAAtG,EAAe,QAASmD,GAAM,CAC7B,MAAMoD,EAAMpD,EAAE,QAAUkB,EAAAA,WAAW,SAC9BiC,EAAS,IAAIC,CAAG,IACpBD,EAAS,IAAIC,EAAK,EAAE,EACpBF,EAAM,KAAKE,CAAG,GAEfD,EAAS,IAAIC,CAAG,GAAG,KAAK,CACvB,MAAOpD,EAAE,aACT,MAAOA,EAAE,QACT,YACCgD,EAAAA,iBAAiBX,aAAWrC,EAAE,QAAUkB,EAAAA,WAAW,QAAQ,CAAC,GAC5D,MAAA,CACD,CACF,CAAC,EACMgC,EAAM,IAAKE,IAAS,CAC1B,OAAQA,EACR,MAAOC,EAAAA,gBAAgBD,CAAG,EAC1B,QAASD,EAAS,IAAIC,CAAG,GAAK,CAAA,EAG9B,UAAWnG,IAAoBmG,CAAiB,EAChD,UAAW,IAAMlG,IAAuBkG,CAAiB,CAAA,EACxD,CACH,GAAA,EAEME,GAAa,SAAY,CAC9B,GAAI,CAACnB,IAAWxD,GACf,OAED,MAAM4E,EAAS3G,EAAO,CACrB,KAAMc,EAAK,KAAA,EACX,aAAAG,EACA,UAAAE,EAAA,MACAE,EACA,YAAAE,EACA,aAAAE,CAAA,CACA,EACD,GAAIkF,GAAU,OAAQA,EAAyB,MAAS,WAAY,CACnE3E,GAAU,EAAI,EACd,GAAI,CACH,MAAM2E,CACP,QAAA,CACC3E,GAAU,EAAK,CAChB,CACD,CACD,EAEM4E,GAAgB,MAAOtD,GAAuC,CACnE,GAAI,GAACpD,GAAamC,GAGlB,CAAAC,GAAagB,CAAI,EACjB,GAAI,CAEH,MAAMuD,EAAW,MAAM3G,EAAUoD,EADjBA,IAAS,eAAiBrC,EAAeE,CACX,EAC1CmC,IAAS,gBACZpC,EAAgB2F,CAAQ,EACxB3E,EAAa+C,GAAMA,EAAI,CAAC,IAExB7D,EAAayF,CAAQ,EACrBzE,EAAa6C,GAAMA,EAAI,CAAC,EAE1B,QAAA,CACC3C,GAAa,IAAI,CAClB,EACD,EAEA,OACCwE,EAAAA,KAAAC,WAAA,CACC,SAAA,CAAAD,EAAAA,KAACE,GAAAA,UAAA,CACA,OAAQzG,GACR,iBAAkB,GAClB,OAAQnB,GACR,sBACC6H,EAAAA,IAACC,EAAAA,iBAAA,CACA,MAAA3G,GACA,SAAS,2FAAA,CAAA,EAGX,MAAM,QACN,YAAa4G,EAAAA,oBACb,UAAWC,EAAAA,kBACX,QAAArH,EACA,gBAAiB,CAChB,YAAa,gBACb,WAAY,OACZ,WAAY,UACZ,KAAM,QACN,SAAU,CAACwF,GACX,UAAWxD,GACX,QAAS2E,EAAA,EAEV,kBAAmB,CAClB,YAAa,kBACb,WAAY,SACZ,WAAY,eACZ,KAAM,QACN,QAAS3G,CAAA,EAGV,SAAA,CAAAkH,EAAAA,IAACI,GAAAA,MAAA,CACA,YAAU,gBACV,UAAU,aACV,cAAa,GACb,YAAY,mBACZ,MAAOvG,EACP,aAAcH,EAAW,KACzB,qBAAqB,MACrB,aAAc,CAAE,SAAU,GAAI,WAAY,MAAA,EAC1C,MAAO0E,EAAkB,UAAY,OACrC,aACCA,EACG,4CACA,OAEJ,aAActE,EAAA,CAAA,EAGfkG,EAAAA,IAACK,GAAAA,cAAA,CACA,YAAU,wBACV,MAAM,eACN,MAAOrG,EACP,SAAUC,EACV,UAAWP,EAAW,aACtB,YAAY,2HACZ,UAAU,QACV,SAAU,SAASsB,EAAQ,GAC3B,aAAAM,EACA,MAAOtC,EACP,YAAa+F,EACb,cAAAnF,EACA,cAAa,GACb,kBAAAR,EACA,qBAAAC,EACA,gBAAiB+C,GACjB,QAASJ,GACT,eAAgBJ,GAChB,OACC3C,EACC+G,EAAAA,IAACtH,GAAA,CACA,KAAK,SACL,YAAU,gCACV,SAAU0C,IAAc,KACxB,QAAS,IAAMuE,GAAc,cAAc,EAE1C,SAAAvE,IAAc,eACZ,aACA,iBAAA,CAAA,EAED,MAAA,CAAA,EAIN4E,EAAAA,IAACK,GAAAA,cAAA,CACA,YAAU,qBACV,MAAM,aACN,MAAOnG,EACP,SAAUC,EACV,UAAWT,EAAW,UACtB,YAAY,kJACZ,UAAU,QACV,SAAU,SAASwB,EAAQ,GAC3B,aAAAI,EACA,MAAOtC,EACP,YAAa+F,EACb,cAAAnF,EACA,cAAa,GACb,kBAAAR,EACA,qBAAAC,EACA,gBAAiB+C,GACjB,QAASH,GACT,eAAgBF,GAChB,OACC9C,EACC+G,EAAAA,IAACtH,GAAA,CACA,KAAK,SACL,YAAU,6BACV,SAAU0C,IAAc,KACxB,QAAS,IAAMuE,GAAc,WAAW,EAEvC,SAAAvE,IAAc,YAAc,aAAe,iBAAA,CAAA,EAE1C,MAAA,CAAA,EAIN4E,EAAAA,IAACM,GAAAA,sBAAA,CACA,MAAM,2BACN,eAAe,iBACf,MAAOxB,GACP,eAAgBI,GAChB,aAAcE,GACd,aAAA9D,EACA,cAAeyD,EACf,UAAU,sBACV,cAAa,GACb,MAAQzC,GAAO,CACdG,EAAmBH,CAAE,EACrBjC,EAAUkC,GAASC,GAAAA,UAAUD,EAAMD,CAAE,CAAC,CACvC,EACA,SAAUsB,GACV,cAAe,CAAE,KAAM,OAAQ,OAAQxF,EAAqB,CAAA,CAAE,CAAA,CAC/D,CAAA,CAAA,EAGAsC,GAAY,OAAS,WACrBsF,EAAAA,IAACO,GAAAA,iBAAA,CAEA,QAAS7F,EAAW,YAAA,WACpBhB,EACA,cAAAE,EACA,UAAWV,EACX,QAAS,IAAMyB,EAAc,IAAI,EACjC,OAAQuC,GACR,OAAQ9E,CAAA,EAPHsC,EAAW,GAAA,EAWjBA,GAAY,OAAS,UACrBA,EAAW,SACXuE,IACCe,EAAAA,IAACQ,GAAAA,gBAAA,CAEA,QAAS9F,EAAW,QACpB,SAAUuE,GACV,QAASvE,EAAW,cAAA,WACpBhB,EACA,cAAAE,EACA,UAAWV,EACX,QAAS,IAAMyB,EAAc,IAAI,EACjC,OAAQ2C,GACR,OAAQlF,CAAA,EATHsC,EAAW,GAAA,EAalB8C,GACAwC,EAAAA,IAACS,GAAAA,QAAA,CAEA,KAAMjD,EAAK,QACX,KAAK,OACL,SAAS,YACT,UAAW,IACX,gBAAe,GACf,YAAa,CACZ,WAAY,OACZ,WAAY,GACZ,cAAe,KACdS,GAAA,EACO,CAAA,EACR,EAED,aAAc,IAAMR,EAAQ,IAAI,CAAA,EAd3BD,EAAK,EAAA,CAeX,EAEF,CAEF"}
|
|
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 type { VariableListInterfaceV3 } from '../../variable-picker-v3/model';\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 = (\n\tkind: 'tool' | 'subagent',\n\tid: string,\n\tlabel?: string,\n\tsource?: string,\n) => 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/**\n\t * Per-source integration connection state (today: Slack). A source mapped to\n\t * `false` shows a \"Connect\" affordance instead of drilling into its tools —\n\t * same gating the main builder's Step 3 tool section gets.\n\t */\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\t/** Open the consumer's connect flow for an unconnected integration source. */\n\tonConnectIntegration?: (source: ToolSource) => void;\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/**\n\t * Names of the other sub-agents already on this agent (exclude the one being\n\t * edited). Blocks saving a duplicate name — the LLM references sub-agents by it.\n\t */\n\texistingNames?: string[];\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\t/** Variable catalog for the editors' `@` picker \"Variables\" view. */\n\tvariablesData?: VariableListInterfaceV3[];\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\tintegrationStatus,\n\tonConnectIntegration,\n\ttitle = 'Create sub-agent',\n\tinitial,\n\texistingNames = [],\n\tappLabel = 'Manifest',\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tvariablesData,\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\t// Latest custom-tool ids, readable from the mount-captured `@` onSelect handler\n\t// (BikEditor captures it once) — mirrors the context's valueRef trick.\n\tconst customToolIdsRef = useRef<Set<string>>(new Set());\n\tcustomToolIdsRef.current = new Set(\n\t\t[...configTools, ...restApiTools].map((t) => t.id),\n\t);\n\tconst addToolMention = useCallback(\n\t\t(kind: 'tool' | 'subagent', id: string) => {\n\t\t\t// Only catalog tool ids belong in `tools`; custom tools (Rest API / email /\n\t\t\t// Slack) track themselves on their own lists. Picking an existing custom\n\t\t\t// tool from `@` must not leak its id in as a bogus native ref.\n\t\t\tif (kind === 'tool' && !customToolIdsRef.current.has(id)) {\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(\n\t\t(id: string, label?: string, source?: string) => {\n\t\t\tconst target =\n\t\t\t\tinsertersRef.current[lastFocusedRef.current] ??\n\t\t\t\tinsertersRef.current.instructions;\n\t\t\ttarget?.('tool', id, label, source);\n\t\t},\n\t\t[],\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\t// Pass the source so the fresh chip shows its icon (not yet in the list).\n\t\t\tif (isNew) {\n\t\t\t\tinsertToolAtCursor(\n\t\t\t\t\ttool.id,\n\t\t\t\t\trestApiMentionItem(tool).label,\n\t\t\t\t\tToolSource.RestApi,\n\t\t\t\t);\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\tconst source =\n\t\t\t\t\ttool.tool_key === 'send_slack_message'\n\t\t\t\t\t\t? ToolSource.Slack\n\t\t\t\t\t\t: ToolSource.EmailHandover;\n\t\t\t\tinsertToolAtCursor(tool.id, configToolMentionItem(tool).label, source);\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 nameTrimmed = name.trim();\n\t// Case-insensitive: two sub-agents on the same agent can't share a name (the\n\t// LLM references them by it) — mirrors the Rest API tool-name check.\n\tconst isDuplicateName =\n\t\tnameTrimmed.length > 0 &&\n\t\texistingNames.some(\n\t\t\t(n) => n.trim().toLowerCase() === nameTrimmed.toLowerCase(),\n\t\t);\n\tconst canSave =\n\t\tnameTrimmed.length > 0 &&\n\t\t!isDuplicateName &&\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\t\t// Shield flags a tool that needs customer verification, same as\n\t\t\t\t\t\t// the main builder's Step 3 tool rows.\n\t\t\t\t\t\tauthRequired: tool.auth_required,\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. Integration\n\t// state drives the \"Connect\" affordance, same as the main builder's Step 3.\n\tconst toolActionSources = buildToolActions(\n\t\tconfigToolTemplates,\n\t\topenToolAction,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\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, appLabel),\n\t\t\toptions: bySource.get(src) ?? [],\n\t\t\t// Not connected → the source button opens the connect flow instead of\n\t\t\t// its tool list (mirrors Step 3's tool section).\n\t\t\tconnected: integrationStatus?.[src as ToolSource],\n\t\t\tonConnect: () => onConnectIntegration?.(src as ToolSource),\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\tstate={isDuplicateName ? 'invalid' : undefined}\n\t\t\t\t\terrorMessage={\n\t\t\t\t\t\tisDuplicateName\n\t\t\t\t\t\t\t? 'A sub-agent with this name already exists'\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\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. The agent will follow them exactly. The more specific you are, the better it performs.\"\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\tvariablesData={variablesData}\n\t\t\t\t\taddDataButton\n\t\t\t\t\tintegrationStatus={integrationStatus}\n\t\t\t\t\tappLabel={appLabel}\n\t\t\t\t\tonConnectIntegration={onConnectIntegration}\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. Always stay within the cancellation policy. Do not process refunds above ₹10,000 without human approval.\"\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\tvariablesData={variablesData}\n\t\t\t\t\taddDataButton\n\t\t\t\t\tintegrationStatus={integrationStatus}\n\t\t\t\t\tappLabel={appLabel}\n\t\t\t\t\tonConnectIntegration={onConnectIntegration}\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\tappLabel={appLabel}\n\t\t\t\t\tpickerOpensUp\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\tvariablesData={variablesData}\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\tvariablesData={variablesData}\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","integrationStatus","onConnectIntegration","title","initial","existingNames","appLabel","charLimits","AGENT_CHAR_LIMITS","variablesData","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","customToolIdsRef","t","addToolMention","kind","id","prev","addUnique","insertToolAtCursor","label","source","openRestApi","tool","openConfigTool","toolKey","openToolAction","CONFIG_TOOL_SOURCES","handleSaveRestApi","isNew","restApiMentionItem","ToolSource","handleSaveConfigTool","configToolMentionItem","undo","setUndo","undoSnapshotRef","undoIdRef","removeTool","token","strip","text","k","undoRemove","snap","nameTrimmed","isDuplicateName","n","canSave","toolItems","sourceIcon","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,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),h=require("../../../assets/icons/
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),h=require("../../../assets/icons/successIcon.svg.js"),a=require("../../TypographyStyle.js"),r=require("../../../constants/Theme.js"),i=require("../AgentBuilder.styled.js"),x=require("../../modals/styledModal.js"),y=require("../../../icons/Social/Channels/ManifestGlass.js"),n=require("../../button/Button.js"),m=({mode:s,onClose:o,onConfirm:d,onSaveDraft:l,onGoToDashboard:c,isPublishing:u})=>{if(!s)return null;const t=s==="success";return e.jsx(x.StyledModal,{"data-test":"agent-go-live-modal",open:!0,onClose:o,width:t?"400px":"520px",children:e.jsxs(i.ModalBody,{style:{gap:"24px"},children:[e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[e.jsx(i.ModalIcon,{children:t?e.jsx(h.default,{width:64,height:64}):e.jsx(y.default,{width:64,height:64})}),e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[e.jsx(a.TitleMedium,{color:r.COLORS.content.primary,children:t?"Your agent is live!":"Ready to go live?"}),e.jsx(a.BodyPrimary,{color:r.COLORS.content.secondary,children:t?"You can manage your agents from the AI agent dashboard.":"This agent will start handling customer conversations immediately. You can pause it at any time."})]})]}),e.jsx(i.ModalActions,{children:t?e.jsx("div",{style:{display:"flex"},children:e.jsx(n.Button,{"data-test":"agent-go-dashboard",buttonType:"primary",size:"medium",matchParentWidth:!0,buttonText:"Go to Agent dashboard",onClick:c??o})}):e.jsxs(e.Fragment,{children:[e.jsx(i.DraftButtonScope,{children:e.jsx(n.Button,{"data-test":"agent-confirm-save-draft",buttonType:"secondary",size:"medium",matchParentWidth:!0,buttonText:"Save as draft",onClick:l})}),e.jsx("div",{style:{display:"flex"},children:e.jsx(n.Button,{"data-test":"agent-confirm-go-live",buttonType:"primary",size:"medium",matchParentWidth:!0,buttonText:"Go live now",isLoading:u,onClick:d})})]})})]})})};exports.GoLiveModal=m;
|
|
2
2
|
//# sourceMappingURL=GoLiveModal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoLiveModal.js","sources":["../../../../../src/components/agent-builder/components/GoLiveModal.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"GoLiveModal.js","sources":["../../../../../src/components/agent-builder/components/GoLiveModal.tsx"],"sourcesContent":["import SuccessIcon from '@src/assets/icons/successIcon.svg';\nimport { ManifestGlass } from '@src/icons';\nimport React from 'react';\nimport { Button } from '@src/components/button';\nimport { StyledModal } from '@src/components/modals';\nimport { BodyPrimary, TitleMedium } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tDraftButtonScope,\n\tModalActions,\n\tModalBody,\n\tModalIcon,\n} from '../AgentBuilder.styled';\n\nexport type GoLiveModalMode = 'confirm' | 'success' | null;\n\ninterface GoLiveModalProps {\n\tmode: GoLiveModalMode;\n\tonClose: () => void;\n\tonConfirm: () => void;\n\tonSaveDraft: () => void;\n\tonGoToDashboard?: () => void;\n\tisPublishing?: boolean;\n}\n\n/**\n * Confirm / success dialog for going live. Uses `StyledModal` as the shell but\n * renders the actions INSIDE the body (not StyledModal's footer) — the footer's\n * `margin-top:auto` detaches from this short, centered hero layout and spills\n * out of the card. Body-level actions stay anchored under the content.\n */\nexport const GoLiveModal: React.FC<GoLiveModalProps> = ({\n\tmode,\n\tonClose,\n\tonConfirm,\n\tonSaveDraft,\n\tonGoToDashboard,\n\tisPublishing,\n}) => {\n\tif (!mode) {\n\t\treturn null;\n\t}\n\n\tconst isSuccess = mode === 'success';\n\n\treturn (\n\t\t<StyledModal\n\t\t\tdata-test=\"agent-go-live-modal\"\n\t\t\topen\n\t\t\tonClose={onClose}\n\t\t\twidth={isSuccess ? '400px' : '520px'}\n\t\t>\n\t\t\t<ModalBody style={{ gap: '24px' }}>\n\t\t\t\t<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n\t\t\t\t\t<ModalIcon>\n\t\t\t\t\t\t{isSuccess ? (\n\t\t\t\t\t\t\t<SuccessIcon width={64} height={64} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<ManifestGlass width={64} height={64} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</ModalIcon>\n\n\t\t\t\t\t<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n\t\t\t\t\t\t<TitleMedium color={COLORS.content.primary}>\n\t\t\t\t\t\t\t{isSuccess ? 'Your agent is live!' : 'Ready to go live?'}\n\t\t\t\t\t\t</TitleMedium>\n\t\t\t\t\t\t<BodyPrimary color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t{isSuccess\n\t\t\t\t\t\t\t\t? 'You can manage your agents from the AI agent dashboard.'\n\t\t\t\t\t\t\t\t: 'This agent will start handling customer conversations immediately. You can pause it at any time.'}\n\t\t\t\t\t\t</BodyPrimary>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<ModalActions>\n\t\t\t\t\t{isSuccess ? (\n\t\t\t\t\t\t<div style={{ display: 'flex' }}>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tdata-test=\"agent-go-dashboard\"\n\t\t\t\t\t\t\t\tbuttonType=\"primary\"\n\t\t\t\t\t\t\t\tsize=\"medium\"\n\t\t\t\t\t\t\t\tmatchParentWidth\n\t\t\t\t\t\t\t\tbuttonText=\"Go to Agent dashboard\"\n\t\t\t\t\t\t\t\tonClick={onGoToDashboard ?? onClose}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<DraftButtonScope>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tdata-test=\"agent-confirm-save-draft\"\n\t\t\t\t\t\t\t\t\tbuttonType=\"secondary\"\n\t\t\t\t\t\t\t\t\tsize=\"medium\"\n\t\t\t\t\t\t\t\t\tmatchParentWidth\n\t\t\t\t\t\t\t\t\tbuttonText=\"Save as draft\"\n\t\t\t\t\t\t\t\t\tonClick={onSaveDraft}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</DraftButtonScope>\n\t\t\t\t\t\t\t<div style={{ display: 'flex' }}>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tdata-test=\"agent-confirm-go-live\"\n\t\t\t\t\t\t\t\t\tbuttonType=\"primary\"\n\t\t\t\t\t\t\t\t\tsize=\"medium\"\n\t\t\t\t\t\t\t\t\tmatchParentWidth\n\t\t\t\t\t\t\t\t\tbuttonText=\"Go live now\"\n\t\t\t\t\t\t\t\t\tisLoading={isPublishing}\n\t\t\t\t\t\t\t\t\tonClick={onConfirm}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t</ModalActions>\n\t\t\t</ModalBody>\n\t\t</StyledModal>\n\t);\n};\n"],"names":["GoLiveModal","mode","onClose","onConfirm","onSaveDraft","onGoToDashboard","isPublishing","isSuccess","jsx","StyledModal","ModalBody","jsxs","ModalIcon","SuccessIcon","ManifestGlass","TitleMedium","COLORS","BodyPrimary","ModalActions","Button","Fragment","DraftButtonScope"],"mappings":"2aA+BaA,EAA0C,CAAC,CACvD,KAAAC,EACA,QAAAC,EACA,UAAAC,EACA,YAAAC,EACA,gBAAAC,EACA,aAAAC,CACD,IAAM,CACL,GAAI,CAACL,EACJ,OAAO,KAGR,MAAMM,EAAYN,IAAS,UAE3B,OACCO,EAAAA,IAACC,EAAAA,YAAA,CACA,YAAU,sBACV,KAAI,GACJ,QAAAP,EACA,MAAOK,EAAY,QAAU,QAE7B,gBAACG,EAAAA,UAAA,CAAU,MAAO,CAAE,IAAK,QACxB,SAAA,CAAAC,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,KAAA,EAC5D,SAAA,CAAAH,MAACI,EAAAA,UAAA,CACC,SAAAL,EACAC,EAAAA,IAACK,EAAAA,QAAA,CAAY,MAAO,GAAI,OAAQ,GAAI,QAEnCC,EAAAA,QAAA,CAAc,MAAO,GAAI,OAAQ,GAAI,EAExC,EAEAH,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,KAAA,EAC5D,SAAA,CAAAH,EAAAA,IAACO,EAAAA,aAAY,MAAOC,SAAO,QAAQ,QACjC,SAAAT,EAAY,sBAAwB,mBAAA,CACtC,EACAC,EAAAA,IAACS,EAAAA,aAAY,MAAOD,SAAO,QAAQ,UACjC,SAAAT,EACE,0DACA,kGAAA,CACJ,CAAA,CAAA,CACD,CAAA,EACD,EAEAC,EAAAA,IAACU,EAAAA,cACC,SAAAX,EACAC,EAAAA,IAAC,OAAI,MAAO,CAAE,QAAS,MAAA,EACtB,SAAAA,EAAAA,IAACW,EAAAA,OAAA,CACA,YAAU,qBACV,WAAW,UACX,KAAK,SACL,iBAAgB,GAChB,WAAW,wBACX,QAASd,GAAmBH,CAAA,CAAA,CAC7B,CACD,EAEAS,EAAAA,KAAAS,EAAAA,SAAA,CACC,SAAA,CAAAZ,MAACa,EAAAA,iBAAA,CACA,SAAAb,EAAAA,IAACW,EAAAA,OAAA,CACA,YAAU,2BACV,WAAW,YACX,KAAK,SACL,iBAAgB,GAChB,WAAW,gBACX,QAASf,CAAA,CAAA,EAEX,QACC,MAAA,CAAI,MAAO,CAAE,QAAS,QACtB,SAAAI,EAAAA,IAACW,EAAAA,OAAA,CACA,YAAU,wBACV,WAAW,UACX,KAAK,SACL,iBAAgB,GAChB,WAAW,cACX,UAAWb,EACX,QAASH,CAAA,CAAA,CACV,CACD,CAAA,CAAA,CACD,CAAA,CAEF,CAAA,CAAA,CACD,CAAA,CAAA,CAGH"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),r=require("react"),R=require("styled-components"),E=require("../../TypographyStyle.js"),H=require("../../../constants/Theme.js"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),r=require("react"),R=require("styled-components"),E=require("../../TypographyStyle.js"),H=require("../../../constants/Theme.js"),W=require("../../add-variableV2/AddDataPill.js"),S=require("../AgentBuilder.styled.js"),X=require("../constants/editorStyle.js"),c=require("../utils/mentionSerialization.js"),O=require("../utils/sourceIcons.js"),Z=require("./MentionPicker.js"),ee=require("../../../editor/BikEditor.js"),te=n=>n&&typeof n=="object"&&"default"in n?n:{default:n},ne=te(R),re=n=>n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/\r?\n/g,"<br>"),oe=({label:n,value:s,onChange:P,maxLength:u,placeholder:$,minHeight:v="200px",resetKey:B,mentionItems:l,tools:_,onMentionSelect:A,onFocus:D,registerInsert:d,onCreateSubAgent:y,toolActions:m,integrationStatus:L,onConnectIntegration:F,appLabel:V,variablesData:f,addDataButton:N,action:w,...I})=>{const i=r.useRef(null),[z,C]=r.useState(s.length),[T,M]=r.useState(!1),h=(f?.length??0)>0,G=l.length===0&&(m?.length??0)===0&&!y&&h,J=r.useCallback(e=>{const t=c.variableTokenName(e.actualValue);i.current?.insertInlineContent(`${c.buildMentionHtml(t,`{{${t}}}`,"variable")} `)},[]),p=r.useRef(s.length),K=r.useCallback(({text:e})=>{if(!e)return!1;const t=i.current,b=t?.getSelectedText().length??0,a=u-(p.current-b);return e.length<=a?!1:(a<=0||t?.insertContent(re(e.slice(0,a))),!0)},[u]),q=r.useCallback((e,t,b,a)=>{const x=i.current;if(!x)return;const j=l.find(k=>String(k.id)===String(t)&&k.meta?.kind===e),Q=b??j?.label??t,U=a??j?.meta?.source;x.insertInlineContent(`${c.buildMentionHtml(String(t),Q,e,U)} `)},[l]);r.useEffect(()=>{if(d)return d(q),()=>d(null)},[d,q]);const g=`${B??""}:${h?"v1":"v0"}`,Y=r.useMemo(()=>c.instructionsToEditorHtml(s,[...l,...c.buildVariableMentionItems(f)]),[g]);return r.useEffect(()=>{C(s.length),p.current=s.length},[g]),o.jsxs(S.FieldBlock,{children:[o.jsxs(S.FieldLabelRow,{children:[o.jsx(E.TitleSmall,{color:H.COLORS.content.primary,children:n}),o.jsxs(E.BodyCaption,{color:H.COLORS.content.secondary,children:[z,"/",u]})]}),o.jsxs(ie,{minHeight:v,focused:T,$atHint:h,style:{position:"relative"},"data-test":I["data-test"],children:[o.jsx(ee.BikEditor,{ref:i,initialContent:Y,placeholder:$,characterLimit:u,characterLimitHard:!0,onPaste:K,minHeight:"120px",maxHeight:"320px",style:{border:"none"},editorStyle:X.AGENT_EDITOR_STYLE,onFocus:()=>{M(!0),D?.()},onBlur:()=>M(!1),mentions:{agents:l,removeTriggerOnDismiss:!0,renderChipIcon:e=>O.renderSourceIcon(O.sourceIcon(e??void 0),-6),renderDropdown:e=>o.jsx(Z.MentionPicker,{...e,onCreateSubAgent:y,toolActions:m,integrationStatus:L,appLabel:V,onConnectIntegration:F,variablesData:f,onSelectVariable:J}),onSelect:e=>{const t=e.meta?.kind;(t==="tool"||t==="subagent")&&A?.(t,String(e.id))}},onChange:e=>{C(e.characterCount),p.current=e.characterCount;const t=i.current?.getJSON()??null;P(c.editorDocToInstructions(t,_))}},g),w,N&&T&&o.jsx(W.AddDataPill,{"data-test":"mention-add-data",label:G?"Add variable":void 0,onOpen:()=>i.current?.actions.openMentionMenu("@")})]})]})},ie=ne.default(S.AiTextAreaShell)`
|
|
2
2
|
${n=>n.$atHint&&R.css`
|
|
3
3
|
.ProseMirror.ProseMirror-focused p.is-editor-empty:first-child::before {
|
|
4
4
|
content: 'Enter text, type @ to add variable';
|
|
5
5
|
}
|
|
6
6
|
`}
|
|
7
|
-
`;exports.MentionEditor=
|
|
7
|
+
`;exports.MentionEditor=oe;
|
|
8
8
|
//# sourceMappingURL=MentionEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MentionEditor.js","sources":["../../../../../src/components/agent-builder/components/MentionEditor.tsx"],"sourcesContent":["import { BikEditor, BikEditorRef, MentionItem, PasteData } from '@src/editor';\nimport React, {\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport styled, { css } from 'styled-components';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport { AddDataPill } from '../../add-variableV2/AddDataPill';\nimport type {\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport { AgentTool } from '../AgentBuilder.model';\nimport {\n\tAiTextAreaShell,\n\tFieldBlock,\n\tFieldLabelRow,\n} from '../AgentBuilder.styled';\nimport { AGENT_EDITOR_STYLE } from '../constants/editorStyle';\nimport type { ToolAction, ToolSource } from '../constants/tools';\nimport {\n\tbuildMentionHtml,\n\tbuildVariableMentionItems,\n\teditorDocToInstructions,\n\tinstructionsToEditorHtml,\n\tMentionKindMeta,\n\tvariableTokenName,\n} from '../utils/mentionSerialization';\nimport { renderSourceIcon, sourceIcon } from '../utils/sourceIcons';\nimport { MentionPicker } from './MentionPicker';\n\ntype InsertFn = (\n\tkind: 'tool' | 'subagent',\n\tid: string,\n\tlabel?: string,\n\tsource?: string,\n) => void;\n\n// Insert-safe HTML for a plain-text run: escape entities so pasted text is never\n// interpreted as markup, and keep line breaks (mirrors the plain-paste pipeline).\nconst plainTextToHtml = (text: string): string =>\n\ttext\n\t\t.replace(/&/g, '&')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n\t\t.replace(/\\r?\\n/g, '<br>');\n\ninterface MentionEditorProps {\n\tlabel: string;\n\tvalue: string;\n\tonChange: (text: string) => void;\n\tmaxLength: number;\n\tplaceholder?: string;\n\tminHeight?: string;\n\t/** Changing this remounts the editor with fresh content. */\n\tresetKey?: string | number;\n\t/** Items shown in the `@` picker (tools, and sub-agents where allowed). */\n\tmentionItems: MentionItem[];\n\t/** Tools used to serialise mention nodes back to `{{tool:KEY}}`. */\n\ttools: AgentTool[];\n\t/** Called when an item is picked from the `@` menu (to attach it upstream). */\n\tonMentionSelect?: (kind: 'tool' | 'subagent', id: string) => void;\n\tonFocus?: () => void;\n\t/** Receives an insert-at-cursor fn (and null on unmount) for side-panel adds. */\n\tregisterInsert?: (fn: InsertFn | null) => void;\n\t/**\n\t * When set, the `@` picker's Sub-agent view shows a \"Create new\" row that calls\n\t * this (opens the create-sub-agent drawer). Omit to hide it (e.g. the drawer's\n\t * own editors, which can't nest sub-agents).\n\t */\n\tonCreateSubAgent?: () => void;\n\t/**\n\t * Built-in tool actions (Rest API / Handover to email) shown in the `@` picker's\n\t * Tools view. Picking one opens its drawer instead of inserting a mention.\n\t */\n\ttoolActions?: ToolAction[];\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\tonConnectIntegration?: (source: ToolSource) => void;\n\t/**\n\t * Variable catalog for the `@` picker's \"Variables\" view. Picking one inserts\n\t * a `{{<name>}}` mention chip (rendered as the purple raw token) at the\n\t * cursor, persisted as `{{variable:<name>}}`. Omit to hide the category.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\n\t/**\n\t * Show a floating \"+ Add data\" pill at the field's bottom-right while it is\n\t * focused. Clicking it opens the same `@` reference menu at the cursor.\n\t */\n\taddDataButton?: boolean;\n\t/** Optional action(s) rendered inside the shell, below the editor. */\n\taction?: React.ReactNode;\n\t'data-test'?: string;\n}\n\n/**\n * Presentational BikEditor field with `@` mentions. Stores firebase token text\n * (`{{tool:KEY}}` / `{{subagent:ID}}`). Context-free — both the builder's\n * Step-3 fields and the create-sub-agent drawer compose it.\n */\nexport const MentionEditor: React.FC<MentionEditorProps> = ({\n\tlabel,\n\tvalue,\n\tonChange,\n\tmaxLength,\n\tplaceholder,\n\tminHeight = '200px',\n\tresetKey,\n\tmentionItems,\n\ttools,\n\tonMentionSelect,\n\tonFocus,\n\tregisterInsert,\n\tonCreateSubAgent,\n\ttoolActions,\n\tintegrationStatus,\n\tonConnectIntegration,\n\tvariablesData,\n\taddDataButton,\n\taction,\n\t...rest\n}) => {\n\tconst editorRef = useRef<BikEditorRef>(null);\n\tconst [count, setCount] = useState(value.length);\n\tconst [focused, setFocused] = useState(false);\n\n\tconst hasVariables = (variablesData?.length ?? 0) > 0;\n\t// No tools / sub-agents on offer → `@` lands directly on the variable list,\n\t// so the affordance reads \"Add variable\" rather than the generic \"Add data\".\n\tconst variablesOnly =\n\t\tmentionItems.length === 0 &&\n\t\t(toolActions?.length ?? 0) === 0 &&\n\t\t!onCreateSubAgent &&\n\t\thasVariables;\n\n\t// The picker dismissed itself already (stripping the \"@\" + query) — drop a\n\t// mention chip at the cursor whose text is the raw token (`{{<name>}}`,\n\t// rendered purple by the editor). `editorDocToInstructions` serializes it\n\t// back to a `{{variable:<name>}}` token.\n\tconst onSelectVariable = useCallback((variable: VariableV3) => {\n\t\tconst name = variableTokenName(variable.actualValue);\n\t\teditorRef.current?.insertInlineContent(\n\t\t\t`${buildMentionHtml(name, `{{${name}}}`, 'variable')} `,\n\t\t);\n\t}, []);\n\t// Live character count for the paste handler (BikEditor captures onPaste once\n\t// at mount, so it can't read the `count` state without going stale).\n\tconst countRef = useRef(value.length);\n\n\t// On paste, insert only the characters that still fit under the limit instead\n\t// of letting the paste overflow. Pastes that fit fall through to the editor's\n\t// normal (break-preserving) plain-paste pipeline.\n\tconst handlePaste = useCallback(\n\t\t({ text }: PasteData): boolean | void => {\n\t\t\tif (!text) {\n\t\t\t\treturn false; // non-text (e.g. images) → default handling\n\t\t\t}\n\t\t\tconst editor = editorRef.current;\n\t\t\tconst selectionLength = editor?.getSelectedText().length ?? 0;\n\t\t\tconst room = maxLength - (countRef.current - selectionLength);\n\t\t\tif (text.length <= room) {\n\t\t\t\treturn false; // fits → let the default plain-paste pipeline run\n\t\t\t}\n\t\t\tif (room <= 0) {\n\t\t\t\treturn true; // already full → drop the paste\n\t\t\t}\n\t\t\teditor?.insertContent(plainTextToHtml(text.slice(0, room)));\n\t\t\treturn true;\n\t\t},\n\t\t[maxLength],\n\t);\n\n\tconst insert = useCallback<InsertFn>(\n\t\t(kind, id, overrideLabel, overrideSource) => {\n\t\t\tconst editor = editorRef.current;\n\t\t\tif (!editor) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst item = mentionItems.find(\n\t\t\t\t(m) =>\n\t\t\t\t\tString(m.id) === String(id) &&\n\t\t\t\t\t(m.meta as unknown as MentionKindMeta | undefined)?.kind === kind,\n\t\t\t);\n\t\t\tconst finalLabel = overrideLabel ?? item?.label ?? id;\n\t\t\t// Prefer the caller-supplied source: a JUST-created custom tool (Rest API /\n\t\t\t// email / Slack) isn't in `mentionItems` yet, so the lookup would miss and\n\t\t\t// the chip would render without its icon until reload.\n\t\t\tconst source =\n\t\t\t\toverrideSource ??\n\t\t\t\t(item?.meta as unknown as MentionKindMeta | undefined)?.source;\n\t\t\teditor.insertInlineContent(\n\t\t\t\t`${buildMentionHtml(String(id), finalLabel, kind, source)} `,\n\t\t\t);\n\t\t},\n\t\t[mentionItems],\n\t);\n\n\tuseEffect(() => {\n\t\tif (!registerInsert) {\n\t\t\treturn;\n\t\t}\n\t\tregisterInsert(insert);\n\t\treturn () => registerInsert(null);\n\t}, [registerInsert, insert]);\n\n\t// Initial HTML, re-derived (editor remounted via editorKey) on resetKey AND\n\t// when the variable catalog first arrives — a consumer may fetch it async,\n\t// and without the re-seed, stored `{{variable:…}}` tokens stay literal text\n\t// instead of chips. `value` is kept current by onChange, so the remount\n\t// re-seeds from the latest content.\n\tconst editorKey = `${resetKey ?? ''}:${hasVariables ? 'v1' : 'v0'}`;\n\tconst initialHtml = useMemo(\n\t\t() =>\n\t\t\tinstructionsToEditorHtml(value, [\n\t\t\t\t...mentionItems,\n\t\t\t\t...buildVariableMentionItems(variablesData),\n\t\t\t]),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editorKey],\n\t);\n\n\tuseEffect(\n\t\t() => {\n\t\t\tsetCount(value.length);\n\t\t\tcountRef.current = value.length;\n\t\t},\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editorKey],\n\t);\n\n\treturn (\n\t\t<FieldBlock>\n\t\t\t<FieldLabelRow>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>{label}</TitleSmall>\n\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t{count}/{maxLength}\n\t\t\t\t</BodyCaption>\n\t\t\t</FieldLabelRow>\n\n\t\t\t<MentionShell\n\t\t\t\tminHeight={minHeight}\n\t\t\t\tfocused={focused}\n\t\t\t\t$atHint={hasVariables}\n\t\t\t\t// Anchors the floating pill to the shell's corner.\n\t\t\t\tstyle={{ position: 'relative' }}\n\t\t\t\tdata-test={rest['data-test']}\n\t\t\t>\n\t\t\t\t<BikEditor\n\t\t\t\t\tkey={editorKey}\n\t\t\t\t\tref={editorRef}\n\t\t\t\t\tinitialContent={initialHtml}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t// Hard limit: nothing may push the content past the cap. Typing,\n\t\t\t\t\t// Enter and drop past it are rejected; a paste is truncated to fill\n\t\t\t\t\t// the remaining room (`onPaste` pre-trims; the hard filter trims any\n\t\t\t\t\t// residue). Content loaded over the cap is kept and can only shrink.\n\t\t\t\t\t// Same metric as the shown count.\n\t\t\t\t\tcharacterLimit={maxLength}\n\t\t\t\t\tcharacterLimitHard\n\t\t\t\t\tonPaste={handlePaste}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"320px\"\n\t\t\t\t\tstyle={{ border: 'none' }}\n\t\t\t\t\teditorStyle={AGENT_EDITOR_STYLE}\n\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\tsetFocused(true);\n\t\t\t\t\t\tonFocus?.();\n\t\t\t\t\t}}\n\t\t\t\t\tonBlur={() => setFocused(false)}\n\t\t\t\t\tmentions={{\n\t\t\t\t\t\tagents: mentionItems,\n\t\t\t\t\t\tremoveTriggerOnDismiss: true,\n\t\t\t\t\t\t// Tool chips lead with their source glyph (manifest / shopify / …);\n\t\t\t\t\t\t// sub-agent chips have no source, so no icon.\n\t\t\t\t\t\trenderChipIcon: (source) =>\n\t\t\t\t\t\t\trenderSourceIcon(sourceIcon(source ?? undefined), -6),\n\t\t\t\t\t\trenderDropdown: (props) => (\n\t\t\t\t\t\t\t<MentionPicker\n\t\t\t\t\t\t\t\t{...props}\n\t\t\t\t\t\t\t\tonCreateSubAgent={onCreateSubAgent}\n\t\t\t\t\t\t\t\ttoolActions={toolActions}\n\t\t\t\t\t\t\t\tintegrationStatus={integrationStatus}\n\t\t\t\t\t\t\t\tonConnectIntegration={onConnectIntegration}\n\t\t\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t\t\t\tonSelectVariable={onSelectVariable}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t),\n\t\t\t\t\t\tonSelect: (item) => {\n\t\t\t\t\t\t\tconst kind = (item.meta as unknown as MentionKindMeta | undefined)\n\t\t\t\t\t\t\t\t?.kind;\n\t\t\t\t\t\t\t// Variables never come through this path (they use the embedded\n\t\t\t\t\t\t\t// picker's onSelectVariable) and have nothing to attach upstream.\n\t\t\t\t\t\t\tif (kind === 'tool' || kind === 'subagent') {\n\t\t\t\t\t\t\t\tonMentionSelect?.(kind, String(item.id));\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\tonChange={(snapshot) => {\n\t\t\t\t\t\tsetCount(snapshot.characterCount);\n\t\t\t\t\t\tcountRef.current = snapshot.characterCount;\n\t\t\t\t\t\tconst doc = editorRef.current?.getJSON() ?? null;\n\t\t\t\t\t\tonChange(editorDocToInstructions(doc, tools));\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t{action}\n\t\t\t\t{addDataButton && focused && (\n\t\t\t\t\t<AddDataPill\n\t\t\t\t\t\tdata-test=\"mention-add-data\"\n\t\t\t\t\t\tlabel={variablesOnly ? 'Add variable' : undefined}\n\t\t\t\t\t\tonOpen={() => editorRef.current?.actions.openMentionMenu('@')}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</MentionShell>\n\t\t</FieldBlock>\n\t);\n};\n\n// While the (empty) editor is focused, the placeholder switches to the `@`\n// hint — but only when a variable catalog is actually on offer; a field\n// without one keeps its own placeholder (the hint would promise a Variables\n// category the picker doesn't show).\nconst MentionShell = styled(AiTextAreaShell)<{ $atHint: boolean }>`\n\t${(p) =>\n\t\tp.$atHint &&\n\t\tcss`\n\t\t\t.ProseMirror.ProseMirror-focused p.is-editor-empty:first-child::before {\n\t\t\t\tcontent: 'Enter text, type @ to add variable';\n\t\t\t}\n\t\t`}\n`;\n"],"names":["plainTextToHtml","text","MentionEditor","label","value","onChange","maxLength","placeholder","minHeight","resetKey","mentionItems","tools","onMentionSelect","onFocus","registerInsert","onCreateSubAgent","toolActions","integrationStatus","onConnectIntegration","variablesData","addDataButton","action","rest","editorRef","useRef","count","setCount","useState","focused","setFocused","hasVariables","variablesOnly","onSelectVariable","useCallback","variable","name","variableTokenName","buildMentionHtml","countRef","handlePaste","editor","selectionLength","room","insert","kind","id","overrideLabel","overrideSource","item","m","finalLabel","source","useEffect","editorKey","initialHtml","useMemo","instructionsToEditorHtml","buildVariableMentionItems","FieldBlock","jsxs","FieldLabelRow","jsx","TitleSmall","COLORS","BodyCaption","MentionShell","BikEditor","AGENT_EDITOR_STYLE","renderSourceIcon","sourceIcon","props","MentionPicker","snapshot","doc","editorDocToInstructions","AddDataPill","styled","AiTextAreaShell","p","css"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MentionEditor.js","sources":["../../../../../src/components/agent-builder/components/MentionEditor.tsx"],"sourcesContent":["import { BikEditor, BikEditorRef, MentionItem, PasteData } from '@src/editor';\nimport React, {\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport styled, { css } from 'styled-components';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport { AddDataPill } from '../../add-variableV2/AddDataPill';\nimport type {\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport { AgentTool } from '../AgentBuilder.model';\nimport {\n\tAiTextAreaShell,\n\tFieldBlock,\n\tFieldLabelRow,\n} from '../AgentBuilder.styled';\nimport { AGENT_EDITOR_STYLE } from '../constants/editorStyle';\nimport type { ToolAction, ToolSource } from '../constants/tools';\nimport {\n\tbuildMentionHtml,\n\tbuildVariableMentionItems,\n\teditorDocToInstructions,\n\tinstructionsToEditorHtml,\n\tMentionKindMeta,\n\tvariableTokenName,\n} from '../utils/mentionSerialization';\nimport { renderSourceIcon, sourceIcon } from '../utils/sourceIcons';\nimport { MentionPicker } from './MentionPicker';\n\ntype InsertFn = (\n\tkind: 'tool' | 'subagent',\n\tid: string,\n\tlabel?: string,\n\tsource?: string,\n) => void;\n\n// Insert-safe HTML for a plain-text run: escape entities so pasted text is never\n// interpreted as markup, and keep line breaks (mirrors the plain-paste pipeline).\nconst plainTextToHtml = (text: string): string =>\n\ttext\n\t\t.replace(/&/g, '&')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n\t\t.replace(/\\r?\\n/g, '<br>');\n\ninterface MentionEditorProps {\n\tlabel: string;\n\tvalue: string;\n\tonChange: (text: string) => void;\n\tmaxLength: number;\n\tplaceholder?: string;\n\tminHeight?: string;\n\t/** Changing this remounts the editor with fresh content. */\n\tresetKey?: string | number;\n\t/** Items shown in the `@` picker (tools, and sub-agents where allowed). */\n\tmentionItems: MentionItem[];\n\t/** Tools used to serialise mention nodes back to `{{tool:KEY}}`. */\n\ttools: AgentTool[];\n\t/** Called when an item is picked from the `@` menu (to attach it upstream). */\n\tonMentionSelect?: (kind: 'tool' | 'subagent', id: string) => void;\n\tonFocus?: () => void;\n\t/** Receives an insert-at-cursor fn (and null on unmount) for side-panel adds. */\n\tregisterInsert?: (fn: InsertFn | null) => void;\n\t/**\n\t * When set, the `@` picker's Sub-agent view shows a \"Create new\" row that calls\n\t * this (opens the create-sub-agent drawer). Omit to hide it (e.g. the drawer's\n\t * own editors, which can't nest sub-agents).\n\t */\n\tonCreateSubAgent?: () => void;\n\t/**\n\t * Built-in tool actions (Rest API / Handover to email) shown in the `@` picker's\n\t * Tools view. Picking one opens its drawer instead of inserting a mention.\n\t */\n\ttoolActions?: ToolAction[];\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\tonConnectIntegration?: (source: ToolSource) => void;\n\t/** Host-app name for the native tool group in the `@` picker (see MentionPicker). */\n\tappLabel?: string;\n\t/**\n\t * Variable catalog for the `@` picker's \"Variables\" view. Picking one inserts\n\t * a `{{<name>}}` mention chip (rendered as the purple raw token) at the\n\t * cursor, persisted as `{{variable:<name>}}`. Omit to hide the category.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\n\t/**\n\t * Show a floating \"+ Add data\" pill at the field's bottom-right while it is\n\t * focused. Clicking it opens the same `@` reference menu at the cursor.\n\t */\n\taddDataButton?: boolean;\n\t/** Optional action(s) rendered inside the shell, below the editor. */\n\taction?: React.ReactNode;\n\t'data-test'?: string;\n}\n\n/**\n * Presentational BikEditor field with `@` mentions. Stores firebase token text\n * (`{{tool:KEY}}` / `{{subagent:ID}}`). Context-free — both the builder's\n * Step-3 fields and the create-sub-agent drawer compose it.\n */\nexport const MentionEditor: React.FC<MentionEditorProps> = ({\n\tlabel,\n\tvalue,\n\tonChange,\n\tmaxLength,\n\tplaceholder,\n\tminHeight = '200px',\n\tresetKey,\n\tmentionItems,\n\ttools,\n\tonMentionSelect,\n\tonFocus,\n\tregisterInsert,\n\tonCreateSubAgent,\n\ttoolActions,\n\tintegrationStatus,\n\tonConnectIntegration,\n\tappLabel,\n\tvariablesData,\n\taddDataButton,\n\taction,\n\t...rest\n}) => {\n\tconst editorRef = useRef<BikEditorRef>(null);\n\tconst [count, setCount] = useState(value.length);\n\tconst [focused, setFocused] = useState(false);\n\n\tconst hasVariables = (variablesData?.length ?? 0) > 0;\n\t// No tools / sub-agents on offer → `@` lands directly on the variable list,\n\t// so the affordance reads \"Add variable\" rather than the generic \"Add data\".\n\tconst variablesOnly =\n\t\tmentionItems.length === 0 &&\n\t\t(toolActions?.length ?? 0) === 0 &&\n\t\t!onCreateSubAgent &&\n\t\thasVariables;\n\n\t// The picker dismissed itself already (stripping the \"@\" + query) — drop a\n\t// mention chip at the cursor whose text is the raw token (`{{<name>}}`,\n\t// rendered purple by the editor). `editorDocToInstructions` serializes it\n\t// back to a `{{variable:<name>}}` token.\n\tconst onSelectVariable = useCallback((variable: VariableV3) => {\n\t\tconst name = variableTokenName(variable.actualValue);\n\t\teditorRef.current?.insertInlineContent(\n\t\t\t`${buildMentionHtml(name, `{{${name}}}`, 'variable')} `,\n\t\t);\n\t}, []);\n\t// Live character count for the paste handler (BikEditor captures onPaste once\n\t// at mount, so it can't read the `count` state without going stale).\n\tconst countRef = useRef(value.length);\n\n\t// On paste, insert only the characters that still fit under the limit instead\n\t// of letting the paste overflow. Pastes that fit fall through to the editor's\n\t// normal (break-preserving) plain-paste pipeline.\n\tconst handlePaste = useCallback(\n\t\t({ text }: PasteData): boolean | void => {\n\t\t\tif (!text) {\n\t\t\t\treturn false; // non-text (e.g. images) → default handling\n\t\t\t}\n\t\t\tconst editor = editorRef.current;\n\t\t\tconst selectionLength = editor?.getSelectedText().length ?? 0;\n\t\t\tconst room = maxLength - (countRef.current - selectionLength);\n\t\t\tif (text.length <= room) {\n\t\t\t\treturn false; // fits → let the default plain-paste pipeline run\n\t\t\t}\n\t\t\tif (room <= 0) {\n\t\t\t\treturn true; // already full → drop the paste\n\t\t\t}\n\t\t\teditor?.insertContent(plainTextToHtml(text.slice(0, room)));\n\t\t\treturn true;\n\t\t},\n\t\t[maxLength],\n\t);\n\n\tconst insert = useCallback<InsertFn>(\n\t\t(kind, id, overrideLabel, overrideSource) => {\n\t\t\tconst editor = editorRef.current;\n\t\t\tif (!editor) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst item = mentionItems.find(\n\t\t\t\t(m) =>\n\t\t\t\t\tString(m.id) === String(id) &&\n\t\t\t\t\t(m.meta as unknown as MentionKindMeta | undefined)?.kind === kind,\n\t\t\t);\n\t\t\tconst finalLabel = overrideLabel ?? item?.label ?? id;\n\t\t\t// Prefer the caller-supplied source: a JUST-created custom tool (Rest API /\n\t\t\t// email / Slack) isn't in `mentionItems` yet, so the lookup would miss and\n\t\t\t// the chip would render without its icon until reload.\n\t\t\tconst source =\n\t\t\t\toverrideSource ??\n\t\t\t\t(item?.meta as unknown as MentionKindMeta | undefined)?.source;\n\t\t\teditor.insertInlineContent(\n\t\t\t\t`${buildMentionHtml(String(id), finalLabel, kind, source)} `,\n\t\t\t);\n\t\t},\n\t\t[mentionItems],\n\t);\n\n\tuseEffect(() => {\n\t\tif (!registerInsert) {\n\t\t\treturn;\n\t\t}\n\t\tregisterInsert(insert);\n\t\treturn () => registerInsert(null);\n\t}, [registerInsert, insert]);\n\n\t// Initial HTML, re-derived (editor remounted via editorKey) on resetKey AND\n\t// when the variable catalog first arrives — a consumer may fetch it async,\n\t// and without the re-seed, stored `{{variable:…}}` tokens stay literal text\n\t// instead of chips. `value` is kept current by onChange, so the remount\n\t// re-seeds from the latest content.\n\tconst editorKey = `${resetKey ?? ''}:${hasVariables ? 'v1' : 'v0'}`;\n\tconst initialHtml = useMemo(\n\t\t() =>\n\t\t\tinstructionsToEditorHtml(value, [\n\t\t\t\t...mentionItems,\n\t\t\t\t...buildVariableMentionItems(variablesData),\n\t\t\t]),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editorKey],\n\t);\n\n\tuseEffect(\n\t\t() => {\n\t\t\tsetCount(value.length);\n\t\t\tcountRef.current = value.length;\n\t\t},\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editorKey],\n\t);\n\n\treturn (\n\t\t<FieldBlock>\n\t\t\t<FieldLabelRow>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>{label}</TitleSmall>\n\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t{count}/{maxLength}\n\t\t\t\t</BodyCaption>\n\t\t\t</FieldLabelRow>\n\n\t\t\t<MentionShell\n\t\t\t\tminHeight={minHeight}\n\t\t\t\tfocused={focused}\n\t\t\t\t$atHint={hasVariables}\n\t\t\t\t// Anchors the floating pill to the shell's corner.\n\t\t\t\tstyle={{ position: 'relative' }}\n\t\t\t\tdata-test={rest['data-test']}\n\t\t\t>\n\t\t\t\t<BikEditor\n\t\t\t\t\tkey={editorKey}\n\t\t\t\t\tref={editorRef}\n\t\t\t\t\tinitialContent={initialHtml}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t// Hard limit: nothing may push the content past the cap. Typing,\n\t\t\t\t\t// Enter and drop past it are rejected; a paste is truncated to fill\n\t\t\t\t\t// the remaining room (`onPaste` pre-trims; the hard filter trims any\n\t\t\t\t\t// residue). Content loaded over the cap is kept and can only shrink.\n\t\t\t\t\t// Same metric as the shown count.\n\t\t\t\t\tcharacterLimit={maxLength}\n\t\t\t\t\tcharacterLimitHard\n\t\t\t\t\tonPaste={handlePaste}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"320px\"\n\t\t\t\t\tstyle={{ border: 'none' }}\n\t\t\t\t\teditorStyle={AGENT_EDITOR_STYLE}\n\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\tsetFocused(true);\n\t\t\t\t\t\tonFocus?.();\n\t\t\t\t\t}}\n\t\t\t\t\tonBlur={() => setFocused(false)}\n\t\t\t\t\tmentions={{\n\t\t\t\t\t\tagents: mentionItems,\n\t\t\t\t\t\tremoveTriggerOnDismiss: true,\n\t\t\t\t\t\t// Tool chips lead with their source glyph (manifest / shopify / …);\n\t\t\t\t\t\t// sub-agent chips have no source, so no icon.\n\t\t\t\t\t\trenderChipIcon: (source) =>\n\t\t\t\t\t\t\trenderSourceIcon(sourceIcon(source ?? undefined), -6),\n\t\t\t\t\t\trenderDropdown: (props) => (\n\t\t\t\t\t\t\t<MentionPicker\n\t\t\t\t\t\t\t\t{...props}\n\t\t\t\t\t\t\t\tonCreateSubAgent={onCreateSubAgent}\n\t\t\t\t\t\t\t\ttoolActions={toolActions}\n\t\t\t\t\t\t\t\tintegrationStatus={integrationStatus}\n\t\t\t\t\t\t\t\tappLabel={appLabel}\n\t\t\t\t\t\t\t\tonConnectIntegration={onConnectIntegration}\n\t\t\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t\t\t\tonSelectVariable={onSelectVariable}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t),\n\t\t\t\t\t\tonSelect: (item) => {\n\t\t\t\t\t\t\tconst kind = (item.meta as unknown as MentionKindMeta | undefined)\n\t\t\t\t\t\t\t\t?.kind;\n\t\t\t\t\t\t\t// Variables never come through this path (they use the embedded\n\t\t\t\t\t\t\t// picker's onSelectVariable) and have nothing to attach upstream.\n\t\t\t\t\t\t\tif (kind === 'tool' || kind === 'subagent') {\n\t\t\t\t\t\t\t\tonMentionSelect?.(kind, String(item.id));\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\tonChange={(snapshot) => {\n\t\t\t\t\t\tsetCount(snapshot.characterCount);\n\t\t\t\t\t\tcountRef.current = snapshot.characterCount;\n\t\t\t\t\t\tconst doc = editorRef.current?.getJSON() ?? null;\n\t\t\t\t\t\tonChange(editorDocToInstructions(doc, tools));\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t{action}\n\t\t\t\t{addDataButton && focused && (\n\t\t\t\t\t<AddDataPill\n\t\t\t\t\t\tdata-test=\"mention-add-data\"\n\t\t\t\t\t\tlabel={variablesOnly ? 'Add variable' : undefined}\n\t\t\t\t\t\tonOpen={() => editorRef.current?.actions.openMentionMenu('@')}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</MentionShell>\n\t\t</FieldBlock>\n\t);\n};\n\n// While the (empty) editor is focused, the placeholder switches to the `@`\n// hint — but only when a variable catalog is actually on offer; a field\n// without one keeps its own placeholder (the hint would promise a Variables\n// category the picker doesn't show).\nconst MentionShell = styled(AiTextAreaShell)<{ $atHint: boolean }>`\n\t${(p) =>\n\t\tp.$atHint &&\n\t\tcss`\n\t\t\t.ProseMirror.ProseMirror-focused p.is-editor-empty:first-child::before {\n\t\t\t\tcontent: 'Enter text, type @ to add variable';\n\t\t\t}\n\t\t`}\n`;\n"],"names":["plainTextToHtml","text","MentionEditor","label","value","onChange","maxLength","placeholder","minHeight","resetKey","mentionItems","tools","onMentionSelect","onFocus","registerInsert","onCreateSubAgent","toolActions","integrationStatus","onConnectIntegration","appLabel","variablesData","addDataButton","action","rest","editorRef","useRef","count","setCount","useState","focused","setFocused","hasVariables","variablesOnly","onSelectVariable","useCallback","variable","name","variableTokenName","buildMentionHtml","countRef","handlePaste","editor","selectionLength","room","insert","kind","id","overrideLabel","overrideSource","item","m","finalLabel","source","useEffect","editorKey","initialHtml","useMemo","instructionsToEditorHtml","buildVariableMentionItems","FieldBlock","jsxs","FieldLabelRow","jsx","TitleSmall","COLORS","BodyCaption","MentionShell","BikEditor","AGENT_EDITOR_STYLE","renderSourceIcon","sourceIcon","props","MentionPicker","snapshot","doc","editorDocToInstructions","AddDataPill","styled","AiTextAreaShell","p","css"],"mappings":"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"}
|
|
@@ -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 B=require("react/jsx-runtime"),n=require("react"),L=require("../context/AgentBuilderContext.js"),i=require("../utils/mentionSerialization.js"),h=require("../utils/toolActions.js"),k=require("./MentionEditor.js"),D=({fieldKey:e,label:d,placeholder:A,maxLength:T,minHeight:m,...M})=>{const{value:t,patch:C,addReference:u,availableTools:s,availableSubAgents:c,applicationType:a,mentionResetKey:S,registerMentionField:b,notifyMentionFocus:q,onCreateSubAgent:v,requestCreateSubAgent:F,requestToolAction:g,configToolTemplates:p,integrationStatus:r,onConnectIntegration:l,variablesData:I}=L.useAgentBuilderContext(),x=n.useMemo(()=>[...i.buildAgentMentionItems(s,c,i.appTypeLabel(a)),...i.buildCustomToolMentionItems(t.configTools,t.restApiTools)],[s,c,a,t.configTools,t.restApiTools]),R=n.useMemo(()=>h.buildToolActions(p,g,r,l),[g,p,r,l]),$=n.useCallback(o=>b(e,o),[b,e]),j=n.useCallback((o,y)=>u(o,y),[u]);return B.jsx(k.MentionEditor,{label:d,value:t[e]??"",onChange:o=>C({[e]:o}),maxLength:T,placeholder:A,minHeight:m,resetKey:`${t.id}:${e}:${S}`,mentionItems:x,tools:s,onMentionSelect:j,onFocus:()=>q(e),registerInsert:$,onCreateSubAgent:v?F:void 0,toolActions:R,integrationStatus:r,appLabel:i.appTypeLabel(a),onConnectIntegration:l,variablesData:I,addDataButton:!0,"data-test":M["data-test"]})};exports.MentionField=D;
|
|
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 { 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\tintegrationStatus,\n\t\tonConnectIntegration,\n\t\tvariablesData,\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() =>\n\t\t\tbuildToolActions(\n\t\t\t\tconfigToolTemplates,\n\t\t\t\trequestToolAction,\n\t\t\t\tintegrationStatus,\n\t\t\t\tonConnectIntegration,\n\t\t\t),\n\t\t[\n\t\t\trequestToolAction,\n\t\t\tconfigToolTemplates,\n\t\t\tintegrationStatus,\n\t\t\tonConnectIntegration,\n\t\t],\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\tintegrationStatus={integrationStatus}\n\t\t\tonConnectIntegration={onConnectIntegration}\n\t\t\tvariablesData={variablesData}\n\t\t\t// Step-3 fields get the floating \"+ Add data\" pill (same as typing @).\n\t\t\taddDataButton\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","integrationStatus","onConnectIntegration","variablesData","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,EACA,kBAAAC,EACA,qBAAAC,EACA,cAAAC,CAAA,EACGC,yBAAA,EAKEC,EAAeC,EAAAA,QACpB,IAAM,CACL,GAAGC,EAAAA,uBACFhB,EACAC,EACAgB,EAAAA,aAAaf,CAAe,CAAA,EAE7B,GAAGgB,8BAA4BrB,EAAM,YAAaA,EAAM,YAAY,CAAA,EAErE,CACCG,EACAC,EACAC,EACAL,EAAM,YACNA,EAAM,YAAA,CACP,EAOKsB,EAAcJ,EAAAA,QACnB,IACCK,EAAAA,iBACCX,EACAD,EACAE,EACAC,CAAA,EAEF,CACCH,EACAC,EACAC,EACAC,CAAA,CACD,EAGKU,EAAiBC,EAAAA,YACrBC,GACAnB,EAAqBb,EAAUgC,CAAE,EAClC,CAACnB,EAAsBb,CAAQ,CAAA,EAM1BiC,EAAkBF,EAAAA,YACvB,CAACG,EAA2BC,IAAe3B,EAAa0B,EAAMC,CAAE,EAChE,CAAC3B,CAAY,CAAA,EAGd,OACC4B,EAAAA,IAACC,EAAAA,cAAA,CACA,MAAApC,EACA,MAAQK,EAAMN,CAAQ,GAA4B,GAClD,SAAWsC,GAAS/B,EAAM,CAAE,CAACP,CAAQ,EAAGsC,EAA6B,EACrE,UAAAnC,EACA,YAAAD,EACA,UAAAE,EACA,SAAU,GAAGE,EAAM,EAAE,IAAIN,CAAQ,IAAIY,CAAe,GACpD,aAAAW,EACA,MAAOd,EACP,gBAAAwB,EACA,QAAS,IAAMnB,EAAmBd,CAAQ,EAC1C,eAAA8B,EACA,iBAAkBf,EAAmBC,EAAwB,OAAA,YAC7DY,EACA,kBAAAT,EACA,
|
|
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\tintegrationStatus,\n\t\tonConnectIntegration,\n\t\tvariablesData,\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() =>\n\t\t\tbuildToolActions(\n\t\t\t\tconfigToolTemplates,\n\t\t\t\trequestToolAction,\n\t\t\t\tintegrationStatus,\n\t\t\t\tonConnectIntegration,\n\t\t\t),\n\t\t[\n\t\t\trequestToolAction,\n\t\t\tconfigToolTemplates,\n\t\t\tintegrationStatus,\n\t\t\tonConnectIntegration,\n\t\t],\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\tintegrationStatus={integrationStatus}\n\t\t\tappLabel={appTypeLabel(applicationType)}\n\t\t\tonConnectIntegration={onConnectIntegration}\n\t\t\tvariablesData={variablesData}\n\t\t\t// Step-3 fields get the floating \"+ Add data\" pill (same as typing @).\n\t\t\taddDataButton\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","integrationStatus","onConnectIntegration","variablesData","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,EACA,kBAAAC,EACA,qBAAAC,EACA,cAAAC,CAAA,EACGC,yBAAA,EAKEC,EAAeC,EAAAA,QACpB,IAAM,CACL,GAAGC,EAAAA,uBACFhB,EACAC,EACAgB,EAAAA,aAAaf,CAAe,CAAA,EAE7B,GAAGgB,8BAA4BrB,EAAM,YAAaA,EAAM,YAAY,CAAA,EAErE,CACCG,EACAC,EACAC,EACAL,EAAM,YACNA,EAAM,YAAA,CACP,EAOKsB,EAAcJ,EAAAA,QACnB,IACCK,EAAAA,iBACCX,EACAD,EACAE,EACAC,CAAA,EAEF,CACCH,EACAC,EACAC,EACAC,CAAA,CACD,EAGKU,EAAiBC,EAAAA,YACrBC,GACAnB,EAAqBb,EAAUgC,CAAE,EAClC,CAACnB,EAAsBb,CAAQ,CAAA,EAM1BiC,EAAkBF,EAAAA,YACvB,CAACG,EAA2BC,IAAe3B,EAAa0B,EAAMC,CAAE,EAChE,CAAC3B,CAAY,CAAA,EAGd,OACC4B,EAAAA,IAACC,EAAAA,cAAA,CACA,MAAApC,EACA,MAAQK,EAAMN,CAAQ,GAA4B,GAClD,SAAWsC,GAAS/B,EAAM,CAAE,CAACP,CAAQ,EAAGsC,EAA6B,EACrE,UAAAnC,EACA,YAAAD,EACA,UAAAE,EACA,SAAU,GAAGE,EAAM,EAAE,IAAIN,CAAQ,IAAIY,CAAe,GACpD,aAAAW,EACA,MAAOd,EACP,gBAAAwB,EACA,QAAS,IAAMnB,EAAmBd,CAAQ,EAC1C,eAAA8B,EACA,iBAAkBf,EAAmBC,EAAwB,OAAA,YAC7DY,EACA,kBAAAT,EACA,SAAUO,EAAAA,aAAaf,CAAe,EACtC,qBAAAS,EACA,cAAAC,EAEA,cAAa,GACb,YAAWhB,EAAK,WAAW,CAAA,CAAA,CAG9B"}
|