@bikdotai/bik-component-library 0.0.849-beta.2 → 0.0.849-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js +11 -11
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +5 -5
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js +7 -7
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +2 -2
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js +9 -0
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/cjs/editor/extensions/mention/MentionDropdown.js +1 -1
- package/dist/cjs/editor/extensions/mention/MentionDropdown.js.map +1 -1
- package/dist/cjs/editor/extensions/mention/MentionExtension.js +1 -1
- package/dist/cjs/editor/extensions/mention/MentionExtension.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.d.ts +8 -0
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +151 -124
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +90 -88
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.d.ts +7 -0
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +174 -133
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.d.ts +9 -0
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +65 -47
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.d.ts +27 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js +70 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +93 -91
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/esm/editor/extensions/mention/MentionDropdown.js +19 -19
- package/dist/esm/editor/extensions/mention/MentionDropdown.js.map +1 -1
- package/dist/esm/editor/extensions/mention/MentionExtension.js +15 -15
- package/dist/esm/editor/extensions/mention/MentionExtension.js.map +1 -1
- package/package.json +1 -1
|
@@ -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\
|
|
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\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,EACA,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,9 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("react/jsx-runtime"),l=require("react"),m=require("styled-components"),k=require("../../variable-picker-v3/model.js"),x=require("../utils/mentionSerialization.js"),y=require("../../variable-picker-v3/VariablePicker.js"),T=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},p=T(m),v=e=>`{{variable:${x.variableTokenName(e.actualValue)}}}`,f=/[\s,;:/?&=(){}[\]"'<>]/,w=e=>{if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){const t=e.selectionStart??e.value.length,s=t===0?" ":e.value[t-1]??" ";return{ok:f.test(s),caret:t}}const i=window.getSelection(),u=i?.anchorNode?.textContent??"",a=i?.anchorOffset??0,o=a===0?" ":u[a-1]??" ";return{ok:f.test(o),caret:null}},E=({variablesData:e,onInsert:i,children:u})=>{const a=l.useRef(null),[o,t]=l.useState(null),s=(e?.length??0)>0,g=l.useCallback(n=>{if(!s||n.key!=="@")return;const c=w(n.target);if(!c.ok)return;n.preventDefault(),n.stopPropagation();const r=a.current?.getBoundingClientRect(),b=!!r&&window.innerHeight-r.bottom<340;t({caret:c.caret,above:b})},[s]);return l.useEffect(()=>{if(!o)return;const n=r=>{r.key==="Escape"&&(r.stopPropagation(),t(null))},c=r=>{a.current?.contains(r.target)||t(null)};return document.addEventListener("keydown",n,!0),document.addEventListener("mousedown",c),()=>{document.removeEventListener("keydown",n,!0),document.removeEventListener("mousedown",c)}},[o]),d.jsxs(h,{ref:a,onKeyDownCapture:g,children:[u,o&&d.jsx(R,{$above:o.above,"data-test":"variable-trigger-panel",children:d.jsx(y.VariablePicker,{type:k.PickerType.FLOATER,data:e??[],showRecommendedBar:!1,onClose:()=>t(null),onSelect:n=>{t(null),i(v(n),o.caret)}})})]})},h=p.default.div`
|
|
2
|
+
position: relative;
|
|
3
|
+
`,R=p.default.div`
|
|
4
|
+
position: absolute;
|
|
5
|
+
left: 0;
|
|
6
|
+
z-index: 1000;
|
|
7
|
+
${e=>e.$above?"bottom: calc(100% + 4px);":"top: calc(100% + 4px);"}
|
|
8
|
+
`;exports.VariableTriggerArea=E;exports.variableToken=v;
|
|
9
|
+
//# 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 { VariablePicker } from '../../variable-picker-v3';\nimport { PickerType } from '../../variable-picker-v3/model';\nimport type {\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport { variableTokenName } from '../utils/mentionSerialization';\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 */\nconst BOUNDARY = /[\\s,;:/?&=(){}[\\]\"'<>]/;\n\nconst triggerContext = (\n\ttarget: EventTarget | null,\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 prev = caret === 0 ? ' ' : target.value[caret - 1] ?? ' ';\n\t\treturn { ok: 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 prev = offset === 0 ? ' ' : text[offset - 1] ?? ' ';\n\treturn { ok: 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\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\tchildren,\n}) => {\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\t// Non-null while the panel is open: where to put the token when picked, and\n\t// whether the panel renders above the field (not enough room below).\n\tconst [trigger, setTrigger] = useState<{\n\t\tcaret: number | null;\n\t\tabove: boolean;\n\t} | null>(null);\n\n\tconst enabled = (variablesData?.length ?? 0) > 0;\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(e.target);\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\tconst rect = containerRef.current?.getBoundingClientRect();\n\t\t\tconst above = !!rect && window.innerHeight - rect.bottom < 340;\n\t\t\tsetTrigger({ caret: ctx.caret, above });\n\t\t},\n\t\t[enabled],\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\tsetTrigger(null);\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\tsetTrigger(null);\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 ref={containerRef} onKeyDownCapture={onKeyDownCapture}>\n\t\t\t{children}\n\t\t\t{trigger && (\n\t\t\t\t<FloaterBox $above={trigger.above} data-test=\"variable-trigger-panel\">\n\t\t\t\t\t<VariablePicker\n\t\t\t\t\t\ttype={PickerType.FLOATER}\n\t\t\t\t\t\tdata={variablesData ?? []}\n\t\t\t\t\t\tshowRecommendedBar={false}\n\t\t\t\t\t\tonClose={() => setTrigger(null)}\n\t\t\t\t\t\tonSelect={(variable: VariableV3) => {\n\t\t\t\t\t\t\tsetTrigger(null);\n\t\t\t\t\t\t\tonInsert(variableToken(variable), trigger.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; VariablePicker brings its own card\n// styling. High z-index: these fields live inside side-modal drawers.\nconst FloaterBox = styled.div<{ $above: boolean }>`\n\tposition: absolute;\n\tleft: 0;\n\tz-index: 1000;\n\t${(p) => (p.$above ? 'bottom: calc(100% + 4px);' : 'top: calc(100% + 4px);')}\n`;\n"],"names":["variableToken","variable","variableTokenName","BOUNDARY","triggerContext","target","caret","prev","sel","text","offset","VariableTriggerArea","variablesData","onInsert","children","containerRef","useRef","trigger","setTrigger","useState","enabled","onKeyDownCapture","useCallback","e","ctx","rect","above","useEffect","onKey","onDown","jsxs","TriggerWrap","jsx","FloaterBox","VariablePicker","PickerType","styled","p"],"mappings":"2XAWaA,EAAiBC,GAC7B,cAAcC,EAAAA,kBAAkBD,EAAS,WAAW,CAAC,KAUhDE,EAAW,yBAEXC,EACLC,GAC2C,CAC3C,GACCA,aAAkB,kBAClBA,aAAkB,oBACjB,CACD,MAAMC,EAAQD,EAAO,gBAAkBA,EAAO,MAAM,OAC9CE,EAAOD,IAAU,EAAI,IAAMD,EAAO,MAAMC,EAAQ,CAAC,GAAK,IAC5D,MAAO,CAAE,GAAIH,EAAS,KAAKI,CAAI,EAAG,MAAAD,CAAA,CACnC,CAGA,MAAME,EAAM,OAAO,aAAA,EACbC,EAAOD,GAAK,YAAY,aAAe,GACvCE,EAASF,GAAK,cAAgB,EAC9BD,EAAOG,IAAW,EAAI,IAAMD,EAAKC,EAAS,CAAC,GAAK,IACtD,MAAO,CAAE,GAAIP,EAAS,KAAKI,CAAI,EAAG,MAAO,IAAA,CAC1C,EAwBaI,EAA0D,CAAC,CACvE,cAAAC,EACA,SAAAC,EACA,SAAAC,CACD,IAAM,CACL,MAAMC,EAAeC,EAAAA,OAAuB,IAAI,EAG1C,CAACC,EAASC,CAAU,EAAIC,EAAAA,SAGpB,IAAI,EAERC,GAAWR,GAAe,QAAU,GAAK,EAEzCS,EAAmBC,EAAAA,YACvBC,GAA2B,CAC3B,GAAI,CAACH,GAAWG,EAAE,MAAQ,IACzB,OAED,MAAMC,EAAMpB,EAAemB,EAAE,MAAM,EACnC,GAAI,CAACC,EAAI,GACR,OAGDD,EAAE,eAAA,EACFA,EAAE,gBAAA,EACF,MAAME,EAAOV,EAAa,SAAS,sBAAA,EAC7BW,EAAQ,CAAC,CAACD,GAAQ,OAAO,YAAcA,EAAK,OAAS,IAC3DP,EAAW,CAAE,MAAOM,EAAI,MAAO,MAAAE,EAAO,CACvC,EACA,CAACN,CAAO,CAAA,EAITO,OAAAA,EAAAA,UAAU,IAAM,CACf,GAAI,CAACV,EACJ,OAED,MAAMW,EAASL,GAAqB,CAC/BA,EAAE,MAAQ,WACbA,EAAE,gBAAA,EACFL,EAAW,IAAI,EAEjB,EACMW,EAAUN,GAAkB,CAC5BR,EAAa,SAAS,SAASQ,EAAE,MAAc,GACnDL,EAAW,IAAI,CAEjB,EAGA,gBAAS,iBAAiB,UAAWU,EAAO,EAAI,EAChD,SAAS,iBAAiB,YAAaC,CAAM,EACtC,IAAM,CACZ,SAAS,oBAAoB,UAAWD,EAAO,EAAI,EACnD,SAAS,oBAAoB,YAAaC,CAAM,CACjD,CACD,EAAG,CAACZ,CAAO,CAAC,EAGXa,EAAAA,KAACC,EAAA,CAAY,IAAKhB,EAAc,iBAAAM,EAC9B,SAAA,CAAAP,EACAG,GACAe,EAAAA,IAACC,EAAA,CAAW,OAAQhB,EAAQ,MAAO,YAAU,yBAC5C,SAAAe,EAAAA,IAACE,EAAAA,eAAA,CACA,KAAMC,EAAAA,WAAW,QACjB,KAAMvB,GAAiB,CAAA,EACvB,mBAAoB,GACpB,QAAS,IAAMM,EAAW,IAAI,EAC9B,SAAWjB,GAAyB,CACnCiB,EAAW,IAAI,EACfL,EAASb,EAAcC,CAAQ,EAAGgB,EAAQ,KAAK,CAChD,CAAA,CAAA,CACD,CACD,CAAA,EAEF,CAEF,EAEMc,EAAcK,EAAAA,QAAO;AAAA;AAAA,EAMrBH,EAAaG,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA,GAItBC,GAAOA,EAAE,OAAS,4BAA8B,wBAAyB;AAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),i=require("react"),A=require("../../TypographyStyle.js"),I=require("../../../constants/Theme.js"),p=require("../AgentBuilder.styled.js"),we=require("../components/ConfigToolPanel.js"),qe=require("../components/CreateSubAgentPanel.js"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),i=require("react"),A=require("../../TypographyStyle.js"),I=require("../../../constants/Theme.js"),p=require("../AgentBuilder.styled.js"),we=require("../components/ConfigToolPanel.js"),qe=require("../components/CreateSubAgentPanel.js"),te=require("../components/MentionField.js"),je=require("../components/RequireVerificationModal.js"),ke=require("../components/RestApiToolPanel.js"),oe=require("../components/SelectableListSection.js"),_e=require("../components/StepSectionHeader.js"),Me=require("../constants/steps.js"),m=require("../constants/tools.js"),Ee=require("../context/AgentBuilderContext.js"),r=require("../utils/mentionSerialization.js"),x=require("../utils/sourceIcons.js"),Le=require("../utils/toolActions.js"),Pe=require("../../../icons/Informational/Common UI/Shield.js"),De=require("../../switch/Switch.js"),ne=require("../../dropdown/Dropdown.js"),le=require("../../dropdown/utils.js"),Ne=n=>x.renderSourceIcon(x.sourceIcon(n))??void 0,ie=n=>({label:n.display_name,value:n.tool_id,leadingIcon:Ne(n.source??m.ToolSource.Manifest)}),se=Me.STEP_DEFINITIONS[2],W=[{label:"OTP to phone",value:"phone_otp"},{label:"OTP to email",value:"email_otp"}],ae=(n,s)=>{const y=n??[];return y.some(d=>d.id===s.id)?y.map(d=>d.id===s.id?s:d):[...y,s]},He=()=>{const{value:n,patch:s,updateField:y,addReference:d,removeReference:z,availableTools:c,availableSubAgents:re,availableModels:_,configToolTemplates:M,applicationType:$,charLimits:C,insertMention:u,onCreateSubAgent:h,onFetchSubAgent:O,onUpdateSubAgent:E,onImproveSubAgent:ce,onImproveToolInstructions:L,registerSubAgentCreator:P,registerToolActionHandler:D,integrationStatus:J,onConnectIntegration:Q,variablesData:N}=Ee.useAgentBuilderContext(),[g,R]=i.useState(null),w=i.useRef(0),[a,S]=i.useState(null),q=i.useRef(0),H=i.useCallback(e=>{q.current+=1,S({key:q.current,kind:"restapi",initialRest:e})},[]),B=i.useCallback((e,t)=>{q.current+=1,S({key:q.current,kind:"config",toolKey:e,initialConfig:t})},[]),ue=i.useCallback(e=>{const t=!(n.restApiTools??[]).some(l=>l.id===e.id);s({restApiTools:ae(n.restApiTools,e)}),t&&u("tool",e.id,r.restApiMentionItem(e).label),S(null)},[s,n.restApiTools,u]),de=i.useCallback(e=>{const t=!(n.configTools??[]).some(l=>l.id===e.id);s({configTools:ae(n.configTools,e)}),t&&u("tool",e.id,r.configToolMentionItem(e).label),S(null)},[s,n.configTools,u]),K=i.useCallback(e=>{const t=m.CONFIG_TOOL_SOURCES[e];t?B(t):H()},[B,H]);i.useEffect(()=>(D(K),()=>D(null)),[D,K]);const[pe,X]=i.useState([]),j=new Map;re.forEach(e=>j.set(e.id,e)),pe.forEach(e=>j.set(e.id,e));const Y=Array.from(j.values()),F=i.useCallback(()=>{w.current+=1,R({key:w.current,title:"Create sub-agent"})},[]);i.useEffect(()=>{if(h)return P(F),()=>P(null)},[P,F,h]);const ge=i.useCallback(async e=>{if(!O)return;const t=await O(e);w.current+=1,R({key:w.current,title:"Edit sub-agent",editingId:e,initial:t})},[O]),me=i.useCallback(async e=>{if(g?.editingId){if(E){const t=await E(g.editingId,e);X(l=>[...l.filter(T=>T.id!==t.id),t])}}else if(h){const t=await h(e);X(l=>[...l,t]),s({subagents:[...n.subagents,t.id]}),u("subagent",t.id,`sub-agent: ${t.name}`)}R(null)},[g,E,h,s,n.subagents,u]),b=n.tools.some(e=>c.find(t=>t.tool_id===e)?.auth_required),f=n.authentication?.enabled??!1,v=n.authentication?.type??"email_otp";i.useEffect(()=>{b&&!f&&s({authentication:{enabled:!0,type:v}})},[b,f,v,s]);const[k,G]=i.useState(null),U=i.useCallback(e=>{u("tool",e),d("tool",e)},[u,d]),he=i.useCallback(e=>{if(c.find(l=>l.tool_id===e)?.auth_required&&!f){G(e);return}U(e)},[c,f,U]),Se=n.tools.map(e=>{const t=c.find(l=>l.tool_id===e);return t?{id:e,label:t.display_name,icon:x.sourceIcon(t.source??m.ToolSource.Manifest),authRequired:t.auth_required}:null}).filter(e=>e!==null),be=(n.restApiTools??[]).map(e=>({id:e.id,label:r.restApiToolName(e),icon:x.SOURCE_ICONS[m.ToolSource.RestApi],onConfigure:()=>H(e)})),fe=(n.configTools??[]).map(e=>({id:e.id,label:r.configToolName(e),icon:x.SOURCE_ICONS[e.tool_key==="send_slack_message"?m.ToolSource.Slack:m.ToolSource.EmailHandover],onConfigure:()=>B(e.tool_key,e)})),Te=[...Se,...be,...fe],ye=Le.buildToolActions(M,K,J,Q),Ce=c.map(ie),ve=(()=>{const e=[],t=new Map;return c.forEach(l=>{const T=l.source??m.ToolSource.Manifest;t.has(T)||(t.set(T,[]),e.push(T)),t.get(T)?.push(ie(l))}),e.map(l=>({source:l,label:r.toolSourceLabel(l),options:t.get(l)??[],connected:J?.[l],onConnect:()=>Q?.(l)}))})(),Ae=n.subagents.map(e=>{const t=j.get(e);return t?{id:e,label:t.name}:null}).filter(e=>e!==null),Ie=Y.map(e=>({label:e.name,value:e.id})),Z=r.appTypeLabel($),xe=[...r.buildAgentMentionItems(c,[],Z),...r.buildCustomToolMentionItems(n.configTools,n.restApiTools)],Oe=r.buildAgentMentionItems([],Y,Z),Re=_.map(e=>({label:e.label,value:e.value,selected:e.value===n.model})),V=_.find(e=>e.value===n.model),ee=a?.kind==="config"&&a.toolKey?M?.[a.toolKey]:void 0;return o.jsxs(p.Step3Root,{children:[o.jsx(_e.StepSectionHeader,{title:se.title,helper:se.helper}),o.jsxs(p.Step3Grid,{$grow:!0,children:[o.jsxs(p.SectionBodyWrap,{children:[o.jsx(te.MentionField,{fieldKey:"instructions","data-test":"agent-instructions",label:"Instructions",maxLength:C.instructions,placeholder:"Write the steps in plain English. The agent will follow them exactly. The more specific you are, the better it performs.",minHeight:"200px"}),o.jsx(te.MentionField,{fieldKey:"guardrail","data-test":"agent-guardrail",label:"Guardrails",maxLength:C.guardrail,placeholder:"e.g. Never discuss competitor pricing. Always stay within the cancellation policy. Do not process refunds above ₹10,000 without human approval.",minHeight:"140px"})]}),o.jsx(p.Step3Divider,{}),o.jsxs(p.SectionBodyWrap,{children:[o.jsx(oe.SelectableListSection,{title:"Tools",helper:"Actions this agent can take while responding.",dataTestPrefix:"agent-tools",items:Te,addableOptions:Ce,sourceGroups:ve,mentionItems:xe,actionSources:ye,emptyText:"No tools added yet.",onAdd:he,onRemove:e=>z("tool",e),confirmDelete:{noun:"tool"}}),o.jsx(oe.SelectableListSection,{title:"Sub-agents",helper:"Other agents this agent can hand off the conversation to.",dataTestPrefix:"agent-subagents",items:Ae,addableOptions:Ie,mentionItems:Oe,emptyText:"No sub-agents added yet.",onAdd:e=>{u("subagent",e),d("subagent",e)},onRemove:e=>z("subagent",e),confirmDelete:{noun:"sub-agent"},onConfigure:O?ge:void 0,createOption:h?{label:"Create new",onSelect:F}:void 0}),o.jsxs(p.SideSection,{children:[o.jsxs(p.SideSectionHeader,{children:[o.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[o.jsx(Pe.default,{size:20}),o.jsx(A.TitleSmall,{color:I.COLORS.content.primary,children:"Require customer verification"})]}),o.jsx(De.Switch,{"data-test":"agent-auth-toggle",value:f||b,disabled:b,onValueChange:async e=>{s({authentication:{enabled:e,type:v}})}})]}),o.jsx(A.BodyCaption,{color:I.COLORS.content.secondary,children:b?"Required — this agent uses a tool that accesses customer order details.":"Customers must verify their identity before this agent responds."}),(f||b)&&o.jsxs(o.Fragment,{children:[o.jsx(A.BodySecondary,{color:I.COLORS.content.primary,children:"Select verification method"}),o.jsx(ne.Dropdown,{"data-test":"agent-auth-method",size:"small",width:"100%",dropdownWidth:"328px",placeHolder:"Select verification method",options:W,defaultOptions:[W.find(e=>e.value===v)??W[0]],onSelect:e=>{const t=le.unwrapDropdownValue(e);t&&s({authentication:{enabled:!0,type:t}})}})]})]}),_.length>0&&o.jsxs(p.SideSection,{children:[o.jsx(A.TitleSmall,{color:I.COLORS.content.primary,children:"Advanced settings"}),o.jsx(A.BodySecondary,{color:I.COLORS.content.primary,children:"Select AI model"}),o.jsx(ne.Dropdown,{"data-test":"agent-model",size:"small",width:"100%",dropdownWidth:"328px",placeHolder:"Select model",options:Re,defaultOptions:V?[{label:V.label,value:V.value}]:void 0,onSelect:e=>{const t=le.unwrapDropdownValue(e);t&&y("model",t)}})]})]})]}),g&&o.jsx(qe.CreateSubAgentPanel,{title:g.title,initial:g.initial,availableTools:c,configToolTemplates:M,variablesData:N,appLabel:r.appTypeLabel($),charLimits:C,onImprove:ce,onImproveToolInstructions:L,onClose:()=>R(null),onSave:me},g.key),a?.kind==="restapi"&&o.jsx(ke.RestApiToolPanel,{initial:a.initialRest,charLimits:C,variablesData:N,existingNames:(n.restApiTools??[]).filter(e=>e.id!==a.initialRest?.id).map(e=>e.name),onImprove:L,onClose:()=>S(null),onSave:ue},a.key),a?.kind==="config"&&a.toolKey&&ee&&o.jsx(we.ConfigToolPanel,{toolKey:a.toolKey,template:ee,initial:a.initialConfig,charLimits:C,variablesData:N,onImprove:L,onClose:()=>S(null),onSave:de},a.key),o.jsx(je.RequireVerificationModal,{open:k!==null,toolLabel:c.find(e=>e.tool_id===k)?.display_name??"This tool",onCancel:()=>G(null),onConfirm:()=>{s({authentication:{enabled:!0,type:v}}),k&&U(k),G(null)}})]})};exports.Step3HowItResponds=He;
|
|
2
2
|
//# sourceMappingURL=Step3HowItResponds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Step3HowItResponds.js","sources":["../../../../../src/components/agent-builder/steps/Step3HowItResponds.tsx"],"sourcesContent":["import { Shield } from '@src/icons';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Dropdown, unwrapDropdownValue } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { Switch } from '@src/components/switch';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tAgentTool,\n\tAuthentication,\n\tConfigToolConfig,\n\tConfigToolKey,\n\tRestApiToolConfig,\n\tSubAgentDraft,\n\tSubAgentRef,\n} from '../AgentBuilder.model';\nimport {\n\tSectionBodyWrap,\n\tSideSection,\n\tSideSectionHeader,\n\tStep3Divider,\n\tStep3Grid,\n\tStep3Root,\n} from '../AgentBuilder.styled';\nimport { ConfigToolPanel } from '../components/ConfigToolPanel';\nimport { CreateSubAgentPanel } from '../components/CreateSubAgentPanel';\nimport { MentionField } from '../components/MentionField';\nimport { RequireVerificationModal } from '../components/RequireVerificationModal';\nimport { RestApiToolPanel } from '../components/RestApiToolPanel';\nimport {\n\tSelectableItem,\n\tSelectableListSection,\n\tSourceGroup,\n} from '../components/SelectableListSection';\nimport { StepSectionHeader } from '../components/StepSectionHeader';\nimport { STEP_DEFINITIONS } from '../constants/steps';\nimport { CONFIG_TOOL_SOURCES, ToolSource } from '../constants/tools';\nimport { useAgentBuilderContext } from '../context/AgentBuilderContext';\nimport {\n\tappTypeLabel,\n\tbuildAgentMentionItems,\n\tbuildCustomToolMentionItems,\n\tconfigToolMentionItem,\n\tconfigToolName,\n\trestApiMentionItem,\n\trestApiToolName,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport {\n\trenderSourceIcon,\n\tSOURCE_ICONS,\n\tsourceIcon,\n} from '../utils/sourceIcons';\nimport { buildToolActions } from '../utils/toolActions';\n\n/** Source brand glyph for a tool, as a dropdown leadingIcon element. */\nconst toolIconEl = (source: string): JSX.Element | undefined =>\n\trenderSourceIcon(sourceIcon(source)) ?? undefined;\n\n/** Dropdown option for a tool: icon left of the name, no description. */\nconst toolOption = (t: AgentTool): SingleOption => ({\n\tlabel: t.display_name,\n\tvalue: t.tool_id,\n\tleadingIcon: toolIconEl(t.source ?? ToolSource.Manifest),\n});\n\nconst STEP = STEP_DEFINITIONS[2];\n\n/** Customer-verification OTP methods, in the dropdown's display order. */\nconst AUTH_METHOD_OPTIONS: SingleOption[] = [\n\t{ label: 'OTP to phone', value: 'phone_otp' },\n\t{ label: 'OTP to email', value: 'email_otp' },\n];\n\n/** Drawer state — null when closed; `key` remounts it fresh per open. */\ninterface SubAgentPanelState {\n\tkey: number;\n\ttitle: string;\n\teditingId?: string;\n\tinitial?: SubAgentDraft;\n}\n\n/**\n * Config-tool drawer state; `key` remounts fresh. `restapi` is the bespoke Rest\n * API panel; `config` is the shared dynamic panel (email / Slack), tagged with\n * its `toolKey`.\n */\ninterface ToolDrawerState {\n\tkey: number;\n\tkind: 'restapi' | 'config';\n\ttoolKey?: ConfigToolKey;\n\tinitialRest?: RestApiToolConfig;\n\tinitialConfig?: ConfigToolConfig;\n}\n\n/** Upsert an item by id (replace when present, append otherwise). */\nconst upsertById = <T extends { id: string }>(\n\tlist: T[] | undefined,\n\titem: T,\n): T[] => {\n\tconst arr = list ?? [];\n\treturn arr.some((x) => x.id === item.id)\n\t\t? arr.map((x) => (x.id === item.id ? item : x))\n\t\t: [...arr, item];\n};\n\nexport const Step3HowItResponds: React.FC = () => {\n\tconst {\n\t\tvalue,\n\t\tpatch,\n\t\tupdateField,\n\t\taddReference,\n\t\tremoveReference,\n\t\tavailableTools,\n\t\tavailableSubAgents,\n\t\tavailableModels,\n\t\tconfigToolTemplates,\n\t\tapplicationType,\n\t\tcharLimits,\n\t\tinsertMention,\n\t\tonCreateSubAgent,\n\t\tonFetchSubAgent,\n\t\tonUpdateSubAgent,\n\t\tonImproveSubAgent,\n\t\tonImproveToolInstructions,\n\t\tregisterSubAgentCreator,\n\t\tregisterToolActionHandler,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t\tvariablesData,\n\t} = useAgentBuilderContext();\n\n\tconst [panel, setPanel] = useState<SubAgentPanelState | null>(null);\n\tconst panelKeyRef = useRef(0);\n\n\t// Rest API (bespoke) + shared config-tool drawers (separate from the sub-agent one).\n\tconst [toolDrawer, setToolDrawer] = useState<ToolDrawerState | null>(null);\n\tconst toolDrawerKeyRef = useRef(0);\n\tconst openRestApi = useCallback((initial?: RestApiToolConfig) => {\n\t\ttoolDrawerKeyRef.current += 1;\n\t\tsetToolDrawer({\n\t\t\tkey: toolDrawerKeyRef.current,\n\t\t\tkind: 'restapi',\n\t\t\tinitialRest: initial,\n\t\t});\n\t}, []);\n\tconst openConfigTool = useCallback(\n\t\t(toolKey: ConfigToolKey, initial?: ConfigToolConfig) => {\n\t\t\ttoolDrawerKeyRef.current += 1;\n\t\t\tsetToolDrawer({\n\t\t\t\tkey: toolDrawerKeyRef.current,\n\t\t\t\tkind: 'config',\n\t\t\t\ttoolKey,\n\t\t\t\tinitialConfig: initial,\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\tconst handleSaveRestApi = useCallback(\n\t\t(config: RestApiToolConfig) => {\n\t\t\tconst isNew = !(value.restApiTools ?? []).some((t) => t.id === config.id);\n\t\t\tpatch({ restApiTools: upsertById(value.restApiTools, config) });\n\t\t\t// Drop a reference chip at the cursor on creation (edits keep the chip).\n\t\t\tif (isNew) {\n\t\t\t\tinsertMention('tool', config.id, restApiMentionItem(config).label);\n\t\t\t}\n\t\t\tsetToolDrawer(null);\n\t\t},\n\t\t[patch, value.restApiTools, insertMention],\n\t);\n\tconst handleSaveConfigTool = useCallback(\n\t\t(config: ConfigToolConfig) => {\n\t\t\tconst isNew = !(value.configTools ?? []).some((t) => t.id === config.id);\n\t\t\tpatch({ configTools: upsertById(value.configTools, config) });\n\t\t\tif (isNew) {\n\t\t\t\tinsertMention('tool', config.id, configToolMentionItem(config).label);\n\t\t\t}\n\t\t\tsetToolDrawer(null);\n\t\t},\n\t\t[patch, value.configTools, insertMention],\n\t);\n\n\t// Open a tool action's drawer by picker source (restapi / email / slack).\n\tconst openToolAction = useCallback(\n\t\t(source: ToolSource) => {\n\t\t\tconst toolKey = CONFIG_TOOL_SOURCES[source];\n\t\t\tif (toolKey) {\n\t\t\t\topenConfigTool(toolKey);\n\t\t\t} else {\n\t\t\t\topenRestApi();\n\t\t\t}\n\t\t},\n\t\t[openConfigTool, openRestApi],\n\t);\n\t// Let the `@` reference picker (Instructions / Guardrails) open these drawers.\n\tuseEffect(() => {\n\t\tregisterToolActionHandler(openToolAction);\n\t\treturn () => registerToolActionHandler(null);\n\t}, [registerToolActionHandler, openToolAction]);\n\t// Sub-agents created / edited in this session, so a chip resolves (and reflects\n\t// a renamed sub-agent) before the consumer refreshes `availableSubAgents`.\n\tconst [createdSubAgents, setCreatedSubAgents] = useState<SubAgentRef[]>([]);\n\t// Created/edited refs take precedence over the consumer-supplied list.\n\tconst subAgentById = new Map<string, SubAgentRef>();\n\tavailableSubAgents.forEach((s) => subAgentById.set(s.id, s));\n\tcreatedSubAgents.forEach((s) => subAgentById.set(s.id, s));\n\tconst knownSubAgents = Array.from(subAgentById.values());\n\n\tconst openCreate = useCallback(() => {\n\t\tpanelKeyRef.current += 1;\n\t\tsetPanel({ key: panelKeyRef.current, title: 'Create sub-agent' });\n\t}, []);\n\n\t// Let the `@` picker's \"Create new\" row open this step's drawer.\n\tuseEffect(() => {\n\t\tif (!onCreateSubAgent) {\n\t\t\treturn;\n\t\t}\n\t\tregisterSubAgentCreator(openCreate);\n\t\treturn () => registerSubAgentCreator(null);\n\t}, [registerSubAgentCreator, openCreate, onCreateSubAgent]);\n\n\tconst openConfigure = useCallback(\n\t\tasync (id: string) => {\n\t\t\tif (!onFetchSubAgent) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst data = await onFetchSubAgent(id);\n\t\t\tpanelKeyRef.current += 1;\n\t\t\tsetPanel({\n\t\t\t\tkey: panelKeyRef.current,\n\t\t\t\ttitle: 'Edit sub-agent',\n\t\t\t\teditingId: id,\n\t\t\t\tinitial: data,\n\t\t\t});\n\t\t},\n\t\t[onFetchSubAgent],\n\t);\n\n\tconst handlePanelSave = useCallback(\n\t\tasync (draft: SubAgentDraft) => {\n\t\t\tif (panel?.editingId) {\n\t\t\t\tif (onUpdateSubAgent) {\n\t\t\t\t\tconst ref = await onUpdateSubAgent(panel.editingId, draft);\n\t\t\t\t\tsetCreatedSubAgents((prev) => [\n\t\t\t\t\t\t...prev.filter((s) => s.id !== ref.id),\n\t\t\t\t\t\tref,\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t} else if (onCreateSubAgent) {\n\t\t\t\tconst ref = await onCreateSubAgent(draft);\n\t\t\t\tsetCreatedSubAgents((prev) => [...prev, ref]);\n\t\t\t\tpatch({ subagents: [...value.subagents, ref.id] });\n\t\t\t\tinsertMention('subagent', ref.id, `sub-agent: ${ref.name}`);\n\t\t\t}\n\t\t\tsetPanel(null);\n\t\t},\n\t\t[\n\t\t\tpanel,\n\t\t\tonUpdateSubAgent,\n\t\t\tonCreateSubAgent,\n\t\t\tpatch,\n\t\t\tvalue.subagents,\n\t\t\tinsertMention,\n\t\t],\n\t);\n\n\t// ── Customer verification (auth) ──────────────────────────────────────────\n\t// Order tools (auth_required) can't run unless the customer is verified first,\n\t// so verification is MANDATORY whenever such a tool is attached.\n\tconst hasAuthRequiredTool = value.tools.some(\n\t\t(id) => availableTools.find((t) => t.tool_id === id)?.auth_required,\n\t);\n\tconst authEnabled = value.authentication?.enabled ?? false;\n\tconst authType: Authentication['type'] =\n\t\tvalue.authentication?.type ?? 'email_otp';\n\n\t// Reconcile the invariant: a loaded agent that already holds an auth_required\n\t// tool must have verification on (a fail-closed tool otherwise runs silently).\n\tuseEffect(() => {\n\t\tif (hasAuthRequiredTool && !authEnabled) {\n\t\t\tpatch({ authentication: { enabled: true, type: authType } });\n\t\t}\n\t}, [hasAuthRequiredTool, authEnabled, authType, patch]);\n\n\t// A tool add awaiting the mandatory-verification confirm (null = no prompt).\n\tconst [pendingAuthTool, setPendingAuthTool] = useState<string | null>(null);\n\tconst addTool = useCallback(\n\t\t(id: string) => {\n\t\t\t// Always drop a chip at the cursor; addReference dedupes and reads the\n\t\t\t// latest value.\n\t\t\tinsertMention('tool', id);\n\t\t\taddReference('tool', id);\n\t\t},\n\t\t[insertMention, addReference],\n\t);\n\t// Adding an auth_required tool while verification is off prompts first; confirm\n\t// turns verification on and adds, cancel skips the add.\n\tconst handleAddTool = useCallback(\n\t\t(id: string) => {\n\t\t\tconst tool = availableTools.find((t) => t.tool_id === id);\n\t\t\tif (tool?.auth_required && !authEnabled) {\n\t\t\t\tsetPendingAuthTool(id);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\taddTool(id);\n\t\t},\n\t\t[availableTools, authEnabled, addTool],\n\t);\n\n\tconst toolItems: SelectableItem[] = value.tools\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst tool = availableTools.find((t) => t.tool_id === id);\n\t\t\treturn tool\n\t\t\t\t? {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tlabel: tool.display_name,\n\t\t\t\t\t\ticon: sourceIcon(tool.source ?? ToolSource.Manifest),\n\t\t\t\t\t\tauthRequired: tool.auth_required,\n\t\t\t\t }\n\t\t\t\t: null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\t// Inline-configured tools (Rest API + the shared email / Slack tools) live on\n\t// the value, not in `tools`. They render as rows in the same Tools list, each\n\t// with its own Configure (edit) action that reopens its drawer.\n\tconst restApiItems: SelectableItem[] = (value.restApiTools ?? []).map(\n\t\t(t) => ({\n\t\t\tid: t.id,\n\t\t\tlabel: restApiToolName(t),\n\t\t\ticon: SOURCE_ICONS[ToolSource.RestApi],\n\t\t\tonConfigure: () => openRestApi(t),\n\t\t}),\n\t);\n\tconst configToolItems: SelectableItem[] = (value.configTools ?? []).map(\n\t\t(t) => ({\n\t\t\tid: t.id,\n\t\t\tlabel: configToolName(t),\n\t\t\ticon: SOURCE_ICONS[\n\t\t\t\tt.tool_key === 'send_slack_message'\n\t\t\t\t\t? ToolSource.Slack\n\t\t\t\t\t: ToolSource.EmailHandover\n\t\t\t],\n\t\t\tonConfigure: () => openConfigTool(t.tool_key, t),\n\t\t}),\n\t);\n\tconst allToolItems: SelectableItem[] = [\n\t\t...toolItems,\n\t\t...restApiItems,\n\t\t...configToolItems,\n\t];\n\n\t// Built-in tools that open a config drawer instead of inserting a mention.\n\t// Shown as empty-state buttons AND in the `@` picker's Tools view. The shared\n\t// email / Slack forms are backend-driven, so each is offered only when its\n\t// template was provided.\n\tconst toolActionSources = buildToolActions(\n\t\tconfigToolTemplates,\n\t\topenToolAction,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t);\n\n\t// All tools are offered (even already-added ones) so a tool can be referenced\n\t// again in the text; the chip list below still shows each only once.\n\tconst toolOptions: SingleOption[] = availableTools.map(toolOption);\n\n\t// Group tools by source (Manifest / Shopify / …) for the empty-state buttons.\n\tconst toolSourceGroups: SourceGroup[] = (() => {\n\t\tconst order: string[] = [];\n\t\tconst bySource = new Map<string, SingleOption[]>();\n\t\tavailableTools.forEach((t) => {\n\t\t\tconst src = t.source ?? ToolSource.Manifest;\n\t\t\tif (!bySource.has(src)) {\n\t\t\t\tbySource.set(src, []);\n\t\t\t\torder.push(src);\n\t\t\t}\n\t\t\tbySource.get(src)?.push(toolOption(t));\n\t\t});\n\t\treturn order.map((src) => ({\n\t\t\tsource: src,\n\t\t\tlabel: toolSourceLabel(src),\n\t\t\toptions: bySource.get(src) ?? [],\n\t\t\t// Not connected → the source button opens the connect flow instead of\n\t\t\t// its tool list (see SelectableListSection / onConnectIntegration).\n\t\t\tconnected: integrationStatus?.[src as ToolSource],\n\t\t\tonConnect: () => onConnectIntegration?.(src as ToolSource),\n\t\t}));\n\t})();\n\n\tconst subAgentItems: SelectableItem[] = value.subagents\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst sub = subAgentById.get(id);\n\t\t\treturn sub ? { id, label: sub.name } : null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\tconst subAgentOptions: SingleOption[] = knownSubAgents.map((s) => ({\n\t\tlabel: s.name,\n\t\tvalue: s.id,\n\t}));\n\n\t// Per-section `@`-picker items so the header \"+\" opens the same reference\n\t// picker as the Instructions editor, drilled straight into this section's\n\t// category (tools OR sub-agents).\n\tconst appLabel = appTypeLabel(applicationType);\n\tconst toolMentionItems = [\n\t\t...buildAgentMentionItems(availableTools, [], appLabel),\n\t\t...buildCustomToolMentionItems(value.configTools, value.restApiTools),\n\t];\n\tconst subAgentMentionItems = buildAgentMentionItems(\n\t\t[],\n\t\tknownSubAgents,\n\t\tappLabel,\n\t);\n\n\tconst modelOptions: SingleOption[] = availableModels.map((m) => ({\n\t\tlabel: m.label,\n\t\tvalue: m.value,\n\t\tselected: m.value === value.model,\n\t}));\n\tconst selectedModel = availableModels.find((m) => m.value === value.model);\n\n\t// The template for the open shared-drawer tool (undefined unless a config\n\t// drawer is open and its template was provided).\n\tconst openConfigTemplate =\n\t\ttoolDrawer?.kind === 'config' && toolDrawer.toolKey\n\t\t\t? configToolTemplates?.[toolDrawer.toolKey]\n\t\t\t: undefined;\n\n\treturn (\n\t\t<Step3Root>\n\t\t\t<StepSectionHeader title={STEP.title} helper={STEP.helper} />\n\n\t\t\t<Step3Grid $grow>\n\t\t\t\t<SectionBodyWrap>\n\t\t\t\t\t<MentionField\n\t\t\t\t\t\tfieldKey=\"instructions\"\n\t\t\t\t\t\tdata-test=\"agent-instructions\"\n\t\t\t\t\t\tlabel=\"Instructions\"\n\t\t\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\t\t\tplaceholder=\"Write the steps in plain English. The agent will follow them exactly. The more specific you are, the better it performs.\"\n\t\t\t\t\t\tminHeight=\"200px\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<MentionField\n\t\t\t\t\t\tfieldKey=\"guardrail\"\n\t\t\t\t\t\tdata-test=\"agent-guardrail\"\n\t\t\t\t\t\tlabel=\"Guardrails\"\n\t\t\t\t\t\tmaxLength={charLimits.guardrail}\n\t\t\t\t\t\tplaceholder=\"e.g. Never discuss competitor pricing. Always stay within the cancellation policy. Do not process refunds above ₹10,000 without human approval.\"\n\t\t\t\t\t\tminHeight=\"140px\"\n\t\t\t\t\t/>\n\t\t\t\t</SectionBodyWrap>\n\n\t\t\t\t<Step3Divider />\n\n\t\t\t\t<SectionBodyWrap>\n\t\t\t\t\t<SelectableListSection\n\t\t\t\t\t\ttitle=\"Tools\"\n\t\t\t\t\t\thelper=\"Actions this agent can take while responding.\"\n\t\t\t\t\t\tdataTestPrefix=\"agent-tools\"\n\t\t\t\t\t\titems={allToolItems}\n\t\t\t\t\t\taddableOptions={toolOptions}\n\t\t\t\t\t\tsourceGroups={toolSourceGroups}\n\t\t\t\t\t\tmentionItems={toolMentionItems}\n\t\t\t\t\t\tactionSources={toolActionSources}\n\t\t\t\t\t\temptyText=\"No tools added yet.\"\n\t\t\t\t\t\tonAdd={handleAddTool}\n\t\t\t\t\t\t// Strips the tool's tokens AND drops it from whichever list holds it\n\t\t\t\t\t\t// (catalog `tools` or an inline custom-tool list).\n\t\t\t\t\t\tonRemove={(id) => removeReference('tool', id)}\n\t\t\t\t\t\tconfirmDelete={{ noun: 'tool' }}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<SelectableListSection\n\t\t\t\t\t\ttitle=\"Sub-agents\"\n\t\t\t\t\t\thelper=\"Other agents this agent can hand off the conversation to.\"\n\t\t\t\t\t\tdataTestPrefix=\"agent-subagents\"\n\t\t\t\t\t\titems={subAgentItems}\n\t\t\t\t\t\taddableOptions={subAgentOptions}\n\t\t\t\t\t\tmentionItems={subAgentMentionItems}\n\t\t\t\t\t\temptyText=\"No sub-agents added yet.\"\n\t\t\t\t\t\tonAdd={(id) => {\n\t\t\t\t\t\t\tinsertMention('subagent', id);\n\t\t\t\t\t\t\taddReference('subagent', id);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonRemove={(id) => removeReference('subagent', id)}\n\t\t\t\t\t\tconfirmDelete={{ noun: 'sub-agent' }}\n\t\t\t\t\t\tonConfigure={onFetchSubAgent ? openConfigure : undefined}\n\t\t\t\t\t\tcreateOption={\n\t\t\t\t\t\t\tonCreateSubAgent\n\t\t\t\t\t\t\t\t? { label: 'Create new', onSelect: openCreate }\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<SideSection>\n\t\t\t\t\t\t<SideSectionHeader>\n\t\t\t\t\t\t\t<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n\t\t\t\t\t\t\t\t<Shield size={20} />\n\t\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\tRequire customer verification\n\t\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\t\tdata-test=\"agent-auth-toggle\"\n\t\t\t\t\t\t\t\tvalue={authEnabled || hasAuthRequiredTool}\n\t\t\t\t\t\t\t\t// Mandatory (can't turn off) while an auth_required tool is attached.\n\t\t\t\t\t\t\t\tdisabled={hasAuthRequiredTool}\n\t\t\t\t\t\t\t\tonValueChange={async (enabled) => {\n\t\t\t\t\t\t\t\t\tpatch({ authentication: { enabled, type: authType } });\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</SideSectionHeader>\n\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t{hasAuthRequiredTool\n\t\t\t\t\t\t\t\t? 'Required — this agent uses a tool that accesses customer order details.'\n\t\t\t\t\t\t\t\t: 'Customers must verify their identity before this agent responds.'}\n\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t{(authEnabled || hasAuthRequiredTool) && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\tSelect verification method\n\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\t\t\tdata-test=\"agent-auth-method\"\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\t\t\t// Popover is portalled, so \"100%\" collapses to content width —\n\t\t\t\t\t\t\t\t\t// match the input: 360px side column − 2×16px padding.\n\t\t\t\t\t\t\t\t\tdropdownWidth=\"328px\"\n\t\t\t\t\t\t\t\t\tplaceHolder=\"Select verification method\"\n\t\t\t\t\t\t\t\t\toptions={AUTH_METHOD_OPTIONS}\n\t\t\t\t\t\t\t\t\tdefaultOptions={[\n\t\t\t\t\t\t\t\t\t\tAUTH_METHOD_OPTIONS.find((o) => o.value === authType) ??\n\t\t\t\t\t\t\t\t\t\t\tAUTH_METHOD_OPTIONS[0],\n\t\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\t\t\t\t\tpatch({\n\t\t\t\t\t\t\t\t\t\t\t\tauthentication: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: v as Authentication['type'],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</SideSection>\n\n\t\t\t\t\t{availableModels.length > 0 && (\n\t\t\t\t\t\t<SideSection>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\tAdvanced settings\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\tSelect AI model\n\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\t\tdata-test=\"agent-model\"\n\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\t\t// Popover is portalled, so \"100%\" collapses to content width —\n\t\t\t\t\t\t\t\t// match the input: 360px side column − 2×16px SectionBodyWrap\n\t\t\t\t\t\t\t\t// padding.\n\t\t\t\t\t\t\t\tdropdownWidth=\"328px\"\n\t\t\t\t\t\t\t\tplaceHolder=\"Select model\"\n\t\t\t\t\t\t\t\toptions={modelOptions}\n\t\t\t\t\t\t\t\tdefaultOptions={\n\t\t\t\t\t\t\t\t\tselectedModel\n\t\t\t\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tlabel: selectedModel.label,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: selectedModel.value,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t ]\n\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\t\t\t\tupdateField('model', v);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</SideSection>\n\t\t\t\t\t)}\n\t\t\t\t</SectionBodyWrap>\n\t\t\t</Step3Grid>\n\n\t\t\t{panel && (\n\t\t\t\t<CreateSubAgentPanel\n\t\t\t\t\tkey={panel.key}\n\t\t\t\t\ttitle={panel.title}\n\t\t\t\t\tinitial={panel.initial}\n\t\t\t\t\tavailableTools={availableTools}\n\t\t\t\t\tconfigToolTemplates={configToolTemplates}\n\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\tappLabel={appTypeLabel(applicationType)}\n\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\tonImprove={onImproveSubAgent}\n\t\t\t\t\tonImproveToolInstructions={onImproveToolInstructions}\n\t\t\t\t\tonClose={() => setPanel(null)}\n\t\t\t\t\tonSave={handlePanelSave}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{toolDrawer?.kind === 'restapi' && (\n\t\t\t\t<RestApiToolPanel\n\t\t\t\t\tkey={toolDrawer.key}\n\t\t\t\t\tinitial={toolDrawer.initialRest}\n\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\t// Block reusing another tool's name (exclude the one being edited).\n\t\t\t\t\texistingNames={(value.restApiTools ?? [])\n\t\t\t\t\t\t.filter((t) => t.id !== toolDrawer.initialRest?.id)\n\t\t\t\t\t\t.map((t) => t.name)}\n\t\t\t\t\tonImprove={onImproveToolInstructions}\n\t\t\t\t\tonClose={() => setToolDrawer(null)}\n\t\t\t\t\tonSave={handleSaveRestApi}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{toolDrawer?.kind === 'config' &&\n\t\t\t\ttoolDrawer.toolKey &&\n\t\t\t\topenConfigTemplate && (\n\t\t\t\t\t<ConfigToolPanel\n\t\t\t\t\t\tkey={toolDrawer.key}\n\t\t\t\t\t\ttoolKey={toolDrawer.toolKey}\n\t\t\t\t\t\ttemplate={openConfigTemplate}\n\t\t\t\t\t\tinitial={toolDrawer.initialConfig}\n\t\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\t\tonImprove={onImproveToolInstructions}\n\t\t\t\t\t\tonClose={() => setToolDrawer(null)}\n\t\t\t\t\t\tonSave={handleSaveConfigTool}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\n\t\t\t<RequireVerificationModal\n\t\t\t\topen={pendingAuthTool !== null}\n\t\t\t\ttoolLabel={\n\t\t\t\t\tavailableTools.find((t) => t.tool_id === pendingAuthTool)\n\t\t\t\t\t\t?.display_name ?? 'This tool'\n\t\t\t\t}\n\t\t\t\tonCancel={() => setPendingAuthTool(null)}\n\t\t\t\tonConfirm={() => {\n\t\t\t\t\tpatch({ authentication: { enabled: true, type: authType } });\n\t\t\t\t\tif (pendingAuthTool) {\n\t\t\t\t\t\taddTool(pendingAuthTool);\n\t\t\t\t\t}\n\t\t\t\t\tsetPendingAuthTool(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t</Step3Root>\n\t);\n};\n"],"names":["toolIconEl","source","renderSourceIcon","sourceIcon","toolOption","t","ToolSource","STEP","STEP_DEFINITIONS","AUTH_METHOD_OPTIONS","upsertById","list","item","arr","x","Step3HowItResponds","value","patch","updateField","addReference","removeReference","availableTools","availableSubAgents","availableModels","configToolTemplates","applicationType","charLimits","insertMention","onCreateSubAgent","onFetchSubAgent","onUpdateSubAgent","onImproveSubAgent","onImproveToolInstructions","registerSubAgentCreator","registerToolActionHandler","integrationStatus","onConnectIntegration","variablesData","useAgentBuilderContext","panel","setPanel","useState","panelKeyRef","useRef","toolDrawer","setToolDrawer","toolDrawerKeyRef","openRestApi","useCallback","initial","openConfigTool","toolKey","handleSaveRestApi","config","isNew","restApiMentionItem","handleSaveConfigTool","configToolMentionItem","openToolAction","CONFIG_TOOL_SOURCES","useEffect","createdSubAgents","setCreatedSubAgents","subAgentById","s","knownSubAgents","openCreate","openConfigure","id","data","handlePanelSave","draft","ref","prev","hasAuthRequiredTool","authEnabled","authType","pendingAuthTool","setPendingAuthTool","addTool","handleAddTool","toolItems","tool","restApiItems","restApiToolName","SOURCE_ICONS","configToolItems","configToolName","allToolItems","toolActionSources","buildToolActions","toolOptions","toolSourceGroups","order","bySource","src","toolSourceLabel","subAgentItems","sub","subAgentOptions","appLabel","appTypeLabel","toolMentionItems","buildAgentMentionItems","buildCustomToolMentionItems","subAgentMentionItems","modelOptions","m","selectedModel","openConfigTemplate","Step3Root","jsx","StepSectionHeader","jsxs","Step3Grid","SectionBodyWrap","MentionField","Step3Divider","SelectableListSection","SideSection","SideSectionHeader","Shield","TitleSmall","COLORS","Switch","enabled","BodyCaption","Fragment","BodySecondary","Dropdown","o","opt","v","unwrapDropdownValue","CreateSubAgentPanel","RestApiToolPanel","ConfigToolPanel","RequireVerificationModal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Step3HowItResponds.js","sources":["../../../../../src/components/agent-builder/steps/Step3HowItResponds.tsx"],"sourcesContent":["import { Shield } from '@src/icons';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Dropdown, unwrapDropdownValue } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { Switch } from '@src/components/switch';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tAgentTool,\n\tAuthentication,\n\tConfigToolConfig,\n\tConfigToolKey,\n\tRestApiToolConfig,\n\tSubAgentDraft,\n\tSubAgentRef,\n} from '../AgentBuilder.model';\nimport {\n\tSectionBodyWrap,\n\tSideSection,\n\tSideSectionHeader,\n\tStep3Divider,\n\tStep3Grid,\n\tStep3Root,\n} from '../AgentBuilder.styled';\nimport { ConfigToolPanel } from '../components/ConfigToolPanel';\nimport { CreateSubAgentPanel } from '../components/CreateSubAgentPanel';\nimport { MentionField } from '../components/MentionField';\nimport { RequireVerificationModal } from '../components/RequireVerificationModal';\nimport { RestApiToolPanel } from '../components/RestApiToolPanel';\nimport {\n\tSelectableItem,\n\tSelectableListSection,\n\tSourceGroup,\n} from '../components/SelectableListSection';\nimport { StepSectionHeader } from '../components/StepSectionHeader';\nimport { STEP_DEFINITIONS } from '../constants/steps';\nimport { CONFIG_TOOL_SOURCES, ToolSource } from '../constants/tools';\nimport { useAgentBuilderContext } from '../context/AgentBuilderContext';\nimport {\n\tappTypeLabel,\n\tbuildAgentMentionItems,\n\tbuildCustomToolMentionItems,\n\tconfigToolMentionItem,\n\tconfigToolName,\n\trestApiMentionItem,\n\trestApiToolName,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport {\n\trenderSourceIcon,\n\tSOURCE_ICONS,\n\tsourceIcon,\n} from '../utils/sourceIcons';\nimport { buildToolActions } from '../utils/toolActions';\n\n/** Source brand glyph for a tool, as a dropdown leadingIcon element. */\nconst toolIconEl = (source: string): JSX.Element | undefined =>\n\trenderSourceIcon(sourceIcon(source)) ?? undefined;\n\n/** Dropdown option for a tool: icon left of the name, no description. */\nconst toolOption = (t: AgentTool): SingleOption => ({\n\tlabel: t.display_name,\n\tvalue: t.tool_id,\n\tleadingIcon: toolIconEl(t.source ?? ToolSource.Manifest),\n});\n\nconst STEP = STEP_DEFINITIONS[2];\n\n/** Customer-verification OTP methods, in the dropdown's display order. */\nconst AUTH_METHOD_OPTIONS: SingleOption[] = [\n\t{ label: 'OTP to phone', value: 'phone_otp' },\n\t{ label: 'OTP to email', value: 'email_otp' },\n];\n\n/** Drawer state — null when closed; `key` remounts it fresh per open. */\ninterface SubAgentPanelState {\n\tkey: number;\n\ttitle: string;\n\teditingId?: string;\n\tinitial?: SubAgentDraft;\n}\n\n/**\n * Config-tool drawer state; `key` remounts fresh. `restapi` is the bespoke Rest\n * API panel; `config` is the shared dynamic panel (email / Slack), tagged with\n * its `toolKey`.\n */\ninterface ToolDrawerState {\n\tkey: number;\n\tkind: 'restapi' | 'config';\n\ttoolKey?: ConfigToolKey;\n\tinitialRest?: RestApiToolConfig;\n\tinitialConfig?: ConfigToolConfig;\n}\n\n/** Upsert an item by id (replace when present, append otherwise). */\nconst upsertById = <T extends { id: string }>(\n\tlist: T[] | undefined,\n\titem: T,\n): T[] => {\n\tconst arr = list ?? [];\n\treturn arr.some((x) => x.id === item.id)\n\t\t? arr.map((x) => (x.id === item.id ? item : x))\n\t\t: [...arr, item];\n};\n\nexport const Step3HowItResponds: React.FC = () => {\n\tconst {\n\t\tvalue,\n\t\tpatch,\n\t\tupdateField,\n\t\taddReference,\n\t\tremoveReference,\n\t\tavailableTools,\n\t\tavailableSubAgents,\n\t\tavailableModels,\n\t\tconfigToolTemplates,\n\t\tapplicationType,\n\t\tcharLimits,\n\t\tinsertMention,\n\t\tonCreateSubAgent,\n\t\tonFetchSubAgent,\n\t\tonUpdateSubAgent,\n\t\tonImproveSubAgent,\n\t\tonImproveToolInstructions,\n\t\tregisterSubAgentCreator,\n\t\tregisterToolActionHandler,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t\tvariablesData,\n\t} = useAgentBuilderContext();\n\n\tconst [panel, setPanel] = useState<SubAgentPanelState | null>(null);\n\tconst panelKeyRef = useRef(0);\n\n\t// Rest API (bespoke) + shared config-tool drawers (separate from the sub-agent one).\n\tconst [toolDrawer, setToolDrawer] = useState<ToolDrawerState | null>(null);\n\tconst toolDrawerKeyRef = useRef(0);\n\tconst openRestApi = useCallback((initial?: RestApiToolConfig) => {\n\t\ttoolDrawerKeyRef.current += 1;\n\t\tsetToolDrawer({\n\t\t\tkey: toolDrawerKeyRef.current,\n\t\t\tkind: 'restapi',\n\t\t\tinitialRest: initial,\n\t\t});\n\t}, []);\n\tconst openConfigTool = useCallback(\n\t\t(toolKey: ConfigToolKey, initial?: ConfigToolConfig) => {\n\t\t\ttoolDrawerKeyRef.current += 1;\n\t\t\tsetToolDrawer({\n\t\t\t\tkey: toolDrawerKeyRef.current,\n\t\t\t\tkind: 'config',\n\t\t\t\ttoolKey,\n\t\t\t\tinitialConfig: initial,\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\tconst handleSaveRestApi = useCallback(\n\t\t(config: RestApiToolConfig) => {\n\t\t\tconst isNew = !(value.restApiTools ?? []).some((t) => t.id === config.id);\n\t\t\tpatch({ restApiTools: upsertById(value.restApiTools, config) });\n\t\t\t// Drop a reference chip at the cursor on creation (edits keep the chip).\n\t\t\tif (isNew) {\n\t\t\t\tinsertMention('tool', config.id, restApiMentionItem(config).label);\n\t\t\t}\n\t\t\tsetToolDrawer(null);\n\t\t},\n\t\t[patch, value.restApiTools, insertMention],\n\t);\n\tconst handleSaveConfigTool = useCallback(\n\t\t(config: ConfigToolConfig) => {\n\t\t\tconst isNew = !(value.configTools ?? []).some((t) => t.id === config.id);\n\t\t\tpatch({ configTools: upsertById(value.configTools, config) });\n\t\t\tif (isNew) {\n\t\t\t\tinsertMention('tool', config.id, configToolMentionItem(config).label);\n\t\t\t}\n\t\t\tsetToolDrawer(null);\n\t\t},\n\t\t[patch, value.configTools, insertMention],\n\t);\n\n\t// Open a tool action's drawer by picker source (restapi / email / slack).\n\tconst openToolAction = useCallback(\n\t\t(source: ToolSource) => {\n\t\t\tconst toolKey = CONFIG_TOOL_SOURCES[source];\n\t\t\tif (toolKey) {\n\t\t\t\topenConfigTool(toolKey);\n\t\t\t} else {\n\t\t\t\topenRestApi();\n\t\t\t}\n\t\t},\n\t\t[openConfigTool, openRestApi],\n\t);\n\t// Let the `@` reference picker (Instructions / Guardrails) open these drawers.\n\tuseEffect(() => {\n\t\tregisterToolActionHandler(openToolAction);\n\t\treturn () => registerToolActionHandler(null);\n\t}, [registerToolActionHandler, openToolAction]);\n\t// Sub-agents created / edited in this session, so a chip resolves (and reflects\n\t// a renamed sub-agent) before the consumer refreshes `availableSubAgents`.\n\tconst [createdSubAgents, setCreatedSubAgents] = useState<SubAgentRef[]>([]);\n\t// Created/edited refs take precedence over the consumer-supplied list.\n\tconst subAgentById = new Map<string, SubAgentRef>();\n\tavailableSubAgents.forEach((s) => subAgentById.set(s.id, s));\n\tcreatedSubAgents.forEach((s) => subAgentById.set(s.id, s));\n\tconst knownSubAgents = Array.from(subAgentById.values());\n\n\tconst openCreate = useCallback(() => {\n\t\tpanelKeyRef.current += 1;\n\t\tsetPanel({ key: panelKeyRef.current, title: 'Create sub-agent' });\n\t}, []);\n\n\t// Let the `@` picker's \"Create new\" row open this step's drawer.\n\tuseEffect(() => {\n\t\tif (!onCreateSubAgent) {\n\t\t\treturn;\n\t\t}\n\t\tregisterSubAgentCreator(openCreate);\n\t\treturn () => registerSubAgentCreator(null);\n\t}, [registerSubAgentCreator, openCreate, onCreateSubAgent]);\n\n\tconst openConfigure = useCallback(\n\t\tasync (id: string) => {\n\t\t\tif (!onFetchSubAgent) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst data = await onFetchSubAgent(id);\n\t\t\tpanelKeyRef.current += 1;\n\t\t\tsetPanel({\n\t\t\t\tkey: panelKeyRef.current,\n\t\t\t\ttitle: 'Edit sub-agent',\n\t\t\t\teditingId: id,\n\t\t\t\tinitial: data,\n\t\t\t});\n\t\t},\n\t\t[onFetchSubAgent],\n\t);\n\n\tconst handlePanelSave = useCallback(\n\t\tasync (draft: SubAgentDraft) => {\n\t\t\tif (panel?.editingId) {\n\t\t\t\tif (onUpdateSubAgent) {\n\t\t\t\t\tconst ref = await onUpdateSubAgent(panel.editingId, draft);\n\t\t\t\t\tsetCreatedSubAgents((prev) => [\n\t\t\t\t\t\t...prev.filter((s) => s.id !== ref.id),\n\t\t\t\t\t\tref,\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t} else if (onCreateSubAgent) {\n\t\t\t\tconst ref = await onCreateSubAgent(draft);\n\t\t\t\tsetCreatedSubAgents((prev) => [...prev, ref]);\n\t\t\t\tpatch({ subagents: [...value.subagents, ref.id] });\n\t\t\t\tinsertMention('subagent', ref.id, `sub-agent: ${ref.name}`);\n\t\t\t}\n\t\t\tsetPanel(null);\n\t\t},\n\t\t[\n\t\t\tpanel,\n\t\t\tonUpdateSubAgent,\n\t\t\tonCreateSubAgent,\n\t\t\tpatch,\n\t\t\tvalue.subagents,\n\t\t\tinsertMention,\n\t\t],\n\t);\n\n\t// ── Customer verification (auth) ──────────────────────────────────────────\n\t// Order tools (auth_required) can't run unless the customer is verified first,\n\t// so verification is MANDATORY whenever such a tool is attached.\n\tconst hasAuthRequiredTool = value.tools.some(\n\t\t(id) => availableTools.find((t) => t.tool_id === id)?.auth_required,\n\t);\n\tconst authEnabled = value.authentication?.enabled ?? false;\n\tconst authType: Authentication['type'] =\n\t\tvalue.authentication?.type ?? 'email_otp';\n\n\t// Reconcile the invariant: a loaded agent that already holds an auth_required\n\t// tool must have verification on (a fail-closed tool otherwise runs silently).\n\tuseEffect(() => {\n\t\tif (hasAuthRequiredTool && !authEnabled) {\n\t\t\tpatch({ authentication: { enabled: true, type: authType } });\n\t\t}\n\t}, [hasAuthRequiredTool, authEnabled, authType, patch]);\n\n\t// A tool add awaiting the mandatory-verification confirm (null = no prompt).\n\tconst [pendingAuthTool, setPendingAuthTool] = useState<string | null>(null);\n\tconst addTool = useCallback(\n\t\t(id: string) => {\n\t\t\t// Always drop a chip at the cursor; addReference dedupes and reads the\n\t\t\t// latest value.\n\t\t\tinsertMention('tool', id);\n\t\t\taddReference('tool', id);\n\t\t},\n\t\t[insertMention, addReference],\n\t);\n\t// Adding an auth_required tool while verification is off prompts first; confirm\n\t// turns verification on and adds, cancel skips the add.\n\tconst handleAddTool = useCallback(\n\t\t(id: string) => {\n\t\t\tconst tool = availableTools.find((t) => t.tool_id === id);\n\t\t\tif (tool?.auth_required && !authEnabled) {\n\t\t\t\tsetPendingAuthTool(id);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\taddTool(id);\n\t\t},\n\t\t[availableTools, authEnabled, addTool],\n\t);\n\n\tconst toolItems: SelectableItem[] = value.tools\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst tool = availableTools.find((t) => t.tool_id === id);\n\t\t\treturn tool\n\t\t\t\t? {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tlabel: tool.display_name,\n\t\t\t\t\t\ticon: sourceIcon(tool.source ?? ToolSource.Manifest),\n\t\t\t\t\t\tauthRequired: tool.auth_required,\n\t\t\t\t }\n\t\t\t\t: null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\t// Inline-configured tools (Rest API + the shared email / Slack tools) live on\n\t// the value, not in `tools`. They render as rows in the same Tools list, each\n\t// with its own Configure (edit) action that reopens its drawer.\n\tconst restApiItems: SelectableItem[] = (value.restApiTools ?? []).map(\n\t\t(t) => ({\n\t\t\tid: t.id,\n\t\t\tlabel: restApiToolName(t),\n\t\t\ticon: SOURCE_ICONS[ToolSource.RestApi],\n\t\t\tonConfigure: () => openRestApi(t),\n\t\t}),\n\t);\n\tconst configToolItems: SelectableItem[] = (value.configTools ?? []).map(\n\t\t(t) => ({\n\t\t\tid: t.id,\n\t\t\tlabel: configToolName(t),\n\t\t\ticon: SOURCE_ICONS[\n\t\t\t\tt.tool_key === 'send_slack_message'\n\t\t\t\t\t? ToolSource.Slack\n\t\t\t\t\t: ToolSource.EmailHandover\n\t\t\t],\n\t\t\tonConfigure: () => openConfigTool(t.tool_key, t),\n\t\t}),\n\t);\n\tconst allToolItems: SelectableItem[] = [\n\t\t...toolItems,\n\t\t...restApiItems,\n\t\t...configToolItems,\n\t];\n\n\t// Built-in tools that open a config drawer instead of inserting a mention.\n\t// Shown as empty-state buttons AND in the `@` picker's Tools view. The shared\n\t// email / Slack forms are backend-driven, so each is offered only when its\n\t// template was provided.\n\tconst toolActionSources = buildToolActions(\n\t\tconfigToolTemplates,\n\t\topenToolAction,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t);\n\n\t// All tools are offered (even already-added ones) so a tool can be referenced\n\t// again in the text; the chip list below still shows each only once.\n\tconst toolOptions: SingleOption[] = availableTools.map(toolOption);\n\n\t// Group tools by source (Manifest / Shopify / …) for the empty-state buttons.\n\tconst toolSourceGroups: SourceGroup[] = (() => {\n\t\tconst order: string[] = [];\n\t\tconst bySource = new Map<string, SingleOption[]>();\n\t\tavailableTools.forEach((t) => {\n\t\t\tconst src = t.source ?? ToolSource.Manifest;\n\t\t\tif (!bySource.has(src)) {\n\t\t\t\tbySource.set(src, []);\n\t\t\t\torder.push(src);\n\t\t\t}\n\t\t\tbySource.get(src)?.push(toolOption(t));\n\t\t});\n\t\treturn order.map((src) => ({\n\t\t\tsource: src,\n\t\t\tlabel: toolSourceLabel(src),\n\t\t\toptions: bySource.get(src) ?? [],\n\t\t\t// Not connected → the source button opens the connect flow instead of\n\t\t\t// its tool list (see SelectableListSection / onConnectIntegration).\n\t\t\tconnected: integrationStatus?.[src as ToolSource],\n\t\t\tonConnect: () => onConnectIntegration?.(src as ToolSource),\n\t\t}));\n\t})();\n\n\tconst subAgentItems: SelectableItem[] = value.subagents\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst sub = subAgentById.get(id);\n\t\t\treturn sub ? { id, label: sub.name } : null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\tconst subAgentOptions: SingleOption[] = knownSubAgents.map((s) => ({\n\t\tlabel: s.name,\n\t\tvalue: s.id,\n\t}));\n\n\t// Per-section `@`-picker items so the header \"+\" opens the same reference\n\t// picker as the Instructions editor, drilled straight into this section's\n\t// category (tools OR sub-agents).\n\tconst appLabel = appTypeLabel(applicationType);\n\tconst toolMentionItems = [\n\t\t...buildAgentMentionItems(availableTools, [], appLabel),\n\t\t...buildCustomToolMentionItems(value.configTools, value.restApiTools),\n\t];\n\tconst subAgentMentionItems = buildAgentMentionItems(\n\t\t[],\n\t\tknownSubAgents,\n\t\tappLabel,\n\t);\n\n\tconst modelOptions: SingleOption[] = availableModels.map((m) => ({\n\t\tlabel: m.label,\n\t\tvalue: m.value,\n\t\tselected: m.value === value.model,\n\t}));\n\tconst selectedModel = availableModels.find((m) => m.value === value.model);\n\n\t// The template for the open shared-drawer tool (undefined unless a config\n\t// drawer is open and its template was provided).\n\tconst openConfigTemplate =\n\t\ttoolDrawer?.kind === 'config' && toolDrawer.toolKey\n\t\t\t? configToolTemplates?.[toolDrawer.toolKey]\n\t\t\t: undefined;\n\n\treturn (\n\t\t<Step3Root>\n\t\t\t<StepSectionHeader title={STEP.title} helper={STEP.helper} />\n\n\t\t\t<Step3Grid $grow>\n\t\t\t\t<SectionBodyWrap>\n\t\t\t\t\t<MentionField\n\t\t\t\t\t\tfieldKey=\"instructions\"\n\t\t\t\t\t\tdata-test=\"agent-instructions\"\n\t\t\t\t\t\tlabel=\"Instructions\"\n\t\t\t\t\t\tmaxLength={charLimits.instructions}\n\t\t\t\t\t\tplaceholder=\"Write the steps in plain English. The agent will follow them exactly. The more specific you are, the better it performs.\"\n\t\t\t\t\t\tminHeight=\"200px\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<MentionField\n\t\t\t\t\t\tfieldKey=\"guardrail\"\n\t\t\t\t\t\tdata-test=\"agent-guardrail\"\n\t\t\t\t\t\tlabel=\"Guardrails\"\n\t\t\t\t\t\tmaxLength={charLimits.guardrail}\n\t\t\t\t\t\tplaceholder=\"e.g. Never discuss competitor pricing. Always stay within the cancellation policy. Do not process refunds above ₹10,000 without human approval.\"\n\t\t\t\t\t\tminHeight=\"140px\"\n\t\t\t\t\t/>\n\t\t\t\t</SectionBodyWrap>\n\n\t\t\t\t<Step3Divider />\n\n\t\t\t\t<SectionBodyWrap>\n\t\t\t\t\t<SelectableListSection\n\t\t\t\t\t\ttitle=\"Tools\"\n\t\t\t\t\t\thelper=\"Actions this agent can take while responding.\"\n\t\t\t\t\t\tdataTestPrefix=\"agent-tools\"\n\t\t\t\t\t\titems={allToolItems}\n\t\t\t\t\t\taddableOptions={toolOptions}\n\t\t\t\t\t\tsourceGroups={toolSourceGroups}\n\t\t\t\t\t\tmentionItems={toolMentionItems}\n\t\t\t\t\t\tactionSources={toolActionSources}\n\t\t\t\t\t\temptyText=\"No tools added yet.\"\n\t\t\t\t\t\tonAdd={handleAddTool}\n\t\t\t\t\t\t// Strips the tool's tokens AND drops it from whichever list holds it\n\t\t\t\t\t\t// (catalog `tools` or an inline custom-tool list).\n\t\t\t\t\t\tonRemove={(id) => removeReference('tool', id)}\n\t\t\t\t\t\tconfirmDelete={{ noun: 'tool' }}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<SelectableListSection\n\t\t\t\t\t\ttitle=\"Sub-agents\"\n\t\t\t\t\t\thelper=\"Other agents this agent can hand off the conversation to.\"\n\t\t\t\t\t\tdataTestPrefix=\"agent-subagents\"\n\t\t\t\t\t\titems={subAgentItems}\n\t\t\t\t\t\taddableOptions={subAgentOptions}\n\t\t\t\t\t\tmentionItems={subAgentMentionItems}\n\t\t\t\t\t\temptyText=\"No sub-agents added yet.\"\n\t\t\t\t\t\tonAdd={(id) => {\n\t\t\t\t\t\t\tinsertMention('subagent', id);\n\t\t\t\t\t\t\taddReference('subagent', id);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonRemove={(id) => removeReference('subagent', id)}\n\t\t\t\t\t\tconfirmDelete={{ noun: 'sub-agent' }}\n\t\t\t\t\t\tonConfigure={onFetchSubAgent ? openConfigure : undefined}\n\t\t\t\t\t\tcreateOption={\n\t\t\t\t\t\t\tonCreateSubAgent\n\t\t\t\t\t\t\t\t? { label: 'Create new', onSelect: openCreate }\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<SideSection>\n\t\t\t\t\t\t<SideSectionHeader>\n\t\t\t\t\t\t\t<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n\t\t\t\t\t\t\t\t<Shield size={20} />\n\t\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\tRequire customer verification\n\t\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\t\tdata-test=\"agent-auth-toggle\"\n\t\t\t\t\t\t\t\tvalue={authEnabled || hasAuthRequiredTool}\n\t\t\t\t\t\t\t\t// Mandatory (can't turn off) while an auth_required tool is attached.\n\t\t\t\t\t\t\t\tdisabled={hasAuthRequiredTool}\n\t\t\t\t\t\t\t\tonValueChange={async (enabled) => {\n\t\t\t\t\t\t\t\t\tpatch({ authentication: { enabled, type: authType } });\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</SideSectionHeader>\n\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t{hasAuthRequiredTool\n\t\t\t\t\t\t\t\t? 'Required — this agent uses a tool that accesses customer order details.'\n\t\t\t\t\t\t\t\t: 'Customers must verify their identity before this agent responds.'}\n\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t{(authEnabled || hasAuthRequiredTool) && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\tSelect verification method\n\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\t\t\tdata-test=\"agent-auth-method\"\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\t\t\t// Popover is portalled, so \"100%\" collapses to content width —\n\t\t\t\t\t\t\t\t\t// match the input: 360px side column − 2×16px padding.\n\t\t\t\t\t\t\t\t\tdropdownWidth=\"328px\"\n\t\t\t\t\t\t\t\t\tplaceHolder=\"Select verification method\"\n\t\t\t\t\t\t\t\t\toptions={AUTH_METHOD_OPTIONS}\n\t\t\t\t\t\t\t\t\tdefaultOptions={[\n\t\t\t\t\t\t\t\t\t\tAUTH_METHOD_OPTIONS.find((o) => o.value === authType) ??\n\t\t\t\t\t\t\t\t\t\t\tAUTH_METHOD_OPTIONS[0],\n\t\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\t\t\t\t\tpatch({\n\t\t\t\t\t\t\t\t\t\t\t\tauthentication: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: v as Authentication['type'],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</SideSection>\n\n\t\t\t\t\t{availableModels.length > 0 && (\n\t\t\t\t\t\t<SideSection>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\tAdvanced settings\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\tSelect AI model\n\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\t\tdata-test=\"agent-model\"\n\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\t\t// Popover is portalled, so \"100%\" collapses to content width —\n\t\t\t\t\t\t\t\t// match the input: 360px side column − 2×16px SectionBodyWrap\n\t\t\t\t\t\t\t\t// padding.\n\t\t\t\t\t\t\t\tdropdownWidth=\"328px\"\n\t\t\t\t\t\t\t\tplaceHolder=\"Select model\"\n\t\t\t\t\t\t\t\toptions={modelOptions}\n\t\t\t\t\t\t\t\tdefaultOptions={\n\t\t\t\t\t\t\t\t\tselectedModel\n\t\t\t\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tlabel: selectedModel.label,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: selectedModel.value,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t ]\n\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\t\t\t\tupdateField('model', v);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</SideSection>\n\t\t\t\t\t)}\n\t\t\t\t</SectionBodyWrap>\n\t\t\t</Step3Grid>\n\n\t\t\t{panel && (\n\t\t\t\t<CreateSubAgentPanel\n\t\t\t\t\tkey={panel.key}\n\t\t\t\t\ttitle={panel.title}\n\t\t\t\t\tinitial={panel.initial}\n\t\t\t\t\tavailableTools={availableTools}\n\t\t\t\t\tconfigToolTemplates={configToolTemplates}\n\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\tappLabel={appTypeLabel(applicationType)}\n\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\tonImprove={onImproveSubAgent}\n\t\t\t\t\tonImproveToolInstructions={onImproveToolInstructions}\n\t\t\t\t\tonClose={() => setPanel(null)}\n\t\t\t\t\tonSave={handlePanelSave}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{toolDrawer?.kind === 'restapi' && (\n\t\t\t\t<RestApiToolPanel\n\t\t\t\t\tkey={toolDrawer.key}\n\t\t\t\t\tinitial={toolDrawer.initialRest}\n\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t// Block reusing another tool's name (exclude the one being edited).\n\t\t\t\t\texistingNames={(value.restApiTools ?? [])\n\t\t\t\t\t\t.filter((t) => t.id !== toolDrawer.initialRest?.id)\n\t\t\t\t\t\t.map((t) => t.name)}\n\t\t\t\t\tonImprove={onImproveToolInstructions}\n\t\t\t\t\tonClose={() => setToolDrawer(null)}\n\t\t\t\t\tonSave={handleSaveRestApi}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{toolDrawer?.kind === 'config' &&\n\t\t\t\ttoolDrawer.toolKey &&\n\t\t\t\topenConfigTemplate && (\n\t\t\t\t\t<ConfigToolPanel\n\t\t\t\t\t\tkey={toolDrawer.key}\n\t\t\t\t\t\ttoolKey={toolDrawer.toolKey}\n\t\t\t\t\t\ttemplate={openConfigTemplate}\n\t\t\t\t\t\tinitial={toolDrawer.initialConfig}\n\t\t\t\t\t\tcharLimits={charLimits}\n\t\t\t\t\t\tvariablesData={variablesData}\n\t\t\t\t\t\tonImprove={onImproveToolInstructions}\n\t\t\t\t\t\tonClose={() => setToolDrawer(null)}\n\t\t\t\t\t\tonSave={handleSaveConfigTool}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\n\t\t\t<RequireVerificationModal\n\t\t\t\topen={pendingAuthTool !== null}\n\t\t\t\ttoolLabel={\n\t\t\t\t\tavailableTools.find((t) => t.tool_id === pendingAuthTool)\n\t\t\t\t\t\t?.display_name ?? 'This tool'\n\t\t\t\t}\n\t\t\t\tonCancel={() => setPendingAuthTool(null)}\n\t\t\t\tonConfirm={() => {\n\t\t\t\t\tpatch({ authentication: { enabled: true, type: authType } });\n\t\t\t\t\tif (pendingAuthTool) {\n\t\t\t\t\t\taddTool(pendingAuthTool);\n\t\t\t\t\t}\n\t\t\t\t\tsetPendingAuthTool(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t</Step3Root>\n\t);\n};\n"],"names":["toolIconEl","source","renderSourceIcon","sourceIcon","toolOption","t","ToolSource","STEP","STEP_DEFINITIONS","AUTH_METHOD_OPTIONS","upsertById","list","item","arr","x","Step3HowItResponds","value","patch","updateField","addReference","removeReference","availableTools","availableSubAgents","availableModels","configToolTemplates","applicationType","charLimits","insertMention","onCreateSubAgent","onFetchSubAgent","onUpdateSubAgent","onImproveSubAgent","onImproveToolInstructions","registerSubAgentCreator","registerToolActionHandler","integrationStatus","onConnectIntegration","variablesData","useAgentBuilderContext","panel","setPanel","useState","panelKeyRef","useRef","toolDrawer","setToolDrawer","toolDrawerKeyRef","openRestApi","useCallback","initial","openConfigTool","toolKey","handleSaveRestApi","config","isNew","restApiMentionItem","handleSaveConfigTool","configToolMentionItem","openToolAction","CONFIG_TOOL_SOURCES","useEffect","createdSubAgents","setCreatedSubAgents","subAgentById","s","knownSubAgents","openCreate","openConfigure","id","data","handlePanelSave","draft","ref","prev","hasAuthRequiredTool","authEnabled","authType","pendingAuthTool","setPendingAuthTool","addTool","handleAddTool","toolItems","tool","restApiItems","restApiToolName","SOURCE_ICONS","configToolItems","configToolName","allToolItems","toolActionSources","buildToolActions","toolOptions","toolSourceGroups","order","bySource","src","toolSourceLabel","subAgentItems","sub","subAgentOptions","appLabel","appTypeLabel","toolMentionItems","buildAgentMentionItems","buildCustomToolMentionItems","subAgentMentionItems","modelOptions","m","selectedModel","openConfigTemplate","Step3Root","jsx","StepSectionHeader","jsxs","Step3Grid","SectionBodyWrap","MentionField","Step3Divider","SelectableListSection","SideSection","SideSectionHeader","Shield","TitleSmall","COLORS","Switch","enabled","BodyCaption","Fragment","BodySecondary","Dropdown","o","opt","v","unwrapDropdownValue","CreateSubAgentPanel","RestApiToolPanel","ConfigToolPanel","RequireVerificationModal"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),l=require("react"),c=require("../editorDropdown.styles.js"),j=l.forwardRef(({items:r,query:p,command:d,renderItem:f,renderDropdown:s,dismiss:y},b)=>{const[a,u]=l.useState(0),x=l.useRef(null),i=l.useRef(null),w=l.useCallback(e=>{i.current=e},[]),h=l.useCallback(e=>{const n=x.current;if(!n)return;n.children[e]?.scrollIntoView({block:"nearest"})},[]),g=e=>{r[e]&&d(r[e])};return l.useImperativeHandle(b,()=>({onKeyDown:({event:e})=>s&&i.current?i.current(e):r.length?e.key==="ArrowUp"?(u(n=>{const o=(n+r.length-1)%r.length;return h(o),o}),!0):e.key==="ArrowDown"?(u(n=>{const o=(n+1)%r.length;return h(o),o}),!0):e.key==="Enter"?(g(a),!0):!1:!1})),l.useEffect(()=>u(0),[r]),!r.length&&!s?null:s?t.jsx(t.Fragment,{children:s({items:r,query:p,activeIndex:a,onSelect:e=>d(e),registerKeyHandler:w,onClose:y})}):t.jsx(c.DropdownContainer,{ref:x,children:r.map((e,n)=>t.jsx(c.DropdownItem,{$isActive:n===a,onMouseEnter:()=>u(n),onClick:()=>g(n),children:f?f(e,n===a):t.jsxs(t.Fragment,{children:[e.avatarUrl?t.jsx(c.MentionAvatar,{src:e.avatarUrl,alt:""}):t.jsx(c.MentionAvatarFallback,{children:e.label.charAt(0).toUpperCase()}),t.jsx(c.MentionLabel,{children:e.label}),e.isOnline!==void 0&&t.jsx(c.MentionPresenceDot,{$online:e.isOnline})]})},e.id))})});j.displayName="MentionDropdown";exports.MentionDropdown=j;
|
|
2
2
|
//# sourceMappingURL=MentionDropdown.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MentionDropdown.js","sources":["../../../../../src/editor/extensions/mention/MentionDropdown.tsx"],"sourcesContent":["import React, {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tDropdownContainer,\n\tDropdownItem,\n\tMentionAvatar,\n\tMentionAvatarFallback,\n\tMentionLabel,\n\tMentionPresenceDot,\n} from '../editorDropdown.styles';\n\ninterface Props {\n\titems: MentionItem[];\n\tquery: string;\n\tcommand: (item: MentionItem) => void;\n\t/** Custom per-row renderer. Receives the item and whether it is the active row. */\n\trenderItem?: (item: MentionItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Full custom dropdown renderer. Takes priority over renderItem.\n\t * The editor passes activeIndex and onSelect — you handle all the visual rendering.\n\t */\n\trenderDropdown?: (props: MentionDropdownRenderProps) => React.ReactNode;\n\t/** Close the menu without selecting (strips the typed trigger). Injected by the extension. */\n\tdismiss?: () => void;\n}\n\nexport const MentionDropdown = forwardRef<any, Props>(\n\t({ items, query, command, renderItem, renderDropdown, dismiss }, ref) => {\n\t\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\n\t\t// A custom dropdown (renderDropdown) can claim keyboard nav for itself.\n\t\tconst customKeyHandlerRef = useRef<\n\t\t\t((event: KeyboardEvent) => boolean) | null\n\t\t>(null);\n\n\t\tconst registerKeyHandler = useCallback(\n\t\t\t(handler: ((event: KeyboardEvent) => boolean) | null) => {\n\t\t\t\tcustomKeyHandlerRef.current = handler;\n\t\t\t},\n\t\t\t[],\n\t\t);\n\n\t\tconst scrollToIndex = useCallback((index: number) => {\n\t\t\tconst container = containerRef.current;\n\t\t\tif (!container) return;\n\t\t\tconst item = container.children[index] as HTMLElement | undefined;\n\t\t\titem?.scrollIntoView({ block: 'nearest' });\n\t\t}, []);\n\n\t\tconst select = (i: number) => {\n\t\t\tif (items[i]) command(items[i]);\n\t\t};\n\n\t\tuseImperativeHandle(ref, () => ({\n\t\t\tonKeyDown: ({ event }: { event: KeyboardEvent }) => {\n\t\t\t\t// A custom dropdown that registered a handler owns navigation.\n\t\t\t\tif (renderDropdown && customKeyHandlerRef.current) {\n\t\t\t\t\treturn customKeyHandlerRef.current(event);\n\t\t\t\t}\n\t\t\t\tif (!items.length) return false;\n\t\t\t\tif (event.key === 'ArrowUp') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + items.length - 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'ArrowDown') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tselect(selectedIndex);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t}));\n\n\t\tuseEffect(() => setSelectedIndex(0), [items]);\n\n\t\tif (!items.length) return null;\n\n\t\t// Full custom dropdown — editor still manages keyboard nav via selectedIndex\n\t\tif (renderDropdown) {\n\t\t\treturn (\n\t\t\t\t<>\n\t\t\t\t\t{renderDropdown({\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tquery,\n\t\t\t\t\t\tactiveIndex: selectedIndex,\n\t\t\t\t\t\tonSelect: (item) => command(item),\n\t\t\t\t\t\tregisterKeyHandler,\n\t\t\t\t\t\tonClose: dismiss,\n\t\t\t\t\t})}\n\t\t\t\t</>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<DropdownContainer ref={containerRef}>\n\t\t\t\t{items.map((item, i) => (\n\t\t\t\t\t<DropdownItem\n\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t$isActive={i === selectedIndex}\n\t\t\t\t\t\tonMouseEnter={() => setSelectedIndex(i)}\n\t\t\t\t\t\tonClick={() => select(i)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{renderItem ? (\n\t\t\t\t\t\t\trenderItem(item, i === selectedIndex)\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t{item.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<MentionAvatar src={item.avatarUrl} alt=\"\" />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<MentionAvatarFallback>\n\t\t\t\t\t\t\t\t\t\t{item.label.charAt(0).toUpperCase()}\n\t\t\t\t\t\t\t\t\t</MentionAvatarFallback>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<MentionLabel>{item.label}</MentionLabel>\n\t\t\t\t\t\t\t\t{item.isOnline !== undefined && (\n\t\t\t\t\t\t\t\t\t<MentionPresenceDot $online={item.isOnline} />\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</DropdownItem>\n\t\t\t\t))}\n\t\t\t</DropdownContainer>\n\t\t);\n\t},\n);\nMentionDropdown.displayName = 'MentionDropdown';\n"],"names":["MentionDropdown","forwardRef","items","query","command","renderItem","renderDropdown","dismiss","ref","selectedIndex","setSelectedIndex","useState","containerRef","useRef","customKeyHandlerRef","registerKeyHandler","useCallback","handler","scrollToIndex","index","container","select","i","useImperativeHandle","event","prev","next","useEffect","item","jsx","DropdownContainer","DropdownItem","jsxs","Fragment","MentionAvatar","MentionAvatarFallback","MentionLabel","MentionPresenceDot"],"mappings":"iLAoCaA,EAAkBC,EAAAA,WAC9B,CAAC,CAAE,MAAAC,EAAO,MAAAC,EAAO,QAAAC,EAAS,WAAAC,EAAY,eAAAC,EAAgB,QAAAC,CAAA,EAAWC,IAAQ,CACxE,KAAM,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SAAS,CAAC,EAC9CC,EAAeC,EAAAA,OAAuB,IAAI,EAE1CC,EAAsBD,EAAAA,OAE1B,IAAI,EAEAE,EAAqBC,EAAAA,YACzBC,GAAwD,CACxDH,EAAoB,QAAUG,CAC/B,EACA,CAAA,CAAC,EAGIC,EAAgBF,cAAaG,GAAkB,CACpD,MAAMC,EAAYR,EAAa,QAC/B,GAAI,CAACQ,EAAW,OACHA,EAAU,SAASD,CAAK,GAC/B,eAAe,CAAE,MAAO,SAAA,CAAW,CAC1C,EAAG,CAAA,CAAE,EAECE,EAAUC,GAAc,CACzBpB,EAAMoB,CAAC,GAAGlB,EAAQF,EAAMoB,CAAC,CAAC,CAC/B,
|
|
1
|
+
{"version":3,"file":"MentionDropdown.js","sources":["../../../../../src/editor/extensions/mention/MentionDropdown.tsx"],"sourcesContent":["import React, {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tDropdownContainer,\n\tDropdownItem,\n\tMentionAvatar,\n\tMentionAvatarFallback,\n\tMentionLabel,\n\tMentionPresenceDot,\n} from '../editorDropdown.styles';\n\ninterface Props {\n\titems: MentionItem[];\n\tquery: string;\n\tcommand: (item: MentionItem) => void;\n\t/** Custom per-row renderer. Receives the item and whether it is the active row. */\n\trenderItem?: (item: MentionItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Full custom dropdown renderer. Takes priority over renderItem.\n\t * The editor passes activeIndex and onSelect — you handle all the visual rendering.\n\t */\n\trenderDropdown?: (props: MentionDropdownRenderProps) => React.ReactNode;\n\t/** Close the menu without selecting (strips the typed trigger). Injected by the extension. */\n\tdismiss?: () => void;\n}\n\nexport const MentionDropdown = forwardRef<any, Props>(\n\t({ items, query, command, renderItem, renderDropdown, dismiss }, ref) => {\n\t\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\n\t\t// A custom dropdown (renderDropdown) can claim keyboard nav for itself.\n\t\tconst customKeyHandlerRef = useRef<\n\t\t\t((event: KeyboardEvent) => boolean) | null\n\t\t>(null);\n\n\t\tconst registerKeyHandler = useCallback(\n\t\t\t(handler: ((event: KeyboardEvent) => boolean) | null) => {\n\t\t\t\tcustomKeyHandlerRef.current = handler;\n\t\t\t},\n\t\t\t[],\n\t\t);\n\n\t\tconst scrollToIndex = useCallback((index: number) => {\n\t\t\tconst container = containerRef.current;\n\t\t\tif (!container) return;\n\t\t\tconst item = container.children[index] as HTMLElement | undefined;\n\t\t\titem?.scrollIntoView({ block: 'nearest' });\n\t\t}, []);\n\n\t\tconst select = (i: number) => {\n\t\t\tif (items[i]) command(items[i]);\n\t\t};\n\n\t\tuseImperativeHandle(ref, () => ({\n\t\t\tonKeyDown: ({ event }: { event: KeyboardEvent }) => {\n\t\t\t\t// A custom dropdown that registered a handler owns navigation.\n\t\t\t\tif (renderDropdown && customKeyHandlerRef.current) {\n\t\t\t\t\treturn customKeyHandlerRef.current(event);\n\t\t\t\t}\n\t\t\t\tif (!items.length) return false;\n\t\t\t\tif (event.key === 'ArrowUp') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + items.length - 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'ArrowDown') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tselect(selectedIndex);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t}));\n\n\t\tuseEffect(() => setSelectedIndex(0), [items]);\n\n\t\t// A custom dropdown owns its own empty state — it can have content even\n\t\t// with zero mention items (e.g. the agent-builder's variables-only mode).\n\t\t// Only the default row list bails on empty.\n\t\tif (!items.length && !renderDropdown) return null;\n\n\t\t// Full custom dropdown — editor still manages keyboard nav via selectedIndex\n\t\tif (renderDropdown) {\n\t\t\treturn (\n\t\t\t\t<>\n\t\t\t\t\t{renderDropdown({\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tquery,\n\t\t\t\t\t\tactiveIndex: selectedIndex,\n\t\t\t\t\t\tonSelect: (item) => command(item),\n\t\t\t\t\t\tregisterKeyHandler,\n\t\t\t\t\t\tonClose: dismiss,\n\t\t\t\t\t})}\n\t\t\t\t</>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<DropdownContainer ref={containerRef}>\n\t\t\t\t{items.map((item, i) => (\n\t\t\t\t\t<DropdownItem\n\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t$isActive={i === selectedIndex}\n\t\t\t\t\t\tonMouseEnter={() => setSelectedIndex(i)}\n\t\t\t\t\t\tonClick={() => select(i)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{renderItem ? (\n\t\t\t\t\t\t\trenderItem(item, i === selectedIndex)\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t{item.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<MentionAvatar src={item.avatarUrl} alt=\"\" />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<MentionAvatarFallback>\n\t\t\t\t\t\t\t\t\t\t{item.label.charAt(0).toUpperCase()}\n\t\t\t\t\t\t\t\t\t</MentionAvatarFallback>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<MentionLabel>{item.label}</MentionLabel>\n\t\t\t\t\t\t\t\t{item.isOnline !== undefined && (\n\t\t\t\t\t\t\t\t\t<MentionPresenceDot $online={item.isOnline} />\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</DropdownItem>\n\t\t\t\t))}\n\t\t\t</DropdownContainer>\n\t\t);\n\t},\n);\nMentionDropdown.displayName = 'MentionDropdown';\n"],"names":["MentionDropdown","forwardRef","items","query","command","renderItem","renderDropdown","dismiss","ref","selectedIndex","setSelectedIndex","useState","containerRef","useRef","customKeyHandlerRef","registerKeyHandler","useCallback","handler","scrollToIndex","index","container","select","i","useImperativeHandle","event","prev","next","useEffect","item","jsx","DropdownContainer","DropdownItem","jsxs","Fragment","MentionAvatar","MentionAvatarFallback","MentionLabel","MentionPresenceDot"],"mappings":"iLAoCaA,EAAkBC,EAAAA,WAC9B,CAAC,CAAE,MAAAC,EAAO,MAAAC,EAAO,QAAAC,EAAS,WAAAC,EAAY,eAAAC,EAAgB,QAAAC,CAAA,EAAWC,IAAQ,CACxE,KAAM,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SAAS,CAAC,EAC9CC,EAAeC,EAAAA,OAAuB,IAAI,EAE1CC,EAAsBD,EAAAA,OAE1B,IAAI,EAEAE,EAAqBC,EAAAA,YACzBC,GAAwD,CACxDH,EAAoB,QAAUG,CAC/B,EACA,CAAA,CAAC,EAGIC,EAAgBF,cAAaG,GAAkB,CACpD,MAAMC,EAAYR,EAAa,QAC/B,GAAI,CAACQ,EAAW,OACHA,EAAU,SAASD,CAAK,GAC/B,eAAe,CAAE,MAAO,SAAA,CAAW,CAC1C,EAAG,CAAA,CAAE,EAECE,EAAUC,GAAc,CACzBpB,EAAMoB,CAAC,GAAGlB,EAAQF,EAAMoB,CAAC,CAAC,CAC/B,EAsCA,OApCAC,EAAAA,oBAAoBf,EAAK,KAAO,CAC/B,UAAW,CAAC,CAAE,MAAAgB,KAETlB,GAAkBQ,EAAoB,QAClCA,EAAoB,QAAQU,CAAK,EAEpCtB,EAAM,OACPsB,EAAM,MAAQ,WACjBd,EAAkBe,GAAS,CAC1B,MAAMC,GAAQD,EAAOvB,EAAM,OAAS,GAAKA,EAAM,OAC/C,OAAAgB,EAAcQ,CAAI,EACXA,CACR,CAAC,EACM,IAEJF,EAAM,MAAQ,aACjBd,EAAkBe,GAAS,CAC1B,MAAMC,GAAQD,EAAO,GAAKvB,EAAM,OAChC,OAAAgB,EAAcQ,CAAI,EACXA,CACR,CAAC,EACM,IAEJF,EAAM,MAAQ,SACjBH,EAAOZ,CAAa,EACb,IAED,GArBmB,EAsB3B,EACC,EAEFkB,EAAAA,UAAU,IAAMjB,EAAiB,CAAC,EAAG,CAACR,CAAK,CAAC,EAKxC,CAACA,EAAM,QAAU,CAACI,EAAuB,KAGzCA,oBAGA,SAAAA,EAAe,CACf,MAAAJ,EACA,MAAAC,EACA,YAAaM,EACb,SAAWmB,GAASxB,EAAQwB,CAAI,EAChC,mBAAAb,EACA,QAASR,CAAA,CACT,EACF,EAKDsB,MAACC,EAAAA,mBAAkB,IAAKlB,EACtB,WAAM,IAAI,CAACgB,EAAMN,IACjBO,EAAAA,IAACE,EAAAA,aAAA,CAEA,UAAWT,IAAMb,EACjB,aAAc,IAAMC,EAAiBY,CAAC,EACtC,QAAS,IAAMD,EAAOC,CAAC,EAEtB,WACAjB,EAAWuB,EAAMN,IAAMb,CAAa,EAEpCuB,EAAAA,KAAAC,WAAA,CACE,SAAA,CAAAL,EAAK,UACLC,EAAAA,IAACK,gBAAA,CAAc,IAAKN,EAAK,UAAW,IAAI,EAAA,CAAG,EAE3CC,EAAAA,IAACM,EAAAA,uBACC,SAAAP,EAAK,MAAM,OAAO,CAAC,EAAE,cACvB,EAEDC,EAAAA,IAACO,EAAAA,aAAA,CAAc,SAAAR,EAAK,KAAA,CAAM,EACzBA,EAAK,WAAa,cACjBS,EAAAA,mBAAA,CAAmB,QAAST,EAAK,QAAA,CAAU,CAAA,CAAA,CAE9C,CAAA,EApBIA,EAAK,EAAA,CAuBX,EACF,CAEF,CACD,EACA5B,EAAgB,YAAc"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("../../../node_modules/@tiptap/core/dist/index.js"),b=require("@tiptap/extension-mention"),k=require("@tiptap/react"),M=require("../suggestionPopup.js"),w=require("./MentionDropdown.js"),p=i=>i&&typeof i=="object"&&"default"in i?i:{default:i},D=p(b);function T(i,o){const{renderItem:d,renderDropdown:u,removeTriggerOnDismiss:s}=i;return()=>{let a,r,e,t=null;const l=()=>{if(o.picked=!0,e?.editor&&e?.range){const{editor:n,range:c}=e;n.chain().focus().deleteRange(c).run()}};return{onStart:n=>{e=n,o.picked=!1,a=new k.ReactRenderer(w.MentionDropdown,{props:{...n,renderItem:d,renderDropdown:u,dismiss:l},editor:n.editor}),r=M.createSuggestionPopup(a.element,n.clientRect),t=c=>{const g=c.target;!g||r.element.contains(g)||e?.editor?.view?.dom?.contains(g)||(o.picked=!0,e?.editor&&e?.range&&e.editor.chain().deleteRange(e.range).run(),r.hide())},document.addEventListener("mousedown",t)},onUpdate:n=>{if(e=n,a.updateProps({...n,renderItem:d,renderDropdown:u,dismiss:l}),!n.items?.length){r.hide();return}r.show(),r.updatePosition(n.clientRect)},onKeyDown:n=>n.event.key==="Escape"?(r.hide(),!0):a.ref?.onKeyDown(n)??!1,onExit:()=>{if(t&&(document.removeEventListener("mousedown",t),t=null),r.destroy(),a.destroy(),s&&!o.picked&&e?.editor&&e?.range){const{editor:n,range:c}=e;setTimeout(()=>{n.isDestroyed||n.chain().deleteRange(c).run()},0)}}}}}function m(i,o,d,u,s,a){const r={picked:!1};return D.default.extend({name:i,addAttributes(){return{...this.parent?.(),kind:{default:null,parseHTML:e=>e.getAttribute("data-kind"),renderHTML:e=>e.kind?{"data-kind":String(e.kind)}:{}}}}}).configure({HTMLAttributes:{class:o},renderText:({options:e,node:t})=>`${t.attrs.kind?"":e.suggestion.char}${t.attrs.label}`,renderHTML:({options:e,node:t})=>["span",f.mergeAttributes(e.HTMLAttributes,t.attrs.kind?{"data-kind":String(t.attrs.kind)}:{}),`${t.attrs.kind?"":e.suggestion.char}${t.attrs.label}`],suggestion:{char:d,allowSpaces:!0,items:({query:e})=>u.current.filter(t=>t.label.toLowerCase().includes(e.toLowerCase())),command:({editor:e,range:t,props:l})=>{r.picked=!0,e.chain().focus().deleteRange(t).insertContent({type:i,attrs:{id:l.id,label:l.label,kind:l.meta?.kind??null}}).run(),s?.(l,d)},render:T(a,r)}})}function h(i,o,d,u,s){return m("mentionAgent","bik-mention bik-mention--agent","@",i,o,{renderItem:d,renderDropdown:u,removeTriggerOnDismiss:s})}function y(i,o,d,u,s){return m("mentionTeam","bik-mention bik-mention--team","#",i,o,{renderItem:d,renderDropdown:u,removeTriggerOnDismiss:s})}exports.buildAgentMentionExtension=h;exports.buildTeamMentionExtension=y;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("../../../node_modules/@tiptap/core/dist/index.js"),b=require("@tiptap/extension-mention"),k=require("@tiptap/react"),M=require("../suggestionPopup.js"),w=require("./MentionDropdown.js"),p=i=>i&&typeof i=="object"&&"default"in i?i:{default:i},D=p(b);function T(i,o){const{renderItem:d,renderDropdown:u,removeTriggerOnDismiss:s}=i;return()=>{let a,r,e,t=null;const l=()=>{if(o.picked=!0,e?.editor&&e?.range){const{editor:n,range:c}=e;n.chain().focus().deleteRange(c).run()}};return{onStart:n=>{e=n,o.picked=!1,a=new k.ReactRenderer(w.MentionDropdown,{props:{...n,renderItem:d,renderDropdown:u,dismiss:l},editor:n.editor}),r=M.createSuggestionPopup(a.element,n.clientRect),t=c=>{const g=c.target;!g||r.element.contains(g)||e?.editor?.view?.dom?.contains(g)||(o.picked=!0,e?.editor&&e?.range&&e.editor.chain().deleteRange(e.range).run(),r.hide())},document.addEventListener("mousedown",t)},onUpdate:n=>{if(e=n,a.updateProps({...n,renderItem:d,renderDropdown:u,dismiss:l}),!n.items?.length&&!u){r.hide();return}r.show(),r.updatePosition(n.clientRect)},onKeyDown:n=>n.event.key==="Escape"?(r.hide(),!0):a.ref?.onKeyDown(n)??!1,onExit:()=>{if(t&&(document.removeEventListener("mousedown",t),t=null),r.destroy(),a.destroy(),s&&!o.picked&&e?.editor&&e?.range){const{editor:n,range:c}=e;setTimeout(()=>{n.isDestroyed||n.chain().deleteRange(c).run()},0)}}}}}function m(i,o,d,u,s,a){const r={picked:!1};return D.default.extend({name:i,addAttributes(){return{...this.parent?.(),kind:{default:null,parseHTML:e=>e.getAttribute("data-kind"),renderHTML:e=>e.kind?{"data-kind":String(e.kind)}:{}}}}}).configure({HTMLAttributes:{class:o},renderText:({options:e,node:t})=>`${t.attrs.kind?"":e.suggestion.char}${t.attrs.label}`,renderHTML:({options:e,node:t})=>["span",f.mergeAttributes(e.HTMLAttributes,t.attrs.kind?{"data-kind":String(t.attrs.kind)}:{}),`${t.attrs.kind?"":e.suggestion.char}${t.attrs.label}`],suggestion:{char:d,allowSpaces:!0,items:({query:e})=>u.current.filter(t=>t.label.toLowerCase().includes(e.toLowerCase())),command:({editor:e,range:t,props:l})=>{r.picked=!0,e.chain().focus().deleteRange(t).insertContent({type:i,attrs:{id:l.id,label:l.label,kind:l.meta?.kind??null}}).run(),s?.(l,d)},render:T(a,r)}})}function h(i,o,d,u,s){return m("mentionAgent","bik-mention bik-mention--agent","@",i,o,{renderItem:d,renderDropdown:u,removeTriggerOnDismiss:s})}function y(i,o,d,u,s){return m("mentionTeam","bik-mention bik-mention--team","#",i,o,{renderItem:d,renderDropdown:u,removeTriggerOnDismiss:s})}exports.buildAgentMentionExtension=h;exports.buildTeamMentionExtension=y;
|
|
2
2
|
//# sourceMappingURL=MentionExtension.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MentionExtension.js","sources":["../../../../../src/editor/extensions/mention/MentionExtension.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport Mention from '@tiptap/extension-mention';\nimport { ReactRenderer } from '@tiptap/react';\nimport type { ReactNode } from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tcreateSuggestionPopup,\n\ttype SuggestionPopup,\n} from '../suggestionPopup';\nimport { MentionDropdown } from './MentionDropdown';\n\ninterface MentionBuildOptions {\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode;\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode;\n\t/** Remove the typed trigger char + query if the menu closes without a selection. */\n\tremoveTriggerOnDismiss?: boolean;\n}\n\nfunction buildRender(\n\toptions: MentionBuildOptions,\n\tpickedRef: { picked: boolean },\n) {\n\tconst { renderItem, renderDropdown, removeTriggerOnDismiss } = options;\n\treturn () => {\n\t\tlet component: ReactRenderer;\n\t\tlet popup: SuggestionPopup;\n\t\tlet latestProps: any;\n\t\t// Closes the menu when the user clicks anywhere outside it. The `@` popup\n\t\t// lives on document.body (not inside the editor), so nothing dismisses it on\n\t\t// an outside click otherwise — only Escape / moving the cursor did.\n\t\tlet onDocMouseDown: ((event: MouseEvent) => void) | null = null;\n\n\t\t// Close the menu without a selection: drop the typed \"@query\" so no orphan\n\t\t// trigger is left, and mark as picked so onExit doesn't delete it twice.\n\t\tconst dismiss = () => {\n\t\t\tpickedRef.picked = true;\n\t\t\tif (latestProps?.editor && latestProps?.range) {\n\t\t\t\tconst { editor, range } = latestProps;\n\t\t\t\teditor.chain().focus().deleteRange(range).run();\n\t\t\t}\n\t\t};\n\n\t\treturn {\n\t\t\tonStart: (props: any) => {\n\t\t\t\tlatestProps = props;\n\t\t\t\tpickedRef.picked = false;\n\t\t\t\tcomponent = new ReactRenderer(MentionDropdown, {\n\t\t\t\t\tprops: { ...props, renderItem, renderDropdown, dismiss },\n\t\t\t\t\teditor: props.editor,\n\t\t\t\t});\n\t\t\t\tpopup = createSuggestionPopup(component.element, props.clientRect);\n\t\t\t\tonDocMouseDown = (event: MouseEvent) => {\n\t\t\t\t\tconst target = event.target as Node | null;\n\t\t\t\t\tif (!target) return;\n\t\t\t\t\t// Inside the picker → keep open (row clicks fire on `click`).\n\t\t\t\t\tif (popup.element.contains(target)) return;\n\t\t\t\t\t// Inside the editor → the suggestion plugin already closes it.\n\t\t\t\t\tconst editorDom = latestProps?.editor?.view?.dom as\n\t\t\t\t\t\t| HTMLElement\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (editorDom?.contains(target)) return;\n\t\t\t\t\t// Anywhere else → drop the typed \"@query\" (no refocus — clicking\n\t\t\t\t\t// away shouldn't yank focus back) and close.\n\t\t\t\t\tpickedRef.picked = true;\n\t\t\t\t\tif (latestProps?.editor && latestProps?.range) {\n\t\t\t\t\t\tlatestProps.editor.chain().deleteRange(latestProps.range).run();\n\t\t\t\t\t}\n\t\t\t\t\tpopup.hide();\n\t\t\t\t};\n\t\t\t\tdocument.addEventListener('mousedown', onDocMouseDown);\n\t\t\t},\n\t\t\tonUpdate: (props: any) => {\n\t\t\t\tlatestProps = props;\n\t\t\t\tcomponent.updateProps({\n\t\t\t\t\t...props,\n\t\t\t\t\trenderItem,\n\t\t\t\t\trenderDropdown,\n\t\t\t\t\tdismiss,\n\t\t\t\t});\n\t\t\t\tif (!props.items?.length) {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tpopup.show();\n\t\t\t\tpopup.updatePosition(props.clientRect);\n\t\t\t},\n\t\t\tonKeyDown: (props: any) => {\n\t\t\t\tif (props.event.key === 'Escape') {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn (component.ref as any)?.onKeyDown(props) ?? false;\n\t\t\t},\n\t\t\tonExit: () => {\n\t\t\t\tif (onDocMouseDown) {\n\t\t\t\t\tdocument.removeEventListener('mousedown', onDocMouseDown);\n\t\t\t\t\tonDocMouseDown = null;\n\t\t\t\t}\n\t\t\t\tpopup.destroy();\n\t\t\t\tcomponent.destroy();\n\t\t\t\t// Nothing was picked → strip the orphan \"@query\" the user typed.\n\t\t\t\tif (\n\t\t\t\t\tremoveTriggerOnDismiss &&\n\t\t\t\t\t!pickedRef.picked &&\n\t\t\t\t\tlatestProps?.editor &&\n\t\t\t\t\tlatestProps?.range\n\t\t\t\t) {\n\t\t\t\t\tconst { editor, range } = latestProps;\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (!editor.isDestroyed) {\n\t\t\t\t\t\t\teditor.chain().deleteRange(range).run();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 0);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t};\n}\n\n/**\n * Builds a TipTap Mention extension.\n *\n * Each inserted node carries an optional `kind` attribute. When set, the chip is\n * rendered WITHOUT the trigger char (the `label` already encodes the full text)\n * and a `data-kind` attribute is emitted so CSS can colour it per kind. When\n * `kind` is null the legacy `${char}${label}` chip is rendered (back-compatible).\n */\nfunction buildMentionExtension(\n\tname: 'mentionAgent' | 'mentionTeam',\n\tcssClass: string,\n\tchar: '@' | '#',\n\titemsRef: { current: MentionItem[] },\n\tonSelect: ((item: MentionItem, char: '@' | '#') => void) | undefined,\n\toptions: MentionBuildOptions,\n) {\n\tconst pickedRef = { picked: false };\n\n\treturn Mention.extend({\n\t\tname,\n\t\taddAttributes() {\n\t\t\treturn {\n\t\t\t\t...this.parent?.(),\n\t\t\t\tkind: {\n\t\t\t\t\tdefault: null,\n\t\t\t\t\tparseHTML: (el: HTMLElement) => el.getAttribute('data-kind'),\n\t\t\t\t\trenderHTML: (attrs: Record<string, unknown>) =>\n\t\t\t\t\t\tattrs['kind'] ? { 'data-kind': String(attrs['kind']) } : {},\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t}).configure({\n\t\tHTMLAttributes: { class: cssClass },\n\t\trenderText: ({ options: opt, node }: any) =>\n\t\t\t`${node.attrs['kind'] ? '' : opt.suggestion.char}${node.attrs['label']}`,\n\t\trenderHTML: ({ options: opt, node }: any) => [\n\t\t\t'span',\n\t\t\tmergeAttributes(\n\t\t\t\topt.HTMLAttributes,\n\t\t\t\tnode.attrs['kind'] ? { 'data-kind': String(node.attrs['kind']) } : {},\n\t\t\t),\n\t\t\t`${node.attrs['kind'] ? '' : opt.suggestion.char}${node.attrs['label']}`,\n\t\t],\n\t\tsuggestion: {\n\t\t\tchar,\n\t\t\tallowSpaces: true,\n\t\t\titems: ({ query }: { query: string }) =>\n\t\t\t\titemsRef.current.filter((a) =>\n\t\t\t\t\ta.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t),\n\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\tpickedRef.picked = true;\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.deleteRange(range)\n\t\t\t\t\t.insertContent({\n\t\t\t\t\t\ttype: name,\n\t\t\t\t\t\tattrs: {\n\t\t\t\t\t\t\tid: props.id,\n\t\t\t\t\t\t\tlabel: props.label,\n\t\t\t\t\t\t\tkind: props.meta?.kind ?? null,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\t.run();\n\t\t\t\tonSelect?.(props, char);\n\t\t\t},\n\t\t\trender: buildRender(options, pickedRef),\n\t\t},\n\t});\n}\n\nexport function buildAgentMentionExtension(\n\tagentsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n\tremoveTriggerOnDismiss?: boolean,\n) {\n\treturn buildMentionExtension(\n\t\t'mentionAgent',\n\t\t'bik-mention bik-mention--agent',\n\t\t'@',\n\t\tagentsRef,\n\t\tonSelect,\n\t\t{ renderItem, renderDropdown, removeTriggerOnDismiss },\n\t);\n}\n\nexport function buildTeamMentionExtension(\n\tteamsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n\tremoveTriggerOnDismiss?: boolean,\n) {\n\treturn buildMentionExtension(\n\t\t'mentionTeam',\n\t\t'bik-mention bik-mention--team',\n\t\t'#',\n\t\tteamsRef,\n\t\tonSelect,\n\t\t{ renderItem, renderDropdown, removeTriggerOnDismiss },\n\t);\n}\n"],"names":["buildRender","options","pickedRef","renderItem","renderDropdown","removeTriggerOnDismiss","component","popup","latestProps","onDocMouseDown","dismiss","editor","range","props","ReactRenderer","MentionDropdown","createSuggestionPopup","event","target","buildMentionExtension","name","cssClass","char","itemsRef","onSelect","Mention","el","attrs","opt","node","mergeAttributes","query","a","buildAgentMentionExtension","agentsRef","buildTeamMentionExtension","teamsRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MentionExtension.js","sources":["../../../../../src/editor/extensions/mention/MentionExtension.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport Mention from '@tiptap/extension-mention';\nimport { ReactRenderer } from '@tiptap/react';\nimport type { ReactNode } from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tcreateSuggestionPopup,\n\ttype SuggestionPopup,\n} from '../suggestionPopup';\nimport { MentionDropdown } from './MentionDropdown';\n\ninterface MentionBuildOptions {\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode;\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode;\n\t/** Remove the typed trigger char + query if the menu closes without a selection. */\n\tremoveTriggerOnDismiss?: boolean;\n}\n\nfunction buildRender(\n\toptions: MentionBuildOptions,\n\tpickedRef: { picked: boolean },\n) {\n\tconst { renderItem, renderDropdown, removeTriggerOnDismiss } = options;\n\treturn () => {\n\t\tlet component: ReactRenderer;\n\t\tlet popup: SuggestionPopup;\n\t\tlet latestProps: any;\n\t\t// Closes the menu when the user clicks anywhere outside it. The `@` popup\n\t\t// lives on document.body (not inside the editor), so nothing dismisses it on\n\t\t// an outside click otherwise — only Escape / moving the cursor did.\n\t\tlet onDocMouseDown: ((event: MouseEvent) => void) | null = null;\n\n\t\t// Close the menu without a selection: drop the typed \"@query\" so no orphan\n\t\t// trigger is left, and mark as picked so onExit doesn't delete it twice.\n\t\tconst dismiss = () => {\n\t\t\tpickedRef.picked = true;\n\t\t\tif (latestProps?.editor && latestProps?.range) {\n\t\t\t\tconst { editor, range } = latestProps;\n\t\t\t\teditor.chain().focus().deleteRange(range).run();\n\t\t\t}\n\t\t};\n\n\t\treturn {\n\t\t\tonStart: (props: any) => {\n\t\t\t\tlatestProps = props;\n\t\t\t\tpickedRef.picked = false;\n\t\t\t\tcomponent = new ReactRenderer(MentionDropdown, {\n\t\t\t\t\tprops: { ...props, renderItem, renderDropdown, dismiss },\n\t\t\t\t\teditor: props.editor,\n\t\t\t\t});\n\t\t\t\tpopup = createSuggestionPopup(component.element, props.clientRect);\n\t\t\t\tonDocMouseDown = (event: MouseEvent) => {\n\t\t\t\t\tconst target = event.target as Node | null;\n\t\t\t\t\tif (!target) return;\n\t\t\t\t\t// Inside the picker → keep open (row clicks fire on `click`).\n\t\t\t\t\tif (popup.element.contains(target)) return;\n\t\t\t\t\t// Inside the editor → the suggestion plugin already closes it.\n\t\t\t\t\tconst editorDom = latestProps?.editor?.view?.dom as\n\t\t\t\t\t\t| HTMLElement\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (editorDom?.contains(target)) return;\n\t\t\t\t\t// Anywhere else → drop the typed \"@query\" (no refocus — clicking\n\t\t\t\t\t// away shouldn't yank focus back) and close.\n\t\t\t\t\tpickedRef.picked = true;\n\t\t\t\t\tif (latestProps?.editor && latestProps?.range) {\n\t\t\t\t\t\tlatestProps.editor.chain().deleteRange(latestProps.range).run();\n\t\t\t\t\t}\n\t\t\t\t\tpopup.hide();\n\t\t\t\t};\n\t\t\t\tdocument.addEventListener('mousedown', onDocMouseDown);\n\t\t\t},\n\t\t\tonUpdate: (props: any) => {\n\t\t\t\tlatestProps = props;\n\t\t\t\tcomponent.updateProps({\n\t\t\t\t\t...props,\n\t\t\t\t\trenderItem,\n\t\t\t\t\trenderDropdown,\n\t\t\t\t\tdismiss,\n\t\t\t\t});\n\t\t\t\t// Empty result list closes the DEFAULT dropdown; a custom dropdown\n\t\t\t\t// (renderDropdown) may have content of its own with zero items —\n\t\t\t\t// e.g. the agent-builder's variables-only mode — so it stays open.\n\t\t\t\tif (!props.items?.length && !renderDropdown) {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tpopup.show();\n\t\t\t\tpopup.updatePosition(props.clientRect);\n\t\t\t},\n\t\t\tonKeyDown: (props: any) => {\n\t\t\t\tif (props.event.key === 'Escape') {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn (component.ref as any)?.onKeyDown(props) ?? false;\n\t\t\t},\n\t\t\tonExit: () => {\n\t\t\t\tif (onDocMouseDown) {\n\t\t\t\t\tdocument.removeEventListener('mousedown', onDocMouseDown);\n\t\t\t\t\tonDocMouseDown = null;\n\t\t\t\t}\n\t\t\t\tpopup.destroy();\n\t\t\t\tcomponent.destroy();\n\t\t\t\t// Nothing was picked → strip the orphan \"@query\" the user typed.\n\t\t\t\tif (\n\t\t\t\t\tremoveTriggerOnDismiss &&\n\t\t\t\t\t!pickedRef.picked &&\n\t\t\t\t\tlatestProps?.editor &&\n\t\t\t\t\tlatestProps?.range\n\t\t\t\t) {\n\t\t\t\t\tconst { editor, range } = latestProps;\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (!editor.isDestroyed) {\n\t\t\t\t\t\t\teditor.chain().deleteRange(range).run();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 0);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t};\n}\n\n/**\n * Builds a TipTap Mention extension.\n *\n * Each inserted node carries an optional `kind` attribute. When set, the chip is\n * rendered WITHOUT the trigger char (the `label` already encodes the full text)\n * and a `data-kind` attribute is emitted so CSS can colour it per kind. When\n * `kind` is null the legacy `${char}${label}` chip is rendered (back-compatible).\n */\nfunction buildMentionExtension(\n\tname: 'mentionAgent' | 'mentionTeam',\n\tcssClass: string,\n\tchar: '@' | '#',\n\titemsRef: { current: MentionItem[] },\n\tonSelect: ((item: MentionItem, char: '@' | '#') => void) | undefined,\n\toptions: MentionBuildOptions,\n) {\n\tconst pickedRef = { picked: false };\n\n\treturn Mention.extend({\n\t\tname,\n\t\taddAttributes() {\n\t\t\treturn {\n\t\t\t\t...this.parent?.(),\n\t\t\t\tkind: {\n\t\t\t\t\tdefault: null,\n\t\t\t\t\tparseHTML: (el: HTMLElement) => el.getAttribute('data-kind'),\n\t\t\t\t\trenderHTML: (attrs: Record<string, unknown>) =>\n\t\t\t\t\t\tattrs['kind'] ? { 'data-kind': String(attrs['kind']) } : {},\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t}).configure({\n\t\tHTMLAttributes: { class: cssClass },\n\t\trenderText: ({ options: opt, node }: any) =>\n\t\t\t`${node.attrs['kind'] ? '' : opt.suggestion.char}${node.attrs['label']}`,\n\t\trenderHTML: ({ options: opt, node }: any) => [\n\t\t\t'span',\n\t\t\tmergeAttributes(\n\t\t\t\topt.HTMLAttributes,\n\t\t\t\tnode.attrs['kind'] ? { 'data-kind': String(node.attrs['kind']) } : {},\n\t\t\t),\n\t\t\t`${node.attrs['kind'] ? '' : opt.suggestion.char}${node.attrs['label']}`,\n\t\t],\n\t\tsuggestion: {\n\t\t\tchar,\n\t\t\tallowSpaces: true,\n\t\t\titems: ({ query }: { query: string }) =>\n\t\t\t\titemsRef.current.filter((a) =>\n\t\t\t\t\ta.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t),\n\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\tpickedRef.picked = true;\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.deleteRange(range)\n\t\t\t\t\t.insertContent({\n\t\t\t\t\t\ttype: name,\n\t\t\t\t\t\tattrs: {\n\t\t\t\t\t\t\tid: props.id,\n\t\t\t\t\t\t\tlabel: props.label,\n\t\t\t\t\t\t\tkind: props.meta?.kind ?? null,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\t.run();\n\t\t\t\tonSelect?.(props, char);\n\t\t\t},\n\t\t\trender: buildRender(options, pickedRef),\n\t\t},\n\t});\n}\n\nexport function buildAgentMentionExtension(\n\tagentsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n\tremoveTriggerOnDismiss?: boolean,\n) {\n\treturn buildMentionExtension(\n\t\t'mentionAgent',\n\t\t'bik-mention bik-mention--agent',\n\t\t'@',\n\t\tagentsRef,\n\t\tonSelect,\n\t\t{ renderItem, renderDropdown, removeTriggerOnDismiss },\n\t);\n}\n\nexport function buildTeamMentionExtension(\n\tteamsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n\tremoveTriggerOnDismiss?: boolean,\n) {\n\treturn buildMentionExtension(\n\t\t'mentionTeam',\n\t\t'bik-mention bik-mention--team',\n\t\t'#',\n\t\tteamsRef,\n\t\tonSelect,\n\t\t{ renderItem, renderDropdown, removeTriggerOnDismiss },\n\t);\n}\n"],"names":["buildRender","options","pickedRef","renderItem","renderDropdown","removeTriggerOnDismiss","component","popup","latestProps","onDocMouseDown","dismiss","editor","range","props","ReactRenderer","MentionDropdown","createSuggestionPopup","event","target","buildMentionExtension","name","cssClass","char","itemsRef","onSelect","Mention","el","attrs","opt","node","mergeAttributes","query","a","buildAgentMentionExtension","agentsRef","buildTeamMentionExtension","teamsRef"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
import { VariableListInterfaceV3 } from '../../variable-picker-v3/model';
|
|
2
3
|
import { ConfigToolConfig, ConfigToolKey, ParamsBlob } from '../AgentBuilder.model';
|
|
3
4
|
import { AgentCharLimits } from '../constants/charLimits';
|
|
4
5
|
interface ConfigToolPanelProps {
|
|
@@ -18,6 +19,13 @@ interface ConfigToolPanelProps {
|
|
|
18
19
|
/** Optional "Improve with AI" for multiline fields. Omit to hide it. */
|
|
19
20
|
onImprove?: (text: string) => Promise<string>;
|
|
20
21
|
charLimits?: AgentCharLimits;
|
|
22
|
+
/**
|
|
23
|
+
* Variable catalog for the `@` trigger. When non-empty, `@` in the email
|
|
24
|
+
* tool's Subject / Send To / Reply To / CC opens the variable picker
|
|
25
|
+
* directly, and Message Instructions upgrades to the variables-only mention
|
|
26
|
+
* editor. Absent → the drawer behaves exactly as before.
|
|
27
|
+
*/
|
|
28
|
+
variablesData?: VariableListInterfaceV3[];
|
|
21
29
|
/** SideModal stacking order — raise it when opened over another drawer. */
|
|
22
30
|
zIndex?: number;
|
|
23
31
|
}
|