feat(fireflies): added fireflies tools and trigger (#2713)

* feat(fireflies): added fireflies tools and trigger

* finished fireflies

* added wandConfig to all timestamp subblocks on the platform

* added current time to timestamp wand generation

* fix file upload subblock styling, tested all fireflies ops

* removed dropdown for trigger for fireflies

* updated docs

* added fireflies to formatWebhookInput

* added more wandConfigs
This commit is contained in:
Waleed
2026-01-07 13:40:36 -08:00
committed by GitHub
parent 3b4f7d6adb
commit 2bd27f9a4d
85 changed files with 7360 additions and 68 deletions

View File

@@ -4414,3 +4414,164 @@ export function JiraServiceManagementIcon(props: SVGProps<SVGSVGElement>) {
</svg>
)
}
export function FirefliesIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='-6 -6 68 68'>
<defs>
<linearGradient
id='fireflies_g1'
gradientUnits='userSpaceOnUse'
x1='144.6644'
y1='-133.7781'
x2='54.3811'
y2='-38.9195'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.113' stopColor='#DE2D7A' />
<stop offset='0.3' stopColor='#C5388F' />
<stop offset='0.54' stopColor='#9B4AB0' />
<stop offset='0.818' stopColor='#6262DE' />
<stop offset='0.994' stopColor='#3B73FF' />
</linearGradient>
<linearGradient
id='fireflies_g2'
gradientUnits='userSpaceOnUse'
x1='145.1664'
y1='-133.3084'
x2='54.8831'
y2='-38.4499'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#FF3C82' />
<stop offset='0.103' stopColor='#F53E88' />
<stop offset='0.274' stopColor='#DC4598' />
<stop offset='0.492' stopColor='#B251B2' />
<stop offset='0.745' stopColor='#7961D7' />
<stop offset='0.994' stopColor='#3B73FF' />
</linearGradient>
<linearGradient
id='fireflies_g3'
gradientUnits='userSpaceOnUse'
x1='144.7625'
y1='-123.2011'
x2='114.171'
y2='-12.3403'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.113' stopColor='#DE2D7A' />
<stop offset='0.3' stopColor='#C5388F' />
<stop offset='0.54' stopColor='#9B4AB0' />
<stop offset='0.818' stopColor='#6262DE' />
<stop offset='0.994' stopColor='#3B73FF' />
</linearGradient>
<linearGradient
id='fireflies_g4'
gradientUnits='userSpaceOnUse'
x1='134.8237'
y1='-132.3271'
x2='25.3098'
y2='-98.9636'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.113' stopColor='#DE2D7A' />
<stop offset='0.3' stopColor='#C5388F' />
<stop offset='0.54' stopColor='#9B4AB0' />
<stop offset='0.818' stopColor='#6262DE' />
<stop offset='0.994' stopColor='#3B73FF' />
</linearGradient>
<linearGradient
id='fireflies_g5'
gradientUnits='userSpaceOnUse'
x1='82.2078'
y1='-52.7908'
x2='112.8836'
y2='-123.0805'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.114' stopColor='#DE286E' />
<stop offset='0.303' stopColor='#C52361' />
<stop offset='0.544' stopColor='#9B1A4D' />
<stop offset='0.825' stopColor='#620F30' />
<stop offset='0.994' stopColor='#3D081E' />
</linearGradient>
<linearGradient
id='fireflies_g6'
gradientUnits='userSpaceOnUse'
x1='107.6542'
y1='-78.5296'
x2='138.33'
y2='-148.8194'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.114' stopColor='#DE286E' />
<stop offset='0.303' stopColor='#C52361' />
<stop offset='0.544' stopColor='#9B1A4D' />
<stop offset='0.825' stopColor='#620F30' />
<stop offset='0.994' stopColor='#3D081E' />
</linearGradient>
<linearGradient
id='fireflies_g7'
gradientUnits='userSpaceOnUse'
x1='70.8311'
y1='-99.3209'
x2='140.3046'
y2='-145.474'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.114' stopColor='#DE286E' />
<stop offset='0.303' stopColor='#C52361' />
<stop offset='0.544' stopColor='#9B1A4D' />
<stop offset='0.825' stopColor='#620F30' />
<stop offset='0.994' stopColor='#3D081E' />
</linearGradient>
<linearGradient
id='fireflies_g8'
gradientUnits='userSpaceOnUse'
x1='297.6904'
y1='-1360.8851'
x2='309.5946'
y2='-1454.8754'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.114' stopColor='#DE286E' />
<stop offset='0.303' stopColor='#C52361' />
<stop offset='0.544' stopColor='#9B1A4D' />
<stop offset='0.825' stopColor='#620F30' />
<stop offset='0.994' stopColor='#3D081E' />
</linearGradient>
</defs>
<g>
<path fill='url(#fireflies_g1)' d='M18.4,0H0v18.3h18.4V0z' />
<path fill='url(#fireflies_g2)' d='M40.2,22.1H21.8v18.3h18.4V22.1z' />
<path
fill='url(#fireflies_g3)'
d='M40.2,0H21.8v18.3H56v-2.6c0-4.2-1.7-8.1-4.6-11.1C48.4,1.7,44.4,0,40.2,0L40.2,0z'
/>
<path
fill='url(#fireflies_g4)'
d='M0,22.1v18.3c0,4.2,1.7,8.1,4.6,11.1c3,2.9,7,4.6,11.2,4.6h2.6V22.1H0z'
/>
<path fill='url(#fireflies_g5)' opacity='0.18' d='M0,0l18.4,18.3H0V0z' />
<path fill='url(#fireflies_g6)' opacity='0.18' d='M21.8,22.1l18.4,18.3H21.8V22.1z' />
<path
fill='url(#fireflies_g7)'
opacity='0.18'
d='M0,40.3c0,4.2,1.7,8.1,4.6,11.1c3,2.9,7,4.6,11.2,4.6h2.6V22.1L0,40.3z'
/>
<path
fill='url(#fireflies_g8)'
opacity='0.18'
d='M40.2,0c4.2,0,8.2,1.7,11.2,4.6c3,2.9,4.6,6.9,4.6,11.1v2.6H21.8L40.2,0z'
/>
</g>
</svg>
)
}

View File

@@ -28,6 +28,7 @@ import {
ExaAIIcon,
EyeIcon,
FirecrawlIcon,
FirefliesIcon,
GithubIcon,
GitLabIcon,
GmailIcon,
@@ -147,6 +148,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
exa: ExaAIIcon,
file: DocumentIcon,
firecrawl: FirecrawlIcon,
fireflies: FirefliesIcon,
github: GithubIcon,
gitlab: GitLabIcon,
gmail: GmailIcon,

View File

@@ -0,0 +1,238 @@
---
title: Fireflies
description: Interact with Fireflies.ai meeting transcripts and recordings
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="fireflies"
color="#100730"
/>
{/* MANUAL-CONTENT-START:intro */}
[Fireflies.ai](https://fireflies.ai/) is a meeting transcription and intelligence platform that integrates with Sim, allowing your agents to work directly with meeting recordings, transcripts, and insights through no-code automations.
The Fireflies integration in Sim provides tools to:
- **List meeting transcripts:** Fetch multiple meetings and their summary information for your team or account.
- **Retrieve full transcript details:** Access detailed transcripts, including summaries, action items, topics, and participant analytics for any meeting.
- **Upload audio or video:** Upload audio/video files or provide URLs for transcription—optionally set language, title, attendees, and receive automated meeting notes.
- **Search transcripts:** Find meetings by keyword, participant, host, or timeframe to quickly locate relevant discussions.
- **Delete transcripts:** Remove specific meeting transcripts from your Fireflies workspace.
- **Create soundbites (Bites):** Extract and highlight key moments from transcripts as audio or video clips.
- **Trigger workflows on transcription completion:** Activate Sim workflows automatically when a Fireflies meeting transcription finishes using the provided webhook trigger—enabling real-time automations and notifications based on new meeting data.
By combining these capabilities, you can streamline post-meeting actions, extract structured insights, automate notifications, manage recordings, and orchestrate custom workflows around your organizations calls—all securely using your API key and Fireflies credentials.
{/* MANUAL-CONTENT-END */}
## Usage Instructions
Integrate Fireflies.ai into the workflow. Manage meeting transcripts, add bot to live meetings, create soundbites, and more. Can also trigger workflows when transcriptions complete.
## Tools
### `fireflies_list_transcripts`
List meeting transcripts from Fireflies.ai with optional filtering
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
| `keyword` | string | No | Search keyword in meeting title or transcript |
| `fromDate` | string | No | Filter transcripts from this date \(ISO 8601 format\) |
| `toDate` | string | No | Filter transcripts until this date \(ISO 8601 format\) |
| `hostEmail` | string | No | Filter by meeting host email |
| `participants` | string | No | Filter by participant emails \(comma-separated\) |
| `limit` | number | No | Maximum number of transcripts to return \(max 50\) |
| `skip` | number | No | Number of transcripts to skip for pagination |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `transcripts` | array | List of transcripts |
| `count` | number | Number of transcripts returned |
### `fireflies_get_transcript`
Get a single transcript with full details including summary, action items, and analytics
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
| `transcriptId` | string | Yes | The transcript ID to retrieve |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `transcript` | object | The transcript with full details |
### `fireflies_get_user`
Get user information from Fireflies.ai. Returns current user if no ID specified.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
| `userId` | string | No | User ID to retrieve \(optional, defaults to API key owner\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `user` | object | User information |
### `fireflies_list_users`
List all users within your Fireflies.ai team
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `users` | array | List of team users |
### `fireflies_upload_audio`
Upload an audio file URL to Fireflies.ai for transcription
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
| `audioFile` | file | No | Audio/video file to upload for transcription |
| `audioUrl` | string | No | Public HTTPS URL of the audio/video file \(MP3, MP4, WAV, M4A, OGG\) |
| `title` | string | No | Title for the meeting/transcript |
| `webhook` | string | No | Webhook URL to notify when transcription is complete |
| `language` | string | No | Language code for transcription \(e.g., "es" for Spanish, "de" for German\) |
| `attendees` | string | No | Attendees in JSON format: \[\{"displayName": "Name", "email": "email@example.com"\}\] |
| `clientReferenceId` | string | No | Custom reference ID for tracking |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Whether the upload was successful |
| `title` | string | Title of the uploaded meeting |
| `message` | string | Status message from Fireflies |
### `fireflies_delete_transcript`
Delete a transcript from Fireflies.ai
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
| `transcriptId` | string | Yes | The transcript ID to delete |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Whether the transcript was successfully deleted |
### `fireflies_add_to_live_meeting`
Add the Fireflies.ai bot to an ongoing meeting to record and transcribe
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
| `meetingLink` | string | Yes | Valid meeting URL \(Zoom, Google Meet, Microsoft Teams, etc.\) |
| `title` | string | No | Title for the meeting \(max 256 characters\) |
| `meetingPassword` | string | No | Password for the meeting if required \(max 32 characters\) |
| `duration` | number | No | Meeting duration in minutes \(15-120, default: 60\) |
| `language` | string | No | Language code for transcription \(e.g., "en", "es", "de"\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Whether the bot was successfully added to the meeting |
### `fireflies_create_bite`
Create a soundbite/highlight from a specific time range in a transcript
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
| `transcriptId` | string | Yes | ID of the transcript to create the bite from |
| `startTime` | number | Yes | Start time of the bite in seconds |
| `endTime` | number | Yes | End time of the bite in seconds |
| `name` | string | No | Name for the bite \(max 256 characters\) |
| `mediaType` | string | No | Media type: "video" or "audio" |
| `summary` | string | No | Summary for the bite \(max 500 characters\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `bite` | object | Created bite details |
### `fireflies_list_bites`
List soundbites/highlights from Fireflies.ai
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
| `transcriptId` | string | No | Filter bites for a specific transcript |
| `mine` | boolean | No | Only return bites owned by the API key owner \(default: true\) |
| `limit` | number | No | Maximum number of bites to return \(max 50\) |
| `skip` | number | No | Number of bites to skip for pagination |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `bites` | array | List of bites/soundbites |
### `fireflies_list_contacts`
List all contacts from your Fireflies.ai meetings
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Fireflies API key |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `contacts` | array | List of contacts from meetings |
## Notes
- Category: `tools`
- Type: `fireflies`

View File

@@ -23,6 +23,7 @@
"exa",
"file",
"firecrawl",
"fireflies",
"github",
"gitlab",
"gmail",

View File

@@ -59,6 +59,7 @@ interface RequestBody {
stream?: boolean
history?: ChatMessage[]
workflowId?: string
generationType?: string
}
function safeStringify(value: unknown): string {
@@ -158,7 +159,7 @@ export async function POST(req: NextRequest) {
try {
const body = (await req.json()) as RequestBody
const { prompt, systemPrompt, stream = false, history = [], workflowId } = body
const { prompt, systemPrompt, stream = false, history = [], workflowId, generationType } = body
if (!prompt) {
logger.warn(`[${requestId}] Invalid request: Missing prompt.`)
@@ -222,10 +223,26 @@ export async function POST(req: NextRequest) {
)
}
const finalSystemPrompt =
let finalSystemPrompt =
systemPrompt ||
'You are a helpful AI assistant. Generate content exactly as requested by the user.'
if (generationType === 'timestamp') {
const now = new Date()
const currentTimeContext = `\n\nCurrent date and time context for reference:
- Current UTC timestamp: ${now.toISOString()}
- Current Unix timestamp (seconds): ${Math.floor(now.getTime() / 1000)}
- Current Unix timestamp (milliseconds): ${now.getTime()}
- Current date (UTC): ${now.toISOString().split('T')[0]}
- Current year: ${now.getUTCFullYear()}
- Current month: ${now.getUTCMonth() + 1}
- Current day of month: ${now.getUTCDate()}
- Current day of week: ${['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][now.getUTCDay()]}
Use this context to calculate relative dates like "yesterday", "last week", "beginning of this month", etc.`
finalSystemPrompt += currentTimeContext
}
const messages: ChatMessage[] = [{ role: 'system', content: finalSystemPrompt }]
messages.push(...history.filter((msg) => msg.role !== 'system'))

View File

@@ -6,6 +6,7 @@ import { X } from 'lucide-react'
import { useParams } from 'next/navigation'
import { Button, Combobox } from '@/components/emcn/components'
import { Progress } from '@/components/ui/progress'
import { cn } from '@/lib/core/utils/cn'
import type { WorkspaceFileRecord } from '@/lib/uploads/contexts/workspace'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
@@ -429,14 +430,14 @@ export function FileUpload({
<Button
type='button'
variant='ghost'
className='h-6 w-6 shrink-0 p-0'
className='h-5 w-5 shrink-0 p-0'
onClick={(e) => handleRemoveFile(file, e)}
disabled={isDeleting}
>
{isDeleting ? (
<div className='h-4 w-4 animate-spin rounded-full border-[1.5px] border-current border-t-transparent' />
<div className='h-3.5 w-3.5 animate-spin rounded-full border-[1.5px] border-current border-t-transparent' />
) : (
<X className='h-4 w-4' />
<X className='h-3.5 w-3.5' />
)}
</Button>
</div>
@@ -453,8 +454,8 @@ export function FileUpload({
<span className='text-[var(--text-primary)]'>{file.name}</span>
<span className='ml-2 text-[var(--text-muted)]'>({formatFileSize(file.size)})</span>
</div>
<div className='flex h-8 w-8 shrink-0 items-center justify-center'>
<div className='h-4 w-4 animate-spin rounded-full border-[1.5px] border-current border-t-transparent' />
<div className='flex h-5 w-5 shrink-0 items-center justify-center'>
<div className='h-3.5 w-3.5 animate-spin rounded-full border-[1.5px] border-current border-t-transparent' />
</div>
</div>
)
@@ -512,72 +513,66 @@ export function FileUpload({
{/* Error message */}
{uploadError && <div className='mb-2 text-red-600 text-sm'>{uploadError}</div>}
<div>
{/* File list with consistent spacing */}
{(hasFiles || isUploading) && (
<div className='mb-2 space-y-2'>
{/* Only show files that aren't currently uploading */}
{filesArray.map((file) => {
const isCurrentlyUploading = uploadingFiles.some(
(uploadingFile) => uploadingFile.name === file.name
)
return !isCurrentlyUploading && renderFileItem(file)
})}
{isUploading && (
<>
{uploadingFiles.map(renderUploadingItem)}
<div className='mt-1'>
<Progress
value={uploadProgress}
className='h-2 w-full'
indicatorClassName='bg-foreground'
/>
<div className='mt-1 text-center text-muted-foreground text-xs'>
{uploadProgress < 100 ? 'Uploading...' : 'Upload complete!'}
</div>
{/* File list with consistent spacing */}
{(hasFiles || isUploading) && (
<div className={cn('space-y-2', multiple && 'mb-2')}>
{/* Only show files that aren't currently uploading */}
{filesArray.map((file) => {
const isCurrentlyUploading = uploadingFiles.some(
(uploadingFile) => uploadingFile.name === file.name
)
return !isCurrentlyUploading && renderFileItem(file)
})}
{isUploading && (
<>
{uploadingFiles.map(renderUploadingItem)}
<div className='mt-1'>
<Progress
value={uploadProgress}
className='h-2 w-full'
indicatorClassName='bg-foreground'
/>
<div className='mt-1 text-center text-muted-foreground text-xs'>
{uploadProgress < 100 ? 'Uploading...' : 'Upload complete!'}
</div>
</>
)}
</div>
)}
</div>
</>
)}
</div>
)}
{/* Add More dropdown for multiple files */}
{hasFiles && multiple && !isUploading && (
<div>
<Combobox
options={comboboxOptions}
value={inputValue}
onChange={handleComboboxChange}
onOpenChange={(open) => {
if (open) void loadWorkspaceFiles()
}}
placeholder={loadingWorkspaceFiles ? 'Loading files...' : '+ Add More'}
disabled={disabled || loadingWorkspaceFiles}
editable={true}
filterOptions={true}
isLoading={loadingWorkspaceFiles}
/>
</div>
)}
</div>
{/* Add More dropdown for multiple files */}
{hasFiles && multiple && !isUploading && (
<Combobox
options={comboboxOptions}
value={inputValue}
onChange={handleComboboxChange}
onOpenChange={(open) => {
if (open) void loadWorkspaceFiles()
}}
placeholder={loadingWorkspaceFiles ? 'Loading files...' : '+ Add More'}
disabled={disabled || loadingWorkspaceFiles}
editable={true}
filterOptions={true}
isLoading={loadingWorkspaceFiles}
/>
)}
{/* Show dropdown selector if no files and not uploading */}
{!hasFiles && !isUploading && (
<div className='flex items-center'>
<Combobox
options={comboboxOptions}
value={inputValue}
onChange={handleComboboxChange}
onOpenChange={(open) => {
if (open) void loadWorkspaceFiles()
}}
placeholder={loadingWorkspaceFiles ? 'Loading files...' : 'Select or upload file'}
disabled={disabled || loadingWorkspaceFiles}
editable={true}
filterOptions={true}
isLoading={loadingWorkspaceFiles}
/>
</div>
<Combobox
options={comboboxOptions}
value={inputValue}
onChange={handleComboboxChange}
onOpenChange={(open) => {
if (open) void loadWorkspaceFiles()
}}
placeholder={loadingWorkspaceFiles ? 'Loading files...' : 'Select or upload file'}
disabled={disabled || loadingWorkspaceFiles}
editable={true}
filterOptions={true}
isLoading={loadingWorkspaceFiles}
/>
)}
</div>
)

View File

@@ -169,6 +169,7 @@ export function useWand({
systemPrompt: systemPrompt,
stream: true,
history: wandConfig?.maintainHistory ? conversationHistory : [],
generationType: wandConfig?.generationType,
}),
signal: abortControllerRef.current.signal,
cache: 'no-store',

View File

@@ -46,6 +46,19 @@ export const AhrefsBlock: BlockConfig<AhrefsResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD (defaults to today)',
condition: { field: 'operation', value: 'ahrefs_domain_rating' },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Current date in YYYY-MM-DD format
- "yesterday" -> Yesterday's date in YYYY-MM-DD format
- "last week" -> Date 7 days ago in YYYY-MM-DD format
- "beginning of this month" -> First day of current month in YYYY-MM-DD format
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "yesterday", "last week", "start of month")...',
generationType: 'timestamp',
},
},
// Backlinks operation inputs
{
@@ -89,6 +102,19 @@ export const AhrefsBlock: BlockConfig<AhrefsResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD (defaults to today)',
condition: { field: 'operation', value: 'ahrefs_backlinks' },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Current date in YYYY-MM-DD format
- "yesterday" -> Yesterday's date in YYYY-MM-DD format
- "last week" -> Date 7 days ago in YYYY-MM-DD format
- "beginning of this month" -> First day of current month in YYYY-MM-DD format
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "yesterday", "last week", "start of month")...',
generationType: 'timestamp',
},
},
// Backlinks Stats operation inputs
{
@@ -118,6 +144,19 @@ export const AhrefsBlock: BlockConfig<AhrefsResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD (defaults to today)',
condition: { field: 'operation', value: 'ahrefs_backlinks_stats' },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Current date in YYYY-MM-DD format
- "yesterday" -> Yesterday's date in YYYY-MM-DD format
- "last week" -> Date 7 days ago in YYYY-MM-DD format
- "beginning of this month" -> First day of current month in YYYY-MM-DD format
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "yesterday", "last week", "start of month")...',
generationType: 'timestamp',
},
},
// Referring Domains operation inputs
{
@@ -161,6 +200,19 @@ export const AhrefsBlock: BlockConfig<AhrefsResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD (defaults to today)',
condition: { field: 'operation', value: 'ahrefs_referring_domains' },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Current date in YYYY-MM-DD format
- "yesterday" -> Yesterday's date in YYYY-MM-DD format
- "last week" -> Date 7 days ago in YYYY-MM-DD format
- "beginning of this month" -> First day of current month in YYYY-MM-DD format
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "yesterday", "last week", "start of month")...',
generationType: 'timestamp',
},
},
// Organic Keywords operation inputs
{
@@ -228,6 +280,19 @@ export const AhrefsBlock: BlockConfig<AhrefsResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD (defaults to today)',
condition: { field: 'operation', value: 'ahrefs_organic_keywords' },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Current date in YYYY-MM-DD format
- "yesterday" -> Yesterday's date in YYYY-MM-DD format
- "last week" -> Date 7 days ago in YYYY-MM-DD format
- "beginning of this month" -> First day of current month in YYYY-MM-DD format
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "yesterday", "last week", "start of month")...',
generationType: 'timestamp',
},
},
// Top Pages operation inputs
{
@@ -294,6 +359,19 @@ export const AhrefsBlock: BlockConfig<AhrefsResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD (defaults to today)',
condition: { field: 'operation', value: 'ahrefs_top_pages' },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Current date in YYYY-MM-DD format
- "yesterday" -> Yesterday's date in YYYY-MM-DD format
- "last week" -> Date 7 days ago in YYYY-MM-DD format
- "beginning of this month" -> First day of current month in YYYY-MM-DD format
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "yesterday", "last week", "start of month")...',
generationType: 'timestamp',
},
},
// Keyword Overview operation inputs
{
@@ -370,6 +448,19 @@ export const AhrefsBlock: BlockConfig<AhrefsResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD (defaults to today)',
condition: { field: 'operation', value: 'ahrefs_broken_backlinks' },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Current date in YYYY-MM-DD format
- "yesterday" -> Yesterday's date in YYYY-MM-DD format
- "last week" -> Date 7 days ago in YYYY-MM-DD format
- "beginning of this month" -> First day of current month in YYYY-MM-DD format
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "yesterday", "last week", "start of month")...',
generationType: 'timestamp',
},
},
// API Key (common to all operations)
{

View File

@@ -79,6 +79,37 @@ export const AirtableBlock: BlockConfig<AirtableResponse> = {
type: 'long-input',
placeholder: 'Airtable formula to filter records (optional)',
condition: { field: 'operation', value: 'list' },
wandConfig: {
enabled: true,
prompt: `Generate an Airtable filter formula based on the user's description.
Airtable formulas use a syntax similar to Excel/spreadsheet formulas.
Common functions:
- {Field Name} - Reference a field by name (with curly braces)
- AND(condition1, condition2) - Both conditions must be true
- OR(condition1, condition2) - Either condition can be true
- NOT(condition) - Negates the condition
- IF(condition, value_if_true, value_if_false)
- FIND("text", {Field}) - Find text in a field (returns position or 0)
- SEARCH("text", {Field}) - Case-insensitive search
- LEN({Field}) - Length of text
- DATETIME_DIFF(date1, date2, 'days') - Difference between dates
- TODAY() - Current date
- NOW() - Current date and time
- BLANK() - Empty value
- {Field} = "" - Check if field is empty
- {Field} != "" - Check if field is not empty
Examples:
- "find all completed tasks" -> {Status} = "Completed"
- "records from last 7 days" -> DATETIME_DIFF(NOW(), {Created}, 'days') <= 7
- "name contains John" -> FIND("John", {Name}) > 0
- "status is active or pending" -> OR({Status} = "Active", {Status} = "Pending")
- "priority is high and not assigned" -> AND({Priority} = "High", {Assignee} = "")
Return ONLY the formula - no explanations, no quotes around the entire formula.`,
placeholder: 'Describe the filter criteria (e.g., "completed tasks from last week")...',
},
},
{
id: 'records',
@@ -87,6 +118,44 @@ export const AirtableBlock: BlockConfig<AirtableResponse> = {
placeholder: 'For Create: `[{ "fields": { ... } }]`\n',
condition: { field: 'operation', value: ['create', 'updateMultiple'] },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate an Airtable records JSON array based on the user's description.
The array should contain objects with a "fields" property containing the record data.
Current records: {context}
Format:
[
{
"fields": {
"Field Name": "value",
"Another Field": "another value"
}
}
]
For updates, include the record ID:
[
{
"id": "recXXXXXXXXXXXXXX",
"fields": {
"Field Name": "updated value"
}
}
]
Examples:
- "add a task called 'Review PR' with status 'Pending'" ->
[{"fields": {"Name": "Review PR", "Status": "Pending"}}]
- "create 3 contacts: John, Jane, Bob" ->
[{"fields": {"Name": "John"}}, {"fields": {"Name": "Jane"}}, {"fields": {"Name": "Bob"}}]
Return ONLY the valid JSON array - no explanations, no markdown.`,
placeholder: 'Describe the records to create or update...',
generationType: 'json-object',
},
},
{
id: 'fields',
@@ -95,6 +164,32 @@ export const AirtableBlock: BlockConfig<AirtableResponse> = {
placeholder: 'Fields to update: `{ "Field Name": "New Value" }`',
condition: { field: 'operation', value: 'update' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate an Airtable fields JSON object based on the user's description.
The object should contain field names as keys and their values.
Current fields: {context}
Format:
{
"Field Name": "value",
"Another Field": "another value",
"Number Field": 123,
"Checkbox Field": true
}
Examples:
- "set status to completed and priority to low" ->
{"Status": "Completed", "Priority": "Low"}
- "update the name to 'New Project' and set the due date" ->
{"Name": "New Project", "Due Date": "2024-12-31"}
Return ONLY the valid JSON object - no explanations, no markdown.`,
placeholder: 'Describe the fields to update...',
generationType: 'json-object',
},
},
...getTrigger('airtable_webhook').subBlocks,
],

View File

