@vertesia/ui 1.6.0-dev.20261008.064737Z → 1.6.0-dev.20261014.015055Z
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 +24 -0
- package/lib/boot/index.d.ts +12 -1
- package/lib/boot/index.d.ts.map +1 -1
- package/lib/boot/index.js +65 -10
- package/lib/boot/index.js.map +1 -1
- package/lib/boot/text.d.ts +13 -0
- package/lib/boot/text.d.ts.map +1 -0
- package/lib/boot/text.js +68 -0
- package/lib/boot/text.js.map +1 -0
- package/lib/core/components/shadcn/button.d.ts +1 -0
- package/lib/core/components/shadcn/button.d.ts.map +1 -1
- package/lib/core/components/shadcn/button.js +2 -2
- package/lib/core/components/shadcn/button.js.map +1 -1
- package/lib/core/components/shadcn/selectBox.d.ts.map +1 -1
- package/lib/core/components/shadcn/selectBox.js +2 -2
- package/lib/core/components/shadcn/selectBox.js.map +1 -1
- package/lib/env/index.d.ts +1 -1
- package/lib/env/index.d.ts.map +1 -1
- package/lib/env/index.js +1 -1
- package/lib/env/index.js.map +1 -1
- package/lib/features/agent/PayloadBuilder.d.ts +6 -0
- package/lib/features/agent/PayloadBuilder.d.ts.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.d.ts.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.js +2 -1
- package/lib/features/agent/chat/AskUserWidget.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +6 -4
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +2 -253
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts +1 -3
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js +2 -8
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js +58 -0
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.d.ts +4 -0
- package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.js +248 -0
- package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.js.map +1 -0
- package/lib/features/agent/chat/SkillWidgetProvider.d.ts.map +1 -1
- package/lib/features/agent/chat/SkillWidgetProvider.js +3 -2
- package/lib/features/agent/chat/SkillWidgetProvider.js.map +1 -1
- package/lib/i18n/LanguageProvider.d.ts +9 -1
- package/lib/i18n/LanguageProvider.d.ts.map +1 -1
- package/lib/i18n/LanguageProvider.js +7 -4
- package/lib/i18n/LanguageProvider.js.map +1 -1
- package/lib/i18n/locales/ar.json +6 -1
- package/lib/i18n/locales/de.json +6 -1
- package/lib/i18n/locales/en.json +6 -1
- package/lib/i18n/locales/es.json +6 -1
- package/lib/i18n/locales/fr.json +6 -1
- package/lib/i18n/locales/it.json +6 -1
- package/lib/i18n/locales/ja.json +6 -1
- package/lib/i18n/locales/ko.json +6 -1
- package/lib/i18n/locales/pt.json +6 -1
- package/lib/i18n/locales/ru.json +6 -1
- package/lib/i18n/locales/tr.json +6 -1
- package/lib/i18n/locales/zh-TW.json +6 -1
- package/lib/i18n/locales/zh.json +6 -1
- package/lib/i18n/rtl.d.ts +4 -2
- package/lib/i18n/rtl.d.ts.map +1 -1
- package/lib/i18n/rtl.js +4 -2
- package/lib/i18n/rtl.js.map +1 -1
- package/lib/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/session/UserSessionProvider.js +10 -4
- package/lib/session/UserSessionProvider.js.map +1 -1
- package/lib/session/auth/composable.d.ts +1 -5
- package/lib/session/auth/composable.d.ts.map +1 -1
- package/lib/session/auth/composable.js +1 -10
- package/lib/session/auth/composable.js.map +1 -1
- package/lib/session/auth/firebase.d.ts.map +1 -1
- package/lib/session/auth/firebase.js +8 -5
- package/lib/session/auth/firebase.js.map +1 -1
- package/lib/session/auth/oauth.d.ts.map +1 -1
- package/lib/session/auth/oauth.js +53 -25
- package/lib/session/auth/oauth.js.map +1 -1
- package/lib/session/auth/vertesiaHosts.d.ts +0 -40
- package/lib/session/auth/vertesiaHosts.d.ts.map +1 -1
- package/lib/session/auth/vertesiaHosts.js +2 -45
- package/lib/session/auth/vertesiaHosts.js.map +1 -1
- package/lib/session/index.d.ts +1 -1
- package/lib/session/index.d.ts.map +1 -1
- package/lib/session/index.js +1 -1
- package/lib/session/index.js.map +1 -1
- package/lib/session/scopeSelection.d.ts +4 -0
- package/lib/session/scopeSelection.d.ts.map +1 -1
- package/lib/session/scopeSelection.js +11 -0
- package/lib/session/scopeSelection.js.map +1 -1
- package/lib/shell/VertesiaShell.d.ts +7 -2
- package/lib/shell/VertesiaShell.d.ts.map +1 -1
- package/lib/shell/VertesiaShell.js +2 -2
- package/lib/shell/VertesiaShell.js.map +1 -1
- package/lib/shell/login/InviteAcceptModal.d.ts.map +1 -1
- package/lib/shell/login/InviteAcceptModal.js +83 -42
- package/lib/shell/login/InviteAcceptModal.js.map +1 -1
- package/lib/vertesia-ui-boot.js +52 -15
- package/lib/vertesia-ui-boot.js.map +1 -1
- package/lib/vertesia-ui-core.js +44 -44
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-env.js +1 -1
- package/lib/vertesia-ui-env.js.map +1 -1
- package/lib/vertesia-ui-features.js +570 -585
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.B1Nd8-dE.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.B1Nd8-dE.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.B2Z7mx1x.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.B2Z7mx1x.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.B756-YtS.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.B756-YtS.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.BICdgAEn.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.BICdgAEn.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.B_yx0c2A.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.B_yx0c2A.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.BwPrGiQn.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.BwPrGiQn.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.CfQbOHm3.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.CfQbOHm3.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.DMISlF16.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.DMISlF16.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.D_WA36Yq.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.D_WA36Yq.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.Dp3KuMs-.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.Dp3KuMs-.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.DsioKoQ3.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.DsioKoQ3.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.QEIqEPlv.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.QEIqEPlv.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.js +2 -2
- package/lib/vertesia-ui-i18n.js.map +1 -1
- package/lib/vertesia-ui-layout.js +15 -15
- package/lib/vertesia-ui-layout.js.map +1 -1
- package/lib/vertesia-ui-rich-text.js +44 -44
- package/lib/vertesia-ui-rich-text.js.map +1 -1
- package/lib/vertesia-ui-session.js +1 -1
- package/lib/vertesia-ui-session.js.map +1 -1
- package/lib/vertesia-ui-shell.js +51 -51
- package/lib/vertesia-ui-shell.js.map +1 -1
- package/lib/vertesia-ui-widgets.js +51 -51
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/package.json +20 -20
- package/src/boot/index.ts +74 -11
- package/src/boot/text.ts +80 -0
- package/src/core/components/shadcn/button.tsx +3 -2
- package/src/core/components/shadcn/selectBox.tsx +12 -4
- package/src/css/index.css +1 -1
- package/src/css/typography.css +111 -88
- package/src/env/index.ts +0 -2
- package/src/features/agent/chat/AskUserWidget.tsx +3 -1
- package/src/features/agent/chat/ModernAgentConversation.tsx +7 -4
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +2 -253
- package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.tsx +2 -8
- package/src/features/agent/chat/ModernAgentOutput/SummaryConversation.ts +60 -0
- package/src/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.ts +248 -0
- package/src/features/agent/chat/SkillWidgetProvider.tsx +3 -2
- package/src/i18n/LanguageProvider.tsx +16 -4
- package/src/i18n/locales/ar.json +6 -1
- package/src/i18n/locales/de.json +6 -1
- package/src/i18n/locales/en.json +6 -1
- package/src/i18n/locales/es.json +6 -1
- package/src/i18n/locales/fr.json +6 -1
- package/src/i18n/locales/it.json +6 -1
- package/src/i18n/locales/ja.json +6 -1
- package/src/i18n/locales/ko.json +6 -1
- package/src/i18n/locales/pt.json +6 -1
- package/src/i18n/locales/ru.json +6 -1
- package/src/i18n/locales/tr.json +6 -1
- package/src/i18n/locales/zh-TW.json +6 -1
- package/src/i18n/locales/zh.json +6 -1
- package/src/i18n/rtl.ts +5 -2
- package/src/session/UserSessionProvider.tsx +11 -4
- package/src/session/auth/composable.ts +1 -11
- package/src/session/auth/firebase.ts +9 -6
- package/src/session/auth/oauth.ts +65 -25
- package/src/session/auth/vertesiaHosts.ts +2 -47
- package/src/session/index.ts +1 -1
- package/src/session/scopeSelection.ts +13 -0
- package/src/shell/VertesiaShell.tsx +8 -2
- package/src/shell/login/InviteAcceptModal.tsx +112 -65
- package/lib/vertesia-ui-i18n.B0orbJb6.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.B0orbJb6.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BChwIQVA.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BChwIQVA.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BTEcAVQm.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BTEcAVQm.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BeJQKbv7.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BeJQKbv7.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BpGr0-5g.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BpGr0-5g.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.Bs8x-1wI.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.Bs8x-1wI.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BymQoOm0.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BymQoOm0.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.CNT_wabV.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.CNT_wabV.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.Cxh1iVk0.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.Cxh1iVk0.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.DLYCM9fV.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.DLYCM9fV.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.QvAVguDs.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.QvAVguDs.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.smozeSmI.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.smozeSmI.chunk.js.map +0 -1
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
} from '../workstreams.js';
|
|
44
44
|
import { createAgentMarkdownAnchor } from './AgentMarkdownAnchor';
|
|
45
45
|
import { AttachmentPreviewList, parseUserMessageAttachments } from './AttachmentPreview';
|
|
46
|
+
import { agentMarkdownStyles } from './agentMarkdownStyles.js';
|
|
46
47
|
import BatchProgressPanel, { type BatchProgressPanelClassNames } from './BatchProgressPanel';
|
|
47
48
|
import {
|
|
48
49
|
AGENT_LINE_CLAMP_CLASS,
|
|
@@ -3118,259 +3119,7 @@ function AllMessagesMixedComponent({
|
|
|
3118
3119
|
data-view-mode={viewMode}
|
|
3119
3120
|
>
|
|
3120
3121
|
{/* Global styles for vprose markdown content */}
|
|
3121
|
-
<style>{
|
|
3122
|
-
/* Better vertical rhythm for markdown */
|
|
3123
|
-
.vprose > * + * {
|
|
3124
|
-
margin-top: 0.625rem;
|
|
3125
|
-
}
|
|
3126
|
-
.vprose > h1 + *,
|
|
3127
|
-
.vprose > h2 + *,
|
|
3128
|
-
.vprose > h3 + * {
|
|
3129
|
-
margin-top: 0.375rem;
|
|
3130
|
-
}
|
|
3131
|
-
/* Tables should read like part of the conversation, not a separate app grid. */
|
|
3132
|
-
.vprose table {
|
|
3133
|
-
margin-top: 0.875rem;
|
|
3134
|
-
margin-bottom: 0.875rem;
|
|
3135
|
-
border-collapse: collapse;
|
|
3136
|
-
width: 100%;
|
|
3137
|
-
background: transparent;
|
|
3138
|
-
}
|
|
3139
|
-
.vprose th,
|
|
3140
|
-
.vprose td {
|
|
3141
|
-
padding: 0.5rem 0.625rem;
|
|
3142
|
-
border: 0;
|
|
3143
|
-
border-bottom: 1px solid color-mix(in oklch, var(--border) 70%, transparent);
|
|
3144
|
-
background: transparent;
|
|
3145
|
-
text-align: left;
|
|
3146
|
-
}
|
|
3147
|
-
.vprose thead th {
|
|
3148
|
-
background: transparent;
|
|
3149
|
-
font-weight: 600;
|
|
3150
|
-
color: var(--muted);
|
|
3151
|
-
font-size: 0.75rem;
|
|
3152
|
-
text-transform: none;
|
|
3153
|
-
letter-spacing: 0;
|
|
3154
|
-
}
|
|
3155
|
-
.vprose tbody tr:hover {
|
|
3156
|
-
background: transparent;
|
|
3157
|
-
}
|
|
3158
|
-
/* Dark mode table styles */
|
|
3159
|
-
.dark .vprose th,
|
|
3160
|
-
.dark .vprose td {
|
|
3161
|
-
border-color: color-mix(in oklch, var(--border) 70%, transparent);
|
|
3162
|
-
}
|
|
3163
|
-
.dark .vprose thead th {
|
|
3164
|
-
background: transparent;
|
|
3165
|
-
color: var(--muted);
|
|
3166
|
-
}
|
|
3167
|
-
.dark .vprose tbody tr:hover {
|
|
3168
|
-
background: transparent;
|
|
3169
|
-
}
|
|
3170
|
-
/* Horizontal rules as section dividers */
|
|
3171
|
-
.vprose hr {
|
|
3172
|
-
margin-top: 1rem;
|
|
3173
|
-
margin-bottom: 1rem;
|
|
3174
|
-
border-color: var(--border);
|
|
3175
|
-
}
|
|
3176
|
-
/* Better blockquote styling */
|
|
3177
|
-
.vprose blockquote {
|
|
3178
|
-
margin-top: 0.875rem;
|
|
3179
|
-
margin-bottom: 0.875rem;
|
|
3180
|
-
padding-left: 1rem;
|
|
3181
|
-
border-left-width: 3px;
|
|
3182
|
-
border-left-color: var(--border);
|
|
3183
|
-
color: var(--muted);
|
|
3184
|
-
}
|
|
3185
|
-
/* Code blocks */
|
|
3186
|
-
.vprose pre {
|
|
3187
|
-
margin-top: 0.75rem;
|
|
3188
|
-
margin-bottom: 0.75rem;
|
|
3189
|
-
padding: 0.75rem;
|
|
3190
|
-
border-radius: 0.5rem;
|
|
3191
|
-
overflow-x: auto;
|
|
3192
|
-
background-color: var(--muted-background);
|
|
3193
|
-
color: var(--foreground);
|
|
3194
|
-
}
|
|
3195
|
-
.vprose pre code {
|
|
3196
|
-
color: inherit;
|
|
3197
|
-
}
|
|
3198
|
-
.dark .vprose pre {
|
|
3199
|
-
color: var(--foreground);
|
|
3200
|
-
}
|
|
3201
|
-
|
|
3202
|
-
/* Summary chat markdown: keep structure, but match the app's quieter conversation surface. */
|
|
3203
|
-
.agent-markdown {
|
|
3204
|
-
color: color-mix(in oklch, var(--foreground) 78%, transparent);
|
|
3205
|
-
font-size: 0.875rem;
|
|
3206
|
-
line-height: 1.625;
|
|
3207
|
-
overflow-x: auto;
|
|
3208
|
-
}
|
|
3209
|
-
.agent-markdown > * + * {
|
|
3210
|
-
margin-top: 0.65rem;
|
|
3211
|
-
}
|
|
3212
|
-
.agent-markdown p {
|
|
3213
|
-
margin-top: 0.5rem;
|
|
3214
|
-
margin-bottom: 0.5rem;
|
|
3215
|
-
}
|
|
3216
|
-
.agent-markdown h1,
|
|
3217
|
-
.agent-markdown h2,
|
|
3218
|
-
.agent-markdown h3,
|
|
3219
|
-
.agent-markdown h4 {
|
|
3220
|
-
margin-top: 1.2rem;
|
|
3221
|
-
margin-bottom: 0.45rem;
|
|
3222
|
-
color: var(--foreground);
|
|
3223
|
-
font-weight: 650;
|
|
3224
|
-
letter-spacing: 0;
|
|
3225
|
-
line-height: 1.3;
|
|
3226
|
-
}
|
|
3227
|
-
.agent-markdown h1 {
|
|
3228
|
-
font-size: 1.2rem;
|
|
3229
|
-
}
|
|
3230
|
-
.agent-markdown h2 {
|
|
3231
|
-
font-size: 1.05rem;
|
|
3232
|
-
}
|
|
3233
|
-
.agent-markdown h3,
|
|
3234
|
-
.agent-markdown h4 {
|
|
3235
|
-
font-size: 0.95rem;
|
|
3236
|
-
}
|
|
3237
|
-
.agent-markdown h1:first-child,
|
|
3238
|
-
.agent-markdown h2:first-child,
|
|
3239
|
-
.agent-markdown h3:first-child,
|
|
3240
|
-
.agent-markdown h4:first-child {
|
|
3241
|
-
margin-top: 0;
|
|
3242
|
-
}
|
|
3243
|
-
.agent-markdown hr {
|
|
3244
|
-
margin: 1.15rem 0;
|
|
3245
|
-
border: 0;
|
|
3246
|
-
border-top: 1px solid var(--border);
|
|
3247
|
-
opacity: 0.65;
|
|
3248
|
-
}
|
|
3249
|
-
.agent-markdown ul,
|
|
3250
|
-
.agent-markdown ol {
|
|
3251
|
-
margin-top: 0.55rem;
|
|
3252
|
-
margin-bottom: 0.55rem;
|
|
3253
|
-
padding-left: 1.25rem;
|
|
3254
|
-
}
|
|
3255
|
-
.agent-markdown li {
|
|
3256
|
-
margin-top: 0.2rem;
|
|
3257
|
-
margin-bottom: 0.2rem;
|
|
3258
|
-
padding-left: 0.1rem;
|
|
3259
|
-
color: inherit;
|
|
3260
|
-
}
|
|
3261
|
-
.agent-markdown li::marker {
|
|
3262
|
-
color: var(--muted);
|
|
3263
|
-
}
|
|
3264
|
-
.agent-markdown strong {
|
|
3265
|
-
color: var(--foreground);
|
|
3266
|
-
font-weight: 600;
|
|
3267
|
-
}
|
|
3268
|
-
.agent-markdown em {
|
|
3269
|
-
color: color-mix(in oklch, var(--foreground) 72%, transparent);
|
|
3270
|
-
}
|
|
3271
|
-
.agent-markdown a {
|
|
3272
|
-
color: var(--foreground);
|
|
3273
|
-
text-decoration-color: var(--muted);
|
|
3274
|
-
text-underline-offset: 3px;
|
|
3275
|
-
}
|
|
3276
|
-
.agent-markdown blockquote {
|
|
3277
|
-
margin-top: 0.85rem;
|
|
3278
|
-
margin-bottom: 0.85rem;
|
|
3279
|
-
padding-left: 0.875rem;
|
|
3280
|
-
border-left: 2px solid var(--border);
|
|
3281
|
-
color: var(--muted);
|
|
3282
|
-
font-style: normal;
|
|
3283
|
-
}
|
|
3284
|
-
.agent-markdown :not(pre) > code {
|
|
3285
|
-
border: 1px solid var(--border);
|
|
3286
|
-
border-radius: 0.375rem;
|
|
3287
|
-
background: var(--muted);
|
|
3288
|
-
color: var(--foreground);
|
|
3289
|
-
padding: 0.1rem 0.35rem;
|
|
3290
|
-
font-size: 0.8125em;
|
|
3291
|
-
font-weight: 500;
|
|
3292
|
-
}
|
|
3293
|
-
.agent-markdown pre {
|
|
3294
|
-
margin-top: 0.85rem;
|
|
3295
|
-
margin-bottom: 0.85rem;
|
|
3296
|
-
max-height: 32rem;
|
|
3297
|
-
overflow: auto;
|
|
3298
|
-
border: 1px solid var(--border);
|
|
3299
|
-
border-radius: 0.75rem;
|
|
3300
|
-
background: var(--muted);
|
|
3301
|
-
color: var(--foreground);
|
|
3302
|
-
padding: 0.875rem;
|
|
3303
|
-
font-size: 0.8125rem;
|
|
3304
|
-
line-height: 1.55;
|
|
3305
|
-
}
|
|
3306
|
-
.agent-markdown pre code {
|
|
3307
|
-
border: 0;
|
|
3308
|
-
background: transparent;
|
|
3309
|
-
color: inherit;
|
|
3310
|
-
padding: 0;
|
|
3311
|
-
font-size: inherit;
|
|
3312
|
-
}
|
|
3313
|
-
.agent-markdown table {
|
|
3314
|
-
display: table;
|
|
3315
|
-
width: 100%;
|
|
3316
|
-
max-width: 100%;
|
|
3317
|
-
margin: 0.9rem 0 1rem;
|
|
3318
|
-
border: 0;
|
|
3319
|
-
border-collapse: collapse;
|
|
3320
|
-
border-spacing: 0;
|
|
3321
|
-
font-size: 0.8125rem;
|
|
3322
|
-
table-layout: fixed;
|
|
3323
|
-
background: transparent;
|
|
3324
|
-
}
|
|
3325
|
-
.agent-markdown thead {
|
|
3326
|
-
background: transparent;
|
|
3327
|
-
}
|
|
3328
|
-
.agent-markdown th,
|
|
3329
|
-
.agent-markdown td {
|
|
3330
|
-
border: 0;
|
|
3331
|
-
border-bottom: 1px solid color-mix(in oklch, var(--border) 70%, transparent);
|
|
3332
|
-
background: transparent;
|
|
3333
|
-
padding: 0.55rem 0.75rem;
|
|
3334
|
-
text-align: left;
|
|
3335
|
-
vertical-align: top;
|
|
3336
|
-
overflow-wrap: anywhere;
|
|
3337
|
-
word-break: normal;
|
|
3338
|
-
white-space: normal;
|
|
3339
|
-
}
|
|
3340
|
-
.agent-markdown th {
|
|
3341
|
-
color: var(--muted);
|
|
3342
|
-
font-size: 0.75rem;
|
|
3343
|
-
font-weight: 600;
|
|
3344
|
-
letter-spacing: 0;
|
|
3345
|
-
text-transform: none;
|
|
3346
|
-
white-space: nowrap;
|
|
3347
|
-
}
|
|
3348
|
-
.agent-markdown td {
|
|
3349
|
-
color: inherit;
|
|
3350
|
-
}
|
|
3351
|
-
.agent-markdown th + th,
|
|
3352
|
-
.agent-markdown td + td {
|
|
3353
|
-
padding-inline-start: 1.75rem;
|
|
3354
|
-
}
|
|
3355
|
-
.agent-markdown th:first-child,
|
|
3356
|
-
.agent-markdown td:first-child {
|
|
3357
|
-
min-width: 0;
|
|
3358
|
-
width: auto;
|
|
3359
|
-
white-space: normal;
|
|
3360
|
-
}
|
|
3361
|
-
.agent-markdown col {
|
|
3362
|
-
width: var(--agent-markdown-table-column-width);
|
|
3363
|
-
}
|
|
3364
|
-
.agent-markdown tr:last-child td {
|
|
3365
|
-
border-bottom: 0;
|
|
3366
|
-
}
|
|
3367
|
-
.agent-markdown tbody tr:nth-child(even) {
|
|
3368
|
-
background: transparent;
|
|
3369
|
-
}
|
|
3370
|
-
.agent-markdown tbody tr:hover {
|
|
3371
|
-
background: transparent;
|
|
3372
|
-
}
|
|
3373
|
-
`}</style>
|
|
3122
|
+
<style>{agentMarkdownStyles}</style>
|
|
3374
3123
|
|
|
3375
3124
|
{/* Workstream tabs are a debug affordance; Summary keeps the conversation surface quiet. */}
|
|
3376
3125
|
{viewMode === 'stacked' && (
|
|
@@ -3,15 +3,9 @@ import { useUITranslation } from '@vertesia/ui/i18n';
|
|
|
3
3
|
import { MarkdownRenderer, type MarkdownRendererProps } from '@vertesia/ui/widgets';
|
|
4
4
|
import { ChevronDown } from 'lucide-react';
|
|
5
5
|
import { useState } from 'react';
|
|
6
|
+
import { AGENT_PROSE_CLASS } from './agentMarkdownStyles.js';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
export const AGENT_PROSE_CLASS = [
|
|
9
|
-
'agent-markdown vprose prose max-w-none break-words text-sm leading-6 text-foreground/80',
|
|
10
|
-
'prose-p:my-2 prose-p:leading-6 prose-li:my-0.5 prose-pre:my-3 prose-headings:tracking-normal',
|
|
11
|
-
'prose-headings:text-foreground prose-strong:text-foreground prose-code:text-foreground',
|
|
12
|
-
'prose-a:text-foreground prose-a:underline prose-a:decoration-muted prose-a:underline-offset-4',
|
|
13
|
-
'[&_p]:text-foreground/80 [&_li]:text-foreground/80 [&_li::marker]:text-muted',
|
|
14
|
-
].join(' ');
|
|
8
|
+
export { AGENT_PROSE_CLASS } from './agentMarkdownStyles.js';
|
|
15
9
|
|
|
16
10
|
/** Clamp applied to collapsed markdown. Kept as a literal so Tailwind emits the utility. */
|
|
17
11
|
export const AGENT_LINE_CLAMP_CLASS =
|
|
@@ -281,6 +281,54 @@ function isSummaryWorkMessage(message: AgentMessage): boolean {
|
|
|
281
281
|
return message.type === AgentMessageType.THOUGHT && !message.details?.streamed;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
+
function isEmptyAnswerMessage(message: AgentMessage): boolean {
|
|
285
|
+
return message.type === AgentMessageType.ANSWER && !getMessageText(message);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function isToolPreambleProse(message: AgentMessage): boolean {
|
|
289
|
+
const text = getMessageText(message);
|
|
290
|
+
return message.details?.display_role === 'tool_preamble' && Boolean(text) && !isLowSignalSummaryText(text);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Tools a model tends to call last, with its answer written as that call's preamble.
|
|
294
|
+
const ANSWER_CARRYING_TOOLS = new Set(['update_plan']);
|
|
295
|
+
|
|
296
|
+
function getFinalToolPreambleProseIndex(messages: AgentMessage[]): number {
|
|
297
|
+
// Check the latest preamble before filtering its text, so an empty or low-signal
|
|
298
|
+
// final preamble cannot make us fall back to prose from an earlier call.
|
|
299
|
+
const index = messages.findLastIndex(isToolPreambleMessage);
|
|
300
|
+
if (index < 0 || !isToolPreambleProse(messages[index])) return -1;
|
|
301
|
+
|
|
302
|
+
const details = messages[index].details;
|
|
303
|
+
const tools = details?.tools?.length ? details.tools : details?.tool ? [details.tool] : [];
|
|
304
|
+
if (tools.length === 0 || !tools.every((tool) => ANSWER_CARRYING_TOOLS.has(tool))) return -1;
|
|
305
|
+
|
|
306
|
+
let iteration = details?.tool_iteration;
|
|
307
|
+
let hasMatchingTool = false;
|
|
308
|
+
const toolRuns = new Map<string, Set<string>>();
|
|
309
|
+
for (const message of messages.slice(index + 1)) {
|
|
310
|
+
const tool = message.details?.tool;
|
|
311
|
+
if (!tool) continue;
|
|
312
|
+
// A later call without a preamble must not reuse an earlier call's prose.
|
|
313
|
+
if (!tools.includes(tool)) return -1;
|
|
314
|
+
const runId = message.details?.tool_run_id ?? message.details?.tool_use_id;
|
|
315
|
+
if (runId) {
|
|
316
|
+
const runs = toolRuns.get(tool) ?? new Set<string>();
|
|
317
|
+
runs.add(runId);
|
|
318
|
+
toolRuns.set(tool, runs);
|
|
319
|
+
if (runs.size > tools.filter((name) => name === tool).length) return -1;
|
|
320
|
+
}
|
|
321
|
+
const toolIteration = message.details?.tool_iteration;
|
|
322
|
+
if (toolIteration !== undefined) {
|
|
323
|
+
if (iteration !== undefined && iteration !== toolIteration) return -1;
|
|
324
|
+
iteration = toolIteration;
|
|
325
|
+
}
|
|
326
|
+
hasMatchingTool = true;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return hasMatchingTool ? index : -1;
|
|
330
|
+
}
|
|
331
|
+
|
|
284
332
|
export function buildSummaryConversationItems(
|
|
285
333
|
messages: AgentMessage[],
|
|
286
334
|
isCompleted: boolean,
|
|
@@ -332,6 +380,18 @@ export function buildSummaryConversationItems(
|
|
|
332
380
|
}
|
|
333
381
|
}
|
|
334
382
|
|
|
383
|
+
if (isEmptyAnswerMessage(message)) {
|
|
384
|
+
// A model that writes its answer alongside a last tool call leaves that prose as a
|
|
385
|
+
// tool preamble and ends the turn on an empty answer; show the prose as the answer.
|
|
386
|
+
const proseIndex = getFinalToolPreambleProseIndex(pendingWork);
|
|
387
|
+
if (proseIndex >= 0) {
|
|
388
|
+
const [prose] = pendingWork.splice(proseIndex, 1);
|
|
389
|
+
flushWork(false, message);
|
|
390
|
+
items.push({ type: 'message', message: { ...message, message: prose.message } });
|
|
391
|
+
}
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
|
|
335
395
|
if (message.type === AgentMessageType.COMPLETE || message.type === AgentMessageType.IDLE) {
|
|
336
396
|
if (isUserStoppedMessage(message)) {
|
|
337
397
|
const pendingWorkStartTimestamp = pendingWork[0]?.timestamp;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/** Prose styling used for agent/model message markdown, shared across the conversation UI. */
|
|
2
|
+
export const AGENT_PROSE_CLASS = [
|
|
3
|
+
'agent-markdown vprose prose max-w-none break-words text-sm leading-6 text-foreground/80',
|
|
4
|
+
'prose-p:my-2 prose-p:leading-6 prose-li:my-0.5 prose-pre:my-3 prose-headings:tracking-normal',
|
|
5
|
+
'prose-headings:text-foreground prose-strong:text-foreground prose-code:text-foreground',
|
|
6
|
+
'prose-a:text-foreground prose-a:underline prose-a:decoration-muted prose-a:underline-offset-4',
|
|
7
|
+
'prose-p:text-foreground/80 prose-li:text-foreground/80 prose-li:marker:text-muted',
|
|
8
|
+
].join(' ');
|
|
9
|
+
|
|
10
|
+
// Shared with rendered regression checks so they exercise the styles the chat actually injects.
|
|
11
|
+
export const agentMarkdownStyles = `
|
|
12
|
+
/* Better vertical rhythm for markdown */
|
|
13
|
+
.vprose > * + *:not(:where(.not-prose, .not-prose *)) {
|
|
14
|
+
margin-top: 0.625rem;
|
|
15
|
+
}
|
|
16
|
+
.vprose > h1 + *:not(:where(.not-prose, .not-prose *)),
|
|
17
|
+
.vprose > h2 + *:not(:where(.not-prose, .not-prose *)),
|
|
18
|
+
.vprose > h3 + *:not(:where(.not-prose, .not-prose *)) {
|
|
19
|
+
margin-top: 0.375rem;
|
|
20
|
+
}
|
|
21
|
+
/* Tables should read like part of the conversation, not a separate app grid. */
|
|
22
|
+
.vprose table:not(:where(.not-prose, .not-prose *)) {
|
|
23
|
+
margin-top: 0.875rem;
|
|
24
|
+
margin-bottom: 0.875rem;
|
|
25
|
+
border-collapse: collapse;
|
|
26
|
+
width: 100%;
|
|
27
|
+
background: transparent;
|
|
28
|
+
}
|
|
29
|
+
.vprose th:not(:where(.not-prose, .not-prose *)),
|
|
30
|
+
.vprose td:not(:where(.not-prose, .not-prose *)) {
|
|
31
|
+
padding: 0.5rem 0.625rem;
|
|
32
|
+
border: 0;
|
|
33
|
+
border-bottom: 1px solid color-mix(in oklch, var(--border) 70%, transparent);
|
|
34
|
+
background: transparent;
|
|
35
|
+
text-align: left;
|
|
36
|
+
}
|
|
37
|
+
.vprose thead th:not(:where(.not-prose, .not-prose *)) {
|
|
38
|
+
background: transparent;
|
|
39
|
+
font-weight: 600;
|
|
40
|
+
color: var(--muted);
|
|
41
|
+
font-size: 0.75rem;
|
|
42
|
+
text-transform: none;
|
|
43
|
+
letter-spacing: 0;
|
|
44
|
+
}
|
|
45
|
+
.vprose tbody tr:hover:not(:where(.not-prose, .not-prose *)) {
|
|
46
|
+
background: transparent;
|
|
47
|
+
}
|
|
48
|
+
/* Horizontal rules as section dividers */
|
|
49
|
+
.vprose hr:not(:where(.not-prose, .not-prose *)) {
|
|
50
|
+
margin-top: 1rem;
|
|
51
|
+
margin-bottom: 1rem;
|
|
52
|
+
border-color: var(--border);
|
|
53
|
+
}
|
|
54
|
+
/* Better blockquote styling */
|
|
55
|
+
.vprose blockquote:not(:where(.not-prose, .not-prose *)) {
|
|
56
|
+
margin-top: 0.875rem;
|
|
57
|
+
margin-bottom: 0.875rem;
|
|
58
|
+
padding-left: 1rem;
|
|
59
|
+
border-left-width: 3px;
|
|
60
|
+
border-left-color: var(--border);
|
|
61
|
+
color: var(--muted);
|
|
62
|
+
}
|
|
63
|
+
/* Code blocks */
|
|
64
|
+
.vprose pre:not(:where(.not-prose, .not-prose *)) {
|
|
65
|
+
margin-top: 0.75rem;
|
|
66
|
+
margin-bottom: 0.75rem;
|
|
67
|
+
padding: 0.75rem;
|
|
68
|
+
border-radius: 0.5rem;
|
|
69
|
+
overflow-x: auto;
|
|
70
|
+
background-color: var(--muted-background);
|
|
71
|
+
color: var(--foreground);
|
|
72
|
+
}
|
|
73
|
+
.vprose pre code:not(:where(.not-prose, .not-prose *)) {
|
|
74
|
+
color: inherit;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Summary chat markdown: keep structure, but match the app's quieter conversation surface. */
|
|
78
|
+
.agent-markdown:not(:where(.not-prose, .not-prose *)) {
|
|
79
|
+
color: color-mix(in oklch, var(--foreground) 78%, transparent);
|
|
80
|
+
font-size: 0.875rem;
|
|
81
|
+
line-height: 1.625;
|
|
82
|
+
overflow-x: auto;
|
|
83
|
+
}
|
|
84
|
+
.agent-markdown > * + *:not(:where(.not-prose, .not-prose *)) {
|
|
85
|
+
margin-top: 0.65rem;
|
|
86
|
+
}
|
|
87
|
+
.agent-markdown p:not(:where(.not-prose, .not-prose *)) {
|
|
88
|
+
margin-top: 0.5rem;
|
|
89
|
+
margin-bottom: 0.5rem;
|
|
90
|
+
}
|
|
91
|
+
.agent-markdown h1:not(:where(.not-prose, .not-prose *)),
|
|
92
|
+
.agent-markdown h2:not(:where(.not-prose, .not-prose *)),
|
|
93
|
+
.agent-markdown h3:not(:where(.not-prose, .not-prose *)),
|
|
94
|
+
.agent-markdown h4:not(:where(.not-prose, .not-prose *)) {
|
|
95
|
+
margin-top: 1.2rem;
|
|
96
|
+
margin-bottom: 0.45rem;
|
|
97
|
+
color: var(--foreground);
|
|
98
|
+
font-weight: 650;
|
|
99
|
+
letter-spacing: 0;
|
|
100
|
+
line-height: 1.3;
|
|
101
|
+
}
|
|
102
|
+
.agent-markdown h1:not(:where(.not-prose, .not-prose *)) {
|
|
103
|
+
font-size: 1.2rem;
|
|
104
|
+
}
|
|
105
|
+
.agent-markdown h2:not(:where(.not-prose, .not-prose *)) {
|
|
106
|
+
font-size: 1.05rem;
|
|
107
|
+
}
|
|
108
|
+
.agent-markdown h3:not(:where(.not-prose, .not-prose *)),
|
|
109
|
+
.agent-markdown h4:not(:where(.not-prose, .not-prose *)) {
|
|
110
|
+
font-size: 0.95rem;
|
|
111
|
+
}
|
|
112
|
+
.agent-markdown h1:first-child:not(:where(.not-prose, .not-prose *)),
|
|
113
|
+
.agent-markdown h2:first-child:not(:where(.not-prose, .not-prose *)),
|
|
114
|
+
.agent-markdown h3:first-child:not(:where(.not-prose, .not-prose *)),
|
|
115
|
+
.agent-markdown h4:first-child:not(:where(.not-prose, .not-prose *)) {
|
|
116
|
+
margin-top: 0;
|
|
117
|
+
}
|
|
118
|
+
.agent-markdown hr:not(:where(.not-prose, .not-prose *)) {
|
|
119
|
+
margin: 1.15rem 0;
|
|
120
|
+
border: 0;
|
|
121
|
+
border-top: 1px solid var(--border);
|
|
122
|
+
opacity: 0.65;
|
|
123
|
+
}
|
|
124
|
+
.agent-markdown ul:not(:where(.not-prose, .not-prose *)),
|
|
125
|
+
.agent-markdown ol:not(:where(.not-prose, .not-prose *)) {
|
|
126
|
+
margin-top: 0.55rem;
|
|
127
|
+
margin-bottom: 0.55rem;
|
|
128
|
+
padding-left: 1.25rem;
|
|
129
|
+
}
|
|
130
|
+
.agent-markdown li:not(:where(.not-prose, .not-prose *)) {
|
|
131
|
+
margin-top: 0.2rem;
|
|
132
|
+
margin-bottom: 0.2rem;
|
|
133
|
+
padding-left: 0.1rem;
|
|
134
|
+
color: inherit;
|
|
135
|
+
}
|
|
136
|
+
.agent-markdown li:not(:where(.not-prose, .not-prose *))::marker {
|
|
137
|
+
color: var(--muted);
|
|
138
|
+
}
|
|
139
|
+
.agent-markdown strong:not(:where(.not-prose, .not-prose *)) {
|
|
140
|
+
color: var(--foreground);
|
|
141
|
+
font-weight: 600;
|
|
142
|
+
}
|
|
143
|
+
.agent-markdown em:not(:where(.not-prose, .not-prose *)) {
|
|
144
|
+
color: color-mix(in oklch, var(--foreground) 72%, transparent);
|
|
145
|
+
}
|
|
146
|
+
.agent-markdown a:not(:where(.not-prose, .not-prose *)) {
|
|
147
|
+
color: var(--foreground);
|
|
148
|
+
text-decoration-color: var(--muted);
|
|
149
|
+
text-underline-offset: 3px;
|
|
150
|
+
}
|
|
151
|
+
.agent-markdown blockquote:not(:where(.not-prose, .not-prose *)) {
|
|
152
|
+
margin-top: 0.85rem;
|
|
153
|
+
margin-bottom: 0.85rem;
|
|
154
|
+
padding-left: 0.875rem;
|
|
155
|
+
border-left: 2px solid var(--border);
|
|
156
|
+
color: var(--muted);
|
|
157
|
+
font-style: normal;
|
|
158
|
+
}
|
|
159
|
+
.agent-markdown :not(pre) > code:not(:where(.not-prose, .not-prose *)) {
|
|
160
|
+
border: 1px solid var(--border);
|
|
161
|
+
border-radius: 0.375rem;
|
|
162
|
+
background: var(--muted-background);
|
|
163
|
+
color: var(--foreground);
|
|
164
|
+
padding: 0.1rem 0.35rem;
|
|
165
|
+
font-size: 0.8125em;
|
|
166
|
+
font-weight: 500;
|
|
167
|
+
}
|
|
168
|
+
.agent-markdown pre:not(:where(.not-prose, .not-prose *)) {
|
|
169
|
+
margin-top: 0.85rem;
|
|
170
|
+
margin-bottom: 0.85rem;
|
|
171
|
+
max-height: 32rem;
|
|
172
|
+
overflow: auto;
|
|
173
|
+
border: 1px solid var(--border);
|
|
174
|
+
border-radius: 0.75rem;
|
|
175
|
+
background: var(--muted-background);
|
|
176
|
+
color: var(--foreground);
|
|
177
|
+
padding: 0.875rem;
|
|
178
|
+
font-size: 0.8125rem;
|
|
179
|
+
line-height: 1.55;
|
|
180
|
+
}
|
|
181
|
+
.agent-markdown pre code:not(:where(.not-prose, .not-prose *)) {
|
|
182
|
+
border: 0;
|
|
183
|
+
background: transparent;
|
|
184
|
+
color: inherit;
|
|
185
|
+
padding: 0;
|
|
186
|
+
font-size: inherit;
|
|
187
|
+
}
|
|
188
|
+
.agent-markdown table:not(:where(.not-prose, .not-prose *)) {
|
|
189
|
+
display: table;
|
|
190
|
+
width: 100%;
|
|
191
|
+
max-width: 100%;
|
|
192
|
+
margin: 0.9rem 0 1rem;
|
|
193
|
+
border: 0;
|
|
194
|
+
border-collapse: collapse;
|
|
195
|
+
border-spacing: 0;
|
|
196
|
+
font-size: 0.8125rem;
|
|
197
|
+
table-layout: fixed;
|
|
198
|
+
background: transparent;
|
|
199
|
+
}
|
|
200
|
+
.agent-markdown thead:not(:where(.not-prose, .not-prose *)) {
|
|
201
|
+
background: transparent;
|
|
202
|
+
}
|
|
203
|
+
.agent-markdown th:not(:where(.not-prose, .not-prose *)),
|
|
204
|
+
.agent-markdown td:not(:where(.not-prose, .not-prose *)) {
|
|
205
|
+
border: 0;
|
|
206
|
+
border-bottom: 1px solid color-mix(in oklch, var(--border) 70%, transparent);
|
|
207
|
+
background: transparent;
|
|
208
|
+
padding: 0.55rem 0.75rem;
|
|
209
|
+
text-align: left;
|
|
210
|
+
vertical-align: top;
|
|
211
|
+
overflow-wrap: anywhere;
|
|
212
|
+
word-break: normal;
|
|
213
|
+
white-space: normal;
|
|
214
|
+
}
|
|
215
|
+
.agent-markdown th:not(:where(.not-prose, .not-prose *)) {
|
|
216
|
+
color: var(--muted);
|
|
217
|
+
font-size: 0.75rem;
|
|
218
|
+
font-weight: 600;
|
|
219
|
+
letter-spacing: 0;
|
|
220
|
+
text-transform: none;
|
|
221
|
+
white-space: nowrap;
|
|
222
|
+
}
|
|
223
|
+
.agent-markdown td:not(:where(.not-prose, .not-prose *)) {
|
|
224
|
+
color: inherit;
|
|
225
|
+
}
|
|
226
|
+
.agent-markdown th + th:not(:where(.not-prose, .not-prose *)),
|
|
227
|
+
.agent-markdown td + td:not(:where(.not-prose, .not-prose *)) {
|
|
228
|
+
padding-inline-start: 1.75rem;
|
|
229
|
+
}
|
|
230
|
+
.agent-markdown th:first-child:not(:where(.not-prose, .not-prose *)),
|
|
231
|
+
.agent-markdown td:first-child:not(:where(.not-prose, .not-prose *)) {
|
|
232
|
+
min-width: 0;
|
|
233
|
+
width: auto;
|
|
234
|
+
white-space: normal;
|
|
235
|
+
}
|
|
236
|
+
.agent-markdown col:not(:where(.not-prose, .not-prose *)) {
|
|
237
|
+
width: var(--agent-markdown-table-column-width);
|
|
238
|
+
}
|
|
239
|
+
.agent-markdown tr:last-child td:not(:where(.not-prose, .not-prose *)) {
|
|
240
|
+
border-bottom: 0;
|
|
241
|
+
}
|
|
242
|
+
.agent-markdown tbody tr:nth-child(even):not(:where(.not-prose, .not-prose *)) {
|
|
243
|
+
background: transparent;
|
|
244
|
+
}
|
|
245
|
+
.agent-markdown tbody tr:hover:not(:where(.not-prose, .not-prose *)) {
|
|
246
|
+
background: transparent;
|
|
247
|
+
}
|
|
248
|
+
`;
|
|
@@ -142,8 +142,9 @@ async function fetchSkillWidgets(
|
|
|
142
142
|
}
|
|
143
143
|
return widgets;
|
|
144
144
|
})
|
|
145
|
-
.catch(() => {
|
|
146
|
-
|
|
145
|
+
.catch((err: unknown) => {
|
|
146
|
+
// The chat still renders; only that app's custom widgets are missing.
|
|
147
|
+
console.warn('Failed to fetch skill widgets from', url, err);
|
|
147
148
|
return null;
|
|
148
149
|
});
|
|
149
150
|
}),
|
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
import { DirectionProvider } from '@radix-ui/react-direction';
|
|
2
2
|
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
3
|
-
import { isRTL, resolveLanguage, type SupportedLanguage } from './rtl.js';
|
|
3
|
+
import { isRTL, LANGUAGE_STORAGE_KEY, resolveLanguage, type SupportedLanguage } from './rtl.js';
|
|
4
4
|
|
|
5
5
|
type LanguageProviderProps = {
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
defaultLanguage?: SupportedLanguage;
|
|
8
|
+
/**
|
|
9
|
+
* Pin the language this app renders in, whatever the saved choice or browser language. The
|
|
10
|
+
* user's own language is still tracked, and exposed as `preferredLanguage`.
|
|
11
|
+
*/
|
|
12
|
+
language?: SupportedLanguage;
|
|
8
13
|
storageKey?: string;
|
|
9
14
|
};
|
|
10
15
|
|
|
11
16
|
type LanguageProviderState = {
|
|
17
|
+
/** The language the app renders in. */
|
|
12
18
|
language: SupportedLanguage;
|
|
19
|
+
/** The user's own language (saved choice, then browser); equals `language` unless pinned. */
|
|
20
|
+
preferredLanguage: SupportedLanguage;
|
|
13
21
|
setLanguage: (language: SupportedLanguage, options?: { persist?: boolean }) => void;
|
|
14
22
|
isRTL: boolean;
|
|
15
23
|
};
|
|
16
24
|
|
|
17
25
|
const initialState: LanguageProviderState = {
|
|
18
26
|
language: 'en',
|
|
27
|
+
preferredLanguage: 'en',
|
|
19
28
|
setLanguage: () => null,
|
|
20
29
|
isRTL: false,
|
|
21
30
|
};
|
|
@@ -36,12 +45,14 @@ function readInitialLanguage(storageKey: string, defaultLanguage: SupportedLangu
|
|
|
36
45
|
export function LanguageProvider({
|
|
37
46
|
children,
|
|
38
47
|
defaultLanguage = 'en',
|
|
39
|
-
|
|
48
|
+
language: pinnedLanguage,
|
|
49
|
+
storageKey = LANGUAGE_STORAGE_KEY,
|
|
40
50
|
...props
|
|
41
51
|
}: LanguageProviderProps) {
|
|
42
|
-
const [
|
|
52
|
+
const [preferredLanguage, setLanguageState] = useState<SupportedLanguage>(() =>
|
|
43
53
|
readInitialLanguage(storageKey, defaultLanguage),
|
|
44
54
|
);
|
|
55
|
+
const language = pinnedLanguage ?? preferredLanguage;
|
|
45
56
|
|
|
46
57
|
const rtl = isRTL(language);
|
|
47
58
|
|
|
@@ -62,10 +73,11 @@ export function LanguageProvider({
|
|
|
62
73
|
const value = useMemo<LanguageProviderState>(
|
|
63
74
|
() => ({
|
|
64
75
|
language,
|
|
76
|
+
preferredLanguage,
|
|
65
77
|
isRTL: rtl,
|
|
66
78
|
setLanguage,
|
|
67
79
|
}),
|
|
68
|
-
[language, rtl, setLanguage],
|
|
80
|
+
[language, preferredLanguage, rtl, setLanguage],
|
|
69
81
|
);
|
|
70
82
|
|
|
71
83
|
return (
|