@bmx-labs/chat-widget 0.0.2 → 0.0.4

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/styles.css CHANGED
@@ -1 +1 @@
1
- [data-bmx-chat-bot-root]{--bmx-font-family: "Darker Grotesque", system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica Neue, Arial, sans-serif;--bmx-color-accent: #0153ff;--bmx-color-bg: #060911;--bmx-color-panel: #090d18;--bmx-color-border: #1f2937;--bmx-color-text: #e5e7eb;--bmx-color-title: #f3f4f6;--bmx-color-button-bg: #111827;--bmx-color-user-bubble: #1d4ed8;--bmx-color-input-bg: #0b1220}.orb-container{position:relative;z-index:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.orb-container canvas{display:block;width:100% !important;height:100% !important;object-fit:contain}.iridescence-container{width:100%;height:100%}.bmxcb{font-family:var(--bmx-font-family)}.bmxcb__button{cursor:pointer;width:56px;height:56px;border-radius:28px;background:var(--bmx-color-button-bg);color:#fff;border:1px solid var(--bmx-color-bg);box-shadow:0 8px 24px rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center}.bmxcb__orb-button{cursor:pointer;width:60px;height:60px;border:none;border-radius:50%;padding:0;overflow:hidden;background:rgba(0,0,0,0);position:relative;display:flex;align-items:center;justify-content:center;box-shadow:0 8px 24px rgba(0,0,0,.3)}.bmxcb__orb-button .orb-container{width:100%;height:100%;position:relative;display:flex;align-items:center;justify-content:center}.bmxcb__orb-button .orb-container canvas{width:100% !important;height:100% !important;display:block !important;object-fit:contain;border-radius:50%}.bmxcb__panel{position:absolute;right:0;bottom:64px;width:360px;max-width:calc(100vw - 32px);max-height:70vh;min-height:400px;background:var(--bmx-color-bg);color:var(--bmx-color-text);border:1px solid var(--bmx-color-border);border-radius:12px;overflow:hidden;box-shadow:0 16px 48px rgba(0,0,0,.4);display:flex;flex-direction:column}.bmxcb__header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;font-weight:600;background:var(--bmx-color-panel);color:var(--bmx-color-title);height:45px}.bmxcb__messages{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;scroll-behavior:smooth;max-height:400px;position:relative}.bmxcb__messages::-webkit-scrollbar{width:6px}.bmxcb__messages::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.bmxcb__messages::-webkit-scrollbar-thumb{background:var(--bmx-color-border);border-radius:3px}.bmxcb__messages::-webkit-scrollbar-thumb:hover{background:var(--bmx-color-text)}.bmxcb__scroll-to-bottom{position:sticky;bottom:12px;width:32px;height:32px;border-radius:50%;background:var(--bmx-color-accent);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:16px;box-shadow:0 2px 8px rgba(0,0,0,.2);transition:all .2s ease;z-index:10;margin:0 auto;margin-top:auto;flex-shrink:0}.bmxcb__scroll-to-bottom:hover{background:#0041cc;transform:scale(1.1)}.bmxcb__message{margin:8px 0}.bmxcb__message--user{display:flex;justify-content:flex-end;align-self:flex-end;max-width:80%}.bmxcb__message--assistant{display:flex;align-items:flex-start;gap:12px;justify-content:flex-start;align-self:flex-start;max-width:100%}.bmxcb__message-avatar{flex-shrink:0;margin-top:4px}.bmxcb__avatar{width:32px;height:32px;border-radius:50%;background:var(--bmx-color-accent);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 8px rgba(0,0,0,.1);overflow:hidden;border:.5px solid var(--bmx-color-border)}.bmxcb__avatar-icon{font-size:16px;line-height:1}.bmxcb__message-content{min-width:0;position:relative}.bmxcb__typing{display:inline-flex;align-items:center;gap:4px;background:var(--bmx-color-panel);border:1px solid var(--bmx-color-border);border-radius:12px;padding:6px 10px}.bmxcb__dot{width:6px;height:6px;border-radius:50%;background:var(--bmx-color-text);opacity:.4}.bmxcb__message-text{padding:6px 10px;border-radius:10px;font-size:15px;line-height:1.4;word-wrap:break-word;overflow-wrap:break-word;background:var(--bmx-color-accent);color:#fff;text-align:right;display:inline-block;max-width:100%;min-width:0}.bmxcb__message-time{margin-top:4px;font-size:12px;color:#9ca3af}.bmxcb__message-time--user{text-align:right}.bmxcb__input{flex:1;color:var(--bmx-color-text);background:var(--bmx-color-input-bg);border:1px solid var(--bmx-color-border);border-radius:8px;padding:10px 10px;resize:none;font-family:var(--bmx-font-family);font-size:16px;font-weight:400;line-height:12px}.bmxcb__input:focus{outline:none;border-color:var(--bmx-color-accent);box-shadow:0 0 0 2px rgba(1,83,255,.2)}.bmxcb__inputRow{padding:10px;border-top:1px solid var(--bmx-color-border);background:var(--bmx-color-panel);display:flex;align-items:center;gap:8px}.bmxcb__send{background:var(--bmx-color-accent);color:#fff;padding:8px;border-radius:8px;cursor:pointer;border:none;display:flex;align-items:center;justify-content:center;min-width:36px;height:36px;line-height:10px}.bmxcb__send:disabled{cursor:not-allowed;opacity:.6}.bmxcb__close{cursor:pointer;color:var(--bmx-color-text);padding:6px;background:none;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease}.bmxcb__close:hover{background-color:hsla(0,0%,100%,.1)}.bmxcb__header-actions{display:flex;align-items:center;gap:4px}.bmxcb__settings-button{cursor:pointer;color:var(--bmx-color-text);padding:6px;background:none;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease}.bmxcb__settings-button:hover{background-color:hsla(0,0%,100%,.1)}.bmxcb__settings-panel{flex:1;display:flex;flex-direction:column;overflow:hidden}.bmxcb__settings-header{display:flex;align-items:center;justify-content:space-between;padding:6px 24px;border-bottom:1px solid var(--bmx-color-border);background:var(--bmx-color-panel);height:45px}.bmxcb__settings-title{display:flex;align-items:center;gap:8px;font-weight:600;color:var(--bmx-color-title);font-size:16px}.bmxcb__settings-close{cursor:pointer;color:var(--bmx-color-text);padding:6px;background:none;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease}.bmxcb__settings-close:hover{background-color:hsla(0,0%,100%,.1)}.bmxcb__settings-content{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:24px;justify-content:space-between}.bmxcb__settings-section{display:flex;flex-direction:column;gap:16px}.bmxcb__settings-section-title{display:flex;align-items:center;gap:8px;font-weight:600;color:var(--bmx-color-title);font-size:14px;margin:0}.bmxcb__settings-group{display:flex;flex-direction:column;gap:8px}.bmxcb__settings-label{font-size:14px;color:var(--bmx-color-text);font-weight:500}.bmxcb__settings-slider{width:100%;height:6px;border-radius:3px;background:var(--bmx-color-border);outline:none;cursor:pointer;appearance:none}.bmxcb__settings-slider::-webkit-slider-thumb{appearance:none;width:18px;height:18px;border-radius:50%;background:var(--bmx-color-accent);cursor:pointer;border:2px solid var(--bmx-color-bg);box-shadow:0 2px 4px rgba(0,0,0,.2)}.bmxcb__settings-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:var(--bmx-color-accent);cursor:pointer;border:2px solid var(--bmx-color-bg);box-shadow:0 2px 4px rgba(0,0,0,.2)}.bmxcb__settings-checkbox-label{display:flex;align-items:center;gap:8px;cursor:pointer;font-size:14px;color:var(--bmx-color-text)}.bmxcb__settings-checkbox{width:16px;height:16px;accent-color:var(--bmx-color-accent);cursor:pointer}.bmxcb__settings-clear-button{display:flex;align-items:center;justify-content:center;gap:8px;padding:8px 16px;background:#dc2626;color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:16px;font-weight:500;line-height:10px;transition:all .2s ease;font-family:var(--bmx-font-family)}.bmxcb__settings-clear-button:hover{background:#b91c1c;transform:translateY(-1px)}.bmxcb__settings-clear-button:active{transform:translateY(0)}.bmxcb__markdown{line-height:1.4;color:inherit;font-size:inherit;font-family:inherit;position:relative;z-index:1}.bmxcb__markdown h1,.bmxcb__markdown h2,.bmxcb__markdown h3,.bmxcb__markdown h4,.bmxcb__markdown h5,.bmxcb__markdown h6{margin:.5em 0 .25em 0;font-weight:600;line-height:1.2;color:var(--bmx-color-text)}.bmxcb__markdown h1{font-size:1.2em}.bmxcb__markdown h2{font-size:1.15em}.bmxcb__markdown h3{font-size:1.1em}.bmxcb__markdown h4,.bmxcb__markdown h5,.bmxcb__markdown h6{font-size:1.05em}.bmxcb__markdown p{margin:.4em 0;line-height:1.4}.bmxcb__markdown ul,.bmxcb__markdown ol{margin:.5em 0;padding-left:1.2em}.bmxcb__markdown li{margin:.2em 0;line-height:1.4}.bmxcb__markdown pre{background:rgba(0,0,0,.05);border:1px solid var(--bmx-color-border);border-radius:6px;padding:.75em;margin:.75em 0;overflow-x:auto;font-family:"Monaco","Menlo","Ubuntu Mono",monospace;font-size:.85em;line-height:1.3}.bmxcb__markdown code{background:rgba(0,0,0,.05);border:1px solid var(--bmx-color-border);border-radius:3px;padding:.15em .3em;font-family:"Monaco","Menlo","Ubuntu Mono",monospace;font-size:.85em;color:var(--bmx-color-accent)}.bmxcb__markdown pre code{background:none;border:none;padding:0;color:inherit}.bmxcb__markdown blockquote{margin:.75em 0;padding:.5em .75em;border-left:3px solid var(--bmx-color-accent);background:rgba(0,0,0,.02);border-radius:0 4px 4px 0;font-style:italic}.bmxcb__markdown table{width:100%;border-collapse:collapse;margin:.75em 0;border:1px solid var(--bmx-color-border);border-radius:6px;overflow:hidden}.bmxcb__markdown th,.bmxcb__markdown td{padding:.5em .75em;text-align:left;border-bottom:1px solid var(--bmx-color-border)}.bmxcb__markdown th{background:rgba(0,0,0,.02);font-weight:600}.bmxcb__markdown tr:last-child td{border-bottom:none}.bmxcb__markdown a{color:var(--bmx-color-accent);text-decoration:none;border-bottom:1px solid rgba(0,0,0,0);transition:border-color .2s ease}.bmxcb__markdown a:hover{border-bottom-color:var(--bmx-color-accent)}.bmxcb__markdown hr{border:none;height:1px;background:var(--bmx-color-border);margin:1em 0}.bmxcb__markdown strong{font-weight:600}.bmxcb__markdown em{font-style:italic}.bmxcb__markdown input[type=checkbox]{margin-right:.5em;accent-color:var(--bmx-color-accent)}.bmxcb__markdown .hljs{background:rgba(0,0,0,0) !important}
1
+ .orb-container{position:relative;z-index:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.orb-container canvas{display:block;width:100% !important;height:100% !important;object-fit:contain}.iridescence-container{width:100%;height:100%}[data-bmx-chat-bot-root]{--bmx-font-family: "Darker Grotesque", system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica Neue, Arial, sans-serif;--bmx-color-accent: #0153ff;--bmx-color-bg: #060911;--bmx-color-panel: #090d18;--bmx-color-border: #1f2937;--bmx-color-text: #e5e7eb;--bmx-color-title: #f3f4f6;--bmx-color-button-bg: #111827;--bmx-color-user-bubble: #1d4ed8;--bmx-color-input-bg: #0b1220}.bmxcb{font-family:var(--bmx-font-family)}.bmxcb__button{cursor:pointer;width:56px;height:56px;border-radius:28px;background:var(--bmx-color-button-bg);color:#fff;border:1px solid var(--bmx-color-bg);box-shadow:0 8px 24px rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center}.bmxcb__orb-button{cursor:pointer;width:60px;height:60px;border:none;border-radius:50%;padding:0;overflow:hidden;background:rgba(0,0,0,0);position:relative;display:flex;align-items:center;justify-content:center;box-shadow:0 8px 24px rgba(0,0,0,.3)}.bmxcb__orb-button .orb-container{width:100%;height:100%;position:relative;display:flex;align-items:center;justify-content:center}.bmxcb__orb-button .orb-container canvas{width:100% !important;height:100% !important;display:block !important;object-fit:contain;border-radius:50%}.bmxcb__panel{position:absolute;right:0;bottom:64px;width:360px;max-width:calc(100vw - 32px);max-height:70vh;min-height:400px;background:var(--bmx-color-bg);color:var(--bmx-color-text);border:1px solid var(--bmx-color-border);border-radius:12px;overflow:hidden;box-shadow:0 16px 48px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.2),inset 0 1px 0 hsla(0,0%,100%,.05);display:flex;flex-direction:column;z-index:1}.bmxcb__header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;font-weight:600;background:var(--bmx-color-panel);color:var(--bmx-color-title);height:45px}.bmxcb__header-brand{display:flex;align-items:center;gap:8px}.bmxcb__header-logo{height:18px;width:auto;object-fit:contain}.bmxcb__header-title{font-size:14px;font-weight:600;background:linear-gradient(135deg, var(--bmx-color-title) 0%, var(--bmx-color-accent) 100%);-webkit-background-clip:text;-webkit-text-fill-color:rgba(0,0,0,0);background-clip:text}.bmxcb__messages{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;scroll-behavior:smooth;max-height:400px;position:relative}.bmxcb__messages--empty{padding:0}.bmxcb__messages::-webkit-scrollbar{width:6px}.bmxcb__messages::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.bmxcb__messages::-webkit-scrollbar-thumb{background:var(--bmx-color-border);border-radius:3px}.bmxcb__messages::-webkit-scrollbar-thumb:hover{background:var(--bmx-color-text)}.bmxcb__empty-state{display:flex;align-items:center;justify-content:center;height:100%;min-height:300px;padding:20px;text-align:center;position:relative}.bmxcb__empty-state::before{position:absolute;top:0;left:0;width:100%;height:100%;content:"";box-shadow:-11px 13px 20px rgba(0,0,0,.15);-webkit-backdrop-filter:blur(15px);backdrop-filter:blur(15px);background:radial-gradient(55.05% 82.01% at -1.19% -1.92%, rgba(1, 83, 255, 0.6) 0%, rgba(0, 0, 0, 0.2) 100%);pointer-events:none;z-index:0}.bmxcb__empty-state-content{max-width:280px;display:flex;flex-direction:column;align-items:center;gap:16px;position:relative;z-index:1}.bmxcb__empty-state-title{font-size:19px;font-weight:600;background:linear-gradient(135deg, var(--bmx-color-text) 0%, var(--bmx-color-accent) 100%);-webkit-background-clip:text;-webkit-text-fill-color:rgba(0,0,0,0);background-clip:text;margin:0}.bmxcb__empty-state-description{font-size:15px;color:var(--bmx-color-text-muted);margin:0;line-height:1.4}.bmxcb__empty-state-suggestions{display:flex;flex-direction:column;align-items:center;gap:12px;margin-top:8px}.bmxcb__empty-state-suggestion{font-size:13px;color:var(--bmx-color-text-muted);font-weight:500}.bmxcb__empty-state-suggestion-chips{display:flex;flex-wrap:wrap;gap:8px;justify-content:center}.bmxcb__empty-state-chip{background:var(--bmx-color-bg-light);color:var(--bmx-color-text);padding:6px 12px;border-radius:16px;font-size:14px;font-weight:500;border:1px solid var(--bmx-color-border);cursor:pointer;transition:all .2s ease;outline:none;font-family:var(--bmx-font-family)}.bmxcb__empty-state-chip:hover{background:var(--bmx-color-accent);color:#fff;transform:translateY(-1px)}.bmxcb__empty-state-chip:focus{outline:1px solid var(--bmx-color-accent);outline-offset:1px;background:var(--bmx-color-accent);color:#fff}.bmxcb__empty-state-chip:active{transform:translateY(0)}.bmxcb__scroll-to-bottom{position:sticky;bottom:12px;width:32px;height:32px;border-radius:50%;background:var(--bmx-color-accent);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:16px;box-shadow:0 2px 8px rgba(0,0,0,.2);transition:all .2s ease;z-index:10;margin:0 auto;margin-top:auto;flex-shrink:0}.bmxcb__scroll-to-bottom:hover{background:#0041cc;transform:scale(1.1)}.bmxcb__message{margin:8px 0}.bmxcb__message--user{display:flex;justify-content:flex-end;align-self:flex-end;max-width:80%}.bmxcb__message--assistant{display:flex;align-items:flex-start;gap:12px;justify-content:flex-start;align-self:flex-start;max-width:100%}.bmxcb__message-avatar{flex-shrink:0;margin-top:4px}.bmxcb__avatar{width:32px;height:32px;border-radius:50%;background:var(--bmx-color-accent);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 8px rgba(0,0,0,.1);overflow:hidden;border:.5px solid var(--bmx-color-border)}.bmxcb__avatar-icon{font-size:16px;line-height:1}.bmxcb__message-content{min-width:0;position:relative}.bmxcb__typing{display:inline-flex;align-items:center;gap:4px;background:var(--bmx-color-panel);border:1px solid var(--bmx-color-border);border-radius:12px;padding:6px 10px}.bmxcb__dot{width:6px;height:6px;border-radius:50%;background:var(--bmx-color-text);opacity:.4}.bmxcb__message-text{padding:6px 10px;border-radius:10px;font-size:15px;line-height:1.4;word-wrap:break-word;overflow-wrap:break-word;background:var(--bmx-color-accent);color:#fff;text-align:right;display:inline-block;max-width:100%;min-width:0}.bmxcb__message-footer{display:flex;align-items:center;justify-content:space-between;margin-top:4px;gap:8px}.bmxcb__message-footer--user{flex-direction:row-reverse}.bmxcb__message-time{font-size:13px;color:#9ca3af;flex-shrink:0}.bmxcb__message-time--user{text-align:right}.bmxcb__message-actions{display:flex;align-items:center;gap:4px;opacity:0;transition:opacity .2s ease}.bmxcb__message-action{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;background:rgba(0,0,0,0);color:#9ca3af;border-radius:4px;cursor:pointer;transition:all .2s ease;outline:none;position:relative}.bmxcb__message-action:hover{background:hsla(0,0%,100%,.1);color:var(--bmx-color-text)}.bmxcb__message-action:focus{outline:1px solid var(--bmx-color-accent);outline-offset:1px;background:hsla(0,0%,100%,.1);color:var(--bmx-color-text)}.bmxcb__message-action:active{transform:scale(0.95)}.bmxcb__message-action[aria-label*=Copied]{color:#10b981;animation:copySuccess .3s ease}@keyframes copySuccess{0%{transform:scale(1)}50%{transform:scale(1.2)}100%{transform:scale(1)}}.bmxcb__message:hover .bmxcb__message-actions{opacity:1}.bmxcb__input{flex:1;color:var(--bmx-color-text);background:var(--bmx-color-input-bg);border:1px solid var(--bmx-color-border);border-radius:8px;padding:10px 10px;resize:none;font-family:var(--bmx-font-family);font-size:16px;font-weight:400;line-height:1.4;min-height:20px;max-height:120px;overflow-y:hidden;transition:height .2s ease}.bmxcb__input:focus{outline:none;border-color:var(--bmx-color-accent);box-shadow:0 0 0 2px rgba(1,83,255,.2)}.bmxcb__inputRow{padding:10px;border-top:1px solid var(--bmx-color-border);background:var(--bmx-color-panel);display:flex;align-items:center;gap:8px}.bmxcb__send{background:var(--bmx-color-accent);color:#fff;padding:8px;border-radius:8px;cursor:pointer;border:none;display:flex;align-items:center;justify-content:center;min-width:36px;height:36px;line-height:10px;outline:none;transition:all .2s ease}.bmxcb__send:disabled{cursor:not-allowed;opacity:.6}.bmxcb__send:focus{outline:1px solid var(--bmx-color-accent);outline-offset:1px;box-shadow:0 0 0 4px rgba(1,83,255,.2)}.bmxcb__close{cursor:pointer;color:var(--bmx-color-text);padding:6px;background:none;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease;outline:none}.bmxcb__close:hover{background-color:hsla(0,0%,100%,.1)}.bmxcb__close:focus{outline:1px solid var(--bmx-color-accent);outline-offset:1px;background-color:hsla(0,0%,100%,.1)}.bmxcb__header-actions{display:flex;align-items:center;gap:4px}.bmxcb__settings-button{cursor:pointer;color:var(--bmx-color-text);padding:6px;background:none;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease;outline:none}.bmxcb__settings-button:hover{background-color:hsla(0,0%,100%,.1)}.bmxcb__settings-button:focus{outline:1px solid var(--bmx-color-accent);outline-offset:1px;background-color:hsla(0,0%,100%,.1)}.bmxcb__settings-panel{flex:1;display:flex;flex-direction:column;overflow:hidden}.bmxcb__settings-header{display:flex;align-items:center;justify-content:space-between;padding:6px 24px;border-bottom:1px solid var(--bmx-color-border);background:var(--bmx-color-panel);height:45px}.bmxcb__settings-title{display:flex;align-items:center;gap:8px;font-weight:600;color:var(--bmx-color-title);font-size:16px}.bmxcb__settings-close{cursor:pointer;color:var(--bmx-color-text);padding:6px;background:none;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease}.bmxcb__settings-close:hover{background-color:hsla(0,0%,100%,.1)}.bmxcb__settings-content{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:24px;justify-content:space-between}.bmxcb__settings-section{display:flex;flex-direction:column;gap:16px}.bmxcb__settings-section-title{display:flex;align-items:center;gap:8px;font-weight:600;color:var(--bmx-color-title);font-size:14px;margin:0}.bmxcb__settings-group{display:flex;flex-direction:column;gap:8px}.bmxcb__settings-label{font-size:14px;color:var(--bmx-color-text);font-weight:500}.bmxcb__settings-slider{width:100%;height:6px;border-radius:3px;background:var(--bmx-color-border);outline:none;cursor:pointer;appearance:none}.bmxcb__settings-slider::-webkit-slider-thumb{appearance:none;width:18px;height:18px;border-radius:50%;background:var(--bmx-color-accent);cursor:pointer;border:2px solid var(--bmx-color-bg);box-shadow:0 2px 4px rgba(0,0,0,.2)}.bmxcb__settings-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:var(--bmx-color-accent);cursor:pointer;border:2px solid var(--bmx-color-bg);box-shadow:0 2px 4px rgba(0,0,0,.2)}.bmxcb__settings-checkbox-label{display:flex;align-items:center;gap:8px;cursor:pointer;font-size:14px;color:var(--bmx-color-text)}.bmxcb__settings-checkbox{width:15px;height:15px;accent-color:var(--bmx-color-accent);cursor:pointer}.bmxcb__settings-shortcuts{display:flex;flex-direction:column;gap:12px}.bmxcb__settings-shortcut{display:flex;align-items:center;gap:6px;font-size:14px;color:var(--bmx-color-text)}.bmxcb__settings-shortcut span{color:var(--bmx-color-text-muted);font-size:14px}.bmxcb__settings-kbd{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:2px 6px;background:var(--bmx-color-bg-light);border:1px solid var(--bmx-color-border);border-radius:4px;font-family:"Monaco","Menlo","Ubuntu Mono",monospace;font-size:11px;font-weight:600;color:var(--bmx-color-text);box-shadow:0 1px 2px rgba(0,0,0,.1)}.bmxcb__settings-clear-button{display:flex;align-items:center;justify-content:center;gap:8px;padding:8px 16px;background:#dc2626;color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:16px;font-weight:500;line-height:10px;transition:all .2s ease;font-family:var(--bmx-font-family)}.bmxcb__settings-clear-button:hover{background:#b91c1c;transform:translateY(-1px)}.bmxcb__settings-clear-button:active{transform:translateY(0)}.bmxcb__markdown{line-height:1.4;color:inherit;font-size:inherit;font-family:inherit;position:relative;z-index:1}.bmxcb__markdown h1,.bmxcb__markdown h2,.bmxcb__markdown h3,.bmxcb__markdown h4,.bmxcb__markdown h5,.bmxcb__markdown h6{margin:.5em 0 .25em 0;font-weight:600;line-height:1.2;color:var(--bmx-color-text)}.bmxcb__markdown h1{font-size:1.2em}.bmxcb__markdown h2{font-size:1.15em}.bmxcb__markdown h3{font-size:1.1em}.bmxcb__markdown h4,.bmxcb__markdown h5,.bmxcb__markdown h6{font-size:1.05em}.bmxcb__markdown p{margin:.4em 0;line-height:1.4}.bmxcb__markdown ul,.bmxcb__markdown ol{margin:.5em 0;padding-left:1.2em}.bmxcb__markdown li{margin:.2em 0;line-height:1.4}.bmxcb__markdown pre{background:rgba(0,0,0,.05);border:1px solid var(--bmx-color-border);border-radius:6px;padding:.75em;margin:.75em 0;overflow-x:auto;font-family:"Monaco","Menlo","Ubuntu Mono",monospace;font-size:.85em;line-height:1.3}.bmxcb__markdown code{background:rgba(0,0,0,.05);border:1px solid var(--bmx-color-border);border-radius:3px;padding:.15em .3em;font-family:"Monaco","Menlo","Ubuntu Mono",monospace;font-size:.85em;color:var(--bmx-color-accent)}.bmxcb__markdown pre code{background:none;border:none;padding:0;color:inherit}.bmxcb__markdown blockquote{margin:.75em 0;padding:.5em .75em;border-left:3px solid var(--bmx-color-accent);background:rgba(0,0,0,.02);border-radius:0 4px 4px 0;font-style:italic}.bmxcb__markdown table{width:100%;border-collapse:collapse;margin:.75em 0;border:1px solid var(--bmx-color-border);border-radius:6px;overflow:hidden}.bmxcb__markdown th,.bmxcb__markdown td{padding:.5em .75em;text-align:left;border-bottom:1px solid var(--bmx-color-border)}.bmxcb__markdown th{background:rgba(0,0,0,.02);font-weight:600}.bmxcb__markdown tr:last-child td{border-bottom:none}.bmxcb__markdown a{color:var(--bmx-color-accent);text-decoration:none;border-bottom:1px solid rgba(0,0,0,0);transition:border-color .2s ease}.bmxcb__markdown a:hover{border-bottom-color:var(--bmx-color-accent)}.bmxcb__markdown hr{border:none;height:1px;background:var(--bmx-color-border);margin:1em 0}.bmxcb__markdown strong{font-weight:600}.bmxcb__markdown em{font-style:italic}.bmxcb__markdown input[type=checkbox]{margin-right:.5em;accent-color:var(--bmx-color-accent)}.bmxcb__markdown .hljs{background:rgba(0,0,0,0) !important}
package/dist/types.d.ts CHANGED
@@ -85,3 +85,17 @@ export type OpenAIChatCompletionResponse = {
85
85
  export type ChatCompletionResult = {
86
86
  content: string;
87
87
  };
88
+ /**
89
+ * Rest adapter configuration.
90
+ */
91
+ export interface RestAdapterConfig {
92
+ baseUrl: string;
93
+ /**
94
+ * The endpoint to call.
95
+ */
96
+ endpoint?: string;
97
+ /**
98
+ * The headers to send.
99
+ */
100
+ headers?: Record<string, string>;
101
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bmx-labs/chat-widget",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "private": false,
5
5
  "description": "BMX Chat Widget for React/Next.js with RAG capabilities",
6
6
  "license": "GNU AGPLv3",
@@ -1,75 +0,0 @@
1
- import type { BmxChatApiAdapter, ChatMessage, PineconeRAGAdapterConfig } from "../../types";
2
- /**
3
- * Pinecone RAG Adapter.
4
- *
5
- * This adapter uses Pinecone for vector search and OpenAI for chat completion.
6
- * It embeds the user's query, retrieves the most relevant context from Pinecone,
7
- * builds a system prompt with the context, and calls OpenAI chat to generate the final response.
8
- */
9
- export declare class PineconeRAGAdapter implements BmxChatApiAdapter {
10
- /**
11
- * OpenAI API key.
12
- */
13
- private openAIApiKey;
14
- /**
15
- * Pinecone API key.
16
- */
17
- private pineconeApiKey;
18
- /**
19
- * Pinecone index URL.
20
- */
21
- private pineconeIndexUrl;
22
- /**
23
- * Pinecone namespace.
24
- */
25
- private namespace;
26
- /**
27
- * Number of relevant chunks to retrieve.
28
- */
29
- private topK;
30
- /**
31
- * OpenAI model for chat completion.
32
- */
33
- private chatModel;
34
- /**
35
- * OpenAI model for embeddings.
36
- */
37
- private embeddingModel;
38
- /**
39
- * OpenAI API base URL.
40
- */
41
- private openAIBaseURL;
42
- /**
43
- * Maximum context tokens.
44
- */
45
- private maxContextTokens;
46
- /**
47
- * Minimum score threshold.
48
- */
49
- private minScoreThreshold;
50
- /**
51
- * Logger.
52
- */
53
- private logger;
54
- /**
55
- * Dynamic context.
56
- */
57
- private dynamicContext?;
58
- /**
59
- * Initialize the adapter.
60
- *
61
- * @param {PineconeRAGAdapterConfig} cfg - The configuration.
62
- */
63
- constructor(cfg: PineconeRAGAdapterConfig);
64
- /**
65
- * Send a message to the adapter.
66
- *
67
- * @param {ChatMessage[]} history - The history of messages.
68
- * @param {string} input - The input message.
69
- * @param {AbortSignal} options?.signal - The abort signal.
70
- * @returns {Promise<ChatMessage>} The response message.
71
- */
72
- sendMessage(history: ChatMessage[], input: string, options?: {
73
- signal?: AbortSignal;
74
- }): Promise<ChatMessage>;
75
- }
@@ -1,11 +0,0 @@
1
- import { PineconeQueryMatch } from "../../types";
2
- import { Logger } from "../../utils/logger";
3
- /**
4
- * Debug logging for the filtered matches.
5
- *
6
- * @param {string} processedInput - The processed input.
7
- * @param {PineconeQueryMatch[]} allMatches - The all matches.
8
- * @param {PineconeQueryMatch[]} filteredMatches - The filtered matches.
9
- * @param {Logger} logger - The logger.
10
- */
11
- export declare function debugFilterMatches(processedInput: string, allMatches: PineconeQueryMatch[], filteredMatches: PineconeQueryMatch[], logger: Logger): void;
@@ -1,40 +0,0 @@
1
- import { ChatCompletionResult, OpenAIModel, PineconeQueryMatch } from "../../types";
2
- import { Logger } from "../../utils/logger";
3
- /**
4
- * Embeds text using OpenAI embeddings.
5
- *
6
- * @param {string} text - The text to embed.
7
- * @param {string} openAIBaseURL - The OpenAI API base URL.
8
- * @param {string} openAIApiKey - The OpenAI API key.
9
- * @param {string} embeddingModel - The OpenAI embedding model.
10
- * @param {AbortSignal} signal - The abort signal.
11
- * @returns {Promise<number[]>} The embedding.
12
- */
13
- export declare function getEmbeddedVector(text: string, openAIBaseURL: string, openAIApiKey: string, embeddingModel: string, signal?: AbortSignal): Promise<number[]>;
14
- /**
15
- * Calls OpenAI Chat Completions API and returns the assistant content.
16
- *
17
- * @param {string} openAIBaseURL - The OpenAI API base URL.
18
- * @param {string} openAIApiKey - The OpenAI API key.
19
- * @param {OpenAIModel} model - The OpenAI chat model.
20
- * @param {Array<{role: string; content: string}>} messages - The chat messages.
21
- * @param {Logger} logger - The logger.
22
- * @param {AbortSignal} signal - Abort signal.
23
- * @returns {Promise<ChatCompletionResult>} The assistant content.
24
- */
25
- export declare function getChatCompletion(openAIBaseURL: string, openAIApiKey: string, model: OpenAIModel, messages: Array<{
26
- role: string;
27
- content: string;
28
- }>, logger: Logger, signal?: AbortSignal): Promise<ChatCompletionResult>;
29
- /**
30
- * Queries Pinecone for the most relevant matches.
31
- *
32
- * @param {number[]} vector - The embedding vector.
33
- * @param {string} pineconeIndexUrl - The Pinecone index URL.
34
- * @param {string} pineconeApiKey - The Pinecone API key.
35
- * @param {number} topK - The number of relevant matches to retrieve.
36
- * @param {string} namespace - The Pinecone namespace.
37
- * @param {AbortSignal} signal - The abort signal.
38
- * @returns {Promise<PineconeQueryMatch[]>} The relevant matches.
39
- */
40
- export declare function queryPinecone(vector: number[], pineconeIndexUrl: string, pineconeApiKey: string, topK: number, namespace: string, signal?: AbortSignal): Promise<PineconeQueryMatch[]>;
@@ -1 +0,0 @@
1
- export { PineconeRAGAdapter } from "./PineconeRAGAdapter";
@@ -1,96 +0,0 @@
1
- import { ChatMessage, PineconeQueryMatch } from "../../types";
2
- import { Logger } from "../../utils/logger";
3
- /**
4
- * Preprocesses the query for better retrieval.
5
- *
6
- * @param {string} query - The query.
7
- * @returns {string} The preprocessed query.
8
- */
9
- export declare function preprocessQuery(query: string): string;
10
- /**
11
- * Optionally fetches dynamic (live) context and appends it to the retrieved
12
- * Pinecone matches before prompting the LLM.
13
- *
14
- * Typical use cases include live token prices, on-chain metrics, or any
15
- * time-sensitive information you want the assistant to reference. This keeps
16
- * the adapter decoupled from arbitrary APIs while allowing the host app to
17
- * supply additional context blocks on demand.
18
- *
19
- * Behavior:
20
- * - If `dynamicContext` is not provided, returns `filteredMatches` unchanged.
21
- * - If the provider returns blocks, they are converted into synthetic matches
22
- * (scored as 1 to prioritize) and merged with existing matches.
23
- * - The merged list is truncated by `maxContextTokens` to control cost.
24
- * - Any errors are logged and the original matches are returned (no throw).
25
- *
26
- * @param {string} processedInput - A normalized version of the user's input (e.g., after query expansion)
27
- * @param {PineconeQueryMatch[]} filteredMatches - Matches already filtered by score and topK
28
- * @param {number} maxContextTokens - Hard cap for context tokens to keep OpenAI cost bounded
29
- * @param {Logger} logger - Logger instance for structured (optional) debug output
30
- * @param {Function} dynamicContext - Optional async provider that returns additional context blocks
31
- * @param {AbortSignal} options - Optional AbortSignal for cancellation
32
- * @returns {PineconeQueryMatch[]} The merged and truncated list of matches ready for prompting
33
- */
34
- export declare function processDynamicContext(processedInput: string, filteredMatches: PineconeQueryMatch[], maxContextTokens: number, logger: Logger, dynamicContext?: (input: string, options?: {
35
- signal?: AbortSignal;
36
- }) => Promise<Array<{
37
- title?: string;
38
- url?: string;
39
- text: string;
40
- }>>, options?: {
41
- signal?: AbortSignal;
42
- }): Promise<PineconeQueryMatch[]>;
43
- /**
44
- * Coarse token estimator used for quick context-size budgeting.
45
- *
46
- * The heuristic assumes ~4 characters per token. This is intentionally simple
47
- * and fast; for strict budgeting consider a model-specific tokenizer if needed.
48
- *
49
- * @param {string} text - Arbitrary text to estimate token count for
50
- * @returns {number} Estimated token count
51
- */
52
- export declare function estimateTokens(text: string): number;
53
- /**
54
- * Truncates a list of matches so that the combined preview text fits within a
55
- * specified token budget. Preserves order and partially truncates the last
56
- * match if needed (and if there is enough remaining budget to be meaningful).
57
- *
58
- * Rationale: Keeping the most relevant matches at the top and avoiding hard cuts
59
- * that remove all context for the last item often yields better LLM answers.
60
- *
61
- * @param {PineconeQueryMatch[]} matches - Ordered list of matches (highest priority first)
62
- * @param {number} maxContextTokens - Total token budget for all match texts combined
63
- * @returns {PineconeQueryMatch[]} A truncated list of matches within the token budget
64
- */
65
- export declare function truncateContext(matches: PineconeQueryMatch[], maxContextTokens: number): PineconeQueryMatch[];
66
- /**
67
- * Refuse gracefully if no relevant matches are found.
68
- *
69
- * @param {Logger} logger - The logger.
70
- */
71
- export declare function createNoMatchesResponse(logger: Logger): ChatMessage;
72
- /**
73
- * Extracts sources from the matches.
74
- *
75
- * @param {PineconeQueryMatch[]} matches - The matches.
76
- * @returns {Array<{ title: string; url: string }>} The sources.
77
- */
78
- export declare function extractSources(matches: PineconeQueryMatch[]): Array<{
79
- title: string;
80
- url: string;
81
- }>;
82
- /**
83
- * Ensures that the content has a Sources section with real links from context.
84
- *
85
- * @param {string} content - The content.
86
- * @param {PineconeQueryMatch[]} finalMatches - The final matches.
87
- * @returns {string} The content with the Sources section.
88
- */
89
- export declare function ensureSources(content: string, finalMatches: PineconeQueryMatch[]): string;
90
- /**
91
- * Builds the system prompt for the LLM.
92
- *
93
- * @param {PineconeQueryMatch[]} matches - The matches.
94
- * @returns {string} The system prompt.
95
- */
96
- export declare function buildSystemPrompt(matches: PineconeQueryMatch[]): string;
@@ -1,7 +0,0 @@
1
- /**
2
- * Comprehensive Morphex BMX Data
3
- * This constant contains all the latest information about Morphex BMX
4
- * for use in the chat bot's context
5
- */
6
- export declare const MORPHEX_BMX_DATA = "\n# Morphex BMX - Complete Information Guide\n\n## Overview\nBMX is a DeFi ecosystem designed to address a core challenge for long-term users and liquidity providers: the reliance on speculative trading cycles and temporary, unsustainable incentive programs. The protocol provides an alternative design for long-term holding, built on the principle of capturing real fees from a wide range of activities and routing them back to users without inflationary token emissions.\n\n## Catalyst Ahead\n- **DeliSwap Launch**: Long awaited launch of DeliSwap, a Base-native DEX built on Uniswap v4 hooks. Highly innovative design.\n- **Fee Cycling**: 100% of fees cycle back into BMX (97% auto-swapped, 3% to stakers). Even if routed through other aggregators, DeliSwap still captures backend fees.\n\n## Team, Tokenomics, Backing / Sentiment\n**Unique Backing**: One and only project after Aero where Coinbase market bought half a million $ worth of tokens onchain at 20% below current price.\n\n**Team**: Ex-Coinbase by Coinbase people, strong praise/support from Moonwell founder, Jesse etc.\n\n**Tokenomics**:\n- All tokens are unlocked\n- Only 16% in active circulation:\n - 70% are staked\n - 10% are in the treasury (according to the docs)\n - 4% are held by Coinbase Ventures, won't be sold anytime soon\n- ~2.7M Total supply, 700k tokens Circ.\n- At current prices that's just ~$4M effective mcap.\n- Project has Zero inflation, only buybacks announced recently\n\n## Platform Architecture\nThe ecosystem's architecture is centered around wBLT, an auto-compounding liquidity token comprised of blue-chip assets like BTC, ETH, and USDC. wBLT is designed to capture fees generated not only by BMX's native products but also from broader onchain activity, such as swaps routed through major DEX aggregators.\n\n## Core Products\n\n### 1. wBLT (Wrapped BMX Liquidity Token)\n- **Composition**: Blue-chip assets (cbBTC, ETH, USDC)\n- **Features**: Auto-compounding, transferable vault token\n- **APR**: Historical annualized APR around 60% (future rates may vary)\n- **Use Cases**: \n - High-quality collateral for platforms like Morpho\n - Useful pairing asset on DEXes\n - Auto-fee-accruing version of BLT\n\n### 2. BMX Classic\n- **Type**: Spot and margin trading platform based on GMX-v1\n- **Focus**: Capital efficiency and low fees\n- **Settlement**: All trades settled against singular liquidity pool (BLT)\n- **Liquidity**: Users can provide liquidity with any whitelisted asset\n\n### 3. BMX Freestyle\n- **Type**: Intent-based trading platform\n- **Features**: Low fees, access to over 250 trading markets\n- **Technology**: Powered by SYMMIO protocol\n- **Leverage**: Up to 60x leverage available\n\n### 4. Carousel (formerly Based MediaX)\n- **Type**: Non-fungible asset (NFA) exchange\n- **Features**: \n - Scan listings from all major NFT platforms\n - Save 50%+ on standard fees (0.25%)\n - Access auctions and randomized \"Carousel\" style listings\n - Earn or post incentives permissionlessly\n\n### 5. Deli Swap (Coming Soon)\n- **Type**: Base-native DEX built on Uniswap v4 hooks\n- **Architecture**: Non-custodial, decentralized, permissionless\n- **Features**: \n - Built on Uniswap V4 with hooks\n - wBLT base pairs in v1\n - 100% of fees distributed to BMX ecosystem\n - Static pool fees for v1, dynamic fees for v2\n\n## Fee Distribution System\n**Protocol Accrued Fee Allocation (BIP-20)**:\n- **Classic**: 80% to BLT, 20% to BMX Staking Safety Module (vote-directed)\n- **Freestyle**: 40% to BLT, 60% to BMX Staking Safety Module (vote-directed)\n- **Carousel**: 40% to BLT, 60% to BMX Staking Safety Module (vote-directed)\n- **Deli Swap**: 97% to LPs as BMX, 3% to BMX Staking Safety Module (vote-directed)\n\n## BMX Staking System\n**Staking Benefits**:\n- No lock up period\n- Receive multiplier points (100% APR)\n- Accrued fees routed as wETH\n- Available on Base, Mode, and Sonic\n\n**Multiplier Points (MPs)**:\n- Accrue at 100% APR on staked balance\n- Boost formula: Boost = MP / BMX\n- Unstaking burns MPs (encourages long-term staking)\n- Non-transferable and supply-neutral\n\n## Tokenomics & Distribution\n**Total Supply**: 2.85M BMX (after burns)\n**Allocation**:\n- **Treasury**: 322.61K BMX (10%)\n- **Team**: 419.39K BMX (13%)\n- **MPX Claimable Airdrop**: 600K BMX as oBMX (18.5%) - No Longer Active\n- **Initial Seed Liquidity**: 80.65K BMX (2.5%)\n\n**Recent Burns**: 179,688 BMX burned (bought back with treasury wBLT) as of June 15, 2024.\n\n## Technical Specifications\n**Networks**: Base, Mode, Sonic\n**Oracles**: Chainlink (onchain) and Pyth (offchain)\n**Governance**: Gas-free, off-chain voting via Snapshot\n**Security**: Multi-sig governed, audited contracts\n\n## Recent Developments\n- **Token Burns**: Over 5 million BMX tokens burned, valued at over $8 million\n- **Freestyle Launch**: New decentralized perpetual trading engine with 60x leverage\n- **wBLT Introduction**: Wrapped, composable, multi-use token with auto-fee-accruing\n- **DeliSwap Development**: Base-native DEX on Uniswap v4 hooks\n\n## Community & Resources\n- **Website**: https://morphex.trade\n- **Documentation**: https://docs.morphex.trade\n- **Discord**: https://discord.com/invite/morphex\n- **Warpcast**: https://warpcast.com/~/channel/morphex\n- **GitHub**: https://github.com/morphex\n- **Snapshot**: https://snapshot.box/#/s:bmxonbase.eth\n\n## Key Innovations\n1. **Vault-First Approach**: Automated fee-processing vaults\n2. **Composability**: wBLT enables multiple use cases\n3. **Capital Efficiency**: Eliminates competition between trading and native token liquidity\n4. **Zero Emissions**: No inflationary token emissions\n5. **Real Fee Capture**: Powered by actual protocol cash flow\n\n## Risk Management\n- **Counterparty Risk**: BLT is counterparty to traders\n- **Smart Contract Risk**: Standard DeFi protocol risks\n- **Asset Risk**: Exposure to bridged tokens and volatile assets\n- **Liquidation Risk**: Positions can be liquidated if margin insufficient\n\n## Getting Started\n1. Visit https://morphex.trade\n2. Connect wallet to Base/Mode/Sonic\n3. Choose product (Classic, Freestyle, Carousel)\n4. Deposit collateral and start trading\n5. Stake BMX for governance and fee accrual\n\nThis comprehensive guide covers all aspects of the BMX ecosystem including platform architecture, products, tokenomics, staking, and recent developments.\n";
7
- export default MORPHEX_BMX_DATA;