@digithings-ai/ui 0.0.0-stage → 0.1.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 +48 -2
- package/package.json +143 -4
- package/src/components/NavShell.tsx +776 -0
- package/src/components/SocialRow.tsx +87 -0
- package/src/components/Spinner.tsx +27 -0
- package/src/components/StackLogo.tsx +40 -0
- package/src/components/Terminal.tsx +110 -0
- package/src/components/TerminalManifest.tsx +212 -0
- package/src/components/ThemeProvider.tsx +271 -0
- package/src/components/account/AuthCard.tsx +309 -0
- package/src/components/assistant-ui/elements/mermaid-diagram.aui.tsx +63 -0
- package/src/components/assistant-ui/elements/mermaid-diagram.tsx +340 -0
- package/src/components/brand/BrandWordmark.tsx +32 -0
- package/src/components/changelog/ReleaseRail.tsx +81 -0
- package/src/components/changelog/index.ts +1 -0
- package/src/components/chat/ChatCodeBlock.tsx +67 -0
- package/src/components/chat/ChatMarkdown.tsx +66 -0
- package/src/components/chat/ChatMarkdownSource.tsx +203 -0
- package/src/components/chat/ChatMermaidBlock.tsx +202 -0
- package/src/components/chat/ChatMessage.tsx +77 -0
- package/src/components/chat/ChatPlayback.tsx +422 -0
- package/src/components/chat/ChatStreamCursor.tsx +25 -0
- package/src/components/chat/ChatThinking.tsx +113 -0
- package/src/components/chat/ChatToolCall.tsx +190 -0
- package/src/components/chat/ChatTranscript.tsx +60 -0
- package/src/components/chat/ChatWidgetFrame.tsx +107 -0
- package/src/components/chat/DigichatBootLoader.tsx +683 -0
- package/src/components/chat/DigichatLauncher.tsx +361 -0
- package/src/components/chat/DigichatThread.tsx +118 -0
- package/src/components/chat/DigichatThreadList.tsx +54 -0
- package/src/components/chat/DigichatWordmark.tsx +24 -0
- package/src/components/chat/DotMatrix.tsx +650 -0
- package/src/components/chat/boot-lab.tsx +766 -0
- package/src/components/chat/boot-signal.ts +144 -0
- package/src/components/chat/chat-surfaces.ts +52 -0
- package/src/components/chat/connection-status.ts +40 -0
- package/src/components/chat/digichat-wordmark.ts +355 -0
- package/src/components/chat/disclosure-chevron.tsx +49 -0
- package/src/components/chat/followable-href.ts +9 -0
- package/src/components/chat/gallery-thread/action-icons.tsx +25 -0
- package/src/components/chat/gallery-thread/attachment.aui.tsx +262 -0
- package/src/components/chat/gallery-thread/block-caret.tsx +439 -0
- package/src/components/chat/gallery-thread/cn.ts +1 -0
- package/src/components/chat/gallery-thread/composer-keyboard.ts +106 -0
- package/src/components/chat/gallery-thread/composer-trigger-popover.aui.tsx +235 -0
- package/src/components/chat/gallery-thread/css.d.ts +6 -0
- package/src/components/chat/gallery-thread/file.tsx +238 -0
- package/src/components/chat/gallery-thread/follow-up-suggestions.aui.tsx +92 -0
- package/src/components/chat/gallery-thread/format-json-dump.ts +112 -0
- package/src/components/chat/gallery-thread/hooks/use-attachment-src.ts +46 -0
- package/src/components/chat/gallery-thread/hooks/use-copy-to-clipboard.ts +9 -0
- package/src/components/chat/gallery-thread/image.tsx +519 -0
- package/src/components/chat/gallery-thread/markdown-text.tsx +278 -0
- package/src/components/chat/gallery-thread/message-error.aui.tsx +105 -0
- package/src/components/chat/gallery-thread/message-timing.aui.tsx +143 -0
- package/src/components/chat/gallery-thread/private-work-step.tsx +188 -0
- package/src/components/chat/gallery-thread/reasoning.tsx +332 -0
- package/src/components/chat/gallery-thread/scroll-mode.ts +174 -0
- package/src/components/chat/gallery-thread/source.tsx +76 -0
- package/src/components/chat/gallery-thread/thread.aui.tsx +1619 -0
- package/src/components/chat/gallery-thread/tooltip-icon-button.tsx +53 -0
- package/src/components/chat/gallery-thread/typed-welcome-copy.tsx +18 -0
- package/src/components/chat/gallery-thread/ui/tooltip.tsx +22 -0
- package/src/components/chat/gallery-thread/work-chain-summary.tsx +48 -0
- package/src/components/chat/gallery-thread/work-chain.tsx +110 -0
- package/src/components/chat/gallery-thread/work-status.ts +66 -0
- package/src/components/chat/overlay-scrollbar.tsx +86 -0
- package/src/components/chat/sanitize-mermaid-svg.ts +38 -0
- package/src/components/chat/skins/SOURCE.md +36 -0
- package/src/components/chat/skins/base/attachment.aui.tsx +287 -0
- package/src/components/chat/skins/base/aui-default/README.md +45 -0
- package/src/components/chat/skins/base/aui-default/collapsible-root.tsx +19 -0
- package/src/components/chat/skins/base/aui-default/collapsible.tsx +21 -0
- package/src/components/chat/skins/base/aui-default/reasoning.aui.tsx +120 -0
- package/src/components/chat/skins/base/aui-default/reasoning.tsx +331 -0
- package/src/components/chat/skins/base/aui-default/surfaces.ts +7 -0
- package/src/components/chat/skins/base/aui-default/tool-fallback.aui.tsx +772 -0
- package/src/components/chat/skins/base/aui-default/tool-group.aui.tsx +241 -0
- package/src/components/chat/skins/base/docs-model-options.ts +6 -0
- package/src/components/chat/skins/base/elements/assistant-trace.aui.tsx +169 -0
- package/src/components/chat/skins/base/elements/composer-trigger-popover.aui.tsx +271 -0
- package/src/components/chat/skins/base/elements/directive-text.aui.tsx +29 -0
- package/src/components/chat/skins/base/elements/directive-text.tsx +76 -0
- package/src/components/chat/skins/base/elements/message-timing.aui.tsx +104 -0
- package/src/components/chat/skins/base/elements/model-selector.aui.tsx +140 -0
- package/src/components/chat/skins/base/elements/model-selector.tsx +720 -0
- package/src/components/chat/skins/base/elements/quote.aui.tsx +290 -0
- package/src/components/chat/skins/base/elements/work-chain.tsx +100 -0
- package/src/components/chat/skins/base/markdown-text.tsx +294 -0
- package/src/components/chat/skins/base/model.ts +1 -0
- package/src/components/chat/skins/base/thread.tsx +1050 -0
- package/src/components/chat/skins/base/tooltip-icon-button.tsx +56 -0
- package/src/components/chat/skins/base/ui/avatar.tsx +115 -0
- package/src/components/chat/skins/base/ui/badge.tsx +51 -0
- package/src/components/chat/skins/base/ui/button.tsx +67 -0
- package/src/components/chat/skins/base/ui/command.tsx +185 -0
- package/src/components/chat/skins/base/ui/dialog.tsx +168 -0
- package/src/components/chat/skins/base/ui/dot-matrix.tsx +267 -0
- package/src/components/chat/skins/base/ui/popover.tsx +97 -0
- package/src/components/chat/skins/base/ui/skeleton.tsx +20 -0
- package/src/components/chat/skins/base/ui/textarea.tsx +24 -0
- package/src/components/chat/skins/base/ui/tooltip.tsx +73 -0
- package/src/components/chat/skins/base-assistant-ui/config-provider.tsx +90 -0
- package/src/components/chat/skins/base-assistant-ui/defaults.ts +419 -0
- package/src/components/chat/skins/base-assistant-ui/index.tsx +44 -0
- package/src/components/chat/skins/chatgpt.tsx +448 -0
- package/src/components/chat/skins/claude.tsx +380 -0
- package/src/components/chat/skins/digichat-composer-toolbar.tsx +151 -0
- package/src/components/chat/skins/digichat-context-meter-shares.ts +158 -0
- package/src/components/chat/skins/digichat-context-meter.tsx +243 -0
- package/src/components/chat/skins/digichat-meter-tone.ts +26 -0
- package/src/components/chat/skins/digichat-usage-meter.tsx +103 -0
- package/src/components/chat/skins/digichat.tsx +144 -0
- package/src/components/chat/skins/expo-react-native.tsx +29 -0
- package/src/components/chat/skins/gemini.tsx +322 -0
- package/src/components/chat/skins/grok-icon.tsx +34 -0
- package/src/components/chat/skins/grok.tsx +369 -0
- package/src/components/chat/skins/index.ts +46 -0
- package/src/components/chat/skins/perplexity.tsx +462 -0
- package/src/components/chat/skins/product-page-assistant/assistant-modal.tsx +73 -0
- package/src/components/chat/skins/product-page-assistant/index.tsx +19 -0
- package/src/components/chat/skins/product-page-assistant/product-dashboard.tsx +164 -0
- package/src/components/chat/skins/react-ink.tsx +97 -0
- package/src/components/chat/skins/thread-skin-host-contract.ts +102 -0
- package/src/components/chat/skins/thread-skin-view.tsx +156 -0
- package/src/components/chat/skins/thread-skins.ts +143 -0
- package/src/components/chat/skins/tooltip-icon-button.tsx +35 -0
- package/src/components/chat/skins/ui/dropdown-menu.tsx +272 -0
- package/src/components/chat/skins/webpage-assistant/assistant-config.ts +238 -0
- package/src/components/chat/skins/webpage-assistant/assistant-modal.tsx +78 -0
- package/src/components/chat/skins/webpage-assistant/config-provider.tsx +132 -0
- package/src/components/chat/skins/webpage-assistant/docs-app.tsx +106 -0
- package/src/components/chat/skins/webpage-assistant/docs-article.tsx +109 -0
- package/src/components/chat/skins/webpage-assistant/docs-assistant.tsx +73 -0
- package/src/components/chat/skins/webpage-assistant/docs-nav.tsx +81 -0
- package/src/components/chat/skins/webpage-assistant/host-ui.ts +79 -0
- package/src/components/chat/skins/webpage-assistant/index.tsx +12 -0
- package/src/components/chat/skins/webpage-assistant/markdown-page.tsx +11 -0
- package/src/components/chat/skins/webpage-assistant/pages.ts +9 -0
- package/src/components/chat/skins/webpage-assistant/types.ts +178 -0
- package/src/components/chat/skins/webpage-assistant/use-mobile.ts +19 -0
- package/src/components/chat/stock/SOURCE.md +90 -0
- package/src/components/chat/stock/artifacts-panel.tsx +305 -0
- package/src/components/chat/stock/attachment.aui.tsx +280 -0
- package/src/components/chat/stock/chat-notice.tsx +143 -0
- package/src/components/chat/stock/chat-private-mode.tsx +64 -0
- package/src/components/chat/stock/deploy-ui-context.tsx +89 -0
- package/src/components/chat/stock/embed-chat-prefs.tsx +471 -0
- package/src/components/chat/stock/file.tsx +265 -0
- package/src/components/chat/stock/follow-up-suggestions.aui.tsx +83 -0
- package/src/components/chat/stock/image.tsx +531 -0
- package/src/components/chat/stock/index.ts +129 -0
- package/src/components/chat/stock/json-view.tsx +140 -0
- package/src/components/chat/stock/markdown-text.tsx +319 -0
- package/src/components/chat/stock/message-error.aui.tsx +96 -0
- package/src/components/chat/stock/message-export-menu.tsx +156 -0
- package/src/components/chat/stock/palette-row-preview.tsx +26 -0
- package/src/components/chat/stock/reasoning.aui.tsx +120 -0
- package/src/components/chat/stock/reasoning.tsx +335 -0
- package/src/components/chat/stock/skin-chrome.tsx +81 -0
- package/src/components/chat/stock/skin-credit.tsx +63 -0
- package/src/components/chat/stock/skin-palette-bridge.tsx +235 -0
- package/src/components/chat/stock/skin-palette-context.ts +16 -0
- package/src/components/chat/stock/skin-runtime.tsx +52 -0
- package/src/components/chat/stock/skin-slash-palette.tsx +393 -0
- package/src/components/chat/stock/skin-types.ts +217 -0
- package/src/components/chat/stock/stock-chat-prefs-host.tsx +501 -0
- package/src/components/chat/stock/stock-send-gate.tsx +94 -0
- package/src/components/chat/stock/stock-shape.tsx +39 -0
- package/src/components/chat/stock/thread.aui.tsx +645 -0
- package/src/components/chat/stock/tool-display.ts +6 -0
- package/src/components/chat/stock/tool-fallback.aui.tsx +866 -0
- package/src/components/chat/stock/tool-group.aui.tsx +244 -0
- package/src/components/chat/stock/tool-surface.ts +120 -0
- package/src/components/chat/stock/tooltip-icon-button.tsx +49 -0
- package/src/components/chat/stock/ui/avatar.tsx +108 -0
- package/src/components/chat/stock/ui/button.tsx +81 -0
- package/src/components/chat/stock/ui/collapsible.tsx +21 -0
- package/src/components/chat/stock/ui/dialog.tsx +163 -0
- package/src/components/chat/stock/ui/skeleton.tsx +13 -0
- package/src/components/chat/stock/ui/textarea.tsx +20 -0
- package/src/components/chat/stock/ui/tooltip.tsx +68 -0
- package/src/components/chat/stock/use-attachment-src.ts +42 -0
- package/src/components/chat/stock/use-copy-to-clipboard.ts +29 -0
- package/src/components/chat/strip-model-boilerplate.ts +42 -0
- package/src/components/chat/suggestion-cycle.tsx +230 -0
- package/src/components/chat/suggestion-scroll-row.tsx +81 -0
- package/src/components/chat/trace-grouping/chain-group-by.ts +44 -0
- package/src/components/chat/trace-grouping/chain-state.ts +141 -0
- package/src/components/chat/trace-grouping/index.ts +32 -0
- package/src/components/chat/trace-grouping/tool-row.ts +74 -0
- package/src/components/chat/trace-grouping/use-deploy-work-disclosure.ts +35 -0
- package/src/components/chat/trace-grouping/use-work-chain.ts +103 -0
- package/src/components/chat/trace-i18n/core.ts +48 -0
- package/src/components/chat/trace-i18n/index.tsx +23 -0
- package/src/components/chat/trace-i18n/locales/en.ts +24 -0
- package/src/components/chat/trace-i18n/locales/fr.ts +28 -0
- package/src/components/chat/trace-i18n/types.ts +35 -0
- package/src/components/chat/trace-spacing.ts +249 -0
- package/src/components/chat/transcript/activity-view.ts +375 -0
- package/src/components/chat/transcript/chat-export.ts +133 -0
- package/src/components/chat/transcript/index.ts +10 -0
- package/src/components/chat/transcript/save-file.ts +209 -0
- package/src/components/chat/transcript/transcript-markdown.ts +428 -0
- package/src/components/chat/transcript/types.ts +81 -0
- package/src/components/chat/turn-outcome.ts +52 -0
- package/src/components/chat/use-warmup-phase.ts +18 -0
- package/src/components/chat/work-status-lead.tsx +49 -0
- package/src/components/chrome.tsx +264 -0
- package/src/components/command-palette/CommandPalette.tsx +404 -0
- package/src/components/command-palette/index.ts +6 -0
- package/src/components/contact/ContactMailto.tsx +112 -0
- package/src/components/contact/index.ts +5 -0
- package/src/components/conviction/ConvictionMeter.tsx +40 -0
- package/src/components/conviction/SignedConvictionBadge.tsx +26 -0
- package/src/components/conviction/index.ts +7 -0
- package/src/components/data-layout/BentoGrid.tsx +52 -0
- package/src/components/data-layout/CardRail.tsx +150 -0
- package/src/components/data-layout/DotMatrixStat.tsx +65 -0
- package/src/components/data-layout/FeatureCell.tsx +80 -0
- package/src/components/data-layout/MediaFrame.tsx +125 -0
- package/src/components/data-layout/ModuleGrid.tsx +735 -0
- package/src/components/data-layout/Odometer.tsx +149 -0
- package/src/components/data-layout/ProductFrame.tsx +79 -0
- package/src/components/data-layout/TestimonialWall.tsx +139 -0
- package/src/components/data-layout/index.ts +19 -0
- package/src/components/data-layout/treemap.ts +368 -0
- package/src/components/deck/DeckStack.tsx +243 -0
- package/src/components/desk/DataTable.tsx +373 -0
- package/src/components/desk/KpiGrid.tsx +80 -0
- package/src/components/desk/Sparkline.tsx +63 -0
- package/src/components/desk/StateBlock.tsx +132 -0
- package/src/components/desk/index.ts +18 -0
- package/src/components/diagrams/ArchitectureDiagram.tsx +350 -0
- package/src/components/diagrams/ArchitectureTour.tsx +912 -0
- package/src/components/diagrams/TerminalSchematic.tsx +192 -0
- package/src/components/diagrams/architecture-svg.tsx +384 -0
- package/src/components/diagrams/index.ts +30 -0
- package/src/components/diagrams/mermaid-theme.ts +115 -0
- package/src/components/diagrams/tour-camera.ts +171 -0
- package/src/components/docs/CodeTabs.tsx +90 -0
- package/src/components/docs/CopyCommand.tsx +151 -0
- package/src/components/docs/DocsLayout.tsx +197 -0
- package/src/components/docs/DocsSearch.tsx +97 -0
- package/src/components/docs/Endpoint.tsx +135 -0
- package/src/components/document/DocumentFrame.tsx +43 -0
- package/src/components/document/GlyphList.tsx +51 -0
- package/src/components/document/PageTitle.tsx +44 -0
- package/src/components/document/Prose.tsx +38 -0
- package/src/components/document/Section.tsx +55 -0
- package/src/components/document/index.ts +13 -0
- package/src/components/effects-chrome/AnnouncementBar.tsx +88 -0
- package/src/components/effects-chrome/HorizontalScrollTrack.tsx +461 -0
- package/src/components/effects-chrome/Pipeline.tsx +226 -0
- package/src/components/effects-chrome/RotatingPrompts.tsx +116 -0
- package/src/components/effects-chrome/StackingPanels.tsx +101 -0
- package/src/components/effects-chrome/TabStrip.tsx +232 -0
- package/src/components/effects-chrome/ToastStack.tsx +201 -0
- package/src/components/effects-chrome/horizontal-track-core.ts +70 -0
- package/src/components/effects-chrome/index.ts +35 -0
- package/src/components/emblems.tsx +188 -0
- package/src/components/faviconTheme.ts +23 -0
- package/src/components/figure/Figure.tsx +38 -0
- package/src/components/figure/index.ts +2 -0
- package/src/components/finance-charts/DrawdownPlot.tsx +76 -0
- package/src/components/finance-charts/EquityCurve.tsx +71 -0
- package/src/components/finance-charts/PriceChart.tsx +119 -0
- package/src/components/finance-charts/chart-host.tsx +236 -0
- package/src/components/finance-charts/chart-scale.ts +93 -0
- package/src/components/finance-charts/demo-data.ts +88 -0
- package/src/components/finance-charts/index.ts +46 -0
- package/src/components/finance-charts/lw-chart.tsx +292 -0
- package/src/components/finance-composites/MarketBar.tsx +243 -0
- package/src/components/finance-composites/OrderBook.tsx +133 -0
- package/src/components/finance-composites/PerformanceDashboard.tsx +185 -0
- package/src/components/finance-composites/SortableTable.tsx +144 -0
- package/src/components/finance-composites/StockTicker.tsx +65 -0
- package/src/components/finance-composites/SyncedTearsheet.tsx +226 -0
- package/src/components/finance-composites/index.ts +28 -0
- package/src/components/finance-tearsheet/KpiStrip.tsx +49 -0
- package/src/components/finance-tearsheet/LiveBadge.tsx +29 -0
- package/src/components/finance-tearsheet/ReturnsMatrix.tsx +321 -0
- package/src/components/finance-tearsheet/StrategyTearsheet.tsx +99 -0
- package/src/components/finance-tearsheet/TearsheetCard.tsx +54 -0
- package/src/components/finance-tearsheet/TradeLogTable.tsx +73 -0
- package/src/components/finance-tearsheet/charts.tsx +2624 -0
- package/src/components/finance-tearsheet/demo-data.ts +177 -0
- package/src/components/finance-tearsheet/format.ts +41 -0
- package/src/components/finance-tearsheet/index.ts +120 -0
- package/src/components/finance-tearsheet/print.ts +52 -0
- package/src/components/finance-tearsheet/risk-bands.ts +48 -0
- package/src/components/finance-tearsheet/stats.ts +35 -0
- package/src/components/finance-tearsheet/strategy-sheet-model.ts +238 -0
- package/src/components/finance-tearsheet/types.ts +58 -0
- package/src/components/footer/FooterCells.tsx +109 -0
- package/src/components/footer/index.ts +6 -0
- package/src/components/graph.tsx +158 -0
- package/src/components/icons.tsx +98 -0
- package/src/components/landing/PixelWordmark.tsx +36 -0
- package/src/components/logos.ts +39 -0
- package/src/components/marquee/Marquee.tsx +204 -0
- package/src/components/metrics/PerfMetrics.tsx +68 -0
- package/src/components/metrics/StatCounter.tsx +104 -0
- package/src/components/page-geometry.tsx +177 -0
- package/src/components/pricing/Pricing.tsx +174 -0
- package/src/components/pricing/PricingMatrix.tsx +219 -0
- package/src/components/prose/index.ts +2 -0
- package/src/components/prose/prose.tsx +86 -0
- package/src/components/repo-activity/RepoActivity.tsx +599 -0
- package/src/components/repo-activity/RepoHeatmap.tsx +225 -0
- package/src/components/repo-activity/demo.ts +201 -0
- package/src/components/repo-activity/fetch.ts +211 -0
- package/src/components/repo-activity/heatmap.ts +123 -0
- package/src/components/repo-activity/index.ts +28 -0
- package/src/components/repo-activity/types.ts +99 -0
- package/src/components/stages/NumberedStages.tsx +116 -0
- package/src/components/symbols/marks.tsx +116 -0
- package/src/components/symbols/terminal-lockup.tsx +136 -0
- package/src/components/symbols/terminal-marks.tsx +226 -0
- package/src/components/terminal/ChatResponseLoader.tsx +67 -0
- package/src/components/terminal/ContainerBootLoader.tsx +82 -0
- package/src/components/terminal/TerminalStepCaret.tsx +202 -0
- package/src/components/themeInit.ts +24 -0
- package/src/components/typography/MotionReveal.tsx +108 -0
- package/src/components/typography/TypewriterReveal.tsx +101 -0
- package/src/components/typography/WordReveal.tsx +143 -0
- package/src/data/modules.ts +378 -0
- package/src/data/subsystems.ts +101 -0
- package/src/index.ts +587 -0
- package/src/lib/base-path.ts +60 -0
- package/src/lib/cx.ts +25 -0
- package/src/lib/gloomberb.ts +69 -0
- package/src/lib/record.ts +19 -0
- package/src/lib/stub-payload.ts +183 -0
- package/src/lib/useBodyScrollLock.ts +44 -0
- package/src/lib/utils.ts +6 -0
- package/src/motion/primitives.tsx +105 -0
- package/src/motion/scroll-glide.ts +62 -0
- package/src/motion/scrolly-core.ts +38 -0
- package/src/motion/scrolly.tsx +95 -0
- package/src/navigation/HashScrollManager.tsx +167 -0
- package/src/navigation/hashScroll.ts +78 -0
- package/src/replay/browser.ts +280 -0
- package/src/replay/chat-export-run.ts +121 -0
- package/src/replay/export-format.ts +25 -0
- package/src/replay/export-mount.ts +32 -0
- package/src/replay/filename.ts +54 -0
- package/src/replay/index.ts +21 -0
- package/src/replay/redact-dom.ts +178 -0
- package/src/replay/redact.ts +113 -0
- package/src/replay/snapshot.ts +659 -0
- package/src/styles/account-auth.css +339 -0
- package/src/styles/brand-wordmark.css +11 -0
- package/src/styles/card-rail.css +120 -0
- package/src/styles/chat-aui.css +1143 -0
- package/src/styles/chat-core.css +469 -0
- package/src/styles/chat-digichat.css +2531 -0
- package/src/styles/chat-math.css +70 -0
- package/src/styles/chat-skin-palette.css +138 -0
- package/src/styles/chat-stock-menu.css +37 -0
- package/src/styles/chat-widgets.css +190 -0
- package/src/styles/command-palette.css +372 -0
- package/src/styles/controls-core.css +2261 -0
- package/src/styles/controls-overlay.css +603 -0
- package/src/styles/data-layout.css +288 -0
- package/src/styles/deck.css +141 -0
- package/src/styles/diagrams.css +1860 -0
- package/src/styles/digichat-app-theme.css +250 -0
- package/src/styles/digichat-boot-loader.css +487 -0
- package/src/styles/digichat-launcher.css +377 -0
- package/src/styles/docs.css +165 -0
- package/src/styles/effects-chrome.css +888 -0
- package/src/styles/finance-composites.css +214 -0
- package/src/styles/finance-tearsheet-overlay.css +90 -0
- package/src/styles/finance-tearsheet.css +945 -0
- package/src/styles/marquee.css +168 -0
- package/src/styles/metrics.css +82 -0
- package/src/styles/nav-shell.css +551 -0
- package/src/styles/pricing.css +79 -0
- package/src/styles/repo-activity.css +575 -0
- package/src/styles/stages.css +69 -0
- package/src/styles/terminal-loaders.css +122 -0
- package/src/styles/terminal-manifest.css +228 -0
- package/src/styles/web-theme.css +1007 -0
- package/src/styles/word-reveal.css +204 -0
- package/src/theme/apply-theme.ts +214 -0
- package/src/theme/index.ts +27 -0
- package/src/theme/palette-registry.ts +855 -0
- package/src/theme/tui-prefs.ts +64 -0
- package/src/ui/alert.tsx +78 -0
- package/src/ui/avatar.tsx +104 -0
- package/src/ui/badge.tsx +75 -0
- package/src/ui/breadcrumb.tsx +61 -0
- package/src/ui/button.tsx +67 -0
- package/src/ui/card.tsx +139 -0
- package/src/ui/checkbox.tsx +27 -0
- package/src/ui/collapsible.tsx +32 -0
- package/src/ui/date-pager.tsx +325 -0
- package/src/ui/dialog.tsx +157 -0
- package/src/ui/dropdown-menu.tsx +267 -0
- package/src/ui/empty-state.tsx +165 -0
- package/src/ui/field.tsx +104 -0
- package/src/ui/form.tsx +36 -0
- package/src/ui/icon-button.tsx +36 -0
- package/src/ui/index.ts +34 -0
- package/src/ui/input.tsx +33 -0
- package/src/ui/kbd.tsx +30 -0
- package/src/ui/label.tsx +32 -0
- package/src/ui/pager.tsx +119 -0
- package/src/ui/pagination.tsx +126 -0
- package/src/ui/radio-group.tsx +51 -0
- package/src/ui/search-bar.tsx +85 -0
- package/src/ui/segmented-control.tsx +76 -0
- package/src/ui/select.tsx +257 -0
- package/src/ui/separator.tsx +24 -0
- package/src/ui/sheet.tsx +141 -0
- package/src/ui/skeleton.tsx +76 -0
- package/src/ui/slider.tsx +76 -0
- package/src/ui/switch.tsx +31 -0
- package/src/ui/table.tsx +179 -0
- package/src/ui/tabs.tsx +89 -0
- package/src/ui/tags-input.tsx +168 -0
- package/src/ui/textarea.tsx +17 -0
- package/src/ui/tooltip.tsx +71 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ActionBarPrimitive,
|
|
5
|
+
AuiIf,
|
|
6
|
+
AttachmentPrimitive,
|
|
7
|
+
ComposerPrimitive,
|
|
8
|
+
MessagePrimitive,
|
|
9
|
+
ThreadPrimitive,
|
|
10
|
+
useAuiState,
|
|
11
|
+
} from "@assistant-ui/react";
|
|
12
|
+
import {
|
|
13
|
+
ArrowUpIcon,
|
|
14
|
+
AudioLines,
|
|
15
|
+
Calendar as CalendarIcon,
|
|
16
|
+
CheckIcon,
|
|
17
|
+
ChevronDownIcon,
|
|
18
|
+
ClipboardIcon,
|
|
19
|
+
Code as CodeIcon,
|
|
20
|
+
Download,
|
|
21
|
+
FolderOpen,
|
|
22
|
+
GraduationCap,
|
|
23
|
+
MoreHorizontal,
|
|
24
|
+
PencilIcon,
|
|
25
|
+
PenLine,
|
|
26
|
+
PlusIcon,
|
|
27
|
+
RefreshCwIcon,
|
|
28
|
+
Sparkle,
|
|
29
|
+
ThumbsDown,
|
|
30
|
+
ThumbsUp,
|
|
31
|
+
XIcon,
|
|
32
|
+
} from "lucide-react";
|
|
33
|
+
import { useState, type FC } from "react";
|
|
34
|
+
import { useAttachmentSrc } from "../stock/use-attachment-src";
|
|
35
|
+
import { MarkdownText } from "../stock/markdown-text";
|
|
36
|
+
import { MessageExportMenu } from "../stock/message-export-menu";
|
|
37
|
+
import { SkinCredit, useComposerCopy } from "../stock";
|
|
38
|
+
import {
|
|
39
|
+
DropdownMenu,
|
|
40
|
+
DropdownMenuContent,
|
|
41
|
+
DropdownMenuItem,
|
|
42
|
+
DropdownMenuSeparator,
|
|
43
|
+
DropdownMenuTrigger,
|
|
44
|
+
} from "./ui/dropdown-menu";
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
const messageActionButtonClassName =
|
|
48
|
+
"flex size-8 items-center justify-center rounded-md text-[#5b5950] transition-colors hover:bg-[#1a1a18]/5 hover:text-[#1a1a18] dark:text-[#a3a098] dark:hover:bg-white/5 dark:hover:text-[#eee]";
|
|
49
|
+
|
|
50
|
+
export const Claude: FC = () => {
|
|
51
|
+
return (
|
|
52
|
+
<ThreadPrimitive.Root data-export-thread="" className="flex h-full flex-col items-stretch bg-[#F0ECE0] font-serif text-[#1a1a18] dark:bg-[#2b2a27] dark:text-[#eee]">
|
|
53
|
+
<AuiIf condition={(s) => s.thread.isEmpty}>
|
|
54
|
+
<EmptyState />
|
|
55
|
+
</AuiIf>
|
|
56
|
+
|
|
57
|
+
<AuiIf condition={(s) => !s.thread.isEmpty}>
|
|
58
|
+
<ThreadPrimitive.Viewport className="flex grow flex-col overflow-y-auto px-4 pt-12">
|
|
59
|
+
<ThreadPrimitive.Messages>
|
|
60
|
+
{() => <ChatMessage />}
|
|
61
|
+
</ThreadPrimitive.Messages>
|
|
62
|
+
|
|
63
|
+
<ThreadPrimitive.ViewportFooter className="sticky bottom-0 mx-auto mt-auto w-full max-w-3xl bg-linear-to-b from-transparent via-[#F0ECE0]/85 to-[#F0ECE0] pt-4 pb-1 dark:via-[#2b2a27]/85 dark:to-[#2b2a27]">
|
|
64
|
+
<Composer />
|
|
65
|
+
<SkinCredit />
|
|
66
|
+
</ThreadPrimitive.ViewportFooter>
|
|
67
|
+
</ThreadPrimitive.Viewport>
|
|
68
|
+
</AuiIf>
|
|
69
|
+
</ThreadPrimitive.Root>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const EmptyState: FC = () => {
|
|
74
|
+
const { welcome } = useComposerCopy(
|
|
75
|
+
"How can I help you today?",
|
|
76
|
+
"How can I help you today?",
|
|
77
|
+
);
|
|
78
|
+
return (
|
|
79
|
+
<div className="relative flex grow flex-col items-center justify-center px-4">
|
|
80
|
+
<div className="mx-auto flex w-full max-w-2xl flex-col items-stretch gap-5">
|
|
81
|
+
<h1 className="flex items-center justify-center gap-3 font-serif text-3xl text-[#1a1a18] sm:text-4xl dark:text-[#eee]">
|
|
82
|
+
<Sparkle className="size-7 fill-[#c96442] text-[#c96442]" />
|
|
83
|
+
<span>{welcome}</span>
|
|
84
|
+
</h1>
|
|
85
|
+
<Composer />
|
|
86
|
+
<ModeTabs />
|
|
87
|
+
</div>
|
|
88
|
+
<div className="pointer-events-none absolute inset-x-0 bottom-0 px-4 pb-2">
|
|
89
|
+
<SkinCredit />
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const Composer: FC = () => {
|
|
96
|
+
const { placeholder } = useComposerCopy(
|
|
97
|
+
"How can I help you today?",
|
|
98
|
+
"How can I help you today?",
|
|
99
|
+
);
|
|
100
|
+
return (
|
|
101
|
+
<ComposerPrimitive.Root data-export-chrome="" className="flex w-full flex-col gap-2 rounded-2xl border border-[#E5E0D6] bg-white px-3.5 pt-3 pb-2.5 dark:border-[#3d3a35] dark:bg-[#1f1e1b]">
|
|
102
|
+
<ComposerPrimitive.Input
|
|
103
|
+
placeholder={placeholder}
|
|
104
|
+
rows={1}
|
|
105
|
+
className="block max-h-72 min-h-6 w-full resize-none bg-transparent text-[#1a1a18] outline-none placeholder:text-[#9a9893] dark:text-[#eee] dark:placeholder:text-[#9a9893]"
|
|
106
|
+
/>
|
|
107
|
+
|
|
108
|
+
<div className="flex w-full items-center gap-2">
|
|
109
|
+
<ComposerPrimitive.AddAttachment
|
|
110
|
+
aria-label="Add attachment"
|
|
111
|
+
className="flex size-8 shrink-0 items-center justify-center rounded-md text-[#5b5950] transition-colors hover:bg-[#1a1a18]/5 hover:text-[#1a1a18] dark:text-[#a3a098] dark:hover:bg-white/5 dark:hover:text-[#eee]"
|
|
112
|
+
>
|
|
113
|
+
<PlusIcon width={16} height={16} />
|
|
114
|
+
</ComposerPrimitive.AddAttachment>
|
|
115
|
+
|
|
116
|
+
<div className="ml-auto flex items-center gap-1">
|
|
117
|
+
<ClaudeModelPicker />
|
|
118
|
+
<ComposerPrimaryAction />
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<AuiIf condition={(s) => s.composer.attachments.length > 0}>
|
|
123
|
+
<div className="-mx-1 -mb-1 flex flex-row gap-2 overflow-x-auto pt-1">
|
|
124
|
+
<ComposerPrimitive.Attachments>
|
|
125
|
+
{() => <ClaudeAttachment />}
|
|
126
|
+
</ComposerPrimitive.Attachments>
|
|
127
|
+
</div>
|
|
128
|
+
</AuiIf>
|
|
129
|
+
</ComposerPrimitive.Root>
|
|
130
|
+
);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const ComposerPrimaryAction: FC = () => {
|
|
134
|
+
return (
|
|
135
|
+
<>
|
|
136
|
+
<AuiIf condition={(s) => s.thread.isRunning}>
|
|
137
|
+
<ComposerPrimitive.Cancel className="flex size-8 items-center justify-center rounded-md bg-[#c96442] text-white transition-colors hover:bg-[#b1573a]">
|
|
138
|
+
<div className="size-2.5 rounded-[2px] bg-current" />
|
|
139
|
+
</ComposerPrimitive.Cancel>
|
|
140
|
+
</AuiIf>
|
|
141
|
+
|
|
142
|
+
<AuiIf
|
|
143
|
+
condition={(s) => !s.thread.isRunning && s.composer.dictation != null}
|
|
144
|
+
>
|
|
145
|
+
<ComposerPrimitive.StopDictation
|
|
146
|
+
className="flex size-8 items-center justify-center rounded-md bg-[#c96442] text-white transition-colors hover:bg-[#b1573a]"
|
|
147
|
+
aria-label="Stop dictation"
|
|
148
|
+
>
|
|
149
|
+
<div className="size-2.5 animate-pulse rounded-[2px] bg-current" />
|
|
150
|
+
</ComposerPrimitive.StopDictation>
|
|
151
|
+
</AuiIf>
|
|
152
|
+
|
|
153
|
+
<AuiIf
|
|
154
|
+
condition={(s) =>
|
|
155
|
+
!s.thread.isRunning &&
|
|
156
|
+
s.composer.dictation == null &&
|
|
157
|
+
!s.composer.isEmpty
|
|
158
|
+
}
|
|
159
|
+
>
|
|
160
|
+
<ComposerPrimitive.Send className="flex size-8 items-center justify-center rounded-md bg-[#c96442] text-white transition-colors hover:bg-[#b1573a] disabled:pointer-events-none disabled:opacity-50">
|
|
161
|
+
<ArrowUpIcon width={16} height={16} />
|
|
162
|
+
</ComposerPrimitive.Send>
|
|
163
|
+
</AuiIf>
|
|
164
|
+
|
|
165
|
+
<AuiIf
|
|
166
|
+
condition={(s) =>
|
|
167
|
+
!s.thread.isRunning &&
|
|
168
|
+
s.composer.dictation == null &&
|
|
169
|
+
s.composer.isEmpty
|
|
170
|
+
}
|
|
171
|
+
>
|
|
172
|
+
<ComposerPrimitive.Dictate
|
|
173
|
+
className="flex size-8 items-center justify-center rounded-md text-[#5b5950] transition-colors hover:bg-[#1a1a18]/5 hover:text-[#1a1a18] dark:text-[#a3a098] dark:hover:bg-white/5 dark:hover:text-[#eee]"
|
|
174
|
+
aria-label="Use voice mode"
|
|
175
|
+
>
|
|
176
|
+
<AudioLines className="size-4" />
|
|
177
|
+
</ComposerPrimitive.Dictate>
|
|
178
|
+
</AuiIf>
|
|
179
|
+
</>
|
|
180
|
+
);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const CLAUDE_MODELS = [
|
|
184
|
+
{
|
|
185
|
+
id: "sonnet-4.5",
|
|
186
|
+
name: "Sonnet 4.5",
|
|
187
|
+
description: "Smart, fast, everyday tasks",
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: "opus-4.7",
|
|
191
|
+
name: "Opus 4.7",
|
|
192
|
+
description: "Anthropic's most capable model",
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
id: "haiku-4.5",
|
|
196
|
+
name: "Haiku 4.5",
|
|
197
|
+
description: "Fastest, most affordable",
|
|
198
|
+
},
|
|
199
|
+
];
|
|
200
|
+
|
|
201
|
+
const ClaudeModelPicker: FC = () => {
|
|
202
|
+
const [model, setModel] = useState(CLAUDE_MODELS[0]!.id);
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<div data-deploy-model-picker className="contents">
|
|
206
|
+
<DropdownMenu>
|
|
207
|
+
<DropdownMenuTrigger className="flex h-8 items-center gap-1 rounded-md px-2.5 text-sm whitespace-nowrap text-[#1a1a18] transition hover:bg-[#1a1a18]/5 dark:text-[#eee] dark:hover:bg-white/5">
|
|
208
|
+
<span className="font-serif">
|
|
209
|
+
{CLAUDE_MODELS.find((m) => m.id === model)?.name}
|
|
210
|
+
</span>
|
|
211
|
+
<ChevronDownIcon width={16} height={16} className="opacity-60" />
|
|
212
|
+
</DropdownMenuTrigger>
|
|
213
|
+
<DropdownMenuContent align="end" className="min-w-64">
|
|
214
|
+
{CLAUDE_MODELS.map((m) => (
|
|
215
|
+
<DropdownMenuItem
|
|
216
|
+
key={m.id}
|
|
217
|
+
onClick={() => setModel(m.id)}
|
|
218
|
+
className="flex items-start gap-3"
|
|
219
|
+
>
|
|
220
|
+
<span className="mt-0.5 flex size-4 items-center justify-center text-[#c96442]">
|
|
221
|
+
{m.id === model ? <CheckIcon /> : null}
|
|
222
|
+
</span>
|
|
223
|
+
<span className="flex flex-1 flex-col">
|
|
224
|
+
<span className="text-foreground font-serif text-sm">
|
|
225
|
+
{m.name}
|
|
226
|
+
</span>
|
|
227
|
+
<span className="text-muted-foreground text-xs">
|
|
228
|
+
{m.description}
|
|
229
|
+
</span>
|
|
230
|
+
</span>
|
|
231
|
+
</DropdownMenuItem>
|
|
232
|
+
))}
|
|
233
|
+
<DropdownMenuSeparator />
|
|
234
|
+
<DropdownMenuItem className="text-muted-foreground text-sm">
|
|
235
|
+
More options
|
|
236
|
+
</DropdownMenuItem>
|
|
237
|
+
</DropdownMenuContent>
|
|
238
|
+
</DropdownMenu>
|
|
239
|
+
</div>
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const ModeTabs: FC = () => {
|
|
244
|
+
const tabs = [
|
|
245
|
+
{ label: "Write", Icon: PenLine },
|
|
246
|
+
{ label: "Learn", Icon: GraduationCap },
|
|
247
|
+
{ label: "Code", Icon: CodeIcon },
|
|
248
|
+
{ label: "From Drive", Icon: FolderOpen },
|
|
249
|
+
{ label: "From Calendar", Icon: CalendarIcon },
|
|
250
|
+
];
|
|
251
|
+
|
|
252
|
+
return (
|
|
253
|
+
<div className="flex flex-wrap items-center justify-center gap-2">
|
|
254
|
+
{tabs.map(({ label, Icon }) => (
|
|
255
|
+
<button
|
|
256
|
+
key={label}
|
|
257
|
+
type="button"
|
|
258
|
+
aria-hidden="true"
|
|
259
|
+
tabIndex={-1}
|
|
260
|
+
className="flex h-8 items-center gap-1.5 rounded-lg border border-[#E5E0D6] bg-transparent px-3 text-sm whitespace-nowrap text-[#3d3a35] transition-colors hover:bg-white/60 dark:border-[#3d3a35] dark:text-[#cdc9be] dark:hover:bg-[#1f1e1b]/60"
|
|
261
|
+
>
|
|
262
|
+
<Icon className="size-3.5 text-[#8a8780] dark:text-[#a3a098]" />
|
|
263
|
+
<span className="font-serif">{label}</span>
|
|
264
|
+
</button>
|
|
265
|
+
))}
|
|
266
|
+
</div>
|
|
267
|
+
);
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const ChatMessage: FC = () => {
|
|
271
|
+
const role = useAuiState((s) => s.message.role);
|
|
272
|
+
return (
|
|
273
|
+
<MessagePrimitive.Root data-role={role} className="group/message relative mx-auto flex w-full max-w-3xl flex-col py-2">
|
|
274
|
+
<AuiIf condition={(s) => s.message.role === "user"}>
|
|
275
|
+
<div className="flex flex-col items-end gap-1">
|
|
276
|
+
<div className="max-w-[80%] rounded-2xl bg-[#E5E0D6] px-4 py-2.5 wrap-break-word whitespace-pre-wrap text-[#1a1a18] dark:bg-[#393937] dark:text-[#eee]">
|
|
277
|
+
<MessagePrimitive.Parts>
|
|
278
|
+
{({ part }) => {
|
|
279
|
+
if (part.type === "text") return <MarkdownText />;
|
|
280
|
+
return null;
|
|
281
|
+
}}
|
|
282
|
+
</MessagePrimitive.Parts>
|
|
283
|
+
</div>
|
|
284
|
+
<ActionBarPrimitive.Root data-export-chrome="" className="-mt-px flex items-center gap-0.5 opacity-0 transition-opacity group-focus-within/message:opacity-100 group-hover/message:opacity-100">
|
|
285
|
+
<ActionBarPrimitive.Edit className={messageActionButtonClassName}>
|
|
286
|
+
<PencilIcon width={16} height={16} />
|
|
287
|
+
</ActionBarPrimitive.Edit>
|
|
288
|
+
<ActionBarPrimitive.Copy className={messageActionButtonClassName}>
|
|
289
|
+
<AuiIf condition={(s) => s.message.isCopied}>
|
|
290
|
+
<CheckIcon />
|
|
291
|
+
</AuiIf>
|
|
292
|
+
<AuiIf condition={(s) => !s.message.isCopied}>
|
|
293
|
+
<ClipboardIcon width={16} height={16} />
|
|
294
|
+
</AuiIf>
|
|
295
|
+
</ActionBarPrimitive.Copy>
|
|
296
|
+
</ActionBarPrimitive.Root>
|
|
297
|
+
</div>
|
|
298
|
+
</AuiIf>
|
|
299
|
+
|
|
300
|
+
<AuiIf condition={(s) => s.message.role === "assistant"}>
|
|
301
|
+
<div className="flex flex-col">
|
|
302
|
+
<div className="prose prose-claude font-serif leading-[1.65rem] wrap-break-word text-[#1a1a18] dark:text-[#eee]">
|
|
303
|
+
<MessagePrimitive.Parts>
|
|
304
|
+
{({ part }) => {
|
|
305
|
+
if (part.type === "text") return <MarkdownText />;
|
|
306
|
+
return null;
|
|
307
|
+
}}
|
|
308
|
+
</MessagePrimitive.Parts>
|
|
309
|
+
</div>
|
|
310
|
+
<ActionBarPrimitive.Root data-export-chrome="" className="mt-2 flex items-center gap-0.5 opacity-0 transition-opacity group-focus-within/message:opacity-100 group-hover/message:opacity-100">
|
|
311
|
+
<ActionBarPrimitive.Copy className={messageActionButtonClassName}>
|
|
312
|
+
<AuiIf condition={(s) => s.message.isCopied}>
|
|
313
|
+
<CheckIcon />
|
|
314
|
+
</AuiIf>
|
|
315
|
+
<AuiIf condition={(s) => !s.message.isCopied}>
|
|
316
|
+
<ClipboardIcon width={16} height={16} />
|
|
317
|
+
</AuiIf>
|
|
318
|
+
</ActionBarPrimitive.Copy>
|
|
319
|
+
<ActionBarPrimitive.FeedbackPositive
|
|
320
|
+
className={messageActionButtonClassName}
|
|
321
|
+
>
|
|
322
|
+
<ThumbsUp className="size-4" />
|
|
323
|
+
</ActionBarPrimitive.FeedbackPositive>
|
|
324
|
+
<ActionBarPrimitive.FeedbackNegative
|
|
325
|
+
className={messageActionButtonClassName}
|
|
326
|
+
>
|
|
327
|
+
<ThumbsDown className="size-4" />
|
|
328
|
+
</ActionBarPrimitive.FeedbackNegative>
|
|
329
|
+
<ActionBarPrimitive.Reload className={messageActionButtonClassName}>
|
|
330
|
+
<RefreshCwIcon width={16} height={16} />
|
|
331
|
+
</ActionBarPrimitive.Reload>
|
|
332
|
+
<MessageExportMenu
|
|
333
|
+
trigger={
|
|
334
|
+
<button type="button" aria-label="More" className={messageActionButtonClassName}>
|
|
335
|
+
<MoreHorizontal width={16} height={16} />
|
|
336
|
+
</button>
|
|
337
|
+
}
|
|
338
|
+
icon={<Download className="size-4" />}
|
|
339
|
+
align="start"
|
|
340
|
+
contentClassName="bg-popover text-popover-foreground data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:animate-out z-50 min-w-40 overflow-hidden rounded-xl border p-1.5 shadow-md"
|
|
341
|
+
itemClassName="text-muted-foreground focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-pointer items-center gap-2.5 rounded-lg px-3 py-2 text-sm outline-none select-none"
|
|
342
|
+
/>
|
|
343
|
+
</ActionBarPrimitive.Root>
|
|
344
|
+
</div>
|
|
345
|
+
</AuiIf>
|
|
346
|
+
</MessagePrimitive.Root>
|
|
347
|
+
);
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
const ClaudeAttachment: FC = () => {
|
|
351
|
+
const isImage = useAuiState((s) => s.attachment.type === "image");
|
|
352
|
+
const src = useAttachmentSrc();
|
|
353
|
+
|
|
354
|
+
return (
|
|
355
|
+
<AttachmentPrimitive.Root className="group/thumbnail relative">
|
|
356
|
+
<div
|
|
357
|
+
className="overflow-hidden rounded-lg border border-[#E5E0D6] dark:border-[#3d3a35]"
|
|
358
|
+
style={{ width: "80px", height: "80px" }}
|
|
359
|
+
>
|
|
360
|
+
{isImage && src ? (
|
|
361
|
+
<img
|
|
362
|
+
className="h-full w-full object-cover"
|
|
363
|
+
alt="Attachment"
|
|
364
|
+
src={src}
|
|
365
|
+
/>
|
|
366
|
+
) : (
|
|
367
|
+
<div className="flex h-full w-full items-center justify-center bg-white text-[#5b5950] dark:bg-[#2b2a27] dark:text-[#a3a098]">
|
|
368
|
+
<AttachmentPrimitive.unstable_Thumb className="text-xs" />
|
|
369
|
+
</div>
|
|
370
|
+
)}
|
|
371
|
+
</div>
|
|
372
|
+
<AttachmentPrimitive.Remove
|
|
373
|
+
className="absolute -top-1.5 -right-1.5 flex size-5 items-center justify-center rounded-full bg-[#1a1a18] text-white opacity-0 transition-opacity group-focus-within/thumbnail:opacity-100 group-hover/thumbnail:opacity-100 hover:bg-[#3d3a35] dark:bg-white dark:text-[#1a1a18] dark:hover:bg-[#cdc9be]"
|
|
374
|
+
aria-label="Remove attachment"
|
|
375
|
+
>
|
|
376
|
+
<XIcon width={12} height={12} />
|
|
377
|
+
</AttachmentPrimitive.Remove>
|
|
378
|
+
</AttachmentPrimitive.Root>
|
|
379
|
+
);
|
|
380
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Fragment, type ReactNode } from "react";
|
|
4
|
+
import type { EmbedChatPrefsApi } from "../stock/embed-chat-prefs";
|
|
5
|
+
import { connectedToolIsOn, countToolSurface } from "../stock/tool-surface";
|
|
6
|
+
import { DigichatContextMeter } from "./digichat-context-meter";
|
|
7
|
+
import { DigichatUsageMeter } from "./digichat-usage-meter";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Plain-text composer footer for the digichat skin. Shows the selected
|
|
11
|
+
* model and the active backend on the left and the context fill on the
|
|
12
|
+
* right. Clicking the model opens the full settings menu — that is the only
|
|
13
|
+
* control here; the settings button and the per-control chips are gone.
|
|
14
|
+
*
|
|
15
|
+
* The backend chip is a backend indicator, so it appears only where BYOK is
|
|
16
|
+
* on the table (`showByok`) and the host named the backend that serves the
|
|
17
|
+
* chat (`providerLabel`). The label is the host's: this package holds no
|
|
18
|
+
* provider vocabulary, and a host that cannot name the backend shows no
|
|
19
|
+
* chip rather than a wrong one.
|
|
20
|
+
*/
|
|
21
|
+
export function DigichatComposerToolbar({ prefs }: { prefs: EmbedChatPrefsApi }) {
|
|
22
|
+
const sessionModel = prefs.prefs.model.trim();
|
|
23
|
+
// The chip names the session model. The bar sizes to the model the turn
|
|
24
|
+
// sends (`meterModel`), including a bring-your-own-key binding.
|
|
25
|
+
const modelLabel = sessionModel || "auto";
|
|
26
|
+
const meterModel = prefs.meterModel?.trim() || sessionModel;
|
|
27
|
+
const providerLabel = prefs.providerLabel?.trim() ?? "";
|
|
28
|
+
// The backend is named whenever the host named one — a Foundry tenant is
|
|
29
|
+
// served by Azure AI Foundry, not by the house model provider. It is a
|
|
30
|
+
// button only where the tenant can switch it.
|
|
31
|
+
const showProvider = providerLabel.length > 0;
|
|
32
|
+
|
|
33
|
+
// Connected MCP servers and the tools inside them: one ticket server with
|
|
34
|
+
// five tools reads "1 MCP / 5 tools", not "5 MCPs". The rows come from the
|
|
35
|
+
// same expansion `/tools` renders (`../stock/tool-surface`), so the count
|
|
36
|
+
// and the list behind it cannot disagree. Per-tool toggles live in
|
|
37
|
+
// prefs.extra (tool id -> off); a row follows its own switch.
|
|
38
|
+
const toolSwitch = {
|
|
39
|
+
digisearch: prefs.hasDigisearch,
|
|
40
|
+
vault: prefs.hasVault,
|
|
41
|
+
webSearch: prefs.tenantAllowsWeb,
|
|
42
|
+
extraToolOn: prefs.extraToolOn,
|
|
43
|
+
};
|
|
44
|
+
const mcpCounts = countToolSurface(prefs.mcpServers, {
|
|
45
|
+
isOn: (id) => connectedToolIsOn(id, toolSwitch),
|
|
46
|
+
isToolOn: prefs.extraToolOn,
|
|
47
|
+
});
|
|
48
|
+
const mcpToolTotal = mcpCounts.tools;
|
|
49
|
+
|
|
50
|
+
// The row is a list of facts separated by slashes. Build the list and
|
|
51
|
+
// join it, so a tenant that has no model (or no provider) never leaves a
|
|
52
|
+
// dangling separator at the front.
|
|
53
|
+
const items: ReactNode[] = [];
|
|
54
|
+
|
|
55
|
+
if (prefs.showModels) {
|
|
56
|
+
items.push(
|
|
57
|
+
<button
|
|
58
|
+
key="model"
|
|
59
|
+
type="button"
|
|
60
|
+
className="aui-composer-meta aui-composer-meta-action"
|
|
61
|
+
onClick={prefs.openModels}
|
|
62
|
+
aria-label="Open models"
|
|
63
|
+
>
|
|
64
|
+
{modelLabel}
|
|
65
|
+
</button>,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (showProvider) {
|
|
70
|
+
items.push(
|
|
71
|
+
prefs.showByok ? (
|
|
72
|
+
<button
|
|
73
|
+
key="provider"
|
|
74
|
+
type="button"
|
|
75
|
+
className="aui-composer-meta aui-composer-meta-action"
|
|
76
|
+
onClick={() => prefs.openByok()}
|
|
77
|
+
aria-label="Open provider menu"
|
|
78
|
+
>
|
|
79
|
+
{providerLabel}
|
|
80
|
+
</button>
|
|
81
|
+
) : (
|
|
82
|
+
<span key="provider" className="aui-composer-meta">
|
|
83
|
+
{providerLabel}
|
|
84
|
+
</span>
|
|
85
|
+
),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (mcpCounts.servers > 0) {
|
|
90
|
+
items.push(
|
|
91
|
+
<button
|
|
92
|
+
key="mcp"
|
|
93
|
+
type="button"
|
|
94
|
+
className="aui-composer-meta aui-composer-meta-action"
|
|
95
|
+
onClick={() => prefs.openMcp()}
|
|
96
|
+
aria-label="Open MCP servers"
|
|
97
|
+
>
|
|
98
|
+
{mcpCounts.servers} MCP{mcpCounts.servers === 1 ? "" : "s"}
|
|
99
|
+
</button>,
|
|
100
|
+
<button
|
|
101
|
+
key="tools"
|
|
102
|
+
type="button"
|
|
103
|
+
className="aui-composer-meta aui-composer-meta-action"
|
|
104
|
+
onClick={() => prefs.openTools()}
|
|
105
|
+
aria-label="Open tools"
|
|
106
|
+
>
|
|
107
|
+
{mcpCounts.tools} tool{mcpCounts.tools === 1 ? "" : "s"}
|
|
108
|
+
</button>,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
items.push(
|
|
113
|
+
<button
|
|
114
|
+
key="language"
|
|
115
|
+
type="button"
|
|
116
|
+
className="aui-composer-meta aui-composer-meta-action"
|
|
117
|
+
onClick={() => prefs.openLanguage()}
|
|
118
|
+
aria-label="Open response language"
|
|
119
|
+
>
|
|
120
|
+
{prefs.prefs.language.slice(0, 2).toUpperCase()}
|
|
121
|
+
</button>,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<div data-slot="aui_composer-toolbar-inner" className="aui-composer-toolbar-inner">
|
|
126
|
+
{items.map((item, index) => (
|
|
127
|
+
<Fragment key={index}>
|
|
128
|
+
{index > 0 ? (
|
|
129
|
+
<span className="aui-composer-meta-sep" aria-hidden>
|
|
130
|
+
/
|
|
131
|
+
</span>
|
|
132
|
+
) : null}
|
|
133
|
+
{item}
|
|
134
|
+
</Fragment>
|
|
135
|
+
))}
|
|
136
|
+
<span className="aui-composer-meta-spacer" aria-hidden />
|
|
137
|
+
{/* A gate budget outranks the context estimate: it is the number that
|
|
138
|
+
stops the visitor, and it is available even when the backend
|
|
139
|
+
reports no token usage at all (a Foundry agent). A zero budget is
|
|
140
|
+
not a meter, so it falls through to the context slot. */}
|
|
141
|
+
{prefs.usage && prefs.usage.limit > 0 ? (
|
|
142
|
+
<DigichatUsageMeter usage={prefs.usage} />
|
|
143
|
+
) : prefs.showContextMeter ? (
|
|
144
|
+
<DigichatContextMeter
|
|
145
|
+
model={meterModel}
|
|
146
|
+
toolCount={mcpToolTotal + prefs.catalogTools.length}
|
|
147
|
+
/>
|
|
148
|
+
) : null}
|
|
149
|
+
</div>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The context meter's share arithmetic, kept out of the component so it
|
|
3
|
+
* can be tested without a React tree.
|
|
4
|
+
*
|
|
5
|
+
* Decision (DIG-4459, #5967): the provider reports only the prompt
|
|
6
|
+
* total, so the system / tools / user split is an estimate. The three
|
|
7
|
+
* quantities are therefore a PARTITION of that reported total, never
|
|
8
|
+
* three independent estimates of it. The measured user text is clamped
|
|
9
|
+
* into the total first, the flat per-tool allowance is clamped into what
|
|
10
|
+
* is left, and the system prompt takes the remainder. The consequence is
|
|
11
|
+
* that the three token counts always sum to the reported total, so no
|
|
12
|
+
* share can print above 100 and the printed numbers always describe the
|
|
13
|
+
* same turn.
|
|
14
|
+
*
|
|
15
|
+
* The percentages are each computed from their own token count and then
|
|
16
|
+
* normalised to exactly 100 by the largest-remainder method, because
|
|
17
|
+
* independent rounding can sum to 99 or 101 and a leftover-derived
|
|
18
|
+
* share would then be wrong (the old leftover share went negative on a
|
|
19
|
+
* rounding remainder).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/** Bar segments in the context meter grid. */
|
|
23
|
+
export const CONTEXT_BAR_CELLS = 25;
|
|
24
|
+
|
|
25
|
+
/** Rough tokens per tool schema (name, description, JSON schema). */
|
|
26
|
+
export const CONTEXT_TOKENS_PER_TOOL = 220;
|
|
27
|
+
|
|
28
|
+
export type ContextMeterShares = {
|
|
29
|
+
/** Token counts. They sum to the reported prompt total. */
|
|
30
|
+
systemTokens: number;
|
|
31
|
+
toolTokens: number;
|
|
32
|
+
userTokens: number;
|
|
33
|
+
/** Percentages. They sum to exactly 100 when a turn reported usage. */
|
|
34
|
+
systemPct: number;
|
|
35
|
+
toolPct: number;
|
|
36
|
+
userPct: number;
|
|
37
|
+
/** Bar cells. They sum to the used span. */
|
|
38
|
+
systemCells: number;
|
|
39
|
+
toolCells: number;
|
|
40
|
+
userCells: number;
|
|
41
|
+
/** Bar cells in the used span. */
|
|
42
|
+
usedCells: number;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type ContextMeterInput = {
|
|
46
|
+
/** Prompt total the provider reported for the last turn, 0 when unknown. */
|
|
47
|
+
input: number;
|
|
48
|
+
/** Characters of user text in the thread. */
|
|
49
|
+
userChars: number;
|
|
50
|
+
/** Connected tool count, used for the schema estimate. */
|
|
51
|
+
toolCount: number;
|
|
52
|
+
/** The model's context window, in tokens. */
|
|
53
|
+
window: number;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** Rough tokens for the user text held in the thread. */
|
|
57
|
+
const userTokensFromChars = (userChars: number): number =>
|
|
58
|
+
Math.round(userChars / 4);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Round exact shares so the rounded values sum to exactly 100.
|
|
62
|
+
*
|
|
63
|
+
* Largest remainder: floor every share, then hand the leftover points
|
|
64
|
+
* to the shares with the biggest fractional part. Each result stays
|
|
65
|
+
* within one point of its exact share and no result is negative.
|
|
66
|
+
*/
|
|
67
|
+
const normaliseToHundred = (exact: readonly number[]): number[] => {
|
|
68
|
+
const rounded = exact.map((value) => Math.floor(value));
|
|
69
|
+
const exactTotal = exact.reduce((sum, value) => sum + value, 0);
|
|
70
|
+
// Only a set of exact shares that adds up to a hundred can be
|
|
71
|
+
// normalised. Anything else (no reported usage) is left alone, so the
|
|
72
|
+
// leftover points are never handed out against nothing.
|
|
73
|
+
if (Math.abs(exactTotal - 100) > 0.5) {
|
|
74
|
+
return exact.map((value) => Math.round(value));
|
|
75
|
+
}
|
|
76
|
+
let leftover = 100 - rounded.reduce((sum, value) => sum + value, 0);
|
|
77
|
+
if (leftover <= 0) return rounded;
|
|
78
|
+
const order = exact
|
|
79
|
+
.map((value, index) => ({
|
|
80
|
+
index,
|
|
81
|
+
fraction: value - Math.floor(value),
|
|
82
|
+
}))
|
|
83
|
+
.sort((a, b) => b.fraction - a.fraction || a.index - b.index);
|
|
84
|
+
for (const { index } of order) {
|
|
85
|
+
if (leftover <= 0) break;
|
|
86
|
+
rounded[index] += 1;
|
|
87
|
+
leftover -= 1;
|
|
88
|
+
}
|
|
89
|
+
return rounded;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Split a reported prompt total into system, tools and user.
|
|
94
|
+
*
|
|
95
|
+
* The token counts are a partition of `input`, so they always sum to it
|
|
96
|
+
* and no share can exceed 100. The percentages are each derived from
|
|
97
|
+
* their own token count and normalised to exactly 100.
|
|
98
|
+
*/
|
|
99
|
+
export const computeContextShares = ({
|
|
100
|
+
input,
|
|
101
|
+
userChars,
|
|
102
|
+
toolCount,
|
|
103
|
+
window,
|
|
104
|
+
}: ContextMeterInput): ContextMeterShares => {
|
|
105
|
+
const total = input > 0 ? input : 0;
|
|
106
|
+
|
|
107
|
+
// Partition of the reported total: measured text first, then the flat
|
|
108
|
+
// tool estimate into what is left, then the remainder is the system
|
|
109
|
+
// prompt.
|
|
110
|
+
const userTokens =
|
|
111
|
+
total > 0 ? Math.min(userTokensFromChars(userChars), total) : 0;
|
|
112
|
+
const toolTokens =
|
|
113
|
+
total > 0
|
|
114
|
+
? Math.min(toolCount * CONTEXT_TOKENS_PER_TOOL, total - userTokens)
|
|
115
|
+
: 0;
|
|
116
|
+
const systemTokens = total - userTokens - toolTokens;
|
|
117
|
+
|
|
118
|
+
const exact =
|
|
119
|
+
total > 0
|
|
120
|
+
? [
|
|
121
|
+
(userTokens / total) * 100,
|
|
122
|
+
(toolTokens / total) * 100,
|
|
123
|
+
(systemTokens / total) * 100,
|
|
124
|
+
]
|
|
125
|
+
: [0, 0, 0];
|
|
126
|
+
// With no reported usage there is nothing to normalise: the three
|
|
127
|
+
// exact shares are zero, not a third of a hundred each.
|
|
128
|
+
const [userPct, toolPct, systemPct] =
|
|
129
|
+
total > 0 ? normaliseToHundred(exact) : [0, 0, 0];
|
|
130
|
+
|
|
131
|
+
// The used span grows with the window ratio; inside it the three types
|
|
132
|
+
// take their share of the prompt.
|
|
133
|
+
const ratio = window > 0 ? Math.min(1, total / window) : 0;
|
|
134
|
+
const usedCells =
|
|
135
|
+
total > 0 ? Math.max(1, Math.round(ratio * CONTEXT_BAR_CELLS)) : 0;
|
|
136
|
+
const systemCells = Math.min(
|
|
137
|
+
usedCells,
|
|
138
|
+
total > 0 ? Math.round((usedCells * systemTokens) / total) : 0,
|
|
139
|
+
);
|
|
140
|
+
const toolCells = Math.min(
|
|
141
|
+
usedCells - systemCells,
|
|
142
|
+
total > 0 ? Math.round((usedCells * toolTokens) / total) : 0,
|
|
143
|
+
);
|
|
144
|
+
const userCells = Math.max(0, usedCells - systemCells - toolCells);
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
systemTokens,
|
|
148
|
+
toolTokens,
|
|
149
|
+
userTokens,
|
|
150
|
+
systemPct,
|
|
151
|
+
toolPct,
|
|
152
|
+
userPct,
|
|
153
|
+
systemCells,
|
|
154
|
+
toolCells,
|
|
155
|
+
userCells,
|
|
156
|
+
usedCells,
|
|
157
|
+
};
|
|
158
|
+
};
|