Skip to content

Commit 85d6e3e

Browse files
authored
fix(misc): added trace spans back to notifications for webhooks, updated verification code for users signing in with email, updated welcome email (#2828)
* added back trace spans to notifications * fixed double verification code * fix dashboard * updated welcome email * added link to cal for team * update dashboard stats route * added react grab URL to CSP if FF is enabled, removed dead db hook * fix failing test * ensure MCP add server tool is centered * updated A2A copy button and MCP location, and default description matching * updated button on chat page * added vite version override * fix
1 parent ccf2685 commit 85d6e3e

File tree

24 files changed

+377
-354
lines changed

24 files changed

+377
-354
lines changed

apps/sim/app/(auth)/signup/signup-form.tsx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -359,15 +359,6 @@ function SignupFormContent({
359359
}
360360
}
361361

362-
try {
363-
await client.emailOtp.sendVerificationOtp({
364-
email: emailValue,
365-
type: 'sign-in',
366-
})
367-
} catch (otpErr) {
368-
logger.warn('Failed to send sign-in OTP after signup; user can press Resend', otpErr)
369-
}
370-
371362
router.push('/verify?fromSignup=true')
372363
} catch (error) {
373364
logger.error('Signup error:', error)

apps/sim/app/(auth)/verify/use-verification.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export function useVerification({
9393

9494
try {
9595
const normalizedEmail = email.trim().toLowerCase()
96-
const response = await client.signIn.emailOtp({
96+
const response = await client.emailOtp.verifyEmail({
9797
email: normalizedEmail,
9898
otp,
9999
})
@@ -169,7 +169,7 @@ export function useVerification({
169169
client.emailOtp
170170
.sendVerificationOtp({
171171
email: normalizedEmail,
172-
type: 'sign-in',
172+
type: 'email-verification',
173173
})
174174
.then(() => {})
175175
.catch(() => {

apps/sim/app/api/logs/stats/route.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,14 @@ export async function GET(request: NextRequest) {
9999

100100
const totalMs = Math.max(1, endTime.getTime() - startTime.getTime())
101101
const segmentMs = Math.max(60000, Math.floor(totalMs / params.segmentCount))
102+
const startTimeIso = startTime.toISOString()
102103

103104
const statsQuery = await db
104105
.select({
105106
workflowId: workflowExecutionLogs.workflowId,
106107
workflowName: workflow.name,
107108
segmentIndex:
108-
sql<number>`FLOOR(EXTRACT(EPOCH FROM (${workflowExecutionLogs.startedAt} - ${startTime}::timestamp)) * 1000 / ${segmentMs})`.as(
109+
sql<number>`FLOOR(EXTRACT(EPOCH FROM (${workflowExecutionLogs.startedAt} - ${startTimeIso}::timestamp)) * 1000 / ${segmentMs})`.as(
109110
'segment_index'
110111
),
111112
totalExecutions: sql<number>`COUNT(*)`.as('total_executions'),
@@ -129,12 +130,7 @@ export async function GET(request: NextRequest) {
129130
)
130131
)
131132
.where(whereCondition)
132-
.groupBy(
133-
workflowExecutionLogs.workflowId,
134-
workflow.name,
135-
sql`FLOOR(EXTRACT(EPOCH FROM (${workflowExecutionLogs.startedAt} - ${startTime}::timestamp)) * 1000 / ${segmentMs})`
136-
)
137-
.orderBy(workflowExecutionLogs.workflowId, sql`segment_index`)
133+
.groupBy(workflowExecutionLogs.workflowId, workflow.name, sql`segment_index`)
138134

139135
const workflowMap = new Map<
140136
string,

apps/sim/app/api/workspaces/[id]/notifications/[notificationId]/route.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ const updateNotificationSchema = z
8080
levelFilter: levelFilterSchema.optional(),
8181
triggerFilter: triggerFilterSchema.optional(),
8282
includeFinalOutput: z.boolean().optional(),
83+
includeTraceSpans: z.boolean().optional(),
8384
includeRateLimits: z.boolean().optional(),
8485
includeUsageData: z.boolean().optional(),
8586
alertConfig: alertConfigSchema.optional(),
@@ -146,6 +147,7 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
146147
levelFilter: subscription.levelFilter,
147148
triggerFilter: subscription.triggerFilter,
148149
includeFinalOutput: subscription.includeFinalOutput,
150+
includeTraceSpans: subscription.includeTraceSpans,
149151
includeRateLimits: subscription.includeRateLimits,
150152
includeUsageData: subscription.includeUsageData,
151153
webhookConfig: subscription.webhookConfig,
@@ -220,6 +222,7 @@ export async function PUT(request: NextRequest, { params }: RouteParams) {
220222
if (data.triggerFilter !== undefined) updateData.triggerFilter = data.triggerFilter
221223
if (data.includeFinalOutput !== undefined)
222224
updateData.includeFinalOutput = data.includeFinalOutput
225+
if (data.includeTraceSpans !== undefined) updateData.includeTraceSpans = data.includeTraceSpans
223226
if (data.includeRateLimits !== undefined) updateData.includeRateLimits = data.includeRateLimits
224227
if (data.includeUsageData !== undefined) updateData.includeUsageData = data.includeUsageData
225228
if (data.alertConfig !== undefined) updateData.alertConfig = data.alertConfig
@@ -257,6 +260,7 @@ export async function PUT(request: NextRequest, { params }: RouteParams) {
257260
levelFilter: subscription.levelFilter,
258261
triggerFilter: subscription.triggerFilter,
259262
includeFinalOutput: subscription.includeFinalOutput,
263+
includeTraceSpans: subscription.includeTraceSpans,
260264
includeRateLimits: subscription.includeRateLimits,
261265
includeUsageData: subscription.includeUsageData,
262266
webhookConfig: subscription.webhookConfig,

apps/sim/app/api/workspaces/[id]/notifications/[notificationId]/test/route.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,22 @@ function buildTestPayload(subscription: typeof workspaceNotificationSubscription
9292
data.usage = { currentPeriodCost: 2.45, limit: 20, percentUsed: 12.25, isExceeded: false }
9393
}
9494

95+
if (subscription.includeTraceSpans && subscription.notificationType === 'webhook') {
96+
data.traceSpans = [
97+
{
98+
name: 'test-block',
99+
startTime: timestamp,
100+
endTime: timestamp + 150,
101+
duration: 150,
102+
status: 'success',
103+
blockId: 'block_test_1',
104+
blockType: 'agent',
105+
blockName: 'Test Agent',
106+
children: [],
107+
},
108+
]
109+
}
110+
95111
return { payload, timestamp }
96112
}
97113

apps/sim/app/api/workspaces/[id]/notifications/route.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const createNotificationSchema = z
8383
levelFilter: levelFilterSchema.default(['info', 'error']),
8484
triggerFilter: triggerFilterSchema.default([...CORE_TRIGGER_TYPES]),
8585
includeFinalOutput: z.boolean().default(false),
86+
includeTraceSpans: z.boolean().default(false),
8687
includeRateLimits: z.boolean().default(false),
8788
includeUsageData: z.boolean().default(false),
8889
alertConfig: alertConfigSchema.optional(),
@@ -137,6 +138,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
137138
levelFilter: workspaceNotificationSubscription.levelFilter,
138139
triggerFilter: workspaceNotificationSubscription.triggerFilter,
139140
includeFinalOutput: workspaceNotificationSubscription.includeFinalOutput,
141+
includeTraceSpans: workspaceNotificationSubscription.includeTraceSpans,
140142
includeRateLimits: workspaceNotificationSubscription.includeRateLimits,
141143
includeUsageData: workspaceNotificationSubscription.includeUsageData,
142144
webhookConfig: workspaceNotificationSubscription.webhookConfig,
@@ -220,7 +222,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
220222
}
221223
}
222224

223-
// Encrypt webhook secret if provided
224225
let webhookConfig = data.webhookConfig || null
225226
if (webhookConfig?.secret) {
226227
const { encrypted } = await encryptSecret(webhookConfig.secret)
@@ -238,6 +239,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
238239
levelFilter: data.levelFilter,
239240
triggerFilter: data.triggerFilter,
240241
includeFinalOutput: data.includeFinalOutput,
242+
includeTraceSpans: data.includeTraceSpans,
241243
includeRateLimits: data.includeRateLimits,
242244
includeUsageData: data.includeUsageData,
243245
alertConfig: data.alertConfig || null,
@@ -263,6 +265,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
263265
levelFilter: subscription.levelFilter,
264266
triggerFilter: subscription.triggerFilter,
265267
includeFinalOutput: subscription.includeFinalOutput,
268+
includeTraceSpans: subscription.includeTraceSpans,
266269
includeRateLimits: subscription.includeRateLimits,
267270
includeUsageData: subscription.includeUsageData,
268271
webhookConfig: subscription.webhookConfig,

apps/sim/app/workspace/[workspaceId]/logs/components/logs-toolbar/components/notifications/notifications.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export function NotificationSettings({
136136
levelFilter: ['info', 'error'] as LogLevel[],
137137
triggerFilter: [...CORE_TRIGGER_TYPES] as CoreTriggerType[],
138138
includeFinalOutput: false,
139+
includeTraceSpans: false,
139140
includeRateLimits: false,
140141
includeUsageData: false,
141142
webhookUrl: '',
@@ -202,6 +203,7 @@ export function NotificationSettings({
202203
levelFilter: ['info', 'error'],
203204
triggerFilter: [...CORE_TRIGGER_TYPES],
204205
includeFinalOutput: false,
206+
includeTraceSpans: false,
205207
includeRateLimits: false,
206208
includeUsageData: false,
207209
webhookUrl: '',
@@ -420,6 +422,8 @@ export function NotificationSettings({
420422
levelFilter: formData.levelFilter,
421423
triggerFilter: formData.triggerFilter,
422424
includeFinalOutput: formData.includeFinalOutput,
425+
// Trace spans only available for webhooks (too large for email/Slack)
426+
includeTraceSpans: activeTab === 'webhook' ? formData.includeTraceSpans : false,
423427
includeRateLimits: formData.includeRateLimits,
424428
includeUsageData: formData.includeUsageData,
425429
alertConfig,
@@ -471,6 +475,7 @@ export function NotificationSettings({
471475
levelFilter: subscription.levelFilter as LogLevel[],
472476
triggerFilter: subscription.triggerFilter as CoreTriggerType[],
473477
includeFinalOutput: subscription.includeFinalOutput,
478+
includeTraceSpans: subscription.includeTraceSpans,
474479
includeRateLimits: subscription.includeRateLimits,
475480
includeUsageData: subscription.includeUsageData,
476481
webhookUrl: subscription.webhookConfig?.url || '',
@@ -826,13 +831,18 @@ export function NotificationSettings({
826831
<Combobox
827832
options={[
828833
{ label: 'Final Output', value: 'includeFinalOutput' },
834+
// Trace spans only available for webhooks (too large for email/Slack)
835+
...(activeTab === 'webhook'
836+
? [{ label: 'Trace Spans', value: 'includeTraceSpans' }]
837+
: []),
829838
{ label: 'Rate Limits', value: 'includeRateLimits' },
830839
{ label: 'Usage Data', value: 'includeUsageData' },
831840
]}
832841
multiSelect
833842
multiSelectValues={
834843
[
835844
formData.includeFinalOutput && 'includeFinalOutput',
845+
formData.includeTraceSpans && activeTab === 'webhook' && 'includeTraceSpans',
836846
formData.includeRateLimits && 'includeRateLimits',
837847
formData.includeUsageData && 'includeUsageData',
838848
].filter(Boolean) as string[]
@@ -841,6 +851,7 @@ export function NotificationSettings({
841851
setFormData({
842852
...formData,
843853
includeFinalOutput: values.includes('includeFinalOutput'),
854+
includeTraceSpans: values.includes('includeTraceSpans'),
844855
includeRateLimits: values.includes('includeRateLimits'),
845856
includeUsageData: values.includes('includeUsageData'),
846857
})
@@ -849,11 +860,13 @@ export function NotificationSettings({
849860
overlayContent={(() => {
850861
const labels: Record<string, string> = {
851862
includeFinalOutput: 'Final Output',
863+
includeTraceSpans: 'Trace Spans',
852864
includeRateLimits: 'Rate Limits',
853865
includeUsageData: 'Usage Data',
854866
}
855867
const selected = [
856868
formData.includeFinalOutput && 'includeFinalOutput',
869+
formData.includeTraceSpans && activeTab === 'webhook' && 'includeTraceSpans',
857870
formData.includeRateLimits && 'includeRateLimits',
858871
formData.includeUsageData && 'includeUsageData',
859872
].filter(Boolean) as string[]

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/a2a/a2a.tsx

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ function isDefaultDescription(desc: string | null | undefined, workflowName: str
5252
if (!desc) return true
5353
const normalized = desc.toLowerCase().trim()
5454
return (
55-
normalized === '' || normalized === 'new workflow' || normalized === workflowName.toLowerCase()
55+
normalized === '' ||
56+
normalized === 'new workflow' ||
57+
normalized === 'your first workflow - start building here!' ||
58+
normalized === workflowName.toLowerCase()
5659
)
5760
}
5861

@@ -685,9 +688,31 @@ console.log(data);`
685688
{/* Endpoint URL (shown when agent exists) */}
686689
{existingAgent && endpoint && (
687690
<div>
688-
<Label className='mb-[6.5px] block pl-[2px] font-medium text-[13px] text-[var(--text-primary)]'>
689-
URL
690-
</Label>
691+
<div className='mb-[6.5px] flex items-center justify-between'>
692+
<Label className='block pl-[2px] font-medium text-[13px] text-[var(--text-primary)]'>
693+
URL
694+
</Label>
695+
<Tooltip.Root>
696+
<Tooltip.Trigger asChild>
697+
<Button
698+
type='button'
699+
variant='ghost'
700+
onClick={() => {
701+
navigator.clipboard.writeText(endpoint)
702+
setUrlCopied(true)
703+
setTimeout(() => setUrlCopied(false), 2000)
704+
}}
705+
aria-label='Copy URL'
706+
className='!p-1.5 -my-1.5'
707+
>
708+
{urlCopied ? <Check className='h-3 w-3' /> : <Clipboard className='h-3 w-3' />}
709+
</Button>
710+
</Tooltip.Trigger>
711+
<Tooltip.Content>
712+
<span>{urlCopied ? 'Copied' : 'Copy'}</span>
713+
</Tooltip.Content>
714+
</Tooltip.Root>
715+
</div>
691716
<div className='relative flex items-stretch overflow-hidden rounded-[4px] border border-[var(--border-1)]'>
692717
<div className='flex items-center whitespace-nowrap bg-[var(--surface-5)] pr-[6px] pl-[8px] font-medium text-[var(--text-secondary)] text-sm dark:bg-[var(--surface-5)]'>
693718
{baseUrl.replace(/^https?:\/\//, '')}/api/a2a/serve/
@@ -696,30 +721,8 @@ console.log(data);`
696721
<Input
697722
value={existingAgent.id}
698723
readOnly
699-
className='rounded-none border-0 pr-[32px] pl-0 text-[var(--text-tertiary)] shadow-none'
724+
className='rounded-none border-0 pl-0 text-[var(--text-tertiary)] shadow-none'
700725
/>
701-
<Tooltip.Root>
702-
<Tooltip.Trigger asChild>
703-
<button
704-
type='button'
705-
onClick={() => {
706-
navigator.clipboard.writeText(endpoint)
707-
setUrlCopied(true)
708-
setTimeout(() => setUrlCopied(false), 2000)
709-
}}
710-
className='-translate-y-1/2 absolute top-1/2 right-2'
711-
>
712-
{urlCopied ? (
713-
<Check className='h-3 w-3 text-[var(--brand-tertiary-2)]' />
714-
) : (
715-
<Clipboard className='h-3 w-3 text-[var(--text-tertiary)]' />
716-
)}
717-
</button>
718-
</Tooltip.Trigger>
719-
<Tooltip.Content>
720-
<span>{urlCopied ? 'Copied' : 'Copy'}</span>
721-
</Tooltip.Content>
722-
</Tooltip.Root>
723726
</div>
724727
</div>
725728
<p className='mt-[6.5px] text-[11px] text-[var(--text-secondary)]'>

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/chat/chat.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ export function ChatDeploy({
415415
>
416416
Cancel
417417
</Button>
418-
<Button variant='destructive' onClick={handleDelete} disabled={isDeleting}>
418+
<Button variant='default' onClick={handleDelete} disabled={isDeleting}>
419419
{isDeleting ? 'Deleting...' : 'Delete'}
420420
</Button>
421421
</ModalFooter>
@@ -532,7 +532,8 @@ function IdentifierInput({
532532
</div>
533533
) : (
534534
isValid &&
535-
value && (
535+
value &&
536+
value !== originalIdentifier && (
536537
<Tooltip.Root>
537538
<Tooltip.Trigger asChild>
538539
<div className='-translate-y-1/2 absolute top-1/2 right-2'>

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/mcp/mcp.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,12 @@ export function McpDeploy({
138138

139139
const [toolName, setToolName] = useState(() => sanitizeToolName(workflowName))
140140
const [toolDescription, setToolDescription] = useState(() => {
141+
const normalizedDesc = workflowDescription?.toLowerCase().trim()
141142
const isDefaultDescription =
142143
!workflowDescription ||
143144
workflowDescription === workflowName ||
144-
workflowDescription.toLowerCase() === 'new workflow'
145+
normalizedDesc === 'new workflow' ||
146+
normalizedDesc === 'your first workflow - start building here!'
145147

146148
return isDefaultDescription ? '' : workflowDescription
147149
})
@@ -193,10 +195,12 @@ export function McpDeploy({
193195
setToolName(toolInfo.tool.toolName)
194196

195197
const loadedDescription = toolInfo.tool.toolDescription || ''
198+
const normalizedLoadedDesc = loadedDescription.toLowerCase().trim()
196199
const isDefaultDescription =
197200
!loadedDescription ||
198201
loadedDescription === workflowName ||
199-
loadedDescription.toLowerCase() === 'new workflow'
202+
normalizedLoadedDesc === 'new workflow' ||
203+
normalizedLoadedDesc === 'your first workflow - start building here!'
200204
setToolDescription(isDefaultDescription ? '' : loadedDescription)
201205

202206
const schema = toolInfo.tool.parameterSchema as Record<string, unknown> | undefined

0 commit comments

Comments
 (0)