@magicx-eng/ai-autocomplete-react 0.1.14 → 0.1.16

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/AIAutocomplete.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/AIAutocomplete.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/AIAutocompleteDropdown.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionGrid.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionItem.module.css.js","../src/components/SuggestionItem.tsx","../src/components/SuggestionGrid.tsx","../src/AIAutocompleteDropdown.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/PillList.module.css.js","../src/components/PillList.tsx","../src/hooks/useAIAutocomplete.ts","../src/utils/filtering.ts","../src/utils/segments.ts","../src/hooks/useAutocompleteFetch.ts","../src/utils/api.ts","../src/utils/buildQuery.ts","../src/utils/overrides.ts","../src/hooks/useAutocompleteKeyboard.ts","../src/hooks/useAutocompletePills.ts"],"sourcesContent":["export { AIAutocomplete } from \"./AIAutocomplete\";\nexport { AIAutocompleteDropdown } from \"./AIAutocompleteDropdown\";\nexport { useAIAutocomplete } from \"./hooks/useAIAutocomplete\";\nexport type {\n AIAutocompleteDropdownProps,\n AIAutocompleteHandle,\n AIAutocompleteProps,\n APIConfig,\n AutocompleteResult,\n CompletedParam,\n CompletedParamState,\n OptionOverrides,\n Segment,\n Suggestion,\n SuggestionOption,\n TaskKind,\n UseAIAutocompleteOptions,\n UseAIAutocompleteReturn,\n} from \"./types\";\n","import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from \"react\";\nimport styles from \"./AIAutocomplete.module.css\";\nimport { AIAutocompleteDropdown } from \"./AIAutocompleteDropdown\";\nimport { PillList } from \"./components/PillList\";\nimport { useAIAutocomplete } from \"./hooks/useAIAutocomplete\";\nimport type { AIAutocompleteHandle, AIAutocompleteProps, AutocompleteResult } from \"./types\";\nimport { buildQuery } from \"./utils/buildQuery\";\n\nexport const AIAutocomplete = forwardRef<AIAutocompleteHandle, AIAutocompleteProps>(\n function AIAutocomplete(\n {\n onSubmit,\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder,\n className,\n apiConfig,\n columns,\n eagerSuggestions,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n },\n ref,\n ) {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n // Render-phase ref assignment — matches the pattern in useAIAutocomplete.ts\n const handleSubmitRef = useRef<(result: AutocompleteResult) => void>(() => {});\n\n useEffect(() => {\n textareaRef.current?.focus();\n }, []);\n\n const {\n completedParams,\n suggestionPills,\n setActivePill,\n segments,\n inputProps,\n dropdownProps,\n reset,\n } = useAIAutocomplete({\n onSubmit: (result) => handleSubmitRef.current(result),\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder,\n apiConfig,\n columns,\n eagerSuggestions,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n });\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => textareaRef.current?.focus(),\n reset,\n }),\n [reset],\n );\n\n const handleContainerClick = () => {\n textareaRef.current?.focus();\n };\n\n const canSubmit = !!inputProps.value || completedParams.length > 0;\n\n const handleSubmit = useCallback(() => {\n if (!canSubmit) return;\n const { rawQuery, completedParams: finalParams } = buildQuery(\n inputProps.value,\n completedParams,\n );\n onSubmit({\n query: inputProps.value.trim(),\n raw_query: rawQuery,\n completed_params: finalParams,\n });\n reset();\n }, [canSubmit, inputProps.value, completedParams, onSubmit, reset]);\n\n handleSubmitRef.current = handleSubmit;\n\n const { onChange, placeholder: inputPlaceholder, ...restProps } = inputProps;\n const isEmpty = !inputProps.value;\n\n return (\n <div className={`${styles.container} ${className ?? \"\"}`}>\n <AIAutocompleteDropdown {...dropdownProps} />\n {/* biome-ignore lint/a11y/useKeyWithClickEvents: container click delegates to textarea focus */}\n {/* biome-ignore lint/a11y/noStaticElementInteractions: wrapper delegates focus to textarea */}\n <div className={styles.inputWrapper} onClick={handleContainerClick}>\n <div className={styles.editorArea}>\n <div className={styles.sizerContent} aria-hidden=\"true\">\n {isEmpty && inputPlaceholder ? (\n <span className={styles.placeholderText}>{inputPlaceholder} </span>\n ) : (\n <span className={styles.sizerText}>\n {segments.map((seg, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`}>{seg.value}</span>\n ))}\n {segments.length === 0 && \"\\u00A0\"}\n </span>\n )}\n {\" \"}\n <PillList pills={suggestionPills} activePillIndex={0} onSelectPill={setActivePill} />\n </div>\n <textarea\n ref={textareaRef}\n className={styles.textarea}\n rows={1}\n onChange={onChange}\n {...restProps}\n />\n </div>\n <button\n type=\"button\"\n className={styles.submitButton}\n disabled={!canSubmit}\n onClick={(e) => {\n e.stopPropagation();\n handleSubmit();\n }}\n aria-label=\"Submit\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n role=\"img\"\n aria-label=\"Submit\"\n >\n <path\n d=\"M9 14V4M9 4L4 9M9 4L14 9\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n );\n },\n);\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-cc65f4cc\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-cc65f4cc\";\n s.textContent = `.AIAutocomplete-module_container_KKjFU {\n position: relative;\n font-family: \"IBM Plex Sans\", sans-serif;\n}\n\n.AIAutocomplete-module_inputWrapper_FLq1b {\n min-height: 60px;\n padding: 24px;\n border: 1px solid var(--ac-color-border-default, #9ea5b2);\n border-radius: 23px;\n background: transparent;\n overflow: hidden;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.AIAutocomplete-module_editorArea_7rBWq {\n position: relative;\n flex: 1;\n min-width: 0;\n}\n\n.AIAutocomplete-module_sizerContent_DQgmV {\n position: relative;\n z-index: 1;\n pointer-events: none;\n min-height: 60px;\n white-space: pre-wrap;\n word-break: break-word;\n font-family: inherit;\n font-size: 19px;\n line-height: 38px;\n}\n\n.AIAutocomplete-module_sizerText_iZIMK {\n color: transparent;\n}\n\n.AIAutocomplete-module_placeholderText_K3ayy {\n color: var(--ac-color-text-muted, #c1c4cb);\n opacity: 0.7;\n}\n\n.AIAutocomplete-module_textarea_eyn6A {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--ac-color-text-default, #fff);\n caret-color: var(--ac-color-text-default, #fff);\n font-family: inherit;\n font-size: 19px;\n line-height: 38px;\n white-space: pre-wrap;\n word-break: break-word;\n outline: none;\n resize: none;\n overflow: hidden;\n}\n\n.AIAutocomplete-module_textarea_eyn6A::placeholder {\n color: var(--ac-color-text-muted, #c1c4cb);\n}\n\n.AIAutocomplete-module_submitButton_sl1Mi {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: var(--ac-color-text-default, #fff);\n color: var(--ac-color-bg-default, #000);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n transition: opacity 0.2s ease;\n}\n\n.AIAutocomplete-module_submitButton_sl1Mi:hover {\n opacity: 0.85;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"container\":\"AIAutocomplete-module_container_KKjFU\",\"inputWrapper\":\"AIAutocomplete-module_inputWrapper_FLq1b\",\"editorArea\":\"AIAutocomplete-module_editorArea_7rBWq\",\"sizerContent\":\"AIAutocomplete-module_sizerContent_DQgmV\",\"sizerText\":\"AIAutocomplete-module_sizerText_iZIMK\",\"placeholderText\":\"AIAutocomplete-module_placeholderText_K3ayy\",\"textarea\":\"AIAutocomplete-module_textarea_eyn6A\",\"submitButton\":\"AIAutocomplete-module_submitButton_sl1Mi\"};","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-2eef895d\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-2eef895d\";\n s.textContent = `.AIAutocompleteDropdown-module_dropdown_yz2KC {\n position: absolute;\n left: 0;\n right: 0;\n top: 100%;\n margin-top: 6px;\n background: var(--ac-color-background-default, #0b0247);\n border-radius: 23px;\n overflow: hidden;\n z-index: 10;\n opacity: 0;\n pointer-events: none;\n transition: opacity 400ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.AIAutocompleteDropdown-module_visible_QCoXj {\n opacity: 1;\n pointer-events: auto;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"dropdown\":\"AIAutocompleteDropdown-module_dropdown_yz2KC\",\"visible\":\"AIAutocompleteDropdown-module_visible_QCoXj\"};","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-d91f2b06\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-d91f2b06\";\n s.textContent = `.SuggestionGrid-module_grid_jvaPb {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px 18px;\n padding: 18px 24px;\n max-height: 192px;\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: rgba(255, 255, 255, 0.3) transparent;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar {\n width: 6px;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 3px;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"grid\":\"SuggestionGrid-module_grid_jvaPb\"};","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-f6bdc634\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-f6bdc634\";\n s.textContent = `.SuggestionItem-module_item_d4vpD {\n display: flex;\n align-items: center;\n font-family: \"IBM Plex Sans\", sans-serif;\n font-size: 19px;\n line-height: 30px;\n color: var(--ac-color-text-muted, #c1c4cb);\n white-space: normal;\n word-break: break-word;\n opacity: 0.35;\n animation: SuggestionItem-module_fadeIn_I8u35 400ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes SuggestionItem-module_fadeIn_I8u35 {\n from {\n opacity: 0;\n }\n}\n\n.SuggestionItem-module_tappable_70KcX {\n cursor: pointer;\n}\n\n.SuggestionItem-module_tappable_70KcX:hover {\n color: var(--ac-color-text-default, #fff);\n}\n\n.SuggestionItem-module_nonTappable_xSZM- {\n cursor: default;\n opacity: 0.3;\n}\n\n.SuggestionItem-module_highlighted_Hb0SU {\n color: var(--ac-color-text-default, #fff);\n opacity: 0.5;\n}\n\n.SuggestionItem-module_tag_e3Fwe {\n font-size: 11px;\n margin-left: 6px;\n opacity: 0.5;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"item\":\"SuggestionItem-module_item_d4vpD\",\"fadeIn\":\"SuggestionItem-module_fadeIn_I8u35\",\"tappable\":\"SuggestionItem-module_tappable_70KcX\",\"nonTappable\":\"SuggestionItem-module_nonTappable_xSZM-\",\"highlighted\":\"SuggestionItem-module_highlighted_Hb0SU\",\"tag\":\"SuggestionItem-module_tag_e3Fwe\"};","import type { SuggestionOption } from \"../types\";\nimport styles from \"./SuggestionItem.module.css\";\n\ninterface SuggestionItemProps {\n option: SuggestionOption;\n isHighlighted: boolean;\n onSelect: (option: SuggestionOption) => void;\n onHighlight: () => void;\n id: string;\n}\n\nexport function SuggestionItem({\n option,\n isHighlighted,\n onSelect,\n onHighlight,\n id,\n}: SuggestionItemProps) {\n const className = [\n styles.item,\n isHighlighted ? styles.highlighted : \"\",\n option.is_tappable ? styles.tappable : styles.nonTappable,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n id={id}\n role=\"option\"\n aria-selected={isHighlighted}\n className={className}\n tabIndex={option.is_tappable ? 0 : -1}\n onClick={() => option.is_tappable && onSelect(option)}\n onKeyDown={(e) => {\n if (option.is_tappable && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n onSelect(option);\n }\n }}\n onMouseEnter={onHighlight}\n >\n {option.icon ? `${option.icon} ${option.text}` : option.text}\n {option.tag && <span className={styles.tag}>{option.tag}</span>}\n </div>\n );\n}\n","import type { SuggestionOption } from \"../types\";\nimport styles from \"./SuggestionGrid.module.css\";\nimport { SuggestionItem } from \"./SuggestionItem\";\n\ninterface SuggestionGridProps {\n options: SuggestionOption[];\n activeIndex: number;\n onSelect: (option: SuggestionOption) => void;\n onHighlight: (index: number) => void;\n listboxId: string;\n}\n\nexport function SuggestionGrid({\n options,\n activeIndex,\n onSelect,\n onHighlight,\n listboxId,\n}: SuggestionGridProps) {\n return (\n <div className={styles.grid}>\n {options.map((option, i) => (\n <SuggestionItem\n key={option.text}\n option={option}\n isHighlighted={i === activeIndex}\n onSelect={onSelect}\n onHighlight={() => onHighlight(i)}\n id={`${listboxId}-option-${i}`}\n />\n ))}\n </div>\n );\n}\n","import styles from \"./AIAutocompleteDropdown.module.css\";\nimport { SuggestionGrid } from \"./components/SuggestionGrid\";\nimport type { AIAutocompleteDropdownProps } from \"./types\";\n\nexport function AIAutocompleteDropdown({\n suggestions,\n activeIndex,\n onSelect,\n onHighlight,\n isOpen,\n id,\n className,\n}: AIAutocompleteDropdownProps) {\n const activeSuggestion = suggestions[0];\n const options = activeSuggestion?.options ?? [];\n const hasOptions = isOpen && options.length > 0;\n\n return (\n <div\n id={id}\n role=\"listbox\"\n className={`${styles.dropdown} ${hasOptions ? styles.visible : \"\"} ${className ?? \"\"}`}\n onMouseDown={(e) => e.preventDefault()}\n >\n {options.length > 0 && (\n <SuggestionGrid\n options={options}\n activeIndex={activeIndex}\n onSelect={onSelect}\n onHighlight={onHighlight}\n listboxId={id}\n />\n )}\n </div>\n );\n}\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-b745b4fb\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-b745b4fb\";\n s.textContent = `.PillList-module_list_qvLqO {\n position: relative;\n z-index: 1;\n pointer-events: auto;\n display: inline-flex;\n gap: 5px;\n align-items: center;\n vertical-align: middle;\n transform: translateY(-3px);\n}\n\n.PillList-module_pill_osSyz {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 36px;\n padding: 7px 9px;\n border: none;\n border-radius: 6px;\n background: var(--ac-color-background-supportive, #313255);\n color: var(--ac-color-text-muted, #c1c4cb);\n font-family: \"IBM Plex Sans\", sans-serif;\n font-size: 19px;\n line-height: 30px;\n cursor: pointer;\n white-space: nowrap;\n animation: PillList-module_fadeIn_Aezob 400ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.PillList-module_pill_osSyz:hover {\n filter: brightness(1.2);\n}\n\n.PillList-module_active_Oll-- {\n outline: 1px solid #5a5b8a;\n}\n\n@keyframes PillList-module_fadeIn_Aezob {\n from {\n opacity: 0;\n }\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"list\":\"PillList-module_list_qvLqO\",\"pill\":\"PillList-module_pill_osSyz\",\"fadeIn\":\"PillList-module_fadeIn_Aezob\",\"active\":\"PillList-module_active_Oll--\"};","import type { Suggestion } from \"../types\";\nimport styles from \"./PillList.module.css\";\n\ninterface PillListProps {\n pills: Suggestion[];\n activePillIndex: number;\n onSelectPill: (index: number) => void;\n}\n\nfunction getPillOpacity(index: number): number {\n if (index === 0) return 0.4;\n if (index === 1) return 0.3;\n return 0.15;\n}\n\nexport function PillList({ pills, activePillIndex, onSelectPill }: PillListProps) {\n return (\n <span className={styles.list}>\n {pills.map((pill, i) => (\n <button\n key={`${pill.type}-${pill.text}`}\n type=\"button\"\n className={`${styles.pill} ${i === activePillIndex ? styles.active : \"\"}`}\n style={{ opacity: getPillOpacity(i) }}\n onClick={() => onSelectPill(i)}\n >\n {pill.text}\n </button>\n ))}\n </span>\n );\n}\n","import { type ChangeEvent, useCallback, useMemo, useRef, useState } from \"react\";\nimport type {\n CompletedParamState,\n Suggestion,\n SuggestionOption,\n UseAIAutocompleteOptions,\n UseAIAutocompleteReturn,\n} from \"../types\";\nimport { extractFilterQuery, filterOptions, findExactMatch } from \"../utils/filtering\";\nimport { deriveSegments, reconcileParams } from \"../utils/segments\";\nimport { useAutocompleteFetch, useDebouncedFetch } from \"./useAutocompleteFetch\";\nimport { useAutocompleteKeyboard } from \"./useAutocompleteKeyboard\";\nimport { useAutocompletePills } from \"./useAutocompletePills\";\n\nlet idCounter = 0;\nfunction useStableId(): string {\n const id = useRef<string | null>(null);\n if (id.current === null) {\n id.current = `:ac-${++idCounter}:`;\n }\n return id.current;\n}\n\nexport function useAIAutocomplete({\n onSubmit,\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder: customPlaceholder,\n apiConfig,\n columns = 2,\n eagerSuggestions = true,\n value: controlledValue,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n}: UseAIAutocompleteOptions): UseAIAutocompleteReturn {\n // === Controlled / uncontrolled state ===\n const isTextControlled = controlledValue !== undefined;\n const isParamsControlled = controlledParams !== undefined;\n\n const [internalText, setInternalText] = useState(\"\");\n const [internalCompletedParams, setInternalCompletedParams] = useState<CompletedParamState[]>([]);\n const [suggestions, setSuggestions] = useState<Suggestion[]>([]);\n const [activeDropdownIndex, setActiveDropdownIndex] = useState(-1);\n\n const text = isTextControlled ? controlledValue : internalText;\n const completedParams = isParamsControlled ? controlledParams : internalCompletedParams;\n\n // === Refs — must be before setText/setCompletedParams which read them ===\n const onSubmitRef = useRef(onSubmit);\n onSubmitRef.current = onSubmit;\n const onChangeRef = useRef(onChangeProp);\n onChangeRef.current = onChangeProp;\n const onParamsChangeRef = useRef(onParamsChange);\n onParamsChangeRef.current = onParamsChange;\n const controlledValueRef = useRef(controlledValue);\n controlledValueRef.current = controlledValue;\n const controlledParamsRef = useRef(controlledParams);\n controlledParamsRef.current = controlledParams;\n\n // Stable setText that reads controlled value + callback via refs (no stale closures)\n const setText = useCallback(\n (value: string | ((prev: string) => string)) => {\n if (typeof value === \"function\") {\n if (isTextControlled) {\n const newVal = value(controlledValueRef.current ?? \"\");\n onChangeRef.current?.(newVal);\n } else {\n setInternalText((prev) => {\n const newVal = value(prev);\n onChangeRef.current?.(newVal);\n return newVal;\n });\n }\n } else {\n if (!isTextControlled) setInternalText(value);\n onChangeRef.current?.(value);\n }\n },\n [isTextControlled],\n );\n\n // Stable setCompletedParams — same ref pattern\n const setCompletedParams = useCallback(\n (value: CompletedParamState[] | ((prev: CompletedParamState[]) => CompletedParamState[])) => {\n if (typeof value === \"function\") {\n if (isParamsControlled) {\n const newVal = value(controlledParamsRef.current ?? []);\n onParamsChangeRef.current?.(newVal);\n } else {\n setInternalCompletedParams((prev) => {\n const newVal = value(prev);\n onParamsChangeRef.current?.(newVal);\n return newVal;\n });\n }\n } else {\n if (!isParamsControlled) setInternalCompletedParams(value);\n onParamsChangeRef.current?.(value);\n }\n },\n [isParamsControlled],\n );\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const optionOverridesRef = useRef(optionOverrides);\n optionOverridesRef.current = optionOverrides;\n const maskCompletedTextRef = useRef(maskCompletedText);\n maskCompletedTextRef.current = maskCompletedText;\n const apiConfigRef = useRef(apiConfig);\n apiConfigRef.current = apiConfig;\n const textRef = useRef(text);\n textRef.current = text;\n const suggestionsRef = useRef(suggestions);\n suggestionsRef.current = suggestions;\n const filterBaseRef = useRef(0);\n const filterInProgressRef = useRef(false);\n const pillTappedRef = useRef(false);\n const skipNextFetchRef = useRef(false);\n const listboxId = useStableId();\n\n // === Fetch ===\n const { doFetch, isLoading, error, isReady, lastRawQueryRef } = useAutocompleteFetch({\n textRef,\n suggestionsRef,\n filterBaseRef,\n filterInProgressRef,\n maskCompletedTextRef,\n apiConfigRef,\n optionOverridesRef,\n onErrorRef,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n });\n\n useDebouncedFetch({\n text,\n completedParams,\n doFetch,\n filterBaseRef,\n filterInProgressRef,\n skipNextFetchRef,\n suggestionsRef,\n lastRawQueryRef,\n });\n\n // === Derived ===\n const segments = useMemo(() => deriveSegments(text, completedParams), [text, completedParams]);\n\n filterBaseRef.current = Math.min(filterBaseRef.current, text.length);\n const filterQuery = extractFilterQuery(text, filterBaseRef.current, filterInProgressRef.current);\n\n const placeholderText = useMemo(() => {\n const serverPlaceholder = suggestions\n .filter((s) => s.type === \"placeholder\")\n .map((s) => s.text)\n .join(\" \");\n return serverPlaceholder || customPlaceholder || \"\";\n }, [suggestions, customPlaceholder]);\n const actionableSuggestions = useMemo(\n () => suggestions.filter((s) => s.type !== \"placeholder\"),\n [suggestions],\n );\n const activeSuggestion: Suggestion | undefined = actionableSuggestions[0];\n const overrideFn = activeSuggestion ? optionOverrides?.[activeSuggestion.type] : undefined;\n const baseOptions = activeSuggestion\n ? overrideFn\n ? overrideFn(filterQuery.trim())\n : (activeSuggestion.options ?? [])\n : [];\n const filteredOptions = useMemo(\n () => filterOptions(baseOptions, filterQuery),\n [baseOptions, filterQuery],\n );\n const hasPlaceholder = placeholderText.length > 0;\n const isDropdownOpen =\n !isLoading &&\n filteredOptions.length > 0 &&\n (!!text || pillTappedRef.current || !hasPlaceholder);\n\n // === Option selection ===\n const selectOption = useCallback(\n (option: SuggestionOption) => {\n if (!activeSuggestion) return;\n\n const completed: CompletedParamState = {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: activeSuggestion.type,\n text: option.text,\n kind: option.kind,\n suggestionType: activeSuggestion.type,\n suggestionPlaceholder: activeSuggestion.text,\n options: activeSuggestion.options ?? [],\n metadata: option.metadata,\n };\n\n const base = filterBaseRef.current;\n let prefix = textRef.current.slice(0, base);\n if (prefix.length > 0 && !prefix.endsWith(\" \")) {\n const lastWord = prefix.split(/\\s+/).pop() ?? \"\";\n if (lastWord && option.text.toLowerCase().startsWith(lastWord.toLowerCase())) {\n prefix = prefix.slice(0, prefix.length - lastWord.length);\n }\n }\n\n const needsSpace = prefix.length > 0 && prefix[prefix.length - 1] !== \" \";\n const newText = prefix + (needsSpace ? \" \" : \"\") + option.text + \" \";\n setText(newText);\n filterBaseRef.current = newText.length;\n setCompletedParams((prev) => [...prev, completed]);\n pillTappedRef.current = false;\n setActiveDropdownIndex(-1);\n const remainingActionable = actionableSuggestions.length - 1;\n if (eagerSuggestions && remainingActionable > 0) {\n // Keep cached suggestions visible and skip the fetch\n setSuggestions((prev) => prev.filter((s) => s !== activeSuggestion));\n skipNextFetchRef.current = true;\n } else {\n // Clear all suggestions and let the debounced fetch bring fresh ones\n setSuggestions((prev) => prev.filter((s) => s.type === \"placeholder\"));\n }\n },\n [activeSuggestion, actionableSuggestions, eagerSuggestions, setText, setCompletedParams],\n );\n\n // === Text change handler ===\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLTextAreaElement>) => {\n const raw = e.target.value;\n const shouldCapitalize =\n raw.length > 0 &&\n !(e.nativeEvent as InputEvent)?.isComposing &&\n raw[0] !== raw[0].toUpperCase();\n const newValue = shouldCapitalize ? raw[0].toUpperCase() + raw.slice(1) : raw;\n setText(newValue);\n pillTappedRef.current = false;\n setActiveDropdownIndex(-1);\n\n const { valid, invalid } = reconcileParams(newValue, completedParams);\n if (invalid.length > 0) {\n setCompletedParams(() => valid);\n for (const param of invalid) {\n setSuggestions((prev) => [\n {\n type: param.suggestionType,\n text: param.suggestionPlaceholder,\n required: true,\n options: param.options,\n },\n ...prev,\n ]);\n }\n }\n\n if (activeSuggestion && invalid.length === 0) {\n const newFilterQuery = extractFilterQuery(\n newValue,\n filterBaseRef.current,\n filterInProgressRef.current,\n );\n const match = findExactMatch(activeSuggestion.options, newFilterQuery);\n if (match) {\n setCompletedParams((prev) => [\n ...prev,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: activeSuggestion.type,\n text: match.text,\n kind: match.kind,\n suggestionType: activeSuggestion.type,\n suggestionPlaceholder: activeSuggestion.text,\n options: activeSuggestion.options ?? [],\n metadata: match.metadata,\n },\n ]);\n setSuggestions((prev) => prev.filter((s) => s !== activeSuggestion));\n }\n }\n },\n [completedParams, activeSuggestion, setText, setCompletedParams],\n );\n\n // === Pills ===\n const pills = useAutocompletePills({\n completedParams,\n suggestions,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n filterBaseRef,\n pillTappedRef,\n });\n\n const reEditParam = useCallback(\n (param: CompletedParamState) => {\n pills.reEditParam(param).apply(setText);\n },\n [pills, setText],\n );\n\n // === Keyboard ===\n const { handleKeyDown } = useAutocompleteKeyboard({\n activeDropdownIndex,\n setActiveDropdownIndex,\n filteredOptions,\n selectOption,\n onSubmitRef,\n text,\n completedParams,\n isDropdownOpen,\n hasPlaceholder,\n placeholderText,\n suggestions,\n actionableSuggestions,\n setActivePill: pills.setActivePill,\n filterBaseRef,\n columns,\n setText,\n setCompletedParams,\n setSuggestions,\n });\n\n // === Reset ===\n const reset = useCallback(() => {\n setText(\"\");\n setCompletedParams(() => []);\n setSuggestions([]);\n setActiveDropdownIndex(-1);\n filterBaseRef.current = 0;\n filterInProgressRef.current = false;\n lastRawQueryRef.current = \"\";\n doFetch(\"\", []);\n }, [doFetch, setText, setCompletedParams, lastRawQueryRef]);\n\n const activeDescendantId =\n activeDropdownIndex >= 0 ? `${listboxId}-option-${activeDropdownIndex}` : undefined;\n\n return {\n completedParams,\n suggestionPills: actionableSuggestions,\n setActivePill: pills.setActivePill,\n removeLastParam: pills.removeLastParam,\n reEditParam,\n segments,\n suggestions,\n activeIndex: activeDropdownIndex,\n isReady,\n isLoading,\n error,\n inputProps: {\n value: text,\n placeholder: placeholderText || undefined,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n role: \"combobox\" as const,\n \"aria-expanded\": isDropdownOpen,\n \"aria-activedescendant\": activeDescendantId,\n \"aria-autocomplete\": \"list\" as const,\n \"aria-controls\": listboxId,\n },\n reset,\n dropdownProps: {\n suggestions: activeSuggestion ? [{ ...activeSuggestion, options: filteredOptions }] : [],\n activeIndex: activeDropdownIndex,\n onSelect: selectOption,\n onHighlight: setActiveDropdownIndex,\n isOpen: isDropdownOpen,\n id: listboxId,\n },\n };\n}\n","import type { SuggestionOption } from \"../types\";\n\n/**\n * Extracts the effective filter query from the region after filterBase.\n * If the server marked the region as in_progress, the full region is used.\n * Otherwise, filtering only starts after the first space (to avoid filtering\n * mid-word when the user continues typing a word that was already in the input).\n */\nexport function extractFilterQuery(\n text: string,\n filterBase: number,\n isInProgress: boolean,\n): string {\n const rawRegion = text.slice(filterBase);\n if (isInProgress || filterBase === 0 || text[filterBase - 1] === \" \") {\n return rawRegion;\n }\n const spaceIdx = rawRegion.indexOf(\" \");\n return spaceIdx === -1 ? \"\" : rawRegion.slice(spaceIdx + 1);\n}\n\n/**\n * Filters options using partial substring match on the text after the last completed param.\n */\nexport function filterOptions(\n options: SuggestionOption[] | undefined,\n query: string,\n): SuggestionOption[] {\n if (!options) return [];\n const trimmed = query.trimStart();\n if (!trimmed) return options;\n const lower = trimmed.toLowerCase();\n return options.filter((o) => !o.is_tappable || o.text.toLowerCase().includes(lower));\n}\n\n/**\n * Finds an exact match for the trimmed filter query against options.\n */\nexport function findExactMatch(\n options: SuggestionOption[] | undefined,\n query: string,\n): SuggestionOption | null {\n if (!options) return null;\n const trimmed = query.trim();\n if (!trimmed) return null;\n const lower = trimmed.toLowerCase();\n return options.find((o) => o.is_tappable && o.text.toLowerCase() === lower) ?? null;\n}\n","import type { CompletedParamState, Segment } from \"../types\";\n\n/**\n * Derives segments for overlay rendering by matching completed params in text.\n */\nexport function deriveSegments(text: string, completedParams: CompletedParamState[]): Segment[] {\n const result: Segment[] = [];\n let pos = 0;\n\n for (const param of completedParams) {\n const idx = text.indexOf(param.text, pos);\n if (idx === -1) continue;\n if (idx > pos) {\n result.push({ type: \"text\", value: text.slice(pos, idx) });\n }\n result.push({ type: \"completed\", value: param.text, param });\n pos = idx + param.text.length;\n }\n\n const remaining = text.slice(pos);\n if (remaining) {\n result.push({ type: \"text\", value: remaining });\n }\n\n return result;\n}\n\n/**\n * Checks which completed params still exist in the new text.\n */\nexport function reconcileParams(\n text: string,\n completedParams: CompletedParamState[],\n): { valid: CompletedParamState[]; invalid: CompletedParamState[] } {\n const valid: CompletedParamState[] = [];\n const invalid: CompletedParamState[] = [];\n let pos = 0;\n\n for (const param of completedParams) {\n const idx = text.indexOf(param.text, pos);\n if (idx === -1) {\n invalid.push(param);\n } else {\n valid.push(param);\n pos = idx + param.text.length;\n }\n }\n\n return { valid, invalid };\n}\n","import { type MutableRefObject, useCallback, useEffect, useRef, useState } from \"react\";\nimport type {\n APIConfig,\n CompletedParamState,\n OptionOverrides,\n Suggestion,\n SuggestionOption,\n} from \"../types\";\nimport { fetchSuggestions } from \"../utils/api\";\nimport { buildQuery } from \"../utils/buildQuery\";\nimport { extractFilterQuery, filterOptions, findExactMatch } from \"../utils/filtering\";\nimport { applyOptionOverrides } from \"../utils/overrides\";\n\nconst DEBOUNCE_MS = 100;\nconst SLOW_DEBOUNCE_MS = 300;\nconst MIN_CHARS_DIFF = 2;\n\ninterface UseAutocompleteFetchOptions {\n textRef: MutableRefObject<string>;\n suggestionsRef: MutableRefObject<Suggestion[]>;\n filterBaseRef: MutableRefObject<number>;\n filterInProgressRef: MutableRefObject<boolean>;\n maskCompletedTextRef: MutableRefObject<boolean | undefined>;\n apiConfigRef: MutableRefObject<APIConfig | undefined>;\n optionOverridesRef: MutableRefObject<OptionOverrides | undefined>;\n onErrorRef: MutableRefObject<((error: Error) => void) | undefined>;\n setCompletedParams: (fn: (prev: CompletedParamState[]) => CompletedParamState[]) => void;\n setSuggestions: (fn: Suggestion[] | ((prev: Suggestion[]) => Suggestion[])) => void;\n setActiveDropdownIndex: (index: number) => void;\n}\n\ninterface UseAutocompleteFetchReturn {\n doFetch: (rawQuery: string, completed: CompletedParamState[]) => Promise<void>;\n isLoading: boolean;\n error: Error | null;\n isReady: boolean;\n lastRawQueryRef: MutableRefObject<string>;\n}\n\nexport function useAutocompleteFetch({\n textRef,\n suggestionsRef,\n filterBaseRef,\n filterInProgressRef,\n maskCompletedTextRef,\n apiConfigRef,\n optionOverridesRef,\n onErrorRef,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n}: UseAutocompleteFetchOptions): UseAutocompleteFetchReturn {\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [isReady, setIsReady] = useState(false);\n const fetchVersionRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n const lastRawQueryRef = useRef(\"\");\n\n const doFetch = useCallback(\n async (rawQuery: string, completed: CompletedParamState[]) => {\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n const version = ++fetchVersionRef.current;\n const textAtRequest = textRef.current.length;\n\n const hasSuggestions = suggestionsRef.current.some((s) => s.type !== \"placeholder\");\n if (!hasSuggestions) setIsLoading(true);\n setError(null);\n try {\n const res = await fetchSuggestions(rawQuery, completed, {\n maskCompletedText: maskCompletedTextRef.current,\n signal: controller.signal,\n apiConfig: apiConfigRef.current,\n });\n\n if (version !== fetchVersionRef.current) return;\n\n let newSuggestions = applyOptionOverrides(\n res.data.suggestions ?? [],\n optionOverridesRef.current,\n );\n setIsReady(res.data.is_ready ?? false);\n lastRawQueryRef.current = rawQuery;\n\n const input = res.data.input ?? [];\n const lastInput = input[input.length - 1];\n const currentText = textRef.current;\n if (lastInput?.state === \"in_progress\") {\n filterInProgressRef.current = true;\n const inProgressIdx = currentText.toLowerCase().lastIndexOf(lastInput.text.toLowerCase());\n if (inProgressIdx !== -1) {\n filterBaseRef.current = inProgressIdx;\n } else {\n filterBaseRef.current = textAtRequest;\n }\n } else {\n filterInProgressRef.current = false;\n filterBaseRef.current = textAtRequest;\n }\n\n // Check if the user already typed an exact match while waiting\n const actionable = newSuggestions.filter((s) => s.type !== \"placeholder\");\n const active = actionable[0];\n if (active) {\n const query = extractFilterQuery(\n currentText,\n filterBaseRef.current,\n filterInProgressRef.current,\n );\n const match = findExactMatch(active.options, query);\n if (match) {\n setCompletedParams((prev) => [\n ...prev,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: active.type,\n text: match.text,\n kind: match.kind,\n suggestionType: active.type,\n suggestionPlaceholder: active.text,\n options: active.options ?? [],\n metadata: match.metadata,\n },\n ]);\n newSuggestions = newSuggestions.filter((s) => s !== active);\n }\n }\n\n setSuggestions(newSuggestions);\n setIsLoading(false);\n setActiveDropdownIndex(-1);\n } catch (err) {\n if (version === fetchVersionRef.current) {\n const caughtError = err instanceof Error ? err : new Error(String(err));\n setError(caughtError);\n setIsLoading(false);\n onErrorRef.current?.(caughtError);\n }\n }\n },\n [\n textRef,\n suggestionsRef,\n filterBaseRef,\n filterInProgressRef,\n maskCompletedTextRef,\n apiConfigRef,\n optionOverridesRef,\n onErrorRef,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n ],\n );\n\n // Mount fetch\n useEffect(() => {\n doFetch(\"\", []);\n return () => {\n abortRef.current?.abort();\n };\n }, [doFetch]);\n\n return { doFetch, isLoading, error, isReady, lastRawQueryRef };\n}\n\ninterface UseDebouncedFetchOptions {\n text: string;\n completedParams: CompletedParamState[];\n doFetch: (rawQuery: string, completed: CompletedParamState[]) => Promise<void>;\n filterBaseRef: MutableRefObject<number>;\n filterInProgressRef: MutableRefObject<boolean>;\n skipNextFetchRef: MutableRefObject<boolean>;\n suggestionsRef: MutableRefObject<Suggestion[]>;\n lastRawQueryRef: MutableRefObject<string>;\n}\n\nexport function useDebouncedFetch({\n text,\n completedParams,\n doFetch,\n filterBaseRef,\n filterInProgressRef,\n skipNextFetchRef,\n suggestionsRef,\n lastRawQueryRef,\n}: UseDebouncedFetchOptions): void {\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const slowDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const hasFetchedRef = useRef(true);\n\n useEffect(() => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (slowDebounceRef.current) clearTimeout(slowDebounceRef.current);\n\n const attemptFetch = (minDiff: number): boolean => {\n if (skipNextFetchRef.current) {\n skipNextFetchRef.current = false;\n return false;\n }\n\n if (!text && completedParams.length === 0) {\n if (!hasFetchedRef.current) {\n hasFetchedRef.current = true;\n return false;\n }\n doFetch(\"\", []);\n return true;\n }\n\n const currentQuery = extractFilterQuery(\n text,\n filterBaseRef.current,\n filterInProgressRef.current,\n );\n const currentSuggestions = suggestionsRef.current;\n const actionable = currentSuggestions.filter((s: Suggestion) => s.type !== \"placeholder\");\n const active = actionable[0];\n const currentFiltered = active ? filterOptions(active.options, currentQuery) : [];\n const tappableFiltered = currentFiltered.filter((o: SuggestionOption) => o.is_tappable);\n const hasExactMatch = active ? findExactMatch(active.options, currentQuery) !== null : false;\n\n const isInFilterZone = currentQuery.trim().length > 0;\n if (tappableFiltered.length > 0 && !hasExactMatch && isInFilterZone) return false;\n\n const { rawQuery, completedParams: updatedParams } = buildQuery(text, completedParams);\n const isDeleting = rawQuery.length < lastRawQueryRef.current.length;\n const charDiff = Math.abs(rawQuery.length - lastRawQueryRef.current.length);\n if (isDeleting || charDiff >= minDiff) {\n doFetch(rawQuery, updatedParams);\n return true;\n }\n return false;\n };\n\n debounceRef.current = setTimeout(() => {\n if (attemptFetch(MIN_CHARS_DIFF)) {\n if (slowDebounceRef.current) clearTimeout(slowDebounceRef.current);\n }\n }, DEBOUNCE_MS);\n\n slowDebounceRef.current = setTimeout(() => attemptFetch(1), SLOW_DEBOUNCE_MS);\n\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (slowDebounceRef.current) clearTimeout(slowDebounceRef.current);\n };\n }, [\n text,\n completedParams,\n doFetch,\n filterBaseRef,\n filterInProgressRef,\n skipNextFetchRef,\n suggestionsRef,\n lastRawQueryRef,\n ]);\n}\n","import type {\n APIConfig,\n AutocompleteRequest,\n AutocompleteResponse,\n CompletedParam,\n CompletedParamState,\n} from \"../types\";\n\n// Replaced at build time by tsup/vitest `define` config with the package.json version.\ndeclare const __SDK_VERSION__: string;\nconst SDK_VERSION = __SDK_VERSION__;\n\nlet hasWarnedMissingKey = false;\n\nfunction generateRequestId(): string {\n return crypto.randomUUID();\n}\n\nfunction toWireParam(param: CompletedParamState, includeText: boolean): CompletedParam {\n return {\n placeholder: param.placeholder,\n type: param.type,\n ...(includeText && { text: param.text }),\n kind: param.kind,\n };\n}\n\nexport async function fetchSuggestions(\n rawQuery: string,\n completedParams: CompletedParamState[],\n options?: {\n maskCompletedText?: boolean;\n signal?: AbortSignal;\n apiConfig?: APIConfig;\n },\n): Promise<AutocompleteResponse> {\n const apiConfig = options?.apiConfig;\n const apiKey = apiConfig?.apiKey ?? \"\";\n if (!apiKey && !hasWarnedMissingKey) {\n hasWarnedMissingKey = true;\n // biome-ignore lint/suspicious/noConsole: intentional dev warning\n console.warn(\n \"[AIAutocomplete] No apiKey in apiConfig. Requests will be sent without an Authorization header.\",\n );\n }\n const authScheme = apiConfig?.authScheme ?? \"Bearer\";\n const includeText = !options?.maskCompletedText;\n\n const rawCount = completedParams.find(\n (p) => p.type === \"contact\" && p.metadata?.contact_account_count,\n )?.metadata?.contact_account_count;\n const contactAccountCount = typeof rawCount === \"number\" ? rawCount : undefined;\n\n const body: AutocompleteRequest = {\n data: {\n raw_query: rawQuery,\n completed_params: completedParams.map((p) => toWireParam(p, includeText)),\n ...(contactAccountCount != null && { contact_account_count: contactAccountCount }),\n },\n meta: {\n request_id: generateRequestId(),\n request_at: new Date().toISOString(),\n language: typeof navigator !== \"undefined\" ? navigator.language : \"en-US\",\n client_version: SDK_VERSION,\n },\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(apiConfig?.appIdentifier && { \"X-App-Identifier\": apiConfig.appIdentifier }),\n ...apiConfig?.headers,\n };\n if (apiKey) {\n headers.Authorization = authScheme === \"Basic\" ? `Basic ${btoa(apiKey)}` : `Bearer ${apiKey}`;\n }\n\n const response = await fetch(apiConfig?.endpoint ?? \"/ac/suggest\", {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n });\n\n if (!response.ok) {\n throw new Error(`API error: ${response.status} ${response.statusText}`);\n }\n\n return response.json() as Promise<AutocompleteResponse>;\n}\n","import type { CompletedParamState } from \"../types\";\n\ninterface BuildQueryResult {\n rawQuery: string;\n completedParams: CompletedParamState[];\n}\n\n/**\n * Takes the raw input text and completed params (without placeholders),\n * replaces each completed param's text in the string with a {{TYPE_N}} token,\n * and returns the transformed query + params with placeholders filled in.\n *\n * Replacements happen left-to-right, first occurrence only per param.\n * Counter is per-type (e.g. {{TASK_1}}, {{GOAL_1}}, {{GOAL_2}}).\n */\nexport function buildQuery(text: string, completedParams: CompletedParamState[]): BuildQueryResult {\n let result = text;\n const typeCounts: Record<string, number> = {};\n const updatedParams: CompletedParamState[] = [];\n\n for (const param of completedParams) {\n const count = (typeCounts[param.type] ?? 0) + 1;\n typeCounts[param.type] = count;\n\n const typeKey = param.type.toUpperCase().replace(/\\s+/g, \"_\");\n const placeholder = `{{${typeKey}_${count}}}`;\n\n // Replace first occurrence of the param text in the string\n const index = result.indexOf(param.text);\n if (index !== -1) {\n result = result.slice(0, index) + placeholder + result.slice(index + param.text.length);\n }\n\n updatedParams.push({ ...param, placeholder });\n }\n\n return { rawQuery: result, completedParams: updatedParams };\n}\n","import type { Suggestion, SuggestionOption } from \"../types\";\n\n/**\n * Applies option overrides by calling the override function with an empty query,\n * then prepending results to suggestions that match by type, deduplicating by text.\n */\nexport function applyOptionOverrides(\n suggestions: Suggestion[],\n overrides?: Record<string, (query: string) => SuggestionOption[]>,\n): Suggestion[] {\n if (!overrides) return suggestions;\n return suggestions.map((s) => {\n const fn = overrides[s.type];\n if (!fn) return s;\n const extra = fn(\"\");\n if (extra.length === 0) return s;\n const existingTexts = new Set(extra.map((o) => o.text));\n const deduped = (s.options ?? []).filter((o) => !existingTexts.has(o.text));\n return { ...s, options: [...extra, ...deduped] };\n });\n}\n","import { type KeyboardEvent, type MutableRefObject, useCallback } from \"react\";\nimport type {\n AutocompleteResult,\n CompletedParamState,\n Suggestion,\n SuggestionOption,\n} from \"../types\";\nimport { buildQuery } from \"../utils/buildQuery\";\n\ninterface UseAutocompleteKeyboardOptions {\n activeDropdownIndex: number;\n setActiveDropdownIndex: (index: number) => void;\n filteredOptions: SuggestionOption[];\n selectOption: (option: SuggestionOption) => void;\n onSubmitRef: MutableRefObject<((result: AutocompleteResult) => void) | undefined>;\n text: string;\n completedParams: CompletedParamState[];\n isDropdownOpen: boolean;\n hasPlaceholder: boolean;\n placeholderText: string;\n suggestions: Suggestion[];\n actionableSuggestions: Suggestion[];\n setActivePill: (index: number) => void;\n filterBaseRef: MutableRefObject<number>;\n columns: number;\n setText: (value: string) => void;\n setCompletedParams: (fn: (prev: CompletedParamState[]) => CompletedParamState[]) => void;\n setSuggestions: (fn: (prev: Suggestion[]) => Suggestion[]) => void;\n}\n\nexport function useAutocompleteKeyboard({\n activeDropdownIndex,\n setActiveDropdownIndex,\n filteredOptions,\n selectOption,\n onSubmitRef,\n text,\n completedParams,\n isDropdownOpen,\n hasPlaceholder,\n placeholderText,\n suggestions,\n actionableSuggestions,\n setActivePill,\n filterBaseRef,\n columns,\n setText,\n setCompletedParams,\n setSuggestions,\n}: UseAutocompleteKeyboardOptions) {\n const getTappableIndices = useCallback(() => {\n const tappable = filteredOptions\n .map((o, i) => (o.is_tappable ? i : -1))\n .filter((i) => i !== -1);\n // Column-first ordering: all column-0 items, then column-1, etc.\n const buckets: number[][] = Array.from({ length: columns }, () => []);\n for (const i of tappable) buckets[i % columns].push(i);\n return buckets.flat();\n }, [filteredOptions, columns]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n const tappableIndices = getTappableIndices();\n\n switch (e.key) {\n case \"ArrowDown\": {\n e.preventDefault();\n if (tappableIndices.length === 0) return;\n const currentPos = tappableIndices.indexOf(activeDropdownIndex);\n const nextPos = currentPos < tappableIndices.length - 1 ? currentPos + 1 : 0;\n setActiveDropdownIndex(tappableIndices[nextPos]);\n break;\n }\n case \"ArrowUp\": {\n e.preventDefault();\n if (tappableIndices.length === 0) return;\n const currentPos = tappableIndices.indexOf(activeDropdownIndex);\n const prevPos = currentPos > 0 ? currentPos - 1 : tappableIndices.length - 1;\n setActiveDropdownIndex(tappableIndices[prevPos]);\n break;\n }\n case \"ArrowRight\": {\n if (activeDropdownIndex < 0) {\n // Only cycle pills if the cursor is at the end of the input\n const target = e.target as HTMLTextAreaElement;\n const atEnd =\n target.selectionStart != null && target.selectionStart === target.value.length;\n if (atEnd && actionableSuggestions.length > 1) {\n e.preventDefault();\n setActivePill(1);\n }\n break;\n }\n const col = activeDropdownIndex % columns;\n if (col < columns - 1) {\n const rightNeighbor = activeDropdownIndex + 1;\n if (\n rightNeighbor < filteredOptions.length &&\n filteredOptions[rightNeighbor]?.is_tappable\n ) {\n e.preventDefault();\n setActiveDropdownIndex(rightNeighbor);\n }\n }\n break;\n }\n case \"ArrowLeft\": {\n if (activeDropdownIndex < 0) break;\n if (activeDropdownIndex % columns > 0) {\n const leftNeighbor = activeDropdownIndex - 1;\n if (leftNeighbor >= 0 && filteredOptions[leftNeighbor]?.is_tappable) {\n e.preventDefault();\n setActiveDropdownIndex(leftNeighbor);\n }\n }\n break;\n }\n case \"Enter\": {\n e.preventDefault();\n if (activeDropdownIndex >= 0 && filteredOptions[activeDropdownIndex]?.is_tappable) {\n selectOption(filteredOptions[activeDropdownIndex]);\n } else if (onSubmitRef.current) {\n const { rawQuery, completedParams: finalParams } = buildQuery(text, completedParams);\n const result: AutocompleteResult = {\n query: text.trim(),\n raw_query: rawQuery,\n completed_params: finalParams,\n };\n onSubmitRef.current(result);\n }\n break;\n }\n case \"Tab\": {\n if (activeDropdownIndex >= 0 && filteredOptions[activeDropdownIndex]?.is_tappable) {\n e.preventDefault();\n selectOption(filteredOptions[activeDropdownIndex]);\n } else if (isDropdownOpen) {\n const firstTappable = filteredOptions.find((o) => o.is_tappable);\n if (firstTappable) {\n e.preventDefault();\n selectOption(firstTappable);\n }\n } else if (!text && hasPlaceholder) {\n e.preventDefault();\n const placeholderSuggestion = suggestions.find((s) => s.type === \"placeholder\");\n if (placeholderSuggestion) {\n setText(placeholderText);\n filterBaseRef.current = placeholderText.length;\n setCompletedParams((prev) => [\n ...prev,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: placeholderSuggestion.type,\n text: placeholderText,\n kind: null,\n suggestionType: placeholderSuggestion.type,\n suggestionPlaceholder: placeholderSuggestion.text,\n options: placeholderSuggestion.options ?? [],\n },\n ]);\n setSuggestions((prev) => prev.filter((s) => s !== placeholderSuggestion));\n } else {\n setText(placeholderText);\n filterBaseRef.current = placeholderText.length;\n }\n }\n break;\n }\n case \"Escape\":\n setActiveDropdownIndex(-1);\n break;\n }\n },\n [\n actionableSuggestions,\n activeDropdownIndex,\n columns,\n completedParams,\n filteredOptions,\n filterBaseRef,\n getTappableIndices,\n hasPlaceholder,\n isDropdownOpen,\n onSubmitRef,\n placeholderText,\n selectOption,\n setActiveDropdownIndex,\n setActivePill,\n setCompletedParams,\n setSuggestions,\n setText,\n suggestions,\n text,\n ],\n );\n\n return { handleKeyDown, getTappableIndices };\n}\n","import { type MutableRefObject, useCallback } from \"react\";\nimport type { CompletedParamState, Suggestion } from \"../types\";\n\ninterface UseAutocompletePillsOptions {\n completedParams: CompletedParamState[];\n suggestions: Suggestion[];\n setCompletedParams: (fn: (prev: CompletedParamState[]) => CompletedParamState[]) => void;\n setSuggestions: (fn: Suggestion[] | ((prev: Suggestion[]) => Suggestion[])) => void;\n setActiveDropdownIndex: (index: number) => void;\n filterBaseRef: MutableRefObject<number>;\n pillTappedRef: MutableRefObject<boolean>;\n}\n\nexport function useAutocompletePills({\n completedParams,\n suggestions,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n filterBaseRef,\n pillTappedRef,\n}: UseAutocompletePillsOptions) {\n const setActivePill = useCallback(\n (index: number) => {\n const actionable = suggestions.filter((s) => s.type !== \"placeholder\");\n if (index < 0 || index >= actionable.length) return;\n const moved = actionable[index];\n const rest = actionable.filter((_, i) => i !== index);\n const placeholders = suggestions.filter((s) => s.type === \"placeholder\");\n setSuggestions([...placeholders, moved, ...rest]);\n pillTappedRef.current = true;\n setActiveDropdownIndex(-1);\n },\n [suggestions, setSuggestions, setActiveDropdownIndex, pillTappedRef],\n );\n\n const removeLastParam = useCallback(() => {\n if (completedParams.length === 0) return;\n const lastParam = completedParams[completedParams.length - 1];\n const restoredSuggestion: Suggestion = {\n type: lastParam.suggestionType,\n text: lastParam.suggestionPlaceholder,\n required: true,\n options: lastParam.options,\n };\n setCompletedParams((prev) => prev.slice(0, -1));\n setSuggestions((prev: Suggestion[]) => [restoredSuggestion, ...prev]);\n setActiveDropdownIndex(-1);\n }, [completedParams, setCompletedParams, setSuggestions, setActiveDropdownIndex]);\n\n const reEditParam = useCallback(\n (param: CompletedParamState) => {\n const restoredSuggestion: Suggestion = {\n type: param.suggestionType,\n text: param.suggestionPlaceholder,\n required: true,\n options: param.options,\n };\n return {\n apply: (setText: (fn: (prev: string) => string) => void) => {\n setText((prev) => {\n let pos = 0;\n for (const p of completedParams) {\n const idx = prev.indexOf(p.text, pos);\n if (idx === -1) continue;\n if (p.id === param.id) {\n const before = prev.slice(0, idx);\n const after = prev.slice(idx + param.text.length);\n const cleaned = (before + after).replace(/ {2,}/g, \" \");\n filterBaseRef.current = Math.min(filterBaseRef.current, cleaned.length);\n return cleaned;\n }\n pos = idx + p.text.length;\n }\n return prev;\n });\n setCompletedParams((prev) => prev.filter((p) => p.id !== param.id));\n setSuggestions((prev: Suggestion[]) => [restoredSuggestion, ...prev]);\n setActiveDropdownIndex(-1);\n pillTappedRef.current = true;\n },\n };\n },\n [\n completedParams,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n filterBaseRef,\n pillTappedRef,\n ],\n );\n\n return { setActivePill, removeLastParam, reEditParam };\n}\n"],"mappings":"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","names":["index_exports","__export","AIAutocomplete","AIAutocompleteDropdown","useAIAutocomplete","__toCommonJS","import_react","s","AIAutocomplete_module_css_default","s","AIAutocompleteDropdown_module_css_default","s","SuggestionGrid_module_css_default","s","SuggestionItem_module_css_default","import_jsx_runtime","SuggestionItem","option","isHighlighted","onSelect","onHighlight","id","className","SuggestionItem_module_css_default","e","import_jsx_runtime","SuggestionGrid","options","activeIndex","onSelect","onHighlight","listboxId","SuggestionGrid_module_css_default","option","i","SuggestionItem","import_jsx_runtime","AIAutocompleteDropdown","suggestions","activeIndex","onSelect","onHighlight","isOpen","id","className","options","hasOptions","AIAutocompleteDropdown_module_css_default","e","SuggestionGrid","s","PillList_module_css_default","import_jsx_runtime","getPillOpacity","index","PillList","pills","activePillIndex","onSelectPill","PillList_module_css_default","pill","i","import_react","extractFilterQuery","text","filterBase","isInProgress","rawRegion","spaceIdx","filterOptions","options","query","trimmed","lower","o","findExactMatch","deriveSegments","text","completedParams","result","pos","param","idx","remaining","reconcileParams","valid","invalid","import_react","SDK_VERSION","hasWarnedMissingKey","generateRequestId","toWireParam","param","includeText","fetchSuggestions","rawQuery","completedParams","options","apiConfig","apiKey","authScheme","rawCount","p","contactAccountCount","body","headers","response","buildQuery","text","completedParams","result","typeCounts","updatedParams","param","count","placeholder","index","applyOptionOverrides","suggestions","overrides","s","fn","extra","existingTexts","o","deduped","DEBOUNCE_MS","SLOW_DEBOUNCE_MS","MIN_CHARS_DIFF","useAutocompleteFetch","textRef","suggestionsRef","filterBaseRef","filterInProgressRef","maskCompletedTextRef","apiConfigRef","optionOverridesRef","onErrorRef","setCompletedParams","setSuggestions","setActiveDropdownIndex","isLoading","setIsLoading","error","setError","isReady","setIsReady","fetchVersionRef","abortRef","lastRawQueryRef","doFetch","rawQuery","completed","controller","version","textAtRequest","s","res","fetchSuggestions","newSuggestions","applyOptionOverrides","input","lastInput","currentText","inProgressIdx","active","query","extractFilterQuery","match","findExactMatch","prev","err","caughtError","useDebouncedFetch","text","completedParams","skipNextFetchRef","debounceRef","slowDebounceRef","hasFetchedRef","attemptFetch","minDiff","currentQuery","tappableFiltered","filterOptions","o","hasExactMatch","isInFilterZone","updatedParams","buildQuery","isDeleting","charDiff","import_react","useAutocompleteKeyboard","activeDropdownIndex","setActiveDropdownIndex","filteredOptions","selectOption","onSubmitRef","text","completedParams","isDropdownOpen","hasPlaceholder","placeholderText","suggestions","actionableSuggestions","setActivePill","filterBaseRef","columns","setText","setCompletedParams","setSuggestions","getTappableIndices","tappable","o","i","buckets","e","tappableIndices","currentPos","nextPos","prevPos","target","rightNeighbor","leftNeighbor","rawQuery","finalParams","buildQuery","result","firstTappable","placeholderSuggestion","s","prev","import_react","useAutocompletePills","completedParams","suggestions","setCompletedParams","setSuggestions","setActiveDropdownIndex","filterBaseRef","pillTappedRef","setActivePill","index","actionable","s","moved","rest","_","i","placeholders","removeLastParam","lastParam","restoredSuggestion","prev","reEditParam","param","setText","pos","p","idx","before","after","cleaned","idCounter","useStableId","id","useAIAutocomplete","onSubmit","onError","optionOverrides","maskCompletedText","customPlaceholder","apiConfig","columns","eagerSuggestions","controlledValue","controlledParams","onChangeProp","onParamsChange","isTextControlled","isParamsControlled","internalText","setInternalText","internalCompletedParams","setInternalCompletedParams","suggestions","setSuggestions","activeDropdownIndex","setActiveDropdownIndex","text","completedParams","onSubmitRef","onChangeRef","onParamsChangeRef","controlledValueRef","controlledParamsRef","setText","value","newVal","prev","setCompletedParams","onErrorRef","optionOverridesRef","maskCompletedTextRef","apiConfigRef","textRef","suggestionsRef","filterBaseRef","filterInProgressRef","pillTappedRef","skipNextFetchRef","listboxId","doFetch","isLoading","error","isReady","lastRawQueryRef","useAutocompleteFetch","useDebouncedFetch","segments","deriveSegments","filterQuery","extractFilterQuery","placeholderText","s","actionableSuggestions","activeSuggestion","overrideFn","baseOptions","filteredOptions","filterOptions","hasPlaceholder","isDropdownOpen","selectOption","option","completed","base","prefix","lastWord","needsSpace","newText","remainingActionable","handleChange","e","raw","newValue","valid","invalid","reconcileParams","param","newFilterQuery","match","findExactMatch","pills","useAutocompletePills","reEditParam","handleKeyDown","useAutocompleteKeyboard","reset","activeDescendantId","import_jsx_runtime","AIAutocomplete","onSubmit","onError","optionOverrides","maskCompletedText","placeholder","className","apiConfig","columns","eagerSuggestions","value","controlledParams","onChangeProp","onParamsChange","ref","textareaRef","handleSubmitRef","completedParams","suggestionPills","setActivePill","segments","inputProps","dropdownProps","reset","useAIAutocomplete","result","handleContainerClick","canSubmit","handleSubmit","rawQuery","finalParams","buildQuery","onChange","inputPlaceholder","restProps","isEmpty","AIAutocomplete_module_css_default","AIAutocompleteDropdown","seg","i","PillList","e"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/AIAutocomplete.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/AIAutocomplete.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/AIAutocompleteDropdown.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionGrid.module.css.js","../src/components/SuggestionItem.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionItem.module.css.js","../src/components/SuggestionGrid.tsx","../src/AIAutocompleteDropdown.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/PillList.module.css.js","../src/components/PillList.tsx","../src/hooks/useAIAutocomplete.ts","../src/utils/filtering.ts","../src/utils/segments.ts","../src/hooks/useAutocompleteFetch.ts","../src/utils/api.ts","../src/utils/buildQuery.ts","../src/utils/overrides.ts","../src/hooks/useAutocompleteKeyboard.ts","../src/hooks/useAutocompletePills.ts"],"sourcesContent":["export { AIAutocomplete } from \"./AIAutocomplete\";\nexport { AIAutocompleteDropdown } from \"./AIAutocompleteDropdown\";\nexport { useAIAutocomplete } from \"./hooks/useAIAutocomplete\";\nexport type {\n AIAutocompleteDropdownProps,\n AIAutocompleteHandle,\n AIAutocompleteProps,\n APIConfig,\n AutocompleteResult,\n CompletedParam,\n CompletedParamState,\n OptionOverrides,\n Segment,\n Suggestion,\n SuggestionOption,\n TaskKind,\n UseAIAutocompleteOptions,\n UseAIAutocompleteReturn,\n} from \"./types\";\n","import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from \"react\";\nimport styles from \"./AIAutocomplete.module.css\";\nimport { AIAutocompleteDropdown } from \"./AIAutocompleteDropdown\";\nimport { PillList } from \"./components/PillList\";\nimport { useAIAutocomplete } from \"./hooks/useAIAutocomplete\";\nimport type { AIAutocompleteHandle, AIAutocompleteProps, AutocompleteResult } from \"./types\";\nimport { buildQuery } from \"./utils/buildQuery\";\n\nexport const AIAutocomplete = forwardRef<AIAutocompleteHandle, AIAutocompleteProps>(\n function AIAutocomplete(\n {\n onSubmit,\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder,\n className,\n apiConfig,\n columns,\n typewriterEffect = true,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n },\n ref,\n ) {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n // Render-phase ref assignment — matches the pattern in useAIAutocomplete.ts\n const handleSubmitRef = useRef<(result: AutocompleteResult) => void>(() => {});\n const [revealCount, setRevealCount] = useState(0);\n const revealTimerRef = useRef<number | undefined>(undefined);\n\n useEffect(() => {\n textareaRef.current?.focus();\n return () => {\n if (revealTimerRef.current) cancelAnimationFrame(revealTimerRef.current);\n };\n }, []);\n\n const {\n completedParams,\n suggestionPills,\n setActivePill,\n segments,\n newParamId,\n clearNewParamId,\n inputProps,\n dropdownProps,\n reset,\n } = useAIAutocomplete({\n onSubmit: (result) => handleSubmitRef.current(result),\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder,\n apiConfig,\n columns,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n });\n\n // Typewriter reveal for newly added param\n useEffect(() => {\n if (revealTimerRef.current) cancelAnimationFrame(revealTimerRef.current);\n if (!newParamId) {\n setRevealCount(0);\n return;\n }\n const param = completedParams.find((p) => p.id === newParamId);\n if (!param) return;\n const totalChars = param.text.length;\n\n if (!typewriterEffect) {\n // No typewriter — reveal all at once, shimmer sweep plays via CSS animation\n setRevealCount(totalChars);\n const timeoutId = window.setTimeout(() => clearNewParamId(), 650);\n return () => window.clearTimeout(timeoutId);\n }\n\n setRevealCount(0);\n const startTime = performance.now();\n const duration = 300;\n const tick = () => {\n const elapsed = performance.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n const chars = Math.ceil(progress * totalChars);\n setRevealCount(chars);\n if (chars < totalChars) {\n revealTimerRef.current = requestAnimationFrame(tick);\n } else {\n // Defer cleanup to next frame to avoid a flash\n revealTimerRef.current = requestAnimationFrame(() => {\n clearNewParamId();\n });\n }\n };\n revealTimerRef.current = requestAnimationFrame(tick);\n return () => {\n if (revealTimerRef.current) cancelAnimationFrame(revealTimerRef.current);\n };\n }, [newParamId, completedParams, clearNewParamId, typewriterEffect]);\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => textareaRef.current?.focus(),\n reset,\n }),\n [reset],\n );\n\n const handleContainerClick = () => {\n textareaRef.current?.focus();\n };\n\n const canSubmit = !!inputProps.value || completedParams.length > 0;\n\n const handleSubmit = useCallback(() => {\n if (!canSubmit) return;\n const { rawQuery, completedParams: finalParams } = buildQuery(\n inputProps.value,\n completedParams,\n );\n onSubmit({\n query: inputProps.value.trim(),\n raw_query: rawQuery,\n completed_params: finalParams,\n });\n reset();\n }, [canSubmit, inputProps.value, completedParams, onSubmit, reset]);\n\n handleSubmitRef.current = handleSubmit;\n\n const { onChange, placeholder: inputPlaceholder, ...restProps } = inputProps;\n const isEmpty = !inputProps.value;\n\n return (\n <div className={`${styles.container} ${className ?? \"\"}`}>\n <AIAutocompleteDropdown {...dropdownProps} />\n {/* biome-ignore lint/a11y/useKeyWithClickEvents: container click delegates to textarea focus */}\n {/* biome-ignore lint/a11y/noStaticElementInteractions: wrapper delegates focus to textarea */}\n <div className={styles.inputWrapper} onClick={handleContainerClick}>\n <div className={styles.editorArea}>\n <div className={styles.sizerContent} aria-hidden=\"true\">\n {isEmpty && inputPlaceholder ? (\n <span className={styles.placeholderText}>{inputPlaceholder} </span>\n ) : (\n <span\n className={`${styles.sizerText} ${newParamId ? styles.sizerTextVisible : \"\"}`}\n >\n {segments.map((seg, i) => {\n const isNew = seg.type === \"completed\" && seg.param.id === newParamId;\n if (isNew) {\n if (!typewriterEffect) {\n // No typewriter — show all text, CSS animation handles the sweep\n const cls = `${styles.shimmerRevealed} ${styles.shimmerSweep}`;\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`} className={cls}>\n {seg.value}\n </span>\n );\n }\n const total = seg.value.length;\n const revealed = seg.value.slice(0, revealCount);\n const hidden = seg.value.slice(revealCount);\n const progress = total > 0 ? revealCount / total : 0;\n const bgPos = `${100 - progress * 100}% 0`;\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`} className={styles.shimmer}>\n <span\n className={styles.shimmerRevealed}\n style={{ backgroundPosition: bgPos }}\n >\n {revealed}\n </span>\n <span className={styles.shimmerHidden}>{hidden}</span>\n </span>\n );\n }\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`}>{seg.value}</span>\n );\n })}\n {segments.length === 0 && \"\\u00A0\"}\n </span>\n )}\n {\" \"}\n <PillList pills={suggestionPills} activePillIndex={0} onSelectPill={setActivePill} />\n </div>\n <textarea\n ref={textareaRef}\n className={`${styles.textarea} ${newParamId ? styles.textareaHidden : \"\"}`}\n rows={1}\n onChange={onChange}\n {...restProps}\n />\n </div>\n <button\n type=\"button\"\n className={styles.submitButton}\n disabled={!canSubmit}\n onClick={(e) => {\n e.stopPropagation();\n handleSubmit();\n }}\n aria-label=\"Submit\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n role=\"img\"\n aria-label=\"Submit\"\n >\n <path\n d=\"M9 14V4M9 4L4 9M9 4L14 9\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n );\n },\n);\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-cc65f4cc\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-cc65f4cc\";\n s.textContent = `.AIAutocomplete-module_container_KKjFU {\n position: relative;\n font-family: \"IBM Plex Sans\", sans-serif;\n}\n\n.AIAutocomplete-module_inputWrapper_FLq1b {\n min-height: 60px;\n padding: 24px;\n border: 1px solid var(--ac-color-border-default, #9ea5b2);\n border-radius: 23px;\n background: transparent;\n overflow: hidden;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.AIAutocomplete-module_editorArea_7rBWq {\n position: relative;\n flex: 1;\n min-width: 0;\n}\n\n.AIAutocomplete-module_sizerContent_DQgmV {\n position: relative;\n z-index: 1;\n pointer-events: none;\n min-height: 60px;\n white-space: pre-wrap;\n word-break: break-word;\n font-family: inherit;\n font-size: 19px;\n line-height: 38px;\n}\n\n.AIAutocomplete-module_sizerText_iZIMK {\n color: transparent;\n}\n\n.AIAutocomplete-module_sizerTextVisible_HR-5h {\n color: var(--ac-color-text-default, #fff);\n}\n\n.AIAutocomplete-module_textareaHidden_UayJt {\n color: transparent !important;\n}\n\n.AIAutocomplete-module_placeholderText_K3ayy {\n color: var(--ac-color-text-muted, #c1c4cb);\n opacity: 0.7;\n}\n\n.AIAutocomplete-module_textarea_eyn6A {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--ac-color-text-default, #fff);\n caret-color: var(--ac-color-text-default, #fff);\n font-family: inherit;\n font-size: 19px;\n line-height: 38px;\n white-space: pre-wrap;\n word-break: break-word;\n outline: none;\n resize: none;\n overflow: hidden;\n}\n\n.AIAutocomplete-module_textarea_eyn6A::placeholder {\n color: var(--ac-color-text-muted, #c1c4cb);\n}\n\n.AIAutocomplete-module_submitButton_sl1Mi {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: var(--ac-color-text-default, #fff);\n color: var(--ac-color-bg-default, #000);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n transition: opacity 0.2s ease;\n}\n\n.AIAutocomplete-module_submitButton_sl1Mi:hover {\n opacity: 0.85;\n}\n\n/* Text shimmer on newly added completed param.\n The sizer sits above the textarea (z-index: 1). Normally sizer text is\n transparent and the textarea shows the real text. During the shimmer, we\n make this span visible with a moving gradient clipped to the text shape,\n so the shimmer renders on top of the textarea's static white text. */\n\n.AIAutocomplete-module_shimmer_13AnY {\n position: relative;\n z-index: 2;\n display: inline;\n}\n\n.AIAutocomplete-module_shimmerRevealed_RR8dp {\n color: transparent;\n background: linear-gradient(\n 120deg,\n var(--ac-color-text-default, #fff) 0%,\n var(--ac-color-text-default, #fff) 44%,\n #b0b0b0 48%,\n #b0b0b0 52%,\n var(--ac-color-text-default, #fff) 56%,\n var(--ac-color-text-default, #fff) 100%\n );\n background-size: 200% 100%;\n -webkit-background-clip: text;\n background-clip: text;\n}\n\n.AIAutocomplete-module_shimmerSweep_ARCon {\n animation: AIAutocomplete-module_textShimmer_eCLdq 650ms ease-out forwards;\n}\n\n@keyframes AIAutocomplete-module_textShimmer_eCLdq {\n 0% {\n background-position: 100% 0;\n }\n 100% {\n background-position: -50% 0;\n }\n}\n\n.AIAutocomplete-module_shimmerHidden_45-Pf {\n color: transparent !important;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"container\":\"AIAutocomplete-module_container_KKjFU\",\"inputWrapper\":\"AIAutocomplete-module_inputWrapper_FLq1b\",\"editorArea\":\"AIAutocomplete-module_editorArea_7rBWq\",\"sizerContent\":\"AIAutocomplete-module_sizerContent_DQgmV\",\"sizerText\":\"AIAutocomplete-module_sizerText_iZIMK\",\"sizerTextVisible\":\"AIAutocomplete-module_sizerTextVisible_HR-5h\",\"textareaHidden\":\"AIAutocomplete-module_textareaHidden_UayJt\",\"placeholderText\":\"AIAutocomplete-module_placeholderText_K3ayy\",\"textarea\":\"AIAutocomplete-module_textarea_eyn6A\",\"submitButton\":\"AIAutocomplete-module_submitButton_sl1Mi\",\"shimmer\":\"AIAutocomplete-module_shimmer_13AnY\",\"shimmerRevealed\":\"AIAutocomplete-module_shimmerRevealed_RR8dp\",\"shimmerSweep\":\"AIAutocomplete-module_shimmerSweep_ARCon\",\"textShimmer\":\"AIAutocomplete-module_textShimmer_eCLdq\",\"shimmerHidden\":\"AIAutocomplete-module_shimmerHidden_45-Pf\"};","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-2eef895d\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-2eef895d\";\n s.textContent = `.AIAutocompleteDropdown-module_dropdown_yz2KC {\n position: absolute;\n left: 0;\n right: 0;\n top: 100%;\n margin-top: 6px;\n background: var(--ac-color-background-default, #0b0247);\n border-radius: 23px;\n overflow: hidden;\n z-index: 10;\n opacity: 0;\n pointer-events: none;\n transition: opacity 400ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.AIAutocompleteDropdown-module_visible_QCoXj {\n opacity: 1;\n pointer-events: auto;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"dropdown\":\"AIAutocompleteDropdown-module_dropdown_yz2KC\",\"visible\":\"AIAutocompleteDropdown-module_visible_QCoXj\"};","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-d91f2b06\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-d91f2b06\";\n s.textContent = `.SuggestionGrid-module_grid_jvaPb {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0 18px;\n padding: 18px 24px;\n max-height: 192px;\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: rgba(255, 255, 255, 0.3) transparent;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar {\n width: 6px;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 3px;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"grid\":\"SuggestionGrid-module_grid_jvaPb\"};","import { useRef, useState } from \"react\";\nimport type { SuggestionOption } from \"../types\";\nimport styles from \"./SuggestionItem.module.css\";\n\ninterface SuggestionItemProps {\n option: SuggestionOption;\n isHighlighted: boolean;\n onSelect: (option: SuggestionOption) => void;\n onHighlight: () => void;\n id: string;\n}\n\nexport function SuggestionItem({\n option,\n isHighlighted,\n onSelect,\n onHighlight,\n id,\n}: SuggestionItemProps) {\n const [pressed, setPressed] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const handleSelect = () => {\n if (!option.is_tappable || pressed) return;\n setPressed(true);\n onSelect(option);\n clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setPressed(false), 400);\n };\n\n const className = [\n styles.item,\n isHighlighted ? styles.highlighted : \"\",\n option.is_tappable ? styles.tappable : styles.nonTappable,\n pressed ? styles.pressed : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n id={id}\n role=\"option\"\n aria-selected={isHighlighted}\n className={className}\n tabIndex={option.is_tappable ? 0 : -1}\n onClick={handleSelect}\n onKeyDown={(e) => {\n if (option.is_tappable && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n handleSelect();\n }\n }}\n onMouseEnter={onHighlight}\n >\n <div className={styles.streaks} />\n <div className={styles.streaksVert} />\n <span className={styles.content}>\n {option.icon ? `${option.icon} ${option.text}` : option.text}\n {option.tag && <span className={styles.tag}>{option.tag}</span>}\n </span>\n </div>\n );\n}\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-f6bdc634\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-f6bdc634\";\n s.textContent = `.SuggestionItem-module_item_d4vpD {\n position: relative;\n overflow: visible;\n display: flex;\n align-items: center;\n font-family: \"IBM Plex Sans\", sans-serif;\n font-size: 19px;\n line-height: 30px;\n color: var(--ac-color-text-muted, #c1c4cb);\n white-space: normal;\n word-break: break-word;\n opacity: 0.35;\n border-radius: 12px;\n padding: 12px 10px;\n animation: SuggestionItem-module_fadeIn_I8u35 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes SuggestionItem-module_fadeIn_I8u35 {\n from {\n opacity: 0;\n }\n}\n\n.SuggestionItem-module_content_T-Qba {\n position: relative;\n z-index: 2;\n}\n\n.SuggestionItem-module_tappable_70KcX {\n cursor: pointer;\n}\n\n.SuggestionItem-module_tappable_70KcX:hover {\n color: var(--ac-color-text-default, #fff);\n}\n\n.SuggestionItem-module_nonTappable_xSZM- {\n cursor: default;\n opacity: 0.3;\n}\n\n.SuggestionItem-module_highlighted_Hb0SU {\n color: var(--ac-color-text-default, #fff);\n opacity: 0.5;\n}\n\n.SuggestionItem-module_tag_e3Fwe {\n font-size: 11px;\n margin-left: 6px;\n opacity: 0.5;\n}\n\n.SuggestionItem-module_pressed_98o-r {\n opacity: 0.8;\n color: var(--ac-color-text-default, #fff);\n background: rgba(255, 255, 255, 0.06);\n animation:\n SuggestionItem-module_glassFade_oyiSj 500ms ease forwards,\n SuggestionItem-module_tapDown_G3WGz 500ms ease forwards;\n}\n\n@keyframes SuggestionItem-module_tapDown_G3WGz {\n 0% {\n transform: scale(1);\n }\n 30% {\n transform: scale(0.97);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes SuggestionItem-module_glassFade_oyiSj {\n 0% {\n background: rgba(255, 255, 255, 0.1);\n }\n 100% {\n background: transparent;\n }\n}\n\n/* Border streaks — horizontal segments */\n\n.SuggestionItem-module_streaks_d9PEB {\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n border-radius: inherit;\n overflow: hidden;\n}\n\n/* Bottom horizontal: 40% from right → right corner */\n.SuggestionItem-module_streaks_d9PEB::before {\n content: \"\";\n position: absolute;\n bottom: -3px;\n left: 60%;\n width: 0;\n height: 6px;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.5) 0%,\n rgba(255, 255, 255, 0.2) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.2);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n/* Top horizontal: 40% from left → left corner */\n.SuggestionItem-module_streaks_d9PEB::after {\n content: \"\";\n position: absolute;\n top: -3px;\n right: 60%;\n width: 0;\n height: 6px;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.5) 0%,\n rgba(255, 255, 255, 0.2) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.2);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n/* Border streaks — vertical segments */\n\n.SuggestionItem-module_streaksVert_ERlV1 {\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n border-radius: inherit;\n overflow: hidden;\n}\n\n/* Right vertical: bottom-right corner → up */\n.SuggestionItem-module_streaksVert_ERlV1::before {\n content: \"\";\n position: absolute;\n bottom: 0;\n right: -3px;\n width: 6px;\n height: 0;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.4) 0%,\n rgba(255, 255, 255, 0.15) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.15);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n/* Left vertical: top-left corner → down */\n.SuggestionItem-module_streaksVert_ERlV1::after {\n content: \"\";\n position: absolute;\n top: 0;\n left: -3px;\n width: 6px;\n height: 0;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.4) 0%,\n rgba(255, 255, 255, 0.15) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.15);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaks_d9PEB::before {\n animation: SuggestionItem-module_streakHorizRight_aboGz 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaks_d9PEB::after {\n animation: SuggestionItem-module_streakHorizLeft_BreWJ 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaksVert_ERlV1::before {\n animation: SuggestionItem-module_streakVertUp_to1GD 300ms cubic-bezier(0.3, 0, 0.2, 1) 200ms forwards;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaksVert_ERlV1::after {\n animation: SuggestionItem-module_streakVertDown_OrcLh 300ms cubic-bezier(0.3, 0, 0.2, 1) 200ms forwards;\n}\n\n/* Horizontal: bottom center-ish → right edge */\n@keyframes SuggestionItem-module_streakHorizRight_aboGz {\n 0% {\n width: 0;\n height: 4px;\n opacity: 0;\n filter: blur(1px);\n box-shadow: 0 0 8px 3px rgba(255, 255, 255, 0.3);\n }\n 15% {\n height: 4px;\n opacity: 1;\n filter: blur(1px);\n box-shadow: 0 0 10px 4px rgba(255, 255, 255, 0.3);\n }\n 80% {\n width: 50%;\n height: 10px;\n opacity: 0.8;\n filter: blur(3px);\n box-shadow: 0 0 16px 6px rgba(255, 255, 255, 0.1);\n }\n 100% {\n width: 50%;\n height: 12px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 20px 8px rgba(255, 255, 255, 0.03);\n }\n}\n\n/* Horizontal: top center-ish → left edge */\n@keyframes SuggestionItem-module_streakHorizLeft_BreWJ {\n 0% {\n width: 0;\n height: 4px;\n opacity: 0;\n filter: blur(1px);\n box-shadow: 0 0 8px 3px rgba(255, 255, 255, 0.3);\n }\n 15% {\n height: 4px;\n opacity: 1;\n filter: blur(1px);\n box-shadow: 0 0 10px 4px rgba(255, 255, 255, 0.3);\n }\n 80% {\n width: 50%;\n height: 10px;\n opacity: 0.8;\n filter: blur(3px);\n box-shadow: 0 0 16px 6px rgba(255, 255, 255, 0.1);\n }\n 100% {\n width: 50%;\n height: 12px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 20px 8px rgba(255, 255, 255, 0.03);\n }\n}\n\n/* Vertical segments start matching horizontal state at 200ms handoff */\n@keyframes SuggestionItem-module_streakVertUp_to1GD {\n 0% {\n height: 0;\n width: 6px;\n opacity: 0.9;\n filter: blur(1.8px);\n box-shadow: 0 0 12px 5px rgba(255, 255, 255, 0.25);\n }\n 75% {\n height: 100%;\n width: 10px;\n opacity: 0.4;\n filter: blur(3px);\n box-shadow: 0 0 18px 8px rgba(255, 255, 255, 0.06);\n }\n 100% {\n height: 100%;\n width: 14px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 24px 10px rgba(255, 255, 255, 0.02);\n }\n}\n\n@keyframes SuggestionItem-module_streakVertDown_OrcLh {\n 0% {\n height: 0;\n width: 6px;\n opacity: 0.9;\n filter: blur(1.8px);\n box-shadow: 0 0 12px 5px rgba(255, 255, 255, 0.25);\n }\n 75% {\n height: 100%;\n width: 10px;\n opacity: 0.4;\n filter: blur(3px);\n box-shadow: 0 0 18px 8px rgba(255, 255, 255, 0.06);\n }\n 100% {\n height: 100%;\n width: 14px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 24px 10px rgba(255, 255, 255, 0.02);\n }\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"item\":\"SuggestionItem-module_item_d4vpD\",\"fadeIn\":\"SuggestionItem-module_fadeIn_I8u35\",\"content\":\"SuggestionItem-module_content_T-Qba\",\"tappable\":\"SuggestionItem-module_tappable_70KcX\",\"nonTappable\":\"SuggestionItem-module_nonTappable_xSZM-\",\"highlighted\":\"SuggestionItem-module_highlighted_Hb0SU\",\"tag\":\"SuggestionItem-module_tag_e3Fwe\",\"pressed\":\"SuggestionItem-module_pressed_98o-r\",\"glassFade\":\"SuggestionItem-module_glassFade_oyiSj\",\"tapDown\":\"SuggestionItem-module_tapDown_G3WGz\",\"streaks\":\"SuggestionItem-module_streaks_d9PEB\",\"streaksVert\":\"SuggestionItem-module_streaksVert_ERlV1\",\"streakHorizRight\":\"SuggestionItem-module_streakHorizRight_aboGz\",\"streakHorizLeft\":\"SuggestionItem-module_streakHorizLeft_BreWJ\",\"streakVertUp\":\"SuggestionItem-module_streakVertUp_to1GD\",\"streakVertDown\":\"SuggestionItem-module_streakVertDown_OrcLh\"};","import type { SuggestionOption } from \"../types\";\nimport styles from \"./SuggestionGrid.module.css\";\nimport { SuggestionItem } from \"./SuggestionItem\";\n\ninterface SuggestionGridProps {\n options: SuggestionOption[];\n activeIndex: number;\n onSelect: (option: SuggestionOption) => void;\n onHighlight: (index: number) => void;\n listboxId: string;\n}\n\nexport function SuggestionGrid({\n options,\n activeIndex,\n onSelect,\n onHighlight,\n listboxId,\n}: SuggestionGridProps) {\n return (\n <div className={styles.grid}>\n {options.map((option, i) => (\n <SuggestionItem\n key={option.text}\n option={option}\n isHighlighted={i === activeIndex}\n onSelect={onSelect}\n onHighlight={() => onHighlight(i)}\n id={`${listboxId}-option-${i}`}\n />\n ))}\n </div>\n );\n}\n","import styles from \"./AIAutocompleteDropdown.module.css\";\nimport { SuggestionGrid } from \"./components/SuggestionGrid\";\nimport type { AIAutocompleteDropdownProps } from \"./types\";\n\nexport function AIAutocompleteDropdown({\n suggestions,\n activeIndex,\n onSelect,\n onHighlight,\n isOpen,\n id,\n className,\n}: AIAutocompleteDropdownProps) {\n const activeSuggestion = suggestions[0];\n const options = activeSuggestion?.options ?? [];\n const hasOptions = isOpen && options.length > 0;\n\n return (\n <div\n id={id}\n role=\"listbox\"\n className={`${styles.dropdown} ${hasOptions ? styles.visible : \"\"} ${className ?? \"\"}`}\n onMouseDown={(e) => e.preventDefault()}\n >\n {options.length > 0 && (\n <SuggestionGrid\n options={options}\n activeIndex={activeIndex}\n onSelect={onSelect}\n onHighlight={onHighlight}\n listboxId={id}\n />\n )}\n </div>\n );\n}\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-b745b4fb\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-b745b4fb\";\n s.textContent = `.PillList-module_list_qvLqO {\n position: relative;\n z-index: 1;\n pointer-events: auto;\n display: inline-flex;\n gap: 5px;\n align-items: center;\n vertical-align: middle;\n transform: translateY(-3px);\n}\n\n.PillList-module_pill_osSyz {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 36px;\n padding: 7px 9px;\n border: none;\n border-radius: 6px;\n background: var(--ac-color-background-supportive, #313255);\n color: var(--ac-color-text-muted, #c1c4cb);\n font-family: \"IBM Plex Sans\", sans-serif;\n font-size: 19px;\n line-height: 30px;\n cursor: pointer;\n white-space: nowrap;\n animation: PillList-module_fadeIn_Aezob 400ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.PillList-module_pill_osSyz:hover {\n filter: brightness(1.2);\n}\n\n.PillList-module_active_Oll-- {\n outline: 1px solid #5a5b8a;\n}\n\n@keyframes PillList-module_fadeIn_Aezob {\n from {\n opacity: 0;\n }\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"list\":\"PillList-module_list_qvLqO\",\"pill\":\"PillList-module_pill_osSyz\",\"fadeIn\":\"PillList-module_fadeIn_Aezob\",\"active\":\"PillList-module_active_Oll--\"};","import type { Suggestion } from \"../types\";\nimport styles from \"./PillList.module.css\";\n\ninterface PillListProps {\n pills: Suggestion[];\n activePillIndex: number;\n onSelectPill: (index: number) => void;\n}\n\nfunction getPillOpacity(index: number): number {\n if (index === 0) return 0.4;\n if (index === 1) return 0.3;\n return 0.15;\n}\n\nexport function PillList({ pills, activePillIndex, onSelectPill }: PillListProps) {\n return (\n <span className={styles.list}>\n {pills.map((pill, i) => (\n <button\n key={`${pill.type}-${pill.text}`}\n type=\"button\"\n className={`${styles.pill} ${i === activePillIndex ? styles.active : \"\"}`}\n style={{ opacity: getPillOpacity(i) }}\n onClick={() => onSelectPill(i)}\n >\n {pill.text}\n </button>\n ))}\n </span>\n );\n}\n","import { type ChangeEvent, useCallback, useMemo, useRef, useState } from \"react\";\nimport type {\n CompletedParamState,\n Suggestion,\n SuggestionOption,\n UseAIAutocompleteOptions,\n UseAIAutocompleteReturn,\n} from \"../types\";\nimport { extractFilterQuery, filterOptions, findExactMatch } from \"../utils/filtering\";\nimport { deriveSegments, reconcileParams } from \"../utils/segments\";\nimport { useAutocompleteFetch, useDebouncedFetch } from \"./useAutocompleteFetch\";\nimport { useAutocompleteKeyboard } from \"./useAutocompleteKeyboard\";\nimport { useAutocompletePills } from \"./useAutocompletePills\";\n\nlet idCounter = 0;\nfunction useStableId(): string {\n const id = useRef<string | null>(null);\n if (id.current === null) {\n id.current = `:ac-${++idCounter}:`;\n }\n return id.current;\n}\n\nexport function useAIAutocomplete({\n onSubmit,\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder: customPlaceholder,\n apiConfig,\n columns = 2,\n value: controlledValue,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n}: UseAIAutocompleteOptions): UseAIAutocompleteReturn {\n // === Controlled / uncontrolled state ===\n const isTextControlled = controlledValue !== undefined;\n const isParamsControlled = controlledParams !== undefined;\n\n const [internalText, setInternalText] = useState(\"\");\n const [internalCompletedParams, setInternalCompletedParams] = useState<CompletedParamState[]>([]);\n const [suggestions, setSuggestions] = useState<Suggestion[]>([]);\n const [activeDropdownIndex, setActiveDropdownIndex] = useState(-1);\n const [newParamId, setNewParamId] = useState<string | null>(null);\n const clearNewParamId = useCallback(() => setNewParamId(null), []);\n\n const text = isTextControlled ? controlledValue : internalText;\n const completedParams = isParamsControlled ? controlledParams : internalCompletedParams;\n\n // === Refs — must be before setText/setCompletedParams which read them ===\n const onSubmitRef = useRef(onSubmit);\n onSubmitRef.current = onSubmit;\n const onChangeRef = useRef(onChangeProp);\n onChangeRef.current = onChangeProp;\n const onParamsChangeRef = useRef(onParamsChange);\n onParamsChangeRef.current = onParamsChange;\n const controlledValueRef = useRef(controlledValue);\n controlledValueRef.current = controlledValue;\n const controlledParamsRef = useRef(controlledParams);\n controlledParamsRef.current = controlledParams;\n\n // Stable setText that reads controlled value + callback via refs (no stale closures)\n const setText = useCallback(\n (value: string | ((prev: string) => string)) => {\n if (typeof value === \"function\") {\n if (isTextControlled) {\n const newVal = value(controlledValueRef.current ?? \"\");\n onChangeRef.current?.(newVal);\n } else {\n setInternalText((prev) => {\n const newVal = value(prev);\n onChangeRef.current?.(newVal);\n return newVal;\n });\n }\n } else {\n if (!isTextControlled) setInternalText(value);\n onChangeRef.current?.(value);\n }\n },\n [isTextControlled],\n );\n\n // Stable setCompletedParams — same ref pattern\n const setCompletedParams = useCallback(\n (value: CompletedParamState[] | ((prev: CompletedParamState[]) => CompletedParamState[])) => {\n if (typeof value === \"function\") {\n if (isParamsControlled) {\n const newVal = value(controlledParamsRef.current ?? []);\n onParamsChangeRef.current?.(newVal);\n } else {\n setInternalCompletedParams((prev) => {\n const newVal = value(prev);\n onParamsChangeRef.current?.(newVal);\n return newVal;\n });\n }\n } else {\n if (!isParamsControlled) setInternalCompletedParams(value);\n onParamsChangeRef.current?.(value);\n }\n },\n [isParamsControlled],\n );\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const optionOverridesRef = useRef(optionOverrides);\n optionOverridesRef.current = optionOverrides;\n const maskCompletedTextRef = useRef(maskCompletedText);\n maskCompletedTextRef.current = maskCompletedText;\n const apiConfigRef = useRef(apiConfig);\n apiConfigRef.current = apiConfig;\n const textRef = useRef(text);\n textRef.current = text;\n const suggestionsRef = useRef(suggestions);\n suggestionsRef.current = suggestions;\n const filterBaseRef = useRef(0);\n const filterInProgressRef = useRef(false);\n const pillTappedRef = useRef(false);\n const skipNextFetchRef = useRef(false);\n const listboxId = useStableId();\n\n // === Fetch ===\n const { doFetch, isLoading, error, isReady, lastRawQueryRef } = useAutocompleteFetch({\n textRef,\n suggestionsRef,\n filterBaseRef,\n filterInProgressRef,\n maskCompletedTextRef,\n apiConfigRef,\n optionOverridesRef,\n onErrorRef,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n });\n\n useDebouncedFetch({\n text,\n completedParams,\n doFetch,\n filterBaseRef,\n filterInProgressRef,\n skipNextFetchRef,\n suggestionsRef,\n lastRawQueryRef,\n });\n\n // === Derived ===\n const segments = useMemo(() => deriveSegments(text, completedParams), [text, completedParams]);\n\n filterBaseRef.current = Math.min(filterBaseRef.current, text.length);\n const filterQuery = extractFilterQuery(text, filterBaseRef.current, filterInProgressRef.current);\n\n const placeholderText = useMemo(() => {\n const serverPlaceholder = suggestions\n .filter((s) => s.type === \"placeholder\")\n .map((s) => s.text)\n .join(\" \");\n return serverPlaceholder || customPlaceholder || \"\";\n }, [suggestions, customPlaceholder]);\n const actionableSuggestions = useMemo(\n () => suggestions.filter((s) => s.type !== \"placeholder\"),\n [suggestions],\n );\n const activeSuggestion: Suggestion | undefined = actionableSuggestions[0];\n const overrideFn = activeSuggestion ? optionOverrides?.[activeSuggestion.type] : undefined;\n const baseOptions = activeSuggestion\n ? overrideFn\n ? overrideFn(filterQuery.trim())\n : (activeSuggestion.options ?? [])\n : [];\n const filteredOptions = useMemo(\n () => filterOptions(baseOptions, filterQuery),\n [baseOptions, filterQuery],\n );\n const hasPlaceholder = placeholderText.length > 0;\n const isDropdownOpen =\n !isLoading &&\n filteredOptions.length > 0 &&\n (!!text || pillTappedRef.current || !hasPlaceholder);\n\n // === Option selection ===\n const selectOption = useCallback(\n (option: SuggestionOption) => {\n if (!activeSuggestion) return;\n\n const base = filterBaseRef.current;\n let prefix = textRef.current.slice(0, base);\n\n // If input is empty and placeholder is visible, prepend placeholder\n const inputWasEmpty = prefix.length === 0 && textRef.current.length === 0;\n if (inputWasEmpty && placeholderText) {\n prefix = placeholderText + \" \";\n }\n\n if (prefix.length > 0 && !prefix.endsWith(\" \")) {\n const lastWord = prefix.split(/\\s+/).pop() ?? \"\";\n if (lastWord && option.text.toLowerCase().startsWith(lastWord.toLowerCase())) {\n prefix = prefix.slice(0, prefix.length - lastWord.length);\n }\n }\n\n const needsSpace = prefix.length > 0 && prefix[prefix.length - 1] !== \" \";\n const newText = prefix + (needsSpace ? \" \" : \"\") + option.text + \" \";\n // Capitalize the first character of the entire text when input was empty\n const finalText =\n inputWasEmpty && newText.length > 0 ? newText[0].toUpperCase() + newText.slice(1) : newText;\n // Find the option text as it appears in finalText (may be capitalized)\n const optionStart = finalText.toLowerCase().lastIndexOf(option.text.toLowerCase());\n const optionInFinal =\n optionStart >= 0\n ? finalText.slice(optionStart, optionStart + option.text.length)\n : option.text;\n\n const completed: CompletedParamState = {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: activeSuggestion.type,\n text: optionInFinal,\n kind: option.kind,\n suggestionType: activeSuggestion.type,\n suggestionPlaceholder: activeSuggestion.text,\n options: activeSuggestion.options ?? [],\n metadata: option.metadata,\n };\n setText(finalText);\n filterBaseRef.current = finalText.length;\n setCompletedParams((prev) => [...prev, completed]);\n setNewParamId(completed.id);\n pillTappedRef.current = false;\n setActiveDropdownIndex(-1);\n // Skip the debounced fetch if there are remaining cached suggestions\n const remainingActionable = actionableSuggestions.length - 1;\n if (remainingActionable > 0) {\n skipNextFetchRef.current = true;\n }\n // Delay suggestion removal so the dropdown streak animation can play\n setTimeout(() => {\n setSuggestions((prev) => prev.filter((s) => s !== activeSuggestion));\n }, 400);\n },\n [activeSuggestion, actionableSuggestions, placeholderText, setText, setCompletedParams],\n );\n\n // === Text change handler ===\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLTextAreaElement>) => {\n const raw = e.target.value;\n const shouldCapitalize =\n raw.length > 0 &&\n !(e.nativeEvent as InputEvent)?.isComposing &&\n raw[0] !== raw[0].toUpperCase();\n const newValue = shouldCapitalize ? raw[0].toUpperCase() + raw.slice(1) : raw;\n setText(newValue);\n pillTappedRef.current = false;\n setActiveDropdownIndex(-1);\n\n const { valid, invalid } = reconcileParams(newValue, completedParams);\n if (invalid.length > 0) {\n setCompletedParams(() => valid);\n for (const param of invalid) {\n setSuggestions((prev) => [\n {\n type: param.suggestionType,\n text: param.suggestionPlaceholder,\n required: true,\n options: param.options,\n },\n ...prev,\n ]);\n }\n }\n\n if (activeSuggestion && invalid.length === 0) {\n const newFilterQuery = extractFilterQuery(\n newValue,\n filterBaseRef.current,\n filterInProgressRef.current,\n );\n const match = findExactMatch(activeSuggestion.options, newFilterQuery);\n if (match) {\n setCompletedParams((prev) => [\n ...prev,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: activeSuggestion.type,\n text: match.text,\n kind: match.kind,\n suggestionType: activeSuggestion.type,\n suggestionPlaceholder: activeSuggestion.text,\n options: activeSuggestion.options ?? [],\n metadata: match.metadata,\n },\n ]);\n setSuggestions((prev) => prev.filter((s) => s !== activeSuggestion));\n }\n }\n },\n [completedParams, activeSuggestion, setText, setCompletedParams],\n );\n\n // === Pills ===\n const pills = useAutocompletePills({\n completedParams,\n suggestions,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n filterBaseRef,\n pillTappedRef,\n });\n\n const reEditParam = useCallback(\n (param: CompletedParamState) => {\n pills.reEditParam(param).apply(setText);\n },\n [pills, setText],\n );\n\n // === Keyboard ===\n const { handleKeyDown } = useAutocompleteKeyboard({\n activeDropdownIndex,\n setActiveDropdownIndex,\n filteredOptions,\n selectOption,\n onSubmitRef,\n text,\n completedParams,\n isDropdownOpen,\n hasPlaceholder,\n placeholderText,\n suggestions,\n actionableSuggestions,\n setActivePill: pills.setActivePill,\n listboxId,\n pillTappedRef,\n filterBaseRef,\n columns,\n setText,\n setCompletedParams,\n setSuggestions,\n });\n\n // === Reset ===\n const reset = useCallback(() => {\n setText(\"\");\n setCompletedParams(() => []);\n setSuggestions([]);\n setActiveDropdownIndex(-1);\n filterBaseRef.current = 0;\n filterInProgressRef.current = false;\n lastRawQueryRef.current = \"\";\n doFetch(\"\", []);\n }, [doFetch, setText, setCompletedParams, lastRawQueryRef]);\n\n const activeDescendantId =\n activeDropdownIndex >= 0 ? `${listboxId}-option-${activeDropdownIndex}` : undefined;\n\n return {\n completedParams,\n suggestionPills: actionableSuggestions,\n setActivePill: pills.setActivePill,\n removeLastParam: pills.removeLastParam,\n reEditParam,\n segments,\n newParamId,\n clearNewParamId,\n suggestions,\n activeIndex: activeDropdownIndex,\n isReady,\n isLoading,\n error,\n inputProps: {\n value: text,\n placeholder: placeholderText || undefined,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n role: \"combobox\" as const,\n \"aria-expanded\": isDropdownOpen,\n \"aria-activedescendant\": activeDescendantId,\n \"aria-autocomplete\": \"list\" as const,\n \"aria-controls\": listboxId,\n },\n reset,\n dropdownProps: {\n suggestions: activeSuggestion ? [{ ...activeSuggestion, options: filteredOptions }] : [],\n activeIndex: activeDropdownIndex,\n onSelect: selectOption,\n onHighlight: setActiveDropdownIndex,\n isOpen: isDropdownOpen,\n id: listboxId,\n },\n };\n}\n","import type { SuggestionOption } from \"../types\";\n\n/**\n * Extracts the effective filter query from the region after filterBase.\n * If the server marked the region as in_progress, the full region is used.\n * Otherwise, filtering only starts after the first space (to avoid filtering\n * mid-word when the user continues typing a word that was already in the input).\n */\nexport function extractFilterQuery(\n text: string,\n filterBase: number,\n isInProgress: boolean,\n): string {\n const rawRegion = text.slice(filterBase);\n if (isInProgress || filterBase === 0 || text[filterBase - 1] === \" \") {\n return rawRegion;\n }\n const spaceIdx = rawRegion.indexOf(\" \");\n return spaceIdx === -1 ? \"\" : rawRegion.slice(spaceIdx + 1);\n}\n\n/**\n * Filters options using partial substring match on the text after the last completed param.\n */\nexport function filterOptions(\n options: SuggestionOption[] | undefined,\n query: string,\n): SuggestionOption[] {\n if (!options) return [];\n const trimmed = query.trimStart();\n if (!trimmed) return options;\n const lower = trimmed.toLowerCase();\n return options.filter((o) => !o.is_tappable || o.text.toLowerCase().includes(lower));\n}\n\n/**\n * Finds an exact match for the trimmed filter query against options.\n */\nexport function findExactMatch(\n options: SuggestionOption[] | undefined,\n query: string,\n): SuggestionOption | null {\n if (!options) return null;\n const trimmed = query.trim();\n if (!trimmed) return null;\n const lower = trimmed.toLowerCase();\n return options.find((o) => o.is_tappable && o.text.toLowerCase() === lower) ?? null;\n}\n","import type { CompletedParamState, Segment } from \"../types\";\n\n/**\n * Derives segments for overlay rendering by matching completed params in text.\n */\nexport function deriveSegments(text: string, completedParams: CompletedParamState[]): Segment[] {\n const result: Segment[] = [];\n let pos = 0;\n\n for (const param of completedParams) {\n const idx = text.indexOf(param.text, pos);\n if (idx === -1) continue;\n if (idx > pos) {\n result.push({ type: \"text\", value: text.slice(pos, idx) });\n }\n result.push({ type: \"completed\", value: param.text, param });\n pos = idx + param.text.length;\n }\n\n const remaining = text.slice(pos);\n if (remaining) {\n result.push({ type: \"text\", value: remaining });\n }\n\n return result;\n}\n\n/**\n * Checks which completed params still exist in the new text.\n */\nexport function reconcileParams(\n text: string,\n completedParams: CompletedParamState[],\n): { valid: CompletedParamState[]; invalid: CompletedParamState[] } {\n const valid: CompletedParamState[] = [];\n const invalid: CompletedParamState[] = [];\n let pos = 0;\n\n for (const param of completedParams) {\n const idx = text.indexOf(param.text, pos);\n if (idx === -1) {\n invalid.push(param);\n } else {\n valid.push(param);\n pos = idx + param.text.length;\n }\n }\n\n return { valid, invalid };\n}\n","import { type MutableRefObject, useCallback, useEffect, useRef, useState } from \"react\";\nimport type {\n APIConfig,\n CompletedParamState,\n OptionOverrides,\n Suggestion,\n SuggestionOption,\n} from \"../types\";\nimport { fetchSuggestions } from \"../utils/api\";\nimport { buildQuery } from \"../utils/buildQuery\";\nimport { extractFilterQuery, filterOptions, findExactMatch } from \"../utils/filtering\";\nimport { applyOptionOverrides } from \"../utils/overrides\";\n\nconst DEBOUNCE_MS = 100;\nconst SLOW_DEBOUNCE_MS = 300;\nconst MIN_CHARS_DIFF = 2;\n\ninterface UseAutocompleteFetchOptions {\n textRef: MutableRefObject<string>;\n suggestionsRef: MutableRefObject<Suggestion[]>;\n filterBaseRef: MutableRefObject<number>;\n filterInProgressRef: MutableRefObject<boolean>;\n maskCompletedTextRef: MutableRefObject<boolean | undefined>;\n apiConfigRef: MutableRefObject<APIConfig | undefined>;\n optionOverridesRef: MutableRefObject<OptionOverrides | undefined>;\n onErrorRef: MutableRefObject<((error: Error) => void) | undefined>;\n setCompletedParams: (fn: (prev: CompletedParamState[]) => CompletedParamState[]) => void;\n setSuggestions: (fn: Suggestion[] | ((prev: Suggestion[]) => Suggestion[])) => void;\n setActiveDropdownIndex: (index: number) => void;\n}\n\ninterface UseAutocompleteFetchReturn {\n doFetch: (rawQuery: string, completed: CompletedParamState[]) => Promise<void>;\n isLoading: boolean;\n error: Error | null;\n isReady: boolean;\n lastRawQueryRef: MutableRefObject<string>;\n}\n\nexport function useAutocompleteFetch({\n textRef,\n suggestionsRef,\n filterBaseRef,\n filterInProgressRef,\n maskCompletedTextRef,\n apiConfigRef,\n optionOverridesRef,\n onErrorRef,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n}: UseAutocompleteFetchOptions): UseAutocompleteFetchReturn {\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [isReady, setIsReady] = useState(false);\n const fetchVersionRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n const lastRawQueryRef = useRef(\"\");\n\n const doFetch = useCallback(\n async (rawQuery: string, completed: CompletedParamState[]) => {\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n const version = ++fetchVersionRef.current;\n const textAtRequest = textRef.current.length;\n\n const hasSuggestions = suggestionsRef.current.some((s) => s.type !== \"placeholder\");\n if (!hasSuggestions) setIsLoading(true);\n setError(null);\n try {\n const res = await fetchSuggestions(rawQuery, completed, {\n maskCompletedText: maskCompletedTextRef.current,\n signal: controller.signal,\n apiConfig: apiConfigRef.current,\n });\n\n if (version !== fetchVersionRef.current) return;\n\n let newSuggestions = applyOptionOverrides(\n res.data.suggestions ?? [],\n optionOverridesRef.current,\n );\n setIsReady(res.data.is_ready ?? false);\n lastRawQueryRef.current = rawQuery;\n\n const input = res.data.input ?? [];\n const lastInput = input[input.length - 1];\n const currentText = textRef.current;\n if (lastInput?.state === \"in_progress\") {\n filterInProgressRef.current = true;\n const inProgressIdx = currentText.toLowerCase().lastIndexOf(lastInput.text.toLowerCase());\n if (inProgressIdx !== -1) {\n filterBaseRef.current = inProgressIdx;\n } else {\n filterBaseRef.current = textAtRequest;\n }\n } else {\n filterInProgressRef.current = false;\n filterBaseRef.current = textAtRequest;\n }\n\n // Check if the user already typed an exact match while waiting\n const actionable = newSuggestions.filter((s) => s.type !== \"placeholder\");\n const active = actionable[0];\n if (active) {\n const query = extractFilterQuery(\n currentText,\n filterBaseRef.current,\n filterInProgressRef.current,\n );\n const match = findExactMatch(active.options, query);\n if (match) {\n setCompletedParams((prev) => [\n ...prev,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: active.type,\n text: match.text,\n kind: match.kind,\n suggestionType: active.type,\n suggestionPlaceholder: active.text,\n options: active.options ?? [],\n metadata: match.metadata,\n },\n ]);\n newSuggestions = newSuggestions.filter((s) => s !== active);\n }\n }\n\n setSuggestions(newSuggestions);\n setIsLoading(false);\n setActiveDropdownIndex(-1);\n } catch (err) {\n if (version === fetchVersionRef.current) {\n const caughtError = err instanceof Error ? err : new Error(String(err));\n setError(caughtError);\n setIsLoading(false);\n onErrorRef.current?.(caughtError);\n }\n }\n },\n [\n textRef,\n suggestionsRef,\n filterBaseRef,\n filterInProgressRef,\n maskCompletedTextRef,\n apiConfigRef,\n optionOverridesRef,\n onErrorRef,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n ],\n );\n\n // Mount fetch\n useEffect(() => {\n doFetch(\"\", []);\n return () => {\n abortRef.current?.abort();\n };\n }, [doFetch]);\n\n return { doFetch, isLoading, error, isReady, lastRawQueryRef };\n}\n\ninterface UseDebouncedFetchOptions {\n text: string;\n completedParams: CompletedParamState[];\n doFetch: (rawQuery: string, completed: CompletedParamState[]) => Promise<void>;\n filterBaseRef: MutableRefObject<number>;\n filterInProgressRef: MutableRefObject<boolean>;\n skipNextFetchRef: MutableRefObject<boolean>;\n suggestionsRef: MutableRefObject<Suggestion[]>;\n lastRawQueryRef: MutableRefObject<string>;\n}\n\nexport function useDebouncedFetch({\n text,\n completedParams,\n doFetch,\n filterBaseRef,\n filterInProgressRef,\n skipNextFetchRef,\n suggestionsRef,\n lastRawQueryRef,\n}: UseDebouncedFetchOptions): void {\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const slowDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const hasFetchedRef = useRef(true);\n\n useEffect(() => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (slowDebounceRef.current) clearTimeout(slowDebounceRef.current);\n\n if (skipNextFetchRef.current) {\n skipNextFetchRef.current = false;\n return;\n }\n\n const attemptFetch = (minDiff: number): boolean => {\n if (!text && completedParams.length === 0) {\n if (!hasFetchedRef.current) {\n hasFetchedRef.current = true;\n return false;\n }\n doFetch(\"\", []);\n return true;\n }\n\n const currentQuery = extractFilterQuery(\n text,\n filterBaseRef.current,\n filterInProgressRef.current,\n );\n const currentSuggestions = suggestionsRef.current;\n const actionable = currentSuggestions.filter((s: Suggestion) => s.type !== \"placeholder\");\n const active = actionable[0];\n const currentFiltered = active ? filterOptions(active.options, currentQuery) : [];\n const tappableFiltered = currentFiltered.filter((o: SuggestionOption) => o.is_tappable);\n const hasExactMatch = active ? findExactMatch(active.options, currentQuery) !== null : false;\n\n const isInFilterZone = currentQuery.trim().length > 0;\n if (tappableFiltered.length > 0 && !hasExactMatch && isInFilterZone) return false;\n\n const { rawQuery, completedParams: updatedParams } = buildQuery(text, completedParams);\n const isDeleting = rawQuery.length < lastRawQueryRef.current.length;\n const charDiff = Math.abs(rawQuery.length - lastRawQueryRef.current.length);\n if (isDeleting || charDiff >= minDiff) {\n doFetch(rawQuery, updatedParams);\n return true;\n }\n return false;\n };\n\n debounceRef.current = setTimeout(() => {\n if (attemptFetch(MIN_CHARS_DIFF)) {\n if (slowDebounceRef.current) clearTimeout(slowDebounceRef.current);\n }\n }, DEBOUNCE_MS);\n\n slowDebounceRef.current = setTimeout(() => attemptFetch(1), SLOW_DEBOUNCE_MS);\n\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (slowDebounceRef.current) clearTimeout(slowDebounceRef.current);\n };\n }, [\n text,\n completedParams,\n doFetch,\n filterBaseRef,\n filterInProgressRef,\n skipNextFetchRef,\n suggestionsRef,\n lastRawQueryRef,\n ]);\n}\n","import type {\n APIConfig,\n AutocompleteRequest,\n AutocompleteResponse,\n CompletedParam,\n CompletedParamState,\n} from \"../types\";\n\n// Replaced at build time by tsup/vitest `define` config with the package.json version.\ndeclare const __SDK_VERSION__: string;\nconst SDK_VERSION = __SDK_VERSION__;\n\nlet hasWarnedMissingKey = false;\n\nfunction generateRequestId(): string {\n return crypto.randomUUID();\n}\n\nfunction toWireParam(param: CompletedParamState, includeText: boolean): CompletedParam {\n return {\n placeholder: param.placeholder,\n type: param.type,\n ...(includeText && { text: param.text }),\n kind: param.kind,\n };\n}\n\nexport async function fetchSuggestions(\n rawQuery: string,\n completedParams: CompletedParamState[],\n options?: {\n maskCompletedText?: boolean;\n signal?: AbortSignal;\n apiConfig?: APIConfig;\n },\n): Promise<AutocompleteResponse> {\n const apiConfig = options?.apiConfig;\n const apiKey = apiConfig?.apiKey ?? \"\";\n if (!apiKey && !hasWarnedMissingKey) {\n hasWarnedMissingKey = true;\n // biome-ignore lint/suspicious/noConsole: intentional dev warning\n console.warn(\n \"[AIAutocomplete] No apiKey in apiConfig. Requests will be sent without an Authorization header.\",\n );\n }\n const authScheme = apiConfig?.authScheme ?? \"Bearer\";\n const includeText = !options?.maskCompletedText;\n\n const rawCount = completedParams.find(\n (p) => p.type === \"contact\" && p.metadata?.contact_account_count,\n )?.metadata?.contact_account_count;\n const contactAccountCount = typeof rawCount === \"number\" ? rawCount : undefined;\n\n const body: AutocompleteRequest = {\n data: {\n raw_query: rawQuery,\n completed_params: completedParams.map((p) => toWireParam(p, includeText)),\n ...(contactAccountCount != null && { contact_account_count: contactAccountCount }),\n },\n meta: {\n request_id: generateRequestId(),\n request_at: new Date().toISOString(),\n language: typeof navigator !== \"undefined\" ? navigator.language : \"en-US\",\n client_version: SDK_VERSION,\n },\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(apiConfig?.appIdentifier && { \"X-App-Identifier\": apiConfig.appIdentifier }),\n ...apiConfig?.headers,\n };\n if (apiKey) {\n headers.Authorization = authScheme === \"Basic\" ? `Basic ${btoa(apiKey)}` : `Bearer ${apiKey}`;\n }\n\n const response = await fetch(apiConfig?.endpoint ?? \"/ac/suggest\", {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n });\n\n if (!response.ok) {\n throw new Error(`API error: ${response.status} ${response.statusText}`);\n }\n\n return response.json() as Promise<AutocompleteResponse>;\n}\n","import type { CompletedParamState } from \"../types\";\n\ninterface BuildQueryResult {\n rawQuery: string;\n completedParams: CompletedParamState[];\n}\n\n/**\n * Takes the raw input text and completed params (without placeholders),\n * replaces each completed param's text in the string with a {{TYPE_N}} token,\n * and returns the transformed query + params with placeholders filled in.\n *\n * Replacements happen left-to-right, first occurrence only per param.\n * Counter is per-type (e.g. {{TASK_1}}, {{GOAL_1}}, {{GOAL_2}}).\n */\nexport function buildQuery(text: string, completedParams: CompletedParamState[]): BuildQueryResult {\n let result = text;\n const typeCounts: Record<string, number> = {};\n const updatedParams: CompletedParamState[] = [];\n\n for (const param of completedParams) {\n const count = (typeCounts[param.type] ?? 0) + 1;\n typeCounts[param.type] = count;\n\n const typeKey = param.type.toUpperCase().replace(/\\s+/g, \"_\");\n const placeholder = `{{${typeKey}_${count}}}`;\n\n // Replace first occurrence of the param text in the string\n const index = result.indexOf(param.text);\n if (index !== -1) {\n result = result.slice(0, index) + placeholder + result.slice(index + param.text.length);\n }\n\n updatedParams.push({ ...param, placeholder });\n }\n\n return { rawQuery: result, completedParams: updatedParams };\n}\n","import type { Suggestion, SuggestionOption } from \"../types\";\n\n/**\n * Applies option overrides by calling the override function with an empty query,\n * then prepending results to suggestions that match by type, deduplicating by text.\n */\nexport function applyOptionOverrides(\n suggestions: Suggestion[],\n overrides?: Record<string, (query: string) => SuggestionOption[]>,\n): Suggestion[] {\n if (!overrides) return suggestions;\n return suggestions.map((s) => {\n const fn = overrides[s.type];\n if (!fn) return s;\n const extra = fn(\"\");\n if (extra.length === 0) return s;\n const existingTexts = new Set(extra.map((o) => o.text));\n const deduped = (s.options ?? []).filter((o) => !existingTexts.has(o.text));\n return { ...s, options: [...extra, ...deduped] };\n });\n}\n","import { type KeyboardEvent, type MutableRefObject, useCallback } from \"react\";\nimport type {\n AutocompleteResult,\n CompletedParamState,\n Suggestion,\n SuggestionOption,\n} from \"../types\";\nimport { buildQuery } from \"../utils/buildQuery\";\n\ninterface UseAutocompleteKeyboardOptions {\n activeDropdownIndex: number;\n setActiveDropdownIndex: (index: number) => void;\n filteredOptions: SuggestionOption[];\n selectOption: (option: SuggestionOption) => void;\n onSubmitRef: MutableRefObject<((result: AutocompleteResult) => void) | undefined>;\n text: string;\n completedParams: CompletedParamState[];\n isDropdownOpen: boolean;\n hasPlaceholder: boolean;\n placeholderText: string;\n suggestions: Suggestion[];\n actionableSuggestions: Suggestion[];\n setActivePill: (index: number) => void;\n listboxId: string;\n pillTappedRef: MutableRefObject<boolean>;\n filterBaseRef: MutableRefObject<number>;\n columns: number;\n setText: (value: string) => void;\n setCompletedParams: (fn: (prev: CompletedParamState[]) => CompletedParamState[]) => void;\n setSuggestions: (fn: (prev: Suggestion[]) => Suggestion[]) => void;\n}\n\nexport function useAutocompleteKeyboard({\n activeDropdownIndex,\n setActiveDropdownIndex,\n filteredOptions,\n selectOption,\n onSubmitRef,\n text,\n completedParams,\n isDropdownOpen,\n hasPlaceholder,\n placeholderText,\n suggestions,\n actionableSuggestions,\n setActivePill,\n listboxId,\n pillTappedRef,\n filterBaseRef,\n columns,\n setText,\n setCompletedParams,\n setSuggestions,\n}: UseAutocompleteKeyboardOptions) {\n const getTappableIndices = useCallback(() => {\n const tappable = filteredOptions\n .map((o, i) => (o.is_tappable ? i : -1))\n .filter((i) => i !== -1);\n // Column-first ordering: all column-0 items, then column-1, etc.\n const buckets: number[][] = Array.from({ length: columns }, () => []);\n for (const i of tappable) buckets[i % columns].push(i);\n return buckets.flat();\n }, [filteredOptions, columns]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n const tappableIndices = getTappableIndices();\n\n switch (e.key) {\n case \"ArrowDown\": {\n // Only navigate dropdown if cursor is at the end of the input\n const target = e.target as HTMLTextAreaElement;\n const cursorAtEnd =\n target.selectionStart != null && target.selectionStart === target.value.length;\n if (!cursorAtEnd && activeDropdownIndex < 0) break;\n\n e.preventDefault();\n // If dropdown is closed but there are options available, open it and select the first option\n if (!isDropdownOpen && actionableSuggestions.length > 0) {\n pillTappedRef.current = true;\n const firstTappable = tappableIndices[0];\n setActiveDropdownIndex(firstTappable ?? 0);\n break;\n }\n if (tappableIndices.length === 0) return;\n const currentPos = tappableIndices.indexOf(activeDropdownIndex);\n const nextPos = currentPos < tappableIndices.length - 1 ? currentPos + 1 : 0;\n setActiveDropdownIndex(tappableIndices[nextPos]);\n break;\n }\n case \"ArrowUp\": {\n if (tappableIndices.length === 0 || activeDropdownIndex < 0) break;\n e.preventDefault();\n // If on the first row, deselect and return focus to the input\n const isFirstRow = activeDropdownIndex < columns;\n if (isFirstRow) {\n setActiveDropdownIndex(-1);\n break;\n }\n const currentPos = tappableIndices.indexOf(activeDropdownIndex);\n const prevPos = currentPos > 0 ? currentPos - 1 : tappableIndices.length - 1;\n setActiveDropdownIndex(tappableIndices[prevPos]);\n break;\n }\n case \"ArrowRight\": {\n if (activeDropdownIndex < 0) {\n // Only cycle pills if the cursor is at the end of the input\n const target = e.target as HTMLTextAreaElement;\n const atEnd =\n target.selectionStart != null && target.selectionStart === target.value.length;\n if (atEnd && actionableSuggestions.length > 1) {\n e.preventDefault();\n setActivePill(1);\n }\n break;\n }\n const col = activeDropdownIndex % columns;\n if (col < columns - 1) {\n const rightNeighbor = activeDropdownIndex + 1;\n if (\n rightNeighbor < filteredOptions.length &&\n filteredOptions[rightNeighbor]?.is_tappable\n ) {\n e.preventDefault();\n setActiveDropdownIndex(rightNeighbor);\n }\n }\n break;\n }\n case \"ArrowLeft\": {\n if (activeDropdownIndex < 0) break;\n if (activeDropdownIndex % columns > 0) {\n const leftNeighbor = activeDropdownIndex - 1;\n if (leftNeighbor >= 0 && filteredOptions[leftNeighbor]?.is_tappable) {\n e.preventDefault();\n setActiveDropdownIndex(leftNeighbor);\n }\n }\n break;\n }\n case \"Enter\": {\n e.preventDefault();\n if (activeDropdownIndex >= 0 && filteredOptions[activeDropdownIndex]?.is_tappable) {\n const optionEl = document.getElementById(`${listboxId}-option-${activeDropdownIndex}`);\n if (optionEl) {\n optionEl.click();\n } else {\n selectOption(filteredOptions[activeDropdownIndex]);\n }\n } else if (onSubmitRef.current) {\n const { rawQuery, completedParams: finalParams } = buildQuery(text, completedParams);\n const result: AutocompleteResult = {\n query: text.trim(),\n raw_query: rawQuery,\n completed_params: finalParams,\n };\n onSubmitRef.current(result);\n }\n break;\n }\n case \"Tab\": {\n if (activeDropdownIndex >= 0 && filteredOptions[activeDropdownIndex]?.is_tappable) {\n e.preventDefault();\n const optionEl = document.getElementById(`${listboxId}-option-${activeDropdownIndex}`);\n if (optionEl) {\n optionEl.click();\n } else {\n selectOption(filteredOptions[activeDropdownIndex]);\n }\n } else if (isDropdownOpen) {\n const firstTappableIdx = filteredOptions.findIndex((o) => o.is_tappable);\n if (firstTappableIdx >= 0) {\n e.preventDefault();\n const optionEl = document.getElementById(`${listboxId}-option-${firstTappableIdx}`);\n if (optionEl) {\n optionEl.click();\n } else {\n selectOption(filteredOptions[firstTappableIdx]);\n }\n }\n } else if (!text && hasPlaceholder) {\n e.preventDefault();\n const placeholderSuggestion = suggestions.find((s) => s.type === \"placeholder\");\n if (placeholderSuggestion) {\n setText(placeholderText);\n filterBaseRef.current = placeholderText.length;\n setCompletedParams((prev) => [\n ...prev,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: placeholderSuggestion.type,\n text: placeholderText,\n kind: null,\n suggestionType: placeholderSuggestion.type,\n suggestionPlaceholder: placeholderSuggestion.text,\n options: placeholderSuggestion.options ?? [],\n },\n ]);\n setSuggestions((prev) => prev.filter((s) => s !== placeholderSuggestion));\n } else {\n setText(placeholderText);\n filterBaseRef.current = placeholderText.length;\n }\n }\n break;\n }\n case \"Escape\":\n setActiveDropdownIndex(-1);\n break;\n }\n },\n [\n actionableSuggestions,\n activeDropdownIndex,\n columns,\n completedParams,\n filteredOptions,\n filterBaseRef,\n getTappableIndices,\n hasPlaceholder,\n listboxId,\n pillTappedRef,\n isDropdownOpen,\n onSubmitRef,\n placeholderText,\n selectOption,\n setActiveDropdownIndex,\n setActivePill,\n setCompletedParams,\n setSuggestions,\n setText,\n suggestions,\n text,\n ],\n );\n\n return { handleKeyDown, getTappableIndices };\n}\n","import { type MutableRefObject, useCallback } from \"react\";\nimport type { CompletedParamState, Suggestion } from \"../types\";\n\ninterface UseAutocompletePillsOptions {\n completedParams: CompletedParamState[];\n suggestions: Suggestion[];\n setCompletedParams: (fn: (prev: CompletedParamState[]) => CompletedParamState[]) => void;\n setSuggestions: (fn: Suggestion[] | ((prev: Suggestion[]) => Suggestion[])) => void;\n setActiveDropdownIndex: (index: number) => void;\n filterBaseRef: MutableRefObject<number>;\n pillTappedRef: MutableRefObject<boolean>;\n}\n\nexport function useAutocompletePills({\n completedParams,\n suggestions,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n filterBaseRef,\n pillTappedRef,\n}: UseAutocompletePillsOptions) {\n const setActivePill = useCallback(\n (index: number) => {\n const actionable = suggestions.filter((s) => s.type !== \"placeholder\");\n if (index < 0 || index >= actionable.length) return;\n const moved = actionable[index];\n const rest = actionable.filter((_, i) => i !== index);\n const placeholders = suggestions.filter((s) => s.type === \"placeholder\");\n setSuggestions([...placeholders, moved, ...rest]);\n pillTappedRef.current = true;\n setActiveDropdownIndex(-1);\n },\n [suggestions, setSuggestions, setActiveDropdownIndex, pillTappedRef],\n );\n\n const removeLastParam = useCallback(() => {\n if (completedParams.length === 0) return;\n const lastParam = completedParams[completedParams.length - 1];\n const restoredSuggestion: Suggestion = {\n type: lastParam.suggestionType,\n text: lastParam.suggestionPlaceholder,\n required: true,\n options: lastParam.options,\n };\n setCompletedParams((prev) => prev.slice(0, -1));\n setSuggestions((prev: Suggestion[]) => [restoredSuggestion, ...prev]);\n setActiveDropdownIndex(-1);\n }, [completedParams, setCompletedParams, setSuggestions, setActiveDropdownIndex]);\n\n const reEditParam = useCallback(\n (param: CompletedParamState) => {\n const restoredSuggestion: Suggestion = {\n type: param.suggestionType,\n text: param.suggestionPlaceholder,\n required: true,\n options: param.options,\n };\n return {\n apply: (setText: (fn: (prev: string) => string) => void) => {\n setText((prev) => {\n let pos = 0;\n for (const p of completedParams) {\n const idx = prev.indexOf(p.text, pos);\n if (idx === -1) continue;\n if (p.id === param.id) {\n const before = prev.slice(0, idx);\n const after = prev.slice(idx + param.text.length);\n const cleaned = (before + after).replace(/ {2,}/g, \" \");\n filterBaseRef.current = Math.min(filterBaseRef.current, cleaned.length);\n return cleaned;\n }\n pos = idx + p.text.length;\n }\n return prev;\n });\n setCompletedParams((prev) => prev.filter((p) => p.id !== param.id));\n setSuggestions((prev: Suggestion[]) => [restoredSuggestion, ...prev]);\n setActiveDropdownIndex(-1);\n pillTappedRef.current = true;\n },\n };\n },\n [\n completedParams,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n filterBaseRef,\n pillTappedRef,\n ],\n );\n\n return { setActivePill, removeLastParam, reEditParam };\n}\n"],"mappings":"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","names":["index_exports","__export","AIAutocomplete","AIAutocompleteDropdown","useAIAutocomplete","__toCommonJS","import_react","s","AIAutocomplete_module_css_default","s","AIAutocompleteDropdown_module_css_default","s","SuggestionGrid_module_css_default","import_react","s","SuggestionItem_module_css_default","import_jsx_runtime","SuggestionItem","option","isHighlighted","onSelect","onHighlight","id","pressed","setPressed","timerRef","handleSelect","className","SuggestionItem_module_css_default","e","import_jsx_runtime","SuggestionGrid","options","activeIndex","onSelect","onHighlight","listboxId","SuggestionGrid_module_css_default","option","i","SuggestionItem","import_jsx_runtime","AIAutocompleteDropdown","suggestions","activeIndex","onSelect","onHighlight","isOpen","id","className","options","hasOptions","AIAutocompleteDropdown_module_css_default","e","SuggestionGrid","s","PillList_module_css_default","import_jsx_runtime","getPillOpacity","index","PillList","pills","activePillIndex","onSelectPill","PillList_module_css_default","pill","i","import_react","extractFilterQuery","text","filterBase","isInProgress","rawRegion","spaceIdx","filterOptions","options","query","trimmed","lower","o","findExactMatch","deriveSegments","text","completedParams","result","pos","param","idx","remaining","reconcileParams","valid","invalid","import_react","SDK_VERSION","hasWarnedMissingKey","generateRequestId","toWireParam","param","includeText","fetchSuggestions","rawQuery","completedParams","options","apiConfig","apiKey","authScheme","rawCount","p","contactAccountCount","body","headers","response","buildQuery","text","completedParams","result","typeCounts","updatedParams","param","count","placeholder","index","applyOptionOverrides","suggestions","overrides","s","fn","extra","existingTexts","o","deduped","DEBOUNCE_MS","SLOW_DEBOUNCE_MS","MIN_CHARS_DIFF","useAutocompleteFetch","textRef","suggestionsRef","filterBaseRef","filterInProgressRef","maskCompletedTextRef","apiConfigRef","optionOverridesRef","onErrorRef","setCompletedParams","setSuggestions","setActiveDropdownIndex","isLoading","setIsLoading","error","setError","isReady","setIsReady","fetchVersionRef","abortRef","lastRawQueryRef","doFetch","rawQuery","completed","controller","version","textAtRequest","s","res","fetchSuggestions","newSuggestions","applyOptionOverrides","input","lastInput","currentText","inProgressIdx","active","query","extractFilterQuery","match","findExactMatch","prev","err","caughtError","useDebouncedFetch","text","completedParams","skipNextFetchRef","debounceRef","slowDebounceRef","hasFetchedRef","attemptFetch","minDiff","currentQuery","tappableFiltered","filterOptions","o","hasExactMatch","isInFilterZone","updatedParams","buildQuery","isDeleting","charDiff","import_react","useAutocompleteKeyboard","activeDropdownIndex","setActiveDropdownIndex","filteredOptions","selectOption","onSubmitRef","text","completedParams","isDropdownOpen","hasPlaceholder","placeholderText","suggestions","actionableSuggestions","setActivePill","listboxId","pillTappedRef","filterBaseRef","columns","setText","setCompletedParams","setSuggestions","getTappableIndices","tappable","o","i","buckets","e","tappableIndices","target","firstTappable","currentPos","nextPos","prevPos","rightNeighbor","leftNeighbor","optionEl","rawQuery","finalParams","buildQuery","result","firstTappableIdx","placeholderSuggestion","prev","s","import_react","useAutocompletePills","completedParams","suggestions","setCompletedParams","setSuggestions","setActiveDropdownIndex","filterBaseRef","pillTappedRef","setActivePill","index","actionable","s","moved","rest","_","i","placeholders","removeLastParam","lastParam","restoredSuggestion","prev","reEditParam","param","setText","pos","p","idx","before","after","cleaned","idCounter","useStableId","id","useAIAutocomplete","onSubmit","onError","optionOverrides","maskCompletedText","customPlaceholder","apiConfig","columns","controlledValue","controlledParams","onChangeProp","onParamsChange","isTextControlled","isParamsControlled","internalText","setInternalText","internalCompletedParams","setInternalCompletedParams","suggestions","setSuggestions","activeDropdownIndex","setActiveDropdownIndex","newParamId","setNewParamId","clearNewParamId","text","completedParams","onSubmitRef","onChangeRef","onParamsChangeRef","controlledValueRef","controlledParamsRef","setText","value","newVal","prev","setCompletedParams","onErrorRef","optionOverridesRef","maskCompletedTextRef","apiConfigRef","textRef","suggestionsRef","filterBaseRef","filterInProgressRef","pillTappedRef","skipNextFetchRef","listboxId","doFetch","isLoading","error","isReady","lastRawQueryRef","useAutocompleteFetch","useDebouncedFetch","segments","deriveSegments","filterQuery","extractFilterQuery","placeholderText","s","actionableSuggestions","activeSuggestion","overrideFn","baseOptions","filteredOptions","filterOptions","hasPlaceholder","isDropdownOpen","selectOption","option","base","prefix","inputWasEmpty","lastWord","needsSpace","newText","finalText","optionStart","optionInFinal","completed","handleChange","e","raw","newValue","valid","invalid","reconcileParams","param","newFilterQuery","match","findExactMatch","pills","useAutocompletePills","reEditParam","handleKeyDown","useAutocompleteKeyboard","reset","activeDescendantId","import_jsx_runtime","AIAutocomplete","onSubmit","onError","optionOverrides","maskCompletedText","placeholder","className","apiConfig","columns","typewriterEffect","value","controlledParams","onChangeProp","onParamsChange","ref","textareaRef","handleSubmitRef","revealCount","setRevealCount","revealTimerRef","completedParams","suggestionPills","setActivePill","segments","newParamId","clearNewParamId","inputProps","dropdownProps","reset","useAIAutocomplete","result","param","p","totalChars","timeoutId","startTime","duration","tick","elapsed","progress","chars","handleContainerClick","canSubmit","handleSubmit","rawQuery","finalParams","buildQuery","onChange","inputPlaceholder","restProps","isEmpty","AIAutocomplete_module_css_default","AIAutocompleteDropdown","seg","i","cls","total","revealed","hidden","bgPos","PillList","e"]}