@ensembleapp/client-sdk 0.0.38 → 0.0.40
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.d.ts +237 -72
- package/dist/index.js +1358 -517
- package/dist/index.js.map +1 -1
- package/dist/widget/widget.global.d.ts +26 -0
- package/dist/widget/widget.global.js +212 -0
- package/dist/widget/widget.global.js.map +1 -0
- package/lib/chat/ChatWidget.css +57 -19
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -27,11 +27,77 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// lib/chat/ChatWidget.css
|
|
30
|
-
styleInject(':root[data-chat-widget],\n[data-chat-widget] {\n --chat-primary: #3b82f6;\n --chat-primary-text: #ffffff;\n --chat-primary-hover: #2563eb;\n --chat-background: #ffffff;\n --chat-border: #e5e7eb;\n --chat-header-text: #ffffff;\n --chat-user-text: #ffffff;\n --chat-assistant-bg: transparent;\n --chat-assistant-text: #111827;\n --chat-font-family:\n "Inter",\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n sans-serif;\n --chat-radius: 0.75rem;\n --chat-input-bg: #ffffff;\n --chat-input-text: #111827;\n --chat-input-placeholder: #6b7280;\n --chat-thought-border: #d1d5db;\n --chat-font-size: 0.925rem;\n --chat-thought-font-size: 0.75rem;\n}\n.chat-widget {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 24rem;\n background: var(--chat-background);\n border: 1px solid var(--chat-border);\n border-radius: var(--chat-radius);\n box-shadow: 0 20px 45px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n font-family: var(--chat-font-family);\n color: var(--chat-assistant-text);\n}\n.chat-widget__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 40px;\n padding: 0.75rem 1rem;\n background: var(--chat-primary);\n color: var(--chat-header-text);\n}\n.chat-widget__title {\n margin: 0;\n font-size: 0.875rem;\n font-weight: 600;\n}\n.chat-widget__messages {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n.chat-widget__message {\n display: flex;\n flex-direction: column;\n gap: 0;\n}\n.chat-widget__message-row {\n display: flex;\n}\n.chat-widget__message-row--user {\n justify-content: flex-end;\n}\n.chat-widget__message-row--assistant {\n justify-content: flex-start;\n}\n.chat-widget__bubble {\n max-width: 90%;\n padding: 0.5rem 0.25rem;\n border-radius: calc(var(--chat-radius) * 0.65);\n font-size: var(--chat-font-size);\n}\n.chat-widget__bubble--user {\n background: var(--chat-primary);\n color: var(--chat-user-text);\n border-bottom-right-radius: 0.35rem;\n}\n.chat-widget__bubble--assistant {\n width: 90%;\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n border-bottom-left-radius: 0.35rem;\n}\n.chat-widget__widget {\n width: 100%;\n}\n.chat-widget__markdown {\n white-space: normal;\n font-size: var(--chat-font-size);\n}\n.chat-widget__markdown h1 {\n font-size: calc(var(--chat-font-size) * 1.4);\n}\n.chat-widget__markdown h2 {\n font-size: calc(var(--chat-font-size) * 1.25);\n}\n.chat-widget__markdown h3 {\n font-size: calc(var(--chat-font-size) * 1.1);\n}\n.chat-widget__markdown h4 {\n font-size: calc(var(--chat-font-size) * 1.05);\n}\n.chat-widget__markdown h5 {\n font-size: calc(var(--chat-font-size) * 1);\n}\n.chat-widget__markdown h6 {\n font-size: calc(var(--chat-font-size) * 0.95);\n}\n.chat-widget__anchor-button {\n position: fixed;\n bottom: 20px;\n right: 20px;\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.65rem 0.85rem;\n background: var(--chat-primary);\n color: var(--chat-primary-text);\n border: none;\n border-radius: 999px;\n box-shadow: 0 10px 25px rgba(15, 23, 42, 0.2);\n cursor: pointer;\n font-weight: 600;\n z-index: 99999;\n}\n.chat-widget__anchor-button:hover {\n background: var(--chat-primary-hover);\n}\n.chat-widget__anchor--left {\n right: auto;\n left: 20px;\n}\n.chat-widget__anchor-icon {\n width: 1.1rem;\n height: 1.1rem;\n}\n.chat-widget__popup {\n position: fixed;\n bottom: 80px;\n right: 20px;\n z-index: 99998;\n}\n.chat-widget__anchor--left.chat-widget__popup {\n right: auto;\n left: 20px;\n}\n.chat-widget__popup-inner {\n width: 384px;\n max-width: calc(100vw - 40px);\n height: 500px;\n max-height: calc(100vh - 140px);\n box-shadow: 0 20px 45px rgba(15, 23, 42, 0.12);\n border-radius: 12px;\n overflow: hidden;\n}\n.chat-widget__markdown table {\n width: 100%;\n border-collapse: collapse;\n margin: 0.5rem 0;\n}\n.chat-widget__markdown th,\n.chat-widget__markdown td {\n border: 1px solid var(--chat-border);\n padding: 0.5rem;\n text-align: left;\n vertical-align: top;\n}\n.chat-widget__markdown thead th {\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n font-weight: 600;\n}\n.chat-widget__thoughts {\n min-width: 0;\n --chat-font-size: var(--chat-thought-font-size);\n}\n.chat-widget__details {\n border: 0;\n}\n.chat-widget__thoughts-summary {\n list-style: none;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n cursor: pointer;\n color: #6b7280;\n font-size: 0.8125rem;\n}\n.chat-widget__thoughts-summary:hover {\n color: var(--chat-assistant-text);\n}\n.chat-widget__thoughts-icon-container {\n display: flex;\n border: 1px solid #d1d5db;\n border-radius: 999px;\n align-items: center;\n justify-content: center;\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__thoughts-icon {\n width: 0.75rem;\n height: 0.75rem;\n transition: transform 0.2s ease;\n}\n.chat-widget__details[open] .chat-widget__thoughts-icon {\n transform: rotate(90deg);\n}\n.chat-widget__thoughts-content {\n margin-top: 0.5rem;\n margin-left: 0.4rem;\n padding: 0.75rem;\n border-left: 2px solid var(--chat-thought-border);\n border-color: var(--chat-primary);\n max-width: 100%;\n overflow-x: auto;\n}\n.chat-widget__thoughts-text {\n margin: 0;\n line-height: 1.5;\n color: #4b5563;\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n "Liberation Mono",\n "Courier New",\n monospace;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-wrap: anywhere;\n display: block;\n}\n.chat-widget__loading {\n display: flex;\n justify-content: flex-start;\n}\n.chat-widget__loading-bubble {\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n border-radius: calc(var(--chat-radius) * 0.65);\n border-bottom-left-radius: 0.35rem;\n padding: 0.5rem 0.75rem;\n}\n.chat-widget__loading-dots {\n display: flex;\n gap: 0.35rem;\n}\n.chat-widget__loading-dot {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 999px;\n background: #9ca3af;\n animation: chat-widget-bounce 1s infinite ease-in-out;\n}\n.chat-widget__loading-dot[data-delay="1"] {\n animation-delay: 0.1s;\n}\n.chat-widget__loading-dot[data-delay="2"] {\n animation-delay: 0.2s;\n}\n@keyframes chat-widget-bounce {\n 0%, 80%, 100% {\n transform: scale(0.6);\n opacity: 0.4;\n }\n 40% {\n transform: scale(1);\n opacity: 1;\n }\n}\n.chat-widget__input {\n border-top: 1px solid var(--chat-border);\n padding: 0.25rem 0 0.75rem;\n background: var(--chat-input-bg);\n}\n.chat-widget__form {\n position: relative;\n}\n.chat-widget__textarea {\n width: 100%;\n border: 0;\n padding: 0.75rem 5.25rem 0.75rem 0.75rem;\n background: transparent;\n font-size: 0.925rem;\n resize: none;\n color: var(--chat-input-text);\n font-family: inherit;\n}\n.chat-widget__textarea::-moz-placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__textarea::placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__textarea:focus-visible {\n outline: none;\n}\n.chat-widget__textarea:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.chat-widget__toolbar {\n position: absolute;\n top: 0;\n right: 3.75rem;\n height: 100%;\n display: flex;\n align-items: center;\n padding: 0 0.5rem;\n border-right: 1px solid var(--chat-border);\n}\n.chat-widget__submit {\n position: absolute;\n top: 50%;\n right: 0.75rem;\n transform: translateY(-50%);\n background: transparent;\n border: 0;\n width: 2.5rem;\n height: 2.5rem;\n display: grid;\n place-items: center;\n color: var(--chat-primary);\n cursor: pointer;\n}\n.chat-widget__submit:disabled {\n color: #9ca3af;\n cursor: not-allowed;\n}\n.chat-widget__submit:not(:disabled):hover {\n color: var(--chat-primary-hover);\n}\n.chat-widget__send-icon {\n width: 1.2rem;\n height: 1.2rem;\n}\n.chat-widget__mic-button {\n position: relative;\n border: none;\n background: transparent;\n width: 2.25rem;\n height: 2.25rem;\n display: grid;\n place-items: center;\n color: var(--chat-primary);\n cursor: pointer;\n border-radius: 999px;\n}\n.chat-widget__mic-button:disabled {\n color: #9ca3af;\n cursor: not-allowed;\n}\n.chat-widget__mic-button--active {\n color: var(--chat-primary-hover);\n background: rgba(59, 130, 246, 0.08);\n}\n.chat-widget__mic-icon {\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__mic-bar {\n position: absolute;\n bottom: 0.1rem;\n left: 50%;\n width: 16px;\n height: 2px;\n border-radius: 999px;\n background: rgba(148, 163, 184, 0.4);\n overflow: hidden;\n display: block;\n transform: translateX(-50%);\n pointer-events: none;\n}\n.chat-widget__mic-bar-fill {\n display: block;\n width: 100%;\n height: 100%;\n background: currentColor;\n transform-origin: left;\n transition: transform 0.12s linear;\n}\n.chat-widget__voice {\n display: flex;\n margin-top: 0.25rem;\n}\n.chat-widget__voice-button {\n border: none;\n background: none;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.1rem 0;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--chat-primary);\n cursor: pointer;\n}\n.chat-widget__voice-button:disabled {\n color: #9ca3af;\n cursor: not-allowed;\n}\n.chat-widget__voice-button--active {\n color: var(--chat-primary-hover);\n}\n.chat-widget__voice-icon {\n width: 0.95rem;\n height: 0.95rem;\n}\n.chat-widget__voice-icon--spin {\n animation: chat-widget-spin 1s linear infinite;\n}\n@keyframes chat-widget-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.chat-widget__collapsed {\n position: relative;\n margin-bottom: 0.25rem;\n}\n.chat-widget__collapsed-content {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 300ms ease-out;\n}\n.chat-widget__collapsed-content--expanded {\n grid-template-rows: 1fr;\n}\n.chat-widget__collapsed-content-inner {\n overflow: hidden;\n}\n.chat-widget__collapsed-preview {\n position: relative;\n max-height: 1.5em;\n overflow: hidden;\n opacity: 0.6;\n pointer-events: none;\n transition: opacity 300ms ease-out, max-height 300ms ease-out;\n}\n.chat-widget__collapsed-preview--hidden {\n opacity: 0;\n max-height: 0;\n pointer-events: none;\n}\n.chat-widget__collapsed-gradient {\n position: absolute;\n top: 0;\n right: 0;\n width: 70%;\n height: 100%;\n background:\n linear-gradient(\n to right,\n transparent 0%,\n var(--chat-background) 90%);\n pointer-events: none;\n}\n.chat-widget__collapsed-toggle {\n display: inline-block;\n padding: 0;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--chat-primary);\n background: transparent;\n border: none;\n cursor: pointer;\n}\n.chat-widget__collapsed-toggle:hover {\n text-decoration: underline;\n}\n@keyframes chat-widget-slide-up {\n from {\n opacity: 1;\n transform: translateY(0);\n max-height: 200px;\n }\n to {\n opacity: 0.6;\n transform: translateY(-8px);\n max-height: 1.5em;\n }\n}\n.chat-widget__collapsed--animating .chat-widget__collapsed-preview {\n animation: chat-widget-slide-up 300ms ease-out forwards;\n}\n');
|
|
30
|
+
styleInject(':root[data-chat-widget],\n[data-chat-widget] {\n --chat-primary: #3b82f6;\n --chat-primary-text: #ffffff;\n --chat-primary-hover: #2563eb;\n --chat-primary-subtle: rgba(59, 130, 246, 0.1);\n --chat-background: #ffffff;\n --chat-background-secondary: #f9fafb;\n --chat-background-tertiary: #f3f4f6;\n --chat-border: #e5e7eb;\n --chat-border-light: #f3f4f6;\n --chat-text: #111827;\n --chat-text-secondary: #4b5563;\n --chat-text-muted: #6b7280;\n --chat-text-disabled: #9ca3af;\n --chat-success: #22c55e;\n --chat-success-bg: rgba(34, 197, 94, 0.1);\n --chat-error: #ef4444;\n --chat-error-bg: rgba(239, 68, 68, 0.1);\n --chat-header-text: #ffffff;\n --chat-user-text: #ffffff;\n --chat-assistant-bg: transparent;\n --chat-assistant-text: var(--chat-text);\n --chat-input-bg: var(--chat-background);\n --chat-input-text: var(--chat-text);\n --chat-input-placeholder: var(--chat-text-muted);\n --chat-thought-border: var(--chat-border);\n --chat-font-family:\n "Inter",\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n sans-serif;\n --chat-radius: 0.75rem;\n --chat-font-size: 0.925rem;\n --chat-thought-font-size: 0.75rem;\n --chat-shadow: 0 20px 45px rgba(0, 0, 0, 0.12);\n --chat-shadow-sm: 0 4px 12px rgba(0, 0, 0, 0.1);\n --chat-overlay-bg: rgba(0, 0, 0, 0.3);\n}\n.chat-widget {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 24rem;\n background: var(--chat-background);\n border: 1px solid var(--chat-border);\n border-radius: var(--chat-radius);\n box-shadow: var(--chat-shadow);\n overflow: hidden;\n font-family: var(--chat-font-family);\n color: var(--chat-assistant-text);\n}\n.chat-widget__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 40px;\n padding: 0.75rem 1rem;\n background: var(--chat-primary);\n color: var(--chat-header-text);\n}\n.chat-widget__title {\n margin: 0;\n font-size: 0.875rem;\n font-weight: 600;\n}\n.chat-widget__messages {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n.chat-widget__message {\n display: flex;\n flex-direction: column;\n gap: 0;\n}\n.chat-widget__message-row {\n display: flex;\n}\n.chat-widget__message-row--user {\n justify-content: flex-end;\n}\n.chat-widget__message-row--assistant {\n justify-content: flex-start;\n}\n.chat-widget__bubble {\n max-width: 90%;\n padding: 0.5rem 0.25rem;\n border-radius: calc(var(--chat-radius) * 0.65);\n font-size: var(--chat-font-size);\n}\n.chat-widget__bubble--user {\n background: var(--chat-primary);\n color: var(--chat-user-text);\n border-bottom-right-radius: 0.35rem;\n}\n.chat-widget__bubble--assistant {\n width: 90%;\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n border-bottom-left-radius: 0.35rem;\n}\n.chat-widget__widget {\n width: 100%;\n}\n.chat-widget__markdown {\n white-space: normal;\n font-size: var(--chat-font-size);\n}\n.chat-widget__markdown h1 {\n font-size: calc(var(--chat-font-size) * 1.4);\n}\n.chat-widget__markdown h2 {\n font-size: calc(var(--chat-font-size) * 1.25);\n}\n.chat-widget__markdown h3 {\n font-size: calc(var(--chat-font-size) * 1.1);\n}\n.chat-widget__markdown h4 {\n font-size: calc(var(--chat-font-size) * 1.05);\n}\n.chat-widget__markdown h5 {\n font-size: calc(var(--chat-font-size) * 1);\n}\n.chat-widget__markdown h6 {\n font-size: calc(var(--chat-font-size) * 0.95);\n}\n.chat-widget__anchor-button {\n position: fixed;\n bottom: 20px;\n right: 20px;\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.65rem 0.85rem;\n background: var(--chat-primary);\n color: var(--chat-primary-text);\n border: none;\n border-radius: 999px;\n box-shadow: var(--chat-shadow);\n cursor: pointer;\n font-weight: 600;\n z-index: 99999;\n}\n.chat-widget__anchor-button:hover {\n background: var(--chat-primary-hover);\n}\n.chat-widget__anchor--left {\n right: auto;\n left: 20px;\n}\n.chat-widget__anchor-icon {\n width: 1.1rem;\n height: 1.1rem;\n}\n.chat-widget__popup {\n position: fixed;\n bottom: 80px;\n right: 20px;\n z-index: 99998;\n}\n.chat-widget__anchor--left.chat-widget__popup {\n right: auto;\n left: 20px;\n}\n.chat-widget__popup-inner {\n width: 384px;\n max-width: calc(100vw - 40px);\n height: 500px;\n max-height: calc(100vh - 140px);\n box-shadow: var(--chat-shadow);\n border-radius: 12px;\n overflow: hidden;\n}\n.chat-widget__markdown a {\n color: var(--chat-primary);\n text-decoration: underline;\n}\n.chat-widget__markdown a:hover {\n color: var(--chat-primary-hover);\n}\n.chat-widget__markdown table {\n width: 100%;\n border-collapse: collapse;\n margin: 0.5rem 0;\n}\n.chat-widget__markdown th,\n.chat-widget__markdown td {\n border: 1px solid var(--chat-border);\n padding: 0.5rem;\n text-align: left;\n vertical-align: top;\n}\n.chat-widget__markdown thead th {\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n font-weight: 600;\n}\n.chat-widget__thoughts {\n min-width: 0;\n --chat-font-size: var(--chat-thought-font-size);\n}\n.chat-widget__details {\n border: 0;\n}\n.chat-widget__thoughts-summary {\n list-style: none;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n cursor: pointer;\n color: var(--chat-text-muted);\n font-size: 0.8125rem;\n}\n.chat-widget__thoughts-summary:hover {\n color: var(--chat-assistant-text);\n}\n.chat-widget__thoughts-icon-container {\n display: flex;\n border: 1px solid var(--chat-border);\n border-radius: 999px;\n align-items: center;\n justify-content: center;\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__thoughts-icon {\n width: 0.75rem;\n height: 0.75rem;\n transition: transform 0.2s ease;\n}\n.chat-widget__details[open] .chat-widget__thoughts-icon {\n transform: rotate(90deg);\n}\n.chat-widget__thoughts-content {\n margin-top: 0.5rem;\n margin-left: 0.4rem;\n padding: 0.75rem;\n border-left: 2px solid var(--chat-thought-border);\n border-color: var(--chat-primary);\n max-width: 100%;\n overflow-x: auto;\n}\n.chat-widget__thoughts-text {\n margin: 0;\n line-height: 1.5;\n color: var(--chat-text-secondary);\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n "Liberation Mono",\n "Courier New",\n monospace;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-wrap: anywhere;\n display: block;\n}\n.chat-widget__loading {\n display: flex;\n justify-content: flex-start;\n}\n.chat-widget__loading-bubble {\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n border-radius: calc(var(--chat-radius) * 0.65);\n border-bottom-left-radius: 0.35rem;\n padding: 0.5rem 0.75rem;\n}\n.chat-widget__loading-dots {\n display: flex;\n gap: 0.35rem;\n}\n.chat-widget__loading-dot {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 999px;\n background: var(--chat-text-disabled);\n animation: chat-widget-bounce 1s infinite ease-in-out;\n}\n.chat-widget__loading-dot[data-delay="1"] {\n animation-delay: 0.1s;\n}\n.chat-widget__loading-dot[data-delay="2"] {\n animation-delay: 0.2s;\n}\n@keyframes chat-widget-bounce {\n 0%, 80%, 100% {\n transform: scale(0.6);\n opacity: 0.4;\n }\n 40% {\n transform: scale(1);\n opacity: 1;\n }\n}\n.chat-widget__input {\n border-top: 1px solid var(--chat-border);\n padding: 0.25rem 0 0.75rem;\n background: var(--chat-input-bg);\n}\n.chat-widget__form {\n position: relative;\n}\n.chat-widget__textarea {\n width: 100%;\n border: 0;\n padding: 0.75rem 5.25rem 0.75rem 0.75rem;\n background: transparent;\n font-size: 0.925rem;\n resize: none;\n color: var(--chat-input-text);\n font-family: inherit;\n}\n.chat-widget__textarea::-moz-placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__textarea::placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__textarea:focus-visible {\n outline: none;\n}\n.chat-widget__textarea:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.chat-widget__toolbar {\n position: absolute;\n top: 0;\n right: 3.75rem;\n height: 100%;\n display: flex;\n align-items: center;\n padding: 0 0.5rem;\n border-right: 1px solid var(--chat-border);\n}\n.chat-widget__submit {\n position: absolute;\n top: 50%;\n right: 0.75rem;\n transform: translateY(-50%);\n background: transparent;\n border: 0;\n width: 2.5rem;\n height: 2.5rem;\n display: grid;\n place-items: center;\n color: var(--chat-primary);\n cursor: pointer;\n}\n.chat-widget__submit:disabled {\n color: var(--chat-text-disabled);\n cursor: not-allowed;\n}\n.chat-widget__submit:not(:disabled):hover {\n color: var(--chat-primary-hover);\n}\n.chat-widget__send-icon {\n width: 1.2rem;\n height: 1.2rem;\n}\n.chat-widget__mic-button {\n position: relative;\n border: none;\n background: transparent;\n width: 2.25rem;\n height: 2.25rem;\n display: grid;\n place-items: center;\n color: var(--chat-primary);\n cursor: pointer;\n border-radius: 999px;\n}\n.chat-widget__mic-button:disabled {\n color: var(--chat-text-disabled);\n cursor: not-allowed;\n}\n.chat-widget__mic-button--active {\n color: var(--chat-primary-hover);\n background: var(--chat-primary-subtle);\n}\n.chat-widget__mic-icon {\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__mic-bar {\n position: absolute;\n bottom: 0.1rem;\n left: 50%;\n width: 16px;\n height: 2px;\n border-radius: 999px;\n background: var(--chat-border);\n overflow: hidden;\n display: block;\n transform: translateX(-50%);\n pointer-events: none;\n}\n.chat-widget__mic-bar-fill {\n display: block;\n width: 100%;\n height: 100%;\n background: currentColor;\n transform-origin: left;\n transition: transform 0.12s linear;\n}\n.chat-widget__voice {\n display: flex;\n margin-top: 0.25rem;\n}\n.chat-widget__voice-button {\n border: none;\n background: none;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.1rem 0;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--chat-primary);\n cursor: pointer;\n}\n.chat-widget__voice-button:disabled {\n color: var(--chat-text-disabled);\n cursor: not-allowed;\n}\n.chat-widget__voice-button--active {\n color: var(--chat-primary-hover);\n}\n.chat-widget__voice-icon {\n width: 0.95rem;\n height: 0.95rem;\n}\n.chat-widget__voice-icon--spin {\n animation: chat-widget-spin 1s linear infinite;\n}\n@keyframes chat-widget-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.chat-widget__collapsed {\n position: relative;\n margin-bottom: 0.25rem;\n}\n.chat-widget__collapsed-content {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 300ms ease-out;\n}\n.chat-widget__collapsed-content--expanded {\n grid-template-rows: 1fr;\n}\n.chat-widget__collapsed-content-inner {\n overflow: hidden;\n}\n.chat-widget__collapsed-preview {\n position: relative;\n max-height: 1.5em;\n overflow: hidden;\n opacity: 0.6;\n pointer-events: none;\n transition: opacity 300ms ease-out, max-height 300ms ease-out;\n}\n.chat-widget__collapsed-preview--hidden {\n opacity: 0;\n max-height: 0;\n pointer-events: none;\n}\n.chat-widget__collapsed-gradient {\n position: absolute;\n top: 0;\n right: 0;\n width: 70%;\n height: 100%;\n background:\n linear-gradient(\n to right,\n transparent 0%,\n var(--chat-background) 90%);\n pointer-events: none;\n}\n.chat-widget__collapsed-toggle {\n display: inline-block;\n padding: 0;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--chat-primary);\n background: transparent;\n border: none;\n cursor: pointer;\n}\n.chat-widget__collapsed-toggle:hover {\n text-decoration: underline;\n}\n@keyframes chat-widget-slide-up {\n from {\n opacity: 1;\n transform: translateY(0);\n max-height: 200px;\n }\n to {\n opacity: 0.6;\n transform: translateY(-8px);\n max-height: 1.5em;\n }\n}\n.chat-widget__collapsed--animating .chat-widget__collapsed-preview {\n animation: chat-widget-slide-up 300ms ease-out forwards;\n}\n');
|
|
31
31
|
|
|
32
32
|
// lib/chat/ChatWidget.tsx
|
|
33
33
|
import { Send, StopCircle } from "lucide-react";
|
|
34
|
-
import { forwardRef, useCallback as useCallback6, useEffect as useEffect6, useImperativeHandle, useMemo as useMemo5, useRef as useRef5, useState as
|
|
34
|
+
import { forwardRef, useCallback as useCallback6, useEffect as useEffect6, useImperativeHandle, useMemo as useMemo5, useRef as useRef5, useState as useState9 } from "react";
|
|
35
|
+
|
|
36
|
+
// lib/api/fetchApprovalConfig.ts
|
|
37
|
+
async function fetchApprovalConfig(options) {
|
|
38
|
+
const { api, agentId, agentVersion, toolName, args = {}, onAuthError } = options;
|
|
39
|
+
const { baseUrl, headers: customHeaders = {} } = api;
|
|
40
|
+
const doFetch = (token) => fetch(`${baseUrl}/chat/tools/${encodeURIComponent(toolName)}/approval-config`, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: {
|
|
43
|
+
"Content-Type": "application/json",
|
|
44
|
+
Authorization: `Bearer ${token}`,
|
|
45
|
+
"agent-id": agentId,
|
|
46
|
+
...agentVersion !== void 0 ? { version: String(agentVersion) } : {},
|
|
47
|
+
...customHeaders
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify({ args })
|
|
50
|
+
});
|
|
51
|
+
let response = await doFetch(api.token);
|
|
52
|
+
if (response.status === 401 && onAuthError) {
|
|
53
|
+
const newToken = await onAuthError();
|
|
54
|
+
if (newToken) {
|
|
55
|
+
response = await doFetch(newToken);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
console.error(
|
|
60
|
+
`[fetchApprovalConfig] Failed to fetch approval config for ${toolName}:`,
|
|
61
|
+
response.status
|
|
62
|
+
);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return response.json();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// lib/api/invokeTool.ts
|
|
69
|
+
function createInvokeTool(api, onAuthError) {
|
|
70
|
+
return async (toolId, request = {}) => {
|
|
71
|
+
const { baseUrl, headers: customHeaders = {} } = api;
|
|
72
|
+
const doFetch = (token) => fetch(`${baseUrl}/api/tools/${toolId}/invoke`, {
|
|
73
|
+
method: "POST",
|
|
74
|
+
headers: {
|
|
75
|
+
"Content-Type": "application/json",
|
|
76
|
+
Authorization: `Bearer ${token}`,
|
|
77
|
+
...customHeaders
|
|
78
|
+
},
|
|
79
|
+
body: JSON.stringify(request)
|
|
80
|
+
});
|
|
81
|
+
let response = await doFetch(api.token);
|
|
82
|
+
if (response.status === 401 && onAuthError) {
|
|
83
|
+
const newToken = await onAuthError();
|
|
84
|
+
if (newToken) {
|
|
85
|
+
response = await doFetch(newToken);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
return {
|
|
90
|
+
success: false,
|
|
91
|
+
error: {
|
|
92
|
+
message: `HTTP ${response.status}`,
|
|
93
|
+
details: [await response.text().catch(() => response.statusText)],
|
|
94
|
+
code: "HTTP_ERROR"
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return response.json();
|
|
99
|
+
};
|
|
100
|
+
}
|
|
35
101
|
|
|
36
102
|
// ../../node_modules/.pnpm/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
|
|
37
103
|
var marker = "vercel.ai.error";
|
|
@@ -20998,6 +21064,15 @@ var uiMessageChunkSchema = lazySchema(
|
|
|
20998
21064
|
])
|
|
20999
21065
|
)
|
|
21000
21066
|
);
|
|
21067
|
+
function isStaticToolUIPart(part) {
|
|
21068
|
+
return part.type.startsWith("tool-");
|
|
21069
|
+
}
|
|
21070
|
+
function isDynamicToolUIPart(part) {
|
|
21071
|
+
return part.type === "dynamic-tool";
|
|
21072
|
+
}
|
|
21073
|
+
function isToolUIPart(part) {
|
|
21074
|
+
return isStaticToolUIPart(part) || isDynamicToolUIPart(part);
|
|
21075
|
+
}
|
|
21001
21076
|
var originalGenerateId2 = createIdGenerator({
|
|
21002
21077
|
prefix: "aitxt",
|
|
21003
21078
|
size: 24
|
|
@@ -21417,6 +21492,46 @@ var DefaultChatTransport = class extends HttpChatTransport {
|
|
|
21417
21492
|
);
|
|
21418
21493
|
}
|
|
21419
21494
|
};
|
|
21495
|
+
function lastAssistantMessageIsCompleteWithApprovalResponses({
|
|
21496
|
+
messages
|
|
21497
|
+
}) {
|
|
21498
|
+
const message = messages[messages.length - 1];
|
|
21499
|
+
if (!message) {
|
|
21500
|
+
return false;
|
|
21501
|
+
}
|
|
21502
|
+
if (message.role !== "assistant") {
|
|
21503
|
+
return false;
|
|
21504
|
+
}
|
|
21505
|
+
const lastStepStartIndex = message.parts.reduce((lastIndex, part, index) => {
|
|
21506
|
+
return part.type === "step-start" ? index : lastIndex;
|
|
21507
|
+
}, -1);
|
|
21508
|
+
const lastStepToolInvocations = message.parts.slice(lastStepStartIndex + 1).filter(isToolUIPart).filter((part) => !part.providerExecuted);
|
|
21509
|
+
return (
|
|
21510
|
+
// has at least one tool approval response
|
|
21511
|
+
lastStepToolInvocations.filter((part) => part.state === "approval-responded").length > 0 && // all tool approvals must have a response
|
|
21512
|
+
lastStepToolInvocations.every(
|
|
21513
|
+
(part) => part.state === "output-available" || part.state === "output-error" || part.state === "approval-responded"
|
|
21514
|
+
)
|
|
21515
|
+
);
|
|
21516
|
+
}
|
|
21517
|
+
function lastAssistantMessageIsCompleteWithToolCalls({
|
|
21518
|
+
messages
|
|
21519
|
+
}) {
|
|
21520
|
+
const message = messages[messages.length - 1];
|
|
21521
|
+
if (!message) {
|
|
21522
|
+
return false;
|
|
21523
|
+
}
|
|
21524
|
+
if (message.role !== "assistant") {
|
|
21525
|
+
return false;
|
|
21526
|
+
}
|
|
21527
|
+
const lastStepStartIndex = message.parts.reduce((lastIndex, part, index) => {
|
|
21528
|
+
return part.type === "step-start" ? index : lastIndex;
|
|
21529
|
+
}, -1);
|
|
21530
|
+
const lastStepToolInvocations = message.parts.slice(lastStepStartIndex + 1).filter(isToolUIPart).filter((part) => !part.providerExecuted);
|
|
21531
|
+
return lastStepToolInvocations.length > 0 && lastStepToolInvocations.every(
|
|
21532
|
+
(part) => part.state === "output-available" || part.state === "output-error"
|
|
21533
|
+
);
|
|
21534
|
+
}
|
|
21420
21535
|
|
|
21421
21536
|
// lib/hooks/useChat.ts
|
|
21422
21537
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
@@ -21486,6 +21601,7 @@ function transformMessage(msg) {
|
|
|
21486
21601
|
}
|
|
21487
21602
|
|
|
21488
21603
|
// lib/hooks/useChat.ts
|
|
21604
|
+
var COLLECT_USER_INPUT_TOOL = "collect_user_input";
|
|
21489
21605
|
function createAuthAwareFetch(tokenRef, onAuthError) {
|
|
21490
21606
|
return async (input, init) => {
|
|
21491
21607
|
const doFetch = (token) => fetch(input, {
|
|
@@ -21557,10 +21673,16 @@ function useChat({
|
|
|
21557
21673
|
status,
|
|
21558
21674
|
sendMessage,
|
|
21559
21675
|
stop,
|
|
21560
|
-
setMessages
|
|
21676
|
+
setMessages,
|
|
21677
|
+
addToolOutput,
|
|
21678
|
+
addToolApprovalResponse
|
|
21561
21679
|
} = useAIChat({
|
|
21562
21680
|
id: threadId,
|
|
21563
21681
|
transport,
|
|
21682
|
+
// Automatically resubmit when:
|
|
21683
|
+
// 1. Tool result is populated (collect_user_input use case)
|
|
21684
|
+
// 2. Tool approval responses are complete (human-in-the-loop approval)
|
|
21685
|
+
sendAutomaticallyWhen: ({ messages: messages2 }) => lastAssistantMessageIsCompleteWithToolCalls({ messages: messages2 }) || lastAssistantMessageIsCompleteWithApprovalResponses({ messages: messages2 }),
|
|
21564
21686
|
onError: (error48) => {
|
|
21565
21687
|
console.error("Chat error:", error48);
|
|
21566
21688
|
onError?.(error48);
|
|
@@ -21609,13 +21731,56 @@ function useChat({
|
|
|
21609
21731
|
const rtnMessages = useMemo(() => {
|
|
21610
21732
|
return messages.map((msg) => transformMessage(msg));
|
|
21611
21733
|
}, [messages]);
|
|
21734
|
+
const pendingToolOutput = useMemo(() => {
|
|
21735
|
+
const lastMessage = messages[messages.length - 1];
|
|
21736
|
+
if (!lastMessage || lastMessage.role !== "assistant") return null;
|
|
21737
|
+
for (const part of lastMessage.parts ?? []) {
|
|
21738
|
+
const isToolPart = part.type.startsWith("tool-") || part.type === "dynamic-tool";
|
|
21739
|
+
if (!isToolPart) continue;
|
|
21740
|
+
const toolName = "toolName" in part ? part.toolName : part.type.replace("tool-", "");
|
|
21741
|
+
if (toolName !== COLLECT_USER_INPUT_TOOL) continue;
|
|
21742
|
+
const state = "state" in part ? part.state : void 0;
|
|
21743
|
+
if (state === "input-available") {
|
|
21744
|
+
return {
|
|
21745
|
+
toolCallId: part.toolCallId,
|
|
21746
|
+
args: part.input
|
|
21747
|
+
};
|
|
21748
|
+
}
|
|
21749
|
+
}
|
|
21750
|
+
return null;
|
|
21751
|
+
}, [messages]);
|
|
21752
|
+
const pendingToolApproval = useMemo(() => {
|
|
21753
|
+
const lastMessage = messages[messages.length - 1];
|
|
21754
|
+
if (!lastMessage || lastMessage.role !== "assistant") return null;
|
|
21755
|
+
for (const part of lastMessage.parts ?? []) {
|
|
21756
|
+
const isToolPart = part.type.startsWith("tool-") || part.type === "dynamic-tool";
|
|
21757
|
+
if (!isToolPart) continue;
|
|
21758
|
+
const state = "state" in part ? part.state : void 0;
|
|
21759
|
+
if (state === "approval-requested") {
|
|
21760
|
+
const toolName = "toolName" in part ? part.toolName : part.type.replace("tool-", "");
|
|
21761
|
+
const approval = "approval" in part ? part.approval : null;
|
|
21762
|
+
if (!approval?.id) continue;
|
|
21763
|
+
return {
|
|
21764
|
+
toolCallId: part.toolCallId,
|
|
21765
|
+
toolName,
|
|
21766
|
+
args: part.input ?? {},
|
|
21767
|
+
approvalId: approval.id
|
|
21768
|
+
};
|
|
21769
|
+
}
|
|
21770
|
+
}
|
|
21771
|
+
return null;
|
|
21772
|
+
}, [messages]);
|
|
21612
21773
|
return {
|
|
21613
21774
|
messages: rtnMessages,
|
|
21614
21775
|
status,
|
|
21615
21776
|
isLoadingInitial,
|
|
21616
21777
|
sendMessage,
|
|
21617
21778
|
stop,
|
|
21618
|
-
setMessages
|
|
21779
|
+
setMessages,
|
|
21780
|
+
addToolOutput,
|
|
21781
|
+
addToolApprovalResponse,
|
|
21782
|
+
pendingToolOutput,
|
|
21783
|
+
pendingToolApproval
|
|
21619
21784
|
};
|
|
21620
21785
|
}
|
|
21621
21786
|
|
|
@@ -21715,15 +21880,376 @@ function cn(...inputs) {
|
|
|
21715
21880
|
return twMerge(clsx(inputs));
|
|
21716
21881
|
}
|
|
21717
21882
|
|
|
21883
|
+
// lib/chat/components/InputFormOverlay.css
|
|
21884
|
+
styleInject('@import "./input-fields/InputFields.css";\n.input-form-overlay {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n top: 0;\n z-index: 10;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n pointer-events: none;\n}\n@keyframes slideUp {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n.input-form-overlay__content {\n pointer-events: auto;\n animation: slideUp 0.2s ease-out;\n display: flex;\n flex-direction: column;\n background-color: var(--chat-background);\n border-top: 1px solid var(--chat-border);\n border-radius: var(--chat-radius) var(--chat-radius) 0 0;\n box-shadow: var(--chat-shadow-sm);\n max-height: 80%;\n font-family: var(--chat-font-family);\n}\n.input-form-overlay__title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--chat-assistant-text);\n margin: 0 0 0.375rem 0;\n}\n.input-form-overlay__description {\n font-size: 0.8125rem;\n color: var(--chat-input-placeholder);\n margin: 0 0 1rem 0;\n line-height: 1.4;\n}\n.input-form-overlay__form {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n}\n.input-form-overlay__scrollable {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding: 1rem 1.25rem;\n}\n.input-form-overlay__fields {\n}\n.input-form-overlay__footer {\n flex-shrink: 0;\n padding: 0.5rem 1.25rem;\n border-top: 1px solid var(--chat-border);\n}\n.input-form-overlay__actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n justify-content: flex-start;\n}\n.input-form-overlay__button {\n padding: 0.5rem 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: calc(var(--chat-radius) * 0.5);\n cursor: pointer;\n transition: all 0.15s ease-in-out;\n border: none;\n}\n.input-form-overlay__button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.input-form-overlay__button--primary {\n background-color: var(--chat-primary);\n color: var(--chat-primary-text);\n}\n.input-form-overlay__button--primary:hover:not(:disabled) {\n background-color: var(--chat-primary-hover);\n}\n.input-form-overlay__button--secondary {\n background-color: var(--chat-border);\n color: var(--chat-assistant-text);\n}\n.input-form-overlay__button--secondary:hover:not(:disabled) {\n opacity: 0.8;\n}\n.input-form-overlay__freeform-toggle {\n padding: 0.5rem 0;\n font-size: 0.75rem;\n color: var(--chat-input-placeholder);\n background: none;\n border: none;\n cursor: pointer;\n transition: color 0.15s ease-in-out;\n white-space: nowrap;\n}\n.input-form-overlay__freeform-toggle:hover {\n color: var(--chat-primary);\n text-decoration: underline;\n}\n.input-form-overlay__freeform {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n}\n.input-form-overlay__freeform-body {\n padding: 1rem 1.25rem;\n}\n.input-form-overlay__freeform-input {\n flex: 1;\n width: 100%;\n padding: 0.625rem;\n font-size: var(--chat-font-size);\n line-height: 1.4;\n color: var(--chat-input-text);\n background-color: var(--chat-input-bg);\n border: 1px solid var(--chat-border);\n border-radius: calc(var(--chat-radius) * 0.5);\n resize: vertical;\n min-height: 5rem;\n font-family: var(--chat-font-family);\n}\n.input-form-overlay__freeform-input:focus {\n outline: none;\n border-color: var(--chat-primary);\n box-shadow: 0 0 0 2px var(--chat-primary-subtle);\n}\n');
|
|
21885
|
+
|
|
21886
|
+
// lib/chat/components/InputFormOverlay.tsx
|
|
21887
|
+
import { useState as useState3 } from "react";
|
|
21888
|
+
|
|
21889
|
+
// lib/chat/components/input-fields/CheckboxField.tsx
|
|
21890
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21891
|
+
function CheckboxField({ field, value, onChange }) {
|
|
21892
|
+
const { name: name21, label } = field;
|
|
21893
|
+
return /* @__PURE__ */ jsx("div", { className: "input-field input-field--checkbox", children: /* @__PURE__ */ jsxs("label", { className: "input-field__checkbox-wrapper", children: [
|
|
21894
|
+
/* @__PURE__ */ jsx(
|
|
21895
|
+
"input",
|
|
21896
|
+
{
|
|
21897
|
+
type: "checkbox",
|
|
21898
|
+
name: name21,
|
|
21899
|
+
checked: value ?? false,
|
|
21900
|
+
onChange: (e) => onChange(e.target.checked),
|
|
21901
|
+
className: "input-field__checkbox"
|
|
21902
|
+
}
|
|
21903
|
+
),
|
|
21904
|
+
/* @__PURE__ */ jsx("span", { className: "input-field__checkbox-label", children: label })
|
|
21905
|
+
] }) });
|
|
21906
|
+
}
|
|
21907
|
+
|
|
21908
|
+
// lib/chat/components/input-fields/ChoicesField.tsx
|
|
21909
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
21910
|
+
function ChoicesField({ field, value, onChange }) {
|
|
21911
|
+
const { name: name21, label, options, multiSelect, required: required2 } = field;
|
|
21912
|
+
if (multiSelect) {
|
|
21913
|
+
const selectedValues = Array.isArray(value) ? value : value ? [value] : [];
|
|
21914
|
+
const handleCheckboxChange = (optionValue, checked) => {
|
|
21915
|
+
if (checked) {
|
|
21916
|
+
onChange([...selectedValues, optionValue]);
|
|
21917
|
+
} else {
|
|
21918
|
+
onChange(selectedValues.filter((v) => v !== optionValue));
|
|
21919
|
+
}
|
|
21920
|
+
};
|
|
21921
|
+
return /* @__PURE__ */ jsxs2("div", { className: "input-field input-field--choices", children: [
|
|
21922
|
+
/* @__PURE__ */ jsxs2("label", { className: "input-field__label", children: [
|
|
21923
|
+
label,
|
|
21924
|
+
required2 && /* @__PURE__ */ jsx2("span", { className: "input-field__required", children: "*" })
|
|
21925
|
+
] }),
|
|
21926
|
+
/* @__PURE__ */ jsx2("div", { className: "input-field__options input-field__options--checkbox", children: options.map((option) => /* @__PURE__ */ jsxs2("label", { className: "input-field__option", children: [
|
|
21927
|
+
/* @__PURE__ */ jsx2(
|
|
21928
|
+
"input",
|
|
21929
|
+
{
|
|
21930
|
+
type: "checkbox",
|
|
21931
|
+
name: name21,
|
|
21932
|
+
value: option.value,
|
|
21933
|
+
checked: selectedValues.includes(option.value),
|
|
21934
|
+
onChange: (e) => handleCheckboxChange(option.value, e.target.checked),
|
|
21935
|
+
className: "input-field__checkbox"
|
|
21936
|
+
}
|
|
21937
|
+
),
|
|
21938
|
+
/* @__PURE__ */ jsxs2("span", { className: "input-field__option-content", children: [
|
|
21939
|
+
/* @__PURE__ */ jsx2("span", { className: "input-field__option-label", children: option.label }),
|
|
21940
|
+
option.description && /* @__PURE__ */ jsx2("span", { className: "input-field__option-description", children: option.description })
|
|
21941
|
+
] })
|
|
21942
|
+
] }, option.value)) })
|
|
21943
|
+
] });
|
|
21944
|
+
}
|
|
21945
|
+
const selectedValue = Array.isArray(value) ? value[0] : value;
|
|
21946
|
+
return /* @__PURE__ */ jsxs2("div", { className: "input-field input-field--choices", children: [
|
|
21947
|
+
/* @__PURE__ */ jsxs2("label", { className: "input-field__label", children: [
|
|
21948
|
+
label,
|
|
21949
|
+
required2 && /* @__PURE__ */ jsx2("span", { className: "input-field__required", children: "*" })
|
|
21950
|
+
] }),
|
|
21951
|
+
/* @__PURE__ */ jsx2("div", { className: "input-field__options input-field__options--radio", children: options.map((option) => /* @__PURE__ */ jsxs2("label", { className: "input-field__option", children: [
|
|
21952
|
+
/* @__PURE__ */ jsx2(
|
|
21953
|
+
"input",
|
|
21954
|
+
{
|
|
21955
|
+
type: "radio",
|
|
21956
|
+
name: name21,
|
|
21957
|
+
value: option.value,
|
|
21958
|
+
checked: selectedValue === option.value,
|
|
21959
|
+
onChange: () => onChange(option.value),
|
|
21960
|
+
className: "input-field__radio"
|
|
21961
|
+
}
|
|
21962
|
+
),
|
|
21963
|
+
/* @__PURE__ */ jsxs2("span", { className: "input-field__option-content", children: [
|
|
21964
|
+
/* @__PURE__ */ jsx2("span", { className: "input-field__option-label", children: option.label }),
|
|
21965
|
+
option.description && /* @__PURE__ */ jsx2("span", { className: "input-field__option-description", children: option.description })
|
|
21966
|
+
] })
|
|
21967
|
+
] }, option.value)) })
|
|
21968
|
+
] });
|
|
21969
|
+
}
|
|
21970
|
+
|
|
21971
|
+
// lib/chat/components/input-fields/DateField.tsx
|
|
21972
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
21973
|
+
function DateField({ field, value, onChange }) {
|
|
21974
|
+
const { label, required: required2 } = field;
|
|
21975
|
+
return /* @__PURE__ */ jsxs3("div", { className: "input-field input-field--date", children: [
|
|
21976
|
+
/* @__PURE__ */ jsxs3("label", { className: "input-field__label", children: [
|
|
21977
|
+
label,
|
|
21978
|
+
required2 && /* @__PURE__ */ jsx3("span", { className: "input-field__required", children: "*" })
|
|
21979
|
+
] }),
|
|
21980
|
+
/* @__PURE__ */ jsx3(
|
|
21981
|
+
"input",
|
|
21982
|
+
{
|
|
21983
|
+
type: "date",
|
|
21984
|
+
value: value ?? "",
|
|
21985
|
+
onChange: (e) => onChange(e.target.value),
|
|
21986
|
+
className: "input-field__input"
|
|
21987
|
+
}
|
|
21988
|
+
)
|
|
21989
|
+
] });
|
|
21990
|
+
}
|
|
21991
|
+
|
|
21992
|
+
// lib/chat/components/input-fields/NumberField.tsx
|
|
21993
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
21994
|
+
function NumberField({ field, value, onChange }) {
|
|
21995
|
+
const { label, min, max, required: required2 } = field;
|
|
21996
|
+
const handleChange = (e) => {
|
|
21997
|
+
const val = e.target.value;
|
|
21998
|
+
if (val === "") {
|
|
21999
|
+
onChange(void 0);
|
|
22000
|
+
} else {
|
|
22001
|
+
const num = parseFloat(val);
|
|
22002
|
+
if (!isNaN(num)) {
|
|
22003
|
+
onChange(num);
|
|
22004
|
+
}
|
|
22005
|
+
}
|
|
22006
|
+
};
|
|
22007
|
+
return /* @__PURE__ */ jsxs4("div", { className: "input-field input-field--number", children: [
|
|
22008
|
+
/* @__PURE__ */ jsxs4("label", { className: "input-field__label", children: [
|
|
22009
|
+
label,
|
|
22010
|
+
required2 && /* @__PURE__ */ jsx4("span", { className: "input-field__required", children: "*" })
|
|
22011
|
+
] }),
|
|
22012
|
+
/* @__PURE__ */ jsx4(
|
|
22013
|
+
"input",
|
|
22014
|
+
{
|
|
22015
|
+
type: "number",
|
|
22016
|
+
value: value ?? "",
|
|
22017
|
+
onChange: handleChange,
|
|
22018
|
+
min,
|
|
22019
|
+
max,
|
|
22020
|
+
className: "input-field__input"
|
|
22021
|
+
}
|
|
22022
|
+
)
|
|
22023
|
+
] });
|
|
22024
|
+
}
|
|
22025
|
+
|
|
22026
|
+
// lib/chat/components/input-fields/TextField.tsx
|
|
22027
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
22028
|
+
function TextField({ field, value, onChange }) {
|
|
22029
|
+
const { label, placeholder, multiline, required: required2 } = field;
|
|
22030
|
+
if (multiline) {
|
|
22031
|
+
return /* @__PURE__ */ jsxs5("div", { className: "input-field input-field--text", children: [
|
|
22032
|
+
/* @__PURE__ */ jsxs5("label", { className: "input-field__label", children: [
|
|
22033
|
+
label,
|
|
22034
|
+
required2 && /* @__PURE__ */ jsx5("span", { className: "input-field__required", children: "*" })
|
|
22035
|
+
] }),
|
|
22036
|
+
/* @__PURE__ */ jsx5(
|
|
22037
|
+
"textarea",
|
|
22038
|
+
{
|
|
22039
|
+
value: value ?? "",
|
|
22040
|
+
onChange: (e) => onChange(e.target.value),
|
|
22041
|
+
placeholder,
|
|
22042
|
+
className: "input-field__textarea",
|
|
22043
|
+
rows: 4
|
|
22044
|
+
}
|
|
22045
|
+
)
|
|
22046
|
+
] });
|
|
22047
|
+
}
|
|
22048
|
+
return /* @__PURE__ */ jsxs5("div", { className: "input-field input-field--text", children: [
|
|
22049
|
+
/* @__PURE__ */ jsxs5("label", { className: "input-field__label", children: [
|
|
22050
|
+
label,
|
|
22051
|
+
required2 && /* @__PURE__ */ jsx5("span", { className: "input-field__required", children: "*" })
|
|
22052
|
+
] }),
|
|
22053
|
+
/* @__PURE__ */ jsx5(
|
|
22054
|
+
"input",
|
|
22055
|
+
{
|
|
22056
|
+
type: "text",
|
|
22057
|
+
value: value ?? "",
|
|
22058
|
+
onChange: (e) => onChange(e.target.value),
|
|
22059
|
+
placeholder,
|
|
22060
|
+
className: "input-field__input"
|
|
22061
|
+
}
|
|
22062
|
+
)
|
|
22063
|
+
] });
|
|
22064
|
+
}
|
|
22065
|
+
|
|
22066
|
+
// lib/chat/components/input-fields/FieldRenderer.tsx
|
|
22067
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
22068
|
+
function FieldRenderer({ field, value, onChange }) {
|
|
22069
|
+
switch (field.type) {
|
|
22070
|
+
case "choices":
|
|
22071
|
+
return /* @__PURE__ */ jsx6(
|
|
22072
|
+
ChoicesField,
|
|
22073
|
+
{
|
|
22074
|
+
field,
|
|
22075
|
+
value,
|
|
22076
|
+
onChange
|
|
22077
|
+
}
|
|
22078
|
+
);
|
|
22079
|
+
case "text":
|
|
22080
|
+
return /* @__PURE__ */ jsx6(
|
|
22081
|
+
TextField,
|
|
22082
|
+
{
|
|
22083
|
+
field,
|
|
22084
|
+
value,
|
|
22085
|
+
onChange
|
|
22086
|
+
}
|
|
22087
|
+
);
|
|
22088
|
+
case "number":
|
|
22089
|
+
return /* @__PURE__ */ jsx6(
|
|
22090
|
+
NumberField,
|
|
22091
|
+
{
|
|
22092
|
+
field,
|
|
22093
|
+
value,
|
|
22094
|
+
onChange
|
|
22095
|
+
}
|
|
22096
|
+
);
|
|
22097
|
+
case "checkbox":
|
|
22098
|
+
return /* @__PURE__ */ jsx6(
|
|
22099
|
+
CheckboxField,
|
|
22100
|
+
{
|
|
22101
|
+
field,
|
|
22102
|
+
value,
|
|
22103
|
+
onChange
|
|
22104
|
+
}
|
|
22105
|
+
);
|
|
22106
|
+
case "date":
|
|
22107
|
+
return /* @__PURE__ */ jsx6(
|
|
22108
|
+
DateField,
|
|
22109
|
+
{
|
|
22110
|
+
field,
|
|
22111
|
+
value,
|
|
22112
|
+
onChange
|
|
22113
|
+
}
|
|
22114
|
+
);
|
|
22115
|
+
default:
|
|
22116
|
+
const _exhaustive = field;
|
|
22117
|
+
return null;
|
|
22118
|
+
}
|
|
22119
|
+
}
|
|
22120
|
+
|
|
22121
|
+
// lib/chat/components/InputFormOverlay.tsx
|
|
22122
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
22123
|
+
function InputFormOverlay({ args, onComplete }) {
|
|
22124
|
+
const {
|
|
22125
|
+
title,
|
|
22126
|
+
description,
|
|
22127
|
+
fields,
|
|
22128
|
+
submitLabel = "Submit",
|
|
22129
|
+
cancelLabel = "Cancel",
|
|
22130
|
+
allowFreeformResponse = true
|
|
22131
|
+
} = args;
|
|
22132
|
+
const [values, setValues] = useState3(() => {
|
|
22133
|
+
const initial = {};
|
|
22134
|
+
for (const field of fields) {
|
|
22135
|
+
if (field.defaultValue !== void 0) {
|
|
22136
|
+
initial[field.name] = field.defaultValue;
|
|
22137
|
+
}
|
|
22138
|
+
}
|
|
22139
|
+
return initial;
|
|
22140
|
+
});
|
|
22141
|
+
const [freeformText, setFreeformText] = useState3("");
|
|
22142
|
+
const [showFreeform, setShowFreeform] = useState3(false);
|
|
22143
|
+
const handleFieldChange = (name21, value) => {
|
|
22144
|
+
setValues((prev) => ({ ...prev, [name21]: value }));
|
|
22145
|
+
};
|
|
22146
|
+
const handleSubmit = (e) => {
|
|
22147
|
+
e.preventDefault();
|
|
22148
|
+
onComplete({ values });
|
|
22149
|
+
};
|
|
22150
|
+
const handleCancel = () => {
|
|
22151
|
+
onComplete({ cancelled: true });
|
|
22152
|
+
};
|
|
22153
|
+
const handleFreeformSubmit = () => {
|
|
22154
|
+
if (freeformText.trim()) {
|
|
22155
|
+
onComplete({ freeformResponse: freeformText.trim() });
|
|
22156
|
+
}
|
|
22157
|
+
};
|
|
22158
|
+
const isFormValid = fields.every((field) => {
|
|
22159
|
+
if (!("required" in field) || !field.required) return true;
|
|
22160
|
+
const value = values[field.name];
|
|
22161
|
+
if (value === void 0 || value === null || value === "") return false;
|
|
22162
|
+
if (Array.isArray(value) && value.length === 0) return false;
|
|
22163
|
+
return true;
|
|
22164
|
+
});
|
|
22165
|
+
return /* @__PURE__ */ jsx7("div", { className: "input-form-overlay", children: /* @__PURE__ */ jsx7("div", { className: "input-form-overlay__content", children: !showFreeform ? /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className: "input-form-overlay__form", children: [
|
|
22166
|
+
/* @__PURE__ */ jsxs6("div", { className: "input-form-overlay__scrollable", children: [
|
|
22167
|
+
title && /* @__PURE__ */ jsx7("h3", { className: "input-form-overlay__title", children: title }),
|
|
22168
|
+
description && /* @__PURE__ */ jsx7("p", { className: "input-form-overlay__description", children: description }),
|
|
22169
|
+
/* @__PURE__ */ jsx7("div", { className: "input-form-overlay__fields", children: fields.map((field) => /* @__PURE__ */ jsx7(
|
|
22170
|
+
FieldRenderer,
|
|
22171
|
+
{
|
|
22172
|
+
field,
|
|
22173
|
+
value: values[field.name],
|
|
22174
|
+
onChange: (v) => handleFieldChange(field.name, v)
|
|
22175
|
+
},
|
|
22176
|
+
field.name
|
|
22177
|
+
)) })
|
|
22178
|
+
] }),
|
|
22179
|
+
/* @__PURE__ */ jsx7("div", { className: "input-form-overlay__footer", children: /* @__PURE__ */ jsxs6("div", { className: "input-form-overlay__actions", children: [
|
|
22180
|
+
/* @__PURE__ */ jsx7(
|
|
22181
|
+
"button",
|
|
22182
|
+
{
|
|
22183
|
+
type: "submit",
|
|
22184
|
+
disabled: !isFormValid,
|
|
22185
|
+
className: "input-form-overlay__button input-form-overlay__button--primary",
|
|
22186
|
+
children: submitLabel
|
|
22187
|
+
}
|
|
22188
|
+
),
|
|
22189
|
+
/* @__PURE__ */ jsx7(
|
|
22190
|
+
"button",
|
|
22191
|
+
{
|
|
22192
|
+
type: "button",
|
|
22193
|
+
onClick: handleCancel,
|
|
22194
|
+
className: "input-form-overlay__button input-form-overlay__button--secondary",
|
|
22195
|
+
children: cancelLabel
|
|
22196
|
+
}
|
|
22197
|
+
),
|
|
22198
|
+
allowFreeformResponse && /* @__PURE__ */ jsx7(
|
|
22199
|
+
"button",
|
|
22200
|
+
{
|
|
22201
|
+
type: "button",
|
|
22202
|
+
className: "input-form-overlay__freeform-toggle",
|
|
22203
|
+
onClick: () => setShowFreeform(true),
|
|
22204
|
+
children: "Or type a response instead..."
|
|
22205
|
+
}
|
|
22206
|
+
)
|
|
22207
|
+
] }) })
|
|
22208
|
+
] }) : /* @__PURE__ */ jsxs6("div", { className: "input-form-overlay__freeform", children: [
|
|
22209
|
+
/* @__PURE__ */ jsx7("div", { className: "input-form-overlay__freeform-body", children: /* @__PURE__ */ jsx7(
|
|
22210
|
+
"textarea",
|
|
22211
|
+
{
|
|
22212
|
+
value: freeformText,
|
|
22213
|
+
onChange: (e) => setFreeformText(e.target.value),
|
|
22214
|
+
placeholder: "Type your response...",
|
|
22215
|
+
className: "input-form-overlay__freeform-input",
|
|
22216
|
+
autoFocus: true,
|
|
22217
|
+
rows: 4
|
|
22218
|
+
}
|
|
22219
|
+
) }),
|
|
22220
|
+
/* @__PURE__ */ jsx7("div", { className: "input-form-overlay__footer", children: /* @__PURE__ */ jsxs6("div", { className: "input-form-overlay__actions", children: [
|
|
22221
|
+
/* @__PURE__ */ jsx7(
|
|
22222
|
+
"button",
|
|
22223
|
+
{
|
|
22224
|
+
type: "button",
|
|
22225
|
+
onClick: handleFreeformSubmit,
|
|
22226
|
+
disabled: !freeformText.trim(),
|
|
22227
|
+
className: "input-form-overlay__button input-form-overlay__button--primary",
|
|
22228
|
+
children: "Send"
|
|
22229
|
+
}
|
|
22230
|
+
),
|
|
22231
|
+
/* @__PURE__ */ jsx7(
|
|
22232
|
+
"button",
|
|
22233
|
+
{
|
|
22234
|
+
type: "button",
|
|
22235
|
+
onClick: () => setShowFreeform(false),
|
|
22236
|
+
className: "input-form-overlay__button input-form-overlay__button--secondary",
|
|
22237
|
+
children: "Back to form"
|
|
22238
|
+
}
|
|
22239
|
+
)
|
|
22240
|
+
] }) })
|
|
22241
|
+
] }) }) });
|
|
22242
|
+
}
|
|
22243
|
+
|
|
21718
22244
|
// lib/chat/components/SpeechToTextButton.tsx
|
|
21719
22245
|
import { Mic, MicOff } from "lucide-react";
|
|
21720
22246
|
import {
|
|
21721
22247
|
useCallback as useCallback2,
|
|
21722
22248
|
useEffect as useEffect2,
|
|
21723
22249
|
useRef as useRef2,
|
|
21724
|
-
useState as
|
|
22250
|
+
useState as useState4
|
|
21725
22251
|
} from "react";
|
|
21726
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
22252
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
21727
22253
|
var getSpeechRecognitionCtor = () => {
|
|
21728
22254
|
if (typeof window === "undefined") return null;
|
|
21729
22255
|
const win = window;
|
|
@@ -21742,11 +22268,11 @@ function SpeechToTextButton({
|
|
|
21742
22268
|
disabled,
|
|
21743
22269
|
className
|
|
21744
22270
|
}) {
|
|
21745
|
-
const [isListening, setIsListening] =
|
|
21746
|
-
const [isSupported, setIsSupported] =
|
|
21747
|
-
const [countdown, setCountdown] =
|
|
22271
|
+
const [isListening, setIsListening] = useState4(false);
|
|
22272
|
+
const [isSupported, setIsSupported] = useState4(false);
|
|
22273
|
+
const [countdown, setCountdown] = useState4(0);
|
|
21748
22274
|
const recognitionRef = useRef2(null);
|
|
21749
|
-
const [countdownActive, setCountdownActive] =
|
|
22275
|
+
const [countdownActive, setCountdownActive] = useState4(false);
|
|
21750
22276
|
const silenceTimer = useRef2(null);
|
|
21751
22277
|
const finalTimer = useRef2(null);
|
|
21752
22278
|
const finalTextRef = useRef2("");
|
|
@@ -21956,7 +22482,7 @@ function SpeechToTextButton({
|
|
|
21956
22482
|
if (!isSupported) {
|
|
21957
22483
|
return null;
|
|
21958
22484
|
}
|
|
21959
|
-
return /* @__PURE__ */
|
|
22485
|
+
return /* @__PURE__ */ jsxs7(
|
|
21960
22486
|
"button",
|
|
21961
22487
|
{
|
|
21962
22488
|
type: "button",
|
|
@@ -21970,8 +22496,8 @@ function SpeechToTextButton({
|
|
|
21970
22496
|
"aria-pressed": isListening,
|
|
21971
22497
|
"aria-label": "Toggle microphone",
|
|
21972
22498
|
children: [
|
|
21973
|
-
isListening ? /* @__PURE__ */
|
|
21974
|
-
finalDelay > 0 && isListening && countdownActive && /* @__PURE__ */
|
|
22499
|
+
isListening ? /* @__PURE__ */ jsx8(Mic, { className: "chat-widget__mic-icon" }) : /* @__PURE__ */ jsx8(MicOff, { className: "chat-widget__mic-icon" }),
|
|
22500
|
+
finalDelay > 0 && isListening && countdownActive && /* @__PURE__ */ jsx8("span", { className: "chat-widget__mic-bar", "aria-hidden": "true", children: /* @__PURE__ */ jsx8(
|
|
21975
22501
|
"span",
|
|
21976
22502
|
{
|
|
21977
22503
|
className: "chat-widget__mic-bar-fill",
|
|
@@ -21983,16 +22509,114 @@ function SpeechToTextButton({
|
|
|
21983
22509
|
);
|
|
21984
22510
|
}
|
|
21985
22511
|
|
|
22512
|
+
// lib/chat/components/ToolApprovalOverlay.css
|
|
22513
|
+
styleInject(".tool-approval-overlay {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n top: 0;\n z-index: 10;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n background-color: var(--chat-overlay-bg);\n}\n@keyframes slideUp {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n.tool-approval-overlay__content {\n animation: slideUp 0.2s ease-out;\n display: flex;\n flex-direction: column;\n background-color: var(--chat-background);\n border-top: 1px solid var(--chat-border);\n border-radius: var(--chat-radius) var(--chat-radius) 0 0;\n box-shadow: var(--chat-shadow-sm);\n max-height: 80%;\n font-family: var(--chat-font-family);\n transition: max-height 0.2s ease-out;\n}\n.tool-approval-overlay__content--loading {\n max-height: 160px;\n}\n.tool-approval-overlay__scrollable {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding: 1rem 1.25rem;\n}\n.tool-approval-overlay__title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--chat-assistant-text);\n margin: 0 0 0.375rem 0;\n}\n.tool-approval-overlay__description {\n font-size: 0.8125rem;\n color: var(--chat-input-placeholder);\n margin: 0 0 1rem 0;\n line-height: 1.4;\n}\n.tool-approval-overlay__tool-name {\n background-color: var(--chat-border);\n padding: 0.125rem 0.375rem;\n border-radius: 0.25rem;\n font-size: 0.8125rem;\n}\n.tool-approval-overlay__args {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n.tool-approval-overlay__arg {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n.tool-approval-overlay__arg-label {\n font-size: 0.6875rem;\n font-weight: 500;\n color: var(--chat-input-placeholder);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n.tool-approval-overlay__arg-value {\n font-size: 0.875rem;\n color: var(--chat-assistant-text);\n white-space: pre-wrap;\n word-break: break-word;\n}\n.tool-approval-overlay__no-args {\n font-size: 0.8125rem;\n color: var(--chat-input-placeholder);\n font-style: italic;\n}\n.tool-approval-overlay__footer {\n flex-shrink: 0;\n padding: 0.5rem 1.25rem;\n border-top: 1px solid var(--chat-border);\n}\n.tool-approval-overlay__actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n justify-content: flex-start;\n}\n.tool-approval-overlay__button {\n padding: 0.5rem 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: calc(var(--chat-radius) * 0.5);\n cursor: pointer;\n transition: all 0.15s ease-in-out;\n border: none;\n}\n.tool-approval-overlay__button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.tool-approval-overlay__button--primary {\n background-color: var(--chat-primary);\n color: var(--chat-primary-text);\n}\n.tool-approval-overlay__button--primary:hover:not(:disabled) {\n background-color: var(--chat-primary-hover);\n}\n.tool-approval-overlay__button--secondary {\n background-color: var(--chat-border);\n color: var(--chat-assistant-text);\n}\n.tool-approval-overlay__button--secondary:hover:not(:disabled) {\n opacity: 0.8;\n}\n.tool-approval-overlay__freeform-toggle {\n padding: 0.5rem 0;\n font-size: 0.75rem;\n color: var(--chat-input-placeholder);\n background: none;\n border: none;\n cursor: pointer;\n transition: color 0.15s ease-in-out;\n white-space: nowrap;\n}\n.tool-approval-overlay__freeform-toggle:hover {\n color: var(--chat-primary);\n text-decoration: underline;\n}\n.tool-approval-overlay__freeform {\n display: flex;\n flex-direction: column;\n}\n.tool-approval-overlay__freeform-body {\n padding: 1rem 1.25rem;\n}\n.tool-approval-overlay__freeform-input {\n width: 100%;\n padding: 0.75rem;\n font-size: 0.875rem;\n font-family: var(--chat-font-family);\n color: var(--chat-input-text);\n background-color: var(--chat-input-bg);\n border: 1px solid var(--chat-border);\n border-radius: calc(var(--chat-radius) * 0.5);\n resize: vertical;\n min-height: 80px;\n box-sizing: border-box;\n}\n.tool-approval-overlay__freeform-input:focus {\n outline: none;\n border-color: var(--chat-primary);\n box-shadow: 0 0 0 2px var(--chat-primary-subtle);\n}\n.tool-approval-overlay__freeform-input::-moz-placeholder {\n color: var(--chat-input-placeholder);\n}\n.tool-approval-overlay__freeform-input::placeholder {\n color: var(--chat-input-placeholder);\n}\n.tool-approval-overlay__loading {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 160px;\n}\n.tool-approval-overlay__loading-spinner {\n width: 24px;\n height: 24px;\n border: 2px solid var(--chat-border);\n border-top-color: var(--chat-primary);\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n}\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n");
|
|
22514
|
+
|
|
22515
|
+
// lib/chat/components/ToolApprovalOverlay.tsx
|
|
22516
|
+
import { useState as useState5 } from "react";
|
|
22517
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
22518
|
+
function ToolApprovalOverlay({ approval, config: config2, configLoading, onApprove, onDeny }) {
|
|
22519
|
+
const { toolName, args } = approval;
|
|
22520
|
+
const [showFreeform, setShowFreeform] = useState5(false);
|
|
22521
|
+
const [freeformText, setFreeformText] = useState5("");
|
|
22522
|
+
const handleApprove = () => {
|
|
22523
|
+
onApprove();
|
|
22524
|
+
};
|
|
22525
|
+
const handleDeny = () => {
|
|
22526
|
+
onDeny();
|
|
22527
|
+
};
|
|
22528
|
+
const handleFreeformSubmit = () => {
|
|
22529
|
+
if (freeformText.trim()) {
|
|
22530
|
+
onDeny(freeformText.trim());
|
|
22531
|
+
}
|
|
22532
|
+
};
|
|
22533
|
+
const entries = Object.entries(args);
|
|
22534
|
+
const title = config2?.message || `Approve ${toolName} execution?`;
|
|
22535
|
+
const approveLabel = config2?.approveLabel || "Approve";
|
|
22536
|
+
const denyLabel = config2?.denyLabel || "Deny";
|
|
22537
|
+
return /* @__PURE__ */ jsx9("div", { className: "tool-approval-overlay", children: /* @__PURE__ */ jsx9("div", { className: `tool-approval-overlay__content ${configLoading ? "tool-approval-overlay__content--loading" : ""}`, children: configLoading ? /* @__PURE__ */ jsx9("div", { className: "tool-approval-overlay__loading", children: /* @__PURE__ */ jsx9("div", { className: "tool-approval-overlay__loading-spinner" }) }) : !showFreeform ? /* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
22538
|
+
/* @__PURE__ */ jsxs8("div", { className: "tool-approval-overlay__scrollable", children: [
|
|
22539
|
+
/* @__PURE__ */ jsx9("h3", { className: "tool-approval-overlay__title", children: title }),
|
|
22540
|
+
entries.length > 0 ? /* @__PURE__ */ jsx9("div", { className: "tool-approval-overlay__args", children: entries.map(([key, value]) => /* @__PURE__ */ jsxs8("div", { className: "tool-approval-overlay__arg", children: [
|
|
22541
|
+
/* @__PURE__ */ jsx9("label", { className: "tool-approval-overlay__arg-label", children: key }),
|
|
22542
|
+
/* @__PURE__ */ jsx9("div", { className: "tool-approval-overlay__arg-value", children: typeof value === "string" ? value : JSON.stringify(value, null, 2) })
|
|
22543
|
+
] }, key)) }) : /* @__PURE__ */ jsx9("p", { className: "tool-approval-overlay__no-args", children: "No inputs provided." })
|
|
22544
|
+
] }),
|
|
22545
|
+
/* @__PURE__ */ jsx9("div", { className: "tool-approval-overlay__footer", children: /* @__PURE__ */ jsxs8("div", { className: "tool-approval-overlay__actions", children: [
|
|
22546
|
+
/* @__PURE__ */ jsx9(
|
|
22547
|
+
"button",
|
|
22548
|
+
{
|
|
22549
|
+
type: "button",
|
|
22550
|
+
onClick: handleApprove,
|
|
22551
|
+
className: "tool-approval-overlay__button tool-approval-overlay__button--primary",
|
|
22552
|
+
children: approveLabel
|
|
22553
|
+
}
|
|
22554
|
+
),
|
|
22555
|
+
/* @__PURE__ */ jsx9(
|
|
22556
|
+
"button",
|
|
22557
|
+
{
|
|
22558
|
+
type: "button",
|
|
22559
|
+
onClick: handleDeny,
|
|
22560
|
+
className: "tool-approval-overlay__button tool-approval-overlay__button--secondary",
|
|
22561
|
+
children: denyLabel
|
|
22562
|
+
}
|
|
22563
|
+
),
|
|
22564
|
+
/* @__PURE__ */ jsx9(
|
|
22565
|
+
"button",
|
|
22566
|
+
{
|
|
22567
|
+
type: "button",
|
|
22568
|
+
onClick: () => setShowFreeform(true),
|
|
22569
|
+
className: "tool-approval-overlay__freeform-toggle",
|
|
22570
|
+
children: "Or type a response instead..."
|
|
22571
|
+
}
|
|
22572
|
+
)
|
|
22573
|
+
] }) })
|
|
22574
|
+
] }) : /* @__PURE__ */ jsxs8("div", { className: "tool-approval-overlay__freeform", children: [
|
|
22575
|
+
/* @__PURE__ */ jsx9("div", { className: "tool-approval-overlay__freeform-body", children: /* @__PURE__ */ jsx9(
|
|
22576
|
+
"textarea",
|
|
22577
|
+
{
|
|
22578
|
+
value: freeformText,
|
|
22579
|
+
onChange: (e) => setFreeformText(e.target.value),
|
|
22580
|
+
placeholder: "Tell the assistant what's wrong or what you'd like instead...",
|
|
22581
|
+
className: "tool-approval-overlay__freeform-input",
|
|
22582
|
+
autoFocus: true,
|
|
22583
|
+
rows: 4
|
|
22584
|
+
}
|
|
22585
|
+
) }),
|
|
22586
|
+
/* @__PURE__ */ jsx9("div", { className: "tool-approval-overlay__footer", children: /* @__PURE__ */ jsxs8("div", { className: "tool-approval-overlay__actions", children: [
|
|
22587
|
+
/* @__PURE__ */ jsx9(
|
|
22588
|
+
"button",
|
|
22589
|
+
{
|
|
22590
|
+
type: "button",
|
|
22591
|
+
onClick: handleFreeformSubmit,
|
|
22592
|
+
disabled: !freeformText.trim(),
|
|
22593
|
+
className: "tool-approval-overlay__button tool-approval-overlay__button--primary",
|
|
22594
|
+
children: "Send"
|
|
22595
|
+
}
|
|
22596
|
+
),
|
|
22597
|
+
/* @__PURE__ */ jsx9(
|
|
22598
|
+
"button",
|
|
22599
|
+
{
|
|
22600
|
+
type: "button",
|
|
22601
|
+
onClick: () => setShowFreeform(false),
|
|
22602
|
+
className: "tool-approval-overlay__button tool-approval-overlay__button--secondary",
|
|
22603
|
+
children: "Back"
|
|
22604
|
+
}
|
|
22605
|
+
)
|
|
22606
|
+
] }) })
|
|
22607
|
+
] }) }) });
|
|
22608
|
+
}
|
|
22609
|
+
|
|
21986
22610
|
// lib/chat/display-modes/BriefDisplayMode.tsx
|
|
21987
|
-
import React2, { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3, useState as
|
|
21988
|
-
import { Fragment, jsx as
|
|
22611
|
+
import React2, { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3, useState as useState6 } from "react";
|
|
22612
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
21989
22613
|
function CollapsedDisplay({
|
|
21990
22614
|
collapsed,
|
|
21991
22615
|
renderPart,
|
|
21992
22616
|
itemKey
|
|
21993
22617
|
}) {
|
|
21994
|
-
const [isExpanded, setIsExpanded] =
|
|
21995
|
-
const [isAnimating, setIsAnimating] =
|
|
22618
|
+
const [isExpanded, setIsExpanded] = useState6(false);
|
|
22619
|
+
const [isAnimating, setIsAnimating] = useState6(false);
|
|
21996
22620
|
const contentRef = useRef3(null);
|
|
21997
22621
|
const partsCountRef = useRef3(collapsed.parts.length);
|
|
21998
22622
|
useEffect3(() => {
|
|
@@ -22010,19 +22634,19 @@ function CollapsedDisplay({
|
|
|
22010
22634
|
"chat-widget__collapsed",
|
|
22011
22635
|
isAnimating ? "chat-widget__collapsed--animating" : ""
|
|
22012
22636
|
].filter(Boolean).join(" ");
|
|
22013
|
-
return /* @__PURE__ */
|
|
22014
|
-
/* @__PURE__ */
|
|
22637
|
+
return /* @__PURE__ */ jsxs9("div", { className: collapsedClasses, children: [
|
|
22638
|
+
/* @__PURE__ */ jsx10(
|
|
22015
22639
|
"div",
|
|
22016
22640
|
{
|
|
22017
22641
|
className: `chat-widget__collapsed-content ${isExpanded ? "chat-widget__collapsed-content--expanded" : ""}`,
|
|
22018
|
-
children: /* @__PURE__ */
|
|
22642
|
+
children: /* @__PURE__ */ jsx10("div", { ref: contentRef, className: "chat-widget__collapsed-content-inner", children: collapsed.parts.map((part, idx) => /* @__PURE__ */ jsx10("div", { children: renderPart(part, `${itemKey}-expanded-${idx}`) }, `${itemKey}-expanded-${idx}`)) })
|
|
22019
22643
|
}
|
|
22020
22644
|
),
|
|
22021
|
-
/* @__PURE__ */
|
|
22645
|
+
/* @__PURE__ */ jsxs9("div", { className: `chat-widget__collapsed-preview ${isExpanded ? "chat-widget__collapsed-preview--hidden" : ""}`, children: [
|
|
22022
22646
|
renderPart(collapsed.lastPart, `${itemKey}-preview`),
|
|
22023
|
-
/* @__PURE__ */
|
|
22647
|
+
/* @__PURE__ */ jsx10("div", { className: "chat-widget__collapsed-gradient" })
|
|
22024
22648
|
] }),
|
|
22025
|
-
/* @__PURE__ */
|
|
22649
|
+
/* @__PURE__ */ jsx10(
|
|
22026
22650
|
"button",
|
|
22027
22651
|
{
|
|
22028
22652
|
type: "button",
|
|
@@ -22117,9 +22741,9 @@ function BriefDisplayMode({
|
|
|
22117
22741
|
() => computeCollapsedView(sections, messageId),
|
|
22118
22742
|
[sections, messageId]
|
|
22119
22743
|
);
|
|
22120
|
-
return /* @__PURE__ */
|
|
22744
|
+
return /* @__PURE__ */ jsx10(Fragment2, { children: viewItems.map((viewItem) => {
|
|
22121
22745
|
if (viewItem.type === "collapsed") {
|
|
22122
|
-
return /* @__PURE__ */
|
|
22746
|
+
return /* @__PURE__ */ jsx10(
|
|
22123
22747
|
CollapsedDisplay,
|
|
22124
22748
|
{
|
|
22125
22749
|
collapsed: viewItem.collapsed,
|
|
@@ -22130,11 +22754,11 @@ function BriefDisplayMode({
|
|
|
22130
22754
|
);
|
|
22131
22755
|
}
|
|
22132
22756
|
if (viewItem.type === "parts") {
|
|
22133
|
-
return /* @__PURE__ */
|
|
22757
|
+
return /* @__PURE__ */ jsx10(React2.Fragment, { children: viewItem.parts.map((part, idx) => /* @__PURE__ */ jsx10("div", { children: renderPart(part, `${viewItem.key}-part-${idx}`) }, `${viewItem.key}-part-${idx}`)) }, viewItem.key);
|
|
22134
22758
|
}
|
|
22135
22759
|
if (viewItem.type === "group") {
|
|
22136
|
-
const children = /* @__PURE__ */
|
|
22137
|
-
viewItem.collapsedParts && /* @__PURE__ */
|
|
22760
|
+
const children = /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
22761
|
+
viewItem.collapsedParts && /* @__PURE__ */ jsx10(
|
|
22138
22762
|
CollapsedDisplay,
|
|
22139
22763
|
{
|
|
22140
22764
|
collapsed: viewItem.collapsedParts,
|
|
@@ -22142,7 +22766,7 @@ function BriefDisplayMode({
|
|
|
22142
22766
|
itemKey: `${viewItem.key}-collapsed`
|
|
22143
22767
|
}
|
|
22144
22768
|
),
|
|
22145
|
-
viewItem.currentParts.map((part, idx) => /* @__PURE__ */
|
|
22769
|
+
viewItem.currentParts.map((part, idx) => /* @__PURE__ */ jsx10("div", { children: renderPart(part, `${viewItem.key}-current-${idx}`) }, `${viewItem.key}-current-${idx}`))
|
|
22146
22770
|
] });
|
|
22147
22771
|
return renderGroup(viewItem.groupName, viewItem.key, children);
|
|
22148
22772
|
}
|
|
@@ -22152,22 +22776,22 @@ function BriefDisplayMode({
|
|
|
22152
22776
|
|
|
22153
22777
|
// lib/chat/display-modes/FullDisplayMode.tsx
|
|
22154
22778
|
import React3 from "react";
|
|
22155
|
-
import { Fragment as
|
|
22779
|
+
import { Fragment as Fragment3, jsx as jsx11 } from "react/jsx-runtime";
|
|
22156
22780
|
function FullDisplayMode({
|
|
22157
22781
|
sections,
|
|
22158
22782
|
messageId,
|
|
22159
22783
|
renderPart,
|
|
22160
22784
|
renderGroup
|
|
22161
22785
|
}) {
|
|
22162
|
-
return /* @__PURE__ */
|
|
22786
|
+
return /* @__PURE__ */ jsx11(Fragment3, { children: sections.map((section, sectionIdx) => {
|
|
22163
22787
|
const sectionKey = `${messageId}-section-${sectionIdx}`;
|
|
22164
22788
|
if (section.type === "step") {
|
|
22165
|
-
return /* @__PURE__ */
|
|
22789
|
+
return /* @__PURE__ */ jsx11(React3.Fragment, { children: section.parts.map((part, partIdx) => /* @__PURE__ */ jsx11("div", { children: renderPart(part, `${sectionKey}-part-${partIdx}`) }, `${sectionKey}-part-${partIdx}`)) }, sectionKey);
|
|
22166
22790
|
}
|
|
22167
22791
|
if (section.type === "group") {
|
|
22168
22792
|
const groupKey = `${messageId}-group-${section.groupName}`;
|
|
22169
|
-
const children = section.parts.map((part, partIdx) => /* @__PURE__ */
|
|
22170
|
-
return renderGroup(section.groupName, groupKey, /* @__PURE__ */
|
|
22793
|
+
const children = section.parts.map((part, partIdx) => /* @__PURE__ */ jsx11("div", { children: renderPart(part, `${groupKey}-part-${partIdx}`) }, `${groupKey}-part-${partIdx}`));
|
|
22794
|
+
return renderGroup(section.groupName, groupKey, /* @__PURE__ */ jsx11(Fragment3, { children }));
|
|
22171
22795
|
}
|
|
22172
22796
|
return null;
|
|
22173
22797
|
}) });
|
|
@@ -25637,12 +26261,12 @@ function remarkGfm(options) {
|
|
|
25637
26261
|
}
|
|
25638
26262
|
|
|
25639
26263
|
// lib/chat/components/MessageFeedback.css
|
|
25640
|
-
styleInject(".chat-widget__feedback {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n margin-top: 0.35rem;\n}\n.chat-widget__feedback-button {\n border: none;\n background: transparent;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n color:
|
|
26264
|
+
styleInject(".chat-widget__feedback {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n margin-top: 0.35rem;\n}\n.chat-widget__feedback-button {\n border: none;\n background: transparent;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n color: var(--chat-text-disabled);\n cursor: pointer;\n border-radius: 0.35rem;\n transition: all 0.15s ease;\n}\n.chat-widget__feedback-button:hover:not(:disabled) {\n background: var(--chat-primary-subtle);\n color: var(--chat-text-muted);\n}\n.chat-widget__feedback-button:disabled {\n cursor: default;\n opacity: 0.5;\n}\n.chat-widget__feedback-button--positive.chat-widget__feedback-button--selected {\n color: var(--chat-success);\n background: var(--chat-success-bg);\n}\n.chat-widget__feedback-button--negative.chat-widget__feedback-button--selected {\n color: var(--chat-error);\n background: var(--chat-error-bg);\n}\n.chat-widget__feedback-button--comment.chat-widget__feedback-button--selected {\n background: var(--chat-primary-subtle);\n}\n.chat-widget__feedback-button--comment.chat-widget__feedback-button--has-content {\n color: var(--chat-primary);\n}\n.chat-widget__feedback-icon {\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__feedback-comment-section {\n margin-top: 0.75rem;\n background: var(--chat-background);\n border: 1px solid var(--chat-border);\n border-radius: 0.5rem;\n padding: 0.75rem;\n width: 100%;\n max-width: 400px;\n}\n.chat-widget__feedback-comment-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 0.5rem;\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--chat-text);\n}\n.chat-widget__feedback-comment-required {\n font-size: 0.6875rem;\n font-weight: 500;\n color: var(--chat-error);\n background: var(--chat-error-bg);\n padding: 0.125rem 0.375rem;\n border-radius: 0.25rem;\n}\n.chat-widget__feedback-comment-body {\n display: flex;\n gap: 0.5rem;\n align-items: flex-start;\n}\n.chat-widget__feedback-textarea {\n flex: 1;\n min-height: 60px;\n padding: 0.625rem;\n border: 1px solid var(--chat-border);\n border-radius: 0.35rem;\n font-size: 0.875rem;\n font-family: inherit;\n resize: vertical;\n color: var(--chat-input-text);\n background: var(--chat-input-bg);\n line-height: 1.5;\n}\n.chat-widget__feedback-textarea:focus {\n outline: none;\n border-color: var(--chat-primary);\n box-shadow: 0 0 0 2px var(--chat-primary-subtle);\n}\n.chat-widget__feedback-textarea::-moz-placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__feedback-textarea::placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__feedback-actions {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n}\n.chat-widget__feedback-cancel,\n.chat-widget__feedback-submit {\n padding: 0.35rem 0.75rem;\n font-size: 0.75rem;\n font-weight: 500;\n border-radius: 0.3rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.chat-widget__feedback-cancel {\n background: transparent;\n border: none;\n color: var(--chat-text-disabled);\n padding: 0.25rem 0.5rem;\n}\n.chat-widget__feedback-cancel:hover {\n color: var(--chat-text-muted);\n}\n.chat-widget__feedback-submit {\n background: var(--chat-primary);\n border: none;\n color: var(--chat-primary-text);\n}\n.chat-widget__feedback-submit:hover:not(:disabled) {\n background: var(--chat-primary-hover);\n}\n.chat-widget__feedback-submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.chat-widget__feedback-wrapper {\n position: relative;\n}\n");
|
|
25641
26265
|
|
|
25642
26266
|
// lib/chat/components/MessageFeedback.tsx
|
|
25643
26267
|
import { MessageSquare, MessageSquareText, ThumbsDown, ThumbsUp } from "lucide-react";
|
|
25644
|
-
import { useCallback as useCallback4, useEffect as useEffect4, useState as
|
|
25645
|
-
import { jsx as
|
|
26268
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useState as useState7 } from "react";
|
|
26269
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
25646
26270
|
var classNames = {
|
|
25647
26271
|
wrapper: "chat-widget__feedback-wrapper",
|
|
25648
26272
|
container: "chat-widget__feedback",
|
|
@@ -25670,11 +26294,11 @@ var MessageFeedback = ({
|
|
|
25670
26294
|
requireCommentForNegative = false,
|
|
25671
26295
|
onSubmit
|
|
25672
26296
|
}) => {
|
|
25673
|
-
const [savedRating, setSavedRating] =
|
|
25674
|
-
const [savedComment, setSavedComment] =
|
|
25675
|
-
const [pendingRating, setPendingRating] =
|
|
25676
|
-
const [showCommentBox, setShowCommentBox] =
|
|
25677
|
-
const [commentText, setCommentText] =
|
|
26297
|
+
const [savedRating, setSavedRating] = useState7(existingRating ?? null);
|
|
26298
|
+
const [savedComment, setSavedComment] = useState7(existingComment ?? "");
|
|
26299
|
+
const [pendingRating, setPendingRating] = useState7(null);
|
|
26300
|
+
const [showCommentBox, setShowCommentBox] = useState7(false);
|
|
26301
|
+
const [commentText, setCommentText] = useState7(existingComment ?? "");
|
|
25678
26302
|
useEffect4(() => {
|
|
25679
26303
|
if (existingRating) {
|
|
25680
26304
|
setSavedRating(existingRating);
|
|
@@ -25759,9 +26383,9 @@ var MessageFeedback = ({
|
|
|
25759
26383
|
const hasComment = savedComment.length > 0;
|
|
25760
26384
|
const canSubmitComment = (!isCommentRequired || commentText.trim().length > 0) && (displayRating || commentText.trim().length > 0 || hasComment);
|
|
25761
26385
|
const CommentIcon = hasComment ? MessageSquareText : MessageSquare;
|
|
25762
|
-
return /* @__PURE__ */
|
|
25763
|
-
/* @__PURE__ */
|
|
25764
|
-
/* @__PURE__ */
|
|
26386
|
+
return /* @__PURE__ */ jsxs10("div", { className: classNames.wrapper, children: [
|
|
26387
|
+
/* @__PURE__ */ jsxs10("div", { className: classNames.container, children: [
|
|
26388
|
+
/* @__PURE__ */ jsx12(
|
|
25765
26389
|
"button",
|
|
25766
26390
|
{
|
|
25767
26391
|
type: "button",
|
|
@@ -25770,10 +26394,10 @@ var MessageFeedback = ({
|
|
|
25770
26394
|
disabled: isSubmitting,
|
|
25771
26395
|
title: "Good response",
|
|
25772
26396
|
"aria-label": "Mark as good response",
|
|
25773
|
-
children: /* @__PURE__ */
|
|
26397
|
+
children: /* @__PURE__ */ jsx12(ThumbsUp, { className: classNames.icon })
|
|
25774
26398
|
}
|
|
25775
26399
|
),
|
|
25776
|
-
/* @__PURE__ */
|
|
26400
|
+
/* @__PURE__ */ jsx12(
|
|
25777
26401
|
"button",
|
|
25778
26402
|
{
|
|
25779
26403
|
type: "button",
|
|
@@ -25782,10 +26406,10 @@ var MessageFeedback = ({
|
|
|
25782
26406
|
disabled: isSubmitting,
|
|
25783
26407
|
title: "Could be improved",
|
|
25784
26408
|
"aria-label": "Mark as could be improved",
|
|
25785
|
-
children: /* @__PURE__ */
|
|
26409
|
+
children: /* @__PURE__ */ jsx12(ThumbsDown, { className: classNames.icon })
|
|
25786
26410
|
}
|
|
25787
26411
|
),
|
|
25788
|
-
/* @__PURE__ */
|
|
26412
|
+
/* @__PURE__ */ jsx12(
|
|
25789
26413
|
"button",
|
|
25790
26414
|
{
|
|
25791
26415
|
type: "button",
|
|
@@ -25794,14 +26418,14 @@ var MessageFeedback = ({
|
|
|
25794
26418
|
disabled: isSubmitting,
|
|
25795
26419
|
title: "Add comment",
|
|
25796
26420
|
"aria-label": "Add comment",
|
|
25797
|
-
children: /* @__PURE__ */
|
|
26421
|
+
children: /* @__PURE__ */ jsx12(CommentIcon, { className: classNames.icon })
|
|
25798
26422
|
}
|
|
25799
26423
|
)
|
|
25800
26424
|
] }),
|
|
25801
|
-
showCommentBox && /* @__PURE__ */
|
|
25802
|
-
/* @__PURE__ */
|
|
25803
|
-
/* @__PURE__ */
|
|
25804
|
-
/* @__PURE__ */
|
|
26425
|
+
showCommentBox && /* @__PURE__ */ jsxs10("div", { className: classNames.commentSection, children: [
|
|
26426
|
+
/* @__PURE__ */ jsx12("div", { className: classNames.commentHeader, children: isCommentRequired && /* @__PURE__ */ jsx12("span", { className: classNames.commentRequired, children: "Required" }) }),
|
|
26427
|
+
/* @__PURE__ */ jsxs10("div", { className: classNames.commentBody, children: [
|
|
26428
|
+
/* @__PURE__ */ jsx12(
|
|
25805
26429
|
"textarea",
|
|
25806
26430
|
{
|
|
25807
26431
|
className: classNames.textarea,
|
|
@@ -25811,8 +26435,8 @@ var MessageFeedback = ({
|
|
|
25811
26435
|
rows: 3
|
|
25812
26436
|
}
|
|
25813
26437
|
),
|
|
25814
|
-
/* @__PURE__ */
|
|
25815
|
-
/* @__PURE__ */
|
|
26438
|
+
/* @__PURE__ */ jsxs10("div", { className: classNames.actions, children: [
|
|
26439
|
+
/* @__PURE__ */ jsx12(
|
|
25816
26440
|
"button",
|
|
25817
26441
|
{
|
|
25818
26442
|
type: "button",
|
|
@@ -25822,7 +26446,7 @@ var MessageFeedback = ({
|
|
|
25822
26446
|
children: "Save"
|
|
25823
26447
|
}
|
|
25824
26448
|
),
|
|
25825
|
-
/* @__PURE__ */
|
|
26449
|
+
/* @__PURE__ */ jsx12(
|
|
25826
26450
|
"button",
|
|
25827
26451
|
{
|
|
25828
26452
|
type: "button",
|
|
@@ -25838,19 +26462,19 @@ var MessageFeedback = ({
|
|
|
25838
26462
|
};
|
|
25839
26463
|
|
|
25840
26464
|
// lib/chat/components/TagGroupDisplay.css
|
|
25841
|
-
styleInject('.tag-group {\n margin: 6px 0;\n}\n.tag-group-header {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: none;\n border: none;\n padding: 2px 6px 2px 2px;\n cursor: pointer;\n font-size: 13px;\n color:
|
|
26465
|
+
styleInject('.tag-group {\n margin: 6px 0;\n}\n.tag-group-header {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: none;\n border: none;\n padding: 2px 6px 2px 2px;\n cursor: pointer;\n font-size: 13px;\n color: var(--chat-text-muted);\n border-radius: 4px;\n transition: background-color 0.15s ease;\n}\n.tag-group-header:hover {\n background: var(--chat-background-secondary);\n}\n.tag-group-chevron {\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n transition: transform 0.15s ease;\n color: var(--chat-text-disabled);\n}\n.tag-group-chevron--expanded {\n transform: rotate(90deg);\n}\n.tag-group-label {\n font-weight: 500;\n color: var(--chat-text-secondary);\n}\n.tag-group-content {\n margin-left: 7px;\n padding-left: 12px;\n border-left: 2px solid var(--chat-border);\n margin-top: 4px;\n}\n.tag-group-item {\n margin: 4px 0;\n font-size: 13px;\n color: var(--chat-text-secondary);\n}\n.tag-group-item--text {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n}\n.tag-group-item--text::before {\n content: "\\2022";\n color: var(--chat-text-disabled);\n font-size: 14px;\n line-height: 1.4;\n flex-shrink: 0;\n}\n.tag-group-item .tool-call-item {\n margin: 0;\n}\n.tag-group-item--widget {\n display: block;\n margin: 8px 0;\n}\n.tag-group-item .chat-widget__markdown {\n margin: 0;\n}\n.tag-group-item .chat-widget__markdown p {\n margin: 0;\n}\n');
|
|
25842
26466
|
|
|
25843
26467
|
// lib/chat/components/TagGroupDisplay.tsx
|
|
25844
26468
|
import { ChevronRight } from "lucide-react";
|
|
25845
|
-
import { jsx as
|
|
26469
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
25846
26470
|
function TagGroupDisplay({
|
|
25847
26471
|
tagId,
|
|
25848
26472
|
isExpanded,
|
|
25849
26473
|
onToggle,
|
|
25850
26474
|
children
|
|
25851
26475
|
}) {
|
|
25852
|
-
return /* @__PURE__ */
|
|
25853
|
-
/* @__PURE__ */
|
|
26476
|
+
return /* @__PURE__ */ jsxs11("div", { className: "tag-group", children: [
|
|
26477
|
+
/* @__PURE__ */ jsxs11(
|
|
25854
26478
|
"button",
|
|
25855
26479
|
{
|
|
25856
26480
|
className: "tag-group-header",
|
|
@@ -25858,33 +26482,33 @@ function TagGroupDisplay({
|
|
|
25858
26482
|
"aria-expanded": isExpanded,
|
|
25859
26483
|
type: "button",
|
|
25860
26484
|
children: [
|
|
25861
|
-
/* @__PURE__ */
|
|
26485
|
+
/* @__PURE__ */ jsx13(
|
|
25862
26486
|
ChevronRight,
|
|
25863
26487
|
{
|
|
25864
26488
|
className: `tag-group-chevron ${isExpanded ? "tag-group-chevron--expanded" : ""}`,
|
|
25865
26489
|
"aria-hidden": "true"
|
|
25866
26490
|
}
|
|
25867
26491
|
),
|
|
25868
|
-
/* @__PURE__ */
|
|
26492
|
+
/* @__PURE__ */ jsx13("span", { className: "tag-group-label", children: tagId })
|
|
25869
26493
|
]
|
|
25870
26494
|
}
|
|
25871
26495
|
),
|
|
25872
|
-
isExpanded && /* @__PURE__ */
|
|
26496
|
+
isExpanded && /* @__PURE__ */ jsx13("div", { className: "tag-group-content", role: "region", children })
|
|
25873
26497
|
] });
|
|
25874
26498
|
}
|
|
25875
26499
|
|
|
25876
26500
|
// lib/chat/components/ToolCallDisplay.css
|
|
25877
|
-
styleInject(".tool-call-item {\n font-size: 13px;\n color:
|
|
26501
|
+
styleInject(".tool-call-item {\n font-size: 13px;\n color: var(--chat-text-muted);\n margin: 4px 0;\n}\n.tool-call-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n margin-bottom: 4px;\n}\n.tool-call-spinner {\n width: 12px;\n height: 12px;\n border: 2px solid var(--chat-border);\n border-top-color: var(--chat-text-muted);\n border-radius: 50%;\n animation: tool-call-spin 0.8s linear infinite;\n flex-shrink: 0;\n}\n@keyframes tool-call-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.tool-call-status-icon {\n width: 12px;\n height: 12px;\n border: 2px solid var(--chat-border);\n border-radius: 50%;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n.tool-call-status-icon--error {\n border-color: var(--chat-error);\n}\n.tool-call-status-icon__inner {\n width: 8px;\n height: 8px;\n}\n.tool-call-status-icon__inner--success {\n color: var(--chat-text-disabled);\n}\n.tool-call-status-icon__inner--error {\n color: var(--chat-error);\n}\n.tool-call-label {\n color: var(--chat-text-muted);\n}\n.tool-call-label code {\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n monospace;\n font-size: 12px;\n background: var(--chat-background-secondary);\n padding: 2px 6px;\n border-radius: 4px;\n color: var(--chat-text-secondary);\n}\n.tool-call-toggle {\n font-size: 9px;\n font-weight: 600;\n letter-spacing: 0.5px;\n text-transform: uppercase;\n color: var(--chat-text-muted);\n background: transparent;\n border: 1px solid var(--chat-border);\n border-radius: 3px;\n cursor: pointer;\n padding: 2px 6px;\n margin-left: 4px;\n transition: all 0.15s ease;\n}\n.tool-call-toggle:hover {\n color: var(--chat-text-secondary);\n border-color: var(--chat-text-disabled);\n background: var(--chat-background-secondary);\n}\n.tool-call-details {\n margin-top: 8px;\n margin-left: 16px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.tool-call-section {\n display: flex;\n gap: 4px;\n}\n.tool-call-section-label {\n flex-shrink: 0;\n font-size: 10px;\n font-weight: 600;\n color: var(--chat-text-muted);\n width: 28px;\n padding-top: 8px;\n text-align: right;\n}\n.tool-call-section-content-wrapper {\n flex: 1;\n position: relative;\n min-width: 0;\n}\n.tool-call-section-toggle {\n position: absolute;\n top: 4px;\n right: 4px;\n font-size: 9px;\n font-weight: 600;\n letter-spacing: 0.5px;\n text-transform: uppercase;\n color: var(--chat-text-muted);\n background: var(--chat-background);\n border: 1px solid var(--chat-border);\n border-radius: 3px;\n cursor: pointer;\n padding: 2px 6px;\n transition: all 0.15s ease;\n opacity: 0;\n z-index: 1;\n}\n.tool-call-section-content-wrapper:hover .tool-call-section-toggle {\n opacity: 1;\n}\n.tool-call-section-toggle:hover {\n color: var(--chat-text-secondary);\n border-color: var(--chat-text-disabled);\n background: var(--chat-background-secondary);\n}\n.tool-call-section-content {\n padding: 8px 12px;\n background: var(--chat-background-secondary);\n border-radius: 6px;\n border: 1px solid var(--chat-border-light);\n overflow-x: auto;\n}\n.tool-call-section-content.collapsed {\n max-height: 2.4em;\n overflow: hidden;\n padding-top: 4px;\n padding-bottom: 4px;\n}\n.tool-call-section-content.collapsed pre {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: block;\n max-width: 100%;\n}\n.tool-call-section-content pre {\n margin: 0;\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n monospace;\n font-size: 11px;\n color: var(--chat-text);\n white-space: pre-wrap;\n word-break: break-word;\n}\n.tool-call-error {\n color: var(--chat-error);\n font-weight: 600;\n font-size: 9px;\n letter-spacing: 0.5px;\n margin-left: auto;\n}\n");
|
|
25878
26502
|
|
|
25879
26503
|
// lib/chat/components/ToolCallDisplay.tsx
|
|
25880
|
-
import { useState as
|
|
25881
|
-
import { jsx as
|
|
26504
|
+
import { useState as useState8 } from "react";
|
|
26505
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
25882
26506
|
function CollapsibleSection({ label, content }) {
|
|
25883
|
-
const [isCollapsed, setIsCollapsed] =
|
|
25884
|
-
return /* @__PURE__ */
|
|
25885
|
-
/* @__PURE__ */
|
|
25886
|
-
/* @__PURE__ */
|
|
25887
|
-
/* @__PURE__ */
|
|
26507
|
+
const [isCollapsed, setIsCollapsed] = useState8(false);
|
|
26508
|
+
return /* @__PURE__ */ jsxs12("div", { className: "tool-call-section", children: [
|
|
26509
|
+
/* @__PURE__ */ jsx14("div", { className: "tool-call-section-label", children: label }),
|
|
26510
|
+
/* @__PURE__ */ jsxs12("div", { className: "tool-call-section-content-wrapper", children: [
|
|
26511
|
+
/* @__PURE__ */ jsx14(
|
|
25888
26512
|
"button",
|
|
25889
26513
|
{
|
|
25890
26514
|
className: "tool-call-section-toggle",
|
|
@@ -25893,40 +26517,42 @@ function CollapsibleSection({ label, content }) {
|
|
|
25893
26517
|
children: isCollapsed ? "SHOW" : "HIDE"
|
|
25894
26518
|
}
|
|
25895
26519
|
),
|
|
25896
|
-
/* @__PURE__ */
|
|
26520
|
+
/* @__PURE__ */ jsx14("div", { className: `tool-call-section-content ${isCollapsed ? "collapsed" : ""}`, children: /* @__PURE__ */ jsx14("pre", { children: formatOutput(content) }) })
|
|
25897
26521
|
] })
|
|
25898
26522
|
] });
|
|
25899
26523
|
}
|
|
25900
26524
|
function ToolCallDisplay({ toolPart, className = "" }) {
|
|
25901
|
-
const [isExpanded, setIsExpanded] =
|
|
26525
|
+
const [isExpanded, setIsExpanded] = useState8(false);
|
|
25902
26526
|
const toolName = "toolName" in toolPart ? toolPart.toolName : toolPart.type.replace("tool-", "");
|
|
25903
26527
|
const state = "state" in toolPart ? toolPart.state : "pending";
|
|
25904
26528
|
const hasOutput = state === "output-available" && "output" in toolPart && toolPart.output !== void 0;
|
|
25905
26529
|
const isLoading = state === "input-streaming" || state === "input-available" || state === "approval-requested";
|
|
25906
|
-
const hasError = state === "output-error"
|
|
26530
|
+
const hasError = state === "output-error";
|
|
26531
|
+
const isDenied = state === "output-denied";
|
|
26532
|
+
const hasFailed = hasError || isDenied;
|
|
25907
26533
|
const input = "input" in toolPart ? toolPart.input : void 0;
|
|
25908
26534
|
const output = "output" in toolPart ? toolPart.output : void 0;
|
|
25909
26535
|
const hasInput = input !== void 0 && input !== null && !(typeof input === "object" && Object.keys(input).length === 0);
|
|
25910
26536
|
const canExpand = hasInput || hasOutput;
|
|
25911
26537
|
const renderStatusIcon = () => {
|
|
25912
26538
|
if (isLoading) {
|
|
25913
|
-
return /* @__PURE__ */
|
|
26539
|
+
return /* @__PURE__ */ jsx14("span", { className: "tool-call-spinner" });
|
|
25914
26540
|
}
|
|
25915
|
-
const borderClass =
|
|
25916
|
-
return /* @__PURE__ */
|
|
25917
|
-
/* @__PURE__ */
|
|
25918
|
-
/* @__PURE__ */
|
|
25919
|
-
] }) : /* @__PURE__ */
|
|
26541
|
+
const borderClass = hasFailed ? "tool-call-status-icon--error" : "";
|
|
26542
|
+
return /* @__PURE__ */ jsx14("span", { className: `tool-call-status-icon ${borderClass}`, children: hasFailed ? /* @__PURE__ */ jsxs12("svg", { className: "tool-call-status-icon__inner tool-call-status-icon__inner--error", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: [
|
|
26543
|
+
/* @__PURE__ */ jsx14("line", { x1: "5", y1: "5", x2: "11", y2: "11" }),
|
|
26544
|
+
/* @__PURE__ */ jsx14("line", { x1: "11", y1: "5", x2: "5", y2: "11" })
|
|
26545
|
+
] }) : /* @__PURE__ */ jsx14("svg", { className: "tool-call-status-icon__inner tool-call-status-icon__inner--success", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx14("polyline", { points: "4,8 7,11 12,5" }) }) });
|
|
25920
26546
|
};
|
|
25921
|
-
return /* @__PURE__ */
|
|
25922
|
-
/* @__PURE__ */
|
|
26547
|
+
return /* @__PURE__ */ jsxs12("div", { className: `tool-call-item ${className}`, children: [
|
|
26548
|
+
/* @__PURE__ */ jsxs12("div", { className: "tool-call-header", children: [
|
|
25923
26549
|
renderStatusIcon(),
|
|
25924
|
-
/* @__PURE__ */
|
|
26550
|
+
/* @__PURE__ */ jsxs12("span", { className: "tool-call-label", children: [
|
|
25925
26551
|
isLoading ? "Calling" : "Called",
|
|
25926
26552
|
" ",
|
|
25927
|
-
/* @__PURE__ */
|
|
26553
|
+
/* @__PURE__ */ jsx14("code", { children: toolName })
|
|
25928
26554
|
] }),
|
|
25929
|
-
canExpand && /* @__PURE__ */
|
|
26555
|
+
canExpand && /* @__PURE__ */ jsx14(
|
|
25930
26556
|
"button",
|
|
25931
26557
|
{
|
|
25932
26558
|
className: "tool-call-toggle",
|
|
@@ -25935,11 +26561,12 @@ function ToolCallDisplay({ toolPart, className = "" }) {
|
|
|
25935
26561
|
children: isExpanded ? "HIDE" : "SHOW"
|
|
25936
26562
|
}
|
|
25937
26563
|
),
|
|
25938
|
-
|
|
26564
|
+
isDenied && /* @__PURE__ */ jsx14("span", { className: "tool-call-error", children: "DENIED" }),
|
|
26565
|
+
hasError && /* @__PURE__ */ jsx14("span", { className: "tool-call-error", children: "ERROR" })
|
|
25939
26566
|
] }),
|
|
25940
|
-
isExpanded && canExpand && /* @__PURE__ */
|
|
25941
|
-
hasInput && /* @__PURE__ */
|
|
25942
|
-
hasOutput && /* @__PURE__ */
|
|
26567
|
+
isExpanded && canExpand && /* @__PURE__ */ jsxs12("div", { className: "tool-call-details", children: [
|
|
26568
|
+
hasInput && /* @__PURE__ */ jsx14(CollapsibleSection, { label: "IN", content: input }),
|
|
26569
|
+
hasOutput && /* @__PURE__ */ jsx14(CollapsibleSection, { label: "OUT", content: output })
|
|
25943
26570
|
] })
|
|
25944
26571
|
] });
|
|
25945
26572
|
}
|
|
@@ -25974,7 +26601,7 @@ function createSDKWidget(widget) {
|
|
|
25974
26601
|
var createWidget = (widget) => widget;
|
|
25975
26602
|
|
|
25976
26603
|
// lib/chat/components/WidgetRenderer.tsx
|
|
25977
|
-
import { Fragment as
|
|
26604
|
+
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
25978
26605
|
function renderError(container, message) {
|
|
25979
26606
|
container.innerHTML = "";
|
|
25980
26607
|
const errorDiv = document.createElement("div");
|
|
@@ -25982,7 +26609,7 @@ function renderError(container, message) {
|
|
|
25982
26609
|
errorDiv.textContent = message;
|
|
25983
26610
|
container.appendChild(errorDiv);
|
|
25984
26611
|
}
|
|
25985
|
-
function WidgetRenderer({ widget, payload, enriched, messageContext }) {
|
|
26612
|
+
function WidgetRenderer({ widget, payload, enriched, messageContext, invokeTool }) {
|
|
25986
26613
|
const containerRef = useRef4(null);
|
|
25987
26614
|
const rootRef = useRef4(null);
|
|
25988
26615
|
const customerReactDOMRef = useRef4(void 0);
|
|
@@ -26019,7 +26646,7 @@ function WidgetRenderer({ widget, payload, enriched, messageContext }) {
|
|
|
26019
26646
|
}
|
|
26020
26647
|
let element;
|
|
26021
26648
|
try {
|
|
26022
|
-
element = widget.render(payload, enriched, { messageContext });
|
|
26649
|
+
element = widget.render(payload, enriched, { messageContext, invokeTool });
|
|
26023
26650
|
} catch (error48) {
|
|
26024
26651
|
console.error(`Widget "${widget.widgetType}" render function threw:`, error48);
|
|
26025
26652
|
renderError(containerRef.current, `Widget render error: ${widget.widgetType}`);
|
|
@@ -26080,28 +26707,37 @@ To fix, add your ReactDOM to the widget config:
|
|
|
26080
26707
|
renderError(containerRef.current, `Widget system error: ${widget.widgetType}`);
|
|
26081
26708
|
}
|
|
26082
26709
|
}
|
|
26083
|
-
}, [isSdk, widget, payload, enriched, payloadHash, enrichedHash, messageContext]);
|
|
26710
|
+
}, [isSdk, widget, payload, enriched, payloadHash, enrichedHash, messageContext, invokeTool]);
|
|
26084
26711
|
if (isSdk) {
|
|
26085
26712
|
try {
|
|
26086
|
-
const element = widget.render(payload, enriched, { messageContext });
|
|
26087
|
-
return /* @__PURE__ */
|
|
26713
|
+
const element = widget.render(payload, enriched, { messageContext, invokeTool });
|
|
26714
|
+
return /* @__PURE__ */ jsx15(Fragment4, { children: element });
|
|
26088
26715
|
} catch (error48) {
|
|
26089
26716
|
console.error(`SDK widget "${widget.widgetType}" render threw:`, error48);
|
|
26090
26717
|
const errorMessage = error48 instanceof Error ? error48.message : String(error48);
|
|
26091
|
-
return /* @__PURE__ */
|
|
26718
|
+
return /* @__PURE__ */ jsxs13("div", { className: "widget-error", title: errorMessage, children: [
|
|
26092
26719
|
"Widget error: ",
|
|
26093
26720
|
widget.widgetType
|
|
26094
26721
|
] });
|
|
26095
26722
|
}
|
|
26096
26723
|
}
|
|
26097
|
-
return /* @__PURE__ */
|
|
26724
|
+
return /* @__PURE__ */ jsx15("div", { ref: containerRef, className: "widget-customer-root" });
|
|
26098
26725
|
}
|
|
26099
26726
|
|
|
26100
26727
|
// lib/chat/renderers/MessageRenderer.tsx
|
|
26101
|
-
import { Fragment as
|
|
26728
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
26102
26729
|
function FormattedMarkdownComponent({ children }) {
|
|
26103
26730
|
const MarkdownComponent = ReactMarkdown;
|
|
26104
|
-
return /* @__PURE__ */
|
|
26731
|
+
return /* @__PURE__ */ jsx16(
|
|
26732
|
+
MarkdownComponent,
|
|
26733
|
+
{
|
|
26734
|
+
remarkPlugins: [remarkGfm],
|
|
26735
|
+
components: {
|
|
26736
|
+
a: ({ children: children2, href, ...props }) => /* @__PURE__ */ jsx16("a", { href, target: "_blank", rel: "noopener noreferrer", ...props, children: children2 })
|
|
26737
|
+
},
|
|
26738
|
+
children: children.replace(/\n\n/gi, "\n\n \n\n")
|
|
26739
|
+
}
|
|
26740
|
+
);
|
|
26105
26741
|
}
|
|
26106
26742
|
var FormattedMarkdown = React5.memo(FormattedMarkdownComponent);
|
|
26107
26743
|
function MessageRenderer({
|
|
@@ -26111,7 +26747,8 @@ function MessageRenderer({
|
|
|
26111
26747
|
displayMode = "brief",
|
|
26112
26748
|
tagExpansion,
|
|
26113
26749
|
className,
|
|
26114
|
-
feedback
|
|
26750
|
+
feedback,
|
|
26751
|
+
invokeTool
|
|
26115
26752
|
}) {
|
|
26116
26753
|
const messageContext = useMemo4(() => {
|
|
26117
26754
|
if (!feedback) return void 0;
|
|
@@ -26133,43 +26770,44 @@ function MessageRenderer({
|
|
|
26133
26770
|
if (part.type === "text") {
|
|
26134
26771
|
const trimmed = part.text?.trim();
|
|
26135
26772
|
if (!trimmed) return null;
|
|
26136
|
-
return /* @__PURE__ */
|
|
26773
|
+
return /* @__PURE__ */ jsx16("div", { className: "chat-widget__markdown", children: /* @__PURE__ */ jsx16(FormattedMarkdown, { children: trimmed }) }, key);
|
|
26137
26774
|
}
|
|
26138
26775
|
if (part.type.startsWith("tool-") || part.type === "dynamic-tool") {
|
|
26139
|
-
return /* @__PURE__ */
|
|
26776
|
+
return /* @__PURE__ */ jsx16(ToolCallDisplay, { toolPart: part }, key);
|
|
26140
26777
|
}
|
|
26141
26778
|
if (part.type === "data-ui") {
|
|
26142
26779
|
const dataPart = part;
|
|
26143
26780
|
const uiWidgets = dataPart.data;
|
|
26144
26781
|
if (!Array.isArray(uiWidgets)) return null;
|
|
26145
26782
|
if (!widgets || widgets.length === 0) {
|
|
26146
|
-
return /* @__PURE__ */
|
|
26783
|
+
return /* @__PURE__ */ jsxs14("div", { className: "text-muted-foreground text-sm italic", children: [
|
|
26147
26784
|
"[UI Widget: ",
|
|
26148
26785
|
uiWidgets.map((w) => w.widgetType || "unknown").join(", "),
|
|
26149
26786
|
"]"
|
|
26150
26787
|
] }, key);
|
|
26151
26788
|
}
|
|
26152
|
-
return /* @__PURE__ */
|
|
26789
|
+
return /* @__PURE__ */ jsx16(React5.Fragment, { children: uiWidgets.map((widget, idx) => {
|
|
26153
26790
|
const widgetDef = widgets.find((w) => w.widgetType === widget.widgetType);
|
|
26154
26791
|
if (!widgetDef) {
|
|
26155
|
-
return /* @__PURE__ */
|
|
26792
|
+
return /* @__PURE__ */ jsxs14("span", { children: [
|
|
26156
26793
|
"[Unknown widget: ",
|
|
26157
26794
|
widget.widgetType,
|
|
26158
26795
|
"]"
|
|
26159
26796
|
] }, `${key}-widget-${idx}`);
|
|
26160
26797
|
}
|
|
26161
|
-
return /* @__PURE__ */
|
|
26798
|
+
return /* @__PURE__ */ jsx16(
|
|
26162
26799
|
"div",
|
|
26163
26800
|
{
|
|
26164
26801
|
className: "chat-widget__widget",
|
|
26165
26802
|
inert: readonly2 ? true : void 0,
|
|
26166
|
-
children: /* @__PURE__ */
|
|
26803
|
+
children: /* @__PURE__ */ jsx16(
|
|
26167
26804
|
WidgetRenderer,
|
|
26168
26805
|
{
|
|
26169
26806
|
widget: widgetDef,
|
|
26170
26807
|
payload: widget.payload,
|
|
26171
26808
|
enriched: widget.enriched ?? {},
|
|
26172
|
-
messageContext: messageContext ?? void 0
|
|
26809
|
+
messageContext: messageContext ?? void 0,
|
|
26810
|
+
invokeTool
|
|
26173
26811
|
}
|
|
26174
26812
|
)
|
|
26175
26813
|
},
|
|
@@ -26184,7 +26822,7 @@ function MessageRenderer({
|
|
|
26184
26822
|
const renderGroup = useCallback5(
|
|
26185
26823
|
(groupName, key, children) => {
|
|
26186
26824
|
const isExpanded = tagExpansion?.state.get(key) ?? true;
|
|
26187
|
-
return /* @__PURE__ */
|
|
26825
|
+
return /* @__PURE__ */ jsx16(
|
|
26188
26826
|
TagGroupDisplay,
|
|
26189
26827
|
{
|
|
26190
26828
|
tagId: groupName,
|
|
@@ -26198,8 +26836,8 @@ function MessageRenderer({
|
|
|
26198
26836
|
[tagExpansion]
|
|
26199
26837
|
);
|
|
26200
26838
|
const DisplayMode = displayMode === "brief" ? BriefDisplayMode : FullDisplayMode;
|
|
26201
|
-
return /* @__PURE__ */
|
|
26202
|
-
/* @__PURE__ */
|
|
26839
|
+
return /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
26840
|
+
/* @__PURE__ */ jsx16("div", { className, children: /* @__PURE__ */ jsx16(
|
|
26203
26841
|
DisplayMode,
|
|
26204
26842
|
{
|
|
26205
26843
|
sections: message.sections,
|
|
@@ -26208,7 +26846,7 @@ function MessageRenderer({
|
|
|
26208
26846
|
renderGroup
|
|
26209
26847
|
}
|
|
26210
26848
|
) }),
|
|
26211
|
-
!readonly2 && feedback && /* @__PURE__ */
|
|
26849
|
+
!readonly2 && feedback && /* @__PURE__ */ jsx16(
|
|
26212
26850
|
MessageFeedback,
|
|
26213
26851
|
{
|
|
26214
26852
|
messageId: message.id,
|
|
@@ -26223,7 +26861,7 @@ function MessageRenderer({
|
|
|
26223
26861
|
}
|
|
26224
26862
|
|
|
26225
26863
|
// lib/chat/ChatWidget.tsx
|
|
26226
|
-
import { jsx as
|
|
26864
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
26227
26865
|
var classNames2 = {
|
|
26228
26866
|
container: "chat-widget",
|
|
26229
26867
|
header: "chat-widget__header",
|
|
@@ -26255,15 +26893,23 @@ var classNames2 = {
|
|
|
26255
26893
|
voiceControl: "chat-widget__voice",
|
|
26256
26894
|
micButton: "chat-widget__mic-button"
|
|
26257
26895
|
};
|
|
26258
|
-
var
|
|
26896
|
+
var lightTheme = {
|
|
26897
|
+
theme: "light",
|
|
26259
26898
|
primaryColor: "#3b82f6",
|
|
26260
26899
|
primaryTextColor: "#ffffff",
|
|
26261
26900
|
backgroundColor: "#ffffff",
|
|
26901
|
+
backgroundSecondary: "#f9fafb",
|
|
26902
|
+
backgroundTertiary: "#f3f4f6",
|
|
26262
26903
|
borderColor: "#e5e7eb",
|
|
26904
|
+
borderColorLight: "#f3f4f6",
|
|
26263
26905
|
headerTextColor: "#ffffff",
|
|
26264
26906
|
userBubbleTextColor: "#ffffff",
|
|
26265
26907
|
assistantBubbleBackground: "transparent",
|
|
26266
26908
|
assistantBubbleTextColor: "#111827",
|
|
26909
|
+
textColor: "#111827",
|
|
26910
|
+
textSecondary: "#4b5563",
|
|
26911
|
+
textMuted: "#6b7280",
|
|
26912
|
+
textDisabled: "#9ca3af",
|
|
26267
26913
|
fontFamily: `'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif`,
|
|
26268
26914
|
borderRadius: "0.75rem",
|
|
26269
26915
|
inputBackground: "#ffffff",
|
|
@@ -26271,6 +26917,44 @@ var defaultTheme = {
|
|
|
26271
26917
|
inputPlaceholderColor: "#6b7280",
|
|
26272
26918
|
thoughtsBorderColor: "#d1d5db"
|
|
26273
26919
|
};
|
|
26920
|
+
var darkTheme = {
|
|
26921
|
+
theme: "dark",
|
|
26922
|
+
primaryColor: "#3b82f6",
|
|
26923
|
+
primaryTextColor: "#ffffff",
|
|
26924
|
+
backgroundColor: "#1f2937",
|
|
26925
|
+
backgroundSecondary: "#374151",
|
|
26926
|
+
backgroundTertiary: "#4b5563",
|
|
26927
|
+
borderColor: "#4b5563",
|
|
26928
|
+
borderColorLight: "#374151",
|
|
26929
|
+
headerTextColor: "#ffffff",
|
|
26930
|
+
userBubbleTextColor: "#ffffff",
|
|
26931
|
+
assistantBubbleBackground: "transparent",
|
|
26932
|
+
assistantBubbleTextColor: "#f9fafb",
|
|
26933
|
+
textColor: "#f9fafb",
|
|
26934
|
+
textSecondary: "#d1d5db",
|
|
26935
|
+
textMuted: "#9ca3af",
|
|
26936
|
+
textDisabled: "#6b7280",
|
|
26937
|
+
fontFamily: `'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif`,
|
|
26938
|
+
borderRadius: "0.75rem",
|
|
26939
|
+
inputBackground: "#374151",
|
|
26940
|
+
inputTextColor: "#f9fafb",
|
|
26941
|
+
inputPlaceholderColor: "#9ca3af",
|
|
26942
|
+
thoughtsBorderColor: "#4b5563"
|
|
26943
|
+
};
|
|
26944
|
+
function detectDarkMode() {
|
|
26945
|
+
if (typeof window === "undefined") return false;
|
|
26946
|
+
const html2 = document.documentElement;
|
|
26947
|
+
const body = document.body;
|
|
26948
|
+
const dataTheme = html2.getAttribute("data-theme") || body.getAttribute("data-theme");
|
|
26949
|
+
if (dataTheme === "dark") return true;
|
|
26950
|
+
if (dataTheme === "light") return false;
|
|
26951
|
+
if (html2.classList.contains("dark") || body.classList.contains("dark")) return true;
|
|
26952
|
+
if (html2.classList.contains("light") || body.classList.contains("light")) return false;
|
|
26953
|
+
const colorScheme = getComputedStyle(html2).colorScheme;
|
|
26954
|
+
if (colorScheme === "dark") return true;
|
|
26955
|
+
if (colorScheme === "light") return false;
|
|
26956
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
26957
|
+
}
|
|
26274
26958
|
var mixWithBlack = (hex3, ratio = 0.15) => {
|
|
26275
26959
|
const normalized = hex3.replace("#", "");
|
|
26276
26960
|
if (!/^[0-9a-fA-F]{6}$/.test(normalized)) return hex3;
|
|
@@ -26303,17 +26987,50 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26303
26987
|
widgets,
|
|
26304
26988
|
feedback
|
|
26305
26989
|
}, ref) {
|
|
26306
|
-
const
|
|
26307
|
-
|
|
26308
|
-
|
|
26309
|
-
|
|
26990
|
+
const [detectedDarkMode, setDetectedDarkMode] = useState9(false);
|
|
26991
|
+
useEffect6(() => {
|
|
26992
|
+
setDetectedDarkMode(detectDarkMode());
|
|
26993
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
26994
|
+
const handleChange = () => setDetectedDarkMode(detectDarkMode());
|
|
26995
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
26996
|
+
const observer = new MutationObserver(() => {
|
|
26997
|
+
setDetectedDarkMode(detectDarkMode());
|
|
26998
|
+
});
|
|
26999
|
+
observer.observe(document.documentElement, {
|
|
27000
|
+
attributes: true,
|
|
27001
|
+
attributeFilter: ["data-theme", "class"]
|
|
27002
|
+
});
|
|
27003
|
+
observer.observe(document.body, {
|
|
27004
|
+
attributes: true,
|
|
27005
|
+
attributeFilter: ["data-theme", "class"]
|
|
27006
|
+
});
|
|
27007
|
+
return () => {
|
|
27008
|
+
mediaQuery.removeEventListener("change", handleChange);
|
|
27009
|
+
observer.disconnect();
|
|
27010
|
+
};
|
|
27011
|
+
}, []);
|
|
27012
|
+
const theme = useMemo5(() => {
|
|
27013
|
+
const themeMode = styleProps?.theme || "auto";
|
|
27014
|
+
const isDark = themeMode === "dark" || themeMode === "auto" && detectedDarkMode;
|
|
27015
|
+
const baseTheme = isDark ? darkTheme : lightTheme;
|
|
27016
|
+
return { ...baseTheme, ...styleProps || {} };
|
|
27017
|
+
}, [styleProps, detectedDarkMode]);
|
|
26310
27018
|
const themeVariables = useMemo5(
|
|
26311
27019
|
() => ({
|
|
26312
27020
|
"--chat-primary": theme.primaryColor,
|
|
26313
27021
|
"--chat-primary-text": theme.primaryTextColor,
|
|
26314
27022
|
"--chat-primary-hover": mixWithBlack(theme.primaryColor, 0.2),
|
|
27023
|
+
"--chat-primary-subtle": `${theme.primaryColor}1a`,
|
|
27024
|
+
// 10% opacity
|
|
26315
27025
|
"--chat-background": theme.backgroundColor,
|
|
27026
|
+
"--chat-background-secondary": theme.backgroundSecondary,
|
|
27027
|
+
"--chat-background-tertiary": theme.backgroundTertiary,
|
|
26316
27028
|
"--chat-border": theme.borderColor,
|
|
27029
|
+
"--chat-border-light": theme.borderColorLight,
|
|
27030
|
+
"--chat-text": theme.textColor,
|
|
27031
|
+
"--chat-text-secondary": theme.textSecondary,
|
|
27032
|
+
"--chat-text-muted": theme.textMuted,
|
|
27033
|
+
"--chat-text-disabled": theme.textDisabled,
|
|
26317
27034
|
"--chat-header-text": theme.headerTextColor,
|
|
26318
27035
|
"--chat-user-text": theme.userBubbleTextColor,
|
|
26319
27036
|
"--chat-assistant-bg": theme.assistantBubbleBackground,
|
|
@@ -26327,9 +27044,9 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26327
27044
|
}),
|
|
26328
27045
|
[theme]
|
|
26329
27046
|
);
|
|
26330
|
-
const [input, setInput] =
|
|
26331
|
-
const [isMicActive, setIsMicActive] =
|
|
26332
|
-
const [isSpeechPending, setIsSpeechPending] =
|
|
27047
|
+
const [input, setInput] = useState9("");
|
|
27048
|
+
const [isMicActive, setIsMicActive] = useState9(false);
|
|
27049
|
+
const [isSpeechPending, setIsSpeechPending] = useState9(false);
|
|
26333
27050
|
const messagesEndRef = useRef5(null);
|
|
26334
27051
|
const scrollContainerRef = useRef5(null);
|
|
26335
27052
|
const isAtBottomRef = useRef5(true);
|
|
@@ -26341,7 +27058,11 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26341
27058
|
isLoadingInitial,
|
|
26342
27059
|
sendMessage,
|
|
26343
27060
|
stop,
|
|
26344
|
-
setMessages
|
|
27061
|
+
setMessages,
|
|
27062
|
+
addToolOutput,
|
|
27063
|
+
addToolApprovalResponse,
|
|
27064
|
+
pendingToolOutput,
|
|
27065
|
+
pendingToolApproval
|
|
26345
27066
|
} = useChat({
|
|
26346
27067
|
api,
|
|
26347
27068
|
threadId,
|
|
@@ -26354,6 +27075,24 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26354
27075
|
onFinish,
|
|
26355
27076
|
onMessage
|
|
26356
27077
|
});
|
|
27078
|
+
const handleToolOutput = useCallback6((result) => {
|
|
27079
|
+
if (pendingToolOutput && addToolOutput) {
|
|
27080
|
+
addToolOutput({
|
|
27081
|
+
tool: "collect_user_input",
|
|
27082
|
+
toolCallId: pendingToolOutput.toolCallId,
|
|
27083
|
+
output: result
|
|
27084
|
+
});
|
|
27085
|
+
}
|
|
27086
|
+
}, [pendingToolOutput, addToolOutput]);
|
|
27087
|
+
const handleToolApproval = useCallback6((approved, reason) => {
|
|
27088
|
+
if (!pendingToolApproval) return;
|
|
27089
|
+
addToolApprovalResponse({
|
|
27090
|
+
id: pendingToolApproval.approvalId,
|
|
27091
|
+
approved,
|
|
27092
|
+
reason
|
|
27093
|
+
});
|
|
27094
|
+
}, [pendingToolApproval, addToolApprovalResponse]);
|
|
27095
|
+
const isInputDisabled = status !== "ready" || !!pendingToolOutput || !!pendingToolApproval;
|
|
26357
27096
|
useImperativeHandle(ref, () => ({
|
|
26358
27097
|
sendMessage: (message) => {
|
|
26359
27098
|
if (message.trim() && status === "ready") {
|
|
@@ -26372,7 +27111,36 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26372
27111
|
agentId,
|
|
26373
27112
|
agentVersion
|
|
26374
27113
|
});
|
|
26375
|
-
const
|
|
27114
|
+
const invokeTool = useMemo5(
|
|
27115
|
+
() => createInvokeTool(api, onAuthError),
|
|
27116
|
+
[api, onAuthError]
|
|
27117
|
+
);
|
|
27118
|
+
const [tagExpansionState, setTagExpansionState] = useState9(/* @__PURE__ */ new Map());
|
|
27119
|
+
const [approvalConfig, setApprovalConfig] = useState9(null);
|
|
27120
|
+
const [approvalConfigLoading, setApprovalConfigLoading] = useState9(false);
|
|
27121
|
+
useEffect6(() => {
|
|
27122
|
+
if (!pendingToolApproval) {
|
|
27123
|
+
setApprovalConfig(null);
|
|
27124
|
+
setApprovalConfigLoading(false);
|
|
27125
|
+
return;
|
|
27126
|
+
}
|
|
27127
|
+
setApprovalConfigLoading(true);
|
|
27128
|
+
fetchApprovalConfig({
|
|
27129
|
+
api,
|
|
27130
|
+
agentId,
|
|
27131
|
+
agentVersion,
|
|
27132
|
+
toolName: pendingToolApproval.toolName,
|
|
27133
|
+
args: pendingToolApproval.args,
|
|
27134
|
+
onAuthError
|
|
27135
|
+
}).then((config2) => {
|
|
27136
|
+
setApprovalConfig(config2);
|
|
27137
|
+
}).catch((err) => {
|
|
27138
|
+
console.error("[ChatWidget] Failed to fetch approval config:", err);
|
|
27139
|
+
setApprovalConfig(null);
|
|
27140
|
+
}).finally(() => {
|
|
27141
|
+
setApprovalConfigLoading(false);
|
|
27142
|
+
});
|
|
27143
|
+
}, [pendingToolApproval, api, agentId, agentVersion, onAuthError]);
|
|
26376
27144
|
const handleTagToggle = useCallback6((messageId, tagId, currentlyExpanded) => {
|
|
26377
27145
|
suppressScrollRef.current = true;
|
|
26378
27146
|
setTagExpansionState((prev) => {
|
|
@@ -26455,11 +27223,11 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26455
27223
|
}, [status]);
|
|
26456
27224
|
const sendText = useCallback6((raw) => {
|
|
26457
27225
|
const text4 = (raw ?? input).trim();
|
|
26458
|
-
if (!text4 ||
|
|
27226
|
+
if (!text4 || isInputDisabled) return false;
|
|
26459
27227
|
sendMessage({ text: text4 });
|
|
26460
27228
|
setInput("");
|
|
26461
27229
|
return true;
|
|
26462
|
-
}, [input,
|
|
27230
|
+
}, [input, isInputDisabled, sendMessage, setInput]);
|
|
26463
27231
|
const handleSendMessage = () => {
|
|
26464
27232
|
sendText();
|
|
26465
27233
|
};
|
|
@@ -26505,15 +27273,15 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26505
27273
|
console.error("Failed to register chat widgets", err);
|
|
26506
27274
|
});
|
|
26507
27275
|
}, [api, threadId, widgets, onAuthError]);
|
|
26508
|
-
return /* @__PURE__ */
|
|
27276
|
+
return /* @__PURE__ */ jsxs15(
|
|
26509
27277
|
"div",
|
|
26510
27278
|
{
|
|
26511
27279
|
className: cn(classNames2.container, className),
|
|
26512
27280
|
style: themeVariables,
|
|
26513
27281
|
"data-chat-widget": "",
|
|
26514
27282
|
children: [
|
|
26515
|
-
title && /* @__PURE__ */
|
|
26516
|
-
/* @__PURE__ */
|
|
27283
|
+
title && /* @__PURE__ */ jsx17("div", { className: classNames2.header, children: /* @__PURE__ */ jsx17("h3", { className: classNames2.headerTitle, children: title }) }),
|
|
27284
|
+
/* @__PURE__ */ jsxs15(
|
|
26517
27285
|
"div",
|
|
26518
27286
|
{
|
|
26519
27287
|
className: classNames2.messagesContainer,
|
|
@@ -26524,21 +27292,21 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26524
27292
|
const isUser = message.role === "user";
|
|
26525
27293
|
const isLastMessage = index === messages.length - 1;
|
|
26526
27294
|
const showFeedback = feedbackEnabled && !isUser && !(status === "streaming" && isLastMessage);
|
|
26527
|
-
return /* @__PURE__ */
|
|
27295
|
+
return /* @__PURE__ */ jsx17("div", { className: classNames2.messageWrapper, children: /* @__PURE__ */ jsx17(
|
|
26528
27296
|
"div",
|
|
26529
27297
|
{
|
|
26530
27298
|
className: cn(
|
|
26531
27299
|
classNames2.messageRow,
|
|
26532
27300
|
isUser ? classNames2.userMessageRow : classNames2.assistantMessageRow
|
|
26533
27301
|
),
|
|
26534
|
-
children: /* @__PURE__ */
|
|
27302
|
+
children: /* @__PURE__ */ jsx17(
|
|
26535
27303
|
"div",
|
|
26536
27304
|
{
|
|
26537
27305
|
className: cn(
|
|
26538
27306
|
classNames2.messageBubble,
|
|
26539
27307
|
isUser ? classNames2.userMessage : classNames2.assistantMessage
|
|
26540
27308
|
),
|
|
26541
|
-
children: /* @__PURE__ */
|
|
27309
|
+
children: /* @__PURE__ */ jsx17(
|
|
26542
27310
|
MessageRenderer,
|
|
26543
27311
|
{
|
|
26544
27312
|
message,
|
|
@@ -26553,7 +27321,8 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26553
27321
|
requireCommentForNegative: feedback?.requireCommentForNegative,
|
|
26554
27322
|
getFeedback: () => getFeedback(message.id),
|
|
26555
27323
|
submitFeedback: (params) => submitFeedback(message.id, params)
|
|
26556
|
-
} : void 0
|
|
27324
|
+
} : void 0,
|
|
27325
|
+
invokeTool
|
|
26557
27326
|
}
|
|
26558
27327
|
)
|
|
26559
27328
|
}
|
|
@@ -26561,17 +27330,17 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26561
27330
|
}
|
|
26562
27331
|
) }, message.id);
|
|
26563
27332
|
}),
|
|
26564
|
-
status === "streaming" && /* @__PURE__ */
|
|
26565
|
-
/* @__PURE__ */
|
|
26566
|
-
/* @__PURE__ */
|
|
26567
|
-
/* @__PURE__ */
|
|
27333
|
+
status === "streaming" && /* @__PURE__ */ jsx17("div", { className: classNames2.loadingContainer, children: /* @__PURE__ */ jsx17("div", { className: classNames2.loadingBubble, children: /* @__PURE__ */ jsxs15("div", { className: classNames2.loadingDots, children: [
|
|
27334
|
+
/* @__PURE__ */ jsx17("div", { className: classNames2.loadingDot }),
|
|
27335
|
+
/* @__PURE__ */ jsx17("div", { className: classNames2.loadingDot, "data-delay": "1" }),
|
|
27336
|
+
/* @__PURE__ */ jsx17("div", { className: classNames2.loadingDot, "data-delay": "2" })
|
|
26568
27337
|
] }) }) }),
|
|
26569
|
-
/* @__PURE__ */
|
|
27338
|
+
/* @__PURE__ */ jsx17("div", { ref: messagesEndRef })
|
|
26570
27339
|
]
|
|
26571
27340
|
}
|
|
26572
27341
|
),
|
|
26573
|
-
/* @__PURE__ */
|
|
26574
|
-
/* @__PURE__ */
|
|
27342
|
+
/* @__PURE__ */ jsx17("div", { className: classNames2.inputContainer, children: /* @__PURE__ */ jsxs15("form", { onSubmit: handleSubmit, className: classNames2.inputForm, children: [
|
|
27343
|
+
/* @__PURE__ */ jsx17(
|
|
26575
27344
|
"textarea",
|
|
26576
27345
|
{
|
|
26577
27346
|
ref: textareaRef,
|
|
@@ -26579,12 +27348,12 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26579
27348
|
onChange: (e) => setInput(e.target.value),
|
|
26580
27349
|
onKeyDown: handleKeyDown,
|
|
26581
27350
|
placeholder: inputPlaceholder,
|
|
26582
|
-
disabled:
|
|
27351
|
+
disabled: isInputDisabled,
|
|
26583
27352
|
rows: 1,
|
|
26584
27353
|
className: classNames2.textarea
|
|
26585
27354
|
}
|
|
26586
27355
|
),
|
|
26587
|
-
/* @__PURE__ */
|
|
27356
|
+
/* @__PURE__ */ jsx17("div", { className: classNames2.toolbar, children: speechEnabled && /* @__PURE__ */ jsx17(
|
|
26588
27357
|
SpeechToTextButton,
|
|
26589
27358
|
{
|
|
26590
27359
|
className: classNames2.micButton,
|
|
@@ -26598,32 +27367,49 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
26598
27367
|
onListeningChange: setIsMicActive
|
|
26599
27368
|
}
|
|
26600
27369
|
) }),
|
|
26601
|
-
/* @__PURE__ */
|
|
27370
|
+
/* @__PURE__ */ jsx17(
|
|
26602
27371
|
"button",
|
|
26603
27372
|
{
|
|
26604
27373
|
type: "button",
|
|
26605
27374
|
onClick: status === "streaming" ? stop : handleSendMessage,
|
|
26606
|
-
disabled: status === "streaming" ? false : !input.trim() ||
|
|
27375
|
+
disabled: status === "streaming" ? false : !input.trim() || isInputDisabled,
|
|
26607
27376
|
className: classNames2.submitButton,
|
|
26608
|
-
children: status === "streaming" ? /* @__PURE__ */
|
|
27377
|
+
children: status === "streaming" ? /* @__PURE__ */ jsx17(StopCircle, { className: classNames2.sendIcon }) : /* @__PURE__ */ jsx17(Send, { className: classNames2.sendIcon })
|
|
26609
27378
|
}
|
|
26610
27379
|
)
|
|
26611
|
-
] }) })
|
|
27380
|
+
] }) }),
|
|
27381
|
+
pendingToolOutput && /* @__PURE__ */ jsx17(
|
|
27382
|
+
InputFormOverlay,
|
|
27383
|
+
{
|
|
27384
|
+
args: pendingToolOutput.args,
|
|
27385
|
+
onComplete: handleToolOutput
|
|
27386
|
+
}
|
|
27387
|
+
),
|
|
27388
|
+
pendingToolApproval && /* @__PURE__ */ jsx17(
|
|
27389
|
+
ToolApprovalOverlay,
|
|
27390
|
+
{
|
|
27391
|
+
approval: pendingToolApproval,
|
|
27392
|
+
config: approvalConfig,
|
|
27393
|
+
configLoading: approvalConfigLoading,
|
|
27394
|
+
onApprove: () => handleToolApproval(true),
|
|
27395
|
+
onDeny: (reason) => handleToolApproval(false, reason)
|
|
27396
|
+
}
|
|
27397
|
+
)
|
|
26612
27398
|
]
|
|
26613
27399
|
}
|
|
26614
27400
|
);
|
|
26615
27401
|
});
|
|
26616
27402
|
|
|
26617
27403
|
// lib/chat/PopupChatWidget.css
|
|
26618
|
-
styleInject(".chat-popup__anchor {\n position: fixed;\n inset-block-end: 20px;\n inset-inline-end: 20px;\n}\n.chat-popup--start {\n inset-inline-end: auto;\n inset-inline-start: 20px;\n}\n.chat-popup__anchor-button {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.65rem 0.85rem;\n background: var(--chat-primary);\n color: var(--chat-primary-text);\n border: none;\n border-radius: 999px;\n box-shadow:
|
|
27404
|
+
styleInject(".chat-popup__anchor {\n position: fixed;\n inset-block-end: 20px;\n inset-inline-end: 20px;\n}\n.chat-popup--start {\n inset-inline-end: auto;\n inset-inline-start: 20px;\n}\n.chat-popup__anchor-button {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.65rem 0.85rem;\n background: var(--chat-primary);\n color: var(--chat-primary-text);\n border: none;\n border-radius: 999px;\n box-shadow: var(--chat-shadow);\n cursor: pointer;\n font-weight: 600;\n z-index: 99999;\n}\n.chat-popup__anchor-button:hover {\n background: var(--chat-primary-hover);\n}\n.chat-popup__anchor-icon {\n width: 1.1rem;\n height: 1.1rem;\n}\n.chat-popup__panel {\n position: fixed;\n inset-block-end: 20px;\n inset-inline-end: 20px;\n z-index: 99998;\n transition: opacity 0.15s ease, visibility 0.15s ease;\n}\n.chat-popup--start.chat-popup__panel {\n inset-inline-end: auto;\n inset-inline-start: 20px;\n}\n.chat-popup__panel--open {\n opacity: 1;\n visibility: visible;\n pointer-events: auto;\n}\n.chat-popup__panel--closed {\n opacity: 0;\n visibility: hidden;\n pointer-events: none;\n}\n.chat-popup__panel-inner {\n width: 384px;\n max-width: calc(100vw - 40px);\n height: 500px;\n max-height: calc(100vh - 140px);\n box-shadow: var(--chat-shadow);\n border-radius: 12px;\n overflow: visible;\n background: var(--chat-background);\n border: 1px solid var(--chat-border);\n position: relative;\n}\n.chat-popup__close {\n position: absolute;\n top: 0;\n z-index: 10;\n transform: translate(30%, -40%);\n}\n.chat-popup__close--end {\n inset-inline-end: 0;\n}\n.chat-popup__close--start {\n inset-inline-start: 0;\n}\n.chat-popup__close-button {\n border: none;\n background: var(--chat-primary);\n color: var(--chat-primary-text);\n width: 32px;\n height: 32px;\n border-radius: 999px;\n cursor: pointer;\n display: grid;\n place-items: center;\n box-shadow: var(--chat-shadow);\n}\n.chat-popup__close-button:hover {\n background: var(--chat-primary-hover);\n}\n.chat-popup__close-icon {\n width: 16px;\n height: 16px;\n}\n");
|
|
26619
27405
|
|
|
26620
27406
|
// lib/chat/PopupChatWidget.tsx
|
|
26621
27407
|
import { MessageSquare as MessageSquare2, X } from "lucide-react";
|
|
26622
|
-
import { useEffect as useEffect7, useMemo as useMemo6, useState as
|
|
26623
|
-
import { jsx as
|
|
27408
|
+
import { useEffect as useEffect7, useMemo as useMemo6, useState as useState10 } from "react";
|
|
27409
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
26624
27410
|
function PopupChatWidget({ anchor, ...props }) {
|
|
26625
|
-
const [isOpen, setIsOpen] =
|
|
26626
|
-
const [hasOpened, setHasOpened] =
|
|
27411
|
+
const [isOpen, setIsOpen] = useState10(anchor?.initiallyOpen ?? false);
|
|
27412
|
+
const [hasOpened, setHasOpened] = useState10(anchor?.initiallyOpen ?? false);
|
|
26627
27413
|
const openResolved = props.openOverride ?? isOpen;
|
|
26628
27414
|
useEffect7(() => {
|
|
26629
27415
|
if (props.openOverride === void 0) return;
|
|
@@ -26677,8 +27463,8 @@ function PopupChatWidget({ anchor, ...props }) {
|
|
|
26677
27463
|
maxHeight: size.maxHeight ?? "calc(100vh - 140px)"
|
|
26678
27464
|
};
|
|
26679
27465
|
}, [props.popupSize]);
|
|
26680
|
-
return /* @__PURE__ */
|
|
26681
|
-
/* @__PURE__ */
|
|
27466
|
+
return /* @__PURE__ */ jsxs16("div", { style: themeStyle, children: [
|
|
27467
|
+
/* @__PURE__ */ jsx18("div", { className: cn("chat-popup__anchor", anchorPositionClass), children: anchor?.render ? anchor.render({ isOpen: openResolved, toggle: handleToggle }) : !openResolved && /* @__PURE__ */ jsxs16(
|
|
26682
27468
|
"button",
|
|
26683
27469
|
{
|
|
26684
27470
|
type: "button",
|
|
@@ -26687,12 +27473,12 @@ function PopupChatWidget({ anchor, ...props }) {
|
|
|
26687
27473
|
"aria-expanded": isOpen,
|
|
26688
27474
|
"aria-label": anchor?.label ?? "Open chat",
|
|
26689
27475
|
children: [
|
|
26690
|
-
/* @__PURE__ */
|
|
26691
|
-
/* @__PURE__ */
|
|
27476
|
+
/* @__PURE__ */ jsx18(MessageSquare2, { className: "chat-popup__anchor-icon" }),
|
|
27477
|
+
/* @__PURE__ */ jsx18("span", { children: anchor?.label ?? "Chat" })
|
|
26692
27478
|
]
|
|
26693
27479
|
}
|
|
26694
27480
|
) }),
|
|
26695
|
-
/* @__PURE__ */
|
|
27481
|
+
/* @__PURE__ */ jsx18(
|
|
26696
27482
|
"div",
|
|
26697
27483
|
{
|
|
26698
27484
|
className: cn(
|
|
@@ -26700,87 +27486,68 @@ function PopupChatWidget({ anchor, ...props }) {
|
|
|
26700
27486
|
anchorPositionClass,
|
|
26701
27487
|
openResolved ? "chat-popup__panel--open" : "chat-popup__panel--closed"
|
|
26702
27488
|
),
|
|
26703
|
-
children: /* @__PURE__ */
|
|
26704
|
-
showClose && /* @__PURE__ */
|
|
27489
|
+
children: /* @__PURE__ */ jsxs16("div", { className: "chat-popup__panel-inner", style: popupStyle, children: [
|
|
27490
|
+
showClose && /* @__PURE__ */ jsx18(
|
|
26705
27491
|
"div",
|
|
26706
27492
|
{
|
|
26707
27493
|
className: cn(
|
|
26708
27494
|
"chat-popup__close",
|
|
26709
27495
|
closeConfig?.position === "top-start" ? "chat-popup__close--start" : "chat-popup__close--end"
|
|
26710
27496
|
),
|
|
26711
|
-
children: closeConfig?.render ? closeConfig.render({ toggle: handleToggle }) : /* @__PURE__ */
|
|
27497
|
+
children: closeConfig?.render ? closeConfig.render({ toggle: handleToggle }) : /* @__PURE__ */ jsx18(
|
|
26712
27498
|
"button",
|
|
26713
27499
|
{
|
|
26714
27500
|
type: "button",
|
|
26715
27501
|
className: "chat-popup__close-button",
|
|
26716
27502
|
onClick: handleToggle,
|
|
26717
27503
|
"aria-label": "Close chat",
|
|
26718
|
-
children: /* @__PURE__ */
|
|
27504
|
+
children: /* @__PURE__ */ jsx18(X, { className: "chat-popup__close-icon" })
|
|
26719
27505
|
}
|
|
26720
27506
|
)
|
|
26721
27507
|
}
|
|
26722
27508
|
),
|
|
26723
|
-
hasOpened && /* @__PURE__ */
|
|
27509
|
+
hasOpened && /* @__PURE__ */ jsx18(ChatWidget, { ...props })
|
|
26724
27510
|
] })
|
|
26725
27511
|
}
|
|
26726
27512
|
)
|
|
26727
27513
|
] });
|
|
26728
27514
|
}
|
|
26729
27515
|
|
|
26730
|
-
// lib/chat/widgets/
|
|
27516
|
+
// lib/chat/widgets/HybridVendorCards.tsx
|
|
26731
27517
|
import { MessageSquare as MessageSquare3, MessageSquareText as MessageSquareText2, ThumbsDown as ThumbsDown2, ThumbsUp as ThumbsUp2 } from "lucide-react";
|
|
26732
|
-
import
|
|
26733
|
-
import { Fragment as
|
|
26734
|
-
var
|
|
26735
|
-
|
|
26736
|
-
|
|
26737
|
-
|
|
26738
|
-
|
|
26739
|
-
|
|
26740
|
-
|
|
26741
|
-
|
|
26742
|
-
|
|
26743
|
-
|
|
26744
|
-
|
|
26745
|
-
|
|
26746
|
-
|
|
26747
|
-
|
|
26748
|
-
|
|
26749
|
-
|
|
26750
|
-
|
|
26751
|
-
|
|
26752
|
-
|
|
26753
|
-
|
|
26754
|
-
|
|
26755
|
-
|
|
26756
|
-
|
|
26757
|
-
|
|
26758
|
-
|
|
26759
|
-
|
|
26760
|
-
|
|
26761
|
-
|
|
26762
|
-
|
|
26763
|
-
|
|
26764
|
-
|
|
26765
|
-
// latitude: { type: 'number' },
|
|
26766
|
-
// longitude: { type: 'number' },
|
|
26767
|
-
// },
|
|
26768
|
-
// required: ['latitude', 'longitude'],
|
|
26769
|
-
// },
|
|
26770
|
-
},
|
|
26771
|
-
required: ["vendor_id"]
|
|
26772
|
-
// required: ['vendor_id', 'vendorCoordinates'],
|
|
26773
|
-
}
|
|
26774
|
-
// description: '5-7 vendors to display. With notes for the top 3 only',
|
|
26775
|
-
}
|
|
26776
|
-
},
|
|
26777
|
-
required: ["vendors"]
|
|
26778
|
-
// required: ['fromLocation', 'fromCoordinates', 'vendors'],
|
|
26779
|
-
});
|
|
26780
|
-
function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedback }) {
|
|
26781
|
-
const [feedbackState, setFeedbackState] = React8.useState({});
|
|
26782
|
-
const initializedRef = React8.useRef(false);
|
|
26783
|
-
React8.useEffect(() => {
|
|
27518
|
+
import { useEffect as useEffect8, useMemo as useMemo7, useRef as useRef6, useState as useState11 } from "react";
|
|
27519
|
+
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
27520
|
+
var vendorCardsHybridSchema = zod_default.object({
|
|
27521
|
+
fromLocation: zod_default.string().describe("The location the user is searching from"),
|
|
27522
|
+
fromCoordinates: zod_default.object({
|
|
27523
|
+
latitude: zod_default.number(),
|
|
27524
|
+
longitude: zod_default.number()
|
|
27525
|
+
}).describe("The user's lat/lng coordinates from geocoding"),
|
|
27526
|
+
vendors: zod_default.array(zod_default.object({
|
|
27527
|
+
vendor_id: zod_default.string(),
|
|
27528
|
+
notes: zod_default.string().optional().describe("7-10 words on why this vendor was recommended. Be brief and concise - do not include unecessary details such as vendor names.")
|
|
27529
|
+
}))
|
|
27530
|
+
}).describe("Display vendor cards. Only vendor IDs needed - details enriched server-side, distances fetched client-side.");
|
|
27531
|
+
function HybridVendorCards({
|
|
27532
|
+
payload,
|
|
27533
|
+
serverEnriched,
|
|
27534
|
+
distanceMatrixToolId,
|
|
27535
|
+
invokeTool,
|
|
27536
|
+
messageContext
|
|
27537
|
+
}) {
|
|
27538
|
+
const [distanceMatrix, setDistanceMatrix] = useState11();
|
|
27539
|
+
const [loadingDistance, setLoadingDistance] = useState11(true);
|
|
27540
|
+
const [feedbackState, setFeedbackState] = useState11({});
|
|
27541
|
+
const hasFetchedRef = useRef6(false);
|
|
27542
|
+
const initializedRef = useRef6(false);
|
|
27543
|
+
const vendorIds = useMemo7(
|
|
27544
|
+
() => payload.vendors.map((v) => v.vendor_id).join(","),
|
|
27545
|
+
[payload.vendors]
|
|
27546
|
+
);
|
|
27547
|
+
const originKey = `${payload.fromCoordinates.latitude},${payload.fromCoordinates.longitude}`;
|
|
27548
|
+
const hasVendorDetails = serverEnriched.vendorDetails?.success ?? false;
|
|
27549
|
+
const existingFeedback = messageContext?.getFeedback?.()?.notes;
|
|
27550
|
+
useEffect8(() => {
|
|
26784
27551
|
if (!initializedRef.current && existingFeedback && existingFeedback.length > 0) {
|
|
26785
27552
|
initializedRef.current = true;
|
|
26786
27553
|
const initialState = {};
|
|
@@ -26796,6 +27563,44 @@ function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedb
|
|
|
26796
27563
|
setFeedbackState(initialState);
|
|
26797
27564
|
}
|
|
26798
27565
|
}, [existingFeedback]);
|
|
27566
|
+
useEffect8(() => {
|
|
27567
|
+
if (hasFetchedRef.current) {
|
|
27568
|
+
return;
|
|
27569
|
+
}
|
|
27570
|
+
if (!invokeTool || !hasVendorDetails) {
|
|
27571
|
+
setLoadingDistance(false);
|
|
27572
|
+
return;
|
|
27573
|
+
}
|
|
27574
|
+
const fetchDistance = async () => {
|
|
27575
|
+
hasFetchedRef.current = true;
|
|
27576
|
+
try {
|
|
27577
|
+
const vendorDetails = serverEnriched.vendorDetails?.data;
|
|
27578
|
+
const destinations = payload.vendors.map((v) => {
|
|
27579
|
+
const detail = vendorDetails?.[v.vendor_id];
|
|
27580
|
+
return detail?.location?.coordinates ?? null;
|
|
27581
|
+
}).filter(Boolean);
|
|
27582
|
+
if (destinations.length === 0) {
|
|
27583
|
+
setLoadingDistance(false);
|
|
27584
|
+
return;
|
|
27585
|
+
}
|
|
27586
|
+
const distanceResult = await invokeTool(distanceMatrixToolId, {
|
|
27587
|
+
args: {
|
|
27588
|
+
origin: payload.fromCoordinates,
|
|
27589
|
+
destinations
|
|
27590
|
+
}
|
|
27591
|
+
});
|
|
27592
|
+
setDistanceMatrix(
|
|
27593
|
+
distanceResult.success ? { success: true, data: distanceResult.data } : { success: false }
|
|
27594
|
+
);
|
|
27595
|
+
} catch (error48) {
|
|
27596
|
+
console.warn("[HybridVendorCards] Distance fetch failed:", error48);
|
|
27597
|
+
setDistanceMatrix({ success: false });
|
|
27598
|
+
} finally {
|
|
27599
|
+
setLoadingDistance(false);
|
|
27600
|
+
}
|
|
27601
|
+
};
|
|
27602
|
+
fetchDistance();
|
|
27603
|
+
}, [invokeTool, vendorIds, originKey, hasVendorDetails, distanceMatrixToolId, payload, serverEnriched]);
|
|
26799
27604
|
const getFeedbackState = (vendorId) => {
|
|
26800
27605
|
return feedbackState[vendorId] || { rating: null, commentText: null, showComment: false };
|
|
26801
27606
|
};
|
|
@@ -26807,52 +27612,63 @@ function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedb
|
|
|
26807
27612
|
};
|
|
26808
27613
|
const removeFeedbackState = (vendorId) => {
|
|
26809
27614
|
setFeedbackState((prev) => {
|
|
26810
|
-
const { [vendorId]:
|
|
27615
|
+
const { [vendorId]: _removed, ...rest } = prev;
|
|
27616
|
+
void _removed;
|
|
26811
27617
|
return rest;
|
|
26812
27618
|
});
|
|
26813
27619
|
};
|
|
26814
|
-
const
|
|
26815
|
-
|
|
26816
|
-
|
|
27620
|
+
const handleFeedback = (noteId, feedbackPayload) => {
|
|
27621
|
+
messageContext?.submitFeedback?.({
|
|
27622
|
+
notes: [{
|
|
27623
|
+
noteId,
|
|
27624
|
+
...feedbackPayload
|
|
27625
|
+
}]
|
|
27626
|
+
});
|
|
27627
|
+
};
|
|
26817
27628
|
const formatDistance = (meters) => {
|
|
26818
27629
|
const miles = meters / 1609.34;
|
|
26819
27630
|
return miles < 0.1 ? "< 0.1 mi" : `${miles.toFixed(1)} mi`;
|
|
26820
27631
|
};
|
|
26821
|
-
|
|
26822
|
-
|
|
26823
|
-
|
|
26824
|
-
|
|
26825
|
-
|
|
26826
|
-
|
|
26827
|
-
|
|
26828
|
-
|
|
26829
|
-
|
|
26830
|
-
|
|
26831
|
-
|
|
26832
|
-
|
|
26833
|
-
|
|
26834
|
-
|
|
26835
|
-
|
|
26836
|
-
|
|
26837
|
-
|
|
26838
|
-
|
|
26839
|
-
|
|
26840
|
-
|
|
26841
|
-
|
|
26842
|
-
|
|
26843
|
-
|
|
26844
|
-
|
|
26845
|
-
|
|
26846
|
-
|
|
26847
|
-
|
|
26848
|
-
|
|
26849
|
-
|
|
26850
|
-
|
|
26851
|
-
|
|
26852
|
-
|
|
26853
|
-
|
|
26854
|
-
|
|
26855
|
-
|
|
27632
|
+
if (!serverEnriched || !serverEnriched.vendorDetails) {
|
|
27633
|
+
return /* @__PURE__ */ jsx19("div", { children: "Loading vendor details..." });
|
|
27634
|
+
}
|
|
27635
|
+
const vendorData = serverEnriched.vendorDetails?.data ?? {};
|
|
27636
|
+
const distances = distanceMatrix?.data ?? [];
|
|
27637
|
+
return /* @__PURE__ */ jsxs17("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
27638
|
+
loadingDistance && /* @__PURE__ */ jsx19("style", { children: `@keyframes hybrid-vendor-cards-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }` }),
|
|
27639
|
+
payload.vendors.map((v, index) => {
|
|
27640
|
+
const data = vendorData[v.vendor_id];
|
|
27641
|
+
const name21 = data?.names?.[0]?.value ?? "Unknown";
|
|
27642
|
+
const address = data?.location?.address;
|
|
27643
|
+
const distanceEntry = distances.find((d) => d.destinationIndex === index);
|
|
27644
|
+
const distance = distanceEntry && distanceEntry.distanceMeters ? formatDistance(distanceEntry.distanceMeters) : void 0;
|
|
27645
|
+
const hourlyRate = data?.financials?.fees?.find((f) => f.fee_type?.includes("Hourly"))?.amount;
|
|
27646
|
+
const avgRating = data?.avg_rating;
|
|
27647
|
+
const reviewCount = data?.review_count;
|
|
27648
|
+
const verification = data?.verification;
|
|
27649
|
+
const cnScore = data?.quality_scores?.completeness_score;
|
|
27650
|
+
const subtypes = data?.subtype ?? [];
|
|
27651
|
+
const careLocationType = subtypes.includes("In-Home") ? "In-Home" : subtypes.includes("In-Center") ? "In-Center" : null;
|
|
27652
|
+
const backgroundCheckStatus = data?.references_and_background_check?.background_check_status?.toLowerCase();
|
|
27653
|
+
const hasBackgroundCheck = backgroundCheckStatus === "clear" || backgroundCheckStatus === "completed";
|
|
27654
|
+
return /* @__PURE__ */ jsxs17(
|
|
27655
|
+
"div",
|
|
27656
|
+
{
|
|
27657
|
+
style: {
|
|
27658
|
+
display: "flex",
|
|
27659
|
+
flexDirection: "column",
|
|
27660
|
+
gap: "0.2rem",
|
|
27661
|
+
padding: "1rem",
|
|
27662
|
+
background: "#ffffff",
|
|
27663
|
+
border: "1px solid #e5e7eb",
|
|
27664
|
+
borderRadius: "0.5rem",
|
|
27665
|
+
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1)",
|
|
27666
|
+
fontSize: "0.875rem",
|
|
27667
|
+
position: "relative"
|
|
27668
|
+
},
|
|
27669
|
+
children: [
|
|
27670
|
+
/* @__PURE__ */ jsx19("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start" }, children: /* @__PURE__ */ jsxs17("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
27671
|
+
/* @__PURE__ */ jsx19("div", { style: {
|
|
26856
27672
|
width: "2rem",
|
|
26857
27673
|
height: "2rem",
|
|
26858
27674
|
borderRadius: "9999px",
|
|
@@ -26864,163 +27680,111 @@ function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedb
|
|
|
26864
27680
|
fontSize: "0.875rem",
|
|
26865
27681
|
color: "#374151"
|
|
26866
27682
|
}, children: name21.charAt(0).toUpperCase() }),
|
|
26867
|
-
/* @__PURE__ */
|
|
27683
|
+
/* @__PURE__ */ jsx19("span", { style: { fontWeight: 600, fontSize: "1rem", color: "#111827" }, children: name21 })
|
|
27684
|
+
] }) }),
|
|
27685
|
+
(reviewCount != null || cnScore != null) && /* @__PURE__ */ jsxs17("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", color: "#6b7280" }, children: [
|
|
27686
|
+
avgRating != null && /* @__PURE__ */ jsxs17(Fragment6, { children: [
|
|
27687
|
+
/* @__PURE__ */ jsx19("span", { style: { color: "#facc15" }, children: "\u2605" }),
|
|
27688
|
+
/* @__PURE__ */ jsx19("span", { children: avgRating.toFixed(1) }),
|
|
27689
|
+
reviewCount != null && /* @__PURE__ */ jsxs17("span", { style: { color: "#9ca3af" }, children: [
|
|
27690
|
+
"(",
|
|
27691
|
+
reviewCount,
|
|
27692
|
+
" reviews)"
|
|
27693
|
+
] })
|
|
27694
|
+
] }),
|
|
27695
|
+
avgRating != null && cnScore != null ? /* @__PURE__ */ jsx19("span", { style: { color: "#9ca3af" }, children: "\u2022" }) : null,
|
|
27696
|
+
cnScore != null ? /* @__PURE__ */ jsxs17("span", { children: [
|
|
27697
|
+
"CN Score: ",
|
|
27698
|
+
cnScore
|
|
27699
|
+
] }) : null
|
|
26868
27700
|
] }),
|
|
26869
|
-
|
|
26870
|
-
|
|
26871
|
-
|
|
26872
|
-
|
|
26873
|
-
|
|
26874
|
-
|
|
26875
|
-
|
|
26876
|
-
|
|
26877
|
-
|
|
26878
|
-
|
|
26879
|
-
|
|
26880
|
-
|
|
26881
|
-
|
|
26882
|
-
}
|
|
26883
|
-
|
|
26884
|
-
|
|
26885
|
-
|
|
26886
|
-
|
|
26887
|
-
|
|
26888
|
-
|
|
26889
|
-
|
|
26890
|
-
|
|
26891
|
-
|
|
26892
|
-
"
|
|
27701
|
+
careLocationType && /* @__PURE__ */ jsx19("div", { style: { color: "#6b7280" }, children: careLocationType }),
|
|
27702
|
+
address && /* @__PURE__ */ jsx19("div", { style: { color: "#6b7280" }, children: address }),
|
|
27703
|
+
/* @__PURE__ */ jsx19("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280", minHeight: "1.25rem" }, children: loadingDistance ? /* @__PURE__ */ jsxs17(Fragment6, { children: [
|
|
27704
|
+
/* @__PURE__ */ jsx19("span", { children: "\u{1F4CD}" }),
|
|
27705
|
+
/* @__PURE__ */ jsx19("span", { style: {
|
|
27706
|
+
width: "100px",
|
|
27707
|
+
height: "0.875rem",
|
|
27708
|
+
background: "linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%)",
|
|
27709
|
+
backgroundSize: "200% 100%",
|
|
27710
|
+
animation: "hybrid-vendor-cards-shimmer 1.5s infinite",
|
|
27711
|
+
borderRadius: "0.25rem"
|
|
27712
|
+
} })
|
|
27713
|
+
] }) : distance ? /* @__PURE__ */ jsxs17(Fragment6, { children: [
|
|
27714
|
+
/* @__PURE__ */ jsx19("span", { children: "\u{1F4CD}" }),
|
|
27715
|
+
/* @__PURE__ */ jsxs17("span", { children: [
|
|
27716
|
+
distance,
|
|
27717
|
+
" from ",
|
|
27718
|
+
payload.fromLocation
|
|
27719
|
+
] })
|
|
27720
|
+
] }) : null }),
|
|
27721
|
+
hourlyRate && /* @__PURE__ */ jsxs17("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280" }, children: [
|
|
27722
|
+
/* @__PURE__ */ jsx19("span", { children: "\u{1F4B0}" }),
|
|
27723
|
+
/* @__PURE__ */ jsxs17("span", { children: [
|
|
27724
|
+
"Rate: $",
|
|
27725
|
+
hourlyRate,
|
|
27726
|
+
"/hr"
|
|
26893
27727
|
] })
|
|
26894
27728
|
] }),
|
|
26895
|
-
|
|
26896
|
-
|
|
26897
|
-
"
|
|
26898
|
-
|
|
26899
|
-
] })
|
|
26900
|
-
|
|
26901
|
-
|
|
26902
|
-
|
|
26903
|
-
|
|
26904
|
-
|
|
26905
|
-
|
|
26906
|
-
|
|
26907
|
-
|
|
26908
|
-
|
|
26909
|
-
|
|
26910
|
-
|
|
26911
|
-
|
|
26912
|
-
|
|
26913
|
-
|
|
26914
|
-
|
|
26915
|
-
|
|
26916
|
-
|
|
26917
|
-
|
|
26918
|
-
|
|
26919
|
-
|
|
26920
|
-
|
|
26921
|
-
|
|
26922
|
-
|
|
26923
|
-
|
|
26924
|
-
|
|
26925
|
-
|
|
26926
|
-
|
|
26927
|
-
|
|
26928
|
-
const handleRatingClick = (rating) => {
|
|
26929
|
-
const currentState = getFeedbackState(v.vendor_id);
|
|
26930
|
-
if (currentState.rating === rating) {
|
|
26931
|
-
removeFeedbackState(v.vendor_id);
|
|
26932
|
-
onFeedback?.(v.vendor_id, {});
|
|
26933
|
-
} else {
|
|
26934
|
-
updateFeedbackState(v.vendor_id, { rating });
|
|
26935
|
-
onFeedback?.(v.vendor_id, { rating, vendorId: v.vendor_id, vendorName: name21 });
|
|
26936
|
-
}
|
|
26937
|
-
};
|
|
26938
|
-
const handleCommentToggle = () => {
|
|
26939
|
-
const currentState = getFeedbackState(v.vendor_id);
|
|
26940
|
-
updateFeedbackState(v.vendor_id, { showComment: !currentState.showComment });
|
|
26941
|
-
};
|
|
26942
|
-
const handleCommentSubmit = () => {
|
|
26943
|
-
const currentState = getFeedbackState(v.vendor_id);
|
|
26944
|
-
const trimmedComment = currentState.commentText?.trim();
|
|
26945
|
-
if (trimmedComment) {
|
|
26946
|
-
updateFeedbackState(v.vendor_id, { showComment: false, commentText: trimmedComment });
|
|
26947
|
-
onFeedback?.(v.vendor_id, { comment: trimmedComment, vendorId: v.vendor_id, vendorName: name21 });
|
|
26948
|
-
}
|
|
26949
|
-
};
|
|
26950
|
-
return /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
26951
|
-
/* @__PURE__ */ jsxs10("div", { style: {
|
|
26952
|
-
display: "flex",
|
|
26953
|
-
flexWrap: "wrap",
|
|
26954
|
-
gap: "0.5rem",
|
|
26955
|
-
// marginTop: '0.25rem',
|
|
26956
|
-
alignItems: "center",
|
|
26957
|
-
minHeight: "1.75rem"
|
|
26958
|
-
}, children: [
|
|
26959
|
-
verification?.verified && /* @__PURE__ */ jsxs10("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
|
|
26960
|
-
/* @__PURE__ */ jsx11("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
|
|
26961
|
-
" Wellthy Verified"
|
|
26962
|
-
] }),
|
|
26963
|
-
hasBackgroundCheck && /* @__PURE__ */ jsxs10("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
|
|
26964
|
-
/* @__PURE__ */ jsx11("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
|
|
26965
|
-
" Background check"
|
|
26966
|
-
] }),
|
|
26967
|
-
onFeedback && /* @__PURE__ */ jsxs10("div", { style: {
|
|
26968
|
-
marginLeft: "auto",
|
|
27729
|
+
v.notes && /* @__PURE__ */ jsxs17("div", { style: { color: "#374151", marginTop: "0.4rem" }, children: [
|
|
27730
|
+
/* @__PURE__ */ jsx19("span", { style: { marginRight: "0.25rem" }, children: "\u2728" }),
|
|
27731
|
+
/* @__PURE__ */ jsx19("strong", { children: "Recommendation notes" }),
|
|
27732
|
+
/* @__PURE__ */ jsx19("div", { style: { marginLeft: "1.25rem", marginTop: "0.25rem", color: "#6b7280" }, children: v.notes })
|
|
27733
|
+
] }),
|
|
27734
|
+
(() => {
|
|
27735
|
+
const state = getFeedbackState(v.vendor_id);
|
|
27736
|
+
const isPositiveSelected = state.rating === "positive";
|
|
27737
|
+
const isNegativeSelected = state.rating === "negative";
|
|
27738
|
+
const handleRatingClick = (rating) => {
|
|
27739
|
+
const currentState = getFeedbackState(v.vendor_id);
|
|
27740
|
+
if (currentState.rating === rating) {
|
|
27741
|
+
removeFeedbackState(v.vendor_id);
|
|
27742
|
+
handleFeedback(v.vendor_id, {});
|
|
27743
|
+
} else {
|
|
27744
|
+
updateFeedbackState(v.vendor_id, { rating });
|
|
27745
|
+
handleFeedback(v.vendor_id, { rating, vendorId: v.vendor_id, vendorName: name21 });
|
|
27746
|
+
}
|
|
27747
|
+
};
|
|
27748
|
+
const handleCommentToggle = () => {
|
|
27749
|
+
const currentState = getFeedbackState(v.vendor_id);
|
|
27750
|
+
updateFeedbackState(v.vendor_id, { showComment: !currentState.showComment });
|
|
27751
|
+
};
|
|
27752
|
+
const handleCommentSubmit = () => {
|
|
27753
|
+
const currentState = getFeedbackState(v.vendor_id);
|
|
27754
|
+
const trimmedComment = currentState.commentText?.trim();
|
|
27755
|
+
if (trimmedComment) {
|
|
27756
|
+
updateFeedbackState(v.vendor_id, { showComment: false, commentText: trimmedComment });
|
|
27757
|
+
handleFeedback(v.vendor_id, { comment: trimmedComment, vendorId: v.vendor_id, vendorName: name21 });
|
|
27758
|
+
}
|
|
27759
|
+
};
|
|
27760
|
+
return /* @__PURE__ */ jsxs17(Fragment6, { children: [
|
|
27761
|
+
/* @__PURE__ */ jsxs17("div", { style: {
|
|
26969
27762
|
display: "flex",
|
|
26970
|
-
|
|
26971
|
-
|
|
27763
|
+
flexWrap: "wrap",
|
|
27764
|
+
gap: "0.5rem",
|
|
27765
|
+
alignItems: "center",
|
|
27766
|
+
minHeight: "1.75rem"
|
|
26972
27767
|
}, children: [
|
|
26973
|
-
/* @__PURE__ */
|
|
26974
|
-
"
|
|
26975
|
-
|
|
26976
|
-
|
|
26977
|
-
|
|
26978
|
-
|
|
26979
|
-
|
|
26980
|
-
|
|
26981
|
-
|
|
26982
|
-
|
|
26983
|
-
|
|
26984
|
-
|
|
26985
|
-
|
|
26986
|
-
|
|
26987
|
-
|
|
26988
|
-
height: "1.75rem"
|
|
26989
|
-
},
|
|
26990
|
-
title: "This vendor was helpful",
|
|
26991
|
-
children: /* @__PURE__ */ jsx11(ThumbsUp2, { style: { width: "1rem", height: "1rem" } })
|
|
26992
|
-
}
|
|
26993
|
-
),
|
|
26994
|
-
/* @__PURE__ */ jsx11(
|
|
26995
|
-
"button",
|
|
26996
|
-
{
|
|
26997
|
-
onClick: () => handleRatingClick("negative"),
|
|
26998
|
-
style: {
|
|
26999
|
-
background: isNegativeSelected ? "rgba(239, 68, 68, 0.1)" : "transparent",
|
|
27000
|
-
border: "none",
|
|
27001
|
-
borderRadius: "0.35rem",
|
|
27002
|
-
padding: "0.25rem",
|
|
27003
|
-
cursor: "pointer",
|
|
27004
|
-
display: "flex",
|
|
27005
|
-
alignItems: "center",
|
|
27006
|
-
justifyContent: "center",
|
|
27007
|
-
color: isNegativeSelected ? "#ef4444" : "#9ca3af",
|
|
27008
|
-
width: "1.75rem",
|
|
27009
|
-
height: "1.75rem"
|
|
27010
|
-
},
|
|
27011
|
-
title: "This vendor was not helpful",
|
|
27012
|
-
children: /* @__PURE__ */ jsx11(ThumbsDown2, { style: { width: "1rem", height: "1rem" } })
|
|
27013
|
-
}
|
|
27014
|
-
),
|
|
27015
|
-
(() => {
|
|
27016
|
-
const hasComment = !!state.commentText?.trim();
|
|
27017
|
-
const CommentIcon = hasComment ? MessageSquareText2 : MessageSquare3;
|
|
27018
|
-
return /* @__PURE__ */ jsx11(
|
|
27768
|
+
verification?.verified && /* @__PURE__ */ jsxs17("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
|
|
27769
|
+
/* @__PURE__ */ jsx19("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
|
|
27770
|
+
" Wellthy Verified"
|
|
27771
|
+
] }),
|
|
27772
|
+
hasBackgroundCheck && /* @__PURE__ */ jsxs17("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
|
|
27773
|
+
/* @__PURE__ */ jsx19("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
|
|
27774
|
+
" Background check"
|
|
27775
|
+
] }),
|
|
27776
|
+
messageContext && /* @__PURE__ */ jsxs17("div", { style: {
|
|
27777
|
+
marginLeft: "auto",
|
|
27778
|
+
display: "flex",
|
|
27779
|
+
gap: "0.25rem",
|
|
27780
|
+
alignItems: "center"
|
|
27781
|
+
}, children: [
|
|
27782
|
+
/* @__PURE__ */ jsx19(
|
|
27019
27783
|
"button",
|
|
27020
27784
|
{
|
|
27021
|
-
onClick:
|
|
27785
|
+
onClick: () => handleRatingClick("positive"),
|
|
27022
27786
|
style: {
|
|
27023
|
-
background:
|
|
27787
|
+
background: isPositiveSelected ? "rgba(34, 197, 94, 0.1)" : "transparent",
|
|
27024
27788
|
border: "none",
|
|
27025
27789
|
borderRadius: "0.35rem",
|
|
27026
27790
|
padding: "0.25rem",
|
|
@@ -27028,96 +27792,190 @@ function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedb
|
|
|
27028
27792
|
display: "flex",
|
|
27029
27793
|
alignItems: "center",
|
|
27030
27794
|
justifyContent: "center",
|
|
27031
|
-
color:
|
|
27795
|
+
color: isPositiveSelected ? "#22c55e" : "#9ca3af",
|
|
27032
27796
|
width: "1.75rem",
|
|
27033
27797
|
height: "1.75rem"
|
|
27034
27798
|
},
|
|
27035
|
-
title:
|
|
27036
|
-
children: /* @__PURE__ */
|
|
27799
|
+
title: "This vendor was helpful",
|
|
27800
|
+
children: /* @__PURE__ */ jsx19(ThumbsUp2, { style: { width: "1rem", height: "1rem" } })
|
|
27037
27801
|
}
|
|
27038
|
-
)
|
|
27039
|
-
|
|
27040
|
-
|
|
27041
|
-
|
|
27042
|
-
|
|
27043
|
-
|
|
27044
|
-
|
|
27045
|
-
|
|
27046
|
-
|
|
27047
|
-
|
|
27048
|
-
|
|
27049
|
-
|
|
27050
|
-
|
|
27051
|
-
|
|
27052
|
-
|
|
27053
|
-
|
|
27054
|
-
|
|
27055
|
-
|
|
27056
|
-
|
|
27057
|
-
|
|
27058
|
-
|
|
27059
|
-
|
|
27060
|
-
|
|
27061
|
-
|
|
27062
|
-
|
|
27063
|
-
|
|
27064
|
-
|
|
27065
|
-
|
|
27066
|
-
|
|
27067
|
-
|
|
27068
|
-
|
|
27069
|
-
|
|
27070
|
-
|
|
27071
|
-
|
|
27072
|
-
|
|
27073
|
-
|
|
27074
|
-
|
|
27802
|
+
),
|
|
27803
|
+
/* @__PURE__ */ jsx19(
|
|
27804
|
+
"button",
|
|
27805
|
+
{
|
|
27806
|
+
onClick: () => handleRatingClick("negative"),
|
|
27807
|
+
style: {
|
|
27808
|
+
background: isNegativeSelected ? "rgba(239, 68, 68, 0.1)" : "transparent",
|
|
27809
|
+
border: "none",
|
|
27810
|
+
borderRadius: "0.35rem",
|
|
27811
|
+
padding: "0.25rem",
|
|
27812
|
+
cursor: "pointer",
|
|
27813
|
+
display: "flex",
|
|
27814
|
+
alignItems: "center",
|
|
27815
|
+
justifyContent: "center",
|
|
27816
|
+
color: isNegativeSelected ? "#ef4444" : "#9ca3af",
|
|
27817
|
+
width: "1.75rem",
|
|
27818
|
+
height: "1.75rem"
|
|
27819
|
+
},
|
|
27820
|
+
title: "This vendor was not helpful",
|
|
27821
|
+
children: /* @__PURE__ */ jsx19(ThumbsDown2, { style: { width: "1rem", height: "1rem" } })
|
|
27822
|
+
}
|
|
27823
|
+
),
|
|
27824
|
+
(() => {
|
|
27825
|
+
const hasComment = !!state.commentText?.trim();
|
|
27826
|
+
const CommentIcon = hasComment ? MessageSquareText2 : MessageSquare3;
|
|
27827
|
+
return /* @__PURE__ */ jsx19(
|
|
27828
|
+
"button",
|
|
27829
|
+
{
|
|
27830
|
+
onClick: handleCommentToggle,
|
|
27831
|
+
style: {
|
|
27832
|
+
background: state.showComment ? "rgba(0, 0, 0, 0.05)" : "transparent",
|
|
27833
|
+
border: "none",
|
|
27834
|
+
borderRadius: "0.35rem",
|
|
27835
|
+
padding: "0.25rem",
|
|
27836
|
+
cursor: "pointer",
|
|
27837
|
+
display: "flex",
|
|
27838
|
+
alignItems: "center",
|
|
27839
|
+
justifyContent: "center",
|
|
27840
|
+
color: hasComment ? "#3b82f6" : state.showComment ? "#6b7280" : "#9ca3af",
|
|
27841
|
+
width: "1.75rem",
|
|
27842
|
+
height: "1.75rem"
|
|
27843
|
+
},
|
|
27844
|
+
title: hasComment ? "Edit comment" : "Add comment",
|
|
27845
|
+
children: /* @__PURE__ */ jsx19(CommentIcon, { style: { width: "1rem", height: "1rem" } })
|
|
27846
|
+
}
|
|
27847
|
+
);
|
|
27848
|
+
})()
|
|
27849
|
+
] })
|
|
27850
|
+
] }),
|
|
27851
|
+
state.showComment && /* @__PURE__ */ jsx19("div", { style: {
|
|
27852
|
+
position: "absolute",
|
|
27853
|
+
bottom: 0,
|
|
27854
|
+
left: 0,
|
|
27855
|
+
right: 0,
|
|
27856
|
+
background: "#ffffff",
|
|
27857
|
+
borderTop: "1px solid #e5e7eb",
|
|
27858
|
+
borderRadius: "0 0 0.5rem 0.5rem",
|
|
27859
|
+
padding: "0.75rem 1rem",
|
|
27860
|
+
boxShadow: "0 -2px 8px rgba(0, 0, 0, 0.1)"
|
|
27861
|
+
}, children: /* @__PURE__ */ jsxs17("div", { style: { display: "flex", gap: "0.5rem", alignItems: "flex-start" }, children: [
|
|
27862
|
+
/* @__PURE__ */ jsx19(
|
|
27863
|
+
"textarea",
|
|
27075
27864
|
{
|
|
27076
|
-
|
|
27077
|
-
|
|
27865
|
+
placeholder: "Share your thoughts about this vendor...",
|
|
27866
|
+
value: state.commentText ?? "",
|
|
27867
|
+
onChange: (e) => updateFeedbackState(v.vendor_id, { commentText: e.target.value }),
|
|
27868
|
+
rows: 2,
|
|
27078
27869
|
style: {
|
|
27079
|
-
|
|
27080
|
-
|
|
27081
|
-
|
|
27082
|
-
borderRadius: "0.
|
|
27083
|
-
|
|
27084
|
-
|
|
27085
|
-
|
|
27086
|
-
|
|
27087
|
-
|
|
27088
|
-
},
|
|
27089
|
-
children: "Save"
|
|
27870
|
+
flex: 1,
|
|
27871
|
+
padding: "0.5rem",
|
|
27872
|
+
border: "1px solid #e5e7eb",
|
|
27873
|
+
borderRadius: "0.35rem",
|
|
27874
|
+
fontSize: "0.875rem",
|
|
27875
|
+
fontFamily: "inherit",
|
|
27876
|
+
resize: "none",
|
|
27877
|
+
minHeight: "50px"
|
|
27878
|
+
}
|
|
27090
27879
|
}
|
|
27091
27880
|
),
|
|
27092
|
-
/* @__PURE__ */
|
|
27093
|
-
|
|
27094
|
-
|
|
27095
|
-
|
|
27096
|
-
|
|
27097
|
-
|
|
27098
|
-
|
|
27099
|
-
|
|
27100
|
-
|
|
27101
|
-
|
|
27102
|
-
|
|
27103
|
-
|
|
27104
|
-
|
|
27105
|
-
|
|
27106
|
-
|
|
27107
|
-
|
|
27108
|
-
|
|
27109
|
-
|
|
27110
|
-
|
|
27111
|
-
|
|
27112
|
-
|
|
27113
|
-
|
|
27114
|
-
|
|
27115
|
-
|
|
27116
|
-
|
|
27881
|
+
/* @__PURE__ */ jsxs17("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
|
|
27882
|
+
/* @__PURE__ */ jsx19(
|
|
27883
|
+
"button",
|
|
27884
|
+
{
|
|
27885
|
+
onClick: handleCommentSubmit,
|
|
27886
|
+
disabled: !state.commentText?.trim(),
|
|
27887
|
+
style: {
|
|
27888
|
+
padding: "0.35rem 0.75rem",
|
|
27889
|
+
fontSize: "0.75rem",
|
|
27890
|
+
fontWeight: 500,
|
|
27891
|
+
borderRadius: "0.3rem",
|
|
27892
|
+
cursor: state.commentText?.trim() ? "pointer" : "not-allowed",
|
|
27893
|
+
background: "#3b82f6",
|
|
27894
|
+
border: "none",
|
|
27895
|
+
color: "#ffffff",
|
|
27896
|
+
opacity: state.commentText?.trim() ? 1 : 0.5
|
|
27897
|
+
},
|
|
27898
|
+
children: "Save"
|
|
27899
|
+
}
|
|
27900
|
+
),
|
|
27901
|
+
/* @__PURE__ */ jsx19(
|
|
27902
|
+
"button",
|
|
27903
|
+
{
|
|
27904
|
+
onClick: handleCommentToggle,
|
|
27905
|
+
style: {
|
|
27906
|
+
padding: "0.25rem 0.5rem",
|
|
27907
|
+
fontSize: "0.75rem",
|
|
27908
|
+
fontWeight: 500,
|
|
27909
|
+
background: "transparent",
|
|
27910
|
+
border: "none",
|
|
27911
|
+
color: "#9ca3af",
|
|
27912
|
+
cursor: "pointer"
|
|
27913
|
+
},
|
|
27914
|
+
children: "Cancel"
|
|
27915
|
+
}
|
|
27916
|
+
)
|
|
27917
|
+
] })
|
|
27918
|
+
] }) })
|
|
27919
|
+
] });
|
|
27920
|
+
})()
|
|
27921
|
+
]
|
|
27922
|
+
},
|
|
27923
|
+
v.vendor_id
|
|
27924
|
+
);
|
|
27925
|
+
})
|
|
27926
|
+
] });
|
|
27117
27927
|
}
|
|
27118
27928
|
|
|
27929
|
+
// lib/chat/widgets/VendorCards.tsx
|
|
27930
|
+
import { MessageSquare as MessageSquare4, MessageSquareText as MessageSquareText3, ThumbsDown as ThumbsDown3, ThumbsUp as ThumbsUp3 } from "lucide-react";
|
|
27931
|
+
import React9 from "react";
|
|
27932
|
+
import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
27933
|
+
var vendorCardsSchema = jsonSchema({
|
|
27934
|
+
type: "object",
|
|
27935
|
+
description: "displaying a list of vendor cards. Use this widget to represent data from CareNetwork vendor search tool.",
|
|
27936
|
+
properties: {
|
|
27937
|
+
fromLocation: {
|
|
27938
|
+
type: "string",
|
|
27939
|
+
description: "The location the user is searching for"
|
|
27940
|
+
},
|
|
27941
|
+
fromCoordinates: {
|
|
27942
|
+
type: "object",
|
|
27943
|
+
description: "The location's lat/lng coordinates. This must come from the previous geocoding tool as-is - do NOT guess",
|
|
27944
|
+
properties: {
|
|
27945
|
+
latitude: { type: "number" },
|
|
27946
|
+
longitude: { type: "number" }
|
|
27947
|
+
},
|
|
27948
|
+
required: ["latitude", "longitude"]
|
|
27949
|
+
},
|
|
27950
|
+
vendors: {
|
|
27951
|
+
type: "array",
|
|
27952
|
+
items: {
|
|
27953
|
+
type: "object",
|
|
27954
|
+
properties: {
|
|
27955
|
+
vendor_id: { type: "string" },
|
|
27956
|
+
notes: {
|
|
27957
|
+
type: "string",
|
|
27958
|
+
description: "Give 7-10 words on why this vendor was recommended"
|
|
27959
|
+
},
|
|
27960
|
+
vendorCoordinates: {
|
|
27961
|
+
type: "object",
|
|
27962
|
+
description: "The lat/lng coordinates of this vendor. This must come from the vendor's location.coordinates from the previous vendor search tool - do NOT guess",
|
|
27963
|
+
properties: {
|
|
27964
|
+
latitude: { type: "number" },
|
|
27965
|
+
longitude: { type: "number" }
|
|
27966
|
+
},
|
|
27967
|
+
required: ["latitude", "longitude"]
|
|
27968
|
+
}
|
|
27969
|
+
},
|
|
27970
|
+
required: ["vendor_id", "vendorCoordinates"]
|
|
27971
|
+
}
|
|
27972
|
+
}
|
|
27973
|
+
},
|
|
27974
|
+
required: ["fromLocation", "fromCoordinates", "vendors"]
|
|
27975
|
+
});
|
|
27976
|
+
|
|
27119
27977
|
// lib/chat/widgets/default-widgets.tsx
|
|
27120
|
-
import { jsx as
|
|
27978
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
27121
27979
|
var defaultChatWidgets = [
|
|
27122
27980
|
createSDKWidget({
|
|
27123
27981
|
widgetType: "person-card",
|
|
@@ -27126,7 +27984,7 @@ var defaultChatWidgets = [
|
|
|
27126
27984
|
photoUri: zod_default.string().optional().describe("URL to a photo of the person"),
|
|
27127
27985
|
details: zod_default.record(zod_default.string(), zod_default.any()).optional()
|
|
27128
27986
|
}).describe("showing a person card with name, photo and additional details"),
|
|
27129
|
-
render: (payload) => /* @__PURE__ */
|
|
27987
|
+
render: (payload) => /* @__PURE__ */ jsx21(
|
|
27130
27988
|
"div",
|
|
27131
27989
|
{
|
|
27132
27990
|
style: {
|
|
@@ -27139,8 +27997,8 @@ var defaultChatWidgets = [
|
|
|
27139
27997
|
borderRadius: "0.5rem",
|
|
27140
27998
|
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"
|
|
27141
27999
|
},
|
|
27142
|
-
children: /* @__PURE__ */
|
|
27143
|
-
payload.photoUri && /* @__PURE__ */
|
|
28000
|
+
children: /* @__PURE__ */ jsxs19("div", { style: { display: "flex", alignItems: "flex-start", gap: "0.75rem" }, children: [
|
|
28001
|
+
payload.photoUri && /* @__PURE__ */ jsx21(
|
|
27144
28002
|
"img",
|
|
27145
28003
|
{
|
|
27146
28004
|
src: payload.photoUri,
|
|
@@ -27155,14 +28013,14 @@ var defaultChatWidgets = [
|
|
|
27155
28013
|
loading: "lazy"
|
|
27156
28014
|
}
|
|
27157
28015
|
),
|
|
27158
|
-
/* @__PURE__ */
|
|
27159
|
-
/* @__PURE__ */
|
|
27160
|
-
payload.details ? /* @__PURE__ */
|
|
27161
|
-
/* @__PURE__ */
|
|
28016
|
+
/* @__PURE__ */ jsxs19("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
28017
|
+
/* @__PURE__ */ jsx21("div", { style: { fontWeight: 600, fontSize: "1rem", color: "#111827", marginBottom: "0.25rem" }, children: payload.name }),
|
|
28018
|
+
payload.details ? /* @__PURE__ */ jsx21("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: Object.entries(payload.details).map(([key, value]) => /* @__PURE__ */ jsxs19("div", { style: { display: "flex", gap: "0.5rem", fontSize: "0.875rem" }, children: [
|
|
28019
|
+
/* @__PURE__ */ jsxs19("span", { style: { color: "#6b7280", fontWeight: 500, minWidth: "fit-content" }, children: [
|
|
27162
28020
|
key,
|
|
27163
28021
|
":"
|
|
27164
28022
|
] }),
|
|
27165
|
-
/* @__PURE__ */
|
|
28023
|
+
/* @__PURE__ */ jsx21("span", { style: { color: "#374151" }, children: String(value) })
|
|
27166
28024
|
] }, key)) }) : null
|
|
27167
28025
|
] })
|
|
27168
28026
|
] })
|
|
@@ -27175,7 +28033,7 @@ var defaultChatWidgets = [
|
|
|
27175
28033
|
uri: zod_default.string().url(),
|
|
27176
28034
|
text: zod_default.string().optional()
|
|
27177
28035
|
}).describe("rendering a clickable link"),
|
|
27178
|
-
render: (payload) => /* @__PURE__ */
|
|
28036
|
+
render: (payload) => /* @__PURE__ */ jsx21(
|
|
27179
28037
|
"a",
|
|
27180
28038
|
{
|
|
27181
28039
|
href: payload.uri,
|
|
@@ -27215,43 +28073,25 @@ var getVendorCardsWidget = (isProd) => {
|
|
|
27215
28073
|
return [
|
|
27216
28074
|
createSDKWidget({
|
|
27217
28075
|
widgetType: "vendor-cards",
|
|
27218
|
-
schema:
|
|
28076
|
+
schema: vendorCardsHybridSchema,
|
|
28077
|
+
// Server-side enrichment for vendor details (runs parallel to LLM)
|
|
27219
28078
|
enrich: {
|
|
27220
|
-
/** fetch vendor details from the list of IDs */
|
|
27221
28079
|
vendorDetails: {
|
|
27222
28080
|
toolId: vendorDetailsToolId,
|
|
27223
28081
|
inputs: {
|
|
27224
28082
|
vendorIds: "${vendors|map('vendor_id')|join(',')}"
|
|
27225
28083
|
}
|
|
27226
28084
|
}
|
|
27227
|
-
/* calculate distance from user to each vendor */
|
|
27228
|
-
// distanceMatrix: {
|
|
27229
|
-
// toolId: distanceMatrixToolId,
|
|
27230
|
-
// inputs: {
|
|
27231
|
-
// origin: "${fromCoordinates}",
|
|
27232
|
-
// destinations: "${vendors|map('vendorCoordinates')}",
|
|
27233
|
-
// },
|
|
27234
|
-
// }
|
|
27235
28085
|
},
|
|
27236
|
-
|
|
27237
|
-
|
|
28086
|
+
// Client-side: fetch distance matrix progressively
|
|
28087
|
+
render: (payload, enriched, { messageContext, invokeTool }) => /* @__PURE__ */ jsx21(
|
|
28088
|
+
HybridVendorCards,
|
|
27238
28089
|
{
|
|
27239
28090
|
payload,
|
|
27240
|
-
enriched,
|
|
27241
|
-
|
|
27242
|
-
|
|
27243
|
-
|
|
27244
|
-
detail: { vendorId }
|
|
27245
|
-
}));
|
|
27246
|
-
},
|
|
27247
|
-
onFeedback: (noteId, payload2) => {
|
|
27248
|
-
messageContext?.submitFeedback?.({
|
|
27249
|
-
notes: [{
|
|
27250
|
-
noteId,
|
|
27251
|
-
...payload2
|
|
27252
|
-
}]
|
|
27253
|
-
});
|
|
27254
|
-
}
|
|
28091
|
+
serverEnriched: enriched,
|
|
28092
|
+
distanceMatrixToolId,
|
|
28093
|
+
invokeTool,
|
|
28094
|
+
messageContext
|
|
27255
28095
|
}
|
|
27256
28096
|
)
|
|
27257
28097
|
})
|
|
@@ -27272,6 +28112,7 @@ export {
|
|
|
27272
28112
|
createSDKWidget,
|
|
27273
28113
|
createWidget,
|
|
27274
28114
|
defaultChatWidgets,
|
|
28115
|
+
fetchApprovalConfig,
|
|
27275
28116
|
getVendorCardsWidget,
|
|
27276
28117
|
isSDKWidget,
|
|
27277
28118
|
registerChatWidgets,
|