mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 15:07:55 -05:00
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:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
238
apps/docs/content/docs/en/tools/fireflies.mdx
Normal file
238
apps/docs/content/docs/en/tools/fireflies.mdx
Normal 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 organization’s 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`
|
||||
@@ -23,6 +23,7 @@
|
||||
"exa",
|
||||
"file",
|
||||
"firecrawl",
|
||||
"fireflies",
|
||||
"github",
|
||||
"gitlab",
|
||||
"gmail",
|
||||
|
||||
@@ -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'))
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
],
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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
|
||||
|
||||
589
apps/sim/blocks/blocks/fireflies.ts
Normal file
589
apps/sim/blocks/blocks/fireflies.ts
Normal 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'],
|
||||
},
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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...',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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 ==========
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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>© *|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
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -37,6 +37,7 @@ export type GenerationType =
|
||||
| 'mongodb-update'
|
||||
| 'neo4j-cypher'
|
||||
| 'neo4j-parameters'
|
||||
| 'timestamp'
|
||||
|
||||
export type SubBlockType =
|
||||
| 'short-input' // Single line input
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
148
apps/sim/tools/fireflies/add_to_live_meeting.ts
Normal file
148
apps/sim/tools/fireflies/add_to_live_meeting.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
}
|
||||
166
apps/sim/tools/fireflies/create_bite.ts
Normal file
166
apps/sim/tools/fireflies/create_bite.ts
Normal 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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
89
apps/sim/tools/fireflies/delete_transcript.ts
Normal file
89
apps/sim/tools/fireflies/delete_transcript.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
}
|
||||
205
apps/sim/tools/fireflies/get_transcript.ts
Normal file
205
apps/sim/tools/fireflies/get_transcript.ts
Normal 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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
112
apps/sim/tools/fireflies/get_user.ts
Normal file
112
apps/sim/tools/fireflies/get_user.ts
Normal 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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
11
apps/sim/tools/fireflies/index.ts
Normal file
11
apps/sim/tools/fireflies/index.ts
Normal 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'
|
||||
155
apps/sim/tools/fireflies/list_bites.ts
Normal file
155
apps/sim/tools/fireflies/list_bites.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
}
|
||||
84
apps/sim/tools/fireflies/list_contacts.ts
Normal file
84
apps/sim/tools/fireflies/list_contacts.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
}
|
||||
173
apps/sim/tools/fireflies/list_transcripts.ts
Normal file
173
apps/sim/tools/fireflies/list_transcripts.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
}
|
||||
98
apps/sim/tools/fireflies/list_users.ts
Normal file
98
apps/sim/tools/fireflies/list_users.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
}
|
||||
300
apps/sim/tools/fireflies/types.ts
Normal file
300
apps/sim/tools/fireflies/types.ts
Normal 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
|
||||
176
apps/sim/tools/fireflies/upload_audio.ts
Normal file
176
apps/sim/tools/fireflies/upload_audio.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
1
apps/sim/triggers/fireflies/index.ts
Normal file
1
apps/sim/triggers/fireflies/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { firefliesTranscriptionCompleteTrigger } from './transcription_complete'
|
||||
85
apps/sim/triggers/fireflies/transcription_complete.ts
Normal file
85
apps/sim/triggers/fireflies/transcription_complete.ts
Normal 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=...',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user