@@ -46,6 +46,32 @@ export const ApifyBlock: BlockConfig<RunActorResult> = {
language: 'json',
placeholder: '{\n "startUrl": "https://example.com",\n "maxPages": 10\n}',
required: false,
wandConfig: {
enabled: true,
prompt: `Generate a JSON configuration object for an Apify actor based on the user's description.
Apify actors typically accept configuration for web scraping, automation, or data processing tasks.
Current input: {context}
Common Apify actor input patterns:
- Web scrapers: startUrls, maxPages, proxyConfiguration
- Crawlers: startUrls, maxRequestsPerCrawl, maxConcurrency
- Data processors: inputData, outputFormat, filters
Examples:
- "scrape 5 pages starting from example.com" ->
{"startUrls": [{"url": "https://example.com"}], "maxPages": 5}
- "crawl the site with proxy and limit to 100 requests" ->
{"startUrls": [{"url": "https://example.com"}], "maxRequestsPerCrawl": 100, "proxyConfiguration": {"useApifyProxy": true}}
- "extract product data with custom selectors" ->
{"startUrls": [{"url": "https://shop.example.com"}], "selectors": {"title": "h1.product-title", "price": ".price"}}
Return ONLY the valid JSON object - no explanations, no markdown.`,
placeholder: 'Describe the actor configuration you need...',
generationType: 'json-object',
},
},
{
id: 'timeout',

View File

@@ -421,6 +421,19 @@ export const ApolloBlock: BlockConfig<ApolloResponse> = {
field: 'operation',
value: ['opportunity_create', 'opportunity_update'],
},
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "end of this quarter" -> Calculate the last day of the current quarter in YYYY-MM-DD format
- "next month" -> Calculate 30 days from now in YYYY-MM-DD format
- "in 2 weeks" -> Calculate 14 days from now in YYYY-MM-DD format
- "end of year" -> December 31st of the current year in YYYY-MM-DD format
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "end of quarter", "in 2 weeks")...',
generationType: 'timestamp',
},
},
{
id: 'description',
@@ -517,6 +530,20 @@ export const ApolloBlock: BlockConfig<ApolloResponse> = {
type: 'short-input',
placeholder: 'ISO date (e.g., 2024-12-31T23:59:59Z)',
condition: { field: 'operation', value: 'task_create' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "tomorrow at 5pm" -> Calculate tomorrow's date at 17:00:00Z
- "end of day" -> Today's date at 23:59:59Z
- "next week" -> 7 days from now at 17:00:00Z
- "in 3 days" -> 3 days from now at 17:00:00Z
Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the due date (e.g., "tomorrow at 5pm", "end of week")...',
generationType: 'timestamp',
},
},
{
id: 'completed',

View File

@@ -147,6 +147,19 @@ export const AsanaBlock: BlockConfig<AsanaResponse> = {
field: 'operation',
value: ['create_task', 'update_task'],
},
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "tomorrow" -> Calculate tomorrow's date in YYYY-MM-DD format
- "next Friday" -> Calculate the next Friday's date in YYYY-MM-DD format
- "in 3 days" -> Calculate 3 days from now in YYYY-MM-DD format
- "end of week" -> Calculate the upcoming Friday or Sunday in YYYY-MM-DD format
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the due date (e.g., "tomorrow", "next Friday", "in 3 days")...',
generationType: 'timestamp',
},
},
{

View File

@@ -92,6 +92,20 @@ export const CalendlyBlock: BlockConfig<ToolResponse> = {
type: 'short-input',
placeholder: 'ISO 8601 format (e.g., 2024-01-01T00:00:00Z)',
condition: { field: 'operation', value: 'calendly_list_scheduled_events' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "today" -> Today's date at 00:00:00Z
- "beginning of this week" -> Monday of the current week at 00:00:00Z
- "start of month" -> First day of current month at 00:00:00Z
- "last week" -> 7 days ago at 00:00:00Z
Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start time (e.g., "today", "start of month")...',
generationType: 'timestamp',
},
},
{
id: 'max_start_time',
@@ -99,6 +113,20 @@ export const CalendlyBlock: BlockConfig<ToolResponse> = {
type: 'short-input',
placeholder: 'ISO 8601 format (e.g., 2024-12-31T23:59:59Z)',
condition: { field: 'operation', value: 'calendly_list_scheduled_events' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "end of today" -> Today's date at 23:59:59Z
- "end of this week" -> Sunday of the current week at 23:59:59Z
- "end of month" -> Last day of current month at 23:59:59Z
- "next week" -> 7 days from now at 23:59:59Z
Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end time (e.g., "end of week", "end of month")...',
generationType: 'timestamp',
},
},
{
id: 'status',

View File

@@ -30,6 +30,14 @@ export const ClayBlock: BlockConfig<ClayPopulateResponse> = {
JSON: Best for populating multiple columns.
Plain Text: Best for populating a table in free-form style.
`,
wandConfig: {
enabled: true,
prompt:
'Generate JSON data structure or plain text content based on the user description. For JSON, create a well-structured object or array with appropriate keys and sample values. Return ONLY the data content - no explanations, no extra formatting.',
placeholder:
'Describe the data structure you need (e.g., "array of contacts with name, email, and company")...',
generationType: 'json-object',
},
},
{
id: 'authToken',

View File

@@ -54,6 +54,19 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
]`,
condition: { field: 'operation', value: 'datadog_submit_metrics' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of Datadog metrics based on the user's description.
Each metric object should have:
- "metric": The metric name (e.g., "custom.app.response_time")
- "type": The metric type ("gauge", "count", or "rate")
- "points": Array of {timestamp, value} objects
- "tags": Array of tag strings (e.g., "env:production")
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the metrics you want to submit...',
generationType: 'json-object',
},
},
// ========================
@@ -66,6 +79,18 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'avg:system.cpu.user{*}',
condition: { field: 'operation', value: 'datadog_query_timeseries' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a Datadog metrics query based on the user's description.
The query format is: <aggregation>:<metric_name>{<tag_filters>}
Examples:
- "avg:system.cpu.user{*}" - Average CPU usage across all hosts
- "sum:app.requests{env:production} by {service}" - Sum of requests grouped by service
- "max:system.mem.used{host:webserver-1}" - Max memory on specific host
Return ONLY the query string - no explanations, no quotes around the entire query.`,
placeholder: 'Describe what metrics you want to query...',
},
},
{
id: 'from',
@@ -74,6 +99,19 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'e.g., 1701360000',
condition: { field: 'operation', value: 'datadog_query_timeseries' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp (seconds since epoch) based on the user's description.
The timestamp should be a number representing seconds since January 1, 1970 UTC.
Examples:
- "yesterday" -> Calculate yesterday's date at 00:00:00 UTC as Unix timestamp
- "last week" -> Calculate 7 days ago at 00:00:00 UTC as Unix timestamp
- "1 hour ago" -> Calculate current time minus 3600 seconds
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start time (e.g., "1 hour ago", "yesterday")...',
generationType: 'timestamp',
},
},
{
id: 'to',
@@ -82,6 +120,19 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'e.g., 1701446400',
condition: { field: 'operation', value: 'datadog_query_timeseries' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp (seconds since epoch) based on the user's description.
The timestamp should be a number representing seconds since January 1, 1970 UTC.
Examples:
- "now" -> Calculate current time as Unix timestamp
- "end of today" -> Calculate today at 23:59:59 UTC as Unix timestamp
- "tomorrow" -> Calculate tomorrow's date at 00:00:00 UTC as Unix timestamp
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end time (e.g., "now", "end of today")...',
generationType: 'timestamp',
},
},
// ========================
@@ -94,6 +145,15 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'Deployment completed',
condition: { field: 'operation', value: 'datadog_create_event' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a concise, descriptive event title for Datadog based on the user's description.
The title should be short (under 100 characters), clear, and action-oriented.
Examples: "Deployment completed", "High CPU usage detected", "Service restart initiated"
Return ONLY the title text - no quotes, no extra formatting.`,
placeholder: 'Describe the event you want to create...',
},
},
{
id: 'text',
@@ -102,6 +162,15 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'Describe the event...',
condition: { field: 'operation', value: 'datadog_create_event' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate descriptive event text for a Datadog event based on the user's description.
Include relevant details like what happened, when, and any important context.
Can use Markdown formatting for readability.
Return the event description text directly - no extra formatting needed.`,
placeholder: 'Describe the event details...',
},
},
{
id: 'alertType',
@@ -145,6 +214,15 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'High CPU Usage Alert',
condition: { field: 'operation', value: 'datadog_create_monitor' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a clear, descriptive monitor name for Datadog based on the user's description.
The name should be concise but descriptive, indicating what is being monitored.
Examples: "High CPU Usage Alert", "Database Connection Pool Low", "API Error Rate Spike"
Return ONLY the monitor name - no quotes, no extra formatting.`,
placeholder: 'Describe what the monitor should track...',
},
},
{
id: 'type',
@@ -170,6 +248,18 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'avg(last_5m):avg:system.cpu.idle{*} < 20',
condition: { field: 'operation', value: 'datadog_create_monitor' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a Datadog monitor query based on the user's description.
Monitor query format: <aggregation>(<time_window>):<metric_query> <comparator> <threshold>
Examples:
- "avg(last_5m):avg:system.cpu.idle{*} < 20" - Alert when average CPU idle is below 20%
- "sum(last_1h):sum:app.errors{env:production} > 100" - Alert when errors exceed 100 in an hour
- "max(last_15m):max:system.disk.used{*} by {host} > 90" - Alert when disk usage exceeds 90%
Return ONLY the monitor query string - no explanations.`,
placeholder: 'Describe what condition should trigger the alert...',
},
},
{
id: 'message',
@@ -177,6 +267,17 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
type: 'long-input',
placeholder: 'Alert! CPU usage is high. @slack-alerts',
condition: { field: 'operation', value: 'datadog_create_monitor' },
wandConfig: {
enabled: true,
prompt: `Generate a Datadog monitor notification message based on the user's description.
The message should include:
- A clear description of what triggered the alert
- Relevant template variables like {{host.name}}, {{value}}
- Optional: notification handles like @slack-channel or @pagerduty
Return the notification message text directly.`,
placeholder: 'Describe what the notification should say...',
},
},
{
id: 'monitorTags',
@@ -198,6 +299,20 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
type: 'code',
placeholder: '{"notify_no_data": true, "thresholds": {"critical": 90}}',
condition: { field: 'operation', value: 'datadog_create_monitor' },
wandConfig: {
enabled: true,
prompt: `Generate Datadog monitor options JSON based on the user's description.
Common options include:
- "notify_no_data": boolean - Notify when data stops arriving
- "thresholds": {"critical": number, "warning": number} - Alert thresholds
- "renotify_interval": number - Minutes between re-notifications
- "timeout_h": number - Hours before auto-resolving
- "include_tags": boolean - Include trigger tags in notifications
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the monitor options you need...',
generationType: 'json-object',
},
},
// ========================
@@ -254,6 +369,19 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
type: 'short-input',
placeholder: 'Leave empty for indefinite',
condition: { field: 'operation', value: 'datadog_mute_monitor' },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp (seconds since epoch) based on the user's description.
The timestamp should be a number representing seconds since January 1, 1970 UTC.
Examples:
- "in 1 hour" -> Calculate current time plus 3600 seconds
- "tomorrow morning" -> Calculate tomorrow at 09:00:00 UTC as Unix timestamp
- "end of day" -> Calculate today at 23:59:59 UTC as Unix timestamp
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe when mute should end (e.g., "in 1 hour", "tomorrow")...',
generationType: 'timestamp',
},
},
// ========================
@@ -266,6 +394,18 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'service:web-app status:error',
condition: { field: 'operation', value: 'datadog_query_logs' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a Datadog log search query based on the user's description.
The query uses facet syntax: facet:value
Examples:
- "service:web-app status:error" - Errors from web-app service
- "source:nginx @http.status_code:>=500" - Nginx 5xx errors
- "host:prod-* @duration:>1000" - Slow requests on prod hosts
Return ONLY the search query string - no explanations.`,
placeholder: 'Describe what logs you want to find...',
},
},
{
id: 'logFrom',
@@ -274,6 +414,20 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'now-1h',
condition: { field: 'operation', value: 'datadog_query_logs' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a Datadog relative time string based on the user's description.
The format uses relative time syntax like: now-1h, now-15m, now-1d, now-1w
Examples:
- "1 hour ago" -> now-1h
- "15 minutes ago" -> now-15m
- "yesterday" -> now-1d
- "last week" -> now-7d
Return ONLY the relative time string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start time (e.g., "1 hour ago", "yesterday")...',
generationType: 'timestamp',
},
},
{
id: 'logTo',
@@ -282,6 +436,19 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
placeholder: 'now',
condition: { field: 'operation', value: 'datadog_query_logs' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a Datadog relative time string based on the user's description.
The format uses relative time syntax like: now, now-1h, now-15m
Examples:
- "now" or "current time" -> now
- "5 minutes ago" -> now-5m
- "1 hour ago" -> now-1h
Return ONLY the relative time string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end time (e.g., "now", "5 minutes ago")...',
generationType: 'timestamp',
},
},
{
id: 'logLimit',
@@ -308,6 +475,20 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
]`,
condition: { field: 'operation', value: 'datadog_send_logs' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of Datadog log entries based on the user's description.
Each log object should have:
- "message": The log message text
- "service": The service name
- "ddsource": The log source (e.g., "custom", "nodejs", "python")
- "ddtags": Comma-separated tags (e.g., "env:production,version:1.0")
- Optional: "hostname", "status" (info/warn/error)
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the logs you want to send...',
generationType: 'json-object',
},
},
// ========================
@@ -327,6 +508,15 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
type: 'long-input',
placeholder: 'Scheduled maintenance',
condition: { field: 'operation', value: 'datadog_create_downtime' },
wandConfig: {
enabled: true,
prompt: `Generate a downtime message for Datadog based on the user's description.
The message should explain why monitoring is being muted.
Examples: "Scheduled maintenance window", "Deploying new version", "Infrastructure upgrade in progress"
Return the message text directly - no extra formatting.`,
placeholder: 'Describe the reason for the downtime...',
},
},
{
id: 'downtimeStart',
@@ -334,6 +524,19 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
type: 'short-input',
placeholder: 'Leave empty for now',
condition: { field: 'operation', value: 'datadog_create_downtime' },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp (seconds since epoch) based on the user's description.
The timestamp should be a number representing seconds since January 1, 1970 UTC.
Examples:
- "now" -> Calculate current time as Unix timestamp
- "in 30 minutes" -> Calculate current time plus 1800 seconds
- "tonight at 10pm" -> Calculate today at 22:00:00 UTC as Unix timestamp
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe when downtime should start (e.g., "now", "in 30 minutes")...',
generationType: 'timestamp',
},
},
{
id: 'downtimeEnd',
@@ -341,6 +544,19 @@ export const DatadogBlock: BlockConfig<DatadogResponse> = {
type: 'short-input',
placeholder: 'e.g., 1701450000',
condition: { field: 'operation', value: 'datadog_create_downtime' },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp (seconds since epoch) based on the user's description.
The timestamp should be a number representing seconds since January 1, 1970 UTC.
Examples:
- "in 2 hours" -> Calculate current time plus 7200 seconds
- "tomorrow morning" -> Calculate tomorrow at 09:00:00 UTC as Unix timestamp
- "end of maintenance window" -> Interpret based on context
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe when downtime should end (e.g., "in 2 hours", "tomorrow")...',
generationType: 'timestamp',
},
},
{
id: 'downtimeMonitorId',

View File

@@ -235,6 +235,19 @@ export const DropboxBlock: BlockConfig<DropboxResponse> = {
type: 'short-input',
placeholder: '2025-12-31T23:59:59Z',
condition: { field: 'operation', value: 'dropbox_create_shared_link' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "in 1 week" -> Calculate 7 days from now at 23:59:59Z
- "end of month" -> Calculate last day of current month at 23:59:59Z
- "next year" -> Calculate January 1st of next year at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe when link should expire (e.g., "in 1 week", "end of month")...',
generationType: 'timestamp',
},
},
// Search operation inputs
{

View File

@@ -65,6 +65,18 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
placeholder: '{\n "pk": "user#123"\n}',
condition: { field: 'operation', value: 'get' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB primary key JSON object based on the user's description.
The key should include partition key and optionally sort key.
Examples:
- {"pk": "user#123"} - Simple partition key
- {"pk": "order#456", "sk": "2024-01-15"} - Partition key with sort key
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the item key...',
generationType: 'json-object',
},
},
{
id: 'key',
@@ -73,6 +85,18 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
placeholder: '{\n "pk": "user#123"\n}',
condition: { field: 'operation', value: 'update' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB primary key JSON object based on the user's description.
The key should include partition key and optionally sort key.
Examples:
- {"pk": "user#123"} - Simple partition key
- {"pk": "order#456", "sk": "2024-01-15"} - Partition key with sort key
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the item key...',
generationType: 'json-object',
},
},
{
id: 'key',
@@ -81,6 +105,18 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
placeholder: '{\n "pk": "user#123"\n}',
condition: { field: 'operation', value: 'delete' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB primary key JSON object based on the user's description.
The key should include partition key and optionally sort key.
Examples:
- {"pk": "user#123"} - Simple partition key
- {"pk": "order#456", "sk": "2024-01-15"} - Partition key with sort key
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the item key...',
generationType: 'json-object',
},
},
// Consistent read for get
{
@@ -103,6 +139,16 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
'{\n "pk": "user#123",\n "name": "John Doe",\n "email": "john@example.com"\n}',
condition: { field: 'operation', value: 'put' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB item JSON object based on the user's description.
The item must include the primary key and any additional attributes.
Use appropriate data types for values (strings, numbers, booleans, lists, maps).
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the item you want to store...',
generationType: 'json-object',
},
},
// Key condition expression for query
{
@@ -112,6 +158,19 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
placeholder: 'pk = :pk',
condition: { field: 'operation', value: 'query' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB key condition expression based on the user's description.
The expression must reference the partition key and optionally the sort key.
Use :placeholders for values and #names for reserved words.
Examples:
- "pk = :pk" - Match partition key
- "pk = :pk AND sk BETWEEN :start AND :end" - Range query on sort key
- "pk = :pk AND begins_with(sk, :prefix)" - Prefix match on sort key
Return ONLY the expression - no explanations.`,
placeholder: 'Describe the key condition...',
},
},
// Update expression for update operation
{
@@ -121,6 +180,19 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
placeholder: 'SET #name = :name',
condition: { field: 'operation', value: 'update' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB update expression based on the user's description.
Use SET, REMOVE, ADD, or DELETE clauses.
Use :placeholders for values and #names for attribute names.
Examples:
- "SET #name = :name, #age = :age" - Update multiple attributes
- "SET #count = #count + :increment" - Increment a counter
- "REMOVE #oldAttribute" - Remove an attribute
Return ONLY the expression - no explanations.`,
placeholder: 'Describe what updates to make...',
},
},
// Filter expression for query and scan
{
@@ -129,6 +201,19 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'short-input',
placeholder: 'attribute_exists(email)',
condition: { field: 'operation', value: 'query' },
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB filter expression based on the user's description.
Filter expressions are applied after the query but before results are returned.
Use comparison operators, functions like attribute_exists(), contains(), begins_with().
Examples:
- "attribute_exists(email)" - Items with email attribute
- "#status = :active AND #age > :minAge" - Multiple conditions
- "contains(#tags, :tag)" - Contains a value in a list
Return ONLY the expression - no explanations.`,
placeholder: 'Describe how to filter results...',
},
},
{
id: 'filterExpression',
@@ -136,6 +221,19 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'short-input',
placeholder: 'attribute_exists(email)',
condition: { field: 'operation', value: 'scan' },
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB filter expression based on the user's description.
Filter expressions are applied after the scan but before results are returned.
Use comparison operators, functions like attribute_exists(), contains(), begins_with().
Examples:
- "attribute_exists(email)" - Items with email attribute
- "#status = :active AND #age > :minAge" - Multiple conditions
- "contains(#tags, :tag)" - Contains a value in a list
Return ONLY the expression - no explanations.`,
placeholder: 'Describe how to filter results...',
},
},
// Projection expression for scan
{
@@ -152,6 +250,17 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'code',
placeholder: '{\n "#name": "name"\n}',
condition: { field: 'operation', value: 'query' },
wandConfig: {
enabled: true,
prompt: `Generate DynamoDB expression attribute names JSON based on the user's description.
Map placeholder names (starting with #) to actual attribute names.
Required when using reserved words or for clarity.
Example: {"#name": "name", "#status": "status"}
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the attribute name mappings...',
generationType: 'json-object',
},
},
{
id: 'expressionAttributeNames',
@@ -159,6 +268,17 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'code',
placeholder: '{\n "#name": "name"\n}',
condition: { field: 'operation', value: 'scan' },
wandConfig: {
enabled: true,
prompt: `Generate DynamoDB expression attribute names JSON based on the user's description.
Map placeholder names (starting with #) to actual attribute names.
Required when using reserved words or for clarity.
Example: {"#name": "name", "#status": "status"}
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the attribute name mappings...',
generationType: 'json-object',
},
},
{
id: 'expressionAttributeNames',
@@ -166,6 +286,17 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'code',
placeholder: '{\n "#name": "name"\n}',
condition: { field: 'operation', value: 'update' },
wandConfig: {
enabled: true,
prompt: `Generate DynamoDB expression attribute names JSON based on the user's description.
Map placeholder names (starting with #) to actual attribute names.
Required when using reserved words or for clarity.
Example: {"#name": "name", "#status": "status"}
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the attribute name mappings...',
generationType: 'json-object',
},
},
// Expression attribute values for query, scan, update
{
@@ -174,6 +305,16 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'code',
placeholder: '{\n ":pk": "user#123",\n ":name": "Jane"\n}',
condition: { field: 'operation', value: 'query' },
wandConfig: {
enabled: true,
prompt: `Generate DynamoDB expression attribute values JSON based on the user's description.
Map placeholder values (starting with :) to actual values.
Example: {":pk": "user#123", ":status": "active", ":minAge": 18}
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the attribute values...',
generationType: 'json-object',
},
},
{
id: 'expressionAttributeValues',
@@ -181,6 +322,16 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'code',
placeholder: '{\n ":status": "active"\n}',
condition: { field: 'operation', value: 'scan' },
wandConfig: {
enabled: true,
prompt: `Generate DynamoDB expression attribute values JSON based on the user's description.
Map placeholder values (starting with :) to actual values.
Example: {":status": "active", ":minAge": 18}
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the attribute values...',
generationType: 'json-object',
},
},
{
id: 'expressionAttributeValues',
@@ -188,6 +339,16 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'code',
placeholder: '{\n ":name": "Jane Doe"\n}',
condition: { field: 'operation', value: 'update' },
wandConfig: {
enabled: true,
prompt: `Generate DynamoDB expression attribute values JSON based on the user's description.
Map placeholder values (starting with :) to actual values.
Example: {":name": "Jane Doe", ":count": 1}
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the attribute values...',
generationType: 'json-object',
},
},
// Index name for query
{
@@ -219,6 +380,18 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'short-input',
placeholder: 'attribute_exists(pk)',
condition: { field: 'operation', value: 'update' },
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB condition expression based on the user's description.
Condition expressions prevent the operation if the condition is not met.
Examples:
- "attribute_exists(pk)" - Item must exist
- "attribute_not_exists(pk)" - Item must not exist (for inserts)
- "#version = :expectedVersion" - Optimistic locking
Return ONLY the expression - no explanations.`,
placeholder: 'Describe the condition that must be true...',
},
},
{
id: 'conditionExpression',
@@ -226,6 +399,17 @@ export const DynamoDBBlock: BlockConfig<DynamoDBResponse> = {
type: 'short-input',
placeholder: 'attribute_exists(pk)',
condition: { field: 'operation', value: 'delete' },
wandConfig: {
enabled: true,
prompt: `Generate a DynamoDB condition expression based on the user's description.
Condition expressions prevent the operation if the condition is not met.
Examples:
- "attribute_exists(pk)" - Item must exist
- "#status = :deletable" - Only delete if status matches
Return ONLY the expression - no explanations.`,
placeholder: 'Describe the condition that must be true...',
},
},
],
tools: {

View File

@@ -174,6 +174,16 @@ export const ElasticsearchBlock: BlockConfig<ElasticsearchResponse> = {
placeholder: '{ "field": "value", "another_field": 123 }',
required: true,
condition: { field: 'operation', value: 'elasticsearch_index_document' },
wandConfig: {
enabled: true,
prompt: `Generate an Elasticsearch document JSON object based on the user's description.
The document should contain the fields and values to be indexed.
Use appropriate data types (strings, numbers, booleans, arrays, nested objects).
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the document you want to index...',
generationType: 'json-object',
},
},
// Document body - for update (partial)
@@ -184,6 +194,15 @@ export const ElasticsearchBlock: BlockConfig<ElasticsearchResponse> = {
placeholder: '{ "field_to_update": "new_value" }',
required: true,
condition: { field: 'operation', value: 'elasticsearch_update_document' },
wandConfig: {
enabled: true,
prompt: `Generate an Elasticsearch partial document JSON for updating based on the user's description.
Only include the fields that need to be updated - other fields will remain unchanged.
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the fields you want to update...',
generationType: 'json-object',
},
},
// Search query
@@ -193,6 +212,19 @@ export const ElasticsearchBlock: BlockConfig<ElasticsearchResponse> = {
type: 'code',
placeholder: '{ "match": { "field": "search term" } }',
condition: { field: 'operation', value: 'elasticsearch_search' },
wandConfig: {
enabled: true,
prompt: `Generate an Elasticsearch query DSL JSON based on the user's description.
Common query types:
- {"match": {"field": "text"}} - Full-text search
- {"term": {"field": "exact_value"}} - Exact match
- {"range": {"field": {"gte": 10, "lte": 100}}} - Range query
- {"bool": {"must": [...], "filter": [...]}} - Boolean combinations
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe what you want to search for...',
generationType: 'json-object',
},
},
// Count query
@@ -202,6 +234,18 @@ export const ElasticsearchBlock: BlockConfig<ElasticsearchResponse> = {
type: 'code',
placeholder: '{ "match": { "field": "value" } }',
condition: { field: 'operation', value: 'elasticsearch_count' },
wandConfig: {
enabled: true,
prompt: `Generate an Elasticsearch query DSL JSON for counting documents based on the user's description.
Common query types:
- {"match": {"field": "text"}} - Full-text search
- {"term": {"field": "exact_value"}} - Exact match
- {"range": {"field": {"gte": 10}}} - Range query
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe which documents to count...',
generationType: 'json-object',
},
},
// Search size
@@ -229,6 +273,18 @@ export const ElasticsearchBlock: BlockConfig<ElasticsearchResponse> = {
type: 'code',
placeholder: '[{ "field": { "order": "asc" } }]',
condition: { field: 'operation', value: 'elasticsearch_search' },
wandConfig: {
enabled: true,
prompt: `Generate an Elasticsearch sort specification JSON array based on the user's description.
Format: [{"field_name": {"order": "asc"|"desc"}}]
Examples:
- [{"timestamp": {"order": "desc"}}] - Sort by timestamp descending
- [{"_score": {"order": "desc"}}, {"date": {"order": "asc"}}] - Multi-field sort
Return ONLY valid JSON array - no explanations, no markdown code blocks.`,
placeholder: 'Describe how to sort the results...',
generationType: 'json-object',
},
},
// Source includes
@@ -264,6 +320,20 @@ export const ElasticsearchBlock: BlockConfig<ElasticsearchResponse> = {
'{ "index": { "_index": "my-index", "_id": "1" } }\n{ "field": "value" }\n{ "delete": { "_index": "my-index", "_id": "2" } }',
required: true,
condition: { field: 'operation', value: 'elasticsearch_bulk' },
wandConfig: {
enabled: true,
prompt: `Generate Elasticsearch bulk operations in NDJSON format based on the user's description.
Each operation consists of an action line followed by an optional document line.
Actions: index, create, update, delete
Format:
{"index": {"_index": "my-index", "_id": "1"}}
{"field": "value"}
{"delete": {"_index": "my-index", "_id": "2"}}
Return ONLY the NDJSON content - no explanations, no markdown code blocks.`,
placeholder: 'Describe the bulk operations you want to perform...',
generationType: 'json-object',
},
},
// Index settings
@@ -273,6 +343,19 @@ export const ElasticsearchBlock: BlockConfig<ElasticsearchResponse> = {
type: 'code',
placeholder: '{ "number_of_shards": 1, "number_of_replicas": 1 }',
condition: { field: 'operation', value: 'elasticsearch_create_index' },
wandConfig: {
enabled: true,
prompt: `Generate Elasticsearch index settings JSON based on the user's description.
Common settings:
- "number_of_shards": Number of primary shards
- "number_of_replicas": Number of replica shards
- "refresh_interval": How often to refresh the index
- "analysis": Custom analyzers, tokenizers, filters
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the index settings you need...',
generationType: 'json-object',
},
},
// Index mappings
@@ -282,6 +365,21 @@ export const ElasticsearchBlock: BlockConfig<ElasticsearchResponse> = {
type: 'code',
placeholder: '{ "properties": { "field": { "type": "text" } } }',
condition: { field: 'operation', value: 'elasticsearch_create_index' },
wandConfig: {
enabled: true,
prompt: `Generate Elasticsearch index mappings JSON based on the user's description.
Define field types and properties:
- "text": Full-text searchable
- "keyword": Exact match, sorting, aggregations
- "integer", "long", "float", "double": Numeric types
- "date": Date/time values
- "boolean": True/false values
- "object", "nested": Complex types
Return ONLY valid JSON - no explanations, no markdown code blocks.`,
placeholder: 'Describe the fields and their types...',
generationType: 'json-object',
},
},
// Refresh option

View File

