Skip to content

Commit 8d14a51

Browse files
committed
Error tags
1 parent d20a8a8 commit 8d14a51

File tree

1 file changed

+52
-3
lines changed
  • apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags

1 file changed

+52
-3
lines changed

apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,32 @@ export interface CredentialTagData {
2525
provider?: string
2626
}
2727

28+
export interface MothershipErrorTagData {
29+
message: string
30+
code: string
31+
provider: string
32+
}
33+
2834
export type ContentSegment =
2935
| { type: 'text'; content: string }
3036
| { type: 'thinking'; content: string }
3137
| { type: 'options'; data: OptionsTagData }
3238
| { type: 'usage_upgrade'; data: UsageUpgradeTagData }
3339
| { type: 'credential'; data: CredentialTagData }
40+
| { type: 'mothership-error'; data: MothershipErrorTagData }
3441

3542
export interface ParsedSpecialContent {
3643
segments: ContentSegment[]
3744
hasPendingTag: boolean
3845
}
3946

40-
const SPECIAL_TAG_NAMES = ['thinking', 'options', 'usage_upgrade', 'credential'] as const
47+
const SPECIAL_TAG_NAMES = [
48+
'thinking',
49+
'options',
50+
'usage_upgrade',
51+
'credential',
52+
'mothership-error',
53+
] as const
4154

4255
/**
4356
* Parses inline special tags (`<options>`, `<usage_upgrade>`) from streamed
@@ -69,7 +82,7 @@ export function parseSpecialTags(content: string, isStreaming: boolean): ParsedS
6982
let remaining = content.slice(cursor)
7083

7184
if (isStreaming) {
72-
const partial = remaining.match(/<[a-z_]*$/i)
85+
const partial = remaining.match(/<[a-z_-]*$/i)
7386
if (partial) {
7487
const fragment = partial[0].slice(1)
7588
if (fragment.length > 0 && SPECIAL_TAG_NAMES.some((t) => t.startsWith(fragment))) {
@@ -111,7 +124,10 @@ export function parseSpecialTags(content: string, isStreaming: boolean): ParsedS
111124
} else {
112125
try {
113126
const data = JSON.parse(body)
114-
segments.push({ type: nearestTagName as 'options' | 'usage_upgrade' | 'credential', data })
127+
segments.push({
128+
type: nearestTagName as 'options' | 'usage_upgrade' | 'credential' | 'mothership-error',
129+
data,
130+
})
115131
} catch {
116132
/* malformed JSON — drop the tag silently */
117133
}
@@ -152,6 +168,8 @@ export function SpecialTags({ segment, onOptionSelect }: SpecialTagsProps) {
152168
return <UsageUpgradeDisplay data={segment.data} />
153169
case 'credential':
154170
return <CredentialDisplay data={segment.data} />
171+
case 'mothership-error':
172+
return <MothershipErrorDisplay data={segment.data} />
155173
default:
156174
return null
157175
}
@@ -276,6 +294,37 @@ function CredentialDisplay({ data }: { data: CredentialTagData }) {
276294
)
277295
}
278296

297+
function MothershipErrorDisplay({ data }: { data: MothershipErrorTagData }) {
298+
return (
299+
<div className='animate-stream-fade-in rounded-xl border border-red-300/40 bg-red-50/50 px-4 py-3 dark:border-red-500/20 dark:bg-red-950/20'>
300+
<div className='flex items-center gap-2'>
301+
<svg
302+
className='h-4 w-4 shrink-0 text-red-600 dark:text-red-400'
303+
viewBox='0 0 16 16'
304+
fill='none'
305+
xmlns='http://www.w3.org/2000/svg'
306+
>
307+
<circle cx='8' cy='8' r='6.5' stroke='currentColor' strokeWidth='1.3' />
308+
<path d='M8 4.5v4' stroke='currentColor' strokeWidth='1.3' strokeLinecap='round' />
309+
<circle cx='8' cy='11' r='0.75' fill='currentColor' />
310+
</svg>
311+
<span className='font-[500] text-[14px] text-red-800 leading-5 dark:text-red-300'>
312+
Something went wrong
313+
</span>
314+
</div>
315+
<p className='mt-1.5 text-[13px] text-red-700/90 leading-[20px] dark:text-red-400/80'>
316+
{data.message}
317+
</p>
318+
{data.code && (
319+
<span className='mt-1 inline-block text-[11px] text-red-500/70 dark:text-red-500/50'>
320+
{data.provider ? `${data.provider}:` : ''}
321+
{data.code}
322+
</span>
323+
)}
324+
</div>
325+
)
326+
}
327+
279328
function UsageUpgradeDisplay({ data }: { data: UsageUpgradeTagData }) {
280329
const { workspaceId } = useParams<{ workspaceId: string }>()
281330
const settingsPath = `/workspace/${workspaceId}/settings/subscription`

0 commit comments

Comments
 (0)