Skip to content

Commit 0415eb4

Browse files
fix(minor-bugs): grafana, zep, video generation, templates fixes (#2336)
* make creator profile required * fix grafana tag dropdown / outputs mismatch * fix grafana annotations to make dashboard id required * fix fal ai * fix fal ai * fix zep
1 parent 49d31c8 commit 0415eb4

File tree

19 files changed

+254
-165
lines changed

19 files changed

+254
-165
lines changed

apps/sim/app/api/proxy/video/route.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -807,18 +807,31 @@ async function generateWithFalAI(
807807
// Build request body based on model requirements
808808
const requestBody: any = { prompt }
809809

810-
// Format duration based on model requirements
811-
const formattedDuration = formatDuration(model, duration)
812-
if (formattedDuration !== undefined) {
813-
requestBody.duration = formattedDuration
814-
}
810+
// Models that support duration and aspect_ratio parameters
811+
const supportsStandardParams = [
812+
'kling-2.5-turbo-pro',
813+
'kling-2.1-pro',
814+
'minimax-hailuo-2.3-pro',
815+
'minimax-hailuo-2.3-standard',
816+
]
817+
818+
// Models that only need prompt (minimal params)
819+
const minimalParamModels = ['ltxv-0.9.8', 'wan-2.1', 'veo-3.1', 'sora-2']
820+
821+
if (supportsStandardParams.includes(model)) {
822+
// Kling and MiniMax models support duration and aspect_ratio
823+
const formattedDuration = formatDuration(model, duration)
824+
if (formattedDuration !== undefined) {
825+
requestBody.duration = formattedDuration
826+
}
815827

816-
if (aspectRatio) {
817-
requestBody.aspect_ratio = aspectRatio
818-
}
828+
if (aspectRatio) {
829+
requestBody.aspect_ratio = aspectRatio
830+
}
819831

820-
if (resolution) {
821-
requestBody.resolution = resolution
832+
if (resolution) {
833+
requestBody.resolution = resolution
834+
}
822835
}
823836

824837
// MiniMax models support prompt optimizer

apps/sim/app/api/templates/route.ts

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const CreateTemplateSchema = z.object({
4040
about: z.string().optional(), // Markdown long description
4141
})
4242
.optional(),
43-
creatorId: z.string().optional(), // Creator profile ID
43+
creatorId: z.string().min(1, 'Creator profile is required'),
4444
tags: z.array(z.string()).max(10, 'Maximum 10 tags allowed').optional().default([]),
4545
})
4646

@@ -204,50 +204,47 @@ export async function POST(request: NextRequest) {
204204
return NextResponse.json({ error: 'Workflow not found' }, { status: 404 })
205205
}
206206

207-
// Validate creator profile if provided
208-
if (data.creatorId) {
209-
// Verify the creator profile exists and user has access
210-
const creatorProfile = await db
211-
.select()
212-
.from(templateCreators)
213-
.where(eq(templateCreators.id, data.creatorId))
214-
.limit(1)
207+
// Validate creator profile - required for all templates
208+
const creatorProfile = await db
209+
.select()
210+
.from(templateCreators)
211+
.where(eq(templateCreators.id, data.creatorId))
212+
.limit(1)
213+
214+
if (creatorProfile.length === 0) {
215+
logger.warn(`[${requestId}] Creator profile not found: ${data.creatorId}`)
216+
return NextResponse.json({ error: 'Creator profile not found' }, { status: 404 })
217+
}
218+
219+
const creator = creatorProfile[0]
215220

216-
if (creatorProfile.length === 0) {
217-
logger.warn(`[${requestId}] Creator profile not found: ${data.creatorId}`)
218-
return NextResponse.json({ error: 'Creator profile not found' }, { status: 404 })
221+
// Verify user has permission to use this creator profile
222+
if (creator.referenceType === 'user') {
223+
if (creator.referenceId !== session.user.id) {
224+
logger.warn(`[${requestId}] User cannot use creator profile: ${data.creatorId}`)
225+
return NextResponse.json(
226+
{ error: 'You do not have permission to use this creator profile' },
227+
{ status: 403 }
228+
)
219229
}
230+
} else if (creator.referenceType === 'organization') {
231+
// Verify user is a member of the organization
232+
const membership = await db
233+
.select()
234+
.from(member)
235+
.where(
236+
and(eq(member.userId, session.user.id), eq(member.organizationId, creator.referenceId))
237+
)
238+
.limit(1)
220239

221-
const creator = creatorProfile[0]
222-
223-
// Verify user has permission to use this creator profile
224-
if (creator.referenceType === 'user') {
225-
if (creator.referenceId !== session.user.id) {
226-
logger.warn(`[${requestId}] User cannot use creator profile: ${data.creatorId}`)
227-
return NextResponse.json(
228-
{ error: 'You do not have permission to use this creator profile' },
229-
{ status: 403 }
230-
)
231-
}
232-
} else if (creator.referenceType === 'organization') {
233-
// Verify user is a member of the organization
234-
const membership = await db
235-
.select()
236-
.from(member)
237-
.where(
238-
and(eq(member.userId, session.user.id), eq(member.organizationId, creator.referenceId))
239-
)
240-
.limit(1)
241-
242-
if (membership.length === 0) {
243-
logger.warn(
244-
`[${requestId}] User not a member of organization for creator: ${data.creatorId}`
245-
)
246-
return NextResponse.json(
247-
{ error: 'You must be a member of the organization to use its creator profile' },
248-
{ status: 403 }
249-
)
250-
}
240+
if (membership.length === 0) {
241+
logger.warn(
242+
`[${requestId}] User not a member of organization for creator: ${data.creatorId}`
243+
)
244+
return NextResponse.json(
245+
{ error: 'You must be a member of the organization to use its creator profile' },
246+
{ status: 403 }
247+
)
251248
}
252249
}
253250

@@ -307,7 +304,7 @@ export async function POST(request: NextRequest) {
307304
workflowId: data.workflowId,
308305
name: data.name,
309306
details: data.details || null,
310-
creatorId: data.creatorId || null,
307+
creatorId: data.creatorId,
311308
views: 0,
312309
stars: 0,
313310
status: 'pending' as const, // All new templates start as pending

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

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ export function TemplateDeploy({
8989

9090
const isSubmitting = createMutation.isPending || updateMutation.isPending
9191
const isFormValid =
92-
formData.name.trim().length > 0 && formData.name.length <= 100 && formData.tagline.length <= 200
92+
formData.name.trim().length > 0 &&
93+
formData.name.length <= 100 &&
94+
formData.tagline.length <= 200 &&
95+
formData.creatorId.length > 0
9396

9497
const updateField = <K extends keyof TemplateFormData>(field: K, value: TemplateFormData[K]) => {
9598
setFormData((prev) => ({ ...prev, [field]: value }))
@@ -201,7 +204,7 @@ export function TemplateDeploy({
201204
tagline: formData.tagline.trim(),
202205
about: formData.about.trim(),
203206
},
204-
creatorId: formData.creatorId || undefined,
207+
creatorId: formData.creatorId,
205208
tags: formData.tags,
206209
}
207210

@@ -285,7 +288,7 @@ export function TemplateDeploy({
285288

286289
<div>
287290
<Label className='mb-[6.5px] block pl-[2px] font-medium text-[13px] text-[var(--text-primary)]'>
288-
Name
291+
Name <span className='text-[var(--text-error)]'>*</span>
289292
</Label>
290293
<Input
291294
placeholder='Deep Research Agent'
@@ -323,29 +326,34 @@ export function TemplateDeploy({
323326

324327
<div>
325328
<Label className='mb-[6.5px] block pl-[2px] font-medium text-[13px] text-[var(--text-primary)]'>
326-
Creator
329+
Creator <span className='text-[var(--text-error)]'>*</span>
327330
</Label>
328331
{creatorOptions.length === 0 && !loadingCreators ? (
329-
<Button
330-
type='button'
331-
variant='primary'
332-
onClick={() => {
333-
try {
334-
const event = new CustomEvent('open-settings', {
335-
detail: { tab: 'template-profile' },
336-
})
337-
window.dispatchEvent(event)
338-
logger.info('Opened Settings modal at template-profile section')
339-
} catch (error) {
340-
logger.error('Failed to open Settings modal for template profile', {
341-
error,
342-
})
343-
}
344-
}}
345-
className='gap-[8px]'
346-
>
347-
<span>Create Template Profile</span>
348-
</Button>
332+
<div className='space-y-[8px]'>
333+
<p className='text-[12px] text-[var(--text-tertiary)]'>
334+
A creator profile is required to publish templates.
335+
</p>
336+
<Button
337+
type='button'
338+
variant='primary'
339+
onClick={() => {
340+
try {
341+
const event = new CustomEvent('open-settings', {
342+
detail: { tab: 'template-profile' },
343+
})
344+
window.dispatchEvent(event)
345+
logger.info('Opened Settings modal at template-profile section')
346+
} catch (error) {
347+
logger.error('Failed to open Settings modal for template profile', {
348+
error,
349+
})
350+
}
351+
}}
352+
className='gap-[8px]'
353+
>
354+
<span>Create Template Profile</span>
355+
</Button>
356+
</div>
349357
) : (
350358
<Combobox
351359
options={creatorOptions.map((option) => ({

apps/sim/blocks/blocks/grafana.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
298298
id: 'annotationDashboardUid',
299299
title: 'Dashboard UID',
300300
type: 'short-input',
301-
placeholder: 'Optional - attach to specific dashboard',
301+
placeholder: 'Enter dashboard UID',
302+
required: true,
302303
condition: {
303304
field: 'operation',
304305
value: ['grafana_create_annotation', 'grafana_list_annotations'],

apps/sim/blocks/blocks/video_generator.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,29 @@ export const VideoGeneratorBlock: BlockConfig<VideoBlockResponse> = {
169169
required: false,
170170
},
171171

172+
// Duration selection - Fal.ai (only for Kling and MiniMax models)
173+
{
174+
id: 'duration',
175+
title: 'Duration (seconds)',
176+
type: 'dropdown',
177+
condition: {
178+
field: 'model',
179+
value: [
180+
'kling-2.5-turbo-pro',
181+
'kling-2.1-pro',
182+
'minimax-hailuo-2.3-pro',
183+
'minimax-hailuo-2.3-standard',
184+
],
185+
},
186+
options: [
187+
{ label: '5', id: '5' },
188+
{ label: '8', id: '8' },
189+
{ label: '10', id: '10' },
190+
],
191+
value: () => '5',
192+
required: false,
193+
},
194+
172195
// Aspect ratio selection - Veo (only 16:9 and 9:16)
173196
{
174197
id: 'aspectRatio',
@@ -213,6 +236,28 @@ export const VideoGeneratorBlock: BlockConfig<VideoBlockResponse> = {
213236
required: false,
214237
},
215238

239+
// Aspect ratio selection - Fal.ai (only for Kling and MiniMax models)
240+
{
241+
id: 'aspectRatio',
242+
title: 'Aspect Ratio',
243+
type: 'dropdown',
244+
condition: {
245+
field: 'model',
246+
value: [
247+
'kling-2.5-turbo-pro',
248+
'kling-2.1-pro',
249+
'minimax-hailuo-2.3-pro',
250+
'minimax-hailuo-2.3-standard',
251+
],
252+
},
253+
options: [
254+
{ label: '16:9', id: '16:9' },
255+
{ label: '9:16', id: '9:16' },
256+
],
257+
value: () => '16:9',
258+
required: false,
259+
},
260+
216261
// Note: MiniMax aspect ratio is fixed at 16:9 (not configurable)
217262

218263
// Note: Runway Gen-4 Turbo outputs at 720p natively (no resolution selector needed)

apps/sim/blocks/blocks/zep.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,26 +276,26 @@ export const ZepBlock: BlockConfig<ZepResponse> = {
276276
metadata: { type: 'json', description: 'User metadata' },
277277
},
278278
outputs: {
279+
// Thread operations
279280
threadId: { type: 'string', description: 'Thread identifier' },
280-
userId: { type: 'string', description: 'User identifier' },
281281
uuid: { type: 'string', description: 'Internal UUID' },
282282
createdAt: { type: 'string', description: 'Creation timestamp' },
283283
updatedAt: { type: 'string', description: 'Update timestamp' },
284284
threads: { type: 'json', description: 'Array of threads' },
285285
deleted: { type: 'boolean', description: 'Deletion status' },
286+
// Message operations
286287
messages: { type: 'json', description: 'Message data' },
287-
messageIds: { type: 'json', description: 'Message identifiers' },
288-
context: { type: 'string', description: 'User context string' },
289-
facts: { type: 'json', description: 'Extracted facts' },
290-
entities: { type: 'json', description: 'Extracted entities' },
291-
summary: { type: 'string', description: 'Conversation summary' },
292-
batchId: { type: 'string', description: 'Batch operation ID' },
288+
messageIds: { type: 'json', description: 'Array of added message UUIDs' },
289+
added: { type: 'boolean', description: 'Whether messages were added successfully' },
290+
// Context operations
291+
context: { type: 'string', description: 'User context string (summary or basic mode)' },
292+
// User operations
293+
userId: { type: 'string', description: 'User identifier' },
293294
email: { type: 'string', description: 'User email' },
294295
firstName: { type: 'string', description: 'User first name' },
295296
lastName: { type: 'string', description: 'User last name' },
296297
metadata: { type: 'json', description: 'User metadata' },
297-
responseCount: { type: 'number', description: 'Number of items in response' },
298-
totalCount: { type: 'number', description: 'Total number of items available' },
299-
rowCount: { type: 'number', description: 'Number of rows in response' },
298+
// Counts
299+
totalCount: { type: 'number', description: 'Total number of items returned' },
300300
},
301301
}

apps/sim/tools/grafana/create_annotation.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,9 @@ export const createAnnotationTool: ToolConfig<
4646
},
4747
dashboardUid: {
4848
type: 'string',
49-
required: false,
49+
required: true,
5050
visibility: 'user-or-llm',
51-
description:
52-
'UID of the dashboard to add the annotation to (optional for global annotations)',
51+
description: 'UID of the dashboard to add the annotation to',
5352
},
5453
panelId: {
5554
type: 'number',

apps/sim/tools/grafana/create_folder.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,45 @@ export const createFolderTool: ToolConfig<GrafanaCreateFolderParams, GrafanaCrea
108108
type: 'string',
109109
description: 'The URL path to the folder',
110110
},
111+
hasAcl: {
112+
type: 'boolean',
113+
description: 'Whether the folder has custom ACL permissions',
114+
},
115+
canSave: {
116+
type: 'boolean',
117+
description: 'Whether the current user can save the folder',
118+
},
119+
canEdit: {
120+
type: 'boolean',
121+
description: 'Whether the current user can edit the folder',
122+
},
123+
canAdmin: {
124+
type: 'boolean',
125+
description: 'Whether the current user has admin rights on the folder',
126+
},
127+
canDelete: {
128+
type: 'boolean',
129+
description: 'Whether the current user can delete the folder',
130+
},
131+
createdBy: {
132+
type: 'string',
133+
description: 'Username of who created the folder',
134+
},
135+
created: {
136+
type: 'string',
137+
description: 'Timestamp when the folder was created',
138+
},
139+
updatedBy: {
140+
type: 'string',
141+
description: 'Username of who last updated the folder',
142+
},
143+
updated: {
144+
type: 'string',
145+
description: 'Timestamp when the folder was last updated',
146+
},
147+
version: {
148+
type: 'number',
149+
description: 'Version number of the folder',
150+
},
111151
},
112152
}

0 commit comments

Comments
 (0)