@@ -0,0 +1,589 @@
import { FirefliesIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import { AuthMode } from '@/blocks/types'
import type { FirefliesResponse } from '@/tools/fireflies/types'
import { getTrigger } from '@/triggers'
export const FirefliesBlock: BlockConfig<FirefliesResponse> = {
type: 'fireflies',
name: 'Fireflies',
description: 'Interact with Fireflies.ai meeting transcripts and recordings',
authMode: AuthMode.ApiKey,
triggerAllowed: true,
longDescription:
'Integrate Fireflies.ai into the workflow. Manage meeting transcripts, add bot to live meetings, create soundbites, and more. Can also trigger workflows when transcriptions complete.',
docsLink: 'https://docs.fireflies.ai',
category: 'tools',
icon: FirefliesIcon,
bgColor: '#100730',
subBlocks: [
{
id: 'operation',
title: 'Operation',
type: 'dropdown',
options: [
{ label: 'List Transcripts', id: 'fireflies_list_transcripts' },
{ label: 'Get Transcript', id: 'fireflies_get_transcript' },
{ label: 'Get User', id: 'fireflies_get_user' },
{ label: 'List Users', id: 'fireflies_list_users' },
{ label: 'Upload Audio', id: 'fireflies_upload_audio' },
{ label: 'Delete Transcript', id: 'fireflies_delete_transcript' },
{ label: 'Add Bot to Live Meeting', id: 'fireflies_add_to_live_meeting' },
{ label: 'Create Bite', id: 'fireflies_create_bite' },
{ label: 'List Bites', id: 'fireflies_list_bites' },
{ label: 'List Contacts', id: 'fireflies_list_contacts' },
],
value: () => 'fireflies_list_transcripts',
},
{
id: 'apiKey',
title: 'API Key',
type: 'short-input',
placeholder: 'Enter your Fireflies API key',
password: true,
required: true,
},
// Transcript ID (for get/delete/create_bite/list_bites)
{
id: 'transcriptId',
title: 'Transcript ID',
type: 'short-input',
placeholder: 'Enter transcript ID',
required: {
field: 'operation',
value: ['fireflies_get_transcript', 'fireflies_delete_transcript', 'fireflies_create_bite'],
},
condition: {
field: 'operation',
value: [
'fireflies_get_transcript',
'fireflies_delete_transcript',
'fireflies_create_bite',
'fireflies_list_bites',
],
},
},
// User ID (optional for get user)
{
id: 'userId',
title: 'User ID',
type: 'short-input',
placeholder: 'Leave empty for current user',
required: false,
condition: {
field: 'operation',
value: 'fireflies_get_user',
},
},
// List Transcripts filters
{
id: 'keyword',
title: 'Keyword',
type: 'short-input',
placeholder: 'Search in title or transcript',
required: false,
condition: {
field: 'operation',
value: 'fireflies_list_transcripts',
},
},
{
id: 'fromDate',
title: 'From Date',
type: 'short-input',
placeholder: 'e.g., 2024-01-01T00:00:00Z',
required: false,
condition: {
field: 'operation',
value: 'fireflies_list_transcripts',
},
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "yesterday" -> Calculate yesterday's date at 00:00:00Z
- "last week" -> Calculate 7 days ago at 00:00:00Z
- "beginning of this month" -> First day of current month at 00:00:00Z
- "January 1st 2024" -> 2024-01-01T00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "last week", "beginning of this month")...',
generationType: 'timestamp',
},
},
{
id: 'toDate',
title: 'To Date',
type: 'short-input',
placeholder: 'e.g., 2024-12-31T23:59:59Z',
required: false,
condition: {
field: 'operation',
value: 'fireflies_list_transcripts',
},
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "today" -> Calculate today's date at 23:59:59Z
- "end of this week" -> Calculate end of week at 23:59:59Z
- "end of this month" -> Last day of current month at 23:59:59Z
- "December 31st 2024" -> 2024-12-31T23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "today", "end of this month")...',
generationType: 'timestamp',
},
},
{
id: 'hostEmail',
title: 'Host Email',
type: 'short-input',
placeholder: 'Filter by host email',
required: false,
condition: {
field: 'operation',
value: 'fireflies_list_transcripts',
},
},
{
id: 'participants',
title: 'Participants',
type: 'short-input',
placeholder: 'Comma-separated participant emails',
required: false,
condition: {
field: 'operation',
value: 'fireflies_list_transcripts',
},
},
{
id: 'limit',
title: 'Limit',
type: 'short-input',
placeholder: 'Max 50 (default: 50)',
required: false,
condition: {
field: 'operation',
value: ['fireflies_list_transcripts', 'fireflies_list_bites'],
},
},
// Upload Audio fields - File upload (basic mode)
{
id: 'audioFile',
title: 'Audio/Video File',
type: 'file-upload',
canonicalParamId: 'audioFile',
placeholder: 'Upload an audio or video file',
mode: 'basic',
multiple: false,
required: false,
acceptedTypes: '.mp3,.m4a,.wav,.webm,.ogg,.flac,.aac,.opus,.mp4,.mov,.avi,.mkv',
condition: {
field: 'operation',
value: 'fireflies_upload_audio',
},
},
// Upload Audio fields - File reference (advanced mode)
{
id: 'audioFileReference',
title: 'Audio/Video File Reference',
type: 'short-input',
canonicalParamId: 'audioFile',
placeholder: 'Reference audio/video from previous blocks',
mode: 'advanced',
required: false,
condition: {
field: 'operation',
value: 'fireflies_upload_audio',
},
},
// Upload Audio fields - URL input
{
id: 'audioUrl',
title: 'Audio/Video URL',
type: 'short-input',
placeholder: 'Or enter publicly accessible audio/video URL',
description: 'Public HTTPS URL to audio file (MP3, MP4, WAV, M4A, OGG)',
required: false,
condition: {
field: 'operation',
value: 'fireflies_upload_audio',
},
},
{
id: 'title',
title: 'Title',
type: 'short-input',
placeholder: 'Meeting title',
required: false,
condition: {
field: 'operation',
value: ['fireflies_upload_audio', 'fireflies_add_to_live_meeting'],
},
wandConfig: {
enabled: true,
prompt: `Generate a clear, professional meeting title based on the user's description.
The title should be concise (3-8 words) and descriptive.
Examples:
- "weekly sync with engineering" -> "Weekly Engineering Team Sync"
- "discussing q1 roadmap" -> "Q1 Roadmap Planning Discussion"
- "interview with john for backend role" -> "Backend Engineer Interview - John"
- "customer demo for acme corp" -> "Product Demo - Acme Corp"
Return ONLY the title - no quotes, no explanations.`,
placeholder:
'Describe the meeting (e.g., "weekly team sync", "customer call with Acme")...',
},
},
{
id: 'language',
title: 'Language',
type: 'short-input',
placeholder: 'e.g., es, de, fr (default: English)',
required: false,
condition: {
field: 'operation',
value: ['fireflies_upload_audio', 'fireflies_add_to_live_meeting'],
},
wandConfig: {
enabled: true,
prompt: `Convert the language name to its ISO 639-1 two-letter code.
Examples:
- "Spanish" -> es
- "French" -> fr
- "German" -> de
- "Portuguese" -> pt
- "Japanese" -> ja
- "Chinese" -> zh
- "Korean" -> ko
- "Italian" -> it
- "Dutch" -> nl
- "Russian" -> ru
Return ONLY the two-letter language code - no explanations, no quotes.`,
placeholder: 'Enter language name (e.g., "Spanish", "French")...',
},
},
{
id: 'attendees',
title: 'Attendees',
type: 'long-input',
placeholder: '[{"displayName": "John", "email": "john@example.com"}]',
description: 'JSON array of attendees',
required: false,
condition: {
field: 'operation',
value: 'fireflies_upload_audio',
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of attendees based on the user's description.
Each attendee should have "displayName" and "email" fields.
Examples:
- "John Smith at john@example.com" -> [{"displayName": "John Smith", "email": "john@example.com"}]
- "Alice (alice@test.com) and Bob (bob@test.com)" -> [{"displayName": "Alice", "email": "alice@test.com"}, {"displayName": "Bob", "email": "bob@test.com"}]
- "Sarah Johnson, sarah.j@company.org" -> [{"displayName": "Sarah Johnson", "email": "sarah.j@company.org"}]
Return ONLY the valid JSON array - no explanations, no markdown code blocks.`,
placeholder:
'Describe attendees (e.g., "John Smith at john@example.com and Jane Doe at jane@test.com")...',
generationType: 'json-object',
},
},
{
id: 'clientReferenceId',
title: 'Reference ID',
type: 'short-input',
placeholder: 'Custom tracking ID',
required: false,
condition: {
field: 'operation',
value: 'fireflies_upload_audio',
},
},
// Add to Live Meeting fields
{
id: 'meetingLink',
title: 'Meeting Link',
type: 'short-input',
placeholder: 'https://zoom.us/j/... or https://meet.google.com/...',
description: 'URL for Zoom, Google Meet, or Microsoft Teams meeting',
required: true,
condition: {
field: 'operation',
value: 'fireflies_add_to_live_meeting',
},
},
{
id: 'meetingPassword',
title: 'Meeting Password',
type: 'short-input',
placeholder: 'Optional meeting password',
password: true,
required: false,
condition: {
field: 'operation',
value: 'fireflies_add_to_live_meeting',
},
},
{
id: 'duration',
title: 'Duration (minutes)',
type: 'short-input',
placeholder: '60 (15-120 minutes)',
required: false,
condition: {
field: 'operation',
value: 'fireflies_add_to_live_meeting',
},
},
// Create Bite fields
{
id: 'startTime',
title: 'Start Time (seconds)',
type: 'short-input',
placeholder: 'e.g., 30',
required: true,
condition: {
field: 'operation',
value: 'fireflies_create_bite',
},
},
{
id: 'endTime',
title: 'End Time (seconds)',
type: 'short-input',
placeholder: 'e.g., 90',
required: true,
condition: {
field: 'operation',
value: 'fireflies_create_bite',
},
},
{
id: 'biteName',
title: 'Bite Name',
type: 'short-input',
placeholder: 'Name for this highlight',
required: false,
condition: {
field: 'operation',
value: 'fireflies_create_bite',
},
},
{
id: 'biteSummary',
title: 'Summary',
type: 'long-input',
placeholder: 'Brief description of the highlight',
required: false,
condition: {
field: 'operation',
value: 'fireflies_create_bite',
},
wandConfig: {
enabled: true,
prompt: `Write a concise, professional summary for a meeting highlight/soundbite based on the user's description.
The summary should be 1-2 sentences that capture the key point of the highlighted segment.
Guidelines:
- Be clear and concise
- Focus on the main topic or decision discussed
- Use professional language
- Avoid filler words
Return ONLY the summary text - no quotes, no labels.`,
placeholder: 'Describe what this highlight is about...',
},
},
// Trigger SubBlocks
...getTrigger('fireflies_transcription_complete').subBlocks,
],
tools: {
access: [
'fireflies_list_transcripts',
'fireflies_get_transcript',
'fireflies_get_user',
'fireflies_list_users',
'fireflies_upload_audio',
'fireflies_delete_transcript',
'fireflies_add_to_live_meeting',
'fireflies_create_bite',
'fireflies_list_bites',
'fireflies_list_contacts',
],
config: {
tool: (params) => {
return params.operation || 'fireflies_list_transcripts'
},
params: (params) => {
const baseParams: Record<string, unknown> = {
apiKey: params.apiKey,
}
switch (params.operation) {
case 'fireflies_list_transcripts':
return {
...baseParams,
keyword: params.keyword || undefined,
fromDate: params.fromDate || undefined,
toDate: params.toDate || undefined,
hostEmail: params.hostEmail || undefined,
participants: params.participants || undefined,
limit: params.limit ? Number(params.limit) : undefined,
}
case 'fireflies_get_transcript':
if (!params.transcriptId?.trim()) {
throw new Error('Transcript ID is required.')
}
return {
...baseParams,
transcriptId: params.transcriptId.trim(),
}
case 'fireflies_get_user':
return {
...baseParams,
userId: params.userId?.trim() || undefined,
}
case 'fireflies_list_users':
return baseParams
case 'fireflies_upload_audio': {
// Support both file upload and URL
const audioUrl = params.audioUrl?.trim()
const audioFile = params.audioFile
const audioFileReference = params.audioFileReference
if (!audioUrl && !audioFile && !audioFileReference) {
throw new Error('Either audio file or audio URL is required.')
}
return {
...baseParams,
audioUrl: audioUrl || undefined,
audioFile: audioFile || undefined,
audioFileReference: audioFileReference || undefined,
title: params.title?.trim() || undefined,
language: params.language?.trim() || undefined,
attendees: params.attendees?.trim() || undefined,
clientReferenceId: params.clientReferenceId?.trim() || undefined,
}
}
case 'fireflies_delete_transcript':
if (!params.transcriptId?.trim()) {
throw new Error('Transcript ID is required.')
}
return {
...baseParams,
transcriptId: params.transcriptId.trim(),
}
case 'fireflies_add_to_live_meeting':
if (!params.meetingLink?.trim()) {
throw new Error('Meeting link is required.')
}
return {
...baseParams,
meetingLink: params.meetingLink.trim(),
title: params.title?.trim() || undefined,
meetingPassword: params.meetingPassword?.trim() || undefined,
duration: params.duration ? Number(params.duration) : undefined,
language: params.language?.trim() || undefined,
}
case 'fireflies_create_bite':
if (!params.transcriptId?.trim()) {
throw new Error('Transcript ID is required.')
}
if (!params.startTime || !params.endTime) {
throw new Error('Start time and end time are required.')
}
return {
...baseParams,
transcriptId: params.transcriptId.trim(),
startTime: Number(params.startTime),
endTime: Number(params.endTime),
name: params.biteName?.trim() || undefined,
summary: params.biteSummary?.trim() || undefined,
}
case 'fireflies_list_bites':
return {
...baseParams,
transcriptId: params.transcriptId?.trim() || undefined,
mine: true,
limit: params.limit ? Number(params.limit) : undefined,
}
case 'fireflies_list_contacts':
return baseParams
default:
return baseParams
}
},
},
},
inputs: {
operation: { type: 'string', description: 'Operation to perform' },
apiKey: { type: 'string', description: 'Fireflies API key' },
transcriptId: { type: 'string', description: 'Transcript identifier' },
userId: { type: 'string', description: 'User identifier' },
keyword: { type: 'string', description: 'Search keyword' },
fromDate: { type: 'string', description: 'Filter from date (ISO 8601)' },
toDate: { type: 'string', description: 'Filter to date (ISO 8601)' },
hostEmail: { type: 'string', description: 'Filter by host email' },
participants: { type: 'string', description: 'Filter by participants (comma-separated)' },
limit: { type: 'number', description: 'Maximum results to return' },
audioFile: { type: 'json', description: 'Audio/video file (UserFile)' },
audioFileReference: { type: 'json', description: 'Audio/video file reference' },
audioUrl: { type: 'string', description: 'Public URL to audio file' },
title: { type: 'string', description: 'Meeting title' },
language: { type: 'string', description: 'Language code for transcription' },
attendees: { type: 'string', description: 'JSON array of attendees' },
clientReferenceId: { type: 'string', description: 'Custom reference ID for tracking' },
meetingLink: { type: 'string', description: 'Meeting URL (Zoom, Meet, Teams)' },
meetingPassword: { type: 'string', description: 'Meeting password if required' },
duration: { type: 'number', description: 'Meeting duration in minutes (15-120)' },
startTime: { type: 'number', description: 'Bite start time in seconds' },
endTime: { type: 'number', description: 'Bite end time in seconds' },
biteName: { type: 'string', description: 'Name for the bite/highlight' },
biteSummary: { type: 'string', description: 'Summary for the bite' },
},
outputs: {
// List transcripts outputs
transcripts: { type: 'json', description: 'List of transcripts' },
count: { type: 'number', description: 'Number of transcripts returned' },
// Get transcript outputs
transcript: { type: 'json', description: 'Full transcript data with summary and analytics' },
// User outputs
user: { type: 'json', description: 'User information' },
users: { type: 'json', description: 'List of team users' },
// Bite outputs
bite: { type: 'json', description: 'Created bite details' },
bites: { type: 'json', description: 'List of bites/soundbites' },
// Contact outputs
contacts: { type: 'json', description: 'List of contacts from meetings' },
// Common outputs
success: { type: 'boolean', description: 'Operation success status' },
message: { type: 'string', description: 'Status message' },
// Trigger outputs
meetingId: { type: 'string', description: 'Meeting/transcript ID from webhook' },
eventType: { type: 'string', description: 'Webhook event type' },
clientReferenceId: { type: 'string', description: 'Custom reference ID if set during upload' },
},
triggers: {
enabled: true,
available: ['fireflies_transcription_complete'],
},
}

View File

@@ -143,6 +143,14 @@ export const GitLabBlock: BlockConfig<GitLabResponse> = {
field: 'operation',
value: ['gitlab_create_issue', 'gitlab_create_merge_request'],
},
wandConfig: {
enabled: true,
prompt: `Generate a clear, descriptive title for a GitLab issue or merge request based on the user's request.
The title should be concise but informative.
Return ONLY the title - no explanations, no extra text.`,
placeholder: 'Describe the issue or merge request...',
},
},
// Description
{
@@ -159,6 +167,20 @@ export const GitLabBlock: BlockConfig<GitLabResponse> = {
'gitlab_update_merge_request',
],
},
wandConfig: {
enabled: true,
prompt: `Generate a comprehensive description for a GitLab issue or merge request based on the user's request.
Include relevant sections as appropriate:
- Summary of changes or problem
- Context and motivation
- Testing done (for MRs)
- Steps to reproduce (for bugs)
Use Markdown formatting for readability.
Return ONLY the description - no explanations outside the content.`,
placeholder: 'Describe the content in detail...',
},
},
// Comment body
{
@@ -171,6 +193,15 @@ export const GitLabBlock: BlockConfig<GitLabResponse> = {
field: 'operation',
value: ['gitlab_create_issue_note', 'gitlab_create_merge_request_note'],
},
wandConfig: {
enabled: true,
prompt: `Generate a helpful GitLab comment based on the user's request.
The comment should be clear, constructive, and professional.
Use Markdown formatting for readability.
Return ONLY the comment text - no explanations, no extra formatting.`,
placeholder: 'Describe the comment you want to write...',
},
},
// Source branch (for MR creation)
{
@@ -352,6 +383,14 @@ export const GitLabBlock: BlockConfig<GitLabResponse> = {
field: 'operation',
value: ['gitlab_merge_merge_request'],
},
wandConfig: {
enabled: true,
prompt: `Generate a clear merge commit message based on the user's request.
The message should summarize what is being merged and why.
Return ONLY the commit message - no explanations, no extra text.`,
placeholder: 'Describe the merge...',
},
},
// Per page (pagination)
{

View File

@@ -68,6 +68,14 @@ export const GmailBlock: BlockConfig<GmailToolResponse> = {
placeholder: 'Email subject',
condition: { field: 'operation', value: ['send_gmail', 'draft_gmail'] },
required: false,
wandConfig: {
enabled: true,
prompt: `Generate a clear, professional email subject line based on the user's request.
The subject should be concise yet informative about the email's purpose.
Return ONLY the subject line - no explanations, no extra text.`,
placeholder: 'Describe the email topic...',
},
},
{
id: 'body',
@@ -76,6 +84,18 @@ export const GmailBlock: BlockConfig<GmailToolResponse> = {
placeholder: 'Email content',
condition: { field: 'operation', value: ['send_gmail', 'draft_gmail'] },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate professional email content based on the user's request.
The email should:
- Have an appropriate greeting
- Be clear and well-structured
- Have a professional tone
- Include a proper closing
Return ONLY the email body - no explanations, no extra text.`,
placeholder: 'Describe the email you want to write...',
},
},
{
id: 'contentType',
@@ -207,6 +227,18 @@ export const GmailBlock: BlockConfig<GmailToolResponse> = {
placeholder: 'Enter search terms',
condition: { field: 'operation', value: 'search_gmail' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a Gmail search query based on the user's request.
Gmail search supports operators like:
- from: to: subject: has:attachment
- is:unread is:starred is:important
- before: after: older: newer:
- filename: label: category:
Return ONLY the search query - no explanations, no extra text.`,
placeholder: 'Describe what emails you want to find...',
},
},
{
id: 'maxResults',

View File

@@ -21,6 +21,25 @@ export const GoogleSearchBlock: BlockConfig<GoogleSearchResponse> = {
type: 'long-input',
placeholder: 'Enter your search query',
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a Google search query based on the user's description.
Create an effective search query that will find relevant results.
Use search operators when appropriate:
- "exact phrase" for exact matches
- site:domain.com to search within a site
- -word to exclude terms
- OR for alternatives
- filetype:pdf for specific file types
Examples:
- "latest AI news" -> latest artificial intelligence news 2024
- "python tutorials on youtube" -> site:youtube.com python tutorial
- "PDF reports about climate change" -> climate change report filetype:pdf
Return ONLY the search query - no explanations, no quotes around the whole thing, no extra text.`,
placeholder: 'Describe what you want to search for...',
},
},
{
id: 'searchEngineId',

View File

@@ -67,6 +67,14 @@ export const GoogleCalendarBlock: BlockConfig<GoogleCalendarResponse> = {
placeholder: 'Meeting with team',
condition: { field: 'operation', value: 'create' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a clear, descriptive calendar event title based on the user's request.
The title should be concise but informative about the event's purpose.
Return ONLY the event title - no explanations, no extra text.`,
placeholder: 'Describe the event...',
},
},
{
id: 'description',
@@ -74,6 +82,18 @@ export const GoogleCalendarBlock: BlockConfig<GoogleCalendarResponse> = {
type: 'long-input',
placeholder: 'Event description',
condition: { field: 'operation', value: 'create' },
wandConfig: {
enabled: true,
prompt: `Generate a helpful calendar event description based on the user's request.
Include relevant details like:
- Purpose of the event
- Agenda items
- Preparation notes
- Links or resources
Return ONLY the description - no explanations, no extra text.`,
placeholder: 'Describe the event details...',
},
},
{
id: 'location',
@@ -89,6 +109,19 @@ export const GoogleCalendarBlock: BlockConfig<GoogleCalendarResponse> = {
placeholder: '2025-06-03T10:00:00-08:00',
condition: { field: 'operation', value: 'create' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp with timezone offset based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SS+HH:MM or YYYY-MM-DDTHH:MM:SS-HH:MM
Examples:
- "tomorrow at 2pm" -> Calculate tomorrow's date at 14:00:00 with local timezone offset
- "next Monday at 9am" -> Calculate next Monday at 09:00:00 with local timezone offset
- "in 2 hours" -> Calculate current time + 2 hours with local timezone offset
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start time (e.g., "tomorrow at 2pm", "next Monday at 9am")...',
generationType: 'timestamp',
},
},
{
id: 'endDateTime',
@@ -97,6 +130,19 @@ export const GoogleCalendarBlock: BlockConfig<GoogleCalendarResponse> = {
placeholder: '2025-06-03T11:00:00-08:00',
condition: { field: 'operation', value: 'create' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp with timezone offset based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SS+HH:MM or YYYY-MM-DDTHH:MM:SS-HH:MM
Examples:
- "tomorrow at 3pm" -> Calculate tomorrow's date at 15:00:00 with local timezone offset
- "1 hour after start" -> Calculate start time + 1 hour with local timezone offset
- "next Monday at 5pm" -> Calculate next Monday at 17:00:00 with local timezone offset
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end time (e.g., "tomorrow at 3pm", "1 hour after start")...',
generationType: 'timestamp',
},
},
{
id: 'attendees',
@@ -113,6 +159,20 @@ export const GoogleCalendarBlock: BlockConfig<GoogleCalendarResponse> = {
type: 'short-input',
placeholder: '2025-06-03T00:00:00Z',
condition: { field: 'operation', value: 'list' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp in UTC based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "today" -> Calculate today's date at 00:00:00Z
- "yesterday" -> Calculate yesterday's date at 00:00:00Z
- "last week" -> Calculate 7 days ago at 00:00:00Z
- "beginning of this month" -> Calculate the first day of current month at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start of time range (e.g., "today", "last week")...',
generationType: 'timestamp',
},
},
{
id: 'timeMax',
@@ -120,6 +180,20 @@ export const GoogleCalendarBlock: BlockConfig<GoogleCalendarResponse> = {
type: 'short-input',
placeholder: '2025-06-04T00:00:00Z',
condition: { field: 'operation', value: 'list' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp in UTC based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "tomorrow" -> Calculate tomorrow's date at 00:00:00Z
- "end of today" -> Calculate today's date at 23:59:59Z
- "next week" -> Calculate 7 days from now at 00:00:00Z
- "end of this month" -> Calculate the last day of current month at 23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end of time range (e.g., "tomorrow", "end of this week")...',
generationType: 'timestamp',
},
},
// Get Event Fields
@@ -159,6 +233,23 @@ export const GoogleCalendarBlock: BlockConfig<GoogleCalendarResponse> = {
placeholder: 'Meeting with John tomorrow at 3pm for 1 hour',
condition: { field: 'operation', value: 'quick_add' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a natural language event description that Google Calendar can parse.
Include:
- Event title/purpose
- Date and time
- Duration (optional)
- Location (optional)
Examples:
- "Meeting with John tomorrow at 3pm for 1 hour"
- "Lunch at Cafe Milano on Friday at noon"
- "Team standup every Monday at 9am"
Return ONLY the natural language event text - no explanations.`,
placeholder: 'Describe the event in natural language...',
},
},
{
id: 'attendees',

View File

@@ -73,6 +73,14 @@ export const GoogleDocsBlock: BlockConfig<GoogleDocsResponse> = {
placeholder: 'Enter title for the new document',
condition: { field: 'operation', value: 'create' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a clear, descriptive document title based on the user's request.
The title should be concise but informative about the document's purpose.
Return ONLY the document title - no explanations, no extra text.`,
placeholder: 'Describe the document...',
},
},
// Folder selector (basic mode)
{
@@ -107,6 +115,14 @@ export const GoogleDocsBlock: BlockConfig<GoogleDocsResponse> = {
placeholder: 'Enter document content',
condition: { field: 'operation', value: 'write' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate document content based on the user's request.
The content should be well-structured and appropriate for a Google Doc.
Return ONLY the document content - no explanations, no extra text.`,
placeholder: 'Describe the document content you want to write...',
},
},
// Content Field for create operation
{
@@ -115,6 +131,14 @@ export const GoogleDocsBlock: BlockConfig<GoogleDocsResponse> = {
type: 'long-input',
placeholder: 'Enter document content',
condition: { field: 'operation', value: 'create' },
wandConfig: {
enabled: true,
prompt: `Generate initial document content based on the user's request.
The content should be well-structured and appropriate for a new Google Doc.
Return ONLY the document content - no explanations, no extra text.`,
placeholder: 'Describe the document content you want to create...',
},
},
],
tools: {

View File

@@ -80,6 +80,17 @@ export const GoogleDriveBlock: BlockConfig<GoogleDriveResponse> = {
placeholder: 'Text content for the file',
condition: { field: 'operation', value: 'create_file' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate file content based on the user's description.
Create well-structured content appropriate for the file type.
For text files, use clear formatting and organization.
For HTML, include proper structure with appropriate tags.
For CSV, use proper comma-separated formatting.
Return ONLY the file content - no explanations, no markdown code blocks, no extra text.`,
placeholder: 'Describe the content you want to create...',
},
},
{
id: 'mimeType',
@@ -229,6 +240,24 @@ export const GoogleDriveBlock: BlockConfig<GoogleDriveResponse> = {
type: 'short-input',
placeholder: 'Search for specific files (e.g., name contains "report")',
condition: { field: 'operation', value: 'list' },
wandConfig: {
enabled: true,
prompt: `Generate a Google Drive search query based on the user's description.
Use Google Drive query syntax:
- name contains 'term' - search by filename
- mimeType = 'type' - filter by file type
- modifiedTime > 'date' - filter by date
- 'email' in owners - filter by owner
- fullText contains 'term' - search file contents
Examples:
- "PDF files" -> mimeType = 'application/pdf'
- "files named report" -> name contains 'report'
- "spreadsheets modified today" -> mimeType = 'application/vnd.google-apps.spreadsheet' and modifiedTime > '2024-01-01'
Return ONLY the query string - no explanations, no quotes around the whole thing, no extra text.`,
placeholder: 'Describe the files you want to find...',
},
},
{
id: 'pageSize',

View File

@@ -66,6 +66,22 @@ export const GoogleGroupsBlock: BlockConfig = {
type: 'short-input',
placeholder: 'Filter query (e.g., email:admin*)',
condition: { field: 'operation', value: 'list_groups' },
wandConfig: {
enabled: true,
prompt: `Generate a Google Groups search query based on the user's description.
Use Google Groups Admin SDK query syntax:
- email:pattern* - search by email address (supports wildcards)
- name:term - search by group name
- memberKey:email - search by member email
Examples:
- "groups starting with admin" -> email:admin*
- "groups with support in the name" -> name:support*
- "groups containing user@example.com" -> memberKey:user@example.com
Return ONLY the query string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the groups you want to find...',
},
},
{
id: 'maxResults',
@@ -115,6 +131,22 @@ export const GoogleGroupsBlock: BlockConfig = {
placeholder: 'Display name for the group',
required: true,
condition: { field: 'operation', value: 'create_group' },
wandConfig: {
enabled: true,
prompt: `Generate a professional group display name based on the user's description.
The name should be:
- Clear and descriptive
- Appropriate for a workplace setting
- Concise (typically 2-5 words)
Examples:
- "marketing team" -> Marketing Team
- "project managers" -> Project Managers
- "sales leadership" -> Sales Leadership Team
Return ONLY the group name - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the group you want to create...',
},
},
{
id: 'description',
@@ -122,6 +154,17 @@ export const GoogleGroupsBlock: BlockConfig = {
type: 'long-input',
placeholder: 'Optional description for the group',
condition: { field: 'operation', value: ['create_group', 'update_group'] },
wandConfig: {
enabled: true,
prompt: `Generate a professional group description based on the user's request.
The description should:
- Clearly explain the purpose of the group
- Be concise but informative (1-3 sentences)
- Use professional language appropriate for a workplace setting
Return ONLY the description text - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the purpose of this group...',
},
},
{

View File

@@ -83,6 +83,22 @@ export const GoogleSheetsBlock: BlockConfig<GoogleSheetsResponse> = {
'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]]) or an array of objects (e.g., [{"name":"John", "age":30}, {"name":"Jane", "age":25}])',
condition: { field: 'operation', value: 'write' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate Google Sheets data as a JSON array based on the user's description.
Format options:
1. Array of arrays: [["Header1", "Header2"], ["Value1", "Value2"]]
2. Array of objects: [{"column1": "value1", "column2": "value2"}]
Examples:
- "sales data with product and revenue columns" -> [["Product", "Revenue"], ["Widget A", 1500], ["Widget B", 2300]]
- "list of employees with name and email" -> [{"name": "John Doe", "email": "john@example.com"}, {"name": "Jane Smith", "email": "jane@example.com"}]
Return ONLY the JSON array - no explanations, no markdown, no extra text.`,
placeholder: 'Describe the data you want to write...',
generationType: 'json-object',
},
},
{
id: 'valueInputOption',
@@ -103,6 +119,22 @@ export const GoogleSheetsBlock: BlockConfig<GoogleSheetsResponse> = {
'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]]) or an array of objects (e.g., [{"name":"John", "age":30}, {"name":"Jane", "age":25}])',
condition: { field: 'operation', value: 'update' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate Google Sheets data as a JSON array based on the user's description.
Format options:
1. Array of arrays: [["Header1", "Header2"], ["Value1", "Value2"]]
2. Array of objects: [{"column1": "value1", "column2": "value2"}]
Examples:
- "update with new prices" -> [["Product", "Price"], ["Widget A", 29.99], ["Widget B", 49.99]]
- "quarterly targets" -> [{"Q1": 10000, "Q2": 12000, "Q3": 15000, "Q4": 18000}]
Return ONLY the JSON array - no explanations, no markdown, no extra text.`,
placeholder: 'Describe the data you want to update...',
generationType: 'json-object',
},
},
{
id: 'valueInputOption',
@@ -123,6 +155,22 @@ export const GoogleSheetsBlock: BlockConfig<GoogleSheetsResponse> = {
'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]]) or an array of objects (e.g., [{"name":"John", "age":30}, {"name":"Jane", "age":25}])',
condition: { field: 'operation', value: 'append' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate Google Sheets data as a JSON array based on the user's description.
Format options:
1. Array of arrays: [["Value1", "Value2"], ["Value3", "Value4"]]
2. Array of objects: [{"column1": "value1", "column2": "value2"}]
Examples:
- "add new sales record" -> [["2024-01-15", "Widget Pro", 5, 249.99]]
- "append customer info" -> [{"name": "Acme Corp", "contact": "John Smith", "status": "Active"}]
Return ONLY the JSON array - no explanations, no markdown, no extra text.`,
placeholder: 'Describe the data you want to append...',
generationType: 'json-object',
},
},
{
id: 'valueInputOption',

View File

@@ -91,6 +91,17 @@ export const GoogleSlidesBlock: BlockConfig<GoogleSlidesResponse> = {
placeholder: 'Enter slide content',
condition: { field: 'operation', value: 'write' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate slide content based on the user's description.
Create clear, concise content suitable for a presentation slide.
- Use bullet points for lists
- Keep text brief and impactful
- Focus on key points
Return ONLY the slide content - no explanations, no markdown formatting markers, no extra text.`,
placeholder: 'Describe what you want on this slide...',
},
},
// ========== Create Operation Fields ==========
@@ -101,6 +112,22 @@ export const GoogleSlidesBlock: BlockConfig<GoogleSlidesResponse> = {
placeholder: 'Enter title for the new presentation',
condition: { field: 'operation', value: 'create' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a professional presentation title based on the user's description.
The title should be:
- Clear and descriptive
- Professional and engaging
- Concise (typically 3-8 words)
Examples:
- "quarterly sales" -> Q4 2024 Sales Performance Review
- "product launch" -> Introducing Our New Product Line
- "team meeting" -> Weekly Team Sync - Updates & Goals
Return ONLY the title - no explanations, no quotes, no extra text.`,
placeholder: 'Describe your presentation topic...',
},
},
// Folder selector (basic mode)
{
@@ -134,6 +161,16 @@ export const GoogleSlidesBlock: BlockConfig<GoogleSlidesResponse> = {
type: 'long-input',
placeholder: 'Enter initial slide content (optional)',
condition: { field: 'operation', value: 'create' },
wandConfig: {
enabled: true,
prompt: `Generate initial slide content for a new presentation based on the user's description.
Create clear, concise content suitable for a title or introductory slide.
- Keep text brief and impactful
- Focus on the main message or theme
Return ONLY the slide content - no explanations, no markdown formatting markers, no extra text.`,
placeholder: 'Describe the initial slide content...',
},
},
// ========== Replace All Text Operation Fields ==========
@@ -152,6 +189,14 @@ export const GoogleSlidesBlock: BlockConfig<GoogleSlidesResponse> = {
placeholder: 'Text to replace with',
condition: { field: 'operation', value: 'replace_all_text' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate replacement text based on the user's description.
The text should be appropriate for a presentation slide - concise and professional.
Return ONLY the replacement text - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the replacement text...',
},
},
{
id: 'matchCase',
@@ -201,6 +246,28 @@ export const GoogleSlidesBlock: BlockConfig<GoogleSlidesResponse> = {
placeholder: 'JSON array: [{"layoutPlaceholder":{"type":"TITLE"},"objectId":"my_title"}]',
condition: { field: 'operation', value: 'add_slide' },
mode: 'advanced',
wandConfig: {
enabled: true,
prompt: `Generate Google Slides placeholder ID mappings as a JSON array.
Structure:
[
{
"layoutPlaceholder": {"type": "PLACEHOLDER_TYPE", "index": 0},
"objectId": "unique_object_id"
}
]
Placeholder types: TITLE, SUBTITLE, BODY, CENTERED_TITLE, HEADER, FOOTER, SLIDE_NUMBER, DATE_AND_TIME, CHART, TABLE, MEDIA, IMAGE
Examples:
- "title and body placeholders" -> [{"layoutPlaceholder":{"type":"TITLE"},"objectId":"title_1"},{"layoutPlaceholder":{"type":"BODY"},"objectId":"body_1"}]
- "just a title" -> [{"layoutPlaceholder":{"type":"TITLE"},"objectId":"my_title"}]
Return ONLY the JSON array - no explanations, no markdown, no extra text.`,
placeholder: 'Describe the placeholder mappings you need...',
generationType: 'json-object',
},
},
// ========== Add Image Operation Fields ==========

View File

@@ -90,6 +90,22 @@ export const GoogleVaultBlock: BlockConfig = {
placeholder: 'Name for the export',
condition: { field: 'operation', value: 'create_matters_export' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a descriptive export name for Google Vault based on the user's description.
The name should be:
- Clear and descriptive
- Include relevant identifiers (date, case, scope)
- Professional and concise
Examples:
- "email export for Q4" -> Q4_2024_Email_Export
- "drive files for legal case" -> Legal_Case_Drive_Files_Export
- "john's messages" -> John_Doe_Messages_Export
Return ONLY the export name - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the export...',
},
},
{
id: 'holdName',
@@ -98,6 +114,22 @@ export const GoogleVaultBlock: BlockConfig = {
placeholder: 'Name of the hold',
condition: { field: 'operation', value: 'create_matters_holds' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a descriptive hold name for Google Vault based on the user's description.
The name should be:
- Clear and descriptive
- Include relevant identifiers (case name, scope, date)
- Professional and concise
Examples:
- "hold for investigation" -> Investigation_Hold_2024
- "preserve emails for John" -> John_Doe_Email_Preservation
- "legal hold for project alpha" -> Project_Alpha_Legal_Hold
Return ONLY the hold name - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the hold...',
},
},
{
id: 'corpus',
@@ -169,6 +201,22 @@ export const GoogleVaultBlock: BlockConfig = {
placeholder: 'Enter Matter name',
condition: { field: 'operation', value: 'create_matters' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a descriptive matter name for Google Vault based on the user's description.
The name should be:
- Clear and descriptive
- Professional and suitable for legal/compliance purposes
- Include relevant identifiers if applicable
Examples:
- "investigation into data breach" -> Data_Breach_Investigation_2024
- "lawsuit from acme corp" -> Acme_Corp_Litigation
- "HR complaint case" -> HR_Complaint_Matter_001
Return ONLY the matter name - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the matter...',
},
},
{
id: 'description',
@@ -176,6 +224,17 @@ export const GoogleVaultBlock: BlockConfig = {
type: 'short-input',
placeholder: 'Optional description for the matter',
condition: { field: 'operation', value: 'create_matters' },
wandConfig: {
enabled: true,
prompt: `Generate a professional description for a Google Vault matter based on the user's request.
The description should:
- Clearly explain the purpose and scope of the matter
- Be concise but informative (1-3 sentences)
- Use professional language appropriate for legal/compliance contexts
Return ONLY the description text - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the purpose of this matter...',
},
},
// Optional get specific matter by ID
{

View File

@@ -103,6 +103,19 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
type: 'short-input',
placeholder: 'Filter dashboards by title',
condition: { field: 'operation', value: 'grafana_list_dashboards' },
wandConfig: {
enabled: true,
prompt: `Generate a Grafana dashboard search query based on the user's description.
The query should be a simple text string to filter dashboards by title.
Examples:
- "production dashboards" -> production
- "kubernetes monitoring" -> kubernetes
- "api performance" -> api performance
Return ONLY the search query - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the dashboards you want to find...',
},
},
{
id: 'tag',
@@ -120,6 +133,22 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
placeholder: 'Enter dashboard title',
required: true,
condition: { field: 'operation', value: 'grafana_create_dashboard' },
wandConfig: {
enabled: true,
prompt: `Generate a professional Grafana dashboard title based on the user's description.
The title should be:
- Clear and descriptive
- Indicate the purpose or scope of monitoring
- Concise (typically 2-5 words)
Examples:
- "api monitoring" -> API Performance Dashboard
- "kubernetes cluster" -> Kubernetes Cluster Overview
- "database metrics" -> Database Health & Metrics
Return ONLY the title - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the dashboard...',
},
},
{
id: 'folderUid',
@@ -154,6 +183,39 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
field: 'operation',
value: ['grafana_create_dashboard', 'grafana_update_dashboard'],
},
wandConfig: {
enabled: true,
prompt: `Generate Grafana panel configurations as a JSON array based on the user's description.
Basic panel structure:
[
{
"title": "Panel Title",
"type": "graph|stat|gauge|table|text|heatmap|bargauge",
"gridPos": {"x": 0, "y": 0, "w": 12, "h": 8},
"targets": [
{
"expr": "prometheus_query_here",
"refId": "A"
}
]
}
]
Common panel types:
- "graph" / "timeseries": Line charts for time-series data
- "stat": Single value display
- "gauge": Gauge visualization
- "table": Tabular data
- "bargauge": Bar gauge
Examples:
- "CPU usage panel" -> [{"title":"CPU Usage","type":"timeseries","gridPos":{"x":0,"y":0,"w":12,"h":8},"targets":[{"expr":"100 - (avg(irate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)","refId":"A"}]}]
Return ONLY the JSON array - no explanations, no markdown, no extra text.`,
placeholder: 'Describe the panels you want to create...',
generationType: 'json-object',
},
},
{
id: 'message',
@@ -187,6 +249,22 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
field: 'operation',
value: ['grafana_create_alert_rule', 'grafana_update_alert_rule'],
},
wandConfig: {
enabled: true,
prompt: `Generate a professional Grafana alert rule name based on the user's description.
The name should be:
- Clear and descriptive
- Indicate what is being monitored and the condition
- Follow naming conventions (PascalCase or with spaces)
Examples:
- "high cpu alert" -> High CPU Usage Alert
- "disk space warning" -> Low Disk Space Warning
- "api error rate" -> API Error Rate Threshold
Return ONLY the alert title - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the alert...',
},
},
{
id: 'folderUid',
@@ -227,6 +305,48 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
field: 'operation',
value: ['grafana_create_alert_rule', 'grafana_update_alert_rule'],
},
wandConfig: {
enabled: true,
prompt: `Generate Grafana alert query data as a JSON array based on the user's description.
Structure for alert queries:
[
{
"refId": "A",
"datasourceUid": "datasource_uid",
"model": {
"expr": "prometheus_query",
"refId": "A"
}
},
{
"refId": "B",
"datasourceUid": "-100",
"model": {
"type": "reduce",
"expression": "A",
"reducer": "last"
}
},
{
"refId": "C",
"datasourceUid": "-100",
"model": {
"type": "threshold",
"expression": "B",
"conditions": [{"evaluator": {"type": "gt", "params": [80]}}]
}
}
]
Examples:
- "alert when CPU > 80%" -> Query for CPU metrics with threshold condition
- "memory usage warning" -> Query for memory with reduce and threshold
Return ONLY the JSON array - no explanations, no markdown, no extra text.`,
placeholder: 'Describe the alert query conditions...',
generationType: 'json-object',
},
},
{
id: 'forDuration',
@@ -279,6 +399,22 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
field: 'operation',
value: ['grafana_create_annotation', 'grafana_update_annotation'],
},
wandConfig: {
enabled: true,
prompt: `Generate annotation text for Grafana based on the user's description.
The annotation should:
- Clearly describe the event or observation
- Be concise but informative
- Include relevant details (what happened, impact, etc.)
Examples:
- "deployment started" -> Deployment v2.3.1 started - API service
- "high traffic period" -> High traffic period began - 3x normal load
- "config change" -> Configuration update: increased connection pool size to 50
Return ONLY the annotation text - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the annotation...',
},
},
{
id: 'annotationTags',
@@ -324,6 +460,19 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
field: 'operation',
value: ['grafana_create_annotation', 'grafana_update_annotation'],
},
wandConfig: {
enabled: true,
prompt: `Generate an epoch timestamp in milliseconds based on the user's description.
The timestamp should be a Unix epoch time in milliseconds (13 digits).
Examples:
- "now" -> Current timestamp in milliseconds
- "yesterday" -> Yesterday at 00:00:00 in milliseconds
- "1 hour ago" -> Subtract 3600000 from current time
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the time (e.g., "now", "1 hour ago", "yesterday at noon")...',
generationType: 'timestamp',
},
},
{
id: 'timeEnd',
@@ -334,6 +483,19 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
field: 'operation',
value: ['grafana_create_annotation', 'grafana_update_annotation'],
},
wandConfig: {
enabled: true,
prompt: `Generate an epoch timestamp in milliseconds based on the user's description.
The timestamp should be a Unix epoch time in milliseconds (13 digits).
Examples:
- "now" -> Current timestamp in milliseconds
- "in 1 hour" -> Add 3600000 to current time
- "end of today" -> Today at 23:59:59 in milliseconds
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end time (e.g., "in 1 hour", "end of today")...',
generationType: 'timestamp',
},
},
{
id: 'annotationId',
@@ -352,6 +514,19 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
type: 'short-input',
placeholder: 'Filter from time',
condition: { field: 'operation', value: 'grafana_list_annotations' },
wandConfig: {
enabled: true,
prompt: `Generate an epoch timestamp in milliseconds based on the user's description.
The timestamp should be a Unix epoch time in milliseconds (13 digits).
Examples:
- "last week" -> 7 days ago at 00:00:00 in milliseconds
- "beginning of this month" -> First day of current month at 00:00:00
- "24 hours ago" -> Subtract 86400000 from current time
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start time (e.g., "last week", "beginning of this month")...',
generationType: 'timestamp',
},
},
{
id: 'to',
@@ -359,6 +534,19 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
type: 'short-input',
placeholder: 'Filter to time',
condition: { field: 'operation', value: 'grafana_list_annotations' },
wandConfig: {
enabled: true,
prompt: `Generate an epoch timestamp in milliseconds based on the user's description.
The timestamp should be a Unix epoch time in milliseconds (13 digits).
Examples:
- "now" -> Current timestamp in milliseconds
- "end of today" -> Today at 23:59:59 in milliseconds
- "end of last week" -> Last Sunday at 23:59:59 in milliseconds
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end time (e.g., "now", "end of today")...',
generationType: 'timestamp',
},
},
// Folder operations
@@ -369,6 +557,22 @@ export const GrafanaBlock: BlockConfig<GrafanaResponse> = {
placeholder: 'Enter folder title',
required: true,
condition: { field: 'operation', value: 'grafana_create_folder' },
wandConfig: {
enabled: true,
prompt: `Generate a Grafana folder title based on the user's description.
The title should be:
- Clear and descriptive
- Indicate the category or scope of dashboards it will contain
- Concise (typically 1-3 words)
Examples:
- "production monitoring" -> Production
- "kubernetes dashboards" -> Kubernetes
- "team alpha metrics" -> Team Alpha
Return ONLY the folder title - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the folder...',
},
},
{
id: 'folderUidNew',

View File

@@ -73,6 +73,19 @@ export const GrainBlock: BlockConfig = {
field: 'operation',
value: ['grain_list_recordings', 'grain_create_hook'],
},
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "yesterday" -> Calculate yesterday's date at 00:00:00Z
- "last week" -> Calculate 7 days ago at 00:00:00Z
- "beginning of this month" -> First day of current month at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "yesterday", "last week")...',
generationType: 'timestamp',
},
},
// After datetime filter
{
@@ -84,6 +97,19 @@ export const GrainBlock: BlockConfig = {
field: 'operation',
value: ['grain_list_recordings', 'grain_create_hook'],
},
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "today" -> Today's date at 00:00:00Z
- "last Monday" -> Calculate last Monday's date at 00:00:00Z
- "beginning of last month" -> First day of previous month at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "today", "last Monday")...',
generationType: 'timestamp',
},
},
// Participant scope filter
{
@@ -111,6 +137,21 @@ export const GrainBlock: BlockConfig = {
field: 'operation',
value: ['grain_list_recordings'],
},
wandConfig: {
enabled: true,
prompt: `Generate a search term for finding recordings by title based on the user's description.
The search term should be:
- Keywords or phrases that would appear in recording titles
- Concise and targeted
Examples:
- "meetings with john" -> John
- "weekly standup" -> standup
- "product demo" -> demo product
Return ONLY the search term - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the recordings you want to find...',
},
},
// Team ID filter
{

View File

@@ -73,6 +73,30 @@ export const GuardrailsBlock: BlockConfig<GuardrailsResponse> = {
field: 'validationType',
value: ['regex'],
},
wandConfig: {
enabled: true,
prompt: `Generate a regular expression pattern based on the user's description.
The regex should be:
- Valid JavaScript regex syntax
- Properly escaped for special characters
- Optimized for the use case
Common patterns:
- Email: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$
- Phone (US): ^\\+?1?[-.\\s]?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}$
- URL: ^https?:\\/\\/[\\w\\-]+(\\.[\\w\\-]+)+[/#?]?.*$
- Date (YYYY-MM-DD): ^\\d{4}-\\d{2}-\\d{2}$
- UUID: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
- IP Address: ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
Examples:
- "validate email" -> ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$
- "check for numbers only" -> ^\\d+$
- "alphanumeric with underscores" -> ^[a-zA-Z0-9_]+$
Return ONLY the regex pattern - no explanations, no quotes, no forward slashes, no extra text.`,
placeholder: 'Describe the pattern you want to match...',
},
},
{
id: 'knowledgeBaseId',

View File

@@ -125,6 +125,18 @@ export const HunterBlock: BlockConfig<HunterResponse> = {
placeholder: 'Enter search query (e.g., "software companies in San Francisco")',
condition: { field: 'operation', value: 'hunter_discover' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a company discovery search query for Hunter.io based on the user's description.
The query should be optimized for finding companies and should include:
- Industry or business type
- Location if relevant
- Company size or other relevant criteria
Return ONLY the search query text - no explanations.`,
placeholder:
'Describe the companies you want to find (e.g., "fintech startups in NYC", "healthcare companies in Europe")...',
},
},
{
id: 'domain',

View File

@@ -127,6 +127,17 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
type: 'short-input',
placeholder: 'Enter incident name...',
condition: { field: 'operation', value: 'incidentio_incidents_create' },
wandConfig: {
enabled: true,
prompt: `Generate a concise, descriptive incident name based on the user's description.
The incident name should:
- Be clear and descriptive
- Indicate the nature of the issue
- Be suitable for incident tracking and communication
Return ONLY the incident name - no explanations.`,
placeholder: 'Describe the incident (e.g., "database outage", "API latency issues")...',
},
},
{
id: 'summary',
@@ -137,6 +148,17 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
field: 'operation',
value: ['incidentio_incidents_create', 'incidentio_incidents_update'],
},
wandConfig: {
enabled: true,
prompt: `Generate an incident summary based on the user's description.
The summary should:
- Clearly describe the impact and scope of the incident
- Include relevant technical details
- Be professional and suitable for stakeholder communication
Return ONLY the summary text - no explanations.`,
placeholder: 'Describe the incident details (e.g., "users unable to login since 2pm")...',
},
},
{
id: 'severity_id',
@@ -281,6 +303,18 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
placeholder: 'Enter escalation title...',
condition: { field: 'operation', value: 'incidentio_escalations_create' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate an escalation title based on the user's description.
The title should:
- Be concise and urgent
- Clearly indicate the escalation reason
- Be suitable for paging and alerting
Return ONLY the title - no explanations.`,
placeholder:
'Describe the escalation reason (e.g., "critical system down", "security breach detected")...',
},
},
{
id: 'escalation_path_id',
@@ -383,6 +417,26 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
'JSON configuration with rotations. Example: {"rotations": [{"name": "Primary", "users": [{"id": "user_id"}], "handover_start_at": "2024-01-01T09:00:00Z", "handovers": [{"interval": 1, "interval_type": "weekly"}]}]}',
condition: { field: 'operation', value: 'incidentio_schedules_create' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON schedule configuration for incident.io based on the user's description.
The configuration must follow this structure:
{
"rotations": [
{
"name": "Rotation Name",
"users": [{"id": "user_id"}],
"handover_start_at": "ISO8601 timestamp",
"handovers": [{"interval": number, "interval_type": "daily|weekly|monthly"}]
}
]
}
Return ONLY the JSON object - no explanations or markdown formatting.`,
placeholder:
'Describe the schedule (e.g., "weekly rotation between 3 engineers starting Monday 9am")...',
generationType: 'json-object',
},
},
{
id: 'timezone',
@@ -427,6 +481,18 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
value: ['incidentio_custom_fields_create', 'incidentio_custom_fields_update'],
},
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a description for a custom field based on the user's description.
The description should:
- Explain what the field is used for
- Provide guidance on how to fill it out
- Be clear and concise
Return ONLY the description text - no explanations.`,
placeholder:
'Describe the custom field purpose (e.g., "tracks affected customer count", "categorizes incident type")...',
},
},
{
id: 'field_type',
@@ -454,6 +520,18 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
value: ['incidentio_incident_roles_create', 'incidentio_incident_roles_update'],
},
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a description for an incident role based on the user's description.
The description should:
- Explain the role's responsibilities
- Clarify when this role is needed
- Be suitable for incident response documentation
Return ONLY the description text - no explanations.`,
placeholder:
'Describe the role (e.g., "coordinates communication with stakeholders", "leads technical investigation")...',
},
},
{
id: 'instructions',
@@ -465,6 +543,18 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
value: ['incidentio_incident_roles_create', 'incidentio_incident_roles_update'],
},
required: true,
wandConfig: {
enabled: true,
prompt: `Generate instructions for an incident role based on the user's description.
The instructions should:
- Provide step-by-step guidance for the role
- Include key actions and responsibilities
- Be actionable and clear during an incident
Return ONLY the instructions text - no explanations.`,
placeholder:
'Describe what the role should do (e.g., "manage external communications during outages")...',
},
},
{
id: 'shortform',
@@ -504,6 +594,19 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
type: 'short-input',
placeholder: 'ISO 8601 format (e.g., 2024-01-01T00:00:00Z)...',
condition: { field: 'operation', value: 'incidentio_schedule_entries_list' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "beginning of this week" -> Monday of current week at 00:00:00Z
- "last month" -> First day of previous month at 00:00:00Z
- "yesterday" -> Yesterday's date at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date (e.g., "beginning of this week", "last month")...',
generationType: 'timestamp',
},
},
{
id: 'entry_window_end',
@@ -511,6 +614,19 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
type: 'short-input',
placeholder: 'ISO 8601 format (e.g., 2024-12-31T23:59:59Z)...',
condition: { field: 'operation', value: 'incidentio_schedule_entries_list' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "end of this week" -> Sunday of current week at 23:59:59Z
- "end of next month" -> Last day of next month at 23:59:59Z
- "tomorrow" -> Tomorrow's date at 23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end date (e.g., "end of this week", "end of next month")...',
generationType: 'timestamp',
},
},
// Schedule Overrides inputs
{
@@ -552,6 +668,19 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
placeholder: 'ISO 8601 format (e.g., 2024-01-01T00:00:00Z)...',
condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "now" -> Current date and time in UTC
- "tomorrow at 9am" -> Tomorrow at 09:00:00Z
- "next Monday" -> Next Monday at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start time (e.g., "now", "tomorrow at 9am")...',
generationType: 'timestamp',
},
},
{
id: 'end_at',
@@ -560,6 +689,19 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
placeholder: 'ISO 8601 format (e.g., 2024-12-31T23:59:59Z)...',
condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "in 4 hours" -> Current time plus 4 hours
- "tomorrow at 5pm" -> Tomorrow at 17:00:00Z
- "end of next week" -> Next Sunday at 23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end time (e.g., "in 4 hours", "tomorrow at 5pm")...',
generationType: 'timestamp',
},
},
// Escalation Paths inputs
{
@@ -573,6 +715,24 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
value: 'incidentio_escalation_paths_create',
},
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON array for escalation path configuration based on the user's description.
The array must follow this structure:
[
{
"targets": [{"id": "target_id", "type": "user|schedule", "urgency": "high|low"}],
"time_to_ack_seconds": number
}
]
Each level represents an escalation step with acknowledgment timeout.
Return ONLY the JSON array - no explanations or markdown formatting.`,
placeholder:
'Describe the escalation path (e.g., "page on-call first, then manager after 5 min")...',
generationType: 'json-object',
},
},
{
id: 'path',
@@ -596,6 +756,18 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
field: 'operation',
value: ['incidentio_escalation_paths_create', 'incidentio_escalation_paths_update'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON array for working hours configuration based on the user's description.
The array must follow this structure:
[
{"weekday": "monday|tuesday|wednesday|thursday|friday|saturday|sunday", "start_time": "HH:MM", "end_time": "HH:MM"}
]
Return ONLY the JSON array - no explanations or markdown formatting.`,
placeholder: 'Describe working hours (e.g., "9-5 Monday to Friday", "24/7 coverage")...',
generationType: 'json-object',
},
},
// API Key (common)
{

View File

@@ -130,6 +130,19 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['create_contact', 'update_contact'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
The timestamp should be a Unix epoch time in seconds (10 digits).
Examples:
- "yesterday" -> Yesterday at 00:00:00 as Unix timestamp
- "last week" -> 7 days ago at 00:00:00 as Unix timestamp
- "January 1, 2024" -> 1704067200
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the signup date (e.g., "yesterday", "January 1, 2024")...',
generationType: 'timestamp',
},
},
{
id: 'last_seen_at',
@@ -140,6 +153,19 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['create_contact', 'update_contact'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
The timestamp should be a Unix epoch time in seconds (10 digits).
Examples:
- "now" -> Current Unix timestamp
- "1 hour ago" -> Current time minus 3600 seconds
- "today at noon" -> Today at 12:00:00 as Unix timestamp
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the last seen time (e.g., "now", "1 hour ago")...',
generationType: 'timestamp',
},
},
{
id: 'owner_id',
@@ -173,6 +199,17 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['create_contact', 'update_contact'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for Intercom custom attributes based on the user's description.
The object should contain key-value pairs for custom contact attributes.
Example: {"plan_type": "enterprise", "signup_source": "website", "industry": "technology"}
Return ONLY the JSON object - no explanations or markdown formatting.`,
placeholder:
'Describe the custom attributes (e.g., "enterprise customer, signed up from marketing campaign")...',
generationType: 'json-object',
},
},
{
id: 'contact_company_id',
@@ -194,6 +231,17 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['search_contacts', 'search_conversations'],
},
wandConfig: {
enabled: true,
prompt: `Generate a search query for Intercom based on the user's description.
This can be either:
1. A simple text search query
2. A JSON query object for advanced filtering
Return ONLY the query - no explanations.`,
placeholder:
'Describe what you want to search for (e.g., "active users from last week", "open conversations about billing")...',
},
},
{
id: 'sort_field',
@@ -310,6 +358,20 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['create_company'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
The timestamp should be a Unix epoch time in seconds (10 digits).
Examples:
- "2 years ago" -> Calculate 2 years ago as Unix timestamp
- "January 2022" -> January 1, 2022 at 00:00:00 as Unix timestamp
- "last year" -> 1 year ago at 00:00:00 as Unix timestamp
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder:
'Describe when the company was created (e.g., "2 years ago", "January 2022")...',
generationType: 'timestamp',
},
},
// Conversation fields
{
@@ -396,6 +458,18 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['reply_conversation', 'create_message'],
},
wandConfig: {
enabled: true,
prompt: `Generate a message body for Intercom based on the user's description.
The message should:
- Be professional and friendly
- Be clear and concise
- Match the context (support reply, outreach, etc.)
Return ONLY the message text - no explanations.`,
placeholder:
'Describe the message you want to send (e.g., "thank customer for feedback", "follow up on support ticket")...',
},
},
{
id: 'admin_id',
@@ -427,6 +501,19 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['reply_conversation'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
The timestamp should be a Unix epoch time in seconds (10 digits).
Examples:
- "now" -> Current Unix timestamp
- "5 minutes ago" -> Current time minus 300 seconds
- "earlier today" -> Today at 09:00:00 as Unix timestamp
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the reply time (e.g., "now", "5 minutes ago")...',
generationType: 'timestamp',
},
},
// Ticket fields
{
@@ -461,6 +548,16 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['create_ticket'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of contact identifiers for Intercom based on the user's description.
The array should contain contact identifier objects.
Example: [{"id": "contact_id_1"}, {"id": "contact_id_2"}] or [{"email": "user@example.com"}]
Return ONLY the JSON array - no explanations or markdown formatting.`,
placeholder: 'Describe the contacts (e.g., "user with email john@example.com")...',
generationType: 'json-object',
},
},
{
id: 'ticket_attributes',
@@ -472,6 +569,16 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['create_ticket'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for Intercom ticket attributes based on the user's description.
The object should contain the ticket's custom attributes based on your ticket type schema.
Example: {"_default_title_": "Issue title", "_default_description_": "Issue description", "priority": "high"}
Return ONLY the JSON object - no explanations or markdown formatting.`,
placeholder: 'Describe the ticket (e.g., "high priority bug report about login issues")...',
generationType: 'json-object',
},
},
{
id: 'ticket_company_id',
@@ -492,6 +599,19 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['create_ticket'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
The timestamp should be a Unix epoch time in seconds (10 digits).
Examples:
- "now" -> Current Unix timestamp
- "when the issue was reported" -> Use current time
- "yesterday" -> Yesterday at 00:00:00 as Unix timestamp
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the ticket creation time (e.g., "now", "yesterday")...',
generationType: 'timestamp',
},
},
{
id: 'conversation_to_link_id',
@@ -554,6 +674,18 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['create_message'],
},
wandConfig: {
enabled: true,
prompt: `Generate an email subject line for Intercom based on the user's description.
The subject should:
- Be concise and attention-grabbing
- Clearly indicate the email purpose
- Be professional
Return ONLY the subject line - no explanations.`,
placeholder:
'Describe the email purpose (e.g., "welcome new customer", "feature announcement")...',
},
},
{
id: 'from_type',
@@ -608,6 +740,19 @@ export const IntercomBlock: BlockConfig = {
field: 'operation',
value: ['create_message'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
The timestamp should be a Unix epoch time in seconds (10 digits).
Examples:
- "now" -> Current Unix timestamp
- "just now" -> Current Unix timestamp
- "a few minutes ago" -> Current time minus 300 seconds
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the message time (e.g., "now", "just now")...',
generationType: 'timestamp',
},
},
// Pagination fields
{

View File

@@ -186,6 +186,18 @@ export const JiraBlock: BlockConfig<JiraResponse> = {
placeholder: 'Enter new summary for the issue',
dependsOn: ['projectId'],
condition: { field: 'operation', value: ['update', 'write'] },
wandConfig: {
enabled: true,
prompt: `Generate a concise Jira issue summary/title based on the user's description.
The summary should:
- Be clear and descriptive
- Capture the essence of the issue
- Be suitable for issue tracking
Return ONLY the summary text - no explanations.`,
placeholder:
'Describe the issue (e.g., "login page not loading", "add dark mode feature")...',
},
},
{
id: 'description',
@@ -194,6 +206,18 @@ export const JiraBlock: BlockConfig<JiraResponse> = {
placeholder: 'Enter new description for the issue',
dependsOn: ['projectId'],
condition: { field: 'operation', value: ['update', 'write'] },
wandConfig: {
enabled: true,
prompt: `Generate a detailed Jira issue description based on the user's description.
The description should:
- Provide context and details about the issue
- Include steps to reproduce (for bugs) or requirements (for features)
- Be professional and clear
Return ONLY the description text - no explanations.`,
placeholder:
'Describe the issue details (e.g., "users seeing 500 error when clicking submit")...',
},
},
// Write Issue additional fields
{
@@ -227,6 +251,19 @@ export const JiraBlock: BlockConfig<JiraResponse> = {
placeholder: 'YYYY-MM-DD (e.g., 2024-12-31)',
dependsOn: ['projectId'],
condition: { field: 'operation', value: 'write' },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "tomorrow" -> Calculate tomorrow's date
- "next week" -> Calculate 7 days from now
- "end of month" -> Calculate the last day of the current month
- "in 2 weeks" -> Calculate 14 days from now
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the due date (e.g., "next Friday", "end of month")...',
generationType: 'timestamp',
},
},
{
id: 'reporter',
@@ -296,6 +333,17 @@ export const JiraBlock: BlockConfig<JiraResponse> = {
type: 'long-input',
placeholder: 'Add optional comment for transition',
condition: { field: 'operation', value: 'transition' },
wandConfig: {
enabled: true,
prompt: `Generate a transition comment for a Jira issue based on the user's description.
The comment should:
- Explain the reason for the status change
- Provide any relevant context
- Be professional and informative
Return ONLY the comment text - no explanations.`,
placeholder: 'Describe the transition reason (e.g., "fixed bug", "ready for QA review")...',
},
},
// Search Issues fields
{
@@ -305,6 +353,22 @@ export const JiraBlock: BlockConfig<JiraResponse> = {
required: true,
placeholder: 'Enter JQL query (e.g., project = PROJ AND status = "In Progress")',
condition: { field: 'operation', value: 'search' },
wandConfig: {
enabled: true,
prompt: `Generate a JQL (Jira Query Language) query based on the user's description.
JQL syntax examples:
- project = PROJ
- status = "In Progress"
- assignee = currentUser()
- created >= -7d
- priority = High AND status != Done
- labels in (bug, urgent)
Return ONLY the JQL query - no explanations or markdown formatting.`,
placeholder:
'Describe what you want to search for (e.g., "open bugs assigned to me", "high priority issues from last week")...',
generationType: 'sql-query',
},
},
{
id: 'maxResults',
@@ -321,6 +385,18 @@ export const JiraBlock: BlockConfig<JiraResponse> = {
required: true,
placeholder: 'Enter comment text',
condition: { field: 'operation', value: ['add_comment', 'update_comment'] },
wandConfig: {
enabled: true,
prompt: `Generate a Jira issue comment based on the user's description.
The comment should:
- Be professional and informative
- Provide relevant updates or information
- Be suitable for team collaboration
Return ONLY the comment text - no explanations.`,
placeholder:
'Describe what you want to comment (e.g., "update on investigation", "requesting review")...',
},
},
{
id: 'commentId',
@@ -361,6 +437,18 @@ export const JiraBlock: BlockConfig<JiraResponse> = {
type: 'long-input',
placeholder: 'Enter optional worklog comment',
condition: { field: 'operation', value: ['add_worklog', 'update_worklog'] },
wandConfig: {
enabled: true,
prompt: `Generate a worklog comment for Jira based on the user's description.
The comment should:
- Describe the work that was done
- Be concise but informative
- Be suitable for time tracking records
Return ONLY the comment text - no explanations.`,
placeholder:
'Describe the work done (e.g., "implemented API endpoint", "fixed login bug")...',
},
},
{
id: 'started',
@@ -368,6 +456,20 @@ export const JiraBlock: BlockConfig<JiraResponse> = {
type: 'short-input',
placeholder: 'ISO timestamp (defaults to now)',
condition: { field: 'operation', value: ['add_worklog', 'update_worklog'] },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SS.sssZ (UTC timezone).
Examples:
- "now" -> Current timestamp
- "yesterday at 9am" -> Yesterday's date at 09:00:00.000Z
- "last Monday at 2pm" -> Calculate last Monday at 14:00:00.000Z
- "start of today" -> Today's date at 00:00:00.000Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe when the work started (e.g., "yesterday at 9am")...',
generationType: 'timestamp',
},
},
{
id: 'worklogId',
@@ -408,6 +510,18 @@ export const JiraBlock: BlockConfig<JiraResponse> = {
type: 'long-input',
placeholder: 'Add optional comment for the link',
condition: { field: 'operation', value: 'create_link' },
wandConfig: {
enabled: true,
prompt: `Generate a comment for a Jira issue link based on the user's description.
The comment should:
- Explain why the issues are linked
- Provide context for the relationship
- Be concise and clear
Return ONLY the comment text - no explanations.`,
placeholder:
'Describe the relationship (e.g., "blocks deployment", "related to refactoring effort")...',
},
},
{
id: 'linkId',

View File

@@ -149,6 +149,18 @@ export const JiraServiceManagementBlock: BlockConfig<JsmResponse> = {
required: true,
placeholder: 'Enter request summary',
condition: { field: 'operation', value: 'create_request' },
wandConfig: {
enabled: true,
prompt: `Generate a concise service request summary based on the user's description.
The summary should:
- Be clear and descriptive
- Capture the essence of the request
- Be suitable for service desk tracking
Return ONLY the summary text - no explanations.`,
placeholder:
'Describe the service request (e.g., "need VPN access", "laptop keyboard not working")...',
},
},
{
id: 'description',
@@ -156,6 +168,18 @@ export const JiraServiceManagementBlock: BlockConfig<JsmResponse> = {
type: 'long-input',
placeholder: 'Enter request description',
condition: { field: 'operation', value: 'create_request' },
wandConfig: {
enabled: true,
prompt: `Generate a detailed service request description based on the user's description.
The description should:
- Provide context and details about the request
- Include relevant information for the service desk agent
- Be professional and clear
Return ONLY the description text - no explanations.`,
placeholder:
'Describe the request details (e.g., "need access to shared drive for new project")...',
},
},
{
id: 'raiseOnBehalfOf',
@@ -171,6 +195,18 @@ export const JiraServiceManagementBlock: BlockConfig<JsmResponse> = {
required: true,
placeholder: 'Enter comment text',
condition: { field: 'operation', value: 'add_comment' },
wandConfig: {
enabled: true,
prompt: `Generate a service request comment based on the user's description.
The comment should:
- Be professional and helpful
- Provide relevant information or updates
- Be suitable for customer or internal communication
Return ONLY the comment text - no explanations.`,
placeholder:
'Describe what you want to communicate (e.g., "update on ticket progress", "request more information")...',
},
},
{
id: 'isPublic',
@@ -212,6 +248,18 @@ export const JiraServiceManagementBlock: BlockConfig<JsmResponse> = {
type: 'long-input',
placeholder: 'Add optional comment during transition',
condition: { field: 'operation', value: 'transition_request' },
wandConfig: {
enabled: true,
prompt: `Generate a transition comment for a service request based on the user's description.
The comment should:
- Explain the reason for the status change
- Provide any relevant context
- Be professional and informative
Return ONLY the comment text - no explanations.`,
placeholder:
'Describe the transition reason (e.g., "resolved issue", "waiting for customer input")...',
},
},
{
id: 'requestOwnership',

View File

@@ -176,6 +176,19 @@ export const KalshiBlock: BlockConfig = {
type: 'short-input',
placeholder: 'Minimum timestamp (Unix milliseconds)',
condition: { field: 'operation', value: ['get_fills'] },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in milliseconds based on the user's description.
Examples:
- "yesterday" -> Calculate yesterday at 00:00:00 in milliseconds since epoch
- "last week" -> Calculate 7 days ago at 00:00:00 in milliseconds since epoch
- "start of today" -> Today at 00:00:00 in milliseconds since epoch
- "1 hour ago" -> Current time minus 1 hour in milliseconds since epoch
Return ONLY the numeric timestamp (milliseconds since Unix epoch) - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the minimum date/time (e.g., "yesterday", "last week")...',
generationType: 'timestamp',
},
},
{
id: 'maxTs',
@@ -183,6 +196,19 @@ export const KalshiBlock: BlockConfig = {
type: 'short-input',
placeholder: 'Maximum timestamp (Unix milliseconds)',
condition: { field: 'operation', value: ['get_fills'] },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in milliseconds based on the user's description.
Examples:
- "now" -> Current time in milliseconds since epoch
- "end of today" -> Today at 23:59:59 in milliseconds since epoch
- "tomorrow" -> Tomorrow at 00:00:00 in milliseconds since epoch
- "end of this week" -> End of current week in milliseconds since epoch
Return ONLY the numeric timestamp (milliseconds since Unix epoch) - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the maximum date/time (e.g., "now", "end of today")...',
generationType: 'timestamp',
},
},
// Get Candlesticks fields
{
@@ -208,6 +234,19 @@ export const KalshiBlock: BlockConfig = {
placeholder: 'Start timestamp (Unix seconds)',
required: true,
condition: { field: 'operation', value: ['get_candlesticks'] },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
Examples:
- "yesterday" -> Calculate yesterday at 00:00:00 in seconds since epoch
- "last week" -> Calculate 7 days ago at 00:00:00 in seconds since epoch
- "start of this month" -> First day of current month at 00:00:00 in seconds since epoch
- "24 hours ago" -> Current time minus 24 hours in seconds since epoch
Return ONLY the numeric timestamp (seconds since Unix epoch) - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date/time (e.g., "yesterday", "start of this month")...',
generationType: 'timestamp',
},
},
{
id: 'endTs',
@@ -216,6 +255,19 @@ export const KalshiBlock: BlockConfig = {
placeholder: 'End timestamp (Unix seconds)',
required: true,
condition: { field: 'operation', value: ['get_candlesticks'] },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
Examples:
- "now" -> Current time in seconds since epoch
- "end of today" -> Today at 23:59:59 in seconds since epoch
- "end of this month" -> Last day of current month at 23:59:59 in seconds since epoch
- "tomorrow" -> Tomorrow at 00:00:00 in seconds since epoch
Return ONLY the numeric timestamp (seconds since Unix epoch) - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end date/time (e.g., "now", "end of today")...',
generationType: 'timestamp',
},
},
{
id: 'periodInterval',
@@ -372,6 +424,19 @@ export const KalshiBlock: BlockConfig = {
type: 'short-input',
placeholder: 'Unix timestamp for order expiration',
condition: { field: 'operation', value: ['create_order'] },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description for when the order should expire.
Examples:
- "in 1 hour" -> Current time plus 1 hour in seconds since epoch
- "end of day" -> Today at 23:59:59 in seconds since epoch
- "tomorrow at noon" -> Tomorrow at 12:00:00 in seconds since epoch
- "in 30 minutes" -> Current time plus 30 minutes in seconds since epoch
Return ONLY the numeric timestamp (seconds since Unix epoch) - no explanations, no quotes, no extra text.`,
placeholder: 'Describe when the order should expire (e.g., "in 1 hour", "end of day")...',
generationType: 'timestamp',
},
},
{
id: 'postOnly',

View File

@@ -317,6 +317,17 @@ export const LinearBlock: BlockConfig<LinearResponse> = {
field: 'operation',
value: ['linear_create_issue', 'linear_update_issue'],
},
wandConfig: {
enabled: true,
prompt: `Generate a concise Linear issue title based on the user's description.
The title should:
- Be clear and descriptive
- Capture the essence of the issue
- Be suitable for project management tracking
Return ONLY the title text - no explanations.`,
placeholder: 'Describe the issue (e.g., "login not working", "add export feature")...',
},
},
// Description (for issue creation/update, comments, projects)
{
@@ -333,6 +344,17 @@ export const LinearBlock: BlockConfig<LinearResponse> = {
'linear_update_project',
],
},
wandConfig: {
enabled: true,
prompt: `Generate a detailed description based on the user's description.
The description should:
- Provide context and details
- Include acceptance criteria or requirements when applicable
- Be professional and clear
Return ONLY the description text - no explanations.`,
placeholder: 'Describe the details (e.g., "users report errors when logging in")...',
},
},
// Comment body
{
@@ -348,6 +370,18 @@ export const LinearBlock: BlockConfig<LinearResponse> = {
field: 'operation',
value: ['linear_create_comment', 'linear_update_comment', 'linear_create_project_update'],
},
wandConfig: {
enabled: true,
prompt: `Generate a comment or project update based on the user's description.
The comment should:
- Be professional and informative
- Provide relevant updates or information
- Be suitable for team collaboration
Return ONLY the comment text - no explanations.`,
placeholder:
'Describe what you want to communicate (e.g., "progress update", "request for review")...',
},
},
// Comment ID
{
@@ -476,6 +510,18 @@ export const LinearBlock: BlockConfig<LinearResponse> = {
field: 'operation',
value: ['linear_search_issues'],
},
wandConfig: {
enabled: true,
prompt: `Generate a search query for Linear issues based on the user's description.
The query should:
- Be specific and targeted
- Use relevant keywords
- Be suitable for finding issues
Return ONLY the search query - no explanations.`,
placeholder:
'Describe what you want to search for (e.g., "open bugs", "my assigned tasks")...',
},
},
// Include archived (for list operations)
{
@@ -509,6 +555,19 @@ export const LinearBlock: BlockConfig<LinearResponse> = {
field: 'operation',
value: ['linear_create_cycle', 'linear_create_project'],
},
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Today's date
- "next Monday" -> Calculate the next Monday
- "start of next month" -> First day of next month
- "in 2 weeks" -> Calculate 14 days from now
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date (e.g., "next Monday", "start of next month")...',
generationType: 'timestamp',
},
},
{
id: 'endDate',
@@ -519,6 +578,19 @@ export const LinearBlock: BlockConfig<LinearResponse> = {
field: 'operation',
value: ['linear_create_cycle'],
},
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "in 2 weeks" -> Calculate 14 days from now
- "end of month" -> Last day of current month
- "next Friday" -> Calculate the next Friday
- "end of quarter" -> Last day of current quarter
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end date (e.g., "in 2 weeks", "end of month")...',
generationType: 'timestamp',
},
},
// Target date (for projects)
{
@@ -530,6 +602,19 @@ export const LinearBlock: BlockConfig<LinearResponse> = {
field: 'operation',
value: ['linear_create_project', 'linear_update_project'],
},
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "end of quarter" -> Last day of current quarter
- "in 3 months" -> Calculate 3 months from now
- "end of year" -> December 31 of current year
- "next month" -> First day of next month
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the target date (e.g., "end of quarter", "in 3 months")...',
generationType: 'timestamp',
},
},
// Attachment URL
{
@@ -849,6 +934,18 @@ export const LinearBlock: BlockConfig<LinearResponse> = {
field: 'operation',
value: ['linear_create_customer_request', 'linear_update_customer_request'],
},
wandConfig: {
enabled: true,
prompt: `Generate a customer request description based on the user's description.
The description should:
- Clearly explain the customer's need or request
- Include relevant context and details
- Be professional and suitable for product feedback
Return ONLY the description text - no explanations.`,
placeholder:
'Describe the customer request (e.g., "need bulk export feature", "integration with Slack")...',
},
},
// Customer request priority/urgency
{
@@ -1098,6 +1195,19 @@ export const LinearBlock: BlockConfig<LinearResponse> = {
field: 'operation',
value: ['linear_create_project_milestone', 'linear_update_project_milestone'],
},
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "in 2 weeks" -> Calculate 14 days from now
- "end of sprint" -> Calculate based on typical 2-week sprint
- "next milestone" -> Calculate a reasonable next milestone date
- "end of month" -> Last day of current month
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the milestone target date (e.g., "in 2 weeks", "end of month")...',
generationType: 'timestamp',
},
},
// Project status fields
{

View File

@@ -61,12 +61,38 @@ export const LinkupBlock: BlockConfig<LinkupSearchToolResponse> = {
title: 'From Date',
type: 'short-input',
placeholder: 'YYYY-MM-DD',
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "last week" -> Calculate 7 days ago
- "beginning of this month" -> First day of current month
- "last year" -> January 1 of last year
- "3 months ago" -> Calculate 3 months ago
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the from date (e.g., "last week", "beginning of this month")...',
generationType: 'timestamp',
},
},
{
id: 'toDate',
title: 'To Date',
type: 'short-input',
placeholder: 'YYYY-MM-DD',
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Today's date
- "yesterday" -> Yesterday's date
- "end of last month" -> Last day of previous month
- "now" -> Today's date
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the to date (e.g., "today", "end of last month")...',
generationType: 'timestamp',
},
},
{
id: 'includeDomains',

View File

@@ -221,6 +221,23 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_audience', 'update_audience'],
},
wandConfig: {
enabled: true,
prompt: `Generate a clear, descriptive name for a Mailchimp audience/mailing list based on the user's description.
### GUIDELINES
- Keep it concise but descriptive (2-5 words typically)
- Make it easy to identify the audience purpose
- Use professional naming conventions
### EXAMPLES
"Newsletter subscribers" -> "Newsletter Subscribers"
"Customers who bought product X" -> "Product X Customers"
"Event attendees from 2024" -> "2024 Event Attendees"
Return ONLY the audience name - no explanations.`,
placeholder: 'Describe the audience...',
},
},
{
id: 'contact',
@@ -235,6 +252,25 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_audience', 'update_audience'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object with contact information for a Mailchimp audience based on the user's description.
### REQUIRED FIELDS
- company: Company or organization name
- address1: Street address
- city: City name
- state: State/province
- zip: Postal/ZIP code
- country: Country code (e.g., "US", "CA", "GB")
### EXAMPLE OUTPUT
{"company": "Acme Corp", "address1": "123 Main Street", "city": "San Francisco", "state": "CA", "zip": "94102", "country": "US"}
Return ONLY the JSON object - no explanations or markdown.`,
placeholder: 'Describe the company contact info...',
generationType: 'json-object',
},
},
{
id: 'permissionReminder',
@@ -249,6 +285,25 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_audience', 'update_audience'],
},
wandConfig: {
enabled: true,
prompt: `Generate a permission reminder message for a Mailchimp audience based on the user's description.
This text reminds subscribers how they signed up and why they're receiving emails.
### GUIDELINES
- Be clear about how they joined the list
- Keep it concise (1-2 sentences)
- Make it friendly and professional
### EXAMPLES
"Newsletter signup" -> "You signed up for our newsletter on our website."
"Event registration" -> "You're receiving this email because you registered for one of our events."
"Product purchase" -> "You subscribed to updates when you made a purchase from our store."
Return ONLY the permission reminder text - no explanations.`,
placeholder: 'Describe how subscribers joined...',
},
},
{
id: 'campaignDefaults',
@@ -263,6 +318,23 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_audience', 'update_audience'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object with campaign default settings for a Mailchimp audience based on the user's description.
### REQUIRED FIELDS
- from_name: Sender name that appears in emails
- from_email: Sender email address
- subject: Default email subject line
- language: Language code (e.g., "en" for English)
### EXAMPLE OUTPUT
{"from_name": "Acme Marketing", "from_email": "marketing@acme.com", "subject": "News from Acme", "language": "en"}
Return ONLY the JSON object - no explanations or markdown.`,
placeholder: 'Describe the campaign defaults...',
generationType: 'json-object',
},
},
{
id: 'emailTypeOption',
@@ -395,6 +467,24 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['add_member', 'add_or_update_member', 'update_member'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object with merge field values for a Mailchimp subscriber based on the user's description.
### COMMON MERGE FIELDS
- FNAME: First name
- LNAME: Last name
- PHONE: Phone number
- BIRTHDAY: Birthday (MM/DD format)
- ADDRESS: Mailing address
### EXAMPLE OUTPUT
{"FNAME": "John", "LNAME": "Doe", "PHONE": "+1-555-123-4567"}
Return ONLY the JSON object - no explanations or markdown.`,
placeholder: 'Describe the subscriber info...',
generationType: 'json-object',
},
},
{
id: 'interests',
@@ -405,6 +495,21 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['add_member', 'add_or_update_member', 'update_member'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object with interest group settings for a Mailchimp subscriber.
Interest IDs map to boolean values indicating whether the subscriber is interested in that category.
### EXAMPLE OUTPUT
{"abc123def456": true, "xyz789ghi012": false, "mno345pqr678": true}
Note: You'll need actual interest IDs from your Mailchimp audience. Use Get Interest Categories to find them.
Return ONLY the JSON object - no explanations or markdown.`,
placeholder: 'Describe the interests to set...',
generationType: 'json-object',
},
},
{
id: 'tags',
@@ -419,6 +524,21 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['add_member_tags', 'remove_member_tags'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of tag objects for Mailchimp member tagging based on the user's description.
### TAG OBJECT FORMAT
- name: Tag name
- status: "active" to add, "inactive" to remove
### EXAMPLE OUTPUT
[{"name": "VIP Customer", "status": "active"}, {"name": "Newsletter", "status": "active"}]
Return ONLY the JSON array - no explanations or markdown.`,
placeholder: 'Describe the tags to add or remove...',
generationType: 'json-object',
},
},
// Campaign fields
{
@@ -490,6 +610,24 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_campaign', 'update_campaign'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object with campaign settings for a Mailchimp email campaign based on the user's description.
### COMMON SETTINGS
- subject_line: Email subject line
- preview_text: Preview text shown in inbox
- from_name: Sender name
- reply_to: Reply-to email address
- title: Internal campaign title
### EXAMPLE OUTPUT
{"subject_line": "Your Weekly Newsletter", "preview_text": "Check out what's new this week", "from_name": "Acme Team", "reply_to": "hello@acme.com", "title": "Weekly Newsletter - Jan 2024"}
Return ONLY the JSON object - no explanations or markdown.`,
placeholder: 'Describe the campaign settings...',
generationType: 'json-object',
},
},
{
id: 'recipients',
@@ -500,6 +638,26 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_campaign', 'update_campaign'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object defining campaign recipients for a Mailchimp campaign based on the user's description.
### REQUIRED FIELDS
- list_id: The audience/list ID to send to
### OPTIONAL FIELDS
- segment_opts: Segment filtering options
- saved_segment_id: ID of a saved segment
- match: "any" or "all" for condition matching
- conditions: Array of filter conditions
### EXAMPLE OUTPUT
{"list_id": "abc123def", "segment_opts": {"saved_segment_id": 12345}}
Return ONLY the JSON object - no explanations or markdown.`,
placeholder: 'Describe the recipients...',
generationType: 'json-object',
},
},
{
id: 'scheduleTime',
@@ -514,6 +672,21 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['schedule_campaign'],
},
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp with timezone offset based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SS+00:00 (with timezone offset).
Examples:
- "tomorrow at 10am" -> Tomorrow's date at 10:00:00+00:00
- "next Monday at 9am EST" -> Next Monday at 09:00:00-05:00
- "in 2 hours" -> Current time plus 2 hours with appropriate timezone
- "next week Tuesday at noon" -> Calculate next Tuesday at 12:00:00+00:00
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder:
'Describe when to schedule (e.g., "tomorrow at 10am", "next Monday at 9am")...',
generationType: 'timestamp',
},
},
{
id: 'html',
@@ -524,6 +697,31 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['set_campaign_content'],
},
wandConfig: {
enabled: true,
prompt: `Generate HTML email content for a Mailchimp campaign based on the user's description.
### GUIDELINES
- Use inline CSS for styling (email clients don't support external stylesheets)
- Keep the design simple and mobile-friendly
- Use tables for layout (better email client support)
- Include proper structure with header, body, and footer sections
### EXAMPLE STRUCTURE
<html>
<body style="font-family: Arial, sans-serif; margin: 0; padding: 20px;">
<table width="100%" cellpadding="0" cellspacing="0">
<tr><td style="padding: 20px; background: #f4f4f4;">
<h1 style="color: #333;">Your Title</h1>
<p style="color: #666;">Your content here...</p>
</td></tr>
</table>
</body>
</html>
Return ONLY the HTML content - no explanations or markdown.`,
placeholder: 'Describe the email content...',
},
},
{
id: 'plainText',
@@ -534,6 +732,34 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['set_campaign_content'],
},
wandConfig: {
enabled: true,
prompt: `Generate plain text email content for a Mailchimp campaign based on the user's description.
### GUIDELINES
- Use clear formatting with line breaks
- Keep paragraphs short and readable
- Include clear calls-to-action with full URLs
- Use dashes or asterisks for bullet points
### EXAMPLE
Hello [FNAME],
Thank you for subscribing to our newsletter!
Here's what's new this week:
- Feature update #1
- Exciting announcement
- Upcoming events
Visit our website: https://example.com
Best regards,
The Team
Return ONLY the plain text content - no explanations.`,
placeholder: 'Describe the email content...',
},
},
{
id: 'templateId',
@@ -562,6 +788,23 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_template', 'update_template'],
},
wandConfig: {
enabled: true,
prompt: `Generate a descriptive name for a Mailchimp email template based on the user's description.
### GUIDELINES
- Keep it clear and identifiable
- Include the purpose or use case
- Use professional naming conventions
### EXAMPLES
"Welcome email template" -> "Welcome Email Template"
"Monthly newsletter design" -> "Monthly Newsletter Template"
"Product announcement" -> "Product Announcement Template"
Return ONLY the template name - no explanations.`,
placeholder: 'Describe the template...',
},
},
{
id: 'templateHtml',
@@ -576,6 +819,35 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_template', 'update_template'],
},
wandConfig: {
enabled: true,
prompt: `Generate HTML content for a Mailchimp email template based on the user's description.
### GUIDELINES
- Use mc:edit regions for editable content areas
- Use inline CSS for styling
- Design for mobile-first responsiveness
- Include proper Mailchimp merge tags (*|FNAME|*, *|CURRENT_YEAR|*, etc.)
### EXAMPLE STRUCTURE
<html>
<body style="font-family: Arial, sans-serif;">
<div mc:edit="header">
<h1>*|MC:SUBJECT|*</h1>
</div>
<div mc:edit="body_content">
<p>Hello *|FNAME|*,</p>
<p>Your content here...</p>
</div>
<div mc:edit="footer">
<p>&copy; *|CURRENT_YEAR|* Your Company</p>
</div>
</body>
</html>
Return ONLY the HTML content - no explanations or markdown.`,
placeholder: 'Describe the template design...',
},
},
// Automation fields
{
@@ -658,6 +930,23 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_segment', 'update_segment'],
},
wandConfig: {
enabled: true,
prompt: `Generate a descriptive name for a Mailchimp audience segment based on the user's description.
### GUIDELINES
- Make it clear who is in the segment
- Keep it concise but informative
- Use professional naming conventions
### EXAMPLES
"Active customers last 30 days" -> "Active Customers - Last 30 Days"
"High value subscribers" -> "High-Value Subscribers"
"Users who opened last campaign" -> "Last Campaign Openers"
Return ONLY the segment name - no explanations.`,
placeholder: 'Describe the segment...',
},
},
{
id: 'segmentOptions',
@@ -668,6 +957,27 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_segment', 'update_segment'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object with segment conditions for a Mailchimp audience segment based on the user's description.
### SEGMENT OPTIONS FORMAT
- match: "any" or "all" (how conditions combine)
- conditions: Array of condition objects
### CONDITION OBJECT FIELDS
- condition_type: Type of condition (e.g., "EmailActivity", "DateMerge", "TextMerge")
- field: The field to check
- op: Operator (e.g., "is", "contains", "greater", "less")
- value: The value to compare
### EXAMPLE OUTPUT
{"match": "all", "conditions": [{"condition_type": "EmailActivity", "field": "campaign_id", "op": "open", "value": "abc123"}]}
Return ONLY the JSON object - no explanations or markdown.`,
placeholder: 'Describe the segment conditions...',
generationType: 'json-object',
},
},
// Merge field fields
{
@@ -697,6 +1007,25 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_merge_field', 'update_merge_field'],
},
wandConfig: {
enabled: true,
prompt: `Generate a name for a Mailchimp merge field based on the user's description.
Merge fields are custom fields that store subscriber data.
### GUIDELINES
- Use descriptive, clear names
- Keep it concise
- Use Title Case
### EXAMPLES
"Customer phone number" -> "Phone Number"
"Company size" -> "Company Size"
"Preferred language" -> "Preferred Language"
Return ONLY the merge field name - no explanations.`,
placeholder: 'Describe the merge field...',
},
},
{
id: 'mergeType',
@@ -770,6 +1099,25 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_interest_category', 'update_interest_category'],
},
wandConfig: {
enabled: true,
prompt: `Generate a title for a Mailchimp interest category based on the user's description.
Interest categories group related subscriber preferences.
### GUIDELINES
- Make it descriptive of the category
- Keep it concise
- Use Title Case
### EXAMPLES
"Product preferences" -> "Product Preferences"
"Communication frequency" -> "Communication Preferences"
"Topics of interest" -> "Topics of Interest"
Return ONLY the category title - no explanations.`,
placeholder: 'Describe the interest category...',
},
},
{
id: 'interestCategoryType',
@@ -818,6 +1166,25 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_interest', 'update_interest'],
},
wandConfig: {
enabled: true,
prompt: `Generate a name for a Mailchimp interest option based on the user's description.
Interests are individual options within an interest category.
### GUIDELINES
- Make it clear and specific
- Keep it concise
- Use Title Case
### EXAMPLES
"Weekly email updates" -> "Weekly Updates"
"Product announcements" -> "Product Announcements"
"Special offers" -> "Special Offers & Promotions"
Return ONLY the interest name - no explanations.`,
placeholder: 'Describe the interest...',
},
},
// Landing page fields
{
@@ -855,6 +1222,23 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_landing_page', 'update_landing_page'],
},
wandConfig: {
enabled: true,
prompt: `Generate a title for a Mailchimp landing page based on the user's description.
### GUIDELINES
- Make it compelling and action-oriented
- Keep it concise
- Focus on the value proposition
### EXAMPLES
"Newsletter signup page" -> "Join Our Newsletter"
"Free ebook download" -> "Download Your Free Guide"
"Event registration" -> "Register for Our Exclusive Event"
Return ONLY the landing page title - no explanations.`,
placeholder: 'Describe the landing page...',
},
},
{
id: 'landingPageType',
@@ -901,6 +1285,26 @@ export const MailchimpBlock: BlockConfig = {
field: 'operation',
value: ['create_batch_operation'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of batch operations for Mailchimp based on the user's description.
### OPERATION OBJECT FORMAT
- method: HTTP method (GET, POST, PUT, PATCH, DELETE)
- path: API endpoint path
- operation_id: Unique identifier for the operation
- body: Request body (for POST/PUT/PATCH)
### EXAMPLE OUTPUT
[
{"method": "POST", "path": "/lists/abc123/members", "operation_id": "add_member_1", "body": {"email_address": "user@example.com", "status": "subscribed"}},
{"method": "POST", "path": "/lists/abc123/members", "operation_id": "add_member_2", "body": {"email_address": "user2@example.com", "status": "subscribed"}}
]
Return ONLY the JSON array - no explanations or markdown.`,
placeholder: 'Describe the batch operations...',
generationType: 'json-object',
},
},
// Pagination and filtering
{

View File

@@ -76,6 +76,24 @@ export const MailgunBlock: BlockConfig<SendMessageResult> = {
placeholder: 'Email subject',
condition: { field: 'operation', value: 'send_message' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a compelling email subject line based on the user's description.
### GUIDELINES
- Keep it concise (50 characters or less is ideal)
- Make it attention-grabbing
- Avoid spam trigger words
- Be clear about the email content
### EXAMPLES
"Welcome email for new users" -> "Welcome to Our Platform!"
"Order confirmation" -> "Your Order #12345 is Confirmed"
"Newsletter about new features" -> "New Features You'll Love"
Return ONLY the subject line - no explanations.`,
placeholder: 'Describe the email topic...',
},
},
{
id: 'text',
@@ -83,6 +101,33 @@ export const MailgunBlock: BlockConfig<SendMessageResult> = {
type: 'long-input',
placeholder: 'Plain text email body',
condition: { field: 'operation', value: 'send_message' },
wandConfig: {
enabled: true,
prompt: `Generate plain text email content based on the user's description.
### GUIDELINES
- Use clear, readable formatting
- Keep paragraphs short
- Include appropriate greeting and sign-off
- Use line breaks for readability
### EXAMPLE
Hello,
Thank you for your interest in our product.
Here are the details you requested:
- Point 1
- Point 2
Let us know if you have any questions.
Best regards,
The Team
Return ONLY the email body text - no explanations.`,
placeholder: 'Describe the email content...',
},
},
{
id: 'html',
@@ -90,6 +135,31 @@ export const MailgunBlock: BlockConfig<SendMessageResult> = {
type: 'code',
placeholder: '<html><body>HTML email body</body></html>',
condition: { field: 'operation', value: 'send_message' },
wandConfig: {
enabled: true,
prompt: `Generate HTML email content based on the user's description.
### GUIDELINES
- Use inline CSS for styling (email clients don't support external stylesheets)
- Keep the design simple and mobile-friendly
- Use tables for layout (better email client support)
- Include proper structure
### EXAMPLE STRUCTURE
<html>
<body style="font-family: Arial, sans-serif; margin: 0; padding: 20px;">
<table width="100%" cellpadding="0" cellspacing="0">
<tr><td style="padding: 20px; background: #f4f4f4;">
<h1 style="color: #333;">Your Title</h1>
<p style="color: #666;">Your content here...</p>
</td></tr>
</table>
</body>
</html>
Return ONLY the HTML content - no explanations or markdown.`,
placeholder: 'Describe the email content...',
},
},
{
id: 'cc',
@@ -165,6 +235,23 @@ export const MailgunBlock: BlockConfig<SendMessageResult> = {
type: 'short-input',
placeholder: 'My Mailing List',
condition: { field: 'operation', value: 'create_mailing_list' },
wandConfig: {
enabled: true,
prompt: `Generate a name for a Mailgun mailing list based on the user's description.
### GUIDELINES
- Keep it clear and descriptive
- Use professional naming conventions
- Make it easy to identify the list purpose
### EXAMPLES
"Newsletter subscribers" -> "Newsletter Subscribers"
"Beta testers" -> "Beta Testers"
"Customer updates" -> "Customer Updates List"
Return ONLY the list name - no explanations.`,
placeholder: 'Describe the mailing list...',
},
},
{
id: 'description',
@@ -172,6 +259,22 @@ export const MailgunBlock: BlockConfig<SendMessageResult> = {
type: 'long-input',
placeholder: 'Description of the mailing list',
condition: { field: 'operation', value: 'create_mailing_list' },
wandConfig: {
enabled: true,
prompt: `Generate a description for a Mailgun mailing list based on the user's description.
### GUIDELINES
- Explain the purpose of the list
- Keep it concise but informative
- Mention what subscribers will receive
### EXAMPLES
"Newsletter for product updates" -> "Subscribers receive weekly updates about new features, product announcements, and company news."
"Beta program list" -> "Early access program members who test new features before public release."
Return ONLY the description text - no explanations.`,
placeholder: 'Describe the purpose of the list...',
},
},
{
id: 'accessLevel',
@@ -207,6 +310,22 @@ export const MailgunBlock: BlockConfig<SendMessageResult> = {
type: 'code',
placeholder: '{"key": "value"}',
condition: { field: 'operation', value: 'add_list_member' },
wandConfig: {
enabled: true,
prompt: `Generate a JSON object with custom variables for a Mailgun mailing list member based on the user's description.
### GUIDELINES
- Use descriptive key names
- Include relevant member data
- Keep values properly typed
### EXAMPLE OUTPUT
{"first_name": "John", "last_name": "Doe", "company": "Acme Corp", "plan": "premium"}
Return ONLY the JSON object - no explanations or markdown.`,
placeholder: 'Describe the member data...',
generationType: 'json-object',
},
},
{
id: 'subscribed',

View File

@@ -75,6 +75,19 @@ export const Mem0Block: BlockConfig<Mem0Response> = {
field: 'operation',
value: 'get',
},
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "last week" -> Calculate 7 days ago
- "beginning of this month" -> First day of current month
- "30 days ago" -> Calculate 30 days ago
- "start of year" -> January 1 of current year
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date (e.g., "last week", "30 days ago")...',
generationType: 'timestamp',
},
},
{
id: 'endDate',
@@ -85,6 +98,19 @@ export const Mem0Block: BlockConfig<Mem0Response> = {
field: 'operation',
value: 'get',
},
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Today's date
- "yesterday" -> Yesterday's date
- "end of last week" -> Last Sunday's date
- "now" -> Today's date
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end date (e.g., "today", "yesterday")...',
generationType: 'timestamp',
},
},
{
id: 'apiKey',

View File

@@ -190,6 +190,20 @@ export const MicrosoftPlannerBlock: BlockConfig<MicrosoftPlannerResponse> = {
type: 'short-input',
placeholder: 'Enter due date in ISO 8601 format (e.g., 2024-12-31T23:59:59Z)',
condition: { field: 'operation', value: ['create_task', 'update_task'] },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description for Microsoft Planner task due date.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "tomorrow" -> Calculate tomorrow's date at 23:59:59Z
- "next Friday" -> Calculate the next Friday at 17:00:00Z
- "end of the month" -> Calculate the last day of the current month at 23:59:59Z
- "in 3 days" -> Calculate 3 days from now at 17:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the due date (e.g., "next Friday", "end of the month")...',
generationType: 'timestamp',
},
},
// Start Date
@@ -199,6 +213,20 @@ export const MicrosoftPlannerBlock: BlockConfig<MicrosoftPlannerResponse> = {
type: 'short-input',
placeholder: 'Enter start date in ISO 8601 format (optional)',
condition: { field: 'operation', value: ['update_task'] },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description for Microsoft Planner task start date.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "today" -> Calculate today's date at 09:00:00Z
- "next Monday" -> Calculate the next Monday at 09:00:00Z
- "beginning of next week" -> Calculate the next Monday at 09:00:00Z
- "tomorrow morning" -> Calculate tomorrow's date at 09:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date (e.g., "next Monday", "tomorrow morning")...',
generationType: 'timestamp',
},
},
// Assignee

View File

@@ -90,6 +90,12 @@ export const NotionBlock: BlockConfig<NotionResponse> = {
field: 'operation',
value: 'notion_create_page',
},
wandConfig: {
enabled: true,
prompt:
"Generate a concise, descriptive title for a Notion page based on the user's description. The title should be clear and professional. Return ONLY the title text - no explanations, no quotes.",
placeholder: 'Describe what the page is about...',
},
},
// Content input for write/create operations
{
@@ -102,6 +108,12 @@ export const NotionBlock: BlockConfig<NotionResponse> = {
value: 'notion_write',
},
required: true,
wandConfig: {
enabled: true,
prompt:
"Generate content to append to a Notion page based on the user's description. The content can include paragraphs, lists, headings, and other text elements. Format it appropriately for Notion. Return ONLY the content - no explanations.",
placeholder: 'Describe the content you want to add...',
},
},
{
id: 'content',
@@ -113,6 +125,12 @@ export const NotionBlock: BlockConfig<NotionResponse> = {
value: 'notion_create_page',
},
required: true,
wandConfig: {
enabled: true,
prompt:
"Generate content for a new Notion page based on the user's description. The content can include paragraphs, lists, headings, and other text elements. Format it appropriately for Notion. Return ONLY the content - no explanations.",
placeholder: 'Describe the content you want to create...',
},
},
// Query Database Fields
{
@@ -130,6 +148,14 @@ export const NotionBlock: BlockConfig<NotionResponse> = {
placeholder: 'Enter filter conditions as JSON (optional)',
condition: { field: 'operation', value: 'notion_query_database' },
required: true,
wandConfig: {
enabled: true,
prompt:
'Generate a Notion database filter object in JSON format based on the user\'s description. Notion filters use properties like "property", "equals", "contains", "checkbox", "date", etc. Example: {"property": "Status", "select": {"equals": "Done"}}. For compound filters use "and" or "or" arrays. Return ONLY valid JSON - no explanations.',
placeholder:
'Describe what you want to filter (e.g., "status is done", "created after last week")...',
generationType: 'json-object',
},
},
{
id: 'sorts',
@@ -137,6 +163,13 @@ export const NotionBlock: BlockConfig<NotionResponse> = {
type: 'long-input',
placeholder: 'Enter sort criteria as JSON array (optional)',
condition: { field: 'operation', value: 'notion_query_database' },
wandConfig: {
enabled: true,
prompt:
'Generate a Notion database sort criteria array in JSON format based on the user\'s description. Each sort object has "property" (property name) or "timestamp" ("created_time" or "last_edited_time") and "direction" ("ascending" or "descending"). Example: [{"property": "Name", "direction": "ascending"}]. Return ONLY a valid JSON array - no explanations.',
placeholder: 'Describe how to sort (e.g., "by name ascending", "newest first")...',
generationType: 'json-object',
},
},
{
id: 'pageSize',
@@ -152,6 +185,12 @@ export const NotionBlock: BlockConfig<NotionResponse> = {
type: 'short-input',
placeholder: 'Enter search terms (leave empty for all pages)',
condition: { field: 'operation', value: 'notion_search' },
wandConfig: {
enabled: true,
prompt:
"Generate a search query string for searching a Notion workspace based on the user's description. The query should be concise and use relevant keywords. Return ONLY the search query text - no explanations, no quotes.",
placeholder: 'Describe what you want to search for...',
},
},
{
id: 'filterType',
@@ -180,6 +219,12 @@ export const NotionBlock: BlockConfig<NotionResponse> = {
placeholder: 'Title for the new database',
condition: { field: 'operation', value: 'notion_create_database' },
required: true,
wandConfig: {
enabled: true,
prompt:
"Generate a concise, descriptive title for a Notion database based on the user's description. The title should clearly indicate what data the database will contain. Return ONLY the title text - no explanations, no quotes.",
placeholder: 'Describe what the database will track...',
},
},
{
id: 'properties',
@@ -187,6 +232,14 @@ export const NotionBlock: BlockConfig<NotionResponse> = {
type: 'long-input',
placeholder: 'Enter database properties as JSON object',
condition: { field: 'operation', value: 'notion_create_database' },
wandConfig: {
enabled: true,
prompt:
'Generate Notion database properties in JSON format based on the user\'s description. Properties define the schema of the database. Common types: "title" (required), "rich_text", "number", "select" (with options), "multi_select", "date", "checkbox", "url", "email", "phone_number". Example: {"Name": {"title": {}}, "Status": {"select": {"options": [{"name": "To Do"}, {"name": "Done"}]}}, "Priority": {"number": {}}}. Return ONLY valid JSON - no explanations.',
placeholder:
'Describe the columns/properties you want (e.g., "name, status dropdown, due date, priority number")...',
generationType: 'json-object',
},
},
],
tools: {

View File

@@ -128,6 +128,20 @@ export const PerplexityBlock: BlockConfig<PerplexityResponse> = {
type: 'short-input',
placeholder: 'MM/DD/YYYY',
condition: { field: 'operation', value: 'perplexity_search' },
wandConfig: {
enabled: true,
prompt: `Generate a date in MM/DD/YYYY format based on the user's description for Perplexity search "after date" filter.
This filters results to only include content published after this date.
Examples:
- "last week" -> Calculate 7 days ago in MM/DD/YYYY format
- "beginning of this year" -> 01/01/[current year]
- "3 months ago" -> Calculate 3 months ago in MM/DD/YYYY format
- "last January" -> 01/01/[last year or current year depending on context]
Return ONLY the date string in MM/DD/YYYY format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "last week", "beginning of this year")...',
generationType: 'timestamp',
},
},
{
id: 'search_before_date',
@@ -135,6 +149,20 @@ export const PerplexityBlock: BlockConfig<PerplexityResponse> = {
type: 'short-input',
placeholder: 'MM/DD/YYYY',
condition: { field: 'operation', value: 'perplexity_search' },
wandConfig: {
enabled: true,
prompt: `Generate a date in MM/DD/YYYY format based on the user's description for Perplexity search "before date" filter.
This filters results to only include content published before this date.
Examples:
- "today" -> Calculate today's date in MM/DD/YYYY format
- "end of last month" -> Last day of previous month in MM/DD/YYYY format
- "6 months ago" -> Calculate 6 months ago in MM/DD/YYYY format
- "end of 2023" -> 12/31/2023
Return ONLY the date string in MM/DD/YYYY format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "end of last month", "today")...',
generationType: 'timestamp',
},
},
{
id: 'apiKey',

View File

@@ -52,6 +52,13 @@ export const PineconeBlock: BlockConfig<PineconeResponse> = {
placeholder: '[{"text": "Your text here"}]',
condition: { field: 'operation', value: 'generate' },
required: true,
wandConfig: {
enabled: true,
prompt:
'Generate a JSON array of text inputs for embedding generation based on the user\'s description. Each item should be an object with a "text" field. Example: [{"text": "First text"}, {"text": "Second text"}]. Return ONLY valid JSON - no explanations.',
placeholder: 'Describe the texts you want to embed...',
generationType: 'json-object',
},
},
// Upsert text fields
{
@@ -78,6 +85,13 @@ export const PineconeBlock: BlockConfig<PineconeResponse> = {
'{"_id": "rec1", "text": "Apple\'s first product, the Apple I, was released in 1976.", "category": "product"}\n{"_id": "rec2", "chunk_text": "Apples are a great source of dietary fiber.", "category": "nutrition"}',
condition: { field: 'operation', value: 'upsert_text' },
required: true,
wandConfig: {
enabled: true,
prompt:
'Generate newline-delimited JSON records for upserting to Pinecone based on the user\'s description. Each line should be a JSON object with "_id", "text" (or "chunk_text"), and optional metadata fields like "category". Return ONLY the newline-delimited JSON records - no explanations.',
placeholder: 'Describe the records you want to upsert...',
generationType: 'json-object',
},
},
// Search text fields
{
@@ -103,6 +117,12 @@ export const PineconeBlock: BlockConfig<PineconeResponse> = {
placeholder: 'Enter text to search for',
condition: { field: 'operation', value: 'search_text' },
required: true,
wandConfig: {
enabled: true,
prompt:
"Generate a search query for semantic search in Pinecone based on the user's description. The query should capture the semantic meaning of what the user wants to find. Return ONLY the search query text - no explanations, no quotes.",
placeholder: 'Describe what you want to search for...',
},
},
{
id: 'topK',
@@ -117,6 +137,13 @@ export const PineconeBlock: BlockConfig<PineconeResponse> = {
type: 'long-input',
placeholder: '["category", "text"]',
condition: { field: 'operation', value: 'search_text' },
wandConfig: {
enabled: true,
prompt:
'Generate a JSON array of field names to return from Pinecone search results based on the user\'s description. Example: ["category", "text", "date"]. Return ONLY a valid JSON array - no explanations.',
placeholder: 'Describe which fields you want returned...',
generationType: 'json-object',
},
},
{
id: 'filter',
@@ -124,6 +151,13 @@ export const PineconeBlock: BlockConfig<PineconeResponse> = {
type: 'long-input',
placeholder: '{"category": "product"}',
condition: { field: 'operation', value: 'search_text' },
wandConfig: {
enabled: true,
prompt:
'Generate a Pinecone metadata filter object in JSON format based on the user\'s description. Use operators like $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin for comparisons, and $and, $or for combining conditions. Example: {"category": {"$eq": "product"}}. Return ONLY valid JSON - no explanations.',
placeholder: 'Describe how you want to filter results...',
generationType: 'json-object',
},
},
{
id: 'rerank',
@@ -131,6 +165,13 @@ export const PineconeBlock: BlockConfig<PineconeResponse> = {
type: 'long-input',
placeholder: '{"model": "bge-reranker-v2-m3", "rank_fields": ["text"], "top_n": 2}',
condition: { field: 'operation', value: 'search_text' },
wandConfig: {
enabled: true,
prompt:
'Generate Pinecone rerank options in JSON format based on the user\'s description. Include "model" (e.g., "bge-reranker-v2-m3"), "rank_fields" (array of fields to use for reranking), and optionally "top_n" (number of results to return after reranking). Return ONLY valid JSON - no explanations.',
placeholder: 'Describe your reranking preferences...',
generationType: 'json-object',
},
},
// Fetch fields
{
@@ -156,6 +197,13 @@ export const PineconeBlock: BlockConfig<PineconeResponse> = {
placeholder: '["vec1", "vec2"]',
condition: { field: 'operation', value: 'fetch' },
required: true,
wandConfig: {
enabled: true,
prompt:
'Generate a JSON array of vector IDs to fetch from Pinecone based on the user\'s description. Example: ["vec1", "vec2", "vec3"]. Return ONLY a valid JSON array - no explanations.',
placeholder: 'Describe which vector IDs to fetch...',
generationType: 'json-object',
},
},
// Add vector search fields
{
@@ -181,6 +229,13 @@ export const PineconeBlock: BlockConfig<PineconeResponse> = {
placeholder: '[0.1, 0.2, 0.3, ...]',
condition: { field: 'operation', value: 'search_vector' },
required: true,
wandConfig: {
enabled: true,
prompt:
"Generate a JSON array representing a query vector for Pinecone vector search based on the user's description. The array should contain floating-point numbers. Note: For semantic search, you typically generate this from an embedding model, but if you need a sample vector, provide an array of floats. Return ONLY a valid JSON array - no explanations.",
placeholder: 'Describe the vector or paste embedding values...',
generationType: 'json-object',
},
},
{
id: 'topK',

View File

@@ -98,6 +98,19 @@ export const PipedriveBlock: BlockConfig<PipedriveResponse> = {
type: 'short-input',
placeholder: 'Date (2025-01-01T10:20:00Z)',
condition: { field: 'operation', value: ['get_all_deals'] },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "yesterday" -> Calculate yesterday's date at 00:00:00Z
- "last week" -> Calculate 7 days ago at 00:00:00Z
- "2 hours ago" -> Calculate the timestamp 2 hours before now
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "last week", "yesterday")...',
generationType: 'timestamp',
},
},
{
id: 'limit',
@@ -182,6 +195,18 @@ export const PipedriveBlock: BlockConfig<PipedriveResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD ',
condition: { field: 'operation', value: ['create_deal', 'update_deal'] },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "next Friday" -> Calculate the next Friday's date
- "end of month" -> Calculate the last day of the current month
- "in 2 weeks" -> Calculate the date 14 days from now
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "next Friday", "end of month")...',
generationType: 'timestamp',
},
},
{
id: 'title',
@@ -365,6 +390,18 @@ export const PipedriveBlock: BlockConfig<PipedriveResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD ',
condition: { field: 'operation', value: ['create_project'] },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Today's date
- "next Monday" -> Calculate the next Monday's date
- "beginning of next month" -> The 1st of next month
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "today", "next Monday")...',
generationType: 'timestamp',
},
},
{
id: 'end_date',
@@ -372,6 +409,18 @@ export const PipedriveBlock: BlockConfig<PipedriveResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD ',
condition: { field: 'operation', value: ['create_project'] },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "end of month" -> Calculate the last day of the current month
- "in 3 weeks" -> Calculate the date 21 days from now
- "December 31st" -> 2024-12-31 (or next occurrence)
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "end of month", "in 3 weeks")...',
generationType: 'timestamp',
},
},
{
id: 'deal_id',
@@ -460,6 +509,18 @@ export const PipedriveBlock: BlockConfig<PipedriveResponse> = {
placeholder: 'YYYY-MM-DD',
required: true,
condition: { field: 'operation', value: ['create_activity', 'update_activity'] },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "tomorrow" -> Calculate tomorrow's date
- "next week" -> Calculate the date 7 days from now
- "this Friday" -> Calculate the coming Friday's date
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "tomorrow", "next week")...',
generationType: 'timestamp',
},
},
{
id: 'due_time',
@@ -467,6 +528,19 @@ export const PipedriveBlock: BlockConfig<PipedriveResponse> = {
type: 'short-input',
placeholder: 'HH:MM ',
condition: { field: 'operation', value: ['create_activity', 'update_activity'] },
wandConfig: {
enabled: true,
prompt: `Generate a time in HH:MM format (24-hour) based on the user's description.
Examples:
- "9am" -> 09:00
- "2:30 PM" -> 14:30
- "noon" -> 12:00
- "end of business day" -> 17:00
Return ONLY the time string in HH:MM format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the time (e.g., "9am", "2:30 PM")...',
generationType: 'timestamp',
},
},
{
id: 'duration',
@@ -575,6 +649,18 @@ export const PipedriveBlock: BlockConfig<PipedriveResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD',
condition: { field: 'operation', value: ['create_lead', 'update_lead'] },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "next quarter" -> Calculate the last day of the next quarter
- "in 30 days" -> Calculate the date 30 days from now
- "end of year" -> Calculate December 31st of the current year
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "next quarter", "in 30 days")...',
generationType: 'timestamp',
},
},
{
id: 'is_archived',

View File

@@ -170,6 +170,18 @@ export const PolymarketBlock: BlockConfig = {
type: 'short-input',
placeholder: 'Unix timestamp UTC (if no interval)',
condition: { field: 'operation', value: ['get_price_history'] },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp (seconds since epoch) based on the user's description.
Examples:
- "yesterday" -> Unix timestamp for yesterday at 00:00:00 UTC
- "last week" -> Unix timestamp for 7 days ago at 00:00:00 UTC
- "beginning of this month" -> Unix timestamp for the 1st of the current month at 00:00:00 UTC
Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start time (e.g., "last week", "beginning of month")...',
generationType: 'timestamp',
},
},
{
id: 'endTs',
@@ -177,6 +189,18 @@ export const PolymarketBlock: BlockConfig = {
type: 'short-input',
placeholder: 'Unix timestamp UTC (if no interval)',
condition: { field: 'operation', value: ['get_price_history'] },
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp (seconds since epoch) based on the user's description.
Examples:
- "now" -> Current Unix timestamp
- "yesterday" -> Unix timestamp for yesterday at 23:59:59 UTC
- "end of last week" -> Unix timestamp for last Sunday at 23:59:59 UTC
Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end time (e.g., "now", "end of last week")...',
generationType: 'timestamp',
},
},
// Filters for list operations
{

View File

@@ -212,6 +212,34 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
type: 'long-input',
placeholder: '{"key": "value"}',
condition: { field: 'operation', value: 'posthog_capture_event' },
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for PostHog event properties based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY valid JSON starting with { and ending with }
- Use camelCase or snake_case consistently for property names
- Include relevant properties for analytics tracking (e.g., $browser, $device, custom properties)
- Use appropriate data types (strings, numbers, booleans, arrays)
### EXAMPLE
User: "Track a purchase event with product info and price"
Output:
{
"product_id": "SKU-123",
"product_name": "Premium Plan",
"price": 99.99,
"currency": "USD",
"quantity": 1
}
Return ONLY the JSON object.`,
placeholder: 'Describe the event properties...',
generationType: 'json-object',
},
},
{
id: 'timestamp',
@@ -219,6 +247,19 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
type: 'short-input',
placeholder: '2024-01-01T12:00:00Z',
condition: { field: 'operation', value: 'posthog_capture_event' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "now" -> Current timestamp in ISO 8601 format
- "yesterday at 3pm" -> Yesterday's date at 15:00:00Z
- "last Monday" -> Last Monday's date at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the timestamp (e.g., "now", "yesterday at 3pm")...',
generationType: 'timestamp',
},
},
// Evaluate Flags fields
@@ -228,6 +269,31 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
type: 'long-input',
placeholder: '{"company": "company_id_in_your_db"}',
condition: { field: 'operation', value: 'posthog_evaluate_flags' },
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for PostHog groups based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY valid JSON starting with { and ending with }
- Group types are keys (e.g., "company", "team", "project")
- Group IDs are values (the unique identifier in your database)
- Common group types: company, organization, team, project, workspace
### EXAMPLE
User: "Evaluate for Acme Corp company and engineering team"
Output:
{
"company": "acme-corp-123",
"team": "engineering"
}
Return ONLY the JSON object.`,
placeholder: 'Describe the groups...',
generationType: 'json-object',
},
},
{
id: 'personProperties',
@@ -235,6 +301,33 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
type: 'long-input',
placeholder: '{"email": "user@example.com", "plan": "enterprise"}',
condition: { field: 'operation', value: 'posthog_evaluate_flags' },
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for PostHog person properties based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY valid JSON starting with { and ending with }
- Common properties: email, name, plan, role, created_at, subscription_status
- Use appropriate data types for each property
- These properties are used for feature flag evaluation
### EXAMPLE
User: "Enterprise user from the sales team signed up last month"
Output:
{
"email": "user@example.com",
"plan": "enterprise",
"department": "sales",
"signup_date": "2024-01-15"
}
Return ONLY the JSON object.`,
placeholder: 'Describe the person properties...',
generationType: 'json-object',
},
},
{
id: 'groupProperties',
@@ -252,6 +345,32 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
placeholder: '[{"event": "page_view", "distinct_id": "user123", "properties": {...}}]',
condition: { field: 'operation', value: 'posthog_batch_events' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of PostHog events for batch capture based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON array starting with [ and ending with ]
- Each event object must have: event (name), distinct_id (user identifier)
- Optional: properties, timestamp
- Common events: page_view, button_clicked, form_submitted, purchase_completed
### EXAMPLE
User: "Track 3 page views for user123 on the homepage, pricing, and checkout pages"
Output:
[
{"event": "page_view", "distinct_id": "user123", "properties": {"page": "/home"}},
{"event": "page_view", "distinct_id": "user123", "properties": {"page": "/pricing"}},
{"event": "page_view", "distinct_id": "user123", "properties": {"page": "/checkout"}}
]
Return ONLY the JSON array.`,
placeholder: 'Describe the batch of events...',
generationType: 'json-object',
},
},
// Query fields
@@ -298,6 +417,19 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
type: 'short-input',
placeholder: '2024-01-01T12:00:00Z',
condition: { field: 'operation', value: 'posthog_list_events' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "today" -> Today's date at 00:00:00Z
- "this week" -> The start of this week at 00:00:00Z
- "last month" -> The 1st of last month at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the cutoff date (e.g., "today", "this week")...',
generationType: 'timestamp',
},
},
{
id: 'after',
@@ -305,6 +437,19 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
type: 'short-input',
placeholder: '2024-01-01T00:00:00Z',
condition: { field: 'operation', value: 'posthog_list_events' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "yesterday" -> Yesterday's date at 00:00:00Z
- "last week" -> 7 days ago at 00:00:00Z
- "beginning of this month" -> The 1st of this month at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date (e.g., "yesterday", "last week")...',
generationType: 'timestamp',
},
},
{
id: 'distinctIdFilter',
@@ -457,6 +602,22 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
'posthog_update_property_definition',
],
},
wandConfig: {
enabled: true,
prompt: `Write a clear, concise description for a PostHog resource based on the user's request.
### CONTEXT
{context}
### GUIDELINES
- Be descriptive but concise (1-3 sentences)
- Explain the purpose and use case
- Include relevant context like target audience or business goal
- Use professional language
Return ONLY the description text.`,
placeholder: 'Describe what this resource is for...',
},
},
// Feature Flag specific fields
@@ -496,6 +657,37 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
'posthog_create_experiment',
],
},
wandConfig: {
enabled: true,
prompt: `Generate PostHog filters JSON based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY valid JSON starting with { and ending with }
- Use PostHog filter structure with "groups" array
- Each group can have "properties" array with conditions
- Property conditions include: key, value, operator (exact, icontains, regex, etc.)
### EXAMPLE
User: "Target users on the enterprise plan in the US"
Output:
{
"groups": [
{
"properties": [
{"key": "plan", "value": "enterprise", "operator": "exact"},
{"key": "$geoip_country_code", "value": "US", "operator": "exact"}
]
}
]
}
Return ONLY the JSON object.`,
placeholder: 'Describe the filter conditions...',
generationType: 'json-object',
},
},
// Insight specific fields
@@ -577,6 +769,26 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
placeholder: 'Annotation content',
condition: { field: 'operation', value: 'posthog_create_annotation' },
required: true,
wandConfig: {
enabled: true,
prompt: `Write annotation content for PostHog based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Be concise but informative
- Include relevant details (what happened, why it matters)
- Use clear language that team members can understand
- Mention impact if applicable (e.g., "deployed new feature", "fixed critical bug")
### EXAMPLE
User: "We deployed the new checkout flow today"
Output: Deployed new checkout flow v2.0 - simplified 5-step process to 3 steps. Expected improvement in conversion rate.
Return ONLY the annotation text.`,
placeholder: 'Describe the annotation...',
},
},
{
id: 'dateMarker',
@@ -585,6 +797,19 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
placeholder: '2024-01-01T12:00:00Z',
condition: { field: 'operation', value: 'posthog_create_annotation' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "today" -> Today's date at 00:00:00Z
- "when we launched" -> Parse the contextual date if given, otherwise today
- "January 15th" -> 2024-01-15T00:00:00Z (or next occurrence)
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the annotation date (e.g., "today", "release date")...',
generationType: 'timestamp',
},
},
{
id: 'scope',
@@ -627,6 +852,19 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
type: 'short-input',
placeholder: '2024-01-01T00:00:00Z',
condition: { field: 'operation', value: 'posthog_create_experiment' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "today" -> Today's date at 00:00:00Z
- "next Monday" -> Next Monday's date at 00:00:00Z
- "beginning of next month" -> The 1st of next month at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the experiment start date (e.g., "today", "next Monday")...',
generationType: 'timestamp',
},
},
{
id: 'experimentEndDate',
@@ -634,6 +872,19 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
type: 'short-input',
placeholder: '2024-12-31T23:59:59Z',
condition: { field: 'operation', value: 'posthog_create_experiment' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "in 2 weeks" -> 14 days from now at 23:59:59Z
- "end of month" -> Last day of current month at 23:59:59Z
- "end of Q1" -> March 31st at 23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the experiment end date (e.g., "in 2 weeks", "end of month")...',
generationType: 'timestamp',
},
},
// Survey fields
@@ -647,6 +898,31 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
value: 'posthog_create_survey',
},
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of PostHog survey questions based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON array starting with [ and ending with ]
- Question types: "open" (free text), "rating" (1-5 scale), "multiple_choice", "single_choice", "link"
- Each question needs: type, question (the text)
- For choice questions, include "choices" array
### EXAMPLE
User: "NPS survey asking how likely they are to recommend and why"
Output:
[
{"type": "rating", "question": "How likely are you to recommend us to a friend or colleague?", "scale": 10},
{"type": "open", "question": "What is the primary reason for your score?"}
]
Return ONLY the JSON array.`,
placeholder: 'Describe the survey questions...',
generationType: 'json-object',
},
},
{
id: 'questions',
@@ -657,6 +933,31 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
field: 'operation',
value: 'posthog_update_survey',
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of PostHog survey questions based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON array starting with [ and ending with ]
- Question types: "open" (free text), "rating" (1-5 scale), "multiple_choice", "single_choice", "link"
- Each question needs: type, question (the text)
- For choice questions, include "choices" array
### EXAMPLE
User: "Customer satisfaction survey with rating and feedback"
Output:
[
{"type": "rating", "question": "How satisfied are you with our product?", "scale": 5},
{"type": "open", "question": "How can we improve your experience?"}
]
Return ONLY the JSON array.`,
placeholder: 'Describe the survey questions...',
generationType: 'json-object',
},
},
{
id: 'surveyType',
@@ -681,6 +982,19 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
field: 'operation',
value: ['posthog_create_survey', 'posthog_update_survey'],
},
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "now" -> Current timestamp
- "tomorrow" -> Tomorrow's date at 00:00:00Z
- "next week" -> 7 days from now at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the survey start date (e.g., "now", "tomorrow")...',
generationType: 'timestamp',
},
},
{
id: 'surveyEndDate',
@@ -691,6 +1005,19 @@ export const PostHogBlock: BlockConfig<PostHogResponse> = {
field: 'operation',
value: ['posthog_create_survey', 'posthog_update_survey'],
},
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "in 1 month" -> 30 days from now at 23:59:59Z
- "end of quarter" -> Last day of current quarter at 23:59:59Z
- "December 31st" -> 2024-12-31T23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the survey end date (e.g., "in 1 month", "end of quarter")...',
generationType: 'timestamp',
},
},
{
id: 'appearance',

View File

@@ -50,6 +50,31 @@ export const QdrantBlock: BlockConfig<QdrantResponse> = {
placeholder: '[{"id": 1, "vector": [0.1, 0.2], "payload": {"category": "a"}}]',
condition: { field: 'operation', value: 'upsert' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of Qdrant points for vector database upsert based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON array starting with [ and ending with ]
- Each point must have: id (number or string UUID), vector (array of floats)
- Optional: payload (object with metadata)
- Vector dimensions must match the collection's configuration
### EXAMPLE
User: "Create 2 points for product embeddings with category and price"
Output:
[
{"id": 1, "vector": [0.1, 0.2, 0.3], "payload": {"category": "electronics", "price": 299.99}},
{"id": 2, "vector": [0.4, 0.5, 0.6], "payload": {"category": "clothing", "price": 49.99}}
]
Return ONLY the JSON array.`,
placeholder: 'Describe the points to upsert...',
generationType: 'json-object',
},
},
// Search fields
{
@@ -89,6 +114,34 @@ export const QdrantBlock: BlockConfig<QdrantResponse> = {
type: 'long-input',
placeholder: '{"must":[{"key":"city","match":{"value":"London"}}]}',
condition: { field: 'operation', value: 'search' },
wandConfig: {
enabled: true,
prompt: `Generate a Qdrant filter JSON object based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON object starting with { and ending with }
- Use Qdrant filter syntax with "must", "should", or "must_not" arrays
- Each condition has: key (field name), match/range/geo (condition type)
- Match types: value (exact), text (full-text), any (array contains)
- Range types: gt, gte, lt, lte
### EXAMPLE
User: "Filter for products in electronics category with price under 500"
Output:
{
"must": [
{"key": "category", "match": {"value": "electronics"}},
{"key": "price", "range": {"lt": 500}}
]
}
Return ONLY the JSON object.`,
placeholder: 'Describe the filter conditions...',
generationType: 'json-object',
},
},
{
id: 'search_return_data',

View File

@@ -205,6 +205,35 @@ Return ONLY the SQL query - no explanations, no markdown, no extra text.`,
placeholder: '{\n "name": "John Doe",\n "email": "john@example.com",\n "active": true\n}',
condition: { field: 'operation', value: 'insert' },
required: true,
wandConfig: {
enabled: true,
maintainHistory: true,
prompt: `You are an expert database developer. Generate a JSON object for inserting data into an Amazon RDS table based on the user's request.
### CONTEXT
{context}
### CRITICAL INSTRUCTION
Return ONLY a valid JSON object. Do not include any explanations, markdown formatting, or additional text.
### GUIDELINES
1. Use appropriate data types (strings in quotes, numbers without, booleans as true/false)
2. Use snake_case for field names (common database convention)
3. Include relevant fields based on the table structure
4. Use null for optional fields that should be empty
### EXAMPLE
User: "Insert a new customer with name, email, and premium status"
Output:
{
"name": "John Doe",
"email": "john@example.com",
"is_premium": true,
"created_at": "NOW()"
}`,
placeholder: 'Describe the data you want to insert...',
generationType: 'json-object',
},
},
// Set clause for updates
{
@@ -214,6 +243,34 @@ Return ONLY the SQL query - no explanations, no markdown, no extra text.`,
placeholder: '{\n "name": "Jane Doe",\n "email": "jane@example.com"\n}',
condition: { field: 'operation', value: 'update' },
required: true,
wandConfig: {
enabled: true,
maintainHistory: true,
prompt: `You are an expert database developer. Generate a JSON object for updating data in an Amazon RDS table based on the user's request.
### CONTEXT
{context}
### CRITICAL INSTRUCTION
Return ONLY a valid JSON object containing the fields to update. Do not include any explanations, markdown formatting, or additional text.
### GUIDELINES
1. Only include fields that need to be updated
2. Use appropriate data types (strings in quotes, numbers without, booleans as true/false)
3. Use snake_case for field names
4. Consider including updated_at field if appropriate
### EXAMPLE
User: "Update the customer to inactive and clear their subscription"
Output:
{
"is_active": false,
"subscription_id": null,
"updated_at": "NOW()"
}`,
placeholder: 'Describe the fields you want to update...',
generationType: 'json-object',
},
},
// Conditions for update/delete (parameterized for SQL injection prevention)
{
@@ -223,6 +280,31 @@ Return ONLY the SQL query - no explanations, no markdown, no extra text.`,
placeholder: '{\n "id": 1\n}',
condition: { field: 'operation', value: 'update' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for RDS WHERE conditions based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON object starting with { and ending with }
- Each key-value pair represents a column and its expected value
- Multiple conditions will be combined with AND
- Use appropriate data types (strings, numbers, booleans)
### EXAMPLE
User: "Update records where user_id is 123 and status is active"
Output:
{
"user_id": 123,
"status": "active"
}
Return ONLY the JSON object.`,
placeholder: 'Describe the conditions...',
generationType: 'json-object',
},
},
{
id: 'conditions',
@@ -231,6 +313,32 @@ Return ONLY the SQL query - no explanations, no markdown, no extra text.`,
placeholder: '{\n "id": 1\n}',
condition: { field: 'operation', value: 'delete' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for RDS WHERE conditions based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON object starting with { and ending with }
- Each key-value pair represents a column and its expected value
- Multiple conditions will be combined with AND
- Use appropriate data types (strings, numbers, booleans)
- Be careful with delete conditions - they determine which rows are removed
### EXAMPLE
User: "Delete records where status is expired and created before 2023"
Output:
{
"status": "expired",
"created_year": 2022
}
Return ONLY the JSON object.`,
placeholder: 'Describe the conditions...',
generationType: 'json-object',
},
},
],
tools: {

View File

@@ -299,6 +299,18 @@ export const SalesforceBlock: BlockConfig<SalesforceResponse> = {
placeholder: 'YYYY-MM-DD (required for create)',
condition: { field: 'operation', value: ['create_opportunity', 'update_opportunity'] },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "end of quarter" -> Calculate the last day of the current quarter
- "next month" -> Calculate the last day of next month
- "in 90 days" -> Calculate the date 90 days from now
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the close date (e.g., "end of quarter", "in 90 days")...',
generationType: 'timestamp',
},
},
{
id: 'amount',
@@ -363,6 +375,18 @@ export const SalesforceBlock: BlockConfig<SalesforceResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DD',
condition: { field: 'operation', value: ['create_task', 'update_task'] },
wandConfig: {
enabled: true,
prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "tomorrow" -> Calculate tomorrow's date
- "next Friday" -> Calculate the next Friday's date
- "in 3 days" -> Calculate the date 3 days from now
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the due date (e.g., "tomorrow", "next Friday")...',
generationType: 'timestamp',
},
},
{
id: 'whoId',

View File

@@ -147,6 +147,37 @@ export const SendGridBlock: BlockConfig<SendMailResult> = {
type: 'code',
placeholder: '{"name": "John", "order_id": "12345"}',
condition: { field: 'operation', value: 'send_mail' },
wandConfig: {
enabled: true,
prompt: `Generate SendGrid dynamic template data JSON based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON object starting with { and ending with }
- Include all variables that the template might use
- Use descriptive key names that match template variables
- Values should be sample data or variable references
### EXAMPLE
User: "Order confirmation with customer name, order number, items list, and total"
Output:
{
"customer_name": "John Doe",
"order_id": "ORD-12345",
"items": [
{"name": "Product A", "quantity": 2, "price": 29.99},
{"name": "Product B", "quantity": 1, "price": 49.99}
],
"total": "$109.97",
"order_date": "January 15, 2024"
}
Return ONLY the JSON object.`,
placeholder: 'Describe the template variables...',
generationType: 'json-object',
},
},
// File upload (basic mode)
{
@@ -200,6 +231,31 @@ export const SendGridBlock: BlockConfig<SendMailResult> = {
type: 'code',
placeholder: '{"custom_field_1": "value1"}',
condition: { field: 'operation', value: ['add_contact'] },
wandConfig: {
enabled: true,
prompt: `Generate SendGrid custom fields JSON based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON object starting with { and ending with }
- Use the custom field IDs defined in your SendGrid account
- Custom field IDs are typically like "e1_T" or similar format
- Include appropriate values for each custom field
### EXAMPLE
User: "Add company name and signup source as custom fields"
Output:
{
"e1_T": "Acme Corporation",
"e2_T": "website_signup"
}
Return ONLY the JSON object.`,
placeholder: 'Describe the custom field values...',
generationType: 'json-object',
},
},
{
id: 'contactListIds',
@@ -223,6 +279,27 @@ export const SendGridBlock: BlockConfig<SendMailResult> = {
placeholder: "email LIKE '%example.com%'",
condition: { field: 'operation', value: ['search_contacts'] },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a SendGrid contact search query (SGQL) based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Use SendGrid Query Language (SGQL) syntax
- Available operators: LIKE, NOT LIKE, IS, IS NOT, IN, NOT IN, BETWEEN
- Available fields: email, first_name, last_name, created_at, updated_at, and custom fields
- Use AND/OR for combining conditions
- Use single quotes for string values
### EXAMPLE
User: "Find all contacts from gmail addresses added in the last 30 days"
Output: email LIKE '%@gmail.com' AND created_at > TIMESTAMP '2024-01-01'
Return ONLY the SGQL query.`,
placeholder: 'Describe the search criteria...',
},
},
{
id: 'contactIds',
@@ -242,6 +319,32 @@ export const SendGridBlock: BlockConfig<SendMailResult> = {
placeholder: '[{"email": "user@example.com", "first_name": "John"}]',
condition: { field: 'operation', value: 'add_contacts_to_list' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of SendGrid contacts based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON array starting with [ and ending with ]
- Each contact must have an "email" field
- Optional fields: first_name, last_name, custom_fields
- For custom fields, use the field ID format (e.g., "e1_T")
### EXAMPLE
User: "Add 3 contacts from the marketing team"
Output:
[
{"email": "alice@company.com", "first_name": "Alice", "last_name": "Smith"},
{"email": "bob@company.com", "first_name": "Bob", "last_name": "Jones"},
{"email": "carol@company.com", "first_name": "Carol", "last_name": "Williams"}
]
Return ONLY the JSON array.`,
placeholder: 'Describe the contacts to add...',
generationType: 'json-object',
},
},
// List fields
{
@@ -330,6 +433,26 @@ export const SendGridBlock: BlockConfig<SendMailResult> = {
placeholder: 'Email subject',
condition: { field: 'operation', value: 'create_template_version' },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate an email subject line for a SendGrid template based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Keep it concise (under 60 characters for best deliverability)
- Use Handlebars variables: {{variable_name}}
- Make it clear and descriptive
- Avoid spam trigger words
### EXAMPLE
User: "Order shipped notification with order number"
Output: Your order #{{order_id}} has shipped!
Return ONLY the subject line.`,
placeholder: 'Describe the template subject...',
},
},
{
id: 'htmlContent',
@@ -337,6 +460,52 @@ export const SendGridBlock: BlockConfig<SendMailResult> = {
type: 'code',
placeholder: '<html><body>{{name}}</body></html>',
condition: { field: 'operation', value: 'create_template_version' },
wandConfig: {
enabled: true,
prompt: `Generate SendGrid email template HTML based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return valid HTML for email (use tables for layout, inline CSS)
- Use Handlebars syntax for dynamic content: {{variable_name}}
- Use conditionals: {{#if variable}}...{{/if}}
- Use loops: {{#each items}}...{{/each}}
- Include proper HTML structure with doctype
- Make it mobile-responsive
### EXAMPLE
User: "Simple order confirmation template with customer name and order details"
Output:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
.container { max-width: 600px; margin: 0 auto; }
.header { background: #007bff; color: white; padding: 20px; text-align: center; }
.content { padding: 20px; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Order Confirmation</h1>
</div>
<div class="content">
<p>Hi {{customer_name}},</p>
<p>Thank you for your order #{{order_id}}!</p>
<p>Total: {{total}}</p>
</div>
</div>
</body>
</html>
Return ONLY the HTML content.`,
placeholder: 'Describe the email template...',
},
},
{
id: 'plainContent',

View File

@@ -52,6 +52,28 @@ export const SentryBlock: BlockConfig<SentryResponse> = {
type: 'long-input',
placeholder: 'e.g., is:unresolved, level:error',
condition: { field: 'operation', value: 'sentry_issues_list' },
wandConfig: {
enabled: true,
prompt: `Generate a Sentry issue search query based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Use Sentry search syntax
- Common filters: is:unresolved, is:resolved, is:ignored, level:error, level:warning
- Time-based: firstSeen:, lastSeen:, age:
- Assignment: assigned:, assigned_to_team:, bookmarks:
- Tags: tags[key]:value, browser:, os:, device:
- Events: event.type:, message:
### EXAMPLE
User: "Find unresolved high-priority errors from the last week"
Output: is:unresolved level:error age:-7d
Return ONLY the search query.`,
placeholder: 'Describe what issues you want to find...',
},
},
{
id: 'statsPeriod',
@@ -279,6 +301,27 @@ export const SentryBlock: BlockConfig<SentryResponse> = {
type: 'long-input',
placeholder: 'e.g., user.email:*@example.com',
condition: { field: 'operation', value: 'sentry_events_list' },
wandConfig: {
enabled: true,
prompt: `Generate a Sentry events search query based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Use Sentry search syntax for events
- User filters: user.email:, user.id:, user.username:
- Context: browser:, os:, device:, url:, environment:
- Error details: error.type:, error.value:, message:
- Use wildcards (*) for partial matches
### EXAMPLE
User: "Find events from users at gmail in production"
Output: user.email:*@gmail.com environment:production
Return ONLY the search query.`,
placeholder: 'Describe what events you want to find...',
},
},
{
id: 'limit',
@@ -331,6 +374,25 @@ export const SentryBlock: BlockConfig<SentryResponse> = {
type: 'long-input',
placeholder: 'Search for specific release versions',
condition: { field: 'operation', value: 'sentry_releases_list' },
wandConfig: {
enabled: true,
prompt: `Generate a Sentry releases search query based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Search by version string or partial match
- Can include version numbers, package names, commit SHAs
- Use wildcards for partial matches if needed
### EXAMPLE
User: "Find all releases from version 2.x"
Output: 2.*
Return ONLY the search query.`,
placeholder: 'Describe which releases you want to find...',
},
},
{
id: 'limit',
@@ -379,6 +441,20 @@ export const SentryBlock: BlockConfig<SentryResponse> = {
type: 'short-input',
placeholder: 'ISO 8601 timestamp (defaults to now)',
condition: { field: 'operation', value: 'sentry_releases_create' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "yesterday" -> Calculate yesterday's date at 00:00:00Z
- "last week" -> Calculate 7 days ago at 00:00:00Z
- "now" -> Current date and time in UTC
- "beginning of this month" -> First day of current month at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the date (e.g., "now", "yesterday", "last Friday")...',
generationType: 'timestamp',
},
},
{
id: 'commits',
@@ -386,6 +462,32 @@ export const SentryBlock: BlockConfig<SentryResponse> = {
type: 'long-input',
placeholder: '[{"id":"abc123","message":"Fix bug"}]',
condition: { field: 'operation', value: 'sentry_releases_create' },
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of commits for a Sentry release based on the user's description.
### CONTEXT
{context}
### GUIDELINES
- Return ONLY a valid JSON array starting with [ and ending with ]
- Each commit must have: id (commit SHA)
- Optional fields: message, author_name, author_email, timestamp
- Include meaningful commit messages
### EXAMPLE
User: "3 commits for bug fixes and a feature addition"
Output:
[
{"id": "abc123def", "message": "Fix authentication timeout issue"},
{"id": "def456ghi", "message": "Fix memory leak in data processor"},
{"id": "ghi789jkl", "message": "Add user dashboard analytics feature"}
]
Return ONLY the JSON array.`,
placeholder: 'Describe the commits for this release...',
generationType: 'json-object',
},
},
// =====================================================================
@@ -427,6 +529,20 @@ export const SentryBlock: BlockConfig<SentryResponse> = {
type: 'short-input',
placeholder: 'ISO 8601 timestamp (defaults to now)',
condition: { field: 'operation', value: 'sentry_releases_deploy' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "now" -> Current date and time in UTC
- "5 minutes ago" -> Calculate 5 minutes before current time
- "start of deploy" -> Current date and time in UTC
- "yesterday at 3pm" -> Yesterday at 15:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe when the deploy started (e.g., "now", "5 minutes ago")...',
generationType: 'timestamp',
},
},
{
id: 'dateFinished',
@@ -434,6 +550,20 @@ export const SentryBlock: BlockConfig<SentryResponse> = {
type: 'short-input',
placeholder: 'ISO 8601 timestamp',
condition: { field: 'operation', value: 'sentry_releases_deploy' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "now" -> Current date and time in UTC
- "in 10 minutes" -> Calculate 10 minutes after current time
- "when deploy completes" -> Current date and time in UTC
- "end of day" -> Current date at 23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe when the deploy finished (e.g., "now", "in 10 minutes")...',
generationType: 'timestamp',
},
},
// =====================================================================

View File

@@ -325,6 +325,22 @@ export const SlackBlock: BlockConfig<SlackResponse> = {
field: 'operation',
value: 'read',
},
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
This timestamp is used to filter Slack messages - only messages after this timestamp will be returned.
Examples:
- "last hour" -> Calculate 1 hour ago from current time
- "yesterday" -> Calculate yesterday's date at 00:00:00Z
- "last week" -> Calculate 7 days ago at 00:00:00Z
- "beginning of this month" -> First day of current month at 00:00:00Z
- "30 minutes ago" -> Calculate 30 minutes before current time
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the cutoff date (e.g., "last hour", "yesterday", "last week")...',
generationType: 'timestamp',
},
},
// Download File specific fields
{

View File

@@ -148,6 +148,21 @@ export const TrelloBlock: BlockConfig<ToolResponse> = {
field: 'operation',
value: 'trello_create_card',
},
wandConfig: {
enabled: true,
prompt: `Generate a date or timestamp based on the user's description.
The timestamp should be in ISO 8601 format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "tomorrow" -> Calculate tomorrow's date in YYYY-MM-DD format
- "next Friday" -> Calculate the next Friday in YYYY-MM-DD format
- "in 3 days" -> Calculate 3 days from now in YYYY-MM-DD format
- "end of month" -> Calculate the last day of the current month
- "next week at 3pm" -> Calculate next week's date at 15:00:00Z
Return ONLY the date/timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the due date (e.g., "next Friday", "in 2 weeks")...',
generationType: 'timestamp',
},
},
{
@@ -235,6 +250,21 @@ export const TrelloBlock: BlockConfig<ToolResponse> = {
field: 'operation',
value: 'trello_update_card',
},
wandConfig: {
enabled: true,
prompt: `Generate a date or timestamp based on the user's description.
The timestamp should be in ISO 8601 format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "tomorrow" -> Calculate tomorrow's date in YYYY-MM-DD format
- "next Friday" -> Calculate the next Friday in YYYY-MM-DD format
- "in 3 days" -> Calculate 3 days from now in YYYY-MM-DD format
- "end of month" -> Calculate the last day of the current month
- "next week at 3pm" -> Calculate next week's date at 15:00:00Z
Return ONLY the date/timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the due date (e.g., "next Friday", "in 2 weeks")...',
generationType: 'timestamp',
},
},
{

View File

@@ -189,6 +189,21 @@ export const TwilioVoiceBlock: BlockConfig<ToolResponse> = {
field: 'operation',
value: 'list_calls',
},
wandConfig: {
enabled: true,
prompt: `Generate a date based on the user's description.
The date should be in YYYY-MM-DD format.
Examples:
- "yesterday" -> Calculate yesterday's date
- "last week" -> Calculate 7 days ago
- "beginning of this month" -> First day of the current month (YYYY-MM-01)
- "last Monday" -> Calculate the most recent Monday
- "30 days ago" -> Calculate 30 days before today
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date (e.g., "last week", "beginning of month")...',
generationType: 'timestamp',
},
},
{
id: 'startTimeBefore',
@@ -199,6 +214,21 @@ export const TwilioVoiceBlock: BlockConfig<ToolResponse> = {
field: 'operation',
value: 'list_calls',
},
wandConfig: {
enabled: true,
prompt: `Generate a date based on the user's description.
The date should be in YYYY-MM-DD format.
Examples:
- "today" -> Today's date
- "end of this month" -> Last day of the current month
- "next Friday" -> Calculate the upcoming Friday
- "in 7 days" -> Calculate 7 days from today
- "end of year" -> December 31st of the current year
Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end date (e.g., "today", "end of month")...',
generationType: 'timestamp',
},
},
{
id: 'recordingSid',

View File

@@ -72,6 +72,21 @@ export const TypeformBlock: BlockConfig<TypeformResponse> = {
type: 'short-input',
placeholder: 'Retrieve responses after this date (ISO format)',
condition: { field: 'operation', value: 'typeform_responses' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "yesterday" -> Calculate yesterday's date at 00:00:00Z
- "last week" -> Calculate 7 days ago at 00:00:00Z
- "beginning of this month" -> First day of current month at 00:00:00Z
- "24 hours ago" -> Calculate exactly 24 hours before now
- "last Monday at 9am" -> Calculate the most recent Monday at 09:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date (e.g., "last week", "beginning of month")...',
generationType: 'timestamp',
},
},
{
id: 'until',
@@ -79,6 +94,21 @@ export const TypeformBlock: BlockConfig<TypeformResponse> = {
type: 'short-input',
placeholder: 'Retrieve responses before this date (ISO format)',
condition: { field: 'operation', value: 'typeform_responses' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone).
Examples:
- "now" -> Current timestamp
- "today at midnight" -> Today's date at 23:59:59Z
- "end of this month" -> Last day of current month at 23:59:59Z
- "yesterday" -> Yesterday's date at 23:59:59Z
- "end of last week" -> Most recent Sunday at 23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end date (e.g., "now", "end of yesterday")...',
generationType: 'timestamp',
},
},
{
id: 'completed',

View File

@@ -87,6 +87,19 @@ export const WealthboxBlock: BlockConfig<WealthboxResponse> = {
placeholder: 'Enter due date (e.g., 2015-05-24 11:00 AM -0400)',
condition: { field: 'operation', value: ['write_task'] },
required: true,
wandConfig: {
enabled: true,
prompt: `Generate a date/time string based on the user's description.
The format should be: YYYY-MM-DD HH:MM AM/PM ZZZZ (e.g., 2015-05-24 11:00 AM -0400).
Examples:
- "tomorrow at 2pm" -> Calculate tomorrow's date at 02:00 PM with local timezone offset
- "next Monday at 9am" -> Calculate next Monday at 09:00 AM with local timezone offset
- "in 3 days at noon" -> Calculate 3 days from now at 12:00 PM with local timezone offset
Return ONLY the date/time string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the due date (e.g., "tomorrow at 2pm", "next Friday morning")...',
generationType: 'timestamp',
},
},
{
id: 'firstName',

View File

@@ -108,6 +108,20 @@ export const XBlock: BlockConfig<XResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DDTHH:mm:ssZ',
condition: { field: 'operation', value: 'x_search' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:mm:ssZ (UTC timezone).
Examples:
- "yesterday" -> Calculate yesterday's date at 00:00:00Z
- "last week" -> Calculate 7 days ago at 00:00:00Z
- "beginning of this month" -> Calculate the 1st of current month at 00:00:00Z
- "2 hours ago" -> Calculate the timestamp 2 hours before now
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start time (e.g., "last week", "yesterday")...',
generationType: 'timestamp',
},
},
{
id: 'endTime',
@@ -115,6 +129,20 @@ export const XBlock: BlockConfig<XResponse> = {
type: 'short-input',
placeholder: 'YYYY-MM-DDTHH:mm:ssZ',
condition: { field: 'operation', value: 'x_search' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:mm:ssZ (UTC timezone).
Examples:
- "now" -> Current timestamp
- "today" -> Today's date at 23:59:59Z
- "end of this week" -> Calculate the end of current week at 23:59:59Z
- "yesterday evening" -> Calculate yesterday at 23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end time (e.g., "now", "end of today")...',
generationType: 'timestamp',
},
},
{
id: 'username',

View File

@@ -62,6 +62,21 @@ export const YouTubeBlock: BlockConfig<YouTubeResponse> = {
type: 'short-input',
placeholder: '2024-01-01T00:00:00Z',
condition: { field: 'operation', value: 'youtube_search' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:mm:ssZ (UTC timezone).
This is for filtering YouTube videos published after this date.
Examples:
- "last month" -> Calculate 30 days ago at 00:00:00Z
- "beginning of 2024" -> 2024-01-01T00:00:00Z
- "last year" -> Calculate 1 year ago at 00:00:00Z
- "past 7 days" -> Calculate 7 days ago at 00:00:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date (e.g., "last month", "beginning of 2024")...',
generationType: 'timestamp',
},
},
{
id: 'publishedBefore',
@@ -69,6 +84,21 @@ export const YouTubeBlock: BlockConfig<YouTubeResponse> = {
type: 'short-input',
placeholder: '2024-12-31T23:59:59Z',
condition: { field: 'operation', value: 'youtube_search' },
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:mm:ssZ (UTC timezone).
This is for filtering YouTube videos published before this date.
Examples:
- "today" -> Today's date at 23:59:59Z
- "end of 2024" -> 2024-12-31T23:59:59Z
- "yesterday" -> Yesterday's date at 23:59:59Z
- "end of last month" -> Last day of previous month at 23:59:59Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end date (e.g., "today", "end of last year")...',
generationType: 'timestamp',
},
},
{
id: 'videoDuration',

View File

@@ -93,6 +93,18 @@ export const ZendeskBlock: BlockConfig = {
field: 'operation',
value: ['create_ticket', 'update_ticket'],
},
wandConfig: {
enabled: true,
prompt: `Generate a clear, concise support ticket subject line based on the user's description.
Keep it brief but informative (under 100 characters).
Examples:
- "customer can't log in" -> Unable to access account - Login authentication issue
- "billing question about renewal" -> Billing inquiry: Subscription renewal question
- "feature request for dark mode" -> Feature Request: Dark mode support
Return ONLY the subject line - no explanations.`,
placeholder: 'Describe the ticket issue briefly...',
},
},
{
id: 'description',
@@ -107,6 +119,23 @@ export const ZendeskBlock: BlockConfig = {
field: 'operation',
value: ['create_ticket', 'update_ticket'],
},
wandConfig: {
enabled: true,
prompt: `Write a detailed support ticket description based on the user's input.
Include relevant details that would help support agents understand the issue.
Structure the description clearly with:
- Issue summary
- Steps to reproduce (if applicable)
- Expected vs actual behavior
- Any relevant context
Examples:
- "user forgot password and email not working" -> Detailed description of password reset issue with email delivery problems
- "subscription not renewing automatically" -> Clear explanation of billing/subscription issue
Return ONLY the description text - no explanations.`,
placeholder: 'Describe the issue in detail...',
},
},
{
id: 'status',
@@ -177,6 +206,22 @@ export const ZendeskBlock: BlockConfig = {
field: 'operation',
value: ['create_ticket', 'update_ticket'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for Zendesk custom fields based on the user's description.
Custom fields use numeric IDs and can have various value types.
Format: {"id": field_id, "value": "field_value"}
Examples:
- "set product to Enterprise and region to EMEA" ->
[{"id": 123456, "value": "enterprise"}, {"id": 789012, "value": "emea"}]
- "mark as VIP customer with priority support" ->
[{"id": 111111, "value": true}, {"id": 222222, "value": "priority"}]
Return ONLY the JSON array - no explanations.`,
placeholder: 'Describe the custom field values to set...',
generationType: 'json-object',
},
},
{
id: 'tickets',
@@ -188,6 +233,25 @@ export const ZendeskBlock: BlockConfig = {
field: 'operation',
value: ['create_tickets_bulk', 'update_tickets_bulk'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of Zendesk ticket objects based on the user's description.
Each ticket object should include: subject, description (comment.body), and optionally priority, status, tags.
Example structure:
[
{
"subject": "Issue title",
"comment": {"body": "Issue description"},
"priority": "normal",
"tags": ["tag1", "tag2"]
}
]
Return ONLY the JSON array - no explanations.`,
placeholder: 'Describe the tickets to create or update...',
generationType: 'json-object',
},
},
{
id: 'targetTicketId',
@@ -257,6 +321,25 @@ export const ZendeskBlock: BlockConfig = {
field: 'operation',
value: ['create_users_bulk', 'update_users_bulk'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of Zendesk user objects based on the user's description.
Each user object should include: name, email, and optionally role, phone, organization_id, tags.
Example structure:
[
{
"name": "John Doe",
"email": "john@example.com",
"role": "end-user",
"phone": "+1234567890"
}
]
Return ONLY the JSON array - no explanations.`,
placeholder: 'Describe the users to create or update...',
generationType: 'json-object',
},
},
// Organization fields
{
@@ -305,6 +388,25 @@ export const ZendeskBlock: BlockConfig = {
field: 'operation',
value: ['create_organizations_bulk'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON array of Zendesk organization objects based on the user's description.
Each organization object should include: name, and optionally domain_names, tags, notes.
Example structure:
[
{
"name": "Acme Corp",
"domain_names": ["acme.com", "acme.io"],
"tags": ["enterprise", "priority"],
"notes": "Key customer since 2020"
}
]
Return ONLY the JSON array - no explanations.`,
placeholder: 'Describe the organizations to create...',
generationType: 'json-object',
},
},
// Search fields
{
@@ -320,6 +422,26 @@ export const ZendeskBlock: BlockConfig = {
field: 'operation',
value: ['search_users', 'search', 'search_count'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Zendesk search query based on the user's description.
Use Zendesk search syntax for precise results:
- type:ticket, type:user, type:organization - filter by type
- status:open, status:pending, status:solved - ticket status
- priority:urgent, priority:high - ticket priority
- assignee:name - assigned to specific agent
- created>2024-01-01 - date filters
- tags:billing - filter by tags
- "exact phrase" - exact match
Examples:
- "urgent tickets from last week" -> type:ticket priority:urgent created>1week
- "open tickets about billing" -> type:ticket status:open tags:billing
- "customers named John" -> type:user name:John*
Return ONLY the search query - no explanations.`,
placeholder: 'Describe what you want to search for...',
},
},
{
id: 'sortBy',

View File

@@ -135,6 +135,22 @@ export const ZoomBlock: BlockConfig<ZoomResponse> = {
field: 'operation',
value: ['zoom_create_meeting', 'zoom_update_meeting'],
},
wandConfig: {
enabled: true,
prompt: `Generate an ISO 8601 timestamp based on the user's description.
The timestamp should be in the format: YYYY-MM-DDTHH:mm:ssZ (UTC timezone).
This is for scheduling a Zoom meeting start time.
Examples:
- "tomorrow at 10am" -> Calculate tomorrow's date at 10:00:00Z (adjust for user's timezone)
- "next Monday at 2pm" -> Calculate next Monday at 14:00:00Z
- "in 1 hour" -> Calculate 1 hour from now
- "Friday at 3:30pm" -> Calculate next Friday at 15:30:00Z
Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
placeholder:
'Describe the meeting time (e.g., "tomorrow at 10am", "next Monday at 2pm")...',
generationType: 'timestamp',
},
},
// Duration
{
@@ -290,6 +306,21 @@ export const ZoomBlock: BlockConfig<ZoomResponse> = {
field: 'operation',
value: ['zoom_list_recordings'],
},
wandConfig: {
enabled: true,
prompt: `Generate a date string based on the user's description.
The date should be in the format: yyyy-mm-dd (e.g., 2024-01-15).
This is for filtering Zoom recordings from this date (must be within last 6 months).
Examples:
- "last month" -> Calculate 30 days ago in yyyy-mm-dd format
- "beginning of this month" -> First day of current month in yyyy-mm-dd format
- "2 weeks ago" -> Calculate 14 days ago in yyyy-mm-dd format
- "start of last week" -> Calculate the Monday of last week
Return ONLY the date string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the start date (e.g., "last month", "2 weeks ago")...',
generationType: 'timestamp',
},
},
{
id: 'toDate',
@@ -300,6 +331,21 @@ export const ZoomBlock: BlockConfig<ZoomResponse> = {
field: 'operation',
value: ['zoom_list_recordings'],
},
wandConfig: {
enabled: true,
prompt: `Generate a date string based on the user's description.
The date should be in the format: yyyy-mm-dd (e.g., 2024-01-15).
This is for filtering Zoom recordings up to this date.
Examples:
- "today" -> Today's date in yyyy-mm-dd format
- "yesterday" -> Yesterday's date in yyyy-mm-dd format
- "end of last week" -> Calculate the Sunday of last week
- "end of this month" -> Last day of current month
Return ONLY the date string - no explanations, no quotes, no extra text.`,
placeholder: 'Describe the end date (e.g., "today", "yesterday")...',
generationType: 'timestamp',
},
},
// Recording ID for delete
{

View File

@@ -27,6 +27,7 @@ import { EvaluatorBlock } from '@/blocks/blocks/evaluator'
import { ExaBlock } from '@/blocks/blocks/exa'
import { FileBlock } from '@/blocks/blocks/file'
import { FirecrawlBlock } from '@/blocks/blocks/firecrawl'
import { FirefliesBlock } from '@/blocks/blocks/fireflies'
import { FunctionBlock } from '@/blocks/blocks/function'
import { GenericWebhookBlock } from '@/blocks/blocks/generic_webhook'
import { GitHubBlock } from '@/blocks/blocks/github'
@@ -174,6 +175,7 @@ export const registry: Record<string, BlockConfig> = {
exa: ExaBlock,
file: FileBlock,
firecrawl: FirecrawlBlock,
fireflies: FirefliesBlock,
function: FunctionBlock,
generic_webhook: GenericWebhookBlock,
github: GitHubBlock,

View File

@@ -37,6 +37,7 @@ export type GenerationType =
| 'mongodb-update'
| 'neo4j-cypher'
| 'neo4j-parameters'
| 'timestamp'
export type SubBlockType =
| 'short-input' // Single line input

View File

@@ -4414,3 +4414,164 @@ export function JiraServiceManagementIcon(props: SVGProps<SVGSVGElement>) {
</svg>
)
}
export function FirefliesIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='-6 -6 68 68'>
<defs>
<linearGradient
id='fireflies_g1'
gradientUnits='userSpaceOnUse'
x1='144.6644'
y1='-133.7781'
x2='54.3811'
y2='-38.9195'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.113' stopColor='#DE2D7A' />
<stop offset='0.3' stopColor='#C5388F' />
<stop offset='0.54' stopColor='#9B4AB0' />
<stop offset='0.818' stopColor='#6262DE' />
<stop offset='0.994' stopColor='#3B73FF' />
</linearGradient>
<linearGradient
id='fireflies_g2'
gradientUnits='userSpaceOnUse'
x1='145.1664'
y1='-133.3084'
x2='54.8831'
y2='-38.4499'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#FF3C82' />
<stop offset='0.103' stopColor='#F53E88' />
<stop offset='0.274' stopColor='#DC4598' />
<stop offset='0.492' stopColor='#B251B2' />
<stop offset='0.745' stopColor='#7961D7' />
<stop offset='0.994' stopColor='#3B73FF' />
</linearGradient>
<linearGradient
id='fireflies_g3'
gradientUnits='userSpaceOnUse'
x1='144.7625'
y1='-123.2011'
x2='114.171'
y2='-12.3403'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.113' stopColor='#DE2D7A' />
<stop offset='0.3' stopColor='#C5388F' />
<stop offset='0.54' stopColor='#9B4AB0' />
<stop offset='0.818' stopColor='#6262DE' />
<stop offset='0.994' stopColor='#3B73FF' />
</linearGradient>
<linearGradient
id='fireflies_g4'
gradientUnits='userSpaceOnUse'
x1='134.8237'
y1='-132.3271'
x2='25.3098'
y2='-98.9636'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.113' stopColor='#DE2D7A' />
<stop offset='0.3' stopColor='#C5388F' />
<stop offset='0.54' stopColor='#9B4AB0' />
<stop offset='0.818' stopColor='#6262DE' />
<stop offset='0.994' stopColor='#3B73FF' />
</linearGradient>
<linearGradient
id='fireflies_g5'
gradientUnits='userSpaceOnUse'
x1='82.2078'
y1='-52.7908'
x2='112.8836'
y2='-123.0805'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.114' stopColor='#DE286E' />
<stop offset='0.303' stopColor='#C52361' />
<stop offset='0.544' stopColor='#9B1A4D' />
<stop offset='0.825' stopColor='#620F30' />
<stop offset='0.994' stopColor='#3D081E' />
</linearGradient>
<linearGradient
id='fireflies_g6'
gradientUnits='userSpaceOnUse'
x1='107.6542'
y1='-78.5296'
x2='138.33'
y2='-148.8194'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.114' stopColor='#DE286E' />
<stop offset='0.303' stopColor='#C52361' />
<stop offset='0.544' stopColor='#9B1A4D' />
<stop offset='0.825' stopColor='#620F30' />
<stop offset='0.994' stopColor='#3D081E' />
</linearGradient>
<linearGradient
id='fireflies_g7'
gradientUnits='userSpaceOnUse'
x1='70.8311'
y1='-99.3209'
x2='140.3046'
y2='-145.474'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.114' stopColor='#DE286E' />
<stop offset='0.303' stopColor='#C52361' />
<stop offset='0.544' stopColor='#9B1A4D' />
<stop offset='0.825' stopColor='#620F30' />
<stop offset='0.994' stopColor='#3D081E' />
</linearGradient>
<linearGradient
id='fireflies_g8'
gradientUnits='userSpaceOnUse'
x1='297.6904'
y1='-1360.8851'
x2='309.5946'
y2='-1454.8754'
gradientTransform='matrix(0.8571 0 0 -0.8571 -79.2389 -68.1736)'
>
<stop offset='0' stopColor='#E82A73' />
<stop offset='0.114' stopColor='#DE286E' />
<stop offset='0.303' stopColor='#C52361' />
<stop offset='0.544' stopColor='#9B1A4D' />
<stop offset='0.825' stopColor='#620F30' />
<stop offset='0.994' stopColor='#3D081E' />
</linearGradient>
</defs>
<g>
<path fill='url(#fireflies_g1)' d='M18.4,0H0v18.3h18.4V0z' />
<path fill='url(#fireflies_g2)' d='M40.2,22.1H21.8v18.3h18.4V22.1z' />
<path
fill='url(#fireflies_g3)'
d='M40.2,0H21.8v18.3H56v-2.6c0-4.2-1.7-8.1-4.6-11.1C48.4,1.7,44.4,0,40.2,0L40.2,0z'
/>
<path
fill='url(#fireflies_g4)'
d='M0,22.1v18.3c0,4.2,1.7,8.1,4.6,11.1c3,2.9,7,4.6,11.2,4.6h2.6V22.1H0z'
/>
<path fill='url(#fireflies_g5)' opacity='0.18' d='M0,0l18.4,18.3H0V0z' />
<path fill='url(#fireflies_g6)' opacity='0.18' d='M21.8,22.1l18.4,18.3H21.8V22.1z' />
<path
fill='url(#fireflies_g7)'
opacity='0.18'
d='M0,40.3c0,4.2,1.7,8.1,4.6,11.1c3,2.9,7,4.6,11.2,4.6h2.6V22.1L0,40.3z'
/>
<path
fill='url(#fireflies_g8)'
opacity='0.18'
d='M40.2,0c4.2,0,8.2,1.7,11.2,4.6c3,2.9,4.6,6.9,4.6,11.1v2.6H21.8L40.2,0z'
/>
</g>
</svg>
)
}

View File

@@ -512,6 +512,33 @@ export async function verifyProviderAuth(
}
}
if (foundWebhook.provider === 'fireflies') {
const secret = providerConfig.webhookSecret as string | undefined
if (secret) {
const signature = request.headers.get('x-hub-signature')
if (!signature) {
logger.warn(`[${requestId}] Fireflies webhook missing signature header`)
return new NextResponse('Unauthorized - Missing Fireflies signature', { status: 401 })
}
const { validateFirefliesSignature } = await import('@/lib/webhooks/utils.server')
const isValidSignature = validateFirefliesSignature(secret, signature, rawBody)
if (!isValidSignature) {
logger.warn(`[${requestId}] Fireflies signature verification failed`, {
signatureLength: signature.length,
secretLength: secret.length,
})
return new NextResponse('Unauthorized - Invalid Fireflies signature', { status: 401 })
}
logger.debug(`[${requestId}] Fireflies signature verified successfully`)
}
}
if (foundWebhook.provider === 'generic') {
if (providerConfig.requireAuth) {
const configToken = providerConfig.token

View File

@@ -1522,6 +1522,28 @@ export async function formatWebhookInput(
}
}
if (foundWebhook.provider === 'fireflies') {
// Fireflies webhook payload uses camelCase:
// { meetingId, eventType, clientReferenceId }
return {
meetingId: body.meetingId || '',
eventType: body.eventType || 'Transcription completed',
clientReferenceId: body.clientReferenceId || '',
webhook: {
data: {
provider: 'fireflies',
path: foundWebhook.path,
providerConfig: foundWebhook.providerConfig,
payload: body,
headers: Object.fromEntries(request.headers.entries()),
method: request.method,
},
},
workflowId: foundWorkflow.id,
}
}
// Generic format for other providers
return {
webhook: {
@@ -1772,6 +1794,64 @@ export function validateJiraSignature(secret: string, signature: string, body: s
}
}
/**
* Validates a Fireflies webhook request signature using HMAC SHA-256
* @param secret - Fireflies webhook secret (16-32 characters)
* @param signature - x-hub-signature header value (format: 'sha256=<hex>')
* @param body - Raw request body string
* @returns Whether the signature is valid
*/
export function validateFirefliesSignature(
secret: string,
signature: string,
body: string
): boolean {
try {
if (!secret || !signature || !body) {
logger.warn('Fireflies signature validation missing required fields', {
hasSecret: !!secret,
hasSignature: !!signature,
hasBody: !!body,
})
return false
}
if (!signature.startsWith('sha256=')) {
logger.warn('Fireflies signature has invalid format (expected sha256=)', {
signaturePrefix: signature.substring(0, 10),
})
return false
}
const providedSignature = signature.substring(7)
const crypto = require('crypto')
const computedHash = crypto.createHmac('sha256', secret).update(body, 'utf8').digest('hex')
logger.debug('Fireflies signature comparison', {
computedSignature: `${computedHash.substring(0, 10)}...`,
providedSignature: `${providedSignature.substring(0, 10)}...`,
computedLength: computedHash.length,
providedLength: providedSignature.length,
match: computedHash === providedSignature,
})
if (computedHash.length !== providedSignature.length) {
return false
}
let result = 0
for (let i = 0; i < computedHash.length; i++) {
result |= computedHash.charCodeAt(i) ^ providedSignature.charCodeAt(i)
}
return result === 0
} catch (error) {
logger.error('Error validating Fireflies signature:', error)
return false
}
}
/**
* Validates a GitHub webhook request signature using HMAC SHA-256 or SHA-1
* @param secret - GitHub webhook secret (plain text)

View File

@@ -0,0 +1,148 @@
import type {
FirefliesAddToLiveMeetingParams,
FirefliesAddToLiveMeetingResponse,
} from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesAddToLiveMeetingTool: ToolConfig<
FirefliesAddToLiveMeetingParams,
FirefliesAddToLiveMeetingResponse
> = {
id: 'fireflies_add_to_live_meeting',
name: 'Fireflies Add to Live Meeting',
description: 'Add the Fireflies.ai bot to an ongoing meeting to record and transcribe',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
meetingLink: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Valid meeting URL (Zoom, Google Meet, Microsoft Teams, etc.)',
},
title: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Title for the meeting (max 256 characters)',
},
meetingPassword: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Password for the meeting if required (max 32 characters)',
},
duration: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Meeting duration in minutes (15-120, default: 60)',
},
language: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Language code for transcription (e.g., "en", "es", "de")',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: (params) => {
if (!params.meetingLink || !params.meetingLink.startsWith('http')) {
throw new Error('Meeting link must be a valid HTTP/HTTPS URL')
}
const variables: Record<string, unknown> = {
meetingLink: params.meetingLink,
}
if (params.title) variables.title = params.title.substring(0, 256)
if (params.meetingPassword)
variables.meeting_password = params.meetingPassword.substring(0, 32)
if (params.duration) {
const duration = Math.min(Math.max(Number(params.duration), 15), 120)
variables.duration = duration
}
if (params.language) variables.language = params.language.substring(0, 5)
return {
query: `
mutation AddToLiveMeeting(
$meetingLink: String!
$title: String
$meeting_password: String
$duration: Int
$language: String
) {
addToLiveMeeting(
meeting_link: $meetingLink
title: $title
meeting_password: $meeting_password
duration: $duration
language: $language
) {
success
}
}
`,
variables,
}
},
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
const error = data.errors[0]
const errorCode = error?.extensions?.code || ''
let errorMessage = error?.message || 'Failed to add bot to meeting'
if (errorCode === 'too_many_requests') {
errorMessage = 'Rate limit exceeded. This endpoint allows 3 requests per 20 minutes.'
} else if (errorCode === 'invalid_language_code') {
errorMessage = 'Invalid language code provided'
} else if (errorCode === 'unsupported_platform') {
errorMessage = 'Meeting platform is not supported'
}
return {
success: false,
error: errorMessage,
output: {},
}
}
const result = data.data?.addToLiveMeeting
return {
success: result?.success ?? false,
output: {
success: result?.success ?? false,
},
}
},
outputs: {
success: {
type: 'boolean',
description: 'Whether the bot was successfully added to the meeting',
},
},
}

View File

@@ -0,0 +1,166 @@
import type {
FirefliesCreateBiteParams,
FirefliesCreateBiteResponse,
} from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesCreateBiteTool: ToolConfig<
FirefliesCreateBiteParams,
FirefliesCreateBiteResponse
> = {
id: 'fireflies_create_bite',
name: 'Fireflies Create Bite',
description: 'Create a soundbite/highlight from a specific time range in a transcript',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
transcriptId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the transcript to create the bite from',
},
startTime: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Start time of the bite in seconds',
},
endTime: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'End time of the bite in seconds',
},
name: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Name for the bite (max 256 characters)',
},
mediaType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Media type: "video" or "audio"',
},
summary: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Summary for the bite (max 500 characters)',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: (params) => {
if (!params.transcriptId) {
throw new Error('Transcript ID is required')
}
if (params.startTime === undefined || params.endTime === undefined) {
throw new Error('Start time and end time are required')
}
if (params.startTime >= params.endTime) {
throw new Error('Start time must be less than end time')
}
const variables: Record<string, unknown> = {
transcriptId: params.transcriptId,
startTime: Number(params.startTime),
endTime: Number(params.endTime),
}
if (params.name) variables.name = params.name.substring(0, 256)
if (params.mediaType) variables.media_type = params.mediaType
if (params.summary) variables.summary = params.summary.substring(0, 500)
return {
query: `
mutation CreateBite(
$transcriptId: ID!
$startTime: Float!
$endTime: Float!
$name: String
$media_type: String
$summary: String
) {
createBite(
transcript_Id: $transcriptId
start_time: $startTime
end_time: $endTime
name: $name
media_type: $media_type
summary: $summary
) {
id
name
status
}
}
`,
variables,
}
},
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
return {
success: false,
error: data.errors[0]?.message || 'Failed to create bite',
output: {},
}
}
const bite = data.data?.createBite
if (!bite) {
return {
success: false,
error: 'Failed to create bite',
output: {},
}
}
return {
success: true,
output: {
bite: {
id: bite.id,
name: bite.name,
status: bite.status,
},
},
}
},
outputs: {
bite: {
type: 'object',
description: 'Created bite details',
properties: {
id: { type: 'string', description: 'Bite ID' },
name: { type: 'string', description: 'Bite name' },
status: { type: 'string', description: 'Processing status' },
},
},
},
}

View File

@@ -0,0 +1,89 @@
import type {
FirefliesDeleteTranscriptParams,
FirefliesDeleteTranscriptResponse,
} from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesDeleteTranscriptTool: ToolConfig<
FirefliesDeleteTranscriptParams,
FirefliesDeleteTranscriptResponse
> = {
id: 'fireflies_delete_transcript',
name: 'Fireflies Delete Transcript',
description: 'Delete a transcript from Fireflies.ai',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
transcriptId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The transcript ID to delete',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: (params) => {
if (!params.transcriptId) {
throw new Error('Transcript ID is required')
}
return {
query: `
mutation DeleteTranscript($id: String!) {
deleteTranscript(id: $id) {
success
}
}
`,
variables: {
id: params.transcriptId,
},
}
},
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
return {
success: false,
error: data.errors[0]?.message || 'Failed to delete transcript',
output: {},
}
}
const result = data.data?.deleteTranscript
return {
success: result?.success ?? false,
output: {
success: result?.success ?? false,
},
}
},
outputs: {
success: {
type: 'boolean',
description: 'Whether the transcript was successfully deleted',
},
},
}

View File

@@ -0,0 +1,205 @@
import type {
FirefliesGetTranscriptParams,
FirefliesGetTranscriptResponse,
} from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesGetTranscriptTool: ToolConfig<
FirefliesGetTranscriptParams,
FirefliesGetTranscriptResponse
> = {
id: 'fireflies_get_transcript',
name: 'Fireflies Get Transcript',
description:
'Get a single transcript with full details including summary, action items, and analytics',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
transcriptId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The transcript ID to retrieve',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: (params) => ({
query: `
query Transcript($id: String!) {
transcript(id: $id) {
id
title
date
dateString
duration
privacy
transcript_url
audio_url
video_url
meeting_link
host_email
organizer_email
participants
fireflies_users
speakers {
id
name
}
meeting_attendees {
displayName
email
phoneNumber
name
location
}
sentences {
index
speaker_name
speaker_id
text
raw_text
start_time
end_time
ai_filters {
task
pricing
metric
question
date_and_time
sentiment
}
}
summary {
keywords
action_items
outline
shorthand_bullet
overview
bullet_gist
gist
short_summary
short_overview
meeting_type
topics_discussed
}
analytics {
sentiments {
negative_pct
neutral_pct
positive_pct
}
categories {
questions
date_times
metrics
tasks
}
speakers {
speaker_id
name
duration
word_count
longest_monologue
monologues_count
filler_words
questions
duration_pct
words_per_minute
}
}
}
}
`,
variables: {
id: params.transcriptId,
},
}),
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
return {
success: false,
error: data.errors[0]?.message || 'Failed to fetch transcript',
output: {},
}
}
const transcript = data.data?.transcript
if (!transcript) {
return {
success: false,
error: 'Transcript not found',
output: {},
}
}
return {
success: true,
output: {
transcript: {
id: transcript.id,
title: transcript.title,
date: transcript.date,
dateString: transcript.dateString,
duration: transcript.duration,
privacy: transcript.privacy,
transcript_url: transcript.transcript_url,
audio_url: transcript.audio_url,
video_url: transcript.video_url,
meeting_link: transcript.meeting_link,
host_email: transcript.host_email,
organizer_email: transcript.organizer_email,
participants: transcript.participants,
fireflies_users: transcript.fireflies_users,
speakers: transcript.speakers,
meeting_attendees: transcript.meeting_attendees,
sentences: transcript.sentences,
summary: transcript.summary,
analytics: transcript.analytics,
},
},
}
},
outputs: {
transcript: {
type: 'object',
description: 'The transcript with full details',
properties: {
id: { type: 'string', description: 'Transcript ID' },
title: { type: 'string', description: 'Meeting title' },
date: { type: 'number', description: 'Meeting timestamp' },
duration: { type: 'number', description: 'Meeting duration in seconds' },
transcript_url: { type: 'string', description: 'URL to view transcript' },
audio_url: { type: 'string', description: 'URL to audio recording' },
host_email: { type: 'string', description: 'Host email address' },
participants: { type: 'array', description: 'List of participant emails' },
speakers: { type: 'array', description: 'List of speakers' },
sentences: { type: 'array', description: 'Transcript sentences' },
summary: { type: 'object', description: 'Meeting summary and action items' },
analytics: { type: 'object', description: 'Meeting analytics and sentiment' },
},
},
},
}

View File

@@ -0,0 +1,112 @@
import type { FirefliesGetUserParams, FirefliesGetUserResponse } from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesGetUserTool: ToolConfig<FirefliesGetUserParams, FirefliesGetUserResponse> = {
id: 'fireflies_get_user',
name: 'Fireflies Get User',
description: 'Get user information from Fireflies.ai. Returns current user if no ID specified.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
userId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'User ID to retrieve (optional, defaults to API key owner)',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: (params) => ({
query: `
query User($id: String) {
user(id: $id) {
user_id
name
email
integrations
is_admin
minutes_consumed
num_transcripts
recent_transcript
recent_meeting
}
}
`,
variables: params.userId ? { id: params.userId } : {},
}),
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
return {
success: false,
error: data.errors[0]?.message || 'Failed to fetch user',
output: {},
}
}
const user = data.data?.user
if (!user) {
return {
success: false,
error: 'User not found',
output: {},
}
}
return {
success: true,
output: {
user: {
user_id: user.user_id,
name: user.name,
email: user.email,
integrations: user.integrations,
is_admin: user.is_admin,
minutes_consumed: user.minutes_consumed,
num_transcripts: user.num_transcripts,
recent_transcript: user.recent_transcript,
recent_meeting: user.recent_meeting,
},
},
}
},
outputs: {
user: {
type: 'object',
description: 'User information',
properties: {
user_id: { type: 'string', description: 'User ID' },
name: { type: 'string', description: 'User name' },
email: { type: 'string', description: 'User email' },
integrations: { type: 'array', description: 'Connected integrations' },
is_admin: { type: 'boolean', description: 'Whether user is admin' },
minutes_consumed: { type: 'number', description: 'Total minutes transcribed' },
num_transcripts: { type: 'number', description: 'Number of transcripts' },
recent_transcript: { type: 'string', description: 'Most recent transcript ID' },
recent_meeting: { type: 'string', description: 'Most recent meeting date' },
},
},
},
}

View File

@@ -0,0 +1,11 @@
export { firefliesAddToLiveMeetingTool } from './add_to_live_meeting'
export { firefliesCreateBiteTool } from './create_bite'
export { firefliesDeleteTranscriptTool } from './delete_transcript'
export { firefliesGetTranscriptTool } from './get_transcript'
export { firefliesGetUserTool } from './get_user'
export { firefliesListBitesTool } from './list_bites'
export { firefliesListContactsTool } from './list_contacts'
export { firefliesListTranscriptsTool } from './list_transcripts'
export { firefliesListUsersTool } from './list_users'
export * from './types'
export { firefliesUploadAudioTool } from './upload_audio'

View File

@@ -0,0 +1,155 @@
import type { FirefliesListBitesParams, FirefliesListBitesResponse } from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesListBitesTool: ToolConfig<
FirefliesListBitesParams,
FirefliesListBitesResponse
> = {
id: 'fireflies_list_bites',
name: 'Fireflies List Bites',
description: 'List soundbites/highlights from Fireflies.ai',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
transcriptId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter bites for a specific transcript',
},
mine: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Only return bites owned by the API key owner (default: true)',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of bites to return (max 50)',
},
skip: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of bites to skip for pagination',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: (params) => {
const variables: Record<string, unknown> = {
mine: params.mine !== false,
}
if (params.transcriptId) variables.transcript_id = params.transcriptId
if (params.limit) variables.limit = Math.min(Number(params.limit), 50)
if (params.skip) variables.skip = Number(params.skip)
return {
query: `
query Bites(
$mine: Boolean
$transcript_id: ID
$limit: Int
$skip: Int
) {
bites(
mine: $mine
transcript_id: $transcript_id
limit: $limit
skip: $skip
) {
id
name
transcript_id
user_id
start_time
end_time
status
summary
media_type
thumbnail
preview
created_at
}
}
`,
variables,
}
},
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
return {
success: false,
error: data.errors[0]?.message || 'Failed to fetch bites',
output: {},
}
}
const bites = data.data?.bites || []
return {
success: true,
output: {
bites: bites.map(
(b: {
id: string
name?: string
transcript_id?: string
user_id?: string
start_time?: number
end_time?: number
status?: string
summary?: string
media_type?: string
thumbnail?: string
preview?: string
created_at?: string
}) => ({
id: b.id,
name: b.name,
transcript_id: b.transcript_id,
user_id: b.user_id,
start_time: b.start_time,
end_time: b.end_time,
status: b.status,
summary: b.summary,
media_type: b.media_type,
thumbnail: b.thumbnail,
preview: b.preview,
created_at: b.created_at,
})
),
},
}
},
outputs: {
bites: {
type: 'array',
description: 'List of bites/soundbites',
},
},
}

View File

@@ -0,0 +1,84 @@
import type {
FirefliesListContactsParams,
FirefliesListContactsResponse,
} from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesListContactsTool: ToolConfig<
FirefliesListContactsParams,
FirefliesListContactsResponse
> = {
id: 'fireflies_list_contacts',
name: 'Fireflies List Contacts',
description: 'List all contacts from your Fireflies.ai meetings',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: () => ({
query: `
query Contacts {
contacts {
email
name
picture
last_meeting_date
}
}
`,
}),
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
return {
success: false,
error: data.errors[0]?.message || 'Failed to fetch contacts',
output: {},
}
}
const contacts = data.data?.contacts || []
return {
success: true,
output: {
contacts: contacts.map(
(c: { email?: string; name?: string; picture?: string; last_meeting_date?: string }) => ({
email: c.email,
name: c.name,
picture: c.picture,
last_meeting_date: c.last_meeting_date,
})
),
},
}
},
outputs: {
contacts: {
type: 'array',
description: 'List of contacts from meetings',
},
},
}

View File

@@ -0,0 +1,173 @@
import type {
FirefliesListTranscriptsParams,
FirefliesListTranscriptsResponse,
} from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesListTranscriptsTool: ToolConfig<
FirefliesListTranscriptsParams,
FirefliesListTranscriptsResponse
> = {
id: 'fireflies_list_transcripts',
name: 'Fireflies List Transcripts',
description: 'List meeting transcripts from Fireflies.ai with optional filtering',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
keyword: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Search keyword in meeting title or transcript',
},
fromDate: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter transcripts from this date (ISO 8601 format)',
},
toDate: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter transcripts until this date (ISO 8601 format)',
},
hostEmail: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by meeting host email',
},
participants: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by participant emails (comma-separated)',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of transcripts to return (max 50)',
},
skip: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of transcripts to skip for pagination',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: (params) => {
const variables: Record<string, unknown> = {}
if (params.keyword) variables.keyword = params.keyword
if (params.fromDate) variables.fromDate = params.fromDate
if (params.toDate) variables.toDate = params.toDate
if (params.hostEmail) variables.host_email = params.hostEmail
if (params.participants) {
variables.participants = params.participants.split(',').map((p) => p.trim())
}
if (params.limit) variables.limit = Math.min(Number(params.limit), 50)
if (params.skip) variables.skip = Number(params.skip)
return {
query: `
query Transcripts(
$keyword: String
$fromDate: DateTime
$toDate: DateTime
$host_email: String
$participants: [String!]
$limit: Int
$skip: Int
) {
transcripts(
keyword: $keyword
fromDate: $fromDate
toDate: $toDate
host_email: $host_email
participants: $participants
limit: $limit
skip: $skip
) {
id
title
date
duration
host_email
participants
}
}
`,
variables,
}
},
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
return {
success: false,
error: data.errors[0]?.message || 'Failed to fetch transcripts',
output: {},
}
}
const transcripts = data.data?.transcripts || []
return {
success: true,
output: {
transcripts: transcripts.map(
(t: {
id: string
title: string
date: number
duration: number
host_email?: string
participants?: string[]
}) => ({
id: t.id,
title: t.title,
date: t.date,
duration: t.duration,
host_email: t.host_email,
participants: t.participants,
})
),
count: transcripts.length,
},
}
},
outputs: {
transcripts: {
type: 'array',
description: 'List of transcripts',
},
count: {
type: 'number',
description: 'Number of transcripts returned',
},
},
}

View File

@@ -0,0 +1,98 @@
import type { FirefliesListUsersParams, FirefliesListUsersResponse } from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesListUsersTool: ToolConfig<
FirefliesListUsersParams,
FirefliesListUsersResponse
> = {
id: 'fireflies_list_users',
name: 'Fireflies List Users',
description: 'List all users within your Fireflies.ai team',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: () => ({
query: `
query Users {
users {
user_id
email
name
num_transcripts
recent_meeting
minutes_consumed
is_admin
integrations
}
}
`,
}),
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
return {
success: false,
error: data.errors[0]?.message || 'Failed to fetch users',
output: {},
}
}
const users = data.data?.users || []
return {
success: true,
output: {
users: users.map(
(u: {
user_id: string
email: string
name: string
num_transcripts?: number
recent_meeting?: string
minutes_consumed?: number
is_admin?: boolean
integrations?: string[]
}) => ({
user_id: u.user_id,
email: u.email,
name: u.name,
num_transcripts: u.num_transcripts,
recent_meeting: u.recent_meeting,
minutes_consumed: u.minutes_consumed,
is_admin: u.is_admin,
integrations: u.integrations,
})
),
},
}
},
outputs: {
users: {
type: 'array',
description: 'List of team users',
},
},
}

View File

@@ -0,0 +1,300 @@
import type { ToolResponse } from '@/tools/types'
export interface FirefliesTranscript {
id: string
title: string
date: number
dateString?: string
duration: number
privacy?: string
transcript_url?: string
audio_url?: string
video_url?: string
meeting_link?: string
host_email?: string
organizer_email?: string
participants?: string[]
fireflies_users?: string[]
speakers?: FirefliesSpeaker[]
meeting_attendees?: FirefliesAttendee[]
sentences?: FirefliesSentence[]
summary?: FirefliesSummary
analytics?: FirefliesAnalytics
}
export interface FirefliesSpeaker {
id: string
name: string
}
export interface FirefliesAttendee {
displayName?: string
email?: string
phoneNumber?: string
name?: string
location?: string
}
export interface FirefliesSentence {
index: number
speaker_name?: string
speaker_id?: string
text: string
raw_text?: string
start_time: number
end_time: number
ai_filters?: {
task?: boolean
pricing?: boolean
metric?: boolean
question?: boolean
date_and_time?: boolean
text_cleanup?: string
sentiment?: string
}
}
export interface FirefliesSummary {
keywords?: string[]
action_items?: string[]
outline?: string[]
shorthand_bullet?: string[]
overview?: string
bullet_gist?: string[]
gist?: string
short_summary?: string
short_overview?: string
meeting_type?: string
topics_discussed?: string[]
transcript_chapters?: Array<{
title?: string
start_time?: number
end_time?: number
}>
}
export interface FirefliesAnalytics {
sentiments?: {
negative_pct?: number
neutral_pct?: number
positive_pct?: number
}
categories?: {
questions?: number
date_times?: number
metrics?: number
tasks?: number
}
speakers?: FirefliesSpeakerAnalytics[]
}
export interface FirefliesSpeakerAnalytics {
speaker_id?: string
name?: string
duration?: number
word_count?: number
longest_monologue?: number
monologues_count?: number
filler_words?: number
questions?: number
duration_pct?: number
words_per_minute?: number
}
export interface FirefliesUser {
user_id: string
name: string
email: string
integrations?: string[]
is_admin?: boolean
minutes_consumed?: number
num_transcripts?: number
recent_transcript?: string
recent_meeting?: string
}
export interface FirefliesListTranscriptsParams {
apiKey: string
keyword?: string
fromDate?: string
toDate?: string
hostEmail?: string
participants?: string
limit?: number
skip?: number
}
export interface FirefliesGetTranscriptParams {
apiKey: string
transcriptId: string
}
export interface FirefliesGetUserParams {
apiKey: string
userId?: string
}
export interface FirefliesUploadAudioParams {
apiKey: string
audioUrl?: string
audioFile?: {
url?: string
path?: string
name?: string
size?: number
type?: string
key?: string
}
title?: string
webhook?: string
language?: string
attendees?: string
clientReferenceId?: string
}
export interface FirefliesDeleteTranscriptParams {
apiKey: string
transcriptId: string
}
export interface FirefliesAddToLiveMeetingParams {
apiKey: string
meetingLink: string
title?: string
meetingPassword?: string
duration?: number
language?: string
}
export interface FirefliesListUsersParams {
apiKey: string
}
export interface FirefliesCreateBiteParams {
apiKey: string
transcriptId: string
startTime: number
endTime: number
name?: string
mediaType?: string
summary?: string
}
export interface FirefliesListBitesParams {
apiKey: string
transcriptId?: string
mine?: boolean
limit?: number
skip?: number
}
export interface FirefliesListContactsParams {
apiKey: string
}
export interface FirefliesListTranscriptsResponse extends ToolResponse {
output: {
transcripts?: Array<{
id: string
title: string
date: number
duration: number
host_email?: string
participants?: string[]
}>
count?: number
}
}
export interface FirefliesGetTranscriptResponse extends ToolResponse {
output: {
transcript?: FirefliesTranscript
}
}
export interface FirefliesGetUserResponse extends ToolResponse {
output: {
user?: FirefliesUser
}
}
export interface FirefliesUploadAudioResponse extends ToolResponse {
output: {
success?: boolean
title?: string
message?: string
}
}
export interface FirefliesDeleteTranscriptResponse extends ToolResponse {
output: {
success?: boolean
}
}
export interface FirefliesAddToLiveMeetingResponse extends ToolResponse {
output: {
success?: boolean
}
}
export interface FirefliesListUsersResponse extends ToolResponse {
output: {
users?: FirefliesUser[]
}
}
export interface FirefliesBite {
id: string
name?: string
transcript_id?: string
user_id?: string
start_time?: number
end_time?: number
status?: string
summary?: string
media_type?: string
thumbnail?: string
preview?: string
created_at?: string
}
export interface FirefliesCreateBiteResponse extends ToolResponse {
output: {
bite?: {
id: string
name?: string
status?: string
}
}
}
export interface FirefliesListBitesResponse extends ToolResponse {
output: {
bites?: FirefliesBite[]
}
}
export interface FirefliesContact {
email?: string
name?: string
picture?: string
last_meeting_date?: string
}
export interface FirefliesListContactsResponse extends ToolResponse {
output: {
contacts?: FirefliesContact[]
}
}
export type FirefliesResponse =
| FirefliesListTranscriptsResponse
| FirefliesGetTranscriptResponse
| FirefliesGetUserResponse
| FirefliesUploadAudioResponse
| FirefliesDeleteTranscriptResponse
| FirefliesAddToLiveMeetingResponse
| FirefliesListUsersResponse
| FirefliesCreateBiteResponse
| FirefliesListBitesResponse
| FirefliesListContactsResponse

View File

@@ -0,0 +1,176 @@
import type {
FirefliesUploadAudioParams,
FirefliesUploadAudioResponse,
} from '@/tools/fireflies/types'
import type { ToolConfig } from '@/tools/types'
export const firefliesUploadAudioTool: ToolConfig<
FirefliesUploadAudioParams,
FirefliesUploadAudioResponse
> = {
id: 'fireflies_upload_audio',
name: 'Fireflies Upload Audio',
description: 'Upload an audio file URL to Fireflies.ai for transcription',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Fireflies API key',
},
audioFile: {
type: 'file',
required: false,
visibility: 'user-or-llm',
description: 'Audio/video file to upload for transcription',
},
audioUrl: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Public HTTPS URL of the audio/video file (MP3, MP4, WAV, M4A, OGG)',
},
title: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Title for the meeting/transcript',
},
webhook: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Webhook URL to notify when transcription is complete',
},
language: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Language code for transcription (e.g., "es" for Spanish, "de" for German)',
},
attendees: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Attendees in JSON format: [{"displayName": "Name", "email": "email@example.com"}]',
},
clientReferenceId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Custom reference ID for tracking',
},
},
request: {
url: 'https://api.fireflies.ai/graphql',
method: 'POST',
headers: (params) => {
if (!params.apiKey) {
throw new Error('Missing API key for Fireflies API request')
}
return {
'Content-Type': 'application/json',
Authorization: `Bearer ${params.apiKey}`,
}
},
body: (params) => {
let url: string | undefined
if (params.audioFile) {
url = params.audioFile.url || params.audioFile.path
}
if (!url && params.audioUrl) {
url = params.audioUrl
}
if (!url) {
throw new Error('Either an audio file or audio URL is required')
}
if (!url.startsWith('https://')) {
throw new Error('Audio URL must be a valid HTTPS URL')
}
const input: Record<string, unknown> = {
url,
}
if (params.title) input.title = params.title
if (params.webhook) input.webhook = params.webhook
if (params.language) input.custom_language = params.language
if (params.clientReferenceId) input.client_reference_id = params.clientReferenceId
if (params.attendees) {
try {
input.attendees = JSON.parse(params.attendees)
} catch {
throw new Error('Invalid attendees JSON format')
}
}
return {
query: `
mutation UploadAudio($input: AudioUploadInput) {
uploadAudio(input: $input) {
success
title
message
}
}
`,
variables: {
input,
},
}
},
},
transformResponse: async (response) => {
const data = await response.json()
if (data.errors) {
return {
success: false,
error: data.errors[0]?.message || 'Failed to upload audio',
output: {},
}
}
const result = data.data?.uploadAudio
if (!result) {
return {
success: false,
error: 'Upload failed',
output: {},
}
}
return {
success: result.success,
output: {
success: result.success,
title: result.title,
message: result.message,
},
}
},
outputs: {
success: {
type: 'boolean',
description: 'Whether the upload was successful',
},
title: {
type: 'string',
description: 'Title of the uploaded meeting',
},
message: {
type: 'string',
description: 'Status message from Fireflies',
},
},
}

View File

@@ -194,6 +194,18 @@ import {
firecrawlScrapeTool,
firecrawlSearchTool,
} from '@/tools/firecrawl'
import {
firefliesAddToLiveMeetingTool,
firefliesCreateBiteTool,
firefliesDeleteTranscriptTool,
firefliesGetTranscriptTool,
firefliesGetUserTool,
firefliesListBitesTool,
firefliesListContactsTool,
firefliesListTranscriptsTool,
firefliesListUsersTool,
firefliesUploadAudioTool,
} from '@/tools/fireflies'
import { functionExecuteTool } from '@/tools/function'
import {
githubAddAssigneesTool,
@@ -1427,6 +1439,16 @@ export const tools: Record<string, ToolConfig> = {
firecrawl_map: firecrawlMapTool,
firecrawl_extract: firecrawlExtractTool,
firecrawl_agent: firecrawlAgentTool,
fireflies_list_transcripts: firefliesListTranscriptsTool,
fireflies_get_transcript: firefliesGetTranscriptTool,
fireflies_get_user: firefliesGetUserTool,
fireflies_list_users: firefliesListUsersTool,
fireflies_upload_audio: firefliesUploadAudioTool,
fireflies_delete_transcript: firefliesDeleteTranscriptTool,
fireflies_add_to_live_meeting: firefliesAddToLiveMeetingTool,
fireflies_create_bite: firefliesCreateBiteTool,
fireflies_list_bites: firefliesListBitesTool,
fireflies_list_contacts: firefliesListContactsTool,
grafana_get_dashboard: grafanaGetDashboardTool,
grafana_list_dashboards: grafanaListDashboardsTool,
grafana_create_dashboard: grafanaCreateDashboardTool,

View File

@@ -0,0 +1 @@
export { firefliesTranscriptionCompleteTrigger } from './transcription_complete'

View File

@@ -0,0 +1,85 @@
import { FirefliesIcon } from '@/components/icons'
import type { TriggerConfig } from '@/triggers/types'
export const firefliesTranscriptionCompleteTrigger: TriggerConfig = {
id: 'fireflies_transcription_complete',
name: 'Fireflies Transcription Complete',
provider: 'fireflies',
description: 'Trigger workflow when a Fireflies meeting transcription is complete',
version: '1.0.0',
icon: FirefliesIcon,
subBlocks: [
{
id: 'webhookUrlDisplay',
title: 'Webhook URL',
type: 'short-input',
readOnly: true,
showCopyButton: true,
useWebhookUrl: true,
placeholder: 'Webhook URL will be generated',
mode: 'trigger',
},
{
id: 'webhookSecret',
title: 'Webhook Secret',
type: 'short-input',
placeholder: 'Enter your 16-32 character secret',
description: 'Secret key for HMAC signature verification (set in Fireflies dashboard)',
password: true,
required: false,
mode: 'trigger',
},
{
id: 'triggerSave',
title: '',
type: 'trigger-save',
hideFromPreview: true,
mode: 'trigger',
triggerId: 'fireflies_transcription_complete',
},
{
id: 'triggerInstructions',
title: 'Setup Instructions',
hideFromPreview: true,
type: 'text',
defaultValue: [
'Go to <a href="https://app.fireflies.ai/settings" target="_blank" rel="noopener noreferrer">app.fireflies.ai/settings</a>',
'Navigate to the <strong>Developer settings</strong> tab',
'In the <strong>Webhook</strong> section, paste the Webhook URL above',
'Enter a <strong>Secret</strong> (16-32 characters) and save it here as well',
'Click <strong>Save</strong> in Fireflies to activate the webhook',
'Your workflow will now trigger when any meeting transcription completes',
]
.map(
(instruction, index) =>
`<div class="mb-3"><strong>${index + 1}.</strong> ${instruction}</div>`
)
.join(''),
mode: 'trigger',
},
],
outputs: {
meetingId: {
type: 'string',
description: 'The ID of the transcribed meeting',
},
eventType: {
type: 'string',
description: 'The type of event (Transcription completed)',
},
clientReferenceId: {
type: 'string',
description: 'Custom reference ID if set during upload',
},
},
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-hub-signature': 'sha256=...',
},
},
}

View File

@@ -10,6 +10,7 @@ import {
circlebackMeetingNotesTrigger,
circlebackWebhookTrigger,
} from '@/triggers/circleback'
import { firefliesTranscriptionCompleteTrigger } from '@/triggers/fireflies'
import { genericWebhookTrigger } from '@/triggers/generic'
import {
githubIssueClosedTrigger,
@@ -121,6 +122,7 @@ export const TRIGGER_REGISTRY: TriggerRegistry = {
github_push: githubPushTrigger,
github_release_published: githubReleasePublishedTrigger,
github_workflow_run: githubWorkflowRunTrigger,
fireflies_transcription_complete: firefliesTranscriptionCompleteTrigger,
gmail_poller: gmailPollingTrigger,
grain_webhook: grainWebhookTrigger,
grain_recording_created: grainRecordingCreatedTrigger,