@bikdotai/bik-component-library 0.0.853 → 0.0.855

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/cjs/components/add-variableV2/AddDataPill.js +10 -0
  2. package/dist/cjs/components/add-variableV2/AddDataPill.js.map +1 -0
  3. package/dist/cjs/components/agent-builder/AgentBuilder.js +1 -1
  4. package/dist/cjs/components/agent-builder/AgentBuilder.js.map +1 -1
  5. package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js +11 -11
  6. package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
  7. package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +5 -5
  8. package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
  9. package/dist/cjs/components/agent-builder/components/MentionEditor.js +7 -1
  10. package/dist/cjs/components/agent-builder/components/MentionEditor.js.map +1 -1
  11. package/dist/cjs/components/agent-builder/components/MentionField.js +1 -1
  12. package/dist/cjs/components/agent-builder/components/MentionField.js.map +1 -1
  13. package/dist/cjs/components/agent-builder/components/MentionPicker.js +41 -14
  14. package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
  15. package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js +6 -5
  16. package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
  17. package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +2 -2
  18. package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
  19. package/dist/cjs/components/agent-builder/components/VariableInlineField.js +65 -0
  20. package/dist/cjs/components/agent-builder/components/VariableInlineField.js.map +1 -0
  21. package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js +10 -0
  22. package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
  23. package/dist/cjs/components/agent-builder/constants/tools.js +1 -1
  24. package/dist/cjs/components/agent-builder/constants/tools.js.map +1 -1
  25. package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js +1 -1
  26. package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
  27. package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js +1 -1
  28. package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
  29. package/dist/cjs/components/agent-builder/utils/mentionSerialization.js +4 -4
  30. package/dist/cjs/components/agent-builder/utils/mentionSerialization.js.map +1 -1
  31. package/dist/cjs/components/toaster/Toaster.js +1 -1
  32. package/dist/cjs/components/toaster/Toaster.js.map +1 -1
  33. package/dist/cjs/components/toaster/Toaster.styled.js +7 -7
  34. package/dist/cjs/components/toaster/Toaster.styled.js.map +1 -1
  35. package/dist/cjs/components/variable-picker-v3/Content.js +1 -1
  36. package/dist/cjs/components/variable-picker-v3/Content.js.map +1 -1
  37. package/dist/cjs/editor/BikEditor.js +1 -1
  38. package/dist/cjs/editor/BikEditor.js.map +1 -1
  39. package/dist/cjs/editor/BikEditor.styles.js +8 -0
  40. package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
  41. package/dist/cjs/editor/BikEditor.types.js.map +1 -1
  42. package/dist/cjs/editor/extensions/mention/MentionDropdown.js +1 -1
  43. package/dist/cjs/editor/extensions/mention/MentionDropdown.js.map +1 -1
  44. package/dist/cjs/editor/extensions/mention/MentionExtension.js +1 -1
  45. package/dist/cjs/editor/extensions/mention/MentionExtension.js.map +1 -1
  46. package/dist/cjs/index.js +1 -1
  47. package/dist/esm/components/add-variableV2/AddDataPill.d.ts +24 -0
  48. package/dist/esm/components/add-variableV2/AddDataPill.js +33 -0
  49. package/dist/esm/components/add-variableV2/AddDataPill.js.map +1 -0
  50. package/dist/esm/components/add-variableV2/index.d.ts +1 -0
  51. package/dist/esm/components/agent-builder/AgentBuilder.js +76 -74
  52. package/dist/esm/components/agent-builder/AgentBuilder.js.map +1 -1
  53. package/dist/esm/components/agent-builder/AgentBuilder.model.d.ts +8 -0
  54. package/dist/esm/components/agent-builder/components/ConfigToolPanel.d.ts +8 -0
  55. package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +182 -136
  56. package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
  57. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.d.ts +3 -0
  58. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +195 -188
  59. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
  60. package/dist/esm/components/agent-builder/components/MentionEditor.d.ts +12 -0
  61. package/dist/esm/components/agent-builder/components/MentionEditor.js +144 -103
  62. package/dist/esm/components/agent-builder/components/MentionEditor.js.map +1 -1
  63. package/dist/esm/components/agent-builder/components/MentionField.js +48 -45
  64. package/dist/esm/components/agent-builder/components/MentionField.js.map +1 -1
  65. package/dist/esm/components/agent-builder/components/MentionPicker.d.ts +14 -1
  66. package/dist/esm/components/agent-builder/components/MentionPicker.js +286 -218
  67. package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
  68. package/dist/esm/components/agent-builder/components/RestApiToolPanel.d.ts +8 -0
  69. package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +192 -176
  70. package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
  71. package/dist/esm/components/agent-builder/components/ToolInstructionsField.d.ts +9 -0
  72. package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +67 -48
  73. package/dist/esm/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
  74. package/dist/esm/components/agent-builder/components/VariableInlineField.d.ts +26 -0
  75. package/dist/esm/components/agent-builder/components/VariableInlineField.js +149 -0
  76. package/dist/esm/components/agent-builder/components/VariableInlineField.js.map +1 -0
  77. package/dist/esm/components/agent-builder/components/VariableTriggerArea.d.ts +46 -0
  78. package/dist/esm/components/agent-builder/components/VariableTriggerArea.js +118 -0
  79. package/dist/esm/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
  80. package/dist/esm/components/agent-builder/constants/tools.d.ts +1 -1
  81. package/dist/esm/components/agent-builder/constants/tools.js +14 -13
  82. package/dist/esm/components/agent-builder/constants/tools.js.map +1 -1
  83. package/dist/esm/components/agent-builder/context/AgentBuilderContext.d.ts +7 -0
  84. package/dist/esm/components/agent-builder/context/AgentBuilderContext.js +99 -96
  85. package/dist/esm/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
  86. package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +164 -160
  87. package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
  88. package/dist/esm/components/agent-builder/utils/mentionSerialization.d.ts +14 -4
  89. package/dist/esm/components/agent-builder/utils/mentionSerialization.js +54 -36
  90. package/dist/esm/components/agent-builder/utils/mentionSerialization.js.map +1 -1
  91. package/dist/esm/components/toaster/Toaster.js +30 -25
  92. package/dist/esm/components/toaster/Toaster.js.map +1 -1
  93. package/dist/esm/components/toaster/Toaster.styled.js +5 -5
  94. package/dist/esm/components/toaster/Toaster.styled.js.map +1 -1
  95. package/dist/esm/components/variable-picker-v3/Content.js +16 -15
  96. package/dist/esm/components/variable-picker-v3/Content.js.map +1 -1
  97. package/dist/esm/editor/BikEditor.js +40 -34
  98. package/dist/esm/editor/BikEditor.js.map +1 -1
  99. package/dist/esm/editor/BikEditor.styles.js +20 -12
  100. package/dist/esm/editor/BikEditor.styles.js.map +1 -1
  101. package/dist/esm/editor/BikEditor.types.d.ts +9 -0
  102. package/dist/esm/editor/BikEditor.types.js.map +1 -1
  103. package/dist/esm/editor/extensions/mention/MentionDropdown.js +28 -28
  104. package/dist/esm/editor/extensions/mention/MentionDropdown.js.map +1 -1
  105. package/dist/esm/editor/extensions/mention/MentionExtension.js +23 -19
  106. package/dist/esm/editor/extensions/mention/MentionExtension.js.map +1 -1
  107. package/dist/esm/icons/index.d.ts +25 -25
  108. package/dist/esm/index.js +543 -541
  109. package/dist/esm/index.js.map +1 -1
  110. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"RestApiToolPanel.js","sources":["../../../../../src/components/agent-builder/components/RestApiToolPanel.tsx"],"sourcesContent":["import DeleteIcon from '@src/assets/icons/delete.svg';\nimport PlusIcon from '@src/assets/icons/plus.svg';\nimport { BikEditor } from '@src/editor';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { Dropdown, unwrapDropdownValue } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tRestApiHeader,\n\tRestApiMethod,\n\tRestApiToolConfig,\n} from '../AgentBuilder.model';\nimport { FieldBlock } from '../AgentBuilder.styled';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport {\n\tDRAWER_BODY_STYLE,\n\tDRAWER_HEADER_STYLE,\n\tDrawerHeaderText,\n} from './DrawerHeaderText';\nimport { ToolInstructionsField } from './ToolInstructionsField';\n\ninterface RestApiToolPanelProps {\n\tonClose: () => void;\n\t/** Persist the config. A pending promise shows the Save loader. */\n\tonSave: (config: RestApiToolConfig) => void | Promise<void>;\n\t/** Seed values when editing an existing tool. */\n\tinitial?: RestApiToolConfig;\n\t/** Optional \"Improve with AI\" for the instructions field. Omit to hide it. */\n\tonImprove?: (text: string) => Promise<string>;\n\tcharLimits?: AgentCharLimits;\n\t/** SideModal stacking order — raise it when opened over another drawer. */\n\tzIndex?: number;\n\t/** Names of the OTHER tools — a new tool can't reuse one of these. */\n\texistingNames?: string[];\n}\n\nconst METHODS: RestApiMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];\nconst METHOD_OPTIONS: SingleOption[] = METHODS.map((m) => ({\n\tlabel: m,\n\tvalue: m,\n}));\n\n// A callable endpoint needs an explicit http(s):// scheme AND a real, dotted\n// host. `new URL` alone is too lenient — it accepts single-label hosts\n// (\"https://abc\"), a one-slash scheme (\"https:/abc.com\"), and dangling-dot\n// hosts (\"https://.com\" / \"https://abc.\"). Require the `://` prefix on the raw\n// value plus a hostname that is either dotted (example.com) or an IPv4.\nconst isValidHttpUrl = (value: string): boolean => {\n\tif (!/^https?:\\/\\//i.test(value)) {\n\t\treturn false;\n\t}\n\tlet host: string;\n\ttry {\n\t\thost = new URL(value).hostname;\n\t} catch {\n\t\treturn false;\n\t}\n\treturn host.includes('.') && !host.startsWith('.') && !host.endsWith('.');\n};\n\n/**\n * Right-side drawer to configure a \"Rest API\" tool: the endpoint the agent can\n * call, plus a JSON request-body template and a sample response. Mount it fresh\n * per open (key it) so `initial` seeds the state. Built on the shared `SideModal`\n * shell and the BikEditor JSON body mode for the Request / Response editors.\n */\nexport const RestApiToolPanel: React.FC<RestApiToolPanelProps> = ({\n\tonClose,\n\tonSave,\n\tinitial,\n\tonImprove,\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tzIndex,\n\texistingNames = [],\n}) => {\n\tconst [name, setName] = useState(initial?.name ?? '');\n\tconst [instructions, setInstructions] = useState(initial?.instructions ?? '');\n\t// New tools start with the scheme pre-filled so the user only types the host.\n\tconst [url, setUrl] = useState(initial?.url ?? 'https://');\n\tconst [method, setMethod] = useState<RestApiMethod>(\n\t\tinitial?.method ?? 'POST',\n\t);\n\tconst [headers, setHeaders] = useState<RestApiHeader[]>(\n\t\tinitial?.headers ?? [{ key: '', value: '' }],\n\t);\n\tconst [requestBody, setRequestBody] = useState(initial?.requestBody ?? '');\n\tconst [responseSample, setResponseSample] = useState(\n\t\tinitial?.responseSample ?? '',\n\t);\n\tconst [saving, setSaving] = useState(false);\n\n\tconst patchHeader = (i: number, patch: Partial<RestApiHeader>) =>\n\t\tsetHeaders((prev) =>\n\t\t\tprev.map((h, idx) => (idx === i ? { ...h, ...patch } : h)),\n\t\t);\n\tconst addHeader = () =>\n\t\tsetHeaders((prev) => [...prev, { key: '', value: '' }]);\n\tconst removeHeader = (i: number) =>\n\t\tsetHeaders((prev) => prev.filter((_, idx) => idx !== i));\n\n\tconst nameTrimmed = name.trim();\n\t// Case-insensitive: two tools can't share a name (the LLM references them by it).\n\tconst isDuplicateName =\n\t\tnameTrimmed.length > 0 &&\n\t\texistingNames.some(\n\t\t\t(n) => n.trim().toLowerCase() === nameTrimmed.toLowerCase(),\n\t\t);\n\tconst urlTrimmed = url.trim();\n\t// Save needs a real endpoint, but don't flash the error while the field still\n\t// holds its pristine \"https://\" seed — only once the user has typed past it.\n\tconst isUrlInvalid =\n\t\turlTrimmed.length > 0 &&\n\t\turlTrimmed !== 'https://' &&\n\t\t!isValidHttpUrl(urlTrimmed);\n\tconst canSave =\n\t\tnameTrimmed.length > 0 && isValidHttpUrl(urlTrimmed) && !isDuplicateName;\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst config: RestApiToolConfig = {\n\t\t\tid: initial?.id ?? `restapi_${Date.now().toString(36)}`,\n\t\t\tname: name.trim(),\n\t\t\tinstructions,\n\t\t\turl: url.trim(),\n\t\t\tmethod,\n\t\t\t// Drop fully-empty header rows.\n\t\t\theaders: headers.filter((h) => h.key.trim() || h.value.trim()),\n\t\t\trequestBody,\n\t\t\tresponseSample,\n\t\t};\n\t\tconst result = onSave(config);\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetSaving(true);\n\t\t\ttry {\n\t\t\t\tawait result;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t}\n\t};\n\n\treturn (\n\t\t<SideModal\n\t\t\theader=\"Rest API\"\n\t\t\tcloseOnEscapeKey={false}\n\t\t\tzIndex={zIndex}\n\t\t\theaderCustomComponent={\n\t\t\t\t<DrawerHeaderText\n\t\t\t\t\ttitle=\"Rest API\"\n\t\t\t\t\tsubtitle=\"Connect to any API endpoint. Define the request and a sample response for the agent to reference.\"\n\t\t\t\t/>\n\t\t\t}\n\t\t\twidth=\"431px\"\n\t\t\theaderStyle={DRAWER_HEADER_STYLE}\n\t\t\tbodyStyle={DRAWER_BODY_STYLE}\n\t\t\tonClose={onClose}\n\t\t\tsaveButtonProps={{\n\t\t\t\t'data-test': 'restapi-save',\n\t\t\t\tbuttonText: 'Save',\n\t\t\t\tbuttonType: 'primary',\n\t\t\t\tsize: 'small',\n\t\t\t\tdisabled: !canSave,\n\t\t\t\tisLoading: saving,\n\t\t\t\tonClick: handleSave,\n\t\t\t}}\n\t\t\tcancelButtonProps={{\n\t\t\t\t'data-test': 'restapi-cancel',\n\t\t\t\tbuttonText: 'Cancel',\n\t\t\t\tbuttonType: 'tertiaryGray',\n\t\t\t\tsize: 'small',\n\t\t\t\tonClick: onClose,\n\t\t\t}}\n\t\t>\n\t\t\t<Input\n\t\t\t\tdata-test=\"restapi-name\"\n\t\t\t\tvariant=\"small\"\n\t\t\t\tlabelText=\"Name\"\n\t\t\t\tlabelTextBold\n\t\t\t\tplaceholder=\"Enter action name\"\n\t\t\t\tvalue={name}\n\t\t\t\tmaxCharLimit={charLimits.name}\n\t\t\t\tstate={isDuplicateName ? 'invalid' : undefined}\n\t\t\t\terrorMessage={\n\t\t\t\t\tisDuplicateName ? 'A tool with this name already exists' : undefined\n\t\t\t\t}\n\t\t\t\tonChangeText={setName}\n\t\t\t/>\n\n\t\t\t<ToolInstructionsField\n\t\t\t\tdata-test=\"restapi-instructions\"\n\t\t\t\tlabel=\"Instructions\"\n\t\t\t\tvalue={instructions}\n\t\t\t\tonChange={setInstructions}\n\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\tplaceholder=\"Describe how should the LLM generate the rest API\"\n\t\t\t\tonImprove={onImprove}\n\t\t\t/>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<Input\n\t\t\t\t\tdata-test=\"restapi-url\"\n\t\t\t\t\tvariant=\"small\"\n\t\t\t\t\tlabelText=\"Request URL\"\n\t\t\t\t\tlabelTextBold\n\t\t\t\t\tplaceholder=\"https://\"\n\t\t\t\t\ttype=\"url\"\n\t\t\t\t\tvalue={url}\n\t\t\t\t\tstate={isUrlInvalid ? 'invalid' : undefined}\n\t\t\t\t\terrorMessage={\n\t\t\t\t\t\tisUrlInvalid ? 'Enter a valid URL (including https://)' : undefined\n\t\t\t\t\t}\n\t\t\t\t\tonChangeText={setUrl}\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>HTTP method</TitleSmall>\n\t\t\t\t<Dropdown\n\t\t\t\t\tdata-test=\"restapi-method\"\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\tdropdownWidth=\"399px\"\n\t\t\t\t\toptions={METHOD_OPTIONS}\n\t\t\t\t\tdefaultOptions={[{ label: method, value: method }]}\n\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\tsetMethod(v as RestApiMethod);\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Headers</TitleSmall>\n\t\t\t\t{headers.map((h, i) => (\n\t\t\t\t\t// eslint-disable-next-line react/no-array-index-key\n\t\t\t\t\t<HeaderRow key={i} data-test={`restapi-header-${i}`}>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tvariant=\"small\"\n\t\t\t\t\t\t\thideInputHeader\n\t\t\t\t\t\t\tplaceholder=\"Enter name\"\n\t\t\t\t\t\t\tvalue={h.key}\n\t\t\t\t\t\t\tonChangeText={(v) => patchHeader(i, { key: v })}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tvariant=\"small\"\n\t\t\t\t\t\t\thideInputHeader\n\t\t\t\t\t\t\tplaceholder=\"Enter value\"\n\t\t\t\t\t\t\tvalue={h.value}\n\t\t\t\t\t\t\tonChangeText={(v) => patchHeader(i, { value: v })}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<IconBtn\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-label=\"Remove header\"\n\t\t\t\t\t\t\tdata-test={`restapi-header-remove-${i}`}\n\t\t\t\t\t\t\tonClick={() => removeHeader(i)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<DeleteIcon\n\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</IconBtn>\n\t\t\t\t\t</HeaderRow>\n\t\t\t\t))}\n\t\t\t\t<AddHeaderRow>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tdata-test=\"restapi-add-header\"\n\t\t\t\t\t\tbuttonType=\"dashRegular\"\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\tLeadingIcon={PlusIcon}\n\t\t\t\t\t\tbuttonText=\"Add header\"\n\t\t\t\t\t\tonClick={addHeader}\n\t\t\t\t\t/>\n\t\t\t\t</AddHeaderRow>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Request </TitleSmall>\n\t\t\t\t<BikEditor\n\t\t\t\t\tfeatures={{ jsonMode: true }}\n\t\t\t\t\tinitialContent={requestBody}\n\t\t\t\t\tstyle={JsonFieldBox}\n\t\t\t\t\tplaceholder=\"Type or paste JSON here\"\n\t\t\t\t\tonChange={(c) => setRequestBody(c.text)}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"240px\"\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Response </TitleSmall>\n\t\t\t\t<BikEditor\n\t\t\t\t\tfeatures={{ jsonMode: true }}\n\t\t\t\t\tstyle={JsonFieldBox}\n\t\t\t\t\tinitialContent={responseSample}\n\t\t\t\t\tplaceholder=\"Type or paste JSON here\"\n\t\t\t\t\tonChange={(c) => setResponseSample(c.text)}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"240px\"\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\t\t</SideModal>\n\t);\n};\n\nconst HeaderRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n`;\n\nconst AddHeaderRow = styled.div`\n\tdisplay: flex;\n`;\n\nconst IconBtn = styled.button`\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-shrink: 0;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbackground: ${COLORS.surface.standard};\n\tcursor: pointer;\n\n\t&:hover {\n\t\tborder-color: ${COLORS.content.secondary};\n\t}\n`;\n\nexport const JsonFieldBox = {\n\tborderRadius: '4px',\n\toverflow: 'hidden',\n};\n"],"names":["METHODS","METHOD_OPTIONS","m","isValidHttpUrl","value","host","RestApiToolPanel","onClose","onSave","initial","onImprove","charLimits","AGENT_CHAR_LIMITS","zIndex","existingNames","name","setName","useState","instructions","setInstructions","url","setUrl","method","setMethod","headers","setHeaders","requestBody","setRequestBody","responseSample","setResponseSample","saving","setSaving","patchHeader","i","patch","prev","h","idx","addHeader","removeHeader","_","nameTrimmed","isDuplicateName","n","urlTrimmed","isUrlInvalid","canSave","handleSave","config","result","jsxs","SideModal","jsx","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","Input","ToolInstructionsField","FieldBlock","TitleSmall","COLORS","Dropdown","opt","v","unwrapDropdownValue","HeaderRow","IconBtn","DeleteIcon","AddHeaderRow","Button","PlusIcon","BikEditor","JsonFieldBox","c","styled"],"mappings":"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"}
