mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
feat(integrations): suggest curated skills per integration with one-click add (#4912)
* feat(integrations): suggest curated skills per integration with one-click add Curate research-backed, capability-grounded skills for every catalog integration and surface them on the integration detail page. Each skill maps to operations the block actually supports and can be added to the workspace in one click; track adds in PostHog. - Add SuggestedSkill type + skills field on BlockMeta; populate skills for all 193 catalog integrations (3 audit passes for grounding/sourcing) - getSuggestedSkillsForBlock() with versioned-type (e.g. notion_v2) base fallback - Skills section on the integration detail page with add/added states - integration_skill_added PostHog event with workspace/integration metadata * fix(integrations): flip suggested-skill row to Added immediately after add The row derived Added state solely from the useSkills cache, so between a successful create and the list refetch the row still showed Add and could be clicked again, hitting the server duplicate-name check. Track added names in local state so the row reflects the add immediately. * fix(integrations): harden suggested-skill add flow; document skill authoring Address PR review feedback on the suggested-skills section: - Make useSkills the single source of truth for Added state by writing the created skill into the React Query cache onSuccess (fixes stale Added that survived a delete, and the lag that allowed a duplicate click) - Track in-flight adds in a Set so concurrent adds keep independent pending state and cannot be double-submitted - Surface failures with toast.error instead of swallowing the rejection - Extract the duplicated SkillTile into a shared workspace component Also document the new BlockMeta.skills field in the add-block and validate-integration skills (+ blocks AGENTS.md): skills must be grounded in the block's tools.access and sourced from real online use cases, never invented. * fix(integrations): synchronous in-flight guard for skill add; align cursor docs - Guard handleAdd with a ref so two rapid clicks cannot both fire a create before the disabled state re-renders (pendingNames is async) - Fold the create-cache-merge rationale into the hook's TSDoc and drop non-TSDoc inline comments to match the repo convention - Align .cursor add-block/validate-integration command docs with the newer .claude/.agents versions: BlockMeta section + skills authoring/validation guidance (grounded in tools.access, sourced from real online use cases) * fix(integrations): gate skill Add/Added on authoritative workspace skills useSkills uses keepPreviousData, so during initial load or a workspace switch the list could be empty or a prior workspace's placeholder — making rows show a misleading Add (duplicate-submittable) or a false Added. Derive skillsReady from !isPending && !isPlaceholderData, only mark Added when ready, and disable Add until the current workspace's list has loaded. * chore(integrations): drop local-variable comments in skills section Keep to the repo's TSDoc-on-declarations convention — the in-flight guard and skillsReady derivation are self-evident from naming.
This commit is contained in:
@@ -651,6 +651,14 @@ export const {Service}BlockMeta = {
|
||||
alsoIntegrations: ['slack'], // Other blocks referenced in the prompt (optional)
|
||||
},
|
||||
],
|
||||
skills: [ // Optional but strongly encouraged
|
||||
{
|
||||
name: 'summarize-thread', // kebab-case, becomes the created skill's name
|
||||
description: 'One line: what it does and when to use it.',
|
||||
content:
|
||||
'# Summarize Thread\n\n...\n\n## Steps\n1. ...\n\n## Output\n...', // markdown
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
```
|
||||
|
||||
@@ -665,6 +673,16 @@ export const {Service}BlockMeta = {
|
||||
- **`alsoIntegrations`** names other block types (e.g. `'slack'`, `'linear'`) referenced in the template prompt — helps the catalog surface this template when those blocks are selected
|
||||
- Place the export **after** the main `{Service}Block` export, at the very bottom of the file
|
||||
|
||||
#### `skills` — curated, ready-to-add agent skills
|
||||
|
||||
`skills` is an optional array of `SuggestedSkill` (`{ name, description, content }`) shown on the integration's detail page; users click **Add** to create the skill in their workspace. Aim for 3–5 skills for mainstream services, 2–3 for niche/low-level ones.
|
||||
|
||||
- **`name`** — kebab-case, lowercase letters/numbers/hyphens, ≤ 64 chars, unique within the integration, verb-led (e.g. `summarize-thread`).
|
||||
- **`description`** — one line, ≤ 1024 chars: what it does and when to use it.
|
||||
- **`content`** — markdown instructions for the agent (literal `\n` for newlines): a `# Title`, then `## Steps` and an output/guidance section. Keep ~600–2000 chars.
|
||||
- **Ground every skill in operations the block actually exposes.** Cross-check each skill's steps against the block's `tools.access` list — never describe an action the integration cannot perform (e.g. "receive messages" when the block only sends).
|
||||
- **Skills MUST be derived from real, popular use cases found online — never invented.** Before adding a skill, web-search the service's documented use cases (vendor use-case/solutions pages, official docs describing the workflow, reputable "top automations for X" articles). If you cannot source a use case as something people genuinely do with the service, do not add it. Do not hallucinate skills.
|
||||
|
||||
### Register in the blocksMeta object
|
||||
|
||||
After adding `{Service}BlockMeta` to the block file, register it in `apps/sim/blocks/registry.ts`:
|
||||
@@ -888,6 +906,7 @@ All tool IDs referenced in `tools.access` and returned by `tools.config.tool` MU
|
||||
- [ ] Outputs match tool outputs
|
||||
- [ ] Block registered in `registry.ts` blocks object (alphabetically)
|
||||
- [ ] `{Service}BlockMeta` exported at bottom of block file with `tags` and `templates`
|
||||
- [ ] `skills` added to `{Service}BlockMeta`, each grounded in the block's `tools.access` and derived from a real online-sourced use case (not invented)
|
||||
- [ ] `BlockMeta` imported from `@/blocks/types` alongside `BlockConfig`
|
||||
- [ ] Block meta registered in `registry.ts` blocksMeta object (alphabetically)
|
||||
- [ ] If icon missing: asked user to provide SVG
|
||||
|
||||
@@ -207,6 +207,12 @@ For **each tool** in `tools.access`:
|
||||
- [ ] `authMode` is set correctly (`AuthMode.OAuth` or `AuthMode.ApiKey`)
|
||||
- [ ] Block is registered in `blocks/registry.ts` alphabetically
|
||||
|
||||
### BlockMeta Skills (catalog)
|
||||
- [ ] `{Service}BlockMeta.skills` is present (3–5 for mainstream services, 2–3 for niche/low-level)
|
||||
- [ ] **Every skill is grounded** — its steps only use operations the block exposes in `tools.access`; flag any skill that implies an unsupported action (e.g. "receive messages" when the block only sends)
|
||||
- [ ] **Every skill is real, not hallucinated** — web-search the service and confirm each skill maps to a popular use case attested online (vendor use-case/solutions pages, official docs describing the workflow, reputable "top automations for X" articles). Rewrite or remove any skill you cannot source as something people genuinely do with the service.
|
||||
- [ ] Each skill has a kebab-case `name` (≤64 chars, unique), a one-line `description`, and markdown `content` with `# Title` + `## Steps` + an output/guidance section
|
||||
|
||||
### Block Inputs
|
||||
- [ ] `inputs` section lists all subBlock params that the block accepts
|
||||
- [ ] Input types match the subBlock types
|
||||
|
||||
@@ -807,11 +807,25 @@ export const {Service}BlockMeta = {
|
||||
},
|
||||
// ... at least 6 more
|
||||
],
|
||||
skills: [ // SuggestedSkill[] — 3–5 mainstream, 2–3 niche
|
||||
{
|
||||
name: 'summarize-thread', // kebab-case, ≤64 chars, unique, verb-led
|
||||
description: 'One line: what it does and when to use it.', // ≤1024 chars
|
||||
content:
|
||||
'# Summarize Thread\n\n...\n\n## Steps\n1. ...\n\n## Output\n...', // markdown
|
||||
},
|
||||
// ... more
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
```
|
||||
|
||||
Derive templates from the service's real use cases. Each prompt should name a concrete trigger, transformation, and output — not a generic description of what the service does.
|
||||
|
||||
`skills` are curated, ready-to-add agent skills shown on the integration's detail page (users click **Add** to create them in their workspace). Two hard rules:
|
||||
|
||||
- **Ground every skill in operations the block actually exposes** — cross-check each skill's steps against `tools.access`. Never describe an action the integration cannot perform.
|
||||
- **Derive skills from real, popular use cases found online — never invent them.** Web-search the service's documented use cases (vendor use-case/solutions pages, official docs describing the workflow, reputable "top automations for X" articles) and only add a skill you can source as something people genuinely do with the service. Do not hallucinate skills.
|
||||
|
||||
## Checklist Before Finishing
|
||||
|
||||
- [ ] `integrationType` is set to the correct `IntegrationType` enum value
|
||||
@@ -831,6 +845,7 @@ Derive templates from the service's real use cases. Each prompt should name a co
|
||||
- [ ] Optional/rarely-used fields set to `mode: 'advanced'`
|
||||
- [ ] Timestamps and complex inputs have `wandConfig` enabled
|
||||
- [ ] Exported `{Service}BlockMeta` with at least 7 templates
|
||||
- [ ] `skills` added to `{Service}BlockMeta`, each grounded in `tools.access` and sourced from a real online use case (not invented)
|
||||
|
||||
## Final Validation (Required)
|
||||
|
||||
|
||||
@@ -197,6 +197,8 @@ For **each tool** in `tools.access`:
|
||||
- [ ] Has at least 7 templates, each with `icon`, `title`, `prompt`, `modules`, `category`, and `tags`
|
||||
- [ ] Prompts describe concrete use cases, not generic descriptions of what the service does
|
||||
- [ ] `alsoIntegrations` is set on any template whose prompt references another service
|
||||
- [ ] `skills` present (3–5 mainstream, 2–3 niche), each grounded in `tools.access` — flag any skill implying an unsupported action
|
||||
- [ ] **Each skill is real, not hallucinated** — web-search and confirm it maps to a popular use case attested online (vendor use-case pages, official docs describing the workflow, reputable "top automations" articles); rewrite/remove any you cannot source
|
||||
|
||||
### Block Inputs
|
||||
- [ ] `inputs` section lists all subBlock params that the block accepts
|
||||
|
||||
@@ -793,6 +793,47 @@ Use `wandConfig` for fields that are hard to fill out manually, such as timestam
|
||||
|
||||
All tool IDs referenced in `tools.access` and returned by `tools.config.tool` MUST use `snake_case` (e.g., `x_create_tweet`, `slack_send_message`). Never use camelCase or PascalCase.
|
||||
|
||||
## BlockMeta (Required)
|
||||
|
||||
Every block file must export a `{Service}BlockMeta` alongside the block — **minimum 7 templates**. Look at existing examples in `apps/sim/blocks/blocks/` (e.g. `browser_use.ts`, `google_sheets.ts`) for the pattern.
|
||||
|
||||
```typescript
|
||||
import type { BlockMeta } from '@/blocks/types'
|
||||
|
||||
export const {Service}BlockMeta = {
|
||||
tags: ['tag1', 'tag2'], // IntegrationTag[]
|
||||
templates: [
|
||||
{
|
||||
icon: {Service}Icon,
|
||||
title: '{Service} <use-case>', // 2–5 words
|
||||
prompt: 'Build a workflow that...', // specific use case, 1–3 sentences
|
||||
modules: ['agent', 'workflows'], // 'agent' | 'workflows' | 'tables' | 'files' | 'scheduled' | 'knowledge-base'
|
||||
category: 'operations', // 'operations' | 'marketing' | 'sales' | 'engineering' | 'productivity' | 'support' | 'popular'
|
||||
tags: ['automation'],
|
||||
alsoIntegrations: ['slack'], // optional — other block IDs referenced in the prompt
|
||||
featured: true, // optional
|
||||
},
|
||||
// ... at least 6 more
|
||||
],
|
||||
skills: [ // SuggestedSkill[] — 3–5 mainstream, 2–3 niche
|
||||
{
|
||||
name: 'summarize-thread', // kebab-case, ≤64 chars, unique, verb-led
|
||||
description: 'One line: what it does and when to use it.', // ≤1024 chars
|
||||
content:
|
||||
'# Summarize Thread\n\n...\n\n## Steps\n1. ...\n\n## Output\n...', // markdown
|
||||
},
|
||||
// ... more
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
```
|
||||
|
||||
Derive templates from the service's real use cases. Each prompt should name a concrete trigger, transformation, and output — not a generic description of what the service does.
|
||||
|
||||
`skills` are curated, ready-to-add agent skills shown on the integration's detail page (users click **Add** to create them in their workspace). Two hard rules:
|
||||
|
||||
- **Ground every skill in operations the block actually exposes** — cross-check each skill's steps against `tools.access`. Never describe an action the integration cannot perform.
|
||||
- **Derive skills from real, popular use cases found online — never invent them.** Web-search the service's documented use cases (vendor use-case/solutions pages, official docs describing the workflow, reputable "top automations for X" articles) and only add a skill you can source as something people genuinely do with the service. Do not hallucinate skills.
|
||||
|
||||
## Checklist Before Finishing
|
||||
|
||||
- [ ] `integrationType` is set to the correct `IntegrationType` enum value
|
||||
@@ -811,6 +852,8 @@ All tool IDs referenced in `tools.access` and returned by `tools.config.tool` MU
|
||||
- [ ] If triggers exist: `triggers` config set, trigger subBlocks spread
|
||||
- [ ] Optional/rarely-used fields set to `mode: 'advanced'`
|
||||
- [ ] Timestamps and complex inputs have `wandConfig` enabled
|
||||
- [ ] Exported `{Service}BlockMeta` with at least 7 templates
|
||||
- [ ] `skills` added to `{Service}BlockMeta`, each grounded in `tools.access` and sourced from a real online use case (not invented)
|
||||
|
||||
## Final Validation (Required)
|
||||
|
||||
|
||||
@@ -187,6 +187,14 @@ For **each tool** in `tools.access`:
|
||||
- [ ] `authMode` is set correctly (`AuthMode.OAuth` or `AuthMode.ApiKey`)
|
||||
- [ ] Block is registered in `blocks/registry.ts` alphabetically
|
||||
|
||||
### BlockMeta
|
||||
- [ ] `{Service}BlockMeta` is exported in the same file as the block
|
||||
- [ ] Has at least 7 templates, each with `icon`, `title`, `prompt`, `modules`, `category`, and `tags`
|
||||
- [ ] Prompts describe concrete use cases, not generic descriptions of what the service does
|
||||
- [ ] `alsoIntegrations` is set on any template whose prompt references another service
|
||||
- [ ] `skills` present (3–5 mainstream, 2–3 niche), each grounded in `tools.access` — flag any skill implying an unsupported action
|
||||
- [ ] **Each skill is real, not hallucinated** — web-search and confirm it maps to a popular use case attested online (vendor use-case pages, official docs describing the workflow, reputable "top automations" articles); rewrite/remove any you cannot source
|
||||
|
||||
### Block Inputs
|
||||
- [ ] `inputs` section lists all subBlock params that the block accepts
|
||||
- [ ] Input types match the subBlock types
|
||||
|
||||
@@ -27,3 +27,4 @@ export type {
|
||||
SelectableConfig,
|
||||
} from './resource/resource'
|
||||
export { EMPTY_CELL_PLACEHOLDER, Resource, ResourceTable } from './resource/resource'
|
||||
export { SkillTile } from './skill-tile'
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { SkillTile } from './skill-tile'
|
||||
@@ -0,0 +1,16 @@
|
||||
import { AgentSkillsIcon } from '@/components/icons'
|
||||
|
||||
/**
|
||||
* Square tile bearing the agent-skills glyph. Shared chrome for any surface
|
||||
* that lists a skill (the Skills page and integration detail pages) so the two
|
||||
* do not drift.
|
||||
*/
|
||||
export function SkillTile() {
|
||||
return (
|
||||
<div className='size-9 flex-shrink-0'>
|
||||
<div className='flex size-full items-center justify-center rounded-xl border border-[var(--border-1)] bg-[var(--surface-4)] dark:bg-[var(--surface-5)]'>
|
||||
<AgentSkillsIcon className='size-5 text-[var(--text-icon)]' />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
+15
-1
@@ -14,6 +14,7 @@ import {
|
||||
} from '@/lib/integrations'
|
||||
import { getServiceConfigByProviderId } from '@/lib/oauth'
|
||||
import { ConnectOAuthModal } from '@/app/workspace/[workspaceId]/components/connect-oauth-modal'
|
||||
import { IntegrationSkillsSection } from '@/app/workspace/[workspaceId]/integrations/[block]/integration-skills-section'
|
||||
import { ConnectServiceAccountModal } from '@/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal'
|
||||
import { IntegrationSection } from '@/app/workspace/[workspaceId]/integrations/components/integration-section'
|
||||
import { IntegrationTile } from '@/app/workspace/[workspaceId]/integrations/components/integrations-showcase'
|
||||
@@ -21,7 +22,11 @@ import {
|
||||
CONNECT_MODE,
|
||||
CONNECT_QUERY_PARAM,
|
||||
} from '@/app/workspace/[workspaceId]/integrations/connect-route'
|
||||
import { getTemplatesForBlock, type ScopedBlockTemplate } from '@/blocks/registry'
|
||||
import {
|
||||
getSuggestedSkillsForBlock,
|
||||
getTemplatesForBlock,
|
||||
type ScopedBlockTemplate,
|
||||
} from '@/blocks/registry'
|
||||
import { useWorkspaceCredentials } from '@/hooks/queries/credentials'
|
||||
import { useOAuthReturnRouter } from '@/hooks/use-oauth-return'
|
||||
|
||||
@@ -46,6 +51,7 @@ export function IntegrationBlockDetail({ integration, workspaceId }: Integration
|
||||
const searchParams = useSearchParams()
|
||||
const Icon = blockTypeToIconMap[integration.type]
|
||||
const matchingTemplates = getTemplatesForBlock(integration.type)
|
||||
const suggestedSkills = getSuggestedSkillsForBlock(integration.type)
|
||||
const oauthService = resolveOAuthServiceForIntegration(integration)
|
||||
const [oauthOpen, setOAuthOpen] = useState(false)
|
||||
|
||||
@@ -210,6 +216,14 @@ export function IntegrationBlockDetail({ integration, workspaceId }: Integration
|
||||
</IntegrationSection>
|
||||
)}
|
||||
|
||||
{suggestedSkills.length > 0 && (
|
||||
<IntegrationSkillsSection
|
||||
skills={suggestedSkills}
|
||||
workspaceId={workspaceId}
|
||||
integrationType={integration.type}
|
||||
/>
|
||||
)}
|
||||
|
||||
{matchingTemplates.length > 0 && (
|
||||
<TemplatesSection
|
||||
integration={integration}
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
'use client'
|
||||
|
||||
import { useMemo, useRef, useState } from 'react'
|
||||
import { Check, Plus } from 'lucide-react'
|
||||
import { usePostHog } from 'posthog-js/react'
|
||||
import { Chip, toast } from '@/components/emcn'
|
||||
import { captureEvent } from '@/lib/posthog/client'
|
||||
import { SkillTile } from '@/app/workspace/[workspaceId]/components'
|
||||
import type { SuggestedSkill } from '@/blocks/types'
|
||||
import { useCreateSkill, useSkills } from '@/hooks/queries/skills'
|
||||
|
||||
interface IntegrationSkillsSectionProps {
|
||||
skills: readonly SuggestedSkill[]
|
||||
workspaceId: string
|
||||
integrationType: string
|
||||
}
|
||||
|
||||
interface SkillRowProps {
|
||||
skill: SuggestedSkill
|
||||
added: boolean
|
||||
pending: boolean
|
||||
disabled: boolean
|
||||
onAdd: () => void
|
||||
}
|
||||
|
||||
function SkillRow({ skill, added, pending, disabled, onAdd }: SkillRowProps) {
|
||||
return (
|
||||
<div className='flex items-center gap-2.5 rounded-lg p-2'>
|
||||
<SkillTile />
|
||||
<div className='flex min-w-0 flex-1 flex-col'>
|
||||
<span className='truncate text-[14px] text-[var(--text-body)]'>{skill.name}</span>
|
||||
<span className='truncate text-[12px] text-[var(--text-muted)]'>{skill.description}</span>
|
||||
</div>
|
||||
{added ? (
|
||||
<Chip variant='filled' leftIcon={Check} disabled flush>
|
||||
Added
|
||||
</Chip>
|
||||
) : (
|
||||
<Chip variant='primary' leftIcon={Plus} onClick={onAdd} disabled={disabled} flush>
|
||||
{pending ? 'Adding...' : 'Add'}
|
||||
</Chip>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Curated, research-backed skills for an integration. Each row adds the skill
|
||||
* to the workspace via the same `useCreateSkill` mutation the Skills page uses;
|
||||
* `useSkills` is the single source of truth for the "Added" state, so a skill
|
||||
* removed elsewhere correctly reverts to "Add".
|
||||
*/
|
||||
export function IntegrationSkillsSection({
|
||||
skills,
|
||||
workspaceId,
|
||||
integrationType,
|
||||
}: IntegrationSkillsSectionProps) {
|
||||
const posthog = usePostHog()
|
||||
const { data: existingSkills = [], isPending, isPlaceholderData } = useSkills(workspaceId)
|
||||
const createSkill = useCreateSkill()
|
||||
const skillsReady = !isPending && !isPlaceholderData
|
||||
const [pendingNames, setPendingNames] = useState<ReadonlySet<string>>(new Set())
|
||||
const inFlightRef = useRef<Set<string>>(new Set())
|
||||
|
||||
const existingNames = useMemo(() => new Set(existingSkills.map((s) => s.name)), [existingSkills])
|
||||
|
||||
const handleAdd = async (skill: SuggestedSkill, position: number) => {
|
||||
if (inFlightRef.current.has(skill.name)) return
|
||||
inFlightRef.current.add(skill.name)
|
||||
setPendingNames((prev) => new Set(prev).add(skill.name))
|
||||
try {
|
||||
await createSkill.mutateAsync({ workspaceId, skill })
|
||||
captureEvent(posthog, 'integration_skill_added', {
|
||||
workspace_id: workspaceId,
|
||||
integration_type: integrationType,
|
||||
skill_name: skill.name,
|
||||
position,
|
||||
skill_count: skills.length,
|
||||
})
|
||||
} catch {
|
||||
toast.error(`Failed to add "${skill.name}" — please try again`)
|
||||
} finally {
|
||||
inFlightRef.current.delete(skill.name)
|
||||
setPendingNames((prev) => {
|
||||
const next = new Set(prev)
|
||||
next.delete(skill.name)
|
||||
return next
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<section className='flex flex-col'>
|
||||
<span className='pl-0.5 text-[var(--text-muted)] text-small'>Skills</span>
|
||||
<div className='mt-[9px] mb-3 h-px bg-[var(--border)]' />
|
||||
<div className='-mx-2 flex flex-col gap-y-0.5'>
|
||||
{skills.map((skill, index) => (
|
||||
<SkillRow
|
||||
key={skill.name}
|
||||
skill={skill}
|
||||
added={skillsReady && existingNames.has(skill.name)}
|
||||
pending={pendingNames.has(skill.name)}
|
||||
disabled={pendingNames.has(skill.name) || !skillsReady}
|
||||
onAdd={() => handleAdd(skill, index)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
ChipModalHeader,
|
||||
Search,
|
||||
} from '@/components/emcn'
|
||||
import { AgentSkillsIcon } from '@/components/icons'
|
||||
import { SkillTile } from '@/app/workspace/[workspaceId]/components'
|
||||
import { IntegrationTabsHeader } from '@/app/workspace/[workspaceId]/integrations/components/integration-tabs-header'
|
||||
import { ShowcaseWithExplore } from '@/app/workspace/[workspaceId]/integrations/components/showcase-with-explore'
|
||||
import { SkillModal } from '@/app/workspace/[workspaceId]/skills/components/skill-modal'
|
||||
@@ -29,16 +29,6 @@ const logger = createLogger('SkillsSettings')
|
||||
|
||||
const SKILLS_LABEL = 'Skills'
|
||||
|
||||
function SkillTile() {
|
||||
return (
|
||||
<div className='size-9 flex-shrink-0'>
|
||||
<div className='flex size-full items-center justify-center rounded-xl border border-[var(--border-1)] bg-[var(--surface-4)] dark:bg-[var(--surface-5)]'>
|
||||
<AgentSkillsIcon className='size-5 text-[var(--text-icon)]' />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
interface SkillItemProps {
|
||||
name: string
|
||||
description: string
|
||||
|
||||
@@ -10,3 +10,4 @@ These rules apply to block definitions under `apps/sim/blocks/**`.
|
||||
- Put type coercion in `tools.config.params`, never in `tools.config.tool`.
|
||||
- When supporting file inputs, follow the basic/advanced pattern and normalize with `normalizeFileInput`.
|
||||
- Keep block outputs aligned with what the referenced tools actually return.
|
||||
- `{Service}BlockMeta.skills` (curated, one-click-add agent skills shown on the integration detail page) must be grounded in operations the block exposes via `tools.access` and derived from real, popular use cases found online — web-search and source each one; never invent or hallucinate skills.
|
||||
|
||||
@@ -690,4 +690,27 @@ export const AgentMailBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'triage-inbox-messages',
|
||||
description:
|
||||
'Read new messages in an AgentMail inbox, classify them, and reply or escalate as needed.',
|
||||
content:
|
||||
'# Triage Inbox Messages\n\nProcess unread email in an AgentMail inbox and act on each thread.\n\n## Steps\n1. List recent messages in the inbox and identify which threads are unread or unanswered.\n2. Read each thread for context including prior replies.\n3. Classify intent (question, request, spam, follow-up needed) and urgency.\n4. Draft and send a reply on the thread for routine items, or escalate by flagging the ones needing a human.\n\n## Output\nA summary of threads handled: who, the classification, and the action taken (replied, escalated, ignored).',
|
||||
},
|
||||
{
|
||||
name: 'extract-verification-code',
|
||||
description:
|
||||
'Read a verification or OTP email in an AgentMail inbox and extract the code or confirmation link.',
|
||||
content:
|
||||
'# Extract Verification Code\n\nPull a 2FA/OTP code or confirmation link from an email so an agent can complete a signup or login flow.\n\n## Steps\n1. Search the inbox for the most recent message from the expected sender or matching the subject.\n2. Read the message body and extract the verification code or the confirmation URL.\n3. Return only the code or link.\n\n## Output\nThe extracted code or link. If multiple recent matches exist, return the newest and note its timestamp.',
|
||||
},
|
||||
{
|
||||
name: 'send-and-track-outreach',
|
||||
description:
|
||||
'Send an email from an AgentMail inbox and monitor the thread for a reply to continue the conversation.',
|
||||
content:
|
||||
'# Send and Track Outreach\n\nSend an outbound email and follow the resulting thread.\n\n## Steps\n1. Compose the message with a clear subject and body from the provided details.\n2. Send it from the AgentMail inbox to the recipient.\n3. Check the thread for a reply; when one arrives, read it and determine the next action.\n\n## Output\nConfirm the message was sent with the thread ID. When a reply arrives, summarize it and recommend the next step.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -822,4 +822,27 @@ export const AgentPhoneBlockMeta = {
|
||||
alsoIntegrations: ['zendesk'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'send-sms-notification',
|
||||
description:
|
||||
'Send an SMS or iMessage from an AgentPhone number to notify or remind a recipient.',
|
||||
content:
|
||||
'# Send SMS Notification\n\nSend a text message to a person from an AgentPhone number.\n\n## Steps\n1. Determine the sending number and the recipient phone number.\n2. Write a clear, concise message (reminder, alert, confirmation, or update).\n3. Send the SMS or iMessage.\n\n## Output\nConfirm the message was sent with the recipient number and a short preview of the text. Note any send failure.',
|
||||
},
|
||||
{
|
||||
name: 'place-outbound-call',
|
||||
description:
|
||||
'Place a voice call from an AgentPhone number to deliver a message or run a short scripted interaction.',
|
||||
content:
|
||||
'# Place Outbound Call\n\nMake a voice call from an AgentPhone number for reminders, confirmations, or notifications.\n\n## Steps\n1. Determine the AgentPhone number to call from and the destination number.\n2. Prepare the spoken message or script to deliver.\n3. Place the call and deliver the message.\n\n## Output\nConfirm the call was placed with the destination number and the message delivered. Report call status or transcript if available.',
|
||||
},
|
||||
{
|
||||
name: 'provision-and-respond',
|
||||
description:
|
||||
'Provision a phone number and handle inbound SMS by reading the message and sending an appropriate reply.',
|
||||
content:
|
||||
'# Provision and Respond\n\nSet up a phone number and respond to incoming texts.\n\n## Steps\n1. Provision a US or Canadian phone number if one is not already assigned.\n2. Read inbound SMS messages received on that number.\n3. For each message, determine intent and send a relevant reply.\n\n## Output\nReport the provisioned number, the inbound messages handled, and the replies sent.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -504,4 +504,27 @@ export const AgiloftBlockMeta = {
|
||||
alsoIntegrations: ['linear'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'flag-expiring-contracts',
|
||||
description:
|
||||
'Query Agiloft for contracts approaching their renewal or expiration date and report the ones at risk.',
|
||||
content:
|
||||
'# Flag Expiring Contracts\n\nFind contracts in Agiloft that are nearing expiration or auto-renewal so the team can act in time.\n\n## Steps\n1. Query the contract records for upcoming expiration or renewal dates within the target window.\n2. For each match, read key terms: counterparty, value, renewal type, and notice period.\n3. Identify contracts with auto-renewal clauses that need a decision before the notice deadline.\n\n## Output\nA list of at-risk contracts sorted by date, with counterparty, expiration date, renewal type, and recommended action.',
|
||||
},
|
||||
{
|
||||
name: 'create-contract-record',
|
||||
description:
|
||||
'Create a new contract or related record in Agiloft from provided deal or request details.',
|
||||
content:
|
||||
'# Create Contract Record\n\nAdd a new contract record to Agiloft from intake details.\n\n## Steps\n1. Map the provided details to the contract record fields (counterparty, type, value, start/end dates, owner).\n2. Set status to the correct initial stage in the lifecycle.\n3. Create the record and capture its ID.\n\n## Output\nConfirm the record was created with its ID and key fields. Note any required fields that were missing.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-contract-terms',
|
||||
description:
|
||||
'Read a contract record in Agiloft and produce a plain-language summary of its key obligations and dates.',
|
||||
content:
|
||||
'# Summarize Contract Terms\n\nTurn an Agiloft contract record into a concise brief.\n\n## Steps\n1. Read the contract record and its key fields and attached terms.\n2. Identify obligations, payment terms, renewal/termination clauses, and critical dates.\n3. Note any unusual or high-risk terms.\n\n## Output\nA short brief: parties, term, value, key obligations, critical dates, and any risk flags. Keep it readable for non-lawyers.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -645,4 +645,27 @@ export const AhrefsBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'analyze-competitor-backlinks',
|
||||
description:
|
||||
"Pull a competitor domain's backlink profile from Ahrefs and surface link-building opportunities.",
|
||||
content:
|
||||
"# Analyze Competitor Backlinks\n\nUse Ahrefs to study a competitor's backlinks and find outreach targets.\n\n## Steps\n1. Run a backlink/referring-domains report for the competitor URL or domain.\n2. Identify high-authority referring domains and the anchor texts they use.\n3. Compare against your own domain to find sites linking to them but not you.\n\n## Output\nA prioritized list of link opportunities: referring domain, authority, linked page, and why it is worth pursuing.",
|
||||
},
|
||||
{
|
||||
name: 'keyword-research-report',
|
||||
description:
|
||||
'Research keywords in Ahrefs for a topic and report volume, difficulty, and ranking opportunities.',
|
||||
content:
|
||||
'# Keyword Research Report\n\nBuild a keyword opportunity report from Ahrefs data.\n\n## Steps\n1. Pull the organic keywords a competitor domain already ranks for to source candidate keywords for the topic.\n2. Run a keyword overview on the most relevant candidates to collect search volume and keyword difficulty.\n3. Highlight keywords with meaningful volume and lower difficulty as quick wins.\n\n## Output\nA table of keywords with volume and difficulty, grouped into quick wins vs long-term targets, with a short recommendation.',
|
||||
},
|
||||
{
|
||||
name: 'track-organic-rankings',
|
||||
description:
|
||||
"Pull a domain's organic keyword rankings from Ahrefs and report top movers and lost positions.",
|
||||
content:
|
||||
'# Track Organic Rankings\n\nReport how a domain is ranking in organic search using Ahrefs.\n\n## Steps\n1. Pull the organic keywords report for the target domain.\n2. Identify the top-ranking keywords and their positions.\n3. Compare against a prior snapshot if available to find gains and losses.\n\n## Output\nA summary of top organic keywords, notable position gains and drops, and pages that may need attention.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -432,4 +432,27 @@ export const AirtableBlockMeta = {
|
||||
alsoIntegrations: ['gmail'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'sync-records-to-table',
|
||||
description:
|
||||
'Parse incoming emails, forms, or documents and create or update structured Airtable records.',
|
||||
content:
|
||||
'# Sync Records to Airtable\n\nTurn unstructured inbound data into clean Airtable records.\n\n## Steps\n1. Read the source content (email body, form payload, or document text).\n2. Extract the fields that map to the target table columns (name, email, company, amount, status, etc.).\n3. Search the table for an existing record matching a unique key (such as email or order ID).\n4. Update the existing record if found; otherwise create a new one.\n5. Set any derived fields (category, priority, owner) based on the content.\n\n## Output\nReport how many records were created vs updated and list the record IDs. Flag any rows skipped for missing required fields.',
|
||||
},
|
||||
{
|
||||
name: 'triage-and-route-records',
|
||||
description:
|
||||
'Classify new Airtable records (leads, tickets, requests) and assign owner, priority, and due dates.',
|
||||
content:
|
||||
'# Triage and Route Records\n\nAutomatically qualify and route new Airtable records.\n\n## Steps\n1. List recently created records in the target table.\n2. For each record, read the free-text fields (notes, message, transcript) and classify intent, urgency, and category.\n3. Set the owner, priority, and status fields based on the classification.\n4. Compute and set a due date for time-sensitive items.\n\n## Output\nSummarize the records triaged grouped by owner and priority. Note any records that need human review.',
|
||||
},
|
||||
{
|
||||
name: 'generate-status-report',
|
||||
description:
|
||||
'Query an Airtable table or view and produce a rolled-up status report of progress, blockers, and trends.',
|
||||
content:
|
||||
'# Generate Status Report\n\nBuild a concise report from an Airtable table or view.\n\n## Steps\n1. Read records from the specified table or filtered view.\n2. Group by the relevant dimension (project, status, owner, or stage).\n3. Count totals per group and identify overdue or stalled items.\n4. Highlight notable changes or anomalies in the data.\n\n## Output\nA short report: totals per group, items at risk, and 2-3 takeaways. Keep it scannable with bullet points.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -172,4 +172,20 @@ export const AirweaveBlockMeta = {
|
||||
tags: ['research', 'reporting'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'answer-from-collection',
|
||||
description:
|
||||
'Search an Airweave collection across synced sources and answer a question with grounded, cited results.',
|
||||
content:
|
||||
'# Answer From Collection\n\nUse Airweave to retrieve current context across connected apps and answer a question.\n\n## Steps\n1. Take the user question and search the relevant Airweave collection.\n2. Review the top results, noting which source each came from (docs, tickets, CRM, etc.).\n3. Synthesize an answer grounded only in the retrieved content.\n4. If the collection returns nothing relevant, say so instead of guessing.\n\n## Output\nA concise answer with citations back to the source records. Do not include claims unsupported by the results.',
|
||||
},
|
||||
{
|
||||
name: 'build-context-brief',
|
||||
description:
|
||||
'Search an Airweave collection for a person, account, or project and compile a context brief from all sources.',
|
||||
content:
|
||||
'# Build Context Brief\n\nGather everything Airweave knows about a subject across synced sources into one brief.\n\n## Steps\n1. Search the collection for the subject (account name, project, customer, or person).\n2. Pull relevant hits from each source type and group them.\n3. Summarize the current state, recent activity, and any open items.\n\n## Output\nA short brief organized by source, highlighting the most recent and relevant facts plus open questions.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -716,4 +716,27 @@ export const AlgoliaBlockMeta = {
|
||||
tags: ['engineering', 'automation'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'answer-from-search-index',
|
||||
description:
|
||||
'Search an Algolia index for a user question and return a grounded answer with the matching records.',
|
||||
content:
|
||||
'# Answer From Search Index\n\nUse Algolia retrieval to answer questions over indexed content (docs, products, knowledge base).\n\n## Steps\n1. Take the user question and run a search against the relevant Algolia index.\n2. Apply filters or facets to narrow results (category, status, language) when appropriate.\n3. Read the top hits and synthesize an answer grounded only in the returned records.\n4. If no relevant hits are returned, say so rather than guessing.\n\n## Output\nA concise answer plus the titles and IDs of the records used. Do not invent content not present in the hits.',
|
||||
},
|
||||
{
|
||||
name: 'index-new-records',
|
||||
description:
|
||||
'Take new or updated content and push it into an Algolia index as searchable records.',
|
||||
content:
|
||||
'# Index New Records\n\nKeep an Algolia index in sync with new content.\n\n## Steps\n1. Collect the source items to index (products, articles, entries).\n2. Map each item to a record object with a stable objectID and the searchable/filterable attributes.\n3. Save the records to the target index, updating existing objectIDs in place.\n4. Verify by running a quick search for one of the new records.\n\n## Output\nReport how many records were added or updated and confirm one is retrievable via search.',
|
||||
},
|
||||
{
|
||||
name: 'audit-search-relevance',
|
||||
description:
|
||||
'Run a set of test queries against an Algolia index and report which return weak or empty results.',
|
||||
content:
|
||||
'# Audit Search Relevance\n\nCheck that important queries return good results from an Algolia index.\n\n## Steps\n1. Run each query in the provided test set against the index.\n2. Record the top results, total hit count, and whether the expected record appears.\n3. Flag queries that return zero hits, too many hits, or miss the expected record.\n\n## Output\nA table of queries with result counts and pass/fail, plus suggestions for synonyms or ranking tweaks where relevance is weak.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -819,4 +819,34 @@ export const AmplitudeBlockMeta = {
|
||||
alsoIntegrations: ['hex', 'slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'track-product-event',
|
||||
description:
|
||||
'Send a behavioral event to Amplitude with user and event properties for analytics.',
|
||||
content:
|
||||
'# Track Product Event\n\nLog a user action to Amplitude so it shows up in analytics.\n\n## Steps\n1. Determine the event name and the user identifier (user ID or device ID).\n2. Attach relevant event properties (plan, source, value) and user properties.\n3. Send the event to Amplitude.\n\n## Output\nConfirm the event was sent with its name and the user it was attributed to. Note any required field that was missing.',
|
||||
},
|
||||
{
|
||||
name: 'segment-event-counts',
|
||||
description:
|
||||
'Run Amplitude event segmentation over a date range and report unique and total counts, optionally grouped by a property.',
|
||||
content:
|
||||
'# Segment Event Counts\n\nMeasure how often an event fires in Amplitude over a time window.\n\n## Steps\n1. Identify the event type and the start and end dates (YYYYMMDD) to analyze.\n2. Pick the measurement (uniques, totals, or average) and the interval (daily, weekly, monthly).\n3. Optionally group by a user or event property to break the counts down by segment.\n4. Run the event segmentation query and read the resulting time series.\n\n## Output\nThe series of counts per interval, the segment breakdown if grouped, and a callout of the largest movement versus the start of the range.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-engagement-metrics',
|
||||
description:
|
||||
'Pull Amplitude active users, top events, and revenue and summarize product engagement for a period.',
|
||||
content:
|
||||
'# Summarize Engagement Metrics\n\nProduce a short product engagement summary from Amplitude data.\n\n## Steps\n1. Query active and new users for the target period.\n2. Pull the most-triggered events with event segmentation to see what users do most.\n3. Pull revenue metrics for the same period.\n4. Compare each against the prior period to spot trends.\n\n## Output\nA concise summary: active users, top events, revenue, and notable trends versus the prior period.',
|
||||
},
|
||||
{
|
||||
name: 'lookup-user-activity',
|
||||
description:
|
||||
'Find a user in Amplitude by ID and pull their recent event activity and profile properties.',
|
||||
content:
|
||||
'# Lookup User Activity\n\nInvestigate a single user in Amplitude for support or debugging.\n\n## Steps\n1. Search for the user by user ID, device ID, or Amplitude ID to resolve their Amplitude ID.\n2. Pull the user activity stream for that Amplitude ID, ordered latest first.\n3. Optionally fetch the user profile to see their current properties.\n\n## Output\nA timeline of the user recent events plus key profile properties. Note the time range covered.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -309,4 +309,34 @@ export const ApifyBlockMeta = {
|
||||
tags: ['sales', 'monitoring'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'scrape-site-to-table',
|
||||
description:
|
||||
'Run an Apify actor to scrape a target website and write the extracted rows into a structured table. Use for one-off or recurring data extraction jobs.',
|
||||
content:
|
||||
'# Scrape Site to Table\n\nRun an Apify actor against a target site and load the results into a clean table.\n\n## Steps\n1. Pick the actor or saved task (e.g. a web scraper) and assemble its JSON input — start URLs, page or request limits, and proxy settings.\n2. Run the actor synchronously for small jobs, or asynchronously and poll Get Run for larger crawls.\n3. Once the run status is SUCCEEDED, fetch the dataset items, selecting only the fields you need.\n4. Normalize each item into consistent columns and write the rows to the destination table.\n\n## Output\nReport the run ID, final status, and row count. If the run failed, surface the error and the actor input that produced it so it can be retried.',
|
||||
},
|
||||
{
|
||||
name: 'monitor-prices',
|
||||
description:
|
||||
'Use an Apify scraper to capture competitor or product prices on a schedule, track history, and alert on changes. Use for price and stock monitoring.',
|
||||
content:
|
||||
'# Monitor Prices\n\nTrack pricing on target product pages over time and flag meaningful changes.\n\n## Steps\n1. Run the scraping actor with the product or category URLs to watch.\n2. From the dataset, extract product name, price, currency, and stock status for each item.\n3. Compare each price against the last recorded value for that product.\n4. Append the new snapshot to a price-history table.\n\n## Output\nList any products whose price dropped, rose, or went out of stock, with old and new values. If nothing changed, say so briefly.',
|
||||
},
|
||||
{
|
||||
name: 'build-lead-list',
|
||||
description:
|
||||
'Run an Apify directory or maps scraper to collect business listings and produce a deduplicated, CRM-ready lead list. Use for prospecting and lead generation.',
|
||||
content:
|
||||
'# Build Lead List\n\nCollect business listings from a directory and turn them into a usable prospect list.\n\n## Steps\n1. Run the directory or maps scraper actor with the search terms, location, and result limit.\n2. Fetch the dataset and pull company name, website, phone, email, and address for each listing.\n3. Drop entries missing the fields you require, then deduplicate by domain or phone.\n4. Write the cleaned rows to a lead table ready for enrichment or CRM import.\n\n## Output\nReport total listings scraped, how many passed filtering, and how many duplicates were removed.',
|
||||
},
|
||||
{
|
||||
name: 'collect-content-for-knowledge-base',
|
||||
description:
|
||||
'Use an Apify crawler to extract article or documentation text from a site and prepare it for ingestion into a knowledge base or RAG pipeline.',
|
||||
content:
|
||||
'# Collect Content for Knowledge Base\n\nCrawl a content site and gather clean text for downstream ingestion.\n\n## Steps\n1. Run the crawler actor with the start URLs and a request limit, scoped to the relevant section of the site.\n2. Fetch dataset items and extract title, URL, and main body text for each page.\n3. Strip navigation, boilerplate, and empty pages.\n4. Hand the cleaned documents to the knowledge base for chunking and indexing.\n\n## Output\nReport the number of pages crawled and ingested, and list any URLs that failed or returned no usable text.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -1442,4 +1442,41 @@ export const ApolloBlockMeta = {
|
||||
tags: ['sales', 'crm', 'automation', 'enrichment'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'build-prospect-list',
|
||||
description:
|
||||
'Search Apollo for people matching an ideal customer profile and produce a targeted prospect list. Use for outbound prospecting and territory building.',
|
||||
content:
|
||||
'# Build Prospect List\n\nFind decision-makers that match an ICP and assemble a clean prospect list.\n\n## Steps\n1. Translate the ICP into an Apollo people search — job titles, seniorities, locations, and company size or industry filters.\n2. Run the search, paging through results up to the requested count.\n3. For each person capture name, title, company, verified email status, and LinkedIn URL.\n4. Write the deduplicated prospects to a table for review or sequencing.\n\n## Output\nReport how many prospects matched and the filters used. Flag any with unverified or missing emails.',
|
||||
},
|
||||
{
|
||||
name: 'enrich-contacts',
|
||||
description:
|
||||
'Enrich one or many contacts through Apollo to refresh titles, emails, phones, and company data. Use to keep CRM records accurate before outreach.',
|
||||
content:
|
||||
'# Enrich Contacts\n\nFill in or refresh missing contact data using Apollo enrichment.\n\n## Steps\n1. Gather the contacts to enrich — a single person, or a batch for bulk enrich.\n2. Provide the strongest identifiers available (email, name plus company domain).\n3. Run people enrich or bulk enrich, optionally revealing personal emails or phone numbers.\n4. Merge the returned fields back onto each record, keeping existing values when enrichment returns nothing.\n\n## Output\nReport how many records were enriched versus left unmatched, and which fields were newly filled. Note any credits consumed.',
|
||||
},
|
||||
{
|
||||
name: 'sync-leads-to-crm',
|
||||
description:
|
||||
'Create or update Apollo contacts and accounts from an inbound lead, then map them into your CRM. Use to route new signups into pipeline.',
|
||||
content:
|
||||
'# Sync Leads to CRM\n\nTurn an inbound lead into structured Apollo records.\n\n## Steps\n1. Take the lead details and enrich the person and their company through Apollo.\n2. Create or update the matching Apollo account for the company.\n3. Create or update the contact, linking it to the account and setting owner and stage.\n4. Pass the enriched fields to the connected CRM to create or update the matching records.\n\n## Output\nReport whether each record was created or updated, with the resulting contact and account IDs.',
|
||||
},
|
||||
{
|
||||
name: 'add-prospects-to-sequence',
|
||||
description:
|
||||
'Search for matching contacts and add them to an Apollo email sequence. Use to launch or top up outbound campaigns.',
|
||||
content:
|
||||
'# Add Prospects to Sequence\n\nEnroll the right contacts into an outbound sequence.\n\n## Steps\n1. Identify the target sequence by name or ID, and confirm the sending email account.\n2. Gather the contact IDs to enroll — from a prior search or a provided list.\n3. Add the contacts to the sequence with the chosen sending account and initial status.\n4. Review which contacts were added versus skipped.\n\n## Output\nReport totals added and skipped, and the reason for each skip (already enrolled, unverified, missing ownership).',
|
||||
},
|
||||
{
|
||||
name: 'pipeline-deal-digest',
|
||||
description:
|
||||
'Search Apollo opportunities by stage and summarize new and at-risk deals into a digest. Use for recurring pipeline reviews.',
|
||||
content:
|
||||
'# Pipeline Deal Digest\n\nSummarize opportunity movement for a sales pipeline review.\n\n## Steps\n1. Search Apollo opportunities filtered by the stages you care about.\n2. For each deal capture name, amount, stage, owner, and close date.\n3. Group deals into new, advancing, and at-risk (stalled or past close date).\n4. Write a concise digest grouped by category.\n\n## Output\nA short digest: deal counts and total value per stage, with at-risk deals called out by name, owner, and reason.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -225,4 +225,34 @@ export const ArxivBlockMeta = {
|
||||
tags: ['research', 'content'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'search-recent-papers',
|
||||
description:
|
||||
'Search ArXiv for the most relevant or most recent papers on a topic and return a ranked, summarized list. Use for literature discovery and topic scans.',
|
||||
content:
|
||||
'# Search Recent Papers\n\nFind the papers most worth reading on a given topic.\n\n## Steps\n1. Build the ArXiv query from the topic, choosing the search field (title, abstract, or all) and a result limit.\n2. Sort by relevance for a broad scan, or by submitted date to surface the newest work.\n3. For each result capture title, authors, ArXiv ID, publication date, and abstract.\n4. Write a one-line summary per paper highlighting the contribution.\n\n## Output\nA ranked list of papers with ID, title, authors, date, and a one-line takeaway each. Lead with the most relevant.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-paper',
|
||||
description:
|
||||
'Fetch a specific ArXiv paper by ID and produce a structured summary of its contribution, method, and results. Use to digest a single paper quickly.',
|
||||
content:
|
||||
'# Summarize Paper\n\nProduce a structured read of one ArXiv paper.\n\n## Steps\n1. Fetch the paper details using its ArXiv ID.\n2. Read the abstract and metadata to identify the problem, approach, and headline results.\n3. Note the authors, publication date, and primary category.\n4. Write a structured summary.\n\n## Output\nA brief covering: problem addressed, method, key results, and why it matters — plus the ArXiv ID and link. Keep it tight and skip filler.',
|
||||
},
|
||||
{
|
||||
name: 'track-author-publications',
|
||||
description:
|
||||
"Retrieve an author's recent ArXiv papers and report new work since the last check. Use to follow specific researchers or labs.",
|
||||
content:
|
||||
"# Track Author Publications\n\nMonitor a researcher for new ArXiv output.\n\n## Steps\n1. Fetch the author's papers by name, sorted by submitted date.\n2. Compare the results against the previously seen list to find new entries.\n3. For each new paper capture title, ID, date, and abstract.\n4. Summarize what is new since the last check.\n\n## Output\nList only the new papers with title, ID, date, and a one-line summary. If there is nothing new, say so.",
|
||||
},
|
||||
{
|
||||
name: 'build-literature-review',
|
||||
description:
|
||||
'Search ArXiv on a topic, summarize the key papers, and assemble a themed literature review. Use to bootstrap research on a new area.',
|
||||
content:
|
||||
'# Build Literature Review\n\nAssemble a starting literature review for a research topic.\n\n## Steps\n1. Search ArXiv for the most relevant and most cited recent papers on the topic.\n2. Fetch details and summarize each selected paper.\n3. Cluster the papers into themes or sub-questions.\n4. Write a review that introduces the topic, walks through each theme citing the papers, and notes open gaps.\n\n## Output\nA structured review document with a theme-by-theme synthesis and a reference list of ArXiv IDs and titles.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -441,4 +441,27 @@ export const AsanaBlockMeta = {
|
||||
alsoIntegrations: ['github'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'create-task-from-request',
|
||||
description:
|
||||
'Turn an incoming request or message into a well-formed Asana task in the right project with assignee and due date. Use for intake and ticket creation.',
|
||||
content:
|
||||
'# Create Task from Request\n\nConvert an incoming request into a structured Asana task.\n\n## Steps\n1. Extract the work to be done, the relevant project, an assignee if named, and any due date.\n2. If the project is referenced by name, list projects to resolve its ID.\n3. Create the task with a clear name, a description capturing the request details, the project, assignee, and due date.\n4. Add a comment with any links or source context if helpful.\n\n## Output\nReport the created task name, its URL or ID, project, assignee, and due date.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-project-tasks',
|
||||
description:
|
||||
'Search tasks in an Asana project and summarize status, overdue items, and who owns what. Use for standups and project status checks.',
|
||||
content:
|
||||
'# Summarize Project Tasks\n\nProduce a status snapshot of an Asana project.\n\n## Steps\n1. Resolve the project, then search its tasks.\n2. For each task capture name, assignee, due date, and completion state.\n3. Group into completed, in progress, and overdue or due soon.\n4. Note any unassigned tasks or tasks with no due date.\n\n## Output\nA concise status summary: counts per group, overdue tasks called out by name and owner, and any gaps to address.',
|
||||
},
|
||||
{
|
||||
name: 'update-task-status',
|
||||
description:
|
||||
'Find an Asana task and update its fields — assignee, due date, completion, or add a progress comment. Use to keep tasks current from other systems.',
|
||||
content:
|
||||
'# Update Task Status\n\nKeep an Asana task in sync with the latest state.\n\n## Steps\n1. Identify the target task by ID, or search to find it by name.\n2. Read the current task to confirm it is the right one.\n3. Update the relevant fields — completion, assignee, or due date.\n4. Add a comment summarizing what changed and why.\n\n## Output\nReport which fields changed and confirm the task ID. If no matching task was found, say so.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -1040,4 +1040,27 @@ export const AshbyBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'add-candidate',
|
||||
description:
|
||||
'Create a candidate in Ashby from an inbound application or referral and attach them to a job. Use for sourcing and referral intake.',
|
||||
content:
|
||||
'# Add Candidate\n\nCapture a new candidate into Ashby and link them to the right role.\n\n## Steps\n1. Gather the candidate name, email, source, and the target job.\n2. If the job is named, list jobs to resolve its ID.\n3. Create the candidate, then create an application linking them to the job with the correct source.\n4. Add a note with referral context or screening details, and apply any relevant tags.\n\n## Output\nReport the created candidate and application IDs, the linked job, and the source applied.',
|
||||
},
|
||||
{
|
||||
name: 'advance-candidate-stage',
|
||||
description:
|
||||
'Move a candidate application to a new interview stage in Ashby and log the decision. Use to keep the pipeline moving after interviews.',
|
||||
content:
|
||||
'# Advance Candidate Stage\n\nProgress a candidate through the hiring pipeline.\n\n## Steps\n1. Find the application — by ID, or list applications for the candidate or job.\n2. Confirm the current stage by getting the application.\n3. Change the application stage to the target stage.\n4. Add a note capturing the rationale and any interview feedback.\n\n## Output\nConfirm the candidate, the stage moved from and to, and the note added.',
|
||||
},
|
||||
{
|
||||
name: 'pipeline-status-report',
|
||||
description:
|
||||
'List candidates and applications by status or job in Ashby and summarize pipeline health. Use for recruiting standups and weekly reports.',
|
||||
content:
|
||||
'# Pipeline Status Report\n\nSummarize the state of an Ashby hiring pipeline.\n\n## Steps\n1. List the relevant jobs, or focus on one role.\n2. List applications, grouping candidates by current stage and status (active, hired, archived).\n3. Flag candidates stalled in a stage or awaiting feedback.\n4. Note new candidates added since the last report.\n\n## Output\nA pipeline summary: candidate counts per stage and status, stalled candidates called out by name and role, and recent additions.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -542,4 +542,27 @@ export const AthenaBlockMeta = {
|
||||
alsoIntegrations: ['gmail'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'run-query',
|
||||
description:
|
||||
'Run a SQL query against data in S3 via Athena, wait for completion, and return the results. Use for ad-hoc analysis and reporting over your data lake.',
|
||||
content:
|
||||
'# Run Query\n\nExecute a SQL query in Athena and return the results.\n\n## Steps\n1. Compose the SQL, naming the database and confirming the output location.\n2. Start the query to obtain a query execution ID.\n3. Poll get query execution until the state is SUCCEEDED, FAILED, or CANCELLED.\n4. On success, fetch the query results and shape the rows into a clean table.\n\n## Output\nReturn the result rows plus the execution ID, data scanned, and runtime. On failure, surface the Athena error message and the SQL that caused it.',
|
||||
},
|
||||
{
|
||||
name: 'scheduled-metrics-report',
|
||||
description:
|
||||
'Run a saved or composed Athena query on a schedule to compute metrics and produce a report. Use for recurring KPI and usage reporting.',
|
||||
content:
|
||||
'# Scheduled Metrics Report\n\nCompute recurring metrics from data in S3.\n\n## Steps\n1. Use a named query, or compose the metrics SQL for the reporting period.\n2. Start the query and poll execution until it completes.\n3. Fetch the results and format the metrics for reporting.\n4. Compare against the prior period to highlight movement where relevant.\n\n## Output\nA metrics summary with current values, period-over-period change, and the execution ID for traceability.',
|
||||
},
|
||||
{
|
||||
name: 'manage-named-queries',
|
||||
description:
|
||||
'Create, look up, and list saved (named) queries in Athena to standardize reusable SQL. Use to maintain a library of vetted analytics queries.',
|
||||
content:
|
||||
'# Manage Named Queries\n\nMaintain a library of reusable Athena queries.\n\n## Steps\n1. To save a query, create a named query with a clear name, description, database, and the SQL body.\n2. To reuse one, list named queries or get a named query by ID to retrieve its SQL.\n3. Run the retrieved SQL via start query when execution is needed.\n4. Keep names and descriptions accurate so the right query is easy to find.\n\n## Output\nReport the named query ID and name for creates, or the resolved SQL for lookups.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -1398,4 +1398,34 @@ export const AttioBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'upsert-record',
|
||||
description:
|
||||
'Create or update a person, company, or deal record in Attio, matching on a key field to avoid duplicates. Use to sync external data into the CRM.',
|
||||
content:
|
||||
'# Upsert Record\n\nKeep an Attio record in sync without creating duplicates.\n\n## Steps\n1. Identify the target object (people, companies, or a custom object) and the matching attribute, such as email or domain.\n2. Assemble the record values to set.\n3. Use assert record to upsert on the matching attribute so an existing record is updated and a new one is created only when needed.\n4. Verify the resulting record by getting it back.\n\n## Output\nReport whether the record was created or updated and its record ID.',
|
||||
},
|
||||
{
|
||||
name: 'log-note-on-record',
|
||||
description:
|
||||
'Attach a note to an Attio record capturing a call, meeting, or update. Use to keep CRM context current after interactions.',
|
||||
content:
|
||||
'# Log Note on Record\n\nRecord context against the right Attio record.\n\n## Steps\n1. Find the target record — by ID, or search records to locate it by name or domain.\n2. Compose the note title and body summarizing the interaction or update.\n3. Create the note on that record.\n4. Optionally create a follow-up task if next steps were agreed.\n\n## Output\nConfirm the record the note was attached to and the note ID, plus any follow-up task created.',
|
||||
},
|
||||
{
|
||||
name: 'create-followup-task',
|
||||
description:
|
||||
'Create a task in Attio linked to a record with an owner and due date. Use to capture follow-ups and next steps from deals or conversations.',
|
||||
content:
|
||||
'# Create Follow-up Task\n\nTurn a next step into a tracked Attio task.\n\n## Steps\n1. Identify the related record and the work to be done.\n2. Determine the assignee and a due date.\n3. Create the task with a clear description, linked record, owner, and deadline.\n4. Confirm the task was created against the right record.\n\n## Output\nReport the created task ID, the linked record, assignee, and due date.',
|
||||
},
|
||||
{
|
||||
name: 'manage-list-pipeline',
|
||||
description:
|
||||
'Query and update entries in an Attio list to move records through a pipeline or segment. Use for managing deal stages and curated segments.',
|
||||
content:
|
||||
'# Manage List Pipeline\n\nMove records through an Attio list-based pipeline.\n\n## Steps\n1. Resolve the target list, then query list entries to see current state.\n2. Identify which entries need to change stage or attributes.\n3. Create, update, or remove list entries as needed to reflect the new state.\n4. Summarize the pipeline distribution after the changes.\n\n## Output\nReport which entries moved and their new stage, plus the resulting count of records per stage.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -697,4 +697,34 @@ export const AzureDevOpsBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'triage-build-failure',
|
||||
description:
|
||||
'Investigate a failed Azure DevOps build, pinpoint the failing stage, and summarize the root cause. Use when a pipeline run breaks.',
|
||||
content:
|
||||
'# Triage Build Failure\n\nDiagnose why an Azure DevOps build failed.\n\n## Steps\n1. Use Get Build Timeline for the build id to find which stage, job, or task failed.\n2. Use List Build Logs to locate the log id for the failing step, then Get Build Log to read its contents.\n3. Scan the log for the first error, the failing command, and the exit code; ignore noise after the initial failure.\n4. Optionally use Get Work Items Between Builds against the last successful build to see what changed.\n\n## Output\nReturn a concise root-cause summary: the failing stage/task, the key error line, the likely cause, and a suggested next action. Include a deep link to the run when available.',
|
||||
},
|
||||
{
|
||||
name: 'create-work-item',
|
||||
description:
|
||||
'Create a new Azure DevOps work item (Issue, Task, or Epic) with the right fields. Use to file bugs, tasks, or features from another system.',
|
||||
content:
|
||||
'# Create Work Item\n\nFile a structured Azure DevOps work item.\n\n## Steps\n1. Choose the work item type: Issue, Task, or Epic, matching the request.\n2. Use Create Work Item with a clear title and an HTML or plain-text description.\n3. Set context fields where known: assignee, priority (1-4), area path, iteration path, and semicolon-separated tags.\n4. For a Task, set Activity, Remaining Work, and Completed Work; for an Epic, set Start Date and Target Date.\n\n## Output\nReturn the new work item id, type, title, state, and a link. Confirm the assignee and iteration. If a required field is missing, ask for it rather than guessing.',
|
||||
},
|
||||
{
|
||||
name: 'generate-release-notes',
|
||||
description:
|
||||
'Compile release notes from the work items completed between two Azure DevOps builds. Use at release time to summarize what shipped.',
|
||||
content:
|
||||
'# Generate Release Notes\n\nProduce release notes for a build range.\n\n## Steps\n1. Identify the From Build ID (previous release) and To Build ID (current release).\n2. Use Get Work Items Between Builds to list the associated work items.\n3. For each work item, use Get Work Items Batch or Get Work Item to pull title, type, and state.\n4. Group items by type (Features/Epics, Tasks, Bugs/Issues) and write a one-line summary per item.\n\n## Output\nReturn formatted Markdown release notes grouped by category, each line linking the work item id and title. Add a short headline summary of the most user-facing changes at the top.',
|
||||
},
|
||||
{
|
||||
name: 'report-pipeline-health',
|
||||
description:
|
||||
'Summarize recent Azure DevOps pipeline run results to surface pass rate and regressions. Use for daily or weekly engineering health reports.',
|
||||
content:
|
||||
'# Report Pipeline Health\n\nSummarize recent pipeline reliability.\n\n## Steps\n1. Use List Pipelines to enumerate the pipelines you care about.\n2. For each, use List Pipeline Runs to pull recent runs within your window.\n3. Compute pass rate (succeeded vs total), average duration, and the count of recent failures per pipeline.\n4. Flag pipelines whose pass rate dropped or whose duration increased noticeably versus prior runs.\n\n## Output\nReturn a per-pipeline summary table (name, pass rate, avg duration, recent failures) and a short narrative calling out regressions and any pipeline that is consistently red.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -669,4 +669,34 @@ export const BoxBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'send-document-for-signature',
|
||||
description:
|
||||
'Send a Box document for e-signature and confirm the request. Use for contracts, NDAs, and approval forms that need a signer.',
|
||||
content:
|
||||
'# Send Document For Signature\n\nKick off a Box Sign request for one or more documents.\n\n## Steps\n1. Identify the Box file id(s) to sign (use Search or List Folder Items if you only have a name).\n2. Use Create Sign Request with the source file ids and the primary signer email; set the signer role (signer, approver, or final copy reader).\n3. Add a clear email subject and message, and add any additional signers as a JSON array of email/role objects.\n4. Optionally set a destination folder for the signed copy, days valid, and reminders.\n\n## Output\nReturn the sign request id, status, signer list, and the prepare/sign URL. Tell the user the request was sent and how to track it. If a file id cannot be resolved, ask for clarification.',
|
||||
},
|
||||
{
|
||||
name: 'track-signature-status',
|
||||
description:
|
||||
'Check the status of Box Sign requests and follow up on pending signers. Use to monitor outstanding e-signature requests.',
|
||||
content:
|
||||
'# Track Signature Status\n\nReport on outstanding and completed Box Sign requests.\n\n## Steps\n1. Use List Sign Requests to retrieve recent requests, paging with the marker when needed.\n2. For a specific request, use Get Sign Request with the sign request id to read per-signer status.\n3. Identify requests that are still pending versus signed, declined, or expired.\n4. For stalled requests, use Resend Sign Request to nudge signers, or Cancel Sign Request if it is no longer needed.\n\n## Output\nReturn a status summary per request: name, overall status, which signers have signed, and which are outstanding. Recommend resend or cancel actions for stale requests.',
|
||||
},
|
||||
{
|
||||
name: 'organize-files-into-folder',
|
||||
description:
|
||||
'Upload files into a structured Box folder, creating folders as needed. Use to file documents into a standard organized layout.',
|
||||
content:
|
||||
'# Organize Files Into Folder\n\nPlace documents into the correct Box folder structure.\n\n## Steps\n1. Determine the destination. Use List Folder Items or Search to find an existing folder, or Create Folder under the right parent (use "0" for root) if it does not exist.\n2. Upload each file with Upload File, setting the parent folder id and an explicit file name when needed.\n3. To reorganize existing files, use Update File to rename, move (set Move to Folder ID), tag, or describe them.\n4. Use Copy File when a document must live in more than one folder.\n\n## Output\nReturn the created folder id (if any) and a list of the files placed, each with its id, name, and final folder. Confirm the resulting structure.',
|
||||
},
|
||||
{
|
||||
name: 'search-box-content',
|
||||
description:
|
||||
'Find files and folders in Box matching a query and return their details. Use to locate documents before acting on them.',
|
||||
content:
|
||||
'# Search Box Content\n\nLocate documents in Box.\n\n## Steps\n1. Use Search with the query string. Narrow with optional filters: ancestor folder id, file extensions (e.g. pdf,docx), and content type (file, folder, or web link).\n2. Page through results with limit and offset if there are many matches.\n3. For promising hits, use Get File Info to confirm name, size, owner, and modified date.\n\n## Output\nReturn the matching items with id, name, type, owner, and last-modified date. If the query is ambiguous or returns too many results, suggest a tighter query or folder scope.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -169,4 +169,27 @@ export const BrandfetchBlockMeta = {
|
||||
alsoIntegrations: ['docusign'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'enrich-company-by-domain',
|
||||
description:
|
||||
'Look up a company by domain and return its brand assets and firmographics. Use to enrich a CRM record, lead, or account with logo, colors, and company data.',
|
||||
content:
|
||||
'# Enrich Company By Domain\n\nFetch brand and company data for a known domain.\n\n## Steps\n1. Use Get Brand with the company domain as the identifier (e.g. nike.com). A stock ticker, ISIN, or crypto symbol also works.\n2. Read the returned logos, colors, fonts, links, description, and company firmographics.\n3. Pick the best logo for the use case (prefer a transparent or themed variant) and the primary brand color.\n\n## Output\nReturn a tidy record: company name, domain, description, primary logo URL, primary brand color hex, social links, and key firmographics. If the quality score is low or the brand is unclaimed, note that the data may be incomplete.',
|
||||
},
|
||||
{
|
||||
name: 'resolve-brand-by-name',
|
||||
description:
|
||||
'Search for a brand by name to find its domain and logo when you only have the company name. Use to disambiguate or resolve a domain before deeper enrichment.',
|
||||
content:
|
||||
'# Resolve Brand By Name\n\nFind a brand when you only know its name.\n\n## Steps\n1. Use Search Brands with the company name (e.g. "Nike").\n2. Review the results array; each entry has a brand name, domain, and icon.\n3. Choose the best match by exact name and most likely official domain.\n4. Optionally follow up with Get Brand on the chosen domain for full assets and firmographics.\n\n## Output\nReturn the resolved brand name, domain, and icon URL. If several plausible matches exist, list the top candidates with their domains so the user can confirm.',
|
||||
},
|
||||
{
|
||||
name: 'collect-brand-assets-for-personalization',
|
||||
description:
|
||||
'Gather a prospect or customer brand kit (logo, colors, fonts) for personalizing decks, emails, or portals. Use ahead of personalized outreach or design work.',
|
||||
content:
|
||||
'# Collect Brand Assets For Personalization\n\nBuild a usable brand kit for a target company.\n\n## Steps\n1. Resolve the company domain (use Search Brands first if you only have a name).\n2. Use Get Brand to retrieve logos, colors, and fonts.\n3. Select assets fit for purpose: a high-contrast logo for a deck cover, the primary and secondary colors, and the brand font names.\n\n## Output\nReturn a brand kit object: logo URLs by theme (light/dark), an ordered color palette with hex values, and font names. Note any missing asset so the design step can fall back to a neutral default.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -414,4 +414,34 @@ export const BrightDataBlockMeta = {
|
||||
tags: ['ecommerce', 'research'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'scrape-page-content',
|
||||
description:
|
||||
'Fetch the content of a single web page through Bright Data Web Unlocker, bypassing bot blocks and geo-restrictions. Use to read a page an agent cannot otherwise access.',
|
||||
content:
|
||||
'# Scrape Page Content\n\nRetrieve a page that is normally blocked or geo-restricted.\n\n## Steps\n1. Use Scrape URL with the target URL and your unlocker zone (e.g. web_unlocker1).\n2. Choose the format: Raw HTML for full markup, or JSON for a parsed response.\n3. Set the Country code when the page differs by region.\n4. Run it and read the returned content and HTTP status code.\n\n## Output\nReturn the cleaned page content (text or relevant HTML) and the status code. If the status indicates a block or error, report it and suggest a different zone or country rather than returning empty content.',
|
||||
},
|
||||
{
|
||||
name: 'search-the-web',
|
||||
description:
|
||||
'Run a search-engine query through Bright Data SERP API and return ranked results. Use for keyword research, competitive monitoring, or grounding an answer in fresh results.',
|
||||
content:
|
||||
'# Search The Web\n\nGet structured search results for a query.\n\n## Steps\n1. Use SERP Search with the query and your SERP zone.\n2. Pick the search engine (Google, Bing, DuckDuckGo, or Yandex) and set country/language for localized results.\n3. Set the number of results to the amount you need.\n4. Read the results array (title, URL, snippet, rank).\n\n## Output\nReturn the ranked results as a list with title, URL, and snippet. Summarize the top findings for the user, and note the engine, country, and query used so the result is reproducible.',
|
||||
},
|
||||
{
|
||||
name: 'discover-pages-by-intent',
|
||||
description:
|
||||
'Find web pages that match a described intent using Bright Data Discover, optionally pulling page content. Use to gather sources on a topic without crafting exact queries.',
|
||||
content:
|
||||
'# Discover Pages By Intent\n\nFind relevant pages from a natural-language description.\n\n## Steps\n1. Use Discover with a search query and an Intent describing what you actually want (e.g. "official pricing pages and recent change notes").\n2. Set the number of results, country, and language as needed.\n3. Enable Include Page Content and choose Markdown or JSON when you want the page bodies, not just links.\n\n## Output\nReturn the discovered pages ranked by relevance with URL, title, and (if requested) extracted content. Summarize what was found and flag any low-relevance results so they can be filtered out.',
|
||||
},
|
||||
{
|
||||
name: 'run-dataset-scraper',
|
||||
description:
|
||||
'Trigger a Bright Data pre-built dataset scraper for structured extraction across many URLs and retrieve the results. Use for bulk structured data from sites like e-commerce or social.',
|
||||
content:
|
||||
'# Run Dataset Scraper\n\nExtract structured records across many URLs with a pre-built scraper.\n\n## Steps\n1. Identify the dataset scraper id for the target site (e.g. gd_...).\n2. For small batches (up to 20 URLs), use Sync Scrape to get results back inline; choose JSON, NDJSON, or CSV.\n3. For larger jobs, use Scrape Dataset, which returns a snapshot id.\n4. Poll Snapshot Status until it is ready, then use Download Snapshot to fetch the data. Use Cancel Snapshot to abort a job that is no longer needed.\n\n## Output\nReturn the structured records (or the snapshot id and status for async jobs). For async runs, report progress and only return data once the snapshot is complete.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -283,4 +283,27 @@ export const BrowserUseBlockMeta = {
|
||||
tags: ['marketing', 'monitoring'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'automate-web-task',
|
||||
description:
|
||||
'Drive a browser agent to complete a multi-step task on a website, like navigating, clicking, and submitting. Use when a site has no API and a human would normally do the clicks.',
|
||||
content:
|
||||
'# Automate Web Task\n\nHave the browser agent perform a goal-oriented task on the web.\n\n## Steps\n1. Write a clear, step-by-step Task describing the goal and any success condition (e.g. "log in, open Billing, download the latest invoice").\n2. Set the Start URL so the agent begins on the right page.\n3. Put any credentials or sensitive inputs in Variables (Secrets) and reference them in the task by name rather than pasting them inline.\n4. Restrict Allowed Domains to keep the agent on the intended site, and raise Max Steps for longer flows.\n\n## Output\nReturn whether the task succeeded, the final output, and the share URL for the recorded session so the run can be audited. If the agent gets stuck, report the last step and what blocked it.',
|
||||
},
|
||||
{
|
||||
name: 'extract-structured-data-from-site',
|
||||
description:
|
||||
'Use a browser agent to navigate a site and return data in a defined JSON schema. Use to pull structured records (prices, listings, table rows) from pages without an API.',
|
||||
content:
|
||||
'# Extract Structured Data From Site\n\nNavigate a website and return structured data.\n\n## Steps\n1. Write a Task that tells the agent what to find and where (e.g. "go to the pricing page and collect every plan name and monthly price").\n2. Set the Start URL and limit Allowed Domains to the target site.\n3. Provide a Structured Output Schema (stringified JSON schema) describing the exact fields you want back.\n4. Run it; the agent fills the schema from what it observes on the page.\n\n## Output\nReturn the data as objects matching the provided schema. Confirm each field was actually found on the page; if a field could not be located, leave it null and note it rather than fabricating a value.',
|
||||
},
|
||||
{
|
||||
name: 'fill-and-submit-form',
|
||||
description:
|
||||
'Have a browser agent fill out and submit a web form using supplied field values. Use for vendor portals, questionnaires, or applications that have no API.',
|
||||
content:
|
||||
'# Fill And Submit Form\n\nComplete a web form end to end.\n\n## Steps\n1. Describe the form and the mapping of values to fields in the Task (e.g. "fill the contact form: name, company, message, then submit").\n2. Set the Start URL to the form page and constrain Allowed Domains.\n3. Pass any private values through Variables (Secrets) so they are injected securely.\n4. Ask the agent to confirm the submission succeeded (look for a success message or confirmation page) before finishing.\n\n## Output\nReturn whether the form submitted successfully, any confirmation text or reference number shown, and the session share URL as an audit trail. If a required field was missing or validation failed, report which field and why.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -991,4 +991,34 @@ export const CalComBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'book-a-meeting',
|
||||
description:
|
||||
'Create a Cal.com booking for an attendee on a chosen event type and time. Use to schedule a call once you know the slot and attendee details.',
|
||||
content:
|
||||
'# Book A Meeting\n\nCreate a confirmed Cal.com booking.\n\n## Steps\n1. Identify the event type to book (select it or pass its numeric event type id).\n2. Set the Start Time as an ISO 8601 UTC timestamp.\n3. Provide the attendee name, email, and IANA time zone (e.g. America/New_York). Add guests or a duration override if needed.\n4. Create the booking.\n\n## Output\nReturn the booking UID, start and end time, attendee, and the meeting URL. Confirm the booking to the user. If the slot is unavailable, suggest checking available slots first and propose alternatives.',
|
||||
},
|
||||
{
|
||||
name: 'find-available-slots',
|
||||
description:
|
||||
'Look up open time slots for a Cal.com event type within a date range. Use before booking to offer the attendee valid times.',
|
||||
content:
|
||||
'# Find Available Slots\n\nRetrieve bookable time slots for an event type.\n\n## Steps\n1. Select the event type (or pass its id, or an event type slug plus username).\n2. Set the Start Time and End Time of the window to search (ISO 8601 UTC).\n3. Set the attendee time zone so slots are returned in their local time, and a duration if the event supports multiple lengths.\n4. Read the returned slots.\n\n## Output\nReturn the available slots as a clean list of start times in the requested time zone. Summarize the next few openings for the user; if none exist in the window, widen the range and retry.',
|
||||
},
|
||||
{
|
||||
name: 'reschedule-or-cancel-booking',
|
||||
description:
|
||||
'Move a Cal.com booking to a new time or cancel it, with a reason. Use to handle change or cancellation requests for an existing booking.',
|
||||
content:
|
||||
'# Reschedule Or Cancel Booking\n\nChange or cancel an existing Cal.com booking.\n\n## Steps\n1. Identify the booking by its UID (use List Bookings to find it if you only have attendee or date details).\n2. To move it, use Reschedule Booking with the new Start Time (ISO 8601) and an optional rescheduling reason.\n3. To cancel, use Cancel Booking with an optional cancellation reason.\n4. For request-based event types, use Confirm Booking or Decline Booking instead.\n\n## Output\nReturn the booking UID and its new status (rescheduled, cancelled, confirmed, or declined) plus the updated time when applicable. Confirm the change to the user.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-upcoming-bookings',
|
||||
description:
|
||||
'List and summarize upcoming Cal.com bookings for a period. Use for a daily agenda or to brief a host on their schedule.',
|
||||
content:
|
||||
'# Summarize Upcoming Bookings\n\nProduce an agenda from Cal.com bookings.\n\n## Steps\n1. Use List Bookings with status Upcoming.\n2. For each booking, read the title, start/end time, attendees, and meeting URL.\n3. Sort chronologically and group by day if the range spans multiple days.\n\n## Output\nReturn an ordered agenda: each entry with time, title, attendee name, and join link. Add a short headline like the number of meetings and the first start time so the host gets a quick read on the day.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -401,4 +401,27 @@ export const CalendlyBlockMeta = {
|
||||
alsoIntegrations: ['gmail'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'list-upcoming-meetings',
|
||||
description:
|
||||
'Pull upcoming Calendly scheduled events for a date range and summarize them. Use to brief a host on their schedule or build a daily agenda.',
|
||||
content:
|
||||
'# List Upcoming Meetings\n\nSummarize upcoming Calendly events.\n\n## Steps\n1. Use List Scheduled Events. Filter to status active and set Min Start Time and Max Start Time (ISO 8601 UTC) for the window.\n2. Filter by user or organization URI when scoping to a specific host (Get Current User returns your URI if needed).\n3. For each event, read name, start_time, end_time, location, and scheduling_url; page with the page token if there are many.\n\n## Output\nReturn an ordered agenda: each meeting with time, name, location/join link, and the invitee. Add a one-line headline (count and first start time) for a quick read.',
|
||||
},
|
||||
{
|
||||
name: 'get-event-attendees',
|
||||
description:
|
||||
'Retrieve the invitees for a Calendly scheduled event, including answers and contact info. Use to prep for a meeting or sync attendees to a CRM.',
|
||||
content:
|
||||
'# Get Event Attendees\n\nList who is attending a Calendly event.\n\n## Steps\n1. Identify the scheduled event by its UUID or URI (use List Scheduled Events to locate it).\n2. Use List Event Invitees for that event; optionally filter by email or status.\n3. Read each invitee record: name, email, status, and any questions and answers captured at booking.\n\n## Output\nReturn the invitees with name, email, status, and their intake answers. Flag canceled or no-show invitees so they can be handled differently from confirmed attendees.',
|
||||
},
|
||||
{
|
||||
name: 'cancel-scheduled-event',
|
||||
description:
|
||||
'Cancel a Calendly scheduled event with an optional reason. Use to call off a meeting and notify the invitee through Calendly.',
|
||||
content:
|
||||
'# Cancel Scheduled Event\n\nCall off a Calendly meeting.\n\n## Steps\n1. Find the scheduled event UUID or URI (use List Scheduled Events filtered by invitee email or time if you only have those details).\n2. Use Cancel Event with the event UUID and a clear cancellation reason.\n3. Calendly notifies the invitee automatically.\n\n## Output\nReturn the event UUID and confirmation that it was canceled. Echo the reason. If the event is already canceled or cannot be found, report that instead of retrying.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -140,4 +140,20 @@ export const ClayBlockMeta = {
|
||||
tags: ['sales', 'automation', 'enrichment'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'push-record-to-clay',
|
||||
description:
|
||||
'Send a single contact or account record to a Clay table via its populate webhook so Clay can enrich it. Use to hand a lead off to a Clay enrichment waterfall.',
|
||||
content:
|
||||
'# Push Record To Clay\n\nSend one record into a Clay table for enrichment.\n\n## Steps\n1. Get the Clay table populate webhook URL (Clay shows it on the table when you add a "Webhook" source).\n2. Build the record as a JSON object whose keys match the Clay table column names you want to populate (e.g. name, email, company, domain, linkedin_url).\n3. If the table has webhook authentication enabled, supply the auth token; it is sent in the x-clay-webhook-auth header.\n4. Populate the table with the record.\n\n## Output\nReturn the webhook response and metadata (status, timestamp). Confirm the record was accepted. Note that enrichment runs asynchronously inside Clay, so the enriched columns appear there, not in the immediate response.',
|
||||
},
|
||||
{
|
||||
name: 'bulk-load-list-into-clay',
|
||||
description:
|
||||
'Push many prospect or account rows from a table into a Clay workbook for enrichment. Use to seed a lead list or sync a CRM segment into Clay.',
|
||||
content:
|
||||
'# Bulk Load List Into Clay\n\nLoad a list of records into a Clay table.\n\n## Steps\n1. Gather the source rows (e.g. from a Sim table or a CRM query).\n2. Get the Clay table populate webhook URL and any auth token.\n3. For each row, map your fields to the Clay column names and populate the table once per record. Keep the JSON keys consistent across all records so columns line up.\n4. Send the records, pacing them if the list is large.\n\n## Output\nReturn a count of records pushed and any that failed (with the error). Remind the user that Clay enriches the rows on its side, and suggest they verify the row count in the Clay table once ingestion completes.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -483,4 +483,34 @@ export const ClerkBlockMeta = {
|
||||
alsoIntegrations: ['s3'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'find-user',
|
||||
description:
|
||||
'Look up a Clerk user by email, username, or name and return their profile. Use to resolve a user before acting on their account or syncing them elsewhere.',
|
||||
content:
|
||||
'# Find User\n\nLocate a Clerk user account.\n\n## Steps\n1. Use List Users with a Search Query (matches email, phone, username, or name), or the email/username filters for an exact match.\n2. If you already have the Clerk user id (user_...), use Get User instead for the full record.\n3. Review the returned profile: id, primary email, name, externalId, and flags like banned, locked, and twoFactorEnabled.\n\n## Output\nReturn the matched user id, primary email, name, and key status flags. If multiple users match, list the candidates with their emails so the right one can be confirmed; if none match, say so.',
|
||||
},
|
||||
{
|
||||
name: 'provision-user',
|
||||
description:
|
||||
'Create or update a Clerk user with email, name, and metadata. Use to onboard a user or sync profile changes from another system into Clerk.',
|
||||
content:
|
||||
'# Provision User\n\nCreate or update a Clerk user.\n\n## Steps\n1. To create, use Create User with at least an email address (and optionally phone, username, password, first/last name).\n2. To set application roles or app data, pass Public Metadata (visible to the frontend) and Private Metadata (server-only) as JSON.\n3. Set External ID to link the Clerk user to your own system id.\n4. To modify an existing user, use Update User with the user id and only the fields that change.\n\n## Output\nReturn the user id, primary email, and the metadata that was set. Confirm whether the user was created or updated. If a required field is missing or the email already exists, report it clearly.',
|
||||
},
|
||||
{
|
||||
name: 'audit-user-sessions',
|
||||
description:
|
||||
'List and inspect a Clerk user active sessions and revoke suspicious ones. Use for security review or forced sign-out.',
|
||||
content:
|
||||
'# Audit User Sessions\n\nReview and control Clerk sessions.\n\n## Steps\n1. Use List Sessions filtered by user id and status (e.g. active) to see current sessions.\n2. For a specific session, use Get Session to read its details: client, status, lastActiveAt.\n3. Identify sessions that look risky (stale, unexpected client, or flagged by your own logic).\n4. Use Revoke Session with the session id to force sign-out of any session that should not continue.\n\n## Output\nReturn the list of sessions reviewed with status and last-active time, and the ids of any sessions revoked. Summarize the action taken so the security trail is clear.',
|
||||
},
|
||||
{
|
||||
name: 'manage-organization',
|
||||
description:
|
||||
'Create a Clerk organization or look up its details and membership. Use when provisioning a new team or tenant in a multi-tenant app.',
|
||||
content:
|
||||
'# Manage Organization\n\nCreate or inspect a Clerk organization.\n\n## Steps\n1. To create, use Create Organization with the organization name and the Creator User ID (that user becomes the admin); optionally set a slug and max members.\n2. To inspect, use Get Organization by org id or slug, or List Organizations with a search query and include members count.\n3. Read back the org id, slug, members count, and limits.\n\n## Output\nReturn the organization id, name, slug, and member count. When creating, confirm the admin user and echo the org id so it can be linked back to your billing or CRM record.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -497,4 +497,27 @@ export const ClickHouseBlockMeta = {
|
||||
tags: ['data-analytics', 'data-warehouse'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'answer-question-with-sql',
|
||||
description:
|
||||
'Translate a plain-English analytics question into ClickHouse SQL, run it, and return the answer. Use for ad-hoc data questions over a ClickHouse table.',
|
||||
content:
|
||||
'# Answer Question With SQL\n\nTurn a natural-language question into a ClickHouse query and report the result.\n\n## Steps\n1. If you do not know the schema, use Introspect Schema or Describe Table to learn the columns and types.\n2. Write a ClickHouse SELECT using ClickHouse functions (toDate, uniqExact, quantile, etc.). Filter on primary/sorting keys and add a LIMIT for exploratory queries.\n3. Run it with the Query (SELECT) operation against the connection (host, port, database, credentials).\n4. Inspect the returned rows and row count.\n\n## Output\nReturn the result as a small table plus a one-sentence answer to the original question. Include the SQL you ran so it is reproducible. If the query errors, report the message and adjust the SQL rather than guessing blindly.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-metrics',
|
||||
description:
|
||||
'Run aggregation queries against ClickHouse and summarize key metrics and trends. Use for a recurring metrics digest or dashboard refresh.',
|
||||
content:
|
||||
'# Summarize Metrics\n\nCompute and summarize metrics from ClickHouse.\n\n## Steps\n1. Confirm the relevant table and time column with Describe Table if needed.\n2. Write aggregation queries (e.g. daily uniqExact users, counts, quantiles over a time window) using Query (SELECT).\n3. Run each query against the connection and collect the results.\n4. Compare against the prior period to spot increases, drops, or anomalies.\n\n## Output\nReturn a concise digest: the headline numbers, period-over-period change, and any notable anomalies. Keep it readable, lead with the most important metric, and note the time window covered.',
|
||||
},
|
||||
{
|
||||
name: 'bulk-insert-events',
|
||||
description:
|
||||
'Insert a batch of rows into a ClickHouse table after mapping them to the right columns. Use to ingest event or record payloads into ClickHouse.',
|
||||
content:
|
||||
'# Bulk Insert Events\n\nLoad a batch of records into a ClickHouse table.\n\n## Steps\n1. Use Describe Table to confirm the target column names and types.\n2. Map each incoming payload to those columns, coercing types (e.g. timestamps to DateTime format, numbers to the right width).\n3. Build a JSON array of row objects with consistent keys, then use Insert Rows (Bulk) against the table.\n4. Verify with Count Rows or a small SELECT.\n\n## Output\nReturn the number of rows inserted and any rows that were skipped or failed validation, with the reason. Confirm the new total row count so the caller knows ingestion succeeded.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -1169,4 +1169,27 @@ export const CloudflareBlockMeta = {
|
||||
tags: ['devops', 'enterprise', 'monitoring'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'audit-dns-records',
|
||||
description:
|
||||
'Pull all DNS records for a Cloudflare zone and report on misconfigurations, dangling records, and sensitive record changes.',
|
||||
content:
|
||||
'# Audit Cloudflare DNS Records\n\nExport and review the DNS configuration for a zone to catch misconfigurations and risky records.\n\n## Steps\n1. Resolve the zone ID for the target domain.\n2. List every DNS record (A, AAAA, CNAME, MX, TXT, NS) for the zone.\n3. Flag records that point to deprovisioned hosts, wildcard CNAMEs, missing SPF/DMARC TXT records, and proxied vs. unproxied mismatches.\n4. Group findings by record type and severity.\n\n## Output\nA prioritized list of DNS issues with the record name, type, current value, and recommended fix.',
|
||||
},
|
||||
{
|
||||
name: 'purge-cache',
|
||||
description:
|
||||
'Purge Cloudflare cache for specific URLs or an entire zone after a deploy, then confirm what was cleared.',
|
||||
content:
|
||||
'# Purge Cloudflare Cache\n\nClear cached content so visitors see the latest deploy.\n\n## Steps\n1. Identify the affected zone and the paths or hostnames that changed.\n2. Purge by specific files when possible; only purge everything for the zone if the change is global.\n3. Confirm the purge succeeded and note the timestamp.\n\n## Output\nA short confirmation listing the zone, the purged URLs (or "full zone"), and the purge time.',
|
||||
},
|
||||
{
|
||||
name: 'check-ssl-and-zone-settings',
|
||||
description:
|
||||
'Inspect SSL certificate status and security settings for Cloudflare zones and report drift from a desired baseline.',
|
||||
content:
|
||||
'# Check SSL and Zone Settings\n\nVerify SSL/TLS posture and key security settings across zones.\n\n## Steps\n1. List the target zones.\n2. For each zone read SSL mode, certificate status/expiry, minimum TLS version, and security level.\n3. Compare against the desired baseline (e.g. Full Strict, TLS 1.2+).\n4. Flag expiring certs and any setting weaker than the baseline.\n\n## Output\nA per-zone table of SSL status, settings, and any drift that needs remediation.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -400,4 +400,27 @@ export const CloudFormationBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'detect-stack-drift',
|
||||
description:
|
||||
'Run drift detection on CloudFormation stacks and summarize resources whose live config no longer matches the template.',
|
||||
content:
|
||||
'# Detect CloudFormation Stack Drift\n\nFind resources that have been changed outside of CloudFormation.\n\n## Steps\n1. List the target stacks (or accept a specific stack name).\n2. Initiate drift detection for each stack and poll until detection completes.\n3. Pull the drift results and isolate resources with status DRIFTED or DELETED.\n4. For each drifted resource, summarize the property differences.\n\n## Output\nA per-stack drift report listing each drifted resource, its type, and the specific properties that differ from the template.',
|
||||
},
|
||||
{
|
||||
name: 'inventory-stacks',
|
||||
description:
|
||||
'List CloudFormation stacks with their status, region, and resources to build a single inventory of deployed infrastructure.',
|
||||
content:
|
||||
'# Inventory CloudFormation Stacks\n\nBuild a unified view of all deployed stacks.\n\n## Steps\n1. List every stack and capture name, status, creation/update time, and region.\n2. For each stack, describe its resources and count them by type.\n3. Highlight stacks in failed or rollback states.\n\n## Output\nA table of stacks with status, region, resource count, and any stacks needing attention.',
|
||||
},
|
||||
{
|
||||
name: 'investigate-stack-failure',
|
||||
description:
|
||||
'Pull recent CloudFormation stack events to diagnose a failed create, update, or rollback and explain the root cause.',
|
||||
content:
|
||||
'# Investigate CloudFormation Stack Failure\n\nDiagnose why a stack operation failed.\n\n## Steps\n1. Describe the target stack and confirm its current status.\n2. Pull recent stack events, ordered newest first.\n3. Find the first FAILED event and read its resource status reason.\n4. Trace any dependent resource failures that cascaded from it.\n\n## Output\nA plain-English root-cause summary naming the failing resource, the error reason, and a suggested fix.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -950,4 +950,27 @@ export const CloudWatchBlockMeta = {
|
||||
alsoIntegrations: ['linear', 'slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'investigate-error-spike',
|
||||
description:
|
||||
'Run a CloudWatch Logs Insights query to find and summarize error spikes in a log group over a time window.',
|
||||
content:
|
||||
'# Investigate CloudWatch Error Spike\n\nFind the cause of an error spike using Logs Insights.\n\n## Steps\n1. Identify the relevant log group and the time window to investigate.\n2. Run a Logs Insights query that filters for error or exception lines and aggregates by error type.\n3. Pull representative sample log events for the top error groups.\n4. Correlate timing with any recent deploys or traffic changes.\n\n## Output\nA summary of the top error types, their counts, sample messages, and the likely cause.',
|
||||
},
|
||||
{
|
||||
name: 'check-metric-health',
|
||||
description:
|
||||
'Pull CloudWatch metric statistics for a resource and report whether key metrics are within healthy ranges.',
|
||||
content:
|
||||
'# Check CloudWatch Metric Health\n\nReview key metrics for a resource against expected thresholds.\n\n## Steps\n1. Identify the namespace, metric names, and dimensions for the resource (e.g. CPUUtilization, latency, error rate).\n2. Get metric statistics over the chosen window with an appropriate period and statistic (Average, p99, Sum).\n3. Compare values against healthy thresholds.\n\n## Output\nA per-metric summary with the current value, trend, and whether it is within a healthy range.',
|
||||
},
|
||||
{
|
||||
name: 'review-alarm-state',
|
||||
description:
|
||||
'List CloudWatch alarms, report which are in ALARM or INSUFFICIENT_DATA, and optionally mute noisy alarms.',
|
||||
content:
|
||||
'# Review CloudWatch Alarm State\n\nGet a snapshot of alarm health across the account.\n\n## Steps\n1. Describe alarms and group them by state (OK, ALARM, INSUFFICIENT_DATA).\n2. For alarms in ALARM, capture the metric, threshold, and reason.\n3. If asked, mute alarms that are known-noisy during a maintenance window and note them.\n\n## Output\nA list of alarms currently firing or missing data, with the metric and threshold for each.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -1675,4 +1675,34 @@ export const ConfluenceBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'publish-meeting-notes',
|
||||
description:
|
||||
'Create a Confluence page with structured meeting notes including attendees, decisions, and action items in the right space.',
|
||||
content:
|
||||
'# Publish Meeting Notes to Confluence\n\nTurn raw meeting notes into a clean, structured Confluence page.\n\n## Steps\n1. Confirm the target space and any parent page.\n2. Structure the notes into sections: attendees, agenda, decisions, and action items with owners.\n3. Create the page with a clear, dated title.\n4. Return the page URL.\n\n## Output\nA confirmation with the new page title and link, plus the list of action items captured.',
|
||||
},
|
||||
{
|
||||
name: 'update-doc-page',
|
||||
description:
|
||||
'Read an existing Confluence page, apply updates, and save it back, respecting version control to avoid conflicts.',
|
||||
content:
|
||||
'# Update a Confluence Page\n\nSafely edit an existing documentation page.\n\n## Steps\n1. Read the target page to get its current content and version number.\n2. Apply the requested changes to the body, preserving existing structure and formatting.\n3. Update the page, incrementing the version number by one to avoid optimistic-locking conflicts.\n4. If the update fails on a version conflict, re-read and retry.\n\n## Output\nA confirmation of the updated page with its new version number and link.',
|
||||
},
|
||||
{
|
||||
name: 'search-knowledge',
|
||||
description:
|
||||
'Search Confluence content for a topic and summarize the most relevant pages with links for quick reference.',
|
||||
content:
|
||||
'# Search Confluence Knowledge\n\nFind and summarize documentation on a topic.\n\n## Steps\n1. Search content using the topic keywords, optionally scoped to a space.\n2. Read the top matching pages.\n3. Summarize what each page covers and how it relates to the question.\n\n## Output\nA short briefing answering the question, with links to the source pages cited.',
|
||||
},
|
||||
{
|
||||
name: 'collect-page-feedback',
|
||||
description:
|
||||
'List and summarize comments on a Confluence page so you can triage feedback and open questions.',
|
||||
content:
|
||||
'# Collect Confluence Page Feedback\n\nGather and organize comments left on a page.\n\n## Steps\n1. Read the target page to confirm its identity.\n2. List all comments on the page.\n3. Group comments into themes: questions, corrections, and approvals.\n\n## Output\nA digest of comment themes with any unresolved questions flagged for follow-up.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -281,4 +281,20 @@ export const CrowdStrikeBlockMeta = {
|
||||
tags: ['enterprise', 'analysis'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'audit-identity-sensors',
|
||||
description:
|
||||
'Query CrowdStrike Identity Protection sensors and report on coverage, status, and devices missing protection.',
|
||||
content:
|
||||
'# Audit CrowdStrike Identity Sensors\n\nReview Identity Protection sensor coverage across the fleet.\n\n## Steps\n1. Query sensors, optionally filtered by status or hostname.\n2. For sensors of interest, pull detailed attributes (version, last seen, assigned policy).\n3. Flag sensors that are offline, stale, or out of policy.\n\n## Output\nA coverage report listing healthy sensors, plus any that are offline, stale, or misconfigured for SOC review.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-sensor-aggregates',
|
||||
description:
|
||||
'Pull documented CrowdStrike sensor aggregates and summarize the fleet distribution by version, status, or platform.',
|
||||
content:
|
||||
'# Summarize CrowdStrike Sensor Aggregates\n\nBuild a high-level picture of the sensor fleet.\n\n## Steps\n1. Request the documented sensor aggregates (e.g. counts by version, status, or platform).\n2. Compute the distribution and identify outliers, such as a large share of outdated versions.\n3. Compare against the expected baseline.\n\n## Output\nA fleet summary with key counts and any segments that need attention (outdated, offline).',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -351,4 +351,27 @@ export const CursorBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'launch-coding-agent',
|
||||
description:
|
||||
'Launch a Cursor cloud agent on a GitHub repository with a clear task prompt and report the agent id and starting status.',
|
||||
content:
|
||||
'# Launch a Cursor Coding Agent\n\nKick off an autonomous Cursor agent to work on a repo.\n\n## Steps\n1. Confirm the target repository and the task to perform.\n2. Write a precise prompt: what to change, constraints, and acceptance criteria.\n3. Launch the agent with the chosen model and repository.\n4. Capture the agent id and initial status.\n\n## Output\nA confirmation with the agent id, repository, and the task prompt it was given.',
|
||||
},
|
||||
{
|
||||
name: 'track-agent-progress',
|
||||
description:
|
||||
'Poll a Cursor agent for status and conversation updates and summarize what it has done so far.',
|
||||
content:
|
||||
'# Track Cursor Agent Progress\n\nMonitor a running Cursor agent.\n\n## Steps\n1. Get the agent status for the given agent id.\n2. Pull the conversation to see the latest actions and reasoning.\n3. If the agent is finished, list its artifacts; if blocked, identify why.\n\n## Output\nA status summary describing progress, current state, and any blockers or produced artifacts.',
|
||||
},
|
||||
{
|
||||
name: 'send-agent-followup',
|
||||
description:
|
||||
'Send a follow-up instruction to an in-progress Cursor agent to refine or redirect its work.',
|
||||
content:
|
||||
'# Send a Cursor Agent Follow-up\n\nGuide an active agent with additional instructions.\n\n## Steps\n1. Confirm the agent id and review its recent conversation.\n2. Compose a clear follow-up message addressing what to change or add.\n3. Add the follow-up to the agent.\n4. Note that the agent has resumed work.\n\n## Output\nA confirmation that the follow-up was delivered, with the instruction sent.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -741,4 +741,34 @@ export const DagsterBlockMeta = {
|
||||
alsoIntegrations: ['databricks'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'launch-pipeline-run',
|
||||
description:
|
||||
'Launch a Dagster job run with the right config and report the run id and starting status.',
|
||||
content:
|
||||
'# Launch a Dagster Pipeline Run\n\nKick off a data pipeline job.\n\n## Steps\n1. List jobs to confirm the target job name.\n2. Assemble the run config (partitions, tags, resources) for the run.\n3. Launch the run and capture the run id.\n4. Confirm the run entered the queue or started.\n\n## Output\nA confirmation with the run id, job name, and initial status.',
|
||||
},
|
||||
{
|
||||
name: 'monitor-failed-runs',
|
||||
description:
|
||||
'List recent Dagster runs, surface failures, and pull logs to diagnose why a run failed.',
|
||||
content:
|
||||
'# Monitor Failed Dagster Runs\n\nFind and diagnose pipeline failures.\n\n## Steps\n1. List recent runs and filter to those in a failed state.\n2. For each failed run, get the run details and pull its logs.\n3. Identify the failing step/op and the error message.\n4. Decide whether a re-execute of the failed steps is appropriate.\n\n## Output\nA per-run failure summary with the failing op, error, and a recommendation (retry or investigate).',
|
||||
},
|
||||
{
|
||||
name: 'reexecute-failed-run',
|
||||
description:
|
||||
'Re-execute a failed Dagster run from the point of failure and confirm the new run started.',
|
||||
content:
|
||||
'# Re-execute a Failed Dagster Run\n\nRetry a pipeline from where it broke.\n\n## Steps\n1. Get the failed run to confirm its id and failure point.\n2. Re-execute the run, scoping to the failed and downstream steps when supported.\n3. Capture the new run id and status.\n\n## Output\nA confirmation with the original run id, the new run id, and the re-execution scope.',
|
||||
},
|
||||
{
|
||||
name: 'manage-schedules',
|
||||
description:
|
||||
'List Dagster schedules and sensors and start or stop them to control automated pipeline execution.',
|
||||
content:
|
||||
'# Manage Dagster Schedules\n\nControl which automated triggers are running.\n\n## Steps\n1. List schedules and sensors with their current running state.\n2. Identify the schedule or sensor to change.\n3. Start or stop it as requested.\n4. Confirm the new state.\n\n## Output\nA confirmation of which schedules/sensors were started or stopped and their resulting state.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -490,4 +490,27 @@ export const DatabricksBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'run-sql-query',
|
||||
description:
|
||||
'Execute a SQL query against a Databricks SQL warehouse and return the results in a clean, summarized form.',
|
||||
content:
|
||||
'# Run a Databricks SQL Query\n\nQuery a table or view and summarize the result.\n\n## Steps\n1. Confirm the SQL warehouse and the query to run.\n2. Execute the SQL statement and wait for it to complete.\n3. Capture the returned rows and column schema.\n4. Summarize key findings (counts, totals, notable values).\n\n## Output\nThe query results plus a short plain-English summary of what they show.',
|
||||
},
|
||||
{
|
||||
name: 'trigger-job-run',
|
||||
description:
|
||||
'Trigger a Databricks job, capture the run id, and confirm it started successfully.',
|
||||
content:
|
||||
'# Trigger a Databricks Job\n\nKick off a job and confirm it launched.\n\n## Steps\n1. List jobs to confirm the target job id and name.\n2. Run the job with any required parameters.\n3. Capture the run id and starting state.\n\n## Output\nA confirmation with the job name, run id, and initial status.',
|
||||
},
|
||||
{
|
||||
name: 'monitor-job-run',
|
||||
description:
|
||||
'Check the status of a Databricks job run, pull its output, and diagnose failures.',
|
||||
content:
|
||||
'# Monitor a Databricks Job Run\n\nTrack a job run to completion and report results.\n\n## Steps\n1. Get the run for the given run id and read its lifecycle and result state.\n2. If still running, report progress; if finished, pull the run output.\n3. On failure, capture the error and the failing task.\n\n## Output\nA run summary with final state, key output, and (on failure) the error and failing task.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -907,4 +907,34 @@ export const DatadogBlockMeta = {
|
||||
alsoIntegrations: ['gmail'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'triage-firing-monitors',
|
||||
description:
|
||||
'List Datadog monitors, surface those in alert or warn state, and summarize what is firing and why.',
|
||||
content:
|
||||
'# Triage Firing Datadog Monitors\n\nGet a clear picture of what is alerting right now.\n\n## Steps\n1. List monitors and filter to those in Alert or Warn states.\n2. For each, get the monitor details: query, threshold, and current value.\n3. Group by service or tag to find common root causes.\n\n## Output\nA prioritized list of firing monitors with the metric, threshold, and likely affected service.',
|
||||
},
|
||||
{
|
||||
name: 'investigate-logs',
|
||||
description:
|
||||
'Query Datadog logs for a service and time window to find errors and summarize patterns.',
|
||||
content:
|
||||
'# Investigate Datadog Logs\n\nSearch logs to diagnose an issue.\n\n## Steps\n1. Confirm the service, environment, and time window.\n2. Query logs filtering for error/critical status and the relevant service tag.\n3. Aggregate by error message or type to find the dominant patterns.\n4. Pull sample log lines for the top patterns.\n\n## Output\nA summary of the top error patterns with counts and sample log lines.',
|
||||
},
|
||||
{
|
||||
name: 'analyze-metric-trend',
|
||||
description:
|
||||
'Query a Datadog timeseries metric over a window and report the trend, anomalies, and current value.',
|
||||
content:
|
||||
'# Analyze a Datadog Metric Trend\n\nUnderstand how a metric is behaving over time.\n\n## Steps\n1. Confirm the metric query and the time window.\n2. Query the timeseries and compute the trend (rising, flat, falling).\n3. Identify spikes, dips, or anomalies and when they occurred.\n\n## Output\nA short analysis with the current value, overall trend, and any notable anomalies with timestamps.',
|
||||
},
|
||||
{
|
||||
name: 'schedule-maintenance-downtime',
|
||||
description:
|
||||
'Create a Datadog downtime to mute monitors during a maintenance window, then confirm the scope and timing.',
|
||||
content:
|
||||
'# Schedule Datadog Maintenance Downtime\n\nSuppress alerts during planned maintenance.\n\n## Steps\n1. Confirm the scope (tags/monitors) and the start and end times.\n2. Create the downtime with that scope and window.\n3. Verify it was created by listing active downtimes.\n\n## Output\nA confirmation of the downtime with its scope, start/end time, and id.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -389,4 +389,27 @@ export const DevinBlockMeta = {
|
||||
alsoIntegrations: ['linear'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'start-engineering-session',
|
||||
description:
|
||||
'Create a Devin session with a clear engineering task prompt and report the session id and link.',
|
||||
content:
|
||||
'# Start a Devin Engineering Session\n\nKick off an autonomous engineering task with Devin.\n\n## Steps\n1. Confirm the repository and the task to perform.\n2. Write a precise prompt: the goal, constraints, and acceptance criteria.\n3. Create the session, optionally tagging it for tracking.\n4. Capture the session id and URL.\n\n## Output\nA confirmation with the session id, link, and the task prompt Devin was given.',
|
||||
},
|
||||
{
|
||||
name: 'check-session-progress',
|
||||
description:
|
||||
'Get a Devin session status and recent messages and summarize what it has accomplished or where it is blocked.',
|
||||
content:
|
||||
'# Check Devin Session Progress\n\nMonitor a running Devin session.\n\n## Steps\n1. Get the session for the given session id and read its status.\n2. List recent session messages to see Devin actions and reasoning.\n3. Determine whether it is making progress, finished, or blocked needing input.\n\n## Output\nA status summary describing progress, current state, and any questions Devin is waiting on.',
|
||||
},
|
||||
{
|
||||
name: 'guide-session',
|
||||
description:
|
||||
'Send a message to an active Devin session to answer a question or redirect its work.',
|
||||
content:
|
||||
'# Guide a Devin Session\n\nUnblock or steer an active session.\n\n## Steps\n1. Confirm the session id and review the latest messages.\n2. Compose a clear reply: answer the open question or give new direction.\n3. Send the message to the session.\n4. Confirm Devin has resumed.\n\n## Output\nA confirmation that the message was sent, with the guidance provided.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -868,4 +868,34 @@ export const DiscordBlockMeta = {
|
||||
alsoIntegrations: ['luma', 'google_calendar'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'post-announcement',
|
||||
description:
|
||||
'Post a formatted announcement message to a Discord channel and optionally pin it.',
|
||||
content:
|
||||
'# Post a Discord Announcement\n\nShare an announcement with a community channel.\n\n## Steps\n1. Confirm the target channel and the announcement content.\n2. Format the message clearly, using mentions or roles only if requested.\n3. Send the message to the channel.\n4. If it is important, pin the message.\n\n## Output\nA confirmation with the channel, message link or id, and whether it was pinned.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-channel-activity',
|
||||
description:
|
||||
'Read recent Discord channel messages and produce a summary of discussions, questions, and decisions.',
|
||||
content:
|
||||
'# Summarize Discord Channel Activity\n\nCatch up on what happened in a channel.\n\n## Steps\n1. Confirm the channel and how many recent messages to review.\n2. Get the channel messages.\n3. Group the conversation into themes: announcements, questions, and decisions.\n4. Flag unanswered questions that need a reply.\n\n## Output\nA concise digest of the discussion with unanswered questions called out.',
|
||||
},
|
||||
{
|
||||
name: 'open-discussion-thread',
|
||||
description:
|
||||
'Create a Discord thread for a topic and post a kickoff message to organize community discussion.',
|
||||
content:
|
||||
'# Open a Discord Discussion Thread\n\nSpin up a focused thread for a topic.\n\n## Steps\n1. Confirm the parent channel and the thread topic.\n2. Create the thread with a clear name.\n3. Post a kickoff message framing the discussion and any prompts.\n\n## Output\nA confirmation with the thread name, link or id, and the kickoff message posted.',
|
||||
},
|
||||
{
|
||||
name: 'collect-reactions-feedback',
|
||||
description:
|
||||
'Post a poll-style message in Discord, add reaction options, and read back the tally as feedback.',
|
||||
content:
|
||||
'# Collect Discord Reaction Feedback\n\nRun a lightweight reaction poll.\n\n## Steps\n1. Confirm the channel, the question, and the reaction options.\n2. Send the poll message.\n3. Add each reaction option to the message.\n4. After the polling window, read the message to tally the reaction counts.\n\n## Output\nThe poll question with the reaction tally and which option leads.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -446,4 +446,33 @@ export const DocuSignBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'send-contract-for-signature',
|
||||
description:
|
||||
'Send a document to one or more signers for e-signature, using a DocuSign template or an uploaded file.',
|
||||
content:
|
||||
'# Send Contract for Signature\n\nSend a document out for e-signature through DocuSign and confirm it was delivered.\n\n## Steps\n1. Determine whether to send from a template (preferred for standard agreements) or from an uploaded document. If a template is named, use List Templates to resolve its ID.\n2. For a template, call Send from Template with the template ID and a template-roles JSON array mapping each role name to a signer name and email. For an ad-hoc document, call Send Envelope with the email subject, signer name, signer email, and the document file.\n3. Add any CC recipients and set the email subject to something the signer will recognize.\n4. Send immediately unless asked to save as a draft.\n\n## Output\nReport the envelope ID and status. List each signer and CC recipient with their email so the requester can confirm the right people were addressed.',
|
||||
},
|
||||
{
|
||||
name: 'track-pending-envelopes',
|
||||
description:
|
||||
'List envelopes awaiting signature, identify ones stalled past a threshold, and surface who still needs to sign.',
|
||||
content:
|
||||
'# Track Pending Envelopes\n\nFind DocuSign envelopes that are sent but not yet completed so stalled signatures can be chased.\n\n## Steps\n1. Call List Envelopes filtered to sent and delivered status over a recent date window.\n2. For each envelope, use List Recipients to see which signers have signed and which are still outstanding.\n3. Compute how long each envelope has been waiting and flag any past the requested threshold (default 48 hours).\n\n## Output\nReturn a table of stalled envelopes: envelope ID, subject, days waiting, and the outstanding signer name and email. Sort by longest waiting first.',
|
||||
},
|
||||
{
|
||||
name: 'archive-completed-documents',
|
||||
description:
|
||||
'Find completed envelopes, download the signed PDFs, and extract key metadata for archiving.',
|
||||
content:
|
||||
'# Archive Completed Documents\n\nCollect signed documents once an envelope is complete and capture their metadata.\n\n## Steps\n1. Call List Envelopes filtered to completed status over the requested date window.\n2. For each completed envelope, call Download Document with "combined" to get the full signed PDF.\n3. Record the envelope ID, subject, completed date, and signer list for each document.\n\n## Output\nReturn each completed envelope with its downloaded file, signers, and completed date. Note any envelope where the download failed so it can be retried.',
|
||||
},
|
||||
{
|
||||
name: 'void-stale-envelope',
|
||||
description: 'Void an envelope that should no longer be signed and record the reason.',
|
||||
content:
|
||||
'# Void Stale Envelope\n\nCancel a DocuSign envelope that is no longer valid — wrong recipient, superseded terms, or expired offer.\n\n## Steps\n1. Confirm the envelope ID. If only a subject or signer is known, use List Envelopes to resolve it, and verify it is not already completed.\n2. Call Get Envelope to confirm the current status is still voidable (created, sent, or delivered).\n3. Call Void Envelope with a clear void reason describing why it is being cancelled.\n\n## Output\nConfirm the envelope ID, its new voided status, and the recorded reason. If the envelope was already completed or voided, report that instead of attempting to void it.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -472,4 +472,33 @@ export const DropboxBlockMeta = {
|
||||
alsoIntegrations: ['docusign'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'upload-file-to-dropbox',
|
||||
description:
|
||||
'Upload a file to a specific Dropbox path and optionally generate a shareable link.',
|
||||
content:
|
||||
'# Upload File to Dropbox\n\nSave a file into Dropbox at a chosen location and optionally share it.\n\n## Steps\n1. Determine the destination path, including the filename and extension (e.g., /reports/q3-summary.pdf).\n2. Call Upload File with the file and destination path. Use overwrite mode only if replacing an existing file; otherwise use add and enable auto-rename to avoid clobbering.\n3. If a shareable link is requested, call Create Shared Link on the uploaded path with the requested visibility (public, team-only, or password-protected).\n\n## Output\nReport the final stored path (after any auto-rename) and, if created, the shared link URL.',
|
||||
},
|
||||
{
|
||||
name: 'find-files-in-dropbox',
|
||||
description:
|
||||
'Search Dropbox for files by query, extension, or folder, and return matching paths.',
|
||||
content:
|
||||
'# Find Files in Dropbox\n\nLocate files in Dropbox matching a search term or filter.\n\n## Steps\n1. Use Search Files with the query term. Scope to a folder path when the location is known, and pass file extensions (e.g., pdf,xlsx) to narrow results.\n2. If browsing a known folder instead of searching, use List Folder with the folder path; enable recursive listing to include subfolders.\n3. For any candidate match, use Get Metadata to confirm size, type, and last-modified time before acting on it.\n\n## Output\nReturn the matching files as a list of path, name, size, and last-modified. If nothing matches, say so and suggest a broader query.',
|
||||
},
|
||||
{
|
||||
name: 'organize-dropbox-folder',
|
||||
description: 'List a folder and move, copy, or delete files to reorganize Dropbox contents.',
|
||||
content:
|
||||
'# Organize Dropbox Folder\n\nReorganize files in Dropbox by moving them into the right folders.\n\n## Steps\n1. Call List Folder on the source path to enumerate the files to process.\n2. Decide each file destination based on the requested rules (by type, date, campaign, or naming pattern). Create target folders with Create Folder if they do not exist.\n3. Use Move File/Folder to relocate each file, or Copy File/Folder when the original must stay in place. Enable auto-rename to avoid conflicts.\n\n## Output\nReturn a summary of every file moved or copied with its old and new path, and flag any operation that failed.',
|
||||
},
|
||||
{
|
||||
name: 'share-dropbox-link',
|
||||
description:
|
||||
'Create a shared link for a Dropbox file or folder with controlled visibility and expiration.',
|
||||
content:
|
||||
'# Share Dropbox Link\n\nGenerate a shareable link for an existing Dropbox item with the right access controls.\n\n## Steps\n1. Confirm the exact path of the file or folder. Use Get Metadata to verify it exists.\n2. Call Create Shared Link with the path and the requested visibility — public for anyone, team-only for internal sharing, or password-protected with a supplied password.\n3. Set an expiration date if the link should not be permanent.\n\n## Output\nReturn the shared link URL, its visibility setting, and the expiration date if one was applied.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -244,4 +244,27 @@ export const DSPyBlockMeta = {
|
||||
tags: ['research', 'llm', 'agentic'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'run-dspy-prediction',
|
||||
description:
|
||||
'Call a self-hosted DSPy Predict program to get a structured output from an input.',
|
||||
content:
|
||||
'# Run DSPy Prediction\n\nSend input to a self-hosted DSPy Predict program and return its structured answer.\n\n## Steps\n1. Confirm the DSPy server base URL and, if required, the API key.\n2. Choose the Predict operation and supply the input text. Set the input field name only if the program signature expects something other than the default.\n3. Pass any extra signature fields as an additional-inputs JSON object.\n\n## Output\nReturn the program answer and any structured fields it produced. If the server returns a non-success status, surface the status and the raw output for debugging.',
|
||||
},
|
||||
{
|
||||
name: 'reason-with-chain-of-thought',
|
||||
description:
|
||||
'Use a DSPy Chain of Thought program to answer a question with explicit reasoning.',
|
||||
content:
|
||||
'# Reason with Chain of Thought\n\nAnswer a question through a self-hosted DSPy Chain of Thought program that exposes its reasoning.\n\n## Steps\n1. Confirm the DSPy server base URL and API key if needed.\n2. Choose the Chain of Thought operation and supply the question. Add any background as context.\n3. Run the program and capture both the answer and the reasoning trace.\n\n## Output\nReturn the final answer plus the reasoning rationale so the requester can audit how the conclusion was reached.',
|
||||
},
|
||||
{
|
||||
name: 'run-dspy-react-agent',
|
||||
description:
|
||||
'Run a DSPy ReAct agent on a task that requires multi-step tool use, and capture its trajectory.',
|
||||
content:
|
||||
'# Run DSPy ReAct Agent\n\nExecute a task with a self-hosted DSPy ReAct agent that interleaves reasoning and actions.\n\n## Steps\n1. Confirm the DSPy server base URL and API key if needed.\n2. Choose the ReAct operation and describe the task clearly. Set a max-iterations cap to bound how many reasoning-action cycles run.\n3. Provide any needed context, then execute the agent.\n\n## Output\nReturn the final answer and the step-by-step trajectory (thoughts, actions, observations). If the agent hit the iteration cap without finishing, note that and summarize the last state.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -562,4 +562,34 @@ export const DubBlockMeta = {
|
||||
tags: ['marketing', 'analysis', 'reporting'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'create-tracked-short-link',
|
||||
description:
|
||||
'Create a Dub short link for a destination URL with UTM parameters and an optional custom slug.',
|
||||
content:
|
||||
'# Create Tracked Short Link\n\nTurn a long destination URL into a branded, trackable Dub short link.\n\n## Steps\n1. Take the destination URL and any campaign metadata (source, medium, campaign name).\n2. Call Create Link with the URL. Set the UTM source, medium, and campaign fields so clicks attribute correctly, and set a custom slug when a memorable link is wanted.\n3. Add a custom domain, title, or tag IDs if the request specifies them.\n\n## Output\nReturn the full short link URL, its slug, the destination, and the QR code URL. Confirm which UTM parameters were applied.',
|
||||
},
|
||||
{
|
||||
name: 'report-link-analytics',
|
||||
description:
|
||||
'Pull Dub click, lead, and sales analytics for a link or campaign over a time window.',
|
||||
content:
|
||||
'# Report Link Analytics\n\nSummarize how a Dub short link or campaign is performing.\n\n## Steps\n1. Choose the Get Analytics operation. Set the event type (clicks, leads, sales, or composite) the request cares about.\n2. Scope to a specific link via link ID or external ID, or to a domain for a whole campaign. Set the interval (e.g., 7d, 30d) or explicit start and end dates.\n3. Set group-by to break results down by country, device, referrer, or top links when a breakdown is asked for; otherwise use count for totals.\n\n## Output\nReport the headline metrics (clicks, leads, sales, revenue) and, when grouped, the top segments. Call out notable winners and decliners versus the prior period when comparison data is available.',
|
||||
},
|
||||
{
|
||||
name: 'batch-create-campaign-links',
|
||||
description:
|
||||
'Upsert a Dub short link for each row in a list of destinations with consistent UTM tagging.',
|
||||
content:
|
||||
'# Batch Create Campaign Links\n\nGenerate consistent tracked links for many destinations at once.\n\n## Steps\n1. For each destination URL in the list, build the UTM parameters and slug from the row data so tagging is uniform across the batch.\n2. Use Upsert Link (keyed on external ID or slug) so re-runs refresh rather than duplicate existing links.\n3. Collect the resulting short link for each row.\n\n## Output\nReturn a table mapping each destination to its short link and external ID. Report how many links were created versus refreshed, and flag any rows that failed.',
|
||||
},
|
||||
{
|
||||
name: 'audit-existing-links',
|
||||
description:
|
||||
'List Dub links and check each destination for broken or stale URLs to flag for cleanup.',
|
||||
content:
|
||||
'# Audit Existing Links\n\nReview existing Dub links to catch broken or outdated destinations.\n\n## Steps\n1. Call List Links, optionally filtered by domain or tag IDs, paginating until all links are retrieved.\n2. For each link, inspect the destination URL and check it for 4xx or 5xx responses or obviously stale targets.\n3. Note links with low or zero clicks over a long period as candidates for archiving.\n\n## Output\nReturn a remediation list: short link, destination, detected issue (broken, redirecting, stale), and a suggested action. Sort broken links first.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -130,4 +130,27 @@ export const DuckDuckGoBlockMeta = {
|
||||
alsoIntegrations: ['hubspot'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'answer-with-duckduckgo',
|
||||
description:
|
||||
'Search DuckDuckGo for a quick instant answer or abstract on a topic and return it with its source.',
|
||||
content:
|
||||
'# Answer with DuckDuckGo\n\nGet a fast, privacy-preserving answer to a factual question using DuckDuckGo Instant Answers.\n\n## Steps\n1. Form a concise query from the question. Enable Remove HTML so returned text is clean.\n2. Run the search and read the instant answer, abstract, and abstract source.\n3. If the result is a disambiguation page rather than a direct answer, refine the query to be more specific and search again.\n\n## Output\nReturn the answer or abstract text along with the source name and URL so the claim is attributable. If no instant answer exists, say so and surface the related topics instead.',
|
||||
},
|
||||
{
|
||||
name: 'gather-related-topics',
|
||||
description:
|
||||
'Use DuckDuckGo to collect related topics and external links around a subject for research.',
|
||||
content:
|
||||
'# Gather Related Topics\n\nBuild a quick research starting point on a subject using DuckDuckGo.\n\n## Steps\n1. Search the subject with Remove HTML enabled.\n2. Collect the heading, abstract, related topics, and any external link results.\n3. Group the related topics into themes and pick the most authoritative links to explore further.\n\n## Output\nReturn the abstract summary plus a list of related topics and external links, each with its URL, organized by theme.',
|
||||
},
|
||||
{
|
||||
name: 'validate-claim-online',
|
||||
description:
|
||||
'Check a stated claim against DuckDuckGo results to confirm or flag it as unsupported.',
|
||||
content:
|
||||
'# Validate Claim Online\n\nVerify whether a claim is supported by public web sources via DuckDuckGo.\n\n## Steps\n1. Turn the claim into a focused search query and run it with Remove HTML enabled.\n2. Compare the instant answer, abstract, and source against the claim.\n3. Decide whether the result supports, contradicts, or is silent on the claim.\n\n## Output\nReturn a verdict — supported, contradicted, or unverified — with the source name and URL. If unverified, recommend a more targeted query or a dedicated source.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -901,4 +901,26 @@ export const DynamoDBBlockMeta = {
|
||||
alsoIntegrations: ['athena'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'lookup-item-by-key',
|
||||
description:
|
||||
'Get a single DynamoDB item by its primary key and return the requested attributes.',
|
||||
content:
|
||||
'# Lookup Item by Key\n\nRetrieve one record from a DynamoDB table by its key.\n\n## Steps\n1. Identify the table and the partition key (and sort key if the table uses one).\n2. Get the item by its key.\n3. Return the requested attributes, or report that no item exists for that key.\n\n## Output\nThe item attributes if found, or a clear "not found" result. Do not fabricate values for missing attributes.',
|
||||
},
|
||||
{
|
||||
name: 'query-table-records',
|
||||
description:
|
||||
'Query a DynamoDB table or index by partition key with optional filters and return the matching items.',
|
||||
content:
|
||||
'# Query Table Records\n\nFetch a set of related items from DynamoDB using a query.\n\n## Steps\n1. Determine the table or secondary index and the partition key value to query.\n2. Add a sort-key condition or filter expression if needed to narrow results.\n3. Run the query and collect the items, paginating if there are more.\n\n## Output\nThe matching items and a count. Note if results were truncated by a limit or pagination boundary.',
|
||||
},
|
||||
{
|
||||
name: 'upsert-item',
|
||||
description: 'Create or update a DynamoDB item, setting attributes from provided values.',
|
||||
content:
|
||||
'# Upsert Item\n\nWrite a record into a DynamoDB table.\n\n## Steps\n1. Build the item with its primary key and the attributes to set.\n2. Put the item, or use an update expression to modify only specific attributes.\n3. Confirm the write succeeded.\n\n## Output\nConfirm the item key written and which attributes were set or updated.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -607,4 +607,31 @@ export const ElasticsearchBlockMeta = {
|
||||
alsoIntegrations: ['langsmith'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'search-elasticsearch-index',
|
||||
description: 'Run a query against an Elasticsearch index and return the matching documents.',
|
||||
content:
|
||||
'# Search Elasticsearch Index\n\nQuery an index and return the relevant documents.\n\n## Steps\n1. Confirm the connection details (host or cloud ID and auth) and the target index name.\n2. Choose the Search operation and build the query DSL — match for full-text, term for exact values, range for numeric or date bounds, and bool to combine clauses.\n3. Set size and offset for paging, add a sort spec when ordering matters, and use source includes/excludes to trim returned fields.\n\n## Output\nReturn the matching hits with their _id, _score, and relevant _source fields, plus the total count and query time. If nothing matched, report zero hits and suggest loosening the query.',
|
||||
},
|
||||
{
|
||||
name: 'index-document',
|
||||
description: 'Add or update a document in an Elasticsearch index.',
|
||||
content:
|
||||
'# Index Document\n\nWrite a document into an Elasticsearch index so it becomes searchable.\n\n## Steps\n1. Confirm the connection details and target index.\n2. Build the document as a JSON object with appropriate field types. Choose the Index Document operation; supply a document ID to upsert a known record, or omit it to let Elasticsearch auto-generate one.\n3. To change only specific fields of an existing document, use Update Document with a partial document and the document ID instead.\n4. Set the refresh policy to immediate or wait-for when the write must be searchable right away.\n\n## Output\nReturn the resulting _id, _version, and the operation result (created or updated).',
|
||||
},
|
||||
{
|
||||
name: 'bulk-load-documents',
|
||||
description:
|
||||
'Index, update, or delete many Elasticsearch documents in a single bulk request.',
|
||||
content:
|
||||
'# Bulk Load Documents\n\nApply many document operations to Elasticsearch efficiently in one call.\n\n## Steps\n1. Confirm the connection details and target index.\n2. Assemble the operations as NDJSON: an action line (index, create, update, or delete) followed by the document line where required.\n3. Run the Bulk Operations call and set a refresh policy if the data must be immediately searchable.\n\n## Output\nReport whether any errors occurred and summarize the per-item results — how many succeeded versus failed and the reason for any failures.',
|
||||
},
|
||||
{
|
||||
name: 'check-cluster-health',
|
||||
description: 'Report Elasticsearch cluster health and key index statistics.',
|
||||
content:
|
||||
'# Check Cluster Health\n\nAssess the health of an Elasticsearch deployment.\n\n## Steps\n1. Confirm the connection details.\n2. Call Cluster Health to get the overall status (green, yellow, red) and node count. Optionally wait for a target status.\n3. Use List Indices and Get Index Info to spot oversized, unassigned, or unhealthy indices, and Cluster Stats for storage and shard totals.\n\n## Output\nReport the cluster status, number of nodes, and any indices that look problematic. If status is yellow or red, explain the likely cause (e.g., unassigned replicas) and what to check next.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -175,4 +175,26 @@ export const ElevenLabsBlockMeta = {
|
||||
tags: ['support', 'communication', 'automation'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'narrate-text-to-speech',
|
||||
description:
|
||||
'Convert a block of text into natural-sounding speech audio with a chosen ElevenLabs voice.',
|
||||
content:
|
||||
'# Narrate Text to Speech\n\nGenerate spoken audio from text using ElevenLabs.\n\n## Steps\n1. Take the text to narrate and confirm the target voice ID (ask for one if not provided).\n2. Pick a model — use a multilingual model for non-English or mixed-language text, or a turbo/flash model when low latency matters.\n3. For consistent delivery, set stability higher; for more expressive variation, set it lower. Raise similarity boost to stay closer to the reference voice.\n\n## Output\nReturn the generated audio file and its URL. Confirm the voice and model used so the requester can adjust if the delivery is not right.',
|
||||
},
|
||||
{
|
||||
name: 'narrate-article-as-audio',
|
||||
description: 'Turn a long article or blog post into a podcast-style audio narration.',
|
||||
content:
|
||||
'# Narrate Article as Audio\n\nProduce a listenable audio version of written content.\n\n## Steps\n1. Clean the source text — strip markdown, navigation, and boilerplate so only the readable prose remains. Expand abbreviations the voice should speak in full.\n2. Choose a voice ID suited to the content and a high-quality multilingual model for natural delivery.\n3. Convert the cleaned text to speech, keeping stability moderate so the narration sounds engaging but consistent.\n\n## Output\nReturn the audio file and a player-ready URL, along with the voice used. If the text is very long, note any truncation and suggest splitting it into parts.',
|
||||
},
|
||||
{
|
||||
name: 'generate-voice-prompt',
|
||||
description:
|
||||
'Generate a short branded voice clip such as an IVR prompt, greeting, or notification.',
|
||||
content:
|
||||
'# Generate Voice Prompt\n\nCreate a short, polished voice clip for things like phone menus, greetings, or alerts.\n\n## Steps\n1. Take the exact script for the prompt. Keep it concise and confirm pronunciation of any names or numbers.\n2. Select a consistent brand voice ID so every prompt sounds the same.\n3. Set stability high for a steady, professional delivery and convert the script to speech.\n\n## Output\nReturn the audio file and its URL. When generating a set of prompts, list each clip with its script so they can be wired into the phone tree or app.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -697,4 +697,34 @@ export const EmailBisonBlockMeta = {
|
||||
tags: ['sales', 'automation', 'analysis'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'add-leads-to-campaign',
|
||||
description:
|
||||
'Create leads in Email Bison and attach them to an outbound campaign with personalization variables.',
|
||||
content:
|
||||
'# Add Leads to Campaign\n\nLoad prospects into Email Bison and enroll them in a campaign.\n\n## Steps\n1. Confirm the instance URL and target campaign. If only a campaign name is known, use List Campaigns to resolve its ID.\n2. For each prospect, call Create Lead with first name, last name, email, and any title or company. Pass personalization fields as a custom-variables JSON array (e.g., linkedin_url, first_line).\n3. Collect the new lead IDs and call Attach Leads to Campaign with the campaign ID and those IDs.\n\n## Output\nReport how many leads were created and attached, list any duplicates or invalid emails that were skipped, and confirm the campaign they were added to.',
|
||||
},
|
||||
{
|
||||
name: 'triage-campaign-replies',
|
||||
description:
|
||||
'Pull recent Email Bison replies, classify each by intent, and tag the lead accordingly.',
|
||||
content:
|
||||
'# Triage Campaign Replies\n\nProcess inbound replies to outbound campaigns and route them.\n\n## Steps\n1. Call List Replies, optionally scoped to a campaign, sender email, or the inbox folder, and filter to unread when only new replies matter.\n2. Classify each reply as interested, not interested, objection, out-of-office, or auto-reply based on its content.\n3. Resolve or create the matching tag with List Tags / Create Tag, then call Attach Tags to Leads to label the lead by intent.\n\n## Output\nReturn each reply with its lead, classification, and the tag applied. Highlight interested replies so a rep can follow up first.',
|
||||
},
|
||||
{
|
||||
name: 'manage-campaign-status',
|
||||
description:
|
||||
'Pause, resume, or archive an Email Bison campaign and adjust its sending settings.',
|
||||
content:
|
||||
'# Manage Campaign Status\n\nControl whether an Email Bison campaign is actively sending and tune its limits.\n\n## Steps\n1. Confirm the campaign ID (resolve via List Campaigns if only a name is given).\n2. Call Update Campaign Status with pause, resume, or archive as requested.\n3. To adjust throughput or behavior, call Update Campaign to change max emails per day, max new leads per day, sequence prioritization, or tracking settings.\n\n## Output\nConfirm the campaign new status and any sending settings that changed. Note the prior values so the change can be reverted if needed.',
|
||||
},
|
||||
{
|
||||
name: 'report-campaign-performance',
|
||||
description:
|
||||
'Summarize Email Bison campaign performance — sends, opens, replies, and positive reply rate.',
|
||||
content:
|
||||
'# Report Campaign Performance\n\nProduce a performance snapshot across Email Bison campaigns.\n\n## Steps\n1. Call List Campaigns to get the active campaigns and their stats.\n2. For reply-level detail, call List Replies per campaign and tally interested versus total to compute positive reply rate.\n3. Rank campaigns by reply rate and identify top and bottom performers.\n\n## Output\nReturn a digest: per-campaign sends, opens, replies, and positive reply rate, with the best and worst performers called out and a one-line takeaway for each.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -697,4 +697,34 @@ export const EnrichBlockMeta = {
|
||||
alsoIntegrations: ['hubspot'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'enrich-contact-from-email',
|
||||
description:
|
||||
'Enrich a person from their email address — name, role, company, social profiles, and more.',
|
||||
content:
|
||||
'# Enrich Contact from Email\n\nTurn an email address into a full contact profile using Enrich.so.\n\n## Steps\n1. Take the email address. Choose Email to Profile for a full enrichment, or Email to Person (Lite) for a fast, cheaper lookup.\n2. Enable fresh-data fetch when up-to-date info matters more than speed.\n3. Read back name, current title, company, location, and any LinkedIn or social URLs.\n\n## Output\nReturn the enriched fields in a clean object. Note which fields could not be resolved so downstream steps know what is missing, and report remaining credits if relevant.',
|
||||
},
|
||||
{
|
||||
name: 'find-and-verify-work-email',
|
||||
description:
|
||||
'Find a prospect work email from a name and company or LinkedIn URL, then verify deliverability.',
|
||||
content:
|
||||
'# Find and Verify Work Email\n\nLocate a reliable work email for a prospect and confirm it is safe to send to.\n\n## Steps\n1. If you have a name and company domain, use Find Email. If you have a LinkedIn profile URL, use LinkedIn to Work Email instead.\n2. Run Verify Email on the returned address to check deliverability, and Disposable Email Check to rule out throwaway domains.\n3. If the work email cannot be found, optionally fall back to LinkedIn to Personal Email when appropriate.\n\n## Output\nReturn the discovered email, its verification status (valid, risky, invalid), and whether it is disposable. Recommend whether the address is safe to add to outreach.',
|
||||
},
|
||||
{
|
||||
name: 'enrich-company-firmographics',
|
||||
description:
|
||||
'Look up firmographic data for a company — size, industry, funding, revenue, and traffic.',
|
||||
content:
|
||||
'# Enrich Company Firmographics\n\nBuild a firmographic profile for a target account using Enrich.so.\n\n## Steps\n1. Identify the company by name or domain. Use Company Lookup for core firmographics.\n2. Add Company Funding & Traffic and Company Revenue for deeper financial signals when account scoring needs them.\n3. If you only have a visitor IP, use IP to Company first to resolve the organization.\n\n## Output\nReturn a consolidated account brief: company name, domain, industry, employee count, funding, revenue, and traffic. Flag any data points that could not be resolved.',
|
||||
},
|
||||
{
|
||||
name: 'search-prospects',
|
||||
description:
|
||||
'Search Enrich.so for people or companies matching an ideal-customer-profile filter.',
|
||||
content:
|
||||
'# Search Prospects\n\nFind people or companies that match a target profile.\n\n## Steps\n1. For people, use Search People with filters like job title, industry, location, and skills. For companies, use Search Company with industry, location, and employee-size bounds.\n2. To pull contacts at known accounts, use Search Company Employees with the company IDs and target job titles.\n3. Page through results using the page and page-size parameters until you have enough matches.\n\n## Output\nReturn the matching people or companies with their key identifying fields and any profile URLs, plus a count of total matches. Suggest tighter filters if too many or too few results come back.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -193,4 +193,27 @@ export const EnrichmentBlockMeta = {
|
||||
tags: ['sales', 'research', 'enrichment'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'find-work-email',
|
||||
description:
|
||||
'Find a verified work email for a contact given their full name and company domain using the Work Email enrichment.',
|
||||
content:
|
||||
'# Find a Work Email\n\nResolve a verified work email for a prospect.\n\n## Steps\n1. Confirm you have the contact full name and the company domain (resolve the domain first if only a company name is given).\n2. Run the Work Email enrichment with name and domain.\n3. Capture the email and its verification confidence.\n\n## Output\nThe verified work email with its confidence level, or a clear note that no match was found.',
|
||||
},
|
||||
{
|
||||
name: 'enrich-company-profile',
|
||||
description:
|
||||
'Pull firmographics (industry, headcount, founded year, description) for a company domain using the Company Info enrichment.',
|
||||
content:
|
||||
'# Enrich a Company Profile\n\nBuild a firmographic profile for an account.\n\n## Steps\n1. Confirm the company domain (resolve it with the Company Domain enrichment if you only have a name).\n2. Run the Company Info enrichment on the domain.\n3. Capture industry, employee count, founded year, and description.\n\n## Output\nA structured company profile with the key firmographics, ready to write into an accounts record.',
|
||||
},
|
||||
{
|
||||
name: 'build-full-contact',
|
||||
description:
|
||||
'Take a prospect name and company, resolve the domain, then find the work email and phone to assemble a complete contact.',
|
||||
content:
|
||||
'# Build a Full Contact\n\nGo from a name and company to a complete, enriched contact.\n\n## Steps\n1. Run the Company Domain enrichment to resolve the company website domain.\n2. Run the Work Email enrichment using the name and resolved domain.\n3. Run the Phone Number enrichment for a direct phone.\n4. Assemble the results into one contact record.\n\n## Output\nA complete contact with name, company, domain, verified email, and phone, plus confidence for each field.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -378,4 +378,31 @@ export const EvernoteBlockMeta = {
|
||||
tags: ['individual', 'research'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'create-evernote-note',
|
||||
description: 'Create a new Evernote note with a title, content, tags, and target notebook.',
|
||||
content:
|
||||
'# Create Evernote Note\n\nSave new content as a note in Evernote.\n\n## Steps\n1. Confirm the note title and content. Plain text is fine; the content is stored as ENML.\n2. Choose the Create Note operation. To file it in a specific notebook, resolve the notebook GUID with List Notebooks and pass it.\n3. Add comma-separated tag names so the note is findable later.\n\n## Output\nReturn the new note GUID, its title, and the notebook and tags it was saved under.',
|
||||
},
|
||||
{
|
||||
name: 'search-evernote-notes',
|
||||
description:
|
||||
'Search Evernote for notes matching a query and return their titles and metadata.',
|
||||
content:
|
||||
'# Search Evernote Notes\n\nFind notes across Evernote using its search grammar.\n\n## Steps\n1. Build a query using Evernote search syntax — e.g., tag:work, intitle:meeting, notebook scoping, or plain keywords.\n2. Run Search Notes. Scope to a notebook GUID when the location is known, and set max results and offset to page through matches.\n3. For any note you need the body of, call Get Note with its GUID and include content.\n\n## Output\nReturn the matching notes with title, GUID, and notebook, plus the total match count. If a note body is needed, include its retrieved content.',
|
||||
},
|
||||
{
|
||||
name: 'extract-note-action-items',
|
||||
description: 'Read recent Evernote notes and extract action items, owners, and due dates.',
|
||||
content:
|
||||
'# Extract Note Action Items\n\nPull tasks out of meeting notes or research notes in Evernote.\n\n## Steps\n1. Use Search Notes to find the relevant recent notes (e.g., by tag or notebook).\n2. For each match, call Get Note with content to read the full body.\n3. Identify action items, the responsible owner, and any due dates mentioned in the text.\n\n## Output\nReturn a structured list of action items, each with its owner, due date if stated, and a link back to the source note GUID. Flag items with no clear owner.',
|
||||
},
|
||||
{
|
||||
name: 'organize-notes-with-tags',
|
||||
description: 'Create tags and apply them to Evernote notes to keep them organized.',
|
||||
content:
|
||||
'# Organize Notes with Tags\n\nKeep Evernote notes structured by tagging them consistently.\n\n## Steps\n1. Call List Tags to see existing tags and avoid duplicates. Create any missing tag with Create Tag (optionally nested under a parent tag).\n2. For each note to organize, read it with Get Note if needed, decide the right tags from its content, and apply them via Update Note with the tag names.\n3. Keep tag names consistent in casing and wording across notes.\n\n## Output\nReturn each note GUID with the tags applied and note any new tags that were created.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -514,4 +514,31 @@ export const ExaBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'search-the-web-with-exa',
|
||||
description:
|
||||
'Run an Exa neural or keyword search to find high-quality web sources on a topic.',
|
||||
content:
|
||||
'# Search the Web with Exa\n\nFind authoritative web pages on a topic using Exa AI search.\n\n## Steps\n1. Use the Search operation with a clear query. Pick the search type — neural for meaning-based discovery, keyword for exact terms, or auto to let Exa decide.\n2. Narrow results with include/exclude domains, a category filter (research paper, news article, company, GitHub), and published-date bounds for recency.\n3. Enable include-text or include-summary so each result comes back with usable content rather than just a link.\n\n## Output\nReturn the top results with title, URL, published date, and the text or summary. Note which filters were applied so the search can be tightened or broadened.',
|
||||
},
|
||||
{
|
||||
name: 'answer-question-with-citations',
|
||||
description: 'Use Exa Answer to get a direct, sourced answer to a factual question.',
|
||||
content:
|
||||
'# Answer Question with Citations\n\nGet a grounded answer to a question with supporting sources via Exa.\n\n## Steps\n1. Use the Answer operation and pass the question in natural language.\n2. Enable include-text when you want the supporting passages, not just the citation URLs.\n3. Review the citations to confirm the answer is well-supported before relying on it.\n\n## Output\nReturn the answer text plus its citations (titles and URLs). If the citations are weak or conflicting, say so and recommend a follow-up search.',
|
||||
},
|
||||
{
|
||||
name: 'extract-page-contents',
|
||||
description: 'Use Exa Get Contents to pull clean text and summaries from a set of URLs.',
|
||||
content:
|
||||
'# Extract Page Contents\n\nRetrieve readable content from specific web pages using Exa.\n\n## Steps\n1. Use the Get Contents operation with the target URLs (comma-separated).\n2. Enable include-text for full content, and supply a summary query to get a focused summary tailored to what you need.\n3. To pull deeper context from a site, set a subpage count and target keywords (e.g., docs, pricing, about).\n\n## Output\nReturn each URL with its extracted text or summary and any highlights. Flag any URL that could not be crawled.',
|
||||
},
|
||||
{
|
||||
name: 'find-similar-pages',
|
||||
description: 'Use Exa Find Similar Links to discover pages related to a known URL.',
|
||||
content:
|
||||
'# Find Similar Pages\n\nDiscover sources similar to a reference page using Exa.\n\n## Steps\n1. Use the Find Similar Links operation with the source URL.\n2. Set the number of results and enable exclude-source-domain so you get genuinely new sources, not more pages from the same site.\n3. Apply a category filter or include/exclude domains to keep the discovery on-target, and enable include-text or include-summary for context.\n\n## Output\nReturn the similar pages with title, URL, and a snippet or summary, ordered by relevance. Note the filters used.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -280,4 +280,27 @@ export const ExtendBlockMeta = {
|
||||
tags: ['legal', 'document-processing', 'automation'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'extract-invoice-fields',
|
||||
description:
|
||||
'Parse an uploaded invoice with Extend and return structured vendor, line item, and total fields.',
|
||||
content:
|
||||
'# Extract Invoice Fields\n\nUse Extend to turn an invoice PDF or image into structured, validated data.\n\n## Steps\n1. Take the uploaded invoice document (file upload or URL).\n2. Run the Extend parser to produce structured chunks and blocks.\n3. Pull the key fields: vendor name, invoice number, invoice date, due date, line items (description, quantity, unit price), subtotal, tax, and total.\n4. Validate that totals add up and that required fields are present; flag any that are missing or inconsistent.\n\n## Output\nReturn a clean JSON object with the extracted fields plus a list of any validation warnings. Note the page count and credits used so cost can be tracked.',
|
||||
},
|
||||
{
|
||||
name: 'parse-document-to-markdown',
|
||||
description:
|
||||
'Convert a scanned or complex document into clean, LLM-ready markdown using Extend.',
|
||||
content:
|
||||
'# Parse Document to Markdown\n\nUse Extend to convert any supported document (PDF, image, or Office file) into clean markdown an agent can reason over.\n\n## Steps\n1. Take the source document and choose a chunking strategy (page, section, or document) based on how the content will be consumed.\n2. Run the Extend parser with markdown output.\n3. Stitch the returned chunks into a single ordered markdown document, preserving headings, tables, and lists.\n\n## Output\nReturn the full markdown text plus the page count. If the document was chunked, also return the per-chunk markdown so downstream steps can process sections independently.',
|
||||
},
|
||||
{
|
||||
name: 'classify-and-route-document',
|
||||
description:
|
||||
'Parse an uploaded document with Extend, identify its type, and route it to the right downstream handler.',
|
||||
content:
|
||||
'# Classify and Route Document\n\nUse Extend to read an incoming document and decide where it should go.\n\n## Steps\n1. Run the Extend parser on the uploaded document to get its text content.\n2. Inspect the parsed content to classify the document type (e.g. invoice, contract, claim form, purchase order, KYC document).\n3. Pull the few identifying fields needed for routing (such as document type, reference number, and amount).\n4. Decide the destination queue, table, or channel based on the classification and any thresholds.\n\n## Output\nReturn the detected document type, the routing decision, and the extracted routing fields. Note any document that could not be confidently classified for manual review.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -283,4 +283,27 @@ export const FathomBlockMeta = {
|
||||
alsoIntegrations: ['gmail'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'summarize-recent-meetings',
|
||||
description:
|
||||
'List recent Fathom meetings and produce a concise digest of decisions, owners, and action items.',
|
||||
content:
|
||||
'# Summarize Recent Meetings\n\nUse Fathom to pull recent meetings and turn them into a readable digest.\n\n## Steps\n1. List Fathom meetings, filtering by a date range (createdAfter / createdBefore) and optionally by team or recorder.\n2. Request summaries and action items in the response so each meeting comes back with its recap.\n3. Across the meetings, group the key decisions, commitments, and open action items by topic or owner.\n\n## Output\nReturn a digest with one short section per meeting (title, date, attendees, key points) followed by a consolidated action-item list with owners. Use the pagination cursor to cover the full range if there are many meetings.',
|
||||
},
|
||||
{
|
||||
name: 'extract-meeting-action-items',
|
||||
description:
|
||||
'Pull a specific Fathom meeting summary and extract a clean list of action items with owners.',
|
||||
content:
|
||||
'# Extract Meeting Action Items\n\nUse Fathom to turn a single meeting into a tracked task list.\n\n## Steps\n1. Get the meeting summary for the given recording ID.\n2. Identify every commitment or next step mentioned, with the responsible owner and any stated due date.\n3. If owners are unclear, fall back to the transcript to find who made each commitment.\n\n## Output\nReturn a structured list of action items, each with the task description, owner, and due date (or null). Include a one-line meeting recap at the top for context.',
|
||||
},
|
||||
{
|
||||
name: 'log-sales-call-to-crm',
|
||||
description:
|
||||
'Pull a Fathom call summary and CRM matches, then format a CRM-ready note with next steps.',
|
||||
content:
|
||||
'# Log Sales Call to CRM\n\nUse Fathom to capture a sales call and prepare it for the CRM.\n\n## Steps\n1. Get the summary for the meeting recording ID, including CRM matches so the linked contact or deal is known.\n2. Extract the customer pain points, objections, commitments, and agreed next steps.\n3. Format a concise call note suitable for logging against the matched CRM record.\n\n## Output\nReturn the matched CRM contact or deal identifier, a formatted call note, and a list of follow-up next steps with owners and dates so they can be written into the CRM.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -501,4 +501,34 @@ export const FindymailBlockMeta = {
|
||||
tags: ['sales', 'research', 'enrichment'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'find-verified-email',
|
||||
description:
|
||||
'Find a prospect verified work email from their name and company, or from a LinkedIn URL.',
|
||||
content:
|
||||
'# Find Verified Email\n\nUse Findymail to discover a deliverable work email for a prospect.\n\n## Steps\n1. If you have a name plus company domain, use Find Email From Name. If you have a LinkedIn profile URL, use Find Email From LinkedIn.\n2. Findymail verifies the email at discovery time, so the returned address is already checked for deliverability.\n3. Capture the contact name, email, and domain from the response.\n\n## Output\nReturn the verified email, the matched contact name, and the source company domain. If no email was found, say so clearly rather than guessing an address.',
|
||||
},
|
||||
{
|
||||
name: 'verify-email-list',
|
||||
description:
|
||||
'Run a list of email addresses through Findymail verification and split into deliverable and undeliverable.',
|
||||
content:
|
||||
'# Verify Email List\n\nUse Findymail to clean an email list before an outbound send.\n\n## Steps\n1. For each email address, run Verify Email.\n2. Read the verified flag and the detected provider for each result.\n3. Partition the list into deliverable addresses and undeliverable ones.\n\n## Output\nReturn two lists: deliverable emails (with provider) and undeliverable emails. Include a short summary count so the caller knows how many were removed.',
|
||||
},
|
||||
{
|
||||
name: 'map-company-team',
|
||||
description:
|
||||
'Given a company domain, find employees by job title and enrich the company profile into a team map.',
|
||||
content:
|
||||
'# Map Company Team\n\nUse Findymail to build an org map for a target account.\n\n## Steps\n1. Use Get Company Info on the domain to pull industry, size, and description.\n2. Use Find Employees with the company website and a list of target job titles to pull matching people.\n3. Optionally find each contact verified email or phone for the highest-priority roles.\n\n## Output\nReturn the company profile plus a list of employees (name, job title, LinkedIn URL, and email where available), grouped by function so the account team can see the buying committee.',
|
||||
},
|
||||
{
|
||||
name: 'enrich-from-email',
|
||||
description:
|
||||
'Reverse-lookup an email address with Findymail to recover the full LinkedIn profile and current company.',
|
||||
content:
|
||||
'# Enrich From Email\n\nUse Findymail to turn a bare email address into a full contact record.\n\n## Steps\n1. Run Reverse Email Lookup on the email, requesting the full profile.\n2. Pull the full name, headline, job title, location, current company, and profile details.\n3. Optionally call Get Company Info on the recovered company domain for firmographics.\n\n## Output\nReturn a structured contact record: name, title, company, location, LinkedIn URL, and the original email. Note any fields the lookup could not resolve.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -729,4 +729,34 @@ export const FirecrawlBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'scrape-page-to-markdown',
|
||||
description:
|
||||
'Scrape a single URL with Firecrawl and return clean main-content markdown for an agent to read.',
|
||||
content:
|
||||
'# Scrape Page to Markdown\n\nUse Firecrawl to fetch a web page as clean, LLM-ready markdown.\n\n## Steps\n1. Use the Scrape operation on the target URL.\n2. Enable Only Main Content to strip navigation, ads, and footers; set a Wait For delay if the page renders content with JavaScript.\n3. Return the markdown output and capture page metadata (title, description).\n\n## Output\nReturn the page markdown plus key metadata. If the page failed to load or returned empty content, report that instead of fabricating text.',
|
||||
},
|
||||
{
|
||||
name: 'extract-structured-data',
|
||||
description:
|
||||
'Pull structured fields from one or more URLs using Firecrawl Extract with a prompt or schema.',
|
||||
content:
|
||||
'# Extract Structured Data\n\nUse Firecrawl to extract specific fields from web pages.\n\n## Steps\n1. Use the Extract operation with the list of target URLs.\n2. Provide a clear extraction prompt describing exactly what to pull (for example product name, price, and description).\n3. Run the extraction and read the structured data from the response.\n\n## Output\nReturn the extracted records as structured JSON. List the source URLs and flag any URL that yielded no data.',
|
||||
},
|
||||
{
|
||||
name: 'crawl-site',
|
||||
description:
|
||||
'Crawl an entire site or section with Firecrawl and return the page content for indexing or analysis.',
|
||||
content:
|
||||
'# Crawl Site\n\nUse Firecrawl to traverse a site and collect its pages.\n\n## Steps\n1. Use the Crawl operation on the root URL, setting a sensible page Limit to control cost.\n2. Enable Only Main Content so each page comes back as clean markdown.\n3. Collect the crawled pages and their URLs from the response.\n\n## Output\nReturn the list of crawled pages with their URL and markdown content, plus the total page count. This output is ready to chunk and embed into a knowledge base.',
|
||||
},
|
||||
{
|
||||
name: 'research-with-search',
|
||||
description:
|
||||
'Run a web search with Firecrawl, then scrape the top results into a cited research brief.',
|
||||
content:
|
||||
'# Research With Search\n\nUse Firecrawl to gather and synthesize web sources on a topic.\n\n## Steps\n1. Use the Search operation with the research query and a result Limit.\n2. For the most relevant results, use Scrape to pull the full page markdown.\n3. Synthesize the findings into a brief, attributing each claim to its source URL.\n\n## Output\nReturn a structured research brief with key findings and a Sources list of the URLs used. Keep claims grounded in the scraped content.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -732,6 +732,29 @@ export const FirefliesBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'summarize-meeting-transcript',
|
||||
description:
|
||||
'Fetch a Fireflies transcript and produce a structured recap with decisions, action items, and owners.',
|
||||
content:
|
||||
'# Summarize Meeting Transcript\n\nUse Fireflies to turn a recorded meeting into a clean recap.\n\n## Steps\n1. Get the transcript for the given transcript ID (or pick the latest from List Transcripts).\n2. Read the sentences and any provided summary to identify the main topics discussed.\n3. Extract key decisions, action items with owners, and notable questions or risks.\n\n## Output\nReturn a structured recap: a short overview, a bulleted list of decisions, and an action-item table (task, owner, due date). Keep it grounded in the transcript content.',
|
||||
},
|
||||
{
|
||||
name: 'extract-action-items',
|
||||
description:
|
||||
'Pull a Fireflies transcript and extract a clean list of action items with owners and due dates.',
|
||||
content:
|
||||
'# Extract Action Items\n\nUse Fireflies to capture follow-ups from a meeting.\n\n## Steps\n1. Get the transcript for the meeting by its transcript ID.\n2. Scan the sentences for commitments, assignments, and next steps.\n3. Attribute each item to the speaker who owns it and capture any stated deadline.\n\n## Output\nReturn a list of action items, each with the task, owner, and due date (or null). Add a one-line meeting summary at the top for context.',
|
||||
},
|
||||
{
|
||||
name: 'create-meeting-soundbite',
|
||||
description:
|
||||
'Create a Fireflies soundbite (bite) clipping a key moment from a transcript for sharing.',
|
||||
content:
|
||||
'# Create Meeting Soundbite\n\nUse Fireflies to clip and share a highlight from a recorded meeting.\n\n## Steps\n1. Get the transcript and find the start and end timestamps of the moment to clip.\n2. Use Create Bite with the transcript ID and the chosen time range.\n3. Confirm the bite was created and capture its identifier or link.\n\n## Output\nReturn the soundbite identifier or shareable link plus a short caption describing the clipped moment.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
export const FirefliesV2BlockMeta = {
|
||||
|
||||
@@ -413,4 +413,32 @@ export const GammaBlockMeta = {
|
||||
alsoIntegrations: ['hubspot'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'generate-presentation',
|
||||
description: 'Generate a polished presentation deck from a topic or outline using Gamma.',
|
||||
content:
|
||||
'# Generate Presentation\n\nUse Gamma to turn a topic or outline into a finished presentation.\n\n## Steps\n1. Gather the source content: a topic, a brief, or a structured outline of the points to cover.\n2. Call Gamma to generate a presentation, choosing the number of cards and a theme that fits the audience.\n3. Request an export format (such as PDF or PPTX) if a downloadable file is needed.\n\n## Output\nReturn the link to the generated Gamma and, if requested, the export file URL. Summarize the deck structure (titles per card) so the requester can review before sharing.',
|
||||
},
|
||||
{
|
||||
name: 'generate-document',
|
||||
description: 'Generate a structured document or webpage from input text using Gamma.',
|
||||
content:
|
||||
'# Generate Document\n\nUse Gamma to produce a formatted document or webpage from raw input.\n\n## Steps\n1. Provide the input text and choose the output format (document or webpage).\n2. Call Gamma to generate the content, setting a theme and the desired length or number of cards.\n3. Capture the resulting Gamma URL and any export URL.\n\n## Output\nReturn the generated Gamma link plus a short outline of the sections it produced. Include the export file URL if one was requested.',
|
||||
},
|
||||
{
|
||||
name: 'personalize-deck-from-template',
|
||||
description:
|
||||
'Adapt an existing Gamma template into a prospect or client-specific deck with Generate from Template.',
|
||||
content:
|
||||
'# Personalize Deck From Template\n\nUse Gamma to scale on-brand, personalized decks from a proven template.\n\n## Steps\n1. Identify the template gamma ID to adapt (a master pitch or proposal deck) and collect the recipient details and the angle to tailor for.\n2. Use Generate from Template with that template gamma ID and a prompt that retargets the audience, swaps in the recipient name and use case, and adjusts emphasis (for example highlight compliance for a healthcare buyer). The template structure is preserved by default.\n3. Request an export (PDF or PPTX) if a downloadable file is needed.\n\n## Output\nReturn the generated Gamma link and any export URL. Note the recipient it was generated for so it can be attached to the right CRM record or email.',
|
||||
},
|
||||
{
|
||||
name: 'check-generation-status',
|
||||
description:
|
||||
'Poll a Gamma generation job by its generation ID and return the final deck link once ready.',
|
||||
content:
|
||||
'# Check Generation Status\n\nGamma generation is asynchronous, so use this to wait for a deck to finish.\n\n## Steps\n1. Take the generation ID returned when the deck was requested.\n2. Use Check Status to read the current status of the job.\n3. Repeat until the status is completed (or failed), respecting a sensible polling interval.\n\n## Output\nReturn the final status and, on success, the Gamma URL and any export URL. On failure, return the error details so the caller can retry or adjust the request.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -2157,6 +2157,36 @@ export const GitHubBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'review-pull-request',
|
||||
description:
|
||||
'Fetch a GitHub PR, its changed files, and diff, then post a structured review comment.',
|
||||
content:
|
||||
'# Review Pull Request\n\nUse GitHub to read a pull request and leave a useful review.\n\n## Steps\n1. Get PR details for the given owner, repo, and PR number to read the title, description, and status.\n2. Get the PR files to see the changed paths and diffs.\n3. Assess the changes for correctness, missing tests, and risky edits.\n4. Post a PR comment summarizing the review with specific, actionable feedback.\n\n## Output\nConfirm the comment was posted and return a short summary of the findings: what looks good, what needs changes, and any blocking concerns.',
|
||||
},
|
||||
{
|
||||
name: 'triage-new-issue',
|
||||
description:
|
||||
'Read a GitHub issue, classify it, apply labels, and assign it to the right owner.',
|
||||
content:
|
||||
'# Triage New Issue\n\nUse GitHub to triage an incoming issue.\n\n## Steps\n1. Get the issue by owner, repo, and issue number to read its title and body.\n2. Classify it (bug, feature, question, docs) and judge its severity.\n3. Add the appropriate labels with Add issue labels.\n4. Assign the issue to the relevant owner with Add issue assignees.\n\n## Output\nReturn the applied labels, the assignee, and a one-line triage summary. If the issue lacks reproduction details, note what information is missing.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-repo-activity',
|
||||
description:
|
||||
'Pull recent GitHub PRs, commits, and issues for a repo and produce a concise activity digest.',
|
||||
content:
|
||||
'# Summarize Repo Activity\n\nUse GitHub to build a status digest for a repository.\n\n## Steps\n1. List open pull requests and recent issues for the owner and repo.\n2. Get the latest commit to anchor the digest in time.\n3. Group activity into in-progress work, newly opened items, and anything stalled or awaiting review.\n\n## Output\nReturn a digest with three sections: open PRs (title, author, status), notable issues, and the latest commit. Keep it short enough to drop into a standup or Slack channel.',
|
||||
},
|
||||
{
|
||||
name: 'open-pull-request-with-changes',
|
||||
description:
|
||||
'Create a branch, commit a file change, and open a GitHub pull request for review.',
|
||||
content:
|
||||
'# Open Pull Request With Changes\n\nUse GitHub to land a change as a reviewable PR.\n\n## Steps\n1. Create a new branch off the default branch with Create branch.\n2. Create or update the target file on that branch with Create file or Update file, including a clear commit message.\n3. Open a pull request from the new branch with Create pull request, writing a descriptive title and body.\n4. Optionally request reviewers with Request PR reviewers.\n\n## Output\nReturn the new PR number and URL, the branch name, and the files changed so the requester can track it to merge.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
export const GitHubV2BlockMeta = {
|
||||
|
||||
@@ -819,4 +819,27 @@ export const GitLabBlockMeta = {
|
||||
tags: ['engineering', 'research', 'devops'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'review-merge-request',
|
||||
description:
|
||||
'Fetch a GitLab merge request and post a structured review comment with actionable feedback.',
|
||||
content:
|
||||
'# Review Merge Request\n\nUse GitLab to read a merge request and leave a useful review.\n\n## Steps\n1. Get the merge request by project ID and MR IID to read its title, description, and changes.\n2. Assess the change for correctness, missing tests, and risky edits.\n3. Post a review note on the MR with Add MR Comment, summarizing the feedback.\n\n## Output\nConfirm the comment was posted and return a short summary: what looks good, what needs changes, and any blocking concerns.',
|
||||
},
|
||||
{
|
||||
name: 'triage-gitlab-issue',
|
||||
description:
|
||||
'Read a GitLab issue, classify it, and post a triage comment or update its fields.',
|
||||
content:
|
||||
'# Triage GitLab Issue\n\nUse GitLab to triage an incoming issue.\n\n## Steps\n1. Get the issue by project ID and issue IID to read its title and description.\n2. Classify it (bug, feature, question) and judge severity.\n3. Update the issue with the right labels and assignee using Update Issue, and add a triage note with Add Issue Comment.\n\n## Output\nReturn the classification, applied labels, assignee, and a one-line triage summary. Note any missing reproduction details.',
|
||||
},
|
||||
{
|
||||
name: 'monitor-pipeline-status',
|
||||
description:
|
||||
'Check GitLab pipeline status for a project and report failures, optionally retrying a failed pipeline.',
|
||||
content:
|
||||
'# Monitor Pipeline Status\n\nUse GitLab to keep an eye on CI pipelines.\n\n## Steps\n1. List pipelines for the project and identify the most recent runs.\n2. Get the pipeline details for any that failed to read the status and reason.\n3. If a failure looks transient, use Retry Pipeline to re-run it.\n\n## Output\nReturn a summary of recent pipeline runs (ref, status, when) and call out any failures. If a retry was triggered, include the retried pipeline ID.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -728,6 +728,33 @@ export const GmailBlockMeta = {
|
||||
alsoIntegrations: ['notion'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'triage-inbox',
|
||||
description:
|
||||
'Sort unread email by urgency and draft replies for the most important messages.',
|
||||
content:
|
||||
'# Triage Inbox\n\nReview unread Gmail messages and bring order to the inbox.\n\n## Steps\n1. Read unread messages from the relevant time window.\n2. Classify each as Urgent, Today, This week, or FYI based on sender, subject, and content.\n3. For Urgent and Today items, draft a concise reply.\n4. Flag anything that needs a meeting or a decision from someone else.\n\n## Output\nReturn a prioritized list: each message with its sender, a one-line summary, the assigned priority, and the draft reply where one was written. Do not send anything without confirmation.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-email-thread',
|
||||
description: 'Condense a long email thread into the key points, decisions, and action items.',
|
||||
content:
|
||||
'# Summarize Email Thread\n\nGiven a Gmail thread, produce a tight summary.\n\n## Steps\n1. Read every message in the thread in order.\n2. Identify the core topic, what was decided, and what is still open.\n3. Pull out action items and who owns each.\n\n## Output\n- A one-sentence TL;DR.\n- Key decisions as bullets.\n- Action items with owners.\n- Open questions that still need an answer.',
|
||||
},
|
||||
{
|
||||
name: 'draft-reply-from-context',
|
||||
description: 'Draft a contextual reply to an email in the right tone, ready for review.',
|
||||
content:
|
||||
'# Draft Reply From Context\n\nWrite a reply to an incoming email that is ready to send after a quick review.\n\n## Steps\n1. Read the email and any prior thread context.\n2. Determine what the sender is asking for and the appropriate tone (formal, friendly, brief).\n3. Draft a reply that answers every question and proposes clear next steps.\n\n## Output\nA complete draft reply with subject and body. Keep it concise, match the sender style, and leave placeholders in brackets for any detail you cannot infer. Do not send without confirmation.',
|
||||
},
|
||||
{
|
||||
name: 'find-and-extract-emails',
|
||||
description: 'Search Gmail for messages matching a query and extract the details you need.',
|
||||
content:
|
||||
'# Find And Extract Emails\n\nLocate specific emails and pull structured information from them.\n\n## Steps\n1. Build a Gmail search query from the request (sender, subject keywords, date range, label, has attachment).\n2. Retrieve matching messages.\n3. Extract the requested fields from each, for example invoice amounts, order numbers, contact details, or attachment names.\n\n## Output\nA structured list of the matching emails with the extracted fields, plus a link or message id for each so the source can be opened.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
export const GmailV2BlockMeta = {
|
||||
|
||||
@@ -784,4 +784,27 @@ export const GongBlockMeta = {
|
||||
tags: ['sales', 'research'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'summarize-call',
|
||||
description:
|
||||
'Pull a Gong call transcript and produce a structured recap with topics, objections, and next steps.',
|
||||
content:
|
||||
'# Summarize Call\n\nUse Gong to turn a recorded call into a clean recap.\n\n## Steps\n1. Get the call by its call ID to read the metadata (participants, duration, account).\n2. Get the call transcript for the same call ID.\n3. Identify the main topics, customer objections, and agreed next steps from the transcript.\n\n## Output\nReturn a recap: a short overview, key topics discussed, objections raised, and a list of next steps with owners. Keep it grounded in the transcript.',
|
||||
},
|
||||
{
|
||||
name: 'extract-deal-signals',
|
||||
description:
|
||||
'Read a Gong call transcript and extract CRM-ready deal signals like decision-maker, competitor, and next step.',
|
||||
content:
|
||||
'# Extract Deal Signals\n\nUse Gong to turn conversation content into structured deal attributes.\n\n## Steps\n1. Get the call transcript for the given call ID.\n2. Scan for high-value signals: decision-maker, budget, timeline, competitor mentions, use case, and the agreed next step with its date.\n3. Normalize each signal into a structured field.\n\n## Output\nReturn a structured object of deal attributes (decision_maker, competitor, next_step, next_step_date, use_case, and any others found). Leave fields null when not mentioned rather than guessing, so they can be written to CRM.',
|
||||
},
|
||||
{
|
||||
name: 'review-recent-calls',
|
||||
description:
|
||||
'List recent Gong calls in a date range and produce a digest of themes and follow-ups across them.',
|
||||
content:
|
||||
'# Review Recent Calls\n\nUse Gong to summarize a batch of recent calls.\n\n## Steps\n1. List calls (or use Get Extensive Calls) filtered by a date range and optionally by user or workspace.\n2. For the most relevant calls, get the transcript to pull themes and outcomes.\n3. Roll the findings up into recurring themes, common objections, and open follow-ups across the calls.\n\n## Output\nReturn a digest: a per-call one-liner, the cross-call themes, and a consolidated follow-up list. Note any call missing a clear next step.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -162,4 +162,27 @@ export const GoogleSearchBlockMeta = {
|
||||
tags: ['support', 'research', 'automation'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'search-the-web',
|
||||
description:
|
||||
'Run a Google web search and return the most relevant results with titles and links.',
|
||||
content:
|
||||
'# Search the Web\n\nFind current information with Google Custom Search.\n\n## Steps\n1. Turn the request into an effective query. Use operators when helpful: "exact phrase", `site:domain.com`, `-exclude`, `OR`, `filetype:pdf`.\n2. Set Number of Results to a sensible value (e.g., 10).\n3. Run the search with the API key and Custom Search Engine ID.\n4. Read the result items: title, link, and snippet.\n\n## Output\nA ranked list of results, each with title, URL, and a one-line snippet. Drop low-relevance hits and note if the query returned little so it can be broadened.',
|
||||
},
|
||||
{
|
||||
name: 'research-and-summarize',
|
||||
description:
|
||||
'Search Google for a topic, gather the best sources, and synthesize a cited answer.',
|
||||
content:
|
||||
'# Research and Summarize\n\nAnswer a question from fresh web sources.\n\n## Steps\n1. Break the question into 1-3 focused search queries.\n2. Run each search and collect the most relevant result items (title, link, snippet).\n3. Synthesize a concise answer grounded in the snippets; do not assert facts the sources do not support.\n4. Attribute each claim to its source link.\n\n## Output\nA short, sourced answer followed by a list of the sources used (title + URL). If sources conflict, say so rather than guessing.',
|
||||
},
|
||||
{
|
||||
name: 'monitor-mentions',
|
||||
description:
|
||||
'Search Google for recent mentions of a brand, person, or keyword and surface notable hits.',
|
||||
content:
|
||||
'# Monitor Mentions\n\nFind recent web mentions of a target term.\n\n## Steps\n1. Build queries for the brand/person/keyword, optionally scoped with `site:` for specific outlets or quotes for exact names.\n2. Run the searches and collect result items.\n3. Filter out irrelevant or stale hits and dedupe near-identical results.\n4. Classify each remaining mention (e.g., news, review, social) and gauge tone where possible.\n\n## Output\nA list of notable mentions: title, source URL, a one-line summary, and a tone tag. Lead with the most significant items.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -364,4 +364,27 @@ export const GoogleAdsBlockMeta = {
|
||||
tags: ['marketing', 'analysis'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'report-campaign-performance',
|
||||
description:
|
||||
'Pull Google Ads campaign performance for a date range and produce a clear metrics report.',
|
||||
content:
|
||||
'# Report Campaign Performance\n\nUse Google Ads to summarize how campaigns are performing.\n\n## Steps\n1. List campaigns for the customer to know what is active.\n2. Use Campaign Performance over the chosen date range to pull impressions, clicks, cost, conversions, CTR, CPC, and ROAS.\n3. Rank campaigns by spend and by efficiency to surface what is working and what is not.\n\n## Output\nReturn a per-campaign metrics table plus a short narrative: top performers, underperformers, and where spend is being wasted. Note the date range used.',
|
||||
},
|
||||
{
|
||||
name: 'analyze-ad-performance',
|
||||
description:
|
||||
'Pull ad-level Google Ads performance and identify the best and worst creatives in each ad group.',
|
||||
content:
|
||||
'# Analyze Ad Performance\n\nUse Google Ads to compare creatives within campaigns.\n\n## Steps\n1. List ad groups for the target campaign or customer.\n2. Use Ad Performance over the date range to pull per-ad clicks, conversions, CTR, and cost.\n3. Within each ad group, identify the strongest and weakest ads.\n\n## Output\nReturn, per ad group, the best and worst performing ads with their key metrics, plus a recommendation (scale, pause, or rewrite). Keep recommendations tied to the data.',
|
||||
},
|
||||
{
|
||||
name: 'run-gaql-query',
|
||||
description:
|
||||
'Run a custom GAQL query against Google Ads to answer a specific reporting question.',
|
||||
content:
|
||||
'# Run GAQL Query\n\nUse Google Ads to answer an ad-hoc reporting question with GAQL.\n\n## Steps\n1. Clarify the metrics, dimensions, and segments the question needs.\n2. Write a valid GAQL query (SELECT fields FROM resource WHERE conditions) scoped to the customer and date range.\n3. Use the Custom Query operation to run it and read the rows.\n\n## Output\nReturn the result rows as a clean table along with the GAQL query that produced them, so the analysis is reproducible.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -359,4 +359,26 @@ export const GoogleBigQueryBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'answer-question-with-sql',
|
||||
description:
|
||||
'Inspect BigQuery schema, translate a natural-language question into safe SQL, run it, and return results.',
|
||||
content:
|
||||
'# Answer Question With SQL\n\nUse BigQuery to answer a data question from plain English.\n\n## Steps\n1. List datasets and tables, and Get Table on the relevant ones to understand the schema and column types.\n2. Translate the question into a single read-only BigQuery Standard SQL query, scoping it with filters and a LIMIT to control cost.\n3. Use Run Query to execute it.\n\n## Output\nReturn the result rows as a table plus the exact SQL query used, so the answer is verifiable. If the schema cannot support the question, say what is missing.',
|
||||
},
|
||||
{
|
||||
name: 'explore-dataset-schema',
|
||||
description:
|
||||
'List BigQuery datasets and tables and summarize the schema of a dataset for an analyst.',
|
||||
content:
|
||||
'# Explore Dataset Schema\n\nUse BigQuery to map out what data is available.\n\n## Steps\n1. List datasets in the project.\n2. List tables in the target dataset.\n3. Get Table on each relevant table to read its columns, types, and descriptions.\n\n## Output\nReturn a structured schema summary: each table with its columns, types, and a one-line purpose. Highlight likely join keys so an analyst can plan queries.',
|
||||
},
|
||||
{
|
||||
name: 'load-rows-to-table',
|
||||
description: 'Insert structured rows into a BigQuery table for logging or pipeline output.',
|
||||
content:
|
||||
'# Load Rows to Table\n\nUse BigQuery to write structured records into a table.\n\n## Steps\n1. Confirm the target dataset and table, and Get Table to verify the expected columns and types.\n2. Shape the incoming records to match the table schema exactly.\n3. Use Insert Rows to write the batch.\n\n## Output\nReturn the count of rows inserted and any rows rejected with their error. If types did not match the schema, report which fields failed rather than silently dropping data.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -271,4 +271,27 @@ export const GoogleBooksBlockMeta = {
|
||||
tags: ['research'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'find-books-on-topic',
|
||||
description:
|
||||
'Search Google Books for the most relevant titles on a topic and return a ranked, summarized list.',
|
||||
content:
|
||||
'# Find Books on a Topic\n\nUse Google Books to discover authoritative titles for a subject and present a clean shortlist.\n\n## Steps\n1. Take the topic or question from the request.\n2. Run a Search Volumes operation with a focused query. Use field operators when helpful: `intitle:`, `inauthor:`, `subject:`. Set Order By to `relevance` (or `newest` for recent works).\n3. Set Max Results (1-40) and optionally filter by Print Type (books) or eBook availability.\n4. For the top hits, read title, authors, publisher, published date, average rating, and a short description.\n5. Rank by relevance and rating; drop clearly off-topic results.\n\n## Output\nA numbered list of up to 10 books, each with title, author(s), year, rating (if present), one-line summary, and the preview/info link. Note if a result set is thin so the requester can broaden the query.',
|
||||
},
|
||||
{
|
||||
name: 'lookup-book-by-isbn',
|
||||
description:
|
||||
'Resolve an ISBN or title into a single canonical book record with full metadata.',
|
||||
content:
|
||||
'# Look Up a Book by ISBN or Title\n\nResolve a specific book to its canonical Google Books record.\n\n## Steps\n1. If you have an ISBN, run Search Volumes with query `isbn:<the isbn>`. Otherwise search by `intitle:` plus `inauthor:` to disambiguate.\n2. Pick the best-matching volume and capture its volume ID.\n3. Run Get Volume Details on that volume ID for the fullest metadata.\n4. Collect title, subtitle, authors, publisher, published date, page count, categories, language, ISBN-10/13, and description.\n\n## Output\nA single structured record: title, authors, publisher, year, ISBNs, page count, categories, and the info link. If multiple editions match, list them and flag which is most likely intended.',
|
||||
},
|
||||
{
|
||||
name: 'build-reading-list',
|
||||
description:
|
||||
'Assemble a curated, themed reading list with summaries from Google Books search results.',
|
||||
content:
|
||||
'# Build a Reading List\n\nTurn a topic into a curated reading list a person can act on.\n\n## Steps\n1. Identify the theme and any constraints (level, recency, language) from the request.\n2. Run one or more Search Volumes queries covering the main subtopics; use `langRestrict` and `orderBy` as needed.\n3. For each candidate, capture authors, year, rating, and description.\n4. Deduplicate editions of the same work and keep the best edition.\n5. Group the final picks into 2-4 logical sections (e.g., foundational, advanced, recent).\n\n## Output\nA grouped reading list. Each entry: title, author(s), year, a one-sentence reason it is included, and the preview link. Keep it to 8-15 titles unless asked otherwise.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -782,6 +782,34 @@ export const GoogleCalendarBlockMeta = {
|
||||
tags: ['sales', 'research', 'automation'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'schedule-meeting',
|
||||
description:
|
||||
'Create a Google Calendar event with the right time, attendees, and details, sending invites.',
|
||||
content:
|
||||
'# Schedule a Meeting\n\nCreate a calendar event and invite attendees.\n\n## Steps\n1. Determine the calendar (default to `primary`), title, start and end times, location, and description from the request.\n2. Convert times to ISO 8601 with the correct timezone offset (e.g., `2025-06-03T10:00:00-08:00`).\n3. If the request is conversational (e.g., "lunch with John tomorrow at noon"), use Quick Add instead of building each field by hand.\n4. Run Create Event (or Quick Add) with the attendee emails as a comma-separated list.\n5. Set Send Email Notifications to `all` so attendees are invited.\n\n## Output\nConfirm the created event: title, start/end in a readable format, attendees, and the event link (htmlLink). If a conflict is likely, note it.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-daily-agenda',
|
||||
description:
|
||||
"List today's Google Calendar events and produce a clean, ordered agenda summary.",
|
||||
content:
|
||||
'# Summarize the Daily Agenda\n\nProduce a readable agenda for a day or window.\n\n## Steps\n1. Resolve the target window into UTC ISO timestamps for Start Time Filter (timeMin) and End Time Filter (timeMax). For "today", use 00:00:00Z to 23:59:59Z.\n2. Run List Events on the chosen calendar with those filters and a reasonable Max Results.\n3. Sort events chronologically and read summary, start/end, location, and attendees for each.\n4. Flag back-to-back meetings and any event with no agenda or description.\n\n## Output\nA chronological agenda. Each line: time range, title, location (if any), and attendee count. Add a short header with total meetings and total meeting hours.',
|
||||
},
|
||||
{
|
||||
name: 'find-and-reschedule-event',
|
||||
description: 'Locate an existing event and update its time, attendees, or details.',
|
||||
content:
|
||||
'# Find and Reschedule an Event\n\nUpdate an existing calendar event.\n\n## Steps\n1. If you do not have the event ID, run List Events over a suitable window and match by title/attendees to find the event ID.\n2. Run Get Event to read the current details and confirm it is the right one.\n3. Run Update Event with only the changed fields (new start/end in ISO 8601 with offset, new attendees, new location, or title).\n4. Set Send Email Notifications to `all` so attendees see the change.\n\n## Output\nConfirm what changed (old vs new time/attendees) and return the event link. If multiple events matched, list them and ask which to update before changing anything destructive.',
|
||||
},
|
||||
{
|
||||
name: 'invite-attendees-to-event',
|
||||
description: 'Add attendees to an existing Google Calendar event and notify them.',
|
||||
content:
|
||||
'# Invite Attendees to an Event\n\nAdd people to an event without recreating it.\n\n## Steps\n1. Obtain the event ID (use List Events to find it if needed).\n2. Collect the attendee emails to add as a comma-separated list.\n3. Run Invite Attendees with Replace Existing set to `Add to existing attendees` (unless asked to replace the whole list).\n4. Set Send Email Notifications to `all`.\n\n## Output\nConfirm the added attendees and the resulting full attendee list, with the event link.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
export const GoogleCalendarV2BlockMeta = {
|
||||
|
||||
@@ -347,4 +347,26 @@ export const GoogleContactsBlockMeta = {
|
||||
alsoIntegrations: ['workday'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'add-contact',
|
||||
description: 'Create a new Google Contact with name, email, phone, and organization details.',
|
||||
content:
|
||||
'# Add a Contact\n\nCreate a new entry in Google Contacts.\n\n## Steps\n1. Gather the contact fields from the request: first name (required), last name, email, phone, organization, job title, and notes.\n2. Before creating, run Search Contacts on the email or full name to avoid duplicates.\n3. If no match exists, run Create Contact with the gathered fields and the appropriate email/phone types (work, home, mobile).\n4. Capture the new resource name from the response.\n\n## Output\nConfirm the created contact with name, email, organization, and the resource name. If a likely duplicate was found, surface it and ask before creating.',
|
||||
},
|
||||
{
|
||||
name: 'find-contact',
|
||||
description:
|
||||
'Search Google Contacts by name, email, phone, or organization and return matches.',
|
||||
content:
|
||||
'# Find a Contact\n\nLook up someone in Google Contacts.\n\n## Steps\n1. Build a query from whatever identifier you have (name, email, phone, or organization).\n2. Run Search Contacts with that query and a sensible Page Size.\n3. If you need full details for one match, take its resource name and run Get Contact.\n\n## Output\nA list of matching contacts with name, email, phone, organization, and resource name. If exactly one matches, return its full record; if several match, list them so the requester can disambiguate.',
|
||||
},
|
||||
{
|
||||
name: 'update-contact-details',
|
||||
description:
|
||||
'Update fields on an existing Google Contact such as email, phone, or job title.',
|
||||
content:
|
||||
'# Update Contact Details\n\nModify an existing Google Contact safely.\n\n## Steps\n1. If you do not have the resource name, run Search Contacts to find it.\n2. Run Get Contact to read the current values and capture the ETag (required for updates).\n3. Run Update Contact with the resource name, the ETag, and the changed fields only.\n4. If the update fails on a stale ETag, re-run Get Contact and retry with the fresh ETag.\n\n## Output\nConfirm which fields changed (old vs new) and return the updated record. Never update without first fetching the current ETag.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -284,4 +284,26 @@ export const GoogleDocsBlockMeta = {
|
||||
tags: ['team', 'research', 'sync'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'create-document-from-content',
|
||||
description: 'Create a new Google Doc with a title and formatted content in a chosen folder.',
|
||||
content:
|
||||
'# Create a Document from Content\n\nGenerate a new Google Doc from supplied or drafted content.\n\n## Steps\n1. Determine the document title and the body content from the request.\n2. If the content uses headings, bold, lists, tables, or links, enable the Markdown option so it renders as formatted Doc content; otherwise leave it off for plain text.\n3. Optionally set the parent folder ID to file the doc in the right place.\n4. Run the Create Document operation with the title, content, and folder.\n\n## Output\nConfirm creation and return the document ID and link. If a folder was specified, confirm it was placed there.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-document',
|
||||
description:
|
||||
'Read a Google Doc and produce a concise summary with key points and action items.',
|
||||
content:
|
||||
'# Summarize a Document\n\nRead a Doc and distill it.\n\n## Steps\n1. Obtain the document ID (select the doc or pass its ID).\n2. Run the Read Document operation to pull the full text.\n3. Identify the main thesis, key points, decisions, and any action items or owners.\n4. Keep the summary faithful to the source; do not invent details not present.\n\n## Output\nA short summary: a one-line gist, 3-6 bullet key points, and an Action Items section (owner + task) if any exist. Reference the doc link.',
|
||||
},
|
||||
{
|
||||
name: 'append-to-document',
|
||||
description:
|
||||
'Write additional content into an existing Google Doc, such as a running log or report section.',
|
||||
content:
|
||||
'# Append to a Document\n\nAdd a new section to an existing Doc.\n\n## Steps\n1. Obtain the target document ID.\n2. Draft the content to add, clearly delimited (e.g., a dated heading for a running log).\n3. Run the Write to Document operation with the document ID and the new content.\n4. For recurring updates, prefix each entry with a date or section header so the doc stays organized.\n\n## Output\nConfirm the content was written and return the document link. Summarize in one line what was appended.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -1281,4 +1281,34 @@ export const GoogleDriveBlockMeta = {
|
||||
tags: ['team', 'research', 'sync'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'find-file-in-drive',
|
||||
description:
|
||||
'Search Google Drive with query syntax to locate files by name, type, content, or date.',
|
||||
content:
|
||||
"# Find a File in Drive\n\nLocate files using Drive query syntax.\n\n## Steps\n1. Translate the request into a Drive query. Common clauses: `name contains 'term'`, `fullText contains 'term'`, `mimeType = 'application/pdf'`, `modifiedTime > '2024-01-01T00:00:00'`, `'email' in owners`, `trashed = false`.\n2. Run the Search Files operation with that query and a Results Per Page value.\n3. If results are too broad, add `and` clauses (file type, owner, date) to narrow.\n4. For a chosen result, run Get File Info for full metadata.\n\n## Output\nA list of matching files: name, type, owner, modified date, and the file ID. Highlight the single best match if the intent was specific.",
|
||||
},
|
||||
{
|
||||
name: 'organize-files-into-folders',
|
||||
description:
|
||||
'Create folders and move or copy files in Google Drive to keep storage organized.',
|
||||
content:
|
||||
'# Organize Files into Folders\n\nFile and tidy Drive content.\n\n## Steps\n1. Identify the target structure: which folder should exist and what goes in it.\n2. If the destination folder does not exist, run Create Folder (set its parent if needed) and capture the new folder ID.\n3. For each file to relocate, run Move File with the destination folder ID. Use Copy File instead when the original must stay in place.\n4. Optionally run Update File to rename files to a consistent convention.\n\n## Output\nA summary of what was created and moved: destination folder link, count of files relocated, and any renames applied.',
|
||||
},
|
||||
{
|
||||
name: 'share-file-with-people',
|
||||
description:
|
||||
'Grant access to a Google Drive file for users, groups, a domain, or anyone with the link.',
|
||||
content:
|
||||
'# Share a File\n\nGrant access to a Drive file with the right permission level.\n\n## Steps\n1. Obtain the file ID (select it or run Search Files).\n2. Decide the share target: a specific user/group email, an entire domain, or anyone with the link.\n3. Choose the permission level: Viewer (reader), Commenter, or Editor (writer).\n4. Run the Share File operation with the target and role. For user/group shares, optionally include a notification message.\n\n## Output\nConfirm who now has access and at what level, plus the file link. Avoid `anyone` unless explicitly requested.',
|
||||
},
|
||||
{
|
||||
name: 'read-file-content',
|
||||
description:
|
||||
'Extract the text content of a Google Drive file, exporting Workspace files to a usable format.',
|
||||
content:
|
||||
'# Read File Content\n\nPull the text out of a Drive file for downstream use.\n\n## Steps\n1. Obtain the file ID.\n2. Run the Get File Content operation. For Google Docs/Sheets/Slides, set Export Format (Auto picks the best, or choose Plain Text / PDF / DOCX explicitly).\n3. For non-Workspace files (PDF, TXT), the content is returned directly.\n4. Use the returned text for summarization, extraction, or indexing.\n\n## Output\nReturn the extracted content (or a summary of it if large), noting the file name and the export format used.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -543,4 +543,25 @@ export const GoogleFormsBlockMeta = {
|
||||
alsoIntegrations: ['gmail'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'collect-form-responses',
|
||||
description: 'Retrieve and structure responses from a Google Form for analysis or routing.',
|
||||
content:
|
||||
'# Collect Form Responses\n\nPull submissions from a Google Form.\n\n## Steps\n1. Select the form (or pass its form ID).\n2. Run the Get Responses operation; set Page Size to cover the expected volume. Leave Response ID empty to fetch all, or set it to fetch one specific submission.\n3. To map answers to questions, run Get Form once and use the item titles to label each answer.\n4. Normalize each response into clean rows keyed by question.\n\n## Output\nA structured list of responses with respondent answers labeled by question. Include the total count and the time range covered.',
|
||||
},
|
||||
{
|
||||
name: 'analyze-survey-results',
|
||||
description:
|
||||
'Read Google Form responses and summarize trends, sentiment, and notable findings.',
|
||||
content:
|
||||
'# Analyze Survey Results\n\nTurn raw form responses into insight.\n\n## Steps\n1. Run Get Form to learn the questions and their types (choice, scale, text).\n2. Run Get Responses to pull all submissions.\n3. For choice/scale questions, compute distributions and averages. For free-text, cluster into themes and gauge sentiment.\n4. Surface the strongest signals and any outliers or recurring complaints.\n\n## Output\nA digest: response count, per-question breakdown (top choices, averages), 3-5 key themes from free text, and notable verbatim quotes. Keep numbers accurate to the data.',
|
||||
},
|
||||
{
|
||||
name: 'create-form',
|
||||
description: 'Create a new Google Form and add questions via batch update.',
|
||||
content:
|
||||
'# Create a Form\n\nBuild a new Google Form with questions.\n\n## Steps\n1. Run Create Form with the form title (and optional document title). Capture the returned form ID.\n2. Build a Batch Update requests array to add questions. Use `createItem` with `choiceQuestion` (RADIO/CHECKBOX/DROP_DOWN), `textQuestion`, or `scaleQuestion`, each at a `location.index`.\n3. Run Batch Update on the form ID with that requests array.\n4. If the form should accept submissions, run Set Publish Settings with Published on.\n\n## Output\nConfirm the form was created, list the questions added, and return the responder URL and form ID.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -530,4 +530,31 @@ export const GoogleGroupsBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'add-member-to-group',
|
||||
description:
|
||||
'Add a user to a Google Workspace group with a chosen role and confirm membership.',
|
||||
content:
|
||||
'# Add a Member to a Group\n\nGrant someone membership in a Workspace group.\n\n## Steps\n1. Identify the group email or ID and the member email.\n2. Run Check Membership first to see if the user is already a member; skip the add if so.\n3. Run Add Member with the member email and the desired role (MEMBER, MANAGER, or OWNER; default MEMBER).\n4. Optionally run Check Membership again to confirm the add succeeded.\n\n## Output\nConfirm the user was added (or already present), the role granted, and the group. Note if the operation requires admin privileges that were missing.',
|
||||
},
|
||||
{
|
||||
name: 'audit-group-membership',
|
||||
description: 'List the members and roles of a Google Group for access review or compliance.',
|
||||
content:
|
||||
'# Audit Group Membership\n\nProduce a membership roster for a group.\n\n## Steps\n1. Identify the group email or ID.\n2. Run List Members with a Max Results value; optionally filter by roles (OWNER, MANAGER, MEMBER).\n3. Page through results using the next page token until all members are collected.\n4. Separate owners/managers from regular members and flag any external-domain addresses.\n\n## Output\nA roster grouped by role: owners, managers, members. Include total counts and a list of any external members for review.',
|
||||
},
|
||||
{
|
||||
name: 'create-group',
|
||||
description: 'Create a new Google Workspace group with an email, name, and description.',
|
||||
content:
|
||||
'# Create a Group\n\nStand up a new Workspace group.\n\n## Steps\n1. Decide the group email address, display name, and a clear description of its purpose.\n2. Run List Groups (filter by the intended email/name) to confirm it does not already exist.\n3. Run Create Group with the email, name, and description.\n4. Optionally run Add Member to seed initial owners/managers.\n\n## Output\nConfirm the created group with its email, name, and description. List any initial members added. Note that this requires Workspace admin access.',
|
||||
},
|
||||
{
|
||||
name: 'remove-member-from-group',
|
||||
description: 'Remove a user from a Google Group, useful for offboarding and access cleanup.',
|
||||
content:
|
||||
"# Remove a Member from a Group\n\nRevoke a user's group membership.\n\n## Steps\n1. Identify the group email/ID and the member email or ID.\n2. Run Check Membership to confirm the user is actually a member.\n3. If present, run Remove Member with the group and member keys.\n4. For offboarding across many groups, run List Groups filtered by `memberKey:<email>` first to find every group the user belongs to, then remove from each.\n\n## Output\nConfirm the removal per group, and for offboarding list every group the user was removed from. Note any failures for manual follow-up.",
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -712,4 +712,32 @@ export const GoogleMapsBlockMeta = {
|
||||
alsoIntegrations: ['hunter', 'hubspot'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'geocode-address',
|
||||
description:
|
||||
'Convert an address into latitude/longitude coordinates with a normalized formatted address.',
|
||||
content:
|
||||
'# Geocode an Address\n\nTurn a street address into coordinates.\n\n## Steps\n1. Take the address string from the request.\n2. Run the Geocode Address operation; optionally set a Region Bias (country code) to disambiguate.\n3. Read the returned lat, lng, formatted address, place ID, and location type.\n4. If multiple candidates are likely, note the accuracy/location type so the requester can confirm.\n\n## Output\nReturn the formatted address, latitude, longitude, and place ID. To go the other way (coordinates to address), use Reverse Geocode instead.',
|
||||
},
|
||||
{
|
||||
name: 'get-directions',
|
||||
description:
|
||||
'Compute a route between two locations with distance, duration, and turn-by-turn steps.',
|
||||
content:
|
||||
'# Get Directions\n\nRoute between an origin and a destination.\n\n## Steps\n1. Capture origin and destination (addresses or `lat,lng`).\n2. Choose Travel Mode (driving, walking, bicycling, transit) and optionally features to Avoid (tolls, highways, ferries).\n3. Add Waypoints (pipe-separated) for intermediate stops if requested, and pick Units (metric/imperial).\n4. Run the Get Directions operation.\n\n## Output\nReturn total distance and duration (as text and numeric), start/end addresses, and a concise turn-by-turn step list. Mention the travel mode used.',
|
||||
},
|
||||
{
|
||||
name: 'find-nearby-places',
|
||||
description: 'Search for places matching a query near a location and return ranked results.',
|
||||
content:
|
||||
'# Find Nearby Places\n\nDiscover places (restaurants, hotels, etc.) near a spot.\n\n## Steps\n1. Build the Search Query (e.g., "coffee near Times Square") and set a Location Bias (`lat,lng`) and Radius if known.\n2. Optionally constrain by Place Type (restaurant, hotel, gas_station, etc.).\n3. Run the Search Places operation.\n4. For a chosen result, run Place Details with its Place ID to get rating, hours, phone, and website.\n\n## Output\nA ranked list of places: name, address, rating and number of ratings, open-now status, and place ID. Include phone/website for the top pick when details were fetched.',
|
||||
},
|
||||
{
|
||||
name: 'calculate-travel-distances',
|
||||
description: 'Compute distances and travel times from one origin to many destinations.',
|
||||
content:
|
||||
'# Calculate Travel Distances\n\nGet a distance matrix from an origin to multiple destinations.\n\n## Steps\n1. Set the Origin and provide Destinations as a pipe-separated list (e.g., "New York, NY|Boston, MA").\n2. Choose Travel Mode and Units; optionally set features to Avoid.\n3. Run the Distance Matrix operation.\n4. Read each row for distance and duration to each destination.\n\n## Output\nA table of destinations sorted by travel time or distance, each with distance text and duration text. Useful for picking the nearest option or planning routes.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -254,4 +254,25 @@ export const GoogleMeetBlockMeta = {
|
||||
alsoIntegrations: ['notion'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'create-meeting-space',
|
||||
description: 'Create a Google Meet space and return its join link and meeting code.',
|
||||
content:
|
||||
'# Create a Meeting Space\n\nSpin up a Google Meet space to share.\n\n## Steps\n1. Decide the Access Type: Open (anyone with link), Trusted (organization members), or Restricted (invited only).\n2. Optionally set Entry Point Access if the space should only be joinable from the creating app.\n3. Run the Create Space operation.\n4. Capture the meeting URI and meeting code from the response.\n\n## Output\nReturn the meeting link (meetingUri), the meeting code, the access type, and the space resource name so it can be referenced or shared.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-meeting-attendance',
|
||||
description:
|
||||
'Pull a Google Meet conference record and its participants to report who attended.',
|
||||
content:
|
||||
'# Summarize Meeting Attendance\n\nReport attendance for a finished meeting.\n\n## Steps\n1. If you only have the space, run List Conference Records (filter by `space.name = "spaces/..."`) to find the conference record name.\n2. Run Get Conference Record to read start time, end time, and duration.\n3. Run List Participants on that conference record name, paging through results.\n4. Build the attendee list and compute meeting duration.\n\n## Output\nAn attendance summary: meeting start/end and duration, total participant count, and the list of participants. Flag the meeting if no participants are recorded.',
|
||||
},
|
||||
{
|
||||
name: 'list-recent-conferences',
|
||||
description: 'List recent Google Meet conference records for reporting or archival.',
|
||||
content:
|
||||
'# List Recent Conferences\n\nEnumerate past Meet conferences.\n\n## Steps\n1. Run List Conference Records with a Page Size; optionally apply a Filter (e.g., by space name or time).\n2. Page through using the next page token until you have the needed window.\n3. For each record capture the conference record name, associated space, start time, and end time.\n4. Optionally fetch participants per record (List Participants) when attendance is needed.\n\n## Output\nA list of conferences sorted by start time, each with space, start/end, and duration. Include the conference record name so any record can be drilled into.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -150,4 +150,25 @@ export const GooglePagespeedBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'audit-page-performance',
|
||||
description:
|
||||
'Run a PageSpeed Insights analysis on a URL and report scores and Core Web Vitals.',
|
||||
content:
|
||||
'# Audit Page Performance\n\nMeasure a page with PageSpeed Insights (Lighthouse).\n\n## Steps\n1. Take the page URL.\n2. Choose the Strategy: mobile (recommended for ranking) or desktop. Run once per strategy if both are needed.\n3. Optionally set Categories (performance, accessibility, best-practices, seo) and Locale.\n4. Run the analysis and read the category scores plus Core Web Vitals (LCP, FCP, CLS, TBT, Speed Index, TTI).\n\n## Output\nA report: per-category scores (0-100), Core Web Vitals with their display values, and the final URL analyzed. Call out any metric in the poor range and the strategy used.',
|
||||
},
|
||||
{
|
||||
name: 'compare-mobile-vs-desktop',
|
||||
description: 'Analyze a page on both mobile and desktop and contrast the scores and vitals.',
|
||||
content:
|
||||
"# Compare Mobile vs Desktop\n\nContrast a page's performance across form factors.\n\n## Steps\n1. Run the analysis on the URL with Strategy = mobile.\n2. Run it again with Strategy = desktop.\n3. Line up the category scores and Core Web Vitals from each run.\n4. Identify the biggest gaps (typically LCP/TBT on mobile).\n\n## Output\nA side-by-side comparison table of mobile vs desktop scores and key vitals, plus a short note on where mobile lags and what likely causes it.",
|
||||
},
|
||||
{
|
||||
name: 'track-core-web-vitals',
|
||||
description: 'Capture Core Web Vitals for one or more pages to feed a monitoring history.',
|
||||
content:
|
||||
'# Track Core Web Vitals\n\nCapture CWV metrics for trend tracking.\n\n## Steps\n1. For each target URL, run the analysis (usually Strategy = mobile) limiting Categories to performance for speed.\n2. Extract LCP, CLS, TBT, FCP, Speed Index, and TTI numeric values plus the performance score.\n3. Stamp each row with the URL and analysis timestamp.\n4. Compare against any prior baseline to detect regressions.\n\n## Output\nOne row per URL with the performance score and CWV numeric values, ready to append to a history table. Flag any metric that regressed beyond a threshold versus the baseline.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -1176,6 +1176,32 @@ export const GoogleSheetsBlockMeta = {
|
||||
alsoIntegrations: ['notion'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'read-sheet-data',
|
||||
description: 'Read rows from a Google Sheet, optionally filtering by a column value.',
|
||||
content:
|
||||
'# Read Sheet Data\n\nPull data out of a spreadsheet tab.\n\n## Steps\n1. Select the spreadsheet and the Sheet (tab) to read.\n2. Optionally set a Cell Range (e.g., A1:D100); leave blank to read the used range.\n3. To narrow rows, set Filter Column (a header name), Filter Value, and Match Type (contains, exact, gt, etc.).\n4. Run the Read Data operation and treat the first row as headers if present.\n\n## Output\nReturn the rows (as a 2D array or labeled objects keyed by header), the range read, and a filter summary if a filter was applied. Note the row count.',
|
||||
},
|
||||
{
|
||||
name: 'append-rows-to-sheet',
|
||||
description: 'Add new rows to the end of a Google Sheet without overwriting existing data.',
|
||||
content:
|
||||
'# Append Rows to a Sheet\n\nAdd records to the bottom of a tab.\n\n## Steps\n1. Select the spreadsheet and Sheet (tab).\n2. Build the Values as a JSON array of arrays (each inner array is a row) or array of objects keyed by column.\n3. Set Insert Data Option to Insert Rows so existing data is not overwritten.\n4. Choose Value Input Option: User Entered (parses formulas/dates) or Raw.\n5. Run the Append Data operation.\n\n## Output\nConfirm the append: updated range, rows added, and the table range. Ensure column order matches the sheet headers.',
|
||||
},
|
||||
{
|
||||
name: 'update-cells',
|
||||
description: 'Write or update values in a specific range of a Google Sheet.',
|
||||
content:
|
||||
'# Update Cells\n\nWrite values into a targeted range.\n\n## Steps\n1. Select the spreadsheet and Sheet (tab) and set the Cell Range to write (e.g., B2:D2).\n2. Build the Values JSON so its dimensions match the range.\n3. Pick Value Input Option: User Entered to evaluate formulas, or Raw to store literal text.\n4. Run the Update Data operation (use Write Data to set a fresh block).\n\n## Output\nConfirm updated range and the count of updated cells/rows/columns. If writing formulas, confirm User Entered was used so they evaluate.',
|
||||
},
|
||||
{
|
||||
name: 'create-spreadsheet',
|
||||
description: 'Create a new Google Sheets spreadsheet with named tabs and return its link.',
|
||||
content:
|
||||
'# Create a Spreadsheet\n\nStand up a new spreadsheet.\n\n## Steps\n1. Set the Spreadsheet Title.\n2. Optionally provide Sheet Names as a comma-separated list (e.g., "Data, Summary").\n3. Run the Create Spreadsheet operation and capture the spreadsheet ID and URL.\n4. Follow up with Write or Append operations to populate the tabs.\n\n## Output\nReturn the new spreadsheet title, ID, URL, and the list of sheets created. Hand back the ID so subsequent steps can write to it.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
export const GoogleSheetsV2BlockMeta = {
|
||||
|
||||
@@ -3567,6 +3567,36 @@ export const GoogleSlidesBlockMeta = {
|
||||
alsoIntegrations: ['salesforce', 'gmail'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'generate-deck-from-template',
|
||||
description:
|
||||
'Copy a Google Slides template and replace placeholder text and images with data to produce a finished deck.',
|
||||
content:
|
||||
'# Generate Deck From Template\n\nProduce a finished presentation by copying a template deck and filling in dynamic values.\n\n## Steps\n1. Create a copy of the template presentation, or create a new presentation, and capture its presentationId.\n2. For each placeholder token (e.g. {{company}}, {{date}}, {{metric}}), call replace all text to substitute the real value across every slide.\n3. Replace placeholder images by adding images to the relevant slides, sizing and positioning them on the page.\n4. Add or duplicate slides for repeating sections (one per item) so the deck length matches the data.\n5. Read the presentation back to confirm every placeholder was resolved.\n\n## Output\nReturn the presentationId and the shareable link. Note any placeholders that had no matching data so they can be reviewed.',
|
||||
},
|
||||
{
|
||||
name: 'build-metrics-slide',
|
||||
description:
|
||||
'Add a slide with a table and shapes that summarizes KPIs or metrics into a Google Slides deck.',
|
||||
content:
|
||||
'# Build Metrics Slide\n\nInsert a clean, data-driven metrics slide into an existing presentation.\n\n## Steps\n1. Add a new slide to the target presentation and capture the new slide objectId.\n2. Create a table on the slide sized to the number of metrics (rows) and columns needed.\n3. Insert text into each cell with the metric name, current value, and change vs prior period.\n4. Optionally create shape callouts for headline numbers and apply text and paragraph styles for emphasis.\n5. Get a thumbnail to verify layout and readability.\n\n## Output\nReturn the slide objectId and a thumbnail link. Summarize which metrics were added.',
|
||||
},
|
||||
{
|
||||
name: 'extract-deck-content',
|
||||
description:
|
||||
'Read a Google Slides presentation and extract all slide text into a structured outline.',
|
||||
content:
|
||||
'# Extract Deck Content\n\nPull the full text of a presentation into a structured outline for summarization or repurposing.\n\n## Steps\n1. Read the presentation by ID to get all slides and page elements.\n2. For each slide, collect title text, body text, table cell text, and speaker notes if present.\n3. Preserve slide order and group text under each slide number.\n4. Skip purely decorative elements with no text.\n\n## Output\nReturn a numbered outline (one section per slide) with the extracted text. Useful as input for a summary, recap email, or knowledge base entry.',
|
||||
},
|
||||
{
|
||||
name: 'rebrand-deck',
|
||||
description:
|
||||
'Roll out a brand or naming change across an entire deck by swapping text and logo images everywhere.',
|
||||
content:
|
||||
'# Rebrand Deck\n\nApply a consistent brand or naming change across every slide in one pass.\n\n## Steps\n1. Read the presentation by ID to confirm which terms and logo placeholders appear.\n2. For each old-to-new term (product name, tagline, company name), call replace all text so it updates across every slide at once.\n3. Replace the old logo by calling replace all shapes with image, or replace image on each logo element, with the new asset URL.\n4. Optionally update shape or page properties to match new brand colors.\n5. Read the presentation back to confirm no stale terms or logos remain.\n\n## Output\nReturn the presentationId and a list of the terms and images that were replaced, flagging any old references that still appear.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
export const GoogleSlidesV2BlockMeta = {
|
||||
|
||||
@@ -354,4 +354,26 @@ export const GoogleTasksBlockMeta = {
|
||||
alsoIntegrations: ['google_calendar'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'capture-action-items',
|
||||
description:
|
||||
'Turn a list of action items into Google Tasks with titles, notes, and due dates in the right task list.',
|
||||
content:
|
||||
'# Capture Action Items\n\nConvert extracted action items into well-formed Google Tasks.\n\n## Steps\n1. List the available task lists and pick the target list (default to the primary list if none specified).\n2. For each action item, create a task with a concise title, detailed notes for context, and a due date if one was given.\n3. Avoid duplicates by skipping items whose title already exists in the list.\n\n## Output\nReturn the created task IDs and titles, grouped by task list. Note any items skipped as duplicates.',
|
||||
},
|
||||
{
|
||||
name: 'list-due-and-overdue',
|
||||
description:
|
||||
'List open Google Tasks that are due soon or overdue across a task list for a daily review.',
|
||||
content:
|
||||
'# List Due and Overdue Tasks\n\nSurface tasks that need attention for a daily or weekly review.\n\n## Steps\n1. List the task lists, or use a specified list.\n2. List tasks in the list, including completed status and due dates.\n3. Filter to incomplete tasks and split into Overdue (due before today) and Due Soon (due within the next few days).\n4. Sort each group by due date ascending.\n\n## Output\nReturn two sections, Overdue and Due Soon, each with task title, due date, and task ID. Useful for posting a standup or reminder digest.',
|
||||
},
|
||||
{
|
||||
name: 'complete-task-by-title',
|
||||
description: 'Find a Google Task by its title and mark it completed.',
|
||||
content:
|
||||
'# Complete Task By Title\n\nMark a task done when given a title rather than an ID.\n\n## Steps\n1. List tasks in the relevant task list and match the requested title (case-insensitive, allow partial match).\n2. If multiple match, prefer the incomplete one; if still ambiguous, return the candidates and ask for clarification.\n3. Update the matched task to set its status to completed.\n4. Confirm the update by reading the task back.\n\n## Output\nReturn the completed task title and ID, or the list of ambiguous candidates if no single match was found.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -289,4 +289,26 @@ export const GoogleTranslateBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'translate-to-language',
|
||||
description:
|
||||
'Translate a block of text into a target language using Google Cloud Translation.',
|
||||
content:
|
||||
'# Translate To Language\n\nTranslate text into a specified target language.\n\n## Steps\n1. Take the source text and the target language code (e.g. es, fr, ja).\n2. If the source language is unknown, detect it first; otherwise pass it explicitly for accuracy.\n3. Call translate text with the target language and capture the translated output.\n4. For long content, split into paragraph-sized chunks and translate each to preserve formatting.\n\n## Output\nReturn the translated text along with the detected or supplied source language and the target language. Preserve line breaks from the original.',
|
||||
},
|
||||
{
|
||||
name: 'detect-and-route-language',
|
||||
description: 'Detect the language of incoming text and route or label it accordingly.',
|
||||
content:
|
||||
'# Detect and Route Language\n\nIdentify the language of a message so it can be routed, labeled, or translated.\n\n## Steps\n1. Call detect language on the input text and capture the language code and confidence.\n2. If confidence is low, fall back to detecting on a longer sample or flag as uncertain.\n3. Decide the route: if the detected language differs from the team language, translate it; otherwise pass through unchanged.\n\n## Output\nReturn the detected language code, confidence, and a recommended action (translate or pass-through). Include the translated text when translation was performed.',
|
||||
},
|
||||
{
|
||||
name: 'localize-message-set',
|
||||
description:
|
||||
'Translate one source message into several target languages for multilingual delivery.',
|
||||
content:
|
||||
'# Localize Message Set\n\nProduce localized versions of a single message for multiple audiences.\n\n## Steps\n1. Take the source text and the list of target language codes.\n2. For each target language, call translate text with the source language set explicitly for consistency.\n3. Keep placeholders, names, and URLs intact across all translations.\n\n## Output\nReturn a mapping of language code to translated text. Note any target language where translation appeared incomplete or unchanged.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -616,4 +616,27 @@ export const GoogleVaultBlockMeta = {
|
||||
tags: ['legal', 'enterprise'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'open-legal-hold',
|
||||
description:
|
||||
'Create a Vault matter and place a legal hold on custodians for an investigation or litigation.',
|
||||
content:
|
||||
'# Open Legal Hold\n\nStand up a Vault matter and preserve data for the relevant custodians.\n\n## Steps\n1. Create a matter with a clear name and description tied to the case or investigation.\n2. List existing matters first to avoid creating a duplicate for the same case.\n3. Create a hold on the matter for the named custodians and the relevant service (mail, Drive, etc.).\n4. List holds on the matter to confirm the custodians were preserved.\n\n## Output\nReturn the matterId, the holdId, and the list of custodians now under hold. Note any custodian that could not be added.',
|
||||
},
|
||||
{
|
||||
name: 'run-discovery-export',
|
||||
description:
|
||||
'Create a Vault export for a matter using a search query, then retrieve the export files.',
|
||||
content:
|
||||
'# Run Discovery Export\n\nProduce an export of matching data for eDiscovery or compliance review.\n\n## Steps\n1. Identify or create the matter for the export.\n2. Create an export with the search query, date range, and target accounts/org unit scoped as narrowly as possible.\n3. List exports on the matter and poll until the new export status is completed.\n4. Download the export files once the export is ready.\n\n## Output\nReturn the exportId, its status, and the downloaded file references. Summarize the query and scope used so the export is auditable.',
|
||||
},
|
||||
{
|
||||
name: 'audit-active-holds',
|
||||
description:
|
||||
'List Vault matters and their holds to produce a custodian preservation status report.',
|
||||
content:
|
||||
'# Audit Active Holds\n\nGenerate a status report of which matters and custodians are currently preserved.\n\n## Steps\n1. List all matters and capture their IDs, names, and states.\n2. For each open matter, list its holds and the custodians and services covered.\n3. Flag matters with no holds and custodians that appear across multiple matters.\n\n## Output\nReturn a per-matter summary listing holds, services, and custodians, plus a flagged section for matters missing holds. Suitable for a monthly legal review.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -987,4 +987,33 @@ export const GrafanaBlockMeta = {
|
||||
alsoIntegrations: ['linear', 'slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'annotate-deploy',
|
||||
description:
|
||||
'Create a Grafana annotation marking a deploy or incident so it shows on dashboards.',
|
||||
content:
|
||||
'# Annotate Deploy\n\nMark a deploy, release, or incident on Grafana dashboards for correlation.\n\n## Steps\n1. Build the annotation text (e.g. version, PR link, who triggered it) and tags for filtering.\n2. Create an annotation with the event time, or a time range for incidents with a start and end.\n3. Optionally scope the annotation to a specific dashboard so it appears only there.\n4. List annotations for the window to confirm it was recorded.\n\n## Output\nReturn the annotation ID, time, and tags. Useful for correlating metric changes with deploys later.',
|
||||
},
|
||||
{
|
||||
name: 'review-firing-alerts',
|
||||
description:
|
||||
'List Grafana alert rules and surface those currently firing with their contact points.',
|
||||
content:
|
||||
'# Review Firing Alerts\n\nProduce a snapshot of alerting health for an on-call handoff or incident triage.\n\n## Steps\n1. List alert rules and capture each rule name, condition, and current state.\n2. Get details on rules that are firing or in a pending state.\n3. List contact points so each firing rule can be mapped to who gets notified.\n4. Group findings by severity or folder.\n\n## Output\nReturn a list of firing and pending alerts with rule name, state, and notification target, plus a count of healthy rules. Suitable for an on-call digest.',
|
||||
},
|
||||
{
|
||||
name: 'audit-dashboards',
|
||||
description: 'List Grafana dashboards and folders and report data sources each depends on.',
|
||||
content:
|
||||
'# Audit Dashboards\n\nInventory dashboards and the data sources they rely on.\n\n## Steps\n1. List folders and dashboards to build the full inventory.\n2. Get details for each dashboard of interest to read its panels and referenced data sources.\n3. List data sources and cross-reference to flag dashboards pointing at missing or deprecated sources.\n\n## Output\nReturn an inventory grouped by folder, each dashboard with its UID and the data sources it uses, plus a flagged list of dashboards with broken or unknown data source references.',
|
||||
},
|
||||
{
|
||||
name: 'provision-monitoring-folder',
|
||||
description:
|
||||
'Create a Grafana folder and seed it with a starter dashboard for a new service or team.',
|
||||
content:
|
||||
'# Provision Monitoring Folder\n\nSet up an organized monitoring home for a new service or team.\n\n## Steps\n1. Create a folder with a descriptive title for the service or team.\n2. List data sources and pick the one the new dashboard should query.\n3. Create a dashboard inside the folder with starter panels for the key metrics.\n4. Get the dashboard back to confirm it was created in the right folder.\n\n## Output\nReturn the folder UID and the new dashboard UID and link. Note the data source the dashboard was wired to.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -534,4 +534,26 @@ export const GrainBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'summarize-recent-calls',
|
||||
description:
|
||||
'Pull recent Grain recordings and produce a digest of key takeaways and action items per call.',
|
||||
content:
|
||||
'# Summarize Recent Calls\n\nTurn recent meeting recordings into a readable digest.\n\n## Steps\n1. List recordings, optionally filtered by a before/after datetime window, and paginate with the cursor if needed.\n2. For each recording, get the recording details and the transcript.\n3. From each transcript, extract the main topic, key takeaways, decisions, and action items with owners.\n4. Keep the per-call summary concise and consistent in structure.\n\n## Output\nReturn a digest with one section per call: title, date, participants, takeaways, and action items. Suitable for a daily or weekly recap.',
|
||||
},
|
||||
{
|
||||
name: 'extract-deal-signals',
|
||||
description:
|
||||
'Scan Grain sales-call transcripts for buying signals, objections, and competitor mentions.',
|
||||
content:
|
||||
'# Extract Deal Signals\n\nMine sales transcripts for signals that move a deal forward.\n\n## Steps\n1. List recordings for the target time window, or filter by a view that holds sales calls.\n2. Get the transcript for each recording.\n3. Classify mentions into buying signals, objections/risks, competitor mentions, and next steps, capturing the verbatim quote and context.\n4. Apply a framework (e.g. MEDDIC or SPICED) if one is specified to tag each insight.\n\n## Output\nReturn a structured list of signals grouped by category, each with the quote, the call it came from, and a suggested follow-up. Useful for CRM notes or a deal review.',
|
||||
},
|
||||
{
|
||||
name: 'pull-transcript',
|
||||
description: 'Retrieve a specific Grain recording and its full transcript by ID.',
|
||||
content:
|
||||
'# Pull Transcript\n\nFetch a single recording and its transcript for downstream use.\n\n## Steps\n1. If only a title or date is known, list recordings and match to find the recording ID.\n2. Get the recording details for metadata (title, participants, duration, date).\n3. Get the transcript for the recording.\n4. Clean the transcript into readable speaker-labeled turns.\n\n## Output\nReturn the recording metadata plus the formatted transcript. This is the building block for summaries, follow-up emails, or knowledge base ingestion.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -249,4 +249,26 @@ export const GranolaBlockMeta = {
|
||||
tags: ['team', 'reporting'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'digest-meeting-notes',
|
||||
description:
|
||||
'List recent Granola notes and produce a structured digest of takeaways and action items.',
|
||||
content:
|
||||
'# Digest Meeting Notes\n\nTurn recent Granola meeting notes into a concise digest.\n\n## Steps\n1. List notes, optionally limited to a recent time window.\n2. For each note, get the full note content.\n3. Extract the meeting title, key decisions, takeaways, and action items with owners and due dates if present.\n4. Keep each meeting summary short and uniformly structured.\n\n## Output\nReturn a digest with one section per meeting: title, date, decisions, takeaways, and action items. Suitable for a team recap or daily summary.',
|
||||
},
|
||||
{
|
||||
name: 'extract-action-items',
|
||||
description: 'Read a Granola note and pull out a clean list of action items with owners.',
|
||||
content:
|
||||
'# Extract Action Items\n\nIsolate the follow-ups from a single meeting note.\n\n## Steps\n1. If only a title or date is known, list notes and match to find the note ID.\n2. Get the note content.\n3. Identify every action item, normalizing each into a clear task with an owner and due date when stated.\n4. Drop duplicates and merge near-identical items.\n\n## Output\nReturn a list of action items, each with the task, owner, and due date. Ready to push into a task manager or tracking table.',
|
||||
},
|
||||
{
|
||||
name: 'log-decisions',
|
||||
description:
|
||||
'Scan Granola notes for decisions made and compile them into a dated decision log.',
|
||||
content:
|
||||
'# Log Decisions\n\nBuild an auditable record of decisions captured in meetings.\n\n## Steps\n1. List notes across the target window.\n2. Get each note and identify explicit decisions, the rationale, and who made them.\n3. Normalize each into a row with date, decision, owner, and context.\n\n## Output\nReturn a chronological decision log, each entry with date, decision, owner, and supporting context. Useful for writing to a decision-tracking table.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -495,4 +495,26 @@ export const GreenhouseBlockMeta = {
|
||||
alsoIntegrations: ['gmail', 'slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'build-pipeline-report',
|
||||
description:
|
||||
'Summarize Greenhouse applications per job by stage to produce a hiring pipeline report.',
|
||||
content:
|
||||
'# Build Pipeline Report\n\nReport how candidates are progressing through each open job.\n\n## Steps\n1. List jobs and filter to open requisitions, capturing job IDs and titles.\n2. List job stages so application counts can be bucketed correctly.\n3. List applications, optionally filtered by status, and group them by job and current stage.\n4. Compute counts per stage and flag jobs with no recent movement.\n\n## Output\nReturn a per-job breakdown showing candidate counts by stage, total active candidates, and a flagged list of stalled requisitions. Suitable for a weekly recruiting standup.',
|
||||
},
|
||||
{
|
||||
name: 'assemble-candidate-brief',
|
||||
description:
|
||||
'Pull a Greenhouse candidate and their application details into a one-page interviewer brief.',
|
||||
content:
|
||||
'# Assemble Candidate Brief\n\nCompile everything an interviewer needs about a candidate.\n\n## Steps\n1. Find the candidate by listing candidates and matching name, or use a known candidate ID.\n2. Get the candidate to retrieve profile details and attachments.\n3. Get the application to read the job applied for, current stage, and source.\n4. Get the job for the role context and requirements.\n\n## Output\nReturn a one-page brief: candidate summary, role and current stage, key background points, and any notes. Ready to email or DM to the interviewer before the slot.',
|
||||
},
|
||||
{
|
||||
name: 'audit-open-roles',
|
||||
description: 'List open Greenhouse jobs with their departments, offices, and hiring teams.',
|
||||
content:
|
||||
'# Audit Open Roles\n\nInventory active requisitions and who owns them.\n\n## Steps\n1. List jobs and filter to open status.\n2. List departments and offices to resolve the names referenced on each job.\n3. List users to map hiring team members and recruiters to each role.\n4. Assemble each job with its department, office, and owning team.\n\n## Output\nReturn an inventory of open roles, each with title, department, office, and hiring team. Flag any role missing a recruiter or hiring manager.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -231,4 +231,27 @@ export const GreptileBlockMeta = {
|
||||
alsoIntegrations: ['github'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'answer-codebase-question',
|
||||
description:
|
||||
'Ask Greptile a natural-language question about an indexed repository and return a cited answer.',
|
||||
content:
|
||||
'# Answer Codebase Question\n\nGet an accurate, source-cited answer about how a codebase works.\n\n## Steps\n1. Confirm the repository is indexed by checking its index status; if not ready, index it first and wait.\n2. Query Greptile with the natural-language question (e.g. how authentication flows, where payments are processed).\n3. Capture the answer along with the file and function references it cites.\n4. If the answer is vague, refine the question with more specifics and re-query.\n\n## Output\nReturn the answer plus a list of cited files and symbols. Useful for onboarding, debugging, and understanding unfamiliar code.',
|
||||
},
|
||||
{
|
||||
name: 'review-pull-request',
|
||||
description:
|
||||
'Use Greptile to assess how a PR diff interacts with the rest of the repo and draft review notes.',
|
||||
content:
|
||||
'# Review Pull Request\n\nProduce a codebase-aware review of a set of changes.\n\n## Steps\n1. Ensure the repository is indexed (check status, index if needed).\n2. Query Greptile describing the changed files and ask how they interact with the rest of the codebase, what might break, and what edge cases to test.\n3. Collect the impact analysis and the cited files affected beyond the diff.\n4. Organize findings into bugs/risks, style/consistency, and suggested tests.\n\n## Output\nReturn structured review notes grouped by severity, each with the cited file and a concrete suggestion. Ready to post as a PR comment.',
|
||||
},
|
||||
{
|
||||
name: 'index-and-verify-repo',
|
||||
description:
|
||||
'Trigger Greptile indexing for a repository and poll until it is ready to query.',
|
||||
content:
|
||||
'# Index and Verify Repo\n\nMake a repository queryable in Greptile.\n\n## Steps\n1. Start indexing for the repository, specifying the remote, owner/repo, and branch.\n2. Poll the index status until it reports completed or fails.\n3. On failure, report the error and the branch/remote used so it can be corrected.\n4. On success, run a quick sanity query to confirm answers come back with citations.\n\n## Output\nReturn the final index status, the branch indexed, and the result of the sanity query. Confirms the repo is ready for codebase questions and reviews.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -520,4 +520,30 @@ export const HexBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'run-project-with-params',
|
||||
description: 'Trigger a Hex project run with input parameters and poll until it completes.',
|
||||
content:
|
||||
'# Run Project With Params\n\nKick off a Hex project and wait for the result.\n\n## Steps\n1. If only a project name is known, list projects to resolve the project ID.\n2. Run the project, passing any input parameters the project expects.\n3. Capture the run ID and poll the run status until it reaches a terminal state (completed, errored, or killed).\n4. If it is still pending after a reasonable timeout, report the current status rather than blocking indefinitely.\n\n## Output\nReturn the run ID, final status, and any output or result link. On error, include the failure reason.',
|
||||
},
|
||||
{
|
||||
name: 'monitor-recent-runs',
|
||||
description: 'List recent Hex project runs, check their statuses, and surface failures.',
|
||||
content:
|
||||
'# Monitor Recent Runs\n\nWatch project runs and flag the ones that failed.\n\n## Steps\n1. List project runs for the relevant project or projects.\n2. Get the run status for each recent run.\n3. Filter to runs that errored or were killed and capture the error detail.\n4. Group successes and failures with timestamps.\n\n## Output\nReturn a summary of recent runs with status and timing, plus a flagged failures section with run IDs, error messages, and links. Suitable for an hourly monitoring digest.',
|
||||
},
|
||||
{
|
||||
name: 'cancel-stuck-run',
|
||||
description: 'Find a long-running or stuck Hex run and cancel it.',
|
||||
content:
|
||||
'# Cancel Stuck Run\n\nStop a run that is hung or no longer needed.\n\n## Steps\n1. List project runs and get the status of in-progress runs.\n2. Identify runs exceeding an expected duration or explicitly targeted for cancellation.\n3. Cancel the run by its run ID.\n4. Re-check the status to confirm cancellation took effect.\n\n## Output\nReturn the cancelled run ID and its confirmed final status. Note any run that could not be cancelled.',
|
||||
},
|
||||
{
|
||||
name: 'inventory-projects',
|
||||
description: 'List Hex projects, collections, and data connections to map analytics assets.',
|
||||
content:
|
||||
'# Inventory Projects\n\nMap what projects and data sources exist in the workspace.\n\n## Steps\n1. List projects and capture IDs, names, and owners.\n2. List collections and get details to see how projects are grouped.\n3. List data connections to map which sources power the projects.\n4. Cross-reference projects to their collections and data connections.\n\n## Output\nReturn an inventory of projects grouped by collection, each annotated with its data connections. Useful for governance and cleanup.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -1331,4 +1331,38 @@ export const HubSpotBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'upsert-contact',
|
||||
description:
|
||||
'Find a HubSpot contact by email and update it, or create it if it does not exist.',
|
||||
content:
|
||||
'# Upsert Contact\n\nKeep a contact record current without creating duplicates.\n\n## Steps\n1. Search contacts by the email address to check if the person already exists.\n2. If a match is found, update the contact with the new property values.\n3. If no match exists, create a new contact with the email and known properties.\n4. Read the contact back to confirm the final property values.\n\n## Output\nReturn the contact ID and whether it was created or updated, along with the properties that were set.',
|
||||
},
|
||||
{
|
||||
name: 'create-deal-for-account',
|
||||
description: 'Create a HubSpot deal and associate it with the right company and contact.',
|
||||
content:
|
||||
'# Create Deal For Account\n\nLog a new opportunity tied to the correct account.\n\n## Steps\n1. Search companies to resolve the company by name or domain; create it if missing.\n2. Search contacts to find the primary contact for the deal.\n3. Create the deal with name, amount, pipeline, and stage, associating it with the company and contact.\n4. Read the deal back to confirm associations and stage.\n\n## Output\nReturn the deal ID, its stage and amount, and the associated company and contact IDs.',
|
||||
},
|
||||
{
|
||||
name: 'triage-support-ticket',
|
||||
description:
|
||||
'Classify a HubSpot ticket, set priority, and associate it with the correct company.',
|
||||
content:
|
||||
'# Triage Support Ticket\n\nRoute and prioritize an incoming support ticket.\n\n## Steps\n1. Get the ticket to read its subject and content.\n2. Classify topic and priority from the content.\n3. Update the ticket with the priority and any pipeline stage change.\n4. Search companies to find the requesting account and associate the ticket with it.\n\n## Output\nReturn the ticket ID, assigned priority and topic, and the associated company. Flag high-priority tickets for escalation.',
|
||||
},
|
||||
{
|
||||
name: 'summarize-open-deals',
|
||||
description: 'Search HubSpot deals by stage and produce a pipeline summary with totals.',
|
||||
content:
|
||||
'# Summarize Open Deals\n\nReport on the active sales pipeline.\n\n## Steps\n1. Search deals filtered to open stages, paginating through all results.\n2. Group deals by pipeline stage and capture amount and close date.\n3. Sum amounts per stage and overall, and flag deals with a close date in the past.\n4. Identify the largest deals and any missing key properties.\n\n## Output\nReturn a per-stage breakdown with deal counts and total value, a grand total, and a flagged list of overdue or incomplete deals. Suitable for a sales pipeline review.',
|
||||
},
|
||||
{
|
||||
name: 'build-quote-from-deal',
|
||||
description: 'Gather a HubSpot deal and its line items to assemble a quote summary.',
|
||||
content:
|
||||
'# Build Quote From Deal\n\nCompile the commercial details needed to quote a deal.\n\n## Steps\n1. Get the deal by ID for its name, amount, and stage.\n2. List line items and get details to capture product, quantity, and price for each.\n3. Get the associated quote if one exists, or summarize the line items into a draft quote.\n4. Total the line items and compare against the deal amount, flagging mismatches.\n\n## Output\nReturn the deal summary, an itemized line-item list with totals, and any existing quote reference. Flag discrepancies between the line-item total and the deal amount.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -190,4 +190,26 @@ export const HuggingFaceBlockMeta = {
|
||||
tags: ['llm', 'engineering', 'analysis'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'run-chat-completion',
|
||||
description:
|
||||
'Send a prompt to a Hugging Face chat model via the Inference API and return the response.',
|
||||
content:
|
||||
'# Run Chat Completion\n\nGenerate a completion from an open chat model.\n\n## Steps\n1. Choose the model (e.g. an instruct or chat-tuned model available via the Inference API).\n2. Build the messages with a clear system instruction and the user prompt.\n3. Call chat with the model and messages, setting temperature and max tokens appropriate to the task.\n4. Capture the assistant response and any token usage returned.\n\n## Output\nReturn the model output and the model name used. Note token usage when available for cost tracking.',
|
||||
},
|
||||
{
|
||||
name: 'extract-structured-data',
|
||||
description:
|
||||
'Use a Hugging Face chat model to extract fields from unstructured text into a structured object.',
|
||||
content:
|
||||
'# Extract Structured Data\n\nPull named fields out of free text using an open model.\n\n## Steps\n1. Define the exact fields to extract and their types.\n2. Build a system message instructing the model to return only valid JSON matching the schema, with nulls for missing fields.\n3. Call chat with the source text as the user message and a low temperature for determinism.\n4. Parse the response and validate it against the expected fields; retry once with a stricter instruction if parsing fails.\n\n## Output\nReturn the parsed structured object. On repeated parse failure, return the raw model text and an error note.',
|
||||
},
|
||||
{
|
||||
name: 'compare-model-outputs',
|
||||
description: 'Run the same prompt through two Hugging Face models and compare their outputs.',
|
||||
content:
|
||||
'# Compare Model Outputs\n\nEvaluate how two open models handle the same task.\n\n## Steps\n1. Define the shared prompt and the two model identifiers to compare.\n2. Call chat once per model with identical messages and generation settings.\n3. Capture each output along with latency and token usage.\n4. Score the outputs against the task criteria (accuracy, format, completeness).\n\n## Output\nReturn both responses side by side with their latency, token usage, and a brief quality comparison. Suitable for logging to an evaluation table.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -480,4 +480,26 @@ export const HunterBlockMeta = {
|
||||
alsoIntegrations: ['apollo'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'find-decision-maker-emails',
|
||||
description:
|
||||
'Find verified email addresses for key roles at a target company using domain search.',
|
||||
content:
|
||||
'# Find Decision-Maker Emails\n\nGiven a company domain, find verified professional email addresses for the people who matter.\n\n## Steps\n1. Run a domain search for the target domain (e.g. example.com).\n2. Filter results by department or seniority (executive, sales, IT) to surface decision-makers.\n3. For each candidate, capture the full name, role, email, and confidence score.\n4. Drop any result below your confidence threshold (e.g. < 80).\n\n## Output\nReturn a list of contacts with name, title, email, and confidence score, sorted by seniority. Note the total emails available on the domain so the user knows coverage.',
|
||||
},
|
||||
{
|
||||
name: 'verify-email-list',
|
||||
description:
|
||||
'Verify a batch of email addresses and flag undeliverable or risky ones before sending.',
|
||||
content:
|
||||
'# Verify Email List\n\nClean a list of email addresses so a campaign only sends to deliverable inboxes.\n\n## Steps\n1. For each address, run the email verifier.\n2. Record the verification status (valid, invalid, accept-all, disposable, webmail) and the deliverability score.\n3. Bucket addresses into deliverable, risky, and undeliverable.\n\n## Output\nReturn the three buckets with counts, and a recommended clean list containing only deliverable addresses.',
|
||||
},
|
||||
{
|
||||
name: 'find-person-email',
|
||||
description: 'Find the most likely email address for a named person at a specific company.',
|
||||
content:
|
||||
'# Find a Person Email\n\nGiven a first name, last name, and company domain, find that person email address.\n\n## Steps\n1. Run the email finder with the full name and domain.\n2. Capture the returned email, confidence score, and the sources Hunter used.\n3. If confidence is low, optionally run a domain search to confirm the pattern.\n\n## Output\nReturn the email, confidence score, and supporting sources. State clearly when no confident match was found.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
@@ -738,4 +738,34 @@ export const IAMBlockMeta = {
|
||||
alsoIntegrations: ['slack'],
|
||||
},
|
||||
],
|
||||
skills: [
|
||||
{
|
||||
name: 'audit-iam-permissions',
|
||||
description:
|
||||
'List IAM users, roles, and their attached policies to produce an access audit. Use for security reviews and least-privilege checks.',
|
||||
content:
|
||||
'# Audit IAM Permissions\n\nReport who and what has access in IAM.\n\n## Steps\n1. List users and roles to establish the inventory.\n2. For each principal of interest, list attached user or role policies.\n3. Optionally simulate principal policy to confirm whether a principal can perform sensitive actions.\n4. Flag overly broad policies, unused principals, or access keys that should be rotated.\n\n## Output\nAn audit summary: principals and their attached policies, with risky or excessive grants called out. Do not expose secret values.',
|
||||
},
|
||||
{
|
||||
name: 'check-effective-permissions',
|
||||
description:
|
||||
'Use IAM policy simulation to verify whether a user or role can perform specific actions on resources. Use for troubleshooting access and validating changes.',
|
||||
content:
|
||||
'# Check Effective Permissions\n\nDetermine whether a principal is actually allowed to do something.\n\n## Steps\n1. Identify the principal (user or role) and the actions and resource ARNs to test.\n2. Run simulate principal policy for those actions against the resources.\n3. Read the allowed or denied decision for each action, noting which statement governs it.\n4. If denied unexpectedly, inspect the attached policies to explain why.\n\n## Output\nA per-action allow/deny verdict with the governing policy, and a plain-language explanation of any denial.',
|
||||
},
|
||||
{
|
||||
name: 'provision-iam-principal',
|
||||
description:
|
||||
'Create an IAM user or role, attach managed policies, and place users into groups to grant scoped access. Use for onboarding and standing up service roles.',
|
||||
content:
|
||||
'# Provision IAM Principal\n\nStand up a new IAM user or role with the right permissions.\n\n## Steps\n1. Decide whether to create a user (for a person or app) or a role (for a service or cross-account access).\n2. For a user, create the user, then add them to the relevant groups or attach the needed managed policy ARNs. For a role, create the role with a trust policy that names the allowed principal, then attach the policy ARNs.\n3. Prefer attaching existing managed policies over broad wildcards; grant only the actions required.\n4. Confirm the result by listing the attached user or role policies.\n\n## Output\nReport the created principal name and ARN and the policies now attached. Do not print any generated secret values.',
|
||||
},
|
||||
{
|
||||
name: 'rotate-access-keys',
|
||||
description:
|
||||
'Create a fresh IAM access key for a user and delete the old one to complete a safe rotation. Use for scheduled key rotation and remediating aged keys.',
|
||||
content:
|
||||
'# Rotate Access Keys\n\nReplace a user’s access key following the two-step rotation pattern.\n\n## Steps\n1. Create a new access key for the target user so two keys exist briefly.\n2. Hand the new key to its consumer securely and let dependents switch over and verify they still work.\n3. Once the new key is confirmed in use, delete the old access key by its ID.\n4. Confirm only the intended key remains for the user.\n\n## Output\nReport the user, that a new key was issued, and the old key ID that was deleted. Never print the secret access key value — reference keys only by their access key ID.',
|
||||
},
|
||||
],
|
||||
} as const satisfies BlockMeta
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user