mirror of
https://github.com/simstudioai/sim.git
synced 2026-10-25 09:34:44 +08:00
feat(tools): added sentry, incidentio, and posthog tools (#2116)
* feat(tools): added sentry, incidentio, and posthog tools * update docs * fixed docs to use native fumadocs for llms.txt and copy markdown, fixed tool issues * cleanup * enhance error extractor, fixed posthog tools * docs enhancements, cleanup * added more incident io ops, remove zustand/shallow in favor of zustand/react/shallow * fix type errors * remove unnecessary comments * added vllm to docs
This commit is contained in:
@@ -201,13 +201,7 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
|
||||
<div className='relative mt-6 sm:mt-0'>
|
||||
<div className='absolute top-1 right-0 flex items-center gap-2'>
|
||||
<div className='hidden sm:flex'>
|
||||
<CopyPageButton
|
||||
content={`# ${page.data.title}
|
||||
|
||||
${page.data.description || ''}
|
||||
|
||||
${page.data.content || ''}`}
|
||||
/>
|
||||
<CopyPageButton markdownUrl={`${page.url}.mdx`} />
|
||||
</div>
|
||||
<PageNavigationArrows previous={neighbours?.previous} next={neighbours?.next} />
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,11 @@ export async function GET(_req: NextRequest, { params }: { params: Promise<{ slu
|
||||
const page = source.getPage(slug)
|
||||
if (!page) notFound()
|
||||
|
||||
return new NextResponse(await getLLMText(page))
|
||||
return new NextResponse(await getLLMText(page), {
|
||||
headers: {
|
||||
'Content-Type': 'text/markdown',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function generateStaticParams() {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"aliases": {
|
||||
"uiDir": "./components/ui",
|
||||
"componentsDir": "./components",
|
||||
"blockDir": "./components",
|
||||
"cssDir": "./styles",
|
||||
"libDir": "./lib"
|
||||
},
|
||||
"baseDir": "",
|
||||
"commands": {}
|
||||
}
|
||||
@@ -4150,3 +4150,96 @@ export function VideoIcon(props: SVGProps<SVGSVGElement>) {
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function VllmIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg {...props} fill='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
|
||||
<title>vLLM</title>
|
||||
<path d='M0 4.973h9.324V23L0 4.973z' fill='#FDB515' />
|
||||
<path d='M13.986 4.351L22.378 0l-6.216 23H9.324l4.662-18.649z' fill='#30A2FF' />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function PosthogIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
width='50'
|
||||
height='30'
|
||||
viewBox='0 0 50 30'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
d='M10.8914 17.2057c-.3685.7371-1.42031.7371-1.78884 0L8.2212 15.443c-.14077-.2815-.14077-.6129 0-.8944l.88136-1.7627c.36853-.7371 1.42034-.7371 1.78884 0l.8814 1.7627c.1407.2815.1407.6129 0 .8944l-.8814 1.7627zM10.8914 27.2028c-.3685.737-1.42031.737-1.78884 0L8.2212 25.44c-.14077-.2815-.14077-.6129 0-.8944l.88136-1.7627c.36853-.7371 1.42034-.7371 1.78884 0l.8814 1.7627c.1407.2815.1407.6129 0 .8944l-.8814 1.7628z'
|
||||
fill='#1D4AFF'
|
||||
/>
|
||||
<path
|
||||
d='M0 23.4082c0-.8909 1.07714-1.3371 1.70711-.7071l4.58338 4.5834c.62997.63.1838 1.7071-.7071 1.7071H.999999c-.552284 0-.999999-.4477-.999999-1v-4.5834zm0-4.8278c0 .2652.105357.5196.292893.7071l9.411217 9.4112c.18753.1875.44189.2929.70709.2929h5.1692c.8909 0 1.3371-1.0771.7071-1.7071L1.70711 12.7041C1.07714 12.0741 0 12.5203 0 13.4112v5.1692zm0-9.99701c0 .26521.105357.51957.292893.7071L19.7011 28.6987c.1875.1875.4419.2929.7071.2929h5.1692c.8909 0 1.3371-1.0771.7071-1.7071L1.70711 2.70711C1.07715 2.07715 0 2.52331 0 3.41421v5.16918zm9.997 0c0 .26521.1054.51957.2929.7071l17.994 17.99401c.63.63 1.7071.1838 1.7071-.7071v-5.1692c0-.2652-.1054-.5196-.2929-.7071l-17.994-17.994c-.63-.62996-1.7071-.18379-1.7071.70711v5.16918zm11.7041-5.87628c-.63-.62997-1.7071-.1838-1.7071.7071v5.16918c0 .26521.1054.51957.2929.7071l7.997 7.99701c.63.63 1.7071.1838 1.7071-.7071v-5.1692c0-.2652-.1054-.5196-.2929-.7071l-7.997-7.99699z'
|
||||
fill='#F9BD2B'
|
||||
/>
|
||||
<path
|
||||
d='M42.5248 23.5308l-9.4127-9.4127c-.63-.63-1.7071-.1838-1.7071.7071v13.1664c0 .5523.4477 1 1 1h14.5806c.5523 0 1-.4477 1-1v-1.199c0-.5523-.4496-.9934-.9973-1.0647-1.6807-.2188-3.2528-.9864-4.4635-2.1971zm-6.3213 2.2618c-.8829 0-1.5995-.7166-1.5995-1.5996 0-.8829.7166-1.5995 1.5995-1.5995.883 0 1.5996.7166 1.5996 1.5995 0 .883-.7166 1.5996-1.5996 1.5996z'
|
||||
fill='#000'
|
||||
/>
|
||||
<path
|
||||
d='M0 27.9916c0 .5523.447715 1 1 1h4.58339c.8909 0 1.33707-1.0771.70711-1.7071l-4.58339-4.5834C1.07714 22.0711 0 22.5173 0 23.4082v4.5834zM9.997 10.997L1.70711 2.70711C1.07714 2.07714 0 2.52331 0 3.41421v5.16918c0 .26521.105357.51957.292893.7071L9.997 18.9946V10.997zM1.70711 12.7041C1.07714 12.0741 0 12.5203 0 13.4112v5.1692c0 .2652.105357.5196.292893.7071L9.997 28.9916V20.994l-8.28989-8.2899z'
|
||||
fill='#1D4AFF'
|
||||
/>
|
||||
<path
|
||||
d='M19.994 11.4112c0-.2652-.1053-.5196-.2929-.7071l-7.997-7.99699c-.6299-.62997-1.70709-.1838-1.70709.7071v5.16918c0 .26521.10539.51957.29289.7071l9.7041 9.70411v-7.5834zM9.99701 28.9916h5.58339c.8909 0 1.3371-1.0771.7071-1.7071L9.99701 20.994v7.9976zM9.99701 10.997v7.5834c0 .2652.10539.5196.29289.7071l9.7041 9.7041v-7.5834c0-.2652-.1053-.5196-.2929-.7071L9.99701 10.997z'
|
||||
fill='#F54E00'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function SentryIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
width='800px'
|
||||
height='800px'
|
||||
viewBox='0 -14.5 256 256'
|
||||
version='1.1'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
preserveAspectRatio='xMidYMid'
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d='M148.367708,12.4025287 C144.036807,5.21480737 136.258026,0.820118864 127.866362,0.820118864 C119.474697,0.820118864 111.695916,5.21480737 107.365016,12.4025287 L73.6403017,70.165071 C126.066153,96.3390588 160.689085,148.341727 164.615024,206.806542 L140.93597,206.806542 C137.017513,156.694333 106.874845,112.396698 61.6982677,90.3588968 L30.4849684,144.32869 C55.8497707,155.704426 73.6778379,179.211206 77.7918243,206.704035 L23.4120041,206.704035 C22.1018479,206.611361 20.9266153,205.864669 20.2861278,204.71799 C19.6456403,203.571311 19.6261529,202.179068 20.2342955,201.014912 L35.3027847,175.388229 C30.1976229,171.128798 24.3630321,167.829476 18.0816541,165.65009 L3.16692493,191.276772 C0.0305635285,196.656417 -0.818661742,203.068719 0.809210488,209.079324 C2.43708272,215.08993 6.40620885,220.197261 11.8287436,223.258872 C15.3657216,225.251729 19.3523095,226.310116 23.4120041,226.334074 L97.8831433,226.334074 C100.696274,191.620878 85.1423372,157.966047 56.8804514,137.614499 L68.7199787,117.113153 C104.398813,141.618242 124.473737,183.151896 121.510945,226.334074 L184.603837,226.334074 C187.593899,160.904124 155.557278,98.8221906 100.497065,63.3483734 L124.432386,22.3456815 C125.542508,20.4856859 127.944329,19.8680747 129.81399,20.9618406 C132.530418,22.4481882 233.807067,199.169791 235.703442,201.219925 C236.383476,202.439289 236.358897,203.929352 235.639016,205.125624 C234.919136,206.321896 233.614065,207.041397 232.218213,207.011555 L207.821611,207.011555 C208.129131,213.537817 208.129131,220.046994 207.821611,226.539592 L232.32072,226.539592 C238.604421,226.580218 244.643414,224.105731 249.091568,219.667205 C253.539722,215.228679 256.027289,209.195062 256,202.911286 C256.002825,198.802186 254.905596,194.767215 252.822066,191.225519 L148.367708,12.4025287 Z'
|
||||
fill='#362D59'
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function IncidentioIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
width='128'
|
||||
height='163'
|
||||
viewBox='0 0 128 163'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<g clipPath='url(#clip0_1361_12561)'>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M48.7336 139.642V163C20.7585 156.323 0 131.711 0 102.372C0 85.4557 7.15792 72.0354 18.1053 58.8703C27.1831 47.9534 49.5985 19.0426 56.6543 3.08954C58.3673 -0.783473 62.7348 -0.633805 64.6182 1.44721C70.6432 8.10421 78.0694 22.6432 80.4983 39.135C80.9932 42.4953 81.1969 45.2388 81.3587 47.4184C81.706 52.0954 81.8604 54.1748 84.2854 54.1748C88.0955 54.1748 90.588 48.3977 91.1358 42.4345C91.4869 38.6136 95.2774 37.3346 97.8914 38.6136C110.463 44.7644 123.292 74.0426 126.393 88.4102C127.366 92.9158 128 97.5719 128 102.372C128 131.646 107.335 156.214 79.4537 162.955V139.642H48.7336ZM64.0002 130.333C73.8316 130.333 81.8016 122.789 81.8016 113.483C81.8016 98.6407 70.8577 88.0345 65.4048 84.8105C65.0364 84.5928 64.8523 84.4839 64.3512 84.4974C63.9843 84.5073 63.4429 84.7369 63.181 84.9935C62.8232 85.3441 62.7283 85.743 62.5387 86.5409C61.5721 90.6065 58.5292 93.5054 55.327 96.556C50.9141 100.76 46.1988 105.252 46.1988 113.483C46.1988 122.789 54.1688 130.333 64.0002 130.333Z'
|
||||
fill='#F25533'
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id='clip0_1361_12561'>
|
||||
<rect width='128' height='163' fill='white' />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { cva, type VariantProps } from 'class-variance-authority'
|
||||
|
||||
const variants = {
|
||||
primary: 'bg-fd-primary text-fd-primary-foreground hover:bg-fd-primary/80',
|
||||
outline: 'border hover:bg-fd-accent hover:text-fd-accent-foreground',
|
||||
ghost: 'hover:bg-fd-accent hover:text-fd-accent-foreground',
|
||||
secondary:
|
||||
'border bg-fd-secondary text-fd-secondary-foreground hover:bg-fd-accent hover:text-fd-accent-foreground',
|
||||
} as const
|
||||
|
||||
export const buttonVariants = cva(
|
||||
'inline-flex items-center justify-center rounded-md p-2 text-sm font-medium transition-colors duration-100 disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-ring',
|
||||
{
|
||||
variants: {
|
||||
variant: variants,
|
||||
color: variants,
|
||||
size: {
|
||||
sm: 'gap-1 px-2 py-1.5 text-xs',
|
||||
icon: 'p-1.5 [&_svg]:size-5',
|
||||
'icon-sm': 'p-1.5 [&_svg]:size-4.5',
|
||||
'icon-xs': 'p-1 [&_svg]:size-4',
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
export type ButtonProps = VariantProps<typeof buttonVariants>
|
||||
@@ -3,25 +3,48 @@
|
||||
import { useState } from 'react'
|
||||
import { Check, Copy } from 'lucide-react'
|
||||
|
||||
const cache = new Map<string, string>()
|
||||
|
||||
interface CopyPageButtonProps {
|
||||
content: string
|
||||
markdownUrl: string
|
||||
}
|
||||
|
||||
export function CopyPageButton({ content }: CopyPageButtonProps) {
|
||||
export function CopyPageButton({ markdownUrl }: CopyPageButtonProps) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
const [isLoading, setLoading] = useState(false)
|
||||
|
||||
const handleCopy = async () => {
|
||||
const cached = cache.get(markdownUrl)
|
||||
if (cached) {
|
||||
await navigator.clipboard.writeText(cached)
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
return
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
try {
|
||||
await navigator.clipboard.writeText(content)
|
||||
await navigator.clipboard.write([
|
||||
new ClipboardItem({
|
||||
'text/plain': fetch(markdownUrl).then(async (res) => {
|
||||
const content = await res.text()
|
||||
cache.set(markdownUrl, content)
|
||||
return content
|
||||
}),
|
||||
}),
|
||||
])
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
} catch (err) {
|
||||
console.error('Failed to copy:', err)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
disabled={isLoading}
|
||||
onClick={handleCopy}
|
||||
className='flex cursor-pointer items-center gap-1.5 rounded-lg border border-border/40 bg-background px-2.5 py-2 text-muted-foreground/60 text-sm leading-none transition-all hover:border-border hover:bg-accent/50 hover:text-muted-foreground'
|
||||
aria-label={copied ? 'Copied to clipboard' : 'Copy page content'}
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
HuggingFaceIcon,
|
||||
HunterIOIcon,
|
||||
ImageIcon,
|
||||
IncidentioIcon,
|
||||
JinaAIIcon,
|
||||
JiraIcon,
|
||||
LinearIcon,
|
||||
@@ -55,11 +56,13 @@ import {
|
||||
PineconeIcon,
|
||||
PipedriveIcon,
|
||||
PostgresIcon,
|
||||
PosthogIcon,
|
||||
QdrantIcon,
|
||||
RedditIcon,
|
||||
ResendIcon,
|
||||
S3Icon,
|
||||
SalesforceIcon,
|
||||
SentryIcon,
|
||||
SerperIcon,
|
||||
SlackIcon,
|
||||
STTIcon,
|
||||
@@ -112,11 +115,13 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
|
||||
slack: SlackIcon,
|
||||
sharepoint: MicrosoftSharepointIcon,
|
||||
serper: SerperIcon,
|
||||
sentry: SentryIcon,
|
||||
salesforce: SalesforceIcon,
|
||||
s3: S3Icon,
|
||||
resend: ResendIcon,
|
||||
reddit: RedditIcon,
|
||||
qdrant: QdrantIcon,
|
||||
posthog: PosthogIcon,
|
||||
postgresql: PostgresIcon,
|
||||
pipedrive: PipedriveIcon,
|
||||
pinecone: PineconeIcon,
|
||||
@@ -140,6 +145,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
|
||||
knowledge: PackageSearchIcon,
|
||||
jira: JiraIcon,
|
||||
jina: JinaAIIcon,
|
||||
incidentio: IncidentioIcon,
|
||||
image_generator: ImageIcon,
|
||||
hunter: HunterIOIcon,
|
||||
huggingface: HuggingFaceIcon,
|
||||
|
||||
@@ -46,7 +46,7 @@ The Agent block supports multiple LLM providers through a unified inference inte
|
||||
- **Anthropic**: Claude 4.5 Sonnet, Claude Opus 4.1
|
||||
- **Google**: Gemini 2.5 Pro, Gemini 2.0 Flash
|
||||
- **Other Providers**: Groq, Cerebras, xAI, Azure OpenAI, OpenRouter
|
||||
- **Local Models**: Ollama-compatible models
|
||||
- **Local Models**: Ollama or VLLM compatible models
|
||||
|
||||
### Temperature
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ Choose an AI model to perform the evaluation:
|
||||
- **Anthropic**: Claude 3.7 Sonnet
|
||||
- **Google**: Gemini 2.5 Pro, Gemini 2.0 Flash
|
||||
- **Other Providers**: Groq, Cerebras, xAI, DeepSeek
|
||||
- **Local Models**: Ollama-compatible models
|
||||
- **Local Models**: Ollama or VLLM compatible models
|
||||
|
||||
Use models with strong reasoning capabilities like GPT-4o or Claude 3.7 Sonnet for best results.
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ Uses Retrieval-Augmented Generation (RAG) with LLM scoring to detect when AI-gen
|
||||
**Configuration:**
|
||||
- **Knowledge Base**: Select from your existing knowledge bases
|
||||
- **Model**: Choose LLM for scoring (requires strong reasoning - GPT-4o, Claude 3.7 Sonnet recommended)
|
||||
- **API Key**: Authentication for selected LLM provider (auto-hidden for hosted/Ollama models)
|
||||
- **API Key**: Authentication for selected LLM provider (auto-hidden for hosted/Ollama or VLLM compatible models)
|
||||
- **Confidence Threshold**: Minimum score to pass (0-10, default: 3)
|
||||
- **Top K** (Advanced): Number of knowledge base chunks to retrieve (default: 10)
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ Choose an AI model to power the routing decision:
|
||||
- **Anthropic**: Claude 3.7 Sonnet
|
||||
- **Google**: Gemini 2.5 Pro, Gemini 2.0 Flash
|
||||
- **Other Providers**: Groq, Cerebras, xAI, DeepSeek
|
||||
- **Local Models**: Ollama-compatible models
|
||||
- **Local Models**: Ollama or VLLM compatible models
|
||||
|
||||
Use models with strong reasoning capabilities like GPT-4o or Claude 3.7 Sonnet for best results.
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ The model breakdown shows:
|
||||
| Groq | Llama 4 Scout | $0.40 / $0.60 |
|
||||
| Cerebras | Llama 3.3 70B | $0.94 / $0.94 |
|
||||
| Ollama | Local models | Free |
|
||||
| VLLM | Local models | Free |
|
||||
|
||||
*Pay providers directly with no markup*
|
||||
</Tab>
|
||||
@@ -86,7 +87,7 @@ The model breakdown shows:
|
||||
|
||||
- **Model Selection**: Choose models based on task complexity. Simple tasks can use GPT-4.1-nano while complex reasoning might need o1 or Claude Opus.
|
||||
- **Prompt Engineering**: Well-structured, concise prompts reduce token usage without sacrificing quality.
|
||||
- **Local Models**: Use Ollama for non-critical tasks to eliminate API costs entirely.
|
||||
- **Local Models**: Use Ollama or VLLM for non-critical tasks to eliminate API costs entirely.
|
||||
- **Caching and Reuse**: Store frequently used results in variables or files to avoid repeated AI model calls.
|
||||
- **Batch Processing**: Process multiple items in a single AI request rather than making individual calls.
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ Enable your team to build together. Multiple users can edit workflows simultaneo
|
||||
|
||||
Sim provides native integrations with 80+ services across multiple categories:
|
||||
|
||||
- **AI Models**: OpenAI, Anthropic, Google Gemini, Groq, Cerebras, local models via Ollama
|
||||
- **AI Models**: OpenAI, Anthropic, Google Gemini, Groq, Cerebras, local models via Ollama or VLLM
|
||||
- **Communication**: Gmail, Slack, Microsoft Teams, Telegram, WhatsApp
|
||||
- **Productivity**: Notion, Google Workspace, Airtable, Monday.com
|
||||
- **Development**: GitHub, Jira, Linear, automated browser testing
|
||||
|
||||
@@ -0,0 +1,846 @@
|
||||
---
|
||||
title: incidentio
|
||||
description: Manage incidents with incident.io
|
||||
---
|
||||
|
||||
import { BlockInfoCard } from "@/components/ui/block-info-card"
|
||||
|
||||
<BlockInfoCard
|
||||
type="incidentio"
|
||||
color="#E0E0E0"
|
||||
/>
|
||||
|
||||
{/* MANUAL-CONTENT-START:intro */}
|
||||
Supercharge your incident management with [incident.io](https://incident.io) – the leading platform for orchestrating incidents, streamlining response processes, and tracking action items all in one place. Seamlessly integrate incident.io into your automated workflows to take command of incident creation, real-time collaboration, follow-ups, scheduling, escalations, and much more.
|
||||
|
||||
With the incident.io tool, you can:
|
||||
|
||||
- **List and search incidents**: Quickly retrieve a list of ongoing or historical incidents, complete with metadata such as severity, status, and timestamps, using `incidentio_incidents_list`.
|
||||
- **Create new incidents**: Trigger new incident creation programmatically via `incidentio_incidents_create`, specifying severity, name, type, and custom details to ensure nothing slows your response down.
|
||||
- **Automate incident follow-ups**: Leverage incident.io’s powerful automation to ensure important action items and learnings aren't missed, helping teams resolve issues and improve processes.
|
||||
- **Customize workflows**: Integrate bespoke incident types, severities, and custom fields tailored to your organization’s needs.
|
||||
- **Enforce best practices with schedules & escalations**: Streamline on-call and incident management by automatically assigning, notifying, and escalating as situations evolve.
|
||||
|
||||
incident.io empowers modern organizations to respond faster, coordinate teams, and capture learnings for continuous improvement. Whether you manage SRE, DevOps, Security, or IT incidents, incident.io brings centralized, best-in-class incident response programmatically to your agent workflows.
|
||||
|
||||
**Key operations available**:
|
||||
- `incidentio_incidents_list`: List, paginate and filter incidents with full detail.
|
||||
- `incidentio_incidents_create`: Programmatically open new incidents with custom attributes and control over duplication (idempotency).
|
||||
- ...and more to come!
|
||||
|
||||
Enhance your reliability, accountability, and operational excellence by integrating incident.io with your workflow automations today.
|
||||
{/* MANUAL-CONTENT-END */}
|
||||
|
||||
|
||||
## Usage Instructions
|
||||
|
||||
Integrate incident.io into the workflow. Manage incidents, actions, follow-ups, workflows, schedules, escalations, custom fields, and more.
|
||||
|
||||
|
||||
|
||||
## Tools
|
||||
|
||||
### `incidentio_incidents_list`
|
||||
|
||||
List incidents from incident.io. Returns a list of incidents with their details including severity, status, and timestamps.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `page_size` | number | No | Number of incidents to return per page \(default: 25\) |
|
||||
| `after` | string | No | Pagination cursor to fetch the next page of results |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incidents` | array | List of incidents |
|
||||
|
||||
### `incidentio_incidents_create`
|
||||
|
||||
Create a new incident in incident.io. Requires idempotency_key, severity_id, and visibility. Optionally accepts name, summary, type, and status.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `idempotency_key` | string | Yes | Unique identifier to prevent duplicate incident creation. Use a UUID or unique string. |
|
||||
| `name` | string | No | Name of the incident \(optional\) |
|
||||
| `summary` | string | No | Brief summary of the incident |
|
||||
| `severity_id` | string | Yes | ID of the severity level \(required\) |
|
||||
| `incident_type_id` | string | No | ID of the incident type |
|
||||
| `incident_status_id` | string | No | ID of the initial incident status |
|
||||
| `visibility` | string | Yes | Visibility of the incident: "public" or "private" \(required\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident` | object | The created incident object |
|
||||
|
||||
### `incidentio_incidents_show`
|
||||
|
||||
Retrieve detailed information about a specific incident from incident.io by its ID. Returns full incident details including custom fields and role assignments.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | ID of the incident to retrieve |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident` | object | Detailed incident information |
|
||||
|
||||
### `incidentio_incidents_update`
|
||||
|
||||
Update an existing incident in incident.io. Can update name, summary, severity, status, or type.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | ID of the incident to update |
|
||||
| `name` | string | No | Updated name of the incident |
|
||||
| `summary` | string | No | Updated summary of the incident |
|
||||
| `severity_id` | string | No | Updated severity ID for the incident |
|
||||
| `incident_status_id` | string | No | Updated status ID for the incident |
|
||||
| `incident_type_id` | string | No | Updated incident type ID |
|
||||
| `notify_incident_channel` | boolean | Yes | Whether to notify the incident channel about this update |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident` | object | The updated incident object |
|
||||
|
||||
### `incidentio_actions_list`
|
||||
|
||||
List actions from incident.io. Optionally filter by incident ID.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `incident_id` | string | No | Filter actions by incident ID |
|
||||
| `page_size` | number | No | Number of actions to return per page |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `actions` | array | List of actions |
|
||||
|
||||
### `incidentio_actions_show`
|
||||
|
||||
Get detailed information about a specific action from incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | Action ID |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `action` | object | Action details |
|
||||
|
||||
### `incidentio_follow_ups_list`
|
||||
|
||||
List follow-ups from incident.io. Optionally filter by incident ID.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `incident_id` | string | No | Filter follow-ups by incident ID |
|
||||
| `page_size` | number | No | Number of follow-ups to return per page |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `follow_ups` | array | List of follow-ups |
|
||||
|
||||
### `incidentio_follow_ups_show`
|
||||
|
||||
Get detailed information about a specific follow-up from incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | Follow-up ID |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `follow_up` | object | Follow-up details |
|
||||
|
||||
### `incidentio_users_list`
|
||||
|
||||
List all users in your Incident.io workspace. Returns user details including id, name, email, and role.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Incident.io API Key |
|
||||
| `page_size` | number | No | Number of results to return per page \(default: 25\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `users` | array | List of users in the workspace |
|
||||
|
||||
### `incidentio_users_show`
|
||||
|
||||
Get detailed information about a specific user in your Incident.io workspace by their ID.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Incident.io API Key |
|
||||
| `id` | string | Yes | The unique identifier of the user to retrieve |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `user` | object | Details of the requested user |
|
||||
|
||||
### `incidentio_workflows_list`
|
||||
|
||||
List all workflows in your incident.io workspace.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `page_size` | number | No | Number of workflows to return per page |
|
||||
| `after` | string | No | Pagination cursor to fetch the next page of results |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `workflows` | array | List of workflows |
|
||||
|
||||
### `incidentio_workflows_show`
|
||||
|
||||
Get details of a specific workflow in incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the workflow to retrieve |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `workflow` | object | The workflow details |
|
||||
|
||||
### `incidentio_workflows_update`
|
||||
|
||||
Update an existing workflow in incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the workflow to update |
|
||||
| `name` | string | No | New name for the workflow |
|
||||
| `state` | string | No | New state for the workflow \(active, draft, or disabled\) |
|
||||
| `folder` | string | No | New folder for the workflow |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `workflow` | object | The updated workflow |
|
||||
|
||||
### `incidentio_workflows_delete`
|
||||
|
||||
Delete a workflow in incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the workflow to delete |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `message` | string | Success message |
|
||||
|
||||
### `incidentio_schedules_list`
|
||||
|
||||
List all schedules in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `page_size` | number | No | Number of results per page \(default: 25\) |
|
||||
| `after` | string | No | Pagination cursor to fetch the next page of results |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `schedules` | array | List of schedules |
|
||||
|
||||
### `incidentio_schedules_create`
|
||||
|
||||
Create a new schedule in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `name` | string | Yes | Name of the schedule |
|
||||
| `timezone` | string | Yes | Timezone for the schedule \(e.g., America/New_York\) |
|
||||
| `config` | string | Yes | Schedule configuration as JSON string with rotations. Example: \{"rotations": \[\{"name": "Primary", "users": \[\{"id": "user_id"\}\], "handover_start_at": "2024-01-01T09:00:00Z", "handovers": \[\{"interval": 1, "interval_type": "weekly"\}\]\}\]\} |
|
||||
| `Example` | string | No | No description |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `schedule` | object | The created schedule |
|
||||
|
||||
### `incidentio_schedules_show`
|
||||
|
||||
Get details of a specific schedule in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the schedule |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `schedule` | object | The schedule details |
|
||||
|
||||
### `incidentio_schedules_update`
|
||||
|
||||
Update an existing schedule in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the schedule to update |
|
||||
| `name` | string | No | New name for the schedule |
|
||||
| `timezone` | string | No | New timezone for the schedule \(e.g., America/New_York\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `schedule` | object | The updated schedule |
|
||||
|
||||
### `incidentio_schedules_delete`
|
||||
|
||||
Delete a schedule in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the schedule to delete |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `message` | string | Success message |
|
||||
|
||||
### `incidentio_escalations_list`
|
||||
|
||||
List all escalation policies in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `page_size` | number | No | Number of results per page \(default: 25\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `escalations` | array | List of escalation policies |
|
||||
|
||||
### `incidentio_escalations_create`
|
||||
|
||||
Create a new escalation policy in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `idempotency_key` | string | Yes | Unique identifier to prevent duplicate escalation creation. Use a UUID or unique string. |
|
||||
| `title` | string | Yes | Title of the escalation |
|
||||
| `escalation_path_id` | string | No | ID of the escalation path to use \(required if user_ids not provided\) |
|
||||
| `user_ids` | string | No | Comma-separated list of user IDs to notify \(required if escalation_path_id not provided\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `escalation` | object | The created escalation policy |
|
||||
|
||||
### `incidentio_escalations_show`
|
||||
|
||||
Get details of a specific escalation policy in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the escalation policy |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `escalation` | object | The escalation policy details |
|
||||
|
||||
### `incidentio_custom_fields_list`
|
||||
|
||||
List all custom fields from incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `custom_fields` | array | List of custom fields |
|
||||
|
||||
### `incidentio_custom_fields_create`
|
||||
|
||||
Create a new custom field in incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `name` | string | Yes | Name of the custom field |
|
||||
| `description` | string | Yes | Description of the custom field \(required\) |
|
||||
| `field_type` | string | Yes | Type of the custom field \(e.g., text, single_select, multi_select, numeric, datetime, link, user, team\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `custom_field` | object | Created custom field |
|
||||
|
||||
### `incidentio_custom_fields_show`
|
||||
|
||||
Get detailed information about a specific custom field from incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | Custom field ID |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `custom_field` | object | Custom field details |
|
||||
|
||||
### `incidentio_custom_fields_update`
|
||||
|
||||
Update an existing custom field in incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | Custom field ID |
|
||||
| `name` | string | Yes | New name for the custom field \(required\) |
|
||||
| `description` | string | Yes | New description for the custom field \(required\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `custom_field` | object | Updated custom field |
|
||||
|
||||
### `incidentio_custom_fields_delete`
|
||||
|
||||
Delete a custom field from incident.io.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | Custom field ID |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `message` | string | Success message |
|
||||
|
||||
### `incidentio_severities_list`
|
||||
|
||||
List all severity levels configured in your Incident.io workspace. Returns severity details including id, name, description, and rank.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Incident.io API Key |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `severities` | array | List of severity levels |
|
||||
|
||||
### `incidentio_incident_statuses_list`
|
||||
|
||||
List all incident statuses configured in your Incident.io workspace. Returns status details including id, name, description, and category.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Incident.io API Key |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident_statuses` | array | List of incident statuses |
|
||||
|
||||
### `incidentio_incident_types_list`
|
||||
|
||||
List all incident types configured in your Incident.io workspace. Returns type details including id, name, description, and default flag.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Incident.io API Key |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident_types` | array | List of incident types |
|
||||
|
||||
### `incidentio_incident_roles_list`
|
||||
|
||||
List all incident roles in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident_roles` | array | List of incident roles |
|
||||
|
||||
### `incidentio_incident_roles_create`
|
||||
|
||||
Create a new incident role in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `name` | string | Yes | Name of the incident role |
|
||||
| `description` | string | Yes | Description of the incident role |
|
||||
| `instructions` | string | Yes | Instructions for the incident role |
|
||||
| `shortform` | string | Yes | Short form abbreviation for the role |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident_role` | object | The created incident role |
|
||||
|
||||
### `incidentio_incident_roles_show`
|
||||
|
||||
Get details of a specific incident role in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the incident role |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident_role` | object | The incident role details |
|
||||
|
||||
### `incidentio_incident_roles_update`
|
||||
|
||||
Update an existing incident role in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the incident role to update |
|
||||
| `name` | string | Yes | Name of the incident role |
|
||||
| `description` | string | Yes | Description of the incident role |
|
||||
| `instructions` | string | Yes | Instructions for the incident role |
|
||||
| `shortform` | string | Yes | Short form abbreviation for the role |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident_role` | object | The updated incident role |
|
||||
|
||||
### `incidentio_incident_roles_delete`
|
||||
|
||||
Delete an incident role in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the incident role to delete |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `message` | string | Success message |
|
||||
|
||||
### `incidentio_incident_timestamps_list`
|
||||
|
||||
List all incident timestamp definitions in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident_timestamps` | array | List of incident timestamp definitions |
|
||||
|
||||
### `incidentio_incident_timestamps_show`
|
||||
|
||||
Get details of a specific incident timestamp definition in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the incident timestamp |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident_timestamp` | object | The incident timestamp details |
|
||||
|
||||
### `incidentio_incident_updates_list`
|
||||
|
||||
List all updates for a specific incident in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `incident_id` | string | No | The ID of the incident to get updates for \(optional - if not provided, returns all updates\) |
|
||||
| `page_size` | number | No | Number of results to return per page |
|
||||
| `after` | string | No | Cursor for pagination |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `incident_updates` | array | List of incident updates |
|
||||
|
||||
### `incidentio_schedule_entries_list`
|
||||
|
||||
List all entries for a specific schedule in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `schedule_id` | string | Yes | The ID of the schedule to get entries for |
|
||||
| `entry_window_start` | string | No | Start date/time to filter entries \(ISO 8601 format\) |
|
||||
| `entry_window_end` | string | No | End date/time to filter entries \(ISO 8601 format\) |
|
||||
| `page_size` | number | No | Number of results to return per page |
|
||||
| `after` | string | No | Cursor for pagination |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `schedule_entries` | array | List of schedule entries |
|
||||
|
||||
### `incidentio_schedule_overrides_create`
|
||||
|
||||
Create a new schedule override in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `rotation_id` | string | Yes | The ID of the rotation to override |
|
||||
| `schedule_id` | string | Yes | The ID of the schedule |
|
||||
| `user_id` | string | No | The ID of the user to assign \(provide one of: user_id, user_email, or user_slack_id\) |
|
||||
| `user_email` | string | No | The email of the user to assign \(provide one of: user_id, user_email, or user_slack_id\) |
|
||||
| `user_slack_id` | string | No | The Slack ID of the user to assign \(provide one of: user_id, user_email, or user_slack_id\) |
|
||||
| `start_at` | string | Yes | When the override starts \(ISO 8601 format\) |
|
||||
| `end_at` | string | Yes | When the override ends \(ISO 8601 format\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `override` | object | The created schedule override |
|
||||
|
||||
### `incidentio_escalation_paths_create`
|
||||
|
||||
Create a new escalation path in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `name` | string | Yes | Name of the escalation path |
|
||||
| `path` | json | Yes | Array of escalation levels with targets and time to acknowledge in seconds. Each level should have: targets \(array of \{id, type, schedule_id?, user_id?, urgency\}\) and time_to_ack_seconds \(number\) |
|
||||
| `working_hours` | json | No | Optional working hours configuration. Array of \{weekday, start_time, end_time\} |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `escalation_path` | object | The created escalation path |
|
||||
|
||||
### `incidentio_escalation_paths_show`
|
||||
|
||||
Get details of a specific escalation path in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the escalation path |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `escalation_path` | object | The escalation path details |
|
||||
|
||||
### `incidentio_escalation_paths_update`
|
||||
|
||||
Update an existing escalation path in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the escalation path to update |
|
||||
| `name` | string | No | New name for the escalation path |
|
||||
| `path` | json | No | New escalation path configuration. Array of escalation levels with targets and time_to_ack_seconds |
|
||||
| `working_hours` | json | No | New working hours configuration. Array of \{weekday, start_time, end_time\} |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `escalation_path` | object | The updated escalation path |
|
||||
|
||||
### `incidentio_escalation_paths_delete`
|
||||
|
||||
Delete an escalation path in incident.io
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | incident.io API Key |
|
||||
| `id` | string | Yes | The ID of the escalation path to delete |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `message` | string | Success message |
|
||||
|
||||
|
||||
|
||||
## Notes
|
||||
|
||||
- Category: `tools`
|
||||
- Type: `incidentio`
|
||||
@@ -47,6 +47,10 @@ Search for similar content in a knowledge base using vector similarity
|
||||
| `query` | string | No | Search query text \(optional when using tag filters\) |
|
||||
| `topK` | number | No | Number of most similar results to return \(1-100\) |
|
||||
| `tagFilters` | array | No | Array of tag filters with tagName and tagValue properties |
|
||||
| `items` | object | No | No description |
|
||||
| `properties` | string | No | No description |
|
||||
| `tagName` | string | No | No description |
|
||||
| `tagValue` | string | No | No description |
|
||||
|
||||
#### Output
|
||||
|
||||
@@ -91,6 +95,11 @@ Create a new document in a knowledge base
|
||||
| `tag6` | string | No | Tag 6 value for the document |
|
||||
| `tag7` | string | No | Tag 7 value for the document |
|
||||
| `documentTagsData` | array | No | Structured tag data with names, types, and values |
|
||||
| `items` | object | No | No description |
|
||||
| `properties` | string | No | No description |
|
||||
| `tagName` | string | No | No description |
|
||||
| `tagValue` | string | No | No description |
|
||||
| `tagType` | string | No | No description |
|
||||
|
||||
#### Output
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
"huggingface",
|
||||
"hunter",
|
||||
"image_generator",
|
||||
"incidentio",
|
||||
"jina",
|
||||
"jira",
|
||||
"knowledge",
|
||||
@@ -50,11 +51,13 @@
|
||||
"pinecone",
|
||||
"pipedrive",
|
||||
"postgresql",
|
||||
"posthog",
|
||||
"qdrant",
|
||||
"reddit",
|
||||
"resend",
|
||||
"s3",
|
||||
"salesforce",
|
||||
"sentry",
|
||||
"serper",
|
||||
"sharepoint",
|
||||
"slack",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,310 @@
|
||||
---
|
||||
title: Sentry
|
||||
description: Manage Sentry issues, projects, events, and releases
|
||||
---
|
||||
|
||||
import { BlockInfoCard } from "@/components/ui/block-info-card"
|
||||
|
||||
<BlockInfoCard
|
||||
type="sentry"
|
||||
color="#E0E0E0"
|
||||
/>
|
||||
|
||||
{/* MANUAL-CONTENT-START:intro */}
|
||||
Supercharge your error monitoring and application reliability with [Sentry](https://sentry.io/) — the industry-leading platform for real-time error tracking, performance monitoring, and release management. Seamlessly integrate Sentry into your automated agent workflows to easily monitor issues, track critical events, manage projects, and orchestrate releases across all your applications and services.
|
||||
|
||||
With the Sentry tool, you can:
|
||||
|
||||
- **Monitor and triage issues**: Fetch comprehensive lists of issues using the `sentry_issues_list` operation and retrieve detailed information on individual errors and bugs via `sentry_issues_get`. Instantly access metadata, tags, stack traces, and statistics to reduce mean time to resolution.
|
||||
- **Track event data**: Analyze specific error and event instances with `sentry_events_list` and `sentry_events_get`, providing deep insight into error occurrences and user impact.
|
||||
- **Manage projects and teams**: Use `sentry_projects_list` and `sentry_project_get` to enumerate and review all your Sentry projects, ensuring smooth team collaboration and centralized configuration.
|
||||
- **Coordinate releases**: Automate version tracking, deployment health, and change management across your codebase with operations like `sentry_releases_list`, `sentry_release_get`, and more.
|
||||
- **Gain powerful application insights**: Leverage advanced filters and queries to find unresolved or high-priority issues, aggregate event statistics over time, and track regressions as your codebase evolves.
|
||||
|
||||
Sentry's integration empowers engineering and DevOps teams to detect issues early, prioritize the most impactful bugs, and continuously improve application health across development stacks. Programmatically orchestrate workflow automation for modern observability, incident response, and release lifecycle management—reducing downtime and increasing user satisfaction.
|
||||
|
||||
**Key Sentry operations available**:
|
||||
- `sentry_issues_list`: List Sentry issues for organizations and projects, with powerful search and filtering.
|
||||
- `sentry_issues_get`: Retrieve detailed information for a specific Sentry issue.
|
||||
- `sentry_events_list`: Enumerate the events for a particular issue for root-cause analysis.
|
||||
- `sentry_events_get`: Get full detail on an individual event, including stack traces, context, and metadata.
|
||||
- `sentry_projects_list`: List all Sentry projects within your organization.
|
||||
- `sentry_project_get`: Retrieve configuration and details for a specific project.
|
||||
- `sentry_releases_list`: List recent releases and their deployment status.
|
||||
- `sentry_release_get`: Retrieve detailed release information, including associated commits and issues.
|
||||
|
||||
Whether you're proactively managing app health, troubleshooting production errors, or automating release workflows, Sentry equips you with world-class monitoring, actionable alerts, and seamless DevOps integration. Boost your software quality and search visibility by leveraging Sentry for error tracking, observability, and release management—all from your agentic workflows.
|
||||
{/* MANUAL-CONTENT-END */}
|
||||
|
||||
|
||||
## Usage Instructions
|
||||
|
||||
Integrate Sentry into the workflow. Monitor issues, manage projects, track events, and coordinate releases across your applications.
|
||||
|
||||
|
||||
|
||||
## Tools
|
||||
|
||||
### `sentry_issues_list`
|
||||
|
||||
List issues from Sentry for a specific organization and optionally a specific project. Returns issue details including status, error counts, and last seen timestamps.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `projectSlug` | string | No | Filter issues by specific project slug \(optional\) |
|
||||
| `query` | string | No | Search query to filter issues. Supports Sentry search syntax \(e.g., "is:unresolved", "level:error"\) |
|
||||
| `statsPeriod` | string | No | Time period for stats \(e.g., "24h", "7d", "30d"\). Defaults to 24h if not specified. |
|
||||
| `cursor` | string | No | Pagination cursor for retrieving next page of results |
|
||||
| `limit` | number | No | Number of issues to return per page \(default: 25, max: 100\) |
|
||||
| `status` | string | No | Filter by issue status: unresolved, resolved, ignored, or muted |
|
||||
| `sort` | string | No | Sort order: date, new, freq, priority, or user \(default: date\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `issues` | array | List of Sentry issues |
|
||||
|
||||
### `sentry_issues_get`
|
||||
|
||||
Retrieve detailed information about a specific Sentry issue by its ID. Returns complete issue details including metadata, tags, and statistics.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `issueId` | string | Yes | The unique ID of the issue to retrieve |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `issue` | object | Detailed information about the Sentry issue |
|
||||
|
||||
### `sentry_issues_update`
|
||||
|
||||
Update a Sentry issue by changing its status, assignment, bookmark state, or other properties. Returns the updated issue details.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `issueId` | string | Yes | The unique ID of the issue to update |
|
||||
| `status` | string | No | New status for the issue: resolved, unresolved, ignored, or resolvedInNextRelease |
|
||||
| `assignedTo` | string | No | User ID or email to assign the issue to. Use empty string to unassign. |
|
||||
| `isBookmarked` | boolean | No | Whether to bookmark the issue |
|
||||
| `isSubscribed` | boolean | No | Whether to subscribe to issue updates |
|
||||
| `isPublic` | boolean | No | Whether the issue should be publicly visible |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `issue` | object | The updated Sentry issue |
|
||||
|
||||
### `sentry_projects_list`
|
||||
|
||||
List all projects in a Sentry organization. Returns project details including name, platform, teams, and configuration.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `cursor` | string | No | Pagination cursor for retrieving next page of results |
|
||||
| `limit` | number | No | Number of projects to return per page \(default: 25, max: 100\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `projects` | array | List of Sentry projects |
|
||||
|
||||
### `sentry_projects_get`
|
||||
|
||||
Retrieve detailed information about a specific Sentry project by its slug. Returns complete project details including teams, features, and configuration.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `projectSlug` | string | Yes | The ID or slug of the project to retrieve |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `project` | object | Detailed information about the Sentry project |
|
||||
|
||||
### `sentry_projects_create`
|
||||
|
||||
Create a new Sentry project in an organization. Requires a team to associate the project with. Returns the created project details.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `name` | string | Yes | The name of the project |
|
||||
| `teamSlug` | string | Yes | The slug of the team that will own this project |
|
||||
| `slug` | string | No | URL-friendly project identifier \(auto-generated from name if not provided\) |
|
||||
| `platform` | string | No | Platform/language for the project \(e.g., javascript, python, node, react-native\). If not specified, defaults to "other" |
|
||||
| `defaultRules` | boolean | No | Whether to create default alert rules \(default: true\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `project` | object | The newly created Sentry project |
|
||||
|
||||
### `sentry_projects_update`
|
||||
|
||||
Update a Sentry project by changing its name, slug, platform, or other settings. Returns the updated project details.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `projectSlug` | string | Yes | The slug of the project to update |
|
||||
| `name` | string | No | New name for the project |
|
||||
| `slug` | string | No | New URL-friendly project identifier |
|
||||
| `platform` | string | No | New platform/language for the project \(e.g., javascript, python, node\) |
|
||||
| `isBookmarked` | boolean | No | Whether to bookmark the project |
|
||||
| `digestsMinDelay` | number | No | Minimum delay \(in seconds\) for digest notifications |
|
||||
| `digestsMaxDelay` | number | No | Maximum delay \(in seconds\) for digest notifications |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `project` | object | The updated Sentry project |
|
||||
|
||||
### `sentry_events_list`
|
||||
|
||||
List events from a Sentry project. Can be filtered by issue ID, query, or time period. Returns event details including context, tags, and user information.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `projectSlug` | string | Yes | The slug of the project to list events from |
|
||||
| `issueId` | string | No | Filter events by a specific issue ID |
|
||||
| `query` | string | No | Search query to filter events. Supports Sentry search syntax \(e.g., "user.email:*@example.com"\) |
|
||||
| `cursor` | string | No | Pagination cursor for retrieving next page of results |
|
||||
| `limit` | number | No | Number of events to return per page \(default: 50, max: 100\) |
|
||||
| `statsPeriod` | string | No | Time period to query \(e.g., "24h", "7d", "30d"\). Defaults to 90d if not specified. |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `events` | array | List of Sentry events |
|
||||
|
||||
### `sentry_events_get`
|
||||
|
||||
Retrieve detailed information about a specific Sentry event by its ID. Returns complete event details including stack traces, breadcrumbs, context, and user information.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `projectSlug` | string | Yes | The slug of the project |
|
||||
| `eventId` | string | Yes | The unique ID of the event to retrieve |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `event` | object | Detailed information about the Sentry event |
|
||||
|
||||
### `sentry_releases_list`
|
||||
|
||||
List releases for a Sentry organization or project. Returns release details including version, commits, deploy information, and associated projects.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `projectSlug` | string | No | Filter releases by specific project slug \(optional\) |
|
||||
| `query` | string | No | Search query to filter releases \(e.g., version name pattern\) |
|
||||
| `cursor` | string | No | Pagination cursor for retrieving next page of results |
|
||||
| `limit` | number | No | Number of releases to return per page \(default: 25, max: 100\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `releases` | array | List of Sentry releases |
|
||||
|
||||
### `sentry_releases_create`
|
||||
|
||||
Create a new release in Sentry. A release is a version of your code deployed to an environment. Can include commit information and associated projects. Returns the created release details.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `version` | string | Yes | Version identifier for the release \(e.g., "2.0.0", "my-app@1.0.0", or a git commit SHA\) |
|
||||
| `projects` | string | Yes | Comma-separated list of project slugs to associate with this release |
|
||||
| `ref` | string | No | Git reference \(commit SHA, tag, or branch\) for this release |
|
||||
| `url` | string | No | URL pointing to the release \(e.g., GitHub release page\) |
|
||||
| `dateReleased` | string | No | ISO 8601 timestamp for when the release was deployed \(defaults to current time\) |
|
||||
| `commits` | string | No | JSON array of commit objects with id, repository \(optional\), and message \(optional\). Example: \[\{"id":"abc123","message":"Fix bug"\}\] |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `release` | object | The newly created Sentry release |
|
||||
|
||||
### `sentry_releases_deploy`
|
||||
|
||||
Create a deploy record for a Sentry release in a specific environment. Deploys track when and where releases are deployed. Returns the created deploy details.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Sentry API authentication token |
|
||||
| `organizationSlug` | string | Yes | The slug of the organization |
|
||||
| `version` | string | Yes | Version identifier of the release being deployed |
|
||||
| `environment` | string | Yes | Environment name where the release is being deployed \(e.g., "production", "staging"\) |
|
||||
| `name` | string | No | Optional name for this deploy \(e.g., "Deploy v2.0 to Production"\) |
|
||||
| `url` | string | No | URL pointing to the deploy \(e.g., CI/CD pipeline URL\) |
|
||||
| `dateStarted` | string | No | ISO 8601 timestamp for when the deploy started \(defaults to current time\) |
|
||||
| `dateFinished` | string | No | ISO 8601 timestamp for when the deploy finished |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `deploy` | object | The newly created deploy record |
|
||||
|
||||
|
||||
|
||||
## Notes
|
||||
|
||||
- Category: `tools`
|
||||
- Type: `sentry`
|
||||
@@ -0,0 +1 @@
|
||||
export { twMerge as cn } from 'tailwind-merge'
|
||||
+2
-30
@@ -1,38 +1,10 @@
|
||||
import type { InferPageType } from 'fumadocs-core/source'
|
||||
import { remarkInclude } from 'fumadocs-mdx/config'
|
||||
import { remark } from 'remark'
|
||||
import remarkGfm from 'remark-gfm'
|
||||
import remarkMdx from 'remark-mdx'
|
||||
import type { source } from '@/lib/source'
|
||||
|
||||
const processor = remark().use(remarkMdx).use(remarkInclude).use(remarkGfm)
|
||||
|
||||
export async function getLLMText(page: InferPageType<typeof source>) {
|
||||
// Skip pages without proper file data
|
||||
if (!page?.data?._file?.absolutePath || !page?.data?.content) {
|
||||
return `# ${page.data.title || 'Untitled'}
|
||||
URL: ${page.url || 'Unknown'}
|
||||
|
||||
${page.data.description || 'No description available'}`
|
||||
}
|
||||
|
||||
try {
|
||||
const processed = await processor.process({
|
||||
path: page.data._file.absolutePath,
|
||||
value: page.data.content,
|
||||
})
|
||||
|
||||
return `# ${page.data.title || 'Untitled'}
|
||||
URL: ${page.url || 'Unknown'}
|
||||
return `# ${page.data.title} (${page.url})
|
||||
|
||||
${page.data.description || ''}
|
||||
|
||||
${processed.value}`
|
||||
} catch (error) {
|
||||
console.error(`Error processing page ${page.url}:`, error)
|
||||
return `# ${page.data.title || 'Untitled'}
|
||||
URL: ${page.url || 'Unknown'}
|
||||
|
||||
${page.data.description || 'No description available'}`
|
||||
}
|
||||
${page.data.content || ''}`
|
||||
}
|
||||
|
||||
+19
-2
@@ -1,8 +1,25 @@
|
||||
import { createI18nMiddleware } from 'fumadocs-core/i18n/middleware'
|
||||
import { isMarkdownPreferred, rewritePath } from 'fumadocs-core/negotiation'
|
||||
import { type NextFetchEvent, type NextRequest, NextResponse } from 'next/server'
|
||||
import { i18n } from '@/lib/i18n'
|
||||
|
||||
export default createI18nMiddleware(i18n)
|
||||
const { rewrite: rewriteLLM } = rewritePath('/docs/*path', '/llms.mdx/*path')
|
||||
const i18nMiddleware = createI18nMiddleware(i18n)
|
||||
|
||||
export default function middleware(request: NextRequest, event: NextFetchEvent) {
|
||||
if (isMarkdownPreferred(request)) {
|
||||
const result = rewriteLLM(request.nextUrl.pathname)
|
||||
|
||||
if (result) {
|
||||
return NextResponse.rewrite(new URL(result, request.nextUrl))
|
||||
}
|
||||
}
|
||||
|
||||
return i18nMiddleware(request, event)
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ['/((?!api|_next/static|_next/image|favicon|static|robots.txt|sitemap.xml|llms.txt).*)'],
|
||||
matcher: [
|
||||
'/((?!api|_next/static|_next/image|favicon|static|robots.txt|sitemap.xml|llms.txt|llms-full.txt).*)',
|
||||
],
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { shallow } from 'zustand/shallow'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { createLogger } from '@/lib/logs/console/logger'
|
||||
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
|
||||
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
|
||||
@@ -112,8 +112,7 @@ export function useMentionData(props: UseMentionDataProps) {
|
||||
|
||||
// Only subscribe to block keys to avoid re-rendering on position updates
|
||||
const blockKeys = useWorkflowStore(
|
||||
useCallback((state) => Object.keys(state.blocks), []),
|
||||
shallow
|
||||
useShallow(useCallback((state) => Object.keys(state.blocks), []))
|
||||
)
|
||||
|
||||
// Use workflow registry as source of truth for workflows
|
||||
|
||||
+3
-4
@@ -3,7 +3,7 @@
|
||||
import { useCallback, useRef, useState } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import { ChevronDown, RepeatIcon, SplitIcon } from 'lucide-react'
|
||||
import { shallow } from 'zustand/shallow'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { createLogger } from '@/lib/logs/console/logger'
|
||||
import {
|
||||
FieldItem,
|
||||
@@ -190,10 +190,9 @@ export function ConnectionBlocks({ connections, currentBlockId }: ConnectionBloc
|
||||
const connectionRefs = useRef<Map<string, HTMLDivElement>>(new Map())
|
||||
|
||||
const { blocks } = useWorkflowStore(
|
||||
(state) => ({
|
||||
useShallow((state) => ({
|
||||
blocks: state.blocks,
|
||||
}),
|
||||
shallow
|
||||
}))
|
||||
)
|
||||
|
||||
const workflowId = useWorkflowRegistry((state) => state.activeWorkflowId)
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { shallow } from 'zustand/shallow'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import {
|
||||
Popover,
|
||||
PopoverAnchor,
|
||||
@@ -426,13 +426,12 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
|
||||
const itemRefs = useRef<Map<number, HTMLElement>>(new Map())
|
||||
|
||||
const { blocks, edges, loops, parallels } = useWorkflowStore(
|
||||
(state) => ({
|
||||
useShallow((state) => ({
|
||||
blocks: state.blocks,
|
||||
edges: state.edges,
|
||||
loops: state.loops || {},
|
||||
parallels: state.parallels || {},
|
||||
}),
|
||||
shallow
|
||||
}))
|
||||
)
|
||||
|
||||
const workflowId = useWorkflowRegistry((state) => state.activeWorkflowId)
|
||||
|
||||
+3
-4
@@ -1,4 +1,4 @@
|
||||
import { shallow } from 'zustand/shallow'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { BlockPathCalculator } from '@/lib/block-path-calculator'
|
||||
import { extractFieldsFromSchema, parseResponseFormatSafely } from '@/lib/response-format'
|
||||
import { getBlockOutputs } from '@/lib/workflows/block-outputs'
|
||||
@@ -33,11 +33,10 @@ export interface ConnectedBlock {
|
||||
|
||||
export function useBlockConnections(blockId: string) {
|
||||
const { edges, blocks } = useWorkflowStore(
|
||||
(state) => ({
|
||||
useShallow((state) => ({
|
||||
edges: state.edges,
|
||||
blocks: state.blocks,
|
||||
}),
|
||||
shallow
|
||||
}))
|
||||
)
|
||||
|
||||
const workflowId = useWorkflowRegistry((state) => state.activeWorkflowId)
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
import { useMemo } from 'react'
|
||||
import { shallow } from 'zustand/shallow'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { BlockPathCalculator } from '@/lib/block-path-calculator'
|
||||
import { SYSTEM_REFERENCE_PREFIXES } from '@/lib/workflows/references'
|
||||
import { normalizeBlockName } from '@/stores/workflows/utils'
|
||||
@@ -8,13 +8,12 @@ import type { Loop, Parallel } from '@/stores/workflows/workflow/types'
|
||||
|
||||
export function useAccessibleReferencePrefixes(blockId?: string | null): Set<string> | undefined {
|
||||
const { blocks, edges, loops, parallels } = useWorkflowStore(
|
||||
(state) => ({
|
||||
useShallow((state) => ({
|
||||
blocks: state.blocks,
|
||||
edges: state.edges,
|
||||
loops: state.loops || {},
|
||||
parallels: state.parallels || {},
|
||||
}),
|
||||
shallow
|
||||
}))
|
||||
)
|
||||
|
||||
return useMemo(() => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { shallow } from 'zustand/shallow'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { BlockPathCalculator } from '@/lib/block-path-calculator'
|
||||
import { createLogger } from '@/lib/logs/console/logger'
|
||||
import { getBlockOutputs } from '@/lib/workflows/block-outputs'
|
||||
@@ -88,11 +88,10 @@ function extractFieldsFromSchema(schema: any): Field[] {
|
||||
|
||||
export function useBlockConnections(blockId: string) {
|
||||
const { edges, blocks } = useWorkflowStore(
|
||||
(state) => ({
|
||||
useShallow((state) => ({
|
||||
edges: state.edges,
|
||||
blocks: state.blocks,
|
||||
}),
|
||||
shallow
|
||||
}))
|
||||
)
|
||||
|
||||
const workflowId = useWorkflowRegistry((state) => state.activeWorkflowId)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMemo } from 'react'
|
||||
import type { Edge } from 'reactflow'
|
||||
import { shallow } from 'zustand/shallow'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { useWorkflowDiffStore } from '@/stores/workflow-diff/store'
|
||||
import type { DeploymentStatus } from '@/stores/workflows/registry/types'
|
||||
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
|
||||
@@ -44,20 +44,22 @@ export interface CurrentWorkflow {
|
||||
export function useCurrentWorkflow(): CurrentWorkflow {
|
||||
// Get normal workflow state - optimized with shallow comparison
|
||||
// This prevents re-renders when only subblock values change (not block structure)
|
||||
const normalWorkflow = useWorkflowStore((state) => {
|
||||
const workflow = state.getWorkflowState()
|
||||
return {
|
||||
blocks: workflow.blocks,
|
||||
edges: workflow.edges,
|
||||
loops: workflow.loops,
|
||||
parallels: workflow.parallels,
|
||||
lastSaved: workflow.lastSaved,
|
||||
isDeployed: workflow.isDeployed,
|
||||
deployedAt: workflow.deployedAt,
|
||||
deploymentStatuses: workflow.deploymentStatuses,
|
||||
needsRedeployment: workflow.needsRedeployment,
|
||||
}
|
||||
}, shallow)
|
||||
const normalWorkflow = useWorkflowStore(
|
||||
useShallow((state) => {
|
||||
const workflow = state.getWorkflowState()
|
||||
return {
|
||||
blocks: workflow.blocks,
|
||||
edges: workflow.edges,
|
||||
loops: workflow.loops,
|
||||
parallels: workflow.parallels,
|
||||
lastSaved: workflow.lastSaved,
|
||||
isDeployed: workflow.isDeployed,
|
||||
deployedAt: workflow.deployedAt,
|
||||
deploymentStatuses: workflow.deploymentStatuses,
|
||||
needsRedeployment: workflow.needsRedeployment,
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// Get diff state - now including isDiffReady
|
||||
const { isShowingDiff, isDiffReady, hasActiveDiff, baselineWorkflow } = useWorkflowDiffStore()
|
||||
|
||||
@@ -0,0 +1,854 @@
|
||||
import { IncidentioIcon } from '@/components/icons'
|
||||
import type { BlockConfig } from '@/blocks/types'
|
||||
import { AuthMode } from '@/blocks/types'
|
||||
import type { IncidentioResponse } from '@/tools/incidentio/types'
|
||||
|
||||
export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
|
||||
type: 'incidentio',
|
||||
name: 'incidentio',
|
||||
description: 'Manage incidents with incident.io',
|
||||
authMode: AuthMode.ApiKey,
|
||||
longDescription:
|
||||
'Integrate incident.io into the workflow. Manage incidents, actions, follow-ups, workflows, schedules, escalations, custom fields, and more.',
|
||||
docsLink: 'https://docs.sim.ai/tools/incidentio',
|
||||
category: 'tools',
|
||||
bgColor: '#E0E0E0',
|
||||
icon: IncidentioIcon,
|
||||
subBlocks: [
|
||||
{
|
||||
id: 'operation',
|
||||
title: 'Operation',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
// Incidents
|
||||
{ label: 'List Incidents', id: 'incidentio_incidents_list' },
|
||||
{ label: 'Create Incident', id: 'incidentio_incidents_create' },
|
||||
{ label: 'Show Incident', id: 'incidentio_incidents_show' },
|
||||
{ label: 'Update Incident', id: 'incidentio_incidents_update' },
|
||||
// Actions
|
||||
{ label: 'List Actions', id: 'incidentio_actions_list' },
|
||||
{ label: 'Show Action', id: 'incidentio_actions_show' },
|
||||
// Follow-ups
|
||||
{ label: 'List Follow-ups', id: 'incidentio_follow_ups_list' },
|
||||
{ label: 'Show Follow-up', id: 'incidentio_follow_ups_show' },
|
||||
// Users
|
||||
{ label: 'List Users', id: 'incidentio_users_list' },
|
||||
{ label: 'Show User', id: 'incidentio_users_show' },
|
||||
// Workflows
|
||||
{ label: 'List Workflows', id: 'incidentio_workflows_list' },
|
||||
{ label: 'Show Workflow', id: 'incidentio_workflows_show' },
|
||||
{ label: 'Update Workflow', id: 'incidentio_workflows_update' },
|
||||
{ label: 'Delete Workflow', id: 'incidentio_workflows_delete' },
|
||||
// Schedules
|
||||
{ label: 'List Schedules', id: 'incidentio_schedules_list' },
|
||||
{ label: 'Create Schedule', id: 'incidentio_schedules_create' },
|
||||
{ label: 'Show Schedule', id: 'incidentio_schedules_show' },
|
||||
{ label: 'Update Schedule', id: 'incidentio_schedules_update' },
|
||||
{ label: 'Delete Schedule', id: 'incidentio_schedules_delete' },
|
||||
// Escalations
|
||||
{ label: 'List Escalations', id: 'incidentio_escalations_list' },
|
||||
{ label: 'Create Escalation', id: 'incidentio_escalations_create' },
|
||||
{ label: 'Show Escalation', id: 'incidentio_escalations_show' },
|
||||
// Custom Fields
|
||||
{ label: 'List Custom Fields', id: 'incidentio_custom_fields_list' },
|
||||
{ label: 'Create Custom Field', id: 'incidentio_custom_fields_create' },
|
||||
{ label: 'Show Custom Field', id: 'incidentio_custom_fields_show' },
|
||||
{ label: 'Update Custom Field', id: 'incidentio_custom_fields_update' },
|
||||
{ label: 'Delete Custom Field', id: 'incidentio_custom_fields_delete' },
|
||||
// Reference Data
|
||||
{ label: 'List Severities', id: 'incidentio_severities_list' },
|
||||
{ label: 'List Incident Statuses', id: 'incidentio_incident_statuses_list' },
|
||||
{ label: 'List Incident Types', id: 'incidentio_incident_types_list' },
|
||||
// Incident Roles
|
||||
{ label: 'List Incident Roles', id: 'incidentio_incident_roles_list' },
|
||||
{ label: 'Create Incident Role', id: 'incidentio_incident_roles_create' },
|
||||
{ label: 'Show Incident Role', id: 'incidentio_incident_roles_show' },
|
||||
{ label: 'Update Incident Role', id: 'incidentio_incident_roles_update' },
|
||||
{ label: 'Delete Incident Role', id: 'incidentio_incident_roles_delete' },
|
||||
// Incident Timestamps
|
||||
{ label: 'List Incident Timestamps', id: 'incidentio_incident_timestamps_list' },
|
||||
{ label: 'Show Incident Timestamp', id: 'incidentio_incident_timestamps_show' },
|
||||
// Incident Updates
|
||||
{ label: 'List Incident Updates', id: 'incidentio_incident_updates_list' },
|
||||
// Schedule Entries
|
||||
{ label: 'List Schedule Entries', id: 'incidentio_schedule_entries_list' },
|
||||
// Schedule Overrides
|
||||
{ label: 'Create Schedule Override', id: 'incidentio_schedule_overrides_create' },
|
||||
// Escalation Paths
|
||||
{ label: 'Create Escalation Path', id: 'incidentio_escalation_paths_create' },
|
||||
{ label: 'Show Escalation Path', id: 'incidentio_escalation_paths_show' },
|
||||
{ label: 'Update Escalation Path', id: 'incidentio_escalation_paths_update' },
|
||||
{ label: 'Delete Escalation Path', id: 'incidentio_escalation_paths_delete' },
|
||||
],
|
||||
value: () => 'incidentio_incidents_list',
|
||||
},
|
||||
// Common pagination field
|
||||
{
|
||||
id: 'page_size',
|
||||
title: 'Page Size',
|
||||
type: 'short-input',
|
||||
placeholder: '25',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: [
|
||||
'incidentio_incidents_list',
|
||||
'incidentio_actions_list',
|
||||
'incidentio_follow_ups_list',
|
||||
'incidentio_users_list',
|
||||
'incidentio_workflows_list',
|
||||
'incidentio_schedules_list',
|
||||
'incidentio_escalations_list',
|
||||
'incidentio_incident_updates_list',
|
||||
'incidentio_schedule_entries_list',
|
||||
],
|
||||
},
|
||||
},
|
||||
// Pagination 'after' field for list operations
|
||||
{
|
||||
id: 'after',
|
||||
title: 'After (Pagination)',
|
||||
type: 'short-input',
|
||||
placeholder: 'Cursor for pagination',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: [
|
||||
'incidentio_incidents_list',
|
||||
'incidentio_workflows_list',
|
||||
'incidentio_schedules_list',
|
||||
'incidentio_incident_updates_list',
|
||||
'incidentio_schedule_entries_list',
|
||||
],
|
||||
},
|
||||
},
|
||||
// Incidents Create operation inputs
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Incident Name',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter incident name...',
|
||||
condition: { field: 'operation', value: 'incidentio_incidents_create' },
|
||||
},
|
||||
{
|
||||
id: 'summary',
|
||||
title: 'Summary',
|
||||
type: 'long-input',
|
||||
placeholder: 'Enter incident summary...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_incidents_create', 'incidentio_incidents_update'],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'severity_id',
|
||||
title: 'Severity ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter severity ID...',
|
||||
condition: { field: 'operation', value: 'incidentio_incidents_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'severity_id',
|
||||
title: 'Severity ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter severity ID...',
|
||||
condition: { field: 'operation', value: 'incidentio_incidents_update' },
|
||||
},
|
||||
{
|
||||
id: 'incident_type_id',
|
||||
title: 'Incident Type ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter incident type ID...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_incidents_create', 'incidentio_incidents_update'],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'incident_status_id',
|
||||
title: 'Incident Status ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter incident status ID...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_incidents_create', 'incidentio_incidents_update'],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'notify_incident_channel',
|
||||
title: 'Notify Incident Channel',
|
||||
type: 'switch',
|
||||
value: () => 'true',
|
||||
condition: { field: 'operation', value: 'incidentio_incidents_update' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'visibility',
|
||||
title: 'Visibility',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Public', id: 'public' },
|
||||
{ label: 'Private', id: 'private' },
|
||||
],
|
||||
value: () => 'public',
|
||||
condition: { field: 'operation', value: 'incidentio_incidents_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'idempotency_key',
|
||||
title: 'Idempotency Key',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter unique key (e.g., UUID)',
|
||||
condition: { field: 'operation', value: 'incidentio_incidents_create' },
|
||||
required: true,
|
||||
},
|
||||
// Show/Update Incident inputs
|
||||
{
|
||||
id: 'id',
|
||||
title: 'ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter ID...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: [
|
||||
'incidentio_incidents_show',
|
||||
'incidentio_incidents_update',
|
||||
'incidentio_actions_show',
|
||||
'incidentio_follow_ups_show',
|
||||
'incidentio_users_show',
|
||||
'incidentio_workflows_show',
|
||||
'incidentio_workflows_update',
|
||||
'incidentio_workflows_delete',
|
||||
'incidentio_schedules_show',
|
||||
'incidentio_schedules_update',
|
||||
'incidentio_schedules_delete',
|
||||
'incidentio_escalations_show',
|
||||
'incidentio_custom_fields_show',
|
||||
'incidentio_custom_fields_update',
|
||||
'incidentio_custom_fields_delete',
|
||||
'incidentio_incident_roles_show',
|
||||
'incidentio_incident_roles_update',
|
||||
'incidentio_incident_roles_delete',
|
||||
'incidentio_incident_timestamps_show',
|
||||
'incidentio_escalation_paths_show',
|
||||
'incidentio_escalation_paths_update',
|
||||
'incidentio_escalation_paths_delete',
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Name',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter name...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: [
|
||||
'incidentio_schedules_create',
|
||||
'incidentio_custom_fields_create',
|
||||
'incidentio_custom_fields_update',
|
||||
'incidentio_incident_roles_create',
|
||||
'incidentio_incident_roles_update',
|
||||
'incidentio_escalation_paths_create',
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Name',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter name (optional for update)...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: 'incidentio_escalation_paths_update',
|
||||
},
|
||||
required: false,
|
||||
},
|
||||
// Escalations inputs
|
||||
{
|
||||
id: 'idempotency_key',
|
||||
title: 'Idempotency Key',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter unique key (e.g., UUID)...',
|
||||
condition: { field: 'operation', value: 'incidentio_escalations_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'title',
|
||||
title: 'Title',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter escalation title...',
|
||||
condition: { field: 'operation', value: 'incidentio_escalations_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'escalation_path_id',
|
||||
title: 'Escalation Path ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter escalation path ID (required if no user IDs)...',
|
||||
condition: { field: 'operation', value: 'incidentio_escalations_create' },
|
||||
},
|
||||
{
|
||||
id: 'user_ids',
|
||||
title: 'User IDs',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter user IDs, comma-separated (required if no path ID)...',
|
||||
condition: { field: 'operation', value: 'incidentio_escalations_create' },
|
||||
},
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Name',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter name...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: [
|
||||
'incidentio_incidents_update',
|
||||
'incidentio_workflows_update',
|
||||
'incidentio_schedules_update',
|
||||
],
|
||||
},
|
||||
},
|
||||
// Actions List inputs
|
||||
{
|
||||
id: 'incident_id',
|
||||
title: 'Incident ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Filter by incident ID...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_actions_list', 'incidentio_follow_ups_list'],
|
||||
},
|
||||
},
|
||||
// Workflows inputs
|
||||
{
|
||||
id: 'folder',
|
||||
title: 'Folder',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter folder name...',
|
||||
condition: { field: 'operation', value: 'incidentio_workflows_update' },
|
||||
},
|
||||
{
|
||||
id: 'state',
|
||||
title: 'State',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Active', id: 'active' },
|
||||
{ label: 'Draft', id: 'draft' },
|
||||
{ label: 'Disabled', id: 'disabled' },
|
||||
],
|
||||
value: () => 'active',
|
||||
condition: { field: 'operation', value: 'incidentio_workflows_update' },
|
||||
},
|
||||
// Schedules inputs
|
||||
{
|
||||
id: 'timezone',
|
||||
title: 'Timezone',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'America/New_York (Eastern)', id: 'America/New_York' },
|
||||
{ label: 'America/Chicago (Central)', id: 'America/Chicago' },
|
||||
{ label: 'America/Denver (Mountain)', id: 'America/Denver' },
|
||||
{ label: 'America/Los_Angeles (Pacific)', id: 'America/Los_Angeles' },
|
||||
{ label: 'America/Phoenix (Arizona)', id: 'America/Phoenix' },
|
||||
{ label: 'America/Anchorage (Alaska)', id: 'America/Anchorage' },
|
||||
{ label: 'Pacific/Honolulu (Hawaii)', id: 'Pacific/Honolulu' },
|
||||
{ label: 'Europe/London (UK)', id: 'Europe/London' },
|
||||
{ label: 'Europe/Paris (Central Europe)', id: 'Europe/Paris' },
|
||||
{ label: 'Europe/Berlin (Germany)', id: 'Europe/Berlin' },
|
||||
{ label: 'Europe/Dublin (Ireland)', id: 'Europe/Dublin' },
|
||||
{ label: 'Europe/Amsterdam (Netherlands)', id: 'Europe/Amsterdam' },
|
||||
{ label: 'Asia/Tokyo (Japan)', id: 'Asia/Tokyo' },
|
||||
{ label: 'Asia/Singapore', id: 'Asia/Singapore' },
|
||||
{ label: 'Asia/Hong_Kong', id: 'Asia/Hong_Kong' },
|
||||
{ label: 'Asia/Shanghai (China)', id: 'Asia/Shanghai' },
|
||||
{ label: 'Asia/Seoul (South Korea)', id: 'Asia/Seoul' },
|
||||
{ label: 'Asia/Dubai (UAE)', id: 'Asia/Dubai' },
|
||||
{ label: 'Asia/Kolkata (India)', id: 'Asia/Kolkata' },
|
||||
{ label: 'Australia/Sydney', id: 'Australia/Sydney' },
|
||||
{ label: 'Australia/Melbourne', id: 'Australia/Melbourne' },
|
||||
{ label: 'Pacific/Auckland (New Zealand)', id: 'Pacific/Auckland' },
|
||||
{ label: 'UTC', id: 'UTC' },
|
||||
],
|
||||
value: () => 'UTC',
|
||||
condition: { field: 'operation', value: 'incidentio_schedules_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'config',
|
||||
title: 'Schedule Configuration',
|
||||
type: 'long-input',
|
||||
placeholder:
|
||||
'JSON configuration with rotations. Example: {"rotations": [{"name": "Primary", "users": [{"id": "user_id"}], "handover_start_at": "2024-01-01T09:00:00Z", "handovers": [{"interval": 1, "interval_type": "weekly"}]}]}',
|
||||
condition: { field: 'operation', value: 'incidentio_schedules_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'timezone',
|
||||
title: 'Timezone',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'America/New_York (Eastern)', id: 'America/New_York' },
|
||||
{ label: 'America/Chicago (Central)', id: 'America/Chicago' },
|
||||
{ label: 'America/Denver (Mountain)', id: 'America/Denver' },
|
||||
{ label: 'America/Los_Angeles (Pacific)', id: 'America/Los_Angeles' },
|
||||
{ label: 'America/Phoenix (Arizona)', id: 'America/Phoenix' },
|
||||
{ label: 'America/Anchorage (Alaska)', id: 'America/Anchorage' },
|
||||
{ label: 'Pacific/Honolulu (Hawaii)', id: 'Pacific/Honolulu' },
|
||||
{ label: 'Europe/London (UK)', id: 'Europe/London' },
|
||||
{ label: 'Europe/Paris (Central Europe)', id: 'Europe/Paris' },
|
||||
{ label: 'Europe/Berlin (Germany)', id: 'Europe/Berlin' },
|
||||
{ label: 'Europe/Dublin (Ireland)', id: 'Europe/Dublin' },
|
||||
{ label: 'Europe/Amsterdam (Netherlands)', id: 'Europe/Amsterdam' },
|
||||
{ label: 'Asia/Tokyo (Japan)', id: 'Asia/Tokyo' },
|
||||
{ label: 'Asia/Singapore', id: 'Asia/Singapore' },
|
||||
{ label: 'Asia/Hong_Kong', id: 'Asia/Hong_Kong' },
|
||||
{ label: 'Asia/Shanghai (China)', id: 'Asia/Shanghai' },
|
||||
{ label: 'Asia/Seoul (South Korea)', id: 'Asia/Seoul' },
|
||||
{ label: 'Asia/Dubai (UAE)', id: 'Asia/Dubai' },
|
||||
{ label: 'Asia/Kolkata (India)', id: 'Asia/Kolkata' },
|
||||
{ label: 'Australia/Sydney', id: 'Australia/Sydney' },
|
||||
{ label: 'Australia/Melbourne', id: 'Australia/Melbourne' },
|
||||
{ label: 'Pacific/Auckland (New Zealand)', id: 'Pacific/Auckland' },
|
||||
{ label: 'UTC', id: 'UTC' },
|
||||
],
|
||||
value: () => 'UTC',
|
||||
condition: { field: 'operation', value: 'incidentio_schedules_update' },
|
||||
},
|
||||
// Custom Fields inputs
|
||||
{
|
||||
id: 'description',
|
||||
title: 'Description',
|
||||
type: 'long-input',
|
||||
placeholder: 'Enter description...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_custom_fields_create', 'incidentio_custom_fields_update'],
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'field_type',
|
||||
title: 'Field Type',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Text', id: 'text' },
|
||||
{ label: 'Single Select', id: 'single_select' },
|
||||
{ label: 'Multi Select', id: 'multi_select' },
|
||||
{ label: 'Numeric', id: 'numeric' },
|
||||
{ label: 'Link', id: 'link' },
|
||||
],
|
||||
value: () => 'text',
|
||||
condition: { field: 'operation', value: 'incidentio_custom_fields_create' },
|
||||
required: true,
|
||||
},
|
||||
// Incident Roles inputs
|
||||
{
|
||||
id: 'description',
|
||||
title: 'Description',
|
||||
type: 'long-input',
|
||||
placeholder: 'Enter description...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_incident_roles_create', 'incidentio_incident_roles_update'],
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'instructions',
|
||||
title: 'Instructions',
|
||||
type: 'long-input',
|
||||
placeholder: 'Enter instructions for the role...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_incident_roles_create', 'incidentio_incident_roles_update'],
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'shortform',
|
||||
title: 'Shortform',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter short form abbreviation (e.g., INC, LEAD)...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_incident_roles_create', 'incidentio_incident_roles_update'],
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
// Incident Updates inputs
|
||||
{
|
||||
id: 'incident_id',
|
||||
title: 'Incident ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter incident ID (optional - leave blank for all incidents)...',
|
||||
condition: { field: 'operation', value: 'incidentio_incident_updates_list' },
|
||||
required: false,
|
||||
},
|
||||
// Schedule Entries inputs
|
||||
{
|
||||
id: 'schedule_id',
|
||||
title: 'Schedule ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter schedule ID...',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_schedule_entries_list', 'incidentio_schedule_overrides_create'],
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'entry_window_start',
|
||||
title: 'Entry Window Start (Date/Time)',
|
||||
type: 'short-input',
|
||||
placeholder: 'ISO 8601 format (e.g., 2024-01-01T00:00:00Z)...',
|
||||
condition: { field: 'operation', value: 'incidentio_schedule_entries_list' },
|
||||
},
|
||||
{
|
||||
id: 'entry_window_end',
|
||||
title: 'Entry Window End (Date/Time)',
|
||||
type: 'short-input',
|
||||
placeholder: 'ISO 8601 format (e.g., 2024-12-31T23:59:59Z)...',
|
||||
condition: { field: 'operation', value: 'incidentio_schedule_entries_list' },
|
||||
},
|
||||
// Schedule Overrides inputs
|
||||
{
|
||||
id: 'rotation_id',
|
||||
title: 'Rotation ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter rotation ID...',
|
||||
condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'user_id',
|
||||
title: 'User ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter user ID (provide one of: user_id, user_email, or user_slack_id)...',
|
||||
condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' },
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: 'user_email',
|
||||
title: 'User Email',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter user email (provide one of: user_id, user_email, or user_slack_id)...',
|
||||
condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' },
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: 'user_slack_id',
|
||||
title: 'User Slack ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter user Slack ID (provide one of: user_id, user_email, or user_slack_id)...',
|
||||
condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' },
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: 'start_at',
|
||||
title: 'Start At',
|
||||
type: 'short-input',
|
||||
placeholder: 'ISO 8601 format (e.g., 2024-01-01T00:00:00Z)...',
|
||||
condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'end_at',
|
||||
title: 'End At',
|
||||
type: 'short-input',
|
||||
placeholder: 'ISO 8601 format (e.g., 2024-12-31T23:59:59Z)...',
|
||||
condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' },
|
||||
required: true,
|
||||
},
|
||||
// Escalation Paths inputs
|
||||
{
|
||||
id: 'path',
|
||||
title: 'Path Configuration',
|
||||
type: 'long-input',
|
||||
placeholder:
|
||||
'JSON array of escalation levels: [{"targets": [{"id": "...", "type": "...", "urgency": "..."}], "time_to_ack_seconds": 300}]',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: 'incidentio_escalation_paths_create',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'path',
|
||||
title: 'Path Configuration',
|
||||
type: 'long-input',
|
||||
placeholder:
|
||||
'JSON array of escalation levels (optional for update): [{"targets": [{"id": "...", "type": "...", "urgency": "..."}], "time_to_ack_seconds": 300}]',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: 'incidentio_escalation_paths_update',
|
||||
},
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
id: 'working_hours',
|
||||
title: 'Working Hours',
|
||||
type: 'long-input',
|
||||
placeholder:
|
||||
'Optional JSON array: [{"weekday": "monday", "start_time": "09:00", "end_time": "17:00"}]',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['incidentio_escalation_paths_create', 'incidentio_escalation_paths_update'],
|
||||
},
|
||||
},
|
||||
// API Key (common)
|
||||
{
|
||||
id: 'apiKey',
|
||||
title: 'API Key',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter your incident.io API key',
|
||||
password: true,
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
tools: {
|
||||
access: [
|
||||
'incidentio_incidents_list',
|
||||
'incidentio_incidents_create',
|
||||
'incidentio_incidents_show',
|
||||
'incidentio_incidents_update',
|
||||
'incidentio_actions_list',
|
||||
'incidentio_actions_show',
|
||||
'incidentio_follow_ups_list',
|
||||
'incidentio_follow_ups_show',
|
||||
'incidentio_users_list',
|
||||
'incidentio_users_show',
|
||||
'incidentio_workflows_list',
|
||||
'incidentio_workflows_show',
|
||||
'incidentio_workflows_update',
|
||||
'incidentio_workflows_delete',
|
||||
'incidentio_schedules_list',
|
||||
'incidentio_schedules_create',
|
||||
'incidentio_schedules_show',
|
||||
'incidentio_schedules_update',
|
||||
'incidentio_schedules_delete',
|
||||
'incidentio_escalations_list',
|
||||
'incidentio_escalations_create',
|
||||
'incidentio_escalations_show',
|
||||
'incidentio_custom_fields_list',
|
||||
'incidentio_custom_fields_create',
|
||||
'incidentio_custom_fields_show',
|
||||
'incidentio_custom_fields_update',
|
||||
'incidentio_custom_fields_delete',
|
||||
'incidentio_severities_list',
|
||||
'incidentio_incident_statuses_list',
|
||||
'incidentio_incident_types_list',
|
||||
'incidentio_incident_roles_list',
|
||||
'incidentio_incident_roles_create',
|
||||
'incidentio_incident_roles_show',
|
||||
'incidentio_incident_roles_update',
|
||||
'incidentio_incident_roles_delete',
|
||||
'incidentio_incident_timestamps_list',
|
||||
'incidentio_incident_timestamps_show',
|
||||
'incidentio_incident_updates_list',
|
||||
'incidentio_schedule_entries_list',
|
||||
'incidentio_schedule_overrides_create',
|
||||
'incidentio_escalation_paths_create',
|
||||
'incidentio_escalation_paths_show',
|
||||
'incidentio_escalation_paths_update',
|
||||
'incidentio_escalation_paths_delete',
|
||||
],
|
||||
config: {
|
||||
tool: (params) => {
|
||||
// Convert page_size to a number if provided
|
||||
if (params.page_size) {
|
||||
params.page_size = Number(params.page_size)
|
||||
}
|
||||
|
||||
// Convert notify_incident_channel from string to boolean
|
||||
if (params.notify_incident_channel !== undefined) {
|
||||
params.notify_incident_channel = params.notify_incident_channel === 'true'
|
||||
}
|
||||
|
||||
switch (params.operation) {
|
||||
case 'incidentio_incidents_list':
|
||||
return 'incidentio_incidents_list'
|
||||
case 'incidentio_incidents_create':
|
||||
return 'incidentio_incidents_create'
|
||||
case 'incidentio_incidents_show':
|
||||
return 'incidentio_incidents_show'
|
||||
case 'incidentio_incidents_update':
|
||||
return 'incidentio_incidents_update'
|
||||
case 'incidentio_actions_list':
|
||||
return 'incidentio_actions_list'
|
||||
case 'incidentio_actions_show':
|
||||
return 'incidentio_actions_show'
|
||||
case 'incidentio_follow_ups_list':
|
||||
return 'incidentio_follow_ups_list'
|
||||
case 'incidentio_follow_ups_show':
|
||||
return 'incidentio_follow_ups_show'
|
||||
case 'incidentio_users_list':
|
||||
return 'incidentio_users_list'
|
||||
case 'incidentio_users_show':
|
||||
return 'incidentio_users_show'
|
||||
case 'incidentio_workflows_list':
|
||||
return 'incidentio_workflows_list'
|
||||
case 'incidentio_workflows_show':
|
||||
return 'incidentio_workflows_show'
|
||||
case 'incidentio_workflows_update':
|
||||
return 'incidentio_workflows_update'
|
||||
case 'incidentio_workflows_delete':
|
||||
return 'incidentio_workflows_delete'
|
||||
case 'incidentio_schedules_list':
|
||||
return 'incidentio_schedules_list'
|
||||
case 'incidentio_schedules_create':
|
||||
return 'incidentio_schedules_create'
|
||||
case 'incidentio_schedules_show':
|
||||
return 'incidentio_schedules_show'
|
||||
case 'incidentio_schedules_update':
|
||||
return 'incidentio_schedules_update'
|
||||
case 'incidentio_schedules_delete':
|
||||
return 'incidentio_schedules_delete'
|
||||
case 'incidentio_escalations_list':
|
||||
return 'incidentio_escalations_list'
|
||||
case 'incidentio_escalations_create':
|
||||
return 'incidentio_escalations_create'
|
||||
case 'incidentio_escalations_show':
|
||||
return 'incidentio_escalations_show'
|
||||
case 'incidentio_custom_fields_list':
|
||||
return 'incidentio_custom_fields_list'
|
||||
case 'incidentio_custom_fields_create':
|
||||
return 'incidentio_custom_fields_create'
|
||||
case 'incidentio_custom_fields_show':
|
||||
return 'incidentio_custom_fields_show'
|
||||
case 'incidentio_custom_fields_update':
|
||||
return 'incidentio_custom_fields_update'
|
||||
case 'incidentio_custom_fields_delete':
|
||||
return 'incidentio_custom_fields_delete'
|
||||
case 'incidentio_severities_list':
|
||||
return 'incidentio_severities_list'
|
||||
case 'incidentio_incident_statuses_list':
|
||||
return 'incidentio_incident_statuses_list'
|
||||
case 'incidentio_incident_types_list':
|
||||
return 'incidentio_incident_types_list'
|
||||
case 'incidentio_incident_roles_list':
|
||||
return 'incidentio_incident_roles_list'
|
||||
case 'incidentio_incident_roles_create':
|
||||
return 'incidentio_incident_roles_create'
|
||||
case 'incidentio_incident_roles_show':
|
||||
return 'incidentio_incident_roles_show'
|
||||
case 'incidentio_incident_roles_update':
|
||||
return 'incidentio_incident_roles_update'
|
||||
case 'incidentio_incident_roles_delete':
|
||||
return 'incidentio_incident_roles_delete'
|
||||
case 'incidentio_incident_timestamps_list':
|
||||
return 'incidentio_incident_timestamps_list'
|
||||
case 'incidentio_incident_timestamps_show':
|
||||
return 'incidentio_incident_timestamps_show'
|
||||
case 'incidentio_incident_updates_list':
|
||||
return 'incidentio_incident_updates_list'
|
||||
case 'incidentio_schedule_entries_list':
|
||||
return 'incidentio_schedule_entries_list'
|
||||
case 'incidentio_schedule_overrides_create':
|
||||
return 'incidentio_schedule_overrides_create'
|
||||
case 'incidentio_escalation_paths_create':
|
||||
return 'incidentio_escalation_paths_create'
|
||||
case 'incidentio_escalation_paths_show':
|
||||
return 'incidentio_escalation_paths_show'
|
||||
case 'incidentio_escalation_paths_update':
|
||||
return 'incidentio_escalation_paths_update'
|
||||
case 'incidentio_escalation_paths_delete':
|
||||
return 'incidentio_escalation_paths_delete'
|
||||
default:
|
||||
return 'incidentio_incidents_list'
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
inputs: {
|
||||
operation: { type: 'string', description: 'Operation to perform' },
|
||||
apiKey: { type: 'string', description: 'incident.io API key' },
|
||||
// Common fields
|
||||
id: { type: 'string', description: 'Resource ID' },
|
||||
name: { type: 'string', description: 'Resource name' },
|
||||
page_size: { type: 'number', description: 'Number of results per page' },
|
||||
after: { type: 'string', description: 'Pagination cursor' },
|
||||
// Incident fields
|
||||
summary: { type: 'string', description: 'Incident summary' },
|
||||
severity_id: { type: 'string', description: 'Severity ID' },
|
||||
incident_type_id: { type: 'string', description: 'Incident type ID' },
|
||||
incident_status_id: { type: 'string', description: 'Incident status ID' },
|
||||
visibility: { type: 'string', description: 'Incident visibility' },
|
||||
incident_id: { type: 'string', description: 'Incident ID for filtering' },
|
||||
notify_incident_channel: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to notify the incident channel',
|
||||
},
|
||||
// Workflow fields
|
||||
folder: { type: 'string', description: 'Workflow folder' },
|
||||
state: { type: 'string', description: 'Workflow state' },
|
||||
// Schedule fields
|
||||
timezone: { type: 'string', description: 'Schedule timezone' },
|
||||
// Custom field fields
|
||||
description: { type: 'string', description: 'Custom field description' },
|
||||
field_type: { type: 'string', description: 'Custom field type' },
|
||||
idempotency_key: { type: 'string', description: 'Unique key to prevent duplicate creation' },
|
||||
// Incident Roles fields
|
||||
role_type: { type: 'string', description: 'Type of incident role' },
|
||||
required: { type: 'boolean', description: 'Whether the role is required' },
|
||||
// Schedule Entries/Overrides fields
|
||||
schedule_id: { type: 'string', description: 'Schedule ID' },
|
||||
from: { type: 'string', description: 'Start date/time for filtering' },
|
||||
to: { type: 'string', description: 'End date/time for filtering' },
|
||||
user_id: { type: 'string', description: 'User ID' },
|
||||
start_at: { type: 'string', description: 'Start date/time' },
|
||||
end_at: { type: 'string', description: 'End date/time' },
|
||||
layer_id: { type: 'string', description: 'Schedule layer ID' },
|
||||
// Escalation Paths fields
|
||||
path: { type: 'json', description: 'Escalation path configuration' },
|
||||
working_hours: { type: 'json', description: 'Working hours configuration' },
|
||||
},
|
||||
outputs: {
|
||||
// Incidents
|
||||
incidents: { type: 'json', description: 'List of incidents' },
|
||||
incident: { type: 'json', description: 'Incident details' },
|
||||
// Actions
|
||||
actions: { type: 'json', description: 'List of actions' },
|
||||
action: { type: 'json', description: 'Action details' },
|
||||
// Follow-ups
|
||||
follow_ups: { type: 'json', description: 'List of follow-ups' },
|
||||
follow_up: { type: 'json', description: 'Follow-up details' },
|
||||
// Users
|
||||
users: { type: 'json', description: 'List of users' },
|
||||
user: { type: 'json', description: 'User details' },
|
||||
// Workflows
|
||||
workflows: { type: 'json', description: 'List of workflows' },
|
||||
workflow: { type: 'json', description: 'Workflow details' },
|
||||
// Schedules
|
||||
schedules: { type: 'json', description: 'List of schedules' },
|
||||
schedule: { type: 'json', description: 'Schedule details' },
|
||||
// Escalations
|
||||
escalations: { type: 'json', description: 'List of escalations' },
|
||||
escalation: { type: 'json', description: 'Escalation details' },
|
||||
// Custom Fields
|
||||
custom_fields: { type: 'json', description: 'List of custom fields' },
|
||||
custom_field: { type: 'json', description: 'Custom field details' },
|
||||
// Reference Data
|
||||
severities: { type: 'json', description: 'List of severities' },
|
||||
incident_statuses: { type: 'json', description: 'List of incident statuses' },
|
||||
incident_types: { type: 'json', description: 'List of incident types' },
|
||||
// Incident Roles
|
||||
incident_roles: { type: 'json', description: 'List of incident roles' },
|
||||
incident_role: { type: 'json', description: 'Incident role details' },
|
||||
// Incident Timestamps
|
||||
incident_timestamps: { type: 'json', description: 'List of incident timestamps' },
|
||||
incident_timestamp: { type: 'json', description: 'Incident timestamp details' },
|
||||
// Incident Updates
|
||||
incident_updates: { type: 'json', description: 'List of incident updates' },
|
||||
// Schedule Entries
|
||||
schedule_entries: { type: 'json', description: 'List of schedule entries' },
|
||||
// Schedule Overrides
|
||||
schedule_override: { type: 'json', description: 'Schedule override details' },
|
||||
// Escalation Paths
|
||||
escalation_path: { type: 'json', description: 'Escalation path details' },
|
||||
// General
|
||||
message: { type: 'string', description: 'Operation result message' },
|
||||
pagination_meta: { type: 'json', description: 'Pagination metadata' },
|
||||
},
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,565 @@
|
||||
import { SentryIcon } from '@/components/icons'
|
||||
import type { BlockConfig } from '@/blocks/types'
|
||||
import { AuthMode } from '@/blocks/types'
|
||||
import type { SentryResponse } from '@/tools/sentry/types'
|
||||
|
||||
export const SentryBlock: BlockConfig<SentryResponse> = {
|
||||
type: 'sentry',
|
||||
name: 'Sentry',
|
||||
description: 'Manage Sentry issues, projects, events, and releases',
|
||||
authMode: AuthMode.ApiKey,
|
||||
longDescription:
|
||||
'Integrate Sentry into the workflow. Monitor issues, manage projects, track events, and coordinate releases across your applications.',
|
||||
docsLink: 'https://docs.sim.ai/tools/sentry',
|
||||
category: 'tools',
|
||||
bgColor: '#E0E0E0',
|
||||
icon: SentryIcon,
|
||||
subBlocks: [
|
||||
{
|
||||
id: 'operation',
|
||||
title: 'Operation',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'List Issues', id: 'sentry_issues_list' },
|
||||
{ label: 'Get Issue', id: 'sentry_issues_get' },
|
||||
{ label: 'Update Issue', id: 'sentry_issues_update' },
|
||||
{ label: 'List Projects', id: 'sentry_projects_list' },
|
||||
{ label: 'Get Project', id: 'sentry_projects_get' },
|
||||
{ label: 'Create Project', id: 'sentry_projects_create' },
|
||||
{ label: 'Update Project', id: 'sentry_projects_update' },
|
||||
{ label: 'List Events', id: 'sentry_events_list' },
|
||||
{ label: 'Get Event', id: 'sentry_events_get' },
|
||||
{ label: 'List Releases', id: 'sentry_releases_list' },
|
||||
{ label: 'Create Release', id: 'sentry_releases_create' },
|
||||
{ label: 'Create Deploy', id: 'sentry_releases_deploy' },
|
||||
],
|
||||
value: () => 'sentry_issues_list',
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// LIST ISSUES
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'projectSlug',
|
||||
title: 'Project Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Filter by project (optional)',
|
||||
condition: { field: 'operation', value: 'sentry_issues_list' },
|
||||
},
|
||||
{
|
||||
id: 'query',
|
||||
title: 'Search Query',
|
||||
type: 'long-input',
|
||||
placeholder: 'e.g., is:unresolved, level:error',
|
||||
condition: { field: 'operation', value: 'sentry_issues_list' },
|
||||
},
|
||||
{
|
||||
id: 'statsPeriod',
|
||||
title: 'Stats Period',
|
||||
type: 'short-input',
|
||||
placeholder: '24h, 7d, 30d',
|
||||
condition: { field: 'operation', value: 'sentry_issues_list' },
|
||||
},
|
||||
{
|
||||
id: 'limit',
|
||||
title: 'Limit',
|
||||
type: 'short-input',
|
||||
placeholder: '25',
|
||||
condition: { field: 'operation', value: 'sentry_issues_list' },
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
title: 'Status',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'All', id: '' },
|
||||
{ label: 'Unresolved', id: 'unresolved' },
|
||||
{ label: 'Resolved', id: 'resolved' },
|
||||
{ label: 'Ignored', id: 'ignored' },
|
||||
{ label: 'Muted', id: 'muted' },
|
||||
],
|
||||
value: () => '',
|
||||
condition: { field: 'operation', value: 'sentry_issues_list' },
|
||||
},
|
||||
{
|
||||
id: 'sort',
|
||||
title: 'Sort By',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Date', id: 'date' },
|
||||
{ label: 'New', id: 'new' },
|
||||
{ label: 'Frequency', id: 'freq' },
|
||||
{ label: 'Priority', id: 'priority' },
|
||||
{ label: 'User Count', id: 'user' },
|
||||
],
|
||||
value: () => 'date',
|
||||
condition: { field: 'operation', value: 'sentry_issues_list' },
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// GET ISSUE
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'issueId',
|
||||
title: 'Issue ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter issue ID',
|
||||
condition: { field: 'operation', value: 'sentry_issues_get' },
|
||||
required: true,
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// UPDATE ISSUE
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'issueId',
|
||||
title: 'Issue ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter issue ID',
|
||||
condition: { field: 'operation', value: 'sentry_issues_update' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
title: 'New Status',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'No Change', id: '' },
|
||||
{ label: 'Resolved', id: 'resolved' },
|
||||
{ label: 'Unresolved', id: 'unresolved' },
|
||||
{ label: 'Ignored', id: 'ignored' },
|
||||
{ label: 'Resolved in Next Release', id: 'resolvedInNextRelease' },
|
||||
],
|
||||
value: () => '',
|
||||
condition: { field: 'operation', value: 'sentry_issues_update' },
|
||||
},
|
||||
{
|
||||
id: 'assignedTo',
|
||||
title: 'Assign To',
|
||||
type: 'short-input',
|
||||
placeholder: 'User ID or email (empty to unassign)',
|
||||
condition: { field: 'operation', value: 'sentry_issues_update' },
|
||||
},
|
||||
{
|
||||
id: 'isBookmarked',
|
||||
title: 'Bookmark Issue',
|
||||
type: 'switch',
|
||||
condition: { field: 'operation', value: 'sentry_issues_update' },
|
||||
},
|
||||
{
|
||||
id: 'isSubscribed',
|
||||
title: 'Subscribe to Updates',
|
||||
type: 'switch',
|
||||
condition: { field: 'operation', value: 'sentry_issues_update' },
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// LIST PROJECTS
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'limit',
|
||||
title: 'Limit',
|
||||
type: 'short-input',
|
||||
placeholder: '25',
|
||||
condition: { field: 'operation', value: 'sentry_projects_list' },
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// GET PROJECT
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'projectSlug',
|
||||
title: 'Project ID or Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter project ID or slug',
|
||||
condition: { field: 'operation', value: 'sentry_projects_get' },
|
||||
required: true,
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// CREATE PROJECT
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Project Name',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter project name',
|
||||
condition: { field: 'operation', value: 'sentry_projects_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'teamSlug',
|
||||
title: 'Team Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Team that will own the project',
|
||||
condition: { field: 'operation', value: 'sentry_projects_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'slug',
|
||||
title: 'Project Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Auto-generated if not provided',
|
||||
condition: { field: 'operation', value: 'sentry_projects_create' },
|
||||
},
|
||||
{
|
||||
id: 'platform',
|
||||
title: 'Platform',
|
||||
type: 'short-input',
|
||||
placeholder: 'javascript, python, node, etc.',
|
||||
condition: { field: 'operation', value: 'sentry_projects_create' },
|
||||
},
|
||||
{
|
||||
id: 'defaultRules',
|
||||
title: 'Create Default Alert Rules',
|
||||
type: 'switch',
|
||||
condition: { field: 'operation', value: 'sentry_projects_create' },
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// UPDATE PROJECT
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'projectSlug',
|
||||
title: 'Project Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter project slug',
|
||||
condition: { field: 'operation', value: 'sentry_projects_update' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'name',
|
||||
title: 'New Name',
|
||||
type: 'short-input',
|
||||
placeholder: 'Leave empty to keep current name',
|
||||
condition: { field: 'operation', value: 'sentry_projects_update' },
|
||||
},
|
||||
{
|
||||
id: 'slug',
|
||||
title: 'New Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Leave empty to keep current slug',
|
||||
condition: { field: 'operation', value: 'sentry_projects_update' },
|
||||
},
|
||||
{
|
||||
id: 'platform',
|
||||
title: 'Platform',
|
||||
type: 'short-input',
|
||||
placeholder: 'Leave empty to keep current platform',
|
||||
condition: { field: 'operation', value: 'sentry_projects_update' },
|
||||
},
|
||||
{
|
||||
id: 'isBookmarked',
|
||||
title: 'Bookmark Project',
|
||||
type: 'switch',
|
||||
condition: { field: 'operation', value: 'sentry_projects_update' },
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// LIST EVENTS
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'projectSlug',
|
||||
title: 'Project Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter project slug',
|
||||
condition: { field: 'operation', value: 'sentry_events_list' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'issueId',
|
||||
title: 'Issue ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Filter by specific issue (optional)',
|
||||
condition: { field: 'operation', value: 'sentry_events_list' },
|
||||
},
|
||||
{
|
||||
id: 'query',
|
||||
title: 'Search Query',
|
||||
type: 'long-input',
|
||||
placeholder: 'e.g., user.email:*@example.com',
|
||||
condition: { field: 'operation', value: 'sentry_events_list' },
|
||||
},
|
||||
{
|
||||
id: 'limit',
|
||||
title: 'Limit',
|
||||
type: 'short-input',
|
||||
placeholder: '50',
|
||||
condition: { field: 'operation', value: 'sentry_events_list' },
|
||||
},
|
||||
{
|
||||
id: 'statsPeriod',
|
||||
title: 'Stats Period',
|
||||
type: 'short-input',
|
||||
placeholder: '24h, 7d, 30d, 90d',
|
||||
condition: { field: 'operation', value: 'sentry_events_list' },
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// GET EVENT
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'projectSlug',
|
||||
title: 'Project Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter project slug',
|
||||
condition: { field: 'operation', value: 'sentry_events_get' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'eventId',
|
||||
title: 'Event ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter event ID',
|
||||
condition: { field: 'operation', value: 'sentry_events_get' },
|
||||
required: true,
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// LIST RELEASES
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'projectSlug',
|
||||
title: 'Project Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Filter by project (optional)',
|
||||
condition: { field: 'operation', value: 'sentry_releases_list' },
|
||||
},
|
||||
{
|
||||
id: 'query',
|
||||
title: 'Search Query',
|
||||
type: 'long-input',
|
||||
placeholder: 'Search for specific release versions',
|
||||
condition: { field: 'operation', value: 'sentry_releases_list' },
|
||||
},
|
||||
{
|
||||
id: 'limit',
|
||||
title: 'Limit',
|
||||
type: 'short-input',
|
||||
placeholder: '25',
|
||||
condition: { field: 'operation', value: 'sentry_releases_list' },
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// CREATE RELEASE
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'version',
|
||||
title: 'Version',
|
||||
type: 'short-input',
|
||||
placeholder: 'e.g., 2.0.0 or my-app@1.0.0',
|
||||
condition: { field: 'operation', value: 'sentry_releases_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'projects',
|
||||
title: 'Projects',
|
||||
type: 'long-input',
|
||||
placeholder: 'Comma-separated project slugs',
|
||||
condition: { field: 'operation', value: 'sentry_releases_create' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'ref',
|
||||
title: 'Git Reference',
|
||||
type: 'short-input',
|
||||
placeholder: 'Commit SHA, tag, or branch',
|
||||
condition: { field: 'operation', value: 'sentry_releases_create' },
|
||||
},
|
||||
{
|
||||
id: 'url',
|
||||
title: 'Release URL',
|
||||
type: 'long-input',
|
||||
placeholder: 'URL to release page (e.g., GitHub release)',
|
||||
condition: { field: 'operation', value: 'sentry_releases_create' },
|
||||
},
|
||||
{
|
||||
id: 'dateReleased',
|
||||
title: 'Release Date',
|
||||
type: 'short-input',
|
||||
placeholder: 'ISO 8601 timestamp (defaults to now)',
|
||||
condition: { field: 'operation', value: 'sentry_releases_create' },
|
||||
},
|
||||
{
|
||||
id: 'commits',
|
||||
title: 'Commits (JSON)',
|
||||
type: 'long-input',
|
||||
placeholder: '[{"id":"abc123","message":"Fix bug"}]',
|
||||
condition: { field: 'operation', value: 'sentry_releases_create' },
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// CREATE DEPLOY
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'version',
|
||||
title: 'Version',
|
||||
type: 'short-input',
|
||||
placeholder: 'Release version to deploy',
|
||||
condition: { field: 'operation', value: 'sentry_releases_deploy' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'environment',
|
||||
title: 'Environment',
|
||||
type: 'short-input',
|
||||
placeholder: 'production, staging, etc.',
|
||||
condition: { field: 'operation', value: 'sentry_releases_deploy' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Deploy Name',
|
||||
type: 'short-input',
|
||||
placeholder: 'Optional deploy name',
|
||||
condition: { field: 'operation', value: 'sentry_releases_deploy' },
|
||||
},
|
||||
{
|
||||
id: 'url',
|
||||
title: 'Deploy URL',
|
||||
type: 'long-input',
|
||||
placeholder: 'URL to CI/CD pipeline or deploy',
|
||||
condition: { field: 'operation', value: 'sentry_releases_deploy' },
|
||||
},
|
||||
{
|
||||
id: 'dateStarted',
|
||||
title: 'Start Time',
|
||||
type: 'short-input',
|
||||
placeholder: 'ISO 8601 timestamp (defaults to now)',
|
||||
condition: { field: 'operation', value: 'sentry_releases_deploy' },
|
||||
},
|
||||
{
|
||||
id: 'dateFinished',
|
||||
title: 'Finish Time',
|
||||
type: 'short-input',
|
||||
placeholder: 'ISO 8601 timestamp',
|
||||
condition: { field: 'operation', value: 'sentry_releases_deploy' },
|
||||
},
|
||||
|
||||
// =====================================================================
|
||||
// COMMON PARAMETERS
|
||||
// =====================================================================
|
||||
{
|
||||
id: 'apiKey',
|
||||
title: 'API Key',
|
||||
type: 'short-input',
|
||||
placeholder: 'Enter your Sentry API token',
|
||||
password: true,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'organizationSlug',
|
||||
title: 'Organization Slug',
|
||||
type: 'short-input',
|
||||
placeholder: 'Your Sentry organization slug',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
tools: {
|
||||
access: [
|
||||
'sentry_issues_list',
|
||||
'sentry_issues_get',
|
||||
'sentry_issues_update',
|
||||
'sentry_projects_list',
|
||||
'sentry_projects_get',
|
||||
'sentry_projects_create',
|
||||
'sentry_projects_update',
|
||||
'sentry_events_list',
|
||||
'sentry_events_get',
|
||||
'sentry_releases_list',
|
||||
'sentry_releases_create',
|
||||
'sentry_releases_deploy',
|
||||
],
|
||||
config: {
|
||||
tool: (params) => {
|
||||
// Convert numeric fields
|
||||
if (params.limit) {
|
||||
params.limit = Number(params.limit)
|
||||
}
|
||||
|
||||
// Return the appropriate tool based on operation
|
||||
switch (params.operation) {
|
||||
case 'sentry_issues_list':
|
||||
return 'sentry_issues_list'
|
||||
case 'sentry_issues_get':
|
||||
return 'sentry_issues_get'
|
||||
case 'sentry_issues_update':
|
||||
return 'sentry_issues_update'
|
||||
case 'sentry_projects_list':
|
||||
return 'sentry_projects_list'
|
||||
case 'sentry_projects_get':
|
||||
return 'sentry_projects_get'
|
||||
case 'sentry_projects_create':
|
||||
return 'sentry_projects_create'
|
||||
case 'sentry_projects_update':
|
||||
return 'sentry_projects_update'
|
||||
case 'sentry_events_list':
|
||||
return 'sentry_events_list'
|
||||
case 'sentry_events_get':
|
||||
return 'sentry_events_get'
|
||||
case 'sentry_releases_list':
|
||||
return 'sentry_releases_list'
|
||||
case 'sentry_releases_create':
|
||||
return 'sentry_releases_create'
|
||||
case 'sentry_releases_deploy':
|
||||
return 'sentry_releases_deploy'
|
||||
default:
|
||||
return 'sentry_issues_list'
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
inputs: {
|
||||
operation: { type: 'string', description: 'Operation to perform' },
|
||||
apiKey: { type: 'string', description: 'Sentry API authentication token' },
|
||||
organizationSlug: { type: 'string', description: 'Organization slug' },
|
||||
// Issue fields
|
||||
issueId: { type: 'string', description: 'Issue ID' },
|
||||
assignedTo: { type: 'string', description: 'User to assign issue to' },
|
||||
isBookmarked: { type: 'boolean', description: 'Bookmark state' },
|
||||
isSubscribed: { type: 'boolean', description: 'Subscription state' },
|
||||
// Project fields
|
||||
projectSlug: { type: 'string', description: 'Project slug' },
|
||||
name: { type: 'string', description: 'Project or deploy name' },
|
||||
teamSlug: { type: 'string', description: 'Team slug' },
|
||||
slug: { type: 'string', description: 'Project slug for creation/update' },
|
||||
platform: { type: 'string', description: 'Platform/language' },
|
||||
defaultRules: { type: 'boolean', description: 'Create default alert rules' },
|
||||
// Event fields
|
||||
eventId: { type: 'string', description: 'Event ID' },
|
||||
// Release fields
|
||||
version: { type: 'string', description: 'Release version' },
|
||||
projects: { type: 'string', description: 'Comma-separated project slugs' },
|
||||
ref: { type: 'string', description: 'Git reference' },
|
||||
url: { type: 'string', description: 'URL' },
|
||||
dateReleased: { type: 'string', description: 'Release date' },
|
||||
commits: { type: 'string', description: 'Commits JSON' },
|
||||
environment: { type: 'string', description: 'Environment name' },
|
||||
dateStarted: { type: 'string', description: 'Deploy start time' },
|
||||
dateFinished: { type: 'string', description: 'Deploy finish time' },
|
||||
// Common fields
|
||||
query: { type: 'string', description: 'Search query' },
|
||||
limit: { type: 'number', description: 'Result limit' },
|
||||
status: { type: 'string', description: 'Status filter' },
|
||||
sort: { type: 'string', description: 'Sort order' },
|
||||
statsPeriod: { type: 'string', description: 'Statistics time period' },
|
||||
},
|
||||
outputs: {
|
||||
// Issue outputs
|
||||
issues: { type: 'json', description: 'List of issues' },
|
||||
issue: { type: 'json', description: 'Single issue details' },
|
||||
// Project outputs
|
||||
projects: { type: 'json', description: 'List of projects' },
|
||||
project: { type: 'json', description: 'Single project details' },
|
||||
// Event outputs
|
||||
events: { type: 'json', description: 'List of events' },
|
||||
event: { type: 'json', description: 'Single event details' },
|
||||
// Release outputs
|
||||
releases: { type: 'json', description: 'List of releases' },
|
||||
release: { type: 'json', description: 'Single release details' },
|
||||
deploy: { type: 'json', description: 'Deploy details' },
|
||||
// Pagination
|
||||
nextCursor: { type: 'string', description: 'Pagination cursor' },
|
||||
hasMore: { type: 'boolean', description: 'More results available' },
|
||||
},
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import { HuggingFaceBlock } from '@/blocks/blocks/huggingface'
|
||||
import { HumanInTheLoopBlock } from '@/blocks/blocks/human_in_the_loop'
|
||||
import { HunterBlock } from '@/blocks/blocks/hunter'
|
||||
import { ImageGeneratorBlock } from '@/blocks/blocks/image_generator'
|
||||
import { IncidentioBlock } from '@/blocks/blocks/incidentio'
|
||||
import { InputTriggerBlock } from '@/blocks/blocks/input_trigger'
|
||||
import { JinaBlock } from '@/blocks/blocks/jina'
|
||||
import { JiraBlock } from '@/blocks/blocks/jira'
|
||||
@@ -61,6 +62,7 @@ import { PerplexityBlock } from '@/blocks/blocks/perplexity'
|
||||
import { PineconeBlock } from '@/blocks/blocks/pinecone'
|
||||
import { PipedriveBlock } from '@/blocks/blocks/pipedrive'
|
||||
import { PostgreSQLBlock } from '@/blocks/blocks/postgresql'
|
||||
import { PostHogBlock } from '@/blocks/blocks/posthog'
|
||||
import { QdrantBlock } from '@/blocks/blocks/qdrant'
|
||||
import { RedditBlock } from '@/blocks/blocks/reddit'
|
||||
import { ResendBlock } from '@/blocks/blocks/resend'
|
||||
@@ -69,6 +71,7 @@ import { RouterBlock } from '@/blocks/blocks/router'
|
||||
import { S3Block } from '@/blocks/blocks/s3'
|
||||
import { SalesforceBlock } from '@/blocks/blocks/salesforce'
|
||||
import { ScheduleBlock } from '@/blocks/blocks/schedule'
|
||||
import { SentryBlock } from '@/blocks/blocks/sentry'
|
||||
import { SerperBlock } from '@/blocks/blocks/serper'
|
||||
import { SharepointBlock } from '@/blocks/blocks/sharepoint'
|
||||
import { SlackBlock } from '@/blocks/blocks/slack'
|
||||
@@ -140,6 +143,7 @@ export const registry: Record<string, BlockConfig> = {
|
||||
human_in_the_loop: HumanInTheLoopBlock,
|
||||
hunter: HunterBlock,
|
||||
image_generator: ImageGeneratorBlock,
|
||||
incidentio: IncidentioBlock,
|
||||
jina: JinaBlock,
|
||||
jira: JiraBlock,
|
||||
knowledge: KnowledgeBlock,
|
||||
@@ -162,6 +166,7 @@ export const registry: Record<string, BlockConfig> = {
|
||||
onedrive: OneDriveBlock,
|
||||
parallel_ai: ParallelBlock,
|
||||
perplexity: PerplexityBlock,
|
||||
posthog: PostHogBlock,
|
||||
pinecone: PineconeBlock,
|
||||
pipedrive: PipedriveBlock,
|
||||
postgresql: PostgreSQLBlock,
|
||||
@@ -174,6 +179,7 @@ export const registry: Record<string, BlockConfig> = {
|
||||
schedule: ScheduleBlock,
|
||||
s3: S3Block,
|
||||
salesforce: SalesforceBlock,
|
||||
sentry: SentryBlock,
|
||||
serper: SerperBlock,
|
||||
sharepoint: SharepointBlock,
|
||||
stagehand: StagehandBlock,
|
||||
|
||||
@@ -4160,3 +4160,86 @@ export function VllmIcon(props: SVGProps<SVGSVGElement>) {
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function PosthogIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
width='50'
|
||||
height='30'
|
||||
viewBox='0 0 50 30'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
d='M10.8914 17.2057c-.3685.7371-1.42031.7371-1.78884 0L8.2212 15.443c-.14077-.2815-.14077-.6129 0-.8944l.88136-1.7627c.36853-.7371 1.42034-.7371 1.78884 0l.8814 1.7627c.1407.2815.1407.6129 0 .8944l-.8814 1.7627zM10.8914 27.2028c-.3685.737-1.42031.737-1.78884 0L8.2212 25.44c-.14077-.2815-.14077-.6129 0-.8944l.88136-1.7627c.36853-.7371 1.42034-.7371 1.78884 0l.8814 1.7627c.1407.2815.1407.6129 0 .8944l-.8814 1.7628z'
|
||||
fill='#1D4AFF'
|
||||
/>
|
||||
<path
|
||||
d='M0 23.4082c0-.8909 1.07714-1.3371 1.70711-.7071l4.58338 4.5834c.62997.63.1838 1.7071-.7071 1.7071H.999999c-.552284 0-.999999-.4477-.999999-1v-4.5834zm0-4.8278c0 .2652.105357.5196.292893.7071l9.411217 9.4112c.18753.1875.44189.2929.70709.2929h5.1692c.8909 0 1.3371-1.0771.7071-1.7071L1.70711 12.7041C1.07714 12.0741 0 12.5203 0 13.4112v5.1692zm0-9.99701c0 .26521.105357.51957.292893.7071L19.7011 28.6987c.1875.1875.4419.2929.7071.2929h5.1692c.8909 0 1.3371-1.0771.7071-1.7071L1.70711 2.70711C1.07715 2.07715 0 2.52331 0 3.41421v5.16918zm9.997 0c0 .26521.1054.51957.2929.7071l17.994 17.99401c.63.63 1.7071.1838 1.7071-.7071v-5.1692c0-.2652-.1054-.5196-.2929-.7071l-17.994-17.994c-.63-.62996-1.7071-.18379-1.7071.70711v5.16918zm11.7041-5.87628c-.63-.62997-1.7071-.1838-1.7071.7071v5.16918c0 .26521.1054.51957.2929.7071l7.997 7.99701c.63.63 1.7071.1838 1.7071-.7071v-5.1692c0-.2652-.1054-.5196-.2929-.7071l-7.997-7.99699z'
|
||||
fill='#F9BD2B'
|
||||
/>
|
||||
<path
|
||||
d='M42.5248 23.5308l-9.4127-9.4127c-.63-.63-1.7071-.1838-1.7071.7071v13.1664c0 .5523.4477 1 1 1h14.5806c.5523 0 1-.4477 1-1v-1.199c0-.5523-.4496-.9934-.9973-1.0647-1.6807-.2188-3.2528-.9864-4.4635-2.1971zm-6.3213 2.2618c-.8829 0-1.5995-.7166-1.5995-1.5996 0-.8829.7166-1.5995 1.5995-1.5995.883 0 1.5996.7166 1.5996 1.5995 0 .883-.7166 1.5996-1.5996 1.5996z'
|
||||
fill='#000'
|
||||
/>
|
||||
<path
|
||||
d='M0 27.9916c0 .5523.447715 1 1 1h4.58339c.8909 0 1.33707-1.0771.70711-1.7071l-4.58339-4.5834C1.07714 22.0711 0 22.5173 0 23.4082v4.5834zM9.997 10.997L1.70711 2.70711C1.07714 2.07714 0 2.52331 0 3.41421v5.16918c0 .26521.105357.51957.292893.7071L9.997 18.9946V10.997zM1.70711 12.7041C1.07714 12.0741 0 12.5203 0 13.4112v5.1692c0 .2652.105357.5196.292893.7071L9.997 28.9916V20.994l-8.28989-8.2899z'
|
||||
fill='#1D4AFF'
|
||||
/>
|
||||
<path
|
||||
d='M19.994 11.4112c0-.2652-.1053-.5196-.2929-.7071l-7.997-7.99699c-.6299-.62997-1.70709-.1838-1.70709.7071v5.16918c0 .26521.10539.51957.29289.7071l9.7041 9.70411v-7.5834zM9.99701 28.9916h5.58339c.8909 0 1.3371-1.0771.7071-1.7071L9.99701 20.994v7.9976zM9.99701 10.997v7.5834c0 .2652.10539.5196.29289.7071l9.7041 9.7041v-7.5834c0-.2652-.1053-.5196-.2929-.7071L9.99701 10.997z'
|
||||
fill='#F54E00'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function SentryIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
width='800px'
|
||||
height='800px'
|
||||
viewBox='0 -14.5 256 256'
|
||||
version='1.1'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
preserveAspectRatio='xMidYMid'
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d='M148.367708,12.4025287 C144.036807,5.21480737 136.258026,0.820118864 127.866362,0.820118864 C119.474697,0.820118864 111.695916,5.21480737 107.365016,12.4025287 L73.6403017,70.165071 C126.066153,96.3390588 160.689085,148.341727 164.615024,206.806542 L140.93597,206.806542 C137.017513,156.694333 106.874845,112.396698 61.6982677,90.3588968 L30.4849684,144.32869 C55.8497707,155.704426 73.6778379,179.211206 77.7918243,206.704035 L23.4120041,206.704035 C22.1018479,206.611361 20.9266153,205.864669 20.2861278,204.71799 C19.6456403,203.571311 19.6261529,202.179068 20.2342955,201.014912 L35.3027847,175.388229 C30.1976229,171.128798 24.3630321,167.829476 18.0816541,165.65009 L3.16692493,191.276772 C0.0305635285,196.656417 -0.818661742,203.068719 0.809210488,209.079324 C2.43708272,215.08993 6.40620885,220.197261 11.8287436,223.258872 C15.3657216,225.251729 19.3523095,226.310116 23.4120041,226.334074 L97.8831433,226.334074 C100.696274,191.620878 85.1423372,157.966047 56.8804514,137.614499 L68.7199787,117.113153 C104.398813,141.618242 124.473737,183.151896 121.510945,226.334074 L184.603837,226.334074 C187.593899,160.904124 155.557278,98.8221906 100.497065,63.3483734 L124.432386,22.3456815 C125.542508,20.4856859 127.944329,19.8680747 129.81399,20.9618406 C132.530418,22.4481882 233.807067,199.169791 235.703442,201.219925 C236.383476,202.439289 236.358897,203.929352 235.639016,205.125624 C234.919136,206.321896 233.614065,207.041397 232.218213,207.011555 L207.821611,207.011555 C208.129131,213.537817 208.129131,220.046994 207.821611,226.539592 L232.32072,226.539592 C238.604421,226.580218 244.643414,224.105731 249.091568,219.667205 C253.539722,215.228679 256.027289,209.195062 256,202.911286 C256.002825,198.802186 254.905596,194.767215 252.822066,191.225519 L148.367708,12.4025287 Z'
|
||||
fill='#362D59'
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function IncidentioIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
width='128'
|
||||
height='163'
|
||||
viewBox='0 0 128 163'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<g clipPath='url(#clip0_1361_12561)'>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M48.7336 139.642V163C20.7585 156.323 0 131.711 0 102.372C0 85.4557 7.15792 72.0354 18.1053 58.8703C27.1831 47.9534 49.5985 19.0426 56.6543 3.08954C58.3673 -0.783473 62.7348 -0.633805 64.6182 1.44721C70.6432 8.10421 78.0694 22.6432 80.4983 39.135C80.9932 42.4953 81.1969 45.2388 81.3587 47.4184C81.706 52.0954 81.8604 54.1748 84.2854 54.1748C88.0955 54.1748 90.588 48.3977 91.1358 42.4345C91.4869 38.6136 95.2774 37.3346 97.8914 38.6136C110.463 44.7644 123.292 74.0426 126.393 88.4102C127.366 92.9158 128 97.5719 128 102.372C128 131.646 107.335 156.214 79.4537 162.955V139.642H48.7336ZM64.0002 130.333C73.8316 130.333 81.8016 122.789 81.8016 113.483C81.8016 98.6407 70.8577 88.0345 65.4048 84.8105C65.0364 84.5928 64.8523 84.4839 64.3512 84.4974C63.9843 84.5073 63.4429 84.7369 63.181 84.9935C62.8232 85.3441 62.7283 85.743 62.5387 86.5409C61.5721 90.6065 58.5292 93.5054 55.327 96.556C50.9141 100.76 46.1988 105.252 46.1988 113.483C46.1988 122.789 54.1688 130.333 64.0002 130.333Z'
|
||||
fill='#F25533'
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id='clip0_1361_12561'>
|
||||
<rect width='128' height='163' fill='white' />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -100,6 +100,42 @@ describe('Error Extractors', () => {
|
||||
expect(extractErrorMessage(errorInfo)).toBe('Email is required')
|
||||
})
|
||||
|
||||
it('should extract plain text error responses', () => {
|
||||
const errorInfo: ErrorInfo = {
|
||||
status: 401,
|
||||
statusText: 'Unauthorized',
|
||||
data: 'Invalid access token',
|
||||
}
|
||||
expect(extractErrorMessage(errorInfo)).toBe('Invalid access token')
|
||||
})
|
||||
|
||||
it('should extract plain text error from APIs like Apollo', () => {
|
||||
const errorInfo: ErrorInfo = {
|
||||
status: 403,
|
||||
statusText: 'Forbidden',
|
||||
data: 'Invalid API key provided',
|
||||
}
|
||||
expect(extractErrorMessage(errorInfo)).toBe('Invalid API key provided')
|
||||
})
|
||||
|
||||
it('should trim whitespace from plain text errors', () => {
|
||||
const errorInfo: ErrorInfo = {
|
||||
status: 400,
|
||||
statusText: 'Bad Request',
|
||||
data: ' Error message with spaces ',
|
||||
}
|
||||
expect(extractErrorMessage(errorInfo)).toBe('Error message with spaces')
|
||||
})
|
||||
|
||||
it('should skip empty plain text and use HTTP status text fallback', () => {
|
||||
const errorInfo: ErrorInfo = {
|
||||
status: 500,
|
||||
statusText: 'Internal Server Error',
|
||||
data: ' ',
|
||||
}
|
||||
expect(extractErrorMessage(errorInfo)).toBe('Internal Server Error')
|
||||
})
|
||||
|
||||
it('should use HTTP status text as fallback', () => {
|
||||
const errorInfo: ErrorInfo = {
|
||||
status: 404,
|
||||
@@ -128,7 +164,6 @@ describe('Error Extractors', () => {
|
||||
message: '',
|
||||
},
|
||||
}
|
||||
// Should skip empty message and use fallback
|
||||
expect(extractErrorMessage(errorInfo)).toBe('Request failed with status 400')
|
||||
})
|
||||
})
|
||||
@@ -143,7 +178,6 @@ describe('Error Extractors', () => {
|
||||
},
|
||||
}
|
||||
|
||||
// With explicit extractor ID, should use Telegram extractor
|
||||
expect(extractErrorMessage(errorInfo, ErrorExtractorId.TELEGRAM_DESCRIPTION)).toBe(
|
||||
"Forbidden: bots can't send messages to bots"
|
||||
)
|
||||
@@ -153,12 +187,11 @@ describe('Error Extractors', () => {
|
||||
const errorInfo: ErrorInfo = {
|
||||
status: 400,
|
||||
data: {
|
||||
errors: [{ message: 'GraphQL error' }], // This would match first normally
|
||||
message: 'Standard message', // Explicitly request this one
|
||||
errors: [{ message: 'GraphQL error' }],
|
||||
message: 'Standard message',
|
||||
},
|
||||
}
|
||||
|
||||
// With explicit ID, should skip GraphQL and use standard message
|
||||
expect(extractErrorMessage(errorInfo, ErrorExtractorId.STANDARD_MESSAGE)).toBe(
|
||||
'Standard message'
|
||||
)
|
||||
@@ -172,7 +205,6 @@ describe('Error Extractors', () => {
|
||||
},
|
||||
}
|
||||
|
||||
// Telegram extractor won't find anything, should fallback
|
||||
expect(extractErrorMessage(errorInfo, ErrorExtractorId.TELEGRAM_DESCRIPTION)).toBe(
|
||||
'Request failed with status 404'
|
||||
)
|
||||
@@ -186,10 +218,21 @@ describe('Error Extractors', () => {
|
||||
},
|
||||
}
|
||||
|
||||
// Non-existent extractor should fallback
|
||||
expect(extractErrorMessage(errorInfo, 'non-existent-extractor')).toBe(
|
||||
'Request failed with status 500'
|
||||
)
|
||||
})
|
||||
|
||||
it('should use plain text extractor when explicitly specified', () => {
|
||||
const errorInfo: ErrorInfo = {
|
||||
status: 403,
|
||||
statusText: 'Forbidden',
|
||||
data: 'Plain text error message',
|
||||
}
|
||||
|
||||
expect(extractErrorMessage(errorInfo, ErrorExtractorId.PLAIN_TEXT_DATA)).toBe(
|
||||
'Plain text error message'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -112,6 +112,18 @@ const ERROR_EXTRACTORS: ErrorExtractorConfig[] = [
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'plain-text-data',
|
||||
description: 'Plain text error response',
|
||||
examples: ['APIs returning plain text errors like Apollo'],
|
||||
extract: (errorInfo) => {
|
||||
// If data is a plain string (not an object), use it directly
|
||||
if (typeof errorInfo?.data === 'string' && errorInfo.data.trim()) {
|
||||
return errorInfo.data.trim()
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'http-status-text',
|
||||
description: 'HTTP response status text fallback',
|
||||
@@ -171,5 +183,6 @@ export const ErrorExtractorId = {
|
||||
SOAP_FAULT: 'soap-fault',
|
||||
OAUTH_ERROR_DESCRIPTION: 'oauth-error-description',
|
||||
NESTED_ERROR_OBJECT: 'nested-error-object',
|
||||
PLAIN_TEXT_DATA: 'plain-text-data',
|
||||
HTTP_STATUS_TEXT: 'http-status-text',
|
||||
} as const
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
import type {
|
||||
IncidentioActionsListParams,
|
||||
IncidentioActionsListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const actionsListTool: ToolConfig<
|
||||
IncidentioActionsListParams,
|
||||
IncidentioActionsListResponse
|
||||
> = {
|
||||
id: 'incidentio_actions_list',
|
||||
name: 'incident.io Actions List',
|
||||
description: 'List actions from incident.io. Optionally filter by incident ID.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
incident_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter actions by incident ID',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Number of actions to return per page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/actions')
|
||||
|
||||
if (params.incident_id) {
|
||||
url.searchParams.append('incident_id', params.incident_id)
|
||||
}
|
||||
|
||||
if (params.page_size) {
|
||||
url.searchParams.append('page_size', params.page_size.toString())
|
||||
}
|
||||
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
actions:
|
||||
data.actions?.map((action: any) => ({
|
||||
id: action.id,
|
||||
description: action.description || '',
|
||||
assignee: action.assignee
|
||||
? {
|
||||
id: action.assignee.id,
|
||||
name: action.assignee.name,
|
||||
email: action.assignee.email,
|
||||
}
|
||||
: undefined,
|
||||
status: action.status,
|
||||
due_at: action.due_at,
|
||||
created_at: action.created_at,
|
||||
updated_at: action.updated_at,
|
||||
incident_id: action.incident_id,
|
||||
creator: action.creator
|
||||
? {
|
||||
id: action.creator.id,
|
||||
name: action.creator.name,
|
||||
email: action.creator.email,
|
||||
}
|
||||
: undefined,
|
||||
completed_at: action.completed_at,
|
||||
external_issue_reference: action.external_issue_reference
|
||||
? {
|
||||
provider: action.external_issue_reference.provider,
|
||||
issue_name: action.external_issue_reference.issue_name,
|
||||
issue_permalink: action.external_issue_reference.issue_permalink,
|
||||
}
|
||||
: undefined,
|
||||
})) || [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
actions: {
|
||||
type: 'array',
|
||||
description: 'List of actions',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Action ID' },
|
||||
description: { type: 'string', description: 'Action description' },
|
||||
assignee: {
|
||||
type: 'object',
|
||||
description: 'Assigned user',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
status: { type: 'string', description: 'Action status' },
|
||||
due_at: { type: 'string', description: 'Due date/time' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
incident_id: { type: 'string', description: 'Associated incident ID' },
|
||||
creator: {
|
||||
type: 'object',
|
||||
description: 'User who created the action',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
completed_at: { type: 'string', description: 'Completion timestamp' },
|
||||
external_issue_reference: {
|
||||
type: 'object',
|
||||
description: 'External issue tracking reference',
|
||||
optional: true,
|
||||
properties: {
|
||||
provider: {
|
||||
type: 'string',
|
||||
description: 'Issue tracking provider (e.g., Jira, Linear)',
|
||||
},
|
||||
issue_name: { type: 'string', description: 'Issue identifier' },
|
||||
issue_permalink: { type: 'string', description: 'URL to the external issue' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import type {
|
||||
IncidentioActionsShowParams,
|
||||
IncidentioActionsShowResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const actionsShowTool: ToolConfig<
|
||||
IncidentioActionsShowParams,
|
||||
IncidentioActionsShowResponse
|
||||
> = {
|
||||
id: 'incidentio_actions_show',
|
||||
name: 'incident.io Actions Show',
|
||||
description: 'Get detailed information about a specific action from incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Action ID',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/actions/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
action: {
|
||||
id: data.action.id,
|
||||
description: data.action.description || '',
|
||||
assignee: data.action.assignee
|
||||
? {
|
||||
id: data.action.assignee.id,
|
||||
name: data.action.assignee.name,
|
||||
email: data.action.assignee.email,
|
||||
}
|
||||
: undefined,
|
||||
status: data.action.status,
|
||||
due_at: data.action.due_at,
|
||||
created_at: data.action.created_at,
|
||||
updated_at: data.action.updated_at,
|
||||
incident_id: data.action.incident_id,
|
||||
creator: data.action.creator
|
||||
? {
|
||||
id: data.action.creator.id,
|
||||
name: data.action.creator.name,
|
||||
email: data.action.creator.email,
|
||||
}
|
||||
: undefined,
|
||||
completed_at: data.action.completed_at,
|
||||
external_issue_reference: data.action.external_issue_reference
|
||||
? {
|
||||
provider: data.action.external_issue_reference.provider,
|
||||
issue_name: data.action.external_issue_reference.issue_name,
|
||||
issue_permalink: data.action.external_issue_reference.issue_permalink,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
action: {
|
||||
type: 'object',
|
||||
description: 'Action details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Action ID' },
|
||||
description: { type: 'string', description: 'Action description' },
|
||||
assignee: {
|
||||
type: 'object',
|
||||
description: 'Assigned user',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
status: { type: 'string', description: 'Action status' },
|
||||
due_at: { type: 'string', description: 'Due date/time' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
incident_id: { type: 'string', description: 'Associated incident ID' },
|
||||
creator: {
|
||||
type: 'object',
|
||||
description: 'User who created the action',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
completed_at: { type: 'string', description: 'Completion timestamp' },
|
||||
external_issue_reference: {
|
||||
type: 'object',
|
||||
description: 'External issue tracking reference',
|
||||
optional: true,
|
||||
properties: {
|
||||
provider: {
|
||||
type: 'string',
|
||||
description: 'Issue tracking provider (e.g., Jira, Linear)',
|
||||
},
|
||||
issue_name: { type: 'string', description: 'Issue identifier' },
|
||||
issue_permalink: { type: 'string', description: 'URL to the external issue' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import type { CustomFieldsCreateParams, CustomFieldsCreateResponse } from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const customFieldsCreateTool: ToolConfig<
|
||||
CustomFieldsCreateParams,
|
||||
CustomFieldsCreateResponse
|
||||
> = {
|
||||
id: 'incidentio_custom_fields_create',
|
||||
name: 'incident.io Custom Fields Create',
|
||||
description: 'Create a new custom field in incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the custom field',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Description of the custom field (required)',
|
||||
},
|
||||
field_type: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Type of the custom field (e.g., text, single_select, multi_select, numeric, datetime, link, user, team)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/custom_fields',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
return {
|
||||
name: params.name,
|
||||
field_type: params.field_type,
|
||||
description: params.description,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
custom_field: {
|
||||
id: data.custom_field.id,
|
||||
name: data.custom_field.name,
|
||||
description: data.custom_field.description,
|
||||
field_type: data.custom_field.field_type,
|
||||
created_at: data.custom_field.created_at,
|
||||
updated_at: data.custom_field.updated_at,
|
||||
options: data.custom_field.options,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
custom_field: {
|
||||
type: 'object',
|
||||
description: 'Created custom field',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Custom field ID' },
|
||||
name: { type: 'string', description: 'Custom field name' },
|
||||
description: { type: 'string', description: 'Custom field description' },
|
||||
field_type: { type: 'string', description: 'Custom field type' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import type { CustomFieldsDeleteParams, CustomFieldsDeleteResponse } from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const customFieldsDeleteTool: ToolConfig<
|
||||
CustomFieldsDeleteParams,
|
||||
CustomFieldsDeleteResponse
|
||||
> = {
|
||||
id: 'incidentio_custom_fields_delete',
|
||||
name: 'incident.io Custom Fields Delete',
|
||||
description: 'Delete a custom field from incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Custom field ID',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/custom_fields/${params.id}`,
|
||||
method: 'DELETE',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: 'Custom field successfully deleted',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'Success message',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import type { CustomFieldsListParams, CustomFieldsListResponse } from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const customFieldsListTool: ToolConfig<CustomFieldsListParams, CustomFieldsListResponse> = {
|
||||
id: 'incidentio_custom_fields_list',
|
||||
name: 'incident.io Custom Fields List',
|
||||
description: 'List all custom fields from incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/custom_fields',
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
custom_fields: data.custom_fields.map((field: any) => ({
|
||||
id: field.id,
|
||||
name: field.name,
|
||||
description: field.description,
|
||||
field_type: field.field_type,
|
||||
created_at: field.created_at,
|
||||
updated_at: field.updated_at,
|
||||
options: field.options,
|
||||
})),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
custom_fields: {
|
||||
type: 'array',
|
||||
description: 'List of custom fields',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Custom field ID' },
|
||||
name: { type: 'string', description: 'Custom field name' },
|
||||
description: { type: 'string', description: 'Custom field description' },
|
||||
field_type: { type: 'string', description: 'Custom field type' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import type { CustomFieldsShowParams, CustomFieldsShowResponse } from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const customFieldsShowTool: ToolConfig<CustomFieldsShowParams, CustomFieldsShowResponse> = {
|
||||
id: 'incidentio_custom_fields_show',
|
||||
name: 'incident.io Custom Fields Show',
|
||||
description: 'Get detailed information about a specific custom field from incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Custom field ID',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/custom_fields/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
custom_field: {
|
||||
id: data.custom_field.id,
|
||||
name: data.custom_field.name,
|
||||
description: data.custom_field.description,
|
||||
field_type: data.custom_field.field_type,
|
||||
created_at: data.custom_field.created_at,
|
||||
updated_at: data.custom_field.updated_at,
|
||||
options: data.custom_field.options,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
custom_field: {
|
||||
type: 'object',
|
||||
description: 'Custom field details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Custom field ID' },
|
||||
name: { type: 'string', description: 'Custom field name' },
|
||||
description: { type: 'string', description: 'Custom field description' },
|
||||
field_type: { type: 'string', description: 'Custom field type' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import type { CustomFieldsUpdateParams, CustomFieldsUpdateResponse } from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const customFieldsUpdateTool: ToolConfig<
|
||||
CustomFieldsUpdateParams,
|
||||
CustomFieldsUpdateResponse
|
||||
> = {
|
||||
id: 'incidentio_custom_fields_update',
|
||||
name: 'incident.io Custom Fields Update',
|
||||
description: 'Update an existing custom field in incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Custom field ID',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New name for the custom field (required)',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New description for the custom field (required)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/custom_fields/${params.id}`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
name: params.name,
|
||||
description: params.description,
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
custom_field: {
|
||||
id: data.custom_field.id,
|
||||
name: data.custom_field.name,
|
||||
description: data.custom_field.description,
|
||||
field_type: data.custom_field.field_type,
|
||||
created_at: data.custom_field.created_at,
|
||||
updated_at: data.custom_field.updated_at,
|
||||
options: data.custom_field.options,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
custom_field: {
|
||||
type: 'object',
|
||||
description: 'Updated custom field',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Custom field ID' },
|
||||
name: { type: 'string', description: 'Custom field name' },
|
||||
description: { type: 'string', description: 'Custom field description' },
|
||||
field_type: { type: 'string', description: 'Custom field type' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
import type {
|
||||
IncidentioEscalationPathsCreateParams,
|
||||
IncidentioEscalationPathsCreateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const escalationPathsCreateTool: ToolConfig<
|
||||
IncidentioEscalationPathsCreateParams,
|
||||
IncidentioEscalationPathsCreateResponse
|
||||
> = {
|
||||
id: 'incidentio_escalation_paths_create',
|
||||
name: 'Create Escalation Path',
|
||||
description: 'Create a new escalation path in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the escalation path',
|
||||
},
|
||||
path: {
|
||||
type: 'json',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Array of escalation levels with targets and time to acknowledge in seconds. Each level should have: targets (array of {id, type, schedule_id?, user_id?, urgency}) and time_to_ack_seconds (number)',
|
||||
},
|
||||
working_hours: {
|
||||
type: 'json',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Optional working hours configuration. Array of {weekday, start_time, end_time}',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/escalation_paths',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
name: params.name,
|
||||
path: params.path,
|
||||
}
|
||||
|
||||
if (params.working_hours) {
|
||||
body.working_hours = params.working_hours
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
escalation_path: data.escalation_path || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
escalation_path: {
|
||||
type: 'object',
|
||||
description: 'The created escalation path',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The escalation path ID' },
|
||||
name: { type: 'string', description: 'The escalation path name' },
|
||||
path: {
|
||||
type: 'array',
|
||||
description: 'Array of escalation levels',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
targets: {
|
||||
type: 'array',
|
||||
description: 'Targets for this level',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Target ID' },
|
||||
type: { type: 'string', description: 'Target type' },
|
||||
schedule_id: {
|
||||
type: 'string',
|
||||
description: 'Schedule ID if type is schedule',
|
||||
optional: true,
|
||||
},
|
||||
user_id: {
|
||||
type: 'string',
|
||||
description: 'User ID if type is user',
|
||||
optional: true,
|
||||
},
|
||||
urgency: { type: 'string', description: 'Urgency level' },
|
||||
},
|
||||
},
|
||||
},
|
||||
time_to_ack_seconds: {
|
||||
type: 'number',
|
||||
description: 'Time to acknowledge in seconds',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
working_hours: {
|
||||
type: 'array',
|
||||
description: 'Working hours configuration',
|
||||
optional: true,
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
weekday: { type: 'string', description: 'Day of week' },
|
||||
start_time: { type: 'string', description: 'Start time' },
|
||||
end_time: { type: 'string', description: 'End time' },
|
||||
},
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'When the path was created' },
|
||||
updated_at: { type: 'string', description: 'When the path was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import type {
|
||||
IncidentioEscalationPathsDeleteParams,
|
||||
IncidentioEscalationPathsDeleteResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const escalationPathsDeleteTool: ToolConfig<
|
||||
IncidentioEscalationPathsDeleteParams,
|
||||
IncidentioEscalationPathsDeleteResponse
|
||||
> = {
|
||||
id: 'incidentio_escalation_paths_delete',
|
||||
name: 'Delete Escalation Path',
|
||||
description: 'Delete an escalation path in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the escalation path to delete',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id}`,
|
||||
method: 'DELETE',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: 'Escalation path deleted successfully',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'Success message',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
import type {
|
||||
IncidentioEscalationPathsShowParams,
|
||||
IncidentioEscalationPathsShowResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const escalationPathsShowTool: ToolConfig<
|
||||
IncidentioEscalationPathsShowParams,
|
||||
IncidentioEscalationPathsShowResponse
|
||||
> = {
|
||||
id: 'incidentio_escalation_paths_show',
|
||||
name: 'Show Escalation Path',
|
||||
description: 'Get details of a specific escalation path in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the escalation path',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
escalation_path: data.escalation_path || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
escalation_path: {
|
||||
type: 'object',
|
||||
description: 'The escalation path details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The escalation path ID' },
|
||||
name: { type: 'string', description: 'The escalation path name' },
|
||||
path: {
|
||||
type: 'array',
|
||||
description: 'Array of escalation levels',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
targets: {
|
||||
type: 'array',
|
||||
description: 'Targets for this level',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Target ID' },
|
||||
type: { type: 'string', description: 'Target type' },
|
||||
schedule_id: {
|
||||
type: 'string',
|
||||
description: 'Schedule ID if type is schedule',
|
||||
optional: true,
|
||||
},
|
||||
user_id: {
|
||||
type: 'string',
|
||||
description: 'User ID if type is user',
|
||||
optional: true,
|
||||
},
|
||||
urgency: { type: 'string', description: 'Urgency level' },
|
||||
},
|
||||
},
|
||||
},
|
||||
time_to_ack_seconds: {
|
||||
type: 'number',
|
||||
description: 'Time to acknowledge in seconds',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
working_hours: {
|
||||
type: 'array',
|
||||
description: 'Working hours configuration',
|
||||
optional: true,
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
weekday: { type: 'string', description: 'Day of week' },
|
||||
start_time: { type: 'string', description: 'Start time' },
|
||||
end_time: { type: 'string', description: 'End time' },
|
||||
},
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'When the path was created' },
|
||||
updated_at: { type: 'string', description: 'When the path was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
import type {
|
||||
IncidentioEscalationPathsUpdateParams,
|
||||
IncidentioEscalationPathsUpdateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const escalationPathsUpdateTool: ToolConfig<
|
||||
IncidentioEscalationPathsUpdateParams,
|
||||
IncidentioEscalationPathsUpdateResponse
|
||||
> = {
|
||||
id: 'incidentio_escalation_paths_update',
|
||||
name: 'Update Escalation Path',
|
||||
description: 'Update an existing escalation path in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the escalation path to update',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New name for the escalation path',
|
||||
},
|
||||
path: {
|
||||
type: 'json',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'New escalation path configuration. Array of escalation levels with targets and time_to_ack_seconds',
|
||||
},
|
||||
working_hours: {
|
||||
type: 'json',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New working hours configuration. Array of {weekday, start_time, end_time}',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id}`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {}
|
||||
|
||||
if (params.name !== undefined) {
|
||||
body.name = params.name
|
||||
}
|
||||
|
||||
if (params.path !== undefined) {
|
||||
body.path = params.path
|
||||
}
|
||||
|
||||
if (params.working_hours !== undefined) {
|
||||
body.working_hours = params.working_hours
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
escalation_path: data.escalation_path || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
escalation_path: {
|
||||
type: 'object',
|
||||
description: 'The updated escalation path',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The escalation path ID' },
|
||||
name: { type: 'string', description: 'The escalation path name' },
|
||||
path: {
|
||||
type: 'array',
|
||||
description: 'Array of escalation levels',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
targets: {
|
||||
type: 'array',
|
||||
description: 'Targets for this level',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Target ID' },
|
||||
type: { type: 'string', description: 'Target type' },
|
||||
schedule_id: {
|
||||
type: 'string',
|
||||
description: 'Schedule ID if type is schedule',
|
||||
optional: true,
|
||||
},
|
||||
user_id: {
|
||||
type: 'string',
|
||||
description: 'User ID if type is user',
|
||||
optional: true,
|
||||
},
|
||||
urgency: { type: 'string', description: 'Urgency level' },
|
||||
},
|
||||
},
|
||||
},
|
||||
time_to_ack_seconds: {
|
||||
type: 'number',
|
||||
description: 'Time to acknowledge in seconds',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
working_hours: {
|
||||
type: 'array',
|
||||
description: 'Working hours configuration',
|
||||
optional: true,
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
weekday: { type: 'string', description: 'Day of week' },
|
||||
start_time: { type: 'string', description: 'Start time' },
|
||||
end_time: { type: 'string', description: 'End time' },
|
||||
},
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'When the path was created' },
|
||||
updated_at: { type: 'string', description: 'When the path was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import type {
|
||||
IncidentioEscalationsCreateParams,
|
||||
IncidentioEscalationsCreateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const escalationsCreateTool: ToolConfig<
|
||||
IncidentioEscalationsCreateParams,
|
||||
IncidentioEscalationsCreateResponse
|
||||
> = {
|
||||
id: 'incidentio_escalations_create',
|
||||
name: 'Create Escalation',
|
||||
description: 'Create a new escalation policy in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
idempotency_key: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Unique identifier to prevent duplicate escalation creation. Use a UUID or unique string.',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Title of the escalation',
|
||||
},
|
||||
escalation_path_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the escalation path to use (required if user_ids not provided)',
|
||||
},
|
||||
user_ids: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Comma-separated list of user IDs to notify (required if escalation_path_id not provided)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/escalations',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
idempotency_key: params.idempotency_key,
|
||||
title: params.title,
|
||||
}
|
||||
|
||||
if (params.escalation_path_id) {
|
||||
body.escalation_path_id = params.escalation_path_id
|
||||
}
|
||||
|
||||
if (params.user_ids) {
|
||||
body.user_ids = params.user_ids.split(',').map((id: string) => id.trim())
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
escalation: data.escalation || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
escalation: {
|
||||
type: 'object',
|
||||
description: 'The created escalation policy',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The escalation policy ID' },
|
||||
name: { type: 'string', description: 'The escalation policy name' },
|
||||
created_at: { type: 'string', description: 'When the escalation policy was created' },
|
||||
updated_at: { type: 'string', description: 'When the escalation policy was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import type {
|
||||
IncidentioEscalationsListParams,
|
||||
IncidentioEscalationsListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const escalationsListTool: ToolConfig<
|
||||
IncidentioEscalationsListParams,
|
||||
IncidentioEscalationsListResponse
|
||||
> = {
|
||||
id: 'incidentio_escalations_list',
|
||||
name: 'List Escalations',
|
||||
description: 'List all escalation policies in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Number of results per page (default: 25)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/escalations')
|
||||
if (params.page_size) {
|
||||
url.searchParams.append('page_size', params.page_size.toString())
|
||||
}
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
escalations: data.escalations || [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
escalations: {
|
||||
type: 'array',
|
||||
description: 'List of escalation policies',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The escalation policy ID' },
|
||||
name: { type: 'string', description: 'The escalation policy name' },
|
||||
created_at: { type: 'string', description: 'When the escalation policy was created' },
|
||||
updated_at: {
|
||||
type: 'string',
|
||||
description: 'When the escalation policy was last updated',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import type {
|
||||
IncidentioEscalationsShowParams,
|
||||
IncidentioEscalationsShowResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const escalationsShowTool: ToolConfig<
|
||||
IncidentioEscalationsShowParams,
|
||||
IncidentioEscalationsShowResponse
|
||||
> = {
|
||||
id: 'incidentio_escalations_show',
|
||||
name: 'Show Escalation',
|
||||
description: 'Get details of a specific escalation policy in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the escalation policy',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/escalations/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
escalation: data.escalation || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
escalation: {
|
||||
type: 'object',
|
||||
description: 'The escalation policy details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The escalation policy ID' },
|
||||
name: { type: 'string', description: 'The escalation policy name' },
|
||||
created_at: { type: 'string', description: 'When the escalation policy was created' },
|
||||
updated_at: { type: 'string', description: 'When the escalation policy was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
import type {
|
||||
IncidentioFollowUpsListParams,
|
||||
IncidentioFollowUpsListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const followUpsListTool: ToolConfig<
|
||||
IncidentioFollowUpsListParams,
|
||||
IncidentioFollowUpsListResponse
|
||||
> = {
|
||||
id: 'incidentio_follow_ups_list',
|
||||
name: 'incident.io Follow-ups List',
|
||||
description: 'List follow-ups from incident.io. Optionally filter by incident ID.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
incident_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter follow-ups by incident ID',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Number of follow-ups to return per page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/follow_ups')
|
||||
|
||||
if (params.incident_id) {
|
||||
url.searchParams.append('incident_id', params.incident_id)
|
||||
}
|
||||
|
||||
if (params.page_size) {
|
||||
url.searchParams.append('page_size', params.page_size.toString())
|
||||
}
|
||||
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
follow_ups:
|
||||
data.follow_ups?.map((followUp: any) => ({
|
||||
id: followUp.id,
|
||||
title: followUp.title || '',
|
||||
description: followUp.description,
|
||||
assignee: followUp.assignee
|
||||
? {
|
||||
id: followUp.assignee.id,
|
||||
name: followUp.assignee.name,
|
||||
email: followUp.assignee.email,
|
||||
}
|
||||
: undefined,
|
||||
status: followUp.status,
|
||||
priority: followUp.priority
|
||||
? {
|
||||
id: followUp.priority.id,
|
||||
name: followUp.priority.name,
|
||||
description: followUp.priority.description,
|
||||
rank: followUp.priority.rank,
|
||||
}
|
||||
: undefined,
|
||||
created_at: followUp.created_at,
|
||||
updated_at: followUp.updated_at,
|
||||
incident_id: followUp.incident_id,
|
||||
creator: followUp.creator
|
||||
? {
|
||||
id: followUp.creator.id,
|
||||
name: followUp.creator.name,
|
||||
email: followUp.creator.email,
|
||||
}
|
||||
: undefined,
|
||||
completed_at: followUp.completed_at,
|
||||
labels: followUp.labels || [],
|
||||
external_issue_reference: followUp.external_issue_reference
|
||||
? {
|
||||
provider: followUp.external_issue_reference.provider,
|
||||
issue_name: followUp.external_issue_reference.issue_name,
|
||||
issue_permalink: followUp.external_issue_reference.issue_permalink,
|
||||
}
|
||||
: undefined,
|
||||
})) || [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
follow_ups: {
|
||||
type: 'array',
|
||||
description: 'List of follow-ups',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Follow-up ID' },
|
||||
title: { type: 'string', description: 'Follow-up title' },
|
||||
description: { type: 'string', description: 'Follow-up description' },
|
||||
assignee: {
|
||||
type: 'object',
|
||||
description: 'Assigned user',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
status: { type: 'string', description: 'Follow-up status' },
|
||||
priority: {
|
||||
type: 'object',
|
||||
description: 'Follow-up priority',
|
||||
optional: true,
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Priority ID' },
|
||||
name: { type: 'string', description: 'Priority name' },
|
||||
description: { type: 'string', description: 'Priority description' },
|
||||
rank: { type: 'number', description: 'Priority rank' },
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
incident_id: { type: 'string', description: 'Associated incident ID' },
|
||||
creator: {
|
||||
type: 'object',
|
||||
description: 'User who created the follow-up',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
completed_at: { type: 'string', description: 'Completion timestamp' },
|
||||
labels: {
|
||||
type: 'array',
|
||||
description: 'Labels associated with the follow-up',
|
||||
items: { type: 'string' },
|
||||
},
|
||||
external_issue_reference: {
|
||||
type: 'object',
|
||||
description: 'External issue tracking reference',
|
||||
properties: {
|
||||
provider: { type: 'string', description: 'External provider name' },
|
||||
issue_name: { type: 'string', description: 'External issue name or ID' },
|
||||
issue_permalink: { type: 'string', description: 'Permalink to external issue' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import type {
|
||||
IncidentioFollowUpsShowParams,
|
||||
IncidentioFollowUpsShowResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const followUpsShowTool: ToolConfig<
|
||||
IncidentioFollowUpsShowParams,
|
||||
IncidentioFollowUpsShowResponse
|
||||
> = {
|
||||
id: 'incidentio_follow_ups_show',
|
||||
name: 'incident.io Follow-ups Show',
|
||||
description: 'Get detailed information about a specific follow-up from incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Follow-up ID',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/follow_ups/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
follow_up: {
|
||||
id: data.follow_up.id,
|
||||
title: data.follow_up.title || '',
|
||||
description: data.follow_up.description,
|
||||
assignee: data.follow_up.assignee
|
||||
? {
|
||||
id: data.follow_up.assignee.id,
|
||||
name: data.follow_up.assignee.name,
|
||||
email: data.follow_up.assignee.email,
|
||||
}
|
||||
: undefined,
|
||||
status: data.follow_up.status,
|
||||
priority: data.follow_up.priority
|
||||
? {
|
||||
id: data.follow_up.priority.id,
|
||||
name: data.follow_up.priority.name,
|
||||
description: data.follow_up.priority.description,
|
||||
rank: data.follow_up.priority.rank,
|
||||
}
|
||||
: undefined,
|
||||
created_at: data.follow_up.created_at,
|
||||
updated_at: data.follow_up.updated_at,
|
||||
incident_id: data.follow_up.incident_id,
|
||||
creator: data.follow_up.creator
|
||||
? {
|
||||
id: data.follow_up.creator.id,
|
||||
name: data.follow_up.creator.name,
|
||||
email: data.follow_up.creator.email,
|
||||
}
|
||||
: undefined,
|
||||
completed_at: data.follow_up.completed_at,
|
||||
labels: data.follow_up.labels || [],
|
||||
external_issue_reference: data.follow_up.external_issue_reference
|
||||
? {
|
||||
provider: data.follow_up.external_issue_reference.provider,
|
||||
issue_name: data.follow_up.external_issue_reference.issue_name,
|
||||
issue_permalink: data.follow_up.external_issue_reference.issue_permalink,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
follow_up: {
|
||||
type: 'object',
|
||||
description: 'Follow-up details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Follow-up ID' },
|
||||
title: { type: 'string', description: 'Follow-up title' },
|
||||
description: { type: 'string', description: 'Follow-up description' },
|
||||
assignee: {
|
||||
type: 'object',
|
||||
description: 'Assigned user',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
status: { type: 'string', description: 'Follow-up status' },
|
||||
priority: {
|
||||
type: 'object',
|
||||
description: 'Follow-up priority',
|
||||
optional: true,
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Priority ID' },
|
||||
name: { type: 'string', description: 'Priority name' },
|
||||
description: { type: 'string', description: 'Priority description' },
|
||||
rank: { type: 'number', description: 'Priority rank' },
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
incident_id: { type: 'string', description: 'Associated incident ID' },
|
||||
creator: {
|
||||
type: 'object',
|
||||
description: 'User who created the follow-up',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
completed_at: { type: 'string', description: 'Completion timestamp' },
|
||||
labels: {
|
||||
type: 'array',
|
||||
description: 'Labels associated with the follow-up',
|
||||
items: { type: 'string' },
|
||||
},
|
||||
external_issue_reference: {
|
||||
type: 'object',
|
||||
description: 'External issue tracking reference',
|
||||
properties: {
|
||||
provider: { type: 'string', description: 'External provider name' },
|
||||
issue_name: { type: 'string', description: 'External issue name or ID' },
|
||||
issue_permalink: { type: 'string', description: 'Permalink to external issue' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import type {
|
||||
IncidentioIncidentRolesCreateParams,
|
||||
IncidentioIncidentRolesCreateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentRolesCreateTool: ToolConfig<
|
||||
IncidentioIncidentRolesCreateParams,
|
||||
IncidentioIncidentRolesCreateResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_roles_create',
|
||||
name: 'Create Incident Role',
|
||||
description: 'Create a new incident role in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the incident role',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Description of the incident role',
|
||||
},
|
||||
instructions: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Instructions for the incident role',
|
||||
},
|
||||
shortform: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Short form abbreviation for the role',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/incident_roles',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => ({
|
||||
name: params.name,
|
||||
description: params.description,
|
||||
instructions: params.instructions,
|
||||
shortform: params.shortform,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident_role: data.incident_role || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident_role: {
|
||||
type: 'object',
|
||||
description: 'The created incident role',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The incident role ID' },
|
||||
name: { type: 'string', description: 'The incident role name' },
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'The incident role description',
|
||||
optional: true,
|
||||
},
|
||||
instructions: {
|
||||
type: 'string',
|
||||
description: 'Instructions for the role',
|
||||
},
|
||||
shortform: {
|
||||
type: 'string',
|
||||
description: 'Short form abbreviation of the role',
|
||||
},
|
||||
role_type: { type: 'string', description: 'The type of role' },
|
||||
required: { type: 'boolean', description: 'Whether the role is required' },
|
||||
created_at: { type: 'string', description: 'When the role was created' },
|
||||
updated_at: { type: 'string', description: 'When the role was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import type {
|
||||
IncidentioIncidentRolesDeleteParams,
|
||||
IncidentioIncidentRolesDeleteResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentRolesDeleteTool: ToolConfig<
|
||||
IncidentioIncidentRolesDeleteParams,
|
||||
IncidentioIncidentRolesDeleteResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_roles_delete',
|
||||
name: 'Delete Incident Role',
|
||||
description: 'Delete an incident role in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the incident role to delete',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incident_roles/${params.id}`,
|
||||
method: 'DELETE',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: 'Incident role deleted successfully',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'Success message',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import type {
|
||||
IncidentioIncidentRolesListParams,
|
||||
IncidentioIncidentRolesListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentRolesListTool: ToolConfig<
|
||||
IncidentioIncidentRolesListParams,
|
||||
IncidentioIncidentRolesListResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_roles_list',
|
||||
name: 'List Incident Roles',
|
||||
description: 'List all incident roles in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/incident_roles',
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident_roles: data.incident_roles || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident_roles: {
|
||||
type: 'array',
|
||||
description: 'List of incident roles',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The incident role ID' },
|
||||
name: { type: 'string', description: 'The incident role name' },
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'The incident role description',
|
||||
optional: true,
|
||||
},
|
||||
instructions: {
|
||||
type: 'string',
|
||||
description: 'Instructions for the role',
|
||||
},
|
||||
shortform: {
|
||||
type: 'string',
|
||||
description: 'Short form abbreviation of the role',
|
||||
},
|
||||
role_type: { type: 'string', description: 'The type of role' },
|
||||
required: { type: 'boolean', description: 'Whether the role is required' },
|
||||
created_at: { type: 'string', description: 'When the role was created' },
|
||||
updated_at: { type: 'string', description: 'When the role was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import type {
|
||||
IncidentioIncidentRolesShowParams,
|
||||
IncidentioIncidentRolesShowResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentRolesShowTool: ToolConfig<
|
||||
IncidentioIncidentRolesShowParams,
|
||||
IncidentioIncidentRolesShowResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_roles_show',
|
||||
name: 'Show Incident Role',
|
||||
description: 'Get details of a specific incident role in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the incident role',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incident_roles/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident_role: data.incident_role || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident_role: {
|
||||
type: 'object',
|
||||
description: 'The incident role details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The incident role ID' },
|
||||
name: { type: 'string', description: 'The incident role name' },
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'The incident role description',
|
||||
optional: true,
|
||||
},
|
||||
instructions: {
|
||||
type: 'string',
|
||||
description: 'Instructions for the role',
|
||||
},
|
||||
shortform: {
|
||||
type: 'string',
|
||||
description: 'Short form abbreviation of the role',
|
||||
},
|
||||
role_type: { type: 'string', description: 'The type of role' },
|
||||
required: { type: 'boolean', description: 'Whether the role is required' },
|
||||
created_at: { type: 'string', description: 'When the role was created' },
|
||||
updated_at: { type: 'string', description: 'When the role was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import type {
|
||||
IncidentioIncidentRolesUpdateParams,
|
||||
IncidentioIncidentRolesUpdateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentRolesUpdateTool: ToolConfig<
|
||||
IncidentioIncidentRolesUpdateParams,
|
||||
IncidentioIncidentRolesUpdateResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_roles_update',
|
||||
name: 'Update Incident Role',
|
||||
description: 'Update an existing incident role in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the incident role to update',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the incident role',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Description of the incident role',
|
||||
},
|
||||
instructions: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Instructions for the incident role',
|
||||
},
|
||||
shortform: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Short form abbreviation for the role',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incident_roles/${params.id}`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => ({
|
||||
name: params.name,
|
||||
description: params.description,
|
||||
instructions: params.instructions,
|
||||
shortform: params.shortform,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident_role: data.incident_role || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident_role: {
|
||||
type: 'object',
|
||||
description: 'The updated incident role',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The incident role ID' },
|
||||
name: { type: 'string', description: 'The incident role name' },
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'The incident role description',
|
||||
optional: true,
|
||||
},
|
||||
instructions: {
|
||||
type: 'string',
|
||||
description: 'Instructions for the role',
|
||||
},
|
||||
shortform: {
|
||||
type: 'string',
|
||||
description: 'Short form abbreviation of the role',
|
||||
},
|
||||
role_type: { type: 'string', description: 'The type of role' },
|
||||
required: { type: 'boolean', description: 'Whether the role is required' },
|
||||
created_at: { type: 'string', description: 'When the role was created' },
|
||||
updated_at: { type: 'string', description: 'When the role was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type {
|
||||
IncidentioIncidentStatusesListParams,
|
||||
IncidentioIncidentStatusesListResponse,
|
||||
} from './types'
|
||||
|
||||
export const incidentStatusesListTool: ToolConfig<
|
||||
IncidentioIncidentStatusesListParams,
|
||||
IncidentioIncidentStatusesListResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_statuses_list',
|
||||
name: 'Incident.io Incident Statuses List',
|
||||
description:
|
||||
'List all incident statuses configured in your Incident.io workspace. Returns status details including id, name, description, and category.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Incident.io API Key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v1/incident_statuses',
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident_statuses: data.incident_statuses.map((status: any) => ({
|
||||
id: status.id,
|
||||
name: status.name,
|
||||
description: status.description,
|
||||
category: status.category,
|
||||
})),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident_statuses: {
|
||||
type: 'array',
|
||||
description: 'List of incident statuses',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the incident status' },
|
||||
name: { type: 'string', description: 'Name of the incident status' },
|
||||
description: { type: 'string', description: 'Description of the incident status' },
|
||||
category: { type: 'string', description: 'Category of the incident status' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import type {
|
||||
IncidentioIncidentTimestampsListParams,
|
||||
IncidentioIncidentTimestampsListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentTimestampsListTool: ToolConfig<
|
||||
IncidentioIncidentTimestampsListParams,
|
||||
IncidentioIncidentTimestampsListResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_timestamps_list',
|
||||
name: 'List Incident Timestamps',
|
||||
description: 'List all incident timestamp definitions in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/incident_timestamps',
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident_timestamps: data.incident_timestamps || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident_timestamps: {
|
||||
type: 'array',
|
||||
description: 'List of incident timestamp definitions',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The timestamp ID' },
|
||||
name: { type: 'string', description: 'The timestamp name' },
|
||||
rank: { type: 'number', description: 'The rank/order of the timestamp' },
|
||||
created_at: { type: 'string', description: 'When the timestamp was created' },
|
||||
updated_at: { type: 'string', description: 'When the timestamp was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import type {
|
||||
IncidentioIncidentTimestampsShowParams,
|
||||
IncidentioIncidentTimestampsShowResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentTimestampsShowTool: ToolConfig<
|
||||
IncidentioIncidentTimestampsShowParams,
|
||||
IncidentioIncidentTimestampsShowResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_timestamps_show',
|
||||
name: 'Show Incident Timestamp',
|
||||
description: 'Get details of a specific incident timestamp definition in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the incident timestamp',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incident_timestamps/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident_timestamp: data.incident_timestamp || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident_timestamp: {
|
||||
type: 'object',
|
||||
description: 'The incident timestamp details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The timestamp ID' },
|
||||
name: { type: 'string', description: 'The timestamp name' },
|
||||
rank: { type: 'number', description: 'The rank/order of the timestamp' },
|
||||
created_at: { type: 'string', description: 'When the timestamp was created' },
|
||||
updated_at: { type: 'string', description: 'When the timestamp was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type {
|
||||
IncidentioIncidentTypesListParams,
|
||||
IncidentioIncidentTypesListResponse,
|
||||
} from './types'
|
||||
|
||||
export const incidentTypesListTool: ToolConfig<
|
||||
IncidentioIncidentTypesListParams,
|
||||
IncidentioIncidentTypesListResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_types_list',
|
||||
name: 'Incident.io Incident Types List',
|
||||
description:
|
||||
'List all incident types configured in your Incident.io workspace. Returns type details including id, name, description, and default flag.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Incident.io API Key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v1/incident_types',
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident_types: data.incident_types.map((type: any) => ({
|
||||
id: type.id,
|
||||
name: type.name,
|
||||
description: type.description,
|
||||
is_default: type.is_default,
|
||||
})),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident_types: {
|
||||
type: 'array',
|
||||
description: 'List of incident types',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the incident type' },
|
||||
name: { type: 'string', description: 'Name of the incident type' },
|
||||
description: { type: 'string', description: 'Description of the incident type' },
|
||||
is_default: {
|
||||
type: 'boolean',
|
||||
description: 'Whether this is the default incident type',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
import type {
|
||||
IncidentioIncidentUpdatesListParams,
|
||||
IncidentioIncidentUpdatesListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentUpdatesListTool: ToolConfig<
|
||||
IncidentioIncidentUpdatesListParams,
|
||||
IncidentioIncidentUpdatesListResponse
|
||||
> = {
|
||||
id: 'incidentio_incident_updates_list',
|
||||
name: 'List Incident Updates',
|
||||
description: 'List all updates for a specific incident in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
incident_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'The ID of the incident to get updates for (optional - if not provided, returns all updates)',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return per page',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Cursor for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams: string[] = []
|
||||
|
||||
if (params.incident_id) {
|
||||
queryParams.push(`incident_id=${params.incident_id}`)
|
||||
}
|
||||
|
||||
if (params.page_size) {
|
||||
queryParams.push(`page_size=${params.page_size}`)
|
||||
}
|
||||
|
||||
if (params.after) {
|
||||
queryParams.push(`after=${params.after}`)
|
||||
}
|
||||
|
||||
const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : ''
|
||||
return `https://api.incident.io/v2/incident_updates${queryString}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident_updates: data.incident_updates || data,
|
||||
pagination_meta: data.pagination_meta,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident_updates: {
|
||||
type: 'array',
|
||||
description: 'List of incident updates',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The update ID' },
|
||||
incident_id: { type: 'string', description: 'The incident ID' },
|
||||
message: { type: 'string', description: 'The update message' },
|
||||
new_severity: {
|
||||
type: 'object',
|
||||
description: 'New severity if changed',
|
||||
optional: true,
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Severity ID' },
|
||||
name: { type: 'string', description: 'Severity name' },
|
||||
rank: { type: 'number', description: 'Severity rank' },
|
||||
},
|
||||
},
|
||||
new_status: {
|
||||
type: 'object',
|
||||
description: 'New status if changed',
|
||||
optional: true,
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Status ID' },
|
||||
name: { type: 'string', description: 'Status name' },
|
||||
category: { type: 'string', description: 'Status category' },
|
||||
},
|
||||
},
|
||||
updater: {
|
||||
type: 'object',
|
||||
description: 'User who created the update',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'When the update was created' },
|
||||
updated_at: { type: 'string', description: 'When the update was last modified' },
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination_meta: {
|
||||
type: 'object',
|
||||
description: 'Pagination information',
|
||||
optional: true,
|
||||
properties: {
|
||||
after: { type: 'string', description: 'Cursor for next page', optional: true },
|
||||
page_size: { type: 'number', description: 'Number of results per page' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
import type {
|
||||
IncidentioIncidentsCreateParams,
|
||||
IncidentioIncidentsCreateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentsCreateTool: ToolConfig<
|
||||
IncidentioIncidentsCreateParams,
|
||||
IncidentioIncidentsCreateResponse
|
||||
> = {
|
||||
id: 'incidentio_incidents_create',
|
||||
name: 'incident.io Incidents Create',
|
||||
description:
|
||||
'Create a new incident in incident.io. Requires idempotency_key, severity_id, and visibility. Optionally accepts name, summary, type, and status.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
idempotency_key: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Unique identifier to prevent duplicate incident creation. Use a UUID or unique string.',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the incident (optional)',
|
||||
},
|
||||
summary: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Brief summary of the incident',
|
||||
},
|
||||
severity_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the severity level (required)',
|
||||
},
|
||||
incident_type_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the incident type',
|
||||
},
|
||||
incident_status_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the initial incident status',
|
||||
},
|
||||
visibility: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Visibility of the incident: "public" or "private" (required)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/incidents',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
idempotency_key: params.idempotency_key,
|
||||
severity_id: params.severity_id,
|
||||
visibility: params.visibility,
|
||||
}
|
||||
|
||||
if (params.name) body.name = params.name
|
||||
if (params.summary) body.summary = params.summary
|
||||
if (params.incident_type_id) body.incident_type_id = params.incident_type_id
|
||||
if (params.incident_status_id) body.incident_status_id = params.incident_status_id
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const incident = data.incident || data
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident: {
|
||||
id: incident.id,
|
||||
name: incident.name,
|
||||
summary: incident.summary,
|
||||
description: incident.description,
|
||||
mode: incident.mode,
|
||||
call_url: incident.call_url,
|
||||
severity: incident.severity
|
||||
? {
|
||||
id: incident.severity.id,
|
||||
name: incident.severity.name,
|
||||
rank: incident.severity.rank,
|
||||
}
|
||||
: undefined,
|
||||
status: incident.incident_status
|
||||
? {
|
||||
id: incident.incident_status.id,
|
||||
name: incident.incident_status.name,
|
||||
category: incident.incident_status.category,
|
||||
}
|
||||
: undefined,
|
||||
incident_type: incident.incident_type
|
||||
? {
|
||||
id: incident.incident_type.id,
|
||||
name: incident.incident_type.name,
|
||||
}
|
||||
: undefined,
|
||||
created_at: incident.created_at,
|
||||
updated_at: incident.updated_at,
|
||||
incident_url: incident.incident_url,
|
||||
slack_channel_id: incident.slack_channel_id,
|
||||
slack_channel_name: incident.slack_channel_name,
|
||||
visibility: incident.visibility,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident: {
|
||||
type: 'object',
|
||||
description: 'The created incident object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Incident ID' },
|
||||
name: { type: 'string', description: 'Incident name' },
|
||||
summary: { type: 'string', description: 'Brief summary of the incident' },
|
||||
description: { type: 'string', description: 'Detailed description of the incident' },
|
||||
mode: { type: 'string', description: 'Incident mode (e.g., standard, retrospective)' },
|
||||
call_url: { type: 'string', description: 'URL for the incident call/bridge' },
|
||||
severity: {
|
||||
type: 'object',
|
||||
description: 'Severity of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Severity ID' },
|
||||
name: { type: 'string', description: 'Severity name' },
|
||||
rank: { type: 'number', description: 'Severity rank' },
|
||||
},
|
||||
},
|
||||
status: {
|
||||
type: 'object',
|
||||
description: 'Current status of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Status ID' },
|
||||
name: { type: 'string', description: 'Status name' },
|
||||
category: { type: 'string', description: 'Status category' },
|
||||
},
|
||||
},
|
||||
incident_type: {
|
||||
type: 'object',
|
||||
description: 'Type of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Type ID' },
|
||||
name: { type: 'string', description: 'Type name' },
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
incident_url: { type: 'string', description: 'URL to the incident' },
|
||||
slack_channel_id: { type: 'string', description: 'Associated Slack channel ID' },
|
||||
slack_channel_name: { type: 'string', description: 'Associated Slack channel name' },
|
||||
visibility: { type: 'string', description: 'Incident visibility' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
import type {
|
||||
IncidentioIncidentsListParams,
|
||||
IncidentioIncidentsListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentsListTool: ToolConfig<
|
||||
IncidentioIncidentsListParams,
|
||||
IncidentioIncidentsListResponse
|
||||
> = {
|
||||
id: 'incidentio_incidents_list',
|
||||
name: 'incident.io Incidents List',
|
||||
description:
|
||||
'List incidents from incident.io. Returns a list of incidents with their details including severity, status, and timestamps.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Number of incidents to return per page (default: 25)',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Pagination cursor to fetch the next page of results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/incidents')
|
||||
|
||||
if (params.page_size) {
|
||||
url.searchParams.append('page_size', params.page_size.toString())
|
||||
}
|
||||
|
||||
if (params.after) {
|
||||
url.searchParams.append('after', params.after)
|
||||
}
|
||||
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incidents:
|
||||
data.incidents?.map((incident: any) => ({
|
||||
id: incident.id,
|
||||
name: incident.name,
|
||||
summary: incident.summary,
|
||||
description: incident.description,
|
||||
mode: incident.mode,
|
||||
call_url: incident.call_url,
|
||||
severity: incident.severity
|
||||
? {
|
||||
id: incident.severity.id,
|
||||
name: incident.severity.name,
|
||||
rank: incident.severity.rank,
|
||||
}
|
||||
: undefined,
|
||||
status: incident.incident_status
|
||||
? {
|
||||
id: incident.incident_status.id,
|
||||
name: incident.incident_status.name,
|
||||
category: incident.incident_status.category,
|
||||
}
|
||||
: undefined,
|
||||
incident_type: incident.incident_type
|
||||
? {
|
||||
id: incident.incident_type.id,
|
||||
name: incident.incident_type.name,
|
||||
}
|
||||
: undefined,
|
||||
created_at: incident.created_at,
|
||||
updated_at: incident.updated_at,
|
||||
incident_url: incident.incident_url,
|
||||
slack_channel_id: incident.slack_channel_id,
|
||||
slack_channel_name: incident.slack_channel_name,
|
||||
visibility: incident.visibility,
|
||||
})) || [],
|
||||
pagination_meta: data.pagination_meta
|
||||
? {
|
||||
after: data.pagination_meta.after,
|
||||
page_size: data.pagination_meta.page_size,
|
||||
total_record_count: data.pagination_meta.total_record_count,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incidents: {
|
||||
type: 'array',
|
||||
description: 'List of incidents',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Incident ID' },
|
||||
name: { type: 'string', description: 'Incident name' },
|
||||
summary: { type: 'string', description: 'Brief summary of the incident' },
|
||||
description: { type: 'string', description: 'Detailed description of the incident' },
|
||||
mode: { type: 'string', description: 'Incident mode (e.g., standard, retrospective)' },
|
||||
call_url: { type: 'string', description: 'URL for the incident call/bridge' },
|
||||
severity: {
|
||||
type: 'object',
|
||||
description: 'Severity of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Severity ID' },
|
||||
name: { type: 'string', description: 'Severity name' },
|
||||
rank: { type: 'number', description: 'Severity rank' },
|
||||
},
|
||||
},
|
||||
status: {
|
||||
type: 'object',
|
||||
description: 'Current status of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Status ID' },
|
||||
name: { type: 'string', description: 'Status name' },
|
||||
category: { type: 'string', description: 'Status category' },
|
||||
},
|
||||
},
|
||||
incident_type: {
|
||||
type: 'object',
|
||||
description: 'Type of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Type ID' },
|
||||
name: { type: 'string', description: 'Type name' },
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
incident_url: { type: 'string', description: 'URL to the incident' },
|
||||
slack_channel_id: { type: 'string', description: 'Associated Slack channel ID' },
|
||||
slack_channel_name: { type: 'string', description: 'Associated Slack channel name' },
|
||||
visibility: { type: 'string', description: 'Incident visibility' },
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination_meta: {
|
||||
type: 'object',
|
||||
description: 'Pagination metadata',
|
||||
optional: true,
|
||||
properties: {
|
||||
after: { type: 'string', description: 'Cursor for the next page', optional: true },
|
||||
page_size: { type: 'number', description: 'Number of items per page' },
|
||||
total_record_count: {
|
||||
type: 'number',
|
||||
description: 'Total number of records available',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
import type {
|
||||
IncidentioIncidentsShowParams,
|
||||
IncidentioIncidentsShowResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentsShowTool: ToolConfig<
|
||||
IncidentioIncidentsShowParams,
|
||||
IncidentioIncidentsShowResponse
|
||||
> = {
|
||||
id: 'incidentio_incidents_show',
|
||||
name: 'incident.io Incidents Show',
|
||||
description:
|
||||
'Retrieve detailed information about a specific incident from incident.io by its ID. Returns full incident details including custom fields and role assignments.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the incident to retrieve',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incidents/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const incident = data.incident || data
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident: {
|
||||
id: incident.id,
|
||||
name: incident.name,
|
||||
summary: incident.summary,
|
||||
description: incident.description,
|
||||
mode: incident.mode,
|
||||
call_url: incident.call_url,
|
||||
permalink: incident.permalink,
|
||||
severity: incident.severity
|
||||
? {
|
||||
id: incident.severity.id,
|
||||
name: incident.severity.name,
|
||||
rank: incident.severity.rank,
|
||||
}
|
||||
: undefined,
|
||||
status: incident.incident_status
|
||||
? {
|
||||
id: incident.incident_status.id,
|
||||
name: incident.incident_status.name,
|
||||
category: incident.incident_status.category,
|
||||
}
|
||||
: undefined,
|
||||
incident_type: incident.incident_type
|
||||
? {
|
||||
id: incident.incident_type.id,
|
||||
name: incident.incident_type.name,
|
||||
}
|
||||
: undefined,
|
||||
created_at: incident.created_at,
|
||||
updated_at: incident.updated_at,
|
||||
incident_url: incident.incident_url,
|
||||
slack_channel_id: incident.slack_channel_id,
|
||||
slack_channel_name: incident.slack_channel_name,
|
||||
visibility: incident.visibility,
|
||||
custom_field_entries: incident.custom_field_entries?.map((entry: any) => ({
|
||||
custom_field: {
|
||||
id: entry.custom_field.id,
|
||||
name: entry.custom_field.name,
|
||||
field_type: entry.custom_field.field_type,
|
||||
},
|
||||
values: entry.values?.map((value: any) => ({
|
||||
value_text: value.value_text,
|
||||
value_link: value.value_link,
|
||||
value_numeric: value.value_numeric,
|
||||
})),
|
||||
})),
|
||||
incident_role_assignments: incident.incident_role_assignments?.map((assignment: any) => ({
|
||||
role: {
|
||||
id: assignment.role.id,
|
||||
name: assignment.role.name,
|
||||
role_type: assignment.role.role_type,
|
||||
},
|
||||
assignee: assignment.assignee
|
||||
? {
|
||||
id: assignment.assignee.id,
|
||||
name: assignment.assignee.name,
|
||||
email: assignment.assignee.email,
|
||||
}
|
||||
: undefined,
|
||||
})),
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident: {
|
||||
type: 'object',
|
||||
description: 'Detailed incident information',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Incident ID' },
|
||||
name: { type: 'string', description: 'Incident name' },
|
||||
summary: { type: 'string', description: 'Brief summary of the incident' },
|
||||
description: { type: 'string', description: 'Detailed description of the incident' },
|
||||
mode: { type: 'string', description: 'Incident mode (e.g., standard, retrospective)' },
|
||||
call_url: { type: 'string', description: 'URL for the incident call/bridge' },
|
||||
permalink: { type: 'string', description: 'Permanent link to the incident' },
|
||||
severity: {
|
||||
type: 'object',
|
||||
description: 'Severity of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Severity ID' },
|
||||
name: { type: 'string', description: 'Severity name' },
|
||||
rank: { type: 'number', description: 'Severity rank' },
|
||||
},
|
||||
},
|
||||
status: {
|
||||
type: 'object',
|
||||
description: 'Current status of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Status ID' },
|
||||
name: { type: 'string', description: 'Status name' },
|
||||
category: { type: 'string', description: 'Status category' },
|
||||
},
|
||||
},
|
||||
incident_type: {
|
||||
type: 'object',
|
||||
description: 'Type of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Type ID' },
|
||||
name: { type: 'string', description: 'Type name' },
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
incident_url: { type: 'string', description: 'URL to the incident' },
|
||||
slack_channel_id: { type: 'string', description: 'Associated Slack channel ID' },
|
||||
slack_channel_name: { type: 'string', description: 'Associated Slack channel name' },
|
||||
visibility: { type: 'string', description: 'Incident visibility' },
|
||||
custom_field_entries: {
|
||||
type: 'array',
|
||||
description: 'Custom field values for the incident',
|
||||
},
|
||||
incident_role_assignments: {
|
||||
type: 'array',
|
||||
description: 'Role assignments for the incident',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
import type {
|
||||
IncidentioIncidentsUpdateParams,
|
||||
IncidentioIncidentsUpdateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const incidentsUpdateTool: ToolConfig<
|
||||
IncidentioIncidentsUpdateParams,
|
||||
IncidentioIncidentsUpdateResponse
|
||||
> = {
|
||||
id: 'incidentio_incidents_update',
|
||||
name: 'incident.io Incidents Update',
|
||||
description:
|
||||
'Update an existing incident in incident.io. Can update name, summary, severity, status, or type.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the incident to update',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated name of the incident',
|
||||
},
|
||||
summary: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated summary of the incident',
|
||||
},
|
||||
severity_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated severity ID for the incident',
|
||||
},
|
||||
incident_status_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated status ID for the incident',
|
||||
},
|
||||
incident_type_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated incident type ID',
|
||||
},
|
||||
notify_incident_channel: {
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to notify the incident channel about this update',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incidents/${params.id}/actions/edit`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
// Create incident object
|
||||
const incident: Record<string, any> = {}
|
||||
|
||||
if (params.name) incident.name = params.name
|
||||
if (params.summary) incident.summary = params.summary
|
||||
if (params.severity_id) incident.severity_id = params.severity_id
|
||||
if (params.incident_status_id) incident.incident_status_id = params.incident_status_id
|
||||
if (params.incident_type_id) incident.incident_type_id = params.incident_type_id
|
||||
|
||||
// Wrap in incident object with required notify_incident_channel
|
||||
return {
|
||||
incident,
|
||||
notify_incident_channel: params.notify_incident_channel,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const incident = data.incident || data
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incident: {
|
||||
id: incident.id,
|
||||
name: incident.name,
|
||||
summary: incident.summary,
|
||||
description: incident.description,
|
||||
mode: incident.mode,
|
||||
call_url: incident.call_url,
|
||||
severity: incident.severity
|
||||
? {
|
||||
id: incident.severity.id,
|
||||
name: incident.severity.name,
|
||||
rank: incident.severity.rank,
|
||||
}
|
||||
: undefined,
|
||||
status: incident.incident_status
|
||||
? {
|
||||
id: incident.incident_status.id,
|
||||
name: incident.incident_status.name,
|
||||
category: incident.incident_status.category,
|
||||
}
|
||||
: undefined,
|
||||
incident_type: incident.incident_type
|
||||
? {
|
||||
id: incident.incident_type.id,
|
||||
name: incident.incident_type.name,
|
||||
}
|
||||
: undefined,
|
||||
created_at: incident.created_at,
|
||||
updated_at: incident.updated_at,
|
||||
incident_url: incident.incident_url,
|
||||
slack_channel_id: incident.slack_channel_id,
|
||||
slack_channel_name: incident.slack_channel_name,
|
||||
visibility: incident.visibility,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incident: {
|
||||
type: 'object',
|
||||
description: 'The updated incident object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Incident ID' },
|
||||
name: { type: 'string', description: 'Incident name' },
|
||||
summary: { type: 'string', description: 'Brief summary of the incident' },
|
||||
description: { type: 'string', description: 'Detailed description of the incident' },
|
||||
mode: { type: 'string', description: 'Incident mode (e.g., standard, retrospective)' },
|
||||
call_url: { type: 'string', description: 'URL for the incident call/bridge' },
|
||||
severity: {
|
||||
type: 'object',
|
||||
description: 'Severity of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Severity ID' },
|
||||
name: { type: 'string', description: 'Severity name' },
|
||||
rank: { type: 'number', description: 'Severity rank' },
|
||||
},
|
||||
},
|
||||
status: {
|
||||
type: 'object',
|
||||
description: 'Current status of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Status ID' },
|
||||
name: { type: 'string', description: 'Status name' },
|
||||
category: { type: 'string', description: 'Status category' },
|
||||
},
|
||||
},
|
||||
incident_type: {
|
||||
type: 'object',
|
||||
description: 'Type of the incident',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Type ID' },
|
||||
name: { type: 'string', description: 'Type name' },
|
||||
},
|
||||
},
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
updated_at: { type: 'string', description: 'Last update timestamp' },
|
||||
incident_url: { type: 'string', description: 'URL to the incident' },
|
||||
slack_channel_id: { type: 'string', description: 'Associated Slack channel ID' },
|
||||
slack_channel_name: { type: 'string', description: 'Associated Slack channel name' },
|
||||
visibility: { type: 'string', description: 'Incident visibility' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { actionsListTool } from '@/tools/incidentio/actions_list'
|
||||
import { actionsShowTool } from '@/tools/incidentio/actions_show'
|
||||
import { customFieldsCreateTool } from '@/tools/incidentio/custom_fields_create'
|
||||
import { customFieldsDeleteTool } from '@/tools/incidentio/custom_fields_delete'
|
||||
import { customFieldsListTool } from '@/tools/incidentio/custom_fields_list'
|
||||
import { customFieldsShowTool } from '@/tools/incidentio/custom_fields_show'
|
||||
import { customFieldsUpdateTool } from '@/tools/incidentio/custom_fields_update'
|
||||
import { escalationPathsCreateTool } from '@/tools/incidentio/escalation_paths_create'
|
||||
import { escalationPathsDeleteTool } from '@/tools/incidentio/escalation_paths_delete'
|
||||
import { escalationPathsShowTool } from '@/tools/incidentio/escalation_paths_show'
|
||||
import { escalationPathsUpdateTool } from '@/tools/incidentio/escalation_paths_update'
|
||||
import { escalationsCreateTool } from '@/tools/incidentio/escalations_create'
|
||||
import { escalationsListTool } from '@/tools/incidentio/escalations_list'
|
||||
import { escalationsShowTool } from '@/tools/incidentio/escalations_show'
|
||||
import { followUpsListTool } from '@/tools/incidentio/follow_ups_list'
|
||||
import { followUpsShowTool } from '@/tools/incidentio/follow_ups_show'
|
||||
import { incidentRolesCreateTool } from '@/tools/incidentio/incident_roles_create'
|
||||
import { incidentRolesDeleteTool } from '@/tools/incidentio/incident_roles_delete'
|
||||
import { incidentRolesListTool } from '@/tools/incidentio/incident_roles_list'
|
||||
import { incidentRolesShowTool } from '@/tools/incidentio/incident_roles_show'
|
||||
import { incidentRolesUpdateTool } from '@/tools/incidentio/incident_roles_update'
|
||||
import { incidentStatusesListTool } from '@/tools/incidentio/incident_statuses_list'
|
||||
import { incidentTimestampsListTool } from '@/tools/incidentio/incident_timestamps_list'
|
||||
import { incidentTimestampsShowTool } from '@/tools/incidentio/incident_timestamps_show'
|
||||
import { incidentTypesListTool } from '@/tools/incidentio/incident_types_list'
|
||||
import { incidentUpdatesListTool } from '@/tools/incidentio/incident_updates_list'
|
||||
import { incidentsCreateTool } from '@/tools/incidentio/incidents_create'
|
||||
import { incidentsListTool } from '@/tools/incidentio/incidents_list'
|
||||
import { incidentsShowTool } from '@/tools/incidentio/incidents_show'
|
||||
import { incidentsUpdateTool } from '@/tools/incidentio/incidents_update'
|
||||
import { scheduleEntriesListTool } from '@/tools/incidentio/schedule_entries_list'
|
||||
import { scheduleOverridesCreateTool } from '@/tools/incidentio/schedule_overrides_create'
|
||||
import { schedulesCreateTool } from '@/tools/incidentio/schedules_create'
|
||||
import { schedulesDeleteTool } from '@/tools/incidentio/schedules_delete'
|
||||
import { schedulesListTool } from '@/tools/incidentio/schedules_list'
|
||||
import { schedulesShowTool } from '@/tools/incidentio/schedules_show'
|
||||
import { schedulesUpdateTool } from '@/tools/incidentio/schedules_update'
|
||||
import { severitiesListTool } from '@/tools/incidentio/severities_list'
|
||||
import { usersListTool } from '@/tools/incidentio/users_list'
|
||||
import { usersShowTool } from '@/tools/incidentio/users_show'
|
||||
import { workflowsCreateTool } from '@/tools/incidentio/workflows_create'
|
||||
import { workflowsDeleteTool } from '@/tools/incidentio/workflows_delete'
|
||||
import { workflowsListTool } from '@/tools/incidentio/workflows_list'
|
||||
import { workflowsShowTool } from '@/tools/incidentio/workflows_show'
|
||||
import { workflowsUpdateTool } from '@/tools/incidentio/workflows_update'
|
||||
|
||||
export const incidentioIncidentsListTool = incidentsListTool
|
||||
export const incidentioIncidentsCreateTool = incidentsCreateTool
|
||||
export const incidentioIncidentsShowTool = incidentsShowTool
|
||||
export const incidentioIncidentsUpdateTool = incidentsUpdateTool
|
||||
export const incidentioActionsListTool = actionsListTool
|
||||
export const incidentioActionsShowTool = actionsShowTool
|
||||
export const incidentioFollowUpsListTool = followUpsListTool
|
||||
export const incidentioFollowUpsShowTool = followUpsShowTool
|
||||
export const incidentioWorkflowsListTool = workflowsListTool
|
||||
export const incidentioWorkflowsCreateTool = workflowsCreateTool
|
||||
export const incidentioWorkflowsShowTool = workflowsShowTool
|
||||
export const incidentioWorkflowsUpdateTool = workflowsUpdateTool
|
||||
export const incidentioWorkflowsDeleteTool = workflowsDeleteTool
|
||||
export const incidentioCustomFieldsListTool = customFieldsListTool
|
||||
export const incidentioCustomFieldsCreateTool = customFieldsCreateTool
|
||||
export const incidentioCustomFieldsShowTool = customFieldsShowTool
|
||||
export const incidentioCustomFieldsUpdateTool = customFieldsUpdateTool
|
||||
export const incidentioCustomFieldsDeleteTool = customFieldsDeleteTool
|
||||
export const incidentioUsersListTool = usersListTool
|
||||
export const incidentioUsersShowTool = usersShowTool
|
||||
export const incidentioSeveritiesListTool = severitiesListTool
|
||||
export const incidentioIncidentStatusesListTool = incidentStatusesListTool
|
||||
export const incidentioIncidentTypesListTool = incidentTypesListTool
|
||||
export const incidentioEscalationsListTool = escalationsListTool
|
||||
export const incidentioEscalationsCreateTool = escalationsCreateTool
|
||||
export const incidentioEscalationsShowTool = escalationsShowTool
|
||||
export const incidentioSchedulesListTool = schedulesListTool
|
||||
export const incidentioSchedulesCreateTool = schedulesCreateTool
|
||||
export const incidentioSchedulesShowTool = schedulesShowTool
|
||||
export const incidentioSchedulesUpdateTool = schedulesUpdateTool
|
||||
export const incidentioSchedulesDeleteTool = schedulesDeleteTool
|
||||
export const incidentioIncidentRolesListTool = incidentRolesListTool
|
||||
export const incidentioIncidentRolesCreateTool = incidentRolesCreateTool
|
||||
export const incidentioIncidentRolesShowTool = incidentRolesShowTool
|
||||
export const incidentioIncidentRolesUpdateTool = incidentRolesUpdateTool
|
||||
export const incidentioIncidentRolesDeleteTool = incidentRolesDeleteTool
|
||||
export const incidentioIncidentTimestampsListTool = incidentTimestampsListTool
|
||||
export const incidentioIncidentTimestampsShowTool = incidentTimestampsShowTool
|
||||
export const incidentioIncidentUpdatesListTool = incidentUpdatesListTool
|
||||
export const incidentioScheduleEntriesListTool = scheduleEntriesListTool
|
||||
export const incidentioScheduleOverridesCreateTool = scheduleOverridesCreateTool
|
||||
export const incidentioEscalationPathsCreateTool = escalationPathsCreateTool
|
||||
export const incidentioEscalationPathsShowTool = escalationPathsShowTool
|
||||
export const incidentioEscalationPathsUpdateTool = escalationPathsUpdateTool
|
||||
export const incidentioEscalationPathsDeleteTool = escalationPathsDeleteTool
|
||||
@@ -0,0 +1,136 @@
|
||||
import type {
|
||||
IncidentioScheduleEntriesListParams,
|
||||
IncidentioScheduleEntriesListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const scheduleEntriesListTool: ToolConfig<
|
||||
IncidentioScheduleEntriesListParams,
|
||||
IncidentioScheduleEntriesListResponse
|
||||
> = {
|
||||
id: 'incidentio_schedule_entries_list',
|
||||
name: 'List Schedule Entries',
|
||||
description: 'List all entries for a specific schedule in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
schedule_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the schedule to get entries for',
|
||||
},
|
||||
entry_window_start: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Start date/time to filter entries (ISO 8601 format)',
|
||||
},
|
||||
entry_window_end: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'End date/time to filter entries (ISO 8601 format)',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return per page',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Cursor for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams: string[] = []
|
||||
|
||||
queryParams.push(`schedule_id=${params.schedule_id}`)
|
||||
|
||||
if (params.entry_window_start) {
|
||||
queryParams.push(`entry_window_start=${encodeURIComponent(params.entry_window_start)}`)
|
||||
}
|
||||
|
||||
if (params.entry_window_end) {
|
||||
queryParams.push(`entry_window_end=${encodeURIComponent(params.entry_window_end)}`)
|
||||
}
|
||||
|
||||
if (params.page_size) {
|
||||
queryParams.push(`page_size=${params.page_size}`)
|
||||
}
|
||||
|
||||
if (params.after) {
|
||||
queryParams.push(`after=${params.after}`)
|
||||
}
|
||||
|
||||
const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : ''
|
||||
return `https://api.incident.io/v2/schedule_entries${queryString}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
schedule_entries: data.schedule_entries || data,
|
||||
pagination_meta: data.pagination_meta,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
schedule_entries: {
|
||||
type: 'array',
|
||||
description: 'List of schedule entries',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The entry ID' },
|
||||
schedule_id: { type: 'string', description: 'The schedule ID' },
|
||||
user: {
|
||||
type: 'object',
|
||||
description: 'User assigned to this entry',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
start_at: { type: 'string', description: 'When the entry starts' },
|
||||
end_at: { type: 'string', description: 'When the entry ends' },
|
||||
layer_id: { type: 'string', description: 'The schedule layer ID' },
|
||||
created_at: { type: 'string', description: 'When the entry was created' },
|
||||
updated_at: { type: 'string', description: 'When the entry was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination_meta: {
|
||||
type: 'object',
|
||||
description: 'Pagination information',
|
||||
optional: true,
|
||||
properties: {
|
||||
after: { type: 'string', description: 'Cursor for next page', optional: true },
|
||||
after_url: { type: 'string', description: 'URL for next page', optional: true },
|
||||
page_size: { type: 'number', description: 'Number of results per page' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import type {
|
||||
IncidentioScheduleOverridesCreateParams,
|
||||
IncidentioScheduleOverridesCreateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const scheduleOverridesCreateTool: ToolConfig<
|
||||
IncidentioScheduleOverridesCreateParams,
|
||||
IncidentioScheduleOverridesCreateResponse
|
||||
> = {
|
||||
id: 'incidentio_schedule_overrides_create',
|
||||
name: 'Create Schedule Override',
|
||||
description: 'Create a new schedule override in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
rotation_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the rotation to override',
|
||||
},
|
||||
schedule_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the schedule',
|
||||
},
|
||||
user_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'The ID of the user to assign (provide one of: user_id, user_email, or user_slack_id)',
|
||||
},
|
||||
user_email: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'The email of the user to assign (provide one of: user_id, user_email, or user_slack_id)',
|
||||
},
|
||||
user_slack_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'The Slack ID of the user to assign (provide one of: user_id, user_email, or user_slack_id)',
|
||||
},
|
||||
start_at: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'When the override starts (ISO 8601 format)',
|
||||
},
|
||||
end_at: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'When the override ends (ISO 8601 format)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/schedule_overrides',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const user: { id?: string; email?: string; slack_user_id?: string } = {}
|
||||
if (params.user_id) user.id = params.user_id
|
||||
if (params.user_email) user.email = params.user_email
|
||||
if (params.user_slack_id) user.slack_user_id = params.user_slack_id
|
||||
|
||||
return {
|
||||
rotation_id: params.rotation_id,
|
||||
schedule_id: params.schedule_id,
|
||||
user,
|
||||
start_at: params.start_at,
|
||||
end_at: params.end_at,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
override: data.override || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
override: {
|
||||
type: 'object',
|
||||
description: 'The created schedule override',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The override ID' },
|
||||
rotation_id: { type: 'string', description: 'The rotation ID' },
|
||||
schedule_id: { type: 'string', description: 'The schedule ID' },
|
||||
user: {
|
||||
type: 'object',
|
||||
description: 'User assigned to this override',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
},
|
||||
},
|
||||
start_at: { type: 'string', description: 'When the override starts' },
|
||||
end_at: { type: 'string', description: 'When the override ends' },
|
||||
created_at: { type: 'string', description: 'When the override was created' },
|
||||
updated_at: { type: 'string', description: 'When the override was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import type {
|
||||
IncidentioSchedulesCreateParams,
|
||||
IncidentioSchedulesCreateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const schedulesCreateTool: ToolConfig<
|
||||
IncidentioSchedulesCreateParams,
|
||||
IncidentioSchedulesCreateResponse
|
||||
> = {
|
||||
id: 'incidentio_schedules_create',
|
||||
name: 'Create Schedule',
|
||||
description: 'Create a new schedule in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the schedule',
|
||||
},
|
||||
timezone: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Timezone for the schedule (e.g., America/New_York)',
|
||||
},
|
||||
config: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Schedule configuration as JSON string with rotations. Example: {"rotations": [{"name": "Primary", "users": [{"id": "user_id"}], "handover_start_at": "2024-01-01T09:00:00Z", "handovers": [{"interval": 1, "interval_type": "weekly"}]}]}',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/schedules',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => ({
|
||||
schedule: {
|
||||
name: params.name,
|
||||
timezone: params.timezone,
|
||||
config: typeof params.config === 'string' ? JSON.parse(params.config) : params.config,
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
schedule: data.schedule || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
schedule: {
|
||||
type: 'object',
|
||||
description: 'The created schedule',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The schedule ID' },
|
||||
name: { type: 'string', description: 'The schedule name' },
|
||||
timezone: { type: 'string', description: 'The schedule timezone' },
|
||||
created_at: { type: 'string', description: 'When the schedule was created' },
|
||||
updated_at: { type: 'string', description: 'When the schedule was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import type {
|
||||
IncidentioSchedulesDeleteParams,
|
||||
IncidentioSchedulesDeleteResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const schedulesDeleteTool: ToolConfig<
|
||||
IncidentioSchedulesDeleteParams,
|
||||
IncidentioSchedulesDeleteResponse
|
||||
> = {
|
||||
id: 'incidentio_schedules_delete',
|
||||
name: 'Delete Schedule',
|
||||
description: 'Delete a schedule in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the schedule to delete',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/schedules/${params.id}`,
|
||||
method: 'DELETE',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: 'Schedule deleted successfully',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'Success message',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
import type {
|
||||
IncidentioSchedulesListParams,
|
||||
IncidentioSchedulesListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const schedulesListTool: ToolConfig<
|
||||
IncidentioSchedulesListParams,
|
||||
IncidentioSchedulesListResponse
|
||||
> = {
|
||||
id: 'incidentio_schedules_list',
|
||||
name: 'List Schedules',
|
||||
description: 'List all schedules in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Number of results per page (default: 25)',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Pagination cursor to fetch the next page of results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/schedules')
|
||||
if (params.page_size) {
|
||||
url.searchParams.append('page_size', params.page_size.toString())
|
||||
}
|
||||
if (params.after) {
|
||||
url.searchParams.append('after', params.after)
|
||||
}
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
schedules: data.schedules || [],
|
||||
pagination_meta: data.pagination_meta
|
||||
? {
|
||||
after: data.pagination_meta.after,
|
||||
page_size: data.pagination_meta.page_size,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
schedules: {
|
||||
type: 'array',
|
||||
description: 'List of schedules',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The schedule ID' },
|
||||
name: { type: 'string', description: 'The schedule name' },
|
||||
timezone: { type: 'string', description: 'The schedule timezone' },
|
||||
created_at: { type: 'string', description: 'When the schedule was created' },
|
||||
updated_at: { type: 'string', description: 'When the schedule was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination_meta: {
|
||||
type: 'object',
|
||||
description: 'Pagination metadata',
|
||||
optional: true,
|
||||
properties: {
|
||||
after: { type: 'string', description: 'Cursor for next page', optional: true },
|
||||
page_size: { type: 'number', description: 'Number of results per page' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import type {
|
||||
IncidentioSchedulesShowParams,
|
||||
IncidentioSchedulesShowResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const schedulesShowTool: ToolConfig<
|
||||
IncidentioSchedulesShowParams,
|
||||
IncidentioSchedulesShowResponse
|
||||
> = {
|
||||
id: 'incidentio_schedules_show',
|
||||
name: 'Show Schedule',
|
||||
description: 'Get details of a specific schedule in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the schedule',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/schedules/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
schedule: data.schedule || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
schedule: {
|
||||
type: 'object',
|
||||
description: 'The schedule details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The schedule ID' },
|
||||
name: { type: 'string', description: 'The schedule name' },
|
||||
timezone: { type: 'string', description: 'The schedule timezone' },
|
||||
created_at: { type: 'string', description: 'When the schedule was created' },
|
||||
updated_at: { type: 'string', description: 'When the schedule was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import type {
|
||||
IncidentioSchedulesUpdateParams,
|
||||
IncidentioSchedulesUpdateResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const schedulesUpdateTool: ToolConfig<
|
||||
IncidentioSchedulesUpdateParams,
|
||||
IncidentioSchedulesUpdateResponse
|
||||
> = {
|
||||
id: 'incidentio_schedules_update',
|
||||
name: 'Update Schedule',
|
||||
description: 'Update an existing schedule in incident.io',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the schedule to update',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New name for the schedule',
|
||||
},
|
||||
timezone: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New timezone for the schedule (e.g., America/New_York)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/schedules/${params.id}`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const schedule: Record<string, any> = {}
|
||||
if (params.name) schedule.name = params.name
|
||||
if (params.timezone) schedule.timezone = params.timezone
|
||||
return { schedule }
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
schedule: data.schedule || data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
schedule: {
|
||||
type: 'object',
|
||||
description: 'The updated schedule',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'The schedule ID' },
|
||||
name: { type: 'string', description: 'The schedule name' },
|
||||
timezone: { type: 'string', description: 'The schedule timezone' },
|
||||
created_at: { type: 'string', description: 'When the schedule was created' },
|
||||
updated_at: { type: 'string', description: 'When the schedule was last updated' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { IncidentioSeveritiesListParams, IncidentioSeveritiesListResponse } from './types'
|
||||
|
||||
export const severitiesListTool: ToolConfig<
|
||||
IncidentioSeveritiesListParams,
|
||||
IncidentioSeveritiesListResponse
|
||||
> = {
|
||||
id: 'incidentio_severities_list',
|
||||
name: 'Incident.io Severities List',
|
||||
description:
|
||||
'List all severity levels configured in your Incident.io workspace. Returns severity details including id, name, description, and rank.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Incident.io API Key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v1/severities',
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
severities: data.severities.map((severity: any) => ({
|
||||
id: severity.id,
|
||||
name: severity.name,
|
||||
description: severity.description,
|
||||
rank: severity.rank,
|
||||
})),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
severities: {
|
||||
type: 'array',
|
||||
description: 'List of severity levels',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the severity level' },
|
||||
name: { type: 'string', description: 'Name of the severity level' },
|
||||
description: { type: 'string', description: 'Description of the severity level' },
|
||||
rank: { type: 'number', description: 'Rank/order of the severity level' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,916 @@
|
||||
// Common types for incident.io tools
|
||||
import type { ToolResponse } from '@/tools/types'
|
||||
|
||||
// Common parameters for all incident.io tools
|
||||
export interface IncidentioBaseParams {
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
// Incident types
|
||||
export interface IncidentioIncidentsListParams extends IncidentioBaseParams {
|
||||
page_size?: number
|
||||
after?: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncident {
|
||||
id: string
|
||||
name: string
|
||||
summary?: string
|
||||
description?: string
|
||||
mode?: string
|
||||
call_url?: string
|
||||
severity?: {
|
||||
id: string
|
||||
name: string
|
||||
rank: number
|
||||
}
|
||||
status?: {
|
||||
id: string
|
||||
name: string
|
||||
category: string
|
||||
}
|
||||
incident_type?: {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
created_at: string
|
||||
updated_at: string
|
||||
incident_url?: string
|
||||
slack_channel_id?: string
|
||||
slack_channel_name?: string
|
||||
visibility?: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentsListResponse extends ToolResponse {
|
||||
output: {
|
||||
incidents: IncidentioIncident[]
|
||||
pagination_meta?: {
|
||||
after?: string
|
||||
page_size: number
|
||||
total_record_count?: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentsCreateParams extends IncidentioBaseParams {
|
||||
idempotency_key: string
|
||||
name?: string
|
||||
summary?: string
|
||||
severity_id: string
|
||||
incident_type_id?: string
|
||||
incident_status_id?: string
|
||||
visibility: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentsCreateResponse extends ToolResponse {
|
||||
output: {
|
||||
incident: IncidentioIncident
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentsShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentDetailed extends IncidentioIncident {
|
||||
description?: string
|
||||
mode?: string
|
||||
permalink?: string
|
||||
custom_field_entries?: Array<{
|
||||
custom_field: {
|
||||
id: string
|
||||
name: string
|
||||
field_type: string
|
||||
}
|
||||
values: Array<{
|
||||
value_text?: string
|
||||
value_link?: string
|
||||
value_numeric?: string
|
||||
}>
|
||||
}>
|
||||
incident_role_assignments?: Array<{
|
||||
role: {
|
||||
id: string
|
||||
name: string
|
||||
role_type: string
|
||||
}
|
||||
assignee?: {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
}
|
||||
}>
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentsShowResponse extends ToolResponse {
|
||||
output: {
|
||||
incident: IncidentioIncidentDetailed
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentsUpdateParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
name?: string
|
||||
summary?: string
|
||||
severity_id?: string
|
||||
incident_status_id?: string
|
||||
incident_type_id?: string
|
||||
notify_incident_channel: boolean
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentsUpdateResponse extends ToolResponse {
|
||||
output: {
|
||||
incident: IncidentioIncident
|
||||
}
|
||||
}
|
||||
|
||||
// Action types
|
||||
export interface IncidentioActionsListParams extends IncidentioBaseParams {
|
||||
incident_id?: string
|
||||
page_size?: number
|
||||
}
|
||||
|
||||
export interface IncidentioAction {
|
||||
id: string
|
||||
description: string
|
||||
assignee?: {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
role?: string
|
||||
slack_user_id?: string
|
||||
}
|
||||
status: string
|
||||
due_at?: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
incident_id?: string
|
||||
creator?: {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
}
|
||||
completed_at?: string
|
||||
external_issue_reference?: {
|
||||
provider: string
|
||||
issue_name: string
|
||||
issue_permalink: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioActionsListResponse extends ToolResponse {
|
||||
output: {
|
||||
actions: IncidentioAction[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioActionsShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioActionsShowResponse extends ToolResponse {
|
||||
output: {
|
||||
action: IncidentioAction
|
||||
}
|
||||
}
|
||||
|
||||
// Follow-up types
|
||||
export interface IncidentioFollowUpsListParams extends IncidentioBaseParams {
|
||||
incident_id?: string
|
||||
page_size?: number
|
||||
}
|
||||
|
||||
export interface IncidentioFollowUp {
|
||||
id: string
|
||||
title: string
|
||||
description?: string
|
||||
assignee?: {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
role?: string
|
||||
slack_user_id?: string
|
||||
}
|
||||
status: string
|
||||
priority?: {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
rank: number
|
||||
}
|
||||
created_at: string
|
||||
updated_at: string
|
||||
incident_id?: string
|
||||
creator?: {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
}
|
||||
completed_at?: string
|
||||
labels?: string[]
|
||||
external_issue_reference?: {
|
||||
provider: string
|
||||
issue_name: string
|
||||
issue_permalink: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioFollowUpsListResponse extends ToolResponse {
|
||||
output: {
|
||||
follow_ups: IncidentioFollowUp[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioFollowUpsShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioFollowUpsShowResponse extends ToolResponse {
|
||||
output: {
|
||||
follow_up: IncidentioFollowUp
|
||||
}
|
||||
}
|
||||
|
||||
// Workflow types
|
||||
export interface Workflow {
|
||||
id: string
|
||||
name: string
|
||||
state: 'active' | 'draft' | 'disabled'
|
||||
folder?: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
// Workflows List tool types
|
||||
export interface WorkflowsListParams extends IncidentioBaseParams {
|
||||
page_size?: number
|
||||
after?: string
|
||||
}
|
||||
|
||||
export interface WorkflowsListResponse extends ToolResponse {
|
||||
output: {
|
||||
workflows: Workflow[]
|
||||
pagination_meta?: {
|
||||
after?: string
|
||||
page_size: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Workflows Create tool types
|
||||
export interface WorkflowsCreateParams extends IncidentioBaseParams {
|
||||
name: string
|
||||
folder?: string
|
||||
state?: 'active' | 'draft' | 'disabled'
|
||||
}
|
||||
|
||||
export interface WorkflowsCreateResponse extends ToolResponse {
|
||||
output: {
|
||||
workflow: Workflow
|
||||
}
|
||||
}
|
||||
|
||||
// Workflows Show tool types
|
||||
export interface WorkflowsShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface WorkflowsShowResponse extends ToolResponse {
|
||||
output: {
|
||||
workflow: Workflow
|
||||
}
|
||||
}
|
||||
|
||||
// Workflows Update tool types
|
||||
export interface WorkflowsUpdateParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
name?: string
|
||||
state?: 'active' | 'draft' | 'disabled'
|
||||
folder?: string
|
||||
}
|
||||
|
||||
export interface WorkflowsUpdateResponse extends ToolResponse {
|
||||
output: {
|
||||
workflow: Workflow
|
||||
}
|
||||
}
|
||||
|
||||
// Workflows Delete tool types
|
||||
export interface WorkflowsDeleteParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface WorkflowsDeleteResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
// Custom field types
|
||||
export type CustomFieldType = 'text' | 'single_select' | 'multi_select' | 'numeric' | 'link'
|
||||
|
||||
export interface CustomField {
|
||||
id: string
|
||||
name: string
|
||||
description?: string
|
||||
field_type: CustomFieldType
|
||||
created_at: string
|
||||
updated_at: string
|
||||
options?: CustomFieldOption[]
|
||||
}
|
||||
|
||||
export interface CustomFieldOption {
|
||||
id: string
|
||||
value: string
|
||||
sort_key: number
|
||||
}
|
||||
|
||||
// List custom fields
|
||||
export interface CustomFieldsListParams extends IncidentioBaseParams {}
|
||||
|
||||
export interface CustomFieldsListResponse extends ToolResponse {
|
||||
output: {
|
||||
custom_fields: CustomField[]
|
||||
}
|
||||
}
|
||||
|
||||
// Create custom field
|
||||
export interface CustomFieldsCreateParams extends IncidentioBaseParams {
|
||||
name: string
|
||||
description?: string
|
||||
field_type: CustomFieldType
|
||||
}
|
||||
|
||||
export interface CustomFieldsCreateResponse extends ToolResponse {
|
||||
output: {
|
||||
custom_field: CustomField
|
||||
}
|
||||
}
|
||||
|
||||
// Show custom field
|
||||
export interface CustomFieldsShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface CustomFieldsShowResponse extends ToolResponse {
|
||||
output: {
|
||||
custom_field: CustomField
|
||||
}
|
||||
}
|
||||
|
||||
// Update custom field
|
||||
export interface CustomFieldsUpdateParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
name?: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export interface CustomFieldsUpdateResponse extends ToolResponse {
|
||||
output: {
|
||||
custom_field: CustomField
|
||||
}
|
||||
}
|
||||
|
||||
// Delete custom field
|
||||
export interface CustomFieldsDeleteParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface CustomFieldsDeleteResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
// Users list tool types
|
||||
export interface IncidentioUsersListParams extends IncidentioBaseParams {
|
||||
page_size?: number
|
||||
}
|
||||
|
||||
export interface IncidentioUser {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
role: string
|
||||
}
|
||||
|
||||
export interface IncidentioUsersListResponse extends ToolResponse {
|
||||
output: {
|
||||
users: IncidentioUser[]
|
||||
}
|
||||
}
|
||||
|
||||
// Users show tool types
|
||||
export interface IncidentioUsersShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioUsersShowResponse extends ToolResponse {
|
||||
output: {
|
||||
user: IncidentioUser
|
||||
}
|
||||
}
|
||||
|
||||
// Severities list tool types
|
||||
export interface IncidentioSeveritiesListParams extends IncidentioBaseParams {}
|
||||
|
||||
export interface IncidentioSeverity {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
rank: number
|
||||
}
|
||||
|
||||
export interface IncidentioSeveritiesListResponse extends ToolResponse {
|
||||
output: {
|
||||
severities: IncidentioSeverity[]
|
||||
}
|
||||
}
|
||||
|
||||
// Incident statuses list tool types
|
||||
export interface IncidentioIncidentStatusesListParams extends IncidentioBaseParams {}
|
||||
|
||||
export interface IncidentioIncidentStatus {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
category: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentStatusesListResponse extends ToolResponse {
|
||||
output: {
|
||||
incident_statuses: IncidentioIncidentStatus[]
|
||||
}
|
||||
}
|
||||
|
||||
// Incident types list tool types
|
||||
export interface IncidentioIncidentTypesListParams extends IncidentioBaseParams {}
|
||||
|
||||
export interface IncidentioIncidentType {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
is_default: boolean
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentTypesListResponse extends ToolResponse {
|
||||
output: {
|
||||
incident_types: IncidentioIncidentType[]
|
||||
}
|
||||
}
|
||||
|
||||
export type IncidentioResponse =
|
||||
| IncidentioIncidentsListResponse
|
||||
| IncidentioIncidentsCreateResponse
|
||||
| IncidentioIncidentsShowResponse
|
||||
| IncidentioIncidentsUpdateResponse
|
||||
| IncidentioActionsListResponse
|
||||
| IncidentioActionsShowResponse
|
||||
| IncidentioFollowUpsListResponse
|
||||
| IncidentioFollowUpsShowResponse
|
||||
| WorkflowsListResponse
|
||||
| WorkflowsCreateResponse
|
||||
| WorkflowsShowResponse
|
||||
| WorkflowsUpdateResponse
|
||||
| WorkflowsDeleteResponse
|
||||
| CustomFieldsListResponse
|
||||
| CustomFieldsCreateResponse
|
||||
| CustomFieldsShowResponse
|
||||
| CustomFieldsUpdateResponse
|
||||
| CustomFieldsDeleteResponse
|
||||
| IncidentioUsersListResponse
|
||||
| IncidentioUsersShowResponse
|
||||
| IncidentioSeveritiesListResponse
|
||||
| IncidentioIncidentStatusesListResponse
|
||||
| IncidentioIncidentTypesListResponse
|
||||
| IncidentioEscalationsListResponse
|
||||
| IncidentioEscalationsCreateResponse
|
||||
| IncidentioEscalationsShowResponse
|
||||
| IncidentioSchedulesListResponse
|
||||
| IncidentioSchedulesCreateResponse
|
||||
| IncidentioSchedulesShowResponse
|
||||
| IncidentioSchedulesUpdateResponse
|
||||
| IncidentioSchedulesDeleteResponse
|
||||
| IncidentioIncidentRolesListResponse
|
||||
| IncidentioIncidentRolesCreateResponse
|
||||
| IncidentioIncidentRolesShowResponse
|
||||
| IncidentioIncidentRolesUpdateResponse
|
||||
| IncidentioIncidentRolesDeleteResponse
|
||||
| IncidentioIncidentTimestampsListResponse
|
||||
| IncidentioIncidentTimestampsShowResponse
|
||||
| IncidentioIncidentUpdatesListResponse
|
||||
| IncidentioScheduleEntriesListResponse
|
||||
| IncidentioScheduleOverridesCreateResponse
|
||||
| IncidentioEscalationPathsCreateResponse
|
||||
| IncidentioEscalationPathsShowResponse
|
||||
| IncidentioEscalationPathsUpdateResponse
|
||||
| IncidentioEscalationPathsDeleteResponse
|
||||
|
||||
// Escalations types
|
||||
export interface IncidentioEscalationsListParams extends IncidentioBaseParams {
|
||||
page_size?: number
|
||||
}
|
||||
|
||||
export interface IncidentioEscalation {
|
||||
id: string
|
||||
name: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationsListResponse extends ToolResponse {
|
||||
output: {
|
||||
escalations: IncidentioEscalation[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationsCreateParams extends IncidentioBaseParams {
|
||||
idempotency_key: string
|
||||
title: string
|
||||
escalation_path_id?: string
|
||||
user_ids?: string
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationsCreateResponse extends ToolResponse {
|
||||
output: {
|
||||
escalation: IncidentioEscalation
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationsShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationsShowResponse extends ToolResponse {
|
||||
output: {
|
||||
escalation: IncidentioEscalation
|
||||
}
|
||||
}
|
||||
|
||||
// Schedules types
|
||||
export interface IncidentioSchedulesListParams extends IncidentioBaseParams {
|
||||
page_size?: number
|
||||
after?: string
|
||||
}
|
||||
|
||||
export interface IncidentioSchedule {
|
||||
id: string
|
||||
name: string
|
||||
timezone: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface IncidentioSchedulesListResponse extends ToolResponse {
|
||||
output: {
|
||||
schedules: IncidentioSchedule[]
|
||||
pagination_meta?: {
|
||||
after?: string
|
||||
page_size: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioSchedulesCreateParams extends IncidentioBaseParams {
|
||||
name: string
|
||||
timezone: string
|
||||
config: string
|
||||
}
|
||||
|
||||
export interface IncidentioSchedulesCreateResponse extends ToolResponse {
|
||||
output: {
|
||||
schedule: IncidentioSchedule
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioSchedulesShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioSchedulesShowResponse extends ToolResponse {
|
||||
output: {
|
||||
schedule: IncidentioSchedule
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioSchedulesUpdateParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
name?: string
|
||||
timezone?: string
|
||||
}
|
||||
|
||||
export interface IncidentioSchedulesUpdateResponse extends ToolResponse {
|
||||
output: {
|
||||
schedule: IncidentioSchedule
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioSchedulesDeleteParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioSchedulesDeleteResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
// Incident Roles types
|
||||
export interface IncidentioIncidentRole {
|
||||
id: string
|
||||
name: string
|
||||
description?: string
|
||||
instructions: string
|
||||
shortform: string
|
||||
role_type: string
|
||||
required: boolean
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentRolesListParams extends IncidentioBaseParams {}
|
||||
|
||||
export interface IncidentioIncidentRolesListResponse extends ToolResponse {
|
||||
output: {
|
||||
incident_roles: IncidentioIncidentRole[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentRolesCreateParams extends IncidentioBaseParams {
|
||||
name: string
|
||||
description: string
|
||||
instructions: string
|
||||
shortform: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentRolesCreateResponse extends ToolResponse {
|
||||
output: {
|
||||
incident_role: IncidentioIncidentRole
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentRolesShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentRolesShowResponse extends ToolResponse {
|
||||
output: {
|
||||
incident_role: IncidentioIncidentRole
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentRolesUpdateParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
instructions: string
|
||||
shortform: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentRolesUpdateResponse extends ToolResponse {
|
||||
output: {
|
||||
incident_role: IncidentioIncidentRole
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentRolesDeleteParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentRolesDeleteResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
// Incident Timestamps types
|
||||
export interface IncidentioIncidentTimestamp {
|
||||
id: string
|
||||
name: string
|
||||
rank: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentTimestampsListParams extends IncidentioBaseParams {}
|
||||
|
||||
export interface IncidentioIncidentTimestampsListResponse extends ToolResponse {
|
||||
output: {
|
||||
incident_timestamps: IncidentioIncidentTimestamp[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentTimestampsShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentTimestampsShowResponse extends ToolResponse {
|
||||
output: {
|
||||
incident_timestamp: IncidentioIncidentTimestamp
|
||||
}
|
||||
}
|
||||
|
||||
// Incident Updates types
|
||||
export interface IncidentioIncidentUpdate {
|
||||
id: string
|
||||
incident_id: string
|
||||
message: string
|
||||
new_severity?: {
|
||||
id: string
|
||||
name: string
|
||||
rank: number
|
||||
}
|
||||
new_status?: {
|
||||
id: string
|
||||
name: string
|
||||
category: string
|
||||
}
|
||||
updater: {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
}
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentUpdatesListParams extends IncidentioBaseParams {
|
||||
incident_id?: string
|
||||
page_size?: number
|
||||
after?: string
|
||||
}
|
||||
|
||||
export interface IncidentioIncidentUpdatesListResponse extends ToolResponse {
|
||||
output: {
|
||||
incident_updates: IncidentioIncidentUpdate[]
|
||||
pagination_meta?: {
|
||||
after?: string
|
||||
page_size: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule Entries types
|
||||
export interface IncidentioScheduleEntry {
|
||||
id: string
|
||||
schedule_id: string
|
||||
user: {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
}
|
||||
start_at: string
|
||||
end_at: string
|
||||
layer_id: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface IncidentioScheduleEntriesListParams extends IncidentioBaseParams {
|
||||
schedule_id: string
|
||||
entry_window_start?: string
|
||||
entry_window_end?: string
|
||||
page_size?: number
|
||||
after?: string
|
||||
}
|
||||
|
||||
export interface IncidentioScheduleEntriesListResponse extends ToolResponse {
|
||||
output: {
|
||||
schedule_entries: IncidentioScheduleEntry[]
|
||||
pagination_meta?: {
|
||||
after?: string
|
||||
after_url?: string
|
||||
page_size: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule Overrides types
|
||||
export interface IncidentioScheduleOverride {
|
||||
id: string
|
||||
rotation_id: string
|
||||
schedule_id: string
|
||||
user: {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
}
|
||||
start_at: string
|
||||
end_at: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface IncidentioScheduleOverridesCreateParams extends IncidentioBaseParams {
|
||||
rotation_id: string
|
||||
schedule_id: string
|
||||
user_id?: string
|
||||
user_email?: string
|
||||
user_slack_id?: string
|
||||
start_at: string
|
||||
end_at: string
|
||||
}
|
||||
|
||||
export interface IncidentioScheduleOverridesCreateResponse extends ToolResponse {
|
||||
output: {
|
||||
override: IncidentioScheduleOverride
|
||||
}
|
||||
}
|
||||
|
||||
// Escalation Paths types
|
||||
export interface IncidentioEscalationPathTarget {
|
||||
id: string
|
||||
type: string
|
||||
schedule_id?: string
|
||||
user_id?: string
|
||||
urgency: string
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPathLevel {
|
||||
targets: IncidentioEscalationPathTarget[]
|
||||
time_to_ack_seconds: number
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPath {
|
||||
id: string
|
||||
name: string
|
||||
path: IncidentioEscalationPathLevel[]
|
||||
working_hours?: Array<{
|
||||
weekday: string
|
||||
start_time: string
|
||||
end_time: string
|
||||
}>
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPathsCreateParams extends IncidentioBaseParams {
|
||||
name: string
|
||||
path: Array<{
|
||||
targets: Array<{
|
||||
id: string
|
||||
type: string
|
||||
schedule_id?: string
|
||||
user_id?: string
|
||||
urgency: string
|
||||
}>
|
||||
time_to_ack_seconds: number
|
||||
}>
|
||||
working_hours?: Array<{
|
||||
weekday: string
|
||||
start_time: string
|
||||
end_time: string
|
||||
}>
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPathsCreateResponse extends ToolResponse {
|
||||
output: {
|
||||
escalation_path: IncidentioEscalationPath
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPathsShowParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPathsShowResponse extends ToolResponse {
|
||||
output: {
|
||||
escalation_path: IncidentioEscalationPath
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPathsUpdateParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
name?: string
|
||||
path?: Array<{
|
||||
targets: Array<{
|
||||
id: string
|
||||
type: string
|
||||
schedule_id?: string
|
||||
user_id?: string
|
||||
urgency: string
|
||||
}>
|
||||
time_to_ack_seconds: number
|
||||
}>
|
||||
working_hours?: Array<{
|
||||
weekday: string
|
||||
start_time: string
|
||||
end_time: string
|
||||
}>
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPathsUpdateResponse extends ToolResponse {
|
||||
output: {
|
||||
escalation_path: IncidentioEscalationPath
|
||||
}
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPathsDeleteParams extends IncidentioBaseParams {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IncidentioEscalationPathsDeleteResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { IncidentioUsersListParams, IncidentioUsersListResponse } from './types'
|
||||
|
||||
export const usersListTool: ToolConfig<IncidentioUsersListParams, IncidentioUsersListResponse> = {
|
||||
id: 'incidentio_users_list',
|
||||
name: 'Incident.io Users List',
|
||||
description:
|
||||
'List all users in your Incident.io workspace. Returns user details including id, name, email, and role.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Incident.io API Key',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Number of results to return per page (default: 25)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = 'https://api.incident.io/v2/users'
|
||||
if (params.page_size) {
|
||||
return `${baseUrl}?page_size=${params.page_size}`
|
||||
}
|
||||
return baseUrl
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
users: data.users.map((user: any) => ({
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
role: user.role,
|
||||
})),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
users: {
|
||||
type: 'array',
|
||||
description: 'List of users in the workspace',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the user' },
|
||||
name: { type: 'string', description: 'Full name of the user' },
|
||||
email: { type: 'string', description: 'Email address of the user' },
|
||||
role: { type: 'string', description: 'Role of the user in the workspace' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { IncidentioUsersShowParams, IncidentioUsersShowResponse } from './types'
|
||||
|
||||
export const usersShowTool: ToolConfig<IncidentioUsersShowParams, IncidentioUsersShowResponse> = {
|
||||
id: 'incidentio_users_show',
|
||||
name: 'Incident.io Users Show',
|
||||
description:
|
||||
'Get detailed information about a specific user in your Incident.io workspace by their ID.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The unique identifier of the user to retrieve',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/users/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
user: {
|
||||
id: data.user.id,
|
||||
name: data.user.name,
|
||||
email: data.user.email,
|
||||
role: data.user.role,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
user: {
|
||||
type: 'object',
|
||||
description: 'Details of the requested user',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the user' },
|
||||
name: { type: 'string', description: 'Full name of the user' },
|
||||
email: { type: 'string', description: 'Email address of the user' },
|
||||
role: { type: 'string', description: 'Role of the user in the workspace' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { WorkflowsCreateParams, WorkflowsCreateResponse } from './types'
|
||||
|
||||
export const workflowsCreateTool: ToolConfig<WorkflowsCreateParams, WorkflowsCreateResponse> = {
|
||||
id: 'incidentio_workflows_create',
|
||||
name: 'incident.io Workflows Create',
|
||||
description: 'Create a new workflow in incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the workflow',
|
||||
},
|
||||
folder: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Folder to organize the workflow in',
|
||||
},
|
||||
state: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'State of the workflow (active, draft, or disabled)',
|
||||
default: 'active',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/workflows',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
// incident.io requires all these fields to create a workflow
|
||||
const body: Record<string, any> = {
|
||||
name: params.name,
|
||||
trigger: 'incident.updated',
|
||||
once_for: [],
|
||||
condition_groups: [],
|
||||
steps: [],
|
||||
expressions: [],
|
||||
include_private_incidents: true,
|
||||
runs_on_incident_modes: ['standard'],
|
||||
continue_on_step_error: false,
|
||||
runs_on_incidents: 'newly_created',
|
||||
state: params.state || 'draft',
|
||||
}
|
||||
|
||||
if (params.folder) {
|
||||
body.folder = params.folder
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
workflow: {
|
||||
id: data.workflow.id,
|
||||
name: data.workflow.name,
|
||||
state: data.workflow.state,
|
||||
folder: data.workflow.folder,
|
||||
created_at: data.workflow.created_at,
|
||||
updated_at: data.workflow.updated_at,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
workflow: {
|
||||
type: 'object',
|
||||
description: 'The created workflow',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the workflow' },
|
||||
name: { type: 'string', description: 'Name of the workflow' },
|
||||
state: {
|
||||
type: 'string',
|
||||
description: 'State of the workflow (active, draft, or disabled)',
|
||||
},
|
||||
folder: { type: 'string', description: 'Folder the workflow belongs to', optional: true },
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'When the workflow was created',
|
||||
optional: true,
|
||||
},
|
||||
updated_at: {
|
||||
type: 'string',
|
||||
description: 'When the workflow was last updated',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { WorkflowsDeleteParams, WorkflowsDeleteResponse } from './types'
|
||||
|
||||
export const workflowsDeleteTool: ToolConfig<WorkflowsDeleteParams, WorkflowsDeleteResponse> = {
|
||||
id: 'incidentio_workflows_delete',
|
||||
name: 'incident.io Workflows Delete',
|
||||
description: 'Delete a workflow in incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the workflow to delete',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/workflows/${params.id}`,
|
||||
method: 'DELETE',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: 'Workflow deleted successfully',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'Success message',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { WorkflowsListParams, WorkflowsListResponse } from './types'
|
||||
|
||||
export const workflowsListTool: ToolConfig<WorkflowsListParams, WorkflowsListResponse> = {
|
||||
id: 'incidentio_workflows_list',
|
||||
name: 'incident.io Workflows List',
|
||||
description: 'List all workflows in your incident.io workspace.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Number of workflows to return per page',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Pagination cursor to fetch the next page of results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/workflows')
|
||||
|
||||
if (params.page_size) {
|
||||
url.searchParams.set('page_size', Number(params.page_size).toString())
|
||||
}
|
||||
|
||||
if (params.after) {
|
||||
url.searchParams.set('after', params.after)
|
||||
}
|
||||
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
workflows: data.workflows.map((workflow: any) => ({
|
||||
id: workflow.id,
|
||||
name: workflow.name,
|
||||
state: workflow.state,
|
||||
folder: workflow.folder,
|
||||
created_at: workflow.created_at,
|
||||
updated_at: workflow.updated_at,
|
||||
})),
|
||||
pagination_meta: data.pagination_meta
|
||||
? {
|
||||
after: data.pagination_meta.after,
|
||||
page_size: data.pagination_meta.page_size,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
workflows: {
|
||||
type: 'array',
|
||||
description: 'List of workflows',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the workflow' },
|
||||
name: { type: 'string', description: 'Name of the workflow' },
|
||||
state: {
|
||||
type: 'string',
|
||||
description: 'State of the workflow (active, draft, or disabled)',
|
||||
},
|
||||
folder: { type: 'string', description: 'Folder the workflow belongs to', optional: true },
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'When the workflow was created',
|
||||
optional: true,
|
||||
},
|
||||
updated_at: {
|
||||
type: 'string',
|
||||
description: 'When the workflow was last updated',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination_meta: {
|
||||
type: 'object',
|
||||
description: 'Pagination metadata',
|
||||
optional: true,
|
||||
properties: {
|
||||
after: { type: 'string', description: 'Cursor for next page', optional: true },
|
||||
page_size: { type: 'number', description: 'Number of results per page' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { WorkflowsShowParams, WorkflowsShowResponse } from './types'
|
||||
|
||||
export const workflowsShowTool: ToolConfig<WorkflowsShowParams, WorkflowsShowResponse> = {
|
||||
id: 'incidentio_workflows_show',
|
||||
name: 'incident.io Workflows Show',
|
||||
description: 'Get details of a specific workflow in incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the workflow to retrieve',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/workflows/${params.id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
workflow: {
|
||||
id: data.workflow.id,
|
||||
name: data.workflow.name,
|
||||
state: data.workflow.state,
|
||||
folder: data.workflow.folder,
|
||||
created_at: data.workflow.created_at,
|
||||
updated_at: data.workflow.updated_at,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
workflow: {
|
||||
type: 'object',
|
||||
description: 'The workflow details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the workflow' },
|
||||
name: { type: 'string', description: 'Name of the workflow' },
|
||||
state: {
|
||||
type: 'string',
|
||||
description: 'State of the workflow (active, draft, or disabled)',
|
||||
},
|
||||
folder: { type: 'string', description: 'Folder the workflow belongs to', optional: true },
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'When the workflow was created',
|
||||
optional: true,
|
||||
},
|
||||
updated_at: {
|
||||
type: 'string',
|
||||
description: 'When the workflow was last updated',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { WorkflowsUpdateParams, WorkflowsUpdateResponse } from './types'
|
||||
|
||||
export const workflowsUpdateTool: ToolConfig<WorkflowsUpdateParams, WorkflowsUpdateResponse> = {
|
||||
id: 'incidentio_workflows_update',
|
||||
name: 'incident.io Workflows Update',
|
||||
description: 'Update an existing workflow in incident.io.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'incident.io API Key',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the workflow to update',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New name for the workflow',
|
||||
},
|
||||
state: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New state for the workflow (active, draft, or disabled)',
|
||||
},
|
||||
folder: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New folder for the workflow',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/workflows/${params.id}`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {}
|
||||
|
||||
if (params.name) {
|
||||
body.name = params.name
|
||||
}
|
||||
|
||||
if (params.state) {
|
||||
body.state = params.state
|
||||
}
|
||||
|
||||
if (params.folder) {
|
||||
body.folder = params.folder
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
workflow: {
|
||||
id: data.workflow.id,
|
||||
name: data.workflow.name,
|
||||
state: data.workflow.state,
|
||||
folder: data.workflow.folder,
|
||||
created_at: data.workflow.created_at,
|
||||
updated_at: data.workflow.updated_at,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
workflow: {
|
||||
type: 'object',
|
||||
description: 'The updated workflow',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the workflow' },
|
||||
name: { type: 'string', description: 'Name of the workflow' },
|
||||
state: {
|
||||
type: 'string',
|
||||
description: 'State of the workflow (active, draft, or disabled)',
|
||||
},
|
||||
folder: { type: 'string', description: 'Folder the workflow belongs to', optional: true },
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'When the workflow was created',
|
||||
optional: true,
|
||||
},
|
||||
updated_at: {
|
||||
type: 'string',
|
||||
description: 'When the workflow was last updated',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import { executeTool } from '@/tools/index'
|
||||
import { tools } from '@/tools/registry'
|
||||
import { getTool } from '@/tools/utils'
|
||||
|
||||
// Helper function to create mock ExecutionContext
|
||||
const createMockExecutionContext = (overrides?: Partial<ExecutionContext>): ExecutionContext => ({
|
||||
workflowId: 'test-workflow',
|
||||
workspaceId: 'workspace-456',
|
||||
@@ -33,11 +32,9 @@ describe('Tools Registry', () => {
|
||||
it('should include all expected built-in tools', () => {
|
||||
expect(Object.keys(tools).length).toBeGreaterThan(10)
|
||||
|
||||
// Check for existence of some core tools
|
||||
expect(tools.http_request).toBeDefined()
|
||||
expect(tools.function_execute).toBeDefined()
|
||||
|
||||
// Check for some integrations
|
||||
expect(tools.gmail_read).toBeDefined()
|
||||
expect(tools.gmail_send).toBeDefined()
|
||||
expect(tools.google_drive_list).toBeDefined()
|
||||
@@ -64,7 +61,6 @@ describe('Tools Registry', () => {
|
||||
|
||||
describe('Custom Tools', () => {
|
||||
beforeEach(() => {
|
||||
// Mock custom tools store
|
||||
vi.mock('@/stores/custom-tools/store', () => ({
|
||||
useCustomToolsStore: {
|
||||
getState: () => ({
|
||||
@@ -115,7 +111,6 @@ describe('Custom Tools', () => {
|
||||
},
|
||||
}))
|
||||
|
||||
// Mock environment store
|
||||
vi.mock('@/stores/settings/environment/store', () => ({
|
||||
useEnvironmentStore: {
|
||||
getState: () => ({
|
||||
@@ -151,7 +146,6 @@ describe('executeTool Function', () => {
|
||||
let cleanupEnvVars: () => void
|
||||
|
||||
beforeEach(() => {
|
||||
// Mock fetch
|
||||
global.fetch = Object.assign(
|
||||
vi.fn().mockImplementation(async (url, options) => {
|
||||
const mockResponse = {
|
||||
@@ -180,7 +174,6 @@ describe('executeTool Function', () => {
|
||||
{ preconnect: vi.fn() }
|
||||
) as typeof fetch
|
||||
|
||||
// Set environment variables
|
||||
process.env.NEXT_PUBLIC_APP_URL = 'http://localhost:3000'
|
||||
cleanupEnvVars = mockEnvironmentVariables({
|
||||
NEXT_PUBLIC_APP_URL: 'http://localhost:3000',
|
||||
@@ -200,7 +193,7 @@ describe('executeTool Function', () => {
|
||||
method: 'GET',
|
||||
},
|
||||
true
|
||||
) // Skip proxy
|
||||
)
|
||||
|
||||
expect(result.success).toBe(true)
|
||||
expect(result.output).toBeDefined()
|
||||
@@ -211,7 +204,6 @@ describe('executeTool Function', () => {
|
||||
})
|
||||
|
||||
it('should call internal routes directly', async () => {
|
||||
// Mock transformResponse for function_execute tool
|
||||
const originalFunctionTool = { ...tools.function_execute }
|
||||
tools.function_execute = {
|
||||
...tools.function_execute,
|
||||
@@ -230,10 +222,8 @@ describe('executeTool Function', () => {
|
||||
true
|
||||
) // Skip proxy
|
||||
|
||||
// Restore original tool
|
||||
tools.function_execute = originalFunctionTool
|
||||
|
||||
// Expect transform response to have been called
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/function/execute'),
|
||||
expect.anything()
|
||||
@@ -241,12 +231,10 @@ describe('executeTool Function', () => {
|
||||
})
|
||||
|
||||
it('should handle non-existent tool', async () => {
|
||||
// Create the mock with a matching implementation
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
|
||||
const result = await executeTool('non_existent_tool', {})
|
||||
|
||||
// Expect failure
|
||||
expect(result.success).toBe(false)
|
||||
expect(result.error).toContain('Tool not found')
|
||||
|
||||
@@ -254,7 +242,6 @@ describe('executeTool Function', () => {
|
||||
})
|
||||
|
||||
it('should handle errors from tools', async () => {
|
||||
// Mock a failed response
|
||||
global.fetch = Object.assign(
|
||||
vi.fn().mockImplementation(async () => {
|
||||
return {
|
||||
@@ -315,7 +302,6 @@ describe('Automatic Internal Route Detection', () => {
|
||||
})
|
||||
|
||||
it('should detect internal routes (URLs starting with /api/) and call them directly', async () => {
|
||||
// Mock a tool with an internal route
|
||||
const mockTool = {
|
||||
id: 'test_internal_tool',
|
||||
name: 'Test Internal Tool',
|
||||
@@ -333,14 +319,11 @@ describe('Automatic Internal Route Detection', () => {
|
||||
}),
|
||||
}
|
||||
|
||||
// Mock the tool registry to include our test tool
|
||||
const originalTools = { ...tools }
|
||||
;(tools as any).test_internal_tool = mockTool
|
||||
|
||||
// Mock fetch for the internal API call
|
||||
global.fetch = Object.assign(
|
||||
vi.fn().mockImplementation(async (url) => {
|
||||
// Should call the internal API directly, not the proxy
|
||||
expect(url).toBe('http://localhost:3000/api/test/endpoint')
|
||||
const responseData = { success: true, data: 'test' }
|
||||
return {
|
||||
@@ -362,12 +345,10 @@ describe('Automatic Internal Route Detection', () => {
|
||||
expect(result.output.result).toBe('Internal route success')
|
||||
expect(mockTool.transformResponse).toHaveBeenCalled()
|
||||
|
||||
// Restore original tools
|
||||
Object.assign(tools, originalTools)
|
||||
})
|
||||
|
||||
it('should detect external routes (full URLs) and use proxy', async () => {
|
||||
// Mock a tool with an external route
|
||||
const mockTool = {
|
||||
id: 'test_external_tool',
|
||||
name: 'Test External Tool',
|
||||
@@ -381,11 +362,9 @@ describe('Automatic Internal Route Detection', () => {
|
||||
},
|
||||
}
|
||||
|
||||
// Mock the tool registry to include our test tool
|
||||
const originalTools = { ...tools }
|
||||
;(tools as any).test_external_tool = mockTool
|
||||
|
||||
// Mock fetch for the proxy call
|
||||
global.fetch = Object.assign(
|
||||
vi.fn().mockImplementation(async (url) => {
|
||||
// Should call the proxy, not the external API directly
|
||||
@@ -416,7 +395,6 @@ describe('Automatic Internal Route Detection', () => {
|
||||
})
|
||||
|
||||
it('should handle dynamic URLs that resolve to internal routes', async () => {
|
||||
// Mock a tool with a dynamic URL function that returns internal route
|
||||
const mockTool = {
|
||||
id: 'test_dynamic_internal',
|
||||
name: 'Test Dynamic Internal Tool',
|
||||
@@ -469,7 +447,6 @@ describe('Automatic Internal Route Detection', () => {
|
||||
})
|
||||
|
||||
it('should handle dynamic URLs that resolve to external routes', async () => {
|
||||
// Mock a tool with a dynamic URL function that returns external route
|
||||
const mockTool = {
|
||||
id: 'test_dynamic_external',
|
||||
name: 'Test Dynamic External Tool',
|
||||
@@ -485,14 +462,11 @@ describe('Automatic Internal Route Detection', () => {
|
||||
},
|
||||
}
|
||||
|
||||
// Mock the tool registry to include our test tool
|
||||
const originalTools = { ...tools }
|
||||
;(tools as any).test_dynamic_external = mockTool
|
||||
|
||||
// Mock fetch for the proxy call
|
||||
global.fetch = Object.assign(
|
||||
vi.fn().mockImplementation(async (url) => {
|
||||
// Should call the proxy, not the external API directly
|
||||
expect(url).toBe('http://localhost:3000/api/proxy')
|
||||
const responseData = {
|
||||
success: true,
|
||||
@@ -515,7 +489,6 @@ describe('Automatic Internal Route Detection', () => {
|
||||
expect(result.success).toBe(true)
|
||||
expect(result.output.result).toBe('Dynamic external route via proxy')
|
||||
|
||||
// Restore original tools
|
||||
Object.assign(tools, originalTools)
|
||||
})
|
||||
|
||||
@@ -679,19 +652,19 @@ describe('Centralized Error Handling', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should fall back to HTTP status when JSON parsing fails', async () => {
|
||||
it('should fall back to text when JSON parsing fails and extract error message', async () => {
|
||||
global.fetch = Object.assign(
|
||||
vi.fn().mockImplementation(async () => ({
|
||||
ok: false,
|
||||
status: 500,
|
||||
statusText: 'Internal Server Error',
|
||||
status: 401,
|
||||
statusText: 'Unauthorized',
|
||||
headers: {
|
||||
get: (key: string) => (key === 'content-type' ? 'text/plain' : null),
|
||||
forEach: (callback: (value: string, key: string) => void) => {
|
||||
callback('text/plain', 'content-type')
|
||||
},
|
||||
},
|
||||
text: () => Promise.resolve('Invalid JSON response'),
|
||||
text: () => Promise.resolve('Invalid access token'),
|
||||
json: () => Promise.reject(new Error('Invalid JSON')),
|
||||
clone: vi.fn().mockReturnThis(),
|
||||
})),
|
||||
@@ -705,7 +678,67 @@ describe('Centralized Error Handling', () => {
|
||||
)
|
||||
|
||||
expect(result.success).toBe(false)
|
||||
expect(result.error).toBe('Failed to parse response from function_execute: Error: Invalid JSON')
|
||||
// Should extract the text error message, not the JSON parsing error
|
||||
expect(result.error).toBe('Invalid access token')
|
||||
})
|
||||
|
||||
it('should handle plain text error responses from APIs like Apollo', async () => {
|
||||
global.fetch = Object.assign(
|
||||
vi.fn().mockImplementation(async () => ({
|
||||
ok: false,
|
||||
status: 403,
|
||||
statusText: 'Forbidden',
|
||||
headers: {
|
||||
get: (key: string) => (key === 'content-type' ? 'text/plain' : null),
|
||||
forEach: (callback: (value: string, key: string) => void) => {
|
||||
callback('text/plain', 'content-type')
|
||||
},
|
||||
},
|
||||
text: () => Promise.resolve('Invalid API key provided'),
|
||||
json: () => Promise.reject(new Error('Unexpected token I')),
|
||||
clone: vi.fn().mockReturnThis(),
|
||||
})),
|
||||
{ preconnect: vi.fn() }
|
||||
) as typeof fetch
|
||||
|
||||
const result = await executeTool(
|
||||
'function_execute',
|
||||
{ code: 'return { result: "test" }' },
|
||||
true
|
||||
)
|
||||
|
||||
expect(result.success).toBe(false)
|
||||
expect(result.error).toBe('Invalid API key provided')
|
||||
})
|
||||
|
||||
it('should fall back to HTTP status text when both JSON and text parsing fail', async () => {
|
||||
global.fetch = Object.assign(
|
||||
vi.fn().mockImplementation(async () => ({
|
||||
ok: false,
|
||||
status: 500,
|
||||
statusText: 'Internal Server Error',
|
||||
headers: {
|
||||
get: (key: string) => (key === 'content-type' ? 'text/plain' : null),
|
||||
forEach: (callback: (value: string, key: string) => void) => {
|
||||
callback('text/plain', 'content-type')
|
||||
},
|
||||
},
|
||||
text: () => Promise.reject(new Error('Cannot read response')),
|
||||
json: () => Promise.reject(new Error('Invalid JSON')),
|
||||
clone: vi.fn().mockReturnThis(),
|
||||
})),
|
||||
{ preconnect: vi.fn() }
|
||||
) as typeof fetch
|
||||
|
||||
const result = await executeTool(
|
||||
'function_execute',
|
||||
{ code: 'return { result: "test" }' },
|
||||
true
|
||||
)
|
||||
|
||||
expect(result.success).toBe(false)
|
||||
// Should fall back to HTTP status text when both parsing methods fail
|
||||
expect(result.error).toBe('Internal Server Error')
|
||||
})
|
||||
|
||||
it('should handle complex nested error objects', async () => {
|
||||
|
||||
+22
-15
@@ -499,29 +499,36 @@ async function handleInternalRequest(
|
||||
|
||||
const response = await fetch(fullUrl, requestOptions)
|
||||
|
||||
// For non-OK responses, attempt JSON first; if parsing fails, preserve legacy error expected by tests
|
||||
// For non-OK responses, attempt JSON first; if parsing fails, fall back to text
|
||||
if (!response.ok) {
|
||||
let errorData: any
|
||||
try {
|
||||
errorData = await response.json()
|
||||
} catch (jsonError) {
|
||||
logger.error(`[${requestId}] JSON parse error for ${toolId}:`, {
|
||||
error: jsonError instanceof Error ? jsonError.message : String(jsonError),
|
||||
})
|
||||
throw new Error(`Failed to parse response from ${toolId}: ${jsonError}`)
|
||||
// JSON parsing failed, fall back to reading as text for error extraction
|
||||
logger.warn(`[${requestId}] Response is not JSON for ${toolId}, reading as text`)
|
||||
try {
|
||||
errorData = await response.text()
|
||||
} catch (textError) {
|
||||
logger.error(`[${requestId}] Failed to read response body for ${toolId}`)
|
||||
errorData = null
|
||||
}
|
||||
}
|
||||
|
||||
const { isError, errorInfo } = isErrorResponse(response, errorData)
|
||||
if (isError) {
|
||||
const errorToTransform = createTransformedErrorFromErrorInfo(errorInfo, tool.errorExtractor)
|
||||
|
||||
logger.error(`[${requestId}] Internal API error for ${toolId}:`, {
|
||||
status: errorInfo?.status,
|
||||
errorData: errorInfo?.data,
|
||||
})
|
||||
|
||||
throw errorToTransform
|
||||
const errorInfo: ErrorInfo = {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
data: errorData,
|
||||
}
|
||||
|
||||
const errorToTransform = createTransformedErrorFromErrorInfo(errorInfo, tool.errorExtractor)
|
||||
|
||||
logger.error(`[${requestId}] Internal API error for ${toolId}:`, {
|
||||
status: errorInfo.status,
|
||||
errorData: errorInfo.data,
|
||||
})
|
||||
|
||||
throw errorToTransform
|
||||
}
|
||||
|
||||
// Parse response data once with guard for empty 202 bodies
|
||||
|
||||
@@ -443,7 +443,6 @@ async function applyDynamicSchemaForWorkflow(
|
||||
async function fetchWorkflowInputFields(
|
||||
workflowId: string
|
||||
): Promise<Array<{ name: string; type: string }>> {
|
||||
// Check cache first
|
||||
const cached = workflowInputFieldsCache.get(workflowId)
|
||||
const now = Date.now()
|
||||
|
||||
@@ -491,7 +490,6 @@ async function fetchWorkflowInputFields(
|
||||
}))
|
||||
}
|
||||
|
||||
// Cache the result
|
||||
workflowInputFieldsCache.set(workflowId, { fields, timestamp: now })
|
||||
|
||||
return fields
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export interface PostHogBatchEventsParams {
|
||||
projectApiKey: string
|
||||
region?: 'us' | 'eu'
|
||||
batch: string
|
||||
}
|
||||
|
||||
export interface PostHogBatchEventsResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
status: string
|
||||
eventsProcessed: number
|
||||
}
|
||||
}
|
||||
|
||||
export const batchEventsTool: ToolConfig<PostHogBatchEventsParams, PostHogBatchEventsResponse> = {
|
||||
id: 'posthog_batch_events',
|
||||
name: 'PostHog Batch Events',
|
||||
description:
|
||||
'Capture multiple events at once in PostHog. Use this for bulk event ingestion to improve performance.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
projectApiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Project API Key (public token for event ingestion)',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog region: us (default) or eu',
|
||||
default: 'us',
|
||||
},
|
||||
batch: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'JSON array of events to capture. Each event should have: event, distinct_id, and optional properties, timestamp. Example: [{"event": "page_view", "distinct_id": "user123", "properties": {"page": "/"}}]',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl =
|
||||
params.region === 'eu' ? 'https://eu.i.posthog.com' : 'https://us.i.posthog.com'
|
||||
return `${baseUrl}/batch/`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
let batch: any[]
|
||||
try {
|
||||
batch = JSON.parse(params.batch)
|
||||
} catch (e) {
|
||||
batch = []
|
||||
}
|
||||
|
||||
return {
|
||||
api_key: params.projectApiKey,
|
||||
batch: batch,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
status: 'Batch events captured successfully',
|
||||
eventsProcessed: data.status === 1 ? JSON.parse(data.batch || '[]').length : 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const error = await response.text()
|
||||
return {
|
||||
success: false,
|
||||
output: {
|
||||
status: 'Failed to capture batch events',
|
||||
eventsProcessed: 0,
|
||||
},
|
||||
error: error || 'Unknown error occurred',
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
status: {
|
||||
type: 'string',
|
||||
description: 'Status message indicating whether the batch was captured successfully',
|
||||
},
|
||||
eventsProcessed: {
|
||||
type: 'number',
|
||||
description: 'Number of events processed in the batch',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export interface PostHogCaptureEventParams {
|
||||
projectApiKey: string
|
||||
region?: 'us' | 'eu'
|
||||
event: string
|
||||
distinctId: string
|
||||
properties?: string
|
||||
timestamp?: string
|
||||
}
|
||||
|
||||
export interface PostHogCaptureEventResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
status: string
|
||||
}
|
||||
}
|
||||
|
||||
export const captureEventTool: ToolConfig<PostHogCaptureEventParams, PostHogCaptureEventResponse> =
|
||||
{
|
||||
id: 'posthog_capture_event',
|
||||
name: 'PostHog Capture Event',
|
||||
description:
|
||||
'Capture a single event in PostHog. Use this to track user actions, page views, or custom events.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
projectApiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Project API Key (public token for event ingestion)',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog region: us (default) or eu',
|
||||
default: 'us',
|
||||
},
|
||||
event: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The name of the event to capture (e.g., "page_view", "button_clicked")',
|
||||
},
|
||||
distinctId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Unique identifier for the user or device. Can be user ID, device ID, or anonymous ID',
|
||||
},
|
||||
properties: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'JSON string of event properties (e.g., {"button_name": "signup", "page": "homepage"})',
|
||||
},
|
||||
timestamp: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'ISO 8601 timestamp for when the event occurred. If not provided, uses current time',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl =
|
||||
params.region === 'eu' ? 'https://eu.i.posthog.com' : 'https://us.i.posthog.com'
|
||||
return `${baseUrl}/capture/`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
api_key: params.projectApiKey,
|
||||
event: params.event,
|
||||
distinct_id: params.distinctId,
|
||||
}
|
||||
|
||||
if (params.properties) {
|
||||
try {
|
||||
body.properties = JSON.parse(params.properties)
|
||||
} catch (e) {
|
||||
body.properties = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.timestamp) {
|
||||
body.timestamp = params.timestamp
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (response.ok) {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
status: 'Event captured successfully',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const error = await response.text()
|
||||
return {
|
||||
success: false,
|
||||
output: {
|
||||
status: 'Failed to capture event',
|
||||
},
|
||||
error: error || 'Unknown error occurred',
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
status: {
|
||||
type: 'string',
|
||||
description: 'Status message indicating whether the event was captured successfully',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface PostHogCreateAnnotationParams {
|
||||
apiKey: string
|
||||
projectId: string
|
||||
region: string
|
||||
content: string
|
||||
date_marker: string
|
||||
scope?: string
|
||||
dashboard_item?: string
|
||||
insight_short_id?: string
|
||||
}
|
||||
|
||||
interface PostHogCreateAnnotationResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
id: number
|
||||
content: string
|
||||
date_marker: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
created_by: Record<string, any> | null
|
||||
dashboard_item: number | null
|
||||
insight_short_id: string | null
|
||||
insight_name: string | null
|
||||
scope: string
|
||||
deleted: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export const createAnnotationTool: ToolConfig<
|
||||
PostHogCreateAnnotationParams,
|
||||
PostHogCreateAnnotationResponse
|
||||
> = {
|
||||
id: 'posthog_create_annotation',
|
||||
name: 'PostHog Create Annotation',
|
||||
description:
|
||||
'Create a new annotation in PostHog. Mark important events on your graphs with date and description.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The PostHog project ID',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: "us" or "eu" (default: "us")',
|
||||
default: 'us',
|
||||
},
|
||||
content: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Content/text of the annotation',
|
||||
},
|
||||
date_marker: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'ISO timestamp marking when the annotation applies (e.g., "2024-01-15T10:00:00Z")',
|
||||
},
|
||||
scope: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Scope of the annotation: "project" or "dashboard_item" (default: "project")',
|
||||
},
|
||||
dashboard_item: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of dashboard item to attach this annotation to',
|
||||
},
|
||||
insight_short_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Short ID of the insight to attach this annotation to',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/annotations/`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
content: params.content,
|
||||
date_marker: params.date_marker,
|
||||
}
|
||||
|
||||
if (params.scope) {
|
||||
body.scope = params.scope
|
||||
}
|
||||
|
||||
if (params.dashboard_item) {
|
||||
body.dashboard_item = Number(params.dashboard_item)
|
||||
}
|
||||
|
||||
if (params.insight_short_id) {
|
||||
body.insight_short_id = params.insight_short_id
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.id,
|
||||
content: data.content || '',
|
||||
date_marker: data.date_marker,
|
||||
created_at: data.created_at,
|
||||
updated_at: data.updated_at,
|
||||
created_by: data.created_by || null,
|
||||
dashboard_item: data.dashboard_item || null,
|
||||
insight_short_id: data.insight_short_id || null,
|
||||
insight_name: data.insight_name || null,
|
||||
scope: data.scope || '',
|
||||
deleted: data.deleted || false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: {
|
||||
type: 'number',
|
||||
description: 'Unique identifier for the created annotation',
|
||||
},
|
||||
content: {
|
||||
type: 'string',
|
||||
description: 'Content/text of the annotation',
|
||||
},
|
||||
date_marker: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp marking when the annotation applies',
|
||||
},
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when annotation was created',
|
||||
},
|
||||
updated_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when annotation was last updated',
|
||||
},
|
||||
created_by: {
|
||||
type: 'object',
|
||||
description: 'User who created the annotation',
|
||||
optional: true,
|
||||
},
|
||||
dashboard_item: {
|
||||
type: 'number',
|
||||
description: 'ID of dashboard item this annotation is attached to',
|
||||
optional: true,
|
||||
},
|
||||
insight_short_id: {
|
||||
type: 'string',
|
||||
description: 'Short ID of the insight this annotation is attached to',
|
||||
optional: true,
|
||||
},
|
||||
insight_name: {
|
||||
type: 'string',
|
||||
description: 'Name of the insight this annotation is attached to',
|
||||
optional: true,
|
||||
},
|
||||
scope: {
|
||||
type: 'string',
|
||||
description: 'Scope of the annotation (project or dashboard_item)',
|
||||
},
|
||||
deleted: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the annotation is deleted',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface PostHogCreateCohortParams {
|
||||
apiKey: string
|
||||
projectId: string
|
||||
region: string
|
||||
name: string
|
||||
description?: string
|
||||
filters?: string
|
||||
query?: string
|
||||
is_static?: boolean
|
||||
groups?: string
|
||||
}
|
||||
|
||||
interface PostHogCreateCohortResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
groups: Array<Record<string, any>>
|
||||
deleted: boolean
|
||||
filters: Record<string, any>
|
||||
query: Record<string, any> | null
|
||||
created_at: string
|
||||
created_by: Record<string, any> | null
|
||||
is_calculating: boolean
|
||||
count: number
|
||||
is_static: boolean
|
||||
version: number
|
||||
}
|
||||
}
|
||||
|
||||
export const createCohortTool: ToolConfig<PostHogCreateCohortParams, PostHogCreateCohortResponse> =
|
||||
{
|
||||
id: 'posthog_create_cohort',
|
||||
name: 'PostHog Create Cohort',
|
||||
description:
|
||||
'Create a new cohort in PostHog. Requires cohort name and filter or query configuration.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The PostHog project ID',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: "us" or "eu" (default: "us")',
|
||||
default: 'us',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Name for the cohort (optional - PostHog will use "Untitled cohort" if not provided)',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Description of the cohort',
|
||||
},
|
||||
filters: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON string of filter configuration for the cohort',
|
||||
},
|
||||
query: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON string of query configuration for the cohort',
|
||||
},
|
||||
is_static: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether the cohort is static (default: false)',
|
||||
default: false,
|
||||
},
|
||||
groups: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON string of groups that define the cohort',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/cohorts/`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
name: params.name,
|
||||
}
|
||||
|
||||
if (params.description) {
|
||||
body.description = params.description
|
||||
}
|
||||
|
||||
if (params.filters) {
|
||||
try {
|
||||
body.filters = JSON.parse(params.filters)
|
||||
} catch (e) {
|
||||
body.filters = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.query) {
|
||||
try {
|
||||
body.query = JSON.parse(params.query)
|
||||
} catch (e) {
|
||||
body.query = null
|
||||
}
|
||||
}
|
||||
|
||||
if (params.is_static !== undefined) {
|
||||
body.is_static = params.is_static
|
||||
}
|
||||
|
||||
if (params.groups) {
|
||||
try {
|
||||
body.groups = JSON.parse(params.groups)
|
||||
} catch (e) {
|
||||
body.groups = []
|
||||
}
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.id,
|
||||
name: data.name || '',
|
||||
description: data.description || '',
|
||||
groups: data.groups || [],
|
||||
deleted: data.deleted || false,
|
||||
filters: data.filters || {},
|
||||
query: data.query || null,
|
||||
created_at: data.created_at,
|
||||
created_by: data.created_by || null,
|
||||
is_calculating: data.is_calculating || false,
|
||||
count: data.count || 0,
|
||||
is_static: data.is_static || false,
|
||||
version: data.version || 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: {
|
||||
type: 'number',
|
||||
description: 'Unique identifier for the created cohort',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the cohort',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'Description of the cohort',
|
||||
},
|
||||
groups: {
|
||||
type: 'array',
|
||||
description: 'Groups that define the cohort',
|
||||
},
|
||||
deleted: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the cohort is deleted',
|
||||
},
|
||||
filters: {
|
||||
type: 'object',
|
||||
description: 'Filter configuration for the cohort',
|
||||
},
|
||||
query: {
|
||||
type: 'object',
|
||||
description: 'Query configuration for the cohort',
|
||||
optional: true,
|
||||
},
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when cohort was created',
|
||||
},
|
||||
created_by: {
|
||||
type: 'object',
|
||||
description: 'User who created the cohort',
|
||||
optional: true,
|
||||
},
|
||||
is_calculating: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the cohort is being calculated',
|
||||
},
|
||||
count: {
|
||||
type: 'number',
|
||||
description: 'Number of users in the cohort',
|
||||
},
|
||||
is_static: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the cohort is static',
|
||||
},
|
||||
version: {
|
||||
type: 'number',
|
||||
description: 'Version number of the cohort',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface CreateExperimentParams {
|
||||
projectId: string
|
||||
region: 'us' | 'eu'
|
||||
apiKey: string
|
||||
name: string
|
||||
description?: string
|
||||
featureFlagKey: string
|
||||
parameters?: string
|
||||
filters?: string
|
||||
variants?: string
|
||||
startDate?: string
|
||||
endDate?: string
|
||||
}
|
||||
|
||||
interface Experiment {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
feature_flag_key: string
|
||||
feature_flag: Record<string, any>
|
||||
parameters: Record<string, any>
|
||||
filters: Record<string, any>
|
||||
variants: Record<string, any>
|
||||
start_date: string | null
|
||||
end_date: string | null
|
||||
created_at: string
|
||||
created_by: Record<string, any>
|
||||
archived: boolean
|
||||
}
|
||||
|
||||
interface CreateExperimentResponse {
|
||||
experiment: Experiment
|
||||
}
|
||||
|
||||
export const createExperimentTool: ToolConfig<CreateExperimentParams, CreateExperimentResponse> = {
|
||||
id: 'posthog_create_experiment',
|
||||
name: 'PostHog Create Experiment',
|
||||
description: 'Create a new experiment in PostHog',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The PostHog project ID',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: us or eu',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Experiment name (optional)',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Experiment description',
|
||||
},
|
||||
featureFlagKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Feature flag key to use for the experiment',
|
||||
},
|
||||
parameters: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Experiment parameters as JSON string',
|
||||
},
|
||||
filters: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Experiment filters as JSON string',
|
||||
},
|
||||
variants: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Experiment variants as JSON string',
|
||||
},
|
||||
startDate: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Experiment start date (ISO format)',
|
||||
},
|
||||
endDate: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Experiment end date (ISO format)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/experiments/`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
name: params.name,
|
||||
feature_flag_key: params.featureFlagKey,
|
||||
}
|
||||
|
||||
if (params.description !== undefined) {
|
||||
body.description = params.description
|
||||
}
|
||||
|
||||
if (params.parameters) {
|
||||
try {
|
||||
body.parameters = JSON.parse(params.parameters)
|
||||
} catch {
|
||||
body.parameters = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.filters) {
|
||||
try {
|
||||
body.filters = JSON.parse(params.filters)
|
||||
} catch {
|
||||
body.filters = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.variants) {
|
||||
try {
|
||||
body.variants = JSON.parse(params.variants)
|
||||
} catch {
|
||||
body.variants = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.startDate !== undefined) {
|
||||
body.start_date = params.startDate
|
||||
}
|
||||
|
||||
if (params.endDate !== undefined) {
|
||||
body.end_date = params.endDate
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
experiment: data,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
experiment: {
|
||||
type: 'object',
|
||||
description: 'Created experiment',
|
||||
properties: {
|
||||
id: { type: 'number', description: 'Experiment ID' },
|
||||
name: { type: 'string', description: 'Experiment name' },
|
||||
description: { type: 'string', description: 'Experiment description' },
|
||||
feature_flag_key: { type: 'string', description: 'Associated feature flag key' },
|
||||
feature_flag: { type: 'object', description: 'Feature flag details' },
|
||||
parameters: { type: 'object', description: 'Experiment parameters' },
|
||||
filters: { type: 'object', description: 'Experiment filters' },
|
||||
variants: { type: 'object', description: 'Experiment variants' },
|
||||
start_date: { type: 'string', description: 'Start date' },
|
||||
end_date: { type: 'string', description: 'End date' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
created_by: { type: 'object', description: 'Creator information' },
|
||||
archived: { type: 'boolean', description: 'Whether the experiment is archived' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface CreateFeatureFlagParams {
|
||||
projectId: string
|
||||
region: 'us' | 'eu'
|
||||
apiKey: string
|
||||
name: string
|
||||
key: string
|
||||
filters?: string
|
||||
active?: boolean
|
||||
ensureExperienceContinuity?: boolean
|
||||
rolloutPercentage?: number
|
||||
}
|
||||
|
||||
interface FeatureFlag {
|
||||
id: number
|
||||
name: string
|
||||
key: string
|
||||
filters: Record<string, any>
|
||||
deleted: boolean
|
||||
active: boolean
|
||||
created_at: string
|
||||
created_by: Record<string, any>
|
||||
is_simple_flag: boolean
|
||||
rollout_percentage: number | null
|
||||
ensure_experience_continuity: boolean
|
||||
}
|
||||
|
||||
interface CreateFeatureFlagResponse {
|
||||
flag: FeatureFlag
|
||||
}
|
||||
|
||||
export const createFeatureFlagTool: ToolConfig<CreateFeatureFlagParams, CreateFeatureFlagResponse> =
|
||||
{
|
||||
id: 'posthog_create_feature_flag',
|
||||
name: 'PostHog Create Feature Flag',
|
||||
description: 'Create a new feature flag in PostHog',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The PostHog project ID',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: us or eu',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Feature flag name (optional - can be empty)',
|
||||
},
|
||||
key: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Feature flag key (unique identifier)',
|
||||
},
|
||||
filters: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Feature flag filters as JSON string',
|
||||
},
|
||||
active: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether the flag is active (default: true)',
|
||||
default: true,
|
||||
},
|
||||
ensureExperienceContinuity: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to ensure experience continuity (default: false)',
|
||||
default: false,
|
||||
},
|
||||
rolloutPercentage: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Rollout percentage (0-100)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/feature_flags/`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
name: params.name,
|
||||
key: params.key,
|
||||
}
|
||||
|
||||
if (params.filters) {
|
||||
try {
|
||||
body.filters = JSON.parse(params.filters)
|
||||
} catch {
|
||||
body.filters = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.active !== undefined) {
|
||||
body.active = params.active
|
||||
}
|
||||
|
||||
if (params.ensureExperienceContinuity !== undefined) {
|
||||
body.ensure_experience_continuity = params.ensureExperienceContinuity
|
||||
}
|
||||
|
||||
if (params.rolloutPercentage !== undefined) {
|
||||
body.rollout_percentage = params.rolloutPercentage
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
flag: data,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
flag: {
|
||||
type: 'object',
|
||||
description: 'Created feature flag',
|
||||
properties: {
|
||||
id: { type: 'number', description: 'Feature flag ID' },
|
||||
name: { type: 'string', description: 'Feature flag name' },
|
||||
key: { type: 'string', description: 'Feature flag key' },
|
||||
filters: { type: 'object', description: 'Feature flag filters' },
|
||||
deleted: { type: 'boolean', description: 'Whether the flag is deleted' },
|
||||
active: { type: 'boolean', description: 'Whether the flag is active' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
created_by: { type: 'object', description: 'Creator information' },
|
||||
is_simple_flag: { type: 'boolean', description: 'Whether this is a simple flag' },
|
||||
rollout_percentage: {
|
||||
type: 'number',
|
||||
description: 'Rollout percentage (if applicable)',
|
||||
},
|
||||
ensure_experience_continuity: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ensure experience continuity',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface PostHogCreateInsightParams {
|
||||
apiKey: string
|
||||
projectId: string
|
||||
region: string
|
||||
name: string
|
||||
description?: string
|
||||
filters?: string
|
||||
query?: string
|
||||
dashboards?: string
|
||||
tags?: string
|
||||
}
|
||||
|
||||
interface PostHogCreateInsightResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
filters: Record<string, any>
|
||||
query: Record<string, any> | null
|
||||
created_at: string
|
||||
created_by: Record<string, any> | null
|
||||
last_modified_at: string
|
||||
saved: boolean
|
||||
dashboards: number[]
|
||||
tags: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export const createInsightTool: ToolConfig<
|
||||
PostHogCreateInsightParams,
|
||||
PostHogCreateInsightResponse
|
||||
> = {
|
||||
id: 'posthog_create_insight',
|
||||
name: 'PostHog Create Insight',
|
||||
description:
|
||||
'Create a new insight in PostHog. Requires insight name and configuration filters or query.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The PostHog project ID',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: "us" or "eu" (default: "us")',
|
||||
default: 'us',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Name for the insight (optional - PostHog will generate a derived name if not provided)',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Description of the insight',
|
||||
},
|
||||
filters: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON string of filter configuration for the insight',
|
||||
},
|
||||
query: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON string of query configuration for the insight',
|
||||
},
|
||||
dashboards: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of dashboard IDs to add this insight to',
|
||||
},
|
||||
tags: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of tags for the insight',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/insights/`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
name: params.name,
|
||||
}
|
||||
|
||||
if (params.description) {
|
||||
body.description = params.description
|
||||
}
|
||||
|
||||
if (params.filters) {
|
||||
try {
|
||||
body.filters = JSON.parse(params.filters)
|
||||
} catch (e) {
|
||||
body.filters = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.query) {
|
||||
try {
|
||||
body.query = JSON.parse(params.query)
|
||||
} catch (e) {
|
||||
body.query = null
|
||||
}
|
||||
}
|
||||
|
||||
if (params.dashboards) {
|
||||
body.dashboards = params.dashboards
|
||||
.split(',')
|
||||
.map((id: string) => Number(id.trim()))
|
||||
.filter((id: number) => !Number.isNaN(id))
|
||||
}
|
||||
|
||||
if (params.tags) {
|
||||
body.tags = params.tags
|
||||
.split(',')
|
||||
.map((tag: string) => tag.trim())
|
||||
.filter((tag: string) => tag.length > 0)
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.id,
|
||||
name: data.name || '',
|
||||
description: data.description || '',
|
||||
filters: data.filters || {},
|
||||
query: data.query || null,
|
||||
created_at: data.created_at,
|
||||
created_by: data.created_by || null,
|
||||
last_modified_at: data.last_modified_at,
|
||||
saved: data.saved || false,
|
||||
dashboards: data.dashboards || [],
|
||||
tags: data.tags || [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: {
|
||||
type: 'number',
|
||||
description: 'Unique identifier for the created insight',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the insight',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'Description of the insight',
|
||||
},
|
||||
filters: {
|
||||
type: 'object',
|
||||
description: 'Filter configuration for the insight',
|
||||
},
|
||||
query: {
|
||||
type: 'object',
|
||||
description: 'Query configuration for the insight',
|
||||
optional: true,
|
||||
},
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when insight was created',
|
||||
},
|
||||
created_by: {
|
||||
type: 'object',
|
||||
description: 'User who created the insight',
|
||||
optional: true,
|
||||
},
|
||||
last_modified_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when insight was last modified',
|
||||
},
|
||||
saved: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the insight is saved',
|
||||
},
|
||||
dashboards: {
|
||||
type: 'array',
|
||||
description: 'IDs of dashboards this insight appears on',
|
||||
},
|
||||
tags: {
|
||||
type: 'array',
|
||||
description: 'Tags associated with the insight',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface PostHogSurveyQuestion {
|
||||
type: 'open' | 'link' | 'rating' | 'multiple_choice'
|
||||
question: string
|
||||
description?: string
|
||||
choices?: string[]
|
||||
scale?: number
|
||||
lowerBoundLabel?: string
|
||||
upperBoundLabel?: string
|
||||
buttonText?: string
|
||||
}
|
||||
|
||||
interface PostHogCreateSurveyParams {
|
||||
apiKey: string
|
||||
projectId: string
|
||||
region?: 'us' | 'eu'
|
||||
name: string
|
||||
description?: string
|
||||
type?: 'popover' | 'api'
|
||||
questions: string // JSON string of questions array
|
||||
startDate?: string
|
||||
endDate?: string
|
||||
appearance?: string // JSON string of appearance config
|
||||
conditions?: string // JSON string of conditions
|
||||
targetingFlagFilters?: string // JSON string of targeting filters
|
||||
linkedFlagId?: string
|
||||
responsesLimit?: number
|
||||
}
|
||||
|
||||
interface PostHogSurvey {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
type: 'popover' | 'api'
|
||||
questions: PostHogSurveyQuestion[]
|
||||
appearance?: Record<string, any>
|
||||
conditions?: Record<string, any>
|
||||
created_at: string
|
||||
created_by: Record<string, any>
|
||||
start_date?: string
|
||||
end_date?: string
|
||||
archived?: boolean
|
||||
targeting_flag_filters?: Record<string, any>
|
||||
linked_flag?: Record<string, any>
|
||||
responses_limit?: number
|
||||
}
|
||||
|
||||
interface PostHogCreateSurveyResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
survey: PostHogSurvey
|
||||
}
|
||||
}
|
||||
|
||||
export const createSurveyTool: ToolConfig<PostHogCreateSurveyParams, PostHogCreateSurveyResponse> =
|
||||
{
|
||||
id: 'posthog_create_survey',
|
||||
name: 'PostHog Create Survey',
|
||||
description:
|
||||
'Create a new survey in PostHog. Supports question types: Basic (open), Link, Rating, and Multiple Choice.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'PostHog Project ID',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: us or eu (default: us)',
|
||||
default: 'us',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Survey name (optional)',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Survey description',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Survey type: popover (in-app) or api (custom implementation) (default: popover)',
|
||||
default: 'popover',
|
||||
},
|
||||
questions: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'JSON string of survey questions array. Each question must have type (open/link/rating/multiple_choice) and question text. Rating questions can have scale (1-10), lowerBoundLabel, upperBoundLabel. Multiple choice questions need choices array. Link questions can have buttonText.',
|
||||
},
|
||||
startDate: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Survey start date in ISO 8601 format',
|
||||
},
|
||||
endDate: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Survey end date in ISO 8601 format',
|
||||
},
|
||||
appearance: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON string of appearance configuration (colors, position, etc.)',
|
||||
},
|
||||
conditions: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON string of display conditions (URL matching, etc.)',
|
||||
},
|
||||
targetingFlagFilters: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON string of feature flag filters for targeting',
|
||||
},
|
||||
linkedFlagId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Feature flag ID to link to this survey',
|
||||
},
|
||||
responsesLimit: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of responses to collect',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/surveys/`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
name: params.name,
|
||||
type: params.type || 'popover',
|
||||
questions: JSON.parse(params.questions),
|
||||
}
|
||||
|
||||
if (params.description) body.description = params.description
|
||||
if (params.startDate) body.start_date = params.startDate
|
||||
if (params.endDate) body.end_date = params.endDate
|
||||
if (params.appearance) body.appearance = JSON.parse(params.appearance)
|
||||
if (params.conditions) body.conditions = JSON.parse(params.conditions)
|
||||
if (params.targetingFlagFilters) {
|
||||
body.targeting_flag_filters = JSON.parse(params.targetingFlagFilters)
|
||||
}
|
||||
if (params.linkedFlagId) body.linked_flag_id = params.linkedFlagId
|
||||
if (params.responsesLimit) body.responses_limit = params.responsesLimit
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
survey: data,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
survey: {
|
||||
type: 'object',
|
||||
description: 'Created survey details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Survey ID' },
|
||||
name: { type: 'string', description: 'Survey name' },
|
||||
description: { type: 'string', description: 'Survey description' },
|
||||
type: { type: 'string', description: 'Survey type (popover or api)' },
|
||||
questions: {
|
||||
type: 'array',
|
||||
description: 'Survey questions',
|
||||
},
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
start_date: { type: 'string', description: 'Survey start date' },
|
||||
end_date: { type: 'string', description: 'Survey end date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface DeleteFeatureFlagParams {
|
||||
projectId: string
|
||||
flagId: string
|
||||
region: 'us' | 'eu'
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
interface DeleteFeatureFlagResponse {
|
||||
success: boolean
|
||||
message: string
|
||||
}
|
||||
|
||||
export const deleteFeatureFlagTool: ToolConfig<DeleteFeatureFlagParams, DeleteFeatureFlagResponse> =
|
||||
{
|
||||
id: 'posthog_delete_feature_flag',
|
||||
name: 'PostHog Delete Feature Flag',
|
||||
description: 'Delete a feature flag from PostHog',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The PostHog project ID',
|
||||
},
|
||||
flagId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The feature flag ID to delete',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: us or eu',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/feature_flags/${params.flagId}`
|
||||
},
|
||||
method: 'DELETE',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
return {
|
||||
success: true,
|
||||
message: 'Feature flag deleted successfully',
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the deletion was successful',
|
||||
},
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'Confirmation message',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export interface PostHogDeletePersonParams {
|
||||
personalApiKey: string
|
||||
region?: 'us' | 'eu'
|
||||
projectId: string
|
||||
personId: string
|
||||
}
|
||||
|
||||
export interface PostHogDeletePersonResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
status: string
|
||||
}
|
||||
}
|
||||
|
||||
export const deletePersonTool: ToolConfig<PostHogDeletePersonParams, PostHogDeletePersonResponse> =
|
||||
{
|
||||
id: 'posthog_delete_person',
|
||||
name: 'PostHog Delete Person',
|
||||
description:
|
||||
'Delete a person from PostHog. This will remove all associated events and data. Use with caution.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
personalApiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key (for authenticated API access)',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog region: us (default) or eu',
|
||||
default: 'us',
|
||||
},
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Project ID',
|
||||
},
|
||||
personId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Person ID or UUID to delete',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/persons/${params.personId}/`
|
||||
},
|
||||
method: 'DELETE',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.personalApiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (response.ok || response.status === 204) {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
status: 'Person deleted successfully',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const error = await response.text()
|
||||
return {
|
||||
success: false,
|
||||
output: {
|
||||
status: 'Failed to delete person',
|
||||
},
|
||||
error: error || 'Unknown error occurred',
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
status: {
|
||||
type: 'string',
|
||||
description: 'Status message indicating whether the person was deleted successfully',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface EvaluateFlagsParams {
|
||||
region: 'us' | 'eu'
|
||||
projectApiKey: string
|
||||
distinctId: string
|
||||
groups?: string
|
||||
personProperties?: string
|
||||
groupProperties?: string
|
||||
}
|
||||
|
||||
interface FlagEvaluation {
|
||||
[key: string]: boolean | string
|
||||
}
|
||||
|
||||
interface EvaluateFlagsResponse {
|
||||
featureFlags: FlagEvaluation
|
||||
featureFlagPayloads: Record<string, any>
|
||||
errorsWhileComputingFlags: boolean
|
||||
}
|
||||
|
||||
export const evaluateFlagsTool: ToolConfig<EvaluateFlagsParams, EvaluateFlagsResponse> = {
|
||||
id: 'posthog_evaluate_flags',
|
||||
name: 'PostHog Evaluate Feature Flags',
|
||||
description:
|
||||
'Evaluate feature flags for a specific user or group. This is a public endpoint that uses the project API key.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: us or eu',
|
||||
},
|
||||
projectApiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Project API Key (not personal API key)',
|
||||
},
|
||||
distinctId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The distinct ID of the user to evaluate flags for',
|
||||
},
|
||||
groups: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Groups as JSON string (e.g., {"company": "company_id_in_your_db"})',
|
||||
},
|
||||
personProperties: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Person properties as JSON string',
|
||||
},
|
||||
groupProperties: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Group properties as JSON string',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl =
|
||||
params.region === 'eu' ? 'https://eu.i.posthog.com' : 'https://us.i.posthog.com'
|
||||
return `${baseUrl}/decide?v=3`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.projectApiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
distinct_id: params.distinctId,
|
||||
}
|
||||
|
||||
if (params.groups) {
|
||||
try {
|
||||
body.groups = JSON.parse(params.groups)
|
||||
} catch {
|
||||
body.groups = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.personProperties) {
|
||||
try {
|
||||
body.person_properties = JSON.parse(params.personProperties)
|
||||
} catch {
|
||||
body.person_properties = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.groupProperties) {
|
||||
try {
|
||||
body.group_properties = JSON.parse(params.groupProperties)
|
||||
} catch {
|
||||
body.group_properties = {}
|
||||
}
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
featureFlags: data.featureFlags || {},
|
||||
featureFlagPayloads: data.featureFlagPayloads || {},
|
||||
errorsWhileComputingFlags: data.errorsWhileComputingFlags || false,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
featureFlags: {
|
||||
type: 'object',
|
||||
description:
|
||||
'Feature flag evaluations (key-value pairs where values are boolean or string variants)',
|
||||
},
|
||||
featureFlagPayloads: {
|
||||
type: 'object',
|
||||
description: 'Additional payloads attached to feature flags',
|
||||
},
|
||||
errorsWhileComputingFlags: {
|
||||
type: 'boolean',
|
||||
description: 'Whether there were errors while computing flags',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface PostHogGetCohortParams {
|
||||
apiKey: string
|
||||
projectId: string
|
||||
cohortId: string
|
||||
region: string
|
||||
}
|
||||
|
||||
interface PostHogGetCohortResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
groups: Array<Record<string, any>>
|
||||
deleted: boolean
|
||||
filters: Record<string, any>
|
||||
query: Record<string, any> | null
|
||||
created_at: string
|
||||
created_by: Record<string, any> | null
|
||||
is_calculating: boolean
|
||||
last_calculation: string
|
||||
errors_calculating: number
|
||||
count: number
|
||||
is_static: boolean
|
||||
version: number
|
||||
}
|
||||
}
|
||||
|
||||
export const getCohortTool: ToolConfig<PostHogGetCohortParams, PostHogGetCohortResponse> = {
|
||||
id: 'posthog_get_cohort',
|
||||
name: 'PostHog Get Cohort',
|
||||
description:
|
||||
'Get a specific cohort by ID from PostHog. Returns detailed cohort definition, filters, and user count.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The PostHog project ID',
|
||||
},
|
||||
cohortId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The cohort ID to retrieve',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: "us" or "eu" (default: "us")',
|
||||
default: 'us',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/cohorts/${params.cohortId}/`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.id,
|
||||
name: data.name || '',
|
||||
description: data.description || '',
|
||||
groups: data.groups || [],
|
||||
deleted: data.deleted || false,
|
||||
filters: data.filters || {},
|
||||
query: data.query || null,
|
||||
created_at: data.created_at,
|
||||
created_by: data.created_by || null,
|
||||
is_calculating: data.is_calculating || false,
|
||||
last_calculation: data.last_calculation || '',
|
||||
errors_calculating: data.errors_calculating || 0,
|
||||
count: data.count || 0,
|
||||
is_static: data.is_static || false,
|
||||
version: data.version || 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: {
|
||||
type: 'number',
|
||||
description: 'Unique identifier for the cohort',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the cohort',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'Description of the cohort',
|
||||
},
|
||||
groups: {
|
||||
type: 'array',
|
||||
description: 'Groups that define the cohort',
|
||||
},
|
||||
deleted: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the cohort is deleted',
|
||||
},
|
||||
filters: {
|
||||
type: 'object',
|
||||
description: 'Filter configuration for the cohort',
|
||||
},
|
||||
query: {
|
||||
type: 'object',
|
||||
description: 'Query configuration for the cohort',
|
||||
optional: true,
|
||||
},
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when cohort was created',
|
||||
},
|
||||
created_by: {
|
||||
type: 'object',
|
||||
description: 'User who created the cohort',
|
||||
optional: true,
|
||||
},
|
||||
is_calculating: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the cohort is being calculated',
|
||||
},
|
||||
last_calculation: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp of last calculation',
|
||||
},
|
||||
errors_calculating: {
|
||||
type: 'number',
|
||||
description: 'Number of errors during calculation',
|
||||
},
|
||||
count: {
|
||||
type: 'number',
|
||||
description: 'Number of users in the cohort',
|
||||
},
|
||||
is_static: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the cohort is static',
|
||||
},
|
||||
version: {
|
||||
type: 'number',
|
||||
description: 'Version number of the cohort',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface PostHogGetDashboardParams {
|
||||
apiKey: string
|
||||
projectId: string
|
||||
dashboardId: string
|
||||
region: string
|
||||
}
|
||||
|
||||
interface PostHogGetDashboardResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
pinned: boolean
|
||||
created_at: string
|
||||
created_by: Record<string, any> | null
|
||||
last_modified_at: string
|
||||
last_modified_by: Record<string, any> | null
|
||||
tiles: Array<Record<string, any>>
|
||||
filters: Record<string, any>
|
||||
tags: string[]
|
||||
restriction_level: number
|
||||
}
|
||||
}
|
||||
|
||||
export const getDashboardTool: ToolConfig<PostHogGetDashboardParams, PostHogGetDashboardResponse> =
|
||||
{
|
||||
id: 'posthog_get_dashboard',
|
||||
name: 'PostHog Get Dashboard',
|
||||
description:
|
||||
'Get a specific dashboard by ID from PostHog. Returns detailed dashboard configuration, tiles, and metadata.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The PostHog project ID',
|
||||
},
|
||||
dashboardId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The dashboard ID to retrieve',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: "us" or "eu" (default: "us")',
|
||||
default: 'us',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/dashboards/${params.dashboardId}/`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.id,
|
||||
name: data.name || '',
|
||||
description: data.description || '',
|
||||
pinned: data.pinned || false,
|
||||
created_at: data.created_at,
|
||||
created_by: data.created_by || null,
|
||||
last_modified_at: data.last_modified_at,
|
||||
last_modified_by: data.last_modified_by || null,
|
||||
tiles: data.tiles || [],
|
||||
filters: data.filters || {},
|
||||
tags: data.tags || [],
|
||||
restriction_level: data.restriction_level || 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: {
|
||||
type: 'number',
|
||||
description: 'Unique identifier for the dashboard',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the dashboard',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'Description of the dashboard',
|
||||
},
|
||||
pinned: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the dashboard is pinned',
|
||||
},
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when dashboard was created',
|
||||
},
|
||||
created_by: {
|
||||
type: 'object',
|
||||
description: 'User who created the dashboard',
|
||||
optional: true,
|
||||
},
|
||||
last_modified_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when dashboard was last modified',
|
||||
},
|
||||
last_modified_by: {
|
||||
type: 'object',
|
||||
description: 'User who last modified the dashboard',
|
||||
optional: true,
|
||||
},
|
||||
tiles: {
|
||||
type: 'array',
|
||||
description: 'Tiles/widgets on the dashboard with their configurations',
|
||||
},
|
||||
filters: {
|
||||
type: 'object',
|
||||
description: 'Global filters applied to the dashboard',
|
||||
},
|
||||
tags: {
|
||||
type: 'array',
|
||||
description: 'Tags associated with the dashboard',
|
||||
},
|
||||
restriction_level: {
|
||||
type: 'number',
|
||||
description: 'Access restriction level for the dashboard',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface PostHogGetEventDefinitionParams {
|
||||
projectId: string
|
||||
eventDefinitionId: string
|
||||
region: 'us' | 'eu'
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
interface EventDefinition {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
tags: string[]
|
||||
volume_30_day: number | null
|
||||
query_usage_30_day: number | null
|
||||
created_at: string
|
||||
last_seen_at: string | null
|
||||
updated_at: string
|
||||
updated_by: {
|
||||
id: number
|
||||
uuid: string
|
||||
distinct_id: string
|
||||
first_name: string
|
||||
email: string
|
||||
} | null
|
||||
verified: boolean
|
||||
verified_at: string | null
|
||||
verified_by: string | null
|
||||
}
|
||||
|
||||
export const getEventDefinitionTool: ToolConfig<PostHogGetEventDefinitionParams, EventDefinition> =
|
||||
{
|
||||
id: 'posthog_get_event_definition',
|
||||
name: 'PostHog Get Event Definition',
|
||||
description:
|
||||
'Get details of a specific event definition in PostHog. Returns comprehensive information about the event including metadata, usage statistics, and verification status.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Project ID',
|
||||
},
|
||||
eventDefinitionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Event Definition ID to retrieve',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: us or eu',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/event_definitions/${params.eventDefinitionId}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
description: data.description || '',
|
||||
tags: data.tags || [],
|
||||
volume_30_day: data.volume_30_day,
|
||||
query_usage_30_day: data.query_usage_30_day,
|
||||
created_at: data.created_at,
|
||||
last_seen_at: data.last_seen_at,
|
||||
updated_at: data.updated_at,
|
||||
updated_by: data.updated_by,
|
||||
verified: data.verified || false,
|
||||
verified_at: data.verified_at,
|
||||
verified_by: data.verified_by,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'Unique identifier for the event definition',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Event name',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'Event description',
|
||||
},
|
||||
tags: {
|
||||
type: 'array',
|
||||
description: 'Tags associated with the event',
|
||||
},
|
||||
volume_30_day: {
|
||||
type: 'number',
|
||||
description: 'Number of events received in the last 30 days',
|
||||
},
|
||||
query_usage_30_day: {
|
||||
type: 'number',
|
||||
description: 'Number of times this event was queried in the last 30 days',
|
||||
},
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when the event was created',
|
||||
},
|
||||
last_seen_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when the event was last seen',
|
||||
},
|
||||
updated_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when the event was updated',
|
||||
},
|
||||
updated_by: {
|
||||
type: 'object',
|
||||
description: 'User who last updated the event',
|
||||
},
|
||||
verified: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the event has been verified',
|
||||
},
|
||||
verified_at: {
|
||||
type: 'string',
|
||||
description: 'ISO timestamp when the event was verified',
|
||||
},
|
||||
verified_by: {
|
||||
type: 'string',
|
||||
description: 'User who verified the event',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
interface GetExperimentParams {
|
||||
projectId: string
|
||||
experimentId: string
|
||||
region: 'us' | 'eu'
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
interface Experiment {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
feature_flag_key: string
|
||||
feature_flag: Record<string, any>
|
||||
parameters: Record<string, any>
|
||||
filters: Record<string, any>
|
||||
variants: Record<string, any>
|
||||
start_date: string | null
|
||||
end_date: string | null
|
||||
created_at: string
|
||||
created_by: Record<string, any>
|
||||
archived: boolean
|
||||
metrics: Array<Record<string, any>>
|
||||
metrics_secondary: Array<Record<string, any>>
|
||||
}
|
||||
|
||||
interface GetExperimentResponse {
|
||||
experiment: Experiment
|
||||
}
|
||||
|
||||
export const getExperimentTool: ToolConfig<GetExperimentParams, GetExperimentResponse> = {
|
||||
id: 'posthog_get_experiment',
|
||||
name: 'PostHog Get Experiment',
|
||||
description: 'Get details of a specific experiment',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
projectId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The PostHog project ID',
|
||||
},
|
||||
experimentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The experiment ID',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog cloud region: us or eu',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PostHog Personal API Key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = params.region === 'eu' ? 'https://eu.posthog.com' : 'https://us.posthog.com'
|
||||
return `${baseUrl}/api/projects/${params.projectId}/experiments/${params.experimentId}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
experiment: data,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
experiment: {
|
||||
type: 'object',
|
||||
description: 'Experiment details',
|
||||
properties: {
|
||||
id: { type: 'number', description: 'Experiment ID' },
|
||||
name: { type: 'string', description: 'Experiment name' },
|
||||
description: { type: 'string', description: 'Experiment description' },
|
||||
feature_flag_key: { type: 'string', description: 'Associated feature flag key' },
|
||||
feature_flag: { type: 'object', description: 'Feature flag details' },
|
||||
parameters: { type: 'object', description: 'Experiment parameters' },
|
||||
filters: { type: 'object', description: 'Experiment filters' },
|
||||
variants: { type: 'object', description: 'Experiment variants' },
|
||||
start_date: { type: 'string', description: 'Start date' },
|
||||
end_date: { type: 'string', description: 'End date' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
created_by: { type: 'object', description: 'Creator information' },
|
||||
archived: { type: 'boolean', description: 'Whether the experiment is archived' },
|
||||
metrics: { type: 'array', description: 'Primary metrics' },
|
||||
metrics_secondary: { type: 'array', description: 'Secondary metrics' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user