1
+ {"version":3,"file":"RestApiToolPanel.js","sources":["../../../../../src/components/agent-builder/components/RestApiToolPanel.tsx"],"sourcesContent":["import DeleteIcon from '@src/assets/icons/delete.svg';\nimport PlusIcon from '@src/assets/icons/plus.svg';\nimport { BikEditor } from '@src/editor';\nimport React, { useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { Dropdown, unwrapDropdownValue } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { Input } from '@src/components/input';\nimport { SideModal } from '@src/components/side-modal';\nimport { BodyCaption, TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport type { VariableListInterfaceV3 } from '../../variable-picker-v3/model';\nimport {\n\tRestApiHeader,\n\tRestApiMethod,\n\tRestApiToolConfig,\n} from '../AgentBuilder.model';\nimport { FieldBlock } from '../AgentBuilder.styled';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport {\n\tDRAWER_BODY_STYLE,\n\tDRAWER_HEADER_STYLE,\n\tDrawerHeaderText,\n} from './DrawerHeaderText';\nimport { ToolInstructionsField } from './ToolInstructionsField';\nimport { VariableInlineField } from './VariableInlineField';\n\ninterface RestApiToolPanelProps {\n\tonClose: () => void;\n\t/** Persist the config. A pending promise shows the Save loader. */\n\tonSave: (config: RestApiToolConfig) => void | Promise<void>;\n\t/** Seed values when editing an existing tool. */\n\tinitial?: RestApiToolConfig;\n\t/** Optional \"Improve with AI\" for the instructions field. Omit to hide it. */\n\tonImprove?: (text: string) => Promise<string>;\n\tcharLimits?: AgentCharLimits;\n\t/** SideModal stacking order — raise it when opened over another drawer. */\n\tzIndex?: number;\n\t/** Names of the OTHER tools — a new tool can't reuse one of these. */\n\texistingNames?: string[];\n\t/**\n\t * Variable catalog for the `@` trigger. When non-empty, `@` opens the\n\t * variable picker directly in Instructions / Request URL / header values.\n\t * (Request / Response JSON editors are deliberately not wired for now.)\n\t * Absent → the drawer behaves exactly as before.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\n}\n\nconst METHODS: RestApiMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];\nconst METHOD_OPTIONS: SingleOption[] = METHODS.map((m) => ({\n\tlabel: m,\n\tvalue: m,\n}));\n\n// A callable endpoint needs an explicit http(s):// scheme AND a real, dotted\n// host. `new URL` alone is too lenient — it accepts single-label hosts\n// (\"https://abc\"), a one-slash scheme (\"https:/abc.com\"), and dangling-dot\n// hosts (\"https://.com\" / \"https://abc.\"). Require the `://` prefix on the raw\n// value plus a hostname that is either dotted (example.com) or an IPv4.\nconst isValidHttpUrl = (value: string): boolean => {\n\tif (!/^https?:\\/\\//i.test(value)) {\n\t\treturn false;\n\t}\n\tlet host: string;\n\ttry {\n\t\thost = new URL(value).hostname;\n\t} catch {\n\t\treturn false;\n\t}\n\treturn host.includes('.') && !host.startsWith('.') && !host.endsWith('.');\n};\n\n/**\n * Right-side drawer to configure a \"Rest API\" tool: the endpoint the agent can\n * call, plus a JSON request-body template and a sample response. Mount it fresh\n * per open (key it) so `initial` seeds the state. Built on the shared `SideModal`\n * shell and the BikEditor JSON body mode for the Request / Response editors.\n */\nexport const RestApiToolPanel: React.FC<RestApiToolPanelProps> = ({\n\tonClose,\n\tonSave,\n\tinitial,\n\tonImprove,\n\tcharLimits = AGENT_CHAR_LIMITS,\n\tzIndex,\n\texistingNames = [],\n\tvariablesData,\n}) => {\n\tconst [name, setName] = useState(initial?.name ?? '');\n\tconst [instructions, setInstructions] = useState(initial?.instructions ?? '');\n\t// New tools start with the scheme pre-filled so the user only types the host.\n\tconst [url, setUrl] = useState(initial?.url ?? 'https://');\n\tconst [method, setMethod] = useState<RestApiMethod>(\n\t\tinitial?.method ?? 'POST',\n\t);\n\tconst [headers, setHeaders] = useState<RestApiHeader[]>(\n\t\tinitial?.headers ?? [{ key: '', value: '' }],\n\t);\n\tconst [requestBody, setRequestBody] = useState(initial?.requestBody ?? '');\n\tconst [responseSample, setResponseSample] = useState(\n\t\tinitial?.responseSample ?? '',\n\t);\n\tconst [saving, setSaving] = useState(false);\n\n\t// Stable per-row identity for React keys, parallel to `headers`. The value\n\t// field is an uncontrolled editor, so a row must keep its mount across\n\t// sibling add/remove — index-based keys would remount every row (dropping\n\t// focus mid-edit) or let a deleted row's text linger in a reused neighbour.\n\tconst headerIdsRef = useRef<number[]>(\n\t\t(initial?.headers ?? [{ key: '', value: '' }]).map(\n\t\t\t(_h: RestApiHeader, i: number) => i,\n\t\t),\n\t);\n\tconst nextHeaderIdRef = useRef(headerIdsRef.current.length);\n\n\tconst patchHeader = (i: number, patch: Partial<RestApiHeader>) =>\n\t\tsetHeaders((prev) =>\n\t\t\tprev.map((h, idx) => (idx === i ? { ...h, ...patch } : h)),\n\t\t);\n\tconst addHeader = () => {\n\t\theaderIdsRef.current = [...headerIdsRef.current, nextHeaderIdRef.current];\n\t\tnextHeaderIdRef.current += 1;\n\t\tsetHeaders((prev) => [...prev, { key: '', value: '' }]);\n\t};\n\tconst removeHeader = (i: number) => {\n\t\theaderIdsRef.current = headerIdsRef.current.filter((_, idx) => idx !== i);\n\t\tsetHeaders((prev) => prev.filter((_, idx) => idx !== i));\n\t};\n\n\tconst nameTrimmed = name.trim();\n\t// Case-insensitive: two tools can't share a name (the LLM references them by it).\n\tconst isDuplicateName =\n\t\tnameTrimmed.length > 0 &&\n\t\texistingNames.some(\n\t\t\t(n) => n.trim().toLowerCase() === nameTrimmed.toLowerCase(),\n\t\t);\n\tconst urlTrimmed = url.trim();\n\t// Save needs a real endpoint, but don't flash the error while the field still\n\t// holds its pristine \"https://\" seed — only once the user has typed past it.\n\t// A URL that interpolates variables can't be parsed literally (braces are\n\t// invalid URL characters) — accept it once a scheme + something follows;\n\t// it only becomes a concrete URL after runtime substitution.\n\tconst urlUsesVariables = urlTrimmed.includes('{{variable:');\n\tconst urlOk = urlUsesVariables\n\t\t? /^https?:\\/\\/./.test(urlTrimmed)\n\t\t: isValidHttpUrl(urlTrimmed);\n\tconst isUrlInvalid =\n\t\turlTrimmed.length > 0 && urlTrimmed !== 'https://' && !urlOk;\n\tconst canSave =\n\t\tnameTrimmed.length > 0 &&\n\t\turlOk &&\n\t\t!isDuplicateName &&\n\t\t// The editor's characterLimit is soft (a paste may exceed it, rendered\n\t\t// grey) — gate the save so over-limit instructions can't be persisted.\n\t\tinstructions.length <= charLimits.instructions;\n\n\tconst handleSave = async () => {\n\t\tif (!canSave || saving) {\n\t\t\treturn;\n\t\t}\n\t\tconst config: RestApiToolConfig = {\n\t\t\tid: initial?.id ?? `restapi_${Date.now().toString(36)}`,\n\t\t\tname: name.trim(),\n\t\t\tinstructions,\n\t\t\turl: url.trim(),\n\t\t\tmethod,\n\t\t\t// Drop fully-empty header rows.\n\t\t\theaders: headers.filter((h) => h.key.trim() || h.value.trim()),\n\t\t\trequestBody,\n\t\t\tresponseSample,\n\t\t};\n\t\tconst result = onSave(config);\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetSaving(true);\n\t\t\ttry {\n\t\t\t\tawait result;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t}\n\t};\n\n\treturn (\n\t\t<SideModal\n\t\t\theader=\"Rest API\"\n\t\t\tcloseOnEscapeKey={false}\n\t\t\tzIndex={zIndex}\n\t\t\theaderCustomComponent={\n\t\t\t\t<DrawerHeaderText\n\t\t\t\t\ttitle=\"Rest API\"\n\t\t\t\t\tsubtitle=\"Connect to any API endpoint. Define the request and a sample response for the agent to reference.\"\n\t\t\t\t/>\n\t\t\t}\n\t\t\twidth=\"431px\"\n\t\t\theaderStyle={DRAWER_HEADER_STYLE}\n\t\t\tbodyStyle={DRAWER_BODY_STYLE}\n\t\t\tonClose={onClose}\n\t\t\tsaveButtonProps={{\n\t\t\t\t'data-test': 'restapi-save',\n\t\t\t\tbuttonText: 'Save',\n\t\t\t\tbuttonType: 'primary',\n\t\t\t\tsize: 'small',\n\t\t\t\tdisabled: !canSave,\n\t\t\t\tisLoading: saving,\n\t\t\t\tonClick: handleSave,\n\t\t\t}}\n\t\t\tcancelButtonProps={{\n\t\t\t\t'data-test': 'restapi-cancel',\n\t\t\t\tbuttonText: 'Cancel',\n\t\t\t\tbuttonType: 'tertiaryGray',\n\t\t\t\tsize: 'small',\n\t\t\t\tonClick: onClose,\n\t\t\t}}\n\t\t>\n\t\t\t<Input\n\t\t\t\tdata-test=\"restapi-name\"\n\t\t\t\tvariant=\"small\"\n\t\t\t\tlabelText=\"Name\"\n\t\t\t\tlabelTextBold\n\t\t\t\tplaceholder=\"Enter action name\"\n\t\t\t\tvalue={name}\n\t\t\t\tmaxCharLimit={charLimits.name}\n\t\t\t\tstate={isDuplicateName ? 'invalid' : undefined}\n\t\t\t\terrorMessage={\n\t\t\t\t\tisDuplicateName ? 'A tool with this name already exists' : undefined\n\t\t\t\t}\n\t\t\t\tonChangeText={setName}\n\t\t\t/>\n\n\t\t\t<ToolInstructionsField\n\t\t\t\tdata-test=\"restapi-instructions\"\n\t\t\t\tlabel=\"Instructions\"\n\t\t\t\tvalue={instructions}\n\t\t\t\tonChange={setInstructions}\n\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\tplaceholder=\"Describe how should the LLM generate the rest API\"\n\t\t\t\tonImprove={onImprove}\n\t\t\t\tvariablesData={variablesData}\n\t\t\t/>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<VariableInlineField\n\t\t\t\t\tdata-test=\"restapi-url\"\n\t\t\t\t\tlabel=\"Request URL\"\n\t\t\t\t\tplaceholder=\"https://\"\n\t\t\t\t\tvalue={url}\n\t\t\t\t\tonChange={setUrl}\n\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t/>\n\t\t\t\t{/* VariableInlineField has no invalid state of its own — surface the\n\t\t\t\t URL validation (from main) as a caption below the field. */}\n\t\t\t\t{isUrlInvalid && (\n\t\t\t\t\t<BodyCaption color={COLORS.content.negative}>\n\t\t\t\t\t\tEnter a valid URL (including https://)\n\t\t\t\t\t</BodyCaption>\n\t\t\t\t)}\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>HTTP method</TitleSmall>\n\t\t\t\t<Dropdown\n\t\t\t\t\tdata-test=\"restapi-method\"\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\tdropdownWidth=\"399px\"\n\t\t\t\t\toptions={METHOD_OPTIONS}\n\t\t\t\t\tdefaultOptions={[{ label: method, value: method }]}\n\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\tsetMethod(v as RestApiMethod);\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Headers</TitleSmall>\n\t\t\t\t{headers.map((h, i) => (\n\t\t\t\t\t<HeaderRow\n\t\t\t\t\t\tkey={headerIdsRef.current[i]}\n\t\t\t\t\t\tdata-test={`restapi-header-${i}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tvariant=\"small\"\n\t\t\t\t\t\t\thideInputHeader\n\t\t\t\t\t\t\tplaceholder=\"Enter name\"\n\t\t\t\t\t\t\tvalue={h.key}\n\t\t\t\t\t\t\tonChangeText={(v) => patchHeader(i, { key: v })}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<VariableInlineField\n\t\t\t\t\t\t\tplaceholder=\"Enter value\"\n\t\t\t\t\t\t\tvalue={h.value}\n\t\t\t\t\t\t\tonChange={(v) => patchHeader(i, { value: v })}\n\t\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<IconBtn\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-label=\"Remove header\"\n\t\t\t\t\t\t\tdata-test={`restapi-header-remove-${i}`}\n\t\t\t\t\t\t\tonClick={() => removeHeader(i)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<DeleteIcon\n\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</IconBtn>\n\t\t\t\t\t</HeaderRow>\n\t\t\t\t))}\n\t\t\t\t<AddHeaderRow>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tdata-test=\"restapi-add-header\"\n\t\t\t\t\t\tbuttonType=\"dashRegular\"\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\tLeadingIcon={PlusIcon}\n\t\t\t\t\t\tbuttonText=\"Add header\"\n\t\t\t\t\t\tonClick={addHeader}\n\t\t\t\t\t/>\n\t\t\t\t</AddHeaderRow>\n\t\t\t</FieldBlock>\n\n\t\t\t{/* Variables intentionally NOT wired here (yet) — the JSON editors are\n\t\t\t plain code fields; @ types a literal @. */}\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Request </TitleSmall>\n\t\t\t\t<BikEditor\n\t\t\t\t\tfeatures={{ jsonMode: true }}\n\t\t\t\t\tinitialContent={requestBody}\n\t\t\t\t\tstyle={JsonFieldBox}\n\t\t\t\t\tplaceholder=\"Type or paste JSON here\"\n\t\t\t\t\tonChange={(c) => setRequestBody(c.text)}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"240px\"\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\n\t\t\t<FieldBlock>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>Response </TitleSmall>\n\t\t\t\t<BikEditor\n\t\t\t\t\tfeatures={{ jsonMode: true }}\n\t\t\t\t\tstyle={JsonFieldBox}\n\t\t\t\t\tinitialContent={responseSample}\n\t\t\t\t\tplaceholder=\"Type or paste JSON here\"\n\t\t\t\t\tonChange={(c) => setResponseSample(c.text)}\n\t\t\t\t\tminHeight=\"120px\"\n\t\t\t\t\tmaxHeight=\"240px\"\n\t\t\t\t/>\n\t\t\t</FieldBlock>\n\t\t</SideModal>\n\t);\n};\n\n// Fixed tracks (name / value / delete): minmax(0, …) lets the fields shrink\n// below their content width, so a long value scrolls inside its field and the\n// delete button can never be pushed off the row.\nconst HeaderRow = styled.div`\n\tdisplay: grid;\n\tgrid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) 32px;\n\talign-items: center;\n\tgap: 8px;\n`;\n\nconst AddHeaderRow = styled.div`\n\tdisplay: flex;\n`;\n\nconst IconBtn = styled.button`\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-shrink: 0;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbackground: ${COLORS.surface.standard};\n\tcursor: pointer;\n\n\t&:hover {\n\t\tborder-color: ${COLORS.content.secondary};\n\t}\n`;\n\nexport const JsonFieldBox = {\n\tborderRadius: '4px',\n\toverflow: 'hidden',\n};\n"],"names":["METHODS","METHOD_OPTIONS","m","isValidHttpUrl","value","host","RestApiToolPanel","onClose","onSave","initial","onImprove","charLimits","AGENT_CHAR_LIMITS","zIndex","existingNames","variablesData","name","setName","useState","instructions","setInstructions","url","setUrl","method","setMethod","headers","setHeaders","requestBody","setRequestBody","responseSample","setResponseSample","saving","setSaving","headerIdsRef","useRef","_h","i","nextHeaderIdRef","patchHeader","patch","prev","idx","addHeader","removeHeader","_","nameTrimmed","isDuplicateName","n","urlTrimmed","urlOk","isUrlInvalid","canSave","handleSave","config","h","result","jsxs","SideModal","jsx","DrawerHeaderText","DRAWER_HEADER_STYLE","DRAWER_BODY_STYLE","Input","ToolInstructionsField","FieldBlock","VariableInlineField","BodyCaption","COLORS","TitleSmall","Dropdown","opt","v","unwrapDropdownValue","HeaderRow","IconBtn","DeleteIcon","AddHeaderRow","Button","PlusIcon","BikEditor","JsonFieldBox","c","styled"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),u=require("react"),x=require("styled-components"),h=require("../../TypographyStyle.js"),T=require("../../../constants/Theme.js"),r=require("../AgentBuilder.styled.js"),j=require("../../button/Button.js"),S=require("../../../icons/BIK AI specific/WandSparkles.js"),q=t=>t&&typeof t=="object"&&"default"in t?t:{default:t},I=q(x),b=({label:t,value:s,onChange:i,maxLength:d,placeholder:f,minHeight:p="120px",onImprove:n,...l})=>{const[y,a]=u.useState(!1),[o,c]=u.useState(!1),m=async()=>{if(!(!n||o||s.trim().length===0)){c(!0);try{i(await n(s))}finally{c(!1)}}};return e.jsxs(r.FieldBlock,{children:[e.jsx(h.TitleSmall,{color:T.COLORS.content.primary,children:t}),e.jsxs(r.AiTextAreaShell,{focused:y,minHeight:p,children:[e.jsx(r.AiTextAreaInput,{"data-test":l["data-test"],value:s,placeholder:f,maxLength:d,onFocus:()=>a(!0),onBlur:()=>a(!1),onChange:g=>i(g.target.value)}),n&&e.jsx(A,{children:e.jsx(j.Button,{"data-test":`${l["data-test"]??"tool"}-improve`,buttonType:"ai",size:"small",LeadingIcon:S.default,buttonText:"Improve with AI",isLoading:o,disabled:o||s.trim().length===0,onClick:m})})]})]})},A=I.default.div`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),l=require("react"),q=require("styled-components"),I=require("../../TypographyStyle.js"),A=require("../../../constants/Theme.js"),c=require("../AgentBuilder.styled.js"),B=require("./MentionEditor.js"),b=require("../../button/Button.js"),v=require("../../../icons/BIK AI specific/WandSparkles.js"),E=t=>t&&typeof t=="object"&&"default"in t?t:{default:t},F=E(q),w=({label:t,value:o,onChange:s,maxLength:d,placeholder:u,minHeight:p="120px",onImprove:i,variablesData:f,...n})=>{const[g,m]=l.useState(!1),[r,y]=l.useState(!1),[j,S]=l.useState(0),x=(f?.length??0)>0,T=async()=>{if(!(!i||r||o.trim().length===0)){y(!0);try{s(await i(o)),x&&S(a=>a+1)}finally{y(!1)}}},h=i?e.jsx(R,{children:e.jsx(b.Button,{"data-test":`${n["data-test"]??"tool"}-improve`,buttonType:"ai",size:"small",LeadingIcon:v.default,buttonText:"Improve with AI",isLoading:r,disabled:r||o.trim().length===0,onClick:T})}):void 0;return x?e.jsx(B.MentionEditor,{"data-test":n["data-test"],label:t,value:o,onChange:s,maxLength:d,placeholder:u,minHeight:p,resetKey:`improve-${j}`,mentionItems:[],tools:[],variablesData:f,addDataButton:!0,action:h}):e.jsxs(c.FieldBlock,{children:[e.jsx(I.TitleSmall,{color:A.COLORS.content.primary,children:t}),e.jsxs(c.AiTextAreaShell,{focused:g,minHeight:p,children:[e.jsx(c.AiTextAreaInput,{"data-test":n["data-test"],value:o,placeholder:u,maxLength:d,onFocus:()=>m(!0),onBlur:()=>m(!1),onChange:a=>s(a.target.value)}),h]})]})},R=F.default.div`
2
2
  display: flex;
3
3
  align-items: center;
4
- `;exports.ToolInstructionsField=b;
4
+ `;exports.ToolInstructionsField=w;
5
5
  //# sourceMappingURL=ToolInstructionsField.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolInstructionsField.js","sources":["../../../../../src/components/agent-builder/components/ToolInstructionsField.tsx"],"sourcesContent":["import { WandSparkles } from '@src/icons';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tAiTextAreaInput,\n\tAiTextAreaShell,\n\tFieldBlock,\n} from '../AgentBuilder.styled';\n\ninterface ToolInstructionsFieldProps {\n\tlabel: string;\n\tvalue: string;\n\tonChange: (value: string) => void;\n\tmaxLength: number;\n\tplaceholder?: string;\n\tminHeight?: string;\n\t/** \"Improve with AI\" — resolves with rewritten text. Omit to hide the button. */\n\tonImprove?: (text: string) => Promise<string>;\n\t'data-test'?: string;\n}\n\n/**\n * A labelled multiline field with an inline \"Improve with AI\" action pinned to\n * the bottom-left of the box (Figma: Rest API / Handover-to-email drawers). The\n * button is hidden when `onImprove` is omitted.\n */\nexport const ToolInstructionsField: React.FC<ToolInstructionsFieldProps> = ({\n\tlabel,\n\tvalue,\n\tonChange,\n\tmaxLength,\n\tplaceholder,\n\tminHeight = '120px',\n\tonImprove,\n\t...rest\n}) => {\n\tconst [focused, setFocused] = useState(false);\n\tconst [improving, setImproving] = useState(false);\n\n\tconst handleImprove = async () => {\n\t\tif (!onImprove || improving || value.trim().length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tsetImproving(true);\n\t\ttry {\n\t\t\tonChange(await onImprove(value));\n\t\t} finally {\n\t\t\tsetImproving(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<FieldBlock>\n\t\t\t<TitleSmall color={COLORS.content.primary}>{label}</TitleSmall>\n\t\t\t<AiTextAreaShell focused={focused} minHeight={minHeight}>\n\t\t\t\t<AiTextAreaInput\n\t\t\t\t\tdata-test={rest['data-test']}\n\t\t\t\t\tvalue={value}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tmaxLength={maxLength}\n\t\t\t\t\tonFocus={() => setFocused(true)}\n\t\t\t\t\tonBlur={() => setFocused(false)}\n\t\t\t\t\tonChange={(e) => onChange(e.target.value)}\n\t\t\t\t/>\n\t\t\t\t{onImprove && (\n\t\t\t\t\t<ImproveRow>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tdata-test={`${rest['data-test'] ?? 'tool'}-improve`}\n\t\t\t\t\t\t\tbuttonType=\"ai\"\n\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\tLeadingIcon={WandSparkles}\n\t\t\t\t\t\t\tbuttonText=\"Improve with AI\"\n\t\t\t\t\t\t\tisLoading={improving}\n\t\t\t\t\t\t\tdisabled={improving || value.trim().length === 0}\n\t\t\t\t\t\t\tonClick={handleImprove}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ImproveRow>\n\t\t\t\t)}\n\t\t\t</AiTextAreaShell>\n\t\t</FieldBlock>\n\t);\n};\n\nconst ImproveRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n`;\n"],"names":["ToolInstructionsField","label","value","onChange","maxLength","placeholder","minHeight","onImprove","rest","focused","setFocused","useState","improving","setImproving","handleImprove","FieldBlock","jsx","TitleSmall","COLORS","jsxs","AiTextAreaShell","AiTextAreaInput","e","ImproveRow","Button","WandSparkles","styled"],"mappings":"4bA6BaA,EAA8D,CAAC,CAC3E,MAAAC,EACA,MAAAC,EACA,SAAAC,EACA,UAAAC,EACA,YAAAC,EACA,UAAAC,EAAY,QACZ,UAAAC,EACA,GAAGC,CACJ,IAAM,CACL,KAAM,CAACC,EAASC,CAAU,EAAIC,EAAAA,SAAS,EAAK,EACtC,CAACC,EAAWC,CAAY,EAAIF,EAAAA,SAAS,EAAK,EAE1CG,EAAgB,SAAY,CACjC,GAAI,GAACP,GAAaK,GAAaV,EAAM,KAAA,EAAO,SAAW,GAGvD,CAAAW,EAAa,EAAI,EACjB,GAAI,CACHV,EAAS,MAAMI,EAAUL,CAAK,CAAC,CAChC,QAAA,CACCW,EAAa,EAAK,CACnB,EACD,EAEA,cACEE,aAAA,CACA,SAAA,CAAAC,MAACC,EAAAA,WAAA,CAAW,MAAOC,EAAAA,OAAO,QAAQ,QAAU,SAAAjB,EAAM,EAClDkB,EAAAA,KAACC,EAAAA,gBAAA,CAAgB,QAAAX,EAAkB,UAAAH,EAClC,SAAA,CAAAU,EAAAA,IAACK,EAAAA,gBAAA,CACA,YAAWb,EAAK,WAAW,EAC3B,MAAAN,EACA,YAAAG,EACA,UAAAD,EACA,QAAS,IAAMM,EAAW,EAAI,EAC9B,OAAQ,IAAMA,EAAW,EAAK,EAC9B,SAAWY,GAAMnB,EAASmB,EAAE,OAAO,KAAK,CAAA,CAAA,EAExCf,SACCgB,EAAA,CACA,SAAAP,EAAAA,IAACQ,EAAAA,OAAA,CACA,YAAW,GAAGhB,EAAK,WAAW,GAAK,MAAM,WACzC,WAAW,KACX,KAAK,QACL,YAAaiB,EAAAA,QACb,WAAW,kBACX,UAAWb,EACX,SAAUA,GAAaV,EAAM,KAAA,EAAO,SAAW,EAC/C,QAASY,CAAA,CAAA,CACV,CACD,CAAA,CAAA,CAEF,CAAA,EACD,CAEF,EAEMS,EAAaG,EAAAA,QAAO;AAAA;AAAA;AAAA"}
1
+ {"version":3,"file":"ToolInstructionsField.js","sources":["../../../../../src/components/agent-builder/components/ToolInstructionsField.tsx"],"sourcesContent":["import { WandSparkles } from '@src/icons';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport type { VariableListInterfaceV3 } from '../../variable-picker-v3/model';\nimport {\n\tAiTextAreaInput,\n\tAiTextAreaShell,\n\tFieldBlock,\n} from '../AgentBuilder.styled';\nimport { MentionEditor } from './MentionEditor';\n\ninterface ToolInstructionsFieldProps {\n\tlabel: string;\n\tvalue: string;\n\tonChange: (value: string) => void;\n\tmaxLength: number;\n\tplaceholder?: string;\n\tminHeight?: string;\n\t/** \"Improve with AI\" — resolves with rewritten text. Omit to hide the button. */\n\tonImprove?: (text: string) => Promise<string>;\n\t/**\n\t * Variable catalog. When non-empty the field upgrades from a plain textarea\n\t * to a variables-only `@` mention editor: typing `@` opens the variable\n\t * categories directly (Variables is the sole category, so the picker skips\n\t * the Tools / Sub-agent root), and picks render as chips persisted as\n\t * `{{variable:<name>}}` tokens.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\n\t'data-test'?: string;\n}\n\n/**\n * A labelled multiline field with an inline \"Improve with AI\" action pinned to\n * the bottom-left of the box (Figma: Rest API / Handover-to-email drawers). The\n * button is hidden when `onImprove` is omitted.\n */\nexport const ToolInstructionsField: React.FC<ToolInstructionsFieldProps> = ({\n\tlabel,\n\tvalue,\n\tonChange,\n\tmaxLength,\n\tplaceholder,\n\tminHeight = '120px',\n\tonImprove,\n\tvariablesData,\n\t...rest\n}) => {\n\tconst [focused, setFocused] = useState(false);\n\tconst [improving, setImproving] = useState(false);\n\t// Bumped when \"Improve with AI\" replaces the text externally — the mention\n\t// editor only reads `value` on (re)mount, so it must be remounted.\n\tconst [editorEpoch, setEditorEpoch] = useState(0);\n\n\tconst withVariables = (variablesData?.length ?? 0) > 0;\n\n\tconst handleImprove = async () => {\n\t\tif (!onImprove || improving || value.trim().length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tsetImproving(true);\n\t\ttry {\n\t\t\tonChange(await onImprove(value));\n\t\t\tif (withVariables) {\n\t\t\t\tsetEditorEpoch((e) => e + 1);\n\t\t\t}\n\t\t} finally {\n\t\t\tsetImproving(false);\n\t\t}\n\t};\n\n\tconst improveAction = onImprove ? (\n\t\t<ImproveRow>\n\t\t\t<Button\n\t\t\t\tdata-test={`${rest['data-test'] ?? 'tool'}-improve`}\n\t\t\t\tbuttonType=\"ai\"\n\t\t\t\tsize=\"small\"\n\t\t\t\tLeadingIcon={WandSparkles}\n\t\t\t\tbuttonText=\"Improve with AI\"\n\t\t\t\tisLoading={improving}\n\t\t\t\tdisabled={improving || value.trim().length === 0}\n\t\t\t\tonClick={handleImprove}\n\t\t\t/>\n\t\t</ImproveRow>\n\t) : undefined;\n\n\t// Variables enabled → the mention-editor variant. `mentionItems` / tool\n\t// hooks stay empty so Variables is the picker's ONLY category and `@` lands\n\t// straight in the variable list.\n\tif (withVariables) {\n\t\treturn (\n\t\t\t<MentionEditor\n\t\t\t\tdata-test={rest['data-test']}\n\t\t\t\tlabel={label}\n\t\t\t\tvalue={value}\n\t\t\t\tonChange={onChange}\n\t\t\t\tmaxLength={maxLength}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tminHeight={minHeight}\n\t\t\t\tresetKey={`improve-${editorEpoch}`}\n\t\t\t\tmentionItems={[]}\n\t\t\t\ttools={[]}\n\t\t\t\tvariablesData={variablesData}\n\t\t\t\t// Drawers get the same focused-field \"+ Add data\" affordance as the\n\t\t\t\t// main Step-3 editors.\n\t\t\t\taddDataButton\n\t\t\t\taction={improveAction}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<FieldBlock>\n\t\t\t<TitleSmall color={COLORS.content.primary}>{label}</TitleSmall>\n\t\t\t<AiTextAreaShell focused={focused} minHeight={minHeight}>\n\t\t\t\t<AiTextAreaInput\n\t\t\t\t\tdata-test={rest['data-test']}\n\t\t\t\t\tvalue={value}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tmaxLength={maxLength}\n\t\t\t\t\tonFocus={() => setFocused(true)}\n\t\t\t\t\tonBlur={() => setFocused(false)}\n\t\t\t\t\tonChange={(e) => onChange(e.target.value)}\n\t\t\t\t/>\n\t\t\t\t{improveAction}\n\t\t\t</AiTextAreaShell>\n\t\t</FieldBlock>\n\t);\n};\n\nconst ImproveRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n`;\n"],"names":["ToolInstructionsField","label","value","onChange","maxLength","placeholder","minHeight","onImprove","variablesData","rest","focused","setFocused","useState","improving","setImproving","editorEpoch","setEditorEpoch","withVariables","handleImprove","e","improveAction","jsx","ImproveRow","Button","WandSparkles","MentionEditor","FieldBlock","TitleSmall","COLORS","jsxs","AiTextAreaShell","AiTextAreaInput","styled"],"mappings":"4dAuCaA,EAA8D,CAAC,CAC3E,MAAAC,EACA,MAAAC,EACA,SAAAC,EACA,UAAAC,EACA,YAAAC,EACA,UAAAC,EAAY,QACZ,UAAAC,EACA,cAAAC,EACA,GAAGC,CACJ,IAAM,CACL,KAAM,CAACC,EAASC,CAAU,EAAIC,EAAAA,SAAS,EAAK,EACtC,CAACC,EAAWC,CAAY,EAAIF,EAAAA,SAAS,EAAK,EAG1C,CAACG,EAAaC,CAAc,EAAIJ,EAAAA,SAAS,CAAC,EAE1CK,GAAiBT,GAAe,QAAU,GAAK,EAE/CU,EAAgB,SAAY,CACjC,GAAI,GAACX,GAAaM,GAAaX,EAAM,KAAA,EAAO,SAAW,GAGvD,CAAAY,EAAa,EAAI,EACjB,GAAI,CACHX,EAAS,MAAMI,EAAUL,CAAK,CAAC,EAC3Be,GACHD,EAAgBG,GAAMA,EAAI,CAAC,CAE7B,QAAA,CACCL,EAAa,EAAK,CACnB,EACD,EAEMM,EAAgBb,EACrBc,EAAAA,IAACC,EAAA,CACA,SAAAD,EAAAA,IAACE,EAAAA,OAAA,CACA,YAAW,GAAGd,EAAK,WAAW,GAAK,MAAM,WACzC,WAAW,KACX,KAAK,QACL,YAAae,EAAAA,QACb,WAAW,kBACX,UAAWX,EACX,SAAUA,GAAaX,EAAM,KAAA,EAAO,SAAW,EAC/C,QAASgB,CAAA,CAAA,EAEX,EACG,OAKJ,OAAID,EAEFI,EAAAA,IAACI,EAAAA,cAAA,CACA,YAAWhB,EAAK,WAAW,EAC3B,MAAAR,EACA,MAAAC,EACA,SAAAC,EACA,UAAAC,EACA,YAAAC,EACA,UAAAC,EACA,SAAU,WAAWS,CAAW,GAChC,aAAc,CAAA,EACd,MAAO,CAAA,EACP,cAAAP,EAGA,cAAa,GACb,OAAQY,CAAA,CAAA,SAMTM,aAAA,CACA,SAAA,CAAAL,MAACM,EAAAA,WAAA,CAAW,MAAOC,EAAAA,OAAO,QAAQ,QAAU,SAAA3B,EAAM,EAClD4B,EAAAA,KAACC,EAAAA,gBAAA,CAAgB,QAAApB,EAAkB,UAAAJ,EAClC,SAAA,CAAAe,EAAAA,IAACU,EAAAA,gBAAA,CACA,YAAWtB,EAAK,WAAW,EAC3B,MAAAP,EACA,YAAAG,EACA,UAAAD,EACA,QAAS,IAAMO,EAAW,EAAI,EAC9B,OAAQ,IAAMA,EAAW,EAAK,EAC9B,SAAWQ,GAAMhB,EAASgB,EAAE,OAAO,KAAK,CAAA,CAAA,EAExCC,CAAA,CAAA,CACF,CAAA,EACD,CAEF,EAEME,EAAaU,EAAAA,QAAO;AAAA;AAAA;AAAA"}
@@ -0,0 +1,65 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),r=require("react"),p=require("styled-components"),x=require("../../TypographyStyle.js"),l=require("../../../constants/Theme.js"),o=require("../utils/mentionSerialization.js"),v=require("./MentionPicker.js"),k=require("./VariableTriggerArea.js"),S=require("../../../editor/BikEditor.js"),C=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},w=C(p),T=e=>o.variableTokenName(e).replace(/^variable:/,""),I=({value:e,onChange:c,label:h,placeholder:m,variablesData:n,...f})=>{const s=r.useRef(null),a=(n?.length??0)>0,u=r.useMemo(()=>o.buildVariableMentionItems(n),[n]),b=r.useMemo(()=>o.instructionsToEditorHtml(e,u),[a]),d=r.useCallback(t=>{s.current?.insertInlineContent(o.buildMentionHtml(t,`{{${t}}}`,"variable"))},[]),g=r.useCallback(t=>d(o.variableTokenName(t.actualValue)),[d]),y=r.useCallback(()=>{const t=s.current?.getJSON()??null;c(o.editorDocToInstructions(t,[]).replace(/\n+/g,""))},[c]);return i.jsxs(M,{children:[h&&i.jsx(x.TitleSmall,{color:l.COLORS.content.primary,children:h}),i.jsx(k.VariableTriggerArea,{variablesData:n,addDataButton:!0,skipNativeBoundaries:!0,onInsert:t=>d(T(t)),children:i.jsx(j,{$atHint:a,"data-test":f["data-test"],children:i.jsx(S.BikEditor,{ref:s,initialContent:b,placeholder:m,minHeight:"20px",maxHeight:"20px",style:{border:"none"},editorStyle:O,onSend:()=>{},sendShortcut:{key:"Enter"},mentions:{agents:u,removeTriggerOnDismiss:!0,renderDropdown:t=>i.jsx(v.MentionPicker,{...t,variablesData:n,onSelectVariable:g})},onChange:y},a?"v1":"v0")})})]})},O={padding:0,fontFamily:"Inter",fontSize:"14px",lineHeight:"20px"},M=w.default.div`
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 4px;
5
+ width: 100%;
6
+ /* In a flex row (header key/value pairs) share the space and allow
7
+ shrinking below content width — long values scroll inside the field
8
+ instead of widening the row / drawer. */
9
+ flex: 1 1 0%;
10
+ min-width: 0;
11
+ `,j=w.default.div`
12
+ /* No global reset in every host — without this, width:100% + padding
13
+ overflows the drawer by the padding + border (the reported overflow). */
14
+ box-sizing: border-box;
15
+ display: flex;
16
+ align-items: center;
17
+ width: 100%;
18
+ min-width: 0;
19
+ overflow: hidden;
20
+ padding: 6px 12px;
21
+ background: ${l.COLORS.surface.standard};
22
+ border: 1px solid ${l.COLORS.stroke.primary};
23
+ border-radius: 4px;
24
+
25
+ /* The editor root is width:100% — cap it so a long value scrolls inside
26
+ the ProseMirror line rather than stretching the shell. */
27
+ > div {
28
+ width: 100%;
29
+ min-width: 0;
30
+ }
31
+
32
+ &:focus-within {
33
+ border-color: ${l.COLORS.stroke.brand};
34
+ }
35
+
36
+ /* While the (empty) field is focused, the placeholder switches to the @
37
+ hint — only when a catalog makes @ do anything; unfocused (or without
38
+ variables) it shows the field's own placeholder. */
39
+ ${e=>e.$atHint&&p.css`
40
+ .ProseMirror.ProseMirror-focused p.is-editor-empty:first-child::before {
41
+ content: 'Enter text, type @ to add variable';
42
+ }
43
+ `}
44
+
45
+ /* Keep the editor to one visual line; long values scroll horizontally the
46
+ way a native input does. */
47
+ .ProseMirror {
48
+ width: 100%;
49
+ max-width: 100%;
50
+ white-space: nowrap;
51
+ overflow-x: auto;
52
+ overflow-y: hidden;
53
+ word-break: normal;
54
+ scrollbar-width: none;
55
+
56
+ &::-webkit-scrollbar {
57
+ display: none;
58
+ }
59
+ }
60
+
61
+ .ProseMirror p {
62
+ display: inline;
63
+ }
64
+ `;exports.VariableInlineField=I;
65
+ //# sourceMappingURL=VariableInlineField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariableInlineField.js","sources":["../../../../../src/components/agent-builder/components/VariableInlineField.tsx"],"sourcesContent":["import { BikEditor, BikEditorRef } from '@src/editor';\nimport React, { useCallback, useMemo, useRef } from 'react';\nimport styled, { css } from 'styled-components';\nimport { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport type {\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport {\n\tbuildMentionHtml,\n\tbuildVariableMentionItems,\n\teditorDocToInstructions,\n\tinstructionsToEditorHtml,\n\tvariableTokenName,\n} from '../utils/mentionSerialization';\nimport { MentionPicker } from './MentionPicker';\nimport { VariableTriggerArea } from './VariableTriggerArea';\n\ninterface VariableInlineFieldProps {\n\t/** Stored string, `{{variable:<name>}}` tokens inline (e.g. a URL). */\n\tvalue: string;\n\tonChange: (text: string) => void;\n\tlabel?: string;\n\tplaceholder?: string;\n\t/** Variable catalog. Absent / empty → behaves as a plain single-line input. */\n\tvariablesData?: VariableListInterfaceV3[];\n\t'data-test'?: string;\n}\n\n/** `{{variable:a.b}}` / `{{a.b}}` → `a.b`. */\nconst nameOf = (token: string): string =>\n\tvariableTokenName(token).replace(/^variable:/, '');\n\n/**\n * Single-line text field whose `{{variable:<name>}}` tokens render as the\n * SAME purple `{{<name>}}` chips as the Instructions / Guardrails editors —\n * BikEditor under the hood, styled like the small `Input`. Used for tool\n * params that mix free text with variables (Request URL, header values).\n *\n * `@` opens the variable panel: after whitespace / at the start via the\n * editor's native mention trigger, after URL/JSON delimiters (`https://@`)\n * via the {@link VariableTriggerArea} wrapper — both render the same\n * {@link MentionPicker}. Enter is swallowed (single-line), and any pasted\n * newlines are dropped on serialize.\n */\nexport const VariableInlineField: React.FC<VariableInlineFieldProps> = ({\n\tvalue,\n\tonChange,\n\tlabel,\n\tplaceholder,\n\tvariablesData,\n\t...rest\n}) => {\n\tconst editorRef = useRef<BikEditorRef>(null);\n\n\tconst hasVariables = (variablesData?.length ?? 0) > 0;\n\tconst mentionItems = useMemo(\n\t\t() => buildVariableMentionItems(variablesData),\n\t\t[variablesData],\n\t);\n\n\t// Initial HTML — the field is uncontrolled after mount (the drawers key\n\t// their fields per open), EXCEPT when the variable catalog first arrives\n\t// (async fetch): the editor re-mounts (keyed below) so stored\n\t// `{{variable:…}}` tokens become chips instead of staying literal text.\n\t// `value` is kept current by onChange, so the re-seed loses nothing.\n\tconst initialHtml = useMemo(\n\t\t() => instructionsToEditorHtml(value, mentionItems),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[hasVariables],\n\t);\n\n\t// Insert the purple `{{<name>}}` chip; serialization emits the stored\n\t// `{{variable:<name>}}` token (same path as the instructions editors).\n\t// Single construction site for BOTH trigger paths (native `@` suggestion\n\t// and the VariableTriggerArea wrapper) so the chip flavor can't diverge.\n\tconst insertChipByName = useCallback((name: string) => {\n\t\teditorRef.current?.insertInlineContent(\n\t\t\tbuildMentionHtml(name, `{{${name}}}`, 'variable'),\n\t\t);\n\t}, []);\n\tconst insertChip = useCallback(\n\t\t(variable: VariableV3) =>\n\t\t\tinsertChipByName(variableTokenName(variable.actualValue)),\n\t\t[insertChipByName],\n\t);\n\n\tconst emitChange = useCallback(() => {\n\t\tconst doc = editorRef.current?.getJSON() ?? null;\n\t\t// Single-line: pasted newlines have no meaning in a URL / header value.\n\t\tonChange(editorDocToInstructions(doc, []).replace(/\\n+/g, ''));\n\t}, [onChange]);\n\n\treturn (\n\t\t<FieldBlockCol>\n\t\t\t{label && <TitleSmall color={COLORS.content.primary}>{label}</TitleSmall>}\n\t\t\t<VariableTriggerArea\n\t\t\t\tvariablesData={variablesData}\n\t\t\t\taddDataButton\n\t\t\t\tskipNativeBoundaries\n\t\t\t\tonInsert={(token) => insertChipByName(nameOf(token))}\n\t\t\t>\n\t\t\t\t<InputShell $atHint={hasVariables} data-test={rest['data-test']}>\n\t\t\t\t\t<BikEditor\n\t\t\t\t\t\tkey={hasVariables ? 'v1' : 'v0'}\n\t\t\t\t\t\tref={editorRef}\n\t\t\t\t\t\tinitialContent={initialHtml}\n\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\tminHeight=\"20px\"\n\t\t\t\t\t\tmaxHeight=\"20px\"\n\t\t\t\t\t\tstyle={{ border: 'none' }}\n\t\t\t\t\t\teditorStyle={INLINE_EDITOR_STYLE}\n\t\t\t\t\t\t// Single-line: Enter is a no-op \"send\".\n\t\t\t\t\t\tonSend={() => undefined}\n\t\t\t\t\t\tsendShortcut={{ key: 'Enter' }}\n\t\t\t\t\t\tmentions={{\n\t\t\t\t\t\t\tagents: mentionItems,\n\t\t\t\t\t\t\tremoveTriggerOnDismiss: true,\n\t\t\t\t\t\t\trenderDropdown: (props) => (\n\t\t\t\t\t\t\t\t<MentionPicker\n\t\t\t\t\t\t\t\t\t{...props}\n\t\t\t\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t\t\t\t\tonSelectVariable={insertChip}\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\tonChange={emitChange}\n\t\t\t\t\t/>\n\t\t\t\t</InputShell>\n\t\t\t</VariableTriggerArea>\n\t\t</FieldBlockCol>\n\t);\n};\n\nconst INLINE_EDITOR_STYLE: React.CSSProperties = {\n\tpadding: 0,\n\tfontFamily: 'Inter',\n\tfontSize: '14px',\n\tlineHeight: '20px',\n};\n\nconst FieldBlockCol = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\twidth: 100%;\n\t/* In a flex row (header key/value pairs) share the space and allow\n\t shrinking below content width — long values scroll inside the field\n\t instead of widening the row / drawer. */\n\tflex: 1 1 0%;\n\tmin-width: 0;\n`;\n\n// Mirrors the small Input's box (border, radius, padding, focus ring) around\n// the single-line editor.\nconst InputShell = styled.div<{ $atHint: boolean }>`\n\t/* No global reset in every host — without this, width:100% + padding\n\t overflows the drawer by the padding + border (the reported overflow). */\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\talign-items: center;\n\twidth: 100%;\n\tmin-width: 0;\n\toverflow: hidden;\n\tpadding: 6px 12px;\n\tbackground: ${COLORS.surface.standard};\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\n\t/* The editor root is width:100% — cap it so a long value scrolls inside\n\t the ProseMirror line rather than stretching the shell. */\n\t> div {\n\t\twidth: 100%;\n\t\tmin-width: 0;\n\t}\n\n\t&:focus-within {\n\t\tborder-color: ${COLORS.stroke.brand};\n\t}\n\n\t/* While the (empty) field is focused, the placeholder switches to the @\n\t hint — only when a catalog makes @ do anything; unfocused (or without\n\t variables) it shows the field's own placeholder. */\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\t/* Keep the editor to one visual line; long values scroll horizontally the\n\t way a native input does. */\n\t.ProseMirror {\n\t\twidth: 100%;\n\t\tmax-width: 100%;\n\t\twhite-space: nowrap;\n\t\toverflow-x: auto;\n\t\toverflow-y: hidden;\n\t\tword-break: normal;\n\t\tscrollbar-width: none;\n\n\t\t&::-webkit-scrollbar {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n\n\t.ProseMirror p {\n\t\tdisplay: inline;\n\t}\n`;\n"],"names":["nameOf","token","variableTokenName","VariableInlineField","value","onChange","label","placeholder","variablesData","rest","editorRef","useRef","hasVariables","mentionItems","useMemo","buildVariableMentionItems","initialHtml","instructionsToEditorHtml","insertChipByName","useCallback","name","buildMentionHtml","insertChip","variable","emitChange","doc","editorDocToInstructions","FieldBlockCol","TitleSmall","COLORS","jsx","VariableTriggerArea","InputShell","BikEditor","INLINE_EDITOR_STYLE","props","MentionPicker","styled","p","css"],"mappings":"mdA+BMA,EAAUC,GACfC,EAAAA,kBAAkBD,CAAK,EAAE,QAAQ,aAAc,EAAE,EAcrCE,EAA0D,CAAC,CACvE,MAAAC,EACA,SAAAC,EACA,MAAAC,EACA,YAAAC,EACA,cAAAC,EACA,GAAGC,CACJ,IAAM,CACL,MAAMC,EAAYC,EAAAA,OAAqB,IAAI,EAErCC,GAAgBJ,GAAe,QAAU,GAAK,EAC9CK,EAAeC,EAAAA,QACpB,IAAMC,EAAAA,0BAA0BP,CAAa,EAC7C,CAACA,CAAa,CAAA,EAQTQ,EAAcF,EAAAA,QACnB,IAAMG,EAAAA,yBAAyBb,EAAOS,CAAY,EAElD,CAACD,CAAY,CAAA,EAORM,EAAmBC,cAAaC,GAAiB,CACtDV,EAAU,SAAS,oBAClBW,EAAAA,iBAAiBD,EAAM,KAAKA,CAAI,KAAM,UAAU,CAAA,CAElD,EAAG,CAAA,CAAE,EACCE,EAAaH,EAAAA,YACjBI,GACAL,EAAiBhB,EAAAA,kBAAkBqB,EAAS,WAAW,CAAC,EACzD,CAACL,CAAgB,CAAA,EAGZM,EAAaL,EAAAA,YAAY,IAAM,CACpC,MAAMM,EAAMf,EAAU,SAAS,QAAA,GAAa,KAE5CL,EAASqB,EAAAA,wBAAwBD,EAAK,CAAA,CAAE,EAAE,QAAQ,OAAQ,EAAE,CAAC,CAC9D,EAAG,CAACpB,CAAQ,CAAC,EAEb,cACEsB,EAAA,CACC,SAAA,CAAArB,SAAUsB,EAAAA,WAAA,CAAW,MAAOC,SAAO,QAAQ,QAAU,SAAAvB,EAAM,EAC5DwB,EAAAA,IAACC,EAAAA,oBAAA,CACA,cAAAvB,EACA,cAAa,GACb,qBAAoB,GACpB,SAAWP,GAAUiB,EAAiBlB,EAAOC,CAAK,CAAC,EAEnD,eAAC+B,EAAA,CAAW,QAASpB,EAAc,YAAWH,EAAK,WAAW,EAC7D,SAAAqB,EAAAA,IAACG,EAAAA,UAAA,CAEA,IAAKvB,EACL,eAAgBM,EAChB,YAAAT,EACA,UAAU,OACV,UAAU,OACV,MAAO,CAAE,OAAQ,MAAA,EACjB,YAAa2B,EAEb,OAAQ,IAAA,GACR,aAAc,CAAE,IAAK,OAAA,EACrB,SAAU,CACT,OAAQrB,EACR,uBAAwB,GACxB,eAAiBsB,GAChBL,EAAAA,IAACM,EAAAA,cAAA,CACC,GAAGD,EACJ,cAAA3B,EACA,iBAAkBc,CAAA,CAAA,CACnB,EAGF,SAAUE,CAAA,EAtBLZ,EAAe,KAAO,IAAA,CAuB5B,CACD,CAAA,CAAA,CACD,EACD,CAEF,EAEMsB,EAA2C,CAChD,QAAS,EACT,WAAY,QACZ,SAAU,OACV,WAAY,MACb,EAEMP,EAAgBU,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcvBL,EAAaK,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAUXR,EAAAA,OAAO,QAAQ,QAAQ;AAAA,qBACjBA,EAAAA,OAAO,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAWxBA,EAAAA,OAAO,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMjCS,GACFA,EAAE,SACFC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GAIC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA"}
@@ -0,0 +1,10 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("react/jsx-runtime"),i=require("react"),A=require("styled-components"),D=require("../../add-variableV2/AddDataPill.js"),P=require("../utils/mentionSerialization.js"),L=require("./MentionPicker.js"),M=t=>t&&typeof t=="object"&&"default"in t?t:{default:t},y=M(A),E=t=>`{{variable:${P.variableTokenName(t.actualValue)}}}`,h=/[\s,;:/?&=({[<"']/,j=/[,;:/?&=({[<"']/,k=(t,u,d)=>{if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement){const a=t.selectionStart??t.value.length,c=a===0,n=c?" ":t.value[a-1]??" ";return{ok:c?!d:u.test(n),caret:a}}const l=window.getSelection(),f=l?.anchorNode?.textContent??"",g=l?.anchorOffset??0,r=g===0,m=r?" ":f[g-1]??" ";return{ok:r?!d:u.test(m),caret:null}},q=({variablesData:t,onInsert:u,addDataButton:d,skipNativeBoundaries:l,onOpenChange:f,children:g})=>{const r=i.useRef(null),[m,a]=i.useState(!1),c=i.useRef(null),[n,x]=i.useState(null),b=(t?.length??0)>0,T=e=>{x(e),f?.(!0)},p=()=>{x(null),f?.(!1)},w=()=>{const e=r.current?.getBoundingClientRect();return{above:!!e&&window.innerHeight-e.bottom<385,alignRight:!!e&&window.innerWidth-e.left<360}},R=i.useCallback(e=>{if(!b||e.key!=="@")return;const o=k(e.target,l?j:h,!!l);o.ok&&(e.preventDefault(),e.stopPropagation(),T({caret:o.caret,...w()}))},[b]),S=()=>{const e=k(c.current,h,!1);T({caret:e.caret,...w()})};return i.useEffect(()=>{if(!n)return;const e=s=>{s.key==="Escape"&&(s.stopPropagation(),p())},o=s=>{r.current?.contains(s.target)||p()};return document.addEventListener("keydown",e,!0),document.addEventListener("mousedown",o),()=>{document.removeEventListener("keydown",e,!0),document.removeEventListener("mousedown",o)}},[n]),v.jsxs(F,{ref:r,onKeyDownCapture:R,onFocus:e=>{e.target.closest?.('[data-test="variable-trigger-panel"]')||(c.current=e.target,a(!0))},onBlur:()=>a(!1),children:[g,d&&b&&(m||n)&&v.jsx(D.AddDataPill,{label:"Add variable",onOpen:S}),n&&v.jsx($,{$above:n.above,$right:n.alignRight,"data-test":"variable-trigger-panel",onMouseDown:e=>{e.target.closest("input")||e.preventDefault()},children:v.jsx(L.MentionPicker,{items:[],query:"",activeIndex:-1,onSelect:()=>{},onClose:p,variablesData:t,onSelectVariable:e=>{p();const o=c.current,s=o instanceof HTMLInputElement||o instanceof HTMLTextAreaElement?o.selectionStart??n.caret:n.caret;u(E(e),s)}})})]})},F=y.default.div`
2
+ position: relative;
3
+ `,$=y.default.div`
4
+ position: absolute;
5
+ z-index: 1000;
6
+ width: 344px;
7
+ ${t=>t.$right?"right: 0;":"left: 0;"}
8
+ ${t=>t.$above?"bottom: calc(100% + 4px);":"top: calc(100% + 4px);"}
9
+ `;exports.VariableTriggerArea=q;exports.variableToken=E;
10
+ //# sourceMappingURL=VariableTriggerArea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariableTriggerArea.js","sources":["../../../../../src/components/agent-builder/components/VariableTriggerArea.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport { AddDataPill } from '../../add-variableV2/AddDataPill';\nimport type {\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport { variableTokenName } from '../utils/mentionSerialization';\nimport { MentionPicker } from './MentionPicker';\n\n/** The persisted form of a picked variable (`{{variable:<name>}}`). */\nexport const variableToken = (variable: VariableV3): string =>\n\t`{{variable:${variableTokenName(variable.actualValue)}}}`;\n\n/**\n * Boundary test for the `@` trigger: an `@` typed at the start of the field or\n * after a separator opens the picker. The separator set covers URL and JSON\n * delimiters too (`https://@`, `Bearer=@`, `\"@`, `[@`) — an email address's `@`\n * always follows a letter / digit / dot, so `john@acme.com` still types\n * through untouched. Returns the caret index for input / textarea targets\n * (where the caller can splice the token in), null for contenteditable ones.\n */\n// Opening delimiters trigger; closing ones (`}` `)` `]` `>`) deliberately do\n// NOT — typing a literal `@` right after an inserted `{{token}}` (e.g.\n// `{{store_name}}@acme.com`) must stay literal.\nconst BOUNDARY = /[\\s,;:/?&=({[<\"']/;\n// The subset the editor's own `@` mention trigger does NOT handle (it only\n// fires after whitespace / at the start) — used by `skipNativeBoundaries`\n// fields so the two triggers never fire for the same keystroke.\nconst NON_NATIVE_BOUNDARY = /[,;:/?&=({[<\"']/;\n\nconst triggerContext = (\n\ttarget: EventTarget | null,\n\tboundary: RegExp,\n\tskipStart: boolean,\n): { ok: boolean; caret: number | null } => {\n\tif (\n\t\ttarget instanceof HTMLInputElement ||\n\t\ttarget instanceof HTMLTextAreaElement\n\t) {\n\t\tconst caret = target.selectionStart ?? target.value.length;\n\t\tconst atStart = caret === 0;\n\t\tconst prev = atStart ? ' ' : target.value[caret - 1] ?? ' ';\n\t\treturn { ok: atStart ? !skipStart : boundary.test(prev), caret };\n\t}\n\t// Rich editor (ProseMirror contenteditable): read the character before the\n\t// selection.\n\tconst sel = window.getSelection();\n\tconst text = sel?.anchorNode?.textContent ?? '';\n\tconst offset = sel?.anchorOffset ?? 0;\n\tconst atStart = offset === 0;\n\tconst prev = atStart ? ' ' : text[offset - 1] ?? ' ';\n\treturn { ok: atStart ? !skipStart : boundary.test(prev), caret: null };\n};\n\ninterface VariableTriggerAreaProps {\n\t/** Variable catalog. Absent / empty → the wrapper is inert (children only). */\n\tvariablesData?: VariableListInterfaceV3[];\n\t/**\n\t * Insert `token` into the wrapped field. `caret` is the character index the\n\t * `@` was typed at (input / textarea targets — splice the token in there);\n\t * null for rich-editor targets (insert at the editor's own cursor).\n\t */\n\tonInsert: (token: string, caret: number | null) => void;\n\t/**\n\t * Show the floating \"+ Add data\" pill while the wrapped field is focused.\n\t * Clicking it opens this same variable panel at the field's caret — the\n\t * button equivalent of typing `@`.\n\t */\n\taddDataButton?: boolean;\n\t/**\n\t * The wrapped field is a BikEditor whose OWN `@` mention trigger already\n\t * fires after whitespace / at the start — this wrapper then only handles\n\t * the delimiter boundaries the native trigger misses (`https://@`, `\"@`…),\n\t * so the two never open a panel for the same keystroke.\n\t */\n\tskipNativeBoundaries?: boolean;\n\t/**\n\t * Observes the panel's open state. Fields that commit on blur (the email\n\t * chips entry) use this to hold off while focus is bouncing through the\n\t * panel — blur-time focus targets are unreliable mid-transition.\n\t */\n\tonOpenChange?: (open: boolean) => void;\n\tchildren: React.ReactNode;\n}\n\n/**\n * Wraps any plain field (input / textarea / chips entry / BikEditor) and opens\n * the shared {@link VariablePicker} as a floating panel when `@` is typed at a\n * word boundary. The `@` keystroke itself is swallowed (never reaches the\n * field); picking a variable calls `onInsert` with the `{{variable:<name>}}`\n * token, and Escape / click-outside / the panel's ✕ just closes the panel.\n *\n * Purely presentational wrapper — it renders a `position: relative` block, so\n * the wrapped field must be happy inside a plain block container.\n */\nexport const VariableTriggerArea: React.FC<VariableTriggerAreaProps> = ({\n\tvariablesData,\n\tonInsert,\n\taddDataButton,\n\tskipNativeBoundaries,\n\tonOpenChange,\n\tchildren,\n}) => {\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\t// Whether the wrapped field (any focusable inside) currently has focus, and\n\t// the element that had it — the pill inserts at that element's caret.\n\tconst [fieldFocused, setFieldFocused] = useState(false);\n\tconst lastFocusedRef = useRef<EventTarget | null>(null);\n\t// Non-null while the panel is open: where to put the token when picked, and\n\t// which way the panel flips to stay on screen (above when there's no room\n\t// below, right-aligned when the field sits too close to the right edge —\n\t// e.g. header-value inputs in the Rest API drawer).\n\tconst [trigger, setTrigger] = useState<{\n\t\tcaret: number | null;\n\t\tabove: boolean;\n\t\talignRight: boolean;\n\t} | null>(null);\n\n\tconst enabled = (variablesData?.length ?? 0) > 0;\n\n\tconst openPanel = (t: NonNullable<typeof trigger>) => {\n\t\tsetTrigger(t);\n\t\tonOpenChange?.(true);\n\t};\n\tconst closePanel = () => {\n\t\tsetTrigger(null);\n\t\tonOpenChange?.(false);\n\t};\n\n\t// Panel is ~344px wide / ~385px tall (the MentionPicker card in its\n\t// variables view, plus a little slack), anchored to the field's left edge —\n\t// flip above / right-align when it would spill past the viewport (avoids\n\t// the drawer growing scrollbars).\n\tconst placement = () => {\n\t\tconst rect = containerRef.current?.getBoundingClientRect();\n\t\treturn {\n\t\t\tabove: !!rect && window.innerHeight - rect.bottom < 385,\n\t\t\talignRight: !!rect && window.innerWidth - rect.left < 360,\n\t\t};\n\t};\n\n\tconst onKeyDownCapture = useCallback(\n\t\t(e: React.KeyboardEvent) => {\n\t\t\tif (!enabled || e.key !== '@') {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst ctx = triggerContext(\n\t\t\t\te.target,\n\t\t\t\tskipNativeBoundaries ? NON_NATIVE_BOUNDARY : BOUNDARY,\n\t\t\t\t!!skipNativeBoundaries,\n\t\t\t);\n\t\t\tif (!ctx.ok) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Swallow the `@` so the field's value stays untouched while picking.\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\topenPanel({ caret: ctx.caret, ...placement() });\n\t\t},\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[enabled],\n\t);\n\n\t// The pill's click — same panel, anchored at the focused field's caret (no\n\t// boundary rule: an explicit button click is always intentional).\n\tconst openFromButton = () => {\n\t\tconst ctx = triggerContext(lastFocusedRef.current, BOUNDARY, false);\n\t\topenPanel({ caret: ctx.caret, ...placement() });\n\t};\n\n\t// Escape / click-outside dismiss, active only while open.\n\tuseEffect(() => {\n\t\tif (!trigger) {\n\t\t\treturn;\n\t\t}\n\t\tconst onKey = (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\te.stopPropagation();\n\t\t\t\tclosePanel();\n\t\t\t}\n\t\t};\n\t\tconst onDown = (e: MouseEvent) => {\n\t\t\tif (!containerRef.current?.contains(e.target as Node)) {\n\t\t\t\tclosePanel();\n\t\t\t}\n\t\t};\n\t\t// Capture phase so an Escape meant for the panel never also closes the\n\t\t// drawer underneath.\n\t\tdocument.addEventListener('keydown', onKey, true);\n\t\tdocument.addEventListener('mousedown', onDown);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', onKey, true);\n\t\t\tdocument.removeEventListener('mousedown', onDown);\n\t\t};\n\t}, [trigger]);\n\n\treturn (\n\t\t<TriggerWrap\n\t\t\tref={containerRef}\n\t\t\tonKeyDownCapture={onKeyDownCapture}\n\t\t\t// React's focus/blur bubble — this tracks any focusable child (the\n\t\t\t// input, a chips entry, the ProseMirror contenteditable).\n\t\t\tonFocus={(e) => {\n\t\t\t\t// Focus landing inside the floating panel (its search box) is not\n\t\t\t\t// the field — inserting at \"its caret\" would target the wrong input.\n\t\t\t\tif (\n\t\t\t\t\t(e.target as HTMLElement).closest?.(\n\t\t\t\t\t\t'[data-test=\"variable-trigger-panel\"]',\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlastFocusedRef.current = e.target;\n\t\t\t\tsetFieldFocused(true);\n\t\t\t}}\n\t\t\tonBlur={() => setFieldFocused(false)}\n\t\t>\n\t\t\t{children}\n\t\t\t{addDataButton && enabled && (fieldFocused || trigger) && (\n\t\t\t\t<AddDataPill label=\"Add variable\" onOpen={openFromButton} />\n\t\t\t)}\n\t\t\t{trigger && (\n\t\t\t\t<FloaterBox\n\t\t\t\t\t$above={trigger.above}\n\t\t\t\t\t$right={trigger.alignRight}\n\t\t\t\t\tdata-test=\"variable-trigger-panel\"\n\t\t\t\t\t// Keep the field focused while clicking rows (a blur mid-pick\n\t\t\t\t\t// would e.g. commit a half-typed email chip). The panel's own\n\t\t\t\t\t// inputs (search) still take focus normally.\n\t\t\t\t\tonMouseDown={(e) => {\n\t\t\t\t\t\tconst t = e.target as HTMLElement;\n\t\t\t\t\t\tif (!t.closest('input')) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{/* The EXACT panel the Instructions / Guardrails @ opens: with no\n\t\t\t\t\t tools / sub-agents, Variables is its sole category, so it\n\t\t\t\t\t renders the \"Variables\" header + variable list directly. */}\n\t\t\t\t\t<MentionPicker\n\t\t\t\t\t\titems={[]}\n\t\t\t\t\t\tquery=\"\"\n\t\t\t\t\t\tactiveIndex={-1}\n\t\t\t\t\t\tonSelect={() => undefined}\n\t\t\t\t\t\tonClose={closePanel}\n\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t\tonSelectVariable={(variable: VariableV3) => {\n\t\t\t\t\t\t\tclosePanel();\n\t\t\t\t\t\t\t// Re-read the caret at PICK time: the user may have clicked\n\t\t\t\t\t\t\t// elsewhere in the field since the `@` (the panel stays open\n\t\t\t\t\t\t\t// for clicks inside the wrapper), and an input keeps its\n\t\t\t\t\t\t\t// selection while unfocused — trigger.caret is the fallback.\n\t\t\t\t\t\t\tconst el = lastFocusedRef.current;\n\t\t\t\t\t\t\tconst caret =\n\t\t\t\t\t\t\t\tel instanceof HTMLInputElement ||\n\t\t\t\t\t\t\t\tel instanceof HTMLTextAreaElement\n\t\t\t\t\t\t\t\t\t? el.selectionStart ?? trigger.caret\n\t\t\t\t\t\t\t\t\t: trigger.caret;\n\t\t\t\t\t\t\tonInsert(variableToken(variable), caret);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</FloaterBox>\n\t\t\t)}\n\t\t</TriggerWrap>\n\t);\n};\n\nconst TriggerWrap = styled.div`\n\tposition: relative;\n`;\n\n// Floats under (or over) the wrapped field; the MentionPicker inside brings\n// its own card chrome (same as the Instructions / Guardrails @ menu). High\n// z-index: these fields live inside side-modal drawers.\nconst FloaterBox = styled.div<{ $above: boolean; $right: boolean }>`\n\tposition: absolute;\n\tz-index: 1000;\n\twidth: 344px;\n\t${(p) => (p.$right ? 'right: 0;' : 'left: 0;')}\n\t${(p) => (p.$above ? 'bottom: calc(100% + 4px);' : 'top: calc(100% + 4px);')}\n`;\n"],"names":["variableToken","variable","variableTokenName","BOUNDARY","NON_NATIVE_BOUNDARY","triggerContext","target","boundary","skipStart","caret","atStart","prev","sel","text","offset","VariableTriggerArea","variablesData","onInsert","addDataButton","skipNativeBoundaries","onOpenChange","children","containerRef","useRef","fieldFocused","setFieldFocused","useState","lastFocusedRef","trigger","setTrigger","enabled","openPanel","t","closePanel","placement","rect","onKeyDownCapture","useCallback","ctx","openFromButton","useEffect","onKey","e","onDown","jsxs","TriggerWrap","AddDataPill","jsx","FloaterBox","MentionPicker","el","styled","p"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=[{key:"tool",label:"Tools"},{key:"subagent",label:"Sub-agent"}];var e=(i=>(i.Manifest="manifest",i.Shopify="shopify",i.Bigcommerce="bigcommerce",i.Shipstation="shipstation",i.Skio="skio",i.Gorgias="gorgias",i.Integration="integration",i.RestApi="rest_api",i.EmailHandover="email_handover",i.Slack="slack",i))(e||{});const O={manifest:"Manifest",shopify:"Shopify",bigcommerce:"BigCommerce",shipstation:"ShipStation",skio:"Skio",gorgias:"Gorgias",integration:"Integration",rest_api:"Rest API",email_handover:"Email",slack:"Slack"},o={rest_api:"REST API",email_handover:"Send email",slack:"Send Slack message"},_=["rest_api","email_handover","slack"],t={manifest:0,shopify:1,bigcommerce:2,skio:3,gorgias:4,shipstation:5,slack:6,email_handover:7,rest_api:8},s=["shopify","bigcommerce","shipstation","skio","gorgias","integration"],E=new Set(s),S=i=>E.has(i),a=["shipstation","integration"],R=new Set(a),r=i=>R.has(i),I="more_integrations",c="More Integrations",N=9,T=Object.keys(t).length,g=i=>t[i]??T,A={email_handover:"send_email",slack:"send_slack_message"};exports.CATEGORIES=n;exports.CONFIG_TOOL_SOURCES=A;exports.INTEGRATION_SOURCES=s;exports.MORE_INTEGRATIONS_KEY=I;exports.MORE_INTEGRATIONS_LABEL=c;exports.MORE_INTEGRATIONS_RANK=N;exports.MORE_INTEGRATION_SOURCES=a;exports.TOOL_ACTION_LABELS=o;exports.TOOL_ACTION_SOURCES=_;exports.TOOL_SOURCE_LABELS=O;exports.TOOL_SOURCE_RANK=t;exports.ToolSource=e;exports.isIntegrationSource=S;exports.isMoreIntegrationSource=r;exports.toolSourceRank=g;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=[{key:"tool",label:"Tools"},{key:"subagent",label:"Sub-agent"},{key:"variable",label:"Variables"}];var t=(e=>(e.Manifest="manifest",e.Shopify="shopify",e.Bigcommerce="bigcommerce",e.Shipstation="shipstation",e.Skio="skio",e.Gorgias="gorgias",e.Integration="integration",e.RestApi="rest_api",e.EmailHandover="email_handover",e.Slack="slack",e))(t||{});const O={manifest:"Manifest",shopify:"Shopify",bigcommerce:"BigCommerce",shipstation:"ShipStation",skio:"Skio",gorgias:"Gorgias",integration:"Integration",rest_api:"Rest API",email_handover:"Email",slack:"Slack"},o={rest_api:"REST API",email_handover:"Send email",slack:"Send Slack message"},_=["rest_api","email_handover","slack"],i={manifest:0,shopify:1,bigcommerce:2,skio:3,gorgias:4,shipstation:5,slack:6,email_handover:7,rest_api:8},s=["shopify","bigcommerce","shipstation","skio","gorgias","integration"],E=new Set(s),S=e=>E.has(e),a=["shipstation","integration"],R=new Set(a),r=e=>R.has(e),I="more_integrations",c="More Integrations",N=9,T=Object.keys(i).length,g=e=>i[e]??T,A={email_handover:"send_email",slack:"send_slack_message"};exports.CATEGORIES=n;exports.CONFIG_TOOL_SOURCES=A;exports.INTEGRATION_SOURCES=s;exports.MORE_INTEGRATIONS_KEY=I;exports.MORE_INTEGRATIONS_LABEL=c;exports.MORE_INTEGRATIONS_RANK=N;exports.MORE_INTEGRATION_SOURCES=a;exports.TOOL_ACTION_LABELS=o;exports.TOOL_ACTION_SOURCES=_;exports.TOOL_SOURCE_LABELS=O;exports.TOOL_SOURCE_RANK=i;exports.ToolSource=t;exports.isIntegrationSource=S;exports.isMoreIntegrationSource=r;exports.toolSourceRank=g;
2
2
  //# sourceMappingURL=tools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sources":["../../../../../src/components/agent-builder/constants/tools.ts"],"sourcesContent":["import type { ToolSource as ModelToolSource } from '@bikdotai/bik-models/ai-agents/models/agent-tool';\nimport type { FunctionComponent, SVGAttributes } from 'react';\n\n/**\n * Static tool-related constants for the builder's Step 3 (tools & sub-agents):\n * the reference-picker category tabs and the per-source display labels. Kept here\n * (rather than inline in the picker / serialization utils) so the labels a user\n * sees are all in one obvious place.\n */\n\n/** A reference-picker category tab. */\nexport type Category = 'tool' | 'subagent';\n\n/** Category tabs shown at the root of the `@` reference picker. */\nexport const CATEGORIES: { key: Category; label: string }[] = [\n\t{ key: 'tool', label: 'Tools' },\n\t{ key: 'subagent', label: 'Sub-agent' },\n];\n\n/**\n * Every tool \"source\" the builder renders an icon / label / picker entry for.\n * Enum VALUES are the backend's canonical read-only `source` wire strings\n * (`app/agents/config/schema.py` → `ToolSource`, derived from `tool_key`): the\n * configurable tools are `email_handover` / `rest_api` / `slack`, every native\n * tool is `manifest`. `shopify` / `integration` are legacy bik-models sources\n * kept for back-compat (the backend now collapses natives to `manifest`).\n * Dynamic/unknown sources are looked up leniently — see `toolSourceLabel` and\n * `sourceIcon`.\n *\n * This is the RUNTIME mirror of the canonical `@bikdotai/bik-models` `ToolSource`\n * union (the shape the backend persists as `AgentToolDoc.source`). We keep an\n * enum — not a re-export of the type — because the members are needed at runtime\n * for labels, ranks, icons and `===` comparisons; a type-only union can't do\n * that. The two are kept in lock-step by {@link ToolSourceMatchesBikModels}\n * below, which fails to compile if they ever drift.\n */\nexport enum ToolSource {\n\tManifest = 'manifest',\n\tShopify = 'shopify',\n\tBigcommerce = 'bigcommerce',\n\tShipstation = 'shipstation',\n\tSkio = 'skio',\n\tGorgias = 'gorgias',\n\tIntegration = 'integration',\n\tRestApi = 'rest_api',\n\tEmailHandover = 'email_handover',\n\tSlack = 'slack',\n}\n\n/**\n * Compile-time guard that {@link ToolSource} stays a faithful mirror of the\n * canonical `@bikdotai/bik-models` `ToolSource` union. If a source is added to\n * (or removed from) either side without the other, `AssertTrue` receives `false`\n * and this type stops compiling — so the runtime enum can never silently diverge\n * from what the backend persists as `AgentToolDoc.source`. The tuple wrappers\n * (`[…]`) stop the conditionals from distributing over the unions, so it checks\n * set-equality in both directions.\n *\n * Type-only (erased at build): a drift shows up as a compile error on\n * `ToolSourceMatchesBikModels` telling you to reconcile this enum with\n * `@bikdotai/bik-models` (bump the dep and/or the enum).\n */\ntype AssertTrue<T extends true> = T;\ntype ToolSourceMatchesBikModels = AssertTrue<\n\t[`${ToolSource}`] extends [ModelToolSource]\n\t\t? [ModelToolSource] extends [`${ToolSource}`]\n\t\t\t? true\n\t\t\t: false\n\t\t: false\n>;\n\n/**\n * Display labels for the known tool sources — the CATEGORY/integration name, used\n * for the picker's source headers (drill-in groups), the empty-state source\n * buttons and the mention-chip prefix. A source is a category (\"Slack\") you drill\n * into; the specific addable action inside it (\"Send Slack message\") is\n * `TOOL_ACTION_LABELS`. Unknown sources fall back to the raw key (see\n * `toolSourceLabel`).\n */\nexport const TOOL_SOURCE_LABELS: Record<ToolSource, string> = {\n\t[ToolSource.Manifest]: 'Manifest',\n\t[ToolSource.Shopify]: 'Shopify',\n\t[ToolSource.Bigcommerce]: 'BigCommerce',\n\t[ToolSource.Shipstation]: 'ShipStation',\n\t[ToolSource.Skio]: 'Skio',\n\t[ToolSource.Gorgias]: 'Gorgias',\n\t[ToolSource.Integration]: 'Integration',\n\t[ToolSource.RestApi]: 'Rest API',\n\t[ToolSource.EmailHandover]: 'Email',\n\t[ToolSource.Slack]: 'Slack',\n};\n\n/**\n * The addable action inside a configurable/rest source — shown as the \"add\" row\n * in the `@` picker (below any existing instances) and the empty-state button.\n * Distinct from `TOOL_SOURCE_LABELS`, which names the category the action lives in\n * (e.g. category \"Slack\" → action \"Send Slack message\").\n */\nexport const TOOL_ACTION_LABELS: Partial<Record<ToolSource, string>> = {\n\t[ToolSource.RestApi]: 'REST API',\n\t[ToolSource.EmailHandover]: 'Send email',\n\t[ToolSource.Slack]: 'Send Slack message',\n};\n\n/** A tool source's brand-glyph component. */\nexport type IconComp = FunctionComponent<SVGAttributes<SVGElement>>;\n\n/** Brand glyph for a tool source, with its own size so each keeps its aspect ratio. */\nexport interface SourceIcon {\n\tIcon: IconComp;\n\tw: number;\n\th: number;\n}\n\n/**\n * A built-in \"tool\" that opens a config drawer (Rest API / email handover /\n * Slack) rather than inserting a mention. Surfaced as an empty-state source\n * button in the Tools section and as a row in the `@`-picker Tools view; picking\n * it opens the drawer and never writes into the instructions text.\n */\nexport interface ToolAction {\n\tsource: ToolSource;\n\tlabel: string;\n\ticon?: SourceIcon;\n\t/** Open this tool's config drawer. */\n\tonSelect: () => void;\n\t/**\n\t * Integration connection state for this source. `undefined` = no connection\n\t * gating (default). `false` = the store hasn't connected this integration →\n\t * the `@` picker shows a \"Connect\" row that calls {@link onConnect} instead of\n\t * drilling in / offering \"Create new\". `true` = connected (renders normally).\n\t * Set by the consumer via `config.integrationStatus` (today: Slack only).\n\t */\n\tconnected?: boolean;\n\t/** Open the parent's connect flow for this source (used when `connected === false`). */\n\tonConnect?: () => void;\n}\n\n/** Sources of the built-in drawer tools, in display order. */\nexport const TOOL_ACTION_SOURCES: ToolSource[] = [\n\tToolSource.RestApi,\n\tToolSource.EmailHandover,\n\tToolSource.Slack,\n];\n\n/**\n * Fixed display rank for the `@`-picker's tool-source groups (lower = higher). The\n * picker sorts its source rows by this so adding/updating a tool never reshuffles\n * them. Manifest (the native tools) leads; any source not listed here\n * (dynamic/unknown, e.g. Integration) sorts AFTER Slack, keeping its discovery\n * order among the rest (Array.sort is stable).\n */\nexport const TOOL_SOURCE_RANK: Partial<Record<ToolSource, number>> = {\n\t[ToolSource.Manifest]: 0,\n\t[ToolSource.Shopify]: 1,\n\t// BigCommerce / Skio / Gorgias are their OWN top-level rows; rank orders them\n\t// so adding/updating a tool never reshuffles them.\n\t[ToolSource.Bigcommerce]: 2,\n\t[ToolSource.Skio]: 3,\n\t[ToolSource.Gorgias]: 4,\n\t// ShipStation lives under the \"More Integrations\" umbrella; its rank only\n\t// orders it inside that drill-in view (never shown at the root).\n\t[ToolSource.Shipstation]: 5,\n\t[ToolSource.Slack]: 6,\n\t// Send Email then REST API sit after the integration sources at the top level.\n\t[ToolSource.EmailHandover]: 7,\n\t[ToolSource.RestApi]: 8,\n};\n\n/**\n * External integration / vendor sources. Each renders as its OWN top-level\n * drill-in group in the picker — even when it has a single tool — so the vendor\n * reads as its own discoverable, connectable unit (never collapsed to a lone\n * leaf; see the single-leaf flatten in `MentionPicker`). Deliberately excludes\n * `Manifest` (the built-in natives) and the config/rest action sources (Rest API\n * / Email / Slack), whose single capability is surfaced flat.\n */\nexport const INTEGRATION_SOURCES: ToolSource[] = [\n\tToolSource.Shopify,\n\tToolSource.Bigcommerce,\n\tToolSource.Shipstation,\n\tToolSource.Skio,\n\tToolSource.Gorgias,\n\tToolSource.Integration,\n];\n\nconst INTEGRATION_SOURCE_SET = new Set<string>(INTEGRATION_SOURCES);\n\n/** True for an external integration/vendor source (never collapsed to a single leaf). */\nexport const isIntegrationSource = (source: string): boolean =>\n\tINTEGRATION_SOURCE_SET.has(source);\n\n/**\n * Vendor integrations that live UNDER the \"More Integrations\" umbrella in the `@`\n * picker (a single top-level row → their list), instead of each being its own\n * root row. Shopify, BigCommerce, Skio and Gorgias stay top-level sources of\n * their own; only the less-common vendors (ShipStation) and the generic\n * catch-all Integration are tucked away here.\n */\nexport const MORE_INTEGRATION_SOURCES: ToolSource[] = [\n\tToolSource.Shipstation,\n\tToolSource.Integration,\n];\n\nconst MORE_INTEGRATION_SOURCE_SET = new Set<string>(MORE_INTEGRATION_SOURCES);\n\n/** True for a source shown under the \"More Integrations\" umbrella. */\nexport const isMoreIntegrationSource = (source: string): boolean =>\n\tMORE_INTEGRATION_SOURCE_SET.has(source);\n\n/**\n * Synthetic picker key / label / rank for the \"More Integrations\" umbrella row.\n * The rank lives here (not in {@link TOOL_SOURCE_RANK}) because that map is keyed\n * by the drift-guarded {@link ToolSource} enum — the backend's canonical wire\n * strings — and `more_integrations` is a picker-only key, not a real source.\n */\nexport const MORE_INTEGRATIONS_KEY = 'more_integrations';\nexport const MORE_INTEGRATIONS_LABEL = 'More Integrations';\n/** Always last — sits after every named top-level source (REST API, rank 8). */\nexport const MORE_INTEGRATIONS_RANK = 9;\n\nconst UNRANKED_SOURCE_RANK = Object.keys(TOOL_SOURCE_RANK).length;\n\n/** Sort rank for a source string; unknown sources rank after all known ones. */\nexport const toolSourceRank = (source: string): number =>\n\tTOOL_SOURCE_RANK[source as ToolSource] ?? UNRANKED_SOURCE_RANK;\n\n/**\n * `tool_key` of a configurable shared-drawer tool (email / Slack). Lives here (not\n * in AgentBuilder.model) so this leaf constants file has no back-edge to the model\n * — the dependency stays one-way (model → constants), avoiding a circular import.\n */\nexport type ConfigToolKey = 'send_email' | 'send_slack_message';\n\n/**\n * Drawer sources rendered by the shared dynamic panel (`ConfigToolPanel`), each\n * mapped to its backend `tool_key`. Rest API is absent — it has a bespoke panel.\n */\nexport const CONFIG_TOOL_SOURCES: Partial<Record<ToolSource, ConfigToolKey>> = {\n\t[ToolSource.EmailHandover]: 'send_email',\n\t[ToolSource.Slack]: 'send_slack_message',\n};\n"],"names":["CATEGORIES","ToolSource","TOOL_SOURCE_LABELS","TOOL_ACTION_LABELS","TOOL_ACTION_SOURCES","TOOL_SOURCE_RANK","INTEGRATION_SOURCES","INTEGRATION_SOURCE_SET","isIntegrationSource","source","MORE_INTEGRATION_SOURCES","MORE_INTEGRATION_SOURCE_SET","isMoreIntegrationSource","MORE_INTEGRATIONS_KEY","MORE_INTEGRATIONS_LABEL","MORE_INTEGRATIONS_RANK","UNRANKED_SOURCE_RANK","toolSourceRank","CONFIG_TOOL_SOURCES"],"mappings":"gFAcO,MAAMA,EAAiD,CAC7D,CAAE,IAAK,OAAQ,MAAO,OAAA,EACtB,CAAE,IAAK,WAAY,MAAO,WAAA,CAC3B,EAmBO,IAAKC,GAAAA,IACXA,EAAA,SAAW,WACXA,EAAA,QAAU,UACVA,EAAA,YAAc,cACdA,EAAA,YAAc,cACdA,EAAA,KAAO,OACPA,EAAA,QAAU,UACVA,EAAA,YAAc,cACdA,EAAA,QAAU,WACVA,EAAA,cAAgB,iBAChBA,EAAA,MAAQ,QAVGA,IAAAA,GAAA,CAAA,CAAA,EA2CL,MAAMC,EAAiD,CAC5D,SAAsB,WACtB,QAAqB,UACrB,YAAyB,cACzB,YAAyB,cACzB,KAAkB,OAClB,QAAqB,UACrB,YAAyB,cACzB,SAAqB,WACrB,eAA2B,QAC3B,MAAmB,OACrB,EAQaC,EAA0D,CACrE,SAAqB,WACrB,eAA2B,aAC3B,MAAmB,oBACrB,EAqCaC,EAAoC,CAChD,WACA,iBACA,OACD,EASaC,EAAwD,CACnE,SAAsB,EACtB,QAAqB,EAGrB,YAAyB,EACzB,KAAkB,EAClB,QAAqB,EAGrB,YAAyB,EACzB,MAAmB,EAEnB,eAA2B,EAC3B,SAAqB,CACvB,EAUaC,EAAoC,CAChD,UACA,cACA,cACA,OACA,UACA,aACD,EAEMC,EAAyB,IAAI,IAAYD,CAAmB,EAGrDE,EAAuBC,GACnCF,EAAuB,IAAIE,CAAM,EASrBC,EAAyC,CACrD,cACA,aACD,EAEMC,EAA8B,IAAI,IAAYD,CAAwB,EAG/DE,EAA2BH,GACvCE,EAA4B,IAAIF,CAAM,EAQ1BI,EAAwB,oBACxBC,EAA0B,oBAE1BC,EAAyB,EAEhCC,EAAuB,OAAO,KAAKX,CAAgB,EAAE,OAG9CY,EAAkBR,GAC9BJ,EAAiBI,CAAoB,GAAKO,EAa9BE,EAAkE,CAC7E,eAA2B,aAC3B,MAAmB,oBACrB"}
1
+ {"version":3,"file":"tools.js","sources":["../../../../../src/components/agent-builder/constants/tools.ts"],"sourcesContent":["import type { ToolSource as ModelToolSource } from '@bikdotai/bik-models/ai-agents/models/agent-tool';\nimport type { FunctionComponent, SVGAttributes } from 'react';\n\n/**\n * Static tool-related constants for the builder's Step 3 (tools & sub-agents):\n * the reference-picker category tabs and the per-source display labels. Kept here\n * (rather than inline in the picker / serialization utils) so the labels a user\n * sees are all in one obvious place.\n */\n\n/** A reference-picker category tab. */\nexport type Category = 'tool' | 'subagent' | 'variable';\n\n/** Category tabs shown at the root of the `@` reference picker. */\nexport const CATEGORIES: { key: Category; label: string }[] = [\n\t{ key: 'tool', label: 'Tools' },\n\t{ key: 'subagent', label: 'Sub-agent' },\n\t{ key: 'variable', label: 'Variables' },\n];\n\n/**\n * Every tool \"source\" the builder renders an icon / label / picker entry for.\n * Enum VALUES are the backend's canonical read-only `source` wire strings\n * (`app/agents/config/schema.py` → `ToolSource`, derived from `tool_key`): the\n * configurable tools are `email_handover` / `rest_api` / `slack`, every native\n * tool is `manifest`. `shopify` / `integration` are legacy bik-models sources\n * kept for back-compat (the backend now collapses natives to `manifest`).\n * Dynamic/unknown sources are looked up leniently — see `toolSourceLabel` and\n * `sourceIcon`.\n *\n * This is the RUNTIME mirror of the canonical `@bikdotai/bik-models` `ToolSource`\n * union (the shape the backend persists as `AgentToolDoc.source`). We keep an\n * enum — not a re-export of the type — because the members are needed at runtime\n * for labels, ranks, icons and `===` comparisons; a type-only union can't do\n * that. The two are kept in lock-step by {@link ToolSourceMatchesBikModels}\n * below, which fails to compile if they ever drift.\n */\nexport enum ToolSource {\n\tManifest = 'manifest',\n\tShopify = 'shopify',\n\tBigcommerce = 'bigcommerce',\n\tShipstation = 'shipstation',\n\tSkio = 'skio',\n\tGorgias = 'gorgias',\n\tIntegration = 'integration',\n\tRestApi = 'rest_api',\n\tEmailHandover = 'email_handover',\n\tSlack = 'slack',\n}\n\n/**\n * Compile-time guard that {@link ToolSource} stays a faithful mirror of the\n * canonical `@bikdotai/bik-models` `ToolSource` union. If a source is added to\n * (or removed from) either side without the other, `AssertTrue` receives `false`\n * and this type stops compiling — so the runtime enum can never silently diverge\n * from what the backend persists as `AgentToolDoc.source`. The tuple wrappers\n * (`[…]`) stop the conditionals from distributing over the unions, so it checks\n * set-equality in both directions.\n *\n * Type-only (erased at build): a drift shows up as a compile error on\n * `ToolSourceMatchesBikModels` telling you to reconcile this enum with\n * `@bikdotai/bik-models` (bump the dep and/or the enum).\n */\ntype AssertTrue<T extends true> = T;\ntype ToolSourceMatchesBikModels = AssertTrue<\n\t[`${ToolSource}`] extends [ModelToolSource]\n\t\t? [ModelToolSource] extends [`${ToolSource}`]\n\t\t\t? true\n\t\t\t: false\n\t\t: false\n>;\n\n/**\n * Display labels for the known tool sources — the CATEGORY/integration name, used\n * for the picker's source headers (drill-in groups), the empty-state source\n * buttons and the mention-chip prefix. A source is a category (\"Slack\") you drill\n * into; the specific addable action inside it (\"Send Slack message\") is\n * `TOOL_ACTION_LABELS`. Unknown sources fall back to the raw key (see\n * `toolSourceLabel`).\n */\nexport const TOOL_SOURCE_LABELS: Record<ToolSource, string> = {\n\t[ToolSource.Manifest]: 'Manifest',\n\t[ToolSource.Shopify]: 'Shopify',\n\t[ToolSource.Bigcommerce]: 'BigCommerce',\n\t[ToolSource.Shipstation]: 'ShipStation',\n\t[ToolSource.Skio]: 'Skio',\n\t[ToolSource.Gorgias]: 'Gorgias',\n\t[ToolSource.Integration]: 'Integration',\n\t[ToolSource.RestApi]: 'Rest API',\n\t[ToolSource.EmailHandover]: 'Email',\n\t[ToolSource.Slack]: 'Slack',\n};\n\n/**\n * The addable action inside a configurable/rest source — shown as the \"add\" row\n * in the `@` picker (below any existing instances) and the empty-state button.\n * Distinct from `TOOL_SOURCE_LABELS`, which names the category the action lives in\n * (e.g. category \"Slack\" → action \"Send Slack message\").\n */\nexport const TOOL_ACTION_LABELS: Partial<Record<ToolSource, string>> = {\n\t[ToolSource.RestApi]: 'REST API',\n\t[ToolSource.EmailHandover]: 'Send email',\n\t[ToolSource.Slack]: 'Send Slack message',\n};\n\n/** A tool source's brand-glyph component. */\nexport type IconComp = FunctionComponent<SVGAttributes<SVGElement>>;\n\n/** Brand glyph for a tool source, with its own size so each keeps its aspect ratio. */\nexport interface SourceIcon {\n\tIcon: IconComp;\n\tw: number;\n\th: number;\n}\n\n/**\n * A built-in \"tool\" that opens a config drawer (Rest API / email handover /\n * Slack) rather than inserting a mention. Surfaced as an empty-state source\n * button in the Tools section and as a row in the `@`-picker Tools view; picking\n * it opens the drawer and never writes into the instructions text.\n */\nexport interface ToolAction {\n\tsource: ToolSource;\n\tlabel: string;\n\ticon?: SourceIcon;\n\t/** Open this tool's config drawer. */\n\tonSelect: () => void;\n\t/**\n\t * Integration connection state for this source. `undefined` = no connection\n\t * gating (default). `false` = the store hasn't connected this integration →\n\t * the `@` picker shows a \"Connect\" row that calls {@link onConnect} instead of\n\t * drilling in / offering \"Create new\". `true` = connected (renders normally).\n\t * Set by the consumer via `config.integrationStatus` (today: Slack only).\n\t */\n\tconnected?: boolean;\n\t/** Open the parent's connect flow for this source (used when `connected === false`). */\n\tonConnect?: () => void;\n}\n\n/** Sources of the built-in drawer tools, in display order. */\nexport const TOOL_ACTION_SOURCES: ToolSource[] = [\n\tToolSource.RestApi,\n\tToolSource.EmailHandover,\n\tToolSource.Slack,\n];\n\n/**\n * Fixed display rank for the `@`-picker's tool-source groups (lower = higher). The\n * picker sorts its source rows by this so adding/updating a tool never reshuffles\n * them. Manifest (the native tools) leads; any source not listed here\n * (dynamic/unknown, e.g. Integration) sorts AFTER Slack, keeping its discovery\n * order among the rest (Array.sort is stable).\n */\nexport const TOOL_SOURCE_RANK: Partial<Record<ToolSource, number>> = {\n\t[ToolSource.Manifest]: 0,\n\t[ToolSource.Shopify]: 1,\n\t// BigCommerce / Skio / Gorgias are their OWN top-level rows; rank orders them\n\t// so adding/updating a tool never reshuffles them.\n\t[ToolSource.Bigcommerce]: 2,\n\t[ToolSource.Skio]: 3,\n\t[ToolSource.Gorgias]: 4,\n\t// ShipStation lives under the \"More Integrations\" umbrella; its rank only\n\t// orders it inside that drill-in view (never shown at the root).\n\t[ToolSource.Shipstation]: 5,\n\t[ToolSource.Slack]: 6,\n\t// Send Email then REST API sit after the integration sources at the top level.\n\t[ToolSource.EmailHandover]: 7,\n\t[ToolSource.RestApi]: 8,\n};\n\n/**\n * External integration / vendor sources. Each renders as its OWN top-level\n * drill-in group in the picker — even when it has a single tool — so the vendor\n * reads as its own discoverable, connectable unit (never collapsed to a lone\n * leaf; see the single-leaf flatten in `MentionPicker`). Deliberately excludes\n * `Manifest` (the built-in natives) and the config/rest action sources (Rest API\n * / Email / Slack), whose single capability is surfaced flat.\n */\nexport const INTEGRATION_SOURCES: ToolSource[] = [\n\tToolSource.Shopify,\n\tToolSource.Bigcommerce,\n\tToolSource.Shipstation,\n\tToolSource.Skio,\n\tToolSource.Gorgias,\n\tToolSource.Integration,\n];\n\nconst INTEGRATION_SOURCE_SET = new Set<string>(INTEGRATION_SOURCES);\n\n/** True for an external integration/vendor source (never collapsed to a single leaf). */\nexport const isIntegrationSource = (source: string): boolean =>\n\tINTEGRATION_SOURCE_SET.has(source);\n\n/**\n * Vendor integrations that live UNDER the \"More Integrations\" umbrella in the `@`\n * picker (a single top-level row → their list), instead of each being its own\n * root row. Shopify, BigCommerce, Skio and Gorgias stay top-level sources of\n * their own; only the less-common vendors (ShipStation) and the generic\n * catch-all Integration are tucked away here.\n */\nexport const MORE_INTEGRATION_SOURCES: ToolSource[] = [\n\tToolSource.Shipstation,\n\tToolSource.Integration,\n];\n\nconst MORE_INTEGRATION_SOURCE_SET = new Set<string>(MORE_INTEGRATION_SOURCES);\n\n/** True for a source shown under the \"More Integrations\" umbrella. */\nexport const isMoreIntegrationSource = (source: string): boolean =>\n\tMORE_INTEGRATION_SOURCE_SET.has(source);\n\n/**\n * Synthetic picker key / label / rank for the \"More Integrations\" umbrella row.\n * The rank lives here (not in {@link TOOL_SOURCE_RANK}) because that map is keyed\n * by the drift-guarded {@link ToolSource} enum — the backend's canonical wire\n * strings — and `more_integrations` is a picker-only key, not a real source.\n */\nexport const MORE_INTEGRATIONS_KEY = 'more_integrations';\nexport const MORE_INTEGRATIONS_LABEL = 'More Integrations';\n/** Always last — sits after every named top-level source (REST API, rank 8). */\nexport const MORE_INTEGRATIONS_RANK = 9;\n\nconst UNRANKED_SOURCE_RANK = Object.keys(TOOL_SOURCE_RANK).length;\n\n/** Sort rank for a source string; unknown sources rank after all known ones. */\nexport const toolSourceRank = (source: string): number =>\n\tTOOL_SOURCE_RANK[source as ToolSource] ?? UNRANKED_SOURCE_RANK;\n\n/**\n * `tool_key` of a configurable shared-drawer tool (email / Slack). Lives here (not\n * in AgentBuilder.model) so this leaf constants file has no back-edge to the model\n * — the dependency stays one-way (model → constants), avoiding a circular import.\n */\nexport type ConfigToolKey = 'send_email' | 'send_slack_message';\n\n/**\n * Drawer sources rendered by the shared dynamic panel (`ConfigToolPanel`), each\n * mapped to its backend `tool_key`. Rest API is absent — it has a bespoke panel.\n */\nexport const CONFIG_TOOL_SOURCES: Partial<Record<ToolSource, ConfigToolKey>> = {\n\t[ToolSource.EmailHandover]: 'send_email',\n\t[ToolSource.Slack]: 'send_slack_message',\n};\n"],"names":["CATEGORIES","ToolSource","TOOL_SOURCE_LABELS","TOOL_ACTION_LABELS","TOOL_ACTION_SOURCES","TOOL_SOURCE_RANK","INTEGRATION_SOURCES","INTEGRATION_SOURCE_SET","isIntegrationSource","source","MORE_INTEGRATION_SOURCES","MORE_INTEGRATION_SOURCE_SET","isMoreIntegrationSource","MORE_INTEGRATIONS_KEY","MORE_INTEGRATIONS_LABEL","MORE_INTEGRATIONS_RANK","UNRANKED_SOURCE_RANK","toolSourceRank","CONFIG_TOOL_SOURCES"],"mappings":"gFAcO,MAAMA,EAAiD,CAC7D,CAAE,IAAK,OAAQ,MAAO,OAAA,EACtB,CAAE,IAAK,WAAY,MAAO,WAAA,EAC1B,CAAE,IAAK,WAAY,MAAO,WAAA,CAC3B,EAmBO,IAAKC,GAAAA,IACXA,EAAA,SAAW,WACXA,EAAA,QAAU,UACVA,EAAA,YAAc,cACdA,EAAA,YAAc,cACdA,EAAA,KAAO,OACPA,EAAA,QAAU,UACVA,EAAA,YAAc,cACdA,EAAA,QAAU,WACVA,EAAA,cAAgB,iBAChBA,EAAA,MAAQ,QAVGA,IAAAA,GAAA,CAAA,CAAA,EA2CL,MAAMC,EAAiD,CAC5D,SAAsB,WACtB,QAAqB,UACrB,YAAyB,cACzB,YAAyB,cACzB,KAAkB,OAClB,QAAqB,UACrB,YAAyB,cACzB,SAAqB,WACrB,eAA2B,QAC3B,MAAmB,OACrB,EAQaC,EAA0D,CACrE,SAAqB,WACrB,eAA2B,aAC3B,MAAmB,oBACrB,EAqCaC,EAAoC,CAChD,WACA,iBACA,OACD,EASaC,EAAwD,CACnE,SAAsB,EACtB,QAAqB,EAGrB,YAAyB,EACzB,KAAkB,EAClB,QAAqB,EAGrB,YAAyB,EACzB,MAAmB,EAEnB,eAA2B,EAC3B,SAAqB,CACvB,EAUaC,EAAoC,CAChD,UACA,cACA,cACA,OACA,UACA,aACD,EAEMC,EAAyB,IAAI,IAAYD,CAAmB,EAGrDE,EAAuBC,GACnCF,EAAuB,IAAIE,CAAM,EASrBC,EAAyC,CACrD,cACA,aACD,EAEMC,EAA8B,IAAI,IAAYD,CAAwB,EAG/DE,EAA2BH,GACvCE,EAA4B,IAAIF,CAAM,EAQ1BI,EAAwB,oBACxBC,EAA0B,oBAE1BC,EAAyB,EAEhCC,EAAuB,OAAO,KAAKX,CAAgB,EAAE,OAG9CY,EAAkBR,GAC9BJ,EAAiBI,CAAoB,GAAKO,EAa9BE,EAAkE,CAC7E,eAA2B,aAC3B,MAAmB,oBACrB"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const at=require("react/jsx-runtime"),s=require("react"),ft=require("../constants/charLimits.js"),l=require("../constants/steps.js"),gt=t=>t&&typeof t=="object"&&"default"in t?t:{default:t},mt=gt(s),ct=mt.default.createContext(null),Rt=()=>{const t=s.useContext(ct);if(!t)throw new Error("useAgentBuilderContext must be used within an AgentBuilderProvider");return t},bt=(t,r)=>{const a=t.trigger.mode==="custom_intent"?(t.trigger.custom_intent??"").trim().length>0:t.trigger.intents.length>0;return{about:t.name.trim().length>0&&t.name.length<=r.name&&t.description.length<=r.description,trigger:a,response:t.instructions.trim().length>0||(t.guardrail??"").trim().length>0,handover:!0}},St=({value:t,onChange:r,activeStep:a,onStepChange:C,availableTools:m,availableSubAgents:R,availableIntents:A,availableModels:_,configToolTemplates:k,integrationStatus:E,onConnectIntegration:P,validation:M,applicationType:h,charLimits:B,disableStepNavigation:K=!0,onCreateSubAgent:q,onFetchSubAgent:Y,onUpdateSubAgent:j,onImproveSubAgent:y,onImproveToolInstructions:F,children:it})=>{const[ut,lt]=s.useState("about"),b=a??ut,i=l.getStepIndex(b),L=s.useRef(t);L.current=t;const[$,w]=s.useState(0),x=s.useRef({}),H=s.useRef("instructions"),I=s.useCallback((e,n)=>{n?x.current[e]=n:delete x.current[e]},[]),V=s.useCallback(e=>{H.current=e},[]),D=s.useRef(null),G=s.useCallback(e=>{D.current=e},[]),N=s.useCallback(()=>{D.current?.()},[]),U=s.useRef(null),z=s.useCallback(e=>{U.current=e},[]),J=s.useCallback(e=>{U.current?.(e)},[]),O=s.useCallback((e,n,c,g)=>{const u=x.current;(u[H.current]??u.instructions)?.(e,n,c,g)},[]),[Q,p]=s.useState(null),S=s.useRef(null),W=s.useRef(0),T=s.useMemo(()=>({...ft.AGENT_CHAR_LIMITS,...B}),[B]),f=s.useMemo(()=>({...bt(t,T),...M}),[t,T,M]),d=s.useCallback(e=>{const n=l.STEP_KEYS.indexOf(e);n>i&&l.STEP_KEYS.slice(0,n).some(c=>!f[c])||(a===void 0&&lt(e),C?.(e))},[a,C,i,f]),X=s.useCallback(()=>{const e=l.STEP_KEYS[Math.min(i+1,l.STEP_KEYS.length-1)];d(e)},[i,d]),Z=s.useCallback(()=>{const e=l.STEP_KEYS[Math.max(i-1,0)];d(e)},[i,d]),v=s.useCallback(e=>r(e),[r]),tt=s.useCallback((e,n)=>r({[e]:n}),[r]),et=s.useCallback((e,n)=>{const c=L.current;e==="tool"?!((c.configTools??[]).some(u=>u.id===n)||(c.restApiTools??[]).some(u=>u.id===n))&&!c.tools.includes(n)&&r({tools:[...c.tools,n]}):c.subagents.includes(n)||r({subagents:[...c.subagents,n]})},[r]),st=s.useCallback((e,n)=>{const c=e==="tool"?`{{tool:${n}}}`:`{{subagent:${n}}}`,g=o=>o.split(c).join("");S.current={tools:t.tools,subagents:t.subagents,configTools:t.configTools,restApiTools:t.restApiTools,instructions:t.instructions,guardrail:t.guardrail};const u={instructions:g(t.instructions),guardrail:g(t.guardrail??""),...e==="tool"?{tools:t.tools.filter(o=>o!==n),configTools:(t.configTools??[]).filter(o=>o.id!==n),restApiTools:(t.restApiTools??[]).filter(o=>o.id!==n)}:{subagents:t.subagents.filter(o=>o!==n)}};r(u),w(o=>o+1);const rt=e==="tool"?m.find(o=>o.tool_id===n)?.display_name??(t.restApiTools??[]).find(o=>o.id===n)?.name??"Tool":R.find(o=>o.id===n)?.name??"Sub-agent";W.current+=1,p({id:W.current,message:`${e==="tool"?"Tool":"Sub-agent"} "${rt}" removed`})},[m,R,t,r]),nt=s.useCallback(()=>{S.current&&(r(S.current),S.current=null,w(e=>e+1)),p(null)},[r]),ot=s.useCallback(()=>p(null),[]),dt=s.useMemo(()=>({value:t,patch:v,updateField:tt,addReference:et,removeReference:st,mentionResetKey:$,insertMention:O,registerMentionField:I,notifyMentionFocus:V,undoToast:Q,undoRemoval:nt,dismissUndo:ot,activeStep:b,activeIndex:i,goToStep:d,goNext:X,goPrev:Z,isFirstStep:i===0,isLastStep:i===l.STEP_KEYS.length-1,validation:f,isActiveStepValid:f[b],availableTools:m,availableSubAgents:R,availableIntents:A,availableModels:_,configToolTemplates:k,integrationStatus:E,onConnectIntegration:P,applicationType:h,charLimits:T,disableStepNavigation:K,onCreateSubAgent:q,registerSubAgentCreator:G,requestCreateSubAgent:N,registerToolActionHandler:z,requestToolAction:J,onFetchSubAgent:Y,onUpdateSubAgent:j,onImproveSubAgent:y,onImproveToolInstructions:F}),[t,v,tt,et,st,$,O,I,V,Q,nt,ot,b,i,d,X,Z,f,m,R,A,_,k,E,P,h,T,K,q,G,N,z,J,Y,j,y,F]);return at.jsx(ct.Provider,{value:dt,children:it})};exports.AgentBuilderProvider=St;exports.useAgentBuilderContext=Rt;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const gt=require("react/jsx-runtime"),s=require("react"),at=require("../constants/charLimits.js"),l=require("../constants/steps.js"),mt=t=>t&&typeof t=="object"&&"default"in t?t:{default:t},Rt=mt(s),it=Rt.default.createContext(null),St=()=>{const t=s.useContext(it);if(!t)throw new Error("useAgentBuilderContext must be used within an AgentBuilderProvider");return t},Tt=(t,r)=>{const f=t.trigger.mode==="custom_intent"?(t.trigger.custom_intent??"").trim().length>0:t.trigger.intents.length>0;return{about:t.name.trim().length>0&&t.name.length<=r.name&&t.description.length<=r.description,trigger:f,response:t.instructions.trim().length>0||(t.guardrail??"").trim().length>0,handover:!0}},bt=({value:t,onChange:r,activeStep:f,onStepChange:C,availableTools:m,availableSubAgents:R,availableIntents:A,availableModels:_,configToolTemplates:k,integrationStatus:E,onConnectIntegration:P,variablesData:M,validation:h,applicationType:B,charLimits:K,disableStepNavigation:q=!0,onCreateSubAgent:Y,onFetchSubAgent:j,onUpdateSubAgent:y,onImproveSubAgent:F,onImproveToolInstructions:L,children:ut})=>{const[lt,dt]=s.useState("about"),S=f??lt,i=l.getStepIndex(S),$=s.useRef(t);$.current=t;const[w,H]=s.useState(0),x=s.useRef({}),I=s.useRef("instructions"),V=s.useCallback((e,n)=>{n?x.current[e]=n:delete x.current[e]},[]),G=s.useCallback(e=>{I.current=e},[]),N=s.useRef(null),U=s.useCallback(e=>{N.current=e},[]),z=s.useCallback(()=>{N.current?.()},[]),D=s.useRef(null),J=s.useCallback(e=>{D.current=e},[]),O=s.useCallback(e=>{D.current?.(e)},[]),Q=s.useCallback((e,n,c,a)=>{const u=x.current;(u[I.current]??u.instructions)?.(e,n,c,a)},[]),[W,p]=s.useState(null),T=s.useRef(null),X=s.useRef(0),b=s.useMemo(()=>({...at.AGENT_CHAR_LIMITS,...K}),[K]),g=s.useMemo(()=>({...Tt(t,b),...h}),[t,b,h]),d=s.useCallback(e=>{const n=l.STEP_KEYS.indexOf(e);n>i&&l.STEP_KEYS.slice(0,n).some(c=>!g[c])||(f===void 0&&dt(e),C?.(e))},[f,C,i,g]),Z=s.useCallback(()=>{const e=l.STEP_KEYS[Math.min(i+1,l.STEP_KEYS.length-1)];d(e)},[i,d]),v=s.useCallback(()=>{const e=l.STEP_KEYS[Math.max(i-1,0)];d(e)},[i,d]),tt=s.useCallback(e=>r(e),[r]),et=s.useCallback((e,n)=>r({[e]:n}),[r]),st=s.useCallback((e,n)=>{const c=$.current;e==="tool"?!((c.configTools??[]).some(u=>u.id===n)||(c.restApiTools??[]).some(u=>u.id===n))&&!c.tools.includes(n)&&r({tools:[...c.tools,n]}):c.subagents.includes(n)||r({subagents:[...c.subagents,n]})},[r]),nt=s.useCallback((e,n)=>{const c=e==="tool"?`{{tool:${n}}}`:`{{subagent:${n}}}`,a=o=>o.split(c).join("");T.current={tools:t.tools,subagents:t.subagents,configTools:t.configTools,restApiTools:t.restApiTools,instructions:t.instructions,guardrail:t.guardrail};const u={instructions:a(t.instructions),guardrail:a(t.guardrail??""),...e==="tool"?{tools:t.tools.filter(o=>o!==n),configTools:(t.configTools??[]).filter(o=>o.id!==n),restApiTools:(t.restApiTools??[]).filter(o=>o.id!==n)}:{subagents:t.subagents.filter(o=>o!==n)}};r(u),H(o=>o+1);const ct=e==="tool"?m.find(o=>o.tool_id===n)?.display_name??(t.restApiTools??[]).find(o=>o.id===n)?.name??"Tool":R.find(o=>o.id===n)?.name??"Sub-agent";X.current+=1,p({id:X.current,message:`${e==="tool"?"Tool":"Sub-agent"} "${ct}" removed`})},[m,R,t,r]),ot=s.useCallback(()=>{T.current&&(r(T.current),T.current=null,H(e=>e+1)),p(null)},[r]),rt=s.useCallback(()=>p(null),[]),ft=s.useMemo(()=>({value:t,patch:tt,updateField:et,addReference:st,removeReference:nt,mentionResetKey:w,insertMention:Q,registerMentionField:V,notifyMentionFocus:G,undoToast:W,undoRemoval:ot,dismissUndo:rt,activeStep:S,activeIndex:i,goToStep:d,goNext:Z,goPrev:v,isFirstStep:i===0,isLastStep:i===l.STEP_KEYS.length-1,validation:g,isActiveStepValid:g[S],availableTools:m,availableSubAgents:R,availableIntents:A,availableModels:_,configToolTemplates:k,integrationStatus:E,onConnectIntegration:P,variablesData:M,applicationType:B,charLimits:b,disableStepNavigation:q,onCreateSubAgent:Y,registerSubAgentCreator:U,requestCreateSubAgent:z,registerToolActionHandler:J,requestToolAction:O,onFetchSubAgent:j,onUpdateSubAgent:y,onImproveSubAgent:F,onImproveToolInstructions:L}),[t,tt,et,st,nt,w,Q,V,G,W,ot,rt,S,i,d,Z,v,g,m,R,A,_,k,E,P,M,B,b,q,Y,U,z,J,O,j,y,F,L]);return gt.jsx(it.Provider,{value:ft,children:ut})};exports.AgentBuilderProvider=bt;exports.useAgentBuilderContext=St;
2
2
  //# sourceMappingURL=AgentBuilderContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentBuilderContext.js","sources":["../../../../../src/components/agent-builder/context/AgentBuilderContext.tsx"],"sourcesContent":["import type { ApplicationType } from '@bikdotai/bik-models/growth';\nimport React, {\n\tuseCallback,\n\tuseContext,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport {\n\tAgentTool,\n\tAgentValue,\n\tConfigToolKey,\n\tIntentOption,\n\tModelOption,\n\tParamsBlob,\n\tStepKey,\n\tStepValidation,\n\tSubAgentDraft,\n\tSubAgentRef,\n} from '../AgentBuilder.model';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport { getStepIndex, STEP_KEYS } from '../constants/steps';\nimport type { ToolSource } from '../constants/tools';\n\n/** Mention-capable text fields in Step 3 (both store firebase token text). */\nexport type MentionFieldKey = 'instructions' | 'guardrail';\ntype MentionInsertFn = (\n\tkind: 'tool' | 'subagent',\n\tid: string,\n\tlabel?: string,\n\t/** Tool source, for the chip's leading icon. Pass it for a JUST-created custom\n\t * tool that isn't in the editor's mention list yet (else the chip has no icon\n\t * until reload); existing tools resolve it from the list. */\n\tsource?: string,\n) => void;\n\n/** Toast shown after a tool / sub-agent is removed, offering an undo. */\nexport interface UndoToastState {\n\t/** Bumped per removal so the toast timer restarts. */\n\tid: number;\n\tmessage: string;\n}\n\nexport interface AgentBuilderContextShape {\n\t/** Controlled value relayed from props. */\n\tvalue: AgentValue;\n\t/** Patch one or more fields. */\n\tpatch: (partial: Partial<AgentValue>) => void;\n\t/** Patch a single field. */\n\tupdateField: <K extends keyof AgentValue>(key: K, val: AgentValue[K]) => void;\n\t/**\n\t * Remove a tool / sub-agent everywhere: drops it from the list AND strips ALL\n\t * its `{{tool:KEY}}` / `{{subagent:ID}}` tokens from BOTH the instructions and\n\t * the guardrails, remounts the editors, and raises an undo toast.\n\t */\n\tremoveReference: (kind: 'tool' | 'subagent', id: string) => void;\n\t/**\n\t * Append a tool / sub-agent id to its list (deduped), reading the LATEST value\n\t * via a ref. Use this instead of `patch({ tools: [...value.tools, id] })` from\n\t * any handler that may be captured with a stale `value` — notably the `@`\n\t * editor's mount-time `onSelect`, which would otherwise keep only the last pick.\n\t */\n\taddReference: (kind: 'tool' | 'subagent', id: string) => void;\n\t/** Remount signal for the mention editors after an external edit. */\n\tmentionResetKey: number;\n\t/**\n\t * Insert a tool / sub-agent mention chip at the last cursor position of\n\t * whichever mention field was focused most recently (Instructions or\n\t * Guardrails). `label` overrides the chip text (e.g. a just-created sub-agent\n\t * not yet in the available list).\n\t */\n\tinsertMention: MentionInsertFn;\n\t/** A mention field registers its editor-backed insert here (internal). */\n\tregisterMentionField: (\n\t\tfieldKey: MentionFieldKey,\n\t\tfn: MentionInsertFn | null,\n\t) => void;\n\t/** A mention field reports focus so inserts target it (internal). */\n\tnotifyMentionFocus: (fieldKey: MentionFieldKey) => void;\n\n\t// Undo (post-removal)\n\t/** Non-null while the undo toast should be visible. */\n\tundoToast: UndoToastState | null;\n\t/** Restore the last removed tool / sub-agent (list + stripped tokens). */\n\tundoRemoval: () => void;\n\t/** Dismiss the undo toast without restoring. */\n\tdismissUndo: () => void;\n\n\t// Navigation\n\tactiveStep: StepKey;\n\tactiveIndex: number;\n\tgoToStep: (step: StepKey) => void;\n\tgoNext: () => void;\n\tgoPrev: () => void;\n\tisFirstStep: boolean;\n\tisLastStep: boolean;\n\n\t// Validation\n\tvalidation: StepValidation;\n\tisActiveStepValid: boolean;\n\n\t// Reference data\n\tavailableTools: AgentTool[];\n\tavailableSubAgents: SubAgentRef[];\n\tavailableIntents: IntentOption[];\n\tavailableModels: ModelOption[];\n\t/**\n\t * Backend templates for the shared-drawer tools (email / Slack), keyed by\n\t * `tool_key`. A present key drives its dynamic form + enables its tool action.\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` renders a \"Connect\" row in the `@` picker instead of drilling in;\n\t * `true`/absent renders normally. Fed by the consumer via `integrationStatus`.\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/** Host application context (e.g. MANIFEST) — drives tool-chip labelling. */\n\tapplicationType?: ApplicationType;\n\t/** Resolved per-field character limits (consumer overrides merged over defaults). */\n\tcharLimits: AgentCharLimits;\n\t/** When true, step-rail items are not clickable (Back / Next only). */\n\tdisableStepNavigation: boolean;\n\n\t// Sub-agent creation (Step 3 drawer)\n\t/** Persist a new sub-agent and resolve with its ref. Omit to hide the create flow. */\n\tonCreateSubAgent?: (draft: SubAgentDraft) => Promise<SubAgentRef>;\n\t/**\n\t * Step 3 registers its \"open create-sub-agent drawer\" action here so the `@`\n\t * picker's \"Create new\" row can trigger it. Pass `null` to unregister.\n\t */\n\tregisterSubAgentCreator: (fn: (() => void) | null) => void;\n\t/** Open the create-sub-agent drawer (no-op until Step 3 registers it). */\n\trequestCreateSubAgent: () => void;\n\t/**\n\t * Step 3 registers its \"open the drawer for this built-in tool action\"\n\t * (Rest API / email handover / Slack) handler here so the `@` reference picker\n\t * can trigger it. Pass `null` to unregister.\n\t */\n\tregisterToolActionHandler: (\n\t\tfn: ((source: ToolSource) => void) | null,\n\t) => void;\n\t/** Open a built-in tool action's drawer (no-op until Step 3 registers it). */\n\trequestToolAction: (source: ToolSource) => void;\n\t/** Fetch a sub-agent's editable data (Configure). Omit to hide Configure. */\n\tonFetchSubAgent?: (id: string) => Promise<SubAgentDraft>;\n\t/** Persist edits to an existing sub-agent. */\n\tonUpdateSubAgent?: (id: string, draft: SubAgentDraft) => Promise<SubAgentRef>;\n\t/** Optional \"Improve with AI\" for the drawer's instructions / guardrails. */\n\tonImproveSubAgent?: (\n\t\tkind: 'instructions' | 'guardrail',\n\t\ttext: string,\n\t) => Promise<string>;\n\t/** Optional \"Improve with AI\" for the Rest API / email-handover tool drawers. */\n\tonImproveToolInstructions?: (text: string) => Promise<string>;\n}\n\nconst AgentBuilderContext =\n\tReact.createContext<AgentBuilderContextShape | null>(null);\n\nexport const useAgentBuilderContext = (): AgentBuilderContextShape => {\n\tconst ctx = useContext(AgentBuilderContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t'useAgentBuilderContext must be used within an AgentBuilderProvider',\n\t\t);\n\t}\n\treturn ctx;\n};\n\n/** Validity derived purely from the current value (no effects). */\nconst deriveValidation = (\n\tvalue: AgentValue,\n\tlimits: AgentCharLimits,\n): StepValidation => {\n\tconst triggerValid =\n\t\tvalue.trigger.mode === 'custom_intent'\n\t\t\t? (value.trigger.custom_intent ?? '').trim().length > 0\n\t\t\t: value.trigger.intents.length > 0;\n\n\treturn {\n\t\tabout:\n\t\t\tvalue.name.trim().length > 0 &&\n\t\t\tvalue.name.length <= limits.name &&\n\t\t\tvalue.description.length <= limits.description,\n\t\ttrigger: triggerValid,\n\t\t// At least one of Instructions / Guardrails must be filled.\n\t\tresponse:\n\t\t\tvalue.instructions.trim().length > 0 ||\n\t\t\t(value.guardrail ?? '').trim().length > 0,\n\t\t// Optional until specced further — never blocks go-live.\n\t\thandover: true,\n\t};\n};\n\ninterface ProviderProps {\n\tvalue: AgentValue;\n\tonChange: (patch: Partial<AgentValue>) => void;\n\tactiveStep?: StepKey;\n\tonStepChange?: (step: StepKey) => void;\n\tavailableTools: AgentTool[];\n\tavailableSubAgents: SubAgentRef[];\n\tavailableIntents: IntentOption[];\n\tavailableModels: ModelOption[];\n\tconfigToolTemplates?: Partial<Record<ConfigToolKey, ParamsBlob>>;\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\tonConnectIntegration?: (source: ToolSource) => void;\n\tvalidation?: Partial<StepValidation>;\n\tapplicationType?: ApplicationType;\n\tcharLimits?: Partial<AgentCharLimits>;\n\tdisableStepNavigation?: boolean;\n\tonCreateSubAgent?: (draft: SubAgentDraft) => Promise<SubAgentRef>;\n\tonFetchSubAgent?: (id: string) => Promise<SubAgentDraft>;\n\tonUpdateSubAgent?: (id: string, draft: SubAgentDraft) => Promise<SubAgentRef>;\n\tonImproveSubAgent?: (\n\t\tkind: 'instructions' | 'guardrail',\n\t\ttext: string,\n\t) => Promise<string>;\n\tonImproveToolInstructions?: (text: string) => Promise<string>;\n\tchildren: React.ReactNode;\n}\n\nexport const AgentBuilderProvider: React.FC<ProviderProps> = ({\n\tvalue,\n\tonChange,\n\tactiveStep: controlledStep,\n\tonStepChange,\n\tavailableTools,\n\tavailableSubAgents,\n\tavailableIntents,\n\tavailableModels,\n\tconfigToolTemplates,\n\tintegrationStatus,\n\tonConnectIntegration,\n\tvalidation: validationOverride,\n\tapplicationType,\n\tcharLimits: charLimitsOverride,\n\tdisableStepNavigation = true,\n\tonCreateSubAgent,\n\tonFetchSubAgent,\n\tonUpdateSubAgent,\n\tonImproveSubAgent,\n\tonImproveToolInstructions,\n\tchildren,\n}) => {\n\tconst [internalStep, setInternalStep] = useState<StepKey>('about');\n\tconst activeStep = controlledStep ?? internalStep;\n\tconst activeIndex = getStepIndex(activeStep);\n\n\t// Latest value, so closure-captured handlers (e.g. the `@` editor's mount-time\n\t// mention onSelect) append against the current lists, not a stale snapshot.\n\tconst valueRef = useRef(value);\n\tvalueRef.current = value;\n\n\t// Bumped when a mention field is edited from OUTSIDE its editor (removing a\n\t// tool from the side list, undo), forcing the mention editors to remount.\n\tconst [mentionResetKey, setMentionResetKey] = useState(0);\n\n\t// Each mention field registers an editor-backed insert fn + reports focus, so\n\t// side-panel adds drop a chip into the last-focused field at its cursor.\n\tconst mentionInsertersRef = useRef<\n\t\tPartial<Record<MentionFieldKey, MentionInsertFn>>\n\t>({});\n\tconst lastFocusedFieldRef = useRef<MentionFieldKey>('instructions');\n\tconst registerMentionField = useCallback(\n\t\t(fieldKey: MentionFieldKey, fn: MentionInsertFn | null) => {\n\t\t\tif (fn) {\n\t\t\t\tmentionInsertersRef.current[fieldKey] = fn;\n\t\t\t} else {\n\t\t\t\tdelete mentionInsertersRef.current[fieldKey];\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\tconst notifyMentionFocus = useCallback((fieldKey: MentionFieldKey) => {\n\t\tlastFocusedFieldRef.current = fieldKey;\n\t}, []);\n\n\t// Step 3 registers its drawer opener here; the `@` picker's \"Create new\" calls it.\n\tconst subAgentCreatorRef = useRef<(() => void) | null>(null);\n\tconst registerSubAgentCreator = useCallback((fn: (() => void) | null) => {\n\t\tsubAgentCreatorRef.current = fn;\n\t}, []);\n\tconst requestCreateSubAgent = useCallback(() => {\n\t\tsubAgentCreatorRef.current?.();\n\t}, []);\n\n\t// Step 3 registers a dispatcher that opens a built-in tool action's drawer.\n\tconst toolActionHandlerRef = useRef<((source: ToolSource) => void) | null>(\n\t\tnull,\n\t);\n\tconst registerToolActionHandler = useCallback(\n\t\t(fn: ((source: ToolSource) => void) | null) => {\n\t\t\ttoolActionHandlerRef.current = fn;\n\t\t},\n\t\t[],\n\t);\n\tconst requestToolAction = useCallback((source: ToolSource) => {\n\t\ttoolActionHandlerRef.current?.(source);\n\t}, []);\n\tconst insertMention = useCallback<MentionInsertFn>(\n\t\t(kind, id, label, source) => {\n\t\t\tconst inserters = mentionInsertersRef.current;\n\t\t\tconst target =\n\t\t\t\tinserters[lastFocusedFieldRef.current] ?? inserters.instructions;\n\t\t\ttarget?.(kind, id, label, source);\n\t\t},\n\t\t[],\n\t);\n\n\t// Undo state for the most recent removal.\n\tconst [undoToast, setUndoToast] = useState<UndoToastState | null>(null);\n\tconst undoSnapshotRef = useRef<Partial<AgentValue> | null>(null);\n\tconst undoIdRef = useRef(0);\n\n\t// Consumer overrides merged over the built-in defaults (name 60, rest 1000).\n\tconst charLimits = useMemo<AgentCharLimits>(\n\t\t() => ({ ...AGENT_CHAR_LIMITS, ...charLimitsOverride }),\n\t\t[charLimitsOverride],\n\t);\n\n\tconst validation: StepValidation = useMemo(\n\t\t() => ({ ...deriveValidation(value, charLimits), ...validationOverride }),\n\t\t[value, charLimits, validationOverride],\n\t);\n\n\tconst goToStep = useCallback(\n\t\t(step: StepKey) => {\n\t\t\t// Forward jumps (side rail) must not skip past an incomplete step —\n\t\t\t// otherwise an agent with an empty step 3 could reach step 4 and be\n\t\t\t// published. Going back is always allowed.\n\t\t\tconst targetIndex = STEP_KEYS.indexOf(step);\n\t\t\tif (\n\t\t\t\ttargetIndex > activeIndex &&\n\t\t\t\tSTEP_KEYS.slice(0, targetIndex).some((k) => !validation[k])\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (controlledStep === undefined) {\n\t\t\t\tsetInternalStep(step);\n\t\t\t}\n\t\t\tonStepChange?.(step);\n\t\t},\n\t\t[controlledStep, onStepChange, activeIndex, validation],\n\t);\n\n\tconst goNext = useCallback(() => {\n\t\tconst next = STEP_KEYS[Math.min(activeIndex + 1, STEP_KEYS.length - 1)];\n\t\tgoToStep(next);\n\t}, [activeIndex, goToStep]);\n\n\tconst goPrev = useCallback(() => {\n\t\tconst prev = STEP_KEYS[Math.max(activeIndex - 1, 0)];\n\t\tgoToStep(prev);\n\t}, [activeIndex, goToStep]);\n\n\tconst patch = useCallback(\n\t\t(partial: Partial<AgentValue>) => onChange(partial),\n\t\t[onChange],\n\t);\n\n\tconst updateField = useCallback(\n\t\t<K extends keyof AgentValue>(key: K, val: AgentValue[K]) =>\n\t\t\tonChange({ [key]: val } as Partial<AgentValue>),\n\t\t[onChange],\n\t);\n\n\tconst addReference = useCallback(\n\t\t(kind: 'tool' | 'subagent', id: string) => {\n\t\t\tconst v = valueRef.current;\n\t\t\tif (kind === 'tool') {\n\t\t\t\t// Custom tools (Rest API / email / Slack) track themselves on their own\n\t\t\t\t// lists; only catalog/native ids belong in `tools`. Picking an EXISTING\n\t\t\t\t// custom tool from the `@` picker must not leak its id in here — on save\n\t\t\t\t// it becomes a bogus native ref and create-agent validation rejects it.\n\t\t\t\tconst isCustom =\n\t\t\t\t\t(v.configTools ?? []).some((t) => t.id === id) ||\n\t\t\t\t\t(v.restApiTools ?? []).some((t) => t.id === id);\n\t\t\t\tif (!isCustom && !v.tools.includes(id)) {\n\t\t\t\t\tonChange({ tools: [...v.tools, id] });\n\t\t\t\t}\n\t\t\t} else if (!v.subagents.includes(id)) {\n\t\t\t\tonChange({ subagents: [...v.subagents, id] });\n\t\t\t}\n\t\t},\n\t\t[onChange],\n\t);\n\n\tconst removeReference = useCallback(\n\t\t(kind: 'tool' | 'subagent', id: string) => {\n\t\t\t// Tokens store the id for both kinds (a tool's id is its tool_id).\n\t\t\tconst token = kind === 'tool' ? `{{tool:${id}}}` : `{{subagent:${id}}}`;\n\t\t\tconst strip = (text: string) => text.split(token).join('');\n\n\t\t\t// Snapshot every field a removal touches, for undo. Custom tools (Rest\n\t\t\t// API / email / Slack) live on their own lists, so include them too.\n\t\t\tundoSnapshotRef.current = {\n\t\t\t\ttools: value.tools,\n\t\t\t\tsubagents: value.subagents,\n\t\t\t\tconfigTools: value.configTools,\n\t\t\t\trestApiTools: value.restApiTools,\n\t\t\t\tinstructions: value.instructions,\n\t\t\t\tguardrail: value.guardrail,\n\t\t\t};\n\n\t\t\tconst next: Partial<AgentValue> = {\n\t\t\t\tinstructions: strip(value.instructions),\n\t\t\t\tguardrail: strip(value.guardrail ?? ''),\n\t\t\t\t...(kind === 'tool'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t// A tool id may be a catalog tool OR an inline custom tool — drop\n\t\t\t\t\t\t\t// it from whichever list holds it (the others are no-op filters).\n\t\t\t\t\t\t\ttools: value.tools.filter((t) => t !== id),\n\t\t\t\t\t\t\tconfigTools: (value.configTools ?? []).filter((t) => t.id !== id),\n\t\t\t\t\t\t\trestApiTools: (value.restApiTools ?? []).filter(\n\t\t\t\t\t\t\t\t(t) => t.id !== id,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t }\n\t\t\t\t\t: { subagents: value.subagents.filter((s) => s !== id) }),\n\t\t\t};\n\t\t\tonChange(next);\n\t\t\tsetMentionResetKey((k) => k + 1);\n\n\t\t\tconst label =\n\t\t\t\tkind === 'tool'\n\t\t\t\t\t? availableTools.find((t) => t.tool_id === id)?.display_name ??\n\t\t\t\t\t (value.restApiTools ?? []).find((t) => t.id === id)?.name ??\n\t\t\t\t\t 'Tool'\n\t\t\t\t\t: availableSubAgents.find((s) => s.id === id)?.name ?? 'Sub-agent';\n\t\t\tundoIdRef.current += 1;\n\t\t\tsetUndoToast({\n\t\t\t\tid: undoIdRef.current,\n\t\t\t\tmessage: `${kind === 'tool' ? 'Tool' : 'Sub-agent'} \"${label}\" removed`,\n\t\t\t});\n\t\t},\n\t\t[availableTools, availableSubAgents, value, onChange],\n\t);\n\n\tconst undoRemoval = useCallback(() => {\n\t\tif (undoSnapshotRef.current) {\n\t\t\tonChange(undoSnapshotRef.current);\n\t\t\tundoSnapshotRef.current = null;\n\t\t\tsetMentionResetKey((k) => k + 1);\n\t\t}\n\t\tsetUndoToast(null);\n\t}, [onChange]);\n\n\tconst dismissUndo = useCallback(() => setUndoToast(null), []);\n\n\tconst ctx = useMemo<AgentBuilderContextShape>(\n\t\t() => ({\n\t\t\tvalue,\n\t\t\tpatch,\n\t\t\tupdateField,\n\t\t\taddReference,\n\t\t\tremoveReference,\n\t\t\tmentionResetKey,\n\t\t\tinsertMention,\n\t\t\tregisterMentionField,\n\t\t\tnotifyMentionFocus,\n\t\t\tundoToast,\n\t\t\tundoRemoval,\n\t\t\tdismissUndo,\n\t\t\tactiveStep,\n\t\t\tactiveIndex,\n\t\t\tgoToStep,\n\t\t\tgoNext,\n\t\t\tgoPrev,\n\t\t\tisFirstStep: activeIndex === 0,\n\t\t\tisLastStep: activeIndex === STEP_KEYS.length - 1,\n\t\t\tvalidation,\n\t\t\tisActiveStepValid: validation[activeStep],\n\t\t\tavailableTools,\n\t\t\tavailableSubAgents,\n\t\t\tavailableIntents,\n\t\t\tavailableModels,\n\t\t\tconfigToolTemplates,\n\t\t\tintegrationStatus,\n\t\t\tonConnectIntegration,\n\t\t\tapplicationType,\n\t\t\tcharLimits,\n\t\t\tdisableStepNavigation,\n\t\t\tonCreateSubAgent,\n\t\t\tregisterSubAgentCreator,\n\t\t\trequestCreateSubAgent,\n\t\t\tregisterToolActionHandler,\n\t\t\trequestToolAction,\n\t\t\tonFetchSubAgent,\n\t\t\tonUpdateSubAgent,\n\t\t\tonImproveSubAgent,\n\t\t\tonImproveToolInstructions,\n\t\t}),\n\t\t[\n\t\t\tvalue,\n\t\t\tpatch,\n\t\t\tupdateField,\n\t\t\taddReference,\n\t\t\tremoveReference,\n\t\t\tmentionResetKey,\n\t\t\tinsertMention,\n\t\t\tregisterMentionField,\n\t\t\tnotifyMentionFocus,\n\t\t\tundoToast,\n\t\t\tundoRemoval,\n\t\t\tdismissUndo,\n\t\t\tactiveStep,\n\t\t\tactiveIndex,\n\t\t\tgoToStep,\n\t\t\tgoNext,\n\t\t\tgoPrev,\n\t\t\tvalidation,\n\t\t\tavailableTools,\n\t\t\tavailableSubAgents,\n\t\t\tavailableIntents,\n\t\t\tavailableModels,\n\t\t\tconfigToolTemplates,\n\t\t\tintegrationStatus,\n\t\t\tonConnectIntegration,\n\t\t\tapplicationType,\n\t\t\tcharLimits,\n\t\t\tdisableStepNavigation,\n\t\t\tonCreateSubAgent,\n\t\t\tregisterSubAgentCreator,\n\t\t\trequestCreateSubAgent,\n\t\t\tregisterToolActionHandler,\n\t\t\trequestToolAction,\n\t\t\tonFetchSubAgent,\n\t\t\tonUpdateSubAgent,\n\t\t\tonImproveSubAgent,\n\t\t\tonImproveToolInstructions,\n\t\t],\n\t);\n\n\treturn (\n\t\t<AgentBuilderContext.Provider value={ctx}>\n\t\t\t{children}\n\t\t</AgentBuilderContext.Provider>\n\t);\n};\n"],"names":["AgentBuilderContext","React","useAgentBuilderContext","ctx","useContext","deriveValidation","value","limits","triggerValid","AgentBuilderProvider","onChange","controlledStep","onStepChange","availableTools","availableSubAgents","availableIntents","availableModels","configToolTemplates","integrationStatus","onConnectIntegration","validationOverride","applicationType","charLimitsOverride","disableStepNavigation","onCreateSubAgent","onFetchSubAgent","onUpdateSubAgent","onImproveSubAgent","onImproveToolInstructions","children","internalStep","setInternalStep","useState","activeStep","activeIndex","getStepIndex","valueRef","useRef","mentionResetKey","setMentionResetKey","mentionInsertersRef","lastFocusedFieldRef","registerMentionField","useCallback","fieldKey","fn","notifyMentionFocus","subAgentCreatorRef","registerSubAgentCreator","requestCreateSubAgent","toolActionHandlerRef","registerToolActionHandler","requestToolAction","source","insertMention","kind","id","label","inserters","undoToast","setUndoToast","undoSnapshotRef","undoIdRef","charLimits","useMemo","AGENT_CHAR_LIMITS","validation","goToStep","step","targetIndex","STEP_KEYS","k","goNext","next","goPrev","prev","patch","partial","updateField","key","val","addReference","v","t","removeReference","token","strip","text","s","undoRemoval","dismissUndo"],"mappings":"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"}
1
+ {"version":3,"file":"AgentBuilderContext.js","sources":["../../../../../src/components/agent-builder/context/AgentBuilderContext.tsx"],"sourcesContent":["import type { ApplicationType } from '@bikdotai/bik-models/growth';\nimport React, {\n\tuseCallback,\n\tuseContext,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type { VariableListInterfaceV3 } from '../../variable-picker-v3/model';\nimport {\n\tAgentTool,\n\tAgentValue,\n\tConfigToolKey,\n\tIntentOption,\n\tModelOption,\n\tParamsBlob,\n\tStepKey,\n\tStepValidation,\n\tSubAgentDraft,\n\tSubAgentRef,\n} from '../AgentBuilder.model';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport type { AgentCharLimits } from '../constants/charLimits';\nimport { getStepIndex, STEP_KEYS } from '../constants/steps';\nimport type { ToolSource } from '../constants/tools';\n\n/** Mention-capable text fields in Step 3 (both store firebase token text). */\nexport type MentionFieldKey = 'instructions' | 'guardrail';\ntype MentionInsertFn = (\n\tkind: 'tool' | 'subagent',\n\tid: string,\n\tlabel?: string,\n\t/** Tool source, for the chip's leading icon. Pass it for a JUST-created custom\n\t * tool that isn't in the editor's mention list yet (else the chip has no icon\n\t * until reload); existing tools resolve it from the list. */\n\tsource?: string,\n) => void;\n\n/** Toast shown after a tool / sub-agent is removed, offering an undo. */\nexport interface UndoToastState {\n\t/** Bumped per removal so the toast timer restarts. */\n\tid: number;\n\tmessage: string;\n}\n\nexport interface AgentBuilderContextShape {\n\t/** Controlled value relayed from props. */\n\tvalue: AgentValue;\n\t/** Patch one or more fields. */\n\tpatch: (partial: Partial<AgentValue>) => void;\n\t/** Patch a single field. */\n\tupdateField: <K extends keyof AgentValue>(key: K, val: AgentValue[K]) => void;\n\t/**\n\t * Remove a tool / sub-agent everywhere: drops it from the list AND strips ALL\n\t * its `{{tool:KEY}}` / `{{subagent:ID}}` tokens from BOTH the instructions and\n\t * the guardrails, remounts the editors, and raises an undo toast.\n\t */\n\tremoveReference: (kind: 'tool' | 'subagent', id: string) => void;\n\t/**\n\t * Append a tool / sub-agent id to its list (deduped), reading the LATEST value\n\t * via a ref. Use this instead of `patch({ tools: [...value.tools, id] })` from\n\t * any handler that may be captured with a stale `value` — notably the `@`\n\t * editor's mount-time `onSelect`, which would otherwise keep only the last pick.\n\t */\n\taddReference: (kind: 'tool' | 'subagent', id: string) => void;\n\t/** Remount signal for the mention editors after an external edit. */\n\tmentionResetKey: number;\n\t/**\n\t * Insert a tool / sub-agent mention chip at the last cursor position of\n\t * whichever mention field was focused most recently (Instructions or\n\t * Guardrails). `label` overrides the chip text (e.g. a just-created sub-agent\n\t * not yet in the available list).\n\t */\n\tinsertMention: MentionInsertFn;\n\t/** A mention field registers its editor-backed insert here (internal). */\n\tregisterMentionField: (\n\t\tfieldKey: MentionFieldKey,\n\t\tfn: MentionInsertFn | null,\n\t) => void;\n\t/** A mention field reports focus so inserts target it (internal). */\n\tnotifyMentionFocus: (fieldKey: MentionFieldKey) => void;\n\n\t// Undo (post-removal)\n\t/** Non-null while the undo toast should be visible. */\n\tundoToast: UndoToastState | null;\n\t/** Restore the last removed tool / sub-agent (list + stripped tokens). */\n\tundoRemoval: () => void;\n\t/** Dismiss the undo toast without restoring. */\n\tdismissUndo: () => void;\n\n\t// Navigation\n\tactiveStep: StepKey;\n\tactiveIndex: number;\n\tgoToStep: (step: StepKey) => void;\n\tgoNext: () => void;\n\tgoPrev: () => void;\n\tisFirstStep: boolean;\n\tisLastStep: boolean;\n\n\t// Validation\n\tvalidation: StepValidation;\n\tisActiveStepValid: boolean;\n\n\t// Reference data\n\tavailableTools: AgentTool[];\n\tavailableSubAgents: SubAgentRef[];\n\tavailableIntents: IntentOption[];\n\tavailableModels: ModelOption[];\n\t/**\n\t * Backend templates for the shared-drawer tools (email / Slack), keyed by\n\t * `tool_key`. A present key drives its dynamic form + enables its tool action.\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` renders a \"Connect\" row in the `@` picker instead of drilling in;\n\t * `true`/absent renders normally. Fed by the consumer via `integrationStatus`.\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/**\n\t * Variable catalog for the `@` picker's \"Variables\" view. Absent / empty →\n\t * the category is hidden. Fed by the consumer via `variablesData`.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\n\t/** Host application context (e.g. MANIFEST) — drives tool-chip labelling. */\n\tapplicationType?: ApplicationType;\n\t/** Resolved per-field character limits (consumer overrides merged over defaults). */\n\tcharLimits: AgentCharLimits;\n\t/** When true, step-rail items are not clickable (Back / Next only). */\n\tdisableStepNavigation: boolean;\n\n\t// Sub-agent creation (Step 3 drawer)\n\t/** Persist a new sub-agent and resolve with its ref. Omit to hide the create flow. */\n\tonCreateSubAgent?: (draft: SubAgentDraft) => Promise<SubAgentRef>;\n\t/**\n\t * Step 3 registers its \"open create-sub-agent drawer\" action here so the `@`\n\t * picker's \"Create new\" row can trigger it. Pass `null` to unregister.\n\t */\n\tregisterSubAgentCreator: (fn: (() => void) | null) => void;\n\t/** Open the create-sub-agent drawer (no-op until Step 3 registers it). */\n\trequestCreateSubAgent: () => void;\n\t/**\n\t * Step 3 registers its \"open the drawer for this built-in tool action\"\n\t * (Rest API / email handover / Slack) handler here so the `@` reference picker\n\t * can trigger it. Pass `null` to unregister.\n\t */\n\tregisterToolActionHandler: (\n\t\tfn: ((source: ToolSource) => void) | null,\n\t) => void;\n\t/** Open a built-in tool action's drawer (no-op until Step 3 registers it). */\n\trequestToolAction: (source: ToolSource) => void;\n\t/** Fetch a sub-agent's editable data (Configure). Omit to hide Configure. */\n\tonFetchSubAgent?: (id: string) => Promise<SubAgentDraft>;\n\t/** Persist edits to an existing sub-agent. */\n\tonUpdateSubAgent?: (id: string, draft: SubAgentDraft) => Promise<SubAgentRef>;\n\t/** Optional \"Improve with AI\" for the drawer's instructions / guardrails. */\n\tonImproveSubAgent?: (\n\t\tkind: 'instructions' | 'guardrail',\n\t\ttext: string,\n\t) => Promise<string>;\n\t/** Optional \"Improve with AI\" for the Rest API / email-handover tool drawers. */\n\tonImproveToolInstructions?: (text: string) => Promise<string>;\n}\n\nconst AgentBuilderContext =\n\tReact.createContext<AgentBuilderContextShape | null>(null);\n\nexport const useAgentBuilderContext = (): AgentBuilderContextShape => {\n\tconst ctx = useContext(AgentBuilderContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t'useAgentBuilderContext must be used within an AgentBuilderProvider',\n\t\t);\n\t}\n\treturn ctx;\n};\n\n/** Validity derived purely from the current value (no effects). */\nconst deriveValidation = (\n\tvalue: AgentValue,\n\tlimits: AgentCharLimits,\n): StepValidation => {\n\tconst triggerValid =\n\t\tvalue.trigger.mode === 'custom_intent'\n\t\t\t? (value.trigger.custom_intent ?? '').trim().length > 0\n\t\t\t: value.trigger.intents.length > 0;\n\n\treturn {\n\t\tabout:\n\t\t\tvalue.name.trim().length > 0 &&\n\t\t\tvalue.name.length <= limits.name &&\n\t\t\tvalue.description.length <= limits.description,\n\t\ttrigger: triggerValid,\n\t\t// At least one of Instructions / Guardrails must be filled.\n\t\tresponse:\n\t\t\tvalue.instructions.trim().length > 0 ||\n\t\t\t(value.guardrail ?? '').trim().length > 0,\n\t\t// Optional until specced further — never blocks go-live.\n\t\thandover: true,\n\t};\n};\n\ninterface ProviderProps {\n\tvalue: AgentValue;\n\tonChange: (patch: Partial<AgentValue>) => void;\n\tactiveStep?: StepKey;\n\tonStepChange?: (step: StepKey) => void;\n\tavailableTools: AgentTool[];\n\tavailableSubAgents: SubAgentRef[];\n\tavailableIntents: IntentOption[];\n\tavailableModels: ModelOption[];\n\tconfigToolTemplates?: Partial<Record<ConfigToolKey, ParamsBlob>>;\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\tonConnectIntegration?: (source: ToolSource) => void;\n\tvariablesData?: VariableListInterfaceV3[];\n\tvalidation?: Partial<StepValidation>;\n\tapplicationType?: ApplicationType;\n\tcharLimits?: Partial<AgentCharLimits>;\n\tdisableStepNavigation?: boolean;\n\tonCreateSubAgent?: (draft: SubAgentDraft) => Promise<SubAgentRef>;\n\tonFetchSubAgent?: (id: string) => Promise<SubAgentDraft>;\n\tonUpdateSubAgent?: (id: string, draft: SubAgentDraft) => Promise<SubAgentRef>;\n\tonImproveSubAgent?: (\n\t\tkind: 'instructions' | 'guardrail',\n\t\ttext: string,\n\t) => Promise<string>;\n\tonImproveToolInstructions?: (text: string) => Promise<string>;\n\tchildren: React.ReactNode;\n}\n\nexport const AgentBuilderProvider: React.FC<ProviderProps> = ({\n\tvalue,\n\tonChange,\n\tactiveStep: controlledStep,\n\tonStepChange,\n\tavailableTools,\n\tavailableSubAgents,\n\tavailableIntents,\n\tavailableModels,\n\tconfigToolTemplates,\n\tintegrationStatus,\n\tonConnectIntegration,\n\tvariablesData,\n\tvalidation: validationOverride,\n\tapplicationType,\n\tcharLimits: charLimitsOverride,\n\tdisableStepNavigation = true,\n\tonCreateSubAgent,\n\tonFetchSubAgent,\n\tonUpdateSubAgent,\n\tonImproveSubAgent,\n\tonImproveToolInstructions,\n\tchildren,\n}) => {\n\tconst [internalStep, setInternalStep] = useState<StepKey>('about');\n\tconst activeStep = controlledStep ?? internalStep;\n\tconst activeIndex = getStepIndex(activeStep);\n\n\t// Latest value, so closure-captured handlers (e.g. the `@` editor's mount-time\n\t// mention onSelect) append against the current lists, not a stale snapshot.\n\tconst valueRef = useRef(value);\n\tvalueRef.current = value;\n\n\t// Bumped when a mention field is edited from OUTSIDE its editor (removing a\n\t// tool from the side list, undo), forcing the mention editors to remount.\n\tconst [mentionResetKey, setMentionResetKey] = useState(0);\n\n\t// Each mention field registers an editor-backed insert fn + reports focus, so\n\t// side-panel adds drop a chip into the last-focused field at its cursor.\n\tconst mentionInsertersRef = useRef<\n\t\tPartial<Record<MentionFieldKey, MentionInsertFn>>\n\t>({});\n\tconst lastFocusedFieldRef = useRef<MentionFieldKey>('instructions');\n\tconst registerMentionField = useCallback(\n\t\t(fieldKey: MentionFieldKey, fn: MentionInsertFn | null) => {\n\t\t\tif (fn) {\n\t\t\t\tmentionInsertersRef.current[fieldKey] = fn;\n\t\t\t} else {\n\t\t\t\tdelete mentionInsertersRef.current[fieldKey];\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\tconst notifyMentionFocus = useCallback((fieldKey: MentionFieldKey) => {\n\t\tlastFocusedFieldRef.current = fieldKey;\n\t}, []);\n\n\t// Step 3 registers its drawer opener here; the `@` picker's \"Create new\" calls it.\n\tconst subAgentCreatorRef = useRef<(() => void) | null>(null);\n\tconst registerSubAgentCreator = useCallback((fn: (() => void) | null) => {\n\t\tsubAgentCreatorRef.current = fn;\n\t}, []);\n\tconst requestCreateSubAgent = useCallback(() => {\n\t\tsubAgentCreatorRef.current?.();\n\t}, []);\n\n\t// Step 3 registers a dispatcher that opens a built-in tool action's drawer.\n\tconst toolActionHandlerRef = useRef<((source: ToolSource) => void) | null>(\n\t\tnull,\n\t);\n\tconst registerToolActionHandler = useCallback(\n\t\t(fn: ((source: ToolSource) => void) | null) => {\n\t\t\ttoolActionHandlerRef.current = fn;\n\t\t},\n\t\t[],\n\t);\n\tconst requestToolAction = useCallback((source: ToolSource) => {\n\t\ttoolActionHandlerRef.current?.(source);\n\t}, []);\n\tconst insertMention = useCallback<MentionInsertFn>(\n\t\t(kind, id, label, source) => {\n\t\t\tconst inserters = mentionInsertersRef.current;\n\t\t\tconst target =\n\t\t\t\tinserters[lastFocusedFieldRef.current] ?? inserters.instructions;\n\t\t\ttarget?.(kind, id, label, source);\n\t\t},\n\t\t[],\n\t);\n\n\t// Undo state for the most recent removal.\n\tconst [undoToast, setUndoToast] = useState<UndoToastState | null>(null);\n\tconst undoSnapshotRef = useRef<Partial<AgentValue> | null>(null);\n\tconst undoIdRef = useRef(0);\n\n\t// Consumer overrides merged over the built-in defaults (name 60, rest 1000).\n\tconst charLimits = useMemo<AgentCharLimits>(\n\t\t() => ({ ...AGENT_CHAR_LIMITS, ...charLimitsOverride }),\n\t\t[charLimitsOverride],\n\t);\n\n\tconst validation: StepValidation = useMemo(\n\t\t() => ({ ...deriveValidation(value, charLimits), ...validationOverride }),\n\t\t[value, charLimits, validationOverride],\n\t);\n\n\tconst goToStep = useCallback(\n\t\t(step: StepKey) => {\n\t\t\t// Forward jumps (side rail) must not skip past an incomplete step —\n\t\t\t// otherwise an agent with an empty step 3 could reach step 4 and be\n\t\t\t// published. Going back is always allowed.\n\t\t\tconst targetIndex = STEP_KEYS.indexOf(step);\n\t\t\tif (\n\t\t\t\ttargetIndex > activeIndex &&\n\t\t\t\tSTEP_KEYS.slice(0, targetIndex).some((k) => !validation[k])\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (controlledStep === undefined) {\n\t\t\t\tsetInternalStep(step);\n\t\t\t}\n\t\t\tonStepChange?.(step);\n\t\t},\n\t\t[controlledStep, onStepChange, activeIndex, validation],\n\t);\n\n\tconst goNext = useCallback(() => {\n\t\tconst next = STEP_KEYS[Math.min(activeIndex + 1, STEP_KEYS.length - 1)];\n\t\tgoToStep(next);\n\t}, [activeIndex, goToStep]);\n\n\tconst goPrev = useCallback(() => {\n\t\tconst prev = STEP_KEYS[Math.max(activeIndex - 1, 0)];\n\t\tgoToStep(prev);\n\t}, [activeIndex, goToStep]);\n\n\tconst patch = useCallback(\n\t\t(partial: Partial<AgentValue>) => onChange(partial),\n\t\t[onChange],\n\t);\n\n\tconst updateField = useCallback(\n\t\t<K extends keyof AgentValue>(key: K, val: AgentValue[K]) =>\n\t\t\tonChange({ [key]: val } as Partial<AgentValue>),\n\t\t[onChange],\n\t);\n\n\tconst addReference = useCallback(\n\t\t(kind: 'tool' | 'subagent', id: string) => {\n\t\t\tconst v = valueRef.current;\n\t\t\tif (kind === 'tool') {\n\t\t\t\t// Custom tools (Rest API / email / Slack) track themselves on their own\n\t\t\t\t// lists; only catalog/native ids belong in `tools`. Picking an EXISTING\n\t\t\t\t// custom tool from the `@` picker must not leak its id in here — on save\n\t\t\t\t// it becomes a bogus native ref and create-agent validation rejects it.\n\t\t\t\tconst isCustom =\n\t\t\t\t\t(v.configTools ?? []).some((t) => t.id === id) ||\n\t\t\t\t\t(v.restApiTools ?? []).some((t) => t.id === id);\n\t\t\t\tif (!isCustom && !v.tools.includes(id)) {\n\t\t\t\t\tonChange({ tools: [...v.tools, id] });\n\t\t\t\t}\n\t\t\t} else if (!v.subagents.includes(id)) {\n\t\t\t\tonChange({ subagents: [...v.subagents, id] });\n\t\t\t}\n\t\t},\n\t\t[onChange],\n\t);\n\n\tconst removeReference = useCallback(\n\t\t(kind: 'tool' | 'subagent', id: string) => {\n\t\t\t// Tokens store the id for both kinds (a tool's id is its tool_id).\n\t\t\tconst token = kind === 'tool' ? `{{tool:${id}}}` : `{{subagent:${id}}}`;\n\t\t\tconst strip = (text: string) => text.split(token).join('');\n\n\t\t\t// Snapshot every field a removal touches, for undo. Custom tools (Rest\n\t\t\t// API / email / Slack) live on their own lists, so include them too.\n\t\t\tundoSnapshotRef.current = {\n\t\t\t\ttools: value.tools,\n\t\t\t\tsubagents: value.subagents,\n\t\t\t\tconfigTools: value.configTools,\n\t\t\t\trestApiTools: value.restApiTools,\n\t\t\t\tinstructions: value.instructions,\n\t\t\t\tguardrail: value.guardrail,\n\t\t\t};\n\n\t\t\tconst next: Partial<AgentValue> = {\n\t\t\t\tinstructions: strip(value.instructions),\n\t\t\t\tguardrail: strip(value.guardrail ?? ''),\n\t\t\t\t...(kind === 'tool'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t// A tool id may be a catalog tool OR an inline custom tool — drop\n\t\t\t\t\t\t\t// it from whichever list holds it (the others are no-op filters).\n\t\t\t\t\t\t\ttools: value.tools.filter((t) => t !== id),\n\t\t\t\t\t\t\tconfigTools: (value.configTools ?? []).filter((t) => t.id !== id),\n\t\t\t\t\t\t\trestApiTools: (value.restApiTools ?? []).filter(\n\t\t\t\t\t\t\t\t(t) => t.id !== id,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t }\n\t\t\t\t\t: { subagents: value.subagents.filter((s) => s !== id) }),\n\t\t\t};\n\t\t\tonChange(next);\n\t\t\tsetMentionResetKey((k) => k + 1);\n\n\t\t\tconst label =\n\t\t\t\tkind === 'tool'\n\t\t\t\t\t? availableTools.find((t) => t.tool_id === id)?.display_name ??\n\t\t\t\t\t (value.restApiTools ?? []).find((t) => t.id === id)?.name ??\n\t\t\t\t\t 'Tool'\n\t\t\t\t\t: availableSubAgents.find((s) => s.id === id)?.name ?? 'Sub-agent';\n\t\t\tundoIdRef.current += 1;\n\t\t\tsetUndoToast({\n\t\t\t\tid: undoIdRef.current,\n\t\t\t\tmessage: `${kind === 'tool' ? 'Tool' : 'Sub-agent'} \"${label}\" removed`,\n\t\t\t});\n\t\t},\n\t\t[availableTools, availableSubAgents, value, onChange],\n\t);\n\n\tconst undoRemoval = useCallback(() => {\n\t\tif (undoSnapshotRef.current) {\n\t\t\tonChange(undoSnapshotRef.current);\n\t\t\tundoSnapshotRef.current = null;\n\t\t\tsetMentionResetKey((k) => k + 1);\n\t\t}\n\t\tsetUndoToast(null);\n\t}, [onChange]);\n\n\tconst dismissUndo = useCallback(() => setUndoToast(null), []);\n\n\tconst ctx = useMemo<AgentBuilderContextShape>(\n\t\t() => ({\n\t\t\tvalue,\n\t\t\tpatch,\n\t\t\tupdateField,\n\t\t\taddReference,\n\t\t\tremoveReference,\n\t\t\tmentionResetKey,\n\t\t\tinsertMention,\n\t\t\tregisterMentionField,\n\t\t\tnotifyMentionFocus,\n\t\t\tundoToast,\n\t\t\tundoRemoval,\n\t\t\tdismissUndo,\n\t\t\tactiveStep,\n\t\t\tactiveIndex,\n\t\t\tgoToStep,\n\t\t\tgoNext,\n\t\t\tgoPrev,\n\t\t\tisFirstStep: activeIndex === 0,\n\t\t\tisLastStep: activeIndex === STEP_KEYS.length - 1,\n\t\t\tvalidation,\n\t\t\tisActiveStepValid: validation[activeStep],\n\t\t\tavailableTools,\n\t\t\tavailableSubAgents,\n\t\t\tavailableIntents,\n\t\t\tavailableModels,\n\t\t\tconfigToolTemplates,\n\t\t\tintegrationStatus,\n\t\t\tonConnectIntegration,\n\t\t\tvariablesData,\n\t\t\tapplicationType,\n\t\t\tcharLimits,\n\t\t\tdisableStepNavigation,\n\t\t\tonCreateSubAgent,\n\t\t\tregisterSubAgentCreator,\n\t\t\trequestCreateSubAgent,\n\t\t\tregisterToolActionHandler,\n\t\t\trequestToolAction,\n\t\t\tonFetchSubAgent,\n\t\t\tonUpdateSubAgent,\n\t\t\tonImproveSubAgent,\n\t\t\tonImproveToolInstructions,\n\t\t}),\n\t\t[\n\t\t\tvalue,\n\t\t\tpatch,\n\t\t\tupdateField,\n\t\t\taddReference,\n\t\t\tremoveReference,\n\t\t\tmentionResetKey,\n\t\t\tinsertMention,\n\t\t\tregisterMentionField,\n\t\t\tnotifyMentionFocus,\n\t\t\tundoToast,\n\t\t\tundoRemoval,\n\t\t\tdismissUndo,\n\t\t\tactiveStep,\n\t\t\tactiveIndex,\n\t\t\tgoToStep,\n\t\t\tgoNext,\n\t\t\tgoPrev,\n\t\t\tvalidation,\n\t\t\tavailableTools,\n\t\t\tavailableSubAgents,\n\t\t\tavailableIntents,\n\t\t\tavailableModels,\n\t\t\tconfigToolTemplates,\n\t\t\tintegrationStatus,\n\t\t\tonConnectIntegration,\n\t\t\tvariablesData,\n\t\t\tapplicationType,\n\t\t\tcharLimits,\n\t\t\tdisableStepNavigation,\n\t\t\tonCreateSubAgent,\n\t\t\tregisterSubAgentCreator,\n\t\t\trequestCreateSubAgent,\n\t\t\tregisterToolActionHandler,\n\t\t\trequestToolAction,\n\t\t\tonFetchSubAgent,\n\t\t\tonUpdateSubAgent,\n\t\t\tonImproveSubAgent,\n\t\t\tonImproveToolInstructions,\n\t\t],\n\t);\n\n\treturn (\n\t\t<AgentBuilderContext.Provider value={ctx}>\n\t\t\t{children}\n\t\t</AgentBuilderContext.Provider>\n\t);\n};\n"],"names":["AgentBuilderContext","React","useAgentBuilderContext","ctx","useContext","deriveValidation","value","limits","triggerValid","AgentBuilderProvider","onChange","controlledStep","onStepChange","availableTools","availableSubAgents","availableIntents","availableModels","configToolTemplates","integrationStatus","onConnectIntegration","variablesData","validationOverride","applicationType","charLimitsOverride","disableStepNavigation","onCreateSubAgent","onFetchSubAgent","onUpdateSubAgent","onImproveSubAgent","onImproveToolInstructions","children","internalStep","setInternalStep","useState","activeStep","activeIndex","getStepIndex","valueRef","useRef","mentionResetKey","setMentionResetKey","mentionInsertersRef","lastFocusedFieldRef","registerMentionField","useCallback","fieldKey","fn","notifyMentionFocus","subAgentCreatorRef","registerSubAgentCreator","requestCreateSubAgent","toolActionHandlerRef","registerToolActionHandler","requestToolAction","source","insertMention","kind","id","label","inserters","undoToast","setUndoToast","undoSnapshotRef","undoIdRef","charLimits","useMemo","AGENT_CHAR_LIMITS","validation","goToStep","step","targetIndex","STEP_KEYS","k","goNext","next","goPrev","prev","patch","partial","updateField","key","val","addReference","v","t","removeReference","token","strip","text","s","undoRemoval","dismissUndo"],"mappings":"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"}