@devicai/ui 0.57.0 → 0.58.0
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/README.md +162 -0
- package/dist/cjs/api/types.js.map +1 -1
- package/dist/cjs/components/AICommandBar/AICommandBar.js +10 -7
- package/dist/cjs/components/AICommandBar/AICommandBar.js.map +1 -1
- package/dist/cjs/components/AICommandBar/useAICommandBar.js +7 -5
- package/dist/cjs/components/AICommandBar/useAICommandBar.js.map +1 -1
- package/dist/cjs/components/AIElementWrapper/AIElementWrapper.js +17 -14
- package/dist/cjs/components/AIElementWrapper/AIElementWrapper.js.map +1 -1
- package/dist/cjs/components/AIElementWrapper/useAIElementWrapper.js +7 -5
- package/dist/cjs/components/AIElementWrapper/useAIElementWrapper.js.map +1 -1
- package/dist/cjs/components/AIGenerationButton/AIGenerationButton.js +11 -6
- package/dist/cjs/components/AIGenerationButton/AIGenerationButton.js.map +1 -1
- package/dist/cjs/components/AIGenerationButton/useAIGenerationButton.js +6 -4
- package/dist/cjs/components/AIGenerationButton/useAIGenerationButton.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js +26 -12
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ChatInput.js +21 -15
- package/dist/cjs/components/ChatDrawer/ChatInput.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ChatMessages.js +54 -13
- package/dist/cjs/components/ChatDrawer/ChatMessages.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/CompactionWidget.js +13 -4
- package/dist/cjs/components/ChatDrawer/CompactionWidget.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ConversationSelector.js +6 -4
- package/dist/cjs/components/ChatDrawer/ConversationSelector.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/GuardrailNotice.js +40 -0
- package/dist/cjs/components/ChatDrawer/GuardrailNotice.js.map +1 -0
- package/dist/cjs/components/ChatDrawer/HandoffSubagentWidget.js +3 -1
- package/dist/cjs/components/ChatDrawer/HandoffSubagentWidget.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/LimitBanner.js +19 -9
- package/dist/cjs/components/ChatDrawer/LimitBanner.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/QueueNotice.js +19 -7
- package/dist/cjs/components/ChatDrawer/QueueNotice.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/RecalledMemoriesWidget.js +17 -5
- package/dist/cjs/components/ChatDrawer/RecalledMemoriesWidget.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ReferenceChip.js +3 -1
- package/dist/cjs/components/ChatDrawer/ReferenceChip.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/UsageBar.js +23 -18
- package/dist/cjs/components/ChatDrawer/UsageBar.js.map +1 -1
- package/dist/cjs/components/CoreMemoryModal/CoreMemoryModal.js +20 -9
- package/dist/cjs/components/CoreMemoryModal/CoreMemoryModal.js.map +1 -1
- package/dist/cjs/components/Feedback/FeedbackModal.js +5 -1
- package/dist/cjs/components/Feedback/FeedbackModal.js.map +1 -1
- package/dist/cjs/components/Feedback/MessageActions.js +3 -1
- package/dist/cjs/components/Feedback/MessageActions.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/ConnectFieldsForm.js +12 -8
- package/dist/cjs/components/IntegrationsModal/ConnectFieldsForm.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/IntegrationsHint.js +5 -3
- package/dist/cjs/components/IntegrationsModal/IntegrationsHint.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/IntegrationsLauncher.js +12 -3
- package/dist/cjs/components/IntegrationsModal/IntegrationsLauncher.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/IntegrationsPanel.js +34 -24
- package/dist/cjs/components/IntegrationsModal/IntegrationsPanel.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/IntegrationsToggle.js +15 -6
- package/dist/cjs/components/IntegrationsModal/IntegrationsToggle.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/McpConnectForm.js +15 -7
- package/dist/cjs/components/IntegrationsModal/McpConnectForm.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/McpServersSection.js +32 -19
- package/dist/cjs/components/IntegrationsModal/McpServersSection.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/useIntegrations.js +3 -1
- package/dist/cjs/components/IntegrationsModal/useIntegrations.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/useTenantMcp.js +3 -1
- package/dist/cjs/components/IntegrationsModal/useTenantMcp.js.map +1 -1
- package/dist/cjs/components/ThreadStateTag/ThreadStateTag.js +63 -40
- package/dist/cjs/components/ThreadStateTag/ThreadStateTag.js.map +1 -1
- package/dist/cjs/hooks/useDevicChat.js +11 -5
- package/dist/cjs/hooks/useDevicChat.js.map +1 -1
- package/dist/cjs/hooks/useSpeechRecording.js +8 -4
- package/dist/cjs/hooks/useSpeechRecording.js.map +1 -1
- package/dist/cjs/i18n/translate.js +48 -0
- package/dist/cjs/i18n/translate.js.map +1 -0
- package/dist/cjs/i18n/useTranslations.js +57 -0
- package/dist/cjs/i18n/useTranslations.js.map +1 -0
- package/dist/cjs/index.js +11 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/provider/DevicProvider.js +3 -1
- package/dist/cjs/provider/DevicProvider.js.map +1 -1
- package/dist/cjs/styles.css +1 -1
- package/dist/esm/api/types.d.ts +10 -1
- package/dist/esm/api/types.js.map +1 -1
- package/dist/esm/components/AICommandBar/AICommandBar.js +11 -8
- package/dist/esm/components/AICommandBar/AICommandBar.js.map +1 -1
- package/dist/esm/components/AICommandBar/AICommandBar.types.d.ts +10 -0
- package/dist/esm/components/AICommandBar/useAICommandBar.js +7 -5
- package/dist/esm/components/AICommandBar/useAICommandBar.js.map +1 -1
- package/dist/esm/components/AIElementWrapper/AIElementWrapper.js +17 -14
- package/dist/esm/components/AIElementWrapper/AIElementWrapper.js.map +1 -1
- package/dist/esm/components/AIElementWrapper/AIElementWrapper.types.d.ts +10 -0
- package/dist/esm/components/AIElementWrapper/useAIElementWrapper.js +7 -5
- package/dist/esm/components/AIElementWrapper/useAIElementWrapper.js.map +1 -1
- package/dist/esm/components/AIGenerationButton/AIGenerationButton.js +12 -7
- package/dist/esm/components/AIGenerationButton/AIGenerationButton.js.map +1 -1
- package/dist/esm/components/AIGenerationButton/AIGenerationButton.types.d.ts +10 -0
- package/dist/esm/components/AIGenerationButton/useAIGenerationButton.js +6 -4
- package/dist/esm/components/AIGenerationButton/useAIGenerationButton.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.js +27 -13
- package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.types.d.ts +33 -0
- package/dist/esm/components/ChatDrawer/ChatInput.js +21 -15
- package/dist/esm/components/ChatDrawer/ChatInput.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatMessages.d.ts +1 -1
- package/dist/esm/components/ChatDrawer/ChatMessages.js +54 -13
- package/dist/esm/components/ChatDrawer/ChatMessages.js.map +1 -1
- package/dist/esm/components/ChatDrawer/CompactionWidget.js +13 -4
- package/dist/esm/components/ChatDrawer/CompactionWidget.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ConversationSelector.js +6 -4
- package/dist/esm/components/ChatDrawer/ConversationSelector.js.map +1 -1
- package/dist/esm/components/ChatDrawer/GuardrailNotice.d.ts +36 -0
- package/dist/esm/components/ChatDrawer/GuardrailNotice.js +38 -0
- package/dist/esm/components/ChatDrawer/GuardrailNotice.js.map +1 -0
- package/dist/esm/components/ChatDrawer/HandoffSubagentWidget.js +3 -1
- package/dist/esm/components/ChatDrawer/HandoffSubagentWidget.js.map +1 -1
- package/dist/esm/components/ChatDrawer/LimitBanner.js +19 -9
- package/dist/esm/components/ChatDrawer/LimitBanner.js.map +1 -1
- package/dist/esm/components/ChatDrawer/QueueNotice.js +19 -7
- package/dist/esm/components/ChatDrawer/QueueNotice.js.map +1 -1
- package/dist/esm/components/ChatDrawer/RecalledMemoriesWidget.js +17 -5
- package/dist/esm/components/ChatDrawer/RecalledMemoriesWidget.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ReferenceChip.js +3 -1
- package/dist/esm/components/ChatDrawer/ReferenceChip.js.map +1 -1
- package/dist/esm/components/ChatDrawer/UsageBar.js +23 -18
- package/dist/esm/components/ChatDrawer/UsageBar.js.map +1 -1
- package/dist/esm/components/ChatDrawer/index.d.ts +2 -0
- package/dist/esm/components/CoreMemoryModal/CoreMemoryModal.js +20 -9
- package/dist/esm/components/CoreMemoryModal/CoreMemoryModal.js.map +1 -1
- package/dist/esm/components/Feedback/FeedbackModal.js +5 -1
- package/dist/esm/components/Feedback/FeedbackModal.js.map +1 -1
- package/dist/esm/components/Feedback/MessageActions.js +3 -1
- package/dist/esm/components/Feedback/MessageActions.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/ConnectFieldsForm.js +12 -8
- package/dist/esm/components/IntegrationsModal/ConnectFieldsForm.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsHint.js +5 -3
- package/dist/esm/components/IntegrationsModal/IntegrationsHint.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsLauncher.js +12 -3
- package/dist/esm/components/IntegrationsModal/IntegrationsLauncher.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsPanel.d.ts +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsPanel.js +34 -24
- package/dist/esm/components/IntegrationsModal/IntegrationsPanel.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsToggle.d.ts +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsToggle.js +15 -6
- package/dist/esm/components/IntegrationsModal/IntegrationsToggle.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/McpConnectForm.js +15 -7
- package/dist/esm/components/IntegrationsModal/McpConnectForm.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/McpServersSection.js +32 -19
- package/dist/esm/components/IntegrationsModal/McpServersSection.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/useIntegrations.js +3 -1
- package/dist/esm/components/IntegrationsModal/useIntegrations.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/useTenantMcp.js +3 -1
- package/dist/esm/components/IntegrationsModal/useTenantMcp.js.map +1 -1
- package/dist/esm/components/ThreadStateTag/ThreadStateTag.js +63 -40
- package/dist/esm/components/ThreadStateTag/ThreadStateTag.js.map +1 -1
- package/dist/esm/hooks/useDevicChat.js +12 -6
- package/dist/esm/hooks/useDevicChat.js.map +1 -1
- package/dist/esm/hooks/useSpeechRecording.js +8 -4
- package/dist/esm/hooks/useSpeechRecording.js.map +1 -1
- package/dist/esm/i18n/index.d.ts +4 -0
- package/dist/esm/i18n/translate.d.ts +23 -0
- package/dist/esm/i18n/translate.js +43 -0
- package/dist/esm/i18n/translate.js.map +1 -0
- package/dist/esm/i18n/types.d.ts +27 -0
- package/dist/esm/i18n/useTranslations.d.ts +32 -0
- package/dist/esm/i18n/useTranslations.js +53 -0
- package/dist/esm/i18n/useTranslations.js.map +1 -0
- package/dist/esm/index.d.ts +4 -2
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/provider/DevicProvider.d.ts +1 -1
- package/dist/esm/provider/DevicProvider.js +3 -1
- package/dist/esm/provider/DevicProvider.js.map +1 -1
- package/dist/esm/provider/types.d.ts +33 -0
- package/dist/esm/styles.css +1 -1
- package/package.json +1 -1
package/dist/cjs/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.devic-state-tag{align-items:center;border:1px solid;border-radius:4px;cursor:default;display:inline-flex;font-family:var(--devic-font-family,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif);font-size:12px;font-weight:500;gap:6px;line-height:20px;padding:2px 8px;position:relative;white-space:nowrap}.devic-state-tag[data-interactive=true]{cursor:pointer}.devic-state-tag[data-interactive=true]:hover{opacity:.85}.devic-state-tag[data-color=gold]{background:rgba(250,173,20,.15);border-color:rgba(250,173,20,.35);color:#faad14}.devic-state-tag[data-color=processing]{background:rgba(22,119,255,.15);border-color:rgba(22,119,255,.35);color:#4096ff}.devic-state-tag[data-color=success]{background:rgba(82,196,26,.15);border-color:rgba(82,196,26,.35);color:#52c41a}.devic-state-tag[data-color=error]{background:rgba(255,77,79,.15);border-color:rgba(255,77,79,.35);color:#ff4d4f}.devic-state-tag[data-color=default]{background:hsla(0,0%,60%,.15);border-color:hsla(0,0%,60%,.35);color:#999}.devic-state-tag[data-color=purple]{background:rgba(114,46,209,.15);border-color:rgba(114,46,209,.35);color:#b37feb}.devic-state-tag[data-color=blue]{background:rgba(22,119,255,.15);border-color:rgba(22,119,255,.35);color:#4096ff}.devic-state-tag-icon{align-items:center;display:inline-flex;flex-shrink:0}.devic-state-tag-caret{align-items:center;display:inline-flex;margin-left:2px;transition:transform .2s ease}.devic-state-tag[data-dropdown-open=true] .devic-state-tag-caret{transform:rotate(180deg)}.devic-state-spinner{animation:devic-state-spin 1s linear infinite}@keyframes devic-state-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.devic-state-tooltip{background:rgba(0,0,0,.85);border-radius:6px;bottom:calc(100% + 8px);color:#fff;font-family:SFMono-Regular,Consolas,monospace;font-size:12px;font-weight:400;line-height:1.4;max-width:280px;padding:6px 10px;pointer-events:none;white-space:normal;z-index:1060}.devic-state-tooltip,.devic-state-tooltip:after{left:50%;position:absolute;transform:translateX(-50%)}.devic-state-tooltip:after{border:5px solid transparent;border-top-color:rgba(0,0,0,.85);content:"";top:100%}.devic-state-dropdown{animation:devic-dropdownSlide .15s ease-out;background:#fff;border:1px solid #e8e8e8;border-radius:8px;box-shadow:0 6px 16px rgba(0,0,0,.08),0 3px 6px rgba(0,0,0,.06);min-width:180px;padding:4px 0;position:absolute;right:0;top:calc(100% + 4px);z-index:1050}@keyframes devic-dropdownSlide{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.devic-state-dropdown-item{align-items:center;background:none;border:none;color:#333;cursor:pointer;display:flex;font-family:inherit;font-size:13px;gap:8px;padding:8px 12px;text-align:left;transition:background .15s;width:100%}.devic-state-dropdown-item:hover{background:#f5f5f5}.devic-state-dropdown-item-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center;width:18px}.devic-state-tooltip-portal{background:rgba(0,0,0,.85);border-radius:6px;color:#fff;font-family:SFMono-Regular,Consolas,monospace;font-size:12px;font-weight:400;line-height:1.4;max-width:280px;padding:6px 10px;pointer-events:none;white-space:normal;z-index:99999}.devic-state-dropdown-portal{animation:devic-dropdownSlide .15s ease-out;background:#fff;border:1px solid #e8e8e8;border-radius:8px;box-shadow:0 6px 16px rgba(0,0,0,.08),0 3px 6px rgba(0,0,0,.06);min-width:180px;padding:4px 0;z-index:99999}.devic-state-modal-overlay{align-items:center;animation:devic-fadeIn .2s ease;background:rgba(0,0,0,.45);display:flex;inset:0;justify-content:center;position:fixed;z-index:1050}@keyframes devic-fadeIn{0%{opacity:0}to{opacity:1}}.devic-state-modal{animation:devic-modalSlide .2s ease-out;background:#fff;border-radius:8px;box-shadow:0 6px 16px rgba(0,0,0,.08);display:flex;flex-direction:column;max-height:80vh;max-width:520px;width:90%}@keyframes devic-modalSlide{0%{opacity:0;transform:translateY(-16px)}to{opacity:1;transform:translateY(0)}}.devic-state-modal-header{align-items:center;border-bottom:1px solid #f0f0f0;display:flex;justify-content:space-between;padding:16px 20px}.devic-state-modal-title{align-items:center;display:flex;font-size:16px;font-weight:600;gap:8px;margin:0}.devic-state-modal-close{align-items:center;background:none;border:none;border-radius:4px;color:#999;cursor:pointer;display:flex;padding:4px}.devic-state-modal-close:hover{background:#f5f5f5;color:#333}.devic-state-modal-body{flex:1;overflow-y:auto;padding:20px}.devic-state-modal-footer{border-top:1px solid #f0f0f0;display:flex;gap:8px;justify-content:flex-end;padding:12px 20px}.devic-state-btn{align-items:center;background:#fff;border:1px solid #d9d9d9;border-radius:6px;color:#333;cursor:pointer;display:inline-flex;font-family:inherit;font-size:14px;font-weight:500;gap:6px;justify-content:center;padding:6px 16px;transition:all .2s}.devic-state-btn:hover{border-color:#1677ff;color:#1677ff}.devic-state-btn-primary{background:#1677ff;border-color:#1677ff;color:#fff}.devic-state-btn-primary:hover{background:#4096ff;border-color:#4096ff;color:#fff}.devic-state-btn-danger{background:#ff4d4f;border-color:#ff4d4f;color:#fff}.devic-state-btn-danger:hover{background:#ff7875;border-color:#ff7875;color:#fff}.devic-state-btn-success{background:#52c41a;border-color:#52c41a;color:#fff}.devic-state-btn-success:hover{background:#73d13d;border-color:#73d13d;color:#fff}.devic-state-btn:disabled{cursor:not-allowed;opacity:.5}.devic-explain-content{border:1px solid #e8e8e8;border-radius:8px;font-family:SFMono-Regular,Consolas,monospace;font-size:13px;line-height:1.6;max-height:300px;min-height:150px;overflow-y:auto;padding:12px;white-space:pre-wrap}.devic-typing-cursor{animation:devic-blink 1s step-end infinite}@keyframes devic-blink{0%,to{opacity:1}50%{opacity:0}}.devic-approval-layout{display:flex;gap:16px}.devic-approval-request{background:#fafafa;border:1px solid #e8e8e8;border-radius:8px;flex:1;font-size:13px;line-height:1.6;max-height:250px;overflow-y:auto;padding:12px}.devic-approval-actions{display:flex;flex:1;flex-direction:column;gap:12px}.devic-approval-textarea{border:1px solid #d9d9d9;border-radius:6px;box-sizing:border-box;font-family:inherit;font-size:13px;min-height:80px;outline:none;padding:8px 12px;resize:vertical;width:100%}.devic-approval-textarea:focus{border-color:#1677ff}.devic-approval-buttons{display:flex;flex-direction:column;gap:8px}.devic-completion-select{background:#fff;border:1px solid #d9d9d9;border-radius:6px;cursor:pointer;font-family:inherit;font-size:14px;outline:none;padding:8px 12px;width:100%}.devic-completion-select:focus{border-color:#1677ff}.devic-state-loading{align-items:center;display:flex;justify-content:center;padding:24px}.devic-state-loading-spinner{animation:devic-state-spin .8s linear infinite;border:2px solid #f0f0f0;border-radius:50%;border-top-color:#1677ff;height:24px;width:24px}.devic-state-warning{align-items:flex-start;color:#cf1322;display:flex;font-size:13px;font-weight:500;gap:6px;margin-top:8px}.devic-message-actions{align-items:center;display:flex;gap:4px;opacity:0;transition:opacity .15s ease}.devic-message-actions:focus-within,.devic-message:hover .devic-message-actions{opacity:1}.devic-message-actions:has(.devic-action-btn--active){opacity:1}.devic-action-btn{align-items:center;background:transparent;border:none;border-radius:var(--devic-radius-sm,6px);color:var(--devic-text-muted,#94a3b8);cursor:pointer;display:flex;height:28px;justify-content:center;padding:0;transition:all .15s ease;width:28px}.devic-action-btn:hover:not(:disabled){background:var(--devic-bg-secondary,#f8fafc);color:var(--devic-text-secondary,#64748b)}.devic-action-btn:disabled{cursor:not-allowed;opacity:.5}.devic-action-btn--active{color:var(--devic-primary,#3b82f6)}.devic-action-btn--active.devic-action-btn--positive{color:#22c55e}.devic-action-btn--active.devic-action-btn--negative{color:#ef4444}.devic-feedback-overlay{align-items:center;animation:devic-feedback-fade-in .15s ease;background:rgba(0,0,0,.4);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:10001}@keyframes devic-feedback-fade-in{0%{opacity:0}to{opacity:1}}.devic-feedback-modal{animation:devic-feedback-slide-up .2s ease;background:var(--devic-bg,#fff);border-radius:var(--devic-radius,12px);box-shadow:0 20px 60px rgba(0,0,0,.2);margin:16px;max-width:400px;width:100%}@keyframes devic-feedback-slide-up{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.devic-feedback-modal-header{align-items:center;border-bottom:1px solid var(--devic-border,#e2e8f0);display:flex;gap:10px;padding:16px 16px 12px}.devic-feedback-modal-icon{align-items:center;background:var(--devic-bg-secondary,#f8fafc);border-radius:8px;color:var(--devic-text,#1e293b);display:flex;height:32px;justify-content:center;width:32px}.devic-feedback-modal-title{color:var(--devic-text,#1e293b);flex:1;font-size:15px;font-weight:600}.devic-feedback-modal-close{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--devic-text-muted,#94a3b8);cursor:pointer;display:flex;height:28px;justify-content:center;padding:0;transition:all .15s ease;width:28px}.devic-feedback-modal-close:hover{background:var(--devic-bg-secondary,#f8fafc);color:var(--devic-text-secondary,#64748b)}.devic-feedback-textarea{background:transparent;border:none;border-bottom:1px solid var(--devic-border,#e2e8f0);box-sizing:border-box;color:var(--devic-text,#1e293b);display:block;font-family:inherit;font-size:14px;line-height:1.5;padding:12px 16px;resize:none;width:100%}.devic-feedback-textarea:focus{outline:none}.devic-feedback-textarea::placeholder{color:var(--devic-text-muted,#94a3b8)}.devic-feedback-modal-actions{display:flex;gap:8px;justify-content:flex-end;padding:12px 16px}.devic-feedback-btn{border:none;border-radius:var(--devic-radius-sm,6px);cursor:pointer;font-family:inherit;font-size:14px;font-weight:500;padding:8px 16px;transition:all .15s ease}.devic-feedback-btn:disabled{cursor:not-allowed;opacity:.6}.devic-feedback-btn--secondary{background:var(--devic-bg-secondary,#f8fafc);color:var(--devic-text-secondary,#64748b)}.devic-feedback-btn--secondary:hover:not(:disabled){background:var(--devic-border,#e2e8f0)}.devic-feedback-btn--primary{background:var(--devic-primary,#3b82f6);color:#fff}.devic-feedback-btn--primary:hover:not(:disabled){background:var(--devic-primary-hover,#2563eb)}.devic-cmd-result-actions{border-top:1px solid var(--devic-cmd-border,var(--devic-border,#e5e7eb));margin-top:8px;padding-top:8px}.devic-cmd-result-actions .devic-message-actions{opacity:1;padding-left:10px}.devic-cmd-result-actions .devic-action-btn{opacity:.7}.devic-cmd-result-actions .devic-action-btn--active,.devic-cmd-result-actions .devic-action-btn:hover{opacity:1}.devic-cm-overlay{align-items:center;background:rgba(0,0,0,.45);display:flex;inset:0;justify-content:center;position:fixed;z-index:10000}.devic-cm-modal{background:var(--devic-bg,#fff);border-radius:12px;box-shadow:0 12px 40px rgba(0,0,0,.22);color:var(--devic-text,#333);display:flex;flex-direction:column;font-size:13px;max-height:min(640px,calc(100vh - 64px));width:min(560px,calc(100vw - 32px))}.devic-cm-header{align-items:center;border-bottom:1px solid var(--devic-border,#e8e8e8);display:flex;justify-content:space-between;padding:14px 16px}.devic-cm-title{align-items:center;display:flex;font-size:15px;font-weight:600;gap:8px;margin:0}.devic-cm-title svg{color:var(--devic-recall-accent,#722ed1)}.devic-cm-close{background:transparent;border:none;border-radius:6px;color:var(--devic-text-muted,#999);cursor:pointer;font-size:20px;line-height:1;padding:2px 6px}.devic-cm-close:hover{background:var(--devic-bg-secondary,#f5f5f5);color:var(--devic-text,#333)}.devic-cm-body{display:flex;flex-direction:column;gap:12px;overflow-y:auto;padding:12px 16px}.devic-cm-error{background:rgba(255,77,79,.08);border:1px solid rgba(255,77,79,.4);border-radius:8px;color:#cf1322;font-size:12px;padding:8px 10px}.devic-cm-empty,.devic-cm-loading{color:var(--devic-text-muted,#999);padding:24px 8px;text-align:center}.devic-cm-section-title{color:var(--devic-text-muted,#999);font-size:10px;font-weight:700;letter-spacing:.6px;margin-bottom:6px;text-transform:uppercase}.devic-cm-entry{align-items:flex-start;border:1px solid var(--devic-border,#e8e8e8);border-radius:8px;display:flex;gap:8px;justify-content:space-between;margin-bottom:6px;padding:8px 10px}.devic-cm-entry-content{align-items:flex-start;display:flex;flex:1;gap:6px;white-space:pre-wrap;word-break:break-word}.devic-cm-pin{color:var(--devic-recall-accent,#722ed1);flex-shrink:0;margin-top:2px}.devic-cm-entry-actions{display:flex;flex-shrink:0;gap:4px}.devic-cm-editor{display:flex;flex:1;flex-direction:column;gap:6px}.devic-cm-textarea{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#d9d9d9);border-radius:8px;box-sizing:border-box;color:inherit;font:inherit;min-height:64px;padding:8px 10px;resize:vertical;width:100%}.devic-cm-textarea:focus{border-color:var(--devic-recall-accent,#722ed1);outline:none}.devic-cm-composer,.devic-cm-editor-actions{display:flex;gap:6px}.devic-cm-composer{flex-direction:column}.devic-cm-composer-row{display:flex;gap:6px}.devic-cm-select{color:inherit;padding:4px 8px}.devic-cm-btn,.devic-cm-select{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#d9d9d9);border-radius:6px;font:inherit}.devic-cm-btn{color:var(--devic-text,#333);cursor:pointer;font-size:12px;padding:5px 12px}.devic-cm-btn:hover:not(:disabled){border-color:var(--devic-recall-accent,#722ed1);color:var(--devic-recall-accent,#722ed1)}.devic-cm-btn:disabled{cursor:not-allowed;opacity:.5}.devic-cm-btn-primary{background:var(--devic-recall-accent,#722ed1);border-color:var(--devic-recall-accent,#722ed1);color:#fff}.devic-cm-btn-primary:hover:not(:disabled){color:#fff;opacity:.9}.devic-cm-btn-small{font-size:11px;padding:2px 8px}.devic-cm-btn-danger:hover:not(:disabled){border-color:#ff4d4f;color:#ff4d4f}.devic-cm-footer{border-top:1px solid var(--devic-border,#e8e8e8);color:var(--devic-text-muted,#999);font-size:11px;padding:10px 16px}.devic-int-overlay{align-items:center;background:rgba(0,0,0,.45);display:flex;inset:0;justify-content:center;position:fixed;z-index:10000}.devic-int-panel{background:var(--devic-bg,#fff);color:var(--devic-text,#333);display:flex;flex-direction:column;font-size:13px;min-width:0;width:100%}.devic-int-modal{border-radius:12px;box-shadow:0 12px 40px rgba(0,0,0,.22);max-height:min(660px,calc(100vh - 64px));width:min(620px,calc(100vw - 32px))}.devic-int-header{align-items:center;border-bottom:1px solid var(--devic-border,#e8e8e8);display:flex;justify-content:space-between;padding:14px 16px}.devic-int-title{align-items:center;display:flex;font-size:15px;font-weight:600;gap:8px;margin:0}.devic-int-title svg{color:var(--devic-primary,#1677ff)}.devic-int-close{background:transparent;border:none;border-radius:6px;color:var(--devic-text-muted,#999);cursor:pointer;font-size:20px;line-height:1;padding:2px 6px}.devic-int-close:hover{background:var(--devic-bg-secondary,#f5f5f5);color:var(--devic-text,#333)}.devic-int-search{align-items:center;background:var(--devic-bg-secondary,#f7f7f7);border:1px solid var(--devic-border,#e8e8e8);border-radius:8px;color:var(--devic-text-muted,#999);display:flex;gap:8px;margin:12px 16px 0;padding:7px 10px}.devic-int-search:focus-within{border-color:var(--devic-primary,#1677ff)}.devic-int-search input{-webkit-appearance:none;appearance:none;background:transparent;border:none;color:var(--devic-text,#333);flex:1;font:inherit;font-size:13px;min-width:0;outline:none}.devic-int-search input::-webkit-search-cancel-button{-webkit-appearance:none}.devic-int-search input::placeholder{color:var(--devic-text-muted,#999)}.devic-int-body{display:flex;flex-direction:column;gap:10px;overflow-y:auto;padding:12px 16px}.devic-int-error{background:rgba(255,77,79,.08);border:1px solid rgba(255,77,79,.4);border-radius:8px;color:#ff4d4f;font-size:12px;padding:8px 10px}.devic-int-notice{background:rgba(250,173,20,.1);border:1px solid rgba(250,173,20,.45);border-radius:8px;color:inherit;font-size:12px;padding:8px 10px}.devic-int-notice a{color:var(--devic-primary,#1677ff)}.devic-int-empty,.devic-int-loading{color:var(--devic-text-muted,#999);padding:24px 8px;text-align:center}.devic-int-grid{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(158px,1fr))}.devic-int-card{border:1px solid var(--devic-border,#e8e8e8);border-radius:10px;display:flex;flex-direction:column;gap:6px;padding:12px}.devic-int-card[data-state=connected]{border-color:rgba(82,196,26,.45)}.devic-int-card[data-state=reconnect]{border-color:rgba(250,173,20,.5)}.devic-int-card-head{align-items:center;display:flex;gap:8px;justify-content:space-between}.devic-int-logo{background:var(--devic-bg-secondary,#f5f5f5);border-radius:8px;flex-shrink:0;height:32px;object-fit:contain;width:32px}.devic-int-logo-fallback{align-items:center;color:var(--devic-text-muted,#999);display:flex;font-weight:600;justify-content:center}.devic-int-name{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-state{align-items:center;color:var(--devic-text-muted,#999);display:inline-flex;font-size:11px;gap:4px;white-space:nowrap}.devic-int-card[data-state=connected] .devic-int-state{color:#52c41a}.devic-int-card[data-state=reconnect] .devic-int-state{color:#faad14}.devic-int-description{-webkit-line-clamp:2;-webkit-box-orient:vertical;color:var(--devic-text-muted,#999);display:-webkit-box;font-size:12px;line-height:1.4;overflow:hidden}.devic-int-accounts{display:flex;flex-direction:column;gap:4px;list-style:none;margin:0;padding:0}.devic-int-account{align-items:center;background:var(--devic-bg-secondary,#f7f7f7);border-radius:6px;display:flex;font-size:11px;gap:6px;padding:3px 6px}.devic-int-account-label{color:var(--devic-text-muted,#999);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-account-warn{color:#faad14}.devic-int-dot{background:#faad14;border-radius:50%;flex-shrink:0;height:6px;width:6px}.devic-int-dot[data-ok=true]{background:#52c41a}.devic-int-dot[data-off=true]{background:var(--devic-text-muted,#bbb)}.devic-int-unlink{background:transparent;border:none;border-radius:4px;color:var(--devic-text-muted,#999);cursor:pointer;flex-shrink:0;font-size:14px;line-height:1;padding:0 2px}.devic-int-unlink:hover:not(:disabled){color:#ff4d4f}.devic-int-unlink:disabled{cursor:not-allowed;opacity:.4}.devic-int-btn{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#d9d9d9);border-radius:6px;color:var(--devic-text,#333);cursor:pointer;flex-shrink:0;font:inherit;font-size:12px;padding:5px 12px}.devic-int-btn:hover:not(:disabled){border-color:var(--devic-primary,#1677ff);color:var(--devic-primary,#1677ff)}.devic-int-btn:disabled{cursor:not-allowed;opacity:.5}.devic-int-btn-block{margin-top:auto;text-align:center;width:100%}.devic-int-btn-primary{background:var(--devic-primary,#1677ff);border-color:var(--devic-primary,#1677ff);color:#fff}.devic-int-btn-primary:hover:not(:disabled){color:#fff;opacity:.9}.devic-int-btn-small{font-size:11px;padding:2px 8px}.devic-int-overlay-stacked{background:rgba(0,0,0,.5);z-index:10001}.devic-int-connect-dialog{background:var(--devic-bg,#fff);border-radius:12px;box-shadow:0 12px 40px rgba(0,0,0,.3);color:var(--devic-text,#333);display:flex;flex-direction:column;font-size:13px;max-height:calc(100vh - 64px);width:min(440px,calc(100vw - 32px))}.devic-int-connect-header{align-items:flex-start;border-bottom:1px solid var(--devic-border,#e8e8e8);display:flex;gap:10px;padding:14px 16px}.devic-int-connect-heading{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.devic-int-connect-heading strong{font-size:14px}.devic-int-connect-heading span{color:var(--devic-text-muted,#999);font-size:11px;line-height:1.4}.devic-int-connect-body{display:flex;flex-direction:column;gap:14px;overflow-y:auto;padding:16px}.devic-int-connect-field{display:flex;flex-direction:column;gap:5px}.devic-int-connect-label{color:var(--devic-text,#333);font-size:12px;font-weight:500}.devic-int-connect-label em{color:var(--devic-text-muted,#999);font-style:normal;font-weight:400}.devic-int-connect-field input,.devic-int-connect-field select{background:var(--devic-bg-secondary,#fafafa);border:1px solid var(--devic-border,#d9d9d9);border-radius:8px;box-sizing:border-box;color:var(--devic-text,#333);font:inherit;font-size:13px;height:36px;line-height:normal;padding:0 10px;transition:border-color .15s,box-shadow .15s;width:100%}.devic-int-connect-field input::placeholder{color:var(--devic-text-muted,#bbb)}.devic-int-connect-field input:focus,.devic-int-connect-field select:focus{border-color:var(--devic-primary,#1677ff);box-shadow:0 0 0 3px color-mix(in srgb,var(--devic-primary,#1677ff) 18%,transparent);outline:none}.devic-int-connect-field input[data-invalid]{border-color:#ff4d4f}.devic-int-connect-field input[data-invalid]:focus{box-shadow:0 0 0 3px rgba(255,77,79,.18)}.devic-int-connect-hint{color:var(--devic-text-muted,#999);font-size:11px;line-height:1.45}.devic-int-connect-guide{color:var(--devic-primary,#1677ff);font-size:12px}.devic-int-connect-actions{justify-content:flex-end;padding:12px 16px}.devic-int-connect-actions,.devic-int-footer{border-top:1px solid var(--devic-border,#e8e8e8);display:flex;gap:8px}.devic-int-footer{align-items:center;color:var(--devic-text-muted,#999);font-size:11px;justify-content:space-between;padding:10px 16px}.devic-int-launcher{align-items:center;background:none;border:none;border-radius:var(--devic-radius-sm,6px);cursor:pointer;display:inline-flex;padding:4px 5px;transition:background var(--devic-transition,.2s)}.devic-int-launcher:hover{background:var(--devic-bg-secondary,#f5f5f5)}.devic-int-launcher-item{align-items:center;background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#e8e8e8);border-radius:6px;box-sizing:border-box;display:flex;flex-shrink:0;height:22px;justify-content:center;margin-left:-4px;overflow:hidden;width:22px}.devic-int-launcher-item:first-child{margin-left:0}.devic-int-launcher-item[data-connected=false]{opacity:.55}.devic-int-logo.devic-int-launcher-logo{background:transparent;border-radius:3px;font-size:11px;height:16px;width:16px}.devic-int-launcher-initial{align-items:center;display:inline-flex;font-size:10px;font-weight:600;justify-content:center;line-height:1}.devic-int-launcher-more{background:var(--devic-bg-secondary,#f0f0f0);color:var(--devic-text-muted,#999);font-size:10px;font-weight:600}.devic-int-launcher-loading{cursor:default}.devic-int-launcher-loading:hover{background:none}.devic-int-launcher-skeleton{animation:devic-int-pulse 1.4s ease-in-out infinite;background:var(--devic-bg-secondary,#f0f0f0)}.devic-int-launcher-skeleton:nth-child(2){animation-delay:.16s}.devic-int-launcher-skeleton:nth-child(3){animation-delay:.32s}.devic-int-launcher-skeleton:nth-child(n+4){animation-delay:.48s}@keyframes devic-int-pulse{0%,to{opacity:.35}50%{opacity:.75}}@media (prefers-reduced-motion:reduce){.devic-int-launcher-skeleton{animation:none;opacity:.5}}.devic-int-launcher[data-dark=true] .devic-int-launcher-item{background:hsla(0,0%,100%,.92);border-color:hsla(0,0%,100%,.16)}.devic-int-launcher[data-dark=true] .devic-int-launcher-more{background:var(--devic-bg-secondary,#f0f0f0);border-color:var(--devic-border,#e8e8e8)}.devic-int-panel[data-dark=true] .devic-int-card .devic-int-logo{background:hsla(0,0%,100%,.92)}.devic-int-panel[data-dark=true] .devic-int-card .devic-int-logo-fallback{color:#595959}.devic-int-hint{align-items:center;background:var(--devic-bg-secondary,#f7f7f7);border:1px solid var(--devic-border,#e8e8e8);border-radius:12px;display:flex;gap:4px;margin:0 0 8px;padding:6px 8px 6px 12px;transition:opacity .2s ease,transform .2s ease}.devic-int-hint[data-leaving=true]{opacity:0;pointer-events:none;transform:translateY(-4px)}.devic-int-hint-main{align-items:center;background:none;border:none;border-radius:8px;color:inherit;cursor:pointer;display:flex;flex:1;font:inherit;gap:10px;justify-content:space-between;min-width:0;padding:2px}.devic-int-hint-label{color:var(--devic-text-muted,#8c8c8c);font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-hint-main:hover .devic-int-hint-label{color:var(--devic-text,#333)}.devic-int-hint-logos{gap:6px}.devic-int-hint-item,.devic-int-hint-logos{align-items:center;display:flex;flex-shrink:0}.devic-int-hint-item{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#e8e8e8);border-radius:6px;box-sizing:border-box;height:24px;justify-content:center;overflow:hidden;width:24px}.devic-int-hint-item[data-connected=false]{opacity:.6}.devic-int-logo.devic-int-hint-logo{background:transparent;border-radius:3px;font-size:11px;height:17px;width:17px}.devic-int-hint-more{background:var(--devic-bg-secondary,#f0f0f0);color:var(--devic-text-muted,#999);font-size:10px;font-weight:600}.devic-int-hint-close{background:transparent;border:none;border-radius:6px;color:var(--devic-text-muted,#999);cursor:pointer;flex-shrink:0;font-size:18px;line-height:1;padding:2px 6px}.devic-int-hint-close:hover{background:var(--devic-bg,#fff);color:var(--devic-text,#333)}.devic-int-hint[data-dark=true] .devic-int-hint-item{background:hsla(0,0%,100%,.92);border-color:hsla(0,0%,100%,.16)}.devic-int-hint[data-dark=true] .devic-int-hint-more{background:var(--devic-bg,#1f1f1f);border-color:var(--devic-border,#303030)}.devic-int-hint-ghost{align-items:center;display:flex;gap:6px;pointer-events:none;position:fixed;z-index:10001}.devic-int-toggle{display:inline-flex;flex-shrink:0;position:relative}.devic-int-toggle-btn{position:relative}.devic-int-toggle-badge{background:var(--devic-primary,#1677ff);border-radius:7px;box-sizing:border-box;color:#fff;font-size:9px;font-weight:600;height:14px;line-height:14px;min-width:14px;padding:0 3px;position:absolute;right:-2px;text-align:center;top:-2px}.devic-int-toggle-popover{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#e8e8e8);border-radius:var(--devic-radius,10px);bottom:calc(100% + 8px);box-shadow:0 8px 24px rgba(0,0,0,.14);box-sizing:border-box;color:var(--devic-text,#333);left:0;max-height:320px;overflow-y:auto;padding:10px;position:absolute;width:260px;z-index:10002}.devic-int-toggle-head{border-bottom:1px solid var(--devic-border,#e8e8e8);display:flex;flex-direction:column;gap:2px;margin-bottom:6px;padding:2px 2px 8px}.devic-int-toggle-head strong{font-size:13px}.devic-int-toggle-head span{color:var(--devic-text-muted,#999);font-size:11px;line-height:1.4}.devic-int-toggle-list{list-style:none;margin:0;padding:0}.devic-int-toggle-row{align-items:center;border-radius:var(--devic-radius-sm,6px);cursor:pointer;display:flex;gap:8px;justify-content:space-between;padding:6px 4px}.devic-int-toggle-row:hover{background:var(--devic-bg-secondary,#f5f5f5)}.devic-int-toggle-app{align-items:center;display:flex;gap:8px;min-width:0}.devic-int-toggle-app .devic-int-logo{border-radius:4px;flex-shrink:0;height:18px;object-fit:contain;width:18px}.devic-int-toggle-name{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-toggle-group{border-top:1px solid var(--devic-border,hsla(0,0%,50%,.22));font-size:10px;letter-spacing:.06em;margin-top:6px;opacity:.55;padding:10px 4px 4px;text-transform:uppercase}.devic-int-toggle-mcp-logo{border-radius:4px;flex-shrink:0;height:18px;object-fit:contain;width:18px}.devic-int-toggle-mcp-fallback{align-items:center;background:var(--devic-surface-2,hsla(0,0%,50%,.18));color:inherit;display:inline-flex;font-size:10px;font-weight:600;justify-content:center}.devic-int-toggle-switch{appearance:none;-webkit-appearance:none;background:var(--devic-border,#d9d9d9);border-radius:9px;cursor:pointer;flex-shrink:0;height:18px;margin:0;position:relative;transition:background var(--devic-transition,.2s);width:32px}.devic-int-toggle-switch:after{background:#fff;border-radius:50%;content:"";height:14px;left:2px;position:absolute;top:2px;transition:transform var(--devic-transition,.2s);width:14px}.devic-int-toggle-switch:checked{background:var(--devic-primary,#1677ff)}.devic-int-toggle-switch:checked:after{transform:translateX(14px)}.devic-int-toggle-switch:focus-visible{outline:2px solid var(--devic-primary,#1677ff);outline-offset:2px}.devic-int-toggle-manage{background:none;border:none;border-radius:0 0 var(--devic-radius-sm,6px) var(--devic-radius-sm,6px);border-top:1px solid var(--devic-border,#e8e8e8);color:var(--devic-primary,#1677ff);cursor:pointer;font:inherit;font-size:12px;margin-top:6px;padding:6px;width:100%}.devic-int-toggle-manage:hover{background:var(--devic-bg-secondary,#f5f5f5)}.devic-int-toggle[data-dark=true] .devic-int-toggle-popover{box-shadow:0 8px 24px rgba(0,0,0,.45)}.devic-int-toggle[data-dark=true] .devic-int-toggle-switch:not(:checked){background:var(--devic-border,#434343)}.devic-int-body-secondary{overflow:visible;padding-top:0}.devic-int-mcp-section{border-top:1px solid var(--devic-border,#e8e8e8);display:flex;flex-direction:column;gap:10px;padding-top:12px}.devic-int-mcp-heading h4{font-size:13px;font-weight:600;margin:0}.devic-int-mcp-heading span{color:var(--devic-text-muted,#999);display:block;font-size:12px;margin-top:2px}.devic-int-mcp-logo{border-radius:8px;flex-shrink:0;height:32px;object-fit:contain;width:32px}.devic-int-mcp-logo-fallback{align-items:center;background:var(--devic-primary,#1677ff);color:#fff;display:inline-flex;font-size:14px;font-weight:600;justify-content:center}.devic-int-mcp-note{color:var(--devic-text-muted,#999);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-mcp-note-warn{color:#faad14}.devic-int-mcp-add{align-self:flex-start;border-style:dashed}.devic-int-mcp-remove{border-color:rgba(255,77,79,.35);color:#ff4d4f}.devic-int-mcp-advanced{display:flex;flex-direction:column;gap:8px}.devic-int-mcp-disclosure{align-self:flex-start;font:inherit;font-size:12px}.devic-int-mcp-copy,.devic-int-mcp-disclosure{background:none;border:none;color:var(--devic-primary,#1677ff);cursor:pointer;padding:0}.devic-int-mcp-copy{font:inherit;font-size:inherit}.devic-int-toggle-btn-loading{animation:devic-int-toggle-pulse 1.4s ease-in-out infinite;cursor:default;opacity:.35}@keyframes devic-int-toggle-pulse{0%,to{opacity:.25}50%{opacity:.5}}.devic-chat-drawer{--devic-primary:#1890ff;--devic-primary-hover:#40a9ff;--devic-primary-light:#e6f7ff;--devic-bg:#fff;--devic-bg-secondary:#f5f5f5;--devic-text:#333;--devic-text-secondary:#666;--devic-text-muted:#999;--devic-border:#e8e8e8;--devic-shadow:0 4px 12px rgba(0,0,0,.15);--devic-error:#ff4d4f;--devic-queued-accent:var(--devic-text-muted);--devic-queued-bubble-bg:transparent;--devic-queued-border:var(--devic-border);--devic-radius:8px;--devic-radius-sm:4px;--devic-radius-lg:16px;--devic-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--devic-transition:0.3s ease;background:var(--devic-bg);bottom:0;box-shadow:var(--devic-shadow);color:var(--devic-text);display:flex;flex-direction:column;font-family:var(--devic-font-family);font-size:14px;line-height:1.5;position:fixed;top:0;transition:transform var(--devic-transition)}.devic-chat-drawer[data-position=right]{right:0;transform:translateX(100%)}.devic-chat-drawer[data-position=left]{left:0;transform:translateX(-100%)}.devic-chat-drawer[data-open=true]{transform:translateX(0)}.devic-drawer-overlay{background:rgba(0,0,0,.3);inset:0;opacity:0;position:fixed;transition:opacity var(--devic-transition),visibility var(--devic-transition);visibility:hidden}.devic-drawer-overlay[data-open=true]{opacity:1;visibility:visible}.devic-drawer-header{align-items:center;border-bottom:1px solid var(--devic-border);display:flex;flex-shrink:0;justify-content:space-between;padding:16px}.devic-drawer-avatar{border-radius:50%;flex-shrink:0;height:28px;object-fit:cover;width:28px}.devic-drawer-title{flex-shrink:1;font-size:16px;font-weight:600;margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-drawer-close{background:none;border:none;border-radius:var(--devic-radius-sm);color:var(--devic-text-secondary);cursor:pointer;padding:8px;transition:background var(--devic-transition),color var(--devic-transition)}.devic-drawer-close:hover{background:var(--devic-bg-secondary);color:var(--devic-text)}.devic-messages-container{display:flex;flex:1;flex-direction:column;gap:12px;overflow-y:auto;padding:16px}.devic-welcome{color:var(--devic-text-secondary);padding:24px 16px;text-align:center}.devic-welcome-text{font-size:16px;margin-bottom:16px}.devic-suggested-messages{display:flex;flex-wrap:wrap;gap:8px;justify-content:center}.devic-suggested-btn{background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:var(--devic-radius-lg);color:var(--devic-text);cursor:pointer;font-size:13px;padding:8px 16px;transition:border-color var(--devic-transition),background var(--devic-transition)}.devic-suggested-btn:hover{background:var(--devic-primary-light);border-color:var(--devic-primary)}.devic-message{display:flex;flex-direction:column;max-width:85%}.devic-message[data-role=user]{align-self:flex-end}.devic-message[data-role=assistant],.devic-message[data-role=tool]{align-self:flex-start}.devic-message-bubble{word-wrap:break-word;border-radius:var(--devic-radius);padding:10px 14px}.devic-message[data-role=user] .devic-message-bubble{background:var(--devic-user-bubble,var(--devic-primary));border-bottom-right-radius:var(--devic-radius-sm);color:var(--devic-user-bubble-text,#fff)}.devic-message[data-role=assistant] .devic-message-bubble{background:var(--devic-assistant-bubble,var(--devic-bg-secondary));border-bottom-left-radius:var(--devic-radius-sm);color:var(--devic-assistant-bubble-text,var(--devic-text))}.devic-message[data-role=tool] .devic-message-bubble{background:var(--devic-primary-light);border:1px solid var(--devic-primary);color:var(--devic-text);font-size:12px}.devic-message-footer{align-items:center;display:flex;gap:8px;justify-content:space-between;margin-top:4px}.devic-message-time{color:var(--devic-text-muted);font-size:11px}.devic-message[data-role=user] .devic-message-footer{justify-content:flex-end}.devic-message[data-role=user] .devic-message-time{text-align:right}.devic-message[data-queued=true] .devic-message-bubble{background:var(--devic-queued-bubble-bg);border:1px dashed var(--devic-queued-border);color:var(--devic-text);opacity:.85}.devic-message-queued-label{align-items:center;color:var(--devic-queued-accent);display:inline-flex;font-size:11px;gap:4px}.devic-message-files{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}.devic-message-file{align-items:center;background:hsla(0,0%,100%,.2);border-radius:var(--devic-radius-sm);display:flex;font-size:12px;gap:6px;padding:6px 10px}.devic-recall{align-self:flex-start;background:var(--devic-recall-bg,rgba(114,46,209,.06));border:1px solid var(--devic-recall-border,rgba(114,46,209,.3));border-radius:var(--devic-radius-sm,8px);color:var(--devic-text-secondary);flex-shrink:0;font-size:12px;margin:2px 0 8px;max-width:88%;overflow:hidden}.devic-recall-header{align-items:center;background:transparent;border:none;color:inherit;cursor:pointer;display:flex;font:inherit;gap:6px;padding:6px 10px;text-align:left;width:100%}.devic-recall-icon{color:var(--devic-recall-accent,#722ed1);flex-shrink:0}.devic-recall-title{color:var(--devic-text);font-weight:600;white-space:nowrap}.devic-recall-summary{opacity:.75;white-space:nowrap}.devic-recall-spacer{flex:1}.devic-recall-source{border:1px solid var(--devic-recall-border,rgba(114,46,209,.3));border-radius:4px;color:var(--devic-recall-accent,#722ed1);font-size:10px;line-height:16px;padding:0 6px;white-space:nowrap}.devic-recall-chevron{flex-shrink:0;opacity:.6;transition:transform .15s ease}.devic-recall-body{display:flex;flex-direction:column;gap:8px;padding:2px 10px 10px}.devic-recall-facts{display:flex;flex-direction:column;gap:6px}.devic-recall-fact{color:var(--devic-text);display:flex;flex-direction:column;gap:2px}.devic-recall-fact-meta{color:var(--devic-text-muted);font-size:10px}.devic-recall-entities{display:flex;flex-wrap:wrap;gap:4px}.devic-recall-entity{background:var(--devic-bg);border:1px solid var(--devic-border,#d9d9d9);border-radius:4px;color:var(--devic-text-secondary);font-size:10px;line-height:18px;padding:0 6px}.devic-recall-entity-type{opacity:.55}.devic-recall-turns{display:flex;flex-direction:column;gap:3px}.devic-recall-turns-title{font-size:10px;font-weight:600;letter-spacing:.4px;opacity:.7;text-transform:uppercase}.devic-recall-turn{font-size:11px;opacity:.85}.devic-recall-turn-role{font-weight:600}.devic-loading{align-self:flex-start;display:flex;gap:4px;padding:10px 14px}.devic-loading-dot{animation:devic-bounce 1.4s ease-in-out infinite both;background:var(--devic-text-muted);border-radius:50%;height:8px;width:8px}.devic-loading-dot:first-child{animation-delay:-.32s}.devic-loading-dot:nth-child(2){animation-delay:-.16s}@keyframes devic-bounce{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}.devic-tool-group{align-self:flex-start;display:flex;flex-direction:column;gap:2px;max-width:85%}.devic-tool-activity{align-items:flex-start;animation:devic-slideUp .3s ease-out;display:flex;gap:8px;padding:4px 0}.devic-tool-activity-icon{align-items:center;color:var(--devic-text-muted);display:flex;flex-shrink:0;margin-top:1px}.devic-tool-activity--active .devic-tool-activity-icon{color:var(--devic-primary)}.devic-tool-activity-text{color:var(--devic-text-secondary);font-size:13px;line-height:1.4}.devic-glow-text{animation:devic-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes devic-pulse{0%,to{opacity:1}50%{opacity:.5}}.devic-spinner{animation:devic-spin 1s linear infinite}@keyframes devic-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes devic-slideUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.devic-tool-collapse-btn{align-items:center;background:none;border:none;color:var(--devic-text-muted);cursor:pointer;display:flex;font-family:var(--devic-font-family);font-size:12px;gap:6px;padding:4px 0;transition:color .2s ease}.devic-tool-collapse-btn:hover{color:var(--devic-primary)}.devic-tool-group-items{animation:devic-expandItems .4s ease-out;overflow:hidden}.devic-tool-group-items[data-expanded=true]{max-height:500px}@keyframes devic-expandItems{0%{max-height:0;opacity:0}to{max-height:500px;opacity:1}}.devic-input-area{border-top:1px solid var(--devic-border);flex-shrink:0;padding:16px}.devic-input-wrapper{--devic-input-row-height:28px;--devic-input-line-height:20px;align-items:flex-end;background:var(--devic-bg-secondary);border-radius:var(--devic-radius);display:flex;gap:8px;padding:8px 12px}.devic-input{background:none;border:none;box-sizing:border-box;color:var(--devic-text);flex:1;font-family:inherit;font-size:14px;line-height:var(--devic-input-line-height);max-height:120px;min-height:var(--devic-input-row-height);outline:none;padding:calc((var(--devic-input-row-height) - var(--devic-input-line-height))/2) 0;resize:none}.devic-input::placeholder{color:var(--devic-text-muted)}.devic-input-btn{align-items:center;background:none;border:none;border-radius:var(--devic-radius-sm);box-sizing:border-box;color:var(--devic-text-secondary);cursor:pointer;display:inline-flex;flex-shrink:0;justify-content:center;min-height:var(--devic-input-row-height,28px);padding:4px;transition:color var(--devic-transition)}.devic-input-btn:hover:not(:disabled){color:var(--devic-primary)}.devic-input-btn:disabled{cursor:not-allowed;opacity:.5}.devic-send-btn{padding:4px 12px}.devic-send-btn,.devic-stop-btn{background:var(--devic-send-btn,var(--devic-primary));border-radius:var(--devic-radius-sm);color:#fff}.devic-stop-btn{min-width:var(--devic-input-row-height,28px);padding:4px}.devic-stop-btn:hover{background:var(--devic-primary-hover);color:#fff}.devic-send-btn-wrapper{flex-shrink:0;position:relative}.devic-send-btn-custom{align-items:center;display:flex;justify-content:center;pointer-events:none}.devic-send-btn-overlay{background:transparent;border:none;cursor:pointer;inset:0;margin:0;padding:0;position:absolute}.devic-send-btn-overlay:disabled{cursor:not-allowed;opacity:.5}.devic-send-btn:hover:not(:disabled){background:var(--devic-primary-hover);color:#fff}.devic-speech-error{background:#fff1f0;border:1px solid #ffccc7;border-radius:var(--devic-radius-sm);color:#cf1322;font-size:12px;margin-bottom:8px;padding:6px 10px}.devic-speech-mic.devic-input-btn:hover:not(:disabled){color:var(--devic-primary)}.devic-speech-mic-wrap{align-items:center;display:inline-flex;flex-shrink:0;justify-content:center;position:relative}.devic-speech-mic-wrap[data-holding=true] .devic-speech-mic{color:var(--devic-primary)}.devic-mic-hold-ring{height:calc(100% + 6px);inset:-3px;pointer-events:none;position:absolute;transform:rotate(-90deg);width:calc(100% + 6px)}.devic-mic-hold-ring-track{fill:none;stroke:var(--devic-primary);stroke-opacity:.18;stroke-width:3}.devic-mic-hold-ring-progress{fill:none;stroke:var(--devic-primary);stroke-width:3;stroke-linecap:round;transition:stroke-dashoffset 90ms linear}.devic-speech-panel{align-items:center;display:flex;flex:1;gap:8px;min-height:var(--devic-input-row-height,28px)}.devic-speech-live{align-items:center;display:flex;flex:1;gap:10px;justify-content:flex-start}.devic-speech-timer{color:var(--devic-text-secondary);font-size:13px;font-variant-numeric:tabular-nums}.devic-speech-confirm{color:#389e0d}.devic-speech-confirm.devic-input-btn:hover:not(:disabled){color:#237804}.devic-speech-confirm-wrap{align-items:center;display:inline-flex;flex-shrink:0;justify-content:center;position:relative}.devic-autostop-ring{height:calc(100% + 6px);inset:-3px;pointer-events:none;position:absolute;transform:rotate(-90deg);width:calc(100% + 6px)}.devic-autostop-ring-track{fill:none;stroke:#389e0d;stroke-opacity:.18;stroke-width:3}.devic-autostop-ring-progress{fill:none;stroke:#389e0d;stroke-width:3;stroke-linecap:round;transition:stroke-dashoffset 90ms linear}.devic-speech-confirm-wrap[data-autostop=true] .devic-speech-confirm{animation:devic-autostop-pulse 1s ease-in-out infinite}@keyframes devic-autostop-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.08)}}.devic-handoff-bar{align-items:center;background:var(--devic-primary-light,#e6f7ff);border-radius:8px;color:var(--devic-primary);display:flex;font-size:12px;gap:8px;margin-bottom:6px;padding:5px 8px}.devic-handoff-dot{animation:devic-handoff-blink 1.2s ease-in-out infinite;background:var(--devic-primary);border-radius:50%;flex-shrink:0;height:8px;width:8px}.devic-handoff-bar[data-waiting=true] .devic-handoff-dot{animation-duration:.7s}@keyframes devic-handoff-blink{0%,to{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.7)}}.devic-handoff-label{flex:1;font-weight:500}.devic-handoff-stop{align-items:center;background:transparent;border:none;border-radius:50%;color:inherit;cursor:pointer;display:inline-flex;height:22px;justify-content:center;opacity:.8;padding:0;width:22px}.devic-handoff-stop:hover{background:rgba(0,0,0,.06);opacity:1}.devic-handoff-pending{align-items:center;animation:devic-handoff-pending-in .18s ease-out;display:flex;flex:1;gap:10px;min-height:24px;min-width:0}@keyframes devic-handoff-pending-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}.devic-handoff-pending-icon{align-items:center;animation:devic-autostop-pulse 1s ease-in-out infinite;color:var(--devic-primary);display:inline-flex;flex-shrink:0;height:36px;justify-content:center;position:relative;width:36px}.devic-handoff-ring{height:100%;inset:0;pointer-events:none;position:absolute;transform:rotate(-90deg);width:100%}.devic-handoff-ring-track{fill:none;stroke:var(--devic-primary);stroke-opacity:.18;stroke-width:3}.devic-handoff-ring-progress{fill:none;stroke:var(--devic-primary);stroke-width:3;stroke-linecap:round;transition:stroke-dashoffset 90ms linear}.devic-handoff-pending-text{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.devic-handoff-pending-title{color:var(--devic-primary);font-size:13px;font-weight:500}.devic-handoff-pending-preview{color:var(--devic-text-secondary);font-size:12px;max-height:4.5em;overflow-wrap:anywhere;overflow-y:auto;white-space:normal;word-break:break-word}.devic-speech-cancel{color:var(--devic-text-muted)}.devic-speech-cancel.devic-input-btn:hover:not(:disabled){color:#cf1322}.devic-speech-status{color:var(--devic-text-secondary);font-size:13px}.devic-speech-spinner{animation:devic-spin .8s linear infinite;border:2px solid var(--devic-border);border-radius:50%;border-top-color:var(--devic-primary);flex-shrink:0;height:16px;width:16px}.devic-transcript-playback{align-items:center;background:hsla(0,0%,100%,.18);border-radius:999px;display:inline-flex;font-size:12px;gap:6px;line-height:1;margin-top:6px;max-width:100%;padding:3px 8px 3px 3px}.devic-message[data-role=assistant] .devic-transcript-playback{background:var(--devic-bg-secondary,rgba(0,0,0,.05))}.devic-transcript-btn{align-items:center;background:hsla(0,0%,100%,.85);border:none;border-radius:50%;color:var(--devic-primary,#6c5ce7);cursor:pointer;display:inline-flex;flex-shrink:0;height:22px;justify-content:center;padding:0;transition:background .15s ease;width:22px}.devic-transcript-btn:hover:not(:disabled){background:#fff}.devic-transcript-btn:disabled{cursor:default;opacity:.7}.devic-transcript-icon{align-items:center;display:inline-flex;opacity:.85}.devic-transcript-playback[data-playing=true] .devic-transcript-icon{animation:devic-pulse 1.2s ease-in-out infinite}.devic-transcript-label{opacity:.9;white-space:nowrap}.devic-transcript-spinner{animation:devic-spin .8s linear infinite;border:2px solid rgba(108,92,231,.3);border-radius:50%;border-top:2px solid var(--devic-primary,#6c5ce7);height:12px;width:12px}.devic-equalizer{align-items:center;display:flex;gap:3px;height:24px}.devic-equalizer-bar{background:var(--devic-primary);border-radius:2px;min-height:3px;transition:height 90ms ease-out;width:3px}.devic-equalizer[data-paused=true] .devic-equalizer-bar{background:var(--devic-text-muted);height:10%!important}.devic-file-preview{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.devic-file-preview-item{align-items:center;background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:var(--devic-radius-sm);display:flex;font-size:12px;gap:6px;padding:4px 8px}.devic-file-remove{background:none;border:none;color:var(--devic-text-muted);cursor:pointer;font-size:16px;line-height:1;padding:0}.devic-file-remove:hover{color:#ff4d4f}.devic-file-preview-thumb{border-radius:var(--devic-radius-sm);display:block;height:28px;object-fit:cover;width:28px}.devic-input-area{position:relative}.devic-drop-overlay{align-items:center;background:var(--devic-bg);border:2px dashed var(--devic-primary,var(--devic-border));border-radius:var(--devic-radius);color:var(--devic-text-muted);display:flex;flex-direction:column;font-size:13px;gap:8px;inset:0;justify-content:center;pointer-events:none;position:absolute;z-index:2}.devic-pasted-cards{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.devic-pasted-card{background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:var(--devic-radius);font-size:12px;max-width:240px;padding:10px;position:relative;text-align:left}.devic-pasted-card-preview{-webkit-line-clamp:5;-webkit-box-orient:vertical;color:var(--devic-text-muted);display:-webkit-box;line-height:1.4;margin:0 0 8px;overflow:hidden}.devic-pasted-card-footer{align-items:center;display:flex;gap:8px}.devic-pasted-card-badge{background:var(--devic-bg-secondary);border-radius:var(--devic-radius-sm);color:var(--devic-text);font-size:10px;font-weight:600;letter-spacing:.04em;padding:2px 6px}.devic-pasted-card-meta{color:var(--devic-text-muted);font-size:11px}.devic-pasted-card-remove{position:absolute;right:6px;top:4px}.devic-message-pasted{display:flex;flex-direction:column;gap:8px;margin-bottom:8px}.devic-message-pasted .devic-pasted-card{max-width:100%;overflow:hidden;padding:0}.devic-pasted-card-toggle{background:none;border:none;color:var(--devic-text);cursor:pointer;display:block;font:inherit;padding:10px;text-align:left;width:100%}.devic-pasted-card-full{color:var(--devic-text);font-family:var(--devic-font-mono,ui-monospace,SFMono-Regular,Menlo,monospace);font-size:11px;line-height:1.5;margin:0 0 8px;max-height:320px;overflow:auto;white-space:pre-wrap;word-break:break-word}.devic-message-file-image{border-radius:var(--devic-radius-sm);display:block;max-width:220px;overflow:hidden}.devic-message-file-image img{display:block;height:auto;width:100%}.devic-trigger{align-items:center;background:var(--devic-primary);border:none;border-radius:50%;box-shadow:var(--devic-shadow);color:#fff;cursor:pointer;display:flex;height:56px;justify-content:center;position:fixed;transition:background var(--devic-transition),transform var(--devic-transition);width:56px}.devic-trigger:hover{background:var(--devic-primary-hover);transform:scale(1.05)}.devic-trigger svg{height:24px;width:24px}.devic-error{background:#fff2f0;border:1px solid #ffccc7;border-radius:var(--devic-radius);color:#ff4d4f;font-size:13px;margin:8px 16px;padding:12px}.devic-messages-container::-webkit-scrollbar{width:6px}.devic-messages-container::-webkit-scrollbar-track{background:transparent}.devic-messages-container::-webkit-scrollbar-thumb{background:var(--devic-border);border-radius:3px}.devic-messages-container::-webkit-scrollbar-thumb:hover{background:var(--devic-text-muted)}.devic-chat-drawer[data-mode=inline]{border:1px solid var(--devic-border);bottom:auto;box-shadow:none;height:100%;left:auto;position:relative;right:auto;top:auto;transform:none}.devic-drawer-header-actions{align-items:center;display:flex;gap:4px;margin-left:auto}.devic-new-chat-btn{background:none;border:none;border-radius:var(--devic-radius-sm);color:var(--devic-text-secondary);cursor:pointer;padding:8px;transition:background var(--devic-transition),color var(--devic-transition)}.devic-new-chat-btn:hover{background:var(--devic-bg-secondary);color:var(--devic-primary)}.devic-conversation-selector{flex:1;margin:0 8px;min-width:72px;position:relative}.devic-conversation-selector-trigger{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:var(--devic-radius-sm);color:var(--devic-text);cursor:pointer;display:flex;font-family:var(--devic-font-family);font-size:13px;gap:6px;padding:6px 10px;text-align:left;transition:border-color var(--devic-transition);width:100%}.devic-conversation-selector-trigger:hover{border-color:var(--devic-primary)}.devic-conversation-selector-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-conversation-dropdown{background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:var(--devic-radius);box-shadow:var(--devic-shadow);display:flex;flex-direction:column;left:0;max-height:320px;position:absolute;right:0;top:calc(100% + 4px);z-index:10}.devic-conversation-search-wrapper{border-bottom:1px solid var(--devic-border);padding:8px}.devic-conversation-search{background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:var(--devic-radius-sm);box-sizing:border-box;color:var(--devic-text);font-family:var(--devic-font-family);font-size:13px;outline:none;padding:6px 8px;width:100%}.devic-conversation-search:focus{border-color:var(--devic-primary)}.devic-conversation-list{flex:1;overflow-y:auto}.devic-conversation-item{align-items:center;background:none;border:none;color:var(--devic-text);cursor:pointer;display:flex;font-family:var(--devic-font-family);font-size:13px;justify-content:space-between;padding:8px 12px;text-align:left;transition:background .15s;width:100%}.devic-conversation-item:hover,.devic-conversation-item[data-active=true]{background:var(--devic-bg-secondary)}.devic-conversation-item-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-conversation-item-date{color:var(--devic-text-muted);flex-shrink:0;font-size:11px;margin-left:8px}.devic-conversation-empty,.devic-conversation-loading{color:var(--devic-text-muted);font-size:13px;padding:12px;text-align:center}.devic-conversation-load-more{background:none;border:none;color:var(--devic-text-muted);cursor:pointer;display:block;font-family:var(--devic-font-family);font-size:12px;padding:8px 12px;text-align:center;transition:background .15s;width:100%}.devic-conversation-load-more:hover{background:var(--devic-bg-secondary);color:var(--devic-primary)}.devic-conversation-new{background:none;border:none;border-top:1px solid var(--devic-border);color:var(--devic-primary);cursor:pointer;display:block;font-family:var(--devic-font-family);font-size:13px;padding:10px 12px;text-align:left;transition:background .15s;width:100%}.devic-conversation-new:hover{background:var(--devic-bg-secondary)}.devic-conversation-item-check{align-items:center;color:var(--devic-primary);display:flex;flex-shrink:0;margin-right:6px}.devic-message-bubble h1,.devic-message-bubble h2,.devic-message-bubble h3,.devic-message-bubble h4,.devic-message-bubble h5,.devic-message-bubble h6{line-height:1.3;margin:8px 0 4px}.devic-message-bubble h1{font-size:1.3em}.devic-message-bubble h2{font-size:1.2em}.devic-message-bubble h3{font-size:1.1em}.devic-message-bubble p{margin:4px 0}.devic-message-bubble ol,.devic-message-bubble ul{margin:4px 0;padding-left:20px}.devic-message-bubble code{background:rgba(0,0,0,.06);border-radius:3px;color:inherit;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:.9em;padding:1px 4px}.devic-message-bubble pre{background:rgba(0,0,0,.06);border-radius:var(--devic-radius-sm);color:inherit;margin:8px 0;overflow-x:auto;padding:10px}.devic-message-bubble pre code{background:none;color:inherit;padding:0}.devic-message-bubble blockquote{border-left:3px solid var(--devic-border);color:var(--devic-text-secondary);margin:4px 0;padding-left:12px}.devic-message-bubble a{color:var(--devic-primary);text-decoration:underline}.devic-message-bubble p:first-child{margin-top:0}.devic-message-bubble p:last-child{margin-bottom:0}.devic-message[data-role=user] .devic-message-bubble a{color:inherit}.devic-message[data-role=user] .devic-message-bubble code,.devic-message[data-role=user] .devic-message-bubble pre{background:hsla(0,0%,100%,.18)}.devic-message[data-role=user] .devic-message-bubble blockquote{border-left-color:hsla(0,0%,100%,.45);color:inherit}.markdown-table{margin:8px 0;overflow-x:auto}.markdown-table table{border-collapse:collapse;font-size:13px;width:100%}.markdown-table td,.markdown-table th{border:1px solid var(--devic-border);padding:6px 10px;text-align:left}.markdown-table th{background:var(--devic-bg-secondary);font-weight:600}.devic-resize-handle{bottom:0;cursor:col-resize;position:absolute;top:0;width:6px;z-index:1}.devic-resize-handle[data-position=right]{left:0}.devic-resize-handle[data-position=left]{right:0}.devic-resize-handle:active,.devic-resize-handle:hover{background:var(--devic-primary);opacity:.3}.devic-handoff-widget{animation:devic-slideUp .3s ease-out;background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:8px;display:flex;flex-direction:column;gap:10px;max-width:320px;padding:12px;width:100%}.devic-handoff-header{align-items:center;display:flex;gap:8px}.devic-handoff-agent-avatar{align-items:center;background:var(--devic-bg-secondary);border-radius:50%;display:flex;flex-shrink:0;height:24px;justify-content:center;overflow:hidden;width:24px}.devic-handoff-avatar-img{height:100%;object-fit:cover;width:100%}.devic-handoff-agent-name{color:var(--devic-text);font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-handoff-progress,.devic-handoff-state-row{align-items:center;display:flex;gap:8px}.devic-handoff-progress-bar{background:#f0f0f0;border-radius:3px;flex:1;height:6px;overflow:hidden;position:relative}.devic-handoff-progress-fill{border-radius:3px;height:100%;transition:width .4s ease}.devic-handoff-progress-fill[data-status=active]{background:var(--devic-primary)}.devic-handoff-progress-fill[data-status=success]{background:#52c41a}.devic-handoff-progress-fill[data-status=error]{background:#ff4d4f}.devic-handoff-progress-text{color:var(--devic-text-muted);flex-shrink:0;font-size:11px}.devic-handoff-progress-indeterminate{animation:devic-indeterminate 1.5s ease-in-out infinite;background:var(--devic-primary);border-radius:3px;height:100%;width:40%}@keyframes devic-indeterminate{0%{transform:translateX(-100%)}50%{transform:translateX(150%)}to{transform:translateX(-100%)}}.devic-handoff-summary{-webkit-line-clamp:2;-webkit-box-orient:vertical;color:var(--devic-text-secondary);display:-webkit-box;font-size:12px;line-height:1.4;overflow:hidden;text-overflow:ellipsis}.devic-handoff-summary-active{animation:devic-pulse 2s cubic-bezier(.4,0,.6,1) infinite}.devic-handoff-elapsed{align-items:center;color:var(--devic-text-muted);display:flex;font-size:11px;gap:4px}.devic-message[data-role=user] .devic-message-references{display:flex;flex-wrap:wrap;gap:4px;justify-content:flex-end;margin-bottom:4px}.devic-message-reference-chip{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:999px;color:var(--devic-text);display:inline-flex;font-size:11px;gap:4px;max-width:220px;padding:3px 8px}.devic-message-reference-chip-label{color:var(--devic-primary);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-reference-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:4px;padding:6px 8px}.devic-reference-chip{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:999px;color:var(--devic-text);display:inline-flex;font-size:12px;gap:6px;max-width:220px;padding:4px 8px}.devic-reference-chip-label{color:var(--devic-primary);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-reference-chip-remove{align-items:center;background:transparent;border:none;border-radius:4px;color:var(--devic-text-muted);cursor:pointer;display:inline-flex;font-size:16px;line-height:1;padding:0 2px}.devic-reference-chip-remove:hover{background:rgba(0,0,0,.06);color:var(--devic-text)}.devic-queue-notice{align-items:center;background:var(--devic-bg-secondary);border:1px dashed var(--devic-queued-border);border-radius:var(--devic-radius);color:var(--devic-text-secondary);display:flex;font-size:12px;gap:6px;line-height:1.4;margin-bottom:4px;padding:8px 12px}.devic-queue-notice-icon{color:var(--devic-queued-accent);display:flex;flex-shrink:0}.devic-queue-notice[data-alert=true]{border-color:var(--devic-error,#ff4d4f);border-style:solid;color:var(--devic-text)}.devic-queue-notice[data-alert=true] .devic-queue-notice-icon{color:var(--devic-error,#ff4d4f)}.devic-input-disabled-notice{align-items:center;background:var(--devic-bg-secondary);border-radius:var(--devic-radius);color:var(--devic-text-muted);display:flex;font-size:12px;gap:6px;justify-content:center;margin-bottom:4px;padding:8px 12px}.devic-inline-widgets{display:flex;flex-direction:column;gap:8px;padding:8px 12px}.devic-inline-widget{background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:var(--devic-radius);padding:12px}.devic-input-widget{padding:8px;width:100%}.devic-limit-banner{align-items:flex-start;background:#fff7e6;border:1px solid #ffd591;border-radius:var(--devic-radius);color:#ad4e00;display:flex;font-size:13px;gap:8px;margin-bottom:8px;padding:8px 12px}.devic-limit-banner-icon{color:#fa8c16;display:inline-flex;flex-shrink:0;margin-top:1px}.devic-limit-banner-text{display:flex;flex-direction:column;gap:2px;line-height:1.35}.devic-limit-banner-title{font-weight:600}.devic-limit-banner-reset{color:var(--devic-text-secondary);font-size:12px}.devic-usage-bar-wrap{display:flex;flex-direction:column;gap:6px;margin-bottom:8px}.devic-usage-bar-head{align-items:center;display:flex;gap:8px;justify-content:space-between}.devic-usage-tier{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:999px;color:var(--devic-text-secondary);display:inline-flex;font-size:11px;font-weight:600;letter-spacing:.02em;padding:2px 8px;text-transform:uppercase;white-space:nowrap}.devic-usage-bar-window{color:var(--devic-text-muted);white-space:nowrap}.devic-usage-bar-group{background:var(--devic-bg-secondary);border-radius:var(--devic-radius);display:flex;flex-direction:column;gap:4px;padding:5px 10px}.devic-usage-bar-group .devic-usage-bar{background:transparent;padding:0}.devic-usage-bar{align-items:center;background:var(--devic-bg-secondary);border-radius:var(--devic-radius);color:var(--devic-text-secondary);display:flex;font-size:12px;gap:8px;padding:5px 10px}.devic-usage-bar[data-empty=true]{color:var(--devic-text-muted);justify-content:space-between}.devic-usage-bar-label{font-weight:500;white-space:nowrap}.devic-usage-bar-track{background:var(--devic-border);border-radius:999px;flex:1;height:6px;overflow:hidden}.devic-usage-bar-fill{border-radius:999px;height:100%;transition:width var(--devic-transition),background-color var(--devic-transition)}.devic-usage-bar-reset{color:var(--devic-text-muted);white-space:nowrap}.devic-usage-toggle{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:999px;color:var(--devic-text-secondary);cursor:pointer;display:inline-flex;font-size:12px;font-weight:500;gap:6px;padding:4px 10px;transition:background var(--devic-transition),color var(--devic-transition)}.devic-usage-toggle:hover{background:var(--devic-border);color:var(--devic-text)}.devic-usage-collapse{align-items:center;background:transparent;border:none;border-radius:var(--devic-radius-sm);color:var(--devic-text-muted);cursor:pointer;display:inline-flex;font-size:16px;height:18px;justify-content:center;line-height:1;padding:0;width:18px}.devic-usage-collapse:hover{background:var(--devic-border);color:var(--devic-text)}@media (max-width:480px){.devic-chat-drawer{width:100%}}.devic-compaction{color:var(--devic-text-secondary);flex-shrink:0;font-size:12px;margin:10px 0;width:100%}.devic-compaction-head,.devic-compaction-running{align-items:center;display:flex;gap:8px}.devic-compaction-rule{background:var(--devic-compaction-border,rgba(114,46,209,.3));flex:1;height:1px}.devic-compaction-pill{align-items:center;background:var(--devic-compaction-bg,rgba(114,46,209,.06));border:1px solid var(--devic-compaction-border,rgba(114,46,209,.3));border-radius:999px;color:inherit;cursor:pointer;display:flex;flex-shrink:0;font:inherit;gap:8px;max-width:100%;overflow:hidden;padding:4px 12px;white-space:nowrap}.devic-compaction-pill-static,.devic-compaction-running .devic-compaction-pill{cursor:default}.devic-compaction-icon{color:var(--devic-compaction-accent,#722ed1);flex-shrink:0}.devic-compaction-title{color:var(--devic-text);font-weight:600}.devic-compaction-meta{opacity:.75;overflow:hidden;text-overflow:ellipsis}.devic-compaction-tag{border:1px solid var(--devic-compaction-border,rgba(114,46,209,.3));border-radius:4px;font-size:10px;line-height:16px;opacity:.8;padding:0 6px}.devic-compaction-chevron{flex-shrink:0;opacity:.6;transition:transform .15s ease}.devic-compaction-dots{display:inline-flex;flex-shrink:0;gap:3px}.devic-compaction-dots i{animation:devic-compaction-blink 1.2s ease-in-out infinite;background:var(--devic-compaction-accent,#722ed1);border-radius:50%;height:4px;width:4px}.devic-compaction-dots i:nth-child(2){animation-delay:.2s}.devic-compaction-dots i:nth-child(3){animation-delay:.4s}@keyframes devic-compaction-blink{0%,80%,to{opacity:.25}40%{opacity:1}}.devic-compaction-body{background:var(--devic-compaction-bg,rgba(114,46,209,.06));border:1px solid var(--devic-compaction-border,rgba(114,46,209,.3));border-radius:var(--devic-radius-sm,8px);display:flex;flex-direction:column;gap:10px;margin-top:8px;padding:10px 12px}.devic-compaction-note{color:var(--devic-text-muted);font-size:11px}.devic-compaction-section{color:var(--devic-text);display:flex;flex-direction:column;gap:3px}.devic-compaction-section-title{font-size:10px;font-weight:600;letter-spacing:.5px;opacity:.7;text-transform:uppercase}.devic-compaction-list{margin:0;padding-left:18px}.devic-compaction-raw{white-space:pre-wrap}.devic-compaction-facts{display:flex;flex-wrap:wrap;gap:4px}.devic-compaction-fact{border:1px solid var(--devic-compaction-border,rgba(114,46,209,.3));border-radius:4px;font-family:var(--devic-font-mono,ui-monospace,SFMono-Regular,monospace);font-size:11px;line-height:18px;padding:0 6px}.devic-compaction-fact-label{opacity:.65}.devic-command-bar-container{--devic-cmd-bg:var(--devic-cmd-bg-override,#fff);--devic-cmd-text:var(--devic-cmd-text-override,#1f2937);--devic-cmd-text-secondary:var(--devic-cmd-text-secondary-override,#6b7280);--devic-cmd-border:var(--devic-cmd-border-override,#e5e7eb);--devic-cmd-radius:var(--devic-cmd-radius-override,12px);--devic-cmd-shadow:var(--devic-cmd-shadow-override,0 4px 20px rgba(0,0,0,.1));--devic-cmd-primary:var(--devic-cmd-primary-override,#3b82f6);--devic-cmd-font-family:var(--devic-cmd-font-family-override,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif);--devic-cmd-font-size:var(--devic-cmd-font-size-override,14px);--devic-cmd-animation-duration:var(--devic-cmd-animation-duration-override,200ms);color:var(--devic-cmd-text);display:flex;flex-direction:column;font-family:var(--devic-cmd-font-family);font-size:var(--devic-cmd-font-size);gap:8px;max-width:100%;width:400px}.devic-command-bar-container[data-position=fixed]{position:fixed}.devic-command-bar-container[data-position=inline]{position:relative}.devic-command-bar-container[data-visible=false]{opacity:0;pointer-events:none;transform:translateY(8px)}.devic-command-bar-container[data-visible=false],.devic-command-bar-container[data-visible=true]{transition:opacity var(--devic-cmd-animation-duration) ease,transform var(--devic-cmd-animation-duration) ease}.devic-command-bar-container[data-visible=true]{opacity:1;transform:translateY(0)}.devic-command-bar{align-items:center;background:var(--devic-cmd-bg);border:1px solid var(--devic-cmd-border);border-radius:var(--devic-cmd-radius);box-shadow:var(--devic-cmd-shadow);display:flex;gap:12px;padding:12px 16px}.devic-command-bar-icon{align-items:center;color:var(--devic-cmd-text-secondary);display:flex;flex-shrink:0;height:20px;justify-content:center;width:20px}.devic-command-bar-icon svg{height:100%;width:100%}.devic-command-bar-input{background:transparent;border:none;color:inherit;flex:1;font-family:inherit;font-size:inherit;min-width:0;outline:none}.devic-command-bar-input::placeholder{color:var(--devic-cmd-text-secondary)}.devic-command-bar-summary{animation:devic-cmd-pulse 1.5s ease-in-out infinite;color:var(--devic-cmd-text-secondary);flex:1;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@keyframes devic-cmd-pulse{0%,to{opacity:1}50%{opacity:.6}}.devic-command-bar-shortcut{background:var(--devic-cmd-border);border-radius:6px;color:var(--devic-cmd-text-secondary);flex-shrink:0;font-size:12px;font-weight:500;letter-spacing:.5px;padding:4px 8px}.devic-command-bar-spinner{animation:devic-cmd-spin .8s linear infinite;border:2px solid var(--devic-cmd-border);border-radius:50%;border-top-color:var(--devic-cmd-primary);height:20px;width:20px}@keyframes devic-cmd-spin{to{transform:rotate(1turn)}}.devic-command-bar-result{animation:devic-cmd-slide-up .2s ease-out;background:var(--devic-cmd-bg);border:1px solid var(--devic-cmd-border);border-radius:var(--devic-cmd-radius);box-shadow:var(--devic-cmd-shadow);overflow:hidden}@keyframes devic-cmd-slide-up{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.devic-command-bar-result-tools{border-bottom:1px solid var(--devic-cmd-border)}.devic-command-bar-result-tools-header{align-items:center;color:var(--devic-cmd-text-secondary);cursor:pointer;display:flex;font-size:13px;gap:8px;padding:10px 14px;transition:background .15s ease;user-select:none}.devic-command-bar-result-tools-header:hover{background:rgba(0,0,0,.02)}.devic-command-bar-result-tools-chevron{height:16px;transition:transform .2s ease;width:16px}.devic-command-bar-result-tools-header[data-expanded=true] .devic-command-bar-result-tools-chevron{transform:rotate(90deg)}.devic-command-bar-result-tools-count{align-items:center;background:var(--devic-cmd-primary);border-radius:10px;color:#fff;display:inline-flex;font-size:11px;font-weight:600;height:20px;justify-content:center;min-width:20px;padding:0 6px}.devic-command-bar-result-tools-list{display:flex;flex-direction:column;gap:6px;padding:8px 14px 12px}.devic-command-bar-result-tools-list[data-expanded=false]{display:none}.devic-command-bar-result-tool-item{align-items:center;background:rgba(0,0,0,.02);border-radius:6px;display:flex;font-size:12px;gap:8px;padding:6px 10px}.devic-command-bar-result-tool-icon{color:#10b981;height:14px;width:14px}.devic-command-bar-result-tool-name{color:var(--devic-cmd-text-secondary)}.devic-command-bar-result-message{line-height:1.5;max-height:300px;overflow-y:auto;padding:14px}.devic-command-bar-result-message::-webkit-scrollbar{width:6px}.devic-command-bar-result-message::-webkit-scrollbar-track{background:transparent}.devic-command-bar-result-message::-webkit-scrollbar-thumb{background:var(--devic-cmd-border);border-radius:3px}.devic-command-bar-error{background:#fef2f2;border:1px solid #fecaca;border-radius:var(--devic-cmd-radius);color:#dc2626;font-size:13px;padding:10px 14px}.devic-command-bar-result-empty{color:var(--devic-cmd-text-secondary);font-size:13px;padding:14px;text-align:center}.devic-command-bar-dropdown{animation:devic-cmd-slide-up .2s ease-out;background:var(--devic-cmd-bg);border:1px solid var(--devic-cmd-border);border-radius:var(--devic-cmd-radius);box-shadow:var(--devic-cmd-shadow);overflow:hidden}.devic-command-bar-dropdown-header{align-items:center;border-bottom:1px solid var(--devic-cmd-border);color:var(--devic-cmd-text-secondary);display:flex;font-size:12px;font-weight:600;justify-content:space-between;letter-spacing:.5px;padding:10px 14px;text-transform:uppercase}.devic-command-bar-dropdown-hint{align-items:center;display:flex;font-weight:400;gap:4px;letter-spacing:0;text-transform:none}.devic-command-bar-dropdown-hint kbd{align-items:center;background:var(--devic-cmd-border);border-radius:4px;display:inline-flex;font-family:inherit;font-size:10px;height:18px;justify-content:center;min-width:18px;padding:0 4px}.devic-command-bar-dropdown-clear{background:none;border:none;border-radius:4px;color:var(--devic-cmd-primary);cursor:pointer;font-family:inherit;font-size:12px;font-weight:500;letter-spacing:0;padding:2px 6px;text-transform:none}.devic-command-bar-dropdown-clear:hover{background:rgba(0,0,0,.05)}.devic-command-bar-dropdown-list{max-height:250px;overflow-y:auto}.devic-command-bar-dropdown-list::-webkit-scrollbar{width:6px}.devic-command-bar-dropdown-list::-webkit-scrollbar-track{background:transparent}.devic-command-bar-dropdown-list::-webkit-scrollbar-thumb{background:var(--devic-cmd-border);border-radius:3px}.devic-command-bar-dropdown-item{align-items:center;cursor:pointer;display:flex;gap:10px;padding:10px 14px;transition:background .15s ease}.devic-command-bar-dropdown-item:hover,.devic-command-bar-dropdown-item[data-selected=true]{background:rgba(0,0,0,.04)}.devic-command-bar-dropdown-item[data-selected=true]{background:var(--devic-cmd-primary);background:rgba(59,130,246,.1)}.devic-command-bar-dropdown-icon{align-items:center;color:var(--devic-cmd-text-secondary);display:flex;flex-shrink:0;height:16px;justify-content:center;width:16px}.devic-command-bar-dropdown-keyword{color:var(--devic-cmd-text);flex-shrink:0;font-weight:600}.devic-command-bar-dropdown-desc{color:var(--devic-cmd-text-secondary);flex:1;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-command-bar-dropdown-empty{color:var(--devic-cmd-text-secondary);font-size:13px;padding:20px 14px;text-align:center}.devic-command-bar-history-item{border-bottom:1px solid rgba(0,0,0,.04)}.devic-command-bar-history-item:last-child{border-bottom:none}.devic-command-bar-history-text{flex:1;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-gen-container{--devic-gen-primary:var(--devic-gen-primary-override,#3b82f6);--devic-gen-primary-hover:var(--devic-gen-primary-hover-override,#2563eb);--devic-gen-bg:var(--devic-gen-bg-override,#fff);--devic-gen-text:var(--devic-gen-text-override,#1f2937);--devic-gen-text-secondary:var(--devic-gen-text-secondary-override,#6b7280);--devic-gen-border:var(--devic-gen-border-override,#e5e7eb);--devic-gen-radius:var(--devic-gen-radius-override,8px);--devic-gen-font-family:var(--devic-gen-font-family-override,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif);--devic-gen-font-size:var(--devic-gen-font-size-override,14px);--devic-gen-z-index:var(--devic-gen-z-index-override,10000);--devic-gen-animation-duration:var(--devic-gen-animation-duration-override,200ms);--devic-gen-modal-bg:var(--devic-gen-modal-bg-override,#fff);--devic-gen-modal-text:var(--devic-gen-modal-text-override,#1f2937);--devic-gen-modal-border:var(--devic-gen-modal-border-override,#e5e7eb);font-family:var(--devic-gen-font-family);font-size:var(--devic-gen-font-size)}.devic-gen-button{align-items:center;border:none;border-radius:var(--devic-gen-radius);cursor:pointer;display:inline-flex;font-family:inherit;font-weight:500;gap:8px;justify-content:center;transition:all var(--devic-gen-animation-duration) ease}.devic-gen-button:disabled{cursor:not-allowed;opacity:.6}.devic-gen-button[data-size=small]{font-size:12px;padding:6px 12px}.devic-gen-button[data-size=medium]{font-size:14px;padding:8px 16px}.devic-gen-button[data-size=large]{font-size:16px;padding:12px 24px}.devic-gen-button[data-variant=primary]{background:var(--devic-gen-primary);color:#fff}.devic-gen-button[data-variant=primary]:hover:not(:disabled){background:var(--devic-gen-primary-hover)}.devic-gen-button[data-variant=secondary]{background:var(--devic-gen-border);color:var(--devic-gen-text)}.devic-gen-button[data-variant=secondary]:hover:not(:disabled){background:#d1d5db}.devic-gen-button[data-variant=outline]{background:transparent;border:1px solid var(--devic-gen-primary);color:var(--devic-gen-primary)}.devic-gen-button[data-variant=outline]:hover:not(:disabled){background:rgba(59,130,246,.1)}.devic-gen-button[data-variant=ghost]{background:transparent;color:var(--devic-gen-text)}.devic-gen-button[data-variant=ghost]:hover:not(:disabled){background:rgba(0,0,0,.05)}.devic-gen-button-icon{align-items:center;display:flex;height:16px;justify-content:center;width:16px}.devic-gen-button-icon svg{height:100%;width:100%}.devic-gen-spinner{animation:devic-gen-spin .8s linear infinite;border:2px solid;border-radius:50%;border-top:2px solid transparent;height:16px;width:16px}.devic-gen-spinner-small{border-width:1.5px;height:12px;width:12px}@keyframes devic-gen-spin{to{transform:rotate(1turn)}}.devic-gen-input{background:var(--devic-gen-modal-bg);border:1px solid var(--devic-gen-modal-border);border-radius:var(--devic-gen-radius);color:var(--devic-gen-modal-text);font-family:inherit;font-size:inherit;min-height:80px;outline:none;padding:12px;resize:vertical;transition:border-color var(--devic-gen-animation-duration) ease;width:100%}.devic-gen-input:focus{border-color:var(--devic-gen-primary)}.devic-gen-input::placeholder{color:var(--devic-gen-text-secondary)}.devic-gen-error{background:#fef2f2;border:1px solid #fecaca;border-radius:var(--devic-gen-radius);color:#dc2626;font-size:13px;margin-top:8px;padding:8px 12px}.devic-gen-tooltip{animation:devic-gen-fade-in var(--devic-gen-animation-duration) ease-out;background:var(--devic-gen-modal-bg);border:1px solid var(--devic-gen-modal-border);border-radius:var(--devic-gen-radius);box-shadow:0 4px 20px rgba(0,0,0,.15);padding:12px}@keyframes devic-gen-fade-in{0%{opacity:0;transform:translateY(4px) translateX(-50%)}to{opacity:1;transform:translateY(0) translateX(-50%)}}.devic-gen-tooltip[data-placement=left],.devic-gen-tooltip[data-placement=right]{animation-name:devic-gen-fade-in-horizontal}@keyframes devic-gen-fade-in-horizontal{0%{opacity:0;transform:translateX(4px) translateY(-50%)}to{opacity:1;transform:translateX(0) translateY(-50%)}}.devic-gen-tooltip-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:12px}.devic-gen-tooltip-cancel,.devic-gen-tooltip-confirm{align-items:center;border-radius:var(--devic-gen-radius);cursor:pointer;display:inline-flex;font-family:inherit;font-size:13px;font-weight:500;gap:6px;padding:6px 12px;transition:all var(--devic-gen-animation-duration) ease}.devic-gen-tooltip-cancel{background:transparent;border:1px solid var(--devic-gen-modal-border);color:var(--devic-gen-text-secondary)}.devic-gen-tooltip-cancel:hover{background:rgba(0,0,0,.05)}.devic-gen-tooltip-confirm{background:var(--devic-gen-primary);border:none;color:#fff}.devic-gen-tooltip-confirm:hover:not(:disabled){background:var(--devic-gen-primary-hover)}.devic-gen-tooltip-confirm:disabled{cursor:not-allowed;opacity:.6}.devic-gen-modal-overlay{align-items:center;animation:devic-gen-overlay-fade-in var(--devic-gen-animation-duration) ease-out;background:rgba(0,0,0,.5);display:flex;inset:0;justify-content:center;position:fixed;z-index:var(--devic-gen-z-index)}@keyframes devic-gen-overlay-fade-in{0%{opacity:0}to{opacity:1}}.devic-gen-modal{animation:devic-gen-modal-slide-up var(--devic-gen-animation-duration) ease-out;background:var(--devic-gen-modal-bg);border-radius:calc(var(--devic-gen-radius) + 4px);box-shadow:0 20px 50px rgba(0,0,0,.2);margin:16px;max-width:480px;width:100%}@keyframes devic-gen-modal-slide-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.devic-gen-modal-header{align-items:center;border-bottom:1px solid var(--devic-gen-modal-border);display:flex;justify-content:space-between;padding:16px 20px}.devic-gen-modal-title{color:var(--devic-gen-modal-text);font-size:18px;font-weight:600;margin:0}.devic-gen-modal-close{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--devic-gen-text-secondary);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:all var(--devic-gen-animation-duration) ease;width:32px}.devic-gen-modal-close:hover{background:rgba(0,0,0,.05);color:var(--devic-gen-modal-text)}.devic-gen-modal-description{color:var(--devic-gen-text-secondary);font-size:14px;line-height:1.5;margin:0;padding:12px 20px 0}.devic-gen-modal-body{padding:16px 20px}.devic-gen-modal-footer{border-top:1px solid var(--devic-gen-modal-border);display:flex;gap:12px;justify-content:flex-end;padding:16px 20px}.devic-gen-modal-cancel,.devic-gen-modal-confirm{align-items:center;border-radius:var(--devic-gen-radius);cursor:pointer;display:inline-flex;font-family:inherit;font-size:14px;font-weight:500;gap:8px;padding:10px 20px;transition:all var(--devic-gen-animation-duration) ease}.devic-gen-modal-cancel{background:transparent;border:1px solid var(--devic-gen-modal-border);color:var(--devic-gen-text-secondary)}.devic-gen-modal-cancel:hover{background:rgba(0,0,0,.05);color:var(--devic-gen-modal-text)}.devic-gen-modal-confirm{background:var(--devic-gen-primary);border:none;color:#fff}.devic-gen-modal-confirm:hover:not(:disabled){background:var(--devic-gen-primary-hover)}.devic-gen-modal-confirm:disabled{cursor:not-allowed;opacity:.6}.devic-gen-input::-webkit-scrollbar{width:6px}.devic-gen-input::-webkit-scrollbar-track{background:transparent}.devic-gen-input::-webkit-scrollbar-thumb{background:var(--devic-gen-border);border-radius:3px}.devic-gen-input:disabled{background:var(--devic-gen-border);cursor:not-allowed;opacity:.6}.devic-gen-tool-calls{background:rgba(0,0,0,.02);border:1px solid var(--devic-gen-modal-border);border-radius:var(--devic-gen-radius);display:flex;flex-direction:column;gap:6px;margin-bottom:12px;padding:10px 12px}.devic-gen-tool-item{align-items:center;color:var(--devic-gen-text-secondary);display:flex;font-size:13px;gap:8px}.devic-gen-tool-item[data-status=executing]{color:var(--devic-gen-primary)}.devic-gen-tool-item[data-status=completed] .devic-gen-tool-icon{color:#10b981}.devic-gen-tool-icon{align-items:center;display:flex;flex-shrink:0;height:16px;justify-content:center;width:16px}.devic-gen-tool-icon svg{height:100%;width:100%}.devic-gen-tool-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-gen-tool-custom{padding:8px 0}.devic-gen-processing-status{align-items:center;background:rgba(59,130,246,.05);border:1px solid rgba(59,130,246,.2);border-radius:var(--devic-gen-radius);display:flex;gap:8px;margin-bottom:12px;padding:10px 12px}.devic-gen-processing-text{animation:devic-gen-pulse 1.5s ease-in-out infinite;color:var(--devic-gen-primary);font-size:13px}@keyframes devic-gen-pulse{0%,to{opacity:1}50%{opacity:.6}}.devic-aiwrap-container,.devic-aiwrap-tooltip,.devic-aiwrap-trigger-wrapper{--devic-aiwrap-color:#7c3aed;--devic-aiwrap-color-2:#4f46e5;--devic-aiwrap-bg:#fff;--devic-aiwrap-text:#1f2937;--devic-aiwrap-border:#e5e7eb;--devic-aiwrap-shadow:0 8px 24px rgba(0,0,0,.12)}.devic-aiwrap-container[data-highlight=true] .devic-aiwrap-content{background:rgba(124,58,237,.08);border-radius:4px;outline:1px dashed rgba(124,58,237,.45);outline-offset:2px;transition:background .15s ease,outline-color .15s ease}.devic-aiwrap-content{display:inline;transition:background .15s ease}.devic-aiwrap-trigger-wrapper{display:inline-flex}.devic-aiwrap-trigger{align-items:center;background:linear-gradient(90deg,var(--devic-aiwrap-color) 0,var(--devic-aiwrap-color-2) 100%);border:1px solid hsla(0,0%,100%,.25);box-shadow:0 4px 14px rgba(124,58,237,.35);color:#fff;cursor:pointer;display:inline-flex;font-family:inherit;font-size:13px;font-weight:500;gap:6px;padding:6px 12px;transition:transform .12s ease,box-shadow .12s ease;white-space:nowrap}.devic-aiwrap-trigger:hover{box-shadow:0 6px 18px rgba(124,58,237,.45);transform:translateY(-1px)}.devic-aiwrap-trigger:active{transform:translateY(0)}.devic-aiwrap-trigger-icon{align-items:center;display:inline-flex}.devic-aiwrap-trigger-label{line-height:1}.devic-aiwrap-tooltip{background:var(--devic-aiwrap-bg);border:1px solid var(--devic-aiwrap-border);border-radius:12px;box-shadow:var(--devic-aiwrap-shadow);color:var(--devic-aiwrap-text);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px;overflow:hidden}.devic-aiwrap-tooltip-header{align-items:center;background:rgba(124,58,237,.05);border-bottom:1px solid var(--devic-aiwrap-border);display:flex;gap:8px;justify-content:space-between;padding:10px 12px}.devic-aiwrap-tooltip-label{color:var(--devic-aiwrap-color);font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-aiwrap-tooltip-close{align-items:center;background:transparent;border:none;border-radius:4px;color:#6b7280;cursor:pointer;display:inline-flex;padding:2px}.devic-aiwrap-tooltip-close:hover{background:rgba(0,0,0,.06);color:#111827}.devic-aiwrap-tooltip-body{line-height:1.5;max-height:320px;overflow-y:auto;padding:12px}.devic-aiwrap-processing{align-items:center;color:#6b7280;display:flex;font-size:13px;gap:8px}.devic-aiwrap-spinner{animation:devic-aiwrap-spin .7s linear infinite;border:2px solid rgba(124,58,237,.25);border-radius:50%;border-top:2px solid var(--devic-aiwrap-color);flex-shrink:0;height:14px;width:14px}@keyframes devic-aiwrap-spin{to{transform:rotate(1turn)}}.devic-aiwrap-error{color:#dc2626;font-size:13px}.devic-aiwrap-answer{white-space:pre-wrap;word-break:break-word}
|
|
1
|
+
.devic-state-tag{align-items:center;border:1px solid;border-radius:4px;cursor:default;display:inline-flex;font-family:var(--devic-font-family,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif);font-size:12px;font-weight:500;gap:6px;line-height:20px;padding:2px 8px;position:relative;white-space:nowrap}.devic-state-tag[data-interactive=true]{cursor:pointer}.devic-state-tag[data-interactive=true]:hover{opacity:.85}.devic-state-tag[data-color=gold]{background:rgba(250,173,20,.15);border-color:rgba(250,173,20,.35);color:#faad14}.devic-state-tag[data-color=processing]{background:rgba(22,119,255,.15);border-color:rgba(22,119,255,.35);color:#4096ff}.devic-state-tag[data-color=success]{background:rgba(82,196,26,.15);border-color:rgba(82,196,26,.35);color:#52c41a}.devic-state-tag[data-color=error]{background:rgba(255,77,79,.15);border-color:rgba(255,77,79,.35);color:#ff4d4f}.devic-state-tag[data-color=default]{background:hsla(0,0%,60%,.15);border-color:hsla(0,0%,60%,.35);color:#999}.devic-state-tag[data-color=purple]{background:rgba(114,46,209,.15);border-color:rgba(114,46,209,.35);color:#b37feb}.devic-state-tag[data-color=blue]{background:rgba(22,119,255,.15);border-color:rgba(22,119,255,.35);color:#4096ff}.devic-state-tag-icon{align-items:center;display:inline-flex;flex-shrink:0}.devic-state-tag-caret{align-items:center;display:inline-flex;margin-left:2px;transition:transform .2s ease}.devic-state-tag[data-dropdown-open=true] .devic-state-tag-caret{transform:rotate(180deg)}.devic-state-spinner{animation:devic-state-spin 1s linear infinite}@keyframes devic-state-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.devic-state-tooltip{background:rgba(0,0,0,.85);border-radius:6px;bottom:calc(100% + 8px);color:#fff;font-family:SFMono-Regular,Consolas,monospace;font-size:12px;font-weight:400;line-height:1.4;max-width:280px;padding:6px 10px;pointer-events:none;white-space:normal;z-index:1060}.devic-state-tooltip,.devic-state-tooltip:after{left:50%;position:absolute;transform:translateX(-50%)}.devic-state-tooltip:after{border:5px solid transparent;border-top-color:rgba(0,0,0,.85);content:"";top:100%}.devic-state-dropdown{animation:devic-dropdownSlide .15s ease-out;background:#fff;border:1px solid #e8e8e8;border-radius:8px;box-shadow:0 6px 16px rgba(0,0,0,.08),0 3px 6px rgba(0,0,0,.06);min-width:180px;padding:4px 0;position:absolute;right:0;top:calc(100% + 4px);z-index:1050}@keyframes devic-dropdownSlide{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.devic-state-dropdown-item{align-items:center;background:none;border:none;color:#333;cursor:pointer;display:flex;font-family:inherit;font-size:13px;gap:8px;padding:8px 12px;text-align:left;transition:background .15s;width:100%}.devic-state-dropdown-item:hover{background:#f5f5f5}.devic-state-dropdown-item-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center;width:18px}.devic-state-tooltip-portal{background:rgba(0,0,0,.85);border-radius:6px;color:#fff;font-family:SFMono-Regular,Consolas,monospace;font-size:12px;font-weight:400;line-height:1.4;max-width:280px;padding:6px 10px;pointer-events:none;white-space:normal;z-index:99999}.devic-state-dropdown-portal{animation:devic-dropdownSlide .15s ease-out;background:#fff;border:1px solid #e8e8e8;border-radius:8px;box-shadow:0 6px 16px rgba(0,0,0,.08),0 3px 6px rgba(0,0,0,.06);min-width:180px;padding:4px 0;z-index:99999}.devic-state-modal-overlay{align-items:center;animation:devic-fadeIn .2s ease;background:rgba(0,0,0,.45);display:flex;inset:0;justify-content:center;position:fixed;z-index:1050}@keyframes devic-fadeIn{0%{opacity:0}to{opacity:1}}.devic-state-modal{animation:devic-modalSlide .2s ease-out;background:#fff;border-radius:8px;box-shadow:0 6px 16px rgba(0,0,0,.08);display:flex;flex-direction:column;max-height:80vh;max-width:520px;width:90%}@keyframes devic-modalSlide{0%{opacity:0;transform:translateY(-16px)}to{opacity:1;transform:translateY(0)}}.devic-state-modal-header{align-items:center;border-bottom:1px solid #f0f0f0;display:flex;justify-content:space-between;padding:16px 20px}.devic-state-modal-title{align-items:center;display:flex;font-size:16px;font-weight:600;gap:8px;margin:0}.devic-state-modal-close{align-items:center;background:none;border:none;border-radius:4px;color:#999;cursor:pointer;display:flex;padding:4px}.devic-state-modal-close:hover{background:#f5f5f5;color:#333}.devic-state-modal-body{flex:1;overflow-y:auto;padding:20px}.devic-state-modal-footer{border-top:1px solid #f0f0f0;display:flex;gap:8px;justify-content:flex-end;padding:12px 20px}.devic-state-btn{align-items:center;background:#fff;border:1px solid #d9d9d9;border-radius:6px;color:#333;cursor:pointer;display:inline-flex;font-family:inherit;font-size:14px;font-weight:500;gap:6px;justify-content:center;padding:6px 16px;transition:all .2s}.devic-state-btn:hover{border-color:#1677ff;color:#1677ff}.devic-state-btn-primary{background:#1677ff;border-color:#1677ff;color:#fff}.devic-state-btn-primary:hover{background:#4096ff;border-color:#4096ff;color:#fff}.devic-state-btn-danger{background:#ff4d4f;border-color:#ff4d4f;color:#fff}.devic-state-btn-danger:hover{background:#ff7875;border-color:#ff7875;color:#fff}.devic-state-btn-success{background:#52c41a;border-color:#52c41a;color:#fff}.devic-state-btn-success:hover{background:#73d13d;border-color:#73d13d;color:#fff}.devic-state-btn:disabled{cursor:not-allowed;opacity:.5}.devic-explain-content{border:1px solid #e8e8e8;border-radius:8px;font-family:SFMono-Regular,Consolas,monospace;font-size:13px;line-height:1.6;max-height:300px;min-height:150px;overflow-y:auto;padding:12px;white-space:pre-wrap}.devic-typing-cursor{animation:devic-blink 1s step-end infinite}@keyframes devic-blink{0%,to{opacity:1}50%{opacity:0}}.devic-approval-layout{display:flex;gap:16px}.devic-approval-request{background:#fafafa;border:1px solid #e8e8e8;border-radius:8px;flex:1;font-size:13px;line-height:1.6;max-height:250px;overflow-y:auto;padding:12px}.devic-approval-actions{display:flex;flex:1;flex-direction:column;gap:12px}.devic-approval-textarea{border:1px solid #d9d9d9;border-radius:6px;box-sizing:border-box;font-family:inherit;font-size:13px;min-height:80px;outline:none;padding:8px 12px;resize:vertical;width:100%}.devic-approval-textarea:focus{border-color:#1677ff}.devic-approval-buttons{display:flex;flex-direction:column;gap:8px}.devic-completion-select{background:#fff;border:1px solid #d9d9d9;border-radius:6px;cursor:pointer;font-family:inherit;font-size:14px;outline:none;padding:8px 12px;width:100%}.devic-completion-select:focus{border-color:#1677ff}.devic-state-loading{align-items:center;display:flex;justify-content:center;padding:24px}.devic-state-loading-spinner{animation:devic-state-spin .8s linear infinite;border:2px solid #f0f0f0;border-radius:50%;border-top-color:#1677ff;height:24px;width:24px}.devic-state-warning{align-items:flex-start;color:#cf1322;display:flex;font-size:13px;font-weight:500;gap:6px;margin-top:8px}.devic-message-actions{align-items:center;display:flex;gap:4px;opacity:0;transition:opacity .15s ease}.devic-message-actions:focus-within,.devic-message:hover .devic-message-actions{opacity:1}.devic-message-actions:has(.devic-action-btn--active){opacity:1}.devic-action-btn{align-items:center;background:transparent;border:none;border-radius:var(--devic-radius-sm,6px);color:var(--devic-text-muted,#94a3b8);cursor:pointer;display:flex;height:28px;justify-content:center;padding:0;transition:all .15s ease;width:28px}.devic-action-btn:hover:not(:disabled){background:var(--devic-bg-secondary,#f8fafc);color:var(--devic-text-secondary,#64748b)}.devic-action-btn:disabled{cursor:not-allowed;opacity:.5}.devic-action-btn--active{color:var(--devic-primary,#3b82f6)}.devic-action-btn--active.devic-action-btn--positive{color:#22c55e}.devic-action-btn--active.devic-action-btn--negative{color:#ef4444}.devic-feedback-overlay{align-items:center;animation:devic-feedback-fade-in .15s ease;background:rgba(0,0,0,.4);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:10001}@keyframes devic-feedback-fade-in{0%{opacity:0}to{opacity:1}}.devic-feedback-modal{animation:devic-feedback-slide-up .2s ease;background:var(--devic-bg,#fff);border-radius:var(--devic-radius,12px);box-shadow:0 20px 60px rgba(0,0,0,.2);margin:16px;max-width:400px;width:100%}@keyframes devic-feedback-slide-up{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.devic-feedback-modal-header{align-items:center;border-bottom:1px solid var(--devic-border,#e2e8f0);display:flex;gap:10px;padding:16px 16px 12px}.devic-feedback-modal-icon{align-items:center;background:var(--devic-bg-secondary,#f8fafc);border-radius:8px;color:var(--devic-text,#1e293b);display:flex;height:32px;justify-content:center;width:32px}.devic-feedback-modal-title{color:var(--devic-text,#1e293b);flex:1;font-size:15px;font-weight:600}.devic-feedback-modal-close{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--devic-text-muted,#94a3b8);cursor:pointer;display:flex;height:28px;justify-content:center;padding:0;transition:all .15s ease;width:28px}.devic-feedback-modal-close:hover{background:var(--devic-bg-secondary,#f8fafc);color:var(--devic-text-secondary,#64748b)}.devic-feedback-textarea{background:transparent;border:none;border-bottom:1px solid var(--devic-border,#e2e8f0);box-sizing:border-box;color:var(--devic-text,#1e293b);display:block;font-family:inherit;font-size:14px;line-height:1.5;padding:12px 16px;resize:none;width:100%}.devic-feedback-textarea:focus{outline:none}.devic-feedback-textarea::placeholder{color:var(--devic-text-muted,#94a3b8)}.devic-feedback-modal-actions{display:flex;gap:8px;justify-content:flex-end;padding:12px 16px}.devic-feedback-btn{border:none;border-radius:var(--devic-radius-sm,6px);cursor:pointer;font-family:inherit;font-size:14px;font-weight:500;padding:8px 16px;transition:all .15s ease}.devic-feedback-btn:disabled{cursor:not-allowed;opacity:.6}.devic-feedback-btn--secondary{background:var(--devic-bg-secondary,#f8fafc);color:var(--devic-text-secondary,#64748b)}.devic-feedback-btn--secondary:hover:not(:disabled){background:var(--devic-border,#e2e8f0)}.devic-feedback-btn--primary{background:var(--devic-primary,#3b82f6);color:#fff}.devic-feedback-btn--primary:hover:not(:disabled){background:var(--devic-primary-hover,#2563eb)}.devic-cmd-result-actions{border-top:1px solid var(--devic-cmd-border,var(--devic-border,#e5e7eb));margin-top:8px;padding-top:8px}.devic-cmd-result-actions .devic-message-actions{opacity:1;padding-left:10px}.devic-cmd-result-actions .devic-action-btn{opacity:.7}.devic-cmd-result-actions .devic-action-btn--active,.devic-cmd-result-actions .devic-action-btn:hover{opacity:1}.devic-cm-overlay{align-items:center;background:rgba(0,0,0,.45);display:flex;inset:0;justify-content:center;position:fixed;z-index:10000}.devic-cm-modal{background:var(--devic-bg,#fff);border-radius:12px;box-shadow:0 12px 40px rgba(0,0,0,.22);color:var(--devic-text,#333);display:flex;flex-direction:column;font-size:13px;max-height:min(640px,calc(100vh - 64px));width:min(560px,calc(100vw - 32px))}.devic-cm-header{align-items:center;border-bottom:1px solid var(--devic-border,#e8e8e8);display:flex;justify-content:space-between;padding:14px 16px}.devic-cm-title{align-items:center;display:flex;font-size:15px;font-weight:600;gap:8px;margin:0}.devic-cm-title svg{color:var(--devic-recall-accent,#722ed1)}.devic-cm-close{background:transparent;border:none;border-radius:6px;color:var(--devic-text-muted,#999);cursor:pointer;font-size:20px;line-height:1;padding:2px 6px}.devic-cm-close:hover{background:var(--devic-bg-secondary,#f5f5f5);color:var(--devic-text,#333)}.devic-cm-body{display:flex;flex-direction:column;gap:12px;overflow-y:auto;padding:12px 16px}.devic-cm-error{background:rgba(255,77,79,.08);border:1px solid rgba(255,77,79,.4);border-radius:8px;color:#cf1322;font-size:12px;padding:8px 10px}.devic-cm-empty,.devic-cm-loading{color:var(--devic-text-muted,#999);padding:24px 8px;text-align:center}.devic-cm-section-title{color:var(--devic-text-muted,#999);font-size:10px;font-weight:700;letter-spacing:.6px;margin-bottom:6px;text-transform:uppercase}.devic-cm-entry{align-items:flex-start;border:1px solid var(--devic-border,#e8e8e8);border-radius:8px;display:flex;gap:8px;justify-content:space-between;margin-bottom:6px;padding:8px 10px}.devic-cm-entry-content{align-items:flex-start;display:flex;flex:1;gap:6px;white-space:pre-wrap;word-break:break-word}.devic-cm-pin{color:var(--devic-recall-accent,#722ed1);flex-shrink:0;margin-top:2px}.devic-cm-entry-actions{display:flex;flex-shrink:0;gap:4px}.devic-cm-editor{display:flex;flex:1;flex-direction:column;gap:6px}.devic-cm-textarea{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#d9d9d9);border-radius:8px;box-sizing:border-box;color:inherit;font:inherit;min-height:64px;padding:8px 10px;resize:vertical;width:100%}.devic-cm-textarea:focus{border-color:var(--devic-recall-accent,#722ed1);outline:none}.devic-cm-composer,.devic-cm-editor-actions{display:flex;gap:6px}.devic-cm-composer{flex-direction:column}.devic-cm-composer-row{display:flex;gap:6px}.devic-cm-select{color:inherit;padding:4px 8px}.devic-cm-btn,.devic-cm-select{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#d9d9d9);border-radius:6px;font:inherit}.devic-cm-btn{color:var(--devic-text,#333);cursor:pointer;font-size:12px;padding:5px 12px}.devic-cm-btn:hover:not(:disabled){border-color:var(--devic-recall-accent,#722ed1);color:var(--devic-recall-accent,#722ed1)}.devic-cm-btn:disabled{cursor:not-allowed;opacity:.5}.devic-cm-btn-primary{background:var(--devic-recall-accent,#722ed1);border-color:var(--devic-recall-accent,#722ed1);color:#fff}.devic-cm-btn-primary:hover:not(:disabled){color:#fff;opacity:.9}.devic-cm-btn-small{font-size:11px;padding:2px 8px}.devic-cm-btn-danger:hover:not(:disabled){border-color:#ff4d4f;color:#ff4d4f}.devic-cm-footer{border-top:1px solid var(--devic-border,#e8e8e8);color:var(--devic-text-muted,#999);font-size:11px;padding:10px 16px}.devic-int-overlay{align-items:center;background:rgba(0,0,0,.45);display:flex;inset:0;justify-content:center;position:fixed;z-index:10000}.devic-int-panel{background:var(--devic-bg,#fff);color:var(--devic-text,#333);display:flex;flex-direction:column;font-size:13px;min-width:0;width:100%}.devic-int-modal{border-radius:12px;box-shadow:0 12px 40px rgba(0,0,0,.22);max-height:min(660px,calc(100vh - 64px));width:min(620px,calc(100vw - 32px))}.devic-int-header{align-items:center;border-bottom:1px solid var(--devic-border,#e8e8e8);display:flex;justify-content:space-between;padding:14px 16px}.devic-int-title{align-items:center;display:flex;font-size:15px;font-weight:600;gap:8px;margin:0}.devic-int-title svg{color:var(--devic-primary,#1677ff)}.devic-int-close{background:transparent;border:none;border-radius:6px;color:var(--devic-text-muted,#999);cursor:pointer;font-size:20px;line-height:1;padding:2px 6px}.devic-int-close:hover{background:var(--devic-bg-secondary,#f5f5f5);color:var(--devic-text,#333)}.devic-int-search{align-items:center;background:var(--devic-bg-secondary,#f7f7f7);border:1px solid var(--devic-border,#e8e8e8);border-radius:8px;color:var(--devic-text-muted,#999);display:flex;gap:8px;margin:12px 16px 0;padding:7px 10px}.devic-int-search:focus-within{border-color:var(--devic-primary,#1677ff)}.devic-int-search input{-webkit-appearance:none;appearance:none;background:transparent;border:none;color:var(--devic-text,#333);flex:1;font:inherit;font-size:13px;min-width:0;outline:none}.devic-int-search input::-webkit-search-cancel-button{-webkit-appearance:none}.devic-int-search input::placeholder{color:var(--devic-text-muted,#999)}.devic-int-body{display:flex;flex-direction:column;gap:10px;overflow-y:auto;padding:12px 16px}.devic-int-error{background:rgba(255,77,79,.08);border:1px solid rgba(255,77,79,.4);border-radius:8px;color:#ff4d4f;font-size:12px;padding:8px 10px}.devic-int-notice{background:rgba(250,173,20,.1);border:1px solid rgba(250,173,20,.45);border-radius:8px;color:inherit;font-size:12px;padding:8px 10px}.devic-int-notice a{color:var(--devic-primary,#1677ff)}.devic-int-empty,.devic-int-loading{color:var(--devic-text-muted,#999);padding:24px 8px;text-align:center}.devic-int-grid{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(158px,1fr))}.devic-int-card{border:1px solid var(--devic-border,#e8e8e8);border-radius:10px;display:flex;flex-direction:column;gap:6px;padding:12px}.devic-int-card[data-state=connected]{border-color:rgba(82,196,26,.45)}.devic-int-card[data-state=reconnect]{border-color:rgba(250,173,20,.5)}.devic-int-card-head{align-items:center;display:flex;gap:8px;justify-content:space-between}.devic-int-logo{background:var(--devic-bg-secondary,#f5f5f5);border-radius:8px;flex-shrink:0;height:32px;object-fit:contain;width:32px}.devic-int-logo-fallback{align-items:center;color:var(--devic-text-muted,#999);display:flex;font-weight:600;justify-content:center}.devic-int-name{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-state{align-items:center;color:var(--devic-text-muted,#999);display:inline-flex;font-size:11px;gap:4px;white-space:nowrap}.devic-int-card[data-state=connected] .devic-int-state{color:#52c41a}.devic-int-card[data-state=reconnect] .devic-int-state{color:#faad14}.devic-int-description{-webkit-line-clamp:2;-webkit-box-orient:vertical;color:var(--devic-text-muted,#999);display:-webkit-box;font-size:12px;line-height:1.4;overflow:hidden}.devic-int-accounts{display:flex;flex-direction:column;gap:4px;list-style:none;margin:0;padding:0}.devic-int-account{align-items:center;background:var(--devic-bg-secondary,#f7f7f7);border-radius:6px;display:flex;font-size:11px;gap:6px;padding:3px 6px}.devic-int-account-label{color:var(--devic-text-muted,#999);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-account-warn{color:#faad14}.devic-int-dot{background:#faad14;border-radius:50%;flex-shrink:0;height:6px;width:6px}.devic-int-dot[data-ok=true]{background:#52c41a}.devic-int-dot[data-off=true]{background:var(--devic-text-muted,#bbb)}.devic-int-unlink{background:transparent;border:none;border-radius:4px;color:var(--devic-text-muted,#999);cursor:pointer;flex-shrink:0;font-size:14px;line-height:1;padding:0 2px}.devic-int-unlink:hover:not(:disabled){color:#ff4d4f}.devic-int-unlink:disabled{cursor:not-allowed;opacity:.4}.devic-int-btn{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#d9d9d9);border-radius:6px;color:var(--devic-text,#333);cursor:pointer;flex-shrink:0;font:inherit;font-size:12px;padding:5px 12px}.devic-int-btn:hover:not(:disabled){border-color:var(--devic-primary,#1677ff);color:var(--devic-primary,#1677ff)}.devic-int-btn:disabled{cursor:not-allowed;opacity:.5}.devic-int-btn-block{margin-top:auto;text-align:center;width:100%}.devic-int-btn-primary{background:var(--devic-primary,#1677ff);border-color:var(--devic-primary,#1677ff);color:#fff}.devic-int-btn-primary:hover:not(:disabled){color:#fff;opacity:.9}.devic-int-btn-small{font-size:11px;padding:2px 8px}.devic-int-overlay-stacked{background:rgba(0,0,0,.5);z-index:10001}.devic-int-connect-dialog{background:var(--devic-bg,#fff);border-radius:12px;box-shadow:0 12px 40px rgba(0,0,0,.3);color:var(--devic-text,#333);display:flex;flex-direction:column;font-size:13px;max-height:calc(100vh - 64px);width:min(440px,calc(100vw - 32px))}.devic-int-connect-header{align-items:flex-start;border-bottom:1px solid var(--devic-border,#e8e8e8);display:flex;gap:10px;padding:14px 16px}.devic-int-connect-heading{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.devic-int-connect-heading strong{font-size:14px}.devic-int-connect-heading span{color:var(--devic-text-muted,#999);font-size:11px;line-height:1.4}.devic-int-connect-body{display:flex;flex-direction:column;gap:14px;overflow-y:auto;padding:16px}.devic-int-connect-field{display:flex;flex-direction:column;gap:5px}.devic-int-connect-label{color:var(--devic-text,#333);font-size:12px;font-weight:500}.devic-int-connect-label em{color:var(--devic-text-muted,#999);font-style:normal;font-weight:400}.devic-int-connect-field input,.devic-int-connect-field select{background:var(--devic-bg-secondary,#fafafa);border:1px solid var(--devic-border,#d9d9d9);border-radius:8px;box-sizing:border-box;color:var(--devic-text,#333);font:inherit;font-size:13px;height:36px;line-height:normal;padding:0 10px;transition:border-color .15s,box-shadow .15s;width:100%}.devic-int-connect-field input::placeholder{color:var(--devic-text-muted,#bbb)}.devic-int-connect-field input:focus,.devic-int-connect-field select:focus{border-color:var(--devic-primary,#1677ff);box-shadow:0 0 0 3px color-mix(in srgb,var(--devic-primary,#1677ff) 18%,transparent);outline:none}.devic-int-connect-field input[data-invalid]{border-color:#ff4d4f}.devic-int-connect-field input[data-invalid]:focus{box-shadow:0 0 0 3px rgba(255,77,79,.18)}.devic-int-connect-hint{color:var(--devic-text-muted,#999);font-size:11px;line-height:1.45}.devic-int-connect-guide{color:var(--devic-primary,#1677ff);font-size:12px}.devic-int-connect-actions{justify-content:flex-end;padding:12px 16px}.devic-int-connect-actions,.devic-int-footer{border-top:1px solid var(--devic-border,#e8e8e8);display:flex;gap:8px}.devic-int-footer{align-items:center;color:var(--devic-text-muted,#999);font-size:11px;justify-content:space-between;padding:10px 16px}.devic-int-launcher{align-items:center;background:none;border:none;border-radius:var(--devic-radius-sm,6px);cursor:pointer;display:inline-flex;padding:4px 5px;transition:background var(--devic-transition,.2s)}.devic-int-launcher:hover{background:var(--devic-bg-secondary,#f5f5f5)}.devic-int-launcher-item{align-items:center;background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#e8e8e8);border-radius:6px;box-sizing:border-box;display:flex;flex-shrink:0;height:22px;justify-content:center;margin-left:-4px;overflow:hidden;width:22px}.devic-int-launcher-item:first-child{margin-left:0}.devic-int-launcher-item[data-connected=false]{opacity:.55}.devic-int-logo.devic-int-launcher-logo{background:transparent;border-radius:3px;font-size:11px;height:16px;width:16px}.devic-int-launcher-initial{align-items:center;display:inline-flex;font-size:10px;font-weight:600;justify-content:center;line-height:1}.devic-int-launcher-more{background:var(--devic-bg-secondary,#f0f0f0);color:var(--devic-text-muted,#999);font-size:10px;font-weight:600}.devic-int-launcher-loading{cursor:default}.devic-int-launcher-loading:hover{background:none}.devic-int-launcher-skeleton{animation:devic-int-pulse 1.4s ease-in-out infinite;background:var(--devic-bg-secondary,#f0f0f0)}.devic-int-launcher-skeleton:nth-child(2){animation-delay:.16s}.devic-int-launcher-skeleton:nth-child(3){animation-delay:.32s}.devic-int-launcher-skeleton:nth-child(n+4){animation-delay:.48s}@keyframes devic-int-pulse{0%,to{opacity:.35}50%{opacity:.75}}@media (prefers-reduced-motion:reduce){.devic-int-launcher-skeleton{animation:none;opacity:.5}}.devic-int-launcher[data-dark=true] .devic-int-launcher-item{background:hsla(0,0%,100%,.92);border-color:hsla(0,0%,100%,.16)}.devic-int-launcher[data-dark=true] .devic-int-launcher-more{background:var(--devic-bg-secondary,#f0f0f0);border-color:var(--devic-border,#e8e8e8)}.devic-int-panel[data-dark=true] .devic-int-card .devic-int-logo{background:hsla(0,0%,100%,.92)}.devic-int-panel[data-dark=true] .devic-int-card .devic-int-logo-fallback{color:#595959}.devic-int-hint{align-items:center;background:var(--devic-bg-secondary,#f7f7f7);border:1px solid var(--devic-border,#e8e8e8);border-radius:12px;display:flex;gap:4px;margin:0 0 8px;padding:6px 8px 6px 12px;transition:opacity .2s ease,transform .2s ease}.devic-int-hint[data-leaving=true]{opacity:0;pointer-events:none;transform:translateY(-4px)}.devic-int-hint-main{align-items:center;background:none;border:none;border-radius:8px;color:inherit;cursor:pointer;display:flex;flex:1;font:inherit;gap:10px;justify-content:space-between;min-width:0;padding:2px}.devic-int-hint-label{color:var(--devic-text-muted,#8c8c8c);font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-hint-main:hover .devic-int-hint-label{color:var(--devic-text,#333)}.devic-int-hint-logos{gap:6px}.devic-int-hint-item,.devic-int-hint-logos{align-items:center;display:flex;flex-shrink:0}.devic-int-hint-item{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#e8e8e8);border-radius:6px;box-sizing:border-box;height:24px;justify-content:center;overflow:hidden;width:24px}.devic-int-hint-item[data-connected=false]{opacity:.6}.devic-int-logo.devic-int-hint-logo{background:transparent;border-radius:3px;font-size:11px;height:17px;width:17px}.devic-int-hint-more{background:var(--devic-bg-secondary,#f0f0f0);color:var(--devic-text-muted,#999);font-size:10px;font-weight:600}.devic-int-hint-close{background:transparent;border:none;border-radius:6px;color:var(--devic-text-muted,#999);cursor:pointer;flex-shrink:0;font-size:18px;line-height:1;padding:2px 6px}.devic-int-hint-close:hover{background:var(--devic-bg,#fff);color:var(--devic-text,#333)}.devic-int-hint[data-dark=true] .devic-int-hint-item{background:hsla(0,0%,100%,.92);border-color:hsla(0,0%,100%,.16)}.devic-int-hint[data-dark=true] .devic-int-hint-more{background:var(--devic-bg,#1f1f1f);border-color:var(--devic-border,#303030)}.devic-int-hint-ghost{align-items:center;display:flex;gap:6px;pointer-events:none;position:fixed;z-index:10001}.devic-int-toggle{display:inline-flex;flex-shrink:0;position:relative}.devic-int-toggle-btn{position:relative}.devic-int-toggle-badge{background:var(--devic-primary,#1677ff);border-radius:7px;box-sizing:border-box;color:#fff;font-size:9px;font-weight:600;height:14px;line-height:14px;min-width:14px;padding:0 3px;position:absolute;right:-2px;text-align:center;top:-2px}.devic-int-toggle-popover{background:var(--devic-bg,#fff);border:1px solid var(--devic-border,#e8e8e8);border-radius:var(--devic-radius,10px);bottom:calc(100% + 8px);box-shadow:0 8px 24px rgba(0,0,0,.14);box-sizing:border-box;color:var(--devic-text,#333);left:0;max-height:320px;overflow-y:auto;padding:10px;position:absolute;width:260px;z-index:10002}.devic-int-toggle-head{border-bottom:1px solid var(--devic-border,#e8e8e8);display:flex;flex-direction:column;gap:2px;margin-bottom:6px;padding:2px 2px 8px}.devic-int-toggle-head strong{font-size:13px}.devic-int-toggle-head span{color:var(--devic-text-muted,#999);font-size:11px;line-height:1.4}.devic-int-toggle-list{list-style:none;margin:0;padding:0}.devic-int-toggle-row{align-items:center;border-radius:var(--devic-radius-sm,6px);cursor:pointer;display:flex;gap:8px;justify-content:space-between;padding:6px 4px}.devic-int-toggle-row:hover{background:var(--devic-bg-secondary,#f5f5f5)}.devic-int-toggle-app{align-items:center;display:flex;gap:8px;min-width:0}.devic-int-toggle-app .devic-int-logo{border-radius:4px;flex-shrink:0;height:18px;object-fit:contain;width:18px}.devic-int-toggle-name{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-toggle-group{border-top:1px solid var(--devic-border,hsla(0,0%,50%,.22));font-size:10px;letter-spacing:.06em;margin-top:6px;opacity:.55;padding:10px 4px 4px;text-transform:uppercase}.devic-int-toggle-mcp-logo{border-radius:4px;flex-shrink:0;height:18px;object-fit:contain;width:18px}.devic-int-toggle-mcp-fallback{align-items:center;background:var(--devic-surface-2,hsla(0,0%,50%,.18));color:inherit;display:inline-flex;font-size:10px;font-weight:600;justify-content:center}.devic-int-toggle-switch{appearance:none;-webkit-appearance:none;background:var(--devic-border,#d9d9d9);border-radius:9px;cursor:pointer;flex-shrink:0;height:18px;margin:0;position:relative;transition:background var(--devic-transition,.2s);width:32px}.devic-int-toggle-switch:after{background:#fff;border-radius:50%;content:"";height:14px;left:2px;position:absolute;top:2px;transition:transform var(--devic-transition,.2s);width:14px}.devic-int-toggle-switch:checked{background:var(--devic-primary,#1677ff)}.devic-int-toggle-switch:checked:after{transform:translateX(14px)}.devic-int-toggle-switch:focus-visible{outline:2px solid var(--devic-primary,#1677ff);outline-offset:2px}.devic-int-toggle-manage{background:none;border:none;border-radius:0 0 var(--devic-radius-sm,6px) var(--devic-radius-sm,6px);border-top:1px solid var(--devic-border,#e8e8e8);color:var(--devic-primary,#1677ff);cursor:pointer;font:inherit;font-size:12px;margin-top:6px;padding:6px;width:100%}.devic-int-toggle-manage:hover{background:var(--devic-bg-secondary,#f5f5f5)}.devic-int-toggle[data-dark=true] .devic-int-toggle-popover{box-shadow:0 8px 24px rgba(0,0,0,.45)}.devic-int-toggle[data-dark=true] .devic-int-toggle-switch:not(:checked){background:var(--devic-border,#434343)}.devic-int-body-secondary{overflow:visible;padding-top:0}.devic-int-mcp-section{border-top:1px solid var(--devic-border,#e8e8e8);display:flex;flex-direction:column;gap:10px;padding-top:12px}.devic-int-mcp-heading h4{font-size:13px;font-weight:600;margin:0}.devic-int-mcp-heading span{color:var(--devic-text-muted,#999);display:block;font-size:12px;margin-top:2px}.devic-int-mcp-logo{border-radius:8px;flex-shrink:0;height:32px;object-fit:contain;width:32px}.devic-int-mcp-logo-fallback{align-items:center;background:var(--devic-primary,#1677ff);color:#fff;display:inline-flex;font-size:14px;font-weight:600;justify-content:center}.devic-int-mcp-note{color:var(--devic-text-muted,#999);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-int-mcp-note-warn{color:#faad14}.devic-int-mcp-add{align-self:flex-start;border-style:dashed}.devic-int-mcp-remove{border-color:rgba(255,77,79,.35);color:#ff4d4f}.devic-int-mcp-advanced{display:flex;flex-direction:column;gap:8px}.devic-int-mcp-disclosure{align-self:flex-start;font:inherit;font-size:12px}.devic-int-mcp-copy,.devic-int-mcp-disclosure{background:none;border:none;color:var(--devic-primary,#1677ff);cursor:pointer;padding:0}.devic-int-mcp-copy{font:inherit;font-size:inherit}.devic-int-toggle-btn-loading{animation:devic-int-toggle-pulse 1.4s ease-in-out infinite;cursor:default;opacity:.35}@keyframes devic-int-toggle-pulse{0%,to{opacity:.25}50%{opacity:.5}}.devic-chat-drawer{--devic-primary:#1890ff;--devic-primary-hover:#40a9ff;--devic-primary-light:#e6f7ff;--devic-bg:#fff;--devic-bg-secondary:#f5f5f5;--devic-text:#333;--devic-text-secondary:#666;--devic-text-muted:#999;--devic-border:#e8e8e8;--devic-shadow:0 4px 12px rgba(0,0,0,.15);--devic-error:#ff4d4f;--devic-queued-accent:var(--devic-text-muted);--devic-queued-bubble-bg:transparent;--devic-queued-border:var(--devic-border);--devic-radius:8px;--devic-radius-sm:4px;--devic-radius-lg:16px;--devic-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--devic-transition:0.3s ease;background:var(--devic-bg);bottom:0;box-shadow:var(--devic-shadow);color:var(--devic-text);display:flex;flex-direction:column;font-family:var(--devic-font-family);font-size:14px;line-height:1.5;position:fixed;top:0;transition:transform var(--devic-transition)}.devic-chat-drawer[data-position=right]{right:0;transform:translateX(100%)}.devic-chat-drawer[data-position=left]{left:0;transform:translateX(-100%)}.devic-chat-drawer[data-open=true]{transform:translateX(0)}.devic-drawer-overlay{background:rgba(0,0,0,.3);inset:0;opacity:0;position:fixed;transition:opacity var(--devic-transition),visibility var(--devic-transition);visibility:hidden}.devic-drawer-overlay[data-open=true]{opacity:1;visibility:visible}.devic-drawer-header{align-items:center;border-bottom:1px solid var(--devic-border);display:flex;flex-shrink:0;justify-content:space-between;padding:16px}.devic-drawer-avatar{border-radius:50%;flex-shrink:0;height:28px;object-fit:cover;width:28px}.devic-drawer-title{flex-shrink:1;font-size:16px;font-weight:600;margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-drawer-close{background:none;border:none;border-radius:var(--devic-radius-sm);color:var(--devic-text-secondary);cursor:pointer;padding:8px;transition:background var(--devic-transition),color var(--devic-transition)}.devic-drawer-close:hover{background:var(--devic-bg-secondary);color:var(--devic-text)}.devic-messages-container{display:flex;flex:1;flex-direction:column;gap:12px;overflow-y:auto;padding:16px}.devic-welcome{color:var(--devic-text-secondary);padding:24px 16px;text-align:center}.devic-welcome-text{font-size:16px;margin-bottom:16px}.devic-suggested-messages{display:flex;flex-wrap:wrap;gap:8px;justify-content:center}.devic-suggested-btn{background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:var(--devic-radius-lg);color:var(--devic-text);cursor:pointer;font-size:13px;padding:8px 16px;transition:border-color var(--devic-transition),background var(--devic-transition)}.devic-suggested-btn:hover{background:var(--devic-primary-light);border-color:var(--devic-primary)}.devic-message{display:flex;flex-direction:column;max-width:85%}.devic-message[data-role=user]{align-self:flex-end}.devic-message[data-role=assistant],.devic-message[data-role=tool]{align-self:flex-start}.devic-message-bubble{word-wrap:break-word;border-radius:var(--devic-radius);padding:10px 14px}.devic-message[data-role=user] .devic-message-bubble{background:var(--devic-user-bubble,var(--devic-primary));border-bottom-right-radius:var(--devic-radius-sm);color:var(--devic-user-bubble-text,#fff)}.devic-message[data-role=assistant] .devic-message-bubble{background:var(--devic-assistant-bubble,var(--devic-bg-secondary));border-bottom-left-radius:var(--devic-radius-sm);color:var(--devic-assistant-bubble-text,var(--devic-text))}.devic-message[data-role=tool] .devic-message-bubble{background:var(--devic-primary-light);border:1px solid var(--devic-primary);color:var(--devic-text);font-size:12px}.devic-message-footer{align-items:center;display:flex;gap:8px;justify-content:space-between;margin-top:4px}.devic-message-time{color:var(--devic-text-muted);font-size:11px}.devic-message[data-role=user] .devic-message-footer{justify-content:flex-end}.devic-message[data-role=user] .devic-message-time{text-align:right}.devic-message[data-queued=true] .devic-message-bubble{background:var(--devic-queued-bubble-bg);border:1px dashed var(--devic-queued-border);color:var(--devic-text);opacity:.85}.devic-message-queued-label{align-items:center;color:var(--devic-queued-accent);display:inline-flex;font-size:11px;gap:4px}.devic-message-files{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}.devic-message-file{align-items:center;background:hsla(0,0%,100%,.2);border-radius:var(--devic-radius-sm);display:flex;font-size:12px;gap:6px;padding:6px 10px}.devic-recall{align-self:flex-start;background:var(--devic-recall-bg,rgba(114,46,209,.06));border:1px solid var(--devic-recall-border,rgba(114,46,209,.3));border-radius:var(--devic-radius-sm,8px);color:var(--devic-text-secondary);flex-shrink:0;font-size:12px;margin:2px 0 8px;max-width:88%;overflow:hidden}.devic-recall-header{align-items:center;background:transparent;border:none;color:inherit;cursor:pointer;display:flex;font:inherit;gap:6px;padding:6px 10px;text-align:left;width:100%}.devic-recall-icon{color:var(--devic-recall-accent,#722ed1);flex-shrink:0}.devic-recall-title{color:var(--devic-text);font-weight:600;white-space:nowrap}.devic-recall-summary{opacity:.75;white-space:nowrap}.devic-recall-spacer{flex:1}.devic-recall-source{border:1px solid var(--devic-recall-border,rgba(114,46,209,.3));border-radius:4px;color:var(--devic-recall-accent,#722ed1);font-size:10px;line-height:16px;padding:0 6px;white-space:nowrap}.devic-recall-chevron{flex-shrink:0;opacity:.6;transition:transform .15s ease}.devic-recall-body{display:flex;flex-direction:column;gap:8px;padding:2px 10px 10px}.devic-recall-facts{display:flex;flex-direction:column;gap:6px}.devic-recall-fact{color:var(--devic-text);display:flex;flex-direction:column;gap:2px}.devic-recall-fact-meta{color:var(--devic-text-muted);font-size:10px}.devic-recall-entities{display:flex;flex-wrap:wrap;gap:4px}.devic-recall-entity{background:var(--devic-bg);border:1px solid var(--devic-border,#d9d9d9);border-radius:4px;color:var(--devic-text-secondary);font-size:10px;line-height:18px;padding:0 6px}.devic-recall-entity-type{opacity:.55}.devic-recall-turns{display:flex;flex-direction:column;gap:3px}.devic-recall-turns-title{font-size:10px;font-weight:600;letter-spacing:.4px;opacity:.7;text-transform:uppercase}.devic-recall-turn{font-size:11px;opacity:.85}.devic-recall-turn-role{font-weight:600}.devic-loading{align-self:flex-start;display:flex;gap:4px;padding:10px 14px}.devic-loading-dot{animation:devic-bounce 1.4s ease-in-out infinite both;background:var(--devic-text-muted);border-radius:50%;height:8px;width:8px}.devic-loading-dot:first-child{animation-delay:-.32s}.devic-loading-dot:nth-child(2){animation-delay:-.16s}@keyframes devic-bounce{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}.devic-tool-group{align-self:flex-start;display:flex;flex-direction:column;gap:2px;max-width:85%}.devic-tool-activity{align-items:flex-start;animation:devic-slideUp .3s ease-out;display:flex;gap:8px;padding:4px 0}.devic-tool-activity-icon{align-items:center;color:var(--devic-text-muted);display:flex;flex-shrink:0;margin-top:1px}.devic-tool-activity--active .devic-tool-activity-icon{color:var(--devic-primary)}.devic-tool-activity-text{color:var(--devic-text-secondary);font-size:13px;line-height:1.4}.devic-glow-text{animation:devic-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes devic-pulse{0%,to{opacity:1}50%{opacity:.5}}.devic-spinner{animation:devic-spin 1s linear infinite}@keyframes devic-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes devic-slideUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.devic-tool-collapse-btn{align-items:center;background:none;border:none;color:var(--devic-text-muted);cursor:pointer;display:flex;font-family:var(--devic-font-family);font-size:12px;gap:6px;padding:4px 0;transition:color .2s ease}.devic-tool-collapse-btn:hover{color:var(--devic-primary)}.devic-tool-group-items{animation:devic-expandItems .4s ease-out;overflow:hidden}.devic-tool-group-items[data-expanded=true]{max-height:500px}@keyframes devic-expandItems{0%{max-height:0;opacity:0}to{max-height:500px;opacity:1}}.devic-input-area{border-top:1px solid var(--devic-border);flex-shrink:0;padding:16px}.devic-input-wrapper{--devic-input-row-height:28px;--devic-input-line-height:20px;align-items:flex-end;background:var(--devic-bg-secondary);border-radius:var(--devic-radius);display:flex;gap:8px;padding:8px 12px}.devic-input{background:none;border:none;box-sizing:border-box;color:var(--devic-text);flex:1;font-family:inherit;font-size:14px;line-height:var(--devic-input-line-height);max-height:120px;min-height:var(--devic-input-row-height);outline:none;padding:calc((var(--devic-input-row-height) - var(--devic-input-line-height))/2) 0;resize:none}.devic-input::placeholder{color:var(--devic-text-muted)}.devic-input-btn{align-items:center;background:none;border:none;border-radius:var(--devic-radius-sm);box-sizing:border-box;color:var(--devic-text-secondary);cursor:pointer;display:inline-flex;flex-shrink:0;justify-content:center;min-height:var(--devic-input-row-height,28px);padding:4px;transition:color var(--devic-transition)}.devic-input-btn:hover:not(:disabled){color:var(--devic-primary)}.devic-input-btn:disabled{cursor:not-allowed;opacity:.5}.devic-send-btn{padding:4px 12px}.devic-send-btn,.devic-stop-btn{background:var(--devic-send-btn,var(--devic-primary));border-radius:var(--devic-radius-sm);color:#fff}.devic-stop-btn{min-width:var(--devic-input-row-height,28px);padding:4px}.devic-stop-btn:hover{background:var(--devic-primary-hover);color:#fff}.devic-send-btn-wrapper{flex-shrink:0;position:relative}.devic-send-btn-custom{align-items:center;display:flex;justify-content:center;pointer-events:none}.devic-send-btn-overlay{background:transparent;border:none;cursor:pointer;inset:0;margin:0;padding:0;position:absolute}.devic-send-btn-overlay:disabled{cursor:not-allowed;opacity:.5}.devic-send-btn:hover:not(:disabled){background:var(--devic-primary-hover);color:#fff}.devic-speech-error{background:#fff1f0;border:1px solid #ffccc7;border-radius:var(--devic-radius-sm);color:#cf1322;font-size:12px;margin-bottom:8px;padding:6px 10px}.devic-speech-mic.devic-input-btn:hover:not(:disabled){color:var(--devic-primary)}.devic-speech-mic-wrap{align-items:center;display:inline-flex;flex-shrink:0;justify-content:center;position:relative}.devic-speech-mic-wrap[data-holding=true] .devic-speech-mic{color:var(--devic-primary)}.devic-mic-hold-ring{height:calc(100% + 6px);inset:-3px;pointer-events:none;position:absolute;transform:rotate(-90deg);width:calc(100% + 6px)}.devic-mic-hold-ring-track{fill:none;stroke:var(--devic-primary);stroke-opacity:.18;stroke-width:3}.devic-mic-hold-ring-progress{fill:none;stroke:var(--devic-primary);stroke-width:3;stroke-linecap:round;transition:stroke-dashoffset 90ms linear}.devic-speech-panel{align-items:center;display:flex;flex:1;gap:8px;min-height:var(--devic-input-row-height,28px)}.devic-speech-live{align-items:center;display:flex;flex:1;gap:10px;justify-content:flex-start}.devic-speech-timer{color:var(--devic-text-secondary);font-size:13px;font-variant-numeric:tabular-nums}.devic-speech-confirm{color:#389e0d}.devic-speech-confirm.devic-input-btn:hover:not(:disabled){color:#237804}.devic-speech-confirm-wrap{align-items:center;display:inline-flex;flex-shrink:0;justify-content:center;position:relative}.devic-autostop-ring{height:calc(100% + 6px);inset:-3px;pointer-events:none;position:absolute;transform:rotate(-90deg);width:calc(100% + 6px)}.devic-autostop-ring-track{fill:none;stroke:#389e0d;stroke-opacity:.18;stroke-width:3}.devic-autostop-ring-progress{fill:none;stroke:#389e0d;stroke-width:3;stroke-linecap:round;transition:stroke-dashoffset 90ms linear}.devic-speech-confirm-wrap[data-autostop=true] .devic-speech-confirm{animation:devic-autostop-pulse 1s ease-in-out infinite}@keyframes devic-autostop-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.08)}}.devic-handoff-bar{align-items:center;background:var(--devic-primary-light,#e6f7ff);border-radius:8px;color:var(--devic-primary);display:flex;font-size:12px;gap:8px;margin-bottom:6px;padding:5px 8px}.devic-handoff-dot{animation:devic-handoff-blink 1.2s ease-in-out infinite;background:var(--devic-primary);border-radius:50%;flex-shrink:0;height:8px;width:8px}.devic-handoff-bar[data-waiting=true] .devic-handoff-dot{animation-duration:.7s}@keyframes devic-handoff-blink{0%,to{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.7)}}.devic-handoff-label{flex:1;font-weight:500}.devic-handoff-stop{align-items:center;background:transparent;border:none;border-radius:50%;color:inherit;cursor:pointer;display:inline-flex;height:22px;justify-content:center;opacity:.8;padding:0;width:22px}.devic-handoff-stop:hover{background:rgba(0,0,0,.06);opacity:1}.devic-handoff-pending{align-items:center;animation:devic-handoff-pending-in .18s ease-out;display:flex;flex:1;gap:10px;min-height:24px;min-width:0}@keyframes devic-handoff-pending-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}.devic-handoff-pending-icon{align-items:center;animation:devic-autostop-pulse 1s ease-in-out infinite;color:var(--devic-primary);display:inline-flex;flex-shrink:0;height:36px;justify-content:center;position:relative;width:36px}.devic-handoff-ring{height:100%;inset:0;pointer-events:none;position:absolute;transform:rotate(-90deg);width:100%}.devic-handoff-ring-track{fill:none;stroke:var(--devic-primary);stroke-opacity:.18;stroke-width:3}.devic-handoff-ring-progress{fill:none;stroke:var(--devic-primary);stroke-width:3;stroke-linecap:round;transition:stroke-dashoffset 90ms linear}.devic-handoff-pending-text{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.devic-handoff-pending-title{color:var(--devic-primary);font-size:13px;font-weight:500}.devic-handoff-pending-preview{color:var(--devic-text-secondary);font-size:12px;max-height:4.5em;overflow-wrap:anywhere;overflow-y:auto;white-space:normal;word-break:break-word}.devic-speech-cancel{color:var(--devic-text-muted)}.devic-speech-cancel.devic-input-btn:hover:not(:disabled){color:#cf1322}.devic-speech-status{color:var(--devic-text-secondary);font-size:13px}.devic-speech-spinner{animation:devic-spin .8s linear infinite;border:2px solid var(--devic-border);border-radius:50%;border-top-color:var(--devic-primary);flex-shrink:0;height:16px;width:16px}.devic-transcript-playback{align-items:center;background:hsla(0,0%,100%,.18);border-radius:999px;display:inline-flex;font-size:12px;gap:6px;line-height:1;margin-top:6px;max-width:100%;padding:3px 8px 3px 3px}.devic-message[data-role=assistant] .devic-transcript-playback{background:var(--devic-bg-secondary,rgba(0,0,0,.05))}.devic-transcript-btn{align-items:center;background:hsla(0,0%,100%,.85);border:none;border-radius:50%;color:var(--devic-primary,#6c5ce7);cursor:pointer;display:inline-flex;flex-shrink:0;height:22px;justify-content:center;padding:0;transition:background .15s ease;width:22px}.devic-transcript-btn:hover:not(:disabled){background:#fff}.devic-transcript-btn:disabled{cursor:default;opacity:.7}.devic-transcript-icon{align-items:center;display:inline-flex;opacity:.85}.devic-transcript-playback[data-playing=true] .devic-transcript-icon{animation:devic-pulse 1.2s ease-in-out infinite}.devic-transcript-label{opacity:.9;white-space:nowrap}.devic-transcript-spinner{animation:devic-spin .8s linear infinite;border:2px solid rgba(108,92,231,.3);border-radius:50%;border-top:2px solid var(--devic-primary,#6c5ce7);height:12px;width:12px}.devic-equalizer{align-items:center;display:flex;gap:3px;height:24px}.devic-equalizer-bar{background:var(--devic-primary);border-radius:2px;min-height:3px;transition:height 90ms ease-out;width:3px}.devic-equalizer[data-paused=true] .devic-equalizer-bar{background:var(--devic-text-muted);height:10%!important}.devic-file-preview{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.devic-file-preview-item{align-items:center;background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:var(--devic-radius-sm);display:flex;font-size:12px;gap:6px;padding:4px 8px}.devic-file-remove{background:none;border:none;color:var(--devic-text-muted);cursor:pointer;font-size:16px;line-height:1;padding:0}.devic-file-remove:hover{color:#ff4d4f}.devic-file-preview-thumb{border-radius:var(--devic-radius-sm);display:block;height:28px;object-fit:cover;width:28px}.devic-input-area{position:relative}.devic-drop-overlay{align-items:center;background:var(--devic-bg);border:2px dashed var(--devic-primary,var(--devic-border));border-radius:var(--devic-radius);color:var(--devic-text-muted);display:flex;flex-direction:column;font-size:13px;gap:8px;inset:0;justify-content:center;pointer-events:none;position:absolute;z-index:2}.devic-pasted-cards{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.devic-pasted-card{background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:var(--devic-radius);font-size:12px;max-width:240px;padding:10px;position:relative;text-align:left}.devic-pasted-card-preview{-webkit-line-clamp:5;-webkit-box-orient:vertical;color:var(--devic-text-muted);display:-webkit-box;line-height:1.4;margin:0 0 8px;overflow:hidden}.devic-pasted-card-footer{align-items:center;display:flex;gap:8px}.devic-pasted-card-badge{background:var(--devic-bg-secondary);border-radius:var(--devic-radius-sm);color:var(--devic-text);font-size:10px;font-weight:600;letter-spacing:.04em;padding:2px 6px}.devic-pasted-card-meta{color:var(--devic-text-muted);font-size:11px}.devic-pasted-card-remove{position:absolute;right:6px;top:4px}.devic-message-pasted{display:flex;flex-direction:column;gap:8px;margin-bottom:8px}.devic-message-pasted .devic-pasted-card{max-width:100%;overflow:hidden;padding:0}.devic-pasted-card-toggle{background:none;border:none;color:var(--devic-text);cursor:pointer;display:block;font:inherit;padding:10px;text-align:left;width:100%}.devic-pasted-card-full{color:var(--devic-text);font-family:var(--devic-font-mono,ui-monospace,SFMono-Regular,Menlo,monospace);font-size:11px;line-height:1.5;margin:0 0 8px;max-height:320px;overflow:auto;white-space:pre-wrap;word-break:break-word}.devic-message-file-image{border-radius:var(--devic-radius-sm);display:block;max-width:220px;overflow:hidden}.devic-message-file-image img{display:block;height:auto;width:100%}.devic-trigger{align-items:center;background:var(--devic-primary);border:none;border-radius:50%;box-shadow:var(--devic-shadow);color:#fff;cursor:pointer;display:flex;height:56px;justify-content:center;position:fixed;transition:background var(--devic-transition),transform var(--devic-transition);width:56px}.devic-trigger:hover{background:var(--devic-primary-hover);transform:scale(1.05)}.devic-trigger svg{height:24px;width:24px}.devic-error{background:#fff2f0;border:1px solid #ffccc7;border-radius:var(--devic-radius);color:#ff4d4f;font-size:13px;margin:8px 16px;padding:12px}.devic-messages-container::-webkit-scrollbar{width:6px}.devic-messages-container::-webkit-scrollbar-track{background:transparent}.devic-messages-container::-webkit-scrollbar-thumb{background:var(--devic-border);border-radius:3px}.devic-messages-container::-webkit-scrollbar-thumb:hover{background:var(--devic-text-muted)}.devic-chat-drawer[data-mode=inline]{border:1px solid var(--devic-border);bottom:auto;box-shadow:none;height:100%;left:auto;position:relative;right:auto;top:auto;transform:none}.devic-drawer-header-actions{align-items:center;display:flex;gap:4px;margin-left:auto}.devic-new-chat-btn{background:none;border:none;border-radius:var(--devic-radius-sm);color:var(--devic-text-secondary);cursor:pointer;padding:8px;transition:background var(--devic-transition),color var(--devic-transition)}.devic-new-chat-btn:hover{background:var(--devic-bg-secondary);color:var(--devic-primary)}.devic-conversation-selector{flex:1;margin:0 8px;min-width:72px;position:relative}.devic-conversation-selector-trigger{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:var(--devic-radius-sm);color:var(--devic-text);cursor:pointer;display:flex;font-family:var(--devic-font-family);font-size:13px;gap:6px;padding:6px 10px;text-align:left;transition:border-color var(--devic-transition);width:100%}.devic-conversation-selector-trigger:hover{border-color:var(--devic-primary)}.devic-conversation-selector-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-conversation-dropdown{background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:var(--devic-radius);box-shadow:var(--devic-shadow);display:flex;flex-direction:column;left:0;max-height:320px;position:absolute;right:0;top:calc(100% + 4px);z-index:10}.devic-conversation-search-wrapper{border-bottom:1px solid var(--devic-border);padding:8px}.devic-conversation-search{background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:var(--devic-radius-sm);box-sizing:border-box;color:var(--devic-text);font-family:var(--devic-font-family);font-size:13px;outline:none;padding:6px 8px;width:100%}.devic-conversation-search:focus{border-color:var(--devic-primary)}.devic-conversation-list{flex:1;overflow-y:auto}.devic-conversation-item{align-items:center;background:none;border:none;color:var(--devic-text);cursor:pointer;display:flex;font-family:var(--devic-font-family);font-size:13px;justify-content:space-between;padding:8px 12px;text-align:left;transition:background .15s;width:100%}.devic-conversation-item:hover,.devic-conversation-item[data-active=true]{background:var(--devic-bg-secondary)}.devic-conversation-item-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-conversation-item-date{color:var(--devic-text-muted);flex-shrink:0;font-size:11px;margin-left:8px}.devic-conversation-empty,.devic-conversation-loading{color:var(--devic-text-muted);font-size:13px;padding:12px;text-align:center}.devic-conversation-load-more{background:none;border:none;color:var(--devic-text-muted);cursor:pointer;display:block;font-family:var(--devic-font-family);font-size:12px;padding:8px 12px;text-align:center;transition:background .15s;width:100%}.devic-conversation-load-more:hover{background:var(--devic-bg-secondary);color:var(--devic-primary)}.devic-conversation-new{background:none;border:none;border-top:1px solid var(--devic-border);color:var(--devic-primary);cursor:pointer;display:block;font-family:var(--devic-font-family);font-size:13px;padding:10px 12px;text-align:left;transition:background .15s;width:100%}.devic-conversation-new:hover{background:var(--devic-bg-secondary)}.devic-conversation-item-check{align-items:center;color:var(--devic-primary);display:flex;flex-shrink:0;margin-right:6px}.devic-message-bubble h1,.devic-message-bubble h2,.devic-message-bubble h3,.devic-message-bubble h4,.devic-message-bubble h5,.devic-message-bubble h6{line-height:1.3;margin:8px 0 4px}.devic-message-bubble h1{font-size:1.3em}.devic-message-bubble h2{font-size:1.2em}.devic-message-bubble h3{font-size:1.1em}.devic-message-bubble p{margin:4px 0}.devic-message-bubble ol,.devic-message-bubble ul{margin:4px 0;padding-left:20px}.devic-message-bubble code{background:rgba(0,0,0,.06);border-radius:3px;color:inherit;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:.9em;padding:1px 4px}.devic-message-bubble pre{background:rgba(0,0,0,.06);border-radius:var(--devic-radius-sm);color:inherit;margin:8px 0;overflow-x:auto;padding:10px}.devic-message-bubble pre code{background:none;color:inherit;padding:0}.devic-message-bubble blockquote{border-left:3px solid var(--devic-border);color:var(--devic-text-secondary);margin:4px 0;padding-left:12px}.devic-message-bubble a{color:var(--devic-primary);text-decoration:underline}.devic-message-bubble p:first-child{margin-top:0}.devic-message-bubble p:last-child{margin-bottom:0}.devic-message[data-role=user] .devic-message-bubble a{color:inherit}.devic-message[data-role=user] .devic-message-bubble code,.devic-message[data-role=user] .devic-message-bubble pre{background:hsla(0,0%,100%,.18)}.devic-message[data-role=user] .devic-message-bubble blockquote{border-left-color:hsla(0,0%,100%,.45);color:inherit}.markdown-table{margin:8px 0;overflow-x:auto}.markdown-table table{border-collapse:collapse;font-size:13px;width:100%}.markdown-table td,.markdown-table th{border:1px solid var(--devic-border);padding:6px 10px;text-align:left}.markdown-table th{background:var(--devic-bg-secondary);font-weight:600}.devic-resize-handle{bottom:0;cursor:col-resize;position:absolute;top:0;width:6px;z-index:1}.devic-resize-handle[data-position=right]{left:0}.devic-resize-handle[data-position=left]{right:0}.devic-resize-handle:active,.devic-resize-handle:hover{background:var(--devic-primary);opacity:.3}.devic-handoff-widget{animation:devic-slideUp .3s ease-out;background:var(--devic-bg);border:1px solid var(--devic-border);border-radius:8px;display:flex;flex-direction:column;gap:10px;max-width:320px;padding:12px;width:100%}.devic-handoff-header{align-items:center;display:flex;gap:8px}.devic-handoff-agent-avatar{align-items:center;background:var(--devic-bg-secondary);border-radius:50%;display:flex;flex-shrink:0;height:24px;justify-content:center;overflow:hidden;width:24px}.devic-handoff-avatar-img{height:100%;object-fit:cover;width:100%}.devic-handoff-agent-name{color:var(--devic-text);font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-handoff-progress,.devic-handoff-state-row{align-items:center;display:flex;gap:8px}.devic-handoff-progress-bar{background:#f0f0f0;border-radius:3px;flex:1;height:6px;overflow:hidden;position:relative}.devic-handoff-progress-fill{border-radius:3px;height:100%;transition:width .4s ease}.devic-handoff-progress-fill[data-status=active]{background:var(--devic-primary)}.devic-handoff-progress-fill[data-status=success]{background:#52c41a}.devic-handoff-progress-fill[data-status=error]{background:#ff4d4f}.devic-handoff-progress-text{color:var(--devic-text-muted);flex-shrink:0;font-size:11px}.devic-handoff-progress-indeterminate{animation:devic-indeterminate 1.5s ease-in-out infinite;background:var(--devic-primary);border-radius:3px;height:100%;width:40%}@keyframes devic-indeterminate{0%{transform:translateX(-100%)}50%{transform:translateX(150%)}to{transform:translateX(-100%)}}.devic-handoff-summary{-webkit-line-clamp:2;-webkit-box-orient:vertical;color:var(--devic-text-secondary);display:-webkit-box;font-size:12px;line-height:1.4;overflow:hidden;text-overflow:ellipsis}.devic-handoff-summary-active{animation:devic-pulse 2s cubic-bezier(.4,0,.6,1) infinite}.devic-handoff-elapsed{align-items:center;color:var(--devic-text-muted);display:flex;font-size:11px;gap:4px}.devic-message[data-role=user] .devic-message-references{display:flex;flex-wrap:wrap;gap:4px;justify-content:flex-end;margin-bottom:4px}.devic-message-reference-chip{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:999px;color:var(--devic-text);display:inline-flex;font-size:11px;gap:4px;max-width:220px;padding:3px 8px}.devic-message-reference-chip-label{color:var(--devic-primary);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-reference-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:4px;padding:6px 8px}.devic-reference-chip{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:999px;color:var(--devic-text);display:inline-flex;font-size:12px;gap:6px;max-width:220px;padding:4px 8px}.devic-reference-chip-label{color:var(--devic-primary);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-reference-chip-remove{align-items:center;background:transparent;border:none;border-radius:4px;color:var(--devic-text-muted);cursor:pointer;display:inline-flex;font-size:16px;line-height:1;padding:0 2px}.devic-reference-chip-remove:hover{background:rgba(0,0,0,.06);color:var(--devic-text)}.devic-queue-notice{align-items:center;background:var(--devic-bg-secondary);border:1px dashed var(--devic-queued-border);border-radius:var(--devic-radius);color:var(--devic-text-secondary);display:flex;font-size:12px;gap:6px;line-height:1.4;margin-bottom:4px;padding:8px 12px}.devic-queue-notice-icon{color:var(--devic-queued-accent);display:flex;flex-shrink:0}.devic-queue-notice[data-alert=true]{border-color:var(--devic-error,#ff4d4f);border-style:solid;color:var(--devic-text)}.devic-queue-notice[data-alert=true] .devic-queue-notice-icon{color:var(--devic-error,#ff4d4f)}.devic-input-disabled-notice{align-items:center;background:var(--devic-bg-secondary);border-radius:var(--devic-radius);color:var(--devic-text-muted);display:flex;font-size:12px;gap:6px;justify-content:center;margin-bottom:4px;padding:8px 12px}.devic-inline-widgets{display:flex;flex-direction:column;gap:8px;padding:8px 12px}.devic-inline-widget{background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:var(--devic-radius);padding:12px}.devic-input-widget{padding:8px;width:100%}.devic-limit-banner{align-items:flex-start;background:#fff7e6;border:1px solid #ffd591;border-radius:var(--devic-radius);color:#ad4e00;display:flex;font-size:13px;gap:8px;margin-bottom:8px;padding:8px 12px}.devic-limit-banner-icon{color:#fa8c16;display:inline-flex;flex-shrink:0;margin-top:1px}.devic-limit-banner-text{display:flex;flex-direction:column;gap:2px;line-height:1.35}.devic-limit-banner-title{font-weight:600}.devic-limit-banner-reset{color:var(--devic-text-secondary);font-size:12px}.devic-usage-bar-wrap{display:flex;flex-direction:column;gap:6px;margin-bottom:8px}.devic-usage-bar-head{align-items:center;display:flex;gap:8px;justify-content:space-between}.devic-usage-tier{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:999px;color:var(--devic-text-secondary);display:inline-flex;font-size:11px;font-weight:600;letter-spacing:.02em;padding:2px 8px;text-transform:uppercase;white-space:nowrap}.devic-usage-bar-window{color:var(--devic-text-muted);white-space:nowrap}.devic-usage-bar-group{background:var(--devic-bg-secondary);border-radius:var(--devic-radius);display:flex;flex-direction:column;gap:4px;padding:5px 10px}.devic-usage-bar-group .devic-usage-bar{background:transparent;padding:0}.devic-usage-bar{align-items:center;background:var(--devic-bg-secondary);border-radius:var(--devic-radius);color:var(--devic-text-secondary);display:flex;font-size:12px;gap:8px;padding:5px 10px}.devic-usage-bar[data-empty=true]{color:var(--devic-text-muted);justify-content:space-between}.devic-usage-bar-label{font-weight:500;white-space:nowrap}.devic-usage-bar-track{background:var(--devic-border);border-radius:999px;flex:1;height:6px;overflow:hidden}.devic-usage-bar-fill{border-radius:999px;height:100%;transition:width var(--devic-transition),background-color var(--devic-transition)}.devic-usage-bar-reset{color:var(--devic-text-muted);white-space:nowrap}.devic-usage-toggle{align-items:center;background:var(--devic-bg-secondary);border:1px solid var(--devic-border);border-radius:999px;color:var(--devic-text-secondary);cursor:pointer;display:inline-flex;font-size:12px;font-weight:500;gap:6px;padding:4px 10px;transition:background var(--devic-transition),color var(--devic-transition)}.devic-usage-toggle:hover{background:var(--devic-border);color:var(--devic-text)}.devic-usage-collapse{align-items:center;background:transparent;border:none;border-radius:var(--devic-radius-sm);color:var(--devic-text-muted);cursor:pointer;display:inline-flex;font-size:16px;height:18px;justify-content:center;line-height:1;padding:0;width:18px}.devic-usage-collapse:hover{background:var(--devic-border);color:var(--devic-text)}@media (max-width:480px){.devic-chat-drawer{width:100%}}.devic-compaction{color:var(--devic-text-secondary);flex-shrink:0;font-size:12px;margin:10px 0;width:100%}.devic-compaction-head,.devic-compaction-running{align-items:center;display:flex;gap:8px}.devic-compaction-rule{background:var(--devic-compaction-border,rgba(114,46,209,.3));flex:1;height:1px}.devic-compaction-pill{align-items:center;background:var(--devic-compaction-bg,rgba(114,46,209,.06));border:1px solid var(--devic-compaction-border,rgba(114,46,209,.3));border-radius:999px;color:inherit;cursor:pointer;display:flex;flex-shrink:0;font:inherit;gap:8px;max-width:100%;overflow:hidden;padding:4px 12px;white-space:nowrap}.devic-compaction-pill-static,.devic-compaction-running .devic-compaction-pill{cursor:default}.devic-compaction-icon{color:var(--devic-compaction-accent,#722ed1);flex-shrink:0}.devic-compaction-title{color:var(--devic-text);font-weight:600}.devic-compaction-meta{opacity:.75;overflow:hidden;text-overflow:ellipsis}.devic-compaction-tag{border:1px solid var(--devic-compaction-border,rgba(114,46,209,.3));border-radius:4px;font-size:10px;line-height:16px;opacity:.8;padding:0 6px}.devic-compaction-chevron{flex-shrink:0;opacity:.6;transition:transform .15s ease}.devic-compaction-dots{display:inline-flex;flex-shrink:0;gap:3px}.devic-compaction-dots i{animation:devic-compaction-blink 1.2s ease-in-out infinite;background:var(--devic-compaction-accent,#722ed1);border-radius:50%;height:4px;width:4px}.devic-compaction-dots i:nth-child(2){animation-delay:.2s}.devic-compaction-dots i:nth-child(3){animation-delay:.4s}@keyframes devic-compaction-blink{0%,80%,to{opacity:.25}40%{opacity:1}}.devic-compaction-body{background:var(--devic-compaction-bg,rgba(114,46,209,.06));border:1px solid var(--devic-compaction-border,rgba(114,46,209,.3));border-radius:var(--devic-radius-sm,8px);display:flex;flex-direction:column;gap:10px;margin-top:8px;padding:10px 12px}.devic-compaction-note{color:var(--devic-text-muted);font-size:11px}.devic-compaction-section{color:var(--devic-text);display:flex;flex-direction:column;gap:3px}.devic-compaction-section-title{font-size:10px;font-weight:600;letter-spacing:.5px;opacity:.7;text-transform:uppercase}.devic-compaction-list{margin:0;padding-left:18px}.devic-compaction-raw{white-space:pre-wrap}.devic-compaction-facts{display:flex;flex-wrap:wrap;gap:4px}.devic-compaction-fact{border:1px solid var(--devic-compaction-border,rgba(114,46,209,.3));border-radius:4px;font-family:var(--devic-font-mono,ui-monospace,SFMono-Regular,monospace);font-size:11px;line-height:18px;padding:0 6px}.devic-compaction-fact-label{opacity:.65}.devic-guardrail-notice{align-items:center;background:var(--devic-guardrail-bg,rgba(255,77,79,.06));border:1px solid var(--devic-guardrail-border,rgba(255,77,79,.25));border-radius:var(--devic-radius);color:var(--devic-text-secondary);display:flex;flex-shrink:0;font-size:12px;gap:6px;justify-content:center;line-height:1.4;margin:10px 0;padding:8px 12px;text-align:center;width:100%}.devic-guardrail-notice-icon{color:var(--devic-error,#ff4d4f);display:flex;flex-shrink:0}.devic-command-bar-container{--devic-cmd-bg:var(--devic-cmd-bg-override,#fff);--devic-cmd-text:var(--devic-cmd-text-override,#1f2937);--devic-cmd-text-secondary:var(--devic-cmd-text-secondary-override,#6b7280);--devic-cmd-border:var(--devic-cmd-border-override,#e5e7eb);--devic-cmd-radius:var(--devic-cmd-radius-override,12px);--devic-cmd-shadow:var(--devic-cmd-shadow-override,0 4px 20px rgba(0,0,0,.1));--devic-cmd-primary:var(--devic-cmd-primary-override,#3b82f6);--devic-cmd-font-family:var(--devic-cmd-font-family-override,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif);--devic-cmd-font-size:var(--devic-cmd-font-size-override,14px);--devic-cmd-animation-duration:var(--devic-cmd-animation-duration-override,200ms);color:var(--devic-cmd-text);display:flex;flex-direction:column;font-family:var(--devic-cmd-font-family);font-size:var(--devic-cmd-font-size);gap:8px;max-width:100%;width:400px}.devic-command-bar-container[data-position=fixed]{position:fixed}.devic-command-bar-container[data-position=inline]{position:relative}.devic-command-bar-container[data-visible=false]{opacity:0;pointer-events:none;transform:translateY(8px)}.devic-command-bar-container[data-visible=false],.devic-command-bar-container[data-visible=true]{transition:opacity var(--devic-cmd-animation-duration) ease,transform var(--devic-cmd-animation-duration) ease}.devic-command-bar-container[data-visible=true]{opacity:1;transform:translateY(0)}.devic-command-bar{align-items:center;background:var(--devic-cmd-bg);border:1px solid var(--devic-cmd-border);border-radius:var(--devic-cmd-radius);box-shadow:var(--devic-cmd-shadow);display:flex;gap:12px;padding:12px 16px}.devic-command-bar-icon{align-items:center;color:var(--devic-cmd-text-secondary);display:flex;flex-shrink:0;height:20px;justify-content:center;width:20px}.devic-command-bar-icon svg{height:100%;width:100%}.devic-command-bar-input{background:transparent;border:none;color:inherit;flex:1;font-family:inherit;font-size:inherit;min-width:0;outline:none}.devic-command-bar-input::placeholder{color:var(--devic-cmd-text-secondary)}.devic-command-bar-summary{animation:devic-cmd-pulse 1.5s ease-in-out infinite;color:var(--devic-cmd-text-secondary);flex:1;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@keyframes devic-cmd-pulse{0%,to{opacity:1}50%{opacity:.6}}.devic-command-bar-shortcut{background:var(--devic-cmd-border);border-radius:6px;color:var(--devic-cmd-text-secondary);flex-shrink:0;font-size:12px;font-weight:500;letter-spacing:.5px;padding:4px 8px}.devic-command-bar-spinner{animation:devic-cmd-spin .8s linear infinite;border:2px solid var(--devic-cmd-border);border-radius:50%;border-top-color:var(--devic-cmd-primary);height:20px;width:20px}@keyframes devic-cmd-spin{to{transform:rotate(1turn)}}.devic-command-bar-result{animation:devic-cmd-slide-up .2s ease-out;background:var(--devic-cmd-bg);border:1px solid var(--devic-cmd-border);border-radius:var(--devic-cmd-radius);box-shadow:var(--devic-cmd-shadow);overflow:hidden}@keyframes devic-cmd-slide-up{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.devic-command-bar-result-tools{border-bottom:1px solid var(--devic-cmd-border)}.devic-command-bar-result-tools-header{align-items:center;color:var(--devic-cmd-text-secondary);cursor:pointer;display:flex;font-size:13px;gap:8px;padding:10px 14px;transition:background .15s ease;user-select:none}.devic-command-bar-result-tools-header:hover{background:rgba(0,0,0,.02)}.devic-command-bar-result-tools-chevron{height:16px;transition:transform .2s ease;width:16px}.devic-command-bar-result-tools-header[data-expanded=true] .devic-command-bar-result-tools-chevron{transform:rotate(90deg)}.devic-command-bar-result-tools-count{align-items:center;background:var(--devic-cmd-primary);border-radius:10px;color:#fff;display:inline-flex;font-size:11px;font-weight:600;height:20px;justify-content:center;min-width:20px;padding:0 6px}.devic-command-bar-result-tools-list{display:flex;flex-direction:column;gap:6px;padding:8px 14px 12px}.devic-command-bar-result-tools-list[data-expanded=false]{display:none}.devic-command-bar-result-tool-item{align-items:center;background:rgba(0,0,0,.02);border-radius:6px;display:flex;font-size:12px;gap:8px;padding:6px 10px}.devic-command-bar-result-tool-icon{color:#10b981;height:14px;width:14px}.devic-command-bar-result-tool-name{color:var(--devic-cmd-text-secondary)}.devic-command-bar-result-message{line-height:1.5;max-height:300px;overflow-y:auto;padding:14px}.devic-command-bar-result-message::-webkit-scrollbar{width:6px}.devic-command-bar-result-message::-webkit-scrollbar-track{background:transparent}.devic-command-bar-result-message::-webkit-scrollbar-thumb{background:var(--devic-cmd-border);border-radius:3px}.devic-command-bar-error{background:#fef2f2;border:1px solid #fecaca;border-radius:var(--devic-cmd-radius);color:#dc2626;font-size:13px;padding:10px 14px}.devic-command-bar-result-empty{color:var(--devic-cmd-text-secondary);font-size:13px;padding:14px;text-align:center}.devic-command-bar-dropdown{animation:devic-cmd-slide-up .2s ease-out;background:var(--devic-cmd-bg);border:1px solid var(--devic-cmd-border);border-radius:var(--devic-cmd-radius);box-shadow:var(--devic-cmd-shadow);overflow:hidden}.devic-command-bar-dropdown-header{align-items:center;border-bottom:1px solid var(--devic-cmd-border);color:var(--devic-cmd-text-secondary);display:flex;font-size:12px;font-weight:600;justify-content:space-between;letter-spacing:.5px;padding:10px 14px;text-transform:uppercase}.devic-command-bar-dropdown-hint{align-items:center;display:flex;font-weight:400;gap:4px;letter-spacing:0;text-transform:none}.devic-command-bar-dropdown-hint kbd{align-items:center;background:var(--devic-cmd-border);border-radius:4px;display:inline-flex;font-family:inherit;font-size:10px;height:18px;justify-content:center;min-width:18px;padding:0 4px}.devic-command-bar-dropdown-clear{background:none;border:none;border-radius:4px;color:var(--devic-cmd-primary);cursor:pointer;font-family:inherit;font-size:12px;font-weight:500;letter-spacing:0;padding:2px 6px;text-transform:none}.devic-command-bar-dropdown-clear:hover{background:rgba(0,0,0,.05)}.devic-command-bar-dropdown-list{max-height:250px;overflow-y:auto}.devic-command-bar-dropdown-list::-webkit-scrollbar{width:6px}.devic-command-bar-dropdown-list::-webkit-scrollbar-track{background:transparent}.devic-command-bar-dropdown-list::-webkit-scrollbar-thumb{background:var(--devic-cmd-border);border-radius:3px}.devic-command-bar-dropdown-item{align-items:center;cursor:pointer;display:flex;gap:10px;padding:10px 14px;transition:background .15s ease}.devic-command-bar-dropdown-item:hover,.devic-command-bar-dropdown-item[data-selected=true]{background:rgba(0,0,0,.04)}.devic-command-bar-dropdown-item[data-selected=true]{background:var(--devic-cmd-primary);background:rgba(59,130,246,.1)}.devic-command-bar-dropdown-icon{align-items:center;color:var(--devic-cmd-text-secondary);display:flex;flex-shrink:0;height:16px;justify-content:center;width:16px}.devic-command-bar-dropdown-keyword{color:var(--devic-cmd-text);flex-shrink:0;font-weight:600}.devic-command-bar-dropdown-desc{color:var(--devic-cmd-text-secondary);flex:1;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-command-bar-dropdown-empty{color:var(--devic-cmd-text-secondary);font-size:13px;padding:20px 14px;text-align:center}.devic-command-bar-history-item{border-bottom:1px solid rgba(0,0,0,.04)}.devic-command-bar-history-item:last-child{border-bottom:none}.devic-command-bar-history-text{flex:1;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-gen-container{--devic-gen-primary:var(--devic-gen-primary-override,#3b82f6);--devic-gen-primary-hover:var(--devic-gen-primary-hover-override,#2563eb);--devic-gen-bg:var(--devic-gen-bg-override,#fff);--devic-gen-text:var(--devic-gen-text-override,#1f2937);--devic-gen-text-secondary:var(--devic-gen-text-secondary-override,#6b7280);--devic-gen-border:var(--devic-gen-border-override,#e5e7eb);--devic-gen-radius:var(--devic-gen-radius-override,8px);--devic-gen-font-family:var(--devic-gen-font-family-override,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif);--devic-gen-font-size:var(--devic-gen-font-size-override,14px);--devic-gen-z-index:var(--devic-gen-z-index-override,10000);--devic-gen-animation-duration:var(--devic-gen-animation-duration-override,200ms);--devic-gen-modal-bg:var(--devic-gen-modal-bg-override,#fff);--devic-gen-modal-text:var(--devic-gen-modal-text-override,#1f2937);--devic-gen-modal-border:var(--devic-gen-modal-border-override,#e5e7eb);font-family:var(--devic-gen-font-family);font-size:var(--devic-gen-font-size)}.devic-gen-button{align-items:center;border:none;border-radius:var(--devic-gen-radius);cursor:pointer;display:inline-flex;font-family:inherit;font-weight:500;gap:8px;justify-content:center;transition:all var(--devic-gen-animation-duration) ease}.devic-gen-button:disabled{cursor:not-allowed;opacity:.6}.devic-gen-button[data-size=small]{font-size:12px;padding:6px 12px}.devic-gen-button[data-size=medium]{font-size:14px;padding:8px 16px}.devic-gen-button[data-size=large]{font-size:16px;padding:12px 24px}.devic-gen-button[data-variant=primary]{background:var(--devic-gen-primary);color:#fff}.devic-gen-button[data-variant=primary]:hover:not(:disabled){background:var(--devic-gen-primary-hover)}.devic-gen-button[data-variant=secondary]{background:var(--devic-gen-border);color:var(--devic-gen-text)}.devic-gen-button[data-variant=secondary]:hover:not(:disabled){background:#d1d5db}.devic-gen-button[data-variant=outline]{background:transparent;border:1px solid var(--devic-gen-primary);color:var(--devic-gen-primary)}.devic-gen-button[data-variant=outline]:hover:not(:disabled){background:rgba(59,130,246,.1)}.devic-gen-button[data-variant=ghost]{background:transparent;color:var(--devic-gen-text)}.devic-gen-button[data-variant=ghost]:hover:not(:disabled){background:rgba(0,0,0,.05)}.devic-gen-button-icon{align-items:center;display:flex;height:16px;justify-content:center;width:16px}.devic-gen-button-icon svg{height:100%;width:100%}.devic-gen-spinner{animation:devic-gen-spin .8s linear infinite;border:2px solid;border-radius:50%;border-top:2px solid transparent;height:16px;width:16px}.devic-gen-spinner-small{border-width:1.5px;height:12px;width:12px}@keyframes devic-gen-spin{to{transform:rotate(1turn)}}.devic-gen-input{background:var(--devic-gen-modal-bg);border:1px solid var(--devic-gen-modal-border);border-radius:var(--devic-gen-radius);color:var(--devic-gen-modal-text);font-family:inherit;font-size:inherit;min-height:80px;outline:none;padding:12px;resize:vertical;transition:border-color var(--devic-gen-animation-duration) ease;width:100%}.devic-gen-input:focus{border-color:var(--devic-gen-primary)}.devic-gen-input::placeholder{color:var(--devic-gen-text-secondary)}.devic-gen-error{background:#fef2f2;border:1px solid #fecaca;border-radius:var(--devic-gen-radius);color:#dc2626;font-size:13px;margin-top:8px;padding:8px 12px}.devic-gen-tooltip{animation:devic-gen-fade-in var(--devic-gen-animation-duration) ease-out;background:var(--devic-gen-modal-bg);border:1px solid var(--devic-gen-modal-border);border-radius:var(--devic-gen-radius);box-shadow:0 4px 20px rgba(0,0,0,.15);padding:12px}@keyframes devic-gen-fade-in{0%{opacity:0;transform:translateY(4px) translateX(-50%)}to{opacity:1;transform:translateY(0) translateX(-50%)}}.devic-gen-tooltip[data-placement=left],.devic-gen-tooltip[data-placement=right]{animation-name:devic-gen-fade-in-horizontal}@keyframes devic-gen-fade-in-horizontal{0%{opacity:0;transform:translateX(4px) translateY(-50%)}to{opacity:1;transform:translateX(0) translateY(-50%)}}.devic-gen-tooltip-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:12px}.devic-gen-tooltip-cancel,.devic-gen-tooltip-confirm{align-items:center;border-radius:var(--devic-gen-radius);cursor:pointer;display:inline-flex;font-family:inherit;font-size:13px;font-weight:500;gap:6px;padding:6px 12px;transition:all var(--devic-gen-animation-duration) ease}.devic-gen-tooltip-cancel{background:transparent;border:1px solid var(--devic-gen-modal-border);color:var(--devic-gen-text-secondary)}.devic-gen-tooltip-cancel:hover{background:rgba(0,0,0,.05)}.devic-gen-tooltip-confirm{background:var(--devic-gen-primary);border:none;color:#fff}.devic-gen-tooltip-confirm:hover:not(:disabled){background:var(--devic-gen-primary-hover)}.devic-gen-tooltip-confirm:disabled{cursor:not-allowed;opacity:.6}.devic-gen-modal-overlay{align-items:center;animation:devic-gen-overlay-fade-in var(--devic-gen-animation-duration) ease-out;background:rgba(0,0,0,.5);display:flex;inset:0;justify-content:center;position:fixed;z-index:var(--devic-gen-z-index)}@keyframes devic-gen-overlay-fade-in{0%{opacity:0}to{opacity:1}}.devic-gen-modal{animation:devic-gen-modal-slide-up var(--devic-gen-animation-duration) ease-out;background:var(--devic-gen-modal-bg);border-radius:calc(var(--devic-gen-radius) + 4px);box-shadow:0 20px 50px rgba(0,0,0,.2);margin:16px;max-width:480px;width:100%}@keyframes devic-gen-modal-slide-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.devic-gen-modal-header{align-items:center;border-bottom:1px solid var(--devic-gen-modal-border);display:flex;justify-content:space-between;padding:16px 20px}.devic-gen-modal-title{color:var(--devic-gen-modal-text);font-size:18px;font-weight:600;margin:0}.devic-gen-modal-close{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--devic-gen-text-secondary);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:all var(--devic-gen-animation-duration) ease;width:32px}.devic-gen-modal-close:hover{background:rgba(0,0,0,.05);color:var(--devic-gen-modal-text)}.devic-gen-modal-description{color:var(--devic-gen-text-secondary);font-size:14px;line-height:1.5;margin:0;padding:12px 20px 0}.devic-gen-modal-body{padding:16px 20px}.devic-gen-modal-footer{border-top:1px solid var(--devic-gen-modal-border);display:flex;gap:12px;justify-content:flex-end;padding:16px 20px}.devic-gen-modal-cancel,.devic-gen-modal-confirm{align-items:center;border-radius:var(--devic-gen-radius);cursor:pointer;display:inline-flex;font-family:inherit;font-size:14px;font-weight:500;gap:8px;padding:10px 20px;transition:all var(--devic-gen-animation-duration) ease}.devic-gen-modal-cancel{background:transparent;border:1px solid var(--devic-gen-modal-border);color:var(--devic-gen-text-secondary)}.devic-gen-modal-cancel:hover{background:rgba(0,0,0,.05);color:var(--devic-gen-modal-text)}.devic-gen-modal-confirm{background:var(--devic-gen-primary);border:none;color:#fff}.devic-gen-modal-confirm:hover:not(:disabled){background:var(--devic-gen-primary-hover)}.devic-gen-modal-confirm:disabled{cursor:not-allowed;opacity:.6}.devic-gen-input::-webkit-scrollbar{width:6px}.devic-gen-input::-webkit-scrollbar-track{background:transparent}.devic-gen-input::-webkit-scrollbar-thumb{background:var(--devic-gen-border);border-radius:3px}.devic-gen-input:disabled{background:var(--devic-gen-border);cursor:not-allowed;opacity:.6}.devic-gen-tool-calls{background:rgba(0,0,0,.02);border:1px solid var(--devic-gen-modal-border);border-radius:var(--devic-gen-radius);display:flex;flex-direction:column;gap:6px;margin-bottom:12px;padding:10px 12px}.devic-gen-tool-item{align-items:center;color:var(--devic-gen-text-secondary);display:flex;font-size:13px;gap:8px}.devic-gen-tool-item[data-status=executing]{color:var(--devic-gen-primary)}.devic-gen-tool-item[data-status=completed] .devic-gen-tool-icon{color:#10b981}.devic-gen-tool-icon{align-items:center;display:flex;flex-shrink:0;height:16px;justify-content:center;width:16px}.devic-gen-tool-icon svg{height:100%;width:100%}.devic-gen-tool-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-gen-tool-custom{padding:8px 0}.devic-gen-processing-status{align-items:center;background:rgba(59,130,246,.05);border:1px solid rgba(59,130,246,.2);border-radius:var(--devic-gen-radius);display:flex;gap:8px;margin-bottom:12px;padding:10px 12px}.devic-gen-processing-text{animation:devic-gen-pulse 1.5s ease-in-out infinite;color:var(--devic-gen-primary);font-size:13px}@keyframes devic-gen-pulse{0%,to{opacity:1}50%{opacity:.6}}.devic-aiwrap-container,.devic-aiwrap-tooltip,.devic-aiwrap-trigger-wrapper{--devic-aiwrap-color:#7c3aed;--devic-aiwrap-color-2:#4f46e5;--devic-aiwrap-bg:#fff;--devic-aiwrap-text:#1f2937;--devic-aiwrap-border:#e5e7eb;--devic-aiwrap-shadow:0 8px 24px rgba(0,0,0,.12)}.devic-aiwrap-container[data-highlight=true] .devic-aiwrap-content{background:rgba(124,58,237,.08);border-radius:4px;outline:1px dashed rgba(124,58,237,.45);outline-offset:2px;transition:background .15s ease,outline-color .15s ease}.devic-aiwrap-content{display:inline;transition:background .15s ease}.devic-aiwrap-trigger-wrapper{display:inline-flex}.devic-aiwrap-trigger{align-items:center;background:linear-gradient(90deg,var(--devic-aiwrap-color) 0,var(--devic-aiwrap-color-2) 100%);border:1px solid hsla(0,0%,100%,.25);box-shadow:0 4px 14px rgba(124,58,237,.35);color:#fff;cursor:pointer;display:inline-flex;font-family:inherit;font-size:13px;font-weight:500;gap:6px;padding:6px 12px;transition:transform .12s ease,box-shadow .12s ease;white-space:nowrap}.devic-aiwrap-trigger:hover{box-shadow:0 6px 18px rgba(124,58,237,.45);transform:translateY(-1px)}.devic-aiwrap-trigger:active{transform:translateY(0)}.devic-aiwrap-trigger-icon{align-items:center;display:inline-flex}.devic-aiwrap-trigger-label{line-height:1}.devic-aiwrap-tooltip{background:var(--devic-aiwrap-bg);border:1px solid var(--devic-aiwrap-border);border-radius:12px;box-shadow:var(--devic-aiwrap-shadow);color:var(--devic-aiwrap-text);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px;overflow:hidden}.devic-aiwrap-tooltip-header{align-items:center;background:rgba(124,58,237,.05);border-bottom:1px solid var(--devic-aiwrap-border);display:flex;gap:8px;justify-content:space-between;padding:10px 12px}.devic-aiwrap-tooltip-label{color:var(--devic-aiwrap-color);font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devic-aiwrap-tooltip-close{align-items:center;background:transparent;border:none;border-radius:4px;color:#6b7280;cursor:pointer;display:inline-flex;padding:2px}.devic-aiwrap-tooltip-close:hover{background:rgba(0,0,0,.06);color:#111827}.devic-aiwrap-tooltip-body{line-height:1.5;max-height:320px;overflow-y:auto;padding:12px}.devic-aiwrap-processing{align-items:center;color:#6b7280;display:flex;font-size:13px;gap:8px}.devic-aiwrap-spinner{animation:devic-aiwrap-spin .7s linear infinite;border:2px solid rgba(124,58,237,.25);border-radius:50%;border-top:2px solid var(--devic-aiwrap-color);flex-shrink:0;height:14px;width:14px}@keyframes devic-aiwrap-spin{to{transform:rotate(1turn)}}.devic-aiwrap-error{color:#dc2626;font-size:13px}.devic-aiwrap-answer{white-space:pre-wrap;word-break:break-word}
|
package/dist/esm/api/types.d.ts
CHANGED
|
@@ -27,6 +27,15 @@ export interface MessageFile {
|
|
|
27
27
|
* Message content structure
|
|
28
28
|
*/
|
|
29
29
|
export interface MessageContent {
|
|
30
|
+
/**
|
|
31
|
+
* The message text.
|
|
32
|
+
*
|
|
33
|
+
* Declared as a string because that is what it is for every role a reader
|
|
34
|
+
* cares about, but do not trust it blindly on a `guard_rail` message:
|
|
35
|
+
* conversations stopped by a guardrail before the backend fix carry the raw
|
|
36
|
+
* provider result object here instead. Guard a `typeof x === 'string'` check
|
|
37
|
+
* around anything that treats it as text.
|
|
38
|
+
*/
|
|
30
39
|
message?: string;
|
|
31
40
|
data?: any;
|
|
32
41
|
files?: MessageFile[];
|
|
@@ -53,7 +62,7 @@ export interface ToolCall {
|
|
|
53
62
|
*/
|
|
54
63
|
export interface ChatMessage {
|
|
55
64
|
uid: string;
|
|
56
|
-
role: 'user' | 'assistant' | 'developer' | 'system' | 'tool';
|
|
65
|
+
role: 'user' | 'assistant' | 'developer' | 'system' | 'tool' | 'guard_rail';
|
|
57
66
|
content: MessageContent;
|
|
58
67
|
timestamp: number;
|
|
59
68
|
chatUid?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../src/api/types.ts"],"sourcesContent":["import type { AvatarStyle } from '../utils/avatar';\n\nimport type React from 'react';\n\n/**\n * File attachment for messages\n */\nexport interface ChatFile {\n name: string;\n downloadUrl?: string;\n fileType?: 'image' | 'document' | 'audio' | 'video' | 'other';\n}\n\n/**\n * Attachment as it appears on a message.\n *\n * Two shapes reach the UI for the same thing: the optimistic message built\n * locally on send uses `url`/`type`, while the history returned by the API\n * carries the stored `downloadUrl`/`fileType`. Both are accepted here; use\n * `normalizeMessageFile` before reading them.\n */\nexport interface MessageFile {\n name: string;\n url?: string;\n type?: string;\n downloadUrl?: string;\n fileType?: string;\n}\n\n/**\n * Message content structure\n */\nexport interface MessageContent {\n message?: string;\n data?: any;\n files?: MessageFile[];\n}\n\n/** Collapse either attachment shape into a single one the UI can render. */\nexport function normalizeMessageFile(file: MessageFile): {\n name: string;\n url: string;\n type: string;\n} {\n return {\n name: file.name,\n url: file.url || file.downloadUrl || '',\n type: file.type || file.fileType || 'other',\n };\n}\n\n/**\n * Tool call from the model\n */\nexport interface ToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * Chat message structure\n */\nexport interface ChatMessage {\n uid: string;\n role: 'user' | 'assistant' | 'developer' | 'system' | 'tool';\n content: MessageContent;\n timestamp: number;\n chatUid?: string;\n tool_calls?: ToolCall[];\n tool_call_id?: string;\n summary?: string;\n /**\n * Where `content.message` came from, when the model did not write it.\n * `'finish_tool'`: the assistant is configured to require a tool call to\n * finish (\"Require Tool Use to Finish\") and the backend lifted the reply from\n * the finish tool's `message` argument, so it can be read without parsing\n * tool calls. Absent on replies the model wrote itself — use it to label the\n * bubble as produced by the tool.\n */\n contentSource?: string;\n /**\n * Id of a speech-to-text transcript (from POST /api/v1/whisper) that seeded\n * this message. Present on user messages dictated by voice; the chat can use\n * it to fetch the source audio (GET /api/v1/whisper/:transcriptId) and offer\n * playback.\n */\n transcriptId?: string;\n /**\n * Original server uid, present when the UI adopted an optimistic uid for\n * this message to keep React keys stable. Server-side references (e.g.\n * memory recall anchors) match against it.\n */\n serverUid?: string;\n /**\n * Client-side only: the conversation was busy when this message was sent, so\n * it was accepted into the queue and is waiting its turn. Drawn as a message\n * that has not landed rather than as part of the conversation. Falls away on\n * its own once the message comes back inside the history.\n */\n queued?: boolean;\n /**\n * Client-side only: when this message was accepted into the queue. Used to\n * tell \"the server has not reported it yet\" from \"the server no longer has\n * it\", which the timestamp is the only honest way to decide.\n */\n queuedAt?: number;\n}\n\n/**\n * Previous conversation message for initialization\n */\nexport interface PreviousMessage {\n message: string;\n role: 'user' | 'assistant';\n}\n\n/**\n * Model interface tool schema following OpenAI function calling format\n */\nexport interface ModelInterfaceToolSchema {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: {\n type: 'object';\n properties: Record<string, any>;\n required?: string[];\n };\n };\n}\n\n/**\n * Props passed to a response widget component.\n * The widget is responsible for collecting the user's response and\n * calling `submit` with the payload to resolve the tool call.\n */\nexport interface ResponseWidgetProps {\n /** The tool call this widget is responding to */\n toolCall: ToolCall;\n /** Parsed arguments from the tool call */\n params: any;\n /** Submit the tool response payload (sent as the tool call result to the model) */\n submit: (response: any) => void;\n /** Cancel the tool call. Sends an error response so the model can continue. */\n cancel?: (reason?: string) => void;\n /** Whether the widget is currently submitting */\n isSubmitting?: boolean;\n}\n\n/**\n * Interactive response widget configuration for a client-side tool.\n *\n * When the model calls a tool configured with a `responseWidget`, the\n * widget is rendered in the chat UI instead of executing a callback.\n * The user interacts with the widget, which calls `submit(response)` to\n * define the tool response sent back to the model.\n *\n * - `render: 'inline'` renders the widget in the message thread at the\n * position of the tool call. The text input remains enabled.\n * - `render: 'input'` replaces the chat input area with the widget\n * while it is pending. The text input is disabled until submission.\n */\nexport interface ResponseWidgetConfig {\n /** Where to render the widget */\n render: 'inline' | 'input';\n /** The widget component */\n component: React.ComponentType<ResponseWidgetProps>;\n}\n\n/**\n * Model interface tool definition for client-side tools.\n *\n * A tool must provide either a `callback` (executed automatically when\n * the model invokes the tool) or a `responseWidget` (renders UI for\n * the user to produce the tool response). Providing both is an error.\n */\nexport interface ModelInterfaceTool {\n toolName: string;\n schema: ModelInterfaceToolSchema;\n /** Executed automatically when the model calls this tool */\n callback?: (params: any) => Promise<any> | any;\n /** Interactive widget that collects the user's tool response */\n responseWidget?: ResponseWidgetConfig;\n}\n\n/**\n * Tool call response to send back to the API\n */\nexport interface ToolCallResponse {\n tool_call_id: string;\n content: any;\n role: 'tool';\n /**\n * The client-side tools still on offer for the rest of the turn. The API\n * reads them off the first response of the batch: leaving them out drops\n * the tools from the continuation, so the model cannot call them again.\n */\n tools?: ModelInterfaceToolSchema[];\n}\n\n/**\n * DTO for sending messages to the assistant\n */\nexport interface ProcessMessageDto {\n message: string;\n chatUid?: string;\n userName?: string;\n files?: ChatFile[];\n /** Tags to associate with this chat (top-level, distinct from `metadata`). */\n tags?: string[];\n metadata?: {\n promptTemplateParams?: Record<string, any>;\n tenantToken?: string;\n [key: string]: any;\n };\n tenantId?: string;\n previousConversation?: PreviousMessage[];\n enabledTools?: string[];\n provider?: string;\n model?: string;\n // Model interface protocol fields\n tools?: ModelInterfaceToolSchema[];\n applicationState?: Record<string, any>;\n skipSummarization?: boolean;\n /**\n * Id of a speech-to-text transcript (from POST /api/v1/whisper) that seeded\n * this message. Sent so the conversation keeps a link to the original audio.\n */\n transcriptId?: string;\n}\n\n/**\n * Response from the /whisper speech-to-text endpoint.\n */\nexport interface WhisperTranscriptionResponse {\n /** Public id of the transcript; send it back as ProcessMessageDto.transcriptId. */\n transcriptId: string;\n /** Transcribed text. */\n text: string;\n /** Language hint used, if any. */\n language?: string;\n /** Download URL of the source audio. */\n audioUrl?: string;\n /** Transcription model used. */\n model?: string;\n}\n\n/**\n * Response from the assistant\n */\nexport interface AssistantResponse {\n messages: ChatMessage[];\n chatUid: string;\n inputTokens?: number;\n outputTokens?: number;\n}\n\n/**\n * Async mode response\n */\nexport interface AsyncResponse {\n chatUid: string;\n message?: string;\n error?: string;\n /**\n * The conversation could not take the message right now, so it was queued\n * instead of starting a run of its own. Still an acceptance: the answer comes\n * later, and may cover several messages at once.\n */\n queued?: boolean;\n /** How many messages are queued on this conversation, this one included. */\n queuePosition?: number;\n /** When the queued message reaches the model. */\n willProcess?: QueueDisposition;\n}\n\n/**\n * When a queued message will reach the model.\n *\n * `after_delay` is the one that is not about being busy: an idle conversation\n * on an assistant with an input delay collects what is written during the\n * window, so a message can come back queued with nothing in flight at all.\n */\nexport type QueueDisposition = 'after_delay' | 'next_turn' | 'on_resume';\n\n/** Response of the stop endpoint. */\nexport interface StopChatResponse {\n chatUid: string;\n message: string;\n /**\n * Queued messages the stop threw away — answering them would be the opposite\n * of what was asked. Handed back so their text can be put where the user\n * wrote it. Absent on an API older than this, and when nothing was queued.\n */\n discardedMessages?: ChatMessage[];\n}\n\n/**\n * Real-time chat history status.\n * `limit_exceeded` means the message was blocked before reaching the LLM\n * because a configured tenant/subtenant usage limit was reached.\n */\nexport type RealtimeStatus =\n | 'processing'\n | 'completed'\n | 'error'\n | 'waiting_for_tool_response'\n | 'handed_off'\n | 'limit_exceeded'\n /** Collecting messages during the assistant's input delay, before any run. */\n | 'buffering';\n\n/**\n * Details of a tenant/subtenant usage limit that blocked a message.\n * Returned on the realtime endpoint when status is `limit_exceeded`, and on\n * the HTTP 429 body (`details`) when a synchronous request is blocked.\n */\nexport interface TenantLimitExceeded {\n /** Human-readable message describing the block. */\n message?: string;\n /** The rule that triggered the block (scope, metric, window, limit…). */\n blockingRule?: {\n scope?: 'tenant' | 'subtenant';\n subtenantId?: string;\n metric?: 'tokens' | 'cost';\n windowUnit?: 'hour' | 'day' | 'week' | 'month';\n windowEvery?: number;\n limit?: number;\n };\n /** Current consumption in the blocking window. */\n current?: number;\n /** The limit that was reached. */\n limit?: number;\n /** Epoch ms when the blocking window resets and usage is allowed again. */\n resetsAt?: number;\n}\n\n/** One fact a long-term-memory recall surfaced. */\nexport interface RecalledMemoryFact {\n fact: string;\n relation: string;\n /** Source entity name of the graph edge, when the fact connects two. */\n source: string | null;\n /** Target entity name of the graph edge, when the fact connects two. */\n target: string | null;\n /** ISO date the fact became valid, if known. */\n validAt: string | null;\n}\n\n/** One graph entity a long-term-memory recall surfaced. */\nexport interface RecalledMemoryEntity {\n id: string;\n name: string;\n type: string;\n summary: string | null;\n}\n\n/** One previous-session turn a conversation-start recall carried over. */\nexport interface RecalledMemoryTurn {\n role: string;\n content: string;\n}\n\n/**\n * One structured long-term-memory recall event of a conversation: the facts,\n * entities and previous-session turns a recall surfaced, plus the uid of the\n * message that brought it in (`messageUid`: the initial user message, or the\n * assistant message carrying the memory tool call — resolvable through\n * `toolCallId` while the run is still in flight).\n */\nexport interface RecalledMemoryRecord {\n uid: string;\n messageUid?: string;\n toolCallId?: string;\n source:\n | 'conversation_start'\n | 'search_memory'\n | 'search_memory_nodes'\n | 'explore_memory_graph';\n query?: string;\n facts?: RecalledMemoryFact[];\n entities?: RecalledMemoryEntity[];\n turns?: RecalledMemoryTurn[];\n timestampMs: number;\n}\n\n/**\n * Snapshot of the core-memory block a conversation saw (audit trail): the\n * render revision plus the injected entries as structured items.\n */\nexport interface CoreMemorySnapshot {\n uid: string;\n revision: string;\n items: Array<{\n id: number;\n section: string;\n content: string;\n pinned: boolean;\n source: string;\n }>;\n entries: number;\n omitted: number;\n chars: number;\n timestampMs: number;\n}\n\n/**\n * Real-time chat history response\n */\nexport interface RealtimeChatHistory {\n chatUID: string;\n clientUID: string;\n chatHistory: ChatMessage[];\n status: RealtimeStatus;\n lastUpdatedAt: number;\n pendingToolCalls?: ToolCall[];\n handedOffSubThreadId?: string;\n /** Present only when status is `limit_exceeded`. */\n limitExceeded?: TenantLimitExceeded;\n /**\n * Memory-recall events of the in-flight run — lets the UI show what the\n * assistant is recalling while the response is still processing.\n */\n recalledMemories?: RecalledMemoryRecord[];\n /**\n * Messages accepted into this conversation that the model has not seen yet.\n * Non-zero means more is coming: a `completed` status with messages still\n * queued is not the end of the exchange.\n */\n queuedMessages?: number;\n /**\n * The queued messages themselves. This is the conversation's queue, not the\n * caller's — it can include messages the same conversation received through\n * another channel. Absent on an API that does not return them, in which case\n * the widget falls back to its own optimistic copies.\n */\n pendingUserMessages?: ChatMessage[];\n /**\n * Compaction checkpoints of the in-flight run. A conversation that compacts\n * mid-run stops sending the messages above the cut immediately, so these\n * arrive here before they are persisted on the conversation.\n */\n compactions?: CompactionCheckpoint[];\n /** The compaction running right now, if any. */\n compaction?: CompactionActivity;\n}\n\n/**\n * A single usage rule with its current consumption (from GET\n * /api/v1/tenant-usage/:tenantId[/subtenants/:subtenantId]).\n */\nexport interface TenantUsageRule {\n scope: 'tenant' | 'subtenant';\n subtenantId?: string;\n metric: 'tokens' | 'cost';\n windowUnit: 'hour' | 'day' | 'week' | 'month';\n windowEvery: number;\n /** Configured limit for the window. */\n limit: number;\n /** Current consumption in the active window. */\n current: number;\n /** Utilization percentage (0..100, capped). */\n percent: number;\n /** Epoch ms when the active window resets. */\n resetsAt?: number;\n /** Where the rule comes from ('tier' | 'adhoc'). */\n origin?: string;\n /** Tier the rule belongs to, if any. */\n tierId?: string;\n}\n\n/**\n * Response of GET /api/v1/tenant-usage/:tenantId[/subtenants/:subtenantId]:\n * the effective usage rules with their current consumption + the active tier.\n */\nexport interface TenantUsage {\n tenantId: string;\n subtenantId?: string;\n tierId?: string;\n usage: TenantUsageRule[];\n}\n\n/**\n * A durable per-window usage history row (from GET\n * /api/v1/tenant-usage/:tenantId/history).\n */\nexport interface TenantUsageHistoryRow {\n clientUID: string;\n tenantId: string;\n subtenantId: string;\n scope: 'tenant' | 'subtenant';\n metric: 'tokens' | 'cost';\n windowUnit: 'hour' | 'day' | 'week' | 'month';\n windowEvery: number;\n windowKey: string;\n windowStart: number;\n windowEnd: number;\n /** Counted consumption (enforced). */\n consumption: number;\n /** Exempt consumption that did not count toward the limit, if any. */\n exemptConsumption?: number;\n limit: number;\n percent: number;\n tierId?: string;\n origin?: string;\n capturedAt: number;\n}\n\n/**\n * Options for querying tenant usage history.\n */\nexport interface TenantUsageHistoryQuery {\n subtenantId?: string;\n scope?: 'tenant' | 'subtenant';\n metric?: 'tokens' | 'cost';\n windowUnit?: 'hour' | 'day' | 'week' | 'month';\n /** Epoch ms lower bound (windowEnd >= from). */\n from?: number;\n /** Epoch ms upper bound (windowEnd <= to). */\n to?: number;\n limit?: number;\n skip?: number;\n}\n\n/**\n * Chat history structure\n */\n/** A concrete value carried verbatim through a compaction. */\nexport interface CompactionFact {\n kind: string;\n value: string;\n label?: string;\n}\n\n/** The structured body a compaction produced. */\nexport interface CompactionSummary {\n goal?: string;\n constraints?: string[];\n inProgress?: string;\n pending?: string[];\n decisions?: string[];\n data?: Array<{ label: string; value: string }>;\n done?: string[];\n openQuestions?: string[];\n /** Fallback when the model answered without structure. */\n raw?: string;\n}\n\n/**\n * One compaction of a conversation: the messages before its boundary folded\n * into a written summary plus the identifiers, paths and urls lifted out of\n * them verbatim. From then on the model receives the checkpoint instead of\n * those messages — which are still in the conversation, and still shown.\n *\n * Only the newest checkpoint is in force: each compaction merges the previous\n * summary into itself.\n */\nexport interface CompactionCheckpoint {\n uid: string;\n /** 1 for the first compaction of the conversation, 2 for the next… */\n index: number;\n timestampMs: number;\n trigger: 'auto' | 'manual';\n /** First message that still travels verbatim. */\n firstKeptMessageUid?: string;\n /** Last folded message: where the widget belongs in the conversation. */\n anchorMessageUid?: string;\n compactedMessageCount: number;\n summary: CompactionSummary;\n facts: CompactionFact[];\n tokensBefore: number;\n tokensAfter: number;\n provider?: string;\n model?: string;\n cost?: number;\n}\n\n/**\n * A compaction happening right now, from the realtime endpoint.\n *\n * A compaction is a model call of its own, taken between two assistant\n * messages, so a client that only knows `processing` shows a conversation\n * that appears to have stalled for a few seconds. Present while it runs and\n * on the single update that reports it finished.\n */\nexport interface CompactionActivity {\n state: 'running' | 'completed';\n startedAt: number;\n /**\n * What this pass is folding: the messages new since the last checkpoint.\n * Not the conversation's totals — a checkpoint's own\n * `compactedMessageCount` and `tokensBefore` are cumulative across every\n * compaction, so the two are on different scales and must not be paired.\n */\n messageCount: number;\n tokensBefore: number;\n /** Which checkpoint the pass produced, once it is done. */\n index?: number;\n finishedAt?: number;\n}\n\nexport interface ChatHistory {\n chatUID: string;\n clientUID: string;\n userUID: string;\n chatContent: ChatMessage[];\n name?: string;\n assistantSpecializationIdentifier: string;\n creationTimestampMs: number;\n lastEditTimestampMs?: number;\n llm?: string;\n inputTokens?: number;\n outputTokens?: number;\n metadata?: Record<string, any>;\n tenantId?: string;\n handedOff?: boolean;\n handedOffSubThreadId?: string;\n handedOffToolCallId?: string;\n /** Structured long-term-memory recall events of the conversation. */\n recalledMemories?: RecalledMemoryRecord[];\n /** Audit trail of the core-memory blocks the conversation saw. */\n coreMemories?: CoreMemorySnapshot[];\n /** Compaction checkpoints of the conversation, oldest first. */\n compactions?: CompactionCheckpoint[];\n}\n\n/** One core memory entry (the always-injected tier), as returned by the memory API. */\nexport interface CoreMemoryEntry {\n id: number;\n section: string;\n content: string;\n source: string;\n pinned: boolean;\n supersedes: number | null;\n archivedAt: string | null;\n createdAt?: string;\n updatedAt?: string;\n}\n\n/** Deployment caps of the core memory tier. */\nexport interface CoreMemoryLimits {\n maxChars: number;\n maxEntries: number;\n maxEntryChars: number;\n}\n\n/**\n * Response of GET /api/v1/memory/assistants/:identifier/core — the entries\n * of the bucket the assistant resolves for a tenant/subtenant combination.\n */\nexport interface CoreMemoryList {\n /** False when the assistant does not have the core memory tier enabled. */\n enabled: boolean;\n /** The resolved bucket tuple (tenant/subtenant/owner dimensions). */\n bucket: { tenantId?: string; subtenantId?: string; entityId?: string };\n entries: CoreMemoryEntry[];\n limits?: CoreMemoryLimits;\n}\n\n/**\n * Assistant specialization info\n */\nexport interface AssistantSpecialization {\n identifier: string;\n name: string;\n description: string;\n state: 'active' | 'inactive' | 'coming_soon';\n imgUrl?: string;\n /** Pinned style of the generated avatar shown when there is no imgUrl. */\n avatarStyle?: AvatarStyle;\n availableToolsGroups?: Array<{\n name: string;\n description?: string;\n uid?: string;\n iconUrl?: string;\n tools?: Array<{\n name: string;\n description: string;\n }>;\n }>;\n model?: string;\n isCustom?: boolean;\n creationTimestampMs?: number;\n /**\n * Whether this assistant offers MCP servers of the tenant's own.\n *\n * Same contract as `tenantIntegrations` below, absence included.\n */\n tenantMcpServers?: {\n enabled: boolean;\n /** Servers listed ready to connect. Says nothing about how many are connected. */\n count?: number;\n };\n /**\n * Whether this assistant offers connected apps to its tenants.\n *\n * **Absent means \"cannot tell\", not \"no\"** — an API older than this field\n * says nothing, and treating silence as a no would hide the connected-apps\n * button from anyone whose deployment has not caught up yet.\n */\n tenantIntegrations?: {\n enabled: boolean;\n /**\n * How many apps the catalogue offers. An upper bound — the listing drops\n * any the provider cannot resolve — and enough to size a placeholder.\n */\n count?: number;\n };\n /**\n * Whether this assistant accepts messages sent while the conversation is\n * busy, queueing them instead of refusing them.\n *\n * **Absent means no**, unlike `tenantIntegrations` above. Promising a queue\n * that does not exist is paid for with a 409 and with the user's text left in\n * the air, so silence is read as the safe answer rather than as the open one.\n */\n messageQueueEnabled?: boolean;\n /** How many messages may wait at once before further sends are refused. */\n maxQueuedMessages?: number;\n}\n\n/**\n * Summary of a conversation for listing\n */\nexport interface ConversationSummary {\n chatUID: string;\n name?: string;\n creationTimestampMs: number;\n lastEditTimestampMs?: number;\n}\n\nexport interface ListConversationsResponse {\n histories: ConversationSummary[];\n total: number;\n offset: number;\n limit: number;\n}\n\n/**\n * API error response\n */\nexport interface ApiError {\n statusCode: number;\n message: string;\n error?: string;\n /** Optional structured details (e.g. usage-limit blocking info on a 429). */\n details?: any;\n}\n\n/**\n * Feedback submission request\n */\nexport interface FeedbackSubmission {\n messageId: string;\n feedback?: boolean;\n feedbackComment?: string;\n feedbackData?: Record<string, any>;\n}\n\n/**\n * Feedback entry response\n */\nexport interface FeedbackEntry {\n _id: string;\n requestId: string;\n chatUID?: string;\n threadId?: string;\n agentId?: string;\n feedback?: boolean;\n feedbackComment?: string;\n feedbackData?: Record<string, any>;\n creationTimestamp: string;\n lastEditTimestamp?: string;\n}\n\n/**\n * Agent thread states\n */\nexport enum AgentThreadState {\n QUEUED = 'queued',\n PROCESSING = 'processing',\n COMPLETED = 'completed',\n FAILED = 'failed',\n TERMINATED = 'terminated',\n PAUSED = 'paused',\n PAUSED_FOR_APPROVAL = 'paused_for_approval',\n APPROVAL_REJECTED = 'approval_rejected',\n WAITING_FOR_RESPONSE = 'waiting_for_response',\n PAUSED_FOR_RESUME = 'paused_for_resume',\n HANDED_OFF = 'handed_off',\n GUARDRAIL_TRIGGER = 'guardrail_trigger',\n}\n\n/**\n * Task within an agent thread\n */\nexport interface AgentTaskDto {\n _id?: string;\n title?: string;\n description?: string;\n completed: boolean;\n}\n\n/**\n * Agent thread DTO\n */\nexport interface AgentThreadDto {\n _id?: string;\n agentId: string;\n state: AgentThreadState;\n threadContent: ChatMessage[];\n tasks?: AgentTaskDto[];\n finishReason?: string;\n pausedReason?: string;\n name?: string;\n creationTimestampMs?: number;\n lastEditTimestampMs?: number;\n pauseUntil?: number;\n isSubthread?: boolean;\n parentThreadId?: string;\n subThreadToolCallId?: string;\n parentAgentId?: string;\n}\n\n/**\n * Agent details\n */\nexport interface AgentDto {\n _id?: string;\n name: string;\n description?: string;\n imgUrl?: string;\n /** Pinned style of the generated avatar shown when there is no imgUrl. */\n avatarStyle?: AvatarStyle;\n agentId?: string;\n}\n\n/**\n * Hand-off tool response content\n */\nexport interface HandOffToolResponse {\n response: string;\n subthreadId: string;\n}\n\n/**\n * Represents a single tool call within a tool group\n */\nexport interface ToolGroupCall {\n name: string;\n input: any;\n output: any;\n toolCallId: string;\n}\n\n/**\n * Configuration for grouping consecutive tool calls under a single renderer\n */\nexport interface ToolGroupConfig {\n tools: string[];\n renderer: (calls: ToolGroupCall[]) => React.ReactNode;\n}\n\n/**\n * One of the end user's connected accounts for an app.\n *\n * The provider's own identifiers do not travel here beyond `id`, which the\n * client needs in order to name the account it wants disconnected — and which\n * the server re-checks against the caller's tenant on the way back in.\n */\nexport interface IntegrationAccount {\n id: string;\n status: string;\n connectedAt?: string;\n updatedAt?: string;\n /** True when the account exists but can no longer run tools. */\n needsReconnect?: boolean;\n statusReason?: string;\n}\n\n/**\n * One value the end user is asked for before an account can be connected —\n * their API key, the subdomain of their instance.\n *\n * Comes from the provider's own catalogue, so the form is rendered from this\n * rather than from anything app-specific: most apps do not authenticate with\n * credentials Devic holds, and there are hundreds of them.\n */\nexport interface IntegrationAuthField {\n name: string;\n label: string;\n type: string;\n required: boolean;\n description?: string;\n /** Prefilled — usually a provider endpoint most accounts should keep. */\n default?: string;\n /** Mask it on screen. */\n secret: boolean;\n}\n\n/**\n * One way of connecting an app.\n *\n * `redirect` schemes send the user to the provider; the rest are connected\n * with the values they type, without ever leaving the page.\n *\n * There is deliberately no field for the *application's* credentials: the\n * OAuth application belongs to the developer who embedded this widget, is\n * registered once for every tenant, and is never the end user's to supply.\n */\nexport interface IntegrationAuthScheme {\n /** The provider's own name for it: `OAUTH2`, `API_KEY`, … */\n mode: string;\n /** Credentials for this scheme are held for you — nothing to fill in. */\n composioManaged: boolean;\n redirect: boolean;\n /** What this account supplies. Empty for a scheme that asks nothing. */\n accountFields: IntegrationAuthField[];\n /** The provider's own setup guide, when there is one. */\n guideUrl?: string;\n}\n\n/**\n * The answer when connecting needs values that were not sent.\n *\n * `stage` decides who can act on it: `account` is the end user, and the form\n * asks them. `app` is the developer's OAuth application, which the end user\n * cannot register — so that case is shown as \"not available yet\" instead of a\n * form asking a stranger for someone else's client secret.\n */\nexport interface IntegrationSetupRequired {\n code: \"INTEGRATION_SETUP_REQUIRED\";\n message: string;\n toolkit: string;\n authScheme: string;\n stage: \"app\" | \"account\";\n fields: IntegrationAuthField[];\n guideUrl?: string;\n}\n\n/**\n * An app the assistant offers to its tenants, with the accounts THIS tenant\n * has connected. Never another tenant's.\n */\nexport interface Integration {\n /** App slug, e.g. `gmail`. */\n app: string;\n name: string;\n description?: string;\n logo?: string;\n /** True when at least one account is active. */\n connected: boolean;\n accounts: IntegrationAccount[];\n /** Event types the developer allows this tenant to switch on. */\n availableTriggers?: string[];\n}\n\n// ── MCP servers the end user connects for themselves ──────────────────────\n\nexport type TenantMcpAuthMode = \"oauth\" | \"header\" | \"none\";\n\n/** One of the end user's own MCP connections. */\nexport interface TenantMcpConnection {\n id: string;\n /**\n * What to put in `disabledIntegrations` to have this server sit a message\n * out. Sent by the API so the prefix that separates it from an app slug lives\n * on the server, in one place.\n */\n toggleId?: string;\n name?: string;\n url: string;\n /** The developer's template this came from, when it came from one. */\n templateId?: string;\n authMode?: TenantMcpAuthMode;\n status: \"pending_auth\" | \"active\" | \"error\";\n toolCount?: number;\n tools?: string[];\n lastProbeStatus?: string;\n lastProbeError?: string;\n lastProbeTimestampMs?: number;\n /** Connected for the whole tenant, so every end user of it shares this. */\n shared: boolean;\n /** True when this end user may use it but not change or remove it. */\n readOnly: boolean;\n}\n\n/**\n * One row of the MCP panel: either a server the developer offers ready to\n * connect, or one this end user added.\n *\n * A single list rather than two, because that is what the panel draws — keeping\n * \"offered\" and \"connected\" apart would leave them out of step for a moment\n * after every connect.\n */\nexport interface TenantMcpServer {\n source: \"template\" | \"custom\";\n templateId?: string;\n name: string;\n url: string;\n description?: string;\n logoUrl?: string;\n authMode?: TenantMcpAuthMode;\n /** Header the credential travels in, for `header` servers. */\n headerName?: string;\n /** Whether the end user may supply their own OAuth application. */\n allowClientCredentials?: boolean;\n /** Null until this tenant connects it. */\n connection: TenantMcpConnection | null;\n}\n\nexport interface TenantMcpListing {\n offered: boolean;\n /** Whether adding a server of one's own is permitted. */\n allowCustom: boolean;\n limits: { maxServers: number; maxToolsPerServer: number; used: number };\n servers: TenantMcpServer[];\n}\n\n/** Credentials the end user supplies when connecting a server. */\nexport interface TenantMcpAuthInput {\n mode?: TenantMcpAuthMode;\n headerName?: string;\n headerValue?: string;\n upstreamOAuth?: { clientId?: string; clientSecret?: string; scopes?: string[] };\n}\n\n/**\n * What connecting answers with.\n *\n * `status: \"active\"` means it is done. `authorizationUrl` must be opened in a\n * popup. `requiresClientCredentials` means the server has no dynamic client\n * registration and the end user has to register an OAuth application with it\n * themselves, authorising `callbackUrl` as the redirect URI.\n */\nexport interface TenantMcpConnectResult {\n id: string;\n status: \"pending_auth\" | \"active\" | \"error\";\n toolCount?: number;\n authorizationUrl?: string;\n requiresClientCredentials?: boolean;\n callbackUrl?: string;\n error?: string;\n}\n"],"names":[],"mappings":"AAsCA;AACM,SAAU,oBAAoB,CAAC,IAAiB,EAAA;IAKpD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE;QACvC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,OAAO;KAC5C;AACH;AA2tBA;;AAEG;IACS;AAAZ,CAAA,UAAY,gBAAgB,EAAA;AAC1B,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,gBAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AACzB,IAAA,gBAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,gBAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AACzB,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,gBAAA,CAAA,qBAAA,CAAA,GAAA,qBAA2C;AAC3C,IAAA,gBAAA,CAAA,mBAAA,CAAA,GAAA,mBAAuC;AACvC,IAAA,gBAAA,CAAA,sBAAA,CAAA,GAAA,sBAA6C;AAC7C,IAAA,gBAAA,CAAA,mBAAA,CAAA,GAAA,mBAAuC;AACvC,IAAA,gBAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AACzB,IAAA,gBAAA,CAAA,mBAAA,CAAA,GAAA,mBAAuC;AACzC,CAAC,EAbW,gBAAgB,KAAhB,gBAAgB,GAAA,EAAA,CAAA,CAAA;;"}
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../src/api/types.ts"],"sourcesContent":["import type { AvatarStyle } from '../utils/avatar';\n\nimport type React from 'react';\n\n/**\n * File attachment for messages\n */\nexport interface ChatFile {\n name: string;\n downloadUrl?: string;\n fileType?: 'image' | 'document' | 'audio' | 'video' | 'other';\n}\n\n/**\n * Attachment as it appears on a message.\n *\n * Two shapes reach the UI for the same thing: the optimistic message built\n * locally on send uses `url`/`type`, while the history returned by the API\n * carries the stored `downloadUrl`/`fileType`. Both are accepted here; use\n * `normalizeMessageFile` before reading them.\n */\nexport interface MessageFile {\n name: string;\n url?: string;\n type?: string;\n downloadUrl?: string;\n fileType?: string;\n}\n\n/**\n * Message content structure\n */\nexport interface MessageContent {\n /**\n * The message text.\n *\n * Declared as a string because that is what it is for every role a reader\n * cares about, but do not trust it blindly on a `guard_rail` message:\n * conversations stopped by a guardrail before the backend fix carry the raw\n * provider result object here instead. Guard a `typeof x === 'string'` check\n * around anything that treats it as text.\n */\n message?: string;\n data?: any;\n files?: MessageFile[];\n}\n\n/** Collapse either attachment shape into a single one the UI can render. */\nexport function normalizeMessageFile(file: MessageFile): {\n name: string;\n url: string;\n type: string;\n} {\n return {\n name: file.name,\n url: file.url || file.downloadUrl || '',\n type: file.type || file.fileType || 'other',\n };\n}\n\n/**\n * Tool call from the model\n */\nexport interface ToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * Chat message structure\n */\nexport interface ChatMessage {\n uid: string;\n role: 'user' | 'assistant' | 'developer' | 'system' | 'tool' | 'guard_rail';\n content: MessageContent;\n timestamp: number;\n chatUid?: string;\n tool_calls?: ToolCall[];\n tool_call_id?: string;\n summary?: string;\n /**\n * Where `content.message` came from, when the model did not write it.\n * `'finish_tool'`: the assistant is configured to require a tool call to\n * finish (\"Require Tool Use to Finish\") and the backend lifted the reply from\n * the finish tool's `message` argument, so it can be read without parsing\n * tool calls. Absent on replies the model wrote itself — use it to label the\n * bubble as produced by the tool.\n */\n contentSource?: string;\n /**\n * Id of a speech-to-text transcript (from POST /api/v1/whisper) that seeded\n * this message. Present on user messages dictated by voice; the chat can use\n * it to fetch the source audio (GET /api/v1/whisper/:transcriptId) and offer\n * playback.\n */\n transcriptId?: string;\n /**\n * Original server uid, present when the UI adopted an optimistic uid for\n * this message to keep React keys stable. Server-side references (e.g.\n * memory recall anchors) match against it.\n */\n serverUid?: string;\n /**\n * Client-side only: the conversation was busy when this message was sent, so\n * it was accepted into the queue and is waiting its turn. Drawn as a message\n * that has not landed rather than as part of the conversation. Falls away on\n * its own once the message comes back inside the history.\n */\n queued?: boolean;\n /**\n * Client-side only: when this message was accepted into the queue. Used to\n * tell \"the server has not reported it yet\" from \"the server no longer has\n * it\", which the timestamp is the only honest way to decide.\n */\n queuedAt?: number;\n}\n\n/**\n * Previous conversation message for initialization\n */\nexport interface PreviousMessage {\n message: string;\n role: 'user' | 'assistant';\n}\n\n/**\n * Model interface tool schema following OpenAI function calling format\n */\nexport interface ModelInterfaceToolSchema {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: {\n type: 'object';\n properties: Record<string, any>;\n required?: string[];\n };\n };\n}\n\n/**\n * Props passed to a response widget component.\n * The widget is responsible for collecting the user's response and\n * calling `submit` with the payload to resolve the tool call.\n */\nexport interface ResponseWidgetProps {\n /** The tool call this widget is responding to */\n toolCall: ToolCall;\n /** Parsed arguments from the tool call */\n params: any;\n /** Submit the tool response payload (sent as the tool call result to the model) */\n submit: (response: any) => void;\n /** Cancel the tool call. Sends an error response so the model can continue. */\n cancel?: (reason?: string) => void;\n /** Whether the widget is currently submitting */\n isSubmitting?: boolean;\n}\n\n/**\n * Interactive response widget configuration for a client-side tool.\n *\n * When the model calls a tool configured with a `responseWidget`, the\n * widget is rendered in the chat UI instead of executing a callback.\n * The user interacts with the widget, which calls `submit(response)` to\n * define the tool response sent back to the model.\n *\n * - `render: 'inline'` renders the widget in the message thread at the\n * position of the tool call. The text input remains enabled.\n * - `render: 'input'` replaces the chat input area with the widget\n * while it is pending. The text input is disabled until submission.\n */\nexport interface ResponseWidgetConfig {\n /** Where to render the widget */\n render: 'inline' | 'input';\n /** The widget component */\n component: React.ComponentType<ResponseWidgetProps>;\n}\n\n/**\n * Model interface tool definition for client-side tools.\n *\n * A tool must provide either a `callback` (executed automatically when\n * the model invokes the tool) or a `responseWidget` (renders UI for\n * the user to produce the tool response). Providing both is an error.\n */\nexport interface ModelInterfaceTool {\n toolName: string;\n schema: ModelInterfaceToolSchema;\n /** Executed automatically when the model calls this tool */\n callback?: (params: any) => Promise<any> | any;\n /** Interactive widget that collects the user's tool response */\n responseWidget?: ResponseWidgetConfig;\n}\n\n/**\n * Tool call response to send back to the API\n */\nexport interface ToolCallResponse {\n tool_call_id: string;\n content: any;\n role: 'tool';\n /**\n * The client-side tools still on offer for the rest of the turn. The API\n * reads them off the first response of the batch: leaving them out drops\n * the tools from the continuation, so the model cannot call them again.\n */\n tools?: ModelInterfaceToolSchema[];\n}\n\n/**\n * DTO for sending messages to the assistant\n */\nexport interface ProcessMessageDto {\n message: string;\n chatUid?: string;\n userName?: string;\n files?: ChatFile[];\n /** Tags to associate with this chat (top-level, distinct from `metadata`). */\n tags?: string[];\n metadata?: {\n promptTemplateParams?: Record<string, any>;\n tenantToken?: string;\n [key: string]: any;\n };\n tenantId?: string;\n previousConversation?: PreviousMessage[];\n enabledTools?: string[];\n provider?: string;\n model?: string;\n // Model interface protocol fields\n tools?: ModelInterfaceToolSchema[];\n applicationState?: Record<string, any>;\n skipSummarization?: boolean;\n /**\n * Id of a speech-to-text transcript (from POST /api/v1/whisper) that seeded\n * this message. Sent so the conversation keeps a link to the original audio.\n */\n transcriptId?: string;\n}\n\n/**\n * Response from the /whisper speech-to-text endpoint.\n */\nexport interface WhisperTranscriptionResponse {\n /** Public id of the transcript; send it back as ProcessMessageDto.transcriptId. */\n transcriptId: string;\n /** Transcribed text. */\n text: string;\n /** Language hint used, if any. */\n language?: string;\n /** Download URL of the source audio. */\n audioUrl?: string;\n /** Transcription model used. */\n model?: string;\n}\n\n/**\n * Response from the assistant\n */\nexport interface AssistantResponse {\n messages: ChatMessage[];\n chatUid: string;\n inputTokens?: number;\n outputTokens?: number;\n}\n\n/**\n * Async mode response\n */\nexport interface AsyncResponse {\n chatUid: string;\n message?: string;\n error?: string;\n /**\n * The conversation could not take the message right now, so it was queued\n * instead of starting a run of its own. Still an acceptance: the answer comes\n * later, and may cover several messages at once.\n */\n queued?: boolean;\n /** How many messages are queued on this conversation, this one included. */\n queuePosition?: number;\n /** When the queued message reaches the model. */\n willProcess?: QueueDisposition;\n}\n\n/**\n * When a queued message will reach the model.\n *\n * `after_delay` is the one that is not about being busy: an idle conversation\n * on an assistant with an input delay collects what is written during the\n * window, so a message can come back queued with nothing in flight at all.\n */\nexport type QueueDisposition = 'after_delay' | 'next_turn' | 'on_resume';\n\n/** Response of the stop endpoint. */\nexport interface StopChatResponse {\n chatUid: string;\n message: string;\n /**\n * Queued messages the stop threw away — answering them would be the opposite\n * of what was asked. Handed back so their text can be put where the user\n * wrote it. Absent on an API older than this, and when nothing was queued.\n */\n discardedMessages?: ChatMessage[];\n}\n\n/**\n * Real-time chat history status.\n * `limit_exceeded` means the message was blocked before reaching the LLM\n * because a configured tenant/subtenant usage limit was reached.\n */\nexport type RealtimeStatus =\n | 'processing'\n | 'completed'\n | 'error'\n | 'waiting_for_tool_response'\n | 'handed_off'\n | 'limit_exceeded'\n /** Collecting messages during the assistant's input delay, before any run. */\n | 'buffering';\n\n/**\n * Details of a tenant/subtenant usage limit that blocked a message.\n * Returned on the realtime endpoint when status is `limit_exceeded`, and on\n * the HTTP 429 body (`details`) when a synchronous request is blocked.\n */\nexport interface TenantLimitExceeded {\n /** Human-readable message describing the block. */\n message?: string;\n /** The rule that triggered the block (scope, metric, window, limit…). */\n blockingRule?: {\n scope?: 'tenant' | 'subtenant';\n subtenantId?: string;\n metric?: 'tokens' | 'cost';\n windowUnit?: 'hour' | 'day' | 'week' | 'month';\n windowEvery?: number;\n limit?: number;\n };\n /** Current consumption in the blocking window. */\n current?: number;\n /** The limit that was reached. */\n limit?: number;\n /** Epoch ms when the blocking window resets and usage is allowed again. */\n resetsAt?: number;\n}\n\n/** One fact a long-term-memory recall surfaced. */\nexport interface RecalledMemoryFact {\n fact: string;\n relation: string;\n /** Source entity name of the graph edge, when the fact connects two. */\n source: string | null;\n /** Target entity name of the graph edge, when the fact connects two. */\n target: string | null;\n /** ISO date the fact became valid, if known. */\n validAt: string | null;\n}\n\n/** One graph entity a long-term-memory recall surfaced. */\nexport interface RecalledMemoryEntity {\n id: string;\n name: string;\n type: string;\n summary: string | null;\n}\n\n/** One previous-session turn a conversation-start recall carried over. */\nexport interface RecalledMemoryTurn {\n role: string;\n content: string;\n}\n\n/**\n * One structured long-term-memory recall event of a conversation: the facts,\n * entities and previous-session turns a recall surfaced, plus the uid of the\n * message that brought it in (`messageUid`: the initial user message, or the\n * assistant message carrying the memory tool call — resolvable through\n * `toolCallId` while the run is still in flight).\n */\nexport interface RecalledMemoryRecord {\n uid: string;\n messageUid?: string;\n toolCallId?: string;\n source:\n | 'conversation_start'\n | 'search_memory'\n | 'search_memory_nodes'\n | 'explore_memory_graph';\n query?: string;\n facts?: RecalledMemoryFact[];\n entities?: RecalledMemoryEntity[];\n turns?: RecalledMemoryTurn[];\n timestampMs: number;\n}\n\n/**\n * Snapshot of the core-memory block a conversation saw (audit trail): the\n * render revision plus the injected entries as structured items.\n */\nexport interface CoreMemorySnapshot {\n uid: string;\n revision: string;\n items: Array<{\n id: number;\n section: string;\n content: string;\n pinned: boolean;\n source: string;\n }>;\n entries: number;\n omitted: number;\n chars: number;\n timestampMs: number;\n}\n\n/**\n * Real-time chat history response\n */\nexport interface RealtimeChatHistory {\n chatUID: string;\n clientUID: string;\n chatHistory: ChatMessage[];\n status: RealtimeStatus;\n lastUpdatedAt: number;\n pendingToolCalls?: ToolCall[];\n handedOffSubThreadId?: string;\n /** Present only when status is `limit_exceeded`. */\n limitExceeded?: TenantLimitExceeded;\n /**\n * Memory-recall events of the in-flight run — lets the UI show what the\n * assistant is recalling while the response is still processing.\n */\n recalledMemories?: RecalledMemoryRecord[];\n /**\n * Messages accepted into this conversation that the model has not seen yet.\n * Non-zero means more is coming: a `completed` status with messages still\n * queued is not the end of the exchange.\n */\n queuedMessages?: number;\n /**\n * The queued messages themselves. This is the conversation's queue, not the\n * caller's — it can include messages the same conversation received through\n * another channel. Absent on an API that does not return them, in which case\n * the widget falls back to its own optimistic copies.\n */\n pendingUserMessages?: ChatMessage[];\n /**\n * Compaction checkpoints of the in-flight run. A conversation that compacts\n * mid-run stops sending the messages above the cut immediately, so these\n * arrive here before they are persisted on the conversation.\n */\n compactions?: CompactionCheckpoint[];\n /** The compaction running right now, if any. */\n compaction?: CompactionActivity;\n}\n\n/**\n * A single usage rule with its current consumption (from GET\n * /api/v1/tenant-usage/:tenantId[/subtenants/:subtenantId]).\n */\nexport interface TenantUsageRule {\n scope: 'tenant' | 'subtenant';\n subtenantId?: string;\n metric: 'tokens' | 'cost';\n windowUnit: 'hour' | 'day' | 'week' | 'month';\n windowEvery: number;\n /** Configured limit for the window. */\n limit: number;\n /** Current consumption in the active window. */\n current: number;\n /** Utilization percentage (0..100, capped). */\n percent: number;\n /** Epoch ms when the active window resets. */\n resetsAt?: number;\n /** Where the rule comes from ('tier' | 'adhoc'). */\n origin?: string;\n /** Tier the rule belongs to, if any. */\n tierId?: string;\n}\n\n/**\n * Response of GET /api/v1/tenant-usage/:tenantId[/subtenants/:subtenantId]:\n * the effective usage rules with their current consumption + the active tier.\n */\nexport interface TenantUsage {\n tenantId: string;\n subtenantId?: string;\n tierId?: string;\n usage: TenantUsageRule[];\n}\n\n/**\n * A durable per-window usage history row (from GET\n * /api/v1/tenant-usage/:tenantId/history).\n */\nexport interface TenantUsageHistoryRow {\n clientUID: string;\n tenantId: string;\n subtenantId: string;\n scope: 'tenant' | 'subtenant';\n metric: 'tokens' | 'cost';\n windowUnit: 'hour' | 'day' | 'week' | 'month';\n windowEvery: number;\n windowKey: string;\n windowStart: number;\n windowEnd: number;\n /** Counted consumption (enforced). */\n consumption: number;\n /** Exempt consumption that did not count toward the limit, if any. */\n exemptConsumption?: number;\n limit: number;\n percent: number;\n tierId?: string;\n origin?: string;\n capturedAt: number;\n}\n\n/**\n * Options for querying tenant usage history.\n */\nexport interface TenantUsageHistoryQuery {\n subtenantId?: string;\n scope?: 'tenant' | 'subtenant';\n metric?: 'tokens' | 'cost';\n windowUnit?: 'hour' | 'day' | 'week' | 'month';\n /** Epoch ms lower bound (windowEnd >= from). */\n from?: number;\n /** Epoch ms upper bound (windowEnd <= to). */\n to?: number;\n limit?: number;\n skip?: number;\n}\n\n/**\n * Chat history structure\n */\n/** A concrete value carried verbatim through a compaction. */\nexport interface CompactionFact {\n kind: string;\n value: string;\n label?: string;\n}\n\n/** The structured body a compaction produced. */\nexport interface CompactionSummary {\n goal?: string;\n constraints?: string[];\n inProgress?: string;\n pending?: string[];\n decisions?: string[];\n data?: Array<{ label: string; value: string }>;\n done?: string[];\n openQuestions?: string[];\n /** Fallback when the model answered without structure. */\n raw?: string;\n}\n\n/**\n * One compaction of a conversation: the messages before its boundary folded\n * into a written summary plus the identifiers, paths and urls lifted out of\n * them verbatim. From then on the model receives the checkpoint instead of\n * those messages — which are still in the conversation, and still shown.\n *\n * Only the newest checkpoint is in force: each compaction merges the previous\n * summary into itself.\n */\nexport interface CompactionCheckpoint {\n uid: string;\n /** 1 for the first compaction of the conversation, 2 for the next… */\n index: number;\n timestampMs: number;\n trigger: 'auto' | 'manual';\n /** First message that still travels verbatim. */\n firstKeptMessageUid?: string;\n /** Last folded message: where the widget belongs in the conversation. */\n anchorMessageUid?: string;\n compactedMessageCount: number;\n summary: CompactionSummary;\n facts: CompactionFact[];\n tokensBefore: number;\n tokensAfter: number;\n provider?: string;\n model?: string;\n cost?: number;\n}\n\n/**\n * A compaction happening right now, from the realtime endpoint.\n *\n * A compaction is a model call of its own, taken between two assistant\n * messages, so a client that only knows `processing` shows a conversation\n * that appears to have stalled for a few seconds. Present while it runs and\n * on the single update that reports it finished.\n */\nexport interface CompactionActivity {\n state: 'running' | 'completed';\n startedAt: number;\n /**\n * What this pass is folding: the messages new since the last checkpoint.\n * Not the conversation's totals — a checkpoint's own\n * `compactedMessageCount` and `tokensBefore` are cumulative across every\n * compaction, so the two are on different scales and must not be paired.\n */\n messageCount: number;\n tokensBefore: number;\n /** Which checkpoint the pass produced, once it is done. */\n index?: number;\n finishedAt?: number;\n}\n\nexport interface ChatHistory {\n chatUID: string;\n clientUID: string;\n userUID: string;\n chatContent: ChatMessage[];\n name?: string;\n assistantSpecializationIdentifier: string;\n creationTimestampMs: number;\n lastEditTimestampMs?: number;\n llm?: string;\n inputTokens?: number;\n outputTokens?: number;\n metadata?: Record<string, any>;\n tenantId?: string;\n handedOff?: boolean;\n handedOffSubThreadId?: string;\n handedOffToolCallId?: string;\n /** Structured long-term-memory recall events of the conversation. */\n recalledMemories?: RecalledMemoryRecord[];\n /** Audit trail of the core-memory blocks the conversation saw. */\n coreMemories?: CoreMemorySnapshot[];\n /** Compaction checkpoints of the conversation, oldest first. */\n compactions?: CompactionCheckpoint[];\n}\n\n/** One core memory entry (the always-injected tier), as returned by the memory API. */\nexport interface CoreMemoryEntry {\n id: number;\n section: string;\n content: string;\n source: string;\n pinned: boolean;\n supersedes: number | null;\n archivedAt: string | null;\n createdAt?: string;\n updatedAt?: string;\n}\n\n/** Deployment caps of the core memory tier. */\nexport interface CoreMemoryLimits {\n maxChars: number;\n maxEntries: number;\n maxEntryChars: number;\n}\n\n/**\n * Response of GET /api/v1/memory/assistants/:identifier/core — the entries\n * of the bucket the assistant resolves for a tenant/subtenant combination.\n */\nexport interface CoreMemoryList {\n /** False when the assistant does not have the core memory tier enabled. */\n enabled: boolean;\n /** The resolved bucket tuple (tenant/subtenant/owner dimensions). */\n bucket: { tenantId?: string; subtenantId?: string; entityId?: string };\n entries: CoreMemoryEntry[];\n limits?: CoreMemoryLimits;\n}\n\n/**\n * Assistant specialization info\n */\nexport interface AssistantSpecialization {\n identifier: string;\n name: string;\n description: string;\n state: 'active' | 'inactive' | 'coming_soon';\n imgUrl?: string;\n /** Pinned style of the generated avatar shown when there is no imgUrl. */\n avatarStyle?: AvatarStyle;\n availableToolsGroups?: Array<{\n name: string;\n description?: string;\n uid?: string;\n iconUrl?: string;\n tools?: Array<{\n name: string;\n description: string;\n }>;\n }>;\n model?: string;\n isCustom?: boolean;\n creationTimestampMs?: number;\n /**\n * Whether this assistant offers MCP servers of the tenant's own.\n *\n * Same contract as `tenantIntegrations` below, absence included.\n */\n tenantMcpServers?: {\n enabled: boolean;\n /** Servers listed ready to connect. Says nothing about how many are connected. */\n count?: number;\n };\n /**\n * Whether this assistant offers connected apps to its tenants.\n *\n * **Absent means \"cannot tell\", not \"no\"** — an API older than this field\n * says nothing, and treating silence as a no would hide the connected-apps\n * button from anyone whose deployment has not caught up yet.\n */\n tenantIntegrations?: {\n enabled: boolean;\n /**\n * How many apps the catalogue offers. An upper bound — the listing drops\n * any the provider cannot resolve — and enough to size a placeholder.\n */\n count?: number;\n };\n /**\n * Whether this assistant accepts messages sent while the conversation is\n * busy, queueing them instead of refusing them.\n *\n * **Absent means no**, unlike `tenantIntegrations` above. Promising a queue\n * that does not exist is paid for with a 409 and with the user's text left in\n * the air, so silence is read as the safe answer rather than as the open one.\n */\n messageQueueEnabled?: boolean;\n /** How many messages may wait at once before further sends are refused. */\n maxQueuedMessages?: number;\n}\n\n/**\n * Summary of a conversation for listing\n */\nexport interface ConversationSummary {\n chatUID: string;\n name?: string;\n creationTimestampMs: number;\n lastEditTimestampMs?: number;\n}\n\nexport interface ListConversationsResponse {\n histories: ConversationSummary[];\n total: number;\n offset: number;\n limit: number;\n}\n\n/**\n * API error response\n */\nexport interface ApiError {\n statusCode: number;\n message: string;\n error?: string;\n /** Optional structured details (e.g. usage-limit blocking info on a 429). */\n details?: any;\n}\n\n/**\n * Feedback submission request\n */\nexport interface FeedbackSubmission {\n messageId: string;\n feedback?: boolean;\n feedbackComment?: string;\n feedbackData?: Record<string, any>;\n}\n\n/**\n * Feedback entry response\n */\nexport interface FeedbackEntry {\n _id: string;\n requestId: string;\n chatUID?: string;\n threadId?: string;\n agentId?: string;\n feedback?: boolean;\n feedbackComment?: string;\n feedbackData?: Record<string, any>;\n creationTimestamp: string;\n lastEditTimestamp?: string;\n}\n\n/**\n * Agent thread states\n */\nexport enum AgentThreadState {\n QUEUED = 'queued',\n PROCESSING = 'processing',\n COMPLETED = 'completed',\n FAILED = 'failed',\n TERMINATED = 'terminated',\n PAUSED = 'paused',\n PAUSED_FOR_APPROVAL = 'paused_for_approval',\n APPROVAL_REJECTED = 'approval_rejected',\n WAITING_FOR_RESPONSE = 'waiting_for_response',\n PAUSED_FOR_RESUME = 'paused_for_resume',\n HANDED_OFF = 'handed_off',\n GUARDRAIL_TRIGGER = 'guardrail_trigger',\n}\n\n/**\n * Task within an agent thread\n */\nexport interface AgentTaskDto {\n _id?: string;\n title?: string;\n description?: string;\n completed: boolean;\n}\n\n/**\n * Agent thread DTO\n */\nexport interface AgentThreadDto {\n _id?: string;\n agentId: string;\n state: AgentThreadState;\n threadContent: ChatMessage[];\n tasks?: AgentTaskDto[];\n finishReason?: string;\n pausedReason?: string;\n name?: string;\n creationTimestampMs?: number;\n lastEditTimestampMs?: number;\n pauseUntil?: number;\n isSubthread?: boolean;\n parentThreadId?: string;\n subThreadToolCallId?: string;\n parentAgentId?: string;\n}\n\n/**\n * Agent details\n */\nexport interface AgentDto {\n _id?: string;\n name: string;\n description?: string;\n imgUrl?: string;\n /** Pinned style of the generated avatar shown when there is no imgUrl. */\n avatarStyle?: AvatarStyle;\n agentId?: string;\n}\n\n/**\n * Hand-off tool response content\n */\nexport interface HandOffToolResponse {\n response: string;\n subthreadId: string;\n}\n\n/**\n * Represents a single tool call within a tool group\n */\nexport interface ToolGroupCall {\n name: string;\n input: any;\n output: any;\n toolCallId: string;\n}\n\n/**\n * Configuration for grouping consecutive tool calls under a single renderer\n */\nexport interface ToolGroupConfig {\n tools: string[];\n renderer: (calls: ToolGroupCall[]) => React.ReactNode;\n}\n\n/**\n * One of the end user's connected accounts for an app.\n *\n * The provider's own identifiers do not travel here beyond `id`, which the\n * client needs in order to name the account it wants disconnected — and which\n * the server re-checks against the caller's tenant on the way back in.\n */\nexport interface IntegrationAccount {\n id: string;\n status: string;\n connectedAt?: string;\n updatedAt?: string;\n /** True when the account exists but can no longer run tools. */\n needsReconnect?: boolean;\n statusReason?: string;\n}\n\n/**\n * One value the end user is asked for before an account can be connected —\n * their API key, the subdomain of their instance.\n *\n * Comes from the provider's own catalogue, so the form is rendered from this\n * rather than from anything app-specific: most apps do not authenticate with\n * credentials Devic holds, and there are hundreds of them.\n */\nexport interface IntegrationAuthField {\n name: string;\n label: string;\n type: string;\n required: boolean;\n description?: string;\n /** Prefilled — usually a provider endpoint most accounts should keep. */\n default?: string;\n /** Mask it on screen. */\n secret: boolean;\n}\n\n/**\n * One way of connecting an app.\n *\n * `redirect` schemes send the user to the provider; the rest are connected\n * with the values they type, without ever leaving the page.\n *\n * There is deliberately no field for the *application's* credentials: the\n * OAuth application belongs to the developer who embedded this widget, is\n * registered once for every tenant, and is never the end user's to supply.\n */\nexport interface IntegrationAuthScheme {\n /** The provider's own name for it: `OAUTH2`, `API_KEY`, … */\n mode: string;\n /** Credentials for this scheme are held for you — nothing to fill in. */\n composioManaged: boolean;\n redirect: boolean;\n /** What this account supplies. Empty for a scheme that asks nothing. */\n accountFields: IntegrationAuthField[];\n /** The provider's own setup guide, when there is one. */\n guideUrl?: string;\n}\n\n/**\n * The answer when connecting needs values that were not sent.\n *\n * `stage` decides who can act on it: `account` is the end user, and the form\n * asks them. `app` is the developer's OAuth application, which the end user\n * cannot register — so that case is shown as \"not available yet\" instead of a\n * form asking a stranger for someone else's client secret.\n */\nexport interface IntegrationSetupRequired {\n code: \"INTEGRATION_SETUP_REQUIRED\";\n message: string;\n toolkit: string;\n authScheme: string;\n stage: \"app\" | \"account\";\n fields: IntegrationAuthField[];\n guideUrl?: string;\n}\n\n/**\n * An app the assistant offers to its tenants, with the accounts THIS tenant\n * has connected. Never another tenant's.\n */\nexport interface Integration {\n /** App slug, e.g. `gmail`. */\n app: string;\n name: string;\n description?: string;\n logo?: string;\n /** True when at least one account is active. */\n connected: boolean;\n accounts: IntegrationAccount[];\n /** Event types the developer allows this tenant to switch on. */\n availableTriggers?: string[];\n}\n\n// ── MCP servers the end user connects for themselves ──────────────────────\n\nexport type TenantMcpAuthMode = \"oauth\" | \"header\" | \"none\";\n\n/** One of the end user's own MCP connections. */\nexport interface TenantMcpConnection {\n id: string;\n /**\n * What to put in `disabledIntegrations` to have this server sit a message\n * out. Sent by the API so the prefix that separates it from an app slug lives\n * on the server, in one place.\n */\n toggleId?: string;\n name?: string;\n url: string;\n /** The developer's template this came from, when it came from one. */\n templateId?: string;\n authMode?: TenantMcpAuthMode;\n status: \"pending_auth\" | \"active\" | \"error\";\n toolCount?: number;\n tools?: string[];\n lastProbeStatus?: string;\n lastProbeError?: string;\n lastProbeTimestampMs?: number;\n /** Connected for the whole tenant, so every end user of it shares this. */\n shared: boolean;\n /** True when this end user may use it but not change or remove it. */\n readOnly: boolean;\n}\n\n/**\n * One row of the MCP panel: either a server the developer offers ready to\n * connect, or one this end user added.\n *\n * A single list rather than two, because that is what the panel draws — keeping\n * \"offered\" and \"connected\" apart would leave them out of step for a moment\n * after every connect.\n */\nexport interface TenantMcpServer {\n source: \"template\" | \"custom\";\n templateId?: string;\n name: string;\n url: string;\n description?: string;\n logoUrl?: string;\n authMode?: TenantMcpAuthMode;\n /** Header the credential travels in, for `header` servers. */\n headerName?: string;\n /** Whether the end user may supply their own OAuth application. */\n allowClientCredentials?: boolean;\n /** Null until this tenant connects it. */\n connection: TenantMcpConnection | null;\n}\n\nexport interface TenantMcpListing {\n offered: boolean;\n /** Whether adding a server of one's own is permitted. */\n allowCustom: boolean;\n limits: { maxServers: number; maxToolsPerServer: number; used: number };\n servers: TenantMcpServer[];\n}\n\n/** Credentials the end user supplies when connecting a server. */\nexport interface TenantMcpAuthInput {\n mode?: TenantMcpAuthMode;\n headerName?: string;\n headerValue?: string;\n upstreamOAuth?: { clientId?: string; clientSecret?: string; scopes?: string[] };\n}\n\n/**\n * What connecting answers with.\n *\n * `status: \"active\"` means it is done. `authorizationUrl` must be opened in a\n * popup. `requiresClientCredentials` means the server has no dynamic client\n * registration and the end user has to register an OAuth application with it\n * themselves, authorising `callbackUrl` as the redirect URI.\n */\nexport interface TenantMcpConnectResult {\n id: string;\n status: \"pending_auth\" | \"active\" | \"error\";\n toolCount?: number;\n authorizationUrl?: string;\n requiresClientCredentials?: boolean;\n callbackUrl?: string;\n error?: string;\n}\n"],"names":[],"mappings":"AA+CA;AACM,SAAU,oBAAoB,CAAC,IAAiB,EAAA;IAKpD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE;QACvC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,OAAO;KAC5C;AACH;AA2tBA;;AAEG;IACS;AAAZ,CAAA,UAAY,gBAAgB,EAAA;AAC1B,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,gBAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AACzB,IAAA,gBAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,gBAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AACzB,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,gBAAA,CAAA,qBAAA,CAAA,GAAA,qBAA2C;AAC3C,IAAA,gBAAA,CAAA,mBAAA,CAAA,GAAA,mBAAuC;AACvC,IAAA,gBAAA,CAAA,sBAAA,CAAA,GAAA,sBAA6C;AAC7C,IAAA,gBAAA,CAAA,mBAAA,CAAA,GAAA,mBAAuC;AACvC,IAAA,gBAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AACzB,IAAA,gBAAA,CAAA,mBAAA,CAAA,GAAA,mBAAuC;AACzC,CAAC,EAbW,gBAAgB,KAAhB,gBAAgB,GAAA,EAAA,CAAA,CAAA;;"}
|